Merge fx-team to m-c. a=merge

This commit is contained in:
Ryan VanderMeulen 2016-08-29 12:31:32 -04:00
commit 8b0f132c86
76 changed files with 1207 additions and 1244 deletions

View File

@ -428,8 +428,9 @@ var MigrationWizard = {
this.reportDataRecencyTelemetry();
}
if (this._autoMigrate) {
Services.telemetry.getKeyedHistogramById("FX_MIGRATION_HOMEPAGE_IMPORTED")
.add(this._source, !!this._newHomePage);
let hasImportedHomepage = !!(this._newHomePage && this._newHomePage != "DEFAULT");
Services.telemetry.getKeyedHistogramById("FX_MIGRATION_IMPORTED_HOMEPAGE")
.add(this._source, hasImportedHomepage);
if (this._newHomePage) {
try {
// set homepage properly

View File

@ -63,11 +63,11 @@
background-color: rgba(0,0,0,.3);
}
#navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar) {
#navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar):not(#addon-bar) {
background-image: linear-gradient(@toolbarHighlight@, @toolbarHighlight@);
}
#navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar):-moz-lwtheme {
#navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar):not(#addon-bar):-moz-lwtheme {
background-image: linear-gradient(@toolbarHighlightLWT@, @toolbarHighlightLWT@);
}

View File

@ -22,9 +22,7 @@ loader.lazyRequireGetter(this, "EventEmitter", "devtools/shared/event-emitter");
loader.lazyRequireGetter(this, "AnimationsFront", "devtools/shared/fronts/animation", true);
const { LocalizationHelper } = require("devtools/shared/l10n");
const STRINGS_URI = "devtools/locale/animationinspector.properties";
const L10N = new LocalizationHelper(STRINGS_URI);
const L10N = new LocalizationHelper("devtools/locale/animationinspector.properties");
// Global toolbox/inspector, set when startup is called.
var gToolbox, gInspector;

View File

@ -10,9 +10,7 @@ const EventEmitter = require("devtools/shared/event-emitter");
const {createNode, TimeScale} = require("devtools/client/animationinspector/utils");
const { LocalizationHelper } = require("devtools/shared/l10n");
const STRINGS_URI = "devtools/locale/animationinspector.properties";
const L10N = new LocalizationHelper(STRINGS_URI);
const L10N = new LocalizationHelper("devtools/locale/animationinspector.properties");
/**
* UI component responsible for displaying a single animation timeline, which

View File

@ -9,9 +9,7 @@
const EventEmitter = require("devtools/shared/event-emitter");
const {createNode} = require("devtools/client/animationinspector/utils");
const { LocalizationHelper } = require("devtools/shared/l10n");
const STRINGS_URI = "devtools/locale/animationinspector.properties";
const L10N = new LocalizationHelper(STRINGS_URI);
const L10N = new LocalizationHelper("devtools/locale/animationinspector.properties");
// List of playback rate presets displayed in the timeline toolbar.
const PLAYBACK_RATES = [.1, .25, .5, 1, 2, 5, 10];

View File

@ -4,9 +4,8 @@
"use strict";
const { LocalizationHelper } = require("devtools/shared/l10n");
const STRINGS_URI = "global/locale/layout_errors.properties";
const L10N = new LocalizationHelper(STRINGS_URI);
const LAYOUT_ERRORS_L10N =
new LocalizationHelper("global/locale/layout_errors.properties");
// Test that when an animation is selected, its list of animated properties is
// displayed below it.
@ -79,7 +78,7 @@ function hasExpectedWarnings(containerEl) {
for (let warning of warnings) {
let warningID =
"CompositorAnimationWarningTransformWithGeometricProperties";
if (warning.getAttribute("title") == L10N.getStr(warningID)) {
if (warning.getAttribute("title") == LAYOUT_ERRORS_L10N.getStr(warningID)) {
return true;
}
}

View File

@ -7,11 +7,6 @@ requestLongerTimeout(2);
// Test that the panel shows no animation data for invalid or not animated nodes
const { LocalizationHelper } = require("devtools/shared/l10n");
const STRINGS_URI = "devtools/locale/animationinspector.properties";
const L10N = new LocalizationHelper(STRINGS_URI);
add_task(function* () {
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {inspector, panel, window} = yield openAnimationInspector();
@ -28,7 +23,7 @@ add_task(function* () {
is(panel.animationsTimelineComponent.animationsEl.childNodes.length, 0,
"No animation displayed in the timeline component for a still node");
is(document.querySelector("#error-type").textContent,
L10N.getStr("panel.invalidElementSelected"),
ANIMATION_L10N.getStr("panel.invalidElementSelected"),
"The correct error message is displayed");
info("Select the comment text node and check that the panel is empty");
@ -42,6 +37,6 @@ add_task(function* () {
is(panel.animationsTimelineComponent.animationsEl.childNodes.length, 0,
"No animation displayed in the timeline component for a text node");
is(document.querySelector("#error-type").textContent,
L10N.getStr("panel.invalidElementSelected"),
ANIMATION_L10N.getStr("panel.invalidElementSelected"),
"The correct error message is displayed");
});

View File

@ -9,11 +9,6 @@ requestLongerTimeout(2);
// Test that when animations displayed in the timeline are running on the
// compositor, they get a special icon and information in the tooltip.
const { LocalizationHelper } = require("devtools/shared/l10n");
const STRINGS_URI = "devtools/locale/animationinspector.properties";
const L10N = new LocalizationHelper(STRINGS_URI);
add_task(function* () {
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspector();
@ -26,7 +21,7 @@ add_task(function* () {
ok(animationEl.classList.contains("fast-track"),
"The animation element has the fast-track css class");
ok(hasTooltip(animationEl,
L10N.getStr("player.allPropertiesOnCompositorTooltip")),
ANIMATION_L10N.getStr("player.allPropertiesOnCompositorTooltip")),
"The animation element has the right tooltip content");
info("Select a node we know doesn't have an animation on the compositor");
@ -36,10 +31,10 @@ add_task(function* () {
ok(!animationEl.classList.contains("fast-track"),
"The animation element does not have the fast-track css class");
ok(!hasTooltip(animationEl,
L10N.getStr("player.allPropertiesOnCompositorTooltip")),
ANIMATION_L10N.getStr("player.allPropertiesOnCompositorTooltip")),
"The animation element does not have oncompositor tooltip content");
ok(!hasTooltip(animationEl,
L10N.getStr("player.somePropertiesOnCompositorTooltip")),
ANIMATION_L10N.getStr("player.somePropertiesOnCompositorTooltip")),
"The animation element does not have oncompositor tooltip content");
info("Select a node we know has animation on the compositor and not on the" +
@ -50,7 +45,7 @@ add_task(function* () {
ok(animationEl.classList.contains("fast-track"),
"The animation element has the fast-track css class");
ok(hasTooltip(animationEl,
L10N.getStr("player.somePropertiesOnCompositorTooltip")),
ANIMATION_L10N.getStr("player.somePropertiesOnCompositorTooltip")),
"The animation element has the right tooltip content");
});

View File

@ -14,6 +14,8 @@ Services.scriptloader.loadSubScript(
const FRAME_SCRIPT_URL = CHROME_URL_ROOT + "doc_frame_script.js";
const COMMON_FRAME_SCRIPT_URL = "chrome://devtools/content/shared/frame-script-utils.js";
const TAB_NAME = "animationinspector";
const ANIMATION_L10N =
new LocalizationHelper("devtools/locale/animationinspector.properties");
// Auto clean-up when a test ends
registerCleanupFunction(function* () {

View File

@ -9,9 +9,7 @@
loader.lazyRequireGetter(this, "EventEmitter", "devtools/shared/event-emitter");
const { LocalizationHelper } = require("devtools/shared/l10n");
const STRINGS_URI = "devtools/locale/animationinspector.properties";
const L10N = new LocalizationHelper(STRINGS_URI);
const L10N = new LocalizationHelper("devtools/locale/animationinspector.properties");
// How many times, maximum, can we loop before we find the optimal time
// interval in the timeline graph.

View File

@ -24,35 +24,36 @@ loader.lazyGetter(this, "ScratchpadPanel", () => require("devtools/client/scratc
loader.lazyGetter(this, "DomPanel", () => require("devtools/client/dom/dom-panel").DomPanel);
// Strings
const toolboxProps = "chrome://devtools/locale/toolbox.properties";
const inspectorProps = "chrome://devtools/locale/inspector.properties";
const webConsoleProps = "chrome://devtools/locale/webconsole.properties";
const debuggerProps = "chrome://devtools/locale/debugger.properties";
const styleEditorProps = "chrome://devtools/locale/styleeditor.properties";
const shaderEditorProps = "chrome://devtools/locale/shadereditor.properties";
const canvasDebuggerProps = "chrome://devtools/locale/canvasdebugger.properties";
const webAudioEditorProps = "chrome://devtools/locale/webaudioeditor.properties";
const performanceProps = "chrome://devtools/locale/performance.properties";
const netMonitorProps = "chrome://devtools/locale/netmonitor.properties";
const storageProps = "chrome://devtools/locale/storage.properties";
const scratchpadProps = "chrome://devtools/locale/scratchpad.properties";
const memoryProps = "chrome://devtools/locale/memory.properties";
const domProps = "chrome://devtools/locale/dom.properties";
const toolboxProps = "devtools/locale/toolbox.properties";
const inspectorProps = "devtools/locale/inspector.properties";
const webConsoleProps = "devtools/locale/webconsole.properties";
const debuggerProps = "devtools/locale/debugger.properties";
const styleEditorProps = "devtools/locale/styleeditor.properties";
const shaderEditorProps = "devtools/locale/shadereditor.properties";
const canvasDebuggerProps = "devtools/locale/canvasdebugger.properties";
const webAudioEditorProps = "devtools/locale/webaudioeditor.properties";
const performanceProps = "devtools/locale/performance.properties";
const netMonitorProps = "devtools/locale/netmonitor.properties";
const storageProps = "devtools/locale/storage.properties";
const scratchpadProps = "devtools/locale/scratchpad.properties";
const memoryProps = "devtools/locale/memory.properties";
const domProps = "devtools/locale/dom.properties";
loader.lazyGetter(this, "toolboxStrings", () => Services.strings.createBundle(toolboxProps));
loader.lazyGetter(this, "performanceStrings", () => Services.strings.createBundle(performanceProps));
loader.lazyGetter(this, "webConsoleStrings", () => Services.strings.createBundle(webConsoleProps));
loader.lazyGetter(this, "debuggerStrings", () => Services.strings.createBundle(debuggerProps));
loader.lazyGetter(this, "styleEditorStrings", () => Services.strings.createBundle(styleEditorProps));
loader.lazyGetter(this, "shaderEditorStrings", () => Services.strings.createBundle(shaderEditorProps));
loader.lazyGetter(this, "canvasDebuggerStrings", () => Services.strings.createBundle(canvasDebuggerProps));
loader.lazyGetter(this, "webAudioEditorStrings", () => Services.strings.createBundle(webAudioEditorProps));
loader.lazyGetter(this, "inspectorStrings", () => Services.strings.createBundle(inspectorProps));
loader.lazyGetter(this, "netMonitorStrings", () => Services.strings.createBundle(netMonitorProps));
loader.lazyGetter(this, "storageStrings", () => Services.strings.createBundle(storageProps));
loader.lazyGetter(this, "scratchpadStrings", () => Services.strings.createBundle(scratchpadProps));
loader.lazyGetter(this, "memoryStrings", () => Services.strings.createBundle(memoryProps));
loader.lazyGetter(this, "domStrings", () => Services.strings.createBundle(domProps));
const {LocalizationHelper} = require("devtools/shared/l10n");
const toolboxStrings = new LocalizationHelper(toolboxProps);
const performanceStrings = new LocalizationHelper(performanceProps);
const webConsoleStrings = new LocalizationHelper(webConsoleProps);
const debuggerStrings = new LocalizationHelper(debuggerProps);
const styleEditorStrings = new LocalizationHelper(styleEditorProps);
const shaderEditorStrings = new LocalizationHelper(shaderEditorProps);
const canvasDebuggerStrings = new LocalizationHelper(canvasDebuggerProps);
const webAudioEditorStrings = new LocalizationHelper(webAudioEditorProps);
const inspectorStrings = new LocalizationHelper(inspectorProps);
const netMonitorStrings = new LocalizationHelper(netMonitorProps);
const storageStrings = new LocalizationHelper(storageProps);
const scratchpadStrings = new LocalizationHelper(scratchpadProps);
const memoryStrings = new LocalizationHelper(memoryProps);
const domStrings = new LocalizationHelper(domProps);
var Tools = {};
exports.Tools = Tools;
@ -494,8 +495,7 @@ exports.defaultThemes = [
*/
function l10n(name, bundle, arg) {
try {
return arg ? bundle.formatStringFromName(name, [arg], 1)
: bundle.GetStringFromName(name);
return arg ? bundle.getFormatStr(name, arg) : bundle.getStr(name);
} catch (ex) {
console.log("Error reading '" + name + "'");
throw new Error("l10n error with " + name);

View File

@ -8,14 +8,8 @@ const {Cc, Ci, Cu} = require("chrome");
const Services = require("Services");
const defer = require("devtools/shared/defer");
function l10n(name) {
const bundle = Services.strings.createBundle("chrome://devtools/locale/toolbox.properties");
try {
return bundle.GetStringFromName(name);
} catch (e) {
throw new Error("Failed loading l10n string: " + name);
}
}
const {LocalizationHelper} = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools/locale/toolbox.properties");
function handleThreadState(toolbox, event, packet) {
// Suppress interrupted events by default because the thread is
@ -78,7 +72,7 @@ function attachThread(toolbox) {
if (res.error === "wrongOrder") {
const box = toolbox.getNotificationBox();
box.appendNotification(
l10n("toolbox.resumeOrderWarning"),
L10N.getStr("toolbox.resumeOrderWarning"),
"wrong-resume-order",
"",
box.PRIORITY_WARNING_HIGH

View File

@ -12,8 +12,8 @@
* - devtools/client/definitions for tool-specifics entries
*/
const Services = require("Services");
const MenuStrings = Services.strings.createBundle("chrome://devtools/locale/menus.properties");
const {LocalizationHelper} = require("devtools/shared/l10n");
const MENUS_L10N = new LocalizationHelper("devtools/locale/menus.properties");
loader.lazyRequireGetter(this, "gDevTools", "devtools/client/framework/devtools", true);
loader.lazyRequireGetter(this, "gDevToolsBrowser", "devtools/client/framework/devtools-browser", true);
@ -23,7 +23,7 @@ loader.lazyRequireGetter(this, "gDevToolsBrowser", "devtools/client/framework/de
const FragmentsCache = new Map();
function l10n(key) {
return MenuStrings.GetStringFromName(key);
return MENUS_L10N.getStr(key);
}
/**

View File

@ -8,21 +8,18 @@
var Cu = Components.utils;
var {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
var {XPCOMUtils} = require("resource://gre/modules/XPCOMUtils.jsm");
var Services = require("Services");
var {gDevTools} = require("devtools/client/framework/devtools");
var {TargetFactory} = require("devtools/client/framework/target");
var {Toolbox} = require("devtools/client/framework/toolbox");
var {DebuggerClient} = require("devtools/shared/client/main");
var {Task} = require("devtools/shared/task");
var {LocalizationHelper} = require("devtools/shared/l10n");
var L10N = new LocalizationHelper("devtools/locale/connection-screen.properties");
var gClient;
var gConnectionTimeout;
XPCOMUtils.defineLazyGetter(window, "l10n", function () {
return Services.strings.createBundle("chrome://devtools/locale/connection-screen.properties");
});
/**
* Once DOM is ready, we prefil the host/port inputs with
* pref-stored values.
@ -134,7 +131,7 @@ var onConnectionReady = Task.async(function* ([aType, aTraits]) {
openToolbox(globals, true, "webconsole", false);
}
};
a.title = a.textContent = window.l10n.GetStringFromName("mainProcess");
a.title = a.textContent = L10N.getStr("mainProcess");
a.className = "remote-process";
a.href = "#";
gParent.appendChild(a);

View File

@ -30,7 +30,8 @@ loader.lazyRequireGetter(this, "BrowserMenus", "devtools/client/framework/browse
loader.lazyImporter(this, "CustomizableUI", "resource:///modules/CustomizableUI.jsm");
loader.lazyImporter(this, "AppConstants", "resource://gre/modules/AppConstants.jsm");
const bundle = Services.strings.createBundle("chrome://devtools/locale/toolbox.properties");
const {LocalizationHelper} = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools/locale/toolbox.properties");
const TABS_OPEN_PEAK_HISTOGRAM = "DEVTOOLS_TABS_OPEN_PEAK_LINEAR";
const TABS_OPEN_AVG_HISTOGRAM = "DEVTOOLS_TABS_OPEN_AVERAGE_LINEAR";
@ -244,7 +245,7 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
// Do nothing if there is only one process, the parent process.
let contentProcesses = response.processes.filter(p => (!p.parent));
if (contentProcesses.length < 1) {
let msg = bundle.GetStringFromName("toolbox.noContentProcess.message");
let msg = L10N.getStr("toolbox.noContentProcess.message");
Services.prompt.alert(null, "", msg);
deferred.reject("No content processes available.");
return;

View File

@ -4,12 +4,14 @@
"use strict";
var {XPCOMUtils} = require("resource://gre/modules/XPCOMUtils.jsm");
var Services = require("Services");
var {Task} = require("devtools/shared/task");
var EventEmitter = require("devtools/shared/event-emitter");
var Telemetry = require("devtools/client/shared/telemetry");
const {LocalizationHelper} = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools/locale/toolbox.properties");
const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
/**
@ -130,7 +132,8 @@ ToolSidebar.prototype = {
this._allTabsBtn.setAttribute("top", "0");
this._allTabsBtn.setAttribute("width", "15");
this._allTabsBtn.setAttribute("type", "menu");
this._allTabsBtn.setAttribute("tooltiptext", l10n("sidebar.showAllTabs.tooltip"));
this._allTabsBtn.setAttribute("tooltiptext",
L10N.getStr("sidebar.showAllTabs.tooltip"));
this._allTabsBtn.setAttribute("hidden", "true");
allTabsContainer.appendChild(this._allTabsBtn);
@ -587,19 +590,3 @@ ToolSidebar.prototype = {
this._toolPanel = null;
})
};
XPCOMUtils.defineLazyGetter(this, "l10n", function () {
let bundle = Services.strings.createBundle("chrome://devtools/locale/toolbox.properties");
let l10n = function (aName, ...aArgs) {
try {
if (aArgs.length == 0) {
return bundle.GetStringFromName(aName);
} else {
return bundle.formatStringFromName(aName, aArgs, aArgs.length);
}
} catch (ex) {
console.log("Error reading '" + aName + "'");
}
};
return l10n;
});

View File

@ -10,8 +10,9 @@
const URL = "data:text/html;charset=utf8,test page";
var {Toolbox} = require("devtools/client/framework/toolbox");
var strings = Services.strings.createBundle(
"chrome://devtools/locale/toolbox.properties");
const {LocalizationHelper} = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools/locale/toolbox.properties");
function getZoomValue() {
return parseFloat(Services.prefs.getCharPref("devtools.toolbox.zoomValue"));
@ -39,7 +40,7 @@ add_task(function* () {
});
function zoomWithKey(toolbox, key) {
let shortcut = strings.GetStringFromName(key);
let shortcut = L10N.getStr(key);
if (!shortcut) {
info("Key was empty, skipping zoomWithKey");
return;

View File

@ -11,8 +11,9 @@
const URL = "data:text/html;charset=utf8,test page for toolbox switching";
var {Toolbox} = require("devtools/client/framework/toolbox");
var strings = Services.strings.createBundle(
"chrome://devtools/locale/toolbox.properties");
const {LocalizationHelper} = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools/locale/toolbox.properties");
add_task(function* () {
info("Create a test tab and open the toolbox");
@ -20,7 +21,7 @@ add_task(function* () {
let target = TargetFactory.forTab(tab);
let toolbox = yield gDevTools.showToolbox(target, "webconsole");
let shortcut = strings.GetStringFromName("toolbox.toggleHost.key");
let shortcut = L10N.getStr("toolbox.toggleHost.key");
let {SIDE, BOTTOM, WINDOW} = Toolbox.HostType;
checkHostType(toolbox, BOTTOM, SIDE);

View File

@ -10,8 +10,8 @@
// and toggles appropriate things in the toolbox.
var doc = null, toolbox = null, panelWin = null, modifiedPrefs = [];
var strings = Services.strings.createBundle(
"chrome://devtools/locale/toolbox.properties");
const {LocalizationHelper} = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools/locale/toolbox.properties");
add_task(function* () {
const URL = "data:text/html;charset=utf8,test for dynamically registering " +
@ -60,18 +60,18 @@ function* testOptionsShortcut() {
yield toolbox.selectTool("webconsole");
is(toolbox.currentToolId, "webconsole", "webconsole is selected");
synthesizeKeyShortcut(strings.GetStringFromName("toolbox.options.key"));
synthesizeKeyShortcut(L10N.getStr("toolbox.options.key"));
is(toolbox.currentToolId, "options", "Toolbox selected via shortcut key (1)");
synthesizeKeyShortcut(strings.GetStringFromName("toolbox.options.key"));
synthesizeKeyShortcut(L10N.getStr("toolbox.options.key"));
is(toolbox.currentToolId, "webconsole", "webconsole is selected (1)");
yield toolbox.selectTool("webconsole");
is(toolbox.currentToolId, "webconsole", "webconsole is selected");
synthesizeKeyShortcut(strings.GetStringFromName("toolbox.help.key"));
synthesizeKeyShortcut(L10N.getStr("toolbox.help.key"));
is(toolbox.currentToolId, "options", "Toolbox selected via shortcut key (2)");
synthesizeKeyShortcut(strings.GetStringFromName("toolbox.options.key"));
synthesizeKeyShortcut(L10N.getStr("toolbox.options.key"));
is(toolbox.currentToolId, "webconsole", "webconsole is reselected (2)");
synthesizeKeyShortcut(strings.GetStringFromName("toolbox.help.key"));
synthesizeKeyShortcut(L10N.getStr("toolbox.help.key"));
is(toolbox.currentToolId, "options", "Toolbox selected via shortcut key (2)");
}

View File

@ -3,11 +3,14 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
requestLongerTimeout(2);
var {Toolbox} = require("devtools/client/framework/toolbox");
var strings = Services.strings.createBundle(
"chrome://devtools/locale/toolbox.properties");
const {LocalizationHelper} = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools/locale/toolbox.properties");
add_task(function* () {
let tab = yield addTab("about:blank");
@ -18,10 +21,9 @@ add_task(function* () {
.filter(def => def.isTargetSupported(target))
.map(def => def.id);
let toolbox = yield gDevTools.showToolbox(target, toolIDs[0],
Toolbox.HostType.BOTTOM);
let nextShortcut = strings.GetStringFromName("toolbox.nextTool.key")
let prevShortcut = strings.GetStringFromName("toolbox.previousTool.key")
let toolbox = yield gDevTools.showToolbox(target, toolIDs[0], Toolbox.HostType.BOTTOM);
let nextShortcut = L10N.getStr("toolbox.nextTool.key");
let prevShortcut = L10N.getStr("toolbox.previousTool.key");
// Iterate over all tools, starting from options to netmonitor, in normal
// order.

View File

@ -10,8 +10,9 @@ const TEST_URL = "data:text/html;charset=utf-8," +
"<body><h1>Testing reload from devtools</h1></body></html>";
var {Toolbox} = require("devtools/client/framework/toolbox");
var strings = Services.strings.createBundle(
"chrome://devtools/locale/toolbox.properties");
const {LocalizationHelper} = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools/locale/toolbox.properties");
var target, toolbox, description, reloadsSent, toolIDs;
@ -83,7 +84,7 @@ function testReload(shortcut, docked, toolID, callback) {
description = docked + " devtools with tool " + toolID + ", shortcut #" + shortcut;
info("Testing reload in " + description);
synthesizeKeyShortcut(strings.GetStringFromName(shortcut), toolbox.win);
synthesizeKeyShortcut(L10N.getStr(shortcut), toolbox.win);
reloadsSent++;
}

View File

@ -3,13 +3,12 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
var modifiers = {
accelKey: true
};
"use strict";
var toolbox;
var strings = Services.strings.createBundle(
"chrome://devtools/locale/toolbox.properties");
const {LocalizationHelper} = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools/locale/toolbox.properties");
function test() {
addTab("about:blank").then(openToolbox);
@ -48,7 +47,7 @@ function testZoomLevel(type, times, expected) {
function sendZoomKey(shortcut, times) {
for (let i = 0; i < times; i++) {
synthesizeKeyShortcut(strings.GetStringFromName(shortcut));
synthesizeKeyShortcut(L10N.getStr(shortcut));
}
}
@ -61,7 +60,7 @@ function tidyUp() {
toolbox.destroy().then(function () {
gBrowser.removeCurrentTab();
toolbox = modifiers = null;
toolbox = null;
finish();
});
}

View File

@ -8,26 +8,13 @@
const Services = require("Services");
const defer = require("devtools/shared/defer");
const {XPCOMUtils} = require("resource://gre/modules/XPCOMUtils.jsm");
const {Task} = require("devtools/shared/task");
const {gDevTools} = require("devtools/client/framework/devtools");
exports.OptionsPanel = OptionsPanel;
const {LocalizationHelper} = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools/locale/toolbox.properties");
XPCOMUtils.defineLazyGetter(this, "l10n", function () {
let bundle = Services.strings.createBundle("chrome://devtools/locale/toolbox.properties");
let l10n = function (name, ...aArgs) {
try {
if (aArgs.length == 0) {
return bundle.GetStringFromName(name);
}
return bundle.formatStringFromName(name, aArgs, aArgs.length);
} catch (ex) {
console.log("Error reading '" + name + "'");
}
};
return l10n;
});
exports.OptionsPanel = OptionsPanel;
function GetPref(name) {
let type = Services.prefs.getPrefType(name);
@ -220,8 +207,8 @@ OptionsPanel.prototype = {
checkboxSpanLabel.textContent = tool.label;
} else {
atleastOneToolNotSupported = true;
checkboxSpanLabel.textContent = l10n(
"options.toolNotSupportedMarker", tool.label);
checkboxSpanLabel.textContent =
L10N.getFormatStr("options.toolNotSupportedMarker", tool.label);
checkboxInput.setAttribute("data-unsupported", "true");
checkboxInput.setAttribute("disabled", "true");
}

View File

@ -32,21 +32,9 @@ const { KeyCodes } = require("devtools/client/shared/keycodes");
const { BrowserLoader } =
Cu.import("resource://devtools/client/shared/browser-loader.js", {});
loader.lazyGetter(this, "toolboxStrings", () => {
const properties = "chrome://devtools/locale/toolbox.properties";
const bundle = Services.strings.createBundle(properties);
return (name, ...args) => {
try {
if (!args.length) {
return bundle.GetStringFromName(name);
}
return bundle.formatStringFromName(name, args, args.length);
} catch (ex) {
console.log("Error reading '" + name + "'");
return null;
}
};
});
const {LocalizationHelper} = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools/locale/toolbox.properties");
loader.lazyRequireGetter(this, "CommandUtils",
"devtools/client/shared/developer-toolbar", true);
loader.lazyRequireGetter(this, "getHighlighterUtils",
@ -386,7 +374,7 @@ Toolbox.prototype = {
useOnlyShared: true
}).require;
iframe.setAttribute("aria-label", toolboxStrings("toolbox.label"));
iframe.setAttribute("aria-label", L10N.getStr("toolbox.label"));
let domHelper = new DOMHelpers(iframe.contentWindow);
domHelper.onceDOMReady(() => {
domReady.resolve();
@ -545,8 +533,8 @@ Toolbox.prototype = {
// Prevent the opening of bookmarks window on toolbox.options.key
event.preventDefault();
};
shortcuts.on(toolboxStrings("toolbox.options.key"), selectOptions);
shortcuts.on(toolboxStrings("toolbox.help.key"), selectOptions);
shortcuts.on(L10N.getStr("toolbox.options.key"), selectOptions);
shortcuts.on(L10N.getStr("toolbox.help.key"), selectOptions);
},
_splitConsoleOnKeypress: function (e) {
@ -591,7 +579,7 @@ Toolbox.prototype = {
["forceReload", true],
["forceReload2", true]
].forEach(([id, force]) => {
let key = toolboxStrings("toolbox." + id + ".key");
let key = L10N.getStr("toolbox." + id + ".key");
shortcuts.on(key, (name, event) => {
this.reloadTarget(force);
@ -602,13 +590,13 @@ Toolbox.prototype = {
},
_addHostListeners: function (shortcuts) {
shortcuts.on(toolboxStrings("toolbox.nextTool.key"),
shortcuts.on(L10N.getStr("toolbox.nextTool.key"),
this.selectNextTool.bind(this));
shortcuts.on(toolboxStrings("toolbox.previousTool.key"),
shortcuts.on(L10N.getStr("toolbox.previousTool.key"),
this.selectPreviousTool.bind(this));
shortcuts.on(toolboxStrings("toolbox.minimize.key"),
shortcuts.on(L10N.getStr("toolbox.minimize.key"),
this._toggleMinimizeMode.bind(this));
shortcuts.on(toolboxStrings("toolbox.toggleHost.key"),
shortcuts.on(L10N.getStr("toolbox.toggleHost.key"),
(name, event) => {
this.switchToPreviousHost();
event.preventDefault();
@ -703,7 +691,7 @@ Toolbox.prototype = {
let key = doc.createElement("key");
key.id = "key_browserconsole";
key.setAttribute("key", toolboxStrings("browserConsoleCmd.commandkey"));
key.setAttribute("key", L10N.getStr("browserConsoleCmd.commandkey"));
key.setAttribute("modifiers", "accel,shift");
// needed. See bug 371900
key.setAttribute("oncommand", "void(0)");
@ -807,7 +795,7 @@ Toolbox.prototype = {
let button = this.doc.createElementNS(HTML_NS, "button");
button.id = "toolbox-dock-" + position;
button.className = "toolbox-dock-button devtools-button";
button.setAttribute("title", toolboxStrings("toolboxDockButtons." +
button.setAttribute("title", L10N.getStr("toolboxDockButtons." +
position + ".tooltip"));
button.addEventListener("click", () => {
this.switchHost(position);
@ -818,7 +806,7 @@ Toolbox.prototype = {
},
_getMinimizeButtonShortcutTooltip: function () {
let str = toolboxStrings("toolbox.minimize.key");
let str = L10N.getStr("toolbox.minimize.key");
let key = KeyShortcuts.parseElectronKey(this.win, str);
return "(" + KeyShortcuts.stringify(key) + ")";
},
@ -828,7 +816,7 @@ Toolbox.prototype = {
btn.className = "minimized";
btn.setAttribute("title",
toolboxStrings("toolboxDockButtons.bottom.maximize") + " " +
L10N.getStr("toolboxDockButtons.bottom.maximize") + " " +
this._getMinimizeButtonShortcutTooltip());
},
@ -837,7 +825,7 @@ Toolbox.prototype = {
btn.className = "maximized";
btn.setAttribute("title",
toolboxStrings("toolboxDockButtons.bottom.minimize") + " " +
L10N.getStr("toolboxDockButtons.bottom.minimize") + " " +
this._getMinimizeButtonShortcutTooltip());
},
@ -985,7 +973,7 @@ Toolbox.prototype = {
this._pickerButton = this.doc.createElementNS(HTML_NS, "button");
this._pickerButton.id = "command-button-pick";
this._pickerButton.className = "command-button command-button-invertable devtools-button";
this._pickerButton.setAttribute("title", toolboxStrings("pickButton.tooltip"));
this._pickerButton.setAttribute("title", L10N.getStr("pickButton.tooltip"));
this._pickerButton.setAttribute("hidden", "true");
let container = this.doc.querySelector("#toolbox-picker-container");
@ -1577,10 +1565,10 @@ Toolbox.prototype = {
_refreshHostTitle: function () {
let title;
if (this.target.name && this.target.name != this.target.url) {
title = toolboxStrings("toolbox.titleTemplate2",
this.target.name, this.target.url);
title = L10N.getFormatStr("toolbox.titleTemplate2", this.target.name,
this.target.url);
} else {
title = toolboxStrings("toolbox.titleTemplate1", this.target.url);
title = L10N.getFormatStr("toolbox.titleTemplate1", this.target.url);
}
this._host.setTitle(title);
},
@ -1588,7 +1576,7 @@ Toolbox.prototype = {
// Returns an instance of the preference actor
get _preferenceFront() {
return this.target.root.then(rootForm => {
return new getPreferenceFront(this.target.client, rootForm);
return new L10N.getFormatStr(this.target.client, rootForm);
});
},

View File

@ -32,10 +32,9 @@ const clipboardHelper = require("devtools/shared/platform/clipboard");
XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
"resource://gre/modules/PluralForm.jsm");
XPCOMUtils.defineLazyGetter(CssComputedView, "_strings", function () {
return Services.strings.createBundle(
"chrome://devtools-shared/locale/styleinspector.properties");
});
const STYLE_INSPECTOR_PROPERTIES = "devtools-shared/locale/styleinspector.properties";
const {LocalizationHelper} = require("devtools/shared/l10n");
const STYLE_INSPECTOR_L10N = new LocalizationHelper(STYLE_INSPECTOR_PROPERTIES);
const FILTER_CHANGED_TIMEOUT = 150;
const HTML_NS = "http://www.w3.org/1999/xhtml";
@ -210,7 +209,7 @@ function CssComputedView(inspector, document, pageStyle) {
}
/**
* Memoized lookup of a l10n string from a string bundle.
* Lookup a l10n string in the shared styleinspector string bundle.
*
* @param {String} name
* The key to lookup.
@ -218,7 +217,7 @@ function CssComputedView(inspector, document, pageStyle) {
*/
CssComputedView.l10n = function (name) {
try {
return CssComputedView._strings.GetStringFromName(name);
return STYLE_INSPECTOR_L10N.getStr(name);
} catch (ex) {
console.log("Error reading '" + name + "'");
throw new Error("l10n error with " + name);

View File

@ -31,12 +31,9 @@ const {ToolSidebar} = require("devtools/client/inspector/toolsidebar");
const {ViewHelpers} = require("devtools/client/shared/widgets/view-helpers");
const clipboardHelper = require("devtools/shared/platform/clipboard");
loader.lazyGetter(this, "strings", () => {
return Services.strings.createBundle("chrome://devtools/locale/inspector.properties");
});
loader.lazyGetter(this, "toolboxStrings", () => {
return Services.strings.createBundle("chrome://devtools/locale/toolbox.properties");
});
const {LocalizationHelper} = require("devtools/shared/l10n");
const INSPECTOR_L10N = new LocalizationHelper("devtools/locale/inspector.properties");
const TOOLBOX_L10N = new LocalizationHelper("devtools/locale/toolbox.properties");
/**
* Represents an open instance of the Inspector for a tab.
@ -213,7 +210,7 @@ InspectorPanel.prototype = {
notificationBox.getNotificationWithValue("inspector-script-paused");
if (!notification && this._toolbox.currentToolId == "inspector" &&
this._toolbox.threadClient.paused) {
let message = strings.GetStringFromName("debuggerPausedWarning.message");
let message = INSPECTOR_L10N.getStr("debuggerPausedWarning.message");
notificationBox.appendNotification(message,
"inspector-script-paused", "", notificationBox.PRIORITY_WARNING_HIGH);
}
@ -361,7 +358,7 @@ InspectorPanel.prototype = {
let shortcuts = new KeyShortcuts({
window: this.panelDoc.defaultView,
});
let key = strings.GetStringFromName("inspector.searchHTML.key");
let key = INSPECTOR_L10N.getStr("inspector.searchHTML.key");
shortcuts.on(key, (name, event) => {
// Prevent overriding same shortcut from the computed/rule views
if (event.target.closest("#sidebar-panel-ruleview") ||
@ -381,11 +378,10 @@ InspectorPanel.prototype = {
let str = "";
if (event !== "search-cleared") {
if (result) {
str = strings.formatStringFromName(
"inspector.searchResultsCount2",
[result.resultsIndex + 1, result.resultsLength], 2);
str = INSPECTOR_L10N.getFormatStr(
"inspector.searchResultsCount2", result.resultsIndex + 1, result.resultsLength);
} else {
str = strings.GetStringFromName("inspector.searchResultsNone");
str = INSPECTOR_L10N.getStr("inspector.searchResultsNone");
}
}
@ -423,12 +419,12 @@ InspectorPanel.prototype = {
// Append all side panels
this.sidebar.addExistingTab(
"ruleview",
strings.GetStringFromName("inspector.sidebar.ruleViewTitle"),
INSPECTOR_L10N.getStr("inspector.sidebar.ruleViewTitle"),
defaultTab == "ruleview");
this.sidebar.addExistingTab(
"computedview",
strings.GetStringFromName("inspector.sidebar.computedViewTitle"),
INSPECTOR_L10N.getStr("inspector.sidebar.computedViewTitle"),
defaultTab == "computedview");
this._setDefaultSidebar = (event, toolId) => {
@ -443,7 +439,7 @@ InspectorPanel.prototype = {
if (this.target.form.animationsActor) {
this.sidebar.addFrameTab(
"animationinspector",
strings.GetStringFromName("inspector.sidebar.animationInspectorTitle"),
INSPECTOR_L10N.getStr("inspector.sidebar.animationInspectorTitle"),
"chrome://devtools/content/animationinspector/animation-inspector.xhtml",
defaultTab == "animationinspector");
}
@ -452,7 +448,7 @@ InspectorPanel.prototype = {
this.canGetUsedFontFaces) {
this.sidebar.addExistingTab(
"fontinspector",
strings.GetStringFromName("inspector.sidebar.fontInspectorTitle"),
INSPECTOR_L10N.getStr("inspector.sidebar.fontInspectorTitle"),
defaultTab == "fontinspector");
this.fontInspector = new FontInspector(this, this.panelWin);
@ -519,8 +515,8 @@ InspectorPanel.prototype = {
let sidebarToggle = SidebarToggle({
onClick: this.onPaneToggleButtonClicked,
collapsed: false,
expandPaneTitle: strings.GetStringFromName("inspector.expandPane"),
collapsePaneTitle: strings.GetStringFromName("inspector.collapsePane"),
expandPaneTitle: INSPECTOR_L10N.getStr("inspector.expandPane"),
collapsePaneTitle: INSPECTOR_L10N.getStr("inspector.collapsePane"),
});
let parentBox = this.panelDoc.getElementById("inspector-sidebar-toggle-box");
@ -875,37 +871,37 @@ InspectorPanel.prototype = {
let menu = new Menu();
menu.append(new MenuItem({
id: "node-menu-edithtml",
label: strings.GetStringFromName("inspectorHTMLEdit.label"),
accesskey: strings.GetStringFromName("inspectorHTMLEdit.accesskey"),
label: INSPECTOR_L10N.getStr("inspectorHTMLEdit.label"),
accesskey: INSPECTOR_L10N.getStr("inspectorHTMLEdit.accesskey"),
disabled: !isEditableElement || !this.isOuterHTMLEditable,
click: () => this.editHTML(),
}));
menu.append(new MenuItem({
id: "node-menu-add",
label: strings.GetStringFromName("inspectorAddNode.label"),
accesskey: strings.GetStringFromName("inspectorAddNode.accesskey"),
label: INSPECTOR_L10N.getStr("inspectorAddNode.label"),
accesskey: INSPECTOR_L10N.getStr("inspectorAddNode.accesskey"),
disabled: !this.canAddHTMLChild(),
click: () => this.addNode(),
}));
menu.append(new MenuItem({
id: "node-menu-duplicatenode",
label: strings.GetStringFromName("inspectorDuplicateNode.label"),
label: INSPECTOR_L10N.getStr("inspectorDuplicateNode.label"),
hidden: !this._supportsDuplicateNode,
disabled: !isDuplicatableElement,
click: () => this.duplicateNode(),
}));
menu.append(new MenuItem({
id: "node-menu-delete",
label: strings.GetStringFromName("inspectorHTMLDelete.label"),
accesskey: strings.GetStringFromName("inspectorHTMLDelete.accesskey"),
label: INSPECTOR_L10N.getStr("inspectorHTMLDelete.label"),
accesskey: INSPECTOR_L10N.getStr("inspectorHTMLDelete.accesskey"),
disabled: !isEditableElement,
click: () => this.deleteNode(),
}));
menu.append(new MenuItem({
label: strings.GetStringFromName("inspectorAttributesSubmenu.label"),
label: INSPECTOR_L10N.getStr("inspectorAttributesSubmenu.label"),
accesskey:
strings.GetStringFromName("inspectorAttributesSubmenu.accesskey"),
INSPECTOR_L10N.getStr("inspectorAttributesSubmenu.accesskey"),
submenu: this._getAttributesSubmenu(isEditableElement),
}));
@ -939,42 +935,42 @@ InspectorPanel.prototype = {
let copySubmenu = new Menu();
copySubmenu.append(new MenuItem({
id: "node-menu-copyinner",
label: strings.GetStringFromName("inspectorCopyInnerHTML.label"),
accesskey: strings.GetStringFromName("inspectorCopyInnerHTML.accesskey"),
label: INSPECTOR_L10N.getStr("inspectorCopyInnerHTML.label"),
accesskey: INSPECTOR_L10N.getStr("inspectorCopyInnerHTML.accesskey"),
disabled: !isSelectionElement,
click: () => this.copyInnerHTML(),
}));
copySubmenu.append(new MenuItem({
id: "node-menu-copyouter",
label: strings.GetStringFromName("inspectorCopyOuterHTML.label"),
accesskey: strings.GetStringFromName("inspectorCopyOuterHTML.accesskey"),
label: INSPECTOR_L10N.getStr("inspectorCopyOuterHTML.label"),
accesskey: INSPECTOR_L10N.getStr("inspectorCopyOuterHTML.accesskey"),
disabled: !isSelectionElement,
click: () => this.copyOuterHTML(),
}));
copySubmenu.append(new MenuItem({
id: "node-menu-copyuniqueselector",
label: strings.GetStringFromName("inspectorCopyCSSSelector.label"),
label: INSPECTOR_L10N.getStr("inspectorCopyCSSSelector.label"),
accesskey:
strings.GetStringFromName("inspectorCopyCSSSelector.accesskey"),
INSPECTOR_L10N.getStr("inspectorCopyCSSSelector.accesskey"),
disabled: !isSelectionElement,
hidden: !this.canGetUniqueSelector,
click: () => this.copyUniqueSelector(),
}));
copySubmenu.append(new MenuItem({
id: "node-menu-copyimagedatauri",
label: strings.GetStringFromName("inspectorImageDataUri.label"),
label: INSPECTOR_L10N.getStr("inspectorImageDataUri.label"),
disabled: !isSelectionElement || !markupContainer ||
!markupContainer.isPreviewable(),
click: () => this.copyImageDataUri(),
}));
menu.append(new MenuItem({
label: strings.GetStringFromName("inspectorCopyHTMLSubmenu.label"),
label: INSPECTOR_L10N.getStr("inspectorCopyHTMLSubmenu.label"),
submenu: copySubmenu,
}));
menu.append(new MenuItem({
label: strings.GetStringFromName("inspectorPasteHTMLSubmenu.label"),
label: INSPECTOR_L10N.getStr("inspectorPasteHTMLSubmenu.label"),
submenu: this._getPasteSubmenu(isEditableElement),
}));
@ -986,13 +982,13 @@ InspectorPanel.prototype = {
markupContainer.hasChildren;
menu.append(new MenuItem({
id: "node-menu-expand",
label: strings.GetStringFromName("inspectorExpandNode.label"),
label: INSPECTOR_L10N.getStr("inspectorExpandNode.label"),
disabled: !isNodeWithChildren,
click: () => this.expandNode(),
}));
menu.append(new MenuItem({
id: "node-menu-collapse",
label: strings.GetStringFromName("inspectorCollapseNode.label"),
label: INSPECTOR_L10N.getStr("inspectorCollapseNode.label"),
disabled: !isNodeWithChildren || !markupContainer.expanded,
click: () => this.collapseNode(),
}));
@ -1003,27 +999,27 @@ InspectorPanel.prototype = {
menu.append(new MenuItem({
id: "node-menu-scrollnodeintoview",
label: strings.GetStringFromName("inspectorScrollNodeIntoView.label"),
label: INSPECTOR_L10N.getStr("inspectorScrollNodeIntoView.label"),
accesskey:
strings.GetStringFromName("inspectorScrollNodeIntoView.accesskey"),
INSPECTOR_L10N.getStr("inspectorScrollNodeIntoView.accesskey"),
hidden: !this._supportsScrollIntoView,
disabled: !isSelectionElement,
click: () => this.scrollNodeIntoView(),
}));
menu.append(new MenuItem({
id: "node-menu-screenshotnode",
label: strings.GetStringFromName("inspectorScreenshotNode.label"),
label: INSPECTOR_L10N.getStr("inspectorScreenshotNode.label"),
disabled: !isScreenshotable,
click: () => this.screenshotNode(),
}));
menu.append(new MenuItem({
id: "node-menu-useinconsole",
label: strings.GetStringFromName("inspectorUseInConsole.label"),
label: INSPECTOR_L10N.getStr("inspectorUseInConsole.label"),
click: () => this.useInConsole(),
}));
menu.append(new MenuItem({
id: "node-menu-showdomproperties",
label: strings.GetStringFromName("inspectorShowDOMProperties.label"),
label: INSPECTOR_L10N.getStr("inspectorShowDOMProperties.label"),
click: () => this.showDOMProperties(),
}));
@ -1055,47 +1051,47 @@ InspectorPanel.prototype = {
let pasteSubmenu = new Menu();
pasteSubmenu.append(new MenuItem({
id: "node-menu-pasteinnerhtml",
label: strings.GetStringFromName("inspectorPasteInnerHTML.label"),
accesskey: strings.GetStringFromName("inspectorPasteInnerHTML.accesskey"),
label: INSPECTOR_L10N.getStr("inspectorPasteInnerHTML.label"),
accesskey: INSPECTOR_L10N.getStr("inspectorPasteInnerHTML.accesskey"),
disabled: !isPasteable || !this.canPasteInnerOrAdjacentHTML,
click: () => this.pasteInnerHTML(),
}));
pasteSubmenu.append(new MenuItem({
id: "node-menu-pasteouterhtml",
label: strings.GetStringFromName("inspectorPasteOuterHTML.label"),
accesskey: strings.GetStringFromName("inspectorPasteOuterHTML.accesskey"),
label: INSPECTOR_L10N.getStr("inspectorPasteOuterHTML.label"),
accesskey: INSPECTOR_L10N.getStr("inspectorPasteOuterHTML.accesskey"),
disabled: !isPasteable || !this.isOuterHTMLEditable,
click: () => this.pasteOuterHTML(),
}));
pasteSubmenu.append(new MenuItem({
id: "node-menu-pastebefore",
label: strings.GetStringFromName("inspectorHTMLPasteBefore.label"),
label: INSPECTOR_L10N.getStr("inspectorHTMLPasteBefore.label"),
accesskey:
strings.GetStringFromName("inspectorHTMLPasteBefore.accesskey"),
INSPECTOR_L10N.getStr("inspectorHTMLPasteBefore.accesskey"),
disabled: disableAdjacentPaste,
click: () => this.pasteAdjacentHTML("beforeBegin"),
}));
pasteSubmenu.append(new MenuItem({
id: "node-menu-pasteafter",
label: strings.GetStringFromName("inspectorHTMLPasteAfter.label"),
label: INSPECTOR_L10N.getStr("inspectorHTMLPasteAfter.label"),
accesskey:
strings.GetStringFromName("inspectorHTMLPasteAfter.accesskey"),
INSPECTOR_L10N.getStr("inspectorHTMLPasteAfter.accesskey"),
disabled: disableAdjacentPaste,
click: () => this.pasteAdjacentHTML("afterEnd"),
}));
pasteSubmenu.append(new MenuItem({
id: "node-menu-pastefirstchild",
label: strings.GetStringFromName("inspectorHTMLPasteFirstChild.label"),
label: INSPECTOR_L10N.getStr("inspectorHTMLPasteFirstChild.label"),
accesskey:
strings.GetStringFromName("inspectorHTMLPasteFirstChild.accesskey"),
INSPECTOR_L10N.getStr("inspectorHTMLPasteFirstChild.accesskey"),
disabled: disableFirstLastPaste,
click: () => this.pasteAdjacentHTML("afterBegin"),
}));
pasteSubmenu.append(new MenuItem({
id: "node-menu-pastelastchild",
label: strings.GetStringFromName("inspectorHTMLPasteLastChild.label"),
label: INSPECTOR_L10N.getStr("inspectorHTMLPasteLastChild.label"),
accesskey:
strings.GetStringFromName("inspectorHTMLPasteLastChild.accesskey"),
INSPECTOR_L10N.getStr("inspectorHTMLPasteLastChild.accesskey"),
disabled: disableFirstLastPaste,
click: () => this.pasteAdjacentHTML("beforeEnd"),
}));
@ -1111,26 +1107,26 @@ InspectorPanel.prototype = {
attributesSubmenu.append(new MenuItem({
id: "node-menu-add-attribute",
label: strings.GetStringFromName("inspectorAddAttribute.label"),
accesskey: strings.GetStringFromName("inspectorAddAttribute.accesskey"),
label: INSPECTOR_L10N.getStr("inspectorAddAttribute.label"),
accesskey: INSPECTOR_L10N.getStr("inspectorAddAttribute.accesskey"),
disabled: !isEditableElement,
click: () => this.onAddAttribute(),
}));
attributesSubmenu.append(new MenuItem({
id: "node-menu-edit-attribute",
label: strings.formatStringFromName("inspectorEditAttribute.label",
[isAttributeClicked ? `"${nodeInfo.name}"` : ""], 1),
accesskey: strings.GetStringFromName("inspectorEditAttribute.accesskey"),
label: INSPECTOR_L10N.getFormatStr("inspectorEditAttribute.label",
isAttributeClicked ? `"${nodeInfo.name}"` : ""),
accesskey: INSPECTOR_L10N.getStr("inspectorEditAttribute.accesskey"),
disabled: !isAttributeClicked,
click: () => this.onEditAttribute(),
}));
attributesSubmenu.append(new MenuItem({
id: "node-menu-remove-attribute",
label: strings.formatStringFromName("inspectorRemoveAttribute.label",
[isAttributeClicked ? `"${nodeInfo.name}"` : ""], 1),
label: INSPECTOR_L10N.getFormatStr("inspectorRemoveAttribute.label",
isAttributeClicked ? `"${nodeInfo.name}"` : ""),
accesskey:
strings.GetStringFromName("inspectorRemoveAttribute.accesskey"),
INSPECTOR_L10N.getStr("inspectorRemoveAttribute.accesskey"),
disabled: !isAttributeClicked,
click: () => this.onRemoveAttribute(),
}));
@ -1168,25 +1164,25 @@ InspectorPanel.prototype = {
// Links can't be opened in new tabs in the browser toolbox.
if (type === "uri" && !this.target.chrome) {
linkFollow.visible = true;
linkFollow.label = strings.GetStringFromName(
linkFollow.label = INSPECTOR_L10N.getStr(
"inspector.menu.openUrlInNewTab.label");
} else if (type === "cssresource") {
linkFollow.visible = true;
linkFollow.label = toolboxStrings.GetStringFromName(
linkFollow.label = TOOLBOX_L10N.getStr(
"toolbox.viewCssSourceInStyleEditor.label");
} else if (type === "jsresource") {
linkFollow.visible = true;
linkFollow.label = toolboxStrings.GetStringFromName(
linkFollow.label = TOOLBOX_L10N.getStr(
"toolbox.viewJsSourceInDebugger.label");
}
linkCopy.visible = true;
linkCopy.label = strings.GetStringFromName(
linkCopy.label = INSPECTOR_L10N.getStr(
"inspector.menu.copyUrlToClipboard.label");
} else if (type === "idref") {
linkFollow.visible = true;
linkFollow.label = strings.formatStringFromName(
"inspector.menu.selectElement.label", [popupNode.dataset.link], 1);
linkFollow.label = INSPECTOR_L10N.getFormatStr(
"inspector.menu.selectElement.label", popupNode.dataset.link);
}
return [linkFollow, linkCopy];
@ -1210,7 +1206,7 @@ InspectorPanel.prototype = {
this._markupBox.appendChild(this._markupFrame);
this._markupFrame.setAttribute("src", "chrome://devtools/content/inspector/markup/markup.xhtml");
this._markupFrame.setAttribute("aria-label",
strings.GetStringFromName("inspector.panelLabel.markupView"));
INSPECTOR_L10N.getStr("inspector.panelLabel.markupView"));
},
_onMarkupFrameLoad: function () {

View File

@ -113,19 +113,17 @@ InspectorSearch.prototype = {
}),
_onInput: function () {
if (this.searchBox.value.length === 0) {
this._onSearch();
}
},
_onKeyDown: function (event) {
if (this.searchBox.value.length === 0) {
this.searchClearButton.hidden = true;
this.searchBox.removeAttribute("filled");
this._onSearch();
} else {
this.searchClearButton.hidden = false;
this.searchBox.setAttribute("filled", true);
}
},
_onKeyDown: function (event) {
if (event.keyCode === KeyCodes.DOM_VK_RETURN) {
this._onSearch(event.shiftKey);
}

View File

@ -61,6 +61,9 @@ const {KeyCodes} = require("devtools/client/shared/keycodes");
const {AutocompletePopup} = require("devtools/client/shared/autocomplete-popup");
const clipboardHelper = require("devtools/shared/platform/clipboard");
const {LocalizationHelper} = require("devtools/shared/l10n");
const INSPECTOR_L10N = new LocalizationHelper("devtools/locale/inspector.properties");
XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
"resource://gre/modules/PluralForm.jsm");
@ -686,7 +689,7 @@ MarkupView.prototype = {
["markupView.hide.key",
"markupView.edit.key",
"markupView.scrollInto.key"].forEach(name => {
let key = this.strings.GetStringFromName(name);
let key = INSPECTOR_L10N.getStr(name);
shortcuts.on(key, (_, event) => this._onShortcut(name, event));
});
@ -1666,9 +1669,9 @@ MarkupView.prototype = {
if (!(children.hasFirst && children.hasLast)) {
let nodesCount = container.node.numChildren;
let showAllString = PluralForm.get(nodesCount,
this.strings.GetStringFromName("markupView.more.showAll2"));
INSPECTOR_L10N.getStr("markupView.more.showAll2"));
let data = {
showing: this.strings.GetStringFromName("markupView.more.showing"),
showing: INSPECTOR_L10N.getStr("markupView.more.showing"),
showAll: showAllString.replace("#1", nodesCount),
allButtonClick: () => {
container.maxChildren = -1;
@ -3616,8 +3619,4 @@ function getAutocompleteMaxWidth(element, container) {
return containerRect.right - elementRect.left - 2;
}
loader.lazyGetter(MarkupView.prototype, "strings", () => Services.strings.createBundle(
"chrome://devtools/locale/inspector.properties"
));
exports.MarkupView = MarkupView;

View File

@ -8,10 +8,8 @@
// in an attribute.
const TEST_URL = URL_ROOT + "doc_markup_links.html";
const STRINGS = Services.strings
.createBundle("chrome://devtools/locale/inspector.properties");
const TOOLBOX_STRINGS = Services.strings
.createBundle("chrome://devtools/locale/toolbox.properties");
const TOOLBOX_L10N = new LocalizationHelper("devtools/locale/toolbox.properties");
// The test case array contains objects with the following properties:
// - selector: css selector for the node to select in the inspector
@ -28,9 +26,9 @@ const TEST_DATA = [{
popupNodeSelector: ".link",
isLinkFollowItemVisible: true,
isLinkCopyItemVisible: true,
linkFollowItemLabel: TOOLBOX_STRINGS.GetStringFromName(
linkFollowItemLabel: TOOLBOX_L10N.getStr(
"toolbox.viewCssSourceInStyleEditor.label"),
linkCopyItemLabel: STRINGS.GetStringFromName(
linkCopyItemLabel: INSPECTOR_L10N.getStr(
"inspector.menu.copyUrlToClipboard.label")
}, {
selector: "link[rel=icon]",
@ -38,9 +36,9 @@ const TEST_DATA = [{
popupNodeSelector: ".link",
isLinkFollowItemVisible: true,
isLinkCopyItemVisible: true,
linkFollowItemLabel: STRINGS.GetStringFromName(
linkFollowItemLabel: INSPECTOR_L10N.getStr(
"inspector.menu.openUrlInNewTab.label"),
linkCopyItemLabel: STRINGS.GetStringFromName(
linkCopyItemLabel: INSPECTOR_L10N.getStr(
"inspector.menu.copyUrlToClipboard.label")
}, {
selector: "link",
@ -54,17 +52,17 @@ const TEST_DATA = [{
popupNodeSelector: ".link",
isLinkFollowItemVisible: true,
isLinkCopyItemVisible: false,
linkFollowItemLabel: STRINGS.formatStringFromName(
"inspector.menu.selectElement.label", ["name"], 1)
linkFollowItemLabel: INSPECTOR_L10N.getFormatStr(
"inspector.menu.selectElement.label", "name")
}, {
selector: "script",
attributeName: "src",
popupNodeSelector: ".link",
isLinkFollowItemVisible: true,
isLinkCopyItemVisible: true,
linkFollowItemLabel: TOOLBOX_STRINGS.GetStringFromName(
linkFollowItemLabel: TOOLBOX_L10N.getStr(
"toolbox.viewJsSourceInDebugger.label"),
linkCopyItemLabel: STRINGS.GetStringFromName(
linkCopyItemLabel: INSPECTOR_L10N.getStr(
"inspector.menu.copyUrlToClipboard.label")
}, {
selector: "p[for]",

View File

@ -15,6 +15,10 @@ const {promiseWarn} = require("devtools/client/inspector/shared/utils");
const {parseDeclarations} = require("devtools/shared/css-parsing-utils");
const Services = require("Services");
const STYLE_INSPECTOR_PROPERTIES = "devtools-shared/locale/styleinspector.properties";
const {LocalizationHelper} = require("devtools/shared/l10n");
const STYLE_INSPECTOR_L10N = new LocalizationHelper(STYLE_INSPECTOR_PROPERTIES);
/**
* Rule is responsible for the following:
* Manages a single style declaration or rule.
@ -80,8 +84,7 @@ Rule.prototype = {
eltText += "#" + this.inherited.id;
}
this._inheritedSource =
CssLogic._strings.formatStringFromName("rule.inheritedFrom",
[eltText], 1);
STYLE_INSPECTOR_L10N.getFormatStr("rule.inheritedFrom", eltText);
}
return this._inheritedSource;
},
@ -93,8 +96,7 @@ Rule.prototype = {
this._keyframesName = "";
if (this.keyframes) {
this._keyframesName =
CssLogic._strings.formatStringFromName("rule.keyframe",
[this.keyframes.name], 1);
STYLE_INSPECTOR_L10N.getFormatStr("rule.keyframe", this.keyframes.name);
}
return this._keyframesName;
},

View File

@ -10,9 +10,6 @@
const promise = require("promise");
const defer = require("devtools/shared/defer");
const Services = require("Services");
/* eslint-disable mozilla/reject-some-requires */
const {XPCOMUtils} = require("resource://gre/modules/XPCOMUtils.jsm");
/* eslint-enable mozilla/reject-some-requires */
const {Task} = require("devtools/shared/task");
const {Tools} = require("devtools/client/definitions");
const {l10n} = require("devtools/shared/inspector/css-logic");
@ -32,11 +29,6 @@ const StyleInspectorMenu = require("devtools/client/inspector/shared/style-inspe
const {KeyShortcuts} = require("devtools/client/shared/key-shortcuts");
const clipboardHelper = require("devtools/shared/platform/clipboard");
XPCOMUtils.defineLazyGetter(this, "_strings", function () {
return Services.strings.createBundle(
"chrome://devtools-shared/locale/styleinspector.properties");
});
const {AutocompletePopup} = require("devtools/client/shared/autocomplete-popup");
const HTML_NS = "http://www.w3.org/1999/xhtml";

View File

@ -22,7 +22,7 @@ function* addNewRuleFromContextMenu(inspector, view) {
let allMenuItems = openStyleContextMenuAndGetAllItems(view, view.element);
let menuitemAddRule = allMenuItems.find(item => item.label ===
_STRINGS.GetStringFromName("styleinspector.contextmenu.addNewRule"));
STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.addNewRule"));
ok(menuitemAddRule.visible, "Add rule is visible");

View File

@ -17,9 +17,6 @@ const CONTENT = `
</body>
`;
const STRINGS = Services.strings
.createBundle("chrome://devtools-shared/locale/styleinspector.properties");
add_task(function* () {
let tab = yield addTab("data:text/html;charset=utf-8," + CONTENT);
@ -36,13 +33,13 @@ function checkRuleViewContent({styleDocument}) {
is(headers.length, 3, "There are 3 headers for inherited rules");
is(headers[0].textContent,
STRINGS.formatStringFromName("rule.inheritedFrom", ["p"], 1),
STYLE_INSPECTOR_L10N.getFormatStr("rule.inheritedFrom", "p"),
"The first header is correct");
is(headers[1].textContent,
STRINGS.formatStringFromName("rule.inheritedFrom", ["div"], 1),
STYLE_INSPECTOR_L10N.getFormatStr("rule.inheritedFrom", "div"),
"The second header is correct");
is(headers[2].textContent,
STRINGS.formatStringFromName("rule.inheritedFrom", ["body"], 1),
STYLE_INSPECTOR_L10N.getFormatStr("rule.inheritedFrom", "body"),
"The third header is correct");
let rules = styleDocument.querySelectorAll(".ruleview-rule");
@ -50,17 +47,14 @@ function checkRuleViewContent({styleDocument}) {
for (let rule of rules) {
let selector = rule.querySelector(".ruleview-selectorcontainer");
is(selector.textContent,
STRINGS.GetStringFromName("rule.sourceElement"),
is(selector.textContent, STYLE_INSPECTOR_L10N.getStr("rule.sourceElement"),
"The rule's selector is correct");
let propertyNames = [...rule.querySelectorAll(".ruleview-propertyname")];
is(propertyNames.length, 1,
"There's only one property name, as expected");
is(propertyNames.length, 1, "There's only one property name, as expected");
let propertyValues = [...rule.querySelectorAll(".ruleview-propertyvalue")];
is(propertyValues.length, 1,
"There's only one property value, as expected");
is(propertyValues.length, 1, "There's only one property value, as expected");
}
}

View File

@ -61,7 +61,7 @@ function* testMdnContextMenuItemVisibility(view) {
info("Creating context menu with " + node + " as popupNode");
let allMenuItems = openStyleContextMenuAndGetAllItems(view, node);
let menuitemShowMdnDocs = allMenuItems.find(item => item.label ===
_STRINGS.GetStringFromName("styleinspector.contextmenu.showMdnDocs"));
STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.showMdnDocs"));
let isVisible = menuitemShowMdnDocs.visible;
let shouldBeVisible = isPropertyNameNode(node);

View File

@ -45,7 +45,7 @@ add_task(function* () {
let allMenuItems = openStyleContextMenuAndGetAllItems(view, nameSpan.firstChild);
let menuitemShowMdnDocs = allMenuItems.find(item => item.label ===
_STRINGS.GetStringFromName("styleinspector.contextmenu.showMdnDocs"));
STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.showMdnDocs"));
let cssDocs = view.tooltips.cssDocs;

View File

@ -105,7 +105,7 @@ function* testMdnContextMenuItemVisibility(view, shouldBeVisible) {
let node = root.querySelector("." + PROPERTY_NAME_CLASS).firstChild;
let allMenuItems = openStyleContextMenuAndGetAllItems(view, node);
let menuitemShowMdnDocs = allMenuItems.find(item => item.label ===
_STRINGS.GetStringFromName("styleinspector.contextmenu.showMdnDocs"));
STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.showMdnDocs"));
let isVisible = menuitemShowMdnDocs.visible;
is(isVisible, shouldBeVisible,

View File

@ -215,21 +215,21 @@ add_task(function* () {
function* checkCopyStyle(view, node, menuItemLabel, expectedPattern, visible) {
let allMenuItems = openStyleContextMenuAndGetAllItems(view, node);
let menuItem = allMenuItems.find(item =>
item.label === _STRINGS.GetStringFromName(menuItemLabel));
item.label === STYLE_INSPECTOR_L10N.getStr(menuItemLabel));
let menuitemCopy = allMenuItems.find(item => item.label ===
_STRINGS.GetStringFromName("styleinspector.contextmenu.copy"));
STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.copy"));
let menuitemCopyLocation = allMenuItems.find(item => item.label ===
_STRINGS.GetStringFromName("styleinspector.contextmenu.copyLocation"));
STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.copyLocation"));
let menuitemCopyPropertyDeclaration = allMenuItems.find(item => item.label ===
_STRINGS.GetStringFromName("styleinspector.contextmenu.copyPropertyDeclaration"));
STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.copyPropertyDeclaration"));
let menuitemCopyPropertyName = allMenuItems.find(item => item.label ===
_STRINGS.GetStringFromName("styleinspector.contextmenu.copyPropertyName"));
STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.copyPropertyName"));
let menuitemCopyPropertyValue = allMenuItems.find(item => item.label ===
_STRINGS.GetStringFromName("styleinspector.contextmenu.copyPropertyValue"));
STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.copyPropertyValue"));
let menuitemCopySelector = allMenuItems.find(item => item.label ===
_STRINGS.GetStringFromName("styleinspector.contextmenu.copySelector"));
STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.copySelector"));
let menuitemCopyRule = allMenuItems.find(item => item.label ===
_STRINGS.GetStringFromName("styleinspector.contextmenu.copyRule"));
STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.copyRule"));
ok(menuitemCopy.disabled,
"Copy disabled is as expected: true");

View File

@ -16,10 +16,7 @@ add_task(function* () {
let elementStyle = view._elementStyle;
let _strings = Services.strings
.createBundle("chrome://devtools-shared/locale/styleinspector.properties");
let inline = _strings.GetStringFromName("rule.sourceInline");
let inline = STYLE_INSPECTOR_L10N.getStr("rule.sourceInline");
is(elementStyle.rules.length, 3, "Should have 3 rules.");
is(elementStyle.rules[0].title, inline, "check rule 0 title");

View File

@ -69,7 +69,7 @@ function* checkCopySelection(view) {
let allMenuItems = openStyleContextMenuAndGetAllItems(view, prop);
let menuitemCopy = allMenuItems.find(item => item.label ===
_STRINGS.GetStringFromName("styleinspector.contextmenu.copy"));
STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.copy"));
ok(menuitemCopy.visible,
"Copy menu item is displayed as expected");
@ -103,7 +103,7 @@ function* checkSelectAll(view) {
let allMenuItems = openStyleContextMenuAndGetAllItems(view, prop);
let menuitemCopy = allMenuItems.find(item => item.label ===
_STRINGS.GetStringFromName("styleinspector.contextmenu.copy"));
STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.copy"));
ok(menuitemCopy.visible,
"Copy menu item is displayed as expected");
@ -131,7 +131,7 @@ function* checkCopyEditorValue(view) {
let allMenuItems = openStyleContextMenuAndGetAllItems(view, editor.input);
let menuitemCopy = allMenuItems.find(item => item.label ===
_STRINGS.GetStringFromName("styleinspector.contextmenu.copy"));
STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.copy"));
ok(menuitemCopy.visible,
"Copy menu item is displayed as expected");

View File

@ -19,8 +19,8 @@ var {getInplaceEditorForSpan: inplaceEditor} =
const ROOT_TEST_DIR = getRootDirectory(gTestPath);
const FRAME_SCRIPT_URL = ROOT_TEST_DIR + "doc_frame_script.js";
const _STRINGS = Services.strings.createBundle(
"chrome://devtools-shared/locale/styleinspector.properties");
const STYLE_INSPECTOR_L10N = new LocalizationHelper("chrome://devtools-shared/locale/styleinspector.properties");
registerCleanupFunction(() => {
Services.prefs.clearUserPref("devtools.defaultColorUnit");

View File

@ -4,9 +4,6 @@
"use strict";
/* eslint-disable mozilla/reject-some-requires */
const {XPCOMUtils} = require("resource://gre/modules/XPCOMUtils.jsm");
/* eslint-enable mozilla/reject-some-requires */
const {l10n} = require("devtools/shared/inspector/css-logic");
const {ELEMENT_STYLE} = require("devtools/shared/specs/styles");
const {PREF_ORIG_SOURCES} = require("devtools/client/styleeditor/utils");
@ -31,10 +28,9 @@ const promise = require("promise");
const Services = require("Services");
const EventEmitter = require("devtools/shared/event-emitter");
XPCOMUtils.defineLazyGetter(this, "_strings", function () {
return Services.strings.createBundle(
"chrome://devtools-shared/locale/styleinspector.properties");
});
const STYLE_INSPECTOR_PROPERTIES = "devtools-shared/locale/styleinspector.properties";
const {LocalizationHelper} = require("devtools/shared/l10n");
const STYLE_INSPECTOR_L10N = new LocalizationHelper(STYLE_INSPECTOR_PROPERTIES);
const HTML_NS = "http://www.w3.org/1999/xhtml";
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
@ -239,7 +235,7 @@ RuleEditor.prototype = {
}
if (this.rule.isSystem) {
let uaLabel = _strings.GetStringFromName("rule.userAgentStyles");
let uaLabel = STYLE_INSPECTOR_L10N.getStr("rule.userAgentStyles");
sourceLabel.setAttribute("value", uaLabel + " " + title);
// Special case about:PreferenceStyleSheet, as it is generated on the

View File

@ -3,7 +3,6 @@
/* 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/. */
/* global _strings */
"use strict";
@ -16,10 +15,10 @@ const MenuItem = require("devtools/client/framework/menu-item");
const overlays = require("devtools/client/inspector/shared/style-inspector-overlays");
const clipboardHelper = require("devtools/shared/platform/clipboard");
loader.lazyGetter(this, "_strings", () => {
return Services.strings
.createBundle("chrome://devtools-shared/locale/styleinspector.properties");
});
const STYLE_INSPECTOR_PROPERTIES = "devtools-shared/locale/styleinspector.properties";
const {LocalizationHelper} = require("devtools/shared/l10n");
const STYLE_INSPECTOR_L10N = new LocalizationHelper(STYLE_INSPECTOR_PROPERTIES);
const PREF_ENABLE_MDN_DOCS_TOOLTIP =
"devtools.inspector.mdnDocsTooltip.enabled";
@ -83,22 +82,22 @@ StyleInspectorMenu.prototype = {
let menu = new Menu();
let menuitemCopy = new MenuItem({
label: _strings.GetStringFromName("styleinspector.contextmenu.copy"),
accesskey: _strings.GetStringFromName("styleinspector.contextmenu.copy.accessKey"),
label: STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.copy"),
accesskey: STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.copy.accessKey"),
click: () => {
this._onCopy();
},
disabled: !this._hasTextSelected(),
});
let menuitemCopyLocation = new MenuItem({
label: _strings.GetStringFromName("styleinspector.contextmenu.copyLocation"),
label: STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.copyLocation"),
click: () => {
this._onCopyLocation();
},
visible: false,
});
let menuitemCopyRule = new MenuItem({
label: _strings.GetStringFromName("styleinspector.contextmenu.copyRule"),
label: STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.copyRule"),
click: () => {
this._onCopyRule();
},
@ -106,8 +105,8 @@ StyleInspectorMenu.prototype = {
});
let copyColorAccessKey = "styleinspector.contextmenu.copyColor.accessKey";
let menuitemCopyColor = new MenuItem({
label: _strings.GetStringFromName("styleinspector.contextmenu.copyColor"),
accesskey: _strings.GetStringFromName(copyColorAccessKey),
label: STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.copyColor"),
accesskey: STYLE_INSPECTOR_L10N.getStr(copyColorAccessKey),
click: () => {
this._onCopyColor();
},
@ -115,8 +114,8 @@ StyleInspectorMenu.prototype = {
});
let copyUrlAccessKey = "styleinspector.contextmenu.copyUrl.accessKey";
let menuitemCopyUrl = new MenuItem({
label: _strings.GetStringFromName("styleinspector.contextmenu.copyUrl"),
accesskey: _strings.GetStringFromName(copyUrlAccessKey),
label: STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.copyUrl"),
accesskey: STYLE_INSPECTOR_L10N.getStr(copyUrlAccessKey),
click: () => {
this._onCopyUrl();
},
@ -124,8 +123,8 @@ StyleInspectorMenu.prototype = {
});
let copyImageAccessKey = "styleinspector.contextmenu.copyImageDataUrl.accessKey";
let menuitemCopyImageDataUrl = new MenuItem({
label: _strings.GetStringFromName("styleinspector.contextmenu.copyImageDataUrl"),
accesskey: _strings.GetStringFromName(copyImageAccessKey),
label: STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.copyImageDataUrl"),
accesskey: STYLE_INSPECTOR_L10N.getStr(copyImageAccessKey),
click: () => {
this._onCopyImageDataUrl();
},
@ -133,28 +132,28 @@ StyleInspectorMenu.prototype = {
});
let copyPropDeclarationLabel = "styleinspector.contextmenu.copyPropertyDeclaration";
let menuitemCopyPropertyDeclaration = new MenuItem({
label: _strings.GetStringFromName(copyPropDeclarationLabel),
label: STYLE_INSPECTOR_L10N.getStr(copyPropDeclarationLabel),
click: () => {
this._onCopyPropertyDeclaration();
},
visible: false,
});
let menuitemCopyPropertyName = new MenuItem({
label: _strings.GetStringFromName("styleinspector.contextmenu.copyPropertyName"),
label: STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.copyPropertyName"),
click: () => {
this._onCopyPropertyName();
},
visible: false,
});
let menuitemCopyPropertyValue = new MenuItem({
label: _strings.GetStringFromName("styleinspector.contextmenu.copyPropertyValue"),
label: STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.copyPropertyValue"),
click: () => {
this._onCopyPropertyValue();
},
visible: false,
});
let menuitemCopySelector = new MenuItem({
label: _strings.GetStringFromName("styleinspector.contextmenu.copySelector"),
label: STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.copySelector"),
click: () => {
this._onCopySelector();
},
@ -199,8 +198,8 @@ StyleInspectorMenu.prototype = {
// Select All
let selectAllAccessKey = "styleinspector.contextmenu.selectAll.accessKey";
let menuitemSelectAll = new MenuItem({
label: _strings.GetStringFromName("styleinspector.contextmenu.selectAll"),
accesskey: _strings.GetStringFromName(selectAllAccessKey),
label: STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.selectAll"),
accesskey: STYLE_INSPECTOR_L10N.getStr(selectAllAccessKey),
click: () => {
this._onSelectAll();
},
@ -214,8 +213,8 @@ StyleInspectorMenu.prototype = {
// Add new rule
let addRuleAccessKey = "styleinspector.contextmenu.addNewRule.accessKey";
let menuitemAddRule = new MenuItem({
label: _strings.GetStringFromName("styleinspector.contextmenu.addNewRule"),
accesskey: _strings.GetStringFromName(addRuleAccessKey),
label: STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.addNewRule"),
accesskey: STYLE_INSPECTOR_L10N.getStr(addRuleAccessKey),
click: () => {
this._onAddNewRule();
},
@ -228,8 +227,8 @@ StyleInspectorMenu.prototype = {
// Show MDN Docs
let mdnDocsAccessKey = "styleinspector.contextmenu.showMdnDocs.accessKey";
let menuitemShowMdnDocs = new MenuItem({
label: _strings.GetStringFromName("styleinspector.contextmenu.showMdnDocs"),
accesskey: _strings.GetStringFromName(mdnDocsAccessKey),
label: STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.showMdnDocs"),
accesskey: STYLE_INSPECTOR_L10N.getStr(mdnDocsAccessKey),
click: () => {
this._onShowMdnDocs();
},
@ -241,8 +240,8 @@ StyleInspectorMenu.prototype = {
// Show Original Sources
let sourcesAccessKey = "styleinspector.contextmenu.toggleOrigSources.accessKey";
let menuitemSources = new MenuItem({
label: _strings.GetStringFromName("styleinspector.contextmenu.toggleOrigSources"),
accesskey: _strings.GetStringFromName(sourcesAccessKey),
label: STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.toggleOrigSources"),
accesskey: STYLE_INSPECTOR_L10N.getStr(sourcesAccessKey),
click: () => {
this._onToggleOrigSources();
},
@ -397,7 +396,7 @@ StyleInspectorMenu.prototype = {
message = yield data.data.string();
} catch (e) {
message =
_strings.GetStringFromName("styleinspector.copyImageDataUrlError");
STYLE_INSPECTOR_L10N.getStr("styleinspector.copyImageDataUrlError");
}
clipboardHelper.copyString(message);

View File

@ -35,7 +35,7 @@ function* testCopyToClipboard(inspector, view) {
let allMenuItems = openStyleContextMenuAndGetAllItems(view, element);
let menuitemCopyColor = allMenuItems.find(item => item.label ===
_STRINGS.GetStringFromName("styleinspector.contextmenu.copyColor"));
STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.copyColor"));
ok(menuitemCopyColor.visible, "Copy color is visible");

View File

@ -5,17 +5,13 @@
/* Tests both Copy URL and Copy Data URL context menu items */
const PROPERTIES_URL = "chrome://devtools-shared/locale/styleinspector.properties";
const TEST_DATA_URI = "data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=";
// Invalid URL still needs to be reachable otherwise getImageDataUrl will
// timeout. DevTools chrome:// URLs aren't content accessible, so use some
// random resource:// URL here.
const INVALID_IMAGE_URI = "resource://devtools/client/definitions.js";
const ERROR_MESSAGE = Services.strings
.createBundle(PROPERTIES_URL)
.GetStringFromName("styleinspector.copyImageDataUrlError");
const ERROR_MESSAGE = STYLE_INSPECTOR_L10N.getStr("styleinspector.copyImageDataUrlError");
add_task(function* () {
const TEST_URI = `<style type="text/css">
@ -79,9 +75,9 @@ function* testCopyUrlToClipboard({view, inspector}, type, selector, expected) {
info("Simulate right click on the background-image URL");
let allMenuItems = openStyleContextMenuAndGetAllItems(view, imageLink);
let menuitemCopyUrl = allMenuItems.find(item => item.label ===
_STRINGS.GetStringFromName("styleinspector.contextmenu.copyUrl"));
STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.copyUrl"));
let menuitemCopyImageDataUrl = allMenuItems.find(item => item.label ===
_STRINGS.GetStringFromName("styleinspector.contextmenu.copyImageDataUrl"));
STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.copyImageDataUrl"));
info("Context menu is displayed");
ok(menuitemCopyUrl.visible,

View File

@ -21,8 +21,7 @@ const TEST_URL_ROOT_SSL =
"https://example.com/browser/devtools/client/inspector/shared/test/";
const ROOT_TEST_DIR = getRootDirectory(gTestPath);
const FRAME_SCRIPT_URL = ROOT_TEST_DIR + "doc_frame_script.js";
const _STRINGS = Services.strings.createBundle(
"chrome://devtools-shared/locale/styleinspector.properties");
const STYLE_INSPECTOR_L10N = new LocalizationHelper("chrome://devtools-shared/locale/styleinspector.properties");
// Clean-up all prefs that might have been changed during a test run
// (safer here because if the test fails, then the pref is never reverted)

View File

@ -145,6 +145,7 @@ skip-if = os == "mac" # Full keyboard navigation on OSX only works if Full Keybo
[browser_inspector_search-06.js]
[browser_inspector_search-07.js]
[browser_inspector_search-08.js]
[browser_inspector_search-clear.js]
[browser_inspector_search-filter_context-menu.js]
[browser_inspector_search_keyboard_trap.js]
[browser_inspector_search-label.js]

View File

@ -0,0 +1,52 @@
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Bug 1295081 Test searchbox clear button's display behavior is correct
const XHTML = `
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:svg="http://www.w3.org/2000/svg">
<body>
<svg:svg width="100" height="100">
<svg:clipPath>
<svg:rect x="0" y="0" width="10" height="5"></svg:rect>
</svg:clipPath>
<svg:circle cx="0" cy="0" r="5"></svg:circle>
</svg:svg>
</body>
</html>
`;
const TEST_URI = "data:application/xhtml+xml;charset=utf-8," + encodeURI(XHTML);
// Type "d" in inspector-searchbox, Enter [Back space] key and check if the
// clear button is shown correctly
add_task(function* () {
let {inspector} = yield openInspectorForURL(TEST_URI);
let {searchBox, searchClearButton} = inspector;
yield focusSearchBoxUsingShortcut(inspector.panelWin);
info("Type d and the clear button will be shown");
let command = once(searchBox, "input");
EventUtils.synthesizeKey("c", {}, inspector.panelWin);
yield command;
info("Waiting for search query to complete and getting the suggestions");
yield inspector.searchSuggestions._lastQuery;
ok(!searchClearButton.hidden,
"The clear button is shown when some word is in searchBox");
EventUtils.synthesizeKey("VK_BACK_SPACE", {}, inspector.panelWin);
yield command;
info("Waiting for search query to complete and getting the suggestions");
yield inspector.searchSuggestions._lastQuery;
ok(searchClearButton.hidden, "The clear button is hidden when no word is in searchBox");
});

View File

@ -34,6 +34,9 @@ Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/inspector/test/shared-head.js",
this);
const {LocalizationHelper} = require("devtools/shared/l10n");
const INSPECTOR_L10N = new LocalizationHelper("devtools/locale/inspector.properties");
flags.testing = true;
registerCleanupFunction(() => {
flags.testing = false;
@ -228,9 +231,8 @@ var focusSearchBoxUsingShortcut = Task.async(function* (panelWin, callback) {
let focused = once(searchBox, "focus");
panelWin.focus();
let strings = Services.strings.createBundle(
"chrome://devtools/locale/inspector.properties");
synthesizeKeyShortcut(strings.GetStringFromName("inspector.searchHTML.key"));
synthesizeKeyShortcut(INSPECTOR_L10N.getStr("inspector.searchHTML.key"));
yield focused;

View File

@ -6,13 +6,9 @@
"use strict";
var Services = require("Services");
var EventEmitter = require("devtools/shared/event-emitter");
var Telemetry = require("devtools/client/shared/telemetry");
var { Task } = require("devtools/shared/task");
/* eslint-disable mozilla/reject-some-requires */
var { XPCOMUtils } = require("resource://gre/modules/XPCOMUtils.jsm");
/* eslint-enable mozilla/reject-some-requires */
/**
* This object represents replacement for ToolSidebar
@ -302,21 +298,3 @@ ToolSidebar.prototype = {
this._toolPanel = null;
})
};
XPCOMUtils.defineLazyGetter(this, "l10n", function () {
let bundle = Services.strings.createBundle(
"chrome://devtools/locale/toolbox.properties");
let l10n = function (name, ...args) {
try {
if (args.length == 0) {
return bundle.GetStringFromName(name);
}
return bundle.formatStringFromName(name, args, args.length);
} catch (err) {
console.error(err);
}
return null;
};
return l10n;
});

View File

@ -11,6 +11,8 @@ const Services = require("Services");
const { TargetFactory } = require("devtools/client/framework/target");
const Telemetry = require("devtools/client/shared/telemetry");
const {ViewHelpers} = require("devtools/client/shared/widgets/view-helpers");
const {LocalizationHelper} = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools/locale/toolbox.properties");
const NS_XHTML = "http://www.w3.org/1999/xhtml";
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
@ -21,9 +23,6 @@ loader.lazyGetter(this, "prefBranch", function () {
return Services.prefs.getBranch(null)
.QueryInterface(Ci.nsIPrefBranch2);
});
loader.lazyGetter(this, "toolboxStrings", function () {
return Services.strings.createBundle("chrome://devtools/locale/toolbox.properties");
});
loader.lazyRequireGetter(this, "gcliInit", "devtools/shared/gcli/commands/index");
loader.lazyRequireGetter(this, "util", "gcli/util/util");
@ -311,7 +310,7 @@ DeveloperToolbar.prototype.createToolbar = function () {
close.setAttribute("id", "developer-toolbar-closebutton");
close.setAttribute("class", "close-icon");
close.setAttribute("oncommand", "DeveloperToolbar.hide();");
let closeTooltip = toolboxStrings.GetStringFromName("toolbar.closeButton.tooltip");
let closeTooltip = L10N.getStr("toolbar.closeButton.tooltip");
close.setAttribute("tooltiptext", closeTooltip);
let stack = this._doc.createElement("stack");
@ -329,7 +328,7 @@ DeveloperToolbar.prototype.createToolbar = function () {
let toolboxBtn = this._doc.createElement("toolbarbutton");
toolboxBtn.setAttribute("id", "developer-toolbar-toolbox-button");
toolboxBtn.setAttribute("class", "developer-toolbar-button");
let toolboxTooltip = toolboxStrings.GetStringFromName("toolbar.toolsButton.tooltip");
let toolboxTooltip = L10N.getStr("toolbar.toolsButton.tooltip");
toolboxBtn.setAttribute("tooltiptext", toolboxTooltip);
toolboxBtn.addEventListener("command", function (event) {
let window = event.target.ownerDocument.defaultView;
@ -805,17 +804,14 @@ DeveloperToolbar.prototype._updateErrorsCount = function (changedTabId) {
let warnings = this._warningsCount[tabId];
let btn = this._errorCounterButton;
if (errors) {
let errorsText = toolboxStrings
.GetStringFromName("toolboxToggleButton.errors");
let errorsText = L10N.getStr("toolboxToggleButton.errors");
errorsText = PluralForm.get(errors, errorsText).replace("#1", errors);
let warningsText = toolboxStrings
.GetStringFromName("toolboxToggleButton.warnings");
let warningsText = L10N.getStr("toolboxToggleButton.warnings");
warningsText = PluralForm.get(warnings, warningsText).replace("#1", warnings);
let tooltiptext = toolboxStrings
.formatStringFromName("toolboxToggleButton.tooltip",
[errorsText, warningsText], 2);
let tooltiptext = L10N.getFormatStr("toolboxToggleButton.tooltip",
errorsText, warningsText);
btn.setAttribute("error-count", errors);
btn.setAttribute("tooltiptext", tooltiptext);

View File

@ -5,10 +5,10 @@
"use strict";
const { getJSON } = require("devtools/client/shared/getjson");
const Services = require("Services");
const DEVICES_URL = "devtools.devices.url";
const Strings = Services.strings.createBundle("chrome://devtools/locale/device.properties");
const {LocalizationHelper} = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools/locale/device.properties");
/* This is a catalog of common web-enabled devices and their properties,
* intended for (mobile) device emulation.
@ -63,6 +63,6 @@ exports.GetDevices = GetDevices;
// Get the localized string for a device type.
function GetDeviceString(deviceType) {
return Strings.GetStringFromName("device." + deviceType);
return L10N.getStr("device." + deviceType);
}
exports.GetDeviceString = GetDeviceString;

View File

@ -30,6 +30,9 @@ const {getCSSLexer} = require("devtools/shared/css-lexer");
const EventEmitter = require("devtools/shared/event-emitter");
const {gDevTools} = require("devtools/client/framework/devtools");
const {LocalizationHelper} = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools/locale/inspector.properties");
const XHTML_NS = "http://www.w3.org/1999/xhtml";
// Parameters for the XHR request
@ -263,8 +266,7 @@ function MdnDocsWidget(tooltipContainer) {
};
// get the localized string for the link text
this.elements.linkToMdn.textContent =
l10n.strings.GetStringFromName("docsTooltip.visitMDN");
this.elements.linkToMdn.textContent = L10N.getStr("docsTooltip.visitMDN");
// listen for clicks and open in the browser window instead
let mainWindow = Services.wm.getMostRecentWindow(gDevTools.chromeWindowType);
@ -348,8 +350,7 @@ MdnDocsWidget.prototype = {
*/
function gotError(error) {
// show error message
elements.summary.textContent =
l10n.strings.GetStringFromName("docsTooltip.loadDocsError");
elements.summary.textContent = L10N.getStr("docsTooltip.loadDocsError");
// hide the throbber
elements.info.classList.remove("devtools-throbber");
@ -373,19 +374,6 @@ MdnDocsWidget.prototype = {
}
};
/**
* L10N utility class
*/
function L10N() {}
L10N.prototype = {};
var l10n = new L10N();
loader.lazyGetter(L10N.prototype, "strings", () => {
return Services.strings.createBundle(
"chrome://devtools/locale/inspector.properties");
});
/**
* Test whether a node is all whitespace.
*

View File

@ -8,7 +8,7 @@
const Ci = Components.interfaces;
const Cu = Components.utils;
const DBG_STRINGS_URI = "chrome://devtools/locale/debugger.properties";
const DBG_STRINGS_URI = "devtools/locale/debugger.properties";
const LAZY_EMPTY_DELAY = 150; // ms
const SCROLL_PAGE_SIZE_DEFAULT = 0;
const PAGE_SIZE_SCROLL_HEIGHT_RATIO = 100;
@ -29,7 +29,8 @@ const { Heritage, ViewHelpers, setNamedTimeout } =
const { Task } = require("devtools/shared/task");
const nodeConstants = require("devtools/shared/dom-node-constants");
const {KeyCodes} = require("devtools/client/shared/keycodes");
const {ELLIPSIS} = require("devtools/shared/l10n");
const {LocalizationHelper, ELLIPSIS} = require("devtools/shared/l10n");
const L10N = new LocalizationHelper(DBG_STRINGS_URI);
XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
"resource://gre/modules/PluralForm.jsm");
@ -56,11 +57,6 @@ Object.defineProperty(this, "NetworkHelper", {
this.EXPORTED_SYMBOLS = ["VariablesView", "escapeHTML"];
/**
* Debugger localization strings.
*/
const STR = Services.strings.createBundle(DBG_STRINGS_URI);
/**
* A tree view for inspecting scopes, objects and properties.
* Iterable via "for (let [id, scope] of instance) { }".
@ -309,7 +305,7 @@ VariablesView.prototype = {
* This flag is applied recursively onto each scope in this view and
* affects only the child nodes when they're created.
*/
editableValueTooltip: STR.GetStringFromName("variablesEditableValueTooltip"),
editableValueTooltip: L10N.getStr("variablesEditableValueTooltip"),
/**
* The tooltip text shown on a variable or property's name if a |switch|
@ -318,7 +314,7 @@ VariablesView.prototype = {
* This flag is applied recursively onto each scope in this view and
* affects only the child nodes when they're created.
*/
editableNameTooltip: STR.GetStringFromName("variablesEditableNameTooltip"),
editableNameTooltip: L10N.getStr("variablesEditableNameTooltip"),
/**
* The tooltip text shown on a variable or property's edit button if an
@ -328,7 +324,7 @@ VariablesView.prototype = {
* This flag is applied recursively onto each scope in this view and
* affects only the child nodes when they're created.
*/
editButtonTooltip: STR.GetStringFromName("variablesEditButtonTooltip"),
editButtonTooltip: L10N.getStr("variablesEditButtonTooltip"),
/**
* The tooltip text shown on a variable or property's value if that value is
@ -337,7 +333,7 @@ VariablesView.prototype = {
* This flag is applied recursively onto each scope in this view and
* affects only the child nodes when they're created.
*/
domNodeValueTooltip: STR.GetStringFromName("variablesDomNodeValueTooltip"),
domNodeValueTooltip: L10N.getStr("variablesDomNodeValueTooltip"),
/**
* The tooltip text shown on a variable or property's delete button if a
@ -346,7 +342,7 @@ VariablesView.prototype = {
* This flag is applied recursively onto each scope in this view and
* affects only the child nodes when they're created.
*/
deleteButtonTooltip: STR.GetStringFromName("variablesCloseButtonTooltip"),
deleteButtonTooltip: L10N.getStr("variablesCloseButtonTooltip"),
/**
* Specifies the context menu attribute set on variables and properties.
@ -362,7 +358,7 @@ VariablesView.prototype = {
* This flag is applied recursively onto each scope in this view and
* affects only the child nodes when they're created.
*/
separatorStr: STR.GetStringFromName("variablesSeparatorLabel"),
separatorStr: L10N.getStr("variablesSeparatorLabel"),
/**
* Specifies if enumerable properties and variables should be displayed.
@ -2462,13 +2458,13 @@ Variable.prototype = Heritage.extend(Scope.prototype, {
if (aGrip && (aGrip.optimizedOut || aGrip.uninitialized || aGrip.missingArguments)) {
if (aGrip.optimizedOut) {
this._valueString = STR.GetStringFromName("variablesViewOptimizedOut");
this._valueString = L10N.getStr("variablesViewOptimizedOut");
}
else if (aGrip.uninitialized) {
this._valueString = STR.GetStringFromName("variablesViewUninitialized");
this._valueString = L10N.getStr("variablesViewUninitialized");
}
else if (aGrip.missingArguments) {
this._valueString = STR.GetStringFromName("variablesViewMissingArgs");
this._valueString = L10N.getStr("variablesViewMissingArgs");
}
this.eval = null;
}
@ -2713,7 +2709,7 @@ Variable.prototype = Heritage.extend(Scope.prototype, {
for (let type of labels) {
let labelElement = this.document.createElement("label");
labelElement.className = type;
labelElement.setAttribute("value", STR.GetStringFromName(type + "Tooltip"));
labelElement.setAttribute("value", L10N.getStr(type + "Tooltip"));
tooltip.appendChild(labelElement);
}
@ -3698,7 +3694,7 @@ VariablesView.stringifiers.byObjectKind = {
VariablesView.getString(preview.message, { noStringQuotes: true });
if (!VariablesView.isFalsy({ value: preview.stack })) {
msg += "\n" + STR.GetStringFromName("variablesViewErrorStacktrace") +
msg += "\n" + L10N.getStr("variablesViewErrorStacktrace") +
"\n" + preview.stack;
}
@ -3843,7 +3839,7 @@ VariablesView.stringifiers.byObjectKind = {
* @return string
*/
VariablesView.stringifiers._getNMoreString = function (aNumber) {
let str = STR.GetStringFromName("variablesViewMoreObjects");
let str = L10N.getStr("variablesViewMoreObjects");
return PluralForm.get(aNumber, str).replace("#1", aNumber);
};

View File

@ -6,14 +6,8 @@
"use strict";
const Services = require("Services");
loader.lazyGetter(this, "GetStringFromName", () => {
let bundle = Services.strings.createBundle(
"chrome://devtools/locale/inspector.properties");
return key => {
return bundle.GetStringFromName(key);
};
});
const {LocalizationHelper} = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools/locale/inspector.properties");
const Editor = require("devtools/client/sourceeditor/editor");
const beautify = require("devtools/shared/jsbeautify/beautify");
@ -82,7 +76,7 @@ EventTooltip.prototype = {
debuggerIcon.className = "event-tooltip-debugger-icon";
debuggerIcon.setAttribute("src",
"chrome://devtools/skin/images/tool-debugger.svg");
let openInDebugger = GetStringFromName("eventsTooltip.openInDebugger");
let openInDebugger = L10N.getStr("eventsTooltip.openInDebugger");
debuggerIcon.setAttribute("title", openInDebugger);
header.appendChild(debuggerIcon);
}

View File

@ -6,14 +6,8 @@
"use strict";
const Services = require("Services");
loader.lazyGetter(this, "GetStringFromName", () => {
let bundle = Services.strings.createBundle(
"chrome://devtools/locale/inspector.properties");
return key => {
return bundle.GetStringFromName(key);
};
});
const {LocalizationHelper} = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools/locale/inspector.properties");
const XHTML_NS = "http://www.w3.org/1999/xhtml";
@ -131,7 +125,7 @@ function setBrokenImageTooltip(tooltip, doc) {
text-align: center;
line-height: 30px;`;
let message = GetStringFromName("previewTooltip.image.brokenImage");
let message = L10N.getStr("previewTooltip.image.brokenImage");
div.textContent = message;
tooltip.setContent(div, {width: 150, height: 30});
}

View File

@ -12,11 +12,8 @@ const ZOOM_PREF = "devtools.toolbox.zoomValue";
const MIN_ZOOM = 0.5;
const MAX_ZOOM = 2;
const properties = "chrome://devtools/locale/toolbox.properties";
const bundle = Services.strings.createBundle(properties);
function l10n(key) {
return bundle.GetStringFromName(key);
}
const {LocalizationHelper} = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools/locale/toolbox.properties");
/**
* Register generic keys to control zoom level of the given document.
@ -62,26 +59,26 @@ exports.register = function (window) {
// Set zoom to whatever the last setting was.
setZoom(zoomValue);
shortcuts.on(l10n("toolbox.zoomIn.key"), zoomIn);
let zoomIn2 = l10n("toolbox.zoomIn2.key");
shortcuts.on(L10N.getStr("toolbox.zoomIn.key"), zoomIn);
let zoomIn2 = L10N.getStr("toolbox.zoomIn2.key");
if (zoomIn2) {
shortcuts.on(zoomIn2, zoomIn);
}
let zoomIn3 = l10n("toolbox.zoomIn2.key");
let zoomIn3 = L10N.getStr("toolbox.zoomIn2.key");
if (zoomIn3) {
shortcuts.on(zoomIn3, zoomIn);
}
shortcuts.on(l10n("toolbox.zoomOut.key"),
shortcuts.on(L10N.getStr("toolbox.zoomOut.key"),
zoomOut);
let zoomOut2 = l10n("toolbox.zoomOut2.key");
let zoomOut2 = L10N.getStr("toolbox.zoomOut2.key");
if (zoomOut2) {
shortcuts.on(zoomOut2, zoomOut);
}
shortcuts.on(l10n("toolbox.zoomReset.key"),
shortcuts.on(L10N.getStr("toolbox.zoomReset.key"),
zoomReset);
let zoomReset2 = l10n("toolbox.zoomReset2.key");
let zoomReset2 = L10N.getStr("toolbox.zoomReset2.key");
if (zoomReset2) {
shortcuts.on(zoomReset2, zoomReset);
}

View File

@ -21,7 +21,6 @@ const ENABLE_CODE_FOLDING = "devtools.editor.enableCodeFolding";
const KEYMAP = "devtools.editor.keymap";
const AUTO_CLOSE = "devtools.editor.autoclosebrackets";
const AUTOCOMPLETE = "devtools.editor.autocomplete";
const L10N_BUNDLE = "chrome://devtools/locale/sourceeditor.properties";
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
const VALID_KEYMAPS = new Set(["emacs", "vim", "sublime"]);
@ -39,7 +38,8 @@ const promise = require("promise");
const events = require("devtools/shared/event-emitter");
const { PrefObserver } = require("devtools/client/styleeditor/utils");
const L10N = Services.strings.createBundle(L10N_BUNDLE);
const {LocalizationHelper} = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools/locale/sourceeditor.properties");
const { OS } = Services.appinfo;
@ -353,8 +353,8 @@ Editor.prototype = {
// Intercept the find and find again keystroke on CodeMirror, to avoid
// the browser's search
let findKey = L10N.GetStringFromName("find.commandkey");
let findAgainKey = L10N.GetStringFromName("findAgain.commandkey");
let findKey = L10N.getStr("find.commandkey");
let findAgainKey = L10N.getStr("findAgain.commandkey");
let [accel, modifier] = OS === "Darwin"
? ["metaKey", "altKey"]
: ["ctrlKey", "shiftKey"];
@ -434,7 +434,7 @@ Editor.prototype = {
});
win.CodeMirror.defineExtension("l10n", (name) => {
return L10N.GetStringFromName(name);
return L10N.getStr(name);
});
cm.getInputField().controllers.insertControllerAt(0, controller(this));
@ -977,7 +977,7 @@ Editor.prototype = {
let div = doc.createElement("div");
let inp = doc.createElement("input");
let txt =
doc.createTextNode(L10N.GetStringFromName("gotoLineCmd.promptTitle"));
doc.createTextNode(L10N.getStr("gotoLineCmd.promptTitle"));
inp.type = "text";
inp.style.width = "10em";
@ -1275,7 +1275,7 @@ Editor.accel = function (key, modifiers = {}) {
* or disabling default shortcuts.
*/
Editor.keyFor = function (cmd, opts = { noaccel: false }) {
let key = L10N.GetStringFromName(cmd + ".commandkey");
let key = L10N.getStr(cmd + ".commandkey");
return opts.noaccel ? key : Editor.accel(key);
};

View File

@ -5,11 +5,11 @@
"use strict";
const L10N_BUNDLE = "chrome://devtools/locale/sourceeditor.properties";
const L10N = Services.strings.createBundle(L10N_BUNDLE);
const {LocalizationHelper} = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools/locale/sourceeditor.properties");
const FIND_KEY = L10N.GetStringFromName("find.commandkey");
const FINDAGAIN_KEY = L10N.GetStringFromName("findAgain.commandkey");
const FIND_KEY = L10N.getStr("find.commandkey");
const FINDAGAIN_KEY = L10N.getStr("findAgain.commandkey");
const { OS } = Services.appinfo;

View File

@ -44,25 +44,16 @@
.side-menu-widget-item-checkbox .checkbox-check {
-moz-appearance: none;
background-image: url(images/itemToggle.png);
background-image: url(images/itemToggle.svg);
background-color: transparent;
background-repeat: no-repeat;
background-clip: content-box;
background-size: 32px 16px;
background-position: -16px 0;
width: 16px;
height: 16px;
border: 0;
}
@media (min-resolution: 1.1dppx) {
.side-menu-widget-item-checkbox .checkbox-check {
background-image: url(images/itemToggle@2x.png);
}
}
.side-menu-widget-item-checkbox[checked] .checkbox-check {
background-position: 0 0;
.side-menu-widget-item-checkbox:not([checked]) .checkbox-check,
.side-menu-widget-item-checkbox:not([checked]) + vbox {
opacity: 0.3;
}
.side-menu-widget-item:not(.selected) .checkbox-check {

View File

@ -3,24 +3,20 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const Services = require("Services");
const {cssUsageSpec} = require("devtools/shared/specs/csscoverage");
const protocol = require("devtools/shared/protocol");
const {custom} = protocol;
const {LocalizationHelper} = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools-shared/locale/csscoverage.properties");
loader.lazyRequireGetter(this, "gDevTools", "devtools/client/framework/devtools", true);
/**
* Allow: let foo = l10n.lookup("csscoverageFoo");
*/
const l10n = exports.l10n = {
_URI: "chrome://devtools-shared/locale/csscoverage.properties",
lookup: function (msg) {
if (this._stringBundle == null) {
this._stringBundle = Services.strings.createBundle(this._URI);
}
return this._stringBundle.GetStringFromName(msg);
}
lookup: (msg) => L10N.getStr(msg)
};
/**

View File

@ -5,7 +5,6 @@
"use strict";
const l10n = require("gcli/l10n");
const Services = require("Services");
const { XPCOMUtils } = require("resource://gre/modules/XPCOMUtils.jsm");
require("devtools/server/actors/inspector");
const {
@ -13,9 +12,8 @@ const {
HighlighterEnvironment
} = require("devtools/server/actors/highlighters");
XPCOMUtils.defineLazyGetter(this, "nodesSelected", function () {
return Services.strings.createBundle("chrome://devtools-shared/locale/gclicommands.properties");
});
const {LocalizationHelper} = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools-shared/locale/gclicommands.properties");
XPCOMUtils.defineLazyModuleGetter(this, "PluralForm", "resource://gre/modules/PluralForm.jsm");
// How many maximum nodes can be highlighted in parallel
@ -139,7 +137,7 @@ exports.items = [
i++;
}
let highlightText = nodesSelected.GetStringFromName("highlightOutputConfirm2");
let highlightText = L10N.getStr("highlightOutputConfirm2");
let output = PluralForm.get(args.selector.length, highlightText)
.replace("%1$S", args.selector.length);
if (args.selector.length > i) {

View File

@ -14,41 +14,37 @@
* limitations under the License.
*/
'use strict';
"use strict";
var Cc = require('chrome').Cc;
var Ci = require('chrome').Ci;
var Cu = require('chrome').Cu;
var Cc = require("chrome").Cc;
var Ci = require("chrome").Ci;
var prefSvc = Cc['@mozilla.org/preferences-service;1']
.getService(Ci.nsIPrefService);
var prefSvc = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService);
var prefBranch = prefSvc.getBranch(null).QueryInterface(Ci.nsIPrefBranch);
var Services = require("Services");
var stringBundle = Services.strings.createBundle(
'chrome://devtools-shared/locale/gclicommands.properties');
const {LocalizationHelper} = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools-shared/locale/gclicommands.properties");
/**
* Lookup a string in the GCLI string bundle
*/
exports.lookup = function(name) {
exports.lookup = function (name) {
try {
return stringBundle.GetStringFromName(name);
}
catch (ex) {
throw new Error('Failure in lookup(\'' + name + '\')');
return L10N.getStr(name);
} catch (ex) {
throw new Error("Failure in lookup('" + name + "')");
}
};
/**
* An alternative to lookup().
* <code>l10n.lookup('BLAH') === l10n.propertyLookup.BLAH</code>
* <code>l10n.lookup("BLAH") === l10n.propertyLookup.BLAH</code>
* This is particularly nice for templates because you can pass
* <code>l10n:l10n.propertyLookup</code> in the template data and use it
* like <code>${l10n.BLAH}</code>
*/
exports.propertyLookup = new Proxy({}, {
get: function(rcvr, name) {
get: function (rcvr, name) {
return exports.lookup(name);
}
});
@ -56,24 +52,23 @@ exports.propertyLookup = new Proxy({}, {
/**
* Lookup a string in the GCLI string bundle
*/
exports.lookupFormat = function(name, swaps) {
exports.lookupFormat = function (name, swaps) {
try {
return stringBundle.formatStringFromName(name, swaps, swaps.length);
}
catch (ex) {
throw new Error('Failure in lookupFormat(\'' + name + '\')');
return L10N.getFormatStr(name, ...swaps);
} catch (ex) {
throw new Error("Failure in lookupFormat('" + name + "')");
}
};
/**
* Allow GCLI users to be hidden by the 'devtools.chrome.enabled' pref.
* Allow GCLI users to be hidden by the "devtools.chrome.enabled" pref.
* Use it in commands like this:
* <pre>
* name: "somecommand",
* hidden: l10n.hiddenByChromePref(),
* exec: function(args, context) { ... }
* exec: function (args, context) { ... }
* </pre>
*/
exports.hiddenByChromePref = function() {
return !prefBranch.getBoolPref('devtools.chrome.enabled');
exports.hiddenByChromePref = function () {
return !prefBranch.getBoolPref("devtools.chrome.enabled");
};

View File

@ -14,76 +14,67 @@
* limitations under the License.
*/
'use strict';
"use strict";
var Cu = require('chrome').Cu;
var XPCOMUtils = Cu.import('resource://gre/modules/XPCOMUtils.jsm', {}).XPCOMUtils;
var Services = require("Services");
var imports = {};
XPCOMUtils.defineLazyGetter(imports, 'stringBundle', function () {
return Services.strings.createBundle('chrome://devtools-shared/locale/gcli.properties');
});
const {LocalizationHelper} = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools-shared/locale/gcli.properties");
/*
* Not supported when embedded - we're doing things the Mozilla way not the
* Not supported when embedded - we"re doing things the Mozilla way not the
* require.js way.
*/
exports.registerStringsSource = function(modulePath) {
throw new Error('registerStringsSource is not available in mozilla');
exports.registerStringsSource = function (modulePath) {
throw new Error("registerStringsSource is not available in mozilla");
};
exports.unregisterStringsSource = function(modulePath) {
throw new Error('unregisterStringsSource is not available in mozilla');
exports.unregisterStringsSource = function (modulePath) {
throw new Error("unregisterStringsSource is not available in mozilla");
};
exports.lookupSwap = function(key, swaps) {
throw new Error('lookupSwap is not available in mozilla');
exports.lookupSwap = function (key, swaps) {
throw new Error("lookupSwap is not available in mozilla");
};
exports.lookupPlural = function(key, ord, swaps) {
throw new Error('lookupPlural is not available in mozilla');
exports.lookupPlural = function (key, ord, swaps) {
throw new Error("lookupPlural is not available in mozilla");
};
exports.getPreferredLocales = function() {
return [ 'root' ];
exports.getPreferredLocales = function () {
return [ "root" ];
};
/** @see lookup() in lib/gcli/util/l10n.js */
exports.lookup = function(key) {
exports.lookup = function (key) {
try {
// Our memory leak hunter walks reachable objects trying to work out what
// type of thing they are using object.constructor.name. If that causes
// problems then we can avoid the unknown-key-exception with the following:
/*
if (key === 'constructor') {
return { name: 'l10n-mem-leak-defeat' };
if (key === "constructor") {
return { name: "l10n-mem-leak-defeat" };
}
*/
return imports.stringBundle.GetStringFromName(key);
}
catch (ex) {
console.error('Failed to lookup ', key, ex);
return L10N.getStr(key);
} catch (ex) {
console.error("Failed to lookup ", key, ex);
return key;
}
};
/** @see propertyLookup in lib/gcli/util/l10n.js */
exports.propertyLookup = new Proxy({}, {
get: function(rcvr, name) {
get: function (rcvr, name) {
return exports.lookup(name);
}
});
/** @see lookupFormat in lib/gcli/util/l10n.js */
exports.lookupFormat = function(key, swaps) {
exports.lookupFormat = function (key, swaps) {
try {
return imports.stringBundle.formatStringFromName(key, swaps, swaps.length);
}
catch (ex) {
console.error('Failed to format ', key, ex);
return L10N.getFormatStr(key, ...swaps);
} catch (ex) {
console.error("Failed to format ", key, ex);
return key;
}
};

View File

@ -42,6 +42,9 @@
const Services = require("Services");
const CSSLexer = require("devtools/shared/css-lexer");
const {LocalizationHelper} = require("devtools/shared/l10n");
const styleInspectorL10N =
new LocalizationHelper("devtools-shared/locale/styleinspector.properties");
/**
* Special values for filter, in addition to an href these values can be used
@ -70,16 +73,13 @@ exports.STATUS = {
};
/**
* Memoized lookup of a l10n string from a string bundle.
* @param {string} name The key to lookup.
* @returns A localized version of the given key.
* Lookup a l10n string in the shared styleinspector string bundle.
*
* @param {String} name
* The key to lookup.
* @returns {String} A localized version of the given key.
*/
exports.l10n = function (name) {
return exports._strings.GetStringFromName(name);
};
exports._strings = Services.strings
.createBundle("chrome://devtools-shared/locale/styleinspector.properties");
exports.l10n = name => styleInspectorL10N.getStr(name);
/**
* Is the given property sheet a content stylesheet?

View File

@ -14,10 +14,8 @@ loader.lazyRequireGetter(this, "DebuggerSocket",
loader.lazyRequireGetter(this, "AuthenticationResult",
"devtools/shared/security/auth", true);
DevToolsUtils.defineLazyGetter(this, "bundle", () => {
const DBG_STRINGS_URI = "chrome://devtools-shared/locale/debugger.properties";
return Services.strings.createBundle(DBG_STRINGS_URI);
});
const {LocalizationHelper} = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools-shared/locale/debugger.properties");
var Client = exports.Client = {};
var Server = exports.Server = {};
@ -51,13 +49,11 @@ Client.defaultSendOOB = ({ authResult, oob }) => {
if (authResult != AuthenticationResult.PENDING) {
throw new Error("Expected PENDING result, got " + authResult);
}
let title = bundle.GetStringFromName("clientSendOOBTitle");
let header = bundle.GetStringFromName("clientSendOOBHeader");
let hashMsg = bundle.formatStringFromName("clientSendOOBHash",
[oob.sha256], 1);
let title = L10N.getStr("clientSendOOBTitle");
let header = L10N.getStr("clientSendOOBHeader");
let hashMsg = L10N.getFormatStr("clientSendOOBHash", oob.sha256);
let token = oob.sha256.replace(/:/g, "").toLowerCase() + oob.k;
let tokenMsg = bundle.formatStringFromName("clientSendOOBToken",
[token], 1);
let tokenMsg = L10N.getFormatStr("clientSendOOBToken", token);
let msg = `${header}\n\n${hashMsg}\n${tokenMsg}`;
let prompt = Services.prompt;
let flags = prompt.BUTTON_POS_0 * prompt.BUTTON_TITLE_CANCEL;
@ -125,19 +121,15 @@ Client.defaultSendOOB = ({ authResult, oob }) => {
* A promise that will be resolved to the above is also allowed.
*/
Server.defaultAllowConnection = ({ client, server }) => {
let title = bundle.GetStringFromName("remoteIncomingPromptTitle");
let header = bundle.GetStringFromName("remoteIncomingPromptHeader");
let title = L10N.getStr("remoteIncomingPromptTitle");
let header = L10N.getStr("remoteIncomingPromptHeader");
let clientEndpoint = `${client.host}:${client.port}`;
let clientMsg =
bundle.formatStringFromName("remoteIncomingPromptClientEndpoint",
[clientEndpoint], 1);
let clientMsg = L10N.getFormatStr("remoteIncomingPromptClientEndpoint", clientEndpoint);
let serverEndpoint = `${server.host}:${server.port}`;
let serverMsg =
bundle.formatStringFromName("remoteIncomingPromptServerEndpoint",
[serverEndpoint], 1);
let footer = bundle.GetStringFromName("remoteIncomingPromptFooter");
let serverMsg = L10N.getFormatStr("remoteIncomingPromptServerEndpoint", serverEndpoint);
let footer = L10N.getStr("remoteIncomingPromptFooter");
let msg = `${header}\n\n${clientMsg}\n${serverMsg}\n\n${footer}`;
let disableButton = bundle.GetStringFromName("remoteIncomingPromptDisable");
let disableButton = L10N.getStr("remoteIncomingPromptDisable");
let prompt = Services.prompt;
let flags = prompt.BUTTON_POS_0 * prompt.BUTTON_TITLE_OK +
prompt.BUTTON_POS_1 * prompt.BUTTON_TITLE_CANCEL +
@ -170,8 +162,8 @@ Server.defaultAllowConnection = ({ client, server }) => {
* A promise that will be resolved to the above is also allowed.
*/
Server.defaultReceiveOOB = () => {
let title = bundle.GetStringFromName("serverReceiveOOBTitle");
let msg = bundle.GetStringFromName("serverReceiveOOBBody");
let title = L10N.getStr("serverReceiveOOBTitle");
let msg = L10N.getStr("serverReceiveOOBBody");
let input = { value: null };
let prompt = Services.prompt;
let result = prompt.prompt(null, title, msg, input, null, { value: false });

View File

@ -48,7 +48,11 @@ skip-if = toolkit == 'android' # autocomplete
[test_passwords_in_type_password.html]
[test_prompt.html]
skip-if = os == "linux" || toolkit == 'android' # Tests desktop prompts
[test_prompt_http.html]
skip-if = e10s || os == "linux" || toolkit == 'android' # Tests desktop prompts
[test_prompt_promptAuth.html]
skip-if = os == "linux" || toolkit == 'android' # Tests desktop prompts
[test_prompt_promptAuth_proxy.html]
skip-if = e10s || os == "linux" || toolkit == 'android' # Tests desktop prompts
[test_recipe_login_fields.html]
[test_xhr_2.html]

View File

@ -0,0 +1,284 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test HTTP auth prompts by loading authenticate.sjs</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
<script type="text/javascript" src="pwmgr_common.js"></script>
<script type="text/javascript" src="prompt_common.js"></script>
<script type="text/javascript" src="notification_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
<iframe id="iframe"></iframe>
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
var state, action;
var iframe = document.getElementById("iframe");
// Force parent to not look for tab-modal prompts, as they're not used for auth prompts.
isTabModal = false;
let chromeScript = runInParent(SimpleTest.getTestFileURL("pwmgr_common.js"));
runInParent(() => {
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/Services.jsm");
let pwmgr = Cc["@mozilla.org/login-manager;1"].
getService(Ci.nsILoginManager);
let login3A, login3B, login4;
login3A = Cc["@mozilla.org/login-manager/loginInfo;1"].
createInstance(Ci.nsILoginInfo);
login3B = Cc["@mozilla.org/login-manager/loginInfo;1"].
createInstance(Ci.nsILoginInfo);
login4 = Cc["@mozilla.org/login-manager/loginInfo;1"].
createInstance(Ci.nsILoginInfo);
login3A.init("http://mochi.test:8888", null, "mochitest",
"mochiuser1", "mochipass1", "", "");
login3B.init("http://mochi.test:8888", null, "mochitest2",
"mochiuser2", "mochipass2", "", "");
login4.init("http://mochi.test:8888", null, "mochitest3",
"mochiuser3", "mochipass3-old", "", "");
pwmgr.addLogin(login3A);
pwmgr.addLogin(login3B);
pwmgr.addLogin(login4);
});
add_task(function* test_iframe() {
state = {
msg : "http://mochi.test:8888 is requesting your username and password.\n\nThe site says: “mochitest”",
title : "Authentication Required",
textValue : "mochiuser1",
passValue : "mochipass1",
iconClass : "authentication-icon question-icon",
titleHidden : true,
textHidden : false,
passHidden : false,
checkHidden : true,
checkMsg : "",
checked : false,
focused : "textField",
defButton : "button0",
};
action = {
buttonClick : "ok",
};
promptDone = handlePrompt(state, action);
// The following tests are driven by iframe loads
var iframeLoaded = onloadPromiseFor("iframe");
iframe.src = "authenticate.sjs?user=mochiuser1&pass=mochipass1";
yield promptDone;
yield iframeLoaded;
checkEchoedAuthInfo({user: "mochiuser1", pass: "mochipass1"},
iframe.contentDocument);
state = {
msg : "http://mochi.test:8888 is requesting your username and password.\n\nThe site says: “mochitest2”",
title : "Authentication Required",
textValue : "mochiuser2",
passValue : "mochipass2",
iconClass : "authentication-icon question-icon",
titleHidden : true,
textHidden : false,
passHidden : false,
checkHidden : true,
checkMsg : "",
checked : false,
focused : "textField",
defButton : "button0",
};
action = {
buttonClick : "ok",
};
promptDone = handlePrompt(state, action);
// We've already authenticated to this host:port. For this next
// request, the existing auth should be sent, we'll get a 401 reply,
// and we should prompt for new auth.
iframeLoaded = onloadPromiseFor("iframe");
iframe.src = "authenticate.sjs?user=mochiuser2&pass=mochipass2&realm=mochitest2";
yield promptDone;
yield iframeLoaded;
checkEchoedAuthInfo({user: "mochiuser2", pass: "mochipass2"},
iframe.contentDocument);
// Now make a load that requests the realm from test 1000. It was
// already provided there, so auth will *not* be prompted for -- the
// networking layer already knows it!
iframeLoaded = onloadPromiseFor("iframe");
iframe.src = "authenticate.sjs?user=mochiuser1&pass=mochipass1";
yield iframeLoaded;
checkEchoedAuthInfo({user: "mochiuser1", pass: "mochipass1"},
iframe.contentDocument);
// Same realm we've already authenticated to, but with a different
// expected password (to trigger an auth prompt, and change-password
// popup notification).
state = {
msg : "http://mochi.test:8888 is requesting your username and password.\n\nThe site says: “mochitest”",
title : "Authentication Required",
textValue : "mochiuser1",
passValue : "mochipass1",
iconClass : "authentication-icon question-icon",
titleHidden : true,
textHidden : false,
passHidden : false,
checkHidden : true,
checkMsg : "",
checked : false,
focused : "textField",
defButton : "button0",
};
action = {
buttonClick : "ok",
passField : "mochipass1-new",
};
promptDone = handlePrompt(state, action);
iframeLoaded = onloadPromiseFor("iframe");
iframe.src = "authenticate.sjs?user=mochiuser1&pass=mochipass1-new";
yield promptDone;
yield iframeLoaded;
checkEchoedAuthInfo({user: "mochiuser1", pass: "mochipass1-new"},
iframe.contentDocument);
var pwchanged = promiseStorageChanged(["modifyLogin"]);
// Check for the popup notification, and change the password.
var popupNotifications = getPopupNotifications(window.top);
popup = getPopup(popupNotifications, "password-change");
ok(popup, "got popup notification");
clickPopupButton(popup, kChangeButton);
popup.remove();
yield pwchanged;
// Housekeeping: change it back
runInParent(() => {
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/Services.jsm");
var tmpLogin = Cc["@mozilla.org/login-manager/loginInfo;1"].
createInstance(Ci.nsILoginInfo);
tmpLogin.init("http://mochi.test:8888", null, "mochitest",
"mochiuser1", "mochipass1-new", "", "");
var login3A = Cc["@mozilla.org/login-manager/loginInfo;1"].
createInstance(Ci.nsILoginInfo);
login3A.init("http://mochi.test:8888", null, "mochitest",
"mochiuser1", "mochipass1", "", "");
Services.logins.modifyLogin(tmpLogin, login3A);
});
// Same as last test, but for a realm we haven't already authenticated
// to (but have an existing saved login for, so that we'll trigger
// a change-password popup notification.
state = {
msg : "http://mochi.test:8888 is requesting your username and password.\n\nThe site says: “mochitest3”",
title : "Authentication Required",
textValue : "mochiuser3",
passValue : "mochipass3-old",
iconClass : "authentication-icon question-icon",
titleHidden : true,
textHidden : false,
passHidden : false,
checkHidden : true,
checkMsg : "",
checked : false,
focused : "textField",
defButton : "button0",
};
action = {
buttonClick : "ok",
passField : "mochipass3-new",
};
promptDone = handlePrompt(state, action);
iframeLoaded = onloadPromiseFor("iframe");
iframe.src = "authenticate.sjs?user=mochiuser3&pass=mochipass3-new&realm=mochitest3";
yield promptDone;
yield iframeLoaded;
checkEchoedAuthInfo({user: "mochiuser3", pass: "mochipass3-new"},
iframe.contentDocument);
pwchanged = promiseStorageChanged(["modifyLogin"]);
// Check for the popup notification, and change the password.
popup = getPopup(popupNotifications, "password-change");
ok(popup, "got popup notification");
clickPopupButton(popup, kChangeButton);
popup.remove();
yield pwchanged;
// Housekeeping: change it back to the original login4. Actually,
// just delete it and we'll re-add it as the next test.
runInParent(() => {
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/Services.jsm");
var tmpLogin = Cc["@mozilla.org/login-manager/loginInfo;1"].
createInstance(Ci.nsILoginInfo);
tmpLogin.init("http://mochi.test:8888", null, "mochitest3",
"mochiuser3", "mochipass3-new", "", "");
Services.logins.removeLogin(tmpLogin);
// Clear cached auth from this subtest, and avoid leaking due to bug 459620.
var authMgr = Cc['@mozilla.org/network/http-auth-manager;1'].
getService(Ci.nsIHttpAuthManager);
authMgr.clearAll();
});
state = {
msg : "http://mochi.test:8888 is requesting your username and password.\n\nThe site says: “mochitest3”",
title : "Authentication Required",
textValue : "",
passValue : "",
iconClass : "authentication-icon question-icon",
titleHidden : true,
textHidden : false,
passHidden : false,
checkHidden : true,
checkMsg : "",
checked : false,
focused : "textField",
defButton : "button0",
};
action = {
buttonClick : "ok",
textField : "mochiuser3",
passField : "mochipass3-old",
};
// Trigger a new prompt, so we can test adding a new login.
promptDone = handlePrompt(state, action);
iframeLoaded = onloadPromiseFor("iframe");
iframe.src = "authenticate.sjs?user=mochiuser3&pass=mochipass3-old&realm=mochitest3";
yield promptDone;
yield iframeLoaded;
checkEchoedAuthInfo({user: "mochiuser3", pass: "mochipass3-old"},
iframe.contentDocument);
var pwsaved = promiseStorageChanged(["addLogin"]);
// Check for the popup notification, and change the password.
popup = getPopup(popupNotifications, "password-save");
ok(popup, "got popup notification");
clickPopupButton(popup, kRememberButton);
popup.remove();
yield pwsaved;
});
</script>
</pre>
</body>
</html>

View File

@ -7,28 +7,18 @@
<script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
<script type="text/javascript" src="pwmgr_common.js"></script>
<script type="text/javascript" src="prompt_common.js"></script>
<script type="text/javascript" src="notification_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
<iframe id="iframe"></iframe>
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
var state, action;
var pwmgr, observerService;
var tmpLogin, login1, login2A, login2B, login2C, login2D, login2E, login3A, login3B, login4, proxyLogin;
var isOk;
var mozproxy, proxiedHost = "http://mochi.test:8888";
var proxyChannel;
var systemPrincipal = SpecialPowers.Services.scriptSecurityManager.getSystemPrincipal();
var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
var level = Ci.nsIAuthPrompt2.LEVEL_NONE;
var authinfo = {
@ -41,68 +31,63 @@ var authinfo = {
realm : ""
};
var proxyAuthinfo = {
username : "",
password : "",
domain : "",
flags : Ci.nsIAuthInformation.AUTH_PROXY,
authenticationScheme : "basic",
realm : ""
};
var iframe = document.getElementById("iframe");
// Force parent to not look for tab-modal prompts, as they're not used for auth prompts.
isTabModal = false;
var channel1 = ioService.newChannel2("http://example.com",
null,
null,
null, // aLoadingNode
SpecialPowers.Services.
scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
Ci.nsIContentPolicy.TYPE_OTHER);
let chromeScript = runInParent(SimpleTest.getTestFileURL("pwmgr_common.js"));
var channel2 = ioService.newChannel2("http://example2.com",
null,
null,
null, // aLoadingNode
SpecialPowers.Services.
scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
Ci.nsIContentPolicy.TYPE_OTHER);
let prompterParent = runInParent(() => {
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
const promptFac = Cc["@mozilla.org/passwordmanager/authpromptfactory;1"].
getService(Ci.nsIPromptFactory);
Cu.import("resource://gre/modules/Services.jsm");
let chromeWin = Services.wm.getMostRecentWindow("navigator:browser");
let prompter2 = promptFac.getPrompt(chromeWin, Ci.nsIAuthPrompt2);
const Cc_promptFac= Cc["@mozilla.org/passwordmanager/authpromptfactory;1"];
ok(Cc_promptFac != null, "Access Cc[@mozilla.org/passwordmanager/authpromptfactory;1]");
let ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
let channels = {};
channels.channel1 = ioService.newChannel2("http://example.com",
null,
null,
null, // aLoadingNode
Services.
scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
Ci.nsIContentPolicy.TYPE_OTHER);
const Ci_promptFac = Ci.nsIPromptFactory;
ok(Ci_promptFac != null, "Access Ci.nsIPromptFactory");
channels.channel2 = ioService.newChannel2("http://example2.com",
null,
null,
null, // aLoadingNode
Services.
scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
Ci.nsIContentPolicy.TYPE_OTHER);
const promptFac = Cc_promptFac.getService(Ci_promptFac);
ok(promptFac != null, "promptFac getService()");
addMessageListener("proxyPrompter", function onMessage(msg) {
let args = [...msg.args];
let channelName = args.shift();
// Replace the channel name string (arg. 0) with the channel by that name.
args.unshift(channels[channelName]);
var prompter2 = promptFac.getPrompt(window, Ci.nsIAuthPrompt2);
let rv = prompter2[msg.methodName](...args);
return {
rv,
// Send the args back to content so out/inout args can be checked.
args: msg.args,
};
});
function initLogins(pi) {
observerService = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
observerService.addObserver(storageObserver, "passwordmgr-storage-changed", false);
Cu.import("resource://gre/modules/Services.jsm");
pwmgr = Cc["@mozilla.org/login-manager;1"].
getService(Ci.nsILoginManager);
let pwmgr = Cc["@mozilla.org/login-manager;1"].
getService(Ci.nsILoginManager);
mozproxy = "moz-proxy://" + SpecialPowers.wrap(pi).host + ":" +
SpecialPowers.wrap(pi).port;
tmpLogin = Cc["@mozilla.org/login-manager/loginInfo;1"].
createInstance(Ci.nsILoginInfo);
login1 = Cc["@mozilla.org/login-manager/loginInfo;1"]. // TODO
let login1, login2A, login2B, login2C, login2D, login2E;
login1 = Cc["@mozilla.org/login-manager/loginInfo;1"].
createInstance(Ci.nsILoginInfo);
login2A = Cc["@mozilla.org/login-manager/loginInfo;1"].
createInstance(Ci.nsILoginInfo);
@ -114,14 +99,6 @@ function initLogins(pi) {
createInstance(Ci.nsILoginInfo);
login2E = Cc["@mozilla.org/login-manager/loginInfo;1"].
createInstance(Ci.nsILoginInfo);
login3A = Cc["@mozilla.org/login-manager/loginInfo;1"].
createInstance(Ci.nsILoginInfo);
login3B = Cc["@mozilla.org/login-manager/loginInfo;1"].
createInstance(Ci.nsILoginInfo);
login4 = Cc["@mozilla.org/login-manager/loginInfo;1"].
createInstance(Ci.nsILoginInfo);
proxyLogin = Cc["@mozilla.org/login-manager/loginInfo;1"].
createInstance(Ci.nsILoginInfo);
login1.init("http://example.com", null, "http://example.com",
"", "examplepass", "", "");
@ -135,14 +112,6 @@ function initLogins(pi) {
"100@beef", "user3pass", "", "");
login2E.init("http://example2.com", null, "http://example2.com",
"100%beef", "user3pass", "", "");
login3A.init("http://mochi.test:8888", null, "mochitest",
"mochiuser1", "mochipass1", "", "");
login3B.init("http://mochi.test:8888", null, "mochitest2",
"mochiuser2", "mochipass2", "", "");
login4.init("http://mochi.test:8888", null, "mochitest3",
"mochiuser3", "mochipass3-old", "", "");
proxyLogin.init(mozproxy, null, "Proxy Realm",
"proxuser", "proxpass", "", "");
pwmgr.addLogin(login1);
pwmgr.addLogin(login2A);
@ -150,181 +119,11 @@ function initLogins(pi) {
pwmgr.addLogin(login2C);
pwmgr.addLogin(login2D);
pwmgr.addLogin(login2E);
pwmgr.addLogin(login3A);
pwmgr.addLogin(login3B);
pwmgr.addLogin(login4);
pwmgr.addLogin(proxyLogin);
}
function finishTest() {
try {
ok(true, "finishTest removing testing logins...");
observerService.removeObserver(storageObserver, "passwordmgr-storage-changed");
dumpLogins(pwmgr);
ok(true, "removing login 1...");
pwmgr.removeLogin(login1);
ok(true, "removing login 2A...");
pwmgr.removeLogin(login2A);
ok(true, "removing login 2B...");
pwmgr.removeLogin(login2B);
ok(true, "removing login 2C...");
pwmgr.removeLogin(login2C);
ok(true, "removing login 2D...");
pwmgr.removeLogin(login2D);
ok(true, "removing login 2E...");
pwmgr.removeLogin(login2E);
ok(true, "removing login 3A...");
pwmgr.removeLogin(login3A);
ok(true, "removing login 3B...");
pwmgr.removeLogin(login3B);
ok(true, "removing login 4...");
pwmgr.removeLogin(login4);
ok(true, "removing proxyLogin...");
pwmgr.removeLogin(proxyLogin);
} catch (e) {
ok(false, "finishTest FAILED: " + e);
}
ok(true, "whee, done!");
}
var startupCompleteResolver;
var startupComplete = new Promise(resolve => startupCompleteResolver = resolve);
function proxyChannelListener() { }
proxyChannelListener.prototype = {
onStartRequest: function(request, context) {
startupCompleteResolver();
},
onStopRequest: function(request, context, status) { }
};
var resolveCallback = SpecialPowers.wrapCallbackObject({
QueryInterface : function (iid) {
const interfaces = [Ci.nsIProtocolProxyCallback, Ci.nsISupports];
if (!interfaces.some( function(v) { return iid.equals(v) } ))
throw SpecialPowers.Cr.NS_ERROR_NO_INTERFACE;
return this;
},
onProxyAvailable : function (req, uri, pi, status) {
initLogins(pi);
// I'm cheating a bit here... We should probably do some magic foo to get
// something implementing nsIProxiedProtocolHandler and then call
// NewProxiedChannel(), so we have something that's definately a proxied
// channel. But Mochitests use a proxy for a number of hosts, so just
// requesting a normal channel will give us a channel that's proxied.
// The proxyChannel needs to move to at least on-modify-request to
// have valid ProxyInfo, but we use OnStartRequest during startup()
// for simplicity.
proxyChannel = ioService.newChannel2(proxiedHost,
null,
null,
null, // aLoadingNode
systemPrincipal,
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
Ci.nsIContentPolicy.TYPE_OTHER);
proxyChannel.asyncOpen2(SpecialPowers.wrapCallbackObject(new proxyChannelListener()));
}
});
function startup() {
//need to allow for arbitrary network servers defined in PAC instead of a hardcoded moz-proxy.
var ios = SpecialPowers.Cc["@mozilla.org/network/io-service;1"].
getService(SpecialPowers.Ci.nsIIOService);
let prompter2 = new PrompterProxy(prompterParent);
var pps = SpecialPowers.Cc["@mozilla.org/network/protocol-proxy-service;1"].getService();
var channel = ios.newChannel2("http://example.com",
null,
null,
null, // aLoadingNode
systemPrincipal,
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
Ci.nsIContentPolicy.TYPE_OTHER);
pps.asyncResolve(channel, 0, resolveCallback);
}
function addNotificationCallback(cb) {
storageObserver.notificationCallbacks.push(cb);
}
var storageObserver = SpecialPowers.wrapCallbackObject({
notificationCallbacks: [],
QueryInterface : function (iid) {
const interfaces = [Ci.nsIObserver,
Ci.nsISupports, Ci.nsISupportsWeakReference];
if (!interfaces.some( function(v) { return iid.equals(v) } ))
throw SpecialPowers.Cr.NS_ERROR_NO_INTERFACE;
return this;
},
observe : function (subject, topic, data) {
ok(true, ".");
ok(true, "observer for " + topic + " / " + data);
ok(true, "Time is " + (new Date()).toUTCString());
var wrapped = SpecialPowers.wrap(subject);
try {
switch (data) {
case "addLogin":
ok(wrapped.QueryInterface(Ci.nsILoginInfo), "subject QI 1");
ok(wrapped.QueryInterface(Ci.nsILoginMetaInfo), "subject QI 2");
dumpLogin("added: ", subject);
break;
case "modifyLogin":
var arr = wrapped.QueryInterface(Ci.nsIArray);
ok(arr, "subject QI");
is(arr.length, 2, "should be 2 items");
var oldLogin = arr.queryElementAt(0, Ci.nsILoginInfo);
var newLogin = arr.queryElementAt(1, Ci.nsILoginInfo);
dumpLogin("oldLogin: ", oldLogin);
dumpLogin("newLogin: ", newLogin);
break;
case "removeLogin":
ok(wrapped.QueryInterface(Ci.nsILoginInfo), "subject QI 1");
ok(wrapped.QueryInterface(Ci.nsILoginMetaInfo), "subject QI 2");
dumpLogin("removed: ", subject);
break;
case "removeAllLogins":
is(subject, null, "no subject");
break;
case "hostSavingEnabled":
case "hostSavingDisabled":
ok(subject instanceof Ci.nsISupportsString, "subject QI");
ok(true, "state is: " + subject.data);
break;
default:
do_throw("Unhandled notification: " + data + " / " + topic);
}
if (this.notificationCallbacks.length)
this.notificationCallbacks.splice(0, 1)[0]();
} catch (e) {
ok(false, "OBSERVER FAILED: " + e);
}
}
});
startup();
add_task(function* setup() {
info("Waiting for startup to complete...");
yield startupComplete;
// popupNotifications (not *popup*) is a constant, per-tab container. So, we
// only need to fetch it once.
var popupNotifications = getPopupNotifications(window.top);
ok(popupNotifications, "Got popupNotifications");
});
add_task(function* test() {
info("===== test 500 =====");
add_task(function* test_accept() {
state = {
msg : "http://example.com is requesting your username and password.\n\nThe site says: “some realm”",
title : "Authentication Required",
@ -350,14 +149,18 @@ add_task(function* test() {
authinfo.realm = "some realm";
promptDone = handlePrompt(state, action);
isOk = prompter2.promptAuth(channel1, level, authinfo);
// Since prompter2 is actually a proxy to send a message to a chrome script and
// we can't send a channel in a message, we instead send the channel name that
// already exists in the chromeScript.
isOk = prompter2.promptAuth("channel1", level, authinfo);
yield promptDone;
ok(isOk, "Checking dialog return value (accept)");
is(authinfo.username, "outuser", "Checking returned username");
is(authinfo.password, "outpass", "Checking returned password");
});
info("===== test 501 =====");
add_task(function* test_cancel() {
state = {
msg : "http://example.com is requesting your username and password.\n\nThe site says: “some realm”",
title : "Authentication Required",
@ -377,12 +180,13 @@ add_task(function* test() {
buttonClick : "cancel",
};
promptDone = handlePrompt(state, action);
isOk = prompter2.promptAuth(channel1, level, authinfo);
isOk = prompter2.promptAuth("channel1", level, authinfo);
yield promptDone;
ok(!isOk, "Checking dialog return value (cancel)");
});
info("===== test 502 =====");
add_task(function* test_pwonly() {
// test filling in password-only login
state = {
msg : "http://example.com is requesting your username and password.\n\nThe site says: “http://example.com”",
@ -407,14 +211,15 @@ add_task(function* test() {
authinfo.realm = "http://example.com";
promptDone = handlePrompt(state, action);
isOk = prompter2.promptAuth(channel1, level, authinfo);
isOk = prompter2.promptAuth("channel1", level, authinfo);
yield promptDone;
ok(isOk, "Checking dialog return value (accept)");
is(authinfo.username, "", "Checking returned username");
is(authinfo.password, "examplepass", "Checking returned password");
});
info("===== test 503 =====");
add_task(function* test_multipleExisting() {
// test filling in existing login (undetermined from multiple selection)
// user2name/user2pass would also be valid to fill here.
state = {
@ -440,14 +245,15 @@ add_task(function* test() {
authinfo.realm = "http://example2.com";
promptDone = handlePrompt(state, action);
isOk = prompter2.promptAuth(channel2, level, authinfo);
isOk = prompter2.promptAuth("channel2", level, authinfo);
yield promptDone;
ok(isOk, "Checking dialog return value (accept)");
ok(authinfo.username == "user1name" || authinfo.username == "user2name", "Checking returned username");
ok(authinfo.password == "user1pass" || authinfo.password == "user2pass", "Checking returned password");
});
info("===== test 504 =====");
add_task(function* test_multipleExisting2() {
// test filling in existing login (undetermined --> user1)
// user2name/user2pass would also be valid to fill here.
state = {
@ -476,14 +282,15 @@ add_task(function* test() {
authinfo.realm = "http://example2.com";
promptDone = handlePrompt(state, action);
isOk = prompter2.promptAuth(channel2, level, authinfo);
isOk = prompter2.promptAuth("channel2", level, authinfo);
yield promptDone;
ok(isOk, "Checking dialog return value (accept)");
is(authinfo.username, "user1name", "Checking returned username");
is(authinfo.password, "user1pass", "Checking returned password");
});
info("===== test 505 =====");
add_task(function* test_multipleExisting3() {
// test filling in existing login (undetermined --> user2)
// user2name/user2pass would also be valid to fill here.
state = {
@ -511,16 +318,16 @@ add_task(function* test() {
authinfo.password = "";
authinfo.realm = "http://example2.com";
dumpNotifications();
promptDone = handlePrompt(state, action);
isOk = prompter2.promptAuth(channel2, level, authinfo);
isOk = prompter2.promptAuth("channel2", level, authinfo);
yield promptDone;
ok(isOk, "Checking dialog return value (accept)");
is(authinfo.username, "user2name", "Checking returned username");
is(authinfo.password, "user2pass", "Checking returned password");
});
info("===== test 506 =====");
add_task(function* test_changingMultiple() {
// test changing a password (undetermined --> user2 w/ newpass)
// user2name/user2pass would also be valid to fill here.
state = {
@ -548,16 +355,16 @@ add_task(function* test() {
authinfo.password = "";
authinfo.realm = "http://example2.com";
dumpNotifications();
promptDone = handlePrompt(state, action);
isOk = prompter2.promptAuth(channel2, level, authinfo);
isOk = prompter2.promptAuth("channel2", level, authinfo);
yield promptDone;
ok(isOk, "Checking dialog return value (accept)");
is(authinfo.username, "user2name", "Checking returned username");
is(authinfo.password, "NEWuser2pass", "Checking returned password");
});
info("===== test 507 =====");
add_task(function* test_changingMultiple2() {
// test changing a password (undetermined --> user2 w/ origpass)
// user2name/user2pass would also be valid to fill here.
state = {
@ -585,358 +392,13 @@ add_task(function* test() {
authinfo.password = "";
authinfo.realm = "http://example2.com";
dumpNotifications();
promptDone = handlePrompt(state, action);
isOk = prompter2.promptAuth(channel2, level, authinfo);
isOk = prompter2.promptAuth("channel2", level, authinfo);
yield promptDone;
ok(isOk, "Checking dialog return value (accept)");
is(authinfo.username, "user2name", "Checking returned username");
is(authinfo.password, "user2pass", "Checking returned password");
info("===== test 508 =====");
// test proxy login (default = no autologin), make sure it prompts.
state = {
msg : "The proxy moz-proxy://127.0.0.1:8888 is requesting a username and password.\n\nThe site says: “Proxy Realm”",
title : "Authentication Required",
textValue : "proxuser",
passValue : "proxpass",
iconClass : "authentication-icon question-icon",
titleHidden : true,
textHidden : false,
passHidden : false,
checkHidden : true,
checkMsg : "",
checked : false,
focused : "textField",
defButton : "button0",
};
action = {
buttonClick : "ok",
};
proxyAuthinfo.username = "";
proxyAuthinfo.password = "";
proxyAuthinfo.realm = "Proxy Realm";
proxyAuthinfo.flags = Ci.nsIAuthInformation.AUTH_PROXY;
dumpNotifications();
var time1 = pwmgr.findLogins({}, mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed;
promptDone = handlePrompt(state, action);
isOk = prompter2.promptAuth(proxyChannel, level, proxyAuthinfo);
yield promptDone;
var time2 = pwmgr.findLogins({}, mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed;
ok(isOk, "Checking dialog return value (accept)");
isnot(time1, time2, "Checking that timeLastUsed was updated");
is(proxyAuthinfo.username, "proxuser", "Checking returned username");
is(proxyAuthinfo.password, "proxpass", "Checking returned password");
info("===== test 509 =====");
// test proxy login (with autologin)
// Enable the autologin pref.
prefs.setBoolPref("signon.autologin.proxy", true);
proxyAuthinfo.username = "";
proxyAuthinfo.password = "";
proxyAuthinfo.realm = "Proxy Realm";
proxyAuthinfo.flags = Ci.nsIAuthInformation.AUTH_PROXY;
time1 = pwmgr.findLogins({}, mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed;
isOk = prompter2.promptAuth(proxyChannel, level, proxyAuthinfo);
time2 = pwmgr.findLogins({}, mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed;
ok(isOk, "Checking dialog return value (accept)");
isnot(time1, time2, "Checking that timeLastUsed was updated");
is(proxyAuthinfo.username, "proxuser", "Checking returned username");
is(proxyAuthinfo.password, "proxpass", "Checking returned password");
info("===== test 510 =====");
// test proxy login (with autologin), ensure it prompts after a failed auth.
state = {
msg : "The proxy moz-proxy://127.0.0.1:8888 is requesting a username and password.\n\nThe site says: “Proxy Realm”",
title : "Authentication Required",
textValue : "proxuser",
passValue : "proxpass",
iconClass : "authentication-icon question-icon",
titleHidden : true,
textHidden : false,
passHidden : false,
checkHidden : true,
checkMsg : "",
checked : false,
focused : "textField",
defButton : "button0",
};
action = {
buttonClick : "ok",
};
proxyAuthinfo.username = "";
proxyAuthinfo.password = "";
proxyAuthinfo.realm = "Proxy Realm";
proxyAuthinfo.flags = (Ci.nsIAuthInformation.AUTH_PROXY | Ci.nsIAuthInformation.PREVIOUS_FAILED);
time1 = pwmgr.findLogins({}, mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed;
promptDone = handlePrompt(state, action);
isOk = prompter2.promptAuth(proxyChannel, level, proxyAuthinfo);
yield promptDone;
time2 = pwmgr.findLogins({}, mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed;
ok(isOk, "Checking dialog return value (accept)");
isnot(time1, time2, "Checking that timeLastUsed was updated");
is(proxyAuthinfo.username, "proxuser", "Checking returned username");
is(proxyAuthinfo.password, "proxpass", "Checking returned password");
info("===== test 511 =====");
// test proxy login (with autologin), ensure it prompts in Private Browsing mode.
state = {
msg : "the message",
title : "the title",
textValue : "proxuser",
passValue : "proxpass",
};
action = {
buttonClick : "ok",
};
proxyAuthinfo.username = "";
proxyAuthinfo.password = "";
proxyAuthinfo.realm = "Proxy Realm";
proxyAuthinfo.flags = Ci.nsIAuthInformation.AUTH_PROXY;
prefs.clearUserPref("signon.autologin.proxy");
// XXX check for and kill popup notification??
// XXX check for checkbox / checkstate on old prompts?
// XXX check NTLM domain stuff
// clear plain HTTP auth sessions before the test, to allow
// running them more than once.
var authMgr = Cc['@mozilla.org/network/http-auth-manager;1'].
getService(Ci.nsIHttpAuthManager);
authMgr.clearAll();
info("===== test 1000 =====");
state = {
msg : "http://mochi.test:8888 is requesting your username and password.\n\nThe site says: “mochitest”",
title : "Authentication Required",
textValue : "mochiuser1",
passValue : "mochipass1",
iconClass : "authentication-icon question-icon",
titleHidden : true,
textHidden : false,
passHidden : false,
checkHidden : true,
checkMsg : "",
checked : false,
focused : "textField",
defButton : "button0",
};
action = {
buttonClick : "ok",
};
promptDone = handlePrompt(state, action);
// The following tests are driven by iframe loads
var iframeLoaded = onloadPromiseFor("iframe");
iframe.src = "authenticate.sjs?user=mochiuser1&pass=mochipass1";
yield promptDone;
yield iframeLoaded;
checkEchoedAuthInfo({user: "mochiuser1", pass: "mochipass1"},
iframe.contentDocument);
state = {
msg : "http://mochi.test:8888 is requesting your username and password.\n\nThe site says: “mochitest2”",
title : "Authentication Required",
textValue : "mochiuser2",
passValue : "mochipass2",
iconClass : "authentication-icon question-icon",
titleHidden : true,
textHidden : false,
passHidden : false,
checkHidden : true,
checkMsg : "",
checked : false,
focused : "textField",
defButton : "button0",
};
action = {
buttonClick : "ok",
};
promptDone = handlePrompt(state, action);
// We've already authenticated to this host:port. For this next
// request, the existing auth should be sent, we'll get a 401 reply,
// and we should prompt for new auth.
iframeLoaded = onloadPromiseFor("iframe");
iframe.src = "authenticate.sjs?user=mochiuser2&pass=mochipass2&realm=mochitest2";
yield promptDone;
yield iframeLoaded;
checkEchoedAuthInfo({user: "mochiuser2", pass: "mochipass2"},
iframe.contentDocument);
// Now make a load that requests the realm from test 1000. It was
// already provided there, so auth will *not* be prompted for -- the
// networking layer already knows it!
iframeLoaded = onloadPromiseFor("iframe");
iframe.src = "authenticate.sjs?user=mochiuser1&pass=mochipass1";
yield iframeLoaded;
checkEchoedAuthInfo({user: "mochiuser1", pass: "mochipass1"},
iframe.contentDocument);
// Same realm we've already authenticated to, but with a different
// expected password (to trigger an auth prompt, and change-password
// popup notification).
state = {
msg : "http://mochi.test:8888 is requesting your username and password.\n\nThe site says: “mochitest”",
title : "Authentication Required",
textValue : "mochiuser1",
passValue : "mochipass1",
iconClass : "authentication-icon question-icon",
titleHidden : true,
textHidden : false,
passHidden : false,
checkHidden : true,
checkMsg : "",
checked : false,
focused : "textField",
defButton : "button0",
};
action = {
buttonClick : "ok",
passField : "mochipass1-new",
};
promptDone = handlePrompt(state, action);
iframeLoaded = onloadPromiseFor("iframe");
iframe.src = "authenticate.sjs?user=mochiuser1&pass=mochipass1-new";
yield promptDone;
yield iframeLoaded;
checkEchoedAuthInfo({user: "mochiuser1", pass: "mochipass1-new"},
iframe.contentDocument);
// Housekeeping: change it back
var pwchanged = new Promise(resolve => {
function resetIt() {
tmpLogin.init("http://mochi.test:8888", null, "mochitest",
"mochiuser1", "mochipass1-new", "", "");
pwmgr.modifyLogin(tmpLogin, login3A);
resolve(true);
}
addNotificationCallback(resetIt);
});
// Check for the popup notification, and change the password.
popupNotifications = getPopupNotifications(window.top);
popup = getPopup(popupNotifications, "password-change");
ok(popup, "got popup notification");
clickPopupButton(popup, kChangeButton);
popup.remove();
yield pwchanged;
// Same as last test, but for a realm we haven't already authenticated
// to (but have an existing saved login for, so that we'll trigger
// a change-password popup notification.
state = {
msg : "http://mochi.test:8888 is requesting your username and password.\n\nThe site says: “mochitest3”",
title : "Authentication Required",
textValue : "mochiuser3",
passValue : "mochipass3-old",
iconClass : "authentication-icon question-icon",
titleHidden : true,
textHidden : false,
passHidden : false,
checkHidden : true,
checkMsg : "",
checked : false,
focused : "textField",
defButton : "button0",
};
action = {
buttonClick : "ok",
passField : "mochipass3-new",
};
promptDone = handlePrompt(state, action);
iframeLoaded = onloadPromiseFor("iframe");
iframe.src = "authenticate.sjs?user=mochiuser3&pass=mochipass3-new&realm=mochitest3";
yield promptDone;
yield iframeLoaded;
checkEchoedAuthInfo({user: "mochiuser3", pass: "mochipass3-new"},
iframe.contentDocument);
// Housekeeping: change it back to the original login4. Actually,
// just delete it and we'll re-add it as the next test.
pwchanged = new Promise(resolve => {
function clearIt() {
ok(true, "1004's clearIt() called.");
try {
tmpLogin.init("http://mochi.test:8888", null, "mochitest3",
"mochiuser3", "mochipass3-new", "", "");
pwmgr.removeLogin(tmpLogin);
} catch (e) { ok(false, "clearIt GOT EXCEPTION: " + e); }
resolve(true);
}
addNotificationCallback(clearIt);
});
// Check for the popup notification, and change the password.
popup = getPopup(popupNotifications, "password-change");
ok(popup, "got popup notification");
clickPopupButton(popup, kChangeButton);
popup.remove();
yield pwchanged;
// Clear cached auth from this subtest, and avoid leaking due to bug 459620.
authMgr.clearAll();
ok(true, "authMgr cleared cached auth");
state = {
msg : "http://mochi.test:8888 is requesting your username and password.\n\nThe site says: “mochitest3”",
title : "Authentication Required",
textValue : "",
passValue : "",
iconClass : "authentication-icon question-icon",
titleHidden : true,
textHidden : false,
passHidden : false,
checkHidden : true,
checkMsg : "",
checked : false,
focused : "textField",
defButton : "button0",
};
action = {
buttonClick : "ok",
textField : "mochiuser3",
passField : "mochipass3-old",
};
// Trigger a new prompt, so we can test adding a new login.
promptDone = handlePrompt(state, action);
iframeLoaded = onloadPromiseFor("iframe");
iframe.src = "authenticate.sjs?user=mochiuser3&pass=mochipass3-old&realm=mochitest3";
yield promptDone;
yield iframeLoaded;
checkEchoedAuthInfo({user: "mochiuser3", pass: "mochipass3-old"},
iframe.contentDocument);
var pwsaved = new Promise(resolve => {
function finishIt() {
finishTest();
resolve(true);
}
addNotificationCallback(finishIt);
});
// Check for the popup notification, and change the password.
popup = getPopup(popupNotifications, "password-save");
ok(popup, "got popup notification");
clickPopupButton(popup, kRememberButton);
popup.remove();
yield pwsaved;
});
</script>
</pre>

View File

@ -0,0 +1,264 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test promptAuth proxy prompts</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
<script type="text/javascript" src="pwmgr_common.js"></script>
<script type="text/javascript" src="prompt_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
<iframe id="iframe"></iframe>
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
var state, action;
var pwmgr;
var proxyLogin;
var isOk;
var mozproxy, proxiedHost = "http://mochi.test:8888";
var proxyChannel;
var systemPrincipal = SpecialPowers.Services.scriptSecurityManager.getSystemPrincipal();
var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
var level = Ci.nsIAuthPrompt2.LEVEL_NONE;
var proxyAuthinfo = {
username : "",
password : "",
domain : "",
flags : Ci.nsIAuthInformation.AUTH_PROXY,
authenticationScheme : "basic",
realm : ""
};
// Force parent to not look for tab-modal prompts, as they're not used for auth prompts.
isTabModal = false;
const Cc_promptFac= Cc["@mozilla.org/passwordmanager/authpromptfactory;1"];
ok(Cc_promptFac != null, "Access Cc[@mozilla.org/passwordmanager/authpromptfactory;1]");
const Ci_promptFac = Ci.nsIPromptFactory;
ok(Ci_promptFac != null, "Access Ci.nsIPromptFactory");
const promptFac = Cc_promptFac.getService(Ci_promptFac);
ok(promptFac != null, "promptFac getService()");
var prompter2 = promptFac.getPrompt(window, Ci.nsIAuthPrompt2);
function initLogins(pi) {
pwmgr = Cc["@mozilla.org/login-manager;1"].
getService(Ci.nsILoginManager);
mozproxy = "moz-proxy://" + SpecialPowers.wrap(pi).host + ":" +
SpecialPowers.wrap(pi).port;
proxyLogin = Cc["@mozilla.org/login-manager/loginInfo;1"].
createInstance(Ci.nsILoginInfo);
proxyLogin.init(mozproxy, null, "Proxy Realm",
"proxuser", "proxpass", "", "");
pwmgr.addLogin(proxyLogin);
}
var startupCompleteResolver;
var startupComplete = new Promise(resolve => startupCompleteResolver = resolve);
function proxyChannelListener() { }
proxyChannelListener.prototype = {
onStartRequest: function(request, context) {
startupCompleteResolver();
},
onStopRequest: function(request, context, status) { }
};
var resolveCallback = SpecialPowers.wrapCallbackObject({
QueryInterface : function (iid) {
const interfaces = [Ci.nsIProtocolProxyCallback, Ci.nsISupports];
if (!interfaces.some( function(v) { return iid.equals(v) } ))
throw SpecialPowers.Cr.NS_ERROR_NO_INTERFACE;
return this;
},
onProxyAvailable : function (req, uri, pi, status) {
initLogins(pi);
// I'm cheating a bit here... We should probably do some magic foo to get
// something implementing nsIProxiedProtocolHandler and then call
// NewProxiedChannel(), so we have something that's definately a proxied
// channel. But Mochitests use a proxy for a number of hosts, so just
// requesting a normal channel will give us a channel that's proxied.
// The proxyChannel needs to move to at least on-modify-request to
// have valid ProxyInfo, but we use OnStartRequest during startup()
// for simplicity.
proxyChannel = ioService.newChannel2(proxiedHost,
null,
null,
null, // aLoadingNode
systemPrincipal,
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
Ci.nsIContentPolicy.TYPE_OTHER);
proxyChannel.asyncOpen2(SpecialPowers.wrapCallbackObject(new proxyChannelListener()));
}
});
function startup() {
//need to allow for arbitrary network servers defined in PAC instead of a hardcoded moz-proxy.
var ios = SpecialPowers.Cc["@mozilla.org/network/io-service;1"].
getService(SpecialPowers.Ci.nsIIOService);
var pps = SpecialPowers.Cc["@mozilla.org/network/protocol-proxy-service;1"].getService();
var channel = ios.newChannel2("http://example.com",
null,
null,
null, // aLoadingNode
systemPrincipal,
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
Ci.nsIContentPolicy.TYPE_OTHER);
pps.asyncResolve(channel, 0, resolveCallback);
}
startup();
add_task(function* setup() {
info("Waiting for startup to complete...");
yield startupComplete;
})
add_task(function* test_noAutologin() {
// test proxy login (default = no autologin), make sure it prompts.
state = {
msg : "The proxy moz-proxy://127.0.0.1:8888 is requesting a username and password.\n\nThe site says: “Proxy Realm”",
title : "Authentication Required",
textValue : "proxuser",
passValue : "proxpass",
iconClass : "authentication-icon question-icon",
titleHidden : true,
textHidden : false,
passHidden : false,
checkHidden : true,
checkMsg : "",
checked : false,
focused : "textField",
defButton : "button0",
};
action = {
buttonClick : "ok",
};
proxyAuthinfo.username = "";
proxyAuthinfo.password = "";
proxyAuthinfo.realm = "Proxy Realm";
proxyAuthinfo.flags = Ci.nsIAuthInformation.AUTH_PROXY;
var time1 = pwmgr.findLogins({}, mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed;
promptDone = handlePrompt(state, action);
isOk = prompter2.promptAuth(proxyChannel, level, proxyAuthinfo);
yield promptDone;
var time2 = pwmgr.findLogins({}, mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed;
ok(isOk, "Checking dialog return value (accept)");
isnot(time1, time2, "Checking that timeLastUsed was updated");
is(proxyAuthinfo.username, "proxuser", "Checking returned username");
is(proxyAuthinfo.password, "proxpass", "Checking returned password");
});
add_task(function* test_autologin() {
// test proxy login (with autologin)
// Enable the autologin pref.
prefs.setBoolPref("signon.autologin.proxy", true);
proxyAuthinfo.username = "";
proxyAuthinfo.password = "";
proxyAuthinfo.realm = "Proxy Realm";
proxyAuthinfo.flags = Ci.nsIAuthInformation.AUTH_PROXY;
time1 = pwmgr.findLogins({}, mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed;
isOk = prompter2.promptAuth(proxyChannel, level, proxyAuthinfo);
time2 = pwmgr.findLogins({}, mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed;
ok(isOk, "Checking dialog return value (accept)");
isnot(time1, time2, "Checking that timeLastUsed was updated");
is(proxyAuthinfo.username, "proxuser", "Checking returned username");
is(proxyAuthinfo.password, "proxpass", "Checking returned password");
});
add_task(function* test_autologin_incorrect() {
// test proxy login (with autologin), ensure it prompts after a failed auth.
state = {
msg : "The proxy moz-proxy://127.0.0.1:8888 is requesting a username and password.\n\nThe site says: “Proxy Realm”",
title : "Authentication Required",
textValue : "proxuser",
passValue : "proxpass",
iconClass : "authentication-icon question-icon",
titleHidden : true,
textHidden : false,
passHidden : false,
checkHidden : true,
checkMsg : "",
checked : false,
focused : "textField",
defButton : "button0",
};
action = {
buttonClick : "ok",
};
proxyAuthinfo.username = "";
proxyAuthinfo.password = "";
proxyAuthinfo.realm = "Proxy Realm";
proxyAuthinfo.flags = (Ci.nsIAuthInformation.AUTH_PROXY | Ci.nsIAuthInformation.PREVIOUS_FAILED);
time1 = pwmgr.findLogins({}, mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed;
promptDone = handlePrompt(state, action);
isOk = prompter2.promptAuth(proxyChannel, level, proxyAuthinfo);
yield promptDone;
time2 = pwmgr.findLogins({}, mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed;
ok(isOk, "Checking dialog return value (accept)");
isnot(time1, time2, "Checking that timeLastUsed was updated");
is(proxyAuthinfo.username, "proxuser", "Checking returned username");
is(proxyAuthinfo.password, "proxpass", "Checking returned password");
});
add_task(function* test_autologin_private() {
// test proxy login (with autologin), ensure it prompts in Private Browsing mode.
state = {
msg : "the message",
title : "the title",
textValue : "proxuser",
passValue : "proxpass",
};
action = {
buttonClick : "ok",
};
proxyAuthinfo.username = "";
proxyAuthinfo.password = "";
proxyAuthinfo.realm = "Proxy Realm";
proxyAuthinfo.flags = Ci.nsIAuthInformation.AUTH_PROXY;
prefs.clearUserPref("signon.autologin.proxy");
// XXX check for and kill popup notification??
// XXX check for checkbox / checkstate on old prompts?
// XXX check NTLM domain stuff
});
</script>
</pre>
</body>
</html>

View File

@ -1434,10 +1434,10 @@ Task.async(function* (db, folderGuids, options) {
b.type, url, b.guid, p.guid AS parentGuid, b.dateAdded,
b.lastModified, b.title, p.parent AS _grandParentId,
NULL AS _childCount
FROM moz_bookmarks b
FROM descendants
JOIN moz_bookmarks b ON did = b.id
JOIN moz_bookmarks p ON p.id = b.parent
LEFT JOIN moz_places h ON b.fk = h.id
WHERE b.id IN descendants`, { folderGuid });
LEFT JOIN moz_places h ON b.fk = h.id`, { folderGuid });
itemsRemoved = itemsRemoved.concat(rowsToItemsArray(rows));

View File

@ -81,6 +81,32 @@ add_task(function* test_eraseEverything_roots() {
Assert.ok(yield PlacesUtils.bookmarks.fetch(PlacesUtils.bookmarks.rootGuid));
});
function run_test() {
run_next_test();
}
add_task(function* test_eraseEverything_reparented() {
// Create a folder with 1 bookmark in it...
let folder1 = yield PlacesUtils.bookmarks.insert({
parentGuid: PlacesUtils.bookmarks.toolbarGuid,
type: PlacesUtils.bookmarks.TYPE_FOLDER
});
let bookmark1 = yield PlacesUtils.bookmarks.insert({
parentGuid: folder1.guid,
url: "http://example.com/"
});
// ...and a second folder.
let folder2 = yield PlacesUtils.bookmarks.insert({
parentGuid: PlacesUtils.bookmarks.toolbarGuid,
type: PlacesUtils.bookmarks.TYPE_FOLDER
});
// Reparent the bookmark to the 2nd folder.
bookmark1.parentGuid = folder2.guid;
yield PlacesUtils.bookmarks.update(bookmark1);
// Erase everything.
yield PlacesUtils.bookmarks.eraseEverything();
// All the above items should no longer be in the GUIDHelper cache.
for (let guid of [folder1.guid, bookmark1.guid, folder2.guid]) {
yield Assert.rejects(PlacesUtils.promiseItemId(guid),
/no item found for the given GUID/);
}
});

View File

@ -363,15 +363,16 @@ add_task(function* eraseEverything_notification() {
let observer = expectNotifications();
yield PlacesUtils.bookmarks.eraseEverything();
// Bookmarks should always be notified before their parents.
observer.check([ { name: "onItemRemoved",
arguments: [ itemId, parentId, bm.index, bm.type,
bm.url, bm.guid, bm.parentGuid,
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] },
{ name: "onItemRemoved",
arguments: [ folder2Id, folder2ParentId, folder2.index,
folder2.type, null, folder2.guid,
folder2.parentGuid,
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] },
{ name: "onItemRemoved",
arguments: [ itemId, parentId, bm.index, bm.type,
bm.url, bm.guid, bm.parentGuid,
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] },
{ name: "onItemRemoved",
arguments: [ folder1Id, folder1ParentId, folder1.index,
folder1.type, null, folder1.guid,
@ -388,7 +389,51 @@ add_task(function* eraseEverything_notification() {
toolbarBm.index, toolbarBm.type,
toolbarBm.url, toolbarBm.guid,
toolbarBm.parentGuid,
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] }
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] },
]);
});
add_task(function* eraseEverything_reparented_notification() {
// Let's start from a clean situation.
yield PlacesUtils.bookmarks.eraseEverything();
let folder1 = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_FOLDER,
parentGuid: PlacesUtils.bookmarks.unfiledGuid });
let folder1Id = yield PlacesUtils.promiseItemId(folder1.guid);
let folder1ParentId = yield PlacesUtils.promiseItemId(folder1.parentGuid);
let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
parentGuid: folder1.guid,
url: new URL("http://example.com/") });
let itemId = yield PlacesUtils.promiseItemId(bm.guid);
let folder2 = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_FOLDER,
parentGuid: PlacesUtils.bookmarks.unfiledGuid });
let folder2Id = yield PlacesUtils.promiseItemId(folder2.guid);
let folder2ParentId = yield PlacesUtils.promiseItemId(folder2.parentGuid);
bm.parentGuid = folder2.guid;
bm = yield PlacesUtils.bookmarks.update(bm);
let parentId = yield PlacesUtils.promiseItemId(bm.parentGuid);
let observer = expectNotifications();
yield PlacesUtils.bookmarks.eraseEverything();
// Bookmarks should always be notified before their parents.
observer.check([ { name: "onItemRemoved",
arguments: [ itemId, parentId, bm.index, bm.type,
bm.url, bm.guid, bm.parentGuid,
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] },
{ name: "onItemRemoved",
arguments: [ folder2Id, folder2ParentId, folder2.index,
folder2.type, null, folder2.guid,
folder2.parentGuid,
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] },
{ name: "onItemRemoved",
arguments: [ folder1Id, folder1ParentId, folder1.index,
folder1.type, null, folder1.guid,
folder1.parentGuid,
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] },
]);
});

View File

@ -190,8 +190,8 @@ add_task(function* test_nested_content_fails_when_not_allowed() {
let folder2 = yield PlacesUtils.bookmarks.insert({ parentGuid: folder1.guid,
type: PlacesUtils.bookmarks.TYPE_FOLDER,
title: "a folder" });
Assert.rejects(PlacesUtils.bookmarks.remove(folder1, {preventRemovalOfNonEmptyFolders: true}),
/Cannot remove a non-empty folder./);
yield Assert.rejects(PlacesUtils.bookmarks.remove(folder1, {preventRemovalOfNonEmptyFolders: true}),
/Cannot remove a non-empty folder./);
});
function run_test() {

View File

@ -95,7 +95,7 @@ function checkEchoedAuthInfo(expectedState, doc) {
}
/**
* Create a Proxy to relay method calls on an nsIAuthPrompt prompter to a chrome script which can
* Create a Proxy to relay method calls on an nsIAuthPrompt[2] prompter to a chrome script which can
* perform the calls in the parent. Out and inout params will be copied back from the parent to
* content.
*
@ -118,6 +118,10 @@ function PrompterProxy(chromeScript) {
outParams = [/* result */ 5];
break;
}
case "promptAuth": {
outParams = [];
break;
}
case "promptPassword": {
outParams = [/* pwd */ 4];
break;
@ -142,6 +146,12 @@ function PrompterProxy(chromeScript) {
args[outParam].value = result.args[outParam].value;
}
if (prop == "promptAuth") {
args[2].username = result.args[2].username;
args[2].password = result.args[2].password;
args[2].domain = result.args[2].domain;
}
return result.rv;
};
},

View File

@ -4552,6 +4552,8 @@
"description": "THUMBNAILS: Thumbnail found"
},
"FX_MIGRATION_ENTRY_POINT": {
"bug_numbers": [731025],
"alert_emails": ["gijs@mozilla.com"],
"expires_in_version": "53",
"kind": "enumerated",
"n_values": 10,
@ -4559,6 +4561,8 @@
"description": "Where the migration wizard was entered from. 0=Other/catch-all, 1=first-run, 2=refresh-firefox, 3=Places window, 4=Password manager"
},
"FX_MIGRATION_SOURCE_BROWSER": {
"bug_numbers": [731025],
"alert_emails": ["gijs@mozilla.com"],
"expires_in_version": "53",
"kind": "enumerated",
"n_values": 15,
@ -4566,6 +4570,8 @@
"description": "The browser that data is pulled from. The values correspond to the internal browser ID (see MigrationUtils.jsm)"
},
"FX_MIGRATION_ERRORS": {
"bug_numbers": [731025],
"alert_emails": ["gijs@mozilla.com"],
"expires_in_version": "53",
"kind": "enumerated",
"keyed": true,
@ -4574,6 +4580,8 @@
"description": "Errors encountered during migration in buckets defined by the datatype, keyed by the string description of the browser."
},
"FX_MIGRATION_USAGE": {
"bug_numbers": [731025],
"alert_emails": ["gijs@mozilla.com"],
"expires_in_version": "53",
"kind": "enumerated",
"keyed": true,
@ -4581,7 +4589,9 @@
"releaseChannelCollection": "opt-out",
"description": "Usage of migration for each datatype when migration is run through the post-firstrun flow which allows individual datatypes, keyed by the string description of the browser."
},
"FX_MIGRATION_HOMEPAGE_IMPORTED": {
"FX_MIGRATION_IMPORTED_HOMEPAGE": {
"bug_numbers": [731025, 1298208],
"alert_emails": ["gijs@mozilla.com"],
"expires_in_version": "53",
"kind": "boolean",
"keyed": true,

View File

@ -266,11 +266,6 @@
"FX_BROWSER_FULLSCREEN_USED",
"FX_GESTURE_COMPRESS_SNAPSHOT_OF_PAGE",
"FX_GESTURE_INSTALL_SNAPSHOT_OF_PAGE",
"FX_MIGRATION_ENTRY_POINT",
"FX_MIGRATION_ERRORS",
"FX_MIGRATION_HOMEPAGE_IMPORTED",
"FX_MIGRATION_SOURCE_BROWSER",
"FX_MIGRATION_USAGE",
"FX_NEW_WINDOW_MS",
"FX_PAGE_LOAD_MS",
"FX_SESSION_RESTORE_DOM_STORAGE_SIZE_ESTIMATE_CHARS",
@ -1115,11 +1110,6 @@
"FX_BROWSER_FULLSCREEN_USED",
"FX_GESTURE_COMPRESS_SNAPSHOT_OF_PAGE",
"FX_GESTURE_INSTALL_SNAPSHOT_OF_PAGE",
"FX_MIGRATION_ENTRY_POINT",
"FX_MIGRATION_ERRORS",
"FX_MIGRATION_HOMEPAGE_IMPORTED",
"FX_MIGRATION_SOURCE_BROWSER",
"FX_MIGRATION_USAGE",
"FX_NEW_WINDOW_MS",
"FX_PAGE_LOAD_MS",
"FX_SANITIZE_CACHE",