1/*! elementQuery | Author: Tyson Matanich (http://matanich.com), 2013 | License: MIT */ 2(function (window, document, undefined) { 3 // Enable strict mode 4 "use strict"; 5 6 // Use Sizzle standalone or from jQuery 7 var sizzle = window.Sizzle || jQuery.find; 8 9 // Set the number of sizzle selectors to cache (default is 50) 10 //sizzle.selectors.cacheLength = 50; 11 12 var queryData = {}; 13 14 var cssRules = null; 15 16 var setCssRules = function () { 17 if (document.styleSheets[0]) { 18 cssRules = (document.styleSheets[0].cssRules !== undefined) ? "cssRules" : "rules"; 19 } 20 } 21 22 var addQueryDataValue = function (selector, type, pair, number, value) { 23 24 selector = trim(selector); 25 26 if (selector != "") { 27 var parts; 28 if (!number && !value) { 29 parts = /^([0-9]*.?[0-9]+)(px|em|%)$/.exec(pair) 30 if (parts != null) { 31 number = Number(parts[1]); 32 if (number + "" != "NaN") { 33 value = parts[2]; 34 } 35 } 36 } 37 38 if (value) { 39 // Compile the sizzle selector 40 if (sizzle.compile) { 41 sizzle.compile(selector); 42 } 43 44 // Update the queryData object 45 if (queryData[selector] === undefined) { 46 queryData[selector] = {}; 47 } 48 if (queryData[selector][type] === undefined) { 49 queryData[selector][type] = {}; 50 } 51 queryData[selector][type][pair] = [number, value]; 52 } 53 } 54 }; 55 56 var updateQueryData = function (data, doUpdate) { 57 58 var i, j, k; 59 for (i in data) { 60 for (j in data[i]) { 61 if (typeof data[i][j] == "string") { 62 addQueryDataValue(i, j, data[i][j]); 63 } 64 else if (typeof data[i][j] == "object") { 65 for (k = 0; k < data[i][j].length; k++) { 66 addQueryDataValue(i, j, data[i][j][k]); 67 } 68 } 69 } 70 } 71 72 if (doUpdate == true) { 73 refresh(); 74 } 75 }; 76 77 var processSelector = function (selectorText) { 78 79 if (selectorText) { 80 81 var regex = /(\[(min\-width|max\-width|min\-height|max\-height)\~\=(\'|\")([0-9]*.?[0-9]+)(px|em|%)(\'|\")\])(\[(min\-width|max\-width|min\-height|max\-height)\~\=(\'|\")([0-9]*.?[0-9]+)(px|em|%)(\'|\")\])?/gi; 82 83 // Split out the full selectors separated by a comma ',' 84 var selectors = selectorText.split(","); 85 var i, selector, result, number, prevIndex, k, tail, t; 86 for (i = 0; i < selectors.length; i++) { 87 88 selector = null; 89 prevIndex = 0; 90 k = 0; 91 while (k == 0 || result != null) { 92 result = regex.exec(selectors[i]); 93 if (result != null) { 94 95 // result[2] = min-width|max-width|min-height|max-height 96 // result[4] = number 97 // result[5] = px|em|% 98 // result[7] = has another 99 100 // Ensure that it contains a valid numeric value to compare against 101 number = Number(result[4]); 102 if (number + "" != "NaN") { 103 104 if (selector == null) { 105 // New set: update the current selector 106 selector = selectors[i].substring(prevIndex, result.index); 107 108 // Append second half of the selector 109 tail = selectors[i].substring(result.index + result[1].length); 110 if (tail.length > 0) { 111 112 t = tail.indexOf(" "); 113 if (t != 0) { 114 if (t > 0) { 115 // Take only the current part 116 tail = tail.substring(0, t); 117 } 118 119 // Remove any sibling element queries 120 tail = tail.replace(/(\[(min\-width|max\-width|min\-height|max\-height)\~\=(\'|\")([0-9]*.?[0-9]+)(px|em|%)(\'|\")\])/gi, ""); 121 selector += tail; 122 } 123 } 124 } 125 126 // Update the queryData object 127 addQueryDataValue(selector, result[2], result[4] + result[5], number, result[5]); 128 } 129 130 if (result[7] === undefined || result[7] == "") { 131 // Reached the end of the set 132 prevIndex = result.index + result[1].length; 133 selector = null; 134 } 135 else { 136 // Update result index to process next item in the set 137 regex.lastIndex = result.index + result[1].length; 138 } 139 } 140 k++; 141 } 142 } 143 } 144 }; 145 146 var processStyleSheet = function (styleSheet, force) { 147 148 if (cssRules == null) { 149 setCssRules(); 150 } 151 152 153 try { 154 if (styleSheet && styleSheet[cssRules] && styleSheet[cssRules].length > 0) { 155 156 var ownerNode = styleSheet.ownerNode || styleSheet.owningElement; 157 if (force || (ownerNode.getAttribute("data-elementquery-bypass") === null && ownerNode.getAttribute("data-elementquery-processed") === null)) { 158 159 var i, j, rule; 160 161 for (i = 0; i < styleSheet[cssRules].length; i++) { 162 rule = styleSheet[cssRules][i]; 163 164 // Check nested rules in media queries etc 165 if (rule[cssRules] && rule[cssRules].length > 0) { 166 for (j = 0; j < rule[cssRules].length; j++) { 167 processSelector(rule[cssRules][j].selectorText); 168 } 169 } 170 else { 171 processSelector(rule.selectorText); 172 } 173 } 174 175 // Flag the style sheet as processed 176 ownerNode.setAttribute("data-elementquery-processed", ""); 177 } 178 } 179 } catch(error) { 180 jQuery.console.log("Couldn't read cssRules for styleSheet : " + styleSheet.href, styleSheet); 181 } 182 183 }; 184 185 // Refactor from jQuery.trim() 186 var trim = function (text) { 187 if (text == null) { 188 return ""; 189 } 190 else { 191 var core_trim = "".trim; 192 if (core_trim && !core_trim.call("\uFEFF\xA0")) { 193 return core_trim.call(text); 194 } 195 else { 196 return (text + "").replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ""); 197 } 198 } 199 }; 200 201 // Refactor from jquery().addClass() and jquery().removeClass() 202 var clean = function (element, attr) { 203 // This expression is here for better compressibility 204 var val = element.getAttribute(attr); 205 return val ? (" " + val + " ").replace(/[\t\r\n]/g, " ") : " "; 206 }; 207 208 // Refactor from jquery().addClass() 209 var addTo = function (element, attr, value) { 210 211 if (element.nodeType === 1) { 212 var val = trim(value); 213 if (val != "") { 214 var cur = clean(element, attr); 215 216 if (cur.indexOf(" " + val + " ") < 0) { 217 // Add the value if its not already there 218 element.setAttribute(attr, trim(cur + val)); 219 } 220 } 221 } 222 }; 223 224 // Refactor from jquery().removeClass() 225 var removeFrom = function (element, attr, value) { 226 227 if (element.nodeType === 1) { 228 var val = trim(value); 229 if (val != "") { 230 var cur = clean(element, attr); 231 var updated = false;
232 while (cur.indexOf(" " + val + " ") >= 0) { 233 // Remove the value 234 cur = cur.replace(" " + val + " ", " "); 235 updated = true; 236 } 237 if (updated) { 238 // Update the attribute 239 element.setAttribute(attr, trim(cur)); 240 } 241 } 242 } 243 }; 244 245 var init = function () { 246 247 // Process the style sheets 248 var i; 249 for (i = 0; i < document.styleSheets.length; i++) { 250 processStyleSheet(document.styleSheets[i]); 251 } 252 253 refresh(); 254 } 255 256 var refresh = function () { 257 258 var i, ei, j, k, elements, element, val; 259 260 // For each selector 261 for (i in queryData) { 262 263 // Get the items matching the selector 264 elements = sizzle(i); 265 266 if (elements.length > 0) { 267 268 // For each matching element 269 for (ei = 0; ei < elements.length; ei++) { 270 element = elements[ei]; 271 272 // For each min|max-width|height string 273 for (j in queryData[i]) { 274 275 // For each number px|em|% value pair 276 for (k in queryData[i][j]) { 277 278 val = queryData[i][j][k][0]; 279 280 if (queryData[i][j][k][1] == "em") { 281 // Convert EMs to pixels 282 val = val * (window.getEmPixels ? getEmPixels(element) : 16); // NOTE: Using getEmPixels() has a small performance impact 283 } 284 285 /* NOTE: Using offsetWidth/Height so an element can be adjusted when it reaches a specific size. 286 /* For Nested queries scrollWidth/Height or clientWidth/Height may sometime be desired but are not supported. */ 287 var percentWidth = (( element.offsetWidth / element.parentNode.offsetWidth ) * 100); 288 var percentHeight = (( element.offsetHeight / element.parentNode.offsetHeight ) * 100); 289 290 291 if ( (queryData[i][j][k][1] == "px" || queryData[i][j][k][1] == "em" ) && 292 ( 293 (j == "min-width" && element.offsetWidth >= val) || 294 (j == "max-width" && element.offsetWidth <= val) || 295 (j == "min-height" && element.offsetHeight >= val) || 296 (j == "max-height" && element.offsetHeight <= val) 297 ) 298 ) { 299 // Add matching attr value 300 addTo(element, j, k); 301 } 302 else if (queryData[i][j][k][1] == "%" && 303 ( 304 (j == "min-width" && percentWidth >= val) || 305 (j == "max-width" && percentWidth <= val) || 306 (j == "min-height" && percentHeight >= val) || 307 (j == "max-height" && percentHeight <= val) 308 ) 309 ) { 310 // Add matching attr value 311 addTo(element, j, k); 312 } 313 else { 314 // Remove non-matching attr value 315 removeFrom(element, j, k); 316 } 317 } 318 } 319 } 320 } 321 } 322 323 if (!window.addEventListener && window.attachEvent) { 324 // Force a repaint in IE7 and IE8 325 var className = document.documentElement.className; 326 document.documentElement.className = " " + className; 327 document.documentElement.className = className; 328 } 329 } 330 331 // Expose some public functions 332 window.elementQuery = function (arg1, arg2) { 333 334 if (arg1 && typeof arg1 == "object") { 335 if (arg1.cssRules || arg1.rules) { 336 // Process a new style sheet 337 processStyleSheet(arg1, true); 338 339 if (arg2 == true) { 340 refresh(); 341 } 342 } else { 343 // Add new selector queries 344 updateQueryData(arg1, arg2); 345 } 346 } 347 else if (!arg1 && !arg2) { 348 refresh(); 349 } 350 }; 351 352 //NOTE: For development purposes only! 353 window.elementQuery.selectors = function () { 354 355 var data = {}; 356 var i, j, k; 357 358 // For each selector 359 for (i in queryData) { 360 361 // For each min|max-width|height string 362 for (j in queryData[i]) { 363 364 // For each number px|em|% value pair 365 for (k in queryData[i][j]) { 366 367 if (data[i] === undefined) { 368 data[i] = {}; 369 } 370 if (data[i][j] === undefined) { 371 data[i][j] = []; 372 } 373 data[i][j][data[i][j].length] = k; 374 } 375 } 376 } 377 return data; 378 }; 379 380 if (window.addEventListener) { 381 window.addEventListener("resize", refresh, false); 382 window.addEventListener("DOMContentLoaded", init, false); 383 window.addEventListener("load", init, false); 384 } 385 else if (window.attachEvent) { 386 window.attachEvent("onresize", refresh); 387 window.attachEvent("onload", init); 388 } 389}(this, document, undefined)); 390 391/*! getEmPixels | Author: Tyson Matanich (http://matanich.com), 2013 | License: MIT */ 392(function (document, documentElement) { 393 // Enable strict mode 394 "use strict"; 395 396 // Form the style on the fly to result in smaller minified file 397 var important = "!important;"; 398 var style = "position:absolute" + important + "visibility:hidden" + important + "width:1em" + important + "font-size:1em" + important + "padding:0" + important; 399 400 window.getEmPixels = function (element) { 401 402 var extraBody; 403 404 if (!element) { 405 // Emulate the documentElement to get rem value (documentElement does not work in IE6-7) 406 element = extraBody = document.createElement("body"); 407 extraBody.style.cssText = "font-size:1em" + important; 408 documentElement.insertBefore(extraBody, document.body); 409 } 410 411 // Create and style a test element 412 var testElement = document.createElement("i"); 413 testElement.style.cssText = style; 414 element.appendChild(testElement); 415 416 // Get the client width of the test element 417 var value = testElement.clientWidth; 418 419 if (extraBody) { 420 // Remove the extra body element 421 documentElement.removeChild(extraBody); 422 } 423 else { 424 // Remove the test element 425 element.removeChild(testElement); 426 } 427 428 // Return the em value in pixels 429 return value; 430 }; 431}(document, document.documentElement));
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.