Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(144)

Unified Diff: lib/dom/templates/html/impl/impl_Element.darttemplate

Issue 9732019: dart:html perf optimization based on runing Dromaeo benchmarks (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fixes Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: lib/dom/templates/html/impl/impl_Element.darttemplate
diff --git a/lib/dom/templates/html/impl/impl_Element.darttemplate b/lib/dom/templates/html/impl/impl_Element.darttemplate
index 5d0f7b365b38c4a0aa5e398bbe492a5a53ee26f9..f7542b2b8a0356aefdfe1a3ddcebec4e97b31067 100644
--- a/lib/dom/templates/html/impl/impl_Element.darttemplate
+++ b/lib/dom/templates/html/impl/impl_Element.darttemplate
@@ -10,7 +10,7 @@ class _ChildrenElementList implements ElementList {
final _HTMLCollectionImpl _childElements;
_ChildrenElementList._wrap(_ElementImpl element)
- : _childElements = element._children,
+ : _childElements = element.$dom_children,
_element = element;
List<Element> _toList() {
@@ -22,7 +22,7 @@ class _ChildrenElementList implements ElementList {
}
_ElementImpl get first() {
- return _element._firstElementChild;
+ return _element.$dom_firstElementChild;
}
void forEach(void f(Element element)) {
@@ -68,7 +68,7 @@ class _ChildrenElementList implements ElementList {
}
bool isEmpty() {
- return _element._firstElementChild == null;
+ return _element.$dom_firstElementChild == null;
}
int get length() {
@@ -80,7 +80,7 @@ class _ChildrenElementList implements ElementList {
}
void operator []=(int index, _ElementImpl value) {
- _element._replaceChild(value, _childElements[index]);
+ _element.$dom_replaceChild(value, _childElements[index]);
}
void set length(int newLength) {
@@ -89,7 +89,7 @@ class _ChildrenElementList implements ElementList {
}
Element add(_ElementImpl value) {
- _element._appendChild(value);
+ _element.$dom_appendChild(value);
return value;
}
@@ -99,7 +99,7 @@ class _ChildrenElementList implements ElementList {
void addAll(Collection<Element> collection) {
for (_ElementImpl element in collection) {
- _element._appendChild(element);
+ _element.$dom_appendChild(element);
}
}
@@ -144,13 +144,13 @@ class _ChildrenElementList implements ElementList {
Element removeLast() {
final last = this.last();
if (last != null) {
- _element._removeChild(last);
+ _element.$dom_removeChild(last);
}
return last;
}
Element last() {
- return _element.lastElementChild;
+ return _element.$dom_lastElementChild;
}
}
@@ -312,7 +312,7 @@ class ElementAttributeMap implements Map<String, String> {
ElementAttributeMap._wrap(this._element);
bool containsValue(String value) {
- final attributes = _element._attributes;
+ final attributes = _element.$dom_attributes;
for (int i = 0, len = attributes.length; i < len; i++) {
if(value == attributes[i].value) {
return true;
@@ -322,15 +322,15 @@ class ElementAttributeMap implements Map<String, String> {
}
bool containsKey(String key) {
- return _element._hasAttribute(key);
+ return _element.$dom_hasAttribute(key);
}
String operator [](String key) {
- return _element._getAttribute(key);
+ return _element.$dom_getAttribute(key);
}
void operator []=(String key, String value) {
- _element._setAttribute(key, value);
+ _element.$dom_setAttribute(key, value);
}
String putIfAbsent(String key, String ifAbsent()) {
@@ -340,18 +340,18 @@ class ElementAttributeMap implements Map<String, String> {
}
String remove(String key) {
- _element._removeAttribute(key);
+ _element.$dom_removeAttribute(key);
}
void clear() {
- final attributes = _element._attributes;
+ final attributes = _element.$dom_attributes;
for (int i = attributes.length - 1; i >= 0; i--) {
remove(attributes[i].name);
}
}
void forEach(void f(String key, String value)) {
- final attributes = _element._attributes;
+ final attributes = _element.$dom_attributes;
for (int i = 0, len = attributes.length; i < len; i++) {
final item = attributes[i];
f(item.name, item.value);
@@ -360,7 +360,7 @@ class ElementAttributeMap implements Map<String, String> {
Collection<String> getKeys() {
// TODO(jacobr): generate a lazy collection instead.
- final attributes = _element._attributes;
+ final attributes = _element.$dom_attributes;
final keys = new List<String>(attributes.length);
for (int i = 0, len = attributes.length; i < len; i++) {
keys[i] = attributes[i].name;
@@ -370,7 +370,7 @@ class ElementAttributeMap implements Map<String, String> {
Collection<String> getValues() {
// TODO(jacobr): generate a lazy collection instead.
- final attributes = _element._attributes;
+ final attributes = _element.$dom_attributes;
final values = new List<String>(attributes.length);
for (int i = 0, len = attributes.length; i < len; i++) {
values[i] = attributes[i].value;
@@ -382,7 +382,7 @@ class ElementAttributeMap implements Map<String, String> {
* The number of {key, value} pairs in the map.
*/
int get length() {
- return _element._attributes.length;
+ return _element.$dom_attributes.length;
}
/**
@@ -429,20 +429,20 @@ class _ElementRectImpl implements ElementRect {
final _ClientRectListImpl _clientRects;
_ElementRectImpl(_ElementImpl element) :
- client = new _SimpleClientRect(element._clientLeft,
- element._clientTop,
- element._clientWidth,
- element._clientHeight),
- offset = new _SimpleClientRect(element._offsetLeft,
- element._offsetTop,
- element._offsetWidth,
- element._offsetHeight),
- scroll = new _SimpleClientRect(element._scrollLeft,
- element._scrollTop,
- element._scrollWidth,
- element._scrollHeight),
- _boundingClientRect = element._getBoundingClientRect(),
- _clientRects = element._getClientRects();
+ client = new _SimpleClientRect(element.$dom_clientLeft,
+ element.$dom_clientTop,
+ element.$dom_clientWidth,
+ element.$dom_clientHeight),
+ offset = new _SimpleClientRect(element.$dom_offsetLeft,
+ element.$dom_offsetTop,
+ element.$dom_offsetWidth,
+ element.$dom_offsetHeight),
+ scroll = new _SimpleClientRect(element.$dom_scrollLeft,
+ element.$dom_scrollTop,
+ element.$dom_scrollWidth,
+ element.$dom_scrollHeight),
+ _boundingClientRect = element.$dom_getBoundingClientRect(),
+ _clientRects = element.$dom_getClientRects();
_ClientRectImpl get bounding() => _boundingClientRect;
@@ -491,7 +491,7 @@ class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
ElementList get elements() => new _ChildrenElementList._wrap(this);
ElementList queryAll(String selectors) =>
- new _FrozenElementList._wrap(_querySelectorAll(selectors));
+ new _FrozenElementList._wrap($dom_querySelectorAll(selectors));
Set<String> get classes() {
if (_cssClassSet === null) {
@@ -534,8 +534,70 @@ class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
Future<CSSStyleDeclaration> getComputedStyle(String pseudoElement) {
return _createMeasurementFuture(
- () => _window._getComputedStyle(this, pseudoElement),
+ () => _window.$dom_getComputedStyle(this, pseudoElement),
new Completer<CSSStyleDeclaration>());
}
$!MEMBERS
}
+
+final _START_TAG_REGEXP = const RegExp('<(\\w+)');
+class _ElementFactoryProvider {
+ static final _CUSTOM_PARENT_TAG_MAP = const {
+ 'body' : 'html',
+ 'head' : 'html',
+ 'caption' : 'table',
+ 'td': 'tr',
+ 'colgroup': 'table',
+ 'col' : 'colgroup',
+ 'tr' : 'tbody',
+ 'tbody' : 'table',
+ 'tfoot' : 'table',
+ 'thead' : 'table',
+ 'track' : 'audio',
+ };
+
+ /** @domName Document.createElement */
+ factory Element.html(String html) {
+ // TODO(jacobr): this method can be made more robust and performant.
+ // 1) Cache the dummy parent elements required to use innerHTML rather than
+ // creating them every call.
+ // 2) Verify that the html does not contain leading or trailing text nodes.
+ // 3) Verify that the html does not contain both <head> and <body> tags.
+ // 4) Detatch the created element from its dummy parent.
+ String parentTag = 'div';
+ String tag;
+ final match = _START_TAG_REGEXP.firstMatch(html);
+ if (match !== null) {
+ tag = match.group(1).toLowerCase();
+ if (_CUSTOM_PARENT_TAG_MAP.containsKey(tag)) {
+ parentTag = _CUSTOM_PARENT_TAG_MAP[tag];
+ }
+ }
+ final _ElementImpl temp = new Element.tag(parentTag);
+ temp.innerHTML = html;
+
+ Element element;
+ if (temp.elements.length == 1) {
+ element = temp.elements.first;
+ } else if (parentTag == 'html' && temp.elements.length == 2) {
+ // Work around for edge case in WebKit and possibly other browsers where
+ // both body and head elements are created even though the inner html
+ // only contains a head or body element.
+ element = temp.elements[tag == 'head' ? 0 : 1];
+ } else {
+ throw new IllegalArgumentException('HTML had ${temp.elements.length} ' +
+ 'top level elements but 1 expected');
+ }
+ element.remove();
+ return element;
+ }
+
+ /** @domName Document.createElement */
+$if FROG
+ // Optimization to improve performance until the frog compiler inlines this
+ // method.
+ factory Element.tag(String tag) native "return document.createElement(tag)";
+$else
+ factory Element.tag(String tag) => _document.$dom_createElement(tag);
+$endif
+}

Powered by Google App Engine
This is Rietveld 408576698