PageRenderTime 76ms CodeModel.GetById 11ms 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
  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. /* W3C compliance for Microsoft Internet Explorer */
  8. /* credits/thanks:
  9. Shaggy, Martijn Wargers, Jimmy Cerra, Mark D Anderson,
  10. Lars Dieckow, Erik Arvidsson, Gellért Gyuris, James Denny,
  11. Unknown W Brackets, Benjamin Westfarer, Rob Eberhardt,
  12. Bill Edney, Kevin Newman, James Crompton, Matthew Mastracci,
  13. Doug Wright, Richard York, Kenneth Kolano, MegaZone,
  14. Thomas Verelst, Mark 'Tarquin' Wilton-Jones, Rainer ?hlfors,
  15. David Zulaica, Ken Kolano, Kevin Newman
  16. */
  17. // =======================================================================
  18. // TO DO
  19. // =======================================================================
  20. // PNG - unclickable content
  21. // =======================================================================
  22. // TEST/BUGGY
  23. // =======================================================================
  24. // hr{margin:1em auto} (doesn't look right in IE5)
  25. (function() {
  26. IE7 = {
  27. toString: function(){return "IE7 version 2.0 (beta3)"}
  28. };
  29. var appVersion = IE7.appVersion = navigator.appVersion.match(/MSIE (\d\.\d)/)[1];
  30. if (/ie7_off/.test(top.location.search) || appVersion < 5) return;
  31. var Undefined = K();
  32. var quirksMode = document.compatMode != "CSS1Compat";
  33. var documentElement = document.documentElement, body, viewport;
  34. var ANON = "!";
  35. var HEADER = ":link{ie7-link:link}:visited{ie7-link:visited}";
  36. // -----------------------------------------------------------------------
  37. // external
  38. // -----------------------------------------------------------------------
  39. var RELATIVE = /^[\w\.]+[^:]*$/;
  40. function makePath(href, path) {
  41. if (RELATIVE.test(href)) href = (path || "") + href;
  42. return href;
  43. };
  44. function getPath(href, path) {
  45. href = makePath(href, path);
  46. return href.slice(0, href.lastIndexOf("/") + 1);
  47. };
  48. // get the path to this script
  49. var script = document.scripts[document.scripts.length - 1];
  50. var path = getPath(script.src);
  51. // we'll use microsoft's http request object to load external files
  52. try {
  53. var httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
  54. } catch (e) {
  55. // ActiveX disabled
  56. }
  57. var fileCache = {};
  58. function loadFile(href, path) {
  59. try {
  60. href = makePath(href, path);
  61. if (!fileCache[href]) {
  62. // easy to load a file huh?
  63. httpRequest.open("GET", href, false);
  64. httpRequest.send();
  65. if (httpRequest.status == 0 || httpRequest.status == 200) {
  66. fileCache[href] = httpRequest.responseText;
  67. }
  68. }
  69. } catch (e) {
  70. // ignore errors
  71. } finally {
  72. return fileCache[href] || "";
  73. }};
  74. // -----------------------------------------------------------------------
  75. // IE5.0 compatibility
  76. // -----------------------------------------------------------------------
  77. if (appVersion < 5.5) {
  78. undefined = Undefined();
  79. ANON = "HTML:!"; // for anonymous content
  80. // Fix String.replace (Safari1.x/IE5.0).
  81. var GLOBAL = /(g|gi)$/;
  82. var _String_replace = String.prototype.replace;
  83. String.prototype.replace = function(expression, replacement) {
  84. if (typeof replacement == "function") { // Safari doesn't like functions
  85. if (expression && expression.constructor == RegExp) {
  86. var regexp = expression;
  87. var global = regexp.global;
  88. if (global == null) global = GLOBAL.test(regexp);
  89. // we have to convert global RexpExps for exec() to work consistently
  90. if (global) regexp = new RegExp(regexp.source); // non-global
  91. } else {
  92. regexp = new RegExp(rescape(expression));
  93. }
  94. var match, string = this, result = "";
  95. while (string && (match = regexp.exec(string))) {
  96. result += string.slice(0, match.index) + replacement.apply(this, match);
  97. string = string.slice(match.index + match[0].length);
  98. if (!global) break;
  99. }
  100. return result + string;
  101. }
  102. return _String_replace.apply(this, arguments);
  103. };
  104. Array.prototype.pop = function() {
  105. if (this.length) {
  106. var i = this[this.length - 1];
  107. this.length--;
  108. return i;
  109. }
  110. return undefined;
  111. };
  112. Array.prototype.push = function() {
  113. for (var i = 0; i < arguments.length; i++) {
  114. this[this.length] = arguments[i];
  115. }
  116. return this.length;
  117. };
  118. var ns = this;
  119. Function.prototype.apply = function(o, a) {
  120. if (o === undefined) o = ns;
  121. else if (o == null) o = window;
  122. else if (typeof o == "string") o = new String(o);
  123. else if (typeof o == "number") o = new Number(o);
  124. else if (typeof o == "boolean") o = new Boolean(o);
  125. if (arguments.length == 1) a = [];
  126. else if (a[0] && a[0].writeln) a[0] = a[0].documentElement.document || a[0];
  127. var $ = "#ie7_apply", r;
  128. o[$] = this;
  129. switch (a.length) { // unroll for speed
  130. case 0: r = o[$](); break;
  131. case 1: r = o[$](a[0]); break;
  132. case 2: r = o[$](a[0],a[1]); break;
  133. case 3: r = o[$](a[0],a[1],a[2]); break;
  134. case 4: r = o[$](a[0],a[1],a[2],a[3]); break;
  135. case 5: r = o[$](a[0],a[1],a[2],a[3],a[4]); break;
  136. default:
  137. var b = [], i = a.length - 1;
  138. do b[i] = "a[" + i + "]"; while (i--);
  139. eval("r=o[$](" + b + ")");
  140. }
  141. if (typeof o.valueOf == "function") { // not a COM object
  142. delete o[$];
  143. } else {
  144. o[$] = undefined;
  145. if (r && r.writeln) r = r.documentElement.document || r;
  146. }
  147. return r;
  148. };
  149. Function.prototype.call = function(o) {
  150. return this.apply(o, _slice.apply(arguments, [1]));
  151. };
  152. // block elements are "inline" according to IE5.0 so we'll fix it
  153. HEADER += "address,blockquote,body,dd,div,dt,fieldset,form,"+
  154. "frame,frameset,h1,h2,h3,h4,h5,h6,iframe,noframes,object,p,"+
  155. "hr,applet,center,dir,menu,pre,dl,li,ol,ul{display:block}";
  156. }
  157. // -----------------------------------------------------------------------
  158. // OO support
  159. // -----------------------------------------------------------------------
  160. // This is a cut-down version of base2 (http://code.google.com/p/base2/)
  161. var _slice = Array.prototype.slice;
  162. // private
  163. var _FORMAT = /%([1-9])/g;
  164. var _LTRIM = /^\s\s*/;
  165. var _RTRIM = /\s\s*$/;
  166. var _RESCAPE = /([\/()[\]{}|*+-.,^$?\\])/g; // safe regular expressions
  167. var _BASE = /\bbase\b/;
  168. var _HIDDEN = ["constructor", "toString"]; // only override these when prototyping
  169. var prototyping;
  170. function Base(){};
  171. Base.extend = function(_instance, _static) {
  172. // Build the prototype.
  173. prototyping = true;
  174. var _prototype = new this;
  175. extend(_prototype, _instance);
  176. prototyping = false;
  177. // Create the wrapper for the constructor function.
  178. var _constructor = _prototype.constructor;
  179. function klass() {
  180. // Don't call the constructor function when prototyping.
  181. if (!prototyping) _constructor.apply(this, arguments);
  182. };
  183. _prototype.constructor = klass;
  184. // Build the static interface.
  185. klass.extend = arguments.callee;
  186. extend(klass, _static);
  187. klass.prototype = _prototype;
  188. return klass;
  189. };
  190. Base.prototype.extend = function(source) {
  191. return extend(this, source);
  192. };
  193. // A collection of regular expressions and their associated replacement values.
  194. // A Base class for creating parsers.
  195. var _HASH = "#";
  196. var _KEYS = "~";
  197. var _RG_ESCAPE_CHARS = /\\./g;
  198. var _RG_ESCAPE_BRACKETS = /\(\?[:=!]|\[[^\]]+\]/g;
  199. var _RG_BRACKETS = /\(/g;
  200. var RegGrp = Base.extend({
  201. constructor: function(values) {
  202. this[_KEYS] = [];
  203. this.merge(values);
  204. },
  205. exec: function(string) {
  206. var items = this, keys = this[_KEYS];
  207. return String(string).replace(new RegExp(this, this.ignoreCase ? "gi" : "g"), function() {
  208. var item, offset = 1, i = 0;
  209. // Loop through the RegGrp items.
  210. while ((item = items[_HASH + keys[i++]])) {
  211. var next = offset + item.length + 1;
  212. if (arguments[offset]) { // do we have a result?
  213. var replacement = item.replacement;
  214. switch (typeof replacement) {
  215. case "function":
  216. return replacement.apply(items, _slice.call(arguments, offset, next));
  217. case "number":
  218. return arguments[offset + replacement];
  219. default:
  220. return replacement;
  221. }
  222. }
  223. offset = next;
  224. }
  225. });
  226. },
  227. add: function(expression, replacement) {
  228. if (expression instanceof RegExp) {
  229. expression = expression.source;
  230. }
  231. if (!this[_HASH + expression]) this[_KEYS].push(String(expression));
  232. this[_HASH + expression] = new RegGrp.Item(expression, replacement);
  233. },
  234. merge: function(values) {
  235. for (var i in values) this.add(i, values[i]);
  236. },
  237. toString: function() {
  238. // back references not supported in simple RegGrp
  239. return "(" + this[_KEYS].join(")|(") + ")";
  240. }
  241. }, {
  242. IGNORE: "$0",
  243. Item: Base.extend({
  244. constructor: function(expression, replacement) {
  245. expression = expression instanceof RegExp ? expression.source : String(expression);
  246. if (typeof replacement == "number") replacement = String(replacement);
  247. else if (replacement == null) replacement = "";
  248. // does the pattern use sub-expressions?
  249. if (typeof replacement == "string" && /\$(\d+)/.test(replacement)) {
  250. // a simple lookup? (e.g. "$2")
  251. if (/^\$\d+$/.test(replacement)) {
  252. // store the index (used for fast retrieval of matched strings)
  253. replacement = parseInt(replacement.slice(1));
  254. } else { // a complicated lookup (e.g. "Hello $2 $1")
  255. // build a function to do the lookup
  256. var Q = /'/.test(replacement.replace(/\\./g, "")) ? '"' : "'";
  257. replacement = replacement.replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\$(\d+)/g, Q +
  258. "+(arguments[$1]||" + Q+Q + ")+" + Q);
  259. replacement = new Function("return " + Q + replacement.replace(/(['"])\1\+(.*)\+\1\1$/, "$1") + Q);
  260. }
  261. }
  262. this.length = RegGrp.count(expression);
  263. this.replacement = replacement;
  264. this.toString = K(expression);
  265. }
  266. }),
  267. count: function(expression) {
  268. // Count the number of sub-expressions in a RegExp/RegGrp.Item.
  269. expression = String(expression).replace(_RG_ESCAPE_CHARS, "").replace(_RG_ESCAPE_BRACKETS, "");
  270. return match(expression, _RG_BRACKETS).length;
  271. }
  272. });
  273. // =========================================================================
  274. // lang/extend.js
  275. // =========================================================================
  276. function extend(object, source) { // or extend(object, key, value)
  277. if (object && source) {
  278. var proto = (typeof source == "function" ? Function : Object).prototype;
  279. // Add constructor, toString etc
  280. var i = _HIDDEN.length, key;
  281. if (prototyping) while (key = _HIDDEN[--i]) {
  282. var value = source[key];
  283. if (value != proto[key]) {
  284. if (_BASE.test(value)) {
  285. _override(object, key, value)
  286. } else {
  287. object[key] = value;
  288. }
  289. }
  290. }
  291. // Copy each of the source object's properties to the target object.
  292. for (key in source) if (proto[key] === undefined) {
  293. var value = source[key];
  294. // Check for method overriding.
  295. if (object[key] && typeof value == "function" && _BASE.test(value)) {
  296. _override(object, key, value);
  297. } else {
  298. object[key] = value;
  299. }
  300. }
  301. }
  302. return object;
  303. };
  304. function _override(object, name, method) {
  305. // Override an existing method.
  306. var ancestor = object[name];
  307. object[name] = function() {
  308. var previous = this.base;
  309. this.base = ancestor;
  310. var returnValue = method.apply(this, arguments);
  311. this.base = previous;
  312. return returnValue;
  313. };
  314. };
  315. function combine(keys, values) {
  316. // Combine two arrays to make a hash.
  317. if (!values) values = keys;
  318. var hash = {};
  319. for (var i in keys) hash[i] = values[i];
  320. return hash;
  321. };
  322. function format(string) {
  323. // Replace %n with arguments[n].
  324. // e.g. format("%1 %2%3 %2a %1%3", "she", "se", "lls");
  325. // ==> "she sells sea shells"
  326. // Only %1 - %9 supported.
  327. var args = arguments;
  328. var _FORMAT = new RegExp("%([1-" + arguments.length + "])", "g");
  329. return String(string).replace(_FORMAT, function(match, index) {
  330. return index < args.length ? args[index] : match;
  331. });
  332. };
  333. function match(string, expression) {
  334. // Same as String.match() except that this function will return an empty
  335. // array if there is no match.
  336. return String(string).match(expression) || [];
  337. };
  338. function rescape(string) {
  339. // Make a string safe for creating a RegExp.
  340. return String(string).replace(_RESCAPE, "\\$1");
  341. };
  342. // http://blog.stevenlevithan.com/archives/faster-trim-javascript
  343. function trim(string) {
  344. return String(string).replace(_LTRIM, "").replace(_RTRIM, "");
  345. };
  346. function K(k) {
  347. return function() {
  348. return k;
  349. };
  350. };
  351. // -----------------------------------------------------------------------
  352. // parsing
  353. // -----------------------------------------------------------------------
  354. var Parser = RegGrp.extend({ignoreCase: true});
  355. var ENCODED = /\x01(\d+)/g,
  356. QUOTES = /'/g,
  357. STRING = /^\x01/,
  358. UNICODE = /\\([\da-fA-F]{1,4})/g;
  359. var _strings = [];
  360. var encoder = new Parser({
  361. // comments
  362. "<!\\-\\-|\\-\\->": "",
  363. "\\/\\*[^*]*\\*+([^\\/][^*]*\\*+)*\\/": "",
  364. // get rid
  365. "@(namespace|import)[^;\\n]+[;\\n]": "",
  366. // strings
  367. "'(\\\\.|[^'\\\\])*'": encodeString,
  368. '"(\\\\.|[^"\\\\])*"': encodeString,
  369. // white space
  370. "\\s+": " "
  371. });
  372. function encode(cssText) {
  373. return encoder.exec(cssText);
  374. };
  375. function decode(cssText) {
  376. return cssText.replace(ENCODED, function(match, index) {
  377. return _strings[index - 1];
  378. });
  379. };
  380. function encodeString(string) {
  381. return "\x01" + _strings.push(string.replace(UNICODE, function(match, chr) {
  382. return eval("'\\u" + "0000".slice(chr.length) + chr + "'");
  383. }).slice(1, -1).replace(QUOTES, "\\'"));
  384. };
  385. function getString(value) {
  386. return STRING.test(value) ? _strings[value.slice(1) - 1] : value;
  387. };
  388. // clone a "width" function to create a "height" function
  389. var rotater = new RegGrp({
  390. Width: "Height",
  391. width: "height",
  392. Left: "Top",
  393. left: "top",
  394. Right: "Bottom",
  395. right: "bottom",
  396. onX: "onY"
  397. });
  398. function rotate(fn) {
  399. return rotater.exec(fn);
  400. };
  401. // -----------------------------------------------------------------------
  402. // event handling
  403. // -----------------------------------------------------------------------
  404. var eventHandlers = [];
  405. function addResize(handler) {
  406. addRecalc(handler);
  407. addEventHandler(window, "onresize", handler);
  408. };
  409. // add an event handler (function) to an element
  410. function addEventHandler(element, type, handler) {
  411. element.attachEvent(type, handler);
  412. // store the handler so it can be detached later
  413. eventHandlers.push(arguments);
  414. };
  415. // remove an event handler assigned to an element by IE7
  416. function removeEventHandler(element, type, handler) {
  417. try {
  418. element.detachEvent(type, handler);
  419. } catch (ignore) {
  420. // write a letter of complaint to microsoft..
  421. }};
  422. // remove event handlers (they eat memory)
  423. addEventHandler(window, "onunload", function() {
  424. var handler;
  425. while (handler = eventHandlers.pop()) {
  426. removeEventHandler(handler[0], handler[1], handler[2]);
  427. }
  428. });
  429. function register(handler, element, condition) { // -@DRE
  430. //var set = handler[element.uniqueID];
  431. if (!handler.elements) handler.elements = {};
  432. if (condition) handler.elements[element.uniqueID] = element;
  433. else delete handler.elements[element.uniqueID];
  434. //return !set && condition;
  435. return condition;
  436. };
  437. addEventHandler(window, "onbeforeprint", function() {
  438. if (!IE7.CSS.print) new StyleSheet("print");
  439. IE7.CSS.print.recalc();
  440. });
  441. // -----------------------------------------------------------------------
  442. // pixel conversion
  443. // -----------------------------------------------------------------------
  444. // this is handy because it means that web developers can mix and match
  445. // measurement units in their style sheets. it is not uncommon to
  446. // express something like padding in "em" units whilst border thickness
  447. // is most often expressed in pixels.
  448. var PIXEL = /^\d+(px)?$/i;
  449. var PERCENT = /^\d+%$/;
  450. var getPixelValue = function(element, value) {
  451. if (PIXEL.test(value)) return parseInt(value);
  452. var style = element.style.left;
  453. var runtimeStyle = element.runtimeStyle.left;
  454. element.runtimeStyle.left = element.currentStyle.left;
  455. element.style.left = value || 0;
  456. value = element.style.pixelLeft;
  457. element.style.left = style;
  458. element.runtimeStyle.left = runtimeStyle;
  459. return value;
  460. };
  461. // -----------------------------------------------------------------------
  462. // generic
  463. // -----------------------------------------------------------------------
  464. var $IE7 = "ie7-";
  465. var Fix = Base.extend({
  466. constructor: function() {
  467. this.fixes = [];
  468. this.recalcs = [];
  469. },
  470. init: Undefined
  471. });
  472. // a store for functions that will be called when refreshing IE7
  473. var recalcs = [];
  474. function addRecalc(recalc) {
  475. recalcs.push(recalc);
  476. };
  477. IE7.recalc = function() {
  478. IE7.HTML.recalc();
  479. // re-apply style sheet rules (re-calculate ie7 classes)
  480. IE7.CSS.recalc();
  481. // apply global fixes to the document
  482. for (var i = 0; i < recalcs.length; i++) recalcs[i]();
  483. };
  484. function isFixed(element) {
  485. return element.currentStyle["ie7-position"] == "fixed";
  486. };
  487. // original style
  488. function getDefinedStyle(element, propertyName) {
  489. return element.currentStyle[$IE7 + propertyName] || element.currentStyle[propertyName];
  490. };
  491. function setOverrideStyle(element, propertyName, value) {
  492. if (element.currentStyle[$IE7 + propertyName] == null) {
  493. element.runtimeStyle[$IE7 + propertyName] = element.currentStyle[propertyName];
  494. }
  495. element.runtimeStyle[propertyName] = value;
  496. };
  497. // create a temporary element which is used to inherit styles
  498. // from the target element. the temporary element can be resized
  499. // to determine pixel widths/heights
  500. function createTempElement(tagName) {
  501. var element = document.createElement(tagName || "object");
  502. element.style.cssText = "position:absolute;padding:0;display:block;border:none;clip:rect(0 0 0 0);left:-9999";
  503. element.ie7_anon = true;
  504. return element;
  505. };
  506. // =========================================================================
  507. // ie7-cssQuery.js
  508. // =========================================================================
  509. function cssQuery(selector, context, single) {
  510. if (!_cache[selector]) {
  511. reg = []; // store for RegExp objects
  512. var fn = "";
  513. var selectors = cssParser.escape(selector).split(",");
  514. for (var i = 0; i < selectors.length; i++) {
  515. _wild = _index = _list = 0; // reset
  516. _duplicate = selectors.length > 1 ? 2 : 0; // reset
  517. var block = cssParser.exec(selectors[i]) || "if(0){";
  518. if (_wild) { // IE's pesky comment nodes
  519. block += format("if(e%1.nodeName!='!'){", _index);
  520. }
  521. // check for duplicates before storing results
  522. var store = _duplicate > 1 ? _TEST : "";
  523. block += format(store + _STORE, _index);
  524. // add closing braces
  525. block += Array(match(block, /\{/g).length + 1).join("}");
  526. fn += block;
  527. }
  528. eval(format(_FN, reg) + cssParser.unescape(fn) + "return s?null:r}");
  529. _cache[selector] = _selectorFunction;
  530. }
  531. return _cache[selector](context || document, single);
  532. };
  533. var _MSIE5 = appVersion < 6;
  534. var _EVALUATED = /^(href|src)$/;
  535. var _ATTRIBUTES = {
  536. "class": "className",
  537. "for": "htmlFor"
  538. };
  539. IE7._indexed = 1;
  540. IE7._byId = function(document, id) {
  541. var result = document.all[id] || null;
  542. // returns a single element or a collection
  543. if (!result || result.id == id) return result;
  544. // document.all has returned a collection of elements with name/id
  545. for (var i = 0; i < result.length; i++) {
  546. if (result[i].id == id) return result[i];
  547. }
  548. return null;
  549. };
  550. IE7._getAttribute = function(element, name) {
  551. if (name == "src" && element.pngSrc) return element.pngSrc;
  552. var attribute = _MSIE5 ? (element.attributes[name] || element.attributes[_ATTRIBUTES[name.toLowerCase()]]) : element.getAttributeNode(name);
  553. if (attribute && (attribute.specified || name == "value")) {
  554. if (_EVALUATED.test(name)) {
  555. return element.getAttribute(name, 2);
  556. } else if (name == "class") {
  557. return element.className.replace(/\sie7_\w+/g, "");
  558. } else if (name == "style") {
  559. return element.style.cssText;
  560. } else {
  561. return attribute.nodeValue;
  562. }
  563. }
  564. return null;
  565. };
  566. var names = "colSpan,rowSpan,vAlign,dateTime,accessKey,tabIndex,encType,maxLength,readOnly,longDesc";
  567. // Convert the list of strings to a hash, mapping the lowercase name to the camelCase name.
  568. extend(_ATTRIBUTES, combine(names.toLowerCase().split(","), names.split(",")));
  569. IE7._getNextElementSibling = function(node) {
  570. // return the next element to the supplied element
  571. // nextSibling is not good enough as it might return a text or comment node
  572. while (node && (node = node.nextSibling) && (node.nodeType != 1 || node.nodeName == "!")) continue;
  573. return node;
  574. };
  575. IE7._getPreviousElementSibling = function(node) {
  576. // return the previous element to the supplied element
  577. while (node && (node = node.previousSibling) && (node.nodeType != 1 || node.nodeName == "!")) continue;
  578. return node;
  579. };
  580. // =========================================================================
  581. // CSSParser
  582. // =========================================================================
  583. var IMPLIED_ASTERISK = /([\s>+~,]|[^(]\+|^)([#.:\[])/g,
  584. IMPLIED_SPACE = /(^|,)([^\s>+~])/g,
  585. WHITESPACE = /\s*([\s>+~(),]|^|$)\s*/g,
  586. WILD_CARD = /\s\*\s/g;;
  587. var CSSParser = RegGrp.extend({
  588. constructor: function(items) {
  589. this.base(items);
  590. this.sorter = new RegGrp;
  591. this.sorter.add(/:not\([^)]*\)/, RegGrp.IGNORE);
  592. this.sorter.add(/([ >](\*|[\w-]+))([^: >+~]*)(:\w+-child(\([^)]+\))?)([^: >+~]*)/, "$1$3$6$4");
  593. },
  594. ignoreCase: true,
  595. escape: function(selector) {
  596. return this.optimise(this.format(selector));
  597. },
  598. format: function(selector) {
  599. return selector
  600. .replace(WHITESPACE, "$1")
  601. .replace(IMPLIED_SPACE, "$1 $2")
  602. .replace(IMPLIED_ASTERISK, "$1*$2");
  603. },
  604. optimise: function(selector) {
  605. // optimise wild card descendant selectors
  606. return this.sorter.exec(selector.replace(WILD_CARD, ">* "));
  607. },
  608. unescape: function(selector) {
  609. return decode(selector);
  610. }
  611. });
  612. // some constants
  613. var _OPERATORS = {
  614. "": "%1!=null",
  615. "=": "%1=='%2'",
  616. "~=": /(^| )%1( |$)/,
  617. "|=": /^%1(-|$)/,
  618. "^=": /^%1/,
  619. "$=": /%1$/,
  620. "*=": /%1/
  621. };
  622. var _PSEUDO_CLASSES = {
  623. "first-child": "!IE7._getPreviousElementSibling(e%1)",
  624. "link": "e%1.currentStyle['ie7-link']=='link'",
  625. "visited": "e%1.currentStyle['ie7-link']=='visited'"
  626. };
  627. var _VAR = "var p%2=0,i%2,e%2,n%2=e%1.";
  628. var _ID = "e%1.sourceIndex";
  629. var _TEST = "var g=" + _ID + ";if(!p[g]){p[g]=1;";
  630. var _STORE = "r[r.length]=e%1;if(s)return e%1;";
  631. var _FN = "var _selectorFunction=function(e0,s){IE7._indexed++;var r=[],p={},reg=[%1],d=document;";
  632. var reg; // a store for RexExp objects
  633. var _index;
  634. var _wild; // need to flag certain _wild card selectors as MSIE includes comment nodes
  635. var _list; // are we processing a node _list?
  636. var _duplicate; // possible duplicates?
  637. var _cache = {}; // store parsed selectors
  638. // a hideous parser
  639. var cssParser = new CSSParser({
  640. " (\\*|[\\w-]+)#([\\w-]+)": function(match, tagName, id) { // descendant selector followed by ID
  641. _wild = false;
  642. var replacement = "var e%2=IE7._byId(d,'%4');if(e%2&&";
  643. if (tagName != "*") replacement += "e%2.nodeName=='%3'&&";
  644. replacement += "(e%1==d||e%1.contains(e%2))){";
  645. if (_list) replacement += format("i%1=n%1.length;", _list);
  646. return format(replacement, _index++, _index, tagName.toUpperCase(), id);
  647. },
  648. " (\\*|[\\w-]+)": function(match, tagName) { // descendant selector
  649. _duplicate++; // this selector may produce duplicates
  650. _wild = tagName == "*";
  651. var replacement = _VAR;
  652. // IE5.x does not support getElementsByTagName("*");
  653. replacement += (_wild && _MSIE5) ? "all" : "getElementsByTagName('%3')";
  654. replacement += ";for(i%2=0;(e%2=n%2[i%2]);i%2++){";
  655. return format(replacement, _index++, _list = _index, tagName.toUpperCase());
  656. },
  657. ">(\\*|[\\w-]+)": function(match, tagName) { // child selector
  658. var children = _list;
  659. _wild = tagName == "*";
  660. var replacement = _VAR;
  661. // use the children property for MSIE as it does not contain text nodes
  662. // (but the children collection still includes comments).
  663. // the document object does not have a children collection
  664. replacement += children ? "children": "childNodes";
  665. if (!_wild && children) replacement += ".tags('%3')";
  666. replacement += ";for(i%2=0;(e%2=n%2[i%2]);i%2++){";
  667. if (_wild) {
  668. replacement += "if(e%2.nodeType==1){";
  669. _wild = _MSIE5;
  670. } else {
  671. if (!children) replacement += "if(e%2.nodeName=='%3'){";
  672. }
  673. return format(replacement, _index++, _list = _index, tagName.toUpperCase());
  674. },
  675. "\\+(\\*|[\\w-]+)": function(match, tagName) { // direct adjacent selector
  676. var replacement = "";
  677. if (_wild) replacement += "if(e%1.nodeName!='!'){";
  678. _wild = false;
  679. replacement += "e%1=IE7._getNextElementSibling(e%1);if(e%1";
  680. if (tagName != "*") replacement += "&&e%1.nodeName=='%2'";
  681. replacement += "){";
  682. return format(replacement, _index, tagName.toUpperCase());
  683. },
  684. "~(\\*|[\\w-]+)": function(match, tagName) { // indirect adjacent selector
  685. var replacement = "";
  686. if (_wild) replacement += "if(e%1.nodeName!='!'){";
  687. _wild = false;
  688. _duplicate = 2; // this selector may produce duplicates
  689. replacement += "while(e%1=e%1.nextSibling){if(e%1.ie7_adjacent==IE7._indexed)break;if(";
  690. if (tagName == "*") {
  691. replacement += "e%1.nodeType==1";
  692. if (_MSIE5) replacement += "&&e%1.nodeName!='!'";
  693. } else replacement += "e%1.nodeName=='%2'";
  694. replacement += "){e%1.ie7_adjacent=IE7._indexed;";
  695. return format(replacement, _index, tagName.toUpperCase());
  696. },
  697. "#([\\w-]+)": function(match, id) { // ID selector
  698. _wild = false;
  699. var replacement = "if(e%1.id=='%2'){";
  700. if (_list) replacement += format("i%1=n%1.length;", _list);
  701. return format(replacement, _index, id);
  702. },
  703. "\\.([\\w-]+)": function(match, className) { // class selector
  704. _wild = false;
  705. // store RegExp objects - slightly faster on IE
  706. reg.push(new RegExp("(^|\\s)" + rescape(className) + "(\\s|$)"));
  707. return format("if(e%1.className&&reg[%2].test(e%1.className)){", _index, reg.length - 1);
  708. },
  709. "\\[([\\w-]+)\\s*([^=]?=)?\\s*([^\\]]*)\\]": function(match, attr, operator, value) { // attribute selectors
  710. var alias = _ATTRIBUTES[attr] || attr;
  711. if (operator) {
  712. var getAttribute = "e%1.getAttribute('%2',2)";
  713. if (!_EVALUATED.test(attr)) {
  714. getAttribute = "e%1.%3||" + getAttribute;
  715. }
  716. attr = format("(" + getAttribute + ")", _index, attr, alias);
  717. } else {
  718. attr = format("IE7._getAttribute(e%1,'%2')", _index, attr);
  719. }
  720. var replacement = _OPERATORS[operator || ""] || "0";
  721. if (replacement && replacement.source) {
  722. reg.push(new RegExp(format(replacement.source, rescape(cssParser.unescape(value)))));
  723. replacement = "reg[%2].test(%1)";
  724. value = reg.length - 1;
  725. }
  726. return "if(" + format(replacement, attr, value) + "){";
  727. },
  728. ":+([\\w-]+)(\\(([^)]+)\\))?": function(match, pseudoClass, $2, args) { // pseudo class selectors
  729. pseudoClass = _PSEUDO_CLASSES[pseudoClass];
  730. return "if(" + (pseudoClass ? format(pseudoClass, _index, args || "") : "0") + "){";
  731. }
  732. });
  733. // =========================================================================
  734. // ie7-css.js
  735. // =========================================================================
  736. var HYPERLINK = /a(#[\w-]+)?(\.[\w-]+)?:(hover|active)/i;
  737. var BRACE1 = /\s*\{\s*/, BRACE2 = /\s*\}\s*/, COMMA = /\s*\,\s*/;
  738. var FIRST_LINE_LETTER = /(.*)(:first-(line|letter))/;
  739. //var UNKNOWN = /UNKNOWN|([:.])\w+\1/i;
  740. var styleSheets = document.styleSheets;
  741. IE7.CSS = new (Fix.extend({ // single instance
  742. parser: new Parser,
  743. screen: "",
  744. print: "",
  745. styles: [],
  746. rules: [],
  747. pseudoClasses: appVersion < 7 ? "first\\-child" : "",
  748. dynamicPseudoClasses: {
  749. toString: function() {
  750. var strings = [];
  751. for (var pseudoClass in this) strings.push(pseudoClass);
  752. return strings.join("|");
  753. }
  754. },
  755. init: function() {
  756. var NONE = "^\x01$";
  757. var CLASS = "\\[class=?[^\\]]*\\]";
  758. var pseudoClasses = [];
  759. if (this.pseudoClasses) pseudoClasses.push(this.pseudoClasses);
  760. var dynamicPseudoClasses = this.dynamicPseudoClasses.toString();
  761. if (dynamicPseudoClasses) pseudoClasses.push(dynamicPseudoClasses);
  762. pseudoClasses = pseudoClasses.join("|");
  763. var unknown = appVersion < 7 ? ["[>+~[(]|([:.])\\w+\\1"] : [CLASS];
  764. if (pseudoClasses) unknown.push(":(" + pseudoClasses + ")");
  765. this.UNKNOWN = new RegExp(unknown.join("|") || NONE, "i");
  766. var complex = appVersion < 7 ? ["\\[[^\\]]+\\]|[^\\s(\\[]+\\s*[+~]"] : [CLASS];
  767. var complexRule = complex.concat();
  768. if (pseudoClasses) complexRule.push(":(" + pseudoClasses + ")");
  769. Rule.COMPLEX = new RegExp(complexRule.join("|") || NONE, "ig");
  770. if (this.pseudoClasses) complex.push(":(" + this.pseudoClasses + ")");
  771. DynamicRule.COMPLEX = new RegExp(complex.join("|") || NONE, "i");
  772. DynamicRule.MATCH = new RegExp(dynamicPseudoClasses ? "(.*):(" + dynamicPseudoClasses + ")(.*)" : NONE, "i");
  773. this.createStyleSheet();
  774. this.refresh();
  775. },
  776. addEventHandler: function() {
  777. addEventHandler.apply(null, arguments);
  778. },
  779. addFix: function(expression, replacement) {
  780. this.parser.add(expression, replacement);
  781. },
  782. addRecalc: function(propertyName, test, handler, replacement) {
  783. // recalcs occur whenever the document is refreshed using document.recalc()
  784. test = new RegExp("([{;\\s])" + propertyName + "\\s*:\\s*" + test + "[^;}]*");
  785. var id = this.recalcs.length;
  786. if (replacement) replacement = propertyName + ":" + replacement;
  787. this.addFix(test, function(match, $1) {
  788. return (replacement ? $1 + replacement : match) + ";ie7-" + match.slice(1) + ";ie7_recalc" + id + ":1";
  789. });
  790. this.recalcs.push(arguments);
  791. return id;
  792. },
  793. apply: function() {
  794. this.getInlineStyles();
  795. new StyleSheet("screen");
  796. this.trash();
  797. },
  798. createStyleSheet: function() {
  799. // create the IE7 style sheet
  800. this.styleSheet = document.createStyleSheet();
  801. // flag it so we can ignore it during parsing
  802. this.styleSheet.ie7 = true;
  803. this.styleSheet.owningElement.ie7 = true;
  804. this.styleSheet.cssText = HEADER;
  805. },
  806. getInlineStyles: function() {
  807. // load inline styles
  808. var styleSheets = document.getElementsByTagName("style"), styleSheet;
  809. for (var i = styleSheets.length - 1; (styleSheet = styleSheets[i]); i--) {
  810. if (!styleSheet.disabled && !styleSheet.ie7) {
  811. this.styles.push(styleSheet.innerHTML);
  812. }
  813. }
  814. },
  815. getText: function(styleSheet, path) {
  816. // explorer will trash unknown selectors (it converts them to "UNKNOWN").
  817. // so we must reload external style sheets (internal style sheets can have their text
  818. // extracted through the innerHTML property).
  819. // load the style sheet text from an external file
  820. try {
  821. var cssText = styleSheet.cssText;
  822. } catch (e) {
  823. cssText = "";
  824. }
  825. if (httpRequest) cssText = loadFile(styleSheet.href, path) || cssText;
  826. return cssText;
  827. },
  828. recalc: function() {
  829. this.screen.recalc();
  830. // we're going to read through all style rules.
  831. // certain rules have had ie7 properties added to them.
  832. // e.g. p{top:0; ie7_recalc2:1; left:0}
  833. // this flags a property in the rule as needing a fix.
  834. // the selector text is then used to query the document.
  835. // we can then loop through the results of the query
  836. // and fix the elements.
  837. // we ignore the IE7 rules - so count them in the header
  838. var RECALCS = /ie7_recalc\d+/g;
  839. var start = HEADER.match(/[{,]/g).length;
  840. // only calculate screen fixes. print fixes don't show up anyway
  841. var stop = start + (this.screen.cssText.match(/\{/g)||"").length;
  842. var rules = this.styleSheet.rules, rule;
  843. var calcs, calc, elements, element, i, j, k, id;
  844. // loop through all rules
  845. for (i = start; i < stop; i++) {
  846. rule = rules[i];
  847. var cssText = rule.style.cssText;
  848. // search for the "ie7_recalc" flag (there may be more than one)
  849. if (rule && (calcs = cssText.match(RECALCS))) {
  850. // use the selector text to query the document
  851. elements = cssQuery(rule.selectorText);
  852. // if there are matching elements then loop
  853. // through the recalc functions and apply them
  854. // to each element
  855. if (elements.length) for (j = 0; j < calcs.length; j++) {
  856. // get the matching flag (e.g. ie7_recalc3)
  857. id = calcs[j];
  858. // extract the numeric id from the end of the flag
  859. // and use it to index the collection of recalc
  860. // functions
  861. calc = IE7.CSS.recalcs[id.slice(10)][2];
  862. for (k = 0; (element = elements[k]); k++) {
  863. // apply the fix
  864. if (element.currentStyle[id]) calc(element, cssText);
  865. }
  866. }
  867. }
  868. }
  869. },
  870. refresh: function() {
  871. this.styleSheet.cssText = HEADER + this.screen + this.print;
  872. },
  873. trash: function() {
  874. // trash the old style sheets
  875. for (var i = 0; i < styleSheets.length; i++) {
  876. if (!styleSheets[i].ie7) {
  877. try {
  878. var cssText = styleSheets[i].cssText;
  879. } catch (e) {
  880. cssText = "";
  881. }
  882. if (cssText) styleSheets[i].cssText = "";
  883. }
  884. }
  885. }
  886. }));
  887. // -----------------------------------------------------------------------
  888. // IE7 StyleSheet class
  889. // -----------------------------------------------------------------------
  890. var StyleSheet = Base.extend({
  891. constructor: function(media) {
  892. this.media = media;
  893. this.load();
  894. IE7.CSS[media] = this;
  895. IE7.CSS.refresh();
  896. },
  897. createRule: function(selector, cssText) {
  898. if (IE7.CSS.UNKNOWN.test(selector)) {
  899. var match;
  900. if (PseudoElement && (match = selector.match(PseudoElement.MATCH))) {
  901. return new PseudoElement(match[1], match[2], cssText);
  902. } else if (match = selector.match(DynamicRule.MATCH)) {
  903. if (!HYPERLINK.test(match[0]) || DynamicRule.COMPLEX.test(match[0])) {
  904. return new DynamicRule(selector, match[1], match[2], match[3], cssText);
  905. }
  906. } else return new Rule(selector, cssText);
  907. }
  908. return selector + " {" + cssText + "}";
  909. },
  910. getText: function() {
  911. // store for style sheet text
  912. var _inlineStyles = [].concat(IE7.CSS.styles);
  913. // parse media decalarations
  914. var MEDIA = /@media\s+([^{]*)\{([^@]+\})\s*\}/gi;
  915. var ALL = /\ball\b|^$/i, SCREEN = /\bscreen\b/i, PRINT = /\bprint\b/i;
  916. function _parseMedia(cssText, media) {
  917. _filterMedia.value = media;
  918. return cssText.replace(MEDIA, _filterMedia);
  919. };
  920. function _filterMedia(match, media, cssText) {
  921. media = _simpleMedia(media);
  922. switch (media) {
  923. case "screen":
  924. case "print":
  925. if (media != _filterMedia.value) return "";
  926. case "all":
  927. return cssText;
  928. }
  929. return "";
  930. };
  931. function _simpleMedia(media) {
  932. if (ALL.test(media)) return "all";
  933. else if (SCREEN.test(media)) return (PRINT.test(media)) ? "all" : "screen";
  934. else if (PRINT.test(media)) return "print";
  935. };
  936. var self = this;
  937. function _getCSSText(styleSheet, path, media, level) {
  938. var cssText = "";
  939. if (!level) {
  940. media = _simpleMedia(styleSheet.media);
  941. level = 0;
  942. }
  943. if (media == "all" || media == self.media) {
  944. // IE only allows importing style sheets three levels deep.
  945. // it will crash if you try to access a level below this
  946. if (level < 3) {
  947. // loop through imported style sheets
  948. for (var i = 0; i < styleSheet.imports.length; i++) {
  949. // call this function recursively to get all imported style sheets
  950. cssText += _getCSSText(styleSheet.imports[i], getPath(styleSheet.href, path), media, level + 1);
  951. }
  952. }
  953. // retrieve inline style or load an external style sheet
  954. cssText += encode(styleSheet.href ? _loadStyleSheet(styleSheet, path) : _inlineStyles.pop() || "");
  955. cssText = _parseMedia(cssText, self.media);
  956. }
  957. return cssText;
  958. };
  959. // store loaded cssText URLs
  960. var fileCache = {};
  961. // load an external style sheet
  962. function _loadStyleSheet(styleSheet, path) {
  963. var url = makePath(styleSheet.href, path);
  964. // if the style sheet has already loaded then don't duplicate it
  965. if (fileCache[url]) return "";
  966. // load from source
  967. fileCache[url] = (styleSheet.disabled) ? "" :
  968. _fixUrls(IE7.CSS.getText(styleSheet, path), getPath(styleSheet.href, path));
  969. return fileCache[url];
  970. };
  971. // fix css paths
  972. // we're lumping all css text into one big style sheet so relative
  973. // paths have to be fixed. this is necessary anyway because of other
  974. // explorer bugs.
  975. var URL = /(url\s*\(\s*['"]?)([\w\.]+[^:\)]*['"]?\))/gi;
  976. function _fixUrls(cssText, pathname) {
  977. // hack & slash
  978. return cssText.replace(URL, "$1" + pathname.slice(0, pathname.lastIndexOf("/") + 1) + "$2");
  979. };
  980. // load all style sheets in the document
  981. for (var i = 0; i < styleSheets.length; i++) {
  982. if (!styleSheets[i].disabled && !styleSheets[i].ie7) {
  983. this.cssText += _getCSSText(styleSheets[i]);
  984. }
  985. }
  986. },
  987. load: function() {
  988. this.cssText = "";
  989. this.getText();
  990. this.parse();
  991. this.cssText = decode(this.cssText);
  992. fileCache = {};
  993. },
  994. parse: function() {
  995. this.cssText = IE7.CSS.parser.exec(this.cssText);
  996. // parse the style sheet
  997. var offset = IE7.CSS.rules.length;
  998. var rules = this.cssText.split(BRACE2), rule;
  999. var selectors, cssText, i, j;
  1000. for (i = 0; i < rules.length; i++) {
  1001. rule = rules[i].split(BRACE1);
  1002. selectors = rule[0].split(COMMA);
  1003. cssText = rule[1];
  1004. for (j = 0; j < selectors.length; j++) {
  1005. selectors[j] = cssText ? this.createRule(selectors[j], cssText) : "";
  1006. }
  1007. rules[i] = selectors.join("\n");
  1008. }
  1009. this.cssText = rules.join("\n");
  1010. this.rules = IE7.CSS.rules.slice(offset);
  1011. },
  1012. recalc: function() {
  1013. var rule, i;
  1014. for (i = 0; (rule = this.rules[i]); i++) rule.recalc();
  1015. },
  1016. toString: function() {
  1017. return "@media " + this.media + "{" + this.cssText + "}";
  1018. }
  1019. });
  1020. var PseudoElement;
  1021. // -----------------------------------------------------------------------
  1022. // IE7 style rules
  1023. // -----------------------------------------------------------------------
  1024. var Rule = IE7.Rule = Base.extend({
  1025. // properties
  1026. constructor: function(selector, cssText) {
  1027. this.id = IE7.CSS.rules.length;
  1028. this.className = Rule.PREFIX + this.id;
  1029. selector = selector.match(FIRST_LINE_LETTER) || selector || "*";
  1030. this.selector = selector[1] || selector;
  1031. this.selectorText = this.parse(this.selector) + (selector[2] || "");
  1032. this.cssText = cssText;
  1033. this.MATCH = new RegExp("\\s" + this.className + "(\\s|$)", "g");
  1034. IE7.CSS.rules.push(this);
  1035. this.init();
  1036. },
  1037. init: Undefined,
  1038. add: function(element) {
  1039. // allocate this class
  1040. element.className += " " + this.className;
  1041. },
  1042. recalc: function() {
  1043. // execute the underlying css query for this class
  1044. var match = cssQuery(this.selector);
  1045. // add the class name for all matching elements
  1046. for (var i = 0; i < match.length; i++) this.add(match[i]);
  1047. },
  1048. parse: function(selector) {
  1049. // attempt to preserve specificity for "loose" parsing by
  1050. // removing unknown tokens from a css selector but keep as
  1051. // much as we can..
  1052. var simple = selector.replace(Rule.CHILD, " ").replace(Rule.COMPLEX, "");
  1053. if (appVersion < 7) simple = simple.replace(Rule.MULTI, "");
  1054. var tags = match(simple, Rule.TAGS).length - match(selector, Rule.TAGS).length;
  1055. var classes = match(simple, Rule.CLASSES).length - match(selector, Rule.CLASSES).length + 1;
  1056. while (classes > 0 && Rule.CLASS.test(simple)) {
  1057. simple = simple.replace(Rule.CLASS, "");
  1058. classes--;
  1059. }
  1060. while (tags > 0 && Rule.TAG.test(simple)) {
  1061. simple = simple.replace(Rule.TAG, "$1*");
  1062. tags--;
  1063. }
  1064. simple += "." + this.className;
  1065. classes = Math.min(classes, 2);
  1066. tags = Math.min(tags, 2);
  1067. var score = -10 * classes - tags;
  1068. if (score > 0) {
  1069. simple = simple + "," + Rule.MAP[score] + " " + simple;
  1070. }
  1071. return simple;
  1072. },
  1073. remove: function(element) {
  1074. // deallocate this class
  1075. element.className = element.className.replace(this.MATCH, "$1");
  1076. },
  1077. toString: function() {
  1078. return format("%1 {%2}", this.selectorText, this.cssText);
  1079. }
  1080. }, {
  1081. CHILD: />/g,
  1082. CLASS: /\.[\w-]+/,
  1083. CLASSES: /[.:\[]/g,
  1084. MULTI: /(\.[\w-]+)+/g,
  1085. PREFIX: "ie7_class",
  1086. TAG: /^\w+|([\s>+~])\w+/,
  1087. TAGS: /^\w|[\s>+~]\w/g,
  1088. MAP: {
  1089. 1: "html",
  1090. 2: "html body",
  1091. 10: ".ie7_html",
  1092. 11: "html.ie7_html",
  1093. 12: "html.ie7_html body",
  1094. 20: ".ie7_html .ie7_body",
  1095. 21: "html.ie7_html .ie7_body",
  1096. 22: "html.ie7_html body.ie7_body"
  1097. }
  1098. });
  1099. // -----------------------------------------------------------------------
  1100. // IE7 dynamic style
  1101. // -----------------------------------------------------------------------
  1102. // object properties:
  1103. // attach: the element that an event handler will be attached to
  1104. // target: the element that will have the IE7 class applied
  1105. var DynamicRule = Rule.extend({
  1106. // properties
  1107. constructor: function(selector, attach, dynamicPseudoClass, target, cssText) {
  1108. // initialise object properties
  1109. this.attach = attach || "*";
  1110. this.dynamicPseudoClass = IE7.CSS.dynamicPseudoClasses[dynamicPseudoClass];
  1111. this.target = target;
  1112. this.base(selector, cssText);
  1113. },
  1114. recalc: function() {
  1115. // execute the underlying css query for this class
  1116. var attaches = cssQuery(this.attach), attach;
  1117. // process results
  1118. for (var i = 0; attach = attaches[i]; i++) {
  1119. // retrieve the event handler's target element(s)
  1120. var target = this.target ? cssQuery(this.target, attach) : [attach];
  1121. // attach event handlers for dynamic pseudo-classes
  1122. if (target.length) this.dynamicPseudoClass.apply(attach, target, this);
  1123. }
  1124. }
  1125. });
  1126. // -----------------------------------------------------------------------
  1127. // IE7 dynamic pseudo-classes
  1128. // -----------------------------------------------------------------------
  1129. var DynamicPseudoClass = Base.extend({
  1130. constructor: function(name, apply) {
  1131. this.name = name;
  1132. this.apply = apply;
  1133. this.instances = {};
  1134. IE7.CSS.dynamicPseudoClasses[name] = this;
  1135. },
  1136. register: function(instance) {
  1137. // an "instance" is actually an Arguments object
  1138. var _class = instance[2];
  1139. instance.id = _class.id + instance[0].uniqueID;
  1140. if (!this.instances[instance.id]) {
  1141. var target = instance[1], j;
  1142. for (j = 0; j < target.length; j++) _class.add(target[j]);
  1143. this.instances[instance.id] = instance;
  1144. }
  1145. },
  1146. unregister: function(instance) {
  1147. if (this.instances[instance.id]) {
  1148. var _class = instance[2];
  1149. var target = instance[1], j;
  1150. for (j = 0; j < target.length; j++) _class.remove(target[j]);
  1151. delete this.instances[instance.id];
  1152. }
  1153. }
  1154. });
  1155. // -----------------------------------------------------------------------
  1156. // dynamic pseudo-classes
  1157. // -----------------------------------------------------------------------
  1158. if (appVersion < 7) {
  1159. var Hover = new DynamicPseudoClass("hover", function(element) {
  1160. var instance = arguments;
  1161. IE7.CSS.addEventHandler(element, appVersion < 5.5 ? "onmouseover" : "onmouseenter", function() {
  1162. Hover.register(instance);
  1163. });
  1164. IE7.CSS.addEventHandler(element, appVersion < 5.5 ? "onmouseout" : "onmouseleave", function() {
  1165. Hover.unregister(instance);
  1166. });
  1167. });
  1168. // globally trap the mouseup event (thanks Martijn!)
  1169. addEventHandler(document, "onmouseup", function() {
  1170. var instances = Hover.instances;
  1171. for (var i in instances)
  1172. if (!instances[i][0].contains(event.srcElement))
  1173. Hover.unregister(instances[i]);
  1174. });
  1175. }
  1176. // -----------------------------------------------------------------------
  1177. // propertyName: inherit;
  1178. // -----------------------------------------------------------------------
  1179. IE7.CSS.addRecalc("[\\w-]+", "inherit", function(element, cssText) {
  1180. var inherited = cssText.match(/[\w-]+\s*:\s*inherit/g);
  1181. for (var i = 0; i < inherited.length; i++) {
  1182. var propertyName = inherited[i].replace(/ie7\-|\s*:\s*inherit/g, "").replace(/\-([a-z])/g, function(match, chr) {
  1183. return chr.toUpperCase()
  1184. });
  1185. element.runtimeStyle[propertyName] = element.parentElement.currentStyle[propertyName];
  1186. }
  1187. });
  1188. // =========================================================================
  1189. // ie7-html.js
  1190. // =========================================================================
  1191. // default font-sizes
  1192. //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}";
  1193. IE7.HTML = new (Fix.extend({ // single instance
  1194. fixed: {},
  1195. init: Undefined,
  1196. addFix: function() {
  1197. // fixes are a one-off, they are applied when the document is loaded
  1198. this.fixes.push(arguments);
  1199. },
  1200. apply: function() {
  1201. for (var i = 0; i < this.fixes.length; i++) {
  1202. var match = cssQuery(this.fixes[i][0]);
  1203. var fix = this.fixes[i][1];
  1204. for (var j = 0; j < match.length; j++) fix(match[j]);
  1205. }
  1206. },
  1207. addRecalc: function() {
  1208. // recalcs occur whenever the document is refreshed using document.recalc()
  1209. this.recalcs.push(arguments);
  1210. },
  1211. recalc: function() {
  1212. // loop through the fixes
  1213. for (var i = 0; i < this.recalcs.length; i++) {
  1214. var match = cssQuery(this.recalcs[i][0]);
  1215. var recalc = this.recalcs[i][1], element;
  1216. var key = Math.pow(2, i);
  1217. for (var j = 0; (element = match[j]); j++) {
  1218. var uniqueID = element.uniqueID;
  1219. if ((this.fixed[uniqueID] & key) == 0) {
  1220. element = recalc(element) || element;
  1221. this.fixed[uniqueID] |= key;
  1222. }
  1223. }
  1224. }
  1225. }
  1226. }));
  1227. if (appVersion < 7) {
  1228. // provide support for the <abbr> tag.
  1229. // this is a proper fix, it preserves the DOM structure and
  1230. // <abbr> elements report the correct tagName & namespace prefix
  1231. document.createElement("abbr");
  1232. // bind to the first child control
  1233. IE7.HTML.addRecalc("label", function(label) {
  1234. if (!label.htmlFor) {
  1235. var firstChildControl = cssQuery("input,textarea", label, true);
  1236. if (firstChildControl) {
  1237. addEventHandler(label, "onclick", function() {
  1238. firstChildControl.click();
  1239. });
  1240. }
  1241. }
  1242. });
  1243. }
  1244. // =========================================================================
  1245. // ie7-layout.js
  1246. // =========================================================================
  1247. var NUMERIC = "[.\\d]";
  1248. new function(_) {
  1249. var layout = IE7.Layout = this;
  1250. // big, ugly box-model hack + min/max stuff
  1251. // #tantek > #erik > #dean { voice-family: hacker; }
  1252. // -----------------------------------------------------------------------
  1253. // "layout"
  1254. // -----------------------------------------------------------------------
  1255. HEADER += "*{boxSizing:content-box}";
  1256. // does an element have "layout" ?
  1257. IE7.hasLayout = appVersion < 5.5 ? function(element) {
  1258. // element.currentStyle.hasLayout doesn't work for IE5.0
  1259. return element.clientWidth;
  1260. } : function(element) {
  1261. return element.currentStyle.hasLayout;
  1262. };
  1263. // give an element "layout"
  1264. layout.boxSizing = function(element) {
  1265. if (!IE7.hasLayout(element)) {
  1266. //# element.runtimeStyle.fixedHeight =
  1267. element.style.height = "0cm";
  1268. if (element.currentStyle.verticalAlign == "auto")
  1269. element.runtimeStyle.verticalAlign = "top";
  1270. // when an element acquires "layout", margins no longer collapse correctly
  1271. collapseMargins(element);
  1272. }
  1273. };
  1274. // -----------------------------------------------------------------------
  1275. // Margin Collapse
  1276. // -----------------------------------------------------------------------
  1277. function collapseMargins(element) {
  1278. if (element != viewport && element.currentStyle.position != "absolute") {
  1279. collapseMargin(element, "marginTop");
  1280. collapseMargin(element, "marginBottom");
  1281. }
  1282. };
  1283. function collapseMargin(element, type) {
  1284. if (!element.runtimeStyle[type]) {
  1285. var parentElement = element.parentElement;
  1286. if (parentElement && IE7.hasLayout(parentElement) && !IE7[type == "marginTop" ? "_getPreviousElementSibling" : "_getNextElementSibling"](element)) return;
  1287. var child = cssQuery(">*:" + (type == "marginTop" ? "first" : "last") + "-child", element, true);
  1288. if (child && child.currentStyle.styleFloat == "none" && IE7.hasLayout(child)) {
  1289. collapseMargin(child, type);
  1290. margin = _getMargin(element, element.currentStyle[type]);
  1291. childMargin = _getMargin(child, child.currentStyle[type]);
  1292. if (margin < 0 || childMargin < 0) {
  1293. element.runtimeStyle[type] = margin + childMargin;
  1294. } else {
  1295. element.runtimeStyle[type] = Math.max(childMargin, margin);
  1296. }
  1297. child.runtimeStyle[type] = "0px";
  1298. }
  1299. }
  1300. };
  1301. function _getMargin(element, value) {
  1302. return value == "auto" ? 0 : getPixelValue(element, value);
  1303. };
  1304. // -----------------------------------------------------------------------
  1305. // box-model
  1306. // -----------------------------------------------------------------------
  1307. // constants
  1308. var UNIT = /^[.\d][\w%]*$/, AUTO = /^(auto|0cm)$/;
  1309. var applyWidth, applyHeight;
  1310. IE7.Layout.borderBox = function(element){
  1311. applyWidth(element);
  1312. applyHeight(element);
  1313. };
  1314. var fixWidth = function(HEIGHT) {
  1315. applyWidth = function(element) {
  1316. if (!PERCENT.test(element.currentStyle.width)) fixWidth(element);
  1317. collapseMargins(element);
  1318. };
  1319. function fixWidth(element, value) {
  1320. if (!element.runtimeStyle.fixedWidth) {
  1321. if (!value) value = element.currentStyle.width;
  1322. element.runtimeStyle.fixedWidth = (UNIT.test(value)) ? Math.max(0, getFixedWidth(element, value)) : value;
  1323. setOverrideStyle(element, "width", element.runtimeStyle.fixedWidth);
  1324. }
  1325. };
  1326. function layoutWidth(element) {
  1327. if (!isFixed(element)) {
  1328. var layoutParent = element.offsetParent;
  1329. while (layoutParent && !IE7.hasLayout(layoutParent)) layoutParent = layoutParent.offsetParent;
  1330. }
  1331. return (layoutParent || viewport).clientWidth;
  1332. };
  1333. function getPixelWidth(element, value) {
  1334. if (PERCENT.test(value)) return parseInt(parseFloat(value) / 100 * layoutWidth(element));
  1335. return getPixelValue(element, value);
  1336. };
  1337. var getFixedWidth = function(element, value) {
  1338. var borderBox = element.currentStyle["box-sizing"] == "border-box";
  1339. var adjustment = 0;
  1340. if (quirksMode && !borderBox)
  1341. adjustment += getBorderWidth(element) + getWidth(element, "padding");
  1342. else if (!quirksMode && borderBox)
  1343. adjustment -= getBorderWidth(element) + getWidth(element, "padding");
  1344. return getPixelWidth(element, value) + adjustment;
  1345. };
  1346. // easy way to get border thickness for elements with "layout"
  1347. function getBorderWidth(element) {
  1348. return element.offsetWidth - element.clientWidth;
  1349. };
  1350. // have to do some pixel conversion to get padding/margin thickness :-(
  1351. function getWidth(element, type) {
  1352. return getPixelWidth(element, element.currentStyle[type + "Left"]) + getPixelWidth(element, element.currentStyle[type + "Right"]);
  1353. };
  1354. // -----------------------------------------------------------------------
  1355. // min/max
  1356. // -----------------------------------------------------------------------
  1357. HEADER += "*{minWidth:none;maxWidth:none;min-width:none;max-width:none}";
  1358. // handle min-width property
  1359. layout.minWidth = function(element) {
  1360. // IE6 supports min-height so we frig it here
  1361. //#if (element.currentStyle.minHeight == "auto") element.runtimeStyle.minHeight = 0;
  1362. if (element.currentStyle["min-width"] != null) {
  1363. element.style.minWidth = element.currentStyle["min-width"];
  1364. }
  1365. if (register(arguments.callee, element, element.currentStyle.minWidth != "none")) {
  1366. layout.boxSizing(element);
  1367. fixWidth(element);
  1368. resizeWidth(element);
  1369. }
  1370. };
  1371. // clone the minWidth function to make a maxWidth function
  1372. eval("IE7.Layout.maxWidth=" + String(layout.minWidth).replace(/min/g, "max"));
  1373. // apply min/max restrictions
  1374. function resizeWidth(element) {
  1375. // check boundaries
  1376. var rect = element.getBoundingClientRect();
  1377. var width = rect.right - rect.left;
  1378. if (element.currentStyle.minWidth != "none" && width <= getFixedWidth(element, element.currentStyle.minWidth)) {
  1379. element.runtimeStyle.width = element.currentStyle.minWidth;
  1380. } else if (element.currentStyle.maxWidth != "none" && width >= getFixedWidth(element, element.currentStyle.maxWidth)) {
  1381. element.runtimeStyle.width = element.currentStyle.maxWidth;
  1382. } else {
  1383. element.runtimeStyle.width = element.runtimeStyle.fixedWidth; // || "auto";
  1384. }
  1385. };
  1386. // -----------------------------------------------------------------------
  1387. // right/bottom
  1388. // -----------------------------------------------------------------------
  1389. function fixRight(element) {
  1390. if (register(fixRight, element, /^(fixed|absolute)$/.test(element.currentStyle.position) &&
  1391. getDefinedStyle(element, "left") != "auto" &&
  1392. getDefinedStyle(element, "right") != "auto" &&
  1393. AUTO.test(getDefinedStyle(element, "width")))) {
  1394. resizeRight(element);
  1395. IE7.Layout.boxSizing(element);
  1396. }
  1397. };
  1398. IE7.Layout.fixRight = fixRight;
  1399. function resizeRight(element) {
  1400. var left = getPixelWidth(element, element.runtimeStyle._left || element.currentStyle.left);
  1401. var width = layoutWidth(element) - getPixelWidth(element, element.currentStyle.right) - left - getWidth(element, "margin");
  1402. if (parseInt(element.runtimeStyle.width) == width) return;
  1403. element.runtimeStyle.width = "";
  1404. if (isFixed(element) || HEIGHT || element.offsetWidth < width) {
  1405. if (!quirksMode) width -= getBorderWidth(element) + getWidth(element, "padding");
  1406. if (width < 0) width = 0;
  1407. element.runtimeStyle.fixedWidth = width;
  1408. setOverrideStyle(element, "width", width);
  1409. }
  1410. };
  1411. // -----------------------------------------------------------------------
  1412. // window.onresize
  1413. // -----------------------------------------------------------------------
  1414. // handle window resize
  1415. var clientWidth = 0;
  1416. addResize(function() {
  1417. if (!viewport) return;
  1418. var i, wider = (clientWidth < viewport.clientWidth);
  1419. clientWidth = viewport.clientWidth;
  1420. // resize elements with "min-width" set
  1421. var elements = layout.minWidth.elements;
  1422. for (i in elements) {
  1423. var element = elements[i];
  1424. var fixedWidth = (parseInt(element.runtimeStyle.width) == getFixedWidth(element, element.currentStyle.minWidth));
  1425. if (wider && fixedWidth) element.runtimeStyle.width = "";
  1426. if (wider == fixedWidth) resizeWidth(element);
  1427. }
  1428. // resize elements with "max-width" set
  1429. var elements = layout.maxWidth.elements;
  1430. for (i in elements) {
  1431. var element = elements[i];
  1432. var fixedWidth = (parseInt(element.runtimeStyle.width) == getFixedWidth(element, element.currentStyle.maxWidth));
  1433. if (!wider && fixedWidth) element.runtimeStyle.width = "";
  1434. if (wider != fixedWidth) resizeWidth(element);
  1435. }
  1436. // resize elements with "right" set
  1437. for (i in fixRight.elements) resizeRight(fixRight.elements[i]);
  1438. });
  1439. // -----------------------------------------------------------------------
  1440. // fix CSS
  1441. // -----------------------------------------------------------------------
  1442. if (quirksMode) {
  1443. IE7.CSS.addRecalc("width", NUMERIC, applyWidth);
  1444. }
  1445. if (appVersion < 7) {
  1446. IE7.CSS.addRecalc("min-width", NUMERIC, layout.minWidth);
  1447. IE7.CSS.addRecalc("max-width", NUMERIC, layout.maxWidth);
  1448. IE7.CSS.addRecalc("right", NUMERIC, fixRight);
  1449. }
  1450. };
  1451. eval("var fixHeight=" + rotate(fixWidth));
  1452. // apply box-model + min/max fixes
  1453. fixWidth();
  1454. fixHeight(true);
  1455. };
  1456. // =========================================================================
  1457. // ie7-graphics.js
  1458. // =========================================================================
  1459. // a small transparent image used as a placeholder
  1460. var BLANK_GIF = makePath("blank.gif", path);
  1461. var ALPHA_IMAGE_LOADER = "DXImageTransform.Microsoft.AlphaImageLoader";
  1462. var PNG_FILTER = "progid:" + ALPHA_IMAGE_LOADER + "(src='%1',sizingMethod='%2')";
  1463. // regular expression version of the above
  1464. var PNG;
  1465. var filtered = [];
  1466. function fixImage(element) {
  1467. if (PNG.test(element.src)) {
  1468. // we have to preserve width and height
  1469. var image = new Image(element.width, element.height);
  1470. image.onload = function() {
  1471. element.width = image.width;
  1472. element.height = image.height;
  1473. image = null;
  1474. };
  1475. image.src = element.src;
  1476. // store the original url (we'll put it back when it's printed)
  1477. element.pngSrc = element.src;
  1478. // add the AlphaImageLoader thingy
  1479. addFilter(element);
  1480. }
  1481. };
  1482. if (appVersion >= 5.5 && appVersion < 7) {
  1483. // ** IE7 VARIABLE
  1484. // e.g. only apply the hack to files ending in ".png"
  1485. // IE7_PNG_SUFFIX = ".png";
  1486. // replace background(-image): url(..) .. with background(-image): .. ;filter: ..;
  1487. IE7.CSS.addFix(/background(-image)?\s*:\s*([^};]*)?url\(([^\)]+)\)([^;}]*)?/, function(match, $1, $2, url, $4) {
  1488. url = getString(url);
  1489. return PNG.test(url) ? "filter:" + format(PNG_FILTER, url, "crop") +
  1490. ";zoom:1;background" + ($1||"") + ":" + ($2||"") + "none" + ($4||"") : match;
  1491. });
  1492. // -----------------------------------------------------------------------
  1493. // fix PNG transparency (HTML images)
  1494. // -----------------------------------------------------------------------
  1495. IE7.HTML.addRecalc("img,input", function(element) {
  1496. if (element.tagName == "INPUT" && element.type != "image") return;
  1497. fixImage(element);
  1498. addEventHandler(element, "onpropertychange", function() {
  1499. if (!printing && event.propertyName == "src" &&
  1500. element.src.indexOf(BLANK_GIF) == -1) fixImage(element);
  1501. });
  1502. });
  1503. // assume that background images should not be printed
  1504. // (if they are not transparent then they'll just obscure content)
  1505. // but we'll put foreground images back...
  1506. var printing = false;
  1507. addEventHandler(window, "onbeforeprint", function() {
  1508. printing = true;
  1509. for (var i = 0; i < filtered.length; i++) removeFilter(filtered[i]);
  1510. });
  1511. addEventHandler(window, "onafterprint", function() {
  1512. for (var i = 0; i < filtered.length; i++) addFilter(filtered[i]);
  1513. printing = false;
  1514. });
  1515. }
  1516. // apply a filter
  1517. function addFilter(element, sizingMethod) {
  1518. var filter = element.filters[ALPHA_IMAGE_LOADER];
  1519. if (filter) {
  1520. filter.src = element.src;
  1521. filter.enabled = true;
  1522. } else {
  1523. element.runtimeStyle.filter = format(PNG_FILTER, element.src, sizingMethod || "scale");
  1524. filtered.push(element);
  1525. }
  1526. // remove the real image
  1527. element.src = BLANK_GIF;
  1528. };
  1529. function removeFilter(element) {
  1530. element.src = element.pngSrc;
  1531. element.filters[ALPHA_IMAGE_LOADER].enabled = false;
  1532. };
  1533. // =========================================================================
  1534. // ie7-fixed.js
  1535. // =========================================================================
  1536. new function(_) {
  1537. if (appVersion >= 7) return;
  1538. // some things to consider for this hack.
  1539. // the document body requires a fixed background. even if
  1540. // it is just a blank image.
  1541. // you have to use setExpression instead of onscroll, this
  1542. // together with a fixed body background helps avoid the
  1543. // annoying screen flicker of other solutions.
  1544. IE7.CSS.addRecalc("position", "fixed", _positionFixed, "absolute");
  1545. IE7.CSS.addRecalc("background(-attachment)?", "[^};]*fixed", _backgroundFixed);
  1546. // scrolling is relative to the documentElement (HTML tag) when in
  1547. // standards mode, otherwise it's relative to the document body
  1548. var $viewport = quirksMode ? "body" : "documentElement";
  1549. function _fixBackground() {
  1550. // this is required by both position:fixed and background-attachment:fixed.
  1551. // it is necessary for the document to also have a fixed background image.
  1552. // we can fake this with a blank image if necessary
  1553. if (body.currentStyle.backgroundAttachment != "fixed") {
  1554. if (body.currentStyle.backgroundImage == "none") {
  1555. body.runtimeStyle.backgroundRepeat = "no-repeat";
  1556. body.runtimeStyle.backgroundImage = "url(" + BLANK_GIF + ")"; // dummy
  1557. }
  1558. body.runtimeStyle.backgroundAttachment = "fixed";
  1559. }
  1560. _fixBackground = Undefined;
  1561. };
  1562. var _tmp = createTempElement("img");
  1563. function _isFixed(element) {
  1564. return element ? isFixed(element) || _isFixed(element.parentElement) : false;
  1565. };
  1566. function _setExpression(element, propertyName, expression) {
  1567. setTimeout("document.all." + element.uniqueID + ".runtimeStyle.setExpression('" + propertyName + "','" + expression + "')", 0);
  1568. };
  1569. // -----------------------------------------------------------------------
  1570. // backgroundAttachment: fixed
  1571. // -----------------------------------------------------------------------
  1572. function _backgroundFixed(element) {
  1573. if (register(_backgroundFixed, element, element.currentStyle.backgroundAttachment == "fixed" && !element.contains(body))) {
  1574. _fixBackground();
  1575. bgLeft(element);
  1576. bgTop(element);
  1577. _backgroundPosition(element);
  1578. }
  1579. };
  1580. function _backgroundPosition(element) {
  1581. _tmp.src = element.currentStyle.backgroundImage.slice(5, -2);
  1582. var parentElement = element.canHaveChildren ? element : element.parentElement;
  1583. parentElement.appendChild(_tmp);
  1584. setOffsetLeft(element);
  1585. setOffsetTop(element);
  1586. parentElement.removeChild(_tmp);
  1587. };
  1588. function bgLeft(element) {
  1589. element.style.backgroundPositionX = element.currentStyle.backgroundPositionX;
  1590. if (!_isFixed(element)) {
  1591. _setExpression(element, "backgroundPositionX", "(parseInt(runtimeStyle.offsetLeft)+document." + $viewport + ".scrollLeft)||0");
  1592. }
  1593. };
  1594. eval(rotate(bgLeft));
  1595. function setOffsetLeft(element) {
  1596. var propertyName = _isFixed(element) ? "backgroundPositionX" : "offsetLeft";
  1597. element.runtimeStyle[propertyName] =
  1598. getOffsetLeft(element, element.style.backgroundPositionX) -
  1599. element.getBoundingClientRect().left - element.clientLeft + 2;
  1600. };
  1601. eval(rotate(setOffsetLeft));
  1602. function getOffsetLeft(element, position) {
  1603. switch (position) {
  1604. case "left":
  1605. case "top":
  1606. return 0;
  1607. case "right":
  1608. case "bottom":
  1609. return viewport.clientWidth - _tmp.offsetWidth;
  1610. case "center":
  1611. return (viewport.clientWidth - _tmp.offsetWidth) / 2;
  1612. default:
  1613. if (PERCENT.test(position)) {
  1614. return parseInt((viewport.clientWidth - _tmp.offsetWidth) * parseFloat(position) / 100);
  1615. }
  1616. _tmp.style.left = position;
  1617. return _tmp.offsetLeft;
  1618. }
  1619. };
  1620. eval(rotate(getOffsetLeft));
  1621. // -----------------------------------------------------------------------
  1622. // position: fixed
  1623. // -----------------------------------------------------------------------
  1624. function _positionFixed(element) {
  1625. if (register(_positionFixed, element, isFixed(element))) {
  1626. setOverrideStyle(element, "position", "absolute");
  1627. setOverrideStyle(element, "left", element.currentStyle.left);
  1628. setOverrideStyle(element, "top", element.currentStyle.top);
  1629. _fixBackground();
  1630. IE7.Layout.fixRight(element);
  1631. _foregroundPosition(element);
  1632. }
  1633. };
  1634. function _foregroundPosition(element, recalc) {
  1635. positionTop(element, recalc);
  1636. positionLeft(element, recalc, true);
  1637. if (!element.runtimeStyle.autoLeft && element.currentStyle.marginLeft == "auto" &&
  1638. element.currentStyle.right != "auto") {
  1639. var left = viewport.clientWidth - getPixelWidth(element, element.currentStyle.right) -
  1640. getPixelWidth(element, element.runtimeStyle._left) - element.clientWidth;
  1641. if (element.currentStyle.marginRight == "auto") left = parseInt(left / 2);
  1642. if (_isFixed(element.offsetParent)) element.runtimeStyle.pixelLeft += left;
  1643. else element.runtimeStyle.shiftLeft = left;
  1644. }
  1645. clipWidth(element);
  1646. clipHeight(element);
  1647. };
  1648. function clipWidth(element) {
  1649. var fixWidth = element.runtimeStyle.fixWidth;
  1650. element.runtimeStyle.borderRightWidth = "";
  1651. element.runtimeStyle.width = fixWidth ? getPixelWidth(element, fixWidth) : "";
  1652. if (element.currentStyle.width != "auto") {
  1653. var rect = element.getBoundingClientRect();
  1654. var width = element.offsetWidth - viewport.clientWidth + rect.left - 2;
  1655. if (width >= 0) {
  1656. element.runtimeStyle.borderRightWidth = "0px";
  1657. width = Math.max(getPixelValue(element, element.currentStyle.width) - width, 0);
  1658. setOverrideStyle(element, "width", width);
  1659. return width;
  1660. }
  1661. }
  1662. };
  1663. eval(rotate(clipWidth));
  1664. function positionLeft(element, recalc) {
  1665. // if the element's width is in % units then it must be recalculated
  1666. // with respect to the viewport
  1667. if (!recalc && PERCENT.test(element.currentStyle.width)) {
  1668. element.runtimeStyle.fixWidth = element.currentStyle.width;
  1669. }
  1670. if (element.runtimeStyle.fixWidth) {
  1671. element.runtimeStyle.width = getPixelWidth(element, element.runtimeStyle.fixWidth);
  1672. }
  1673. //if (recalc) {
  1674. // // if the element is fixed on the right then no need to recalculate
  1675. // if (!element.runtimeStyle.autoLeft) return;
  1676. //} else {
  1677. element.runtimeStyle.shiftLeft = 0;
  1678. element.runtimeStyle._left = element.currentStyle.left;
  1679. // is the element fixed on the right?
  1680. element.runtimeStyle.autoLeft = element.currentStyle.right != "auto" &&
  1681. element.currentStyle.left == "auto";
  1682. //}
  1683. // reset the element's "left" value and get it's natural position
  1684. element.runtimeStyle.left = "";
  1685. element.runtimeStyle.screenLeft = getScreenLeft(element);
  1686. element.runtimeStyle.pixelLeft = element.runtimeStyle.screenLeft;
  1687. // if the element is contained by another fixed element then there is no need to
  1688. // continually recalculate it's left position
  1689. if (!recalc && !_isFixed(element.offsetParent)) {
  1690. // onsrcoll produces jerky movement, so we use an expression
  1691. _setExpression(element, "pixelLeft", "runtimeStyle.screenLeft+runtimeStyle.shiftLeft+document." + $viewport + ".scrollLeft");
  1692. }
  1693. };
  1694. // clone this function so we can do "top"
  1695. eval(rotate(positionLeft));
  1696. // I've forgotten how this works...
  1697. function getScreenLeft(element) { // thanks to kevin newman (captainn)
  1698. var screenLeft = element.offsetLeft, nested = 1;
  1699. if (element.runtimeStyle.autoLeft) {
  1700. screenLeft = viewport.clientWidth - element.offsetWidth - getPixelWidth(element, element.currentStyle.right);
  1701. }
  1702. // accommodate margins
  1703. if (element.currentStyle.marginLeft != "auto") {
  1704. screenLeft -= getPixelWidth(element, element.currentStyle.marginLeft);
  1705. }
  1706. while (element = element.offsetParent) {
  1707. if (element.currentStyle.position != "static") nested = -1;
  1708. screenLeft += element.offsetLeft * nested;
  1709. }
  1710. return screenLeft;
  1711. };
  1712. eval(rotate(getScreenLeft));
  1713. function getPixelWidth(element, value) {
  1714. return PERCENT.test(value) ? parseInt(parseFloat(value) / 100 * viewport.clientWidth) : getPixelValue(element, value);
  1715. };
  1716. eval(rotate(getPixelWidth));
  1717. // -----------------------------------------------------------------------
  1718. // capture window resize
  1719. // -----------------------------------------------------------------------
  1720. function _resize() {
  1721. // if the window has been resized then some positions need to be
  1722. // recalculated (especially those aligned to "right" or "top"
  1723. var elements = _backgroundFixed.elements;
  1724. for (var i in elements) _backgroundPosition(elements[i]);
  1725. elements = _positionFixed.elements;
  1726. for (i in elements) {
  1727. _foregroundPosition(elements[i], true);
  1728. // do this twice to be sure - hackish, I know :-)
  1729. _foregroundPosition(elements[i], true);
  1730. }
  1731. _timer = 0;
  1732. };
  1733. // use a timer for some reason.
  1734. // (sometimes this is a good way to prevent resize loops)
  1735. var _timer;
  1736. addResize(function() {
  1737. if (!_timer) _timer = setTimeout(_resize, 0);
  1738. });
  1739. };
  1740. // =========================================================================
  1741. // ie7-oveflow.js
  1742. // =========================================================================
  1743. /* ---------------------------------------------------------------------
  1744. This module alters the structure of the document.
  1745. It may adversely affect other CSS rules. Be warned.
  1746. --------------------------------------------------------------------- */
  1747. var WRAPPER_STYLE = {
  1748. backgroundColor: "transparent",
  1749. backgroundImage: "none",
  1750. backgroundPositionX: null,
  1751. backgroundPositionY: null,
  1752. backgroundRepeat: null,
  1753. borderTopWidth: 0,
  1754. borderRightWidth: 0,
  1755. borderBottomWidth: 0,
  1756. borderLeftStyle: "none",
  1757. borderTopStyle: "none",
  1758. borderRightStyle: "none",
  1759. borderBottomStyle: "none",
  1760. borderLeftWidth: 0,
  1761. height: null,
  1762. marginTop: 0,
  1763. marginBottom: 0,
  1764. marginRight: 0,
  1765. marginLeft: 0,
  1766. width: "100%"
  1767. };
  1768. IE7.CSS.addRecalc("overflow", "visible", function(element) {
  1769. // don't do this again
  1770. if (element.parentNode.ie7_wrapped) return;
  1771. // if max-height is applied, makes sure it gets applied first
  1772. if (IE7.Layout && element.currentStyle["max-height"] != "auto") {
  1773. IE7.Layout.maxHeight(element);
  1774. }
  1775. if (element.currentStyle.marginLeft == "auto") element.style.marginLeft = 0;
  1776. if (element.currentStyle.marginRight == "auto") element.style.marginRight = 0;
  1777. var wrapper = document.createElement(ANON);
  1778. wrapper.ie7_wrapped = element;
  1779. for (var propertyName in WRAPPER_STYLE) {
  1780. wrapper.style[propertyName] = element.currentStyle[propertyName];
  1781. if (WRAPPER_STYLE[propertyName] != null) {
  1782. element.runtimeStyle[propertyName] = WRAPPER_STYLE[propertyName];
  1783. }
  1784. }
  1785. wrapper.style.display = "block";
  1786. wrapper.style.position = "relative";
  1787. element.runtimeStyle.position = "absolute";
  1788. element.parentNode.insertBefore(wrapper, element);
  1789. wrapper.appendChild(element);
  1790. });
  1791. // =========================================================================
  1792. // ie7-quirks.js
  1793. // =========================================================================
  1794. function ie7Quirks() {
  1795. var FONT_SIZES = "xx-small,x-small,small,medium,large,x-large,xx-large".split(",");
  1796. for (var i = 0; i < FONT_SIZES.length; i++) {
  1797. FONT_SIZES[FONT_SIZES[i]] = FONT_SIZES[i - 1] || "0.67em";
  1798. }
  1799. IE7.CSS.addFix(/(font(-size)?\s*:\s*)([\w.-]+)/, function(match, label, size, value) {
  1800. return label + (FONT_SIZES[value] || value);
  1801. });
  1802. if (appVersion < 6) {
  1803. var NEGATIVE = /^\-/, LENGTH = /(em|ex)$/i;
  1804. var EM = /em$/i, EX = /ex$/i;
  1805. getPixelValue = function(element, value) {
  1806. if (PIXEL.test(value)) return parseInt(value)||0;
  1807. var scale = NEGATIVE.test(value)? -1 : 1;
  1808. if (LENGTH.test(value)) scale *= getFontScale(element);
  1809. temp.style.width = (scale < 0) ? value.slice(1) : value;
  1810. body.appendChild(temp);
  1811. // retrieve pixel width
  1812. value = scale * temp.offsetWidth;
  1813. // remove the temporary element
  1814. temp.removeNode();
  1815. return parseInt(value);
  1816. };
  1817. var temp = createTempElement();
  1818. function getFontScale(element) {
  1819. var scale = 1;
  1820. temp.style.fontFamily = element.currentStyle.fontFamily;
  1821. temp.style.lineHeight = element.currentStyle.lineHeight;
  1822. //temp.style.fontSize = "";
  1823. while (element != body) {
  1824. var fontSize = element.currentStyle["ie7-font-size"];
  1825. if (fontSize) {
  1826. if (EM.test(fontSize)) scale *= parseFloat(fontSize);
  1827. else if (PERCENT.test(fontSize)) scale *= (parseFloat(fontSize) / 100);
  1828. else if (EX.test(fontSize)) scale *= (parseFloat(fontSize) / 2);
  1829. else {
  1830. temp.style.fontSize = fontSize;
  1831. return 1;
  1832. }
  1833. }
  1834. element = element.parentElement;
  1835. }
  1836. return scale;
  1837. };
  1838. // cursor:pointer (IE5.x)
  1839. IE7.CSS.addFix(/cursor\s*:\s*pointer/, "cursor:hand");
  1840. // display:list-item (IE5.x)
  1841. IE7.CSS.addFix(/display\s*:\s*list-item/, "display:block");
  1842. }
  1843. // -----------------------------------------------------------------------
  1844. // margin:auto
  1845. // -----------------------------------------------------------------------
  1846. function fixMargin(element) {
  1847. if (appVersion < 5.5) IE7.Layout.boxSizing(element.parentElement);
  1848. var parent = element.parentElement;
  1849. var margin = parent.offsetWidth - element.offsetWidth - getPaddingWidth(parent);
  1850. var autoRight = (element.currentStyle["ie7-margin"] && element.currentStyle.marginRight == "auto") ||
  1851. element.currentStyle["ie7-margin-right"] == "auto";
  1852. switch (parent.currentStyle.textAlign) {
  1853. case "right":
  1854. margin = autoRight ? parseInt(margin / 2) : 0;
  1855. element.runtimeStyle.marginRight = margin + "px";
  1856. break;
  1857. case "center":
  1858. if (autoRight) margin = 0;
  1859. default:
  1860. if (autoRight) margin /= 2;
  1861. element.runtimeStyle.marginLeft = parseInt(margin) + "px";
  1862. }
  1863. };
  1864. function getPaddingWidth(element) {
  1865. return getPixelValue(element, element.currentStyle.paddingLeft) +
  1866. getPixelValue(element, element.currentStyle.paddingRight);
  1867. };
  1868. IE7.CSS.addRecalc("margin(-left|-right)?", "[^};]*auto", function(element) {
  1869. if (register(fixMargin, element,
  1870. element.parentElement &&
  1871. element.currentStyle.display == "block" &&
  1872. element.currentStyle.marginLeft == "auto" &&
  1873. element.currentStyle.position != "absolute")) {
  1874. fixMargin(element);
  1875. }
  1876. });
  1877. addResize(function() {
  1878. for (var i in fixMargin.elements) {
  1879. var element = fixMargin.elements[i];
  1880. element.runtimeStyle.marginLeft =
  1881. element.runtimeStyle.marginRight = "";
  1882. fixMargin(element);
  1883. }
  1884. });
  1885. };
  1886. // =========================================================================
  1887. // ie8-cssQuery.js
  1888. // =========================================================================
  1889. IE7._isEmpty = function(element) {
  1890. element = element.firstChild;
  1891. while (element) {
  1892. if (element.nodeType == 3 || (element.nodeType == 1 && element.nodeName != "!")) return false;
  1893. element = element.nextSibling;
  1894. }
  1895. return true;
  1896. };
  1897. IE7._isLang = function(element, code) {
  1898. while (element && !element.getAttribute("lang")) element = element.parentNode;
  1899. return element && new RegExp("^" + rescape(code), "i").test(element.getAttribute("lang"));
  1900. };
  1901. function _nthChild(match, args, position, last) {
  1902. // ugly but it works...
  1903. last = /last/i.test(match) ? last + "+1-" : "";
  1904. if (!isNaN(args)) args = "0n+" + args;
  1905. else if (args == "even") args = "2n";
  1906. else if (args == "odd") args = "2n+1";
  1907. args = args.split("n");
  1908. var a = args[0] ? (args[0] == "-") ? -1 : parseInt(args[0]) : 1;
  1909. var b = parseInt(args[1]) || 0;
  1910. var negate = a < 0;
  1911. if (negate) {
  1912. a = -a;
  1913. if (a == 1) b++;
  1914. }
  1915. var query = format(a == 0 ? "%3%7" + (last + b) : "(%4%3-%2)%6%1%70%5%4%3>=%2", a, b, position, last, "&&", "%", "==");
  1916. if (negate) query = "!(" + query + ")";
  1917. return query;
  1918. };
  1919. _PSEUDO_CLASSES = {
  1920. "link": "e%1.currentStyle['ie7-link']=='link'",
  1921. "visited": "e%1.currentStyle['ie7-link']=='visited'",
  1922. "checked": "e%1.checked",
  1923. "contains": "e%1.innerText.indexOf('%2')!=-1",
  1924. "disabled": "e%1.isDisabled",
  1925. "empty": "IE7._isEmpty(e%1)",
  1926. "enabled": "e%1.disabled===false",
  1927. "first-child": "!IE7._getPreviousElementSibling(e%1)",
  1928. "lang": "IE7._isLang(e%1,'%2')",
  1929. "last-child": "!IE7._getNextElementSibling(e%1)",
  1930. "only-child": "!IE7._getPreviousElementSibling(e%1)&&!IE7._getNextElementSibling(e%1)",
  1931. "target": "e%1.id==location.hash.slice(1)",
  1932. "indeterminate": "e%1.indeterminate"
  1933. };
  1934. // register a node and index its children
  1935. IE7._register = function(element) {
  1936. if (element.rows) {
  1937. element.ie7_length = element.rows.length;
  1938. element.ie7_lookup = "rowIndex";
  1939. } else if (element.cells) {
  1940. element.ie7_length = element.cells.length;
  1941. element.ie7_lookup = "cellIndex";
  1942. } else if (element.ie7_indexed != IE7._indexed) {
  1943. var index = 0;
  1944. var child = element.firstChild;
  1945. while (child) {
  1946. if (child.nodeType == 1 && child.nodeName != "!") {
  1947. child.ie7_index = ++index;
  1948. }
  1949. child = child.nextSibling;
  1950. }
  1951. element.ie7_length = index;
  1952. element.ie7_lookup = "ie7_index";
  1953. }
  1954. element.ie7_indexed = IE7._indexed;
  1955. return element;
  1956. };
  1957. var keys = cssParser[_KEYS];
  1958. var pseudoClass = keys[keys.length - 1];
  1959. keys.length--;
  1960. cssParser.merge({
  1961. ":not\\((\\*|[\\w-]+)?([^)]*)\\)": function(match, tagName, filters) { // :not pseudo class
  1962. var replacement = (tagName && tagName != "*") ? format("if(e%1.nodeName=='%2'){", _index, tagName.toUpperCase()) : "";
  1963. replacement += cssParser.exec(filters);
  1964. return "if(!" + replacement.slice(2, -1).replace(/\)\{if\(/g, "&&") + "){";
  1965. },
  1966. ":nth(-last)?-child\\(([^)]+)\\)": function(match, last, args) { // :nth-child pseudo classes
  1967. _wild = false;
  1968. last = format("e%1.parentNode.ie7_length", _index);
  1969. var replacement = "if(p%1!==e%1.parentNode)p%1=IE7._register(e%1.parentNode);";
  1970. replacement += "var i=e%1[p%1.ie7_lookup];if(p%1.ie7_lookup!='ie7_index')i++;if(";
  1971. return format(replacement, _index) + _nthChild(match, args, "i", last) + "){";
  1972. }
  1973. });
  1974. keys.push(pseudoClass);
  1975. // =========================================================================
  1976. // ie8-css.js
  1977. // =========================================================================
  1978. var BRACKETS = "\\([^)]*\\)";
  1979. if (IE7.CSS.pseudoClasses) IE7.CSS.pseudoClasses += "|";
  1980. IE7.CSS.pseudoClasses += "before|after|last\\-child|only\\-child|empty|root|" +
  1981. "not|nth\\-child|nth\\-last\\-child|contains|lang".split("|").join(BRACKETS + "|") + BRACKETS;
  1982. // pseudo-elements can be declared with a double colon
  1983. encoder.add(/::/, ":");
  1984. // -----------------------------------------------------------------------
  1985. // dynamic pseudo-classes
  1986. // -----------------------------------------------------------------------
  1987. var Focus = new DynamicPseudoClass("focus", function(element) {
  1988. var instance = arguments;
  1989. IE7.CSS.addEventHandler(element, "onfocus", function() {
  1990. Focus.unregister(instance); // in case it starts with focus
  1991. Focus.register(instance);
  1992. });
  1993. IE7.CSS.addEventHandler(element, "onblur", function() {
  1994. Focus.unregister(instance);
  1995. });
  1996. // check the active element for initial state
  1997. if (element == document.activeElement) {
  1998. Focus.register(instance)
  1999. }
  2000. });
  2001. var Active = new DynamicPseudoClass("active", function(element) {
  2002. var instance = arguments;
  2003. IE7.CSS.addEventHandler(element, "onmousedown", function() {
  2004. Active.register(instance);
  2005. });
  2006. });
  2007. // globally trap the mouseup event (thanks Martijn!)
  2008. addEventHandler(document, "onmouseup", function() {
  2009. var instances = Active.instances;
  2010. for (var i in instances) Active.unregister(instances[i]);
  2011. });
  2012. // :checked
  2013. var Checked = new DynamicPseudoClass("checked", function(element) {
  2014. if (typeof element.checked != "boolean") return;
  2015. var instance = arguments;
  2016. IE7.CSS.addEventHandler(element, "onpropertychange", function() {
  2017. if (event.propertyName == "checked") {
  2018. if (element.checked) Checked.register(instance);
  2019. else Checked.unregister(instance);
  2020. }
  2021. });
  2022. // check current checked state
  2023. if (element.checked) Checked.register(instance);
  2024. });
  2025. // :enabled
  2026. var Enabled = new DynamicPseudoClass("enabled", function(element) {
  2027. if (typeof element.disabled != "boolean") return;
  2028. var instance = arguments;
  2029. IE7.CSS.addEventHandler(element, "onpropertychange", function() {
  2030. if (event.propertyName == "disabled") {
  2031. if (!element.isDisabled) Enabled.register(instance);
  2032. else Enabled.unregister(instance);
  2033. }
  2034. });
  2035. // check current disabled state
  2036. if (!element.isDisabled) Enabled.register(instance);
  2037. });
  2038. // :disabled
  2039. var Disabled = new DynamicPseudoClass("disabled", function(element) {
  2040. if (typeof element.disabled != "boolean") return;
  2041. var instance = arguments;
  2042. IE7.CSS.addEventHandler(element, "onpropertychange", function() {
  2043. if (event.propertyName == "disabled") {
  2044. if (element.isDisabled) Disabled.register(instance);
  2045. else Disabled.unregister(instance);
  2046. }
  2047. });
  2048. // check current disabled state
  2049. if (element.isDisabled) Disabled.register(instance);
  2050. });
  2051. // :indeterminate (Kevin Newman)
  2052. var Indeterminate = new DynamicPseudoClass("indeterminate", function(element) {
  2053. if (typeof element.indeterminate != "boolean") return;
  2054. var instance = arguments;
  2055. IE7.CSS.addEventHandler(element, "onpropertychange", function() {
  2056. if (event.propertyName == "indeterminate") {
  2057. if (element.indeterminate) Indeterminate.register(instance);
  2058. else Indeterminate.unregister(instance);
  2059. }
  2060. });
  2061. IE7.CSS.addEventHandler(element, "onclick", function() {
  2062. Indeterminate.unregister(instance);
  2063. });
  2064. // clever Kev says no need to check this up front
  2065. });
  2066. // :target
  2067. var Target = new DynamicPseudoClass("target", function(element) {
  2068. var instance = arguments;
  2069. // if an element has a tabIndex then it can become "active".
  2070. // The default is zero anyway but it works...
  2071. if (!element.tabIndex) element.tabIndex = 0;
  2072. // this doesn't detect the back button. I don't know how to do that :-(
  2073. IE7.CSS.addEventHandler(document, "onpropertychange", function() {
  2074. if (event.propertyName == "activeElement") {
  2075. if (element.id && element.id == location.hash.slice(1)) Target.register(instance);
  2076. else Target.unregister(instance);
  2077. }
  2078. });
  2079. // check the current location
  2080. if (element.id && element.id == location.hash.slice(1)) Target.register(instance);
  2081. });
  2082. // -----------------------------------------------------------------------
  2083. // IE7 pseudo elements
  2084. // -----------------------------------------------------------------------
  2085. // constants
  2086. var ATTR = /^attr/;
  2087. var URL = /^url\s*\(\s*([^)]*)\)$/;
  2088. var POSITION_MAP = {
  2089. before0: "beforeBegin",
  2090. before1: "afterBegin",
  2091. after0: "afterEnd",
  2092. after1: "beforeEnd"
  2093. };
  2094. var PseudoElement = IE7.PseudoElement = Rule.extend({
  2095. constructor: function(selector, position, cssText) {
  2096. // initialise object properties
  2097. this.position = position;
  2098. var content = cssText.match(PseudoElement.CONTENT), match, entity;
  2099. if (content) {
  2100. content = content[1];
  2101. match = content.split(/\s+/);
  2102. for (var i = 0; (entity = match[i]); i++) {
  2103. match[i] = ATTR.test(entity) ? {attr: entity.slice(5, -1)} :
  2104. (entity.charAt(0) == "'") ? getString(entity) : decode(entity);
  2105. }
  2106. content = match;
  2107. }
  2108. this.content = content;
  2109. // CSS text needs to be decoded immediately
  2110. this.base(selector, decode(cssText));
  2111. },
  2112. init: function() {
  2113. // execute the underlying css query for this class
  2114. this.match = cssQuery(this.selector);
  2115. for (var i = 0; i < this.match.length; i++) {
  2116. var runtimeStyle = this.match[i].runtimeStyle;
  2117. if (!runtimeStyle[this.position]) runtimeStyle[this.position] = {cssText:""};
  2118. runtimeStyle[this.position].cssText += ";" + this.cssText;
  2119. if (this.content != null) runtimeStyle[this.position].content = this.content;
  2120. }
  2121. },
  2122. create: function(target) {
  2123. var generated = target.runtimeStyle[this.position];
  2124. if (generated) {
  2125. // copy the array of values
  2126. var content = [].concat(generated.content || "");
  2127. for (var j = 0; j < content.length; j++) {
  2128. if (typeof content[j] == "object") {
  2129. content[j] = target.getAttribute(content[j].attr);
  2130. }
  2131. }
  2132. content = content.join("");
  2133. var url = content.match(URL);
  2134. var cssText = "overflow:hidden;" + generated.cssText.replace(/'/g, '"');
  2135. if (target.currentStyle.styleFloat != "none") {
  2136. //cssText = cssText.replace(/display\s*:\s*block/, "display:inline-block");
  2137. }
  2138. var position = POSITION_MAP[this.position + Number(target.canHaveChildren)];
  2139. var id = 'ie7_pseudo' + PseudoElement.count++;
  2140. target.insertAdjacentHTML(position, format(PseudoElement.ANON, this.className, id, cssText, url ? "" : content));
  2141. if (url) {
  2142. var pseudoElement = document.getElementById(id);
  2143. pseudoElement.src = getString(url[1]);
  2144. addFilter(pseudoElement, "crop");
  2145. }
  2146. target.runtimeStyle[this.position] = null;
  2147. }
  2148. },
  2149. recalc: function() {
  2150. if (this.content == null) return;
  2151. for (var i = 0; i < this.match.length; i++) {
  2152. this.create(this.match[i]);
  2153. }
  2154. },
  2155. toString: function() {
  2156. return "." + this.className + "{display:inline}";
  2157. }
  2158. }, {
  2159. CONTENT: /content\s*:\s*([^;]*)(;|$)/,
  2160. ANON: "<ie7:! class='ie7_anon %1' id=%2 style='%3'>%4</ie7:!>",
  2161. MATCH: /(.*):(before|after).*/,
  2162. count: 0
  2163. });
  2164. // =========================================================================
  2165. // ie8-html.js
  2166. // =========================================================================
  2167. var UNSUCCESSFUL = /^(submit|reset|button)$/;
  2168. // -----------------------------------------------------------------------
  2169. // <button>
  2170. // -----------------------------------------------------------------------
  2171. // IE bug means that innerText is submitted instead of "value"
  2172. IE7.HTML.addRecalc("button,input", function(button) {
  2173. if (button.tagName == "BUTTON") {
  2174. var match = button.outerHTML.match(/ value="([^"]*)"/i);
  2175. button.runtimeStyle.value = (match) ? match[1] : "";
  2176. }
  2177. // flag the button/input that was used to submit the form
  2178. if (button.type == "submit") {
  2179. addEventHandler(button, "onclick", function() {
  2180. button.runtimeStyle.clicked = true;
  2181. setTimeout("document.all." + button.uniqueID + ".runtimeStyle.clicked=false", 1);
  2182. });
  2183. }
  2184. });
  2185. // -----------------------------------------------------------------------
  2186. // <form>
  2187. // -----------------------------------------------------------------------
  2188. // only submit "successful controls
  2189. IE7.HTML.addRecalc("form", function(form) {
  2190. addEventHandler(form, "onsubmit", function() {
  2191. for (var element, i = 0; element = form[i]; i++) {
  2192. if (UNSUCCESSFUL.test(element.type) && !element.disabled && !element.runtimeStyle.clicked) {
  2193. element.disabled = true;
  2194. setTimeout("document.all." + element.uniqueID + ".disabled=false", 1);
  2195. } else if (element.tagName == "BUTTON" && element.type == "submit") {
  2196. setTimeout("document.all." + element.uniqueID + ".value='" +
  2197. element.value + "'", 1);
  2198. element.value = element.runtimeStyle.value;
  2199. }
  2200. }
  2201. });
  2202. });
  2203. // -----------------------------------------------------------------------
  2204. // <img>
  2205. // -----------------------------------------------------------------------
  2206. // get rid of the spurious tooltip produced by the alt attribute on images
  2207. IE7.HTML.addRecalc("img", function(img) {
  2208. if (img.alt && !img.title) img.title = "";
  2209. });
  2210. // =========================================================================
  2211. // ie8-layout.js
  2212. // =========================================================================
  2213. IE7.CSS.addRecalc("border-spacing", NUMERIC, function(element) {
  2214. if (element.currentStyle.borderCollapse != "collapse") {
  2215. element.cellSpacing = getPixelValue(element, element.currentStyle["border-spacing"]);
  2216. }
  2217. });
  2218. IE7.CSS.addRecalc("box-sizing", "content-box", IE7.Layout.boxSizing);
  2219. IE7.CSS.addRecalc("box-sizing", "border-box", IE7.Layout.borderBox);
  2220. // =========================================================================
  2221. // ie8-graphics.js
  2222. // =========================================================================
  2223. IE7.CSS.addFix(/opacity\s*:\s*([\d.]+)/, function(match, value) {
  2224. return "zoom:1;filter:Alpha(opacity=" + ((value * 100) || 1) + ")";
  2225. });
  2226. // fix object[type=image/*]
  2227. var IMAGE = /^image/i;
  2228. IE7.HTML.addRecalc("object", function(element) {
  2229. if (IMAGE.test(element.type)) {
  2230. element.body.style.cssText = "margin:0;padding:0;border:none;overflow:hidden";
  2231. return element;
  2232. }
  2233. });
  2234. // -----------------------------------------------------------------------
  2235. // initialisation
  2236. // -----------------------------------------------------------------------
  2237. IE7.loaded = true;
  2238. (function() {
  2239. try {
  2240. // http://javascript.nwbox.com/IEContentLoaded/
  2241. documentElement.doScroll("left");
  2242. } catch (e) {
  2243. setTimeout(arguments.callee, 1);
  2244. return;
  2245. }
  2246. // execute the inner text of the IE7 script
  2247. try {
  2248. eval(script.innerHTML);
  2249. } catch (e) {
  2250. // ignore errors
  2251. }
  2252. PNG = new RegExp(rescape(typeof IE7_PNG_SUFFIX == "string" ? IE7_PNG_SUFFIX : "-trans.png") + "$", "i");
  2253. // frequently used references
  2254. body = document.body;
  2255. viewport = quirksMode ? body : documentElement;
  2256. // classes
  2257. body.className += " ie7_body";
  2258. documentElement.className += " ie7_html";
  2259. if (quirksMode) ie7Quirks();
  2260. IE7.CSS.init();
  2261. IE7.HTML.init();
  2262. IE7.HTML.apply();
  2263. IE7.CSS.apply();
  2264. IE7.recalc();
  2265. })();
  2266. })();