|
8 | 8 | return (/rem/).test(div.style.fontSize); |
9 | 9 | }, |
10 | 10 |
|
11 | | - // filter returned link nodes for stylesheets |
| 11 | + // filter returned links for stylesheets |
12 | 12 | isStyleSheet = function () { |
13 | 13 | var styles = document.getElementsByTagName('link'), |
14 | | - filteredStyles = []; |
| 14 | + filteredLinks = []; |
15 | 15 |
|
16 | 16 | for ( var i = 0; i < styles.length; i++) { |
17 | 17 | if ( styles[i].rel.toLowerCase() === 'stylesheet' && styles[i].getAttribute('data-norem') === null ) { |
18 | | - filteredStyles.push( styles[i] ); |
| 18 | + |
| 19 | + filteredLinks.push( styles[i].href ); |
19 | 20 | } |
20 | 21 | } |
21 | 22 |
|
22 | | - return filteredStyles; |
| 23 | + return filteredLinks; |
23 | 24 | }, |
24 | 25 |
|
25 | | - processSheets = function () { |
26 | | - var links = []; |
27 | | - sheets = isStyleSheet(); // search for link tags and confirm it's a stylesheet |
28 | | - sheets.og = sheets.length; // store the original length of sheets as a property |
29 | | - sheets.loaded = 0; // keep track of how many have been loaded so far |
30 | | - for( var i = 0; i < sheets.length; i++ ){ |
31 | | - links[i] = sheets[i].href; |
32 | | - xhr( links[i], storeCSS, i ); |
| 26 | + processLinks = function () { |
| 27 | + if( links.length === 0 ){ |
| 28 | + links = isStyleSheet(); // search for link tags and confirm it's a stylesheet |
| 29 | + } |
| 30 | + |
| 31 | + //prepare to match each link |
| 32 | + for( var i = 0; i < links.length; i++ ){ |
| 33 | + xhr( links[i], storeCSS, links[i], i ); |
33 | 34 | } |
34 | 35 | }, |
35 | 36 |
|
36 | | - storeCSS = function ( response, i ) { |
| 37 | + storeCSS = function ( response, link ) { |
37 | 38 |
|
38 | | - preCSS[i] = response; |
| 39 | + preCSS.push(response.responseText); |
| 40 | + CSSLinks.push(link); |
39 | 41 |
|
40 | | - if( ++sheets.loaded === sheets.og ){ |
41 | | - for ( var j = 0; j < preCSS.length; j++ ){ |
42 | | - matchCSS( preCSS[j] ); |
| 42 | + if( CSSLinks.length === links.length ){ |
| 43 | + for( var j = 0; j < CSSLinks.length; j++ ){ |
| 44 | + matchCSS( preCSS[j], CSSLinks[j] ); |
43 | 45 | } |
44 | 46 |
|
45 | | - buildCSS(); |
| 47 | + if( ( links = importLinks.slice(0) ).length > 0 ){ //after finishing all current links, set links equal to the new imports found |
| 48 | + CSSLinks = []; |
| 49 | + preCSS = []; |
| 50 | + importLinks = []; |
| 51 | + processLinks(); |
| 52 | + } else { |
| 53 | + buildCSS(); |
| 54 | + } |
46 | 55 | } |
47 | | - |
48 | 56 | }, |
49 | | - |
50 | | - matchCSS = function ( response ) { // collect all of the rules from the xhr response texts and match them to a pattern |
51 | | - var clean = removeComments( removeMediaQueries(response.responseText) ), |
| 57 | + |
| 58 | + matchCSS = function ( sheetCSS, link ) { // collect all of the rules from the xhr response texts and match them to a pattern |
| 59 | + var clean = removeComments( removeMediaQueries(sheetCSS) ), |
52 | 60 | 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 |
53 | 61 | current = clean.match(pattern), |
54 | 62 | remPattern =/\d*\.?\d+rem/g, |
55 | | - remCurrent = clean.match(remPattern); |
| 63 | + remCurrent = clean.match(remPattern), |
| 64 | + sheetPathPattern = /(.*\/)/, |
| 65 | + sheetPath = sheetPathPattern.exec(link)[0], //relative path to css file specified in @import |
| 66 | + importPattern = /@import (?:url\()?['"]?([^'\)"]*)['"]?\)?[^;]*/gm, //matches all @import variations outlined at: https://developer.mozilla.org/en-US/docs/Web/CSS/@import |
| 67 | + importStatement; |
| 68 | + |
| 69 | + while( (importStatement = importPattern.exec(sheetCSS)) !== null ){ |
| 70 | + importLinks.push( sheetPath + importStatement[1] ); |
| 71 | + } |
56 | 72 |
|
57 | 73 | if( current !== null && current.length !== 0 ){ |
58 | 74 | found = found.concat( current ); // save all of the blocks of rules with rem in a property |
|
77 | 93 | }, |
78 | 94 |
|
79 | 95 | parseCSS = function () { // replace each set of parentheses with evaluated content |
80 | | - var remSize; |
| 96 | + var remSize; |
81 | 97 | for( var i = 0; i < foundProps.length; i++ ){ |
82 | 98 | remSize = parseFloat(foundProps[i].substr(0,foundProps[i].length-3)); |
83 | 99 | css[i] = Math.round( remSize * fontSize ) + 'px'; |
|
104 | 120 | }, |
105 | 121 |
|
106 | 122 | xhr = function ( url, callback, i ) { // create new XMLHttpRequest object and run it |
| 123 | + |
107 | 124 | try { |
108 | 125 | var xhr = getXMLHttpRequest(); |
109 | 126 | xhr.open( 'GET', url, true ); |
|
163 | 180 | } |
164 | 181 | }, |
165 | 182 |
|
166 | | - // Test for Media Query support |
| 183 | + // Test for Media Query support |
167 | 184 | mediaQuery = function() { |
168 | 185 | if (window.matchMedia || window.msMatchMedia) { return true; } |
169 | 186 | return false; |
|
177 | 194 | css = css.replace(/@media[\s\S]*?\}\s*\}/, ""); |
178 | 195 | } |
179 | 196 |
|
180 | | - return css; |
| 197 | + return css; |
181 | 198 | }, |
182 | 199 |
|
183 | 200 | getXMLHttpRequest = function () { // we're gonna check if our browser will let us use AJAX |
|
198 | 215 |
|
199 | 216 | if( !cssremunit() ){ // this checks if the rem value is supported |
200 | 217 | var rules = '', // initialize the rules variable in this scope so it can be used later |
201 | | - sheets = [], // initialize the array holding the sheets for use later |
| 218 | + links = [], // initialize the array holding the sheets urls for use later |
| 219 | + importLinks = [], //initialize the array holding the import sheet urls for use later |
202 | 220 | found = [], // initialize the array holding the found rules for use later |
203 | 221 | foundProps = [], // initialize the array holding the found properties for use later |
204 | 222 | preCSS = [], // initialize array that holds css before being parsed |
| 223 | + CSSLinks = [], //initialize array holding css links returned from xhr |
205 | 224 | css = [], // initialize the array holding the parsed rules for use later |
206 | 225 | body = document.getElementsByTagName('body')[0], |
207 | 226 | fontSize = ''; |
| 227 | + |
208 | 228 | if (body.currentStyle) { |
209 | 229 | if ( body.currentStyle.fontSize.indexOf("px") >= 0 ) { |
210 | 230 | fontSize = body.currentStyle.fontSize.replace('px', ''); |
|
218 | 238 | } else if (window.getComputedStyle) { |
219 | 239 | fontSize = document.defaultView.getComputedStyle(body, null).getPropertyValue('font-size').replace('px', ''); // find font-size in body element |
220 | 240 | } |
221 | | - processSheets(); |
| 241 | + processLinks(); |
222 | 242 | } // else { do nothing, you are awesome and have REM support } |
223 | 243 |
|
224 | 244 | })(window); |
0 commit comments