/static/scripts/IE8.js
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&®[%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