☠☠ backed out by 820961ff0369 ☠ ☠ | |
author | Andrea Marchesini <amarchesini@mozilla.com> |
Fri, 22 Jul 2016 16:19:50 +0200 | |
changeset 306267 | edad0174cb120f85438a533e8da67af96c29e96d |
parent 306266 | 7ed07b35bad6e2b5571f24213787ab08237d88cc |
child 306268 | c57fd3af416e73fbfabcd6e7e985feedf6979504 |
push id | 79807 |
push user | amarchesini@mozilla.com |
push date | Fri, 22 Jul 2016 14:21:20 +0000 |
treeherder | mozilla-inbound@c57fd3af416e [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | Gijs |
bugs | 1287091 |
milestone | 50.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/browser/base/content/utilityOverlay.js +++ b/browser/base/content/utilityOverlay.js @@ -440,18 +440,22 @@ function createUserContextMenu(event, ad ContextualIdentityService.getIdentities().forEach(identity => { if (identity.userContextId == excludeUserContextId) { return; } let menuitem = document.createElement("menuitem"); menuitem.setAttribute("usercontextid", identity.userContextId); - menuitem.setAttribute("label", bundle.getString(identity.label)); - menuitem.setAttribute("accesskey", bundle.getString(identity.accessKey)); + menuitem.setAttribute("label", ContextualIdentityService.getUserContextLabel(identity.userContextId)); + + if (identity.accessKey) { + menuitem.setAttribute("accesskey", bundle.getString(identity.accessKey)); + } + menuitem.classList.add("menuitem-iconic"); if (addCommandAttribute) { menuitem.setAttribute("command", "Browser:NewUserContextTab"); } menuitem.setAttribute("image", identity.icon);
--- a/browser/components/customizableui/CustomizableWidgets.jsm +++ b/browser/components/customizableui/CustomizableWidgets.jsm @@ -1129,17 +1129,17 @@ const CustomizableWidgets = [ while (items.firstChild) { items.firstChild.remove(); } let fragment = doc.createDocumentFragment(); ContextualIdentityService.getIdentities().forEach(identity => { let bundle = doc.getElementById("bundle_browser"); - let label = bundle.getString(identity.label); + let label = ContextualIdentityService.getUserContextLabel(identity.userContextId); let item = doc.createElementNS(kNSXUL, "toolbarbutton"); item.setAttribute("label", label); item.setAttribute("usercontextid", identity.userContextId); item.setAttribute("class", "subviewbutton"); item.setAttribute("image", identity.icon); fragment.appendChild(item);
--- a/toolkit/components/contextualidentity/ContextualIdentityService.jsm +++ b/toolkit/components/contextualidentity/ContextualIdentityService.jsm @@ -28,70 +28,73 @@ XPCOMUtils.defineLazyModuleGetter(this, "resource://gre/modules/AsyncShutdown.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "DeferredTask", "resource://gre/modules/DeferredTask.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "FileUtils", "resource://gre/modules/FileUtils.jsm"); -this.ContextualIdentityService = { +function _ContextualIdentityService(path) { + this.init(path); +} + +_ContextualIdentityService.prototype = { _defaultIdentities: [ { userContextId: 1, public: true, icon: "chrome://browser/skin/usercontext/personal.svg", color: "#00a7e0", - label: "userContextPersonal.label", + l10nID: "userContextPersonal.label", accessKey: "userContextPersonal.accesskey", telemetryId: 1, }, { userContextId: 2, public: true, icon: "chrome://browser/skin/usercontext/work.svg", color: "#f89c24", - label: "userContextWork.label", + l10nID: "userContextWork.label", accessKey: "userContextWork.accesskey", telemetryId: 2, }, { userContextId: 3, public: true, icon: "chrome://browser/skin/usercontext/banking.svg", color: "#7dc14c", - label: "userContextBanking.label", + l10nID: "userContextBanking.label", accessKey: "userContextBanking.accesskey", telemetryId: 3, }, { userContextId: 4, public: true, icon: "chrome://browser/skin/usercontext/shopping.svg", color: "#ee5195", - label: "userContextShopping.label", + l10nID: "userContextShopping.label", accessKey: "userContextShopping.accesskey", telemetryId: 4, }, { userContextId: 5, public: false, icon: "", color: "", - label: "userContextIdInternal.thumbnail", + name: "userContextIdInternal.thumbnail", accessKey: "" }, ], _identities: null, _openedIdentities: new Set(), _lastUserContextId: 0, _path: null, _dataReady: false, _saver: null, - init() { - this._path = OS.Path.join(OS.Constants.Path.profileDir, "containers.json"); - + init(path) { + this._path = path; this._saver = new DeferredTask(() => this.save(), SAVE_DELAY_MS); AsyncShutdown.profileBeforeChange.addBlocker("ContextualIdentityService: writing data", () => this._saver.finalize()); this.load(); }, load() { @@ -154,16 +157,59 @@ this.ContextualIdentityService = { identities: this._identities }; let bytes = gTextEncoder.encode(JSON.stringify(object)); return OS.File.writeAtomic(this._path, bytes, { tmpPath: this._path + ".tmp" }); }, + create(name, icon, color) { + let identity = { + userContextId: ++this._lastUserContextId, + public: true, + icon, + color, + name + }; + + this._identities.push(identity); + this.saveSoon(); + + return Cu.cloneInto(identity, {}); + }, + + update(userContextId, name, icon, color) { + let identity = this._identities.find(identity => identity.userContextId == userContextId && + identity.public); + if (identity) { + identity.name = name; + identity.color = color; + identity.icon = icon; + delete identity.l10nID; + delete identity.accessKey; + this.saveSoon(); + } + + return !!identity; + }, + + remove(userContextId) { + let index = this._identities.findIndex(i => i.userContextId == userContextId && i.public); + if (index == -1) { + return false; + } + + this._identities.splice(index, 1); + this._openedIdentities.delete(userContextId); + this.saveSoon(); + + return true; + }, + ensureDataReady() { if (this._dataReady) { return; } try { // This reads the file and automatically detects the UTF-8 encoding. let inputStream = Cc["@mozilla.org/network/file-input-stream;1"] @@ -181,35 +227,42 @@ this.ContextualIdentityService = { } catch (error) { this.loadError(error); return; } }, getIdentities() { this.ensureDataReady(); - return this._identities.filter(info => info.public); + return Cu.cloneInto(this._identities.filter(info => info.public), {}); }, - getPrivateIdentity(label) { + getPrivateIdentity(name) { this.ensureDataReady(); - return this._identities.find(info => !info.public && info.label == label); + return Cu.cloneInto(this._identities.find(info => !info.public && info.name == name), {}); }, getIdentityFromId(userContextId) { this.ensureDataReady(); - return this._identities.find(info => info.userContextId == userContextId); + return Cu.cloneInto(this._identities.find(info => info.userContextId == userContextId && + info.public), {}); }, getUserContextLabel(userContextId) { let identity = this.getIdentityFromId(userContextId); if (!identity.public) { return ""; } - return gBrowserBundle.GetStringFromName(identity.label); + + // We cannot localize the user-created identity names. + if (identity.name) { + return identity.name; + } + + return gBrowserBundle.GetStringFromName(identity.l10nID); }, setTabStyle(tab) { // inline style is only a temporary fix for some bad performances related // to the use of CSS vars. This code will be removed in bug 1278177. if (!tab.hasAttribute("usercontextid")) { tab.style.removeProperty("background-image"); tab.style.removeProperty("background-size"); @@ -241,11 +294,16 @@ this.ContextualIdentityService = { Services.telemetry.getHistogramById("TOTAL_CONTAINERS_OPENED").add(1); if (identity.telemetryId) { Services.telemetry.getHistogramById("CONTAINER_USED") .add(identity.telemetryId); } }, -} -ContextualIdentityService.init(); + createNewInstanceForTesting(path) { + return new _ContextualIdentityService(path); + }, +}; + +let path = OS.Path.join(OS.Constants.Path.profileDir, "containers.json"); +this.ContextualIdentityService = new _ContextualIdentityService(path);
--- a/toolkit/components/contextualidentity/moz.build +++ b/toolkit/components/contextualidentity/moz.build @@ -2,8 +2,10 @@ # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. EXTRA_JS_MODULES += [ 'ContextualIdentityService.jsm', ] + +XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
new file mode 100644 --- /dev/null +++ b/toolkit/components/contextualidentity/tests/unit/test_basic.js @@ -0,0 +1,67 @@ +"use strict"; + +do_get_profile(); + +const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; + +Cu.import("resource://gre/modules/ContextualIdentityService.jsm"); + +const TEST_STORE_FILE_NAME = "test-containers.json"; + +let cis; + +// Basic tests +add_task(function() { + ok(!!ContextualIdentityService, "ContextualIdentityService exists"); + + cis = ContextualIdentityService.createNewInstanceForTesting(TEST_STORE_FILE_NAME); + ok(!!cis, "We have our instance of ContextualIdentityService"); + + equal(cis.getIdentities().length, 4, "By default, 4 containers."); + equal(cis.getIdentityFromId(0), null, "No identity with id 0"); + + ok(!!cis.getIdentityFromId(1), "Identity 1 exists"); + ok(!!cis.getIdentityFromId(2), "Identity 2 exists"); + ok(!!cis.getIdentityFromId(3), "Identity 3 exists"); + ok(!!cis.getIdentityFromId(4), "Identity 4 exists"); +}); + +// Create a new identity +add_task(function() { + equal(cis.getIdentities().length, 4, "By default, 4 containers."); + + let identity = cis.create("New Container", "Icon", "Color"); + ok(!!identity, "New container created"); + equal(identity.name, "New Container", "Name matches"); + equal(identity.icon, "Icon", "Icon matches"); + equal(identity.color, "Color", "Color matches"); + + equal(cis.getIdentities().length, 5, "Expected 5 containers."); + + ok(!!cis.getIdentityFromId(identity.userContextId), "Identity exists"); + equal(cis.getIdentityFromId(identity.userContextId).name, "New Container", "Identity name is OK"); + equal(cis.getIdentityFromId(identity.userContextId).icon, "Icon", "Identity icon is OK"); + equal(cis.getIdentityFromId(identity.userContextId).color, "Color", "Identity color is OK"); + equal(cis.getUserContextLabel(identity.userContextId), "New Container", "Identity label is OK"); + + // Remove an identity + equal(cis.remove(-1), false, "cis.remove() returns false if identity doesn't exist."); + equal(cis.remove(1), true, "cis.remove() returns true if identity exists."); + + equal(cis.getIdentities().length, 4, "Expected 4 containers."); +}); + +// Update an identity +add_task(function() { + ok(!!cis.getIdentityFromId(2), "Identity 2 exists"); + + equal(cis.update(-1, "Container", "Icon", "Color"), false, "Update returns false if the identity doesn't exist"); + + equal(cis.update(2, "Container", "Icon", "Color"), true, "Update returns true if everything is OK"); + + ok(!!cis.getIdentityFromId(2), "Identity exists"); + equal(cis.getIdentityFromId(2).name, "Container", "Identity name is OK"); + equal(cis.getIdentityFromId(2).icon, "Icon", "Identity icon is OK"); + equal(cis.getIdentityFromId(2).color, "Color", "Identity color is OK"); + equal(cis.getUserContextLabel(2), "Container", "Identity label is OK"); +});