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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -11,7 +11,7 @@ const TAB_URL = EXAMPLE_URL + "doc_breakpoints-reload.html";
let test = Task.async(function* () {
requestLongerTimeout(4);
const [tab, debuggee, panel] = yield initDebugger(TAB_URL);
const [tab,, panel] = yield initDebugger(TAB_URL);
yield ensureSourceIs(panel, "doc_breakpoints-reload.html", true);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -970,6 +970,15 @@ function callInTab(tab, name) {
waitForMessageFromTab(tab, "test:call");
}
function evalInTab(tab, string) {
info("Evalling string " + string + " in tab.");
sendMessageToTab(tab, "test:eval", {
string: string,
});
waitForMessageFromTab(tab, "test:eval");
}
function sendMouseClickToTab(tab, target) {
info("Sending mouse click to tab.");

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

@ -13,6 +13,8 @@ var gRGB_TO_HSL = {
"rgb(96, 201, 58)": "hsl(104,57%,51%)",
"rgb(240, 195, 111)": "hsl(39,82%,69%)",
"rgb(227, 155, 22)": "hsl(39,82%,49%)",
"rgb(204, 204, 204)": "hsl(0,0%,80%)",
"rgb(153, 153, 153)": "hsl(0,0%,60%)",
};
let test = Task.async(function*() {

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

@ -55,7 +55,13 @@ const TIMELINE_BLUEPRINT = {
fill: "hsl(0,0%,80%)",
stroke: "hsl(0,0%,60%)",
label: L10N.getStr("timeline.label.consoleTime")
}
},
"Javascript": {
group: 4,
fill: "hsl(0,0%,80%)",
stroke: "hsl(0,0%,60%)",
label: L10N.getStr("timeline.label.javascript")
},
};
// Exported symbols.

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

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

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

@ -12,12 +12,19 @@ public class AnnotationInfo {
public final boolean isMultithreaded;
public final boolean noThrow;
public final boolean narrowChars;
public final boolean catchException;
public AnnotationInfo(String aWrapperName, boolean aIsMultithreaded,
boolean aNoThrow, boolean aNarrowChars) {
boolean aNoThrow, boolean aNarrowChars, boolean aCatchException) {
wrapperName = aWrapperName;
isMultithreaded = aIsMultithreaded;
noThrow = aNoThrow;
narrowChars = aNarrowChars;
catchException = aCatchException;
if (!noThrow && catchException) {
// It doesn't make sense to have these together
throw new IllegalArgumentException("noThrow and catchException are not allowed together");
}
}
}

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

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

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

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

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

@ -4,9 +4,9 @@
include $(topsrcdir)/config/rules.mk
JAVA_CLASSPATH := $(ANDROID_SDK)/android.jar
JAVA_CLASSPATH := $(ANDROID_SDK)/android.jar:$(ANDROID_SDK)/../../tools/lib/lint.jar:$(ANDROID_SDK)/../../tools/lib/lint-checks.jar
# Include Android specific java flags, instead of what's in rules.mk.
include $(topsrcdir)/config/android-common.mk
libs:: annotationProcessors.jar
export:: annotationProcessors.jar

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

@ -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/JarClassIterator.java',
'CodeGenerator.java',
'SDKProcessor.java',
'utils/AlphabeticAnnotatableEntityComparator.java',
'utils/GeneratableElementIterator.java',
'utils/Utils.java',

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

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

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

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

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

@ -141,6 +141,10 @@ ifeq (.,$(DEPTH))
# Interdependencies for parallel export.
js/xpconnect/src/export: dom/bindings/export xpcom/xpidl/export
accessible/xpcom/export: xpcom/xpidl/export
# The widget binding generator code is part of the annotationProcessors.
widget/android/bindings/export: build/annotationProcessors/export
ifdef ENABLE_CLANG_PLUGIN
$(filter-out build/clang-plugin/%,$(compile_targets)): build/clang-plugin/target build/clang-plugin/tests/target
build/clang-plugin/tests/target: build/clang-plugin/target

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

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

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

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

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

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

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

@ -54,7 +54,7 @@ interface nsITabParent;
typedef unsigned long nsLoadFlags;
[scriptable, builtinclass, uuid(da8f78f1-8f20-4d6d-be56-fe53e177b630)]
[scriptable, builtinclass, uuid(4e3de242-0b2a-4cf0-81b5-a5fe8628431c)]
interface nsIDocShell : nsIDocShellTreeItem
{
/**
@ -1026,6 +1026,14 @@ interface nsIDocShell : nsIDocShellTreeItem
// URLSearchParams for the window.location is owned by the docShell.
[noscript,notxpcom] URLSearchParams getURLSearchParams();
/**
* Notify DocShell when the browser is about to start executing JS, and after
* that execution has stopped. This only occurs when the Timeline devtool
* is collecting information.
*/
[noscript,notxpcom,nostdcall] void notifyJSRunToCompletionStart();
[noscript,notxpcom,nostdcall] void notifyJSRunToCompletionStop();
/**
* This attribute determines whether a document which is not about:blank has
* already be loaded by this docShell.

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

@ -14,7 +14,7 @@ interface nsISHEntry;
*
*/
[scriptable, uuid(65281BA2-988A-11d3-BDC7-0050040A9B44)]
[scriptable, uuid(67dd0357-8372-4122-bff6-217435e8b7e4)]
interface nsISHContainer : nsISupports
{
/**
@ -38,5 +38,12 @@ interface nsISHContainer : nsISupports
*/
nsISHEntry GetChildAt(in long index);
/**
* Replaces a child which is for the same docshell as aNewChild
* with aNewChild.
* @throw if nothing was replaced.
*/
void ReplaceChild(in nsISHEntry aNewChild);
};

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

@ -690,6 +690,27 @@ nsSHEntry::GetChildAt(int32_t aIndex, nsISHEntry ** aResult)
return NS_OK;
}
NS_IMETHODIMP
nsSHEntry::ReplaceChild(nsISHEntry* aNewEntry)
{
NS_ENSURE_STATE(aNewEntry);
uint64_t docshellID;
aNewEntry->GetDocshellID(&docshellID);
uint64_t otherID;
for (int32_t i = 0; i < mChildren.Count(); ++i) {
if (mChildren[i] && NS_SUCCEEDED(mChildren[i]->GetDocshellID(&otherID)) &&
docshellID == otherID) {
mChildren[i]->SetParent(nullptr);
if (mChildren.ReplaceObjectAt(aNewEntry, i)) {
return aNewEntry->SetParent(this);
}
}
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsSHEntry::AddChildShell(nsIDocShellTreeItem *aShell)
{

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

@ -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_document_write_1.html
file_fragment_handling_during_load.html
file_nested_frames.html
file_static_and_dynamic_1.html
frame0.html
frame1.html

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

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

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

@ -12,6 +12,7 @@
#include "xpcprivate.h" // For AutoCxPusher guts
#include "xpcpublic.h"
#include "nsIGlobalObject.h"
#include "nsIDocShell.h"
#include "nsIScriptGlobalObject.h"
#include "nsIScriptContext.h"
#include "nsContentUtils.h"
@ -70,8 +71,26 @@ public:
ScriptSettingsStackEntry *entry = EntryPoint();
return entry ? entry->mGlobalObject : nullptr;
}
};
static unsigned long gRunToCompletionListeners = 0;
void
UseEntryScriptProfiling()
{
MOZ_ASSERT(NS_IsMainThread());
++gRunToCompletionListeners;
}
void
UnuseEntryScriptProfiling()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(gRunToCompletionListeners > 0);
--gRunToCompletionListeners;
}
void
InitScriptSettings()
{
@ -122,10 +141,44 @@ ScriptSettingsStackEntry::~ScriptSettingsStackEntry()
ScriptSettingsStack::Pop(this);
}
// If the entry or incumbent global ends up being something that the subject
// principal doesn't subsume, we don't want to use it. This never happens on
// the web, but can happen with asymmetric privilege relationships (i.e.
// nsExpandedPrincipal and System Principal).
//
// The most correct thing to use instead would be the topmost global on the
// callstack whose principal is subsumed by the subject principal. But that's
// hard to compute, so we just substitute the global of the current
// compartment. In practice, this is fine.
//
// Note that in particular things like:
//
// |SpecialPowers.wrap(crossOriginWindow).eval(open())|
//
// trigger this case. Although both the entry global and the current global
// have normal principals, the use of Gecko-specific System-Principaled JS
// puts the code from two different origins on the callstack at once, which
// doesn't happen normally on the web.
static nsIGlobalObject*
ClampToSubject(nsIGlobalObject* aGlobalOrNull)
{
if (!aGlobalOrNull || !NS_IsMainThread()) {
return aGlobalOrNull;
}
nsIPrincipal* globalPrin = aGlobalOrNull->PrincipalOrNull();
NS_ENSURE_TRUE(globalPrin, GetCurrentGlobal());
if (!nsContentUtils::SubjectPrincipal()->SubsumesConsideringDomain(globalPrin)) {
return GetCurrentGlobal();
}
return aGlobalOrNull;
}
nsIGlobalObject*
GetEntryGlobal()
{
return ScriptSettingsStack::EntryGlobal();
return ClampToSubject(ScriptSettingsStack::EntryGlobal());
}
nsIDocument*
@ -163,12 +216,12 @@ GetIncumbentGlobal()
// there's nothing on the JS stack, which will cause us to check the
// incumbent script stack below.
if (JSObject *global = JS::GetScriptedCallerGlobal(cx)) {
return xpc::NativeGlobal(global);
return ClampToSubject(xpc::NativeGlobal(global));
}
// Ok, nothing from the JS engine. Let's use whatever's on the
// explicit stack.
return ScriptSettingsStack::IncumbentGlobal();
return ClampToSubject(ScriptSettingsStack::IncumbentGlobal());
}
nsIGlobalObject*
@ -463,14 +516,30 @@ AutoEntryScript::AutoEntryScript(nsIGlobalObject* aGlobalObject,
aCx ? aCx : FindJSContext(aGlobalObject))
, ScriptSettingsStackEntry(aGlobalObject, /* aCandidate = */ true)
, mWebIDLCallerPrincipal(nullptr)
, mDocShellForJSRunToCompletion(nullptr)
{
MOZ_ASSERT(aGlobalObject);
MOZ_ASSERT_IF(!aCx, aIsMainThread); // cx is mandatory off-main-thread.
MOZ_ASSERT_IF(aCx && aIsMainThread, aCx == FindJSContext(aGlobalObject));
if (aIsMainThread && gRunToCompletionListeners > 0) {
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobalObject);
if (window) {
mDocShellForJSRunToCompletion = window->GetDocShell();
}
}
if (mDocShellForJSRunToCompletion) {
mDocShellForJSRunToCompletion->NotifyJSRunToCompletionStart();
}
}
AutoEntryScript::~AutoEntryScript()
{
if (mDocShellForJSRunToCompletion) {
mDocShellForJSRunToCompletion->NotifyJSRunToCompletionStop();
}
// GC when we pop a script entry point. This is a useful heuristic that helps
// us out on certain (flawed) benchmarks like sunspider, because it lets us
// avoid GCing during the timing loop.

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

@ -21,6 +21,7 @@ class nsPIDOMWindow;
class nsGlobalWindow;
class nsIScriptContext;
class nsIDocument;
class nsIDocShell;
namespace mozilla {
namespace dom {
@ -63,6 +64,16 @@ private:
void InitScriptSettings();
void DestroyScriptSettings();
/*
* Static helpers in ScriptSettings which track the number of listeners
* of Javascript RunToCompletion events. These should be used by the code in
* nsDocShell::SetRecordProfileTimelineMarkers to indicate to script
* settings that script run-to-completion needs to be monitored.
* SHOULD BE CALLED ONLY BY MAIN THREAD.
*/
void UseEntryScriptProfiling();
void UnuseEntryScriptProfiling();
// To implement a web-compatible browser, it is often necessary to obtain the
// global object that is "associated" with the currently-running code. This
// process is made more complicated by the fact that, historically, different
@ -331,6 +342,8 @@ private:
// can't go away until then either.
nsIPrincipal* mWebIDLCallerPrincipal;
friend nsIPrincipal* GetWebIDLCallerPrincipal();
nsIDocShell* mDocShellForJSRunToCompletion;
};
/*

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

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

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

@ -2412,9 +2412,10 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
bool thisChrome = IsChromeWindow();
// Check if we're near the stack limit before we get anywhere near the
// transplanting code. We use a conservative check since we'll use a little
// more space before we actually hit the critical "can't fail" path.
// Check if we're anywhere near the stack limit before we reach the
// transplanting code, since it has no good way to handle errors. This uses
// the untrusted script limit, which is not strictly necessary since no
// actual script should run.
JS_CHECK_RECURSION_CONSERVATIVE(cx, return NS_ERROR_FAILURE);
nsCOMPtr<WindowStateHolder> wsh = do_QueryInterface(aState);
@ -7783,46 +7784,15 @@ nsGlobalWindow::GetFrames(nsIDOMWindow** aFrames)
return rv.ErrorCode();
}
JSObject* nsGlobalWindow::CallerGlobal()
{
JSContext *cx = nsContentUtils::GetCurrentJSContext();
if (!cx) {
NS_ERROR("Please don't call this method from C++!");
return nullptr;
}
// If somebody does sameOriginIframeWindow.postMessage(...), they probably
// expect the .source attribute of the resulting message event to be |window|
// rather than |sameOriginIframeWindow|, even though the transparent wrapper
// semantics of same-origin access will cause us to be in the iframe's
// compartment at the time of the call. This means that we want the incumbent
// global here, rather than the global of the current compartment.
//
// There are various edge cases in which the incumbent global and the current
// global would not be same-origin. They include:
// * A privileged caller (System Principal or Expanded Principal) manipulating
// less-privileged content via Xray Waivers.
// * An unprivileged caller invoking a cross-origin function that was exposed
// to it by privileged code (i.e. Sandbox.importFunction).
//
// In these cases, we probably don't want the privileged global appearing in the
// .source attribute. So we fall back to the compartment global there.
JS::Rooted<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::CallerInnerWindow()
{
JSContext *cx = nsContentUtils::GetCurrentJSContext();
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
// sandboxPrototype to make them appear as though they're running in the
@ -7830,7 +7800,7 @@ nsGlobalWindow::CallerInnerWindow()
// the |source| of the received message to be the window set as the
// sandboxPrototype. This used to work incidentally for unrelated reasons, but
// now we need to do some special handling to support it.
{
if (xpc::IsSandbox(scope)) {
JSAutoCompartment ac(cx, scope);
JS::Rooted<JSObject*> scopeProto(cx);
bool ok = JS_GetPrototype(cx, scope, &scopeProto);
@ -7838,26 +7808,14 @@ nsGlobalWindow::CallerInnerWindow()
if (scopeProto && xpc::IsSandboxPrototypeProxy(scopeProto) &&
(scopeProto = js::CheckedUnwrap(scopeProto, /* stopAtOuter = */ false)))
{
scope = scopeProto;
global = xpc::NativeGlobal(scopeProto);
NS_ENSURE_TRUE(global, nullptr);
}
}
JSAutoCompartment ac(cx, scope);
// We don't use xpc::WindowOrNull here because we want to be able to tell
// apart the cases of "scope is not an nsISupports at all" and "scope is an
// nsISupports that's not a window". It's not clear whether that's desirable,
// see bug 984467.
nsISupports* native =
nsContentUtils::XPConnect()->GetNativeOfWrapper(cx, scope);
if (!native)
return nullptr;
// The calling window must be holding a reference, so we can just return a
// raw pointer here and let the QI's addref be balanced by the nsCOMPtr
// destructor's release.
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(native);
if (!win)
return GetCurrentInnerWindowInternal();
// The calling window must be holding a reference, so we can return a weak
// pointer.
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(global);
return static_cast<nsGlobalWindow*>(win.get());
}
@ -8258,10 +8216,9 @@ nsGlobalWindow::PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
else {
// In case the global is not a window, it can be a sandbox, and the sandbox's
// principal can be used for the security check.
JSObject *global = CallerGlobal();
nsIGlobalObject* global = GetIncumbentGlobal();
NS_ASSERTION(global, "Why is there no global object?");
JSCompartment *compartment = js::GetObjectCompartment(global);
callerPrin = xpc::GetCompartmentPrincipal(compartment);
callerPrin = global->PrincipalOrNull();
}
if (!callerPrin) {
return;
@ -12023,6 +11980,9 @@ nsGlobalWindow::InnerForSetTimeoutOrInterval(ErrorResult& aError)
// inner window that's calling window.setTimeout().
forwardTo = CallerInnerWindow();
if (!forwardTo && nsContentUtils::IsCallerChrome()) {
forwardTo = currentInner;
}
if (!forwardTo) {
aError.Throw(NS_ERROR_NOT_AVAILABLE);
return nullptr;
@ -12241,14 +12201,15 @@ nsGlobalWindow::SetTimeoutOrInterval(bool aIsInterval, int32_t *aReturn)
if (IsOuterWindow()) {
nsGlobalWindow* callerInner = CallerInnerWindow();
NS_ENSURE_TRUE(callerInner, NS_ERROR_NOT_AVAILABLE);
NS_ENSURE_TRUE(callerInner || nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
// If the caller and the callee share the same outer window,
// forward to the callee inner. Else, we forward to the current
// inner (e.g. someone is calling setTimeout() on a reference to
// some other window).
if (callerInner->GetOuterWindow() == this &&
if (callerInner &&
callerInner->GetOuterWindow() == this &&
callerInner->IsInnerWindow()) {
return callerInner->SetTimeoutOrInterval(aIsInterval, aReturn);
}

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

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

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

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

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

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

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

@ -66,10 +66,10 @@ ToJSValue(JSContext* aCx,
JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(aArgument.Failed());
ThrowMethodFailedWithDetails(aCx, aArgument, "", "");
if (!JS_GetPendingException(aCx, aValue)) {
return false;
}
DebugOnly<bool> throwResult = ThrowMethodFailedWithDetails(aCx, aArgument, "", "");
MOZ_ASSERT(!throwResult);
DebugOnly<bool> getPendingResult = JS_GetPendingException(aCx, aValue);
MOZ_ASSERT(getPendingResult);
JS_ClearPendingException(aCx);
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-mips.html]
[webgl-conformance/_wrappers/test_conformance__textures__texture-npot-video.html]
skip-if = os == 'win'
skip-if = os == 'win' || buildapp == 'mulet' # Mulet - bug 1089453 (crashes in libLLVM-3.0.so)
[webgl-conformance/_wrappers/test_conformance__textures__texture-npot.html]
[webgl-conformance/_wrappers/test_conformance__textures__texture-size.html]
skip-if = os == 'android'

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

@ -12,7 +12,7 @@ fail-if = (os == 'b2g')
[webgl-mochitest/test_fb_param.html]
[webgl-mochitest/test_fb_param_crash.html]
[webgl-mochitest/test_hidden_alpha.html]
fail-if = (os == 'b2g')
skip-if = (os == 'b2g') || buildapp == 'mulet' # Mulet - bug 1093639 (crashes in libLLVM-3.0.so)
[webgl-mochitest/test_highp_fs.html]
[webgl-mochitest/test_no_arr_points.html]
skip-if = android_version == '10' #Android 2.3 aws only; bug 1030942

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

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

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

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

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

@ -14,7 +14,7 @@
* http://www.w3.org/TR/DOM-Level-2-Core/
*/
[builtinclass, uuid(7d0582bd-09a7-430e-969b-054abbea19fe)]
[builtinclass, uuid(7db491e8-a3a3-4432-ad67-e6c33e24ac6d)]
interface nsIDOMAttr : nsIDOMNode
{
readonly attribute DOMString name;

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

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

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

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

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

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

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

@ -32,7 +32,7 @@ interface nsIDOMLocation;
* http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html
*/
[uuid(08c6400b-0b6d-4ce6-b88d-e7a15a9c7c03)]
[uuid(35dc5030-dc83-4291-88a2-0906c549788e)]
interface nsIDOMDocument : nsIDOMNode
{
readonly attribute nsIDOMDocumentType doctype;

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

@ -14,7 +14,7 @@
* http://www.w3.org/TR/DOM-Level-2-Core/
*/
[builtinclass, uuid(24b34c61-7326-42d4-87ec-5d3b5c0b1b26)]
[builtinclass, uuid(48eb8d72-95bb-402e-a8fc-f2b187abcbdb)]
interface nsIDOMDocumentFragment : nsIDOMNode
{
/**

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

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

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

@ -15,7 +15,7 @@ interface nsIDOMMozNamedAttrMap;
* http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#interface-element
*/
[uuid(59eb63f9-c8c0-41d2-bf73-739de43b17f9)]
[uuid(6289999b-1008-4269-b42a-413ec5a9d3f4)]
interface nsIDOMElement : nsIDOMNode
{
readonly attribute DOMString tagName;

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

@ -16,7 +16,7 @@ interface nsIVariant;
* http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html
*/
[uuid(238222a9-7aa5-4804-9f86-484853ce4b15)]
[uuid(cc35b412-009b-46a3-9be0-76448f12548d)]
interface nsIDOMNode : nsISupports
{
const unsigned short ELEMENT_NODE = 1;
@ -69,6 +69,9 @@ interface nsIDOMNode : nsISupports
// Introduced in DOM Level 2:
readonly attribute DOMString localName;
// For vtable compatibility (see bug 1078674)
[noscript] bool unusedPlaceholder();
// Introduced in DOM Level 3:
// This uses a binaryname to avoid warnings due to name collision with
// nsINode::GetBaseURI

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

@ -15,7 +15,7 @@
* http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html
*/
[uuid(d0163f44-8f5b-4234-b3aa-43cab64e2039)]
[uuid(5a139df7-04d0-438d-bd18-d8122564258f)]
interface nsIDOMProcessingInstruction : nsIDOMCharacterData
{
readonly attribute DOMString target;

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

@ -13,7 +13,7 @@
* http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html
*/
[uuid(775bbd26-1581-4e54-b82c-5d9dc5a3363b)]
[uuid(67273994-6aff-4091-9de9-b788a249f783)]
interface nsIDOMText : nsIDOMCharacterData
{
nsIDOMText splitText(in unsigned long offset)

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -23,6 +23,7 @@
#include "mozilla/a11y/DocAccessibleChild.h"
#endif
#include "mozilla/Preferences.h"
#include "mozilla/docshell/OfflineCacheUpdateChild.h"
#include "mozilla/dom/ContentBridgeChild.h"
#include "mozilla/dom/ContentBridgeParent.h"
#include "mozilla/dom/DOMStorageIPC.h"
@ -2258,6 +2259,25 @@ ContentChild::RecvUnregisterSheet(const URIParams& aURI, const uint32_t& aType)
return true;
}
POfflineCacheUpdateChild*
ContentChild::AllocPOfflineCacheUpdateChild(const URIParams& manifestURI,
const URIParams& documentURI,
const bool& stickDocument,
const TabId& aTabId)
{
NS_RUNTIMEABORT("unused");
return nullptr;
}
bool
ContentChild::DeallocPOfflineCacheUpdateChild(POfflineCacheUpdateChild* actor)
{
OfflineCacheUpdateChild* offlineCacheUpdate =
static_cast<OfflineCacheUpdateChild*>(actor);
NS_RELEASE(offlineCacheUpdate);
return true;
}
#ifdef MOZ_NUWA_PROCESS
class CallNuwaSpawn : public nsRunnable
{

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

@ -404,6 +404,14 @@ public:
PBrowserOrId
GetBrowserOrId(TabChild* aTabChild);
virtual POfflineCacheUpdateChild* AllocPOfflineCacheUpdateChild(
const URIParams& manifestURI,
const URIParams& documentURI,
const bool& stickDocument,
const TabId& aTabId) MOZ_OVERRIDE;
virtual bool
DeallocPOfflineCacheUpdateChild(POfflineCacheUpdateChild* offlineCacheUpdate) MOZ_OVERRIDE;
private:
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;

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

@ -35,6 +35,7 @@
#include "nsAccessibilityService.h"
#endif
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/docshell/OfflineCacheUpdateParent.h"
#include "mozilla/dom/DataStoreService.h"
#include "mozilla/dom/DOMStorageIPC.h"
#include "mozilla/dom/Element.h"
@ -84,6 +85,7 @@
#include "nsChromeRegistryChrome.h"
#include "nsConsoleMessage.h"
#include "nsConsoleService.h"
#include "nsContentUtils.h"
#include "nsDebugImpl.h"
#include "nsFrameMessageManager.h"
#include "nsGeolocationSettings.h"
@ -1487,6 +1489,14 @@ ContentParent::ShutDownProcess(bool aCloseWithError)
}
}
const InfallibleTArray<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
// returned from Get*() while in the midst of shutdown.
MarkAsDead();
@ -4317,6 +4327,62 @@ ContentParent::GetManagedTabContext()
GetTabContextByContentProcess(this->ChildID()));
}
mozilla::docshell::POfflineCacheUpdateParent*
ContentParent::AllocPOfflineCacheUpdateParent(const URIParams& aManifestURI,
const URIParams& aDocumentURI,
const bool& aStickDocument,
const TabId& aTabId)
{
TabContext tabContext;
if (!ContentProcessManager::GetSingleton()->
GetTabContextByProcessAndTabId(this->ChildID(), aTabId, &tabContext)) {
return nullptr;
}
nsRefPtr<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 mozilla

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

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

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

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

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

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

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

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

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

@ -36,7 +36,8 @@ class FilePickerParent : public PFilePickerParent
const nsString& aDefaultFile,
const nsString& aDefaultExtension,
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;

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