| 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 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 * All your element measurement needs in one place | 440 * All your element measurement needs in one place |
| 441 */ | 441 */ |
| 442 class ElementRectWrappingImplementation implements ElementRect { | 442 class ElementRectWrappingImplementation implements ElementRect { |
| 443 final ClientRect client; | 443 final ClientRect client; |
| 444 final ClientRect offset; | 444 final ClientRect offset; |
| 445 final ClientRect scroll; | 445 final ClientRect scroll; |
| 446 | 446 |
| 447 // TODO(jacobr): should we move these outside of ElementRect to avoid the | 447 // TODO(jacobr): should we move these outside of ElementRect to avoid the |
| 448 // overhead of computing them every time even though they are rarely used. | 448 // overhead of computing them every time even though they are rarely used. |
| 449 // This should be type dom.ClientRect but that fails on dartium. b/5522629 | 449 // This should be type dom.ClientRect but that fails on dartium. b/5522629 |
| 450 final _boundingClientRect; | 450 final _boundingClientRect; |
| 451 // an exception due to a dartium bug. | 451 // an exception due to a dartium bug. |
| 452 final dom.ClientRectList _clientRects; | 452 final dom.ClientRectList _clientRects; |
| 453 | 453 |
| 454 ElementRectWrappingImplementation(dom.HTMLElement element) : | 454 ElementRectWrappingImplementation(dom.HTMLElement element) : |
| 455 client = new SimpleClientRect(element.clientLeft, | 455 client = new SimpleClientRect(element.clientLeft, |
| 456 element.clientTop, | 456 element.clientTop, |
| 457 element.clientWidth, | 457 element.clientWidth, |
| 458 element.clientHeight), | 458 element.clientHeight), |
| 459 offset = new SimpleClientRect(element.offsetLeft, | 459 offset = new SimpleClientRect(element.offsetLeft, |
| 460 element.offsetTop, | 460 element.offsetTop, |
| 461 element.offsetWidth, | 461 element.offsetWidth, |
| 462 element.offsetHeight), | 462 element.offsetHeight), |
| 463 scroll = new SimpleClientRect(element.scrollLeft, | 463 scroll = new SimpleClientRect(element.scrollLeft, |
| 464 element.scrollTop, | 464 element.scrollTop, |
| 465 element.scrollWidth, | 465 element.scrollWidth, |
| 466 element.scrollHeight), | 466 element.scrollHeight), |
| 467 _boundingClientRect = element.getBoundingClientRect(), | 467 _boundingClientRect = element.getBoundingClientRect(), |
| 468 _clientRects = element.getClientRects(); | 468 _clientRects = element.getClientRects(); |
| 469 | 469 |
| 470 ClientRect get bounding() => | 470 ClientRect get bounding() => |
| 471 LevelDom.wrapClientRect(_boundingClientRect); | 471 LevelDom.wrapClientRect(_boundingClientRect); |
| 472 | 472 |
| 473 List<ClientRect> get clientRects() { | 473 List<ClientRect> get clientRects() { |
| 474 final out = new List(_clientRects.length); | 474 final out = new List(_clientRects.length); |
| 475 for (num i = 0; i < _clientRects.length; i++) { | 475 for (num i = 0; i < _clientRects.length; i++) { |
| 476 out[i] = LevelDom.wrapClientRect(_clientRects.item(i)); | 476 out[i] = LevelDom.wrapClientRect(_clientRects.item(i)); |
| 477 } | 477 } |
| 478 return out; | 478 return out; |
| 479 } | 479 } |
| 480 } | 480 } |
| 481 | 481 |
| 482 class ElementWrappingImplementation extends NodeWrappingImplementation implement
s Element { | 482 class ElementWrappingImplementation extends NodeWrappingImplementation implement
s Element { |
| 483 | 483 |
| 484 static final _START_TAG_REGEXP = const RegExp('<(\\w+)'); | 484 static final _START_TAG_REGEXP = const RegExp('<(\\w+)'); |
| 485 static final _CUSTOM_PARENT_TAG_MAP = const { | 485 static final _CUSTOM_PARENT_TAG_MAP = const { |
| 486 'body' : 'html', | 486 'body' : 'html', |
| 487 'head' : 'html', | 487 'head' : 'html', |
| 488 'caption' : 'table', | 488 'caption' : 'table', |
| 489 'td': 'tr', | 489 'td': 'tr', |
| 490 'tbody': 'table', | 490 'tbody': 'table', |
| 491 'colgroup': 'table', | 491 'colgroup': 'table', |
| 492 'col' : 'colgroup', | 492 'col' : 'colgroup', |
| 493 'tr' : 'tbody', | 493 'tr' : 'tbody', |
| 494 'tbody' : 'table', | 494 'tbody' : 'table', |
| 495 'tfoot' : 'table', | 495 'tfoot' : 'table', |
| 496 'thead' : 'table', | 496 'thead' : 'table', |
| 497 'track' : 'audio', | 497 'track' : 'audio', |
| 498 }; | 498 }; |
| 499 | 499 |
| 500 factory Element.html(String html) { | 500 factory ElementWrappingImplementation.html(String html) { |
| 501 // TODO(jacobr): this method can be made more robust and performant. | 501 // TODO(jacobr): this method can be made more robust and performant. |
| 502 // 1) Cache the dummy parent elements required to use innerHTML rather than | 502 // 1) Cache the dummy parent elements required to use innerHTML rather than |
| 503 // creating them every call. | 503 // creating them every call. |
| 504 // 2) Verify that the html does not contain leading or trailing text nodes. | 504 // 2) Verify that the html does not contain leading or trailing text nodes. |
| 505 // 3) Verify that the html does not contain both <head> and <body> tags. | 505 // 3) Verify that the html does not contain both <head> and <body> tags. |
| 506 // 4) Detatch the created element from its dummy parent. | 506 // 4) Detatch the created element from its dummy parent. |
| 507 String parentTag = 'div'; | 507 String parentTag = 'div'; |
| 508 String tag; | 508 String tag; |
| 509 final match = _START_TAG_REGEXP.firstMatch(html); | 509 final match = _START_TAG_REGEXP.firstMatch(html); |
| 510 if (match !== null) { | 510 if (match !== null) { |
| 511 tag = match.group(1).toLowerCase(); | 511 tag = match.group(1).toLowerCase(); |
| 512 if (_CUSTOM_PARENT_TAG_MAP.containsKey(tag)) { | 512 if (_CUSTOM_PARENT_TAG_MAP.containsKey(tag)) { |
| 513 parentTag = _CUSTOM_PARENT_TAG_MAP[tag]; | 513 parentTag = _CUSTOM_PARENT_TAG_MAP[tag]; |
| 514 } | 514 } |
| 515 } | 515 } |
| 516 dom.HTMLElement temp = dom.document.createElement(parentTag); | 516 final temp = dom.document.createElement(parentTag); |
| 517 temp.innerHTML = html; | 517 temp.innerHTML = html; |
| 518 | 518 |
| 519 if (temp.childElementCount == 1) { | 519 if (temp.childElementCount == 1) { |
| 520 return LevelDom.wrapElement(temp.firstElementChild); | 520 return LevelDom.wrapElement(temp.firstElementChild); |
| 521 } else if (parentTag == 'html' && temp.childElementCount == 2) { | 521 } else if (parentTag == 'html' && temp.childElementCount == 2) { |
| 522 // Work around for edge case in WebKit and possibly other browsers where | 522 // Work around for edge case in WebKit and possibly other browsers where |
| 523 // both body and head elements are created even though the inner html | 523 // both body and head elements are created even though the inner html |
| 524 // only contains a head or body element. | 524 // only contains a head or body element. |
| 525 return LevelDom.wrapElement(temp.children.item(tag == 'head' ? 0 : 1)); | 525 return LevelDom.wrapElement(temp.children.item(tag == 'head' ? 0 : 1)); |
| 526 } else { | 526 } else { |
| 527 throw 'HTML had ${temp.childElementCount} top level elements but 1 expecte
d'; | 527 throw 'HTML had ${temp.childElementCount} top level elements but 1 expecte
d'; |
| 528 } | 528 } |
| 529 } | 529 } |
| 530 | 530 |
| 531 factory Element.tag(String tag) { | 531 factory ElementWrappingImplementation.tag(String tag) { |
| 532 return LevelDom.wrapElement(dom.document.createElement(tag)); | 532 return LevelDom.wrapElement(dom.document.createElement(tag)); |
| 533 } | 533 } |
| 534 | 534 |
| 535 ElementWrappingImplementation._wrap(ptr) : super._wrap(ptr); | 535 ElementWrappingImplementation._wrap(ptr) : super._wrap(ptr); |
| 536 | 536 |
| 537 ElementAttributeMap _elementAttributeMap; | 537 ElementAttributeMap _elementAttributeMap; |
| 538 ElementList _elements; | 538 ElementList _elements; |
| 539 _CssClassSet _cssClassSet; | 539 _CssClassSet _cssClassSet; |
| 540 _DataAttributeMap _dataAttributes; | 540 _DataAttributeMap _dataAttributes; |
| 541 | 541 |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 703 | 703 |
| 704 void scrollIntoView([bool centerIfNeeded = null]) { | 704 void scrollIntoView([bool centerIfNeeded = null]) { |
| 705 _ptr.scrollIntoViewIfNeeded(centerIfNeeded); | 705 _ptr.scrollIntoViewIfNeeded(centerIfNeeded); |
| 706 } | 706 } |
| 707 | 707 |
| 708 bool matchesSelector([String selectors = null]) { | 708 bool matchesSelector([String selectors = null]) { |
| 709 return _ptr.webkitMatchesSelector(selectors); | 709 return _ptr.webkitMatchesSelector(selectors); |
| 710 } | 710 } |
| 711 | 711 |
| 712 void set scrollLeft(int value) { _ptr.scrollLeft = value; } | 712 void set scrollLeft(int value) { _ptr.scrollLeft = value; } |
| 713 | 713 |
| 714 void set scrollTop(int value) { _ptr.scrollTop = value; } | 714 void set scrollTop(int value) { _ptr.scrollTop = value; } |
| 715 | 715 |
| 716 Future<ElementRect> get rect() { | 716 Future<ElementRect> get rect() { |
| 717 return _createMeasurementFuture( | 717 return _createMeasurementFuture( |
| 718 () => new ElementRectWrappingImplementation(_ptr), | 718 () => new ElementRectWrappingImplementation(_ptr), |
| 719 new Completer<ElementRect>()); | 719 new Completer<ElementRect>()); |
| 720 } | 720 } |
| 721 | 721 |
| 722 Future<CSSStyleDeclaration> get computedStyle() { | 722 Future<CSSStyleDeclaration> get computedStyle() { |
| 723 // TODO(jacobr): last param should be null, see b/5045788 | 723 // TODO(jacobr): last param should be null, see b/5045788 |
| 724 return getComputedStyle(''); | 724 return getComputedStyle(''); |
| 725 } | 725 } |
| 726 | 726 |
| 727 Future<CSSStyleDeclaration> getComputedStyle(String pseudoElement) { | 727 Future<CSSStyleDeclaration> getComputedStyle(String pseudoElement) { |
| 728 return _createMeasurementFuture(() => | 728 return _createMeasurementFuture(() => |
| 729 LevelDom.wrapCSSStyleDeclaration( | 729 LevelDom.wrapCSSStyleDeclaration( |
| 730 dom.window.getComputedStyle(_ptr, pseudoElement)), | 730 dom.window.getComputedStyle(_ptr, pseudoElement)), |
| 731 new Completer<CSSStyleDeclaration>()); | 731 new Completer<CSSStyleDeclaration>()); |
| 732 } | 732 } |
| 733 | 733 |
| 734 ElementEvents get on() { | 734 ElementEvents get on() { |
| 735 if (_on === null) { | 735 if (_on === null) { |
| 736 _on = new ElementEventsImplementation._wrap(_ptr); | 736 _on = new ElementEventsImplementation._wrap(_ptr); |
| 737 } | 737 } |
| 738 return _on; | 738 return _on; |
| 739 } | 739 } |
| 740 } | 740 } |
| OLD | NEW |