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.
This commit is contained in:
parent
93e3a48004
commit
b38dea0597
25901 changed files with 9982925 additions and 369 deletions
358
gaia/shared/js/download/download_ui.js
Executable file
358
gaia/shared/js/download/download_ui.js
Executable file
|
|
@ -0,0 +1,358 @@
|
|||
'use strict';
|
||||
/* exported DownloadUI */
|
||||
/* global DownloadFormatter */
|
||||
/* global LazyLoader */
|
||||
/* global MimeMapper */
|
||||
|
||||
/**
|
||||
* This file defines a component to show download confirmations
|
||||
*
|
||||
* - Stop download (Are you sure you want to stop the download?)
|
||||
* - Download stopped (Download was stopped. Try downloading again?)
|
||||
* - Download failed (xfile failed to download. Try downloading again?)
|
||||
* - Delete download (Delete xfile?)
|
||||
* - Unsupported file type
|
||||
* - File not found
|
||||
* - File open error
|
||||
* - No provider to share file
|
||||
*
|
||||
* var request = DownloadUI.show(DownloadUI.TYPE.STOP, download);
|
||||
*
|
||||
* request.oncancel = function() {
|
||||
* alert('CANCEL');
|
||||
* };
|
||||
*
|
||||
* request.onconfirm = function() {
|
||||
* alert('CONFIRM');
|
||||
* };
|
||||
*
|
||||
* WARNING: To use this library you need to include 'shared/js/l10n.js'
|
||||
*
|
||||
*/
|
||||
var DownloadUI = (function() {
|
||||
|
||||
/**
|
||||
* Download type constructor
|
||||
*
|
||||
* @param {String} Type name
|
||||
* @param {Array} CSS classes to confirm button
|
||||
* @param {Boolean} Message without parameters
|
||||
*/
|
||||
var DownloadType = function(name, classes, isPlainMessage) {
|
||||
this.name = name;
|
||||
this.classes = classes;
|
||||
this.isPlainMessage = isPlainMessage;
|
||||
this.numberOfButtons = classes.indexOf('full') !== -1 ? 1 : 2;
|
||||
};
|
||||
|
||||
/**
|
||||
* Errors reported by the Downloads API.
|
||||
*/
|
||||
var ERRORS = {
|
||||
NO_MEMORY: 2152857616,
|
||||
NO_SDCARD: 2152857618,
|
||||
UNMOUNTED_SDCARD: 2152857621
|
||||
};
|
||||
|
||||
var TYPES = {
|
||||
STOP: new DownloadType('stop', ['danger'], true),
|
||||
STOPPED: new DownloadType('stopped', ['recommend'], true),
|
||||
FAILED: new DownloadType('failed', ['recommend']),
|
||||
DELETE: new DownloadType('delete', ['danger']),
|
||||
DELETE_ALL: new DownloadType('delete_all', ['danger']),
|
||||
UNSUPPORTED_FILE_TYPE: new DownloadType('unsupported_file_type',
|
||||
['danger']),
|
||||
FILE_NOT_FOUND: new DownloadType('file_not_found', ['recommend', 'full'],
|
||||
true),
|
||||
FILE_OPEN_ERROR: new DownloadType('file_open_error', ['danger']),
|
||||
NO_SDCARD: new DownloadType('no_sdcard_found_2', ['recommend', 'full'],
|
||||
true),
|
||||
UNMOUNTED_SDCARD: new DownloadType('unmounted_sdcard_2', ['recommend',
|
||||
'full'], true),
|
||||
NO_PROVIDER: new DownloadType('no_provider', ['recommend', 'full'], true),
|
||||
NO_MEMORY: new DownloadType('no_memory', ['recommend', 'full'], true)
|
||||
};
|
||||
|
||||
var DownloadAction = function(id, type) {
|
||||
this.id = id;
|
||||
this.name = id.toLowerCase();
|
||||
this.title = this.name + '_downloaded_file';
|
||||
this.type = type;
|
||||
};
|
||||
|
||||
var ACTIONS = {
|
||||
OPEN: new DownloadAction('OPEN', 'confirm'),
|
||||
SHARE: new DownloadAction('SHARE', 'confirm'),
|
||||
WALLPAPER: new DownloadAction('WALLPAPER', 'confirm'),
|
||||
RINGTONE: new DownloadAction('RINGTONE', 'confirm')
|
||||
};
|
||||
|
||||
// Confirm dialog containers
|
||||
var confirm = null;
|
||||
var actionMenu = null;
|
||||
|
||||
/**
|
||||
* Request auxiliary object to support asynchronous calls
|
||||
*/
|
||||
var Request = function() {
|
||||
this.cancel = function() {
|
||||
removeContainers();
|
||||
if (typeof this.oncancel === 'function') {
|
||||
this.oncancel();
|
||||
}
|
||||
};
|
||||
|
||||
this.confirm = function(result) {
|
||||
removeContainers();
|
||||
if (typeof this.onconfirm === 'function') {
|
||||
this.result = result;
|
||||
this.onconfirm({
|
||||
target: this
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
function removeContainers() {
|
||||
removeConfirm();
|
||||
removeActionMenu();
|
||||
}
|
||||
|
||||
function addConfirm() {
|
||||
if (confirm !== null) {
|
||||
confirm.parentNode.removeChild(confirm);
|
||||
}
|
||||
|
||||
confirm = document.createElement('form');
|
||||
confirm.id = 'downloadConfirmUI';
|
||||
confirm.setAttribute('role', 'dialog');
|
||||
confirm.setAttribute('data-type', 'confirm');
|
||||
confirm.setAttribute('data-z-index-level', '100');
|
||||
|
||||
var screen = document.getElementById('screen');
|
||||
var container = screen || document.body;
|
||||
|
||||
container.appendChild(confirm);
|
||||
}
|
||||
|
||||
function removeConfirm() {
|
||||
if (confirm === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
confirm.innerHTML = '';
|
||||
confirm.style.display = 'none';
|
||||
}
|
||||
|
||||
// When users click or hold on home button UIs should be removed
|
||||
window.addEventListener('home', removeContainers);
|
||||
window.addEventListener('holdhome', removeContainers);
|
||||
|
||||
function l10n(element, l10nid, l10nargs) {
|
||||
// First set our args.
|
||||
if (l10nargs) {
|
||||
element.setAttribute('data-l10n-args', JSON.stringify(l10nargs));
|
||||
}
|
||||
// Then localize.
|
||||
element.setAttribute('data-l10n-id', l10nid);
|
||||
return element;
|
||||
}
|
||||
|
||||
function createConfirm(type, req, downloads) {
|
||||
addConfirm();
|
||||
|
||||
var dialog = document.createElement('section');
|
||||
|
||||
// Header
|
||||
var header = document.createElement('h1');
|
||||
l10n(header, type.name + '_download_title');
|
||||
dialog.appendChild(header);
|
||||
|
||||
// Message
|
||||
var message = document.createElement('p');
|
||||
if (type.isPlainMessage) {
|
||||
l10n(message, type.name + '_download_message');
|
||||
} else {
|
||||
var args = Object.create(null);
|
||||
if (type === TYPES.DELETE_ALL) {
|
||||
args.number = downloads.length;
|
||||
} else {
|
||||
args.name = DownloadFormatter.getFileName(downloads[0]);
|
||||
}
|
||||
l10n(message, type.name + '_download_message', args);
|
||||
}
|
||||
dialog.appendChild(message);
|
||||
|
||||
var menu = document.createElement('menu');
|
||||
menu.dataset.items = type.numberOfButtons;
|
||||
|
||||
if (type.numberOfButtons === 2) {
|
||||
// Left button
|
||||
var lButton = document.createElement('button');
|
||||
lButton.type = 'button';
|
||||
lButton.setAttribute('data-l10n-id',
|
||||
type.name + '_download_left_button');
|
||||
|
||||
lButton.onclick = function l_cancel() {
|
||||
lButton.onclick = null;
|
||||
req.cancel();
|
||||
};
|
||||
menu.appendChild(lButton);
|
||||
}
|
||||
|
||||
// Right button
|
||||
var rButton = document.createElement('button');
|
||||
rButton.type = 'button';
|
||||
type.classes.forEach(function(clazz) {
|
||||
rButton.classList.add(clazz);
|
||||
});
|
||||
|
||||
rButton.setAttribute('data-l10n-id',
|
||||
type.name + '_download_right_button');
|
||||
|
||||
rButton.onclick = function r_confirm() {
|
||||
rButton.onclick = null;
|
||||
req.confirm();
|
||||
};
|
||||
menu.appendChild(rButton);
|
||||
|
||||
dialog.appendChild(menu);
|
||||
confirm.appendChild(dialog);
|
||||
|
||||
confirm.style.display = 'block';
|
||||
}
|
||||
|
||||
function addActionMenu() {
|
||||
// If we have an actionMenu, empty it and re-create it.
|
||||
if (actionMenu !== null) {
|
||||
document.body.removeChild(actionMenu);
|
||||
}
|
||||
actionMenu = document.createElement('gaia-menu');
|
||||
actionMenu.id = 'downloadActionMenuUI';
|
||||
actionMenu.className = 'actions';
|
||||
}
|
||||
|
||||
function removeActionMenu() {
|
||||
if (actionMenu === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
actionMenu.hide();
|
||||
document.body.removeChild(actionMenu);
|
||||
actionMenu = null;
|
||||
}
|
||||
|
||||
function createActionMenu(req, download) {
|
||||
var actions = [ACTIONS.OPEN, ACTIONS.SHARE];
|
||||
|
||||
var fileName = DownloadFormatter.getFileName(download);
|
||||
var type = MimeMapper.guessTypeFromFileProperties(fileName,
|
||||
download.contentType);
|
||||
if (type.length > 0) {
|
||||
if (type.startsWith('image/')) {
|
||||
actions.push(ACTIONS.WALLPAPER);
|
||||
} else if (type.startsWith('audio/')) {
|
||||
actions.push(ACTIONS.RINGTONE);
|
||||
}
|
||||
}
|
||||
|
||||
doCreateActionMenu(req, fileName, actions);
|
||||
}
|
||||
|
||||
function doCreateActionMenu(req, fileName, actions) {
|
||||
addActionMenu();
|
||||
|
||||
var header = document.createElement('header');
|
||||
header.textContent = fileName;
|
||||
actionMenu.appendChild(header);
|
||||
|
||||
actions.forEach(function addActionButton(action) {
|
||||
var button = document.createElement('button');
|
||||
button.id = action.id;
|
||||
l10n(button, action.title);
|
||||
button.dataset.type = action.type;
|
||||
actionMenu.appendChild(button);
|
||||
button.addEventListener('click', function buttonCliked(evt) {
|
||||
button.removeEventListener('click', buttonCliked);
|
||||
req[evt.target.dataset.type](ACTIONS[evt.target.id]);
|
||||
});
|
||||
});
|
||||
document.body.appendChild(actionMenu);
|
||||
actionMenu.removeAttribute('hidden');
|
||||
}
|
||||
|
||||
var styleSheets = [
|
||||
'shared/style/buttons.css',
|
||||
'shared/style/headers.css',
|
||||
'shared/style/confirm.css'
|
||||
];
|
||||
|
||||
/*
|
||||
* Shows a confirmation depending on type. It returns a request object with
|
||||
* oncancel and onconfirm callbacks
|
||||
*
|
||||
* @param {String} Confirmation type
|
||||
*
|
||||
* @param {Array} It represents the download(s) object(s)
|
||||
*
|
||||
* @param {Boolean} This optional parameter indicates if the library should
|
||||
* include BBs
|
||||
*/
|
||||
function show(type, downloads, ignoreStyles) {
|
||||
var req = new Request();
|
||||
|
||||
downloads = Array.isArray(downloads) ? downloads : [downloads];
|
||||
|
||||
window.setTimeout(function() {
|
||||
var libs = ['shared/js/download/download_formatter.js'];
|
||||
if (!ignoreStyles) {
|
||||
libs.push.apply(libs, styleSheets);
|
||||
}
|
||||
|
||||
// We have to discover the type of UI depending on state when type is null
|
||||
if (type === null) {
|
||||
type = TYPES.STOPPED;
|
||||
|
||||
var download = downloads[0];
|
||||
if (download.state === 'finalized' ||
|
||||
download.state === 'stopped' && download.error !== null) {
|
||||
type = TYPES.FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
LazyLoader.load(libs, createConfirm.call(this, type, req, downloads));
|
||||
}, 0);
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
function showActions(download) {
|
||||
var req = new Request();
|
||||
|
||||
window.setTimeout(function() {
|
||||
LazyLoader.load(['shared/js/mime_mapper.js',
|
||||
'shared/js/download/download_formatter.js',
|
||||
'shared/js/component_utils.js',
|
||||
'shared/elements/gaia_menu/script.js'],
|
||||
createActionMenu.call(this, req, download));
|
||||
}, 0);
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
return {
|
||||
show: show,
|
||||
|
||||
showActions: showActions,
|
||||
|
||||
hide: removeContainers,
|
||||
|
||||
get ERRORS() {
|
||||
return ERRORS;
|
||||
},
|
||||
|
||||
get TYPE() {
|
||||
return TYPES;
|
||||
}
|
||||
};
|
||||
}());
|
||||
Loading…
Reference in a new issue