| 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
|
| +}
|
|
|