diff --git a/lib/core_dom/view_factory.dart b/lib/core_dom/view_factory.dart index 3a21e5dec..97a525fa6 100644 --- a/lib/core_dom/view_factory.dart +++ b/lib/core_dom/view_factory.dart @@ -129,7 +129,7 @@ class ViewCache { ViewFactory fromHtml(String html, DirectiveMap directives) { ViewFactory viewFactory = _viewFactoryCache.get(html); if (viewFactory == null) { - var div = new dom.Element.tag('div'); + var div = new dom.DivElement(); div.setInnerHtml(html, treeSanitizer: treeSanitizer); viewFactory = compiler(div.nodes, directives); _viewFactoryCache.put(html, viewFactory); diff --git a/lib/directive/ng_base_css.dart b/lib/directive/ng_base_css.dart index 7415f789a..a79fc376b 100644 --- a/lib/directive/ng_base_css.dart +++ b/lib/directive/ng_base_css.dart @@ -1,9 +1,6 @@ part of angular.directive; -@Decorator( - selector: '[ng-base-css]', - visibility: Directive.CHILDREN_VISIBILITY -) +@Decorator(selector: '[ng-base-css]') class NgBaseCss { List _urls = const []; diff --git a/lib/directive/ng_form.dart b/lib/directive/ng_form.dart index 9e30a8528..f012f382f 100644 --- a/lib/directive/ng_form.dart +++ b/lib/directive/ng_form.dart @@ -7,24 +7,20 @@ part of angular.directive; */ @Decorator( selector: 'form', - module: NgForm.module, - visibility: Directive.CHILDREN_VISIBILITY) + module: NgForm.module) @Decorator( selector: 'fieldset', - module: NgForm.module, - visibility: Directive.CHILDREN_VISIBILITY) + module: NgForm.module) @Decorator( selector: '.ng-form', - module: NgForm.module, - visibility: Directive.CHILDREN_VISIBILITY) + module: NgForm.module) @Decorator( selector: '[ng-form]', module: NgForm.module, - map: const { 'ng-form': '@name' }, - visibility: Directive.CHILDREN_VISIBILITY) + map: const { 'ng-form': '@name' }) class NgForm extends NgControl { static final Module _module = new Module() - ..factory(NgControl, (i) => i.get(NgForm), visibility: Directive.CHILDREN_VISIBILITY); + ..factory(NgControl, (i) => i.get(NgForm)); static module() => _module; final Scope _scope; diff --git a/lib/directive/ng_model_select.dart b/lib/directive/ng_model_select.dart index db907d64e..1e8e6e047 100644 --- a/lib/directive/ng_model_select.dart +++ b/lib/directive/ng_model_select.dart @@ -18,8 +18,7 @@ part of angular.directive; * */ @Decorator( - selector: 'select[ng-model]', - visibility: Directive.CHILDREN_VISIBILITY) + selector: 'select[ng-model]') class InputSelect implements AttachAware { final expando = new Expando(); final dom.SelectElement _selectElement; diff --git a/lib/routing/ng_bind_route.dart b/lib/routing/ng_bind_route.dart index 4c8bc896c..98f936c1c 100644 --- a/lib/routing/ng_bind_route.dart +++ b/lib/routing/ng_bind_route.dart @@ -23,7 +23,6 @@ part of angular.routing; * however it does not effect view resolution by nested ng-view(s). */ @Decorator( - visibility: Directive.CHILDREN_VISIBILITY, selector: '[ng-bind-route]', module: NgBindRoute.module, map: const {'ng-bind-route': '@routeName'}) diff --git a/lib/routing/ng_view.dart b/lib/routing/ng_view.dart index d39b16af2..342bb07d9 100644 --- a/lib/routing/ng_view.dart +++ b/lib/routing/ng_view.dart @@ -58,49 +58,49 @@ part of angular.routing; @Decorator( selector: 'ng-view', module: NgView.module, - visibility: Directive.CHILDREN_VISIBILITY) + children: Directive.TRANSCLUDE_CHILDREN) class NgView implements DetachAware, RouteProvider { static final Module _module = new Module() - ..factory(RouteProvider, - (i) => i.get(NgView), - visibility: Directive.CHILDREN_VISIBILITY); + ..factory(RouteProvider, (i) => i.get(NgView)); + static module() => _module; - final NgRoutingHelper locationService; - final ViewCache viewCache; - final Injector injector; - final Element element; - final Scope scope; + final NgRoutingHelper _locationService; + final ViewCache _viewCache; + final Injector _injector; + final Scope _scope; RouteHandle _route; + final ViewPort _viewPort; + View _view; - Scope _scope; + Scope _childScope; Route _viewRoute; - NgView(this.element, this.viewCache, - Injector injector, Router router, - this.scope) - : injector = injector, - locationService = injector.get(NgRoutingHelper) + + NgView(this._viewCache, Injector injector, Router router, + this._scope, this._viewPort) + : _injector = injector, + _locationService = injector.get(NgRoutingHelper) { - RouteProvider routeProvider = injector.parent.get(NgView); + RouteProvider routeProvider = _injector.parent.get(NgView); _route = routeProvider != null ? routeProvider.route.newHandle() : router.root.newHandle(); - locationService._registerPortal(this); + _locationService._registerPortal(this); _maybeReloadViews(); } void _maybeReloadViews() { - if (_route.isActive) locationService._reloadViews(startingFrom: _route); + if (_route.isActive) _locationService._reloadViews(startingFrom: _route); } - detach() { + void detach() { _route.discard(); - locationService._unregisterPortal(this); + _locationService._unregisterPortal(this); } - _show(_View viewDef, Route route, List modules) { + void _show(_View viewDef, Route route, List modules) { assert(route.isActive); if (_viewRoute != null) return; @@ -114,44 +114,52 @@ class NgView implements DetachAware, RouteProvider { _cleanUp(); }); - var viewInjector = injector; - if (modules != null) { - viewInjector = forceNewDirectivesAndFilters(viewInjector, modules); - } + var viewInjector = modules == null ? + _injector : + forceNewDirectivesAndFilters(_injector, modules); var newDirectives = viewInjector.get(DirectiveMap); var viewFuture = viewDef.templateHtml != null ? - new Future.value(viewCache.fromHtml(viewDef.templateHtml, newDirectives)) : - viewCache.fromUrl(viewDef.template, newDirectives); + new Future.value(_viewCache.fromHtml(viewDef.templateHtml, newDirectives)) : + _viewCache.fromUrl(viewDef.template, newDirectives); + viewFuture.then((viewFactory) { _cleanUp(); - _scope = scope.createChild(new PrototypeMap(scope.context)); + _childScope = _scope.createChild(new PrototypeMap(_scope.context)); _view = viewFactory( - viewInjector.createChild( - [new Module()..value(Scope, _scope)])); + viewInjector.createChild([new Module()..value(Scope, _childScope)])); - _view.nodes.forEach((elm) => element.append(elm)); + var view = _view; + _scope.rootScope.domWrite(() { + _viewPort.insert(view); + }); }); } - _cleanUp() { + void _cleanUp() { if (_view == null) return; - _view.nodes.forEach((node) => node.remove()); - _scope.destroy(); + var view = _view; + var childScope = _childScope; + _scope.rootScope.domWrite(() { + _viewPort.remove(view); + childScope.destroy(); + }); _view = null; - _scope = null; + _childScope = null; } Route get route => _viewRoute; + String get routeName => _viewRoute.name; + Map get parameters { var res = {}; - var p = _viewRoute; - while (p != null) { - res.addAll(p.parameters); - p = p.parent; + var route = _viewRoute; + while (route != null) { + res.addAll(route.parameters); + route = route.parent; } return res; } diff --git a/lib/routing/routing.dart b/lib/routing/routing.dart index 13507e34e..c40aa0684 100644 --- a/lib/routing/routing.dart +++ b/lib/routing/routing.dart @@ -21,7 +21,7 @@ class RouteViewFactory { _configure(Route route, Map config) { config.forEach((name, cfg) { - var moduledCalled = false; + var modulesCalled = false; List newModules; route.addRoute( name: name, @@ -37,8 +37,8 @@ class RouteViewFactory { } }, preEnter: (RoutePreEnterEvent e) { - if (cfg.modules != null && !moduledCalled) { - moduledCalled = true; + if (cfg.modules != null && !modulesCalled) { + modulesCalled = true; var modules = cfg.modules(); if (modules is Future) { e.allowEnter(modules.then((List m) { @@ -92,10 +92,8 @@ class NgRouteCfg { * * The [init] method will be called by the framework once the router is * instantiated but before [NgBindRouteDirective] and [NgViewDirective]. - * - * Deprecated: use RouteInitializerFn instead. */ -@deprecated +@Deprecated("use RouteInitializerFn instead") abstract class RouteInitializer { void init(Router router, RouteViewFactory viewFactory); } @@ -146,7 +144,7 @@ class NgRoutingHelper { router.listen(appRoot: _ngApp.element); } - _reloadViews({Route startingFrom}) { + void _reloadViews({Route startingFrom}) { var alreadyActiveViews = []; var activePath = router.activePath; if (startingFrom != null) { @@ -169,16 +167,16 @@ class NgRoutingHelper { } } - _route(Route route, String template, {bool fromEvent, List modules, + void _route(Route route, String template, {bool fromEvent, List modules, String templateHtml}) { _templates[_routePath(route)] = new _View(template, templateHtml, modules); } - _registerPortal(NgView ngView) { + void _registerPortal(NgView ngView) { portals.add(ngView); } - _unregisterPortal(NgView ngView) { + void _unregisterPortal(NgView ngView) { portals.remove(ngView); } } diff --git a/test/directive/ng_if_spec.dart b/test/directive/ng_if_spec.dart index 5aefd1068..b5251b261 100644 --- a/test/directive/ng_if_spec.dart +++ b/test/directive/ng_if_spec.dart @@ -141,7 +141,7 @@ main() { compile(html); expect(element).toHaveText('content'); element.querySelector('span').classes.remove('my-class'); - expect(element.querySelector('span').classes.contains('my-class')).not.toBe(true); + expect(element.querySelector('span')).not.toHaveClass('my-class'); rootScope.apply(() { rootScope.context['isVisible'] = false; }); @@ -150,7 +150,7 @@ main() { rootScope.context['isVisible'] = true; }); // The newly inserted node should be a copy of the compiled state. - expect(element.querySelector('span').classes.contains('my-class')).toBe(true); + expect(element.querySelector('span')).toHaveClass('my-class'); } ); diff --git a/test/routing/ng_view_spec.dart b/test/routing/ng_view_spec.dart index ae9208769..c8f6968db 100644 --- a/test/routing/ng_view_spec.dart +++ b/test/routing/ng_view_spec.dart @@ -10,8 +10,8 @@ main() { TestBed _; Router router; - beforeEachModule((Module m) { - m + beforeEachModule((Module module) { + module ..install(new AngularMockModule()) ..type(RouteInitializerFn, implementedBy: FlatRouteInitializer); }); @@ -28,48 +28,53 @@ main() { it('should switch template', async(() { - Element root = _.compile(''); + Element root = _.compile('
'); expect(root.text).toEqual(''); router.route('/foo'); microLeap(); + _.rootScope.apply(); expect(root.text).toEqual('Foo'); router.route('/bar'); microLeap(); + _.rootScope.apply(); expect(root.text).toEqual('Bar'); router.route('/foo'); microLeap(); + _.rootScope.apply(); expect(root.text).toEqual('Foo'); })); it('should switch template when route is already active', async(() { // Force the routing system to initialize. - _.compile(''); + _.compile('
'); router.route('/foo'); microLeap(); - Element root = _.compile(''); + Element root = _.compile('
'); expect(root.text).toEqual(''); - _.rootScope.apply(); microLeap(); + _.rootScope.apply(); expect(root.text).toEqual('Foo'); })); it('should clear template when route is deactivated', async(() { - Element root = _.compile(''); + Element root = _.compile('
'); expect(root.text).toEqual(''); router.route('/foo'); microLeap(); + _.rootScope.apply(); expect(root.text).toEqual('Foo'); router.route('/baz'); // route without a template microLeap(); + _.rootScope.apply(); expect(root.text).toEqual(''); })); @@ -80,8 +85,8 @@ main() { TestBed _; Router router; - beforeEachModule((Module m) { - m + beforeEachModule((Module module) { + module ..install(new AngularMockModule()) ..type(RouteInitializerFn, implementedBy: NestedRouteInitializer); }); @@ -102,25 +107,29 @@ main() { }); it('should switch nested templates', async(() { - Element root = _.compile(''); + Element root = _.compile('
'); expect(root.text).toEqual(''); router.route('/library/all'); microLeap(); + _.rootScope.apply(); expect(root.text).toEqual('LibraryBooks'); router.route('/library/1234'); microLeap(); + _.rootScope.apply(); expect(root.text).toEqual('LibraryBook 1234'); // nothing should change here router.route('/library/1234/overview'); microLeap(); + _.rootScope.apply(); expect(root.text).toEqual('LibraryBook 1234'); // nothing should change here router.route('/library/1234/read'); microLeap(); + _.rootScope.apply(); expect(root.text).toEqual('LibraryRead Book 1234'); })); }); @@ -130,8 +139,8 @@ main() { TestBed _; Router router; - beforeEachModule((Module m) { - m + beforeEachModule((Module module) { + module ..install(new AngularMockModule()) ..value(RouteInitializerFn, (router, views) { views.configure({ @@ -148,11 +157,12 @@ main() { }); it('should switch inline templates', async(() { - Element root = _.compile(''); + Element root = _.compile('
'); expect(root.text).toEqual(''); router.route('/foo'); microLeap(); + _.rootScope.apply(); expect(root.text).toEqual('Hello'); })); }); diff --git a/test/routing/routing_spec.dart b/test/routing/routing_spec.dart index aad1e0ada..3d813d96f 100644 --- a/test/routing/routing_spec.dart +++ b/test/routing/routing_spec.dart @@ -158,12 +158,12 @@ main() { _.injector.get(TemplateCache) .put('foo.html', new HttpResponse(200, '

Foo

')); - Element root = _.compile(''); + Element root = _.compile('
'); expect(root.text).toEqual(''); router.route('/foo'); microLeap(); - + _.rootScope.apply(); expect(enterCount).toBe(1); expect(root.text).toEqual('Foo'); })); @@ -231,18 +231,18 @@ main() { _.injector.get(TemplateCache) .put('foo.html', new HttpResponse(200, '

Foo

')); - Element root = _.compile(''); + Element root = _.compile('
'); expect(root.text).toEqual(''); router.route('/foo'); microLeap(); - + _.rootScope.apply(); expect(root.text).toEqual('Foo'); expect(leaveCount).toBe(0); router.route('/bar'); microLeap(); - + _.rootScope.apply(); expect(root.text).toEqual(''); expect(leaveCount).toBe(1); })); @@ -263,12 +263,12 @@ main() { _.injector.get(TemplateCache) .put('foo.html', new HttpResponse(200, '
Old!
')); - Element root = _.compile(''); + Element root = _.compile('
'); expect(root.text).toEqual(''); router.route('/foo'); microLeap(); - + _.rootScope.apply(); expect(root.text).toEqual('New!'); })); @@ -288,12 +288,12 @@ main() { _.injector.get(TemplateCache) .put('foo.html', new HttpResponse(200, '
Old!
')); - Element root = _.compile(''); + Element root = _.compile('
'); expect(root.text).toEqual(''); router.route('/foo'); microLeap(); - + _.rootScope.apply(); expect(root.text).toEqual('New!'); })); @@ -313,13 +313,12 @@ main() { _.injector.get(TemplateCache) .put('foo.html', new HttpResponse(200, '
{{\'World\' | hello}}
')); - Element root = _.compile(''); + Element root = _.compile('
'); expect(root.text).toEqual(''); router.route('/foo'); microLeap(); _.rootScope.apply(); - expect(root.text).toEqual('Hello, World!'); })); @@ -339,13 +338,12 @@ main() { _.injector.get(TemplateCache) .put('foo.html', new HttpResponse(200, '
{{\'World\' | hello}}
')); - Element root = _.compile(''); + Element root = _.compile('
'); expect(root.text).toEqual(''); router.route('/foo'); microLeap(); _.rootScope.apply(); - expect(root.text).toEqual('Hello, World!'); })); @@ -369,7 +367,7 @@ class NewDirective { @Formatter(name:'hello') class HelloFilter { - call(String str) { + String call(String str) { return 'Hello, $str!'; } }