PageRenderTime 77ms CodeModel.GetById 21ms app.highlight 44ms RepoModel.GetById 0ms app.codeStats 0ms

/static/scripts/IE8.js

https://bitbucket.org/ialbert/galaxy-genetrack
JavaScript | 2601 lines | 2409 code | 87 blank | 105 comment | 114 complexity | 1c54183c35f314e40f072837b4ed31ba MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1// timestamp: Sun, 03 Feb 2008 19:26:22
   2/*
   3  IE7/IE8.js - copyright 2004-2008, Dean Edwards
   4  http://dean.edwards.name/IE7/
   5  http://www.opensource.org/licenses/mit-license.php
   6*/
   7
   8/* W3C compliance for Microsoft Internet Explorer */
   9
  10/* credits/thanks:
  11  Shaggy, Martijn Wargers, Jimmy Cerra, Mark D Anderson,
  12  Lars Dieckow, Erik Arvidsson, Gell�rt Gyuris, James Denny,
  13  Unknown W Brackets, Benjamin Westfarer, Rob Eberhardt,
  14  Bill Edney, Kevin Newman, James Crompton, Matthew Mastracci,
  15  Doug Wright, Richard York, Kenneth Kolano, MegaZone,
  16  Thomas Verelst, Mark 'Tarquin' Wilton-Jones, Rainer ?hlfors,
  17  David Zulaica, Ken Kolano, Kevin Newman
  18*/
  19
  20// =======================================================================
  21// TO DO
  22// =======================================================================
  23
  24// PNG - unclickable content
  25
  26// =======================================================================
  27// TEST/BUGGY
  28// =======================================================================
  29
  30// hr{margin:1em auto} (doesn't look right in IE5)
  31
  32(function() {
  33
  34IE7 = {
  35  toString: function(){return "IE7 version 2.0 (beta3)"}
  36};
  37var appVersion = IE7.appVersion = navigator.appVersion.match(/MSIE (\d\.\d)/)[1];
  38
  39if (/ie7_off/.test(top.location.search) || appVersion < 5) return;
  40
  41var Undefined = K();
  42var quirksMode = document.compatMode != "CSS1Compat";
  43var documentElement = document.documentElement, body, viewport;
  44var ANON = "!";
  45var HEADER = ":link{ie7-link:link}:visited{ie7-link:visited}";
  46
  47// -----------------------------------------------------------------------
  48// external
  49// -----------------------------------------------------------------------
  50
  51var RELATIVE = /^[\w\.]+[^:]*$/;
  52function makePath(href, path) {
  53  if (RELATIVE.test(href)) href = (path || "") + href;
  54  return href;
  55};
  56
  57function getPath(href, path) {
  58  href = makePath(href, path);
  59  return href.slice(0, href.lastIndexOf("/") + 1);
  60};
  61
  62// get the path to this script
  63var script = document.scripts[document.scripts.length - 1];
  64var path = getPath(script.src);
  65
  66// we'll use microsoft's http request object to load external files
  67try {
  68  var httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
  69} catch (e) {
  70  // ActiveX disabled
  71}
  72
  73var fileCache = {};
  74function loadFile(href, path) {
  75try {
  76  href = makePath(href, path);
  77  if (!fileCache[href]) {
  78    // easy to load a file huh?
  79    httpRequest.open("GET", href, false);
  80    httpRequest.send();
  81    if (httpRequest.status == 0 || httpRequest.status == 200) {
  82      fileCache[href] = httpRequest.responseText;
  83    }
  84  }
  85} catch (e) {
  86  // ignore errors
  87} finally {
  88  return fileCache[href] || "";
  89}};
  90
  91// -----------------------------------------------------------------------
  92// IE5.0 compatibility
  93// -----------------------------------------------------------------------
  94
  95
  96if (appVersion < 5.5) {
  97  undefined = Undefined();
  98
  99  ANON = "HTML:!"; // for anonymous content
 100  
 101  // Fix String.replace (Safari1.x/IE5.0).
 102  var GLOBAL = /(g|gi)$/;
 103  var _String_replace = String.prototype.replace; 
 104  String.prototype.replace = function(expression, replacement) {
 105    if (typeof replacement == "function") { // Safari doesn't like functions
 106      if (expression && expression.constructor == RegExp) {
 107        var regexp = expression;
 108        var global = regexp.global;
 109        if (global == null) global = GLOBAL.test(regexp);
 110        // we have to convert global RexpExps for exec() to work consistently
 111        if (global) regexp = new RegExp(regexp.source); // non-global
 112      } else {
 113        regexp = new RegExp(rescape(expression));
 114      }
 115      var match, string = this, result = "";
 116      while (string && (match = regexp.exec(string))) {
 117        result += string.slice(0, match.index) + replacement.apply(this, match);
 118        string = string.slice(match.index + match[0].length);
 119        if (!global) break;
 120      }
 121      return result + string;
 122    }
 123    return _String_replace.apply(this, arguments);
 124  };
 125  
 126  Array.prototype.pop = function() {
 127    if (this.length) {
 128      var i = this[this.length - 1];
 129      this.length--;
 130      return i;
 131    }
 132    return undefined;
 133  };
 134  
 135  Array.prototype.push = function() {
 136    for (var i = 0; i < arguments.length; i++) {
 137      this[this.length] = arguments[i];
 138    }
 139    return this.length;
 140  };
 141  
 142  var ns = this;
 143  Function.prototype.apply = function(o, a) {
 144    if (o === undefined) o = ns;
 145    else if (o == null) o = window;
 146    else if (typeof o == "string") o = new String(o);
 147    else if (typeof o == "number") o = new Number(o);
 148    else if (typeof o == "boolean") o = new Boolean(o);
 149    if (arguments.length == 1) a = [];
 150    else if (a[0] && a[0].writeln) a[0] = a[0].documentElement.document || a[0];
 151    var $ = "#ie7_apply", r;
 152    o[$] = this;
 153    switch (a.length) { // unroll for speed
 154      case 0: r = o[$](); break;
 155      case 1: r = o[$](a[0]); break;
 156      case 2: r = o[$](a[0],a[1]); break;
 157      case 3: r = o[$](a[0],a[1],a[2]); break;
 158      case 4: r = o[$](a[0],a[1],a[2],a[3]); break;
 159      case 5: r = o[$](a[0],a[1],a[2],a[3],a[4]); break;
 160      default:
 161        var b = [], i = a.length - 1;
 162        do b[i] = "a[" + i + "]"; while (i--);
 163        eval("r=o[$](" + b + ")");
 164    }
 165    if (typeof o.valueOf == "function") { // not a COM object
 166      delete o[$];
 167    } else {
 168      o[$] = undefined;
 169      if (r && r.writeln) r = r.documentElement.document || r;
 170    }
 171    return r;
 172  };
 173  
 174  Function.prototype.call = function(o) {
 175    return this.apply(o, _slice.apply(arguments, [1]));
 176  };
 177
 178  // block elements are "inline" according to IE5.0 so we'll fix it
 179  HEADER += "address,blockquote,body,dd,div,dt,fieldset,form,"+
 180    "frame,frameset,h1,h2,h3,h4,h5,h6,iframe,noframes,object,p,"+
 181    "hr,applet,center,dir,menu,pre,dl,li,ol,ul{display:block}";
 182}
 183
 184// -----------------------------------------------------------------------
 185// OO support
 186// -----------------------------------------------------------------------
 187
 188
 189// This is a cut-down version of base2 (http://code.google.com/p/base2/)
 190
 191var _slice = Array.prototype.slice;
 192
 193// private
 194var _FORMAT = /%([1-9])/g;
 195var _LTRIM = /^\s\s*/;
 196var _RTRIM = /\s\s*$/;
 197var _RESCAPE = /([\/()[\]{}|*+-.,^$?\\])/g;           // safe regular expressions
 198var _BASE = /\bbase\b/;
 199var _HIDDEN = ["constructor", "toString"];            // only override these when prototyping
 200
 201var prototyping;
 202
 203function Base(){};
 204Base.extend = function(_instance, _static) {
 205  // Build the prototype.
 206  prototyping = true;
 207  var _prototype = new this;
 208  extend(_prototype, _instance);
 209  prototyping = false;
 210
 211  // Create the wrapper for the constructor function.
 212  var _constructor = _prototype.constructor;
 213  function klass() {
 214    // Don't call the constructor function when prototyping.
 215    if (!prototyping) _constructor.apply(this, arguments);
 216  };
 217  _prototype.constructor = klass;
 218
 219  // Build the static interface.
 220  klass.extend = arguments.callee;
 221  extend(klass, _static);
 222  klass.prototype = _prototype;
 223  return klass;
 224};
 225Base.prototype.extend = function(source) {
 226  return extend(this, source);
 227};
 228
 229// A collection of regular expressions and their associated replacement values.
 230// A Base class for creating parsers.
 231
 232var _HASH   = "#";
 233var _KEYS   = "~";
 234
 235var _RG_ESCAPE_CHARS    = /\\./g;
 236var _RG_ESCAPE_BRACKETS = /\(\?[:=!]|\[[^\]]+\]/g;
 237var _RG_BRACKETS        = /\(/g;
 238
 239var RegGrp = Base.extend({
 240  constructor: function(values) {
 241    this[_KEYS] = [];
 242    this.merge(values);
 243  },
 244
 245  exec: function(string) {
 246    var items = this, keys = this[_KEYS];    
 247    return String(string).replace(new RegExp(this, this.ignoreCase ? "gi" : "g"), function() {
 248      var item, offset = 1, i = 0;
 249      // Loop through the RegGrp items.
 250      while ((item = items[_HASH + keys[i++]])) {
 251        var next = offset + item.length + 1;
 252        if (arguments[offset]) { // do we have a result?
 253          var replacement = item.replacement;
 254          switch (typeof replacement) {
 255            case "function":
 256              return replacement.apply(items, _slice.call(arguments, offset, next));
 257            case "number":
 258              return arguments[offset + replacement];
 259            default:
 260              return replacement;
 261          }
 262        }
 263        offset = next;
 264      }
 265    });
 266  },
 267
 268  add: function(expression, replacement) {
 269    if (expression instanceof RegExp) {
 270      expression = expression.source;
 271    }
 272    if (!this[_HASH + expression]) this[_KEYS].push(String(expression));
 273    this[_HASH + expression] = new RegGrp.Item(expression, replacement);
 274  },
 275
 276  merge: function(values) {
 277    for (var i in values) this.add(i, values[i]);
 278  },
 279
 280  toString: function() {
 281    // back references not supported in simple RegGrp
 282    return "(" + this[_KEYS].join(")|(") + ")";
 283  }
 284}, {
 285  IGNORE: "$0",
 286
 287  Item: Base.extend({
 288    constructor: function(expression, replacement) {
 289      expression = expression instanceof RegExp ? expression.source : String(expression);
 290
 291      if (typeof replacement == "number") replacement = String(replacement);
 292      else if (replacement == null) replacement = "";
 293
 294      // does the pattern use sub-expressions?
 295      if (typeof replacement == "string" && /\$(\d+)/.test(replacement)) {
 296        // a simple lookup? (e.g. "$2")
 297        if (/^\$\d+$/.test(replacement)) {
 298          // store the index (used for fast retrieval of matched strings)
 299          replacement = parseInt(replacement.slice(1));
 300        } else { // a complicated lookup (e.g. "Hello $2 $1")
 301          // build a function to do the lookup
 302          var Q = /'/.test(replacement.replace(/\\./g, "")) ? '"' : "'";
 303          replacement = replacement.replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\$(\d+)/g, Q +
 304            "+(arguments[$1]||" + Q+Q + ")+" + Q);
 305          replacement = new Function("return " + Q + replacement.replace(/(['"])\1\+(.*)\+\1\1$/, "$1") + Q);
 306        }
 307      }
 308
 309      this.length = RegGrp.count(expression);
 310      this.replacement = replacement;
 311      this.toString = K(expression);
 312    }
 313  }),
 314
 315  count: function(expression) {
 316    // Count the number of sub-expressions in a RegExp/RegGrp.Item.
 317    expression = String(expression).replace(_RG_ESCAPE_CHARS, "").replace(_RG_ESCAPE_BRACKETS, "");
 318    return match(expression, _RG_BRACKETS).length;
 319  }
 320});
 321
 322// =========================================================================
 323// lang/extend.js
 324// =========================================================================
 325
 326function extend(object, source) { // or extend(object, key, value)
 327  if (object && source) {
 328    var proto = (typeof source == "function" ? Function : Object).prototype;
 329    // Add constructor, toString etc
 330    var i = _HIDDEN.length, key;
 331    if (prototyping) while (key = _HIDDEN[--i]) {
 332      var value = source[key];
 333      if (value != proto[key]) {
 334        if (_BASE.test(value)) {
 335          _override(object, key, value)
 336        } else {
 337          object[key] = value;
 338        }
 339      }
 340    }
 341    // Copy each of the source object's properties to the target object.
 342    for (key in source) if (proto[key] === undefined) {
 343      var value = source[key];
 344      // Check for method overriding.
 345      if (object[key] && typeof value == "function" && _BASE.test(value)) {
 346        _override(object, key, value);
 347      } else {
 348        object[key] = value;
 349      }
 350    }
 351  }
 352  return object;
 353};
 354
 355function _override(object, name, method) {
 356  // Override an existing method.
 357  var ancestor = object[name];
 358  object[name] = function() {
 359    var previous = this.base;
 360    this.base = ancestor;
 361    var returnValue = method.apply(this, arguments);
 362    this.base = previous;
 363    return returnValue;
 364  };
 365};
 366
 367function combine(keys, values) {
 368  // Combine two arrays to make a hash.
 369  if (!values) values = keys;
 370  var hash = {};
 371  for (var i in keys) hash[i] = values[i];
 372  return hash;
 373};
 374
 375function format(string) {
 376  // Replace %n with arguments[n].
 377  // e.g. format("%1 %2%3 %2a %1%3", "she", "se", "lls");
 378  // ==> "she sells sea shells"
 379  // Only %1 - %9 supported.
 380  var args = arguments;
 381  var _FORMAT = new RegExp("%([1-" + arguments.length + "])", "g");
 382  return String(string).replace(_FORMAT, function(match, index) {
 383    return index < args.length ? args[index] : match;
 384  });
 385};
 386
 387function match(string, expression) {
 388  // Same as String.match() except that this function will return an empty
 389  // array if there is no match.
 390  return String(string).match(expression) || [];
 391};
 392
 393function rescape(string) {
 394  // Make a string safe for creating a RegExp.
 395  return String(string).replace(_RESCAPE, "\\$1");
 396};
 397
 398// http://blog.stevenlevithan.com/archives/faster-trim-javascript
 399function trim(string) {
 400  return String(string).replace(_LTRIM, "").replace(_RTRIM, "");
 401};
 402
 403function K(k) {
 404  return function() {
 405    return k;
 406  };
 407};
 408
 409// -----------------------------------------------------------------------
 410// parsing
 411// -----------------------------------------------------------------------
 412
 413var Parser = RegGrp.extend({ignoreCase: true});
 414
 415var ENCODED = /\x01(\d+)/g,
 416    QUOTES  = /'/g, 
 417    STRING = /^\x01/,
 418    UNICODE = /\\([\da-fA-F]{1,4})/g;
 419
 420var _strings = [];
 421
 422var encoder = new Parser({
 423  // comments
 424  "<!\\-\\-|\\-\\->": "",
 425  "\\/\\*[^*]*\\*+([^\\/][^*]*\\*+)*\\/": "",
 426  // get rid
 427  "@(namespace|import)[^;\\n]+[;\\n]": "",
 428  // strings
 429  "'(\\\\.|[^'\\\\])*'": encodeString,
 430  '"(\\\\.|[^"\\\\])*"': encodeString,
 431  // white space
 432  "\\s+": " "
 433});
 434
 435function encode(cssText) {
 436  return encoder.exec(cssText);
 437};
 438
 439function decode(cssText) {
 440  return cssText.replace(ENCODED, function(match, index) {
 441    return _strings[index - 1];
 442  });
 443};
 444
 445function encodeString(string) {
 446  return "\x01" + _strings.push(string.replace(UNICODE, function(match, chr) {
 447    return eval("'\\u" + "0000".slice(chr.length) + chr + "'");
 448  }).slice(1, -1).replace(QUOTES, "\\'"));
 449};
 450
 451function getString(value) {
 452  return STRING.test(value) ? _strings[value.slice(1) - 1] : value;
 453};
 454
 455// clone a "width" function to create a "height" function
 456var rotater = new RegGrp({
 457  Width: "Height",
 458  width: "height",
 459  Left:  "Top",
 460  left:  "top",
 461  Right: "Bottom",
 462  right: "bottom",
 463  onX:   "onY"
 464});
 465
 466function rotate(fn) {
 467  return rotater.exec(fn);
 468};
 469
 470// -----------------------------------------------------------------------
 471// event handling
 472// -----------------------------------------------------------------------
 473
 474var eventHandlers = [];
 475
 476function addResize(handler) {
 477  addRecalc(handler);
 478  addEventHandler(window, "onresize", handler);
 479};
 480
 481// add an event handler (function) to an element
 482function addEventHandler(element, type, handler) {
 483  element.attachEvent(type, handler);
 484  // store the handler so it can be detached later
 485  eventHandlers.push(arguments);
 486};
 487
 488// remove an event handler assigned to an element by IE7
 489function removeEventHandler(element, type, handler) {
 490try {
 491  element.detachEvent(type, handler);
 492} catch (ignore) {
 493  // write a letter of complaint to microsoft..
 494}};
 495
 496// remove event handlers (they eat memory)
 497addEventHandler(window, "onunload", function() {
 498  var handler;
 499  while (handler = eventHandlers.pop()) {
 500    removeEventHandler(handler[0], handler[1], handler[2]);
 501  }
 502});
 503
 504function register(handler, element, condition) { // -@DRE
 505  //var set = handler[element.uniqueID];
 506  if (!handler.elements) handler.elements = {};
 507  if (condition) handler.elements[element.uniqueID] = element;
 508  else delete handler.elements[element.uniqueID];
 509  //return !set && condition;
 510  return condition;
 511};
 512
 513addEventHandler(window, "onbeforeprint", function() {
 514  if (!IE7.CSS.print) new StyleSheet("print");
 515  IE7.CSS.print.recalc();
 516});
 517
 518// -----------------------------------------------------------------------
 519// pixel conversion
 520// -----------------------------------------------------------------------
 521
 522// this is handy because it means that web developers can mix and match
 523//  measurement units in their style sheets. it is not uncommon to
 524//  express something like padding in "em" units whilst border thickness
 525//  is most often expressed in pixels.
 526
 527var PIXEL = /^\d+(px)?$/i;
 528var PERCENT = /^\d+%$/;
 529var getPixelValue = function(element, value) {
 530  if (PIXEL.test(value)) return parseInt(value);
 531  var style = element.style.left;
 532  var runtimeStyle = element.runtimeStyle.left;
 533  element.runtimeStyle.left = element.currentStyle.left;
 534  element.style.left = value || 0;
 535  value = element.style.pixelLeft;
 536  element.style.left = style;
 537  element.runtimeStyle.left = runtimeStyle;
 538  return value;
 539};
 540
 541// -----------------------------------------------------------------------
 542// generic
 543// -----------------------------------------------------------------------
 544
 545var $IE7 = "ie7-";
 546
 547var Fix = Base.extend({
 548  constructor: function() {
 549    this.fixes = [];
 550    this.recalcs = [];
 551  },
 552  init: Undefined
 553});
 554
 555// a store for functions that will be called when refreshing IE7
 556var recalcs = [];
 557function addRecalc(recalc) {
 558  recalcs.push(recalc);
 559};
 560
 561IE7.recalc = function() {
 562  IE7.HTML.recalc();
 563  // re-apply style sheet rules (re-calculate ie7 classes)
 564  IE7.CSS.recalc();
 565  // apply global fixes to the document
 566  for (var i = 0; i < recalcs.length; i++) recalcs[i]();
 567};
 568
 569function isFixed(element) {
 570  return element.currentStyle["ie7-position"] == "fixed";
 571};
 572
 573// original style
 574function getDefinedStyle(element, propertyName) {
 575  return element.currentStyle[$IE7 + propertyName] || element.currentStyle[propertyName];
 576};
 577
 578function setOverrideStyle(element, propertyName, value) {
 579  if (element.currentStyle[$IE7 + propertyName] == null) {
 580    element.runtimeStyle[$IE7 + propertyName] = element.currentStyle[propertyName];
 581  }
 582  element.runtimeStyle[propertyName] = value;
 583};
 584
 585// create a temporary element which is used to inherit styles
 586//  from the target element. the temporary element can be resized
 587//  to determine pixel widths/heights
 588function createTempElement(tagName) {
 589  var element = document.createElement(tagName || "object");
 590  element.style.cssText = "position:absolute;padding:0;display:block;border:none;clip:rect(0 0 0 0);left:-9999";
 591  element.ie7_anon = true;
 592  return element;
 593};
 594
 595
 596// =========================================================================
 597// ie7-cssQuery.js
 598// =========================================================================
 599
 600function cssQuery(selector, context, single) {
 601  if (!_cache[selector]) {
 602    reg = []; // store for RegExp objects
 603    var fn = "";
 604    var selectors = cssParser.escape(selector).split(",");
 605    for (var i = 0; i < selectors.length; i++) {
 606      _wild = _index = _list = 0; // reset
 607      _duplicate = selectors.length > 1 ? 2 : 0; // reset
 608      var block = cssParser.exec(selectors[i]) || "if(0){";
 609      if (_wild) { // IE's pesky comment nodes
 610        block += format("if(e%1.nodeName!='!'){", _index);
 611      }
 612      // check for duplicates before storing results
 613      var store = _duplicate > 1 ? _TEST : "";
 614      block += format(store + _STORE, _index);
 615      // add closing braces
 616      block += Array(match(block, /\{/g).length + 1).join("}");
 617      fn += block;
 618    }
 619    eval(format(_FN, reg) + cssParser.unescape(fn) + "return s?null:r}");
 620    _cache[selector] = _selectorFunction;
 621  }
 622  return _cache[selector](context || document, single);
 623};
 624
 625var _MSIE5 = appVersion < 6;
 626
 627var _EVALUATED = /^(href|src)$/;
 628var _ATTRIBUTES = {
 629  "class": "className",
 630  "for": "htmlFor"
 631};
 632
 633IE7._indexed = 1;
 634
 635IE7._byId = function(document, id) {
 636  var result = document.all[id] || null;
 637  // returns a single element or a collection
 638  if (!result || result.id == id) return result;
 639  // document.all has returned a collection of elements with name/id
 640  for (var i = 0; i < result.length; i++) {
 641    if (result[i].id == id) return result[i];
 642  }
 643  return null;
 644};
 645
 646IE7._getAttribute = function(element, name) {
 647  if (name == "src" && element.pngSrc) return element.pngSrc;
 648  
 649  var attribute = _MSIE5 ? (element.attributes[name] || element.attributes[_ATTRIBUTES[name.toLowerCase()]]) : element.getAttributeNode(name);
 650  if (attribute && (attribute.specified || name == "value")) {
 651    if (_EVALUATED.test(name)) {
 652      return element.getAttribute(name, 2);
 653    } else if (name == "class") {
 654     return element.className.replace(/\sie7_\w+/g, "");
 655    } else if (name == "style") {
 656     return element.style.cssText;
 657    } else {
 658     return attribute.nodeValue;
 659    }
 660  }
 661  return null;
 662};
 663
 664var names = "colSpan,rowSpan,vAlign,dateTime,accessKey,tabIndex,encType,maxLength,readOnly,longDesc";
 665// Convert the list of strings to a hash, mapping the lowercase name to the camelCase name.
 666extend(_ATTRIBUTES, combine(names.toLowerCase().split(","), names.split(",")));
 667
 668IE7._getNextElementSibling = function(node) {
 669  // return the next element to the supplied element
 670  //  nextSibling is not good enough as it might return a text or comment node
 671  while (node && (node = node.nextSibling) && (node.nodeType != 1 || node.nodeName == "!")) continue;
 672  return node;
 673};
 674
 675IE7._getPreviousElementSibling = function(node) {
 676  // return the previous element to the supplied element
 677  while (node && (node = node.previousSibling) && (node.nodeType != 1 || node.nodeName == "!")) continue;
 678  return node;
 679};
 680
 681// =========================================================================
 682// CSSParser
 683// =========================================================================
 684
 685var IMPLIED_ASTERISK = /([\s>+~,]|[^(]\+|^)([#.:\[])/g,
 686    IMPLIED_SPACE =    /(^|,)([^\s>+~])/g,
 687    WHITESPACE =       /\s*([\s>+~(),]|^|$)\s*/g,
 688    WILD_CARD =        /\s\*\s/g;;
 689
 690var CSSParser = RegGrp.extend({
 691  constructor: function(items) {
 692    this.base(items);
 693    this.sorter = new RegGrp;
 694    this.sorter.add(/:not\([^)]*\)/, RegGrp.IGNORE);
 695    this.sorter.add(/([ >](\*|[\w-]+))([^: >+~]*)(:\w+-child(\([^)]+\))?)([^: >+~]*)/, "$1$3$6$4");
 696  },
 697  
 698  ignoreCase: true,
 699
 700  escape: function(selector) {
 701    return this.optimise(this.format(selector));
 702  },
 703
 704  format: function(selector) {
 705    return selector
 706      .replace(WHITESPACE, "$1")
 707      .replace(IMPLIED_SPACE, "$1 $2")
 708      .replace(IMPLIED_ASTERISK, "$1*$2");
 709  },
 710
 711  optimise: function(selector) {
 712    // optimise wild card descendant selectors
 713    return this.sorter.exec(selector.replace(WILD_CARD, ">* "));
 714  },
 715
 716  unescape: function(selector) {
 717    return decode(selector);
 718  }
 719});
 720
 721// some constants
 722var _OPERATORS = {
 723  "":   "%1!=null",
 724  "=":  "%1=='%2'",
 725  "~=": /(^| )%1( |$)/,
 726  "|=": /^%1(-|$)/,
 727  "^=": /^%1/,
 728  "$=": /%1$/,
 729  "*=": /%1/
 730};
 731
 732var _PSEUDO_CLASSES = {
 733  "first-child": "!IE7._getPreviousElementSibling(e%1)",
 734  "link":        "e%1.currentStyle['ie7-link']=='link'",
 735  "visited":     "e%1.currentStyle['ie7-link']=='visited'"
 736};
 737
 738var _VAR = "var p%2=0,i%2,e%2,n%2=e%1.";
 739var _ID = "e%1.sourceIndex";
 740var _TEST = "var g=" + _ID + ";if(!p[g]){p[g]=1;";
 741var _STORE = "r[r.length]=e%1;if(s)return e%1;";
 742var _FN = "var _selectorFunction=function(e0,s){IE7._indexed++;var r=[],p={},reg=[%1],d=document;";
 743var reg; // a store for RexExp objects
 744var _index;
 745var _wild; // need to flag certain _wild card selectors as MSIE includes comment nodes
 746var _list; // are we processing a node _list?
 747var _duplicate; // possible duplicates?
 748var _cache = {}; // store parsed selectors
 749
 750// a hideous parser
 751var cssParser = new CSSParser({
 752  " (\\*|[\\w-]+)#([\\w-]+)": function(match, tagName, id) { // descendant selector followed by ID
 753    _wild = false;
 754    var replacement = "var e%2=IE7._byId(d,'%4');if(e%2&&";
 755    if (tagName != "*") replacement += "e%2.nodeName=='%3'&&";
 756    replacement += "(e%1==d||e%1.contains(e%2))){";
 757    if (_list) replacement += format("i%1=n%1.length;", _list);
 758    return format(replacement, _index++, _index, tagName.toUpperCase(), id);
 759  },
 760  
 761  " (\\*|[\\w-]+)": function(match, tagName) { // descendant selector
 762    _duplicate++; // this selector may produce duplicates
 763    _wild = tagName == "*";
 764    var replacement = _VAR;
 765    // IE5.x does not support getElementsByTagName("*");
 766    replacement += (_wild && _MSIE5) ? "all" : "getElementsByTagName('%3')";
 767    replacement += ";for(i%2=0;(e%2=n%2[i%2]);i%2++){";
 768    return format(replacement, _index++, _list = _index, tagName.toUpperCase());
 769  },
 770  
 771  ">(\\*|[\\w-]+)": function(match, tagName) { // child selector
 772    var children = _list;
 773    _wild = tagName == "*";
 774    var replacement = _VAR;
 775    // use the children property for MSIE as it does not contain text nodes
 776    //  (but the children collection still includes comments).
 777    // the document object does not have a children collection
 778    replacement += children ? "children": "childNodes";
 779    if (!_wild && children) replacement += ".tags('%3')";
 780    replacement += ";for(i%2=0;(e%2=n%2[i%2]);i%2++){";
 781    if (_wild) {
 782      replacement += "if(e%2.nodeType==1){";
 783      _wild = _MSIE5;
 784    } else {
 785      if (!children) replacement += "if(e%2.nodeName=='%3'){";
 786    }
 787    return format(replacement, _index++, _list = _index, tagName.toUpperCase());
 788  },
 789  
 790  "\\+(\\*|[\\w-]+)": function(match, tagName) { // direct adjacent selector
 791    var replacement = "";
 792    if (_wild) replacement += "if(e%1.nodeName!='!'){";
 793    _wild = false;
 794    replacement += "e%1=IE7._getNextElementSibling(e%1);if(e%1";
 795    if (tagName != "*") replacement += "&&e%1.nodeName=='%2'";
 796    replacement += "){";
 797    return format(replacement, _index, tagName.toUpperCase());
 798  },
 799  
 800  "~(\\*|[\\w-]+)": function(match, tagName) { // indirect adjacent selector
 801    var replacement = "";
 802    if (_wild) replacement += "if(e%1.nodeName!='!'){";
 803    _wild = false;
 804    _duplicate = 2; // this selector may produce duplicates
 805    replacement += "while(e%1=e%1.nextSibling){if(e%1.ie7_adjacent==IE7._indexed)break;if(";
 806    if (tagName == "*") {
 807      replacement += "e%1.nodeType==1";
 808      if (_MSIE5) replacement += "&&e%1.nodeName!='!'";
 809    } else replacement += "e%1.nodeName=='%2'";
 810    replacement += "){e%1.ie7_adjacent=IE7._indexed;";
 811    return format(replacement, _index, tagName.toUpperCase());
 812  },
 813  
 814  "#([\\w-]+)": function(match, id) { // ID selector
 815    _wild = false;
 816    var replacement = "if(e%1.id=='%2'){";
 817    if (_list) replacement += format("i%1=n%1.length;", _list);
 818    return format(replacement, _index, id);
 819  },
 820  
 821  "\\.([\\w-]+)": function(match, className) { // class selector
 822    _wild = false;
 823    // store RegExp objects - slightly faster on IE
 824    reg.push(new RegExp("(^|\\s)" + rescape(className) + "(\\s|$)"));
 825    return format("if(e%1.className&&reg[%2].test(e%1.className)){", _index, reg.length - 1);
 826  },
 827  
 828  "\\[([\\w-]+)\\s*([^=]?=)?\\s*([^\\]]*)\\]": function(match, attr, operator, value) { // attribute selectors
 829    var alias = _ATTRIBUTES[attr] || attr;
 830    if (operator) {
 831      var getAttribute = "e%1.getAttribute('%2',2)";
 832      if (!_EVALUATED.test(attr)) {
 833        getAttribute = "e%1.%3||" + getAttribute;
 834      }
 835      attr = format("(" + getAttribute + ")", _index, attr, alias);
 836    } else {
 837      attr = format("IE7._getAttribute(e%1,'%2')", _index, attr);
 838    }
 839    var replacement = _OPERATORS[operator || ""] || "0";
 840    if (replacement && replacement.source) {
 841      reg.push(new RegExp(format(replacement.source, rescape(cssParser.unescape(value)))));
 842      replacement = "reg[%2].test(%1)";
 843      value = reg.length - 1;
 844    }
 845    return "if(" + format(replacement, attr, value) + "){";
 846  },
 847  
 848  ":+([\\w-]+)(\\(([^)]+)\\))?": function(match, pseudoClass, $2, args) { // pseudo class selectors
 849    pseudoClass = _PSEUDO_CLASSES[pseudoClass];
 850    return "if(" + (pseudoClass ? format(pseudoClass, _index, args || "")  : "0") + "){";
 851  }
 852});
 853
 854// =========================================================================
 855// ie7-css.js
 856// =========================================================================
 857
 858var HYPERLINK = /a(#[\w-]+)?(\.[\w-]+)?:(hover|active)/i;
 859var BRACE1 = /\s*\{\s*/, BRACE2 = /\s*\}\s*/, COMMA = /\s*\,\s*/;
 860var FIRST_LINE_LETTER = /(.*)(:first-(line|letter))/;
 861
 862//var UNKNOWN = /UNKNOWN|([:.])\w+\1/i;
 863
 864var styleSheets = document.styleSheets;
 865
 866IE7.CSS = new (Fix.extend({ // single instance
 867  parser: new Parser,
 868  screen: "",
 869  print: "",
 870  styles: [],
 871  rules: [],
 872  pseudoClasses: appVersion < 7 ? "first\\-child" : "",
 873  dynamicPseudoClasses: {
 874    toString: function() {
 875      var strings = [];
 876      for (var pseudoClass in this) strings.push(pseudoClass);
 877      return strings.join("|");
 878    }
 879  },
 880  
 881  init: function() {
 882    var NONE = "^\x01$";
 883    var CLASS = "\\[class=?[^\\]]*\\]";
 884    var pseudoClasses = [];
 885    if (this.pseudoClasses) pseudoClasses.push(this.pseudoClasses);
 886    var dynamicPseudoClasses = this.dynamicPseudoClasses.toString(); 
 887    if (dynamicPseudoClasses) pseudoClasses.push(dynamicPseudoClasses);
 888    pseudoClasses = pseudoClasses.join("|");
 889    var unknown = appVersion < 7 ? ["[>+~[(]|([:.])\\w+\\1"] : [CLASS];
 890    if (pseudoClasses) unknown.push(":(" + pseudoClasses + ")");
 891    this.UNKNOWN = new RegExp(unknown.join("|") || NONE, "i");
 892    var complex = appVersion < 7 ? ["\\[[^\\]]+\\]|[^\\s(\\[]+\\s*[+~]"] : [CLASS];
 893    var complexRule = complex.concat();
 894    if (pseudoClasses) complexRule.push(":(" + pseudoClasses + ")");
 895    Rule.COMPLEX = new RegExp(complexRule.join("|") || NONE, "ig");
 896    if (this.pseudoClasses) complex.push(":(" + this.pseudoClasses + ")");
 897    DynamicRule.COMPLEX = new RegExp(complex.join("|") || NONE, "i");
 898    DynamicRule.MATCH = new RegExp(dynamicPseudoClasses ? "(.*):(" + dynamicPseudoClasses + ")(.*)" : NONE, "i");
 899    
 900    this.createStyleSheet();
 901    this.refresh();
 902  },
 903  
 904	addEventHandler: function() {
 905		addEventHandler.apply(null, arguments);
 906	},
 907  
 908  addFix: function(expression, replacement) {
 909    this.parser.add(expression, replacement);
 910  },
 911  
 912  addRecalc: function(propertyName, test, handler, replacement) {
 913    // recalcs occur whenever the document is refreshed using document.recalc()
 914    test = new RegExp("([{;\\s])" + propertyName + "\\s*:\\s*" + test + "[^;}]*");
 915    var id = this.recalcs.length;
 916    if (replacement) replacement = propertyName + ":" + replacement;
 917    this.addFix(test, function(match, $1) {
 918      return (replacement ? $1 + replacement : match) + ";ie7-" + match.slice(1) + ";ie7_recalc" + id + ":1";
 919    });
 920    this.recalcs.push(arguments);
 921    return id;
 922  },
 923  
 924  apply: function() {
 925    this.getInlineStyles();
 926    new StyleSheet("screen");
 927    this.trash();
 928  },
 929  
 930  createStyleSheet: function() {
 931    // create the IE7 style sheet
 932    this.styleSheet = document.createStyleSheet();
 933    // flag it so we can ignore it during parsing
 934    this.styleSheet.ie7 = true;
 935    this.styleSheet.owningElement.ie7 = true;
 936    this.styleSheet.cssText = HEADER;
 937  },
 938  
 939  getInlineStyles: function() {
 940    // load inline styles
 941    var styleSheets = document.getElementsByTagName("style"), styleSheet;
 942    for (var i = styleSheets.length - 1; (styleSheet = styleSheets[i]); i--) {
 943      if (!styleSheet.disabled && !styleSheet.ie7) {
 944        this.styles.push(styleSheet.innerHTML);
 945      }
 946    }
 947  },
 948  
 949  getText: function(styleSheet, path) {
 950    // explorer will trash unknown selectors (it converts them to "UNKNOWN").
 951    // so we must reload external style sheets (internal style sheets can have their text
 952    //  extracted through the innerHTML property).
 953      // load the style sheet text from an external file
 954    try {
 955      var cssText = styleSheet.cssText;
 956    } catch (e) {
 957      cssText = "";
 958    }
 959    if (httpRequest) cssText = loadFile(styleSheet.href, path) || cssText;
 960    return cssText;
 961  },
 962  
 963  recalc: function() {
 964    this.screen.recalc();
 965    // we're going to read through all style rules.
 966    //  certain rules have had ie7 properties added to them.
 967    //   e.g. p{top:0; ie7_recalc2:1; left:0}
 968    //  this flags a property in the rule as needing a fix.
 969    //  the selector text is then used to query the document.
 970    //  we can then loop through the results of the query
 971    //  and fix the elements.
 972    // we ignore the IE7 rules - so count them in the header
 973    var RECALCS = /ie7_recalc\d+/g;
 974    var start = HEADER.match(/[{,]/g).length;
 975    // only calculate screen fixes. print fixes don't show up anyway
 976    var stop = start + (this.screen.cssText.match(/\{/g)||"").length;
 977    var rules = this.styleSheet.rules, rule;
 978    var calcs, calc, elements, element, i, j, k, id;
 979    // loop through all rules
 980    for (i = start; i < stop; i++) {
 981      rule = rules[i];
 982      var cssText = rule.style.cssText;
 983      // search for the "ie7_recalc" flag (there may be more than one)
 984      if (rule && (calcs = cssText.match(RECALCS))) {
 985        // use the selector text to query the document
 986        elements = cssQuery(rule.selectorText);
 987        // if there are matching elements then loop
 988        //  through the recalc functions and apply them
 989        //  to each element
 990        if (elements.length) for (j = 0; j < calcs.length; j++) {
 991          // get the matching flag (e.g. ie7_recalc3)
 992          id = calcs[j];
 993          // extract the numeric id from the end of the flag
 994          //  and use it to index the collection of recalc
 995          //  functions
 996          calc = IE7.CSS.recalcs[id.slice(10)][2];
 997          for (k = 0; (element = elements[k]); k++) {
 998            // apply the fix
 999            if (element.currentStyle[id]) calc(element, cssText);
1000          }
1001        }
1002      }
1003    }
1004  },
1005  
1006  refresh: function() {
1007    this.styleSheet.cssText = HEADER + this.screen + this.print;
1008  },
1009  
1010  trash: function() {
1011    // trash the old style sheets
1012    for (var i = 0; i < styleSheets.length; i++) {
1013      if (!styleSheets[i].ie7) {
1014        try {
1015          var cssText = styleSheets[i].cssText;
1016        } catch (e) {
1017          cssText = "";
1018        }
1019        if (cssText) styleSheets[i].cssText = "";
1020      }
1021    }
1022  }
1023}));
1024
1025// -----------------------------------------------------------------------
1026//  IE7 StyleSheet class
1027// -----------------------------------------------------------------------
1028
1029var StyleSheet = Base.extend({
1030  constructor: function(media) {
1031    this.media = media;
1032    this.load();
1033    IE7.CSS[media] = this;
1034    IE7.CSS.refresh();
1035  },
1036  
1037  createRule: function(selector, cssText) {
1038    if (IE7.CSS.UNKNOWN.test(selector)) {
1039      var match;
1040      if (PseudoElement && (match = selector.match(PseudoElement.MATCH))) {
1041        return new PseudoElement(match[1], match[2], cssText);
1042      } else if (match = selector.match(DynamicRule.MATCH)) {
1043        if (!HYPERLINK.test(match[0]) || DynamicRule.COMPLEX.test(match[0])) {
1044          return new DynamicRule(selector, match[1], match[2], match[3], cssText);
1045        }
1046      } else return new Rule(selector, cssText);
1047    }
1048    return selector + " {" + cssText + "}";
1049  },
1050  
1051  getText: function() {
1052    // store for style sheet text
1053    var _inlineStyles = [].concat(IE7.CSS.styles);
1054    // parse media decalarations
1055    var MEDIA = /@media\s+([^{]*)\{([^@]+\})\s*\}/gi;
1056    var ALL = /\ball\b|^$/i, SCREEN = /\bscreen\b/i, PRINT = /\bprint\b/i;
1057    function _parseMedia(cssText, media) {
1058      _filterMedia.value = media;
1059      return cssText.replace(MEDIA, _filterMedia);
1060    };
1061    function _filterMedia(match, media, cssText) {
1062      media = _simpleMedia(media);
1063      switch (media) {
1064        case "screen":
1065        case "print":
1066          if (media != _filterMedia.value) return "";
1067        case "all":
1068          return cssText;
1069      }
1070      return "";
1071    };
1072    function _simpleMedia(media) {
1073      if (ALL.test(media)) return "all";
1074      else if (SCREEN.test(media)) return (PRINT.test(media)) ? "all" : "screen";
1075      else if (PRINT.test(media)) return "print";
1076    };
1077    var self = this;
1078    function _getCSSText(styleSheet, path, media, level) {
1079      var cssText = "";
1080      if (!level) {
1081        media = _simpleMedia(styleSheet.media);
1082        level = 0;
1083      }
1084      if (media == "all" || media == self.media) {
1085        // IE only allows importing style sheets three levels deep.
1086        // it will crash if you try to access a level below this
1087        if (level < 3) {
1088          // loop through imported style sheets
1089          for (var i = 0; i < styleSheet.imports.length; i++) {
1090            // call this function recursively to get all imported style sheets
1091            cssText += _getCSSText(styleSheet.imports[i], getPath(styleSheet.href, path), media, level + 1);
1092          }
1093        }
1094        // retrieve inline style or load an external style sheet
1095        cssText += encode(styleSheet.href ? _loadStyleSheet(styleSheet, path) : _inlineStyles.pop() || "");
1096        cssText = _parseMedia(cssText, self.media);
1097      }
1098      return cssText;
1099    };
1100    // store loaded cssText URLs
1101    var fileCache = {};
1102    // load an external style sheet
1103    function _loadStyleSheet(styleSheet, path) {
1104      var url = makePath(styleSheet.href, path);
1105      // if the style sheet has already loaded then don't duplicate it
1106      if (fileCache[url]) return "";
1107      // load from source
1108      fileCache[url] = (styleSheet.disabled) ? "" :
1109        _fixUrls(IE7.CSS.getText(styleSheet, path), getPath(styleSheet.href, path));
1110      return fileCache[url];
1111    };
1112    // fix css paths
1113    // we're lumping all css text into one big style sheet so relative
1114    //  paths have to be fixed. this is necessary anyway because of other
1115    //  explorer bugs.
1116    var URL = /(url\s*\(\s*['"]?)([\w\.]+[^:\)]*['"]?\))/gi;
1117    function _fixUrls(cssText, pathname) {
1118      // hack & slash
1119      return cssText.replace(URL, "$1" + pathname.slice(0, pathname.lastIndexOf("/") + 1) + "$2");
1120    };
1121
1122    // load all style sheets in the document
1123    for (var i = 0; i < styleSheets.length; i++) {
1124      if (!styleSheets[i].disabled && !styleSheets[i].ie7) {
1125        this.cssText += _getCSSText(styleSheets[i]);
1126      }
1127    }
1128  },
1129  
1130  load: function() {
1131    this.cssText = "";
1132    this.getText();
1133    this.parse();
1134    this.cssText = decode(this.cssText);
1135    fileCache = {};
1136  },
1137  
1138  parse: function() {
1139    this.cssText = IE7.CSS.parser.exec(this.cssText);
1140    
1141    // parse the style sheet
1142    var offset = IE7.CSS.rules.length;
1143    var rules = this.cssText.split(BRACE2), rule;
1144    var selectors, cssText, i, j;
1145    for (i = 0; i < rules.length; i++) {
1146      rule = rules[i].split(BRACE1);
1147      selectors = rule[0].split(COMMA);
1148      cssText = rule[1];
1149      for (j = 0; j < selectors.length; j++) {
1150        selectors[j] = cssText ? this.createRule(selectors[j], cssText) : "";
1151      }
1152      rules[i] = selectors.join("\n");
1153    }
1154    this.cssText = rules.join("\n");
1155    this.rules = IE7.CSS.rules.slice(offset);
1156  },
1157  
1158  recalc: function() {
1159    var rule, i;
1160    for (i = 0; (rule = this.rules[i]); i++) rule.recalc();
1161  },
1162  
1163  toString: function() {
1164    return "@media " + this.media + "{" + this.cssText + "}";
1165  }
1166});
1167
1168var PseudoElement;
1169
1170// -----------------------------------------------------------------------
1171// IE7 style rules
1172// -----------------------------------------------------------------------
1173
1174var Rule = IE7.Rule = Base.extend({
1175  // properties
1176  constructor: function(selector, cssText) {
1177    this.id = IE7.CSS.rules.length;
1178    this.className = Rule.PREFIX + this.id;
1179    selector = selector.match(FIRST_LINE_LETTER) || selector || "*";
1180    this.selector = selector[1] || selector;
1181    this.selectorText = this.parse(this.selector) + (selector[2] || "");
1182    this.cssText = cssText;
1183    this.MATCH = new RegExp("\\s" + this.className + "(\\s|$)", "g");
1184    IE7.CSS.rules.push(this);
1185    this.init();
1186  },
1187  
1188  init: Undefined,
1189  
1190  add: function(element) {
1191    // allocate this class
1192    element.className += " " + this.className;
1193  },
1194  
1195  recalc: function() {
1196    // execute the underlying css query for this class
1197    var match = cssQuery(this.selector);
1198    // add the class name for all matching elements
1199    for (var i = 0; i < match.length; i++) this.add(match[i]);
1200  },
1201
1202  parse: function(selector) {
1203    // attempt to preserve specificity for "loose" parsing by
1204    //  removing unknown tokens from a css selector but keep as
1205    //  much as we can..
1206    var simple = selector.replace(Rule.CHILD, " ").replace(Rule.COMPLEX, "");
1207    if (appVersion < 7) simple = simple.replace(Rule.MULTI, "");
1208    var tags = match(simple, Rule.TAGS).length - match(selector, Rule.TAGS).length;
1209    var classes = match(simple, Rule.CLASSES).length - match(selector, Rule.CLASSES).length + 1;
1210    while (classes > 0 && Rule.CLASS.test(simple)) {
1211      simple = simple.replace(Rule.CLASS, "");
1212      classes--;
1213    }
1214    while (tags > 0 && Rule.TAG.test(simple)) {
1215      simple = simple.replace(Rule.TAG, "$1*");
1216      tags--;
1217    }
1218    simple += "." + this.className;
1219    classes = Math.min(classes, 2);
1220    tags = Math.min(tags, 2);
1221    var score = -10 * classes - tags;
1222    if (score > 0) {
1223      simple = simple + "," + Rule.MAP[score] + " " + simple;
1224    }
1225    return simple;
1226  },
1227  
1228  remove: function(element) {
1229    // deallocate this class
1230    element.className = element.className.replace(this.MATCH, "$1");
1231  },
1232  
1233  toString: function() {
1234    return format("%1 {%2}", this.selectorText, this.cssText);
1235  }
1236}, {
1237  CHILD: />/g,
1238  CLASS: /\.[\w-]+/,
1239  CLASSES: /[.:\[]/g,
1240  MULTI: /(\.[\w-]+)+/g,
1241  PREFIX: "ie7_class",
1242  TAG: /^\w+|([\s>+~])\w+/,
1243  TAGS: /^\w|[\s>+~]\w/g,
1244  MAP: {
1245    1:  "html",
1246    2:  "html body",
1247    10: ".ie7_html",
1248    11: "html.ie7_html",
1249    12: "html.ie7_html body",
1250    20: ".ie7_html .ie7_body",
1251    21: "html.ie7_html .ie7_body",
1252    22: "html.ie7_html body.ie7_body"
1253  }
1254});
1255
1256// -----------------------------------------------------------------------
1257// IE7 dynamic style
1258// -----------------------------------------------------------------------
1259
1260// object properties:
1261// attach: the element that an event handler will be attached to
1262// target: the element that will have the IE7 class applied
1263
1264var DynamicRule = Rule.extend({
1265  // properties
1266  constructor: function(selector, attach, dynamicPseudoClass, target, cssText) {
1267    // initialise object properties
1268    this.attach = attach || "*";
1269    this.dynamicPseudoClass = IE7.CSS.dynamicPseudoClasses[dynamicPseudoClass];
1270    this.target = target;
1271    this.base(selector, cssText);
1272  },
1273  
1274  recalc: function() {
1275    // execute the underlying css query for this class
1276    var attaches = cssQuery(this.attach), attach;
1277    // process results
1278    for (var i = 0; attach = attaches[i]; i++) {
1279      // retrieve the event handler's target element(s)
1280      var target = this.target ? cssQuery(this.target, attach) : [attach];
1281      // attach event handlers for dynamic pseudo-classes
1282      if (target.length) this.dynamicPseudoClass.apply(attach, target, this);
1283    }
1284  }
1285});
1286
1287// -----------------------------------------------------------------------
1288//  IE7 dynamic pseudo-classes
1289// -----------------------------------------------------------------------
1290
1291var DynamicPseudoClass = Base.extend({
1292  constructor: function(name, apply) {
1293    this.name = name;
1294    this.apply = apply;
1295    this.instances = {};
1296    IE7.CSS.dynamicPseudoClasses[name] = this;
1297  },
1298  
1299  register: function(instance) {
1300    // an "instance" is actually an Arguments object
1301    var _class = instance[2];
1302    instance.id = _class.id + instance[0].uniqueID;
1303    if (!this.instances[instance.id]) {
1304      var target = instance[1], j;
1305      for (j = 0; j < target.length; j++) _class.add(target[j]);
1306      this.instances[instance.id] = instance;
1307    }
1308  },
1309  
1310  unregister: function(instance) {
1311    if (this.instances[instance.id]) {
1312      var _class = instance[2];
1313      var target = instance[1], j;
1314      for (j = 0; j < target.length; j++) _class.remove(target[j]);
1315      delete this.instances[instance.id];
1316    }
1317  }
1318});
1319  
1320// -----------------------------------------------------------------------
1321// dynamic pseudo-classes
1322// -----------------------------------------------------------------------
1323
1324if (appVersion < 7) {
1325  var Hover = new DynamicPseudoClass("hover", function(element) {
1326    var instance = arguments;
1327    IE7.CSS.addEventHandler(element, appVersion < 5.5 ? "onmouseover" : "onmouseenter", function() {
1328      Hover.register(instance);
1329    });
1330    IE7.CSS.addEventHandler(element, appVersion < 5.5 ? "onmouseout" : "onmouseleave", function() {
1331      Hover.unregister(instance);
1332    });
1333  });
1334  
1335  // globally trap the mouseup event (thanks Martijn!)
1336  addEventHandler(document, "onmouseup", function() {
1337    var instances = Hover.instances;
1338    for (var i in instances)
1339      if (!instances[i][0].contains(event.srcElement))
1340        Hover.unregister(instances[i]);
1341  });
1342}
1343
1344// -----------------------------------------------------------------------
1345// propertyName: inherit;
1346// -----------------------------------------------------------------------
1347
1348IE7.CSS.addRecalc("[\\w-]+", "inherit", function(element, cssText) {
1349  var inherited = cssText.match(/[\w-]+\s*:\s*inherit/g);
1350  for (var i = 0; i < inherited.length; i++) {
1351    var propertyName = inherited[i].replace(/ie7\-|\s*:\s*inherit/g, "").replace(/\-([a-z])/g, function(match, chr) {
1352      return chr.toUpperCase()
1353    });
1354    element.runtimeStyle[propertyName] = element.parentElement.currentStyle[propertyName];
1355  }
1356});
1357
1358// =========================================================================
1359// ie7-html.js
1360// =========================================================================
1361
1362// default font-sizes
1363//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}";
1364
1365IE7.HTML = new (Fix.extend({ // single instance  
1366  fixed: {},
1367  
1368  init: Undefined,
1369  
1370  addFix: function() {
1371    // fixes are a one-off, they are applied when the document is loaded
1372    this.fixes.push(arguments);
1373  },
1374  
1375  apply: function() {
1376    for (var i = 0; i < this.fixes.length; i++) {
1377      var match = cssQuery(this.fixes[i][0]);
1378      var fix = this.fixes[i][1];
1379      for (var j = 0; j < match.length; j++) fix(match[j]);
1380    }
1381  },
1382  
1383  addRecalc: function() {
1384    // recalcs occur whenever the document is refreshed using document.recalc()
1385    this.recalcs.push(arguments);
1386  },
1387  
1388  recalc: function() {
1389    // loop through the fixes
1390    for (var i = 0; i < this.recalcs.length; i++) {
1391      var match = cssQuery(this.recalcs[i][0]);
1392      var recalc = this.recalcs[i][1], element;
1393      var key = Math.pow(2, i);
1394      for (var j = 0; (element = match[j]); j++) {
1395        var uniqueID = element.uniqueID;
1396        if ((this.fixed[uniqueID] & key) == 0) {
1397          element = recalc(element) || element;
1398          this.fixed[uniqueID] |= key;
1399        }
1400      }
1401    }
1402  }
1403}));
1404
1405if (appVersion < 7) {  
1406  // provide support for the <abbr> tag.
1407  //  this is a proper fix, it preserves the DOM structure and
1408  //  <abbr> elements report the correct tagName & namespace prefix
1409  document.createElement("abbr");
1410  
1411  // bind to the first child control
1412  IE7.HTML.addRecalc("label", function(label) {
1413    if (!label.htmlFor) {
1414      var firstChildControl = cssQuery("input,textarea", label, true);
1415      if (firstChildControl) {
1416        addEventHandler(label, "onclick", function() {
1417          firstChildControl.click();
1418        });
1419      }
1420    }
1421  });
1422}
1423
1424// =========================================================================
1425// ie7-layout.js
1426// =========================================================================
1427
1428var NUMERIC = "[.\\d]";
1429
1430new function(_) {
1431var layout = IE7.Layout = this;
1432
1433  // big, ugly box-model hack + min/max stuff
1434  
1435  // #tantek > #erik > #dean { voice-family: hacker; }
1436  
1437  // -----------------------------------------------------------------------
1438  // "layout"
1439  // -----------------------------------------------------------------------
1440  
1441  HEADER += "*{boxSizing:content-box}";
1442  
1443  // does an element have "layout" ?
1444  IE7.hasLayout = appVersion < 5.5 ? function(element) {
1445    // element.currentStyle.hasLayout doesn't work for IE5.0
1446    return element.clientWidth;
1447  } : function(element) {
1448    return element.currentStyle.hasLayout;
1449  };
1450  
1451  // give an element "layout"
1452  layout.boxSizing = function(element) {
1453    if (!IE7.hasLayout(element)) {
1454    //#  element.runtimeStyle.fixedHeight =
1455      element.style.height = "0cm";
1456      if (element.currentStyle.verticalAlign == "auto")
1457        element.runtimeStyle.verticalAlign = "top";
1458      // when an element acquires "layout", margins no longer collapse correctly
1459      collapseMargins(element);
1460    }
1461  };
1462  
1463  // -----------------------------------------------------------------------
1464  // Margin Collapse
1465  // -----------------------------------------------------------------------
1466  
1467  function collapseMargins(element) {
1468    if (element != viewport && element.currentStyle.position != "absolute") {
1469      collapseMargin(element, "marginTop");
1470      collapseMargin(element, "marginBottom");
1471    }
1472  };
1473  
1474  function collapseMargin(element, type) {
1475    if (!element.runtimeStyle[type]) {
1476      var parentElement = element.parentElement;
1477      if (parentElement && IE7.hasLayout(parentElement) && !IE7[type == "marginTop" ? "_getPreviousElementSibling" : "_getNextElementSibling"](element)) return;
1478      var child = cssQuery(">*:" + (type == "marginTop" ? "first" : "last") + "-child", element, true);
1479      if (child && child.currentStyle.styleFloat == "none" && IE7.hasLayout(child)) {
1480        collapseMargin(child, type);
1481        margin = _getMargin(element, element.currentStyle[type]);
1482        childMargin = _getMargin(child, child.currentStyle[type]);
1483        if (margin < 0 || childMargin < 0) {
1484          element.runtimeStyle[type] = margin + childMargin;
1485        } else {
1486          element.runtimeStyle[type] = Math.max(childMargin, margin);
1487        }
1488        child.runtimeStyle[type] = "0px";
1489      }
1490    }
1491  };
1492  
1493  function _getMargin(element, value) {
1494    return value == "auto" ? 0 : getPixelValue(element, value);
1495  };
1496  
1497  // -----------------------------------------------------------------------
1498  // box-model
1499  // -----------------------------------------------------------------------
1500  
1501  // constants
1502  var UNIT = /^[.\d][\w%]*$/, AUTO = /^(auto|0cm)$/;
1503  
1504  var applyWidth, apply

Large files files are truncated, but you can click here to view the full file