diff --git a/PerformanceTests/Bindings/dom-attributes.html b/PerformanceTests/Bindings/dom-attributes.html index 236a560..4def27d 100644 --- a/PerformanceTests/Bindings/dom-attributes.html +++ b/PerformanceTests/Bindings/dom-attributes.html @@ -99,62 +99,62 @@ div.accessKey; } }, - {name: 'HTMLElement.children', - func: function() { - var div = document.createElement("div"); - for (var i = 0; i < getterRepeat; i++) - div.children; - } - }, - {name: 'HTMLElement.isContentEditable', - func: function() { - var div = document.createElement("div"); - for (var i = 0; i < getterRepeat; i++) - div.isContentEditable; - } - }, - {name: 'HTMLElement.spellcheck', - func: function() { - var div = document.createElement("div"); - for (var i = 0; i < getterRepeat; i++) - div.spellcheck; - } - }, - {name: 'HTMLElement.innerHTML', - func: function() { - var div = document.createElement("div"); - for (var i = 0; i < getterRepeat; i++) - div.innerHTML; - } - }, - {name: 'HTMLElement.innerText', - func: function() { - var div = document.createElement("div"); - for (var i = 0; i < getterRepeat; i++) - div.innerText; - } - }, - {name: 'HTMLElement.outerHTML', - func: function() { - var div = document.createElement("div"); - for (var i = 0; i < getterRepeat; i++) - div.outerHTML; - } - }, - {name: 'HTMLElement.outerText', - func: function() { - var div = document.createElement("div"); - for (var i = 0; i < getterRepeat; i++) - div.outerText; - } - }, - {name: 'HTMLElement.contentEditable', - func: function() { - var div = document.createElement("div"); - for (var i = 0; i < getterRepeat; i++) - div.contentEditable; - } - }, + // {name: 'HTMLElement.children', + // func: function() { + // var div = document.createElement("div"); + // for (var i = 0; i < getterRepeat; i++) + // div.children; + // } + // }, + // {name: 'HTMLElement.isContentEditable', + // func: function() { + // var div = document.createElement("div"); + // for (var i = 0; i < getterRepeat; i++) + // div.isContentEditable; + // } + // }, + // {name: 'HTMLElement.spellcheck', + // func: function() { + // var div = document.createElement("div"); + // for (var i = 0; i < getterRepeat; i++) + // div.spellcheck; + // } + // }, + // {name: 'HTMLElement.innerHTML', + // func: function() { + // var div = document.createElement("div"); + // for (var i = 0; i < getterRepeat; i++) + // div.innerHTML; + // } + // }, + // {name: 'HTMLElement.innerText', + // func: function() { + // var div = document.createElement("div"); + // for (var i = 0; i < getterRepeat; i++) + // div.innerText; + // } + // }, + // {name: 'HTMLElement.outerHTML', + // func: function() { + // var div = document.createElement("div"); + // for (var i = 0; i < getterRepeat; i++) + // div.outerHTML; + // } + // }, + // {name: 'HTMLElement.outerText', + // func: function() { + // var div = document.createElement("div"); + // for (var i = 0; i < getterRepeat; i++) + // div.outerText; + // } + // }, + // {name: 'HTMLElement.contentEditable', + // func: function() { + // var div = document.createElement("div"); + // for (var i = 0; i < getterRepeat; i++) + // div.contentEditable; + // } + // }, {name: 'HTMLElement.id="foo"', func: function() { var div = document.createElement("div"); @@ -225,27 +225,27 @@ div.accessKey = "foo"; } }, - {name: 'HTMLElement.spellcheck="foo"', - func: function() { - var div = document.createElement("div"); - for (var i = 0; i < setterRepeat; i++) - div.spellcheck = "foo"; - } - }, - {name: 'HTMLElement.innerHTML="foo"', - func: function() { - var div = document.createElement("div"); - for (var i = 0; i < setterRepeat; i++) - div.innerHTML = "foo"; - } - }, - {name: 'HTMLElement.innerText="foo"', - func: function() { - var div = document.createElement("div"); - for (var i = 0; i < setterRepeat; i++) - div.innerText = "foo"; - } - }, + // {name: 'HTMLElement.spellcheck="foo"', + // func: function() { + // var div = document.createElement("div"); + // for (var i = 0; i < setterRepeat; i++) + // div.spellcheck = "foo"; + // } + // }, + // {name: 'HTMLElement.innerHTML="foo"', + // func: function() { + // var div = document.createElement("div"); + // for (var i = 0; i < setterRepeat; i++) + // div.innerHTML = "foo"; + // } + // }, + // {name: 'HTMLElement.innerText="foo"', + // func: function() { + // var div = document.createElement("div"); + // for (var i = 0; i < setterRepeat; i++) + // div.innerText = "foo"; + // } + // }, {name: 'Element.tagName', func: function() { var div = document.createElement("div"); @@ -253,41 +253,41 @@ div.tagName; } }, - {name: 'Element.style', - func: function() { - var div = document.createElement("div"); - for (var i = 0; i < getterRepeat; i++) - div.style; - } - }, - {name: 'Element.offsetLeft', - func: function() { - var div = document.createElement("div"); - for (var i = 0; i < getterRepeat; i++) - div.offsetLeft; - } - }, - {name: 'Element.clientLeft', - func: function() { - var div = document.createElement("div"); - for (var i = 0; i < getterRepeat; i++) - div.clientLeft; - } - }, - {name: 'Element.scrollLeft', - func: function() { - var div = document.createElement("div"); - for (var i = 0; i < getterRepeat; i++) - div.scrollLeft; - } - }, - {name: 'Element.dataset', - func: function() { - var div = document.createElement("div"); - for (var i = 0; i < getterRepeat; i++) - div.dataset; - } - }, + // {name: 'Element.style', + // func: function() { + // var div = document.createElement("div"); + // for (var i = 0; i < getterRepeat; i++) + // div.style; + // } + // }, + // {name: 'Element.offsetLeft', + // func: function() { + // var div = document.createElement("div"); + // for (var i = 0; i < getterRepeat; i++) + // div.offsetLeft; + // } + // }, + // {name: 'Element.clientLeft', + // func: function() { + // var div = document.createElement("div"); + // for (var i = 0; i < getterRepeat; i++) + // div.clientLeft; + // } + // }, + // {name: 'Element.scrollLeft', + // func: function() { + // var div = document.createElement("div"); + // for (var i = 0; i < getterRepeat; i++) + // div.scrollLeft; + // } + // }, + // {name: 'Element.dataset', + // func: function() { + // var div = document.createElement("div"); + // for (var i = 0; i < getterRepeat; i++) + // div.dataset; + // } + // }, {name: 'Element.firstElementChild', func: function() { var div = document.createElement("div"); @@ -316,34 +316,34 @@ div.nextElementSibling; } }, - {name: 'Element.childElementCount', - func: function() { - var div = document.createElement("div"); - for (var i = 0; i < getterRepeat; i++) - div.childElementCount; - } - }, - {name: 'Element.onload', - func: function() { - var div = document.createElement("div"); - for (var i = 0; i < getterRepeat; i++) - div.onload; - } - }, - {name: 'Element.scrollLeft="foo"', - func: function() { - var div = document.createElement("div"); - for (var i = 0; i < setterRepeat; i++) - div.scrollLeft = "foo"; - } - }, - {name: 'Element.onload="foo"', - func: function() { - var div = document.createElement("div"); - for (var i = 0; i < setterRepeat; i++) - div.onload = "foo"; - } - }, + // {name: 'Element.childElementCount', + // func: function() { + // var div = document.createElement("div"); + // for (var i = 0; i < getterRepeat; i++) + // div.childElementCount; + // } + // }, + // {name: 'Element.onload', + // func: function() { + // var div = document.createElement("div"); + // for (var i = 0; i < getterRepeat; i++) + // div.onload; + // } + // }, + // {name: 'Element.scrollLeft="foo"', + // func: function() { + // var div = document.createElement("div"); + // for (var i = 0; i < setterRepeat; i++) + // div.scrollLeft = "foo"; + // } + // }, + // {name: 'Element.onload="foo"', + // func: function() { + // var div = document.createElement("div"); + // for (var i = 0; i < setterRepeat; i++) + // div.onload = "foo"; + // } + // }, {name: 'Node.nodeName', func: function() { var div = document.createElement("div"); @@ -400,13 +400,13 @@ div.nextSibling; } }, - {name: 'Node.attributes', - func: function() { - var div = document.createElement("div"); - for (var i = 0; i < getterRepeat; i++) - div.attributes; - } - }, + // {name: 'Node.attributes', + // func: function() { + // var div = document.createElement("div"); + // for (var i = 0; i < getterRepeat; i++) + // div.attributes; + // } + // }, {name: 'Node.ownerDocument', func: function() { var div = document.createElement("div"); @@ -414,27 +414,27 @@ div.ownerDocument; } }, - {name: 'Node.namespaceURI', - func: function() { - var div = document.createElement("div"); - for (var i = 0; i < getterRepeat; i++) - div.namespaceURI; - } - }, - {name: 'Node.localName', - func: function() { - var div = document.createElement("div"); - for (var i = 0; i < getterRepeat; i++) - div.localName; - } - }, - {name: 'Node.baseURI', - func: function() { - var div = document.createElement("div"); - for (var i = 0; i < getterRepeat; i++) - div.baseURI; - } - }, + // {name: 'Node.namespaceURI', + // func: function() { + // var div = document.createElement("div"); + // for (var i = 0; i < getterRepeat; i++) + // div.namespaceURI; + // } + // }, + // {name: 'Node.localName', + // func: function() { + // var div = document.createElement("div"); + // for (var i = 0; i < getterRepeat; i++) + // div.localName; + // } + // }, + // {name: 'Node.baseURI', + // func: function() { + // var div = document.createElement("div"); + // for (var i = 0; i < getterRepeat; i++) + // div.baseURI; + // } + // }, {name: 'Node.parentElement', func: function() { var div = document.createElement("div"); @@ -442,20 +442,20 @@ div.parentElement; } }, - {name: 'Node.nodeValue', - func: function() { - var div = document.createElement("div"); - for (var i = 0; i < getterRepeat; i++) - div.nodeValue; - } - }, - {name: 'Node.prefix', - func: function() { - var div = document.createElement("div"); - for (var i = 0; i < getterRepeat; i++) - div.prefix; - } - }, + // {name: 'Node.nodeValue', + // func: function() { + // var div = document.createElement("div"); + // for (var i = 0; i < getterRepeat; i++) + // div.nodeValue; + // } + // }, + // {name: 'Node.prefix', + // func: function() { + // var div = document.createElement("div"); + // for (var i = 0; i < getterRepeat; i++) + // div.prefix; + // } + // }, {name: 'Node.textContent', func: function() { var div = document.createElement("div"); @@ -463,20 +463,20 @@ div.textContent; } }, - {name: 'Node.nodeValue="foo"', - func: function() { - var div = document.createElement("div"); - for (var i = 0; i < setterRepeat; i++) - div.nodeValue = "foo"; - } - }, - {name: 'Node.prefix="foo"', - func: function() { - var div = document.createElement("div"); - for (var i = 0; i < setterRepeat; i++) - div.prefix = "foo"; - } - }, + // {name: 'Node.nodeValue="foo"', + // func: function() { + // var div = document.createElement("div"); + // for (var i = 0; i < setterRepeat; i++) + // div.nodeValue = "foo"; + // } + // }, + // {name: 'Node.prefix="foo"', + // func: function() { + // var div = document.createElement("div"); + // for (var i = 0; i < setterRepeat; i++) + // div.prefix = "foo"; + // } + // }, {name: 'Node.textContent="foo"', func: function() { var div = document.createElement("div"); diff --git a/Source/Element.js b/Source/Element.js index d59303b..3d5cfd1 100644 --- a/Source/Element.js +++ b/Source/Element.js @@ -23,23 +23,37 @@ var Element = (function() { } Element.prototype = Object.create(Node.prototype, { - setAttribute: util.method(function(name, value) { - var normalizedName = normalizeAttributeName(this, name); + _fastSetAttribute: util.method(function(normalizedName, value) { // var map = GET(this, ATTRIBUTE_MAP); - var map = this._attributeMap; - map.set(normalizedName, String(value)); + this._attributeMap.set(normalizedName, value); + }), + setAttribute: util.method(function(name, value) { + this._fastSetAttribute(normalizeAttributeName(this, name), + String(value)); + }), + + _fastGetAttribute: util.method(function(normalizedName) { + var value = this._attributeMap.get(normalizedName); + return value !== undefined ? value : null; }), getAttribute: util.method(function(name) { - var normalizedName = normalizeAttributeName(this, name); + return this._fastGetAttribute(normalizeAttributeName(this, name)); + }), + + _fastHasAttribute: util.method(function(normalizedName) { // var map = GET(this, ATTRIBUTE_MAP); - var map = this._attributeMap; - return map.has(normalizedName) ? map.get(normalizedName) : null; + return this._attributeMap.has(normalizedName); }), hasAttribute: util.method(function(name) { - var normalizedName = normalizeAttributeName(this, name); + return this._fastHasAttribute(normalizeAttributeName(this, name)); + }), + + _fastRemoveAttribute: util.method(function(normalizedName) { // var map = GET(this, ATTRIBUTE_MAP); - var map = this._attributeMap; - return map.has(normalizedName); + this._attributeMap.delete(normalizedName); + }), + removeAttribute: util.method(function(name) { + this._fastRemoveAttribute(normalizeAttributeName(this, name)); }), tagName: util.readOnly(function() { diff --git a/Source/util.js b/Source/util.js index 95c090a..1a4fd0e 100644 --- a/Source/util.js +++ b/Source/util.js @@ -13,13 +13,13 @@ var util = (function() { function reflectStringAttribute(attributeName) { return { get: function() { - return this.getAttribute(attributeName) || ''; + return this._fastGetAttribute(attributeName) || ''; }, set: function(value) { if (value === null) - this.removeAttribute(attributeName); + this._fastRemoveAttribute(attributeName); else - this.setAttribute(attributeName, value); + this._fastSetAttribute(attributeName, String(value)); }, configurable: true, enumerable: true @@ -35,13 +35,13 @@ var util = (function() { function reflectBooleanAttribute(attributeName) { return { get: function() { - return this.hasAttribute(attributeName); + return this._fastHasAttribute(attributeName); }, set: function(value) { if (!value) - this.removeAttribute(attributeName); + this._fastRemoveAttribute(attributeName); else - this.setAttribute(attributeName, ''); + this._fastSetAttribute(attributeName, ''); }, configurable: true, enumerable: true @@ -52,14 +52,14 @@ var util = (function() { return { get: function() { // TODO(arv): Validate - return parseInt(this.getAttribute(attributeName), 10); + return Number(this._fastGetAttribute(attributeName), 10); }, set: function(value) { if (value === null) { - this.removeAttribute(attributeName); + this._fastRemoveAttribute(attributeName); } else { // TODO(arv): Validate - this.setAttribute(attributeName, Number(value) | 0); + this._fastSetAttribute(attributeName, Number(value) | 0); } }, configurable: true,