找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 6390|回复: 3

google ie9.js下载 使IE5,IE6,IE7,IE8兼容到IE9模式

  [复制链接]
发表于 2015-11-13 13:50:31 | 显示全部楼层 |阅读模式
ie9.js的主要作用是:使IE5,IE6,IE7,IE8兼容到IE9模式


点此下载ie9.js:
ie9.js (118.66 KB, 下载次数: )
使用方法:
  1. <!--[if lt IE 9]>
  2. <script src="ie9.js"></script>
  3. <![endif]-->
复制代码

JS代码如下:
  1. (function(window, document) {

  2.     var IE7 = window.IE7 = {
  3.         version: "2.1(beta4)",
  4.         toString: K("[IE7]")
  5.     };
  6.     IE7.compat = 9;

  7.     var appV = navigator.appVersion.match(/MSIE (\d\.\d)/);
  8.     var appVersion = IE7.appVersion = (appV != null) ? appV[1] - 0 : 0;

  9.     if (/ie7_off/.test(top.location.search) || appVersion < 5.5 || appVersion >= IE7.compat) return;

  10.     var MSIE5 = appVersion < 6;

  11.     var Undefined = K();
  12.     var documentElement = document.documentElement, body, viewport;
  13.     var ANON = "!";
  14.     var HEADER = ":link{ie7-link:link}:visited{ie7-link:visited}";

  15. // -----------------------------------------------------------------------
  16. // external
  17. // -----------------------------------------------------------------------

  18.     var RELATIVE = /^[\w\.]+[^:]*$/;
  19.     function makePath(href, path) {
  20.         if (RELATIVE.test(href)) href = (path || "") + href;
  21.         return href;
  22.     };

  23.     function getPath(href, path) {
  24.         href = makePath(href, path);
  25.         return href.slice(0, href.lastIndexOf("/") + 1);
  26.     };

  27. // Get the path to this script
  28.     var script = document.scripts[document.scripts.length - 1];
  29.     var path = getPath(script.src);

  30. // Use microsoft's http request object to load external files
  31.     try {
  32.         var httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
  33.     } catch (ex) {
  34.         // ActiveX disabled
  35.     }

  36.     var fileCache = {};
  37.     function loadFile(href, path) {
  38.         try {
  39.             href = makePath(href, path);
  40.             if (!fileCache[href]) {
  41.                 httpRequest.open("GET", href, false);
  42.                 httpRequest.send();
  43.                 if (httpRequest.status == 0 || httpRequest.status == 200) {
  44.                     fileCache[href] = httpRequest.responseText;
  45.                 }
  46.             }
  47.         } catch (ex) {
  48.             // ignore errors
  49.         }
  50.         return fileCache[href] || "";
  51.     };

  52. // -----------------------------------------------------------------------
  53. // OO support
  54. // -----------------------------------------------------------------------


  55. // This is a cut-down version of base2 (http://code.google.com/p/base2/)

  56.     var _slice = Array.prototype.slice;

  57. // private
  58.     var _FORMAT = /%([1-9])/g;
  59.     var _LTRIM = /^\s\s*/;
  60.     var _RTRIM = /\s\s*$/;
  61.     var _RESCAPE = /([\/()[\]{}|*+-.,^$?\\])/g;           // safe regular expressions
  62.     var _BASE = /\bbase\b/;
  63.     var _HIDDEN = ["constructor", "toString"];            // only override these when prototyping

  64.     var prototyping;

  65.     function Base(){};
  66.     Base.extend = function(_instance, _static) {
  67.         // Build the prototype.
  68.         prototyping = true;
  69.         var _prototype = new this;
  70.         extend(_prototype, _instance);
  71.         prototyping = false;

  72.         // Create the wrapper for the constructor function.
  73.         var _constructor = _prototype.constructor;
  74.         function klass() {
  75.             // Don't call the constructor function when prototyping.
  76.             if (!prototyping) _constructor.apply(this, arguments);
  77.         };
  78.         _prototype.constructor = klass;

  79.         // Build the static interface.
  80.         klass.extend = arguments.callee;
  81.         extend(klass, _static);
  82.         klass.prototype = _prototype;
  83.         return klass;
  84.     };
  85.     Base.prototype.extend = function(source) {
  86.         return extend(this, source);
  87.     };


  88. // A collection of regular expressions and their associated replacement values.
  89. // A Base class for creating parsers.

  90.     var HASH     = "#";
  91.     var ITEMS    = "#";
  92.     var KEYS     = ".";
  93.     var COMPILED = "/";

  94.     var REGGRP_BACK_REF        = /\\(\d+)/g,
  95.         REGGRP_ESCAPE_COUNT    = /\[(\\.|[^\]\\])+\]|\\.|\(\?/g,
  96.         REGGRP_PAREN           = /\(/g,
  97.         REGGRP_LOOKUP          = /\$(\d+)/,
  98.         REGGRP_LOOKUP_SIMPLE   = /^\$\d+$/,
  99.         REGGRP_LOOKUPS         = /(\[(\\.|[^\]\\])+\]|\\.|\(\?)|\(/g,
  100.         REGGRP_DICT_ENTRY      = /^<#\w+>$/,
  101.         REGGRP_DICT_ENTRIES    = /<#(\w+)>/g;

  102.     var RegGrp = Base.extend({
  103.         constructor: function(values) {
  104.             this[KEYS] = [];
  105.             this[ITEMS] = {};
  106.             this.merge(values);
  107.         },

  108.         //dictionary: null,
  109.         //ignoreCase: false,

  110.         add: function(expression, replacement) {
  111.             delete this[COMPILED];
  112.             if (expression instanceof RegExp) {
  113.                 expression = expression.source;
  114.             }
  115.             if (!this[HASH + expression]) this[KEYS].push(String(expression));
  116.             return this[ITEMS][HASH + expression] = new RegGrp.Item(expression, replacement, this);
  117.         },

  118.         compile: function(recompile) {
  119.             if (recompile || !this[COMPILED]) {
  120.                 this[COMPILED] = new RegExp(this, this.ignoreCase ? "gi" : "g");
  121.             }
  122.             return this[COMPILED];
  123.         },

  124.         merge: function(values) {
  125.             for (var i in values) this.add(i, values[i]);
  126.         },

  127.         exec: function(string) {
  128.             var group = this,
  129.                 patterns = group[KEYS],
  130.                 items = group[ITEMS], item;
  131.             var result = this.compile(true).exec(string);
  132.             if (result) {
  133.                 // Loop through the RegGrp items.
  134.                 var i = 0, offset = 1;
  135.                 while ((item = items[HASH + patterns[i++]])) {
  136.                     var next = offset + item.length + 1;
  137.                     if (result[offset]) { // do we have a result?
  138.                         if (item.replacement === 0) {
  139.                             return group.exec(string);
  140.                         } else {
  141.                             var args = result.slice(offset, next), j = args.length;
  142.                             while (--j) args[j] = args[j] || ""; // some platforms return null/undefined for non-matching sub-expressions
  143.                             args[0] = {match: args[0], item: item};
  144.                             return args;
  145.                         }
  146.                     }
  147.                     offset = next;
  148.                 }
  149.             }
  150.             return null;
  151.         },

  152.         parse: function(string) {
  153.             string += ""; // type safe
  154.             var group = this,
  155.                 patterns = group[KEYS],
  156.                 items = group[ITEMS];
  157.             return string.replace(this.compile(), function(match) {
  158.                 var args = [], item, offset = 1, i = arguments.length;
  159.                 while (--i) args[i] = arguments[i] || ""; // some platforms return null/undefined for non-matching sub-expressions
  160.                 // Loop through the RegGrp items.
  161.                 while ((item = items[HASH + patterns[i++]])) {
  162.                     var next = offset + item.length + 1;
  163.                     if (args[offset]) { // do we have a result?
  164.                         var replacement = item.replacement;
  165.                         switch (typeof replacement) {
  166.                             case "function":
  167.                                 return replacement.apply(group, args.slice(offset, next));
  168.                             case "number":
  169.                                 return args[offset + replacement];
  170.                             default:
  171.                                 return replacement;
  172.                         }
  173.                     }
  174.                     offset = next;
  175.                 }
  176.                 return match;
  177.             });
  178.         },

  179.         toString: function() {
  180.             var strings = [],
  181.                 keys = this[KEYS],
  182.                 items = this[ITEMS], item;
  183.             for (var i = 0; item = items[HASH + keys[i]]; i++) {
  184.                 strings[i] = item.source;
  185.             }
  186.             return "(" + strings.join(")|(") + ")";
  187.         }
  188.     }, {
  189.         IGNORE: null, // a null replacement value means that there is no replacement.

  190.         Item: Base.extend({
  191.             constructor: function(source, replacement, owner) {
  192.                 var length = source.indexOf("(") === -1 ? 0 : RegGrp.count(source);

  193.                 var dictionary = owner.dictionary;
  194.                 if (dictionary && source.indexOf("<#") !== -1) {
  195.                     if (REGGRP_DICT_ENTRY.test(source)) {
  196.                         var entry = dictionary[ITEMS][HASH + source.slice(2, -1)];
  197.                         source = entry.replacement;
  198.                         length = entry._length;
  199.                     } else {
  200.                         source = dictionary.parse(source);
  201.                     }
  202.                 }

  203.                 if (typeof replacement == "number") replacement = String(replacement);
  204.                 else if (replacement == null) replacement = 0;

  205.                 // Does the expression use sub-expression lookups?
  206.                 if (typeof replacement == "string" && REGGRP_LOOKUP.test(replacement)) {
  207.                     if (REGGRP_LOOKUP_SIMPLE.test(replacement)) { // A simple lookup? (e.g. "$2").
  208.                         // Store the index (used for fast retrieval of matched strings).
  209.                         var index = replacement.slice(1) - 0;
  210.                         if (index && index <= length) replacement = index;
  211.                     } else {
  212.                         // A complicated lookup (e.g. "Hello $2 $1.").
  213.                         var lookup = replacement, regexp;
  214.                         replacement = function(match) {
  215.                             if (!regexp) {
  216.                                 regexp = new RegExp(source, "g" + (this.ignoreCase ? "i": ""));
  217.                             }
  218.                             return match.replace(regexp, lookup);
  219.                         };
  220.                     }
  221.                 }

  222.                 this.length = length;
  223.                 this.source = String(source);
  224.                 this.replacement = replacement;
  225.             }
  226.         }),

  227.         count: function(expression) {
  228.             return (String(expression).replace(REGGRP_ESCAPE_COUNT, "").match(REGGRP_PAREN) || "").length;
  229.         }
  230.     });

  231.     var Dictionary = RegGrp.extend({
  232.         parse: function(phrase) {
  233.             // Prevent sub-expressions in dictionary entries from capturing.
  234.             var entries = this[ITEMS];
  235.             return phrase.replace(REGGRP_DICT_ENTRIES, function(match, entry) {
  236.                 entry = entries[HASH + entry];
  237.                 return entry ? entry._nonCapturing : match;
  238.             });
  239.         },

  240.         add: function(expression, replacement) {
  241.             // Get the underlying replacement value.
  242.             if (replacement instanceof RegExp) {
  243.                 replacement = replacement.source;
  244.             }
  245.             // Translate the replacement.
  246.             // The result is the original replacement recursively parsed by this dictionary.
  247.             var nonCapturing = replacement.replace(REGGRP_LOOKUPS, _nonCapture);
  248.             if (replacement.indexOf("(") !== -1) {
  249.                 var realLength = RegGrp.count(replacement);
  250.             }
  251.             if (replacement.indexOf("<#") !== -1) {
  252.                 replacement = this.parse(replacement);
  253.                 nonCapturing = this.parse(nonCapturing);
  254.             }
  255.             var item = this.base(expression, replacement);
  256.             item._nonCapturing = nonCapturing;
  257.             item._length = realLength || item.length; // underlying number of sub-groups
  258.             return item;
  259.         },

  260.         toString: function() {
  261.             return "(<#" + this[PATTERNS].join(">)|(<#") + ">)";
  262.         }
  263.     });

  264.     function _nonCapture(match, escaped) {
  265.         return escaped || "(?:"; // non-capturing
  266.     };

  267. // =========================================================================
  268. // lang/extend.js
  269. // =========================================================================

  270.     function extend(object, source) { // or extend(object, key, value)
  271.         if (object && source) {
  272.             var proto = (typeof source == "function" ? Function : Object).prototype;
  273.             // Add constructor, toString etc
  274.             var i = _HIDDEN.length, key;
  275.             if (prototyping) while (key = _HIDDEN[--i]) {
  276.                 var value = source[key];
  277.                 if (value != proto[key]) {
  278.                     if (_BASE.test(value)) {
  279.                         _override(object, key, value)
  280.                     } else {
  281.                         object[key] = value;
  282.                     }
  283.                 }
  284.             }
  285.             // Copy each of the source object's properties to the target object.
  286.             for (key in source) if (typeof proto[key] == "undefined") {
  287.                 var value = source[key];
  288.                 // Check for method overriding.
  289.                 if (object[key] && typeof value == "function" && _BASE.test(value)) {
  290.                     _override(object, key, value);
  291.                 } else {
  292.                     object[key] = value;
  293.                 }
  294.             }
  295.         }
  296.         return object;
  297.     };

  298.     function _override(object, name, method) {
  299.         // Override an existing method.
  300.         var ancestor = object[name];
  301.         object[name] = function() {
  302.             var previous = this.base;
  303.             this.base = ancestor;
  304.             var returnValue = method.apply(this, arguments);
  305.             this.base = previous;
  306.             return returnValue;
  307.         };
  308.     };

  309.     function combine(keys, values) {
  310.         // Combine two arrays to make a hash.
  311.         if (!values) values = keys;
  312.         var hash = {};
  313.         for (var i in keys) hash[i] = values[i];
  314.         return hash;
  315.     };

  316.     function format(string) {
  317.         // Replace %n with arguments[n].
  318.         // e.g. format("%1 %2%3 %2a %1%3", "she", "se", "lls");
  319.         // ==> "she sells sea shells"
  320.         // Only %1 - %9 supported.
  321.         var args = arguments;
  322.         var _FORMAT = new RegExp("%([1-" + arguments.length + "])", "g");
  323.         return String(string).replace(_FORMAT, function(match, index) {
  324.             return index < args.length ? args[index] : match;
  325.         });
  326.     };

  327.     function match(string, expression) {
  328.         // Same as String.match() except that this function will return an empty
  329.         // array if there is no match.
  330.         return String(string).match(expression) || [];
  331.     };

  332.     function rescape(string) {
  333.         // Make a string safe for creating a RegExp.
  334.         return String(string).replace(_RESCAPE, "\\$1");
  335.     };

  336. // http://blog.stevenlevithan.com/archives/faster-trim-javascript
  337.     function trim(string) {
  338.         return String(string).replace(_LTRIM, "").replace(_RTRIM, "");
  339.     };

  340.     function K(k) {
  341.         return function() {
  342.             return k;
  343.         };
  344.     };

  345. // -----------------------------------------------------------------------
  346. // parsing
  347. // -----------------------------------------------------------------------

  348.     var Parser = RegGrp.extend({ignoreCase: true});

  349.     var SINGLE_QUOTES       = /'/g,
  350.         ESCAPED             = /'(\d+)'/g,
  351.         ESCAPE              = /\\/g,
  352.         UNESCAPE            = /\\([nrtf'"])/g;

  353.     var strings = [];

  354.     var encoder = new Parser({
  355.         // comments
  356.         "<!\\-\\-|\\-\\->": "",
  357.         "\\/\\*[^*]*\\*+([^\\/][^*]*\\*+)*\\/": "",
  358.         // get rid
  359.         "@(namespace|import)[^;\\n]+[;\\n]": "",
  360.         // strings
  361.         "'(\\\\.|[^'\\\\])*'": encodeString,
  362.         '"(\\\\.|[^"\\\\])*"': encodeString,
  363.         // white space
  364.         "\\s+": " "
  365.     });

  366.     function encode(selector) {
  367.         return encoder.parse(selector).replace(UNESCAPE, "$1");
  368.     };

  369.     function decode(query) {
  370.         // put string values back
  371.         return query.replace(ESCAPED, decodeString);
  372.     };

  373.     function encodeString(string) {
  374.         var index = strings.length;
  375.         strings[index] = string.slice(1, -1)
  376.             .replace(UNESCAPE, "$1")
  377.             .replace(SINGLE_QUOTES, "\\'");
  378.         return "'" + index + "'";
  379.     };

  380.     function decodeString(match, index) {
  381.         var string = strings[index];
  382.         if (string == null) return match;
  383.         return "'" + strings[index] + "'";
  384.     };

  385.     function getString(value) {
  386.         return value.indexOf("'") === 0 ? strings[value.slice(1, - 1)] : value;
  387.     };

  388. // clone a "width" function to create a "height" function
  389.     var rotater = new RegGrp({
  390.         Width: "Height",
  391.         width: "height",
  392.         Left:  "Top",
  393.         left:  "top",
  394.         Right: "Bottom",
  395.         right: "bottom",
  396.         onX:   "onY"
  397.     });

  398.     function rotate(fn) {
  399.         return rotater.parse(fn);
  400.     };

  401. // -----------------------------------------------------------------------
  402. // event handling
  403. // -----------------------------------------------------------------------

  404.     var eventHandlers = [];

  405.     function addResize(handler) {
  406.         addRecalc(handler);
  407.         addEventHandler(window, "onresize", handler);
  408.     };

  409. // add an event handler (function) to an element
  410.     function addEventHandler(element, type, handler) {
  411.         element.attachEvent(type, handler);
  412.         // store the handler so it can be detached later
  413.         eventHandlers.push(arguments);
  414.     };

  415. // remove an event handler assigned to an element by IE7
  416.     function removeEventHandler(element, type, handler) {
  417.         try {
  418.             element.detachEvent(type, handler);
  419.         } catch (ex) {
  420.             // write a letter of complaint to microsoft..
  421.         }
  422.     };

  423. // remove event handlers (they eat memory)
  424.     addEventHandler(window, "onunload", function() {
  425.         var handler;
  426.         while (handler = eventHandlers.pop()) {
  427.             removeEventHandler(handler[0], handler[1], handler[2]);
  428.         }
  429.     });

  430.     function register(handler, element, condition) { // -@DRE
  431.                                                      //var set = handler[element.uniqueID];
  432.         if (!handler.elements) handler.elements = {};
  433.         if (condition) handler.elements[element.uniqueID] = element;
  434.         else delete handler.elements[element.uniqueID];
  435.         //return !set && condition;
  436.         return condition;
  437.     };

  438.     addEventHandler(window, "onbeforeprint", function() {
  439.         if (!IE7.CSS.print) new StyleSheet("print");
  440.         IE7.CSS.print.recalc();
  441.     });

  442. // -----------------------------------------------------------------------
  443. // pixel conversion
  444. // -----------------------------------------------------------------------

  445. // this is handy because it means that web developers can mix and match
  446. //  measurement units in their style sheets. it is not uncommon to
  447. //  express something like padding in "em" units whilst border thickness
  448. //  is most often expressed in pixels.

  449.     var PIXEL = /^\d+(px)?$/i;
  450.     var PERCENT = /^\d+%$/;
  451.     var getPixelValue = function(element, value) {
  452.         if (PIXEL.test(value)) return parseInt(value);
  453.         var style = element.style.left;
  454.         var runtimeStyle = element.runtimeStyle.left;
  455.         element.runtimeStyle.left = element.currentStyle.left;
  456.         element.style.left = value || 0;
  457.         value = element.style.pixelLeft;
  458.         element.style.left = style;
  459.         element.runtimeStyle.left = runtimeStyle;
  460.         return value;
  461.     };

  462. // -----------------------------------------------------------------------
  463. // generic
  464. // -----------------------------------------------------------------------

  465.     var $IE7 = "ie7-";

  466.     var Fix = Base.extend({
  467.         constructor: function() {
  468.             this.fixes = [];
  469.             this.recalcs = [];
  470.         },
  471.         init: Undefined
  472.     });

  473. // a store for functions that will be called when refreshing IE7
  474.     var recalcs = [];
  475.     function addRecalc(recalc) {
  476.         recalcs.push(recalc);
  477.     };

  478.     IE7.recalc = function() {
  479.         IE7.HTML.recalc();
  480.         // re-apply style sheet rules (re-calculate ie7 classes)
  481.         IE7.CSS.recalc();
  482.         // apply global fixes to the document
  483.         for (var i = 0; i < recalcs.length; i++) recalcs[i]();
  484.     };

  485.     function isFixed(element) {
  486.         return element.currentStyle["ie7-position"] == "fixed";
  487.     };

  488. // original style
  489.     function getDefinedStyle(element, propertyName) {
  490.         return element.currentStyle[$IE7 + propertyName] || element.currentStyle[propertyName];
  491.     };

  492.     function setOverrideStyle(element, propertyName, value) {
  493.         if (element.currentStyle[$IE7 + propertyName] == null) {
  494.             element.runtimeStyle[$IE7 + propertyName] = element.currentStyle[propertyName];
  495.         }
  496.         element.runtimeStyle[propertyName] = value;
  497.     };

  498. // Create a temporary element which is used to inherit styles
  499. // from the target element.
  500.     function createTempElement(tagName) {
  501.         var element = document.createElement(tagName || "object");
  502.         element.style.cssText = "position:absolute;padding:0;display:block;border:none;clip:rect(0 0 0 0);left:-9999";
  503.         element.ie7_anon = true;
  504.         return element;
  505.     };


  506. // =========================================================================
  507. // ie7-css.js
  508. // =========================================================================

  509.     var NEXT_SIBLING        = "(e.nextSibling&&IE7._getElementSibling(e,'next'))",
  510.         PREVIOUS_SIBLING    = NEXT_SIBLING.replace(/next/g, "previous"),
  511.         IS_ELEMENT          = "e.nodeName>'@'",
  512.         IF_ELEMENT          = "if(" + IS_ELEMENT + "){";

  513.     var ID_ATTRIBUTE  = "(e.nodeName==='FORM'?IE7._getAttribute(e,'id'):e.id)";

  514.     var HYPERLINK = /a(#[\w-]+)?(\.[\w-]+)?:(hover|active)/i;
  515.     var FIRST_LINE_LETTER = /(.*)(:first-(line|letter))/;
  516.     var SPACE = /\s/;
  517.     var RULE = /((?:\\.|[^{\\])+)\{((?:\\.|[^}\\])+)\}/g;
  518.     var SELECTOR = /(?:\\.|[^,\\])+/g;

  519.     var styleSheets = document.styleSheets;

  520.     var inheritedProperties = [];

  521.     IE7.CSS = new (Fix.extend({ // single instance
  522.         parser: new Parser,
  523.         screen: "",
  524.         print: "",
  525.         styles: [],
  526.         rules: [],
  527.         pseudoClasses: appVersion < 7 ? "first\\-child" : "",
  528.         dynamicPseudoClasses: {
  529.             toString: function() {
  530.                 var strings = [];
  531.                 for (var pseudoClass in this) strings.push(pseudoClass);
  532.                 return strings.join("|");
  533.             }
  534.         },

  535.         init: function() {
  536.             var NONE = "^\x01$";
  537.             var CLASS = "\\[class=?[^\\]]*\\]";
  538.             var pseudoClasses = [];
  539.             if (this.pseudoClasses) pseudoClasses.push(this.pseudoClasses);
  540.             var dynamicPseudoClasses = this.dynamicPseudoClasses.toString();
  541.             if (dynamicPseudoClasses) pseudoClasses.push(dynamicPseudoClasses);
  542.             pseudoClasses = pseudoClasses.join("|");
  543.             var unknown = appVersion < 7 ? ["[>+~\\[(]|([:.])[\\w-]+\\1"] : [CLASS];
  544.             if (pseudoClasses) unknown.push(":(" + pseudoClasses + ")");
  545.             this.UNKNOWN = new RegExp(unknown.join("|") || NONE, "i");
  546.             var complex = appVersion < 7 ? ["\\[[^\\]]+\\]|[^\\s(\\[]+\\s*[+~]"] : [CLASS];
  547.             var complexRule = complex.concat();
  548.             if (pseudoClasses) complexRule.push(":(" + pseudoClasses + ")");
  549.             Rule.COMPLEX = new RegExp(complexRule.join("|") || NONE, "ig");
  550.             if (this.pseudoClasses) complex.push(":(" + this.pseudoClasses + ")");
  551.             DynamicRule.COMPLEX = new RegExp(complex.join("|") || NONE, "i");
  552.             dynamicPseudoClasses = "not\\(:" + dynamicPseudoClasses.split("|").join("\\)|not\\(:") + "\\)|" + dynamicPseudoClasses;
  553.             DynamicRule.MATCH = new RegExp(dynamicPseudoClasses ? "(.*?):(" + dynamicPseudoClasses + ")(.*)" : NONE, "i");

  554.             this.createStyleSheet();
  555.             this.refresh();
  556.         },

  557.         addEventHandler: function() {
  558.             addEventHandler.apply(null, arguments);
  559.         },

  560.         addFix: function(expression, replacement) {
  561.             this.parser.add(expression, replacement);
  562.         },

  563.         addRecalc: function(propertyName, test, handler, replacement) {
  564.             // recalcs occur whenever the document is refreshed using document.recalc()
  565.             propertyName = propertyName.source || propertyName;
  566.             test = new RegExp("([{;\\s])" + propertyName + "\\s*:\\s*" + test + "[^;}]*");
  567.             var id = this.recalcs.length;
  568.             if (typeof replacement == "string") replacement = propertyName + ":" + replacement;
  569.             this.addFix(test, function(match) {
  570.                 if (typeof replacement == "function") replacement = replacement(match);
  571.                 return (replacement ? replacement : match) + ";ie7-" + match.slice(1) + ";ie7_recalc" + id + ":1";
  572.             });
  573.             this.recalcs.push(arguments);
  574.             return id;
  575.         },

  576.         apply: function() {
  577.             this.getInlineCSS();
  578.             new StyleSheet("screen");
  579.             this.trash();
  580.         },

  581.         createStyleSheet: function() {
  582.             // create the IE7 style sheet
  583.             document.getElementsByTagName("head")[0].appendChild(document.createElement("style"));
  584.             this.styleSheet = styleSheets[styleSheets.length - 1];
  585.             // flag it so we can ignore it during parsing
  586.             this.styleSheet.ie7 = true;
  587.             this.styleSheet.owningElement.ie7 = true;
  588.             this.styleSheet.cssText = HEADER;
  589.         },

  590.         getInlineCSS: function() {// load inline styles
  591.             var styleSheets = document.getElementsByTagName("style"), styleSheet;
  592.             for (var i = styleSheets.length - 1; styleSheet = styleSheets[i]; i--) {
  593.                 if (!styleSheet.disabled && !styleSheet.ie7) {
  594.                     styleSheet._cssText = styleSheet.innerHTML;
  595.                 }
  596.             }
  597.         },

  598.         getText: function(styleSheet, path) {
  599.             // Internet Explorer will trash unknown selectors (it converts them to "UNKNOWN").
  600.             // So we must reload external style sheets (internal style sheets can have their text
  601.             // extracted through the innerHTML property).

  602.             // load the style sheet text from an external file
  603.             try {
  604.                 var cssText = styleSheet.cssText;
  605.             } catch (e) {
  606.                 cssText = "";
  607.             }
  608.             if (httpRequest) cssText = loadFile(styleSheet.href, path) || cssText;
  609.             return cssText;
  610.         },

  611.         recalc: function() {
  612.             this.screen.recalc();
  613.             // we're going to read through all style rules.
  614.             //  certain rules have had ie7 properties added to them.
  615.             //   e.g. p{top:0; ie7_recalc2:1; left:0}
  616.             //  this flags a property in the rule as needing a fix.
  617.             //  the selector text is then used to query the document.
  618.             //  we can then loop through the results of the query
  619.             //  and fix the elements.
  620.             // we ignore the IE7 rules - so count them in the header
  621.             var RECALCS = /ie7_recalc\d+/g;
  622.             var start = HEADER.match(/[{,]/g).length;
  623.             // only calculate screen fixes. print fixes don't show up anyway
  624.             var rules = this.styleSheet.rules, rule;
  625.             var calcs, calc, elements, element, i, j, k, id;
  626.             // loop through all rules
  627.             for (i = start; rule = rules[i]; i++) {
  628.                 var cssText = rule.style.cssText;
  629.                 // search for the "ie7_recalc" flag (there may be more than one)
  630.                 if (calcs = cssText.match(RECALCS)) {
  631.                     // use the selector text to query the document
  632.                     elements = cssQuery(rule.selectorText);
  633.                     // if there are matching elements then loop
  634.                     //  through the recalc functions and apply them
  635.                     //  to each element
  636.                     if (elements.length) for (j = 0; j < calcs.length; j++) {
  637.                         // get the matching flag (e.g. ie7_recalc3)
  638.                         id = calcs[j];
  639.                         // extract the numeric id from the end of the flag
  640.                         //  and use it to index the collection of recalc
  641.                         //  functions
  642.                         calc = IE7.CSS.recalcs[id.slice(10)][2];
  643.                         for (k = 0; (element = elements[k]); k++) {
  644.                             // apply the fix
  645.                             if (element.currentStyle[id]) calc(element, cssText);
  646.                         }
  647.                     }
  648.                 }
  649.             }
  650.         },

  651.         refresh: function() {
  652.             this.styleSheet.cssText = HEADER + this.screen + this.print;
  653.         },

  654.         trash: function() {
  655.             // trash the old style sheets
  656.             for (var i = 0; i < styleSheets.length; i++) {
  657.                 if (!styleSheets[i].ie7) {
  658.                     try {
  659.                         var cssText = styleSheets[i].cssText;
  660.                     } catch (e) {
  661.                         cssText = "";
  662.                     }
  663.                     if (cssText) styleSheets[i].cssText = "";
  664.                 }
  665.             }
  666.         }
  667.     }));

  668. // -----------------------------------------------------------------------
  669. //  IE7 StyleSheet class
  670. // -----------------------------------------------------------------------

  671.     var StyleSheet = Base.extend({
  672.         constructor: function(media) {
  673.             this.media = media;
  674.             this.load();
  675.             IE7.CSS[media] = this;
  676.             IE7.CSS.refresh();
  677.         },

  678.         createRule: function(selector, cssText) {
  679.             var match;
  680.             if (PseudoElement && (match = selector.match(PseudoElement.MATCH))) {
  681.                 return new PseudoElement(match[1], match[2], cssText);
  682.             } else if (match = selector.match(DynamicRule.MATCH)) {
  683.                 if (!HYPERLINK.test(match[0]) || DynamicRule.COMPLEX.test(match[0])) {
  684.                     return new DynamicRule(selector, match[1], match[2], match[3], cssText);
  685.                 }
  686.             } else {
  687.                 return new Rule(selector, cssText);
  688.             }
  689.             return selector + " {" + cssText + "}";
  690.         },

  691.         getText: function() {
  692.             // store for style sheet text
  693.             // parse media decalarations
  694.             var MEDIA        = /@media\s+([^{]+?)\s*\{([^@]+\})\s*\}/gi;
  695.             var IMPORTS      = /@import[^;\n]+/gi;
  696.             var TRIM_IMPORTS = /@import\s+url\s*\(\s*["']?|["']?\s*\)\s*/gi;
  697.             var URL          = /(url\s*\(\s*['"]?)([\w\.]+[^:\)]*['"]?\))/gi;

  698.             var self = this;

  699.             // Store loaded cssText URLs
  700.             var fileCache = {};

  701.             function getCSSText(styleSheet, path, media, level) {
  702.                 var cssText = "";
  703.                 if (!level) {
  704.                     media = toSimpleMedia(styleSheet.media);
  705.                     level = 0;
  706.                 }
  707.                 if (media === "none") {
  708.                     styleSheet.disabled = true;
  709.                     return "";
  710.                 }
  711.                 if (media === "all" || media === self.media) {
  712.                     // IE only allows importing style sheets three levels deep.
  713.                     // it will crash if you try to access a level below this
  714.                     try {
  715.                         var canAcess = !!styleSheet.cssText;
  716.                     } catch (exe) {}
  717.                     if (level < 3 && canAcess) {
  718.                         var hrefs = styleSheet.cssText.match(IMPORTS);
  719.                         // loop through imported style sheets
  720.                         for (var i = 0, imported; i < styleSheet.imports.length; i++) {
  721.                             var imported = styleSheet.imports[i];
  722.                             var href = styleSheet._href || styleSheet.href;
  723.                             imported._href = hrefs[i].replace(TRIM_IMPORTS, "");
  724.                             // call this function recursively to get all imported style sheets
  725.                             cssText += getCSSText(imported, getPath(href, path), media, level + 1);
  726.                         }
  727.                     }
  728.                     // retrieve inline style or load an external style sheet
  729.                     cssText += encode(styleSheet.href ? loadStyleSheet(styleSheet, path) : styleSheet.owningElement._cssText);
  730.                     cssText = parseMedia(cssText, self.media);
  731.                 }
  732.                 return cssText;
  733.             };

  734.             // Load all style sheets in the document
  735.             for (var i = 0; i < styleSheets.length; i++) {
  736.                 var styleSheet = styleSheets[i];
  737.                 if (!styleSheet.disabled && !styleSheet.ie7) this.cssText += getCSSText(styleSheet);
  738.             }

  739.             // helper functions
  740.             function parseMedia(cssText, media) {
  741.                 filterMedia.value = media;
  742.                 return cssText.replace(MEDIA, filterMedia);
  743.             };

  744.             function filterMedia(match, media, cssText) {
  745.                 media = toSimpleMedia(media);
  746.                 switch (media) {
  747.                     case "screen":
  748.                     case "print":
  749.                         if (media !== filterMedia.value) return "";
  750.                     case "all":
  751.                         return cssText;
  752.                 }
  753.                 return "";
  754.             };

  755.             function toSimpleMedia(media) {
  756.                 if (!media) return "all";
  757.                 var split = media.toLowerCase().split(/\s*,\s*/);
  758.                 media = "none";
  759.                 for (var i = 0; i < split.length; i++) {
  760.                     if (split[i] === "all") return "all";
  761.                     if (split[i] === "screen") {
  762.                         if (media === "print") return "all";
  763.                         media = "screen";
  764.                     } else if (split[i] === "print") {
  765.                         if (media === "screen") return "all";
  766.                         media = "print";
  767.                     }
  768.                 }
  769.                 return media;
  770.             };

  771.             // Load an external style sheet
  772.             function loadStyleSheet(styleSheet, path) {
  773.                 var href = styleSheet._href || styleSheet.href;
  774.                 var url = makePath(href, path);
  775.                 // If the style sheet has already loaded then don't reload it
  776.                 if (fileCache[url]) return "";
  777.                 // Load from source
  778.                 fileCache[url] = styleSheet.disabled ? "" :
  779.                     fixUrls(IE7.CSS.getText(styleSheet, path), getPath(href, path));
  780.                 return fileCache[url];
  781.             };

  782.             // Fix CSS paths.
  783.             // We're lumping all css text into one big style sheet so relative
  784.             // paths have to be fixed. This is necessary anyway because of other
  785.             // Internet Explorer bugs.
  786.             function fixUrls(cssText, pathname) {
  787.                 // hack & slash
  788.                 return cssText.replace(URL, "$1" + pathname.slice(0, pathname.lastIndexOf("/") + 1) + "$2");
  789.             };
  790.         },

  791.         load: function() {
  792.             this.cssText = "";
  793.             this.getText();
  794.             this.parse();
  795.             if (inheritedProperties.length) {
  796.                 this.cssText = parseInherited(this.cssText);
  797.             }
  798.             this.cssText = decode(this.cssText);
  799.             fileCache = {};
  800.         },

  801.         parse: function() {
  802.             var cssText = IE7.CSS.parser.parse(this.cssText);

  803.             var declarations = "";
  804.             this.cssText = cssText.replace(/@charset[^;]+;|@font\-face[^\}]+\}/g, function(match) {
  805.                 declarations += match + "\n";
  806.                 return "";
  807.             });
  808.             this.declarations = decode(declarations);

  809.             // Parse the style sheet
  810.             var offset = IE7.CSS.rules.length;
  811.             var rules = [], rule;
  812.             while ((rule = RULE.exec(this.cssText))) {
  813.                 var cssText = rule[2];
  814.                 if (cssText) {
  815.                     var fixDescendants = appVersion < 7 && cssText.indexOf("AlphaImageLoader") !== -1;
  816.                     var selectors = rule[1].match(SELECTOR), selector;
  817.                     for (var i = 0; selector = selectors[i]; i++) {
  818.                         selector = trim(selector);
  819.                         var isUnknown = IE7.CSS.UNKNOWN.test(selector);
  820.                         selectors[i] = isUnknown ? this.createRule(selector, cssText) : selector + "{" + cssText + "}";
  821.                         if (fixDescendants) selectors[i] += this.createRule(selector + ">*", "position:relative");
  822.                     }
  823.                     rules.push(selectors.join("\n"));
  824.                 }
  825.             }
  826.             this.cssText = rules.join("\n");
  827.             this.rules = IE7.CSS.rules.slice(offset);
  828.         },

  829.         recalc: function() {
  830.             var rule, i;
  831.             for (i = 0; (rule = this.rules[i]); i++) rule.recalc();
  832.         },

  833.         toString: function() {
  834.             return this.declarations + "@media " + this.media + "{" + this.cssText + "}";
  835.         }
  836.     });

  837.     var PseudoElement;

  838. // -----------------------------------------------------------------------
  839. // IE7 style rules
  840. // -----------------------------------------------------------------------

  841.     var Rule = IE7.Rule = Base.extend({
  842.         constructor: function(selector, cssText) {
  843.             this.id = IE7.CSS.rules.length;
  844.             this.className = Rule.PREFIX + this.id;
  845.             var pseudoElement = selector.match(FIRST_LINE_LETTER);
  846.             this.selector = (pseudoElement ? pseudoElement[1] : selector) || "*";
  847.             this.selectorText = this.parse(this.selector) + (pseudoElement ? pseudoElement[2] : "");
  848.             this.cssText = cssText;
  849.             this.MATCH = new RegExp("\\s" + this.className + "(\\s|$)", "g");
  850.             IE7.CSS.rules.push(this);
  851.             this.init();
  852.         },

  853.         init: Undefined,

  854.         add: function(element) {
  855.             // allocate this class
  856.             element.className += " " + this.className;
  857.         },

  858.         recalc: function() {
  859.             // execute the underlying css query for this class
  860.             var match = cssQuery(this.selector);
  861.             // add the class name for all matching elements
  862.             for (var i = 0; i < match.length; i++) this.add(match[i]);
  863.         },

  864.         parse: function(selector) {
  865.             // attempt to preserve specificity for "loose" parsing by
  866.             //  removing unknown tokens from a css selector but keep as
  867.             //  much as we can..
  868.             var simple = selector.replace(Rule.CHILD, " ").replace(Rule.COMPLEX, "");
  869.             if (appVersion < 7) simple = simple.replace(Rule.MULTI, "");
  870.             var tags = match(simple, Rule.TAGS).length - match(selector, Rule.TAGS).length;
  871.             var classes = match(simple, Rule.CLASSES).length - match(selector, Rule.CLASSES).length + 1;
  872.             while (classes > 0 && Rule.CLASS.test(simple)) {
  873.                 simple = simple.replace(Rule.CLASS, "");
  874.                 classes--;
  875.             }
  876.             while (tags > 0 && Rule.TAG.test(simple)) {
  877.                 simple = simple.replace(Rule.TAG, "$1*");
  878.                 tags--;
  879.             }
  880.             simple += "." + this.className;
  881.             classes = Math.min(classes, 2);
  882.             tags = Math.min(tags, 2);
  883.             var score = -10 * classes - tags;
  884.             if (score > 0) {
  885.                 simple = simple + "," + Rule.MAP[score] + " " + simple;
  886.             }
  887.             return simple;
  888.         },

  889.         remove: function(element) {
  890.             // deallocate this class
  891.             element.className = element.className.replace(this.MATCH, "$1");
  892.         },

  893.         toString: function() {
  894.             return format("%1 {%2}", this.selectorText, this.cssText);
  895.         }
  896.     }, {
  897.         CHILD: />/g,
  898.         CLASS: /\.[\w-]+/,
  899.         CLASSES: /[.:\[]/g,
  900.         MULTI: /(\.[\w-]+)+/g,
  901.         PREFIX: "ie7_class",
  902.         TAG: /^\w+|([\s>+~])\w+/,
  903.         TAGS: /^\w|[\s>+~]\w/g,
  904.         MAP: {
  905.             "1":  "html",
  906.             "2":  "html body",
  907.             "10": ".ie7_html",
  908.             "11": "html.ie7_html",
  909.             "12": "html.ie7_html body",
  910.             "20": ".ie7_html .ie7_body",
  911.             "21": "html.ie7_html .ie7_body",
  912.             "22": "html.ie7_html body.ie7_body"
  913.         }
  914.     });

  915. // -----------------------------------------------------------------------
  916. // IE7 dynamic style
  917. // -----------------------------------------------------------------------

  918. // object properties:
  919. // attach: the element that an event handler will be attached to
  920. // target: the element that will have the IE7 class applied

  921.     var DynamicRule = Rule.extend({
  922.         // properties
  923.         constructor: function(selector, attach, dynamicPseudoClass, target, cssText) {
  924.             this.negated = dynamicPseudoClass.indexOf("not") === 0;
  925.             if (this.negated) dynamicPseudoClass = dynamicPseudoClass.slice(5, -1);
  926.             // initialise object properties
  927.             this.attach = attach || "*";
  928.             this.dynamicPseudoClass = IE7.CSS.dynamicPseudoClasses[dynamicPseudoClass];
  929.             this.target = target;
  930.             this.base(selector, cssText);
  931.         },

  932.         recalc: function() {
  933.             // execute the underlying css query for this class
  934.             var attaches = cssQuery(this.attach), attach;
  935.             // process results
  936.             for (var i = 0; attach = attaches[i]; i++) {
  937.                 // retrieve the event handler's target element(s)
  938.                 var target = this.target ? cssQuery(this.target, attach) : [attach];
  939.                 // attach event handlers for dynamic pseudo-classes
  940.                 if (target.length) this.dynamicPseudoClass.apply(attach, target, this);
  941.             }
  942.         }
  943.     });

  944. // -----------------------------------------------------------------------
  945. //  IE7 dynamic pseudo-classes
  946. // -----------------------------------------------------------------------

  947.     var DynamicPseudoClass = Base.extend({
  948.         constructor: function(name, apply) {
  949.             this.name = name;
  950.             this.apply = apply;
  951.             this.instances = {};
  952.             IE7.CSS.dynamicPseudoClasses[name] = this;
  953.         },

  954.         register: function(instance, negated) {
  955.             // an "instance" is actually an Arguments object
  956.             var _class = instance[2];
  957.             if (!negated && _class.negated) {
  958.                 this.unregister(instance, true);
  959.             } else {
  960.                 instance.id = _class.id + instance[0].uniqueID;
  961.                 if (!this.instances[instance.id]) {
  962.                     var target = instance[1], j;
  963.                     for (j = 0; j < target.length; j++) _class.add(target[j]);
  964.                     this.instances[instance.id] = instance;
  965.                 }
  966.             }
  967.         },

  968.         unregister: function(instance, negated) {
  969.             var _class = instance[2];
  970.             if (!negated && _class.negated) {
  971.                 this.register(instance, true);
  972.             } else {
  973.                 if (this.instances[instance.id]) {
  974.                     var target = instance[1], j;
  975.                     for (j = 0; j < target.length; j++) _class.remove(target[j]);
  976.                     delete this.instances[instance.id];
  977.                 }
  978.             }
  979.         }
  980.     });

  981. // -----------------------------------------------------------------------
  982. // dynamic pseudo-classes
  983. // -----------------------------------------------------------------------

  984.     var Hover = new DynamicPseudoClass("hover", function(element) {
  985.         var instance = arguments;
  986.         IE7.CSS.addEventHandler(element, "onmouseenter", function() {
  987.             Hover.register(instance);
  988.         });
  989.         IE7.CSS.addEventHandler(element, "onmouseleave", function() {
  990.             Hover.unregister(instance);
  991.         });
  992.     });

  993. // globally trap the mouseup event (thanks Martijn!)
  994.     addEventHandler(document, "onmouseup", function() {
  995.         var instances = Hover.instances;
  996.         for (var i in instances)
  997.             if (!instances[i][0].contains(event.srcElement))
  998.                 Hover.unregister(instances[i]);
  999.     });

  1000.     var ATTR = {
  1001.         "=":  "%1==='%2'",                           // "[@%1='%2']"
  1002.         "~=": "(' '+%1+' ').indexOf(' %2 ')!==-1",   // "[contains(concat(' ',@%1,' '),' %2 ')]",
  1003.         "|=": "%1==='%2'||%1.indexOf('%2-')===0",    // "[@%1='%2' or starts-with(@%1,'%2-')]",
  1004.         "^=": "%1.indexOf('%2')===0",                // "[starts-with(@%1,'%2')]",
  1005.         "$=": "%1.slice(-'%2'.length)==='%2'",       // "[ends-with(@%1,'%2')]",
  1006.         "*=": "%1.indexOf('%2')!==-1"                // "[contains(@%1,'%2')]"
  1007.     };
  1008.     ATTR[""] = "%1!=null";                         // "[@%1]"

  1009.     var FILTER = {
  1010.         "<#attr>": function(match, name, operator, value) {
  1011.             var attr = "IE7._getAttribute(e,'" + name + "')";
  1012.             value = getString(value);
  1013.             if (operator.length > 1) {
  1014.                 if (!value || operator === "~=" && SPACE.test(value)) {
  1015.                     return "false&&";
  1016.                 }
  1017.                 attr = "(" + attr + "||'')";
  1018.             }
  1019.             return "(" + format(ATTR[operator], attr, value) + ")&&";
  1020.         },

  1021.         "<#id>":    ID_ATTRIBUTE + "==='$1'&&",

  1022.         "<#class>": "e.className&&(' '+e.className+' ').indexOf(' $1 ')!==-1&&",

  1023.         // PSEDUO
  1024.         ":first-child":     "!" + PREVIOUS_SIBLING + "&&",
  1025.         ":link":           "e.currentStyle['ie7-link']=='link'&&",
  1026.         ":visited":        "e.currentStyle['ie7-link']=='visited'&&"
  1027.     };

  1028. // =========================================================================
  1029. // ie7-html.js
  1030. // =========================================================================

  1031. // default font-sizes
  1032. //HEADER += "h1{font-size:2em}h2{font-size:1.5em;}h3{font-size:1.17em;}h4{font-size:1em}h5{font-size:.83em}h6{font-size:.67em}";

  1033.     IE7.HTML = new (Fix.extend({ // single instance
  1034.         fixed: {},

  1035.         init: Undefined,

  1036.         addFix: function() {
  1037.             // fixes are a one-off, they are applied when the document is loaded
  1038.             this.fixes.push(arguments);
  1039.         },

  1040.         apply: function() {
  1041.             for (var i = 0; i < this.fixes.length; i++) {
  1042.                 var match = cssQuery(this.fixes[i][0]);
  1043.                 var fix = this.fixes[i][1];
  1044.                 for (var j = 0; j < match.length; j++) fix(match[j]);
  1045.             }
  1046.         },

  1047.         addRecalc: function() {
  1048.             // recalcs occur whenever the document is refreshed using document.recalc()
  1049.             this.recalcs.push(arguments);
  1050.         },

  1051.         recalc: function() {
  1052.             // loop through the fixes
  1053.             for (var i = 0; i < this.recalcs.length; i++) {
  1054.                 var match = cssQuery(this.recalcs[i][0]);
  1055.                 var recalc = this.recalcs[i][1], element;
  1056.                 var key = Math.pow(2, i);
  1057.                 for (var j = 0; (element = match[j]); j++) {
  1058.                     var uniqueID = element.uniqueID;
  1059.                     if ((this.fixed[uniqueID] & key) === 0) {
  1060.                         element = recalc(element) || element;
  1061.                         this.fixed[uniqueID] |= key;
  1062.                     }
  1063.                 }
  1064.             }
  1065.         }
  1066.     }));

  1067.     if (appVersion < 7) {
  1068.         // provide support for the <abbr> tag.
  1069.         document.createElement("abbr");

  1070.         // bind to the first child control
  1071.         IE7.HTML.addRecalc("label", function(label) {
  1072.             if (!label.htmlFor) {
  1073.                 var firstChildControl = cssQuery("input,textarea", label, true);
  1074.                 if (firstChildControl) {
  1075.                     addEventHandler(label, "onclick", function() {
  1076.                         firstChildControl.click();
  1077.                     });
  1078.                 }
  1079.             }
  1080.         });
  1081.     }

  1082. // =========================================================================
  1083. // ie7-layout.js
  1084. // =========================================================================

  1085.     var NUMERIC = "[.\\d]";

  1086.     (function() {
  1087.         var layout = IE7.Layout = {};

  1088.         // big, ugly box-model hack + min/max stuff

  1089.         // #tantek > #erik > #dean { voice-family: hacker; }

  1090.         // -----------------------------------------------------------------------
  1091.         // "layout"
  1092.         // -----------------------------------------------------------------------

  1093.         HEADER += "*{boxSizing:content-box}";

  1094.         // give an element "layout"
  1095.         layout.boxSizing = function(element) {
  1096.             if (!element.currentStyle.hasLayout) {
  1097.                 //#  element.runtimeStyle.fixedHeight =
  1098.                 element.style.height = "0cm";
  1099.                 if (element.currentStyle.verticalAlign === "auto")
  1100.                     element.runtimeStyle.verticalAlign = "top";
  1101.                 // when an element acquires "layout", margins no longer collapse correctly
  1102.                 collapseMargins(element);
  1103.             }
  1104.         };

  1105.         // -----------------------------------------------------------------------
  1106.         // Margin Collapse
  1107.         // -----------------------------------------------------------------------

  1108.         function collapseMargins(element) {
  1109.             if (element != viewport && element.currentStyle.position !== "absolute") {
  1110.                 collapseMargin(element, "marginTop");
  1111.                 collapseMargin(element, "marginBottom");
  1112.             }
  1113.         };

  1114.         function collapseMargin(element, type) {
  1115.             if (!element.runtimeStyle[type]) {
  1116.                 var parentElement = element.parentElement;
  1117.                 var isTopMargin = type === "marginTop";
  1118.                 if (parentElement && parentElement.currentStyle.hasLayout && !IE7._getElementSibling(element, isTopMargin ? "previous" : "next")) return;
  1119.                 var child = element[isTopMargin ? "firstChild" : "lastChild"];
  1120.                 if (child && child.nodeName < "@") child = IE7._getElementSibling(child, isTopMargin ? "next" : "previous");
  1121.                 if (child && child.currentStyle.styleFloat === "none" && child.currentStyle.hasLayout) {
  1122.                     collapseMargin(child, type);
  1123.                     margin = _getMargin(element, element.currentStyle[type]);
  1124.                     childMargin = _getMargin(child, child.currentStyle[type]);
  1125.                     if (margin < 0 || childMargin < 0) {
  1126.                         element.runtimeStyle[type] = margin + childMargin;
  1127.                     } else {
  1128.                         element.runtimeStyle[type] = Math.max(childMargin, margin);
  1129.                     }
  1130.                     child.runtimeStyle[type] = "0px";
  1131.                 }
  1132.             }
  1133.         };

  1134.         function _getMargin(element, value) {
  1135.             return value === "auto" ? 0 : getPixelValue(element, value);
  1136.         };

  1137.         // -----------------------------------------------------------------------
  1138.         // box-model
  1139.         // -----------------------------------------------------------------------

  1140.         // constants
  1141.         var UNIT = /^[.\d][\w]*$/, AUTO = /^(auto|0cm)$/;

  1142.         var apply = {};
  1143.         layout.borderBox = function(element){
  1144.             apply.Width(element);
  1145.             apply.Height(element);
  1146.         };

  1147.         var _fixWidth = function(HEIGHT) {
  1148.             apply.Width = function(element) {
  1149.                 if (!PERCENT.test(element.currentStyle.width)) _fixWidth(element);
  1150.                 if (HEIGHT) collapseMargins(element);
  1151.             };

  1152.             function _fixWidth(element, value) {
  1153.                 if (!element.runtimeStyle.fixedWidth) {
  1154.                     if (!value) value = element.currentStyle.width;
  1155.                     element.runtimeStyle.fixedWidth = UNIT.test(value) ? Math.max(0, getFixedWidth(element, value)) + "px" : value;
  1156.                     setOverrideStyle(element, "width", element.runtimeStyle.fixedWidth);
  1157.                 }
  1158.             };

  1159.             function layoutWidth(element) {
  1160.                 if (!isFixed(element)) {
  1161.                     var layoutParent = element.offsetParent;
  1162.                     while (layoutParent && !layoutParent.currentStyle.hasLayout) layoutParent = layoutParent.offsetParent;
  1163.                 }
  1164.                 return (layoutParent || viewport).clientWidth;
  1165.             };

  1166.             function getPixelWidth(element, value) {
  1167.                 if (PERCENT.test(value)) return parseInt(parseFloat(value) / 100 * layoutWidth(element));
  1168.                 return getPixelValue(element, value);
  1169.             };

  1170.             var getFixedWidth = function(element, value) {
  1171.                 var borderBox = element.currentStyle["ie7-box-sizing"] === "border-box";
  1172.                 var adjustment = 0;
  1173.                 if (MSIE5 && !borderBox)
  1174.                     adjustment += getBorderWidth(element) + getWidth(element, "padding");
  1175.                 else if (!MSIE5 && borderBox)
  1176.                     adjustment -= getBorderWidth(element) + getWidth(element, "padding");
  1177.                 return getPixelWidth(element, value) + adjustment;
  1178.             };

  1179.             // easy way to get border thickness for elements with "layout"
  1180.             function getBorderWidth(element) {
  1181.                 return element.offsetWidth - element.clientWidth;
  1182.             };

  1183.             // have to do some pixel conversion to get padding/margin thickness :-(
  1184.             function getWidth(element, type) {
  1185.                 return getPixelWidth(element, element.currentStyle[type + "Left"]) + getPixelWidth(element, element.currentStyle[type + "Right"]);
  1186.             };

  1187.             // -----------------------------------------------------------------------
  1188.             // min/max
  1189.             // -----------------------------------------------------------------------

  1190.             HEADER += "*{minWidth:none;maxWidth:none;min-width:none;max-width:none}";

  1191.             // handle min-width property
  1192.             layout.minWidth = function(element) {
  1193.                 // IE6 supports min-height so we frig it here
  1194.                 //#if (element.currentStyle.minHeight === "auto") element.runtimeStyle.minHeight = 0;
  1195.                 if (element.currentStyle["min-width"] != null) {
  1196.                     element.style.minWidth = element.currentStyle["min-width"];
  1197.                 }
  1198.                 if (register(arguments.callee, element, element.currentStyle.minWidth !== "none")) {
  1199.                     layout.boxSizing(element);
  1200.                     _fixWidth(element);
  1201.                     resizeWidth(element);
  1202.                 }
  1203.             };

  1204.             // clone the minWidth function to make a maxWidth function
  1205.             eval("IE7.Layout.maxWidth=" + String(layout.minWidth).replace(/min/g, "max"));

  1206.             // apply min/max restrictions
  1207.             function resizeWidth(element) {
  1208.                 // check boundaries
  1209.                 if (element == document.body) {
  1210.                     var width = element.clientWidth;
  1211.                 } else {
  1212.                     var rect = element.getBoundingClientRect();
  1213.                     width = rect.right - rect.left;
  1214.                 }
  1215.                 if (element.currentStyle.minWidth !== "none" && width < getFixedWidth(element, element.currentStyle.minWidth)) {
  1216.                     element.runtimeStyle.width = element.currentStyle.minWidth;
  1217.                 } else if (element.currentStyle.maxWidth !== "none" && width >= getFixedWidth(element, element.currentStyle.maxWidth)) {
  1218.                     element.runtimeStyle.width = element.currentStyle.maxWidth;
  1219.                 } else {
  1220.                     element.runtimeStyle.width = element.runtimeStyle.fixedWidth;
  1221.                 }
  1222.             };

  1223.             // -----------------------------------------------------------------------
  1224.             // right/bottom
  1225.             // -----------------------------------------------------------------------

  1226.             function fixRight(element) {
  1227.                 if (register(fixRight, element, /^(fixed|absolute)$/.test(element.currentStyle.position) &&
  1228.                         getDefinedStyle(element, "left") !== "auto" &&
  1229.                         getDefinedStyle(element, "right") !== "auto" &&
  1230.                         AUTO.test(getDefinedStyle(element, "width")))) {
  1231.                     resizeRight(element);
  1232.                     layout.boxSizing(element);
  1233.                 }
  1234.             };
  1235.             layout.fixRight = fixRight;

  1236.             function resizeRight(element) {
  1237.                 var left = getPixelWidth(element, element.runtimeStyle._left || element.currentStyle.left);
  1238.                 var width = layoutWidth(element) - getPixelWidth(element, element.currentStyle.right) -  left - getWidth(element, "margin");
  1239.                 if (parseInt(element.runtimeStyle.width) === width) return;
  1240.                 element.runtimeStyle.width = "";
  1241.                 if (isFixed(element) || HEIGHT || element.offsetWidth < width) {
  1242.                     if (!MSIE5) width -= getBorderWidth(element) + getWidth(element, "padding");
  1243.                     if (width < 0) width = 0;
  1244.                     element.runtimeStyle.fixedWidth = width;
  1245.                     setOverrideStyle(element, "width", width);
  1246.                 }
  1247.             };

  1248.             // -----------------------------------------------------------------------
  1249.             // window.onresize
  1250.             // -----------------------------------------------------------------------

  1251.             // handle window resize
  1252.             var clientWidth = 0;
  1253.             addResize(function() {
  1254.                 if (!viewport) return;
  1255.                 var i, wider = (clientWidth < viewport.clientWidth);
  1256.                 clientWidth = viewport.clientWidth;
  1257.                 // resize elements with "min-width" set
  1258.                 var elements = layout.minWidth.elements;
  1259.                 for (i in elements) {
  1260.                     var element = elements[i];
  1261.                     var fixedWidth = (parseInt(element.runtimeStyle.width) === getFixedWidth(element, element.currentStyle.minWidth));
  1262.                     if (wider && fixedWidth) element.runtimeStyle.width = "";
  1263.                     if (wider == fixedWidth) resizeWidth(element);
  1264.                 }
  1265.                 // resize elements with "max-width" set
  1266.                 var elements = layout.maxWidth.elements;
  1267.                 for (i in elements) {
  1268.                     var element = elements[i];
  1269.                     var fixedWidth = (parseInt(element.runtimeStyle.width) === getFixedWidth(element, element.currentStyle.maxWidth));
  1270.                     if (!wider && fixedWidth) element.runtimeStyle.width = "";
  1271.                     if (wider !== fixedWidth) resizeWidth(element);
  1272.                 }
  1273.                 // resize elements with "right" set
  1274.                 for (i in fixRight.elements) resizeRight(fixRight.elements[i]);
  1275.             });

  1276.             // -----------------------------------------------------------------------
  1277.             // fix CSS
  1278.             // -----------------------------------------------------------------------
  1279.             if (MSIE5) {
  1280.                 IE7.CSS.addRecalc("width", NUMERIC, apply.Width);
  1281.             }
  1282.             if (appVersion < 7) {
  1283.                 IE7.CSS.addRecalc("max-width", NUMERIC, layout.maxWidth);
  1284.                 IE7.CSS.addRecalc("right", NUMERIC, fixRight);
  1285.             } else if (appVersion == 7) {
  1286.                 if (HEIGHT) IE7.CSS.addRecalc("height", "[\\d.]+%", function(element) {
  1287.                     element.runtimeStyle.pixelHeight = parseInt(layoutWidth(element) * element.currentStyle["ie7-height"].slice(0, -1) / 100);
  1288.                 });
  1289.             }
  1290.         };

  1291.         eval("var _fixHeight=" + rotate(_fixWidth));

  1292.         // apply box-model + min/max fixes
  1293.         _fixWidth();
  1294.         _fixHeight(true);

  1295.         if (appVersion < 7) {
  1296.             IE7.CSS.addRecalc("min-width", NUMERIC, layout.minWidth);
  1297.             IE7.CSS.addFix(/\bmin-height\s*/, "height");
  1298.         }
  1299.     })();

  1300. // =========================================================================
  1301. // ie7-graphics.js
  1302. // =========================================================================

  1303. // a small transparent image used as a placeholder
  1304.     var BLANK_GIF = makePath("blank.gif", path);

  1305.     var ALPHA_IMAGE_LOADER = "DXImageTransform.Microsoft.AlphaImageLoader";
  1306.     var PNG_FILTER = "progid:" + ALPHA_IMAGE_LOADER + "(src='%1',sizingMethod='%2')";

  1307. // regular expression version of the above
  1308.     var PNG;

  1309.     var filtered = [];

  1310.     function fixImage(element) {
  1311.         if (PNG.test(element.src)) {
  1312.             // we have to preserve width and height
  1313.             var image = new Image(element.width, element.height);
  1314.             image.onload = function() {
  1315.                 element.width = image.width;
  1316.                 element.height = image.height;
  1317.                 image = null;
  1318.             };
  1319.             image.src = element.src;
  1320.             // store the original url (we'll put it back when it's printed)
  1321.             element.pngSrc = element.src;
  1322.             // add the AlphaImageLoader thingy
  1323.             addFilter(element);
  1324.         }
  1325.     };

  1326.     if (appVersion < 7) {
  1327.         // ** IE7 VARIABLE
  1328.         // e.g. apply the hack to all files ending in ".png"
  1329.         // IE7_PNG_SUFFIX = ".png";
  1330.         // You can also set it to a RegExp
  1331.         // IE7_PNG_SUFFIX = /\d+\.png$/;

  1332.         // replace background(-image): url(..) ..  with background(-image): .. ;filter: ..;
  1333.         IE7.CSS.addFix(/background(-image)?\s*:\s*([^};]*)?url\(([^\)]+)\)([^;}]*)?/, function(match, $1, $2, url, $4) {
  1334.             url = getString(url);
  1335.             return PNG.test(url) ? "filter:" + format(PNG_FILTER, url, $4.indexOf("no-repeat") === -1 ? "scale" : "crop") +
  1336.             ";zoom:1;background" + ($1||"") + ":" + ($2||"") + "none" + ($4||"") : match;
  1337.         });

  1338.         // list-style-image
  1339.         IE7.CSS.addRecalc(/list\-style(\-image)?/, "[^};]*url", function(element) {
  1340.             var url = element.currentStyle.listStyleImage.slice(5, -2);
  1341.             if (PNG.test(url)) {
  1342.                 if (element.nodeName === "LI") {
  1343.                     fixListStyleImage(element, url)
  1344.                 } else if (element.nodeName === "UL") {
  1345.                     for (var i = 0, li; li = element.childNodes[i]; i++) {
  1346.                         if (li.nodeName === "LI") fixListStyleImage(li, url);
  1347.                     }
  1348.                 }
  1349.             }
  1350.         });

  1351.         function fixListStyleImage(element, src) {
  1352.             var style = element.runtimeStyle;
  1353.             var originalHeight = element.offsetHeight;
  1354.             var image = new Image;
  1355.             image.onload = function() {
  1356.                 var paddingLeft = element.currentStyle.paddingLeft;
  1357.                 paddingLeft = paddingLeft === "0px" ? 0 : getPixelValue(element, paddingLeft);
  1358.                 style.paddingLeft = (paddingLeft + this.width) + "px";
  1359.                 style.marginLeft = -this.width + "px";
  1360.                 style.listStyleType = "none";
  1361.                 style.listStyleImage = "none";
  1362.                 style.paddingTop = Math.max(originalHeight - element.offsetHeight, 0) + "px";
  1363.                 addFilter(element, "crop", src);
  1364.                 element.style.zoom = "100%";
  1365.             };
  1366.             image.src = src;
  1367.         };

  1368.         // -----------------------------------------------------------------------
  1369.         //  fix PNG transparency (HTML images)
  1370.         // -----------------------------------------------------------------------

  1371.         IE7.HTML.addRecalc("img,input", function(element) {
  1372.             if (element.nodeName === "INPUT" && element.type !== "image") return;
  1373.             fixImage(element);
  1374.             addEventHandler(element, "onpropertychange", function() {
  1375.                 if (!printing && event.propertyName === "src" &&
  1376.                     element.src.indexOf(BLANK_GIF) === -1) fixImage(element);
  1377.             });
  1378.         });

  1379.         // assume that background images should not be printed
  1380.         //  (if they are not transparent then they'll just obscure content)
  1381.         // but we'll put foreground images back...
  1382.         var printing = false;
  1383.         addEventHandler(window, "onbeforeprint", function() {
  1384.             printing = true;
  1385.             for (var i = 0; i < filtered.length; i++) removeFilter(filtered[i]);
  1386.         });
  1387.         addEventHandler(window, "onafterprint", function() {
  1388.             for (var i = 0; i < filtered.length; i++) addFilter(filtered[i]);
  1389.             printing = false;
  1390.         });
  1391.     }

  1392. // apply a filter
  1393.     function addFilter(element, sizingMethod, src) {
  1394.         var filter = element.filters[ALPHA_IMAGE_LOADER];
  1395.         if (filter) {
  1396.             filter.src = src || element.src;
  1397.             filter.enabled = true;
  1398.         } else {
  1399.             element.runtimeStyle.filter = format(PNG_FILTER, src || element.src, sizingMethod || "scale");
  1400.             filtered.push(element);
  1401.         }
  1402.         // remove the real image
  1403.         element.src = BLANK_GIF;
  1404.     };

  1405.     function removeFilter(element) {
  1406.         element.src = element.pngSrc;
  1407.         element.filters[ALPHA_IMAGE_LOADER].enabled = false;
  1408.     };

  1409. // =========================================================================
  1410. // ie7-fixed.js
  1411. // =========================================================================

  1412.     (function() {
  1413.         if (appVersion >= 7) return;

  1414.         // some things to consider for this hack.
  1415.         // the document body requires a fixed background. even if
  1416.         //  it is just a blank image.
  1417.         // you have to use setExpression instead of onscroll, this
  1418.         //  together with a fixed body background helps avoid the
  1419.         //  annoying screen flicker of other solutions.

  1420.         IE7.CSS.addRecalc("position", "fixed", _positionFixed, "absolute");
  1421.         IE7.CSS.addRecalc("background(-attachment)?", "[^};]*fixed", _backgroundFixed);

  1422.         // scrolling is relative to the documentElement (HTML tag) when in
  1423.         //  standards mode, otherwise it's relative to the document body
  1424.         var $viewport = MSIE5 ? "body" : "documentElement";

  1425.         function _fixBackground() {
  1426.             // this is required by both position:fixed and background-attachment:fixed.
  1427.             // it is necessary for the document to also have a fixed background image.
  1428.             // we can fake this with a blank image if necessary
  1429.             if (body.currentStyle.backgroundAttachment !== "fixed") {
  1430.                 if (body.currentStyle.backgroundImage === "none") {
  1431.                     body.runtimeStyle.backgroundRepeat = "no-repeat";
  1432.                     body.runtimeStyle.backgroundImage = "url(" + BLANK_GIF + ")"; // dummy
  1433.                 }
  1434.                 body.runtimeStyle.backgroundAttachment = "fixed";
  1435.             }
  1436.             _fixBackground = Undefined;
  1437.         };

  1438.         var _tmp = createTempElement("img");

  1439.         function _isFixed(element) {
  1440.             return element ? isFixed(element) || _isFixed(element.parentElement) : false;
  1441.         };

  1442.         function _setExpression(element, propertyName, expression) {
  1443.             setTimeout("document.all." + element.uniqueID + ".runtimeStyle.setExpression('" + propertyName + "','" + expression + "')", 0);
  1444.         };

  1445.         // -----------------------------------------------------------------------
  1446.         //  backgroundAttachment: fixed
  1447.         // -----------------------------------------------------------------------

  1448.         function _backgroundFixed(element) {
  1449.             if (register(_backgroundFixed, element, element.currentStyle.backgroundAttachment === "fixed" && !element.contains(body))) {
  1450.                 _fixBackground();
  1451.                 util.bgLeft(element);
  1452.                 util.bgTop(element);
  1453.                 _backgroundPosition(element);
  1454.             }
  1455.         };

  1456.         function _backgroundPosition(element) {
  1457.             _tmp.src = element.currentStyle.backgroundImage.slice(5, -2);
  1458.             var parentElement = element.canHaveChildren ? element : element.parentElement;
  1459.             parentElement.appendChild(_tmp);
  1460.             util.setOffsetLeft(element);
  1461.             util.setOffsetTop(element);
  1462.             parentElement.removeChild(_tmp);
  1463.         };

  1464.         // -----------------------------------------------------------------------
  1465.         //  position: fixed
  1466.         // -----------------------------------------------------------------------

  1467.         function _positionFixed(element) {
  1468.             if (register(_positionFixed, element, isFixed(element))) {
  1469.                 setOverrideStyle(element, "position",  "absolute");
  1470.                 setOverrideStyle(element, "left",  element.currentStyle.left);
  1471.                 setOverrideStyle(element, "top",  element.currentStyle.top);
  1472.                 _fixBackground();
  1473.                 IE7.Layout.fixRight(element);
  1474.                 //IE7.Layout.fixBottom(element);
  1475.                 _foregroundPosition(element);
  1476.             }
  1477.         };

  1478.         function _foregroundPosition(element, recalc) {
  1479.             document.body.getBoundingClientRect(); // force a reflow
  1480.             util.positionTop(element, recalc);
  1481.             util.positionLeft(element, recalc, true);
  1482.             if (!element.runtimeStyle.autoLeft && element.currentStyle.marginLeft === "auto" &&
  1483.                 element.currentStyle.right !== "auto") {
  1484.                 var left = viewport.clientWidth - util.getPixelWidth(element, element.currentStyle.right) -
  1485.                     util.getPixelWidth(element, element.runtimeStyle._left) - element.clientWidth;
  1486.                 if (element.currentStyle.marginRight === "auto") left = parseInt(left / 2);
  1487.                 if (_isFixed(element.offsetParent)) element.runtimeStyle.pixelLeft += left;
  1488.                 else element.runtimeStyle.shiftLeft = left;
  1489.             }
  1490.             if (!element.runtimeStyle.fixedWidth) util.clipWidth(element);
  1491.             if (!element.runtimeStyle.fixedHeight) util.clipHeight(element);
  1492.         };

  1493.         // -----------------------------------------------------------------------
  1494.         //  capture window resize
  1495.         // -----------------------------------------------------------------------

  1496.         function _resize() {
  1497.             // if the window has been resized then some positions need to be
  1498.             //  recalculated (especially those aligned to "right" or "top"
  1499.             var elements = _backgroundFixed.elements;
  1500.             for (var i in elements) _backgroundPosition(elements[i]);
  1501.             elements = _positionFixed.elements;
  1502.             for (i in elements) {
  1503.                 _foregroundPosition(elements[i], true);
  1504.                 _foregroundPosition(elements[i], true);
  1505.             }
  1506.             _timer = 0;
  1507.         };

  1508.         // use a timer (sometimes this is a good way to prevent resize loops)
  1509.         var _timer;
  1510.         addResize(function() {
  1511.             if (!_timer) _timer = setTimeout(_resize, 100);
  1512.         });

  1513.         // -----------------------------------------------------------------------
  1514.         //  rotated
  1515.         // -----------------------------------------------------------------------

  1516.         var util = {};

  1517.         var _horizontal = function(util) {
  1518.             util.bgLeft = function(element) {
  1519.                 element.style.backgroundPositionX = element.currentStyle.backgroundPositionX;
  1520.                 if (!_isFixed(element)) {
  1521.                     _setExpression(element, "backgroundPositionX", "(parseInt(runtimeStyle.offsetLeft)+document." + $viewport + ".scrollLeft)||0");
  1522.                 }
  1523.             };

  1524.             util.setOffsetLeft = function(element) {
  1525.                 var propertyName = _isFixed(element) ? "backgroundPositionX" : "offsetLeft";
  1526.                 element.runtimeStyle[propertyName] =
  1527.                     util.getOffsetLeft(element, element.style.backgroundPositionX) -
  1528.                     element.getBoundingClientRect().left - element.clientLeft + 2;
  1529.             };

  1530.             util.getOffsetLeft = function(element, position) {
  1531.                 switch (position) {
  1532.                     case "left":
  1533.                     case "top":
  1534.                         return 0;
  1535.                     case "right":
  1536.                     case "bottom":
  1537.                         return viewport.clientWidth - _tmp.offsetWidth;
  1538.                     case "center":
  1539.                         return (viewport.clientWidth - _tmp.offsetWidth) / 2;
  1540.                     default:
  1541.                         if (PERCENT.test(position)) {
  1542.                             return parseInt((viewport.clientWidth - _tmp.offsetWidth) * parseFloat(position) / 100);
  1543.                         }
  1544.                         _tmp.style.left = position;
  1545.                         return _tmp.offsetLeft;
  1546.                 }
  1547.             };

  1548.             util.clipWidth = function(element) {
  1549.                 var fixWidth = element.runtimeStyle.fixWidth;
  1550.                 element.runtimeStyle.borderRightWidth = "";
  1551.                 element.runtimeStyle.width = fixWidth ? util.getPixelWidth(element, fixWidth) + "px" : "";
  1552.                 if (element.currentStyle.width !== "auto") {
  1553.                     var rect = element.getBoundingClientRect();
  1554.                     var width = element.offsetWidth - viewport.clientWidth + rect.left - 2;
  1555.                     if (width >= 0) {
  1556.                         element.runtimeStyle.borderRightWidth = "0px";
  1557.                         width = Math.max(getPixelValue(element, element.currentStyle.width) - width, 0);
  1558.                         setOverrideStyle(element, "width",  width);
  1559.                         return width;
  1560.                     }
  1561.                 }
  1562.             };

  1563.             util.positionLeft = function(element, recalc) {
  1564.                 // if the element's width is in % units then it must be recalculated
  1565.                 //  with respect to the viewport
  1566.                 if (!recalc && PERCENT.test(element.currentStyle.width)) {
  1567.                     element.runtimeStyle.fixWidth = element.currentStyle.width;
  1568.                 }
  1569.                 if (element.runtimeStyle.fixWidth) {
  1570.                     element.runtimeStyle.width = util.getPixelWidth(element, element.runtimeStyle.fixWidth);
  1571.                 }
  1572.                 //if (recalc) {
  1573.                 //  // if the element is fixed on the right then no need to recalculate
  1574.                 //  if (!element.runtimeStyle.autoLeft) return;
  1575.                 //} else {
  1576.                 element.runtimeStyle.shiftLeft = 0;
  1577.                 element.runtimeStyle._left = element.currentStyle.left;
  1578.                 // is the element fixed on the right?
  1579.                 element.runtimeStyle.autoLeft = element.currentStyle.right !== "auto" && element.currentStyle.left === "auto";
  1580.                 //}
  1581.                 // reset the element's "left" value and get it's natural position
  1582.                 element.runtimeStyle.left = "";
  1583.                 element.runtimeStyle.screenLeft = util.getScreenLeft(element);
  1584.                 element.runtimeStyle.pixelLeft = element.runtimeStyle.screenLeft;
  1585.                 // if the element is contained by another fixed element then there is no need to
  1586.                 //  continually recalculate it's left position
  1587.                 if (!recalc && !_isFixed(element.offsetParent)) {
  1588.                     // onsrcoll produces jerky movement, so we use an expression
  1589.                     _setExpression(element, "pixelLeft", "runtimeStyle.screenLeft+runtimeStyle.shiftLeft+document." + $viewport + ".scrollLeft");
  1590.                 }
  1591.             };

  1592.             // I've forgotten how this works...
  1593.             util.getScreenLeft = function(element) { // thanks to kevin newman (captainn)
  1594.                 var screenLeft = element.offsetLeft, nested = 1;
  1595.                 if (element.runtimeStyle.autoLeft) {
  1596.                     screenLeft = viewport.clientWidth - element.offsetWidth - util.getPixelWidth(element, element.currentStyle.right);
  1597.                 }
  1598.                 // accommodate margins
  1599.                 if (element.currentStyle.marginLeft !== "auto") {
  1600.                     screenLeft -= util.getPixelWidth(element, element.currentStyle.marginLeft);
  1601.                 }
  1602.                 while (element = element.offsetParent) {
  1603.                     if (element.currentStyle.position !== "static") nested = -1;
  1604.                     screenLeft += element.offsetLeft * nested;
  1605.                 }
  1606.                 return screenLeft;
  1607.             };

  1608.             util.getPixelWidth = function(element, value) {
  1609.                 return PERCENT.test(value) ? parseInt(parseFloat(value) / 100 * viewport.clientWidth) : getPixelValue(element, value);
  1610.             };
  1611.         };
  1612.         eval("var _vertical=" + rotate(_horizontal));
  1613.         _horizontal(util);
  1614.         _vertical(util);
  1615.     })();

  1616. // =========================================================================
  1617. // ie7-oveflow.js
  1618. // =========================================================================

  1619.     /* ---------------------------------------------------------------------
  1620.      This module alters the structure of the document.
  1621.      It may adversely affect other CSS rules. Be warned.
  1622.      --------------------------------------------------------------------- */

  1623.     if (appVersion < 7) {
  1624.         var WRAPPER_STYLE = {
  1625.             backgroundColor: "transparent",
  1626.             backgroundImage: "none",
  1627.             backgroundPositionX: null,
  1628.             backgroundPositionY: null,
  1629.             backgroundRepeat: null,
  1630.             borderTopWidth: 0,
  1631.             borderRightWidth: 0,
  1632.             borderBottomWidth: 0,
  1633.             borderLeftStyle: "none",
  1634.             borderTopStyle: "none",
  1635.             borderRightStyle: "none",
  1636.             borderBottomStyle: "none",
  1637.             borderLeftWidth: 0,
  1638.             borderLeftColor: "#000",
  1639.             borderTopColor: "#000",
  1640.             borderRightColor: "#000",
  1641.             borderBottomColor: "#000",
  1642.             height: null,
  1643.             marginTop: 0,
  1644.             marginBottom: 0,
  1645.             marginRight: 0,
  1646.             marginLeft: 0,
  1647.             width: "100%"
  1648.         };

  1649.         IE7.CSS.addRecalc("overflow", "visible", function(element) {
  1650.             if (element.currentStyle.position === "absolute") return;

  1651.             // don't do this again
  1652.             if (element.parentNode.ie7_wrapped) return;

  1653.             // if max-height is applied, makes sure it gets applied first
  1654.             if (IE7.Layout && element.currentStyle["max-height"] !== "auto") {
  1655.                 IE7.Layout.maxHeight(element);
  1656.             }

  1657.             if (element.currentStyle.marginLeft === "auto") element.style.marginLeft = 0;
  1658.             if (element.currentStyle.marginRight === "auto") element.style.marginRight = 0;

  1659.             var wrapper = document.createElement(ANON);
  1660.             wrapper.ie7_wrapped = element;
  1661.             for (var propertyName in WRAPPER_STYLE) {
  1662.                 wrapper.style[propertyName] = element.currentStyle[propertyName];
  1663.                 if (WRAPPER_STYLE[propertyName] != null) {
  1664.                     element.runtimeStyle[propertyName] = WRAPPER_STYLE[propertyName];
  1665.                 }
  1666.             }
  1667.             wrapper.style.display = "block";
  1668.             wrapper.style.position = "relative";
  1669.             element.runtimeStyle.position = "absolute";
  1670.             element.parentNode.insertBefore(wrapper, element);
  1671.             wrapper.appendChild(element);
  1672.         });
  1673.     }

  1674. // =========================================================================
  1675. // ie7-quirks.js
  1676. // =========================================================================

  1677.     function ie7Quirks() {
  1678.         var FONT_SIZES = "xx-small,x-small,small,medium,large,x-large,xx-large".split(",");
  1679.         for (var i = 0; i < FONT_SIZES.length; i++) {
  1680.             FONT_SIZES[FONT_SIZES[i]] = FONT_SIZES[i - 1] || "0.67em";
  1681.         }

  1682.         IE7.CSS.addFix(/(font(-size)?\s*:\s*)([\w.-]+)/, function(match, label, size, value) {
  1683.             return label + (FONT_SIZES[value] || value);
  1684.         });

  1685.         var NEGATIVE = /^\-/, LENGTH = /(em|ex)$/i;
  1686.         var EM = /em$/i, EX = /ex$/i;

  1687.         getPixelValue = function(element, value) {
  1688.             if (PIXEL.test(value)) return parseInt(value)||0;
  1689.             var scale = NEGATIVE.test(value)? -1 : 1;
  1690.             if (LENGTH.test(value)) scale *= getFontScale(element);
  1691.             temp.style.width = scale < 0 ? value.slice(1) : value;
  1692.             body.appendChild(temp);
  1693.             // retrieve pixel width
  1694.             value = scale * temp.offsetWidth;
  1695.             // remove the temporary element
  1696.             temp.removeNode();
  1697.             return parseInt(value);
  1698.         };

  1699.         var temp = createTempElement();
  1700.         function getFontScale(element) {
  1701.             var scale = 1;
  1702.             temp.style.fontFamily = element.currentStyle.fontFamily;
  1703.             temp.style.lineHeight = element.currentStyle.lineHeight;
  1704.             //temp.style.fontSize = "";
  1705.             while (element != body) {
  1706.                 var fontSize = element.currentStyle["ie7-font-size"];
  1707.                 if (fontSize) {
  1708.                     if (EM.test(fontSize)) scale *= parseFloat(fontSize);
  1709.                     else if (PERCENT.test(fontSize)) scale *= (parseFloat(fontSize) / 100);
  1710.                     else if (EX.test(fontSize)) scale *= (parseFloat(fontSize) / 2);
  1711.                     else {
  1712.                         temp.style.fontSize = fontSize;
  1713.                         return 1;
  1714.                     }
  1715.                 }
  1716.                 element = element.parentElement;
  1717.             }
  1718.             return scale;
  1719.         };

  1720.         // cursor:pointer (IE5.x)
  1721.         IE7.CSS.addFix(/cursor\s*:\s*pointer/, "cursor:hand");
  1722.         // display:list-item (IE5.x)
  1723.         IE7.CSS.addFix(/display\s*:\s*list-item/, "display:block");

  1724.         // -----------------------------------------------------------------------
  1725.         //  margin:auto
  1726.         // -----------------------------------------------------------------------

  1727.         function fixMargin(element) {
  1728.             var parent = element.parentElement;
  1729.             var margin = parent.offsetWidth - element.offsetWidth - getPaddingWidth(parent);
  1730.             var autoRight = (element.currentStyle["ie7-margin"] && element.currentStyle.marginRight === "auto") ||
  1731.                 element.currentStyle["ie7-margin-right"] === "auto";
  1732.             switch (parent.currentStyle.textAlign) {
  1733.                 case "right":
  1734.                     margin = autoRight ? parseInt(margin / 2) : 0;
  1735.                     element.runtimeStyle.marginRight = margin + "px";
  1736.                     break;
  1737.                 case "center":
  1738.                     if (autoRight) margin = 0;
  1739.                 default:
  1740.                     if (autoRight) margin /= 2;
  1741.                     element.runtimeStyle.marginLeft = parseInt(margin) + "px";
  1742.             }
  1743.         };

  1744.         function getPaddingWidth(element) {
  1745.             return getPixelValue(element, element.currentStyle.paddingLeft) +
  1746.                 getPixelValue(element, element.currentStyle.paddingRight);
  1747.         };

  1748.         IE7.CSS.addRecalc("margin(-left|-right)?", "[^};]*auto", function(element) {
  1749.             if (register(fixMargin, element,
  1750.                     element.parentElement &&
  1751.                     element.currentStyle.display === "block" &&
  1752.                     element.currentStyle.marginLeft === "auto" &&
  1753.                     element.currentStyle.position !== "absolute")) {
  1754.                 fixMargin(element);
  1755.             }
  1756.         });

  1757.         addResize(function() {
  1758.             for (var i in fixMargin.elements) {
  1759.                 var element = fixMargin.elements[i];
  1760.                 element.runtimeStyle.marginLeft =
  1761.                     element.runtimeStyle.marginRight = "";
  1762.                 fixMargin(element);
  1763.             }
  1764.         });
  1765.     };


  1766. // =========================================================================
  1767. // ie8-css.js
  1768. // =========================================================================

  1769.     var BRACKETS = "\\([^)]+\\)";

  1770. // pseudo-elements can be declared with a double colon
  1771.     encoder.add(/::(before|after)/, ":$1");

  1772.     if (appVersion < 8) {

  1773.         if (IE7.CSS.pseudoClasses) IE7.CSS.pseudoClasses += "|";
  1774.         IE7.CSS.pseudoClasses += "before|after|lang" + BRACKETS;

  1775.         // -----------------------------------------------------------------------
  1776.         // propertyName: inherit;
  1777.         // -----------------------------------------------------------------------

  1778.         function parseInherited(cssText) {
  1779.             return cssText.replace(new RegExp("([{;\\s])(" + inheritedProperties.join("|") + ")\\s*:\\s*([^;}]+)", "g"), "$1$2:$3;ie7-$2:$3");
  1780.         };

  1781.         var INHERITED = /[\w-]+\s*:\s*inherit/g;
  1782.         var STRIP_IE7_FLAGS = /ie7\-|\s*:\s*inherit/g;
  1783.         var DASH_LOWER = /\-([a-z])/g;
  1784.         function toUpper(match, chr) {return chr.toUpperCase()};

  1785.         IE7.CSS.addRecalc("[\\w-]+", "inherit", function(element, cssText) {
  1786.             if (element.parentElement) {
  1787.                 var inherited = cssText.match(INHERITED);
  1788.                 for (var i = 0; i < inherited.length; i++) {
  1789.                     var propertyName = inherited[i].replace(STRIP_IE7_FLAGS, "");
  1790.                     if (element.currentStyle["ie7-" + propertyName] === "inherit") {
  1791.                         propertyName = propertyName.replace(DASH_LOWER, toUpper);
  1792.                         element.runtimeStyle[propertyName] = element.parentElement.currentStyle[propertyName];
  1793.                     }
  1794.                 }
  1795.             }
  1796.         }, function(match) {
  1797.             inheritedProperties.push(rescape(match.slice(1).split(":")[0]));
  1798.             return match;
  1799.         });

  1800.         // -----------------------------------------------------------------------
  1801.         // dynamic pseudo-classes
  1802.         // -----------------------------------------------------------------------

  1803.         var Focus = new DynamicPseudoClass("focus", function(element) {
  1804.             var instance = arguments;

  1805.             IE7.CSS.addEventHandler(element, "onfocus", function() {
  1806.                 Focus.unregister(instance); // in case it starts with focus
  1807.                 Focus.register(instance);
  1808.             });

  1809.             IE7.CSS.addEventHandler(element, "onblur", function() {
  1810.                 Focus.unregister(instance);
  1811.             });

  1812.             // check the active element for initial state
  1813.             if (element == document.activeElement) {
  1814.                 Focus.register(instance)
  1815.             }
  1816.         });

  1817.         var Active = new DynamicPseudoClass("active", function(element) {
  1818.             var instance = arguments;
  1819.             IE7.CSS.addEventHandler(element, "onmousedown", function() {
  1820.                 Active.register(instance);
  1821.             });
  1822.         });

  1823.         // globally trap the mouseup event (thanks Martijn!)
  1824.         addEventHandler(document, "onmouseup", function() {
  1825.             var instances = Active.instances;
  1826.             for (var i in instances) Active.unregister(instances[i]);
  1827.         });

  1828.         // -----------------------------------------------------------------------
  1829.         // IE7 pseudo elements
  1830.         // -----------------------------------------------------------------------

  1831.         // constants
  1832.         var URL = /^url\s*\(\s*([^)]*)\)$/;
  1833.         var POSITION_MAP = {
  1834.             before0: "beforeBegin",
  1835.             before1: "afterBegin",
  1836.             after0: "afterEnd",
  1837.             after1: "beforeEnd"
  1838.         };

  1839.         var PseudoElement = IE7.PseudoElement = Rule.extend({
  1840.             constructor: function(selector, position, cssText) {
  1841.                 // initialise object properties
  1842.                 this.position = position;
  1843.                 var content = cssText.match(PseudoElement.CONTENT), match, entity;
  1844.                 if (content) {
  1845.                     content = content[1];
  1846.                     match = content.split(/\s+/);
  1847.                     for (var i = 0; (entity = match[i]); i++) {
  1848.                         match[i] = /^attr/.test(entity) ? {attr: entity.slice(5, -1)} :
  1849.                             entity.charAt(0) === "'" ? getString(entity) : decode(entity);
  1850.                     }
  1851.                     content = match;
  1852.                 }
  1853.                 this.content = content;
  1854.                 // CSS text needs to be decoded immediately
  1855.                 this.base(selector, decode(cssText));
  1856.             },

  1857.             init: function() {
  1858.                 // execute the underlying css query for this class
  1859.                 this.match = cssQuery(this.selector);
  1860.                 for (var i = 0; i < this.match.length; i++) {
  1861.                     var runtimeStyle = this.match[i].runtimeStyle;
  1862.                     if (!runtimeStyle[this.position]) runtimeStyle[this.position] = {cssText:""};
  1863.                     runtimeStyle[this.position].cssText += ";" + this.cssText;
  1864.                     if (this.content != null) runtimeStyle[this.position].content = this.content;
  1865.                 }
  1866.             },

  1867.             create: function(target) {
  1868.                 var generated = target.runtimeStyle[this.position];
  1869.                 if (generated) {
  1870.                     // copy the array of values
  1871.                     var content = [].concat(generated.content || "");
  1872.                     for (var j = 0; j < content.length; j++) {
  1873.                         if (typeof content[j] == "object") {
  1874.                             content[j] = target.getAttribute(content[j].attr);
  1875.                         }
  1876.                     }
  1877.                     content = content.join("");
  1878.                     var url = content.match(URL);
  1879.                     var cssText = "overflow:hidden;" + generated.cssText.replace(/'/g, '"');
  1880.                     var position = POSITION_MAP[this.position + Number(target.canHaveChildren)];
  1881.                     var id = 'ie7_pseudo' + PseudoElement.count++;
  1882.                     target.insertAdjacentHTML(position, format(PseudoElement.ANON, this.className, id, cssText, url ? "" : content));
  1883.                     if (url) {
  1884.                         var src = getString(url[1]);
  1885.                         var pseudoElement = document.getElementById(id);
  1886.                         pseudoElement.src = src;
  1887.                         addFilter(pseudoElement, "crop");
  1888.                         var targetIsFloated = target.currentStyle.styleFloat !== "none";
  1889.                         if (pseudoElement.currentStyle.display === "inline" || targetIsFloated) {
  1890.                             if (appVersion < 7 && targetIsFloated && target.canHaveChildren) {
  1891.                                 target.runtimeStyle.display = "inline";
  1892.                                 target.runtimeStyle.position = "relative";
  1893.                                 pseudoElement.runtimeStyle.position = "absolute";
  1894.                             }
  1895.                             pseudoElement.style.display = "inline-block";
  1896.                             if (target.currentStyle.styleFloat !== "none") {
  1897.                                 pseudoElement.style.pixelWidth = target.offsetWidth;
  1898.                             }
  1899.                             var image = new Image;
  1900.                             image.onload = function() {
  1901.                                 pseudoElement.style.pixelWidth = this.width;
  1902.                                 pseudoElement.style.pixelHeight = Math.max(this.height, pseudoElement.offsetHeight);
  1903.                             };
  1904.                             image.src = src;
  1905.                         }
  1906.                     }
  1907.                     target.runtimeStyle[this.position] = null;
  1908.                 }
  1909.             },

  1910.             recalc: function() {
  1911.                 if (this.content == null) return;
  1912.                 for (var i = 0; i < this.match.length; i++) {
  1913.                     this.create(this.match[i]);
  1914.                 }
  1915.             },

  1916.             toString: function() {
  1917.                 return "." + this.className + "{display:inline}";
  1918.             }
  1919.         }, {
  1920.             CONTENT: /content\s*:\s*([^;]*)(;|$)/,
  1921.             ANON: "<ie7:! class='ie7_anon %1' id=%2 style='%3'>%4</ie7:!>",
  1922.             MATCH: /(.*):(before|after).*/,

  1923.             count: 0
  1924.         });

  1925.         IE7._getLang = function(element) {
  1926.             var lang = "";
  1927.             while (element && element.nodeType === 1) {
  1928.                 lang = element.lang || element.getAttribute("lang") || "";
  1929.                 if (lang) break;
  1930.                 element = element.parentNode;
  1931.             }
  1932.             return lang;
  1933.         };

  1934.         FILTER = extend(FILTER, {
  1935.             ":lang\\(([^)]+)\\)":    "((ii=IE7._getLang(e))==='$1'||ii.indexOf('$1-')===0)&&"
  1936.         });
  1937.     }

  1938. // =========================================================================
  1939. // ie8-html.js
  1940. // =========================================================================

  1941.     var UNSUCCESSFUL = /^(submit|reset|button)$/;

  1942. // -----------------------------------------------------------------------
  1943. // <button>
  1944. // -----------------------------------------------------------------------

  1945. // IE bug means that innerText is submitted instead of "value"
  1946.     IE7.HTML.addRecalc("button,input", function(button) {
  1947.         if (button.nodeName === "BUTTON") {
  1948.             var match = button.outerHTML.match(/ value="([^"]*)"/i);
  1949.             button.runtimeStyle.value = match ? match[1] : "";
  1950.         }
  1951.         // flag the button/input that was used to submit the form
  1952.         if (button.type === "submit") {
  1953.             addEventHandler(button, "onclick", function() {
  1954.                 button.runtimeStyle.clicked = true;
  1955.                 setTimeout("document.all." + button.uniqueID + ".runtimeStyle.clicked=false", 1);
  1956.             });
  1957.         }
  1958.     });

  1959. // -----------------------------------------------------------------------
  1960. // <form>
  1961. // -----------------------------------------------------------------------

  1962. // only submit "successful controls
  1963.     IE7.HTML.addRecalc("form", function(form) {
  1964.         addEventHandler(form, "onsubmit", function() {
  1965.             for (var element, i = 0; element = form[i]; i++) {
  1966.                 if (UNSUCCESSFUL.test(element.type) && !element.disabled && !element.runtimeStyle.clicked) {
  1967.                     element.disabled = true;
  1968.                     setTimeout("document.all." + element.uniqueID + ".disabled=false", 1);
  1969.                 } else if (element.nodeName === "BUTTON" && element.type === "submit") {
  1970.                     setTimeout("document.all." + element.uniqueID + ".value='" + element.value + "'", 1);
  1971.                     element.value = element.runtimeStyle.value;
  1972.                 }
  1973.             }
  1974.         });
  1975.     });

  1976. // -----------------------------------------------------------------------
  1977. // <img>
  1978. // -----------------------------------------------------------------------

  1979. // get rid of the spurious tooltip produced by the alt attribute on images
  1980.     IE7.HTML.addRecalc("img", function(img) {
  1981.         if (img.alt && !img.title) img.title = "";
  1982.     });

  1983. // =========================================================================
  1984. // ie8-layout.js
  1985. // =========================================================================

  1986.     if (appVersion < 8) {
  1987.         IE7.CSS.addRecalc("border-spacing", NUMERIC, function(element) {
  1988.             if (element.currentStyle.borderCollapse !== "collapse") {
  1989.                 element.cellSpacing = getPixelValue(element, element.currentStyle["ie7-border-spacing"].split(" ")[0]);
  1990.             }
  1991.         });
  1992.         IE7.CSS.addRecalc("box-sizing", "content-box", IE7.Layout.boxSizing);
  1993.         IE7.CSS.addRecalc("box-sizing", "border-box", IE7.Layout.borderBox);
  1994.     }

  1995. // =========================================================================
  1996. // ie8-graphics.js
  1997. // =========================================================================

  1998.     if (appVersion < 8) {
  1999.         // fix object[type=image/*]
  2000.         var IMAGE = /^image/i;
  2001.         IE7.HTML.addRecalc("object", function(element) {
  2002.             if (IMAGE.test(element.type)) {
  2003.                 element.body.style.cssText = "margin:0;padding:0;border:none;overflow:hidden";
  2004.                 return element;
  2005.             }
  2006.         });
  2007.     }

  2008. // =========================================================================
  2009. // ie9-css.js
  2010. // =========================================================================

  2011.     var NOT_NEXT_BY_TYPE     = "!IE7._getElementSiblingByType(e,'next')&&",
  2012.         NOT_PREVIOUS_BY_TYPE = NOT_NEXT_BY_TYPE.replace("next", "previous");

  2013.     if (IE7.CSS.pseudoClasses) IE7.CSS.pseudoClasses += "|";
  2014.     IE7.CSS.pseudoClasses += "(?:first|last|only)\\-(?:child|of\\-type)|empty|root|target|" +
  2015.         ("not|nth\\-child|nth\\-last\\-child|nth\\-of\\-type|nth\\-last\\-of\\-type".split("|").join(BRACKETS + "|") + BRACKETS);

  2016. // :checked
  2017.     var Checked = new DynamicPseudoClass("checked", function(element) {
  2018.         if (typeof element.checked !== "boolean") return;
  2019.         var instance = arguments;
  2020.         IE7.CSS.addEventHandler(element, "onpropertychange", function() {
  2021.             if (event.propertyName === "checked") {
  2022.                 if (element.checked === true) Checked.register(instance);
  2023.                 else Checked.unregister(instance);
  2024.             }
  2025.         });
  2026.         // check current checked state
  2027.         if (element.checked === true) Checked.register(instance);
  2028.     });

  2029. // :enabled
  2030.     var Enabled = new DynamicPseudoClass("enabled", function(element) {
  2031.         if (typeof element.disabled !== "boolean") return;
  2032.         var instance = arguments;
  2033.         IE7.CSS.addEventHandler(element, "onpropertychange", function() {
  2034.             if (event.propertyName === "disabled") {
  2035.                 if (element.disabled === false) Enabled.register(instance);
  2036.                 else Enabled.unregister(instance);
  2037.             }
  2038.         });
  2039.         // check current disabled state
  2040.         if (element.disabled === false) Enabled.register(instance);
  2041.     });

  2042. // :disabled
  2043.     var Disabled = new DynamicPseudoClass("disabled", function(element) {
  2044.         if (typeof element.disabled !== "boolean") return;
  2045.         var instance = arguments;
  2046.         IE7.CSS.addEventHandler(element, "onpropertychange", function() {
  2047.             if (event.propertyName === "disabled") {
  2048.                 if (element.disabled === true) Disabled.register(instance);
  2049.                 else Disabled.unregister(instance);
  2050.             }
  2051.         });
  2052.         // check current disabled state
  2053.         if (element.disabled === true) Disabled.register(instance);
  2054.     });

  2055. // :indeterminate (Kevin Newman)
  2056.     var Indeterminate = new DynamicPseudoClass("indeterminate", function(element) {
  2057.         if (typeof element.indeterminate !== "boolean") return;
  2058.         var instance = arguments;
  2059.         IE7.CSS.addEventHandler(element, "onpropertychange", function() {
  2060.             if (event.propertyName === "indeterminate") {
  2061.                 if (element.indeterminate === true) Indeterminate.register(instance);
  2062.                 else Indeterminate.unregister(instance);
  2063.             }
  2064.         });
  2065.         IE7.CSS.addEventHandler(element, "onclick", function() {
  2066.             Indeterminate.unregister(instance);
  2067.         });
  2068.         // clever Kev says no need to check this up front
  2069.     });

  2070. // :target
  2071.     var Target = new DynamicPseudoClass("target", function(element) {
  2072.         var instance = arguments;
  2073.         // if an element has a tabIndex then it can become "active".
  2074.         //  The default is zero anyway but it works...
  2075.         if (!element.tabIndex) element.tabIndex = 0;
  2076.         // this doesn't detect the back button. I don't know how to do that without adding an iframe :-(
  2077.         IE7.CSS.addEventHandler(document, "onpropertychange", function() {
  2078.             if (event.propertyName === "activeElement") {
  2079.                 if (element.id && element.id === location.hash.slice(1)) Target.register(instance);
  2080.                 else Target.unregister(instance);
  2081.             }
  2082.         });
  2083.         // check the current location
  2084.         if (element.id && element.id === location.hash.slice(1)) Target.register(instance);
  2085.     });

  2086. // Register a node and index its siblings.
  2087.     var _currentIndex = 1, // -@DRE
  2088.         allIndexes = {_currentIndex: 1};

  2089.     IE7._indexOf = function(element, last, ofType) {
  2090.         var parent = element.parentNode;
  2091.         if (!parent || parent.nodeType !== 1) return NaN;

  2092.         var tagName = ofType ? element.nodeName : "";
  2093.         if (tagName === "TR" && element.sectionRowIndex >= 0) {
  2094.             var index = element.sectionRowIndex;
  2095.             return last ? element.parentNode.rows.length - index + 1 : index;
  2096.         }
  2097.         if ((tagName === "TD" || tagName === "TH") && element.cellIndex >= 0) {
  2098.             index = element.cellIndex;
  2099.             return last ? element.parentNode.cells.length - index + 1 : index;
  2100.         }
  2101.         if (allIndexes._currentIndex !== _currentIndex) {
  2102.             allIndexes = {_currentIndex: _currentIndex};
  2103.         }
  2104.         var id = (parent.uniqueID) + "-" + tagName,
  2105.             indexes = allIndexes[id];
  2106.         if (!indexes) {
  2107.             indexes = {};
  2108.             var index = 0,
  2109.                 child = parent.firstChild;
  2110.             while (child) {
  2111.                 if (ofType ? child.nodeName === tagName : child.nodeName > "@") {
  2112.                     indexes[child.uniqueID] = ++index;
  2113.                 }
  2114.                 child = child.nextSibling;
  2115.             }
  2116.             indexes.length = index;
  2117.             allIndexes[id] = indexes;
  2118.         }
  2119.         index = indexes[element.uniqueID];
  2120.         return last ? indexes.length - index + 1 : index;
  2121.     };

  2122.     IE7._isEmpty = function(node) {
  2123.         node = node.firstChild;
  2124.         while (node) {
  2125.             if (node.nodeType === 3 || node.nodeName > "@") return false;
  2126.             node = node.nextSibling;
  2127.         }
  2128.         return true;
  2129.     };

  2130.     IE7._getElementSiblingByType = function(node, direction) {
  2131.         var tagName = node.nodeName;
  2132.         direction += "Sibling";
  2133.         do {
  2134.             node = node[direction];
  2135.             if (node && node.nodeName === tagName) break;
  2136.         } while (node);
  2137.         return node;
  2138.     };

  2139.     var ONE = {"+": 1, "-": -1}, SPACES = / /g;

  2140.     FILTER = extend(extend({
  2141.         ":nth(-last)?-(?:child|(of-type))\\((<#nth_arg>)\\)(<#filter>)?": function(match, last, ofType, args, filters) { // :nth- pseudo classes
  2142.             args = args.replace(SPACES, "");

  2143.             var index = "IE7._indexOf(e," + !!last + "," + !!ofType + ")";

  2144.             if (args === "even") args = "2n";
  2145.             else if (args === "odd") args = "2n+1";
  2146.             else if (!isNaN(args)) args = "0n" + ~~args;

  2147.             args = args.split("n");
  2148.             var a = ~~(ONE[args[0]] || args[0] || 1),
  2149.                 b = ~~args[1];
  2150.             if (a === 0) {
  2151.                 var expr = index + "===" + b;
  2152.             } else {
  2153.                 expr = "((ii=" + index + ")-(" + b + "))%" + a + "===0&&ii" + (a < 0 ? "<" : ">") + "=" + b;
  2154.             }
  2155.             return this.parse(filters) + expr + "&&";
  2156.         },

  2157.         "<#negation>": function(match, simple) {
  2158.             if (/:not/i.test(simple)) throwSelectorError();

  2159.             if (/^[#.:\[]/.test(simple)) {
  2160.                 simple = "*" + simple;
  2161.             }
  2162.             return "!(" + MATCHER.parse(simple).slice(3, -2) + ")&&";
  2163.         }
  2164.     }, FILTER), {
  2165.         ":checked":         "e.checked===true&&",
  2166.         ":disabled":        "e.disabled===true&&",
  2167.         ":enabled":         "e.disabled===false&&",
  2168.         ":last-child":      "!" + NEXT_SIBLING + "&&",
  2169.         ":only-child":      "!" + PREVIOUS_SIBLING + "&&!" + NEXT_SIBLING + "&&",
  2170.         ":first-of-type":   NOT_PREVIOUS_BY_TYPE,
  2171.         ":last-of-type":    NOT_NEXT_BY_TYPE,
  2172.         ":only-of-type":    NOT_PREVIOUS_BY_TYPE + NOT_NEXT_BY_TYPE,

  2173.         ":empty":          "IE7._isEmpty(e)&&",
  2174.         ":root":           "e==R&&",
  2175.         ":target":         "H&&" + ID_ATTRIBUTE + "===H&&"
  2176.     });

  2177.     var HTML5 = "article,aside,audio,canvas,details,figcaption,figure,footer,header,hgroup,mark,menu,meter,nav,output,progress,section,summary,time,video".split(",");
  2178.     for (var i = 0, tagName; tagName = HTML5[i]; i++) document.createElement(tagName);

  2179.     HEADER += "datalist{display:none}\
  2180. details{padding-left:40px;display:block;margin:1em 0}\
  2181. meter,progress{vertical-align:-0.2em;width:5em;height:1em;display:inline-block}\
  2182. progress{width:10em;}\
  2183. article,aside,figcaption,footer,header,hgroup,summary,section,nav{display:block;margin:1em 0}\
  2184. figure{margin:1em 40px;display:block}\
  2185. mark{background:yellow}";

  2186. // =========================================================================
  2187. // ie9-layout.js
  2188. // =========================================================================

  2189. // =========================================================================
  2190. // ie9-graphics.js
  2191. // =========================================================================

  2192.     IE7.CSS.addFix(/\bopacity\s*:\s*([\d.]+)/, function(match, value) {
  2193.         return "zoom:1;filter:Alpha(opacity=" + ((value * 100) || 1) + ")";
  2194.     });

  2195.     var MATCHER;

  2196.     var cssQuery = (function() {
  2197.         var CONTEXT = /^[>+~]/;

  2198.         var useContext = false;

  2199.         // This is not a selector engine in the strictest sense. So it's best to silently error.
  2200.         function cssQuery(selector, context, single) {
  2201.             selector = trim(selector);
  2202.             if (!context) context = document;
  2203.             var ref = context;
  2204.             useContext = CONTEXT.test(selector);
  2205.             if (useContext) {
  2206.                 context = context.parentNode;
  2207.                 selector = "*" + selector;
  2208.             }
  2209.             try {
  2210.                 return selectQuery.create(selector, useContext)(context, single ? null : [], ref);
  2211.             } catch (ex) {
  2212.                 return single ? null : [];
  2213.             }
  2214.         };

  2215.         var VALID_SELECTOR = /^(\\.|[' >+~#.\[\]:*(),\w-\^|$=]|[^\x00-\xa0])+$/;

  2216.         var _EVALUATED = /^(href|src)$/;
  2217.         var _ATTRIBUTES = {
  2218.             "class": "className",
  2219.             "for": "htmlFor"
  2220.         };

  2221.         var IE7_CLASS_NAMES = /\sie7_\w+/g;

  2222.         var USE_IFLAG = /^(action|cite|codebase|data|dynsrc|href|longdesc|lowsrc|src|usemap|url)$/i;

  2223.         IE7._getAttribute = function(element, name) {
  2224.             if (element.getAttributeNode) {
  2225.                 var attribute = element.getAttributeNode(name);
  2226.             }
  2227.             name = _ATTRIBUTES[name.toLowerCase()] || name;
  2228.             if (!attribute) attribute = element.attributes[name];
  2229.             var specified = attribute && attribute.specified;

  2230.             if (element[name] && typeof element[name] == "boolean") return name.toLowerCase();
  2231.             if ((specified && USE_IFLAG.test(name)) || (!attribute && MSIE5) || name === "value" || name === "type") {
  2232.                 return element.getAttribute(name, 2);
  2233.             }
  2234.             if (name === "style") return element.style.cssText.toLowerCase() || null;

  2235.             return specified ? String(attribute.nodeValue) : null;
  2236.         };

  2237.         var names = "colSpan,rowSpan,vAlign,dateTime,accessKey,tabIndex,encType,maxLength,readOnly,longDesc";
  2238.         // Convert the list of strings to a hash, mapping the lowercase name to the camelCase name.
  2239.         extend(_ATTRIBUTES, combine(names.toLowerCase().split(","), names.split(",")));

  2240.         IE7._getElementSibling = function(node, direction) {
  2241.             direction += "Sibling";
  2242.             do {
  2243.                 node = node[direction];
  2244.                 if (node && node.nodeName > "@") break;
  2245.             } while (node);
  2246.             return node;
  2247.         };

  2248.         var IMPLIED_ASTERISK    = /(^|[, >+~])([#.:\[])/g,
  2249.             BLOCKS              = /\)\{/g,
  2250.             COMMA               = /,/,
  2251.             QUOTED              = /^['"]/,
  2252.             HEX_ESCAPE          = /\\([\da-f]{2,2})/gi,
  2253.             LAST_CHILD          = /last/i;

  2254.         IE7._byId = function(document, id) {
  2255.             var result = document.all[id] || null;
  2256.             // Returns a single element or a collection.
  2257.             if (!result || (result.nodeType && IE7._getAttribute(result, "id") === id)) return result;
  2258.             // document.all has returned a collection of elements with name/id
  2259.             for (var i = 0; i < result.length; i++) {
  2260.                 if (IE7._getAttribute(result[i], "id") === id) return result[i];
  2261.             }
  2262.             return null;
  2263.         };

  2264.         // =========================================================================
  2265.         // dom/selectors-api/CSSSelectorParser.js
  2266.         // =========================================================================

  2267.         // http://www.w3.org/TR/css3-selectors/#w3cselgrammar (kinda)
  2268.         var CSSSelectorParser = RegGrp.extend({
  2269.             dictionary: new Dictionary({
  2270.                 ident:           /\-?(\\.|[_a-z]|[^\x00-\xa0])(\\.|[\w-]|[^\x00-\xa0])*/,
  2271.                 combinator:      /[\s>+~]/,
  2272.                 operator:        /[\^~|$*]?=/,
  2273.                 nth_arg:         /[+-]?\d+|[+-]?\d*n(?:\s*[+-]\s*\d+)?|even|odd/,
  2274.                 tag:             /\*|<#ident>/,
  2275.                 id:              /#(<#ident>)/,
  2276.                 'class':         /\.(<#ident>)/,
  2277.                 pseudo:          /\:([\w-]+)(?:\(([^)]+)\))?/,
  2278.                 attr:            /\[(<#ident>)(?:(<#operator>)((?:\\.|[^\[\]#.:])+))?\]/,
  2279.                 negation:        /:not\((<#tag>|<#id>|<#class>|<#attr>|<#pseudo>)\)/,
  2280.                 sequence:        /(\\.|[~*]=|\+\d|\+?\d*n\s*\+\s*\d|[^\s>+~,\*])+/,
  2281.                 filter:          /[#.:\[]<#sequence>/,
  2282.                 selector:        /[^>+~](\\.|[^,])*?/,
  2283.                 grammar:         /^(<#selector>)((,<#selector>)*)$/
  2284.             }),

  2285.             ignoreCase: true
  2286.         });

  2287.         var normalizer = new CSSSelectorParser({
  2288.             "\\\\.|[~*]\\s+=|\\+\\s+\\d": RegGrp.IGNORE,
  2289.             "\\[\\s+": "[",
  2290.             "\\(\\s+": "(",
  2291.             "\\s+\\)": ")",
  2292.             "\\s+\\]": "]",
  2293.             "\\s*([,>+~]|<#operator>)\\s*": "$1",
  2294.             "\\s+$": "",
  2295.             "\\s+": " "
  2296.         });

  2297.         function normalize(selector) {
  2298.             selector = normalizer.parse(selector.replace(HEX_ESCAPE, "\\x$1"))
  2299.                 .replace(UNESCAPE, "$1")
  2300.                 .replace(IMPLIED_ASTERISK, "$1*$2");
  2301.             if (!VALID_SELECTOR.test(selector)) throwSelectorError();
  2302.             return selector;
  2303.         };

  2304.         function unescape(query) {
  2305.             // put string values back
  2306.             return query.replace(ESCAPED, unescapeString);
  2307.         };

  2308.         function unescapeString(match, index) {
  2309.             return strings[index];
  2310.         };

  2311.         var BRACES = /\{/g, BRACES_ESCAPED = /\\{/g;

  2312.         function closeBlock(group) {
  2313.             return Array((group.replace(BRACES_ESCAPED, "").match(BRACES) || "").length + 1).join("}");
  2314.         };

  2315.         FILTER = new CSSSelectorParser(FILTER);

  2316.         var TARGET = /:target/i, ROOT = /:root/i;

  2317.         function getConstants(selector) {
  2318.             var constants = "";
  2319.             if (ROOT.test(selector)) constants += ",R=d.documentElement";
  2320.             if (TARGET.test(selector)) constants += ",H=d.location;H=H&&H.hash.replace('#','')";
  2321.             if (constants || selector.indexOf("#") !== -1) {
  2322.                 constants = ",t=c.nodeType,d=t===9?c:c.ownerDocument||(c.document||c).parentWindow.document" + constants;
  2323.             }
  2324.             return "var ii" + constants + ";";
  2325.         };

  2326.         var COMBINATOR = {
  2327.             " ":   ";while(e!=s&&(e=e.parentNode)&&e.nodeType===1){",
  2328.             ">":   ".parentElement;if(e){",
  2329.             "+":   ";while((e=e.previousSibling)&&!(" + IS_ELEMENT + "))continue;if(e){",
  2330.             "~":   ";while((e=e.previousSibling)){" + IF_ELEMENT
  2331.         };

  2332.         var TOKEN = /\be\b/g;

  2333.         MATCHER = new CSSSelectorParser({
  2334.             "(?:(<#selector>)(<#combinator>))?(<#tag>)(<#filter>)?$": function(match, before, combinator, tag, filters) {
  2335.                 var group = "";
  2336.                 if (tag !== "*") {
  2337.                     var TAG = tag.toUpperCase();
  2338.                     group += "if(e.nodeName==='" + TAG + (TAG === tag ? "" : "'||e.nodeName==='" + tag) + "'){";
  2339.                 }
  2340.                 if (filters) {
  2341.                     group += "if(" + FILTER.parse(filters).slice(0, -2) + "){";
  2342.                 }
  2343.                 group = group.replace(TOKEN, "e" + this.index);
  2344.                 if (combinator) {
  2345.                     group += "var e=e" + (this.index++) + COMBINATOR[combinator];
  2346.                     group = group.replace(TOKEN, "e" + this.index);
  2347.                 }
  2348.                 if (before) {
  2349.                     group += this.parse(before);
  2350.                 }
  2351.                 return group;
  2352.             }
  2353.         });

  2354.         var BY_ID       = "e0=IE7._byId(d,'%1');if(e0){",
  2355.             BY_TAG_NAME = "var n=c.getElementsByTagName('%1');",
  2356.             STORE       = "if(r==null)return e0;r[k++]=e0;";

  2357.         var TAG_NAME = 1;

  2358.         var SELECTOR = new CSSSelectorParser({
  2359.             "^((?:<#selector>)?(?:<#combinator>))(<#tag>)(<#filter>)?$": true
  2360.         });

  2361.         var cache = {};

  2362.         var selectById = new CSSSelectorParser({
  2363.             "^(<#tag>)#(<#ident>)(<#filter>)?( [^,]*)?$": function(match, tagName, id, filters, after) {
  2364.                 var block = format(BY_ID, id), endBlock = "}";
  2365.                 if (filters) {
  2366.                     block += MATCHER.parse(tagName + filters);
  2367.                     endBlock = closeBlock(block);
  2368.                 }
  2369.                 if (after) {
  2370.                     block += "s=c=e0;" + selectQuery.parse("*" + after);
  2371.                 } else {
  2372.                     block += STORE;
  2373.                 }
  2374.                 return block + endBlock;
  2375.             },

  2376.             "^([^#,]+)#(<#ident>)(<#filter>)?$": function(match, before, id, filters) {
  2377.                 var block = format(BY_ID, id);
  2378.                 if (before === "*") {
  2379.                     block += STORE;
  2380.                 } else {
  2381.                     block += MATCHER.parse(before + filters) + STORE + "break";
  2382.                 }
  2383.                 return block + closeBlock(block);
  2384.             },

  2385.             "^.*$": ""
  2386.         });

  2387.         var selectQuery = new CSSSelectorParser({
  2388.             "<#grammar>": function(match, selector, remainingSelectors) {
  2389.                 if (!this.groups) this.groups = [];

  2390.                 var group = SELECTOR.exec(" " + selector);

  2391.                 if (!group) throwSelectorError();

  2392.                 this.groups.push(group.slice(1));

  2393.                 if (remainingSelectors) {
  2394.                     return this.parse(remainingSelectors.replace(COMMA, ""));
  2395.                 }

  2396.                 var groups = this.groups,
  2397.                     tagName = groups[0][TAG_NAME]; // first tag name

  2398.                 for (var i = 1; group = groups[i]; i++) { // search tag names
  2399.                     if (tagName !== group[TAG_NAME]) {
  2400.                         tagName = "*"; // mixed tag names, so use "*"
  2401.                         break;
  2402.                     }
  2403.                 }

  2404.                 var matcher = "", store = STORE + "continue filtering;";

  2405.                 for (var i = 0; group = groups[i]; i++) {
  2406.                     MATCHER.index = 0;
  2407.                     if (tagName !== "*") group[TAG_NAME] = "*"; // we are already filtering by tagName
  2408.                     group = group.join("");
  2409.                     if (group === " *") { // select all
  2410.                         matcher = store;
  2411.                         break;
  2412.                     } else {
  2413.                         group = MATCHER.parse(group);
  2414.                         if (useContext) group += "if(e" + MATCHER.index + "==s){";
  2415.                         matcher += group + store + closeBlock(group);
  2416.                     }
  2417.                 }

  2418.                 // reduce to a single loop
  2419.                 var isWild = tagName === "*";
  2420.                 return (isWild ? "var n=c.all;" : format(BY_TAG_NAME, tagName)) +
  2421.                     "filtering:while((e0=n[i++]))" +
  2422.                     (isWild ? IF_ELEMENT.replace(TOKEN, "e0") : "{") +
  2423.                     matcher +
  2424.                     "}";
  2425.             },

  2426.             "^.*$": throwSelectorError
  2427.         });

  2428.         var REDUNDANT_NODETYPE_CHECKS = /\&\&(e\d+)\.nodeType===1(\)\{\s*if\(\1\.nodeName=)/g;

  2429.         selectQuery.create = function(selector) {
  2430.             if (!cache[selector]) {
  2431.                 selector = normalize(selector);
  2432.                 this.groups = null;
  2433.                 MATCHER.index = 0;
  2434.                 var block = this.parse(selector);
  2435.                 this.groups = null;
  2436.                 MATCHER.index = 0;
  2437.                 if (selector.indexOf("#") !== -1) {
  2438.                     var byId  = selectById.parse(selector);
  2439.                     if (byId) {
  2440.                         block =
  2441.                             "if(t===1||t===11|!c.getElementById){" +
  2442.                             block +
  2443.                             "}else{" +
  2444.                             byId +
  2445.                             "}";
  2446.                     }
  2447.                 }
  2448.                 // remove redundant nodeType==1 checks
  2449.                 block = block.replace(REDUNDANT_NODETYPE_CHECKS, "$2");
  2450.                 block = getConstants(selector) + decode(block);
  2451.                 cache[selector] = new Function("return function(c,r,s){var i=0,k=0,e0;" + block + "return r}")();
  2452.             }
  2453.             return cache[selector];
  2454.         };

  2455.         return cssQuery;
  2456.     })();

  2457.     function throwSelectorError() {
  2458.         throw new SyntaxError("Invalid selector.");
  2459.     };

  2460. // -----------------------------------------------------------------------
  2461. // initialisation
  2462. // -----------------------------------------------------------------------

  2463.     IE7.loaded = true;
  2464.     IE7.styleLoaded = false;

  2465.     (function() {
  2466.         try {
  2467.             // http://javascript.nwbox.com/IEContentLoaded/
  2468.             if (!IE7.styleLoaded) {
  2469.                 // Hide <body> before applying IE fixes to avoid rendering issues
  2470.                 var headID = document.getElementsByTagName("head")[0];
  2471.                 var cssNode = document.createElement('style');
  2472.                 cssNode.type = 'text/css';
  2473.                 cssNode.styleSheet.cssText = 'body{display:none;}';
  2474.                 headID.appendChild(cssNode);
  2475.                 IE7.styleLoaded = true;
  2476.             }
  2477.             if (!document.body) throw "continue";
  2478.             documentElement.doScroll("left");
  2479.         } catch (ex) {
  2480.             setTimeout(arguments.callee, 1);
  2481.             return;
  2482.         }
  2483.         // execute the inner text of the IE7 script
  2484.         try {
  2485.             eval(script.innerHTML);
  2486.         } catch (ex) {
  2487.             // ignore errors
  2488.         }
  2489.         if (typeof IE7_PNG_SUFFIX == "object") {
  2490.             PNG = IE7_PNG_SUFFIX;
  2491.         } else {
  2492.             PNG = new RegExp(rescape(window.IE7_PNG_SUFFIX || "-trans.png") + "(\\?.*)?$", "i");
  2493.         }

  2494.         // frequently used references
  2495.         body = document.body;
  2496.         viewport = MSIE5 ? body : documentElement;

  2497.         // classes
  2498.         body.className += " ie7_body";
  2499.         documentElement.className += " ie7_html";

  2500.         if (MSIE5) ie7Quirks();

  2501.         IE7.CSS.init();
  2502.         IE7.HTML.init();

  2503.         IE7.HTML.apply();
  2504.         IE7.CSS.apply();

  2505.         IE7.recalc();

  2506.         // Display <body> again after applying IE fixes
  2507.         document.body.style.display = 'block';
  2508.     })();

  2509. })(this, document);
复制代码


回复

使用道具 举报

发表于 2018-3-27 10:24:02 | 显示全部楼层
我用了页面错乱
回复

使用道具 举报

发表于 2018-11-21 19:01:40 | 显示全部楼层
完全看不懂啊
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|Discuz代码分析|Discuz目录结构|DZ起点网 ( 蜀ICP备13000518号-15 )

GMT+8, 2024-4-27 00:53 , Processed in 0.065061 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表