diff --git a/lib/html.dart b/lib/html.dart new file mode 100644 index 0000000..5ed4ed0 --- /dev/null +++ b/lib/html.dart @@ -0,0 +1,4 @@ +export 'src/custom_element.dart'; +export 'src/div_element.dart'; +export 'src/element.dart'; +export 'src/html_element.dart'; diff --git a/lib/interop.js b/lib/interop.js new file mode 100644 index 0000000..66caf63 --- /dev/null +++ b/lib/interop.js @@ -0,0 +1,30 @@ +class CustomElement extends HTMLElement { + constructor() { + super(); + this.dartObject = null; + } + + connectedCallback() { + this.dartObject.connected(); + } + + disconnectedCallback() { + this.dartObject.disconnected(); + } + + attributeChangedCallback(attr, oldVal, newVal) { + this.dartObject.attributeChanged(attr, oldVal, newVal); + } +} +window.CustomElement = CustomElement; + +function defineElement(name, construct, observed) { + customElements.define(name, class extends CustomElement { + constructor() { + super(); + construct(this); + } + + static get observedAttributes() { return observed; } + }); +}; diff --git a/lib/src/custom_element.dart b/lib/src/custom_element.dart new file mode 100644 index 0000000..cb4b06c --- /dev/null +++ b/lib/src/custom_element.dart @@ -0,0 +1,22 @@ +import 'html_element.dart'; +import 'js.dart' as js; + +typedef CustomElementConstructor = CustomElement Function( + js.CustomElement element); + +class CustomElement extends HtmlElement { + CustomElement(js.HtmlElement element) : super(element); + + void connected() {} + void disconnected() {} + void attributeChanged(String attribute, String oldValue, String newValue) {} + + // Register + static void register( + String tag, + CustomElementConstructor constructor, [ + List observed = const [], + ]) { + js.defineElement(tag, constructor, observed); + } +} diff --git a/lib/src/div_element.dart b/lib/src/div_element.dart new file mode 100644 index 0000000..710f09d --- /dev/null +++ b/lib/src/div_element.dart @@ -0,0 +1,7 @@ +import 'js.dart' as js; + +import 'html_element.dart'; + +class DivElement extends HtmlElement { + DivElement(js.HtmlElement element) : super(element); +} diff --git a/lib/src/element.dart b/lib/src/element.dart new file mode 100644 index 0000000..12564b8 --- /dev/null +++ b/lib/src/element.dart @@ -0,0 +1,27 @@ +import 'package:meta/meta.dart'; + +import 'div_element.dart'; +import 'js.dart' as js; + +abstract class Element { + /// + @protected + Element(this.jsObject) { + jsObject.dartObject = this; + } + + @protected + final T jsObject; +} + +DivElement div() => tagName('div') as DivElement; + +Element tagName(String tag) { + final jsElement = js.document.createElement(tag); + + if (tag == 'div') { + return DivElement(jsElement); + } + + return null; +} diff --git a/lib/src/html_element.dart b/lib/src/html_element.dart new file mode 100644 index 0000000..0e620ca --- /dev/null +++ b/lib/src/html_element.dart @@ -0,0 +1,26 @@ +import 'element.dart'; +import 'js.dart' as js; + +abstract class HtmlElement extends Element { + HtmlElement(T jsObject) : super(jsObject); + + void click() { + print('Im clicking'); + jsObject.click(); + } + + void focus() { + print('Im focusing'); + jsObject.focus(); + } + + void blur() { + print('Im bluring'); + jsObject.blur(); + } + + String get text => jsObject.innerText; + set text(String value) { + jsObject.innerText = value; + } +} diff --git a/lib/src/js.dart b/lib/src/js.dart new file mode 100644 index 0000000..81f2d61 --- /dev/null +++ b/lib/src/js.dart @@ -0,0 +1,5 @@ +export 'js/custom_element.dart'; +export 'js/dart_wrapper.dart'; +export 'js/document.dart'; +export 'js/element.dart'; +export 'js/html_element.dart'; diff --git a/lib/src/js/custom_element.dart b/lib/src/js/custom_element.dart new file mode 100644 index 0000000..9f5882b --- /dev/null +++ b/lib/src/js/custom_element.dart @@ -0,0 +1,13 @@ +@JS() +library html_proto.src.js.custom_element; + +import 'package:js/js.dart'; + +import 'html_element.dart'; + +@JS('CustomElement') +abstract class CustomElement implements HtmlElement {} + +@JS('defineElement') +external void defineElement( + String name, Function constructor, List observed); diff --git a/lib/src/js/dart_wrapper.dart b/lib/src/js/dart_wrapper.dart new file mode 100644 index 0000000..b6295d6 --- /dev/null +++ b/lib/src/js/dart_wrapper.dart @@ -0,0 +1,5 @@ +/// A JSObject that contains a Dart object. +abstract class DartWrapper { + /// The object from Dart. + dynamic dartObject; +} diff --git a/lib/src/js/document.dart b/lib/src/js/document.dart new file mode 100644 index 0000000..03a05c0 --- /dev/null +++ b/lib/src/js/document.dart @@ -0,0 +1,14 @@ +@JS() +library html_proto.src.js.document; + +import 'package:js/js.dart'; + +import 'html_element.dart'; + +@JS('Document') +abstract class Document { + HtmlElement createElement(String tag); +} + +@JS('document') +external Document get document; diff --git a/lib/src/js/element.dart b/lib/src/js/element.dart new file mode 100644 index 0000000..93892a9 --- /dev/null +++ b/lib/src/js/element.dart @@ -0,0 +1,9 @@ +@JS() +library html_proto.src.js.element; + +import 'package:js/js.dart'; + +import 'dart_wrapper.dart'; + +@JS('Element') +abstract class Element implements DartWrapper {} diff --git a/lib/src/js/html_element.dart b/lib/src/js/html_element.dart new file mode 100644 index 0000000..5af0309 --- /dev/null +++ b/lib/src/js/html_element.dart @@ -0,0 +1,16 @@ +@JS() +library html_proto.src.js.html_element; + +import 'package:js/js.dart'; + +import 'element.dart'; + +@JS('HTMLElement') +abstract class HtmlElement implements Element { + void click(); + void focus(); + void blur(); + + String get innerText; + set innerText(String value); +} diff --git a/pubspec.yaml b/pubspec.yaml index 33a2fe8..89ac77f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ -name: customElementDemo -description: An absolute bare-bones web app. +name: html_proto +description: Alternate dart:html prototype. # version: 1.0.0 #homepage: https://www.example.com #author: Jenny Messerly @@ -9,6 +9,7 @@ environment: dependencies: js: ^0.6.0 + meta: ^1.1.6 dev_dependencies: build_runner: ^0.10.0 diff --git a/web/index.html b/web/index.html index 4a97767..f59899d 100644 --- a/web/index.html +++ b/web/index.html @@ -5,12 +5,13 @@ - customElementDemo + HTML Prototype Demo - + + diff --git a/web/interop.js b/web/interop.js deleted file mode 100644 index bca79a8..0000000 --- a/web/interop.js +++ /dev/null @@ -1,24 +0,0 @@ -class CustomElement extends HTMLElement { - constructor() { - super(); - this.asDart = null; - } - - connectedCallback() { - this.asDart.connected(); - } - - disconnectedCallback() { - this.asDart.disconnected(); - } -} -window.CustomElement = CustomElement; - -function defineElement(name, construct) { - customElements.define(name, class extends CustomElement { - constructor() { - super(); - construct(this); - } - }); -}; diff --git a/web/main.dart b/web/main.dart index ba9f1d4..7b3f028 100644 --- a/web/main.dart +++ b/web/main.dart @@ -1,55 +1,27 @@ -@JS() -library main; +import 'package:html_proto/html.dart'; +import 'package:html_proto/src/js.dart' as js; -import 'dart:html'; -import 'package:js/js.dart'; +class GreetingElement extends CustomElement { + GreetingElement(js.CustomElement element) : super(element); -@JS('CustomElement') -abstract class JSCustomElement implements HtmlElement { - T asDart; -} - -typedef CustomElementConstructor = CustomElement Function(JSCustomElement e); - -@JS('defineElement') -external void defineElement(String name, CustomElementConstructor constructor); - -class CustomElement { - final JSCustomElement element; - - CustomElement(this.element) { - element.asDart = this; + void connected() { + print('Hello I\'m connected now'); + text = 'Hello from Dart'; } - void connected() {} - void disconnected() {} -} - -class HelloElement extends CustomElement{ - HelloElement(JSCustomElement element) : super(element); - - void sayHello() { - element.text = 'Hello from Dart!'; - element.style.color = '#0175C2'; + void disconnected() { + print('Goodbye I\'m being disconnected now'); } -} -class GoodbyeElement extends CustomElement { - GoodbyeElement(JSCustomElement element) : super(element); + void attributeChanged(String attribute, String oldValue, String newValue) { + text = 'Hello from Dart ${newValue}'; - void sayGoodybe() { - element.text = 'Goodbye from Dart!'; - element.style.color = '#0175C2'; + print('Attribute: $attribute'); + print('Old value: $oldValue'); + print('New value: $newValue'); } } void main() { - defineElement('dart-goodbye', allowInterop((e) => GoodbyeElement(e))); - defineElement('dart-hello', allowInterop((e) => HelloElement(e))); - - var hello = document.body.append(Element.tag('dart-hello')) as JSCustomElement; - hello.asDart.sayHello(); - - var goodbye = document.body.append(Element.tag('dart-goodbye')) as JSCustomElement; - goodbye.asDart.sayGoodybe(); + CustomElement.register('greeting-element', (e) => GreetingElement(e), ['name']); }