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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sky/specs/dom.md ('k') | sky/specs/script.md » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sky/specs/modules.md
diff --git a/sky/specs/modules.md b/sky/specs/modules.md
index 691c761fa38721ae6f059f4a4f5cac1559f9d4b3..f20e0c7d70ee323270cf1ef12d1a914b208dbec4 100644
--- a/sky/specs/modules.md
+++ b/sky/specs/modules.md
@@ -55,98 +55,65 @@ that were declared by that module except the aforementioned element
tree library.
At the end of the ``<script>`` block's source, if it parsed correctly
-and completely, the following code is appended:
+and completely, the conceptual equivalent of the following code is
+appended (but without affecting the library's list of declarations and
+without any possibility of it clashing with identifiers described in
+the library itself):
```dart
class _ { }
-module.registerElements(reflectClass(_).owner);
+void main() {
+ LibraryMirror library = reflectClass(_).owner as LibraryMirror;
+ if (library.declarations.containsKey(#init) && library.declarations[#init] is MethodMirror)
+ init();
+ module.init(library);
+}
```
+Then, that ``main()`` function is called.
+
TODO(ianh): decide what URL and name we should give the libraries, as
exposed in MirrorSystem.getName(libraryMirror.qualifiedName) etc
The ``Module`` class is defined in ``sky:core`` as follows:
+```dart
-TODO(ianh): dartification of the rest of this file
-
-### Exporting element definitions ###
-
-When importing a module into another, Sky runs the following steps:
- - let export be the imported module's ``exports`` value
- - try to import export
- - if that fails:
- - try to import each property of export
-
-"Try to import" a value means to run the following steps:
- - if the value is an element constructor (generated by
- ``registerElement()``), call this importer module's
- ``registerElement()`` with the value
-
-### IDL ###
-
-```javascript
-dictionary InternalElementOptions {
- String tagName;
- Boolean shadow = false;
- Object prototype = Element;
-}
-interface InternalElementConstructorWithoutShadow {
- constructor (Module hostModule);
- attribute String tagName;
-}
-interface InternalElementConstructorWithShadow {
- constructor (Module hostModule);
- attribute String tagName;
- attribute Boolean shadow;
-}
-typedef ElementRegistrationOptions (InternalElementOptions or
- InternalElementConstructorWithoutShadow or
- InternalElementConstructorWithShadow);
-
-abstract class AbstractModule : EventTarget {
- readonly attribute Document document; // O(1) // the Document of the module or application
- Promise<any> import(String url); // O(Yikes) // returns the module's exports
- private Array<Module> getImports(); O(N) // returns the Module objects of all the imported modules
-
- readonly attribute String url;
-
- ElementConstructor registerElement(Object options); // O(1)
- // if you call registerElement() with an object that was created by
- // registerElement(), it just returns the object after registering it,
- // rather than creating a new constructor
- // otherwise, it proceeds as follows:
- // - if options is a Function (i.e. it is either an
- // InternalElementConstructorWithoutShadow object or an
- // InternalElementConstructorWithShadow object), then let
- // constructor be that function, and let prototype be that
- // functions's prototype; otherwise, let constructor be a no-op
- // function and let prototype be the prototype property of the
- // object passed in (the InternalElementOptions; prototype
- // defaults to Element).
- // - let shadow be option's shadow property's value coerced to a
- // boolean, if the property is present, or else the value false.
- // - let tagName be option's tagName property's value.
- // - create a new Function that acts as if it had the signature of
- // the constructors in the ElementConstructor interface, and that
- // runs the follows steps when called:
- // - throw if not called as a constructor
- // - create an actual element object (the C++-backed object)
- // called tagName, along with the specified attributes
- // - initialise the shadow tree if shadow is true
- // - call constructor, if it's not null, with the module
- // within which the new element is being constructed as the
- // argument
- // - append all the specified children
- // - mark that new Function as created by registerElement() so that
- // it can be recognised if used as an argument to
- // registerElement()
- // - let that new Function's prototype be the aforementioned prototype
- // - let that new Function have tagName and shadow properties set to
- // the aforementioned tagName and shadow
- // - register the new tagName with this constructor
- // - return the new Function (which is, not coincidentally, an
- // InternalElementConstructorWithShadow)
+abstract class AbstractModule extends EventTarget {
+ AbstractModule({this.document, this.url});
+
+ final Document document; // O(1)
+ // the Document of the module or application
+
+ final String url;
+
+ @nonnull external Future<@nonnull Module> import(String url); // O(Yikes)
+ // load and return the URL at the given Module
+ // if it's already loaded, the future will resolve immediately
+ // if loading fails, the future will have an error
+
+ @nonnull List</*@nonnull*/ Module> getImports(); // O(N)
+ // returns the Module objects of all the imported modules
+
+ external registerElement(@nonnull String tagname, @nonnull Type elementClass); // O(1)
+ // registers a tag name with the parser
+ // only useful during parse time
+ // verify that tagname isn't null or empty
+ // verify that elementClass is the Type of a class that extends Element (directly or indirectly, but not via "implements" or "with")
+ // (see the @tagname code for an example of how to verify that from dart)
+ // verify that there's not already a class registered for this tag name
+ // if there is, then mark this tagname is broken, so that it acts as if it's not registered in the parser,
+ // and, if this is the first time it was marked broken, log a console message regarding the issue
+ // (mention the tag name but not the classes, so that it's not observable that this currently happens out of order)
+
+ void init(LibraryMirror library) {
+ library.declarations.forEach((Symbol s, DeclarationMirror d) {
+ d.metadata.forEach((InstanceMirror i) {
+ if (i.reflectee is AutomaticMetadata)
+ i.reflectee.init(d, this);
+ });
+ });
+ }
}
class Module : AbstractModule {
« 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