vendor: 23,309 bytes, lines 1-561
1/* 2selectivizr v1.0.2 - (c) Keith Clark, freely distributable under the terms 3of the MIT license. 4 5selectivizr.com 6*/ 7/* 8 9Notes about this source 10----------------------- 11 12 * The #DEBUG_START and #DEBUG_END comments are used to mark blocks of code 13 that will be removed prior to building a final release version (using a 14 pre-compression script) 15 16 17References: 18----------- 19 20 * CSS Syntax : http://www.w3.org/TR/2003/WD-css3-syntax-20030813/#style 21 * Selectors : http://www.w3.org/TR/css3-selectors/#selectors 22 * IE Compatability : http://msdn.microsoft.com/en-us/library/cc351024(VS.85).aspx 23 * W3C Selector Tests : http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/ 24 25*/ 26 27(function(win) { 28 29 // If browser isn't IE, then stop execution! This handles the script 30 // being loaded by non IE browsers because the developer didn't use 31 // conditional comments. 32 if (/*@cc_on!@*/true) return; 33 34 // =========================== Init Objects ============================ 35 36 var doc = document; 37 var root = doc.documentElement; 38 var xhr = getXHRObject(); 39 var ieVersion = /MSIE (\d+)/.exec(navigator.userAgent)[1]; 40 41 // If were not in standards mode, IE is too old / new or we can't create 42 // an XMLHttpRequest object then we should get out now. 43 if (doc.compatMode != 'CSS1Compat' || ieVersion<6 || ieVersion>8 || !xhr) { 44 return; 45 } 46 47 48 // ========================= Common Objects ============================ 49 50 // Compatiable selector engines in order of CSS3 support. Note: '*' is 51 // a placholder for the object key name. (basically, crude compression) 52 var selectorEngines = { 53 "NW" : "*.Dom.select", 54 "MooTools" : "$$", 55 "DOMAssistant" : "*.$", 56 "Prototype" : "$$", 57 "YAHOO" : "*.util.Selector.query", 58 "Sizzle" : "*", 59 "jQuery" : "*", 60 "dojo" : "*.query" 61 }; 62 63 var selectorMethod; 64 var enabledWatchers = []; // array of :enabled/:disabled elements to poll 65 var ie6PatchID = 0; // used to solve ie6's multiple class bug 66 var patchIE6MultipleClasses = true; // if true adds class bloat to ie6 67 var namespace = "slvzr"; 68 69 // Stylesheet parsing regexp's 70 var RE_COMMENT = /(\/\*[^*]*\*+([^\/][^*]*\*+)*\/)\s*/g; 71 var RE_IMPORT = /@import\s*(?:(?:(?:url\(\s*(['"]?)(.*)\1)\s*\))|(?:(['"])(.*)\3))[^;]*;/g; 72 var RE_ASSET_URL = /\burl\(\s*(["']?)(?!data:)([^"')]+)\1\s*\)/g; 73 var RE_PSEUDO_STRUCTURAL = /^:(empty|(first|last|only|nth(-last)?)-(child|of-type))$/; 74 var RE_PSEUDO_ELEMENTS = /:(:first-(?:line|letter))/g; 75 var RE_SELECTOR_GROUP = /(^|})\s*([^\{]*?[\[:][^{]+)/g; 76 var RE_SELECTOR_PARSE = /([ +~>])|(:[a-z-]+(?:\(.*?\)+)?)|(\[.*?\])/g; 77 var RE_LIBRARY_INCOMPATIBLE_PSEUDOS = /(:not\()?:(hover|enabled|disabled|focus|checked|target|active|visited|first-line|first-letter)\)?/g; 78 var RE_PATCH_CLASS_NAME_REPLACE = /[^\w-]/g; 79 80 // HTML UI element regexp's 81 var RE_INPUT_ELEMENTS = /^(INPUT|SELECT|TEXTAREA|BUTTON)$/; 82 var RE_INPUT_CHECKABLE_TYPES = /^(checkbox|radio)$/; 83 84 // Broken attribute selector implementations (IE7/8 native [^=""], [$=""] and [*=""]) 85 var BROKEN_ATTR_IMPLEMENTATIONS = ieVersion>6 ? /[\$\^*]=(['"])\1/ : null; 86 87 // Whitespace normalization regexp's 88 var RE_TIDY_TRAILING_WHITESPACE = /([(\[+~])\s+/g; 89 var RE_TIDY_LEADING_WHITESPACE = /\s+([)\]+~])/g; 90 var RE_TIDY_CONSECUTIVE_WHITESPACE = /\s+/g; 91 var RE_TIDY_TRIM_WHITESPACE = /^\s*((?:[\S\s]*\S)?)\s*$/; 92 93 // String constants 94 var EMPTY_STRING = ""; 95 var SPACE_STRING = " "; 96 var PLACEHOLDER_STRING = "$1"; 97 98 // =========================== Patching ================================ 99 100 // --[ patchStyleSheet() ]---------------------------------------------- 101 // Scans the passed cssText for selectors that require emulation and 102 // creates one or more patches for each matched selector. 103 function patchStyleSheet( cssText ) { 104 return cssText.replace(RE_PSEUDO_ELEMENTS, PLACEHOLDER_STRING). 105 replace(RE_SELECTOR_GROUP, function(m, prefix, selectorText) { 106 var selectorGroups = selectorText.split(","); 107 for (var c = 0, cs = selectorGroups.length; c < cs; c++) { 108 var selector = normalizeSelectorWhitespace(selectorGroups[c]) + SPACE_STRING; 109 var patches = []; 110 selectorGroups[c] = selector.replace(RE_SELECTOR_PARSE, 111 function(match, combinator, pseudo, attribute, index) { 112 if (combinator) { 113 if (patches.length>0) { 114 applyPatches( selector.substring(0, index), patches ); 115 patches = []; 116 } 117 return combinator; 118 } 119 else { 120 var patch = (pseudo) ? patchPseudoClass( pseudo ) : patchAttribute( attribute ); 121 if (patch) { 122 patches.push(patch); 123 return "." + patch.className; 124 } 125 return match; 126 } 127 } 128 ); 129 } 130 return prefix + selectorGroups.join(","); 131 }); 132 }; 133 134 // --[ patchAttribute() ]----------------------------------------------- 135 // returns a patch for an attribute selector. 136 function patchAttribute( attr ) { 137 return (!BROKEN_ATTR_IMPLEMENTATIONS || BROKEN_ATTR_IMPLEMENTATIONS.test(attr)) ? 138 { className: createClassName(attr), applyClass: true } : null; 139 }; 140 141 // --[ patchPseudoClass() ]--------------------------------------------- 142 // returns a patch for a pseudo-class 143 function patchPseudoClass( pseudo ) { 144 145 var applyClass = true; 146 var className = createClassName(pseudo.slice(1)); 147 var isNegated = pseudo.substring(0, 5) == ":not("; 148 var activateEventName; 149 var deactivateEventName; 150 151 // if negated, remove :not() 152 if (isNegated) { 153 pseudo = pseudo.slice(5, -1); 154 } 155 156 // bracket contents are irrelevant - remove them 157 var bracketIndex = pseudo.indexOf("(") 158 if (bracketIndex > -1) { 159 pseudo = pseudo.substring(0, bracketIndex); 160 } 161 162 // check we're still dealing with a pseudo-class 163 if (pseudo.charAt(0) == ":") { 164 switch (pseudo.slice(1)) { 165 166 case "root": 167 applyClass = function(e) { 168 return isNegated ? e != root : e == root; 169 } 170 break; 171 172 case "target": 173 // :target is only supported in IE8 174 if (ieVersion == 8) { 175 applyClass = function(e) { 176 var handler = function() { 177 var hash = location.hash; 178 var hashID = hash.slice(1); 179 return isNegated ? (hash == EMPTY_STRING || e.id != hashID) : (hash != EMPTY_STRING && e.id == hashID); 180 }; 181 addEvent( win, "hashchange", function() { 182 toggleElementClass(e, className, handler()); 183 }) 184 return handler(); 185 } 186 break; 187 } 188 return false; 189 190 case "checked": 191 applyClass = function(e) { 192 if (RE_INPUT_CHECKABLE_TYPES.test(e.type)) { 193 addEvent( e, "propertychange", function() { 194 if (event.propertyName == "checked") { 195 toggleElementClass( e, className, e.checked !== isNegated ); 196 } 197 }) 198 } 199 return e.checked !== isNegated; 200 } 201 break; 202 203 case "disabled": 204 isNegated = !isNegated; 205 206 case "enabled": 207 applyClass = function(e) { 208 if (RE_INPUT_ELEMENTS.test(e.tagName)) { 209 addEvent( e, "propertychange", function() { 210 if (event.propertyName == "$disabled") { 211 toggleElementClass( e, className, e.$disabled === isNegated ); 212 } 213 }); 214 enabledWatchers.push(e); 215 e.$disabled = e.disabled; 216 return e.disabled === isNegated; 217 } 218 return pseudo == ":enabled" ? isNegated : !isNegated; 219 } 220 break; 221 222 case "focus": 223 activateEventName = "focus"; 224 deactivateEventName = "blur"; 225 226 case "hover": 227 if (!activateEventName) { 228 activateEventName = "mouseenter"; 229 deactivateEventName = "mouseleave"; 230 } 231 applyClass = function(e) { 232 addEvent( e, isNegated ? deactivateEventName : activateEventName, function() { 233 toggleElementClass( e, className, true ); 234 }) 235 addEvent( e, isNegated ? activateEventName : deactivateEventName, function() { 236 toggleElementClass( e, className, false ); 237 }) 238 return isNegated; 239 } 240 break; 241 242 // everything else 243 default: 244 // If we don't support this pseudo-class don't create 245 // a patch for it 246 if (!RE_PSEUDO_STRUCTURAL.test(pseudo)) { 247 return false; 248 } 249 break; 250 } 251 } 252 return { className: className, applyClass: applyClass }; 253 }; 254 255 // --[ applyPatches() ]------------------------------------------------- 256 // uses the passed selector text to find DOM nodes and patch them 257 function applyPatches(selectorText, patches) { 258 var elms; 259 260 // Although some selector libraries can find :checked :enabled etc. 261 // we need to find all elements that could have that state because 262 // it can be changed by the user. 263 var domSelectorText = selectorText.replace(RE_LIBRARY_INCOMPATIBLE_PSEUDOS, EMPTY_STRING); 264 265 // If the dom selector equates to an empty string or ends with 266 // whitespace then we need to append a universal selector (*) to it. 267 if (domSelectorText == EMPTY_STRING || domSelectorText.charAt(domSelectorText.length - 1) == SPACE_STRING) { 268 domSelectorText += "*"; 269 } 270 271 // Ensure we catch errors from the selector library 272 try { 273 elms = selectorMethod( domSelectorText ); 274 } catch (ex) { 275 // #DEBUG_START 276 log( "Selector '" + selectorText + "' threw exception '" + ex + "'" ); 277 // #DEBUG_END 278 } 279 280 281 if (elms) { 282 for (var d = 0, dl = elms.length; d < dl; d++) { 283 var elm = elms[d]; 284 var cssClasses = elm.className; 285 for (var f = 0, fl = patches.length; f < fl; f++) { 286 var patch = patches[f]; 287 288 if (!hasPatch(elm, patch)) { 289 if (patch.applyClass && (patch.applyClass === true || patch.applyClass(elm) === true)) { 290 cssClasses = toggleClass(cssClasses, patch.className, true ); 291 } 292 } 293 } 294 elm.className = cssClasses; 295 } 296 } 297 }; 298 299 // --[ hasPatch() ]----------------------------------------------------- 300 // checks for the exsistence of a patch on an element 301 function hasPatch( elm, patch ) { 302 return new RegExp("(^|\\s)" + patch.className + "(\\s|$)").test(elm.className); 303 }; 304 305 306 // =========================== Utility ================================= 307 308 function createClassName( className ) { 309 return namespace + "-" + ((ieVersion == 6 && patchIE6MultipleClasses) ? 310 ie6PatchID++ 311 : 312 className.replace(RE_PATCH_CLASS_NAME_REPLACE, function(a) { return a.charCodeAt(0) })); 313 }; 314 315 // --[ log() ]---------------------------------------------------------- 316 // #DEBUG_START 317 function log( message ) { 318 if (win.console) { 319 win.console.log(message); 320 } 321 }; 322 // #DEBUG_END 323 324 // --[ trim() ]--------------------------------------------------------- 325 // removes leading, trailing whitespace from a string 326 function trim( text ) { 327 return text.replace(RE_TIDY_TRIM_WHITESPACE, PLACEHOLDER_STRING); 328 }; 329 330 // --[ normalizeWhitespace() ]------------------------------------------ 331 // removes leading, trailing and consecutive whitespace from a string 332 function normalizeWhitespace( text ) { 333 return trim(text).replace(RE_TIDY_CONSECUTIVE_WHITESPACE, SPACE_STRING); 334 }; 335 336 // --[ normalizeSelectorWhitespace() ]---------------------------------- 337 // tidies whitespace around selector brackets and combinators 338 function normalizeSelectorWhitespace( selectorText ) { 339 return normalizeWhitespace(selectorText. 340 replace(RE_TIDY_TRAILING_WHITESPACE, PLACEHOLDER_STRING). 341 replace(RE_TIDY_LEADING_WHITESPACE, PLACEHOLDER_STRING) 342 ); 343 }; 344 345 // --[ toggleElementClass() ]------------------------------------------- 346 // toggles a single className on an element 347 function toggleElementClass( elm, className, on ) { 348 var oldClassName = elm.className; 349 var newClassName = toggleClass(oldClassName, className, on); 350 if (newClassName != oldClassName) { 351 elm.className = newClassName; 352 elm.parentNode.className += EMPTY_STRING; 353 } 354 }; 355 356 // --[ toggleClass() ]-------------------------------------------------- 357 // adds / removes a className from a string of classNames. Used to 358 // manage multiple class changes without forcing a DOM redraw 359 function toggleClass( classList, className, on ) { 360 var re = RegExp("(^|\\s)" + className + "(\\s|$)"); 361 var classExists = re.test(classList); 362 if (on) { 363 return classExists ? classList : classList + SPACE_STRING + className; 364 } else { 365 return classExists ? trim(classList.replace(re, PLACEHOLDER_STRING)) : classList; 366 } 367 }; 368 369 // --[ addEvent() ]----------------------------------------------------- 370 function addEvent(elm, eventName, eventHandler) { 371 elm.attachEvent("on" + eventName, eventHandler); 372 }; 373 374 // --[ getXHRObject() ]------------------------------------------------- 375 function getXHRObject() 376 { 377 if (win.XMLHttpRequest) { 378 return new XMLHttpRequest; 379 } 380 try { 381 return new ActiveXObject('Microsoft.XMLHTTP'); 382 } catch(e) { 383 return null; 384 } 385 }; 386 387 // --[ loadStyleSheet() ]----------------------------------------------- 388 function loadStyleSheet( url ) { 389 xhr.open("GET", url, false); 390 xhr.send(); 391 return (xhr.status==200) ? xhr.responseText : EMPTY_STRING; 392 }; 393 394 // --[ resolveUrl() ]--------------------------------------------------- 395 // Converts a URL fragment to a fully qualified URL using the specified 396 // context URL. Returns null if same-origin policy is broken 397 function resolveUrl( url, contextUrl ) { 398 399 function getProtocolAndHost( url ) { 400 return url.substring(0, url.indexOf("/", 8)); 401 }; 402 403 // absolute path 404 if (/^https?:\/\//i.test(url)) { 405 return getProtocolAndHost(contextUrl) == getProtocolAndHost(url) ? url : null; 406 } 407 408 // root-relative path 409 if (url.charAt(0)=="/") { 410 return getProtocolAndHost(contextUrl) + url; 411 } 412 413 // relative path 414 var contextUrlPath = contextUrl.split(/[?#]/)[0]; // ignore query string in the contextUrl 415 if (url.charAt(0) != "?" && contextUrlPath.charAt(contextUrlPath.length - 1) != "/") { 416 contextUrlPath = contextUrlPath.substring(0, contextUrlPath.lastIndexOf("/") + 1); 417 } 418 419 return contextUrlPath + url; 420 }; 421 422 // --[ parseStyleSheet() ]---------------------------------------------- 423 // Downloads the stylesheet specified by the URL, removes it's comments 424 // and recursivly replaces @import rules with their contents, ultimately 425 // returning the full cssText. 426 function parseStyleSheet( url ) { 427 if (url) { 428 return loadStyleSheet(url).replace(RE_COMMENT, EMPTY_STRING). 429 replace(RE_IMPORT, function( match, quoteChar, importUrl, quoteChar2, importUrl2 ) { 430 return parseStyleSheet(resolveUrl(importUrl || importUrl2, url)); 431 }). 432 replace(RE_ASSET_URL, function( match, quoteChar, assetUrl ) { 433 quoteChar = quoteChar || EMPTY_STRING; 434 return " url(" + quoteChar + resolveUrl(assetUrl, url) + quoteChar + ") "; 435 }); 436 } 437 return EMPTY_STRING; 438 }; 439 440 // --[ init() ]--------------------------------------------------------- 441 function init() { 442 // honour the <base> tag 443 var url, stylesheet; 444 var baseTags = doc.getElementsByTagName("BASE"); 445 var baseUrl = (baseTags.length > 0) ? baseTags[0].href : doc.location.href; 446 447 /* Note: This code prevents IE from freezing / crashing when using 448 @font-face .eot files but it modifies the <head> tag and could 449 trigger the IE stylesheet limit. It will also cause FOUC issues. 450 If you choose to use it, make sure you comment out the for loop 451 directly below this comment. 452 453 var head = doc.getElementsByTagName("head")[0]; 454 for (var c=doc.styleSheets.length-1; c>=0; c--) { 455 stylesheet = doc.styleSheets[c] 456 head.appendChild(doc.createElement("style")) 457 var patchedStylesheet = doc.styleSheets[doc.styleSheets.length-1]; 458 459 if (stylesheet.href != EMPTY_STRING) { 460 url = resolveUrl(stylesheet.href, baseUrl) 461 if (url) { 462 patchedStylesheet.cssText = patchStyleSheet( parseStyleSheet( url ) ) 463 stylesheet.disabled = true 464 setTimeout( function () { 465 stylesheet.owningElement.parentNode.removeChild(stylesheet.owningElement) 466 }) 467 } 468 } 469 } 470 */ 471 472 for (var c = 0; c < doc.styleSheets.length; c++) { 473 stylesheet = doc.styleSheets[c] 474 if (stylesheet.href != EMPTY_STRING) { 475 url = resolveUrl(stylesheet.href, baseUrl); 476 if (url) { 477 stylesheet.cssText = patchStyleSheet( parseStyleSheet( url ) ); 478 } 479 } 480 } 481 482 // :enabled & :disabled polling script (since we can't hook 483 // onpropertychange event when an element is disabled) 484 if (enabledWatchers.length > 0) { 485 setInterval( function() { 486 for (var c = 0, cl = enabledWatchers.length; c < cl; c++) { 487 var e = enabledWatchers[c]; 488 if (e.disabled !== e.$disabled) { 489 if (e.disabled) { 490 e.disabled = false; 491 e.$disabled = true; 492 e.disabled = true; 493 } 494 else { 495 e.$disabled = e.disabled; 496 } 497 } 498 } 499 },250) 500 } 501 }; 502 503 // Bind selectivizr to the ContentLoaded event. 504 ContentLoaded(win, function() { 505 // Determine the "best fit" selector engine 506 for (var engine in selectorEngines) { 507 var members, member, context = win; 508 if (win[engine]) { 509 members = selectorEngines[engine].replace("*", engine).split("."); 510 while ((member = members.shift()) && (context = context[member])) {} 511 if (typeof context == "function") { 512 selectorMethod = context; 513 init(); 514 return; 515 } 516 } 517 } 518 }); 519 520 521 /*! 522 * ContentLoaded.js by Diego Perini, modified for IE<9 only (to save space) 523 * 524 * Author: Diego Perini (diego.perini at gmail.com) 525 * Summary: cross-browser wrapper for DOMContentLoaded 526 * Updated: 20101020 527 * License: MIT 528 * Version: 1.2 529 * 530 * URL: 531 * http://javascript.nwbox.com/ContentLoaded/ 532 * http://javascript.nwbox.com/ContentLoaded/MIT-LICENSE 533 * 534 */ 535 536 // @w window reference 537 // @f function reference 538 function ContentLoaded(win, fn) { 539 540 var done = false, top = true, 541 init = function(e) { 542 if (e.type == "readystatechange" && doc.readyState != "complete") return; 543 (e.type == "load" ? win : doc).detachEvent("on" + e.type, init, false); 544 if (!done && (done = true)) fn.call(win, e.type || e); 545 }, 546 poll = function() { 547 try { root.doScroll("left"); } catch(e) { setTimeout(poll, 50); return; } 548 init('poll'); 549 }; 550 551 if (doc.readyState == "complete") fn.call(win, EMPTY_STRING); 552 else { 553 if (doc.createEventObject && root.doScroll) { 554 try { top = !win.frameElement; } catch(e) { } 555 if (top) poll(); 556 } 557 addEvent(doc,"readystatechange", init); 558 addEvent(win,"load", init); 559 } 560 }; 561})(this);
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.