From f89aff8b66cda77c703d6faad62a1ff7e0eaa840 Mon Sep 17 00:00:00 2001 From: James deBoer Date: Thu, 24 Jul 2014 17:06:55 -0700 Subject: [PATCH 1/2] chore(examples): Add a PolymerJS paper component using attribute mappings --- example/bower.json | 24 ++++++++++++++++++++++++ example/web/bower_components | 1 + example/web/index.html | 1 + example/web/paper_progress.dart | 13 +++++++++++++ example/web/paper_progress.html | 31 +++++++++++++++++++++++++++++++ 5 files changed, 70 insertions(+) create mode 100644 example/bower.json create mode 120000 example/web/bower_components create mode 100644 example/web/paper_progress.dart create mode 100644 example/web/paper_progress.html diff --git a/example/bower.json b/example/bower.json new file mode 100644 index 000000000..df727d27d --- /dev/null +++ b/example/bower.json @@ -0,0 +1,24 @@ +{ + "name": "paper-example", + "version": "0.0.1", + "homepage": "https://github.com/angular/angular.dart", + "authors": [ + "James deBoer " + ], + "description": "Paper with AngularDart", + "main": "web/index.html", + "license": "MIT", + "private": true, + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ], + "dependencies": { + "polymer": "Polymer/polymer#~0.3.4", + "paper-elements": "Polymer/paper-elements#~0.3.4", + "core-elements": "Polymer/core-elements#~0.3.4" + } +} diff --git a/example/web/bower_components b/example/web/bower_components new file mode 120000 index 000000000..84cb58a3f --- /dev/null +++ b/example/web/bower_components @@ -0,0 +1 @@ +../bower_components/ \ No newline at end of file diff --git a/example/web/index.html b/example/web/index.html index c7a6b6860..fa87b6f9b 100644 --- a/example/web/index.html +++ b/example/web/index.html @@ -6,6 +6,7 @@
  • hello_world.html
  • todo.html
  • shadow_dom_components.html
  • +
  • paper_progress.html
  • diff --git a/example/web/paper_progress.dart b/example/web/paper_progress.dart new file mode 100644 index 000000000..039629dad --- /dev/null +++ b/example/web/paper_progress.dart @@ -0,0 +1,13 @@ +import 'package:angular/angular.dart'; +import 'package:angular/application_factory.dart'; + + +main() { + var injector = applicationFactory() + .run(); + var scope = injector.get(Scope); + scope.context['text'] = "Hello future"; + scope.context['max'] = 20; + scope.context['curValue'] = 12; + scope.apply(); +} diff --git a/example/web/paper_progress.html b/example/web/paper_progress.html new file mode 100644 index 000000000..815537f56 --- /dev/null +++ b/example/web/paper_progress.html @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + +

    A quick demo of the Polymer paper-progress widget in an AngularDart app.

    +

    The max ({{max}}) and value ({{curValue}}) properties are bound through attribute intropolation

    + +

    Text from Angular: {{text}}

    + +
    + +
    + +

    + Change the value through an ng-model bound input box: + +

    + + From ca68918fd22b370fb0459b0d614025e8e5803332 Mon Sep 17 00:00:00 2001 From: James deBoer Date: Fri, 25 Jul 2014 06:27:37 -0700 Subject: [PATCH 2/2] feat(element binder): Bind to Web Component properties Closes #1277 --- example/web/paper_progress.html | 7 ++- lib/core_dom/element_binder.dart | 10 ++++- test/core_dom/web_components_spec.dart | 62 ++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 test/core_dom/web_components_spec.dart diff --git a/example/web/paper_progress.html b/example/web/paper_progress.html index 815537f56..2c8151c66 100644 --- a/example/web/paper_progress.html +++ b/example/web/paper_progress.html @@ -12,15 +12,18 @@ href="bower_components/paper-progress/paper-progress.html"> +

    A quick demo of the Polymer paper-progress widget in an AngularDart app.

    -

    The max ({{max}}) and value ({{curValue}}) properties are bound through attribute intropolation

    +

    The max ({{max}}) and value ({{curValue}}) properties are bound through bind-* semantics

    Text from Angular: {{text}}

    - +

    diff --git a/lib/core_dom/element_binder.dart b/lib/core_dom/element_binder.dart index 79f4e919d..0a8fac939 100644 --- a/lib/core_dom/element_binder.dart +++ b/lib/core_dom/element_binder.dart @@ -62,7 +62,7 @@ class ElementBinder { } bool get hasDirectivesOrEvents => - _usableDirectiveRefs.isNotEmpty || onEvents.isNotEmpty; + _usableDirectiveRefs.isNotEmpty || onEvents.isNotEmpty || bindAttrs.isNotEmpty; void _bindTwoWay(tasks, AST ast, scope, directiveScope, controller, AST dstAST) { @@ -283,6 +283,14 @@ class ElementBinder { _link(nodeInjector, scope, nodeAttrs); + var jsNode; + bindAttrs.forEach((String prop, ast) { + if (jsNode == null) jsNode = new js.JsObject.fromBrowserObject(node); + scope.watchAST(ast, (v, _) { + jsNode[prop] = v; + }); + }); + if (onEvents.isNotEmpty) { onEvents.forEach((event, value) { view.registerEvent(EventHandler.attrNameToEventName(event)); diff --git a/test/core_dom/web_components_spec.dart b/test/core_dom/web_components_spec.dart new file mode 100644 index 000000000..e20fbaa46 --- /dev/null +++ b/test/core_dom/web_components_spec.dart @@ -0,0 +1,62 @@ +library angular.dom.web_components_spec; + +import '../_specs.dart'; +import 'dart:js' as js; + +registerElement(String name, prototype) { + return (new js.JsObject.fromBrowserObject(document)).callMethod('registerElement', + [name, new js.JsObject.jsify({"prototype": prototype })]); +} + + + +main() { + describe('WebComponent support', () { + TestBed _; + + customProp(String prop, [elt]) { + if (elt == null) elt = _.rootElement; + return (new js.JsObject.fromBrowserObject(elt))[prop]; + } + + beforeEach((TestBed tb) { + _ = tb; + }); + + it('should create custom elements', () { + registerElement('tests-basic', {'prop-x': 6}); + + // Create a web component + _.compile(''); + expect(customProp('prop-x')).toEqual(6); + }); + + + it('should bind to Custom Element properties', () { + registerElement('tests-bound', {'prop-y': 10}); + _.compile(''); + + // Scope has not been digested yet + expect(customProp('prop-y')).toEqual(10); + + _.rootScope.apply(); + expect(customProp('prop-y')).toEqual(27); + }); + + + it('should bind to a non-existent property', () { + registerElement('tests-empty', {}); + _.compile(''); + _.rootScope.apply(); + expect(customProp('new-prop')).toEqual(27); + }); + + it('should bind to both directives and properties', () { + registerElement('tests-double', {}); + _.compile(''); + _.rootScope.apply(); + expect(customProp('ng-bind')).toEqual("hello"); + expect(_.rootElement).toHaveText('hello'); + }); + }); +}