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

Side by Side Diff: tools/dom/templates/html/impl/impl_Element.darttemplate

Issue 1349493003: Dartium JS Interop enabled. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 3 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of $LIBRARYNAME; 5 part of $LIBRARYNAME;
6 6
7 class _ChildrenElementList extends ListBase<Element> 7 class _ChildrenElementList extends ListBase<Element>
8 implements NodeListWrapper { 8 implements NodeListWrapper {
9 // Raw Element. 9 // Raw Element.
10 final Element _element; 10 final Element _element;
(...skipping 15 matching lines...) Expand all
26 } 26 }
27 27
28 Element operator [](int index) { 28 Element operator [](int index) {
29 return _childElements[index]; 29 return _childElements[index];
30 } 30 }
31 31
32 void operator []=(int index, Element value) { 32 void operator []=(int index, Element value) {
33 _element._replaceChild(value, _childElements[index]); 33 _element._replaceChild(value, _childElements[index]);
34 } 34 }
35 35
36 void set length(int newLength) { 36 set length(int newLength) {
37 // TODO(jacobr): remove children when length is reduced. 37 // TODO(jacobr): remove children when length is reduced.
38 throw new UnsupportedError('Cannot resize element lists'); 38 throw new UnsupportedError('Cannot resize element lists');
39 } 39 }
40 40
41 Element add(Element value) { 41 Element add(Element value) {
42 _element.append(value); 42 _element.append(value);
43 return value; 43 return value;
44 } 44 }
45 45
46 Iterator<Element> get iterator => toList().iterator; 46 Iterator<Element> get iterator => toList().iterator;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 throw new UnimplementedError(); 90 throw new UnimplementedError();
91 } 91 }
92 92
93 void fillRange(int start, int end, [Element fillValue]) { 93 void fillRange(int start, int end, [Element fillValue]) {
94 throw new UnimplementedError(); 94 throw new UnimplementedError();
95 } 95 }
96 96
97 bool remove(Object object) { 97 bool remove(Object object) {
98 if (object is Element) { 98 if (object is Element) {
99 Element element = object; 99 Element element = object;
100 $if JSINTEROP
101 // We aren't preserving identity of nodes in JSINTEROP mode
102 if (element.parentNode == _element) {
103 $else
100 if (identical(element.parentNode, _element)) { 104 if (identical(element.parentNode, _element)) {
105 $endif
101 _element._removeChild(element); 106 _element._removeChild(element);
102 return true; 107 return true;
103 } 108 }
104 } 109 }
105 return false; 110 return false;
106 } 111 }
107 112
108 void insert(int index, Element element) { 113 void insert(int index, Element element) {
109 if (index < 0 || index > length) { 114 if (index < 0 || index > length) {
110 throw new RangeError.range(index, 0, length); 115 throw new RangeError.range(index, 0, length);
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 $endif 279 $endif
275 280
276 int get length => _nodeList.length; 281 int get length => _nodeList.length;
277 282
278 Element operator [](int index) => _nodeList[index]; 283 Element operator [](int index) => _nodeList[index];
279 284
280 void operator []=(int index, Element value) { 285 void operator []=(int index, Element value) {
281 throw new UnsupportedError('Cannot modify list'); 286 throw new UnsupportedError('Cannot modify list');
282 } 287 }
283 288
284 void set length(int newLength) { 289 set length(int newLength) {
285 throw new UnsupportedError('Cannot modify list'); 290 throw new UnsupportedError('Cannot modify list');
286 } 291 }
287 292
288 void sort([Comparator<Element> compare]) { 293 void sort([Comparator<Element> compare]) {
289 throw new UnsupportedError('Cannot sort list'); 294 throw new UnsupportedError('Cannot sort list');
290 } 295 }
291 296
292 void shuffle([Random random]) { 297 void shuffle([Random random]) {
293 throw new UnsupportedError('Cannot shuffle list'); 298 throw new UnsupportedError('Cannot shuffle list');
294 } 299 }
295 300
296 Element get first => _nodeList.first; 301 Element get first => _nodeList.first;
297 302
298 Element get last => _nodeList.last; 303 Element get last => _nodeList.last;
299 304
300 Element get single => _nodeList.single; 305 Element get single => _nodeList.single;
301 306
302 CssClassSet get classes => new _MultiElementCssClassSet(this); 307 CssClassSet get classes => new _MultiElementCssClassSet(this);
303 308
304 CssStyleDeclarationBase get style => 309 CssStyleDeclarationBase get style =>
305 new _CssStyleDeclarationSet(this); 310 new _CssStyleDeclarationSet(this);
306 311
307 void set classes(Iterable<String> value) { 312 set classes(Iterable<String> value) {
308 // TODO(sra): This might be faster for Sets: 313 // TODO(sra): This might be faster for Sets:
309 // 314 //
310 // new _MultiElementCssClassSet(this).writeClasses(value) 315 // new _MultiElementCssClassSet(this).writeClasses(value)
311 // 316 //
312 // as the code below converts the Iterable[value] to a string multiple 317 // as the code below converts the Iterable[value] to a string multiple
313 // times. Maybe compute the string and set className here. 318 // times. Maybe compute the string and set className here.
314 _nodeList.forEach((e) => e.classes = value); 319 _nodeList.forEach((e) => e.classes = value);
315 } 320 }
316 321
317 CssRect get contentEdge => new _ContentCssListRect(this); 322 CssRect get contentEdge => new _ContentCssListRect(this);
318 323
319 CssRect get paddingEdge => this.first.paddingEdge; 324 CssRect get paddingEdge => this.first.paddingEdge;
320 325
321 CssRect get borderEdge => this.first.borderEdge; 326 CssRect get borderEdge => this.first.borderEdge;
322 327
323 CssRect get marginEdge => this.first.marginEdge; 328 CssRect get marginEdge => this.first.marginEdge;
324 329
325 List<Node> get rawList => _nodeList; 330 List<Node> get rawList => _nodeList;
326 331
327 $!ELEMENT_STREAM_GETTERS 332 $!ELEMENT_STREAM_GETTERS
328 } 333 }
329 334
330 @DocsEditable() 335 @DocsEditable()
331 $(ANNOTATIONS)$(NATIVESPEC)abstract class $CLASSNAME$EXTENDS$IMPLEMENTS { 336 $(ANNOTATIONS)$(NATIVESPEC)class $CLASSNAME$EXTENDS$IMPLEMENTS {
332 337
333 /** 338 /**
334 * Creates an HTML element from a valid fragment of HTML. 339 * Creates an HTML element from a valid fragment of HTML.
335 * 340 *
336 * var element = new Element.html('<div class="foo">content</div>'); 341 * var element = new Element.html('<div class="foo">content</div>');
337 * 342 *
338 * The HTML fragment should contain only one single root element, any 343 * The HTML fragment should contain only one single root element, any
339 * leading or trailing text nodes will be removed. 344 * leading or trailing text nodes will be removed.
340 * 345 *
341 * The HTML fragment is parsed as if it occurred within the context of a 346 * The HTML fragment is parsed as if it occurred within the context of a
(...skipping 26 matching lines...) Expand all
368 * 373 *
369 * class CustomElement extends Element { 374 * class CustomElement extends Element {
370 * factory CustomElement() => new Element.tag('x-custom'); 375 * factory CustomElement() => new Element.tag('x-custom');
371 * 376 *
372 * CustomElement.created() : super.created() { 377 * CustomElement.created() : super.created() {
373 * // Perform any element initialization. 378 * // Perform any element initialization.
374 * } 379 * }
375 * } 380 * }
376 * document.registerElement('x-custom', CustomElement); 381 * document.registerElement('x-custom', CustomElement);
377 */ 382 */
378 Element.created() : super._created() { 383 Element.created() : super._created();
379 // Validate that this is a custom element & perform any additional
380 // initialization.
381 _initializeCustomElement(this);
382 }
383 384
384 /** 385 /**
385 * Creates the HTML element specified by the tag name. 386 * Creates the HTML element specified by the tag name.
386 * 387 *
387 * This is similar to [Document.createElement]. 388 * This is similar to [Document.createElement].
388 * [tag] should be a valid HTML tag name. If [tag] is an unknown tag then 389 * [tag] should be a valid HTML tag name. If [tag] is an unknown tag then
389 * this will create an [UnknownElement]. 390 * this will create an [UnknownElement].
390 * 391 *
391 * var divElement = new Element.tag('div'); 392 * var divElement = new Element.tag('div');
392 * print(divElement is DivElement); // 'true' 393 * print(divElement is DivElement); // 'true'
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
553 * 554 *
554 * Any modifications to the attribute map will automatically be applied to 555 * Any modifications to the attribute map will automatically be applied to
555 * this element. 556 * this element.
556 * 557 *
557 * This only includes attributes which are not in a namespace 558 * This only includes attributes which are not in a namespace
558 * (such as 'xlink:href'), additional attributes can be accessed via 559 * (such as 'xlink:href'), additional attributes can be accessed via
559 * [getNamespacedAttributes]. 560 * [getNamespacedAttributes].
560 */ 561 */
561 Map<String, String> get attributes => new _ElementAttributeMap(this); 562 Map<String, String> get attributes => new _ElementAttributeMap(this);
562 563
563 void set attributes(Map<String, String> value) { 564 set attributes(Map<String, String> value) {
564 Map<String, String> attributes = this.attributes; 565 Map<String, String> attributes = this.attributes;
565 attributes.clear(); 566 attributes.clear();
566 for (String key in value.keys) { 567 for (String key in value.keys) {
567 attributes[key] = value[key]; 568 attributes[key] = value[key];
568 } 569 }
569 } 570 }
570 571
571 /** 572 /**
572 * List of the direct children of this element. 573 * List of the direct children of this element.
573 * 574 *
574 * This collection can be used to add and remove elements from the document. 575 * This collection can be used to add and remove elements from the document.
575 * 576 *
576 * var item = new DivElement(); 577 * var item = new DivElement();
577 * item.text = 'Something'; 578 * item.text = 'Something';
578 * document.body.children.add(item) // Item is now displayed on the page. 579 * document.body.children.add(item) // Item is now displayed on the page.
579 * for (var element in document.body.children) { 580 * for (var element in document.body.children) {
580 * element.style.background = 'red'; // Turns every child of body red. 581 * element.style.background = 'red'; // Turns every child of body red.
581 * } 582 * }
582 */ 583 */
583 $if DART2JS
584 List<Element> get children => new _ChildrenElementList._wrap(this); 584 List<Element> get children => new _ChildrenElementList._wrap(this);
585 $else
586 $if JSINTEROP
587 List<Element> get children => new FilteredElementList(this);
588 $else
589 List<Element> get children => new _ChildrenElementList._wrap(this);
590 $endif
591 $endif
592 585
593 void set children(List<Element> value) { 586 set children(List<Element> value) {
594 // Copy list first since we don't want liveness during iteration. 587 // Copy list first since we don't want liveness during iteration.
595 List copy = new List.from(value); 588 List copy = new List.from(value);
596 var children = this.children; 589 var children = this.children;
597 children.clear(); 590 children.clear();
598 children.addAll(copy); 591 children.addAll(copy);
599 } 592 }
600 593
601 /** 594 /**
602 * Finds all descendent elements of this element that match the specified 595 * Finds all descendent elements of this element that match the specified
603 * group of selectors. 596 * group of selectors.
604 * 597 *
605 * [selectors] should be a string using CSS selector syntax. 598 * [selectors] should be a string using CSS selector syntax.
606 * 599 *
607 * var items = element.querySelectorAll('.itemClassName'); 600 * var items = element.querySelectorAll('.itemClassName');
608 * 601 *
609 * For details about CSS selector syntax, see the 602 * For details about CSS selector syntax, see the
610 * [CSS selector specification](http://www.w3.org/TR/css3-selectors/). 603 * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
611 */ 604 */
612 @DomName('Element.querySelectorAll') 605 @DomName('Element.querySelectorAll')
613 ElementList<Element> querySelectorAll(String selectors) => 606 ElementList<Element> querySelectorAll(String selectors) =>
614 $if JSINTEROP
615 _querySelectorAll(selectors);
616 $else
617 new _FrozenElementList._wrap(_querySelectorAll(selectors)); 607 new _FrozenElementList._wrap(_querySelectorAll(selectors));
618 $endif
619 608
620 /** 609 /**
621 * Alias for [querySelector]. Note this function is deprecated because its 610 * Alias for [querySelector]. Note this function is deprecated because its
622 * semantics will be changing in the future. 611 * semantics will be changing in the future.
623 */ 612 */
624 @deprecated 613 @deprecated
625 @DomName('Element.querySelector') 614 @DomName('Element.querySelector')
626 @Experimental() 615 @Experimental()
627 Element query(String relativeSelectors) => querySelector(relativeSelectors); 616 Element query(String relativeSelectors) => querySelector(relativeSelectors);
628 617
(...skipping 12 matching lines...) Expand all
641 * 630 *
642 * This set makes it easy to add, remove or toggle the classes applied to 631 * This set makes it easy to add, remove or toggle the classes applied to
643 * this element. 632 * this element.
644 * 633 *
645 * element.classes.add('selected'); 634 * element.classes.add('selected');
646 * element.classes.toggle('isOnline'); 635 * element.classes.toggle('isOnline');
647 * element.classes.remove('selected'); 636 * element.classes.remove('selected');
648 */ 637 */
649 CssClassSet get classes => new _ElementCssClassSet(this); 638 CssClassSet get classes => new _ElementCssClassSet(this);
650 639
651 void set classes(Iterable<String> value) { 640 set classes(Iterable<String> value) {
652 // TODO(sra): Do this without reading the classes in clear() and addAll(), 641 // TODO(sra): Do this without reading the classes in clear() and addAll(),
653 // or writing the classes in clear(). 642 // or writing the classes in clear().
654 CssClassSet classSet = classes; 643 CssClassSet classSet = classes;
655 classSet.clear(); 644 classSet.clear();
656 classSet.addAll(value); 645 classSet.addAll(value);
657 } 646 }
658 647
659 /** 648 /**
660 * Allows access to all custom data attributes (data-*) set on this element. 649 * Allows access to all custom data attributes (data-*) set on this element.
661 * 650 *
(...skipping 13 matching lines...) Expand all
675 * 664 *
676 * var value = element.dataset['myRandomValue']; 665 * var value = element.dataset['myRandomValue'];
677 * 666 *
678 * See also: 667 * See also:
679 * 668 *
680 * * [Custom data attributes](http://www.w3.org/TR/html5/global-attributes.htm l#custom-data-attribute) 669 * * [Custom data attributes](http://www.w3.org/TR/html5/global-attributes.htm l#custom-data-attribute)
681 */ 670 */
682 Map<String, String> get dataset => 671 Map<String, String> get dataset =>
683 new _DataAttributeMap(attributes); 672 new _DataAttributeMap(attributes);
684 673
685 void set dataset(Map<String, String> value) { 674 set dataset(Map<String, String> value) {
686 final data = this.dataset; 675 final data = this.dataset;
687 data.clear(); 676 data.clear();
688 for (String key in value.keys) { 677 for (String key in value.keys) {
689 data[key] = value[key]; 678 data[key] = value[key];
690 } 679 }
691 } 680 }
692 681
693 /** 682 /**
694 * Gets a map for manipulating the attributes of a particular namespace. 683 * Gets a map for manipulating the attributes of a particular namespace.
695 * 684 *
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 /** *Deprecated*: override [attached] instead. */ 783 /** *Deprecated*: override [attached] instead. */
795 @Experimental() 784 @Experimental()
796 @deprecated 785 @deprecated
797 void enteredView() {} 786 void enteredView() {}
798 787
799 /** *Deprecated*: override [detached] instead. */ 788 /** *Deprecated*: override [detached] instead. */
800 @Experimental() 789 @Experimental()
801 @deprecated 790 @deprecated
802 void leftView() {} 791 void leftView() {}
803 792
804 $if DART2JS
805 /** 793 /**
806 * Creates a new AnimationEffect object whose target element is the object 794 * Creates a new AnimationEffect object whose target element is the object
807 * on which the method is called, and calls the play() method of the 795 * on which the method is called, and calls the play() method of the
808 * AnimationTimeline object of the document timeline of the node document 796 * AnimationTimeline object of the document timeline of the node document
809 * of the element, passing the newly created AnimationEffect as the argument 797 * of the element, passing the newly created AnimationEffect as the argument
810 * to the method. Returns an AnimationPlayer for the effect. 798 * to the method. Returns an AnimationPlayer for the effect.
811 * 799 *
812 * Examples 800 * Examples
813 * 801 *
814 * var animation = elem.animate([{"opacity": 75}, {"opacity": 0}], 200); 802 * var animation = elem.animate([{"opacity": 75}, {"opacity": 0}], 200);
815 * 803 *
816 * var animation = elem.animate([ 804 * var animation = elem.animate([
817 * {"transform": "translate(100px, -100%)"}, 805 * {"transform": "translate(100px, -100%)"},
818 * {"transform" : "translate(400px, 500px)"} 806 * {"transform" : "translate(400px, 500px)"}
819 * ], 1500); 807 * ], 1500);
820 * 808 *
821 * The [frames] parameter is an Iterable<Map>, where the 809 * The [frames] parameter is an Iterable<Map>, where the
822 * map entries specify CSS animation effects. The 810 * map entries specify CSS animation effects. The
823 * [timing] paramter can be a double, representing the number of milliseconds 811 * [timing] paramter can be a double, representing the number of milliseconds
824 * for the transition, or a Map with fields corresponding to those 812 * for the transition, or a Map with fields corresponding to those
825 * of the [Timing] object. 813 * of the [Timing] object.
826 *
827 * This is not yet supported in Dartium.
828 **/ 814 **/
829 // TODO(alanknight): Correct above comment once it works in Dartium. 815 @Experimental()
830 @Experimental
831 @SupportedBrowser(SupportedBrowser.CHROME, '36') 816 @SupportedBrowser(SupportedBrowser.CHROME, '36')
832 AnimationPlayer animate(Iterable<Map<String, dynamic>> frames, [timing]) { 817 AnimationPlayer animate(Iterable<Map<String, dynamic>> frames, [timing]) {
833 if (frames is! Iterable || !(frames.every((x) => x is Map))) { 818 if (frames is! Iterable || !(frames.every((x) => x is Map))) {
834 throw new ArgumentError("The frames parameter should be a List of Maps " 819 throw new ArgumentError("The frames parameter should be a List of Maps "
835 "with frame information"); 820 "with frame information");
836 } 821 }
837 var convertedFrames = frames; 822 var convertedFrames = frames;
838 if (convertedFrames is Iterable) { 823 if (convertedFrames is Iterable) {
839 convertedFrames = frames.map(convertDartToNative_Dictionary).toList(); 824 convertedFrames = convertDartToNative_List(
825 frames.map(convertDartToNative_Dictionary).toList());
840 } 826 }
841 var convertedTiming = timing; 827 var convertedTiming = timing;
842 if (convertedTiming is Map) { 828 if (convertedTiming is Map) {
843 convertedTiming = convertDartToNative_Dictionary(convertedTiming); 829 convertedTiming = convertDartToNative_Dictionary(convertedTiming);
844 } 830 }
845 return convertedTiming == null 831 return convertedTiming == null
846 ? _animate(convertedFrames) 832 ? _animate(convertedFrames)
847 : _animate(convertedFrames, convertedTiming); 833 : _animate(convertedFrames, convertedTiming);
848 } 834 }
849 835
836 $if DART2JS
850 @DomName('Element.animate') 837 @DomName('Element.animate')
851 @JSName('animate') 838 @JSName('animate')
852 @Experimental() // untriaged 839 @Experimental() // untriaged
853 AnimationPlayer _animate(Object effect, [timing]) native; 840 AnimationPlayer _animate(Object effect, [timing]) native;
854 $endif 841 $endif
855 /** 842 /**
856 * Called by the DOM whenever an attribute on this has been changed. 843 * Called by the DOM whenever an attribute on this has been changed.
857 */ 844 */
858 void attributeChanged(String name, String oldValue, String newValue) {} 845 void attributeChanged(String name, String oldValue, String newValue) {}
859 846
(...skipping 13 matching lines...) Expand all
873 * 860 *
874 * If xtag has not been set, it will simply return `this` [Element]. 861 * If xtag has not been set, it will simply return `this` [Element].
875 * 862 *
876 * [wc]: http://dvcs.w3.org/hg/webcomponents/raw-file/tip/explainer/index.html 863 * [wc]: http://dvcs.w3.org/hg/webcomponents/raw-file/tip/explainer/index.html
877 * [x-tags]: http://x-tags.org/ 864 * [x-tags]: http://x-tags.org/
878 */ 865 */
879 // Note: return type is `dynamic` for convenience to suppress warnings when 866 // Note: return type is `dynamic` for convenience to suppress warnings when
880 // members of the component are used. The actual type is a subtype of Element. 867 // members of the component are used. The actual type is a subtype of Element.
881 get xtag => _xtag != null ? _xtag : this; 868 get xtag => _xtag != null ? _xtag : this;
882 869
883 void set xtag(Element value) { 870 set xtag(Element value) {
884 _xtag = value; 871 _xtag = value;
885 } 872 }
886 873
887 @DomName('Element.localName') 874 @DomName('Element.localName')
888 @DocsEditable() 875 @DocsEditable()
889 $if DART2JS 876 $if DART2JS
890 @Returns('String') 877 @Returns('String')
891 // Non-null for Elements. 878 // Non-null for Elements.
892 String get localName => JS('String', '#', _localName); 879 String get localName => JS('String', '#', _localName);
893 $else 880 $else
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
999 void insertAdjacentText(String where, String text) { 986 void insertAdjacentText(String where, String text) {
1000 if (JS('bool', '!!#.insertAdjacentText', this)) { 987 if (JS('bool', '!!#.insertAdjacentText', this)) {
1001 _insertAdjacentText(where, text); 988 _insertAdjacentText(where, text);
1002 } else { 989 } else {
1003 _insertAdjacentNode(where, new Text(text)); 990 _insertAdjacentNode(where, new Text(text));
1004 } 991 }
1005 } 992 }
1006 993
1007 @JSName('insertAdjacentText') 994 @JSName('insertAdjacentText')
1008 void _insertAdjacentText(String where, String text) native; 995 void _insertAdjacentText(String where, String text) native;
1009 996
1010 $else 997 $else
1011 $endif 998 $endif
1012 999
1013 /** 1000 /**
1014 * Parses text as an HTML fragment and inserts it into the DOM at the 1001 * Parses text as an HTML fragment and inserts it into the DOM at the
1015 * specified location. 1002 * specified location.
1016 * 1003 *
1017 * The [where] parameter indicates where to insert the HTML fragment: 1004 * The [where] parameter indicates where to insert the HTML fragment:
1018 * 1005 *
1019 * * 'beforeBegin': Immediately before this element. 1006 * * 'beforeBegin': Immediately before this element.
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
1262 @Experimental() 1249 @Experimental()
1263 Point offsetTo(Element parent) { 1250 Point offsetTo(Element parent) {
1264 return Element._offsetToHelper(this, parent); 1251 return Element._offsetToHelper(this, parent);
1265 } 1252 }
1266 1253
1267 static Point _offsetToHelper(Element current, Element parent) { 1254 static Point _offsetToHelper(Element current, Element parent) {
1268 // We're hopping from _offsetParent_ to offsetParent (not just parent), so 1255 // We're hopping from _offsetParent_ to offsetParent (not just parent), so
1269 // offsetParent, "tops out" at BODY. But people could conceivably pass in 1256 // offsetParent, "tops out" at BODY. But people could conceivably pass in
1270 // the document.documentElement and I want it to return an absolute offset, 1257 // the document.documentElement and I want it to return an absolute offset,
1271 // so we have the special case checking for HTML. 1258 // so we have the special case checking for HTML.
1272 bool foundAsParent = identical(current, parent) || parent.tagName == 'HTML'; 1259 $if JSINTEROP
1273 if (current == null || identical(current, parent)) { 1260 bool sameAsParent = current == parent;
1261 $else
1262 bool sameAsParent = identical(current, parent);
1263 $endif
1264 bool foundAsParent = sameAsParent || parent.tagName == 'HTML';
1265 if (current == null || sameAsParent) {
1274 if (foundAsParent) return new Point(0, 0); 1266 if (foundAsParent) return new Point(0, 0);
1275 throw new ArgumentError("Specified element is not a transitive offset " 1267 throw new ArgumentError("Specified element is not a transitive offset "
1276 "parent of this element."); 1268 "parent of this element.");
1277 } 1269 }
1278 Element parentOffset = current.offsetParent; 1270 Element parentOffset = current.offsetParent;
1279 Point p = Element._offsetToHelper(parentOffset, parent); 1271 Point p = Element._offsetToHelper(parentOffset, parent);
1280 return new Point(p.x + current.offsetLeft, p.y + current.offsetTop); 1272 return new Point(p.x + current.offsetLeft, p.y + current.offsetTop);
1281 } 1273 }
1282 1274
1283 static HtmlDocument _parseDocument; 1275 static HtmlDocument _parseDocument;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1321 } 1313 }
1322 treeSanitizer = _defaultSanitizer; 1314 treeSanitizer = _defaultSanitizer;
1323 } else if (validator != null) { 1315 } else if (validator != null) {
1324 throw new ArgumentError( 1316 throw new ArgumentError(
1325 'validator can only be passed if treeSanitizer is null'); 1317 'validator can only be passed if treeSanitizer is null');
1326 } 1318 }
1327 1319
1328 if (_parseDocument == null) { 1320 if (_parseDocument == null) {
1329 _parseDocument = document.implementation.createHtmlDocument(''); 1321 _parseDocument = document.implementation.createHtmlDocument('');
1330 _parseRange = _parseDocument.createRange(); 1322 _parseRange = _parseDocument.createRange();
1331 » 1323
1332 // Workaround for Safari bug. Was also previously Chrome bug 229142 1324 // Workaround for Safari bug. Was also previously Chrome bug 229142
1333 // - URIs are not resolved in new doc.» 1325 // - URIs are not resolved in new doc.
1334 var base = _parseDocument.createElement('base');» 1326 var base = _parseDocument.createElement('base');
1335 base.href = document.baseUri;» 1327 base.href = document.baseUri;
1336 _parseDocument.head.append(base); 1328 _parseDocument.head.append(base);
1337 } 1329 }
1338 var contextElement; 1330 var contextElement;
1339 if (this is BodyElement) { 1331 if (this is BodyElement) {
1340 contextElement = _parseDocument.body; 1332 contextElement = _parseDocument.body;
1341 } else { 1333 } else {
1342 contextElement = _parseDocument.createElement(tagName); 1334 contextElement = _parseDocument.createElement(tagName);
1343 _parseDocument.body.append(contextElement); 1335 _parseDocument.body.append(contextElement);
1344 } 1336 }
1345 var fragment; 1337 var fragment;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1383 'BASE', 'BASEFONT', 'BR', 'COL', 'COLGROUP', 'EMBED', 'FRAME', 'FRAMESET', 1375 'BASE', 'BASEFONT', 'BR', 'COL', 'COLGROUP', 'EMBED', 'FRAME', 'FRAMESET',
1384 'HR', 'IMAGE', 'IMG', 'INPUT', 'ISINDEX', 'LINK', 'META', 'PARAM', 1376 'HR', 'IMAGE', 'IMG', 'INPUT', 'ISINDEX', 'LINK', 'META', 'PARAM',
1385 'SOURCE', 'STYLE', 'TITLE', 'WBR']; 1377 'SOURCE', 'STYLE', 'TITLE', 'WBR'];
1386 1378
1387 /** 1379 /**
1388 * Parses the HTML fragment and sets it as the contents of this element. 1380 * Parses the HTML fragment and sets it as the contents of this element.
1389 * 1381 *
1390 * This uses the default sanitization behavior to sanitize the HTML fragment, 1382 * This uses the default sanitization behavior to sanitize the HTML fragment,
1391 * use [setInnerHtml] to override the default behavior. 1383 * use [setInnerHtml] to override the default behavior.
1392 */ 1384 */
1393 void set innerHtml(String html) { 1385 set innerHtml(String html) {
1394 this.setInnerHtml(html); 1386 this.setInnerHtml(html);
1395 } 1387 }
1396 1388
1397 /** 1389 /**
1398 * Parses the HTML fragment and sets it as the contents of this element. 1390 * Parses the HTML fragment and sets it as the contents of this element.
1399 * This ensures that the generated content follows the sanitization rules 1391 * This ensures that the generated content follows the sanitization rules
1400 * specified by the validator or treeSanitizer. 1392 * specified by the validator or treeSanitizer.
1401 * 1393 *
1402 * If the default validation behavior is too restrictive then a new 1394 * If the default validation behavior is too restrictive then a new
1403 * NodeValidator should be created, either extending or wrapping a default 1395 * NodeValidator should be created, either extending or wrapping a default
(...skipping 21 matching lines...) Expand all
1425 html, validator: validator, treeSanitizer: treeSanitizer)); 1417 html, validator: validator, treeSanitizer: treeSanitizer));
1426 } 1418 }
1427 } 1419 }
1428 String get innerHtml => _innerHtml; 1420 String get innerHtml => _innerHtml;
1429 1421
1430 /** 1422 /**
1431 * This is an ease-of-use accessor for event streams which should only be 1423 * This is an ease-of-use accessor for event streams which should only be
1432 * used when an explicit accessor is not available. 1424 * used when an explicit accessor is not available.
1433 */ 1425 */
1434 ElementEvents get on => new ElementEvents(this); 1426 ElementEvents get on => new ElementEvents(this);
1435 1427
1436 /** 1428 /**
1437 * Verify if any of the attributes that we use in the sanitizer look unexpecte d, 1429 * Verify if any of the attributes that we use in the sanitizer look unexpecte d,
1438 * possibly indicating DOM clobbering attacks. 1430 * possibly indicating DOM clobbering attacks.
1439 * 1431 *
1440 * Those attributes are: attributes, lastChild, children, previousNode and tag Name. 1432 * Those attributes are: attributes, lastChild, children, previousNode and tag Name.
1441 */ 1433 */
1442 $if DART2JS 1434 $if DART2JS
1443 static bool _hasCorruptedAttributes(Element element) { 1435 static bool _hasCorruptedAttributes(Element element) {
1444 return JS('bool', r''' 1436 return JS('bool', r'''
1445 (function(element) { 1437 (function(element) {
1446 if (!(element.attributes instanceof NamedNodeMap)) { 1438 if (!(element.attributes instanceof NamedNodeMap)) {
1447 return true; 1439 return true;
1448 } 1440 }
1449 var childNodes = element.childNodes; 1441 var childNodes = element.childNodes;
1450 if (element.lastChild && 1442 if (element.lastChild &&
1451 element.lastChild !== childNodes[childNodes.length -1]) { 1443 element.lastChild !== childNodes[childNodes.length -1]) {
1452 return true; 1444 return true;
1453 } 1445 }
1454 if (element.children) { // On Safari, children can apparently be null. 1446 if (element.children) { // On Safari, children can apparently be null.
1455 if (!((element.children instanceof HTMLCollection) || 1447 if (!((element.children instanceof HTMLCollection) ||
1456 (element.children instanceof NodeList))) { 1448 (element.children instanceof NodeList))) {
1457 return true; 1449 return true;
1458 } 1450 }
1459 } 1451 }
1460 return false; 1452 return false;
1461 })(#)''', element); 1453 })(#)''', element);
1462 } 1454 }
1463 $else 1455 $else
1464 // Dartium isn't affected by these attacks, because it goes directly to the C+ + API. 1456
1465 static bool _hasCorruptedAttributes(Element element) => false; 1457 static var _namedNodeMap = js.context["NamedNodeMap"];
1458 static var _htmlCollection = js.context["HTMLCollection"];
1459 static var _nodeList = js.context["NodeList"];
1460
1461 static bool _hasCorruptedAttributes(Element element) {
1462 var attributes = unwrap_jso(element)["attributes"];
1463 if (!attributes.instanceof(_namedNodeMap)) {
1464 return true;
1465 }
1466 var childNodes = unwrap_jso(element.childNodes);
1467 var length = childNodes["length"];
1468 var lastChild = unwrap_jso(element.lastChild);
1469 if (null != lastChild &&
1470 lastChild != childNodes[length - 1]) {
1471 return true;
1472 }
1473 var children = unwrap_jso(element._children);
1474 if (null != children) { // On Safari, children can apparently be null.
1475 if (!children.instanceof(_htmlCollection) ||
1476 children.instanceof(_nodeList)) {
1477 » return true;
1478 }
1479 }
1480 return false;
1481 }
1466 $endif 1482 $endif
1467 1483
1484 String get _safeTagName {
1485 String result = 'element tag unavailable';
1486 try {
1487 if (tagName is String) {
1488 result = tagName;
1489 }
1490 } catch (e) {}
1491 return result;
1492 }
1493
1468 $if DART2JS 1494 $if DART2JS
1469 @DomName('Element.offsetHeight') 1495 @DomName('Element.offsetHeight')
1470 @DocsEditable() 1496 @DocsEditable()
1471 int get offsetHeight => JS('num', '#.offsetHeight', this).round(); 1497 int get offsetHeight => JS('num', '#.offsetHeight', this).round();
1472 1498
1473 @DomName('Element.offsetLeft') 1499 @DomName('Element.offsetLeft')
1474 @DocsEditable() 1500 @DocsEditable()
1475 int get offsetLeft => JS('num', '#.offsetLeft', this).round(); 1501 int get offsetLeft => JS('num', '#.offsetLeft', this).round();
1476 1502
1477 @DomName('Element.offsetTop') 1503 @DomName('Element.offsetTop')
(...skipping 23 matching lines...) Expand all
1501 @DomName('Element.scrollHeight') 1527 @DomName('Element.scrollHeight')
1502 @DocsEditable() 1528 @DocsEditable()
1503 int get scrollHeight => JS('num', '#.scrollHeight', this).round(); 1529 int get scrollHeight => JS('num', '#.scrollHeight', this).round();
1504 1530
1505 @DomName('Element.scrollLeft') 1531 @DomName('Element.scrollLeft')
1506 @DocsEditable() 1532 @DocsEditable()
1507 int get scrollLeft => JS('num', '#.scrollLeft', this).round(); 1533 int get scrollLeft => JS('num', '#.scrollLeft', this).round();
1508 1534
1509 @DomName('Element.scrollLeft') 1535 @DomName('Element.scrollLeft')
1510 @DocsEditable() 1536 @DocsEditable()
1511 void set scrollLeft(int value) { 1537 set scrollLeft(int value) {
1512 JS("void", "#.scrollLeft = #", this, value.round()); 1538 JS("void", "#.scrollLeft = #", this, value.round());
1513 } 1539 }
1514 1540
1515 @DomName('Element.scrollTop') 1541 @DomName('Element.scrollTop')
1516 @DocsEditable() 1542 @DocsEditable()
1517 int get scrollTop => JS('num', '#.scrollTop', this).round(); 1543 int get scrollTop => JS('num', '#.scrollTop', this).round();
1518 1544
1519 @DomName('Element.scrollTop') 1545 @DomName('Element.scrollTop')
1520 @DocsEditable() 1546 @DocsEditable()
1521 void set scrollTop(int value) { 1547 set scrollTop(int value) {
1522 JS("void", "#.scrollTop = #", this, value.round()); 1548 JS("void", "#.scrollTop = #", this, value.round());
1523 } 1549 }
1524 1550
1525 @DomName('Element.scrollWidth') 1551 @DomName('Element.scrollWidth')
1526 @DocsEditable() 1552 @DocsEditable()
1527 int get scrollWidth => JS('num', '#.scrollWidth', this).round(); 1553 int get scrollWidth => JS('num', '#.scrollWidth', this).round();
1528 1554
1529 $else 1555 $else
1530 $if JSINTEROP 1556 $if JSINTEROP
1557 // Need to explicitly delegate because Element is no longer abstract for Darti um.
1558 bool get isContentEditable => _blink.BlinkHTMLElement.instance.isContentEditab le_Getter_(unwrap_jso(this));
1559 void click() => _blink.BlinkHTMLElement.instance.click_Callback_0_(unwrap_jso( this));
1560
1531 @DomName('Element.offsetHeight') 1561 @DomName('Element.offsetHeight')
1532 @DocsEditable() 1562 @DocsEditable()
1533 int get offsetHeight => _blink.BlinkElement.instance.offsetHeight_Getter_(unwr ap_jso(this)).round(); 1563 int get offsetHeight => _blink.BlinkElement.instance.offsetHeight_Getter_(unwr ap_jso(this)).round();
1534 1564
1535 @DomName('Element.offsetLeft') 1565 @DomName('Element.offsetLeft')
1536 @DocsEditable() 1566 @DocsEditable()
1537 int get offsetLeft => _blink.BlinkElement.instance.offsetLeft_Getter_(unwrap_j so(this)).round(); 1567 int get offsetLeft => _blink.BlinkElement.instance.offsetLeft_Getter_(unwrap_j so(this)).round();
1538 1568
1539 @DomName('Element.offsetTop') 1569 @DomName('Element.offsetTop')
1540 @DocsEditable() 1570 @DocsEditable()
(...skipping 22 matching lines...) Expand all
1563 @DomName('Element.scrollHeight') 1593 @DomName('Element.scrollHeight')
1564 @DocsEditable() 1594 @DocsEditable()
1565 int get scrollHeight => _blink.BlinkElement.instance.scrollHeight_Getter_(unwr ap_jso(this)).round(); 1595 int get scrollHeight => _blink.BlinkElement.instance.scrollHeight_Getter_(unwr ap_jso(this)).round();
1566 1596
1567 @DomName('Element.scrollLeft') 1597 @DomName('Element.scrollLeft')
1568 @DocsEditable() 1598 @DocsEditable()
1569 int get scrollLeft => _blink.BlinkElement.instance.scrollLeft_Getter_(unwrap_j so(this)).round(); 1599 int get scrollLeft => _blink.BlinkElement.instance.scrollLeft_Getter_(unwrap_j so(this)).round();
1570 1600
1571 @DomName('Element.scrollLeft') 1601 @DomName('Element.scrollLeft')
1572 @DocsEditable() 1602 @DocsEditable()
1573 void set scrollLeft(int value) => _blink.BlinkElement.instance.scrollLeft_Sett er_(unwrap_jso(this), value.round()); 1603 set scrollLeft(int value) => _blink.BlinkElement.instance.scrollLeft_Setter_(u nwrap_jso(this), value.round());
1574 1604
1575 @DomName('Element.scrollTop') 1605 @DomName('Element.scrollTop')
1576 @DocsEditable() 1606 @DocsEditable()
1577 int get scrollTop => _blink.BlinkElement.instance.scrollTop_Getter_(unwrap_jso (this)).round(); 1607 int get scrollTop => _blink.BlinkElement.instance.scrollTop_Getter_(unwrap_jso (this)).round();
1578 1608
1579 @DomName('Element.scrollTop') 1609 @DomName('Element.scrollTop')
1580 @DocsEditable() 1610 @DocsEditable()
1581 void set scrollTop(int value) => _blink.BlinkElement.instance.scrollTop_Setter _(unwrap_jso(this), value.round()); 1611 set scrollTop(int value) => _blink.BlinkElement.instance.scrollTop_Setter_(unw rap_jso(this), value.round());
1582 1612
1583 @DomName('Element.scrollWidth') 1613 @DomName('Element.scrollWidth')
1584 @DocsEditable() 1614 @DocsEditable()
1585 int get scrollWidth => _blink.BlinkElement.instance.scrollWidth_Getter_(unwrap _jso(this)).round(); 1615 int get scrollWidth => _blink.BlinkElement.instance.scrollWidth_Getter_(unwrap _jso(this)).round();
1586 $else 1616 $else
1587 @DomName('Element.offsetHeight') 1617 @DomName('Element.offsetHeight')
1588 @DocsEditable() 1618 @DocsEditable()
1589 int get offsetHeight => _blink.BlinkElement.offsetHeight_Getter(this).round(); 1619 int get offsetHeight => _blink.BlinkElement.offsetHeight_Getter(this).round();
1590 1620
1591 @DomName('Element.offsetLeft') 1621 @DomName('Element.offsetLeft')
(...skipping 27 matching lines...) Expand all
1619 @DomName('Element.scrollHeight') 1649 @DomName('Element.scrollHeight')
1620 @DocsEditable() 1650 @DocsEditable()
1621 int get scrollHeight => _blink.BlinkElement.scrollHeight_Getter(this).round(); 1651 int get scrollHeight => _blink.BlinkElement.scrollHeight_Getter(this).round();
1622 1652
1623 @DomName('Element.scrollLeft') 1653 @DomName('Element.scrollLeft')
1624 @DocsEditable() 1654 @DocsEditable()
1625 int get scrollLeft => _blink.BlinkElement.scrollLeft_Getter(this).round(); 1655 int get scrollLeft => _blink.BlinkElement.scrollLeft_Getter(this).round();
1626 1656
1627 @DomName('Element.scrollLeft') 1657 @DomName('Element.scrollLeft')
1628 @DocsEditable() 1658 @DocsEditable()
1629 void set scrollLeft(int value) => _blink.BlinkElement.scrollLeft_Setter(this, value.round()); 1659 set scrollLeft(int value) => _blink.BlinkElement.scrollLeft_Setter(this, value .round());
1630 1660
1631 @DomName('Element.scrollTop') 1661 @DomName('Element.scrollTop')
1632 @DocsEditable() 1662 @DocsEditable()
1633 int get scrollTop => _blink.BlinkElement.scrollTop_Getter(this).round(); 1663 int get scrollTop => _blink.BlinkElement.scrollTop_Getter(this).round();
1634 1664
1635 @DomName('Element.scrollTop') 1665 @DomName('Element.scrollTop')
1636 @DocsEditable() 1666 @DocsEditable()
1637 void set scrollTop(int value) => _blink.BlinkElement.scrollTop_Setter(this, va lue.round()); 1667 set scrollTop(int value) => _blink.BlinkElement.scrollTop_Setter(this, value.r ound());
1638 1668
1639 @DomName('Element.scrollWidth') 1669 @DomName('Element.scrollWidth')
1640 @DocsEditable() 1670 @DocsEditable()
1641 int get scrollWidth => _blink.BlinkElement.scrollWidth_Getter(this).round(); 1671 int get scrollWidth => _blink.BlinkElement.scrollWidth_Getter(this).round();
1642 $endif 1672 $endif
1643 $endif 1673 $endif
1644 1674
1645 $!MEMBERS 1675 $!MEMBERS
1646 } 1676 }
1647 1677
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1680 const ScrollAlignment._internal(this._value); 1710 const ScrollAlignment._internal(this._value);
1681 toString() => 'ScrollAlignment.$_value'; 1711 toString() => 'ScrollAlignment.$_value';
1682 1712
1683 /// Attempt to align the element to the top of the scrollable area. 1713 /// Attempt to align the element to the top of the scrollable area.
1684 static const TOP = const ScrollAlignment._internal('TOP'); 1714 static const TOP = const ScrollAlignment._internal('TOP');
1685 /// Attempt to center the element in the scrollable area. 1715 /// Attempt to center the element in the scrollable area.
1686 static const CENTER = const ScrollAlignment._internal('CENTER'); 1716 static const CENTER = const ScrollAlignment._internal('CENTER');
1687 /// Attempt to align the element to the bottom of the scrollable area. 1717 /// Attempt to align the element to the bottom of the scrollable area.
1688 static const BOTTOM = const ScrollAlignment._internal('BOTTOM'); 1718 static const BOTTOM = const ScrollAlignment._internal('BOTTOM');
1689 } 1719 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698