VulpesOS/gaia/tv_apps/app-deck/js/context_menu.js
OverSu b38dea0597 Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
2026-09-30 23:13:03 +02:00

252 lines
8 KiB
JavaScript
Executable file

'use strict';
/* global MozActivity, Applications, BookmarkManager, SmartModalDialog */
/* jshint nonew: false */
(function(exports) {
/**
* It handles everything related to contextmenu in app-deck.
*
* @class ContextMenu
* @requires Applications
* @requires SharedUtils
*/
var ContextMenu = function() {
};
ContextMenu.prototype = {
pinToHomeElem: document.getElementById('pin-to-home'),
unpinFromHomeElem: document.getElementById('unpin-from-home'),
mainSection: document.getElementById('main-section'),
removeElem: document.getElementById('remove-card'),
contextMenuElem: document.getElementById('context-menu'),
_appDeck: undefined,
_target: {},
/**
* Initialize ContextMenu
*
* @public
* @method ContextMenu#init
* @param {AppDeck} appDeck - instance of {@link AppDeck}
*/
init: function cm_init(appDeck) {
this._appDeck = appDeck;
this._appDeck.on('focus', this.onFocus.bind(this));
this._bookmarkManager = BookmarkManager;
this._modalDialog = new SmartModalDialog();
this.pinToHomeElem.addEventListener('click', this.pinOrUnpin.bind(this));
this.unpinFromHomeElem.addEventListener(
'click', this.pinOrUnpin.bind(this));
this.removeElem.addEventListener('click', this.onRemove.bind(this));
this._modalDialog.container.addEventListener('modal-dialog-closed',
this._appDeck.enableNavigation.bind(this._appDeck));
this._modalDialog.container.addEventListener('modal-dialog-will-open',
this._appDeck.disableNavigation.bind(this._appDeck));
},
_selfApp: undefined,
/**
* Underlying function which actual send string message on 'appdeck-channel'
*
* @private
* @method ContextMenu#_connectAndSend
* @param {String} message - the message which will be sent on
* 'appdeck-channel'
*/
_connectAndSend: function cm_sendMessage(message) {
this._selfApp.connect('appdeck-channel').then(function (ports) {
ports.forEach(function(port) {
port.postMessage(message);
});
});
},
/**
* Send message on 'appdeck-channel' using Inter-App Communication.
* smart-home will monitor this channel. Currently we use this channel to
* tell smart-home to what app we would like to unpin.
*
* @public
* @method ContextMenu#sendMessage
* @param {String} type - message type, which must be 'unpin' for now.
* @param {Object} data - message data in JSON object format
*/
sendMessage: function cm_sendMessage(type, data) {
var that = this;
var message = {
type: type,
data: data
};
if (this._selfApp) {
this._connectAndSend(message);
} else {
navigator.mozApps.getSelf().onsuccess = function(evt) {
that._selfApp = evt.target.result;
that._connectAndSend(message);
};
}
},
/**
* To tell smart-home what app we would like to unpin
*
* @private
* @method ContextMetnu#_sendUnpinMessage
* @param {HTMLElement} cardElem - the card we'd like to unpin from Home
*/
_sendUnpinMessage: function cm_sendUnpinMessage(cardElem) {
var type = cardElem.getAttribute('app-type');
if (type === 'app') {
// Notice that here we didn't specify launchURL because we assume all
// 'Application' in app-deck are launched by calling app.launch().
// However, in the case of other deck-like app, if we are going to pin
// application which is launched by different launchURL, we must specify
// 'launchURL' here.
this.sendMessage('unpin', {
manifestURL: cardElem.dataset.manifestURL
});
} else if (type === 'bookmark') {
this.sendMessage('unpin', {
url: cardElem.dataset.url
});
}
},
/**
* Based on currently focused SmartButton, we'll decide we are going to
* pin or unpin the app. This function is invoked when we get 'click' event
* on pinToHomeElem. Notice that we use `MozActivity` to pin app because we
* want to bring users to Home when they finish pinning. However we unpin
* app via IAC because we want users stay in AppDeck after unpinning.
*
* @public
* @method ContextMenu#pinOrUnpin
*/
pinOrUnpin: function cm_pinOrUnpin() {
var cardElem = this._target.elem;
var type = this._getTargetType();
var dataset = cardElem.dataset;
if (this._target.pinned) {
this._sendUnpinMessage(this._target.elem);
} else if (type === 'app') {
// XXX: preferredSize should be determined by
// real offsetWidth of cardThumbnailElem in smart-home instead of
// hard-coded value
Applications.getIconBlob(
dataset.manifestURL, dataset.entryPoint, 354, blob => {
// Notice that here we didn't specify launchURL because we assume
// all 'Application' in app-deck are launched by calling
// app.launch().
// However, in the case of other deck-like app, if we are going to
// pin application which is launched by different launchURL, we
// must specify 'launchURL' here.
new MozActivity({
name: 'pin',
data: {
type: 'Application',
group: 'application',
manifestURL: dataset.manifestURL,
// We use app's original icon instead of screenshot here
// because we are in app deck. For the case of getting
// screenshot, please refer to bug 1100238.
thumbnail: blob
}
});
});
} else if (type === 'bookmark') {
this._bookmarkManager.get(dataset.url).then(card => {
new MozActivity({
name: 'pin',
data: {
name: {raw: card.name},
type: 'AppBookmark',
group: 'application',
url: card.url,
thumbnail: card.icon
}
});
});
}
},
onRemove: function cm_onRemove() {
var type = this._getTargetType();
var elem = this._target.elem;
if (type === 'app') {
this.uninstall(elem);
} else if (type === 'bookmark') {
this._appDeck.disableNavigation();
this._modalDialog.open({
message: {
textL10nId: {
id: 'delete-bookmark-alert',
args: {
name: elem.getAttribute('label')
}
}
},
buttonSettings: [
{
textL10nId: 'cancel',
defaultFocus: true,
},
{
textL10nId: 'delete',
class: 'danger',
onClick: () => {
this._bookmarkManager.remove(elem.dataset.url);
this._sendUnpinMessage(elem);
}
}
]
});
}
},
_getTargetType: function cm_getType() {
return this._target.elem && this._target.elem.getAttribute('app-type');
},
/**
* Uninstall app represented by current focused SmartButton
* @public
* @method ContextMenu#uninstall
* @param {HTMLElement} cardElem - the card we'd like to unpin from Home
*/
uninstall: function cm_uninstall(cardElem) {
var appInstance =
Applications.installedApps[cardElem.dataset.manifestURL];
if (appInstance) {
navigator.mozApps.mgmt.uninstall(appInstance);
}
},
onFocus: function cm_onFocus(target) {
this._target = target;
this.contextMenuElem.innerHTML = '';
if (target.pinned) {
this.contextMenuElem.appendChild(this.unpinFromHomeElem);
} else {
this.contextMenuElem.appendChild(this.pinToHomeElem);
}
this.contextMenuElem.appendChild(this.removeElem);
}
};
exports.ContextMenu = ContextMenu;
})(window);