Skip to content

Commit

Permalink
fix(menu): only one menu can be opened at a time
Browse files Browse the repository at this point in the history
fixes #6826
  • Loading branch information
manucorporat committed Jul 13, 2016
1 parent 72c24bc commit 7869c58
Show file tree
Hide file tree
Showing 8 changed files with 174 additions and 154 deletions.
115 changes: 56 additions & 59 deletions src/animations/animation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -286,22 +286,20 @@ export class Animation {
* DOM WRITE
*/
play(opts: PlayOptions = {}) {
var self = this;
var i: number;

let dur = this._dur;
if (isDefined(opts.duration)) {
self._dur = opts.duration;
dur = opts.duration;
}

console.debug('Animation, play, duration', self._dur, 'easing', self._easing);
console.debug('Animation, play, duration', dur, 'easing', this._easing);

// always default that an animation does not tween
// a tween requires that an Animation class has an element
// and that it has at least one FROM/TO effect
// and that the FROM/TO effect can tween numeric values
self.hasTween = false;
self.hasCompleted = false;
self.isPlaying = true;
this.hasTween = false;
this.hasCompleted = false;
this.isPlaying = true;

// this is the top level animation and is in full control
// of when the async play() should actually kick off
Expand All @@ -311,60 +309,60 @@ export class Animation {
// kick off the animation by setting the TO property for each animation

// ensure all past transition end events have been cleared
self._clearAsync();
this._clearAsync();

if (self._dur > 30) {
if (dur > 30) {
// this animation has a duration, so it should animate
// place all the elements with their FROM properties

// set the FROM properties
// ******** DOM WRITE ****************
self._progress(0);
this._progress(0);

// add the will-change or translateZ properties when applicable
// ******** DOM WRITE ****************
self._willChg(true);
this._willChg(true);

// set the async TRANSITION END event
// and run onFinishes when the transition ends
// ******** DOM WRITE ****************
self._asyncEnd(self._dur, true);
this._asyncEnd(dur, true);

// begin each animation when everything is rendered in their place
// and the transition duration/easing is ready to go
rafFrames(self._opts.renderDelay / 16, function() {
rafFrames(this._opts.renderDelay / 16, () => {
// there's been a moment and the elements are in place

// fire off all the "before" function that have DOM READS in them
// elements will be in the DOM, however visibily hidden
// so we can read their dimensions if need be
// ******** DOM READ ****************
self._beforeReadFn();
this._beforeReadFn();

// ******** DOM READS ABOVE / DOM WRITES BELOW ****************

// fire off all the "before" function that have DOM WRITES in them
// ******** DOM WRITE ****************
self._beforeWriteFn();
this._beforeWriteFn();

// stage all of the before css classes and inline styles
// will recursively stage all child elements
// ******** DOM WRITE ****************
self._before();
this._before();

// now set the TRANSITION duration/easing
// ******** DOM WRITE ****************
self._setTrans(self._dur, false);
this._setTrans(dur, false);

// wait a few moments again to wait for the transition
// info to take hold in the DOM
rafFrames(2, function() {
rafFrames(2, () => {
// browser had some time to render everything in place
// and the transition duration/easing is set
// now set the TO properties
// which will trigger the transition to begin
// ******** DOM WRITE ****************
self._progress(1);
this._progress(1);
});

});
Expand All @@ -373,37 +371,37 @@ export class Animation {
// this animation does not have a duration
// but we still need to apply the styles and wait
// a frame so we can accurately read the dimensions
rafFrames(self._opts.renderDelay / 16, function() {
rafFrames(this._opts.renderDelay / 16, () => {

// fire off all the "before" function that have DOM READS in them
// elements will be in the DOM, however visibily hidden
// so we can read their dimensions if need be
// ******** DOM READ ****************
self._beforeReadFn();
this._beforeReadFn();

// ******** DOM READS ABOVE / DOM WRITES BELOW ****************

// fire off all the "before" function that have DOM WRITES in them
// ******** DOM WRITE ****************
self._beforeWriteFn();
this._beforeWriteFn();

// ensure before css has ran
// ******** DOM WRITE ****************
self._before();
this._before();

// this animation does not have a duration, so it should not animate
// just go straight to the TO properties and call it done
// ******** DOM WRITE ****************
self._progress(1);
this._progress(1);

// since there was no animation, immediately run the after
// ******** DOM WRITE ****************
self._after();
this._after();

// since there was no animation, it's done
// fire off all the onFinishes
// and now you know
self._didFinish(true);
this._didFinish(true);

});
}
Expand All @@ -413,39 +411,38 @@ export class Animation {
* DOM WRITE
*/
stop(opts: PlayOptions = {}) {
var self = this;
var duration = isDefined(opts.duration) ? opts.duration : 0;
var stepValue = isDefined(opts.stepValue) ? opts.stepValue : 1;
let duration = isDefined(opts.duration) ? opts.duration : 0;
let stepValue = isDefined(opts.stepValue) ? opts.stepValue : 1;

// ensure all past transition end events have been cleared
this._clearAsync();

// set the TO properties
// ******** DOM WRITE ****************
self._progress(stepValue);
this._progress(stepValue);

if (duration > 30) {
// this animation has a duration, so it should animate
// place all the elements with their TO properties

// now set the TRANSITION duration
// ******** DOM WRITE ****************
self._setTrans(duration, true);
this._setTrans(duration, true);

// set the async TRANSITION END event
// and run onFinishes when the transition ends
// ******** DOM WRITE ****************
self._asyncEnd(duration, false);
this._asyncEnd(duration, false);

} else {
// this animation does not have a duration, so it should not animate
// just go straight to the TO properties and call it done
// ******** DOM WRITE ****************
self._after();
this._after();

// since there was no animation, it's done
// fire off all the onFinishes
self._didFinish(false);
this._didFinish(false);
}
}

Expand Down Expand Up @@ -526,12 +523,12 @@ export class Animation {
*/
_progress(stepValue: number) {
// bread 'n butter
var i: number;
var prop: string;
var fx: EffectProperty;
var val: any;
var transforms: string[];
var tweenEffect: boolean;
let i: number;
let prop: string;
let fx: EffectProperty;
let val: any;
let transforms: string[];
let tweenEffect: boolean;

for (i = 0; i < this._c.length; i++) {
// ******** DOM WRITE ****************
Expand Down Expand Up @@ -642,9 +639,9 @@ export class Animation {
* DOM WRITE
*/
_willChg(addWillChange: boolean) {
var i: number;
var wc: string[];
var prop: string;
let i: number;
let wc: string[];
let prop: string;

for (i = 0; i < this._c.length; i++) {
// ******** DOM WRITE ****************
Expand Down Expand Up @@ -680,10 +677,10 @@ export class Animation {
_before() {
// before the RENDER_DELAY
// before the animations have started
var i: number;
var j: number;
var prop: string;
var ele: HTMLElement;
let i: number;
let j: number;
let prop: string;
let ele: HTMLElement;

// stage all of the child animations
for (i = 0; i < this._c.length; i++) {
Expand Down Expand Up @@ -720,7 +717,7 @@ export class Animation {
* DOM READ
*/
_beforeReadFn() {
var i: number;
let i: number;

for (i = 0; i < this._c.length; i++) {
// ******** DOM READ ****************
Expand All @@ -737,7 +734,7 @@ export class Animation {
* DOM WRITE
*/
_beforeWriteFn() {
var i: number;
let i: number;

for (i = 0; i < this._c.length; i++) {
// ******** DOM WRITE ****************
Expand All @@ -755,10 +752,10 @@ export class Animation {
*/
_after() {
// after the animations have finished
var i: number;
var j: number;
var prop: string;
var ele: HTMLElement;
let i: number;
let j: number;
let prop: string;
let ele: HTMLElement;

for (i = 0; i < this._c.length; i++) {
// ******** DOM WRITE ****************
Expand Down Expand Up @@ -931,7 +928,7 @@ export class Animation {
_didFinish(hasCompleted: boolean) {
this.isPlaying = false;
this.hasCompleted = hasCompleted;
var i: number;
let i: number;

for (i = 0; i < this._fFns.length; i++) {
this._fFns[i](this);
Expand All @@ -957,8 +954,8 @@ export class Animation {
* DOM WRITE
*/
destroy(removeElement?: boolean) {
var i: number;
var ele: HTMLElement;
let i: number;
let ele: HTMLElement;

for (i = 0; i < this._c.length; i++) {
// ******** DOM WRITE ****************
Expand All @@ -982,8 +979,8 @@ export class Animation {
*/
_transEl(): HTMLElement {
// get the lowest level element that has an Animation
var i: number;
var targetEl: HTMLElement;
let i: number;
let targetEl: HTMLElement;

for (i = 0; i < this._c.length; i++) {
targetEl = this._c[i]._transEl();
Expand Down
28 changes: 20 additions & 8 deletions src/components/menu/menu-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ export class MenuController {
open(menuId?: string): Promise<boolean> {
let menu = this.get(menuId);
if (menu) {
let openedMenu = this.getOpen();
if (openedMenu && menu !== openedMenu) {
openedMenu.setOpen(false, false);
}
return menu.open();
}

Expand All @@ -147,7 +151,7 @@ export class MenuController {

} else {
// find the menu that is open
menu = this._menus.find(m => m.isOpen);
menu = this.getOpen();
}

if (menu) {
Expand All @@ -158,11 +162,6 @@ export class MenuController {
return Promise.resolve(false);
}

tempDisable(temporarilyDisable: boolean) {
this._menus.forEach(menu => {
menu.tempDisable(temporarilyDisable);
});
}

/**
* Toggle the menu. If it's closed, it will open, and if opened, it
Expand All @@ -173,6 +172,10 @@ export class MenuController {
toggle(menuId?: string): Promise<boolean> {
let menu = this.get(menuId);
if (menu) {
let openedMenu = this.getOpen();
if (openedMenu && menu !== openedMenu) {
openedMenu.setOpen(false, false);
}
return menu.toggle();
}
return Promise.resolve(false);
Expand Down Expand Up @@ -229,7 +232,7 @@ export class MenuController {
* provided, then it'll try to find the menu using the menu's `id`
* property. If a menu is not found then it'll return `null`.
* @param {string} [menuId] Optionally get the menu by its id, or side.
* @return {Menu} Returns the instance of the menu if found, otherwise `null`.
* @return {Menu} Returns the instance of the menu if found, otherwise `null`.
*/
get(menuId?: string): Menu {
var menu: Menu;
Expand All @@ -252,12 +255,21 @@ export class MenuController {

// return the first enabled menu
menu = this._menus.find(m => m.enabled);
if (menu) return menu;
if (menu) {
return menu;
}

// get the first menu in the array, if one exists
return (this._menus.length ? this._menus[0] : null);
}

/**
* @return {Menu} Returns the instance of the menu already opened, otherwise `null`.
*/
getOpen(): Menu {
return this._menus.find(m => m.isOpen);
}


/**
* @return {Array<Menu>} Returns an array of all menu instances.
Expand Down
2 changes: 2 additions & 0 deletions src/components/menu/menu-gestures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ export class MenuContentGesture extends SlideEdgeGesture {

if (menu.isOpen) {
return true;
} else if (menu.getMenuController().getOpen()) {
return false;
}

let cosine = Math.cos(ev.angle * (Math.PI / 180));
Expand Down
Loading

0 comments on commit 7869c58

Please sign in to comment.