OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 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 | 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 // TODO(jacobr): use Lists.dart to remove some of the duplicated functionality. | 5 // TODO(jacobr): use Lists.dart to remove some of the duplicated functionality. |
6 class _ChildrenElementList implements ElementList { | 6 class _ChildrenElementList implements ElementList { |
7 // Raw Element. | 7 // Raw Element. |
8 final _element; | 8 final _element; |
9 final _childElements; | 9 final _childElements; |
10 | 10 |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 bool containsValue(String value) { | 285 bool containsValue(String value) { |
286 final attributes = _element.attributes; | 286 final attributes = _element.attributes; |
287 for (int i = 0, len = attributes.length; i < len; i++) { | 287 for (int i = 0, len = attributes.length; i < len; i++) { |
288 if(value == attributes.item(i).value) { | 288 if(value == attributes.item(i).value) { |
289 return true; | 289 return true; |
290 } | 290 } |
291 } | 291 } |
292 return false; | 292 return false; |
293 } | 293 } |
294 | 294 |
295 /** @domName Element.hasAttribute */ | |
296 bool containsKey(String key) { | 295 bool containsKey(String key) { |
297 return _element.hasAttribute(key); | 296 return _element.hasAttribute(key); |
298 } | 297 } |
299 | 298 |
300 /** @domName Element.getAttribute */ | |
301 String operator [](String key) { | 299 String operator [](String key) { |
302 return _element.getAttribute(key); | 300 return _element.getAttribute(key); |
303 } | 301 } |
304 | 302 |
305 /** @domName Element.setAttribute */ | |
306 void operator []=(String key, String value) { | 303 void operator []=(String key, String value) { |
307 _element.setAttribute(key, value); | 304 _element.setAttribute(key, value); |
308 } | 305 } |
309 | 306 |
310 String putIfAbsent(String key, String ifAbsent()) { | 307 String putIfAbsent(String key, String ifAbsent()) { |
311 if (!containsKey(key)) { | 308 if (!containsKey(key)) { |
312 this[key] = ifAbsent(); | 309 this[key] = ifAbsent(); |
313 } | 310 } |
314 } | 311 } |
315 | 312 |
316 /** @domName Element.removeAttribute */ | |
317 String remove(String key) { | 313 String remove(String key) { |
318 _element.removeAttribute(key); | 314 _element.removeAttribute(key); |
319 } | 315 } |
320 | 316 |
321 void clear() { | 317 void clear() { |
322 final attributes = _element.attributes; | 318 final attributes = _element.attributes; |
323 for (int i = attributes.length - 1; i >= 0; i--) { | 319 for (int i = attributes.length - 1; i >= 0; i--) { |
324 _element.removeAttribute(attributes.item(i).name); | 320 _element.removeAttribute(attributes.item(i).name); |
325 } | 321 } |
326 } | 322 } |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 | 473 |
478 List<ClientRect> get clientRects() { | 474 List<ClientRect> get clientRects() { |
479 final out = new List(_clientRects.length); | 475 final out = new List(_clientRects.length); |
480 for (num i = 0; i < _clientRects.length; i++) { | 476 for (num i = 0; i < _clientRects.length; i++) { |
481 out[i] = LevelDom.wrapClientRect(_clientRects.item(i)); | 477 out[i] = LevelDom.wrapClientRect(_clientRects.item(i)); |
482 } | 478 } |
483 return out; | 479 return out; |
484 } | 480 } |
485 } | 481 } |
486 | 482 |
| 483 /** @domName Element, HTMLElement */ |
487 class ElementWrappingImplementation extends NodeWrappingImplementation implement
s Element { | 484 class ElementWrappingImplementation extends NodeWrappingImplementation implement
s Element { |
488 | 485 |
489 static final _START_TAG_REGEXP = const RegExp('<(\\w+)'); | 486 static final _START_TAG_REGEXP = const RegExp('<(\\w+)'); |
490 static final _CUSTOM_PARENT_TAG_MAP = const { | 487 static final _CUSTOM_PARENT_TAG_MAP = const { |
491 'body' : 'html', | 488 'body' : 'html', |
492 'head' : 'html', | 489 'head' : 'html', |
493 'caption' : 'table', | 490 'caption' : 'table', |
494 'td': 'tr', | 491 'td': 'tr', |
495 'tbody': 'table', | 492 'tbody': 'table', |
496 'colgroup': 'table', | 493 'colgroup': 'table', |
497 'col' : 'colgroup', | 494 'col' : 'colgroup', |
498 'tr' : 'tbody', | 495 'tr' : 'tbody', |
499 'tbody' : 'table', | 496 'tbody' : 'table', |
500 'tfoot' : 'table', | 497 'tfoot' : 'table', |
501 'thead' : 'table', | 498 'thead' : 'table', |
502 'track' : 'audio', | 499 'track' : 'audio', |
503 }; | 500 }; |
504 | 501 |
505 factory ElementWrappingImplementation.html(String html) { | 502 /** @domName Document.createElement */ |
| 503 factory ElementWrappingImplementation.html(String html) { |
506 // TODO(jacobr): this method can be made more robust and performant. | 504 // TODO(jacobr): this method can be made more robust and performant. |
507 // 1) Cache the dummy parent elements required to use innerHTML rather than | 505 // 1) Cache the dummy parent elements required to use innerHTML rather than |
508 // creating them every call. | 506 // creating them every call. |
509 // 2) Verify that the html does not contain leading or trailing text nodes. | 507 // 2) Verify that the html does not contain leading or trailing text nodes. |
510 // 3) Verify that the html does not contain both <head> and <body> tags. | 508 // 3) Verify that the html does not contain both <head> and <body> tags. |
511 // 4) Detatch the created element from its dummy parent. | 509 // 4) Detatch the created element from its dummy parent. |
512 String parentTag = 'div'; | 510 String parentTag = 'div'; |
513 String tag; | 511 String tag; |
514 final match = _START_TAG_REGEXP.firstMatch(html); | 512 final match = _START_TAG_REGEXP.firstMatch(html); |
515 if (match !== null) { | 513 if (match !== null) { |
(...skipping 11 matching lines...) Expand all Loading... |
527 } else if (parentTag == 'html' && temp.childElementCount == 2) { | 525 } else if (parentTag == 'html' && temp.childElementCount == 2) { |
528 // Work around for edge case in WebKit and possibly other browsers where | 526 // Work around for edge case in WebKit and possibly other browsers where |
529 // both body and head elements are created even though the inner html | 527 // both body and head elements are created even though the inner html |
530 // only contains a head or body element. | 528 // only contains a head or body element. |
531 return LevelDom.wrapElement(temp.children.item(tag == 'head' ? 0 : 1)); | 529 return LevelDom.wrapElement(temp.children.item(tag == 'head' ? 0 : 1)); |
532 } else { | 530 } else { |
533 throw 'HTML had ${temp.childElementCount} top level elements but 1 expecte
d'; | 531 throw 'HTML had ${temp.childElementCount} top level elements but 1 expecte
d'; |
534 } | 532 } |
535 } | 533 } |
536 | 534 |
| 535 /** @domName Document.createElement */ |
537 factory ElementWrappingImplementation.tag(String tag) { | 536 factory ElementWrappingImplementation.tag(String tag) { |
538 return LevelDom.wrapElement(dom.document.createElement(tag)); | 537 return LevelDom.wrapElement(dom.document.createElement(tag)); |
539 } | 538 } |
540 | 539 |
541 ElementWrappingImplementation._wrap(ptr) : super._wrap(ptr); | 540 ElementWrappingImplementation._wrap(ptr) : super._wrap(ptr); |
542 | 541 |
543 ElementAttributeMap _elementAttributeMap; | 542 ElementAttributeMap _elementAttributeMap; |
544 ElementList _elements; | 543 ElementList _elements; |
545 _CssClassSet _cssClassSet; | 544 _CssClassSet _cssClassSet; |
546 _DataAttributeMap _dataAttributes; | 545 _DataAttributeMap _dataAttributes; |
547 | 546 |
| 547 /** |
| 548 * @domName Element.hasAttribute, Element.getAttribute, Element.setAttribute, |
| 549 * Element.removeAttribute |
| 550 */ |
548 Map<String, String> get attributes() { | 551 Map<String, String> get attributes() { |
549 if (_elementAttributeMap === null) { | 552 if (_elementAttributeMap === null) { |
550 _elementAttributeMap = new ElementAttributeMap._wrap(_ptr); | 553 _elementAttributeMap = new ElementAttributeMap._wrap(_ptr); |
551 } | 554 } |
552 return _elementAttributeMap; | 555 return _elementAttributeMap; |
553 } | 556 } |
554 | 557 |
555 void set attributes(Map<String, String> value) { | 558 void set attributes(Map<String, String> value) { |
556 Map<String, String> attributes = this.attributes; | 559 Map<String, String> attributes = this.attributes; |
557 attributes.clear(); | 560 attributes.clear(); |
558 for (String key in value.getKeys()) { | 561 for (String key in value.getKeys()) { |
559 attributes[key] = value[key]; | 562 attributes[key] = value[key]; |
560 } | 563 } |
561 } | 564 } |
562 | 565 |
563 void set elements(Collection<Element> value) { | 566 void set elements(Collection<Element> value) { |
564 // Copy list first since we don't want liveness during iteration. | 567 // Copy list first since we don't want liveness during iteration. |
565 List copy = new List.from(value); | 568 List copy = new List.from(value); |
566 final elements = this.elements; | 569 final elements = this.elements; |
567 elements.clear(); | 570 elements.clear(); |
568 elements.addAll(copy); | 571 elements.addAll(copy); |
569 } | 572 } |
570 | 573 |
| 574 /** |
| 575 * @domName childElementCount, firstElementChild, lastElementChild, |
| 576 * children, appendChild |
| 577 */ |
571 ElementList get elements() { | 578 ElementList get elements() { |
572 if (_elements == null) { | 579 if (_elements == null) { |
573 _elements = new _ChildrenElementList._wrap(_ptr); | 580 _elements = new _ChildrenElementList._wrap(_ptr); |
574 } | 581 } |
575 return _elements; | 582 return _elements; |
576 } | 583 } |
577 | 584 |
| 585 /** @domName className, classList */ |
578 Set<String> get classes() { | 586 Set<String> get classes() { |
579 if (_cssClassSet === null) { | 587 if (_cssClassSet === null) { |
580 _cssClassSet = new _CssClassSet(_ptr); | 588 _cssClassSet = new _CssClassSet(_ptr); |
581 } | 589 } |
582 return _cssClassSet; | 590 return _cssClassSet; |
583 } | 591 } |
584 | 592 |
585 void set classes(Collection<String> value) { | 593 void set classes(Collection<String> value) { |
586 _CssClassSet classSet = classes; | 594 _CssClassSet classSet = classes; |
587 classSet.clear(); | 595 classSet.clear(); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
670 } | 678 } |
671 | 679 |
672 bool contains(Node element) { | 680 bool contains(Node element) { |
673 return _ptr.contains(LevelDom.unwrap(element)); | 681 return _ptr.contains(LevelDom.unwrap(element)); |
674 } | 682 } |
675 | 683 |
676 void focus() { | 684 void focus() { |
677 _ptr.focus(); | 685 _ptr.focus(); |
678 } | 686 } |
679 | 687 |
680 /** @domName HTMLElement.insertAdjacentElement */ | |
681 Element insertAdjacentElement([String where = null, Element element = null]) { | 688 Element insertAdjacentElement([String where = null, Element element = null]) { |
682 return LevelDom.wrapElement(_ptr.insertAdjacentElement(where, LevelDom.unwra
p(element))); | 689 return LevelDom.wrapElement(_ptr.insertAdjacentElement(where, LevelDom.unwra
p(element))); |
683 } | 690 } |
684 | 691 |
685 /** @domName HTMLElement.insertAdjacentHTML */ | |
686 void insertAdjacentHTML([String position_OR_where = null, String text = null])
{ | 692 void insertAdjacentHTML([String position_OR_where = null, String text = null])
{ |
687 _ptr.insertAdjacentHTML(position_OR_where, text); | 693 _ptr.insertAdjacentHTML(position_OR_where, text); |
688 } | 694 } |
689 | 695 |
690 /** @domName HTMLElement.insertAdjacentText */ | |
691 void insertAdjacentText([String where = null, String text = null]) { | 696 void insertAdjacentText([String where = null, String text = null]) { |
692 _ptr.insertAdjacentText(where, text); | 697 _ptr.insertAdjacentText(where, text); |
693 } | 698 } |
694 | 699 |
| 700 /** @domName querySelector, Document.getElementById */ |
695 Element query(String selectors) { | 701 Element query(String selectors) { |
696 // TODO(jacobr): scope fix. | 702 // TODO(jacobr): scope fix. |
697 return LevelDom.wrapElement(_ptr.querySelector(selectors)); | 703 return LevelDom.wrapElement(_ptr.querySelector(selectors)); |
698 } | 704 } |
699 | 705 |
| 706 /** |
| 707 * @domName querySelectorAll, getElementsByClassName, getElementsByTagName, |
| 708 * getElementsByTagNameNS |
| 709 */ |
700 ElementList queryAll(String selectors) { | 710 ElementList queryAll(String selectors) { |
701 // TODO(jacobr): scope fix. | 711 // TODO(jacobr): scope fix. |
702 return new FrozenElementList._wrap(_ptr.querySelectorAll(selectors)); | 712 return new FrozenElementList._wrap(_ptr.querySelectorAll(selectors)); |
703 } | 713 } |
704 | 714 |
705 void scrollByLines([int lines = null]) { | 715 void scrollByLines([int lines = null]) { |
706 _ptr.scrollByLines(lines); | 716 _ptr.scrollByLines(lines); |
707 } | 717 } |
708 | 718 |
709 void scrollByPages([int pages = null]) { | 719 void scrollByPages([int pages = null]) { |
710 _ptr.scrollByPages(pages); | 720 _ptr.scrollByPages(pages); |
711 } | 721 } |
712 | 722 |
| 723 /** @domName scrollIntoView, scrollIntoViewIfNeeded */ |
713 void scrollIntoView([bool centerIfNeeded = null]) { | 724 void scrollIntoView([bool centerIfNeeded = null]) { |
714 _ptr.scrollIntoViewIfNeeded(centerIfNeeded); | 725 _ptr.scrollIntoViewIfNeeded(centerIfNeeded); |
715 } | 726 } |
716 | 727 |
717 bool matchesSelector([String selectors = null]) { | 728 bool matchesSelector([String selectors = null]) { |
718 return _ptr.webkitMatchesSelector(selectors); | 729 return _ptr.webkitMatchesSelector(selectors); |
719 } | 730 } |
720 | 731 |
721 void set scrollLeft(int value) { _ptr.scrollLeft = value; } | 732 void set scrollLeft(int value) { _ptr.scrollLeft = value; } |
722 | 733 |
723 void set scrollTop(int value) { _ptr.scrollTop = value; } | 734 void set scrollTop(int value) { _ptr.scrollTop = value; } |
724 | 735 |
725 /** @domName getClientRects */ | 736 /** |
| 737 * @domName getClientRects, getBoundingClientRect, clientHeight, clientWidth, |
| 738 * clientTop, clientLeft, offsetHeight, offsetWidth, offsetTop, offsetLeft, |
| 739 * scrollHeight, scrollWidth, scrollTop, scrollLeft |
| 740 */ |
726 Future<ElementRect> get rect() { | 741 Future<ElementRect> get rect() { |
727 return _createMeasurementFuture( | 742 return _createMeasurementFuture( |
728 () => new ElementRectWrappingImplementation(_ptr), | 743 () => new ElementRectWrappingImplementation(_ptr), |
729 new Completer<ElementRect>()); | 744 new Completer<ElementRect>()); |
730 } | 745 } |
731 | 746 |
| 747 /** @domName Window.getComputedStyle */ |
732 Future<CSSStyleDeclaration> get computedStyle() { | 748 Future<CSSStyleDeclaration> get computedStyle() { |
733 // TODO(jacobr): last param should be null, see b/5045788 | 749 // TODO(jacobr): last param should be null, see b/5045788 |
734 return getComputedStyle(''); | 750 return getComputedStyle(''); |
735 } | 751 } |
736 | 752 |
737 /** @domName Window.getComputedStyle */ | 753 /** @domName Window.getComputedStyle */ |
738 Future<CSSStyleDeclaration> getComputedStyle(String pseudoElement) { | 754 Future<CSSStyleDeclaration> getComputedStyle(String pseudoElement) { |
739 return _createMeasurementFuture(() => | 755 return _createMeasurementFuture(() => |
740 LevelDom.wrapCSSStyleDeclaration( | 756 LevelDom.wrapCSSStyleDeclaration( |
741 dom.window.getComputedStyle(_ptr, pseudoElement)), | 757 dom.window.getComputedStyle(_ptr, pseudoElement)), |
742 new Completer<CSSStyleDeclaration>()); | 758 new Completer<CSSStyleDeclaration>()); |
743 } | 759 } |
744 | 760 |
745 ElementEvents get on() { | 761 ElementEvents get on() { |
746 if (_on === null) { | 762 if (_on === null) { |
747 _on = new ElementEventsImplementation._wrap(_ptr); | 763 _on = new ElementEventsImplementation._wrap(_ptr); |
748 } | 764 } |
749 return _on; | 765 return _on; |
750 } | 766 } |
751 } | 767 } |
OLD | NEW |