| OLD | NEW |
| (Empty) |
| 1 Sky DOM APIs | |
| 2 ============ | |
| 3 | |
| 4 ```dart | |
| 5 SKY MODULE | |
| 6 <!-- part of sky:core --> | |
| 7 | |
| 8 <script> | |
| 9 // ELEMENT TREE API | |
| 10 | |
| 11 abstract class ChildNode { | |
| 12 @nonnull external TreeScope get ownerScope; // O(1) | |
| 13 | |
| 14 external ParentNode get parentNode; // O(1) | |
| 15 external Element get parentElement; // O(1) // if parentNode isn't an element,
returns null | |
| 16 external ChildNode get previousSibling; // O(1) | |
| 17 external ChildNode get nextSibling; // O(1) | |
| 18 | |
| 19 // the following all throw if parentNode is null | |
| 20 external void insertBefore(@nonnull List</*@nonnull*/ ChildNode> nodes); // O(
N) in number of arguments plus all their descendants | |
| 21 external void insertAfter(@nonnull List</*@nonnull*/ ChildNode> nodes); // O(N
) in number of arguments plus all their descendants | |
| 22 external void replaceWith(@nonnull List</*@nonnull*/ ChildNode> nodes); // O(N
) in number of descendants plus arguments plus all their descendants | |
| 23 external void remove(); // O(N) in number of descendants | |
| 24 | |
| 25 // called when parentNode changes | |
| 26 external void parentChangeCallback(ParentNode oldParent, ParentNode newParent,
ChildNode previousSibling, ChildNode nextSibling); // O(N) in descendants | |
| 27 // default implementation calls attached/detached | |
| 28 void attachedCallback() { } | |
| 29 void detachedCallback() { } | |
| 30 | |
| 31 external List<ContentElement> getDestinationInsertionPoints(); // O(N) in numb
er of insertion points the node is in | |
| 32 // returns the <content> elements to which this element was distributed | |
| 33 } | |
| 34 | |
| 35 abstract class Node extends EventTarget { | |
| 36 @override | |
| 37 external List</*@nonnull*/ EventTarget> getEventDispatchChain(); // O(N) in nu
mber of ancestors across shadow trees | |
| 38 // implements EventTarget.getEventDispatchChain() | |
| 39 // returns the event dispatch chain (including handling shadow trees) | |
| 40 | |
| 41 external Node cloneNode({bool deep: false}); // O(1) if deep=false, O(N) in th
e number of descendants if deep=true | |
| 42 | |
| 43 external ElementStyleDeclarationList get style; // O(1) | |
| 44 // for nodes that aren't reachable from the Application Document, returns null | |
| 45 // (so in particular orphaned subtrees and nodes in module documents don't hav
e one) | |
| 46 // -- should be updated when the node's parent chain changes (same time as, e
.g., | |
| 47 // the id hashtable is updated) | |
| 48 // also always returns null for ContentElement elements and ShadowRoot nodes | |
| 49 | |
| 50 external RenderNode get renderNode; // O(1) | |
| 51 // this will be null until the first time it is rendered | |
| 52 // it becomes null again when it is taken out of the rendering (see style.md) | |
| 53 | |
| 54 Type getLayoutManager() => null; // O(1) | |
| 55 | |
| 56 void resetLayoutManager() { // O(1) | |
| 57 if (renderNode != null) { | |
| 58 renderNode._layoutManager = null; | |
| 59 renderNode._needsManager = true; | |
| 60 } | |
| 61 } | |
| 62 } | |
| 63 | |
| 64 abstract class ParentNode extends Node { | |
| 65 external ChildNode get firstChild; // O(1) | |
| 66 external ChildNode get lastChild; // O(1) | |
| 67 | |
| 68 // Returns a new List every time. | |
| 69 external List</*nonnull*/ ChildNode> getChildNodes(); // O(N) in number of chi
ld nodes | |
| 70 external List<Element> getChildElements(); // O(N) in number of child nodes | |
| 71 // TODO(ianh): might not be necessary if we have the parser drop unnecessary w
hitespace text nodes | |
| 72 | |
| 73 external void append(@nonnull List</*nonnull*/ ChildNode> nodes); // O(N) in n
umber of arguments plus all their descendants | |
| 74 external void prepend(@nonnull List</*nonnull*/ ChildNode> nodes); // O(N) in
number of arguments plus all their descendants | |
| 75 external void replaceChildrenWith(@nonnull List</*nonnull*/ ChildNode> nodes);
// O(N) in number of descendants plus arguments plus all their descendants | |
| 76 } | |
| 77 | |
| 78 class Attr { | |
| 79 const Attr (this.name, [this.value = '']); // O(1) | |
| 80 final String name; // O(1) | |
| 81 final String value; // O(1) | |
| 82 } | |
| 83 | |
| 84 // @tagname annotation for registering elements | |
| 85 // only useful when placed on classes that inherit from Element | |
| 86 class tagname extends AutomaticMetadata { | |
| 87 const tagname(this.name); | |
| 88 @nonnull final String name; | |
| 89 void init(DeclarationMirror target, Module module) { | |
| 90 assert(target is ClassMirror); | |
| 91 if (!target.isSubclassOf(reflectClass(Element))) | |
| 92 throw Error('@tagname can only be used on descendants of Element'); | |
| 93 module.registerElement(name, (target as ClassMirror).reflectedType); | |
| 94 } | |
| 95 } | |
| 96 | |
| 97 abstract class FindRoot { } | |
| 98 | |
| 99 abstract class Element extends ParentNode with ChildNode implements FindRoot { | |
| 100 external Element({Map</*@nonnull*/ String, /*@nonnull*/ String> attributes: nu
ll, | |
| 101 List</*nonnull*/ ChildNode> nodes: null, | |
| 102 Module hostModule: null}); // O(M+N), M = number of attribute
s, N = number of nodes plus all their descendants | |
| 103 // initialises the internal attributes table | |
| 104 // appends the given child nodes | |
| 105 // if this.needsShadow, creates a shadow tree | |
| 106 | |
| 107 @nonnull String get tagName { // O(N) in number of annotations on the class | |
| 108 // throws a StateError if the class doesn't have an @tagname annotation | |
| 109 var tagnameClass = reflectClass(tagname); | |
| 110 return (reflectClass(this.runtimeType).metadata.singleWhere((mirror) => mirr
or.type == tagnameClass).reflectee as tagname).value; | |
| 111 } | |
| 112 | |
| 113 @nonnull external bool hasAttribute(@nonnull String name); // O(N) in number o
f attributes | |
| 114 @nonnull external String getAttribute(@nonnull String name); // O(N) in number
of attributes | |
| 115 external void setAttribute(@nonnull String name, [@nonnull String value = ''])
; // O(N) in number of attributes | |
| 116 external void removeAttribute(@nonnull String name); // O(N) in number of attr
ibutes | |
| 117 | |
| 118 // Returns a new Array and new Attr instances every time. | |
| 119 @nonnull external List<Attr> getAttributes(); // O(N) in number of attributes | |
| 120 | |
| 121 get bool needsShadow => false; // O(1) | |
| 122 external ShadowRoot get shadowRoot; // O(1) | |
| 123 // returns the shadow root | |
| 124 // TODO(ianh): Should this be mutable? It would help explain how it gets set..
. | |
| 125 | |
| 126 void endTagParsedCallback() { } | |
| 127 void attributeChangeCallback(String name, String oldValue, String newValue) {
} | |
| 128 // name will never be null when this is called by sky | |
| 129 | |
| 130 // TODO(ianh): does a node ever need to know when it's been redistributed? | |
| 131 | |
| 132 @override | |
| 133 Type getLayoutManager() { // O(1) | |
| 134 if (renderNode) | |
| 135 return renderNode.getProperty(phDisplay); | |
| 136 return super.getLayoutManager(); | |
| 137 } | |
| 138 } | |
| 139 | |
| 140 class Text extends Node with ChildNode { | |
| 141 external Text([@nonnull String value = '']); // O(1) | |
| 142 | |
| 143 @nonnull external String get value; // O(1) | |
| 144 external void set (@nonnull String value); // O(1) | |
| 145 | |
| 146 void valueChangeCallback(@nonnull String oldValue, @nonnull String newValue) {
} | |
| 147 | |
| 148 @override | |
| 149 Type getLayoutManager() => TextLayoutManager; // O(1) | |
| 150 } | |
| 151 | |
| 152 class DocumentFragment extends ParentNode implements FindRoot { | |
| 153 DocumentFragment([List</*nonnull*/ ChildNode> nodes = null]); // O(N) in numbe
r of arguments plus all their descendants | |
| 154 } | |
| 155 | |
| 156 abstract class TreeScope extends ParentNode { | |
| 157 external Document get ownerDocument; // O(1) | |
| 158 external TreeScope get parentScope; // O(1) | |
| 159 | |
| 160 external Element findId(String id); // O(1) | |
| 161 // throws if id is null | |
| 162 } | |
| 163 | |
| 164 class ShadowRoot extends TreeScope implements FindRoot { | |
| 165 ShadowRoot([this._host]); // O(1) | |
| 166 // note that there is no way in the API to use a newly created ShadowRoot curr
ently | |
| 167 | |
| 168 Element _host; | |
| 169 Element get host => _host; // O(1) | |
| 170 } | |
| 171 | |
| 172 class Document extends TreeScope implements FindRoot { | |
| 173 external Document ([List</*@nonnull*/ ChildNode> nodes = null]); // O(N) in nu
mber of arguments plus all their descendants | |
| 174 } | |
| 175 | |
| 176 class ApplicationDocument extends Document { | |
| 177 external ApplicationDocument ([List</*@nonnull*/ ChildNode> nodes = null]); //
O(N) in number of /nodes/ arguments plus all their descendants | |
| 178 | |
| 179 @override | |
| 180 Type getLayoutManager() => rootLayoutManager; // O(1) | |
| 181 } | |
| 182 | |
| 183 Type rootLayoutManager = BlockLayoutManager; // O(1) | |
| 184 | |
| 185 | |
| 186 // BUILT-IN ELEMENTS | |
| 187 | |
| 188 @tagname('import') | |
| 189 class ImportElement extends Element { | |
| 190 ImportElement = Element; | |
| 191 | |
| 192 @override | |
| 193 Type getLayoutManager() => null; // O(1) | |
| 194 } | |
| 195 | |
| 196 @tagname('template') | |
| 197 class TemplateElement extends Element { | |
| 198 TemplateElement = Element; | |
| 199 | |
| 200 // TODO(ianh): convert <template> to using a token stream instead of a Documen
tFragment | |
| 201 | |
| 202 @nonnull external DocumentFragment get content; // O(1) | |
| 203 | |
| 204 @override | |
| 205 Type getLayoutManager() => null; // O(1) | |
| 206 } | |
| 207 | |
| 208 @tagname('script') | |
| 209 class ScriptElement extends Element { | |
| 210 ScriptElement = Element; | |
| 211 | |
| 212 @override | |
| 213 Type getLayoutManager() => null; // O(1) | |
| 214 } | |
| 215 | |
| 216 @tagname('style') | |
| 217 class StyleElement extends Element { | |
| 218 StyleElement = Element; | |
| 219 | |
| 220 @nonnull external List</*@nonnull*/ Rule> getRules(); // O(N) in rules | |
| 221 | |
| 222 @override | |
| 223 Type getLayoutManager() => null; // O(1) | |
| 224 } | |
| 225 | |
| 226 @tagname('content') | |
| 227 class ContentElement extends Element { | |
| 228 ContentElement = Element; | |
| 229 | |
| 230 @nonnull external List</*@nonnull*/ Node> getDistributedNodes(); // O(N) in di
stributed nodes | |
| 231 | |
| 232 @override | |
| 233 Type getLayoutManager() => null; // O(1) | |
| 234 } | |
| 235 | |
| 236 @tagname('img') | |
| 237 class ImgElement extends Element { | |
| 238 ImgElement = Element; | |
| 239 | |
| 240 @override | |
| 241 Type getLayoutManager() => ImgElementLayoutManager; // O(1) | |
| 242 } | |
| 243 | |
| 244 @tagname('div') | |
| 245 class DivElement extends Element { | |
| 246 DivElement = Element; | |
| 247 } | |
| 248 | |
| 249 @tagname('span') | |
| 250 class SpanElement extends Element { | |
| 251 SpanElement = Element; | |
| 252 } | |
| 253 | |
| 254 @tagname('iframe') | |
| 255 class IframeElement extends Element { | |
| 256 IframeElement = Element; | |
| 257 | |
| 258 @override | |
| 259 Type getLayoutManager() => IframeElementLayoutManager; // O(1) | |
| 260 } | |
| 261 | |
| 262 @tagname('t') | |
| 263 class TElement extends Element { | |
| 264 TElement = Element; | |
| 265 } | |
| 266 | |
| 267 @tagname('a') | |
| 268 class AElement extends Element { | |
| 269 AElement = Element; | |
| 270 } | |
| 271 | |
| 272 @tagname('title') | |
| 273 class TitleElement extends Element { | |
| 274 TitleElement = Element; | |
| 275 | |
| 276 @override | |
| 277 Type getLayoutManager() => null; // O(1) | |
| 278 } | |
| 279 | |
| 280 class _ErrorElement extends Element { | |
| 281 _ErrorElement._create(); | |
| 282 | |
| 283 @override | |
| 284 Type getLayoutManager() => _ErrorElementLayoutManager; // O(1) | |
| 285 } | |
| 286 | |
| 287 class SelectorQuery { | |
| 288 external SelectorQuery(@nonnull String selector); // O(F()) where F() is the c
omplexity of the selector | |
| 289 | |
| 290 @nonnull external bool matches(@nonnull Element element); // O(F()) | |
| 291 external Element find(@nonnull FindRoot root); // O(N*F())+O(M) where N is the
number of descendants and M the average depth of the tree | |
| 292 @nonnull external List</*@nonnull*/ Element> findAll(FindRoot root); // O(N*F(
))+O(N*M) where N is the number of descendants and M the average depth of the tr
ee | |
| 293 } | |
| 294 </script> | |
| 295 ``` | |
| OLD | NEW |