Optimize document.getElementsByClassName and finalize DOM performance optimization refactoring. Closes #6696

This commit is contained in:
Thomas Fuchs 2007-03-04 22:55:08 +00:00
parent 3c743a35f5
commit fcc23f0d70
3 changed files with 85 additions and 97 deletions

View File

@ -1,6 +1,8 @@
*SVN*
* Fix an issue with serializing empty array inputs, fixes #7516. [stakadush, Mislav Marohnić]
* Optimize document.getElementsByClassName and finalize DOM performance optimization refactoring. Closes #6696. [Mislav Marohnić]
* Fix an issue with serializing empty array inputs. Closes #7516. [stakadush, Mislav Marohnić]
* Add optional third parameter "camelized" to Element.setStyle, for optimized performance if style names are known to be camelCased. [Thomas Fuchs]

View File

@ -18,29 +18,24 @@ if (Prototype.BrowserFeatures.XPath) {
results.push(query.snapshotItem(i));
return results;
};
}
document.getElementsByClassName = function(className, parentElement) {
if (Prototype.BrowserFeatures.XPath) {
document.getElementsByClassName = function(className, parentElement) {
var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";
return document._getElementsByXPath(q, parentElement);
} else {
var children = ($(parentElement) || document.body).getElementsByTagName('*');
var elements = [], child;
for (var i = 0, length = children.length; i < length; i++) {
child = children[i];
if (Element.hasClassName(child, className))
elements.push(Element.extend(child));
}
return elements;
}
} else document.getElementsByClassName = function(className, parentElement) {
var children = ($(parentElement) || document.body).getElementsByTagName('*');
var elements = [], child;
for (var i = 0, length = children.length; i < length; i++) {
child = children[i];
if (Element.hasClassName(child, className))
elements.push(Element.extend(child));
}
return elements;
};
/*--------------------------------------------------------------------------*/
if (!window.Element)
var Element = new Object();
if (!window.Element) var Element = {};
Element.extend = function(element) {
var F = Prototype.BrowserFeatures;
@ -421,8 +416,7 @@ if (Prototype.Browser.Opera) {
}
};
}
if (Prototype.Browser.IE) {
else if (Prototype.Browser.IE) {
Element.Methods.getStyle = function(element, style) {
element = $(element);
style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
@ -454,73 +448,8 @@ if (Prototype.Browser.IE) {
'alpha(opacity=' + (value * 100) + ')';
return element;
};
}
if (Prototype.Browser.Gecko) {
Element.Methods.setOpacity = function(element, value) {
element = $(element);
element.style.opacity = (value == 1) ? 0.999999 :
(value === '') ? '' : (value < 0.00001) ? 0 : value;
return element;
};
}
Element._attributeTranslations = {};
Element._attributeTranslations.names = {
colspan: "colSpan",
rowspan: "rowSpan",
valign: "vAlign",
datetime: "dateTime",
accesskey: "accessKey",
tabindex: "tabIndex",
enctype: "encType",
maxlength: "maxLength",
readonly: "readOnly",
longdesc: "longDesc"
};
Element._attributeTranslations.values = {
_getAttr: function(element, attribute) {
return element.getAttribute(attribute, 2);
},
_flag: function(element, attribute) {
return $(element).hasAttribute(attribute) ? attribute : null;
},
style: function(element) {
return element.style.cssText.toLowerCase();
},
title: function(element) {
var node = element.getAttributeNode('title');
return node.specified ? node.nodeValue : null;
}
};
Object.extend(Element._attributeTranslations.values, {
href: Element._attributeTranslations.values._getAttr,
src: Element._attributeTranslations.values._getAttr,
disabled: Element._attributeTranslations.values._flag,
checked: Element._attributeTranslations.values._flag,
readonly: Element._attributeTranslations.values._flag,
multiple: Element._attributeTranslations.values._flag
});
Element.Methods.Simulated = {
hasAttribute: function(element, attribute) {
var t = Element._attributeTranslations, node;
attribute = t.names[attribute] || attribute;
node = $(element).getAttributeNode(attribute);
return node && node.specified;
}
};
Element.Methods.ByTag = {};
// IE is missing .innerHTML support for TABLE-related elements
if (Prototype.Browser.IE){
// IE is missing .innerHTML support for TABLE-related elements
Element.Methods.update = function(element, html) {
element = $(element);
html = typeof html == 'undefined' ? '' : html.toString();
@ -554,8 +483,68 @@ if (Prototype.Browser.IE){
setTimeout(function() {html.evalScripts()}, 10);
return element;
}
}
else if (Prototype.Browser.Gecko) {
Element.Methods.setOpacity = function(element, value) {
element = $(element);
element.style.opacity = (value == 1) ? 0.999999 :
(value === '') ? '' : (value < 0.00001) ? 0 : value;
return element;
};
}
Element._attributeTranslations = {
names: {
colspan: "colSpan",
rowspan: "rowSpan",
valign: "vAlign",
datetime: "dateTime",
accesskey: "accessKey",
tabindex: "tabIndex",
enctype: "encType",
maxlength: "maxLength",
readonly: "readOnly",
longdesc: "longDesc"
},
values: {
_getAttr: function(element, attribute) {
return element.getAttribute(attribute, 2);
},
_flag: function(element, attribute) {
return $(element).hasAttribute(attribute) ? attribute : null;
},
style: function(element) {
return element.style.cssText.toLowerCase();
},
title: function(element) {
var node = element.getAttributeNode('title');
return node.specified ? node.nodeValue : null;
}
}
};
with (Element._attributeTranslations.values) {
Object.extend(this, {
href: _getAttr,
src: _getAttr,
disabled: _flag,
checked: _flag,
readonly: _flag,
multiple: _flag
});
};
Element.Methods.Simulated = {
hasAttribute: function(element, attribute) {
var t = Element._attributeTranslations, node;
attribute = t.names[attribute] || attribute;
node = $(element).getAttributeNode(attribute);
return node && node.specified;
}
};
Element.Methods.ByTag = {};
Object.extend(Element, Element.Methods);
if (!Prototype.BrowserFeatures.ElementExtensions &&
@ -572,12 +561,9 @@ Element.addMethods = function(methods) {
methods = arguments[1];
}
if (!tagName)
Object.extend(Element.Methods, methods || {});
if (!tagName) Object.extend(Element.Methods, methods || {});
else {
if (tagName.constructor == Array) {
tagName.each(extend);
}
if (tagName.constructor == Array) tagName.each(extend);
else extend(tagName);
}
@ -637,8 +623,7 @@ Element.addMethods = function(methods) {
}
};
var Toggle = new Object();
Toggle.display = Element.toggle;
var Toggle = { display: Element.toggle };
/*--------------------------------------------------------------------------*/

View File

@ -631,12 +631,9 @@
}},
testElementSetStyleCamelized: function() { with(this) {
assertNotEqual('30px', $('style_test_3').style.marginTop);
$('style_test_3').setStyle({ marginTop: '30px'}, true);
assertEqual('30px', $('style_test_3').style.marginTop);
// This would work if camelized parameter is false
$('style_test_3').setStyle({ 'margin-top': '20px'}, true);
assertEqual('30px', $('style_test_3').style.marginTop);
}},
testElementSetOpacity: function() { with(this) {
@ -728,7 +725,11 @@
}},
testElementReadAttribute: function() {with(this) {
assertEqual('test.html' , $('attributes_with_issues_1').readAttribute('href'));
assertEqual('test.html' , $('attributes_with_issues_1').readAttribute('href'),
'NOTE: Due to a bug in IE\'s proprietary iFlags extension to getAttribute(), '+
'"href" attribute lookup fails to grab the exact attribute value for protocols '+
'other than http(s), which makes this test fail when run locally (file protocol).');
assertEqual('L' , $('attributes_with_issues_1').readAttribute('accesskey'));
assertEqual('50' , $('attributes_with_issues_1').readAttribute('tabindex'));
assertEqual('a link' , $('attributes_with_issues_1').readAttribute('title'));