Skip to content

Commit

Permalink
updating for more test cases, ignore media queries and fix syntax for…
Browse files Browse the repository at this point in the history
… IE6 XHR callbacks
  • Loading branch information
chuckcarpenter committed Jun 20, 2013
2 parents 22d131d + 143784d commit acd2472
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 59 deletions.
20 changes: 16 additions & 4 deletions css/general.css
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@
/* TEST comments for the CSS */

html {
font-size: 62.5%;
font-size: 100%;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
line-height: 1.6;
}
.test {
background-color:red;
background-color:blue;
color: white;
width: 10em;
height: 3.2rem;
height: 5rem;
}
p {font-size: 1.4rem;}
p {font-size: 5rem;}

/* These styles will only show in REM ready browsers.
If you're expecting these to be ignored, but see a green box
then something went wrong.
*/
@media screen and (min-width: 480px) {
p {
font-size: 10rem;
}
.test {background-color: green;}
}
8 changes: 8 additions & 0 deletions css/ignore.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/* This rule should be ignored by the REM processor.
If your font is tiny, something is wrong. Make
sure you've the data-norem attr on your stylesheet link.
*/

p {
font-size: .2rem;
}
7 changes: 6 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@
<head>
<title>remReplace</title>
<link rel="stylesheet" type="text/css" href="css/general.css" />
<!-- ignore.css shows in normal browsers, but ones where we expect the REM.js to
run then the REM rules should not get parsed.
-->
<link rel="stylesheet" type="text/css" href="css/ignore.css" data-norem />

</head>
<body>
<div class="test">Hello World!</div>
<script src="js/rem.js" type="text/javascript"></script>
<p>This thing works.</p>
<script src="js/rem.min.js" type="text/javascript"></script>
</body>
</html>
124 changes: 71 additions & 53 deletions js/rem.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(function (window, undefined) {

"use strict";
// test for REM unit support
var cssremunit = function() {
var div = document.createElement( 'div' );
Expand All @@ -12,8 +12,9 @@
isStyleSheet = function () {
var styles = document.getElementsByTagName('link'),
filteredStyles = [];
for (i = 0; i < styles.length; i++) {
if ( styles[i].rel.toLowerCase() === 'stylesheet' && !styles[i].hasAttribute('data-norem') ) {

for ( var i = 0; i < styles.length; i++) {
if ( styles[i].rel.toLowerCase() === 'stylesheet' && styles[i].getAttribute('data-norem') === null ) {
filteredStyles.push( styles[i] );
}
}
Expand All @@ -23,86 +24,105 @@

processSheets = function () {
var links = [];
sheets = isStyleSheet(); //search for link tags and confirm it's a stylesheet
sheets.og = sheets.length; //store the original length of sheets as a property
sheets = isStyleSheet(); // search for link tags and confirm it's a stylesheet
sheets.og = sheets.length; // store the original length of sheets as a property
for( var i = 0; i < sheets.length; i++ ){
links[i] = sheets[i].href;
xhr( links[i], matchcss, i );
xhr( links[i], matchCSS, i );
}
},

matchcss = function ( response, i ) { //collect all of the rules from the xhr response texts and match them to a pattern
matchCSS = function ( response, i ) { // collect all of the rules from the xhr response texts and match them to a pattern
var clean = removeComments( removeMediaQueries(response.responseText) ),
pattern = /[\w\d\s\-\/\\\[\]:,.'"*()<>+~%#^$_=|]+\{[\w\d\s\-\/\\%#:;,.'"*()]+\d*\.{0,1}\d+rem[\w\d\s\-\/\\%#:;,.'"*()]*\}/g, //find selectors that use rem in one or more of their rules
pattern = /[\w\d\s\-\/\\\[\]:,.'"*()<>+~%#^$_=|@]+\{[\w\d\s\-\/\\%#:;,.'"*()]+\d*\.?\d+rem[\w\d\s\-\/\\%#:;,.'"*()]*\}/g, //find selectors that use rem in one or more of their rules
current = clean.match(pattern),
remPattern =/\d*\.{0,1}\d+rem/g,
remPattern =/\d*\.?\d+rem/g,
remCurrent = clean.match(remPattern);

if( current !== null && current.length !== 0 ){
found = found.concat( current ); //save all of the blocks of rules with rem in a property
foundProps = foundProps.concat( remCurrent ); //save all of the properties with rem
found = found.concat( current ); // save all of the blocks of rules with rem in a property
foundProps = foundProps.concat( remCurrent ); // save all of the properties with rem
}
if( i === sheets.og-1 ){
buildIt();
buildCSS();
}
},

buildIt = function () { //first build each individual rule from elements in the found array and then add it to the string of rules.
var pattern = /[\w\d\s\-\/\\%#:,.'"*()]+\d*\.{0,1}\d+rem[\w\d\s\-\/\\%#:,.'"*()]*[;}]/g; //find properties with rem values in them
buildCSS = function () { // first build each individual rule from elements in the found array and then add it to the string of rules.
var pattern = /[\w\d\s\-\/\\%#:,.'"*()]+\d*\.?\d+rem[\w\d\s\-\/\\%#:,.'"*()]*[;}]/g; // find properties with rem values in them
for( var i = 0; i < found.length; i++ ){
rules = rules + found[i].substr(0,found[i].indexOf("{")+1); //save the selector portion of each rule with a rem value
rules = rules + found[i].substr(0,found[i].indexOf("{")+1); // save the selector portion of each rule with a rem value
var current = found[i].match( pattern );
for( var j = 0; j<current.length; j++ ){ //build a new set of with only the selector and properties that have rem in the value
for( var j = 0; j<current.length; j++ ){ // build a new set of with only the selector and properties that have rem in the value
rules = rules + current[j];
if( j === current.length-1 && rules[rules.length-1] !== "}" ){
rules = rules + "\n}";
}
}
}

parseIt();
parseCSS();
},

parseIt = function () { //replace each set of parentheses with evaluated content
parseCSS = function () { // replace each set of parentheses with evaluated content

for( var i = 0; i < foundProps.length; i++ ){
css[i] = Math.round( eval(foundProps[i].substr(0,foundProps[i].length-3)*fontSize) ) + 'px';
css[i] = Math.round( parseInt(foundProps[i].substr(0,foundProps[i].length-3)*fontSize, 10) ) + 'px';
}

loadCSS();
},

loadCSS = function () { //replace and load the new rules
for( var i = 0; i < css.length; i++ ){ //only run this loop as many times as css has entries
loadCSS = function () { // replace and load the new rules
for( var i = 0; i < css.length; i++ ){ // only run this loop as many times as css has entries
if( css[i] ){
rules = rules.replace( foundProps[i],css[i] ); //replace old rules with our processed rules
rules = rules.replace( foundProps[i],css[i] ); // replace old rules with our processed rules
}
}
var remcss = document.createElement( 'style' );
remcss.setAttribute( 'type', 'text/css' );
remcss.id = 'remReplace';
document.getElementsByTagName( 'head' )[0].appendChild( remcss ); //create the new element
remcss.styleSheet.cssText = rules; // IE8 will not support innerHTML on read-only elements, such as STYLE
document.getElementsByTagName( 'head' )[0].appendChild( remcss ); // create the new element
if( remcss.styleSheet ) {
remcss.styleSheet.cssText = rules; // IE8 will not support innerHTML on read-only elements, such as STYLE
} else {
remcss.appendChild( document.createTextNode( rules ) );
}
},

xhr = function ( url, callback, i ) { //create new XMLHttpRequest object and run it
xhr = function ( url, callback, i ) { // create new XMLHttpRequest object and run it
try {
var xhr = getXMLHttpRequest();
xhr.open( 'GET', url, true );
xhr.send();
if ( window.XMLHttpRequest ){ //If browser supports AJAX
xhr.onreadystatechange = function() {
var ie = (function () { //function checking IE version
var undef,
v = 3,
div = document.createElement('div'),
all = div.getElementsByTagName('i');
while (
div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->',
all[0]
);
return v > 4 ? v : undef;
}());

if ( ie >= 7 ){ //If IE is greater than 6
// This targets modern browsers and modern versions of IE,
// which don't need the "new" keyword.
xhr.onreadystatechange = function () {
if ( xhr.readyState === 4 ){
callback(xhr, i);
} else { /*callback function on AJAX error*/ }
} // else { callback function on AJAX error }
};
} else { // Then we expect the browser should support AJAX through ActiveX (basically used to target IE6 and IE7)
} else {
// This block targets old versions of IE, which require "new".
xhr.onreadystatechange = new function() { //IE6 and IE7 need the "new function()" syntax to work properly
if ( xhr.readyState === 4 ){
callback(xhr, i);
} else { /*callback function on AJAX error*/ }
} // else { callback function on AJAX error }
};
}
}
} catch (e){
if ( window.XDomainRequest ) {
var xdr = new XDomainRequest();
Expand All @@ -111,7 +131,7 @@
callback(xdr, i);
};
xdr.onerror = function() {
console.log('IE XDR load fail.');
return false; // xdr load fail
};
xdr.send();
}
Expand Down Expand Up @@ -149,46 +169,44 @@
return css;
},

getXMLHttpRequest = function () { //we're gonna check if our browser will let us use AJAX
getXMLHttpRequest = function () { // we're gonna check if our browser will let us use AJAX
if (window.XMLHttpRequest) {
return new XMLHttpRequest();
} else { //if XMLHttpRequest doesn't work
} else { // if XMLHttpRequest doesn't work
try {
return new ActiveXObject("MSXML2.XMLHTTP"); // then we'll instead use AJAX through ActiveX for IE6/IE7
} catch (e1) {
try {
return new ActiveXObject("Microsoft.XMLHTTP"); // other microsoft
} catch (e2) {
//No XHR at all...
// No XHR at all...
}
}
}
};

if( !cssremunit() ){ //this checks if the rem value is supported
var rules = '', //initialize the rules variable in this scope so it can be used later
sheets = [], //initialize the array holding the sheets for use later
found = [], //initialize the array holding the found rules for use later
foundProps = [], //initialize the array holding the found properties for use later
css = [], //initialize the array holding the parsed rules for use later
if( !cssremunit() ){ // this checks if the rem value is supported
var rules = '', // initialize the rules variable in this scope so it can be used later
sheets = [], // initialize the array holding the sheets for use later
found = [], // initialize the array holding the found rules for use later
foundProps = [], // initialize the array holding the found properties for use later
css = [], // initialize the array holding the parsed rules for use later
body = document.getElementsByTagName('body')[0],
fontSize = '';
if (body.currentStyle) {
if ( body.currentStyle['fontSize'].indexOf("px") >= 0 ) {
fontSize = body.currentStyle['fontSize'].replace('px', '');
} else if ( body.currentStyle['fontSize'].indexOf("em") >= 0 ) {
fontSize = body.currentStyle['fontSize'].replace('em', '');
} else if ( body.currentStyle['fontSize'].indexOf("pt") >= 0 ) {
fontSize = body.currentStyle['fontSize'].replace('pt', '');
if ( body.currentStyle.fontSize.indexOf("px") >= 0 ) {
fontSize = body.currentStyle.fontSize.replace('px', '');
} else if ( body.currentStyle.fontSize.indexOf("em") >= 0 ) {
fontSize = body.currentStyle.fontSize.replace('em', '');
} else if ( body.currentStyle.fontSize.indexOf("pt") >= 0 ) {
fontSize = body.currentStyle.fontSize.replace('pt', '');
} else {
fontSize = (body.currentStyle['fontSize'].replace('%', '') / 100) * 16; //IE8 returns the percentage while other browsers return the computed value
fontSize = (body.currentStyle.fontSize.replace('%', '') / 100) * 16; // IE8 returns the percentage while other browsers return the computed value
}
} else if (window.getComputedStyle) {
fontSize = document.defaultView.getComputedStyle(body, null).getPropertyValue('font-size').replace('px', ''); //find font-size in body element
fontSize = document.defaultView.getComputedStyle(body, null).getPropertyValue('font-size').replace('px', ''); // find font-size in body element
}
processSheets();
} else {
// do nothing, you are awesome and have REM support
}
} // else { do nothing, you are awesome and have REM support }

})(window);
Loading

0 comments on commit acd2472

Please sign in to comment.