| // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| import 'dart:async'; |
| import 'dart:html'; |
| |
| HtmlElement element(CustomElement e) => e.element; |
| |
| class CustomElement { |
| static Expando reverseElements = new Expando(); |
| static CustomElement reverse(HtmlElement element) => reverseElements[element]; |
| |
| static List<CustomElement> toBeAttached = <CustomElement>[]; |
| static void drainAttached() { |
| // Send 'attached' to elements that have been attached to the document. |
| bool fired = false; |
| var connectedElements = toBeAttached |
| .where((CustomElement element) => element.element.isConnected) |
| .toList(); |
| for (CustomElement element in connectedElements) { |
| toBeAttached.remove(element); |
| element.attached(); |
| fired = true; |
| } |
| |
| if (toBeAttached.isEmpty) { |
| return; // Done. |
| } |
| |
| if (fired) { |
| // The 'attached' events above may have scheduled microtasks that will |
| // will add more CustomElements to be document, e.g. 'render'. |
| scheduleMicrotask(() => drainAttached()); |
| } |
| |
| while (!toBeAttached.isEmpty) { |
| // Either this element will never be attached or it will be attached |
| // after a turn of the outer event loop. Fire 'attached' in case it is |
| // the latter, since firing it out of order is preferable to not firing |
| // it at all. |
| CustomElement element = toBeAttached.removeLast(); |
| print("Warning: created but not in document: $element"); |
| element.attached(); |
| } |
| } |
| |
| final HtmlElement element; |
| CustomElement.created(String elementClass) |
| : element = document.createElement("shadow") { |
| reverseElements[element] = this; |
| element.classes = [elementClass]; |
| |
| if (toBeAttached.isEmpty) { |
| scheduleMicrotask(() => drainAttached()); |
| } |
| toBeAttached.add(this); |
| } |
| |
| void attached() {} |
| void detached() {} |
| |
| Element get parent => element.parent; |
| |
| List<Element> get children => element.children; |
| set children(List<Element> c) => element.children = c; |
| |
| CssClassSet get classes => element.classes; |
| set classes(dynamic c) => element.classes = c; |
| |
| String get title => element.title; |
| set title(String t) => element.title = t; |
| |
| String get text => element.text; |
| set text(String t) => element.text = t; |
| |
| CssStyleDeclaration get style => element.style; |
| |
| ElementStream<MouseEvent> get onClick => element.onClick; |
| |
| Rectangle getBoundingClientRect() => element.getBoundingClientRect(); |
| |
| List<Node> getElementsByClassName(String c) => |
| element.getElementsByClassName(c); |
| |
| void scrollIntoView() => element.scrollIntoView(); |
| } |