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

Side by Side Diff: client/html/src/ElementWrappingImplementation.dart

Issue 8363040: Implement measurement using futures (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: take2 Created 9 years, 1 month 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 | Annotate | Revision Log
OLDNEW
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 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 EventListenerList get search() => _get("search"); 404 EventListenerList get search() => _get("search");
405 EventListenerList get select() => _get("select"); 405 EventListenerList get select() => _get("select");
406 EventListenerList get selectStart() => _get("selectstart"); 406 EventListenerList get selectStart() => _get("selectstart");
407 EventListenerList get submit() => _get("submit"); 407 EventListenerList get submit() => _get("submit");
408 EventListenerList get touchCancel() => _get("touchcancel"); 408 EventListenerList get touchCancel() => _get("touchcancel");
409 EventListenerList get touchEnd() => _get("touchend"); 409 EventListenerList get touchEnd() => _get("touchend");
410 EventListenerList get touchLeave() => _get("touchleave"); 410 EventListenerList get touchLeave() => _get("touchleave");
411 EventListenerList get touchMove() => _get("touchmove"); 411 EventListenerList get touchMove() => _get("touchmove");
412 EventListenerList get touchStart() => _get("touchstart"); 412 EventListenerList get touchStart() => _get("touchstart");
413 EventListenerList get transitionEnd() => _get("webkitTransitionEnd"); 413 EventListenerList get transitionEnd() => _get("webkitTransitionEnd");
414 EventListenerList get fullscreenChange() => _get("fullscreenchange"); 414 EventListenerList get fullscreenChange() => _get("webkitfullscreenchange");
415 }
416
417 class SimpleClientRect implements ClientRect {
418 final num left;
419 final num top;
420 final num width;
421 final num height;
422 num get right() => left + width;
423 num get bottom() => top + height;
424
425 SimpleClientRect(this.left, this.top, this.width, this.height);
426
427 bool operator ==(ClientRect other) {
428 return other !== null && left == other.left && top == other.top
429 && width == other.width && height == other.height;
430 }
431
432 String toString() => "($left, $top, $width, $height)";
433 }
434
435 // TODO(jacobr): we cannot currently be lazy about calculating the client
436 // rects as we must perform all measurement queries at a safe point to avoid
437 // triggering unneeded layouts.
438 /**
439 * All your element measurement needs in one place
440 */
441 class ElementRectWrappingImplementation implements ElementRect {
442 final ClientRect client;
443 final ClientRect offset;
444 final ClientRect scroll;
445
446 // TODO(jacobr): should we move these outside of ElementRect to avoid the
447 // overhead of computing them every time even though they are rarely used.
448 // This should be type dom.ClientRect but that fails on dartium. b/5522629
449 final _boundingClientRect;
450 // an exception due to a dartium bug.
451 final dom.ClientRectList _clientRects;
452
453 ElementRectWrappingImplementation(dom.HTMLElement element) :
454 client = new SimpleClientRect(element.clientLeft,
455 element.clientTop,
456 element.clientWidth,
457 element.clientHeight),
458 offset = new SimpleClientRect(element.offsetLeft,
459 element.offsetTop,
460 element.offsetWidth,
461 element.offsetHeight),
462 scroll = new SimpleClientRect(element.scrollLeft,
463 element.scrollTop,
464 element.scrollWidth,
465 element.scrollHeight),
466 _boundingClientRect = element.getBoundingClientRect(),
467 _clientRects = element.getClientRects();
468
469 ClientRect get bounding() =>
470 LevelDom.wrapClientRect(_boundingClientRect);
471
472 List<ClientRect> get clientRects() {
arv (Not doing code reviews) 2011/10/27 03:16:13 Maybe just an iterable instead?
Jacob 2011/10/27 20:59:25 Any reason why this case should just be iterable w
473 final out = new List(_clientRects.length);
474 for (num i = 0; i < _clientRects.length; i++) {
475 out[i] = LevelDom.wrapClientRect(_clientRects.item(i));
476 }
477 return out;
478 }
415 } 479 }
416 480
417 class ElementWrappingImplementation extends NodeWrappingImplementation implement s Element { 481 class ElementWrappingImplementation extends NodeWrappingImplementation implement s Element {
482
483 static final _START_TAG_REGEXP = const RegExp('<(\\w+)');
arv (Not doing code reviews) 2011/10/27 03:16:13 Can this be moved to a different patch?
Jacob 2011/10/27 20:59:25 I agree this bug fix is unrelated but at this earl
484 static final _CUSTOM_PARENT_TAG_MAP = const {
485 'body' : 'html',
486 'head' : 'html',
487 'caption' : 'table',
488 'td': 'tr',
489 'tbody': 'table',
490 'colgroup': 'table',
491 'col' : 'colgroup',
492 'tr' : 'tbody',
493 'tbody' : 'table',
494 'tfoot' : 'table',
495 'thead' : 'table',
496 'track' : 'audio',
497 };
418 498
419 factory ElementWrappingImplementation.html(String html) { 499 factory ElementWrappingImplementation.html(String html) {
420 final temp = dom.document.createElement('div'); 500 String parentTag = 'div';
501 String tag;
502 final match = _START_TAG_REGEXP.firstMatch(html);
503 if (null != match) {
504 tag = match.group(1).toLowerCase();
505 if (_CUSTOM_PARENT_TAG_MAP.containsKey(tag)) {
506 parentTag = _CUSTOM_PARENT_TAG_MAP[tag];
507 }
508 }
509 final temp = dom.document.createElement(parentTag);
arv (Not doing code reviews) 2011/10/27 03:16:13 This code is really great. A big improvement over
Jacob 2011/10/27 20:59:25 I think this can be improved further. Added a TODO
421 temp.innerHTML = html; 510 temp.innerHTML = html;
422 511
423 if (temp.childElementCount != 1) { 512 if (temp.childElementCount == 1) {
513 return LevelDom.wrapElement(temp.firstElementChild);
514 } else if (temp.childElementCount > 0 && tag != null &&
515 parentTag == 'html') {
516 // Work around for edge case where both body and head
arv (Not doing code reviews) 2011/10/27 03:16:13 Which browsers? Can we link to bugs here? I think
Jacob 2011/10/27 20:59:25 The issue occurs in WebKit. I agree that your code
517 // elements are created even though the html contains a head or
518 // body.
519 return LevelDom.wrapElement(temp.querySelector(tag));
520 } else {
424 throw 'HTML had ${temp.childElementCount} top level elements but 1 expecte d'; 521 throw 'HTML had ${temp.childElementCount} top level elements but 1 expecte d';
425 } 522 }
426
427 return LevelDom.wrapElement(temp.firstElementChild);
428 } 523 }
429 524
430 factory ElementWrappingImplementation.tag(String tag) { 525 factory ElementWrappingImplementation.tag(String tag) {
431 return LevelDom.wrapElement(dom.document.createElement(tag)); 526 return LevelDom.wrapElement(dom.document.createElement(tag));
432 } 527 }
433 528
434 ElementWrappingImplementation._wrap(ptr) : super._wrap(ptr); 529 ElementWrappingImplementation._wrap(ptr) : super._wrap(ptr);
435 530
436 ElementAttributeMap _elementAttributeMap; 531 ElementAttributeMap _elementAttributeMap;
437 ElementList _elements; 532 ElementList _elements;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 } 584 }
490 585
491 void set dataAttributes(Map<String, String> value) { 586 void set dataAttributes(Map<String, String> value) {
492 Map<String, String> dataAttributes = this.dataAttributes; 587 Map<String, String> dataAttributes = this.dataAttributes;
493 dataAttributes.clear(); 588 dataAttributes.clear();
494 for (String key in value.getKeys()) { 589 for (String key in value.getKeys()) {
495 dataAttributes[key] = value[key]; 590 dataAttributes[key] = value[key];
496 } 591 }
497 } 592 }
498 593
499 int get clientHeight() => _ptr.clientHeight;
500
501 int get clientLeft() => _ptr.clientLeft;
502
503 int get clientTop() => _ptr.clientTop;
504
505 int get clientWidth() => _ptr.clientWidth;
506
507 String get contentEditable() => _ptr.contentEditable; 594 String get contentEditable() => _ptr.contentEditable;
508 595
509 void set contentEditable(String value) { _ptr.contentEditable = value; } 596 void set contentEditable(String value) { _ptr.contentEditable = value; }
510 597
511 String get dir() => _ptr.dir; 598 String get dir() => _ptr.dir;
512 599
513 void set dir(String value) { _ptr.dir = value; } 600 void set dir(String value) { _ptr.dir = value; }
514 601
515 bool get draggable() => _ptr.draggable; 602 bool get draggable() => _ptr.draggable;
516 603
(...skipping 16 matching lines...) Expand all
533 bool get isContentEditable() => _ptr.isContentEditable; 620 bool get isContentEditable() => _ptr.isContentEditable;
534 621
535 String get lang() => _ptr.lang; 622 String get lang() => _ptr.lang;
536 623
537 void set lang(String value) { _ptr.lang = value; } 624 void set lang(String value) { _ptr.lang = value; }
538 625
539 Element get lastElementChild() => LevelDom.wrapElement(_ptr.lastElementChild); 626 Element get lastElementChild() => LevelDom.wrapElement(_ptr.lastElementChild);
540 627
541 Element get nextElementSibling() => LevelDom.wrapElement(_ptr.nextElementSibli ng); 628 Element get nextElementSibling() => LevelDom.wrapElement(_ptr.nextElementSibli ng);
542 629
543 int get offsetHeight() => _ptr.offsetHeight;
544
545 int get offsetLeft() => _ptr.offsetLeft;
546
547 Element get offsetParent() => LevelDom.wrapElement(_ptr.offsetParent); 630 Element get offsetParent() => LevelDom.wrapElement(_ptr.offsetParent);
548 631
549 int get offsetTop() => _ptr.offsetTop;
550
551 int get offsetWidth() => _ptr.offsetWidth;
552
553 String get outerHTML() => _ptr.outerHTML; 632 String get outerHTML() => _ptr.outerHTML;
554 633
555 Element get previousElementSibling() => LevelDom.wrapElement(_ptr.previousElem entSibling); 634 Element get previousElementSibling() => LevelDom.wrapElement(_ptr.previousElem entSibling);
556 635
557 int get scrollHeight() => _ptr.scrollHeight;
558
559 int get scrollLeft() => _ptr.scrollLeft;
560
561 void set scrollLeft(int value) { _ptr.scrollLeft = value; }
562
563 int get scrollTop() => _ptr.scrollTop;
564
565 void set scrollTop(int value) { _ptr.scrollTop = value; }
566
567 int get scrollWidth() => _ptr.scrollWidth;
568
569 bool get spellcheck() => _ptr.spellcheck; 636 bool get spellcheck() => _ptr.spellcheck;
570 637
571 void set spellcheck(bool value) { _ptr.spellcheck = value; } 638 void set spellcheck(bool value) { _ptr.spellcheck = value; }
572 639
573 CSSStyleDeclaration get style() => LevelDom.wrapCSSStyleDeclaration(_ptr.style ); 640 CSSStyleDeclaration get style() => LevelDom.wrapCSSStyleDeclaration(_ptr.style );
574 641
575 int get tabIndex() => _ptr.tabIndex; 642 int get tabIndex() => _ptr.tabIndex;
576 643
577 void set tabIndex(int value) { _ptr.tabIndex = value; } 644 void set tabIndex(int value) { _ptr.tabIndex = value; }
578 645
(...skipping 12 matching lines...) Expand all
591 } 658 }
592 659
593 bool contains(Node element) { 660 bool contains(Node element) {
594 return _ptr.contains(LevelDom.unwrap(element)); 661 return _ptr.contains(LevelDom.unwrap(element));
595 } 662 }
596 663
597 void focus() { 664 void focus() {
598 _ptr.focus(); 665 _ptr.focus();
599 } 666 }
600 667
601 ClientRect getBoundingClientRect() {
602 return LevelDom.wrapClientRect(_ptr.getBoundingClientRect());
603 }
604
605 List<ClientRect> getClientRects() {
606 var rects = _ptr.getClientRects();
607 var out = new List(rects.length);
608 for (var i = 0; i < rects.length; i++) {
609 out.add(LevelDom.wrapClientRect(rects.item(i)));
610 }
611 return out;
612 }
613
614 Element insertAdjacentElement([String where = null, Element element = null]) { 668 Element insertAdjacentElement([String where = null, Element element = null]) {
615 return LevelDom.wrapElement(_ptr.insertAdjacentElement(where, LevelDom.unwra p(element))); 669 return LevelDom.wrapElement(_ptr.insertAdjacentElement(where, LevelDom.unwra p(element)));
616 } 670 }
617 671
618 void insertAdjacentHTML([String position_OR_where = null, String text = null]) { 672 void insertAdjacentHTML([String position_OR_where = null, String text = null]) {
619 _ptr.insertAdjacentHTML(position_OR_where, text); 673 _ptr.insertAdjacentHTML(position_OR_where, text);
620 } 674 }
621 675
622 void insertAdjacentText([String where = null, String text = null]) { 676 void insertAdjacentText([String where = null, String text = null]) {
623 _ptr.insertAdjacentText(where, text); 677 _ptr.insertAdjacentText(where, text);
(...skipping 18 matching lines...) Expand all
642 } 696 }
643 697
644 void scrollIntoView([bool centerIfNeeded = null]) { 698 void scrollIntoView([bool centerIfNeeded = null]) {
645 _ptr.scrollIntoViewIfNeeded(centerIfNeeded); 699 _ptr.scrollIntoViewIfNeeded(centerIfNeeded);
646 } 700 }
647 701
648 bool matchesSelector([String selectors = null]) { 702 bool matchesSelector([String selectors = null]) {
649 return _ptr.webkitMatchesSelector(selectors); 703 return _ptr.webkitMatchesSelector(selectors);
650 } 704 }
651 705
706 void set scrollLeft(int value) { _ptr.scrollLeft = value; }
707
708 void set scrollTop(int value) { _ptr.scrollTop = value; }
709
710 Future<ElementRect> get rect() {
711 return _createMeasurementFuture(
712 () => new ElementRectWrappingImplementation(_ptr),
713 new Completer<ElementRect>());
714 }
715
716 Future<CSSStyleDeclaration> get computedStyle() {
717 // TODO(jacobr): last param should be null, see b/5045788
718 return getComputedStyle('');
719 }
720
721 Future<CSSStyleDeclaration> getComputedStyle(String pseudoElement) {
722 return _createMeasurementFuture(() =>
723 LevelDom.wrapCSSStyleDeclaration(
724 dom.window.getComputedStyle(_ptr, pseudoElement)),
725 new Completer<CSSStyleDeclaration>());
726 }
727
652 ElementEvents get on() { 728 ElementEvents get on() {
653 if (_on === null) { 729 if (_on === null) {
654 _on = new ElementEventsImplementation._wrap(_ptr); 730 _on = new ElementEventsImplementation._wrap(_ptr);
655 } 731 }
656 return _on; 732 return _on;
657 } 733 }
658 } 734 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698