| OLD | NEW | 
| (Empty) |  | 
 |    1 // Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file | 
 |    2 // for details. All rights reserved. Use of this source code is governed by a | 
 |    3 // BSD-style license that can be found in the LICENSE file. | 
 |    4  | 
 |    5 class FilteredElementList implements ElementList { | 
 |    6   final Node _node; | 
 |    7   final NodeList _childNodes; | 
 |    8  | 
 |    9   FilteredElementList(Node node): _childNodes = node.nodes, _node = node; | 
 |   10  | 
 |   11   // We can't memoize this, since it's possible that children will be messed | 
 |   12   // with externally to this class. | 
 |   13   // | 
 |   14   // TODO(nweiz): Do we really need to copy the list to make the types work out? | 
 |   15   List<Element> get _filtered() => | 
 |   16     new List.from(_childNodes.filter((n) => n is Element)); | 
 |   17  | 
 |   18   // Don't use _filtered.first so we can short-circuit once we find an element. | 
 |   19   Element get first() { | 
 |   20     for (final node in _childNodes) { | 
 |   21       if (node is Element) { | 
 |   22         return node; | 
 |   23       } | 
 |   24     } | 
 |   25     return null; | 
 |   26   } | 
 |   27  | 
 |   28   void forEach(void f(Element element)) { | 
 |   29     _filtered.forEach(f); | 
 |   30   } | 
 |   31  | 
 |   32   void operator []=(int index, Element value) { | 
 |   33     this[index].replaceWith(value); | 
 |   34   } | 
 |   35  | 
 |   36   void set length(int newLength) { | 
 |   37     final len = this.length; | 
 |   38     if (newLength >= len) { | 
 |   39       return; | 
 |   40     } else if (newLength < 0) { | 
 |   41       throw const IllegalArgumentException("Invalid list length"); | 
 |   42     } | 
 |   43  | 
 |   44     removeRange(newLength - 1, len - newLength); | 
 |   45   } | 
 |   46  | 
 |   47   void add(Element value) { | 
 |   48     _childNodes.add(value); | 
 |   49   } | 
 |   50  | 
 |   51   void addAll(Collection<Element> collection) { | 
 |   52     collection.forEach(add); | 
 |   53   } | 
 |   54  | 
 |   55   void addLast(Element value) { | 
 |   56     add(value); | 
 |   57   } | 
 |   58  | 
 |   59   void sort(int compare(Element a, Element b)) { | 
 |   60     throw const UnsupportedOperationException('TODO(jacobr): should we impl?'); | 
 |   61   } | 
 |   62  | 
 |   63   void copyFrom(List<Object> src, int srcStart, int dstStart, int count) { | 
 |   64     throw const NotImplementedException(); | 
 |   65   } | 
 |   66  | 
 |   67   void setRange(int start, int length, List from, [int startFrom = 0]) { | 
 |   68     throw const NotImplementedException(); | 
 |   69   } | 
 |   70  | 
 |   71   void removeRange(int start, int length) { | 
 |   72     _filtered.getRange(start, length).forEach((el) => el.remove()); | 
 |   73   } | 
 |   74  | 
 |   75   void insertRange(int start, int length, [initialValue = null]) { | 
 |   76     throw const NotImplementedException(); | 
 |   77   } | 
 |   78  | 
 |   79   void clear() { | 
 |   80     // Currently, ElementList#clear clears even non-element nodes, so we follow | 
 |   81     // that behavior. | 
 |   82     _childNodes.clear(); | 
 |   83   } | 
 |   84  | 
 |   85   Element removeLast() { | 
 |   86     final last = this.last(); | 
 |   87     if (last != null) { | 
 |   88       last.remove(); | 
 |   89     } | 
 |   90     return last; | 
 |   91   } | 
 |   92  | 
 |   93   Collection map(f(Element element)) => _filtered.map(f); | 
 |   94   Collection<Element> filter(bool f(Element element)) => _filtered.filter(f); | 
 |   95   bool every(bool f(Element element)) => _filtered.every(f); | 
 |   96   bool some(bool f(Element element)) => _filtered.some(f); | 
 |   97   bool isEmpty() => _filtered.isEmpty(); | 
 |   98   int get length() => _filtered.length; | 
 |   99   Element operator [](int index) => _filtered[index]; | 
 |  100   Iterator<Element> iterator() => _filtered.iterator(); | 
 |  101   List<Element> getRange(int start, int length) => | 
 |  102     _filtered.getRange(start, length); | 
 |  103   int indexOf(Element element, [int start = 0]) => | 
 |  104     _filtered.indexOf(element, start); | 
 |  105  | 
 |  106   int lastIndexOf(Element element, [int start = null]) { | 
 |  107     if (start === null) start = length - 1; | 
 |  108     return _filtered.lastIndexOf(element, start); | 
 |  109   } | 
 |  110  | 
 |  111   Element last() => _filtered.last(); | 
 |  112 } | 
 |  113  | 
 |  114 Future<CSSStyleDeclaration> _emptyStyleFuture() { | 
 |  115   return _createMeasurementFuture(() => new Element.tag('div').style, | 
 |  116                                   new Completer<CSSStyleDeclaration>()); | 
 |  117 } | 
 |  118  | 
 |  119 class EmptyElementRect implements ElementRect { | 
 |  120   final ClientRect client = const _SimpleClientRect(0, 0, 0, 0); | 
 |  121   final ClientRect offset = const _SimpleClientRect(0, 0, 0, 0); | 
 |  122   final ClientRect scroll = const _SimpleClientRect(0, 0, 0, 0); | 
 |  123   final ClientRect bounding = const _SimpleClientRect(0, 0, 0, 0); | 
 |  124   final List<ClientRect> clientRects = const <ClientRect>[]; | 
 |  125  | 
 |  126   const EmptyElementRect(); | 
 |  127 } | 
 |  128  | 
 |  129 class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC { | 
 |  130   ElementList _elements; | 
 |  131  | 
 |  132   ElementList get elements() { | 
 |  133     if (_elements == null) { | 
 |  134       _elements = new FilteredElementList(this); | 
 |  135     } | 
 |  136     return _elements; | 
 |  137   } | 
 |  138  | 
 |  139   // TODO: The type of value should be Collection<Element>. See http://b/5392897 | 
 |  140   void set elements(value) { | 
 |  141     // Copy list first since we don't want liveness during iteration. | 
 |  142     List copy = new List.from(value); | 
 |  143     final elements = this.elements; | 
 |  144     elements.clear(); | 
 |  145     elements.addAll(copy); | 
 |  146   } | 
 |  147  | 
 |  148   ElementList queryAll(String selectors) => | 
 |  149     new _FrozenElementList._wrap(_querySelectorAll(selectors)); | 
 |  150  | 
 |  151   String get innerHTML() { | 
 |  152     final e = new Element.tag("div"); | 
 |  153     e.nodes.add(this.clone(true)); | 
 |  154     return e.innerHTML; | 
 |  155   } | 
 |  156  | 
 |  157   String get outerHTML() => innerHTML; | 
 |  158  | 
 |  159   // TODO(nweiz): Do we want to support some variant of innerHTML for XML and/or | 
 |  160   // SVG strings? | 
 |  161   void set innerHTML(String value) { | 
 |  162     this.nodes.clear(); | 
 |  163  | 
 |  164     final e = new Element.tag("div"); | 
 |  165     e.innerHTML = value; | 
 |  166  | 
 |  167     // Copy list first since we don't want liveness during iteration. | 
 |  168     List nodes = new List.from(e.nodes); | 
 |  169     this.nodes.addAll(nodes); | 
 |  170   } | 
 |  171  | 
 |  172   Node _insertAdjacentNode(String where, Node node) { | 
 |  173     switch (where.toLowerCase()) { | 
 |  174       case "beforebegin": return null; | 
 |  175       case "afterend": return null; | 
 |  176       case "afterbegin": | 
 |  177         this.insertBefore(node, this.nodes.first); | 
 |  178         return node; | 
 |  179       case "beforeend": | 
 |  180         this.nodes.add(node); | 
 |  181         return node; | 
 |  182       default: | 
 |  183         throw new IllegalArgumentException("Invalid position ${where}"); | 
 |  184     } | 
 |  185   } | 
 |  186  | 
 |  187   Element insertAdjacentElement(String where, Element element) | 
 |  188     => this._insertAdjacentNode(where, element); | 
 |  189  | 
 |  190   void insertAdjacentText(String where, String text) { | 
 |  191     this._insertAdjacentNode(where, new Text(text)); | 
 |  192   } | 
 |  193  | 
 |  194   void insertAdjacentHTML(String where, String text) { | 
 |  195     this._insertAdjacentNode(where, new DocumentFragment.html(text)); | 
 |  196   } | 
 |  197  | 
 |  198   Future<ElementRect> get rect() { | 
 |  199     return _createMeasurementFuture(() => const EmptyElementRect(), | 
 |  200                                     new Completer<ElementRect>()); | 
 |  201   } | 
 |  202  | 
 |  203   // If we can come up with a semi-reasonable default value for an Element | 
 |  204   // getter, we'll use it. In general, these return the same values as an | 
 |  205   // element that has no parent. | 
 |  206   String get contentEditable() => "false"; | 
 |  207   bool get isContentEditable() => false; | 
 |  208   bool get draggable() => false; | 
 |  209   bool get hidden() => false; | 
 |  210   bool get spellcheck() => false; | 
 |  211   bool get translate() => false; | 
 |  212   int get tabIndex() => -1; | 
 |  213   String get id() => ""; | 
 |  214   String get title() => ""; | 
 |  215   String get tagName() => ""; | 
 |  216   String get webkitdropzone() => ""; | 
 |  217   String get webkitRegionOverflow() => ""; | 
 |  218   Element get firstElementChild() => elements.first(); | 
 |  219   Element get lastElementChild() => elements.last(); | 
 |  220   Element get nextElementSibling() => null; | 
 |  221   Element get previousElementSibling() => null; | 
 |  222   Element get offsetParent() => null; | 
 |  223   Element get parent() => null; | 
 |  224   Map<String, String> get attributes() => const {}; | 
 |  225   // Issue 174: this should be a const set. | 
 |  226   Set<String> get classes() => new Set<String>(); | 
 |  227   Map<String, String> get dataAttributes() => const {}; | 
 |  228   CSSStyleDeclaration get style() => new Element.tag('div').style; | 
 |  229   Future<CSSStyleDeclaration> get computedStyle() => | 
 |  230       _emptyStyleFuture(); | 
 |  231   Future<CSSStyleDeclaration> getComputedStyle(String pseudoElement) => | 
 |  232       _emptyStyleFuture(); | 
 |  233   bool matchesSelector(String selectors) => false; | 
 |  234  | 
 |  235   // Imperative Element methods are made into no-ops, as they are on parentless | 
 |  236   // elements. | 
 |  237   void blur() {} | 
 |  238   void focus() {} | 
 |  239   void click() {} | 
 |  240   void scrollByLines(int lines) {} | 
 |  241   void scrollByPages(int pages) {} | 
 |  242   void scrollIntoView([bool centerIfNeeded]) {} | 
 |  243   void webkitRequestFullScreen(int flags) {} | 
 |  244  | 
 |  245   // Setters throw errors rather than being no-ops because we aren't going to | 
 |  246   // retain the values that were set, and erroring out seems clearer. | 
 |  247   void set attributes(Map<String, String> value) { | 
 |  248     throw new UnsupportedOperationException( | 
 |  249       "Attributes can't be set for document fragments."); | 
 |  250   } | 
 |  251  | 
 |  252   void set classes(Collection<String> value) { | 
 |  253     throw new UnsupportedOperationException( | 
 |  254       "Classes can't be set for document fragments."); | 
 |  255   } | 
 |  256  | 
 |  257   void set dataAttributes(Map<String, String> value) { | 
 |  258     throw new UnsupportedOperationException( | 
 |  259       "Data attributes can't be set for document fragments."); | 
 |  260   } | 
 |  261  | 
 |  262   void set contentEditable(String value) { | 
 |  263     throw new UnsupportedOperationException( | 
 |  264       "Content editable can't be set for document fragments."); | 
 |  265   } | 
 |  266  | 
 |  267   String get dir() { | 
 |  268     throw new UnsupportedOperationException( | 
 |  269       "Document fragments don't support text direction."); | 
 |  270   } | 
 |  271  | 
 |  272   void set dir(String value) { | 
 |  273     throw new UnsupportedOperationException( | 
 |  274       "Document fragments don't support text direction."); | 
 |  275   } | 
 |  276  | 
 |  277   void set draggable(bool value) { | 
 |  278     throw new UnsupportedOperationException( | 
 |  279       "Draggable can't be set for document fragments."); | 
 |  280   } | 
 |  281  | 
 |  282   void set hidden(bool value) { | 
 |  283     throw new UnsupportedOperationException( | 
 |  284       "Hidden can't be set for document fragments."); | 
 |  285   } | 
 |  286  | 
 |  287   void set id(String value) { | 
 |  288     throw new UnsupportedOperationException( | 
 |  289       "ID can't be set for document fragments."); | 
 |  290   } | 
 |  291  | 
 |  292   String get lang() { | 
 |  293     throw new UnsupportedOperationException( | 
 |  294       "Document fragments don't support language."); | 
 |  295   } | 
 |  296  | 
 |  297   void set lang(String value) { | 
 |  298     throw new UnsupportedOperationException( | 
 |  299       "Document fragments don't support language."); | 
 |  300   } | 
 |  301  | 
 |  302   void set scrollLeft(int value) { | 
 |  303     throw new UnsupportedOperationException( | 
 |  304       "Document fragments don't support scrolling."); | 
 |  305   } | 
 |  306  | 
 |  307   void set scrollTop(int value) { | 
 |  308     throw new UnsupportedOperationException( | 
 |  309       "Document fragments don't support scrolling."); | 
 |  310   } | 
 |  311  | 
 |  312   void set spellcheck(bool value) { | 
 |  313      throw new UnsupportedOperationException( | 
 |  314       "Spellcheck can't be set for document fragments."); | 
 |  315   } | 
 |  316  | 
 |  317   void set translate(bool value) { | 
 |  318      throw new UnsupportedOperationException( | 
 |  319       "Spellcheck can't be set for document fragments."); | 
 |  320   } | 
 |  321  | 
 |  322   void set tabIndex(int value) { | 
 |  323     throw new UnsupportedOperationException( | 
 |  324       "Tab index can't be set for document fragments."); | 
 |  325   } | 
 |  326  | 
 |  327   void set title(String value) { | 
 |  328     throw new UnsupportedOperationException( | 
 |  329       "Title can't be set for document fragments."); | 
 |  330   } | 
 |  331  | 
 |  332   void set webkitdropzone(String value) { | 
 |  333     throw new UnsupportedOperationException( | 
 |  334       "WebKit drop zone can't be set for document fragments."); | 
 |  335   } | 
 |  336  | 
 |  337   void set webkitRegionOverflow(String value) { | 
 |  338     throw new UnsupportedOperationException( | 
 |  339       "WebKit region overflow can't be set for document fragments."); | 
 |  340   } | 
 |  341  | 
 |  342 $!MEMBERS | 
 |  343 } | 
| OLD | NEW |