Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
299 lines
9.3 KiB
JavaScript
299 lines
9.3 KiB
JavaScript
/* global AppWindow, applications, ManifestHelper */
|
|
'use strict';
|
|
|
|
(function(exports) {
|
|
/**
|
|
* AttentionWindow is a special opened window with specific
|
|
* permission: 'attention'. It would show in front of any
|
|
* existing app windows to get users' attention.
|
|
*
|
|
* ##### Flow chart
|
|
* <a href="http://i.imgur.com/4O1Frs3.png" target="_blank">
|
|
* <img src="http://i.imgur.com/4O1Frs3.png"></img>
|
|
* </a>
|
|
*
|
|
* @example
|
|
* var attention = new AttentionWindow({
|
|
* url: 'app://clock.gaiamobile.org:8080/alarm.html',
|
|
* manifestURL: 'http://gallery.gaiamobile.org:8080/manifest.webapp',
|
|
* iframe: iframe
|
|
* });
|
|
*
|
|
* @class AttentionWindow
|
|
* @param {Object} config The configuration object of this attention.
|
|
* @extends AppWindow
|
|
*/
|
|
/**
|
|
* Fired when the attention window is created.
|
|
* @event AttentionWindow#attentioncreated
|
|
*/
|
|
/**
|
|
* Fired when the attention window is removed.
|
|
* @event AttentionWindow#attentionterminated
|
|
*/
|
|
/**
|
|
* Fired when the attention window is opening.
|
|
* @event AttentionWindow#attentionopening
|
|
*/
|
|
/**
|
|
* Fired when the attention window is opened.
|
|
* @event AttentionWindow#attentionopened
|
|
*/
|
|
/**
|
|
* Fired when the attention window is closing.
|
|
* @event AttentionWindow#attentionclosing
|
|
*/
|
|
/**
|
|
* Fired when the attention window is closed.
|
|
* @event AttentionWindow#attentionclosed
|
|
*/
|
|
/**
|
|
* Fired before the attention window will be rendered.
|
|
* @event AttentionWindow#attentionwillrender
|
|
*/
|
|
/**
|
|
* Fired when the attention window is rendered to the DOM tree.
|
|
* @event AttentionWindow#attentionrendered
|
|
*/
|
|
var AttentionWindow = function AttentionWindow(config) {
|
|
this.reConfig(config);
|
|
this.render();
|
|
if (this._DEBUG) {
|
|
AttentionWindow[this.instanceID] = this;
|
|
}
|
|
this.makeNotification();
|
|
this.publish('created');
|
|
};
|
|
|
|
AttentionWindow.prototype = Object.create(AppWindow.prototype);
|
|
|
|
AttentionWindow.prototype.constructor = AttentionWindow;
|
|
|
|
AttentionWindow.prototype.eventPrefix = 'attention';
|
|
|
|
AttentionWindow.prototype.CLASS_NAME = 'AttentionWindow';
|
|
|
|
AttentionWindow.prototype.CLASS_LIST = 'appWindow attentionWindow';
|
|
|
|
AttentionWindow.prototype.HIERARCHY_MANAGER = 'AttentionWindowManager';
|
|
|
|
/**
|
|
* Turn on this flag to dump debugging messages for all attention windows.
|
|
* @type {Boolean}
|
|
*/
|
|
AttentionWindow.prototype._DEBUG = false;
|
|
AttentionWindow.prototype.closedHeight = 40;
|
|
|
|
AttentionWindow.prototype.openAnimation = 'immediate';
|
|
AttentionWindow.prototype.closeAnimation = 'immediate';
|
|
|
|
AttentionWindow.prototype.isAttentionWindow = true;
|
|
|
|
AttentionWindow.prototype.view = function attw_view() {
|
|
this.debug('intance id: ' + this.instanceID);
|
|
return `<div class="${this.CLASS_LIST}" id="${this.instanceID}">
|
|
<div class="browser-container"></div>
|
|
</div>`;
|
|
};
|
|
|
|
AttentionWindow.SUB_COMPONENTS = {
|
|
'transitionController': 'AppTransitionController',
|
|
'modalDialog': 'AppModalDialog',
|
|
'authDialog': 'AppAuthenticationDialog',
|
|
'attentionToaster': 'AttentionToaster',
|
|
'stautsbar': 'AppStatusbar'
|
|
};
|
|
|
|
AttentionWindow.REGISTERED_EVENTS =
|
|
['mozbrowserclose', 'mozbrowsererror', 'mozbrowservisibilitychange',
|
|
'mozbrowserloadend', 'mozbrowserloadstart',
|
|
'_localized', 'click', '_willdestroy', '_languagechange'];
|
|
|
|
AttentionWindow.prototype.render = function attw_render() {
|
|
this.publish('willrender');
|
|
this.containerElement.insertAdjacentHTML('beforeend', this.view());
|
|
// the iframe is provided already.
|
|
this.browser = {
|
|
element: this.config.iframe
|
|
};
|
|
this.element = document.getElementById(this.instanceID);
|
|
this.browserContainer = this.element.querySelector('.browser-container');
|
|
this.browserContainer.insertBefore(this.browser.element, null);
|
|
this.frame = this.element;
|
|
this.iframe = this.browser.element;
|
|
|
|
this._registerEvents();
|
|
this.installSubComponents();
|
|
this.publish('rendered');
|
|
};
|
|
|
|
AttentionWindow.prototype._handle_click =
|
|
function attw__handle_click(evt) {
|
|
this.publish('will-become-active');
|
|
this.requestOpen();
|
|
};
|
|
|
|
AttentionWindow.prototype.ready = function attw_ready(callback) {
|
|
if (!this.element) {
|
|
return;
|
|
}
|
|
|
|
var self = this;
|
|
if (!this.loaded) {
|
|
this.element.addEventListener('_loaded', function onLoaded() {
|
|
self.element.removeEventListener('_loaded', onLoaded);
|
|
setTimeout(callback);
|
|
});
|
|
} else {
|
|
this.tryWaitForFullRepaint(function() {
|
|
setTimeout(callback);
|
|
});
|
|
}
|
|
};
|
|
|
|
// XXX: We may need to wait the underlying window,
|
|
// which may be attention window or app window to be painted,
|
|
// so keeping track of the request in order to handle
|
|
// |mozbrowserclose| events properly.
|
|
AttentionWindow.prototype.requestOpen = function() {
|
|
this.element.classList.remove('fake-notification');
|
|
this.element.classList.remove('notification-disappearing');
|
|
this._requestedOpen = true;
|
|
// XXX: A hack to reset height.
|
|
AppWindow.prototype.requestOpen.apply(this);
|
|
};
|
|
|
|
AttentionWindow.prototype.open = function(animation) {
|
|
this._requestedOpen = false;
|
|
AppWindow.prototype.open.apply(this);
|
|
};
|
|
|
|
/**
|
|
* Make a fake notification node inside Utility tray.
|
|
* XXX: We should make app to create this notification on their own.
|
|
* XXX: The problem is app is not able to 'launch attention window'
|
|
* in the click callback of the notification. The workaround
|
|
* might be using the same name to open the attention window again.
|
|
* And in child window factory we need to check if current attention
|
|
* window has the same name as the event detail to reopen it or kill it.
|
|
*/
|
|
AttentionWindow.prototype.makeNotification = function() {
|
|
var manifestURL = this.manifestURL;
|
|
if (this.notification || !manifestURL) {
|
|
return;
|
|
}
|
|
|
|
var manifest = applications.getByManifestURL(manifestURL).manifest;
|
|
this.manifest = this.config.manifest = manifest;
|
|
|
|
var iconSrc = manifestURL.replace(
|
|
'/manifest.webapp',
|
|
manifest.icons[Object.keys(manifest.icons)[0]]
|
|
);
|
|
|
|
// Let's create the fake notification.
|
|
var notification = document.createElement('div');
|
|
notification.id = 'notification-' + this.instanceID;
|
|
notification.classList.add('notification');
|
|
notification.classList.add('attention-notification');
|
|
|
|
var icon = document.createElement('img');
|
|
icon.src = iconSrc;
|
|
icon.classList.add('icon');
|
|
notification.appendChild(icon);
|
|
|
|
var message = document.createElement('div');
|
|
this.notificationTitle = document.createTextNode(manifest.name);
|
|
message.appendChild(this.notificationTitle);
|
|
message.classList.add('title-container');
|
|
notification.appendChild(message);
|
|
|
|
var tip = document.createElement('div');
|
|
tip.setAttribute('data-l10n-id', 'attentionScreen-tapToShow');
|
|
tip.classList.add('detail');
|
|
notification.appendChild(tip);
|
|
|
|
var container =
|
|
document.getElementById('attention-window-notifications-container');
|
|
container.insertBefore(notification, null);
|
|
|
|
// Attach an event listener to the fake notification so the
|
|
// attention screen is shown when the user tap on it.
|
|
notification.addEventListener('click',
|
|
function(evt) {
|
|
this._handle_click(evt);
|
|
}.bind(this));
|
|
this.notification = notification;
|
|
|
|
// Hide on creating.
|
|
this.notification.style.display = 'none';
|
|
|
|
this.translateNotification();
|
|
};
|
|
|
|
AttentionWindow.prototype.translateNotification = function() {
|
|
if (!this.notification) {
|
|
return;
|
|
}
|
|
|
|
var manifest = this.manifest;
|
|
var title = this.notificationTitle;
|
|
|
|
navigator.mozL10n.once(function() {
|
|
var helper = new ManifestHelper(manifest);
|
|
title.textContent = helper.name;
|
|
});
|
|
};
|
|
|
|
AttentionWindow.prototype.show = function() {
|
|
if (this.notification) {
|
|
this.translateNotification();
|
|
this.notification.style.display = 'block';
|
|
}
|
|
|
|
// Resize the window to accommodate the presence or absence of the software
|
|
// home button.
|
|
this._resize();
|
|
// Unset width because we don't need
|
|
this.element.style.width = '';
|
|
|
|
AppWindow.prototype.show.call(this);
|
|
};
|
|
|
|
AttentionWindow.prototype.hide = function() {
|
|
if (this.notification) {
|
|
this.notification.style.display = 'none';
|
|
}
|
|
AppWindow.prototype.hide.call(this);
|
|
};
|
|
|
|
AttentionWindow.prototype._handle__willdestroy = function() {
|
|
if (this.notification) {
|
|
this.notification.parentNode.removeChild(this.notification);
|
|
this.notification = null;
|
|
}
|
|
};
|
|
|
|
AttentionWindow.prototype._handle__languagechange = function() {
|
|
this.translateNotification();
|
|
};
|
|
|
|
AttentionWindow.prototype.promote = function() {
|
|
this.element && this.element.classList.add('top-most');
|
|
};
|
|
|
|
AttentionWindow.prototype.demote = function() {
|
|
this.element && this.element.classList.remove('top-most');
|
|
};
|
|
|
|
/**
|
|
* AttentionWindow's default container is '#windows'.
|
|
* However, we could dynamically change this in layout manager
|
|
* after it recieves the attentionwillrender event.
|
|
*/
|
|
AttentionWindow.prototype.containerElement =
|
|
document.getElementById('windows');
|
|
|
|
exports.AttentionWindow = AttentionWindow;
|
|
|
|
}(window));
|