planeui.patch.ie8.js 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365
  1. /*!
  2. * PlaneUI v0.1.0
  3. * @file planeui.patch.ie8.js
  4. * @description The Modern HTML5 Cross-Device Responsive Front-end UI Framework.
  5. * @license MIT License
  6. * @author Pandao
  7. * {@link https://github.com/pandao/planeui}
  8. * @updateTime 2015-06-27
  9. */
  10. /*
  11. selectivizr v1.0.2b - (c) Keith Clark, freely distributable under the terms
  12. of the MIT license.
  13. selectivizr.com
  14. */
  15. /*
  16. Notes about this source
  17. -----------------------
  18. * The #DEBUG_START and #DEBUG_END comments are used to mark blocks of code
  19. that will be removed prior to building a final release version (using a
  20. pre-compression script)
  21. References:
  22. -----------
  23. * CSS Syntax : http://www.w3.org/TR/2003/WD-css3-syntax-20030813/#style
  24. * Selectors : http://www.w3.org/TR/css3-selectors/#selectors
  25. * IE Compatability : http://msdn.microsoft.com/en-us/library/cc351024(VS.85).aspx
  26. * W3C Selector Tests : http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/
  27. */
  28. (function(win) {
  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. // =========================== Init Objects ============================
  34. var doc = document;
  35. var root = doc.documentElement;
  36. var xhr = getXHRObject();
  37. var ieVersion = /MSIE (\d+)/.exec(navigator.userAgent)[1];
  38. // If were not in standards mode, IE is too old / new or we can't create
  39. // an XMLHttpRequest object then we should get out now.
  40. if (doc.compatMode != 'CSS1Compat' || ieVersion<6 || ieVersion>8 || !xhr) {
  41. return;
  42. }
  43. // ========================= Common Objects ============================
  44. // Compatiable selector engines in order of CSS3 support. Note: '*' is
  45. // a placholder for the object key name. (basically, crude compression)
  46. var selectorEngines = {
  47. "NW" : "*.Dom.select",
  48. "MooTools" : "$$",
  49. "DOMAssistant" : "*.$",
  50. "Prototype" : "$$",
  51. "YAHOO" : "*.util.Selector.query",
  52. "Sizzle" : "*",
  53. "jQuery" : "*",
  54. "dojo" : "*.query"
  55. };
  56. var selectorMethod;
  57. var enabledWatchers = []; // array of :enabled/:disabled elements to poll
  58. var ie6PatchID = 0; // used to solve ie6's multiple class bug
  59. var patchIE6MultipleClasses = true; // if true adds class bloat to ie6
  60. var namespace = "slvzr";
  61. // Stylesheet parsing regexp's
  62. var RE_COMMENT = /(\/\*[^*]*\*+([^\/][^*]*\*+)*\/)\s*/g;
  63. var RE_IMPORT = /@import\s*(?:(?:(?:url\(\s*(['"]?)(.*)\1)\s*\))|(?:(['"])(.*)\3))[^;]*;/g;
  64. var RE_ASSET_URL = /\burl\(\s*(["']?)(?!data:)([^"')]+)\1\s*\)/g;
  65. var RE_PSEUDO_STRUCTURAL = /^:(empty|(first|last|only|nth(-last)?)-(child|of-type))$/;
  66. var RE_PSEUDO_ELEMENTS = /:(:first-(?:line|letter))/g;
  67. var RE_SELECTOR_GROUP = /(^|})\s*([^\{]*?[\[:][^{]+)/g;
  68. var RE_SELECTOR_PARSE = /([ +~>])|(:[a-z-]+(?:\(.*?\)+)?)|(\[.*?\])/g;
  69. var RE_LIBRARY_INCOMPATIBLE_PSEUDOS = /(:not\()?:(hover|enabled|disabled|focus|checked|target|active|visited|first-line|first-letter)\)?/g;
  70. var RE_PATCH_CLASS_NAME_REPLACE = /[^\w-]/g;
  71. // HTML UI element regexp's
  72. var RE_INPUT_ELEMENTS = /^(INPUT|SELECT|TEXTAREA|BUTTON)$/;
  73. var RE_INPUT_CHECKABLE_TYPES = /^(checkbox|radio)$/;
  74. // Broken attribute selector implementations (IE7/8 native [^=""], [$=""] and [*=""])
  75. var BROKEN_ATTR_IMPLEMENTATIONS = ieVersion>6 ? /[\$\^*]=(['"])\1/ : null;
  76. // Whitespace normalization regexp's
  77. var RE_TIDY_TRAILING_WHITESPACE = /([(\[+~])\s+/g;
  78. var RE_TIDY_LEADING_WHITESPACE = /\s+([)\]+~])/g;
  79. var RE_TIDY_CONSECUTIVE_WHITESPACE = /\s+/g;
  80. var RE_TIDY_TRIM_WHITESPACE = /^\s*((?:[\S\s]*\S)?)\s*$/;
  81. // String constants
  82. var EMPTY_STRING = "";
  83. var SPACE_STRING = " ";
  84. var PLACEHOLDER_STRING = "$1";
  85. // =========================== Patching ================================
  86. // --[ patchStyleSheet() ]----------------------------------------------
  87. // Scans the passed cssText for selectors that require emulation and
  88. // creates one or more patches for each matched selector.
  89. function patchStyleSheet( cssText ) {
  90. return cssText.replace(RE_PSEUDO_ELEMENTS, PLACEHOLDER_STRING).
  91. replace(RE_SELECTOR_GROUP, function(m, prefix, selectorText) {
  92. var selectorGroups = selectorText.split(",");
  93. for (var c = 0, cs = selectorGroups.length; c < cs; c++) {
  94. var selector = normalizeSelectorWhitespace(selectorGroups[c]) + SPACE_STRING;
  95. var patches = [];
  96. selectorGroups[c] = selector.replace(RE_SELECTOR_PARSE,
  97. function(match, combinator, pseudo, attribute, index) {
  98. if (combinator) {
  99. if (patches.length>0) {
  100. applyPatches( selector.substring(0, index), patches );
  101. patches = [];
  102. }
  103. return combinator;
  104. }
  105. else {
  106. var patch = (pseudo) ? patchPseudoClass( pseudo ) : patchAttribute( attribute );
  107. if (patch) {
  108. patches.push(patch);
  109. return "." + patch.className;
  110. }
  111. return match;
  112. }
  113. }
  114. );
  115. }
  116. return prefix + selectorGroups.join(",");
  117. });
  118. };
  119. // --[ patchAttribute() ]-----------------------------------------------
  120. // returns a patch for an attribute selector.
  121. function patchAttribute( attr ) {
  122. return (!BROKEN_ATTR_IMPLEMENTATIONS || BROKEN_ATTR_IMPLEMENTATIONS.test(attr)) ?
  123. { className: createClassName(attr), applyClass: true } : null;
  124. };
  125. // --[ patchPseudoClass() ]---------------------------------------------
  126. // returns a patch for a pseudo-class
  127. function patchPseudoClass( pseudo ) {
  128. var applyClass = true;
  129. var className = createClassName(pseudo.slice(1));
  130. var isNegated = pseudo.substring(0, 5) == ":not(";
  131. var activateEventName;
  132. var deactivateEventName;
  133. // if negated, remove :not()
  134. if (isNegated) {
  135. pseudo = pseudo.slice(5, -1);
  136. }
  137. // bracket contents are irrelevant - remove them
  138. var bracketIndex = pseudo.indexOf("(")
  139. if (bracketIndex > -1) {
  140. pseudo = pseudo.substring(0, bracketIndex);
  141. }
  142. // check we're still dealing with a pseudo-class
  143. if (pseudo.charAt(0) == ":") {
  144. switch (pseudo.slice(1)) {
  145. case "root":
  146. applyClass = function(e) {
  147. return isNegated ? e != root : e == root;
  148. }
  149. break;
  150. case "target":
  151. // :target is only supported in IE8
  152. if (ieVersion == 8) {
  153. applyClass = function(e) {
  154. var handler = function() {
  155. var hash = location.hash;
  156. var hashID = hash.slice(1);
  157. return isNegated ? (hash == EMPTY_STRING || e.id != hashID) : (hash != EMPTY_STRING && e.id == hashID);
  158. };
  159. addEvent( win, "hashchange", function() {
  160. toggleElementClass(e, className, handler());
  161. })
  162. return handler();
  163. }
  164. break;
  165. }
  166. return false;
  167. case "checked":
  168. applyClass = function(e) {
  169. if (RE_INPUT_CHECKABLE_TYPES.test(e.type)) {
  170. addEvent( e, "propertychange", function() {
  171. if (event.propertyName == "checked") {
  172. toggleElementClass( e, className, e.checked !== isNegated );
  173. }
  174. })
  175. }
  176. return e.checked !== isNegated;
  177. }
  178. break;
  179. case "disabled":
  180. isNegated = !isNegated;
  181. case "enabled":
  182. applyClass = function(e) {
  183. if (RE_INPUT_ELEMENTS.test(e.tagName)) {
  184. addEvent( e, "propertychange", function() {
  185. if (event.propertyName == "$disabled") {
  186. toggleElementClass( e, className, e.$disabled === isNegated );
  187. }
  188. });
  189. enabledWatchers.push(e);
  190. e.$disabled = e.disabled;
  191. return e.disabled === isNegated;
  192. }
  193. return pseudo == ":enabled" ? isNegated : !isNegated;
  194. }
  195. break;
  196. case "focus":
  197. activateEventName = "focus";
  198. deactivateEventName = "blur";
  199. case "hover":
  200. if (!activateEventName) {
  201. activateEventName = "mouseenter";
  202. deactivateEventName = "mouseleave";
  203. }
  204. applyClass = function(e) {
  205. addEvent( e, isNegated ? deactivateEventName : activateEventName, function() {
  206. toggleElementClass( e, className, true );
  207. })
  208. addEvent( e, isNegated ? activateEventName : deactivateEventName, function() {
  209. toggleElementClass( e, className, false );
  210. })
  211. return isNegated;
  212. }
  213. break;
  214. // everything else
  215. default:
  216. // If we don't support this pseudo-class don't create
  217. // a patch for it
  218. if (!RE_PSEUDO_STRUCTURAL.test(pseudo)) {
  219. return false;
  220. }
  221. break;
  222. }
  223. }
  224. return { className: className, applyClass: applyClass };
  225. };
  226. // --[ applyPatches() ]-------------------------------------------------
  227. // uses the passed selector text to find DOM nodes and patch them
  228. function applyPatches(selectorText, patches) {
  229. var elms;
  230. // Although some selector libraries can find :checked :enabled etc.
  231. // we need to find all elements that could have that state because
  232. // it can be changed by the user.
  233. var domSelectorText = selectorText.replace(RE_LIBRARY_INCOMPATIBLE_PSEUDOS, EMPTY_STRING);
  234. // If the dom selector equates to an empty string or ends with
  235. // whitespace then we need to append a universal selector (*) to it.
  236. if (domSelectorText == EMPTY_STRING || domSelectorText.charAt(domSelectorText.length - 1) == SPACE_STRING) {
  237. domSelectorText += "*";
  238. }
  239. // Ensure we catch errors from the selector library
  240. try {
  241. elms = selectorMethod( domSelectorText );
  242. } catch (ex) {
  243. // #DEBUG_START
  244. log( "Selector '" + selectorText + "' threw exception '" + ex + "'" );
  245. // #DEBUG_END
  246. }
  247. if (elms) {
  248. for (var d = 0, dl = elms.length; d < dl; d++) {
  249. var elm = elms[d];
  250. var cssClasses = elm.className;
  251. for (var f = 0, fl = patches.length; f < fl; f++) {
  252. var patch = patches[f];
  253. if (!hasPatch(elm, patch)) {
  254. if (patch.applyClass && (patch.applyClass === true || patch.applyClass(elm) === true)) {
  255. cssClasses = toggleClass(cssClasses, patch.className, true );
  256. }
  257. }
  258. }
  259. elm.className = cssClasses;
  260. }
  261. }
  262. };
  263. // --[ hasPatch() ]-----------------------------------------------------
  264. // checks for the exsistence of a patch on an element
  265. function hasPatch( elm, patch ) {
  266. return new RegExp("(^|\\s)" + patch.className + "(\\s|$)").test(elm.className);
  267. };
  268. // =========================== Utility =================================
  269. function createClassName( className ) {
  270. return namespace + "-" + ((ieVersion == 6 && patchIE6MultipleClasses) ?
  271. ie6PatchID++
  272. :
  273. className.replace(RE_PATCH_CLASS_NAME_REPLACE, function(a) { return a.charCodeAt(0) }));
  274. };
  275. // --[ log() ]----------------------------------------------------------
  276. // #DEBUG_START
  277. function log( message ) {
  278. if (win.console) {
  279. win.console.log(message);
  280. }
  281. };
  282. // #DEBUG_END
  283. // --[ trim() ]---------------------------------------------------------
  284. // removes leading, trailing whitespace from a string
  285. function trim( text ) {
  286. return text.replace(RE_TIDY_TRIM_WHITESPACE, PLACEHOLDER_STRING);
  287. };
  288. // --[ normalizeWhitespace() ]------------------------------------------
  289. // removes leading, trailing and consecutive whitespace from a string
  290. function normalizeWhitespace( text ) {
  291. return trim(text).replace(RE_TIDY_CONSECUTIVE_WHITESPACE, SPACE_STRING);
  292. };
  293. // --[ normalizeSelectorWhitespace() ]----------------------------------
  294. // tidies whitespace around selector brackets and combinators
  295. function normalizeSelectorWhitespace( selectorText ) {
  296. return normalizeWhitespace(selectorText.
  297. replace(RE_TIDY_TRAILING_WHITESPACE, PLACEHOLDER_STRING).
  298. replace(RE_TIDY_LEADING_WHITESPACE, PLACEHOLDER_STRING)
  299. );
  300. };
  301. // --[ toggleElementClass() ]-------------------------------------------
  302. // toggles a single className on an element
  303. function toggleElementClass( elm, className, on ) {
  304. var oldClassName = elm.className;
  305. var newClassName = toggleClass(oldClassName, className, on);
  306. if (newClassName != oldClassName) {
  307. elm.className = newClassName;
  308. elm.parentNode.className += EMPTY_STRING;
  309. }
  310. };
  311. // --[ toggleClass() ]--------------------------------------------------
  312. // adds / removes a className from a string of classNames. Used to
  313. // manage multiple class changes without forcing a DOM redraw
  314. function toggleClass( classList, className, on ) {
  315. var re = RegExp("(^|\\s)" + className + "(\\s|$)");
  316. var classExists = re.test(classList);
  317. if (on) {
  318. return classExists ? classList : classList + SPACE_STRING + className;
  319. } else {
  320. return classExists ? trim(classList.replace(re, PLACEHOLDER_STRING)) : classList;
  321. }
  322. };
  323. // --[ addEvent() ]-----------------------------------------------------
  324. function addEvent(elm, eventName, eventHandler) {
  325. elm.attachEvent("on" + eventName, eventHandler);
  326. };
  327. // --[ getXHRObject() ]-------------------------------------------------
  328. function getXHRObject()
  329. {
  330. if (win.XMLHttpRequest) {
  331. return new XMLHttpRequest;
  332. }
  333. try {
  334. return new ActiveXObject('Microsoft.XMLHTTP');
  335. } catch(e) {
  336. return null;
  337. }
  338. };
  339. // --[ loadStyleSheet() ]-----------------------------------------------
  340. function loadStyleSheet( url ) {
  341. xhr.open("GET", url, false);
  342. xhr.send();
  343. return (xhr.status==200) ? xhr.responseText : EMPTY_STRING;
  344. };
  345. // --[ resolveUrl() ]---------------------------------------------------
  346. // Converts a URL fragment to a fully qualified URL using the specified
  347. // context URL. Returns null if same-origin policy is broken
  348. function resolveUrl( url, contextUrl ) {
  349. function getProtocolAndHost( url ) {
  350. return url.substring(0, url.indexOf("/", 8));
  351. };
  352. // absolute path
  353. if (/^https?:\/\//i.test(url)) {
  354. return getProtocolAndHost(contextUrl) == getProtocolAndHost(url) ? url : null;
  355. }
  356. // root-relative path
  357. if (url.charAt(0)=="/") {
  358. return getProtocolAndHost(contextUrl) + url;
  359. }
  360. // relative path
  361. var contextUrlPath = contextUrl.split(/[?#]/)[0]; // ignore query string in the contextUrl
  362. if (url.charAt(0) != "?" && contextUrlPath.charAt(contextUrlPath.length - 1) != "/") {
  363. contextUrlPath = contextUrlPath.substring(0, contextUrlPath.lastIndexOf("/") + 1);
  364. }
  365. return contextUrlPath + url;
  366. };
  367. // --[ parseStyleSheet() ]----------------------------------------------
  368. // Downloads the stylesheet specified by the URL, removes it's comments
  369. // and recursivly replaces @import rules with their contents, ultimately
  370. // returning the full cssText.
  371. function parseStyleSheet( url ) {
  372. if (url) {
  373. return loadStyleSheet(url).replace(RE_COMMENT, EMPTY_STRING).
  374. replace(RE_IMPORT, function( match, quoteChar, importUrl, quoteChar2, importUrl2 ) {
  375. return parseStyleSheet(resolveUrl(importUrl || importUrl2, url));
  376. }).
  377. replace(RE_ASSET_URL, function( match, quoteChar, assetUrl ) {
  378. quoteChar = quoteChar || EMPTY_STRING;
  379. return " url(" + quoteChar + resolveUrl(assetUrl, url) + quoteChar + ") ";
  380. });
  381. }
  382. return EMPTY_STRING;
  383. };
  384. // --[ init() ]---------------------------------------------------------
  385. function init() {
  386. // honour the <base> tag
  387. var url, stylesheet;
  388. var baseTags = doc.getElementsByTagName("BASE");
  389. var baseUrl = (baseTags.length > 0) ? baseTags[0].href : doc.location.href;
  390. /* Note: This code prevents IE from freezing / crashing when using
  391. @font-face .eot files but it modifies the <head> tag and could
  392. trigger the IE stylesheet limit. It will also cause FOUC issues.
  393. If you choose to use it, make sure you comment out the for loop
  394. directly below this comment.
  395. var head = doc.getElementsByTagName("head")[0];
  396. for (var c=doc.styleSheets.length-1; c>=0; c--) {
  397. stylesheet = doc.styleSheets[c]
  398. head.appendChild(doc.createElement("style"))
  399. var patchedStylesheet = doc.styleSheets[doc.styleSheets.length-1];
  400. if (stylesheet.href != EMPTY_STRING) {
  401. url = resolveUrl(stylesheet.href, baseUrl)
  402. if (url) {
  403. patchedStylesheet.cssText = patchStyleSheet( parseStyleSheet( url ) )
  404. stylesheet.disabled = true
  405. setTimeout( function () {
  406. stylesheet.owningElement.parentNode.removeChild(stylesheet.owningElement)
  407. })
  408. }
  409. }
  410. }
  411. */
  412. for (var c = 0; c < doc.styleSheets.length; c++) {
  413. stylesheet = doc.styleSheets[c]
  414. if (stylesheet.href != EMPTY_STRING) {
  415. url = resolveUrl(stylesheet.href, baseUrl);
  416. if (url) {
  417. stylesheet.cssText = patchStyleSheet( parseStyleSheet( url ) );
  418. }
  419. }
  420. }
  421. // :enabled & :disabled polling script (since we can't hook
  422. // onpropertychange event when an element is disabled)
  423. if (enabledWatchers.length > 0) {
  424. setInterval( function() {
  425. for (var c = 0, cl = enabledWatchers.length; c < cl; c++) {
  426. var e = enabledWatchers[c];
  427. if (e.disabled !== e.$disabled) {
  428. if (e.disabled) {
  429. e.disabled = false;
  430. e.$disabled = true;
  431. e.disabled = true;
  432. }
  433. else {
  434. e.$disabled = e.disabled;
  435. }
  436. }
  437. }
  438. },250)
  439. }
  440. };
  441. // Bind selectivizr to the ContentLoaded event.
  442. ContentLoaded(win, function() {
  443. // Determine the "best fit" selector engine
  444. for (var engine in selectorEngines) {
  445. var members, member, context = win;
  446. if (win[engine]) {
  447. members = selectorEngines[engine].replace("*", engine).split(".");
  448. while ((member = members.shift()) && (context = context[member])) {}
  449. if (typeof context == "function") {
  450. selectorMethod = context;
  451. init();
  452. return;
  453. }
  454. }
  455. }
  456. });
  457. /*!
  458. * ContentLoaded.js by Diego Perini, modified for IE<9 only (to save space)
  459. *
  460. * Author: Diego Perini (diego.perini at gmail.com)
  461. * Summary: cross-browser wrapper for DOMContentLoaded
  462. * Updated: 20101020
  463. * License: MIT
  464. * Version: 1.2
  465. *
  466. * URL:
  467. * http://javascript.nwbox.com/ContentLoaded/
  468. * http://javascript.nwbox.com/ContentLoaded/MIT-LICENSE
  469. *
  470. */
  471. // @w window reference
  472. // @f function reference
  473. function ContentLoaded(win, fn) {
  474. var done = false, top = true,
  475. init = function(e) {
  476. if (e.type == "readystatechange" && doc.readyState != "complete") return;
  477. (e.type == "load" ? win : doc).detachEvent("on" + e.type, init, false);
  478. if (!done && (done = true)) fn.call(win, e.type || e);
  479. },
  480. poll = function() {
  481. try { root.doScroll("left"); } catch(e) { setTimeout(poll, 50); return; }
  482. init('poll');
  483. };
  484. if (doc.readyState == "complete") fn.call(win, EMPTY_STRING);
  485. else {
  486. if (doc.createEventObject && root.doScroll) {
  487. try { top = !win.frameElement; } catch(e) { }
  488. if (top) poll();
  489. }
  490. addEvent(doc,"readystatechange", init);
  491. addEvent(win,"load", init);
  492. }
  493. };
  494. })(this);
  495. /**
  496. * @preserve HTML5 Shiv 3.7.2 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
  497. */
  498. ;(function(window, document) {
  499. /*jshint evil:true */
  500. /** version */
  501. var version = '3.7.2';
  502. /** Preset options */
  503. var options = window.html5 || {};
  504. /** Used to skip problem elements */
  505. var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;
  506. /** Not all elements can be cloned in IE **/
  507. var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i;
  508. /** Detect whether the browser supports default html5 styles */
  509. var supportsHtml5Styles;
  510. /** Name of the expando, to work with multiple documents or to re-shiv one document */
  511. var expando = '_html5shiv';
  512. /** The id for the the documents expando */
  513. var expanID = 0;
  514. /** Cached data for each document */
  515. var expandoData = {};
  516. /** Detect whether the browser supports unknown elements */
  517. var supportsUnknownElements;
  518. (function() {
  519. try {
  520. var a = document.createElement('a');
  521. a.innerHTML = '<xyz></xyz>';
  522. //if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles
  523. supportsHtml5Styles = ('hidden' in a);
  524. supportsUnknownElements = a.childNodes.length == 1 || (function() {
  525. // assign a false positive if unable to shiv
  526. (document.createElement)('a');
  527. var frag = document.createDocumentFragment();
  528. return (
  529. typeof frag.cloneNode == 'undefined' ||
  530. typeof frag.createDocumentFragment == 'undefined' ||
  531. typeof frag.createElement == 'undefined'
  532. );
  533. }());
  534. } catch(e) {
  535. // assign a false positive if detection fails => unable to shiv
  536. supportsHtml5Styles = true;
  537. supportsUnknownElements = true;
  538. }
  539. }());
  540. /*--------------------------------------------------------------------------*/
  541. /**
  542. * Creates a style sheet with the given CSS text and adds it to the document.
  543. * @private
  544. * @param {Document} ownerDocument The document.
  545. * @param {String} cssText The CSS text.
  546. * @returns {StyleSheet} The style element.
  547. */
  548. function addStyleSheet(ownerDocument, cssText) {
  549. var p = ownerDocument.createElement('p'),
  550. parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
  551. p.innerHTML = 'x<style>' + cssText + '</style>';
  552. return parent.insertBefore(p.lastChild, parent.firstChild);
  553. }
  554. /**
  555. * Returns the value of `html5.elements` as an array.
  556. * @private
  557. * @returns {Array} An array of shived element node names.
  558. */
  559. function getElements() {
  560. var elements = html5.elements;
  561. return typeof elements == 'string' ? elements.split(' ') : elements;
  562. }
  563. /**
  564. * Extends the built-in list of html5 elements
  565. * @memberOf html5
  566. * @param {String|Array} newElements whitespace separated list or array of new element names to shiv
  567. * @param {Document} ownerDocument The context document.
  568. */
  569. function addElements(newElements, ownerDocument) {
  570. var elements = html5.elements;
  571. if(typeof elements != 'string'){
  572. elements = elements.join(' ');
  573. }
  574. if(typeof newElements != 'string'){
  575. newElements = newElements.join(' ');
  576. }
  577. html5.elements = elements +' '+ newElements;
  578. shivDocument(ownerDocument);
  579. }
  580. /**
  581. * Returns the data associated to the given document
  582. * @private
  583. * @param {Document} ownerDocument The document.
  584. * @returns {Object} An object of data.
  585. */
  586. function getExpandoData(ownerDocument) {
  587. var data = expandoData[ownerDocument[expando]];
  588. if (!data) {
  589. data = {};
  590. expanID++;
  591. ownerDocument[expando] = expanID;
  592. expandoData[expanID] = data;
  593. }
  594. return data;
  595. }
  596. /**
  597. * returns a shived element for the given nodeName and document
  598. * @memberOf html5
  599. * @param {String} nodeName name of the element
  600. * @param {Document} ownerDocument The context document.
  601. * @returns {Object} The shived element.
  602. */
  603. function createElement(nodeName, ownerDocument, data){
  604. if (!ownerDocument) {
  605. ownerDocument = document;
  606. }
  607. if(supportsUnknownElements){
  608. return ownerDocument.createElement(nodeName);
  609. }
  610. if (!data) {
  611. data = getExpandoData(ownerDocument);
  612. }
  613. var node;
  614. if (data.cache[nodeName]) {
  615. node = data.cache[nodeName].cloneNode();
  616. } else if (saveClones.test(nodeName)) {
  617. node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
  618. } else {
  619. node = data.createElem(nodeName);
  620. }
  621. // Avoid adding some elements to fragments in IE < 9 because
  622. // * Attributes like `name` or `type` cannot be set/changed once an element
  623. // is inserted into a document/fragment
  624. // * Link elements with `src` attributes that are inaccessible, as with
  625. // a 403 response, will cause the tab/window to crash
  626. // * Script elements appended to fragments will execute when their `src`
  627. // or `text` property is set
  628. return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node;
  629. }
  630. /**
  631. * returns a shived DocumentFragment for the given document
  632. * @memberOf html5
  633. * @param {Document} ownerDocument The context document.
  634. * @returns {Object} The shived DocumentFragment.
  635. */
  636. function createDocumentFragment(ownerDocument, data){
  637. if (!ownerDocument) {
  638. ownerDocument = document;
  639. }
  640. if(supportsUnknownElements){
  641. return ownerDocument.createDocumentFragment();
  642. }
  643. data = data || getExpandoData(ownerDocument);
  644. var clone = data.frag.cloneNode(),
  645. i = 0,
  646. elems = getElements(),
  647. l = elems.length;
  648. for(;i<l;i++){
  649. clone.createElement(elems[i]);
  650. }
  651. return clone;
  652. }
  653. /**
  654. * Shivs the `createElement` and `createDocumentFragment` methods of the document.
  655. * @private
  656. * @param {Document|DocumentFragment} ownerDocument The document.
  657. * @param {Object} data of the document.
  658. */
  659. function shivMethods(ownerDocument, data) {
  660. if (!data.cache) {
  661. data.cache = {};
  662. data.createElem = ownerDocument.createElement;
  663. data.createFrag = ownerDocument.createDocumentFragment;
  664. data.frag = data.createFrag();
  665. }
  666. ownerDocument.createElement = function(nodeName) {
  667. //abort shiv
  668. if (!html5.shivMethods) {
  669. return data.createElem(nodeName);
  670. }
  671. return createElement(nodeName, ownerDocument, data);
  672. };
  673. ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' +
  674. 'var n=f.cloneNode(),c=n.createElement;' +
  675. 'h.shivMethods&&(' +
  676. // unroll the `createElement` calls
  677. getElements().join().replace(/[\w\-:]+/g, function(nodeName) {
  678. data.createElem(nodeName);
  679. data.frag.createElement(nodeName);
  680. return 'c("' + nodeName + '")';
  681. }) +
  682. ');return n}'
  683. )(html5, data.frag);
  684. }
  685. /*--------------------------------------------------------------------------*/
  686. /**
  687. * Shivs the given document.
  688. * @memberOf html5
  689. * @param {Document} ownerDocument The document to shiv.
  690. * @returns {Document} The shived document.
  691. */
  692. function shivDocument(ownerDocument) {
  693. if (!ownerDocument) {
  694. ownerDocument = document;
  695. }
  696. var data = getExpandoData(ownerDocument);
  697. if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) {
  698. data.hasCSS = !!addStyleSheet(ownerDocument,
  699. // corrects block display not defined in IE6/7/8/9
  700. 'article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}' +
  701. // adds styling not present in IE6/7/8/9
  702. 'mark{background:#FF0;color:#000}' +
  703. // hides non-rendered elements
  704. 'template{display:none}'
  705. );
  706. }
  707. if (!supportsUnknownElements) {
  708. shivMethods(ownerDocument, data);
  709. }
  710. return ownerDocument;
  711. }
  712. /*--------------------------------------------------------------------------*/
  713. /**
  714. * The `html5` object is exposed so that more elements can be shived and
  715. * existing shiving can be detected on iframes.
  716. * @type Object
  717. * @example
  718. *
  719. * // options can be changed before the script is included
  720. * html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false };
  721. */
  722. var html5 = {
  723. /**
  724. * An array or space separated string of node names of the elements to shiv.
  725. * @memberOf html5
  726. * @type Array|String
  727. */
  728. 'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video',
  729. /**
  730. * current version of html5shiv
  731. */
  732. 'version': version,
  733. /**
  734. * A flag to indicate that the HTML5 style sheet should be inserted.
  735. * @memberOf html5
  736. * @type Boolean
  737. */
  738. 'shivCSS': (options.shivCSS !== false),
  739. /**
  740. * Is equal to true if a browser supports creating unknown/HTML5 elements
  741. * @memberOf html5
  742. * @type boolean
  743. */
  744. 'supportsUnknownElements': supportsUnknownElements,
  745. /**
  746. * A flag to indicate that the document's `createElement` and `createDocumentFragment`
  747. * methods should be overwritten.
  748. * @memberOf html5
  749. * @type Boolean
  750. */
  751. 'shivMethods': (options.shivMethods !== false),
  752. /**
  753. * A string to describe the type of `html5` object ("default" or "default print").
  754. * @memberOf html5
  755. * @type String
  756. */
  757. 'type': 'default',
  758. // shivs the document according to the specified `html5` object options
  759. 'shivDocument': shivDocument,
  760. //creates a shived element
  761. createElement: createElement,
  762. //creates a shived documentFragment
  763. createDocumentFragment: createDocumentFragment,
  764. //extends list of elements
  765. addElements: addElements
  766. };
  767. /*--------------------------------------------------------------------------*/
  768. // expose html5
  769. window.html5 = html5;
  770. // shiv the document
  771. shivDocument(document);
  772. /*------------------------------- Print Shiv -------------------------------*/
  773. /** Used to filter media types */
  774. var reMedia = /^$|\b(?:all|print)\b/;
  775. /** Used to namespace printable elements */
  776. var shivNamespace = 'html5shiv';
  777. /** Detect whether the browser supports shivable style sheets */
  778. var supportsShivableSheets = !supportsUnknownElements && (function() {
  779. // assign a false negative if unable to shiv
  780. var docEl = document.documentElement;
  781. return !(
  782. typeof document.namespaces == 'undefined' ||
  783. typeof document.parentWindow == 'undefined' ||
  784. typeof docEl.applyElement == 'undefined' ||
  785. typeof docEl.removeNode == 'undefined' ||
  786. typeof window.attachEvent == 'undefined'
  787. );
  788. }());
  789. /*--------------------------------------------------------------------------*/
  790. /**
  791. * Wraps all HTML5 elements in the given document with printable elements.
  792. * (eg. the "header" element is wrapped with the "html5shiv:header" element)
  793. * @private
  794. * @param {Document} ownerDocument The document.
  795. * @returns {Array} An array wrappers added.
  796. */
  797. function addWrappers(ownerDocument) {
  798. var node,
  799. nodes = ownerDocument.getElementsByTagName('*'),
  800. index = nodes.length,
  801. reElements = RegExp('^(?:' + getElements().join('|') + ')$', 'i'),
  802. result = [];
  803. while (index--) {
  804. node = nodes[index];
  805. if (reElements.test(node.nodeName)) {
  806. result.push(node.applyElement(createWrapper(node)));
  807. }
  808. }
  809. return result;
  810. }
  811. /**
  812. * Creates a printable wrapper for the given element.
  813. * @private
  814. * @param {Element} element The element.
  815. * @returns {Element} The wrapper.
  816. */
  817. function createWrapper(element) {
  818. var node,
  819. nodes = element.attributes,
  820. index = nodes.length,
  821. wrapper = element.ownerDocument.createElement(shivNamespace + ':' + element.nodeName);
  822. // copy element attributes to the wrapper
  823. while (index--) {
  824. node = nodes[index];
  825. node.specified && wrapper.setAttribute(node.nodeName, node.nodeValue);
  826. }
  827. // copy element styles to the wrapper
  828. wrapper.style.cssText = element.style.cssText;
  829. return wrapper;
  830. }
  831. /**
  832. * Shivs the given CSS text.
  833. * (eg. header{} becomes html5shiv\:header{})
  834. * @private
  835. * @param {String} cssText The CSS text to shiv.
  836. * @returns {String} The shived CSS text.
  837. */
  838. function shivCssText(cssText) {
  839. var pair,
  840. parts = cssText.split('{'),
  841. index = parts.length,
  842. reElements = RegExp('(^|[\\s,>+~])(' + getElements().join('|') + ')(?=[[\\s,>+~#.:]|$)', 'gi'),
  843. replacement = '$1' + shivNamespace + '\\:$2';
  844. while (index--) {
  845. pair = parts[index] = parts[index].split('}');
  846. pair[pair.length - 1] = pair[pair.length - 1].replace(reElements, replacement);
  847. parts[index] = pair.join('}');
  848. }
  849. return parts.join('{');
  850. }
  851. /**
  852. * Removes the given wrappers, leaving the original elements.
  853. * @private
  854. * @params {Array} wrappers An array of printable wrappers.
  855. */
  856. function removeWrappers(wrappers) {
  857. var index = wrappers.length;
  858. while (index--) {
  859. wrappers[index].removeNode();
  860. }
  861. }
  862. /*--------------------------------------------------------------------------*/
  863. /**
  864. * Shivs the given document for print.
  865. * @memberOf html5
  866. * @param {Document} ownerDocument The document to shiv.
  867. * @returns {Document} The shived document.
  868. */
  869. function shivPrint(ownerDocument) {
  870. var shivedSheet,
  871. wrappers,
  872. data = getExpandoData(ownerDocument),
  873. namespaces = ownerDocument.namespaces,
  874. ownerWindow = ownerDocument.parentWindow;
  875. if (!supportsShivableSheets || ownerDocument.printShived) {
  876. return ownerDocument;
  877. }
  878. if (typeof namespaces[shivNamespace] == 'undefined') {
  879. namespaces.add(shivNamespace);
  880. }
  881. function removeSheet() {
  882. clearTimeout(data._removeSheetTimer);
  883. if (shivedSheet) {
  884. shivedSheet.removeNode(true);
  885. }
  886. shivedSheet= null;
  887. }
  888. ownerWindow.attachEvent('onbeforeprint', function() {
  889. removeSheet();
  890. var imports,
  891. length,
  892. sheet,
  893. collection = ownerDocument.styleSheets,
  894. cssText = [],
  895. index = collection.length,
  896. sheets = Array(index);
  897. // convert styleSheets collection to an array
  898. while (index--) {
  899. sheets[index] = collection[index];
  900. }
  901. // concat all style sheet CSS text
  902. while ((sheet = sheets.pop())) {
  903. // IE does not enforce a same origin policy for external style sheets...
  904. // but has trouble with some dynamically created stylesheets
  905. if (!sheet.disabled && reMedia.test(sheet.media)) {
  906. try {
  907. imports = sheet.imports;
  908. length = imports.length;
  909. } catch(er){
  910. length = 0;
  911. }
  912. for (index = 0; index < length; index++) {
  913. sheets.push(imports[index]);
  914. }
  915. try {
  916. cssText.push(sheet.cssText);
  917. } catch(er){}
  918. }
  919. }
  920. // wrap all HTML5 elements with printable elements and add the shived style sheet
  921. cssText = shivCssText(cssText.reverse().join(''));
  922. wrappers = addWrappers(ownerDocument);
  923. shivedSheet = addStyleSheet(ownerDocument, cssText);
  924. });
  925. ownerWindow.attachEvent('onafterprint', function() {
  926. // remove wrappers, leaving the original elements, and remove the shived style sheet
  927. removeWrappers(wrappers);
  928. clearTimeout(data._removeSheetTimer);
  929. data._removeSheetTimer = setTimeout(removeSheet, 500);
  930. });
  931. ownerDocument.printShived = true;
  932. return ownerDocument;
  933. }
  934. /*--------------------------------------------------------------------------*/
  935. // expose API
  936. html5.type += ' print';
  937. html5.shivPrint = shivPrint;
  938. // shiv for print
  939. shivPrint(document);
  940. }(this, document));
  941. /*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */
  942. /*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */
  943. (function(w) {
  944. "use strict";
  945. w.matchMedia = w.matchMedia || function(doc, undefined) {
  946. var bool, docElem = doc.documentElement, refNode = docElem.firstElementChild || docElem.firstChild, fakeBody = doc.createElement("body"), div = doc.createElement("div");
  947. div.id = "mq-test-1";
  948. div.style.cssText = "position:absolute;top:-100em";
  949. fakeBody.style.background = "none";
  950. fakeBody.appendChild(div);
  951. return function(q) {
  952. div.innerHTML = '&shy;<style media="' + q + '"> #mq-test-1 { width: 42px; }</style>';
  953. docElem.insertBefore(fakeBody, refNode);
  954. bool = div.offsetWidth === 42;
  955. docElem.removeChild(fakeBody);
  956. return {
  957. matches: bool,
  958. media: q
  959. };
  960. };
  961. }(w.document);
  962. })(this);
  963. /*! matchMedia() polyfill addListener/removeListener extension. Author & copyright (c) 2012: Scott Jehl. Dual MIT/BSD license */
  964. (function(w) {
  965. "use strict";
  966. if (w.matchMedia && w.matchMedia("all").addListener) {
  967. return false;
  968. }
  969. var localMatchMedia = w.matchMedia, hasMediaQueries = localMatchMedia("only all").matches, isListening = false, timeoutID = 0, queries = [], handleChange = function(evt) {
  970. w.clearTimeout(timeoutID);
  971. timeoutID = w.setTimeout(function() {
  972. for (var i = 0, il = queries.length; i < il; i++) {
  973. var mql = queries[i].mql, listeners = queries[i].listeners || [], matches = localMatchMedia(mql.media).matches;
  974. if (matches !== mql.matches) {
  975. mql.matches = matches;
  976. for (var j = 0, jl = listeners.length; j < jl; j++) {
  977. listeners[j].call(w, mql);
  978. }
  979. }
  980. }
  981. }, 30);
  982. };
  983. w.matchMedia = function(media) {
  984. var mql = localMatchMedia(media), listeners = [], index = 0;
  985. mql.addListener = function(listener) {
  986. if (!hasMediaQueries) {
  987. return;
  988. }
  989. if (!isListening) {
  990. isListening = true;
  991. w.addEventListener("resize", handleChange, true);
  992. }
  993. if (index === 0) {
  994. index = queries.push({
  995. mql: mql,
  996. listeners: listeners
  997. });
  998. }
  999. listeners.push(listener);
  1000. };
  1001. mql.removeListener = function(listener) {
  1002. for (var i = 0, il = listeners.length; i < il; i++) {
  1003. if (listeners[i] === listener) {
  1004. listeners.splice(i, 1);
  1005. }
  1006. }
  1007. };
  1008. return mql;
  1009. };
  1010. })(this);
  1011. /*! Respond.js v1.4.0: min/max-width media query polyfill. (c) Scott Jehl. MIT Lic. j.mp/respondjs */
  1012. (function(w) {
  1013. "use strict";
  1014. var respond = {};
  1015. w.respond = respond;
  1016. respond.update = function() {};
  1017. var requestQueue = [], xmlHttp = function() {
  1018. var xmlhttpmethod = false;
  1019. try {
  1020. xmlhttpmethod = new w.XMLHttpRequest();
  1021. } catch (e) {
  1022. xmlhttpmethod = new w.ActiveXObject("Microsoft.XMLHTTP");
  1023. }
  1024. return function() {
  1025. return xmlhttpmethod;
  1026. };
  1027. }(), ajax = function(url, callback) {
  1028. var req = xmlHttp();
  1029. if (!req) {
  1030. return;
  1031. }
  1032. req.open("GET", url, true);
  1033. req.onreadystatechange = function() {
  1034. if (req.readyState !== 4 || req.status !== 200 && req.status !== 304) {
  1035. return;
  1036. }
  1037. callback(req.responseText);
  1038. };
  1039. if (req.readyState === 4) {
  1040. return;
  1041. }
  1042. req.send(null);
  1043. };
  1044. respond.ajax = ajax;
  1045. respond.queue = requestQueue;
  1046. respond.regex = {
  1047. media: /@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,
  1048. keyframes: /@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,
  1049. urls: /(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,
  1050. findStyles: /@media *([^\{]+)\{([\S\s]+?)$/,
  1051. only: /(only\s+)?([a-zA-Z]+)\s?/,
  1052. minw: /\([\s]*min\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/,
  1053. maxw: /\([\s]*max\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/
  1054. };
  1055. respond.mediaQueriesSupported = w.matchMedia && w.matchMedia("only all") !== null && w.matchMedia("only all").matches;
  1056. if (respond.mediaQueriesSupported) {
  1057. return;
  1058. }
  1059. var doc = w.document, docElem = doc.documentElement, mediastyles = [], rules = [], appendedEls = [], parsedSheets = {}, resizeThrottle = 30, head = doc.getElementsByTagName("head")[0] || docElem, base = doc.getElementsByTagName("base")[0], links = head.getElementsByTagName("link"), lastCall, resizeDefer, eminpx, getEmValue = function() {
  1060. var ret, div = doc.createElement("div"), body = doc.body, originalHTMLFontSize = docElem.style.fontSize, originalBodyFontSize = body && body.style.fontSize, fakeUsed = false;
  1061. div.style.cssText = "position:absolute;font-size:1em;width:1em";
  1062. if (!body) {
  1063. body = fakeUsed = doc.createElement("body");
  1064. body.style.background = "none";
  1065. }
  1066. docElem.style.fontSize = "100%";
  1067. body.style.fontSize = "100%";
  1068. body.appendChild(div);
  1069. if (fakeUsed) {
  1070. docElem.insertBefore(body, docElem.firstChild);
  1071. }
  1072. ret = div.offsetWidth;
  1073. if (fakeUsed) {
  1074. docElem.removeChild(body);
  1075. } else {
  1076. body.removeChild(div);
  1077. }
  1078. docElem.style.fontSize = originalHTMLFontSize;
  1079. if (originalBodyFontSize) {
  1080. body.style.fontSize = originalBodyFontSize;
  1081. }
  1082. ret = eminpx = parseFloat(ret);
  1083. return ret;
  1084. }, applyMedia = function(fromResize) {
  1085. var name = "clientWidth", docElemProp = docElem[name], currWidth = doc.compatMode === "CSS1Compat" && docElemProp || doc.body[name] || docElemProp, styleBlocks = {}, lastLink = links[links.length - 1], now = new Date().getTime();
  1086. if (fromResize && lastCall && now - lastCall < resizeThrottle) {
  1087. w.clearTimeout(resizeDefer);
  1088. resizeDefer = w.setTimeout(applyMedia, resizeThrottle);
  1089. return;
  1090. } else {
  1091. lastCall = now;
  1092. }
  1093. for (var i in mediastyles) {
  1094. if (mediastyles.hasOwnProperty(i)) {
  1095. var thisstyle = mediastyles[i], min = thisstyle.minw, max = thisstyle.maxw, minnull = min === null, maxnull = max === null, em = "em";
  1096. if (!!min) {
  1097. min = parseFloat(min) * (min.indexOf(em) > -1 ? eminpx || getEmValue() : 1);
  1098. }
  1099. if (!!max) {
  1100. max = parseFloat(max) * (max.indexOf(em) > -1 ? eminpx || getEmValue() : 1);
  1101. }
  1102. if (!thisstyle.hasquery || (!minnull || !maxnull) && (minnull || currWidth >= min) && (maxnull || currWidth <= max)) {
  1103. if (!styleBlocks[thisstyle.media]) {
  1104. styleBlocks[thisstyle.media] = [];
  1105. }
  1106. styleBlocks[thisstyle.media].push(rules[thisstyle.rules]);
  1107. }
  1108. }
  1109. }
  1110. for (var j in appendedEls) {
  1111. if (appendedEls.hasOwnProperty(j)) {
  1112. if (appendedEls[j] && appendedEls[j].parentNode === head) {
  1113. head.removeChild(appendedEls[j]);
  1114. }
  1115. }
  1116. }
  1117. appendedEls.length = 0;
  1118. for (var k in styleBlocks) {
  1119. if (styleBlocks.hasOwnProperty(k)) {
  1120. var ss = doc.createElement("style"), css = styleBlocks[k].join("\n");
  1121. ss.type = "text/css";
  1122. ss.media = k;
  1123. head.insertBefore(ss, lastLink.nextSibling);
  1124. if (ss.styleSheet) {
  1125. ss.styleSheet.cssText = css;
  1126. } else {
  1127. ss.appendChild(doc.createTextNode(css));
  1128. }
  1129. appendedEls.push(ss);
  1130. }
  1131. }
  1132. }, translate = function(styles, href, media) {
  1133. var qs = styles.replace(respond.regex.keyframes, "").match(respond.regex.media), ql = qs && qs.length || 0;
  1134. href = href.substring(0, href.lastIndexOf("/"));
  1135. var repUrls = function(css) {
  1136. return css.replace(respond.regex.urls, "$1" + href + "$2$3");
  1137. }, useMedia = !ql && media;
  1138. if (href.length) {
  1139. href += "/";
  1140. }
  1141. if (useMedia) {
  1142. ql = 1;
  1143. }
  1144. for (var i = 0; i < ql; i++) {
  1145. var fullq, thisq, eachq, eql;
  1146. if (useMedia) {
  1147. fullq = media;
  1148. rules.push(repUrls(styles));
  1149. } else {
  1150. fullq = qs[i].match(respond.regex.findStyles) && RegExp.$1;
  1151. rules.push(RegExp.$2 && repUrls(RegExp.$2));
  1152. }
  1153. eachq = fullq.split(",");
  1154. eql = eachq.length;
  1155. for (var j = 0; j < eql; j++) {
  1156. thisq = eachq[j];
  1157. mediastyles.push({
  1158. media: thisq.split("(")[0].match(respond.regex.only) && RegExp.$2 || "all",
  1159. rules: rules.length - 1,
  1160. hasquery: thisq.indexOf("(") > -1,
  1161. minw: thisq.match(respond.regex.minw) && parseFloat(RegExp.$1) + (RegExp.$2 || ""),
  1162. maxw: thisq.match(respond.regex.maxw) && parseFloat(RegExp.$1) + (RegExp.$2 || "")
  1163. });
  1164. }
  1165. }
  1166. applyMedia();
  1167. }, makeRequests = function() {
  1168. if (requestQueue.length) {
  1169. var thisRequest = requestQueue.shift();
  1170. ajax(thisRequest.href, function(styles) {
  1171. translate(styles, thisRequest.href, thisRequest.media);
  1172. parsedSheets[thisRequest.href] = true;
  1173. w.setTimeout(function() {
  1174. makeRequests();
  1175. }, 0);
  1176. });
  1177. }
  1178. }, ripCSS = function() {
  1179. for (var i = 0; i < links.length; i++) {
  1180. var sheet = links[i], href = sheet.href, media = sheet.media, isCSS = sheet.rel && sheet.rel.toLowerCase() === "stylesheet";
  1181. if (!!href && isCSS && !parsedSheets[href]) {
  1182. if (sheet.styleSheet && sheet.styleSheet.rawCssText) {
  1183. translate(sheet.styleSheet.rawCssText, href, media);
  1184. parsedSheets[href] = true;
  1185. } else {
  1186. if (!/^([a-zA-Z:]*\/\/)/.test(href) && !base || href.replace(RegExp.$1, "").split("/")[0] === w.location.host) {
  1187. if (href.substring(0, 2) === "//") {
  1188. href = w.location.protocol + href;
  1189. }
  1190. requestQueue.push({
  1191. href: href,
  1192. media: media
  1193. });
  1194. }
  1195. }
  1196. }
  1197. }
  1198. makeRequests();
  1199. };
  1200. ripCSS();
  1201. respond.update = ripCSS;
  1202. respond.getEmValue = getEmValue;
  1203. function callMedia() {
  1204. applyMedia(true);
  1205. }
  1206. if (w.addEventListener) {
  1207. w.addEventListener("resize", callMedia, false);
  1208. } else if (w.attachEvent) {
  1209. w.attachEvent("onresize", callMedia);
  1210. }
  1211. })(this);