diff --git a/src/components/nav-view/nav-view.js b/src/components/nav-view/nav-view.js index 5c8537ae7e..8affa8d28a 100644 --- a/src/components/nav-view/nav-view.js +++ b/src/components/nav-view/nav-view.js @@ -1,10 +1,18 @@ -import {Component, Template, Inject, Parent, NgElement} from 'angular2/angular2' +import {Component, Template, NgElement} from 'angular2/angular2' import {ComponentConfig} from 'ionic2/config/component-config' import {Log} from 'ionic2/util' +import {Compiler} from 'angular2/src/core/compiler/compiler' +import {EventManager} from 'angular2/src/core/events/event_manager' +import {PrivateComponentLocation} from 'angular2/src/core/compiler/private_component_location' +import {PrivateComponentLoader} from 'angular2/src/core/compiler/private_component_loader' +import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader' +import {ShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy' + @Component({ selector: 'ion-nav', bind: { + initial: 'initial' }, services: [] }) @@ -12,10 +20,34 @@ import {Log} from 'ionic2/util' inline: `` }) export class NavView { - constructor(@NgElement() element: NgElement) { - console.log('Nav View constructed') + constructor( + @NgElement() element: NgElement, + eventManager: EventManager, + compiler: Compiler, + location: PrivateComponentLocation, + loader: PrivateComponentLoader, + directiveMetadataReader: DirectiveMetadataReader, + shadowDomStrategy: ShadowDomStrategy + ) { + this.attacher = new Attacher({ + compiler, + element, + location, + loader, + directiveMetadataReader, + eventManager, + shadowDomStrategy + }) - this._views = [] + this._children = [] + console.log('Nav View constructed') + } + + set initial(Type) { + if (!this.initialized) { + this.initialized = true + this.push(Type) + } } /** @@ -24,14 +56,16 @@ export class NavView { * @param view the new view * @param shouldAnimate whether to animate */ - push(view, shouldAnimate) { - this._views.push(view) + push(Type, shouldAnimate) { + //TODO animation - if(shouldAnimate) { - this._animateIn(view) - } + let current = this._children[this._children.length - 1] + current && current.hide() - Log.log('NAV: PUSH', view, 'Animate?', shouldAnimate) + this.attacher.attachComponent(Type).then(child => { + this._children.push(child) + }) + Log.log('NAV: PUSH', Type.name, 'Animate?', shouldAnimate) } /** @@ -40,12 +74,15 @@ export class NavView { * @param shouldAnimate whether to animate */ pop(shouldAnimate) { - last = this._views.pop() - - if(shouldAnimate) { - this._animateOut(last) + // TODO animation + let current = this._children.pop() + if (current) { + current.remove() + } + let last = this._children[this._children.length - 1] + if (last) { + last.show() } - return last } @@ -69,3 +106,66 @@ export class NavView { } } + +class Attacher { + constructor({ + location, + element, + directiveMetadataReader, + compiler, + shadowDomStrategy, + eventManager + }) { + this.location = location + this.element = element + this.directiveMetadataReader = directiveMetadataReader + this.compiler = compiler + this.shadowDomStrategy = shadowDomStrategy + this.eventManager = eventManager + } + + attachComponent(Type) { + let parentInjector = this.location._elementInjector + let childInjector = parentInjector._proto.instantiate( + /* parent */ parentInjector, + /* host */ null + ) + + let childContainer = document.createElement('div') + childContainer.classList.add('test-child-container') + this.element.domElement.appendChild(childContainer) + + let childNgElement = new NgElement(childContainer) + childInjector._preBuiltObjects = parentInjector._preBuiltObjects + childInjector._preBuiltObjects.element = childNgElement + + let annotation = this.directiveMetadataReader.read(Type).annotation + return this.compiler.compile(Type).then((protoView) => { + let context = childInjector.createPrivateComponent(Type, annotation); + let view = protoView.instantiate(childInjector, this.eventManager) + + view.hydrate(parentInjector.getShadowDomAppInjector(), childInjector, null, context, null) + this.shadowDomStrategy.attachTemplate(childNgElement.domElement, view) + + this.location._view.componentChildViews.push(view) + this.location._view.changeDetector.addChild(view.changeDetector) + + return { + remove() { + // TODO actually remove it from the angular tree + // setTimeout(() => { view.dehydrate() }) + childContainer.parentNode.removeChild(childContainer) + }, + hide() { + // view.dehydrate() + childContainer.style.display = 'none' + }, + show() { + childContainer.style.display = '' + // view.hydrate() + }, + } + }) + } + +} diff --git a/src/components/nav-view/test/basic/main.html b/src/components/nav-view/test/basic/main.html index 0657cd457b..a942ebb790 100644 --- a/src/components/nav-view/test/basic/main.html +++ b/src/components/nav-view/test/basic/main.html @@ -1,4 +1,2 @@ - - - + diff --git a/src/components/nav-view/test/basic/main.js b/src/components/nav-view/test/basic/main.js index 41510076b0..6e51e918de 100644 --- a/src/components/nav-view/test/basic/main.js +++ b/src/components/nav-view/test/basic/main.js @@ -1,112 +1,17 @@ import {bootstrap} from 'angular2/core' -import {Component, Template, NgElement, Parent} from 'angular2/angular2' -import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver' -import {Compiler} from 'angular2/src/core/compiler/compiler' -import {EventManager} from 'angular2/src/core/events/event_manager' +import {Component, Template} from 'angular2/angular2' import {NavView} from 'ionic2/components/nav-view/nav-view' -import {View} from 'ionic2/components/view/view' import {Log} from 'ionic2/util' -import {PrivateComponentLocation} from 'angular2/src/core/compiler/private_component_location' -import {PrivateComponentLoader} from 'angular2/src/core/compiler/private_component_loader' -import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader' -import {ShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy' - -@Component({ - selector: 'my-page' -}) -@Template({ - inline: '
Hello, inside page {{num}}
' -}) -export class InsidePage { - constructor( - ele: NgElement, - @Parent() myPage: MyPage - ) { - console.log(myPage) - this.num = Math.random() - ele.domElement.style.backgroundColor = `rgba(255,0,0,${this.num})` - } -} - -@Component({ - selector: 'my-page', - services: [Compiler, PrivateComponentLocation] -}) -@Template({ - inline: `

I'm a page!

- - -
` -}) -export class MyPage { - constructor( - @NgElement() ele:NgElement, - eventManager: EventManager, - compiler: Compiler, - location: PrivateComponentLocation, - loader: PrivateComponentLoader, - reader: DirectiveMetadataReader, - shadowDomStrategy: ShadowDomStrategy - ) { - this.ele = ele - this.location = location - this.loader = loader - this.reader = reader - this.compiler = compiler - this.eventManager = eventManager - this.shadowDomStrategy = shadowDomStrategy - - this._children = [] - } - push() { - let childInjector = this.location._elementInjector._proto.instantiate( - /* parent */ this.location._elementInjector, - /* host */ null - ) - - let childContainer = document.createElement('div') - childContainer.classList.add('test-child-container') - this.ele.domElement.appendChild(childContainer) - - let childNgElement = new NgElement(childContainer) - childInjector._preBuiltObjects = this.location._elementInjector._preBuiltObjects - childInjector._preBuiltObjects.element = childNgElement - - let annotation = this.reader.read(InsidePage).annotation - this.compiler.compile(InsidePage).then((protoView) => { - let context = childInjector.createPrivateComponent(InsidePage, annotation); - let view = protoView.instantiate(childInjector, this.eventManager) - - view.hydrate(childInjector.getShadowDomAppInjector(), childInjector, null, context, null) - this.shadowDomStrategy.attachTemplate(childNgElement.domElement, view) - - this.location._view.componentChildViews.push(view) - this.location._view.changeDetector.addChild(view.changeDetector) - - this._children.push({ - remove() { - view.dehydrate() - childContainer.parentNode.removeChild(childContainer) - } - }) - }) - } - pop() { - var last = this._children.pop() - if (!last) return; - - last.remove() - } - -} +import {FirstPage} from 'app/pages/first-page' @Component({ selector: '[ion-app]' }) @Template({ - directives: [NavView, View, MyPage], + directives: [NavView], url: 'main.html' }) class IonicApp { constructor() { + this.initial = FirstPage console.log('IonicApp Start') } } diff --git a/src/components/nav-view/test/basic/pages/first-page.html b/src/components/nav-view/test/basic/pages/first-page.html new file mode 100644 index 0000000000..aa4f4da00a --- /dev/null +++ b/src/components/nav-view/test/basic/pages/first-page.html @@ -0,0 +1,3 @@ + + + diff --git a/src/components/nav-view/test/basic/pages/first-page.js b/src/components/nav-view/test/basic/pages/first-page.js new file mode 100644 index 0000000000..7e26fc8e30 --- /dev/null +++ b/src/components/nav-view/test/basic/pages/first-page.js @@ -0,0 +1,23 @@ +import {Component, Template, Parent} from 'angular2/angular2' +import {NavView} from 'ionic2/components/nav-view/nav-view' +import {View} from 'ionic2/components/view/view' +import {SecondPage} from 'app/pages/second-page' + +@Component({ + selector: 'first-page' +}) +@Template({ + url: 'pages/first-page.html', + directives: [View] +}) +export class FirstPage { + constructor( + @Parent() navView: NavView + ) { + this.navView = navView + } + + nextPage() { + this.navView.push(SecondPage) + } +} diff --git a/src/components/nav-view/test/basic/pages/second-page.html b/src/components/nav-view/test/basic/pages/second-page.html new file mode 100644 index 0000000000..56881d34d2 --- /dev/null +++ b/src/components/nav-view/test/basic/pages/second-page.html @@ -0,0 +1,3 @@ + + + diff --git a/src/components/nav-view/test/basic/pages/second-page.js b/src/components/nav-view/test/basic/pages/second-page.js new file mode 100644 index 0000000000..e223650e48 --- /dev/null +++ b/src/components/nav-view/test/basic/pages/second-page.js @@ -0,0 +1,21 @@ +import {Component, Template, Parent} from 'angular2/angular2' +import {NavView} from 'ionic2/components/nav-view/nav-view' +import {View} from 'ionic2/components/view/view' + +@Component({ + selector: 'second-page' +}) +@Template({ + url: 'pages/second-page.html', + directives: [View] +}) +export class SecondPage { + constructor( + @Parent() navView: NavView + ) { + this.navView = navView + } + prevPage() { + this.navView.pop() + } +} diff --git a/src/components/toolbar/back-button.js b/src/components/toolbar/back-button.js index 24ee9817c5..cf1016d210 100644 --- a/src/components/toolbar/back-button.js +++ b/src/components/toolbar/back-button.js @@ -3,13 +3,21 @@ import {ComponentConfig} from 'ionic2/config/component-config' export let BackButtonConfig = new ComponentConfig('back-button') +BackButtonConfig + .platform('ios', instance => { + instance.domElement.querySelector('.back-button-icon').classList.add('ion-ios-arrow-back') + }) + .platform('android', instance => { + instance.domElement.querySelector('.back-button-icon').classList.add('ion-android-arrow-back') + }) + @Component({ selector: '.back-button', services: [BackButtonConfig] }) @Template({ inline: ` - +
Back
diff --git a/src/config/component-config.js b/src/config/component-config.js index f705bca638..eeb27648d9 100644 --- a/src/config/component-config.js +++ b/src/config/component-config.js @@ -17,6 +17,7 @@ export function ComponentConfig(componentCssName) { static classes() { Config.classProperties || (Config.classProperties = []) Config.classProperties.push.apply(Config.classProperties, arguments) + return Config } static delegate(delegateName) { let self = { @@ -27,6 +28,13 @@ export function ComponentConfig(componentCssName) { } return self } + static platform(name, Class) { + Config.platformFns = Config.platformFns || [] + if (name === platformName) { + Config.platformFns.unshift(Class) + } + return Config + } static addCase(delegateName, condition, DelegateConstructor) { Config.registry || (Config.registry = {}) var array = (Config.registry[delegateName] || (Config.registry[delegateName] = [])) @@ -53,6 +61,9 @@ export function ComponentConfig(componentCssName) { let propertyValue = instance[Config.classProperties[i]] instance.domElement.classList.add(`${componentCssName}-${propertyValue}`) } + for (let i = 0; i < (Config.platformFns || []).length; i++) { + new Config.platformFns[i](instance) + } return { getDelegate(delegateName) { let registry = Config.registry && Config.registry[delegateName] || []