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
46
gaia/shared/js/smart-screen/cards/app_bookmark.js
Executable file
46
gaia/shared/js/smart-screen/cards/app_bookmark.js
Executable file
|
|
@ -0,0 +1,46 @@
|
|||
/* global Card */
|
||||
|
||||
(function(exports) {
|
||||
'use strict';
|
||||
|
||||
function AppBookmark(options) {
|
||||
this.url = options.url;
|
||||
this.name = options.name;
|
||||
this.group = options.group;
|
||||
this.thumbnail = options.thumbnail;
|
||||
Card.prototype.constructor.call(this);
|
||||
}
|
||||
|
||||
AppBookmark.deserialize = function ab_deserialize(cardEntry) {
|
||||
var cardInstance;
|
||||
if (cardEntry && cardEntry.type === 'AppBookmark') {
|
||||
cardInstance = new AppBookmark({
|
||||
name: cardEntry.name,
|
||||
url: cardEntry.url,
|
||||
group: cardEntry.group,
|
||||
thumbnail: cardEntry.thumbnail
|
||||
});
|
||||
}
|
||||
return cardInstance;
|
||||
};
|
||||
|
||||
AppBookmark.prototype = Object.create(Card.prototype);
|
||||
|
||||
AppBookmark.prototype.constructor = AppBookmark;
|
||||
|
||||
AppBookmark.prototype.launch = function ab_launch(args) {
|
||||
window.open(this.url, '_blank', 'remote=true,applike=true');
|
||||
};
|
||||
|
||||
AppBookmark.prototype.serialize = function ab_serialize() {
|
||||
return {
|
||||
type: 'AppBookmark',
|
||||
name: this.name,
|
||||
url: this.url,
|
||||
group: this.group,
|
||||
thumbnail: this.thumbnail
|
||||
};
|
||||
};
|
||||
|
||||
exports.AppBookmark = AppBookmark;
|
||||
}(window));
|
||||
86
gaia/shared/js/smart-screen/cards/application.js
Executable file
86
gaia/shared/js/smart-screen/cards/application.js
Executable file
|
|
@ -0,0 +1,86 @@
|
|||
/* global Card */
|
||||
|
||||
(function(exports) {
|
||||
'use strict';
|
||||
|
||||
var Application = function Application(options) {
|
||||
this.nativeApp = options.nativeApp;
|
||||
this.name = options.name;
|
||||
this.cachedIconBlob = undefined;
|
||||
this.thumbnail = options.thumbnail;
|
||||
this.launchURL = options.launchURL;
|
||||
this.group = options.group;
|
||||
Card.prototype.constructor.call(this);
|
||||
};
|
||||
|
||||
Application.deserialize = function app_deserialize(cardEntry, installedApps) {
|
||||
var cardInstance;
|
||||
if (cardEntry && installedApps && cardEntry.type === 'Application') {
|
||||
cardInstance = new Application({
|
||||
nativeApp: installedApps[cardEntry.manifestURL],
|
||||
name: cardEntry.name,
|
||||
thumbnail: cardEntry.thumbnail,
|
||||
launchURL: cardEntry.launchURL,
|
||||
group: cardEntry.group
|
||||
});
|
||||
}
|
||||
return cardInstance;
|
||||
};
|
||||
|
||||
Application.prototype = Object.create(Card.prototype);
|
||||
|
||||
Application.prototype.constructor = Application;
|
||||
|
||||
// expose getter of property of nativeApp
|
||||
var exposedPropertyNames = ['manifest', 'updateManifest'];
|
||||
exposedPropertyNames.forEach(function(propertyName) {
|
||||
Object.defineProperty(Application.prototype, propertyName, {
|
||||
get: function() {
|
||||
return this.nativeApp && this.nativeApp[propertyName];
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Application.prototype.serialize = function app_serialize() {
|
||||
return {
|
||||
manifestURL: this.nativeApp.manifestURL,
|
||||
name: this.name,
|
||||
type: 'Application',
|
||||
thumbnail: this.thumbnail,
|
||||
launchURL: this.launchURL,
|
||||
group: this.group
|
||||
};
|
||||
};
|
||||
|
||||
Application.prototype.launch = function app_launch(args) {
|
||||
if (this.nativeApp && this.nativeApp.launch && !this.launchURL) {
|
||||
this.nativeApp.launch(args);
|
||||
} else {
|
||||
if (!Application._iacPort) {
|
||||
console.error('no iacPort found, we cannot launch Application');
|
||||
return;
|
||||
}
|
||||
|
||||
Application._iacPort.postMessage({
|
||||
'manifestURL': this.nativeApp.manifestURL,
|
||||
'timestamp': (new Date()).getTime(),
|
||||
'url': this.launchURL
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('load', function _retrieveIACPort() {
|
||||
window.removeEventListener('load', _retrieveIACPort);
|
||||
|
||||
navigator.mozApps.getSelf().onsuccess = function(evt) {
|
||||
var app = evt.target.result;
|
||||
if (app) {
|
||||
app.connect('customlaunchpath').then(function onAccepted(ports) {
|
||||
Application._iacPort = ports[0];
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
exports.Application = Application;
|
||||
}(window));
|
||||
40
gaia/shared/js/smart-screen/cards/card.js
Executable file
40
gaia/shared/js/smart-screen/cards/card.js
Executable file
|
|
@ -0,0 +1,40 @@
|
|||
/* global evt */
|
||||
|
||||
(function(exports) {
|
||||
'use strict';
|
||||
|
||||
var _counter = 0;
|
||||
|
||||
// Card is the base class for Application, Deck, and Folder
|
||||
var Card = function Card() {
|
||||
this.generateCardId();
|
||||
};
|
||||
|
||||
Card.deserialize = function c_deserialize(cardEntry) {
|
||||
// just to prevent undefined error
|
||||
};
|
||||
|
||||
Card.prototype = evt({
|
||||
get cardId() {
|
||||
return this._id;
|
||||
},
|
||||
generateCardId: function c_generateCardId() {
|
||||
// XXX: use constructor.name + name + incremental counter
|
||||
// as cardId for now. Notice that cardId is only meaningful for
|
||||
// Smart-Home app. Because only Smart-Home app has 'write' privilege.
|
||||
var name = (this.nativeApp && this.nativeApp.manifest) ?
|
||||
this.nativeApp.manifest.name : 'card';
|
||||
this._id = this.constructor.name + '-' + name + '-' + (_counter);
|
||||
_counter += 1;
|
||||
return this._id;
|
||||
},
|
||||
serialize: function c_serialize() {
|
||||
// just to prevent undefined error
|
||||
},
|
||||
|
||||
constructor: Card
|
||||
});
|
||||
|
||||
exports.Card = Card;
|
||||
|
||||
}(window));
|
||||
61
gaia/shared/js/smart-screen/cards/deck.js
Executable file
61
gaia/shared/js/smart-screen/cards/deck.js
Executable file
|
|
@ -0,0 +1,61 @@
|
|||
/* global Card */
|
||||
|
||||
(function(exports) {
|
||||
'use strict';
|
||||
|
||||
var Deck = function Deck(options) {
|
||||
this.nativeApp = options.nativeApp;
|
||||
this.name = options.name;
|
||||
this.deckClass = options.deckClass;
|
||||
this.group = options.group;
|
||||
Card.prototype.constructor.call(this);
|
||||
};
|
||||
|
||||
Deck.deserialize = function deck_deserialize(cardEntry, installedApps) {
|
||||
var cardInstance;
|
||||
if (cardEntry && installedApps && cardEntry.type === 'Deck') {
|
||||
cardInstance = new Deck({
|
||||
name: cardEntry.name,
|
||||
nativeApp: cardEntry.manifestURL &&
|
||||
installedApps[cardEntry.manifestURL],
|
||||
deckClass: cardEntry.deckClass,
|
||||
group: cardEntry.group
|
||||
});
|
||||
}
|
||||
return cardInstance;
|
||||
};
|
||||
|
||||
Deck.prototype = Object.create(Card.prototype);
|
||||
|
||||
Deck.prototype.constructor = Deck;
|
||||
|
||||
// expose getter of property of nativeApp
|
||||
var exposedPropertyNames = ['manifest', 'updateManifest'];
|
||||
exposedPropertyNames.forEach(function(propertyName) {
|
||||
Object.defineProperty(Deck.prototype, propertyName, {
|
||||
get: function() {
|
||||
return this.nativeApp && this.nativeApp[propertyName];
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Deck.prototype.launch = function deck_launch(args) {
|
||||
if (this.nativeApp && this.nativeApp.launch) {
|
||||
this.nativeApp.launch(args);
|
||||
}
|
||||
};
|
||||
|
||||
Deck.prototype.serialize = function deck_serialize() {
|
||||
// A deck doesn't need background color because it is always full-sized
|
||||
// icon. If not, it is an issue from visual's image.
|
||||
return {
|
||||
name: this.name,
|
||||
deckClass: this.deckClass,
|
||||
manifestURL: this.nativeApp && this.nativeApp.manifestURL,
|
||||
type: 'Deck',
|
||||
group: this.group
|
||||
};
|
||||
};
|
||||
|
||||
exports.Deck = Deck;
|
||||
}(window));
|
||||
231
gaia/shared/js/smart-screen/cards/folder.js
Executable file
231
gaia/shared/js/smart-screen/cards/folder.js
Executable file
|
|
@ -0,0 +1,231 @@
|
|||
/* global Card, uuid */
|
||||
|
||||
(function(exports) {
|
||||
'use strict';
|
||||
|
||||
var Folder = function Folder(options) {
|
||||
this._cardsInFolder = options._cardsInFolder || [];
|
||||
this.name = options.name;
|
||||
// folderId is used in cardStore as key
|
||||
this.folderId = options.folderId || uuid.v4();
|
||||
this._state = options.state || Folder.STATES.NORMAL;
|
||||
Card.prototype.constructor.call(this);
|
||||
};
|
||||
|
||||
Folder.STATES = Object.freeze({
|
||||
// when folder is in DESERIALIZING state, it means we are still in the
|
||||
// process of loading its content from datastore
|
||||
'DESERIALIZING': 'DESERIALIZING',
|
||||
'NORMAL': 'NORMAL',
|
||||
// DIRTY state means the folder is out of sync with data store
|
||||
'DIRTY': 'DIRTY',
|
||||
// DETACHED state means the folder itself is not saved (detached)
|
||||
// in card list
|
||||
'DETACHED': 'DETACHED'
|
||||
});
|
||||
|
||||
Folder.deserialize = function folder_deserialize(cardEntry) {
|
||||
var cardInstance;
|
||||
if (cardEntry && cardEntry.type === 'Folder') {
|
||||
cardInstance = new Folder({
|
||||
name: cardEntry.name,
|
||||
folderId: cardEntry.folderId,
|
||||
// The content of folder is saved in datastore under key of folderId
|
||||
// thus we are not complete deserialize it yet, mark its state
|
||||
// as 'DESERIALIZING'. Caller needs to put content of the folder
|
||||
// back to its structure. Please refer to CardManager#_reloadCardList().
|
||||
state: Folder.STATES.DESERIALIZING
|
||||
});
|
||||
}
|
||||
return cardInstance;
|
||||
};
|
||||
|
||||
Folder.prototype = Object.create(Card.prototype);
|
||||
|
||||
Folder.prototype.constructor = Folder;
|
||||
|
||||
Object.defineProperty(Folder.prototype, 'state', {
|
||||
get: function() {
|
||||
return this._state;
|
||||
},
|
||||
set: function(state) {
|
||||
this._state = state;
|
||||
this.fire('state-changed', this._state);
|
||||
}
|
||||
});
|
||||
|
||||
Folder.prototype.getCardList = function folder_getCardList() {
|
||||
return this._cardsInFolder;
|
||||
};
|
||||
|
||||
Folder.prototype.getFilteredCardList =
|
||||
function folder_getFilteredCardList(filterName) {
|
||||
if (typeof this._cardsInFolder !== 'object') {
|
||||
return;
|
||||
}
|
||||
if (filterName === 'all') {
|
||||
return this._cardsInFolder;
|
||||
} else if (filterName) {
|
||||
return this._cardsInFolder.filter(
|
||||
elem => (elem.group === filterName));
|
||||
}
|
||||
};
|
||||
|
||||
Folder.prototype.isEmpty = function folder_isEmpty() {
|
||||
return this._cardsInFolder.length === 0;
|
||||
};
|
||||
|
||||
Folder.prototype.isNotEmpty = function folder_isNotEmpty() {
|
||||
return this._cardsInFolder.length > 0;
|
||||
};
|
||||
|
||||
Folder.prototype.isDeserializing = function folder_isDeserializing() {
|
||||
return this._state === Folder.STATES.DESERIALIZING;
|
||||
};
|
||||
|
||||
Folder.prototype.isDetached = function folder_isDetached() {
|
||||
return this._state === Folder.STATES.DETACHED;
|
||||
};
|
||||
|
||||
Folder.prototype.loadCardsInFolder = function folder_loadCardsInFolder(opts) {
|
||||
var that = this;
|
||||
if (opts.from === 'config') {
|
||||
// load content of folder from config file (e.g. in 'cardEntry' form)
|
||||
this._cardsInFolder =
|
||||
opts.cardEntry._cardsInFolder.map(opts.deserializer);
|
||||
this.state = Folder.STATES.NORMAL;
|
||||
} else if (opts.from === 'datastore') {
|
||||
// load content of folder from data store
|
||||
opts.datastore.getData(this.folderId).then(function(innerCardList) {
|
||||
innerCardList.forEach(function(innerCardEntry) {
|
||||
that._cardsInFolder.push(opts.deserializer(innerCardEntry));
|
||||
});
|
||||
that.state = Folder.STATES.NORMAL;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// get index of card in folder
|
||||
Folder.prototype._indexOfCard = function folder_indexOfCard(query) {
|
||||
return this._cardsInFolder.indexOf(this.findCard(query));
|
||||
};
|
||||
|
||||
// XXX: this method shares almost the same logic as
|
||||
// findCardFromCardList in CardManager. We should consolidate them. See
|
||||
// http://bugzil.la/1156726
|
||||
// There are three types of query:
|
||||
// 1. query by cardId
|
||||
// 2. query by manifestURL and optionally launchURL
|
||||
// 3. query by bookmark url
|
||||
// 4. query by cardEntry (i.e. serialized card)
|
||||
Folder.prototype.findCard = function folder_findCard(query) {
|
||||
var found;
|
||||
this._cardsInFolder.some(function(card, index) {
|
||||
if (card.cardId === query.cardId) {
|
||||
found = card;
|
||||
return true;
|
||||
} else if (query.manifestURL && card.nativeApp &&
|
||||
card.nativeApp.manifestURL === query.manifestURL) {
|
||||
// if we specify launchURL in query, then we must compare
|
||||
// launchURL first
|
||||
if (query.launchURL) {
|
||||
if (card.launchURL === query.launchURL) {
|
||||
found = card;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
found = card;
|
||||
return true;
|
||||
}
|
||||
} else if (query.url) {
|
||||
if (query.url === card.url) {
|
||||
found = card;
|
||||
}
|
||||
return true;
|
||||
} else if (query.cardEntry) {
|
||||
// XXX: this could be bad at performance because we serialize card
|
||||
// in every loop. We might need improvement on this query.
|
||||
if (JSON.stringify(card.serialize()) ===
|
||||
JSON.stringify(query.cardEntry)) {
|
||||
found = card;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
});
|
||||
return found;
|
||||
};
|
||||
|
||||
Folder.prototype._isInFolder = function folder_isInFolder(card) {
|
||||
if (card) {
|
||||
return this._indexOfCard(card) > -1;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
Folder.prototype._setDirty = function folder_setDirty() {
|
||||
if (this._state !== Folder.STATES.DETACHED) {
|
||||
this._state = Folder.STATES.DIRTY;
|
||||
this.fire('state-changed', this._state);
|
||||
}
|
||||
this.fire('folder-changed', this);
|
||||
};
|
||||
|
||||
Folder.prototype.addCard = function folder_addCard(card, index) {
|
||||
// We don't support folder in folder
|
||||
if (!this._isInFolder(card) && !(card instanceof Folder)) {
|
||||
if (typeof index !== 'number') {
|
||||
index = this._cardsInFolder.length;
|
||||
}
|
||||
this._cardsInFolder.splice(index, 0, card);
|
||||
this._setDirty();
|
||||
this.fire('card-inserted', card, index);
|
||||
}
|
||||
};
|
||||
|
||||
Folder.prototype.removeCard = function folder_removeCard(card) {
|
||||
var index = this._indexOfCard(card);
|
||||
if (index > -1) {
|
||||
this._cardsInFolder.splice(index, 1);
|
||||
this._setDirty();
|
||||
this.fire('card-removed', [index]);
|
||||
}
|
||||
};
|
||||
|
||||
Folder.prototype.updateCard = function folder_updateCard(card, index) {
|
||||
// The card instance is directly reference to card in '_cardsInFolder'
|
||||
// So don't bother to update it again. But we DID need 'folder-changed'
|
||||
// event to notify CardManager to write changes to data store.
|
||||
this._setDirty();
|
||||
this.fire('card-updated', card, index);
|
||||
};
|
||||
|
||||
Folder.prototype.swapCard = function folder_swapCard(card1, card2) {
|
||||
var index1 = (typeof card1 === 'number') ?
|
||||
index1 = card1 : this._indexOfCard(card1);
|
||||
var index2 = (typeof card2 === 'number') ?
|
||||
index2 = card2 : this._indexOfCard(card2);
|
||||
var temp = this._cardsInFolder[index1];
|
||||
this._cardsInFolder[index1] = this._cardsInFolder[index2];
|
||||
this._cardsInFolder[index2] = temp;
|
||||
this._setDirty();
|
||||
this.fire('card-swapped',
|
||||
this._cardsInFolder[index1], this._cardsInFolder[index2],
|
||||
index1, index2);
|
||||
};
|
||||
|
||||
Folder.prototype.launch = function folder_launch() {
|
||||
// fire launch event to inform exterior module
|
||||
this.fire('launch', this);
|
||||
};
|
||||
|
||||
Folder.prototype.serialize = function folder_serialize() {
|
||||
return {
|
||||
name: this.name,
|
||||
folderId: this.folderId,
|
||||
type: 'Folder'
|
||||
};
|
||||
};
|
||||
|
||||
exports.Folder = Folder;
|
||||
}(window));
|
||||
Loading…
Reference in a new issue