1(function (window, undefined) { 2 "use strict"; 3 // test for REM unit support 4 var cssremunit = function() { 5 var div = document.createElement( 'div' ); 6 div.style.cssText = 'font-size: 1rem;'; 7 8 return (/rem/).test(div.style.fontSize); 9 }, 10 11 // filter returned links for stylesheets 12 isStyleSheet = function () { 13 var styles = document.getElementsByTagName('link'), 14 filteredLinks = []; 15 16 for ( var i = 0; i < styles.length; i++) { 17 if ( styles[i].rel.toLowerCase() === 'stylesheet' && styles[i].getAttribute('data-norem') === null ) { 18 19 filteredLinks.push( styles[i].href ); 20 } 21 } 22 23 return filteredLinks; 24 }, 25 26 processLinks = function () { 27 //prepare to match each link 28 for( var i = 0; i < links.length; i++ ){ 29 xhr( links[i], storeCSS ); 30 } 31 }, 32 33 storeCSS = function ( response, link ) { 34 35 preCSS.push(response.responseText); 36 CSSLinks.push(link); 37 38 if( CSSLinks.length === links.length ){ 39 for( var j = 0; j < CSSLinks.length; j++ ){ 40 matchCSS( preCSS[j], CSSLinks[j] ); 41 } 42 43 if( ( links = importLinks.slice(0) ).length > 0 ){ //after finishing all current links, set links equal to the new imports found 44 CSSLinks = []; 45 preCSS = []; 46 importLinks = []; 47 processLinks(); 48 } else { 49 buildCSS(); 50 } 51 } 52 }, 53 54 matchCSS = function ( sheetCSS, link ) { // collect all of the rules from the xhr response texts and match them to a pattern 55 var clean = removeMediaQueries( sheetCSS ).replace(/\/\*[\s\S]*?\*\//g, ''), // remove MediaQueries and comments 56 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 57 current = clean.match(pattern), 58 remPattern =/\d*\.?\d+rem/g, 59 remCurrent = clean.match(remPattern), 60 sheetPathPattern = /(.*\/)/, 61 sheetPath = sheetPathPattern.exec(link)[0], //relative path to css file specified in @import 62 importPattern = /@import (?:url\()?['"]?([^'\)"]*)['"]?\)?[^;]*/gm, //matches all @import variations outlined at: https://developer.mozilla.org/en-US/docs/Web/CSS/@import 63 importStatement; 64 65 while( (importStatement = importPattern.exec(sheetCSS)) !== null ){ 66 importLinks.push( sheetPath + importStatement[1] ); 67 } 68 69 if( current !== null && current.length !== 0 ){ 70 found = found.concat( current ); // save all of the blocks of rules with rem in a property 71 foundProps = foundProps.concat( remCurrent ); // save all of the properties with rem 72 } 73 }, 74 75 buildCSS = function () { // first build each individual rule from elements in the found array and then add it to the string of rules. 76 var pattern = /[\w\d\s\-\/\\%#:,.'"*()]+\d*\.?\d+rem[\w\d\s\-\/\\%#:!,.'"*()]*[;}]/g; // find properties with rem values in them 77 for( var i = 0; i < found.length; i++ ){ 78 rules = rules + found[i].substr(0,found[i].indexOf("{")+1); // save the selector portion of each rule with a rem value 79 var current = found[i].match( pattern ); 80 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 81 rules = rules + current[j]; 82 if( j === current.length-1 && rules[rules.length-1] !== "}" ){ 83 rules = rules + "\n}"; 84 } 85 } 86 } 87 88 parseCSS(); 89 }, 90 91 parseCSS = function () { // replace each set of parentheses with evaluated content 92 for( var i = 0; i < foundProps.length; i++ ){ 93 css[i] = Math.round( parseFloat(foundProps[i].substr(0,foundProps[i].length-3)*fontSize) ) + 'px'; 94 } 95 96 loadCSS(); 97 }, 98 99 loadCSS = function () { // replace and load the new rules 100 for( var i = 0; i < css.length; i++ ){ // only run this loop as many times as css has entries 101 if( css[i] ){ 102 rules = rules.replace( foundProps[i],css[i] ); // replace old rules with our processed rules 103 } 104 } 105 var remcss = document.createElement( 'style' ); 106 remcss.setAttribute( 'type', 'text/css' ); 107 remcss.id = 'remReplace'; 108 document.getElementsByTagName( 'head' )[0].appendChild( remcss ); // create the new element 109 if( remcss.styleSheet ) { 110 remcss.styleSheet.cssText = rules; // IE8 will not support innerHTML on read-only elements, such as STYLE 111 } else { 112 remcss.appendChild( document.createTextNode( rules ) ); 113 } 114 }, 115 116 xhr = function ( url, callback ) { // create new XMLHttpRequest object and run it 117 try { 118 //try to create a request object 119 //arranging the two conditions this way is for IE7/8's benefit 120 //so that it works with any combination of ActiveX or Native XHR settings, 121 //as long as one or the other is enabled; but if both are enabled 122 //it prefers ActiveX, which means it still works with local files 123 //(Native XHR in IE7/8 is blocked and throws "access is denied", 124 // but ActiveX is permitted if the user allows it [default is to prompt]) 125 var xhr = window.ActiveXObject ? ( new ActiveXObject('Microsoft.XMLHTTP') || new ActiveXObject('Msxml2.XMLHTTP') ) : new XMLHttpRequest(); 126 127 xhr.open( 'GET', url, true ); 128 xhr.onreadystatechange = function() { 129 if ( xhr.readyState === 4 ){ 130 callback(xhr, url); 131 } // else { callback function on AJAX error } 132 }; 133 134 xhr.send( null ); 135 } catch (e){ 136 if ( window.XDomainRequest ) { 137 var xdr = new XDomainRequest();
138 xdr.open('get', url); 139 xdr.onload = function() { 140 callback(xdr, url); 141 }; 142 xdr.onerror = function() { 143 return false; // xdr load fail 144 }; 145 xdr.send(); 146 } 147 } 148 }, 149 150 // Remove queries. 151 removeMediaQueries = function(css) { 152 // Test for Media Query support 153 if ( !window.matchMedia && !window.msMatchMedia ) { 154 // If the browser doesn't support media queries, we find all @media declarations in the CSS and remove them. 155 // Note: Since @rules can't be nested in the CSS spec, we're safe to just check for the closest following "}}" to the "@media". 156 css = css.replace(/@media[\s\S]*?\}\s*\}/g, ""); 157 } 158 159 return css; 160 }; 161 162 if( !cssremunit() ){ // this checks if the rem value is supported 163 var rules = '', // initialize the rules variable in this scope so it can be used later 164 links = isStyleSheet(), // initialize the array holding the sheets urls for use later 165 importLinks = [], //initialize the array holding the import sheet urls for use later 166 found = [], // initialize the array holding the found rules for use later 167 foundProps = [], // initialize the array holding the found properties for use later 168 preCSS = [], // initialize array that holds css before being parsed 169 CSSLinks = [], //initialize array holding css links returned from xhr 170 css = [], // initialize the array holding the parsed rules for use later 171 fontSize = ''; 172 173 // Notice: rem is a "root em" that means that in case when html element size was changed by css 174 // or style we should not change document.documentElement.fontSize to 1em - only body size should be changed 175 // to 1em for calculation 176 177 fontSize = (function () { 178 var doc = document, 179 docElement = doc.documentElement, 180 body = doc.body || doc.createElement('body'), 181 isFakeBody = !doc.body, 182 div = doc.createElement('div'), 183 currentSize = body.style.fontSize, 184 size; 185 186 if ( isFakeBody ) { 187 docElement.appendChild( body ); 188 } 189 190 div.style.cssText = 'width:1em; position:absolute; visibility:hidden; padding: 0;'; 191 192 body.style.fontSize = '1em'; 193 194 body.appendChild( div ); 195 size = div.offsetWidth; 196 197 if ( isFakeBody ) { 198 docElement.removeChild( body ); 199 } 200 else { 201 body.removeChild( div ); 202 body.style.fontSize = currentSize; 203 } 204 205 return size; 206 }()); 207 208 processLinks(); 209 } // else { do nothing, you are awesome and have REM support } 210 211})(window);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.