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

Side by Side Diff: sky/specs/elements.md

Issue 926733002: Specs: update elements.md to define List-based APIs in terms of Node-based APIs, and finish dartifi… (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 10 months 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
« no previous file with comments | « no previous file | sky/specs/modules.md » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 Sky DOM APIs 1 Sky DOM APIs
2 ============ 2 ============
3 3
4 ```dart 4 ```dart
5 SKY MODULE 5 SKY MODULE
6 <!-- part of sky:core --> 6 <!-- part of sky:core -->
7 7
8 <script> 8 <script>
9 // ELEMENT TREE API 9 // ELEMENT TREE API
10 10
11 abstract class Node extends EventTarget { 11 abstract class Node extends EventTarget {
12 @override 12 @override
13 external List<EventTarget> getEventDispatchChain(); // O(N) in number of ances tors across shadow trees 13 external List<EventTarget> getEventDispatchChain(); // O(N) in number of ances tors across shadow trees
14 // implements EventTarget.getEventDispatchChain() 14 // implements EventTarget.getEventDispatchChain()
15 // returns the event dispatch chain (including handling shadow trees) 15 // returns the event dispatch chain (including handling shadow trees)
16 16
17 external Root get owner; // O(1) 17 external Root get owner; // O(1)
18 18
19 external ParentNode get parentNode; // O(1) 19 external ParentNode get parentNode; // O(1)
20 external Element get parentElement; // O(1) // if parentNode isn't an element, returns null 20 Element get parentElement => {
21 if (parentNode is Element)
22 return parentNode as Element;
23 return null;
24 }
25
21 external Node get previousSibling; // O(1) 26 external Node get previousSibling; // O(1)
27 Element get previousElementSibling => {
28 var result = previousSibling;
29 while (result != null && result is! Element)
30 result = result.previousSibling;
31 return result as Element;
32 }
33
22 external Node get nextSibling; // O(1) 34 external Node get nextSibling; // O(1)
35 Element get nextElementSibling => {
36 var result = nextSibling;
37 while (result != null && result is! Element)
38 result = result.nextSibling;
39 return result as Element;
40 }
23 41
24 // the following all throw if parentNode is null 42 external void _insertBefore(Node node); // O(N) in number of descendants
25 external void insertBefore(List nodes); // O(N) in number of arguments plus al l their descendants 43 // node must be Text or Element, parentNode must be non-null
26 external void insertAfter(List nodes); // O(N) in number of arguments plus all their descendants 44 void insertBefore(List nodes) {
27 // TODO(ianh): rename insertBefore() and insertAfter() since the Web has an in sertBefore() that means 45 List.forEach((node) {
28 // something else. What's a good name, though? 46 if (node is String)
29 external void replaceWith(List nodes); // O(N) in number of descendants plus a rguments plus all their descendants 47 node = new Text(node);
30 // nodes must be String, Text, or Element 48 _insertBefore(node);
49 });
50 }
51
52 void _insertAfter(Node node); // O(N) in number of arguments plus all their de scendants
53 // node must be Text or Element, parentNode must be non-null
54 void insertAfter(List nodes) {
55 var lastNode = this;
56 List.forEach((node) {
57 if (node is String)
58 node = new Text(node);
59 lastNode._insertAfter(node);
60 lastNode = node;
61 });
62 }
63
64 void replaceWith(List nodes) {
65 if (nextSibling != null) {
66 var anchor = nextSibling;
67 remove(); // parentNode can't be null here, so this won't throw
68 anchor.insertBefore(nodes);
69 } else {
70 var anchor = parentNode;
71 remove(); // throws if parentNode is null
72 anchor.append(nodes);
73 }
74 }
31 75
32 external void remove(); // O(N) in number of descendants 76 external void remove(); // O(N) in number of descendants
77 // parentNode must be non-null
33 78
34 // called when parentNode changes 79 // called when parentNode changes
35 // this is why insertBefore(), append(), et al, are O(N) -- the whole affected subtree is walked 80 // this is why insertBefore(), append(), et al, are O(N) -- the whole affected subtree is walked
36 // mutating the element tree from within this is strongly discouraged, since i t will result in the 81 // mutating the element tree from within this is strongly discouraged, since i t will result in the
37 // callbacks being invoked while the element tree is in a different state than implied by the callbacks 82 // callbacks being invoked while the element tree is in a different state than implied by the callbacks
38 external void parentChangeCallback(ParentNode oldParent, ParentNode newParent, Node previousSibling, Node nextSibling); // O(N) in descendants 83 external void parentChangeCallback(ParentNode oldParent, ParentNode newParent, Node previousSibling, Node nextSibling); // O(N) in descendants
39 // default implementation calls attached/detached 84 // default implementation calls attached/detached
40 void attachedCallback() { } 85 void attachedCallback() { }
41 void detachedCallback() { } 86 void detachedCallback() { }
42 87
(...skipping 20 matching lines...) Expand all
63 void resetLayoutManager() { // O(1) 108 void resetLayoutManager() { // O(1)
64 if (renderNode != null) { 109 if (renderNode != null) {
65 renderNode._layoutManager = null; 110 renderNode._layoutManager = null;
66 renderNode._needsManager = true; 111 renderNode._needsManager = true;
67 } 112 }
68 } 113 }
69 } 114 }
70 115
71 abstract class ParentNode extends Node { 116 abstract class ParentNode extends Node {
72 external Node get firstChild; // O(1) 117 external Node get firstChild; // O(1)
118 Element get firstElementChild => {
119 var result = firstChild;
120 while (result != null && result is! Element)
121 result = result.nextSibling;
122 return result as Element;
123 }
124
73 external Node get lastChild; // O(1) 125 external Node get lastChild; // O(1)
126 Element get lastElementChild => {
127 var result = lastChild;
128 while (result != null && result is! Element)
129 result = result.previousSibling;
130 return result as Element;
131 }
74 132
75 // Returns a new List every time. 133 // Returns a new List every time.
76 external List<Node> getChildren(); // O(N) in number of child nodes 134 external List<Node> getChildren(); // O(N) in number of child nodes
77 external List<Element> getChildElements(); // O(N) in number of child nodes 135 List<Element> getChildElements() {
78 // TODO(ianh): might not be necessary if we have the parser drop unnecessary w hitespace text nodes 136 // that the following works without a cast is absurd
137 return getChildren().where((node) => node is Element).toList();
138 }
79 139
80 external void append(List nodes); // O(N) in number of arguments plus all thei r descendants 140 external void _appendChild(Node node); // O(N) in number of descendants
81 external void appendChild(Node child); // O(N) in number of descandants 141 // node must be Text or Element
82 external void prepend(List nodes); // O(N) in number of arguments plus all the ir descendants 142 void appendChild(Node node) {
83 external void replaceChildrenWith(List nodes); // O(N) in number of descendant s plus arguments plus all their descendants 143 if (node is String)
84 // nodes must be String, Text, or Element 144 node = new Text(node);
145 _appendChild(node);
146 }
147 void append(List nodes) {
148 nodes.forEach(appendChild);
149 }
150
151 external void _prependChild(Node node); // O(N) in number of descendants
152 // node must be Text or Element
153 void prependChild(Node node) {
154 if (node is String)
155 node = new Text(node);
156 _prependChild(node);
157 }
158 void prepend(List nodes) {
159 // note: not implemented in terms of _prependChild()
160 if (firstChild != null)
161 firstChild.insertBefore(nodes);
162 else
163 append(nodes);
164 }
165
166 external void removeChildren(); // O(N) in number of descendants
167 void setChild(Node node) {
168 removeChildren();
169 appendChild(node);
170 }
171 void setChildren(List nodes) {
172 removeChildren();
173 append(nodes);
174 }
85 } 175 }
86 176
87 class Attr { 177 class Attr {
88 const Attr (this.name, [this.value = '']); // O(1) 178 const Attr (this.name, [this.value = '']); // O(1)
89 final String name; // O(1) 179 final String name; // O(1)
90 final String value; // O(1) 180 final String value; // O(1)
91 } 181 }
92 182
93 // @tagname annotation for registering elements 183 // @tagname annotation for registering elements
94 // only useful when placed on classes that inherit from Element 184 // only useful when placed on classes that inherit from Element
95 class tagname extends AutomaticMetadata { 185 class tagname extends AutomaticMetadata {
96 const tagname(this.name); 186 const tagname(this.name);
97 final String name; 187 final String name;
98 void init(DeclarationMirror target, Module module) { 188 void init(DeclarationMirror target, Module module) {
99 assert(target is ClassMirror); 189 assert(target is ClassMirror);
100 if (!target.isSubclassOf(reflectClass(Element))) 190 if (!target.isSubclassOf(reflectClass(Element)))
101 throw Error('@tagname can only be used on descendants of Element'); 191 throw Error('@tagname can only be used on descendants of Element');
102 module.registerElement(name, (target as ClassMirror).reflectedType); 192 module.registerElement(name, (target as ClassMirror).reflectedType);
103 } 193 }
104 } 194 }
105 195
106 abstract class Element extends ParentNode with Node { 196 abstract class Element extends ParentNode with Node {
107 external Element({Map<String, String> attributes: null, 197 external Element({Map<String, String> attributes: null,
108 List children: null, 198 List children: null,
109 Module hostModule: null}); // O(M+N), M = number of attribute s, N = number of children nodes plus all their descendants 199 Module hostModule: null}); // O(M+N), M = number of attribute s, N = number of children nodes plus all their descendants
110 // initialises the internal attributes table 200 // initialises the internal attributes table, which is a ordered list
111 // appends the given children nodes 201 // appends the given children nodes
112 // children must be String, Text, or Element 202 // children must be String, Text, or Element
113 // if this.needsShadow, creates a shadow tree 203 // if this.needsShadow, creates a shadow tree
114 204
115 String get tagName { // O(N) in number of annotations on the class 205 String get tagName { // O(N) in number of annotations on the class
116 // throws a StateError if the class doesn't have an @tagname annotation 206 // throws a StateError if the class doesn't have an @tagname annotation
117 var tagnameClass = reflectClass(tagname); 207 var tagnameClass = reflectClass(tagname);
118 return (reflectClass(this.runtimeType).metadata.singleWhere((mirror) => mirr or.type == tagnameClass).reflectee as tagname).value; 208 return (reflectClass(this.runtimeType).metadata.singleWhere((mirror) => mirr or.type == tagnameClass).reflectee as tagname).value;
119 } 209 }
120 210
121 external bool hasAttribute(String name); // O(N) in number of attributes 211 external bool hasAttribute(String name); // O(N) in number of attributes
122 external String getAttribute(String name); // O(N) in number of attributes 212 external String getAttribute(String name); // O(N) in number of attributes
123 external void setAttribute(String name, [String value = '']); // O(N) in numbe r of attributes 213 external void setAttribute(String name, [String value = '']); // O(N) in numbe r of attributes
124 external void removeAttribute(String name); // O(N) in number of attributes 214 external void removeAttribute(String name); // O(N) in number of attributes
125 // calling setAttribute() with a null value removes the attribute 215 // calling setAttribute() with a null value removes the attribute
126 // (calling it without a value sets it to the empty string) 216 // (calling it without a value sets it to the empty string)
127 217
128 // Returns a new Array and new Attr instances every time. 218 // Returns a new Array and new Attr instances every time.
129 external List<Attr> getAttributes(); // O(N) in number of attributes 219 external List<Attr> getAttributes(); // O(N) in number of attributes
130 220
131 get bool needsShadow => false; // O(1) 221 get bool needsShadow => false; // O(1)
132 external Root get shadowRoot; // O(1) 222 external final Root shadowRoot; // O(1)
133 // returns the shadow root 223 // returns the shadow root
134 // TODO(ianh): Should this be mutable? It would help explain how it gets set.. .
135 224
136 void endTagParsedCallback() { } 225 void endTagParsedCallback() { }
137 void attributeChangeCallback(String name, String oldValue, String newValue) { } 226 void attributeChangeCallback(String name, String oldValue, String newValue) { }
138 // name will never be null when this is called by sky 227 // name will never be null when this is called by sky
139 228
140 // TODO(ianh): does a node ever need to know when it's been redistributed? 229 // TODO(ianh): does a node ever need to know when it's been redistributed?
141 230
142 @override 231 @override
143 Type getLayoutManager() { // O(1) 232 Type getLayoutManager() { // O(1)
144 if (renderNode) 233 if (renderNode)
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 external bool matches(Element element); // O(F()) 381 external bool matches(Element element); // O(F())
293 external Element find(node root); // O(N*F())+O(M) where N is the number of de scendants and M the average depth of the tree 382 external Element find(node root); // O(N*F())+O(M) where N is the number of de scendants and M the average depth of the tree
294 external List<Element> findAll(Node root); // O(N*F())+O(N*M) where N is the n umber of descendants and M the average depth of the tree 383 external List<Element> findAll(Node root); // O(N*F())+O(N*M) where N is the n umber of descendants and M the average depth of the tree
295 // find() and findAll() throw if the root is not one of the following: 384 // find() and findAll() throw if the root is not one of the following:
296 // - Element 385 // - Element
297 // - Fragment 386 // - Fragment
298 // - Root 387 // - Root
299 } 388 }
300 </script> 389 </script>
301 ``` 390 ```
OLDNEW
« no previous file with comments | « no previous file | sky/specs/modules.md » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698