diff --git a/browser/base/content/test/newtab/browser.ini b/browser/base/content/test/newtab/browser.ini index 71a9417e9483..12796489997a 100644 --- a/browser/base/content/test/newtab/browser.ini +++ b/browser/base/content/test/newtab/browser.ini @@ -44,3 +44,4 @@ support-files = [browser_newtab_undo.js] [browser_newtab_unpin.js] [browser_newtab_update.js] +skip-if = true # Bug 1008029 diff --git a/browser/devtools/debugger/test/browser.ini b/browser/devtools/debugger/test/browser.ini index e4ba264eb2c6..6f78b15a7952 100644 --- a/browser/devtools/debugger/test/browser.ini +++ b/browser/devtools/debugger/test/browser.ini @@ -152,33 +152,33 @@ skip-if = e10s || os == "mac" || e10s # Bug 895426 [browser_dbg_break-on-dom-event-02.js] skip-if = e10s [browser_dbg_breakpoints-actual-location.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_breakpoints-actual-location2.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_breakpoints-break-on-last-line-of-script-on-reload.js] -skip-if = e10s +skip-if = e10s # Bug 1093535 [browser_dbg_breakpoints-button-01.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_breakpoints-button-02.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_breakpoints-contextmenu-add.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_breakpoints-contextmenu.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_breakpoints-disabled-reload.js] -skip-if = e10s +skip-if = e10s # Bug 1093535 [browser_dbg_breakpoints-editor.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_breakpoints-highlight.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_breakpoints-new-script.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_breakpoints-other-tabs.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_breakpoints-pane.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_breakpoints-reload.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_chrome-create.js] skip-if = e10s [browser_dbg_chrome-debugging.js] @@ -458,21 +458,21 @@ skip-if = e10s && debug [browser_dbg_variables-view-06.js] skip-if = e10s && debug [browser_dbg_variables-view-accessibility.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_variables-view-data.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_variables-view-edit-cancel.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_variables-view-edit-click.js] skip-if = e10s || (os == 'mac' || os == 'win') && (debug == false) # Bug 986166 [browser_dbg_variables-view-edit-getset-01.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_variables-view-edit-getset-02.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_variables-view-edit-value.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_variables-view-edit-watch.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_variables-view-filter-01.js] skip-if = e10s && debug [browser_dbg_variables-view-filter-02.js] @@ -484,27 +484,27 @@ skip-if = e10s && debug [browser_dbg_variables-view-filter-05.js] skip-if = e10s && debug [browser_dbg_variables-view-filter-pref.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_variables-view-filter-searchbox.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_variables-view-frame-parameters-01.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_variables-view-frame-parameters-02.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_variables-view-frame-parameters-03.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_variables-view-frame-with.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_variables-view-frozen-sealed-nonext.js] -skip-if = e10s || buildapp == 'mulet' +skip-if = e10s && debug || buildapp == 'mulet' [browser_dbg_variables-view-hide-non-enums.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_variables-view-large-array-buffer.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_variables-view-override-01.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_variables-view-override-02.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_variables-view-popup-01.js] skip-if = e10s && debug [browser_dbg_variables-view-popup-02.js] @@ -532,20 +532,20 @@ skip-if = e10s && debug [browser_dbg_variables-view-popup-13.js] skip-if = e10s && debug [browser_dbg_variables-view-popup-14.js] -skip-if = e10s && debug +skip-if = (e10s && debug) || (e10s && os == 'linux') # Linux e10s - bug 1029545 [browser_dbg_variables-view-popup-15.js] skip-if = e10s && debug [browser_dbg_variables-view-popup-16.js] skip-if = e10s && debug [browser_dbg_variables-view-reexpand-01.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_variables-view-reexpand-02.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_variables-view-reexpand-03.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_variables-view-webidl.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_watch-expressions-01.js] -skip-if = e10s +skip-if = e10s && debug [browser_dbg_watch-expressions-02.js] -skip-if = e10s +skip-if = e10s && debug diff --git a/browser/devtools/debugger/test/browser_dbg_breakpoints-actual-location.js b/browser/devtools/debugger/test/browser_dbg_breakpoints-actual-location.js index 880363048cca..de303d829e69 100644 --- a/browser/devtools/debugger/test/browser_dbg_breakpoints-actual-location.js +++ b/browser/devtools/debugger/test/browser_dbg_breakpoints-actual-location.js @@ -9,12 +9,11 @@ const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html"; function test() { - let gTab, gDebuggee, gPanel, gDebugger; + let gTab, gPanel, gDebugger; let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving; - initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { + initDebugger(TAB_URL).then(([aTab,, aPanel]) => { gTab = aTab; - gDebuggee = aDebuggee; gPanel = aPanel; gDebugger = gPanel.panelWin; gEditor = gDebugger.DebuggerView.editor; @@ -24,7 +23,7 @@ function test() { gBreakpointsRemoving = gBreakpoints._removing; waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1).then(performTest); - gDebuggee.firstCall(); + callInTab(gTab, "firstCall"); }); function performTest() { diff --git a/browser/devtools/debugger/test/browser_dbg_breakpoints-actual-location2.js b/browser/devtools/debugger/test/browser_dbg_breakpoints-actual-location2.js index 552a42e37301..24d293ca082e 100644 --- a/browser/devtools/debugger/test/browser_dbg_breakpoints-actual-location2.js +++ b/browser/devtools/debugger/test/browser_dbg_breakpoints-actual-location2.js @@ -10,12 +10,11 @@ const TAB_URL = EXAMPLE_URL + "doc_breakpoint-move.html"; function test() { - let gTab, gDebuggee, gPanel, gDebugger; + let gTab, gPanel, gDebugger; let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving; - initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { + initDebugger(TAB_URL).then(([aTab,, aPanel]) => { gTab = aTab; - gDebuggee = aDebuggee; gPanel = aPanel; gDebugger = gPanel.panelWin; gEditor = gDebugger.DebuggerView.editor; @@ -25,7 +24,7 @@ function test() { gBreakpointsRemoving = gBreakpoints._removing; waitForSourceAndCaretAndScopes(gPanel, ".html", 1).then(performTest); - gDebuggee.ermahgerd(); + callInTab(gTab, "ermahgerd"); }); function performTest() { @@ -62,7 +61,7 @@ function test() { yield resumeAndTestBreakpoint(20); yield doResume(gPanel); - executeSoon(() => gDebuggee.ermahgerd()); + callInTab(gTab, "ermahgerd"); yield waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES); yield resumeAndTestBreakpoint(20); diff --git a/browser/devtools/debugger/test/browser_dbg_breakpoints-break-on-last-line-of-script-on-reload.js b/browser/devtools/debugger/test/browser_dbg_breakpoints-break-on-last-line-of-script-on-reload.js index 4a2e58058e12..f2951bc7801b 100644 --- a/browser/devtools/debugger/test/browser_dbg_breakpoints-break-on-last-line-of-script-on-reload.js +++ b/browser/devtools/debugger/test/browser_dbg_breakpoints-break-on-last-line-of-script-on-reload.js @@ -15,7 +15,7 @@ function test() { let gPanel, gDebugger, gThreadClient, gEvents; - initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { + initDebugger(TAB_URL).then(([aTab,, aPanel]) => { gPanel = aPanel; gDebugger = gPanel.panelWin; gThreadClient = gDebugger.gThreadClient; diff --git a/browser/devtools/debugger/test/browser_dbg_breakpoints-button-01.js b/browser/devtools/debugger/test/browser_dbg_breakpoints-button-01.js index 023fdeba7cc5..70f52ba37cbe 100644 --- a/browser/devtools/debugger/test/browser_dbg_breakpoints-button-01.js +++ b/browser/devtools/debugger/test/browser_dbg_breakpoints-button-01.js @@ -8,12 +8,11 @@ const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html"; function test() { - let gTab, gDebuggee, gPanel, gDebugger; + let gTab, gPanel, gDebugger; let gSources, gBreakpoints; - initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { + initDebugger(TAB_URL).then(([aTab,, aPanel]) => { gTab = aTab; - gDebuggee = aDebuggee; gPanel = aPanel; gDebugger = gPanel.panelWin; gSources = gDebugger.DebuggerView.Sources; diff --git a/browser/devtools/debugger/test/browser_dbg_breakpoints-button-02.js b/browser/devtools/debugger/test/browser_dbg_breakpoints-button-02.js index 504293155df1..dcb55f6c2b48 100644 --- a/browser/devtools/debugger/test/browser_dbg_breakpoints-button-02.js +++ b/browser/devtools/debugger/test/browser_dbg_breakpoints-button-02.js @@ -9,12 +9,11 @@ const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html"; function test() { - let gTab, gDebuggee, gPanel, gDebugger; + let gTab, gPanel, gDebugger; let gSources, gBreakpoints; - initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { + initDebugger(TAB_URL).then(([aTab,, aPanel]) => { gTab = aTab; - gDebuggee = aDebuggee; gPanel = aPanel; gDebugger = gPanel.panelWin; gSources = gDebugger.DebuggerView.Sources; diff --git a/browser/devtools/debugger/test/browser_dbg_breakpoints-contextmenu-add.js b/browser/devtools/debugger/test/browser_dbg_breakpoints-contextmenu-add.js index ab2acf7003a2..92ebb7438edf 100644 --- a/browser/devtools/debugger/test/browser_dbg_breakpoints-contextmenu-add.js +++ b/browser/devtools/debugger/test/browser_dbg_breakpoints-contextmenu-add.js @@ -8,12 +8,11 @@ const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html"; function test() { - let gTab, gDebuggee, gPanel, gDebugger; + let gTab, gPanel, gDebugger; let gEditor, gSources, gContextMenu, gBreakpoints, gBreakpointsAdded; - initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { + initDebugger(TAB_URL).then(([aTab,, aPanel]) => { gTab = aTab; - gDebuggee = aDebuggee; gPanel = aPanel; gDebugger = gPanel.panelWin; gEditor = gDebugger.DebuggerView.editor; @@ -29,7 +28,7 @@ function test() { ok(false, "Got an error: " + aError.message + "\n" + aError.stack); }); - gDebuggee.firstCall(); + callInTab(gTab, "firstCall"); }); function performTest() { diff --git a/browser/devtools/debugger/test/browser_dbg_breakpoints-contextmenu.js b/browser/devtools/debugger/test/browser_dbg_breakpoints-contextmenu.js index 1564c7310a13..b68ae94a0a22 100644 --- a/browser/devtools/debugger/test/browser_dbg_breakpoints-contextmenu.js +++ b/browser/devtools/debugger/test/browser_dbg_breakpoints-contextmenu.js @@ -11,12 +11,11 @@ function test() { // Debug test slaves are a bit slow at this test. requestLongerTimeout(2); - let gTab, gDebuggee, gPanel, gDebugger; + let gTab, gPanel, gDebugger; let gSources, gBreakpoints; - initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { + initDebugger(TAB_URL).then(([aTab,, aPanel]) => { gTab = aTab; - gDebuggee = aDebuggee; gPanel = aPanel; gDebugger = gPanel.panelWin; gSources = gDebugger.DebuggerView.Sources; @@ -95,13 +94,7 @@ function test() { ok(isCaretPos(gPanel, 9), "The editor location is correct before pausing."); - // Spin the event loop before causing the debuggee to pause, to allow - // this function to return first. - executeSoon(() => { - EventUtils.sendMouseEvent({ type: "click" }, - gDebuggee.document.querySelector("button"), - gDebuggee); - }); + sendMouseClickToTab(gTab, content.document.querySelector("button")); return finished; } diff --git a/browser/devtools/debugger/test/browser_dbg_breakpoints-disabled-reload.js b/browser/devtools/debugger/test/browser_dbg_breakpoints-disabled-reload.js index e4a222b56e4f..3b27a4edd703 100644 --- a/browser/devtools/debugger/test/browser_dbg_breakpoints-disabled-reload.js +++ b/browser/devtools/debugger/test/browser_dbg_breakpoints-disabled-reload.js @@ -8,7 +8,8 @@ const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html"; function test() { - initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { + initDebugger(TAB_URL).then(([aTab,, aPanel]) => { + let gTab = aTab; let gDebugger = aPanel.panelWin; let gEvents = gDebugger.EVENTS; let gEditor = gDebugger.DebuggerView.editor; @@ -66,7 +67,7 @@ function test() { yield ensureSourceIs(aPanel, "-01.js"); yield verifyView({ disabled: false, visible: true }); - executeSoon(() => aDebuggee.firstCall()); + callInTab(gTab, "firstCall"); yield waitForDebuggerEvents(aPanel, gEvents.FETCHED_SCOPES); yield ensureSourceIs(aPanel, "-01.js"); yield ensureCaretAt(aPanel, 5); @@ -83,7 +84,7 @@ function test() { yield ensureSourceIs(aPanel, "-02.js", true); yield verifyView({ disabled: false, visible: false }); - executeSoon(() => aDebuggee.firstCall()); + callInTab(gTab, "firstCall"); yield waitForSourceAndCaretAndScopes(aPanel, "-01.js", 1); yield verifyView({ disabled: false, visible: true }); @@ -98,7 +99,7 @@ function test() { yield ensureSourceIs(aPanel, "-02.js", true); yield verifyView({ disabled: true, visible: false }); - executeSoon(() => aDebuggee.firstCall()); + callInTab(gTab, "firstCall"); yield waitForDebuggerEvents(aPanel, gEvents.FETCHED_SCOPES); yield ensureSourceIs(aPanel, "-02.js"); yield ensureCaretAt(aPanel, 1); diff --git a/browser/devtools/debugger/test/browser_dbg_breakpoints-editor.js b/browser/devtools/debugger/test/browser_dbg_breakpoints-editor.js index c19de5f7a1a5..a20961b6e35e 100644 --- a/browser/devtools/debugger/test/browser_dbg_breakpoints-editor.js +++ b/browser/devtools/debugger/test/browser_dbg_breakpoints-editor.js @@ -9,12 +9,11 @@ const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html"; function test() { - let gTab, gDebuggee, gPanel, gDebugger; + let gTab, gPanel, gDebugger; let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving; - initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { + initDebugger(TAB_URL).then(([aTab,, aPanel]) => { gTab = aTab; - gDebuggee = aDebuggee; gPanel = aPanel; gDebugger = gPanel.panelWin; gEditor = gDebugger.DebuggerView.editor; @@ -24,7 +23,7 @@ function test() { gBreakpointsRemoving = gBreakpoints._removing; waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1).then(performTest); - gDebuggee.firstCall(); + callInTab(gTab, "firstCall"); }); function performTest() { diff --git a/browser/devtools/debugger/test/browser_dbg_breakpoints-highlight.js b/browser/devtools/debugger/test/browser_dbg_breakpoints-highlight.js index c0ddc30ee254..eed20b243ae7 100644 --- a/browser/devtools/debugger/test/browser_dbg_breakpoints-highlight.js +++ b/browser/devtools/debugger/test/browser_dbg_breakpoints-highlight.js @@ -8,12 +8,11 @@ const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html"; function test() { - let gTab, gDebuggee, gPanel, gDebugger; + let gTab, gPanel, gDebugger; let gEditor, gSources; - initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { + initDebugger(TAB_URL).then(([aTab,, aPanel]) => { gTab = aTab; - gDebuggee = aDebuggee; gPanel = aPanel; gDebugger = gPanel.panelWin; gEditor = gDebugger.DebuggerView.editor; diff --git a/browser/devtools/debugger/test/browser_dbg_breakpoints-new-script.js b/browser/devtools/debugger/test/browser_dbg_breakpoints-new-script.js index fd747c346f32..f87e1f5fea55 100644 --- a/browser/devtools/debugger/test/browser_dbg_breakpoints-new-script.js +++ b/browser/devtools/debugger/test/browser_dbg_breakpoints-new-script.js @@ -8,12 +8,11 @@ const TAB_URL = EXAMPLE_URL + "doc_inline-script.html"; -let gTab, gDebuggee, gPanel, gDebugger; +let gTab, gPanel, gDebugger; function test() { - initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { + initDebugger(TAB_URL).then(([aTab,, aPanel]) => { gTab = aTab; - gDebuggee = aDebuggee; gPanel = aPanel; gDebugger = gPanel.panelWin; @@ -33,7 +32,7 @@ function addBreakpoint() { }); }); - gDebuggee.runDebuggerStatement(); + callInTab(gTab, "runDebuggerStatement"); } function testResume() { @@ -54,9 +53,7 @@ function testResume() { }); }); - EventUtils.sendMouseEvent({ type: "click" }, - gDebuggee.document.querySelector("button"), - gDebuggee); + sendMouseClickToTab(gTab, content.document.querySelector("button")); }); } @@ -84,7 +81,6 @@ function testBreakpointHit() { registerCleanupFunction(function() { gTab = null; - gDebuggee = null; gPanel = null; gDebugger = null; }); diff --git a/browser/devtools/debugger/test/browser_dbg_breakpoints-other-tabs.js b/browser/devtools/debugger/test/browser_dbg_breakpoints-other-tabs.js index 31fb3ef60dd8..6bcf45675f33 100644 --- a/browser/devtools/debugger/test/browser_dbg_breakpoints-other-tabs.js +++ b/browser/devtools/debugger/test/browser_dbg_breakpoints-other-tabs.js @@ -9,8 +9,8 @@ const TAB_URL = EXAMPLE_URL + "doc_breakpoints-other-tabs.html"; let test = Task.async(function* () { - const [tab1, debuggee1, panel1] = yield initDebugger(TAB_URL); - const [tab2, debuggee2, panel2] = yield initDebugger(TAB_URL); + const [tab1,, panel1] = yield initDebugger(TAB_URL); + const [tab2,, panel2] = yield initDebugger(TAB_URL); yield ensureSourceIs(panel1, "code_breakpoints-other-tabs.js", true); @@ -22,7 +22,7 @@ let test = Task.async(function* () { }); const paused = waitForThreadEvents(panel2, "paused"); - executeSoon(() => debuggee2.testCase()); + callInTab(tab2, "testCase"); const packet = yield paused; is(packet.why.type, "debuggerStatement", diff --git a/browser/devtools/debugger/test/browser_dbg_breakpoints-pane.js b/browser/devtools/debugger/test/browser_dbg_breakpoints-pane.js index 2e8559b27662..3d7ef117af3e 100644 --- a/browser/devtools/debugger/test/browser_dbg_breakpoints-pane.js +++ b/browser/devtools/debugger/test/browser_dbg_breakpoints-pane.js @@ -9,12 +9,11 @@ const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html"; function test() { - let gTab, gDebuggee, gPanel, gDebugger; + let gTab, gPanel, gDebugger; let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving; - initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { + initDebugger(TAB_URL).then(([aTab,, aPanel]) => { gTab = aTab; - gDebuggee = aDebuggee; gPanel = aPanel; gDebugger = gPanel.panelWin; gEditor = gDebugger.DebuggerView.editor; @@ -24,7 +23,7 @@ function test() { gBreakpointsRemoving = gBreakpoints._removing; waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1).then(performTest); - gDebuggee.firstCall(); + callInTab(gTab, "firstCall"); }); let breakpointsAdded = 0; diff --git a/browser/devtools/debugger/test/browser_dbg_breakpoints-reload.js b/browser/devtools/debugger/test/browser_dbg_breakpoints-reload.js index 219676528df9..52ba4f962331 100644 --- a/browser/devtools/debugger/test/browser_dbg_breakpoints-reload.js +++ b/browser/devtools/debugger/test/browser_dbg_breakpoints-reload.js @@ -11,7 +11,7 @@ const TAB_URL = EXAMPLE_URL + "doc_breakpoints-reload.html"; let test = Task.async(function* () { requestLongerTimeout(4); - const [tab, debuggee, panel] = yield initDebugger(TAB_URL); + const [tab,, panel] = yield initDebugger(TAB_URL); yield ensureSourceIs(panel, "doc_breakpoints-reload.html", true); diff --git a/browser/devtools/debugger/test/browser_dbg_variables-view-accessibility.js b/browser/devtools/debugger/test/browser_dbg_variables-view-accessibility.js index 2b856795fbc6..7605b2ccab41 100644 --- a/browser/devtools/debugger/test/browser_dbg_variables-view-accessibility.js +++ b/browser/devtools/debugger/test/browser_dbg_variables-view-accessibility.js @@ -5,13 +5,12 @@ * Make sure that the variables view is keyboard accessible. */ -let gTab, gDebuggee, gPanel, gDebugger; +let gTab, gPanel, gDebugger; let gVariablesView; function test() { - initDebugger("about:blank").then(([aTab, aDebuggee, aPanel]) => { + initDebugger("about:blank").then(([aTab,, aPanel]) => { gTab = aTab; - gDebuggee = aDebuggee; gPanel = aPanel; gDebugger = gPanel.panelWin; gVariablesView = gDebugger.DebuggerView.Variables; @@ -504,7 +503,6 @@ function performTest() { registerCleanupFunction(function() { gTab = null; - gDebuggee = null; gPanel = null; gDebugger = null; gVariablesView = null; diff --git a/browser/devtools/debugger/test/browser_dbg_variables-view-data.js b/browser/devtools/debugger/test/browser_dbg_variables-view-data.js index c95d6855de0b..be2446fb67ae 100644 --- a/browser/devtools/debugger/test/browser_dbg_variables-view-data.js +++ b/browser/devtools/debugger/test/browser_dbg_variables-view-data.js @@ -6,13 +6,12 @@ * when given some raw data. */ -let gTab, gDebuggee, gPanel, gDebugger; +let gTab, gPanel, gDebugger; let gVariablesView, gScope, gVariable; function test() { - initDebugger("about:blank").then(([aTab, aDebuggee, aPanel]) => { + initDebugger("about:blank").then(([aTab,, aPanel]) => { gTab = aTab; - gDebuggee = aDebuggee; gPanel = aPanel; gDebugger = gPanel.panelWin; gVariablesView = gDebugger.DebuggerView.Variables; @@ -602,7 +601,6 @@ function testClearHierarchy() { registerCleanupFunction(function() { gTab = null; - gDebuggee = null; gPanel = null; gDebugger = null; gVariablesView = null; diff --git a/browser/devtools/debugger/test/browser_dbg_variables-view-edit-cancel.js b/browser/devtools/debugger/test/browser_dbg_variables-view-edit-cancel.js index 2f81ea7cdec1..7ba20aad17b8 100644 --- a/browser/devtools/debugger/test/browser_dbg_variables-view-edit-cancel.js +++ b/browser/devtools/debugger/test/browser_dbg_variables-view-edit-cancel.js @@ -10,14 +10,13 @@ const TAB_URL = EXAMPLE_URL + "doc_watch-expressions.html"; function test() { Task.spawn(function*() { - let [tab, debuggee, panel] = yield initDebugger(TAB_URL); + let [tab,, panel] = yield initDebugger(TAB_URL); let win = panel.panelWin; let vars = win.DebuggerView.Variables; win.DebuggerView.WatchExpressions.addExpression("this"); - // Allow this generator function to yield first. - executeSoon(() => debuggee.ermahgerd()); + callInTab(tab, "ermahgerd"); yield waitForDebuggerEvents(panel, win.EVENTS.FETCHED_WATCH_EXPRESSIONS); let exprScope = vars.getScopeAtIndex(0); diff --git a/browser/devtools/debugger/test/browser_dbg_variables-view-edit-getset-01.js b/browser/devtools/debugger/test/browser_dbg_variables-view-edit-getset-01.js index 624803a42635..d15fd6b2a71a 100644 --- a/browser/devtools/debugger/test/browser_dbg_variables-view-edit-getset-01.js +++ b/browser/devtools/debugger/test/browser_dbg_variables-view-edit-getset-01.js @@ -7,16 +7,15 @@ const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html"; -let gTab, gDebuggee, gPanel, gDebugger; +let gTab, gPanel, gDebugger; let gL10N, gEditor, gVars, gWatch; function test() { // Debug test slaves are a bit slow at this test. requestLongerTimeout(2); - initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { + initDebugger(TAB_URL).then(([aTab,, aPanel]) => { gTab = aTab; - gDebuggee = aDebuggee; gPanel = aPanel; gDebugger = gPanel.panelWin; gL10N = gDebugger.L10N; @@ -115,9 +114,7 @@ function test() { ok(false, "Got an error: " + aError.message + "\n" + aError.stack); }); - EventUtils.sendMouseEvent({ type: "click" }, - gDebuggee.document.querySelector("button"), - gDebuggee); + sendMouseClickToTab(gTab, content.document.querySelector("button")); }); } @@ -288,7 +285,6 @@ function testWatchExpressionsRemoved() { registerCleanupFunction(function() { gTab = null; - gDebuggee = null; gPanel = null; gDebugger = null; gL10N = null; diff --git a/browser/devtools/debugger/test/browser_dbg_variables-view-edit-getset-02.js b/browser/devtools/debugger/test/browser_dbg_variables-view-edit-getset-02.js index d86304bec85a..7c760b1af0bb 100644 --- a/browser/devtools/debugger/test/browser_dbg_variables-view-edit-getset-02.js +++ b/browser/devtools/debugger/test/browser_dbg_variables-view-edit-getset-02.js @@ -8,16 +8,15 @@ const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html"; -let gTab, gDebuggee, gPanel, gDebugger; +let gTab, gPanel, gDebugger; let gL10N, gEditor, gVars, gWatch; function test() { // Debug test slaves are a bit slow at this test. requestLongerTimeout(2); - initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { + initDebugger(TAB_URL).then(([aTab,, aPanel]) => { gTab = aTab; - gDebuggee = aDebuggee; gPanel = aPanel; gDebugger = gPanel.panelWin; gL10N = gDebugger.L10N; @@ -36,9 +35,7 @@ function test() { ok(false, "Got an error: " + aError.message + "\n" + aError.stack); }); - EventUtils.sendMouseEvent({ type: "click" }, - gDebuggee.document.querySelector("button"), - gDebuggee); + sendMouseClickToTab(gTab, content.document.querySelector("button")); }); } @@ -94,7 +91,6 @@ function testEdit(aString, aExpected) { registerCleanupFunction(function() { gTab = null; - gDebuggee = null; gPanel = null; gDebugger = null; gL10N = null; diff --git a/browser/devtools/debugger/test/browser_dbg_variables-view-edit-value.js b/browser/devtools/debugger/test/browser_dbg_variables-view-edit-value.js index acdd0b8228b3..c58e6c0da5d0 100644 --- a/browser/devtools/debugger/test/browser_dbg_variables-view-edit-value.js +++ b/browser/devtools/debugger/test/browser_dbg_variables-view-edit-value.js @@ -7,13 +7,12 @@ const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html"; -let gTab, gDebuggee, gPanel, gDebugger; +let gTab, gPanel, gDebugger; let gVars; function test() { - initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { + initDebugger(TAB_URL).then(([aTab,, aPanel]) => { gTab = aTab; - gDebuggee = aDebuggee; gPanel = aPanel; gDebugger = gPanel.panelWin; gVars = gDebugger.DebuggerView.Variables; @@ -38,9 +37,7 @@ function test() { ok(false, "Got an error: " + aError.message + "\n" + aError.stack); }); - EventUtils.sendMouseEvent({ type: "click" }, - gDebuggee.document.querySelector("button"), - gDebuggee); + sendMouseClickToTab(gTab, content.document.querySelector("button")); }); } @@ -82,7 +79,6 @@ function testModification(aNewValue, aNewResult) { registerCleanupFunction(function() { gTab = null; - gDebuggee = null; gPanel = null; gDebugger = null; gVars = null; diff --git a/browser/devtools/debugger/test/browser_dbg_variables-view-edit-watch.js b/browser/devtools/debugger/test/browser_dbg_variables-view-edit-watch.js index bfa8932ffa3b..9f4604af4acf 100644 --- a/browser/devtools/debugger/test/browser_dbg_variables-view-edit-watch.js +++ b/browser/devtools/debugger/test/browser_dbg_variables-view-edit-watch.js @@ -7,13 +7,12 @@ const TAB_URL = EXAMPLE_URL + "doc_watch-expressions.html"; -let gTab, gDebuggee, gPanel, gDebugger; +let gTab, gPanel, gDebugger; let gL10N, gEditor, gVars, gWatch; function test() { - initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { + initDebugger(TAB_URL).then(([aTab,, aPanel]) => { gTab = aTab; - gDebuggee = aDebuggee; gPanel = aPanel; gDebugger = gPanel.panelWin; gL10N = gDebugger.L10N; @@ -44,7 +43,7 @@ function test() { }); addExpressions(); - gDebuggee.ermahgerd(); + callInTab(gTab, "ermahgerd"); }); } @@ -494,7 +493,6 @@ function addCmdExpression(aString) { registerCleanupFunction(function() { gTab = null; - gDebuggee = null; gPanel = null; gDebugger = null; gL10N = null; diff --git a/browser/devtools/debugger/test/browser_dbg_variables-view-filter-pref.js b/browser/devtools/debugger/test/browser_dbg_variables-view-filter-pref.js index 80997af13424..364e22d58966 100644 --- a/browser/devtools/debugger/test/browser_dbg_variables-view-filter-pref.js +++ b/browser/devtools/debugger/test/browser_dbg_variables-view-filter-pref.js @@ -7,13 +7,12 @@ const TAB_URL = EXAMPLE_URL + "doc_with-frame.html"; -let gTab, gDebuggee, gPanel, gDebugger; +let gTab, gPanel, gDebugger; let gPrefs, gOptions, gVariables; function test() { - initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { + initDebugger(TAB_URL).then(([aTab,, aPanel]) => { gTab = aTab; - gDebuggee = aDebuggee; gPanel = aPanel; gDebugger = gPanel.panelWin; gPrefs = gDebugger.Prefs; @@ -72,7 +71,6 @@ function performTest() { registerCleanupFunction(function() { gTab = null; - gDebuggee = null; gPanel = null; gDebugger = null; gPrefs = null; diff --git a/browser/devtools/debugger/test/browser_dbg_variables-view-filter-searchbox.js b/browser/devtools/debugger/test/browser_dbg_variables-view-filter-searchbox.js index 7a07a3288967..4cb1f7b78762 100644 --- a/browser/devtools/debugger/test/browser_dbg_variables-view-filter-searchbox.js +++ b/browser/devtools/debugger/test/browser_dbg_variables-view-filter-searchbox.js @@ -8,13 +8,12 @@ const TAB_URL = EXAMPLE_URL + "doc_with-frame.html"; -let gTab, gDebuggee, gPanel, gDebugger; +let gTab, gPanel, gDebugger; let gVariables; function test() { - initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { + initDebugger(TAB_URL).then(([aTab,, aPanel]) => { gTab = aTab; - gDebuggee = aDebuggee; gPanel = aPanel; gDebugger = gPanel.panelWin; gVariables = gDebugger.DebuggerView.Variables; @@ -139,7 +138,6 @@ function performTest() { registerCleanupFunction(function() { gTab = null; - gDebuggee = null; gPanel = null; gDebugger = null; gVariables = null; diff --git a/browser/devtools/debugger/test/browser_dbg_variables-view-frame-parameters-01.js b/browser/devtools/debugger/test/browser_dbg_variables-view-frame-parameters-01.js index d13ea5da8233..b29977f893ab 100644 --- a/browser/devtools/debugger/test/browser_dbg_variables-view-frame-parameters-01.js +++ b/browser/devtools/debugger/test/browser_dbg_variables-view-frame-parameters-01.js @@ -8,16 +8,15 @@ const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html"; -let gTab, gDebuggee, gPanel, gDebugger; +let gTab, gPanel, gDebugger; let gVariables; function test() { // Debug test slaves are a bit slow at this test. requestLongerTimeout(2); - initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { + initDebugger(TAB_URL).then(([aTab,, aPanel]) => { gTab = aTab; - gDebuggee = aDebuggee; gPanel = aPanel; gDebugger = gPanel.panelWin; gVariables = gDebugger.DebuggerView.Variables; @@ -30,9 +29,7 @@ function test() { ok(false, "Got an error: " + aError.message + "\n" + aError.stack); }); - EventUtils.sendMouseEvent({ type: "click" }, - gDebuggee.document.querySelector("button"), - gDebuggee); + sendMouseClickToTab(gTab, content.document.querySelector("button")); }); } @@ -253,7 +250,6 @@ function testExpandVariables() { registerCleanupFunction(function() { gTab = null; - gDebuggee = null; gPanel = null; gDebugger = null; gVariables = null; diff --git a/browser/devtools/debugger/test/browser_dbg_variables-view-frame-parameters-02.js b/browser/devtools/debugger/test/browser_dbg_variables-view-frame-parameters-02.js index 8f5c39b7354a..b1f482317354 100644 --- a/browser/devtools/debugger/test/browser_dbg_variables-view-frame-parameters-02.js +++ b/browser/devtools/debugger/test/browser_dbg_variables-view-frame-parameters-02.js @@ -8,16 +8,15 @@ const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html"; -let gTab, gDebuggee, gPanel, gDebugger; +let gTab, gPanel, gDebugger; let gVariables; function test() { // Debug test slaves are a bit slow at this test. requestLongerTimeout(2); - initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { + initDebugger(TAB_URL).then(([aTab,, aPanel]) => { gTab = aTab; - gDebuggee = aDebuggee; gPanel = aPanel; gDebugger = gPanel.panelWin; gVariables = gDebugger.DebuggerView.Variables; @@ -35,9 +34,7 @@ function test() { ok(false, "Got an error: " + aError.message + "\n" + aError.stack); }); - EventUtils.sendMouseEvent({ type: "click" }, - gDebuggee.document.querySelector("button"), - gDebuggee); + sendMouseClickToTab(gTab, content.document.querySelector("button")); }); } @@ -543,7 +540,6 @@ function testGetterSetterObject() { registerCleanupFunction(function() { gTab = null; - gDebuggee = null; gPanel = null; gDebugger = null; gVariables = null; diff --git a/browser/devtools/debugger/test/browser_dbg_variables-view-frame-parameters-03.js b/browser/devtools/debugger/test/browser_dbg_variables-view-frame-parameters-03.js index 08b0a109f15a..d667ce67324e 100644 --- a/browser/devtools/debugger/test/browser_dbg_variables-view-frame-parameters-03.js +++ b/browser/devtools/debugger/test/browser_dbg_variables-view-frame-parameters-03.js @@ -8,16 +8,15 @@ const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html"; -let gTab, gDebuggee, gPanel, gDebugger; +let gTab, gPanel, gDebugger; let gVariables; function test() { // Debug test slaves are a bit slow at this test. requestLongerTimeout(2); - initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { + initDebugger(TAB_URL).then(([aTab,, aPanel]) => { gTab = aTab; - gDebuggee = aDebuggee; gPanel = aPanel; gDebugger = gPanel.panelWin; gVariables = gDebugger.DebuggerView.Variables; @@ -32,9 +31,7 @@ function test() { ok(false, "Got an error: " + aError.message + "\n" + aError.stack); }); - EventUtils.sendMouseEvent({ type: "click" }, - gDebuggee.document.querySelector("button"), - gDebuggee); + sendMouseClickToTab(gTab, content.document.querySelector("button")); }); } @@ -148,7 +145,6 @@ function testWindowVariable() { registerCleanupFunction(function() { gTab = null; - gDebuggee = null; gPanel = null; gDebugger = null; gVariables = null; diff --git a/browser/devtools/debugger/test/browser_dbg_variables-view-frame-with.js b/browser/devtools/debugger/test/browser_dbg_variables-view-frame-with.js index de56d894ca11..b96032174772 100644 --- a/browser/devtools/debugger/test/browser_dbg_variables-view-frame-with.js +++ b/browser/devtools/debugger/test/browser_dbg_variables-view-frame-with.js @@ -7,13 +7,12 @@ const TAB_URL = EXAMPLE_URL + "doc_with-frame.html"; -let gTab, gDebuggee, gPanel, gDebugger; +let gTab, gPanel, gDebugger; let gVariables; function test() { - initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { + initDebugger(TAB_URL).then(([aTab,, aPanel]) => { gTab = aTab; - gDebuggee = aDebuggee; gPanel = aPanel; gDebugger = gPanel.panelWin; gVariables = gDebugger.DebuggerView.Variables; @@ -34,9 +33,7 @@ function test() { ok(false, "Got an error: " + aError.message + "\n" + aError.stack); }); - EventUtils.sendMouseEvent({ type: "click" }, - gDebuggee.document.querySelector("button"), - gDebuggee); + sendMouseClickToTab(gTab, content.document.querySelector("button")); }); } @@ -204,7 +201,6 @@ function testFunctionScope() { registerCleanupFunction(function() { gTab = null; - gDebuggee = null; gPanel = null; gDebugger = null; gVariables = null; diff --git a/browser/devtools/debugger/test/browser_dbg_variables-view-frozen-sealed-nonext.js b/browser/devtools/debugger/test/browser_dbg_variables-view-frozen-sealed-nonext.js index a61856abb871..33eafc16282e 100644 --- a/browser/devtools/debugger/test/browser_dbg_variables-view-frozen-sealed-nonext.js +++ b/browser/devtools/debugger/test/browser_dbg_variables-view-frozen-sealed-nonext.js @@ -8,12 +8,11 @@ const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html"; -let gTab, gDebuggee, gPanel, gDebugger; +let gTab, gPanel, gDebugger; function test() { - initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { + initDebugger(TAB_URL).then(([aTab,, aPanel]) => { gTab = aTab; - gDebuggee = aDebuggee; gPanel = aPanel; gDebugger = gPanel.panelWin; @@ -24,7 +23,7 @@ function test() { function prepareTest() { gDebugger.once(gDebugger.EVENTS.FETCHED_SCOPES, runTest); - gDebuggee.eval("(" + function() { + evalInTab(gTab, "(" + function() { var frozen = Object.freeze({}); var sealed = Object.seal({}); var nonExtensible = Object.preventExtensions({}); @@ -83,7 +82,6 @@ function runTest() { registerCleanupFunction(function() { gTab = null; - gDebuggee = null; gPanel = null; gDebugger = null; }); diff --git a/browser/devtools/debugger/test/browser_dbg_variables-view-hide-non-enums.js b/browser/devtools/debugger/test/browser_dbg_variables-view-hide-non-enums.js index 857899a0a433..2030a82f9479 100644 --- a/browser/devtools/debugger/test/browser_dbg_variables-view-hide-non-enums.js +++ b/browser/devtools/debugger/test/browser_dbg_variables-view-hide-non-enums.js @@ -8,17 +8,16 @@ const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html"; -let gTab, gDebuggee, gPanel, gDebugger; +let gTab, gPanel, gDebugger; function test() { - initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { + initDebugger(TAB_URL).then(([aTab,, aPanel]) => { gTab = aTab; - gDebuggee = aDebuggee; gPanel = aPanel; gDebugger = gPanel.panelWin; waitForSourceAndCaretAndScopes(gPanel, ".html", 14).then(performTest); - gDebuggee.simpleCall(); + callInTab(gTab, "simpleCall"); }); } @@ -101,7 +100,6 @@ function performTest() { registerCleanupFunction(function() { gTab = null; - gDebuggee = null; gPanel = null; gDebugger = null; }); diff --git a/browser/devtools/debugger/test/browser_dbg_variables-view-large-array-buffer.js b/browser/devtools/debugger/test/browser_dbg_variables-view-large-array-buffer.js index 69f0788a37ed..d543b49a455d 100644 --- a/browser/devtools/debugger/test/browser_dbg_variables-view-large-array-buffer.js +++ b/browser/devtools/debugger/test/browser_dbg_variables-view-large-array-buffer.js @@ -8,13 +8,12 @@ const TAB_URL = EXAMPLE_URL + "doc_large-array-buffer.html"; -let gTab, gDebuggee, gPanel, gDebugger; +let gTab, gPanel, gDebugger; let gVariables, gEllipsis; function test() { - initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { + initDebugger(TAB_URL).then(([aTab,, aPanel]) => { gTab = aTab; - gDebuggee = aDebuggee; gPanel = aPanel; gDebugger = gPanel.panelWin; gVariables = gDebugger.DebuggerView.Variables; @@ -29,9 +28,7 @@ function test() { ok(false, "Got an error: " + aError.message + "\n" + aError.stack); }); - EventUtils.sendMouseEvent({ type: "click" }, - gDebuggee.document.querySelector("button"), - gDebuggee); + sendMouseClickToTab(gTab, content.document.querySelector("button")); }); } @@ -235,7 +232,6 @@ function verifyNextLevels() { registerCleanupFunction(function() { gTab = null; - gDebuggee = null; gPanel = null; gDebugger = null; gVariables = null; diff --git a/browser/devtools/debugger/test/browser_dbg_variables-view-override-01.js b/browser/devtools/debugger/test/browser_dbg_variables-view-override-01.js index 1e8bf6f726c2..7b2911c38036 100644 --- a/browser/devtools/debugger/test/browser_dbg_variables-view-override-01.js +++ b/browser/devtools/debugger/test/browser_dbg_variables-view-override-01.js @@ -10,13 +10,12 @@ const TAB_URL = EXAMPLE_URL + "doc_scope-variable-2.html"; function test() { Task.spawn(function() { - let [tab, debuggee, panel] = yield initDebugger(TAB_URL); + let [tab,, panel] = yield initDebugger(TAB_URL); let win = panel.panelWin; let events = win.EVENTS; let variables = win.DebuggerView.Variables; - // Allow this generator function to yield first. - executeSoon(() => debuggee.test()); + callInTab(tab, "test"); yield waitForSourceAndCaretAndScopes(panel, ".html", 23); let firstScope = variables.getScopeAtIndex(0); diff --git a/browser/devtools/debugger/test/browser_dbg_variables-view-override-02.js b/browser/devtools/debugger/test/browser_dbg_variables-view-override-02.js index dadfa3ba3e5c..641293d117c6 100644 --- a/browser/devtools/debugger/test/browser_dbg_variables-view-override-02.js +++ b/browser/devtools/debugger/test/browser_dbg_variables-view-override-02.js @@ -9,7 +9,7 @@ const TAB_URL = EXAMPLE_URL + "doc_scope-variable-2.html"; function test() { Task.spawn(function() { - let [tab, debuggee, panel] = yield initDebugger(TAB_URL); + let [tab,, panel] = yield initDebugger(TAB_URL); let win = panel.panelWin; let events = win.EVENTS; let variables = win.DebuggerView.Variables; @@ -18,8 +18,7 @@ function test() { let committedLocalScopeHierarchy = promise.defer(); variables.oncommit = committedLocalScopeHierarchy.resolve; - // Allow this generator function to yield first. - executeSoon(() => debuggee.test()); + callInTab(tab, "test"); yield waitForSourceAndCaretAndScopes(panel, ".html", 23); yield committedLocalScopeHierarchy.promise; diff --git a/browser/devtools/debugger/test/browser_dbg_variables-view-reexpand-01.js b/browser/devtools/debugger/test/browser_dbg_variables-view-reexpand-01.js index 3db66b669577..3e2f69c2927c 100644 --- a/browser/devtools/debugger/test/browser_dbg_variables-view-reexpand-01.js +++ b/browser/devtools/debugger/test/browser_dbg_variables-view-reexpand-01.js @@ -7,16 +7,15 @@ const TAB_URL = EXAMPLE_URL + "doc_with-frame.html"; -let gTab, gDebuggee, gPanel, gDebugger; +let gTab, gPanel, gDebugger; let gBreakpoints, gSources, gVariables; function test() { // Debug test slaves are a bit slow at this test. requestLongerTimeout(4); - initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { + initDebugger(TAB_URL).then(([aTab,, aPanel]) => { gTab = aTab; - gDebuggee = aDebuggee; gPanel = aPanel; gDebugger = gPanel.panelWin; gBreakpoints = gDebugger.DebuggerController.Breakpoints; @@ -45,13 +44,7 @@ function addBreakpoint() { } function pauseDebuggee() { - // Spin the event loop before causing the debuggee to pause, to allow - // this function to return first. - executeSoon(() => { - EventUtils.sendMouseEvent({ type: "click" }, - gDebuggee.document.querySelector("button"), - gDebuggee); - }); + sendMouseClickToTab(gTab, content.document.querySelector("button")); // The first 'with' scope should be expanded by default, but the // variables haven't been fetched yet. This is how 'with' scopes work. @@ -200,7 +193,6 @@ function prepareVariablesAndProperties() { registerCleanupFunction(function() { gTab = null; - gDebuggee = null; gPanel = null; gDebugger = null; gBreakpoints = null; diff --git a/browser/devtools/debugger/test/browser_dbg_variables-view-reexpand-02.js b/browser/devtools/debugger/test/browser_dbg_variables-view-reexpand-02.js index 80393c75341d..e7bb7b1a35ec 100644 --- a/browser/devtools/debugger/test/browser_dbg_variables-view-reexpand-02.js +++ b/browser/devtools/debugger/test/browser_dbg_variables-view-reexpand-02.js @@ -8,16 +8,15 @@ const TAB_URL = EXAMPLE_URL + "doc_with-frame.html"; -let gTab, gDebuggee, gPanel, gDebugger; +let gTab, gPanel, gDebugger; let gBreakpoints, gSources, gVariables; function test() { // Debug test slaves are a bit slow at this test. requestLongerTimeout(4); - initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { + initDebugger(TAB_URL).then(([aTab,, aPanel]) => { gTab = aTab; - gDebuggee = aDebuggee; gPanel = aPanel; gDebugger = gPanel.panelWin; gBreakpoints = gDebugger.DebuggerController.Breakpoints; @@ -46,13 +45,7 @@ function addBreakpoint() { } function pauseDebuggee() { - // Spin the event loop before causing the debuggee to pause, to allow - // this function to return first. - executeSoon(() => { - EventUtils.sendMouseEvent({ type: "click" }, - gDebuggee.document.querySelector("button"), - gDebuggee); - }); + sendMouseClickToTab(gTab, content.document.querySelector("button")); // The first 'with' scope should be expanded by default, but the // variables haven't been fetched yet. This is how 'with' scopes work. @@ -215,7 +208,6 @@ function prepareVariablesAndProperties() { registerCleanupFunction(function() { gTab = null; - gDebuggee = null; gPanel = null; gDebugger = null; gBreakpoints = null; diff --git a/browser/devtools/debugger/test/browser_dbg_variables-view-reexpand-03.js b/browser/devtools/debugger/test/browser_dbg_variables-view-reexpand-03.js index aa88e2f62cac..a3e585e83130 100644 --- a/browser/devtools/debugger/test/browser_dbg_variables-view-reexpand-03.js +++ b/browser/devtools/debugger/test/browser_dbg_variables-view-reexpand-03.js @@ -7,16 +7,15 @@ const TAB_URL = EXAMPLE_URL + "doc_scope-variable-4.html"; -let gTab, gDebuggee, gPanel, gDebugger; +let gTab, gPanel, gDebugger; let gBreakpoints, gSources, gVariables; function test() { // Debug test slaves are a bit slow at this test. requestLongerTimeout(4); - initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { + initDebugger(TAB_URL).then(([aTab,, aPanel]) => { gTab = aTab; - gDebuggee = aDebuggee; gPanel = aPanel; gDebugger = gPanel.panelWin; gBreakpoints = gDebugger.DebuggerController.Breakpoints; @@ -45,11 +44,7 @@ function addBreakpoint() { } function pauseDebuggee() { - // Spin the event loop before causing the debuggee to pause, to allow - // this function to return first. - executeSoon(() => { - gDebuggee.test(); - }); + callInTab(gTab, "test"); return waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES); } @@ -120,7 +115,6 @@ function prepareScopes() { registerCleanupFunction(function() { gTab = null; - gDebuggee = null; gPanel = null; gDebugger = null; gBreakpoints = null; diff --git a/browser/devtools/debugger/test/browser_dbg_variables-view-webidl.js b/browser/devtools/debugger/test/browser_dbg_variables-view-webidl.js index 921d96720941..153fe7499de1 100644 --- a/browser/devtools/debugger/test/browser_dbg_variables-view-webidl.js +++ b/browser/devtools/debugger/test/browser_dbg_variables-view-webidl.js @@ -8,16 +8,15 @@ const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html"; -let gTab, gDebuggee, gPanel, gDebugger; +let gTab, gPanel, gDebugger; let gVariables; function test() { // Debug test slaves are a bit slow at this test. requestLongerTimeout(2); - initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { + initDebugger(TAB_URL).then(([aTab,, aPanel]) => { gTab = aTab; - gDebuggee = aDebuggee; gPanel = aPanel; gDebugger = gPanel.panelWin; gVariables = gDebugger.DebuggerView.Variables; @@ -30,9 +29,7 @@ function test() { ok(false, "Got an error: " + aError.message + "\n" + aError.stack); }); - EventUtils.sendMouseEvent({ type: "click" }, - gDebuggee.document.querySelector("button"), - gDebuggee); + sendMouseClickToTab(gTab, content.document.querySelector("button")); }); } @@ -253,7 +250,6 @@ function performTest() { registerCleanupFunction(function() { gTab = null; - gDebuggee = null; gPanel = null; gDebugger = null; gVariables = null; diff --git a/browser/devtools/debugger/test/browser_dbg_watch-expressions-01.js b/browser/devtools/debugger/test/browser_dbg_watch-expressions-01.js index 999f5016a8ea..51a6d775a806 100644 --- a/browser/devtools/debugger/test/browser_dbg_watch-expressions-01.js +++ b/browser/devtools/debugger/test/browser_dbg_watch-expressions-01.js @@ -11,12 +11,11 @@ function test() { // Debug test slaves are a bit slow at this test. requestLongerTimeout(2); - let gTab, gDebuggee, gPanel, gDebugger; + let gTab, gPanel, gDebugger; let gEditor, gWatch, gVariables; - initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { + initDebugger(TAB_URL).then(([aTab,, aPanel]) => { gTab = aTab; - gDebuggee = aDebuggee; gPanel = aPanel; gDebugger = gPanel.panelWin; gEditor = gDebugger.DebuggerView.editor; diff --git a/browser/devtools/debugger/test/browser_dbg_watch-expressions-02.js b/browser/devtools/debugger/test/browser_dbg_watch-expressions-02.js index 7c0a8be6378a..4d4b785b9abb 100644 --- a/browser/devtools/debugger/test/browser_dbg_watch-expressions-02.js +++ b/browser/devtools/debugger/test/browser_dbg_watch-expressions-02.js @@ -11,12 +11,11 @@ function test() { // Debug test slaves are a bit slow at this test. requestLongerTimeout(2); - let gTab, gDebuggee, gPanel, gDebugger; + let gTab, gPanel, gDebugger; let gWatch, gVariables; - initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { + initDebugger(TAB_URL).then(([aTab,, aPanel]) => { gTab = aTab; - gDebuggee = aDebuggee; gPanel = aPanel; gDebugger = gPanel.panelWin; gWatch = gDebugger.DebuggerView.WatchExpressions; @@ -113,7 +112,7 @@ function test() { aCallback(); }); - gDebuggee.test(); + callInTab(gTab, "test"); } function test2(aCallback) { diff --git a/browser/devtools/debugger/test/code_frame-script.js b/browser/devtools/debugger/test/code_frame-script.js index 5cc700e643f6..c42803b10dfd 100644 --- a/browser/devtools/debugger/test/code_frame-script.js +++ b/browser/devtools/debugger/test/code_frame-script.js @@ -24,3 +24,10 @@ addMessageListener("test:click", function (message) { EventUtils.synthesizeMouseAtCenter(target, {}, target.ownerDocument.defaultView); }); + +addMessageListener("test:eval", function (message) { + dump("Evalling string " + message.data.string + ".\n"); + + content.eval(message.data.string); + sendAsyncMessage("test:eval"); +}); diff --git a/browser/devtools/debugger/test/head.js b/browser/devtools/debugger/test/head.js index 81ceea4a131f..da0791b45c1a 100644 --- a/browser/devtools/debugger/test/head.js +++ b/browser/devtools/debugger/test/head.js @@ -970,6 +970,15 @@ function callInTab(tab, name) { waitForMessageFromTab(tab, "test:call"); } +function evalInTab(tab, string) { + info("Evalling string " + string + " in tab."); + + sendMessageToTab(tab, "test:eval", { + string: string, + }); + waitForMessageFromTab(tab, "test:eval"); +} + function sendMouseClickToTab(tab, target) { info("Sending mouse click to tab."); diff --git a/browser/devtools/timeline/test/browser_timeline_waterfall-styles.js b/browser/devtools/timeline/test/browser_timeline_waterfall-styles.js index 374ddb2487f5..40e700d6a5c9 100644 --- a/browser/devtools/timeline/test/browser_timeline_waterfall-styles.js +++ b/browser/devtools/timeline/test/browser_timeline_waterfall-styles.js @@ -13,6 +13,8 @@ var gRGB_TO_HSL = { "rgb(96, 201, 58)": "hsl(104,57%,51%)", "rgb(240, 195, 111)": "hsl(39,82%,69%)", "rgb(227, 155, 22)": "hsl(39,82%,49%)", + "rgb(204, 204, 204)": "hsl(0,0%,80%)", + "rgb(153, 153, 153)": "hsl(0,0%,60%)", }; let test = Task.async(function*() { diff --git a/browser/devtools/timeline/widgets/global.js b/browser/devtools/timeline/widgets/global.js index 660432bd2e90..ff3630f7e2d8 100644 --- a/browser/devtools/timeline/widgets/global.js +++ b/browser/devtools/timeline/widgets/global.js @@ -55,7 +55,13 @@ const TIMELINE_BLUEPRINT = { fill: "hsl(0,0%,80%)", stroke: "hsl(0,0%,60%)", label: L10N.getStr("timeline.label.consoleTime") - } + }, + "Javascript": { + group: 4, + fill: "hsl(0,0%,80%)", + stroke: "hsl(0,0%,60%)", + label: L10N.getStr("timeline.label.javascript") + }, }; // Exported symbols. diff --git a/browser/locales/en-US/chrome/browser/devtools/timeline.properties b/browser/locales/en-US/chrome/browser/devtools/timeline.properties index 6b0dd1f1fac5..ef7e9514d286 100644 --- a/browser/locales/en-US/chrome/browser/devtools/timeline.properties +++ b/browser/locales/en-US/chrome/browser/devtools/timeline.properties @@ -38,6 +38,7 @@ timeline.records=RECORDS timeline.label.styles=Styles timeline.label.reflow=Reflow timeline.label.paint=Paint +timeline.label.javascript=Javascript timeline.label.domevent=DOM Event timeline.label.consoleTime=Console diff --git a/build/annotationProcessors/AnnotationInfo.java b/build/annotationProcessors/AnnotationInfo.java index 98fdb17d96fb..0f2da147d6a7 100644 --- a/build/annotationProcessors/AnnotationInfo.java +++ b/build/annotationProcessors/AnnotationInfo.java @@ -12,12 +12,19 @@ public class AnnotationInfo { public final boolean isMultithreaded; public final boolean noThrow; public final boolean narrowChars; + public final boolean catchException; public AnnotationInfo(String aWrapperName, boolean aIsMultithreaded, - boolean aNoThrow, boolean aNarrowChars) { + boolean aNoThrow, boolean aNarrowChars, boolean aCatchException) { wrapperName = aWrapperName; isMultithreaded = aIsMultithreaded; noThrow = aNoThrow; narrowChars = aNarrowChars; + catchException = aCatchException; + + if (!noThrow && catchException) { + // It doesn't make sense to have these together + throw new IllegalArgumentException("noThrow and catchException are not allowed together"); + } } } diff --git a/build/annotationProcessors/AnnotationProcessor.java b/build/annotationProcessors/AnnotationProcessor.java index bcd70a58ee8f..66c3918d2744 100644 --- a/build/annotationProcessors/AnnotationProcessor.java +++ b/build/annotationProcessors/AnnotationProcessor.java @@ -52,7 +52,7 @@ public class AnnotationProcessor { "namespace mozilla {\n" + "namespace widget {\n" + "namespace android {\n" + - "void InitStubs(JNIEnv *jEnv);\n\n"); + "void InitStubs(JNIEnv *env);\n\n"); StringBuilder implementationFile = new StringBuilder(GENERATED_COMMENT); implementationFile.append("#include \"GeneratedJNIWrappers.h\"\n" + @@ -66,7 +66,7 @@ public class AnnotationProcessor { // Used to track the calls to the various class-specific initialisation functions. StringBuilder stubInitialiser = new StringBuilder(); - stubInitialiser.append("void InitStubs(JNIEnv *jEnv) {\n"); + stubInitialiser.append("void InitStubs(JNIEnv *env) {\n"); while (jarClassIterator.hasNext()) { ClassWithOptions aClassTuple = jarClassIterator.next(); @@ -81,7 +81,7 @@ public class AnnotationProcessor { } generatorInstance = new CodeGenerator(aClassTuple.wrappedClass, aClassTuple.generatedName); - stubInitialiser.append(" ").append(aClassTuple.generatedName).append("::InitStubs(jEnv);\n"); + stubInitialiser.append(" ").append(aClassTuple.generatedName).append("::InitStubs(env);\n"); // Iterate all annotated members in this class.. while (methodIterator.hasNext()) { diff --git a/build/annotationProcessors/CodeGenerator.java b/build/annotationProcessors/CodeGenerator.java index cb28e6fc4729..215b0009e8dc 100644 --- a/build/annotationProcessors/CodeGenerator.java +++ b/build/annotationProcessors/CodeGenerator.java @@ -12,6 +12,7 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Member; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.util.HashMap; import java.util.HashSet; @@ -40,21 +41,27 @@ public class CodeGenerator { private final HashSet mTakenMemberNames = new HashSet(); private int mNameMunger; + private final boolean mLazyInit; + public CodeGenerator(Class aClass, String aGeneratedName) { + this(aClass, aGeneratedName, false); + } + + public CodeGenerator(Class aClass, String aGeneratedName, boolean aLazyInit) { mClassToWrap = aClass; mCClassName = aGeneratedName; + mLazyInit = aLazyInit; // Write the file header things. Includes and so forth. // GeneratedJNIWrappers.cpp is generated as the concatenation of wrapperStartupCode with // wrapperMethodBodies. Similarly, GeneratedJNIWrappers.h is the concatenation of headerPublic // with headerProtected. - wrapperStartupCode.append("void ").append(mCClassName).append("::InitStubs(JNIEnv *jEnv) {\n" + - " initInit();\n"); + wrapperStartupCode.append("void ").append(mCClassName).append("::InitStubs(JNIEnv *env) {\n"); // Now we write the various GetStaticMethodID calls here... headerPublic.append("class ").append(mCClassName).append(" : public AutoGlobalWrappedJavaObject {\n" + "public:\n" + - " static void InitStubs(JNIEnv *jEnv);\n"); + " static void InitStubs(JNIEnv *env);\n"); headerProtected.append("protected:"); generateWrapperMethod(); @@ -79,7 +86,10 @@ public class CodeGenerator { private void generateMemberCommon(Member theMethod, String aCMethodName, Class aClass) { ensureClassHeaderAndStartup(aClass); writeMemberIdField(theMethod, aCMethodName); - writeStartupCode(theMethod); + + if (!mLazyInit) { + writeMemberInit(theMethod, wrapperStartupCode); + } } /** @@ -101,8 +111,10 @@ public class CodeGenerator { Class returnType = theMethod.getReturnType(); // Get the C++ method signature for this method. - String implementationSignature = Utils.getCImplementationMethodSignature(parameterTypes, returnType, CMethodName, mCClassName, aMethodTuple.mAnnotationInfo.narrowChars); - String headerSignature = Utils.getCHeaderMethodSignature(parameterTypes, theMethod.getParameterAnnotations(), returnType, CMethodName, mCClassName, isFieldStatic, aMethodTuple.mAnnotationInfo.narrowChars); + String implementationSignature = Utils.getCImplementationMethodSignature(parameterTypes, returnType, CMethodName, + mCClassName, aMethodTuple.mAnnotationInfo.narrowChars, aMethodTuple.mAnnotationInfo.catchException); + String headerSignature = Utils.getCHeaderMethodSignature(parameterTypes, theMethod.getParameterAnnotations(), returnType, + CMethodName, mCClassName, isFieldStatic, aMethodTuple.mAnnotationInfo.narrowChars, aMethodTuple.mAnnotationInfo.catchException); // Add the header signature to the header file. writeSignatureToHeader(headerSignature); @@ -111,19 +123,25 @@ public class CodeGenerator { writeMethodBody(implementationSignature, theMethod, mClassToWrap, aMethodTuple.mAnnotationInfo.isMultithreaded, aMethodTuple.mAnnotationInfo.noThrow, - aMethodTuple.mAnnotationInfo.narrowChars); + aMethodTuple.mAnnotationInfo.narrowChars, + aMethodTuple.mAnnotationInfo.catchException); } - private void generateGetterOrSetterBody(Class aFieldType, String aFieldName, boolean aIsFieldStatic, boolean isSetter, boolean aNarrowChars) { + private void generateGetterOrSetterBody(Field aField, String aFieldName, boolean aIsFieldStatic, boolean isSetter, boolean aNarrowChars) { StringBuilder argumentContent = null; + Class fieldType = aField.getType(); if (isSetter) { - Class[] setterArguments = new Class[]{aFieldType}; + Class[] setterArguments = new Class[]{fieldType}; // Marshall the argument.. argumentContent = getArgumentMarshalling(setterArguments); } - boolean isObjectReturningMethod = Utils.isObjectType(aFieldType); + if (mLazyInit) { + writeMemberInit(aField, wrapperMethodBodies); + } + + boolean isObjectReturningMethod = Utils.isObjectType(fieldType); wrapperMethodBodies.append(" "); if (isSetter) { wrapperMethodBodies.append("env->Set"); @@ -131,7 +149,7 @@ public class CodeGenerator { wrapperMethodBodies.append("return "); if (isObjectReturningMethod) { - wrapperMethodBodies.append("static_cast<").append(Utils.getCReturnType(aFieldType, aNarrowChars)).append(">("); + wrapperMethodBodies.append("static_cast<").append(Utils.getCReturnType(fieldType, aNarrowChars)).append(">("); } wrapperMethodBodies.append("env->Get"); @@ -140,7 +158,7 @@ public class CodeGenerator { if (aIsFieldStatic) { wrapperMethodBodies.append("Static"); } - wrapperMethodBodies.append(Utils.getFieldType(aFieldType)) + wrapperMethodBodies.append(Utils.getFieldType(fieldType)) .append("Field("); // Static will require the class and the field id. Nonstatic, the object and the field id. @@ -181,14 +199,14 @@ public class CodeGenerator { boolean isFieldFinal = Utils.isMemberFinal(theField); String getterName = "get" + CFieldName; - String getterSignature = Utils.getCImplementationMethodSignature(EMPTY_CLASS_ARRAY, fieldType, getterName, mCClassName, aFieldTuple.mAnnotationInfo.narrowChars); - String getterHeaderSignature = Utils.getCHeaderMethodSignature(EMPTY_CLASS_ARRAY, GETTER_ARGUMENT_ANNOTATIONS, fieldType, getterName, mCClassName, isFieldStatic, aFieldTuple.mAnnotationInfo.narrowChars); + String getterSignature = Utils.getCImplementationMethodSignature(EMPTY_CLASS_ARRAY, fieldType, getterName, mCClassName, aFieldTuple.mAnnotationInfo.narrowChars, false); + String getterHeaderSignature = Utils.getCHeaderMethodSignature(EMPTY_CLASS_ARRAY, GETTER_ARGUMENT_ANNOTATIONS, fieldType, getterName, mCClassName, isFieldStatic, aFieldTuple.mAnnotationInfo.narrowChars, false); writeSignatureToHeader(getterHeaderSignature); writeFunctionStartupBoilerPlate(getterSignature, true); - generateGetterOrSetterBody(fieldType, CFieldName, isFieldStatic, false, aFieldTuple.mAnnotationInfo.narrowChars); + generateGetterOrSetterBody(theField, CFieldName, isFieldStatic, false, aFieldTuple.mAnnotationInfo.narrowChars); // If field not final, also generate a setter function. if (!isFieldFinal) { @@ -196,14 +214,14 @@ public class CodeGenerator { Class[] setterArguments = new Class[]{fieldType}; - String setterSignature = Utils.getCImplementationMethodSignature(setterArguments, Void.class, setterName, mCClassName, aFieldTuple.mAnnotationInfo.narrowChars); - String setterHeaderSignature = Utils.getCHeaderMethodSignature(setterArguments, SETTER_ARGUMENT_ANNOTATIONS, Void.class, setterName, mCClassName, isFieldStatic, aFieldTuple.mAnnotationInfo.narrowChars); + String setterSignature = Utils.getCImplementationMethodSignature(setterArguments, Void.class, setterName, mCClassName, aFieldTuple.mAnnotationInfo.narrowChars, false); + String setterHeaderSignature = Utils.getCHeaderMethodSignature(setterArguments, SETTER_ARGUMENT_ANNOTATIONS, Void.class, setterName, mCClassName, isFieldStatic, aFieldTuple.mAnnotationInfo.narrowChars, false); writeSignatureToHeader(setterHeaderSignature); writeFunctionStartupBoilerPlate(setterSignature, true); - generateGetterOrSetterBody(fieldType, CFieldName, isFieldStatic, true, aFieldTuple.mAnnotationInfo.narrowChars); + generateGetterOrSetterBody(theField, CFieldName, isFieldStatic, true, aFieldTuple.mAnnotationInfo.narrowChars); } } @@ -214,8 +232,10 @@ public class CodeGenerator { generateMemberCommon(theCtor, mCClassName, mClassToWrap); - String implementationSignature = Utils.getCImplementationMethodSignature(theCtor.getParameterTypes(), Void.class, CMethodName, mCClassName, aCtorTuple.mAnnotationInfo.narrowChars); - String headerSignature = Utils.getCHeaderMethodSignature(theCtor.getParameterTypes(), theCtor.getParameterAnnotations(), Void.class, CMethodName, mCClassName, false, aCtorTuple.mAnnotationInfo.narrowChars); + String implementationSignature = Utils.getCImplementationMethodSignature(theCtor.getParameterTypes(), Void.class, CMethodName, + mCClassName, aCtorTuple.mAnnotationInfo.narrowChars, aCtorTuple.mAnnotationInfo.catchException); + String headerSignature = Utils.getCHeaderMethodSignature(theCtor.getParameterTypes(), theCtor.getParameterAnnotations(), Void.class, CMethodName, + mCClassName, false, aCtorTuple.mAnnotationInfo.narrowChars, aCtorTuple.mAnnotationInfo.catchException); // Slice off the "void " from the start of the constructor declaration. headerSignature = headerSignature.substring(5); @@ -227,13 +247,37 @@ public class CodeGenerator { // Use the implementation signature to generate the method body... writeCtorBody(implementationSignature, theCtor, aCtorTuple.mAnnotationInfo.isMultithreaded, - aCtorTuple.mAnnotationInfo.noThrow); + aCtorTuple.mAnnotationInfo.noThrow, + aCtorTuple.mAnnotationInfo.catchException); if (theCtor.getParameterTypes().length == 0) { mHasEncounteredDefaultConstructor = true; } } + public void generateMembers(Member[] members) { + for (Member m : members) { + if (!Modifier.isPublic(m.getModifiers())) { + continue; + } + + String name = m.getName(); + name = name.substring(0, 1).toUpperCase() + name.substring(1); + + AnnotationInfo info = new AnnotationInfo(name, true, true, true, true); + AnnotatableEntity entity = new AnnotatableEntity(m, info); + if (m instanceof Constructor) { + generateConstructor(entity); + } else if (m instanceof Method) { + generateMethod(entity); + } else if (m instanceof Field) { + generateField(entity); + } else { + throw new IllegalArgumentException("expected member to be Constructor, Method, or Field"); + } + } + } + /** * Writes the appropriate header and startup code to ensure the existence of a reference to the * class specified. If this is already done, does nothing. @@ -258,8 +302,7 @@ public class CodeGenerator { .append(";\n"); // Add startup code to populate it.. - wrapperStartupCode.append('\n') - .append(Utils.getStartupLineForClass(aClass)); + wrapperStartupCode.append(Utils.getStartupLineForClass(aClass)); seenClasses.add(className); } @@ -371,14 +414,30 @@ public class CodeGenerator { return argumentContent; } + private void writeCatchException() { + wrapperMethodBodies.append( + " if (env->ExceptionCheck()) {\n" + + " env->ExceptionClear();\n" + + " if (aResult) {\n" + + " *aResult = NS_ERROR_FAILURE;\n" + + " }\n" + + " } else if (aResult) {\n" + + " *aResult = NS_OK;\n" + + " }\n\n"); + } + private void writeCtorBody(String implementationSignature, Constructor theCtor, - boolean aIsThreaded, boolean aNoThrow) { + boolean aIsThreaded, boolean aNoThrow, boolean aCatchException) { Class[] argumentTypes = theCtor.getParameterTypes(); writeFunctionStartupBoilerPlate(implementationSignature, aIsThreaded); writeFramePushBoilerplate(theCtor, false, aNoThrow); + if (mLazyInit) { + writeMemberInit(theCtor, wrapperMethodBodies); + } + // Marshall arguments for this constructor, if any... boolean hasArguments = argumentTypes.length != 0; @@ -402,9 +461,14 @@ public class CodeGenerator { wrapperMethodBodies.append(mMembersToIds.get(theCtor)) // Tack on the arguments, if any.. .append(argumentContent) - .append("), env);\n" + - " env->PopLocalFrame(nullptr);\n" + - "}\n"); + .append("), env);\n"); + + // Check for exception and set aResult + if (aCatchException) { + writeCatchException(); + } + + wrapperMethodBodies.append(" env->PopLocalFrame(nullptr);\n}\n"); } /** @@ -417,7 +481,8 @@ public class CodeGenerator { */ private void writeMethodBody(String methodSignature, Method aMethod, Class aClass, boolean aIsMultithreaded, - boolean aNoThrow, boolean aNarrowChars) { + boolean aNoThrow, boolean aNarrowChars, + boolean aCatchException) { Class[] argumentTypes = aMethod.getParameterTypes(); Class returnType = aMethod.getReturnType(); @@ -427,6 +492,10 @@ public class CodeGenerator { writeFramePushBoilerplate(aMethod, isObjectReturningMethod, aNoThrow); + if (mLazyInit) { + writeMemberInit(aMethod, wrapperMethodBodies); + } + // Marshall arguments, if we have any. boolean hasArguments = argumentTypes.length != 0; @@ -481,6 +550,11 @@ public class CodeGenerator { wrapperMethodBodies.append(" AndroidBridge::HandleUncaughtException(env);\n"); } + // Check for exception and set aResult + if (aCatchException) { + writeCatchException(); + } + // If we're returning an object, pop the callee's stack frame extracting our ref as the return // value. if (isObjectReturningMethod) { @@ -501,33 +575,41 @@ public class CodeGenerator { } /** - * Generates the code to get the id of the given member on startup. + * Generates the code to get the id of the given member on startup or in the member body if lazy init + * is requested. * * @param aMember The Java member being wrapped. */ - private void writeStartupCode(Member aMember) { - wrapperStartupCode.append(" ") - .append(mMembersToIds.get(aMember)) - .append(" = get"); + private void writeMemberInit(Member aMember, StringBuilder aOutput) { + if (mLazyInit) { + aOutput.append(" if (!" + mMembersToIds.get(aMember) + ") {\n "); + } + + aOutput.append(" " + mMembersToIds.get(aMember)).append(" = AndroidBridge::Get"); if (Utils.isMemberStatic(aMember)) { - wrapperStartupCode.append("Static"); + aOutput.append("Static"); } boolean isField = aMember instanceof Field; if (isField) { - wrapperStartupCode.append("Field(\""); + aOutput.append("FieldID(env, " + Utils.getClassReferenceName(aMember.getDeclaringClass()) + ", \""); } else { - wrapperStartupCode.append("Method(\""); - } - if (aMember instanceof Constructor) { - wrapperStartupCode.append(""); - } else { - wrapperStartupCode.append(aMember.getName()); + aOutput.append("MethodID(env, " + Utils.getClassReferenceName(aMember.getDeclaringClass()) + ", \""); } - wrapperStartupCode.append("\", \"") + if (aMember instanceof Constructor) { + aOutput.append(""); + } else { + aOutput.append(aMember.getName()); + } + + aOutput.append("\", \"") .append(Utils.getTypeSignatureStringForMember(aMember)) .append("\");\n"); + + if (mLazyInit) { + aOutput.append(" }\n\n"); + } } private void writeZeroingFor(Member aMember, final String aMemberName) { diff --git a/build/annotationProcessors/Makefile.in b/build/annotationProcessors/Makefile.in index c7661c36fd5f..b21a52bbd1ff 100644 --- a/build/annotationProcessors/Makefile.in +++ b/build/annotationProcessors/Makefile.in @@ -4,9 +4,9 @@ include $(topsrcdir)/config/rules.mk -JAVA_CLASSPATH := $(ANDROID_SDK)/android.jar +JAVA_CLASSPATH := $(ANDROID_SDK)/android.jar:$(ANDROID_SDK)/../../tools/lib/lint.jar:$(ANDROID_SDK)/../../tools/lib/lint-checks.jar # Include Android specific java flags, instead of what's in rules.mk. include $(topsrcdir)/config/android-common.mk -libs:: annotationProcessors.jar +export:: annotationProcessors.jar diff --git a/build/annotationProcessors/SDKProcessor.java b/build/annotationProcessors/SDKProcessor.java new file mode 100644 index 000000000000..2eab460468a8 --- /dev/null +++ b/build/annotationProcessors/SDKProcessor.java @@ -0,0 +1,255 @@ +/* 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/. */ + +package org.mozilla.gecko.annotationProcessors; + +import com.android.tools.lint.checks.ApiLookup; +import com.android.tools.lint.LintCliClient; + +import org.mozilla.gecko.annotationProcessors.classloader.AnnotatableEntity; +import org.mozilla.gecko.annotationProcessors.classloader.ClassWithOptions; +import org.mozilla.gecko.annotationProcessors.classloader.IterableJarLoadingURLClassLoader; +import org.mozilla.gecko.annotationProcessors.utils.GeneratableElementIterator; +import org.mozilla.gecko.annotationProcessors.utils.Utils; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.Iterator; +import java.util.Properties; +import java.util.Scanner; +import java.util.Vector; +import java.net.URL; +import java.net.URLClassLoader; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Member; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +public class SDKProcessor { + public static final String GENERATED_COMMENT = + "// GENERATED CODE\n" + + "// Generated by the Java program at /build/annotationProcessors at compile time from\n" + + "// annotations on Java methods. To update, change the annotations on the corresponding Java\n" + + "// methods and rerun the build. Manually updating this file will cause your build to fail.\n\n"; + + private static ApiLookup sApiLookup; + private static int sMaxSdkVersion; + + public static void main(String[] args) { + // We expect a list of jars on the commandline. If missing, whinge about it. + if (args.length < 5) { + System.err.println("Usage: java SDKProcessor sdkjar classlistfile outdir fileprefix max-sdk-version"); + System.exit(1); + } + + System.out.println("Processing platform bindings..."); + + String sdkJar = args[0]; + Vector classes = getClassList(args[1]); + String outdir = args[2]; + String generatedFilePrefix = args[3]; + sMaxSdkVersion = Integer.parseInt(args[4]); + + Properties props = System.getProperties(); + props.setProperty("com.android.tools.lint.bindir", + new File(new File(sdkJar).getParentFile(), "../../tools").toString()); + + LintCliClient lintClient = new LintCliClient(); + sApiLookup = ApiLookup.get(lintClient); + + // Start the clock! + long s = System.currentTimeMillis(); + + // Get an iterator over the classes in the jar files given... + // Iterator jarClassIterator = IterableJarLoadingURLClassLoader.getIteratorOverJars(args); + + StringBuilder headerFile = new StringBuilder(GENERATED_COMMENT); + headerFile.append("#ifndef " + generatedFilePrefix + "_h__\n" + + "#define " + generatedFilePrefix + "_h__\n" + + "#include \"nsXPCOMStrings.h\"\n" + + "#include \"AndroidJavaWrappers.h\"\n" + + "\n" + + "namespace mozilla {\n" + + "namespace widget {\n" + + "namespace android {\n" + + "namespace sdk {\n" + + "void Init" + generatedFilePrefix + "Stubs(JNIEnv *jEnv);\n\n"); + + StringBuilder implementationFile = new StringBuilder(GENERATED_COMMENT); + implementationFile.append("#include \"" + generatedFilePrefix + ".h\"\n" + + "#include \"AndroidBridgeUtilities.h\"\n" + + "#include \"nsXPCOMStrings.h\"\n" + + "#include \"AndroidBridge.h\"\n" + + "\n" + + "namespace mozilla {\n" + + "namespace widget {\n" + + "namespace android {\n" + + "namespace sdk {\n"); + + // Used to track the calls to the various class-specific initialisation functions. + StringBuilder stubInitializer = new StringBuilder(); + stubInitializer.append("void Init" + generatedFilePrefix + "Stubs(JNIEnv *jEnv) {\n"); + + ClassLoader loader = null; + try { + loader = URLClassLoader.newInstance(new URL[] { new URL("file://" + sdkJar) }, + SDKProcessor.class.getClassLoader()); + } catch (Exception e) { + System.out.println(e); + } + + for (Iterator i = classes.iterator(); i.hasNext(); ) { + String className = i.next(); + System.out.println("Looking up: " + className); + + try { + Class c = Class.forName(className, true, loader); + + generateClass(Class.forName(className, true, loader), + stubInitializer, + implementationFile, + headerFile); + } catch (Exception e) { + System.out.println("Failed to generate class " + className + ": " + e); + } + } + + implementationFile.append('\n'); + stubInitializer.append("}"); + implementationFile.append(stubInitializer); + + implementationFile.append("\n} /* sdk */\n" + + "} /* android */\n" + + "} /* widget */\n" + + "} /* mozilla */\n"); + + headerFile.append("\n} /* sdk */\n" + + "} /* android */\n" + + "} /* widget */\n" + + "} /* mozilla */\n" + + "#endif\n"); + + writeOutputFiles(outdir, generatedFilePrefix, headerFile, implementationFile); + long e = System.currentTimeMillis(); + System.out.println("SDK processing complete in " + (e - s) + "ms"); + } + + private static Member[] sortAndFilterMembers(Member[] members) { + Arrays.sort(members, new Comparator() { + @Override + public int compare(Member a, Member b) { + return a.getName().compareTo(b.getName()); + } + }); + + ArrayList list = new ArrayList<>(); + for (Member m : members) { + int version = 0; + + if (m instanceof Method || m instanceof Constructor) { + version = sApiLookup.getCallVersion(Utils.getTypeSignatureStringForClass(m.getDeclaringClass()), + m.getName(), + Utils.getTypeSignatureStringForMember(m)); + } else if (m instanceof Field) { + version = sApiLookup.getFieldVersion(Utils.getTypeSignatureStringForClass(m.getDeclaringClass()), + m.getName()); + } else { + throw new IllegalArgumentException("expected member to be Method, Constructor, or Field"); + } + + if (version > sMaxSdkVersion) { + System.out.println("Skipping " + m.getDeclaringClass().getName() + "." + m.getName() + + ", version " + version + " > " + sMaxSdkVersion); + continue; + } + + list.add(m); + } + + return list.toArray(new Member[list.size()]); + } + + private static void generateClass(Class clazz, + StringBuilder stubInitializer, + StringBuilder implementationFile, + StringBuilder headerFile) { + String generatedName = clazz.getSimpleName(); + + CodeGenerator generator = new CodeGenerator(clazz, generatedName, true); + stubInitializer.append(" ").append(generatedName).append("::InitStubs(jEnv);\n"); + + generator.generateMembers(sortAndFilterMembers(clazz.getDeclaredConstructors())); + generator.generateMembers(sortAndFilterMembers(clazz.getDeclaredMethods())); + generator.generateMembers(sortAndFilterMembers(clazz.getDeclaredFields())); + + headerFile.append(generator.getHeaderFileContents()); + implementationFile.append(generator.getWrapperFileContents()); + } + + private static Vector getClassList(String path) { + Scanner scanner = null; + try { + scanner = new Scanner(new FileInputStream(path)); + + Vector lines = new Vector(); + while (scanner.hasNextLine()) { + lines.add(scanner.nextLine()); + } + return lines; + } catch (Exception e) { + System.out.println(e.toString()); + return null; + } finally { + if (scanner != null) { + scanner.close(); + } + } + } + + private static void writeOutputFiles(String aOutputDir, String aPrefix, StringBuilder aHeaderFile, + StringBuilder aImplementationFile) { + FileOutputStream implStream = null; + try { + implStream = new FileOutputStream(new File(aOutputDir, aPrefix + ".cpp")); + implStream.write(aImplementationFile.toString().getBytes()); + } catch (IOException e) { + System.err.println("Unable to write " + aOutputDir + ". Perhaps a permissions issue?"); + e.printStackTrace(System.err); + } finally { + if (implStream != null) { + try { + implStream.close(); + } catch (IOException e) { + System.err.println("Unable to close implStream due to "+e); + e.printStackTrace(System.err); + } + } + } + + FileOutputStream headerStream = null; + try { + headerStream = new FileOutputStream(new File(aOutputDir, aPrefix + ".h")); + headerStream.write(aHeaderFile.toString().getBytes()); + } catch (IOException e) { + System.err.println("Unable to write " + aOutputDir + ". Perhaps a permissions issue?"); + e.printStackTrace(System.err); + } finally { + if (headerStream != null) { + try { + headerStream.close(); + } catch (IOException e) { + System.err.println("Unable to close headerStream due to "+e); + e.printStackTrace(System.err); + } + } + } + } +} \ No newline at end of file diff --git a/build/annotationProcessors/moz.build b/build/annotationProcessors/moz.build index 1fbf9938518e..c8e0fb8bdcfe 100644 --- a/build/annotationProcessors/moz.build +++ b/build/annotationProcessors/moz.build @@ -13,6 +13,7 @@ jar.sources += [ 'classloader/IterableJarLoadingURLClassLoader.java', 'classloader/JarClassIterator.java', 'CodeGenerator.java', + 'SDKProcessor.java', 'utils/AlphabeticAnnotatableEntityComparator.java', 'utils/GeneratableElementIterator.java', 'utils/Utils.java', diff --git a/build/annotationProcessors/utils/GeneratableElementIterator.java b/build/annotationProcessors/utils/GeneratableElementIterator.java index 6e7b1349fbb1..32dd2b963e05 100644 --- a/build/annotationProcessors/utils/GeneratableElementIterator.java +++ b/build/annotationProcessors/utils/GeneratableElementIterator.java @@ -76,6 +76,7 @@ public class GeneratableElementIterator implements Iterator { boolean isMultithreadedStub = false; boolean noThrow = false; boolean narrowChars = false; + boolean catchException = false; try { // Determine the explicitly-given name of the stub to generate, if any. final Method stubNameMethod = annotationType.getDeclaredMethod("stubName"); @@ -97,6 +98,11 @@ public class GeneratableElementIterator implements Iterator { narrowCharsMethod.setAccessible(true); narrowChars = (Boolean) narrowCharsMethod.invoke(annotation); + // Determine if we should catch exceptions + final Method catchExceptionMethod = annotationType.getDeclaredMethod("catchException"); + catchExceptionMethod.setAccessible(true); + catchException = (Boolean) catchExceptionMethod.invoke(annotation); + } catch (NoSuchMethodException e) { System.err.println("Unable to find expected field on WrapElementForJNI annotation. Did the signature change?"); e.printStackTrace(System.err); @@ -118,7 +124,7 @@ public class GeneratableElementIterator implements Iterator { } AnnotationInfo annotationInfo = new AnnotationInfo( - stubName, isMultithreadedStub, noThrow, narrowChars); + stubName, isMultithreadedStub, noThrow, narrowChars, catchException); mNextReturnValue = new AnnotatableEntity(candidateElement, annotationInfo); return; } @@ -128,7 +134,7 @@ public class GeneratableElementIterator implements Iterator { // thanks to the "Generate everything" annotation. if (mIterateEveryEntry) { AnnotationInfo annotationInfo = new AnnotationInfo( - candidateElement.getName(), false, false, false); + candidateElement.getName(), false, false, false, false); mNextReturnValue = new AnnotatableEntity(candidateElement, annotationInfo); return; } diff --git a/build/annotationProcessors/utils/Utils.java b/build/annotationProcessors/utils/Utils.java index f13ae66e1461..44876ebb4b99 100644 --- a/build/annotationProcessors/utils/Utils.java +++ b/build/annotationProcessors/utils/Utils.java @@ -318,6 +318,10 @@ public class Utils { } } + public static String getTypeSignatureStringForClass(Class clazz) { + return clazz.getCanonicalName().replace('.', '/'); + } + public static String getTypeSignatureString(Constructor aConstructor) { Class[] arguments = aConstructor.getParameterTypes(); StringBuilder sb = new StringBuilder(); @@ -341,7 +345,7 @@ public class Utils { * @param c The type of the element to write the subsignature of. */ private static void writeTypeSignature(StringBuilder sb, Class c) { - String name = c.getCanonicalName().replaceAll("\\.", "/"); + String name = Utils.getTypeSignatureStringForClass(c); // Determine if this is an array type and, if so, peel away the array operators.. int len = name.length(); @@ -384,7 +388,8 @@ public class Utils { * @param aCClassName Name of the C++ class into which the method is declared. * @return The C++ method implementation signature for the method described. */ - public static String getCImplementationMethodSignature(Class[] aArgumentTypes, Class aReturnType, String aCMethodName, String aCClassName, boolean aNarrowChars) { + public static String getCImplementationMethodSignature(Class[] aArgumentTypes, Class aReturnType, + String aCMethodName, String aCClassName, boolean aNarrowChars, boolean aCatchException) { StringBuilder retBuffer = new StringBuilder(); retBuffer.append(getCReturnType(aReturnType, aNarrowChars)); @@ -406,6 +411,14 @@ public class Utils { retBuffer.append(", "); } } + + if (aCatchException) { + if (aArgumentTypes.length > 0) { + retBuffer.append(", "); + } + retBuffer.append("nsresult* aResult"); + } + retBuffer.append(')'); return retBuffer.toString(); } @@ -423,7 +436,8 @@ public class Utils { * @param aIsStaticStub true if the generated C++ method should be static, false otherwise. * @return The generated C++ header method signature for the method described. */ - public static String getCHeaderMethodSignature(Class[] aArgumentTypes, Annotation[][] aArgumentAnnotations, Class aReturnType, String aCMethodName, String aCClassName, boolean aIsStaticStub, boolean aNarrowChars) { + public static String getCHeaderMethodSignature(Class[] aArgumentTypes, Annotation[][] aArgumentAnnotations, Class aReturnType, + String aCMethodName, String aCClassName, boolean aIsStaticStub, boolean aNarrowChars, boolean aCatchException) { StringBuilder retBuffer = new StringBuilder(); // Add the static keyword, if applicable. @@ -453,6 +467,14 @@ public class Utils { retBuffer.append(", "); } } + + if (aCatchException) { + if (aArgumentTypes.length > 0) { + retBuffer.append(", "); + } + retBuffer.append("nsresult* aResult = nullptr"); + } + retBuffer.append(')'); return retBuffer.toString(); } @@ -587,9 +609,9 @@ public class Utils { StringBuilder sb = new StringBuilder(); sb.append(" "); sb.append(getClassReferenceName(aClass)); - sb.append(" = getClassGlobalRef(\""); + sb.append(" = AndroidBridge::GetClassGlobalRef(env, \""); - String name = aClass.getCanonicalName().replaceAll("\\.", "/"); + String name = Utils.getTypeSignatureStringForClass(aClass); Class containerClass = aClass.getDeclaringClass(); if (containerClass != null) { // Is an inner class. Add the $ symbol. diff --git a/config/recurse.mk b/config/recurse.mk index e22dde964d84..d073a7dad419 100644 --- a/config/recurse.mk +++ b/config/recurse.mk @@ -141,6 +141,10 @@ ifeq (.,$(DEPTH)) # Interdependencies for parallel export. js/xpconnect/src/export: dom/bindings/export xpcom/xpidl/export accessible/xpcom/export: xpcom/xpidl/export + +# The widget binding generator code is part of the annotationProcessors. +widget/android/bindings/export: build/annotationProcessors/export + ifdef ENABLE_CLANG_PLUGIN $(filter-out build/clang-plugin/%,$(compile_targets)): build/clang-plugin/target build/clang-plugin/tests/target build/clang-plugin/tests/target: build/clang-plugin/target diff --git a/configure.in b/configure.in index ff95391b1ce7..94d136bb1e7b 100644 --- a/configure.in +++ b/configure.in @@ -1459,6 +1459,7 @@ if test "$GNU_CC"; then # -Wignored-qualifiers - catches returns types with qualifiers like const # -Wint-to-pointer-cast - catches cast to pointer from integer of different size # -Wmultichar - catches multicharacter integer constants like 'THIS' + # -Wnon-literal-null-conversion - catches expressions used as a null pointer constant # -Wnonnull - catches NULL used with functions arguments marked as non-null # -Wpointer-arith - catches pointer arithmetic using NULL or sizeof(void) # -Wpointer-sign - catches mixing pointers to signed and unsigned types @@ -1493,6 +1494,8 @@ if test "$GNU_CC"; then _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=sequence-point" _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=trigraphs" _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=unknown-pragmas" + + MOZ_C_SUPPORTS_WARNING(-Werror=, non-literal-null-conversion, ac_c_has_werror_non_literal_null_conversion) fi # Turn off the following warnings that -Wall turns on: @@ -1552,6 +1555,7 @@ if test "$GNU_CXX"; then # -Wendif-labels - catches `#else FOO` and `#endif FOO` not in comment # -Wint-to-pointer-cast - catches cast to pointer from integer of different size # -Wmissing-braces - catches aggregate initializers missing nested braces + # -Wnon-literal-null-conversion - catches expressions used as a null pointer constant # -Woverloaded-virtual - function declaration hides virtual function from base class # -Wparentheses - catches `if (a=b)` and operator precedence bugs # -Wpointer-arith - catches pointer arithmetic using NULL or sizeof(void) @@ -1583,6 +1587,8 @@ if test "$GNU_CXX"; then _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=trigraphs" _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=type-limits" _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=unused-label" + + MOZ_CXX_SUPPORTS_WARNING(-Werror=, non-literal-null-conversion, ac_cxx_has_werror_non_literal_null_conversion) fi # Turn off the following warnings that -Wall turns on: diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 72f3aa402e59..b01916c47131 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -854,7 +854,8 @@ nsDocShell::nsDocShell(): mDefaultLoadFlags(nsIRequest::LOAD_NORMAL), mFrameType(eFrameTypeRegular), mOwnOrContainingAppId(nsIScriptSecurityManager::UNKNOWN_APP_ID), - mParentCharsetSource(0) + mParentCharsetSource(0), + mJSRunToCompletionDepth(0) { mHistoryID = ++gDocshellIDCounter; if (gDocShellCount++ == 0) { @@ -890,6 +891,8 @@ nsDocShell::nsDocShell(): nsDocShell::~nsDocShell() { + MOZ_ASSERT(!mProfileTimelineRecording); + Destroy(); nsCOMPtr @@ -2829,14 +2832,15 @@ NS_IMETHODIMP nsDocShell::SetRecordProfileTimelineMarkers(bool aValue) { #ifdef MOZ_ENABLE_PROFILER_SPS - bool currentValue; - GetRecordProfileTimelineMarkers(¤tValue); + bool currentValue = nsIDocShell::GetRecordProfileTimelineMarkers(); if (currentValue != aValue) { if (aValue) { ++gProfileTimelineRecordingsCount; + UseEntryScriptProfiling(); mProfileTimelineRecording = true; } else { --gProfileTimelineRecordingsCount; + UnuseEntryScriptProfiling(); mProfileTimelineRecording = false; ClearProfileTimelineMarkers(); } @@ -4243,15 +4247,17 @@ nsDocShell::AddChildSHEntry(nsISHEntry * aCloneRef, nsISHEntry * aNewEntry, int32_t aChildOffset, uint32_t loadType, bool aCloneChildren) { - nsresult rv; + nsresult rv = NS_OK; - if (mLSHE && loadType != LOAD_PUSHSTATE && !aCloneRef) { + if (mLSHE && loadType != LOAD_PUSHSTATE) { /* You get here if you are currently building a * hierarchy ie.,you just visited a frameset page */ nsCOMPtr container(do_QueryInterface(mLSHE, &rv)); if (container) { - rv = container->AddChild(aNewEntry, aChildOffset); + if (NS_FAILED(container->ReplaceChild(aNewEntry))) { + rv = container->AddChild(aNewEntry, aChildOffset); + } } } else if (!aCloneRef) { @@ -4260,8 +4266,22 @@ nsDocShell::AddChildSHEntry(nsISHEntry * aCloneRef, nsISHEntry * aNewEntry, if (container) { rv = container->AddChild(aNewEntry, aChildOffset); } + } else { + rv = AddChildSHEntryInternal(aCloneRef, aNewEntry, aChildOffset, + loadType, aCloneChildren); } - else if (mSessionHistory) { + return rv; +} + +nsresult +nsDocShell::AddChildSHEntryInternal(nsISHEntry* aCloneRef, + nsISHEntry* aNewEntry, + int32_t aChildOffset, + uint32_t aLoadType, + bool aCloneChildren) +{ + nsresult rv = NS_OK; + if (mSessionHistory) { /* You are currently in the rootDocShell. * You will get here when a subframe has a new url * to load and you have walked up the tree all the @@ -4300,16 +4320,17 @@ nsDocShell::AddChildSHEntry(nsISHEntry * aCloneRef, nsISHEntry * aNewEntry, nsCOMPtr parent = do_QueryInterface(GetAsSupports(mParent), &rv); if (parent) { - rv = parent->AddChildSHEntry(aCloneRef, aNewEntry, aChildOffset, - loadType, aCloneChildren); - } + rv = static_cast(parent.get())-> + AddChildSHEntryInternal(aCloneRef, aNewEntry, aChildOffset, + aLoadType, aCloneChildren); + } } return rv; } nsresult -nsDocShell::DoAddChildSHEntry(nsISHEntry* aNewEntry, int32_t aChildOffset, - bool aCloneChildren) +nsDocShell::AddChildSHEntryToParent(nsISHEntry* aNewEntry, int32_t aChildOffset, + bool aCloneChildren) { /* You will get here when you are in a subframe and * a new url has been loaded on you. @@ -11653,7 +11674,7 @@ nsDocShell::AddToSessionHistory(nsIURI * aURI, nsIChannel * aChannel, // This is a subframe. if (!mOSHE || !LOAD_TYPE_HAS_FLAGS(mLoadType, LOAD_FLAGS_REPLACE_HISTORY)) - rv = DoAddChildSHEntry(entry, mChildOffset, aCloneChildren); + rv = AddChildSHEntryToParent(entry, mChildOffset, aCloneChildren); } // Return the new SH entry... @@ -13591,6 +13612,30 @@ nsDocShell::GetURLSearchParams() return mURLSearchParams; } +void +nsDocShell::NotifyJSRunToCompletionStart() +{ + bool timelineOn = nsIDocShell::GetRecordProfileTimelineMarkers(); + + // If first start, mark interval start. + if (timelineOn && mJSRunToCompletionDepth == 0) { + AddProfileTimelineMarker("Javascript", TRACING_INTERVAL_START); + } + mJSRunToCompletionDepth++; +} + +void +nsDocShell::NotifyJSRunToCompletionStop() +{ + bool timelineOn = nsIDocShell::GetRecordProfileTimelineMarkers(); + + // If last stop, mark interval end. + mJSRunToCompletionDepth--; + if (timelineOn && mJSRunToCompletionDepth == 0) { + AddProfileTimelineMarker("Javascript", TRACING_INTERVAL_END); + } +} + void nsDocShell::MaybeNotifyKeywordSearchLoading(const nsString &aProvider, const nsString &aKeyword) { diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index 44689ff5d7e2..8ce9b1fec820 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -371,8 +371,12 @@ protected: nsISupports* aOwner, bool aCloneChildren, nsISHEntry ** aNewEntry); - nsresult DoAddChildSHEntry(nsISHEntry* aNewEntry, int32_t aChildOffset, - bool aCloneChildren); + nsresult AddChildSHEntryToParent(nsISHEntry* aNewEntry, int32_t aChildOffset, + bool aCloneChildren); + + nsresult AddChildSHEntryInternal(nsISHEntry* aCloneRef, nsISHEntry* aNewEntry, + int32_t aChildOffset, uint32_t loadType, + bool aCloneChildren); NS_IMETHOD LoadHistoryEntry(nsISHEntry * aEntry, uint32_t aLoadType); NS_IMETHOD PersistLayoutHistoryState(); @@ -946,6 +950,10 @@ private: nsWeakPtr mOpener; nsWeakPtr mOpenedRemote; + // A depth count of how many times NotifyRunToCompletionStart + // has been called without a matching NotifyRunToCompletionStop. + uint32_t mJSRunToCompletionDepth; + // True if recording profiles. bool mProfileTimelineRecording; diff --git a/docshell/base/nsIDocShell.idl b/docshell/base/nsIDocShell.idl index 4aaa717d0837..23cd7096512e 100644 --- a/docshell/base/nsIDocShell.idl +++ b/docshell/base/nsIDocShell.idl @@ -54,7 +54,7 @@ interface nsITabParent; typedef unsigned long nsLoadFlags; -[scriptable, builtinclass, uuid(da8f78f1-8f20-4d6d-be56-fe53e177b630)] +[scriptable, builtinclass, uuid(4e3de242-0b2a-4cf0-81b5-a5fe8628431c)] interface nsIDocShell : nsIDocShellTreeItem { /** @@ -1026,6 +1026,14 @@ interface nsIDocShell : nsIDocShellTreeItem // URLSearchParams for the window.location is owned by the docShell. [noscript,notxpcom] URLSearchParams getURLSearchParams(); + /** + * Notify DocShell when the browser is about to start executing JS, and after + * that execution has stopped. This only occurs when the Timeline devtool + * is collecting information. + */ + [noscript,notxpcom,nostdcall] void notifyJSRunToCompletionStart(); + [noscript,notxpcom,nostdcall] void notifyJSRunToCompletionStop(); + /** * This attribute determines whether a document which is not about:blank has * already be loaded by this docShell. diff --git a/docshell/shistory/public/nsISHContainer.idl b/docshell/shistory/public/nsISHContainer.idl index a9555eca4730..942603d87991 100644 --- a/docshell/shistory/public/nsISHContainer.idl +++ b/docshell/shistory/public/nsISHContainer.idl @@ -14,7 +14,7 @@ interface nsISHEntry; * */ -[scriptable, uuid(65281BA2-988A-11d3-BDC7-0050040A9B44)] +[scriptable, uuid(67dd0357-8372-4122-bff6-217435e8b7e4)] interface nsISHContainer : nsISupports { /** @@ -38,5 +38,12 @@ interface nsISHContainer : nsISupports */ nsISHEntry GetChildAt(in long index); + /** + * Replaces a child which is for the same docshell as aNewChild + * with aNewChild. + * @throw if nothing was replaced. + */ + void ReplaceChild(in nsISHEntry aNewChild); + }; diff --git a/docshell/shistory/src/nsSHEntry.cpp b/docshell/shistory/src/nsSHEntry.cpp index 8e52757359fc..b3bedb1c666b 100644 --- a/docshell/shistory/src/nsSHEntry.cpp +++ b/docshell/shistory/src/nsSHEntry.cpp @@ -690,6 +690,27 @@ nsSHEntry::GetChildAt(int32_t aIndex, nsISHEntry ** aResult) return NS_OK; } +NS_IMETHODIMP +nsSHEntry::ReplaceChild(nsISHEntry* aNewEntry) +{ + NS_ENSURE_STATE(aNewEntry); + + uint64_t docshellID; + aNewEntry->GetDocshellID(&docshellID); + + uint64_t otherID; + for (int32_t i = 0; i < mChildren.Count(); ++i) { + if (mChildren[i] && NS_SUCCEEDED(mChildren[i]->GetDocshellID(&otherID)) && + docshellID == otherID) { + mChildren[i]->SetParent(nullptr); + if (mChildren.ReplaceObjectAt(aNewEntry, i)) { + return aNewEntry->SetParent(this); + } + } + } + return NS_ERROR_FAILURE; +} + NS_IMETHODIMP nsSHEntry::AddChildShell(nsIDocShellTreeItem *aShell) { diff --git a/docshell/test/navigation/file_nested_frames.html b/docshell/test/navigation/file_nested_frames.html new file mode 100644 index 000000000000..f65d8e01b4a9 --- /dev/null +++ b/docshell/test/navigation/file_nested_frames.html @@ -0,0 +1,28 @@ + + + + + + + + + diff --git a/docshell/test/navigation/mochitest.ini b/docshell/test/navigation/mochitest.ini index ad906f146aae..8ba6855cba23 100644 --- a/docshell/test/navigation/mochitest.ini +++ b/docshell/test/navigation/mochitest.ini @@ -9,6 +9,7 @@ support-files = file_bug534178.html file_document_write_1.html file_fragment_handling_during_load.html + file_nested_frames.html file_static_and_dynamic_1.html frame0.html frame1.html diff --git a/docshell/test/navigation/test_sessionhistory.html b/docshell/test/navigation/test_sessionhistory.html index 013151f8bb9f..2d2b1b43b137 100644 --- a/docshell/test/navigation/test_sessionhistory.html +++ b/docshell/test/navigation/test_sessionhistory.html @@ -27,7 +27,8 @@ var testFiles = "file_document_write_1.html", // Session history + document.write //"file_static_and_dynamic_1.html",// Static and dynamic frames and forward-back "file_bug534178.html", // Session history transaction clean-up. - "file_fragment_handling_during_load.html" + "file_fragment_handling_during_load.html", + "file_nested_frames.html" ]; var testCount = 0; // Used by the test files. diff --git a/dom/base/ScriptSettings.cpp b/dom/base/ScriptSettings.cpp index d7c26096da1c..550b25148c5f 100644 --- a/dom/base/ScriptSettings.cpp +++ b/dom/base/ScriptSettings.cpp @@ -12,6 +12,7 @@ #include "xpcprivate.h" // For AutoCxPusher guts #include "xpcpublic.h" #include "nsIGlobalObject.h" +#include "nsIDocShell.h" #include "nsIScriptGlobalObject.h" #include "nsIScriptContext.h" #include "nsContentUtils.h" @@ -70,8 +71,26 @@ public: ScriptSettingsStackEntry *entry = EntryPoint(); return entry ? entry->mGlobalObject : nullptr; } + }; +static unsigned long gRunToCompletionListeners = 0; + +void +UseEntryScriptProfiling() +{ + MOZ_ASSERT(NS_IsMainThread()); + ++gRunToCompletionListeners; +} + +void +UnuseEntryScriptProfiling() +{ + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(gRunToCompletionListeners > 0); + --gRunToCompletionListeners; +} + void InitScriptSettings() { @@ -122,10 +141,44 @@ ScriptSettingsStackEntry::~ScriptSettingsStackEntry() ScriptSettingsStack::Pop(this); } +// If the entry or incumbent global ends up being something that the subject +// principal doesn't subsume, we don't want to use it. This never happens on +// the web, but can happen with asymmetric privilege relationships (i.e. +// nsExpandedPrincipal and System Principal). +// +// The most correct thing to use instead would be the topmost global on the +// callstack whose principal is subsumed by the subject principal. But that's +// hard to compute, so we just substitute the global of the current +// compartment. In practice, this is fine. +// +// Note that in particular things like: +// +// |SpecialPowers.wrap(crossOriginWindow).eval(open())| +// +// trigger this case. Although both the entry global and the current global +// have normal principals, the use of Gecko-specific System-Principaled JS +// puts the code from two different origins on the callstack at once, which +// doesn't happen normally on the web. +static nsIGlobalObject* +ClampToSubject(nsIGlobalObject* aGlobalOrNull) +{ + if (!aGlobalOrNull || !NS_IsMainThread()) { + return aGlobalOrNull; + } + + nsIPrincipal* globalPrin = aGlobalOrNull->PrincipalOrNull(); + NS_ENSURE_TRUE(globalPrin, GetCurrentGlobal()); + if (!nsContentUtils::SubjectPrincipal()->SubsumesConsideringDomain(globalPrin)) { + return GetCurrentGlobal(); + } + + return aGlobalOrNull; +} + nsIGlobalObject* GetEntryGlobal() { - return ScriptSettingsStack::EntryGlobal(); + return ClampToSubject(ScriptSettingsStack::EntryGlobal()); } nsIDocument* @@ -163,12 +216,12 @@ GetIncumbentGlobal() // there's nothing on the JS stack, which will cause us to check the // incumbent script stack below. if (JSObject *global = JS::GetScriptedCallerGlobal(cx)) { - return xpc::NativeGlobal(global); + return ClampToSubject(xpc::NativeGlobal(global)); } // Ok, nothing from the JS engine. Let's use whatever's on the // explicit stack. - return ScriptSettingsStack::IncumbentGlobal(); + return ClampToSubject(ScriptSettingsStack::IncumbentGlobal()); } nsIGlobalObject* @@ -463,14 +516,30 @@ AutoEntryScript::AutoEntryScript(nsIGlobalObject* aGlobalObject, aCx ? aCx : FindJSContext(aGlobalObject)) , ScriptSettingsStackEntry(aGlobalObject, /* aCandidate = */ true) , mWebIDLCallerPrincipal(nullptr) + , mDocShellForJSRunToCompletion(nullptr) { MOZ_ASSERT(aGlobalObject); MOZ_ASSERT_IF(!aCx, aIsMainThread); // cx is mandatory off-main-thread. MOZ_ASSERT_IF(aCx && aIsMainThread, aCx == FindJSContext(aGlobalObject)); + + if (aIsMainThread && gRunToCompletionListeners > 0) { + nsCOMPtr window = do_QueryInterface(aGlobalObject); + if (window) { + mDocShellForJSRunToCompletion = window->GetDocShell(); + } + } + + if (mDocShellForJSRunToCompletion) { + mDocShellForJSRunToCompletion->NotifyJSRunToCompletionStart(); + } } AutoEntryScript::~AutoEntryScript() { + if (mDocShellForJSRunToCompletion) { + mDocShellForJSRunToCompletion->NotifyJSRunToCompletionStop(); + } + // GC when we pop a script entry point. This is a useful heuristic that helps // us out on certain (flawed) benchmarks like sunspider, because it lets us // avoid GCing during the timing loop. diff --git a/dom/base/ScriptSettings.h b/dom/base/ScriptSettings.h index f6559a447e00..4debd1ae0913 100644 --- a/dom/base/ScriptSettings.h +++ b/dom/base/ScriptSettings.h @@ -21,6 +21,7 @@ class nsPIDOMWindow; class nsGlobalWindow; class nsIScriptContext; class nsIDocument; +class nsIDocShell; namespace mozilla { namespace dom { @@ -63,6 +64,16 @@ private: void InitScriptSettings(); void DestroyScriptSettings(); +/* + * Static helpers in ScriptSettings which track the number of listeners + * of Javascript RunToCompletion events. These should be used by the code in + * nsDocShell::SetRecordProfileTimelineMarkers to indicate to script + * settings that script run-to-completion needs to be monitored. + * SHOULD BE CALLED ONLY BY MAIN THREAD. + */ +void UseEntryScriptProfiling(); +void UnuseEntryScriptProfiling(); + // To implement a web-compatible browser, it is often necessary to obtain the // global object that is "associated" with the currently-running code. This // process is made more complicated by the fact that, historically, different @@ -331,6 +342,8 @@ private: // can't go away until then either. nsIPrincipal* mWebIDLCallerPrincipal; friend nsIPrincipal* GetWebIDLCallerPrincipal(); + + nsIDocShell* mDocShellForJSRunToCompletion; }; /* diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index 9e20e6542b59..325837923ad7 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -415,8 +415,6 @@ nsDOMWindowUtils::SetDisplayPortMarginsForElement(float aLeftMargin, float aTopMargin, float aRightMargin, float aBottomMargin, - uint32_t aAlignmentX, - uint32_t aAlignmentY, nsIDOMElement* aElement, uint32_t aPriority) { @@ -451,7 +449,7 @@ nsDOMWindowUtils::SetDisplayPortMarginsForElement(float aLeftMargin, aLeftMargin); nsLayoutUtils::SetDisplayPortMargins(content, presShell, displayportMargins, - aAlignmentX, aAlignmentY, aPriority); + aPriority); return NS_OK; } diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 9926f56a4d1a..f2117121efb3 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -2412,9 +2412,10 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument, bool thisChrome = IsChromeWindow(); - // Check if we're near the stack limit before we get anywhere near the - // transplanting code. We use a conservative check since we'll use a little - // more space before we actually hit the critical "can't fail" path. + // Check if we're anywhere near the stack limit before we reach the + // transplanting code, since it has no good way to handle errors. This uses + // the untrusted script limit, which is not strictly necessary since no + // actual script should run. JS_CHECK_RECURSION_CONSERVATIVE(cx, return NS_ERROR_FAILURE); nsCOMPtr wsh = do_QueryInterface(aState); @@ -7783,46 +7784,15 @@ nsGlobalWindow::GetFrames(nsIDOMWindow** aFrames) return rv.ErrorCode(); } -JSObject* nsGlobalWindow::CallerGlobal() -{ - JSContext *cx = nsContentUtils::GetCurrentJSContext(); - if (!cx) { - NS_ERROR("Please don't call this method from C++!"); - - return nullptr; - } - - // If somebody does sameOriginIframeWindow.postMessage(...), they probably - // expect the .source attribute of the resulting message event to be |window| - // rather than |sameOriginIframeWindow|, even though the transparent wrapper - // semantics of same-origin access will cause us to be in the iframe's - // compartment at the time of the call. This means that we want the incumbent - // global here, rather than the global of the current compartment. - // - // There are various edge cases in which the incumbent global and the current - // global would not be same-origin. They include: - // * A privileged caller (System Principal or Expanded Principal) manipulating - // less-privileged content via Xray Waivers. - // * An unprivileged caller invoking a cross-origin function that was exposed - // to it by privileged code (i.e. Sandbox.importFunction). - // - // In these cases, we probably don't want the privileged global appearing in the - // .source attribute. So we fall back to the compartment global there. - JS::Rooted incumbentGlobal(cx, &IncumbentJSGlobal()); - JS::Rooted compartmentGlobal(cx, JS::CurrentGlobalOrNull(cx)); - nsIPrincipal* incumbentPrin = nsContentUtils::ObjectPrincipal(incumbentGlobal); - nsIPrincipal* compartmentPrin = nsContentUtils::ObjectPrincipal(compartmentGlobal); - return incumbentPrin->EqualsConsideringDomain(compartmentPrin) ? incumbentGlobal - : compartmentGlobal; -} - - nsGlobalWindow* nsGlobalWindow::CallerInnerWindow() { JSContext *cx = nsContentUtils::GetCurrentJSContext(); NS_ENSURE_TRUE(cx, nullptr); - JS::Rooted scope(cx, CallerGlobal()); + nsIGlobalObject* global = GetIncumbentGlobal(); + NS_ENSURE_TRUE(global, nullptr); + JS::Rooted scope(cx, global->GetGlobalJSObject()); + NS_ENSURE_TRUE(scope, nullptr); // When Jetpack runs content scripts inside a sandbox, it uses // sandboxPrototype to make them appear as though they're running in the @@ -7830,7 +7800,7 @@ nsGlobalWindow::CallerInnerWindow() // the |source| of the received message to be the window set as the // sandboxPrototype. This used to work incidentally for unrelated reasons, but // now we need to do some special handling to support it. - { + if (xpc::IsSandbox(scope)) { JSAutoCompartment ac(cx, scope); JS::Rooted scopeProto(cx); bool ok = JS_GetPrototype(cx, scope, &scopeProto); @@ -7838,26 +7808,14 @@ nsGlobalWindow::CallerInnerWindow() if (scopeProto && xpc::IsSandboxPrototypeProxy(scopeProto) && (scopeProto = js::CheckedUnwrap(scopeProto, /* stopAtOuter = */ false))) { - scope = scopeProto; + global = xpc::NativeGlobal(scopeProto); + NS_ENSURE_TRUE(global, nullptr); } } - JSAutoCompartment ac(cx, scope); - // We don't use xpc::WindowOrNull here because we want to be able to tell - // apart the cases of "scope is not an nsISupports at all" and "scope is an - // nsISupports that's not a window". It's not clear whether that's desirable, - // see bug 984467. - nsISupports* native = - nsContentUtils::XPConnect()->GetNativeOfWrapper(cx, scope); - if (!native) - return nullptr; - - // The calling window must be holding a reference, so we can just return a - // raw pointer here and let the QI's addref be balanced by the nsCOMPtr - // destructor's release. - nsCOMPtr win = do_QueryInterface(native); - if (!win) - return GetCurrentInnerWindowInternal(); + // The calling window must be holding a reference, so we can return a weak + // pointer. + nsCOMPtr win = do_QueryInterface(global); return static_cast(win.get()); } @@ -8258,10 +8216,9 @@ nsGlobalWindow::PostMessageMoz(JSContext* aCx, JS::Handle aMessage, else { // In case the global is not a window, it can be a sandbox, and the sandbox's // principal can be used for the security check. - JSObject *global = CallerGlobal(); + nsIGlobalObject* global = GetIncumbentGlobal(); NS_ASSERTION(global, "Why is there no global object?"); - JSCompartment *compartment = js::GetObjectCompartment(global); - callerPrin = xpc::GetCompartmentPrincipal(compartment); + callerPrin = global->PrincipalOrNull(); } if (!callerPrin) { return; @@ -12023,6 +11980,9 @@ nsGlobalWindow::InnerForSetTimeoutOrInterval(ErrorResult& aError) // inner window that's calling window.setTimeout(). forwardTo = CallerInnerWindow(); + if (!forwardTo && nsContentUtils::IsCallerChrome()) { + forwardTo = currentInner; + } if (!forwardTo) { aError.Throw(NS_ERROR_NOT_AVAILABLE); return nullptr; @@ -12241,14 +12201,15 @@ nsGlobalWindow::SetTimeoutOrInterval(bool aIsInterval, int32_t *aReturn) if (IsOuterWindow()) { nsGlobalWindow* callerInner = CallerInnerWindow(); - NS_ENSURE_TRUE(callerInner, NS_ERROR_NOT_AVAILABLE); + NS_ENSURE_TRUE(callerInner || nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE); // If the caller and the callee share the same outer window, // forward to the callee inner. Else, we forward to the current // inner (e.g. someone is calling setTimeout() on a reference to // some other window). - if (callerInner->GetOuterWindow() == this && + if (callerInner && + callerInner->GetOuterWindow() == this && callerInner->IsInnerWindow()) { return callerInner->SetTimeoutOrInterval(aIsInterval, aReturn); } diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h index 3045c5515a25..cd86250321c0 100644 --- a/dom/base/nsGlobalWindow.h +++ b/dom/base/nsGlobalWindow.h @@ -1092,7 +1092,6 @@ protected: } void FreeInnerObjects(); - JSObject *CallerGlobal(); nsGlobalWindow *CallerInnerWindow(); // Only to be called on an inner window. diff --git a/dom/base/nsINode.h b/dom/base/nsINode.h index 119d7d78639a..0909e7fda69d 100644 --- a/dom/base/nsINode.h +++ b/dom/base/nsINode.h @@ -1984,6 +1984,11 @@ ToCanonicalSupports(nsINode* aPointer) aLocalName = nsINode::LocalName(); \ return NS_OK; \ } \ + NS_IMETHOD UnusedPlaceholder(bool* aResult) __VA_ARGS__ \ + { \ + *aResult = false; \ + return NS_OK; \ + } \ NS_IMETHOD GetDOMBaseURI(nsAString& aBaseURI) __VA_ARGS__ \ { \ nsINode::GetBaseURI(aBaseURI); \ diff --git a/dom/bindings/BindingUtils.cpp b/dom/bindings/BindingUtils.cpp index 191b0573a71f..43ada12c3131 100644 --- a/dom/bindings/BindingUtils.cpp +++ b/dom/bindings/BindingUtils.cpp @@ -1698,9 +1698,10 @@ ReparentWrapper(JSContext* aCx, JS::Handle aObjArg) { js::AssertSameCompartment(aCx, aObjArg); - // Check if we're near the stack limit before we get anywhere near the - // transplanting code. We use a conservative check since we'll use a little - // more space before we actually hit the critical "can't fail" path. + // Check if we're anywhere near the stack limit before we reach the + // transplanting code, since it has no good way to handle errors. This uses + // the untrusted script limit, which is not strictly necessary since no + // actual script should run. JS_CHECK_RECURSION_CONSERVATIVE(aCx, return NS_ERROR_FAILURE); JS::Rooted aObj(aCx, aObjArg); diff --git a/dom/bindings/ToJSValue.cpp b/dom/bindings/ToJSValue.cpp index 4fea13b51692..cbefc0218f09 100644 --- a/dom/bindings/ToJSValue.cpp +++ b/dom/bindings/ToJSValue.cpp @@ -66,10 +66,10 @@ ToJSValue(JSContext* aCx, JS::MutableHandle aValue) { MOZ_ASSERT(aArgument.Failed()); - ThrowMethodFailedWithDetails(aCx, aArgument, "", ""); - if (!JS_GetPendingException(aCx, aValue)) { - return false; - } + DebugOnly throwResult = ThrowMethodFailedWithDetails(aCx, aArgument, "", ""); + MOZ_ASSERT(!throwResult); + DebugOnly getPendingResult = JS_GetPendingException(aCx, aValue); + MOZ_ASSERT(getPendingResult); JS_ClearPendingException(aCx); return true; } diff --git a/dom/canvas/test/_webgl-conformance.ini b/dom/canvas/test/_webgl-conformance.ini index 28edb87b12e9..385c3bf13ae1 100644 --- a/dom/canvas/test/_webgl-conformance.ini +++ b/dom/canvas/test/_webgl-conformance.ini @@ -767,7 +767,7 @@ skip-if = (os == 'android') || (os == 'b2g') || (os == 'linux') [webgl-conformance/_wrappers/test_conformance__textures__texture-formats-test.html] [webgl-conformance/_wrappers/test_conformance__textures__texture-mips.html] [webgl-conformance/_wrappers/test_conformance__textures__texture-npot-video.html] -skip-if = os == 'win' +skip-if = os == 'win' || buildapp == 'mulet' # Mulet - bug 1089453 (crashes in libLLVM-3.0.so) [webgl-conformance/_wrappers/test_conformance__textures__texture-npot.html] [webgl-conformance/_wrappers/test_conformance__textures__texture-size.html] skip-if = os == 'android' diff --git a/dom/canvas/test/webgl-mochitest.ini b/dom/canvas/test/webgl-mochitest.ini index ac524b7e328b..71c36708245e 100644 --- a/dom/canvas/test/webgl-mochitest.ini +++ b/dom/canvas/test/webgl-mochitest.ini @@ -12,7 +12,7 @@ fail-if = (os == 'b2g') [webgl-mochitest/test_fb_param.html] [webgl-mochitest/test_fb_param_crash.html] [webgl-mochitest/test_hidden_alpha.html] -fail-if = (os == 'b2g') +skip-if = (os == 'b2g') || buildapp == 'mulet' # Mulet - bug 1093639 (crashes in libLLVM-3.0.so) [webgl-mochitest/test_highp_fs.html] [webgl-mochitest/test_no_arr_points.html] skip-if = android_version == '10' #Android 2.3 aws only; bug 1030942 diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp index d04d54104b21..529023af6135 100644 --- a/dom/html/HTMLInputElement.cpp +++ b/dom/html/HTMLInputElement.cpp @@ -1032,11 +1032,12 @@ UploadLastDir::FetchDirectoryAndDisplayPicker(nsIDocument* aDoc, nsCOMPtr prefCallback = new UploadLastDir::ContentPrefCallback(aFilePicker, aFpCallback); +#ifdef MOZ_B2G if (XRE_GetProcessType() == GeckoProcessType_Content) { - // FIXME (bug 949666): Run this code in the parent process. prefCallback->HandleCompletion(nsIContentPrefCallback2::COMPLETE_ERROR); return NS_OK; } +#endif // Attempt to get the CPS, if it's not present we'll fallback to use the Desktop folder nsCOMPtr contentPrefService = @@ -1062,10 +1063,11 @@ UploadLastDir::StoreLastUsedDirectory(nsIDocument* aDoc, nsIFile* aDir) return NS_OK; } +#ifdef MOZ_B2G if (XRE_GetProcessType() == GeckoProcessType_Content) { - // FIXME (bug 949666): Run this code in the parent process. return NS_OK; } +#endif nsCOMPtr docURI = aDoc->GetDocumentURI(); NS_PRECONDITION(docURI, "docURI is null"); diff --git a/dom/interfaces/base/nsIDOMWindowUtils.idl b/dom/interfaces/base/nsIDOMWindowUtils.idl index 0681ce78cea8..f25e274466d4 100644 --- a/dom/interfaces/base/nsIDOMWindowUtils.idl +++ b/dom/interfaces/base/nsIDOMWindowUtils.idl @@ -51,7 +51,7 @@ interface nsITranslationNodeList; interface nsIJSRAIIHelper; interface nsIContentPermissionRequest; -[scriptable, uuid(e293355b-ae7f-4ef7-9237-452bcf3e9e6b)] +[scriptable, uuid(9621eb05-b498-4e87-a012-95d817987624)] interface nsIDOMWindowUtils : nsISupports { /** @@ -188,8 +188,6 @@ interface nsIDOMWindowUtils : nsISupports { in float aTopMargin, in float aRightMargin, in float aBottomMargin, - in uint32_t aAlignmentX, - in uint32_t aAlignmentY, in nsIDOMElement aElement, in uint32_t aPriority); diff --git a/dom/interfaces/core/nsIDOMAttr.idl b/dom/interfaces/core/nsIDOMAttr.idl index 6fda9609d9ad..f4971ba4406b 100644 --- a/dom/interfaces/core/nsIDOMAttr.idl +++ b/dom/interfaces/core/nsIDOMAttr.idl @@ -14,7 +14,7 @@ * http://www.w3.org/TR/DOM-Level-2-Core/ */ -[builtinclass, uuid(7d0582bd-09a7-430e-969b-054abbea19fe)] +[builtinclass, uuid(7db491e8-a3a3-4432-ad67-e6c33e24ac6d)] interface nsIDOMAttr : nsIDOMNode { readonly attribute DOMString name; diff --git a/dom/interfaces/core/nsIDOMCDATASection.idl b/dom/interfaces/core/nsIDOMCDATASection.idl index af6d04be8e21..c0595c58ca33 100644 --- a/dom/interfaces/core/nsIDOMCDATASection.idl +++ b/dom/interfaces/core/nsIDOMCDATASection.idl @@ -15,7 +15,7 @@ * http://www.w3.org/TR/DOM-Level-2-Core/ */ -[uuid(4ac42d40-69b7-4506-b730-c41ec74b74bd)] +[uuid(e14ef131-34cc-40c8-9c99-a403c001184a)] interface nsIDOMCDATASection : nsIDOMText { }; diff --git a/dom/interfaces/core/nsIDOMCharacterData.idl b/dom/interfaces/core/nsIDOMCharacterData.idl index cb1496dd992e..96cfd40e7548 100644 --- a/dom/interfaces/core/nsIDOMCharacterData.idl +++ b/dom/interfaces/core/nsIDOMCharacterData.idl @@ -13,7 +13,7 @@ * http://www.w3.org/TR/DOM-Level-2-Core/ */ -[uuid(844b8e7e-6d37-4fa1-8196-86e3afdfa0ca)] +[uuid(4109a2d2-e7af-445d-bb72-c7c9b875f35e)] interface nsIDOMCharacterData : nsIDOMNode { attribute DOMString data; diff --git a/dom/interfaces/core/nsIDOMComment.idl b/dom/interfaces/core/nsIDOMComment.idl index 5eb1c80f1923..f7d37216779b 100644 --- a/dom/interfaces/core/nsIDOMComment.idl +++ b/dom/interfaces/core/nsIDOMComment.idl @@ -14,7 +14,7 @@ * http://www.w3.org/TR/DOM-Level-2-Core/ */ -[uuid(c1a1d2ea-e106-4ee8-806d-2633468e8098)] +[uuid(e7866ff8-b7fc-494f-87c0-fb017d8a4d30)] interface nsIDOMComment : nsIDOMCharacterData { }; diff --git a/dom/interfaces/core/nsIDOMDocument.idl b/dom/interfaces/core/nsIDOMDocument.idl index bf38995a589e..d4e258a60e4a 100644 --- a/dom/interfaces/core/nsIDOMDocument.idl +++ b/dom/interfaces/core/nsIDOMDocument.idl @@ -32,7 +32,7 @@ interface nsIDOMLocation; * http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html */ -[uuid(08c6400b-0b6d-4ce6-b88d-e7a15a9c7c03)] +[uuid(35dc5030-dc83-4291-88a2-0906c549788e)] interface nsIDOMDocument : nsIDOMNode { readonly attribute nsIDOMDocumentType doctype; diff --git a/dom/interfaces/core/nsIDOMDocumentFragment.idl b/dom/interfaces/core/nsIDOMDocumentFragment.idl index 6406cccb8a2f..b4f4823a0c82 100644 --- a/dom/interfaces/core/nsIDOMDocumentFragment.idl +++ b/dom/interfaces/core/nsIDOMDocumentFragment.idl @@ -14,7 +14,7 @@ * http://www.w3.org/TR/DOM-Level-2-Core/ */ -[builtinclass, uuid(24b34c61-7326-42d4-87ec-5d3b5c0b1b26)] +[builtinclass, uuid(48eb8d72-95bb-402e-a8fc-f2b187abcbdb)] interface nsIDOMDocumentFragment : nsIDOMNode { /** diff --git a/dom/interfaces/core/nsIDOMDocumentType.idl b/dom/interfaces/core/nsIDOMDocumentType.idl index 570f2c1bd36c..0ce6fc4c876e 100644 --- a/dom/interfaces/core/nsIDOMDocumentType.idl +++ b/dom/interfaces/core/nsIDOMDocumentType.idl @@ -15,7 +15,7 @@ * http://www.w3.org/TR/DOM-Level-2-Core/ */ -[uuid(23c1f549-d40b-49b8-992e-2a1136afa13f)] +[uuid(cd7467b9-0f26-4787-a359-66e80ba8db92)] interface nsIDOMDocumentType : nsIDOMNode { readonly attribute DOMString name; diff --git a/dom/interfaces/core/nsIDOMElement.idl b/dom/interfaces/core/nsIDOMElement.idl index f7b6383716c0..6fdd346bf5af 100644 --- a/dom/interfaces/core/nsIDOMElement.idl +++ b/dom/interfaces/core/nsIDOMElement.idl @@ -15,7 +15,7 @@ interface nsIDOMMozNamedAttrMap; * http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#interface-element */ -[uuid(59eb63f9-c8c0-41d2-bf73-739de43b17f9)] +[uuid(6289999b-1008-4269-b42a-413ec5a9d3f4)] interface nsIDOMElement : nsIDOMNode { readonly attribute DOMString tagName; diff --git a/dom/interfaces/core/nsIDOMNode.idl b/dom/interfaces/core/nsIDOMNode.idl index 9c2450deba60..c9ba03db4c10 100644 --- a/dom/interfaces/core/nsIDOMNode.idl +++ b/dom/interfaces/core/nsIDOMNode.idl @@ -16,7 +16,7 @@ interface nsIVariant; * http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html */ -[uuid(238222a9-7aa5-4804-9f86-484853ce4b15)] +[uuid(cc35b412-009b-46a3-9be0-76448f12548d)] interface nsIDOMNode : nsISupports { const unsigned short ELEMENT_NODE = 1; @@ -69,6 +69,9 @@ interface nsIDOMNode : nsISupports // Introduced in DOM Level 2: readonly attribute DOMString localName; + // For vtable compatibility (see bug 1078674) + [noscript] bool unusedPlaceholder(); + // Introduced in DOM Level 3: // This uses a binaryname to avoid warnings due to name collision with // nsINode::GetBaseURI diff --git a/dom/interfaces/core/nsIDOMProcessingInstruction.idl b/dom/interfaces/core/nsIDOMProcessingInstruction.idl index 6ff1eb283714..bcf8724fc0ce 100644 --- a/dom/interfaces/core/nsIDOMProcessingInstruction.idl +++ b/dom/interfaces/core/nsIDOMProcessingInstruction.idl @@ -15,7 +15,7 @@ * http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html */ -[uuid(d0163f44-8f5b-4234-b3aa-43cab64e2039)] +[uuid(5a139df7-04d0-438d-bd18-d8122564258f)] interface nsIDOMProcessingInstruction : nsIDOMCharacterData { readonly attribute DOMString target; diff --git a/dom/interfaces/core/nsIDOMText.idl b/dom/interfaces/core/nsIDOMText.idl index 7b6f13e892d5..72fcf859bd5b 100644 --- a/dom/interfaces/core/nsIDOMText.idl +++ b/dom/interfaces/core/nsIDOMText.idl @@ -13,7 +13,7 @@ * http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html */ -[uuid(775bbd26-1581-4e54-b82c-5d9dc5a3363b)] +[uuid(67273994-6aff-4091-9de9-b788a249f783)] interface nsIDOMText : nsIDOMCharacterData { nsIDOMText splitText(in unsigned long offset) diff --git a/dom/interfaces/core/nsIDOMXMLDocument.idl b/dom/interfaces/core/nsIDOMXMLDocument.idl index 9910a0d16ec5..db48f174c60e 100644 --- a/dom/interfaces/core/nsIDOMXMLDocument.idl +++ b/dom/interfaces/core/nsIDOMXMLDocument.idl @@ -5,7 +5,7 @@ #include "nsIDOMDocument.idl" -[uuid(1d54e44a-2012-4567-805d-bd5455fc6421)] +[uuid(867379ce-165b-4b8c-8582-299b38096aa8)] interface nsIDOMXMLDocument : nsIDOMDocument { // DOM Level 3 Load & Save, DocumentLS diff --git a/dom/interfaces/html/nsIDOMHTMLDocument.idl b/dom/interfaces/html/nsIDOMHTMLDocument.idl index e0e583c2124c..409e54883c4a 100644 --- a/dom/interfaces/html/nsIDOMHTMLDocument.idl +++ b/dom/interfaces/html/nsIDOMHTMLDocument.idl @@ -13,7 +13,7 @@ */ interface nsISelection; -[uuid(abf369fb-a8b2-4fba-95f5-9e4a896e40a8)] +[uuid(bd2a0a46-17e4-46ea-9e5d-6a97cf5e3b28)] interface nsIDOMHTMLDocument : nsIDOMDocument { attribute DOMString domain; diff --git a/dom/interfaces/html/nsIDOMHTMLElement.idl b/dom/interfaces/html/nsIDOMHTMLElement.idl index 7af6e368f185..2d67399e2f25 100644 --- a/dom/interfaces/html/nsIDOMHTMLElement.idl +++ b/dom/interfaces/html/nsIDOMHTMLElement.idl @@ -19,7 +19,7 @@ interface nsIDOMHTMLMenuElement; * with changes from the work-in-progress WHATWG HTML specification: * http://www.whatwg.org/specs/web-apps/current-work/ */ -[uuid(8c9472c2-785a-40b6-ad47-4d98e64562bd)] +[uuid(b0c42392-d0e7-4f6a-beb5-a698ce648945)] interface nsIDOMHTMLElement : nsIDOMElement { // metadata attributes diff --git a/dom/interfaces/svg/nsIDOMSVGElement.idl b/dom/interfaces/svg/nsIDOMSVGElement.idl index 6d935a087edd..59c16d1ffe02 100644 --- a/dom/interfaces/svg/nsIDOMSVGElement.idl +++ b/dom/interfaces/svg/nsIDOMSVGElement.idl @@ -9,7 +9,7 @@ interface nsIDOMCSSStyleDeclaration; interface nsIDOMCSSValue; -[uuid(6618074e-0c77-4fec-8870-a6f79aa79b07)] +[uuid(c63517c5-8bab-4cd1-8694-bccafc32a195)] interface nsIDOMSVGElement : nsIDOMElement { // raises DOMException on setting diff --git a/dom/interfaces/xul/nsIDOMXULDocument.idl b/dom/interfaces/xul/nsIDOMXULDocument.idl index 2cc132f1121e..24216d3ca163 100644 --- a/dom/interfaces/xul/nsIDOMXULDocument.idl +++ b/dom/interfaces/xul/nsIDOMXULDocument.idl @@ -10,7 +10,7 @@ interface nsIDOMXULCommandDispatcher; interface nsIObserver; interface nsIBoxObject; -[uuid(6f932360-ae43-4fa7-9200-66f64e05a356)] +[uuid(5d876ab0-5525-4f38-bc3b-f1190e3e3b90)] interface nsIDOMXULDocument : nsIDOMDocument { attribute nsIDOMNode popupNode; diff --git a/dom/interfaces/xul/nsIDOMXULElement.idl b/dom/interfaces/xul/nsIDOMXULElement.idl index d68f13daa6aa..c28a3974a7d4 100644 --- a/dom/interfaces/xul/nsIDOMXULElement.idl +++ b/dom/interfaces/xul/nsIDOMXULElement.idl @@ -12,7 +12,7 @@ interface nsIControllers; interface nsIBoxObject; -[uuid(ef62515d-3160-4463-abd7-fc9b7385ecef)] +[uuid(75435ab3-6863-42a1-ade3-025393d9e80e)] interface nsIDOMXULElement : nsIDOMElement { // Layout properties diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index b29b496ae262..9ddb465d93fd 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -23,6 +23,7 @@ #include "mozilla/a11y/DocAccessibleChild.h" #endif #include "mozilla/Preferences.h" +#include "mozilla/docshell/OfflineCacheUpdateChild.h" #include "mozilla/dom/ContentBridgeChild.h" #include "mozilla/dom/ContentBridgeParent.h" #include "mozilla/dom/DOMStorageIPC.h" @@ -2258,6 +2259,25 @@ ContentChild::RecvUnregisterSheet(const URIParams& aURI, const uint32_t& aType) return true; } +POfflineCacheUpdateChild* +ContentChild::AllocPOfflineCacheUpdateChild(const URIParams& manifestURI, + const URIParams& documentURI, + const bool& stickDocument, + const TabId& aTabId) +{ + NS_RUNTIMEABORT("unused"); + return nullptr; +} + +bool +ContentChild::DeallocPOfflineCacheUpdateChild(POfflineCacheUpdateChild* actor) +{ + OfflineCacheUpdateChild* offlineCacheUpdate = + static_cast(actor); + NS_RELEASE(offlineCacheUpdate); + return true; +} + #ifdef MOZ_NUWA_PROCESS class CallNuwaSpawn : public nsRunnable { diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h index 02063e8ab73b..4fa9c53e8928 100644 --- a/dom/ipc/ContentChild.h +++ b/dom/ipc/ContentChild.h @@ -404,6 +404,14 @@ public: PBrowserOrId GetBrowserOrId(TabChild* aTabChild); + virtual POfflineCacheUpdateChild* AllocPOfflineCacheUpdateChild( + const URIParams& manifestURI, + const URIParams& documentURI, + const bool& stickDocument, + const TabId& aTabId) MOZ_OVERRIDE; + virtual bool + DeallocPOfflineCacheUpdateChild(POfflineCacheUpdateChild* offlineCacheUpdate) MOZ_OVERRIDE; + private: virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE; diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 5e7b1e7c5937..b695580bb4e3 100755 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -35,6 +35,7 @@ #include "nsAccessibilityService.h" #endif #include "mozilla/ClearOnShutdown.h" +#include "mozilla/docshell/OfflineCacheUpdateParent.h" #include "mozilla/dom/DataStoreService.h" #include "mozilla/dom/DOMStorageIPC.h" #include "mozilla/dom/Element.h" @@ -84,6 +85,7 @@ #include "nsChromeRegistryChrome.h" #include "nsConsoleMessage.h" #include "nsConsoleService.h" +#include "nsContentUtils.h" #include "nsDebugImpl.h" #include "nsFrameMessageManager.h" #include "nsGeolocationSettings.h" @@ -1487,6 +1489,14 @@ ContentParent::ShutDownProcess(bool aCloseWithError) } } + const InfallibleTArray& ocuParents = + ManagedPOfflineCacheUpdateParent(); + for (uint32_t i = 0; i < ocuParents.Length(); ++i) { + nsRefPtr ocuParent = + static_cast(ocuParents[i]); + ocuParent->StopSendingMessagesToChild(); + } + // NB: must MarkAsDead() here so that this isn't accidentally // returned from Get*() while in the midst of shutdown. MarkAsDead(); @@ -4317,6 +4327,62 @@ ContentParent::GetManagedTabContext() GetTabContextByContentProcess(this->ChildID())); } +mozilla::docshell::POfflineCacheUpdateParent* +ContentParent::AllocPOfflineCacheUpdateParent(const URIParams& aManifestURI, + const URIParams& aDocumentURI, + const bool& aStickDocument, + const TabId& aTabId) +{ + TabContext tabContext; + if (!ContentProcessManager::GetSingleton()-> + GetTabContextByProcessAndTabId(this->ChildID(), aTabId, &tabContext)) { + return nullptr; + } + nsRefPtr update = + new mozilla::docshell::OfflineCacheUpdateParent( + tabContext.OwnOrContainingAppId(), + tabContext.IsBrowserElement()); + // Use this reference as the IPDL reference. + return update.forget().take(); +} + +bool +ContentParent::RecvPOfflineCacheUpdateConstructor(POfflineCacheUpdateParent* aActor, + const URIParams& aManifestURI, + const URIParams& aDocumentURI, + const bool& aStickDocument, + const TabId& aTabId) +{ + MOZ_ASSERT(aActor); + + nsRefPtr update = + static_cast(aActor); + + nsresult rv = update->Schedule(aManifestURI, aDocumentURI, aStickDocument); + if (NS_FAILED(rv) && IsAlive()) { + // Inform the child of failure. + unused << update->SendFinish(false, false); + } + + return true; +} + +bool +ContentParent::DeallocPOfflineCacheUpdateParent(POfflineCacheUpdateParent* aActor) +{ + // Reclaim the IPDL reference. + nsRefPtr update = + dont_AddRef(static_cast(aActor)); + return true; +} + +bool +ContentParent::RecvSetOfflinePermission(const Principal& aPrincipal) +{ + nsIPrincipal* principal = aPrincipal; + nsContentUtils::MaybeAllowOfflineAppByDefault(principal, nullptr); + return true; +} } // namespace dom } // namespace mozilla diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index 5ab32d06ffe6..53090e8ab846 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -311,6 +311,23 @@ public: virtual bool RecvDeallocateTabId(const TabId& aTabId) MOZ_OVERRIDE; nsTArray GetManagedTabContext(); + + virtual POfflineCacheUpdateParent* + AllocPOfflineCacheUpdateParent(const URIParams& aManifestURI, + const URIParams& aDocumentURI, + const bool& aStickDocument, + const TabId& aTabId) MOZ_OVERRIDE; + virtual bool + RecvPOfflineCacheUpdateConstructor(POfflineCacheUpdateParent* aActor, + const URIParams& aManifestURI, + const URIParams& aDocumentURI, + const bool& stickDocument, + const TabId& aTabId) MOZ_OVERRIDE; + virtual bool + DeallocPOfflineCacheUpdateParent(POfflineCacheUpdateParent* aActor) MOZ_OVERRIDE; + + virtual bool RecvSetOfflinePermission(const IPC::Principal& principal) MOZ_OVERRIDE; + protected: void OnChannelConnected(int32_t pid) MOZ_OVERRIDE; virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE; diff --git a/dom/ipc/ContentProcessManager.cpp b/dom/ipc/ContentProcessManager.cpp index 9ea3ded5fe08..0b9ca2ae2547 100644 --- a/dom/ipc/ContentProcessManager.cpp +++ b/dom/ipc/ContentProcessManager.cpp @@ -207,25 +207,29 @@ ContentProcessManager::DeallocateTabId(const ContentParentId& aChildCpId, } } -nsTArray -ContentProcessManager::GetAppIdsByContentProcess(const ContentParentId& aChildCpId) +bool +ContentProcessManager::GetTabContextByProcessAndTabId(const ContentParentId& aChildCpId, + const TabId& aChildTabId, + /*out*/ TabContext* aTabContext) { MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(aTabContext); - nsTArray appIdArray; auto iter = mContentParentMap.find(aChildCpId); if (NS_WARN_IF(iter == mContentParentMap.end())) { ASSERT_UNLESS_FUZZING(); - return Move(appIdArray); + return false; } - for (auto remoteFrameIter = iter->second.mRemoteFrames.begin(); - remoteFrameIter != iter->second.mRemoteFrames.end(); - ++remoteFrameIter) { - appIdArray.AppendElement(remoteFrameIter->second.mContext.OwnOrContainingAppId()); + auto remoteFrameIter = iter->second.mRemoteFrames.find(aChildTabId); + if (NS_WARN_IF(remoteFrameIter == iter->second.mRemoteFrames.end())) { + ASSERT_UNLESS_FUZZING(); + return false; } - return Move(appIdArray); + *aTabContext = remoteFrameIter->second.mContext; + + return true; } nsTArray diff --git a/dom/ipc/ContentProcessManager.h b/dom/ipc/ContentProcessManager.h index bf5827fae0be..5a4192d1ae99 100644 --- a/dom/ipc/ContentProcessManager.h +++ b/dom/ipc/ContentProcessManager.h @@ -88,11 +88,12 @@ public: const TabId& aChildTabId); /** - * Get all app ids which are inside the given content process. - * XXX Currently not used. Plan to be used for bug 1020186. + * Get the TabContext by the given content process and tab id. */ - nsTArray - GetAppIdsByContentProcess(const ContentParentId& aChildCpId); + bool + GetTabContextByProcessAndTabId(const ContentParentId& aChildCpId, + const TabId& aChildTabId, + /*out*/ TabContext* aTabContext); /** * Get all TabContext which are inside the given content process. diff --git a/dom/ipc/FilePickerParent.cpp b/dom/ipc/FilePickerParent.cpp index 1c4bf4082aa8..2636d273c2c8 100644 --- a/dom/ipc/FilePickerParent.cpp +++ b/dom/ipc/FilePickerParent.cpp @@ -202,7 +202,8 @@ FilePickerParent::RecvOpen(const int16_t& aSelectedType, const nsString& aDefaultFile, const nsString& aDefaultExtension, const InfallibleTArray& aFilters, - const InfallibleTArray& aFilterNames) + const InfallibleTArray& aFilterNames, + const nsString& aDisplayDirectory) { if (!CreateFilePicker()) { unused << Send__delete__(this, void_t(), nsIFilePicker::returnCancel); @@ -219,6 +220,14 @@ FilePickerParent::RecvOpen(const int16_t& aSelectedType, mFilePicker->SetDefaultExtension(aDefaultExtension); mFilePicker->SetFilterIndex(aSelectedType); + if (!aDisplayDirectory.IsEmpty()) { + nsCOMPtr localFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID); + if (localFile) { + localFile->InitWithPath(aDisplayDirectory); + mFilePicker->SetDisplayDirectory(localFile); + } + } + mCallback = new FilePickerShownCallback(this); mFilePicker->Open(mCallback); diff --git a/dom/ipc/FilePickerParent.h b/dom/ipc/FilePickerParent.h index 8d6ec2544773..5bcc82533c22 100644 --- a/dom/ipc/FilePickerParent.h +++ b/dom/ipc/FilePickerParent.h @@ -36,7 +36,8 @@ class FilePickerParent : public PFilePickerParent const nsString& aDefaultFile, const nsString& aDefaultExtension, const InfallibleTArray& aFilters, - const InfallibleTArray& aFilterNames) MOZ_OVERRIDE; + const InfallibleTArray& aFilterNames, + const nsString& aDisplayDirectory) MOZ_OVERRIDE; virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE; diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl index 2e9ea4c87451..109a8410ecc7 100644 --- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -14,7 +14,6 @@ include protocol PContentPermissionRequest; include protocol PFilePicker; include protocol PIndexedDBPermissionRequest; include protocol PRenderFrame; -include protocol POfflineCacheUpdate; include protocol PPluginWidget; include DOMTypes; include JavaScriptTypes; @@ -80,7 +79,6 @@ prio(normal upto urgent) intr protocol PBrowser manages PFilePicker; manages PIndexedDBPermissionRequest; manages PRenderFrame; - manages POfflineCacheUpdate; manages PPluginWidget; both: @@ -328,37 +326,6 @@ parent: TextureFactoryIdentifier textureFactoryIdentifier, uint64_t layersId, bool success); - /** - * Starts an offline application cache update. - * @param manifestURI - * URI of the manifest to fetch, the application cache group ID - * @param documentURI - * URI of the document that referred the manifest - * @param stickDocument - * True if the update was initiated by a document load that referred - * a manifest. - * False if the update was initiated by applicationCache.update() call. - * - * Tells the update to carry the documentURI to a potential separate - * update of implicit (master) items. - * - * Why this argument? If the document was not found in an offline cache - * before load and refers a manifest and this manifest itself has not - * been changed since the last fetch, we will not do the application - * cache group update. But we must cache the document (identified by the - * documentURI). This argument will ensure that a previously uncached - * document will get cached and that we don't re-cache a document that - * has already been cached (stickDocument=false). - */ - POfflineCacheUpdate(URIParams manifestURI, URIParams documentURI, - bool stickDocument); - - /** - * Sets "offline-app" permission for the principal. Called when we hit - * a web app with the manifest attribute in and - * offline-apps.allow_by_default is set to true. - */ - SetOfflinePermission(Principal principal); /** * window.open from inside