Skip to content
This repository has been archived by the owner on Nov 3, 2021. It is now read-only.

Commit

Permalink
Merge pull request #27383 from arcturus/bug-1113016
Browse files Browse the repository at this point in the history
Bug 1113016 - Add a panel to manage Addons r=arthurcc
  • Loading branch information
arcturus committed Feb 3, 2015
2 parents c123b64 + 7875c0a commit 8a916e0
Show file tree
Hide file tree
Showing 14 changed files with 474 additions and 0 deletions.
15 changes: 15 additions & 0 deletions apps/settings/elements/addons.html
@@ -0,0 +1,15 @@
<element name="addons" extends="section">
<template>

<gaia-header action="back" data-href="#root">
<h1 data-l10n-id="addons-header"></h1>
</gaia-header>

<div>
<ul class="addon-list"></ul>
</div>

<panel data-path="panels/addons/panel"></panel>

</template>
</element>
5 changes: 5 additions & 0 deletions apps/settings/elements/root.html
Expand Up @@ -121,6 +121,11 @@ <h2 data-l10n-id="personalization">Personalization</h2>
<li class="themes-section" hidden>
<a id="menuItem-themes" class="menu-item" data-icon="themes" href="#themes" data-l10n-id="themes">Themes</a>
</li>
<li id="addons-section" hidden>
<a id="menuItem-addons" class="menu-item" data-icon="add" href="#addons">
<span data-l10n-id="addons">Addons</span>
</a>
</li>
</ul>

<header>
Expand Down
3 changes: 3 additions & 0 deletions apps/settings/index.html
Expand Up @@ -170,6 +170,7 @@
<link rel="import" href="/elements/keyboard.html">
<link rel="import" href="/elements/keyboard_selection_add_more.html">
<link rel="import" href="/elements/themes.html">
<link rel="import" href="/elements/addons.html">
<link rel="import" href="/elements/screen_lock_passcode.html">
<link rel="import" href="/elements/screen_lock.html">
<link rel="import" href="/elements/simpin_dialog.html">
Expand Down Expand Up @@ -336,6 +337,8 @@
<section is="keyboard" role="region" id="keyboard"></section>
<!-- Personalization :: Themes -->
<section is="themes" role="region" id="themes"></section>
<!-- Personalization :: Addons -->
<section is="addons" role="region" id="addons"></section>

<!-- Accounts :: Find My Device -->
<section is="findmydevice" role="region" id="findmydevice"></section>
Expand Down
35 changes: 35 additions & 0 deletions apps/settings/js/panels/addons/addons_list.js
@@ -0,0 +1,35 @@
/**
* UI for Addons panel's functionality.
*
* @module AddonsList
*/
define(function(require) {
'use strict';

var ListView = require('modules/mvvm/list_view');
var AddonItemTemplateFactory = require('panels/addons/addons_template');

function AddonsList(root, manager) {
this._enabled = false;
this._listRoot = root;
this._addonsManager = manager;
var addonTemplate = AddonItemTemplateFactory({
disableAddon: this._addonsManager.disableAddon,
enableAddon: this._addonsManager.enableAddon
});
this._listView = ListView(this._listRoot,
this._addonsManager.addons, addonTemplate);
}

AddonsList.prototype = {
set enabled(value) {
if (value !== this._enabled) {
this._listView.enabled = this._enabled = value;
}
}
};

return function ctor_addons_list(root, manager) {
return new AddonsList(root, manager);
};
});
117 changes: 117 additions & 0 deletions apps/settings/js/panels/addons/addons_manager.js
@@ -0,0 +1,117 @@
/**
* Handle addons panel's functionality.
*
* @module AddonsManager
*/
define(function(require) {
'use strict';

var AppsCache = require('modules/apps_cache');
var ObservableArray = require('modules/mvvm/observable_array');

function AddonsManager() {
this.addons = {};
}

AddonsManager.prototype = {
/**
* initialization
*
* @memberOf AddonsManager
* @access public
*/
init: function am_init() {
this.addons = ObservableArray([]);
return AppsCache.apps().then((apps) => {
apps.some((app) => {
if (this._isAddon(app)) {
this.addons.push(app);
}
});
});
},

set enabled(value) {
if (value !== this._enabled) {
this._enabled = value;
if (this._enabled) {
this._bindEvents();
} else {
this._unbindEvents();
}
}
},

_bindEvents: function am__bindEvents() {
AppsCache.addEventListener('oninstall', this._updateAddons.bind(this));
AppsCache.addEventListener('onuninstall', this._updateAddons.bind(this));
},

_unbindEvents: function am__unbindEvents() {
AppsCache.removeEventListener('oninstall', this._updateAddons);
AppsCache.removeEventListener('onuninstall', this._updateAddons);
},

/**
* We have to update the addon count based on incoming evt and
* decide to show/hide or not.
*
* @param {Object} evt
* @memberOf AddonsManager
*/
_updateAddons: function(evt) {
var app = evt && evt.application;
var type = evt.type;

if (this._isAddon(app)) {
if (type === 'install' && !this._alreadyExists(app)) {
this.addons.push(app);
} else if (type === 'uninstall') {
var index = this._findAddon(app);
if (index !== -1) {
this.addons.splice(index, 1);
}
}
}
},

_alreadyExists: function(app) {
return this._findAddonIndex(app) !== -1;
},

_findAddonIndex: function(app) {
return this.addons.array.findIndex((elem) => {
return app.manifestURL === elem.manifestURL;
});
},

/**
* Check whether this app is an addon
*
* @param {Object} app
* @returns {Boolean}
* @memberOf AddonsManager
*/
_isAddon: function(app) {
var manifest = app.manifest || app.updateManifest;
return manifest.role === 'addon';
},

enableAddon: function(app) {
navigator.mozApps.mgmt.setEnabled(app, true);
},

disableAddon: function(app) {
navigator.mozApps.mgmt.setEnabled(app, false);
},

get length() {
return this.addons.length;
}

};

return function ctor_addons_manager() {
return new AddonsManager();
};
});
48 changes: 48 additions & 0 deletions apps/settings/js/panels/addons/addons_template.js
@@ -0,0 +1,48 @@
/**
* The template function for generating an UI element for an Addon item.
*
* @module addons/addons_template
*/
define(function(require) {
'use strict';

function addonsTemplate(addonEnabler, item, recycled) {
var manifest = item.manifest || item.updateManifest;
var container = null;
var span, toggle;
if (recycled) {
container = recycled;
toggle = container.querySelector('input');
span = container.querySelector('span');
} else {
var kind = 'checkbox';
container = document.createElement('li');
toggle = document.createElement('input');
var label = document.createElement('label');
span = document.createElement('span');
label.className = 'pack-' + kind;
toggle.type = kind;
toggle.value = item.manifestURL;
toggle.checked = item.enabled;
label.appendChild(toggle);
label.appendChild(span);
container.appendChild(label);
}

span.textContent = manifest.name;
toggle.onclick = () => {
if (item.enabled) {
addonEnabler.disableAddon(item);
} else {
addonEnabler.enableAddon(item);
}
};

return container;
}

return function ctor_addonsTemplate(enabler, item, recycled) {
return addonsTemplate.bind(null, enabler);
};

});
33 changes: 33 additions & 0 deletions apps/settings/js/panels/addons/panel.js
@@ -0,0 +1,33 @@
define(function(require) {
'use strict';

var SettingsPanel = require('modules/settings_panel');
var AddonsManager = require('panels/addons/addons_manager');
var AddonsList = require('panels/addons/addons_list');

return function ctor_addons_panel() {
var addonsManager = AddonsManager();
var addonsList;

return SettingsPanel({
onInit: function(panel) {
var elements = {
list: panel.querySelector('.addon-list')
};
return addonsManager.init().then( () => {
addonsList = new AddonsList(elements.list, addonsManager);
});
},

onBeforeShow: function() {
addonsList.enabled = true;
addonsManager.enabled = true;
},

onBeforeHide: function() {
addonsList.enabled = false;
addonsManager.enabled = false;
}
});
};
});
79 changes: 79 additions & 0 deletions apps/settings/js/panels/root/addons_item.js
@@ -0,0 +1,79 @@
/**
* This module is used to show/hide addon menuItem based on the number of
* current installed addons.
*
* @module AddonsItem
*/
define(function(require) {
'use strict';

var AddonsManager = require('panels/addons/addons_manager');

function AddonsItem(element) {
this._enabled = false;
this._element = element;
this.addonsManager = AddonsManager();
this.init();
}

AddonsItem.prototype = {
/**
* Set current status of addonsItem
*
* @access public
* @param {Boolean} enabled
* @memberOf AddonsItem
*/
set enabled(enabled) {
if (this._enabled === enabled) {
return;
} else {
this._enabled = enabled;
if (this._enabled) {
this._updateAddonSectionVisibility();
}
}
},

/**
* Get current status of addonsItem
*
* @access public
* @memberOf AddonsItem
*/
get enabled() {
return this._enabled;
},

/**
* Initialization
*
* @access private
* @memberOf AddonsItem
* @return {Promise}
*/
init: function() {
this.addonsManager.init().then( () => {
var _handleEvent = this._updateAddonSectionVisibility.bind(this);
this.addonsManager.addons.observe('insert', _handleEvent);
this.addonsManager.addons.observe('remove', _handleEvent);
this.addonsManager.addons.observe('reset', _handleEvent);

this._updateAddonSectionVisibility();
});
},

/**
* Update addon section visibility based on _addonCount
*
* @memberOf AddonsItem
*/
_updateAddonSectionVisibility: function() {
this._element.hidden = this.addonsManager.length === 0;
}
};

return function(element) {
return new AddonsItem(element);
};
});

0 comments on commit 8a916e0

Please sign in to comment.