diff --git a/package.json b/package.json
index 414ee2f3a2..92b7454802 100644
--- a/package.json
+++ b/package.json
@@ -35,5 +35,11 @@
"rx": "^2.4.6",
"traceur": "0.0.87",
"zone.js": "0.4.1"
+ },
+ "registry": "jspm",
+ "directories": {
+ "baseURL": "n",
+ "lib": "n",
+ "packages": "n/jspm_packages"
}
}
diff --git a/src/components.js b/src/components.js
index 756b9ffbd2..77e25eefd5 100644
--- a/src/components.js
+++ b/src/components.js
@@ -5,6 +5,7 @@ export * from 'ionic2/components/icon/icon'
export * from 'ionic2/components/item/item'
export * from 'ionic2/components/list/list'
export * from 'ionic2/components/nav-view/nav-view'
+export * from 'ionic2/components/nav-viewport/nav-viewport'
export * from 'ionic2/components/tabs/tabs'
export * from 'ionic2/components/toolbar/toolbar'
export * from 'ionic2/components/view/view'
diff --git a/src/components/app/ionic.scss b/src/components/app/ionic.scss
index 50878bc7eb..a9d2fededb 100644
--- a/src/components/app/ionic.scss
+++ b/src/components/app/ionic.scss
@@ -32,6 +32,7 @@
"../item/item",
"../list/list",
"../modal/modal",
+ "../nav-view/nav-view",
"../radio/radio",
"../search-bar/search-bar",
"../switch/switch",
diff --git a/src/components/item/item-swipe-buttons.js b/src/components/item/item-swipe-buttons.js
index 605bd1f112..f37087c493 100644
--- a/src/components/item/item-swipe-buttons.js
+++ b/src/components/item/item-swipe-buttons.js
@@ -10,14 +10,11 @@ export class ItemPrimarySwipeButtons {
@NgElement() element: NgElement,
@Parent() item: Item
) {
+ item.primarySwipeButtons = this
this.domElement = element.domElement
this.parentItem = item
this.gesture = new ItemSlideGesture(this)
this.gesture.listen()
-
- this.domElement.addEventListener('transitionend', () => {
- this.domElement.classList.remove('changing')
- })
}
setOpen(isOpen) {
diff --git a/src/components/item/item.js b/src/components/item/item.js
index f2e40cbec9..16d7664086 100644
--- a/src/components/item/item.js
+++ b/src/components/item/item.js
@@ -27,20 +27,82 @@ import {
`,
- direcetives: [
+ directives: [
ItemPrimarySwipeButtons,
- ItemSecondarySwipeButtons,
- ItemPrimaryOptions,
- ItemSecondaryOptions
+ // ItemSecondarySwipeButtons,
+ // ItemPrimaryOptions,
+ // ItemSecondaryOptions
]
})
export class Item {
constructor(
@NgElement() ele:NgElement
) {
+ this._isOpen = false
+ this._isSlideActive = false
+ this._isTransitioning = false
+ this._transform = ''
+
this.domElement = ele.domElement
+ this.swipeButtons = {}
+ this.optionButtons = {}
Item.config.invoke(this)
}
}
new IonicComponent(Item, {})
+
+
+function clsSetter(el, name) {
+ return (isSet) => el.classList[isSet?'add':'remove'](name)
+}
+
+import {dom} from 'ionic2/util'
+
+class Slideable {
+ constructor(slideElement: Element) {
+ }
+
+ // override
+ onTransform(str: String) {}
+ // override
+ onTransitionActive(active: Boolean) {}
+ //override
+ onSlideActive(active: boolean) {}
+
+ transform(str: String) {
+ if (arguments.length && str !== this._transform) {
+ this.onTransform()
+ }
+ }
+
+ isTransitionActive(active: Boolean) {
+ if (arguments.length && active !== this._isTransitionActive) {
+ this._isTransitionActive = active
+ this.onSetTransitionActive(active)
+ }
+ return this._isTransitioning
+ }
+
+ isSlideActive(active: Boolean) {
+ if (arguments.length && active !== this._isSlideActive) {
+ this._isSlideActive = active
+ this.onSetDragActive(active)
+ }
+ return this._isSlideActive
+ }
+
+ isOpen(open: Boolean) {
+ if (arguments.length && open !== this._isOpen) {
+ this.isTransitionActive(true)
+ dom.rafPromise().then(() => {
+ this.isOpen = isOpen
+ this.onSetIsOpen(open)
+ })
+ }
+ }
+
+}
+
+class ItemSlideGesture {
+}
diff --git a/src/components/nav-view/nav-view.js b/src/components/nav-view/nav-view.js
index 8affa8d28a..67e2228949 100644
--- a/src/components/nav-view/nav-view.js
+++ b/src/components/nav-view/nav-view.js
@@ -1,171 +1,30 @@
-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 {DynamicComponent, Parent, NgElement} from 'angular2/angular2'
+import {NavViewport} from 'ionic2/components'
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'
+import {PrivateComponentLocation} from 'angular2/src/core/compiler/private_component_location'
-@Component({
- selector: 'ion-nav',
+@DynamicComponent({
+ selector: '.nav-view',
bind: {
- initial: 'initial'
- },
- services: []
-})
-@Template({
- inline: ``
+ item: 'item'
+ }
})
export class NavView {
constructor(
- @NgElement() element: NgElement,
- eventManager: EventManager,
- compiler: Compiler,
- location: PrivateComponentLocation,
loader: PrivateComponentLoader,
- directiveMetadataReader: DirectiveMetadataReader,
- shadowDomStrategy: ShadowDomStrategy
+ location: PrivateComponentLocation,
+ @Parent() viewport: NavViewport,
+ @NgElement() element: NgElement
) {
- this.attacher = new Attacher({
- compiler,
- element,
- location,
- loader,
- directiveMetadataReader,
- eventManager,
- shadowDomStrategy
- })
-
- this._children = []
- console.log('Nav View constructed')
- }
-
- set initial(Type) {
- if (!this.initialized) {
- this.initialized = true
- this.push(Type)
- }
- }
-
- /**
- * Push a new view into the history stack.
- *
- * @param view the new view
- * @param shouldAnimate whether to animate
- */
- push(Type, shouldAnimate) {
- //TODO animation
-
- let current = this._children[this._children.length - 1]
- current && current.hide()
-
- this.attacher.attachComponent(Type).then(child => {
- this._children.push(child)
- })
- Log.log('NAV: PUSH', Type.name, 'Animate?', shouldAnimate)
- }
-
- /**
- * Pop a view off the history
- *
- * @param shouldAnimate whether to animate
- */
- pop(shouldAnimate) {
- // 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
- }
-
- get views() {
- return this._views
- }
- /**
- * Set the view stack explicitly.
- */
- set views(v) {
- this._views = v
- }
-
- // Animate a new view *in*
- _animateIn(view) {
-
- }
-
- // Animate an old view *out*
- _animateOut(view) {
- }
-
-}
-
-class Attacher {
- constructor({
- location,
- element,
- directiveMetadataReader,
- compiler,
- shadowDomStrategy,
- eventManager
- }) {
+ this.loader = loader
this.location = location
- this.element = element
- this.directiveMetadataReader = directiveMetadataReader
- this.compiler = compiler
- this.shadowDomStrategy = shadowDomStrategy
- this.eventManager = eventManager
+ this.viewport = viewport
+ this.domElement = element.domElement
}
- 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()
- },
- }
+ set item(navItem) {
+ this.loader.load(navItem.Class, this.location).then(instance => {
+ navItem.finishSetup(this, instance)
})
}
-
}
diff --git a/src/components/nav-view/nav-view.scss b/src/components/nav-view/nav-view.scss
new file mode 100644
index 0000000000..3b7cc3b202
--- /dev/null
+++ b/src/components/nav-view/nav-view.scss
@@ -0,0 +1,16 @@
+.nav-view {
+ opacity: 0;
+ transition: 0.25s;
+ width: 100%;
+ height: 100%;
+}
+
+.nav-view.in {
+ opacity: 1;
+}
+.nav-view.out {
+ position: absolute;
+ top: 0;
+ left: 0;
+ opacity: 0;
+}
diff --git a/src/components/nav-view/test/basic/main.html b/src/components/nav-view/test/basic/main.html
deleted file mode 100644
index a942ebb790..0000000000
--- a/src/components/nav-view/test/basic/main.html
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
diff --git a/src/components/nav-viewport/nav-viewport.js b/src/components/nav-viewport/nav-viewport.js
new file mode 100644
index 0000000000..a3442cf4f6
--- /dev/null
+++ b/src/components/nav-viewport/nav-viewport.js
@@ -0,0 +1,143 @@
+import {Component, Template, For} from 'angular2/angular2'
+import {ComponentConfig} from 'ionic2/config/component-config'
+import {NavView} from 'ionic2/components/nav-view/nav-view'
+import * as util from 'ionic2/util'
+
+@Component({
+ selector: 'ion-nav-viewport',
+ bind: {
+ initial: 'initial'
+ },
+})
+@Template({
+ inline: `
+
+ `,
+ directives: [NavView, For]
+})
+export class NavViewport {
+ constructor(
+ ) {
+ this.stack = new NavStack();
+ }
+
+ set initial(Class) {
+ if (!this.initialized) {
+ this.initialized = true
+ this.push(Class)
+ }
+ }
+
+ getAnimation(opts) {
+ return 'fade'
+ }
+
+ /**
+ * Push a new view into the history stack.
+ *
+ * @param view the new view
+ * @param shouldAnimate whether to animate
+ */
+ push(Class, opts = {}) {
+ //TODO animation
+ return this.stack.push(Class)
+ }
+
+ /**
+ * Pop a view off the history
+ *
+ * @param shouldAnimate whether to animate
+ */
+ pop() {
+ // TODO animation
+ return this.stack.pop()
+ }
+
+ // Animate a new view *in*
+ _animateIn(view) {
+
+ }
+
+ // Animate an old view *out*
+ _animateOut(view) {
+ }
+
+}
+
+class NavStack {
+ constructor(navView) {
+ // array to communicate with angular for loop. When an element is in this array, it really
+ // exists in the DOM.
+ this._array = []
+ }
+ rawItems() {
+ return this._array
+ }
+
+ push(ComponentClass) {
+ const item = new NavStackItem(ComponentClass)
+ let last = this._array[this._array.length - 1]
+
+ this._array.push(item)
+ return item.setupPromise.then(() => {
+ // Once the item is successfully instantiated, add it to our public history
+ item.animateIn()
+ last && last.animateOut()
+ })
+ }
+
+ pop() {
+ // public registry: instantly remove to make the removal seem 'synchronous' for our data
+ const current = this._array[this._array.length - 1]
+ const previous = this._array[this._array.length - 2]
+ current.animateOut().then(() => {
+ util.array.remove(current)
+ })
+ return previous && previous.animateIn()
+ }
+}
+
+class NavStackItem {
+ constructor(ComponentClass) {
+ this.setupPromise = new Promise((resolve) => {
+ this.finishSetup = (navView, componentInstance) => {
+ this.navView = navView
+ this.instance = componentInstance
+ resolve()
+ }
+ })
+ this.Class = ComponentClass
+ }
+ setInstance(instance) {
+ this.instance = instance
+ }
+ setNavView(navView) {
+ this.navView = navView
+ }
+
+ animateIn() {
+ this.navView.domElement.classList.remove('out')
+ this.navView.domElement.classList.add('in')
+ return new Promise(resolve => {
+ this.navView.domElement.addEventListener('transitionend', (ev) => {
+ if (ev.target !== this.navView.domElement) {
+ return
+ }
+ resolve()
+ })
+ })
+ }
+ animateOut() {
+ this.navView.domElement.classList.add('out')
+ this.navView.domElement.classList.remove('in')
+ return new Promise(resolve => {
+ this.navView.domElement.addEventListener('transitionend', (ev) => {
+ if (ev.target !== this.navView.domElement) {
+ return
+ }
+ resolve()
+ })
+ })
+ }
+}
diff --git a/src/components/nav-viewport/test/basic/main.html b/src/components/nav-viewport/test/basic/main.html
new file mode 100644
index 0000000000..9de8f8a062
--- /dev/null
+++ b/src/components/nav-viewport/test/basic/main.html
@@ -0,0 +1,2 @@
+
+
diff --git a/src/components/nav-view/test/basic/main.js b/src/components/nav-viewport/test/basic/main.js
similarity index 81%
rename from src/components/nav-view/test/basic/main.js
rename to src/components/nav-viewport/test/basic/main.js
index 6e51e918de..103a74c63c 100644
--- a/src/components/nav-view/test/basic/main.js
+++ b/src/components/nav-viewport/test/basic/main.js
@@ -1,12 +1,12 @@
import {bootstrap} from 'angular2/core'
import {Component, Template} from 'angular2/angular2'
-import {NavView} from 'ionic2/components/nav-view/nav-view'
+import {NavViewport} from 'ionic2/components'
import {Log} from 'ionic2/util'
import {FirstPage} from 'app/pages/first-page'
@Component({ selector: '[ion-app]' })
@Template({
- directives: [NavView],
+ directives: [NavViewport],
url: 'main.html'
})
class IonicApp {
diff --git a/src/components/nav-view/test/basic/pages/first-page.html b/src/components/nav-viewport/test/basic/pages/first-page.html
similarity index 100%
rename from src/components/nav-view/test/basic/pages/first-page.html
rename to src/components/nav-viewport/test/basic/pages/first-page.html
diff --git a/src/components/nav-view/test/basic/pages/first-page.js b/src/components/nav-viewport/test/basic/pages/first-page.js
similarity index 69%
rename from src/components/nav-view/test/basic/pages/first-page.js
rename to src/components/nav-viewport/test/basic/pages/first-page.js
index 7e26fc8e30..c6af15e970 100644
--- a/src/components/nav-view/test/basic/pages/first-page.js
+++ b/src/components/nav-viewport/test/basic/pages/first-page.js
@@ -1,5 +1,5 @@
import {Component, Template, Parent} from 'angular2/angular2'
-import {NavView} from 'ionic2/components/nav-view/nav-view'
+import {NavViewport} from 'ionic2/components'
import {View} from 'ionic2/components/view/view'
import {SecondPage} from 'app/pages/second-page'
@@ -12,12 +12,12 @@ import {SecondPage} from 'app/pages/second-page'
})
export class FirstPage {
constructor(
- @Parent() navView: NavView
+ @Parent() viewport: NavViewport
) {
- this.navView = navView
+ this.viewport = viewport
}
nextPage() {
- this.navView.push(SecondPage)
+ this.viewport.push(SecondPage)
}
}
diff --git a/src/components/nav-view/test/basic/pages/second-page.html b/src/components/nav-viewport/test/basic/pages/second-page.html
similarity index 100%
rename from src/components/nav-view/test/basic/pages/second-page.html
rename to src/components/nav-viewport/test/basic/pages/second-page.html
diff --git a/src/components/nav-view/test/basic/pages/second-page.js b/src/components/nav-viewport/test/basic/pages/second-page.js
similarity index 67%
rename from src/components/nav-view/test/basic/pages/second-page.js
rename to src/components/nav-viewport/test/basic/pages/second-page.js
index e223650e48..1a146d6889 100644
--- a/src/components/nav-view/test/basic/pages/second-page.js
+++ b/src/components/nav-viewport/test/basic/pages/second-page.js
@@ -1,5 +1,5 @@
import {Component, Template, Parent} from 'angular2/angular2'
-import {NavView} from 'ionic2/components/nav-view/nav-view'
+import {NavViewport} from 'ionic2/components'
import {View} from 'ionic2/components/view/view'
@Component({
@@ -11,11 +11,11 @@ import {View} from 'ionic2/components/view/view'
})
export class SecondPage {
constructor(
- @Parent() navView: NavView
+ @Parent() viewport: NavViewport
) {
- this.navView = navView
+ this.viewport = viewport
}
prevPage() {
- this.navView.pop()
+ this.viewport.pop()
}
}
diff --git a/src/components/nav-view/nav-view.spec.js b/src/components/nav-viewport/test/nav-viewport.spec.js
similarity index 100%
rename from src/components/nav-view/nav-view.spec.js
rename to src/components/nav-viewport/test/nav-viewport.spec.js
diff --git a/src/util/dom.js b/src/util/dom.js
index 06fee40e12..9f02a17782 100644
--- a/src/util/dom.js
+++ b/src/util/dom.js
@@ -12,7 +12,6 @@ export const raf = nativeRaf || function(callback) {
export const rafCancel = nativeRaf ? nativeCancelRaf : function(id) {
return window.cancelTimeout(id)
}
-
export function rafPromise() {
return new Promise(resolve => raf(resolve))
}
@@ -25,9 +24,11 @@ export let css = {}
if (window.ontransitionend === undefined && window.onwebkittransitionend !== undefined) {
css.prefix = 'webkit'
css.transition = 'webkitTransition'
+ css.transform = 'webkitTransform'
css.transitionEnd = 'webkitTransitionEnd transitionend'
} else {
css.prefix = ''
+ css.transform = 'transform'
css.transition = 'transition'
css.transitionEnd = 'tranistionend'
}
diff --git a/src/util/util.js b/src/util/util.js
index e236709ae3..b60836a834 100644
--- a/src/util/util.js
+++ b/src/util/util.js
@@ -55,6 +55,22 @@ export class Log {
}
}
+export let array = {
+ find(arr, cb) {
+ for (let i = 0, ii = arr.length; i < ii; i++) {
+ if (cb(arr[i], i)) return arr[i];
+ }
+ },
+ remove(arr, item) {
+ const index = arr.indexOf(item)
+ if (index === -1) {
+ return false
+ }
+ arr.splice(index, 1)
+ return true
+ }
+}
+
export function readQueryParams() {
var queryParams = {}
const startIndex = window.location.href.indexOf('?')