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

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

Issue 908983002: Specs: Element registration in the Dart world (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 | « sky/specs/dom.md ('k') | sky/specs/script.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 Module System 1 Sky Module System
2 ================= 2 =================
3 3
4 This document describes the Sky module system. 4 This document describes the Sky module system.
5 5
6 Overview 6 Overview
7 -------- 7 --------
8 8
9 The Sky module system is based on the ``import`` element. In its 9 The Sky module system is based on the ``import`` element. In its
10 most basic form, you import a module as follows: 10 most basic form, you import a module as follows:
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 all the modules referenced by ``<import>`` element up to that 48 all the modules referenced by ``<import>`` element up to that
49 ``<script>`` element and all the libraries defined by ``<script>`` 49 ``<script>`` element and all the libraries defined by ``<script>``
50 elements up to that point, interleaved so as to maintain the same 50 elements up to that point, interleaved so as to maintain the same
51 relative order as those elements were first seen by the parser. 51 relative order as those elements were first seen by the parser.
52 52
53 When a library imports a module, it actually imports all the libraries 53 When a library imports a module, it actually imports all the libraries
54 that were declared by that module except the aforementioned element 54 that were declared by that module except the aforementioned element
55 tree library. 55 tree library.
56 56
57 At the end of the ``<script>`` block's source, if it parsed correctly 57 At the end of the ``<script>`` block's source, if it parsed correctly
58 and completely, the following code is appended: 58 and completely, the conceptual equivalent of the following code is
59 appended (but without affecting the library's list of declarations and
60 without any possibility of it clashing with identifiers described in
61 the library itself):
59 62
60 ```dart 63 ```dart
61 class _ { } 64 class _ { }
62 module.registerElements(reflectClass(_).owner); 65 void main() {
66 LibraryMirror library = reflectClass(_).owner as LibraryMirror;
67 if (library.declarations.containsKey(#init) && library.declarations[#init] is MethodMirror)
68 init();
69 module.init(library);
70 }
63 ``` 71 ```
64 72
73 Then, that ``main()`` function is called.
74
65 TODO(ianh): decide what URL and name we should give the libraries, as 75 TODO(ianh): decide what URL and name we should give the libraries, as
66 exposed in MirrorSystem.getName(libraryMirror.qualifiedName) etc 76 exposed in MirrorSystem.getName(libraryMirror.qualifiedName) etc
67 77
68 The ``Module`` class is defined in ``sky:core`` as follows: 78 The ``Module`` class is defined in ``sky:core`` as follows:
69 79
80 ```dart
70 81
71 TODO(ianh): dartification of the rest of this file 82 abstract class AbstractModule extends EventTarget {
83 AbstractModule({this.document, this.url});
72 84
73 ### Exporting element definitions ### 85 final Document document; // O(1)
86 // the Document of the module or application
74 87
75 When importing a module into another, Sky runs the following steps: 88 final String url;
76 - let export be the imported module's ``exports`` value
77 - try to import export
78 - if that fails:
79 - try to import each property of export
80 89
81 "Try to import" a value means to run the following steps: 90 @nonnull external Future<@nonnull Module> import(String url); // O(Yikes)
82 - if the value is an element constructor (generated by 91 // load and return the URL at the given Module
83 ``registerElement()``), call this importer module's 92 // if it's already loaded, the future will resolve immediately
84 ``registerElement()`` with the value 93 // if loading fails, the future will have an error
85 94
86 ### IDL ### 95 @nonnull List</*@nonnull*/ Module> getImports(); // O(N)
96 // returns the Module objects of all the imported modules
87 97
88 ```javascript 98 external registerElement(@nonnull String tagname, @nonnull Type elementClass); // O(1)
89 dictionary InternalElementOptions { 99 // registers a tag name with the parser
90 String tagName; 100 // only useful during parse time
91 Boolean shadow = false; 101 // verify that tagname isn't null or empty
92 Object prototype = Element; 102 // verify that elementClass is the Type of a class that extends Element (direc tly or indirectly, but not via "implements" or "with")
93 } 103 // (see the @tagname code for an example of how to verify that from dart)
94 interface InternalElementConstructorWithoutShadow { 104 // verify that there's not already a class registered for this tag name
95 constructor (Module hostModule); 105 // if there is, then mark this tagname is broken, so that it acts as if it's n ot registered in the parser,
96 attribute String tagName; 106 // and, if this is the first time it was marked broken, log a console message regarding the issue
97 } 107 // (mention the tag name but not the classes, so that it's not observable that this currently happens out of order)
98 interface InternalElementConstructorWithShadow {
99 constructor (Module hostModule);
100 attribute String tagName;
101 attribute Boolean shadow;
102 }
103 typedef ElementRegistrationOptions (InternalElementOptions or
104 InternalElementConstructorWithoutShadow or
105 InternalElementConstructorWithShadow);
106 108
107 abstract class AbstractModule : EventTarget { 109 void init(LibraryMirror library) {
108 readonly attribute Document document; // O(1) // the Document of the module or application 110 library.declarations.forEach((Symbol s, DeclarationMirror d) {
109 Promise<any> import(String url); // O(Yikes) // returns the module's exports 111 d.metadata.forEach((InstanceMirror i) {
110 private Array<Module> getImports(); O(N) // returns the Module objects of all the imported modules 112 if (i.reflectee is AutomaticMetadata)
111 113 i.reflectee.init(d, this);
112 readonly attribute String url; 114 });
113 115 });
114 ElementConstructor registerElement(Object options); // O(1) 116 }
115 // if you call registerElement() with an object that was created by
116 // registerElement(), it just returns the object after registering it,
117 // rather than creating a new constructor
118 // otherwise, it proceeds as follows:
119 // - if options is a Function (i.e. it is either an
120 // InternalElementConstructorWithoutShadow object or an
121 // InternalElementConstructorWithShadow object), then let
122 // constructor be that function, and let prototype be that
123 // functions's prototype; otherwise, let constructor be a no-op
124 // function and let prototype be the prototype property of the
125 // object passed in (the InternalElementOptions; prototype
126 // defaults to Element).
127 // - let shadow be option's shadow property's value coerced to a
128 // boolean, if the property is present, or else the value false.
129 // - let tagName be option's tagName property's value.
130 // - create a new Function that acts as if it had the signature of
131 // the constructors in the ElementConstructor interface, and that
132 // runs the follows steps when called:
133 // - throw if not called as a constructor
134 // - create an actual element object (the C++-backed object)
135 // called tagName, along with the specified attributes
136 // - initialise the shadow tree if shadow is true
137 // - call constructor, if it's not null, with the module
138 // within which the new element is being constructed as the
139 // argument
140 // - append all the specified children
141 // - mark that new Function as created by registerElement() so that
142 // it can be recognised if used as an argument to
143 // registerElement()
144 // - let that new Function's prototype be the aforementioned prototype
145 // - let that new Function have tagName and shadow properties set to
146 // the aforementioned tagName and shadow
147 // - register the new tagName with this constructor
148 // - return the new Function (which is, not coincidentally, an
149 // InternalElementConstructorWithShadow)
150 } 117 }
151 118
152 class Module : AbstractModule { 119 class Module : AbstractModule {
153 constructor (Application application, Document document, String url); // O(1) 120 constructor (Application application, Document document, String url); // O(1)
154 readonly attribute Application application; // O(1) 121 readonly attribute Application application; // O(1)
155 } 122 }
156 123
157 class Application : AbstractModule { 124 class Application : AbstractModule {
158 constructor (Document document, GestureManager gestureManager, String url); // O(1) 125 constructor (Document document, GestureManager gestureManager, String url); // O(1)
159 attribute String title; // O(1) 126 attribute String title; // O(1)
(...skipping 23 matching lines...) Expand all
183 Where ``name_1`` through ``name_n`` are the names bound to the 150 Where ``name_1`` through ``name_n`` are the names bound to the
184 various named imports in the script element's document, 151 various named imports in the script element's document,
185 ``source_code`` is the text content of the script element, 152 ``source_code`` is the text content of the script element,
186 ``source_module`` is the ``Module`` object of the script element's 153 ``source_module`` is the ``Module`` object of the script element's
187 module, and ``value_1`` through ``value_n`` are the values 154 module, and ``value_1`` through ``value_n`` are the values
188 exported by the various named imports in the script element's 155 exported by the various named imports in the script element's
189 document. 156 document.
190 157
191 When an import fails to load, the ``as`` name for the import gets 158 When an import fails to load, the ``as`` name for the import gets
192 bound to ``undefined``. 159 bound to ``undefined``.
OLDNEW
« no previous file with comments | « sky/specs/dom.md ('k') | sky/specs/script.md » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698