merge mozilla-inbound to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2014-11-14 12:58:54 +01:00
Родитель 75f6039f4f a05d3eba03
Коммит 9bafb1c7ff
298 изменённых файлов: 4087 добавлений и 4295 удалений

Просмотреть файл

@ -44,3 +44,4 @@ support-files =
[browser_newtab_undo.js] [browser_newtab_undo.js]
[browser_newtab_unpin.js] [browser_newtab_unpin.js]
[browser_newtab_update.js] [browser_newtab_update.js]
skip-if = true # Bug 1008029

Просмотреть файл

@ -152,33 +152,33 @@ skip-if = e10s || os == "mac" || e10s # Bug 895426
[browser_dbg_break-on-dom-event-02.js] [browser_dbg_break-on-dom-event-02.js]
skip-if = e10s skip-if = e10s
[browser_dbg_breakpoints-actual-location.js] [browser_dbg_breakpoints-actual-location.js]
skip-if = e10s skip-if = e10s && debug
[browser_dbg_breakpoints-actual-location2.js] [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] [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] [browser_dbg_breakpoints-button-01.js]
skip-if = e10s skip-if = e10s && debug
[browser_dbg_breakpoints-button-02.js] [browser_dbg_breakpoints-button-02.js]
skip-if = e10s skip-if = e10s && debug
[browser_dbg_breakpoints-contextmenu-add.js] [browser_dbg_breakpoints-contextmenu-add.js]
skip-if = e10s skip-if = e10s && debug
[browser_dbg_breakpoints-contextmenu.js] [browser_dbg_breakpoints-contextmenu.js]
skip-if = e10s skip-if = e10s && debug
[browser_dbg_breakpoints-disabled-reload.js] [browser_dbg_breakpoints-disabled-reload.js]
skip-if = e10s skip-if = e10s # Bug 1093535
[browser_dbg_breakpoints-editor.js] [browser_dbg_breakpoints-editor.js]
skip-if = e10s skip-if = e10s && debug
[browser_dbg_breakpoints-highlight.js] [browser_dbg_breakpoints-highlight.js]
skip-if = e10s skip-if = e10s && debug
[browser_dbg_breakpoints-new-script.js] [browser_dbg_breakpoints-new-script.js]
skip-if = e10s skip-if = e10s && debug
[browser_dbg_breakpoints-other-tabs.js] [browser_dbg_breakpoints-other-tabs.js]
skip-if = e10s skip-if = e10s && debug
[browser_dbg_breakpoints-pane.js] [browser_dbg_breakpoints-pane.js]
skip-if = e10s skip-if = e10s && debug
[browser_dbg_breakpoints-reload.js] [browser_dbg_breakpoints-reload.js]
skip-if = e10s skip-if = e10s && debug
[browser_dbg_chrome-create.js] [browser_dbg_chrome-create.js]
skip-if = e10s skip-if = e10s
[browser_dbg_chrome-debugging.js] [browser_dbg_chrome-debugging.js]
@ -458,21 +458,21 @@ skip-if = e10s && debug
[browser_dbg_variables-view-06.js] [browser_dbg_variables-view-06.js]
skip-if = e10s && debug skip-if = e10s && debug
[browser_dbg_variables-view-accessibility.js] [browser_dbg_variables-view-accessibility.js]
skip-if = e10s skip-if = e10s && debug
[browser_dbg_variables-view-data.js] [browser_dbg_variables-view-data.js]
skip-if = e10s skip-if = e10s && debug
[browser_dbg_variables-view-edit-cancel.js] [browser_dbg_variables-view-edit-cancel.js]
skip-if = e10s skip-if = e10s && debug
[browser_dbg_variables-view-edit-click.js] [browser_dbg_variables-view-edit-click.js]
skip-if = e10s || (os == 'mac' || os == 'win') && (debug == false) # Bug 986166 skip-if = e10s || (os == 'mac' || os == 'win') && (debug == false) # Bug 986166
[browser_dbg_variables-view-edit-getset-01.js] [browser_dbg_variables-view-edit-getset-01.js]
skip-if = e10s skip-if = e10s && debug
[browser_dbg_variables-view-edit-getset-02.js] [browser_dbg_variables-view-edit-getset-02.js]
skip-if = e10s skip-if = e10s && debug
[browser_dbg_variables-view-edit-value.js] [browser_dbg_variables-view-edit-value.js]
skip-if = e10s skip-if = e10s && debug
[browser_dbg_variables-view-edit-watch.js] [browser_dbg_variables-view-edit-watch.js]
skip-if = e10s skip-if = e10s && debug
[browser_dbg_variables-view-filter-01.js] [browser_dbg_variables-view-filter-01.js]
skip-if = e10s && debug skip-if = e10s && debug
[browser_dbg_variables-view-filter-02.js] [browser_dbg_variables-view-filter-02.js]
@ -484,27 +484,27 @@ skip-if = e10s && debug
[browser_dbg_variables-view-filter-05.js] [browser_dbg_variables-view-filter-05.js]
skip-if = e10s && debug skip-if = e10s && debug
[browser_dbg_variables-view-filter-pref.js] [browser_dbg_variables-view-filter-pref.js]
skip-if = e10s skip-if = e10s && debug
[browser_dbg_variables-view-filter-searchbox.js] [browser_dbg_variables-view-filter-searchbox.js]
skip-if = e10s skip-if = e10s && debug
[browser_dbg_variables-view-frame-parameters-01.js] [browser_dbg_variables-view-frame-parameters-01.js]
skip-if = e10s skip-if = e10s && debug
[browser_dbg_variables-view-frame-parameters-02.js] [browser_dbg_variables-view-frame-parameters-02.js]
skip-if = e10s skip-if = e10s && debug
[browser_dbg_variables-view-frame-parameters-03.js] [browser_dbg_variables-view-frame-parameters-03.js]
skip-if = e10s skip-if = e10s && debug
[browser_dbg_variables-view-frame-with.js] [browser_dbg_variables-view-frame-with.js]
skip-if = e10s skip-if = e10s && debug
[browser_dbg_variables-view-frozen-sealed-nonext.js] [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] [browser_dbg_variables-view-hide-non-enums.js]
skip-if = e10s skip-if = e10s && debug
[browser_dbg_variables-view-large-array-buffer.js] [browser_dbg_variables-view-large-array-buffer.js]
skip-if = e10s skip-if = e10s && debug
[browser_dbg_variables-view-override-01.js] [browser_dbg_variables-view-override-01.js]
skip-if = e10s skip-if = e10s && debug
[browser_dbg_variables-view-override-02.js] [browser_dbg_variables-view-override-02.js]
skip-if = e10s skip-if = e10s && debug
[browser_dbg_variables-view-popup-01.js] [browser_dbg_variables-view-popup-01.js]
skip-if = e10s && debug skip-if = e10s && debug
[browser_dbg_variables-view-popup-02.js] [browser_dbg_variables-view-popup-02.js]
@ -532,20 +532,20 @@ skip-if = e10s && debug
[browser_dbg_variables-view-popup-13.js] [browser_dbg_variables-view-popup-13.js]
skip-if = e10s && debug skip-if = e10s && debug
[browser_dbg_variables-view-popup-14.js] [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] [browser_dbg_variables-view-popup-15.js]
skip-if = e10s && debug skip-if = e10s && debug
[browser_dbg_variables-view-popup-16.js] [browser_dbg_variables-view-popup-16.js]
skip-if = e10s && debug skip-if = e10s && debug
[browser_dbg_variables-view-reexpand-01.js] [browser_dbg_variables-view-reexpand-01.js]
skip-if = e10s skip-if = e10s && debug
[browser_dbg_variables-view-reexpand-02.js] [browser_dbg_variables-view-reexpand-02.js]
skip-if = e10s skip-if = e10s && debug
[browser_dbg_variables-view-reexpand-03.js] [browser_dbg_variables-view-reexpand-03.js]
skip-if = e10s skip-if = e10s && debug
[browser_dbg_variables-view-webidl.js] [browser_dbg_variables-view-webidl.js]
skip-if = e10s skip-if = e10s && debug
[browser_dbg_watch-expressions-01.js] [browser_dbg_watch-expressions-01.js]
skip-if = e10s skip-if = e10s && debug
[browser_dbg_watch-expressions-02.js] [browser_dbg_watch-expressions-02.js]
skip-if = e10s skip-if = e10s && debug

Просмотреть файл

@ -9,12 +9,11 @@
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html"; const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
function test() { function test() {
let gTab, gDebuggee, gPanel, gDebugger; let gTab, gPanel, gDebugger;
let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving; let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving;
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab; gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel; gPanel = aPanel;
gDebugger = gPanel.panelWin; gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor; gEditor = gDebugger.DebuggerView.editor;
@ -24,7 +23,7 @@ function test() {
gBreakpointsRemoving = gBreakpoints._removing; gBreakpointsRemoving = gBreakpoints._removing;
waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1).then(performTest); waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1).then(performTest);
gDebuggee.firstCall(); callInTab(gTab, "firstCall");
}); });
function performTest() { function performTest() {

Просмотреть файл

@ -10,12 +10,11 @@
const TAB_URL = EXAMPLE_URL + "doc_breakpoint-move.html"; const TAB_URL = EXAMPLE_URL + "doc_breakpoint-move.html";
function test() { function test() {
let gTab, gDebuggee, gPanel, gDebugger; let gTab, gPanel, gDebugger;
let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving; let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving;
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab; gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel; gPanel = aPanel;
gDebugger = gPanel.panelWin; gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor; gEditor = gDebugger.DebuggerView.editor;
@ -25,7 +24,7 @@ function test() {
gBreakpointsRemoving = gBreakpoints._removing; gBreakpointsRemoving = gBreakpoints._removing;
waitForSourceAndCaretAndScopes(gPanel, ".html", 1).then(performTest); waitForSourceAndCaretAndScopes(gPanel, ".html", 1).then(performTest);
gDebuggee.ermahgerd(); callInTab(gTab, "ermahgerd");
}); });
function performTest() { function performTest() {
@ -62,7 +61,7 @@ function test() {
yield resumeAndTestBreakpoint(20); yield resumeAndTestBreakpoint(20);
yield doResume(gPanel); yield doResume(gPanel);
executeSoon(() => gDebuggee.ermahgerd()); callInTab(gTab, "ermahgerd");
yield waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES); yield waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES);
yield resumeAndTestBreakpoint(20); yield resumeAndTestBreakpoint(20);

Просмотреть файл

@ -15,7 +15,7 @@ function test() {
let gPanel, gDebugger, gThreadClient, gEvents; let gPanel, gDebugger, gThreadClient, gEvents;
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gPanel = aPanel; gPanel = aPanel;
gDebugger = gPanel.panelWin; gDebugger = gPanel.panelWin;
gThreadClient = gDebugger.gThreadClient; gThreadClient = gDebugger.gThreadClient;

Просмотреть файл

@ -8,12 +8,11 @@
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html"; const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
function test() { function test() {
let gTab, gDebuggee, gPanel, gDebugger; let gTab, gPanel, gDebugger;
let gSources, gBreakpoints; let gSources, gBreakpoints;
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab; gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel; gPanel = aPanel;
gDebugger = gPanel.panelWin; gDebugger = gPanel.panelWin;
gSources = gDebugger.DebuggerView.Sources; gSources = gDebugger.DebuggerView.Sources;

Просмотреть файл

@ -9,12 +9,11 @@
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html"; const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
function test() { function test() {
let gTab, gDebuggee, gPanel, gDebugger; let gTab, gPanel, gDebugger;
let gSources, gBreakpoints; let gSources, gBreakpoints;
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab; gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel; gPanel = aPanel;
gDebugger = gPanel.panelWin; gDebugger = gPanel.panelWin;
gSources = gDebugger.DebuggerView.Sources; gSources = gDebugger.DebuggerView.Sources;

Просмотреть файл

@ -8,12 +8,11 @@
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html"; const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
function test() { function test() {
let gTab, gDebuggee, gPanel, gDebugger; let gTab, gPanel, gDebugger;
let gEditor, gSources, gContextMenu, gBreakpoints, gBreakpointsAdded; let gEditor, gSources, gContextMenu, gBreakpoints, gBreakpointsAdded;
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab; gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel; gPanel = aPanel;
gDebugger = gPanel.panelWin; gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor; gEditor = gDebugger.DebuggerView.editor;
@ -29,7 +28,7 @@ function test() {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack); ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
}); });
gDebuggee.firstCall(); callInTab(gTab, "firstCall");
}); });
function performTest() { function performTest() {

Просмотреть файл

@ -11,12 +11,11 @@ function test() {
// Debug test slaves are a bit slow at this test. // Debug test slaves are a bit slow at this test.
requestLongerTimeout(2); requestLongerTimeout(2);
let gTab, gDebuggee, gPanel, gDebugger; let gTab, gPanel, gDebugger;
let gSources, gBreakpoints; let gSources, gBreakpoints;
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab; gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel; gPanel = aPanel;
gDebugger = gPanel.panelWin; gDebugger = gPanel.panelWin;
gSources = gDebugger.DebuggerView.Sources; gSources = gDebugger.DebuggerView.Sources;
@ -95,13 +94,7 @@ function test() {
ok(isCaretPos(gPanel, 9), ok(isCaretPos(gPanel, 9),
"The editor location is correct before pausing."); "The editor location is correct before pausing.");
// Spin the event loop before causing the debuggee to pause, to allow sendMouseClickToTab(gTab, content.document.querySelector("button"));
// this function to return first.
executeSoon(() => {
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee);
});
return finished; return finished;
} }

Просмотреть файл

@ -8,7 +8,8 @@
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html"; const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
function test() { function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
let gTab = aTab;
let gDebugger = aPanel.panelWin; let gDebugger = aPanel.panelWin;
let gEvents = gDebugger.EVENTS; let gEvents = gDebugger.EVENTS;
let gEditor = gDebugger.DebuggerView.editor; let gEditor = gDebugger.DebuggerView.editor;
@ -66,7 +67,7 @@ function test() {
yield ensureSourceIs(aPanel, "-01.js"); yield ensureSourceIs(aPanel, "-01.js");
yield verifyView({ disabled: false, visible: true }); yield verifyView({ disabled: false, visible: true });
executeSoon(() => aDebuggee.firstCall()); callInTab(gTab, "firstCall");
yield waitForDebuggerEvents(aPanel, gEvents.FETCHED_SCOPES); yield waitForDebuggerEvents(aPanel, gEvents.FETCHED_SCOPES);
yield ensureSourceIs(aPanel, "-01.js"); yield ensureSourceIs(aPanel, "-01.js");
yield ensureCaretAt(aPanel, 5); yield ensureCaretAt(aPanel, 5);
@ -83,7 +84,7 @@ function test() {
yield ensureSourceIs(aPanel, "-02.js", true); yield ensureSourceIs(aPanel, "-02.js", true);
yield verifyView({ disabled: false, visible: false }); yield verifyView({ disabled: false, visible: false });
executeSoon(() => aDebuggee.firstCall()); callInTab(gTab, "firstCall");
yield waitForSourceAndCaretAndScopes(aPanel, "-01.js", 1); yield waitForSourceAndCaretAndScopes(aPanel, "-01.js", 1);
yield verifyView({ disabled: false, visible: true }); yield verifyView({ disabled: false, visible: true });
@ -98,7 +99,7 @@ function test() {
yield ensureSourceIs(aPanel, "-02.js", true); yield ensureSourceIs(aPanel, "-02.js", true);
yield verifyView({ disabled: true, visible: false }); yield verifyView({ disabled: true, visible: false });
executeSoon(() => aDebuggee.firstCall()); callInTab(gTab, "firstCall");
yield waitForDebuggerEvents(aPanel, gEvents.FETCHED_SCOPES); yield waitForDebuggerEvents(aPanel, gEvents.FETCHED_SCOPES);
yield ensureSourceIs(aPanel, "-02.js"); yield ensureSourceIs(aPanel, "-02.js");
yield ensureCaretAt(aPanel, 1); yield ensureCaretAt(aPanel, 1);

Просмотреть файл

@ -9,12 +9,11 @@
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html"; const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
function test() { function test() {
let gTab, gDebuggee, gPanel, gDebugger; let gTab, gPanel, gDebugger;
let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving; let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving;
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab; gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel; gPanel = aPanel;
gDebugger = gPanel.panelWin; gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor; gEditor = gDebugger.DebuggerView.editor;
@ -24,7 +23,7 @@ function test() {
gBreakpointsRemoving = gBreakpoints._removing; gBreakpointsRemoving = gBreakpoints._removing;
waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1).then(performTest); waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1).then(performTest);
gDebuggee.firstCall(); callInTab(gTab, "firstCall");
}); });
function performTest() { function performTest() {

Просмотреть файл

@ -8,12 +8,11 @@
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html"; const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
function test() { function test() {
let gTab, gDebuggee, gPanel, gDebugger; let gTab, gPanel, gDebugger;
let gEditor, gSources; let gEditor, gSources;
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab; gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel; gPanel = aPanel;
gDebugger = gPanel.panelWin; gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor; gEditor = gDebugger.DebuggerView.editor;

Просмотреть файл

@ -8,12 +8,11 @@
const TAB_URL = EXAMPLE_URL + "doc_inline-script.html"; const TAB_URL = EXAMPLE_URL + "doc_inline-script.html";
let gTab, gDebuggee, gPanel, gDebugger; let gTab, gPanel, gDebugger;
function test() { function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab; gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel; gPanel = aPanel;
gDebugger = gPanel.panelWin; gDebugger = gPanel.panelWin;
@ -33,7 +32,7 @@ function addBreakpoint() {
}); });
}); });
gDebuggee.runDebuggerStatement(); callInTab(gTab, "runDebuggerStatement");
} }
function testResume() { function testResume() {
@ -54,9 +53,7 @@ function testResume() {
}); });
}); });
EventUtils.sendMouseEvent({ type: "click" }, sendMouseClickToTab(gTab, content.document.querySelector("button"));
gDebuggee.document.querySelector("button"),
gDebuggee);
}); });
} }
@ -84,7 +81,6 @@ function testBreakpointHit() {
registerCleanupFunction(function() { registerCleanupFunction(function() {
gTab = null; gTab = null;
gDebuggee = null;
gPanel = null; gPanel = null;
gDebugger = null; gDebugger = null;
}); });

Просмотреть файл

@ -9,8 +9,8 @@
const TAB_URL = EXAMPLE_URL + "doc_breakpoints-other-tabs.html"; const TAB_URL = EXAMPLE_URL + "doc_breakpoints-other-tabs.html";
let test = Task.async(function* () { let test = Task.async(function* () {
const [tab1, debuggee1, panel1] = yield initDebugger(TAB_URL); const [tab1,, panel1] = yield initDebugger(TAB_URL);
const [tab2, debuggee2, panel2] = yield initDebugger(TAB_URL); const [tab2,, panel2] = yield initDebugger(TAB_URL);
yield ensureSourceIs(panel1, "code_breakpoints-other-tabs.js", true); yield ensureSourceIs(panel1, "code_breakpoints-other-tabs.js", true);
@ -22,7 +22,7 @@ let test = Task.async(function* () {
}); });
const paused = waitForThreadEvents(panel2, "paused"); const paused = waitForThreadEvents(panel2, "paused");
executeSoon(() => debuggee2.testCase()); callInTab(tab2, "testCase");
const packet = yield paused; const packet = yield paused;
is(packet.why.type, "debuggerStatement", is(packet.why.type, "debuggerStatement",

Просмотреть файл

@ -9,12 +9,11 @@
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html"; const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
function test() { function test() {
let gTab, gDebuggee, gPanel, gDebugger; let gTab, gPanel, gDebugger;
let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving; let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving;
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab; gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel; gPanel = aPanel;
gDebugger = gPanel.panelWin; gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor; gEditor = gDebugger.DebuggerView.editor;
@ -24,7 +23,7 @@ function test() {
gBreakpointsRemoving = gBreakpoints._removing; gBreakpointsRemoving = gBreakpoints._removing;
waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1).then(performTest); waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1).then(performTest);
gDebuggee.firstCall(); callInTab(gTab, "firstCall");
}); });
let breakpointsAdded = 0; let breakpointsAdded = 0;

Просмотреть файл

@ -11,7 +11,7 @@ const TAB_URL = EXAMPLE_URL + "doc_breakpoints-reload.html";
let test = Task.async(function* () { let test = Task.async(function* () {
requestLongerTimeout(4); 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); yield ensureSourceIs(panel, "doc_breakpoints-reload.html", true);

Просмотреть файл

@ -5,13 +5,12 @@
* Make sure that the variables view is keyboard accessible. * Make sure that the variables view is keyboard accessible.
*/ */
let gTab, gDebuggee, gPanel, gDebugger; let gTab, gPanel, gDebugger;
let gVariablesView; let gVariablesView;
function test() { function test() {
initDebugger("about:blank").then(([aTab, aDebuggee, aPanel]) => { initDebugger("about:blank").then(([aTab,, aPanel]) => {
gTab = aTab; gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel; gPanel = aPanel;
gDebugger = gPanel.panelWin; gDebugger = gPanel.panelWin;
gVariablesView = gDebugger.DebuggerView.Variables; gVariablesView = gDebugger.DebuggerView.Variables;
@ -504,7 +503,6 @@ function performTest() {
registerCleanupFunction(function() { registerCleanupFunction(function() {
gTab = null; gTab = null;
gDebuggee = null;
gPanel = null; gPanel = null;
gDebugger = null; gDebugger = null;
gVariablesView = null; gVariablesView = null;

Просмотреть файл

@ -6,13 +6,12 @@
* when given some raw data. * when given some raw data.
*/ */
let gTab, gDebuggee, gPanel, gDebugger; let gTab, gPanel, gDebugger;
let gVariablesView, gScope, gVariable; let gVariablesView, gScope, gVariable;
function test() { function test() {
initDebugger("about:blank").then(([aTab, aDebuggee, aPanel]) => { initDebugger("about:blank").then(([aTab,, aPanel]) => {
gTab = aTab; gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel; gPanel = aPanel;
gDebugger = gPanel.panelWin; gDebugger = gPanel.panelWin;
gVariablesView = gDebugger.DebuggerView.Variables; gVariablesView = gDebugger.DebuggerView.Variables;
@ -602,7 +601,6 @@ function testClearHierarchy() {
registerCleanupFunction(function() { registerCleanupFunction(function() {
gTab = null; gTab = null;
gDebuggee = null;
gPanel = null; gPanel = null;
gDebugger = null; gDebugger = null;
gVariablesView = null; gVariablesView = null;

Просмотреть файл

@ -10,14 +10,13 @@ const TAB_URL = EXAMPLE_URL + "doc_watch-expressions.html";
function test() { function test() {
Task.spawn(function*() { Task.spawn(function*() {
let [tab, debuggee, panel] = yield initDebugger(TAB_URL); let [tab,, panel] = yield initDebugger(TAB_URL);
let win = panel.panelWin; let win = panel.panelWin;
let vars = win.DebuggerView.Variables; let vars = win.DebuggerView.Variables;
win.DebuggerView.WatchExpressions.addExpression("this"); win.DebuggerView.WatchExpressions.addExpression("this");
// Allow this generator function to yield first. callInTab(tab, "ermahgerd");
executeSoon(() => debuggee.ermahgerd());
yield waitForDebuggerEvents(panel, win.EVENTS.FETCHED_WATCH_EXPRESSIONS); yield waitForDebuggerEvents(panel, win.EVENTS.FETCHED_WATCH_EXPRESSIONS);
let exprScope = vars.getScopeAtIndex(0); let exprScope = vars.getScopeAtIndex(0);

Просмотреть файл

@ -7,16 +7,15 @@
const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html"; const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
let gTab, gDebuggee, gPanel, gDebugger; let gTab, gPanel, gDebugger;
let gL10N, gEditor, gVars, gWatch; let gL10N, gEditor, gVars, gWatch;
function test() { function test() {
// Debug test slaves are a bit slow at this test. // Debug test slaves are a bit slow at this test.
requestLongerTimeout(2); requestLongerTimeout(2);
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab; gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel; gPanel = aPanel;
gDebugger = gPanel.panelWin; gDebugger = gPanel.panelWin;
gL10N = gDebugger.L10N; gL10N = gDebugger.L10N;
@ -115,9 +114,7 @@ function test() {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack); ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
}); });
EventUtils.sendMouseEvent({ type: "click" }, sendMouseClickToTab(gTab, content.document.querySelector("button"));
gDebuggee.document.querySelector("button"),
gDebuggee);
}); });
} }
@ -288,7 +285,6 @@ function testWatchExpressionsRemoved() {
registerCleanupFunction(function() { registerCleanupFunction(function() {
gTab = null; gTab = null;
gDebuggee = null;
gPanel = null; gPanel = null;
gDebugger = null; gDebugger = null;
gL10N = null; gL10N = null;

Просмотреть файл

@ -8,16 +8,15 @@
const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html"; const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
let gTab, gDebuggee, gPanel, gDebugger; let gTab, gPanel, gDebugger;
let gL10N, gEditor, gVars, gWatch; let gL10N, gEditor, gVars, gWatch;
function test() { function test() {
// Debug test slaves are a bit slow at this test. // Debug test slaves are a bit slow at this test.
requestLongerTimeout(2); requestLongerTimeout(2);
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab; gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel; gPanel = aPanel;
gDebugger = gPanel.panelWin; gDebugger = gPanel.panelWin;
gL10N = gDebugger.L10N; gL10N = gDebugger.L10N;
@ -36,9 +35,7 @@ function test() {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack); ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
}); });
EventUtils.sendMouseEvent({ type: "click" }, sendMouseClickToTab(gTab, content.document.querySelector("button"));
gDebuggee.document.querySelector("button"),
gDebuggee);
}); });
} }
@ -94,7 +91,6 @@ function testEdit(aString, aExpected) {
registerCleanupFunction(function() { registerCleanupFunction(function() {
gTab = null; gTab = null;
gDebuggee = null;
gPanel = null; gPanel = null;
gDebugger = null; gDebugger = null;
gL10N = null; gL10N = null;

Просмотреть файл

@ -7,13 +7,12 @@
const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html"; const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
let gTab, gDebuggee, gPanel, gDebugger; let gTab, gPanel, gDebugger;
let gVars; let gVars;
function test() { function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab; gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel; gPanel = aPanel;
gDebugger = gPanel.panelWin; gDebugger = gPanel.panelWin;
gVars = gDebugger.DebuggerView.Variables; gVars = gDebugger.DebuggerView.Variables;
@ -38,9 +37,7 @@ function test() {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack); ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
}); });
EventUtils.sendMouseEvent({ type: "click" }, sendMouseClickToTab(gTab, content.document.querySelector("button"));
gDebuggee.document.querySelector("button"),
gDebuggee);
}); });
} }
@ -82,7 +79,6 @@ function testModification(aNewValue, aNewResult) {
registerCleanupFunction(function() { registerCleanupFunction(function() {
gTab = null; gTab = null;
gDebuggee = null;
gPanel = null; gPanel = null;
gDebugger = null; gDebugger = null;
gVars = null; gVars = null;

Просмотреть файл

@ -7,13 +7,12 @@
const TAB_URL = EXAMPLE_URL + "doc_watch-expressions.html"; const TAB_URL = EXAMPLE_URL + "doc_watch-expressions.html";
let gTab, gDebuggee, gPanel, gDebugger; let gTab, gPanel, gDebugger;
let gL10N, gEditor, gVars, gWatch; let gL10N, gEditor, gVars, gWatch;
function test() { function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab; gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel; gPanel = aPanel;
gDebugger = gPanel.panelWin; gDebugger = gPanel.panelWin;
gL10N = gDebugger.L10N; gL10N = gDebugger.L10N;
@ -44,7 +43,7 @@ function test() {
}); });
addExpressions(); addExpressions();
gDebuggee.ermahgerd(); callInTab(gTab, "ermahgerd");
}); });
} }
@ -494,7 +493,6 @@ function addCmdExpression(aString) {
registerCleanupFunction(function() { registerCleanupFunction(function() {
gTab = null; gTab = null;
gDebuggee = null;
gPanel = null; gPanel = null;
gDebugger = null; gDebugger = null;
gL10N = null; gL10N = null;

Просмотреть файл

@ -7,13 +7,12 @@
const TAB_URL = EXAMPLE_URL + "doc_with-frame.html"; const TAB_URL = EXAMPLE_URL + "doc_with-frame.html";
let gTab, gDebuggee, gPanel, gDebugger; let gTab, gPanel, gDebugger;
let gPrefs, gOptions, gVariables; let gPrefs, gOptions, gVariables;
function test() { function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab; gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel; gPanel = aPanel;
gDebugger = gPanel.panelWin; gDebugger = gPanel.panelWin;
gPrefs = gDebugger.Prefs; gPrefs = gDebugger.Prefs;
@ -72,7 +71,6 @@ function performTest() {
registerCleanupFunction(function() { registerCleanupFunction(function() {
gTab = null; gTab = null;
gDebuggee = null;
gPanel = null; gPanel = null;
gDebugger = null; gDebugger = null;
gPrefs = null; gPrefs = null;

Просмотреть файл

@ -8,13 +8,12 @@
const TAB_URL = EXAMPLE_URL + "doc_with-frame.html"; const TAB_URL = EXAMPLE_URL + "doc_with-frame.html";
let gTab, gDebuggee, gPanel, gDebugger; let gTab, gPanel, gDebugger;
let gVariables; let gVariables;
function test() { function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab; gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel; gPanel = aPanel;
gDebugger = gPanel.panelWin; gDebugger = gPanel.panelWin;
gVariables = gDebugger.DebuggerView.Variables; gVariables = gDebugger.DebuggerView.Variables;
@ -139,7 +138,6 @@ function performTest() {
registerCleanupFunction(function() { registerCleanupFunction(function() {
gTab = null; gTab = null;
gDebuggee = null;
gPanel = null; gPanel = null;
gDebugger = null; gDebugger = null;
gVariables = null; gVariables = null;

Просмотреть файл

@ -8,16 +8,15 @@
const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html"; const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
let gTab, gDebuggee, gPanel, gDebugger; let gTab, gPanel, gDebugger;
let gVariables; let gVariables;
function test() { function test() {
// Debug test slaves are a bit slow at this test. // Debug test slaves are a bit slow at this test.
requestLongerTimeout(2); requestLongerTimeout(2);
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab; gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel; gPanel = aPanel;
gDebugger = gPanel.panelWin; gDebugger = gPanel.panelWin;
gVariables = gDebugger.DebuggerView.Variables; gVariables = gDebugger.DebuggerView.Variables;
@ -30,9 +29,7 @@ function test() {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack); ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
}); });
EventUtils.sendMouseEvent({ type: "click" }, sendMouseClickToTab(gTab, content.document.querySelector("button"));
gDebuggee.document.querySelector("button"),
gDebuggee);
}); });
} }
@ -253,7 +250,6 @@ function testExpandVariables() {
registerCleanupFunction(function() { registerCleanupFunction(function() {
gTab = null; gTab = null;
gDebuggee = null;
gPanel = null; gPanel = null;
gDebugger = null; gDebugger = null;
gVariables = null; gVariables = null;

Просмотреть файл

@ -8,16 +8,15 @@
const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html"; const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
let gTab, gDebuggee, gPanel, gDebugger; let gTab, gPanel, gDebugger;
let gVariables; let gVariables;
function test() { function test() {
// Debug test slaves are a bit slow at this test. // Debug test slaves are a bit slow at this test.
requestLongerTimeout(2); requestLongerTimeout(2);
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab; gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel; gPanel = aPanel;
gDebugger = gPanel.panelWin; gDebugger = gPanel.panelWin;
gVariables = gDebugger.DebuggerView.Variables; gVariables = gDebugger.DebuggerView.Variables;
@ -35,9 +34,7 @@ function test() {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack); ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
}); });
EventUtils.sendMouseEvent({ type: "click" }, sendMouseClickToTab(gTab, content.document.querySelector("button"));
gDebuggee.document.querySelector("button"),
gDebuggee);
}); });
} }
@ -543,7 +540,6 @@ function testGetterSetterObject() {
registerCleanupFunction(function() { registerCleanupFunction(function() {
gTab = null; gTab = null;
gDebuggee = null;
gPanel = null; gPanel = null;
gDebugger = null; gDebugger = null;
gVariables = null; gVariables = null;

Просмотреть файл

@ -8,16 +8,15 @@
const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html"; const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
let gTab, gDebuggee, gPanel, gDebugger; let gTab, gPanel, gDebugger;
let gVariables; let gVariables;
function test() { function test() {
// Debug test slaves are a bit slow at this test. // Debug test slaves are a bit slow at this test.
requestLongerTimeout(2); requestLongerTimeout(2);
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab; gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel; gPanel = aPanel;
gDebugger = gPanel.panelWin; gDebugger = gPanel.panelWin;
gVariables = gDebugger.DebuggerView.Variables; gVariables = gDebugger.DebuggerView.Variables;
@ -32,9 +31,7 @@ function test() {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack); ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
}); });
EventUtils.sendMouseEvent({ type: "click" }, sendMouseClickToTab(gTab, content.document.querySelector("button"));
gDebuggee.document.querySelector("button"),
gDebuggee);
}); });
} }
@ -148,7 +145,6 @@ function testWindowVariable() {
registerCleanupFunction(function() { registerCleanupFunction(function() {
gTab = null; gTab = null;
gDebuggee = null;
gPanel = null; gPanel = null;
gDebugger = null; gDebugger = null;
gVariables = null; gVariables = null;

Просмотреть файл

@ -7,13 +7,12 @@
const TAB_URL = EXAMPLE_URL + "doc_with-frame.html"; const TAB_URL = EXAMPLE_URL + "doc_with-frame.html";
let gTab, gDebuggee, gPanel, gDebugger; let gTab, gPanel, gDebugger;
let gVariables; let gVariables;
function test() { function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab; gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel; gPanel = aPanel;
gDebugger = gPanel.panelWin; gDebugger = gPanel.panelWin;
gVariables = gDebugger.DebuggerView.Variables; gVariables = gDebugger.DebuggerView.Variables;
@ -34,9 +33,7 @@ function test() {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack); ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
}); });
EventUtils.sendMouseEvent({ type: "click" }, sendMouseClickToTab(gTab, content.document.querySelector("button"));
gDebuggee.document.querySelector("button"),
gDebuggee);
}); });
} }
@ -204,7 +201,6 @@ function testFunctionScope() {
registerCleanupFunction(function() { registerCleanupFunction(function() {
gTab = null; gTab = null;
gDebuggee = null;
gPanel = null; gPanel = null;
gDebugger = null; gDebugger = null;
gVariables = null; gVariables = null;

Просмотреть файл

@ -8,12 +8,11 @@
const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html"; const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
let gTab, gDebuggee, gPanel, gDebugger; let gTab, gPanel, gDebugger;
function test() { function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab; gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel; gPanel = aPanel;
gDebugger = gPanel.panelWin; gDebugger = gPanel.panelWin;
@ -24,7 +23,7 @@ function test() {
function prepareTest() { function prepareTest() {
gDebugger.once(gDebugger.EVENTS.FETCHED_SCOPES, runTest); gDebugger.once(gDebugger.EVENTS.FETCHED_SCOPES, runTest);
gDebuggee.eval("(" + function() { evalInTab(gTab, "(" + function() {
var frozen = Object.freeze({}); var frozen = Object.freeze({});
var sealed = Object.seal({}); var sealed = Object.seal({});
var nonExtensible = Object.preventExtensions({}); var nonExtensible = Object.preventExtensions({});
@ -83,7 +82,6 @@ function runTest() {
registerCleanupFunction(function() { registerCleanupFunction(function() {
gTab = null; gTab = null;
gDebuggee = null;
gPanel = null; gPanel = null;
gDebugger = null; gDebugger = null;
}); });

Просмотреть файл

@ -8,17 +8,16 @@
const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html"; const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
let gTab, gDebuggee, gPanel, gDebugger; let gTab, gPanel, gDebugger;
function test() { function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab; gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel; gPanel = aPanel;
gDebugger = gPanel.panelWin; gDebugger = gPanel.panelWin;
waitForSourceAndCaretAndScopes(gPanel, ".html", 14).then(performTest); waitForSourceAndCaretAndScopes(gPanel, ".html", 14).then(performTest);
gDebuggee.simpleCall(); callInTab(gTab, "simpleCall");
}); });
} }
@ -101,7 +100,6 @@ function performTest() {
registerCleanupFunction(function() { registerCleanupFunction(function() {
gTab = null; gTab = null;
gDebuggee = null;
gPanel = null; gPanel = null;
gDebugger = null; gDebugger = null;
}); });

Просмотреть файл

@ -8,13 +8,12 @@
const TAB_URL = EXAMPLE_URL + "doc_large-array-buffer.html"; const TAB_URL = EXAMPLE_URL + "doc_large-array-buffer.html";
let gTab, gDebuggee, gPanel, gDebugger; let gTab, gPanel, gDebugger;
let gVariables, gEllipsis; let gVariables, gEllipsis;
function test() { function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab; gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel; gPanel = aPanel;
gDebugger = gPanel.panelWin; gDebugger = gPanel.panelWin;
gVariables = gDebugger.DebuggerView.Variables; gVariables = gDebugger.DebuggerView.Variables;
@ -29,9 +28,7 @@ function test() {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack); ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
}); });
EventUtils.sendMouseEvent({ type: "click" }, sendMouseClickToTab(gTab, content.document.querySelector("button"));
gDebuggee.document.querySelector("button"),
gDebuggee);
}); });
} }
@ -235,7 +232,6 @@ function verifyNextLevels() {
registerCleanupFunction(function() { registerCleanupFunction(function() {
gTab = null; gTab = null;
gDebuggee = null;
gPanel = null; gPanel = null;
gDebugger = null; gDebugger = null;
gVariables = null; gVariables = null;

Просмотреть файл

@ -10,13 +10,12 @@ const TAB_URL = EXAMPLE_URL + "doc_scope-variable-2.html";
function test() { function test() {
Task.spawn(function() { Task.spawn(function() {
let [tab, debuggee, panel] = yield initDebugger(TAB_URL); let [tab,, panel] = yield initDebugger(TAB_URL);
let win = panel.panelWin; let win = panel.panelWin;
let events = win.EVENTS; let events = win.EVENTS;
let variables = win.DebuggerView.Variables; let variables = win.DebuggerView.Variables;
// Allow this generator function to yield first. callInTab(tab, "test");
executeSoon(() => debuggee.test());
yield waitForSourceAndCaretAndScopes(panel, ".html", 23); yield waitForSourceAndCaretAndScopes(panel, ".html", 23);
let firstScope = variables.getScopeAtIndex(0); let firstScope = variables.getScopeAtIndex(0);

Просмотреть файл

@ -9,7 +9,7 @@ const TAB_URL = EXAMPLE_URL + "doc_scope-variable-2.html";
function test() { function test() {
Task.spawn(function() { Task.spawn(function() {
let [tab, debuggee, panel] = yield initDebugger(TAB_URL); let [tab,, panel] = yield initDebugger(TAB_URL);
let win = panel.panelWin; let win = panel.panelWin;
let events = win.EVENTS; let events = win.EVENTS;
let variables = win.DebuggerView.Variables; let variables = win.DebuggerView.Variables;
@ -18,8 +18,7 @@ function test() {
let committedLocalScopeHierarchy = promise.defer(); let committedLocalScopeHierarchy = promise.defer();
variables.oncommit = committedLocalScopeHierarchy.resolve; variables.oncommit = committedLocalScopeHierarchy.resolve;
// Allow this generator function to yield first. callInTab(tab, "test");
executeSoon(() => debuggee.test());
yield waitForSourceAndCaretAndScopes(panel, ".html", 23); yield waitForSourceAndCaretAndScopes(panel, ".html", 23);
yield committedLocalScopeHierarchy.promise; yield committedLocalScopeHierarchy.promise;

Просмотреть файл

@ -7,16 +7,15 @@
const TAB_URL = EXAMPLE_URL + "doc_with-frame.html"; const TAB_URL = EXAMPLE_URL + "doc_with-frame.html";
let gTab, gDebuggee, gPanel, gDebugger; let gTab, gPanel, gDebugger;
let gBreakpoints, gSources, gVariables; let gBreakpoints, gSources, gVariables;
function test() { function test() {
// Debug test slaves are a bit slow at this test. // Debug test slaves are a bit slow at this test.
requestLongerTimeout(4); requestLongerTimeout(4);
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab; gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel; gPanel = aPanel;
gDebugger = gPanel.panelWin; gDebugger = gPanel.panelWin;
gBreakpoints = gDebugger.DebuggerController.Breakpoints; gBreakpoints = gDebugger.DebuggerController.Breakpoints;
@ -45,13 +44,7 @@ function addBreakpoint() {
} }
function pauseDebuggee() { function pauseDebuggee() {
// Spin the event loop before causing the debuggee to pause, to allow sendMouseClickToTab(gTab, content.document.querySelector("button"));
// this function to return first.
executeSoon(() => {
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee);
});
// The first 'with' scope should be expanded by default, but the // The first 'with' scope should be expanded by default, but the
// variables haven't been fetched yet. This is how 'with' scopes work. // variables haven't been fetched yet. This is how 'with' scopes work.
@ -200,7 +193,6 @@ function prepareVariablesAndProperties() {
registerCleanupFunction(function() { registerCleanupFunction(function() {
gTab = null; gTab = null;
gDebuggee = null;
gPanel = null; gPanel = null;
gDebugger = null; gDebugger = null;
gBreakpoints = null; gBreakpoints = null;

Просмотреть файл

@ -8,16 +8,15 @@
const TAB_URL = EXAMPLE_URL + "doc_with-frame.html"; const TAB_URL = EXAMPLE_URL + "doc_with-frame.html";
let gTab, gDebuggee, gPanel, gDebugger; let gTab, gPanel, gDebugger;
let gBreakpoints, gSources, gVariables; let gBreakpoints, gSources, gVariables;
function test() { function test() {
// Debug test slaves are a bit slow at this test. // Debug test slaves are a bit slow at this test.
requestLongerTimeout(4); requestLongerTimeout(4);
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab; gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel; gPanel = aPanel;
gDebugger = gPanel.panelWin; gDebugger = gPanel.panelWin;
gBreakpoints = gDebugger.DebuggerController.Breakpoints; gBreakpoints = gDebugger.DebuggerController.Breakpoints;
@ -46,13 +45,7 @@ function addBreakpoint() {
} }
function pauseDebuggee() { function pauseDebuggee() {
// Spin the event loop before causing the debuggee to pause, to allow sendMouseClickToTab(gTab, content.document.querySelector("button"));
// this function to return first.
executeSoon(() => {
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee);
});
// The first 'with' scope should be expanded by default, but the // The first 'with' scope should be expanded by default, but the
// variables haven't been fetched yet. This is how 'with' scopes work. // variables haven't been fetched yet. This is how 'with' scopes work.
@ -215,7 +208,6 @@ function prepareVariablesAndProperties() {
registerCleanupFunction(function() { registerCleanupFunction(function() {
gTab = null; gTab = null;
gDebuggee = null;
gPanel = null; gPanel = null;
gDebugger = null; gDebugger = null;
gBreakpoints = null; gBreakpoints = null;

Просмотреть файл

@ -7,16 +7,15 @@
const TAB_URL = EXAMPLE_URL + "doc_scope-variable-4.html"; const TAB_URL = EXAMPLE_URL + "doc_scope-variable-4.html";
let gTab, gDebuggee, gPanel, gDebugger; let gTab, gPanel, gDebugger;
let gBreakpoints, gSources, gVariables; let gBreakpoints, gSources, gVariables;
function test() { function test() {
// Debug test slaves are a bit slow at this test. // Debug test slaves are a bit slow at this test.
requestLongerTimeout(4); requestLongerTimeout(4);
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab; gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel; gPanel = aPanel;
gDebugger = gPanel.panelWin; gDebugger = gPanel.panelWin;
gBreakpoints = gDebugger.DebuggerController.Breakpoints; gBreakpoints = gDebugger.DebuggerController.Breakpoints;
@ -45,11 +44,7 @@ function addBreakpoint() {
} }
function pauseDebuggee() { function pauseDebuggee() {
// Spin the event loop before causing the debuggee to pause, to allow callInTab(gTab, "test");
// this function to return first.
executeSoon(() => {
gDebuggee.test();
});
return waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES); return waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES);
} }
@ -120,7 +115,6 @@ function prepareScopes() {
registerCleanupFunction(function() { registerCleanupFunction(function() {
gTab = null; gTab = null;
gDebuggee = null;
gPanel = null; gPanel = null;
gDebugger = null; gDebugger = null;
gBreakpoints = null; gBreakpoints = null;

Просмотреть файл

@ -8,16 +8,15 @@
const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html"; const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
let gTab, gDebuggee, gPanel, gDebugger; let gTab, gPanel, gDebugger;
let gVariables; let gVariables;
function test() { function test() {
// Debug test slaves are a bit slow at this test. // Debug test slaves are a bit slow at this test.
requestLongerTimeout(2); requestLongerTimeout(2);
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab; gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel; gPanel = aPanel;
gDebugger = gPanel.panelWin; gDebugger = gPanel.panelWin;
gVariables = gDebugger.DebuggerView.Variables; gVariables = gDebugger.DebuggerView.Variables;
@ -30,9 +29,7 @@ function test() {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack); ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
}); });
EventUtils.sendMouseEvent({ type: "click" }, sendMouseClickToTab(gTab, content.document.querySelector("button"));
gDebuggee.document.querySelector("button"),
gDebuggee);
}); });
} }
@ -253,7 +250,6 @@ function performTest() {
registerCleanupFunction(function() { registerCleanupFunction(function() {
gTab = null; gTab = null;
gDebuggee = null;
gPanel = null; gPanel = null;
gDebugger = null; gDebugger = null;
gVariables = null; gVariables = null;

Просмотреть файл

@ -11,12 +11,11 @@ function test() {
// Debug test slaves are a bit slow at this test. // Debug test slaves are a bit slow at this test.
requestLongerTimeout(2); requestLongerTimeout(2);
let gTab, gDebuggee, gPanel, gDebugger; let gTab, gPanel, gDebugger;
let gEditor, gWatch, gVariables; let gEditor, gWatch, gVariables;
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab; gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel; gPanel = aPanel;
gDebugger = gPanel.panelWin; gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor; gEditor = gDebugger.DebuggerView.editor;

Просмотреть файл

@ -11,12 +11,11 @@ function test() {
// Debug test slaves are a bit slow at this test. // Debug test slaves are a bit slow at this test.
requestLongerTimeout(2); requestLongerTimeout(2);
let gTab, gDebuggee, gPanel, gDebugger; let gTab, gPanel, gDebugger;
let gWatch, gVariables; let gWatch, gVariables;
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab; gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel; gPanel = aPanel;
gDebugger = gPanel.panelWin; gDebugger = gPanel.panelWin;
gWatch = gDebugger.DebuggerView.WatchExpressions; gWatch = gDebugger.DebuggerView.WatchExpressions;
@ -113,7 +112,7 @@ function test() {
aCallback(); aCallback();
}); });
gDebuggee.test(); callInTab(gTab, "test");
} }
function test2(aCallback) { function test2(aCallback) {

Просмотреть файл

@ -24,3 +24,10 @@ addMessageListener("test:click", function (message) {
EventUtils.synthesizeMouseAtCenter(target, {}, EventUtils.synthesizeMouseAtCenter(target, {},
target.ownerDocument.defaultView); target.ownerDocument.defaultView);
}); });
addMessageListener("test:eval", function (message) {
dump("Evalling string " + message.data.string + ".\n");
content.eval(message.data.string);
sendAsyncMessage("test:eval");
});

Просмотреть файл

@ -970,6 +970,15 @@ function callInTab(tab, name) {
waitForMessageFromTab(tab, "test:call"); 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) { function sendMouseClickToTab(tab, target) {
info("Sending mouse click to tab."); info("Sending mouse click to tab.");

Просмотреть файл

@ -13,6 +13,8 @@ var gRGB_TO_HSL = {
"rgb(96, 201, 58)": "hsl(104,57%,51%)", "rgb(96, 201, 58)": "hsl(104,57%,51%)",
"rgb(240, 195, 111)": "hsl(39,82%,69%)", "rgb(240, 195, 111)": "hsl(39,82%,69%)",
"rgb(227, 155, 22)": "hsl(39,82%,49%)", "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*() { let test = Task.async(function*() {

Просмотреть файл

@ -55,7 +55,13 @@ const TIMELINE_BLUEPRINT = {
fill: "hsl(0,0%,80%)", fill: "hsl(0,0%,80%)",
stroke: "hsl(0,0%,60%)", stroke: "hsl(0,0%,60%)",
label: L10N.getStr("timeline.label.consoleTime") 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. // Exported symbols.

Просмотреть файл

@ -38,6 +38,7 @@ timeline.records=RECORDS
timeline.label.styles=Styles timeline.label.styles=Styles
timeline.label.reflow=Reflow timeline.label.reflow=Reflow
timeline.label.paint=Paint timeline.label.paint=Paint
timeline.label.javascript=Javascript
timeline.label.domevent=DOM Event timeline.label.domevent=DOM Event
timeline.label.consoleTime=Console timeline.label.consoleTime=Console

Просмотреть файл

@ -12,12 +12,19 @@ public class AnnotationInfo {
public final boolean isMultithreaded; public final boolean isMultithreaded;
public final boolean noThrow; public final boolean noThrow;
public final boolean narrowChars; public final boolean narrowChars;
public final boolean catchException;
public AnnotationInfo(String aWrapperName, boolean aIsMultithreaded, public AnnotationInfo(String aWrapperName, boolean aIsMultithreaded,
boolean aNoThrow, boolean aNarrowChars) { boolean aNoThrow, boolean aNarrowChars, boolean aCatchException) {
wrapperName = aWrapperName; wrapperName = aWrapperName;
isMultithreaded = aIsMultithreaded; isMultithreaded = aIsMultithreaded;
noThrow = aNoThrow; noThrow = aNoThrow;
narrowChars = aNarrowChars; 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");
}
} }
} }

Просмотреть файл

@ -52,7 +52,7 @@ public class AnnotationProcessor {
"namespace mozilla {\n" + "namespace mozilla {\n" +
"namespace widget {\n" + "namespace widget {\n" +
"namespace android {\n" + "namespace android {\n" +
"void InitStubs(JNIEnv *jEnv);\n\n"); "void InitStubs(JNIEnv *env);\n\n");
StringBuilder implementationFile = new StringBuilder(GENERATED_COMMENT); StringBuilder implementationFile = new StringBuilder(GENERATED_COMMENT);
implementationFile.append("#include \"GeneratedJNIWrappers.h\"\n" + 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. // Used to track the calls to the various class-specific initialisation functions.
StringBuilder stubInitialiser = new StringBuilder(); StringBuilder stubInitialiser = new StringBuilder();
stubInitialiser.append("void InitStubs(JNIEnv *jEnv) {\n"); stubInitialiser.append("void InitStubs(JNIEnv *env) {\n");
while (jarClassIterator.hasNext()) { while (jarClassIterator.hasNext()) {
ClassWithOptions aClassTuple = jarClassIterator.next(); ClassWithOptions aClassTuple = jarClassIterator.next();
@ -81,7 +81,7 @@ public class AnnotationProcessor {
} }
generatorInstance = new CodeGenerator(aClassTuple.wrappedClass, aClassTuple.generatedName); 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.. // Iterate all annotated members in this class..
while (methodIterator.hasNext()) { while (methodIterator.hasNext()) {

Просмотреть файл

@ -12,6 +12,7 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Member; import java.lang.reflect.Member;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -40,21 +41,27 @@ public class CodeGenerator {
private final HashSet<String> mTakenMemberNames = new HashSet<String>(); private final HashSet<String> mTakenMemberNames = new HashSet<String>();
private int mNameMunger; private int mNameMunger;
private final boolean mLazyInit;
public CodeGenerator(Class<?> aClass, String aGeneratedName) { public CodeGenerator(Class<?> aClass, String aGeneratedName) {
this(aClass, aGeneratedName, false);
}
public CodeGenerator(Class<?> aClass, String aGeneratedName, boolean aLazyInit) {
mClassToWrap = aClass; mClassToWrap = aClass;
mCClassName = aGeneratedName; mCClassName = aGeneratedName;
mLazyInit = aLazyInit;
// Write the file header things. Includes and so forth. // Write the file header things. Includes and so forth.
// GeneratedJNIWrappers.cpp is generated as the concatenation of wrapperStartupCode with // GeneratedJNIWrappers.cpp is generated as the concatenation of wrapperStartupCode with
// wrapperMethodBodies. Similarly, GeneratedJNIWrappers.h is the concatenation of headerPublic // wrapperMethodBodies. Similarly, GeneratedJNIWrappers.h is the concatenation of headerPublic
// with headerProtected. // with headerProtected.
wrapperStartupCode.append("void ").append(mCClassName).append("::InitStubs(JNIEnv *jEnv) {\n" + wrapperStartupCode.append("void ").append(mCClassName).append("::InitStubs(JNIEnv *env) {\n");
" initInit();\n");
// Now we write the various GetStaticMethodID calls here... // Now we write the various GetStaticMethodID calls here...
headerPublic.append("class ").append(mCClassName).append(" : public AutoGlobalWrappedJavaObject {\n" + headerPublic.append("class ").append(mCClassName).append(" : public AutoGlobalWrappedJavaObject {\n" +
"public:\n" + "public:\n" +
" static void InitStubs(JNIEnv *jEnv);\n"); " static void InitStubs(JNIEnv *env);\n");
headerProtected.append("protected:"); headerProtected.append("protected:");
generateWrapperMethod(); generateWrapperMethod();
@ -79,7 +86,10 @@ public class CodeGenerator {
private void generateMemberCommon(Member theMethod, String aCMethodName, Class<?> aClass) { private void generateMemberCommon(Member theMethod, String aCMethodName, Class<?> aClass) {
ensureClassHeaderAndStartup(aClass); ensureClassHeaderAndStartup(aClass);
writeMemberIdField(theMethod, aCMethodName); writeMemberIdField(theMethod, aCMethodName);
writeStartupCode(theMethod);
if (!mLazyInit) {
writeMemberInit(theMethod, wrapperStartupCode);
}
} }
/** /**
@ -101,8 +111,10 @@ public class CodeGenerator {
Class<?> returnType = theMethod.getReturnType(); Class<?> returnType = theMethod.getReturnType();
// Get the C++ method signature for this method. // Get the C++ method signature for this method.
String implementationSignature = Utils.getCImplementationMethodSignature(parameterTypes, returnType, CMethodName, mCClassName, aMethodTuple.mAnnotationInfo.narrowChars); String implementationSignature = Utils.getCImplementationMethodSignature(parameterTypes, returnType, CMethodName,
String headerSignature = Utils.getCHeaderMethodSignature(parameterTypes, theMethod.getParameterAnnotations(), returnType, CMethodName, mCClassName, isFieldStatic, aMethodTuple.mAnnotationInfo.narrowChars); 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. // Add the header signature to the header file.
writeSignatureToHeader(headerSignature); writeSignatureToHeader(headerSignature);
@ -111,19 +123,25 @@ public class CodeGenerator {
writeMethodBody(implementationSignature, theMethod, mClassToWrap, writeMethodBody(implementationSignature, theMethod, mClassToWrap,
aMethodTuple.mAnnotationInfo.isMultithreaded, aMethodTuple.mAnnotationInfo.isMultithreaded,
aMethodTuple.mAnnotationInfo.noThrow, 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; StringBuilder argumentContent = null;
Class<?> fieldType = aField.getType();
if (isSetter) { if (isSetter) {
Class<?>[] setterArguments = new Class<?>[]{aFieldType}; Class<?>[] setterArguments = new Class<?>[]{fieldType};
// Marshall the argument.. // Marshall the argument..
argumentContent = getArgumentMarshalling(setterArguments); argumentContent = getArgumentMarshalling(setterArguments);
} }
boolean isObjectReturningMethod = Utils.isObjectType(aFieldType); if (mLazyInit) {
writeMemberInit(aField, wrapperMethodBodies);
}
boolean isObjectReturningMethod = Utils.isObjectType(fieldType);
wrapperMethodBodies.append(" "); wrapperMethodBodies.append(" ");
if (isSetter) { if (isSetter) {
wrapperMethodBodies.append("env->Set"); wrapperMethodBodies.append("env->Set");
@ -131,7 +149,7 @@ public class CodeGenerator {
wrapperMethodBodies.append("return "); wrapperMethodBodies.append("return ");
if (isObjectReturningMethod) { 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"); wrapperMethodBodies.append("env->Get");
@ -140,7 +158,7 @@ public class CodeGenerator {
if (aIsFieldStatic) { if (aIsFieldStatic) {
wrapperMethodBodies.append("Static"); wrapperMethodBodies.append("Static");
} }
wrapperMethodBodies.append(Utils.getFieldType(aFieldType)) wrapperMethodBodies.append(Utils.getFieldType(fieldType))
.append("Field("); .append("Field(");
// Static will require the class and the field id. Nonstatic, the object and the field id. // 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); boolean isFieldFinal = Utils.isMemberFinal(theField);
String getterName = "get" + CFieldName; String getterName = "get" + CFieldName;
String getterSignature = Utils.getCImplementationMethodSignature(EMPTY_CLASS_ARRAY, fieldType, getterName, mCClassName, 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); String getterHeaderSignature = Utils.getCHeaderMethodSignature(EMPTY_CLASS_ARRAY, GETTER_ARGUMENT_ANNOTATIONS, fieldType, getterName, mCClassName, isFieldStatic, aFieldTuple.mAnnotationInfo.narrowChars, false);
writeSignatureToHeader(getterHeaderSignature); writeSignatureToHeader(getterHeaderSignature);
writeFunctionStartupBoilerPlate(getterSignature, true); 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 field not final, also generate a setter function.
if (!isFieldFinal) { if (!isFieldFinal) {
@ -196,14 +214,14 @@ public class CodeGenerator {
Class<?>[] setterArguments = new Class<?>[]{fieldType}; Class<?>[] setterArguments = new Class<?>[]{fieldType};
String setterSignature = Utils.getCImplementationMethodSignature(setterArguments, Void.class, setterName, mCClassName, 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); String setterHeaderSignature = Utils.getCHeaderMethodSignature(setterArguments, SETTER_ARGUMENT_ANNOTATIONS, Void.class, setterName, mCClassName, isFieldStatic, aFieldTuple.mAnnotationInfo.narrowChars, false);
writeSignatureToHeader(setterHeaderSignature); writeSignatureToHeader(setterHeaderSignature);
writeFunctionStartupBoilerPlate(setterSignature, true); 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); generateMemberCommon(theCtor, mCClassName, mClassToWrap);
String implementationSignature = Utils.getCImplementationMethodSignature(theCtor.getParameterTypes(), Void.class, CMethodName, mCClassName, aCtorTuple.mAnnotationInfo.narrowChars); String implementationSignature = Utils.getCImplementationMethodSignature(theCtor.getParameterTypes(), Void.class, CMethodName,
String headerSignature = Utils.getCHeaderMethodSignature(theCtor.getParameterTypes(), theCtor.getParameterAnnotations(), Void.class, CMethodName, mCClassName, false, aCtorTuple.mAnnotationInfo.narrowChars); 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. // Slice off the "void " from the start of the constructor declaration.
headerSignature = headerSignature.substring(5); headerSignature = headerSignature.substring(5);
@ -227,13 +247,37 @@ public class CodeGenerator {
// Use the implementation signature to generate the method body... // Use the implementation signature to generate the method body...
writeCtorBody(implementationSignature, theCtor, writeCtorBody(implementationSignature, theCtor,
aCtorTuple.mAnnotationInfo.isMultithreaded, aCtorTuple.mAnnotationInfo.isMultithreaded,
aCtorTuple.mAnnotationInfo.noThrow); aCtorTuple.mAnnotationInfo.noThrow,
aCtorTuple.mAnnotationInfo.catchException);
if (theCtor.getParameterTypes().length == 0) { if (theCtor.getParameterTypes().length == 0) {
mHasEncounteredDefaultConstructor = true; 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 * 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. * class specified. If this is already done, does nothing.
@ -258,8 +302,7 @@ public class CodeGenerator {
.append(";\n"); .append(";\n");
// Add startup code to populate it.. // Add startup code to populate it..
wrapperStartupCode.append('\n') wrapperStartupCode.append(Utils.getStartupLineForClass(aClass));
.append(Utils.getStartupLineForClass(aClass));
seenClasses.add(className); seenClasses.add(className);
} }
@ -371,14 +414,30 @@ public class CodeGenerator {
return argumentContent; 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, private void writeCtorBody(String implementationSignature, Constructor<?> theCtor,
boolean aIsThreaded, boolean aNoThrow) { boolean aIsThreaded, boolean aNoThrow, boolean aCatchException) {
Class<?>[] argumentTypes = theCtor.getParameterTypes(); Class<?>[] argumentTypes = theCtor.getParameterTypes();
writeFunctionStartupBoilerPlate(implementationSignature, aIsThreaded); writeFunctionStartupBoilerPlate(implementationSignature, aIsThreaded);
writeFramePushBoilerplate(theCtor, false, aNoThrow); writeFramePushBoilerplate(theCtor, false, aNoThrow);
if (mLazyInit) {
writeMemberInit(theCtor, wrapperMethodBodies);
}
// Marshall arguments for this constructor, if any... // Marshall arguments for this constructor, if any...
boolean hasArguments = argumentTypes.length != 0; boolean hasArguments = argumentTypes.length != 0;
@ -402,9 +461,14 @@ public class CodeGenerator {
wrapperMethodBodies.append(mMembersToIds.get(theCtor)) wrapperMethodBodies.append(mMembersToIds.get(theCtor))
// Tack on the arguments, if any.. // Tack on the arguments, if any..
.append(argumentContent) .append(argumentContent)
.append("), env);\n" + .append("), env);\n");
" env->PopLocalFrame(nullptr);\n" +
"}\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, private void writeMethodBody(String methodSignature, Method aMethod,
Class<?> aClass, boolean aIsMultithreaded, Class<?> aClass, boolean aIsMultithreaded,
boolean aNoThrow, boolean aNarrowChars) { boolean aNoThrow, boolean aNarrowChars,
boolean aCatchException) {
Class<?>[] argumentTypes = aMethod.getParameterTypes(); Class<?>[] argumentTypes = aMethod.getParameterTypes();
Class<?> returnType = aMethod.getReturnType(); Class<?> returnType = aMethod.getReturnType();
@ -427,6 +492,10 @@ public class CodeGenerator {
writeFramePushBoilerplate(aMethod, isObjectReturningMethod, aNoThrow); writeFramePushBoilerplate(aMethod, isObjectReturningMethod, aNoThrow);
if (mLazyInit) {
writeMemberInit(aMethod, wrapperMethodBodies);
}
// Marshall arguments, if we have any. // Marshall arguments, if we have any.
boolean hasArguments = argumentTypes.length != 0; boolean hasArguments = argumentTypes.length != 0;
@ -481,6 +550,11 @@ public class CodeGenerator {
wrapperMethodBodies.append(" AndroidBridge::HandleUncaughtException(env);\n"); 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 // If we're returning an object, pop the callee's stack frame extracting our ref as the return
// value. // value.
if (isObjectReturningMethod) { 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. * @param aMember The Java member being wrapped.
*/ */
private void writeStartupCode(Member aMember) { private void writeMemberInit(Member aMember, StringBuilder aOutput) {
wrapperStartupCode.append(" ") if (mLazyInit) {
.append(mMembersToIds.get(aMember)) aOutput.append(" if (!" + mMembersToIds.get(aMember) + ") {\n ");
.append(" = get"); }
aOutput.append(" " + mMembersToIds.get(aMember)).append(" = AndroidBridge::Get");
if (Utils.isMemberStatic(aMember)) { if (Utils.isMemberStatic(aMember)) {
wrapperStartupCode.append("Static"); aOutput.append("Static");
} }
boolean isField = aMember instanceof Field; boolean isField = aMember instanceof Field;
if (isField) { if (isField) {
wrapperStartupCode.append("Field(\""); aOutput.append("FieldID(env, " + Utils.getClassReferenceName(aMember.getDeclaringClass()) + ", \"");
} else { } else {
wrapperStartupCode.append("Method(\""); aOutput.append("MethodID(env, " + Utils.getClassReferenceName(aMember.getDeclaringClass()) + ", \"");
}
if (aMember instanceof Constructor) {
wrapperStartupCode.append("<init>");
} else {
wrapperStartupCode.append(aMember.getName());
} }
wrapperStartupCode.append("\", \"") if (aMember instanceof Constructor) {
aOutput.append("<init>");
} else {
aOutput.append(aMember.getName());
}
aOutput.append("\", \"")
.append(Utils.getTypeSignatureStringForMember(aMember)) .append(Utils.getTypeSignatureStringForMember(aMember))
.append("\");\n"); .append("\");\n");
if (mLazyInit) {
aOutput.append(" }\n\n");
}
} }
private void writeZeroingFor(Member aMember, final String aMemberName) { private void writeZeroingFor(Member aMember, final String aMemberName) {

Просмотреть файл

@ -4,9 +4,9 @@
include $(topsrcdir)/config/rules.mk 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 Android specific java flags, instead of what's in rules.mk.
include $(topsrcdir)/config/android-common.mk include $(topsrcdir)/config/android-common.mk
libs:: annotationProcessors.jar export:: annotationProcessors.jar

Просмотреть файл

@ -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<ClassWithOptions> 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<String> 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<Member>() {
@Override
public int compare(Member a, Member b) {
return a.getName().compareTo(b.getName());
}
});
ArrayList<Member> 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<String> 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);
}
}
}
}
}

Просмотреть файл

@ -13,6 +13,7 @@ jar.sources += [
'classloader/IterableJarLoadingURLClassLoader.java', 'classloader/IterableJarLoadingURLClassLoader.java',
'classloader/JarClassIterator.java', 'classloader/JarClassIterator.java',
'CodeGenerator.java', 'CodeGenerator.java',
'SDKProcessor.java',
'utils/AlphabeticAnnotatableEntityComparator.java', 'utils/AlphabeticAnnotatableEntityComparator.java',
'utils/GeneratableElementIterator.java', 'utils/GeneratableElementIterator.java',
'utils/Utils.java', 'utils/Utils.java',

Просмотреть файл

@ -76,6 +76,7 @@ public class GeneratableElementIterator implements Iterator<AnnotatableEntity> {
boolean isMultithreadedStub = false; boolean isMultithreadedStub = false;
boolean noThrow = false; boolean noThrow = false;
boolean narrowChars = false; boolean narrowChars = false;
boolean catchException = false;
try { try {
// Determine the explicitly-given name of the stub to generate, if any. // Determine the explicitly-given name of the stub to generate, if any.
final Method stubNameMethod = annotationType.getDeclaredMethod("stubName"); final Method stubNameMethod = annotationType.getDeclaredMethod("stubName");
@ -97,6 +98,11 @@ public class GeneratableElementIterator implements Iterator<AnnotatableEntity> {
narrowCharsMethod.setAccessible(true); narrowCharsMethod.setAccessible(true);
narrowChars = (Boolean) narrowCharsMethod.invoke(annotation); 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) { } catch (NoSuchMethodException e) {
System.err.println("Unable to find expected field on WrapElementForJNI annotation. Did the signature change?"); System.err.println("Unable to find expected field on WrapElementForJNI annotation. Did the signature change?");
e.printStackTrace(System.err); e.printStackTrace(System.err);
@ -118,7 +124,7 @@ public class GeneratableElementIterator implements Iterator<AnnotatableEntity> {
} }
AnnotationInfo annotationInfo = new AnnotationInfo( AnnotationInfo annotationInfo = new AnnotationInfo(
stubName, isMultithreadedStub, noThrow, narrowChars); stubName, isMultithreadedStub, noThrow, narrowChars, catchException);
mNextReturnValue = new AnnotatableEntity(candidateElement, annotationInfo); mNextReturnValue = new AnnotatableEntity(candidateElement, annotationInfo);
return; return;
} }
@ -128,7 +134,7 @@ public class GeneratableElementIterator implements Iterator<AnnotatableEntity> {
// thanks to the "Generate everything" annotation. // thanks to the "Generate everything" annotation.
if (mIterateEveryEntry) { if (mIterateEveryEntry) {
AnnotationInfo annotationInfo = new AnnotationInfo( AnnotationInfo annotationInfo = new AnnotationInfo(
candidateElement.getName(), false, false, false); candidateElement.getName(), false, false, false, false);
mNextReturnValue = new AnnotatableEntity(candidateElement, annotationInfo); mNextReturnValue = new AnnotatableEntity(candidateElement, annotationInfo);
return; return;
} }

Просмотреть файл

@ -318,6 +318,10 @@ public class Utils {
} }
} }
public static String getTypeSignatureStringForClass(Class<?> clazz) {
return clazz.getCanonicalName().replace('.', '/');
}
public static String getTypeSignatureString(Constructor<?> aConstructor) { public static String getTypeSignatureString(Constructor<?> aConstructor) {
Class<?>[] arguments = aConstructor.getParameterTypes(); Class<?>[] arguments = aConstructor.getParameterTypes();
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
@ -341,7 +345,7 @@ public class Utils {
* @param c The type of the element to write the subsignature of. * @param c The type of the element to write the subsignature of.
*/ */
private static void writeTypeSignature(StringBuilder sb, Class<?> c) { 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.. // Determine if this is an array type and, if so, peel away the array operators..
int len = name.length(); int len = name.length();
@ -384,7 +388,8 @@ public class Utils {
* @param aCClassName Name of the C++ class into which the method is declared. * @param aCClassName Name of the C++ class into which the method is declared.
* @return The C++ method implementation signature for the method described. * @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(); StringBuilder retBuffer = new StringBuilder();
retBuffer.append(getCReturnType(aReturnType, aNarrowChars)); retBuffer.append(getCReturnType(aReturnType, aNarrowChars));
@ -406,6 +411,14 @@ public class Utils {
retBuffer.append(", "); retBuffer.append(", ");
} }
} }
if (aCatchException) {
if (aArgumentTypes.length > 0) {
retBuffer.append(", ");
}
retBuffer.append("nsresult* aResult");
}
retBuffer.append(')'); retBuffer.append(')');
return retBuffer.toString(); return retBuffer.toString();
} }
@ -423,7 +436,8 @@ public class Utils {
* @param aIsStaticStub true if the generated C++ method should be static, false otherwise. * @param aIsStaticStub true if the generated C++ method should be static, false otherwise.
* @return The generated C++ header method signature for the method described. * @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(); StringBuilder retBuffer = new StringBuilder();
// Add the static keyword, if applicable. // Add the static keyword, if applicable.
@ -453,6 +467,14 @@ public class Utils {
retBuffer.append(", "); retBuffer.append(", ");
} }
} }
if (aCatchException) {
if (aArgumentTypes.length > 0) {
retBuffer.append(", ");
}
retBuffer.append("nsresult* aResult = nullptr");
}
retBuffer.append(')'); retBuffer.append(')');
return retBuffer.toString(); return retBuffer.toString();
} }
@ -587,9 +609,9 @@ public class Utils {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(" "); sb.append(" ");
sb.append(getClassReferenceName(aClass)); 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(); Class<?> containerClass = aClass.getDeclaringClass();
if (containerClass != null) { if (containerClass != null) {
// Is an inner class. Add the $ symbol. // Is an inner class. Add the $ symbol.

Просмотреть файл

@ -141,6 +141,10 @@ ifeq (.,$(DEPTH))
# Interdependencies for parallel export. # Interdependencies for parallel export.
js/xpconnect/src/export: dom/bindings/export xpcom/xpidl/export js/xpconnect/src/export: dom/bindings/export xpcom/xpidl/export
accessible/xpcom/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 ifdef ENABLE_CLANG_PLUGIN
$(filter-out build/clang-plugin/%,$(compile_targets)): build/clang-plugin/target build/clang-plugin/tests/target $(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 build/clang-plugin/tests/target: build/clang-plugin/target

Просмотреть файл

@ -1459,6 +1459,7 @@ if test "$GNU_CC"; then
# -Wignored-qualifiers - catches returns types with qualifiers like const # -Wignored-qualifiers - catches returns types with qualifiers like const
# -Wint-to-pointer-cast - catches cast to pointer from integer of different size # -Wint-to-pointer-cast - catches cast to pointer from integer of different size
# -Wmultichar - catches multicharacter integer constants like 'THIS' # -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 # -Wnonnull - catches NULL used with functions arguments marked as non-null
# -Wpointer-arith - catches pointer arithmetic using NULL or sizeof(void) # -Wpointer-arith - catches pointer arithmetic using NULL or sizeof(void)
# -Wpointer-sign - catches mixing pointers to signed and unsigned types # -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=sequence-point"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=trigraphs" _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=trigraphs"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=unknown-pragmas" _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 fi
# Turn off the following warnings that -Wall turns on: # 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 # -Wendif-labels - catches `#else FOO` and `#endif FOO` not in comment
# -Wint-to-pointer-cast - catches cast to pointer from integer of different size # -Wint-to-pointer-cast - catches cast to pointer from integer of different size
# -Wmissing-braces - catches aggregate initializers missing nested braces # -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 # -Woverloaded-virtual - function declaration hides virtual function from base class
# -Wparentheses - catches `if (a=b)` and operator precedence bugs # -Wparentheses - catches `if (a=b)` and operator precedence bugs
# -Wpointer-arith - catches pointer arithmetic using NULL or sizeof(void) # -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=trigraphs"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=type-limits" _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=type-limits"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=unused-label" _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 fi
# Turn off the following warnings that -Wall turns on: # Turn off the following warnings that -Wall turns on:

Просмотреть файл

@ -854,7 +854,8 @@ nsDocShell::nsDocShell():
mDefaultLoadFlags(nsIRequest::LOAD_NORMAL), mDefaultLoadFlags(nsIRequest::LOAD_NORMAL),
mFrameType(eFrameTypeRegular), mFrameType(eFrameTypeRegular),
mOwnOrContainingAppId(nsIScriptSecurityManager::UNKNOWN_APP_ID), mOwnOrContainingAppId(nsIScriptSecurityManager::UNKNOWN_APP_ID),
mParentCharsetSource(0) mParentCharsetSource(0),
mJSRunToCompletionDepth(0)
{ {
mHistoryID = ++gDocshellIDCounter; mHistoryID = ++gDocshellIDCounter;
if (gDocShellCount++ == 0) { if (gDocShellCount++ == 0) {
@ -890,6 +891,8 @@ nsDocShell::nsDocShell():
nsDocShell::~nsDocShell() nsDocShell::~nsDocShell()
{ {
MOZ_ASSERT(!mProfileTimelineRecording);
Destroy(); Destroy();
nsCOMPtr<nsISHistoryInternal> nsCOMPtr<nsISHistoryInternal>
@ -2829,14 +2832,15 @@ NS_IMETHODIMP
nsDocShell::SetRecordProfileTimelineMarkers(bool aValue) nsDocShell::SetRecordProfileTimelineMarkers(bool aValue)
{ {
#ifdef MOZ_ENABLE_PROFILER_SPS #ifdef MOZ_ENABLE_PROFILER_SPS
bool currentValue; bool currentValue = nsIDocShell::GetRecordProfileTimelineMarkers();
GetRecordProfileTimelineMarkers(&currentValue);
if (currentValue != aValue) { if (currentValue != aValue) {
if (aValue) { if (aValue) {
++gProfileTimelineRecordingsCount; ++gProfileTimelineRecordingsCount;
UseEntryScriptProfiling();
mProfileTimelineRecording = true; mProfileTimelineRecording = true;
} else { } else {
--gProfileTimelineRecordingsCount; --gProfileTimelineRecordingsCount;
UnuseEntryScriptProfiling();
mProfileTimelineRecording = false; mProfileTimelineRecording = false;
ClearProfileTimelineMarkers(); ClearProfileTimelineMarkers();
} }
@ -4243,15 +4247,17 @@ nsDocShell::AddChildSHEntry(nsISHEntry * aCloneRef, nsISHEntry * aNewEntry,
int32_t aChildOffset, uint32_t loadType, int32_t aChildOffset, uint32_t loadType,
bool aCloneChildren) 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 /* You get here if you are currently building a
* hierarchy ie.,you just visited a frameset page * hierarchy ie.,you just visited a frameset page
*/ */
nsCOMPtr<nsISHContainer> container(do_QueryInterface(mLSHE, &rv)); nsCOMPtr<nsISHContainer> container(do_QueryInterface(mLSHE, &rv));
if (container) { if (container) {
rv = container->AddChild(aNewEntry, aChildOffset); if (NS_FAILED(container->ReplaceChild(aNewEntry))) {
rv = container->AddChild(aNewEntry, aChildOffset);
}
} }
} }
else if (!aCloneRef) { else if (!aCloneRef) {
@ -4260,8 +4266,22 @@ nsDocShell::AddChildSHEntry(nsISHEntry * aCloneRef, nsISHEntry * aNewEntry,
if (container) { if (container) {
rv = container->AddChild(aNewEntry, aChildOffset); 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 are currently in the rootDocShell.
* You will get here when a subframe has a new url * You will get here when a subframe has a new url
* to load and you have walked up the tree all the * to load and you have walked up the tree all the
@ -4300,16 +4320,17 @@ nsDocShell::AddChildSHEntry(nsISHEntry * aCloneRef, nsISHEntry * aNewEntry,
nsCOMPtr<nsIDocShell> parent = nsCOMPtr<nsIDocShell> parent =
do_QueryInterface(GetAsSupports(mParent), &rv); do_QueryInterface(GetAsSupports(mParent), &rv);
if (parent) { if (parent) {
rv = parent->AddChildSHEntry(aCloneRef, aNewEntry, aChildOffset, rv = static_cast<nsDocShell*>(parent.get())->
loadType, aCloneChildren); AddChildSHEntryInternal(aCloneRef, aNewEntry, aChildOffset,
} aLoadType, aCloneChildren);
}
} }
return rv; return rv;
} }
nsresult nsresult
nsDocShell::DoAddChildSHEntry(nsISHEntry* aNewEntry, int32_t aChildOffset, nsDocShell::AddChildSHEntryToParent(nsISHEntry* aNewEntry, int32_t aChildOffset,
bool aCloneChildren) bool aCloneChildren)
{ {
/* You will get here when you are in a subframe and /* You will get here when you are in a subframe and
* a new url has been loaded on you. * a new url has been loaded on you.
@ -11653,7 +11674,7 @@ nsDocShell::AddToSessionHistory(nsIURI * aURI, nsIChannel * aChannel,
// This is a subframe. // This is a subframe.
if (!mOSHE || !LOAD_TYPE_HAS_FLAGS(mLoadType, if (!mOSHE || !LOAD_TYPE_HAS_FLAGS(mLoadType,
LOAD_FLAGS_REPLACE_HISTORY)) LOAD_FLAGS_REPLACE_HISTORY))
rv = DoAddChildSHEntry(entry, mChildOffset, aCloneChildren); rv = AddChildSHEntryToParent(entry, mChildOffset, aCloneChildren);
} }
// Return the new SH entry... // Return the new SH entry...
@ -13591,6 +13612,30 @@ nsDocShell::GetURLSearchParams()
return mURLSearchParams; 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 void
nsDocShell::MaybeNotifyKeywordSearchLoading(const nsString &aProvider, nsDocShell::MaybeNotifyKeywordSearchLoading(const nsString &aProvider,
const nsString &aKeyword) { const nsString &aKeyword) {

Просмотреть файл

@ -371,8 +371,12 @@ protected:
nsISupports* aOwner, nsISupports* aOwner,
bool aCloneChildren, bool aCloneChildren,
nsISHEntry ** aNewEntry); nsISHEntry ** aNewEntry);
nsresult DoAddChildSHEntry(nsISHEntry* aNewEntry, int32_t aChildOffset, nsresult AddChildSHEntryToParent(nsISHEntry* aNewEntry, int32_t aChildOffset,
bool aCloneChildren); 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 LoadHistoryEntry(nsISHEntry * aEntry, uint32_t aLoadType);
NS_IMETHOD PersistLayoutHistoryState(); NS_IMETHOD PersistLayoutHistoryState();
@ -946,6 +950,10 @@ private:
nsWeakPtr mOpener; nsWeakPtr mOpener;
nsWeakPtr mOpenedRemote; nsWeakPtr mOpenedRemote;
// A depth count of how many times NotifyRunToCompletionStart
// has been called without a matching NotifyRunToCompletionStop.
uint32_t mJSRunToCompletionDepth;
// True if recording profiles. // True if recording profiles.
bool mProfileTimelineRecording; bool mProfileTimelineRecording;

Просмотреть файл

@ -54,7 +54,7 @@ interface nsITabParent;
typedef unsigned long nsLoadFlags; typedef unsigned long nsLoadFlags;
[scriptable, builtinclass, uuid(da8f78f1-8f20-4d6d-be56-fe53e177b630)] [scriptable, builtinclass, uuid(4e3de242-0b2a-4cf0-81b5-a5fe8628431c)]
interface nsIDocShell : nsIDocShellTreeItem interface nsIDocShell : nsIDocShellTreeItem
{ {
/** /**
@ -1026,6 +1026,14 @@ interface nsIDocShell : nsIDocShellTreeItem
// URLSearchParams for the window.location is owned by the docShell. // URLSearchParams for the window.location is owned by the docShell.
[noscript,notxpcom] URLSearchParams getURLSearchParams(); [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 * This attribute determines whether a document which is not about:blank has
* already be loaded by this docShell. * already be loaded by this docShell.

Просмотреть файл

@ -14,7 +14,7 @@ interface nsISHEntry;
* *
*/ */
[scriptable, uuid(65281BA2-988A-11d3-BDC7-0050040A9B44)] [scriptable, uuid(67dd0357-8372-4122-bff6-217435e8b7e4)]
interface nsISHContainer : nsISupports interface nsISHContainer : nsISupports
{ {
/** /**
@ -38,5 +38,12 @@ interface nsISHContainer : nsISupports
*/ */
nsISHEntry GetChildAt(in long index); 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);
}; };

Просмотреть файл

@ -690,6 +690,27 @@ nsSHEntry::GetChildAt(int32_t aIndex, nsISHEntry ** aResult)
return NS_OK; 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 NS_IMETHODIMP
nsSHEntry::AddChildShell(nsIDocShellTreeItem *aShell) nsSHEntry::AddChildShell(nsIDocShellTreeItem *aShell)
{ {

Просмотреть файл

@ -0,0 +1,28 @@
<html>
<head>
<script>
function nestedIframeLoaded() {
var tf = document.getElementById("testframe");
var innerf = tf.contentDocument.getElementsByTagName("iframe")[0];
if (innerf.contentDocument.documentURI.indexOf("frame0") < 0) {
innerf.contentWindow.location.href = "http://mochi.test:8888/tests/docshell/test/navigation/frame0.html";
return;
}
innerf.onload = null;
innerf.src = "about:blank";
var d = innerf.contentDocument;
d.open();
d.write("test");
d.close();
opener.is(window.history.length, 1, "Unexpected history length");
opener.nextTest();
window.close();
}
</script>
</head>
<body>
<iframe id="testframe" src="data:text/html,<iframe onload='parent.nestedIframeLoaded();'></iframe>" onload="frameLoaded()"></iframe>
<script>
</script>
</body>
</html>

Просмотреть файл

@ -9,6 +9,7 @@ support-files =
file_bug534178.html file_bug534178.html
file_document_write_1.html file_document_write_1.html
file_fragment_handling_during_load.html file_fragment_handling_during_load.html
file_nested_frames.html
file_static_and_dynamic_1.html file_static_and_dynamic_1.html
frame0.html frame0.html
frame1.html frame1.html

Просмотреть файл

@ -27,7 +27,8 @@ var testFiles =
"file_document_write_1.html", // Session history + document.write "file_document_write_1.html", // Session history + document.write
//"file_static_and_dynamic_1.html",// Static and dynamic frames and forward-back //"file_static_and_dynamic_1.html",// Static and dynamic frames and forward-back
"file_bug534178.html", // Session history transaction clean-up. "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. var testCount = 0; // Used by the test files.

Просмотреть файл

@ -12,6 +12,7 @@
#include "xpcprivate.h" // For AutoCxPusher guts #include "xpcprivate.h" // For AutoCxPusher guts
#include "xpcpublic.h" #include "xpcpublic.h"
#include "nsIGlobalObject.h" #include "nsIGlobalObject.h"
#include "nsIDocShell.h"
#include "nsIScriptGlobalObject.h" #include "nsIScriptGlobalObject.h"
#include "nsIScriptContext.h" #include "nsIScriptContext.h"
#include "nsContentUtils.h" #include "nsContentUtils.h"
@ -70,8 +71,26 @@ public:
ScriptSettingsStackEntry *entry = EntryPoint(); ScriptSettingsStackEntry *entry = EntryPoint();
return entry ? entry->mGlobalObject : nullptr; 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 void
InitScriptSettings() InitScriptSettings()
{ {
@ -122,10 +141,44 @@ ScriptSettingsStackEntry::~ScriptSettingsStackEntry()
ScriptSettingsStack::Pop(this); 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* nsIGlobalObject*
GetEntryGlobal() GetEntryGlobal()
{ {
return ScriptSettingsStack::EntryGlobal(); return ClampToSubject(ScriptSettingsStack::EntryGlobal());
} }
nsIDocument* nsIDocument*
@ -163,12 +216,12 @@ GetIncumbentGlobal()
// there's nothing on the JS stack, which will cause us to check the // there's nothing on the JS stack, which will cause us to check the
// incumbent script stack below. // incumbent script stack below.
if (JSObject *global = JS::GetScriptedCallerGlobal(cx)) { 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 // Ok, nothing from the JS engine. Let's use whatever's on the
// explicit stack. // explicit stack.
return ScriptSettingsStack::IncumbentGlobal(); return ClampToSubject(ScriptSettingsStack::IncumbentGlobal());
} }
nsIGlobalObject* nsIGlobalObject*
@ -463,14 +516,30 @@ AutoEntryScript::AutoEntryScript(nsIGlobalObject* aGlobalObject,
aCx ? aCx : FindJSContext(aGlobalObject)) aCx ? aCx : FindJSContext(aGlobalObject))
, ScriptSettingsStackEntry(aGlobalObject, /* aCandidate = */ true) , ScriptSettingsStackEntry(aGlobalObject, /* aCandidate = */ true)
, mWebIDLCallerPrincipal(nullptr) , mWebIDLCallerPrincipal(nullptr)
, mDocShellForJSRunToCompletion(nullptr)
{ {
MOZ_ASSERT(aGlobalObject); MOZ_ASSERT(aGlobalObject);
MOZ_ASSERT_IF(!aCx, aIsMainThread); // cx is mandatory off-main-thread. MOZ_ASSERT_IF(!aCx, aIsMainThread); // cx is mandatory off-main-thread.
MOZ_ASSERT_IF(aCx && aIsMainThread, aCx == FindJSContext(aGlobalObject)); MOZ_ASSERT_IF(aCx && aIsMainThread, aCx == FindJSContext(aGlobalObject));
if (aIsMainThread && gRunToCompletionListeners > 0) {
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobalObject);
if (window) {
mDocShellForJSRunToCompletion = window->GetDocShell();
}
}
if (mDocShellForJSRunToCompletion) {
mDocShellForJSRunToCompletion->NotifyJSRunToCompletionStart();
}
} }
AutoEntryScript::~AutoEntryScript() AutoEntryScript::~AutoEntryScript()
{ {
if (mDocShellForJSRunToCompletion) {
mDocShellForJSRunToCompletion->NotifyJSRunToCompletionStop();
}
// GC when we pop a script entry point. This is a useful heuristic that helps // 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 // us out on certain (flawed) benchmarks like sunspider, because it lets us
// avoid GCing during the timing loop. // avoid GCing during the timing loop.

Просмотреть файл

@ -21,6 +21,7 @@ class nsPIDOMWindow;
class nsGlobalWindow; class nsGlobalWindow;
class nsIScriptContext; class nsIScriptContext;
class nsIDocument; class nsIDocument;
class nsIDocShell;
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
@ -63,6 +64,16 @@ private:
void InitScriptSettings(); void InitScriptSettings();
void DestroyScriptSettings(); 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 // To implement a web-compatible browser, it is often necessary to obtain the
// global object that is "associated" with the currently-running code. This // global object that is "associated" with the currently-running code. This
// process is made more complicated by the fact that, historically, different // process is made more complicated by the fact that, historically, different
@ -331,6 +342,8 @@ private:
// can't go away until then either. // can't go away until then either.
nsIPrincipal* mWebIDLCallerPrincipal; nsIPrincipal* mWebIDLCallerPrincipal;
friend nsIPrincipal* GetWebIDLCallerPrincipal(); friend nsIPrincipal* GetWebIDLCallerPrincipal();
nsIDocShell* mDocShellForJSRunToCompletion;
}; };
/* /*

Просмотреть файл

@ -415,8 +415,6 @@ nsDOMWindowUtils::SetDisplayPortMarginsForElement(float aLeftMargin,
float aTopMargin, float aTopMargin,
float aRightMargin, float aRightMargin,
float aBottomMargin, float aBottomMargin,
uint32_t aAlignmentX,
uint32_t aAlignmentY,
nsIDOMElement* aElement, nsIDOMElement* aElement,
uint32_t aPriority) uint32_t aPriority)
{ {
@ -451,7 +449,7 @@ nsDOMWindowUtils::SetDisplayPortMarginsForElement(float aLeftMargin,
aLeftMargin); aLeftMargin);
nsLayoutUtils::SetDisplayPortMargins(content, presShell, displayportMargins, nsLayoutUtils::SetDisplayPortMargins(content, presShell, displayportMargins,
aAlignmentX, aAlignmentY, aPriority); aPriority);
return NS_OK; return NS_OK;
} }

Просмотреть файл

@ -2412,9 +2412,10 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
bool thisChrome = IsChromeWindow(); bool thisChrome = IsChromeWindow();
// Check if we're near the stack limit before we get anywhere near the // Check if we're anywhere near the stack limit before we reach the
// transplanting code. We use a conservative check since we'll use a little // transplanting code, since it has no good way to handle errors. This uses
// more space before we actually hit the critical "can't fail" path. // the untrusted script limit, which is not strictly necessary since no
// actual script should run.
JS_CHECK_RECURSION_CONSERVATIVE(cx, return NS_ERROR_FAILURE); JS_CHECK_RECURSION_CONSERVATIVE(cx, return NS_ERROR_FAILURE);
nsCOMPtr<WindowStateHolder> wsh = do_QueryInterface(aState); nsCOMPtr<WindowStateHolder> wsh = do_QueryInterface(aState);
@ -7783,46 +7784,15 @@ nsGlobalWindow::GetFrames(nsIDOMWindow** aFrames)
return rv.ErrorCode(); 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<JSObject*> incumbentGlobal(cx, &IncumbentJSGlobal());
JS::Rooted<JSObject*> compartmentGlobal(cx, JS::CurrentGlobalOrNull(cx));
nsIPrincipal* incumbentPrin = nsContentUtils::ObjectPrincipal(incumbentGlobal);
nsIPrincipal* compartmentPrin = nsContentUtils::ObjectPrincipal(compartmentGlobal);
return incumbentPrin->EqualsConsideringDomain(compartmentPrin) ? incumbentGlobal
: compartmentGlobal;
}
nsGlobalWindow* nsGlobalWindow*
nsGlobalWindow::CallerInnerWindow() nsGlobalWindow::CallerInnerWindow()
{ {
JSContext *cx = nsContentUtils::GetCurrentJSContext(); JSContext *cx = nsContentUtils::GetCurrentJSContext();
NS_ENSURE_TRUE(cx, nullptr); NS_ENSURE_TRUE(cx, nullptr);
JS::Rooted<JSObject*> scope(cx, CallerGlobal()); nsIGlobalObject* global = GetIncumbentGlobal();
NS_ENSURE_TRUE(global, nullptr);
JS::Rooted<JSObject*> scope(cx, global->GetGlobalJSObject());
NS_ENSURE_TRUE(scope, nullptr);
// When Jetpack runs content scripts inside a sandbox, it uses // When Jetpack runs content scripts inside a sandbox, it uses
// sandboxPrototype to make them appear as though they're running in the // 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 // the |source| of the received message to be the window set as the
// sandboxPrototype. This used to work incidentally for unrelated reasons, but // sandboxPrototype. This used to work incidentally for unrelated reasons, but
// now we need to do some special handling to support it. // now we need to do some special handling to support it.
{ if (xpc::IsSandbox(scope)) {
JSAutoCompartment ac(cx, scope); JSAutoCompartment ac(cx, scope);
JS::Rooted<JSObject*> scopeProto(cx); JS::Rooted<JSObject*> scopeProto(cx);
bool ok = JS_GetPrototype(cx, scope, &scopeProto); bool ok = JS_GetPrototype(cx, scope, &scopeProto);
@ -7838,26 +7808,14 @@ nsGlobalWindow::CallerInnerWindow()
if (scopeProto && xpc::IsSandboxPrototypeProxy(scopeProto) && if (scopeProto && xpc::IsSandboxPrototypeProxy(scopeProto) &&
(scopeProto = js::CheckedUnwrap(scopeProto, /* stopAtOuter = */ false))) (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 // The calling window must be holding a reference, so we can return a weak
// apart the cases of "scope is not an nsISupports at all" and "scope is an // pointer.
// nsISupports that's not a window". It's not clear whether that's desirable, nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(global);
// 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<nsPIDOMWindow> win = do_QueryInterface(native);
if (!win)
return GetCurrentInnerWindowInternal();
return static_cast<nsGlobalWindow*>(win.get()); return static_cast<nsGlobalWindow*>(win.get());
} }
@ -8258,10 +8216,9 @@ nsGlobalWindow::PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
else { else {
// In case the global is not a window, it can be a sandbox, and the sandbox's // 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. // principal can be used for the security check.
JSObject *global = CallerGlobal(); nsIGlobalObject* global = GetIncumbentGlobal();
NS_ASSERTION(global, "Why is there no global object?"); NS_ASSERTION(global, "Why is there no global object?");
JSCompartment *compartment = js::GetObjectCompartment(global); callerPrin = global->PrincipalOrNull();
callerPrin = xpc::GetCompartmentPrincipal(compartment);
} }
if (!callerPrin) { if (!callerPrin) {
return; return;
@ -12023,6 +11980,9 @@ nsGlobalWindow::InnerForSetTimeoutOrInterval(ErrorResult& aError)
// inner window that's calling window.setTimeout(). // inner window that's calling window.setTimeout().
forwardTo = CallerInnerWindow(); forwardTo = CallerInnerWindow();
if (!forwardTo && nsContentUtils::IsCallerChrome()) {
forwardTo = currentInner;
}
if (!forwardTo) { if (!forwardTo) {
aError.Throw(NS_ERROR_NOT_AVAILABLE); aError.Throw(NS_ERROR_NOT_AVAILABLE);
return nullptr; return nullptr;
@ -12241,14 +12201,15 @@ nsGlobalWindow::SetTimeoutOrInterval(bool aIsInterval, int32_t *aReturn)
if (IsOuterWindow()) { if (IsOuterWindow()) {
nsGlobalWindow* callerInner = CallerInnerWindow(); 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, // If the caller and the callee share the same outer window,
// forward to the callee inner. Else, we forward to the current // forward to the callee inner. Else, we forward to the current
// inner (e.g. someone is calling setTimeout() on a reference to // inner (e.g. someone is calling setTimeout() on a reference to
// some other window). // some other window).
if (callerInner->GetOuterWindow() == this && if (callerInner &&
callerInner->GetOuterWindow() == this &&
callerInner->IsInnerWindow()) { callerInner->IsInnerWindow()) {
return callerInner->SetTimeoutOrInterval(aIsInterval, aReturn); return callerInner->SetTimeoutOrInterval(aIsInterval, aReturn);
} }

Просмотреть файл

@ -1092,7 +1092,6 @@ protected:
} }
void FreeInnerObjects(); void FreeInnerObjects();
JSObject *CallerGlobal();
nsGlobalWindow *CallerInnerWindow(); nsGlobalWindow *CallerInnerWindow();
// Only to be called on an inner window. // Only to be called on an inner window.

Просмотреть файл

@ -1984,6 +1984,11 @@ ToCanonicalSupports(nsINode* aPointer)
aLocalName = nsINode::LocalName(); \ aLocalName = nsINode::LocalName(); \
return NS_OK; \ return NS_OK; \
} \ } \
NS_IMETHOD UnusedPlaceholder(bool* aResult) __VA_ARGS__ \
{ \
*aResult = false; \
return NS_OK; \
} \
NS_IMETHOD GetDOMBaseURI(nsAString& aBaseURI) __VA_ARGS__ \ NS_IMETHOD GetDOMBaseURI(nsAString& aBaseURI) __VA_ARGS__ \
{ \ { \
nsINode::GetBaseURI(aBaseURI); \ nsINode::GetBaseURI(aBaseURI); \

Просмотреть файл

@ -1698,9 +1698,10 @@ ReparentWrapper(JSContext* aCx, JS::Handle<JSObject*> aObjArg)
{ {
js::AssertSameCompartment(aCx, aObjArg); js::AssertSameCompartment(aCx, aObjArg);
// Check if we're near the stack limit before we get anywhere near the // Check if we're anywhere near the stack limit before we reach the
// transplanting code. We use a conservative check since we'll use a little // transplanting code, since it has no good way to handle errors. This uses
// more space before we actually hit the critical "can't fail" path. // 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_CHECK_RECURSION_CONSERVATIVE(aCx, return NS_ERROR_FAILURE);
JS::Rooted<JSObject*> aObj(aCx, aObjArg); JS::Rooted<JSObject*> aObj(aCx, aObjArg);

Просмотреть файл

@ -66,10 +66,10 @@ ToJSValue(JSContext* aCx,
JS::MutableHandle<JS::Value> aValue) JS::MutableHandle<JS::Value> aValue)
{ {
MOZ_ASSERT(aArgument.Failed()); MOZ_ASSERT(aArgument.Failed());
ThrowMethodFailedWithDetails(aCx, aArgument, "", ""); DebugOnly<bool> throwResult = ThrowMethodFailedWithDetails(aCx, aArgument, "", "");
if (!JS_GetPendingException(aCx, aValue)) { MOZ_ASSERT(!throwResult);
return false; DebugOnly<bool> getPendingResult = JS_GetPendingException(aCx, aValue);
} MOZ_ASSERT(getPendingResult);
JS_ClearPendingException(aCx); JS_ClearPendingException(aCx);
return true; return true;
} }

Просмотреть файл

@ -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-formats-test.html]
[webgl-conformance/_wrappers/test_conformance__textures__texture-mips.html] [webgl-conformance/_wrappers/test_conformance__textures__texture-mips.html]
[webgl-conformance/_wrappers/test_conformance__textures__texture-npot-video.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-npot.html]
[webgl-conformance/_wrappers/test_conformance__textures__texture-size.html] [webgl-conformance/_wrappers/test_conformance__textures__texture-size.html]
skip-if = os == 'android' skip-if = os == 'android'

Просмотреть файл

@ -12,7 +12,7 @@ fail-if = (os == 'b2g')
[webgl-mochitest/test_fb_param.html] [webgl-mochitest/test_fb_param.html]
[webgl-mochitest/test_fb_param_crash.html] [webgl-mochitest/test_fb_param_crash.html]
[webgl-mochitest/test_hidden_alpha.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_highp_fs.html]
[webgl-mochitest/test_no_arr_points.html] [webgl-mochitest/test_no_arr_points.html]
skip-if = android_version == '10' #Android 2.3 aws only; bug 1030942 skip-if = android_version == '10' #Android 2.3 aws only; bug 1030942

Просмотреть файл

@ -1032,11 +1032,12 @@ UploadLastDir::FetchDirectoryAndDisplayPicker(nsIDocument* aDoc,
nsCOMPtr<nsIContentPrefCallback2> prefCallback = nsCOMPtr<nsIContentPrefCallback2> prefCallback =
new UploadLastDir::ContentPrefCallback(aFilePicker, aFpCallback); new UploadLastDir::ContentPrefCallback(aFilePicker, aFpCallback);
#ifdef MOZ_B2G
if (XRE_GetProcessType() == GeckoProcessType_Content) { if (XRE_GetProcessType() == GeckoProcessType_Content) {
// FIXME (bug 949666): Run this code in the parent process.
prefCallback->HandleCompletion(nsIContentPrefCallback2::COMPLETE_ERROR); prefCallback->HandleCompletion(nsIContentPrefCallback2::COMPLETE_ERROR);
return NS_OK; return NS_OK;
} }
#endif
// Attempt to get the CPS, if it's not present we'll fallback to use the Desktop folder // Attempt to get the CPS, if it's not present we'll fallback to use the Desktop folder
nsCOMPtr<nsIContentPrefService2> contentPrefService = nsCOMPtr<nsIContentPrefService2> contentPrefService =
@ -1062,10 +1063,11 @@ UploadLastDir::StoreLastUsedDirectory(nsIDocument* aDoc, nsIFile* aDir)
return NS_OK; return NS_OK;
} }
#ifdef MOZ_B2G
if (XRE_GetProcessType() == GeckoProcessType_Content) { if (XRE_GetProcessType() == GeckoProcessType_Content) {
// FIXME (bug 949666): Run this code in the parent process.
return NS_OK; return NS_OK;
} }
#endif
nsCOMPtr<nsIURI> docURI = aDoc->GetDocumentURI(); nsCOMPtr<nsIURI> docURI = aDoc->GetDocumentURI();
NS_PRECONDITION(docURI, "docURI is null"); NS_PRECONDITION(docURI, "docURI is null");

Просмотреть файл

@ -51,7 +51,7 @@ interface nsITranslationNodeList;
interface nsIJSRAIIHelper; interface nsIJSRAIIHelper;
interface nsIContentPermissionRequest; interface nsIContentPermissionRequest;
[scriptable, uuid(e293355b-ae7f-4ef7-9237-452bcf3e9e6b)] [scriptable, uuid(9621eb05-b498-4e87-a012-95d817987624)]
interface nsIDOMWindowUtils : nsISupports { interface nsIDOMWindowUtils : nsISupports {
/** /**
@ -188,8 +188,6 @@ interface nsIDOMWindowUtils : nsISupports {
in float aTopMargin, in float aTopMargin,
in float aRightMargin, in float aRightMargin,
in float aBottomMargin, in float aBottomMargin,
in uint32_t aAlignmentX,
in uint32_t aAlignmentY,
in nsIDOMElement aElement, in nsIDOMElement aElement,
in uint32_t aPriority); in uint32_t aPriority);

Просмотреть файл

@ -14,7 +14,7 @@
* http://www.w3.org/TR/DOM-Level-2-Core/ * 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 interface nsIDOMAttr : nsIDOMNode
{ {
readonly attribute DOMString name; readonly attribute DOMString name;

Просмотреть файл

@ -15,7 +15,7 @@
* http://www.w3.org/TR/DOM-Level-2-Core/ * http://www.w3.org/TR/DOM-Level-2-Core/
*/ */
[uuid(4ac42d40-69b7-4506-b730-c41ec74b74bd)] [uuid(e14ef131-34cc-40c8-9c99-a403c001184a)]
interface nsIDOMCDATASection : nsIDOMText interface nsIDOMCDATASection : nsIDOMText
{ {
}; };

Просмотреть файл

@ -13,7 +13,7 @@
* http://www.w3.org/TR/DOM-Level-2-Core/ * http://www.w3.org/TR/DOM-Level-2-Core/
*/ */
[uuid(844b8e7e-6d37-4fa1-8196-86e3afdfa0ca)] [uuid(4109a2d2-e7af-445d-bb72-c7c9b875f35e)]
interface nsIDOMCharacterData : nsIDOMNode interface nsIDOMCharacterData : nsIDOMNode
{ {
attribute DOMString data; attribute DOMString data;

Просмотреть файл

@ -14,7 +14,7 @@
* http://www.w3.org/TR/DOM-Level-2-Core/ * http://www.w3.org/TR/DOM-Level-2-Core/
*/ */
[uuid(c1a1d2ea-e106-4ee8-806d-2633468e8098)] [uuid(e7866ff8-b7fc-494f-87c0-fb017d8a4d30)]
interface nsIDOMComment : nsIDOMCharacterData interface nsIDOMComment : nsIDOMCharacterData
{ {
}; };

Просмотреть файл

@ -32,7 +32,7 @@ interface nsIDOMLocation;
* http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html * 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 interface nsIDOMDocument : nsIDOMNode
{ {
readonly attribute nsIDOMDocumentType doctype; readonly attribute nsIDOMDocumentType doctype;

Просмотреть файл

@ -14,7 +14,7 @@
* http://www.w3.org/TR/DOM-Level-2-Core/ * 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 interface nsIDOMDocumentFragment : nsIDOMNode
{ {
/** /**

Просмотреть файл

@ -15,7 +15,7 @@
* http://www.w3.org/TR/DOM-Level-2-Core/ * http://www.w3.org/TR/DOM-Level-2-Core/
*/ */
[uuid(23c1f549-d40b-49b8-992e-2a1136afa13f)] [uuid(cd7467b9-0f26-4787-a359-66e80ba8db92)]
interface nsIDOMDocumentType : nsIDOMNode interface nsIDOMDocumentType : nsIDOMNode
{ {
readonly attribute DOMString name; readonly attribute DOMString name;

Просмотреть файл

@ -15,7 +15,7 @@ interface nsIDOMMozNamedAttrMap;
* http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#interface-element * 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 interface nsIDOMElement : nsIDOMNode
{ {
readonly attribute DOMString tagName; readonly attribute DOMString tagName;

Просмотреть файл

@ -16,7 +16,7 @@ interface nsIVariant;
* http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html * 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 interface nsIDOMNode : nsISupports
{ {
const unsigned short ELEMENT_NODE = 1; const unsigned short ELEMENT_NODE = 1;
@ -69,6 +69,9 @@ interface nsIDOMNode : nsISupports
// Introduced in DOM Level 2: // Introduced in DOM Level 2:
readonly attribute DOMString localName; readonly attribute DOMString localName;
// For vtable compatibility (see bug 1078674)
[noscript] bool unusedPlaceholder();
// Introduced in DOM Level 3: // Introduced in DOM Level 3:
// This uses a binaryname to avoid warnings due to name collision with // This uses a binaryname to avoid warnings due to name collision with
// nsINode::GetBaseURI // nsINode::GetBaseURI

Просмотреть файл

@ -15,7 +15,7 @@
* http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html * 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 interface nsIDOMProcessingInstruction : nsIDOMCharacterData
{ {
readonly attribute DOMString target; readonly attribute DOMString target;

Просмотреть файл

@ -13,7 +13,7 @@
* http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html * 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 interface nsIDOMText : nsIDOMCharacterData
{ {
nsIDOMText splitText(in unsigned long offset) nsIDOMText splitText(in unsigned long offset)

Просмотреть файл

@ -5,7 +5,7 @@
#include "nsIDOMDocument.idl" #include "nsIDOMDocument.idl"
[uuid(1d54e44a-2012-4567-805d-bd5455fc6421)] [uuid(867379ce-165b-4b8c-8582-299b38096aa8)]
interface nsIDOMXMLDocument : nsIDOMDocument interface nsIDOMXMLDocument : nsIDOMDocument
{ {
// DOM Level 3 Load & Save, DocumentLS // DOM Level 3 Load & Save, DocumentLS

Просмотреть файл

@ -13,7 +13,7 @@
*/ */
interface nsISelection; interface nsISelection;
[uuid(abf369fb-a8b2-4fba-95f5-9e4a896e40a8)] [uuid(bd2a0a46-17e4-46ea-9e5d-6a97cf5e3b28)]
interface nsIDOMHTMLDocument : nsIDOMDocument interface nsIDOMHTMLDocument : nsIDOMDocument
{ {
attribute DOMString domain; attribute DOMString domain;

Просмотреть файл

@ -19,7 +19,7 @@ interface nsIDOMHTMLMenuElement;
* with changes from the work-in-progress WHATWG HTML specification: * with changes from the work-in-progress WHATWG HTML specification:
* http://www.whatwg.org/specs/web-apps/current-work/ * http://www.whatwg.org/specs/web-apps/current-work/
*/ */
[uuid(8c9472c2-785a-40b6-ad47-4d98e64562bd)] [uuid(b0c42392-d0e7-4f6a-beb5-a698ce648945)]
interface nsIDOMHTMLElement : nsIDOMElement interface nsIDOMHTMLElement : nsIDOMElement
{ {
// metadata attributes // metadata attributes

Просмотреть файл

@ -9,7 +9,7 @@ interface nsIDOMCSSStyleDeclaration;
interface nsIDOMCSSValue; interface nsIDOMCSSValue;
[uuid(6618074e-0c77-4fec-8870-a6f79aa79b07)] [uuid(c63517c5-8bab-4cd1-8694-bccafc32a195)]
interface nsIDOMSVGElement : nsIDOMElement interface nsIDOMSVGElement : nsIDOMElement
{ {
// raises DOMException on setting // raises DOMException on setting

Просмотреть файл

@ -10,7 +10,7 @@ interface nsIDOMXULCommandDispatcher;
interface nsIObserver; interface nsIObserver;
interface nsIBoxObject; interface nsIBoxObject;
[uuid(6f932360-ae43-4fa7-9200-66f64e05a356)] [uuid(5d876ab0-5525-4f38-bc3b-f1190e3e3b90)]
interface nsIDOMXULDocument : nsIDOMDocument interface nsIDOMXULDocument : nsIDOMDocument
{ {
attribute nsIDOMNode popupNode; attribute nsIDOMNode popupNode;

Просмотреть файл

@ -12,7 +12,7 @@ interface nsIControllers;
interface nsIBoxObject; interface nsIBoxObject;
[uuid(ef62515d-3160-4463-abd7-fc9b7385ecef)] [uuid(75435ab3-6863-42a1-ade3-025393d9e80e)]
interface nsIDOMXULElement : nsIDOMElement interface nsIDOMXULElement : nsIDOMElement
{ {
// Layout properties // Layout properties

Просмотреть файл

@ -23,6 +23,7 @@
#include "mozilla/a11y/DocAccessibleChild.h" #include "mozilla/a11y/DocAccessibleChild.h"
#endif #endif
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"
#include "mozilla/docshell/OfflineCacheUpdateChild.h"
#include "mozilla/dom/ContentBridgeChild.h" #include "mozilla/dom/ContentBridgeChild.h"
#include "mozilla/dom/ContentBridgeParent.h" #include "mozilla/dom/ContentBridgeParent.h"
#include "mozilla/dom/DOMStorageIPC.h" #include "mozilla/dom/DOMStorageIPC.h"
@ -2258,6 +2259,25 @@ ContentChild::RecvUnregisterSheet(const URIParams& aURI, const uint32_t& aType)
return true; 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<OfflineCacheUpdateChild*>(actor);
NS_RELEASE(offlineCacheUpdate);
return true;
}
#ifdef MOZ_NUWA_PROCESS #ifdef MOZ_NUWA_PROCESS
class CallNuwaSpawn : public nsRunnable class CallNuwaSpawn : public nsRunnable
{ {

Просмотреть файл

@ -404,6 +404,14 @@ public:
PBrowserOrId PBrowserOrId
GetBrowserOrId(TabChild* aTabChild); 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: private:
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE; virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;

Просмотреть файл

@ -35,6 +35,7 @@
#include "nsAccessibilityService.h" #include "nsAccessibilityService.h"
#endif #endif
#include "mozilla/ClearOnShutdown.h" #include "mozilla/ClearOnShutdown.h"
#include "mozilla/docshell/OfflineCacheUpdateParent.h"
#include "mozilla/dom/DataStoreService.h" #include "mozilla/dom/DataStoreService.h"
#include "mozilla/dom/DOMStorageIPC.h" #include "mozilla/dom/DOMStorageIPC.h"
#include "mozilla/dom/Element.h" #include "mozilla/dom/Element.h"
@ -84,6 +85,7 @@
#include "nsChromeRegistryChrome.h" #include "nsChromeRegistryChrome.h"
#include "nsConsoleMessage.h" #include "nsConsoleMessage.h"
#include "nsConsoleService.h" #include "nsConsoleService.h"
#include "nsContentUtils.h"
#include "nsDebugImpl.h" #include "nsDebugImpl.h"
#include "nsFrameMessageManager.h" #include "nsFrameMessageManager.h"
#include "nsGeolocationSettings.h" #include "nsGeolocationSettings.h"
@ -1487,6 +1489,14 @@ ContentParent::ShutDownProcess(bool aCloseWithError)
} }
} }
const InfallibleTArray<POfflineCacheUpdateParent*>& ocuParents =
ManagedPOfflineCacheUpdateParent();
for (uint32_t i = 0; i < ocuParents.Length(); ++i) {
nsRefPtr<mozilla::docshell::OfflineCacheUpdateParent> ocuParent =
static_cast<mozilla::docshell::OfflineCacheUpdateParent*>(ocuParents[i]);
ocuParent->StopSendingMessagesToChild();
}
// NB: must MarkAsDead() here so that this isn't accidentally // NB: must MarkAsDead() here so that this isn't accidentally
// returned from Get*() while in the midst of shutdown. // returned from Get*() while in the midst of shutdown.
MarkAsDead(); MarkAsDead();
@ -4317,6 +4327,62 @@ ContentParent::GetManagedTabContext()
GetTabContextByContentProcess(this->ChildID())); 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<mozilla::docshell::OfflineCacheUpdateParent> 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<mozilla::docshell::OfflineCacheUpdateParent> update =
static_cast<mozilla::docshell::OfflineCacheUpdateParent*>(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<mozilla::docshell::OfflineCacheUpdateParent> update =
dont_AddRef(static_cast<mozilla::docshell::OfflineCacheUpdateParent*>(aActor));
return true;
}
bool
ContentParent::RecvSetOfflinePermission(const Principal& aPrincipal)
{
nsIPrincipal* principal = aPrincipal;
nsContentUtils::MaybeAllowOfflineAppByDefault(principal, nullptr);
return true;
}
} // namespace dom } // namespace dom
} // namespace mozilla } // namespace mozilla

Просмотреть файл

@ -311,6 +311,23 @@ public:
virtual bool RecvDeallocateTabId(const TabId& aTabId) MOZ_OVERRIDE; virtual bool RecvDeallocateTabId(const TabId& aTabId) MOZ_OVERRIDE;
nsTArray<TabContext> GetManagedTabContext(); nsTArray<TabContext> 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: protected:
void OnChannelConnected(int32_t pid) MOZ_OVERRIDE; void OnChannelConnected(int32_t pid) MOZ_OVERRIDE;
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE; virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;

Просмотреть файл

@ -207,25 +207,29 @@ ContentProcessManager::DeallocateTabId(const ContentParentId& aChildCpId,
} }
} }
nsTArray<uint64_t> bool
ContentProcessManager::GetAppIdsByContentProcess(const ContentParentId& aChildCpId) ContentProcessManager::GetTabContextByProcessAndTabId(const ContentParentId& aChildCpId,
const TabId& aChildTabId,
/*out*/ TabContext* aTabContext)
{ {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aTabContext);
nsTArray<uint64_t> appIdArray;
auto iter = mContentParentMap.find(aChildCpId); auto iter = mContentParentMap.find(aChildCpId);
if (NS_WARN_IF(iter == mContentParentMap.end())) { if (NS_WARN_IF(iter == mContentParentMap.end())) {
ASSERT_UNLESS_FUZZING(); ASSERT_UNLESS_FUZZING();
return Move(appIdArray); return false;
} }
for (auto remoteFrameIter = iter->second.mRemoteFrames.begin(); auto remoteFrameIter = iter->second.mRemoteFrames.find(aChildTabId);
remoteFrameIter != iter->second.mRemoteFrames.end(); if (NS_WARN_IF(remoteFrameIter == iter->second.mRemoteFrames.end())) {
++remoteFrameIter) { ASSERT_UNLESS_FUZZING();
appIdArray.AppendElement(remoteFrameIter->second.mContext.OwnOrContainingAppId()); return false;
} }
return Move(appIdArray); *aTabContext = remoteFrameIter->second.mContext;
return true;
} }
nsTArray<TabContext> nsTArray<TabContext>

Просмотреть файл

@ -88,11 +88,12 @@ public:
const TabId& aChildTabId); const TabId& aChildTabId);
/** /**
* Get all app ids which are inside the given content process. * Get the TabContext by the given content process and tab id.
* XXX Currently not used. Plan to be used for bug 1020186.
*/ */
nsTArray<uint64_t> bool
GetAppIdsByContentProcess(const ContentParentId& aChildCpId); GetTabContextByProcessAndTabId(const ContentParentId& aChildCpId,
const TabId& aChildTabId,
/*out*/ TabContext* aTabContext);
/** /**
* Get all TabContext which are inside the given content process. * Get all TabContext which are inside the given content process.

Просмотреть файл

@ -202,7 +202,8 @@ FilePickerParent::RecvOpen(const int16_t& aSelectedType,
const nsString& aDefaultFile, const nsString& aDefaultFile,
const nsString& aDefaultExtension, const nsString& aDefaultExtension,
const InfallibleTArray<nsString>& aFilters, const InfallibleTArray<nsString>& aFilters,
const InfallibleTArray<nsString>& aFilterNames) const InfallibleTArray<nsString>& aFilterNames,
const nsString& aDisplayDirectory)
{ {
if (!CreateFilePicker()) { if (!CreateFilePicker()) {
unused << Send__delete__(this, void_t(), nsIFilePicker::returnCancel); unused << Send__delete__(this, void_t(), nsIFilePicker::returnCancel);
@ -219,6 +220,14 @@ FilePickerParent::RecvOpen(const int16_t& aSelectedType,
mFilePicker->SetDefaultExtension(aDefaultExtension); mFilePicker->SetDefaultExtension(aDefaultExtension);
mFilePicker->SetFilterIndex(aSelectedType); mFilePicker->SetFilterIndex(aSelectedType);
if (!aDisplayDirectory.IsEmpty()) {
nsCOMPtr<nsIFile> localFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);
if (localFile) {
localFile->InitWithPath(aDisplayDirectory);
mFilePicker->SetDisplayDirectory(localFile);
}
}
mCallback = new FilePickerShownCallback(this); mCallback = new FilePickerShownCallback(this);
mFilePicker->Open(mCallback); mFilePicker->Open(mCallback);

Просмотреть файл

@ -36,7 +36,8 @@ class FilePickerParent : public PFilePickerParent
const nsString& aDefaultFile, const nsString& aDefaultFile,
const nsString& aDefaultExtension, const nsString& aDefaultExtension,
const InfallibleTArray<nsString>& aFilters, const InfallibleTArray<nsString>& aFilters,
const InfallibleTArray<nsString>& aFilterNames) MOZ_OVERRIDE; const InfallibleTArray<nsString>& aFilterNames,
const nsString& aDisplayDirectory) MOZ_OVERRIDE;
virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE; virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше