From 3f7cee872e0489fc10a761c21cc247e89977151a Mon Sep 17 00:00:00 2001 From: Roy Sutton Date: Wed, 29 Apr 2015 18:10:53 -0400 Subject: [PATCH 001/210] ENYO-1279 Document and make public containerName/containerOptions Enyo-DCO-1.1-Signed-off-by: Roy Sutton --- lib/DataRepeater.js | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/lib/DataRepeater.js b/lib/DataRepeater.js index 72e539197..bd2656721 100644 --- a/lib/DataRepeater.js +++ b/lib/DataRepeater.js @@ -690,19 +690,35 @@ var DataRepeater = module.exports = kind( childMixins: [RepeaterChildSupport], /** - * @private + * The name of the container specified in + * [containerOptions]{@link enyo.DataRepeater#containerOptions}. This may or may not have the + * same value as [controlParentName]{@link enyo.DataRepeater#controlParentName}. + * + * @type {String} + * @default 'container' + * @public */ - controlParentName: 'container', + containerName: 'container', /** - * @private + * A [Kind]{@glossary Kind} definition that will be used as the chrome for the container + * of the DataRepeater. When specifying a custom definition be sure to include a container + * component that has the name specified in + * [controlParentName]{@link enyo.DataRepeater#controlParentName}. + * + * @type {Object} + * @default {name: 'container', classes: 'enyo-fill enyo-data-repeater-container'} + * @public */ - containerName: 'container', + containerOptions: {name: 'container', classes: 'enyo-fill enyo-data-repeater-container'}, /** - * @private + * See {@link enyo.UiComponent#controlParentName} + * @type {String} + * @default 'container' + * @public */ - containerOptions: {name: 'container', classes: 'enyo-fill enyo-data-repeater-container'}, + controlParentName: 'container', /** * @private From f7452f93cdcf4bcf00c43c5f862ab28385bab01a Mon Sep 17 00:00:00 2001 From: Jason Robitaille Date: Wed, 10 Jun 2015 11:17:38 -0700 Subject: [PATCH 002/210] ENYO-1355: AjaxSource still using enyo.Model.isNew Enyo-DCO-1.1-Signed-off-by: Jason Robitaille --- lib/AjaxSource.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/AjaxSource.js b/lib/AjaxSource.js index a56ff613a..8e97ff252 100644 --- a/lib/AjaxSource.js +++ b/lib/AjaxSource.js @@ -11,6 +11,7 @@ var var XhrSource = require('./XhrSource'), Ajax = require('./Ajax'), + States = require('./States'), AjaxProperties = require('./AjaxProperties'); /** @@ -75,7 +76,7 @@ module.exports = kind( * @public */ commit: function (model, opts) { - opts.method = model.isNew? 'POST': 'PUT'; + opts.method = (model.status & States.NEW) ? 'POST': 'PUT'; opts.url = this.buildUrl(model, opts); opts.postBody = opts.postBody || model.toJSON(); this.go(opts); From 33666d9305670f3b54ea70c04e5e23631af8eda4 Mon Sep 17 00:00:00 2001 From: Yevgen Sukharenko Date: Tue, 28 Jul 2015 15:31:25 +0300 Subject: [PATCH 003/210] ENYO-1029: Add findIndex for enyo.Collection --- lib/Collection.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/Collection.js b/lib/Collection.js index e151019a2..24823ac16 100644 --- a/lib/Collection.js +++ b/lib/Collection.js @@ -726,6 +726,18 @@ exports = module.exports = kind( return this.models.slice().find(fn, ctx || this); }, + /** + * @see {@glossary Array.findIndex} + * @public + */ + findIndex: function (fn, ctx) { + + // ensure that this is an immutable reference to the models such that changes will + // not affect the entire loop - e.g. calling destroy on models won't keep this from + // completing + return this.models.slice().findIndex(fn, ctx || this); + }, + /** * @see {@glossary Array.map} * @public From 98a2dd37720cf4a30582834536bbe2f264c6aaf1 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Mon, 21 Sep 2015 11:59:19 -0500 Subject: [PATCH 004/210] view manager prototype Issue: Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/CardViewLayout/CardViewLayout.js | 10 + src/CardViewLayout/CardViewLayout.less | 13 + src/CardViewLayout/package.json | 6 + .../LeftRightViewLayout.js | 10 + .../LeftRightViewLayout.less | 14 + src/LeftRightViewLayout/package.json | 6 + src/SlideViewLayout/SlideViewLayout.js | 129 ++++++ src/SlideViewLayout/SlideViewLayout.less | 25 + src/SlideViewLayout/package.json | 6 + src/ViewLayout/ViewLayout.js | 145 ++++++ src/ViewLayout/ViewLayout.less | 12 + src/ViewLayout/package.json | 6 + src/ViewManager/ViewManager.js | 432 ++++++++++++++++++ src/ViewManager/package.json | 3 + 14 files changed, 817 insertions(+) create mode 100644 src/CardViewLayout/CardViewLayout.js create mode 100644 src/CardViewLayout/CardViewLayout.less create mode 100644 src/CardViewLayout/package.json create mode 100644 src/LeftRightViewLayout/LeftRightViewLayout.js create mode 100644 src/LeftRightViewLayout/LeftRightViewLayout.less create mode 100644 src/LeftRightViewLayout/package.json create mode 100644 src/SlideViewLayout/SlideViewLayout.js create mode 100644 src/SlideViewLayout/SlideViewLayout.less create mode 100644 src/SlideViewLayout/package.json create mode 100644 src/ViewLayout/ViewLayout.js create mode 100644 src/ViewLayout/ViewLayout.less create mode 100644 src/ViewLayout/package.json create mode 100644 src/ViewManager/ViewManager.js create mode 100644 src/ViewManager/package.json diff --git a/src/CardViewLayout/CardViewLayout.js b/src/CardViewLayout/CardViewLayout.js new file mode 100644 index 000000000..e1ac42721 --- /dev/null +++ b/src/CardViewLayout/CardViewLayout.js @@ -0,0 +1,10 @@ +var + kind = require('enyo/kind'); + +var + ViewLayout = require('../ViewLayout'); + +module.exports = kind({ + kind: ViewLayout, + layoutClass: 'enyo-viewlayout enyo-viewlayout-card' +}); \ No newline at end of file diff --git a/src/CardViewLayout/CardViewLayout.less b/src/CardViewLayout/CardViewLayout.less new file mode 100644 index 000000000..413b0f098 --- /dev/null +++ b/src/CardViewLayout/CardViewLayout.less @@ -0,0 +1,13 @@ +.enyo-viewlayout-card { + &:not(.dragging) > .enyo-view.transitioning { + transition: opacity 300ms linear; + will-change: opacity; + } + + > .enyo-view { + opacity: 0; + &.active { + opacity: 1; + } + } +} \ No newline at end of file diff --git a/src/CardViewLayout/package.json b/src/CardViewLayout/package.json new file mode 100644 index 000000000..c41813ab1 --- /dev/null +++ b/src/CardViewLayout/package.json @@ -0,0 +1,6 @@ +{ + "main": "CardViewLayout.js", + "styles": [ + "CardViewLayout.less" + ] +} \ No newline at end of file diff --git a/src/LeftRightViewLayout/LeftRightViewLayout.js b/src/LeftRightViewLayout/LeftRightViewLayout.js new file mode 100644 index 000000000..8088d9857 --- /dev/null +++ b/src/LeftRightViewLayout/LeftRightViewLayout.js @@ -0,0 +1,10 @@ +var + kind = require('enyo/kind'); + +var + ViewLayout = require('../ViewLayout'); + +module.exports = kind({ + kind: ViewLayout, + layoutClass: 'enyo-viewlayout enyo-viewlayout-leftright' +}); \ No newline at end of file diff --git a/src/LeftRightViewLayout/LeftRightViewLayout.less b/src/LeftRightViewLayout/LeftRightViewLayout.less new file mode 100644 index 000000000..6876641c4 --- /dev/null +++ b/src/LeftRightViewLayout/LeftRightViewLayout.less @@ -0,0 +1,14 @@ +.enyo-viewlayout-leftright { + + > .enyo-view { + transform: translateX(-100%); + &.active { + transform: translateX(0); + } + } + + &:not(.dragging) > .enyo-view.transitioning { + transition: transform 300ms linear; + will-change: transform; + } +} \ No newline at end of file diff --git a/src/LeftRightViewLayout/package.json b/src/LeftRightViewLayout/package.json new file mode 100644 index 000000000..6de288e11 --- /dev/null +++ b/src/LeftRightViewLayout/package.json @@ -0,0 +1,6 @@ +{ + "main": "LeftRightViewLayout.js", + "styles": [ + "LeftRightViewLayout.less" + ] +} \ No newline at end of file diff --git a/src/SlideViewLayout/SlideViewLayout.js b/src/SlideViewLayout/SlideViewLayout.js new file mode 100644 index 000000000..0ad59a7c5 --- /dev/null +++ b/src/SlideViewLayout/SlideViewLayout.js @@ -0,0 +1,129 @@ +var + kind = require('enyo/kind'); + +var + ViewLayout = require('../ViewLayout'); + +/** +* Slides views in from the right or top and out the left or bottom. +* +* Order of operations: +* * `prepareTransition()` +* Applies directional CSS classes (forward or back) to each view based on the animation +* direction. For the becoming-active view, this positions it offscreen. For the becoming-inactive +* view, the directional class is overridden by `active` which keeps it onscreen. Calculates the +* `dragDuration` used as the transition duration when the drag is released. +* * `transition()` +* Sets the transition duration to either its `duration` or a lesser amount to complete the +* animation if the transition happens as a result of a drag operation. If a transform was applied +* during a drag, it is removed. The result is a transition from the currently dragged position +* set by inline style to the final position set by the CSS classes. +* * `completeTransition()` +* Removes the directional classes and resets the `dragDuration` +* +* @class enyo.SlideViewLayout +*/ +module.exports = kind({ + /** + * @private + */ + kind: ViewLayout, + + /** + * @private + */ + layoutClass: 'enyo-viewlayout enyo-viewlayout-slide', + + /** + * Sets the duration of the transition. Imported from the value of `layoutDuration` on the + * container on which the layout is applied. + * + * @type {Number} + * @default 300 + * @public + */ + duration: 300, + + /** + * @private + */ + constructor: function () { + ViewLayout.prototype._constructor.apply(this, arguments); + this.container.addClass(this.container.orientation); + this.duration = this.container.layoutDuration || this.duration; + }, + + /** + * @private + */ + drag: function (event) { + var size, node, + c = this.container, + isHorizontal = c.orientation == 'horizontal', + transform = isHorizontal ? 'translateX' : 'translateY'; + + ViewLayout.prototype.drag.apply(this, arguments); + if (event.percentDelta) + c.active.applyStyle('transform', transform + '(' + event.delta + 'px)'); + if (c.dragView) { + node = c.hasNode(); + size = isHorizontal ? node.clientWidth : node.clientHeight; + c.dragView.applyStyle('transform', transform + '(' + (size * event.direction + event.delta) + 'px)'); + } + + this.dragDuration = this.duration - Math.round(event.percentDelta * this.duration, 2); + }, + + /** + * Applies directional CSS classes to initially position the views. + * + * @private + */ + prepareTransition: function (was, is) { + var c = this.container, + wasIndex = was ? c.panels.indexOf(was) : -1, + isIndex = is ? c.panels.indexOf(is) : -1; + + this.direction = wasIndex < isIndex ? 'forward' : 'back'; + if (is) is.addClass(this.direction); + if (was) was.addClass(this.direction == 'back' ? 'forward' : 'back'); + }, + + /** + * Sets the transition duration, + * + * @private + */ + transition: function (was, is) { + ViewLayout.prototype.transition.apply(this, arguments); + if (was) { + this.applyTransitionDuration(was, this.dragDuration || this.duration); + was.applyStyle('transform', null); + } + if (is) { + is.removeClass(this.direction); + this.applyTransitionDuration(is, this.dragDuration || this.duration); + is.applyStyle('transform', null); + } + + }, + + /** + * Removes the directional CSS class from the deactivating panel + * + * @private + */ + completeTransition: function (was, is) { + ViewLayout.prototype.completeTransition.apply(this, arguments); + this.dragDuration = null; + if (was) was.removeClass(this.direction == 'back' ? 'forward' : 'back'); + }, + + /** + * @private + */ + applyTransitionDuration: function (view, duration) { + view.applyStyle('-webkit-transition-duration', duration + 'ms'); + view.applyStyle('transition-duration', duration + 'ms'); + } +}); \ No newline at end of file diff --git a/src/SlideViewLayout/SlideViewLayout.less b/src/SlideViewLayout/SlideViewLayout.less new file mode 100644 index 000000000..b8fb59389 --- /dev/null +++ b/src/SlideViewLayout/SlideViewLayout.less @@ -0,0 +1,25 @@ +.enyo-viewlayout-slide { + + > .enyo-view { + transform: translateX(-100%); + transition-property: none; + transition-timing-function: ease-in-out; + } + + &:not(.dragging) > .enyo-view.transitioning { + transition-property: transform; + will-change: transform; + } + + &.horizontal > .enyo-view { + &.forward { transform: translateX(100%); } + &.back { transform: translateX(-100%); } + &.active { transform: translateX(0); } + } + + &.vertical > .enyo-view { + &.forward { transform: translateY(-100%); } + &.back { transform: translateY(100%); } + &.active { transform: translateY(0); } + } +} \ No newline at end of file diff --git a/src/SlideViewLayout/package.json b/src/SlideViewLayout/package.json new file mode 100644 index 000000000..45206a06e --- /dev/null +++ b/src/SlideViewLayout/package.json @@ -0,0 +1,6 @@ +{ + "main": "SlideViewLayout.js", + "styles": [ + "SlideViewLayout.less" + ] +} \ No newline at end of file diff --git a/src/ViewLayout/ViewLayout.js b/src/ViewLayout/ViewLayout.js new file mode 100644 index 000000000..2bf428942 --- /dev/null +++ b/src/ViewLayout/ViewLayout.js @@ -0,0 +1,145 @@ +var rAF = window.requestAnimationFrame; + +var + kind = require('enyo/kind'), + utils = require('enyo/utils'), + Layout = require('enyo/Layout'); + +/** +* Order of operations: +* * `prepareTransition()` +* Optionally implementable method by subkinds to apply any CSS before the transition +* * `transition()` +* The `active` CSS class is applied to and removed from the becoming-active and becoming-inactive +* views, respectively. `transitioning` is applied to both views. +* * `completeTransition()` +* Called twice, once for the becoming-active view and once for the becoming-inactive view. +* Removes the `transitioning` class and deactivates the now inactive view. +* +* @class enyo.ViewLayout +*/ +module.exports = kind({ + kind: Layout, + layoutClass: 'enyo-viewlayout', + viewClass: 'enyo-view', + constructor: function () { + Layout.prototype._constructor.apply(this, arguments); + this.container.observe('active', this.activeChanged = this.activeChanged.bind(this)); + this.container.observe('dragging', this.draggingChanged = this.draggingChanged.bind(this)); + this.container.on('drag', this.handleDrag = this.handleDrag.bind(this)); + this.container.on('cancelDrag', this.handleCancelDrag = this.handleCancelDrag.bind(this)); + }, + destroy: function () { + Layout.prototype.destroy.apply(this, arguments); + this.container.unobserve('active', this.activeChanged); + this.container.unobserve('dragging', this.draggingChanged); + this.container.off('drag', this.handleDrag); + this.container.off('cancelDrag', this.handleCancelDrag); + }, + + flow: function () { + + }, + reflow: function () { + + }, + + setupView: function (view) { + if (view && !view.viewSetup) { + view.set('bubbleTarget', this); + view.addClass(this.viewClass); + view.viewSetup = true; + } + }, + + activeChanged: function (was, is) { + this.setupView(is); + + if (this.shouldAnimate()) { + if (this.prepareTransition) { + rAF(function () { + this.prepareTransition(was, is); + rAF(this.transition.bind(this, was, is)); + }.bind(this)); + } else { + rAF(this.transition.bind(this, was, is)); + } + } else { + this.transition(was, is); + if (was) this.completeTransition(was); + if (is) this.completeTransition(is); + } + }, + + draggingChanged: function (was, is) { + this.container.addRemoveClass('dragging', is); + }, + + handleCancelDrag: function (sender, name, event) { + this.activeChanged(this.container.dragView, this.container.active); + }, + + handleDrag: function (sender, name, event) { + // Only update the view once per frame + if (!this.dragEvent) { + rAF(function () { + this.drag(this.dragEvent); + this.dragEvent = null; + }.bind(this)); + } + this.dragEvent = utils.clone(event); + }, + + drag: function (event) { + this.setupView(this.container.dragView); + }, + + prepareTransition: null, + transition: function (was, is) { + if (was) { + was.addClass('transitioning'); + was.removeClass('active'); + } + if (is) { + is.addClass('transitioning'); + is.addClass('active'); + } + }, + completeTransition: function (panel) { + panel.removeClass('transitioning'); + if (panel !== this.container.active) this.container.deactivate(panel.name); + }, + + shouldAnimate: function () { + return this.container.generated && this.container.animated; + }, + + handlers: { + ontransitionend: 'handleTransitioned' + }, + + dispatchBubble: function (name, event, delegate) { + var handler = this.handlers[name]; + if (handler) { + if (this[handler](delegate, event)) { + return true; + } + } else { + return this.container.dispatchBubble(name, event, delegate); + } + }, + + handleTransitioned: function (sender, event) { + var panel = event.originator; + if (panel && panel.container == this.container) { + + if (this.shouldAnimate()) { + rAF(this.completeTransition.bind(this, panel)); + } else { + this.completeTransition(panel); + } + + return true; + } + } +}); \ No newline at end of file diff --git a/src/ViewLayout/ViewLayout.less b/src/ViewLayout/ViewLayout.less new file mode 100644 index 000000000..0ffdceb7f --- /dev/null +++ b/src/ViewLayout/ViewLayout.less @@ -0,0 +1,12 @@ +.enyo-viewlayout { + position: relative; + overflow: hidden; + + > .enyo-view, & > & { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + } +} \ No newline at end of file diff --git a/src/ViewLayout/package.json b/src/ViewLayout/package.json new file mode 100644 index 000000000..6927b4e0a --- /dev/null +++ b/src/ViewLayout/package.json @@ -0,0 +1,6 @@ +{ + "main": "ViewLayout.js", + "styles": [ + "ViewLayout.less" + ] +} \ No newline at end of file diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js new file mode 100644 index 000000000..3e49654de --- /dev/null +++ b/src/ViewManager/ViewManager.js @@ -0,0 +1,432 @@ +var rAF = window.requestAnimationFrame; + +var + kind = require('enyo/kind'), + utils = require('enyo/utils'), + Control = require('enyo/Control'), + EventEmitter = require('enyo/EventEmitter'); + +var + CardViewLayout = require('../CardViewLayout'); + +var ViewMgr = kind({ + kind: Control, + layoutKind: CardViewLayout, + mixins: [EventEmitter], + animated: true, + classes: 'enyo-unselectable', + + /** + * View type + * + * @type {String} + * @default fixed + * @public + */ + type: 'fixed', + + /** + * Active view + * + * @type {Control} + * @private + */ + active: null, + + /** + * When `true`, the views can be dragged into and out of view. + * + * @type {Boolean} + * @default true + * @public + */ + draggable: true, + + /** + * Percent a new view must be dragged into the viewport to be activated on drag release + * + * @type {Number} + * @default 10 + * @public + */ + dragSnapPercent: 25, + + /** + * When `draggable`, this constrains the drag to this direction. + * + * @type {String} + * @default horizontal + * @public + */ + orientation: 'horizontal', + + manager: null, + managerChanged: function (was, is) { + if (was) this.off('*', was.managerEvent); + if (is) this.on('*', is.managerEvent); + }, + + handlers: { + ondown: 'handleDown', + ondragstart: 'handleDragStart', + ondrag: 'handleDrag', + ondragfinish: 'handleDragFinish' + }, + + create: function () { + Control.prototype.create.apply(this, arguments); + this.managerEvent = this.managerEvent.bind(this); + + if (this.type == 'fixed') this.initFirstPanel(); + else if (this.type == 'floating') this.stack = []; + }, + rendered: function () { + Control.prototype.rendered.apply(this, arguments); + if (this.type == 'floating') this.initFirstPanel(); + }, + initComponents: function () { + // panel configs or instance + this.panels = []; + + // map of panel name to index + this.panelNames = {}; + + // import kind and user components into this.panels + this.importPanelConfig(this.kindComponents, this); + this.importPanelConfig(this.components, this.getInstanceOwner()); + + // clean up references + this.components = this.kindComponents = null; + }, + + addControl: function (control, before) { + var index; + Control.prototype.addControl.apply(this, arguments); + + index = this.panelNames[control.name]; + if (!index && index !== 0) { + this.addPanel(control); + } + }, + removeControl: function (control) { + var i, l, + index = this.panels.indexOf(control); + if (index >= 0) { + this.panels.splice(index, 1); + this.panelNames[control.name] = null; + + for (i = index, l = this.panels.length; i < l; i++) { + this.panelNames[this.panels[i].name] = i; + } + } + }, + + /** + * Renders the initially active panel + * + * @private + */ + initFirstPanel: function () { + var name, panel, + i = 0; + + if (this.panels.length === 0) return; + + // find the first declared active panel + while ((panel = this.panels[i++]) && !name) { + if (panel.active) { + name = panel.name; + } + } + + name = name || this.panels[0].name; + if (this.generated) { + this.activate(name); + } else { + panel = this.getPanel(name); + this._activate(panel); + } + }, + + /** + * Adds the list of components as panels + * + * @param {Object[]|enyo.Control[]} components List of components + * @param {enyo.Control|null} [owner] Owner of components + * + * @private + */ + importPanelConfig: function (components, owner) { + var c, + i = 0; + + while (components && (c = components[i++])) { + this.addPanel(c, owner); + } + }, + + /** + * Adds a new panel to the panel set + * + * @param {Object|enyo.Control} panel Panel config or instance + * @param {enyo.Control|null} [owner] Optional owner of panel. Defaults to this. + * + * @private + */ + addPanel: function (panel, owner) { + var isControl = panel instanceof Control, + _panel = isControl ? panel : utils.clone(panel), + index = this.panels.push(_panel), + name = _panel.name || 'panel' + index; + owner = _panel.owner || owner || this; + + if (isControl) { + _panel.set('owner', owner); + _panel.set('name', name); + + if (_panel instanceof ViewMgr) { + _panel.set('manager', this.manager || this); + } + } else { + _panel.owner = owner; + _panel.name = name; + } + + this.panelNames[name] = index - 1; + }, + + /** + * @public + */ + getPanel: function (panelName) { + var index = this.panelNames[panelName], + p = this.panels[index]; + + // not created yet + if (p && !(p instanceof Control)) { + p = this.panels[index] = this.createComponent(p); + } + + return p; + }, + + /** + * @public + */ + next: function () { + var index = this.panels.indexOf(this.active) + 1, + panel = this.panels[index]; + if (panel) { + return this.activate(panel.name); + } + }, + + /** + * @public + */ + previous: function () { + var index = this.panels.indexOf(this.active) - 1, + panel = this.panels[index]; + if (panel) { + return this.activate(panel.name); + } + }, + + /** + * @public + */ + back: function () { + var name; + if (this.type == 'floating') { + this.stack.pop(); + name = this.stack[this.stack.length - 1]; + this.activate(name); + } + }, + + canDrag: function (direction) { + var index; + if (this.draggable) { + if (this.type == 'floating' && direction == -1) { + return true; + } + else if (this.type == 'fixed') { + index = this.panels.indexOf(this.active); + return (index > 0 && direction == -1) || + (index < this.panels.length - 1 && direction == 1); + } + } + + return false; + }, + + /** + * Dismisses a floating view manager + * + * @public + */ + dismiss: function () { + if (this.type == 'floating') { + this.set('active', null); + this.set('dismissed', true); + this.emit('dismiss'); + } + }, + + /** + * Since handler for events emitted from descendant view managers + * + * @param {[type]} viewManager [description] + * @param {[type]} event [description] + * @param {[type]} panel [description] + * + * @return {[type]} [description] + */ + managerEvent: function (viewManager, event, panel) { + if (event == 'dismiss') this.managerDismissing(viewManager); + else if (event == 'dismissed') this.managerDismissed(viewManager); + else if (event == 'activated') this.managerActivated(viewManager, panel); + else if (event == 'deactivated') this.managerDeactivated(viewManager, panel); + }, + + /** + * Handles dismissal of child view managers + * + * @private + */ + managerDismissed: function (viewManager) { + this.log(this.id, 'ViewMgr', viewManager.name, 'dismissed'); + viewManager.destroy(); + }, + + managerDismissing: function (viewManager) { + this.log(this.id, 'ViewMgr', viewManager.name, 'dismissing'); + }, + + managerActivated: function (viewManager, panel) { + this.log(this.id, 'activated', panel.name); + }, + + managerDeactivated: function (viewManager, panel) { + this.log(this.id, 'deactivated', panel.name); + }, + + /** + * @private + */ + activate: function (panelName) { + var p = this.getPanel(panelName); + if (p) { + if (this.type == 'floating' && this.stack[this.stack.length - 1] !== panelName) { + this.stack.push(panelName); + } + rAF(this._activate.bind(this, p)); + } + return p; + }, + + /** + * @private + */ + _activate: function (panel) { + // render the activated panel + if (this.generated) panel.render(); + if (!this.dragging) { + this.set('active', panel); + this.emit('activated', panel); + } + }, + + /** + * @private + */ + deactivate: function (panelName) { + var p = this.getPanel(panelName); + if (p) rAF(this._deactivate.bind(this, p)); + }, + + /** + * @private + */ + _deactivate: function (panel) { + if (panel.node) { + panel.node.remove(); + panel.teardownRender(true); + } + + if (!this.dragging) { + this.emit('deactivated', panel); + if (this.dismissed && this.manager) this.emit('dismissed'); + } + }, + + // Draggable + + handleDown: function (sender, event) { + event.configureHoldPulse({endHold: 'onMove'}); + }, + + handleDragStart: function (sender, event) { + if (!this.draggable) return; + this.set('dragging', true); + this.dragDirection = 0; + this.dragBounds = this.getBounds(); + + return true; + }, + + handleDrag: function (sender, event) { + if (!this.draggable) return; + + this.decorateDragEvent(event); + if (this.canDrag(event.direction)) { + // clean up on change of direction + if (this.dragDirection !== event.direction) { + this.dragDirection = event.direction; + if (this.dragView) { + this.deactivate(this.dragView.name); + this.dragView = null; + } + } + + // set up the new drag view + if (!this.dragView) { + this.dragView = this.dragDirection == 1 ? this.next() : this.previous(); + } + this.emit('drag', event); + } + + return true; + }, + + handleDragFinish: function (sender, event) { + if (!this.draggable) return; + this.decorateDragEvent(event); + if (event.percentDelta * 100 > this.dragSnapPercent) { + if (this.dragView) { + this.activate(this.dragView.name); + this.dragView = null; + } + else if (this.type == 'floating' && event.direction == -1) { + this.dismiss(); + } + } else { + this.emit('cancelDrag', event); + this.dragView = null; + } + this.set('dragging', false); + + return true; + }, + + decorateDragEvent: function (event) { + var isHorizontal = this.orientation == 'horizontal', + size = isHorizontal ? this.dragBounds.width : this.dragBounds.height; + event.delta = isHorizontal ? event.dx : event.dy; + // 'natural' touch causes us to invert the physical change + event.direction = event.delta < 0 ? 1 : -1; + event.percentDelta = 1 - (size - Math.abs(event.delta)) / size; + } +}); + +module.exports = ViewMgr; \ No newline at end of file diff --git a/src/ViewManager/package.json b/src/ViewManager/package.json new file mode 100644 index 000000000..bb442b5d0 --- /dev/null +++ b/src/ViewManager/package.json @@ -0,0 +1,3 @@ +{ + "main": "ViewManager.js" +} \ No newline at end of file From 0588df3a09f7d57e3fd933ab18c45e2afcf03dc6 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Tue, 22 Sep 2015 14:39:58 -0500 Subject: [PATCH 005/210] refactor TransitionViewLayout into kind Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/CardViewLayout/CardViewLayout.js | 27 +++++- src/CardViewLayout/CardViewLayout.less | 3 +- .../LeftRightViewLayout.js | 29 ++++++- .../LeftRightViewLayout.less | 12 +-- src/SlideViewLayout/SlideViewLayout.js | 48 ++--------- src/TransitionViewLayout.js | 86 +++++++++++++++++++ src/ViewLayout/ViewLayout.js | 1 + src/ViewManager/ViewManager.js | 2 +- 8 files changed, 153 insertions(+), 55 deletions(-) create mode 100644 src/TransitionViewLayout.js diff --git a/src/CardViewLayout/CardViewLayout.js b/src/CardViewLayout/CardViewLayout.js index e1ac42721..a1be58944 100644 --- a/src/CardViewLayout/CardViewLayout.js +++ b/src/CardViewLayout/CardViewLayout.js @@ -2,9 +2,30 @@ var kind = require('enyo/kind'); var - ViewLayout = require('../ViewLayout'); + TransitionViewLayout = require('../TransitionViewLayout'); module.exports = kind({ - kind: ViewLayout, - layoutClass: 'enyo-viewlayout enyo-viewlayout-card' + kind: TransitionViewLayout, + layoutClass: 'enyo-viewlayout enyo-viewlayout-card', + + /** + * @private + */ + drag: function (event) { + var c = this.container, + delta = (event.percentDelta < -1 || event.percentDelta > 1) && 1 || + Math.abs(event.percentDelta); + TransitionViewLayout.prototype.drag.apply(this, arguments); + c.active.applyStyle('opacity', 1 - delta); + if (c.dragView) c.dragView.applyStyle('opacity', delta); + }, + + /** + * @private + */ + transition: function (was, is) { + TransitionViewLayout.prototype.transition.apply(this, arguments); + if (was) was.applyStyle('opacity', null); + if (is) is.applyStyle('opacity', null); + } }); \ No newline at end of file diff --git a/src/CardViewLayout/CardViewLayout.less b/src/CardViewLayout/CardViewLayout.less index 413b0f098..2a935e2b5 100644 --- a/src/CardViewLayout/CardViewLayout.less +++ b/src/CardViewLayout/CardViewLayout.less @@ -1,10 +1,11 @@ .enyo-viewlayout-card { &:not(.dragging) > .enyo-view.transitioning { - transition: opacity 300ms linear; + transition-property: opacity; will-change: opacity; } > .enyo-view { + transition-property: none; opacity: 0; &.active { opacity: 1; diff --git a/src/LeftRightViewLayout/LeftRightViewLayout.js b/src/LeftRightViewLayout/LeftRightViewLayout.js index 8088d9857..16bdb2246 100644 --- a/src/LeftRightViewLayout/LeftRightViewLayout.js +++ b/src/LeftRightViewLayout/LeftRightViewLayout.js @@ -2,9 +2,32 @@ var kind = require('enyo/kind'); var - ViewLayout = require('../ViewLayout'); + TransitionViewLayout = require('../TransitionViewLayout'); module.exports = kind({ - kind: ViewLayout, - layoutClass: 'enyo-viewlayout enyo-viewlayout-leftright' + kind: TransitionViewLayout, + layoutClass: 'enyo-viewlayout enyo-viewlayout-leftright', + + /** + * @private + */ + drag: function (event) { + var c = this.container, + node = c.hasNode(), + size = node.clientWidth + delta = Math.min(size, Math.abs(event.delta)); + + TransitionViewLayout.prototype.drag.apply(this, arguments); + c.active.applyStyle('transform', 'translateX(' + delta + 'px)'); + if (c.dragView) c.dragView.applyStyle('transform', 'translateX(' + (size - delta) + 'px)'); + }, + + /** + * @private + */ + transition: function (was, is) { + TransitionViewLayout.prototype.transition.apply(this, arguments); + if (was) was.applyStyle('transform', null); + if (is) is.applyStyle('transform', null); + } }); \ No newline at end of file diff --git a/src/LeftRightViewLayout/LeftRightViewLayout.less b/src/LeftRightViewLayout/LeftRightViewLayout.less index 6876641c4..81ed87795 100644 --- a/src/LeftRightViewLayout/LeftRightViewLayout.less +++ b/src/LeftRightViewLayout/LeftRightViewLayout.less @@ -1,14 +1,16 @@ .enyo-viewlayout-leftright { + &:not(.dragging) > .enyo-view.transitioning { + transition-property: transform; + will-change: transform; + } + > .enyo-view { - transform: translateX(-100%); + transition-property: none; + transform: translateX(100%); &.active { transform: translateX(0); } } - &:not(.dragging) > .enyo-view.transitioning { - transition: transform 300ms linear; - will-change: transform; - } } \ No newline at end of file diff --git a/src/SlideViewLayout/SlideViewLayout.js b/src/SlideViewLayout/SlideViewLayout.js index 0ad59a7c5..3913f795f 100644 --- a/src/SlideViewLayout/SlideViewLayout.js +++ b/src/SlideViewLayout/SlideViewLayout.js @@ -2,7 +2,7 @@ var kind = require('enyo/kind'); var - ViewLayout = require('../ViewLayout'); + TransitionViewLayout = require('../TransitionViewLayout'); /** * Slides views in from the right or top and out the left or bottom. @@ -27,32 +27,13 @@ module.exports = kind({ /** * @private */ - kind: ViewLayout, + kind: TransitionViewLayout, /** * @private */ layoutClass: 'enyo-viewlayout enyo-viewlayout-slide', - /** - * Sets the duration of the transition. Imported from the value of `layoutDuration` on the - * container on which the layout is applied. - * - * @type {Number} - * @default 300 - * @public - */ - duration: 300, - - /** - * @private - */ - constructor: function () { - ViewLayout.prototype._constructor.apply(this, arguments); - this.container.addClass(this.container.orientation); - this.duration = this.container.layoutDuration || this.duration; - }, - /** * @private */ @@ -62,16 +43,13 @@ module.exports = kind({ isHorizontal = c.orientation == 'horizontal', transform = isHorizontal ? 'translateX' : 'translateY'; - ViewLayout.prototype.drag.apply(this, arguments); - if (event.percentDelta) + TransitionViewLayout.prototype.drag.apply(this, arguments); c.active.applyStyle('transform', transform + '(' + event.delta + 'px)'); if (c.dragView) { node = c.hasNode(); size = isHorizontal ? node.clientWidth : node.clientHeight; c.dragView.applyStyle('transform', transform + '(' + (size * event.direction + event.delta) + 'px)'); } - - this.dragDuration = this.duration - Math.round(event.percentDelta * this.duration, 2); }, /** @@ -95,17 +73,12 @@ module.exports = kind({ * @private */ transition: function (was, is) { - ViewLayout.prototype.transition.apply(this, arguments); - if (was) { - this.applyTransitionDuration(was, this.dragDuration || this.duration); - was.applyStyle('transform', null); - } + TransitionViewLayout.prototype.transition.apply(this, arguments); + if (was) was.applyStyle('transform', null); if (is) { is.removeClass(this.direction); - this.applyTransitionDuration(is, this.dragDuration || this.duration); is.applyStyle('transform', null); } - }, /** @@ -114,16 +87,7 @@ module.exports = kind({ * @private */ completeTransition: function (was, is) { - ViewLayout.prototype.completeTransition.apply(this, arguments); - this.dragDuration = null; + TransitionViewLayout.prototype.completeTransition.apply(this, arguments); if (was) was.removeClass(this.direction == 'back' ? 'forward' : 'back'); - }, - - /** - * @private - */ - applyTransitionDuration: function (view, duration) { - view.applyStyle('-webkit-transition-duration', duration + 'ms'); - view.applyStyle('transition-duration', duration + 'ms'); } }); \ No newline at end of file diff --git a/src/TransitionViewLayout.js b/src/TransitionViewLayout.js new file mode 100644 index 000000000..fc487913c --- /dev/null +++ b/src/TransitionViewLayout.js @@ -0,0 +1,86 @@ +var + kind = require('enyo/kind'); + +var + ViewLayout = require('./ViewLayout'); + +/** +* Slides views in from the right or top and out the left or bottom. +* +* Order of operations: +* * `prepareTransition()` +* Applies directional CSS classes (forward or back) to each view based on the animation +* direction. For the becoming-active view, this positions it offscreen. For the becoming-inactive +* view, the directional class is overridden by `active` which keeps it onscreen. Calculates the +* `dragDuration` used as the transition duration when the drag is released. +* * `transition()` +* Sets the transition duration to either its `duration` or a lesser amount to complete the +* animation if the transition happens as a result of a drag operation. If a transform was applied +* during a drag, it is removed. The result is a transition from the currently dragged position +* set by inline style to the final position set by the CSS classes. +* * `completeTransition()` +* Removes the directional classes and resets the `dragDuration` +* +* @class enyo.SlideViewLayout +*/ +module.exports = kind({ + /** + * @private + */ + kind: ViewLayout, + + /** + * Sets the duration of the transition. Imported from the value of `layoutDuration` on the + * container on which the layout is applied. + * + * @type {Number} + * @default 300 + * @public + */ + duration: 300, + + /** + * @private + */ + constructor: function () { + ViewLayout.prototype._constructor.apply(this, arguments); + this.duration = this.container.layoutDuration || this.duration; + }, + + /** + * @private + */ + drag: function (event) { + ViewLayout.prototype.drag.apply(this, arguments); + this.dragDuration = this.duration - Math.round(event.percentDelta * this.duration, 2); + }, + + /** + * Sets the transition duration, + * + * @private + */ + transition: function (was, is) { + ViewLayout.prototype.transition.apply(this, arguments); + if (was) this.applyTransitionDuration(was, this.dragDuration || this.duration); + if (is) this.applyTransitionDuration(is, this.dragDuration || this.duration); + }, + + /** + * Removes the directional CSS class from the deactivating panel + * + * @private + */ + completeTransition: function (was, is) { + ViewLayout.prototype.completeTransition.apply(this, arguments); + this.dragDuration = null; + }, + + /** + * @private + */ + applyTransitionDuration: function (view, duration) { + view.applyStyle('-webkit-transition-duration', duration + 'ms'); + view.applyStyle('transition-duration', duration + 'ms'); + } +}); \ No newline at end of file diff --git a/src/ViewLayout/ViewLayout.js b/src/ViewLayout/ViewLayout.js index 2bf428942..eeed552a9 100644 --- a/src/ViewLayout/ViewLayout.js +++ b/src/ViewLayout/ViewLayout.js @@ -24,6 +24,7 @@ module.exports = kind({ viewClass: 'enyo-view', constructor: function () { Layout.prototype._constructor.apply(this, arguments); + this.container.addClass(this.container.orientation); this.container.observe('active', this.activeChanged = this.activeChanged.bind(this)); this.container.observe('dragging', this.draggingChanged = this.draggingChanged.bind(this)); this.container.on('drag', this.handleDrag = this.handleDrag.bind(this)); diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 3e49654de..426b19164 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -349,7 +349,7 @@ var ViewMgr = kind({ * @private */ _deactivate: function (panel) { - if (panel.node) { + if (panel.node && !panel.persistent) { panel.node.remove(); panel.teardownRender(true); } From 95d20fecc606b6aa3975da1a3d9b5a3d395663f6 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Tue, 22 Sep 2015 15:37:47 -0500 Subject: [PATCH 006/210] prevent handling drag events when a view transition has occurred Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/LeftRightViewLayout/LeftRightViewLayout.js | 2 +- src/ViewLayout/ViewLayout.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/LeftRightViewLayout/LeftRightViewLayout.js b/src/LeftRightViewLayout/LeftRightViewLayout.js index 16bdb2246..4b16aeb34 100644 --- a/src/LeftRightViewLayout/LeftRightViewLayout.js +++ b/src/LeftRightViewLayout/LeftRightViewLayout.js @@ -14,7 +14,7 @@ module.exports = kind({ drag: function (event) { var c = this.container, node = c.hasNode(), - size = node.clientWidth + size = node.clientWidth, delta = Math.min(size, Math.abs(event.delta)); TransitionViewLayout.prototype.drag.apply(this, arguments); diff --git a/src/ViewLayout/ViewLayout.js b/src/ViewLayout/ViewLayout.js index eeed552a9..fc4aaf67a 100644 --- a/src/ViewLayout/ViewLayout.js +++ b/src/ViewLayout/ViewLayout.js @@ -84,7 +84,7 @@ module.exports = kind({ // Only update the view once per frame if (!this.dragEvent) { rAF(function () { - this.drag(this.dragEvent); + if (this.container.dragging) this.drag(this.dragEvent); this.dragEvent = null; }.bind(this)); } From d067d664e40d46f4943c4fdb49c8e850f614b3b1 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Wed, 23 Sep 2015 16:44:28 -0500 Subject: [PATCH 007/210] add support for declarative sub-ViewManager configuration Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/SlideViewLayout/SlideViewLayout.js | 4 +- src/TransitionViewLayout.js | 2 +- src/ViewLayout/ViewLayout.js | 14 +- src/ViewManager/ViewManager.js | 299 +++++++++++++++---------- 4 files changed, 193 insertions(+), 126 deletions(-) diff --git a/src/SlideViewLayout/SlideViewLayout.js b/src/SlideViewLayout/SlideViewLayout.js index 3913f795f..bd1ac590c 100644 --- a/src/SlideViewLayout/SlideViewLayout.js +++ b/src/SlideViewLayout/SlideViewLayout.js @@ -59,8 +59,8 @@ module.exports = kind({ */ prepareTransition: function (was, is) { var c = this.container, - wasIndex = was ? c.panels.indexOf(was) : -1, - isIndex = is ? c.panels.indexOf(is) : -1; + wasIndex = was ? c.views.indexOf(was) : -1, + isIndex = is ? c.views.indexOf(is) : -1; this.direction = wasIndex < isIndex ? 'forward' : 'back'; if (is) is.addClass(this.direction); diff --git a/src/TransitionViewLayout.js b/src/TransitionViewLayout.js index fc487913c..6d8ab3c13 100644 --- a/src/TransitionViewLayout.js +++ b/src/TransitionViewLayout.js @@ -67,7 +67,7 @@ module.exports = kind({ }, /** - * Removes the directional CSS class from the deactivating panel + * Removes the directional CSS class from the deactivating view * * @private */ diff --git a/src/ViewLayout/ViewLayout.js b/src/ViewLayout/ViewLayout.js index fc4aaf67a..ee81fe2dd 100644 --- a/src/ViewLayout/ViewLayout.js +++ b/src/ViewLayout/ViewLayout.js @@ -106,9 +106,9 @@ module.exports = kind({ is.addClass('active'); } }, - completeTransition: function (panel) { - panel.removeClass('transitioning'); - if (panel !== this.container.active) this.container.deactivate(panel.name); + completeTransition: function (view) { + view.removeClass('transitioning'); + if (view !== this.container.active) this.container.deactivate(view.name); }, shouldAnimate: function () { @@ -131,13 +131,13 @@ module.exports = kind({ }, handleTransitioned: function (sender, event) { - var panel = event.originator; - if (panel && panel.container == this.container) { + var view = event.originator; + if (view && view.container == this.container) { if (this.shouldAnimate()) { - rAF(this.completeTransition.bind(this, panel)); + rAF(this.completeTransition.bind(this, view)); } else { - this.completeTransition(panel); + this.completeTransition(view); } return true; diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 426b19164..a0354a9d6 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -76,159 +76,184 @@ var ViewMgr = kind({ create: function () { Control.prototype.create.apply(this, arguments); this.managerEvent = this.managerEvent.bind(this); + this.managerChanged(null, this.manager); - if (this.type == 'fixed') this.initFirstPanel(); + if (this.type == 'fixed') this.initFirstView(); else if (this.type == 'floating') this.stack = []; }, rendered: function () { Control.prototype.rendered.apply(this, arguments); - if (this.type == 'floating') this.initFirstPanel(); + if (this.type == 'floating') this.initFirstView(); + this.set('dismissed', false); }, initComponents: function () { - // panel configs or instance - this.panels = []; + var managersOwner = Object.hasOwnProperty('managers') ? this.getInstanceOwner() : this; - // map of panel name to index - this.panelNames = {}; + // view configs or instances + this.views = []; + this.viewManagers = {}; - // import kind and user components into this.panels - this.importPanelConfig(this.kindComponents, this); - this.importPanelConfig(this.components, this.getInstanceOwner()); + // map of view name to index + this.viewNames = {}; + + // import kind and user components into this.views + this.importViewConfig(this.kindComponents, this); + this.importViewConfig(this.components, this.getInstanceOwner()); + this.importViewConfig(this.managers, managersOwner, true); // clean up references this.components = this.kindComponents = null; }, addControl: function (control, before) { - var index; Control.prototype.addControl.apply(this, arguments); - index = this.panelNames[control.name]; - if (!index && index !== 0) { - this.addPanel(control); + if (!this.viewNames[control.name]) { + this.addView(control); } }, removeControl: function (control) { var i, l, - index = this.panels.indexOf(control); + index = this.views.indexOf(control); if (index >= 0) { - this.panels.splice(index, 1); - this.panelNames[control.name] = null; + this.views.splice(index, 1); + this.viewNames[control.name] = null; - for (i = index, l = this.panels.length; i < l; i++) { - this.panelNames[this.panels[i].name] = i; + for (i = index, l = this.views.length; i < l; i++) { + this.viewNames[this.views[i].name] = i; } } }, /** - * Renders the initially active panel + * Renders the initially active view * * @private */ - initFirstPanel: function () { - var name, panel, + initFirstView: function () { + var name, view, i = 0; - if (this.panels.length === 0) return; + if (this.views.length === 0) return; - // find the first declared active panel - while ((panel = this.panels[i++]) && !name) { - if (panel.active) { - name = panel.name; + // find the first declared active view + while ((view = this.views[i++]) && !name) { + if (view.active) { + name = view.name; } } - name = name || this.panels[0].name; + name = name || this.views[0].name; if (this.generated) { this.activate(name); } else { - panel = this.getPanel(name); - this._activate(panel); + view = this.getView(name); + this._activate(view); } }, /** - * Adds the list of components as panels + * Adds the list of components as views * * @param {Object[]|enyo.Control[]} components List of components * @param {enyo.Control|null} [owner] Owner of components * * @private */ - importPanelConfig: function (components, owner) { + importViewConfig: function (components, owner, isManager) { var c, i = 0; while (components && (c = components[i++])) { - this.addPanel(c, owner); + this.addView(c, owner, isManager); } }, /** - * Adds a new panel to the panel set + * Adds a new view to the view set * - * @param {Object|enyo.Control} panel Panel config or instance - * @param {enyo.Control|null} [owner] Optional owner of panel. Defaults to this. + * @param {Object|enyo.Control} view View config or instance + * @param {enyo.Control|null} [owner] Optional owner of view. Defaults to this. * * @private */ - addPanel: function (panel, owner) { - var isControl = panel instanceof Control, - _panel = isControl ? panel : utils.clone(panel), - index = this.panels.push(_panel), - name = _panel.name || 'panel' + index; - owner = _panel.owner || owner || this; + addView: function (view, owner, isManager) { + var index, name, + isControl = view instanceof Control, + _view = isControl ? view : utils.clone(view); + owner = _view.owner || owner || this; if (isControl) { - _panel.set('owner', owner); - _panel.set('name', name); - - if (_panel instanceof ViewMgr) { - _panel.set('manager', this.manager || this); + _view.set('owner', owner); + if (_view instanceof ViewMgr) { + _view.isManager = true; + _view.set('manager', this.manager || this); } } else { - _panel.owner = owner; - _panel.name = name; + _view.owner = owner; + if (isManager || _view.isManager) { + if (!_view.name) { + _view.name = 'viewManager' + (Object.keys(this.viewManagers).length + 1); + } + _view.isManager = true; + _view.manager = this.manager || this; + } } - this.panelNames[name] = index - 1; + if (_view.isManager) { + this.viewManagers[_view.name] = _view; + } else { + index = this.views.push(_view), + name = _view.name || (_view.name = 'view' + index); + this.viewNames[name] = index - 1; + } }, /** * @public */ - getPanel: function (panelName) { - var index = this.panelNames[panelName], - p = this.panels[index]; - - // not created yet - if (p && !(p instanceof Control)) { - p = this.panels[index] = this.createComponent(p); + getView: function (viewName) { + var view = this.viewManagers[viewName], + index = this.viewNames[viewName]; + + // if it's a manager + if (view) { + // but not created, create it + if (!(view instanceof ViewMgr)) { + view = this.viewManagers[viewName] = this.createComponent(view); + } + } + // otherwise, it's probably a view + else { + view = this.views[index]; + // but it might need to be created too + if (view && !(view instanceof Control)) { + view = this.views[index] = this.createComponent(view); + } } - return p; + return view; }, /** - * @public - */ + * @public + */ next: function () { - var index = this.panels.indexOf(this.active) + 1, - panel = this.panels[index]; - if (panel) { - return this.activate(panel.name); + var index = this.views.indexOf(this.active) + 1, + view = this.views[index]; + if (view) { + return this.activate(view.name); } }, /** - * @public - */ + * @public + */ previous: function () { - var index = this.panels.indexOf(this.active) - 1, - panel = this.panels[index]; - if (panel) { - return this.activate(panel.name); + var index = this.views.indexOf(this.active) - 1, + view = this.views[index]; + if (view) { + return this.activate(view.name); } }, @@ -244,6 +269,9 @@ var ViewMgr = kind({ } }, + /** + * @private + */ canDrag: function (direction) { var index; if (this.draggable) { @@ -251,9 +279,9 @@ var ViewMgr = kind({ return true; } else if (this.type == 'fixed') { - index = this.panels.indexOf(this.active); + index = this.views.indexOf(this.active); return (index > 0 && direction == -1) || - (index < this.panels.length - 1 && direction == 1); + (index < this.views.length - 1 && direction == 1); } } @@ -261,12 +289,13 @@ var ViewMgr = kind({ }, /** - * Dismisses a floating view manager - * - * @public - */ + * Dismisses a view manager. If this is a root (manager-less) view manager, it cannot be + * dismissed. + * + * @public + */ dismiss: function () { - if (this.type == 'floating') { + if (this.manager) { this.set('active', null); this.set('dismissed', true); this.emit('dismiss'); @@ -274,51 +303,45 @@ var ViewMgr = kind({ }, /** - * Since handler for events emitted from descendant view managers - * - * @param {[type]} viewManager [description] - * @param {[type]} event [description] - * @param {[type]} panel [description] - * - * @return {[type]} [description] - */ - managerEvent: function (viewManager, event, panel) { + * @private + */ + managerEvent: function (viewManager, event, view) { if (event == 'dismiss') this.managerDismissing(viewManager); else if (event == 'dismissed') this.managerDismissed(viewManager); - else if (event == 'activated') this.managerActivated(viewManager, panel); - else if (event == 'deactivated') this.managerDeactivated(viewManager, panel); + else if (event == 'activated') this.managerActivated(viewManager, view); + else if (event == 'deactivated') this.managerDeactivated(viewManager, view); }, /** - * Handles dismissal of child view managers - * - * @private - */ + * Handles dismissal of child view managers + * + * @private + */ managerDismissed: function (viewManager) { this.log(this.id, 'ViewMgr', viewManager.name, 'dismissed'); - viewManager.destroy(); + this.teardownView(viewManager); }, managerDismissing: function (viewManager) { this.log(this.id, 'ViewMgr', viewManager.name, 'dismissing'); }, - managerActivated: function (viewManager, panel) { - this.log(this.id, 'activated', panel.name); + managerActivated: function (viewManager, view) { + this.log(this.id, 'activated', view.name); }, - managerDeactivated: function (viewManager, panel) { - this.log(this.id, 'deactivated', panel.name); + managerDeactivated: function (viewManager, view) { + this.log(this.id, 'deactivated', view.name); }, /** * @private */ - activate: function (panelName) { - var p = this.getPanel(panelName); + activate: function (viewName) { + var p = this.getView(viewName); if (p) { - if (this.type == 'floating' && this.stack[this.stack.length - 1] !== panelName) { - this.stack.push(panelName); + if (this.type == 'floating' && this.stack[this.stack.length - 1] !== viewName) { + this.stack.push(viewName); } rAF(this._activate.bind(this, p)); } @@ -328,44 +351,67 @@ var ViewMgr = kind({ /** * @private */ - _activate: function (panel) { - // render the activated panel - if (this.generated) panel.render(); - if (!this.dragging) { - this.set('active', panel); - this.emit('activated', panel); + _activate: function (view) { + // render the activated view + if (this.generated) { + view.set('canGenerate', true); + view.render(); + } + if (!this.dragging && !view.isManager) { + this.set('active', view); + this.emit('activated', view); } }, /** * @private */ - deactivate: function (panelName) { - var p = this.getPanel(panelName); + deactivate: function (viewName) { + var p = this.getView(viewName); if (p) rAF(this._deactivate.bind(this, p)); }, /** * @private */ - _deactivate: function (panel) { - if (panel.node && !panel.persistent) { - panel.node.remove(); - panel.teardownRender(true); - } + _deactivate: function (view) { + this.teardownView(view); if (!this.dragging) { - this.emit('deactivated', panel); - if (this.dismissed && this.manager) this.emit('dismissed'); + if (!view.isManager) this.emit('deactivated', view); + if (this.dismissed) this.emit('dismissed'); + } + }, + + /** + * Tears down a view or ViewManager if not flagged `persistent` + * + * @private + */ + teardownView: function (view) { + if (view.node && !view.persistent) { + view.node.remove(); + view.set('canGenerate', false); + view.teardownRender(true); } }, // Draggable + /** + * Handles `ondown` events + * + * @private + */ handleDown: function (sender, event) { event.configureHoldPulse({endHold: 'onMove'}); }, + /** + * Handles `ondragstart` events + * + * @private + */ handleDragStart: function (sender, event) { if (!this.draggable) return; this.set('dragging', true); @@ -375,6 +421,11 @@ var ViewMgr = kind({ return true; }, + /** + * Handles `ondrag` events + * + * @private + */ handleDrag: function (sender, event) { if (!this.draggable) return; @@ -399,18 +450,28 @@ var ViewMgr = kind({ return true; }, + /** + * Handles `ondragfinish` events + * + * @private + */ handleDragFinish: function (sender, event) { if (!this.draggable) return; this.decorateDragEvent(event); + // if the view has been dragged far enough if (event.percentDelta * 100 > this.dragSnapPercent) { + // normally, there will be a becoming-active view to activate if (this.dragView) { this.activate(this.dragView.name); this.dragView = null; } + // unless it's a floating ViewManager that is being dismissed else if (this.type == 'floating' && event.direction == -1) { this.dismiss(); } - } else { + } + // otherwise the drag was small enough to be cancelled + else { this.emit('cancelDrag', event); this.dragView = null; } @@ -419,6 +480,12 @@ var ViewMgr = kind({ return true; }, + /** + * Calculates and adds a few additional properties to the event to aid in logic in ViewManager + * and ViewLayout + * + * @private + */ decorateDragEvent: function (event) { var isHorizontal = this.orientation == 'horizontal', size = isHorizontal ? this.dragBounds.width : this.dragBounds.height; From 59e1adf95b9a7fedf4cb0cdee87a37e3a702bab6 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Wed, 23 Sep 2015 16:54:03 -0500 Subject: [PATCH 008/210] Revert "add support for declarative sub-ViewManager configuration" This reverts commit d067d664e40d46f4943c4fdb49c8e850f614b3b1. --- src/SlideViewLayout/SlideViewLayout.js | 4 +- src/TransitionViewLayout.js | 2 +- src/ViewLayout/ViewLayout.js | 14 +- src/ViewManager/ViewManager.js | 299 ++++++++++--------------- 4 files changed, 126 insertions(+), 193 deletions(-) diff --git a/src/SlideViewLayout/SlideViewLayout.js b/src/SlideViewLayout/SlideViewLayout.js index bd1ac590c..3913f795f 100644 --- a/src/SlideViewLayout/SlideViewLayout.js +++ b/src/SlideViewLayout/SlideViewLayout.js @@ -59,8 +59,8 @@ module.exports = kind({ */ prepareTransition: function (was, is) { var c = this.container, - wasIndex = was ? c.views.indexOf(was) : -1, - isIndex = is ? c.views.indexOf(is) : -1; + wasIndex = was ? c.panels.indexOf(was) : -1, + isIndex = is ? c.panels.indexOf(is) : -1; this.direction = wasIndex < isIndex ? 'forward' : 'back'; if (is) is.addClass(this.direction); diff --git a/src/TransitionViewLayout.js b/src/TransitionViewLayout.js index 6d8ab3c13..fc487913c 100644 --- a/src/TransitionViewLayout.js +++ b/src/TransitionViewLayout.js @@ -67,7 +67,7 @@ module.exports = kind({ }, /** - * Removes the directional CSS class from the deactivating view + * Removes the directional CSS class from the deactivating panel * * @private */ diff --git a/src/ViewLayout/ViewLayout.js b/src/ViewLayout/ViewLayout.js index ee81fe2dd..fc4aaf67a 100644 --- a/src/ViewLayout/ViewLayout.js +++ b/src/ViewLayout/ViewLayout.js @@ -106,9 +106,9 @@ module.exports = kind({ is.addClass('active'); } }, - completeTransition: function (view) { - view.removeClass('transitioning'); - if (view !== this.container.active) this.container.deactivate(view.name); + completeTransition: function (panel) { + panel.removeClass('transitioning'); + if (panel !== this.container.active) this.container.deactivate(panel.name); }, shouldAnimate: function () { @@ -131,13 +131,13 @@ module.exports = kind({ }, handleTransitioned: function (sender, event) { - var view = event.originator; - if (view && view.container == this.container) { + var panel = event.originator; + if (panel && panel.container == this.container) { if (this.shouldAnimate()) { - rAF(this.completeTransition.bind(this, view)); + rAF(this.completeTransition.bind(this, panel)); } else { - this.completeTransition(view); + this.completeTransition(panel); } return true; diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index a0354a9d6..426b19164 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -76,184 +76,159 @@ var ViewMgr = kind({ create: function () { Control.prototype.create.apply(this, arguments); this.managerEvent = this.managerEvent.bind(this); - this.managerChanged(null, this.manager); - if (this.type == 'fixed') this.initFirstView(); + if (this.type == 'fixed') this.initFirstPanel(); else if (this.type == 'floating') this.stack = []; }, rendered: function () { Control.prototype.rendered.apply(this, arguments); - if (this.type == 'floating') this.initFirstView(); - this.set('dismissed', false); + if (this.type == 'floating') this.initFirstPanel(); }, initComponents: function () { - var managersOwner = Object.hasOwnProperty('managers') ? this.getInstanceOwner() : this; + // panel configs or instance + this.panels = []; - // view configs or instances - this.views = []; - this.viewManagers = {}; + // map of panel name to index + this.panelNames = {}; - // map of view name to index - this.viewNames = {}; - - // import kind and user components into this.views - this.importViewConfig(this.kindComponents, this); - this.importViewConfig(this.components, this.getInstanceOwner()); - this.importViewConfig(this.managers, managersOwner, true); + // import kind and user components into this.panels + this.importPanelConfig(this.kindComponents, this); + this.importPanelConfig(this.components, this.getInstanceOwner()); // clean up references this.components = this.kindComponents = null; }, addControl: function (control, before) { + var index; Control.prototype.addControl.apply(this, arguments); - if (!this.viewNames[control.name]) { - this.addView(control); + index = this.panelNames[control.name]; + if (!index && index !== 0) { + this.addPanel(control); } }, removeControl: function (control) { var i, l, - index = this.views.indexOf(control); + index = this.panels.indexOf(control); if (index >= 0) { - this.views.splice(index, 1); - this.viewNames[control.name] = null; + this.panels.splice(index, 1); + this.panelNames[control.name] = null; - for (i = index, l = this.views.length; i < l; i++) { - this.viewNames[this.views[i].name] = i; + for (i = index, l = this.panels.length; i < l; i++) { + this.panelNames[this.panels[i].name] = i; } } }, /** - * Renders the initially active view + * Renders the initially active panel * * @private */ - initFirstView: function () { - var name, view, + initFirstPanel: function () { + var name, panel, i = 0; - if (this.views.length === 0) return; + if (this.panels.length === 0) return; - // find the first declared active view - while ((view = this.views[i++]) && !name) { - if (view.active) { - name = view.name; + // find the first declared active panel + while ((panel = this.panels[i++]) && !name) { + if (panel.active) { + name = panel.name; } } - name = name || this.views[0].name; + name = name || this.panels[0].name; if (this.generated) { this.activate(name); } else { - view = this.getView(name); - this._activate(view); + panel = this.getPanel(name); + this._activate(panel); } }, /** - * Adds the list of components as views + * Adds the list of components as panels * * @param {Object[]|enyo.Control[]} components List of components * @param {enyo.Control|null} [owner] Owner of components * * @private */ - importViewConfig: function (components, owner, isManager) { + importPanelConfig: function (components, owner) { var c, i = 0; while (components && (c = components[i++])) { - this.addView(c, owner, isManager); + this.addPanel(c, owner); } }, /** - * Adds a new view to the view set + * Adds a new panel to the panel set * - * @param {Object|enyo.Control} view View config or instance - * @param {enyo.Control|null} [owner] Optional owner of view. Defaults to this. + * @param {Object|enyo.Control} panel Panel config or instance + * @param {enyo.Control|null} [owner] Optional owner of panel. Defaults to this. * * @private */ - addView: function (view, owner, isManager) { - var index, name, - isControl = view instanceof Control, - _view = isControl ? view : utils.clone(view); + addPanel: function (panel, owner) { + var isControl = panel instanceof Control, + _panel = isControl ? panel : utils.clone(panel), + index = this.panels.push(_panel), + name = _panel.name || 'panel' + index; + owner = _panel.owner || owner || this; - owner = _view.owner || owner || this; if (isControl) { - _view.set('owner', owner); - if (_view instanceof ViewMgr) { - _view.isManager = true; - _view.set('manager', this.manager || this); + _panel.set('owner', owner); + _panel.set('name', name); + + if (_panel instanceof ViewMgr) { + _panel.set('manager', this.manager || this); } } else { - _view.owner = owner; - if (isManager || _view.isManager) { - if (!_view.name) { - _view.name = 'viewManager' + (Object.keys(this.viewManagers).length + 1); - } - _view.isManager = true; - _view.manager = this.manager || this; - } + _panel.owner = owner; + _panel.name = name; } - if (_view.isManager) { - this.viewManagers[_view.name] = _view; - } else { - index = this.views.push(_view), - name = _view.name || (_view.name = 'view' + index); - this.viewNames[name] = index - 1; - } + this.panelNames[name] = index - 1; }, /** * @public */ - getView: function (viewName) { - var view = this.viewManagers[viewName], - index = this.viewNames[viewName]; - - // if it's a manager - if (view) { - // but not created, create it - if (!(view instanceof ViewMgr)) { - view = this.viewManagers[viewName] = this.createComponent(view); - } - } - // otherwise, it's probably a view - else { - view = this.views[index]; - // but it might need to be created too - if (view && !(view instanceof Control)) { - view = this.views[index] = this.createComponent(view); - } + getPanel: function (panelName) { + var index = this.panelNames[panelName], + p = this.panels[index]; + + // not created yet + if (p && !(p instanceof Control)) { + p = this.panels[index] = this.createComponent(p); } - return view; + return p; }, /** - * @public - */ + * @public + */ next: function () { - var index = this.views.indexOf(this.active) + 1, - view = this.views[index]; - if (view) { - return this.activate(view.name); + var index = this.panels.indexOf(this.active) + 1, + panel = this.panels[index]; + if (panel) { + return this.activate(panel.name); } }, /** - * @public - */ + * @public + */ previous: function () { - var index = this.views.indexOf(this.active) - 1, - view = this.views[index]; - if (view) { - return this.activate(view.name); + var index = this.panels.indexOf(this.active) - 1, + panel = this.panels[index]; + if (panel) { + return this.activate(panel.name); } }, @@ -269,9 +244,6 @@ var ViewMgr = kind({ } }, - /** - * @private - */ canDrag: function (direction) { var index; if (this.draggable) { @@ -279,9 +251,9 @@ var ViewMgr = kind({ return true; } else if (this.type == 'fixed') { - index = this.views.indexOf(this.active); + index = this.panels.indexOf(this.active); return (index > 0 && direction == -1) || - (index < this.views.length - 1 && direction == 1); + (index < this.panels.length - 1 && direction == 1); } } @@ -289,13 +261,12 @@ var ViewMgr = kind({ }, /** - * Dismisses a view manager. If this is a root (manager-less) view manager, it cannot be - * dismissed. - * - * @public - */ + * Dismisses a floating view manager + * + * @public + */ dismiss: function () { - if (this.manager) { + if (this.type == 'floating') { this.set('active', null); this.set('dismissed', true); this.emit('dismiss'); @@ -303,45 +274,51 @@ var ViewMgr = kind({ }, /** - * @private - */ - managerEvent: function (viewManager, event, view) { + * Since handler for events emitted from descendant view managers + * + * @param {[type]} viewManager [description] + * @param {[type]} event [description] + * @param {[type]} panel [description] + * + * @return {[type]} [description] + */ + managerEvent: function (viewManager, event, panel) { if (event == 'dismiss') this.managerDismissing(viewManager); else if (event == 'dismissed') this.managerDismissed(viewManager); - else if (event == 'activated') this.managerActivated(viewManager, view); - else if (event == 'deactivated') this.managerDeactivated(viewManager, view); + else if (event == 'activated') this.managerActivated(viewManager, panel); + else if (event == 'deactivated') this.managerDeactivated(viewManager, panel); }, /** - * Handles dismissal of child view managers - * - * @private - */ + * Handles dismissal of child view managers + * + * @private + */ managerDismissed: function (viewManager) { this.log(this.id, 'ViewMgr', viewManager.name, 'dismissed'); - this.teardownView(viewManager); + viewManager.destroy(); }, managerDismissing: function (viewManager) { this.log(this.id, 'ViewMgr', viewManager.name, 'dismissing'); }, - managerActivated: function (viewManager, view) { - this.log(this.id, 'activated', view.name); + managerActivated: function (viewManager, panel) { + this.log(this.id, 'activated', panel.name); }, - managerDeactivated: function (viewManager, view) { - this.log(this.id, 'deactivated', view.name); + managerDeactivated: function (viewManager, panel) { + this.log(this.id, 'deactivated', panel.name); }, /** * @private */ - activate: function (viewName) { - var p = this.getView(viewName); + activate: function (panelName) { + var p = this.getPanel(panelName); if (p) { - if (this.type == 'floating' && this.stack[this.stack.length - 1] !== viewName) { - this.stack.push(viewName); + if (this.type == 'floating' && this.stack[this.stack.length - 1] !== panelName) { + this.stack.push(panelName); } rAF(this._activate.bind(this, p)); } @@ -351,67 +328,44 @@ var ViewMgr = kind({ /** * @private */ - _activate: function (view) { - // render the activated view - if (this.generated) { - view.set('canGenerate', true); - view.render(); - } - if (!this.dragging && !view.isManager) { - this.set('active', view); - this.emit('activated', view); + _activate: function (panel) { + // render the activated panel + if (this.generated) panel.render(); + if (!this.dragging) { + this.set('active', panel); + this.emit('activated', panel); } }, /** * @private */ - deactivate: function (viewName) { - var p = this.getView(viewName); + deactivate: function (panelName) { + var p = this.getPanel(panelName); if (p) rAF(this._deactivate.bind(this, p)); }, /** * @private */ - _deactivate: function (view) { - this.teardownView(view); - - if (!this.dragging) { - if (!view.isManager) this.emit('deactivated', view); - if (this.dismissed) this.emit('dismissed'); + _deactivate: function (panel) { + if (panel.node && !panel.persistent) { + panel.node.remove(); + panel.teardownRender(true); } - }, - /** - * Tears down a view or ViewManager if not flagged `persistent` - * - * @private - */ - teardownView: function (view) { - if (view.node && !view.persistent) { - view.node.remove(); - view.set('canGenerate', false); - view.teardownRender(true); + if (!this.dragging) { + this.emit('deactivated', panel); + if (this.dismissed && this.manager) this.emit('dismissed'); } }, // Draggable - /** - * Handles `ondown` events - * - * @private - */ handleDown: function (sender, event) { event.configureHoldPulse({endHold: 'onMove'}); }, - /** - * Handles `ondragstart` events - * - * @private - */ handleDragStart: function (sender, event) { if (!this.draggable) return; this.set('dragging', true); @@ -421,11 +375,6 @@ var ViewMgr = kind({ return true; }, - /** - * Handles `ondrag` events - * - * @private - */ handleDrag: function (sender, event) { if (!this.draggable) return; @@ -450,28 +399,18 @@ var ViewMgr = kind({ return true; }, - /** - * Handles `ondragfinish` events - * - * @private - */ handleDragFinish: function (sender, event) { if (!this.draggable) return; this.decorateDragEvent(event); - // if the view has been dragged far enough if (event.percentDelta * 100 > this.dragSnapPercent) { - // normally, there will be a becoming-active view to activate if (this.dragView) { this.activate(this.dragView.name); this.dragView = null; } - // unless it's a floating ViewManager that is being dismissed else if (this.type == 'floating' && event.direction == -1) { this.dismiss(); } - } - // otherwise the drag was small enough to be cancelled - else { + } else { this.emit('cancelDrag', event); this.dragView = null; } @@ -480,12 +419,6 @@ var ViewMgr = kind({ return true; }, - /** - * Calculates and adds a few additional properties to the event to aid in logic in ViewManager - * and ViewLayout - * - * @private - */ decorateDragEvent: function (event) { var isHorizontal = this.orientation == 'horizontal', size = isHorizontal ? this.dragBounds.width : this.dragBounds.height; From 3224dbba6f79f3d88da9619dbe772fb14b98b572 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Wed, 23 Sep 2015 16:44:28 -0500 Subject: [PATCH 009/210] add support for declarative sub-ViewManager configuration Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/SlideViewLayout/SlideViewLayout.js | 4 +- src/TransitionViewLayout.js | 2 +- src/ViewLayout/ViewLayout.js | 14 +- src/ViewManager/ViewManager.js | 299 +++++++++++++++---------- 4 files changed, 193 insertions(+), 126 deletions(-) diff --git a/src/SlideViewLayout/SlideViewLayout.js b/src/SlideViewLayout/SlideViewLayout.js index 3913f795f..bd1ac590c 100644 --- a/src/SlideViewLayout/SlideViewLayout.js +++ b/src/SlideViewLayout/SlideViewLayout.js @@ -59,8 +59,8 @@ module.exports = kind({ */ prepareTransition: function (was, is) { var c = this.container, - wasIndex = was ? c.panels.indexOf(was) : -1, - isIndex = is ? c.panels.indexOf(is) : -1; + wasIndex = was ? c.views.indexOf(was) : -1, + isIndex = is ? c.views.indexOf(is) : -1; this.direction = wasIndex < isIndex ? 'forward' : 'back'; if (is) is.addClass(this.direction); diff --git a/src/TransitionViewLayout.js b/src/TransitionViewLayout.js index fc487913c..6d8ab3c13 100644 --- a/src/TransitionViewLayout.js +++ b/src/TransitionViewLayout.js @@ -67,7 +67,7 @@ module.exports = kind({ }, /** - * Removes the directional CSS class from the deactivating panel + * Removes the directional CSS class from the deactivating view * * @private */ diff --git a/src/ViewLayout/ViewLayout.js b/src/ViewLayout/ViewLayout.js index fc4aaf67a..ee81fe2dd 100644 --- a/src/ViewLayout/ViewLayout.js +++ b/src/ViewLayout/ViewLayout.js @@ -106,9 +106,9 @@ module.exports = kind({ is.addClass('active'); } }, - completeTransition: function (panel) { - panel.removeClass('transitioning'); - if (panel !== this.container.active) this.container.deactivate(panel.name); + completeTransition: function (view) { + view.removeClass('transitioning'); + if (view !== this.container.active) this.container.deactivate(view.name); }, shouldAnimate: function () { @@ -131,13 +131,13 @@ module.exports = kind({ }, handleTransitioned: function (sender, event) { - var panel = event.originator; - if (panel && panel.container == this.container) { + var view = event.originator; + if (view && view.container == this.container) { if (this.shouldAnimate()) { - rAF(this.completeTransition.bind(this, panel)); + rAF(this.completeTransition.bind(this, view)); } else { - this.completeTransition(panel); + this.completeTransition(view); } return true; diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 426b19164..a0354a9d6 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -76,159 +76,184 @@ var ViewMgr = kind({ create: function () { Control.prototype.create.apply(this, arguments); this.managerEvent = this.managerEvent.bind(this); + this.managerChanged(null, this.manager); - if (this.type == 'fixed') this.initFirstPanel(); + if (this.type == 'fixed') this.initFirstView(); else if (this.type == 'floating') this.stack = []; }, rendered: function () { Control.prototype.rendered.apply(this, arguments); - if (this.type == 'floating') this.initFirstPanel(); + if (this.type == 'floating') this.initFirstView(); + this.set('dismissed', false); }, initComponents: function () { - // panel configs or instance - this.panels = []; + var managersOwner = Object.hasOwnProperty('managers') ? this.getInstanceOwner() : this; - // map of panel name to index - this.panelNames = {}; + // view configs or instances + this.views = []; + this.viewManagers = {}; - // import kind and user components into this.panels - this.importPanelConfig(this.kindComponents, this); - this.importPanelConfig(this.components, this.getInstanceOwner()); + // map of view name to index + this.viewNames = {}; + + // import kind and user components into this.views + this.importViewConfig(this.kindComponents, this); + this.importViewConfig(this.components, this.getInstanceOwner()); + this.importViewConfig(this.managers, managersOwner, true); // clean up references this.components = this.kindComponents = null; }, addControl: function (control, before) { - var index; Control.prototype.addControl.apply(this, arguments); - index = this.panelNames[control.name]; - if (!index && index !== 0) { - this.addPanel(control); + if (!this.viewNames[control.name]) { + this.addView(control); } }, removeControl: function (control) { var i, l, - index = this.panels.indexOf(control); + index = this.views.indexOf(control); if (index >= 0) { - this.panels.splice(index, 1); - this.panelNames[control.name] = null; + this.views.splice(index, 1); + this.viewNames[control.name] = null; - for (i = index, l = this.panels.length; i < l; i++) { - this.panelNames[this.panels[i].name] = i; + for (i = index, l = this.views.length; i < l; i++) { + this.viewNames[this.views[i].name] = i; } } }, /** - * Renders the initially active panel + * Renders the initially active view * * @private */ - initFirstPanel: function () { - var name, panel, + initFirstView: function () { + var name, view, i = 0; - if (this.panels.length === 0) return; + if (this.views.length === 0) return; - // find the first declared active panel - while ((panel = this.panels[i++]) && !name) { - if (panel.active) { - name = panel.name; + // find the first declared active view + while ((view = this.views[i++]) && !name) { + if (view.active) { + name = view.name; } } - name = name || this.panels[0].name; + name = name || this.views[0].name; if (this.generated) { this.activate(name); } else { - panel = this.getPanel(name); - this._activate(panel); + view = this.getView(name); + this._activate(view); } }, /** - * Adds the list of components as panels + * Adds the list of components as views * * @param {Object[]|enyo.Control[]} components List of components * @param {enyo.Control|null} [owner] Owner of components * * @private */ - importPanelConfig: function (components, owner) { + importViewConfig: function (components, owner, isManager) { var c, i = 0; while (components && (c = components[i++])) { - this.addPanel(c, owner); + this.addView(c, owner, isManager); } }, /** - * Adds a new panel to the panel set + * Adds a new view to the view set * - * @param {Object|enyo.Control} panel Panel config or instance - * @param {enyo.Control|null} [owner] Optional owner of panel. Defaults to this. + * @param {Object|enyo.Control} view View config or instance + * @param {enyo.Control|null} [owner] Optional owner of view. Defaults to this. * * @private */ - addPanel: function (panel, owner) { - var isControl = panel instanceof Control, - _panel = isControl ? panel : utils.clone(panel), - index = this.panels.push(_panel), - name = _panel.name || 'panel' + index; - owner = _panel.owner || owner || this; + addView: function (view, owner, isManager) { + var index, name, + isControl = view instanceof Control, + _view = isControl ? view : utils.clone(view); + owner = _view.owner || owner || this; if (isControl) { - _panel.set('owner', owner); - _panel.set('name', name); - - if (_panel instanceof ViewMgr) { - _panel.set('manager', this.manager || this); + _view.set('owner', owner); + if (_view instanceof ViewMgr) { + _view.isManager = true; + _view.set('manager', this.manager || this); } } else { - _panel.owner = owner; - _panel.name = name; + _view.owner = owner; + if (isManager || _view.isManager) { + if (!_view.name) { + _view.name = 'viewManager' + (Object.keys(this.viewManagers).length + 1); + } + _view.isManager = true; + _view.manager = this.manager || this; + } } - this.panelNames[name] = index - 1; + if (_view.isManager) { + this.viewManagers[_view.name] = _view; + } else { + index = this.views.push(_view), + name = _view.name || (_view.name = 'view' + index); + this.viewNames[name] = index - 1; + } }, /** * @public */ - getPanel: function (panelName) { - var index = this.panelNames[panelName], - p = this.panels[index]; - - // not created yet - if (p && !(p instanceof Control)) { - p = this.panels[index] = this.createComponent(p); + getView: function (viewName) { + var view = this.viewManagers[viewName], + index = this.viewNames[viewName]; + + // if it's a manager + if (view) { + // but not created, create it + if (!(view instanceof ViewMgr)) { + view = this.viewManagers[viewName] = this.createComponent(view); + } + } + // otherwise, it's probably a view + else { + view = this.views[index]; + // but it might need to be created too + if (view && !(view instanceof Control)) { + view = this.views[index] = this.createComponent(view); + } } - return p; + return view; }, /** - * @public - */ + * @public + */ next: function () { - var index = this.panels.indexOf(this.active) + 1, - panel = this.panels[index]; - if (panel) { - return this.activate(panel.name); + var index = this.views.indexOf(this.active) + 1, + view = this.views[index]; + if (view) { + return this.activate(view.name); } }, /** - * @public - */ + * @public + */ previous: function () { - var index = this.panels.indexOf(this.active) - 1, - panel = this.panels[index]; - if (panel) { - return this.activate(panel.name); + var index = this.views.indexOf(this.active) - 1, + view = this.views[index]; + if (view) { + return this.activate(view.name); } }, @@ -244,6 +269,9 @@ var ViewMgr = kind({ } }, + /** + * @private + */ canDrag: function (direction) { var index; if (this.draggable) { @@ -251,9 +279,9 @@ var ViewMgr = kind({ return true; } else if (this.type == 'fixed') { - index = this.panels.indexOf(this.active); + index = this.views.indexOf(this.active); return (index > 0 && direction == -1) || - (index < this.panels.length - 1 && direction == 1); + (index < this.views.length - 1 && direction == 1); } } @@ -261,12 +289,13 @@ var ViewMgr = kind({ }, /** - * Dismisses a floating view manager - * - * @public - */ + * Dismisses a view manager. If this is a root (manager-less) view manager, it cannot be + * dismissed. + * + * @public + */ dismiss: function () { - if (this.type == 'floating') { + if (this.manager) { this.set('active', null); this.set('dismissed', true); this.emit('dismiss'); @@ -274,51 +303,45 @@ var ViewMgr = kind({ }, /** - * Since handler for events emitted from descendant view managers - * - * @param {[type]} viewManager [description] - * @param {[type]} event [description] - * @param {[type]} panel [description] - * - * @return {[type]} [description] - */ - managerEvent: function (viewManager, event, panel) { + * @private + */ + managerEvent: function (viewManager, event, view) { if (event == 'dismiss') this.managerDismissing(viewManager); else if (event == 'dismissed') this.managerDismissed(viewManager); - else if (event == 'activated') this.managerActivated(viewManager, panel); - else if (event == 'deactivated') this.managerDeactivated(viewManager, panel); + else if (event == 'activated') this.managerActivated(viewManager, view); + else if (event == 'deactivated') this.managerDeactivated(viewManager, view); }, /** - * Handles dismissal of child view managers - * - * @private - */ + * Handles dismissal of child view managers + * + * @private + */ managerDismissed: function (viewManager) { this.log(this.id, 'ViewMgr', viewManager.name, 'dismissed'); - viewManager.destroy(); + this.teardownView(viewManager); }, managerDismissing: function (viewManager) { this.log(this.id, 'ViewMgr', viewManager.name, 'dismissing'); }, - managerActivated: function (viewManager, panel) { - this.log(this.id, 'activated', panel.name); + managerActivated: function (viewManager, view) { + this.log(this.id, 'activated', view.name); }, - managerDeactivated: function (viewManager, panel) { - this.log(this.id, 'deactivated', panel.name); + managerDeactivated: function (viewManager, view) { + this.log(this.id, 'deactivated', view.name); }, /** * @private */ - activate: function (panelName) { - var p = this.getPanel(panelName); + activate: function (viewName) { + var p = this.getView(viewName); if (p) { - if (this.type == 'floating' && this.stack[this.stack.length - 1] !== panelName) { - this.stack.push(panelName); + if (this.type == 'floating' && this.stack[this.stack.length - 1] !== viewName) { + this.stack.push(viewName); } rAF(this._activate.bind(this, p)); } @@ -328,44 +351,67 @@ var ViewMgr = kind({ /** * @private */ - _activate: function (panel) { - // render the activated panel - if (this.generated) panel.render(); - if (!this.dragging) { - this.set('active', panel); - this.emit('activated', panel); + _activate: function (view) { + // render the activated view + if (this.generated) { + view.set('canGenerate', true); + view.render(); + } + if (!this.dragging && !view.isManager) { + this.set('active', view); + this.emit('activated', view); } }, /** * @private */ - deactivate: function (panelName) { - var p = this.getPanel(panelName); + deactivate: function (viewName) { + var p = this.getView(viewName); if (p) rAF(this._deactivate.bind(this, p)); }, /** * @private */ - _deactivate: function (panel) { - if (panel.node && !panel.persistent) { - panel.node.remove(); - panel.teardownRender(true); - } + _deactivate: function (view) { + this.teardownView(view); if (!this.dragging) { - this.emit('deactivated', panel); - if (this.dismissed && this.manager) this.emit('dismissed'); + if (!view.isManager) this.emit('deactivated', view); + if (this.dismissed) this.emit('dismissed'); + } + }, + + /** + * Tears down a view or ViewManager if not flagged `persistent` + * + * @private + */ + teardownView: function (view) { + if (view.node && !view.persistent) { + view.node.remove(); + view.set('canGenerate', false); + view.teardownRender(true); } }, // Draggable + /** + * Handles `ondown` events + * + * @private + */ handleDown: function (sender, event) { event.configureHoldPulse({endHold: 'onMove'}); }, + /** + * Handles `ondragstart` events + * + * @private + */ handleDragStart: function (sender, event) { if (!this.draggable) return; this.set('dragging', true); @@ -375,6 +421,11 @@ var ViewMgr = kind({ return true; }, + /** + * Handles `ondrag` events + * + * @private + */ handleDrag: function (sender, event) { if (!this.draggable) return; @@ -399,18 +450,28 @@ var ViewMgr = kind({ return true; }, + /** + * Handles `ondragfinish` events + * + * @private + */ handleDragFinish: function (sender, event) { if (!this.draggable) return; this.decorateDragEvent(event); + // if the view has been dragged far enough if (event.percentDelta * 100 > this.dragSnapPercent) { + // normally, there will be a becoming-active view to activate if (this.dragView) { this.activate(this.dragView.name); this.dragView = null; } + // unless it's a floating ViewManager that is being dismissed else if (this.type == 'floating' && event.direction == -1) { this.dismiss(); } - } else { + } + // otherwise the drag was small enough to be cancelled + else { this.emit('cancelDrag', event); this.dragView = null; } @@ -419,6 +480,12 @@ var ViewMgr = kind({ return true; }, + /** + * Calculates and adds a few additional properties to the event to aid in logic in ViewManager + * and ViewLayout + * + * @private + */ decorateDragEvent: function (event) { var isHorizontal = this.orientation == 'horizontal', size = isHorizontal ? this.dragBounds.width : this.dragBounds.height; From 5144e3f820d92f8cd92dd878b29420bdb631295e Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Thu, 24 Sep 2015 16:43:49 -0500 Subject: [PATCH 010/210] add layoutCover support to SlideViewLayout Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/SlideViewLayout/SlideViewLayout.js | 27 ++++++++++++++++++------ src/SlideViewLayout/SlideViewLayout.less | 16 ++++++++++++++ src/ViewManager/ViewManager.js | 24 ++++++++++++++++----- 3 files changed, 55 insertions(+), 12 deletions(-) diff --git a/src/SlideViewLayout/SlideViewLayout.js b/src/SlideViewLayout/SlideViewLayout.js index bd1ac590c..9f36dcd06 100644 --- a/src/SlideViewLayout/SlideViewLayout.js +++ b/src/SlideViewLayout/SlideViewLayout.js @@ -34,21 +34,27 @@ module.exports = kind({ */ layoutClass: 'enyo-viewlayout enyo-viewlayout-slide', + constructor: function () { + TransitionViewLayout.prototype._constructor.apply(this, arguments); + if (this.container.layoutCover) this.container.addClass('cover'); + }, + /** * @private */ drag: function (event) { - var size, node, - c = this.container, + var c = this.container, + bounds = c.dragBounds, isHorizontal = c.orientation == 'horizontal', + size = isHorizontal ? bounds.width : bounds.height, + delta = event.delta < 0 ? Math.max(event.delta, -size) : Math.min(event.delta, size), transform = isHorizontal ? 'translateX' : 'translateY'; TransitionViewLayout.prototype.drag.apply(this, arguments); - c.active.applyStyle('transform', transform + '(' + event.delta + 'px)'); + c.active.applyStyle('transform', transform + '(' + delta + 'px)'); if (c.dragView) { - node = c.hasNode(); - size = isHorizontal ? node.clientWidth : node.clientHeight; - c.dragView.applyStyle('transform', transform + '(' + (size * event.direction + event.delta) + 'px)'); + px = this.container.layoutCover ? 0 : size * event.direction + delta; + c.dragView.applyStyle('transform', transform + '(' + px + 'px)'); } }, @@ -74,7 +80,14 @@ module.exports = kind({ */ transition: function (was, is) { TransitionViewLayout.prototype.transition.apply(this, arguments); - if (was) was.applyStyle('transform', null); + if (was) { + was.applyStyle('transform', null); + // when using layoutCover, `was` doesn't transition so the ontransitionend doesn't fire + // to account for that, set a timeout of the same duration to manually clean up. + if (this.container.layoutCover) { + setTimeout(this.completeTransition.bind(this, was), this.dragDuration || this.duration); + } + } if (is) { is.removeClass(this.direction); is.applyStyle('transform', null); diff --git a/src/SlideViewLayout/SlideViewLayout.less b/src/SlideViewLayout/SlideViewLayout.less index b8fb59389..180831210 100644 --- a/src/SlideViewLayout/SlideViewLayout.less +++ b/src/SlideViewLayout/SlideViewLayout.less @@ -22,4 +22,20 @@ &.back { transform: translateY(100%); } &.active { transform: translateY(0); } } + + &.cover { + > .enyo-view { + // the active view should always be on top + &.active { z-index: 5; } + // unless the becoming-active is transitioning in over it + &.forward { z-index: 10; } + // the becoming-inactive view doesn't move + &.back { transform: translateX(0px); } + } + + // promote any ViewLayout children to ensure they are above the active view + > .enyo-viewlayout { + z-index: 20; + } + } } \ No newline at end of file diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index a0354a9d6..61eb0b942 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -261,11 +261,19 @@ var ViewMgr = kind({ * @public */ back: function () { + var view = this.peek(); + if (view) this.stack.pop(); + return view; + }, + + /** + * @public + */ + peek: function () { var name; - if (this.type == 'floating') { - this.stack.pop(); - name = this.stack[this.stack.length - 1]; - this.activate(name); + if (this.type == 'floating' && this.stack.length > 1) { + name = this.stack[this.stack.length - 2]; + return this.activate(name); } }, @@ -442,7 +450,13 @@ var ViewMgr = kind({ // set up the new drag view if (!this.dragView) { - this.dragView = this.dragDirection == 1 ? this.next() : this.previous(); + if (this.dragDirection == 1) { + this.dragView = this.next(); + } else if (this.type == 'floating') { + this.dragView = this.peek(); + } else { + this.dragView = this.previous(); + } } this.emit('drag', event); } From 8aefabca5b91b029556dba9af5faed8b2d4d563b Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Fri, 25 Sep 2015 13:48:09 -0500 Subject: [PATCH 011/210] more handleTransitionEnd to TransitionViewLayout Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/TransitionViewLayout.js | 18 ++++++++++++++++++ src/ViewLayout/ViewLayout.js | 22 ++++------------------ 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/TransitionViewLayout.js b/src/TransitionViewLayout.js index 6d8ab3c13..5532b3a94 100644 --- a/src/TransitionViewLayout.js +++ b/src/TransitionViewLayout.js @@ -82,5 +82,23 @@ module.exports = kind({ applyTransitionDuration: function (view, duration) { view.applyStyle('-webkit-transition-duration', duration + 'ms'); view.applyStyle('transition-duration', duration + 'ms'); + }, + + handlers: { + ontransitionend: 'handleTransitioned' + }, + + handleTransitioned: function (sender, event) { + var view = event.originator; + if (view && view.container == this.container) { + + if (this.shouldAnimate()) { + rAF(this.completeTransition.bind(this, view)); + } else { + this.completeTransition(view); + } + + return true; + } } }); \ No newline at end of file diff --git a/src/ViewLayout/ViewLayout.js b/src/ViewLayout/ViewLayout.js index ee81fe2dd..7ac2f06ff 100644 --- a/src/ViewLayout/ViewLayout.js +++ b/src/ViewLayout/ViewLayout.js @@ -115,12 +115,11 @@ module.exports = kind({ return this.container.generated && this.container.animated; }, - handlers: { - ontransitionend: 'handleTransitioned' - }, - + /** + * @private + */ dispatchBubble: function (name, event, delegate) { - var handler = this.handlers[name]; + var handler = this.handlers && this.handlers[name]; if (handler) { if (this[handler](delegate, event)) { return true; @@ -130,17 +129,4 @@ module.exports = kind({ } }, - handleTransitioned: function (sender, event) { - var view = event.originator; - if (view && view.container == this.container) { - - if (this.shouldAnimate()) { - rAF(this.completeTransition.bind(this, view)); - } else { - this.completeTransition(view); - } - - return true; - } - } }); \ No newline at end of file From e8230b66e053de4d52ee71a7a4e088ce4830a0ab Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Fri, 25 Sep 2015 13:49:38 -0500 Subject: [PATCH 012/210] rework dragging class usage to wrap in rAF and avoid FOUC-ishness Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewLayout/ViewLayout.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ViewLayout/ViewLayout.js b/src/ViewLayout/ViewLayout.js index 7ac2f06ff..7ff3db820 100644 --- a/src/ViewLayout/ViewLayout.js +++ b/src/ViewLayout/ViewLayout.js @@ -72,8 +72,16 @@ module.exports = kind({ } }, + /** + * Adds the dragging class to the container when dragging starts. It is then removed in + * `transition()` to avoid a potential flash due to CSS changes in different frames. + * + * @private + */ draggingChanged: function (was, is) { - this.container.addRemoveClass('dragging', is); + rAF(function () { + if (is) this.container.addClass('dragging'); + }.bind(this)); }, handleCancelDrag: function (sender, name, event) { @@ -97,6 +105,7 @@ module.exports = kind({ prepareTransition: null, transition: function (was, is) { + this.container.removeClass('dragging'); if (was) { was.addClass('transitioning'); was.removeClass('active'); From a79f2b916de8a58545ac8369001417914708cdd4 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Fri, 25 Sep 2015 13:51:16 -0500 Subject: [PATCH 013/210] use enyo/animation for requestAnimationFrame polyfill Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/TransitionViewLayout.js | 4 +++- src/ViewLayout/ViewLayout.js | 6 +++--- src/ViewManager/ViewManager.js | 4 +++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/TransitionViewLayout.js b/src/TransitionViewLayout.js index 5532b3a94..a001e1385 100644 --- a/src/TransitionViewLayout.js +++ b/src/TransitionViewLayout.js @@ -1,5 +1,7 @@ var - kind = require('enyo/kind'); + animation = require('enyo/animation'), + kind = require('enyo/kind'), + rAF = animation.requestAnimationFrame; var ViewLayout = require('./ViewLayout'); diff --git a/src/ViewLayout/ViewLayout.js b/src/ViewLayout/ViewLayout.js index 7ff3db820..ccad63d14 100644 --- a/src/ViewLayout/ViewLayout.js +++ b/src/ViewLayout/ViewLayout.js @@ -1,9 +1,9 @@ -var rAF = window.requestAnimationFrame; - var + animation = require('enyo/animation'), kind = require('enyo/kind'), utils = require('enyo/utils'), - Layout = require('enyo/Layout'); + Layout = require('enyo/Layout'), + rAF = animation.requestAnimationFrame; /** * Order of operations: diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 61eb0b942..d8c774e9c 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -1,10 +1,12 @@ var rAF = window.requestAnimationFrame; var + animation = require('enyo/animation'), kind = require('enyo/kind'), utils = require('enyo/utils'), Control = require('enyo/Control'), - EventEmitter = require('enyo/EventEmitter'); + EventEmitter = require('enyo/EventEmitter'), + rAF = animation.requestAnimationFrame; var CardViewLayout = require('../CardViewLayout'); From d806556c2c02924d21c7e4f18ddd436a33fa9dfc Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Fri, 25 Sep 2015 13:51:40 -0500 Subject: [PATCH 014/210] cleanup and documentation Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/SlideViewLayout/SlideViewLayout.js | 7 +-- src/SlideViewLayout/SlideViewLayout.less | 1 - src/TransitionViewLayout.js | 1 + src/ViewLayout/ViewLayout.js | 62 ++++++++++++++++++++---- src/ViewManager/ViewManager.js | 4 +- 5 files changed, 60 insertions(+), 15 deletions(-) diff --git a/src/SlideViewLayout/SlideViewLayout.js b/src/SlideViewLayout/SlideViewLayout.js index 9f36dcd06..96f8b58dd 100644 --- a/src/SlideViewLayout/SlideViewLayout.js +++ b/src/SlideViewLayout/SlideViewLayout.js @@ -43,7 +43,8 @@ module.exports = kind({ * @private */ drag: function (event) { - var c = this.container, + var px, + c = this.container, bounds = c.dragBounds, isHorizontal = c.orientation == 'horizontal', size = isHorizontal ? bounds.width : bounds.height, @@ -99,8 +100,8 @@ module.exports = kind({ * * @private */ - completeTransition: function (was, is) { + completeTransition: function (view) { TransitionViewLayout.prototype.completeTransition.apply(this, arguments); - if (was) was.removeClass(this.direction == 'back' ? 'forward' : 'back'); + if (view) view.removeClass(this.direction == 'back' ? 'forward' : 'back'); } }); \ No newline at end of file diff --git a/src/SlideViewLayout/SlideViewLayout.less b/src/SlideViewLayout/SlideViewLayout.less index 180831210..df3d3f3cf 100644 --- a/src/SlideViewLayout/SlideViewLayout.less +++ b/src/SlideViewLayout/SlideViewLayout.less @@ -1,5 +1,4 @@ .enyo-viewlayout-slide { - > .enyo-view { transform: translateX(-100%); transition-property: none; diff --git a/src/TransitionViewLayout.js b/src/TransitionViewLayout.js index a001e1385..47b0c98c0 100644 --- a/src/TransitionViewLayout.js +++ b/src/TransitionViewLayout.js @@ -6,6 +6,7 @@ var var ViewLayout = require('./ViewLayout'); + /** * Slides views in from the right or top and out the left or bottom. * diff --git a/src/ViewLayout/ViewLayout.js b/src/ViewLayout/ViewLayout.js index ccad63d14..175641096 100644 --- a/src/ViewLayout/ViewLayout.js +++ b/src/ViewLayout/ViewLayout.js @@ -18,10 +18,27 @@ var * * @class enyo.ViewLayout */ -module.exports = kind({ +module.exports = kind( + /** @lends enyo.ViewLayout.prototype */ { + + /** + * @private + */ kind: Layout, + + /** + * @private + */ layoutClass: 'enyo-viewlayout', + + /** + * @private + */ viewClass: 'enyo-view', + + /** + * @private + */ constructor: function () { Layout.prototype._constructor.apply(this, arguments); this.container.addClass(this.container.orientation); @@ -30,6 +47,10 @@ module.exports = kind({ this.container.on('drag', this.handleDrag = this.handleDrag.bind(this)); this.container.on('cancelDrag', this.handleCancelDrag = this.handleCancelDrag.bind(this)); }, + + /** + * @private + */ destroy: function () { Layout.prototype.destroy.apply(this, arguments); this.container.unobserve('active', this.activeChanged); @@ -38,13 +59,9 @@ module.exports = kind({ this.container.off('cancelDrag', this.handleCancelDrag); }, - flow: function () { - - }, - reflow: function () { - - }, - + /** + * @private + */ setupView: function (view) { if (view && !view.viewSetup) { view.set('bubbleTarget', this); @@ -53,6 +70,9 @@ module.exports = kind({ } }, + /** + * @private + */ activeChanged: function (was, is) { this.setupView(is); @@ -84,10 +104,16 @@ module.exports = kind({ }.bind(this)); }, + /** + * @private + */ handleCancelDrag: function (sender, name, event) { this.activeChanged(this.container.dragView, this.container.active); }, + /** + * @private + */ handleDrag: function (sender, name, event) { // Only update the view once per frame if (!this.dragEvent) { @@ -99,11 +125,21 @@ module.exports = kind({ this.dragEvent = utils.clone(event); }, + /** + * @private + */ drag: function (event) { this.setupView(this.container.dragView); }, + /** + * @protected + */ prepareTransition: null, + + /** + * @protected + */ transition: function (was, is) { this.container.removeClass('dragging'); if (was) { @@ -115,11 +151,18 @@ module.exports = kind({ is.addClass('active'); } }, + + /** + * @protected + */ completeTransition: function (view) { view.removeClass('transitioning'); if (view !== this.container.active) this.container.deactivate(view.name); }, + /** + * @protected + */ shouldAnimate: function () { return this.container.generated && this.container.animated; }, @@ -136,6 +179,5 @@ module.exports = kind({ } else { return this.container.dispatchBubble(name, event, delegate); } - }, - + } }); \ No newline at end of file diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index d8c774e9c..600f2ecba 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -117,6 +117,8 @@ var ViewMgr = kind({ removeControl: function (control) { var i, l, index = this.views.indexOf(control); + + Control.prototype.removeControl.apply(this, arguments); if (index >= 0) { this.views.splice(index, 1); this.viewNames[control.name] = null; @@ -128,7 +130,7 @@ var ViewMgr = kind({ }, /** - * Renders the initially active view + * Activates the initial view * * @private */ From 75ea76801a46023e3a932aafeb670d08748410c4 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Fri, 25 Sep 2015 14:17:53 -0500 Subject: [PATCH 015/210] use SlideViewLayout as default layoutKind for ViewManager Also use cover style by default for floating ViewManagers Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 600f2ecba..0f4b63dfc 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -9,11 +9,11 @@ var rAF = animation.requestAnimationFrame; var - CardViewLayout = require('../CardViewLayout'); + SlideViewLayout = require('../SlideViewLayout'); var ViewMgr = kind({ kind: Control, - layoutKind: CardViewLayout, + layoutKind: SlideViewLayout, mixins: [EventEmitter], animated: true, classes: 'enyo-unselectable', @@ -76,6 +76,9 @@ var ViewMgr = kind({ }, create: function () { + // Set layoutCover for floating ViewManagers that haven't explicitly defined it + if (this.type == 'floating' && this.layoutCover === undefined) this.layoutCover = true; + Control.prototype.create.apply(this, arguments); this.managerEvent = this.managerEvent.bind(this); this.managerChanged(null, this.manager); From 72b920d60d6e49841e66f2d4eaf3494f977f8454 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Sat, 26 Sep 2015 20:55:14 -0500 Subject: [PATCH 016/210] fix stack management for floating ViewMangers Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 66 ++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 0f4b63dfc..0f35bd901 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -62,6 +62,13 @@ var ViewMgr = kind({ */ orientation: 'horizontal', + /** + * During a drag, contains a reference to the becoming-active view + * + * @private + */ + dragView: null, + manager: null, managerChanged: function (was, is) { if (was) this.off('*', was.managerEvent); @@ -155,7 +162,7 @@ var ViewMgr = kind({ this.activate(name); } else { view = this.getView(name); - this._activate(view); + this.activateImmediate(view); } }, @@ -268,19 +275,10 @@ var ViewMgr = kind({ * @public */ back: function () { - var view = this.peek(); - if (view) this.stack.pop(); - return view; - }, - - /** - * @public - */ - peek: function () { var name; - if (this.type == 'floating' && this.stack.length > 1) { - name = this.stack[this.stack.length - 2]; - return this.activate(name); + if (this.type == 'floating') { + name = this.dragging ? this.stack[0] : this.stack.shift(); + return this._activate(name); } }, @@ -350,23 +348,35 @@ var ViewMgr = kind({ }, /** - * @private + * Activates a new view. + * + * For floating ViewManagers, the view will be added to the stack and can be removed by `back()`. + * + * @param {String} viewName Name of the view to activate + * @public */ activate: function (viewName) { - var p = this.getView(viewName); - if (p) { - if (this.type == 'floating' && this.stack[this.stack.length - 1] !== viewName) { - this.stack.push(viewName); - } - rAF(this._activate.bind(this, p)); + var p = this._activate(viewName); + if (p && this.active && this.type == 'floating') { + this.stack.unshift(this.active.name); } + }, + + /** + * Activates a view + * + * @private + */ + _activate: function (viewName) { + var p = this.getView(viewName); + if (p) rAF(this.activateImmediate.bind(this, p)); return p; }, /** * @private */ - _activate: function (view) { + activateImmediate: function (view) { // render the activated view if (this.generated) { view.set('canGenerate', true); @@ -383,13 +393,13 @@ var ViewMgr = kind({ */ deactivate: function (viewName) { var p = this.getView(viewName); - if (p) rAF(this._deactivate.bind(this, p)); + if (p) rAF(this.deactivateImmediate.bind(this, p)); }, /** * @private */ - _deactivate: function (view) { + deactivateImmediate: function (view) { this.teardownView(view); if (!this.dragging) { @@ -456,14 +466,15 @@ var ViewMgr = kind({ } // set up the new drag view - if (!this.dragView) { + if (this.dragView === null) { if (this.dragDirection == 1) { this.dragView = this.next(); } else if (this.type == 'floating') { - this.dragView = this.peek(); + this.dragView = this.back(); } else { this.dragView = this.previous(); } + this.dragView = this.dragView || false; } this.emit('drag', event); } @@ -483,7 +494,10 @@ var ViewMgr = kind({ if (event.percentDelta * 100 > this.dragSnapPercent) { // normally, there will be a becoming-active view to activate if (this.dragView) { - this.activate(this.dragView.name); + if (this.type == 'floating') this.stack.shift(); + // we can safely call _activate because this is a dragged `back()` and no stack + // updates are necessary. + this._activate(this.dragView.name); this.dragView = null; } // unless it's a floating ViewManager that is being dismissed From a66bd1fb819a888d70148896a70d0ece11dee9cb Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Mon, 28 Sep 2015 08:55:24 -0500 Subject: [PATCH 017/210] fix missing return from activate() Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 0f35bd901..73776ee35 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -356,10 +356,11 @@ var ViewMgr = kind({ * @public */ activate: function (viewName) { - var p = this._activate(viewName); - if (p && this.active && this.type == 'floating') { + var view = this._activate(viewName); + if (view && !view.isManager && this.active && this.type == 'floating') { this.stack.unshift(this.active.name); } + return view; }, /** @@ -368,9 +369,9 @@ var ViewMgr = kind({ * @private */ _activate: function (viewName) { - var p = this.getView(viewName); - if (p) rAF(this.activateImmediate.bind(this, p)); - return p; + var view = this.getView(viewName); + if (view) rAF(this.activateImmediate.bind(this, view)); + return view; }, /** @@ -392,8 +393,9 @@ var ViewMgr = kind({ * @private */ deactivate: function (viewName) { - var p = this.getView(viewName); - if (p) rAF(this.deactivateImmediate.bind(this, p)); + var view = this.getView(viewName); + if (view) rAF(this.deactivateImmediate.bind(this, view)); + return view; }, /** @@ -498,7 +500,6 @@ var ViewMgr = kind({ // we can safely call _activate because this is a dragged `back()` and no stack // updates are necessary. this._activate(this.dragView.name); - this.dragView = null; } // unless it's a floating ViewManager that is being dismissed else if (this.type == 'floating' && event.direction == -1) { @@ -508,8 +509,8 @@ var ViewMgr = kind({ // otherwise the drag was small enough to be cancelled else { this.emit('cancelDrag', event); - this.dragView = null; } + this.dragView = null; this.set('dragging', false); return true; From b7868728515b69f45d1db99db4b8a9b03a73ef72 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Mon, 28 Sep 2015 15:04:27 -0500 Subject: [PATCH 018/210] update documentation Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/CardViewLayout/CardViewLayout.js | 8 +++ .../LeftRightViewLayout.js | 8 +++ src/SlideViewLayout/SlideViewLayout.js | 3 + src/TransitionViewLayout.js | 6 ++ src/ViewManager/ViewManager.js | 69 ++++++++++++++++++- 5 files changed, 93 insertions(+), 1 deletion(-) diff --git a/src/CardViewLayout/CardViewLayout.js b/src/CardViewLayout/CardViewLayout.js index a1be58944..b4559fc58 100644 --- a/src/CardViewLayout/CardViewLayout.js +++ b/src/CardViewLayout/CardViewLayout.js @@ -5,7 +5,15 @@ var TransitionViewLayout = require('../TransitionViewLayout'); module.exports = kind({ + + /** + * @private + */ kind: TransitionViewLayout, + + /** + * @private + */ layoutClass: 'enyo-viewlayout enyo-viewlayout-card', /** diff --git a/src/LeftRightViewLayout/LeftRightViewLayout.js b/src/LeftRightViewLayout/LeftRightViewLayout.js index 4b16aeb34..5c148de7a 100644 --- a/src/LeftRightViewLayout/LeftRightViewLayout.js +++ b/src/LeftRightViewLayout/LeftRightViewLayout.js @@ -5,7 +5,15 @@ var TransitionViewLayout = require('../TransitionViewLayout'); module.exports = kind({ + + /** + * @private + */ kind: TransitionViewLayout, + + /** + * @private + */ layoutClass: 'enyo-viewlayout enyo-viewlayout-leftright', /** diff --git a/src/SlideViewLayout/SlideViewLayout.js b/src/SlideViewLayout/SlideViewLayout.js index 96f8b58dd..223e681f4 100644 --- a/src/SlideViewLayout/SlideViewLayout.js +++ b/src/SlideViewLayout/SlideViewLayout.js @@ -34,6 +34,9 @@ module.exports = kind({ */ layoutClass: 'enyo-viewlayout enyo-viewlayout-slide', + /** + * @private + */ constructor: function () { TransitionViewLayout.prototype._constructor.apply(this, arguments); if (this.container.layoutCover) this.container.addClass('cover'); diff --git a/src/TransitionViewLayout.js b/src/TransitionViewLayout.js index 47b0c98c0..c8d9819ec 100644 --- a/src/TransitionViewLayout.js +++ b/src/TransitionViewLayout.js @@ -87,10 +87,16 @@ module.exports = kind({ view.applyStyle('transition-duration', duration + 'ms'); }, + /** + * @private + */ handlers: { ontransitionend: 'handleTransitioned' }, + /** + * @private + */ handleTransitioned: function (sender, event) { var view = event.originator; if (view && view.container == this.container) { diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 73776ee35..feead1e42 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -12,10 +12,30 @@ var SlideViewLayout = require('../SlideViewLayout'); var ViewMgr = kind({ + + /** + * @private + */ kind: Control, + + /** + * @private + */ layoutKind: SlideViewLayout, + + /** + * @private + */ mixins: [EventEmitter], + + /** + * @private + */ animated: true, + + /** + * @private + */ classes: 'enyo-unselectable', /** @@ -35,6 +55,15 @@ var ViewMgr = kind({ */ active: null, + /** + * `true` when a floating view has been dismissed + * + * @type {Boolean} + * @default false + * @public + */ + dismissed: false, + /** * When `true`, the views can be dragged into and out of view. * @@ -48,7 +77,7 @@ var ViewMgr = kind({ * Percent a new view must be dragged into the viewport to be activated on drag release * * @type {Number} - * @default 10 + * @default 25 * @public */ dragSnapPercent: 25, @@ -69,12 +98,28 @@ var ViewMgr = kind({ */ dragView: null, + /** + * If created within another ViewManager, `manager` will maintain a reference to that + * ViewManager which will be notified of activated, deactivated, dismiss, and dismissed events + * from this ViewManager. + * + * @type {enyo.ViewManager} + * @default null + * @public + */ manager: null, + + /** + * @private + */ managerChanged: function (was, is) { if (was) this.off('*', was.managerEvent); if (is) this.on('*', is.managerEvent); }, + /** + * @private + */ handlers: { ondown: 'handleDown', ondragstart: 'handleDragStart', @@ -82,22 +127,35 @@ var ViewMgr = kind({ ondragfinish: 'handleDragFinish' }, + /** + * @private + */ create: function () { // Set layoutCover for floating ViewManagers that haven't explicitly defined it if (this.type == 'floating' && this.layoutCover === undefined) this.layoutCover = true; Control.prototype.create.apply(this, arguments); + + // cache a bound reference to the managerEvent handler this.managerEvent = this.managerEvent.bind(this); this.managerChanged(null, this.manager); if (this.type == 'fixed') this.initFirstView(); else if (this.type == 'floating') this.stack = []; }, + + /** + * @private + */ rendered: function () { Control.prototype.rendered.apply(this, arguments); if (this.type == 'floating') this.initFirstView(); this.set('dismissed', false); }, + + /** + * @private + */ initComponents: function () { var managersOwner = Object.hasOwnProperty('managers') ? this.getInstanceOwner() : this; @@ -117,6 +175,11 @@ var ViewMgr = kind({ this.components = this.kindComponents = null; }, + /** + * If a newly added control doesn't exist in the view or manager array, add it + * + * @private + */ addControl: function (control, before) { Control.prototype.addControl.apply(this, arguments); @@ -124,6 +187,10 @@ var ViewMgr = kind({ this.addView(control); } }, + + /** + * @private + */ removeControl: function (control) { var i, l, index = this.views.indexOf(control); From bf5452639cc8dc2ee57b176686fa09710e051b73 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Mon, 28 Sep 2015 15:05:30 -0500 Subject: [PATCH 019/210] assign ViewManager's manager as direct ancestor rather than root The original intent was the root ViewManager would handle all layout so it made sense to delegate events upstream. With intermediate ViewManagers handling their own layout, that no longer seems right. Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index feead1e42..b40ef7586 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -183,7 +183,7 @@ var ViewMgr = kind({ addControl: function (control, before) { Control.prototype.addControl.apply(this, arguments); - if (!this.viewNames[control.name]) { + if (!this.viewNames[control.name] && !this.viewManagers[control.name]) { this.addView(control); } }, @@ -268,7 +268,7 @@ var ViewMgr = kind({ _view.set('owner', owner); if (_view instanceof ViewMgr) { _view.isManager = true; - _view.set('manager', this.manager || this); + _view.set('manager', this); } } else { _view.owner = owner; @@ -277,7 +277,7 @@ var ViewMgr = kind({ _view.name = 'viewManager' + (Object.keys(this.viewManagers).length + 1); } _view.isManager = true; - _view.manager = this.manager || this; + _view.manager = this; } } From 5f9895dfc6692ab5c50f9195c0c6061c3562b66d Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Tue, 29 Sep 2015 16:38:01 -0500 Subject: [PATCH 020/210] remove type member in favor of boolean floating member Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index b40ef7586..6e958b64b 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -39,13 +39,13 @@ var ViewMgr = kind({ classes: 'enyo-unselectable', /** - * View type + * If `true`, this ViewManager 'floats' over its parent `manager` * - * @type {String} - * @default fixed + * @type {Boolean} + * @default false * @public */ - type: 'fixed', + floating: false, /** * Active view @@ -132,7 +132,7 @@ var ViewMgr = kind({ */ create: function () { // Set layoutCover for floating ViewManagers that haven't explicitly defined it - if (this.type == 'floating' && this.layoutCover === undefined) this.layoutCover = true; + if (this.floating && this.layoutCover === undefined) this.layoutCover = true; Control.prototype.create.apply(this, arguments); @@ -140,8 +140,8 @@ var ViewMgr = kind({ this.managerEvent = this.managerEvent.bind(this); this.managerChanged(null, this.manager); - if (this.type == 'fixed') this.initFirstView(); - else if (this.type == 'floating') this.stack = []; + if (this.floating) this.stack = []; + else this.initFirstView(); }, /** @@ -149,7 +149,7 @@ var ViewMgr = kind({ */ rendered: function () { Control.prototype.rendered.apply(this, arguments); - if (this.type == 'floating') this.initFirstView(); + if (this.floating) this.initFirstView(); this.set('dismissed', false); }, @@ -343,7 +343,7 @@ var ViewMgr = kind({ */ back: function () { var name; - if (this.type == 'floating') { + if (this.floating) { name = this.dragging ? this.stack[0] : this.stack.shift(); return this._activate(name); } @@ -355,10 +355,10 @@ var ViewMgr = kind({ canDrag: function (direction) { var index; if (this.draggable) { - if (this.type == 'floating' && direction == -1) { + if (this.floating && direction == -1) { return true; } - else if (this.type == 'fixed') { + else if (!this.floating) { index = this.views.indexOf(this.active); return (index > 0 && direction == -1) || (index < this.views.length - 1 && direction == 1); @@ -424,7 +424,7 @@ var ViewMgr = kind({ */ activate: function (viewName) { var view = this._activate(viewName); - if (view && !view.isManager && this.active && this.type == 'floating') { + if (view && !view.isManager && this.active && this.floating) { this.stack.unshift(this.active.name); } return view; @@ -538,7 +538,7 @@ var ViewMgr = kind({ if (this.dragView === null) { if (this.dragDirection == 1) { this.dragView = this.next(); - } else if (this.type == 'floating') { + } else if (this.floating) { this.dragView = this.back(); } else { this.dragView = this.previous(); @@ -563,13 +563,13 @@ var ViewMgr = kind({ if (event.percentDelta * 100 > this.dragSnapPercent) { // normally, there will be a becoming-active view to activate if (this.dragView) { - if (this.type == 'floating') this.stack.shift(); + if (this.floating) this.stack.shift(); // we can safely call _activate because this is a dragged `back()` and no stack // updates are necessary. this._activate(this.dragView.name); } // unless it's a floating ViewManager that is being dismissed - else if (this.type == 'floating' && event.direction == -1) { + else if (this.floating && event.direction == -1) { this.dismiss(); } } From 3040e5759272aaf2fd0ba3d1ac61da3b5c89d9b0 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Tue, 29 Sep 2015 16:40:59 -0500 Subject: [PATCH 021/210] add complete event from ViewLayout Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewLayout/ViewLayout.js | 16 +++++++++++----- src/ViewManager/ViewManager.js | 24 ++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/ViewLayout/ViewLayout.js b/src/ViewLayout/ViewLayout.js index 175641096..5d127a69a 100644 --- a/src/ViewLayout/ViewLayout.js +++ b/src/ViewLayout/ViewLayout.js @@ -1,8 +1,9 @@ var - animation = require('enyo/animation'), - kind = require('enyo/kind'), - utils = require('enyo/utils'), - Layout = require('enyo/Layout'), + animation = require('../animation'), + kind = require('../kind'), + utils = require('../utils'), + EventEmitter = require('../EventEmitter'), + Layout = require('../Layout'), rAF = animation.requestAnimationFrame; /** @@ -26,6 +27,11 @@ module.exports = kind( */ kind: Layout, + /** + * @private + */ + mixins: [EventEmitter], + /** * @private */ @@ -157,7 +163,7 @@ module.exports = kind( */ completeTransition: function (view) { view.removeClass('transitioning'); - if (view !== this.container.active) this.container.deactivate(view.name); + this.emit('complete', view); }, /** diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 6e958b64b..6c4116c87 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -117,6 +117,16 @@ var ViewMgr = kind({ if (is) this.on('*', is.managerEvent); }, + /** + * @private + */ + layoutKindChanged: function (was, is) { + Control.prototype.layoutKindChanged.apply(this, arguments); + if (this.layout && this.layout.on) { + this.layout.on('complete', this.handleLayoutComplete, this); + } + }, + /** * @private */ @@ -490,6 +500,20 @@ var ViewMgr = kind({ } }, + // Layout + + /** + * Handles the 'complete' event from its layout indicating a view has completed its layout + * @private + */ + handleLayoutComplete: function (sender, name, view) { + if (view == this.active) { + this.emit('activated', view); + } else { + this.deactivate(view.name); + } + }, + // Draggable /** From 4e0832f7e00698f36e0229b5b6123e854ab73ef3 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Tue, 29 Sep 2015 16:42:33 -0500 Subject: [PATCH 022/210] ensure unique names for views within child ViewManagers Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 6c4116c87..96457876c 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -11,6 +11,8 @@ var var SlideViewLayout = require('../SlideViewLayout'); +var viewCount = 0; + var ViewMgr = kind({ /** @@ -269,9 +271,10 @@ var ViewMgr = kind({ * @private */ addView: function (view, owner, isManager) { - var index, name, - isControl = view instanceof Control, - _view = isControl ? view : utils.clone(view); + var index, + isControl = view instanceof Control, + _view = isControl ? view : utils.clone(view), + name = _view.name = _view.name || 'view' + (++viewCount); owner = _view.owner || owner || this; if (isControl) { @@ -283,19 +286,15 @@ var ViewMgr = kind({ } else { _view.owner = owner; if (isManager || _view.isManager) { - if (!_view.name) { - _view.name = 'viewManager' + (Object.keys(this.viewManagers).length + 1); - } _view.isManager = true; _view.manager = this; } } if (_view.isManager) { - this.viewManagers[_view.name] = _view; + this.viewManagers[name] = _view; } else { index = this.views.push(_view), - name = _view.name || (_view.name = 'view' + index); this.viewNames[name] = index - 1; } }, From cb51ac5c7cb19721e075eb881c26924669748698 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Tue, 29 Sep 2015 16:43:36 -0500 Subject: [PATCH 023/210] add activate and deactivate events along with some cleanup Issue: Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 29 ++++++++--------------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 96457876c..f2f82db20 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -57,6 +57,11 @@ var ViewMgr = kind({ */ active: null, + activeChanged: function (was, is) { + if (was) this.emit('deactivate', was); + if (is) this.emit('activate', is); + }, + /** * `true` when a floating view has been dismissed * @@ -388,6 +393,7 @@ var ViewMgr = kind({ this.set('active', null); this.set('dismissed', true); this.emit('dismiss'); + this.stack = []; } }, @@ -395,10 +401,7 @@ var ViewMgr = kind({ * @private */ managerEvent: function (viewManager, event, view) { - if (event == 'dismiss') this.managerDismissing(viewManager); - else if (event == 'dismissed') this.managerDismissed(viewManager); - else if (event == 'activated') this.managerActivated(viewManager, view); - else if (event == 'deactivated') this.managerDeactivated(viewManager, view); + if (event == 'dismissed') this.managerDismissed(viewManager); }, /** @@ -407,22 +410,9 @@ var ViewMgr = kind({ * @private */ managerDismissed: function (viewManager) { - this.log(this.id, 'ViewMgr', viewManager.name, 'dismissed'); this.teardownView(viewManager); }, - managerDismissing: function (viewManager) { - this.log(this.id, 'ViewMgr', viewManager.name, 'dismissing'); - }, - - managerActivated: function (viewManager, view) { - this.log(this.id, 'activated', view.name); - }, - - managerDeactivated: function (viewManager, view) { - this.log(this.id, 'deactivated', view.name); - }, - /** * Activates a new view. * @@ -459,10 +449,7 @@ var ViewMgr = kind({ view.set('canGenerate', true); view.render(); } - if (!this.dragging && !view.isManager) { - this.set('active', view); - this.emit('activated', view); - } + if (!this.dragging && !view.isManager) this.set('active', view); }, /** From edddb0838d5e443185b70b653b181db8efebd652 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Wed, 30 Sep 2015 11:49:42 -0500 Subject: [PATCH 024/210] fire activation events during drag Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 38 +++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index f2f82db20..25ecca1b4 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -57,9 +57,16 @@ var ViewMgr = kind({ */ active: null, + /** + * @private + */ activeChanged: function (was, is) { - if (was) this.emit('deactivate', was); - if (is) this.emit('activate', is); + if (was) { + this.emit('deactivate', { + view: was, + dragging: false + }); + } }, /** @@ -449,6 +456,10 @@ var ViewMgr = kind({ view.set('canGenerate', true); view.render(); } + this.emit('activate', { + view: view, + dragging: this.dragging + }); if (!this.dragging && !view.isManager) this.set('active', view); }, @@ -467,10 +478,14 @@ var ViewMgr = kind({ deactivateImmediate: function (view) { this.teardownView(view); - if (!this.dragging) { - if (!view.isManager) this.emit('deactivated', view); - if (this.dismissed) this.emit('dismissed'); + if (!view.isManager) { + this.emit('deactivated', { + view: view, + dragging: this.dragging + }); } + + if (!this.dragging && this.dismissed) this.emit('dismissed'); }, /** @@ -494,7 +509,9 @@ var ViewMgr = kind({ */ handleLayoutComplete: function (sender, name, view) { if (view == this.active) { - this.emit('activated', view); + this.emit('activated', { + view: view + }); } else { this.deactivate(view.name); } @@ -539,6 +556,10 @@ var ViewMgr = kind({ if (this.dragDirection !== event.direction) { this.dragDirection = event.direction; if (this.dragView) { + this.emit('deactivate', { + view: this.dragView, + dragging: true + }); this.deactivate(this.dragView.name); this.dragView = null; } @@ -573,9 +594,9 @@ var ViewMgr = kind({ if (event.percentDelta * 100 > this.dragSnapPercent) { // normally, there will be a becoming-active view to activate if (this.dragView) { + // dragging for floating views can only be a back action so shift it off the stack if (this.floating) this.stack.shift(); - // we can safely call _activate because this is a dragged `back()` and no stack - // updates are necessary. + // stack updates aren't necessary as we updated it above this._activate(this.dragView.name); } // unless it's a floating ViewManager that is being dismissed @@ -589,6 +610,7 @@ var ViewMgr = kind({ } this.dragView = null; this.set('dragging', false); + event.preventTap(); return true; }, From 3238f841a1e6978b621dfd55cf336fbd2200c11d Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Wed, 30 Sep 2015 16:58:47 -0500 Subject: [PATCH 025/210] fix duplicate view in views and duplicate dismissed events Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/SlideViewLayout/SlideViewLayout.js | 5 +++-- src/ViewManager/ViewManager.js | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/SlideViewLayout/SlideViewLayout.js b/src/SlideViewLayout/SlideViewLayout.js index 223e681f4..0479bb8ab 100644 --- a/src/SlideViewLayout/SlideViewLayout.js +++ b/src/SlideViewLayout/SlideViewLayout.js @@ -87,8 +87,9 @@ module.exports = kind({ if (was) { was.applyStyle('transform', null); // when using layoutCover, `was` doesn't transition so the ontransitionend doesn't fire - // to account for that, set a timeout of the same duration to manually clean up. - if (this.container.layoutCover) { + // to account for that, set a timeout of the same duration to manually clean up. The + // exception being when dismissing the ViewManager and there is no becoming-active view. + if (this.container.layoutCover && is) { setTimeout(this.completeTransition.bind(this, was), this.dragDuration || this.duration); } } diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 25ecca1b4..883470835 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -205,9 +205,10 @@ var ViewMgr = kind({ * @private */ addControl: function (control, before) { + var viewIndex = this.viewNames[control.name]; Control.prototype.addControl.apply(this, arguments); - if (!this.viewNames[control.name] && !this.viewManagers[control.name]) { + if (!control.isChrome && !(viewIndex || viewIndex === 0) && !this.viewManagers[control.name]) { this.addView(control); } }, From 5a3231ed51063ca7997b5fae7320f3af423a1e23 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Wed, 30 Sep 2015 17:01:12 -0500 Subject: [PATCH 026/210] add activateDefault property to control default view activation Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 883470835..5791ba6db 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -69,12 +69,28 @@ var ViewMgr = kind({ } }, + /** + * Determines if and how the default view is activated. The default view is either the first + * view with a truthy `active` member or the first view if none are marked active. + * + * * 'off' - No view is activated by default + * * 'create' - The default view is activated on create and not animated into position + * * 'render' - The default view is activated on render and animated into position + * * 'auto' - For floating ViewManagers, this is equivalent to 'render'. For non-floating + * ViewManagers, this is equivalent to 'create'. + * + * @type {String} + * @default auto + * @public + */ + activateDefault: 'auto', + /** * `true` when a floating view has been dismissed * * @type {Boolean} * @default false - * @public + * @private */ dismissed: false, @@ -165,7 +181,10 @@ var ViewMgr = kind({ this.managerChanged(null, this.manager); if (this.floating) this.stack = []; - else this.initFirstView(); + + if (this.activateDefault == 'create' || (this.activateDefault == 'auto' && !this.floating)) { + this.initFirstView(); + } }, /** @@ -173,7 +192,9 @@ var ViewMgr = kind({ */ rendered: function () { Control.prototype.rendered.apply(this, arguments); - if (this.floating) this.initFirstView(); + if (this.activateDefault == 'render' || (this.activateDefault == 'auto' && this.floating)) { + this.initFirstView(); + } this.set('dismissed', false); }, From 8e5985f37e3c8eef0dc2cb127d615a47b0eea8db Mon Sep 17 00:00:00 2001 From: Aaron Tam Date: Wed, 30 Sep 2015 16:21:12 -0700 Subject: [PATCH 027/210] ENYO-2621: Add support for specifying default component properties. Enyo-DCO-1.1-Signed-off-by: Aaron Tam --- src/UiComponent.js | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/UiComponent.js b/src/UiComponent.js index 66711b3d6..e4363a761 100644 --- a/src/UiComponent.js +++ b/src/UiComponent.js @@ -233,36 +233,39 @@ var UiComponent = module.exports = kind( }; }), - /** + /** * An alternative component update path that attempts to intelligently update only the * relevant portions of the component which have changed. * - * @param {Array} comps - An array of kind definitions to be set as the child components of + * @param {Object[]} props - An array of kind definitions to be set as the child components of * this component. + * @param {Object} [ext] - Additional properties to be supplied as defaults for components, when + * being created or recreated. These properties have no bearing on the diff computation of the + * child components. * @returns {Boolean} - Whether or not the component should be re-rendered. * @public */ - updateComponents: function (comps) { + updateComponents: function (props, ext) { var allStatefulKeys = {}, - isChanged = this.computeComponentsDiff(comps, allStatefulKeys), - comp, controls, control, keys, key, idxKey, idxComp, kind; + isChanged = this.computeComponentsDiff(props, allStatefulKeys), + prop, controls, control, keys, key, idxKey, idxProp, kind; if (isChanged) { this.destroyClientControls(); - this.createComponents(comps); + this.createComponents(props, ext); return true; } else { controls = this.getClientControls(); - for (idxComp = 0; idxComp < comps.length; idxComp++) { - comp = comps[idxComp]; - control = controls[idxComp]; - kind = comp.kind || this.defaultKind; - keys = allStatefulKeys[idxComp]; + for (idxProp = 0; idxProp < props.length; idxProp++) { + prop = props[idxProp]; + control = controls[idxProp]; + kind = prop.kind || this.defaultKind; + keys = allStatefulKeys[idxProp]; for (idxKey = 0; idxKey < keys.length; idxKey++) { // for each key, determine if there is a change key = keys[idxKey]; - if (comp[key] != control[key]) { - control.set(key, comp[key]); + if (prop[key] != control[key]) { + control.set(key, prop[key]); } } } @@ -702,7 +705,7 @@ var UiComponent = module.exports = kind( ); } }, - + /** * @method * @private From 021abdc426804018317601c0cf347f3a78654d2e Mon Sep 17 00:00:00 2001 From: Aaron Tam Date: Wed, 30 Sep 2015 16:21:57 -0700 Subject: [PATCH 028/210] ENYO-2621: Allow for options to be specified. Enyo-DCO-1.1-Signed-off-by: Aaron Tam --- src/UiComponent.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/UiComponent.js b/src/UiComponent.js index e4363a761..d6d2fbc19 100644 --- a/src/UiComponent.js +++ b/src/UiComponent.js @@ -13,6 +13,15 @@ var var Component = require('./Component'); +/** +* The configurable options used by {@link module:enyo/UiComponent~UiComponent} when updating +* components. +* +* @typedef {Object} enyo/UiComponent~UiComponent~UpdateComponentsOptions +* @property {Boolean} [silent] - If `true`, component properties will be updated silently i.e. they +* will be set directly, rather than via the generic `set` method. +*/ + /** * {@link module:enyo/UiComponent~UiComponent} implements a container strategy suitable for presentation layers. * @@ -242,10 +251,12 @@ var UiComponent = module.exports = kind( * @param {Object} [ext] - Additional properties to be supplied as defaults for components, when * being created or recreated. These properties have no bearing on the diff computation of the * child components. + * @param {module:enyo/UiComponent~UpdateComponentsOptions} [opts] - Additional options for how + * the update operation should behave. * @returns {Boolean} - Whether or not the component should be re-rendered. * @public */ - updateComponents: function (props, ext) { + updateComponents: function (props, ext, opts) { var allStatefulKeys = {}, isChanged = this.computeComponentsDiff(props, allStatefulKeys), prop, controls, control, keys, key, idxKey, idxProp, kind; @@ -265,7 +276,8 @@ var UiComponent = module.exports = kind( for (idxKey = 0; idxKey < keys.length; idxKey++) { // for each key, determine if there is a change key = keys[idxKey]; if (prop[key] != control[key]) { - control.set(key, prop[key]); + if (opts && opts.silent) control[key] = prop[key]; + else control.set(key, prop[key]); } } } From dea5592e4b04146c5ffd21635fa7f879effdfced Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Thu, 1 Oct 2015 11:30:50 -0500 Subject: [PATCH 029/210] add dismissable property to ViewManager Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 41 +++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 5791ba6db..dec5ddf36 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -86,7 +86,7 @@ var ViewMgr = kind({ activateDefault: 'auto', /** - * `true` when a floating view has been dismissed + * `true` when this ViewManager has been dismissed * * @type {Boolean} * @default false @@ -94,6 +94,21 @@ var ViewMgr = kind({ */ dismissed: false, + /** + * Determines if the view can be dismissed by dragging. The ViewManager can be programmatically + * dismissed via dismiss() regardless of the value of this property. If the ViewManager is the + * root and does not have a `manager`, it cannot be dismissed by dragging or by `dismiss()`. + * + * * `true` - Can be dismissed + * * `false` - Cannot be dismissed + * * 'auto' - Can be dismissed if `floating` is `true` + * + * @type {Boolean|String} + * @default auto + * @public + */ + dismissable: 'auto', + /** * When `true`, the views can be dragged into and out of view. * @@ -398,7 +413,7 @@ var ViewMgr = kind({ canDrag: function (direction) { var index; if (this.draggable) { - if (this.floating && direction == -1) { + if (this.isDimissable() && direction == -1) { return true; } else if (!this.floating) { @@ -411,6 +426,16 @@ var ViewMgr = kind({ return false; }, + /** + * Indicates if the view is dismissable via dragging + * + * @return {Boolean} + * @public + */ + isDimissable: function () { + return this.dismissable === true || (this.dismissable == 'auto' && this.floating); + }, + /** * Dismisses a view manager. If this is a root (manager-less) view manager, it cannot be * dismissed. @@ -559,6 +584,7 @@ var ViewMgr = kind({ if (!this.draggable) return; this.set('dragging', true); this.dragDirection = 0; + this.dragView = null; this.dragBounds = this.getBounds(); return true; @@ -585,9 +611,15 @@ var ViewMgr = kind({ this.deactivate(this.dragView.name); this.dragView = null; } + else if (this.dragView === false) { + this.dragView = null; + } } - // set up the new drag view + // dragView can be a View, `false`, or `null`. `null` indicates we need to (try to) + // activate the becoming-active view. It should be null when a drag starts or when + // there's a change of direction. `false` indicates that we've tried to activate a view + // but there isn't one in that direction. if (this.dragView === null) { if (this.dragDirection == 1) { this.dragView = this.next(); @@ -622,7 +654,7 @@ var ViewMgr = kind({ this._activate(this.dragView.name); } // unless it's a floating ViewManager that is being dismissed - else if (this.floating && event.direction == -1) { + else if (this.isDimissable() && event.direction == -1) { this.dismiss(); } } @@ -630,7 +662,6 @@ var ViewMgr = kind({ else { this.emit('cancelDrag', event); } - this.dragView = null; this.set('dragging', false); event.preventTap(); From d4c57a18ced0b77ec6a3735e74052ec8ebdbb1c3 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Thu, 1 Oct 2015 11:40:42 -0500 Subject: [PATCH 030/210] propagate events to ancestor managers Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index dec5ddf36..a01983402 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -456,6 +456,9 @@ var ViewMgr = kind({ */ managerEvent: function (viewManager, event, view) { if (event == 'dismissed') this.managerDismissed(viewManager); + this.emit('manager-' + event, { + manager: viewManager + }); }, /** From 435b59aa1129e85cedf59740beff53fbd2f3ee44 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Thu, 1 Oct 2015 17:45:45 -0500 Subject: [PATCH 031/210] set manager directly to avoid attaching duplicate event handlers Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index a01983402..a13129dfa 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -330,17 +330,17 @@ var ViewMgr = kind({ _view.set('owner', owner); if (_view instanceof ViewMgr) { _view.isManager = true; - _view.set('manager', this); } } else { _view.owner = owner; if (isManager || _view.isManager) { _view.isManager = true; - _view.manager = this; } } if (_view.isManager) { + // setting directly because the change handler is called manually during create + _view.manager = this; this.viewManagers[name] = _view; } else { index = this.views.push(_view), @@ -400,8 +400,9 @@ var ViewMgr = kind({ * @public */ back: function () { - var name; - if (this.floating) { + var name, + depth = this.stack.length; + if (this.floating && depth > 0) { name = this.dragging ? this.stack[0] : this.stack.shift(); return this._activate(name); } From 9fa5a08baf8a9054258a9c5f1ae3c6fdb7905dfd Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Mon, 5 Oct 2015 13:26:07 -0500 Subject: [PATCH 032/210] view layoutCover bug, move z-index to ViewManager Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/SlideViewLayout/SlideViewLayout.js | 18 ++++++++++++------ src/SlideViewLayout/SlideViewLayout.less | 7 +------ src/ViewManager/ViewManager.js | 2 +- src/ViewManager/ViewManager.less | 6 ++++++ src/ViewManager/package.json | 5 ++++- 5 files changed, 24 insertions(+), 14 deletions(-) create mode 100644 src/ViewManager/ViewManager.less diff --git a/src/SlideViewLayout/SlideViewLayout.js b/src/SlideViewLayout/SlideViewLayout.js index 0479bb8ab..b1cbcbdfe 100644 --- a/src/SlideViewLayout/SlideViewLayout.js +++ b/src/SlideViewLayout/SlideViewLayout.js @@ -83,20 +83,26 @@ module.exports = kind({ * @private */ transition: function (was, is) { + var stationaryView; TransitionViewLayout.prototype.transition.apply(this, arguments); if (was) { was.applyStyle('transform', null); - // when using layoutCover, `was` doesn't transition so the ontransitionend doesn't fire - // to account for that, set a timeout of the same duration to manually clean up. The - // exception being when dismissing the ViewManager and there is no becoming-active view. - if (this.container.layoutCover && is) { - setTimeout(this.completeTransition.bind(this, was), this.dragDuration || this.duration); - } } if (is) { is.removeClass(this.direction); is.applyStyle('transform', null); } + + // when using layoutCover, one view doesn't transition so the ontransitionend doesn't fire + // to account for that, set a timeout of the same duration to manually clean up. The + // exception being when dismissing the ViewManager and there is no becoming-active view. + if (this.container.layoutCover) { + stationaryView = this.direction == 'forward' && was + || this.direction == 'back' && is; + if (stationaryView) { + setTimeout(this.completeTransition.bind(this, stationaryView), this.dragDuration || this.duration); + } + } }, /** diff --git a/src/SlideViewLayout/SlideViewLayout.less b/src/SlideViewLayout/SlideViewLayout.less index df3d3f3cf..5590897ed 100644 --- a/src/SlideViewLayout/SlideViewLayout.less +++ b/src/SlideViewLayout/SlideViewLayout.less @@ -2,7 +2,7 @@ > .enyo-view { transform: translateX(-100%); transition-property: none; - transition-timing-function: ease-in-out; + transition-timing-function: linear; } &:not(.dragging) > .enyo-view.transitioning { @@ -31,10 +31,5 @@ // the becoming-inactive view doesn't move &.back { transform: translateX(0px); } } - - // promote any ViewLayout children to ensure they are above the active view - > .enyo-viewlayout { - z-index: 20; - } } } \ No newline at end of file diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index a13129dfa..f9838b9d7 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -38,7 +38,7 @@ var ViewMgr = kind({ /** * @private */ - classes: 'enyo-unselectable', + classes: 'enyo-viewmanager', /** * If `true`, this ViewManager 'floats' over its parent `manager` diff --git a/src/ViewManager/ViewManager.less b/src/ViewManager/ViewManager.less new file mode 100644 index 000000000..5780483ad --- /dev/null +++ b/src/ViewManager/ViewManager.less @@ -0,0 +1,6 @@ +.enyo-viewmanager { + // promote any ViewManager children to ensure they are above the active view + & > & { + z-index: 20; + } +} \ No newline at end of file diff --git a/src/ViewManager/package.json b/src/ViewManager/package.json index bb442b5d0..fa1ca3039 100644 --- a/src/ViewManager/package.json +++ b/src/ViewManager/package.json @@ -1,3 +1,6 @@ { - "main": "ViewManager.js" + "main": "ViewManager.js", + "styles": [ + "ViewManager.less" + ] } \ No newline at end of file From b4bc42b70304df9a8de974ffa5fc429e1f8627da Mon Sep 17 00:00:00 2001 From: Roy Sutton Date: Mon, 5 Oct 2015 11:51:41 -0700 Subject: [PATCH 033/210] ENYO-2646 Move contructor to create Enyo-DCO-1.1-Signed-off-by: Roy Sutton --- src/DataGridList/DataGridList.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DataGridList/DataGridList.js b/src/DataGridList/DataGridList.js index ba2c9e5ad..c63193485 100644 --- a/src/DataGridList/DataGridList.js +++ b/src/DataGridList/DataGridList.js @@ -80,7 +80,7 @@ var DataGridList = module.exports = kind( * @method * @private */ - constructor: kind.inherit(function (sup) { + create: kind.inherit(function (sup) { return function () { var o = this.orientation; // this will only remap _vertical_ and _horizontal_ meaning it is still possible to From dc047bbd2a46471cfdd0d5e2323e595e32e58c2e Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Tue, 6 Oct 2015 12:26:52 -0500 Subject: [PATCH 034/210] prevent drag events for dismissed ViewManagers Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index f9838b9d7..aca840285 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -585,7 +585,7 @@ var ViewMgr = kind({ * @private */ handleDragStart: function (sender, event) { - if (!this.draggable) return; + if (!this.draggable || this.dismissed) return; this.set('dragging', true); this.dragDirection = 0; this.dragView = null; @@ -600,7 +600,7 @@ var ViewMgr = kind({ * @private */ handleDrag: function (sender, event) { - if (!this.draggable) return; + if (!this.draggable || this.dismissed) return; this.decorateDragEvent(event); if (this.canDrag(event.direction)) { @@ -646,7 +646,8 @@ var ViewMgr = kind({ * @private */ handleDragFinish: function (sender, event) { - if (!this.draggable) return; + if (!this.draggable || this.dismissed) return; + this.decorateDragEvent(event); // if the view has been dragged far enough if (event.percentDelta * 100 > this.dragSnapPercent) { From ea080694013a13b0561e584d07e0356a5d810254 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Tue, 6 Oct 2015 14:23:58 -0500 Subject: [PATCH 035/210] fix complete event to fire when a CSS transition does not occur Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/SlideViewLayout/SlideViewLayout.js | 37 ++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/src/SlideViewLayout/SlideViewLayout.js b/src/SlideViewLayout/SlideViewLayout.js index b1cbcbdfe..309c2d261 100644 --- a/src/SlideViewLayout/SlideViewLayout.js +++ b/src/SlideViewLayout/SlideViewLayout.js @@ -51,9 +51,22 @@ module.exports = kind({ bounds = c.dragBounds, isHorizontal = c.orientation == 'horizontal', size = isHorizontal ? bounds.width : bounds.height, - delta = event.delta < 0 ? Math.max(event.delta, -size) : Math.min(event.delta, size), + delta = event.delta, transform = isHorizontal ? 'translateX' : 'translateY'; + + if (event.delta < 0 && event.delta < -size) { + this.overDrag = true; + delta = -size; + } + else if (event.delta > 0 && event.delta > size) { + this.overDrag = true; + delta = size; + } + else { + this.overDrag = false; + } + TransitionViewLayout.prototype.drag.apply(this, arguments); c.active.applyStyle('transform', transform + '(' + delta + 'px)'); if (c.dragView) { @@ -93,15 +106,19 @@ module.exports = kind({ is.applyStyle('transform', null); } + // If the user drags the entire view off screen, it won't animate so we won't see the CSS + // transition event. + if (this.overDrag) { + if (was) this.simulateTransition(was); + if (is) this.simulateTransition(is); + } // when using layoutCover, one view doesn't transition so the ontransitionend doesn't fire // to account for that, set a timeout of the same duration to manually clean up. The // exception being when dismissing the ViewManager and there is no becoming-active view. - if (this.container.layoutCover) { + else if (this.container.layoutCover) { stationaryView = this.direction == 'forward' && was || this.direction == 'back' && is; - if (stationaryView) { - setTimeout(this.completeTransition.bind(this, stationaryView), this.dragDuration || this.duration); - } + if (stationaryView) this.simulateTransition(stationaryView); } }, @@ -113,5 +130,15 @@ module.exports = kind({ completeTransition: function (view) { TransitionViewLayout.prototype.completeTransition.apply(this, arguments); if (view) view.removeClass(this.direction == 'back' ? 'forward' : 'back'); + }, + + /** + * Calls completeTransition after the drag or normal duration in cases where a CSS transition + * will not have occurred. + * + * @private + */ + simulateTransition: function (view) { + setTimeout(this.completeTransition.bind(this, view), this.dragDuration || this.duration); } }); \ No newline at end of file From 93cf3db63b330970212446a27c6cf6e25bc02e0b Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Tue, 6 Oct 2015 14:24:40 -0500 Subject: [PATCH 036/210] prevent rendering a view that has already been rendered Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index aca840285..fe3c4e4a5 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -502,8 +502,8 @@ var ViewMgr = kind({ * @private */ activateImmediate: function (view) { - // render the activated view - if (this.generated) { + // render the activated view if not already + if (this.generated && !view.generated) { view.set('canGenerate', true); view.render(); } From 97b4bc322e31fa968d58d1babbd1ded8016364d7 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Thu, 8 Oct 2015 09:11:00 -0500 Subject: [PATCH 037/210] ignore off-axis drags Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index fe3c4e4a5..d99048835 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -600,7 +600,13 @@ var ViewMgr = kind({ * @private */ handleDrag: function (sender, event) { - if (!this.draggable || this.dismissed) return; + if (!this.dragging || !this.draggable || this.dismissed) return; + + // check direction against orientation to ignore drags that don't apply to this + if (!event[this.orientation]) { + this.set('dragging', false); + return; + } this.decorateDragEvent(event); if (this.canDrag(event.direction)) { From 57a7ebb072a6dfbc72882b2f1b64c84ef3aac140 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Thu, 8 Oct 2015 11:50:35 -0500 Subject: [PATCH 038/210] add viewCount member to ViewManager Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index d99048835..beeb70cd1 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -154,6 +154,17 @@ var ViewMgr = kind({ */ manager: null, + /** + * The number of views managed by this ViewManager. This member is observable but should be + * considered read-only. + * + * @type {Number} + * @default 0 + * @readOnly + * @public + */ + viewCount: 0, + /** * @private */ @@ -230,6 +241,7 @@ var ViewMgr = kind({ this.importViewConfig(this.kindComponents, this); this.importViewConfig(this.components, this.getInstanceOwner()); this.importViewConfig(this.managers, managersOwner, true); + this.viewCount = this.views.length; // clean up references this.components = this.kindComponents = null; @@ -246,6 +258,7 @@ var ViewMgr = kind({ if (!control.isChrome && !(viewIndex || viewIndex === 0) && !this.viewManagers[control.name]) { this.addView(control); + this.set('viewCount', this.views.length); } }, @@ -264,6 +277,7 @@ var ViewMgr = kind({ for (i = index, l = this.views.length; i < l; i++) { this.viewNames[this.views[i].name] = i; } + this.set('viewCount', this.viewCount - 1); } }, From 5eeb0e1d1d20c3c16e6d2a4fbafb9159e2a6a992 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Thu, 8 Oct 2015 15:49:21 -0500 Subject: [PATCH 039/210] add indexOf method Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index beeb70cd1..24e2b9f72 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -362,6 +362,24 @@ var ViewMgr = kind({ } }, + + /** + * Returns the index of the provided view. For fixed ViewManagers, this reflects the view's ordered + * position. For floating ViewManagers, this reflects the last occurence of the view in the stack. If + * the view isn't found, -1 is returned. + * + * @param {enyo.Control} view + * @return {Number} Index of `view` + * @public + */ + indexOf: function (view) { + var index, + name = view && view.name; + if (!name) return -1; + + return this.floating ? this.stack.lastIndexOf(name) : this.views.indexOf(view); + }, + /** * @public */ From 3ab2af4e4b3045a461c2b6e4c4ce46414f215d9b Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Thu, 8 Oct 2015 15:49:56 -0500 Subject: [PATCH 040/210] fix handling stationary view in cover mode Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/SlideViewLayout/SlideViewLayout.js | 35 ++++++++++++++++++------ src/SlideViewLayout/SlideViewLayout.less | 21 ++++++++++---- 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/src/SlideViewLayout/SlideViewLayout.js b/src/SlideViewLayout/SlideViewLayout.js index 309c2d261..ad24c46b5 100644 --- a/src/SlideViewLayout/SlideViewLayout.js +++ b/src/SlideViewLayout/SlideViewLayout.js @@ -82,12 +82,26 @@ module.exports = kind({ */ prepareTransition: function (was, is) { var c = this.container, - wasIndex = was ? c.views.indexOf(was) : -1, - isIndex = is ? c.views.indexOf(is) : -1; + wasIndex = c.indexOf(was), + isIndex = c.indexOf(is); - this.direction = wasIndex < isIndex ? 'forward' : 'back'; + if (c.floating) { + // for a floating VM, if both is and was are not found, we're going back because is was + // already popped off the stack. however when the initial view is displayed, both + // indices will also be -1 but `was` will be null as well so we check that too. + this.direction = was && isIndex == -1 && wasIndex == -1 ? 'back' : 'forward'; + } else { + // fixed VMs direction is based only on each view's ordered position + this.direction = wasIndex < isIndex ? 'forward' : 'back'; + } if (is) is.addClass(this.direction); if (was) was.addClass(this.direction == 'back' ? 'forward' : 'back'); + + if (this.container.layoutCover) { + this.stationaryView = this.direction == 'forward' && was + || this.direction == 'back' && is; + if (this.stationaryView) this.stationaryView.addClass('stationary'); + } }, /** @@ -96,7 +110,6 @@ module.exports = kind({ * @private */ transition: function (was, is) { - var stationaryView; TransitionViewLayout.prototype.transition.apply(this, arguments); if (was) { was.applyStyle('transform', null); @@ -115,10 +128,8 @@ module.exports = kind({ // when using layoutCover, one view doesn't transition so the ontransitionend doesn't fire // to account for that, set a timeout of the same duration to manually clean up. The // exception being when dismissing the ViewManager and there is no becoming-active view. - else if (this.container.layoutCover) { - stationaryView = this.direction == 'forward' && was - || this.direction == 'back' && is; - if (stationaryView) this.simulateTransition(stationaryView); + else if (this.stationaryView) { + this.simulateTransition(this.stationaryView); } }, @@ -129,7 +140,13 @@ module.exports = kind({ */ completeTransition: function (view) { TransitionViewLayout.prototype.completeTransition.apply(this, arguments); - if (view) view.removeClass(this.direction == 'back' ? 'forward' : 'back'); + if (view) { + view.removeClass(this.direction == 'back' ? 'forward' : 'back'); + if (this.stationaryView && this.stationaryView == view) { + this.stationaryView.removeClass('stationary'); + this.stationaryView = null; + } + } }, /** diff --git a/src/SlideViewLayout/SlideViewLayout.less b/src/SlideViewLayout/SlideViewLayout.less index 5590897ed..9babad03a 100644 --- a/src/SlideViewLayout/SlideViewLayout.less +++ b/src/SlideViewLayout/SlideViewLayout.less @@ -23,13 +23,22 @@ } &.cover { + // in cover mode, promote all views up a bit > .enyo-view { - // the active view should always be on top - &.active { z-index: 5; } - // unless the becoming-active is transitioning in over it - &.forward { z-index: 10; } - // the becoming-inactive view doesn't move - &.back { transform: translateX(0px); } + z-index: 5; + // unless it's the stationary view which should always remain behind + &.stationary { + z-index: 0; + transform: translateX(0px); + } + } + + // except when dragging where the active view is promoted + &.dragging { + > .enyo-view { + z-index: 0; + &.active { z-index: 10; } + } } } } \ No newline at end of file From 865b7f31eb2dd460b5a711fd7561b9cff038dd9b Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Thu, 8 Oct 2015 15:50:23 -0500 Subject: [PATCH 041/210] guard handleDragFinish against ignored drags Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 24e2b9f72..85cc22f1b 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -684,7 +684,7 @@ var ViewMgr = kind({ * @private */ handleDragFinish: function (sender, event) { - if (!this.draggable || this.dismissed) return; + if (!this.dragging || !this.draggable || this.dismissed) return; this.decorateDragEvent(event); // if the view has been dragged far enough From dbacf4c4a0f62d242454e3882b5e6d623ea2b8ae Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Thu, 8 Oct 2015 16:22:36 -0500 Subject: [PATCH 042/210] fix jshint Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 85cc22f1b..af06a7f6d 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -373,8 +373,7 @@ var ViewMgr = kind({ * @public */ indexOf: function (view) { - var index, - name = view && view.name; + var name = view && view.name; if (!name) return -1; return this.floating ? this.stack.lastIndexOf(name) : this.views.indexOf(view); From 228d2a276b4d5bd8c101bb2ab0f5d381d8fe18ac Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Fri, 9 Oct 2015 16:07:52 -0500 Subject: [PATCH 043/210] restore ability to drag both directions When dragging back across the starting point, if you were at all off- axis, the drag orientation would change and dragging would be stopped. Instead, we only change the direction on the first drag event. Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index af06a7f6d..e28c6b6ea 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -1,11 +1,12 @@ var rAF = window.requestAnimationFrame; var - animation = require('enyo/animation'), - kind = require('enyo/kind'), - utils = require('enyo/utils'), - Control = require('enyo/Control'), - EventEmitter = require('enyo/EventEmitter'), + animation = require('../animation'), + kind = require('../kind'), + utils = require('../utils'), + Control = require('../Control'), + EventEmitter = require('../EventEmitter'), + SlideViewLayout = require('../SlideViewLayout'), rAF = animation.requestAnimationFrame; var @@ -292,9 +293,9 @@ var ViewMgr = kind({ if (this.views.length === 0) return; - // find the first declared active view + // find the first declared defaultView while ((view = this.views[i++]) && !name) { - if (view.active) { + if (view.defaultView) { name = view.name; } } @@ -578,6 +579,7 @@ var ViewMgr = kind({ teardownView: function (view) { if (view.node && !view.persistent) { view.node.remove(); + view.node = null; view.set('canGenerate', false); view.teardownRender(true); } @@ -617,7 +619,7 @@ var ViewMgr = kind({ */ handleDragStart: function (sender, event) { if (!this.draggable || this.dismissed) return; - this.set('dragging', true); + this.set('dragging', 'start'); this.dragDirection = 0; this.dragView = null; this.dragBounds = this.getBounds(); @@ -633,10 +635,14 @@ var ViewMgr = kind({ handleDrag: function (sender, event) { if (!this.dragging || !this.draggable || this.dismissed) return; - // check direction against orientation to ignore drags that don't apply to this - if (!event[this.orientation]) { + // check direction against orientation to ignore drags that don't apply to this. the check + // should only be necessary for the first drag event so it's further guarded by the special + // 'start' value of dragging. + if (this.dragging == 'start' && !event[this.orientation]) { this.set('dragging', false); return; + } else { + this.set('dragging', true); } this.decorateDragEvent(event); From 089e33d18d9242d31f4453c749ce126138c31c30 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Fri, 9 Oct 2015 16:10:46 -0500 Subject: [PATCH 044/210] add ScrimSupport proposal Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 5 +++-- src/ViewManager/ViewManager.less | 13 +++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index e28c6b6ea..5f879eb46 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -10,7 +10,7 @@ var rAF = animation.requestAnimationFrame; var - SlideViewLayout = require('../SlideViewLayout'); + ScrimSupport = require('./ScrimSupport'); var viewCount = 0; @@ -732,4 +732,5 @@ var ViewMgr = kind({ } }); -module.exports = ViewMgr; \ No newline at end of file +module.exports = ViewMgr; +module.exports.ScrimSupport = ScrimSupport; \ No newline at end of file diff --git a/src/ViewManager/ViewManager.less b/src/ViewManager/ViewManager.less index 5780483ad..396d83b4d 100644 --- a/src/ViewManager/ViewManager.less +++ b/src/ViewManager/ViewManager.less @@ -3,4 +3,17 @@ & > & { z-index: 20; } +} + +.enyo-viewmanager-scrim { + background: #fff; + opacity: 0; + pointer-events: none; + transition: opacity 300ms linear; + z-index: 10; + + &.showing { + opacity: 0.5; + pointer-events: auto; + } } \ No newline at end of file From 0ab00a5eea193f7d30f743f057622ec7a10a1699 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Fri, 9 Oct 2015 16:10:46 -0500 Subject: [PATCH 045/210] add ScrimSupport proposal Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ScrimSupport.js | 17 +++++++++++++++++ src/ViewManager/ViewManager.js | 5 +++-- src/ViewManager/ViewManager.less | 13 +++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 src/ViewManager/ScrimSupport.js diff --git a/src/ViewManager/ScrimSupport.js b/src/ViewManager/ScrimSupport.js new file mode 100644 index 000000000..24b1a506e --- /dev/null +++ b/src/ViewManager/ScrimSupport.js @@ -0,0 +1,17 @@ +var + kind = require('../kind'); + +module.exports = { + initComponents: kind.inherit(function (sup) { + return function () { + sup.apply(this, arguments); + this.createComponent({name: 'scrim', classes: 'enyo-viewmanager-scrim enyo-fit', isChrome: true}); + this.on('activate', function (sender, name, event) { + if (event.view.isManager) this.$.scrim.addClass('showing'); + }, this); + this.on('manager-dismiss', function (sender, name, event) { + this.$.scrim.removeClass('showing'); + }, this); + }; + }) +}; \ No newline at end of file diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index e28c6b6ea..5f879eb46 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -10,7 +10,7 @@ var rAF = animation.requestAnimationFrame; var - SlideViewLayout = require('../SlideViewLayout'); + ScrimSupport = require('./ScrimSupport'); var viewCount = 0; @@ -732,4 +732,5 @@ var ViewMgr = kind({ } }); -module.exports = ViewMgr; \ No newline at end of file +module.exports = ViewMgr; +module.exports.ScrimSupport = ScrimSupport; \ No newline at end of file diff --git a/src/ViewManager/ViewManager.less b/src/ViewManager/ViewManager.less index 5780483ad..396d83b4d 100644 --- a/src/ViewManager/ViewManager.less +++ b/src/ViewManager/ViewManager.less @@ -3,4 +3,17 @@ & > & { z-index: 20; } +} + +.enyo-viewmanager-scrim { + background: #fff; + opacity: 0; + pointer-events: none; + transition: opacity 300ms linear; + z-index: 10; + + &.showing { + opacity: 0.5; + pointer-events: auto; + } } \ No newline at end of file From 0f95b460171cfccca860dc927642cdf3da1441d4 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Mon, 12 Oct 2015 17:00:46 -0500 Subject: [PATCH 046/210] move direction determination to ViewManager Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/SlideViewLayout/SlideViewLayout.js | 36 +++++++++++----------- src/ViewManager/ViewManager.js | 41 ++++++++++++++++++++++++-- 2 files changed, 56 insertions(+), 21 deletions(-) diff --git a/src/SlideViewLayout/SlideViewLayout.js b/src/SlideViewLayout/SlideViewLayout.js index ad24c46b5..9f8afffb2 100644 --- a/src/SlideViewLayout/SlideViewLayout.js +++ b/src/SlideViewLayout/SlideViewLayout.js @@ -42,6 +42,15 @@ module.exports = kind({ if (this.container.layoutCover) this.container.addClass('cover'); }, + /** + * @private + */ + addRemoveDirection: function (view, addRemove, invert) { + var direction = invert ? -this.container.direction : this.container.direction, + className = direction == 1 ? 'forward' : 'back'; + view.addRemoveClass(className, addRemove); + }, + /** * @private */ @@ -81,25 +90,14 @@ module.exports = kind({ * @private */ prepareTransition: function (was, is) { - var c = this.container, - wasIndex = c.indexOf(was), - isIndex = c.indexOf(is); - - if (c.floating) { - // for a floating VM, if both is and was are not found, we're going back because is was - // already popped off the stack. however when the initial view is displayed, both - // indices will also be -1 but `was` will be null as well so we check that too. - this.direction = was && isIndex == -1 && wasIndex == -1 ? 'back' : 'forward'; - } else { - // fixed VMs direction is based only on each view's ordered position - this.direction = wasIndex < isIndex ? 'forward' : 'back'; - } - if (is) is.addClass(this.direction); - if (was) was.addClass(this.direction == 'back' ? 'forward' : 'back'); + var c = this.container; + + if (is) this.addRemoveDirection(is, true); + if (was) this.addRemoveDirection(was, true, true); if (this.container.layoutCover) { - this.stationaryView = this.direction == 'forward' && was - || this.direction == 'back' && is; + this.stationaryView = c.direction == 1 && was + || c.direction == -1 && is; if (this.stationaryView) this.stationaryView.addClass('stationary'); } }, @@ -115,7 +113,7 @@ module.exports = kind({ was.applyStyle('transform', null); } if (is) { - is.removeClass(this.direction); + this.addRemoveDirection(is, false); is.applyStyle('transform', null); } @@ -141,7 +139,7 @@ module.exports = kind({ completeTransition: function (view) { TransitionViewLayout.prototype.completeTransition.apply(this, arguments); if (view) { - view.removeClass(this.direction == 'back' ? 'forward' : 'back'); + this.addRemoveDirection(view, false, true); if (this.stationaryView && this.stationaryView == view) { this.stationaryView.removeClass('stationary'); this.stationaryView = null; diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 5f879eb46..4c75c366c 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -58,6 +58,16 @@ var ViewMgr = kind({ */ active: null, + /** + * Indicates the logical direction of a view activation. May be used by ViewLayouts to inform the + * direction of their animation + * + * @type {Number} + * @default 0 + * @private + */ + direction: 0, + /** * @private */ @@ -413,6 +423,7 @@ var ViewMgr = kind({ var index = this.views.indexOf(this.active) + 1, view = this.views[index]; if (view) { + this.direction = 1; return this.activate(view.name); } }, @@ -424,6 +435,7 @@ var ViewMgr = kind({ var index = this.views.indexOf(this.active) - 1, view = this.views[index]; if (view) { + this.direction = -1; return this.activate(view.name); } }, @@ -436,6 +448,7 @@ var ViewMgr = kind({ depth = this.stack.length; if (this.floating && depth > 0) { name = this.dragging ? this.stack[0] : this.stack.shift(); + this.direction = -1; return this._activate(name); } }, @@ -459,6 +472,24 @@ var ViewMgr = kind({ return false; }, + /** + * @private + */ + determineDirection: function (view) { + var isIndex, wasIndex; + + // for a floating VM, the default direction is always forward + if (this.floating) { + this.direction = 1; + } + // fixed VMs direction is based on each view's ordered position + else { + isIndex = this.indexOf(view); + wasIndex = this.indexOf(this.active); + this.direction = wasIndex < isIndex ? 1 : -1; + } + }, + /** * Indicates if the view is dismissable via dragging * @@ -477,6 +508,7 @@ var ViewMgr = kind({ */ dismiss: function () { if (this.manager) { + this.direction = -1; this.set('active', null); this.set('dismissed', true); this.emit('dismiss'); @@ -513,9 +545,13 @@ var ViewMgr = kind({ */ activate: function (viewName) { var view = this._activate(viewName); - if (view && !view.isManager && this.active && this.floating) { - this.stack.unshift(this.active.name); + if (view && !view.isManager) { + if (this.active && this.floating) { + this.stack.unshift(this.active.name); + } + if (!this.direction) this.determineDirection(view); } + return view; }, @@ -592,6 +628,7 @@ var ViewMgr = kind({ * @private */ handleLayoutComplete: function (sender, name, view) { + this.direction = 0; if (view == this.active) { this.emit('activated', { view: view From cde87bac2f535778031cc3ed67417399266713b9 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Tue, 13 Oct 2015 11:30:53 -0500 Subject: [PATCH 047/210] fix layout bug when cancelling drag Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 4c75c366c..6de9ba21e 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -745,6 +745,10 @@ var ViewMgr = kind({ } // otherwise the drag was small enough to be cancelled else { + // There really isn't a direction in this case but it's most like forward since the + // active view is transition back into position. This prevents determining a -1 + // direction and the resulting odd layout. + this.direction = 1; this.emit('cancelDrag', event); } this.set('dragging', false); From 486b7c5a706a3eacf3ef47c0d95886820823d1e7 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Tue, 13 Oct 2015 11:31:16 -0500 Subject: [PATCH 048/210] add count parameter to ViewManager.back() Enables popping multiple views off the stack Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 6de9ba21e..0eddb79c5 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -391,6 +391,10 @@ var ViewMgr = kind({ }, /** + * Retrieves and creates, if necessary, a view or view manager by name + * + * @param {String} viewName Name of the view or view manager + * @return {enyo.Control} View * @public */ getView: function (viewName) { @@ -417,6 +421,9 @@ var ViewMgr = kind({ }, /** + * Navigates to the next view based on order of definition or creation + * + * @return {enyo.Control} Activated view * @public */ next: function () { @@ -429,6 +436,9 @@ var ViewMgr = kind({ }, /** + * Navigates to the previous view based on order of definition or creation + * + * @return {enyo.Control} Activated view * @public */ previous: function () { @@ -441,13 +451,22 @@ var ViewMgr = kind({ }, /** + * If this is a floating ViewManager, navigates back `count` views from the stack. + * + * @param {Number} [count] Number of views to pop off the stack. Defaults to 1. + * @return {enyo.Control} Activated view * @public */ - back: function () { + back: function (count) { var name, depth = this.stack.length; if (this.floating && depth > 0) { - name = this.dragging ? this.stack[0] : this.stack.shift(); + if (this.dragging) { + name = this.stack[0]; + } else { + count = count > depth ? depth : count || 1; + name = this.stack.splice(0, count).pop(); + } this.direction = -1; return this._activate(name); } From 10f168580a07c43aa264a8bdcfa2fcfd3debd9ca Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Thu, 15 Oct 2015 12:33:39 -0500 Subject: [PATCH 049/210] add notification method invocation for ViewManager lifecycle events Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 0eddb79c5..d3e50ee27 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -211,6 +211,7 @@ var ViewMgr = kind({ // Set layoutCover for floating ViewManagers that haven't explicitly defined it if (this.floating && this.layoutCover === undefined) this.layoutCover = true; + this.on('*', this.notifyViews, this); Control.prototype.create.apply(this, arguments); // cache a bound reference to the managerEvent handler @@ -535,6 +536,22 @@ var ViewMgr = kind({ } }, + /** + * When any view event (activate, activated, deactivate, deactivated) fires, notify the view of + * its change of state by calling a method matching the event (e.g. activate()), if it exists. + * + * @private + */ + notifyViews: function (sender, name, event) { + // Any event for a view will have an event payload with a view property indicating the view + // that is changing. Contained ViewManagers will also fire activate and deactivate events + // but we can't notify them because of method overlap. Also ignore events originating from + // contained ViewManagers (prefixed by manager-). + if (event && event.view && !event.view.isManager && name.indexOf('manager-') !== 0) { + if (utils.isFunction(event.view[name])) event.view[name](event); + } + }, + /** * @private */ From 733e88fa9ac5216a2266805510e7e64a06739479 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Thu, 15 Oct 2015 16:20:06 -0500 Subject: [PATCH 050/210] simply declarative child ViewManager handling Rather than checking for the isManager flag which was inconsistently applied, a VM can call a private isManager method to determine if the provided view exists and is in its viewManagers hash. A consequence of this change is that VMs can only be declared within the managers[] and, when created manually, will always be considered a manager. Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ScrimSupport.js | 2 +- src/ViewManager/ViewManager.js | 28 +++++++++++++++------------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/ViewManager/ScrimSupport.js b/src/ViewManager/ScrimSupport.js index 24b1a506e..e6e28185b 100644 --- a/src/ViewManager/ScrimSupport.js +++ b/src/ViewManager/ScrimSupport.js @@ -7,7 +7,7 @@ module.exports = { sup.apply(this, arguments); this.createComponent({name: 'scrim', classes: 'enyo-viewmanager-scrim enyo-fit', isChrome: true}); this.on('activate', function (sender, name, event) { - if (event.view.isManager) this.$.scrim.addClass('showing'); + if (this.isManager(event.view)) this.$.scrim.addClass('showing'); }, this); this.on('manager-dismiss', function (sender, name, event) { this.$.scrim.removeClass('showing'); diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index d3e50ee27..41a785c45 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -240,7 +240,7 @@ var ViewMgr = kind({ * @private */ initComponents: function () { - var managersOwner = Object.hasOwnProperty('managers') ? this.getInstanceOwner() : this; + var managersOwner = this.hasOwnProperty('managers') ? this.getInstanceOwner() : this; // view configs or instances this.views = []; @@ -347,24 +347,19 @@ var ViewMgr = kind({ */ addView: function (view, owner, isManager) { var index, - isControl = view instanceof Control, + isControl = view instanceof Control, _view = isControl ? view : utils.clone(view), name = _view.name = _view.name || 'view' + (++viewCount); owner = _view.owner || owner || this; if (isControl) { _view.set('owner', owner); - if (_view instanceof ViewMgr) { - _view.isManager = true; - } + isManager = _view instanceof ViewMgr; } else { _view.owner = owner; - if (isManager || _view.isManager) { - _view.isManager = true; - } } - if (_view.isManager) { + if (isManager) { // setting directly because the change handler is called manually during create _view.manager = this; this.viewManagers[name] = _view; @@ -547,7 +542,7 @@ var ViewMgr = kind({ // that is changing. Contained ViewManagers will also fire activate and deactivate events // but we can't notify them because of method overlap. Also ignore events originating from // contained ViewManagers (prefixed by manager-). - if (event && event.view && !event.view.isManager && name.indexOf('manager-') !== 0) { + if (event && event.view && name.indexOf('manager-') !== 0 && !this.isManager(event.view)) { if (utils.isFunction(event.view[name])) event.view[name](event); } }, @@ -581,7 +576,7 @@ var ViewMgr = kind({ */ activate: function (viewName) { var view = this._activate(viewName); - if (view && !view.isManager) { + if (view && !this.isManager(view)) { if (this.active && this.floating) { this.stack.unshift(this.active.name); } @@ -615,7 +610,7 @@ var ViewMgr = kind({ view: view, dragging: this.dragging }); - if (!this.dragging && !view.isManager) this.set('active', view); + if (!this.dragging && !this.isManager(view)) this.set('active', view); }, /** @@ -633,7 +628,7 @@ var ViewMgr = kind({ deactivateImmediate: function (view) { this.teardownView(view); - if (!view.isManager) { + if (!this.isManager(view)) { this.emit('deactivated', { view: view, dragging: this.dragging @@ -657,6 +652,13 @@ var ViewMgr = kind({ } }, + /** + * @private + */ + isManager: function (view) { + return view && this.viewManagers[view.name]; + }, + // Layout /** From 39f52ee3bc73624a3905f9b66607fb06b7be6214 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Thu, 15 Oct 2015 16:34:57 -0500 Subject: [PATCH 051/210] fix (actually this time) the navigation direction for a cancelled drag Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 41a785c45..706cc4b6e 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -783,10 +783,9 @@ var ViewMgr = kind({ } // otherwise the drag was small enough to be cancelled else { - // There really isn't a direction in this case but it's most like forward since the - // active view is transition back into position. This prevents determining a -1 - // direction and the resulting odd layout. - this.direction = 1; + // Since we're restoring the active view, the navigation direction is the opposite of + // the drag direction. + this.direction = -event.direction; this.emit('cancelDrag', event); } this.set('dragging', false); From 9df27e1f902f2ec0b59a226a71926b9c6229a301 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Fri, 16 Oct 2015 11:14:15 -0500 Subject: [PATCH 052/210] refine and standardize view-related events Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 45 ++++++++++++++-------------------- 1 file changed, 19 insertions(+), 26 deletions(-) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 706cc4b6e..300109a69 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -72,12 +72,7 @@ var ViewMgr = kind({ * @private */ activeChanged: function (was, is) { - if (was) { - this.emit('deactivate', { - view: was, - dragging: false - }); - } + if (was) this.emitViewEvent('deactivate', was); }, /** @@ -547,6 +542,17 @@ var ViewMgr = kind({ } }, + /** + * @private + */ + emitViewEvent: function (name, view) { + this.emit(name, { + view: view, + dragging: this.dragging, + direction: this.direction + }); + }, + /** * @private */ @@ -606,10 +612,7 @@ var ViewMgr = kind({ view.set('canGenerate', true); view.render(); } - this.emit('activate', { - view: view, - dragging: this.dragging - }); + this.emitViewEvent('activate', view); if (!this.dragging && !this.isManager(view)) this.set('active', view); }, @@ -628,13 +631,7 @@ var ViewMgr = kind({ deactivateImmediate: function (view) { this.teardownView(view); - if (!this.isManager(view)) { - this.emit('deactivated', { - view: view, - dragging: this.dragging - }); - } - + if (!this.isManager(view)) this.emitViewEvent('deactivated', view); if (!this.dragging && this.dismissed) this.emit('dismissed'); }, @@ -666,14 +663,13 @@ var ViewMgr = kind({ * @private */ handleLayoutComplete: function (sender, name, view) { - this.direction = 0; if (view == this.active) { - this.emit('activated', { - view: view - }); + this.emitViewEvent('activated', view); } else { - this.deactivate(view.name); + // This is already within a rAF + this.deactivateImmediate(view); } + this.direction = 0; }, // Draggable @@ -726,10 +722,7 @@ var ViewMgr = kind({ if (this.dragDirection !== event.direction) { this.dragDirection = event.direction; if (this.dragView) { - this.emit('deactivate', { - view: this.dragView, - dragging: true - }); + this.emitViewEvent('deactivate', this.dragView); this.deactivate(this.dragView.name); this.dragView = null; } From c56a2c3dcfb04040bd9cbd86b9daf6a5152c704a Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Fri, 16 Oct 2015 11:14:41 -0500 Subject: [PATCH 053/210] add getActive() method to ViewManager Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 300109a69..201369731 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -381,6 +381,16 @@ var ViewMgr = kind({ return this.floating ? this.stack.lastIndexOf(name) : this.views.indexOf(view); }, + /** + * Returns the currently active view + * + * @return {enyo.Control} + * @public + */ + getActive: function () { + return this.active; + }, + /** * Retrieves and creates, if necessary, a view or view manager by name * From ded1d66426d11a7ae1cae19bf821b64c815c51fa Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Fri, 16 Oct 2015 13:53:37 -0500 Subject: [PATCH 054/210] add documentation to ViewManager Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/SlideViewLayout/SlideViewLayout.js | 4 +- src/ViewManager/ViewManager.js | 202 +++++++++++++++++++++++-- 2 files changed, 191 insertions(+), 15 deletions(-) diff --git a/src/SlideViewLayout/SlideViewLayout.js b/src/SlideViewLayout/SlideViewLayout.js index 9f8afffb2..5667b99d5 100644 --- a/src/SlideViewLayout/SlideViewLayout.js +++ b/src/SlideViewLayout/SlideViewLayout.js @@ -21,7 +21,9 @@ var * * `completeTransition()` * Removes the directional classes and resets the `dragDuration` * -* @class enyo.SlideViewLayout +* @class SlideViewLayout +* @extends enyo/TransitionViewLayout~TransitionViewLayout +* @public */ module.exports = kind({ /** diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 201369731..e257a36b4 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -1,3 +1,87 @@ +/** +* ViewManager module +* +* @module enyo/ViewManager +*/ + +/** +* Fires after a view has been created and rendered, if necessary, but before it transitions into +* viewport. +* +* @event module:enyo/ViewManager~ViewManager#activate +* @property {module:enyo/Control~Control} view The target view for the event +* @property {Boolean} dragging `true` for `activate` or `deactivate` events that occur as a result +* of dragging +* @property {Number} direction Either 1 representing forward or -1 representing backward +* @public +*/ + +/** +* Fires after a view has been created, rendered, and transitioned into the viewport. +* +* @event module:enyo/ViewManager~ViewManager#activated +* @type {Object} +* @property {module:enyo/Control~Control} view The target view for the event +* @property {Boolean} dragging `true` for `activate` or `deactivate` events that occur as a result +* of dragging +* @property {Number} direction Either 1 representing forward or -1 representing backward +* @public +*/ + +/** +* Fires on the previously active view when a new view has become active but before it has +* transitioned out of the viewport +* +* @event module:enyo/ViewManager~ViewManager#deactivate +* @property {module:enyo/Control~Control} view The target view for the event +* @property {Boolean} dragging `true` for `activate` or `deactivate` events that occur as a result +* of dragging +* @property {Number} direction Either 1 representing forward or -1 representing backward +* @public +*/ + +/** +* Fires on the previously active view when it has transitioned out of the viewport and been torn +* down. +* +* @event module:enyo/ViewManager~ViewManager#deactivated +* @property {module:enyo/Control~Control} view The target view for the event +* @property {Boolean} dragging `true` for `activate` or `deactivate` events that occur as a result +* of dragging +* @property {Number} direction Either 1 representing forward or -1 representing backward +* @public +*/ + +/** +* Fires on the previously active view when it has transitioned out of the viewport and been torn +* down. +* +* @event module:enyo/ViewManager~ViewManager#deactivated +* @property {module:enyo/Control~Control} view The target view for the event +* @property {Boolean} dragging `true` for `activate` or `deactivate` events that occur as a result +* of dragging +* @property {Number} direction Either 1 representing forward or -1 representing backward +* @public +*/ + +/** +* Fires when this ViewManager dimissal is initiated -- either by a call to +* [dismiss()]{@link module:enyo/ViewManager~ViewManager#dismiss} or when a +* [dismissable]{@link module:enyo/ViewManager~ViewManager#dismissable} ViewManager is on its first +* view and is dragged beyond the +* [dragThreshold]{@link module:enyo/ViewManager~ViewManager#dragThreshold}. +* +* @event module:enyo/ViewManager~ViewManager#dismiss +* @public +*/ + +/** +* Fires when a ViewManager completes its dismissal. +* +* @event module:enyo/ViewManager~ViewManager#dismissed +* @public +*/ + var rAF = window.requestAnimationFrame; var @@ -14,7 +98,97 @@ var var viewCount = 0; -var ViewMgr = kind({ +/** +* ViewManager manages views. +* +* ``` +* module.exports = kind({ +* kind: ViewMgr, +* classes: 'contacts', +* +* // All the views are declared in the common components block +* components: [ +* {name: 'history', components: [ +* {content: 'History'}, +* {kind: Button, content: 'Next', ontap: 'next'} +* ]}, +* {name: 'dialer', active: true, components: [ +* {content: 'Dialer'}, +* {kind: Button, content: 'Inline Example', ontap: 'activateInline'}, +* {kind: Button, content: 'Previous', ontap: 'previous'}, +* {kind: Button, content: 'Next', ontap: 'next'} +* ]}, +* {name: 'contacts', components: [ +* {content: 'Contacts'}, +* {kind: Button, content: 'Previous', ontap: 'previous'}, +* {kind: Button, content: 'Add A Contact', ontap: 'pushAddContactView'} +* ]} +* ], +* +* // Child ViewManagers are declared within a new managers block +* managers: [ +* {name: 'add', kind: AddContact}, +* {name: 'inline', kind: ViewMgr, floating: true, components: [ +* {content: 'view1', style: 'background: #424242; color: #fff;', ontap: 'nextInline'}, +* {content: 'view2', style: 'background: #424242; color: #fff;', ontap: 'nextInline'}, +* {content: 'view3', style: 'background: #424242; color: #fff;', ontap: 'dismissInline'} +* ]} +* ], +* +* create: function () { +* ViewMgr.prototype.create.apply(this, arguments); +* +* function log (sender, name, event) { +* console.log('Event', name, +* 'on view', event.view.name, +* event.dragging ? 'while dragging' : ''); +* } +* +* // ViewManager emits events to ease view initialization and teardown without concern for the +* // async nature of animations. +* +* // `view` has been activated but not animated +* this.on('activate', log); +* +* // `view` has been activate and animated +* this.on('activated', log); +* +* // `view` has been deactivated but not animated +* this.on('deactivate', log); +* +* // `view` has been deactivated and animated +* this.on('deactivated', log); +* }, +* +* // Activate and navigate the Inline ViewManager +* activateInline: function () { +* this.activate('inline'); +* }, +* nextInline: function () { +* this.$.inline.next(); +* }, +* dismissInline: function () { +* this.$.inline.dismiss(); +* }, +* +* // Activate the Contacts ViewManager +* pushAddContactView: function () { +* var view = this.activate('add'); +* view.set('model', new Model({ +* first: 'First Name', +* last: 'Last Name' +* })); +* } +* }); +* ``` +* +* @class ViewManager +* @extends module:enyo/Control~Control +* @ui +* @public +*/ +var ViewMgr = kind( + /** @lends module:enyo/ViewManager~ViewManager.prototype */ { /** * @private @@ -131,7 +305,7 @@ var ViewMgr = kind({ * @default 25 * @public */ - dragSnapPercent: 25, + dragThreshold: 25, /** * When `draggable`, this constrains the drag to this direction. @@ -154,7 +328,7 @@ var ViewMgr = kind({ * ViewManager which will be notified of activated, deactivated, dismiss, and dismissed events * from this ViewManager. * - * @type {enyo.ViewManager} + * @type {module:enyo/ViewManager~ViewManager} * @default null * @public */ @@ -318,8 +492,8 @@ var ViewMgr = kind({ /** * Adds the list of components as views * - * @param {Object[]|enyo.Control[]} components List of components - * @param {enyo.Control|null} [owner] Owner of components + * @param {Object[]|module:enyo/Control~Control[]} components List of components + * @param {module:enyo/Control~Control|null} [owner] Owner of components * * @private */ @@ -335,8 +509,8 @@ var ViewMgr = kind({ /** * Adds a new view to the view set * - * @param {Object|enyo.Control} view View config or instance - * @param {enyo.Control|null} [owner] Optional owner of view. Defaults to this. + * @param {Object|module:enyo/Control~Control} view View config or instance + * @param {module:enyo/Control~Control|null} [owner] Optional owner of view. Defaults to this. * * @private */ @@ -370,7 +544,7 @@ var ViewMgr = kind({ * position. For floating ViewManagers, this reflects the last occurence of the view in the stack. If * the view isn't found, -1 is returned. * - * @param {enyo.Control} view + * @param {module:enyo/Control~Control} view * @return {Number} Index of `view` * @public */ @@ -384,7 +558,7 @@ var ViewMgr = kind({ /** * Returns the currently active view * - * @return {enyo.Control} + * @return {module:enyo/Control~Control} * @public */ getActive: function () { @@ -395,7 +569,7 @@ var ViewMgr = kind({ * Retrieves and creates, if necessary, a view or view manager by name * * @param {String} viewName Name of the view or view manager - * @return {enyo.Control} View + * @return {module:enyo/Control~Control} View * @public */ getView: function (viewName) { @@ -424,7 +598,7 @@ var ViewMgr = kind({ /** * Navigates to the next view based on order of definition or creation * - * @return {enyo.Control} Activated view + * @return {module:enyo/Control~Control} Activated view * @public */ next: function () { @@ -439,7 +613,7 @@ var ViewMgr = kind({ /** * Navigates to the previous view based on order of definition or creation * - * @return {enyo.Control} Activated view + * @return {module:enyo/Control~Control} Activated view * @public */ previous: function () { @@ -455,7 +629,7 @@ var ViewMgr = kind({ * If this is a floating ViewManager, navigates back `count` views from the stack. * * @param {Number} [count] Number of views to pop off the stack. Defaults to 1. - * @return {enyo.Control} Activated view + * @return {module:enyo/Control~Control} Activated view * @public */ back: function (count) { @@ -771,7 +945,7 @@ var ViewMgr = kind({ this.decorateDragEvent(event); // if the view has been dragged far enough - if (event.percentDelta * 100 > this.dragSnapPercent) { + if (event.percentDelta * 100 > this.dragThreshold) { // normally, there will be a becoming-active view to activate if (this.dragView) { // dragging for floating views can only be a back action so shift it off the stack From 2f6ff7754f16ffe923953afc9f674da2ad7f7aed Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Sun, 18 Oct 2015 15:23:07 -0500 Subject: [PATCH 055/210] switch to activateImmediate after drag to avoid pause When using activate, the requestAnimationFrame caused a brief delay before the transition began which created an odd pause when releasing the drag. Using activateImmediate resolves this. Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index e257a36b4..7bfcdae2b 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -943,6 +943,7 @@ var ViewMgr = kind( handleDragFinish: function (sender, event) { if (!this.dragging || !this.draggable || this.dismissed) return; + this.set('dragging', false); this.decorateDragEvent(event); // if the view has been dragged far enough if (event.percentDelta * 100 > this.dragThreshold) { @@ -951,7 +952,7 @@ var ViewMgr = kind( // dragging for floating views can only be a back action so shift it off the stack if (this.floating) this.stack.shift(); // stack updates aren't necessary as we updated it above - this._activate(this.dragView.name); + this.activateImmediate(this.dragView); } // unless it's a floating ViewManager that is being dismissed else if (this.isDimissable() && event.direction == -1) { @@ -965,7 +966,6 @@ var ViewMgr = kind( this.direction = -event.direction; this.emit('cancelDrag', event); } - this.set('dragging', false); event.preventTap(); return true; From e370b5761475e630c5b98756fce2d28427316272 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Tue, 20 Oct 2015 11:56:42 -0500 Subject: [PATCH 056/210] add manage event to ViewManager Instead of overloading 'activate' with both views and manager and incongruently using 'deactivate' and 'dismiss' respectively for tear down, add a new 'manage' event for activation of a child ViewManager. Note that, for the time being, there is intentionally no post-transition event (like 'activated' for views) because the ViewManager's activation isn't animated in any way. Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 7bfcdae2b..cfaf92c68 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -64,6 +64,15 @@ * @public */ +/** +* Fires when this ViewManager is [activated]{@link module:enyo/ViewManager~ViewManager#activate} by +* its [manager]{@link module:enyo/ViewManager~ViewManager#manager} and ready to activate its own +* views. +* +* @event module:enyo/ViewManager~ViewManager#manage +* @public +*/ + /** * Fires when this ViewManager dimissal is initiated -- either by a call to * [dismiss()]{@link module:enyo/ViewManager~ViewManager#dismiss} or when a @@ -717,12 +726,13 @@ var ViewMgr = kind( * @private */ notifyViews: function (sender, name, event) { + var viewEvent = name == 'activate' || name == 'activated' + || name == 'deactivate' || name == 'deactivated'; + // Any event for a view will have an event payload with a view property indicating the view - // that is changing. Contained ViewManagers will also fire activate and deactivate events - // but we can't notify them because of method overlap. Also ignore events originating from - // contained ViewManagers (prefixed by manager-). - if (event && event.view && name.indexOf('manager-') !== 0 && !this.isManager(event.view)) { - if (utils.isFunction(event.view[name])) event.view[name](event); + // that is changing. + if (event && event.view && viewEvent && utils.isFunction(event.view[name])) { + event.view[name](event); } }, @@ -796,8 +806,13 @@ var ViewMgr = kind( view.set('canGenerate', true); view.render(); } - this.emitViewEvent('activate', view); - if (!this.dragging && !this.isManager(view)) this.set('active', view); + if (this.isManager(view)) { + view.emit('manage'); + } + else { + this.emitViewEvent('activate', view); + if (!this.dragging) this.set('active', view); + } }, /** @@ -837,7 +852,7 @@ var ViewMgr = kind( * @private */ isManager: function (view) { - return view && this.viewManagers[view.name]; + return view && !!this.viewManagers[view.name]; }, // Layout From d6de25fb837376c9ff5f865801a8e0dfa17a842b Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Tue, 20 Oct 2015 12:03:53 -0500 Subject: [PATCH 057/210] rework transition completion for ViewLayout Previously, transition completion was handled per-view so ViewLayout would fire its 'complete' event twice in most scenarios. Since ViewManager.direction to be reset when the first view transitioned, the event payload for the second view had an incorrect direction value. Furthermore, it doesn't make sense for 'complete' to fire until the entire transition is complete so it now monitors the state of both views' transition and only notifies when both are done. Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/SlideViewLayout/SlideViewLayout.js | 37 ++++++-------- src/TransitionViewLayout.js | 26 ++++++---- src/ViewLayout/ViewLayout.js | 69 ++++++++++++++++++++------ src/ViewManager/ViewManager.js | 27 ++++++---- 4 files changed, 100 insertions(+), 59 deletions(-) diff --git a/src/SlideViewLayout/SlideViewLayout.js b/src/SlideViewLayout/SlideViewLayout.js index 5667b99d5..d6c1e118a 100644 --- a/src/SlideViewLayout/SlideViewLayout.js +++ b/src/SlideViewLayout/SlideViewLayout.js @@ -65,7 +65,6 @@ module.exports = kind({ delta = event.delta, transform = isHorizontal ? 'translateX' : 'translateY'; - if (event.delta < 0 && event.delta < -size) { this.overDrag = true; delta = -size; @@ -93,7 +92,7 @@ module.exports = kind({ */ prepareTransition: function (was, is) { var c = this.container; - + TransitionViewLayout.prototype.prepareTransition.apply(this, arguments); if (is) this.addRemoveDirection(is, true); if (was) this.addRemoveDirection(was, true, true); @@ -110,6 +109,8 @@ module.exports = kind({ * @private */ transition: function (was, is) { + var dir; + TransitionViewLayout.prototype.transition.apply(this, arguments); if (was) { was.applyStyle('transform', null); @@ -122,14 +123,15 @@ module.exports = kind({ // If the user drags the entire view off screen, it won't animate so we won't see the CSS // transition event. if (this.overDrag) { - if (was) this.simulateTransition(was); - if (is) this.simulateTransition(is); + if (was) this.setTransitionComplete('from'); + if (is) this.setTransitionComplete('to'); } // when using layoutCover, one view doesn't transition so the ontransitionend doesn't fire // to account for that, set a timeout of the same duration to manually clean up. The // exception being when dismissing the ViewManager and there is no becoming-active view. else if (this.stationaryView) { - this.simulateTransition(this.stationaryView); + dir = this.getTransitionDirection(this.stationaryView); + if (dir) this.setTransitionComplete(dir); } }, @@ -138,24 +140,13 @@ module.exports = kind({ * * @private */ - completeTransition: function (view) { - TransitionViewLayout.prototype.completeTransition.apply(this, arguments); - if (view) { - this.addRemoveDirection(view, false, true); - if (this.stationaryView && this.stationaryView == view) { - this.stationaryView.removeClass('stationary'); - this.stationaryView = null; - } + completeTransition: function (was, is) { + if (is) this.addRemoveDirection(is, false); + if (was) this.addRemoveDirection(was, false, true); + if (this.stationaryView) { + this.stationaryView.removeClass('stationary'); + this.stationaryView = null; } - }, - - /** - * Calls completeTransition after the drag or normal duration in cases where a CSS transition - * will not have occurred. - * - * @private - */ - simulateTransition: function (view) { - setTimeout(this.completeTransition.bind(this, view), this.dragDuration || this.duration); + TransitionViewLayout.prototype.completeTransition.apply(this, arguments); } }); \ No newline at end of file diff --git a/src/TransitionViewLayout.js b/src/TransitionViewLayout.js index c8d9819ec..0d7f115f7 100644 --- a/src/TransitionViewLayout.js +++ b/src/TransitionViewLayout.js @@ -65,8 +65,14 @@ module.exports = kind({ */ transition: function (was, is) { ViewLayout.prototype.transition.apply(this, arguments); - if (was) this.applyTransitionDuration(was, this.dragDuration || this.duration); - if (is) this.applyTransitionDuration(is, this.dragDuration || this.duration); + if (was) { + was.addClass('transitioning'); + this.applyTransitionDuration(was, this.dragDuration || this.duration); + } + if (is) { + is.addClass('transitioning'); + this.applyTransitionDuration(is, this.dragDuration || this.duration); + } }, /** @@ -75,8 +81,10 @@ module.exports = kind({ * @private */ completeTransition: function (was, is) { - ViewLayout.prototype.completeTransition.apply(this, arguments); + if (was) was.removeClass('transitioning'); + if (is) is.removeClass('transitioning'); this.dragDuration = null; + ViewLayout.prototype.completeTransition.apply(this, arguments); }, /** @@ -98,15 +106,11 @@ module.exports = kind({ * @private */ handleTransitioned: function (sender, event) { - var view = event.originator; + var dir, + view = event.originator; if (view && view.container == this.container) { - - if (this.shouldAnimate()) { - rAF(this.completeTransition.bind(this, view)); - } else { - this.completeTransition(view); - } - + dir = this.getTransitionDirection(view); + if (dir) this.setTransitionComplete(dir); return true; } } diff --git a/src/ViewLayout/ViewLayout.js b/src/ViewLayout/ViewLayout.js index 5d127a69a..90d933e0b 100644 --- a/src/ViewLayout/ViewLayout.js +++ b/src/ViewLayout/ViewLayout.js @@ -52,6 +52,16 @@ module.exports = kind( this.container.observe('dragging', this.draggingChanged = this.draggingChanged.bind(this)); this.container.on('drag', this.handleDrag = this.handleDrag.bind(this)); this.container.on('cancelDrag', this.handleCancelDrag = this.handleCancelDrag.bind(this)); + this._transitioning = { + from: { + view: null, + complete: false + }, + to: { + view: null, + complete: false + } + }; }, /** @@ -93,8 +103,7 @@ module.exports = kind( } } else { this.transition(was, is); - if (was) this.completeTransition(was); - if (is) this.completeTransition(is); + this.completeTransition(was, is); } }, @@ -141,29 +150,61 @@ module.exports = kind( /** * @protected */ - prepareTransition: null, + prepareTransition: function (was, is) { + this.registerTransition(was, is); + }, /** * @protected */ transition: function (was, is) { this.container.removeClass('dragging'); - if (was) { - was.addClass('transitioning'); - was.removeClass('active'); - } - if (is) { - is.addClass('transitioning'); - is.addClass('active'); - } + if (was) was.removeClass('active'); + if (is) is.addClass('active'); }, /** * @protected */ - completeTransition: function (view) { - view.removeClass('transitioning'); - this.emit('complete', view); + completeTransition: function (was, is) { + this.emit('complete', { + was: was, + is: is + }); + }, + + /** + * @private + */ + registerTransition: function (was, is) { + var t = this._transitioning; + t.from.view = was; + t.from.complete = !was; + t.to.view = is; + t.to.complete = !is; + }, + + /** + * @private + */ + setTransitionComplete: function (dir, view) { + var t = this._transitioning; + + t[dir].complete = true; + if (t.from.complete && t.to.complete) { + this.completeTransition(t.from.view, t.to.view); + t.from.view = t.to.view = null; + t.from.complete = t.to.complete = false; + } + }, + + /** + * @private + */ + getTransitionDirection: function (view) { + return this._transitioning.from.view == view && 'from' || + this._transitioning.to.view == view && 'to' || + null; }, /** diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index cfaf92c68..7b5de7673 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -307,6 +307,15 @@ var ViewMgr = kind( */ draggable: true, + /** + * `true` when a drag gesture is in process + * + * @type {Boolean} + * @default false + * @private + */ + dragging: false, + /** * Percent a new view must be dragged into the viewport to be activated on drag release * @@ -861,13 +870,9 @@ var ViewMgr = kind( * Handles the 'complete' event from its layout indicating a view has completed its layout * @private */ - handleLayoutComplete: function (sender, name, view) { - if (view == this.active) { - this.emitViewEvent('activated', view); - } else { - // This is already within a rAF - this.deactivateImmediate(view); - } + handleLayoutComplete: function (sender, name, event) { + if (event.was) this.deactivateImmediate(event.was); + if (event.is) this.emitViewEvent('activated', event.is); this.direction = 0; }, @@ -890,7 +895,7 @@ var ViewMgr = kind( handleDragStart: function (sender, event) { if (!this.draggable || this.dismissed) return; this.set('dragging', 'start'); - this.dragDirection = 0; + this.direction = 0; this.dragView = null; this.dragBounds = this.getBounds(); @@ -918,8 +923,8 @@ var ViewMgr = kind( this.decorateDragEvent(event); if (this.canDrag(event.direction)) { // clean up on change of direction - if (this.dragDirection !== event.direction) { - this.dragDirection = event.direction; + if (this.direction !== event.direction) { + this.direction = event.direction; if (this.dragView) { this.emitViewEvent('deactivate', this.dragView); this.deactivate(this.dragView.name); @@ -935,7 +940,7 @@ var ViewMgr = kind( // there's a change of direction. `false` indicates that we've tried to activate a view // but there isn't one in that direction. if (this.dragView === null) { - if (this.dragDirection == 1) { + if (this.direction == 1) { this.dragView = this.next(); } else if (this.floating) { this.dragView = this.back(); From 4dc24349606613e8ae88c48e25025a3cf2b276ee Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Tue, 20 Oct 2015 12:08:08 -0500 Subject: [PATCH 058/210] allow customization of scrim in ScrimSupport Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ScrimSupport.js | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/ViewManager/ScrimSupport.js b/src/ViewManager/ScrimSupport.js index e6e28185b..15f2c49eb 100644 --- a/src/ViewManager/ScrimSupport.js +++ b/src/ViewManager/ScrimSupport.js @@ -1,16 +1,24 @@ var - kind = require('../kind'); + kind = require('../kind'), + utils = require('enyo/utils'); module.exports = { initComponents: kind.inherit(function (sup) { return function () { + var config = {name: 'scrim', classes: 'enyo-viewmanager-scrim enyo-fit'}; sup.apply(this, arguments); - this.createComponent({name: 'scrim', classes: 'enyo-viewmanager-scrim enyo-fit', isChrome: true}); - this.on('activate', function (sender, name, event) { - if (this.isManager(event.view)) this.$.scrim.addClass('showing'); + + // override defaults with user-provided scrimConfig + if (this.scrimConfig) utils.mixin(config, this.scrimConfig); + this.createComponent(config, {isChrome: true}); + + // monitor the relevant events to hide and show the scrim + // @todo - may need to monitor active manager counts + this.on('manager-manage', function (sender, name, event) { + this.$[config.name].addClass('showing'); }, this); this.on('manager-dismiss', function (sender, name, event) { - this.$.scrim.removeClass('showing'); + this.$[config.name].removeClass('showing'); }, this); }; }) From 001bc49d10354453c12ceaf4083fad8c1e9d1fc2 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Tue, 20 Oct 2015 14:03:44 -0500 Subject: [PATCH 059/210] fix jshint errors Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/TransitionViewLayout.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/TransitionViewLayout.js b/src/TransitionViewLayout.js index 0d7f115f7..75bd307c1 100644 --- a/src/TransitionViewLayout.js +++ b/src/TransitionViewLayout.js @@ -1,7 +1,5 @@ var - animation = require('enyo/animation'), - kind = require('enyo/kind'), - rAF = animation.requestAnimationFrame; + kind = require('enyo/kind'); var ViewLayout = require('./ViewLayout'); From 29468f2572dc662583766aeaacd85e37a5cbae98 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Tue, 20 Oct 2015 15:06:57 -0500 Subject: [PATCH 060/210] complete transitions when dragging starts during Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewLayout/ViewLayout.js | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/ViewLayout/ViewLayout.js b/src/ViewLayout/ViewLayout.js index 90d933e0b..df2b7e6e5 100644 --- a/src/ViewLayout/ViewLayout.js +++ b/src/ViewLayout/ViewLayout.js @@ -114,6 +114,12 @@ module.exports = kind( * @private */ draggingChanged: function (was, is) { + // if there's a transition in-progress, force it complete before dragging + if (is && this.isTransitioning()) { + this.setTransitionComplete('from'); + this.setTransitionComplete('to'); + } + rAF(function () { if (is) this.container.addClass('dragging'); }.bind(this)); @@ -173,6 +179,17 @@ module.exports = kind( }); }, + /** + * `true` if either transition is still incomplete + * + * @return {Boolean} + * @private + */ + isTransitioning: function () { + var t = this._transitioning; + return !t.from.complete || !t.to.complete; + }, + /** * @private */ @@ -191,7 +208,7 @@ module.exports = kind( var t = this._transitioning; t[dir].complete = true; - if (t.from.complete && t.to.complete) { + if (!this.isTransitioning()) { this.completeTransition(t.from.view, t.to.view); t.from.view = t.to.view = null; t.from.complete = t.to.complete = false; From 3c7b841a5be60336039ca83addaa294bed89b8a0 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Fri, 23 Oct 2015 15:04:56 -0500 Subject: [PATCH 061/210] add webkit prefixed transforms Issue: ENYO-2723 Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/SlideViewLayout/SlideViewLayout.js | 12 ++++++----- src/SlideViewLayout/SlideViewLayout.less | 26 ++++++++++++++---------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/SlideViewLayout/SlideViewLayout.js b/src/SlideViewLayout/SlideViewLayout.js index d6c1e118a..787e4b4f0 100644 --- a/src/SlideViewLayout/SlideViewLayout.js +++ b/src/SlideViewLayout/SlideViewLayout.js @@ -1,4 +1,5 @@ var + dom = require('enyo/dom'), kind = require('enyo/kind'); var @@ -78,10 +79,10 @@ module.exports = kind({ } TransitionViewLayout.prototype.drag.apply(this, arguments); - c.active.applyStyle('transform', transform + '(' + delta + 'px)'); + dom.transformValue(c.active, transform, delta + 'px'); if (c.dragView) { px = this.container.layoutCover ? 0 : size * event.direction + delta; - c.dragView.applyStyle('transform', transform + '(' + px + 'px)'); + dom.transformValue(c.dragView, transform, px + 'px'); } }, @@ -109,15 +110,16 @@ module.exports = kind({ * @private */ transition: function (was, is) { - var dir; + var dir, + transform = this.container.orientation == 'horizontal' ? 'translateX' : 'translateY'; TransitionViewLayout.prototype.transition.apply(this, arguments); if (was) { - was.applyStyle('transform', null); + dom.transformValue(was, transform, null); } if (is) { this.addRemoveDirection(is, false); - is.applyStyle('transform', null); + dom.transformValue(is, transform, null); } // If the user drags the entire view off screen, it won't animate so we won't see the CSS diff --git a/src/SlideViewLayout/SlideViewLayout.less b/src/SlideViewLayout/SlideViewLayout.less index 9babad03a..fb6ac46fb 100644 --- a/src/SlideViewLayout/SlideViewLayout.less +++ b/src/SlideViewLayout/SlideViewLayout.less @@ -1,25 +1,29 @@ .enyo-viewlayout-slide { + .pre(@prop, @val) { + -webkit-@{prop}: @val; + @{prop}: @val; + } > .enyo-view { - transform: translateX(-100%); - transition-property: none; - transition-timing-function: linear; + .pre(transform, translateX(-100%)); + .pre(transition-property, none); + .pre(transition-timing-function, linear); } &:not(.dragging) > .enyo-view.transitioning { - transition-property: transform; + .pre(transition-property, transform); will-change: transform; } &.horizontal > .enyo-view { - &.forward { transform: translateX(100%); } - &.back { transform: translateX(-100%); } - &.active { transform: translateX(0); } + &.forward { .pre(transform, translateX(100%)); } + &.back { .pre(transform, translateX(-100%)); } + &.active { .pre(transform, translateX(0)); } } &.vertical > .enyo-view { - &.forward { transform: translateY(-100%); } - &.back { transform: translateY(100%); } - &.active { transform: translateY(0); } + &.forward { .pre(transform, translateY(-100%)); } + &.back { .pre(transform, translateY(100%)); } + &.active { .pre(transform, translateY(0)); } } &.cover { @@ -29,7 +33,7 @@ // unless it's the stationary view which should always remain behind &.stationary { z-index: 0; - transform: translateX(0px); + .pre(transform, translateX(0px)); } } From 0a9f07f57b0355dafd97d9e3705dbe0fda8d7529 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Fri, 23 Oct 2015 15:08:22 -0500 Subject: [PATCH 062/210] support multiple calls to activate() in the same frame View activation is asynchronous (using rAF) so multiple calls to activate() in the same frame produced unexpected results and out of sync styling. For floating panels, the stack would only include the last view. For fixed panels, the direction could be incorrect if the penultimate activation was on the opposite side of the final activated view from the source view. Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 7b5de7673..335ccc3ca 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -607,6 +607,7 @@ var ViewMgr = kind( // but it might need to be created too if (view && !(view instanceof Control)) { view = this.views[index] = this.createComponent(view); + view.addClass('enyo-view'); } } @@ -785,11 +786,8 @@ var ViewMgr = kind( */ activate: function (viewName) { var view = this._activate(viewName); - if (view && !this.isManager(view)) { - if (this.active && this.floating) { - this.stack.unshift(this.active.name); - } - if (!this.direction) this.determineDirection(view); + if (view && !this.isManager(view) && this.active && this.floating) { + this.stack.unshift(this.active.name); } return view; @@ -802,7 +800,18 @@ var ViewMgr = kind( */ _activate: function (viewName) { var view = this.getView(viewName); - if (view) rAF(this.activateImmediate.bind(this, view)); + if (view) { + if (!this._toBeActivated) { + rAF(function () { + this.activateImmediate(this._toBeActivated); + this._toBeActivated = null; + }.bind(this)); + } + else if (this.floating && !this.isManager(view)) { + this.stack.unshift(this._toBeActivated.name); + } + this._toBeActivated = view; + } return view; }, @@ -819,6 +828,7 @@ var ViewMgr = kind( view.emit('manage'); } else { + if (!this.direction) this.determineDirection(view); this.emitViewEvent('activate', view); if (!this.dragging) this.set('active', view); } From c46abed60c98957a7c1dd684214f436f35970f9b Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Mon, 26 Oct 2015 12:35:39 -0500 Subject: [PATCH 063/210] reset drag state when dragging in an invalid direction Issue: ENYO-2714 Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 335ccc3ca..6468ac775 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -960,6 +960,10 @@ var ViewMgr = kind( this.dragView = this.dragView || false; } this.emit('drag', event); + } else { + // Reset the drag state when dragging in an invalid direction + this.dragView = null; + this.direction = 0; } return true; From 0c497bd457720ce606baab05ea0a9147453542b0 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Mon, 26 Oct 2015 13:38:04 -0500 Subject: [PATCH 064/210] add prefixed CSS for webkit transition Issue: ENYO-2723 Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/SlideViewLayout/SlideViewLayout.less | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SlideViewLayout/SlideViewLayout.less b/src/SlideViewLayout/SlideViewLayout.less index fb6ac46fb..8bb5331d5 100644 --- a/src/SlideViewLayout/SlideViewLayout.less +++ b/src/SlideViewLayout/SlideViewLayout.less @@ -10,8 +10,8 @@ } &:not(.dragging) > .enyo-view.transitioning { - .pre(transition-property, transform); - will-change: transform; + -webkit-transition-property: -webkit-transform; + transition-property: transform; } &.horizontal > .enyo-view { From f1b5512ab37ebc790696d9b3ebbe819aff22a08a Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Mon, 26 Oct 2015 14:53:12 -0500 Subject: [PATCH 065/210] refactor cancelDrag to enable cancelling from other paths Issue: ENYO-2714 Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 6468ac775..e492e3a7f 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -977,10 +977,10 @@ var ViewMgr = kind( handleDragFinish: function (sender, event) { if (!this.dragging || !this.draggable || this.dismissed) return; - this.set('dragging', false); this.decorateDragEvent(event); // if the view has been dragged far enough if (event.percentDelta * 100 > this.dragThreshold) { + this.set('dragging', false); // normally, there will be a becoming-active view to activate if (this.dragView) { // dragging for floating views can only be a back action so shift it off the stack @@ -995,16 +995,24 @@ var ViewMgr = kind( } // otherwise the drag was small enough to be cancelled else { - // Since we're restoring the active view, the navigation direction is the opposite of - // the drag direction. - this.direction = -event.direction; - this.emit('cancelDrag', event); + this.cancelDrag(); } event.preventTap(); return true; }, + /** + * @protected + */ + cancelDrag: function () { + this.set('dragging', false); + // Since we're restoring the active view, the navigation direction is the opposite of the + // drag direction. + this.direction = -this.direction; + this.emit('cancelDrag'); + }, + /** * Calculates and adds a few additional properties to the event to aid in logic in ViewManager * and ViewLayout From e6aa9ef50c9a99ce2604dd284576be832cd3e356 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Tue, 27 Oct 2015 09:53:36 -0500 Subject: [PATCH 066/210] properly clean up dragView Issue: ENYO-2714 Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index e492e3a7f..6556fc2a6 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -935,13 +935,10 @@ var ViewMgr = kind( // clean up on change of direction if (this.direction !== event.direction) { this.direction = event.direction; - if (this.dragView) { - this.emitViewEvent('deactivate', this.dragView); - this.deactivate(this.dragView.name); - this.dragView = null; - } - else if (this.dragView === false) { + if (this.dragView === false) { this.dragView = null; + } else { + this.resetDragView(); } } @@ -962,7 +959,7 @@ var ViewMgr = kind( this.emit('drag', event); } else { // Reset the drag state when dragging in an invalid direction - this.dragView = null; + this.resetDragView(); this.direction = 0; } @@ -1002,6 +999,19 @@ var ViewMgr = kind( return true; }, + /** + * Deactivates drag view and resets `dragView` + * + * @private + */ + resetDragView: function () { + if (this.dragView) { + this.emitViewEvent('deactivate', this.dragView); + this.deactivate(this.dragView.name); + this.dragView = null; + } + }, + /** * @protected */ From 73657c0d010b3960abadb2fa8bea5e551653301e Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Thu, 12 Nov 2015 07:30:46 -0600 Subject: [PATCH 067/210] clean up src Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 134 +++++++++++++++++---------------- 1 file changed, 69 insertions(+), 65 deletions(-) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 6556fc2a6..1b06471a9 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -224,39 +224,7 @@ var ViewMgr = kind( */ classes: 'enyo-viewmanager', - /** - * If `true`, this ViewManager 'floats' over its parent `manager` - * - * @type {Boolean} - * @default false - * @public - */ - floating: false, - - /** - * Active view - * - * @type {Control} - * @private - */ - active: null, - - /** - * Indicates the logical direction of a view activation. May be used by ViewLayouts to inform the - * direction of their animation - * - * @type {Number} - * @default 0 - * @private - */ - direction: 0, - - /** - * @private - */ - activeChanged: function (was, is) { - if (was) this.emitViewEvent('deactivate', was); - }, + // PUBLIC PROPERTIES /** * Determines if and how the default view is activated. The default view is either the first @@ -274,15 +242,6 @@ var ViewMgr = kind( */ activateDefault: 'auto', - /** - * `true` when this ViewManager has been dismissed - * - * @type {Boolean} - * @default false - * @private - */ - dismissed: false, - /** * Determines if the view can be dismissed by dragging. The ViewManager can be programmatically * dismissed via dismiss() regardless of the value of this property. If the ViewManager is the @@ -307,15 +266,6 @@ var ViewMgr = kind( */ draggable: true, - /** - * `true` when a drag gesture is in process - * - * @type {Boolean} - * @default false - * @private - */ - dragging: false, - /** * Percent a new view must be dragged into the viewport to be activated on drag release * @@ -326,20 +276,13 @@ var ViewMgr = kind( dragThreshold: 25, /** - * When `draggable`, this constrains the drag to this direction. + * If `true`, this ViewManager 'floats' over its parent `manager` * - * @type {String} - * @default horizontal + * @type {Boolean} + * @default false * @public */ - orientation: 'horizontal', - - /** - * During a drag, contains a reference to the becoming-active view - * - * @private - */ - dragView: null, + floating: false, /** * If created within another ViewManager, `manager` will maintain a reference to that @@ -352,6 +295,23 @@ var ViewMgr = kind( */ manager: null, + /** + * @private + */ + managerChanged: function (was, is) { + if (was) this.off('*', was.managerEvent); + if (is) this.on('*', is.managerEvent); + }, + + /** + * When `draggable`, this constrains the drag to this direction. + * + * @type {String} + * @default horizontal + * @public + */ + orientation: 'horizontal', + /** * The number of views managed by this ViewManager. This member is observable but should be * considered read-only. @@ -363,14 +323,58 @@ var ViewMgr = kind( */ viewCount: 0, + // PRIVATE PROPERTIES + /** + * Active view + * + * @type {Control} * @private */ - managerChanged: function (was, is) { - if (was) this.off('*', was.managerEvent); - if (is) this.on('*', is.managerEvent); + active: null, + + /** + * @private + */ + activeChanged: function (was, is) { + if (was) this.emitViewEvent('deactivate', was); }, + /** + * Indicates the logical direction of a view activation. May be used by ViewLayouts to inform the + * direction of their animation + * + * @type {Number} + * @default 0 + * @private + */ + direction: 0, + + /** + * `true` when this ViewManager has been dismissed + * + * @type {Boolean} + * @default false + * @private + */ + dismissed: false, + + /** + * `true` when a drag gesture is in process + * + * @type {Boolean} + * @default false + * @private + */ + dragging: false, + + /** + * During a drag, contains a reference to the becoming-active view + * + * @private + */ + dragView: null, + /** * @private */ From cb0dc38f6af286524bb87ed61a76f41eb0fcdd08 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Mon, 16 Nov 2015 14:57:00 -0600 Subject: [PATCH 068/210] add dismiss event when dragging VM Also add dragging property to distinguish between dismiss events Issue: PLAT-12048 Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 1b06471a9..a19d3453c 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -81,6 +81,7 @@ * [dragThreshold]{@link module:enyo/ViewManager~ViewManager#dragThreshold}. * * @event module:enyo/ViewManager~ViewManager#dismiss +* @property {Boolean} dragging `true` for when dismissing as a result of dragging * @public */ @@ -728,7 +729,7 @@ var ViewMgr = kind( this.direction = -1; this.set('active', null); this.set('dismissed', true); - this.emit('dismiss'); + this.emit('dismiss', {dragging: false}); this.stack = []; } }, @@ -955,6 +956,7 @@ var ViewMgr = kind( this.dragView = this.next(); } else if (this.floating) { this.dragView = this.back(); + if (!this.dragView) this.emit('dismiss', {dragging: true}); } else { this.dragView = this.previous(); } From 391aa7f9d19283ae442fc1e34f895d18cb68eaec Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Wed, 18 Nov 2015 16:49:48 -0600 Subject: [PATCH 069/210] use mixin instead of bubbleTarget to funnel events to ViewLayout Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewLayout/ViewLayout.js | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/ViewLayout/ViewLayout.js b/src/ViewLayout/ViewLayout.js index df2b7e6e5..412287dc3 100644 --- a/src/ViewLayout/ViewLayout.js +++ b/src/ViewLayout/ViewLayout.js @@ -6,6 +6,21 @@ var Layout = require('../Layout'), rAF = animation.requestAnimationFrame; +// In order to handle DOM events (e.g. ontransitionend), we need to inject ViewLayout into the event +// dispatch chain. Since we can't guarantee the usual event flow would pass through this, we +// override the default behavior to call ViewLayout's event hanlder via a mixin applied to the view +// when it is first setup +var ViewLayoutSupport = { + name: 'enyo.ViewLayoutSupport', + _viewLayout: null, + bubbleUp: kind.inherit(function (sup) { + return function (name, event, sender) { + if (this._viewLayout) this._viewLayout.handleViewEvent(name, event, sender); + return sup.apply(this, arguments); + }; + }) +}; + /** * Order of operations: * * `prepareTransition()` @@ -80,7 +95,8 @@ module.exports = kind( */ setupView: function (view) { if (view && !view.viewSetup) { - view.set('bubbleTarget', this); + view.extend(ViewLayoutSupport); + view._viewLayout = this; view.addClass(this.viewClass); view.viewSetup = true; } @@ -234,14 +250,8 @@ module.exports = kind( /** * @private */ - dispatchBubble: function (name, event, delegate) { + handleViewEvent: function (name, event, sender) { var handler = this.handlers && this.handlers[name]; - if (handler) { - if (this[handler](delegate, event)) { - return true; - } - } else { - return this.container.dispatchBubble(name, event, delegate); - } + if (handler) this[handler](sender, event); } }); \ No newline at end of file From 398b42ddf2263e742f337dd37180f2000171b0de Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Mon, 23 Nov 2015 14:20:03 -0600 Subject: [PATCH 070/210] add flick support to ViewManager Altered ViewManager.draggable to be either Boolean or a String to support draggable, flickable, both or neither. Issue: PLAT-12457 Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 80 +++++++++++++++++++++++++++++----- 1 file changed, 70 insertions(+), 10 deletions(-) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index a19d3453c..6228bd3af 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -259,9 +259,12 @@ var ViewMgr = kind( dismissable: 'auto', /** - * When `true`, the views can be dragged into and out of view. + * When `true`, the views can be dragged or flicked into and out of view. + * When `false`, the views cannot be dragged or flicked. + * When `drag`, the views can *only* be dragged and not flicked. + * When `flick`, the views can *only* be flicked and not dragged. * - * @type {Boolean} + * @type {Boolean|String} * @default true * @public */ @@ -376,6 +379,13 @@ var ViewMgr = kind( */ dragView: null, + /** + * + * + * @type {Boolean} + */ + flicked: false, + /** * @private */ @@ -390,6 +400,7 @@ var ViewMgr = kind( * @private */ handlers: { + onflick: 'handleFlick', ondown: 'handleDown', ondragstart: 'handleDragStart', ondrag: 'handleDrag', @@ -672,11 +683,16 @@ var ViewMgr = kind( }, /** + * Determines if the ViewManager can be dragged in the provided direction + * + * @param {Number} direction -1 or 1 indicating the direction of the drag + * @param {String} [mode] When provided, requires `draggable` be `true` or the provided value * @private */ - canDrag: function (direction) { - var index; - if (this.draggable) { + canDrag: function (direction, mode) { + var index, + check = mode ? this.draggable === true || this.draggable == mode : this.draggable; + if (check) { if (this.isDimissable() && direction == -1) { return true; } @@ -891,6 +907,37 @@ var ViewMgr = kind( this.direction = 0; }, + // Flick + + /** + * Flicks are handled by the drag system so here we only test if there was a valid flick and rely + * on the ondragfinish handler to actually act on the flick as if it were a completed drag. + * + * @private + */ + handleFlick: function (sender, event) { + var isHorizontal = this.orientation == 'horizontal', + dx = event.xVelocity, + dy = event.yVelocity, + adx = Math.abs(dx), + ady = Math.abs(dy), + direction = 0; + + // Set direction iff the primary flick direction matches the orientation + if (isHorizontal && adx > ady) { + direction = dx < 0 ? 1 : -1; + } + else if (!this.isHorizontal && ady > adx) { + direction = dy < 0 ? 1 : -1; + } + + // If we have a direction, are flickable, and flickable in that direction, indicate it + if (direction && this.canDrag(direction, 'flick')) { + this.flicked = true; + return true; + } + }, + // Draggable /** @@ -936,6 +983,8 @@ var ViewMgr = kind( } this.decorateDragEvent(event); + // Intentionally ignoring draggable mode here so dragView will reference the becoming-active + // view even if we are only supporting flick and not drag if (this.canDrag(event.direction)) { // clean up on change of direction if (this.direction !== event.direction) { @@ -982,7 +1031,7 @@ var ViewMgr = kind( this.decorateDragEvent(event); // if the view has been dragged far enough - if (event.percentDelta * 100 > this.dragThreshold) { + if (this.flicked || event.percentDelta * 100 > this.dragThreshold) { this.set('dragging', false); // normally, there will be a becoming-active view to activate if (this.dragView) { @@ -1000,6 +1049,7 @@ var ViewMgr = kind( else { this.cancelDrag(); } + this.flicked = false; event.preventTap(); return true; @@ -1037,11 +1087,21 @@ var ViewMgr = kind( */ decorateDragEvent: function (event) { var isHorizontal = this.orientation == 'horizontal', - size = isHorizontal ? this.dragBounds.width : this.dragBounds.height; - event.delta = isHorizontal ? event.dx : event.dy; + size = isHorizontal ? this.dragBounds.width : this.dragBounds.height, + delta = isHorizontal ? event.dx : event.dy; + // 'natural' touch causes us to invert the physical change - event.direction = event.delta < 0 ? 1 : -1; - event.percentDelta = 1 - (size - Math.abs(event.delta)) / size; + event.direction = delta < 0 ? 1 : -1; + + // if we're only flickable, we won't set the deltas to suppress the views moving until a + // flick is encountered. + if (this.canDrag(event.direction, 'drag')) { + event.delta = delta; + event.percentDelta = 1 - (size - Math.abs(event.delta)) / size; + } else { + event.delta = 0; + event.percentDelta = 0; + } } }); From de845d9909fcbbddd232ea5350acd86bd51604f8 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Mon, 23 Nov 2015 12:31:06 -0600 Subject: [PATCH 071/210] refine handling of view activation/deactivation during dragging Prevents resetting transform on the dragView which caused a visual jump when the view reset its position before transitioning offscreen. Resets dragging when a view is activated and correctly retains a to be tore down node until dragging completes. Issue: PLAT-12619 Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/SlideViewLayout/SlideViewLayout.js | 4 ++-- src/ViewLayout/ViewLayout.js | 6 +++--- src/ViewManager/ViewManager.js | 18 +++++++++++++++--- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/SlideViewLayout/SlideViewLayout.js b/src/SlideViewLayout/SlideViewLayout.js index 787e4b4f0..b5f5c8531 100644 --- a/src/SlideViewLayout/SlideViewLayout.js +++ b/src/SlideViewLayout/SlideViewLayout.js @@ -114,12 +114,12 @@ module.exports = kind({ transform = this.container.orientation == 'horizontal' ? 'translateX' : 'translateY'; TransitionViewLayout.prototype.transition.apply(this, arguments); - if (was) { + if (was && was != this.dragView) { dom.transformValue(was, transform, null); } if (is) { this.addRemoveDirection(is, false); - dom.transformValue(is, transform, null); + if (is != this.dragView) dom.transformValue(is, transform, null); } // If the user drags the entire view off screen, it won't animate so we won't see the CSS diff --git a/src/ViewLayout/ViewLayout.js b/src/ViewLayout/ViewLayout.js index 412287dc3..9f51768a5 100644 --- a/src/ViewLayout/ViewLayout.js +++ b/src/ViewLayout/ViewLayout.js @@ -70,11 +70,11 @@ module.exports = kind( this._transitioning = { from: { view: null, - complete: false + complete: true }, to: { view: null, - complete: false + complete: true } }; }, @@ -227,7 +227,7 @@ module.exports = kind( if (!this.isTransitioning()) { this.completeTransition(t.from.view, t.to.view); t.from.view = t.to.view = null; - t.from.complete = t.to.complete = false; + t.from.complete = t.to.complete = true; } }, diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 6228bd3af..f1066a948 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -341,7 +341,13 @@ var ViewMgr = kind( * @private */ activeChanged: function (was, is) { - if (was) this.emitViewEvent('deactivate', was); + if (was) { + if (this.dragging) { + this.set('dragging', false); + this.releaseDraggedView = was.retainNode(); + } + this.emitViewEvent('deactivate', was); + } }, /** @@ -881,8 +887,10 @@ var ViewMgr = kind( */ teardownView: function (view) { if (view.node && !view.persistent) { - view.node.remove(); - view.node = null; + if (!this.releaseDraggedView) { + view.node.remove(); + view.node = null; + } view.set('canGenerate', false); view.teardownRender(true); } @@ -1027,6 +1035,10 @@ var ViewMgr = kind( * @private */ handleDragFinish: function (sender, event) { + if (this.releaseDraggedView) { + this.releaseDraggedView(); + this.releaseDraggedView = null; + } if (!this.dragging || !this.draggable || this.dismissed) return; this.decorateDragEvent(event); From 51d83f53ceb6d8275c9d3e6500d1684b14f6217b Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Wed, 25 Nov 2015 15:52:07 -0600 Subject: [PATCH 072/210] add support for activation options Added opts parameter to several methods to allow one-time activation configuration (e.g. disabling animation for hiding a floating panel). Issue: PLAT-11951 Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewLayout/ViewLayout.js | 15 ++++++------ src/ViewManager/ViewManager.js | 43 ++++++++++++++++++++-------------- 2 files changed, 33 insertions(+), 25 deletions(-) diff --git a/src/ViewLayout/ViewLayout.js b/src/ViewLayout/ViewLayout.js index 9f51768a5..c1e788b57 100644 --- a/src/ViewLayout/ViewLayout.js +++ b/src/ViewLayout/ViewLayout.js @@ -109,15 +109,12 @@ module.exports = kind( this.setupView(is); if (this.shouldAnimate()) { - if (this.prepareTransition) { - rAF(function () { - this.prepareTransition(was, is); - rAF(this.transition.bind(this, was, is)); - }.bind(this)); - } else { + rAF(function () { + this.prepareTransition(was, is); rAF(this.transition.bind(this, was, is)); - } + }.bind(this)); } else { + this.prepareTransition(was, is); this.transition(was, is); this.completeTransition(was, is); } @@ -244,7 +241,9 @@ module.exports = kind( * @protected */ shouldAnimate: function () { - return this.container.generated && this.container.animated; + var opt = this.container.activationOptions, + animate = (opt && (opt.animate === false || opt.animate === true)) ? opt.animate : this.container.animate; + return this.container.generated && animate; }, /** diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index f1066a948..421ee9305 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -218,7 +218,7 @@ var ViewMgr = kind( /** * @private */ - animated: true, + animate: true, /** * @private @@ -639,30 +639,32 @@ var ViewMgr = kind( /** * Navigates to the next view based on order of definition or creation * + * @param {Object} [opts] Optional parameters to configure the activation * @return {module:enyo/Control~Control} Activated view * @public */ - next: function () { + next: function (opts) { var index = this.views.indexOf(this.active) + 1, view = this.views[index]; if (view) { this.direction = 1; - return this.activate(view.name); + return this.activate(view.name, opts); } }, /** * Navigates to the previous view based on order of definition or creation * + * @param {Object} [opts] Optional parameters to configure the activation * @return {module:enyo/Control~Control} Activated view * @public */ - previous: function () { + previous: function (opts) { var index = this.views.indexOf(this.active) - 1, view = this.views[index]; if (view) { this.direction = -1; - return this.activate(view.name); + return this.activate(view.name, opts); } }, @@ -670,10 +672,11 @@ var ViewMgr = kind( * If this is a floating ViewManager, navigates back `count` views from the stack. * * @param {Number} [count] Number of views to pop off the stack. Defaults to 1. + * @param {Object} [opts] Optional parameters to configure the deactivation * @return {module:enyo/Control~Control} Activated view * @public */ - back: function (count) { + back: function (count, opts) { var name, depth = this.stack.length; if (this.floating && depth > 0) { @@ -684,7 +687,7 @@ var ViewMgr = kind( name = this.stack.splice(0, count).pop(); } this.direction = -1; - return this._activate(name); + return this._activate(name, opts); } }, @@ -744,14 +747,16 @@ var ViewMgr = kind( * Dismisses a view manager. If this is a root (manager-less) view manager, it cannot be * dismissed. * + * @param {Object} [opts] Optional parameters to configure the deactivation * @public */ - dismiss: function () { + dismiss: function (opts) { if (this.manager) { this.direction = -1; - this.set('active', null); + this.set('activationOptions', opts); this.set('dismissed', true); this.emit('dismiss', {dragging: false}); + this.set('active', null); this.stack = []; } }, @@ -809,11 +814,13 @@ var ViewMgr = kind( * For floating ViewManagers, the view will be added to the stack and can be removed by `back()`. * * @param {String} viewName Name of the view to activate + * @param {Object} [opts] Optional parameters to configure the activation * @public */ - activate: function (viewName) { - var view = this._activate(viewName); - if (view && !this.isManager(view) && this.active && this.floating) { + activate: function (viewName, opts) { + var replace = !!(opts && opts.replace), + view = this._activate(viewName, opts); + if (!replace && view && !this.isManager(view) && this.active && this.floating) { this.stack.unshift(this.active.name); } @@ -825,18 +832,20 @@ var ViewMgr = kind( * * @private */ - _activate: function (viewName) { - var view = this.getView(viewName); + _activate: function (viewName, opts) { + var replace = !!(this.activationOptions && this.activationOptions.replace), + view = this.getView(viewName); if (view) { if (!this._toBeActivated) { rAF(function () { - this.activateImmediate(this._toBeActivated); + this.activateImmediate(this._toBeActivated, opts); this._toBeActivated = null; }.bind(this)); } - else if (this.floating && !this.isManager(view)) { + else if (!replace && this.floating && !this.isManager(view)) { this.stack.unshift(this._toBeActivated.name); } + this.set('activationOptions', opts); this._toBeActivated = view; } return view; @@ -845,7 +854,7 @@ var ViewMgr = kind( /** * @private */ - activateImmediate: function (view) { + activateImmediate: function (view, opts) { // render the activated view if not already if (this.generated && !view.generated) { view.set('canGenerate', true); From e5347a61edb200fe03767300a84a65cc63f41711 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Thu, 3 Dec 2015 09:34:15 -0600 Subject: [PATCH 073/210] prevent setting dragging when not really dragging Issue: PLAT-13424 Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 421ee9305..efedaf7ba 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -988,6 +988,7 @@ var ViewMgr = kind( */ handleDrag: function (sender, event) { if (!this.dragging || !this.draggable || this.dismissed) return; + this.decorateDragEvent(event); // check direction against orientation to ignore drags that don't apply to this. the check // should only be necessary for the first drag event so it's further guarded by the special @@ -995,14 +996,12 @@ var ViewMgr = kind( if (this.dragging == 'start' && !event[this.orientation]) { this.set('dragging', false); return; - } else { - this.set('dragging', true); } - - this.decorateDragEvent(event); // Intentionally ignoring draggable mode here so dragView will reference the becoming-active // view even if we are only supporting flick and not drag - if (this.canDrag(event.direction)) { + else if (this.canDrag(event.direction)) { + this.set('dragging', true); + // clean up on change of direction if (this.direction !== event.direction) { this.direction = event.direction; From e4d9d1f26b0bebcd08da4ab56c21e25b925384dc Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Fri, 4 Dec 2015 13:27:09 -0600 Subject: [PATCH 074/210] prevent cancelDrag events for invalid drags We always get the dragStart event but if the subsequent drags are not valid (e.g. there's only 1 view so dragging in any direction is invalid), we'd still fire cancelDrag. Preventing that by requiring dragging to be strictly true. Issue: PLAT-13424 Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewLayout/ViewLayout.js | 2 +- src/ViewManager/ViewManager.js | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/ViewLayout/ViewLayout.js b/src/ViewLayout/ViewLayout.js index c1e788b57..f8b0a7149 100644 --- a/src/ViewLayout/ViewLayout.js +++ b/src/ViewLayout/ViewLayout.js @@ -134,7 +134,7 @@ module.exports = kind( } rAF(function () { - if (is) this.container.addClass('dragging'); + if (is === true) this.container.addClass('dragging'); }.bind(this)); }, diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index efedaf7ba..62073b7a7 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -1092,11 +1092,15 @@ var ViewMgr = kind( * @protected */ cancelDrag: function () { + var was = this.dragging; this.set('dragging', false); - // Since we're restoring the active view, the navigation direction is the opposite of the - // drag direction. - this.direction = -this.direction; - this.emit('cancelDrag'); + // only emit cancelDrag if a valid drag was encountered (=== true and != 'start') + if (was === true) { + // Since we're restoring the active view, the navigation direction is the opposite of the + // drag direction. + this.direction = -this.direction; + this.emit('cancelDrag'); + } }, /** From cbedbaf6159591fa9f99d4b3a483e4325f0ceaf3 Mon Sep 17 00:00:00 2001 From: Aaron Tam Date: Mon, 14 Dec 2015 14:20:19 -0800 Subject: [PATCH 075/210] ENYO-2913: Prevent concurrent transitions when setupTransitions is triggered via an index change or animateTo call. Enyo-DCO-1.1-Signed-off-by: Aaron Tam --- src/LightPanels/LightPanels.js | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/LightPanels/LightPanels.js b/src/LightPanels/LightPanels.js index f0ce6b1a7..d6f3c3e76 100644 --- a/src/LightPanels/LightPanels.js +++ b/src/LightPanels/LightPanels.js @@ -729,17 +729,16 @@ module.exports = kind( currPanel = this._currentPanel, shiftCurrent, fnInitiateTransition; - this._indexDirection = 0; - - // handle the wrapping case - if (this.wrap) { - if (this.index === 0 && previousIndex == panels.length - 1) this._indexDirection = 1; - else if (this.index === panels.length - 1 && previousIndex === 0) this._indexDirection = -1; - } - if (this._indexDirection === 0 && previousIndex != -1) this._indexDirection = this.index - previousIndex; - - if (nextPanel) { + if (nextPanel && !this.transitioning) { this.transitioning = true; + this._indexDirection = 0; + + // handle the wrapping case + if (this.wrap) { + if (this.index === 0 && previousIndex == panels.length - 1) this._indexDirection = 1; + else if (this.index === panels.length - 1 && previousIndex === 0) this._indexDirection = -1; + } + if (this._indexDirection === 0 && previousIndex != -1) this._indexDirection = this.index - previousIndex; // prepare the panel that will be deactivated if (currPanel) { From 365910c73497e2dd61f43b9d87f84fa6b2a1986c Mon Sep 17 00:00:00 2001 From: Roy Sutton Date: Fri, 18 Dec 2015 14:17:32 -0800 Subject: [PATCH 076/210] ENYO-2917 Document wip modules/kinds Enyo-DCO-1.1-Signed-off-by: Roy Sutton --- src/BackgroundTaskManager.js | 1 + src/FluxDispatcher.js | 1 + src/FluxStore.js | 1 + src/LightPanels/LightPanels.js | 2 ++ src/NewAnimator.js | 16 ++++++++++++++++ src/NewDataList.js | 17 ++++++++++++++++- src/NewDrawer/NewDrawer.js | 19 ++++++++++++++++++- src/NewThumb/NewThumb.js | 3 +++ src/PriorityQueue.js | 2 ++ src/SystemMonitor.js | 1 + src/TaskManagerSupport.js | 6 +++++- src/ViewPreloadSupport.js | 2 ++ 12 files changed, 68 insertions(+), 3 deletions(-) diff --git a/src/BackgroundTaskManager.js b/src/BackgroundTaskManager.js index 58fa189c6..039e21c89 100644 --- a/src/BackgroundTaskManager.js +++ b/src/BackgroundTaskManager.js @@ -2,6 +2,7 @@ require('enyo'); /** * Returns the BackgroundTaskManager singleton. +* @wip * @module enyo/BackgroundTaskManager */ diff --git a/src/FluxDispatcher.js b/src/FluxDispatcher.js index e56aac955..723eea776 100644 --- a/src/FluxDispatcher.js +++ b/src/FluxDispatcher.js @@ -1,5 +1,6 @@ /** * Returns the FluxDispatcher singleton. +* @wip * @module enyo/FluxDispatcher */ diff --git a/src/FluxStore.js b/src/FluxStore.js index 57ac44915..224c8f281 100644 --- a/src/FluxStore.js +++ b/src/FluxStore.js @@ -1,5 +1,6 @@ /** * Contains the declaration for the {@link module:enyo/FluxStore~FluxStore} kind. +* @wip * @module enyo/FluxStore */ diff --git a/src/LightPanels/LightPanels.js b/src/LightPanels/LightPanels.js index f0ce6b1a7..7b97dc3ff 100644 --- a/src/LightPanels/LightPanels.js +++ b/src/LightPanels/LightPanels.js @@ -2,6 +2,7 @@ require('enyo'); /** * Contains the declaration for the {@link module:enyo/LightPanels~LightPanels} kind. +* @wip * @module enyo/LightPanels */ @@ -68,6 +69,7 @@ var Orientation = { * @extends module:enyo/Control~Control * @mixes module:enyo/TaskManagerSupport~TaskManagerSupport * @mixes module:enyo/ViewPreloadSupport~ViewPreloadSupport +* @wip * @ui * @public */ diff --git a/src/NewAnimator.js b/src/NewAnimator.js index 139cb7e51..3d7a1d05a 100644 --- a/src/NewAnimator.js +++ b/src/NewAnimator.js @@ -1,3 +1,10 @@ +/** +* Contains the declaration for the {@link module:enyo/NewAnimator~NewAnimator} kind. +* @wip +* @private +* @module enyo/NewAnimator +*/ + require('enyo'); var @@ -8,7 +15,16 @@ var CoreObject = require('./CoreObject'), Loop = require('./Loop'); +/** +* {@link module:enyo/NewAnimator~NewAnimator} is a work-in-progress +* +* @class NewAnimator +* @extends module:enyo/CoreObject~Object +* @wip +* @private +*/ module.exports = kind.singleton({ + /** @lends module:enyo/NewAnimator~NewAnimator.prototype */ { name: 'enyo.NewAnimator', kind: CoreObject, animate: function(fn, duration) { diff --git a/src/NewDataList.js b/src/NewDataList.js index eb44b0767..aaf933637 100644 --- a/src/NewDataList.js +++ b/src/NewDataList.js @@ -1,3 +1,9 @@ +/** +* Contains the declaration for the {@link module:enyo/NewDataList~NewDataList} kind. +* @wip +* @module enyo/NewDataList +*/ + require('enyo'); var @@ -8,7 +14,16 @@ var Scrollable = require('./Scrollable'), VirtualDataRepeater = require('./VirtualDataRepeater'); -module.exports = kind({ +/** +* {@link module:enyo/NewDataList~NewDataList} is a work-in-progress +* +* @class NewDataList +* @extends module:enyo/VirtualDataRepeater~VirtualDataRepeater +* @wip +* @ui +*/ +module.exports = kind( + /** @lends module:enyo/NewDataList~NewDataList.prototype */ { name: 'enyo.NewDataList', kind: VirtualDataRepeater, direction: 'vertical', diff --git a/src/NewDrawer/NewDrawer.js b/src/NewDrawer/NewDrawer.js index 0b9a1d22c..70085a0c2 100644 --- a/src/NewDrawer/NewDrawer.js +++ b/src/NewDrawer/NewDrawer.js @@ -1,3 +1,10 @@ +/** +* Contains the declaration for the {@link module:enyo/NewDrawer~NewDrawer} kind. +* @wip +* @private +* @module enyo/NewDrawer +*/ + require('enyo'); var @@ -8,7 +15,17 @@ var Control = require('../Control'), NewAnimator = require('../NewAnimator'); -module.exports = kind({ +/** +* {@link module:enyo/NewDrawer~NewDrawer} is a work-in-progress +* +* @class NewDrawer +* @extends module:enyo/Control~Control +* @wip +* @private +* @ui +*/ +module.exports = kind( + /** @lends module:enyo/NewDrawer~NewDrawer.prototype */ { name: 'enyo.NewDrawer', kind: Control, classes: 'enyo-new-drawer', diff --git a/src/NewThumb/NewThumb.js b/src/NewThumb/NewThumb.js index 7e1f0c74b..8b461a5e9 100644 --- a/src/NewThumb/NewThumb.js +++ b/src/NewThumb/NewThumb.js @@ -2,6 +2,7 @@ require('enyo'); /** * Contains the declaration for the {@link module:enyo/NewThumb~NewThumb} kind. +* @wip * @module enyo/NewThumb */ @@ -22,6 +23,8 @@ var * `enyo/NewThumb` is not typically created in application code. * * @class NewThumb +* @extends module:enyo/Control~Control +* @wip * @protected */ module.exports = kind( diff --git a/src/PriorityQueue.js b/src/PriorityQueue.js index 752ba4818..6efa5e9a1 100644 --- a/src/PriorityQueue.js +++ b/src/PriorityQueue.js @@ -2,6 +2,7 @@ require('enyo'); /** * Exports Priority options used by {@link module:enyo/BackgroundTaskManager}. +* @wip * @module enyo/PriorityQueue */ @@ -48,6 +49,7 @@ var Priorities = { /** * @class PriorityQueue +* @wip * @public */ module.exports = exports = kind( diff --git a/src/SystemMonitor.js b/src/SystemMonitor.js index 7e5564f09..f3fb399e3 100644 --- a/src/SystemMonitor.js +++ b/src/SystemMonitor.js @@ -2,6 +2,7 @@ require('enyo'); /** * Returns the SystemMonitor singleton +* @wip * @module enyo/SystemMonitor */ diff --git a/src/TaskManagerSupport.js b/src/TaskManagerSupport.js index f7c8516db..38fd7f3ff 100644 --- a/src/TaskManagerSupport.js +++ b/src/TaskManagerSupport.js @@ -1,5 +1,6 @@ /** * Exports the {@link module:enyo/TaskManagerSupport~TaskManagerSupport} mixin +* @wip * @module enyo/TaskManagerSupport */ @@ -14,7 +15,10 @@ var Priorities = PriorityQueue.Priorities, BackgroundTaskManager = require('./BackgroundTaskManager'); -/** @mixin */ +/** +* @mixin +* @wip +*/ var TaskManagerSupport = { /** diff --git a/src/ViewPreloadSupport.js b/src/ViewPreloadSupport.js index 4e0d0059f..a5054dd36 100644 --- a/src/ViewPreloadSupport.js +++ b/src/ViewPreloadSupport.js @@ -1,5 +1,6 @@ /** * Exports the {@link module:enyo/ViewPreloadSupport~ViewPreloadSupport} mixin +* @wip * @module enyo/ViewPreloadSupport */ var @@ -14,6 +15,7 @@ var * A {@glossary mixin} used for preloading views. * * @mixin +* @wip * @private */ var ViewPreloadSupport = { From 0420403c7acc8392148a6e0d268ab0df951148e1 Mon Sep 17 00:00:00 2001 From: Roy Sutton Date: Fri, 18 Dec 2015 15:49:45 -0800 Subject: [PATCH 077/210] ENYO-2917 Document wip modules/kinds Enyo-DCO-1.1-Signed-off-by: Roy Sutton --- src/LightPanels/LightPanel.js | 4 +++- src/NewAnimator.js | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/LightPanels/LightPanel.js b/src/LightPanels/LightPanel.js index fe334da90..564d75bb8 100644 --- a/src/LightPanels/LightPanel.js +++ b/src/LightPanels/LightPanel.js @@ -1,5 +1,6 @@ /** * Contains the declaration for the {@link module:enyo/LightPanels~LightPanel} kind. +* @wip * @module enyo/LightPanels */ @@ -30,6 +31,7 @@ var States = { * @class LightPanel * @extends module:enyo/Control~Control * @ui +* @wip * @public */ module.exports = kind( @@ -70,4 +72,4 @@ module.exports = kind( }); -module.exports.States = States; \ No newline at end of file +module.exports.States = States; diff --git a/src/NewAnimator.js b/src/NewAnimator.js index 3d7a1d05a..ab94de1b3 100644 --- a/src/NewAnimator.js +++ b/src/NewAnimator.js @@ -23,7 +23,7 @@ var * @wip * @private */ -module.exports = kind.singleton({ +module.exports = kind.singleton( /** @lends module:enyo/NewAnimator~NewAnimator.prototype */ { name: 'enyo.NewAnimator', kind: CoreObject, From e0a69ca579abeae205080e81a099fe5aaf5e0c63 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Mon, 21 Dec 2015 13:57:03 -0600 Subject: [PATCH 078/210] remove prototype ViewLayouts and mark VM kinds as WIP Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/CardViewLayout/CardViewLayout.js | 39 ------------------ src/CardViewLayout/CardViewLayout.less | 14 ------- src/CardViewLayout/package.json | 6 --- .../LeftRightViewLayout.js | 41 ------------------- .../LeftRightViewLayout.less | 16 -------- src/LeftRightViewLayout/package.json | 6 --- src/TransitionViewLayout.js | 7 ++++ src/ViewLayout/ViewLayout.js | 8 ++++ src/ViewManager/ViewManager.js | 2 + 9 files changed, 17 insertions(+), 122 deletions(-) delete mode 100644 src/CardViewLayout/CardViewLayout.js delete mode 100644 src/CardViewLayout/CardViewLayout.less delete mode 100644 src/CardViewLayout/package.json delete mode 100644 src/LeftRightViewLayout/LeftRightViewLayout.js delete mode 100644 src/LeftRightViewLayout/LeftRightViewLayout.less delete mode 100644 src/LeftRightViewLayout/package.json diff --git a/src/CardViewLayout/CardViewLayout.js b/src/CardViewLayout/CardViewLayout.js deleted file mode 100644 index b4559fc58..000000000 --- a/src/CardViewLayout/CardViewLayout.js +++ /dev/null @@ -1,39 +0,0 @@ -var - kind = require('enyo/kind'); - -var - TransitionViewLayout = require('../TransitionViewLayout'); - -module.exports = kind({ - - /** - * @private - */ - kind: TransitionViewLayout, - - /** - * @private - */ - layoutClass: 'enyo-viewlayout enyo-viewlayout-card', - - /** - * @private - */ - drag: function (event) { - var c = this.container, - delta = (event.percentDelta < -1 || event.percentDelta > 1) && 1 || - Math.abs(event.percentDelta); - TransitionViewLayout.prototype.drag.apply(this, arguments); - c.active.applyStyle('opacity', 1 - delta); - if (c.dragView) c.dragView.applyStyle('opacity', delta); - }, - - /** - * @private - */ - transition: function (was, is) { - TransitionViewLayout.prototype.transition.apply(this, arguments); - if (was) was.applyStyle('opacity', null); - if (is) is.applyStyle('opacity', null); - } -}); \ No newline at end of file diff --git a/src/CardViewLayout/CardViewLayout.less b/src/CardViewLayout/CardViewLayout.less deleted file mode 100644 index 2a935e2b5..000000000 --- a/src/CardViewLayout/CardViewLayout.less +++ /dev/null @@ -1,14 +0,0 @@ -.enyo-viewlayout-card { - &:not(.dragging) > .enyo-view.transitioning { - transition-property: opacity; - will-change: opacity; - } - - > .enyo-view { - transition-property: none; - opacity: 0; - &.active { - opacity: 1; - } - } -} \ No newline at end of file diff --git a/src/CardViewLayout/package.json b/src/CardViewLayout/package.json deleted file mode 100644 index c41813ab1..000000000 --- a/src/CardViewLayout/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "main": "CardViewLayout.js", - "styles": [ - "CardViewLayout.less" - ] -} \ No newline at end of file diff --git a/src/LeftRightViewLayout/LeftRightViewLayout.js b/src/LeftRightViewLayout/LeftRightViewLayout.js deleted file mode 100644 index 5c148de7a..000000000 --- a/src/LeftRightViewLayout/LeftRightViewLayout.js +++ /dev/null @@ -1,41 +0,0 @@ -var - kind = require('enyo/kind'); - -var - TransitionViewLayout = require('../TransitionViewLayout'); - -module.exports = kind({ - - /** - * @private - */ - kind: TransitionViewLayout, - - /** - * @private - */ - layoutClass: 'enyo-viewlayout enyo-viewlayout-leftright', - - /** - * @private - */ - drag: function (event) { - var c = this.container, - node = c.hasNode(), - size = node.clientWidth, - delta = Math.min(size, Math.abs(event.delta)); - - TransitionViewLayout.prototype.drag.apply(this, arguments); - c.active.applyStyle('transform', 'translateX(' + delta + 'px)'); - if (c.dragView) c.dragView.applyStyle('transform', 'translateX(' + (size - delta) + 'px)'); - }, - - /** - * @private - */ - transition: function (was, is) { - TransitionViewLayout.prototype.transition.apply(this, arguments); - if (was) was.applyStyle('transform', null); - if (is) is.applyStyle('transform', null); - } -}); \ No newline at end of file diff --git a/src/LeftRightViewLayout/LeftRightViewLayout.less b/src/LeftRightViewLayout/LeftRightViewLayout.less deleted file mode 100644 index 81ed87795..000000000 --- a/src/LeftRightViewLayout/LeftRightViewLayout.less +++ /dev/null @@ -1,16 +0,0 @@ -.enyo-viewlayout-leftright { - - &:not(.dragging) > .enyo-view.transitioning { - transition-property: transform; - will-change: transform; - } - - > .enyo-view { - transition-property: none; - transform: translateX(100%); - &.active { - transform: translateX(0); - } - } - -} \ No newline at end of file diff --git a/src/LeftRightViewLayout/package.json b/src/LeftRightViewLayout/package.json deleted file mode 100644 index 6de288e11..000000000 --- a/src/LeftRightViewLayout/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "main": "LeftRightViewLayout.js", - "styles": [ - "LeftRightViewLayout.less" - ] -} \ No newline at end of file diff --git a/src/TransitionViewLayout.js b/src/TransitionViewLayout.js index 75bd307c1..b16f4a1f6 100644 --- a/src/TransitionViewLayout.js +++ b/src/TransitionViewLayout.js @@ -1,3 +1,8 @@ +/** +* @module enyo/TransitionViewLayout +* @wip +*/ + var kind = require('enyo/kind'); @@ -23,6 +28,8 @@ var * Removes the directional classes and resets the `dragDuration` * * @class enyo.SlideViewLayout +* @public +* @wip */ module.exports = kind({ /** diff --git a/src/ViewLayout/ViewLayout.js b/src/ViewLayout/ViewLayout.js index f8b0a7149..1073b3ab3 100644 --- a/src/ViewLayout/ViewLayout.js +++ b/src/ViewLayout/ViewLayout.js @@ -1,3 +1,9 @@ + +/** +* @module enyo/ViewLayout +* @wip +*/ + var animation = require('../animation'), kind = require('../kind'), @@ -33,6 +39,8 @@ var ViewLayoutSupport = { * Removes the `transitioning` class and deactivates the now inactive view. * * @class enyo.ViewLayout +* @public +* @wip */ module.exports = kind( /** @lends enyo.ViewLayout.prototype */ { diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 62073b7a7..50250417f 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -2,6 +2,7 @@ * ViewManager module * * @module enyo/ViewManager +* @wip */ /** @@ -196,6 +197,7 @@ var viewCount = 0; * @extends module:enyo/Control~Control * @ui * @public +* @wip */ var ViewMgr = kind( /** @lends module:enyo/ViewManager~ViewManager.prototype */ { From 990324de3262ac125358c9cfbedfe991ed6991de Mon Sep 17 00:00:00 2001 From: Roy Sutton Date: Tue, 29 Dec 2015 13:10:13 -0800 Subject: [PATCH 079/210] ENYO-2904 Add glossary entries for private/protected Enyo-DCO-1.1-Signed-off-by: Roy Sutton --- docs/external.jsdoc | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/docs/external.jsdoc b/docs/external.jsdoc index 32bfdb9cb..38d0f28f8 100644 --- a/docs/external.jsdoc +++ b/docs/external.jsdoc @@ -153,11 +153,27 @@ * @glossary computed_property */ +/** +* Methods and properties marked as private should not be used by developers. They may be changed or +* removed without notice and their particular implementations should not be relied upon. Kinds and +* modules marked as private are inteded for use only by the framework. +* +* @glossary private +*/ + +/** +* Methods and properties marked as protected should only be used when subclassing a kind. They +* represent the internal workings of a kind and should not be used by outside kinds. Protected kinds +* and modules are not intended to be instantiated directly by developers. +* +* @glossary protected +*/ + ///// Internally Documented Links (Glossary) ///// /** * Binary (bitwise) operations. -* +* * @glossary bitwise * @see http://www.experts-exchange.com/Programming/Misc/A_1842-Binary-Bit-Flags-Tutorial-and-Usage-Tips.html * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators @@ -166,7 +182,7 @@ /** * Strict Equality. This comparison logic ensures not only that the value of the things being * compared is the same, but also their types. -* +* * @glossary === * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Using_the_Equality_Operators */ @@ -176,25 +192,26 @@ * that don't support a native version of said method, in an effort to bring the * browser up to the standards of modern browsers. This allows code that expects * a modern browser to work properly in an older one. -* +* * @glossary polyfill * @see http://en.wikipedia.org/wiki/Polyfill */ /** * The Document Object Model (DOM) is a programming interface for HTML and XML documents. +* * @glossary DOM * @see https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model */ +///// Externally Documented Links ///// + /** * Inheritance * @glossary inheritance * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain */ -///// Externally Documented Links ///// - /** * Universally Unique Identifier * @glossary UUID From f85d4668416bea5b8da59dc5409d25bacc4ac3a0 Mon Sep 17 00:00:00 2001 From: Roy Sutton Date: Tue, 29 Dec 2015 16:23:18 -0800 Subject: [PATCH 080/210] ENYO-2964 Fix mixin declarations Enyo-DCO-1.1-Signed-off-by: Roy Sutton --- src/StylesheetSupport.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/StylesheetSupport.js b/src/StylesheetSupport.js index 7370fe900..c25bb85a6 100644 --- a/src/StylesheetSupport.js +++ b/src/StylesheetSupport.js @@ -1,5 +1,5 @@ /** -* Exports the {@link module:enyo/StylesheetSupport} mixin. +* Exports the {@link module:enyo/StylesheetSupport~StylesheetSupport} mixin. * @module enyo/StylesheetSupport */ @@ -12,7 +12,7 @@ var Style = require('./Style'); /** -* The {@link module:enyo/StylesheetSupport} {@glossary mixin} is used to add a +* The {@link module:enyo/StylesheetSupport~StylesheetSupport} {@glossary mixin} is used to add a * "side-car" inline stylesheet to a [control]{@link module:enyo/Control~Control}, specifically * for procedurally-generated CSS that can't live in the more appropriate * location (i.e., in a CSS/LESS file). @@ -20,7 +20,7 @@ var * @mixin * @public */ -module.exports = { +var StylesheetSupport = { /** * @private @@ -101,3 +101,5 @@ module.exports = { return this.getId() + this._stylesheet_id_suffix; } }; + +module.exports = StylesheetSupport; From 276287107233cb8667b09dbe859335d16ecf3b0a Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Wed, 30 Dec 2015 12:39:48 -0600 Subject: [PATCH 081/210] add drag event validation to ViewManager.handleDragFinish() If a drag is brief enough, we might only see a dragstart and dragfinish thereby skipping the validation logic in handleDrag(). Refactoring that logic out into a method so it can be called from both handlers. Issue: PLAT-14490 Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 92 +++++++++++++++++++--------------- 1 file changed, 52 insertions(+), 40 deletions(-) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 50250417f..34a36ac6f 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -989,21 +989,7 @@ var ViewMgr = kind( * @private */ handleDrag: function (sender, event) { - if (!this.dragging || !this.draggable || this.dismissed) return; - this.decorateDragEvent(event); - - // check direction against orientation to ignore drags that don't apply to this. the check - // should only be necessary for the first drag event so it's further guarded by the special - // 'start' value of dragging. - if (this.dragging == 'start' && !event[this.orientation]) { - this.set('dragging', false); - return; - } - // Intentionally ignoring draggable mode here so dragView will reference the becoming-active - // view even if we are only supporting flick and not drag - else if (this.canDrag(event.direction)) { - this.set('dragging', true); - + if (this.validateDrag(event)) { // clean up on change of direction if (this.direction !== event.direction) { this.direction = event.direction; @@ -1030,13 +1016,13 @@ var ViewMgr = kind( this.dragView = this.dragView || false; } this.emit('drag', event); + + return true; } else { // Reset the drag state when dragging in an invalid direction this.resetDragView(); this.direction = 0; } - - return true; }, /** @@ -1049,32 +1035,31 @@ var ViewMgr = kind( this.releaseDraggedView(); this.releaseDraggedView = null; } - if (!this.dragging || !this.draggable || this.dismissed) return; - - this.decorateDragEvent(event); - // if the view has been dragged far enough - if (this.flicked || event.percentDelta * 100 > this.dragThreshold) { - this.set('dragging', false); - // normally, there will be a becoming-active view to activate - if (this.dragView) { - // dragging for floating views can only be a back action so shift it off the stack - if (this.floating) this.stack.shift(); - // stack updates aren't necessary as we updated it above - this.activateImmediate(this.dragView); + if (this.validateDrag(event)) { + // if the view has been dragged far enough + if (this.flicked || event.percentDelta * 100 > this.dragThreshold) { + this.set('dragging', false); + // normally, there will be a becoming-active view to activate + if (this.dragView) { + // dragging for floating views can only be a back action so shift it off the stack + if (this.floating) this.stack.shift(); + // stack updates aren't necessary as we updated it above + this.activateImmediate(this.dragView); + } + // unless it's a floating ViewManager that is being dismissed + else if (this.isDimissable() && event.direction == -1) { + this.dismiss(); + } } - // unless it's a floating ViewManager that is being dismissed - else if (this.isDimissable() && event.direction == -1) { - this.dismiss(); + // otherwise the drag was small enough to be cancelled + else { + this.cancelDrag(); } - } - // otherwise the drag was small enough to be cancelled - else { - this.cancelDrag(); - } - this.flicked = false; - event.preventTap(); + this.flicked = false; + event.preventTap(); - return true; + return true; + } }, /** @@ -1105,6 +1090,33 @@ var ViewMgr = kind( } }, + /** + * Validates that the drag event should be processed + * + * @private + */ + validateDrag: function (event) { + var dragging = false, + draggable = this.dragging && this.draggable && !this.dismissed; + + if (draggable) { + this.decorateDragEvent(event); + dragging = + // check direction against orientation to ignore drags that don't apply to this. the + // check should only be necessary for the first drag event so it's further guarded + // by the special 'start' value of dragging. + !(this.dragging == 'start' && !event[this.orientation]) && + + // Intentionally ignoring draggable mode here so dragView will reference the + // becoming-active view even if we are only supporting flick and not drag + this.canDrag(event.direction); + + this.set('dragging', dragging); + } + + return draggable && dragging; + }, + /** * Calculates and adds a few additional properties to the event to aid in logic in ViewManager * and ViewLayout From 4989bb2f700f8945d02598afafacf7e3007e4911 Mon Sep 17 00:00:00 2001 From: Aaron Tam Date: Wed, 30 Dec 2015 17:39:07 -0800 Subject: [PATCH 082/210] ENYO-2604: Remove scrim upon destruction. Enyo-DCO-1.1-Signed-off-by: Aaron Tam --- src/Popup/Popup.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Popup/Popup.js b/src/Popup/Popup.js index 89c7a7e72..f657a6086 100644 --- a/src/Popup/Popup.js +++ b/src/Popup/Popup.js @@ -326,6 +326,7 @@ var Popup = module.exports = kind( destroy: kind.inherit(function (sup) { return function() { this.release(); + if (this.showing) this.showHideScrim(false); sup.apply(this, arguments); }; }), From c2bc400a78648ae0dd6af3c1f3a91647094cbb95 Mon Sep 17 00:00:00 2001 From: Roy Sutton Date: Mon, 4 Jan 2016 16:11:34 -0800 Subject: [PATCH 083/210] ENYO-2917 Document wip modules/kinds Enyo-DCO-1.1-Signed-off-by: Roy Sutton --- src/Loop.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Loop.js b/src/Loop.js index 5dd7ba374..6033a653c 100644 --- a/src/Loop.js +++ b/src/Loop.js @@ -2,6 +2,7 @@ require('enyo'); /** * This module returns the Loop singleton +* @wip * @module enyo/Loop */ var From 4d180555ceb16062e69492fb2c09deb62b761893 Mon Sep 17 00:00:00 2001 From: Aaron Tam Date: Mon, 6 Jul 2015 13:33:41 -0700 Subject: [PATCH 084/210] ENYO-2027: Prevent shared data object. Enyo-DCO-1.1-Signed-off-by: Aaron Tam --- src/FluxStore.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/FluxStore.js b/src/FluxStore.js index 224c8f281..9ee1bee57 100644 --- a/src/FluxStore.js +++ b/src/FluxStore.js @@ -51,13 +51,6 @@ module.exports = kind( */ kind: CoreObject, - - /** - * @private - */ - data: {}, - - /** * How a store is identitified to the Flux Dispatcher. This ID is used for * subscribing to a store's state notification change. @@ -68,6 +61,9 @@ module.exports = kind( */ id: -1, + /** + * @private + */ mixins: [EventEmitter, StateSupport], /** @@ -79,6 +75,10 @@ module.exports = kind( */ source: '', + /** + * @private + * @lends module:enyo/FluxStore~FluxStore.prototype + */ published: { /** @@ -99,6 +99,7 @@ module.exports = kind( constructor: kind.inherit(function (sup) { return function () { sup.apply(this, arguments); + this.reset(); //id the store with the dispatcher this.id = FluxDispatcher.subscribe(); From 2d547b439c8cac80aa1f5b46ee4c26feefa43933 Mon Sep 17 00:00:00 2001 From: Aaron Tam Date: Fri, 8 Jan 2016 17:12:37 -0800 Subject: [PATCH 085/210] ENYO-2993: Use correct module name. Enyo-DCO-1.1-Signed-off-by: Aaron Tam --- src/logger.js | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/logger.js b/src/logger.js index 83440115f..e5c289aba 100644 --- a/src/logger.js +++ b/src/logger.js @@ -19,15 +19,15 @@ var dumbConsole = Boolean(platform.android || platform.ios || platform.webos); /** * Internally used methods and properties associated with logging. * -* @module enyo/logging +* @module enyo/logger * @public */ exports = module.exports = { - + /** * The log level to use. Can be a value from -1 to 99, where -1 disables all * logging, 0 is 'error', 10 is 'warn', and 20 is 'log'. It is preferred that - * this value be set using the [setLogLevel()]{@link module:enyo/logging#setLogLevel} + * this value be set using the [setLogLevel()]{@link module:enyo/logger#setLogLevel} * method. * * @type {Number} @@ -35,14 +35,14 @@ exports = module.exports = { * @public */ level: 99, - + /** * The known levels. * * @private */ levels: {log: 20, warn: 10, error: 0}, - + /** * @private */ @@ -50,7 +50,7 @@ exports = module.exports = { var ll = parseInt(this.levels[fn], 0); return (ll <= this.level); }, - + /** * @private */ @@ -66,7 +66,7 @@ exports = module.exports = { } } }, - + /** * @private */ @@ -99,7 +99,7 @@ exports = module.exports = { console.log(a$.join(' ')); } }, - + /** * This is exposed elsewhere. * @@ -125,12 +125,12 @@ exports = module.exports = { * Sets the log level to the given value. This will restrict the amount of output depending on * the settings. The higher the value, the more output that will be allowed. The default is * 99. The value, -1, would silence all logging, even 'error' (0). -* Without the 'see': {@link module:enyo/logging#log}. +* Without the 'see': {@link module:enyo/logger#log}. * -* @see module:enyo/logging#level -* @see module:enyo/logging#log -* @see module:enyo/logging#warn -* @see module:enyo/logging#error +* @see module:enyo/logger#level +* @see module:enyo/logger#log +* @see module:enyo/logger#warn +* @see module:enyo/logger#error * @param {Number} level - The level to set logging to. */ exports.setLogLevel = function (level) { @@ -143,7 +143,7 @@ exports.setLogLevel = function (level) { /** * A wrapper for [console.log()]{@glossary console.log}, compatible * across supported platforms. Will output only if the current -* [log level]{@link module:enyo/logging#level} allows it. [Object]{@glossary Object} +* [log level]{@link module:enyo/logger#level} allows it. [Object]{@glossary Object} * parameters will be serialized via [JSON.stringify()]{@glossary JSON.stringify} * automatically. * @@ -156,7 +156,7 @@ exports.setLogLevel = function (level) { /** * A wrapper for [console.warn()]{@glossary console.warn}, compatible * across supported platforms. Will output only if the current -* [log level]{@link module:enyo/logging#level} allows it. [Object]{@glossary Object} +* [log level]{@link module:enyo/logger#level} allows it. [Object]{@glossary Object} * parameters will be serialized via [JSON.stringify()]{@glossary JSON.stringify} * automatically. * @@ -172,7 +172,7 @@ exports.warn = function () { /** * A wrapper for [console.error()]{@glossary console.error}, compatible * across supported platforms. Will output only if the current -* [log level]{@link module:enyo/logging#level} allows it. [Object]{@glossary Object} +* [log level]{@link module:enyo/logger#level} allows it. [Object]{@glossary Object} * parameters will be serialized via [JSON.stringify()]{@glossary JSON.stringify} * automatically. * From c9573ce69c73ffe70e116a58a123318106c6d24b Mon Sep 17 00:00:00 2001 From: Roy Sutton Date: Fri, 8 Jan 2016 19:51:30 -0800 Subject: [PATCH 086/210] Update old links to module style Enyo-DCO-1.1-Signed-off-by: Roy Sutton --- src/DataRepeater.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/DataRepeater.js b/src/DataRepeater.js index d73acfe76..059988bea 100644 --- a/src/DataRepeater.js +++ b/src/DataRepeater.js @@ -770,8 +770,9 @@ var DataRepeater = module.exports = kind( /** * The name of the container specified in - * [containerOptions]{@link enyo.DataRepeater#containerOptions}. This may or may not have the - * same value as [controlParentName]{@link enyo.DataRepeater#controlParentName}. + * [containerOptions]{@link module:enyo/DataRepeater~DataRepeater#containerOptions}. This may or + * may not have the same value as + * [controlParentName]{@link module:enyo/DataRepeater~DataRepeater#controlParentName}. * * @type {String} * @default 'container' @@ -783,7 +784,7 @@ var DataRepeater = module.exports = kind( * A [Kind]{@glossary Kind} definition that will be used as the chrome for the container * of the DataRepeater. When specifying a custom definition be sure to include a container * component that has the name specified in - * [controlParentName]{@link enyo.DataRepeater#controlParentName}. + * [controlParentName]{@link module:enyo/DataRepeater~DataRepeater#controlParentName}. * * @type {Object} * @default {name: 'container', classes: 'enyo-fill enyo-data-repeater-container'} @@ -792,7 +793,7 @@ var DataRepeater = module.exports = kind( containerOptions: {name: 'container', classes: 'enyo-fill enyo-data-repeater-container'}, /** - * See {@link enyo.UiComponent#controlParentName} + * See {@link module:enyo/UiComponent~UiComponent#controlParentName} * @type {String} * @default 'container' * @public From d2b71087e28ef7ea19fd0e759521a13022726bba Mon Sep 17 00:00:00 2001 From: Aaron Tam Date: Mon, 11 Jan 2016 12:02:10 -0800 Subject: [PATCH 087/210] ENYO-2333: Update license. Enyo-DCO-1.1-Signed-off-by: Aaron Tam --- package.json | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/package.json b/package.json index a899b0142..7f9ed4af4 100644 --- a/package.json +++ b/package.json @@ -26,12 +26,7 @@ "web": "http://enyojs.com/" } ], - "licenses": [ - { - "type": "Apache-2.0", - "url": "http://www.apache.org/licenses/LICENSE-2.0" - } - ], + "license": "Apache-2.0", "scripts": { "test": "./node_modules/.bin/gulp" }, From 7126a020c41804ab51cc767e0f64bc4290f34145 Mon Sep 17 00:00:00 2001 From: wangii Date: Thu, 22 Jan 2015 10:45:09 +0000 Subject: [PATCH 088/210] Android browser detection for some phones ZTE and Lenovo phones have browser userAgent like Android/4.x.x Conflicts: source/dom/platform.js --- src/platform.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/platform.js b/src/platform.js index 831564c56..e8cc5be6f 100644 --- a/src/platform.js +++ b/src/platform.js @@ -35,7 +35,7 @@ var utils = require('./utils'); * * @module enyo/platform */ -exports = module.exports = +exports = module.exports = /** @lends module:enyo/platform~platform */ { //* `true` if the platform has native single-finger [events]{@glossary event}. touch: Boolean(('ontouchstart' in window) || window.navigator.msMaxTouchPoints), @@ -53,6 +53,8 @@ var platforms = [ {platform: 'androidChrome', regex: /Android .* Chrome\/(\d+)[.\d]+/}, // Android 2 - 4 {platform: 'android', regex: /Android (\d+)/}, + // Some android phones, e.g. ZTE and Lenovo + {platform: "android", regex: /Android\/(\d+)/}, // Kindle Fire // Force version to 2, (desktop mode does not list android version) {platform: 'android', regex: /Silk\/1./, forceVersion: 2, extra: {silk: 1}}, From 863825510096a000a2330452ecfb5ba4f37e8ccd Mon Sep 17 00:00:00 2001 From: Aaron Tam Date: Tue, 12 Jan 2016 11:02:18 -0800 Subject: [PATCH 089/210] ENYO-896: Combine Android detection patterns. Enyo-DCO-1.1-Signed-off-by: Aaron Tam --- src/platform.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/platform.js b/src/platform.js index e8cc5be6f..e80190e38 100644 --- a/src/platform.js +++ b/src/platform.js @@ -52,9 +52,7 @@ var platforms = [ // Android 4+ using Chrome {platform: 'androidChrome', regex: /Android .* Chrome\/(\d+)[.\d]+/}, // Android 2 - 4 - {platform: 'android', regex: /Android (\d+)/}, - // Some android phones, e.g. ZTE and Lenovo - {platform: "android", regex: /Android\/(\d+)/}, + {platform: 'android', regex: /Android(?:\s|\/)(\d+)/}, // Kindle Fire // Force version to 2, (desktop mode does not list android version) {platform: 'android', regex: /Silk\/1./, forceVersion: 2, extra: {silk: 1}}, From 9bad71679f00fe094277550ab9b41e39d0352ce9 Mon Sep 17 00:00:00 2001 From: "jeremy.thomas" Date: Fri, 15 Jan 2016 16:40:04 -0500 Subject: [PATCH 090/210] ENYO-2409: Fix Windows 10 app deployment error --- src/dom.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dom.js b/src/dom.js index baf213a66..16ee12f63 100644 --- a/src/dom.js +++ b/src/dom.js @@ -576,7 +576,7 @@ var dom = module.exports = { }; // override setInnerHtml for Windows 8 HTML applications -if (typeof global.MSApp !== 'undefined') { +if (typeof global.MSApp !== 'undefined' && global.MSApp.execUnsafeLocalFunction !== 'undefined') { dom.setInnerHtml = function(node, html) { global.MSApp.execUnsafeLocalFunction(function() { node.innerHTML = html; From e860b6a443f807f8bf02213f89cf807369c80954 Mon Sep 17 00:00:00 2001 From: Roy Sutton Date: Fri, 15 Jan 2016 15:55:10 -0800 Subject: [PATCH 091/210] ENYO-2486 ENYO-3012 Add edge detection, fix docs Enyo-DCO-1.1-Signed-off-by: Roy Sutton --- src/platform.js | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/platform.js b/src/platform.js index e80190e38..89e4d9404 100644 --- a/src/platform.js +++ b/src/platform.js @@ -10,6 +10,7 @@ var utils = require('./utils'); * * androidChrome (Chrome on Android, standard starting in 4.1) * * androidFirefox * * ie +* * edge * * ios * * webos * * windowsPhone @@ -35,17 +36,28 @@ var utils = require('./utils'); * * @module enyo/platform */ -exports = module.exports = - /** @lends module:enyo/platform~platform */ { - //* `true` if the platform has native single-finger [events]{@glossary event}. +exports = module.exports = { + /** + * `true` if the platform has native single-finger [events]{@glossary event}. + * @public + */ touch: Boolean(('ontouchstart' in window) || window.navigator.msMaxTouchPoints), - //* `true` if the platform has native double-finger [events]{@glossary event}. + /** + * `true` if the platform has native double-finger [events]{@glossary event}. + * @public + */ gesture: Boolean(('ongesturestart' in window) || window.navigator.msMaxTouchPoints) + + /** + * The name of the platform that was detected or `undefined` if the platform + * was unrecognized. This value is the key name for the major version of the + * platform on the exported object. + * @var {string} platformName + * @public + */ + }; -/** -* @private -*/ var ua = navigator.userAgent; var ep = exports; var platforms = [ @@ -66,6 +78,8 @@ var platforms = [ {platform: 'ie', regex: /MSIE (\d+)/}, // IE 11 {platform: 'ie', regex: /Trident\/.*; rv:(\d+)/}, + // Edge + {platform: 'edge', regex: /Edge\/(\d+)/}, // iOS 3 - 5 // Apple likes to make this complicated {platform: 'ios', regex: /iP(?:hone|ad;(?: U;)? CPU) OS (\d+)/}, From f19f55e104eaf2102d0c7b7596b447057b26e49d Mon Sep 17 00:00:00 2001 From: "jeremy.thomas" Date: Mon, 18 Jan 2016 17:55:27 -0500 Subject: [PATCH 092/210] ENYO-3016: Fix touch-gesture platform identification for Windows 10, add Windows 10 Mobile --- src/platform.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/platform.js b/src/platform.js index e80190e38..e301f0f24 100644 --- a/src/platform.js +++ b/src/platform.js @@ -38,9 +38,9 @@ var utils = require('./utils'); exports = module.exports = /** @lends module:enyo/platform~platform */ { //* `true` if the platform has native single-finger [events]{@glossary event}. - touch: Boolean(('ontouchstart' in window) || window.navigator.msMaxTouchPoints), + touch: Boolean(('ontouchstart' in window) || window.navigator.msMaxTouchPoints || window.navigator.maxTouchPoints), //* `true` if the platform has native double-finger [events]{@glossary event}. - gesture: Boolean(('ongesturestart' in window) || window.navigator.msMaxTouchPoints) + gesture: Boolean(('ongesturestart' in window) || window.navigator.msMaxTouchPoints || window.navigator.maxTouchPoints) }; /** @@ -49,6 +49,8 @@ exports = module.exports = var ua = navigator.userAgent; var ep = exports; var platforms = [ + // Windows Phone 7 - 10 + {platform: 'windowsPhone', regex: /Windows Phone (?:OS )?(\d+)[.\d]+/}, // Android 4+ using Chrome {platform: 'androidChrome', regex: /Android .* Chrome\/(\d+)[.\d]+/}, // Android 2 - 4 @@ -60,8 +62,6 @@ var platforms = [ // Force version to 4 {platform: 'android', regex: /Silk\/2./, forceVersion: 4, extra: {silk: 2}}, {platform: 'android', regex: /Silk\/3./, forceVersion: 4, extra: {silk: 3}}, - // Windows Phone 7 - 8 - {platform: 'windowsPhone', regex: /Windows Phone (?:OS )?(\d+)[.\d]+/}, // IE 8 - 10 {platform: 'ie', regex: /MSIE (\d+)/}, // IE 11 From b9a31427eba1c911dbc92e6facdb8d6965ec9f1a Mon Sep 17 00:00:00 2001 From: Roy Sutton Date: Mon, 18 Jan 2016 16:16:01 -0800 Subject: [PATCH 093/210] ENYO-3018 Correct badly doc'ed types Enyo-DCO-1.1-Signed-off-by: Roy Sutton --- src/Binding.js | 11 ++++++- src/Group/Group.js | 2 +- src/Jsonp.js | 6 +--- src/Option.js | 4 +-- src/OptionGroup.js | 3 +- src/RelationalModel/RelationalModel.js | 6 +++- src/Repeater.js | 2 +- src/RichText/RichText.js | 6 ++-- src/Selection.js | 2 +- src/Source.js | 27 +++++++++------- src/Store.js | 7 ++--- src/WebService.js | 5 +-- src/XhrSource.js | 2 +- src/dispatcher.js | 43 +++++++++++++------------- src/gesture/gesture.js | 5 ++- src/gesture/touchGestures.js | 2 +- src/kind.js | 39 ++++++++++++++--------- src/logger.js | 2 +- src/resolution.js | 12 +++---- src/touch.js | 20 ++++++++++-- 20 files changed, 120 insertions(+), 86 deletions(-) diff --git a/src/Binding.js b/src/Binding.js index 79aeafc4b..2136af067 100644 --- a/src/Binding.js +++ b/src/Binding.js @@ -95,8 +95,13 @@ function ready (binding) { /*jshint +W093 */ } + +/** +* @class PassiveBinding +* @public +*/ var PassiveBinding = kind( - /** @lends enyo.PassiveBinding.prototype */ { + /** @lends module:enyo/Binding~PassiveBinding.prototype */ { name: 'enyo.PassiveBinding', @@ -680,4 +685,8 @@ exports.DIRTY_TO = DIRTY_TO; */ exports.defaultBindingKind = exports; +/** +* The kind declaration for the [PassiveBinding]{@link module:Binding~PassiveBinding} kind +* @public +*/ exports.PassiveBinding = PassiveBinding; diff --git a/src/Group/Group.js b/src/Group/Group.js index eabd555e3..ec72b5cd5 100644 --- a/src/Group/Group.js +++ b/src/Group/Group.js @@ -14,7 +14,7 @@ var * The extended {@glossary event} [object]{@glossary Object} that is provided when the * [onActiveChanged]{@link module:enyo/Group~Group#onActiveChanged} event is fired. * -* @typedef {Object} enyo.Group~ActiveChangedEvent +* @typedef {Object} module:enyo/Group~Group~ActiveChangedEvent * @property {module:enyo/Control~Control} active - The active [control]{@link module:enyo/Control~Control} for the * [group]{@link module:enyo/Group~Group}. */ diff --git a/src/Jsonp.js b/src/Jsonp.js index 83d0f1840..9abd03e9c 100644 --- a/src/Jsonp.js +++ b/src/Jsonp.js @@ -38,11 +38,11 @@ var JsonpRequest = module.exports = kind( * @private */ published: { + /** @lends module:enyo/Jsonp~JsonpRequest.prototype */ /** * The URL for the service. * - * @memberof enyo.JsonpRequest.prototype * @type {String} * @default '' * @public @@ -52,7 +52,6 @@ var JsonpRequest = module.exports = kind( /** * The optional character set to use to interpret the return data. * - * @memberof enyo.JsonpRequest.prototype * @type {String} * @default null * @public @@ -65,7 +64,6 @@ var JsonpRequest = module.exports = kind( * This may also be set to `null` in some cases. * * @see module:enyo/Jsonp~JsonpRequest.overrideCallback - * @memberof enyo.JsonpRequest.prototype * @type {String} * @default 'callback' * @public @@ -77,7 +75,6 @@ var JsonpRequest = module.exports = kind( * to (attempt to) force a new fetch of the resource instead of reusing a * local cache. * - * @memberof enyo.JsonpRequest.prototype * @type {Boolean} * @default true * @public @@ -92,7 +89,6 @@ var JsonpRequest = module.exports = kind( * name and only one [JsonpRequest]{@link module:enyo/Jsonp~JsonpRequest} using this property may * be active at a time. * - * @memberof enyo.JsonpRequest.prototype * @type {String} * @default null * @public diff --git a/src/Option.js b/src/Option.js index 02ebdcd25..ab4b64c30 100644 --- a/src/Option.js +++ b/src/Option.js @@ -36,12 +36,13 @@ module.exports = kind( * @private */ published: { + /** @lends module:enyo/Option~Option.prototype */ + /** * Value of the [option]{@link module:enyo/Option~Option}. * * @type {String} * @default '' - * @memberof enyo.Option.prototype * @public */ value: '', @@ -51,7 +52,6 @@ module.exports = kind( * * @type {Boolean} * @default false - * @memberof enyo.Option.prototype * @public */ selected: false diff --git a/src/OptionGroup.js b/src/OptionGroup.js index c4bad93af..88fb00bff 100644 --- a/src/OptionGroup.js +++ b/src/OptionGroup.js @@ -40,12 +40,13 @@ module.exports = kind( * @private */ published: { + /** @lends module:enyo/OptionGroup~OptionGroup.prototype */ + /** * The name for this [option group]{@link module:enyo/OptionGroup~OptionGroup}. * * @type {String} * @default '' - * @memberof enyo.OptionGroup.prototype * @public */ label: '' diff --git a/src/RelationalModel/RelationalModel.js b/src/RelationalModel/RelationalModel.js index 90cd16d08..8f07a9c54 100644 --- a/src/RelationalModel/RelationalModel.js +++ b/src/RelationalModel/RelationalModel.js @@ -312,6 +312,9 @@ var RelationalModel = module.exports = kind( /** * Defines a named relation type * +* @name module:enyo/RelationalModel~RelationalModel.defineRelationType +* @static +* @method * @param {String} name Name of relation type * @param {Relation} type Relation kind constructor * @param {Boolean} isDefault `true` if this type should be the default for type-less relations @@ -326,8 +329,9 @@ RelationalModel.defineRelationType = function (name, type, isDefault) { /** * Ensures that we concatenate (sanely) the relations for any subkinds. * -* @name enyo.RelationalModel.concat +* @name module:enyo/RelationalModel~RelationalModel.concat * @static +* @method * @private */ RelationalModel.concat = function (ctor, props) { diff --git a/src/Repeater.js b/src/Repeater.js index 9c7116608..569635545 100644 --- a/src/Repeater.js +++ b/src/Repeater.js @@ -15,7 +15,7 @@ var * The extended {@glossary event} [object]{@glossary Object} that is provided * when the [onSetupItem]{@link module:enyo/Repeater~Repeater#onSetupItem} event is fired. * -* @typedef {Object} enyo.Repeater~SetupItemEvent +* @typedef {Object} module:enyo/Repeater~Repeater~SetupItemEvent * @property {Number} index - The item's index. * @property {Object} item - The item control, for decoration. */ diff --git a/src/RichText/RichText.js b/src/RichText/RichText.js index dae00b0de..023382ee9 100644 --- a/src/RichText/RichText.js +++ b/src/RichText/RichText.js @@ -19,14 +19,14 @@ var /** * The type of change to apply. Possible values are `'move'` and `'extend'`. * -* @typedef {String} enyo.RichText~ModifyType +* @typedef {String} module:enyo/RichText~RichText~ModifyType */ /** * The direction in which to apply the change. Possible values include: `'forward'`, * `'backward'`, `'left'`, and `'right'`. * -* @typedef {String} enyo.RichText~ModifyDirection +* @typedef {String} module:enyo/RichText~RichText~ModifyDirection */ /** @@ -34,7 +34,7 @@ var * `'sentence'`, `'line'`, `'paragraph'`, `'lineboundary'`, `'sentenceboundary'`, * `'paragraphboundary'`, and `'documentboundary'`. * -* @typedef {String} enyo.RichText~ModifyAmount +* @typedef {String} module:enyo/RichText~RichText~ModifyAmount */ /** diff --git a/src/Selection.js b/src/Selection.js index 0f3dfbf86..b588190c8 100644 --- a/src/Selection.js +++ b/src/Selection.js @@ -15,7 +15,7 @@ var * when the [onSelect]{@link module:enyo/Selection~Selection#onSelect} and * [onDeselect]{@link module:enyo/Selection~Selection#onDeselect} events are fired. * -* @typedef {Object} enyo.Selection~SelectionEvent +* @typedef {Object} module:enyo/Selection~Selection~SelectionEvent * @property {Number|String} key The key that was used to register the * [selection]{@link module:enyo/Selection~Selection} (usually a row index). * @property {Object} data - References data registered with the key by the code diff --git a/src/Source.js b/src/Source.js index a01798084..0aed6e36e 100644 --- a/src/Source.js +++ b/src/Source.js @@ -10,13 +10,6 @@ var utils = require('./utils'), logger = require('./logger'); -/** -* All of the known, instanced [sources]{@link module:enyo/Source~Source}, by name. -* -* @name enyo~sources -* @type {Object} -* @readonly -*/ var sources = {}; /** @@ -92,7 +85,7 @@ var Source = module.exports = kind( * Overload this method to handle deletion of data. This method should accept an options * [hash]{@glossary Object} with additional configuration properties, including `success` * and `error` callbacks to handle the result. If called without parameters, it will - * instead destroy itself and be removed from [enyo.sources]{@link enyo~sources}, rendering + * instead destroy itself and be removed from [sources]{@link module:enyo/Source~Source.sources}, rendering * itself unavailable for further operations. * * @param {(module:enyo/Model~Model|module:enyo/Collection~Collection)} model The [model]{@link module:enyo/Model~Model} or @@ -152,11 +145,11 @@ var Source = module.exports = kind( * properties should include a `kind` property with the name of the * [kind]{@glossary kind} of source and a `name` for the instance. This static * method is also available on all [subkinds]{@glossary subkind} of -* `enyo.Source`. The instance will automatically be added to the -* [enyo.sources]{@link enyo~sources} [object]{@glossary Object} and may be +* `enyo/Source`. The instance will automatically be added to the +* [sources]{@link module:enyo/Source~Source.sources} [object]{@glossary Object} and may be * referenced by its `name`. * -* @name enyo.Source.create +* @name module:enyo/Source~Source.create * @static * @method * @param {Object} props - The properties to pass to the constructor for the requested @@ -173,7 +166,9 @@ Source.create = function (props) { }; /** +* @name module:enyo/Source~Source.concat * @static +* @method * @private */ Source.concat = function (ctor, props) { @@ -185,7 +180,9 @@ Source.concat = function (ctor, props) { }; /** +* @name module:enyo/Source~Source.execute * @static +* @method * @private */ Source.execute = function (action, model, opts) { @@ -272,4 +269,12 @@ Source.execute = function (action, model, opts) { } }; +/** +* All of the known, instanced [sources]{@link module:enyo/Source~Source}, by name. +* @name module:enyo/Source~Source.sources +* @type {Object} +* @public +* @readonly +*/ Source.sources = sources; + diff --git a/src/Store.js b/src/Store.js index a0cd310a4..39ba89c36 100644 --- a/src/Store.js +++ b/src/Store.js @@ -30,7 +30,7 @@ var BaseStore = kind({ * should be included in the filtered set for the [find()]{@link module:enyo/Store~Store#find} * method. * -* @callback enyo.Store~Filter +* @callback module:enyo/Store~Store~Filter * @param {module:enyo/Model~Model} model - The [model]{@link module:enyo/Model~Model} to filter. * @returns {Boolean} `true` if the model meets the filter requirements; * otherwise, `false`. @@ -39,7 +39,7 @@ var BaseStore = kind({ /** * The configuration options for the [find()]{@link module:enyo/Store~Store#find} method. * -* @typedef {Object} enyo.Store~FindOptions +* @typedef {Object} module:enyo/Store~Store~FindOptions * @property {Boolean} all=true - Whether or not to include more than one match for the * filter method. If `true`, an array of matches is returned; otherwise, a single match. * @property {Object} context - If provided, it will be used as the `this` (context) of @@ -304,8 +304,7 @@ var Store = kind( * @see module:enyo/Model~Model * @see module:enyo/Collection~Collection * @see module:enyo/RelationalModel~RelationalModel -* @type enyo.Store -* @memberof enyo +* @type module:enyo/Store~Store * @public */ module.exports = new Store(); diff --git a/src/WebService.js b/src/WebService.js index 5a3677c21..89cbd02b6 100644 --- a/src/WebService.js +++ b/src/WebService.js @@ -93,12 +93,12 @@ module.exports = kind( * @private */ published: { + /** @lends module:enyo/WebService~WebService.prototype */ /** * Indicates whether or not to use the [JSONP]{@glossary JSONP} protocol (and * {@link module:enyo/Jsonp~JsonpRequest} instead of {@link module:enyo/Ajax~Ajax}). * - * @memberof enyo.WebService.prototype * @type {Boolean} * @default false * @public @@ -111,7 +111,6 @@ module.exports = kind( * parameter. Enyo will create an internal callback function as necessary. * * @see module:enyo/WebService~WebService.jsonp - * @memberof enyo.WebService.prototype * @type {String} * @default 'callback' * @public @@ -123,7 +122,6 @@ module.exports = kind( * interpret the return data. * * @see module:enyo/WebService~WebService.jsonp - * @memberof enyo.WebService.prototype * @type {String} * @default null * @public @@ -135,7 +133,6 @@ module.exports = kind( * [send()]{@link module:enyo/WebService~WebService#send} call before failing with a timeout * error. * - * @memberof enyo.WebService.prototype * @type {Number} * @default 0 * @public diff --git a/src/XhrSource.js b/src/XhrSource.js index 283fdf4d7..0c030a4fe 100644 --- a/src/XhrSource.js +++ b/src/XhrSource.js @@ -166,7 +166,7 @@ var XhrSource = module.exports = kind( }); /** -* @name enyo.XhrSource.concat +* @name module:enyo/XhrSource~XhrSource.concat * @static * @private */ diff --git a/src/dispatcher.js b/src/dispatcher.js index e1244e2fc..4fe7699a1 100644 --- a/src/dispatcher.js +++ b/src/dispatcher.js @@ -31,10 +31,6 @@ var * any scroll offset. */ -/** -* @private -*/ - /** * @private */ @@ -196,6 +192,9 @@ var dispatcher = module.exports = dispatcher = { /** * Called in the context of an event. * +* @name module:enyo/dispatcher.iePreventDefault +* @static +* @method * @private */ dispatcher.iePreventDefault = function() { @@ -215,6 +214,9 @@ function dispatch (inEvent) { } /** +* @name module:enyo/dispatcher.bubble +* @static +* @method * @private */ dispatcher.bubble = function(inEvent) { @@ -237,7 +239,7 @@ dispatcher.bubbler = "enyo.bubble(arguments[0])"; // The code below helps make Enyo compatible with Google Packaged Apps // Content Security Policy(http://developer.chrome.com/extensions/contentSecurityPolicy.html), // which, among other things, forbids the use of inline scripts. -// We replace online scripting with equivalent means, leaving enyo.bubbler +// We replace online scripting with equivalent means, leaving dispatcher.bubbler // for backward compatibility. (function() { var bubbleUp = function() { @@ -247,6 +249,8 @@ dispatcher.bubbler = "enyo.bubble(arguments[0])"; /** * Makes given events bubble on a specified Enyo control. * + * @name: module:enyo/dispatcher.makeBubble + * @method * @private */ dispatcher.makeBubble = function() { @@ -264,8 +268,10 @@ dispatcher.bubbler = "enyo.bubble(arguments[0])"; /** * Removes the event listening and bubbling initiated by - * [enyo.makeBubble()]{@link enyo.makeBubble} on a specific control. + * [makeBubble()]{@link module:enyo/dispatcher.makeBubble} on a specific control. * + * @name: module:enyo/dispatcher.unmakeBubble + * @method * @private */ dispatcher.unmakeBubble = function() { @@ -364,13 +370,13 @@ dispatcher.getPosition = function () { /** * Key mapping feature: Adds a `keySymbol` property to key [events]{@glossary event}, * based on a global key mapping. Use -* [enyo.dispatcher.registerKeyMap()]{@link enyo.dispatcher.registerKeyMap} to add +* [registerKeyMap()]{@link module:enyo/dispatcher.registerKeyMap} to add * keyCode-to-keySymbol mappings via a simple hash. This method may be called * multiple times from different libraries to mix different maps into the global * mapping table; if conflicts arise, the last-in wins. * * ``` -* enyo.dispatcher.registerKeyMap({ +* dispatcher.registerKeyMap({ * 415 : 'play', * 413 : 'stop', * 19 : 'pause', @@ -402,8 +408,8 @@ utils.mixin(dispatcher, { /** * Event modal capture feature. Capture events to a specific control via -* [enyo.dispatcher.capture(inControl, inShouldForward)]{@linkcode enyo.dispatcher.capture}; -* release events via [enyo.dispatcher.release()]{@link enyo.dispatcher.release}. +* [capture(inControl, inShouldForward)]{@linkcode module:enyo/dispatcher.capture}; +* release events via [release()]{@link module:enyo/dispatcher.release}. * * @private */ @@ -427,7 +433,7 @@ dispatcher.features.push(function(e) { // // NOTE: This object is a plug-in; these methods should -// be called on `enyo.dispatcher`, and not on the plug-in itself. +// be called on `enyo/dispatcher`, and not on the plug-in itself. // utils.mixin(dispatcher, { @@ -491,24 +497,19 @@ utils.mixin(dispatcher, { * Allows {@link module:enyo/Control~Control} ancestors of the {@glossary event} target * a chance (eldest first) to react by implementing `previewDomEvent`. * + * @todo Revisit how/if we document this * @private */ var fn = 'previewDomEvent'; - var preview = - /** @lends enyo.dispatcher.features */ { + var preview = { - /** - * @private - */ feature: function(e) { preview.dispatch(e, e.dispatchTarget); }, - /** + /* * @returns {(Boolean|undefined)} Handlers return `true` to abort preview and prevent default * event processing. - * - * @private */ dispatch: function(evt, control) { var i, l, @@ -521,12 +522,10 @@ utils.mixin(dispatcher, { } }, - /** + /* * We ascend, making a list of Enyo [controls]{@link module:enyo/Control~Control}. * * Note that a control is considered to be its own ancestor. - * - * @private */ buildLineage: function(control) { var lineage = [], diff --git a/src/gesture/gesture.js b/src/gesture/gesture.js index 4eaf02179..958f21f4a 100644 --- a/src/gesture/gesture.js +++ b/src/gesture/gesture.js @@ -1,7 +1,6 @@ -require('enyo'); /** - * @module enyo/gesture - */ +* @module enyo/gesture +*/ var diff --git a/src/gesture/touchGestures.js b/src/gesture/touchGestures.js index eed1a4cb0..6010a0534 100644 --- a/src/gesture/touchGestures.js +++ b/src/gesture/touchGestures.js @@ -4,7 +4,7 @@ var /** * The extended {@glossary event} [object]{@glossary Object} that is provided when we -* emulate iOS gesture events on non-iOS devices. +* emulate iOS multitouch gesture events on non-iOS devices. * * @typedef {Object} module:enyo/gesture/touchGestures~EmulatedGestureEvent * @property {Number} pageX - The x-coordinate of the center point between fingers. diff --git a/src/kind.js b/src/kind.js index a099198fd..7a479c75c 100644 --- a/src/kind.js +++ b/src/kind.js @@ -137,6 +137,8 @@ exports.singleton = function (conf) { }; /** +* @name module:enyo/kind.makeCtor +* @method * @private */ kind.makeCtor = function () { @@ -164,16 +166,10 @@ kind.makeCtor = function () { return enyoConstructor; }; -/** -* Classes referenced by name may omit this namespace (e.g., "Button" instead of "enyo.Button") -* -* @private -*/ -kind.defaultNamespace = 'enyo'; - /** * Feature hooks for the oop system * +* @name module:enyo/kind.features * @private */ kind.features = []; @@ -184,6 +180,8 @@ kind.features = []; * [constructor]{@glossary constructor}, a [prototype]{@glossary Object.prototype}, or an * instance. * +* @name module:enyo/kind.extendMethods +* @method * @private */ kind.extendMethods = function (ctor, props, add) { @@ -233,6 +231,8 @@ kind.features.push(kind.extendMethods); * `this.inherited(arguments)` from within a kind method. This can only be done * safely when there is known to be a super class with the same method. * +* @name module:enyo/kind.inherited +* @method * @private */ kind.inherited = function (originals, replacements) { @@ -268,9 +268,6 @@ kind.inherited = function (originals, replacements) { // dcl inspired super-inheritance -/** -* @private -*/ var Inherited = function (fn) { this.fn = fn; }; @@ -344,10 +341,11 @@ kind.statics = { * it is subclassed, the constructor and properties will be passed through * this method for special handling of important features. * + * @name module:enyo/kind.subclass + * @method * @param {Function} ctor - The [constructor]{@glossary constructor} of the * [kind]{@glossary kind} being subclassed. * @param {Object} props - The properties of the kind being subclassed. - * @memberof enyo.kind * @public */ subclass: function (ctor, props) {}, @@ -358,8 +356,10 @@ kind.statics = { * [constructors]{@glossary constructor}, although calling it on a * [deferred]{@glossary deferred} constructor will force it to be * resolved at that time. This method does not re-run the - * {@link module:enyo/kind~kind.features} against the constructor or instance. + * {@link module:enyo/kind.features} against the constructor or instance. * + * @name module:enyo/kind.extend + * @method * @param {Object|Object[]} props A [hash]{@glossary Object} or [array]{@glossary Array} * of [hashes]{@glossary Object}. Properties will override * [prototype]{@glossary Object.prototype} properties. If a @@ -374,7 +374,6 @@ kind.statics = { * be extended. * @returns {Object} The constructor of the class, or specific * instance, that has been extended. - * @memberof enyo.kind * @public */ extend: function (props, target) { @@ -399,10 +398,11 @@ kind.statics = { /** * Creates a new sub-[kind]{@glossary kind} of the current kind. * + * @name module:enyo/kind.kind + * @method * @param {Object} props A [hash]{@glossary Object} of properties used to define and create * the [kind]{@glossary kind} * @return {Function} Constructor of the new kind - * @memberof enyo.kind * @public */ kind: function (props) { @@ -416,6 +416,7 @@ kind.statics = { }; /** +* @method * @private */ exports.concatHandler = function (ctor, props, instance) { @@ -428,14 +429,18 @@ exports.concatHandler = function (ctor, props, instance) { } }; +var kindCtors = /** * Factory for [kinds]{@glossary kind} identified by [strings]{@glossary String}. * +* @type Object +* @deprecated Since 2.6.0 * @private */ -var kindCtors = exports._kindCtors = {}; + exports._kindCtors = {}; /** +* @method * @private */ var constructorForKind = exports.constructorForKind = function (kind) { @@ -475,11 +480,14 @@ var constructorForKind = exports.constructorForKind = function (kind) { * Namespace for current theme (`enyo.Theme.Button` references the Button specialization for the * current theme). * +* @deprecated Since 2.6.0 * @private */ var Theme = exports.Theme = {}; /** +* @method +* @deprecated Since 2.6.0 * @private */ exports.registerTheme = function (ns) { @@ -487,6 +495,7 @@ exports.registerTheme = function (ns) { }; /** +* @method * @private */ exports.createFromKind = function (nom, param) { diff --git a/src/logger.js b/src/logger.js index e5c289aba..1dccd4dee 100644 --- a/src/logger.js +++ b/src/logger.js @@ -12,7 +12,7 @@ var * * ios * * webos * -* @private +* @ignore */ var dumbConsole = Boolean(platform.android || platform.ios || platform.webos); diff --git a/src/resolution.js b/src/resolution.js index 883bb97bd..c4714cd9d 100644 --- a/src/resolution.js +++ b/src/resolution.js @@ -37,7 +37,9 @@ var ri = module.exports = { * Executing this method also initializes the rest of the resolution-independence code. * * ``` - * ri.defineScreenTypes([ + * var resolution = require('enyo/resolution'); + * + * resolution.defineScreenTypes([ * {name: 'vga', pxPerRem: 8, width: 640, height: 480, aspectRatioName: 'standard'}, * {name: 'xga', pxPerRem: 16, width: 1024, height: 768, aspectRatioName: 'standard'}, * {name: 'hd', pxPerRem: 16, width: 1280, height: 720, aspectRatioName: 'hdtv'}, @@ -182,14 +184,12 @@ var ri = module.exports = { }, /** - * The default configurable [options]{@link ri.selectSrc#options}. + * The default configurable [options]{@link module:enyo/resolution.selectSrc#options}. * - * @typedef {Object} ri.selectSrc~src + * @typedef {Object} module:enyo/resolution.selectSrcSrc * @property {String} hd - HD / 720p Resolution image asset source URI/URL * @property {String} fhd - FHD / 1080p Resolution image asset source URI/URL * @property {String} uhd - UHD / 4K Resolution image asset source URI/URL - * - * @typedef {String} ri.selectSrc~src - Image asset source URI/URL */ /** @@ -217,7 +217,7 @@ var ri = module.exports = { * {kind: Image, src: http://lorempixel.com/128/128/city/1/', alt: 'Large'}, * ``` * - * @param {(String|module:enyo/resolution#selectSrc~src)} src - A string containing + * @param {(String|module:enyo/resolution~selectSrcSrc)} src - A string containing * a single image source or a key/value hash/object containing keys representing screen * types (`'hd'`, `'fhd'`, `'uhd'`, etc.) and values containing the asset source for * that target screen resolution. diff --git a/src/touch.js b/src/touch.js index d31a64662..4e6ec1126 100644 --- a/src/touch.js +++ b/src/touch.js @@ -1,3 +1,9 @@ +/** +* This module has no exports. It merely extends {@link module:enyo/gesture} to enable touch events. +* +* @private +* @module enyo/touch +*/ require('enyo'); var @@ -31,7 +37,7 @@ Dom.requiresWindow(function() { var oldevents = gesture.events; /** - * @private + * @ignore */ gesture.events.touchstart = function (e) { // for duration of this touch, only handle touch events. Old event @@ -41,16 +47,18 @@ Dom.requiresWindow(function() { }; /** - * @private + * @ignore */ var touchGesture = { /** + * @ignore * @private */ _touchCount: 0, /** + * @ignore * @private */ touchstart: function (e) { @@ -67,6 +75,7 @@ Dom.requiresWindow(function() { }, /** + * @ignore * @private */ touchmove: function (e) { @@ -99,6 +108,7 @@ Dom.requiresWindow(function() { }, /** + * @ignore * @private */ touchend: function (e) { @@ -124,6 +134,7 @@ Dom.requiresWindow(function() { * back to default; this works as long as no one did a `preventDefault()` on * the touch events. * + * @ignore * @private */ mouseup: function () { @@ -134,6 +145,7 @@ Dom.requiresWindow(function() { }, /** + * @ignore * @private */ makeEvent: function (e) { @@ -147,6 +159,7 @@ Dom.requiresWindow(function() { }, /** + * @ignore * @private */ calcNodeOffset: function (node) { @@ -162,6 +175,7 @@ Dom.requiresWindow(function() { }, /** + * @ignore * @private */ findTarget: function (e) { @@ -172,6 +186,7 @@ Dom.requiresWindow(function() { * NOTE: Will find only 1 element under the touch and will fail if an element is * positioned outside the bounding box of its parent. * + * @ignore * @private */ findTargetTraverse: function (node, x, y) { @@ -196,6 +211,7 @@ Dom.requiresWindow(function() { }, /** + * @ignore * @private */ connect: function () { From f5b17da288b4e339512ecbc07e61ff296458ea69 Mon Sep 17 00:00:00 2001 From: Aaron Tam Date: Tue, 19 Jan 2016 10:46:05 -0800 Subject: [PATCH 094/210] ENYO-2621: Mark method as WIP. Enyo-DCO-1.1-Signed-off-by: Aaron Tam --- src/UiComponent.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/UiComponent.js b/src/UiComponent.js index d6d2fbc19..00b0820cb 100644 --- a/src/UiComponent.js +++ b/src/UiComponent.js @@ -254,6 +254,7 @@ var UiComponent = module.exports = kind( * @param {module:enyo/UiComponent~UpdateComponentsOptions} [opts] - Additional options for how * the update operation should behave. * @returns {Boolean} - Whether or not the component should be re-rendered. + * @wip * @public */ updateComponents: function (props, ext, opts) { From 052773d2d95a9f0aae6725379018ec1b8c2b82f1 Mon Sep 17 00:00:00 2001 From: Roy Sutton Date: Tue, 19 Jan 2016 11:53:29 -0800 Subject: [PATCH 095/210] @member is more clear than @var Enyo-DCO-1.1-Signed-off-by: Roy Sutton --- src/platform.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform.js b/src/platform.js index 89e4d9404..2357c2c40 100644 --- a/src/platform.js +++ b/src/platform.js @@ -52,7 +52,7 @@ exports = module.exports = { * The name of the platform that was detected or `undefined` if the platform * was unrecognized. This value is the key name for the major version of the * platform on the exported object. - * @var {string} platformName + * @member {string} platformName * @public */ From 597762bac7de557b7d0b25a2a71538b5660d1a7d Mon Sep 17 00:00:00 2001 From: Aaron Tam Date: Tue, 19 Jan 2016 12:04:50 -0800 Subject: [PATCH 096/210] ENYO-2486: Fix member type. Enyo-DCO-1.1-Signed-off-by: Aaron Tam --- src/platform.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform.js b/src/platform.js index 2357c2c40..b1fac7751 100644 --- a/src/platform.js +++ b/src/platform.js @@ -39,7 +39,7 @@ var utils = require('./utils'); exports = module.exports = { /** * `true` if the platform has native single-finger [events]{@glossary event}. - * @public + * @public */ touch: Boolean(('ontouchstart' in window) || window.navigator.msMaxTouchPoints), /** @@ -52,7 +52,7 @@ exports = module.exports = { * The name of the platform that was detected or `undefined` if the platform * was unrecognized. This value is the key name for the major version of the * platform on the exported object. - * @member {string} platformName + * @member {String} platformName * @public */ From 0cc5d75bc005301431f17f23e65c1e79cc052188 Mon Sep 17 00:00:00 2001 From: Stephen Choi Date: Tue, 19 Jan 2016 17:00:08 -0800 Subject: [PATCH 097/210] ENYO-3018: More Correction Enyo-DCO-1.1-Signed-off-by: Stephen Choi --- src/EventEmitter.js | 69 ++++++++++++++++++++--------------------- src/Select.js | 22 ++++++------- src/VerticalDelegate.js | 2 +- 3 files changed, 45 insertions(+), 48 deletions(-) diff --git a/src/EventEmitter.js b/src/EventEmitter.js index 954f67968..73c8c7d68 100644 --- a/src/EventEmitter.js +++ b/src/EventEmitter.js @@ -21,7 +21,7 @@ function addListener(obj, e, fn, ctx) { method: fn, ctx: ctx || obj }); - + return obj; } @@ -31,14 +31,14 @@ function addListener(obj, e, fn, ctx) { function removeListener(obj, e, fn, ctx) { var listeners = obj.listeners() , idx; - + if (listeners.length) { idx = listeners.findIndex(function (ln) { return ln.event == e && ln.method === fn && (ctx? ln.ctx === ctx: true); }); idx >= 0 && listeners.splice(idx, 1); } - + return obj; } @@ -49,7 +49,7 @@ function emit(obj, args) { var len = args.length , e = args[0] , listeners = obj.listeners(e); - + if (listeners.length) { if (len > 1) { args = utils.toArray(args); @@ -59,10 +59,10 @@ function emit(obj, args) { } for (var i=0, ln; (ln=listeners[i]); ++i) ln.method.apply(ln.ctx, args); - + return true; } - + return false; } @@ -77,28 +77,28 @@ function emit(obj, args) { * @public */ var EventEmitter = { - + /** * @private */ name: 'EventEmitter', - + /** * @private */ _silenced: false, - + /** * @private */ _silenceCount: 0, - + /** * Disables propagation of [events]{@glossary event}. This is a counting - * semaphor and [unsilence()]{@link module:enyo/EventEmitter~EventEmitter.unsilence} will need to + * semaphor and [unsilence()]{@link module:enyo/EventEmitter~EventEmitter#unsilence} will need to * be called the same number of times that this method is called. * - * @see module:enyo/EventEmitter~EventEmitter.unsilence + * @see module:enyo/EventEmitter~EventEmitter#unsilence * @returns {this} The callee for chaining. * @public */ @@ -107,13 +107,13 @@ var EventEmitter = { this._silenceCount++; return this; }, - + /** * Enables propagation of [events]{@glossary event}. This is a counting * semaphor and this method will need to be called the same number of times - * that [silence()]{@link module:enyo/EventEmitter~EventEmitter.silence} was called. + * that [silence()]{@link module:enyo/EventEmitter~EventEmitter#silence} was called. * - * @see module:enyo/EventEmitter~EventEmitter.silence + * @see module:enyo/EventEmitter~EventEmitter#silence * @returns {this} The callee for chaining. * @public */ @@ -127,29 +127,28 @@ var EventEmitter = { } return this; }, - + /** - * Determines whether the callee is currently [silenced]{@link module:enyo/EventEmitter~EventEmitter.silence}. + * Determines whether the callee is currently [silenced]{@link module:enyo/EventEmitter~EventEmitter#silence}. * * @returns {Boolean} Whether or not the callee is - * [silenced]{@link module:enyo/EventEmitter~EventEmitter.silence}. + * [silenced]{@link module:enyo/EventEmitter~EventEmitter#silence}. * @public */ isSilenced: function () { return this._silenced; }, - + /** - * @alias enyo.EventEmitter.on - * @deprecated + * @deprecated Replaced by {@link module:enyo/EventEmitter~EventEmitter#on} * @public */ addListener: function (e, fn, ctx) { return addListener(this, e, fn, ctx); }, - + /** - * Adds an {@glossary event} listener. Until [removed]{@link module:enyo/EventEmitter~EventEmitter.off}, + * Adds an {@glossary event} listener. Until [removed]{@link module:enyo/EventEmitter~EventEmitter#off}, * this listener will fire every time the event is * [emitted]{@link module:enyo/EventEmitter~EventEmitter#emit}. * @@ -162,16 +161,15 @@ var EventEmitter = { on: function (e, fn, ctx) { return addListener(this, e, fn, ctx); }, - + /** - * @alias enyo.EventEmitter.off - * @deprecated + * @deprecated Replaced by {@link module:enyo/EventEmitter~EventEmitter#off} * @public */ removeListener: function (e, fn, ctx) { return removeListener(this, e, fn, ctx); }, - + /** * Removes an {@glossary event} listener. * @@ -185,7 +183,7 @@ var EventEmitter = { off: function (e, fn, ctx) { return removeListener(this, e, fn, ctx); }, - + /** * Removes all listeners, or all listeners for a given {@glossary event}. * @@ -195,7 +193,7 @@ var EventEmitter = { removeAllListeners: function (e) { var euid = this.euid , loc = euid && eventTable[euid]; - + if (loc) { if (e) { eventTable[euid] = loc.filter(function (ln) { @@ -205,10 +203,10 @@ var EventEmitter = { eventTable[euid] = null; } } - + return this; }, - + /** * Primarily intended for internal use, this method returns an immutable copy * of all listeners, or all listeners for a particular {@glossary event} (if any). @@ -222,21 +220,20 @@ var EventEmitter = { listeners: function (e) { var euid = this.euid || (this.euid = utils.uid('e')) , loc = eventTable[euid] || (eventTable[euid] = []); - + return !e? loc: loc.filter(function (ln) { return ln.event == e || ln.event == '*'; }); }, - + /** - * @alias enyo.EventEmitter.emit - * @deprecated + * @deprecated Replaced by {@link module:enyo/EventEmitter~EventEmitter#emit} * @public */ triggerEvent: function () { return !this._silenced? emit(this, arguments): false; }, - + /** * Emits the named {@glossary event}. All subsequent arguments will be passed * to the event listeners. diff --git a/src/Select.js b/src/Select.js index cdfd106b1..36392e490 100644 --- a/src/Select.js +++ b/src/Select.js @@ -38,7 +38,7 @@ var * } * } * ``` -* +* * Note: This uses the [<select>]{@glossary select} tag, which isn't implemented for * native webOS applications, although it does work in the webOS Web browser. * @@ -63,12 +63,12 @@ module.exports = kind( /** * @private */ - published: + published: /** @lends module:enyo/Select~Select.prototype */ { - + /** * The index of the selected [option]{@link module:enyo/Option~Option} in the list. - * + * * @type {Number} * @default null * @public @@ -77,7 +77,7 @@ module.exports = kind( /** * The value of the selected [option]{@link module:enyo/Option~Option}. - * + * * @type {Object} * @default null * @public @@ -86,7 +86,7 @@ module.exports = kind( /** * The size of the select box in rows. - * + * * @type {Number} * @default 0 * @public @@ -94,8 +94,8 @@ module.exports = kind( size: 0, /** - * Sets whether the enyo.Select can select multiple options - * + * Sets whether the enyo/Select can select multiple options + * * @type {Boolean} * @default false * @public @@ -103,15 +103,15 @@ module.exports = kind( multiple: false, /** - * Sets whether the enyo.Select is disabled, or not - * + * Sets whether the enyo/Select is disabled, or not + * * @type {Boolean} * @default false * @public */ disabled: false }, - + /** * @private */ diff --git a/src/VerticalDelegate.js b/src/VerticalDelegate.js index d50fd09ce..7c29c0cf4 100644 --- a/src/VerticalDelegate.js +++ b/src/VerticalDelegate.js @@ -905,7 +905,7 @@ module.exports = { * are within the scroller but precede the pages. * * @method - * @param {module:enyo/DataList~DataList} list - The instance of enyo.DataList + * @param {module:enyo/DataList~DataList} list - The instance of enyo/DataList * @private */ calcScrollOffset: function (list) { From 89e04420a02b423e85bc8b4e5025931895e036f1 Mon Sep 17 00:00:00 2001 From: Aaron Tam Date: Tue, 19 Jan 2016 17:01:13 -0800 Subject: [PATCH 098/210] Revert "Merge pull request #1355 from enyojs/ENYO-2409-jeremythomas" This reverts commit 6e135afe6359fe273f2fbbef04c77e882403cb0d, reversing changes made to c0f9c3a7a892c198036aa9e891db5784e5d1d1e6. --- src/dom.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dom.js b/src/dom.js index 16ee12f63..baf213a66 100644 --- a/src/dom.js +++ b/src/dom.js @@ -576,7 +576,7 @@ var dom = module.exports = { }; // override setInnerHtml for Windows 8 HTML applications -if (typeof global.MSApp !== 'undefined' && global.MSApp.execUnsafeLocalFunction !== 'undefined') { +if (typeof global.MSApp !== 'undefined') { dom.setInnerHtml = function(node, html) { global.MSApp.execUnsafeLocalFunction(function() { node.innerHTML = html; From 6d072a5dc7db6198620c712b90d99c97ee2f3822 Mon Sep 17 00:00:00 2001 From: Stephen Choi Date: Tue, 19 Jan 2016 17:30:42 -0800 Subject: [PATCH 099/210] ENYO-3018: Change static members reference from '#' to '.' Enyo-DCO-1.1-Signed-off-by: Stephen Choi --- src/EventEmitter.js | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/EventEmitter.js b/src/EventEmitter.js index 73c8c7d68..2af1b8c04 100644 --- a/src/EventEmitter.js +++ b/src/EventEmitter.js @@ -70,8 +70,8 @@ function emit(obj, args) { * {@link module:enyo/EventEmitter~EventEmitter} is a {@glossary mixin} that adds support for * registered {@glossary event} listeners. These events are different from * bubbled events (e.g., DOM events and [handlers]{@link module:enyo/Component~Component#handlers}). -* When [emitted]{@link module:enyo/EventEmitter~EventEmitter#emit}, these events **do not bubble** -* and will only be handled by [registered listeners]{@link module:enyo/EventEmitter~EventEmitter#on}. +* When [emitted]{@link module:enyo/EventEmitter~EventEmitter.emit}, these events **do not bubble** +* and will only be handled by [registered listeners]{@link module:enyo/EventEmitter~EventEmitter.on}. * * @mixin * @public @@ -95,10 +95,10 @@ var EventEmitter = { /** * Disables propagation of [events]{@glossary event}. This is a counting - * semaphor and [unsilence()]{@link module:enyo/EventEmitter~EventEmitter#unsilence} will need to + * semaphor and [unsilence()]{@link module:enyo/EventEmitter~EventEmitter.unsilence} will need to * be called the same number of times that this method is called. * - * @see module:enyo/EventEmitter~EventEmitter#unsilence + * @see module:enyo/EventEmitter~EventEmitter.unsilence * @returns {this} The callee for chaining. * @public */ @@ -111,9 +111,9 @@ var EventEmitter = { /** * Enables propagation of [events]{@glossary event}. This is a counting * semaphor and this method will need to be called the same number of times - * that [silence()]{@link module:enyo/EventEmitter~EventEmitter#silence} was called. + * that [silence()]{@link module:enyo/EventEmitter~EventEmitter.silence} was called. * - * @see module:enyo/EventEmitter~EventEmitter#silence + * @see module:enyo/EventEmitter~EventEmitter.silence * @returns {this} The callee for chaining. * @public */ @@ -129,10 +129,10 @@ var EventEmitter = { }, /** - * Determines whether the callee is currently [silenced]{@link module:enyo/EventEmitter~EventEmitter#silence}. + * Determines whether the callee is currently [silenced]{@link module:enyo/EventEmitter~EventEmitter.silence}. * * @returns {Boolean} Whether or not the callee is - * [silenced]{@link module:enyo/EventEmitter~EventEmitter#silence}. + * [silenced]{@link module:enyo/EventEmitter~EventEmitter.silence}. * @public */ isSilenced: function () { @@ -140,7 +140,7 @@ var EventEmitter = { }, /** - * @deprecated Replaced by {@link module:enyo/EventEmitter~EventEmitter#on} + * @deprecated Replaced by {@link module:enyo/EventEmitter~EventEmitter.on} * @public */ addListener: function (e, fn, ctx) { @@ -148,9 +148,9 @@ var EventEmitter = { }, /** - * Adds an {@glossary event} listener. Until [removed]{@link module:enyo/EventEmitter~EventEmitter#off}, + * Adds an {@glossary event} listener. Until [removed]{@link module:enyo/EventEmitter~EventEmitter.off}, * this listener will fire every time the event is - * [emitted]{@link module:enyo/EventEmitter~EventEmitter#emit}. + * [emitted]{@link module:enyo/EventEmitter~EventEmitter.emit}. * * @param {String} e - The {@glossary event} name to register for. * @param {Function} fn - The listener. @@ -163,7 +163,7 @@ var EventEmitter = { }, /** - * @deprecated Replaced by {@link module:enyo/EventEmitter~EventEmitter#off} + * @deprecated Replaced by {@link module:enyo/EventEmitter~EventEmitter.off} * @public */ removeListener: function (e, fn, ctx) { @@ -227,7 +227,7 @@ var EventEmitter = { }, /** - * @deprecated Replaced by {@link module:enyo/EventEmitter~EventEmitter#emit} + * @deprecated Replaced by {@link module:enyo/EventEmitter~EventEmitter.emit} * @public */ triggerEvent: function () { From f99879325fbb4a2c30d4d7c1c8286cbce14ac50f Mon Sep 17 00:00:00 2001 From: Stephen Choi Date: Tue, 19 Jan 2016 17:35:24 -0800 Subject: [PATCH 100/210] ENYO-3020: Cleanup unnecessary comments Enyo-DCO-1.1-Signed-off-by: Stephen Choi --- src/RepeaterChildSupport.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/RepeaterChildSupport.js b/src/RepeaterChildSupport.js index 46d665ba4..08bc7349c 100644 --- a/src/RepeaterChildSupport.js +++ b/src/RepeaterChildSupport.js @@ -49,7 +49,7 @@ var RepeaterChildSupport = { * @private */ cachePoint: true, - + /* * @method * @private @@ -109,9 +109,9 @@ var RepeaterChildSupport = { } }, /** - * Deliberately used to supersede the default method and set - * [owner]{@link module:enyo/Component~Component#owner} to this [control]{@link module:enyo/Control~Control} so that there - * are no name collisions in the instance [owner]{@link module:enyo/Component~Component#owner}, and also so + * Deliberately used to supersede the default method and set + * [owner]{@link module:enyo/Component~Component#owner} to this [control]{@link module:enyo/Control~Control} so that there + * are no name collisions in the instance [owner]{@link module:enyo/Component~Component#owner}, and also so * that [bindings]{@link module:enyo/Binding~Binding} will correctly map to names. * * @method @@ -132,7 +132,7 @@ var RepeaterChildSupport = { dispatchEvent: kind.inherit(function (sup) { return function (name, event, sender) { var owner; - + // if the event is coming from a child of the repeater-child (this...) and has a // delegate assigned to it there is a distinct possibility it is supposed to be // targeting the instanceOwner of repeater-child not the repeater-child itself @@ -151,7 +151,7 @@ var RepeaterChildSupport = { } } } - + if (!event._fromRepeaterChild) { if (!!~utils.indexOf(name, this.repeater.selectionEvents)) { this._selectionHandler(); @@ -177,8 +177,7 @@ var RepeaterChildSupport = { var bnd = this.binding({ from: 'model.' + s, to: 'selected', - oneWay: false/*, - kind: enyo.BooleanBinding*/ + oneWay: false }); this._selectionBindingId = bnd.euid; } From b85eedf1b3224f2beaf1268ccde8b84645b83f27 Mon Sep 17 00:00:00 2001 From: Aaron Tam Date: Wed, 20 Jan 2016 11:34:50 -0800 Subject: [PATCH 101/210] PLAT-15389: Allow for clearing of queue for pops without a corresponding history entry. Enyo-DCO-1.1-Signed-off-by: Aaron Tam --- src/History.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/History.js b/src/History.js index eaaeb9890..433ed2688 100644 --- a/src/History.js +++ b/src/History.js @@ -227,7 +227,7 @@ var EnyoHistory = module.exports = kind.singleton( _processing = true; if (_queue.length) { this.processQueue(); - } else { + } else if (_history.length) { this.processPopEntry(_history.pop()); } _processing = false; @@ -394,7 +394,7 @@ var EnyoHistory = module.exports = kind.singleton( * @private */ handlePop: function (event) { - if (this.enabled && _history.length) { + if (this.enabled) { this.processState(event.state); } }, From 918ab704e03594fa689fb4b1b121a10dc0d238ce Mon Sep 17 00:00:00 2001 From: "jeremy.thomas" Date: Wed, 20 Jan 2016 14:40:13 -0500 Subject: [PATCH 102/210] ENYO-2409: Fix Windows 10 app deployment/innerHTML issue --- src/dom.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dom.js b/src/dom.js index baf213a66..5cc7f2690 100644 --- a/src/dom.js +++ b/src/dom.js @@ -576,7 +576,7 @@ var dom = module.exports = { }; // override setInnerHtml for Windows 8 HTML applications -if (typeof global.MSApp !== 'undefined') { +if (typeof global.MSApp !== 'undefined' && typeof global.MSApp.execUnsafeLocalFunction !== 'undefined') { dom.setInnerHtml = function(node, html) { global.MSApp.execUnsafeLocalFunction(function() { node.innerHTML = html; From e41dcb7f6948af66112b320741c2c3c149fa1092 Mon Sep 17 00:00:00 2001 From: Aaron Tam Date: Thu, 14 Jan 2016 11:24:53 -0800 Subject: [PATCH 103/210] PLAT-15150: Fix the popOnBack property so that it takes precedence over cacheViews. Enyo-DCO-1.1-Signed-off-by: Aaron Tam --- src/LightPanels/LightPanels.js | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/src/LightPanels/LightPanels.js b/src/LightPanels/LightPanels.js index 7b97dc3ff..ebb09a38a 100644 --- a/src/LightPanels/LightPanels.js +++ b/src/LightPanels/LightPanels.js @@ -488,11 +488,11 @@ module.exports = kind( if (direction < 0) { for (i = panels.length - 1; i > index; i--) { - this.removePanel(panels[i]); + this.removePanel(panels[i], this.popOnBack); } } else { for (i = 0; i < index; i++) { - this.removePanel(panels[i], true); + this.removePanel(panels[i], !this.cacheViews, true); } } }, @@ -501,17 +501,19 @@ module.exports = kind( * Removes the specified panel. * * @param {Object} panel - The panel to remove. + * @param {Boolean} destroy - Whether or not the panel should be destroyed; if `false`, the panel + * will instead be cached. * @param {Boolean} [preserve] - If {@link module:enyo/LightPanels~LightPanels#cacheViews} is * `true`, this value is used to determine whether or not to preserve the current panel's * position in the component hierarchy and on the screen, when caching. * @private */ - removePanel: function (panel, preserve) { + removePanel: function (panel, destroy, preserve) { if (panel) { - if (this.cacheViews) { - this.cacheView(panel, preserve); - } else { + if (destroy) { panel.destroy(); + } else { + this.cacheView(panel, preserve); } } }, @@ -654,13 +656,7 @@ module.exports = kind( cleanUpPanel: function (panel) { if (panel) { panel.set('state', panel === this._currentPanel ? States.ACTIVE : States.INACTIVE); - if (panel.postTransition) { - // Async'ing this as it seems to improve ending transition performance on the TV. - // Requires further investigation into its behavior. - utils.asyncMethod(this, function () { - panel.postTransition(); - }); - } + panel.postTransition && panel.postTransition(); } }, @@ -679,11 +675,6 @@ module.exports = kind( prevPanel = this._previousPanel; currPanel = this._currentPanel; - if ((this._indexDirection < 0 && (this.popOnBack || this.cacheViews) && this.index < this.getPanels().length - 1) || - (this._indexDirection > 0 && this.cacheViews && this.index > 0)) { - this.removePanels(this.index, this._indexDirection); - } - if (prevPanel) { prevPanel.removeClass('shifted'); prevPanel.addClass('offscreen'); @@ -692,6 +683,11 @@ module.exports = kind( this.cleanUpPanel(prevPanel); this.cleanUpPanel(currPanel); + if ((this._indexDirection < 0 && (this.popOnBack || this.cacheViews) && this.index < this.getPanels().length - 1) || + (this._indexDirection > 0 && this.cacheViews && this.index > 0)) { + this.removePanels(this.index, this._indexDirection); + } + this.removeClass('transitioning'); this.transitioning = false; } From 373bcfbf0f6e07e37d286d32d6da2d42db348870 Mon Sep 17 00:00:00 2001 From: Aaron Tam Date: Fri, 22 Jan 2016 10:15:55 -0800 Subject: [PATCH 104/210] Revert "ENYO-2592: Undefer purging." This reverts commit 73d3cd5289e40908cf484aceb811cf574150df4d. --- src/LightPanels/LightPanels.js | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/LightPanels/LightPanels.js b/src/LightPanels/LightPanels.js index ebb09a38a..61647326c 100644 --- a/src/LightPanels/LightPanels.js +++ b/src/LightPanels/LightPanels.js @@ -680,6 +680,8 @@ module.exports = kind( prevPanel.addClass('offscreen'); } + if (this.popQueue && this.popQueue.length) this.finalizePurge(); + this.cleanUpPanel(prevPanel); this.cleanUpPanel(currPanel); @@ -817,9 +819,20 @@ module.exports = kind( * @private */ purge: function () { - var panels = this.getPanels(), - panel; + var panels = this.getPanels(); + this.popQueue = panels.slice(); + panels.length = 0; + this.index = -1; + }, + /** + * Clean-up any panels queued for destruction. + * + * @private + */ + finalizePurge: function () { + var panels = this.popQueue, + panel; while (panels.length) { panel = panels.pop(); if (this.cacheViews) { @@ -829,8 +842,6 @@ module.exports = kind( panel.destroy(); } } - - this.index = -1; }, /** From b64181f59f274497ffcec00570f861745bccb15c Mon Sep 17 00:00:00 2001 From: Aaron Tam Date: Fri, 22 Jan 2016 11:04:42 -0800 Subject: [PATCH 105/210] PLAT-15150: Purge panels after running transition lifecycle methods. Enyo-DCO-1.1-Signed-off-by: Aaron Tam --- src/LightPanels/LightPanels.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/LightPanels/LightPanels.js b/src/LightPanels/LightPanels.js index 61647326c..54e53d480 100644 --- a/src/LightPanels/LightPanels.js +++ b/src/LightPanels/LightPanels.js @@ -680,13 +680,14 @@ module.exports = kind( prevPanel.addClass('offscreen'); } - if (this.popQueue && this.popQueue.length) this.finalizePurge(); - this.cleanUpPanel(prevPanel); this.cleanUpPanel(currPanel); - if ((this._indexDirection < 0 && (this.popOnBack || this.cacheViews) && this.index < this.getPanels().length - 1) || - (this._indexDirection > 0 && this.cacheViews && this.index > 0)) { + if (this.popQueue && this.popQueue.length) { + this.finalizePurge(); + } else if ((this._indexDirection < 0 && (this.popOnBack || this.cacheViews) + && this.index < this.getPanels().length - 1) + || (this._indexDirection > 0 && this.cacheViews && this.index > 0)) { this.removePanels(this.index, this._indexDirection); } From 4a073afa7d51566f45f2de17d19dec8aea10d400 Mon Sep 17 00:00:00 2001 From: Aaron Tam Date: Fri, 22 Jan 2016 16:15:42 -0800 Subject: [PATCH 106/210] PLAT-15150: Refine panel removal and end-of-transition logic. Add popView method to ViewPreloadSupport. --- src/LightPanels/LightPanels.js | 136 +++++++++++++++++---------------- src/ViewPreloadSupport.js | 18 ++++- 2 files changed, 86 insertions(+), 68 deletions(-) diff --git a/src/LightPanels/LightPanels.js b/src/LightPanels/LightPanels.js index 54e53d480..29b04a601 100644 --- a/src/LightPanels/LightPanels.js +++ b/src/LightPanels/LightPanels.js @@ -134,13 +134,13 @@ module.exports = kind( wrap: false, /** - * When `true`, previous panels are automatically popped when moving backwards. + * When `true`, previous panels are destroyed when moving backwards. * * @type {Boolean} - * @default true + * @default false * @public */ - popOnBack: true, + popOnBack: false, /** * The amount of time, in milliseconds, to run the transition animation between panels. @@ -471,53 +471,6 @@ module.exports = kind( return newPanels; }, - /** - * Removes panels whose index is either greater than, or less than, the specified value, - * depending on the direction. - * - * @param {Number} index - Index at which to start removing panels. - * @param {Number} direction - The direction in which we are changing indices. A negative value - * signifies that we are moving backwards, and want to remove panels whose indices are greater - * than the current index. Conversely, a positive value signifies that we are moving forwards, - * and panels whose indices are less than the current index should be removed. - * @public - */ - removePanels: function (index, direction) { - var panels = this.getPanels(), - i; - - if (direction < 0) { - for (i = panels.length - 1; i > index; i--) { - this.removePanel(panels[i], this.popOnBack); - } - } else { - for (i = 0; i < index; i++) { - this.removePanel(panels[i], !this.cacheViews, true); - } - } - }, - - /** - * Removes the specified panel. - * - * @param {Object} panel - The panel to remove. - * @param {Boolean} destroy - Whether or not the panel should be destroyed; if `false`, the panel - * will instead be cached. - * @param {Boolean} [preserve] - If {@link module:enyo/LightPanels~LightPanels#cacheViews} is - * `true`, this value is used to determine whether or not to preserve the current panel's - * position in the component hierarchy and on the screen, when caching. - * @private - */ - removePanel: function (panel, destroy, preserve) { - if (panel) { - if (destroy) { - panel.destroy(); - } else { - this.cacheView(panel, preserve); - } - } - }, - /** * Replaces the panel(s) at the specified index with panels that will be created via provided * component definition(s). @@ -532,17 +485,16 @@ module.exports = kind( */ replaceAt: function (start, count, info) { var panels = this.getPanels(), - insertBefore, commonInfo, end, idx; + queue = this.popQueue, + insertBefore, commonInfo, end; start = start < 0 ? panels.length + start : start; end = start + count; insertBefore = panels[end]; commonInfo = {addBefore: insertBefore}; + queue = queue || []; - // remove existing panels - for (idx = end - 1; idx >= start; idx--) { - this.removePanel(panels[idx]); - } + queue = queue.concat(panels.splice(start, end - start)); // add replacement panels if (utils.isArray(info)) this.pushPanels(info, commonInfo, {direct: true, force: true}); @@ -680,19 +632,21 @@ module.exports = kind( prevPanel.addClass('offscreen'); } - this.cleanUpPanel(prevPanel); - this.cleanUpPanel(currPanel); - - if (this.popQueue && this.popQueue.length) { - this.finalizePurge(); - } else if ((this._indexDirection < 0 && (this.popOnBack || this.cacheViews) - && this.index < this.getPanels().length - 1) - || (this._indexDirection > 0 && this.cacheViews && this.index > 0)) { - this.removePanels(this.index, this._indexDirection); - } - this.removeClass('transitioning'); this.transitioning = false; + + utils.asyncMethod(this, function () { + this.cleanUpPanel(prevPanel); + this.cleanUpPanel(currPanel); + + if (this.popQueue && this.popQueue.length) { + this.finalizePurge(); + } else if ((this._indexDirection < 0 && (this.popOnBack || this.cacheViews) + && this.index < this.getPanels().length - 1) + || (this._indexDirection > 0 && this.cacheViews && this.index > 0)) { + this.removePanels(this.index, this._indexDirection); + } + }); } }, @@ -814,6 +768,56 @@ module.exports = kind( dom.transformValue(container, 'translate' + this.orientation, value + '%'); }, + /** + * Removes panels whose index is either greater than, or less than, the specified value, + * depending on the direction. + * + * @param {Number} index - Index at which to start removing panels. + * @param {Number} direction - The direction in which we are changing indices. A negative value + * signifies that we are moving backwards, and want to remove panels whose indices are greater + * than the current index. Conversely, a positive value signifies that we are moving forwards, + * and panels whose indices are less than the current index should be removed. + * @private + */ + removePanels: function (index, direction) { + var panels = this.getPanels(), + i; + + if (direction < 0) { + for (i = panels.length - 1; i > index; i--) { + this.removePanel(panels[i], this.cacheViews && !this.popOnBack); + } + } else { + for (i = 0; i < index; i++) { + this.removePanel(panels[i], this.cacheViews, true); + } + } + }, + + /** + * Removes the specified panel. + * + * @param {Object} panel - The panel to remove. + * @param {Boolean} cache - Whether or not the panel should be cached; if `false` or not + * specified, the panel will instead be destroyed (this is the default behavior). + * @param {Boolean} [preserve] - If {@link module:enyo/LightPanels~LightPanels#cacheViews} is + * `true`, this value is used to determine whether or not to preserve the current panel's + * position in the component hierarchy and on the screen, when caching. + * @private + */ + removePanel: function (panel, cache, preserve) { + if (panel) { + if (cache) { + this.cacheView(panel, preserve); + } else { + if (this.cacheViews) { + this.popView(this.getViewId(panel)); + } + panel.destroy(); + } + } + }, + /** * Destroys all panels. * diff --git a/src/ViewPreloadSupport.js b/src/ViewPreloadSupport.js index a5054dd36..5c12e3ee1 100644 --- a/src/ViewPreloadSupport.js +++ b/src/ViewPreloadSupport.js @@ -142,13 +142,27 @@ var ViewPreloadSupport = { * @public */ restoreView: function (id) { + var view = this.popView(id); + + if (view) { + this.addControl(view); + } + + return view; + }, + + /** + * Pops the specified view that was previously cached. + * + * @param {String} id - The unique identifier for the cached view that is being popped. + * @public + */ + popView: function (id) { var cp = this._cachedViews, view = cp[id]; if (view) { this.$.viewCache.removeControl(view); - this.addControl(view); - this._cachedViews[id] = null; } From 85298e0ff367ae9a1fc37a818cd12c6c0083eb37 Mon Sep 17 00:00:00 2001 From: Stephen Choi Date: Fri, 22 Jan 2016 17:44:11 -0800 Subject: [PATCH 107/210] ENYO-3031: Fix broken comment block Enyo-DCO-1.1-Signed-off-by: Stephen Choi --- src/Checkbox/Checkbox.js | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/Checkbox/Checkbox.js b/src/Checkbox/Checkbox.js index d58885aa8..77a011a20 100644 --- a/src/Checkbox/Checkbox.js +++ b/src/Checkbox/Checkbox.js @@ -60,36 +60,36 @@ module.exports = kind( /** * @private */ - published: + published: /** @lends module:enyo/Checkbox~Checkbox.prototype */ { - + /** * Value of the checkbox; will be `true` if checked. - * + * * @type {Boolean} * @default false * @public */ checked: false, - + /** * A [Group API]{@link module:enyo/Group~Group} requirement for determining the selected item. - * + * * @type {Boolean} * @default false * @public */ active: false, - + /** * @private */ type: 'checkbox' }, - + /** * Disable classes inherited from {@link module:enyo/Input~Input}. - * + * * @private */ kindClasses: "", @@ -129,7 +129,7 @@ module.exports = kind( * The [active]{@link module:enyo/Checkbox~Checkbox#active} property and `onActivate` * {@glossary event} are part of the [GroupItem]{@link module:enyo/GroupItem~GroupItem} * interface supported by this [object]{@glossary Object}. - * + * * @private */ activeChanged: function () { @@ -139,7 +139,7 @@ module.exports = kind( }, /** - * All [input]{@link module:enyo/Input~Input} type [controls]{@link module:enyo/Control~Control} support the + * All [input]{@link module:enyo/Input~Input} type [controls]{@link module:enyo/Control~Control} support the * [value]{@link module:enyo/Input~Input#value} property. * * @param {Boolean} val - Whether or not the [checkbox]{@link module:enyo/Checkbox~Checkbox} should @@ -167,14 +167,14 @@ module.exports = kind( * @private */ valueChanged: function () { + // inherited behavior is to set "value" attribute and node-property + // which does not apply to checkbox (uses "checked") so + // we squelch the inherited method + }, /** * @private */ - // inherited behavior is to set "value" attribute and node-property - // which does not apply to checkbox (uses "checked") so - // we squelch the inherited method - }, change: function () { var nodeChecked = utils.isTrue(this.getNodeProperty('checked')); this.setActive(nodeChecked); From 101218a5039baec13623174eab58aa3f286fd18f Mon Sep 17 00:00:00 2001 From: Aaron Tam Date: Mon, 25 Jan 2016 11:31:12 -0800 Subject: [PATCH 108/210] ENYO-3018: Fix additional references to enyo.* Enyo-DCO-1.1-Signed-off-by: Aaron Tam --- src/Filter.js | 142 +++++++++++++++--------------- src/ModelController.js | 63 +++++++------ src/Relation.js | 44 ++++----- src/RelationalModel/manyToMany.js | 31 +++---- src/RelationalModel/toOne.js | 91 +++++++++---------- src/UiComponent.js | 11 +-- src/ViewController.js | 4 +- src/utils.js | 3 +- 8 files changed, 196 insertions(+), 193 deletions(-) diff --git a/src/Filter.js b/src/Filter.js index a8927993c..755d75541 100644 --- a/src/Filter.js +++ b/src/Filter.js @@ -14,7 +14,7 @@ var Collection = require('./Collection'); /** * Used internally (re-use) for filters that do not have a valid filter. This means they will * always keep a mirrored copy of the entire current dataset of the parent filter. -* +* * @private */ function alwaysTrue () { @@ -28,31 +28,31 @@ function alwaysTrue () { * collection, which keeps its own set of [model]{@link module:enyo/Model~Model} instances (and can * create, remove, or destroy them), an {@link module:enyo/Filter~Filter} uses another instance of * `enyo.Collection` as its dataset and safely proxies its models as a complete set or -* according to the needs of its subkind. `enyo.Filter` is not intended to communicate +* according to the needs of its subkind. `enyo/Filter` is not intended to communicate * with [sources]{@link module:enyo/Source~Source} (e.g., via [fetch()]{@link module:enyo/Collection~Collection#fetch}). * It maintains an implementation-specific API (from its subkinds) and propagates the -* events and APIs inherited from `enyo.Collection` that are needed to interact with +* events and APIs inherited from `enyo/Collection` that are needed to interact with * [controls]{@link module:enyo/Control~Control}. -* +* * @class Filter * @extends module:enyo/Collection~Collection * @protected */ var Filter = module.exports = kind( /** @lends module:enyo/Filter~Filter.prototype */ { - + name: 'enyo.Filter', - + /** * @private */ kind: Collection, - + /** * @private */ - + /** * Provide a filter-method that will be applied to each [model]{@link module:enyo/Model~Model} in the * current set of models. This method will accept parameters according to those supplied @@ -64,37 +64,37 @@ var Filter = module.exports = kind( * @public */ method: null, - + /** * The actual {@link module:enyo/Collection~Collection} content to proxy. How the collection is * used varies depending on the [subkind]{@glossary subkind} implementing the * feature. - * + * * @type module:enyo/Collection~Collection * @default null * @public */ collection: null, - + /** * Once all components have been created, those that are [filters]{@link module:enyo/Filter~Filter} * (or [subkinds]{@glossary subkind}) will be added to this [array]{@glossary Array}. * This array is primarily for internal use and should not be modified directly. - * + * * @type Array * @default null * @readonly * @public */ filters: null, - + /** * @private */ defaultProps: { kind: null // replaced after the fact }, - + /** * @private */ @@ -102,23 +102,23 @@ var Filter = module.exports = kind( return function (props) { // all filters are public...always...except when they aren't... if (props.publish !== false) props.publish = true; - + sup.apply(this, arguments); - + // now to ensure that there is the correct kind associated with the child component if (typeof props.kind == 'string') props.kind = kind.constructorForKind(props.kind); if (props.kind && props.kind.prototype instanceof Filter) { if (!props.name) { throw 'enyo.Filter.adjustComponentProps: Child filters must have a name'; } - + // if no method is named explicitly we assume the same name as the filter if (!props.method) props.method = props.name; - + // most likely it will be a string but it is possible that the filter method // be declared inline in the component descriptor block if (typeof props.method == 'string') props.method = this[props.method]; - + // we assign an always true method if none exists just because we assume it was // mean to be a mirror filter for the entire dataset if (typeof props.method != 'function') { @@ -128,30 +128,30 @@ var Filter = module.exports = kind( } }; }), - + /** * @private */ addComponent: kind.inherit(function (sup) { return function (comp) { - + // if the component is a filter we add it to the array if (comp instanceof Filter) this.filters.push(comp); - + return sup.apply(this, arguments); }; }), - + /** * Resets the [filter]{@link module:enyo/Filter~Filter} to its initial state. Behavior will * vary depending on the [subkind]{@glossary subkind} implementation. - * + * * @virtual * @method * @public */ reset: utils.nop, - + /** * @private */ @@ -159,16 +159,16 @@ var Filter = module.exports = kind( return function () { // ensure we have an array to work with this.filters = []; - + // unfortunately we must maintain data structures that need remain out of our // proxy path so we each must create a collection instance for internal use this._internal = new Collection({options: {modelEvents: false}}); this._internal.on('*', this._internalEvent, this); - + sup.apply(this, arguments); }; }), - + /** * @private */ @@ -176,37 +176,37 @@ var Filter = module.exports = kind( return function () { var collection, owner; - + sup.apply(this, arguments); - + // we allow filters to be nested so they need to receive events from the // parent-filter and do with them as they need this.isChildFilter = ((owner = this.owner) && owner instanceof Filter); if(this.isChildFilter) { - + // if we're a child collection we don't want to monitor our parent's own state // we want to monitor their entire dataset this.collection = owner._internal; - + // register especially for owner events as we will differentiate them from // normal collection events this.collection.on('*', this._ownerEvent, this); } - + collection = this.collection; - + // if there is a collection instance already we need to initialize it if (collection) this.collectionChanged(null, collection); }; }), - + /** * @private */ destroy: kind.inherit(function (sup) { return function () { var collection = this.collection; - + // make sure that we remove our listener if we're being destroyed for some // reason (this would seem to be an irregular practice) if (collection) { @@ -215,42 +215,42 @@ var Filter = module.exports = kind( } else { collection.off('*', this._collectionEvent, this); } - + collection.unobserve('destroyed', this._collectionDestroyed, this); } - + sup.apply(this, arguments); - + // free our internal collection this._internal.destroy(); this._internal = null; }; }), - + /** * @private */ collectionChanged: function (was, is) { var internal = this._internal; - + if (was) { was.off('*', this._collectionEvent, this); was.unobserve('destroyed', this._collectionDestroyed, this); } - + // ensure that child-filters cannot have their internal/external collections reset if (is && !(was && this.isChildFilter && was === this.owner._internal)) { - + // case of child-filter whose collection is its owner does not need to receive // these events since it will receive them in a special handler to differentiate // these cases if (!this.isChildFilter || (is !== this.owner._internal)) { is.on('*', this._collectionEvent, this); } - + // if for any reason the collection is destroyed we want to know about it is.observe('destroyed', this._collectionDestroyed, this); - + // reset the models (causing reset to propagate to children or bound parties) internal.set('models', is.models.copy()); } else { @@ -258,7 +258,7 @@ var Filter = module.exports = kind( if (internal.length) internal.empty(); } }, - + /** * This method is invoked when events are received from a * [collection]{@link module:enyo/Collection~Collection} that is not the owner of this @@ -267,42 +267,42 @@ var Filter = module.exports = kind( * As long as we are consistent about applying the same action against ourselves, * we should remain in sync and propagate the same event again, except that * `sort` will end up being a `reset`. - * + * * @private */ _collectionEvent: function (sender, e, props) { // we are listening for particular events to signal that we should update according // to its changes if we are a nested filter - + var models = props.models, internal = this._internal; - + switch (e) { case 'add': - + // will ensure an add gets propagated if the models are new internal.add(models, {merge: false}); break; case 'reset': case 'sort': - + // will ensure a reset gets propagated internal.empty(models); break; case 'remove': - + // will ensure a remove gets propagated (assuming something is removed) internal.remove(models); break; case 'change': - + // we need to propagate the change event as our internal collection's own so that // child filters and/or subclasses will be able to handle this as they need to internal.emit(e, props); break; } }, - + /** * When the collection is destroyed we can't use it anymore so we need to remove it as our * collection to prevent weird things from happening. @@ -312,7 +312,7 @@ var Filter = module.exports = kind( _collectionDestroyed: function () { this.set('collection', null); }, - + /** * To be implemented by [subkind]{@glossary subkind}; for internal use only. * @@ -320,7 +320,7 @@ var Filter = module.exports = kind( * @private */ _internalEvent: utils.nop, - + /** * To be implemented by [subkind]{@glossary subkind}; for internal use only. * @@ -328,7 +328,7 @@ var Filter = module.exports = kind( * @private */ _ownerEvent: utils.nop, - + /** * Unavailable on {@link module:enyo/Filter~Filter} and [subkinds]{@glossary subkind}. * @@ -336,7 +336,7 @@ var Filter = module.exports = kind( * @public */ add: utils.nop, - + /** * Unavailable on {@link module:enyo/Filter~Filter} and [subkinds]{@glossary subkind}. * @@ -344,7 +344,7 @@ var Filter = module.exports = kind( * @public */ remove: utils.nop, - + /** * Unavailable on {@link module:enyo/Filter~Filter} and [subkinds]{@glossary subkind}. * @@ -352,7 +352,7 @@ var Filter = module.exports = kind( * @public */ fetch: utils.nop, - + /** * Unavailable on {@link module:enyo/Filter~Filter} and [subkinds]{@glossary subkind}. * @@ -360,7 +360,7 @@ var Filter = module.exports = kind( * @public */ sort: utils.nop, - + /** * Unavailable on {@link module:enyo/Filter~Filter} and [subkinds]{@glossary subkind}. * @@ -368,7 +368,7 @@ var Filter = module.exports = kind( * @public */ commit: utils.nop, - + /** * Overloaded implementation. * @@ -381,7 +381,7 @@ var Filter = module.exports = kind( return this.models ? sup.apply(this.models.at ? this.models : this, arguments) : undefined; }; }), - + /** * Unavailable on {@link module:enyo/Filter~Filter} and [subkinds]{@glossary subkind}. * @@ -389,7 +389,7 @@ var Filter = module.exports = kind( * @public */ raw: utils.nop, - + /** * Unavailable on {@link module:enyo/Filter~Filter} and [subkinds]{@glossary subkind}. * @@ -397,7 +397,7 @@ var Filter = module.exports = kind( * @public */ toJSON: utils.nop, - + /** * Overloaded implementation. * @@ -410,7 +410,7 @@ var Filter = module.exports = kind( return this.models ? sup.apply(this, arguments) : false; }; }), - + /** * Overloaded implementation. * @@ -423,7 +423,7 @@ var Filter = module.exports = kind( return this.models ? sup.apply(this, arguments) : undefined; }; }), - + /** * Overloaded implementation. * @@ -436,7 +436,7 @@ var Filter = module.exports = kind( return this.models ? sup.apply(this, arguments) : []; }; }), - + /** * Overloaded implementation. * @@ -449,7 +449,7 @@ var Filter = module.exports = kind( return this.models ? sup.apply(this, arguments) : undefined; }; }), - + /** * Overloaded implementation. * @@ -462,7 +462,7 @@ var Filter = module.exports = kind( return this.models ? sup.apply(this, arguments) : []; }; }), - + /** * Overloaded implementation. * @@ -475,7 +475,7 @@ var Filter = module.exports = kind( return this.models ? sup.apply(this, arguments) : -1; }; }), - + /** * Unavailable on {@link module:enyo/Filter~Filter} and [subkinds]{@glossary subkind}. * diff --git a/src/ModelController.js b/src/ModelController.js index 06a375eb5..fb7bce9b9 100644 --- a/src/ModelController.js +++ b/src/ModelController.js @@ -34,18 +34,18 @@ var BaseModelController = kind({ * [model]{@link module:enyo/ModelController~ModelController#model} reserved property, the actual model * may be changed without the bindings' needing to know. It will also propagate * events [emitted]{@link module:enyo/EventEmitter~EventEmitter#emit} by the underlying model. -* +* * It is important to note that `'model'` is a reserved property name. Also * note that bindings should **never** bind through the controller to the model * directly. -* +* * **Rules of property resolution** * * If the controller can call [hasOwnProperty()]{@glossary Object.hasOwnProperty} * and it returns `true`, it will look locally; if the property is resolved to * be a computed property, the requested property will be proxied from the given * model, when available. -* +* * @class ModelController * @extends module:enyo/Component~Component * @mixes module:enyo/ComputedSupport~ComputedSupport @@ -55,18 +55,18 @@ var BaseModelController = kind({ */ module.exports = kind( /** @lends module:enyo/ModelController~ModelController.prototype */ { - + name: 'enyo.ModelController', - + /** * @private */ kind: BaseModelController, - + /** - * The {@link module:enyo/Model~Model} to proxy. If this is set to an instance of `enyo.Model`, - * the [controller]{@link module:enyo/ModelController~ModelController} will propagate `enyo.Model` - * [events]{@glossary event} and [notifications]{@link module:enyo/ObserverSupport~ObserverSupport.notify}. + * The {@link module:enyo/Model~Model} to proxy. If this is set to an instance of `enyo/Model`, + * the [controller]{@link module:enyo/ModelController~ModelController} will propagate `enyo/Model` + * [events]{@glossary event} and [notifications]{@link module:enyo/ObserverSupport~ObserverSupport#notify}. * **No bindings should ever bind directly to attributes of this property.** * * Also note that this is a reserved property name and will collide with any @@ -78,52 +78,51 @@ module.exports = kind( * @public */ model: null, - + /** * @private */ proxyObjectKey: 'model', - + /** * @method * @private */ get: kind.inherit(function (sup) { return function (path) { - + if (this.hasOwnProperty(path) || this.isComputed(path)) { return this._getComputed(path); } - + return sup.apply(this, arguments); }; }), - + /** * @method * @private */ set: kind.inherit(function (sup) { return function (path) { - + if (typeof path == 'string') { if (this.hasOwnProperty(path)) { return this.isComputed(path) ? this : utils.setPath.apply(this, arguments); } } - + return sup.apply(this, arguments); }; }), - + /** * @method * @private */ _getComputed: ComputedSupport.get.fn(CoreObject.prototype.get), - + /** - * @type enyo.ObserverSupport~Observer * @private */ modelChanged: function (was, is, path) { @@ -131,7 +130,7 @@ module.exports = kind( if (was) was.off('*', this._modelEvent, this); // register for events on new model if any if (is) is.on('*', this._modelEvent, this); - + // either way we need to update any observers that might be related // to the model var props = this.modelObservedProperties(); @@ -140,10 +139,10 @@ module.exports = kind( this.notify(key, was && was.get(key), is && is.get(key)); } } - + this.emit('model', {was: was, is: is}); }, - + /** * @method * @private @@ -153,7 +152,7 @@ module.exports = kind( // will be this controller but all listeners should expect to use the third parameter as // is the convention for model listeners this.emit(e, props, model); - + switch (e) { case 'change': if (props) for (var key in props) this.notify(key, model.previous[key], props[key]); @@ -163,7 +162,7 @@ module.exports = kind( break; } }, - + /** * @method * @private @@ -171,7 +170,7 @@ module.exports = kind( modelObservedProperties: function () { return this._observedProps || (this._observedProps = {}); }, - + /** * @method * @private @@ -180,24 +179,24 @@ module.exports = kind( return function (path) { var part = path , parts; - + if (path.indexOf('.') > -1) { parts = path.split('.'); part = parts.shift(); } - + if (!this.hasOwnProperty(part) && !this.isComputed(part)) this.modelObservedProperties()[path] = null; return sup.apply(this, arguments); }; }), - + /** * @private */ addObserver: function () { return this.observe.apply(this, arguments); }, - + /** * @private */ @@ -205,13 +204,13 @@ module.exports = kind( return function (props) { // ensure we have our own model property this.model = null; - + // adhere to normal approach to constructor properties hash props && utils.mixin(this, props); sup.apply(this, arguments); }; }), - + /** * @method * @private @@ -222,5 +221,5 @@ module.exports = kind( this.model && this.model.off('*', this._modelEvent, this); }; }) - + }); diff --git a/src/Relation.js b/src/Relation.js index 6cccc89c9..1657aa906 100644 --- a/src/Relation.js +++ b/src/Relation.js @@ -26,7 +26,7 @@ var * @property {Boolean} parse=false - Whether or not the relation should call the * [parse()]{@link module:enyo/Model~Model#parse} method on incoming data before * [setting]{@link module:enyo/Model~Model#set} it on the [model]{@link module:enyo/RelationalModel~RelationalModel}. -* @property {String} model=enyo.RelationalModel - The kind of the +* @property {String} model=enyo/RelationalModel~RelationModel - The kind of the * reverse of the relation. This will vary depending on the type of relation being declared. * @property {Boolean} fetch=false - Whether or not to automatically call * [fetch()]{@link module:enyo/Model~Model#fetch} (or {@link module:enyo/Collection~Collection#fetch}) after initialization. @@ -59,51 +59,51 @@ var relationDefaults = { */ var Relation = module.exports = kind( /** @lends module:enyo/Relation~Relation.prototype */ { - + /** * @private */ - name: "Relation", - + name: 'enyo.Relation', + /** * @private */ kind: null, - + /** * @private */ options: {}, - + /** * @private */ constructor: function (instance, props) { - + // apply any of the properties to ourself for reference utils.mixin(this, [relationDefaults, this.options, props]); - + // store a reference to the model we're relating this.instance = instance; - + // ensure we have a constructor for our related model kind this.model = kind.constructorForKind(this.model); - + this.includeInJSON = props.includeInJSON == null && !this.isOwner ? (this.model.prototype.primaryKey || 'id') : this.includeInJSON; - + // let the subkinds do their thing this.init(); }, - + /** * @private */ getRelated: function () { return this.related; }, - + /** * @private */ @@ -114,24 +114,24 @@ var Relation = module.exports = kind( key = this.key, changed, prev; - - + + if (related) Store.off(model, 'add', this._changed, this); - + this.related = related; - + if (!inst._changing) { - + changed = inst.changed || (inst.changed = {}), prev = inst.previous || (inst.previous = {}); - + changed[key] = related; prev[key] = was; if (was !== related) inst.emit('change', changed); } return this; }, - + /** * @private */ @@ -139,11 +139,11 @@ var Relation = module.exports = kind( var isOwner = this.isOwner, create = this.create, related = this.related; - + if ((isOwner || create) && related && related.destroy && !related.destroyed) { related.destroy(); } - + this.destroyed = true; this.instance = null; this.related = null; diff --git a/src/RelationalModel/manyToMany.js b/src/RelationalModel/manyToMany.js index 221f9f7fa..2cf460296 100644 --- a/src/RelationalModel/manyToMany.js +++ b/src/RelationalModel/manyToMany.js @@ -19,30 +19,31 @@ var */ var manyToMany = module.exports = kind( /** @lends module:enyo/RelationalModel~manyToMany.prototype */ { - + /** * @private */ kind: toMany, - + /** * @private */ name: 'enyo.manyToMany', - + /** * The default [options]{@link module:enyo/RelationalModel~RelationOptions} overloaded for this * [kind]{@glossary kind}. * * @see module:enyo/RelationalModel~toMany#options * @type module:enyo/RelationalModel~RelationOptions - * @property {String} inverseType=enyo.manyToMany - This is the **required** type. + * @property {module:enyo/Relation} inverseType=module:enyo/RelationalModel~manyToMany - This is + * the **required** type. * @public */ options: { inverseType: null // set after the fact }, - + /** * @private */ @@ -55,10 +56,10 @@ var manyToMany = module.exports = kind( rel = model.getRelation(inverseKey), // id = inst.get(inst.primaryKey), isOwner = this.isOwner; - + if (related && related.has(inst)) { // if (related && (related.has(inst) || related.find(function (model) { return model.attributes[model.primaryKey] == id; }))) { - + // if the relation isn't found it probably wasn't defined and we need // to automatically generate it based on what we know if (!rel) { @@ -72,15 +73,15 @@ var manyToMany = module.exports = kind( related: inst }))); } - + // if (rel.related !== inst) rel.setRelated(inst); // if (!rel.related.has(inst)) rel.related.add(inst); return true; } - + return false; }, - + /** * @private */ @@ -92,12 +93,12 @@ var manyToMany = module.exports = kind( isOwner = this.isOwner, model, i; - + // this is a very tricky scenario that we need to be very careful about to try // and avoid unnecessary work (when possible) and to keep out of an infinite // loop of notifications if (sender === related) { - + // we are attempting to distinguish between the occassions we can encounter // this method here if our related collection emits an add, remove or change // event -- if it is change we know it stemmed from a model already @@ -116,7 +117,7 @@ var manyToMany = module.exports = kind( // in this case we removed a/some model/models that should probably be // updated to know about the removal as well for (i = 0; (model = props.models[i]); ++i) { - + // this event will be caught in the event that the model was destroyed // but should that happen the other collections will also have done // this already (or will do it) but if the model is already destroyed @@ -125,7 +126,7 @@ var manyToMany = module.exports = kind( if (!model.destroyed) model.get(inverseKey).remove(inst); } } - + // manyToMany is a special case that requires us to propagate the changes from // either end as changes to the parent model unlike toMany and toOne that // exclusively rely on the isOwner field and safely assuming uni-directional @@ -142,7 +143,7 @@ var manyToMany = module.exports = kind( // return it to whatever it was originally this.isOwner = isOwner; } - + } else sup.apply(this, arguments); }; }) diff --git a/src/RelationalModel/toOne.js b/src/RelationalModel/toOne.js index 1dd3f0847..6237d4bbf 100644 --- a/src/RelationalModel/toOne.js +++ b/src/RelationalModel/toOne.js @@ -20,23 +20,24 @@ var */ var toOne = module.exports = kind( /** @lends module:enyo/RelationalModel~toOne.prototype */ { - + /** * @private */ kind: Relation, - + /** * @private */ name: 'enyo.toOne', - + /** * The default [options]{@link module:enyo/RelationalModel~RelationOptions} overloaded for this * [kind]{@glossary kind}. * * @type module:enyo/RelationalModel~RelationOptions - * @property {String} inverseType=enyo.toOne - This can be `'enyo.toOne'` or `'enyo.toMany'`. + * @property {module:enyo/Relation} inverseType=module:enyo/RelationalModel~toOne - This can be + * {@link module:enyo/RelationalModel~toOne} or {@link module:enyo/RelationalModel~toMany}. * @property {Object} modelOptions - An options hash to pass to the related instance if * `create` is `true`. * @public @@ -45,12 +46,12 @@ var toOne = module.exports = kind( inverseType: null, // set after the fact modelOptions: null }, - + /** * @private */ init: function () { - + var model = this.model, inverseType = this.inverseType, inst = this.instance, @@ -60,44 +61,44 @@ var toOne = module.exports = kind( modelOptions = this.modelOptions, id, found; - + // ensure we have a valid model constructor if (typeof model == 'string') model = kind.constructorForKind(model); - + // ensure our inverse type constructor is correct if (typeof inverseType == 'string') inverseType = kind.constructorForKind(inverseType); - + // ensure we've got the correct related if any if (related || related === 0) this.related = related; - + // the instance attribute for the designated key will actually point to this relation inst.attributes[key] = this; this.inverseType = inverseType; - + // if we have a related value now check to see if it is something we should attempt // to resolve if (related != null) { - + // just make sure that no one stuck an instance in here if (!(related instanceof Model)) { - + // try and figure out what the assumed id for the related model is if possible if (typeof related == 'object') id = related[model.prototype.primaryKey]; else if (typeof related == 'string' || typeof related == 'number') id = related; - + if (id != null) found = Store.resolve(model, id); - + // if we found an instance we store it and make sure to update the local // reference here if (found) related = this.related = found; } } - + // if this is the owner side of the relation we may need to create the instance // for our relation if it wasn't found already if (related == null || !(related instanceof Model)) { if (this.create) { - + // if the only information we have about the thing is a string or number // then we facade a data hash so the model has the opportunity to work // as expected @@ -106,7 +107,7 @@ var toOne = module.exports = kind( related = {}; related[model.prototype.primaryKey] = id; } - + // if the parse flag is true then we force a parse operation on model // creation regardless of its own flags if (this.parse) { @@ -121,26 +122,26 @@ var toOne = module.exports = kind( this.related = model; } } - + if (!found) Store.on(model, 'add', this._changed, this); - + // last but not least we begin to listen for changes on our model instance inst.on('change', this._changed, this); }, - + /** * @private */ setRelated: kind.inherit(function (sup) { return function (related) { var val; - + if (related && related instanceof Model) { return sup.apply(this, arguments); } else if (related != null) { val = related; related = this.getRelated(); - + // the only thing we can do is assume the value is intended to be the primary // key of the model just like we would had it been passed into the constructor if (this.create && related) related.set(related.primaryKey, val); @@ -155,34 +156,34 @@ var toOne = module.exports = kind( if (related && related instanceof Model) return sup.call(this, related); } } - + // @TODO: This ignores cases that it might be set as null or undefined which // would clear the related but most of the code assumes there will always be // a value for related but it seems _possible_ that this behavior may be // necessary so would need to find a way to handle that }; }), - + /** * @private */ fetchRelated: function () { }, - + /** * @private */ findRelated: function () { - + var related = this.related, // inst = this.instance, isOwner = this.isOwner, found, rev; - + if (related && related instanceof this.model) found = related; else { - + // we need to search for the related instance if we can found = Store.findLocal( this.model, @@ -190,20 +191,20 @@ var toOne = module.exports = kind( {all: false, context: this} ); } - + if (found) { - + // if we are the owner end we may have a listener on the store and can // safely remove it Store.off(this.model, 'add', this._changed, this); - + // update our related value this.related = found; - + // if we can/need to we will establish the other end of this relationship if (this.inverseKey) { rev = found.getRelation(this.inverseKey); - + // if there isn't one then we go ahead and create it implicitly if (!rev) { rev = new this.inverseType(found, { @@ -214,10 +215,10 @@ var toOne = module.exports = kind( model: this.instance.ctor, related: this.instance }); - + found.relations.push(rev); } - + // now we ensure that the instances are pointing at eachother switch (rev.kindName) { case 'enyo.toOne': @@ -228,13 +229,13 @@ var toOne = module.exports = kind( break; } } - + if (isOwner) found.on('change', this._changed, this); } - + return found; }, - + /** * @private */ @@ -244,7 +245,7 @@ var toOne = module.exports = kind( id = inst.get(inst.primaryKey), inverseKey = this.inverseKey, pkey = model.get(model.primaryKey); - + return (related && ( model.euid == related || pkey == related || @@ -252,7 +253,7 @@ var toOne = module.exports = kind( ) || (id != null && model.get(inverseKey) == id) ); }, - + /** * @private */ @@ -267,7 +268,7 @@ var toOne = module.exports = kind( } return raw; }, - + /** * @private */ @@ -276,18 +277,18 @@ var toOne = module.exports = kind( inst = this.instance, isOwner = this.isOwner, changed; - + if (sender === this.instance) { if (e == 'change') { if (key in props) this.findRelated(); } } else if (sender === this.related) { if (e == 'change' && isOwner) { - + // if the instance is already changing then we do not need to do anything // because it probably stemmed from there anyway if (inst._changing) return; - + // @todo This must be updated to be more thorough... inst.isDirty = true; changed = inst.changed || (inst.changed = {}); diff --git a/src/UiComponent.js b/src/UiComponent.js index 99989f982..568a9897c 100644 --- a/src/UiComponent.js +++ b/src/UiComponent.js @@ -37,10 +37,11 @@ var UiComponent = module.exports = kind( statics: { /** - * The default set of keys which are effectively "ignored" when determining whether or not the - * this control has changed in such a way that warrants a complete re-render. When - * {@link enyo.UIComponent#updateComponents} is invoked on a parent component, this set of - * stateful keys is utilized by default, if no stateful keys are provided by us. + * The default set of keys which are effectively "ignored" when determining whether or not + * the this control has changed in such a way that warrants a complete re-render. When + * {@link module:enyo/UiComponent~UiComponent#updateComponents} is invoked on a parent + * component, this set of stateful keys is utilized by default, if no stateful keys are + * provided by us. * * @type {String[]} * @default ['content', active', 'disabled'] @@ -689,7 +690,7 @@ var UiComponent = module.exports = kind( ); } }, - + /** * @method * @private diff --git a/src/ViewController.js b/src/ViewController.js index d079b5fdb..fecef85ba 100644 --- a/src/ViewController.js +++ b/src/ViewController.js @@ -81,10 +81,10 @@ module.exports = kind( * string consisting of either `'document.body'` (the default) or the DOM id * of a node (either inserted by an {@link module:enyo/Control~Control} or static HTML * already in the `document.body`). If the controller has a parent (because - * it was instantiated as a component in an `enyo.Control`, this property + * it was instantiated as a component in an `enyo/Control`, this property * will be ignored and the view will instead be rendered in the parent. This * will not happen if the controller is a component of {@link module:enyo/Component~Component} - * or is set as the `controller` property of an `enyo.Control`. + * or is set as the `controller` property of an `enyo/Control`. * * @type {String} * @default 'document.body' diff --git a/src/utils.js b/src/utils.js index c4204fc9d..858e25329 100644 --- a/src/utils.js +++ b/src/utils.js @@ -369,7 +369,8 @@ exports.asyncMethod = function (scope, method) { * arguments `args` ([Array]{@glossary Array}), if the object and method exist. * * @example -* enyo.call(myWorkObject, 'doWork', [3, 'foo']); +* utils = require('enyo/utils'); +* utils.call(myWorkObject, 'doWork', [3, 'foo']); * * @param {Object} scope - The `this` context for the method. * @param {(Function|String)} method - A Function or the name of a method to bind. From c150264ee81c41725db37a42f29090cde37175cd Mon Sep 17 00:00:00 2001 From: Roy Sutton Date: Mon, 25 Jan 2016 14:16:16 -0800 Subject: [PATCH 109/210] Fix documentation of statics Enyo-DCO-1.1-Signed-off-by: Roy Sutton --- src/Ajax.js | 8 +++++++- src/DataList/DataList.js | 7 ++++++- src/Scroller/Scroller.js | 13 ++++++++++--- src/UiComponent.js | 3 ++- 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/Ajax.js b/src/Ajax.js index c3e282f41..266567c8a 100644 --- a/src/Ajax.js +++ b/src/Ajax.js @@ -355,7 +355,13 @@ var Ajax = module.exports = kind( /** * @private */ - statics: { + statics: /** @lends module:enyo/Ajax~Ajax */ { + /** + * Takes an object and converts it to an encoded URI string. NOTE: It does not traverse into + * objects or arrays, so nested objects will be rendered as the string 'object Object', which + * is not terribly useful. + * @public + */ objectToQuery: function (/*Object*/ map) { var enc = encodeURIComponent; var pairs = []; diff --git a/src/DataList/DataList.js b/src/DataList/DataList.js index 7bce1a45e..d65eb00dc 100644 --- a/src/DataList/DataList.js +++ b/src/DataList/DataList.js @@ -643,7 +643,12 @@ var DataList = module.exports = kind( * * @private */ - statics: {delegates: {vertical: VerticalDelegate, horizontal: HorizontalDelegate}}, + statics: /** @lends module:enyo/DataList~DataList */ { + /** + * @private + */ + delegates: {vertical: VerticalDelegate, horizontal: HorizontalDelegate} + }, /** * An [array]{@glossary Array} of the actual page references for easier access. diff --git a/src/Scroller/Scroller.js b/src/Scroller/Scroller.js index 42f99c8f4..0b467e000 100644 --- a/src/Scroller/Scroller.js +++ b/src/Scroller/Scroller.js @@ -295,9 +295,13 @@ var Scroller = module.exports = kind( classes: 'enyo-scroller', /** + * @lends module:enyo/Scroller~Scroller * @private */ statics: { + /** + * @private + */ osInfo: [ {os: 'android', version: 3}, {os: 'androidChrome', version: 18}, @@ -308,7 +312,7 @@ var Scroller = module.exports = kind( {os: 'blackberry', version:1e9}, {os: 'tizen', version: 2} ], - //* Returns true if platform should have touch events. + /** Returns true if platform should have touch events. */ hasTouchScrolling: function() { for (var i=0, t; (t=this.osInfo[i]); i++) { if (platform[t.os]) { @@ -321,8 +325,8 @@ var Scroller = module.exports = kind( } }, /** - Returns true if the platform has native div scrollers (desktop - browsers always have them). + * Returns true if the platform has native div scrollers (desktop + * browsers always have them). */ hasNativeScrolling: function() { for (var i=0, t; (t=this.osInfo[i]); i++) { @@ -332,6 +336,9 @@ var Scroller = module.exports = kind( } return true; }, + /** + * @private + */ getTouchStrategy: function() { return (platform.androidChrome >= 27) || (platform.android >= 3) || (platform.windowsPhone === 8) || (platform.webos >= 4) ? TranslateScrollStrategy diff --git a/src/UiComponent.js b/src/UiComponent.js index 568a9897c..651599974 100644 --- a/src/UiComponent.js +++ b/src/UiComponent.js @@ -34,7 +34,8 @@ var UiComponent = module.exports = kind( */ kind: Component, - statics: { + statics: + /** @lends module:enyo/UiComponent~UiComponent */ { /** * The default set of keys which are effectively "ignored" when determining whether or not From 93c60ec3ec12d5fb77e60a6194f1d9314423aeda Mon Sep 17 00:00:00 2001 From: Roy Sutton Date: Mon, 25 Jan 2016 15:30:39 -0800 Subject: [PATCH 110/210] Tweak relational options slightly Enyo-DCO-1.1-Signed-off-by: Roy Sutton --- src/RelationalModel/manyToMany.js | 2 +- src/RelationalModel/toMany.js | 2 +- src/RelationalModel/toOne.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/RelationalModel/manyToMany.js b/src/RelationalModel/manyToMany.js index 2cf460296..74eb793bc 100644 --- a/src/RelationalModel/manyToMany.js +++ b/src/RelationalModel/manyToMany.js @@ -36,7 +36,7 @@ var manyToMany = module.exports = kind( * * @see module:enyo/RelationalModel~toMany#options * @type module:enyo/RelationalModel~RelationOptions - * @property {module:enyo/Relation} inverseType=module:enyo/RelationalModel~manyToMany - This is + * @property {module:enyo/Relation~Relation} inverseType=module:enyo/RelationalModel~manyToMany - This is * the **required** type. * @public */ diff --git a/src/RelationalModel/toMany.js b/src/RelationalModel/toMany.js index e2cdd1add..198bb1b15 100644 --- a/src/RelationalModel/toMany.js +++ b/src/RelationalModel/toMany.js @@ -42,7 +42,7 @@ var toMany = module.exports = kind( * @type module:enyo/RelationalModel~RelationOptions * @property {Boolean} create=true - By default, the relation should create the * [collection]{@link module:enyo/Collection~Collection} automatically. - * @property {module:enyo/Collection~Collection} collection=RelationalCollection - The + * @property {module:enyo/Collection~Collection} collection=module:enyo/RelationalModel~RelationalCollection - The * [kind]{@glossary kind} of collection to use; can be the kind name or a * reference to the constructor. * @property {Object} collectionOptions - An options hash to pass to the diff --git a/src/RelationalModel/toOne.js b/src/RelationalModel/toOne.js index 6237d4bbf..baf018e20 100644 --- a/src/RelationalModel/toOne.js +++ b/src/RelationalModel/toOne.js @@ -36,7 +36,7 @@ var toOne = module.exports = kind( * [kind]{@glossary kind}. * * @type module:enyo/RelationalModel~RelationOptions - * @property {module:enyo/Relation} inverseType=module:enyo/RelationalModel~toOne - This can be + * @property {module:enyo/Relation~Relation} inverseType=module:enyo/RelationalModel~toOne - This can be * {@link module:enyo/RelationalModel~toOne} or {@link module:enyo/RelationalModel~toMany}. * @property {Object} modelOptions - An options hash to pass to the related instance if * `create` is `true`. From 4fb919903b89b7ca857c7ad5e41119dae49221c4 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Tue, 26 Jan 2016 15:28:10 -0600 Subject: [PATCH 111/210] guard against shifting onhold events for cancelled holds If endHold() is called during a hold event handlers, this._unsent will be nulled which causes an exception because it is assumed to be an array. Adding a truthy guard to ensure that the next event is only shifted if it hasn't been cleared. Issue: ENYO-3038 Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/gesture/drag.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gesture/drag.js b/src/gesture/drag.js index 8de40002d..deab434ce 100644 --- a/src/gesture/drag.js +++ b/src/gesture/drag.js @@ -586,7 +586,7 @@ module.exports = { } this._pulsing = true; dispatcher.dispatch(e); - n = this._next = this._unsent.shift(); + n = this._next = this._unsent && this._unsent.shift(); } }, From 5355e3dbddd5198b0a6e9855db1e8f4dd490b5fe Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Tue, 26 Jan 2016 11:36:19 -0600 Subject: [PATCH 112/210] clean up drag status ondragfinish Previous assumption was that resetting the drag status on start would be sufficient but a left over dragView can be inadvertently removed when a drag on a contained ViewManager isn't handled and it propagates up to the parent VM. Issue: ENYO-3037 Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewManager/ViewManager.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 34a36ac6f..04d5a0d42 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -1058,7 +1058,11 @@ var ViewMgr = kind( this.flicked = false; event.preventTap(); + this.dragView = null; return true; + } else { + this.set('dragging', false); + this.dragView = null; } }, From 028963adfd9fb35dedaa859ce17aed6f338cabee Mon Sep 17 00:00:00 2001 From: Roy Sutton Date: Thu, 28 Jan 2016 13:26:55 -0800 Subject: [PATCH 113/210] Update documentation for ViewManager Enyo-DCO-1.1-Signed-off-by: Roy Sutton --- src/SlideViewLayout/SlideViewLayout.js | 15 ++++++++++++--- src/TransitionViewLayout.js | 8 +++++--- src/ViewLayout/ViewLayout.js | 10 ++++++---- src/ViewManager/ScrimSupport.js | 18 ++++++++++++++++-- src/ViewManager/ViewManager.js | 22 +++++++++++++--------- 5 files changed, 52 insertions(+), 21 deletions(-) diff --git a/src/SlideViewLayout/SlideViewLayout.js b/src/SlideViewLayout/SlideViewLayout.js index b5f5c8531..00c2d8de1 100644 --- a/src/SlideViewLayout/SlideViewLayout.js +++ b/src/SlideViewLayout/SlideViewLayout.js @@ -1,3 +1,10 @@ +/** +* Exports the {@link module:enyo/SlideViewLayout~SlideViewLayout} kind. +* +* @module enyo/SlideViewLayout +* @wip +*/ + var dom = require('enyo/dom'), kind = require('enyo/kind'); @@ -23,10 +30,12 @@ var * Removes the directional classes and resets the `dragDuration` * * @class SlideViewLayout -* @extends enyo/TransitionViewLayout~TransitionViewLayout +* @extends module:enyo/TransitionViewLayout~TransitionViewLayout +* @wip * @public */ -module.exports = kind({ +module.exports = kind( + /** @lends module:enyo/SlideViewLayout~SlideViewLayout.prototype */ { /** * @private */ @@ -151,4 +160,4 @@ module.exports = kind({ } TransitionViewLayout.prototype.completeTransition.apply(this, arguments); } -}); \ No newline at end of file +}); diff --git a/src/TransitionViewLayout.js b/src/TransitionViewLayout.js index b16f4a1f6..ee6956cc2 100644 --- a/src/TransitionViewLayout.js +++ b/src/TransitionViewLayout.js @@ -27,11 +27,13 @@ var * * `completeTransition()` * Removes the directional classes and resets the `dragDuration` * -* @class enyo.SlideViewLayout +* @class TransitionViewLayout +* @extends module:enyo/ViewLayout~ViewLayout * @public * @wip */ -module.exports = kind({ +module.exports = kind( + /** @lends module:enyo/TransitionViewLayout~TransitionViewLayout.prototype */ { /** * @private */ @@ -119,4 +121,4 @@ module.exports = kind({ return true; } } -}); \ No newline at end of file +}); diff --git a/src/ViewLayout/ViewLayout.js b/src/ViewLayout/ViewLayout.js index 1073b3ab3..b5cdd253a 100644 --- a/src/ViewLayout/ViewLayout.js +++ b/src/ViewLayout/ViewLayout.js @@ -1,5 +1,6 @@ - /** +* Exports the {@link module:enyo/ViewLayout~ViewLayout} kind. +* * @module enyo/ViewLayout * @wip */ @@ -38,12 +39,13 @@ var ViewLayoutSupport = { * Called twice, once for the becoming-active view and once for the becoming-inactive view. * Removes the `transitioning` class and deactivates the now inactive view. * -* @class enyo.ViewLayout +* @class ViewLayout +* @extends module:enyo/Layout~Layout * @public * @wip */ module.exports = kind( - /** @lends enyo.ViewLayout.prototype */ { + /** @lends module:enyo/ViewLayout~ViewLayout.prototype */ { /** * @private @@ -261,4 +263,4 @@ module.exports = kind( var handler = this.handlers && this.handlers[name]; if (handler) this[handler](sender, event); } -}); \ No newline at end of file +}); diff --git a/src/ViewManager/ScrimSupport.js b/src/ViewManager/ScrimSupport.js index 15f2c49eb..7fe6946b4 100644 --- a/src/ViewManager/ScrimSupport.js +++ b/src/ViewManager/ScrimSupport.js @@ -2,7 +2,19 @@ var kind = require('../kind'), utils = require('enyo/utils'); -module.exports = { + +/** +* A mixin for use by ViewManager. Applies a user-defined `scrimConfig` if present. +* +* @name module:enyo/ViewManager~ScrimSupport +* @mixin +* @wip +* @protected +*/ +var ScrimSupport = { + /** + * @private + */ initComponents: kind.inherit(function (sup) { return function () { var config = {name: 'scrim', classes: 'enyo-viewmanager-scrim enyo-fit'}; @@ -22,4 +34,6 @@ module.exports = { }, this); }; }) -}; \ No newline at end of file +}; + +module.exports = ScrimSupport; diff --git a/src/ViewManager/ViewManager.js b/src/ViewManager/ViewManager.js index 34a36ac6f..303b5c0cf 100644 --- a/src/ViewManager/ViewManager.js +++ b/src/ViewManager/ViewManager.js @@ -114,7 +114,7 @@ var viewCount = 0; * * ``` * module.exports = kind({ -* kind: ViewMgr, +* kind: ViewManager, * classes: 'contacts', * * // All the views are declared in the common components block @@ -139,7 +139,7 @@ var viewCount = 0; * // Child ViewManagers are declared within a new managers block * managers: [ * {name: 'add', kind: AddContact}, -* {name: 'inline', kind: ViewMgr, floating: true, components: [ +* {name: 'inline', kind: ViewManager, floating: true, components: [ * {content: 'view1', style: 'background: #424242; color: #fff;', ontap: 'nextInline'}, * {content: 'view2', style: 'background: #424242; color: #fff;', ontap: 'nextInline'}, * {content: 'view3', style: 'background: #424242; color: #fff;', ontap: 'dismissInline'} @@ -147,7 +147,7 @@ var viewCount = 0; * ], * * create: function () { -* ViewMgr.prototype.create.apply(this, arguments); +* ViewManager.prototype.create.apply(this, arguments); * * function log (sender, name, event) { * console.log('Event', name, @@ -334,7 +334,7 @@ var ViewMgr = kind( /** * Active view * - * @type {Control} + * @type {module:enyo/Control~Control} * @private */ active: null, @@ -388,10 +388,8 @@ var ViewMgr = kind( dragView: null, /** - * - * - * @type {Boolean} - */ + * @type {Boolean} + */ flicked: false, /** @@ -1144,4 +1142,10 @@ var ViewMgr = kind( }); module.exports = ViewMgr; -module.exports.ScrimSupport = ScrimSupport; \ No newline at end of file + +/** +* The {@link module:enyo/ViewManager~ScrimSupport} mixin +* +* @private +*/ +module.exports.ScrimSupport = ScrimSupport; From 3b6f01b982a5491c1a0e83fe7138744851eb59f5 Mon Sep 17 00:00:00 2001 From: Roy Sutton Date: Thu, 28 Jan 2016 14:15:52 -0800 Subject: [PATCH 114/210] ENYO-3047 Update (allthedependencies) Enyo-DCO-1.1-Signed-off-by: Roy Sutton --- package.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 7f9ed4af4..67da02234 100644 --- a/package.json +++ b/package.json @@ -35,17 +35,17 @@ "url": "http://github.com/enyojs/enyo" }, "devDependencies": { - "chai": "^3.2.0", - "enyo-dev": "^0.5.1", + "chai": "^3.5.0", + "enyo-dev": "^0.5.2", "gulp": "^3.9.0", "gulp-concat": "^2.6.0", - "gulp-jshint": "^1.11.2", - "gulp-mocha-phantomjs": "^0.9.0", - "jshint": "^2.8.0", - "jshint-stylish": "^2.0.1", - "mocha": "^2.3.0", - "sinon": "^1.16.1", + "gulp-jshint": "^2.0.0", + "gulp-mocha-phantomjs": "^0.10.1", + "jshint": "^2.9.1", + "jshint-stylish": "^2.1.0", + "mocha": "^2.4.4", + "sinon": "^1.17.3", "sinon-chai": "^2.8.0", - "through2": "^0.6.5" + "through2": "^2.0.0" } } From 551b8b8881ee3cd470e7a4d7f1313f70a9e17ee5 Mon Sep 17 00:00:00 2001 From: Gray Norton Date: Fri, 29 Jan 2016 11:41:12 -0800 Subject: [PATCH 115/210] ENYO-3049: Calculate bounds when shown `enyo/Scrollable` has a `calcBoundaries()` method that it uses internally and exposes publicly to ensure that a scrollable Control stays up to date with respect to its own size and the size of its contents. In this change, we add a call to `calcBoundaries()` when the scrollable Control is shown to ensure the boundaries are correct, taking into account any changes that may have occurred while the Control was hidden. This change was prompted by ENYO-3049, in which the scroll boundaries and position were inaccurate after hiding NewDataList, removing items from its backing collection, and then re-showing the list. We chose this simple fix over more complicated alternatives, including deferring calls to `calcBoundaries()` when the scrollable Control was hidden and then calling it only when necessary in `showingChangedHandler()`. In truth, there are probably a bunch of things in Scrollable that can / should be deferred when the Control is hidden, but we'll save that larger effort until we know it's needed. Enyo-DCO-1.1-Signed-Off-By: Gray Norton (gray.norton@lge.com) --- src/Scrollable/Scrollable.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Scrollable/Scrollable.js b/src/Scrollable/Scrollable.js index c2eb8055e..fc3997b9f 100644 --- a/src/Scrollable/Scrollable.js +++ b/src/Scrollable/Scrollable.js @@ -245,6 +245,16 @@ module.exports = { showingChangedHandler: kind.inherit(function (sup) { return function (sender, event) { + // Calculate boundaries when shown, just in case + // anything has happened (like scroller contents changing) + // while we were hidden. We do this unconditionally since + // it's cheap to do it now and we avoid a lot of extra + // complexity by not trying to track whether we need it. + // May need to revisit this decision if related issues + // arise. + if (event.showing) { + this.calcBoundaries(); + } sup.apply(this, arguments); if (!event.showing && this._suppressing) { this._resumeMouseEvents(); From dcc85ec2ec38531bd00e639ed6588390ecf4370b Mon Sep 17 00:00:00 2001 From: Aaron Tam Date: Fri, 29 Jan 2016 13:11:56 -0800 Subject: [PATCH 116/210] ENYO-3053: Mark TransitionScrollStrategy as WIP. Enyo-DCO-1.1-Signed-off-by: Aaron Tam --- src/TransitionScrollStrategy.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/TransitionScrollStrategy.js b/src/TransitionScrollStrategy.js index 0c05cc2a8..90a7b8e04 100644 --- a/src/TransitionScrollStrategy.js +++ b/src/TransitionScrollStrategy.js @@ -2,6 +2,7 @@ require('enyo'); /** * Contains the declaration for the {@link module:enyo/TransitionScrollStrategy~TransitionScrollStrategy} kind. +* @wip * @module enyo/TransitionScrollStrategy */ @@ -60,6 +61,7 @@ var * * @class TransitionScrollStrategy * @extends module:enyo/TouchScrollStrategy~TouchScrollStrategy +* @wip * @protected */ var TransitionScrollStrategy = module.exports = kind( From 50a008cda38bacd8bfd2852aa6295ee7fa93106d Mon Sep 17 00:00:00 2001 From: Roy Sutton Date: Fri, 29 Jan 2016 13:44:45 -0800 Subject: [PATCH 117/210] ENYO-1810 Cleanup in-line samples for modules Enyo-DCO-1.1-Signed-off-by: Roy Sutton --- src/Component.js | 6 +++--- src/Repeater.js | 2 +- src/pageVisibility.js | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Component.js b/src/Component.js index 541d5cbd0..d54b3b15d 100644 --- a/src/Component.js +++ b/src/Component.js @@ -43,7 +43,7 @@ var * var c = new Component({ * name: 'me', * components: [ -* {kind: 'Component', name: 'other'} +* {kind: Component, name: 'other'} * ] * }); * @@ -55,7 +55,7 @@ var * var c = new Component({ * name: 'me', * components: [ -* {kind: 'Component', name: 'other'} +* {kind: Component, name: 'other'} * ] * }); * @@ -83,7 +83,7 @@ var * var c = new Component({ * name: 'me', * components: [ -* {kind: 'Component', name: 'other', publish: true} +* {kind: Component, name: 'other', publish: true} * ] * }); * diff --git a/src/Repeater.js b/src/Repeater.js index 569635545..930ccae2c 100644 --- a/src/Repeater.js +++ b/src/Repeater.js @@ -95,7 +95,7 @@ var OwnerProxy = kind( * Repeater = require('enyo/Repeater'); * * {kind: Repeater, count: 2, onSetupItem: 'setImageSource', components: [ -* {kind: 'Image'} +* {kind: Image} * ]} * * setImageSource: function(inSender, inEvent) { diff --git a/src/pageVisibility.js b/src/pageVisibility.js index c493e7ff9..6f45652f7 100644 --- a/src/pageVisibility.js +++ b/src/pageVisibility.js @@ -22,7 +22,7 @@ var * module.exports = kind({ * name: 'App', * components: [ -* {kind: 'Signals', onvisibilitychange: 'visibilitychanged'} +* {kind: Signals, onvisibilitychange: 'visibilitychanged'} * ], * visibilitychanged: function() { * if(enyo.hidden){ From 69a1267f9dc67705f134828d609850af0d9b7419 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Tue, 12 Jan 2016 16:03:28 -0600 Subject: [PATCH 118/210] remove observers on destroy Remove all observers from an object when destroyed to release any memory retained by references to destroyed objects in the observerTable Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ObserverSupport.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ObserverSupport.js b/src/ObserverSupport.js index 1df5d353c..db4d0a2c7 100644 --- a/src/ObserverSupport.js +++ b/src/ObserverSupport.js @@ -509,7 +509,8 @@ var ObserverSupport = { chain; sup.apply(this, arguments); - + + this.removeAllObservers(); if (chains) { for (path in chains) { chain = chains[path]; From 6bfe76a5499da9ab586a3674d140c588c869bddb Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Wed, 13 Jan 2016 12:40:40 -0600 Subject: [PATCH 119/210] remove event listeners on destroy Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/EventEmitter.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/EventEmitter.js b/src/EventEmitter.js index 2af1b8c04..1e6cdc02a 100644 --- a/src/EventEmitter.js +++ b/src/EventEmitter.js @@ -6,6 +6,7 @@ require('enyo'); var + kind = require('./kind'), utils = require('./utils'); var @@ -245,7 +246,17 @@ var EventEmitter = { */ emit: function () { return !this._silenced? emit(this, arguments): false; - } + }, + + /** + * @private + */ + destroy: kind.inherit(function (sup) { + return function () { + sup.apply(this, arguments); + this.removeAllListeners(); + }; + }) }; module.exports = EventEmitter; From 50ed0ca4fe1799bd995dd8a889812d60b3663d3d Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Wed, 13 Jan 2016 12:41:14 -0600 Subject: [PATCH 120/210] remove models from collection when destroying Ensures that the event listeners added to each model are removed thereby deferencing the collection from the EventEmitter eventTable. Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/Collection.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Collection.js b/src/Collection.js index 2389700c6..e684776aa 100644 --- a/src/Collection.js +++ b/src/Collection.js @@ -1043,12 +1043,13 @@ exports = module.exports = kind( // before we lose access to the collection's content! return this; } - - if (this.length && options.destroy) this.empty(options); - + + // remove the models from the collection which will also remove the its event listeners + if (this.length) this.empty(options); + // set the final resting state of this collection this.set('status', States.DESTROYED); - + sup.apply(this, arguments); }; }), From 315496590f7384425f115db76a8caaa658c80122 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Wed, 13 Jan 2016 16:35:29 -0600 Subject: [PATCH 121/210] ensure each instance of Collection get its own copy of options Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/Collection.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Collection.js b/src/Collection.js index e684776aa..ba720a171 100644 --- a/src/Collection.js +++ b/src/Collection.js @@ -1294,6 +1294,9 @@ exports = module.exports = kind( if (props && props.options) { this.options = utils.mixin({}, [this.options, props.options]); delete props.options; + } else { + // ensure we have our own copy of options + this.options = utils.clone(this.options); } opts = opts? utils.mixin({}, [this.options, opts]): this.options; From 87d1161171e76021eb2d43f9e46f1b59e9248a23 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Fri, 29 Jan 2016 09:53:22 -0600 Subject: [PATCH 122/210] delete observerTable and eventTable entries when removing all Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/EventEmitter.js | 2 +- src/ObserverSupport.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/EventEmitter.js b/src/EventEmitter.js index 1e6cdc02a..38bb50135 100644 --- a/src/EventEmitter.js +++ b/src/EventEmitter.js @@ -201,7 +201,7 @@ var EventEmitter = { return ln.event != e; }); } else { - eventTable[euid] = null; + delete eventTable[euid]; } } diff --git a/src/ObserverSupport.js b/src/ObserverSupport.js index db4d0a2c7..decff104f 100644 --- a/src/ObserverSupport.js +++ b/src/ObserverSupport.js @@ -373,7 +373,7 @@ var ObserverSupport = { if (path) { loc[path] = null; } else { - observerTable[euid] = null; + delete observerTable[euid]; } } From 993f61c2c12c7d0c9ef6fec27b36ef9ffcda724c Mon Sep 17 00:00:00 2001 From: Aaron Tam Date: Thu, 4 Feb 2016 10:51:14 -0800 Subject: [PATCH 123/210] ENYO-2913: Make return values and error conditions consistent. Enyo-DCO-1.1-Signed-off-by: Aaron Tam --- src/LightPanels/LightPanels.js | 43 +++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/src/LightPanels/LightPanels.js b/src/LightPanels/LightPanels.js index d6f3c3e76..ae4058ef0 100644 --- a/src/LightPanels/LightPanels.js +++ b/src/LightPanels/LightPanels.js @@ -336,13 +336,15 @@ module.exports = kind( * Animates to the specified panel index. * * @param {Number} index - The index of the panel we wish to animate a transition to. + * @return {Boolean} If `true`, the index to animate to was successful; `false` otherwise (i.e. + * if the index is invalid, or another animation is already in progress). * @public */ animateTo: function (index) { var from = this.index; this.index = index; this.notifyObservers('index'); - this.setupTransitions(from, true); + return this.setupTransitions(from, true); }, /** @@ -390,7 +392,8 @@ module.exports = kind( * @param {Object} moreInfo - Additional properties to be applied (defaults). * @param {module:enyo/LightPanels~PushPanelOptions} opts - Additional options to be used during * panel pushing. - * @return {Object} The instance of the panel that was created on top of the stack. + * @return {Object|undefined} The instance of the panel that was created; if + * `undefined`, the panel could not be pushed (i.e. we are currently transitioning). * @public */ pushPanel: function (info, moreInfo, opts) { @@ -429,12 +432,12 @@ module.exports = kind( * @param {Object} moreInfo - Additional properties to be applied (defaults). * @param {module:enyo/LightPanels~PushPanelOptions} opts - Additional options to be used when * pushing multiple panels. - * @return {null|Object[]} Array of the panels that were created on top of the stack, or - * `null` if panels could not be created. + * @return {Object[]|undefined} Array of the panels that were created on top of the stack; if + * `undefined`, the panels could not be pushed (i.e. we are currently transitioning). * @public */ pushPanels: function (info, moreInfo, opts) { - if (this.transitioning) return true; + if (this.transitioning) return; if (opts && opts.purge) { this.purge(); @@ -524,11 +527,16 @@ module.exports = kind( * @param {Number} count - The number of panels we wish to replace. * @param {Object|Object[]} info - The component definition (or array of component definitions) * for the replacement panel(s). + * @return {Object|Object[]|undefined} The panel or array of the panels that were pushed; if + * `undefined`, the replacement could not be processed (i.e. we are currently transitioning). * @public */ replaceAt: function (start, count, info) { - var panels = this.getPanels(), - insertBefore, commonInfo, end, idx; + var panels, insertBefore, commonInfo, end, idx; + + if (this.transitioning) return; + + panels = this.getPanels(); start = start < 0 ? panels.length + start : start; end = start + count; @@ -541,8 +549,8 @@ module.exports = kind( } // add replacement panels - if (utils.isArray(info)) this.pushPanels(info, commonInfo, {direct: true, force: true}); - else this.pushPanel(info, commonInfo, {direct: true, force: true}); + if (utils.isArray(info)) return this.pushPanels(info, commonInfo, {direct: true, force: true}); + else return this.pushPanel(info, commonInfo, {direct: true, force: true}); }, @@ -721,15 +729,20 @@ module.exports = kind( * @param {Number} [previousIndex] - The index of the panel we are transitioning from. * @param {Boolean} [animate] - Whether or not there should be a visible animation when * transitioning between the current and next panel. + * @return {Boolean} If `true`, the transition was setup successfully, otherwise it was not (i.e. + * we are currently transitioning or there is no "next" panel to transition to). * @private */ setupTransitions: function (previousIndex, animate) { - var panels = this.getPanels(), - nextPanel = panels[this.index], - currPanel = this._currentPanel, - shiftCurrent, fnInitiateTransition; + var panels, nextPanel, currPanel, shiftCurrent, fnInitiateTransition; + + if (this.transitioning) return; - if (nextPanel && !this.transitioning) { + panels = this.getPanels(); + nextPanel = panels[this.index]; + currPanel = this._currentPanel; + + if (nextPanel) { this.transitioning = true; this._indexDirection = 0; @@ -769,6 +782,8 @@ module.exports = kind( if (!this.generated || !animate) fnInitiateTransition(); else animation.requestAnimationFrame(fnInitiateTransition); + + return true; } }, From 3f6dda5c53b46eaa2b4029d120a29b34efa5b278 Mon Sep 17 00:00:00 2001 From: Jason Robitaille Date: Thu, 4 Feb 2016 17:04:26 -0800 Subject: [PATCH 124/210] ENYO-3080: requestAnimationFrame not in usage for iOS >=7 --- src/animation.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/animation.js b/src/animation.js index 2aa09be80..ebb28a5d9 100644 --- a/src/animation.js +++ b/src/animation.js @@ -33,8 +33,8 @@ var _cancelFrame = function(inId) { }; for (var i = 0, pl = prefix.length, p, wc, wr; (p = prefix[i]) || i < pl; i++) { - // if we're on ios 6 just use setTimeout, requestAnimationFrame has some kinks currently - if (platform.ios >= 6) { + // if we're on ios 6 just use setTimeout, requestAnimationFrame has some kinks + if (platform.ios < 7) { break; } From 60e3e0ffe2305ce49fe5122d71ce936261911c35 Mon Sep 17 00:00:00 2001 From: Roy Sutton Date: Thu, 4 Feb 2016 17:56:46 -0800 Subject: [PATCH 125/210] ENYO-3078 Updated Docs to prevent duplicate modules Enyo-DCO-1.1-Signed-off-by: Roy Sutton --- src/Binding.js | 2 +- src/LightPanels/LightPanel.js | 12 ++++----- src/Relation.js | 6 ++--- src/RelationalModel/RelationalCollection.js | 8 +++--- src/RelationalModel/RelationalModel.js | 30 ++++++++++++--------- src/RelationalModel/index.js | 2 +- src/RelationalModel/manyToMany.js | 18 ++++++------- src/RelationalModel/toMany.js | 12 ++++----- src/RelationalModel/toOne.js | 14 +++++----- 9 files changed, 54 insertions(+), 50 deletions(-) diff --git a/src/Binding.js b/src/Binding.js index 2136af067..1d627e60a 100644 --- a/src/Binding.js +++ b/src/Binding.js @@ -686,7 +686,7 @@ exports.DIRTY_TO = DIRTY_TO; exports.defaultBindingKind = exports; /** -* The kind declaration for the [PassiveBinding]{@link module:Binding~PassiveBinding} kind +* The kind declaration for the [PassiveBinding]{@link module:enyo/Binding~PassiveBinding} kind * @public */ exports.PassiveBinding = PassiveBinding; diff --git a/src/LightPanels/LightPanel.js b/src/LightPanels/LightPanel.js index 564d75bb8..6af768418 100644 --- a/src/LightPanels/LightPanel.js +++ b/src/LightPanels/LightPanel.js @@ -1,7 +1,7 @@ /** -* Contains the declaration for the {@link module:enyo/LightPanels~LightPanel} kind. +* Contains the declaration for the {@link module:enyo/LightPanels/LightPanel~LightPanel} kind. * @wip -* @module enyo/LightPanels +* @module enyo/LightPanels/LightPanel */ require('enyo'); @@ -14,7 +14,7 @@ var /** * @enum {Number} -* @memberof module:enyo/LightPanels~LightPanel +* @memberof module:enyo/LightPanels/LightPanel~LightPanel * @public */ var States = { @@ -35,7 +35,7 @@ var States = { * @public */ module.exports = kind( - /** @lends module:enyo/LightPanels~LightPanel.prototype */ { + /** @lends module:enyo/LightPanels/LightPanel~LightPanel.prototype */ { /** * @private @@ -48,9 +48,9 @@ module.exports = kind( kind: Control, /** - * The current [state]{@link module:enyo/LightPanels~LightPanel#States}. + * The current [state]{@link module:enyo/LightPanels/LightPanel~LightPanel#States}. * - * @type {module:enyo/LightPanels~LightPanel#States} + * @type {module:enyo/LightPanels/LightPanel~LightPanel#States} * @default null * @public */ diff --git a/src/Relation.js b/src/Relation.js index 1657aa906..9fce06f38 100644 --- a/src/Relation.js +++ b/src/Relation.js @@ -13,10 +13,10 @@ var Store = require('./Store'); /** -* The default options for [relations]{@link module:enyo/RelationalModel~RelationalModel#relations}. +* The default options for [relations]{@link module:enyo/RelationalModel/RelationalModel~RelationalModel#relations}. * These may vary depending on the individual [kind]{@glossary kind} of relation. * -* @typedef {Object} module:enyo/RelationalModel~RelationOptions +* @typedef {Object} module:enyo/Relation~RelationOptions * @property {String} type=toOne - The [kind]{@glossary kind} of relation being declared. * Can be the name of the relation type or a reference to the constructor. * @property {String} key=null - The [attribute]{@link module:enyo/Model~Model#attributes} name for the @@ -25,7 +25,7 @@ var * the instance of the related kind. * @property {Boolean} parse=false - Whether or not the relation should call the * [parse()]{@link module:enyo/Model~Model#parse} method on incoming data before -* [setting]{@link module:enyo/Model~Model#set} it on the [model]{@link module:enyo/RelationalModel~RelationalModel}. +* [setting]{@link module:enyo/Model~Model#set} it on the [model]{@link module:enyo/RelationalModel/RelationalModel~RelationalModel}. * @property {String} model=enyo/RelationalModel~RelationModel - The kind of the * reverse of the relation. This will vary depending on the type of relation being declared. * @property {Boolean} fetch=false - Whether or not to automatically call diff --git a/src/RelationalModel/RelationalCollection.js b/src/RelationalModel/RelationalCollection.js index 4989f64b4..3b8852512 100644 --- a/src/RelationalModel/RelationalCollection.js +++ b/src/RelationalModel/RelationalCollection.js @@ -1,6 +1,6 @@ /** -* Contains the declaration for the {@link module:enyo/RelationalModel~RelationalCollection} kind. -* @module enyo/RelationalModel +* Contains the declaration for the {@link module:enyo/RelationalModel/RelationalCollection~RelationalCollection} kind. +* @module enyo/RelationalModel/RelationalCollection */ var @@ -12,14 +12,14 @@ var /** * Private class for a collection with a default model kind of -* {@link module:enyo/RelationalModel~RelationalModel} as opposed to {@link module:enyo/Model~Model}. +* {@link module:enyo/RelationalModel/RelationalModel~RelationalModel} as opposed to {@link module:enyo/Model~Model}. * * @class RelationalCollection * @extends module:enyo/Collection~Collection * @private */ module.exports = kind( - /** @lends module:enyo/RelationalModel~RelationalCollection.prototype */ { + /** @lends module:enyo/RelationalModel/RelationalCollection~RelationalCollection.prototype */ { /** * @private diff --git a/src/RelationalModel/RelationalModel.js b/src/RelationalModel/RelationalModel.js index 8f07a9c54..4399e1e9a 100644 --- a/src/RelationalModel/RelationalModel.js +++ b/src/RelationalModel/RelationalModel.js @@ -1,6 +1,10 @@ /** - * Contains the declaration for the {@link module:enyo/RelationalModel~RelationalModel} kind. - * @module enyo/RelationalModel + * Contains the declaration for the {@link module:enyo/RelationalModel/RelationalModel~RelationalModel} kind. + * + * NOTE: Do not require this module for use in applications. Require + * {@link module:enyo/RelationalModel} instead. + * + * @module enyo/RelationalModel/RelationalModel */ var @@ -18,7 +22,7 @@ var /** * A type of {@link module:enyo/Model~Model} extended to automatically understand relationships with * other models. You may define these relationship via the -* [relations]{@link module:enyo/RelationalModel~RelationalModel#relations} property. These relationships allow +* [relations]{@link module:enyo/RelationalModel/RelationalModel~RelationalModel#relations} property. These relationships allow * individual models to exist separately, but be treated as a single entity. * * @class RelationalModel @@ -26,7 +30,7 @@ var * @public */ var RelationalModel = module.exports = kind( - /** @lends module:enyo/RelationalModel~RelationalModel.prototype */ { + /** @lends module:enyo/RelationalModel/RelationalModel~RelationalModel.prototype */ { name: 'enyo.RelationalModel', @@ -42,12 +46,12 @@ var RelationalModel = module.exports = kind( /** * An [array]{@glossary Array} declaring relationships of this - * [model]{@link module:enyo/RelationalModel~RelationalModel} to other models. + * [model]{@link module:enyo/RelationalModel/RelationalModel~RelationalModel} to other models. * These are [hashes]{@glossary Object} of corresponding - * [properties]{@link module:enyo/RelationalModel~RelationOptions} used to define + * [properties]{@link module:enyo/Relation~RelationOptions} used to define * and configure individual relations. Relations may be of the type - * {@link module:enyo/RelationalModel~toOne}, {@link module:enyo/RelationalModel~toMany}, - * or {@link module:enyo/RelationalModel~manyToMany}. Each relation must include a + * {@link module:enyo/RelationalModel/toOne~toOne}, {@link module:enyo/RelationalModel/toMany~toMany}, + * or {@link module:enyo/RelationalModel/manyToMany~manyToMany}. Each relation must include a * `key` property that is the name of the local * [attribute]{@link module:enyo/Model~Model#attributes}. For example: * @@ -82,7 +86,7 @@ var RelationalModel = module.exports = kind( * ([attribute]{@link module:enyo/Model~Model#attributes}). * * @param {String} key - The key as defined in the - * [relations]{@link module:enyo/RelationalModel~RelationalModel#relations} property. + * [relations]{@link module:enyo/RelationalModel/RelationalModel~RelationalModel#relations} property. * @returns {(Relation|undefined)} The correct relation instance, or * `undefined` if not found. * @public @@ -97,7 +101,7 @@ var RelationalModel = module.exports = kind( * Determines whether the requested key is the name of a relation. * * @param {String} key - The key as defined in the - * [relations]{@link module:enyo/RelationalModel~RelationalModel#relations} property. + * [relations]{@link module:enyo/RelationalModel/RelationalModel~RelationalModel#relations} property. * @returns {(Relation|undefined)} The correct relation instance, or * `undefined` if not found. * @public @@ -134,7 +138,7 @@ var RelationalModel = module.exports = kind( /** * Overloaded version of [set()]{@link module:enyo/Model~Model#set} with the ability to - * set values for related [models]{@link module:enyo/RelationalModel~RelationalModel} as well. + * set values for related [models]{@link module:enyo/RelationalModel/RelationalModel~RelationalModel} as well. * * @private */ @@ -312,7 +316,7 @@ var RelationalModel = module.exports = kind( /** * Defines a named relation type * -* @name module:enyo/RelationalModel~RelationalModel.defineRelationType +* @name module:enyo/RelationalModel/RelationalModel~RelationalModel.defineRelationType * @static * @method * @param {String} name Name of relation type @@ -329,7 +333,7 @@ RelationalModel.defineRelationType = function (name, type, isDefault) { /** * Ensures that we concatenate (sanely) the relations for any subkinds. * -* @name module:enyo/RelationalModel~RelationalModel.concat +* @name module:enyo/RelationalModel/RelationalModel~RelationalModel.concat * @static * @method * @private diff --git a/src/RelationalModel/index.js b/src/RelationalModel/index.js index cb79150ab..3fa195b15 100644 --- a/src/RelationalModel/index.js +++ b/src/RelationalModel/index.js @@ -1,7 +1,7 @@ require('enyo'); /** -* Contains the declaration for the {@link module:enyo/RelationalModel~RelationalModel} kind. +* Entry point for the {@link module:enyo/RelationalModel/RelationalModel~RelationalModel} kind. * @module enyo/RelationalModel */ diff --git a/src/RelationalModel/manyToMany.js b/src/RelationalModel/manyToMany.js index 74eb793bc..8687c3d1e 100644 --- a/src/RelationalModel/manyToMany.js +++ b/src/RelationalModel/manyToMany.js @@ -1,6 +1,6 @@ /** -* Contains the declaration for the {@link module:moonstone/RelationalModel~manyToMany} kind. -* @module enyo/RelationalModel +* Contains the declaration for the {@link module:enyo/RelationalModel/manyToMany~manyToMany} kind. +* @module enyo/RelationalModel/manyToMany */ var @@ -14,11 +14,11 @@ var * models. This is an internally-used class. * * @class manyToMany -* @extends module:enyo/RelationalModel~toMany +* @extends module:enyo/RelationalModel/toMany~toMany * @protected */ var manyToMany = module.exports = kind( - /** @lends module:enyo/RelationalModel~manyToMany.prototype */ { + /** @lends module:enyo/RelationalModel/manyToMany~manyToMany.prototype */ { /** * @private @@ -31,13 +31,13 @@ var manyToMany = module.exports = kind( name: 'enyo.manyToMany', /** - * The default [options]{@link module:enyo/RelationalModel~RelationOptions} overloaded for this + * The default [options]{@link module:enyo/Relation~RelationOptions} overloaded for this * [kind]{@glossary kind}. * - * @see module:enyo/RelationalModel~toMany#options - * @type module:enyo/RelationalModel~RelationOptions - * @property {module:enyo/Relation~Relation} inverseType=module:enyo/RelationalModel~manyToMany - This is - * the **required** type. + * @see module:enyo/RelationalModel/toMany~toMany#options + * @type module:enyo/Relation~RelationOptions + * @property {module:enyo/Relation~Relation} inverseType=module:enyo/RelationalModel/manyToMany~manyToMany - + * This is the **required** type. * @public */ options: { diff --git a/src/RelationalModel/toMany.js b/src/RelationalModel/toMany.js index 198bb1b15..de91352f6 100644 --- a/src/RelationalModel/toMany.js +++ b/src/RelationalModel/toMany.js @@ -1,6 +1,6 @@ /** - * Contains the declaration for the {@link module:enyo/RelationalModel~toMany} kind. - * @module enyo/RelationalModel + * Contains the declaration for the {@link module:enyo/RelationalModel/toMany~toMany} kind. + * @module enyo/RelationalModel/toMany */ var @@ -23,7 +23,7 @@ var * @protected */ var toMany = module.exports = kind( - /** @lends module:enyo/RelationalModel~toMany.prototype */ { + /** @lends module:enyo/RelationalModel/toMany~toMany.prototype */ { /** * @private @@ -36,13 +36,13 @@ var toMany = module.exports = kind( name: 'enyo.toMany', /** - * The default [options]{@link module:enyo/RelationalModel~RelationOptions} overloaded for this + * The default [options]{@link module:enyo/Relation~RelationOptions} overloaded for this * [kind]{@glossary kind}. * - * @type module:enyo/RelationalModel~RelationOptions + * @type module:enyo/Relation~RelationOptions * @property {Boolean} create=true - By default, the relation should create the * [collection]{@link module:enyo/Collection~Collection} automatically. - * @property {module:enyo/Collection~Collection} collection=module:enyo/RelationalModel~RelationalCollection - The + * @property {module:enyo/Collection~Collection} collection=module:enyo/RelationalModel/RelationalCollection~RelationalCollection - The * [kind]{@glossary kind} of collection to use; can be the kind name or a * reference to the constructor. * @property {Object} collectionOptions - An options hash to pass to the diff --git a/src/RelationalModel/toOne.js b/src/RelationalModel/toOne.js index baf018e20..1f760472b 100644 --- a/src/RelationalModel/toOne.js +++ b/src/RelationalModel/toOne.js @@ -1,6 +1,6 @@ /** -* Contains the declaration for the {@link module:enyo/RelationalModel~toOne} kind. -* @module enyo/RelationalModel +* Contains the declaration for the {@link module:enyo/RelationalModel/toOne~toOne} kind. +* @module enyo/RelationalModel/toOne */ var @@ -19,7 +19,7 @@ var * @protected */ var toOne = module.exports = kind( - /** @lends module:enyo/RelationalModel~toOne.prototype */ { + /** @lends module:enyo/RelationalModel/toOne~toOne.prototype */ { /** * @private @@ -32,12 +32,12 @@ var toOne = module.exports = kind( name: 'enyo.toOne', /** - * The default [options]{@link module:enyo/RelationalModel~RelationOptions} overloaded for this + * The default [options]{@link module:enyo/Relation~RelationOptions} overloaded for this * [kind]{@glossary kind}. * - * @type module:enyo/RelationalModel~RelationOptions - * @property {module:enyo/Relation~Relation} inverseType=module:enyo/RelationalModel~toOne - This can be - * {@link module:enyo/RelationalModel~toOne} or {@link module:enyo/RelationalModel~toMany}. + * @type module:enyo/Relation~RelationOptions + * @property {module:enyo/Relation~Relation} inverseType=module:enyo/RelationalModel/toOne~toOne - This can be + * {@link module:enyo/RelationalModel/toOne~toOne} or {@link module:enyo/RelationalModel/toMany~toMany}. * @property {Object} modelOptions - An options hash to pass to the related instance if * `create` is `true`. * @public From 96efc6521df53d29a74e6c0e3859f64dbf8af638 Mon Sep 17 00:00:00 2001 From: Jason Robitaille Date: Thu, 4 Feb 2016 19:47:16 -0800 Subject: [PATCH 126/210] Specific exclusion of iOS 6 for requestAnimationFrame --- src/animation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/animation.js b/src/animation.js index ebb28a5d9..420271680 100644 --- a/src/animation.js +++ b/src/animation.js @@ -34,7 +34,7 @@ var _cancelFrame = function(inId) { for (var i = 0, pl = prefix.length, p, wc, wr; (p = prefix[i]) || i < pl; i++) { // if we're on ios 6 just use setTimeout, requestAnimationFrame has some kinks - if (platform.ios < 7) { + if (platform.ios === 6) { break; } From 1daed0c93befa1c3d3b1894d2398c8f395b0d7b5 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Fri, 5 Feb 2016 14:27:36 -0600 Subject: [PATCH 127/210] complete outstanding transition when registering a new transition There are a couple scenarios in which a transition might not complete before another is registered possibly causing layout completion activities to be skipped. To avoid this, mark any incomplete transitions complete so the callback can fire to clean up before registering the new transition. Issue: ENYO-3071 Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/ViewLayout/ViewLayout.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/ViewLayout/ViewLayout.js b/src/ViewLayout/ViewLayout.js index b5cdd253a..ce27ad7c5 100644 --- a/src/ViewLayout/ViewLayout.js +++ b/src/ViewLayout/ViewLayout.js @@ -218,6 +218,13 @@ module.exports = kind( */ registerTransition: function (was, is) { var t = this._transitioning; + + // if there is an active transition, we need to complete it so things aren't left hanging + // short circuiting isTransitioning to optimize and since we have intimate knowledge here as + // part of the transition registration API. + if (!t.to.complete) this.setTransitionComplete('to'); + if (!t.from.complete) this.setTransitionComplete('from'); + t.from.view = was; t.from.complete = !was; t.to.view = is; From 81f039dc1316ac4041e7f5e871dfd2e0540f23f2 Mon Sep 17 00:00:00 2001 From: "jeremy.thomas" Date: Mon, 8 Feb 2016 17:58:09 -0500 Subject: [PATCH 128/210] Update ms gesture conditional --- src/platform.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform.js b/src/platform.js index 666fbd54c..d00c27592 100644 --- a/src/platform.js +++ b/src/platform.js @@ -46,7 +46,7 @@ exports = module.exports = { * `true` if the platform has native double-finger [events]{@glossary event}. * @public */ - gesture: Boolean(('ongesturestart' in window) || window.navigator.msMaxTouchPoints || window.navigator.maxTouchPoints) + gesture: Boolean(('ongesturestart' in window) || (window.navigator.msMaxTouchPoints && window.navigator.msMaxTouchPoints > 1) || (window.navigator.maxTouchPoints && window.navigator.maxTouchPoints > 1)) /** * The name of the platform that was detected or `undefined` if the platform From 195278b3a647e777a8711ddd7075baf7ab0c3915 Mon Sep 17 00:00:00 2001 From: Aaron Tam Date: Tue, 9 Feb 2016 16:45:30 -0800 Subject: [PATCH 129/210] ENYO-2951: Expose transitioning property via a public method. Enyo-DCO-1.1-Signed-off-by: Aaron Tam --- src/LightPanels/LightPanels.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/LightPanels/LightPanels.js b/src/LightPanels/LightPanels.js index e63fb6ef3..f5e20407f 100644 --- a/src/LightPanels/LightPanels.js +++ b/src/LightPanels/LightPanels.js @@ -192,6 +192,11 @@ module.exports = kind( */ reverseForRtl: false, + /** + * @private + */ + transitioning: false, + /** * @private */ @@ -326,6 +331,16 @@ module.exports = kind( return (this._panels = this._panels || (this.controlParent || this).children); }, + /** + * Whether or not we are currently in the midst of a panel transition. + * + * @return {Boolean} If `true`, we are currently transitioning; otherwise, `false`. + * @public + */ + isTransitioning: function () { + return this.transitioning; + }, + /* From 0f904086c52871307f7c29a6136766d37e2048a3 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Fri, 11 Dec 2015 10:45:45 -0600 Subject: [PATCH 130/210] apply translate3d to views to force compositing during dragging Issue: PLAT-14017 Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/SlideViewLayout/SlideViewLayout.js | 29 +++++++++++++++++------- src/SlideViewLayout/SlideViewLayout.less | 15 ++++++------ 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/src/SlideViewLayout/SlideViewLayout.js b/src/SlideViewLayout/SlideViewLayout.js index 00c2d8de1..6e9d21e12 100644 --- a/src/SlideViewLayout/SlideViewLayout.js +++ b/src/SlideViewLayout/SlideViewLayout.js @@ -63,6 +63,21 @@ module.exports = kind( view.addRemoveClass(className, addRemove); }, + /** + * @private + */ + transform: function (view, px) { + var v, + isHorizontal = this.container.orientation == 'horizontal'; + + if (px === null) { + v = null; + } else { + v = isHorizontal ? px + 'px, 0, 0' : '0, ' + px + 'px, 0'; + } + dom.transformValue(view, 'translate3d', v); + }, + /** * @private */ @@ -72,8 +87,7 @@ module.exports = kind( bounds = c.dragBounds, isHorizontal = c.orientation == 'horizontal', size = isHorizontal ? bounds.width : bounds.height, - delta = event.delta, - transform = isHorizontal ? 'translateX' : 'translateY'; + delta = event.delta; if (event.delta < 0 && event.delta < -size) { this.overDrag = true; @@ -88,10 +102,10 @@ module.exports = kind( } TransitionViewLayout.prototype.drag.apply(this, arguments); - dom.transformValue(c.active, transform, delta + 'px'); + this.transform(c.active, delta); if (c.dragView) { px = this.container.layoutCover ? 0 : size * event.direction + delta; - dom.transformValue(c.dragView, transform, px + 'px'); + this.transform(c.dragView, px); } }, @@ -119,16 +133,15 @@ module.exports = kind( * @private */ transition: function (was, is) { - var dir, - transform = this.container.orientation == 'horizontal' ? 'translateX' : 'translateY'; + var dir; TransitionViewLayout.prototype.transition.apply(this, arguments); if (was && was != this.dragView) { - dom.transformValue(was, transform, null); + this.transform(was, null); } if (is) { this.addRemoveDirection(is, false); - if (is != this.dragView) dom.transformValue(is, transform, null); + if (is != this.dragView) this.transform(is, null); } // If the user drags the entire view off screen, it won't animate so we won't see the CSS diff --git a/src/SlideViewLayout/SlideViewLayout.less b/src/SlideViewLayout/SlideViewLayout.less index 8bb5331d5..b5592f70b 100644 --- a/src/SlideViewLayout/SlideViewLayout.less +++ b/src/SlideViewLayout/SlideViewLayout.less @@ -4,9 +4,10 @@ @{prop}: @val; } > .enyo-view { - .pre(transform, translateX(-100%)); + .pre(transform, translate3d(-100%, 0, 0)); .pre(transition-property, none); .pre(transition-timing-function, linear); + &.active { .pre(transform, translate3d(0, 0, 0)); } } &:not(.dragging) > .enyo-view.transitioning { @@ -15,15 +16,13 @@ } &.horizontal > .enyo-view { - &.forward { .pre(transform, translateX(100%)); } - &.back { .pre(transform, translateX(-100%)); } - &.active { .pre(transform, translateX(0)); } + &.forward { .pre(transform, translate3d(100%, 0, 0)); } + &.back { .pre(transform, translate3d(-100%, 0, 0)); } } &.vertical > .enyo-view { - &.forward { .pre(transform, translateY(-100%)); } - &.back { .pre(transform, translateY(100%)); } - &.active { .pre(transform, translateY(0)); } + &.forward { .pre(transform, translateY(0, -100%, 0)); } + &.back { .pre(transform, translateY(0, 100%, 0)); } } &.cover { @@ -33,7 +32,7 @@ // unless it's the stationary view which should always remain behind &.stationary { z-index: 0; - .pre(transform, translateX(0px)); + .pre(transform, translate3d(0, 0, 0)); } } From 9d353388d8db8b4bc4464c910b0b507be3f707ce Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Tue, 15 Dec 2015 14:38:25 -0600 Subject: [PATCH 131/210] fix CSS ordering for active view positioning Moving it up for DRY-ness broke the transition. /sadtrombone Issue: PLAT-14017 Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/SlideViewLayout/SlideViewLayout.less | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/SlideViewLayout/SlideViewLayout.less b/src/SlideViewLayout/SlideViewLayout.less index b5592f70b..70fc689c4 100644 --- a/src/SlideViewLayout/SlideViewLayout.less +++ b/src/SlideViewLayout/SlideViewLayout.less @@ -7,7 +7,6 @@ .pre(transform, translate3d(-100%, 0, 0)); .pre(transition-property, none); .pre(transition-timing-function, linear); - &.active { .pre(transform, translate3d(0, 0, 0)); } } &:not(.dragging) > .enyo-view.transitioning { @@ -18,11 +17,13 @@ &.horizontal > .enyo-view { &.forward { .pre(transform, translate3d(100%, 0, 0)); } &.back { .pre(transform, translate3d(-100%, 0, 0)); } + &.active { .pre(transform, translate3d(0, 0, 0)); } } &.vertical > .enyo-view { &.forward { .pre(transform, translateY(0, -100%, 0)); } &.back { .pre(transform, translateY(0, 100%, 0)); } + &.active { .pre(transform, translate3d(0, 0, 0)); } } &.cover { From defaa5c12d532cf97908383610f2f95206096ead Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Wed, 10 Feb 2016 16:13:59 -0600 Subject: [PATCH 132/210] clear the model for unrendered rows of a DataRepeater Issue: ENYO-2867 Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/VerticalDelegate.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/VerticalDelegate.js b/src/VerticalDelegate.js index 7c29c0cf4..119315896 100644 --- a/src/VerticalDelegate.js +++ b/src/VerticalDelegate.js @@ -194,6 +194,7 @@ module.exports = { view = page.children[i]; view.teardownRender(); view.canGenerate = false; + view.set('model', null); } // update the entire page at once - this removes old nodes and updates // to the correct ones From f4639ff5254818c7207430533f984eca5cfb7d4b Mon Sep 17 00:00:00 2001 From: Aaron Tam Date: Thu, 11 Feb 2016 15:10:31 -0800 Subject: [PATCH 133/210] PLAT-15150: Clean-up cruft, add documentation. Enyo-DCO-1.1-Signed-off-by: Aaron Tam --- src/LightPanels/LightPanels.js | 7 +++---- src/ViewPreloadSupport.js | 1 + 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/LightPanels/LightPanels.js b/src/LightPanels/LightPanels.js index 29b04a601..313cc95c2 100644 --- a/src/LightPanels/LightPanels.js +++ b/src/LightPanels/LightPanels.js @@ -485,16 +485,15 @@ module.exports = kind( */ replaceAt: function (start, count, info) { var panels = this.getPanels(), - queue = this.popQueue, - insertBefore, commonInfo, end; + panelsToPop, insertBefore, commonInfo, end; start = start < 0 ? panels.length + start : start; end = start + count; insertBefore = panels[end]; commonInfo = {addBefore: insertBefore}; - queue = queue || []; - queue = queue.concat(panels.splice(start, end - start)); + panelsToPop = panels.splice(start, end - start); + this.popQueue = (this.popQueue && this.popQueue.concat(panelsToPop)) || panelsToPop; // add replacement panels if (utils.isArray(info)) this.pushPanels(info, commonInfo, {direct: true, force: true}); diff --git a/src/ViewPreloadSupport.js b/src/ViewPreloadSupport.js index 5c12e3ee1..b1cf4b78e 100644 --- a/src/ViewPreloadSupport.js +++ b/src/ViewPreloadSupport.js @@ -155,6 +155,7 @@ var ViewPreloadSupport = { * Pops the specified view that was previously cached. * * @param {String} id - The unique identifier for the cached view that is being popped. + * @return {Object} The popped view. * @public */ popView: function (id) { From ee1a181d5d510858d8ebb0c193c03ecb605b0349 Mon Sep 17 00:00:00 2001 From: Roy Sutton Date: Thu, 11 Feb 2016 16:10:05 -0800 Subject: [PATCH 134/210] Clarified LightPanel should not be required directly Enyo-DCO-1.1-Signed-off-by: Roy Sutton --- src/LightPanels/LightPanel.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/LightPanels/LightPanel.js b/src/LightPanels/LightPanel.js index 6af768418..5f728b53e 100644 --- a/src/LightPanels/LightPanel.js +++ b/src/LightPanels/LightPanel.js @@ -1,5 +1,8 @@ /** * Contains the declaration for the {@link module:enyo/LightPanels/LightPanel~LightPanel} kind. +* +* Note: LightPanel is exported from {@link module:enyo/LightPanels}. This module should not be +* required directly. * @wip * @module enyo/LightPanels/LightPanel */ From e716ece8803823772b53a7e658dd660e4ecab91f Mon Sep 17 00:00:00 2001 From: Roy Sutton Date: Fri, 12 Feb 2016 17:39:00 -0800 Subject: [PATCH 135/210] Doc LightPanel to be part of LightPanels again Enyo-DCO-1.1-Signed-off-by: Roy Sutton --- src/LightPanels/LightPanel.js | 14 ++++++++------ src/LightPanels/LightPanels.js | 4 ++++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/LightPanels/LightPanel.js b/src/LightPanels/LightPanel.js index 5f728b53e..9af7cffe5 100644 --- a/src/LightPanels/LightPanel.js +++ b/src/LightPanels/LightPanel.js @@ -1,10 +1,11 @@ /** -* Contains the declaration for the {@link module:enyo/LightPanels/LightPanel~LightPanel} kind. +* Contains the declaration for the {@link module:enyo/LightPanels~LightPanel} kind. * * Note: LightPanel is exported from {@link module:enyo/LightPanels}. This module should not be * required directly. * @wip -* @module enyo/LightPanels/LightPanel +* @ignore +* @module enyo/LightPanels */ require('enyo'); @@ -17,7 +18,7 @@ var /** * @enum {Number} -* @memberof module:enyo/LightPanels/LightPanel~LightPanel +* @memberof module:enyo/LightPanels~LightPanel * @public */ var States = { @@ -32,13 +33,14 @@ var States = { * between child components. * * @class LightPanel +* @name module:enyo/LightPanels~LightPanel * @extends module:enyo/Control~Control * @ui * @wip * @public */ module.exports = kind( - /** @lends module:enyo/LightPanels/LightPanel~LightPanel.prototype */ { + /** @lends module:enyo/LightPanels~LightPanel.prototype */ { /** * @private @@ -51,9 +53,9 @@ module.exports = kind( kind: Control, /** - * The current [state]{@link module:enyo/LightPanels/LightPanel~LightPanel#States}. + * The current [state]{@link module:enyo/LightPanels~LightPanel#States}. * - * @type {module:enyo/LightPanels/LightPanel~LightPanel#States} + * @type {module:enyo/LightPanels~LightPanel#States} * @default null * @public */ diff --git a/src/LightPanels/LightPanels.js b/src/LightPanels/LightPanels.js index e63fb6ef3..bdaf95e17 100644 --- a/src/LightPanels/LightPanels.js +++ b/src/LightPanels/LightPanels.js @@ -865,6 +865,10 @@ module.exports = kind( } }); +/** +* The {@link module:enyo/LightPanels~LightPanel} kind export. +* @public +*/ module.exports.Panel = LightPanel; module.exports.Direction = Direction; module.exports.Orientation = Orientation; From c42b810f3be2a8797bc243a1af387d27f9ad2f91 Mon Sep 17 00:00:00 2001 From: Aaron Tam Date: Tue, 16 Feb 2016 12:24:40 -0800 Subject: [PATCH 136/210] ENYO-3011: Ensure that transition clean-up logic is always executed. Enyo-DCO-1.1-Signed-off-by: Aaron Tam --- src/LightPanels/LightPanels.js | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/LightPanels/LightPanels.js b/src/LightPanels/LightPanels.js index e63fb6ef3..90a9d5c04 100644 --- a/src/LightPanels/LightPanels.js +++ b/src/LightPanels/LightPanels.js @@ -677,13 +677,17 @@ module.exports = kind( * * @param {Object} sender - The event sender. * @param {Object} ev - The event object. - * @param {Boolean} [direct] - If `true`, this was a non-animated (direct) transition. * @private */ - transitionFinished: function (sender, ev, direct) { + transitionFinished: function (sender, ev) { var prevPanel, currPanel; - if (this.transitioning && ((ev && ev.originator === this.$.client) || direct)) { + if (this.transitioning && (!ev || ev.originator === this.$.client)) { + if (this._fallbackTimeout) { + global.clearTimeout(this._fallbackTimeout); + this._fallbackTimeout = null; + } + prevPanel = this._previousPanel; currPanel = this._currentPanel; @@ -805,7 +809,8 @@ module.exports = kind( this._currentPanel = nextPanel; // ensure that `transitionFinished` is called in the case where we are not animating - if (!this.shouldAnimate() || !animate) this.transitionFinished(null, null, true); + if (!this.shouldAnimate() || !animate) this.transitionFinished(); + else this.setupFallback(); }, /** @@ -862,6 +867,13 @@ module.exports = kind( for (var idx = 0; idx < viewProps.length; idx++) { this.removeTask(this.getViewId(viewProps[idx])); } + }, + + /** + * @private + */ + setupFallback: function () { + this._fallbackTimeout = global.setTimeout(this.bindSafely('transitionFinished'), this.duration + 100); } }); From 0008016742b84a035c5f8973114535ffd1e8d72d Mon Sep 17 00:00:00 2001 From: Aaron Tam Date: Wed, 17 Feb 2016 11:29:16 -0800 Subject: [PATCH 137/210] ENYO-3011: The fallback should not run faster than the transition; removing offset. Enyo-DCO-1.1-Signed-off-by: Aaron Tam --- src/LightPanels/LightPanels.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LightPanels/LightPanels.js b/src/LightPanels/LightPanels.js index 90a9d5c04..9ec56b0ac 100644 --- a/src/LightPanels/LightPanels.js +++ b/src/LightPanels/LightPanels.js @@ -873,7 +873,7 @@ module.exports = kind( * @private */ setupFallback: function () { - this._fallbackTimeout = global.setTimeout(this.bindSafely('transitionFinished'), this.duration + 100); + this._fallbackTimeout = global.setTimeout(this.bindSafely('transitionFinished'), this.duration); } }); From c0cc93612eaf66de005a0a3d13b8806c75b9bef7 Mon Sep 17 00:00:00 2001 From: Aaron Tam Date: Thu, 18 Feb 2016 17:21:08 -0800 Subject: [PATCH 138/210] ENYO-3112: Update documentation. Enyo-DCO-1.1-Signed-off-by: Aaron Tam --- src/Collection.js | 330 +++++++++++++++++++++++----------------------- src/LinkedList.js | 57 ++++---- 2 files changed, 191 insertions(+), 196 deletions(-) diff --git a/src/Collection.js b/src/Collection.js index 2389700c6..ac73f8ff1 100644 --- a/src/Collection.js +++ b/src/Collection.js @@ -157,7 +157,7 @@ var BaseCollection = kind({ * {@link module:enyo/Collection~Collection#options}. Note that some properties have different * meanings in different contexts. Please review the descriptions below to see * how each property is used in this context. -* +* * @typedef {module:enyo/Collection~Options} module:enyo/Collection~AddOptions * @property {Boolean} merge - Update existing [models]{@link module:enyo/Model~Model} when found. * @property {Boolean} purge - Remove existing models not in the new dataset. @@ -186,7 +186,7 @@ var BaseCollection = kind({ * {@link module:enyo/Collection~Options}. Note that some properties have different * meanings in different contexts. Please review the descriptions below to see * how each property is used in this context. -* +* * @typedef {module:enyo/Collection~Options} module:enyo/Collection~RemoveOptions * @property {Boolean} silent - Emit [events]{@glossary event} and notifications. * @property {Boolean} commit - [Commit]{@link module:enyo/Collection~Collection#commit} changes to the @@ -250,7 +250,7 @@ var BaseCollection = kind({ /** * An array-like structure designed to store instances of {@link module:enyo/Model~Model}. -* +* * @class Collection * @extends module:enyo/Component~Component * @mixes module:enyo/StateSupport~StateSupport @@ -259,19 +259,19 @@ var BaseCollection = kind({ */ exports = module.exports = kind( /** @lends module:enyo/Collection~Collection.prototype */ { - + name: 'enyo.Collection', - + /** * @private */ kind: BaseCollection, - + /** * @private */ - + /** * Used by various [sources]{@link module:enyo/Collection~Collection#source} as part of the * [URI]{@glossary URI} from which they may be [fetched]{@link module:enyo/Collection~Collection#fetch}, @@ -287,7 +287,7 @@ exports = module.exports = kind( * @public */ url: '', - + /** * Implement this method to be used by [sources]{@link module:enyo/Model~Model#source} to * dynamically derive the [URI]{@glossary URI} from which they may be @@ -307,19 +307,19 @@ exports = module.exports = kind( * @public */ getUrl: null, - + /** * The [kind]{@glossary kind) of {@link module:enyo/Model~Model} that this * [collection]{@link module:enyo/Collection~Collection} will contain. This is important to set properly so * that when [fetching]{@link module:enyo/Collection~Collection#fetch}, the returned data will be instanced * as the correct model [subkind]{@glossary subkind}. - * - * @type {(module:enyo/Model~Model|String)} + * + * @type module:enyo/Model~Model * @default module:enyo/Model~Model * @public */ model: Model, - + /** * A special type of [array]{@glossary Array} used internally by * {@link module:enyo/Collection~Collection}. The array should not be modified directly, nor @@ -335,7 +335,7 @@ exports = module.exports = kind( * @protected */ models: null, - + /** * The current [state]{@link module:enyo/States} of the [collection]{@link module:enyo/Collection~Collection}. * This value changes automatically and may be observed for more complex state @@ -348,14 +348,14 @@ exports = module.exports = kind( * @see module:enyo/StateSupport */ status: States.READY, - + /** * The configurable default [options]{@link module:enyo/Collection~Options}. These values will be * used to modify the behavior of the [collection]{@link module:enyo/Collection~Collection} unless additional * options are passed into the methods that use them. When modifying these values in a * [subkind]{@glossary subkind} of {@link module:enyo/Collection~Collection}, they will be merged with * existing values. - * + * * @type {module:enyo/Collection~Options} * @public */ @@ -373,7 +373,7 @@ exports = module.exports = kind( fetch: false, modelEvents: true }, - + /** * Modifies the structure of data so that it can be used by the * [add()]{@link module:enyo/Collection~Collection#add} method. This method will only be used @@ -383,7 +383,7 @@ exports = module.exports = kind( * data coming from a [source]{@link module:enyo/Collection~Collection#source} that requires * modification before it can be added to the [collection]{@link module:enyo/Collection~Collection}. * This is a virtual method and must be implemented. - * + * * @param {*} data - The incoming data passed to the * [constructor]{@link module:enyo/Collection~Collection#constructor} or returned by a successful * [fetch]{@link module:enyo/Collection~Collection#fetch}. @@ -395,7 +395,7 @@ exports = module.exports = kind( parse: function (data) { return data; }, - + /** * Adds data to the [collection]{@link module:enyo/Collection~Collection}. This method can add an * individual [model]{@link module:enyo/Model~Model} or an [array]{@glossary Array} of models. @@ -406,7 +406,7 @@ exports = module.exports = kind( * optimized for batch operations on arrays of models. For better performance, * ensure that loops do not consecutively call this method but instead * build an array to pass as the first parameter. - * + * * @fires module:enyo/Collection~Collection#add * @param {(Object|Object[]|module:enyo/Model~Model|module:enyo/Model~Model[])} models The data to add to the * {@link module:enyo/Collection~Collection} that can be a [hash]{@glossary Object}, an array of @@ -428,16 +428,16 @@ exports = module.exports = kind( , idx = len , removedBeforeIdx = 0 , added, keep, removed, model, attrs, found, id; - + // for backwards compatibility with earlier api standards we allow the // second paramter to be the index and third param options when // necessary !isNaN(opts) && (idx = opts); arguments.length > 2 && (opts = arguments[2]); - + // normalize options so we have values opts = opts? utils.mixin({}, [options, opts]): options; - + // our flags var merge = opts.merge , purge = opts.purge @@ -449,50 +449,50 @@ exports = module.exports = kind( , create = opts.create !== false , modelOpts = opts.modelOptions , index = opts.index; - + idx = !isNaN(index) ? Math.max(0, Math.min(len, index)) : idx; /*jshint -W018 */ sort && !(typeof sort == 'function') && (sort = this.comparator); /*jshint +W018 */ - + // for a special case purge to remove records that aren't in the current // set being added - + if (parse) models = this.parse(models); - + // we treat all additions as an array of additions !(models instanceof Array) && (models = [models]); - + for (var i=0, end=models.length; i -1) it._waiting.splice(idx, 1); if (!it._waiting.length) it._waiting = null; } - + // continue the operation this time with commit false explicitly if (!it._waiting) { options.commit = options.source = null; @@ -1011,9 +1011,9 @@ exports = module.exports = kind( } if (opts && opts.success) opts.success(this, opts, res, source); }; - + options.error = function (source, res) { - + if (it._waiting) { idx = it._waiting.findIndex(function (ln) { return (ln instanceof Source ? ln.name : ln) == source; @@ -1021,38 +1021,38 @@ exports = module.exports = kind( if (idx > -1) it._waiting.splice(idx, 1); if (!it._waiting.length) it._waiting = null; } - + // continue the operation this time with commit false explicitly if (!it._waiting) { options.commit = options.source = null; it.destroy(options); } - - // we don't bother setting the error state if we aren't waiting because + + // we don't bother setting the error state if we aren't waiting because // it will be cleared to DESTROYED and it would be pointless else this.errored('DESTROYING', opts, res, source); }; - + this.set('status', (this.status | States.DESTROYING) & ~States.READY); - + Source.execute('destroy', this, options); } else if (this.status & States.ERROR) this.errored(this.status, opts); - + // we don't allow the destroy to take place and we don't forcibly break-down // the collection errantly so there is an opportuniy to resolve the issue // before we lose access to the collection's content! return this; } - + if (this.length && options.destroy) this.empty(options); - + // set the final resting state of this collection this.set('status', States.DESTROYED); - + sup.apply(this, arguments); }; }), - + /** * This is a virtual method that, when provided, will be used for sorting during * [add()]{@link module:enyo/Collection~Collection#add} when the `sort` flag is `true` or when the @@ -1067,7 +1067,7 @@ exports = module.exports = kind( * @public */ comparator: null, - + /** * Used during [add()]{@link module:enyo/Collection~Collection#add} when `create` is `true` and * the data is a [hash]{@glossary Object}. @@ -1078,19 +1078,19 @@ exports = module.exports = kind( var Ctor = this.model , options = this.options , model; - + attrs instanceof Ctor && (model = attrs); if (!model) { opts = opts || {}; opts.noAdd = true; model = new Ctor(attrs, null, opts); } - + if (options.modelEvents) model.on('*', this._modelEvent, this); - + return model; }, - + /** * When a [commit]{@link module:enyo/Collection~Collection#commit} has completed successfully, it is returned * to this method. This method handles special and important behavior; it should not be @@ -1111,7 +1111,7 @@ exports = module.exports = kind( */ committed: function (opts, res, source) { var idx; - + if (this._waiting) { idx = this._waiting.findIndex(function (ln) { return (ln instanceof Source ? ln.name : ln) == source; @@ -1119,15 +1119,15 @@ exports = module.exports = kind( if (idx > -1) this._waiting.splice(idx, 1); if (!this._waiting.length) this._waiting = null; } - + if (opts && opts.success) opts.success(this, opts, res, source); - + // clear the state if (!this._waiting) { this.set('status', (this.status | States.READY) & ~States.COMMITTING); } }, - + /** * When a [fetch]{@link module:enyo/Collection~Collection#fetch} has completed successfully, it is returned * to this method. This method handles special and important behavior; it should not be @@ -1148,7 +1148,7 @@ exports = module.exports = kind( */ fetched: function (opts, res, source) { var idx; - + if (this._waiting) { idx = this._waiting.findIndex(function (ln) { return (ln instanceof Source ? ln.name : ln) == source; @@ -1156,22 +1156,22 @@ exports = module.exports = kind( if (idx > -1) this._waiting.splice(idx, 1); if (!this._waiting.length) this._waiting = null; } - + // if there is a result we add it to the collection passing it any per-fetch options // that will override the defaults (e.g. parse) we don't do that here as it will // be done in the add method -- also note we reassign the result to whatever was // actually added and pass that to any other success callback if there is one if (res) res = this.add(res, opts); - + // now look for an additional success callback if (opts && opts.success) opts.success(this, opts, res, source); - + // clear the state if (!this._waiting) { this.set('status', (this.status | States.READY) & ~States.FETCHING); } }, - + /** * If an error is encountered while [fetching]{@link module:enyo/Collection~Collection#fetch}, * [committing]{@link module:enyo/Collection~Collection#commit}, or [destroying]{@link module:enyo/Collection~Collection#destroy} @@ -1180,7 +1180,7 @@ exports = module.exports = kind( * property and then checks to see if there is a provided * [error handler]{@link module:enyo/Collection~Collection~Error}. If the error handler * exists, it will be called. - * + * * @param {String} action - The name of the action that failed, * one of `'FETCHING'` or `'COMMITTING'`. * @param {module:enyo/Collection~Collection~ActionOptions} opts - The options hash originally @@ -1192,25 +1192,25 @@ exports = module.exports = kind( */ errored: function (action, opts, res, source) { var stat; - + // if the error action is a status number then we don't need to update it otherwise // we set it to the known state value if (typeof action == 'string') { - + // all built-in errors will pass this as their values are > 0 but we go ahead and // ensure that no developer used the 0x00 for an error code stat = States['ERROR_' + action]; } else stat = action; - + if (isNaN(stat) || !(stat & States.ERROR)) stat = States.ERROR_UNKNOWN; - + // if it has changed give observers the opportunity to respond this.set('status', (this.status | stat) & ~States.READY); - + // we need to check to see if there is an options handler for this error if (opts && opts.error) opts.error(this, action, opts, res, source); }, - + /** * Overloaded version of the method to call [set()]{@link module:enyo/Collection~Collection#set} * instead of simply assigning the value. This allows it to @@ -1223,7 +1223,7 @@ exports = module.exports = kind( clearError: function () { return this.set('status', States.READY); }, - + /** * @private */ @@ -1237,7 +1237,7 @@ exports = module.exports = kind( break; } }, - + /** * Responds to changes to the [models]{@link module:enyo/Collection~Collection#models} property. * @@ -1249,12 +1249,12 @@ exports = module.exports = kind( modelsChanged: function (was, is, prop) { var models = this.models.copy(), len = models.length; - + if (len != this.length) this.set('length', len); - + this.emit('reset', {models: models, collection: this}); }, - + /** * Initializes the [collection]{@link module:enyo/Collection~Collection}. * @@ -1271,48 +1271,48 @@ exports = module.exports = kind( constructor: kind.inherit(function (sup) { return function (recs, props, opts) { // opts = opts? (this.options = enyo.mixin({}, [this.options, opts])): this.options; - + // if properties were passed in but not a records array props = recs && !(recs instanceof Array)? recs: props; if (props === recs) recs = null; // initialize our core records // this.models = this.models || new ModelList(); !this.models && (this.set('models', new ModelList())); - + // this is backwards compatibility if (props && props.records) { recs = recs? recs.concat(props.records): props.records.slice(); delete props.records; } - + if (props && props.models) { recs = recs? recs.concat(props.models): props.models.slice(); delete props.models; } - + if (props && props.options) { this.options = utils.mixin({}, [this.options, props.options]); delete props.options; } - + opts = opts? utils.mixin({}, [this.options, opts]): this.options; - + // @TODO: For now, while there is only one property we manually check for it // if more options arrise that should be configurable this way it may need to // be modified opts.fetch && (this.options.fetch = opts.fetch); - + this.length = this.models.length; this.euid = utils.uid('c'); - + sup.call(this, props); - + typeof this.model == 'string' && (this.model = kind.constructorForKind(this.model)); this.store = this.store || Store; recs && recs.length && this.add(recs, opts); }; }), - + /** * @method * @private @@ -1320,12 +1320,12 @@ exports = module.exports = kind( constructed: kind.inherit(function (sup) { return function () { sup.apply(this, arguments); - + // automatically attempt a fetch after initialization is complete if (this.options.fetch) this.fetch(); }; }) - + }); /** @@ -1335,7 +1335,7 @@ exports = module.exports = kind( */ exports.concat = function (ctor, props) { var proto = ctor.prototype || ctor; - + if (props.options) { proto.options = utils.mixin({}, [proto.options, props.options]); delete props.options; diff --git a/src/LinkedList.js b/src/LinkedList.js index 4bddf681c..46651cfe4 100644 --- a/src/LinkedList.js +++ b/src/LinkedList.js @@ -19,37 +19,32 @@ var */ module.exports = kind( /** @lends module:enyo/LinkedList~LinkedList.prototype */ { - + /** * @private */ kind: null, - - /** - * @private - */ - /** * @private */ nodeKind: LinkedListNode, - + /** * @private */ head: null, - + /** * @private */ tail: null, - + /** * @private */ length: 0, - + /** * @private */ @@ -60,9 +55,9 @@ module.exports = kind( } this.head = null; this.tail = null; - this.length = 0; + this.length = 0; }, - + /** * @private */ @@ -70,20 +65,20 @@ module.exports = kind( var node = fromNode || this.head , list = new this.ctor() , cpy; - + // ensure we have a final node or our tail toNode = toNode || this.tail; - + if (node && node !== toNode) { do { cpy = node.copy(); list.appendNode(cpy); } while ((node = node.next) && node !== toNode); } - + return list; }, - + /** * @private */ @@ -91,67 +86,67 @@ module.exports = kind( this.clear(); this.destroyed = true; }, - + /** * @private */ createNode: function (props) { return new this.nodeKind(props); }, - + /** * @private */ deleteNode: function (node) { this.removeNode(node); - + // can't chain destruct because we removed its chain references node.destroy(); return this; }, - + /** * @private */ removeNode: function (node) { var prev = node.prev , next = node.next; - + prev && (prev.next = next); next && (next.prev = prev); this.length--; node.next = node.prev = null; return this; }, - + /** * @private */ appendNode: function (node, targetNode) { targetNode = targetNode || this.tail; - + if (targetNode) { if (targetNode.next) { node.next = targetNode.next; } - + targetNode.next = node; node.prev = targetNode; - + if (targetNode === this.tail) { this.tail = node; } - + this.length++; } else { - + this.head = this.tail = node; node.prev = node.next = null; this.length = 1; } return this; }, - + /** * @private */ @@ -167,7 +162,7 @@ module.exports = kind( // if no node qualified it returns false return false; }, - + /** * @private */ @@ -183,7 +178,7 @@ module.exports = kind( // returns the last node (if any) that was processed in the chain return node; }, - + /** * @private */ @@ -199,7 +194,7 @@ module.exports = kind( // returns the last node (if any) that was processed in the chain return node; }, - + /** * @private */ From c866d971f035f38e706f681e50541cf863e95ab2 Mon Sep 17 00:00:00 2001 From: Aaron Tam Date: Thu, 18 Feb 2016 19:12:09 -0800 Subject: [PATCH 139/210] ENYO-3098: Switch to a logical panel after replacement occurs. Enyo-DCO-1.1-Signed-off-by: Aaron Tam --- src/LightPanels/LightPanels.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/LightPanels/LightPanels.js b/src/LightPanels/LightPanels.js index 1e82b2d5b..07ce172fd 100644 --- a/src/LightPanels/LightPanels.js +++ b/src/LightPanels/LightPanels.js @@ -422,7 +422,7 @@ module.exports = kind( var lastIndex = this.getPanels().length - 1, nextPanel = this.createPanel(info, moreInfo), - newIndex = lastIndex + 1; + targetIndex = (opts && opts.targetIndex != null) ? opts.targetIndex : lastIndex + 1; if (this.cacheViews) { this.pruneQueue([info]); } @@ -433,8 +433,8 @@ module.exports = kind( nextPanel.postTransition(); } - if (!this.animate || (opts && opts.direct)) this.set('index', newIndex, {force: opts && opts.force}); - else this.animateTo(newIndex); + if (!this.animate || (opts && opts.direct)) this.set('index', targetIndex, {force: opts && opts.force}); + else this.animateTo(targetIndex); // TODO: When pushing panels after we have gone back (but have not popped), we need to // adjust the position of the panels after the previous index before our push. @@ -499,12 +499,15 @@ module.exports = kind( * @param {Number} count - The number of panels we wish to replace. * @param {Object|Object[]} info - The component definition (or array of component definitions) * for the replacement panel(s). + * @param {module:enyo/LightPanels~PushPanelOptions} opts - Additional options to be used when + * pushing multiple panels. Note that for the case of "targetIndex", if this is not specified, + * then the default behavior is to display the first replacement panel. * @return {Object|Object[]|undefined} The panel or array of the panels that were pushed; if * `undefined`, the replacement could not be processed (i.e. we are currently transitioning). * @public */ - replaceAt: function (start, count, info) { - var panels, panelsToPop, insertBefore, commonInfo, end; + replaceAt: function (start, count, info, opts) { + var panels, panelsToPop, insertBefore, commonInfo, end, panelOpts, targetIndex; if (this.transitioning) return; @@ -513,13 +516,15 @@ module.exports = kind( end = start + count; insertBefore = panels[end]; commonInfo = {addBefore: insertBefore}; + targetIndex = opts && opts.targetIndex; + panelOpts = {direct: true, force: true, targetIndex: targetIndex != null ? targetIndex : start}; panelsToPop = panels.splice(start, end - start); this.popQueue = (this.popQueue && this.popQueue.concat(panelsToPop)) || panelsToPop; // add replacement panels - if (utils.isArray(info)) return this.pushPanels(info, commonInfo, {direct: true, force: true}); - else return this.pushPanel(info, commonInfo, {direct: true, force: true}); + if (utils.isArray(info)) return this.pushPanels(info, commonInfo, panelOpts); + else return this.pushPanel(info, commonInfo, panelOpts); }, From bacdff9012f17001daac82509bd8105482188a49 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Fri, 12 Feb 2016 09:03:25 -0600 Subject: [PATCH 140/210] refactor RelationalModel + deps to correct string and circular refs In order to eliminate string references to kindNames and avoid circular dependencies between the private kinds used by RelationalModel, some refactoring was required including some post-kind setup in the module's index.js Issue: ENYO-3033 Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/RelationalModel/Collection.js | 40 +++++++++++++ .../{RelationalModel.js => Model.js} | 54 ++++++++--------- src/{ => RelationalModel}/Relation.js | 58 +++++++++++-------- src/RelationalModel/RelationalCollection.js | 38 ------------ src/RelationalModel/index.js | 17 ++++-- src/RelationalModel/manyToMany.js | 20 ++++--- src/RelationalModel/toMany.js | 37 +++++++----- src/RelationalModel/toOne.js | 39 +++++-------- 8 files changed, 155 insertions(+), 148 deletions(-) create mode 100644 src/RelationalModel/Collection.js rename src/RelationalModel/{RelationalModel.js => Model.js} (83%) rename src/{ => RelationalModel}/Relation.js (72%) delete mode 100644 src/RelationalModel/RelationalCollection.js diff --git a/src/RelationalModel/Collection.js b/src/RelationalModel/Collection.js new file mode 100644 index 000000000..3b7e87e3d --- /dev/null +++ b/src/RelationalModel/Collection.js @@ -0,0 +1,40 @@ +/** +* Contains the declaration for the {@link module:enyo/RelationalModel~Collection} kind. +* @module enyo/RelationalModel/Collection +* @private +*/ + +var + kind = require('../kind'), + Collection = require('../Collection'); + +var + Model = require('./Model'); + +/** +* Private class for a collection with a default model kind of +* {@link module:enyo/RelationalModel~RelationalModel} as opposed to {@link module:enyo/Model~Model}. +* +* @class Collection +* @name module:enyo/RelationalModel~Collection +* @extends module:enyo/Collection~Collection +* @private +*/ +module.exports = kind( + /** @lends module:enyo/RelationalModel~Collection.prototype */ { + + /** + * @private + */ + name: 'Collection', + + /** + * @private + */ + kind: Collection, + + /** + * @private + */ + model: Model +}); diff --git a/src/RelationalModel/RelationalModel.js b/src/RelationalModel/Model.js similarity index 83% rename from src/RelationalModel/RelationalModel.js rename to src/RelationalModel/Model.js index 4399e1e9a..b18c55df1 100644 --- a/src/RelationalModel/RelationalModel.js +++ b/src/RelationalModel/Model.js @@ -1,11 +1,11 @@ /** - * Contains the declaration for the {@link module:enyo/RelationalModel/RelationalModel~RelationalModel} kind. - * - * NOTE: Do not require this module for use in applications. Require - * {@link module:enyo/RelationalModel} instead. - * - * @module enyo/RelationalModel/RelationalModel - */ +* Contains the declaration for the {@link module:enyo/RelationalModel~RelationalModel} kind. +* +* NOTE: Do not require this module for use in applications. Require +* {@link module:enyo/RelationalModel} instead. +* @module enyo/RelationalModel/Model +* @private +*/ var kind = require('../kind'), @@ -14,7 +14,7 @@ var var Model = require('../Model'), Store = require('../Store'), - Relation = require('../Relation'); + Relation = require('./Relation'); var defaultRelationType; @@ -22,15 +22,16 @@ var /** * A type of {@link module:enyo/Model~Model} extended to automatically understand relationships with * other models. You may define these relationship via the -* [relations]{@link module:enyo/RelationalModel/RelationalModel~RelationalModel#relations} property. These relationships allow +* [relations]{@link module:enyo/RelationalModel~RelationalModel#relations} property. These relationships allow * individual models to exist separately, but be treated as a single entity. * * @class RelationalModel +* @name module:enyo/RelationalModel~RelationalModel * @extends module:enyo/Model~Model * @public */ var RelationalModel = module.exports = kind( - /** @lends module:enyo/RelationalModel/RelationalModel~RelationalModel.prototype */ { + /** @lends module:enyo/RelationalModel~RelationalModel.prototype */ { name: 'enyo.RelationalModel', @@ -38,20 +39,15 @@ var RelationalModel = module.exports = kind( * @private */ kind: Model, - - /** - * @private - */ - /** * An [array]{@glossary Array} declaring relationships of this - * [model]{@link module:enyo/RelationalModel/RelationalModel~RelationalModel} to other models. + * [model]{@link module:enyo/RelationalModel~RelationalModel} to other models. * These are [hashes]{@glossary Object} of corresponding - * [properties]{@link module:enyo/Relation~RelationOptions} used to define + * [properties]{@link module:enyo/RelationalModel~RelationOptions} used to define * and configure individual relations. Relations may be of the type - * {@link module:enyo/RelationalModel/toOne~toOne}, {@link module:enyo/RelationalModel/toMany~toMany}, - * or {@link module:enyo/RelationalModel/manyToMany~manyToMany}. Each relation must include a + * {@link module:enyo/RelationalModel~toOne}, {@link module:enyo/RelationalModel~toMany}, + * or {@link module:enyo/RelationalModel~manyToMany}. Each relation must include a * `key` property that is the name of the local * [attribute]{@link module:enyo/Model~Model#attributes}. For example: * @@ -86,8 +82,8 @@ var RelationalModel = module.exports = kind( * ([attribute]{@link module:enyo/Model~Model#attributes}). * * @param {String} key - The key as defined in the - * [relations]{@link module:enyo/RelationalModel/RelationalModel~RelationalModel#relations} property. - * @returns {(Relation|undefined)} The correct relation instance, or + * [relations]{@link module:enyo/RelationalModel~RelationalModel#relations} property. + * @returns {(module:enyo/RelationalModel~Relation|undefined)} The correct relation instance, or * `undefined` if not found. * @public */ @@ -101,8 +97,8 @@ var RelationalModel = module.exports = kind( * Determines whether the requested key is the name of a relation. * * @param {String} key - The key as defined in the - * [relations]{@link module:enyo/RelationalModel/RelationalModel~RelationalModel#relations} property. - * @returns {(Relation|undefined)} The correct relation instance, or + * [relations]{@link module:enyo/RelationalModel~RelationalModel#relations} property. + * @returns {(module:enyo/RelationalModel~Relation|undefined)} The correct relation instance, or * `undefined` if not found. * @public */ @@ -111,8 +107,8 @@ var RelationalModel = module.exports = kind( }, /** - * Overloaded version of [get]{@link module:enyo/Model~Model#get} to be able to use a _path_ through - * relations. + * Overloaded version of [get]{@link module:enyo/Model~Model#get} to be able to use a _path_ + * through relations. * * @method * @private @@ -138,7 +134,7 @@ var RelationalModel = module.exports = kind( /** * Overloaded version of [set()]{@link module:enyo/Model~Model#set} with the ability to - * set values for related [models]{@link module:enyo/RelationalModel/RelationalModel~RelationalModel} as well. + * set values for related [models]{@link module:enyo/RelationalModel~RelationalModel} as well. * * @private */ @@ -316,7 +312,7 @@ var RelationalModel = module.exports = kind( /** * Defines a named relation type * -* @name module:enyo/RelationalModel/RelationalModel~RelationalModel.defineRelationType +* @name module:enyo/RelationalModel~RelationalModel.defineRelationType * @static * @method * @param {String} name Name of relation type @@ -333,7 +329,7 @@ RelationalModel.defineRelationType = function (name, type, isDefault) { /** * Ensures that we concatenate (sanely) the relations for any subkinds. * -* @name module:enyo/RelationalModel/RelationalModel~RelationalModel.concat +* @name module:enyo/RelationalModel~RelationalModel.concat * @static * @method * @private @@ -359,5 +355,3 @@ RelationalModel.concat = function (ctor, props) { // apply our modified relations array to the prototype proto.relations = rels; }; - -Relation.relationDefaults.model = RelationalModel; diff --git a/src/Relation.js b/src/RelationalModel/Relation.js similarity index 72% rename from src/Relation.js rename to src/RelationalModel/Relation.js index 9fce06f38..b94c8c2a7 100644 --- a/src/Relation.js +++ b/src/RelationalModel/Relation.js @@ -1,35 +1,38 @@ require('enyo'); /** -* Contains the declaration for the {@link module:enyo/Relation~Relation} kind. -* @module enyo/Relation +* Contains the declaration for the {@link module:enyo/RelationalModel~Relation} kind. +* @module enyo/RelationalModel/Relation +* @private */ var - kind = require('./kind'), - utils = require('./utils'); + kind = require('../kind'), + utils = require('../utils'); var - Store = require('./Store'); + Store = require('../Store'); /** -* The default options for [relations]{@link module:enyo/RelationalModel/RelationalModel~RelationalModel#relations}. +* The default options for [relations]{@link module:enyo/RelationalModel~RelationalModel#relations}. * These may vary depending on the individual [kind]{@glossary kind} of relation. * -* @typedef {Object} module:enyo/Relation~RelationOptions -* @property {String} type=toOne - The [kind]{@glossary kind} of relation being declared. -* Can be the name of the relation type or a reference to the constructor. -* @property {String} key=null - The [attribute]{@link module:enyo/Model~Model#attributes} name for the -* relation being declared. +* @typedef {Object} module:enyo/RelationalModel~RelationOptions +* @property {module:enyo/RelationalModel~Relation} type=module:enyo/RelationalModel~toOne - The +* [kind]{@glossary kind} of relation being declared. +* @property {String} key=null - The [attribute]{@link module:enyo/Model~Model#attributes} name for +* the relation being declared. * @property {Boolean} create=false - Whether or not the relation should automatically create * the instance of the related kind. * @property {Boolean} parse=false - Whether or not the relation should call the * [parse()]{@link module:enyo/Model~Model#parse} method on incoming data before -* [setting]{@link module:enyo/Model~Model#set} it on the [model]{@link module:enyo/RelationalModel/RelationalModel~RelationalModel}. +* [setting]{@link module:enyo/Model~Model#set} it on the +* [model]{@link module:enyo/RelationalModel~RelationalModel}. * @property {String} model=enyo/RelationalModel~RelationModel - The kind of the * reverse of the relation. This will vary depending on the type of relation being declared. * @property {Boolean} fetch=false - Whether or not to automatically call -* [fetch()]{@link module:enyo/Model~Model#fetch} (or {@link module:enyo/Collection~Collection#fetch}) after initialization. +* [fetch()]{@link module:enyo/Model~Model#fetch} (or +* {@link module:enyo/Collection~Collection#fetch}) after initialization. * @property {String} inverseKey=null - The key of the reverse relation. * @property {String} inverseType=null - The type of the reverse relation. * @property {Boolean} isOwner=false - Whether or not this end of the relation owns the @@ -41,11 +44,11 @@ var * be included. */ var relationDefaults = { - type: 'toOne', + type: null, // set ex post facto by the module key: null, create: false, parse: false, - model: null, + model: null, // set ex post facto by the module fetch: false, inverseKey: null, inverseType: null, @@ -55,10 +58,11 @@ var relationDefaults = { /** * @class Relation -* @protected +* @name module:enyo/RelationalModel~Relation +* @private */ var Relation = module.exports = kind( - /** @lends module:enyo/Relation~Relation.prototype */ { + /** @lends module:enyo/RelationalModel~Relation.prototype */ { /** * @private @@ -86,9 +90,6 @@ var Relation = module.exports = kind( // store a reference to the model we're relating this.instance = instance; - // ensure we have a constructor for our related model kind - this.model = kind.constructorForKind(this.model); - this.includeInJSON = props.includeInJSON == null && !this.isOwner ? (this.model.prototype.primaryKey || 'id') : this.includeInJSON; @@ -97,6 +98,13 @@ var Relation = module.exports = kind( this.init(); }, + /** + * @private + */ + isRelated: function (related) { + return related === this.related; + }, + /** * @private */ @@ -105,9 +113,13 @@ var Relation = module.exports = kind( }, /** + * Sets the `related` model + * + * @param {module:enyo/Model~Model} related - The related model + * @param {Object} [opts] - Used by subkinds to configure the behavior of the method * @private */ - setRelated: function (related) { + setRelated: function (related, opts) { var inst = this.instance, model = this.model, was = this.related, @@ -150,10 +162,6 @@ var Relation = module.exports = kind( } }); -/** -* @private -* @static -*/ Relation.concat = function (ctor, props) { var proto = ctor.prototype; if (props.options) { diff --git a/src/RelationalModel/RelationalCollection.js b/src/RelationalModel/RelationalCollection.js deleted file mode 100644 index 3b8852512..000000000 --- a/src/RelationalModel/RelationalCollection.js +++ /dev/null @@ -1,38 +0,0 @@ -/** -* Contains the declaration for the {@link module:enyo/RelationalModel/RelationalCollection~RelationalCollection} kind. -* @module enyo/RelationalModel/RelationalCollection -*/ - -var - kind = require('../kind'), - Collection = require('../Collection'); - -var - RelationalModel = require('./RelationalModel'); - -/** -* Private class for a collection with a default model kind of -* {@link module:enyo/RelationalModel/RelationalModel~RelationalModel} as opposed to {@link module:enyo/Model~Model}. -* -* @class RelationalCollection -* @extends module:enyo/Collection~Collection -* @private -*/ -module.exports = kind( - /** @lends module:enyo/RelationalModel/RelationalCollection~RelationalCollection.prototype */ { - - /** - * @private - */ - name: "RelationalCollection", - - /** - * @private - */ - kind: Collection, - - /** - * @private - */ - model: RelationalModel -}); diff --git a/src/RelationalModel/index.js b/src/RelationalModel/index.js index 3fa195b15..f3fee3c82 100644 --- a/src/RelationalModel/index.js +++ b/src/RelationalModel/index.js @@ -1,18 +1,23 @@ require('enyo'); /** -* Entry point for the {@link module:enyo/RelationalModel/RelationalModel~RelationalModel} kind. +* Contains the declaration for the {@link module:enyo/RelationalModel~RelationalModel} and +* {@link module:enyo/RelationalModel~Collection} kinds. * @module enyo/RelationalModel */ var - RelationalModel = require('./RelationalModel'), + Model = require('./Model'), + Relation = require('./Relation'), toOne = require('./toOne'), toMany = require('./toMany'), manyToMany = require('./manyToMany'); -RelationalModel.defineRelationType('toOne', toOne, true); -RelationalModel.defineRelationType('toMany', toMany); -RelationalModel.defineRelationType('manyToMany', manyToMany); +Model.defineRelationType('toOne', toOne, true); +Model.defineRelationType('toMany', toMany); +Model.defineRelationType('manyToMany', manyToMany); -module.exports = RelationalModel; +Relation.relationDefaults.model = Model; +Relation.relationDefaults.type = toOne; + +module.exports = Model; \ No newline at end of file diff --git a/src/RelationalModel/manyToMany.js b/src/RelationalModel/manyToMany.js index 8687c3d1e..8003e6d5f 100644 --- a/src/RelationalModel/manyToMany.js +++ b/src/RelationalModel/manyToMany.js @@ -1,6 +1,7 @@ /** -* Contains the declaration for the {@link module:enyo/RelationalModel/manyToMany~manyToMany} kind. +* Contains the declaration for the {@link module:enyo/RelationalModel~manyToMany} kind. * @module enyo/RelationalModel/manyToMany +* @private */ var @@ -14,11 +15,12 @@ var * models. This is an internally-used class. * * @class manyToMany -* @extends module:enyo/RelationalModel/toMany~toMany -* @protected +* @name module:enyo/RelationalModel~manyToMany +* @extends module:enyo/RelationalModel~toMany +* @private */ var manyToMany = module.exports = kind( - /** @lends module:enyo/RelationalModel/manyToMany~manyToMany.prototype */ { + /** @lends module:enyo/RelationalModel~manyToMany.prototype */ { /** * @private @@ -31,13 +33,13 @@ var manyToMany = module.exports = kind( name: 'enyo.manyToMany', /** - * The default [options]{@link module:enyo/Relation~RelationOptions} overloaded for this + * The default [options]{@link module:enyo/RelationalModel~RelationOptions} overloaded for this * [kind]{@glossary kind}. * - * @see module:enyo/RelationalModel/toMany~toMany#options - * @type module:enyo/Relation~RelationOptions - * @property {module:enyo/Relation~Relation} inverseType=module:enyo/RelationalModel/manyToMany~manyToMany - - * This is the **required** type. + * @see module:enyo/RelationalModel~toMany#options + * @type enyo/RelationalModel~RelationOptions + * @property {module:enyo/RelationalModel~Relation} inverseType=module:enyo/RelationalModel~manyToMany - This is + * the **required** type. * @public */ options: { diff --git a/src/RelationalModel/toMany.js b/src/RelationalModel/toMany.js index de91352f6..2c659fc50 100644 --- a/src/RelationalModel/toMany.js +++ b/src/RelationalModel/toMany.js @@ -1,17 +1,18 @@ /** - * Contains the declaration for the {@link module:enyo/RelationalModel/toMany~toMany} kind. + * Contains the declaration for the {@link module:enyo/RelationalModel~toMany} kind. * @module enyo/RelationalModel/toMany + * @private */ var kind = require('../kind'), utils = require('../utils'), Collection = require('../Collection'), - Relation = require('../Relation'), Store = require('../Store'); var - RelationalCollection = require('./RelationalCollection'), + Relation = require('./Relation'), + RelationalCollection = require('./Collection'), toOne = require('./toOne'); /** @@ -19,11 +20,12 @@ var * models. This is an internally-used class. * * @class toMany -* @extends module:enyo/Relation~Relation -* @protected +* @name module:enyo/RelationalModel~toMany +* @extends module:enyo/RelationalModel~Relation +* @private */ var toMany = module.exports = kind( - /** @lends module:enyo/RelationalModel/toMany~toMany.prototype */ { + /** @lends module:enyo/RelationalModel~toMany.prototype */ { /** * @private @@ -36,13 +38,13 @@ var toMany = module.exports = kind( name: 'enyo.toMany', /** - * The default [options]{@link module:enyo/Relation~RelationOptions} overloaded for this - * [kind]{@glossary kind}. + * The default [options]{@link module:enyo/RelationalModel~RelationOptions} overloaded for + * this [kind]{@glossary kind}. * - * @type module:enyo/Relation~RelationOptions + * @type module:enyo/RelationalModel~RelationOptions * @property {Boolean} create=true - By default, the relation should create the * [collection]{@link module:enyo/Collection~Collection} automatically. - * @property {module:enyo/Collection~Collection} collection=module:enyo/RelationalModel/RelationalCollection~RelationalCollection - The + * @property {module:enyo/Collection~Collection} collection=module:enyo/RelationalModel~Collection - The * [kind]{@glossary kind} of collection to use; can be the kind name or a * reference to the constructor. * @property {Object} collectionOptions - An options hash to pass to the @@ -67,9 +69,6 @@ var toMany = module.exports = kind( key = this.key, related = this.related != null ? this.related : inst.attributes[key]; - if (typeof collection == 'string') collection = kind.constructorForKind(collection); - if (typeof model == 'string') model = kind.constructorForKind(model); - // since we allow the model property to be used for the collection constructor // we need to check for and use it if we find it if (model.prototype instanceof Collection) { @@ -130,15 +129,23 @@ var toMany = module.exports = kind( fetchRelated: function () { }, + + /** + * @private + */ + isRelated: function (related) { + return this.related.indexOf(related) >= 0; + }, /** + * @see module:enyo/RelationalModel~Relation#setRelated * @private */ - setRelated: function (data) { + setRelated: function (data, opts) { var related = this.related; // related.add(data, {purge: true, parse: true}); - related.add(data, {purge: true}); + related.add(data, opts || {purge: true}); }, /** diff --git a/src/RelationalModel/toOne.js b/src/RelationalModel/toOne.js index 1f760472b..6cd4a7e25 100644 --- a/src/RelationalModel/toOne.js +++ b/src/RelationalModel/toOne.js @@ -1,25 +1,29 @@ /** -* Contains the declaration for the {@link module:enyo/RelationalModel/toOne~toOne} kind. +* Contains the declaration for the {@link module:enyo/RelationalModel~toOne} kind. * @module enyo/RelationalModel/toOne +* @private */ var kind = require('../kind'), utils = require('../utils'), Model = require('../Model'), - Relation = require('../Relation'), Store = require('../Store'); +var + Relation = require('./Relation'); + /** * Represents a relationship of data from one [model]{@link module:enyo/Model~Model} to another * model. This is an internally-used class. * * @class toOne -* @extends module:enyo/Relation~Relation -* @protected +* @name module:enyo/RelationalModel~toOne +* @extends module:enyo/RelationalModel~Relation +* @private */ var toOne = module.exports = kind( - /** @lends module:enyo/RelationalModel/toOne~toOne.prototype */ { + /** @lends module:enyo/RelationalModel~toOne.prototype */ { /** * @private @@ -32,12 +36,12 @@ var toOne = module.exports = kind( name: 'enyo.toOne', /** - * The default [options]{@link module:enyo/Relation~RelationOptions} overloaded for this + * The default [options]{@link module:enyo/RelationalModel~RelationOptions} overloaded for this * [kind]{@glossary kind}. * - * @type module:enyo/Relation~RelationOptions - * @property {module:enyo/Relation~Relation} inverseType=module:enyo/RelationalModel/toOne~toOne - This can be - * {@link module:enyo/RelationalModel/toOne~toOne} or {@link module:enyo/RelationalModel/toMany~toMany}. + * @type module:enyo/RelationalModel~RelationOptions + * @property {module:enyo/RelationalModel~Relation} inverseType=module:enyo/RelationalModel~toOne - This can be + * {@link module:enyo/RelationalModel~toOne} or {@link module:enyo/RelationalModel~toMany}. * @property {Object} modelOptions - An options hash to pass to the related instance if * `create` is `true`. * @public @@ -62,12 +66,6 @@ var toOne = module.exports = kind( id, found; - // ensure we have a valid model constructor - if (typeof model == 'string') model = kind.constructorForKind(model); - - // ensure our inverse type constructor is correct - if (typeof inverseType == 'string') inverseType = kind.constructorForKind(inverseType); - // ensure we've got the correct related if any if (related || related === 0) this.related = related; @@ -114,11 +112,9 @@ var toOne = module.exports = kind( if (!modelOptions) modelOptions = {}; modelOptions.parse = true; } - /*jshint -W055 */ // we create the empty instance so we can separately deal with the // various ways the related data could be handed to us (could be id or data) found = model = new model(related, null, modelOptions); - /*jshint +W055 */ this.related = model; } } @@ -220,14 +216,7 @@ var toOne = module.exports = kind( } // now we ensure that the instances are pointing at eachother - switch (rev.kindName) { - case 'enyo.toOne': - if (rev.related !== this.instance) rev.setRelated(this.instance); - break; - case 'enyo.toMany': - rev.related.add(this.instance, {merge: false}); - break; - } + if (!rev.isRelated(this.instance)) rev.setRelated(this.instance, {merge: false}); } if (isOwner) found.on('change', this._changed, this); From 09685f852846f13b6dfe2936699179be11f8d744 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Fri, 19 Feb 2016 14:37:52 -0600 Subject: [PATCH 141/210] guard getRelations against nulled this.relations If a RelationalModel particpates in a binding, it may be accessed after it is destroyed. Because it overrides get() to interrogate its related models, if it had been destroyed the array of models would have been nulled causing a runtime error. Issue: ENYO-2990 Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/RelationalModel/RelationalModel.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/RelationalModel/RelationalModel.js b/src/RelationalModel/RelationalModel.js index 4399e1e9a..874a5dbb3 100644 --- a/src/RelationalModel/RelationalModel.js +++ b/src/RelationalModel/RelationalModel.js @@ -92,9 +92,9 @@ var RelationalModel = module.exports = kind( * @public */ getRelation: function (key) { - return this.relations.find(function (ln) { + return this.relations ? this.relations.find(function (ln) { return ln instanceof Relation && ln.key == key; - }); + }) : undefined; }, /** From 7307863c18fa1418ba16d4011ba209eb88135ef0 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Wed, 24 Feb 2016 13:41:52 -0600 Subject: [PATCH 142/210] add docs for RepeaterChildSupport#selectedClass Issue: ENYO-3126 Enyo-DCO-1.1-Signed-off-by: Ryan Duffy (ryan.duffy@lge.com) --- src/RepeaterChildSupport.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/RepeaterChildSupport.js b/src/RepeaterChildSupport.js index 08bc7349c..b917809a5 100644 --- a/src/RepeaterChildSupport.js +++ b/src/RepeaterChildSupport.js @@ -39,6 +39,15 @@ var RepeaterChildSupport = { */ selected: false, + /** + * The CSS class applied to the child when selected + * + * @name module:enyo/RepeaterChildSupport~RepeaterChildSupport#selectedClass + * @type {String} + * @default null + * @public + */ + /** * Setting cachePoint: true ensures that events from the repeater child's subtree will * always bubble up through the child, allowing the events to be decorated with repeater- From 869e812ce339cf170d47d10b3a3fffa44573c34c Mon Sep 17 00:00:00 2001 From: Blake Stephens Date: Mon, 21 Dec 2015 14:10:16 -0800 Subject: [PATCH 143/210] ENYO-2718: Added ShowingTransitionSupport, a mixin to make showing/hiding animations easier. Squashed commit history Take advantage of utils.call, and don't double-bind-safely. Docs update, and moving control to WIP. Enyo-DCO-1.1-Signed-off-by: Blake Stephens Fixup docs Enyo-DCO-1.1-Signed-off-by: Roy Sutton Adding a default for shownClass simplifies the usage a bit in many cases. Added support for methods to be called out of immediate scope, and hardening of unexpected duration changes. Enyo-DCO-1.1-Signed-off-by: Blake Stephens ENYO-2718: Update caching of shown and hidden method scopes. ENYO-2718: Re-add variable assignment for proper module documentation. Enyo-DCO-1.1-Signed-off-by: Aaron Tam Methods should run even if there's no duration Normalized the order of the method execution across all 4 cases. Enyo-DCO-1.1-Signed-off-by: Blake Stephens --- src/ShowingTransitionSupport.js | 244 ++++++++++++++++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100644 src/ShowingTransitionSupport.js diff --git a/src/ShowingTransitionSupport.js b/src/ShowingTransitionSupport.js new file mode 100644 index 000000000..a72077972 --- /dev/null +++ b/src/ShowingTransitionSupport.js @@ -0,0 +1,244 @@ +/** +* This module exports the {@link module:enyo/ShowingTransitionSupport~ShowingTransitionSupport} mixin. +* +* @wip +* @module enyo/ShowingTransitionSupport +*/ + +var kind = require('enyo/kind'), + utils = require('enyo/utils'); + +/** +* The {@link module:enyo/ShowingTransitionSupport~ShowingTransitionSupport} [mixin]{@glossary mixin} +* is applicable to any control that should use a transition or animation when it is shown or hidden. +* This mixin adds optional state-classes to the component at its resting or transitioning states. +* The states are as follows: +* +* * 'shown' and 'hidden' - resting, static, not-transitioning, past tense states. +* * 'showing' and 'hiding' - transitioning-to, progressive tense states. +* +* A CSS class may be optionally supplied and applied to the component during that state. It will be +* removed immediately when the component is no longer in that state. The 'hidden', 'hiding', and +* 'showing' CSS classes are already defined as defaults, to account for the most common use case. +* The same classes are allowed to be used on multiple states. +* +* It may be desirable to have a transition on only one of the showing or hiding states; this is +* also possible. +* +* Transitions take time, so be sure to include a `hidingDuration` and/or `showingDuration`. You may +* take advantage of this [mixin]{@glossary mixin}'s state classes without using transitions by +* leaving the duration properties blank (0, null or undefined) and the resting states will simply be +* applied immediately, skipping the transition state classes. +* +* An optional method may be supplied to fire at the end of either of the transitions, using +* `hidingMethod` and/or `showingMethod`. +* +* @mixin +* @wip +* @public +*/ +var ShowingTransitionSupport = { + + /** + * @ignore + * @readonly + * @private + */ + name: 'ShowingTransitionSupport', + + /** + * A read-only property for checking whether we are in the middle of a transition. + * + * @type {Boolean} + * @default false + * @readonly + * @public + */ + showingTransitioning: false, + + /** + * The amount of time the "showing" transition takes to complete in milliseconds. + * + * @type {Number} + * @default undefined + * @public + */ + showingDuration: undefined, + + /** + * The amount of time the "hiding" transition takes to complete in milliseconds. + * + * @type {Number} + * @default undefined + * @public + */ + hidingDuration: undefined, + + /** + * The method to fire at the end of the "showing" transition. This may be name of a method on the + * component, or a function. + * + * @type {String|Function} + * @default undefined + * @public + */ + shownMethod: undefined, + + /** + * The method to fire at the end of the "hiding" transition. This may be name of a method on the + * component, or a function. + * + * @type {String|Function} + * @default undefined + * @public + */ + hiddenMethod: undefined, + + /** + * The classname to apply for the "shown" (component is visible) resting state. + * + * @type {String} + * @default undefined + * @public + */ + shownClass: undefined, + + /** + * The classname to apply for the "hidden" (component is not visible) resting state. + * + * @type {String} + * @default 'hidden' + * @public + */ + hiddenClass: undefined, + + /** + * The classname to apply for the "hiding" (component has started the transition to the hidden + * state) transition state. + * + * @type {String} + * @default 'hiding' + * @public + */ + hidingClass: undefined, + + /** + * The classname to apply for the "showing" (component has started the transition to the shown + * state) transition state. + * + * @type {String} + * @default 'showing' + * @public + */ + showingClass: undefined, + + /** + * Initializes the defaults, and prepares the component with its classes in case of initially + * "showing: false". + * + * @method + * @private + */ + create: kind.inherit(function (sup) { + return function () { + sup.apply(this, arguments); + + this.showingDuration = (this.showingDuration === undefined) ? null : this.showingDuration; + this.hidingDuration = (this.hidingDuration === undefined) ? null : this.hidingDuration; + this.shownMethod = (this.shownMethod === undefined) ? null : this.shownMethod; + this.hiddenMethod = (this.hiddenMethod === undefined) ? null : this.hiddenMethod; + this.shownClass = (this.shownClass === undefined) ? 'shown' : this.shownClass; + this.hiddenClass = (this.hiddenClass === undefined) ? 'hidden' : this.hiddenClass; + this.hidingClass = (this.hidingClass === undefined) ? 'hiding' : this.hidingClass; + this.showingClass = (this.showingClass === undefined) ? 'showing' : this.showingClass; + if (this.shownMethod) this.shownMethodChanged(); + if (this.hiddenMethod) this.hiddenMethodChanged(); + this.showingChanged(); + }; + }), + + /** + * Overrides the showingChanged handler to add support for transitions at the right times and + * places. + * + * @method + * @private + */ + showingChanged: kind.inherit(function (sup) { + return function (sender, ev) { + var args = arguments; + + // Prepare our visual state + this.applyStyle('display', null); + this.applyStyle('visibility', null); + if (this.showing) { + // Reset our state classes, in case we switched mid-stream + this.removeClass(this.hidingClass); + this.removeClass(this.hiddenClass); + sup.apply(this, args); + if (this.showingDuration && this.hasNode()) { + this.set('showingTransitioning', true); + // Start transition: Apply a class and start a timer. + // When timer finishes, run the exit function, + // remove the transitioning class + // and add the final-state class + this.addClass(this.showingClass); + this.startJob('showingTransition', function () { + this.removeClass(this.showingClass); + this.addClass(this.shownClass); + this.set('showingTransitioning', false); + utils.call(this._shownMethodScope, this.shownMethod); // Run the supplied method. + }, this.showingDuration); + } else { + // No transition, just a shown class. + this.stopJob('showingTransition'); + this.addClass(this.shownClass); + utils.call(this._shownMethodScope, this.shownMethod); // Run the supplied method. + } + } else { + // Reset our state classes, in case we switched mid-stream + this.removeClass(this.showingClass); + this.removeClass(this.shownClass); + if (this.hidingDuration && this.hasNode()) { + this.set('showingTransitioning', true); + this.addClass(this.hidingClass); + this.startJob('showingTransition', function () { + this.removeClass(this.hidingClass); + this.addClass(this.hiddenClass); + this.set('showingTransitioning', false); + sup.apply(this, args); + utils.call(this._hiddenMethodScope, this.hiddenMethod); // Run the supplied method. + this.applyStyle('visibility', 'hidden'); + this.applyStyle('display', null); + }, this.hidingDuration); + } else { + // No transition, just a hidden class. + this.stopJob('showingTransition'); + this.addClass(this.hiddenClass); + sup.apply(this, args); + utils.call(this._hiddenMethodScope, this.hiddenMethod); // Run the supplied method. + this.applyStyle('visibility', 'hidden'); + this.applyStyle('display', null); + } + } + }; + }), + showingDurationChanged: function () { + if (!this.showingDuration) this.stopJob('showingTransition'); + }, + hidingDurationChanged: function () { + if (!this.hidingDuration) this.stopJob('showingTransition'); + }, + shownMethodChanged: function () { + // checking if the actual method exists to workaround hasOwnProperty issues due to the + // mechanism we use for assigning mixin defaults + this._shownMethodScope = this[this.shownMethod] ? this : this.getInstanceOwner(); + }, + hiddenMethodChanged: function () { + // checking if the actual method exists to workaround hasOwnProperty issues due to the + // mechanism we use for assigning mixin defaults + this._hiddenMethodScope = this[this.hiddenMethod] ? this : this.getInstanceOwner(); + } +}; + +module.exports = ShowingTransitionSupport; From 916756d36b9e571c6e6d1bf483b30fb74383d31d Mon Sep 17 00:00:00 2001 From: "jeremy.thomas" Date: Thu, 25 Feb 2016 18:55:42 -0500 Subject: [PATCH 144/210] ENYO-3130: touch/gesture fix --- src/platform.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/platform.js b/src/platform.js index d00c27592..82a6521dd 100644 --- a/src/platform.js +++ b/src/platform.js @@ -41,13 +41,12 @@ exports = module.exports = { * `true` if the platform has native single-finger [events]{@glossary event}. * @public */ - touch: Boolean(('ontouchstart' in window) || window.navigator.msMaxTouchPoints || window.navigator.maxTouchPoints), + touch: Boolean(('ontouchstart' in window) || window.navigator.msMaxTouchPoints || (window.navigator.msManipulationViewsEnabled && window.navigator.maxTouchPoints)), /** * `true` if the platform has native double-finger [events]{@glossary event}. * @public */ - gesture: Boolean(('ongesturestart' in window) || (window.navigator.msMaxTouchPoints && window.navigator.msMaxTouchPoints > 1) || (window.navigator.maxTouchPoints && window.navigator.maxTouchPoints > 1)) - + gesture: Boolean(('ongesturestart' in window) || ('onmsgesturestart' in window && window.navigator.msMaxTouchPoints && window.navigator.msMaxTouchPoints > 1) || ('onmsgesturestart' in window && window.navigator.maxTouchPoints && window.navigator.maxTouchPoints > 1)) /** * The name of the platform that was detected or `undefined` if the platform * was unrecognized. This value is the key name for the major version of the From e98d57f8ae326832639150d8a3ac569a6f1ddb87 Mon Sep 17 00:00:00 2001 From: "jeremy.thomas" Date: Thu, 25 Feb 2016 18:58:01 -0500 Subject: [PATCH 145/210] spacing --- src/platform.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/platform.js b/src/platform.js index 82a6521dd..c34c67683 100644 --- a/src/platform.js +++ b/src/platform.js @@ -47,6 +47,7 @@ exports = module.exports = { * @public */ gesture: Boolean(('ongesturestart' in window) || ('onmsgesturestart' in window && window.navigator.msMaxTouchPoints && window.navigator.msMaxTouchPoints > 1) || ('onmsgesturestart' in window && window.navigator.maxTouchPoints && window.navigator.maxTouchPoints > 1)) + /** * The name of the platform that was detected or `undefined` if the platform * was unrecognized. This value is the key name for the major version of the From 77ab9ca5e9c436ccca05baf9b4feafb109b9d033 Mon Sep 17 00:00:00 2001 From: "jeremy.thomas" Date: Thu, 25 Feb 2016 18:59:53 -0500 Subject: [PATCH 146/210] spacing --- src/platform.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform.js b/src/platform.js index c34c67683..bd6455755 100644 --- a/src/platform.js +++ b/src/platform.js @@ -47,7 +47,7 @@ exports = module.exports = { * @public */ gesture: Boolean(('ongesturestart' in window) || ('onmsgesturestart' in window && window.navigator.msMaxTouchPoints && window.navigator.msMaxTouchPoints > 1) || ('onmsgesturestart' in window && window.navigator.maxTouchPoints && window.navigator.maxTouchPoints > 1)) - + /** * The name of the platform that was detected or `undefined` if the platform * was unrecognized. This value is the key name for the major version of the From 26bbadcdb6e5563c269331d5905cd464f6125292 Mon Sep 17 00:00:00 2001 From: Anish_Ramesan Date: Fri, 26 Feb 2016 22:46:55 +0530 Subject: [PATCH 147/210] Initial version for scene changes Enyo-DCO-1.1-Signed-off-by: Anish Ramesan --- src/AnimationSupport/Actor.js | 305 +++++++++++++ src/AnimationSupport/AnimationSupport.js | 58 +++ src/AnimationSupport/Director.js | 34 +- .../{SceneEditor.js => Editor.js} | 40 +- src/AnimationSupport/Scene.js | 406 +++--------------- src/AnimationSupport/SceneActor.js | 65 --- 6 files changed, 450 insertions(+), 458 deletions(-) create mode 100644 src/AnimationSupport/Actor.js create mode 100644 src/AnimationSupport/AnimationSupport.js rename src/AnimationSupport/{SceneEditor.js => Editor.js} (89%) delete mode 100644 src/AnimationSupport/SceneActor.js diff --git a/src/AnimationSupport/Actor.js b/src/AnimationSupport/Actor.js new file mode 100644 index 000000000..38e1bf5d5 --- /dev/null +++ b/src/AnimationSupport/Actor.js @@ -0,0 +1,305 @@ +var + director = require('./Director'), + editor = require('./Editor'), + animation = require('../animation'), + utils = require('../utils'); + +var _ts, _wasts, _framerate = 16.6; + +/** + * Function to construct all the scenes instantiated from the Scene + * @memberOf module:enyo/AnimationSupport/Scene + * @private + * @param {number} id - id of the scene generated when created + * @return {object} Constructed instance + */ +var Actor = module.exports = function(prop, actor) { + + var scene = Actor.makeScene(actor), fn; + utils.mixin(scene, editor); + + fn = prop.isScene ? createFromScene : create; + fn.call(scene, prop); + return scene; +}; + + +Actor.makeScene = function(actor) { + var + _req, + + _prevDur = 0, + + /** + * Holds refereneces of the all animations added to this scene. + * @memberOf module:enyo/AnimationSupport/Scene + * @private + * @type {Array} + */ + _poses = [], + + _actor = actor, + + /** + * Returns animation pose index for a particular + * instance of time from the list of + * animations added to the scene. + * @param {number} span - Time span from the animation timeline + * @return {number} - index of the animation + * @memberOf module:enyo/AnimationSupport/Scene + * @private + */ + animateAtTime = function(span) { + var startIndex = 0, + stopIndex = _poses.length - 1, + middle = Math.floor((stopIndex + startIndex) / 2); + + if (span === 0) { + return startIndex; + } + + while (_poses[middle].span != span && startIndex < stopIndex) { + if (span < _poses[middle].span) { + stopIndex = middle; + } else if (span > _poses[middle].span) { + startIndex = middle + 1; + } + + middle = Math.floor((stopIndex + startIndex) / 2); + } + return (_poses[middle].span != span) ? startIndex : middle; + }, + + action = function(ts, pose) { + var past, index, tm, + dur = this.span; + + if (_actor && _actor.generated && this.speed) { + tm = this.rolePlay(ts); + if (isNaN(tm) || tm < 0) return pose; + else if (tm <= dur) { + index = animateAtTime(tm); + pose = this.getAnimation(index); + past = index ? this.getAnimation(index - 1).span : 0; + director.action(pose, _actor, tm - past, pose.span - past); + this.step && this.step(_actor); + } else { + this.timeline = dur; + this.speed = 0; + this.actorCompleted && this.actorCompleted(_actor); + } + } + return pose; + }; + + return { + + id: utils.uid("@"), + + isScene: true, + + /** + * An exposed property to know if know the animating state of this scene. + * 'true' - the scene is asked for animation(doesn't mean animation is happening) + * 'false' - the scene is not active(has completed or its actors are not visible) + * @type {Boolean} + * @memberOf module:enyo/AnimationSupport/Scene + * @public + */ + animating: false, + + /** + * An exposed property to know if the scene is ready with actors performing action. + * 'true' - the scene actors are ready for action + * 'false' - some or all actors are not ready + * @type {Boolean} + * @memberOf module:enyo/AnimationSupport/Scene + * @public + */ + active: false, + + /** + * Holds refereneces of complete time span for this scene. + * @type {Number} + * @memberOf module:enyo/AnimationSupport/Scene + * @public + */ + span: 0, + + /** + * This function initiates action on the animation + * from the list of animations for a given scene. + * @param {number} ts - timespan + * @param {Object} pose - pose from the animation list + * @return {Object} - pose + * @memberOf module:enyo/AnimationSupport/Scene + * @private + */ + action: action, + + /** + * Cancel the animation + * @memberOf module:enyo/AnimationSupport/Scene + * @public + */ + cancel: function() { + animation.cancelRequestAnimationFrame(_req); + }, + + /** + * Triggers the Request Animation Frame + * @param {boolean} force - A boolean value for letting the rAF start. + * @memberOf module:enyo/AnimationSupport/Scene + * @public + */ + trigger: function(force) { + if (force || !this.animating) { + _req = animation.requestAnimationFrame(loop); + } + }, + + /** + * Adds new animation on already existing animation for this character. + * @memberOf module:enyo/AnimationSupport/Scene + * @public + */ + addAnimation: function(newProp, span) { + if (_prevDur === 0 && span === 0) { + _poses[0] = { + animate: newProp, + span: 0 + }; + } else { + _prevDur = span || _prevDur; + this.span += _prevDur; + _poses.push({ + animate: newProp, + span: this.span + }); + } + }, + + /** + * Function which returns the length of the poses. + * @memberOf module:enyo/AnimationSupport/Scene + * @public + * @return {number} - length of the poses + */ + length: function() { + return _poses.length; + }, + + /** + * Clears/removes the animation + * @memberOf module:enyo/AnimationSupport/Scene + * @public + */ + clearAnimation: function() { + for (var i = 0; i < _poses.length; i++) { + _poses[i]._startAnim = undefined; + } + }, + + /** + * Returns animation pose based on index from the list of + * animations added to this scene. + * @param {number} index - animation's index from the list of animations + * @return {Object} pose of the animation based on the index in the list + * @memberOf module:enyo/AnimationSupport/Scene + * @public + */ + getAnimation: function(index) { + return index < 0 || _poses[index]; + }, + + + //TODO: Move these events to Event Delegator + /** + * Event to identify when the scene has done animating. + * @memberOf module:enyo/AnimationSupport/Scene + * @public + */ + completed: function() {}, + + /** + * Event to identify when the scene has done a step(rAF updatation of time) in the animation. + * @memberOf module:enyo/AnimationSupport/Scene + * @public + */ + step: function() {}, + + /** + * Event to identify when the actor has done animating. + * @param {Object} actor - animating element + * @memberOf module:enyo/AnimationSupport/Scene + * @public + */ + actorCompleted: function(actor) {} + }; +}; + + + +/** + * Function used to loop in all the animations in a scene + * @memberOf module:enyo/AnimationSupport/Scene + * @private + */ +function loop() { + if (this.animating) { + _ts = utils.perfNow(); + _ts = _ts - (_wasts !== undefined ? _wasts : _ts); + _ts = (_ts > _framerate) ? _framerate : _ts; + director.take(this, _ts); + _wasts = _ts; + this.trigger(true); + } else { + _wasts = undefined; + this.cancel(); + this.completed && this.completed(); + } +} + + +/** + * Creates a empty instance of scene. + * Can be used for runtime creation of animations + * @memberOf module:enyo/AnimationSupport/Scene + * @public + * @return {Object} An instance of the constructor + */ +function create(props) { + if (!props && !props.animation) return; + + var anims = utils.isArray(props.animation) ? props.animation : [props.animation], + dur = props.duration || 0; + + for (var i = 0; i < anims.length; i++) { + this.addAnimation(anims[i], anims[i].duration || dur); + delete anims[i].duration; + } + delete props.animation; + delete props.duration; +} + + +/** + * Creates a empty instance of scene. + * Can be used for runtime creation of animations + * @memberOf module:enyo/AnimationSupport/Scene + * @public + * @return {Object} An instance of the constructor + */ +function createFromScene(source) { + if (source) return; + + var i, l = source.length(), + anim; + + for (i = 0; i < l; i++) { + anim = utils.minin({}, source.getAnimation(i)); + this.addAnimation(anim.animate, anim.span); + } + + utils.mixin(this, source); +} \ No newline at end of file diff --git a/src/AnimationSupport/AnimationSupport.js b/src/AnimationSupport/AnimationSupport.js new file mode 100644 index 000000000..4bde1b34e --- /dev/null +++ b/src/AnimationSupport/AnimationSupport.js @@ -0,0 +1,58 @@ +require('enyo'); + +var + kind = require('../kind'), + scene = require('./Scene'); + +var extend = kind.statics.extend; + +kind.concatenated.push('animation'); + +var AnimationSupport = { + /** + * @private + */ + create: kind.inherit(function (sup) { + return function () { + sup.apply(this, arguments); + scene.link(this, this.scene); + }; + }), + + /** + * @private + */ + rendered: kind.inherit(function (sup) { + return function () { + sup.apply(this, arguments); + }; + }), + + /** + * @private + */ + destroy: kind.inherit(function(sup) { + return function() { + scene.delink(this, this.scene); + sup.apply(this, arguments); + }; + }) +}; + +module.exports = AnimationSupport; + +/** + Hijacking original behaviour as in other Enyo supports. +*/ +var sup = kind.concatHandler; + +/** +* @private +*/ +kind.concatHandler = function (ctor, props, instance) { + sup.call(this, ctor, props, instance); + if (props.scene) { + var proto = ctor.prototype || ctor; + extend(AnimationSupport, proto); + } +}; \ No newline at end of file diff --git a/src/AnimationSupport/Director.js b/src/AnimationSupport/Director.js index 719199534..096f8c95b 100644 --- a/src/AnimationSupport/Director.js +++ b/src/AnimationSupport/Director.js @@ -85,18 +85,12 @@ module.exports = { */ cast: function (actors, scene) { var acts = utils.isArray(actors) ? actors : [actors], - id = scene.getID(), - rolePlays = scene.rolePlays || {}; + rolePlays = scene.rolePlays || []; - if (!rolePlays[id]) { - rolePlays[id] = acts; - } else { - rolePlays[id] = acts.reduce(function(actors, actor) { + scene.rolePlays = acts.reduce(function(actors, actor) { actors.push( actor ); return actors; - }, rolePlays[id]); - } - scene.rolePlays = rolePlays; + }, rolePlays); }, /** @@ -104,19 +98,15 @@ module.exports = { * @param {Array.} actors actor or Array of actors which needs to be casted in the scene. * @param {@link @module enyo/AnimationSupport/Scene} scene Scene from which the actors has to be removed. */ - reject: function (scene, actors) { - var id = scene.getID(), acts, - rolePlays = scene.rolePlays || []; - actors = actors || rolePlays[id]; - acts = utils.isArray(actors) ? actors : [actors]; - if (rolePlays[id]) { - rolePlays[id] = acts.reduce(function(actors, actor) { - var i = actors.indexOf(actor); - if (i >= 0) actors.splice(i, 1); - return actors; - }, rolePlays[id]); - } - scene.rolePlays = rolePlays; + reject: function (actors, scene) { + var rolePlays = scene.rolePlays || [], + acts = utils.isArray(actors) ? actors : [actors]; + + scene.rolePlays = acts.reduce(function(actors, actor) { + var i = actors.indexOf(actor); + if (i >= 0) actors.splice(i, 1); + return actors; + }, rolePlays); }, /** diff --git a/src/AnimationSupport/SceneEditor.js b/src/AnimationSupport/Editor.js similarity index 89% rename from src/AnimationSupport/SceneEditor.js rename to src/AnimationSupport/Editor.js index 14824613a..1f619a915 100644 --- a/src/AnimationSupport/SceneEditor.js +++ b/src/AnimationSupport/Editor.js @@ -1,7 +1,7 @@ require('enyo'); /** -* @module enyo/AnimationSupport/SceneEditor +* @module enyo/AnimationSupport/Editor */ /** @@ -20,19 +20,15 @@ module.exports = { /** * @private */ - _frameSpeed: 0, - /** - * @private - */ - _startTime: 0, + speed: 0, /** * @private */ cache: function(actor) { actor = actor || this; - if(actor._frameSpeed === 0){ - actor._frameSpeed = actor._cachedValue; + if(actor.speed === 0){ + actor.speed = actor._cachedValue; } this.animating = true; }, @@ -45,7 +41,7 @@ module.exports = { */ play: function (actor) { actor = actor || this; - actor._frameSpeed = 1; + actor.speed = 1; if (isNaN(actor.timeline) || !actor.timeline) { actor.timeline = 0; } @@ -62,7 +58,7 @@ module.exports = { resume: function(actor) { this.cache(actor); actor = actor || this; - actor._frameSpeed *= 1; + actor.speed *= 1; }, /** @@ -73,8 +69,8 @@ module.exports = { */ pause: function (actor) { actor = actor || this; - actor._cachedValue = actor._frameSpeed; - actor._frameSpeed = 0; + actor._cachedValue = actor.speed; + actor.speed = 0; }, /** @@ -86,7 +82,7 @@ module.exports = { reverse: function (actor) { this.cache(actor); actor = actor || this; - actor._frameSpeed *= -1; + actor.speed *= -1; }, /** @@ -98,7 +94,7 @@ module.exports = { fast: function (mul, actor) { this.cache(actor); actor = actor || this; - actor._frameSpeed *= mul; + actor.speed *= mul; }, /** @@ -110,7 +106,7 @@ module.exports = { slow: function (mul, actor) { this.cache(actor); actor = actor || this; - actor._frameSpeed *= mul; + actor.speed *= mul; }, /** @@ -118,7 +114,7 @@ module.exports = { * Speed of the animation changed based on the factor.
* To slow down the speed use values between 0 and 1. For Example 0.5 to reduce the speed by 50%.
* To increase the speed use values above 1. For Example 2 to increase the speed by 200%.
- * Animation will be paused if factor is 0. To pause the animation use {@link enyo/AnimationSupport/SceneEditor.pause pause} API.
+ * Animation will be paused if factor is 0. To pause the animation use {@link enyo/AnimationSupport/Editor.pause pause} API.
* Speed will not be affected incase of negative multiplication factor. * @param {Number} factor Multiplication factor which changes the speed * @param [Component {@link module:enyo/Component~Component}] actor The component whose animating speed should be changed @@ -128,7 +124,7 @@ module.exports = { if (mul < 0) return; this.cache(actor); actor = actor || this; - actor._frameSpeed *= mul; + actor.speed *= mul; }, /** @@ -140,10 +136,10 @@ module.exports = { stop: function (actor) { actor = actor || this; actor._cachedValue = 1; - actor._frameSpeed = 0; + actor.speed = 0; actor.timeline = 0; - this.animating = false; - this.cancel(); + // this.animating = false; + // this.cancel(); }, /** @@ -175,9 +171,9 @@ module.exports = { actor.timeline = 0; if(actor.delay > 0) { - actor.delay -= _rolePlay(t, actor._frameSpeed); + actor.delay -= _rolePlay(t, actor.speed); } else { - actor.timeline += _rolePlay(t, actor._frameSpeed); + actor.timeline += _rolePlay(t, actor.speed); } return actor.timeline; } diff --git a/src/AnimationSupport/Scene.js b/src/AnimationSupport/Scene.js index 3be48f4b9..5704aef25 100644 --- a/src/AnimationSupport/Scene.js +++ b/src/AnimationSupport/Scene.js @@ -1,8 +1,7 @@ var - editor = require('./SceneEditor'), - director = require('./Director'), - animation = require('../animation'), - utils = require('../utils'); + actor = require('./Actor'), + director = require('./Director'), + utils = require('../utils'); /** * This module exports "Scene" which is a class/constructor so that we can create an instance of the same. @@ -10,40 +9,46 @@ var * * @module enyo/AnimationSupport/Scene */ -var Scene = module.exports = function(props) { - var scene = Scene.create(), - dur = props.duration || 0; +module.exports = function(props) { + var scene = actor(props); + utils.mixin(scene, Scene); +}; - utils.mixin(scene, editor); +var Scene = { + threshold: 0, - if (props.animation) { - var anims = utils.isArray(props.animation) ? props.animation : [props.animation]; + rolePlays: [], - for (var i = 0; i < anims.length; i++) { - scene.addAnimation(anims[i], anims[i].span || anims[i].duration || dur); - delete anims[i].duration; - } - delete props.animation; - delete props.duration; - } + action: function(ts, pose) { + var i, role, actor, count = 0, + tm = this.rolePlay(ts); - utils.mixin(scene, props); - utils.mixin(scene, SceneAction); - return scene; -}; + tm += this.threshold; + for (i = 0; (role = this.rolePlays[i]); i++) { + //TODO: set matrix 2d to these components + if (tm > role.span) continue; -/** - * Creates a empty instance of scene. - * Can be used for runtime creation of animations - * @memberOf module:enyo/AnimationSupport/Scene - * @public - * @return {Object} An instance of the constructor - */ -Scene.create = function() { - return new sceneConstructor(utils.uid("@")); -}; + actor = role.actor; + if (tm === role.span) { + pose = actor.action(ts, pose); + break; + } else if (tm > role.span) { + pose = actor.action(ts, pose); + } else { + actor.timeline = count * this.threshold; + pose = actor.action(ts, pose); + count ++; + } + } + return pose; + }, + + updateSpan: function(span) { + this.span = this.totalSpan * span / this.threshold; + } +}; /** * Connects an actor/s to a scene. @@ -54,7 +59,18 @@ Scene.create = function() { * @param {Object} scene - The instance of the Scene we've created in the application */ Scene.link = function(actors, scene) { - director.cast(actors, scene); + if (!scene && !actors ) return; + + var actorScene, + acts = utils.isArray(actors) ? actors : [actors]; + + for (var i = 0; i < acts.length; i++) { + actorScene = actor(scene, acts[i]); + if (scene.isScene) { + scene.span += actorScene.span; + scene.rolePlays.push({actor: actorScene, span: scene.span}); + } + } }; @@ -68,321 +84,13 @@ Scene.link = function(actors, scene) { * @param {Object} scene - The instance of the Scene we've created in the application */ Scene.delink = function(actors, scene) { - director.reject(scene, actors); -}; - - -/** - * Function to construct all the scenes instantiated from the Scene - * @memberOf module:enyo/AnimationSupport/Scene - * @private - * @param {number} id - id of the scene generated when created - * @return {object} Constructed instance - */ -var sceneConstructor = function(id) { - var - _ts, _wasts, _req, - _framerate = 16.6, - /** - * Stores the id of the instance created - * @memberOf module:enyo/AnimationSupport/Scene - * @private - * @type {Array} - */ - _id = id, - - /** - * Holds refereneces of the all animations added to this scene. - * @memberOf module:enyo/AnimationSupport/Scene - * @private - * @type {Array} - */ - _poses = [], - - /** - * Holds old animation time span, useful for scenarios where same - * time span is expected to be added for the latest added animation. - * This provides the felxibility to add animation without duration. - * - * Like: scene.addAnimation({translate: '50,0,0'}); - * - * As no duration is mentioned the old animations duration is taken. - * @type {Number} - * @memberOf module:enyo/AnimationSupport/Scene - * @private - */ - _prevDur = 0; - - /** - * An exposed property to know if know the animating state of this scene. - * 'true' - the scene is asked for animation(doesn't mean animation is happening) - * 'false' - the scene is not active(has completed or its actors are not visible) - * @type {Boolean} - * @memberOf module:enyo/AnimationSupport/Scene - * @public - */ - this.animating = false; - - /** - * An exposed property to know if the scene is ready with actors performing action. - * 'true' - the scene actors are ready for action - * 'false' - some or all actors are not ready - * @type {Boolean} - * @memberOf module:enyo/AnimationSupport/Scene - * @public - */ - this.active = false; - - /** - * Holds refereneces of complete time span for this scene. - * @type {Number} - * @memberOf module:enyo/AnimationSupport/Scene - * @public - */ - this.span = 0; - - - /** - * Function used to loop in all the animations in a scene - * @memberOf module:enyo/AnimationSupport/Scene - * @private - */ - function loop() { - if (this.animating) { - _ts = utils.perfNow(); - _ts = _ts - (_wasts !== undefined ? _wasts : _ts); - _ts = (_ts > _framerate) ? _framerate : _ts; - director.take(this, _ts); - _wasts = _ts; - this.trigger(true); - } else { - _wasts = undefined; - this.cancel(); - this.completed && this.completed(); - } - } - /** - * Function used to make start the animation if it is "true" for animating. - * @memberOf module:enyo/AnimationSupport/Scene - * @public - */ - this.ready = function() { - if (this.animating) { - if (!this.active) { - director.roll(this); - } - return this.active; - } - return false; - }; - - /** - * Cancel the animation - * @memberOf module:enyo/AnimationSupport/Scene - * @public - */ - this.cancel = function() { - animation.cancelRequestAnimationFrame(_req); - }; - - - /** - * Triggers the Request Animation Frame - * @param {boolean} force - A boolean value for letting the rAF start. - * @memberOf module:enyo/AnimationSupport/Scene - * @public - */ - this.trigger = function(force) { - if (force || !this.animating) { - _req = animation.requestAnimationFrame(utils.bindSafely(this, loop)); - } - }; - - - /** - * Gets the unique ID assigned to this sceen. - * @return {number} - id - * @memberOf module:enyo/AnimationSupport/Scene - * @public - */ - this.getID = function() { - return _id; - }; - - - /** - * Returns the life span/duration of this sceen. - * @return {number} life span/duration of this sceen - * @memberOf module:enyo/AnimationSupport/Scene - * @public - */ - this.totalSpan = function() { - return this.span; - }; - - /** - * Adds new animation on already existing animation for this character. - * @memberOf module:enyo/AnimationSupport/Scene - * @public - */ - this.addAnimation = function(newProp, span) { - if (_prevDur === 0 && span === 0) { - _poses[0] = { - animate: newProp, - span: 0 - }; - } else { - _prevDur = span || _prevDur; - this.span += _prevDur; - _poses.push({ - animate: newProp, - span: this.span - }); - } - }; - /** - * Function which returns the length of the poses. - * @memberOf module:enyo/AnimationSupport/Scene - * @public - * @return {number} - length of the poses - */ - this.length = function() { - return _poses.length; - }; - /** - * Returns animation pose index for a particular - * instance of time from the list of - * animations added to the scene. - * @param {number} span - Time span from the animation timeline - * @return {number} - index of the animation - * @memberOf module:enyo/AnimationSupport/Scene - * @public - */ - this.animateAtTime = function(span) { - var startIndex = 0, - stopIndex = _poses.length - 1, - middle = Math.floor((stopIndex + startIndex) / 2); - - if (span === 0) { - return startIndex; - } - - while (_poses[middle].span != span && startIndex < stopIndex) { - if (span < _poses[middle].span) { - stopIndex = middle; - } else if (span > _poses[middle].span) { - startIndex = middle + 1; - } - - middle = Math.floor((stopIndex + startIndex) / 2); - } - return (_poses[middle].span != span) ? startIndex : middle; - }; - - /** - * Clears/removes the animation - * @memberOf module:enyo/AnimationSupport/Scene - * @public - */ - this.clearAnimation = function() { - for (var i = 0; i < _poses.length; i++) { - _poses[i]._startAnim = undefined; - } - }; - - /** - * Returns animation pose based on index from the list of - * animations added to this scene. - * @param {number} index - animation's index from the list of animations - * @return {Object} pose of the animation based on the index in the list - * @memberOf module:enyo/AnimationSupport/Scene - * @public - */ - this.getAnimation = function(index) { - return index < 0 || _poses[index]; - }; - - /** - * Sets the newly added animation to the poses - * @param {Numner} index - index to which the new animation should set - * @param {Object} pose - newly added animation - * @memberOf module:enyo/AnimationSupport/Scene - * @public - */ - this.setAnimation = function(index, pose) { - _poses[index] = pose; - }; - - - //TODO: Move these events to Event Delegator - /** - * Event to identify when the scene has done animating. - * @memberOf module:enyo/AnimationSupport/Scene - * @public - */ - this.completed = function() {}; - - /** - * Event to identify when the scene has done a step(rAF updatation of time) in the animation. - * @memberOf module:enyo/AnimationSupport/Scene - * @public - */ - this.step = function() {}; - - /** - * Event to identify when the actor has done animating. - * @param {Object} actor - animating element - * @memberOf module:enyo/AnimationSupport/Scene - * @public - */ - this.actorCompleted = function(actor) {}; -}; - -/** - * SceneAction exposes the api which performs the action on the animation in a given scene - * @type {Object} - * @memberOf module:enyo/AnimationSupport/Scene - * @private - */ -var SceneAction = { - /** - * This function initiates action on the animation - * from the list of animations for a given scene. - * @param {number} ts - timespan - * @param {Object} pose - pose from the animation list - * @return {Object} - pose - * @memberOf module:enyo/AnimationSupport/Scene - * @private - */ - action: function(ts, pose) { - var past, - actor, - actors,i, - tm = this.rolePlay(ts), - index = this.animateAtTime(tm); - - if (index < 0) { - return; - } - pose = this.getAnimation(index); - past = pose.animate; - - if (past instanceof sceneConstructor) { - past._frameSpeed = this._frameSpeed; - director.take(past, ts); - } else { - past = index ? this.getAnimation(index - 1).span : 0; - actors = this.rolePlays[this.getID()]; - for (i = 0; (actor = actors[i]); i++) { - if (actor.generated) { - director.action(pose, - actors[i], - tm - past, - pose.span - past); - this.step && this.step(actor); - } - } - } - return pose; - } + var parent, acts = utils.isArray(actors) ? actors : [actors], actor; + + if (typeof scene == 'function') { + parent = scene; + } + for (var i = 0; i < acts.length; i++) { + director.reject(parent, actor.scene); + actor.scene = undefined; + } }; \ No newline at end of file diff --git a/src/AnimationSupport/SceneActor.js b/src/AnimationSupport/SceneActor.js deleted file mode 100644 index 81eb194fd..000000000 --- a/src/AnimationSupport/SceneActor.js +++ /dev/null @@ -1,65 +0,0 @@ -var - Scene = require('./Scene'), - director = require('./Director'), - utils = require('../utils'); - -var - tm, actor, actors, len, dur; - -var CharacterAction = { - /** - * Overridden function initiates action on the animation - * for the given scene actor. - * @param {number} ts - timespan - * @param {Object} pose - pose from the animation list - * @return {Object} - pose - * @memberOf module:enyo/AnimationSupport/SceneActor - * @private - * @override - */ - action: function (ts, pose) { - var i, past, index; - - actors = this.rolePlays[this.getID()]; - len = actors.length; - dur = this.span; - for (i = 0; (actor = actors[i]); i++) { - //give priority to individual actor than scene. - if (!actor._frameSpeed) { - actor._frameSpeed = this._frameSpeed; - } - - if (actor.generated && actor._frameSpeed) { - tm = this.rolePlay(ts, actor); - if (isNaN(tm) || tm < 0) continue; - else if (tm <= dur) { - index = this.animateAtTime(tm); - pose = this.getAnimation(index); - past = index ? this.getAnimation(index - 1).span : 0; - director.action(pose, actor, tm - past, pose.span - past); - this.step && this.step(actor); - } else { - actor.timeline = dur; - actor._frameSpeed = 0; - this.actorCompleted && this.actorCompleted(actor); - } - } - } - return pose; - } -}; - -/** - * Scene Actor is used to individually manage all the actors

- * The Scene Actor is similar to Scene but can receive - * an actor for playing the animation.
- * Scene Actor's play when called without the actor, - * it works same as Scene playing all the actors.

- * Usage - SceneActorInstance.play(actor) - * @module enyo/AnimationSupport/SceneActor - */ -module.exports = function(props) { - var scene = Scene(props); - utils.mixin(scene, CharacterAction); - return scene; -}; From 11e13948867f777544fefecf94a466e231a9565b Mon Sep 17 00:00:00 2001 From: "jeremy.thomas" Date: Fri, 26 Feb 2016 15:12:36 -0500 Subject: [PATCH 148/210] update gesture conditional --- src/platform.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform.js b/src/platform.js index bd6455755..804c4a3ac 100644 --- a/src/platform.js +++ b/src/platform.js @@ -46,7 +46,7 @@ exports = module.exports = { * `true` if the platform has native double-finger [events]{@glossary event}. * @public */ - gesture: Boolean(('ongesturestart' in window) || ('onmsgesturestart' in window && window.navigator.msMaxTouchPoints && window.navigator.msMaxTouchPoints > 1) || ('onmsgesturestart' in window && window.navigator.maxTouchPoints && window.navigator.maxTouchPoints > 1)) + gesture: Boolean(('ongesturestart' in window) || ('onmsgesturestart' in window && (window.navigator.msMaxTouchPoints > 1 || window.navigator.maxTouchPoints > 1))) /** * The name of the platform that was detected or `undefined` if the platform From a1fe2291191f394833add3f6fd7bf6cf1100b950 Mon Sep 17 00:00:00 2001 From: System Administrator Date: Mon, 29 Feb 2016 03:28:24 +0530 Subject: [PATCH 149/210] some changes related to threshold --- src/AnimationSupport/Actor.js | 17 ++++---- src/AnimationSupport/AnimationSupport.js | 1 + src/AnimationSupport/Editor.js | 21 ++++++---- src/AnimationSupport/Scene.js | 49 ++++++++++++++++-------- 4 files changed, 53 insertions(+), 35 deletions(-) diff --git a/src/AnimationSupport/Actor.js b/src/AnimationSupport/Actor.js index 38e1bf5d5..4e3b47b4b 100644 --- a/src/AnimationSupport/Actor.js +++ b/src/AnimationSupport/Actor.js @@ -154,7 +154,7 @@ Actor.makeScene = function(actor) { */ trigger: function(force) { if (force || !this.animating) { - _req = animation.requestAnimationFrame(loop); + _req = animation.requestAnimationFrame(utils.bindSafely(this, loop)); } }, @@ -269,17 +269,14 @@ function loop() { * @return {Object} An instance of the constructor */ function create(props) { - if (!props && !props.animation) return; + if (!props) return; - var anims = utils.isArray(props.animation) ? props.animation : [props.animation], - dur = props.duration || 0; + var anims = utils.isArray(props) ? props : [props]; for (var i = 0; i < anims.length; i++) { - this.addAnimation(anims[i], anims[i].duration || dur); + this.addAnimation(anims[i], anims[i].duration || 0); delete anims[i].duration; } - delete props.animation; - delete props.duration; } @@ -291,15 +288,15 @@ function create(props) { * @return {Object} An instance of the constructor */ function createFromScene(source) { - if (source) return; + if (!source) return; var i, l = source.length(), anim; for (i = 0; i < l; i++) { - anim = utils.minin({}, source.getAnimation(i)); + anim = utils.mixin({}, source.getAnimation(i)); this.addAnimation(anim.animate, anim.span); } - utils.mixin(this, source); + } \ No newline at end of file diff --git a/src/AnimationSupport/AnimationSupport.js b/src/AnimationSupport/AnimationSupport.js index 4bde1b34e..f19adcb57 100644 --- a/src/AnimationSupport/AnimationSupport.js +++ b/src/AnimationSupport/AnimationSupport.js @@ -16,6 +16,7 @@ var AnimationSupport = { return function () { sup.apply(this, arguments); scene.link(this, this.scene); + console.log("comp : " + this.name + " linked to :", this.scene); }; }), diff --git a/src/AnimationSupport/Editor.js b/src/AnimationSupport/Editor.js index 1f619a915..9c243295d 100644 --- a/src/AnimationSupport/Editor.js +++ b/src/AnimationSupport/Editor.js @@ -21,7 +21,10 @@ module.exports = { * @private */ speed: 0, - + /** + * @private + */ + startTimeline: 0, /** * @private */ @@ -120,12 +123,12 @@ module.exports = { * @param [Component {@link module:enyo/Component~Component}] actor The component whose animating speed should be changed * @public */ - speed: function(mul, actor) { - if (mul < 0) return; - this.cache(actor); - actor = actor || this; - actor.speed *= mul; - }, + // speed: function(mul, actor) { + // if (mul < 0) return; + // this.cache(actor); + // actor = actor || this; + // actor.speed *= mul; + // }, /** * Stops the animation of the actor given in argument. @@ -172,7 +175,9 @@ module.exports = { if(actor.delay > 0) { actor.delay -= _rolePlay(t, actor.speed); - } else { + } if(actor.startTimeline > 0 && actor.timeline == 0){ + actor.timeline = actor.startTimeline; + } else { actor.timeline += _rolePlay(t, actor.speed); } return actor.timeline; diff --git a/src/AnimationSupport/Scene.js b/src/AnimationSupport/Scene.js index 5704aef25..93909bab8 100644 --- a/src/AnimationSupport/Scene.js +++ b/src/AnimationSupport/Scene.js @@ -9,36 +9,48 @@ var * * @module enyo/AnimationSupport/Scene */ -module.exports = function(props) { +var Scene = module.exports = function(props) { var scene = actor(props); - utils.mixin(scene, Scene); + utils.mixin(scene, SceneAction); + utils.mixin(scene, props); + return scene; }; -var Scene = { +var SceneAction = { threshold: 0, rolePlays: [], action: function(ts, pose) { var i, role, actor, count = 0, - tm = this.rolePlay(ts); + tm = this.rolePlay(ts), + animate = false; + thres = this.threshold; - tm += this.threshold; + //tm += this.threshold; for (i = 0; (role = this.rolePlays[i]); i++) { - + actor = role.actor; //TODO: set matrix 2d to these components - if (tm > role.span) continue; + if (actor.timeline >= role.dur) continue; - actor = role.actor; - if (tm === role.span) { - pose = actor.action(ts, pose); + + if (thres === (role.dur)) { + animate = true; break; - } else if (tm > role.span) { - pose = actor.action(ts, pose); + } else if (thres > (role.dur)) { + animate = true; } else { - actor.timeline = count * this.threshold; + if((count * thres) < role.span) { + actor.startTimeline = count * thres; + animate = true; + count ++; + } + } + + if (animate) { + actor.speed = this.speed; pose = actor.action(ts, pose); - count ++; + animate = false; } } return pose; @@ -64,11 +76,14 @@ Scene.link = function(actors, scene) { var actorScene, acts = utils.isArray(actors) ? actors : [actors]; - for (var i = 0; i < acts.length; i++) { - actorScene = actor(scene, acts[i]); + for (var act, i = 0; (act = acts[i]); i++) { if (scene.isScene) { + actorScene = act.scene.isScene ? act.scene : actor(act.scene, act); scene.span += actorScene.span; - scene.rolePlays.push({actor: actorScene, span: scene.span}); + scene.rolePlays.push({actor: actorScene, span: scene.span, dur: actorScene.span}); + } else { + actorScene = actor(scene, act); + acts[i].scene = actorScene; } } }; From 53370c8fe354b6543ce708c82f590903a94f230a Mon Sep 17 00:00:00 2001 From: Aaron Tam Date: Mon, 29 Feb 2016 14:53:29 -0800 Subject: [PATCH 150/210] ENYO-3144: Use container-based infrastructure for Travis. Enyo-DCO-1.1-Signed-off-by: Aaron Tam --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 065e17d82..855feb1f0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ -language: node_js sudo: false +language: node_js node_js: - - "0.12" + - "node" cache: directories: - $HOME/.npm \ No newline at end of file From a4de09e2a171b81b3f3a73eaf07c51eeb855566d Mon Sep 17 00:00:00 2001 From: Jason Robitaille Date: Mon, 29 Feb 2016 16:18:41 -0800 Subject: [PATCH 151/210] Update version string to 2.7.0-rc.1 --- index.js | 2 +- package.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index ca5e1a50e..348ff0185 100644 --- a/index.js +++ b/index.js @@ -1,4 +1,4 @@ 'use strict'; exports = module.exports = require('./src/options'); -exports.version = '2.6.0-rc.1'; +exports.version = '2.7.0-rc.1'; diff --git a/package.json b/package.json index 67da02234..2535f7735 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "main": "index.js", "moduleDir": "src", "filename": "enyo.js", - "version": "2.6.0-pre", + "version": "2.7.0-rc.1", "description": "Enyo is an open source object-oriented JavaScript framework emphasizing encapsulation and modularity. Enyo contains everything you need to create a fast, scalable mobile or web application.", "homepage": "http://enyojs.com/", "bugs": "http://jira.enyojs.com/", @@ -48,4 +48,4 @@ "sinon-chai": "^2.8.0", "through2": "^2.0.0" } -} +} \ No newline at end of file From d469c33dc4e82693f04d9c094c0edf7d33c5065d Mon Sep 17 00:00:00 2001 From: Anish_Ramesan Date: Tue, 1 Mar 2016 21:28:02 +0530 Subject: [PATCH 152/210] threshold with scene Enyo-DCO-1.1-Signed-off-by: Anish Ramesan --- src/AnimationSupport/Actor.js | 3 +- src/AnimationSupport/AnimationSupport.js | 9 +++- src/AnimationSupport/Scene.js | 59 +++++++++++++++--------- 3 files changed, 46 insertions(+), 25 deletions(-) diff --git a/src/AnimationSupport/Actor.js b/src/AnimationSupport/Actor.js index 4e3b47b4b..5e5c82d9f 100644 --- a/src/AnimationSupport/Actor.js +++ b/src/AnimationSupport/Actor.js @@ -86,6 +86,7 @@ Actor.makeScene = function(actor) { } else { this.timeline = dur; this.speed = 0; + this.active = false; this.actorCompleted && this.actorCompleted(_actor); } } @@ -297,6 +298,4 @@ function createFromScene(source) { anim = utils.mixin({}, source.getAnimation(i)); this.addAnimation(anim.animate, anim.span); } - - } \ No newline at end of file diff --git a/src/AnimationSupport/AnimationSupport.js b/src/AnimationSupport/AnimationSupport.js index f19adcb57..b3026a139 100644 --- a/src/AnimationSupport/AnimationSupport.js +++ b/src/AnimationSupport/AnimationSupport.js @@ -2,6 +2,7 @@ require('enyo'); var kind = require('../kind'), + actor = require('./Actor'), scene = require('./Scene'); var extend = kind.statics.extend; @@ -15,7 +16,13 @@ var AnimationSupport = { create: kind.inherit(function (sup) { return function () { sup.apply(this, arguments); - scene.link(this, this.scene); + var parent = this.scene.isScene && this.scene; + if (parent) { + this.scene = actor(this.scene, this); + scene.link(this, parent); + } else { + scene.link(this, this.scene); + } console.log("comp : " + this.name + " linked to :", this.scene); }; }), diff --git a/src/AnimationSupport/Scene.js b/src/AnimationSupport/Scene.js index 93909bab8..83cce1ade 100644 --- a/src/AnimationSupport/Scene.js +++ b/src/AnimationSupport/Scene.js @@ -22,35 +22,26 @@ var SceneAction = { rolePlays: [], action: function(ts, pose) { - var i, role, actor, count = 0, + var i, role, actor, tm = this.rolePlay(ts), - animate = false; - thres = this.threshold; + thres = this.threshold || this.span; - //tm += this.threshold; - for (i = 0; (role = this.rolePlays[i]); i++) { - actor = role.actor; - //TODO: set matrix 2d to these components - if (actor.timeline >= role.dur) continue; - - - if (thres === (role.dur)) { - animate = true; - break; - } else if (thres > (role.dur)) { - animate = true; - } else { - if((count * thres) < role.span) { - actor.startTimeline = count * thres; - animate = true; - count ++; + role = this.rolePlays[Math.floor(tm/thres)]; + if (role && thres < role.dur) { + role.actor.active = true; + } else { + for (i = 0; (role = this.rolePlays[i]); i++) { + if ((tm + thres) >= role.span ) { + role.actor.active = true; } } + } - if (animate) { + for (i = 0; (role = this.rolePlays[i]); i++) { + actor = role.actor; + if (actor.active) { actor.speed = this.speed; pose = actor.action(ts, pose); - animate = false; } } return pose; @@ -62,6 +53,30 @@ var SceneAction = { }; + + + // if (thres === role.dur) { + // actor.speed = this.speed; + // pose = actor.action(ts, pose); + // tm = this.rolePlay(ts); + // console.log(tm + " same duration:"+ role.span); + // break; + // } else if (thres > role.dur) { + // thres -= role.dur; + // actor.speed = this.speed; + // tm = this.rolePlay(ts); + // pose = actor.action(ts, pose); + // console.log(tm + " greater duration"+ role.span); + // } + // else { + // actor.speed = this.speed; + // tm = this.rolePlay(ts); + // // actor.timeline = tm == 0 ? 0 : thres; + // pose = actor.action(ts, pose); + // break; + // } + + /** * Connects an actor/s to a scene. * All the actors should be added before initiating animation otherwise actors will animate for remaining time span From ea4496e8b4fd224c98ab1d5f35c421651b38d8bb Mon Sep 17 00:00:00 2001 From: Stephen Choi Date: Mon, 18 Jan 2016 14:26:23 -0800 Subject: [PATCH 153/210] ENYO-1998: Return source action result on execute Enyo-DCO-1.1-Signed-off-by: Stephen Choi ENYO-1998: Return array of results in case of multiple sources Enyo-DCO-1.1-Signed-off-by: Stephen Choi ENYO-1998: Remove forEach and cleanup Enyo-DCO-1.1-Signed-off-by: Stephen Choi --- src/Source.js | 99 ++++++++++++++++++++++++++++----------------------- 1 file changed, 54 insertions(+), 45 deletions(-) diff --git a/src/Source.js b/src/Source.js index 0aed6e36e..1f41c1b56 100644 --- a/src/Source.js +++ b/src/Source.js @@ -22,19 +22,19 @@ var sources = {}; */ var Source = module.exports = kind( /** @lends module:enyo/Source~Source.prototype */ { - + name: 'enyo.Source', - + /** * @private */ kind: null, - + /** * @private */ - + /** * When initialized, the source should be passed properties to set on itself. * These properties should include the name by which it will be referenced in @@ -46,11 +46,11 @@ var Source = module.exports = kind( constructor: function (props) { if (props) this.importProps(props); // automatic coersion of name removing prefix - this.name || (this.name = this.kindName.replace(/^(.*)\./, "")); + this.name || (this.name = this.kindName.replace(/^(.*)\./, '')); // now add to the global registry of sources sources[this.name] = this; }, - + /** * Overload this method to handle retrieval of data. This method should accept an options * [hash]{@glossary Object} with additional configuration properties, including `success` @@ -65,7 +65,7 @@ var Source = module.exports = kind( fetch: function (model, opts) { // }, - + /** * Overload this method to handle persisting of data. This method should accept an options * [hash]{@glossary Object} with additional configuration properties, including `success` @@ -80,7 +80,7 @@ var Source = module.exports = kind( commit: function (model, opts) { // }, - + /** * Overload this method to handle deletion of data. This method should accept an options * [hash]{@glossary Object} with additional configuration properties, including `success` @@ -94,7 +94,7 @@ var Source = module.exports = kind( * `success` and `error` callbacks. */ destroy: function (model, opts) { - + // if called with no parameters we actually just breakdown the source and remove // it as being available if (!arguments.length) { @@ -102,7 +102,7 @@ var Source = module.exports = kind( this.name = null; } }, - + /** * Overload this method to handle querying of data based on the passed-in constructor. This * method should accept an options [hash]{@glossary Object} with additional configuration @@ -117,21 +117,21 @@ var Source = module.exports = kind( find: function (ctor, opts) { // }, - + /** * @private */ importProps: function (props) { props && utils.mixin(this, props); }, - + /** * @see module:enyo/utils#getPath * @method * @public */ get: utils.getPath, - + /** * @see module:enyo/utils#setPath * @method @@ -159,9 +159,9 @@ var Source = module.exports = kind( */ Source.create = function (props) { var Ctor = (props && props.kind) || this; - + if (typeof Ctor == 'string') Ctor = kind.constructorForKind(Ctor); - + return new Ctor(props); }; @@ -172,10 +172,10 @@ Source.create = function (props) { * @private */ Source.concat = function (ctor, props) { - + // force noDefer so that we can actually set this method on the constructor if (props) props.noDefer = true; - + ctor.create = Source.create; }; @@ -187,86 +187,95 @@ Source.concat = function (ctor, props) { */ Source.execute = function (action, model, opts) { var source = opts.source || model.source, - + // we need to be able to bind the success and error callbacks for each of the // sources we'll be using options = utils.clone(opts, true), nom = source, - msg; - + msg, + ret; + if (source) { - + // if explicitly set to true then we need to use all available sources in the // application if (source === true) { - + for (nom in sources) { source = sources[nom]; if (source[action]) { - + // bind the source name to the success and error callbacks options.success = opts.success.bind(null, nom); options.error = opts.error.bind(null, nom); - - source[action](model, options); + + ret = source[action](model, options); } } } - + // if it is an array of specific sources to use we, well, will only use those! else if (source instanceof Array) { - source.forEach(function (nom) { - var src = typeof nom == 'string' ? sources[nom] : nom; - + var i, + src; + + ret = []; + + for (i = 0; i < source.length; i++) { + nom = source[i]; + src = typeof nom == 'string' ? sources[nom] : nom; + if (src && src[action]) { // bind the source name to the success and error callbacks options.success = opts.success.bind(null, src.name); options.error = opts.error.bind(null, src.name); - - src[action](model, options); + + ret.push(src[action](model, options)); } - }); + } } - + // if it is an instance of a source else if (source instanceof Source && source[action]) { - + // bind the source name to the success and error callbacks options.success = opts.success.bind(null, source.name); options.error = opts.error.bind(null, source.name); - - source[action](model, options); + + ret = source[action](model, options); } - + // otherwise only one was specified and we attempt to use that else if ((source = sources[nom]) && source[action]) { - + // bind the source name to the success and error callbacks options.success = opts.success.bind(null, nom); options.error = opts.error.bind(null, nom); - - source[action](model, options); + + ret = source[action](model, options); } - + // we could not resolve the requested source else { msg = 'enyo.Source.execute(): requested source(s) could not be found for ' + model.kindName + '.' + action + '()'; - + logger.warn(msg); - + // we need to fail the attempt and let it be handled opts.error(nom ? typeof nom == 'string' ? nom : nom.name : 'UNKNOWN', msg); } } else { msg = 'enyo.Source.execute(): no source(s) provided for ' + model.kindName + '.' + action + '()'; - + logger.warn(msg); - + // we need to fail the attempt and let it be handled opts.error(nom ? typeof nom == 'string' ? nom : nom.name : 'UNKNOWN', msg); } + + return ret; }; /** From e7cf74da2ca45d8111756a70f1956a85b9a09426 Mon Sep 17 00:00:00 2001 From: Anish_Ramesan Date: Fri, 4 Mar 2016 21:56:28 +0530 Subject: [PATCH 154/210] updates related to layer optimization Enyo-DCO-1.1-Signed-off-by: Anish Ramesan --- src/AnimationSupport/Actor.js | 63 +++++++++---------- src/AnimationSupport/Director.js | 18 ++++++ src/AnimationSupport/Editor.js | 30 +++++++--- src/AnimationSupport/Frame.js | 100 +++++++++++++++++++++++++++---- src/AnimationSupport/Matrix.js | 15 ++++- src/AnimationSupport/Scene.js | 11 ++-- src/AnimationSupport/Tween.js | 14 ++++- 7 files changed, 182 insertions(+), 69 deletions(-) diff --git a/src/AnimationSupport/Actor.js b/src/AnimationSupport/Actor.js index 5e5c82d9f..dacc95cda 100644 --- a/src/AnimationSupport/Actor.js +++ b/src/AnimationSupport/Actor.js @@ -18,7 +18,7 @@ var Actor = module.exports = function(prop, actor) { var scene = Actor.makeScene(actor), fn; utils.mixin(scene, editor); - fn = prop.isScene ? createFromScene : create; + fn = prop && prop.isScene ? createFromScene : create; fn.call(scene, prop); return scene; }; @@ -74,7 +74,7 @@ Actor.makeScene = function(actor) { var past, index, tm, dur = this.span; - if (_actor && _actor.generated && this.speed) { + if (_actor && _actor.generated) { tm = this.rolePlay(ts); if (isNaN(tm) || tm < 0) return pose; else if (tm <= dur) { @@ -84,13 +84,31 @@ Actor.makeScene = function(actor) { director.action(pose, _actor, tm - past, pose.span - past); this.step && this.step(_actor); } else { - this.timeline = dur; - this.speed = 0; - this.active = false; - this.actorCompleted && this.actorCompleted(_actor); + director.cut(this, _actor); + this.completed && this.completed(_actor); } } return pose; + }, + + /** + * Function used to loop in all the animations in a scene + * @memberOf module:enyo/AnimationSupport/Scene + * @private + */ + loop = function() { + if (this.animating) { + _ts = utils.perfNow(); + _ts = _ts - (_wasts !== undefined ? _wasts : _ts); + _ts = (_ts > _framerate) ? _framerate : _ts; + director.take(this, _ts); + _wasts = _ts; + this.trigger(true); + } else { + _wasts = undefined; + this.cancel(); + this.completed && this.completed(_actor); + } }; return { @@ -227,39 +245,12 @@ Actor.makeScene = function(actor) { * @memberOf module:enyo/AnimationSupport/Scene * @public */ - step: function() {}, - - /** - * Event to identify when the actor has done animating. - * @param {Object} actor - animating element - * @memberOf module:enyo/AnimationSupport/Scene - * @public - */ - actorCompleted: function(actor) {} + step: function() {} }; }; -/** - * Function used to loop in all the animations in a scene - * @memberOf module:enyo/AnimationSupport/Scene - * @private - */ -function loop() { - if (this.animating) { - _ts = utils.perfNow(); - _ts = _ts - (_wasts !== undefined ? _wasts : _ts); - _ts = (_ts > _framerate) ? _framerate : _ts; - director.take(this, _ts); - _wasts = _ts; - this.trigger(true); - } else { - _wasts = undefined; - this.cancel(); - this.completed && this.completed(); - } -} /** @@ -276,7 +267,7 @@ function create(props) { for (var i = 0; i < anims.length; i++) { this.addAnimation(anims[i], anims[i].duration || 0); - delete anims[i].duration; + //delete anims[i].duration; } } @@ -296,6 +287,6 @@ function createFromScene(source) { for (i = 0; i < l; i++) { anim = utils.mixin({}, source.getAnimation(i)); - this.addAnimation(anim.animate, anim.span); + this.addAnimation(anim.animate, anim.animate.duration); } } \ No newline at end of file diff --git a/src/AnimationSupport/Director.js b/src/AnimationSupport/Director.js index 096f8c95b..cb9945c9d 100644 --- a/src/AnimationSupport/Director.js +++ b/src/AnimationSupport/Director.js @@ -77,6 +77,24 @@ module.exports = { tween.step(actor, pose, 1, dur); } }, + + /** + * cut is the method which triggers end of animation of the actor. + * @param {Object} pose Animation poses + * @param {@link module:enyo/Component~Component} actor Component on which the animation should be performed + * @param {Number} since Elapsed time since the animation of this pose has started + * @param {Number} dur Total duration of this pose + */ + cut: function (scene, actor) { + if (actor && scene) { + scene.timeline = scene.span; + scene.speed = 0; + if (scene.active) { + scene.active = false; + tween.halt(actor); + } + } + }, /** * Casts an actor or all the actors in the array to the given scene. diff --git a/src/AnimationSupport/Editor.js b/src/AnimationSupport/Editor.js index 9c243295d..3ecfdbe34 100644 --- a/src/AnimationSupport/Editor.js +++ b/src/AnimationSupport/Editor.js @@ -28,14 +28,18 @@ module.exports = { /** * @private */ - cache: function(actor) { + seekInterval:0, + /** + * @private + */ + cache: function(actor) { actor = actor || this; if(actor.speed === 0){ actor.speed = actor._cachedValue; } this.animating = true; }, - + /** * Starts the animation of the actor given in argument. * If actor is not provided, animation of all the components linked to the {@link module:enyo/AnimationSupport/Scene} will be started. @@ -49,6 +53,7 @@ module.exports = { actor.timeline = 0; } this.trigger(); + actor._cachedValue = actor.speed; this.animating = true; }, @@ -85,6 +90,7 @@ module.exports = { reverse: function (actor) { this.cache(actor); actor = actor || this; + actor._cachedValue = actor.speed; actor.speed *= -1; }, @@ -129,7 +135,7 @@ module.exports = { // actor = actor || this; // actor.speed *= mul; // }, - + /** * Stops the animation of the actor given in argument. * If actor is not provided, animation of all the components linked to the {@link module:enyo/AnimationSupport/Scene} will be stopped. @@ -144,7 +150,7 @@ module.exports = { // this.animating = false; // this.cancel(); }, - + /** * Seeks the animation of the actor to the position provided in timeline * The value of timeline should be between 0 to duration of the animation. @@ -154,11 +160,14 @@ module.exports = { */ seek: function(timeline, actor) { actor = actor || this; - if (this.animating !== true) { + if (timeline>0 ) { this.play(actor); - this.pause(actor); + //this.pause(actor); + }else{ + this.reverse(actor); } - actor.timeline = timeline; + this.seekInterval = actor.timeline + timeline; + //actor.timeline = timeline; }, /** @@ -170,9 +179,12 @@ module.exports = { */ rolePlay: function (t, actor) { actor = actor || this; - if (actor.timeline === undefined || actor.timeline < 0) + if (actor.timeline === undefined || actor.timeline < 0) actor.timeline = 0; - + if(this.seekInterval !== 0) { + if((this.seekInterval-actor.timeline)*actor.speed <= 0) + actor.speed =0; + } if(actor.delay > 0) { actor.delay -= _rolePlay(t, actor.speed); } if(actor.startTimeline > 0 && actor.timeline == 0){ diff --git a/src/AnimationSupport/Frame.js b/src/AnimationSupport/Frame.js index 57a3a2bb5..d8149aaec 100644 --- a/src/AnimationSupport/Frame.js +++ b/src/AnimationSupport/Frame.js @@ -178,6 +178,84 @@ var frame = module.exports = { return true; }, + /** + * Decompose transformation matrix2d from matrix3d. + * @public + * @param {Number[]} matrix Matrix3d + * @param {Object} ret To store various transformation properties like translate, angle and matrix. + * @return {Boolean} ret To store various transformation properties like translate, angle and matrix. + */ + decompose2DMatrix: function (m, ret) { + var row0x = m[0], + row0y = m[1], + row1x = m[4], + row1y = m[5], + scale = [], + matrix = [], + det, angle, sn, cs, + m11, m12, m21, m22; + + ret = ret || {}; + scale = [ + Math.sqrt(row0x * row0x + row0y * row0y), + Math.sqrt(row1x * row1x + row1y * row1y) + ]; + + // If determinant is negative, one axis was flipped. + det = row0x * row1y - row0y * row1x; + if (det < 0) + // Flip axis with minimum unit vector dot product. + if (row0x < row1y) + scale[0] = -scale[0]; + else + scale[1] = -scale[1]; + + // Renormalize matrix to remove scale. + if (scale[0]) { + row0x *= 1 / scale[0]; + row0y *= 1 / scale[0]; + } + + if (scale[1]) { + row1x *= 1 / scale[1]; + row1y *= 1 / scale[1]; + } + ret.scale = scale; + + + // Compute rotation and renormalize matrix. + angle = Math.atan2(row0y, row0x); + + if (angle) { + sn = -row0y; + cs = row0x; + m11 = row0x; + m12 = row0y; + m21 = row1x; + m22 = row1y; + row0x = cs * m11 + sn * m21; + row0y = cs * m12 + sn * m22; + row1x = -sn * m11 + cs * m21; + row1y = -sn * m12 + cs * m22; + } + + // Rotate(-angle) = [cos(angle), sin(angle), -sin(angle), cos(angle)] + // = [row0x, -row0y, row0y, row0x] + // Thanks to the normalization above. + matrix[0] = row0x; + matrix[1] = row0y; + matrix[2] = row1x; + matrix[3] = row1y; + matrix[4] = m[12]; + matrix[5] = m[13]; + ret.matrix2D = matrix; + + // Convert into degrees because our rotation functions expect it. + ret.angle = angle * 180 / Math.PI; + + return ret; + }, + /** * Clones an array based on offset value. * @public @@ -216,7 +294,7 @@ var frame = module.exports = { * @param {Number[]} v Matrix(2d) * @return {Number[]} Matrix3d */ - parseMatrix: function (v) { + parseMatrix3D: function (v) { var m = Matrix.identity(); v = v.replace(/^\w*\(/, '').replace(')', ''); v = this.parseValue(v); @@ -260,7 +338,7 @@ var frame = module.exports = { if (m === undefined || m === null || m == "none") { return ""; } - return this.parseMatrix(m); + return this.parseMatrix3D(m); }, /** @@ -288,9 +366,9 @@ var frame = module.exports = { /** * Applies style property to DOM element. * @public - * @param {enyo.Component} actor Component to be animated. - * @param {String} prop CSS property to be applied. - * @param {Number} val Value of the property applied. + * @param {enyo.Component} actor Component to be animated. + * @param {String} prop CSS property to be applied. + * @param {Number} val Value of the property applied. */ setProperty: function (actor, prop, val) { if (COLOR[prop]) { @@ -311,8 +389,8 @@ var frame = module.exports = { /** * Applies transform property to DOM element. * @public - * @param {enyo.Component} actor Component to be animated. - * @param {Number[]} matrix Matrix3d + * @param {enyo.Component} actor Component to be animated. + * @param {Number[]} matrix Matrix3d */ setTransformProperty: function (actor, matrix) { var mat = Matrix.toString(matrix); @@ -322,10 +400,10 @@ var frame = module.exports = { element.style.msTransform = mat; element.style.OTransform = mat;*/ actor.addStyles('transform:' + mat + ';' - + 'webkitTransform:' + mat + ';' - + 'MozTransform:' + mat + ';' - + 'msTransform' + mat + ';' - + 'OTransform' + mat + ';'); + + 'webkitTransform:' + mat + ';' + + 'MozTransform:' + mat + ';' + + 'msTransform' + mat + ';' + + 'OTransform' + mat + ';'); }, /** diff --git a/src/AnimationSupport/Matrix.js b/src/AnimationSupport/Matrix.js index 9befb02c4..39b844c98 100644 --- a/src/AnimationSupport/Matrix.js +++ b/src/AnimationSupport/Matrix.js @@ -15,6 +15,15 @@ module.exports = { return [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]; }, + /** + * To create Identity Matrix3d (4X4 order). + * @public + * @return {Number[]} Identity Matrix3d + */ + identity2D: function() { + return [1,0,0,0,1,0,0,0,1]; + }, + /** * To translate in any dimension based on co-ordinates. * @public @@ -269,11 +278,11 @@ module.exports = { * @return {String} Matrix3d String */ toString: function (m) { - var ms = 'matrix3d('; - for (var i = 0; i < 15; i++) { + var ms = m.length > 10 ? 'matrix3d(' : 'matrix('; + for (var i = 0; i < m.length -1; i++) { ms += (m[i] < 0.000001 && m[i] > -0.000001) ? '0,' : m[i] + ','; } - ms += m[15] + ')'; + ms += m[m.length -1] + ')'; return ms; } }; \ No newline at end of file diff --git a/src/AnimationSupport/Scene.js b/src/AnimationSupport/Scene.js index 83cce1ade..e785935e0 100644 --- a/src/AnimationSupport/Scene.js +++ b/src/AnimationSupport/Scene.js @@ -10,7 +10,7 @@ var * @module enyo/AnimationSupport/Scene */ var Scene = module.exports = function(props) { - var scene = actor(props); + var scene = actor(props.animation); utils.mixin(scene, SceneAction); utils.mixin(scene, props); return scene; @@ -37,20 +37,16 @@ var SceneAction = { } } + //TODO: cache all DOM updates till the end for (i = 0; (role = this.rolePlays[i]); i++) { actor = role.actor; - if (actor.active) { + if (actor.active && actor.timeline < role.dur) { actor.speed = this.speed; pose = actor.action(ts, pose); } } return pose; - }, - - updateSpan: function(span) { - this.span = this.totalSpan * span / this.threshold; } - }; @@ -93,6 +89,7 @@ Scene.link = function(actors, scene) { for (var act, i = 0; (act = acts[i]); i++) { if (scene.isScene) { + act.scene = act.scene || actor(scene, act); actorScene = act.scene.isScene ? act.scene : actor(act.scene, act); scene.span += actorScene.span; scene.rolePlays.push({actor: actorScene, span: scene.span, dur: actorScene.span}); diff --git a/src/AnimationSupport/Tween.js b/src/AnimationSupport/Tween.js index d4319771f..46e4ec617 100644 --- a/src/AnimationSupport/Tween.js +++ b/src/AnimationSupport/Tween.js @@ -40,8 +40,9 @@ module.exports = { */ step: function(actor, pose, t, d) { if (!(actor && pose && pose.animate)) return; - if (t<0) t=0; - if (t>1) t=1; + t = t < 0 ? 0 : t; + t = t > 1 ? 1 : t; + var k; node = actor.hasNode(); state = actor.currentState = actor.currentState || pose.currentState || {}; @@ -105,7 +106,14 @@ module.exports = { ); frame.accelerate(actor, matrix); state.matrix = matrix; - pose.currentState = state; + + actor.currentState = pose.currentState = state; + }, + + halt: function (actor, pose) { + var matrix = actor.currentState && actor.currentState.matrix; + pose = frame.decompose2DMatrix(matrix, pose); + frame.accelerate(actor, pose.matrix2D); }, /** From 5b2d7f0919fb05e557f581c3c1b04f536d08bcac Mon Sep 17 00:00:00 2001 From: System Administrator Date: Mon, 7 Mar 2016 00:45:40 +0530 Subject: [PATCH 155/210] Added multiple roleplay changes --- src/AnimationSupport/Actor.js | 103 +++++++++++++++------------- src/AnimationSupport/Director.js | 1 - src/AnimationSupport/Editor.js | 33 +++++---- src/AnimationSupport/Scene.js | 114 +++++++++++++++++-------------- 4 files changed, 138 insertions(+), 113 deletions(-) diff --git a/src/AnimationSupport/Actor.js b/src/AnimationSupport/Actor.js index dacc95cda..ac0fe465d 100644 --- a/src/AnimationSupport/Actor.js +++ b/src/AnimationSupport/Actor.js @@ -8,7 +8,7 @@ var _ts, _wasts, _framerate = 16.6; /** * Function to construct all the scenes instantiated from the Scene - * @memberOf module:enyo/AnimationSupport/Scene + * @memberOf module:enyo/AnimationSupport/Actor * @private * @param {number} id - id of the scene generated when created * @return {object} Constructed instance @@ -32,7 +32,7 @@ Actor.makeScene = function(actor) { /** * Holds refereneces of the all animations added to this scene. - * @memberOf module:enyo/AnimationSupport/Scene + * @memberOf module:enyo/AnimationSupport/Actor * @private * @type {Array} */ @@ -40,35 +40,7 @@ Actor.makeScene = function(actor) { _actor = actor, - /** - * Returns animation pose index for a particular - * instance of time from the list of - * animations added to the scene. - * @param {number} span - Time span from the animation timeline - * @return {number} - index of the animation - * @memberOf module:enyo/AnimationSupport/Scene - * @private - */ - animateAtTime = function(span) { - var startIndex = 0, - stopIndex = _poses.length - 1, - middle = Math.floor((stopIndex + startIndex) / 2); - - if (span === 0) { - return startIndex; - } - - while (_poses[middle].span != span && startIndex < stopIndex) { - if (span < _poses[middle].span) { - stopIndex = middle; - } else if (span > _poses[middle].span) { - startIndex = middle + 1; - } - - middle = Math.floor((stopIndex + startIndex) / 2); - } - return (_poses[middle].span != span) ? startIndex : middle; - }, + action = function(ts, pose) { var past, index, tm, @@ -78,12 +50,13 @@ Actor.makeScene = function(actor) { tm = this.rolePlay(ts); if (isNaN(tm) || tm < 0) return pose; else if (tm <= dur) { - index = animateAtTime(tm); + index = Actor.animateAtTime(_poses, tm); pose = this.getAnimation(index); past = index ? this.getAnimation(index - 1).span : 0; director.action(pose, _actor, tm - past, pose.span - past); this.step && this.step(_actor); } else { + this.timeline = this.span; director.cut(this, _actor); this.completed && this.completed(_actor); } @@ -91,9 +64,13 @@ Actor.makeScene = function(actor) { return pose; }, + cut = function () { + director.cut(this, _actor); + }, + /** * Function used to loop in all the animations in a scene - * @memberOf module:enyo/AnimationSupport/Scene + * @memberOf module:enyo/AnimationSupport/Actor * @private */ loop = function() { @@ -122,7 +99,7 @@ Actor.makeScene = function(actor) { * 'true' - the scene is asked for animation(doesn't mean animation is happening) * 'false' - the scene is not active(has completed or its actors are not visible) * @type {Boolean} - * @memberOf module:enyo/AnimationSupport/Scene + * @memberOf module:enyo/AnimationSupport/Actor * @public */ animating: false, @@ -132,7 +109,7 @@ Actor.makeScene = function(actor) { * 'true' - the scene actors are ready for action * 'false' - some or all actors are not ready * @type {Boolean} - * @memberOf module:enyo/AnimationSupport/Scene + * @memberOf module:enyo/AnimationSupport/Actor * @public */ active: false, @@ -140,7 +117,7 @@ Actor.makeScene = function(actor) { /** * Holds refereneces of complete time span for this scene. * @type {Number} - * @memberOf module:enyo/AnimationSupport/Scene + * @memberOf module:enyo/AnimationSupport/Actor * @public */ span: 0, @@ -151,14 +128,16 @@ Actor.makeScene = function(actor) { * @param {number} ts - timespan * @param {Object} pose - pose from the animation list * @return {Object} - pose - * @memberOf module:enyo/AnimationSupport/Scene + * @memberOf module:enyo/AnimationSupport/Actor * @private */ action: action, + cut: cut, + /** * Cancel the animation - * @memberOf module:enyo/AnimationSupport/Scene + * @memberOf module:enyo/AnimationSupport/Actor * @public */ cancel: function() { @@ -168,7 +147,7 @@ Actor.makeScene = function(actor) { /** * Triggers the Request Animation Frame * @param {boolean} force - A boolean value for letting the rAF start. - * @memberOf module:enyo/AnimationSupport/Scene + * @memberOf module:enyo/AnimationSupport/Actor * @public */ trigger: function(force) { @@ -179,7 +158,7 @@ Actor.makeScene = function(actor) { /** * Adds new animation on already existing animation for this character. - * @memberOf module:enyo/AnimationSupport/Scene + * @memberOf module:enyo/AnimationSupport/Actor * @public */ addAnimation: function(newProp, span) { @@ -200,7 +179,7 @@ Actor.makeScene = function(actor) { /** * Function which returns the length of the poses. - * @memberOf module:enyo/AnimationSupport/Scene + * @memberOf module:enyo/AnimationSupport/Actor * @public * @return {number} - length of the poses */ @@ -210,7 +189,7 @@ Actor.makeScene = function(actor) { /** * Clears/removes the animation - * @memberOf module:enyo/AnimationSupport/Scene + * @memberOf module:enyo/AnimationSupport/Actor * @public */ clearAnimation: function() { @@ -224,7 +203,7 @@ Actor.makeScene = function(actor) { * animations added to this scene. * @param {number} index - animation's index from the list of animations * @return {Object} pose of the animation based on the index in the list - * @memberOf module:enyo/AnimationSupport/Scene + * @memberOf module:enyo/AnimationSupport/Actor * @public */ getAnimation: function(index) { @@ -235,20 +214,50 @@ Actor.makeScene = function(actor) { //TODO: Move these events to Event Delegator /** * Event to identify when the scene has done animating. - * @memberOf module:enyo/AnimationSupport/Scene + * @memberOf module:enyo/AnimationSupport/Actor * @public */ completed: function() {}, /** * Event to identify when the scene has done a step(rAF updatation of time) in the animation. - * @memberOf module:enyo/AnimationSupport/Scene + * @memberOf module:enyo/AnimationSupport/Actor * @public */ step: function() {} }; }; +/** + * Returns animation pose index for a particular + * instance of time from the list of + * animations added to the scene. + * @param {number} span - Time span from the animation timeline + * @return {number} - index of the animation + * @memberOf module:enyo/AnimationSupport/Actor + * @private + */ +Actor.animateAtTime = function(anims, span) { + var startIndex = 0, + stopIndex = anims.length - 1, + middle = Math.floor((stopIndex + startIndex) / 2); + + if (span === 0) { + return startIndex; + } + + while (anims[middle].span != span && startIndex < stopIndex) { + if (span < anims[middle].span) { + stopIndex = middle; + } else if (span > anims[middle].span) { + startIndex = middle + 1; + } + + middle = Math.floor((stopIndex + startIndex) / 2); + } + return (anims[middle].span != span) ? startIndex : middle; +}; + @@ -256,7 +265,7 @@ Actor.makeScene = function(actor) { /** * Creates a empty instance of scene. * Can be used for runtime creation of animations - * @memberOf module:enyo/AnimationSupport/Scene + * @memberOf module:enyo/AnimationSupport/Actor * @public * @return {Object} An instance of the constructor */ @@ -275,7 +284,7 @@ function create(props) { /** * Creates a empty instance of scene. * Can be used for runtime creation of animations - * @memberOf module:enyo/AnimationSupport/Scene + * @memberOf module:enyo/AnimationSupport/Actor * @public * @return {Object} An instance of the constructor */ diff --git a/src/AnimationSupport/Director.js b/src/AnimationSupport/Director.js index cb9945c9d..8557d0c34 100644 --- a/src/AnimationSupport/Director.js +++ b/src/AnimationSupport/Director.js @@ -87,7 +87,6 @@ module.exports = { */ cut: function (scene, actor) { if (actor && scene) { - scene.timeline = scene.span; scene.speed = 0; if (scene.active) { scene.active = false; diff --git a/src/AnimationSupport/Editor.js b/src/AnimationSupport/Editor.js index 3ecfdbe34..3e9aa7f3b 100644 --- a/src/AnimationSupport/Editor.js +++ b/src/AnimationSupport/Editor.js @@ -158,16 +158,21 @@ module.exports = { * @param [Component]{@link module:enyo/Component~Component} actor The component to be animated * @public */ - seek: function(timeline, actor) { + seek: function(seek, actor) { actor = actor || this; - if (timeline>0 ) { - this.play(actor); - //this.pause(actor); + actor.timeline = seek; + }, + + seekAnimate: function(seek, actor) { + actor = actor || this; + if (seek >= 0 ) { + if (!this.animating) + this.play(actor); + actor.speed = 1; }else{ - this.reverse(actor); + actor.speed = -1; } - this.seekInterval = actor.timeline + timeline; - //actor.timeline = timeline; + actor.seekInterval = actor.timeline + seek; }, /** @@ -181,17 +186,21 @@ module.exports = { actor = actor || this; if (actor.timeline === undefined || actor.timeline < 0) actor.timeline = 0; - if(this.seekInterval !== 0) { - if((this.seekInterval-actor.timeline)*actor.speed <= 0) - actor.speed =0; - } + if(actor.delay > 0) { actor.delay -= _rolePlay(t, actor.speed); - } if(actor.startTimeline > 0 && actor.timeline == 0){ + } + if(actor.startTimeline > 0 && actor.timeline == 0){ actor.timeline = actor.startTimeline; } else { actor.timeline += _rolePlay(t, actor.speed); } + if(actor.seekInterval !== 0) { + if((actor.seekInterval-actor.timeline)*actor.speed < 0) { + actor.seekInterval = 0; + actor.speed = 0; + } + } return actor.timeline; } }; diff --git a/src/AnimationSupport/Scene.js b/src/AnimationSupport/Scene.js index e785935e0..a26da7f65 100644 --- a/src/AnimationSupport/Scene.js +++ b/src/AnimationSupport/Scene.js @@ -1,5 +1,5 @@ var - actor = require('./Actor'), + Actor = require('./Actor'), director = require('./Director'), utils = require('../utils'); @@ -10,69 +10,72 @@ var * @module enyo/AnimationSupport/Scene */ var Scene = module.exports = function(props) { - var scene = actor(props.animation); + var scene = Actor(props.animation); utils.mixin(scene, SceneAction); utils.mixin(scene, props); return scene; }; var SceneAction = { + + /** + * The boundary of scene within which the scene actors will be animating. + * @memberOf module:enyo/AnimationSupport/Scene + * @public + * @type {number} + */ threshold: 0, + /** + * The actors which are added to this scene. Each actor is responsible for its own role + * within a scene. + * @memberOf module:enyo/AnimationSupport/Scene + * @public + * @type {Array} + */ rolePlays: [], + /** + * This function initiates action on the animation + * from the list of animations for a given scene. + * @param {number} ts - timespan + * @param {Object} pose - pose from the animation list + * @return {Object} - pose + * @memberOf module:enyo/AnimationSupport/Scene + * @private + */ action: function(ts, pose) { var i, role, actor, - tm = this.rolePlay(ts), - thres = this.threshold || this.span; + s, e, + sts = 0, + tm = this.timeline, + th = this.threshold || this.span; - role = this.rolePlays[Math.floor(tm/thres)]; - if (role && thres < role.dur) { - role.actor.active = true; - } else { - for (i = 0; (role = this.rolePlays[i]); i++) { - if ((tm + thres) >= role.span ) { - role.actor.active = true; - } - } - } + s = Actor.animateAtTime(this.rolePlays, tm); + e = Actor.animateAtTime(this.rolePlays, tm + th); - //TODO: cache all DOM updates till the end - for (i = 0; (role = this.rolePlays[i]); i++) { + for (i = 0; + (role = this.rolePlays[i]); i++) { actor = role.actor; - if (actor.active && actor.timeline < role.dur) { + actor.active = true; + if (i < s) { + actor.timeline = role.dur; + pose = actor.action(0, pose); + actor.cut(); + } else if (i >= s && i < e) { + sts += ts; actor.speed = this.speed; pose = actor.action(ts, pose); + } else { + pose = actor.action(0, pose); + actor.cut(); } } + tm = this.rolePlay(sts); return pose; } }; - - - // if (thres === role.dur) { - // actor.speed = this.speed; - // pose = actor.action(ts, pose); - // tm = this.rolePlay(ts); - // console.log(tm + " same duration:"+ role.span); - // break; - // } else if (thres > role.dur) { - // thres -= role.dur; - // actor.speed = this.speed; - // tm = this.rolePlay(ts); - // pose = actor.action(ts, pose); - // console.log(tm + " greater duration"+ role.span); - // } - // else { - // actor.speed = this.speed; - // tm = this.rolePlay(ts); - // // actor.timeline = tm == 0 ? 0 : thres; - // pose = actor.action(ts, pose); - // break; - // } - - /** * Connects an actor/s to a scene. * All the actors should be added before initiating animation otherwise actors will animate for remaining time span @@ -82,19 +85,25 @@ var SceneAction = { * @param {Object} scene - The instance of the Scene we've created in the application */ Scene.link = function(actors, scene) { - if (!scene && !actors ) return; + if (!scene && !actors) return; - var actorScene, + var actorScene, span = 0, acts = utils.isArray(actors) ? actors : [actors]; - for (var act, i = 0; (act = acts[i]); i++) { + for (var act, i = 0; + (act = acts[i]); i++) { if (scene.isScene) { - act.scene = act.scene || actor(scene, act); - actorScene = act.scene.isScene ? act.scene : actor(act.scene, act); - scene.span += actorScene.span; - scene.rolePlays.push({actor: actorScene, span: scene.span, dur: actorScene.span}); + act.scene = act.scene || Actor(scene, act); + actorScene = act.scene.isScene ? act.scene : Actor(act.scene, act); + span += actorScene.span; + scene.rolePlays.push({ + actor: actorScene, + span: span, + dur: actorScene.span + }); + scene.span = span; } else { - actorScene = actor(scene, act); + actorScene = Actor(scene, act); acts[i].scene = actorScene; } } @@ -111,11 +120,10 @@ Scene.link = function(actors, scene) { * @param {Object} scene - The instance of the Scene we've created in the application */ Scene.delink = function(actors, scene) { - var parent, acts = utils.isArray(actors) ? actors : [actors], actor; + var parent, acts = utils.isArray(actors) ? actors : [actors], + actor; - if (typeof scene == 'function') { - parent = scene; - } + if (typeof scene == 'function') parent = scene; for (var i = 0; i < acts.length; i++) { director.reject(parent, actor.scene); actor.scene = undefined; From 8b9c7ae0854bbd40585c1e06d725a650efa3e042 Mon Sep 17 00:00:00 2001 From: Aaron Tam Date: Mon, 7 Mar 2016 17:32:42 -0800 Subject: [PATCH 156/210] ENYO-3174: Deprecate unstable APIs. Enyo-DCO-1.1-Signed-off-by: Aaron Tam --- src/RichText/RichText.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/RichText/RichText.js b/src/RichText/RichText.js index 023382ee9..12f8ff13f 100644 --- a/src/RichText/RichText.js +++ b/src/RichText/RichText.js @@ -277,6 +277,7 @@ var RichText = module.exports = kind( * @param {module:enyo/RichText~ModifyType} type - The type of change to apply. * @param {module:enyo/RichText~ModifyDirection} dir - The direction in which to apply the change. * @param {module:enyo/RichText~ModifyAmount} amount - The granularity of the change. + * @deprecated since version 2.7 * @public */ modifySelection: function (type, dir, amount) { @@ -291,6 +292,7 @@ var RichText = module.exports = kind( * * @param {module:enyo/RichText~ModifyDirection} dir - The direction in which to apply the change. * @param {module:enyo/RichText~ModifyAmount} amount - The granularity of the change. + * @deprecated since version 2.7 * @public */ moveCursor: function (dir, amount) { @@ -300,6 +302,7 @@ var RichText = module.exports = kind( /** * Moves the cursor to end of text field. * + * @deprecated since version 2.7 * @public */ moveCursorToEnd: function () { @@ -309,6 +312,7 @@ var RichText = module.exports = kind( /** * Moves the cursor to start of text field. * + * @deprecated since version 2.7 * @public */ moveCursorToStart: function () { From 30a9bdac41abc331d75fdd6d8fa9e092eb73801e Mon Sep 17 00:00:00 2001 From: Blake Stephens Date: Mon, 7 Mar 2016 13:23:52 -0800 Subject: [PATCH 157/210] ENYO-3175: Added support for Mozilla based browsers Enyo-DCO-1.1-Signed-off-by: Blake Stephens Slightly simpler code for transform Enyo-DCO-1.1-Signed-off-by: Blake Stephens --- src/SpriteAnimation/SpriteAnimation.js | 30 ++++++++++++++++++++------ 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/src/SpriteAnimation/SpriteAnimation.js b/src/SpriteAnimation/SpriteAnimation.js index 82fea364d..e23bb70a0 100644 --- a/src/SpriteAnimation/SpriteAnimation.js +++ b/src/SpriteAnimation/SpriteAnimation.js @@ -295,7 +295,7 @@ module.exports = kind( */ updateKeyframes: function () { if (this.useCssAnimation) { - this.$.spriteImage.set('stylesheetContent', this._generateKeyframes()); + this.$.spriteImage.set('stylesheetContent', this._generateKeyframes('-webkit-') + this._generateKeyframes('-moz-') + this._generateKeyframes()); } else { this._generatePositionList(); } @@ -349,6 +349,7 @@ module.exports = kind( start: function () { if (this.useCssAnimation) { this.$.spriteImage.applyStyle('-webkit-animation-name', this.get('animationName')); + this.$.spriteImage.applyStyle('-moz-animation-name', this.get('animationName')); this.$.spriteImage.applyStyle('animation-name', this.get('animationName')); } else { this._intervalHandle = scope.setInterval(this.bindSafely(this._nextFrame, this), this.get('frameLength')); @@ -363,6 +364,7 @@ module.exports = kind( */ stop: function () { this.$.spriteImage.applyStyle('-webkit-animation-name', null); + this.$.spriteImage.applyStyle('-moz-animation-name', null); this.$.spriteImage.applyStyle('animation-name', null); scope.clearInterval(this._intervalHandle); this._loopCount = 0; @@ -373,6 +375,7 @@ module.exports = kind( */ stopAtEndChanged: function() { this.$.spriteImage.applyStyle('-webkit-animation-fill-mode', this.get('stopAtEnd') ? 'forwards' : null); + this.$.spriteImage.applyStyle('-moz-animation-fill-mode', this.get('stopAtEnd') ? 'forwards' : null); this.$.spriteImage.applyStyle('animation-fill-mode', this.get('stopAtEnd') ? 'forwards' : null); }, @@ -409,6 +412,7 @@ module.exports = kind( iterations = parseInt(this.get('iterationCount'), 10) || null; // strings like "infinite" will be converted to null this.$.spriteImage.applyStyle('-webkit-transform', 'translate3d('+ x +'px, '+ y +'px, 0)'); + this.$.spriteImage.applyStyle('-moz-transform', 'translate3d('+ x +'px, '+ y +'px, 0)'); this.$.spriteImage.applyStyle('transform', 'translate3d('+ x +'px, '+ y +'px, 0)'); if (fi + 1 >= this._positionList.length - 1) { @@ -448,8 +452,10 @@ module.exports = kind( iterations = (iterations && iterations !== 0) ? iterations : 'infinite'; this.$.spriteImage.applyStyle('-webkit-animation-timing-function', 'steps(' + steps + ', start)'); + this.$.spriteImage.applyStyle('-moz-animation-timing-function', 'steps(' + steps + ', start)'); this.$.spriteImage.applyStyle('animation-timing-function', 'steps(' + steps + ', start)'); this.$.spriteImage.applyStyle('-webkit-animation-iteration-count', iterations); + this.$.spriteImage.applyStyle('-moz-animation-iteration-count', iterations); this.$.spriteImage.applyStyle('animation-iteration-count', iterations); this.durationChanged(); }, @@ -457,7 +463,8 @@ module.exports = kind( /** * @private */ - _generateKeyframes: function () { + _generateKeyframes: function (prefix) { + prefix = prefix || ''; var o, width = this.get('width'), height = this.get('height'), @@ -467,7 +474,7 @@ module.exports = kind( kfStr = '', outer = (horiz ? rows : cols); - kfStr += '@-webkit-keyframes '+ this.get('animationName') +' {\n'; + kfStr += '@'+ prefix +'keyframes '+ this.get('animationName') +' {\n'; for (o = 0; o < outer; o++) { kfStr += this._generateKeyframe( // percent @@ -475,7 +482,8 @@ module.exports = kind( // startX horiz ? width : (-width * o), // startY - horiz ? (-height * o) : height + horiz ? (-height * o) : height, + prefix ); kfStr += this._generateKeyframe( // percent @@ -483,7 +491,8 @@ module.exports = kind( // endX horiz ? ((-width * cols) + width) : (-width * o), // endY - horiz ? (-height * o) : ((-height * rows) + height) + horiz ? (-height * o) : ((-height * rows) + height), + prefix ); } kfStr += '}\n'; @@ -493,8 +502,15 @@ module.exports = kind( /** * @private */ - _generateKeyframe: function (percent, x, y) { - return (Math.ceil(percent*1000000) / 10000) +'% { -webkit-transform: translate3d('+ x +'px, '+ y +'px, 0); transform: translate3d('+ x +'px, '+ y +'px, 0); }\n'; + _generateKeyframe: function (percent, x, y, prefix) { + var outStr = (Math.ceil(percent*1000000) / 10000) +'% { ', + transform = 'transform: translate3d('+ x +'px, '+ y +'px, 0); '; + if (prefix) { + // add the prefix and the standard + outStr+= prefix + transform; + } + outStr+= transform +'}\n'; + return outStr; }, _generatePositionList: function () { From 048fac401f1ab095a2b7fafeb21d537384cea442 Mon Sep 17 00:00:00 2001 From: Aaron Tam Date: Tue, 8 Mar 2016 10:04:30 -0800 Subject: [PATCH 158/210] ENYO-3164: Make Control be the default kind. Enyo-DCO-1.1-Signed-off-by: Aaron Tam --- src/ViewController.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ViewController.js b/src/ViewController.js index fecef85ba..c5eb5fba4 100644 --- a/src/ViewController.js +++ b/src/ViewController.js @@ -5,6 +5,9 @@ require('enyo'); * @module enyo/ViewController */ +// needed so that the default kind is Control instead of Component, if it isn't required elsewhere +require('./Control'); + var kind = require('./kind'), utils = require('./utils'); From 9070d895be2e1b32a42d514dcf05d3b7453ed0d3 Mon Sep 17 00:00:00 2001 From: Aaron Tam Date: Tue, 8 Mar 2016 11:37:44 -0800 Subject: [PATCH 159/210] ENYO-3184: Deprecate srcElement property for generated media events. Enyo-DCO-1.1-Signed-off-by: Aaron Tam --- src/Media.js | 85 ++++++++++++++++++++++++++-------------------------- src/Video.js | 71 ++++++++++++++++++++++--------------------- 2 files changed, 77 insertions(+), 79 deletions(-) diff --git a/src/Media.js b/src/Media.js index 745a63b08..9bf329fc5 100644 --- a/src/Media.js +++ b/src/Media.js @@ -25,7 +25,7 @@ var * propagated the {@glossary event}. * @property {Object} event - An [object]{@glossary Object} containing event information. * @public -*/ +*/ /** * Fires when element can resume playback of the [media]{@link module:enyo/Media~Media} data, but may @@ -45,7 +45,7 @@ var * * @event module:enyo/Media~Media#onCanPlayThrough * @type {Object} -* @property {Object} sender - The [component]{@link module:enyo/Component~Component} that most recently +* @property {Object} sender - The [component]{@link module:enyo/Component~Component} that most recently * propagated the {@glossary event}. * @property {Object} event - An [object]{@glossary Object} containing event information. * @public @@ -357,17 +357,17 @@ module.exports = kind( * @private */ kind: Control, - + /** * @private */ - published: + published: /** @lends module:enyo/Media~Media.prototype */ { - + /** * URL of the [media]{@link module:enyo/Media~Media} file to play; may be relative to the * application HTML file. - * + * * @type {String} * @default '' * @public @@ -376,7 +376,7 @@ module.exports = kind( /** * If `true`, [media]{@link module:enyo/Media~Media} will automatically start playback when loaded. - * + * * @type {Boolean} * @default false * @public @@ -385,7 +385,7 @@ module.exports = kind( /** * The desired speed at which the [media]{@link module:enyo/Media~Media} resource is to play. - * + * * @type {Number} * @default 1.0 * @public @@ -394,7 +394,7 @@ module.exports = kind( /** * The amount of time, in seconds, to jump forward or backward. - * + * * @type {Number} * @default 30 * @public @@ -403,7 +403,7 @@ module.exports = kind( /** * The effective playback rate. - * + * * @type {Number} * @default 1.0 * @public @@ -418,7 +418,7 @@ module.exports = kind( * slowRewind: ['-1/2', '-1'] * } * ``` - * + * * @type {Object} * @default { * fastForward: ['2', '4', '8', '16'], @@ -438,7 +438,7 @@ module.exports = kind( /** * Indicates how data should be preloaded, reflecting the `preload` HTML attribute. * Will be one of `'none'` (the default), `'metadata'`, or `'auto'`. - * + * * @type {String} * @default 'none' * @public @@ -447,7 +447,7 @@ module.exports = kind( /** * If `true`, [media]{@link module:enyo/Media~Media} playback restarts from beginning when finished. - * + * * @type {Boolean} * @default false * @public @@ -456,7 +456,7 @@ module.exports = kind( /** * If `true`, [media]{@link module:enyo/Media~Media} playback is muted. - * + * * @type {Boolean} * @default false * @public @@ -465,7 +465,7 @@ module.exports = kind( /** * If `true`, default [media]{@link module:enyo/Media~Media} controls are shown. - * + * * @type {Boolean} * @default false * @public @@ -474,7 +474,7 @@ module.exports = kind( /** * Current playback volume, as a number in the range from 0.0 to 1.0. - * + * * @type {Number} * @default 1.0 * @public @@ -515,7 +515,7 @@ module.exports = kind( onJumpBackward: '', onStart: '' }, - + /** * @private */ @@ -732,7 +732,7 @@ module.exports = kind( _canPlayThrough: function () { this.doCanPlayThrough(); }, - + /** * Called when the [duration]{@link module:enyo/Media~Media#duration} attribute has been changed. * @@ -766,7 +766,7 @@ module.exports = kind( /** * Called when an error occurs while fetching media data. - * + * * @private */ _error: function () { @@ -784,7 +784,7 @@ module.exports = kind( }, /** * Called when the media duration and dimensions of the media resource/text tracks are ready. - * + * * @private */ _loadedMetaData: function () { @@ -856,7 +856,6 @@ module.exports = kind( this.doStart(); } return { - srcElement: node, duration: node.duration, currentTime: node.currentTime, playbackRate: this.getPlaybackRate() @@ -876,7 +875,7 @@ module.exports = kind( return (pbArray.length > 1) ? parseInt(pbArray[0], 10) / parseInt(pbArray[1], 10) : parseInt(rate, 10); }, /** - * Called when either [defaultPlaybackRate]{@link module:enyo/Media~Media#defaultPlaybackRate} or + * Called when either [defaultPlaybackRate]{@link module:enyo/Media~Media#defaultPlaybackRate} or * [playbackRate]{@link module:enyo/Media~Media#playbackRate} has been updated. * * @fires module:enyo/Media~Media#onSlowforward @@ -945,7 +944,7 @@ module.exports = kind( /** * Called when the media controller position has changed. - * + * * @private */ _timeUpdate: function (sender, e) { @@ -1022,7 +1021,7 @@ module.exports = kind( * Retrieves the ranges of the [media]{@link module:enyo/Media~Media} [source]{@link module:enyo/Media~Media#src} * that have been buffered. * - * @returns {TimeRanges} The ranges of the [media]{@link module:enyo/Media~Media} + * @returns {TimeRanges} The ranges of the [media]{@link module:enyo/Media~Media} * [source]{@link module:enyo/Media~Media#src} that have been buffered. * @public */ @@ -1059,7 +1058,7 @@ module.exports = kind( return 0; }, - /** + /** * Determines whether the [media]{@link module:enyo/Media~Media} element is paused. * * @returns {Boolean} `true` if the [media]{@link module:enyo/Media~Media} is paused; @@ -1072,11 +1071,11 @@ module.exports = kind( } }, - /** - * Retrieves the ranges of the [media]{@link module:enyo/Media~Media} [source]{@link module:enyo/Media~Media#src} + /** + * Retrieves the ranges of the [media]{@link module:enyo/Media~Media} [source]{@link module:enyo/Media~Media#src} * that have been played, if any. * - * @returns {TimeRanges} The ranges of the [media]{@link module:enyo/Media~Media} + * @returns {TimeRanges} The ranges of the [media]{@link module:enyo/Media~Media} * [source]{@link module:enyo/Media~Media#src} that have been played. * @public */ @@ -1086,7 +1085,7 @@ module.exports = kind( } }, - /** + /** * Determines the [readiness]{@glossary readyState} of the [media]{@link module:enyo/Media~Media}. * * @returns {ReadyState} The [readiness]{@glossary readyState} state. @@ -1098,7 +1097,7 @@ module.exports = kind( } }, - /** + /** * Retrieves the ranges of the [media]{@link module:enyo/Media~Media} [source]{@link module:enyo/Media~Media#src} * that the user may seek to, if any. * @@ -1112,7 +1111,7 @@ module.exports = kind( } }, - /** + /** * Sets current player position in the [media]{@link module:enyo/Media~Media} element. * * @param {Number} time - The player position, in seconds. @@ -1124,7 +1123,7 @@ module.exports = kind( } }, - /** + /** * Implements custom rewind functionality (until browsers support negative playback rate). * * @public @@ -1136,7 +1135,7 @@ module.exports = kind( /** * Calculates the time that has elapsed since. - * + * * @private */ _rewind: function () { @@ -1149,7 +1148,7 @@ module.exports = kind( this.startRewindJob(); }, - /** + /** * Starts rewind job. * * @public @@ -1159,7 +1158,7 @@ module.exports = kind( Job(this.id + 'rewind', this.bindSafely('_rewind'), 100); }, - /** + /** * Stops rewind job. * * @public @@ -1168,7 +1167,7 @@ module.exports = kind( Job.stop(this.id + 'rewind'); }, - /** + /** * Determines whether the [media]{@link module:enyo/Media~Media} is currently seeking to a new position. * * @returns {Boolean} `true` if currently seeking; otherwise, `false`. @@ -1180,7 +1179,7 @@ module.exports = kind( } }, - /** + /** * Determines whether the [media]{@link module:enyo/Media~Media} is currently in a paused state. * * @returns {Boolean} `true` if paused; otherwise, `false`. @@ -1190,7 +1189,7 @@ module.exports = kind( return this.hasNode() ? this.hasNode().paused : true; }, - /** + /** * Fast forwards the [media]{@link module:enyo/Media~Media}, taking into account the current * playback state. * @@ -1248,7 +1247,7 @@ module.exports = kind( }, - /** + /** * Rewinds the [media]{@link module:enyo/Media~Media}, taking into account the current * playback state. * @@ -1322,7 +1321,7 @@ module.exports = kind( } }, - /** + /** * Jumps backward by an amount specified by the [jumpSec]{@link module:enyo/Media~Media#jumpSec} * property. * @@ -1343,7 +1342,7 @@ module.exports = kind( this.doJumpBackward(utils.mixin(this.createEventData(), {jumpSize: this.jumpSec})); }, - /** + /** * Jumps forward by an amount specified by the [jumpSec]{@link module:enyo/Media~Media#jumpSec} * property. * @@ -1364,7 +1363,7 @@ module.exports = kind( this.doJumpForward(utils.mixin(this.createEventData(), {jumpSize: this.jumpSec})); }, - /** + /** * Jumps to the beginning of the [media]{@link module:enyo/Media~Media} content. * * @public @@ -1382,7 +1381,7 @@ module.exports = kind( this._prevCommand = 'jumpToStart'; }, - /** + /** * Jumps to the end of the [media]{@link module:enyo/Media~Media} content. * * @public diff --git a/src/Video.js b/src/Video.js index 6e9288156..04986d9c2 100644 --- a/src/Video.js +++ b/src/Video.js @@ -120,7 +120,7 @@ var * ``` * * To play a video, call `this.$.video.play()`. -* +* * To get a reference to the actual HTML 5 Video element, call `this.$.video.hasNode()`. * * @class Video @@ -144,12 +144,12 @@ module.exports = kind( /** * @private */ - published: + published: /** @lends module:enyo/Video~Video.prototype */ { /** * Source URL of the video file; may be relative to the application's HTML file. - * + * * @type {String} * @default '' * @public @@ -159,7 +159,7 @@ module.exports = kind( /** * An [object]{@glossary Object} that may be used to specify multiple sources for the * same video file. - * + * * @type {Object} * @default null * @public @@ -168,7 +168,7 @@ module.exports = kind( /** * Source of image file to show when video is not available. - * + * * @type {String} * @default '' * @public @@ -177,7 +177,7 @@ module.exports = kind( /** * If `true`, controls for starting and stopping the video player are shown. - * + * * @type {Boolean} * @default false * @public @@ -190,7 +190,7 @@ module.exports = kind( * - `'auto'`: Preload the video data as soon as possible. * - `'metadata'`: Preload only the video metadata. * - `'none'`: Do not preload any video data. - * + * * @type {String} * @default 'metadata' * @public @@ -199,7 +199,7 @@ module.exports = kind( /** * If `true`, video will automatically start playing. - * + * * @type {Boolean} * @default false * @public @@ -209,7 +209,7 @@ module.exports = kind( /** * If `true`, when playback is finished, the video player will restart from * the beginning. - * + * * @type {Boolean} * @default false * @public @@ -218,7 +218,7 @@ module.exports = kind( /** * If `true`, video will be stretched to fill the entire window (webOS only). - * + * * @type {Boolean} * @default false * @public @@ -227,7 +227,7 @@ module.exports = kind( /** * The video aspect ratio, expressed as `width:height`. - * + * * @type {Number} * @default 0 * @public @@ -236,7 +236,7 @@ module.exports = kind( /** * Number of seconds to jump forward or backward. - * + * * @type {Number} * @default 30 * @public @@ -245,7 +245,7 @@ module.exports = kind( /** * Video playback rate. - * + * * @type {Number} * @default 1 * @public @@ -262,7 +262,7 @@ module.exports = kind( * slowRewind: ['-1/2', '-1'] * } * ``` - * + * * @type {Object} * @default { * fastForward: ['2', '4', '8', '16'], @@ -443,10 +443,10 @@ module.exports = kind( return; } }, - + /** * Loads the current video [source]{@link module:enyo/Video~Video#src}. - * + * * @public */ load: function () { @@ -456,7 +456,7 @@ module.exports = kind( /** * Unloads the current video [source]{@link module:enyo/Video~Video#src}, stopping all * playback and buffering. - * + * * @public */ unload: function() { @@ -469,7 +469,7 @@ module.exports = kind( /** * Initiates playback of the video data. - * + * * @public */ play: function () { @@ -484,7 +484,7 @@ module.exports = kind( /** * Pauses video playback. - * + * * @public */ pause: function () { @@ -556,7 +556,7 @@ module.exports = kind( /** * Changes the playback speed via [selectPlaybackRate()]{@link module:enyo/Video~Video#selectPlaybackRate}. - * + * * @public */ rewind: function () { @@ -667,9 +667,9 @@ module.exports = kind( }, /** - * Jumps to beginning of media [source]{@link module:enyo/Video~Video#src} and sets + * Jumps to beginning of media [source]{@link module:enyo/Video~Video#src} and sets * [playbackRate]{@link module:enyo/Video~Video#playbackRate} to `1`. - * + * * @public */ jumpToStart: function () { @@ -686,9 +686,9 @@ module.exports = kind( }, /** - * Jumps to end of media [source]{@link module:enyo/Video~Video#src} and sets + * Jumps to end of media [source]{@link module:enyo/Video~Video#src} and sets * [playbackRate]{@link module:enyo/Video~Video#playbackRate} to `1`. - * + * * @public */ jumpToEnd: function () { @@ -705,7 +705,7 @@ module.exports = kind( }, /** - * Sets the playback rate type (from the [keys]{@glossary Object.keys} of + * Sets the playback rate type (from the [keys]{@glossary Object.keys} of * [playbackRateHash]{@link module:enyo/Video~Video#playbackRateHash}). * * @param {String} cmd - Key of the playback rate type. @@ -716,7 +716,7 @@ module.exports = kind( }, /** - * Changes [playbackRate]{@link module:enyo/Video~Video#playbackRate} to a valid value when initiating + * Changes [playbackRate]{@link module:enyo/Video~Video#playbackRate} to a valid value when initiating * fast forward or rewind. * * @param {Number} idx - The index of the desired playback rate. @@ -743,7 +743,7 @@ module.exports = kind( /** * Sets [playbackRate]{@link module:enyo/Video~Video#playbackRate}. - * + * * @param {String} rate - The desired playback rate. * @public */ @@ -847,7 +847,7 @@ module.exports = kind( /** * Implements custom rewind functionality (until browsers support negative playback rate). - * + * * @private */ beginRewind: function () { @@ -857,7 +857,7 @@ module.exports = kind( /** * Calculates the time that has elapsed since - * + * * @private */ _rewind: function () { @@ -874,7 +874,7 @@ module.exports = kind( /** * Starts rewind job. - * + * * @private */ startRewindJob: function () { @@ -884,7 +884,7 @@ module.exports = kind( /** * Stops rewind job. - * + * * @private */ stopRewindJob: function () { @@ -893,7 +893,7 @@ module.exports = kind( /** * Calculates numeric value of playback rate (with support for fractions). - * + * * @private */ calcNumberValueOfPlaybackRate: function (rate) { @@ -902,7 +902,7 @@ module.exports = kind( }, /** - * + * * Updates the [aspectRatio]{@link module:enyo/Video~Video#aspectRatio} property when the * video's metadata is received. * @@ -980,7 +980,6 @@ module.exports = kind( this.doStart(); } return { - srcElement: node, duration: node.duration, currentTime: node.currentTime, playbackRate: this.getPlaybackRate() @@ -989,7 +988,7 @@ module.exports = kind( /** * Normalizes Enyo-generated `onPlay` [events]{@glossary event}. - * + * * @fires module:enyo/Video~Video#doPlay * @private */ @@ -1007,7 +1006,7 @@ module.exports = kind( /** * All HTML5 [video]{@glossary video} [events]{@glossary event}. - * + * * @private */ hookupVideoEvents: function () { From 7642beafcba39207431edd9e459b01b39704406c Mon Sep 17 00:00:00 2001 From: Jason Robitaille Date: Tue, 8 Mar 2016 13:39:04 -0800 Subject: [PATCH 160/210] ENYO-3192: Dispatcher not caching touch position as expected --- src/dispatcher.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/dispatcher.js b/src/dispatcher.js index 4fe7699a1..322fc3927 100644 --- a/src/dispatcher.js +++ b/src/dispatcher.js @@ -330,14 +330,15 @@ dispatcher.features.push( (e.type == "click") || (e.type == "touchmove") ) { - _xy.clientX = e.clientX; - _xy.clientY = e.clientY; + var evt = (e.type == "touchmove") ? e.touches[0] : e; + _xy.clientX = evt.clientX; + _xy.clientY = evt.clientY; // note only ie8 does not support pageX/pageY - _xy.pageX = e.pageX; - _xy.pageY = e.pageY; + _xy.pageX = evt.pageX; + _xy.pageY = evt.pageY; // note ie8 and opera report these values incorrectly - _xy.screenX = e.screenX; - _xy.screenY = e.screenY; + _xy.screenX = evt.screenX; + _xy.screenY = evt.screenY; } } ); From 7f2006767e96edb7c52446cf4573e2c207522676 Mon Sep 17 00:00:00 2001 From: "jeremy.thomas" Date: Fri, 19 Feb 2016 16:31:52 -0500 Subject: [PATCH 161/210] ENYO-3019: Remove IE8 support More IE8 support removal string change remove ie8 polyfills Remove module refs IE8 support removal fixes remove forEach-map-filter array polyfills remove additional ie8 code --- src/Ajax.js | 22 ++++---- src/Checkbox/Checkbox.js | 19 +------ src/Control/fullscreen.js | 9 ++-- src/Input/Input.js | 11 +--- src/Select.js | 7 +-- src/Table/Table.js | 5 +- src/dispatcher.js | 55 +++----------------- src/dom.js | 105 +++---------------------------------- src/gesture/drag.js | 6 --- src/gesture/util.js | 5 -- src/i18n.js | 2 - src/ready.js | 10 ++-- src/touch.js | 8 +-- src/utils.js | 106 +------------------------------------- 14 files changed, 39 insertions(+), 331 deletions(-) diff --git a/src/Ajax.js b/src/Ajax.js index 266567c8a..c2c193d30 100644 --- a/src/Ajax.js +++ b/src/Ajax.js @@ -184,7 +184,7 @@ var Ajax = module.exports = kind( } utils.mixin(xhr_headers, this.headers); // don't pass in headers structure if there are no headers defined as this messes - // up CORS code for IE8-9 + // up CORS code for IE9 if (utils.keys(xhr_headers).length === 0) { xhr_headers = undefined; } @@ -278,7 +278,7 @@ var Ajax = module.exports = kind( } } else { var text = ''; - // work around IE8-9 bug where accessing responseText will thrown error + // work around IE9 bug where accessing responseText will thrown error // for binary requests. if (typeof inXhr.responseText === 'string') { text = inXhr.responseText; @@ -337,19 +337,15 @@ var Ajax = module.exports = kind( * @private */ updateProgress: function (event) { - // IE8 doesn't properly support progress events and doesn't pass an object to the - // handlers so we'll check that before continuing. - if (event) { - // filter out 'input' as it causes exceptions on some Firefox versions - // due to unimplemented internal APIs - var ev = {}; - for (var k in event) { - if (k !== 'input') { - ev[k] = event[k]; - } + // filter out 'input' as it causes exceptions on some Firefox versions + // due to unimplemented internal APIs + var ev = {}; + for (var k in event) { + if (k !== 'input') { + ev[k] = event[k]; } - this.sendProgress(event.loaded, 0, event.total, ev); } + this.sendProgress(event.loaded, 0, event.total, ev); }, /** diff --git a/src/Checkbox/Checkbox.js b/src/Checkbox/Checkbox.js index 77a011a20..812988201 100644 --- a/src/Checkbox/Checkbox.js +++ b/src/Checkbox/Checkbox.js @@ -7,8 +7,7 @@ require('enyo'); var kind = require('../kind'), - utils = require('../utils'), - platform = require('../platform'); + utils = require('../utils'); var Input = require('../Input'); @@ -98,8 +97,7 @@ module.exports = kind( * @private */ handlers: { - onchange: 'change', - onclick: 'click' + onchange: 'change' }, /** @@ -180,19 +178,6 @@ module.exports = kind( this.setActive(nodeChecked); }, - /** - * @private - */ - click: function (sender, e) { - // Various versions of IE (notably IE8) do not fire 'onchange' for - // checkboxes, so we discern change via 'click'. - // Note: keyboard interaction (e.g. pressing space when focused) fires - // a click event. - if (platform.ie <= 8) { - this.bubble('onchange', e); - } - }, - // Accessibility /** diff --git a/src/Control/fullscreen.js b/src/Control/fullscreen.js index 82e128bd5..8a6144b84 100644 --- a/src/Control/fullscreen.js +++ b/src/Control/fullscreen.js @@ -236,12 +236,9 @@ module.exports = function (Control) { * @private */ ready(function() { - // no need for IE8 fallback, since it won't ever send this event - if (document.addEventListener) { - document.addEventListener('webkitfullscreenchange', utils.bind(fullscreen, 'detectFullscreenChangeEvent'), false); - document.addEventListener('mozfullscreenchange', utils.bind(fullscreen, 'detectFullscreenChangeEvent'), false); - document.addEventListener('fullscreenchange', utils.bind(fullscreen, 'detectFullscreenChangeEvent'), false); - } + document.addEventListener('webkitfullscreenchange', utils.bind(fullscreen, 'detectFullscreenChangeEvent'), false); + document.addEventListener('mozfullscreenchange', utils.bind(fullscreen, 'detectFullscreenChangeEvent'), false); + document.addEventListener('fullscreenchange', utils.bind(fullscreen, 'detectFullscreenChangeEvent'), false); }); /** diff --git a/src/Input/Input.js b/src/Input/Input.js index a450ca098..4232514fd 100644 --- a/src/Input/Input.js +++ b/src/Input/Input.js @@ -198,14 +198,7 @@ module.exports = kind( rendered: kind.inherit(function (sup) { return function() { sup.apply(this, arguments); - dispatcher.makeBubble(this, 'focus', 'blur'); - - //Force onchange event to be bubbled inside Enyo for IE8 - if(platform.ie == 8){ - this.setAttribute('onchange', dispatcher.bubbler); - } - this.disabledChanged(); if (this.defaultFocus) { this.focus(); @@ -264,8 +257,8 @@ module.exports = kind( */ iekeyup: function (sender, e) { var ie = platform.ie, kc = e.keyCode; - // input event missing on ie 8, fails to fire on backspace and delete keys in ie 9 - if (ie <= 8 || (ie == 9 && (kc == 8 || kc == 46))) { + // input event fails to fire on backspace and delete keys in ie 9 + if (ie == 9 && (kc == 8 || kc == 46)) { this.bubble('oninput', e); } }, diff --git a/src/Select.js b/src/Select.js index 36392e490..3e5fcc8e5 100644 --- a/src/Select.js +++ b/src/Select.js @@ -7,8 +7,7 @@ require('enyo'); var kind = require('./kind'), - platform = require('./platform'), - dispatcher = require('./dispatcher'); + platform = require('./platform'); var Control = require('./Control'), /*jshint -W079*/ @@ -136,10 +135,6 @@ module.exports = kind( rendered: kind.inherit(function (sup) { return function () { sup.apply(this, arguments); - //Trick to force IE8 onchange event bubble - if (platform.ie == 8) { - this.setAttribute('onchange', dispatcher.bubbler); - } // This makes Select.selected a higher priority than Option.selected but ensures that // the former works at create time if (this.selected !== null) { diff --git a/src/Table/Table.js b/src/Table/Table.js index 5770be3ff..847f457e7 100644 --- a/src/Table/Table.js +++ b/src/Table/Table.js @@ -12,10 +12,7 @@ var TableRow = require('../TableRow'); /* -* TODO: Won't work in IE8 because we can't set innerHTML on table elements. We'll need to fall -* back to divs with table display styles applied. -* -* Should also facade certain useful table functionality (specific set TBD). +* TODO: Should facade certain useful table functionality (specific set TBD). */ /** diff --git a/src/dispatcher.js b/src/dispatcher.js index 4fe7699a1..31ee8f096 100644 --- a/src/dispatcher.js +++ b/src/dispatcher.js @@ -8,8 +8,7 @@ require('enyo'); var logger = require('./logger'), master = require('./master'), - utils = require('./utils'), - platform = require('./platform'); + utils = require('./utils'); var Dom = require('./dom'); @@ -86,40 +85,14 @@ var dispatcher = module.exports = dispatcher = { * @private */ listen: function(inListener, inEventName, inHandler) { - if (inListener.addEventListener) { - this.listen = function(inListener, inEventName, inHandler) { - inListener.addEventListener(inEventName, inHandler || dispatch, false); - }; - } else { - //enyo.log("IE8 COMPAT: using 'attachEvent'"); - this.listen = function(inListener, inEvent, inHandler) { - inListener.attachEvent("on" + inEvent, function(e) { - e.target = e.srcElement; - if (!e.preventDefault) { - e.preventDefault = this.iePreventDefault; - } - return (inHandler || dispatch)(e); - }); - }; - } - this.listen(inListener, inEventName, inHandler); + inListener.addEventListener(inEventName, inHandler || dispatch, false); }, /** * @private */ stopListening: function(inListener, inEventName, inHandler) { - if (inListener.addEventListener) { - this.stopListening = function(inListener, inEventName, inHandler) { - inListener.removeEventListener(inEventName, inHandler || dispatch, false); - }; - } else { - //enyo.log("IE8 COMPAT: using 'detachEvent'"); - this.stopListening = function(inListener, inEvent, inHandler) { - inListener.detachEvent("on" + inEvent, inHandler || dispatch); - }; - } - this.stopListening(inListener, inEventName, inHandler); + inListener.removeEventListener(inEventName, inHandler || dispatch, false); }, /** @@ -220,14 +193,8 @@ function dispatch (inEvent) { * @private */ dispatcher.bubble = function(inEvent) { - // '|| window.event' clause needed for IE8 - var e = inEvent || global.event; - if (e) { - // We depend on e.target existing for event tracking and dispatching. - if (!e.target) { - e.target = e.srcElement; - } - dispatcher.dispatch(e); + if (inEvent) { + dispatcher.dispatch(inEvent); } }; @@ -348,22 +315,14 @@ dispatcher.features.push( * `clientY`, `pageX`, `pageY`, `screenX`, and `screenY` properties. It is * important to note that IE8 and Opera have improper reporting for the * `screenX` and `screenY` properties (they both use CSS pixels as opposed to -* device pixels) and IE8 has no support for the `pageX` and `pageY` properties, -* so they are facaded. +* device pixels). * * @returns {module:enyo/dispatcher~CursorCoordinates} An [object]{@glossary Object} describing the * the last known coordinates of the cursor or user-interaction point in touch environments. * @public */ dispatcher.getPosition = function () { - var p = utils.clone(_xy); - // if we are in ie8 we facade the _pageX, pageY_ properties - if (platform.ie < 9) { - var d = (document.documentElement || document.body.parentNode || document.body); - p.pageX = (p.clientX + d.scrollLeft); - p.pageY = (p.clientY + d.scrollTop); - } - return p; + return utils.clone(_xy); }; diff --git a/src/dom.js b/src/dom.js index 5cc7f2690..c74cb7cfe 100644 --- a/src/dom.js +++ b/src/dom.js @@ -70,41 +70,11 @@ var dom = module.exports = { } }, - /** - * This is designed to be copied into the `computedStyle` object. - * - * @private - */ - _ie8GetComputedStyle: function(prop) { - var re = /(\-([a-z]){1})/g; - if (prop === 'float') { - prop = 'styleFloat'; - } else if (re.test(prop)) { - prop = prop.replace(re, function () { - return arguments[2].toUpperCase(); - }); - } - return this[prop] !== undefined ? this[prop] : null; - }, - /** * @private */ getComputedStyle: function(node) { - if(platform.ie < 9 && node && node.currentStyle) { - //simple global.getComputedStyle polyfill for IE8 - var computedStyle = utils.clone(node.currentStyle); - computedStyle.getPropertyValue = this._ie8GetComputedStyle; - computedStyle.setProperty = function() { - return node.currentStyle.setExpression.apply(node.currentStyle, arguments); - }; - computedStyle.removeProperty = function() { - return node.currentStyle.removeAttribute.apply(node.currentStyle, arguments); - }; - return computedStyle; - } else { - return global.getComputedStyle && node && global.getComputedStyle(node, null); - } + return global.getComputedStyle && node && global.getComputedStyle(node, null); }, /** @@ -118,9 +88,9 @@ var dom = module.exports = { if (nIE) { var oConversion = { - 'thin' : (nIE > 8 ? 2 : 1) + 'px', - 'medium' : (nIE > 8 ? 4 : 3) + 'px', - 'thick' : (nIE > 8 ? 6 : 5) + 'px', + 'thin' : '2px', + 'medium' : '4px', + 'thick' : '6px', 'none' : '0' }; if (typeof oConversion[s] != 'undefined') { @@ -216,64 +186,11 @@ var dom = module.exports = { /** * @private */ - // Workaround for lack of compareDocumentPosition support in IE8 - // Code MIT Licensed, John Resig; source: http://ejohn.org/blog/comparing-document-position/ - compareDocumentPosition: function(a, b) { - return a.compareDocumentPosition ? - a.compareDocumentPosition(b) : - a.contains ? - (a != b && a.contains(b) && 16) + - (a != b && b.contains(a) && 8) + - (a.sourceIndex >= 0 && b.sourceIndex >= 0 ? - (a.sourceIndex < b.sourceIndex && 4) + - (a.sourceIndex > b.sourceIndex && 2) : - 1) + - 0 : - 0; - }, - - /** - * @private - */ - // moved from FittableLayout.js into common protected code - _ieCssToPixelValue: function(node, value) { - var v = value; - // From the awesome hack by Dean Edwards - // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 - var s = node.style; - // store style and runtime style values - var l = s.left; - var rl = node.runtimeStyle && node.runtimeStyle.left; - // then put current style in runtime style. - if (rl) { - node.runtimeStyle.left = node.currentStyle.left; - } - // apply given value and measure its pixel value - s.left = v; - v = s.pixelLeft; - // finally restore previous state - s.left = l; - if (rl) { - s.runtimeStyle.left = rl; - } - return v; - }, - - /** - * @private - */ - _pxMatch: /px/i, getComputedBoxValue: function(node, prop, boundary, computedStyle) { var s = computedStyle || this.getComputedStyle(node); - if (s && (!platform.ie || platform.ie >= 9)) { + if (s) { var p = s.getPropertyValue(prop + '-' + boundary); return p === 'auto' ? 0 : parseInt(p, 10); - } else if (node && node.currentStyle) { - var v = node.currentStyle[prop + utils.cap(boundary)]; - if (!v.match(this._pxMatch)) { - v = this._ieCssToPixelValue(node, v); - } - return parseInt(v, 0); } return 0; }, @@ -361,8 +278,7 @@ var dom = module.exports = { if (node.offsetParent) { do { // Adjust the offset if relativeToNode is a child of the offsetParent - // For IE 8 compatibility, have to use integer 8 instead of Node.DOCUMENT_POSITION_CONTAINS - if (relativeToNode && this.compareDocumentPosition(relativeToNode, node.offsetParent) & 8) { + if (relativeToNode && relativeToNode.compareDocumentPosition(node.offsetParent) & Node.DOCUMENT_POSITION_CONTAINS) { offsetAdjustLeft = relativeToNode.offsetLeft; offsetAdjustTop = relativeToNode.offsetTop; } @@ -377,11 +293,7 @@ var dom = module.exports = { } // Need to correct for borders if any exist on parent elements if (node !== targetNode) { - if (node.currentStyle) { - // Oh IE, we do so love working around your incompatibilities - borderLeft = parseInt(node.currentStyle.borderLeftWidth, 10); - borderTop = parseInt(node.currentStyle.borderTopWidth, 10); - } else if (global.getComputedStyle) { + if (global.getComputedStyle) { borderLeft = parseInt(global.getComputedStyle(node, '').getPropertyValue('border-left-width'), 10); borderTop = parseInt(global.getComputedStyle(node, '').getPropertyValue('border-top-width'), 10); } else { @@ -397,8 +309,7 @@ var dom = module.exports = { } } // Continue if we have an additional offsetParent, and either don't have a relativeToNode or the offsetParent is contained by the relativeToNode (if offsetParent contains relativeToNode, then we have already calculated up to the node, and can safely exit) - // For IE 8 compatibility, have to use integer 16 instead of Node.DOCUMENT_POSITION_CONTAINED_BY - } while ((node = node.offsetParent) && (!relativeToNode || this.compareDocumentPosition(relativeToNode, node) & 16)); + } while ((node = node.offsetParent) && (!relativeToNode || relativeToNode.compareDocumentPosition(node) & Node.DOCUMENT_POSITION_CONTAINED_BY)); } return { 'top': top, diff --git a/src/gesture/drag.js b/src/gesture/drag.js index deab434ce..31cc721e3 100644 --- a/src/gesture/drag.js +++ b/src/gesture/drag.js @@ -1,6 +1,5 @@ var dispatcher = require('../dispatcher'), - platform = require('../platform'), utils = require('../utils'); var @@ -307,11 +306,6 @@ module.exports = { e.shiftKey = inEvent.shiftKey; e.srcEvent = inEvent.srcEvent; // }; - //Fix for IE8, which doesn't include pageX and pageY properties - if(platform.ie==8 && e.target) { - e.pageX = e.clientX + e.target.scrollLeft; - e.pageY = e.clientY + e.target.scrollTop; - } e.preventDefault = gestureUtil.preventDefault; e.disablePrevention = gestureUtil.disablePrevention; return e; diff --git a/src/gesture/util.js b/src/gesture/util.js index e2466335c..0f2d9f8a5 100644 --- a/src/gesture/util.js +++ b/src/gesture/util.js @@ -50,11 +50,6 @@ module.exports = { // Note that while 'which' works in IE9, it is broken for mousemove. Therefore, // in IE, use global.event.button if (platform.ie < 10) { - //Fix for IE8, which doesn't include pageX and pageY properties - if(platform.ie==8 && e.target) { - e.pageX = e.clientX + e.target.scrollLeft; - e.pageY = e.clientY + e.target.scrollTop; - } var b = global.event && global.event.button; if (b) { // multi-button not supported, priority: left, right, middle diff --git a/src/i18n.js b/src/i18n.js index 861ef5c9d..ef85b5901 100644 --- a/src/i18n.js +++ b/src/i18n.js @@ -43,8 +43,6 @@ exports.$L = new utils.Extensible(function (str) { * `i18n.updateLocale()`. The default implementation of `i18n.updateLocale()` is a stub, but an * i18n library may override it to update its internal state before the `onlocalechange` signal * is broadcast. -* -* This feature is not supported on IE8, which doesn't support `addEventListener()`. * * @private */ diff --git a/src/ready.js b/src/ready.js index c9937bb8e..d77a36c98 100644 --- a/src/ready.js +++ b/src/ready.js @@ -56,7 +56,7 @@ init = function (event) { flush(); } } - // for an IE8 fallback and legacy WebKit (including webOS 3.x and less) and assurance + // for legacy WebKit (including webOS 3.x and less) and assurance if ((ready = ("complete" === doc.readyState || "loaded" === doc.readyState))) { remove(event.type, init); flush(); @@ -67,18 +67,14 @@ init = function (event) { * @private */ add = function (event, fn) { - var name = doc.addEventListener? "addEventListener": "attachEvent"; - var on = name === "attachEvent"? "on": ""; - doc[name](on + event, fn, false); + doc.addEventListener(event, fn, false); }; /** * @private */ remove = function (event, fn) { - var name = doc.addEventListener? "removeEventListener": "detachEvent"; - var on = name === "detachEvent"? "on": ""; - doc[name](on + event, fn, false); + doc.removeEventListener(event, fn, false); }; /** diff --git a/src/touch.js b/src/touch.js index 4e6ec1126..99ee7eca2 100644 --- a/src/touch.js +++ b/src/touch.js @@ -216,12 +216,8 @@ Dom.requiresWindow(function() { */ connect: function () { utils.forEach(['touchstart', 'touchmove', 'touchend', 'gesturestart', 'gesturechange', 'gestureend'], function(e) { - if(platform.ie < 9){ - document['on' + e] = dispatch; - } else { - // on iOS7 document.ongesturechange is never called - document.addEventListener(e, dispatch, false); - } + // on iOS7 document.ongesturechange is never called + document.addEventListener(e, dispatch, false); }); if (platform.androidChrome <= 18 || platform.silk === 2) { diff --git a/src/utils.js b/src/utils.js index 858e25329..68ddc3e72 100644 --- a/src/utils.js +++ b/src/utils.js @@ -233,8 +233,7 @@ var isArray = exports.isArray = Array.isArray || function (it) { * @public */ exports.isObject = Object.isObject || function (it) { - // explicit null/undefined check for IE8 compatibility - return (it != null) && (toString.call(it) === '[object Object]'); + return toString.call(it) === '[object Object]'; }; /** @@ -737,23 +736,6 @@ Object.keys = Object.keys || function (obj) { results.push(prop); } } - // *sigh* IE 8 - if (!({toString: null}).propertyIsEnumerable('toString')) { - var dontEnums = [ - 'toString', - 'toLocaleString', - 'valueOf', - 'hasOwnProperty', - 'isPrototypeOf', - 'propertyIsEnumerable', - 'constructor' - ]; - for (var i = 0, p; (p = dontEnums[i]); i++) { - if (hop.call(obj, p)) { - results.push(p); - } - } - } return results; }; @@ -1000,60 +982,6 @@ exports.values = function (obj) { // Array Functions // ---------------------------------- -/** -* Because our older API parameters are not consistent with other array API methods, and also -* because only [IE8 lacks integrated support]{@glossary polyfill} for -* [indexOf()]{@linkcode external:Array.indexOf}, we ensure it is defined (only IE8) and advise, -* moving forward, that the built-in method be used. But to preserve our original API, it will -* simply call this method, knowing it exists. -* -* @private -*/ -Array.prototype.indexOf = Array.prototype.indexOf || function (el, offset) { - var len = this.length >>> 0; - - offset = +offset || 0; - - if (Math.abs(offset) === Infinity) offset = 0; - if (offset < 0) offset += len; - if (offset < 0) offset = 0; - - for (; offset < len; ++offset) { - if (this[offset] === el) return offset; - } - - return -1; -}; - -/** -* Because our older API parameters are not consistent with other array API methods, and also -* because only [IE8 lacks integrated support]{@glossary polyfill} for -* [lastIndexOf()]{@glossary Array.lastIndexOf} we ensure it is defined (only IE8) and -* advise, moving forward, that the built-in method be used. But to preserve our original API, it -* will simply call this method, knowing it exists. -* -* @private -*/ -Array.prototype.lastIndexOf = Array.prototype.lastIndexOf || function (el, offset) { - var array = Object(this) - , len = array.length >>> 0; - - if (len === 0) return -1; - - if (offset !== undefined) { - offset = Number(offset); - if (Math.abs(offset) > len) offset = len; - if (offset === Infinity || offset === -Infinity) offset = len; - if (offset < 0) offset += len; - } else offset = len; - - for (; offset > -1; --offset) { - if (array[offset] === el) return offset; - } - - return -1; -}; - /** * A [polyfill]{@glossary polyfill} for platforms that don't support * [Array.findIndex()]{@glossary Array.findIndex}. @@ -1075,38 +1003,6 @@ Array.prototype.find = Array.prototype.find || function (fn, ctx) { } }; -/** -* A [polyfill]{@glossary polyfill} for platforms that don't support -* [Array.forEach()]{@glossary Array.forEach}. -*/ -Array.prototype.forEach = Array.prototype.forEach || function (fn, ctx) { - for (var i=0, len=this.length >>> 0; i>> 0; i>> 0; i Date: Thu, 10 Mar 2016 22:30:16 +0530 Subject: [PATCH 162/210] Updated seek changes Enyo-DCO-1.1-Signed-off-by: Anish Ramesan --- src/AnimationSupport/Editor.js | 248 +++++++++++++++++---------------- 1 file changed, 126 insertions(+), 122 deletions(-) diff --git a/src/AnimationSupport/Editor.js b/src/AnimationSupport/Editor.js index 3e9aa7f3b..b7daadb3c 100644 --- a/src/AnimationSupport/Editor.js +++ b/src/AnimationSupport/Editor.js @@ -9,30 +9,26 @@ require('enyo'); * @private */ module.exports = { - /** - * @private - */ + /** + * @private + */ timeline: 0, - /** - * @private - */ + /** + * @private + */ _cachedValue: 0, - /** - * @private - */ + /** + * @private + */ speed: 0, - /** - * @private - */ - startTimeline: 0, - /** - * @private - */ - seekInterval:0, - /** - * @private - */ - cache: function(actor) { + /** + * @private + */ + seekInterval:0, + /** + * @private + */ + cache: function(actor) { actor = actor || this; if(actor.speed === 0){ actor.speed = actor._cachedValue; @@ -40,12 +36,12 @@ module.exports = { this.animating = true; }, - /** - * Starts the animation of the actor given in argument. - * If actor is not provided, animation of all the components linked to the {@link module:enyo/AnimationSupport/Scene} will be started. - * @param [Component]{@link module:enyo/Component~Component} actor The component to be animated - * @public - */ + /** + * Starts the animation of the actor given in argument. + * If actor is not provided, animation of all the components linked to the {@link module:enyo/AnimationSupport/Scene} will be started. + * @param [Component]{@link module:enyo/Component~Component} actor The component to be animated + * @public + */ play: function (actor) { actor = actor || this; actor.speed = 1; @@ -53,95 +49,95 @@ module.exports = { actor.timeline = 0; } this.trigger(); - actor._cachedValue = actor.speed; + actor._cachedValue = actor.speed; this.animating = true; }, - /** - * Resumes the paused animation of the actor given in argument. - * If actor is not provided, animation of all the components linked to the {@link module:enyo/AnimationSupport/Scene} will be resumed. - * @param [Component]{@link module:enyo/Component~Component} actor The component to be animated - * @public - */ + /** + * Resumes the paused animation of the actor given in argument. + * If actor is not provided, animation of all the components linked to the {@link module:enyo/AnimationSupport/Scene} will be resumed. + * @param [Component]{@link module:enyo/Component~Component} actor The component to be animated + * @public + */ resume: function(actor) { this.cache(actor); actor = actor || this; actor.speed *= 1; }, - /** - * Pauses the animation of the actor given in argument. - * If actor is not provided, animation of all the components linked to the {@link module:enyo/AnimationSupport/Scene} will be paused. - * @param [Component]{@link module:enyo/Component~Component} actor The component to be animated - * @public - */ + /** + * Pauses the animation of the actor given in argument. + * If actor is not provided, animation of all the components linked to the {@link module:enyo/AnimationSupport/Scene} will be paused. + * @param [Component]{@link module:enyo/Component~Component} actor The component to be animated + * @public + */ pause: function (actor) { actor = actor || this; actor._cachedValue = actor.speed; actor.speed = 0; }, - /** - * Reverses the animation of the actor given in argument. - * If actor is not provided, animation of all the components linked to the {@link module:enyo/AnimationSupport/Scene} will be reversed. - * @param [Component]{@link module:enyo/Component~Component} actor The component to be animated - * @public - */ + /** + * Reverses the animation of the actor given in argument. + * If actor is not provided, animation of all the components linked to the {@link module:enyo/AnimationSupport/Scene} will be reversed. + * @param [Component]{@link module:enyo/Component~Component} actor The component to be animated + * @public + */ reverse: function (actor) { this.cache(actor); actor = actor || this; - actor._cachedValue = actor.speed; + actor._cachedValue = actor.speed; actor.speed *= -1; }, - /** - * fast description goes here - * @param {Number} mul description goes here - * @param [Component]{@link module:enyo/Component~Component} actor description goes here - * @public - */ + /** + * fast description goes here + * @param {Number} mul description goes here + * @param [Component]{@link module:enyo/Component~Component} actor description goes here + * @public + */ fast: function (mul, actor) { this.cache(actor); actor = actor || this; actor.speed *= mul; }, - /** - * slow description goes here - * @param {Number} mul description goes here - * @param [Component]{@link module:enyo/Component~Component} actor description goes here - * @public - */ + /** + * slow description goes here + * @param {Number} mul description goes here + * @param [Component]{@link module:enyo/Component~Component} actor description goes here + * @public + */ slow: function (mul, actor) { this.cache(actor); actor = actor || this; actor.speed *= mul; }, - /** - * Changes the speed of the animation.
- * Speed of the animation changed based on the factor.
- * To slow down the speed use values between 0 and 1. For Example 0.5 to reduce the speed by 50%.
- * To increase the speed use values above 1. For Example 2 to increase the speed by 200%.
- * Animation will be paused if factor is 0. To pause the animation use {@link enyo/AnimationSupport/Editor.pause pause} API.
- * Speed will not be affected incase of negative multiplication factor. - * @param {Number} factor Multiplication factor which changes the speed - * @param [Component {@link module:enyo/Component~Component}] actor The component whose animating speed should be changed - * @public - */ - // speed: function(mul, actor) { - // if (mul < 0) return; - // this.cache(actor); - // actor = actor || this; - // actor.speed *= mul; - // }, + /** + * Changes the speed of the animation.
+ * Speed of the animation changed based on the factor.
+ * To slow down the speed use values between 0 and 1. For Example 0.5 to reduce the speed by 50%.
+ * To increase the speed use values above 1. For Example 2 to increase the speed by 200%.
+ * Animation will be paused if factor is 0. To pause the animation use {@link enyo/AnimationSupport/Editor.pause pause} API.
+ * Speed will not be affected incase of negative multiplication factor. + * @param {Number} factor Multiplication factor which changes the speed + * @param [Component {@link module:enyo/Component~Component}] actor The component whose animating speed should be changed + * @public + */ + // speed: function(mul, actor) { + // if (mul < 0) return; + // this.cache(actor); + // actor = actor || this; + // actor.speed *= mul; + // }, - /** - * Stops the animation of the actor given in argument. - * If actor is not provided, animation of all the components linked to the {@link module:enyo/AnimationSupport/Scene} will be stopped. - * @param [Component]{@link module:enyo/Component~Component} actor The component to be animated - * @public - */ + /** + * Stops the animation of the actor given in argument. + * If actor is not provided, animation of all the components linked to the {@link module:enyo/AnimationSupport/Scene} will be stopped. + * @param [Component]{@link module:enyo/Component~Component} actor The component to be animated + * @public + */ stop: function (actor) { actor = actor || this; actor._cachedValue = 1; @@ -151,56 +147,64 @@ module.exports = { // this.cancel(); }, - /** - * Seeks the animation of the actor to the position provided in timeline - * The value of timeline should be between 0 to duration of the animation. - * @param {Number} timeline Value in timeline where the animation has to be seeked - * @param [Component]{@link module:enyo/Component~Component} actor The component to be animated - * @public - */ - seek: function(seek, actor) { - actor = actor || this; - actor.timeline = seek; - }, + /** + * Seeks the animation of the actor to the position provided in seek + * The value of seek should be between 0 to duration of the animation. + * @param {Number} seek Value in seek where the animation has to be seeked + * @param [Component]{@link module:enyo/Component~Component} actor The component to be animated + * @public + */ + seek: function(seek, actor) { + actor = actor || this; + actor.timeline = seek; + }, - seekAnimate: function(seek, actor) { - actor = actor || this; - if (seek >= 0 ) { - if (!this.animating) - this.play(actor); - actor.speed = 1; - }else{ - actor.speed = -1; - } - actor.seekInterval = actor.timeline + seek; - }, + /** + * Seeks actor with animation to the position provided in seek + * The value of seek should be between 0 to duration of the animation. + * @param {Number} seek Value in seek where the animation has to be seeked + * @param [Component]{@link module:enyo/Component~Component} actor The component to be animated + * @public + */ + seekAnimate: function(seek, actor) { + actor = actor || this; + if (seek >= 0 ) { + if (!this.animating) + this.play(actor); + actor.speed = 1; + }else{ + actor.speed = -1; + } + actor.seekInterval = actor.timeline + seek; + if (actor.seekInterval < 0) { + actor.speed = 0; + } + }, - /** - * rolePlay updated the timeline of the actor which is currently animating. - * @param {Number} t Elapsed time since the animation of this pose has started (ratio in factor of 1) - * @param {@link module:enyo/Component~Component} actor The component which is animating - * @return {Number} Returns the updated timeline of the actor - * @access public - */ + /** + * rolePlay updated the timeline of the actor which is currently animating. + * @param {Number} t Elapsed time since the animation of this pose has started (ratio in factor of 1) + * @param {@link module:enyo/Component~Component} actor The component which is animating + * @return {Number} Returns the updated timeline of the actor + * @access public + */ rolePlay: function (t, actor) { actor = actor || this; if (actor.timeline === undefined || actor.timeline < 0) actor.timeline = 0; - + if(actor.delay > 0) { actor.delay -= _rolePlay(t, actor.speed); - } - if(actor.startTimeline > 0 && actor.timeline == 0){ - actor.timeline = actor.startTimeline; - } else { + } else { actor.timeline += _rolePlay(t, actor.speed); } - if(actor.seekInterval !== 0) { - if((actor.seekInterval-actor.timeline)*actor.speed < 0) { - actor.seekInterval = 0; - actor.speed = 0; - } - } + + if(actor.seekInterval !== 0) { + if((actor.seekInterval-actor.timeline)*actor.speed < 0) { + actor.seekInterval = 0; + actor.speed = 0; + } + } return actor.timeline; } }; From 432fc12265152630bf4ca187b358eea285cbcd4c Mon Sep 17 00:00:00 2001 From: Aaron Tam Date: Thu, 10 Mar 2016 10:46:48 -0800 Subject: [PATCH 163/210] ENYO-3192: Converting to single quotes. Enyo-DCO-1.1-Signed-off-by: Aaron Tam --- src/dispatcher.js | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/dispatcher.js b/src/dispatcher.js index 8dd268981..55b387f35 100644 --- a/src/dispatcher.js +++ b/src/dispatcher.js @@ -42,17 +42,17 @@ var dispatcher = module.exports = dispatcher = { * * @private */ - events: ["mousedown", "mouseup", "mouseover", "mouseout", "mousemove", "mousewheel", - "click", "dblclick", "change", "keydown", "keyup", "keypress", "input", - "paste", "copy", "cut", "webkitTransitionEnd", "transitionend", "webkitAnimationEnd", "animationend", - "webkitAnimationStart", "animationstart", "webkitAnimationIteration", "animationiteration"], + events: ['mousedown', 'mouseup', 'mouseover', 'mouseout', 'mousemove', 'mousewheel', + 'click', 'dblclick', 'change', 'keydown', 'keyup', 'keypress', 'input', + 'paste', 'copy', 'cut', 'webkitTransitionEnd', 'transitionend', 'webkitAnimationEnd', 'animationend', + 'webkitAnimationStart', 'animationstart', 'webkitAnimationIteration', 'animationiteration'], /** * These events come from window * * @private */ - windowEvents: ["resize", "load", "unload", "message", "hashchange", "popstate", "focus", "blur"], + windowEvents: ['resize', 'load', 'unload', 'message', 'hashchange', 'popstate', 'focus', 'blur'], /** * Feature plugins (aka filters) @@ -71,8 +71,8 @@ var dispatcher = module.exports = dispatcher = { } for (i=0; (n=d.windowEvents[i]); i++) { // Chrome Packaged Apps don't like "unload" - if(n === "unload" && - (typeof global.chrome === "object") && + if(n === 'unload' && + (typeof global.chrome === 'object') && global.chrome.app) { continue; } @@ -157,7 +157,7 @@ var dispatcher = module.exports = dispatcher = { */ dispatchBubble: function(e, c) { var type = e.type; - type = e.customEvent ? type : "on" + type; + type = e.customEvent ? type : 'on' + type; return c.bubble(type, e, c); } }; @@ -201,7 +201,7 @@ dispatcher.bubble = function(inEvent) { // This string is set on event handlers attributes for DOM elements that // don't normally bubble (like onscroll) so that they can participate in the // Enyo event system. -dispatcher.bubbler = "enyo.bubble(arguments[0])"; +dispatcher.bubbler = 'enyo.bubble(arguments[0])'; // The code below helps make Enyo compatible with Google Packaged Apps // Content Security Policy(http://developer.chrome.com/extensions/contentSecurityPolicy.html), @@ -224,7 +224,7 @@ dispatcher.bubbler = "enyo.bubble(arguments[0])"; var args = Array.prototype.slice.call(arguments, 0), control = args.shift(); - if((typeof control === "object") && (typeof control.hasNode === "function")) { + if((typeof control === 'object') && (typeof control.hasNode === 'function')) { utils.forEach(args, function(event) { if(this.hasNode()) { dispatcher.listen(this.node, event, bubbleUp); @@ -245,7 +245,7 @@ dispatcher.bubbler = "enyo.bubble(arguments[0])"; var args = Array.prototype.slice.call(arguments, 0), control = args.shift(); - if((typeof control === "object") && (typeof control.hasNode === "function")) { + if((typeof control === 'object') && (typeof control.hasNode === 'function')) { utils.forEach(args, function(event) { if(this.hasNode()) { dispatcher.stopListening(this.node, event, bubbleUp); @@ -268,12 +268,12 @@ Dom.requiresWindow(dispatcher.connect); */ dispatcher.features.push( function (e) { - if ("click" === e.type) { + if ('click' === e.type) { if (e.clientX === 0 && e.clientY === 0 && !e.detail) { // this allows the click to dispatch as well // but note the tap event will fire first var cp = utils.clone(e); - cp.type = "tap"; + cp.type = 'tap'; cp.preventDefault = utils.nop; dispatcher.dispatch(cp); } @@ -292,12 +292,12 @@ var _xy = {}; dispatcher.features.push( function (e) { if ( - (e.type == "mousemove") || - (e.type == "tap") || - (e.type == "click") || - (e.type == "touchmove") + (e.type == 'mousemove') || + (e.type == 'tap') || + (e.type == 'click') || + (e.type == 'touchmove') ) { - var evt = (e.type == "touchmove") ? e.touches[0] : e; + var evt = (e.type == 'touchmove') ? e.touches[0] : e; _xy.clientX = evt.clientX; _xy.clientY = evt.clientY; // note only ie8 does not support pageX/pageY @@ -344,7 +344,7 @@ dispatcher.getPosition = function () { * 417 : 'fastforward' * }); * ``` -* +* * @private */ dispatcher.features.push(function(e) { @@ -407,7 +407,7 @@ utils.mixin(dispatcher, { */ captures: [], - /** + /** * Captures [events]{@glossary event} for `inTarget`, where `inEvents` is specified as a * hash of event names mapped to callback handler names to be called on `inTarget` (or, * optionally, `inScope`). The callback is called when any of the captured events are @@ -424,7 +424,7 @@ utils.mixin(dispatcher, { /** * Removes the specified target from the capture list. - * + * * @private */ release: function(inTarget) { @@ -439,7 +439,7 @@ utils.mixin(dispatcher, { /** * Sets the information for a captured {@glossary event}. - * + * * @private */ setCaptureInfo: function(inInfo) { @@ -453,7 +453,7 @@ utils.mixin(dispatcher, { (function () { /** * Dispatcher preview feature - * + * * Allows {@link module:enyo/Control~Control} ancestors of the {@glossary event} target * a chance (eldest first) to react by implementing `previewDomEvent`. * From 215a62ba1ddef53881bcf0527660808afd28505b Mon Sep 17 00:00:00 2001 From: Anish_Ramesan Date: Fri, 11 Mar 2016 21:53:10 +0530 Subject: [PATCH 164/210] updated scene active state Enyo-DCO-1.1-Signed-off-by: Anish Ramesan --- src/AnimationSupport/Actor.js | 2 +- src/AnimationSupport/Editor.js | 10 +- src/AnimationSupport/Scene.js | 45 +++-- test/tests/Director.js | 356 +++++++++++++++++++++++++++++++++ test/tests/Frame.js | 89 +++++++++ test/tests/Vector.js | 117 +++++++++++ 6 files changed, 595 insertions(+), 24 deletions(-) create mode 100644 test/tests/Director.js create mode 100644 test/tests/Frame.js create mode 100644 test/tests/Vector.js diff --git a/src/AnimationSupport/Actor.js b/src/AnimationSupport/Actor.js index ac0fe465d..2c291466b 100644 --- a/src/AnimationSupport/Actor.js +++ b/src/AnimationSupport/Actor.js @@ -112,7 +112,7 @@ Actor.makeScene = function(actor) { * @memberOf module:enyo/AnimationSupport/Actor * @public */ - active: false, + active: _actor && _actor.generated, /** * Holds refereneces of complete time span for this scene. diff --git a/src/AnimationSupport/Editor.js b/src/AnimationSupport/Editor.js index b7daadb3c..82db441f0 100644 --- a/src/AnimationSupport/Editor.js +++ b/src/AnimationSupport/Editor.js @@ -24,7 +24,7 @@ module.exports = { /** * @private */ - seekInterval:0, + seekInterval: 0, /** * @private */ @@ -178,6 +178,7 @@ module.exports = { actor.seekInterval = actor.timeline + seek; if (actor.seekInterval < 0) { actor.speed = 0; + actor.seekInterval = 0; } }, @@ -190,9 +191,7 @@ module.exports = { */ rolePlay: function (t, actor) { actor = actor || this; - if (actor.timeline === undefined || actor.timeline < 0) - actor.timeline = 0; - + if(actor.delay > 0) { actor.delay -= _rolePlay(t, actor.speed); } else { @@ -205,6 +204,9 @@ module.exports = { actor.speed = 0; } } + + if (actor.timeline === undefined || actor.timeline < 0) + actor.timeline = 0; return actor.timeline; } }; diff --git a/src/AnimationSupport/Scene.js b/src/AnimationSupport/Scene.js index a26da7f65..686c3e1d9 100644 --- a/src/AnimationSupport/Scene.js +++ b/src/AnimationSupport/Scene.js @@ -51,28 +51,35 @@ var SceneAction = { tm = this.timeline, th = this.threshold || this.span; - s = Actor.animateAtTime(this.rolePlays, tm); - e = Actor.animateAtTime(this.rolePlays, tm + th); + if (this.rolePlays && this.rolePlays.length > 0 ) { + s = Actor.animateAtTime(this.rolePlays, tm); + e = Actor.animateAtTime(this.rolePlays, tm + th); - for (i = 0; - (role = this.rolePlays[i]); i++) { - actor = role.actor; - actor.active = true; - if (i < s) { - actor.timeline = role.dur; - pose = actor.action(0, pose); - actor.cut(); - } else if (i >= s && i < e) { - sts += ts; - actor.speed = this.speed; - pose = actor.action(ts, pose); - } else { - pose = actor.action(0, pose); - actor.cut(); + for (i = 0; + (role = this.rolePlays[i]); i++) { + actor = role.actor; + if (i < s) { + actor.active = true; + actor.timeline = role.dur; + pose = actor.action(0, pose); + actor.cut(); + } else if (i >= s && i < e) { + actor.active = true; + sts += ts; + actor.speed = this.speed; + pose = actor.action(ts, pose); + } else { + if (actor.active) { + pose = actor.action(0, pose); + actor.cut(); + } + } } + tm = this.rolePlay(sts); + return pose; } - tm = this.rolePlay(sts); - return pose; + + return actor.action(ts, pose); } }; diff --git a/test/tests/Director.js b/test/tests/Director.js new file mode 100644 index 000000000..0a3e6e9ca --- /dev/null +++ b/test/tests/Director.js @@ -0,0 +1,356 @@ +var expect = chai.expect; +var trialactor1 = "actorOne"; +var trialactor2 = "actorTwo"; + +describe("Director", function() { + + describe ("Roll Method",function () { + + it("Director should have Roll method", function() { + expect(Director).to.respondTo('roll'); + }); + + it("Calling Roll method with no argument throw error", function() { + expect(Director.roll).to.throw(Error,'No arguments Passed'); + }); + + it("Passing ungenerated scene to roll method return 'scene.active' as true", function() { + var scene = Scene({}); + Scene.link(trialactor1, scene); + Director.roll(scene); + expect(scene.active).to.equal(true); + }); + + it("Passing generated scene to roll method return 'scene.active' as false", function() { + var scene = Scene({}); + var actor = document.getElementById('demo_actor'); + actor.generated = true; + actor.hasNode = function() { + return this.generated && (this.node || this.findNodeById()); + } + actor.findNodeById = function() { + return this; + } + Scene.link(actor, scene); + Director.roll(scene); + expect(scene.active).to.equal(false); + }); + + }); + + describe("Take Method",function () { + + it("Director should have Take method", function() { + expect(Director).to.respondTo('take'); + }); + + it("Calling take method with no argument throw error", function() { + expect(Director.take).to.throw(Error,'No arguments Passed'); + }); + + it("Passing generated scene and setting framespeed return 'scene.animating' as true", function() { + var scene = Scene({}); + scene.addAnimation({ + rotate: "180, 10, 10" + }, 1000); + var actor = document.getElementById('demo_actor'); + actor.generated = true; + actor.hasNode = function() { + return this.generated && (this.node || this.findNodeById()); + } + actor.findNodeById = function() { + return this; + } + actor.node = actor; + Scene.link(actor, scene); + scene.generated = true; + scene._frameSpeed = 1; + + Director.take(scene,50); + expect(scene.animating).to.equal(true); + }); + + it("Passing non-generated scene and setting framespeed as 0 to take method return 'scene.animating' as false", function() { + var scene = Scene({}); + scene.addAnimation({ + rotate: "180, 10, 10" + }, 1000); + var actor = document.getElementById('demo_actor'); + actor.generated = true; + actor.hasNode = function() { + return this.generated && (this.node || this.findNodeById()); + } + actor.findNodeById = function() { + return this; + } + actor.node = actor; + Scene.link(actor, scene); + scene.generated = false; + Director.take(scene,50); + expect(scene.animating).to.equal(false); + }); + + it("Passing 'scene._frameSpeed = 0' return 'scene.active' as false", function() { + var scene = Scene({}); + var actor = {name:'actor',generated:true}; + Scene.link(actor, scene); + scene.generated = true; + Director.take(scene,5); + expect(scene.animating).to.equal(false); + }); + + it("when scene.totalSpan is lesser than ts, return 'scene.animating' as true", function() { + var scene = Scene({}); + scene.addAnimation({ + rotate: "180, 10, 10" + }, 1000); + var actor = document.getElementById('demo_actor'); + actor.generated = true; + actor.hasNode = function() { + return this.generated && (this.node || this.findNodeById()); + } + actor.findNodeById = function() { + return this; + } + actor.node = actor; + Scene.link(actor, scene); + scene.generated = true; + scene._frameSpeed = 1; + Director.take(scene,50); + expect(scene.animating).to.equal(true); + }); + + it("when scene.totalSpan is greater than ts, return 'scene.animating' as false", function() { + var scene = Scene({}); + scene.addAnimation({ + rotate: "180, 10, 10" + }, 100); + var actor = {name:'actor',generated:true}; + Scene.link(actor, scene); + scene.generated = true; + scene._frameSpeed = 1; + Director.take(scene,1000); + expect(scene.animating).to.equal(false); + }); + + it("when ts is greater than 'scene.totalSpan', then 'scene.timeline' is equal to total scene duration", function() { + var scene = Scene({}); + scene.addAnimation({ + rotate: "180, 10, 10" + }, 100); + var actor = document.getElementById('demo_actor'); + actor.generated = true; + actor.hasNode = function() { + return this.generated && (this.node || this.findNodeById()); + } + actor.findNodeById = function() { + return this; + } + actor.node = actor; + Scene.link(actor, scene); + scene.generated = true; + scene._frameSpeed = 1; + Director.take(scene,1000); + expect(scene.timeline).to.equal(100); + }); + }); + + describe("Action Method",function () { + + it("Director should have 'action' method", function() { + expect(Director).to.respondTo('action'); + }); + + it("Calling action method with no argument throw error", function() { + expect(Director.action).to.throw(Error,'No arguments Passed'); + }); + + it("Scene.currentAnimPosIndex should be 0 by default",function () { + var scene = Scene({}); + expect(scene.currentAnimPosIndex).to.equal(0); + }); + + it("At animPos index 0, previous duration of scene should be zero",function () { + var scene = Scene({}); + scene.addAnimation({ + rotate: "180, 10, 10" + }, 100); + scene.addAnimation({ + translate: "180, 10, 10" + }, 100); + var actor = document.getElementById('demo_actor'); + actor.generated = true; + actor.hasNode = function() { + return this.generated && (this.node || this.findNodeById()); + } + actor.findNodeById = function() { + return this; + } + actor.node = actor; + Director.action(actor, scene, 50); + expect(scene.prevDur).to.equal(0); + }); + + it("At animPos index n, previous duration of scene should be duration of index (n-1)",function () { + var scene = Scene({}); + scene.addAnimation({ + rotate: "180, 10, 10" + }, 100); + scene.addAnimation({ + translate: "180, 10, 10" + }, 100); + var actor = document.getElementById('demo_actor'); + actor.generated = true; + actor.hasNode = function() { + return this.generated && (this.node || this.findNodeById()); + } + actor.findNodeById = function() { + return this; + } + actor.node = actor; + Director.action(actor, scene, 150); + expect(scene.prevDur).to.equal(100); + }); + + }); + + describe("cut Method",function () { + + it("Director should have 'cut' method", function() { + expect(Director).to.respondTo('cut'); + }); + + it("Calling cut method with no argument throw error", function() { + expect(Director.action).to.throw(Error,'No arguments Passed'); + }); + + }); + + describe("cast Method",function () { + + it("Director should have 'cast' method", function() { + expect(Director).to.respondTo('cast'); + }); + + it("Calling cast method with no argument throw error", function() { + expect(Director.cast).to.throw(Error,'No arguments Passed'); + }); + + it("calling cast method should link the actors to the scene", function() { + var scene = Scene({}); + Director.cast('actor1',scene); + Director.cast('actor2',scene); + + var obj = scene.rolePlays; + var firstValue = obj[Object.keys(obj)[0]]; + var v1 = firstValue[Object.keys(firstValue)[0]]; + var v2 = firstValue[Object.keys(firstValue)[1]]; + expect(v1).to.equal("actor1"); + }); + + }); + + describe("reject Method",function () { + + it("Director should have 'reject' method", function() { + expect(Director).to.respondTo('reject'); + }); + + it("Calling reject method with no argument throw error", function() { + expect(Director.reject).to.throw(Error,'No arguments Passed'); + }); + + it("calling reject method should delink the actors from the scene", function() { + var scene = Scene({}); + Scene.link('actor1', scene); + Scene.link('actor2', scene); + Director.reject(scene,'actor1'); + var obj = scene.rolePlays; + var firstValue = obj[Object.keys(obj)[0]]; + var v1 = firstValue[Object.keys(firstValue)[0]]; + var v2 = firstValue[Object.keys(firstValue)[1]]; + expect(v1).to.not.equal("actor1"); + }); + + }); + + describe('First shot Method',function () { + + it("Director should have 'firstShot' method", function() { + expect(Director).to.respondTo('firstShot'); + }); + + it("Calling firstShot method with no argument throw error", function() { + expect(Director.firstShot).to.throw(Error,'No arguments Passed'); + }); + + it('actor._initialPose must be equal to frame.getComputedProperty',function () { + var actor = document.getElementById('demo_actor'); + actor.generated = true; + actor.hasNode = function() { + return this.generated && (this.node || this.findNodeById()); + } + actor.findNodeById = function() { + return this; + } + actor.node = actor; + + var frame_computedProperty = Frame.getComputedProperty(actor, undefined); + frame_computedProperty.duration = 0; + Director.firstShot(actor); + expect(actor._initialPose).eql(frame_computedProperty); + }); + + it('actor._initialPoses should have keys of "_startAnim","_endAnim","_transform","currentState","matrix","props","duration"',function () { + var actor = document.getElementById('demo_actor'); + actor.generated = true; + actor.hasNode = function() { + return this.generated && (this.node || this.findNodeById()); + } + actor.findNodeById = function() { + return this; + } + actor.node = actor; + Director.firstShot(actor); + expect(actor._initialPose).to.have.all.keys('_startAnim', '_endAnim','_transform','currentState','matrix','props','duration'); + }); + + }); + + describe("shot Method",function () { + + it("Director should have 'shot' method", function() { + expect(Director).to.respondTo('shot'); + }); + + it("Calling action method with no argument throw error", function() { + expect(Director.shot).to.throw(Error,'No arguments Passed'); + }); + + }); + + describe('Angle Method',function () { + + it("Director should have 'reject' method", function() { + expect(Director).to.respondTo('angle'); + }); + + it("Calling Angle method with no argument should return 'dX'", function() { + expect(Director.angle()).to.equal('dX'); + }); + + it("Calling Angle method with argument 'X' should return 'dX'", function() { + expect(Director.angle('X')).to.equal('dX'); + }); + + it("Calling Angle method with argument 'Y' should return 'dX'", function() { + expect(Director.angle('Y')).to.equal('dY'); + }); + + it("Calling Angle method with argument 'Z' should return 'dZ'", function() { + expect(Director.angle('Z')).to.equal('dZ'); + }); + + }); + +}); diff --git a/test/tests/Frame.js b/test/tests/Frame.js new file mode 100644 index 000000000..ae3132e33 --- /dev/null +++ b/test/tests/Frame.js @@ -0,0 +1,89 @@ +var expect = chai.expect; +var elem = document.getElementById("elem"); +elem.style.webkitTransform = "matrix3d(1.02496,-0.001491,0,0.001489,0.175375,0.283378,0,-0.002232,0,0,1,0,-8,67,0,1)"; +describe("Vector", function() { + + describe("recomposeMatrix", function() { + it("should combine rotate translate skew perspective and scale matrix to return final matrix", function() { + var a = [1,2,3,3]; + var b = [1,3,3,3]; + var c = [4,5,6,7]; + var d = [5,-2,4,5]; + expect(frame.recomposeMatrix(a,b,c,d,a).toString()).to.equal([-140,-60,144,0,-604,-395,792,0,616,-140,-114,0,1,2,3,1].toString()); + }); + }); + + describe("getStyleValues", function() { + it("should return queried style property from dom style", function() { + expect(frame.getStyleValue(elem.style,"opacity")).to.equal(0); + }); + }); + + describe("getMatrix", function() { + it("should return current transform matrix from dom", function() { + var initial = {opacity:0}; var finalProp = {opacity:1}; + var transform = [1.02496,-0.001491,0,0.001489,0.175375,0.283378,0,-0.002232,0,0,1,0,-8,67,0,1]; + expect(frame.getMatrix(elem.style,"transform").toString()).to.equal(transform.toString()); + }); + }); + describe("setTransformProperty", function() { + it("should set given matrix directly to dom", function() { + var prop = "matrix3d(-140, -60, 144, 0, -604, -395, 792, 0, 616, -140, -114, 0, 1, 2, 3, 1)"; + var mat =[-140, -60, 144, 0, -604, -395, 792, 0, 616, -140, -114, 0, 1, 2, 3, 1]; + frame.setTransformProperty(elem,mat); + expect(elem.style.transform).to.equal(prop); + }); +}); + + describe("setProperty", function() { + it("should set given css property directly to dom", function() { + frame.setProperty(elem,"top",[20]); + expect(elem.style.top).to.equal("20px"); + }); +}); + + describe("decomposeMatrix", function() { + var mat = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, -408, 0, 1]; + var ret = {}; + frame.decomposeMatrix(mat,ret); + it("should extract matrix corresponding to perspective", function() { + expect(ret.perspective.toString()).to.equal([0,0,0,0].toString()); + }); + it("should extract matrix corresponding to translate", function() { + expect(ret.translate.toString()).to.equal([0,-408,0].toString()); + }); + it("should extract matrix corresponding to scale", function() { + expect(ret.scale.toString()).to.equal([1,1,1].toString()); + }); + it("should extract matrix corresponding to rotate", function() { + expect(ret.rotate.toString()).to.equal([0,0,0,1].toString()); + }); + it("should extract matrix corresponding to skew", function() { + expect(ret.skew.toString()).to.equal([0,0,0].toString()); + }); +}); + + describe("accelerate", function() { + it("should set given matrix value directly to dom", function() { + var mat = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, -408, 0, 1]; + frame.accelerate(elem,mat); + expect(elem.style.transform).to.equal("matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, -408, 0, 1)"); + }); +}); + + describe("parseMatrix", function() { + it("should set given matrix value directly to dom", function() { + var mat = "1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, -408, 0, 1"; + expect(frame.parseMatrix(mat).toString()).to.equal([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, -408, 0, 1].toString()); + }); +}); + describe("getComputedProperty", function() { + it("should set endAnim object properties as final state of animation", function() { + var prop = {opacity:1,width:"10px"}; + console.log(frame.getComputedProperty(elem,prop)); + expect(frame.getComputedProperty(elem,prop)._endAnim.opacity.toString()).to.equal("1"); + expect(frame.getComputedProperty(elem,prop)._endAnim.width.toString()).to.equal("10"); + }); +}); + +}); diff --git a/test/tests/Vector.js b/test/tests/Vector.js new file mode 100644 index 000000000..1b94d3074 --- /dev/null +++ b/test/tests/Vector.js @@ -0,0 +1,117 @@ +var expect = chai.expect; +var trialactor1 = "actorOne"; +var trialactor2 = "actorTwo"; + +describe("Vector", function() { + + describe("Add", function() { + it("should add two arrays of equal size and size greater than 3 and return sum of two in a array.", function() { + var a = [1,2,3,3]; + var b = [1,2,3,3]; + expect(Vector.add(a,b).toString()).to.equal([2,4,6,6].toString()); + }); + it("if both arrays having size greater than 3 but not equal in size should add and return array till their indexes match.", function() { + var a = [1,2,3,3,4]; + var b = [1,2,3,3]; + expect(Vector.add(a,b).toString()).to.equal([2,4,6,6].toString()); + }); + it("if both arrays having size greater than 3 but not equal in size should add and return array till their indexes match.", function() { + var a = [1,2,3,3,4]; + var b = [1,2,3]; + expect(Vector.add(a,b).toString()).to.equal([2,4,6].toString()); + }); + }); + + describe("Subtract", function() { + it("should add two arrays of equal size and size greater than 3 and return sum of two in a array.", function() { + var a = [1,2,3,3]; + var b = [1,2,3,3]; + expect(Vector.subtract(a,b).toString()).to.equal([0,0,0,0].toString()); + }); + it("if both arrays having size greater than 3 but not equal in size should add and return array till their indexes match.", function() { + var a = [1,2,3,3,4]; + var b = [1,2,3,3]; + expect(Vector.subtract(a,b).toString()).to.equal([0,0,0,0].toString()); + }); + it("if both arrays having size greater than 3 but not equal in size should add and return array till their indexes match.", function() { + var a = [1,2,3,3,4]; + var b = [1,2,3]; + expect(Vector.subtract(a,b).toString()).to.equal([0,0,0].toString()); + }); + }); + + describe("Divide", function() { + it("if array size greater than 3 function should divide first three values", function() { + var a = [6,2,8,4]; + var b = 2; + expect(Vector.divide(a,b).toString()).to.equal([3,1,4].toString()); + }); + it("should divide the array with second parameter and return result vector", function() { + var a = [6,2,8]; + var b = 2; + expect(Vector.divide(a,b).toString()).to.equal([3,1,4].toString()); + }); + + }); + + describe("Multiply", function() { + it("should multiply all values in array with second parameter", function() { + var a = [1,2,3]; + var b = 2; + expect(Vector.multiply(a,b).toString()).to.equal([2,4,6].toString()); + }); + }); + + describe("EqualS", function() { + it("should compare each values of array to given value", function() { + var a = [1,2,3]; + var b = 2; + expect(Vector.equalS(a,b)).to.equal(false); + }); + }); + describe("GreaterS", function() { + it("should compare each values of array to given value and checks whether it is greate than a given value or not", function() { + var a = [1,2,3]; + var b = 2; + expect(Vector.greaterS(a,b)).to.equal(false); + }); + }); + describe("distance", function() { + it("should calculate absolute distance between two vector given in form of array", function() { + var a = [1,2,3]; + var b = [2,3,6]; + expect(Math.round(Vector.distance(a,b))).to.equal(Math.round(Math.sqrt(11))); + }); + }); + + describe("Direction", function() { + it("should return true when all values in second parameter is greater than all values present in first array", function() { + var a = [1,2,3]; + var b = [2,3,6]; + expect(Vector.direction(a,b)).to.equal(true); + }); + }); + describe("QuantDot", function() { + it("should return dot product of two 3D vectors", function() { + var a = [1,2,3,4]; + var b = [2,3,6,5]; + expect(Vector.quantDot(a,b)).to.equal(46); + }); + }); + describe("QuantCross", function() { + it("should return Cross product of two 3D vectors as array", function() { + var a = [1,2,3,4]; + var b = [2,3,6,5]; + expect(Vector.quantCross(a,b).toString()).to.equal([ 16, 22, 38, -6 ].toString()); + }); + }); + describe("ToQuant", function() { + it("should Convert a rotation vector to a quaternion vector.", function() { + var a = [1,2,3,4]; + var b = [2,3,6,5]; + expect(Vector.toQuant().toString()).to.equal([0,0,0,1].toString()); + }); + }); +}); + + From aa64fa28208a56dc326a98d7deed5fea050293c0 Mon Sep 17 00:00:00 2001 From: Ryan Duffy Date: Fri, 11 Mar 2016 13:51:56 -0600 Subject: [PATCH 165/210] reverting usage of remove() for compatibility IE11 doesn't support node.remove() and the test for it fails for