Chromium Code Reviews| 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 10 matching lines...) Expand all Loading... | |
| 526 } else if (parentTag == 'html' && temp.childElementCount == 2) { | 524 } else if (parentTag == 'html' && temp.childElementCount == 2) { |
| 527 // Work around for edge case in WebKit and possibly other browsers where | 525 // Work around for edge case in WebKit and possibly other browsers where |
| 528 // both body and head elements are created even though the inner html | 526 // both body and head elements are created even though the inner html |
| 529 // only contains a head or body element. | 527 // only contains a head or body element. |
| 530 return LevelDom.wrapElement(temp.children.item(tag == 'head' ? 0 : 1)); | 528 return LevelDom.wrapElement(temp.children.item(tag == 'head' ? 0 : 1)); |
| 531 } else { | 529 } else { |
| 532 throw 'HTML had ${temp.childElementCount} top level elements but 1 expecte d'; | 530 throw 'HTML had ${temp.childElementCount} top level elements but 1 expecte d'; |
| 533 } | 531 } |
| 534 } | 532 } |
| 535 | 533 |
| 534 /** @domName Document.createElement */ | |
| 536 factory ElementWrappingImplementation.tag(String tag) { | 535 factory ElementWrappingImplementation.tag(String tag) { |
| 537 return LevelDom.wrapElement(dom.document.createElement(tag)); | 536 return LevelDom.wrapElement(dom.document.createElement(tag)); |
| 538 } | 537 } |
| 539 | 538 |
| 540 ElementWrappingImplementation._wrap(ptr) : super._wrap(ptr); | 539 ElementWrappingImplementation._wrap(ptr) : super._wrap(ptr); |
| 541 | 540 |
| 542 ElementAttributeMap _elementAttributeMap; | 541 ElementAttributeMap _elementAttributeMap; |
| 543 ElementList _elements; | 542 ElementList _elements; |
| 544 _CssClassSet _cssClassSet; | 543 _CssClassSet _cssClassSet; |
| 545 _DataAttributeMap _dataAttributes; | 544 _DataAttributeMap _dataAttributes; |
| 546 | 545 |
| 546 /** | |
| 547 * @domName Element.hasAttribute, Element.getAttribute, Element.setAttribute, | |
| 548 * Element.removeAttribute | |
| 549 */ | |
| 547 Map<String, String> get attributes() { | 550 Map<String, String> get attributes() { |
| 548 if (_elementAttributeMap === null) { | 551 if (_elementAttributeMap === null) { |
| 549 _elementAttributeMap = new ElementAttributeMap._wrap(_ptr); | 552 _elementAttributeMap = new ElementAttributeMap._wrap(_ptr); |
| 550 } | 553 } |
| 551 return _elementAttributeMap; | 554 return _elementAttributeMap; |
| 552 } | 555 } |
| 553 | 556 |
| 554 void set attributes(Map<String, String> value) { | 557 void set attributes(Map<String, String> value) { |
| 555 Map<String, String> attributes = this.attributes; | 558 Map<String, String> attributes = this.attributes; |
| 556 attributes.clear(); | 559 attributes.clear(); |
| 557 for (String key in value.getKeys()) { | 560 for (String key in value.getKeys()) { |
| 558 attributes[key] = value[key]; | 561 attributes[key] = value[key]; |
| 559 } | 562 } |
| 560 } | 563 } |
| 561 | 564 |
| 562 void set elements(Collection<Element> value) { | 565 void set elements(Collection<Element> value) { |
| 563 // Copy list first since we don't want liveness during iteration. | 566 // Copy list first since we don't want liveness during iteration. |
| 564 List copy = new List.from(value); | 567 List copy = new List.from(value); |
| 565 final elements = this.elements; | 568 final elements = this.elements; |
| 566 elements.clear(); | 569 elements.clear(); |
| 567 elements.addAll(copy); | 570 elements.addAll(copy); |
| 568 } | 571 } |
| 569 | 572 |
| 573 /** | |
| 574 * @domName childElementCount, firstElementChild, lastElementChild, | |
| 575 * children | |
|
Jacob
2011/12/06 22:38:14
and
appendChild
nweiz
2011/12/07 19:26:56
Done.
| |
| 576 */ | |
| 570 ElementList get elements() { | 577 ElementList get elements() { |
| 571 if (_elements == null) { | 578 if (_elements == null) { |
| 572 _elements = new _ChildrenElementList._wrap(_ptr); | 579 _elements = new _ChildrenElementList._wrap(_ptr); |
| 573 } | 580 } |
| 574 return _elements; | 581 return _elements; |
| 575 } | 582 } |
| 576 | 583 |
| 584 /** @domName className, classList */ | |
| 577 Set<String> get classes() { | 585 Set<String> get classes() { |
| 578 if (_cssClassSet === null) { | 586 if (_cssClassSet === null) { |
| 579 _cssClassSet = new _CssClassSet(_ptr); | 587 _cssClassSet = new _CssClassSet(_ptr); |
| 580 } | 588 } |
| 581 return _cssClassSet; | 589 return _cssClassSet; |
| 582 } | 590 } |
| 583 | 591 |
| 584 void set classes(Collection<String> value) { | 592 void set classes(Collection<String> value) { |
| 585 _CssClassSet classSet = classes; | 593 _CssClassSet classSet = classes; |
| 586 classSet.clear(); | 594 classSet.clear(); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 669 } | 677 } |
| 670 | 678 |
| 671 bool contains(Node element) { | 679 bool contains(Node element) { |
| 672 return _ptr.contains(LevelDom.unwrap(element)); | 680 return _ptr.contains(LevelDom.unwrap(element)); |
| 673 } | 681 } |
| 674 | 682 |
| 675 void focus() { | 683 void focus() { |
| 676 _ptr.focus(); | 684 _ptr.focus(); |
| 677 } | 685 } |
| 678 | 686 |
| 679 /** @domName HTMLElement.insertAdjacentElement */ | |
| 680 Element insertAdjacentElement([String where = null, Element element = null]) { | 687 Element insertAdjacentElement([String where = null, Element element = null]) { |
| 681 return LevelDom.wrapElement(_ptr.insertAdjacentElement(where, LevelDom.unwra p(element))); | 688 return LevelDom.wrapElement(_ptr.insertAdjacentElement(where, LevelDom.unwra p(element))); |
| 682 } | 689 } |
| 683 | 690 |
| 684 /** @domName HTMLElement.insertAdjacentHTML */ | |
| 685 void insertAdjacentHTML([String position_OR_where = null, String text = null]) { | 691 void insertAdjacentHTML([String position_OR_where = null, String text = null]) { |
| 686 _ptr.insertAdjacentHTML(position_OR_where, text); | 692 _ptr.insertAdjacentHTML(position_OR_where, text); |
| 687 } | 693 } |
| 688 | 694 |
| 689 /** @domName HTMLElement.insertAdjacentText */ | |
| 690 void insertAdjacentText([String where = null, String text = null]) { | 695 void insertAdjacentText([String where = null, String text = null]) { |
| 691 _ptr.insertAdjacentText(where, text); | 696 _ptr.insertAdjacentText(where, text); |
| 692 } | 697 } |
| 693 | 698 |
| 694 Element query(String selectors) { | 699 Element query(String selectors) { |
|
Jacob
2011/12/06 22:38:14
@domName querySelector, getElementById
nweiz
2011/12/07 19:26:56
Done.
| |
| 695 // TODO(jacobr): scope fix. | 700 // TODO(jacobr): scope fix. |
| 696 return LevelDom.wrapElement(_ptr.querySelector(selectors)); | 701 return LevelDom.wrapElement(_ptr.querySelector(selectors)); |
| 697 } | 702 } |
| 698 | 703 |
| 704 /** | |
| 705 * @domName querySelectorAll, getElementsByClassName, getElementsByTagName, | |
| 706 * getElementsByTagNameNS | |
| 707 */ | |
| 699 ElementList queryAll(String selectors) { | 708 ElementList queryAll(String selectors) { |
| 700 // TODO(jacobr): scope fix. | 709 // TODO(jacobr): scope fix. |
| 701 return new FrozenElementList._wrap(_ptr.querySelectorAll(selectors)); | 710 return new FrozenElementList._wrap(_ptr.querySelectorAll(selectors)); |
| 702 } | 711 } |
| 703 | 712 |
| 704 void scrollByLines([int lines = null]) { | 713 void scrollByLines([int lines = null]) { |
| 705 _ptr.scrollByLines(lines); | 714 _ptr.scrollByLines(lines); |
| 706 } | 715 } |
| 707 | 716 |
| 708 void scrollByPages([int pages = null]) { | 717 void scrollByPages([int pages = null]) { |
| 709 _ptr.scrollByPages(pages); | 718 _ptr.scrollByPages(pages); |
| 710 } | 719 } |
| 711 | 720 |
| 721 /** @domName scrollIntoView, scrollIntoViewIfNeeded */ | |
| 712 void scrollIntoView([bool centerIfNeeded = null]) { | 722 void scrollIntoView([bool centerIfNeeded = null]) { |
| 713 _ptr.scrollIntoViewIfNeeded(centerIfNeeded); | 723 _ptr.scrollIntoViewIfNeeded(centerIfNeeded); |
| 714 } | 724 } |
| 715 | 725 |
| 716 bool matchesSelector([String selectors = null]) { | 726 bool matchesSelector([String selectors = null]) { |
| 717 return _ptr.webkitMatchesSelector(selectors); | 727 return _ptr.webkitMatchesSelector(selectors); |
| 718 } | 728 } |
| 719 | 729 |
| 720 void set scrollLeft(int value) { _ptr.scrollLeft = value; } | 730 void set scrollLeft(int value) { _ptr.scrollLeft = value; } |
| 721 | 731 |
| 722 void set scrollTop(int value) { _ptr.scrollTop = value; } | 732 void set scrollTop(int value) { _ptr.scrollTop = value; } |
| 723 | 733 |
| 724 /** @domName getClientRects */ | 734 /** |
| 735 * @domName getClientRects, getBoundingClientRect, clientHeight, clientWidth, | |
| 736 * clientTop, clientLeft, offsetHeight, offsetWidth, offsetTop, offsetLeft, | |
| 737 * scrollHeight, scrollWidth, scrollTop, scrollLeft | |
| 738 */ | |
| 725 Future<ElementRect> get rect() { | 739 Future<ElementRect> get rect() { |
| 726 return _createMeasurementFuture( | 740 return _createMeasurementFuture( |
| 727 () => new ElementRectWrappingImplementation(_ptr), | 741 () => new ElementRectWrappingImplementation(_ptr), |
| 728 new Completer<ElementRect>()); | 742 new Completer<ElementRect>()); |
| 729 } | 743 } |
| 730 | 744 |
| 745 /** @domName Window.getComputedStyle */ | |
| 731 Future<CSSStyleDeclaration> get computedStyle() { | 746 Future<CSSStyleDeclaration> get computedStyle() { |
| 732 // TODO(jacobr): last param should be null, see b/5045788 | 747 // TODO(jacobr): last param should be null, see b/5045788 |
| 733 return getComputedStyle(''); | 748 return getComputedStyle(''); |
| 734 } | 749 } |
| 735 | 750 |
| 736 /** @domName Window.getComputedStyle */ | 751 /** @domName Window.getComputedStyle */ |
| 737 Future<CSSStyleDeclaration> getComputedStyle(String pseudoElement) { | 752 Future<CSSStyleDeclaration> getComputedStyle(String pseudoElement) { |
| 738 return _createMeasurementFuture(() => | 753 return _createMeasurementFuture(() => |
| 739 LevelDom.wrapCSSStyleDeclaration( | 754 LevelDom.wrapCSSStyleDeclaration( |
| 740 dom.window.getComputedStyle(_ptr, pseudoElement)), | 755 dom.window.getComputedStyle(_ptr, pseudoElement)), |
| 741 new Completer<CSSStyleDeclaration>()); | 756 new Completer<CSSStyleDeclaration>()); |
| 742 } | 757 } |
| 743 | 758 |
| 744 ElementEvents get on() { | 759 ElementEvents get on() { |
| 745 if (_on === null) { | 760 if (_on === null) { |
| 746 _on = new ElementEventsImplementation._wrap(_ptr); | 761 _on = new ElementEventsImplementation._wrap(_ptr); |
| 747 } | 762 } |
| 748 return _on; | 763 return _on; |
| 749 } | 764 } |
| 750 } | 765 } |
| OLD | NEW |