From 38953656b3f6f47d3632a4cc6966f2de68cf7f52 Mon Sep 17 00:00:00 2001 From: Brian Grinstead Date: Wed, 2 Sep 2015 09:06:10 -0700 Subject: [PATCH 01/27] Bug 789430 - Pause on next bytecode instead of immediately;r=fitzgen --HG-- extra : commitid : D6TZ8aRlGIU --- .../devtools/debugger/debugger-controller.js | 5 +- .../debugger/test/mochitest/browser.ini | 2 + .../browser_dbg_break-on-next-console.js | 71 ++++++++++++++ .../mochitest/browser_dbg_break-on-next.js | 93 +++++++++++++++++++ .../test/mochitest/browser_dbg_interrupts.js | 28 ++++++ .../browser_dbg_on-pause-highlight.js | 5 + .../mochitest/browser_dbg_on-pause-raise.js | 5 + .../mochitest/browser_dbg_pause-no-step.js | 35 ++++--- .../mochitest/browser_dbg_pause-resume.js | 9 ++ .../mochitest/browser_dbg_pause-warning.js | 5 + .../devtools/debugger/views/toolbar-view.js | 25 ++++- browser/devtools/framework/gDevTools.jsm | 6 +- .../browser/devtools/debugger.properties | 8 +- browser/themes/shared/devtools/debugger.css | 7 +- toolkit/devtools/client/main.js | 27 +++++- toolkit/devtools/server/actors/script.js | 14 ++- 16 files changed, 317 insertions(+), 28 deletions(-) create mode 100644 browser/devtools/debugger/test/mochitest/browser_dbg_break-on-next-console.js create mode 100644 browser/devtools/debugger/test/mochitest/browser_dbg_break-on-next.js diff --git a/browser/devtools/debugger/debugger-controller.js b/browser/devtools/debugger/debugger-controller.js index dcc5044e983e..4a65aa32844d 100644 --- a/browser/devtools/debugger/debugger-controller.js +++ b/browser/devtools/debugger/debugger-controller.js @@ -695,7 +695,10 @@ StackFrames.prototype = { // script dialog and internal events such as setting breakpoints, ignore // the event to avoid UI flicker. case "interrupted": - return; + if (!aPacket.why.onNext) { + return; + } + break; } this.activeThread.fillFrames(CALL_STACK_PAGE_SIZE); diff --git a/browser/devtools/debugger/test/mochitest/browser.ini b/browser/devtools/debugger/test/mochitest/browser.ini index 3c9b62bc059f..99b1bb038945 100644 --- a/browser/devtools/debugger/test/mochitest/browser.ini +++ b/browser/devtools/debugger/test/mochitest/browser.ini @@ -142,6 +142,8 @@ skip-if = e10s || true # bug 1113935 [browser_dbg_blackboxing-06.js] [browser_dbg_breadcrumbs-access.js] [browser_dbg_break-in-anon.js] +[browser_dbg_break-on-next.js] +[browser_dbg_break-on-next-console.js] [browser_dbg_break-on-dom-01.js] [browser_dbg_break-on-dom-02.js] [browser_dbg_break-on-dom-03.js] diff --git a/browser/devtools/debugger/test/mochitest/browser_dbg_break-on-next-console.js b/browser/devtools/debugger/test/mochitest/browser_dbg_break-on-next-console.js new file mode 100644 index 000000000000..ff259780cc2e --- /dev/null +++ b/browser/devtools/debugger/test/mochitest/browser_dbg_break-on-next-console.js @@ -0,0 +1,71 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Test if 'break on next' functionality works from executions + * in content triggered by the console in the toolbox. + */ + +const TAB_URL = EXAMPLE_URL + "doc_script-eval.html"; + +function test() { + let gTab, gPanel, gDebugger; + let gSources, gBreakpoints, gTarget, gResumeButton, gResumeKey, gThreadClient; + + initDebugger(TAB_URL).then(([aTab,, aPanel]) => { + gTab = aTab; + gPanel = aPanel; + gDebugger = gPanel.panelWin; + gSources = gDebugger.DebuggerView.Sources; + gBreakpoints = gDebugger.DebuggerController.Breakpoints; + gTarget = gDebugger.gTarget; + gThreadClient = gDebugger.gThreadClient; + gResumeButton = gDebugger.document.getElementById("resume"); + gResumeKey = gDebugger.document.getElementById("resumeKey"); + + waitForSourceShown(gPanel, "-eval.js") + .then(testConsole) + .then(() => closeDebuggerAndFinish(gPanel)); + }); + + let testConsole = Task.async(function*() { + info("Starting testConsole"); + + let oncePaused = gTarget.once("thread-paused"); + EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger); + let jsterm = yield getSplitConsole(); + let executed = jsterm.execute("1+1"); + yield oncePaused; + + let updatedFrame = yield waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES); + let variables = gDebugger.DebuggerView.Variables; + + is(variables._store.length, 2, "Correct number of scopes available"); + is(variables.getScopeAtIndex(0).name, "With scope [Object]", + "Paused with correct scope (0)"); + is(variables.getScopeAtIndex(1).name, "Global scope [Window]", + "Paused with correct scope (1)"); + + let onceResumed = gTarget.once("thread-resumed"); + EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger); + yield onceResumed; + + yield executed; + }); + + function getSplitConsole() { + return new Promise(resolve => { + let toolbox = gDevTools.getToolbox(gPanel.target); + toolbox.once("webconsole-ready", () => { + ok(toolbox.splitConsole, "Split console is shown."); + let jsterm = toolbox.getPanel("webconsole").hud.jsterm; + resolve(jsterm); + }); + EventUtils.synthesizeKey("VK_ESCAPE", {}, gDebugger); + }); + } +} + +registerCleanupFunction(() => { + Services.prefs.clearUserPref("devtools.toolbox.splitconsoleEnabled"); +}); diff --git a/browser/devtools/debugger/test/mochitest/browser_dbg_break-on-next.js b/browser/devtools/debugger/test/mochitest/browser_dbg_break-on-next.js new file mode 100644 index 000000000000..af7064ee8c62 --- /dev/null +++ b/browser/devtools/debugger/test/mochitest/browser_dbg_break-on-next.js @@ -0,0 +1,93 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Test if 'break on next' functionality works from executions + * in content that are triggered by the page. + */ + +const TAB_URL = EXAMPLE_URL + "doc_script-eval.html"; + +function test() { + let gTab, gPanel, gDebugger; + let gSources, gBreakpoints, gTarget, gResumeButton, gResumeKey, gThreadClient; + + initDebugger(TAB_URL).then(([aTab,, aPanel]) => { + gTab = aTab; + gPanel = aPanel; + gDebugger = gPanel.panelWin; + gSources = gDebugger.DebuggerView.Sources; + gBreakpoints = gDebugger.DebuggerController.Breakpoints; + gTarget = gDebugger.gTarget; + gThreadClient = gDebugger.gThreadClient; + gResumeButton = gDebugger.document.getElementById("resume"); + gResumeKey = gDebugger.document.getElementById("resumeKey"); + + waitForSourceShown(gPanel, "-eval.js") + .then(testInterval) + .then(testEvent) + .then(() => closeDebuggerAndFinish(gPanel)); + }); + + // Testing an interval instead of a timeout / rAF because + // it's less likely to fail due to timing issues. If the + // first callback happens to fire before the break request + // happens then we'll just get it next time. + let testInterval = Task.async(function*() { + info("Starting testInterval"); + + yield evalInTab(gTab, ` + var interval = setInterval(function() { + return 1+1; + }, 100); + `); + + let oncePaused = gTarget.once("thread-paused"); + EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger); + yield oncePaused; + + let updatedFrame = yield waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES); + let variables = gDebugger.DebuggerView.Variables; + + is(variables._store.length, 3, "Correct number of scopes available"); + is(variables.getScopeAtIndex(0).name, "Function scope [interval<]", + "Paused with correct scope (0)"); + is(variables.getScopeAtIndex(1).name, "Block scope", + "Paused with correct scope (1)"); + is(variables.getScopeAtIndex(2).name, "Global scope [Window]", + "Paused with correct scope (2)"); + + yield evalInTab(gTab, "clearInterval(interval)"); + let onceResumed = gTarget.once("thread-resumed"); + EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger); + yield onceResumed; + }); + + let testEvent = Task.async(function*() { + info("Starting testEvent"); + + let oncePaused = gTarget.once("thread-paused"); + EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger); + once(gDebugger.gClient, "willInterrupt").then(() => { + generateMouseClickInTab(gTab, "content.document.querySelector('button')"); + }); + yield oncePaused; + + let updatedFrame = yield waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES); + let variables = gDebugger.DebuggerView.Variables; + + is(variables._store.length, 4, "Correct number of scopes available"); + is(variables.getScopeAtIndex(0).name, "Function scope [onclick]", + "Paused with correct scope (0)"); + is(variables.getScopeAtIndex(1).name, "With scope [HTMLButtonElement]", + "Paused with correct scope (1)"); + is(variables.getScopeAtIndex(2).name, "With scope [HTMLDocument]", + "Paused with correct scope (2)"); + is(variables.getScopeAtIndex(3).name, "Global scope [Window]", + "Paused with correct scope (3)"); + + let onceResumed = gTarget.once("thread-resumed"); + EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger); + yield onceResumed; + }); +} diff --git a/browser/devtools/debugger/test/mochitest/browser_dbg_interrupts.js b/browser/devtools/debugger/test/mochitest/browser_dbg_interrupts.js index aedf876977ae..27e6645d6fe8 100644 --- a/browser/devtools/debugger/test/mochitest/browser_dbg_interrupts.js +++ b/browser/devtools/debugger/test/mochitest/browser_dbg_interrupts.js @@ -55,13 +55,27 @@ function test() { function testResumeButton() { info ("Pressing the resume button, expecting a thread-paused"); + ok (!gResumeButton.hasAttribute("disabled"), "Resume button is not disabled"); + ok (!gResumeButton.hasAttribute("break-on-next"), "Resume button isn't waiting for next execution"); ok (!gResumeButton.hasAttribute("checked"), "Resume button is not checked"); let oncePaused = gTarget.once("thread-paused"); + + // Click the pause button to break on next execution EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger); + ok (gResumeButton.hasAttribute("disabled"), "Resume button is disabled"); + ok (gResumeButton.hasAttribute("break-on-next"), "Resume button is waiting for next execution"); + ok (!gResumeButton.hasAttribute("checked"), "Resume button is not checked"); + + // Evaluate a script to fully pause the debugger + once(gDebugger.gClient, "willInterrupt").then(() => { + evalInTab(gTab, "1+1;"); + }); return oncePaused .then(() => { + ok (!gResumeButton.hasAttribute("break-on-next"), "Resume button isn't waiting for next execution"); is (gResumeButton.getAttribute("checked"), "true", "Resume button is checked"); + ok (!gResumeButton.hasAttribute("disabled"), "Resume button is not disabled"); }) .then(() => gThreadClient.resume()) .then(() => ensureThreadClientState(gPanel, "resumed")) @@ -71,13 +85,27 @@ function test() { let key = gResumeKey.getAttribute("keycode"); info ("Triggering a pause with keyboard (" + key + "), expecting a thread-paused"); + ok (!gResumeButton.hasAttribute("disabled"), "Resume button is not disabled"); + ok (!gResumeButton.hasAttribute("break-on-next"), "Resume button isn't waiting for next execution"); ok (!gResumeButton.hasAttribute("checked"), "Resume button is not checked"); let oncePaused = gTarget.once("thread-paused"); + + // Press the key to break on next execution EventUtils.synthesizeKey(key, { }, gDebugger); + ok (gResumeButton.hasAttribute("disabled"), "Resume button is disabled"); + ok (gResumeButton.hasAttribute("break-on-next"), "Resume button is waiting for next execution"); + ok (!gResumeButton.hasAttribute("checked"), "Resume button is not checked"); + + // Evaluate a script to fully pause the debugger + once(gDebugger.gClient, "willInterrupt").then(() => { + evalInTab(gTab, "1+1;"); + }); return oncePaused .then(() => { + ok (!gResumeButton.hasAttribute("break-on-next"), "Resume button isn't waiting for next execution"); is (gResumeButton.getAttribute("checked"), "true", "Resume button is checked"); + ok (!gResumeButton.hasAttribute("disabled"), "Resume button is not disabled"); }) .then(() => gThreadClient.resume()) .then(() => ensureThreadClientState(gPanel, "resumed")) diff --git a/browser/devtools/debugger/test/mochitest/browser_dbg_on-pause-highlight.js b/browser/devtools/debugger/test/mochitest/browser_dbg_on-pause-highlight.js index d173cacad91f..df7b19cd54f1 100644 --- a/browser/devtools/debugger/test/mochitest/browser_dbg_on-pause-highlight.js +++ b/browser/devtools/debugger/test/mochitest/browser_dbg_on-pause-highlight.js @@ -48,6 +48,11 @@ function testPause() { EventUtils.sendMouseEvent({ type: "mousedown" }, gDebugger.document.getElementById("resume"), gDebugger); + + // Evaluate a script to fully pause the debugger + once(gDebugger.gClient, "willInterrupt").then(() => { + evalInTab(gTab, "1+1;"); + }) } function testResume() { diff --git a/browser/devtools/debugger/test/mochitest/browser_dbg_on-pause-raise.js b/browser/devtools/debugger/test/mochitest/browser_dbg_on-pause-raise.js index c1b758a95361..b84d72d015e3 100644 --- a/browser/devtools/debugger/test/mochitest/browser_dbg_on-pause-raise.js +++ b/browser/devtools/debugger/test/mochitest/browser_dbg_on-pause-raise.js @@ -96,6 +96,11 @@ function testPause() { EventUtils.sendMouseEvent({ type: "mousedown" }, gDebugger.document.getElementById("resume"), gDebugger); + + // Evaluate a script to fully pause the debugger + once(gDebugger.gClient, "willInterrupt").then(() => { + evalInTab(gTab, "1+1;"); + }); } function testResume() { diff --git a/browser/devtools/debugger/test/mochitest/browser_dbg_pause-no-step.js b/browser/devtools/debugger/test/mochitest/browser_dbg_pause-no-step.js index 8324a5d5afc5..919762ad5cb2 100644 --- a/browser/devtools/debugger/test/mochitest/browser_dbg_pause-no-step.js +++ b/browser/devtools/debugger/test/mochitest/browser_dbg_pause-no-step.js @@ -2,17 +2,19 @@ http://creativecommons.org/publicdomain/zero/1.0/ */ /** - * Tests if stepping only is enabled when paused with a location + * Tests that pausing / stepping is only enabled when there is a + * location. */ const TAB_URL = EXAMPLE_URL + "doc_pause-exceptions.html"; -let gPanel, gDebugger; +let gTab, gPanel, gDebugger; let gResumeButton, gStepOverButton, gStepOutButton, gStepInButton; let gResumeKey, gFrames; function test() { initDebugger(TAB_URL).then(([aTab,, aPanel]) => { + gTab = aTab; gPanel = aPanel; gDebugger = gPanel.panelWin; gResumeButton = gDebugger.document.getElementById("resume"); @@ -33,24 +35,33 @@ function testPause() { ok(gStepOverButton.disabled, "Stepping over button should be disabled"); gDebugger.gThreadClient.addOneTimeListener("paused", () => { - // Nothing should happen here because the button is disabled. If - // this runs any code, there will be errors and the test will fail. - EventUtils.sendMouseEvent({ type: "mousedown" }, gStepOverButton, gDebugger); - ok(gDebugger.gThreadClient.paused, "Should be paused after an interrupt request."); - ok(gStepOutButton.disabled, "Stepping out button should still be disabled"); - ok(gStepInButton.disabled, "Stepping in button should still be disabled"); - ok(gStepOverButton.disabled, "Stepping over button should still be disabled"); + ok(!gStepOutButton.disabled, "Stepping out button should be enabled"); + ok(!gStepInButton.disabled, "Stepping in button should be enabled"); + ok(!gStepOverButton.disabled, "Stepping over button should be enabled"); - is(gFrames.itemCount, 0, - "Should have no frames when paused in the main loop."); + waitForDebuggerEvents(gPanel, gDebugger.EVENTS.AFTER_FRAMES_REFILLED).then(() => { + is(gFrames.itemCount, 1, + "Should have 1 frame from the evalInTab call."); + gDebugger.gThreadClient.resume(testBreakAtLocation); + }); - gDebugger.gThreadClient.resume(testBreakAtLocation); }); EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger); + + ok(!gDebugger.gThreadClient.paused, + "Shouldn't be paused until the next script is executed."); + ok(gStepOutButton.disabled, "Stepping out button should be disabled"); + ok(gStepInButton.disabled, "Stepping in button should be disabled"); + ok(gStepOverButton.disabled, "Stepping over button should be disabled"); + + // Evaluate a script to fully pause the debugger + once(gDebugger.gClient, "willInterrupt").then(() => { + evalInTab(gTab, "1+1;"); + }); } function testBreakAtLocation() { diff --git a/browser/devtools/debugger/test/mochitest/browser_dbg_pause-resume.js b/browser/devtools/debugger/test/mochitest/browser_dbg_pause-resume.js index 0fd89867136a..e73a1076d6b3 100644 --- a/browser/devtools/debugger/test/mochitest/browser_dbg_pause-resume.js +++ b/browser/devtools/debugger/test/mochitest/browser_dbg_pause-resume.js @@ -48,6 +48,15 @@ function testPause() { }); EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger); + + is(gResumeButton.getAttribute("tooltiptext"), + gDebugger.L10N.getFormatStr("pausePendingButtonTooltip"), + "Button tooltip should be 'waiting for execution' when breaking on nex."); + + // Evaluate a script to fully pause the debugger + once(gDebugger.gClient, "willInterrupt").then(() => { + evalInTab(gTab, "1+1;"); + }); } function testResume() { diff --git a/browser/devtools/debugger/test/mochitest/browser_dbg_pause-warning.js b/browser/devtools/debugger/test/mochitest/browser_dbg_pause-warning.js index 4da11190040c..4ffa98f1bfe9 100644 --- a/browser/devtools/debugger/test/mochitest/browser_dbg_pause-warning.js +++ b/browser/devtools/debugger/test/mochitest/browser_dbg_pause-warning.js @@ -36,6 +36,11 @@ function testPause() { EventUtils.sendMouseEvent({ type: "mousedown" }, gDebugger.document.getElementById("resume"), gDebugger); + + // Evaluate a script to fully pause the debugger + once(gDebugger.gClient, "willInterrupt").then(() => { + evalInTab(gTab, "1+1;"); + }); } function testNotificationIsUp1() { diff --git a/browser/devtools/debugger/views/toolbar-view.js b/browser/devtools/debugger/views/toolbar-view.js index dd6f61867830..c39c6f53fd81 100644 --- a/browser/devtools/debugger/views/toolbar-view.js +++ b/browser/devtools/debugger/views/toolbar-view.js @@ -51,6 +51,7 @@ ToolbarView.prototype = { let stepOutKey = ShortcutUtils.prettifyShortcut(document.getElementById("stepOutKey")); this._resumeTooltip = L10N.getFormatStr("resumeButtonTooltip", resumeKey); this._pauseTooltip = L10N.getFormatStr("pauseButtonTooltip", resumeKey); + this._pausePendingTooltip = L10N.getStr("pausePendingButtonTooltip"); this._stepOverTooltip = L10N.getFormatStr("stepOverTooltip", stepOverKey); this._stepInTooltip = L10N.getFormatStr("stepInTooltip", stepInKey); this._stepOutTooltip = L10N.getFormatStr("stepOutTooltip", stepOutKey); @@ -112,11 +113,23 @@ ToolbarView.prototype = { * Sets the resume button state based on the debugger active thread. * * @param string aState - * Either "paused" or "attached". + * Either "paused", "attached", or "breakOnNext". * @param boolean hasLocation * True if we are paused at a specific JS location */ toggleResumeButtonState: function(aState, hasLocation) { + // Intermidiate state after pressing the pause button and waiting + // for the next script execution to happen. + if (aState == "breakOnNext") { + this._resumeButton.setAttribute("break-on-next", "true"); + this._resumeButton.disabled = true; + this._resumeButton.setAttribute("tooltiptext", this._pausePendingTooltip); + return; + } + + this._resumeButton.removeAttribute("break-on-next"); + this._resumeButton.disabled = false; + // If we're paused, check and show a resume label on the button. if (aState == "paused") { this._resumeButton.setAttribute("checked", "true"); @@ -135,7 +148,7 @@ ToolbarView.prototype = { this._resumeButton.removeAttribute("checked"); this._resumeButton.setAttribute("tooltiptext", this._pauseTooltip); this._toggleButtonsState({ enabled: false }); - } + } }, _toggleButtonsState: function({ enabled }) { @@ -146,7 +159,7 @@ ToolbarView.prototype = { ]; for (let button of buttons) { button.disabled = !enabled; - }; + } }, /** @@ -164,7 +177,8 @@ ToolbarView.prototype = { * Listener handling the pause/resume button click event. */ _onResumePressed: function() { - if (this.StackFrames._currentFrameDescription != FRAME_TYPE.NORMAL) { + if (this.StackFrames._currentFrameDescription != FRAME_TYPE.NORMAL || + this._resumeButton.disabled) { return; } @@ -173,7 +187,8 @@ ToolbarView.prototype = { this.activeThread.resume(this.resumptionWarnFunc); } else { this.ThreadState.interruptedByResumeButton = true; - this.activeThread.interrupt(); + this.toggleResumeButtonState("breakOnNext"); + this.activeThread.breakOnNext(); } }, diff --git a/browser/devtools/framework/gDevTools.jsm b/browser/devtools/framework/gDevTools.jsm index 99dd6e3f19de..a264d9f68d8f 100644 --- a/browser/devtools/framework/gDevTools.jsm +++ b/browser/devtools/framework/gDevTools.jsm @@ -883,13 +883,13 @@ let gDevToolsBrowser = { switch (threadClient.state) { case "paused": // When the debugger is already paused. - threadClient.breakOnNext(); + threadClient.resumeThenPause(); aCallback(); break; case "attached": // When the debugger is already open. threadClient.interrupt(() => { - threadClient.breakOnNext(); + threadClient.resumeThenPause(); aCallback(); }); break; @@ -897,7 +897,7 @@ let gDevToolsBrowser = { // The debugger is newly opened. threadClient.addOneTimeListener("resumed", () => { threadClient.interrupt(() => { - threadClient.breakOnNext(); + threadClient.resumeThenPause(); aCallback(); }); }); diff --git a/browser/locales/en-US/chrome/browser/devtools/debugger.properties b/browser/locales/en-US/chrome/browser/devtools/debugger.properties index 386645a4b3c5..d4173628842f 100644 --- a/browser/locales/en-US/chrome/browser/devtools/debugger.properties +++ b/browser/locales/en-US/chrome/browser/devtools/debugger.properties @@ -46,11 +46,15 @@ collapsePanes=Collapse panes # that expands the left and right panes in the debugger UI. expandPanes=Expand panes -# LOCALIZATION NOTE (pauseLabel): The label that is displayed on the pause +# LOCALIZATION NOTE (pauseButtonTooltip): The tooltip that is displayed for the pause # button when the debugger is in a running state. pauseButtonTooltip=Click to pause (%S) -# LOCALIZATION NOTE (resumeLabel): The label that is displayed on the pause +# LOCALIZATION NOTE (pausePendingButtonTooltip): The tooltip that is displayed for +# the pause button after it's been clicked but before the next JavaScript to run. +pausePendingButtonTooltip=Waiting for next execution + +# LOCALIZATION NOTE (resumeButtonTooltip): The label that is displayed on the pause # button when the debugger is in a paused state. resumeButtonTooltip=Click to resume (%S) diff --git a/browser/themes/shared/devtools/debugger.css b/browser/themes/shared/devtools/debugger.css index d79576337518..e16cdb85bbeb 100644 --- a/browser/themes/shared/devtools/debugger.css +++ b/browser/themes/shared/devtools/debugger.css @@ -581,7 +581,12 @@ } #debugger-controls toolbarbutton[disabled] { - opacity: .5; + opacity: .5; + transition: none; +} + +#resume[break-on-next] { + background: var(--theme-highlight-lightorange); } #step-over { diff --git a/toolkit/devtools/client/main.js b/toolkit/devtools/client/main.js index 7df6ea6071c4..5a9a156f4267 100644 --- a/toolkit/devtools/client/main.js +++ b/toolkit/devtools/client/main.js @@ -1661,7 +1661,7 @@ ThreadClient.prototype = { * @param function aOnResponse * Called with the response packet. */ - breakOnNext: function (aOnResponse) { + resumeThenPause: function (aOnResponse) { this._doResume({ type: "break" }, aOnResponse); }, @@ -1695,14 +1695,35 @@ ThreadClient.prototype = { this._doResume({ type: "finish" }, aOnResponse); }, + /** + * Immediately interrupt a running thread. + * + * @param function aOnResponse + * Called with the response packet. + */ + interrupt: function(aOnResponse) { + this._doInterrupt(null, aOnResponse); + }, + + /** + * Pause execution right before the next JavaScript bytecode is executed. + * + * @param function aOnResponse + * Called with the response packet. + */ + breakOnNext: function(aOnResponse) { + this._doInterrupt("onNext", aOnResponse); + }, + /** * Interrupt a running thread. * * @param function aOnResponse * Called with the response packet. */ - interrupt: DebuggerClient.requester({ - type: "interrupt" + _doInterrupt: DebuggerClient.requester({ + type: "interrupt", + when: args(0) }, { telemetry: "INTERRUPT" }), diff --git a/toolkit/devtools/server/actors/script.js b/toolkit/devtools/server/actors/script.js index f4ce487a4693..cb381d354b59 100644 --- a/toolkit/devtools/server/actors/script.js +++ b/toolkit/devtools/server/actors/script.js @@ -1375,7 +1375,19 @@ ThreadActor.prototype = { } try { - // Put ourselves in the paused state. + // If execution should pause just before the next JavaScript bytecode is + // executed, just set an onEnterFrame handler. + if (aRequest.when == "onNext") { + let onEnterFrame = (aFrame) => { + return this._pauseAndRespond(aFrame, { type: "interrupted", onNext: true }); + }; + this.dbg.onEnterFrame = onEnterFrame; + + return { type: "willInterrupt" }; + } + + // If execution should pause immediately, just put ourselves in the paused + // state. let packet = this._paused(); if (!packet) { return { error: "notInterrupted" }; From daaa0935bbe99a2b52f4d19d9bb017a51c014a55 Mon Sep 17 00:00:00 2001 From: Jared Wein Date: Wed, 2 Sep 2015 12:12:10 -0400 Subject: [PATCH 02/27] Bug 1197722 - Respect Win10 pref about bringing up the touch keyboard outside of tablet mode. r=masayuki --HG-- extra : rebase_source : 9b8172ded24f0054c714a6626dfb7f2eb3e2e3c9 --- widget/windows/WinIMEHandler.cpp | 68 +++++++++++++++++++++++++------- widget/windows/WinIMEHandler.h | 2 + 2 files changed, 55 insertions(+), 15 deletions(-) diff --git a/widget/windows/WinIMEHandler.cpp b/widget/windows/WinIMEHandler.cpp index 82a4b8025836..8776b49d1ae7 100644 --- a/widget/windows/WinIMEHandler.cpp +++ b/widget/windows/WinIMEHandler.cpp @@ -16,6 +16,7 @@ #include "nsLookAndFeel.h" #include "nsWindow.h" #include "WinUtils.h" +#include "nsIWindowsRegKey.h" #include "nsIWindowsUIUtils.h" #include "shellapi.h" @@ -535,21 +536,15 @@ IMEHandler::MaybeShowOnScreenKeyboard() return; } - if (Preferences::GetBool(kOskRequireTabletMode, true)) { - // Tablet Mode is only supported on Windows 10 and higher. - // When touch-event detection within IME is better supported - // this check may be removed, and ShowOnScreenKeyboard can - // run on Windows 8 and higher (adjusting the IsWin10OrLater - // guard above and within MaybeDismissOnScreenKeyboard). - nsCOMPtr - uiUtils(do_GetService("@mozilla.org/windows-ui-utils;1")); - if (uiUtils) { - bool isInTabletMode = false; - uiUtils->GetInTabletMode(&isInTabletMode); - if (!isInTabletMode) { - return; - } - } + // Tablet Mode is only supported on Windows 10 and higher. + // When touch-event detection within IME is better supported + // this check may be removed, and ShowOnScreenKeyboard can + // run on Windows 8 and higher (adjusting the IsWin10OrLater + // guard above and within MaybeDismissOnScreenKeyboard). + if (!IsInTabletMode() && + Preferences::GetBool(kOskRequireTabletMode, true) && + !AutoInvokeOnScreenKeyboardInDesktopMode()) { + return; } IMEHandler::ShowOnScreenKeyboard(); @@ -708,6 +703,49 @@ IMEHandler::IsKeyboardPresentOnSlate() return false; } +// static +bool +IMEHandler::IsInTabletMode() +{ + nsCOMPtr + uiUtils(do_GetService("@mozilla.org/windows-ui-utils;1")); + if (NS_WARN_IF(!uiUtils)) { + return false; + } + bool isInTabletMode = false; + uiUtils->GetInTabletMode(&isInTabletMode); + return isInTabletMode; +} + +// static +bool +IMEHandler::AutoInvokeOnScreenKeyboardInDesktopMode() +{ + nsresult rv; + nsCOMPtr regKey + (do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return false; + } + rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER, + NS_LITERAL_STRING("SOFTWARE\\Microsoft\\TabletTip\\1.7"), + nsIWindowsRegKey::ACCESS_QUERY_VALUE); + if (NS_FAILED(rv)) { + return false; + } + // EnableDesktopModeAutoInvoke is an opt-in option from the Windows + // Settings to "Automatically show the touch keyboard in windowed apps + // when there's no keyboard attached to your device." If the user has + // opted-in to this behavior, the tablet-mode requirement is skipped. + uint32_t value; + rv = regKey->ReadIntValue(NS_LITERAL_STRING("EnableDesktopModeAutoInvoke"), + &value); + if (NS_FAILED(rv)) { + return false; + } + return !!value; +} + // Based on DisplayVirtualKeyboard() in Chromium's base/win/win_util.cc. // static void diff --git a/widget/windows/WinIMEHandler.h b/widget/windows/WinIMEHandler.h index 3f0199e3da61..0b434928f3db 100644 --- a/widget/windows/WinIMEHandler.h +++ b/widget/windows/WinIMEHandler.h @@ -130,6 +130,8 @@ private: static bool WStringStartsWithCaseInsensitive(const std::wstring& aHaystack, const std::wstring& aNeedle); static bool IsKeyboardPresentOnSlate(); + static bool IsInTabletMode(); + static bool AutoInvokeOnScreenKeyboardInDesktopMode(); /** * Show the Windows on-screen keyboard. Only allowed for From 70099b93ec6e6e7dbc80902e385a0e1318b404f1 Mon Sep 17 00:00:00 2001 From: Jared Wein Date: Wed, 2 Sep 2015 12:12:55 -0400 Subject: [PATCH 03/27] Bug 1140495 - Remove support for windowed preferences. r=ttaubert --HG-- extra : rebase_source : 2b29244f4813593171b436f551735dfcc13d6474 --- addon-sdk/source/test/test-ui-sidebar.js | 2 +- browser/app/profile/firefox.js | 3 - .../content/test/general/browser_aboutHome.js | 33 +- .../content/test/general/browser_bug735471.js | 36 +- .../browser_datachoices_notification.js | 5 - .../browser_datareporting_notification.js | 5 - .../browser_offlineQuotaNotification.js | 47 +- browser/base/content/utilityOverlay.js | 103 +- .../browser_1087303_button_preferences.js | 7 - browser/components/nsBrowserContentHandler.js | 39 +- browser/components/preferences/advanced.js | 823 ------- browser/components/preferences/advanced.xul | 397 ---- .../preferences/applicationManager.js | 2 - .../preferences/applicationManager.xul | 2 +- .../components/preferences/applications.js | 1911 ----------------- .../components/preferences/applications.xul | 99 - browser/components/preferences/content.js | 209 -- browser/components/preferences/content.xul | 185 -- .../tests/browser_basic_rebuild_fonts_test.js | 2 - .../browser_bug1018066_resetScrollPosition.js | 3 - ...g1020245_openPreferences_to_paneContent.js | 2 - .../in-content/tests/browser_bug410900.js | 2 - .../tests/browser_change_app_handler.js | 3 - .../browser_sanitizeOnShutdown_prefLocked.js | 2 - browser/components/preferences/jar.mn | 22 - browser/components/preferences/main.js | 544 ----- browser/components/preferences/main.xul | 186 -- browser/components/preferences/moz.build | 1 - browser/components/preferences/preferences.js | 19 - .../components/preferences/preferences.xul | 94 - browser/components/preferences/privacy.js | 512 ----- browser/components/preferences/privacy.xul | 292 --- browser/components/preferences/search.js | 544 ----- browser/components/preferences/search.xul | 93 - browser/components/preferences/security.js | 227 -- browser/components/preferences/security.xul | 113 - browser/components/preferences/sync.js | 513 ----- browser/components/preferences/sync.xul | 330 --- browser/components/preferences/tabs.js | 75 - browser/components/preferences/tabs.xul | 64 - .../components/preferences/tests/browser.ini | 25 - .../tests/browser_advanced_update.js | 36 - .../preferences/tests/browser_bug410900.js | 51 - .../preferences/tests/browser_bug705422.js | 143 -- .../tests/browser_chunk_permissions.js | 137 -- .../tests/browser_connection_bug388287.js | 160 -- .../tests/browser_cookies_exceptions.js | 311 --- .../preferences/tests/browser_healthreport.js | 94 - .../preferences/tests/browser_permissions.js | 331 --- .../tests/browser_privacypane_1.js | 24 - .../tests/browser_privacypane_3.js | 23 - .../tests/browser_privacypane_4.js | 32 - .../tests/browser_privacypane_5.js | 27 - .../tests/browser_privacypane_8.js | 32 - .../preferences/tests/browser_telemetry.js | 68 - browser/components/preferences/tests/head.js | 4 - .../tests/privacypane_tests_perwindow.js | 363 ---- 57 files changed, 73 insertions(+), 9339 deletions(-) delete mode 100644 browser/components/preferences/advanced.js delete mode 100644 browser/components/preferences/advanced.xul delete mode 100644 browser/components/preferences/applications.js delete mode 100644 browser/components/preferences/applications.xul delete mode 100644 browser/components/preferences/content.js delete mode 100644 browser/components/preferences/content.xul delete mode 100644 browser/components/preferences/main.js delete mode 100644 browser/components/preferences/main.xul delete mode 100644 browser/components/preferences/preferences.js delete mode 100644 browser/components/preferences/preferences.xul delete mode 100644 browser/components/preferences/privacy.js delete mode 100644 browser/components/preferences/privacy.xul delete mode 100644 browser/components/preferences/search.js delete mode 100644 browser/components/preferences/search.xul delete mode 100644 browser/components/preferences/security.js delete mode 100644 browser/components/preferences/security.xul delete mode 100644 browser/components/preferences/sync.js delete mode 100644 browser/components/preferences/sync.xul delete mode 100644 browser/components/preferences/tabs.js delete mode 100644 browser/components/preferences/tabs.xul delete mode 100644 browser/components/preferences/tests/browser.ini delete mode 100644 browser/components/preferences/tests/browser_advanced_update.js delete mode 100644 browser/components/preferences/tests/browser_bug410900.js delete mode 100644 browser/components/preferences/tests/browser_bug705422.js delete mode 100644 browser/components/preferences/tests/browser_chunk_permissions.js delete mode 100644 browser/components/preferences/tests/browser_connection_bug388287.js delete mode 100644 browser/components/preferences/tests/browser_cookies_exceptions.js delete mode 100644 browser/components/preferences/tests/browser_healthreport.js delete mode 100644 browser/components/preferences/tests/browser_permissions.js delete mode 100644 browser/components/preferences/tests/browser_privacypane_1.js delete mode 100644 browser/components/preferences/tests/browser_privacypane_3.js delete mode 100644 browser/components/preferences/tests/browser_privacypane_4.js delete mode 100644 browser/components/preferences/tests/browser_privacypane_5.js delete mode 100644 browser/components/preferences/tests/browser_privacypane_8.js delete mode 100644 browser/components/preferences/tests/browser_telemetry.js delete mode 100644 browser/components/preferences/tests/head.js delete mode 100644 browser/components/preferences/tests/privacypane_tests_perwindow.js diff --git a/addon-sdk/source/test/test-ui-sidebar.js b/addon-sdk/source/test/test-ui-sidebar.js index 2302d40d9028..916a43e0b08d 100644 --- a/addon-sdk/source/test/test-ui-sidebar.js +++ b/addon-sdk/source/test/test-ui-sidebar.js @@ -1300,7 +1300,7 @@ exports.testDestroyWhileNonBrowserWindowIsOpen = function*(assert) { url: url }); - let window = yield open('chrome://browser/content/preferences/preferences.xul'); + let window = yield open('chrome://browser/content/aboutDialog.xul'); yield sidebar.show(); assert.equal(isSidebarShowing(getMostRecentBrowserWindow()), true, 'the sidebar is showing'); diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index 353130006e86..b9ab86822738 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -855,9 +855,6 @@ pref("browser.preferences.instantApply", false); pref("browser.preferences.instantApply", true); #endif -// Toggles between the two Preferences implementations, pop-up window and in-content -pref("browser.preferences.inContent", true); - pref("browser.download.show_plugins_in_list", true); pref("browser.download.hide_plugins_without_extensions", true); diff --git a/browser/base/content/test/general/browser_aboutHome.js b/browser/base/content/test/general/browser_aboutHome.js index 7f6addd4aaaf..535a453eafff 100644 --- a/browser/base/content/test/general/browser_aboutHome.js +++ b/browser/base/content/test/general/browser_aboutHome.js @@ -619,33 +619,12 @@ function promiseWaitForEvent(node, type, capturing) { } let promisePrefsOpen = Task.async(function*() { - if (Services.prefs.getBoolPref("browser.preferences.inContent")) { - info("Waiting for the preferences tab to open..."); - let event = yield promiseWaitForEvent(gBrowser.tabContainer, "TabOpen", true); - let tab = event.target; - yield promiseTabLoadEvent(tab); - is(tab.linkedBrowser.currentURI.spec, "about:preferences#search", "Should have seen the prefs tab"); - gBrowser.removeTab(tab); - } else { - info("Waiting for the preferences window to open..."); - yield new Promise(resolve => { - let winWatcher = Cc["@mozilla.org/embedcomp/window-watcher;1"]. - getService(Ci.nsIWindowWatcher); - winWatcher.registerNotification(function onWin(subj, topic, data) { - if (topic == "domwindowopened" && subj instanceof Ci.nsIDOMWindow) { - subj.addEventListener("load", function onLoad() { - subj.removeEventListener("load", onLoad); - is(subj.document.documentURI, "chrome://browser/content/preferences/preferences.xul", "Should have seen the prefs window"); - winWatcher.unregisterNotification(onWin); - executeSoon(() => { - subj.close(); - resolve(); - }); - }); - } - }); - }); - } + info("Waiting for the preferences tab to open..."); + let event = yield promiseWaitForEvent(gBrowser.tabContainer, "TabOpen", true); + let tab = event.target; + yield promiseTabLoadEvent(tab); + is(tab.linkedBrowser.currentURI.spec, "about:preferences#search", "Should have seen the prefs tab"); + gBrowser.removeTab(tab); }); function promiseContentSearchChange(newEngineName) { diff --git a/browser/base/content/test/general/browser_bug735471.js b/browser/base/content/test/general/browser_bug735471.js index beb33802fa88..9afb52c4b06b 100644 --- a/browser/base/content/test/general/browser_bug735471.js +++ b/browser/base/content/test/general/browser_bug735471.js @@ -7,49 +7,17 @@ function test() { waitForExplicitFinish(); - registerCleanupFunction(function() { - // Reset pref to its default - Services.prefs.clearUserPref("browser.preferences.inContent"); - }); - - // Verify that about:preferences tab is displayed when - // browser.preferences.inContent is set to true - Services.prefs.setBoolPref("browser.preferences.inContent", true); - // Open a new tab. whenNewTabLoaded(window, testPreferences); } function testPreferences() { whenTabLoaded(gBrowser.selectedTab, function () { - is(Services.prefs.getBoolPref("browser.preferences.inContent"), true, "In-content prefs are enabled"); is(content.location.href, "about:preferences", "Checking if the preferences tab was opened"); gBrowser.removeCurrentTab(); - Services.prefs.setBoolPref("browser.preferences.inContent", false); - openPreferences(); + finish(); }); - - let observer = { - observe: function(aSubject, aTopic, aData) { - if (aTopic == "domwindowopened") { - windowWatcher.unregisterNotification(observer); - - let win = aSubject.QueryInterface(Components.interfaces.nsIDOMWindow); - win.addEventListener("load", function() { - win.removeEventListener("load", arguments.callee, false); - is(Services.prefs.getBoolPref("browser.preferences.inContent"), false, "In-content prefs are disabled"); - is(win.location.href, "chrome://browser/content/preferences/preferences.xul", "Checking if the preferences window was opened"); - win.close(); - finish(); - }, false); - } - } - } - - var windowWatcher = Components.classes["@mozilla.org/embedcomp/window-watcher;1"] - .getService(Components.interfaces.nsIWindowWatcher); - windowWatcher.registerNotification(observer); - + openPreferences(); } diff --git a/browser/base/content/test/general/browser_datachoices_notification.js b/browser/base/content/test/general/browser_datachoices_notification.js index 804d1c66c73f..326294ecb629 100644 --- a/browser/base/content/test/general/browser_datachoices_notification.js +++ b/browser/base/content/test/general/browser_datachoices_notification.js @@ -100,11 +100,6 @@ let checkInfobarButton = Task.async(function* (aNotification) { // Wait for the preferences panel to open. let preferenceWindow = yield paneLoadedPromise; yield promiseNextTick(); - // If the prefs are being displayed in a dialog we need to close it. - // If in a tab (ie, in-content prefs) it closes with the window. - if (!Services.prefs.getBoolPref("browser.preferences.inContent")) { - prefWin.close(); - } }); add_task(function* setup(){ diff --git a/browser/base/content/test/general/browser_datareporting_notification.js b/browser/base/content/test/general/browser_datareporting_notification.js index 85861d70568f..f5d935855c4e 100644 --- a/browser/base/content/test/general/browser_datareporting_notification.js +++ b/browser/base/content/test/general/browser_datareporting_notification.js @@ -177,11 +177,6 @@ function test_multiple_windows() { ok(true, "Advanced preferences opened on info bar button press."); executeSoon(function soon() { prefWindowOpened = true; - // If the prefs are being displayed in a dialog we need to close it. - // If in a tab (ie, in-content prefs) it closes with the window. - if (!Services.prefs.getBoolPref("browser.preferences.inContent")) { - prefWin.close(); - } maybeFinish(); }); }, "advanced-pane-loaded", false); diff --git a/browser/base/content/test/general/browser_offlineQuotaNotification.js b/browser/base/content/test/general/browser_offlineQuotaNotification.js index 6a53675b2869..3424b4675b7e 100644 --- a/browser/base/content/test/general/browser_offlineQuotaNotification.js +++ b/browser/base/content/test/general/browser_offlineQuotaNotification.js @@ -17,25 +17,6 @@ registerCleanupFunction(function() { Services.prefs.clearUserPref("offline-apps.allow_by_default"); }); -// Check that the "preferences" UI is opened and showing which websites have -// offline storage permissions - currently this is the "network" tab in the -// "advanced" pane. -function checkPreferences(prefsWin) { - // We expect a 'paneload' event for the 'advanced' pane, then - // a 'select' event on the 'network' tab inside that pane. - prefsWin.addEventListener("paneload", function paneload(evt) { - prefsWin.removeEventListener("paneload", paneload); - is(evt.target.id, "paneAdvanced", "advanced pane loaded"); - let tabPanels = evt.target.getElementsByTagName("tabpanels")[0]; - tabPanels.addEventListener("select", function tabselect() { - tabPanels.removeEventListener("select", tabselect); - is(tabPanels.selectedPanel.id, "networkPanel", "networkPanel is selected"); - // all good, we are done. - prefsWin.close(); - finish(); - }); - }); -} // Same as the other one, but for in-content preferences function checkInContentPreferences(win) { let doc = win.document; @@ -71,27 +52,15 @@ function test() { let notification = PopupNotifications.getNotification('offline-app-usage'); ok(notification, "have offline-app-usage notification"); // select the default action - this should cause the preferences - // window to open - which we track either via a window watcher (for - // the window-based prefs) or via an "Initialized" event (for - // in-content prefs.) - if (!Services.prefs.getBoolPref("browser.preferences.inContent")) { - Services.ww.registerNotification(function wwobserver(aSubject, aTopic, aData) { - if (aTopic != "domwindowopened") - return; - Services.ww.unregisterNotification(wwobserver); - checkPreferences(aSubject); - }); - } + // tab to open - which we track via an "Initialized" event. PopupNotifications.panel.firstElementChild.button.click(); - if (Services.prefs.getBoolPref("browser.preferences.inContent")) { - let newTabBrowser = gBrowser.getBrowserForTab(gBrowser.selectedTab); - newTabBrowser.addEventListener("Initialized", function PrefInit() { - newTabBrowser.removeEventListener("Initialized", PrefInit, true); - executeSoon(function() { - checkInContentPreferences(newTabBrowser.contentWindow); - }) - }, true); - } + let newTabBrowser = gBrowser.getBrowserForTab(gBrowser.selectedTab); + newTabBrowser.addEventListener("Initialized", function PrefInit() { + newTabBrowser.removeEventListener("Initialized", PrefInit, true); + executeSoon(function() { + checkInContentPreferences(newTabBrowser.contentWindow); + }) + }, true); }); }; Services.prefs.setIntPref("offline-apps.quota.warn", 1); diff --git a/browser/base/content/utilityOverlay.js b/browser/base/content/utilityOverlay.js index 8ec5c9dde38a..c841266c0e93 100644 --- a/browser/base/content/utilityOverlay.js +++ b/browser/base/content/utilityOverlay.js @@ -529,74 +529,55 @@ function openPreferences(paneID, extraArgs) return (aName || "").replace(/^pane./, function(toReplace) { return toReplace[4].toLowerCase(); }); } - if (getBoolPref("browser.preferences.inContent")) { - let win = Services.wm.getMostRecentWindow("navigator:browser"); - let friendlyCategoryName = internalPrefCategoryNameToFriendlyName(paneID); - let params; - if (extraArgs && extraArgs["urlParams"]) { - params = new URLSearchParams(); - let urlParams = extraArgs["urlParams"]; - for (let name in urlParams) { - if (urlParams[name] !== undefined) { - params.set(name, urlParams[name]); - } + let win = Services.wm.getMostRecentWindow("navigator:browser"); + let friendlyCategoryName = internalPrefCategoryNameToFriendlyName(paneID); + let params; + if (extraArgs && extraArgs["urlParams"]) { + params = new URLSearchParams(); + let urlParams = extraArgs["urlParams"]; + for (let name in urlParams) { + if (urlParams[name] !== undefined) { + params.set(name, urlParams[name]); } } - let preferencesURL = "about:preferences" + (params ? "?" + params : "") + - (friendlyCategoryName ? "#" + friendlyCategoryName : ""); - let newLoad = true; - let browser = null; - if (!win) { - const Cc = Components.classes; - const Ci = Components.interfaces; - let windowArguments = Cc["@mozilla.org/supports-array;1"] - .createInstance(Ci.nsISupportsArray); - let supportsStringPrefURL = Cc["@mozilla.org/supports-string;1"] - .createInstance(Ci.nsISupportsString); - supportsStringPrefURL.data = preferencesURL; - windowArguments.AppendElement(supportsStringPrefURL); + } + let preferencesURL = "about:preferences" + (params ? "?" + params : "") + + (friendlyCategoryName ? "#" + friendlyCategoryName : ""); + let newLoad = true; + let browser = null; + if (!win) { + const Cc = Components.classes; + const Ci = Components.interfaces; + let windowArguments = Cc["@mozilla.org/supports-array;1"] + .createInstance(Ci.nsISupportsArray); + let supportsStringPrefURL = Cc["@mozilla.org/supports-string;1"] + .createInstance(Ci.nsISupportsString); + supportsStringPrefURL.data = preferencesURL; + windowArguments.AppendElement(supportsStringPrefURL); - win = Services.ww.openWindow(null, Services.prefs.getCharPref("browser.chromeURL"), - "_blank", "chrome,dialog=no,all", windowArguments); - } else { - newLoad = !win.switchToTabHavingURI(preferencesURL, true, {ignoreFragment: true}); - browser = win.gBrowser.selectedBrowser; - } - - if (newLoad) { - Services.obs.addObserver(function advancedPaneLoadedObs(prefWin, topic, data) { - if (!browser) { - browser = win.gBrowser.selectedBrowser; - } - if (prefWin != browser.contentWindow) { - return; - } - Services.obs.removeObserver(advancedPaneLoadedObs, "advanced-pane-loaded"); - switchToAdvancedSubPane(browser.contentDocument); - }, "advanced-pane-loaded", false); - } else { - if (paneID) { - browser.contentWindow.gotoPref(paneID); - } - switchToAdvancedSubPane(browser.contentDocument); - } + win = Services.ww.openWindow(null, Services.prefs.getCharPref("browser.chromeURL"), + "_blank", "chrome,dialog=no,all", windowArguments); } else { - var instantApply = getBoolPref("browser.preferences.instantApply", false); - var features = "chrome,titlebar,toolbar,centerscreen" + (instantApply ? ",dialog=no" : ",modal"); + newLoad = !win.switchToTabHavingURI(preferencesURL, true, {ignoreFragment: true}); + browser = win.gBrowser.selectedBrowser; + } - var win = Services.wm.getMostRecentWindow("Browser:Preferences"); - if (win) { - win.focus(); - if (paneID) { - var pane = win.document.getElementById(paneID); - win.document.documentElement.showPane(pane); + if (newLoad) { + Services.obs.addObserver(function advancedPaneLoadedObs(prefWin, topic, data) { + if (!browser) { + browser = win.gBrowser.selectedBrowser; } - - switchToAdvancedSubPane(win.document); - } else { - openDialog("chrome://browser/content/preferences/preferences.xul", - "Preferences", features, paneID, extraArgs); + if (prefWin != browser.contentWindow) { + return; + } + Services.obs.removeObserver(advancedPaneLoadedObs, "advanced-pane-loaded"); + switchToAdvancedSubPane(browser.contentDocument); + }, "advanced-pane-loaded", false); + } else { + if (paneID) { + browser.contentWindow.gotoPref(paneID); } + switchToAdvancedSubPane(browser.contentDocument); } } diff --git a/browser/components/customizableui/test/browser_1087303_button_preferences.js b/browser/components/customizableui/test/browser_1087303_button_preferences.js index 9c6f702461e7..f5679b8945e8 100644 --- a/browser/components/customizableui/test/browser_1087303_button_preferences.js +++ b/browser/components/customizableui/test/browser_1087303_button_preferences.js @@ -4,15 +4,11 @@ "use strict"; -const PREF_INCONTENT = "browser.preferences.inContent"; - let newTab = null; add_task(function() { info("Check preferences button existence and functionality"); - Services.prefs.setBoolPref(PREF_INCONTENT, true); - yield PanelUI.show(); info("Menu panel was opened"); @@ -33,9 +29,6 @@ add_task(function asyncCleanup() { gBrowser.removeTab(gBrowser.selectedTab); info("Tabs were restored"); - - // restore the browser.preferences.inContent preference - Services.prefs.clearUserPref(PREF_INCONTENT); }); function waitForPageLoad(aTab) { diff --git a/browser/components/nsBrowserContentHandler.js b/browser/components/nsBrowserContentHandler.js index 1f80bf55f7d0..d583f3c292e6 100644 --- a/browser/components/nsBrowserContentHandler.js +++ b/browser/components/nsBrowserContentHandler.js @@ -231,34 +231,22 @@ function openWindow(parent, url, target, features, args, noExternalArgs) { } function openPreferences() { - if (Services.prefs.getBoolPref("browser.preferences.inContent")) { - var sa = Components.classes["@mozilla.org/supports-array;1"] - .createInstance(Components.interfaces.nsISupportsArray); + var sa = Components.classes["@mozilla.org/supports-array;1"] + .createInstance(Components.interfaces.nsISupportsArray); - var wuri = Components.classes["@mozilla.org/supports-string;1"] - .createInstance(Components.interfaces.nsISupportsString); - wuri.data = "about:preferences"; + var wuri = Components.classes["@mozilla.org/supports-string;1"] + .createInstance(Components.interfaces.nsISupportsString); + wuri.data = "about:preferences"; - sa.AppendElement(wuri); + sa.AppendElement(wuri); - var wwatch = Components.classes["@mozilla.org/embedcomp/window-watcher;1"] - .getService(nsIWindowWatcher); + var wwatch = Components.classes["@mozilla.org/embedcomp/window-watcher;1"] + .getService(nsIWindowWatcher); - wwatch.openWindow(null, gBrowserContentHandler.chromeURL, - "_blank", - "chrome,dialog=no,all", - sa); - } else { - var features = "chrome,titlebar,toolbar,centerscreen,dialog=no"; - var url = "chrome://browser/content/preferences/preferences.xul"; - - var win = getMostRecentWindow("Browser:Preferences"); - if (win) { - win.focus(); - } else { - openWindow(null, url, "_blank", features); - } - } + wwatch.openWindow(null, gBrowserContentHandler.chromeURL, + "_blank", + "chrome,dialog=no,all", + sa); } function getMostRecentWindow(aType) { @@ -396,8 +384,7 @@ nsBrowserContentHandler.prototype = { // Handle old preference dialog URLs. if (chromeParam == "chrome://browser/content/pref/pref.xul" || - (Services.prefs.getBoolPref("browser.preferences.inContent") && - chromeParam == "chrome://browser/content/preferences/preferences.xul")) { + chromeParam == "chrome://browser/content/preferences/preferences.xul") { openPreferences(); cmdLine.preventDefault = true; } else try { diff --git a/browser/components/preferences/advanced.js b/browser/components/preferences/advanced.js deleted file mode 100644 index a1210971da37..000000000000 --- a/browser/components/preferences/advanced.js +++ /dev/null @@ -1,823 +0,0 @@ -# -*- indent-tabs-mode: nil; js-indent-level: 4 -*- -# 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/. - -// Load DownloadUtils module for convertByteUnits -Components.utils.import("resource://gre/modules/DownloadUtils.jsm"); -Components.utils.import("resource://gre/modules/ctypes.jsm"); -Components.utils.import("resource://gre/modules/Services.jsm"); -Components.utils.import("resource://gre/modules/LoadContextInfo.jsm"); -Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); -Components.utils.import("resource://gre/modules/BrowserUtils.jsm"); - -var gAdvancedPane = { - _inited: false, - - /** - * Brings the appropriate tab to the front and initializes various bits of UI. - */ - init: function () - { - this._inited = true; - var advancedPrefs = document.getElementById("advancedPrefs"); - - var extraArgs = window.arguments[1]; - if (extraArgs && extraArgs["advancedTab"]){ - advancedPrefs.selectedTab = document.getElementById(extraArgs["advancedTab"]); - } else { - var preference = document.getElementById("browser.preferences.advanced.selectedTabIndex"); - if (preference.value !== null) - advancedPrefs.selectedIndex = preference.value; - } - -#ifdef MOZ_UPDATER - let onUnload = function () { - window.removeEventListener("unload", onUnload, false); - Services.prefs.removeObserver("app.update.", this); - }.bind(this); - window.addEventListener("unload", onUnload, false); - Services.prefs.addObserver("app.update.", this, false); - this.updateReadPrefs(); -#endif - this.updateOfflineApps(); -#ifdef MOZ_CRASHREPORTER - this.initSubmitCrashes(); -#endif - this.initTelemetry(); -#ifdef MOZ_SERVICES_HEALTHREPORT - this.initSubmitHealthReport(); -#endif - - this.updateCacheSizeInputField(); - this.updateActualCacheSize(); - this.updateActualAppCacheSize(); - - let bundlePrefs = document.getElementById("bundlePreferences"); - document.getElementById("offlineAppsList") - .style.height = bundlePrefs.getString("offlineAppsList.height"); - - // Notify observers that the UI is now ready - Services.obs.notifyObservers(window, "advanced-pane-loaded", null); - }, - - /** - * Stores the identity of the current tab in preferences so that the selected - * tab can be persisted between openings of the preferences window. - */ - tabSelectionChanged: function () - { - if (!this._inited) - return; - var advancedPrefs = document.getElementById("advancedPrefs"); - var preference = document.getElementById("browser.preferences.advanced.selectedTabIndex"); - preference.valueFromPreferences = advancedPrefs.selectedIndex; - }, - - // GENERAL TAB - - /* - * Preferences: - * - * accessibility.browsewithcaret - * - true enables keyboard navigation and selection within web pages using a - * visible caret, false uses normal keyboard navigation with no caret - * accessibility.typeaheadfind - * - when set to true, typing outside text areas and input boxes will - * automatically start searching for what's typed within the current - * document; when set to false, no search action happens - * general.autoScroll - * - when set to true, clicking the scroll wheel on the mouse activates a - * mouse mode where moving the mouse down scrolls the document downward with - * speed correlated with the distance of the cursor from the original - * position at which the click occurred (and likewise with movement upward); - * if false, this behavior is disabled - * general.smoothScroll - * - set to true to enable finer page scrolling than line-by-line on page-up, - * page-down, and other such page movements - * layout.spellcheckDefault - * - an integer: - * 0 disables spellchecking - * 1 enables spellchecking, but only for multiline text fields - * 2 enables spellchecking for all text fields - */ - - /** - * Stores the original value of the spellchecking preference to enable proper - * restoration if unchanged (since we're mapping a tristate onto a checkbox). - */ - _storedSpellCheck: 0, - - /** - * Returns true if any spellchecking is enabled and false otherwise, caching - * the current value to enable proper pref restoration if the checkbox is - * never changed. - */ - readCheckSpelling: function () - { - var pref = document.getElementById("layout.spellcheckDefault"); - this._storedSpellCheck = pref.value; - - return (pref.value != 0); - }, - - /** - * Returns the value of the spellchecking preference represented by UI, - * preserving the preference's "hidden" value if the preference is - * unchanged and represents a value not strictly allowed in UI. - */ - writeCheckSpelling: function () - { - var checkbox = document.getElementById("checkSpelling"); - return checkbox.checked ? (this._storedSpellCheck == 2 ? 2 : 1) : 0; - }, - - /** - * security.OCSP.enabled is an integer value for legacy reasons. - * A value of 1 means OCSP is enabled. Any other value means it is disabled. - */ - readEnableOCSP: function () - { - var preference = document.getElementById("security.OCSP.enabled"); - // This is the case if the preference is the default value. - if (preference.value === undefined) { - return true; - } - return preference.value == 1; - }, - - /** - * See documentation for readEnableOCSP. - */ - writeEnableOCSP: function () - { - var checkbox = document.getElementById("enableOCSP"); - return checkbox.checked ? 1 : 0; - }, - - /** - * When the user toggles the layers.acceleration.disabled pref, - * sync its new value to the gfx.direct2d.disabled pref too. - */ - updateHardwareAcceleration: function() - { -#ifdef XP_WIN - var fromPref = document.getElementById("layers.acceleration.disabled"); - var toPref = document.getElementById("gfx.direct2d.disabled"); - toPref.value = fromPref.value; -#endif - }, - - // DATA CHOICES TAB - - /** - * opening links behind a modal dialog is poor form. Work around flawed text-link handling here. - */ - openTextLink: function (evt) { - let where = Services.prefs.getBoolPref("browser.preferences.instantApply") ? "tab" : "window"; - openUILinkIn(evt.target.getAttribute("href"), where); - evt.preventDefault(); - }, - - /** - * Set up or hide the Learn More links for various data collection options - */ - _setupLearnMoreLink: function (pref, element) { - // set up the Learn More link with the correct URL - let url = Services.prefs.getCharPref(pref); - let el = document.getElementById(element); - - if (url) { - el.setAttribute("href", url); - } else { - el.setAttribute("hidden", "true"); - } - }, - - /** - * - */ - initSubmitCrashes: function () - { - var checkbox = document.getElementById("submitCrashesBox"); - try { - var cr = Components.classes["@mozilla.org/toolkit/crash-reporter;1"]. - getService(Components.interfaces.nsICrashReporter); - checkbox.checked = cr.submitReports; - } catch (e) { - checkbox.style.display = "none"; - } - this._setupLearnMoreLink("toolkit.crashreporter.infoURL", "crashReporterLearnMore"); - }, - - /** - * - */ - updateSubmitCrashes: function () - { - var checkbox = document.getElementById("submitCrashesBox"); - try { - var cr = Components.classes["@mozilla.org/toolkit/crash-reporter;1"]. - getService(Components.interfaces.nsICrashReporter); - cr.submitReports = checkbox.checked; - } catch (e) { } - }, - - - /** - * The preference/checkbox is configured in XUL. - * - * In all cases, set up the Learn More link sanely - */ - initTelemetry: function () - { -#ifdef MOZ_TELEMETRY_REPORTING - this._setupLearnMoreLink("toolkit.telemetry.infoURL", "telemetryLearnMore"); -#endif - }, - - /** - * Set the status of the telemetry controls based on the input argument. - * @param {Boolean} aEnabled False disables the controls, true enables them. - */ - setTelemetrySectionEnabled: function (aEnabled) - { -#ifdef MOZ_TELEMETRY_REPORTING - // If FHR is disabled, additional data sharing should be disabled as well. - let disabled = !aEnabled; - document.getElementById("submitTelemetryBox").disabled = disabled; - if (disabled) { - // If we disable FHR, untick the telemetry checkbox. - Services.prefs.setBoolPref("toolkit.telemetry.enabled", false); - } - document.getElementById("telemetryDataDesc").disabled = disabled; -#endif - }, - -#ifdef MOZ_SERVICES_HEALTHREPORT - /** - * Initialize the health report service reference and checkbox. - */ - initSubmitHealthReport: function () { - this._setupLearnMoreLink("datareporting.healthreport.infoURL", "FHRLearnMore"); - - let policy = Components.classes["@mozilla.org/datareporting/service;1"] - .getService(Components.interfaces.nsISupports) - .wrappedJSObject - .policy; - - let checkbox = document.getElementById("submitHealthReportBox"); - - if (!policy || policy.healthReportUploadLocked) { - checkbox.setAttribute("disabled", "true"); - return; - } - - checkbox.checked = policy.healthReportUploadEnabled; - this.setTelemetrySectionEnabled(checkbox.checked); - }, - - /** - * Update the health report policy acceptance with state from checkbox. - */ - updateSubmitHealthReport: function () { - let policy = Components.classes["@mozilla.org/datareporting/service;1"] - .getService(Components.interfaces.nsISupports) - .wrappedJSObject - .policy; - - if (!policy) { - return; - } - - let checkbox = document.getElementById("submitHealthReportBox"); - policy.recordHealthReportUploadEnabled(checkbox.checked, - "Checkbox from preferences pane"); - this.setTelemetrySectionEnabled(checkbox.checked); - }, -#endif - - // NETWORK TAB - - /* - * Preferences: - * - * browser.cache.disk.capacity - * - the size of the browser cache in KB - * - Only used if browser.cache.disk.smart_size.enabled is disabled - */ - - /** - * Displays a dialog in which proxy settings may be changed. - */ - showConnections: function () - { - document.documentElement.openSubDialog("chrome://browser/content/preferences/connection.xul", - "", null); - }, - - // Retrieves the amount of space currently used by disk cache - updateActualCacheSize: function () - { - var actualSizeLabel = document.getElementById("actualDiskCacheSize"); - var prefStrBundle = document.getElementById("bundlePreferences"); - - // Needs to root the observer since cache service keeps only a weak reference. - this.observer = { - onNetworkCacheDiskConsumption: function(consumption) { - var size = DownloadUtils.convertByteUnits(consumption); - actualSizeLabel.value = prefStrBundle.getFormattedString("actualDiskCacheSize", size); - }, - - QueryInterface: XPCOMUtils.generateQI([ - Components.interfaces.nsICacheStorageConsumptionObserver, - Components.interfaces.nsISupportsWeakReference - ]) - }; - - actualSizeLabel.value = prefStrBundle.getString("actualDiskCacheSizeCalculated"); - - var cacheService = - Components.classes["@mozilla.org/netwerk/cache-storage-service;1"] - .getService(Components.interfaces.nsICacheStorageService); - cacheService.asyncGetDiskConsumption(this.observer); - }, - - // Retrieves the amount of space currently used by offline cache - updateActualAppCacheSize: function () - { - var visitor = { - onCacheStorageInfo: function (aEntryCount, aConsumption, aCapacity, aDiskDirectory) - { - var actualSizeLabel = document.getElementById("actualAppCacheSize"); - var sizeStrings = DownloadUtils.convertByteUnits(aConsumption); - var prefStrBundle = document.getElementById("bundlePreferences"); - var sizeStr = prefStrBundle.getFormattedString("actualAppCacheSize", sizeStrings); - actualSizeLabel.value = sizeStr; - } - }; - - var cacheService = - Components.classes["@mozilla.org/netwerk/cache-storage-service;1"] - .getService(Components.interfaces.nsICacheStorageService); - var storage = cacheService.appCacheStorage(LoadContextInfo.default, null); - storage.asyncVisitStorage(visitor, false); - }, - - updateCacheSizeUI: function (smartSizeEnabled) - { - document.getElementById("useCacheBefore").disabled = smartSizeEnabled; - document.getElementById("cacheSize").disabled = smartSizeEnabled; - document.getElementById("useCacheAfter").disabled = smartSizeEnabled; - }, - - readSmartSizeEnabled: function () - { - // The smart_size.enabled preference element is inverted="true", so its - // value is the opposite of the actual pref value - var disabled = document.getElementById("browser.cache.disk.smart_size.enabled").value; - this.updateCacheSizeUI(!disabled); - }, - - /** - * Converts the cache size from units of KB to units of MB and stores it in - * the textbox element. - */ - updateCacheSizeInputField() - { - let cacheSizeElem = document.getElementById("cacheSize"); - let cachePref = document.getElementById("browser.cache.disk.capacity"); - cacheSizeElem.value = cachePref.value / 1024; - if (cachePref.locked) - cacheSizeElem.disabled = true; - }, - - /** - * Updates the cache size preference once user enters a new value. - * We intentionally do not set preference="browser.cache.disk.capacity" - * onto the textbox directly, as that would update the pref at each keypress - * not only after the final value is entered. - */ - updateCacheSizePref() - { - let cacheSizeElem = document.getElementById("cacheSize"); - let cachePref = document.getElementById("browser.cache.disk.capacity"); - // Converts the cache size as specified in UI (in MB) to KB. - let intValue = parseInt(cacheSizeElem.value, 10); - cachePref.value = isNaN(intValue) ? 0 : intValue * 1024; - }, - - /** - * Clears the cache. - */ - clearCache: function () - { - var cache = Components.classes["@mozilla.org/netwerk/cache-storage-service;1"] - .getService(Components.interfaces.nsICacheStorageService); - try { - cache.clear(); - } catch(ex) {} - this.updateActualCacheSize(); - Services.obs.notifyObservers(null, "clear-private-data", null); - }, - - /** - * Clears the application cache. - */ - clearOfflineAppCache: function () - { - Components.utils.import("resource:///modules/offlineAppCache.jsm"); - OfflineAppCacheHelper.clear(); - - this.updateActualAppCacheSize(); - this.updateOfflineApps(); - Services.obs.notifyObservers(null, "clear-private-data", null); - }, - - readOfflineNotify: function() - { - var pref = document.getElementById("browser.offline-apps.notify"); - var button = document.getElementById("offlineNotifyExceptions"); - button.disabled = !pref.value; - return pref.value; - }, - - showOfflineExceptions: function() - { - var bundlePreferences = document.getElementById("bundlePreferences"); - var params = { blockVisible : false, - sessionVisible : false, - allowVisible : false, - prefilledHost : "", - permissionType : "offline-app", - manageCapability : Components.interfaces.nsIPermissionManager.DENY_ACTION, - windowTitle : bundlePreferences.getString("offlinepermissionstitle"), - introText : bundlePreferences.getString("offlinepermissionstext") }; - document.documentElement.openWindow("Browser:Permissions", - "chrome://browser/content/preferences/permissions.xul", - "resizable", params); - }, - - // XXX: duplicated in browser.js - _getOfflineAppUsage: function (perm, groups) - { - var cacheService = Components.classes["@mozilla.org/network/application-cache-service;1"]. - getService(Components.interfaces.nsIApplicationCacheService); - if (!groups) - groups = cacheService.getGroups(); - - var ios = Components.classes["@mozilla.org/network/io-service;1"]. - getService(Components.interfaces.nsIIOService); - - var usage = 0; - for (var i = 0; i < groups.length; i++) { - var uri = ios.newURI(groups[i], null, null); - if (perm.matchesURI(uri, true)) { - var cache = cacheService.getActiveCache(groups[i]); - usage += cache.usage; - } - } - - return usage; - }, - - /** - * Updates the list of offline applications - */ - updateOfflineApps: function () - { - var pm = Components.classes["@mozilla.org/permissionmanager;1"] - .getService(Components.interfaces.nsIPermissionManager); - - var list = document.getElementById("offlineAppsList"); - while (list.firstChild) { - list.removeChild(list.firstChild); - } - - var cacheService = Components.classes["@mozilla.org/network/application-cache-service;1"]. - getService(Components.interfaces.nsIApplicationCacheService); - var groups = cacheService.getGroups(); - - var bundle = document.getElementById("bundlePreferences"); - - var enumerator = pm.enumerator; - while (enumerator.hasMoreElements()) { - var perm = enumerator.getNext().QueryInterface(Components.interfaces.nsIPermission); - if (perm.type == "offline-app" && - perm.capability != Components.interfaces.nsIPermissionManager.DEFAULT_ACTION && - perm.capability != Components.interfaces.nsIPermissionManager.DENY_ACTION) { - var row = document.createElement("listitem"); - row.id = ""; - row.className = "offlineapp"; - row.setAttribute("origin", perm.principal.origin); - var converted = DownloadUtils. - convertByteUnits(this._getOfflineAppUsage(perm, groups)); - row.setAttribute("usage", - bundle.getFormattedString("offlineAppUsage", - converted)); - list.appendChild(row); - } - } - }, - - offlineAppSelected: function() - { - var removeButton = document.getElementById("offlineAppsListRemove"); - var list = document.getElementById("offlineAppsList"); - if (list.selectedItem) { - removeButton.setAttribute("disabled", "false"); - } else { - removeButton.setAttribute("disabled", "true"); - } - }, - - removeOfflineApp: function() - { - var list = document.getElementById("offlineAppsList"); - var item = list.selectedItem; - var origin = item.getAttribute("origin"); - var principal = BrowserUtils.principalFromOrigin(origin); - - var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"] - .getService(Components.interfaces.nsIPromptService); - var flags = prompts.BUTTON_TITLE_IS_STRING * prompts.BUTTON_POS_0 + - prompts.BUTTON_TITLE_CANCEL * prompts.BUTTON_POS_1; - - var bundle = document.getElementById("bundlePreferences"); - var title = bundle.getString("offlineAppRemoveTitle"); - var prompt = bundle.getFormattedString("offlineAppRemovePrompt", [principal.URI.prePath]); - var confirm = bundle.getString("offlineAppRemoveConfirm"); - var result = prompts.confirmEx(window, title, prompt, flags, confirm, - null, null, null, {}); - if (result != 0) - return; - - // get the permission - var pm = Components.classes["@mozilla.org/permissionmanager;1"] - .getService(Components.interfaces.nsIPermissionManager); - var perm = pm.getPermissionObject(principal, "offline-app"); - - // clear offline cache entries - var cacheService = Components.classes["@mozilla.org/network/application-cache-service;1"]. - getService(Components.interfaces.nsIApplicationCacheService); - var ios = Components.classes["@mozilla.org/network/io-service;1"]. - getService(Components.interfaces.nsIIOService); - var groups = cacheService.getGroups(); - for (var i = 0; i < groups.length; i++) { - var uri = ios.newURI(groups[i], null, null); - if (perm.matchesURI(uri, true)) { - var cache = cacheService.getActiveCache(groups[i]); - cache.discard(); - } - } - - pm.removePermission(perm); - - list.removeChild(item); - gAdvancedPane.offlineAppSelected(); - this.updateActualAppCacheSize(); - }, - - // UPDATE TAB - - /* - * Preferences: - * - * app.update.enabled - * - true if updates to the application are enabled, false otherwise - * extensions.update.enabled - * - true if updates to extensions and themes are enabled, false otherwise - * browser.search.update - * - true if updates to search engines are enabled, false otherwise - * app.update.auto - * - true if updates should be automatically downloaded and installed, - * possibly with a warning if incompatible extensions are installed (see - * app.update.mode); false if the user should be asked what he wants to do - * when an update is available - * app.update.mode - * - an integer: - * 0 do not warn if an update will disable extensions or themes - * 1 warn if an update will disable extensions or themes - * 2 warn if an update will disable extensions or themes *or* if the - * update is a major update - */ - -#ifdef MOZ_UPDATER - /** - * Selects the item of the radiogroup, and sets the warnIncompatible checkbox - * based on the pref values and locked states. - * - * UI state matrix for update preference conditions - * - * UI Components: Preferences - * Radiogroup i = app.update.enabled - * Warn before disabling extensions checkbox ii = app.update.auto - * iii = app.update.mode - * - * Disabled states: - * Element pref value locked disabled - * radiogroup i t/f f false - * i t/f *t* *true* - * ii t/f f false - * ii t/f *t* *true* - * iii 0/1/2 t/f false - * warnIncompatible i t f false - * i t *t* *true* - * i *f* t/f *true* - * ii t f false - * ii t *t* *true* - * ii *f* t/f *true* - * iii 0/1/2 f false - * iii 0/1/2 *t* *true* - */ - updateReadPrefs: function () - { - var enabledPref = document.getElementById("app.update.enabled"); - var autoPref = document.getElementById("app.update.auto"); - var radiogroup = document.getElementById("updateRadioGroup"); - - if (!enabledPref.value) // Don't care for autoPref.value in this case. - radiogroup.value="manual"; // 3. Never check for updates. - else if (autoPref.value) // enabledPref.value && autoPref.value - radiogroup.value="auto"; // 1. Automatically install updates for Desktop only - else // enabledPref.value && !autoPref.value - radiogroup.value="checkOnly"; // 2. Check, but let me choose - - var canCheck = Components.classes["@mozilla.org/updates/update-service;1"]. - getService(Components.interfaces.nsIApplicationUpdateService). - canCheckForUpdates; - // canCheck is false if the enabledPref is false and locked, - // or the binary platform or OS version is not known. - // A locked pref is sufficient to disable the radiogroup. - radiogroup.disabled = !canCheck || enabledPref.locked || autoPref.locked; - - var modePref = document.getElementById("app.update.mode"); - var warnIncompatible = document.getElementById("warnIncompatible"); - // the warnIncompatible checkbox value is set by readAddonWarn - warnIncompatible.disabled = radiogroup.disabled || modePref.locked || - !enabledPref.value || !autoPref.value; - -#ifdef MOZ_MAINTENANCE_SERVICE - // Check to see if the maintenance service is installed. - // If it is don't show the preference at all. - var installed; - try { - var wrk = Components.classes["@mozilla.org/windows-registry-key;1"] - .createInstance(Components.interfaces.nsIWindowsRegKey); - wrk.open(wrk.ROOT_KEY_LOCAL_MACHINE, - "SOFTWARE\\Mozilla\\MaintenanceService", - wrk.ACCESS_READ | wrk.WOW64_64); - installed = wrk.readIntValue("Installed"); - wrk.close(); - } catch(e) { - } - if (installed != 1) { - document.getElementById("useService").hidden = true; - } - try { - const DRIVE_FIXED = 3; - const LPCWSTR = ctypes.char16_t.ptr; - const UINT = ctypes.uint32_t; - let kernel32 = ctypes.open("kernel32"); - let GetDriveType = kernel32.declare("GetDriveTypeW", ctypes.default_abi, UINT, LPCWSTR); - var UpdatesDir = Components.classes["@mozilla.org/updates/update-service;1"]. - getService(Components.interfaces.nsIApplicationUpdateService); - let rootPath = UpdatesDir.getUpdatesDirectory(); - while (rootPath.parent != null) { - rootPath = rootPath.parent; - } - if (GetDriveType(rootPath.path) != DRIVE_FIXED) { - document.getElementById("useService").hidden = true; - } - kernel32.close(); - } catch(e) { - } -#endif - }, - - /** - * Sets the pref values based on the selected item of the radiogroup, - * and sets the disabled state of the warnIncompatible checkbox accordingly. - */ - updateWritePrefs: function () - { - var enabledPref = document.getElementById("app.update.enabled"); - var autoPref = document.getElementById("app.update.auto"); - var modePref = document.getElementById("app.update.mode"); - var radiogroup = document.getElementById("updateRadioGroup"); - switch (radiogroup.value) { - case "auto": // 1. Automatically install updates for Desktop only - enabledPref.value = true; - autoPref.value = true; - break; - case "checkOnly": // 2. Check, but let me choose - enabledPref.value = true; - autoPref.value = false; - break; - case "manual": // 3. Never check for updates. - enabledPref.value = false; - autoPref.value = false; - } - - var warnIncompatible = document.getElementById("warnIncompatible"); - warnIncompatible.disabled = enabledPref.locked || !enabledPref.value || - autoPref.locked || !autoPref.value || - modePref.locked; - }, - - /** - * Stores the value of the app.update.mode preference, which is a tristate - * integer preference. We store the value here so that we can properly - * restore the preference value if the UI reflecting the preference value - * is in a state which can represent either of two integer values (as - * opposed to only one possible value in the other UI state). - */ - _modePreference: -1, - - /** - * Reads the app.update.mode preference and converts its value into a - * true/false value for use in determining whether the "Warn me if this will - * disable extensions or themes" checkbox is checked. We also save the value - * of the preference so that the preference value can be properly restored if - * the user's preferences cannot adequately be expressed by a single checkbox. - * - * app.update.mode Checkbox State Meaning - * 0 Unchecked Do not warn - * 1 Checked Warn if there are incompatibilities - * 2 Checked Warn if there are incompatibilities, - * or the update is major. - */ - readAddonWarn: function () - { - var preference = document.getElementById("app.update.mode"); - var warn = preference.value != 0; - gAdvancedPane._modePreference = warn ? preference.value : 1; - return warn; - }, - - /** - * Converts the state of the "Warn me if this will disable extensions or - * themes" checkbox into the integer preference which represents it, - * returning that value. - */ - writeAddonWarn: function () - { - var warnIncompatible = document.getElementById("warnIncompatible"); - return !warnIncompatible.checked ? 0 : gAdvancedPane._modePreference; - }, - - /** - * Displays the history of installed updates. - */ - showUpdates: function () - { - var prompter = Components.classes["@mozilla.org/updates/update-prompt;1"] - .createInstance(Components.interfaces.nsIUpdatePrompt); - prompter.showUpdateHistory(window); - }, -#endif - - // ENCRYPTION TAB - - /* - * Preferences: - * - * security.default_personal_cert - * - a string: - * "Select Automatically" select a certificate automatically when a site - * requests one - * "Ask Every Time" present a dialog to the user so he can select - * the certificate to use on a site which - * requests one - */ - - /** - * Displays the user's certificates and associated options. - */ - showCertificates: function () - { - document.documentElement.openWindow("mozilla:certmanager", - "chrome://pippki/content/certManager.xul", - "", null); - }, - - /** - * Displays a dialog from which the user can manage his security devices. - */ - showSecurityDevices: function () - { - document.documentElement.openWindow("mozilla:devicemanager", - "chrome://pippki/content/device_manager.xul", - "", null); - }, - -#ifdef MOZ_UPDATER - observe: function (aSubject, aTopic, aData) { - switch(aTopic) { - case "nsPref:changed": - this.updateReadPrefs(); - break; - } - }, -#endif -}; diff --git a/browser/components/preferences/advanced.xul b/browser/components/preferences/advanced.xul deleted file mode 100644 index c375cd33b8f7..000000000000 --- a/browser/components/preferences/advanced.xul +++ /dev/null @@ -1,397 +0,0 @@ - - -# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- -# 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/. - - -%brandDTD; - -%advancedDTD; - -%privacyDTD; -]> - - - - - - - - - - - - - - - - - - -#ifdef XP_WIN - -#endif - - - - -#ifdef MOZ_TELEMETRY_REPORTING - -#endif - - - - - - - - -#ifdef MOZ_UPDATER - - - - - - -#ifdef MOZ_MAINTENANCE_SERVICE - -#endif -#endif - - - - - - - - - - - -#ifdef HAVE_SHELL_SERVICE - - -#endif - - -