Browse files

Merge pull request #2226 from alivedise/fix-modal-dialog-for-systemapp

[F] #2216 -- modal dialog for individual app frame
  • Loading branch information...
2 parents 5803383 + 1e44c4f commit 1c20261fb5f48a7e6f2a335329263f85da644dcd @timdream timdream committed Jul 9, 2012
Showing with 89 additions and 69 deletions.
  1. +80 −60 apps/system/js/modal_dialog.js
  2. +9 −9 apps/system/js/windows/window_manager.js
View
140 apps/system/js/modal_dialog.js
@@ -8,9 +8,6 @@
// (alert/confirm/prompt)
var ModalDialog = {
- // this attribute indicates if modal dialog is shown now.
- blocked: false,
-
// Used for element id access.
// e.g., 'modal-dialog-alert-ok'
prefix: 'modal-dialog-',
@@ -39,8 +36,10 @@ var ModalDialog = {
this.screen = document.getElementById('screen');
},
- // Save the event returned by mozbrowsershowmodalprompt for later use.
- evt: null,
+ // Save the events returned by mozbrowsershowmodalprompt for later use.
+ // The events are stored according to webapp origin
+ // e.g., 'http://uitest.gaiamobile.org': evt
+ currentEvents: {},
init: function md_init() {
// Get all elements initially.
@@ -49,6 +48,8 @@ var ModalDialog = {
// Bind events
window.addEventListener('mozbrowsershowmodalprompt', this);
+ window.addEventListener('appopen', this);
+ window.addEventListener('appwillclose', this);
for (var id in elements) {
if (elements[id].tagName.toLowerCase() == 'button') {
@@ -62,17 +63,17 @@ var ModalDialog = {
var elements = this.elements;
switch (evt.type) {
case 'mozbrowsershowmodalprompt':
- evt.preventDefault();
- this.blocked = true;
+ if (evt.target.dataset.frameType != 'window')
+ return;
- // check if there is another modal dialog now.
- // unblock the previous mozbrowsershowmodalprompt event
- if (this.evt && this.evt.detail.unblock) {
- this.evt.detail.unblock();
- }
+ evt.preventDefault();
+ var origin = evt.target.dataset.frameOrigin;
+ this.currentEvents[origin] = evt;
- this.evt = evt;
- this.show();
+ // Show modal dialog only if
+ // the frame is currently displayed.
+ if (origin == WindowManager.getDisplayedApp())
+ this.show(origin);
break;
case 'click':
@@ -83,99 +84,119 @@ var ModalDialog = {
this.confirmHandler();
}
break;
+
+ case 'appopen':
+ this.show(evt.detail.origin);
+ break;
+
+ case 'appwillclose':
+ // Do nothing if the app is closed at background.
+ if (evt.detail.origin !== this.currentOrigin)
+ return;
+
+ // Reset currentOrigin
+ this.hide();
+ break;
}
},
// Show relative dialog and set message/input value well
- show: function md_show() {
- var message = this.evt.detail.message;
- var elements = this.elements;
- this.screen.classList.add('modal-dialog');
-
- switch (this.evt.detail.promptType) {
- case 'alert':
- elements.alertMessage.textContent = message;
- elements.alert.classList.add('visible');
- break;
-
- case 'prompt':
- elements.prompt.classList.add('visible');
- elements.promptInput.value = this.evt.detail.initialValue;
- elements.promptMessage.textContent = message;
- break;
-
- case 'confirm':
- elements.confirm.classList.add('visible');
- elements.confirmMessage.textContent = message;
- break;
- }
+ show: function md_show(origin) {
+ this.currentOrigin = origin;
+ var evt = this.currentEvents[origin];
+
+ var message = evt.detail.message;
+ var elements = this.elements;
+ this.screen.classList.add('modal-dialog');
+
+ switch (evt.detail.promptType) {
+ case 'alert':
+ elements.alertMessage.textContent = message;
+ elements.alert.classList.add('visible');
+ break;
+
+ case 'prompt':
+ elements.prompt.classList.add('visible');
+ elements.promptInput.value = evt.detail.initialValue;
+ elements.promptMessage.textContent = message;
+ break;
+
+ case 'confirm':
+ elements.confirm.classList.add('visible');
+ elements.confirmMessage.textContent = message;
+ break;
+ }
+ },
+
+ hide: function md_hide() {
+ this.currentOrigin = null;
+ this.screen.classList.remove('modal-dialog');
},
// When user clicks OK button on alert/confirm/prompt
confirmHandler: function md_confirmHandler() {
this.screen.classList.remove('modal-dialog');
var elements = this.elements;
- switch (this.evt.detail.promptType) {
+ var evt = this.currentEvents[this.currentOrigin];
+
+ switch (evt.detail.promptType) {
case 'alert':
elements.alert.classList.remove('visible');
break;
case 'prompt':
- this.evt.detail.returnValue = elements.promptInput.value;
+ evt.detail.returnValue = elements.promptInput.value;
elements.prompt.classList.remove('visible');
break;
case 'confirm':
- this.evt.detail.returnValue = true;
+ evt.detail.returnValue = true;
elements.confirm.classList.remove('visible');
break;
}
- if (this.evt.isPseudo && this.evt.callback) {
- this.evt.callback(this.evt.detail.returnValue);
+ if (evt.isPseudo && evt.callback) {
+ evt.callback(evt.detail.returnValue);
}
- this.evt.detail.unblock();
+ evt.detail.unblock();
- // Let WindowManager know it can return to home now.
- this.blocked = false;
- this.evt = null;
+ delete this.currentEvents[this.currentOrigin];
},
// When user clicks cancel button on confirm/prompt or
// when the user try to escape the dialog with the escape key
cancelHandler: function md_cancelHandler() {
+ var evt = this.currentEvents[this.currentOrigin];
this.screen.classList.remove('modal-dialog');
var elements = this.elements;
- switch (this.evt.detail.promptType) {
+ switch (evt.detail.promptType) {
case 'alert':
elements.alert.classList.remove('visible');
break;
case 'prompt':
/* return null when click cancel */
- this.evt.detail.returnValue = null;
+ evt.detail.returnValue = null;
elements.prompt.classList.remove('visible');
break;
case 'confirm':
/* return false when click cancel */
- this.evt.detail.returnValue = false;
+ evt.detail.returnValue = false;
elements.confirm.classList.remove('visible');
break;
}
- if (this.evt.isPseudo && this.evt.callback) {
- this.evt.callback(this.evt.detail.returnValue);
+ if (evt.isPseudo && evt.callback) {
+ evt.callback(evt.detail.returnValue);
}
- this.evt.detail.unblock();
+ evt.detail.unblock();
- // Let WindowManager know it can return to home now.
- this.blocked = false;
- this.evt = null;
+ delete this.currentEvents[this.currentOrigin];
},
// The below is for system apps to use.
@@ -206,10 +227,6 @@ var ModalDialog = {
},
showWithPseudoEvent: function md_showWithPseudoEvent(config) {
- if (this.evt && this.evt.detail.unblock) {
- this.evt.detail.unblock();
- }
-
var pseudoEvt = {
isPseudo: true,
detail: {
@@ -223,8 +240,11 @@ var ModalDialog = {
if (config.type == 'prompt') {
pseudoEvt.detail.initialValue = config.initialValue;
}
- this.evt = pseudoEvt;
- this.show();
+
+ // Create a virtual mapping in this.currentEvents,
+ // since system-app uses the different way to call ModalDialog.
+ this.currentEvents['system'] = pseudoEvt;
+ this.show('system');
}
};
View
18 apps/system/js/windows/window_manager.js
@@ -161,6 +161,12 @@ var WindowManager = (function() {
} else if (classes.contains('faded') && prop === 'opacity') {
openFrame.setVisible(true);
openFrame.focus();
+
+ // Dispatch a 'appopen' event,
+ // Modal dialog would use this.
+ var evt = document.createEvent('CustomEvent');
+ evt.initCustomEvent('appopen', true, false, { origin: displayedApp });
+ openFrame.dispatchEvent(evt);
setTimeout(openCallback);
} else if (classes.contains('close') && prop === 'color') {
@@ -192,7 +198,7 @@ var WindowManager = (function() {
// The keyboard uses this and the appclose event to know when to close
// See https://github.com/andreasgal/gaia/issues/832
var evt = document.createEvent('CustomEvent');
- evt.initCustomEvent('appwillclose', true, false, {});
+ evt.initCustomEvent('appwillclose', true, false, { origin: origin });
closeFrame.dispatchEvent(evt);
// Take keyboard focus away from the closing window
@@ -671,16 +677,11 @@ var WindowManager = (function() {
// homescreen. Unlike the Home key, apps can intercept this event
// and use it for their own purposes.
if (e.keyCode === e.DOM_VK_ESCAPE &&
- !ModalDialog.blocked &&
!e.defaultPrevented &&
displayedApp !== null) {
setDisplayedApp(null); // back to the homescreen
}
-
- if (e.keyCode === e.DOM_VK_ESCAPE && ModalDialog.blocked) {
- ModalDialog.cancelHandler();
- }
});
// Handle the Home key with capturing event listeners so that
@@ -747,7 +748,7 @@ var WindowManager = (function() {
// the we also itnore it
// Otherwise, make the homescreen visible.
// Also, if the card switcher is visible, then hide it.
- if (!ModalDialog.blocked && !LockScreen.locked && !e.defaultPrevented) {
+ if (!LockScreen.locked && !e.defaultPrevented) {
// The attention screen can 'eat' this event
if (!e.defaultPrevented)
setDisplayedApp(null);
@@ -766,8 +767,7 @@ var WindowManager = (function() {
// and if the card switcher is not already shown
timer = null;
- if (!ModalDialog.blocked &&
- !LockScreen.locked &&
+ if (!LockScreen.locked &&
!CardsView.cardSwitcherIsShown()) {
CardsView.showCardSwitcher();
}

0 comments on commit 1c20261

Please sign in to comment.