IE9.js 96 KB

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