Files
galaxy/static/scripts/IE8.js
T
James Taylor 94f96b47c4 Move 'confirm' javascript up to base template (other scripts to be run on
every page can be added to galaxy.base.js). Cleaned up history templates
accordingly. Also, added scripts from IE7.js which fix many layout bugs in
older versions of IE.
2008-04-28 16:35:00 +00:00

2602 lines
88 KiB
JavaScript

// timestamp: Sun, 03 Feb 2008 19:26:22
/*
IE7/IE8.js - copyright 2004-2008, Dean Edwards
http://dean.edwards.name/IE7/
http://www.opensource.org/licenses/mit-license.php
*/
/* W3C compliance for Microsoft Internet Explorer */
/* credits/thanks:
Shaggy, Martijn Wargers, Jimmy Cerra, Mark D Anderson,
Lars Dieckow, Erik Arvidsson, Gellért Gyuris, James Denny,
Unknown W Brackets, Benjamin Westfarer, Rob Eberhardt,
Bill Edney, Kevin Newman, James Crompton, Matthew Mastracci,
Doug Wright, Richard York, Kenneth Kolano, MegaZone,
Thomas Verelst, Mark 'Tarquin' Wilton-Jones, Rainer Åhlfors,
David Zulaica, Ken Kolano, Kevin Newman
*/
// =======================================================================
// TO DO
// =======================================================================
// PNG - unclickable content
// =======================================================================
// TEST/BUGGY
// =======================================================================
// hr{margin:1em auto} (doesn't look right in IE5)
(function() {
IE7 = {
toString: function(){return "IE7 version 2.0 (beta3)"}
};
var appVersion = IE7.appVersion = navigator.appVersion.match(/MSIE (\d\.\d)/)[1];
if (/ie7_off/.test(top.location.search) || appVersion < 5) return;
var Undefined = K();
var quirksMode = document.compatMode != "CSS1Compat";
var documentElement = document.documentElement, body, viewport;
var ANON = "!";
var HEADER = ":link{ie7-link:link}:visited{ie7-link:visited}";
// -----------------------------------------------------------------------
// external
// -----------------------------------------------------------------------
var RELATIVE = /^[\w\.]+[^:]*$/;
function makePath(href, path) {
if (RELATIVE.test(href)) href = (path || "") + href;
return href;
};
function getPath(href, path) {
href = makePath(href, path);
return href.slice(0, href.lastIndexOf("/") + 1);
};
// get the path to this script
var script = document.scripts[document.scripts.length - 1];
var path = getPath(script.src);
// we'll use microsoft's http request object to load external files
try {
var httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
// ActiveX disabled
}
var fileCache = {};
function loadFile(href, path) {
try {
href = makePath(href, path);
if (!fileCache[href]) {
// easy to load a file huh?
httpRequest.open("GET", href, false);
httpRequest.send();
if (httpRequest.status == 0 || httpRequest.status == 200) {
fileCache[href] = httpRequest.responseText;
}
}
} catch (e) {
// ignore errors
} finally {
return fileCache[href] || "";
}};
// -----------------------------------------------------------------------
// IE5.0 compatibility
// -----------------------------------------------------------------------
if (appVersion < 5.5) {
undefined = Undefined();
ANON = "HTML:!"; // for anonymous content
// Fix String.replace (Safari1.x/IE5.0).
var GLOBAL = /(g|gi)$/;
var _String_replace = String.prototype.replace;
String.prototype.replace = function(expression, replacement) {
if (typeof replacement == "function") { // Safari doesn't like functions
if (expression && expression.constructor == RegExp) {
var regexp = expression;
var global = regexp.global;
if (global == null) global = GLOBAL.test(regexp);
// we have to convert global RexpExps for exec() to work consistently
if (global) regexp = new RegExp(regexp.source); // non-global
} else {
regexp = new RegExp(rescape(expression));
}
var match, string = this, result = "";
while (string && (match = regexp.exec(string))) {
result += string.slice(0, match.index) + replacement.apply(this, match);
string = string.slice(match.index + match[0].length);
if (!global) break;
}
return result + string;
}
return _String_replace.apply(this, arguments);
};
Array.prototype.pop = function() {
if (this.length) {
var i = this[this.length - 1];
this.length--;
return i;
}
return undefined;
};
Array.prototype.push = function() {
for (var i = 0; i < arguments.length; i++) {
this[this.length] = arguments[i];
}
return this.length;
};
var ns = this;
Function.prototype.apply = function(o, a) {
if (o === undefined) o = ns;
else if (o == null) o = window;
else if (typeof o == "string") o = new String(o);
else if (typeof o == "number") o = new Number(o);
else if (typeof o == "boolean") o = new Boolean(o);
if (arguments.length == 1) a = [];
else if (a[0] && a[0].writeln) a[0] = a[0].documentElement.document || a[0];
var $ = "#ie7_apply", r;
o[$] = this;
switch (a.length) { // unroll for speed
case 0: r = o[$](); break;
case 1: r = o[$](a[0]); break;
case 2: r = o[$](a[0],a[1]); break;
case 3: r = o[$](a[0],a[1],a[2]); break;
case 4: r = o[$](a[0],a[1],a[2],a[3]); break;
case 5: r = o[$](a[0],a[1],a[2],a[3],a[4]); break;
default:
var b = [], i = a.length - 1;
do b[i] = "a[" + i + "]"; while (i--);
eval("r=o[$](" + b + ")");
}
if (typeof o.valueOf == "function") { // not a COM object
delete o[$];
} else {
o[$] = undefined;
if (r && r.writeln) r = r.documentElement.document || r;
}
return r;
};
Function.prototype.call = function(o) {
return this.apply(o, _slice.apply(arguments, [1]));
};
// block elements are "inline" according to IE5.0 so we'll fix it
HEADER += "address,blockquote,body,dd,div,dt,fieldset,form,"+
"frame,frameset,h1,h2,h3,h4,h5,h6,iframe,noframes,object,p,"+
"hr,applet,center,dir,menu,pre,dl,li,ol,ul{display:block}";
}
// -----------------------------------------------------------------------
// OO support
// -----------------------------------------------------------------------
// This is a cut-down version of base2 (http://code.google.com/p/base2/)
var _slice = Array.prototype.slice;
// private
var _FORMAT = /%([1-9])/g;
var _LTRIM = /^\s\s*/;
var _RTRIM = /\s\s*$/;
var _RESCAPE = /([\/()[\]{}|*+-.,^$?\\])/g; // safe regular expressions
var _BASE = /\bbase\b/;
var _HIDDEN = ["constructor", "toString"]; // only override these when prototyping
var prototyping;
function Base(){};
Base.extend = function(_instance, _static) {
// Build the prototype.
prototyping = true;
var _prototype = new this;
extend(_prototype, _instance);
prototyping = false;
// Create the wrapper for the constructor function.
var _constructor = _prototype.constructor;
function klass() {
// Don't call the constructor function when prototyping.
if (!prototyping) _constructor.apply(this, arguments);
};
_prototype.constructor = klass;
// Build the static interface.
klass.extend = arguments.callee;
extend(klass, _static);
klass.prototype = _prototype;
return klass;
};
Base.prototype.extend = function(source) {
return extend(this, source);
};
// A collection of regular expressions and their associated replacement values.
// A Base class for creating parsers.
var _HASH = "#";
var _KEYS = "~";
var _RG_ESCAPE_CHARS = /\\./g;
var _RG_ESCAPE_BRACKETS = /\(\?[:=!]|\[[^\]]+\]/g;
var _RG_BRACKETS = /\(/g;
var RegGrp = Base.extend({
constructor: function(values) {
this[_KEYS] = [];
this.merge(values);
},
exec: function(string) {
var items = this, keys = this[_KEYS];
return String(string).replace(new RegExp(this, this.ignoreCase ? "gi" : "g"), function() {
var item, offset = 1, i = 0;
// Loop through the RegGrp items.
while ((item = items[_HASH + keys[i++]])) {
var next = offset + item.length + 1;
if (arguments[offset]) { // do we have a result?
var replacement = item.replacement;
switch (typeof replacement) {
case "function":
return replacement.apply(items, _slice.call(arguments, offset, next));
case "number":
return arguments[offset + replacement];
default:
return replacement;
}
}
offset = next;
}
});
},
add: function(expression, replacement) {
if (expression instanceof RegExp) {
expression = expression.source;
}
if (!this[_HASH + expression]) this[_KEYS].push(String(expression));
this[_HASH + expression] = new RegGrp.Item(expression, replacement);
},
merge: function(values) {
for (var i in values) this.add(i, values[i]);
},
toString: function() {
// back references not supported in simple RegGrp
return "(" + this[_KEYS].join(")|(") + ")";
}
}, {
IGNORE: "$0",
Item: Base.extend({
constructor: function(expression, replacement) {
expression = expression instanceof RegExp ? expression.source : String(expression);
if (typeof replacement == "number") replacement = String(replacement);
else if (replacement == null) replacement = "";
// does the pattern use sub-expressions?
if (typeof replacement == "string" && /\$(\d+)/.test(replacement)) {
// a simple lookup? (e.g. "$2")
if (/^\$\d+$/.test(replacement)) {
// store the index (used for fast retrieval of matched strings)
replacement = parseInt(replacement.slice(1));
} else { // a complicated lookup (e.g. "Hello $2 $1")
// build a function to do the lookup
var Q = /'/.test(replacement.replace(/\\./g, "")) ? '"' : "'";
replacement = replacement.replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\$(\d+)/g, Q +
"+(arguments[$1]||" + Q+Q + ")+" + Q);
replacement = new Function("return " + Q + replacement.replace(/(['"])\1\+(.*)\+\1\1$/, "$1") + Q);
}
}
this.length = RegGrp.count(expression);
this.replacement = replacement;
this.toString = K(expression);
}
}),
count: function(expression) {
// Count the number of sub-expressions in a RegExp/RegGrp.Item.
expression = String(expression).replace(_RG_ESCAPE_CHARS, "").replace(_RG_ESCAPE_BRACKETS, "");
return match(expression, _RG_BRACKETS).length;
}
});
// =========================================================================
// lang/extend.js
// =========================================================================
function extend(object, source) { // or extend(object, key, value)
if (object && source) {
var proto = (typeof source == "function" ? Function : Object).prototype;
// Add constructor, toString etc
var i = _HIDDEN.length, key;
if (prototyping) while (key = _HIDDEN[--i]) {
var value = source[key];
if (value != proto[key]) {
if (_BASE.test(value)) {
_override(object, key, value)
} else {
object[key] = value;
}
}
}
// Copy each of the source object's properties to the target object.
for (key in source) if (proto[key] === undefined) {
var value = source[key];
// Check for method overriding.
if (object[key] && typeof value == "function" && _BASE.test(value)) {
_override(object, key, value);
} else {
object[key] = value;
}
}
}
return object;
};
function _override(object, name, method) {
// Override an existing method.
var ancestor = object[name];
object[name] = function() {
var previous = this.base;
this.base = ancestor;
var returnValue = method.apply(this, arguments);
this.base = previous;
return returnValue;
};
};
function combine(keys, values) {
// Combine two arrays to make a hash.
if (!values) values = keys;
var hash = {};
for (var i in keys) hash[i] = values[i];
return hash;
};
function format(string) {
// Replace %n with arguments[n].
// e.g. format("%1 %2%3 %2a %1%3", "she", "se", "lls");
// ==> "she sells sea shells"
// Only %1 - %9 supported.
var args = arguments;
var _FORMAT = new RegExp("%([1-" + arguments.length + "])", "g");
return String(string).replace(_FORMAT, function(match, index) {
return index < args.length ? args[index] : match;
});
};
function match(string, expression) {
// Same as String.match() except that this function will return an empty
// array if there is no match.
return String(string).match(expression) || [];
};
function rescape(string) {
// Make a string safe for creating a RegExp.
return String(string).replace(_RESCAPE, "\\$1");
};
// http://blog.stevenlevithan.com/archives/faster-trim-javascript
function trim(string) {
return String(string).replace(_LTRIM, "").replace(_RTRIM, "");
};
function K(k) {
return function() {
return k;
};
};
// -----------------------------------------------------------------------
// parsing
// -----------------------------------------------------------------------
var Parser = RegGrp.extend({ignoreCase: true});
var ENCODED = /\x01(\d+)/g,
QUOTES = /'/g,
STRING = /^\x01/,
UNICODE = /\\([\da-fA-F]{1,4})/g;
var _strings = [];
var encoder = new Parser({
// comments
"<!\\-\\-|\\-\\->": "",
"\\/\\*[^*]*\\*+([^\\/][^*]*\\*+)*\\/": "",
// get rid
"@(namespace|import)[^;\\n]+[;\\n]": "",
// strings
"'(\\\\.|[^'\\\\])*'": encodeString,
'"(\\\\.|[^"\\\\])*"': encodeString,
// white space
"\\s+": " "
});
function encode(cssText) {
return encoder.exec(cssText);
};
function decode(cssText) {
return cssText.replace(ENCODED, function(match, index) {
return _strings[index - 1];
});
};
function encodeString(string) {
return "\x01" + _strings.push(string.replace(UNICODE, function(match, chr) {
return eval("'\\u" + "0000".slice(chr.length) + chr + "'");
}).slice(1, -1).replace(QUOTES, "\\'"));
};
function getString(value) {
return STRING.test(value) ? _strings[value.slice(1) - 1] : value;
};
// clone a "width" function to create a "height" function
var rotater = new RegGrp({
Width: "Height",
width: "height",
Left: "Top",
left: "top",
Right: "Bottom",
right: "bottom",
onX: "onY"
});
function rotate(fn) {
return rotater.exec(fn);
};
// -----------------------------------------------------------------------
// event handling
// -----------------------------------------------------------------------
var eventHandlers = [];
function addResize(handler) {
addRecalc(handler);
addEventHandler(window, "onresize", handler);
};
// add an event handler (function) to an element
function addEventHandler(element, type, handler) {
element.attachEvent(type, handler);
// store the handler so it can be detached later
eventHandlers.push(arguments);
};
// remove an event handler assigned to an element by IE7
function removeEventHandler(element, type, handler) {
try {
element.detachEvent(type, handler);
} catch (ignore) {
// write a letter of complaint to microsoft..
}};
// remove event handlers (they eat memory)
addEventHandler(window, "onunload", function() {
var handler;
while (handler = eventHandlers.pop()) {
removeEventHandler(handler[0], handler[1], handler[2]);
}
});
function register(handler, element, condition) { // -@DRE
//var set = handler[element.uniqueID];
if (!handler.elements) handler.elements = {};
if (condition) handler.elements[element.uniqueID] = element;
else delete handler.elements[element.uniqueID];
//return !set && condition;
return condition;
};
addEventHandler(window, "onbeforeprint", function() {
if (!IE7.CSS.print) new StyleSheet("print");
IE7.CSS.print.recalc();
});
// -----------------------------------------------------------------------
// pixel conversion
// -----------------------------------------------------------------------
// this is handy because it means that web developers can mix and match
// measurement units in their style sheets. it is not uncommon to
// express something like padding in "em" units whilst border thickness
// is most often expressed in pixels.
var PIXEL = /^\d+(px)?$/i;
var PERCENT = /^\d+%$/;
var getPixelValue = function(element, value) {
if (PIXEL.test(value)) return parseInt(value);
var style = element.style.left;
var runtimeStyle = element.runtimeStyle.left;
element.runtimeStyle.left = element.currentStyle.left;
element.style.left = value || 0;
value = element.style.pixelLeft;
element.style.left = style;
element.runtimeStyle.left = runtimeStyle;
return value;
};
// -----------------------------------------------------------------------
// generic
// -----------------------------------------------------------------------
var $IE7 = "ie7-";
var Fix = Base.extend({
constructor: function() {
this.fixes = [];
this.recalcs = [];
},
init: Undefined
});
// a store for functions that will be called when refreshing IE7
var recalcs = [];
function addRecalc(recalc) {
recalcs.push(recalc);
};
IE7.recalc = function() {
IE7.HTML.recalc();
// re-apply style sheet rules (re-calculate ie7 classes)
IE7.CSS.recalc();
// apply global fixes to the document
for (var i = 0; i < recalcs.length; i++) recalcs[i]();
};
function isFixed(element) {
return element.currentStyle["ie7-position"] == "fixed";
};
// original style
function getDefinedStyle(element, propertyName) {
return element.currentStyle[$IE7 + propertyName] || element.currentStyle[propertyName];
};
function setOverrideStyle(element, propertyName, value) {
if (element.currentStyle[$IE7 + propertyName] == null) {
element.runtimeStyle[$IE7 + propertyName] = element.currentStyle[propertyName];
}
element.runtimeStyle[propertyName] = value;
};
// create a temporary element which is used to inherit styles
// from the target element. the temporary element can be resized
// to determine pixel widths/heights
function createTempElement(tagName) {
var element = document.createElement(tagName || "object");
element.style.cssText = "position:absolute;padding:0;display:block;border:none;clip:rect(0 0 0 0);left:-9999";
element.ie7_anon = true;
return element;
};
// =========================================================================
// ie7-cssQuery.js
// =========================================================================
function cssQuery(selector, context, single) {
if (!_cache[selector]) {
reg = []; // store for RegExp objects
var fn = "";
var selectors = cssParser.escape(selector).split(",");
for (var i = 0; i < selectors.length; i++) {
_wild = _index = _list = 0; // reset
_duplicate = selectors.length > 1 ? 2 : 0; // reset
var block = cssParser.exec(selectors[i]) || "if(0){";
if (_wild) { // IE's pesky comment nodes
block += format("if(e%1.nodeName!='!'){", _index);
}
// check for duplicates before storing results
var store = _duplicate > 1 ? _TEST : "";
block += format(store + _STORE, _index);
// add closing braces
block += Array(match(block, /\{/g).length + 1).join("}");
fn += block;
}
eval(format(_FN, reg) + cssParser.unescape(fn) + "return s?null:r}");
_cache[selector] = _selectorFunction;
}
return _cache[selector](context || document, single);
};
var _MSIE5 = appVersion < 6;
var _EVALUATED = /^(href|src)$/;
var _ATTRIBUTES = {
"class": "className",
"for": "htmlFor"
};
IE7._indexed = 1;
IE7._byId = function(document, id) {
var result = document.all[id] || null;
// returns a single element or a collection
if (!result || result.id == id) return result;
// document.all has returned a collection of elements with name/id
for (var i = 0; i < result.length; i++) {
if (result[i].id == id) return result[i];
}
return null;
};
IE7._getAttribute = function(element, name) {
if (name == "src" && element.pngSrc) return element.pngSrc;
var attribute = _MSIE5 ? (element.attributes[name] || element.attributes[_ATTRIBUTES[name.toLowerCase()]]) : element.getAttributeNode(name);
if (attribute && (attribute.specified || name == "value")) {
if (_EVALUATED.test(name)) {
return element.getAttribute(name, 2);
} else if (name == "class") {
return element.className.replace(/\sie7_\w+/g, "");
} else if (name == "style") {
return element.style.cssText;
} else {
return attribute.nodeValue;
}
}
return null;
};
var names = "colSpan,rowSpan,vAlign,dateTime,accessKey,tabIndex,encType,maxLength,readOnly,longDesc";
// Convert the list of strings to a hash, mapping the lowercase name to the camelCase name.
extend(_ATTRIBUTES, combine(names.toLowerCase().split(","), names.split(",")));
IE7._getNextElementSibling = function(node) {
// return the next element to the supplied element
// nextSibling is not good enough as it might return a text or comment node
while (node && (node = node.nextSibling) && (node.nodeType != 1 || node.nodeName == "!")) continue;
return node;
};
IE7._getPreviousElementSibling = function(node) {
// return the previous element to the supplied element
while (node && (node = node.previousSibling) && (node.nodeType != 1 || node.nodeName == "!")) continue;
return node;
};
// =========================================================================
// CSSParser
// =========================================================================
var IMPLIED_ASTERISK = /([\s>+~,]|[^(]\+|^)([#.:\[])/g,
IMPLIED_SPACE = /(^|,)([^\s>+~])/g,
WHITESPACE = /\s*([\s>+~(),]|^|$)\s*/g,
WILD_CARD = /\s\*\s/g;;
var CSSParser = RegGrp.extend({
constructor: function(items) {
this.base(items);
this.sorter = new RegGrp;
this.sorter.add(/:not\([^)]*\)/, RegGrp.IGNORE);
this.sorter.add(/([ >](\*|[\w-]+))([^: >+~]*)(:\w+-child(\([^)]+\))?)([^: >+~]*)/, "$1$3$6$4");
},
ignoreCase: true,
escape: function(selector) {
return this.optimise(this.format(selector));
},
format: function(selector) {
return selector
.replace(WHITESPACE, "$1")
.replace(IMPLIED_SPACE, "$1 $2")
.replace(IMPLIED_ASTERISK, "$1*$2");
},
optimise: function(selector) {
// optimise wild card descendant selectors
return this.sorter.exec(selector.replace(WILD_CARD, ">* "));
},
unescape: function(selector) {
return decode(selector);
}
});
// some constants
var _OPERATORS = {
"": "%1!=null",
"=": "%1=='%2'",
"~=": /(^| )%1( |$)/,
"|=": /^%1(-|$)/,
"^=": /^%1/,
"$=": /%1$/,
"*=": /%1/
};
var _PSEUDO_CLASSES = {
"first-child": "!IE7._getPreviousElementSibling(e%1)",
"link": "e%1.currentStyle['ie7-link']=='link'",
"visited": "e%1.currentStyle['ie7-link']=='visited'"
};
var _VAR = "var p%2=0,i%2,e%2,n%2=e%1.";
var _ID = "e%1.sourceIndex";
var _TEST = "var g=" + _ID + ";if(!p[g]){p[g]=1;";
var _STORE = "r[r.length]=e%1;if(s)return e%1;";
var _FN = "var _selectorFunction=function(e0,s){IE7._indexed++;var r=[],p={},reg=[%1],d=document;";
var reg; // a store for RexExp objects
var _index;
var _wild; // need to flag certain _wild card selectors as MSIE includes comment nodes
var _list; // are we processing a node _list?
var _duplicate; // possible duplicates?
var _cache = {}; // store parsed selectors
// a hideous parser
var cssParser = new CSSParser({
" (\\*|[\\w-]+)#([\\w-]+)": function(match, tagName, id) { // descendant selector followed by ID
_wild = false;
var replacement = "var e%2=IE7._byId(d,'%4');if(e%2&&";
if (tagName != "*") replacement += "e%2.nodeName=='%3'&&";
replacement += "(e%1==d||e%1.contains(e%2))){";
if (_list) replacement += format("i%1=n%1.length;", _list);
return format(replacement, _index++, _index, tagName.toUpperCase(), id);
},
" (\\*|[\\w-]+)": function(match, tagName) { // descendant selector
_duplicate++; // this selector may produce duplicates
_wild = tagName == "*";
var replacement = _VAR;
// IE5.x does not support getElementsByTagName("*");
replacement += (_wild && _MSIE5) ? "all" : "getElementsByTagName('%3')";
replacement += ";for(i%2=0;(e%2=n%2[i%2]);i%2++){";
return format(replacement, _index++, _list = _index, tagName.toUpperCase());
},
">(\\*|[\\w-]+)": function(match, tagName) { // child selector
var children = _list;
_wild = tagName == "*";
var replacement = _VAR;
// use the children property for MSIE as it does not contain text nodes
// (but the children collection still includes comments).
// the document object does not have a children collection
replacement += children ? "children": "childNodes";
if (!_wild && children) replacement += ".tags('%3')";
replacement += ";for(i%2=0;(e%2=n%2[i%2]);i%2++){";
if (_wild) {
replacement += "if(e%2.nodeType==1){";
_wild = _MSIE5;
} else {
if (!children) replacement += "if(e%2.nodeName=='%3'){";
}
return format(replacement, _index++, _list = _index, tagName.toUpperCase());
},
"\\+(\\*|[\\w-]+)": function(match, tagName) { // direct adjacent selector
var replacement = "";
if (_wild) replacement += "if(e%1.nodeName!='!'){";
_wild = false;
replacement += "e%1=IE7._getNextElementSibling(e%1);if(e%1";
if (tagName != "*") replacement += "&&e%1.nodeName=='%2'";
replacement += "){";
return format(replacement, _index, tagName.toUpperCase());
},
"~(\\*|[\\w-]+)": function(match, tagName) { // indirect adjacent selector
var replacement = "";
if (_wild) replacement += "if(e%1.nodeName!='!'){";
_wild = false;
_duplicate = 2; // this selector may produce duplicates
replacement += "while(e%1=e%1.nextSibling){if(e%1.ie7_adjacent==IE7._indexed)break;if(";
if (tagName == "*") {
replacement += "e%1.nodeType==1";
if (_MSIE5) replacement += "&&e%1.nodeName!='!'";
} else replacement += "e%1.nodeName=='%2'";
replacement += "){e%1.ie7_adjacent=IE7._indexed;";
return format(replacement, _index, tagName.toUpperCase());
},
"#([\\w-]+)": function(match, id) { // ID selector
_wild = false;
var replacement = "if(e%1.id=='%2'){";
if (_list) replacement += format("i%1=n%1.length;", _list);
return format(replacement, _index, id);
},
"\\.([\\w-]+)": function(match, className) { // class selector
_wild = false;
// store RegExp objects - slightly faster on IE
reg.push(new RegExp("(^|\\s)" + rescape(className) + "(\\s|$)"));
return format("if(e%1.className&&reg[%2].test(e%1.className)){", _index, reg.length - 1);
},
"\\[([\\w-]+)\\s*([^=]?=)?\\s*([^\\]]*)\\]": function(match, attr, operator, value) { // attribute selectors
var alias = _ATTRIBUTES[attr] || attr;
if (operator) {
var getAttribute = "e%1.getAttribute('%2',2)";
if (!_EVALUATED.test(attr)) {
getAttribute = "e%1.%3||" + getAttribute;
}
attr = format("(" + getAttribute + ")", _index, attr, alias);
} else {
attr = format("IE7._getAttribute(e%1,'%2')", _index, attr);
}
var replacement = _OPERATORS[operator || ""] || "0";
if (replacement && replacement.source) {
reg.push(new RegExp(format(replacement.source, rescape(cssParser.unescape(value)))));
replacement = "reg[%2].test(%1)";
value = reg.length - 1;
}
return "if(" + format(replacement, attr, value) + "){";
},
":+([\\w-]+)(\\(([^)]+)\\))?": function(match, pseudoClass, $2, args) { // pseudo class selectors
pseudoClass = _PSEUDO_CLASSES[pseudoClass];
return "if(" + (pseudoClass ? format(pseudoClass, _index, args || "") : "0") + "){";
}
});
// =========================================================================
// ie7-css.js
// =========================================================================
var HYPERLINK = /a(#[\w-]+)?(\.[\w-]+)?:(hover|active)/i;
var BRACE1 = /\s*\{\s*/, BRACE2 = /\s*\}\s*/, COMMA = /\s*\,\s*/;
var FIRST_LINE_LETTER = /(.*)(:first-(line|letter))/;
//var UNKNOWN = /UNKNOWN|([:.])\w+\1/i;
var styleSheets = document.styleSheets;
IE7.CSS = new (Fix.extend({ // single instance
parser: new Parser,
screen: "",
print: "",
styles: [],
rules: [],
pseudoClasses: appVersion < 7 ? "first\\-child" : "",
dynamicPseudoClasses: {
toString: function() {
var strings = [];
for (var pseudoClass in this) strings.push(pseudoClass);
return strings.join("|");
}
},
init: function() {
var NONE = "^\x01$";
var CLASS = "\\[class=?[^\\]]*\\]";
var pseudoClasses = [];
if (this.pseudoClasses) pseudoClasses.push(this.pseudoClasses);
var dynamicPseudoClasses = this.dynamicPseudoClasses.toString();
if (dynamicPseudoClasses) pseudoClasses.push(dynamicPseudoClasses);
pseudoClasses = pseudoClasses.join("|");
var unknown = appVersion < 7 ? ["[>+~[(]|([:.])\\w+\\1"] : [CLASS];
if (pseudoClasses) unknown.push(":(" + pseudoClasses + ")");
this.UNKNOWN = new RegExp(unknown.join("|") || NONE, "i");
var complex = appVersion < 7 ? ["\\[[^\\]]+\\]|[^\\s(\\[]+\\s*[+~]"] : [CLASS];
var complexRule = complex.concat();
if (pseudoClasses) complexRule.push(":(" + pseudoClasses + ")");
Rule.COMPLEX = new RegExp(complexRule.join("|") || NONE, "ig");
if (this.pseudoClasses) complex.push(":(" + this.pseudoClasses + ")");
DynamicRule.COMPLEX = new RegExp(complex.join("|") || NONE, "i");
DynamicRule.MATCH = new RegExp(dynamicPseudoClasses ? "(.*):(" + dynamicPseudoClasses + ")(.*)" : NONE, "i");
this.createStyleSheet();
this.refresh();
},
addEventHandler: function() {
addEventHandler.apply(null, arguments);
},
addFix: function(expression, replacement) {
this.parser.add(expression, replacement);
},
addRecalc: function(propertyName, test, handler, replacement) {
// recalcs occur whenever the document is refreshed using document.recalc()
test = new RegExp("([{;\\s])" + propertyName + "\\s*:\\s*" + test + "[^;}]*");
var id = this.recalcs.length;
if (replacement) replacement = propertyName + ":" + replacement;
this.addFix(test, function(match, $1) {
return (replacement ? $1 + replacement : match) + ";ie7-" + match.slice(1) + ";ie7_recalc" + id + ":1";
});
this.recalcs.push(arguments);
return id;
},
apply: function() {
this.getInlineStyles();
new StyleSheet("screen");
this.trash();
},
createStyleSheet: function() {
// create the IE7 style sheet
this.styleSheet = document.createStyleSheet();
// flag it so we can ignore it during parsing
this.styleSheet.ie7 = true;
this.styleSheet.owningElement.ie7 = true;
this.styleSheet.cssText = HEADER;
},
getInlineStyles: function() {
// load inline styles
var styleSheets = document.getElementsByTagName("style"), styleSheet;
for (var i = styleSheets.length - 1; (styleSheet = styleSheets[i]); i--) {
if (!styleSheet.disabled && !styleSheet.ie7) {
this.styles.push(styleSheet.innerHTML);
}
}
},
getText: function(styleSheet, path) {
// explorer will trash unknown selectors (it converts them to "UNKNOWN").
// so we must reload external style sheets (internal style sheets can have their text
// extracted through the innerHTML property).
// load the style sheet text from an external file
try {
var cssText = styleSheet.cssText;
} catch (e) {
cssText = "";
}
if (httpRequest) cssText = loadFile(styleSheet.href, path) || cssText;
return cssText;
},
recalc: function() {
this.screen.recalc();
// we're going to read through all style rules.
// certain rules have had ie7 properties added to them.
// e.g. p{top:0; ie7_recalc2:1; left:0}
// this flags a property in the rule as needing a fix.
// the selector text is then used to query the document.
// we can then loop through the results of the query
// and fix the elements.
// we ignore the IE7 rules - so count them in the header
var RECALCS = /ie7_recalc\d+/g;
var start = HEADER.match(/[{,]/g).length;
// only calculate screen fixes. print fixes don't show up anyway
var stop = start + (this.screen.cssText.match(/\{/g)||"").length;
var rules = this.styleSheet.rules, rule;
var calcs, calc, elements, element, i, j, k, id;
// loop through all rules
for (i = start; i < stop; i++) {
rule = rules[i];
var cssText = rule.style.cssText;
// search for the "ie7_recalc" flag (there may be more than one)
if (rule && (calcs = cssText.match(RECALCS))) {
// use the selector text to query the document
elements = cssQuery(rule.selectorText);
// if there are matching elements then loop
// through the recalc functions and apply them
// to each element
if (elements.length) for (j = 0; j < calcs.length; j++) {
// get the matching flag (e.g. ie7_recalc3)
id = calcs[j];
// extract the numeric id from the end of the flag
// and use it to index the collection of recalc
// functions
calc = IE7.CSS.recalcs[id.slice(10)][2];
for (k = 0; (element = elements[k]); k++) {
// apply the fix
if (element.currentStyle[id]) calc(element, cssText);
}
}
}
}
},
refresh: function() {
this.styleSheet.cssText = HEADER + this.screen + this.print;
},
trash: function() {
// trash the old style sheets
for (var i = 0; i < styleSheets.length; i++) {
if (!styleSheets[i].ie7) {
try {
var cssText = styleSheets[i].cssText;
} catch (e) {
cssText = "";
}
if (cssText) styleSheets[i].cssText = "";
}
}
}
}));
// -----------------------------------------------------------------------
// IE7 StyleSheet class
// -----------------------------------------------------------------------
var StyleSheet = Base.extend({
constructor: function(media) {
this.media = media;
this.load();
IE7.CSS[media] = this;
IE7.CSS.refresh();
},
createRule: function(selector, cssText) {
if (IE7.CSS.UNKNOWN.test(selector)) {
var match;
if (PseudoElement && (match = selector.match(PseudoElement.MATCH))) {
return new PseudoElement(match[1], match[2], cssText);
} else if (match = selector.match(DynamicRule.MATCH)) {
if (!HYPERLINK.test(match[0]) || DynamicRule.COMPLEX.test(match[0])) {
return new DynamicRule(selector, match[1], match[2], match[3], cssText);
}
} else return new Rule(selector, cssText);
}
return selector + " {" + cssText + "}";
},
getText: function() {
// store for style sheet text
var _inlineStyles = [].concat(IE7.CSS.styles);
// parse media decalarations
var MEDIA = /@media\s+([^{]*)\{([^@]+\})\s*\}/gi;
var ALL = /\ball\b|^$/i, SCREEN = /\bscreen\b/i, PRINT = /\bprint\b/i;
function _parseMedia(cssText, media) {
_filterMedia.value = media;
return cssText.replace(MEDIA, _filterMedia);
};
function _filterMedia(match, media, cssText) {
media = _simpleMedia(media);
switch (media) {
case "screen":
case "print":
if (media != _filterMedia.value) return "";
case "all":
return cssText;
}
return "";
};
function _simpleMedia(media) {
if (ALL.test(media)) return "all";
else if (SCREEN.test(media)) return (PRINT.test(media)) ? "all" : "screen";
else if (PRINT.test(media)) return "print";
};
var self = this;
function _getCSSText(styleSheet, path, media, level) {
var cssText = "";
if (!level) {
media = _simpleMedia(styleSheet.media);
level = 0;
}
if (media == "all" || media == self.media) {
// IE only allows importing style sheets three levels deep.
// it will crash if you try to access a level below this
if (level < 3) {
// loop through imported style sheets
for (var i = 0; i < styleSheet.imports.length; i++) {
// call this function recursively to get all imported style sheets
cssText += _getCSSText(styleSheet.imports[i], getPath(styleSheet.href, path), media, level + 1);
}
}
// retrieve inline style or load an external style sheet
cssText += encode(styleSheet.href ? _loadStyleSheet(styleSheet, path) : _inlineStyles.pop() || "");
cssText = _parseMedia(cssText, self.media);
}
return cssText;
};
// store loaded cssText URLs
var fileCache = {};
// load an external style sheet
function _loadStyleSheet(styleSheet, path) {
var url = makePath(styleSheet.href, path);
// if the style sheet has already loaded then don't duplicate it
if (fileCache[url]) return "";
// load from source
fileCache[url] = (styleSheet.disabled) ? "" :
_fixUrls(IE7.CSS.getText(styleSheet, path), getPath(styleSheet.href, path));
return fileCache[url];
};
// fix css paths
// we're lumping all css text into one big style sheet so relative
// paths have to be fixed. this is necessary anyway because of other
// explorer bugs.
var URL = /(url\s*\(\s*['"]?)([\w\.]+[^:\)]*['"]?\))/gi;
function _fixUrls(cssText, pathname) {
// hack & slash
return cssText.replace(URL, "$1" + pathname.slice(0, pathname.lastIndexOf("/") + 1) + "$2");
};
// load all style sheets in the document
for (var i = 0; i < styleSheets.length; i++) {
if (!styleSheets[i].disabled && !styleSheets[i].ie7) {
this.cssText += _getCSSText(styleSheets[i]);
}
}
},
load: function() {
this.cssText = "";
this.getText();
this.parse();
this.cssText = decode(this.cssText);
fileCache = {};
},
parse: function() {
this.cssText = IE7.CSS.parser.exec(this.cssText);
// parse the style sheet
var offset = IE7.CSS.rules.length;
var rules = this.cssText.split(BRACE2), rule;
var selectors, cssText, i, j;
for (i = 0; i < rules.length; i++) {
rule = rules[i].split(BRACE1);
selectors = rule[0].split(COMMA);
cssText = rule[1];
for (j = 0; j < selectors.length; j++) {
selectors[j] = cssText ? this.createRule(selectors[j], cssText) : "";
}
rules[i] = selectors.join("\n");
}
this.cssText = rules.join("\n");
this.rules = IE7.CSS.rules.slice(offset);
},
recalc: function() {
var rule, i;
for (i = 0; (rule = this.rules[i]); i++) rule.recalc();
},
toString: function() {
return "@media " + this.media + "{" + this.cssText + "}";
}
});
var PseudoElement;
// -----------------------------------------------------------------------
// IE7 style rules
// -----------------------------------------------------------------------
var Rule = IE7.Rule = Base.extend({
// properties
constructor: function(selector, cssText) {
this.id = IE7.CSS.rules.length;
this.className = Rule.PREFIX + this.id;
selector = selector.match(FIRST_LINE_LETTER) || selector || "*";
this.selector = selector[1] || selector;
this.selectorText = this.parse(this.selector) + (selector[2] || "");
this.cssText = cssText;
this.MATCH = new RegExp("\\s" + this.className + "(\\s|$)", "g");
IE7.CSS.rules.push(this);
this.init();
},
init: Undefined,
add: function(element) {
// allocate this class
element.className += " " + this.className;
},
recalc: function() {
// execute the underlying css query for this class
var match = cssQuery(this.selector);
// add the class name for all matching elements
for (var i = 0; i < match.length; i++) this.add(match[i]);
},
parse: function(selector) {
// attempt to preserve specificity for "loose" parsing by
// removing unknown tokens from a css selector but keep as
// much as we can..
var simple = selector.replace(Rule.CHILD, " ").replace(Rule.COMPLEX, "");
if (appVersion < 7) simple = simple.replace(Rule.MULTI, "");
var tags = match(simple, Rule.TAGS).length - match(selector, Rule.TAGS).length;
var classes = match(simple, Rule.CLASSES).length - match(selector, Rule.CLASSES).length + 1;
while (classes > 0 && Rule.CLASS.test(simple)) {
simple = simple.replace(Rule.CLASS, "");
classes--;
}
while (tags > 0 && Rule.TAG.test(simple)) {
simple = simple.replace(Rule.TAG, "$1*");
tags--;
}
simple += "." + this.className;
classes = Math.min(classes, 2);
tags = Math.min(tags, 2);
var score = -10 * classes - tags;
if (score > 0) {
simple = simple + "," + Rule.MAP[score] + " " + simple;
}
return simple;
},
remove: function(element) {
// deallocate this class
element.className = element.className.replace(this.MATCH, "$1");
},
toString: function() {
return format("%1 {%2}", this.selectorText, this.cssText);
}
}, {
CHILD: />/g,
CLASS: /\.[\w-]+/,
CLASSES: /[.:\[]/g,
MULTI: /(\.[\w-]+)+/g,
PREFIX: "ie7_class",
TAG: /^\w+|([\s>+~])\w+/,
TAGS: /^\w|[\s>+~]\w/g,
MAP: {
1: "html",
2: "html body",
10: ".ie7_html",
11: "html.ie7_html",
12: "html.ie7_html body",
20: ".ie7_html .ie7_body",
21: "html.ie7_html .ie7_body",
22: "html.ie7_html body.ie7_body"
}
});
// -----------------------------------------------------------------------
// IE7 dynamic style
// -----------------------------------------------------------------------
// object properties:
// attach: the element that an event handler will be attached to
// target: the element that will have the IE7 class applied
var DynamicRule = Rule.extend({
// properties
constructor: function(selector, attach, dynamicPseudoClass, target, cssText) {
// initialise object properties
this.attach = attach || "*";
this.dynamicPseudoClass = IE7.CSS.dynamicPseudoClasses[dynamicPseudoClass];
this.target = target;
this.base(selector, cssText);
},
recalc: function() {
// execute the underlying css query for this class
var attaches = cssQuery(this.attach), attach;
// process results
for (var i = 0; attach = attaches[i]; i++) {
// retrieve the event handler's target element(s)
var target = this.target ? cssQuery(this.target, attach) : [attach];
// attach event handlers for dynamic pseudo-classes
if (target.length) this.dynamicPseudoClass.apply(attach, target, this);
}
}
});
// -----------------------------------------------------------------------
// IE7 dynamic pseudo-classes
// -----------------------------------------------------------------------
var DynamicPseudoClass = Base.extend({
constructor: function(name, apply) {
this.name = name;
this.apply = apply;
this.instances = {};
IE7.CSS.dynamicPseudoClasses[name] = this;
},
register: function(instance) {
// an "instance" is actually an Arguments object
var _class = instance[2];
instance.id = _class.id + instance[0].uniqueID;
if (!this.instances[instance.id]) {
var target = instance[1], j;
for (j = 0; j < target.length; j++) _class.add(target[j]);
this.instances[instance.id] = instance;
}
},
unregister: function(instance) {
if (this.instances[instance.id]) {
var _class = instance[2];
var target = instance[1], j;
for (j = 0; j < target.length; j++) _class.remove(target[j]);
delete this.instances[instance.id];
}
}
});
// -----------------------------------------------------------------------
// dynamic pseudo-classes
// -----------------------------------------------------------------------
if (appVersion < 7) {
var Hover = new DynamicPseudoClass("hover", function(element) {
var instance = arguments;
IE7.CSS.addEventHandler(element, appVersion < 5.5 ? "onmouseover" : "onmouseenter", function() {
Hover.register(instance);
});
IE7.CSS.addEventHandler(element, appVersion < 5.5 ? "onmouseout" : "onmouseleave", function() {
Hover.unregister(instance);
});
});
// globally trap the mouseup event (thanks Martijn!)
addEventHandler(document, "onmouseup", function() {
var instances = Hover.instances;
for (var i in instances)
if (!instances[i][0].contains(event.srcElement))
Hover.unregister(instances[i]);
});
}
// -----------------------------------------------------------------------
// propertyName: inherit;
// -----------------------------------------------------------------------
IE7.CSS.addRecalc("[\\w-]+", "inherit", function(element, cssText) {
var inherited = cssText.match(/[\w-]+\s*:\s*inherit/g);
for (var i = 0; i < inherited.length; i++) {
var propertyName = inherited[i].replace(/ie7\-|\s*:\s*inherit/g, "").replace(/\-([a-z])/g, function(match, chr) {
return chr.toUpperCase()
});
element.runtimeStyle[propertyName] = element.parentElement.currentStyle[propertyName];
}
});
// =========================================================================
// ie7-html.js
// =========================================================================
// default font-sizes
//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}";
IE7.HTML = new (Fix.extend({ // single instance
fixed: {},
init: Undefined,
addFix: function() {
// fixes are a one-off, they are applied when the document is loaded
this.fixes.push(arguments);
},
apply: function() {
for (var i = 0; i < this.fixes.length; i++) {
var match = cssQuery(this.fixes[i][0]);
var fix = this.fixes[i][1];
for (var j = 0; j < match.length; j++) fix(match[j]);
}
},
addRecalc: function() {
// recalcs occur whenever the document is refreshed using document.recalc()
this.recalcs.push(arguments);
},
recalc: function() {
// loop through the fixes
for (var i = 0; i < this.recalcs.length; i++) {
var match = cssQuery(this.recalcs[i][0]);
var recalc = this.recalcs[i][1], element;
var key = Math.pow(2, i);
for (var j = 0; (element = match[j]); j++) {
var uniqueID = element.uniqueID;
if ((this.fixed[uniqueID] & key) == 0) {
element = recalc(element) || element;
this.fixed[uniqueID] |= key;
}
}
}
}
}));
if (appVersion < 7) {
// provide support for the <abbr> tag.
// this is a proper fix, it preserves the DOM structure and
// <abbr> elements report the correct tagName & namespace prefix
document.createElement("abbr");
// bind to the first child control
IE7.HTML.addRecalc("label", function(label) {
if (!label.htmlFor) {
var firstChildControl = cssQuery("input,textarea", label, true);
if (firstChildControl) {
addEventHandler(label, "onclick", function() {
firstChildControl.click();
});
}
}
});
}
// =========================================================================
// ie7-layout.js
// =========================================================================
var NUMERIC = "[.\\d]";
new function(_) {
var layout = IE7.Layout = this;
// big, ugly box-model hack + min/max stuff
// #tantek > #erik > #dean { voice-family: hacker; }
// -----------------------------------------------------------------------
// "layout"
// -----------------------------------------------------------------------
HEADER += "*{boxSizing:content-box}";
// does an element have "layout" ?
IE7.hasLayout = appVersion < 5.5 ? function(element) {
// element.currentStyle.hasLayout doesn't work for IE5.0
return element.clientWidth;
} : function(element) {
return element.currentStyle.hasLayout;
};
// give an element "layout"
layout.boxSizing = function(element) {
if (!IE7.hasLayout(element)) {
//# element.runtimeStyle.fixedHeight =
element.style.height = "0cm";
if (element.currentStyle.verticalAlign == "auto")
element.runtimeStyle.verticalAlign = "top";
// when an element acquires "layout", margins no longer collapse correctly
collapseMargins(element);
}
};
// -----------------------------------------------------------------------
// Margin Collapse
// -----------------------------------------------------------------------
function collapseMargins(element) {
if (element != viewport && element.currentStyle.position != "absolute") {
collapseMargin(element, "marginTop");
collapseMargin(element, "marginBottom");
}
};
function collapseMargin(element, type) {
if (!element.runtimeStyle[type]) {
var parentElement = element.parentElement;
if (parentElement && IE7.hasLayout(parentElement) && !IE7[type == "marginTop" ? "_getPreviousElementSibling" : "_getNextElementSibling"](element)) return;
var child = cssQuery(">*:" + (type == "marginTop" ? "first" : "last") + "-child", element, true);
if (child && child.currentStyle.styleFloat == "none" && IE7.hasLayout(child)) {
collapseMargin(child, type);
margin = _getMargin(element, element.currentStyle[type]);
childMargin = _getMargin(child, child.currentStyle[type]);
if (margin < 0 || childMargin < 0) {
element.runtimeStyle[type] = margin + childMargin;
} else {
element.runtimeStyle[type] = Math.max(childMargin, margin);
}
child.runtimeStyle[type] = "0px";
}
}
};
function _getMargin(element, value) {
return value == "auto" ? 0 : getPixelValue(element, value);
};
// -----------------------------------------------------------------------
// box-model
// -----------------------------------------------------------------------
// constants
var UNIT = /^[.\d][\w%]*$/, AUTO = /^(auto|0cm)$/;
var applyWidth, applyHeight;
IE7.Layout.borderBox = function(element){
applyWidth(element);
applyHeight(element);
};
var fixWidth = function(HEIGHT) {
applyWidth = function(element) {
if (!PERCENT.test(element.currentStyle.width)) fixWidth(element);
collapseMargins(element);
};
function fixWidth(element, value) {
if (!element.runtimeStyle.fixedWidth) {
if (!value) value = element.currentStyle.width;
element.runtimeStyle.fixedWidth = (UNIT.test(value)) ? Math.max(0, getFixedWidth(element, value)) : value;
setOverrideStyle(element, "width", element.runtimeStyle.fixedWidth);
}
};
function layoutWidth(element) {
if (!isFixed(element)) {
var layoutParent = element.offsetParent;
while (layoutParent && !IE7.hasLayout(layoutParent)) layoutParent = layoutParent.offsetParent;
}
return (layoutParent || viewport).clientWidth;
};
function getPixelWidth(element, value) {
if (PERCENT.test(value)) return parseInt(parseFloat(value) / 100 * layoutWidth(element));
return getPixelValue(element, value);
};
var getFixedWidth = function(element, value) {
var borderBox = element.currentStyle["box-sizing"] == "border-box";
var adjustment = 0;
if (quirksMode && !borderBox)
adjustment += getBorderWidth(element) + getWidth(element, "padding");
else if (!quirksMode && borderBox)
adjustment -= getBorderWidth(element) + getWidth(element, "padding");
return getPixelWidth(element, value) + adjustment;
};
// easy way to get border thickness for elements with "layout"
function getBorderWidth(element) {
return element.offsetWidth - element.clientWidth;
};
// have to do some pixel conversion to get padding/margin thickness :-(
function getWidth(element, type) {
return getPixelWidth(element, element.currentStyle[type + "Left"]) + getPixelWidth(element, element.currentStyle[type + "Right"]);
};
// -----------------------------------------------------------------------
// min/max
// -----------------------------------------------------------------------
HEADER += "*{minWidth:none;maxWidth:none;min-width:none;max-width:none}";
// handle min-width property
layout.minWidth = function(element) {
// IE6 supports min-height so we frig it here
//#if (element.currentStyle.minHeight == "auto") element.runtimeStyle.minHeight = 0;
if (element.currentStyle["min-width"] != null) {
element.style.minWidth = element.currentStyle["min-width"];
}
if (register(arguments.callee, element, element.currentStyle.minWidth != "none")) {
layout.boxSizing(element);
fixWidth(element);
resizeWidth(element);
}
};
// clone the minWidth function to make a maxWidth function
eval("IE7.Layout.maxWidth=" + String(layout.minWidth).replace(/min/g, "max"));
// apply min/max restrictions
function resizeWidth(element) {
// check boundaries
var rect = element.getBoundingClientRect();
var width = rect.right - rect.left;
if (element.currentStyle.minWidth != "none" && width <= getFixedWidth(element, element.currentStyle.minWidth)) {
element.runtimeStyle.width = element.currentStyle.minWidth;
} else if (element.currentStyle.maxWidth != "none" && width >= getFixedWidth(element, element.currentStyle.maxWidth)) {
element.runtimeStyle.width = element.currentStyle.maxWidth;
} else {
element.runtimeStyle.width = element.runtimeStyle.fixedWidth; // || "auto";
}
};
// -----------------------------------------------------------------------
// right/bottom
// -----------------------------------------------------------------------
function fixRight(element) {
if (register(fixRight, element, /^(fixed|absolute)$/.test(element.currentStyle.position) &&
getDefinedStyle(element, "left") != "auto" &&
getDefinedStyle(element, "right") != "auto" &&
AUTO.test(getDefinedStyle(element, "width")))) {
resizeRight(element);
IE7.Layout.boxSizing(element);
}
};
IE7.Layout.fixRight = fixRight;
function resizeRight(element) {
var left = getPixelWidth(element, element.runtimeStyle._left || element.currentStyle.left);
var width = layoutWidth(element) - getPixelWidth(element, element.currentStyle.right) - left - getWidth(element, "margin");
if (parseInt(element.runtimeStyle.width) == width) return;
element.runtimeStyle.width = "";
if (isFixed(element) || HEIGHT || element.offsetWidth < width) {
if (!quirksMode) width -= getBorderWidth(element) + getWidth(element, "padding");
if (width < 0) width = 0;
element.runtimeStyle.fixedWidth = width;
setOverrideStyle(element, "width", width);
}
};
// -----------------------------------------------------------------------
// window.onresize
// -----------------------------------------------------------------------
// handle window resize
var clientWidth = 0;
addResize(function() {
if (!viewport) return;
var i, wider = (clientWidth < viewport.clientWidth);
clientWidth = viewport.clientWidth;
// resize elements with "min-width" set
var elements = layout.minWidth.elements;
for (i in elements) {
var element = elements[i];
var fixedWidth = (parseInt(element.runtimeStyle.width) == getFixedWidth(element, element.currentStyle.minWidth));
if (wider && fixedWidth) element.runtimeStyle.width = "";
if (wider == fixedWidth) resizeWidth(element);
}
// resize elements with "max-width" set
var elements = layout.maxWidth.elements;
for (i in elements) {
var element = elements[i];
var fixedWidth = (parseInt(element.runtimeStyle.width) == getFixedWidth(element, element.currentStyle.maxWidth));
if (!wider && fixedWidth) element.runtimeStyle.width = "";
if (wider != fixedWidth) resizeWidth(element);
}
// resize elements with "right" set
for (i in fixRight.elements) resizeRight(fixRight.elements[i]);
});
// -----------------------------------------------------------------------
// fix CSS
// -----------------------------------------------------------------------
if (quirksMode) {
IE7.CSS.addRecalc("width", NUMERIC, applyWidth);
}
if (appVersion < 7) {
IE7.CSS.addRecalc("min-width", NUMERIC, layout.minWidth);
IE7.CSS.addRecalc("max-width", NUMERIC, layout.maxWidth);
IE7.CSS.addRecalc("right", NUMERIC, fixRight);
}
};
eval("var fixHeight=" + rotate(fixWidth));
// apply box-model + min/max fixes
fixWidth();
fixHeight(true);
};
// =========================================================================
// ie7-graphics.js
// =========================================================================
// a small transparent image used as a placeholder
var BLANK_GIF = makePath("blank.gif", path);
var ALPHA_IMAGE_LOADER = "DXImageTransform.Microsoft.AlphaImageLoader";
var PNG_FILTER = "progid:" + ALPHA_IMAGE_LOADER + "(src='%1',sizingMethod='%2')";
// regular expression version of the above
var PNG;
var filtered = [];
function fixImage(element) {
if (PNG.test(element.src)) {
// we have to preserve width and height
var image = new Image(element.width, element.height);
image.onload = function() {
element.width = image.width;
element.height = image.height;
image = null;
};
image.src = element.src;
// store the original url (we'll put it back when it's printed)
element.pngSrc = element.src;
// add the AlphaImageLoader thingy
addFilter(element);
}
};
if (appVersion >= 5.5 && appVersion < 7) {
// ** IE7 VARIABLE
// e.g. only apply the hack to files ending in ".png"
// IE7_PNG_SUFFIX = ".png";
// replace background(-image): url(..) .. with background(-image): .. ;filter: ..;
IE7.CSS.addFix(/background(-image)?\s*:\s*([^};]*)?url\(([^\)]+)\)([^;}]*)?/, function(match, $1, $2, url, $4) {
url = getString(url);
return PNG.test(url) ? "filter:" + format(PNG_FILTER, url, "crop") +
";zoom:1;background" + ($1||"") + ":" + ($2||"") + "none" + ($4||"") : match;
});
// -----------------------------------------------------------------------
// fix PNG transparency (HTML images)
// -----------------------------------------------------------------------
IE7.HTML.addRecalc("img,input", function(element) {
if (element.tagName == "INPUT" && element.type != "image") return;
fixImage(element);
addEventHandler(element, "onpropertychange", function() {
if (!printing && event.propertyName == "src" &&
element.src.indexOf(BLANK_GIF) == -1) fixImage(element);
});
});
// assume that background images should not be printed
// (if they are not transparent then they'll just obscure content)
// but we'll put foreground images back...
var printing = false;
addEventHandler(window, "onbeforeprint", function() {
printing = true;
for (var i = 0; i < filtered.length; i++) removeFilter(filtered[i]);
});
addEventHandler(window, "onafterprint", function() {
for (var i = 0; i < filtered.length; i++) addFilter(filtered[i]);
printing = false;
});
}
// apply a filter
function addFilter(element, sizingMethod) {
var filter = element.filters[ALPHA_IMAGE_LOADER];
if (filter) {
filter.src = element.src;
filter.enabled = true;
} else {
element.runtimeStyle.filter = format(PNG_FILTER, element.src, sizingMethod || "scale");
filtered.push(element);
}
// remove the real image
element.src = BLANK_GIF;
};
function removeFilter(element) {
element.src = element.pngSrc;
element.filters[ALPHA_IMAGE_LOADER].enabled = false;
};
// =========================================================================
// ie7-fixed.js
// =========================================================================
new function(_) {
if (appVersion >= 7) return;
// some things to consider for this hack.
// the document body requires a fixed background. even if
// it is just a blank image.
// you have to use setExpression instead of onscroll, this
// together with a fixed body background helps avoid the
// annoying screen flicker of other solutions.
IE7.CSS.addRecalc("position", "fixed", _positionFixed, "absolute");
IE7.CSS.addRecalc("background(-attachment)?", "[^};]*fixed", _backgroundFixed);
// scrolling is relative to the documentElement (HTML tag) when in
// standards mode, otherwise it's relative to the document body
var $viewport = quirksMode ? "body" : "documentElement";
function _fixBackground() {
// this is required by both position:fixed and background-attachment:fixed.
// it is necessary for the document to also have a fixed background image.
// we can fake this with a blank image if necessary
if (body.currentStyle.backgroundAttachment != "fixed") {
if (body.currentStyle.backgroundImage == "none") {
body.runtimeStyle.backgroundRepeat = "no-repeat";
body.runtimeStyle.backgroundImage = "url(" + BLANK_GIF + ")"; // dummy
}
body.runtimeStyle.backgroundAttachment = "fixed";
}
_fixBackground = Undefined;
};
var _tmp = createTempElement("img");
function _isFixed(element) {
return element ? isFixed(element) || _isFixed(element.parentElement) : false;
};
function _setExpression(element, propertyName, expression) {
setTimeout("document.all." + element.uniqueID + ".runtimeStyle.setExpression('" + propertyName + "','" + expression + "')", 0);
};
// -----------------------------------------------------------------------
// backgroundAttachment: fixed
// -----------------------------------------------------------------------
function _backgroundFixed(element) {
if (register(_backgroundFixed, element, element.currentStyle.backgroundAttachment == "fixed" && !element.contains(body))) {
_fixBackground();
bgLeft(element);
bgTop(element);
_backgroundPosition(element);
}
};
function _backgroundPosition(element) {
_tmp.src = element.currentStyle.backgroundImage.slice(5, -2);
var parentElement = element.canHaveChildren ? element : element.parentElement;
parentElement.appendChild(_tmp);
setOffsetLeft(element);
setOffsetTop(element);
parentElement.removeChild(_tmp);
};
function bgLeft(element) {
element.style.backgroundPositionX = element.currentStyle.backgroundPositionX;
if (!_isFixed(element)) {
_setExpression(element, "backgroundPositionX", "(parseInt(runtimeStyle.offsetLeft)+document." + $viewport + ".scrollLeft)||0");
}
};
eval(rotate(bgLeft));
function setOffsetLeft(element) {
var propertyName = _isFixed(element) ? "backgroundPositionX" : "offsetLeft";
element.runtimeStyle[propertyName] =
getOffsetLeft(element, element.style.backgroundPositionX) -
element.getBoundingClientRect().left - element.clientLeft + 2;
};
eval(rotate(setOffsetLeft));
function getOffsetLeft(element, position) {
switch (position) {
case "left":
case "top":
return 0;
case "right":
case "bottom":
return viewport.clientWidth - _tmp.offsetWidth;
case "center":
return (viewport.clientWidth - _tmp.offsetWidth) / 2;
default:
if (PERCENT.test(position)) {
return parseInt((viewport.clientWidth - _tmp.offsetWidth) * parseFloat(position) / 100);
}
_tmp.style.left = position;
return _tmp.offsetLeft;
}
};
eval(rotate(getOffsetLeft));
// -----------------------------------------------------------------------
// position: fixed
// -----------------------------------------------------------------------
function _positionFixed(element) {
if (register(_positionFixed, element, isFixed(element))) {
setOverrideStyle(element, "position", "absolute");
setOverrideStyle(element, "left", element.currentStyle.left);
setOverrideStyle(element, "top", element.currentStyle.top);
_fixBackground();
IE7.Layout.fixRight(element);
_foregroundPosition(element);
}
};
function _foregroundPosition(element, recalc) {
positionTop(element, recalc);
positionLeft(element, recalc, true);
if (!element.runtimeStyle.autoLeft && element.currentStyle.marginLeft == "auto" &&
element.currentStyle.right != "auto") {
var left = viewport.clientWidth - getPixelWidth(element, element.currentStyle.right) -
getPixelWidth(element, element.runtimeStyle._left) - element.clientWidth;
if (element.currentStyle.marginRight == "auto") left = parseInt(left / 2);
if (_isFixed(element.offsetParent)) element.runtimeStyle.pixelLeft += left;
else element.runtimeStyle.shiftLeft = left;
}
clipWidth(element);
clipHeight(element);
};
function clipWidth(element) {
var fixWidth = element.runtimeStyle.fixWidth;
element.runtimeStyle.borderRightWidth = "";
element.runtimeStyle.width = fixWidth ? getPixelWidth(element, fixWidth) : "";
if (element.currentStyle.width != "auto") {
var rect = element.getBoundingClientRect();
var width = element.offsetWidth - viewport.clientWidth + rect.left - 2;
if (width >= 0) {
element.runtimeStyle.borderRightWidth = "0px";
width = Math.max(getPixelValue(element, element.currentStyle.width) - width, 0);
setOverrideStyle(element, "width", width);
return width;
}
}
};
eval(rotate(clipWidth));
function positionLeft(element, recalc) {
// if the element's width is in % units then it must be recalculated
// with respect to the viewport
if (!recalc && PERCENT.test(element.currentStyle.width)) {
element.runtimeStyle.fixWidth = element.currentStyle.width;
}
if (element.runtimeStyle.fixWidth) {
element.runtimeStyle.width = getPixelWidth(element, element.runtimeStyle.fixWidth);
}
//if (recalc) {
// // if the element is fixed on the right then no need to recalculate
// if (!element.runtimeStyle.autoLeft) return;
//} else {
element.runtimeStyle.shiftLeft = 0;
element.runtimeStyle._left = element.currentStyle.left;
// is the element fixed on the right?
element.runtimeStyle.autoLeft = element.currentStyle.right != "auto" &&
element.currentStyle.left == "auto";
//}
// reset the element's "left" value and get it's natural position
element.runtimeStyle.left = "";
element.runtimeStyle.screenLeft = getScreenLeft(element);
element.runtimeStyle.pixelLeft = element.runtimeStyle.screenLeft;
// if the element is contained by another fixed element then there is no need to
// continually recalculate it's left position
if (!recalc && !_isFixed(element.offsetParent)) {
// onsrcoll produces jerky movement, so we use an expression
_setExpression(element, "pixelLeft", "runtimeStyle.screenLeft+runtimeStyle.shiftLeft+document." + $viewport + ".scrollLeft");
}
};
// clone this function so we can do "top"
eval(rotate(positionLeft));
// I've forgotten how this works...
function getScreenLeft(element) { // thanks to kevin newman (captainn)
var screenLeft = element.offsetLeft, nested = 1;
if (element.runtimeStyle.autoLeft) {
screenLeft = viewport.clientWidth - element.offsetWidth - getPixelWidth(element, element.currentStyle.right);
}
// accommodate margins
if (element.currentStyle.marginLeft != "auto") {
screenLeft -= getPixelWidth(element, element.currentStyle.marginLeft);
}
while (element = element.offsetParent) {
if (element.currentStyle.position != "static") nested = -1;
screenLeft += element.offsetLeft * nested;
}
return screenLeft;
};
eval(rotate(getScreenLeft));
function getPixelWidth(element, value) {
return PERCENT.test(value) ? parseInt(parseFloat(value) / 100 * viewport.clientWidth) : getPixelValue(element, value);
};
eval(rotate(getPixelWidth));
// -----------------------------------------------------------------------
// capture window resize
// -----------------------------------------------------------------------
function _resize() {
// if the window has been resized then some positions need to be
// recalculated (especially those aligned to "right" or "top"
var elements = _backgroundFixed.elements;
for (var i in elements) _backgroundPosition(elements[i]);
elements = _positionFixed.elements;
for (i in elements) {
_foregroundPosition(elements[i], true);
// do this twice to be sure - hackish, I know :-)
_foregroundPosition(elements[i], true);
}
_timer = 0;
};
// use a timer for some reason.
// (sometimes this is a good way to prevent resize loops)
var _timer;
addResize(function() {
if (!_timer) _timer = setTimeout(_resize, 0);
});
};
// =========================================================================
// ie7-oveflow.js
// =========================================================================
/* ---------------------------------------------------------------------
This module alters the structure of the document.
It may adversely affect other CSS rules. Be warned.
--------------------------------------------------------------------- */
var WRAPPER_STYLE = {
backgroundColor: "transparent",
backgroundImage: "none",
backgroundPositionX: null,
backgroundPositionY: null,
backgroundRepeat: null,
borderTopWidth: 0,
borderRightWidth: 0,
borderBottomWidth: 0,
borderLeftStyle: "none",
borderTopStyle: "none",
borderRightStyle: "none",
borderBottomStyle: "none",
borderLeftWidth: 0,
height: null,
marginTop: 0,
marginBottom: 0,
marginRight: 0,
marginLeft: 0,
width: "100%"
};
IE7.CSS.addRecalc("overflow", "visible", function(element) {
// don't do this again
if (element.parentNode.ie7_wrapped) return;
// if max-height is applied, makes sure it gets applied first
if (IE7.Layout && element.currentStyle["max-height"] != "auto") {
IE7.Layout.maxHeight(element);
}
if (element.currentStyle.marginLeft == "auto") element.style.marginLeft = 0;
if (element.currentStyle.marginRight == "auto") element.style.marginRight = 0;
var wrapper = document.createElement(ANON);
wrapper.ie7_wrapped = element;
for (var propertyName in WRAPPER_STYLE) {
wrapper.style[propertyName] = element.currentStyle[propertyName];
if (WRAPPER_STYLE[propertyName] != null) {
element.runtimeStyle[propertyName] = WRAPPER_STYLE[propertyName];
}
}
wrapper.style.display = "block";
wrapper.style.position = "relative";
element.runtimeStyle.position = "absolute";
element.parentNode.insertBefore(wrapper, element);
wrapper.appendChild(element);
});
// =========================================================================
// ie7-quirks.js
// =========================================================================
function ie7Quirks() {
var FONT_SIZES = "xx-small,x-small,small,medium,large,x-large,xx-large".split(",");
for (var i = 0; i < FONT_SIZES.length; i++) {
FONT_SIZES[FONT_SIZES[i]] = FONT_SIZES[i - 1] || "0.67em";
}
IE7.CSS.addFix(/(font(-size)?\s*:\s*)([\w.-]+)/, function(match, label, size, value) {
return label + (FONT_SIZES[value] || value);
});
if (appVersion < 6) {
var NEGATIVE = /^\-/, LENGTH = /(em|ex)$/i;
var EM = /em$/i, EX = /ex$/i;
getPixelValue = function(element, value) {
if (PIXEL.test(value)) return parseInt(value)||0;
var scale = NEGATIVE.test(value)? -1 : 1;
if (LENGTH.test(value)) scale *= getFontScale(element);
temp.style.width = (scale < 0) ? value.slice(1) : value;
body.appendChild(temp);
// retrieve pixel width
value = scale * temp.offsetWidth;
// remove the temporary element
temp.removeNode();
return parseInt(value);
};
var temp = createTempElement();
function getFontScale(element) {
var scale = 1;
temp.style.fontFamily = element.currentStyle.fontFamily;
temp.style.lineHeight = element.currentStyle.lineHeight;
//temp.style.fontSize = "";
while (element != body) {
var fontSize = element.currentStyle["ie7-font-size"];
if (fontSize) {
if (EM.test(fontSize)) scale *= parseFloat(fontSize);
else if (PERCENT.test(fontSize)) scale *= (parseFloat(fontSize) / 100);
else if (EX.test(fontSize)) scale *= (parseFloat(fontSize) / 2);
else {
temp.style.fontSize = fontSize;
return 1;
}
}
element = element.parentElement;
}
return scale;
};
// cursor:pointer (IE5.x)
IE7.CSS.addFix(/cursor\s*:\s*pointer/, "cursor:hand");
// display:list-item (IE5.x)
IE7.CSS.addFix(/display\s*:\s*list-item/, "display:block");
}
// -----------------------------------------------------------------------
// margin:auto
// -----------------------------------------------------------------------
function fixMargin(element) {
if (appVersion < 5.5) IE7.Layout.boxSizing(element.parentElement);
var parent = element.parentElement;
var margin = parent.offsetWidth - element.offsetWidth - getPaddingWidth(parent);
var autoRight = (element.currentStyle["ie7-margin"] && element.currentStyle.marginRight == "auto") ||
element.currentStyle["ie7-margin-right"] == "auto";
switch (parent.currentStyle.textAlign) {
case "right":
margin = autoRight ? parseInt(margin / 2) : 0;
element.runtimeStyle.marginRight = margin + "px";
break;
case "center":
if (autoRight) margin = 0;
default:
if (autoRight) margin /= 2;
element.runtimeStyle.marginLeft = parseInt(margin) + "px";
}
};
function getPaddingWidth(element) {
return getPixelValue(element, element.currentStyle.paddingLeft) +
getPixelValue(element, element.currentStyle.paddingRight);
};
IE7.CSS.addRecalc("margin(-left|-right)?", "[^};]*auto", function(element) {
if (register(fixMargin, element,
element.parentElement &&
element.currentStyle.display == "block" &&
element.currentStyle.marginLeft == "auto" &&
element.currentStyle.position != "absolute")) {
fixMargin(element);
}
});
addResize(function() {
for (var i in fixMargin.elements) {
var element = fixMargin.elements[i];
element.runtimeStyle.marginLeft =
element.runtimeStyle.marginRight = "";
fixMargin(element);
}
});
};
// =========================================================================
// ie8-cssQuery.js
// =========================================================================
IE7._isEmpty = function(element) {
element = element.firstChild;
while (element) {
if (element.nodeType == 3 || (element.nodeType == 1 && element.nodeName != "!")) return false;
element = element.nextSibling;
}
return true;
};
IE7._isLang = function(element, code) {
while (element && !element.getAttribute("lang")) element = element.parentNode;
return element && new RegExp("^" + rescape(code), "i").test(element.getAttribute("lang"));
};
function _nthChild(match, args, position, last) {
// ugly but it works...
last = /last/i.test(match) ? last + "+1-" : "";
if (!isNaN(args)) args = "0n+" + args;
else if (args == "even") args = "2n";
else if (args == "odd") args = "2n+1";
args = args.split("n");
var a = args[0] ? (args[0] == "-") ? -1 : parseInt(args[0]) : 1;
var b = parseInt(args[1]) || 0;
var negate = a < 0;
if (negate) {
a = -a;
if (a == 1) b++;
}
var query = format(a == 0 ? "%3%7" + (last + b) : "(%4%3-%2)%6%1%70%5%4%3>=%2", a, b, position, last, "&&", "%", "==");
if (negate) query = "!(" + query + ")";
return query;
};
_PSEUDO_CLASSES = {
"link": "e%1.currentStyle['ie7-link']=='link'",
"visited": "e%1.currentStyle['ie7-link']=='visited'",
"checked": "e%1.checked",
"contains": "e%1.innerText.indexOf('%2')!=-1",
"disabled": "e%1.isDisabled",
"empty": "IE7._isEmpty(e%1)",
"enabled": "e%1.disabled===false",
"first-child": "!IE7._getPreviousElementSibling(e%1)",
"lang": "IE7._isLang(e%1,'%2')",
"last-child": "!IE7._getNextElementSibling(e%1)",
"only-child": "!IE7._getPreviousElementSibling(e%1)&&!IE7._getNextElementSibling(e%1)",
"target": "e%1.id==location.hash.slice(1)",
"indeterminate": "e%1.indeterminate"
};
// register a node and index its children
IE7._register = function(element) {
if (element.rows) {
element.ie7_length = element.rows.length;
element.ie7_lookup = "rowIndex";
} else if (element.cells) {
element.ie7_length = element.cells.length;
element.ie7_lookup = "cellIndex";
} else if (element.ie7_indexed != IE7._indexed) {
var index = 0;
var child = element.firstChild;
while (child) {
if (child.nodeType == 1 && child.nodeName != "!") {
child.ie7_index = ++index;
}
child = child.nextSibling;
}
element.ie7_length = index;
element.ie7_lookup = "ie7_index";
}
element.ie7_indexed = IE7._indexed;
return element;
};
var keys = cssParser[_KEYS];
var pseudoClass = keys[keys.length - 1];
keys.length--;
cssParser.merge({
":not\\((\\*|[\\w-]+)?([^)]*)\\)": function(match, tagName, filters) { // :not pseudo class
var replacement = (tagName && tagName != "*") ? format("if(e%1.nodeName=='%2'){", _index, tagName.toUpperCase()) : "";
replacement += cssParser.exec(filters);
return "if(!" + replacement.slice(2, -1).replace(/\)\{if\(/g, "&&") + "){";
},
":nth(-last)?-child\\(([^)]+)\\)": function(match, last, args) { // :nth-child pseudo classes
_wild = false;
last = format("e%1.parentNode.ie7_length", _index);
var replacement = "if(p%1!==e%1.parentNode)p%1=IE7._register(e%1.parentNode);";
replacement += "var i=e%1[p%1.ie7_lookup];if(p%1.ie7_lookup!='ie7_index')i++;if(";
return format(replacement, _index) + _nthChild(match, args, "i", last) + "){";
}
});
keys.push(pseudoClass);
// =========================================================================
// ie8-css.js
// =========================================================================
var BRACKETS = "\\([^)]*\\)";
if (IE7.CSS.pseudoClasses) IE7.CSS.pseudoClasses += "|";
IE7.CSS.pseudoClasses += "before|after|last\\-child|only\\-child|empty|root|" +
"not|nth\\-child|nth\\-last\\-child|contains|lang".split("|").join(BRACKETS + "|") + BRACKETS;
// pseudo-elements can be declared with a double colon
encoder.add(/::/, ":");
// -----------------------------------------------------------------------
// dynamic pseudo-classes
// -----------------------------------------------------------------------
var Focus = new DynamicPseudoClass("focus", function(element) {
var instance = arguments;
IE7.CSS.addEventHandler(element, "onfocus", function() {
Focus.unregister(instance); // in case it starts with focus
Focus.register(instance);
});
IE7.CSS.addEventHandler(element, "onblur", function() {
Focus.unregister(instance);
});
// check the active element for initial state
if (element == document.activeElement) {
Focus.register(instance)
}
});
var Active = new DynamicPseudoClass("active", function(element) {
var instance = arguments;
IE7.CSS.addEventHandler(element, "onmousedown", function() {
Active.register(instance);
});
});
// globally trap the mouseup event (thanks Martijn!)
addEventHandler(document, "onmouseup", function() {
var instances = Active.instances;
for (var i in instances) Active.unregister(instances[i]);
});
// :checked
var Checked = new DynamicPseudoClass("checked", function(element) {
if (typeof element.checked != "boolean") return;
var instance = arguments;
IE7.CSS.addEventHandler(element, "onpropertychange", function() {
if (event.propertyName == "checked") {
if (element.checked) Checked.register(instance);
else Checked.unregister(instance);
}
});
// check current checked state
if (element.checked) Checked.register(instance);
});
// :enabled
var Enabled = new DynamicPseudoClass("enabled", function(element) {
if (typeof element.disabled != "boolean") return;
var instance = arguments;
IE7.CSS.addEventHandler(element, "onpropertychange", function() {
if (event.propertyName == "disabled") {
if (!element.isDisabled) Enabled.register(instance);
else Enabled.unregister(instance);
}
});
// check current disabled state
if (!element.isDisabled) Enabled.register(instance);
});
// :disabled
var Disabled = new DynamicPseudoClass("disabled", function(element) {
if (typeof element.disabled != "boolean") return;
var instance = arguments;
IE7.CSS.addEventHandler(element, "onpropertychange", function() {
if (event.propertyName == "disabled") {
if (element.isDisabled) Disabled.register(instance);
else Disabled.unregister(instance);
}
});
// check current disabled state
if (element.isDisabled) Disabled.register(instance);
});
// :indeterminate (Kevin Newman)
var Indeterminate = new DynamicPseudoClass("indeterminate", function(element) {
if (typeof element.indeterminate != "boolean") return;
var instance = arguments;
IE7.CSS.addEventHandler(element, "onpropertychange", function() {
if (event.propertyName == "indeterminate") {
if (element.indeterminate) Indeterminate.register(instance);
else Indeterminate.unregister(instance);
}
});
IE7.CSS.addEventHandler(element, "onclick", function() {
Indeterminate.unregister(instance);
});
// clever Kev says no need to check this up front
});
// :target
var Target = new DynamicPseudoClass("target", function(element) {
var instance = arguments;
// if an element has a tabIndex then it can become "active".
// The default is zero anyway but it works...
if (!element.tabIndex) element.tabIndex = 0;
// this doesn't detect the back button. I don't know how to do that :-(
IE7.CSS.addEventHandler(document, "onpropertychange", function() {
if (event.propertyName == "activeElement") {
if (element.id && element.id == location.hash.slice(1)) Target.register(instance);
else Target.unregister(instance);
}
});
// check the current location
if (element.id && element.id == location.hash.slice(1)) Target.register(instance);
});
// -----------------------------------------------------------------------
// IE7 pseudo elements
// -----------------------------------------------------------------------
// constants
var ATTR = /^attr/;
var URL = /^url\s*\(\s*([^)]*)\)$/;
var POSITION_MAP = {
before0: "beforeBegin",
before1: "afterBegin",
after0: "afterEnd",
after1: "beforeEnd"
};
var PseudoElement = IE7.PseudoElement = Rule.extend({
constructor: function(selector, position, cssText) {
// initialise object properties
this.position = position;
var content = cssText.match(PseudoElement.CONTENT), match, entity;
if (content) {
content = content[1];
match = content.split(/\s+/);
for (var i = 0; (entity = match[i]); i++) {
match[i] = ATTR.test(entity) ? {attr: entity.slice(5, -1)} :
(entity.charAt(0) == "'") ? getString(entity) : decode(entity);
}
content = match;
}
this.content = content;
// CSS text needs to be decoded immediately
this.base(selector, decode(cssText));
},
init: function() {
// execute the underlying css query for this class
this.match = cssQuery(this.selector);
for (var i = 0; i < this.match.length; i++) {
var runtimeStyle = this.match[i].runtimeStyle;
if (!runtimeStyle[this.position]) runtimeStyle[this.position] = {cssText:""};
runtimeStyle[this.position].cssText += ";" + this.cssText;
if (this.content != null) runtimeStyle[this.position].content = this.content;
}
},
create: function(target) {
var generated = target.runtimeStyle[this.position];
if (generated) {
// copy the array of values
var content = [].concat(generated.content || "");
for (var j = 0; j < content.length; j++) {
if (typeof content[j] == "object") {
content[j] = target.getAttribute(content[j].attr);
}
}
content = content.join("");
var url = content.match(URL);
var cssText = "overflow:hidden;" + generated.cssText.replace(/'/g, '"');
if (target.currentStyle.styleFloat != "none") {
//cssText = cssText.replace(/display\s*:\s*block/, "display:inline-block");
}
var position = POSITION_MAP[this.position + Number(target.canHaveChildren)];
var id = 'ie7_pseudo' + PseudoElement.count++;
target.insertAdjacentHTML(position, format(PseudoElement.ANON, this.className, id, cssText, url ? "" : content));
if (url) {
var pseudoElement = document.getElementById(id);
pseudoElement.src = getString(url[1]);
addFilter(pseudoElement, "crop");
}
target.runtimeStyle[this.position] = null;
}
},
recalc: function() {
if (this.content == null) return;
for (var i = 0; i < this.match.length; i++) {
this.create(this.match[i]);
}
},
toString: function() {
return "." + this.className + "{display:inline}";
}
}, {
CONTENT: /content\s*:\s*([^;]*)(;|$)/,
ANON: "<ie7:! class='ie7_anon %1' id=%2 style='%3'>%4</ie7:!>",
MATCH: /(.*):(before|after).*/,
count: 0
});
// =========================================================================
// ie8-html.js
// =========================================================================
var UNSUCCESSFUL = /^(submit|reset|button)$/;
// -----------------------------------------------------------------------
// <button>
// -----------------------------------------------------------------------
// IE bug means that innerText is submitted instead of "value"
IE7.HTML.addRecalc("button,input", function(button) {
if (button.tagName == "BUTTON") {
var match = button.outerHTML.match(/ value="([^"]*)"/i);
button.runtimeStyle.value = (match) ? match[1] : "";
}
// flag the button/input that was used to submit the form
if (button.type == "submit") {
addEventHandler(button, "onclick", function() {
button.runtimeStyle.clicked = true;
setTimeout("document.all." + button.uniqueID + ".runtimeStyle.clicked=false", 1);
});
}
});
// -----------------------------------------------------------------------
// <form>
// -----------------------------------------------------------------------
// only submit "successful controls
IE7.HTML.addRecalc("form", function(form) {
addEventHandler(form, "onsubmit", function() {
for (var element, i = 0; element = form[i]; i++) {
if (UNSUCCESSFUL.test(element.type) && !element.disabled && !element.runtimeStyle.clicked) {
element.disabled = true;
setTimeout("document.all." + element.uniqueID + ".disabled=false", 1);
} else if (element.tagName == "BUTTON" && element.type == "submit") {
setTimeout("document.all." + element.uniqueID + ".value='" +
element.value + "'", 1);
element.value = element.runtimeStyle.value;
}
}
});
});
// -----------------------------------------------------------------------
// <img>
// -----------------------------------------------------------------------
// get rid of the spurious tooltip produced by the alt attribute on images
IE7.HTML.addRecalc("img", function(img) {
if (img.alt && !img.title) img.title = "";
});
// =========================================================================
// ie8-layout.js
// =========================================================================
IE7.CSS.addRecalc("border-spacing", NUMERIC, function(element) {
if (element.currentStyle.borderCollapse != "collapse") {
element.cellSpacing = getPixelValue(element, element.currentStyle["border-spacing"]);
}
});
IE7.CSS.addRecalc("box-sizing", "content-box", IE7.Layout.boxSizing);
IE7.CSS.addRecalc("box-sizing", "border-box", IE7.Layout.borderBox);
// =========================================================================
// ie8-graphics.js
// =========================================================================
IE7.CSS.addFix(/opacity\s*:\s*([\d.]+)/, function(match, value) {
return "zoom:1;filter:Alpha(opacity=" + ((value * 100) || 1) + ")";
});
// fix object[type=image/*]
var IMAGE = /^image/i;
IE7.HTML.addRecalc("object", function(element) {
if (IMAGE.test(element.type)) {
element.body.style.cssText = "margin:0;padding:0;border:none;overflow:hidden";
return element;
}
});
// -----------------------------------------------------------------------
// initialisation
// -----------------------------------------------------------------------
IE7.loaded = true;
(function() {
try {
// http://javascript.nwbox.com/IEContentLoaded/
documentElement.doScroll("left");
} catch (e) {
setTimeout(arguments.callee, 1);
return;
}
// execute the inner text of the IE7 script
try {
eval(script.innerHTML);
} catch (e) {
// ignore errors
}
PNG = new RegExp(rescape(typeof IE7_PNG_SUFFIX == "string" ? IE7_PNG_SUFFIX : "-trans.png") + "$", "i");
// frequently used references
body = document.body;
viewport = quirksMode ? body : documentElement;
// classes
body.className += " ie7_body";
documentElement.className += " ie7_html";
if (quirksMode) ie7Quirks();
IE7.CSS.init();
IE7.HTML.init();
IE7.HTML.apply();
IE7.CSS.apply();
IE7.recalc();
})();
})();