This commit is contained in:
Wes Kocher 2016-09-12 17:23:31 -07:00
Родитель 6bef888d40 bcc9ea6947
Коммит 5225afcd1a
56 изменённых файлов: 1659 добавлений и 629 удалений

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

@ -228,7 +228,7 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
} }
}, },
_getContentProcessTarget: function () { _getContentProcessTarget: function (processId) {
// Create a DebuggerServer in order to connect locally to it // Create a DebuggerServer in order to connect locally to it
if (!DebuggerServer.initialized) { if (!DebuggerServer.initialized) {
DebuggerServer.init(); DebuggerServer.init();
@ -241,49 +241,54 @@ var gDevToolsBrowser = exports.gDevToolsBrowser = {
let deferred = defer(); let deferred = defer();
client.connect().then(() => { client.connect().then(() => {
client.mainRoot.listProcesses(response => { client.getProcess(processId)
// Do nothing if there is only one process, the parent process. .then(response => {
let contentProcesses = response.processes.filter(p => (!p.parent)); let options = {
if (contentProcesses.length < 1) { form: response.form,
let msg = L10N.getStr("toolbox.noContentProcess.message"); client: client,
Services.prompt.alert(null, "", msg); chrome: true,
deferred.reject("No content processes available."); isTabActor: false
return; };
} return TargetFactory.forRemoteTab(options);
// Otherwise, arbitrary connect to the unique content process. })
client.getProcess(contentProcesses[0].id) .then(target => {
.then(response => { // Ensure closing the connection in order to cleanup
let options = { // the debugger client and also the server created in the
form: response.form, // content process
client: client, target.on("close", () => {
chrome: true, client.close();
isTabActor: false
};
return TargetFactory.forRemoteTab(options);
})
.then(target => {
// Ensure closing the connection in order to cleanup
// the debugger client and also the server created in the
// content process
target.on("close", () => {
client.close();
});
deferred.resolve(target);
}); });
}); deferred.resolve(target);
});
}); });
return deferred.promise; return deferred.promise;
}, },
// Used by browser-sets.inc, command // Used by menus.js
openContentProcessToolbox: function () { openContentProcessToolbox: function (gBrowser) {
this._getContentProcessTarget() let { childCount } = Services.ppmm;
.then(target => { // Get the process message manager for the current tab
// Display a new toolbox, in a new window, with debugger by default let mm = gBrowser.selectedBrowser.messageManager.processMessageManager;
return gDevTools.showToolbox(target, "jsdebugger", let processId = null;
Toolbox.HostType.WINDOW); for (let i = 1; i < childCount; i++) {
}); let child = Services.ppmm.getChildAt(i);
if (child == mm) {
processId = i;
break;
}
}
if (processId) {
this._getContentProcessTarget(processId)
.then(target => {
// Display a new toolbox, in a new window, with debugger by default
return gDevTools.showToolbox(target, "jsdebugger",
Toolbox.HostType.WINDOW);
});
} else {
let msg = L10N.getStr("toolbox.noContentProcessForTab.message");
Services.prompt.alert(null, "", msg);
}
}, },
/** /**

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

@ -189,7 +189,7 @@ Rule.prototype = {
} }
this.applyProperties((modifications) => { this.applyProperties((modifications) => {
modifications.createProperty(ind, name, value, priority); modifications.createProperty(ind, name, value, priority, enabled);
// Now that the rule has been updated, the server might have given us data // Now that the rule has been updated, the server might have given us data
// that changes the state of the property. Update it now. // that changes the state of the property. Update it now.
prop.updateEditor(); prop.updateEditor();

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

@ -29,7 +29,7 @@ function* setPropertyOnAllRules(view) {
// view to be updated. // view to be updated.
let onRefreshed = view.once("ruleview-refreshed"); let onRefreshed = view.once("ruleview-refreshed");
for (let rule of view._elementStyle.rules) { for (let rule of view._elementStyle.rules) {
rule.editor.addProperty("font-weight", "bold", ""); rule.editor.addProperty("font-weight", "bold", "", true);
} }
yield onRefreshed; yield onRefreshed;
} }

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

@ -20,7 +20,7 @@ add_task(function* () {
let ruleEditor = getRuleViewRuleEditor(view, 1); let ruleEditor = getRuleViewRuleEditor(view, 1);
let onRuleViewChanged = view.once("ruleview-changed"); let onRuleViewChanged = view.once("ruleview-changed");
ruleEditor.addProperty("font-weight", "bold", ""); ruleEditor.addProperty("font-weight", "bold", "", true);
yield onRuleViewChanged; yield onRuleViewChanged;
let textProps = ruleEditor.rule.textProps; let textProps = ruleEditor.rule.textProps;

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

@ -47,7 +47,7 @@ function* addNewProperty(view, index, name, value) {
info(`Adding new property "${name}: ${value};"`); info(`Adding new property "${name}: ${value};"`);
let onRuleViewChanged = view.once("ruleview-changed"); let onRuleViewChanged = view.once("ruleview-changed");
idRuleEditor.addProperty(name, value, ""); idRuleEditor.addProperty(name, value, "", true);
yield onRuleViewChanged; yield onRuleViewChanged;
let textProps = idRuleEditor.rule.textProps; let textProps = idRuleEditor.rule.textProps;

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

@ -39,7 +39,7 @@ add_task(function* () {
function* testAddingProperty(view, index) { function* testAddingProperty(view, index) {
let ruleEditor = getRuleViewRuleEditor(view, index); let ruleEditor = getRuleViewRuleEditor(view, index);
ruleEditor.addProperty("font-weight", "bold", ""); ruleEditor.addProperty("font-weight", "bold", "", true);
let textProps = ruleEditor.rule.textProps; let textProps = ruleEditor.rule.textProps;
let lastRule = textProps[textProps.length - 1]; let lastRule = textProps[textProps.length - 1];
is(lastRule.name, "font-weight", "Last rule name is font-weight"); is(lastRule.name, "font-weight", "Last rule name is font-weight");

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

@ -36,7 +36,7 @@ function* testPacman(inspector, view) {
// let defaultView = element.ownerDocument.defaultView; // let defaultView = element.ownerDocument.defaultView;
// let ruleEditor = view.element.children[5].childNodes[0]._ruleEditor; // let ruleEditor = view.element.children[5].childNodes[0]._ruleEditor;
// ruleEditor.addProperty("opacity", "0"); // ruleEditor.addProperty("opacity", "0", true);
// yield ruleEditor._applyingModifications; // yield ruleEditor._applyingModifications;
// yield once(element, "animationend"); // yield once(element, "animationend");

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

@ -70,12 +70,12 @@ function* testTopLeft(inspector, view) {
let onAdded = view.once("ruleview-changed"); let onAdded = view.once("ruleview-changed");
let firstProp = elementFirstLineRuleView.addProperty("background-color", let firstProp = elementFirstLineRuleView.addProperty("background-color",
"rgb(0, 255, 0)", ""); "rgb(0, 255, 0)", "", true);
yield onAdded; yield onAdded;
onAdded = view.once("ruleview-changed"); onAdded = view.once("ruleview-changed");
let secondProp = elementFirstLineRuleView.addProperty("font-style", let secondProp = elementFirstLineRuleView.addProperty("font-style",
"italic", ""); "italic", "", true);
yield onAdded; yield onAdded;
is(firstProp, is(firstProp,
@ -108,7 +108,7 @@ function* testTopLeft(inspector, view) {
onAdded = view.once("ruleview-changed"); onAdded = view.once("ruleview-changed");
firstProp = elementRuleView.addProperty("background-color", firstProp = elementRuleView.addProperty("background-color",
"rgb(0, 0, 255)", ""); "rgb(0, 0, 255)", "", true);
yield onAdded; yield onAdded;
is((yield getComputedStyleProperty(id, null, "background-color")), is((yield getComputedStyleProperty(id, null, "background-color")),

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

@ -32,7 +32,7 @@ function* testPropertyChanges(inspector, ruleView) {
info("Adding a second margin-top value in the element selector"); info("Adding a second margin-top value in the element selector");
let ruleEditor = ruleView._elementStyle.rules[0].editor; let ruleEditor = ruleView._elementStyle.rules[0].editor;
let onRefreshed = inspector.once("rule-view-refreshed"); let onRefreshed = inspector.once("rule-view-refreshed");
ruleEditor.addProperty("margin-top", "5px", ""); ruleEditor.addProperty("margin-top", "5px", "", true);
yield onRefreshed; yield onRefreshed;
let rule = ruleView._elementStyle.rules[0]; let rule = ruleView._elementStyle.rules[0];

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

@ -93,10 +93,10 @@ pickButton.tooltip=Pick an element from the page
# bar, when there's no enough space to show all tabs at once # bar, when there's no enough space to show all tabs at once
sidebar.showAllTabs.tooltip=All tabs sidebar.showAllTabs.tooltip=All tabs
# LOCALIZATION NOTE (toolbox.noContentProcess.message) # LOCALIZATION NOTE (toolbox.noContentProcessForTab.message)
# Used as a message in the alert displayed when trying to open a browser # Used as a message in the alert displayed when trying to open a browser
# content toolbox and there is no content process running # content toolbox and there is no content process running for the current tab
toolbox.noContentProcess.message=No content process running. toolbox.noContentProcessForTab.message=No content process for this tab.
# LOCALIZATION NOTE (toolbox.viewCssSourceInStyleEditor.label) # LOCALIZATION NOTE (toolbox.viewCssSourceInStyleEditor.label)
# Used as a message in either tooltips or contextual menu items to open the # Used as a message in either tooltips or contextual menu items to open the

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

@ -112,8 +112,9 @@ exports.menuitems = [
{ id: "menu_browserContentToolbox", { id: "menu_browserContentToolbox",
l10nKey: "browserContentToolboxMenu", l10nKey: "browserContentToolboxMenu",
disabled: true, disabled: true,
oncommand() { oncommand(event) {
gDevToolsBrowser.openContentProcessToolbox(); let window = event.target.ownerDocument.defaultView;
gDevToolsBrowser.openContentProcessToolbox(window.gBrowser);
} }
}, },
{ id: "menu_browserConsole", { id: "menu_browserConsole",

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

@ -114,6 +114,8 @@ skip-if = (os == 'linux' && e10s && debug) # Bug 1242204
[browser_net_reload-button.js] [browser_net_reload-button.js]
[browser_net_reload-markers.js] [browser_net_reload-markers.js]
[browser_net_req-resp-bodies.js] [browser_net_req-resp-bodies.js]
[browser_net_resend_cors.js]
[browser_net_resend_headers.js]
[browser_net_resend.js] [browser_net_resend.js]
[browser_net_security-details.js] [browser_net_security-details.js]
[browser_net_security-error.js] [browser_net_security-error.js]

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

@ -9,6 +9,7 @@
const ADD_QUERY = "t1=t2"; const ADD_QUERY = "t1=t2";
const ADD_HEADER = "Test-header: true"; const ADD_HEADER = "Test-header: true";
const ADD_UA_HEADER = "User-Agent: Custom-Agent";
const ADD_POSTDATA = "&t3=t4"; const ADD_POSTDATA = "&t3=t4";
add_task(function* () { add_task(function* () {
@ -129,6 +130,11 @@ add_task(function* () {
type(["VK_RETURN"]); type(["VK_RETURN"]);
type(ADD_HEADER); type(ADD_HEADER);
// add a User-Agent header, to check if default headers can be modified
// (there will be two of them, first gets overwritten by the second)
type(["VK_RETURN"]);
type(ADD_UA_HEADER);
let postData = document.getElementById("custom-postdata-value"); let postData = document.getElementById("custom-postdata-value");
let postFocus = once(postData, "focus", false); let postFocus = once(postData, "focus", false);
postData.focus(); postData.focus();
@ -149,6 +155,9 @@ add_task(function* () {
let hasHeader = headers.some(h => `${h.name}: ${h.value}` == ADD_HEADER); let hasHeader = headers.some(h => `${h.name}: ${h.value}` == ADD_HEADER);
ok(hasHeader, "new header added to sent request"); ok(hasHeader, "new header added to sent request");
let hasUAHeader = headers.some(h => `${h.name}: ${h.value}` == ADD_UA_HEADER);
ok(hasUAHeader, "User-Agent header added to sent request");
is(data.requestPostData.postData.text, is(data.requestPostData.postData.text,
origData.requestPostData.postData.text + ADD_POSTDATA, origData.requestPostData.postData.text + ADD_POSTDATA,
"post data added to sent request"); "post data added to sent request");

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

@ -0,0 +1,80 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests if resending a CORS request avoids the security checks and doesn't send
* a preflight OPTIONS request (bug 1270096 and friends)
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(CORS_URL);
info("Starting test... ");
let { EVENTS, NetMonitorView } = monitor.panelWin;
let { RequestsMenu } = NetMonitorView;
RequestsMenu.lazyUpdate = false;
let requestUrl = "http://test1.example.com" + CORS_SJS_PATH;
info("Waiting for OPTIONS, then POST");
let wait = waitForNetworkEvents(monitor, 1, 1);
yield ContentTask.spawn(tab.linkedBrowser, requestUrl, function* (url) {
content.wrappedJSObject.performRequests(url, "triggering/preflight", "post-data");
});
yield wait;
const METHODS = ["OPTIONS", "POST"];
// Check the requests that were sent
for (let [i, method] of METHODS.entries()) {
let { attachment } = RequestsMenu.getItemAtIndex(i);
is(attachment.method, method, `The ${method} request has the right method`);
is(attachment.url, requestUrl, `The ${method} request has the right URL`);
}
// Resend both requests without modification. Wait for resent OPTIONS, then POST.
// POST is supposed to have no preflight OPTIONS request this time (CORS is disabled)
let onRequests = waitForNetworkEvents(monitor, 1, 1);
for (let [i, method] of METHODS.entries()) {
let item = RequestsMenu.getItemAtIndex(i);
info(`Selecting the ${method} request (at index ${i})`);
let onUpdate = monitor.panelWin.once(EVENTS.TAB_UPDATED);
RequestsMenu.selectedItem = item;
yield onUpdate;
info("Cloning the selected request into a custom clone");
let onPopulate = monitor.panelWin.once(EVENTS.CUSTOMREQUESTVIEW_POPULATED);
RequestsMenu.cloneSelectedRequest();
yield onPopulate;
info("Sending the cloned request (without change)");
RequestsMenu.sendCustomRequest();
}
info("Waiting for both resent requests");
yield onRequests;
// Check the resent requests
for (let [i, method] of METHODS.entries()) {
let index = i + 2;
let item = RequestsMenu.getItemAtIndex(index).attachment;
is(item.method, method, `The ${method} request has the right method`);
is(item.url, requestUrl, `The ${method} request has the right URL`);
is(item.status, 200, `The ${method} response has the right status`);
if (method === "POST") {
is(item.requestPostData.postData.text, "post-data",
"The POST request has the right POST data");
// eslint-disable-next-line mozilla/no-cpows-in-tests
is(item.responseContent.content.text, "Access-Control-Allow-Origin: *",
"The POST response has the right content");
}
}
info("Finishing the test");
return teardown(monitor);
});

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

@ -0,0 +1,67 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Test if custom request headers are not ignored (bug 1270096 and friends)
*/
add_task(function* () {
let { monitor } = yield initNetMonitor(SIMPLE_SJS);
info("Starting test... ");
let { NetMonitorView, NetMonitorController } = monitor.panelWin;
let { RequestsMenu } = NetMonitorView;
RequestsMenu.lazyUpdate = false;
let requestUrl = SIMPLE_SJS;
let requestHeaders = [
{ name: "Host", value: "fakehost.example.com" },
{ name: "User-Agent", value: "Testzilla" },
{ name: "Referer", value: "http://example.com/referrer" },
{ name: "Accept", value: "application/jarda"},
{ name: "Accept-Encoding", value: "compress, identity, funcoding" },
{ name: "Accept-Language", value: "cs-CZ" }
];
let wait = waitForNetworkEvents(monitor, 0, 1);
NetMonitorController.webConsoleClient.sendHTTPRequest({
url: requestUrl,
method: "POST",
headers: requestHeaders,
body: "Hello"
});
yield wait;
let { attachment } = RequestsMenu.getItemAtIndex(0);
is(attachment.method, "POST", "The request has the right method");
is(attachment.url, requestUrl, "The request has the right URL");
for (let { name, value } of attachment.requestHeaders.headers) {
info(`Request header: ${name}: ${value}`);
}
function hasRequestHeader(name, value) {
let { headers } = attachment.requestHeaders;
return headers.some(h => h.name === name && h.value === value);
}
function hasNotRequestHeader(name) {
let { headers } = attachment.requestHeaders;
return headers.every(h => h.name !== name);
}
for (let { name, value } of requestHeaders) {
ok(hasRequestHeader(name, value), `The ${name} header has the right value`);
}
// Check that the Cookie header was not added silently (i.e., that the request is
// anonymous.
for (let name of ["Cookie"]) {
ok(hasNotRequestHeader(name), `The ${name} header is not present`);
}
return teardown(monitor);
});

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

@ -64,14 +64,14 @@ const TEST_DATA = [
desc: "simple create", desc: "simple create",
input: "", input: "",
instruction: {type: "create", name: "p", value: "v", priority: "important", instruction: {type: "create", name: "p", value: "v", priority: "important",
index: 0}, index: 0, enabled: true},
expected: "p: v !important;" expected: "p: v !important;"
}, },
{ {
desc: "create between two properties", desc: "create between two properties",
input: "a:b; e: f;", input: "a:b; e: f;",
instruction: {type: "create", name: "c", value: "d", priority: "", instruction: {type: "create", name: "c", value: "d", priority: "",
index: 1}, index: 1, enabled: true},
expected: "a:b; c: d;e: f;" expected: "a:b; c: d;e: f;"
}, },
// "create" is passed the name that the user entered, and must do // "create" is passed the name that the user entered, and must do
@ -80,7 +80,7 @@ const TEST_DATA = [
desc: "create requiring escape", desc: "create requiring escape",
input: "", input: "",
instruction: {type: "create", name: "a b", value: "d", priority: "", instruction: {type: "create", name: "a b", value: "d", priority: "",
index: 1}, index: 1, enabled: true},
expected: "a\\ b: d;" expected: "a\\ b: d;"
}, },
{ {
@ -137,7 +137,7 @@ const TEST_DATA = [
// Note the lack of a trailing semicolon. // Note the lack of a trailing semicolon.
input: "color: red", input: "color: red",
instruction: {type: "create", name: "a", value: "b", priority: "", instruction: {type: "create", name: "a", value: "b", priority: "",
index: 1}, index: 1, enabled: true},
expected: "color: red;a: b;" expected: "color: red;a: b;"
}, },
@ -146,7 +146,7 @@ const TEST_DATA = [
desc: "simple newline insertion", desc: "simple newline insertion",
input: "\ncolor: red;\n", input: "\ncolor: red;\n",
instruction: {type: "create", name: "a", value: "b", priority: "", instruction: {type: "create", name: "a", value: "b", priority: "",
index: 1}, index: 1, enabled: true},
expected: "\ncolor: red;\na: b;\n" expected: "\ncolor: red;\na: b;\n"
}, },
// Newline insertion. // Newline insertion.
@ -155,7 +155,7 @@ const TEST_DATA = [
// Note the lack of a trailing semicolon. // Note the lack of a trailing semicolon.
input: "\ncolor: red\n", input: "\ncolor: red\n",
instruction: {type: "create", name: "a", value: "b", priority: "", instruction: {type: "create", name: "a", value: "b", priority: "",
index: 1}, index: 1, enabled: true},
expected: "\ncolor: red;\na: b;\n" expected: "\ncolor: red;\na: b;\n"
}, },
// Newline insertion. // Newline insertion.
@ -164,7 +164,7 @@ const TEST_DATA = [
// Note the lack of a trailing semicolon and newline. // Note the lack of a trailing semicolon and newline.
input: "\ncolor: red", input: "\ncolor: red",
instruction: {type: "create", name: "a", value: "b", priority: "", instruction: {type: "create", name: "a", value: "b", priority: "",
index: 1}, index: 1, enabled: true},
expected: "\ncolor: red;\na: b;\n" expected: "\ncolor: red;\na: b;\n"
}, },
@ -173,7 +173,7 @@ const TEST_DATA = [
desc: "indentation with create", desc: "indentation with create",
input: "\n color: red;\n", input: "\n color: red;\n",
instruction: {type: "create", name: "a", value: "b", priority: "", instruction: {type: "create", name: "a", value: "b", priority: "",
index: 1}, index: 1, enabled: true},
expected: "\n color: red;\n a: b;\n" expected: "\n color: red;\n a: b;\n"
}, },
// Newline insertion and indentation. // Newline insertion and indentation.
@ -182,7 +182,7 @@ const TEST_DATA = [
// Note the lack of a trailing semicolon. // Note the lack of a trailing semicolon.
input: "\n color: red\n", input: "\n color: red\n",
instruction: {type: "create", name: "a", value: "b", priority: "", instruction: {type: "create", name: "a", value: "b", priority: "",
index: 1}, index: 1, enabled: true},
expected: "\n color: red;\n a: b;\n" expected: "\n color: red;\n a: b;\n"
}, },
{ {
@ -198,7 +198,7 @@ const TEST_DATA = [
// the indentation of the "}". // the indentation of the "}".
input: "\n color: red;\n ", input: "\n color: red;\n ",
instruction: {type: "create", name: "a", value: "b", priority: "", instruction: {type: "create", name: "a", value: "b", priority: "",
index: 1}, index: 1, enabled: true},
expected: "\n color: red;\n a: b;\n " expected: "\n color: red;\n a: b;\n "
}, },
// Newline insertion and indentation. // Newline insertion and indentation.
@ -207,7 +207,7 @@ const TEST_DATA = [
// Note how the comment comes before the declaration. // Note how the comment comes before the declaration.
input: "\n /* comment */ color: red\n", input: "\n /* comment */ color: red\n",
instruction: {type: "create", name: "a", value: "b", priority: "", instruction: {type: "create", name: "a", value: "b", priority: "",
index: 1}, index: 1, enabled: true},
expected: "\n /* comment */ color: red;\n a: b;\n" expected: "\n /* comment */ color: red;\n a: b;\n"
}, },
// Default indentation. // Default indentation.
@ -215,7 +215,7 @@ const TEST_DATA = [
desc: "use of default indentation", desc: "use of default indentation",
input: "\n", input: "\n",
instruction: {type: "create", name: "a", value: "b", priority: "", instruction: {type: "create", name: "a", value: "b", priority: "",
index: 0}, index: 0, enabled: true},
expected: "\n\ta: b;\n" expected: "\n\ta: b;\n"
}, },
@ -275,7 +275,7 @@ const TEST_DATA = [
desc: "create single quote termination", desc: "create single quote termination",
input: "content: 'hi", input: "content: 'hi",
instruction: {type: "create", name: "color", value: "red", priority: "", instruction: {type: "create", name: "color", value: "red", priority: "",
index: 1}, index: 1, enabled: true},
expected: "content: 'hi';color: red;", expected: "content: 'hi';color: red;",
changed: {0: "'hi'"} changed: {0: "'hi'"}
}, },
@ -293,7 +293,7 @@ const TEST_DATA = [
desc: "create double quote termination", desc: "create double quote termination",
input: "content: \"hi", input: "content: \"hi",
instruction: {type: "create", name: "color", value: "red", priority: "", instruction: {type: "create", name: "color", value: "red", priority: "",
index: 1}, index: 1, enabled: true},
expected: "content: \"hi\";color: red;", expected: "content: \"hi\";color: red;",
changed: {0: "\"hi\""} changed: {0: "\"hi\""}
}, },
@ -312,7 +312,7 @@ const TEST_DATA = [
desc: "create url termination", desc: "create url termination",
input: "background-image: url(something.jpg", input: "background-image: url(something.jpg",
instruction: {type: "create", name: "color", value: "red", priority: "", instruction: {type: "create", name: "color", value: "red", priority: "",
index: 1}, index: 1, enabled: true},
expected: "background-image: url(something.jpg);color: red;", expected: "background-image: url(something.jpg);color: red;",
changed: {0: "url(something.jpg)"} changed: {0: "url(something.jpg)"}
}, },
@ -331,7 +331,7 @@ const TEST_DATA = [
desc: "create url single quote termination", desc: "create url single quote termination",
input: "background-image: url('something.jpg", input: "background-image: url('something.jpg",
instruction: {type: "create", name: "color", value: "red", priority: "", instruction: {type: "create", name: "color", value: "red", priority: "",
index: 1}, index: 1, enabled: true},
expected: "background-image: url('something.jpg');color: red;", expected: "background-image: url('something.jpg');color: red;",
changed: {0: "url('something.jpg')"} changed: {0: "url('something.jpg')"}
}, },
@ -350,7 +350,7 @@ const TEST_DATA = [
desc: "enable url double quote termination", desc: "enable url double quote termination",
input: "background-image: url(\"something.jpg", input: "background-image: url(\"something.jpg",
instruction: {type: "create", name: "color", value: "red", priority: "", instruction: {type: "create", name: "color", value: "red", priority: "",
index: 1}, index: 1, enabled: true},
expected: "background-image: url(\"something.jpg\");color: red;", expected: "background-image: url(\"something.jpg\");color: red;",
changed: {0: "url(\"something.jpg\")"} changed: {0: "url(\"something.jpg\")"}
}, },
@ -360,7 +360,7 @@ const TEST_DATA = [
desc: "create backslash termination", desc: "create backslash termination",
input: "something: \\", input: "something: \\",
instruction: {type: "create", name: "color", value: "red", priority: "", instruction: {type: "create", name: "color", value: "red", priority: "",
index: 1}, index: 1, enabled: true},
expected: "something: \\\\;color: red;", expected: "something: \\\\;color: red;",
// The lexer rewrites the token before we see it. However this is // The lexer rewrites the token before we see it. However this is
// so obscure as to be inconsequential. // so obscure as to be inconsequential.
@ -372,7 +372,7 @@ const TEST_DATA = [
desc: "enable backslash single quote termination", desc: "enable backslash single quote termination",
input: "something: '\\", input: "something: '\\",
instruction: {type: "create", name: "color", value: "red", priority: "", instruction: {type: "create", name: "color", value: "red", priority: "",
index: 1}, index: 1, enabled: true},
expected: "something: '\\\\';color: red;", expected: "something: '\\\\';color: red;",
changed: {0: "'\\\\'"} changed: {0: "'\\\\'"}
}, },
@ -380,7 +380,7 @@ const TEST_DATA = [
desc: "enable backslash double quote termination", desc: "enable backslash double quote termination",
input: "something: \"\\", input: "something: \"\\",
instruction: {type: "create", name: "color", value: "red", priority: "", instruction: {type: "create", name: "color", value: "red", priority: "",
index: 1}, index: 1, enabled: true},
expected: "something: \"\\\\\";color: red;", expected: "something: \"\\\\\";color: red;",
changed: {0: "\"\\\\\""} changed: {0: "\"\\\\\""}
}, },
@ -390,7 +390,7 @@ const TEST_DATA = [
desc: "enable comment termination", desc: "enable comment termination",
input: "something: blah /* comment ", input: "something: blah /* comment ",
instruction: {type: "create", name: "color", value: "red", priority: "", instruction: {type: "create", name: "color", value: "red", priority: "",
index: 1}, index: 1, enabled: true},
expected: "something: blah /* comment*/; color: red;" expected: "something: blah /* comment*/; color: red;"
}, },
@ -407,7 +407,7 @@ const TEST_DATA = [
desc: "create sanitize unpaired brace", desc: "create sanitize unpaired brace",
input: "", input: "",
instruction: {type: "create", name: "p", value: "}", priority: "", instruction: {type: "create", name: "p", value: "}", priority: "",
index: 0}, index: 0, enabled: true},
expected: "p: \\};", expected: "p: \\};",
changed: {0: "\\}"} changed: {0: "\\}"}
}, },
@ -435,10 +435,25 @@ const TEST_DATA = [
desc: "disabled declaration does not need semicolon insertion", desc: "disabled declaration does not need semicolon insertion",
input: "/*! no: semicolon */\n", input: "/*! no: semicolon */\n",
instruction: {type: "create", name: "walrus", value: "zebra", priority: "", instruction: {type: "create", name: "walrus", value: "zebra", priority: "",
index: 1}, index: 1, enabled: true},
expected: "/*! no: semicolon */\nwalrus: zebra;\n", expected: "/*! no: semicolon */\nwalrus: zebra;\n",
changed: {} changed: {}
}, },
{
desc: "create commented-out property",
input: "p: v",
instruction: {type: "create", name: "shoveler", value: "duck", priority: "",
index: 1, enabled: false},
expected: "p: v;/*! shoveler: duck; */",
},
{
desc: "disabled create with comment ender in string",
input: "",
instruction: {type: "create", name: "content", value: "'*/'", priority: "",
index: 0, enabled: false},
expected: "/*! content: '*\\/'; */"
},
]; ];
function rewriteDeclarations(inputString, instruction, defaultIndentation) { function rewriteDeclarations(inputString, instruction, defaultIndentation) {
@ -458,7 +473,8 @@ function rewriteDeclarations(inputString, instruction, defaultIndentation) {
case "create": case "create":
rewriter.createProperty(instruction.index, instruction.name, rewriter.createProperty(instruction.index, instruction.name,
instruction.value, instruction.priority); instruction.value, instruction.priority,
instruction.enabled);
break; break;
case "set": case "set":

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

@ -95,6 +95,7 @@ skip-if = e10s && debug # Bug 1252201 - Docshell leak on debug e10s
[browser_styleeditor_sourcemap_large.js] [browser_styleeditor_sourcemap_large.js]
[browser_styleeditor_sourcemap_watching.js] [browser_styleeditor_sourcemap_watching.js]
[browser_styleeditor_sync.js] [browser_styleeditor_sync.js]
[browser_styleeditor_syncAddProperty.js]
[browser_styleeditor_syncAddRule.js] [browser_styleeditor_syncAddRule.js]
[browser_styleeditor_syncAlreadyOpen.js] [browser_styleeditor_syncAlreadyOpen.js]
[browser_styleeditor_syncEditSelector.js] [browser_styleeditor_syncEditSelector.js]

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

@ -0,0 +1,45 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test that adding a new rule is synced to the style editor.
const TESTCASE_URI = TEST_BASE_HTTP + "sync.html";
const expectedText = `
body {
border-width: 15px;
color: red;
}
#testid {
font-size: 4em;
/*! background-color: yellow; */
}
`;
add_task(function* () {
yield addTab(TESTCASE_URI);
let { inspector, view } = yield openRuleView();
yield selectNode("#testid", inspector);
info("Focusing a new property name in the rule-view");
let ruleEditor = getRuleViewRuleEditor(view, 1);
let editor = yield focusEditableField(view, ruleEditor.closeBrace);
is(inplaceEditor(ruleEditor.newPropSpan), editor,
"The new property editor has focus");
let input = editor.input;
input.value = "/* background-color: yellow; */";
info("Pressing return to commit and focus the new value field");
let onModifications = view.once("ruleview-changed");
EventUtils.synthesizeKey("VK_RETURN", {}, view.styleWindow);
yield onModifications;
let { ui } = yield openStyleEditor();
let sourceEditor = yield ui.editors[0].getSourceEditor();
let text = sourceEditor.sourceEditor.getText();
is(text, expectedText, "selector edits are synced");
});

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

@ -23,6 +23,7 @@ loader.lazyRequireGetter(this, "events", "sdk/event/core");
loader.lazyRequireGetter(this, "ServerLoggingListener", "devtools/shared/webconsole/server-logger", true); loader.lazyRequireGetter(this, "ServerLoggingListener", "devtools/shared/webconsole/server-logger", true);
loader.lazyRequireGetter(this, "JSPropertyProvider", "devtools/shared/webconsole/js-property-provider", true); loader.lazyRequireGetter(this, "JSPropertyProvider", "devtools/shared/webconsole/js-property-provider", true);
loader.lazyRequireGetter(this, "Parser", "resource://devtools/shared/Parser.jsm", true); loader.lazyRequireGetter(this, "Parser", "resource://devtools/shared/Parser.jsm", true);
loader.lazyRequireGetter(this, "NetUtil", "resource://gre/modules/NetUtil.jsm", true);
for (let name of ["WebConsoleUtils", "ConsoleServiceListener", for (let name of ["WebConsoleUtils", "ConsoleServiceListener",
"ConsoleAPIListener", "addWebConsoleCommands", "ConsoleAPIListener", "addWebConsoleCommands",
@ -1563,23 +1564,46 @@ WebConsoleActor.prototype =
/** /**
* Send a new HTTP request from the target's window. * Send a new HTTP request from the target's window.
* *
* @param object aMessage * @param object message
* Object with 'request' - the HTTP request details. * Object with 'request' - the HTTP request details.
*/ */
onSendHTTPRequest: function WCA_onSendHTTPRequest(aMessage) onSendHTTPRequest(message) {
{ let { url, method, headers, body } = message.request;
let details = aMessage.request;
// send request from target's window // Set the loadingNode and loadGroup to the target document - otherwise the
let request = new this.window.XMLHttpRequest(); // request won't show up in the opened netmonitor.
request.open(details.method, details.url, true); let doc = this.window.document;
for (let {name, value} of details.headers) { let channel = NetUtil.newChannel({
request.setRequestHeader(name, value); uri: NetUtil.newURI(url),
loadingNode: doc,
securityFlags: Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
contentPolicyType: Ci.nsIContentPolicy.TYPE_OTHER
});
channel.QueryInterface(Ci.nsIHttpChannel);
channel.loadGroup = doc.documentLoadGroup;
channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE |
Ci.nsIRequest.INHIBIT_CACHING |
Ci.nsIRequest.LOAD_ANONYMOUS;
channel.requestMethod = method;
for (let {name, value} of headers) {
channel.setRequestHeader(name, value, false);
} }
request.send(details.body);
let channel = request.channel.QueryInterface(Ci.nsIHttpChannel); if (body) {
channel.QueryInterface(Ci.nsIUploadChannel2);
let bodyStream = Cc["@mozilla.org/io/string-input-stream;1"]
.createInstance(Ci.nsIStringInputStream);
bodyStream.setData(body, body.length);
channel.explicitSetUploadStream(bodyStream, null, -1, method, false);
}
NetUtil.asyncFetch(channel, () => {});
let actor = this.getNetworkEventActor(channel.channelId); let actor = this.getNetworkEventActor(channel.channelId);
// map channel to actor so we can associate future events with it // map channel to actor so we can associate future events with it

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

@ -800,10 +800,12 @@ RuleRewriter.prototype = {
* @param {String} value value of the new property * @param {String} value value of the new property
* @param {String} priority priority of the new property; either * @param {String} priority priority of the new property; either
* the empty string or "important" * the empty string or "important"
* @param {Boolean} enabled True if the new property should be
* enabled, false if disabled
* @return {Promise} a promise that is resolved when the edit has * @return {Promise} a promise that is resolved when the edit has
* completed * completed
*/ */
internalCreateProperty: Task.async(function* (index, name, value, priority) { internalCreateProperty: Task.async(function* (index, name, value, priority, enabled) {
this.completeInitialization(index); this.completeInitialization(index);
let newIndentation = ""; let newIndentation = "";
if (this.hasNewLine) { if (this.hasNewLine) {
@ -833,13 +835,18 @@ RuleRewriter.prototype = {
} }
} }
this.result += newIndentation + CSS.escape(name) + ": " + let newText = CSS.escape(name) + ": " + this.sanitizeText(value, index);
this.sanitizeText(value, index);
if (priority === "important") { if (priority === "important") {
this.result += " !important"; newText += " !important";
} }
this.result += ";"; newText += ";";
if (!enabled) {
newText = "/*" + COMMENT_PARSING_HEURISTIC_BYPASS_CHAR + " " +
escapeCSSComment(newText) + " */";
}
this.result += newIndentation + newText;
if (this.hasNewLine) { if (this.hasNewLine) {
this.result += "\n"; this.result += "\n";
} }
@ -860,10 +867,12 @@ RuleRewriter.prototype = {
* @param {String} value value of the new property * @param {String} value value of the new property
* @param {String} priority priority of the new property; either * @param {String} priority priority of the new property; either
* the empty string or "important" * the empty string or "important"
* @param {Boolean} enabled True if the new property should be
* enabled, false if disabled
*/ */
createProperty: function (index, name, value, priority) { createProperty: function (index, name, value, priority, enabled) {
this.editPromise = this.internalCreateProperty(index, name, value, this.editPromise = this.internalCreateProperty(index, name, value,
priority); priority, enabled);
}, },
/** /**
@ -884,7 +893,7 @@ RuleRewriter.prototype = {
// We might see a "set" on a previously non-existent property; in // We might see a "set" on a previously non-existent property; in
// that case, act like "create". // that case, act like "create".
if (!this.decl) { if (!this.decl) {
this.createProperty(index, name, value, priority); this.createProperty(index, name, value, priority, true);
return; return;
} }

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

@ -398,7 +398,7 @@ var RuleModificationList = Class({
* Create a new property. This implementation does nothing, because * Create a new property. This implementation does nothing, because
* |setRuleText| is not available. * |setRuleText| is not available.
* *
* These parameter are passed, but as they are not used in this * These parameters are passed, but as they are not used in this
* implementation, they are omitted. They are documented here as * implementation, they are omitted. They are documented here as
* this code also defined the interface implemented by @see * this code also defined the interface implemented by @see
* RuleRewriter. * RuleRewriter.
@ -412,6 +412,8 @@ var RuleModificationList = Class({
* @param {String} value value of the new property * @param {String} value value of the new property
* @param {String} priority priority of the new property; either * @param {String} priority priority of the new property; either
* the empty string or "important" * the empty string or "important"
* @param {Boolean} enabled True if the new property should be
* enabled, false if disabled
*/ */
createProperty: function () { createProperty: function () {
// Nothing. // Nothing.

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

@ -9,6 +9,9 @@
@keyframes anim { @keyframes anim {
to { transform: translate(100px); } to { transform: translate(100px); }
} }
@keyframes anotherAnim {
to { transform: translate(0px); }
}
#target { #target {
width: 100px; width: 100px;
height: 100px; height: 100px;
@ -1397,6 +1400,29 @@ function assert_records(expected, desc) {
e.style = ""; e.style = "";
}); });
addAsyncAnimTest("animtion_order_change", aOptions, function*() {
e.style.animation = "anim 100s, anotherAnim 100s";
var animations = e.getAnimations();
yield await_frame();
assert_records([{ added: animations, changed: [], removed: []}],
"records after creation");
e.style.animation = "anotherAnim 100s, anim 100s";
animations = e.getAnimations();
yield await_frame();
assert_records([{ added: [], changed: animations, removed: []}],
"records after the order is changed");
e.style.animation = "anotherAnim 100s, anim 100s";
yield await_frame();
assert_records([],
"no records after applying the same order");
e.style.animation = "";
yield await_frame();
});
}); });
addAsyncAnimTest("tree_ordering", { observe: div, subtree: true }, function*() { addAsyncAnimTest("tree_ordering", { observe: div, subtree: true }, function*() {

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

@ -5982,8 +5982,8 @@ nsGlobalWindow::DispatchResizeEvent(const CSSIntSize& aSize)
CustomEvent* customEvent = static_cast<CustomEvent*>(domEvent.get()); CustomEvent* customEvent = static_cast<CustomEvent*>(domEvent.get());
customEvent->InitCustomEvent(cx, customEvent->InitCustomEvent(cx,
NS_LITERAL_STRING("DOMWindowResize"), NS_LITERAL_STRING("DOMWindowResize"),
/* bubbles = */ true, /* aCanBubble = */ true,
/* cancelable = */ true, /* aCancelable = */ true,
detailValue, detailValue,
res); res);
if (res.Failed()) { if (res.Failed()) {

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

@ -2778,6 +2778,7 @@ nsScriptLoader::PreloadURI(nsIURI *aURI, const nsAString &aCharset,
bool aScriptFromHead, bool aScriptFromHead,
const mozilla::net::ReferrerPolicy aReferrerPolicy) const mozilla::net::ReferrerPolicy aReferrerPolicy)
{ {
NS_ENSURE_TRUE_VOID(mDocument);
// Check to see if scripts has been turned off. // Check to see if scripts has been turned off.
if (!mEnabled || !mDocument->IsScriptEnabled()) { if (!mEnabled || !mDocument->IsScriptEnabled()) {
return; return;
@ -2794,7 +2795,7 @@ nsScriptLoader::PreloadURI(nsIURI *aURI, const nsAString &aCharset,
("nsScriptLoader::PreloadURI, integrity=%s", ("nsScriptLoader::PreloadURI, integrity=%s",
NS_ConvertUTF16toUTF8(aIntegrity).get())); NS_ConvertUTF16toUTF8(aIntegrity).get()));
nsAutoCString sourceUri; nsAutoCString sourceUri;
if (mDocument && mDocument->GetDocumentURI()) { if (mDocument->GetDocumentURI()) {
mDocument->GetDocumentURI()->GetAsciiSpec(sourceUri); mDocument->GetDocumentURI()->GetAsciiSpec(sourceUri);
} }
SRICheck::IntegrityMetadata(aIntegrity, sourceUri, mReporter, &sriMetadata); SRICheck::IntegrityMetadata(aIntegrity, sourceUri, mReporter, &sriMetadata);

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

@ -111,8 +111,8 @@ DispatchCustomDOMEvent(Element* aFrameElement, const nsAString& aEventName,
ErrorResult res; ErrorResult res;
event->InitCustomEvent(cx, event->InitCustomEvent(cx,
aEventName, aEventName,
/* bubbles = */ true, /* aCanBubble = */ true,
/* cancelable = */ true, /* aCancelable = */ true,
aDetailValue, aDetailValue,
res); res);
if (res.Failed()) { if (res.Failed()) {

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

@ -729,11 +729,8 @@ WebGLContext::CreateAndInitGL(bool forceEnabled,
const bool useEGL = PR_GetEnv("MOZ_WEBGL_FORCE_EGL"); const bool useEGL = PR_GetEnv("MOZ_WEBGL_FORCE_EGL");
#ifdef XP_WIN #ifdef XP_WIN
if (!IsWebGL2()) { tryNativeGL = false;
// Use only ANGLE on Windows for WebGL 1. tryANGLE = true;
tryNativeGL = false;
tryANGLE = true;
}
if (gfxPrefs::WebGLDisableWGL()) { if (gfxPrefs::WebGLDisableWGL()) {
tryNativeGL = false; tryNativeGL = false;

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

@ -4593,6 +4593,7 @@ skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.
[generated/test_2_conformance2__state__gl-object-get-calls.html] [generated/test_2_conformance2__state__gl-object-get-calls.html]
skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1')) skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
[generated/test_2_conformance2__transform_feedback__transform_feedback.html] [generated/test_2_conformance2__transform_feedback__transform_feedback.html]
fail-if = (os == 'win' && (os_version == '6.1' || os_version == '6.2' || os_version == '10.0'))
skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1')) skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
[generated/test_2_conformance2__vertex_arrays__vertex-array-object.html] [generated/test_2_conformance2__vertex_arrays__vertex-array-object.html]
fail-if = (os == 'mac') || (os == 'win') fail-if = (os == 'mac') || (os == 'win')
@ -4792,22 +4793,16 @@ skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.
skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1')) skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
[generated/test_2_conformance__glsl__constructors__glsl-construct-bvec2.html] [generated/test_2_conformance__glsl__constructors__glsl-construct-bvec2.html]
skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1')) skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
fail-if = (os == 'win' && os_version == '6.2')
[generated/test_2_conformance__glsl__constructors__glsl-construct-bvec3.html] [generated/test_2_conformance__glsl__constructors__glsl-construct-bvec3.html]
skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1')) skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
fail-if = (os == 'win' && os_version == '6.2')
[generated/test_2_conformance__glsl__constructors__glsl-construct-bvec4.html] [generated/test_2_conformance__glsl__constructors__glsl-construct-bvec4.html]
skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1')) skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
fail-if = (os == 'win' && os_version == '6.2')
[generated/test_2_conformance__glsl__constructors__glsl-construct-ivec2.html] [generated/test_2_conformance__glsl__constructors__glsl-construct-ivec2.html]
skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1')) skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
fail-if = (os == 'win' && os_version == '6.2')
[generated/test_2_conformance__glsl__constructors__glsl-construct-ivec3.html] [generated/test_2_conformance__glsl__constructors__glsl-construct-ivec3.html]
skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1')) skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
fail-if = (os == 'win' && os_version == '6.2')
[generated/test_2_conformance__glsl__constructors__glsl-construct-ivec4.html] [generated/test_2_conformance__glsl__constructors__glsl-construct-ivec4.html]
skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1')) skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
fail-if = (os == 'win' && os_version == '6.2')
[generated/test_2_conformance__glsl__constructors__glsl-construct-mat2.html] [generated/test_2_conformance__glsl__constructors__glsl-construct-mat2.html]
skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1')) skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
[generated/test_2_conformance__glsl__constructors__glsl-construct-mat3.html] [generated/test_2_conformance__glsl__constructors__glsl-construct-mat3.html]
@ -4816,18 +4811,14 @@ skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.
skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1')) skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
[generated/test_2_conformance__glsl__constructors__glsl-construct-vec-mat-corner-cases.html] [generated/test_2_conformance__glsl__constructors__glsl-construct-vec-mat-corner-cases.html]
skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1')) skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
fail-if = (os == 'win' && os_version == '6.2')
[generated/test_2_conformance__glsl__constructors__glsl-construct-vec-mat-index.html] [generated/test_2_conformance__glsl__constructors__glsl-construct-vec-mat-index.html]
skip-if = (os == 'mac') || (os == 'win') || (os == 'linux') || (os == 'android') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1')) skip-if = (os == 'mac') || (os == 'win') || (os == 'linux') || (os == 'android') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
[generated/test_2_conformance__glsl__constructors__glsl-construct-vec2.html] [generated/test_2_conformance__glsl__constructors__glsl-construct-vec2.html]
skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1')) skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
fail-if = (os == 'win' && os_version == '6.2')
[generated/test_2_conformance__glsl__constructors__glsl-construct-vec3.html] [generated/test_2_conformance__glsl__constructors__glsl-construct-vec3.html]
skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1')) skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
fail-if = (os == 'win' && os_version == '6.2')
[generated/test_2_conformance__glsl__constructors__glsl-construct-vec4.html] [generated/test_2_conformance__glsl__constructors__glsl-construct-vec4.html]
skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1')) skip-if = (os == 'win' && os_version == '6.1') || (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
fail-if = (os == 'win' && os_version == '6.2')
[generated/test_2_conformance__glsl__functions__glsl-function-abs.html] [generated/test_2_conformance__glsl__functions__glsl-function-abs.html]
skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1')) skip-if = (os == 'android' || os == 'linux' || (os == 'win' && os_version == '5.1'))
[generated/test_2_conformance__glsl__functions__glsl-function-acos.html] [generated/test_2_conformance__glsl__functions__glsl-function-acos.html]

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

@ -628,49 +628,41 @@ skip-if = (os == 'win' && os_version == '6.1')
[generated/test_2_conformance__glsl__constructors__glsl-construct-bvec2.html] [generated/test_2_conformance__glsl__constructors__glsl-construct-bvec2.html]
# Failure on win7 but got passed on win7 vm # Failure on win7 but got passed on win7 vm
skip-if = (os == 'win' && os_version == '6.1') skip-if = (os == 'win' && os_version == '6.1')
fail-if = (os == 'win' && os_version == '6.2')
[generated/test_2_conformance__glsl__constructors__glsl-construct-bvec3.html] [generated/test_2_conformance__glsl__constructors__glsl-construct-bvec3.html]
# Failure on win7 but got passed on win7 vm # Failure on win7 but got passed on win7 vm
skip-if = (os == 'win' && os_version == '6.1') skip-if = (os == 'win' && os_version == '6.1')
fail-if = (os == 'win' && os_version == '6.2')
[generated/test_2_conformance__glsl__constructors__glsl-construct-bvec4.html] [generated/test_2_conformance__glsl__constructors__glsl-construct-bvec4.html]
# Failure on win7 but got passed on win7 vm # Failure on win7 but got passed on win7 vm
skip-if = (os == 'win' && os_version == '6.1') skip-if = (os == 'win' && os_version == '6.1')
fail-if = (os == 'win' && os_version == '6.2')
[generated/test_2_conformance__glsl__constructors__glsl-construct-ivec2.html] [generated/test_2_conformance__glsl__constructors__glsl-construct-ivec2.html]
# Failure on win7 but got passed on win7 vm # Failure on win7 but got passed on win7 vm
skip-if = (os == 'win' && os_version == '6.1') skip-if = (os == 'win' && os_version == '6.1')
fail-if = (os == 'win' && os_version == '6.2')
[generated/test_2_conformance__glsl__constructors__glsl-construct-ivec3.html] [generated/test_2_conformance__glsl__constructors__glsl-construct-ivec3.html]
# Failure on win7 but got passed on win7 vm # Failure on win7 but got passed on win7 vm
skip-if = (os == 'win' && os_version == '6.1') skip-if = (os == 'win' && os_version == '6.1')
fail-if = (os == 'win' && os_version == '6.2')
[generated/test_2_conformance__glsl__constructors__glsl-construct-ivec4.html] [generated/test_2_conformance__glsl__constructors__glsl-construct-ivec4.html]
# Failure on win7 but got passed on win7 vm # Failure on win7 but got passed on win7 vm
skip-if = (os == 'win' && os_version == '6.1') skip-if = (os == 'win' && os_version == '6.1')
fail-if = (os == 'win' && os_version == '6.2')
[generated/test_2_conformance__glsl__constructors__glsl-construct-vec-mat-corner-cases.html] [generated/test_2_conformance__glsl__constructors__glsl-construct-vec-mat-corner-cases.html]
# Failure on win7 but got passed on win7 vm # Failure on win7 but got passed on win7 vm
skip-if = (os == 'win' && os_version == '6.1') skip-if = (os == 'win' && os_version == '6.1')
fail-if = (os == 'win' && os_version == '6.2')
[generated/test_2_conformance__glsl__constructors__glsl-construct-vec2.html] [generated/test_2_conformance__glsl__constructors__glsl-construct-vec2.html]
# Failure on win7 but got passed on win7 vm # Failure on win7 but got passed on win7 vm
skip-if = (os == 'win' && os_version == '6.1') skip-if = (os == 'win' && os_version == '6.1')
fail-if = (os == 'win' && os_version == '6.2')
[generated/test_2_conformance__glsl__constructors__glsl-construct-vec3.html] [generated/test_2_conformance__glsl__constructors__glsl-construct-vec3.html]
# Failure on win7 but got passed on win7 vm # Failure on win7 but got passed on win7 vm
skip-if = (os == 'win' && os_version == '6.1') skip-if = (os == 'win' && os_version == '6.1')
fail-if = (os == 'win' && os_version == '6.2')
[generated/test_2_conformance__glsl__constructors__glsl-construct-vec4.html] [generated/test_2_conformance__glsl__constructors__glsl-construct-vec4.html]
# Failure on win7 but got passed on win7 vm # Failure on win7 but got passed on win7 vm
skip-if = (os == 'win' && os_version == '6.1') skip-if = (os == 'win' && os_version == '6.1')
fail-if = (os == 'win' && os_version == '6.2')
[generated/test_2_conformance__textures__misc__tex-image-and-sub-image-2d-with-array-buffer-view.html] [generated/test_2_conformance__textures__misc__tex-image-and-sub-image-2d-with-array-buffer-view.html]
# Failure on win7 but got passed on win7 vm # Failure on win7 but got passed on win7 vm
skip-if = (os == 'win' && os_version == '6.1') skip-if = (os == 'win' && os_version == '6.1')
[generated/test_2_conformance__canvas__drawingbuffer-static-canvas-test.html] [generated/test_2_conformance__canvas__drawingbuffer-static-canvas-test.html]
# Framebuffer size can't be GL_MAX_RENDERBUFFER_SIZE # Framebuffer size can't be GL_MAX_RENDERBUFFER_SIZE
skip-if = (os == 'win' && os_version == '6.2') skip-if = (os == 'win' && os_version == '6.2')
[generated/test_2_conformance2__transform_feedback__transform_feedback.html]
fail-if = (os == 'win' && (os_version == '6.1' || os_version == '6.2' || os_version == '10.0'))
#################### ####################
# failure on Windows # failure on Windows

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

@ -1257,7 +1257,7 @@ Geolocation::Shutdown()
if (doc) { if (doc) {
doc->RemoveSystemEventListener(NS_LITERAL_STRING("visibilitychange"), doc->RemoveSystemEventListener(NS_LITERAL_STRING("visibilitychange"),
this, this,
/* useCapture = */ true); /* aUseCapture = */ true);
} }
} }
} }

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

@ -45,6 +45,7 @@
#include "nsThreadUtils.h" #include "nsThreadUtils.h"
#include "nsXULAppAPI.h" #include "nsXULAppAPI.h"
#include "WorkerPrivate.h" #include "WorkerPrivate.h"
#include "WorkerRunnable.h"
#ifdef DEBUG #ifdef DEBUG
#include "BackgroundChild.h" // BackgroundChild::GetForCurrentThread(). #include "BackgroundChild.h" // BackgroundChild::GetForCurrentThread().
@ -1700,10 +1701,17 @@ class BlobChild::RemoteBlobImpl
{ {
protected: protected:
class CreateStreamHelper; class CreateStreamHelper;
class WorkerHolder;
BlobChild* mActor; BlobChild* mActor;
nsCOMPtr<nsIEventTarget> mActorTarget; nsCOMPtr<nsIEventTarget> mActorTarget;
// These member variables are protected by mutex and it's set to null when the
// worker goes away.
WorkerPrivate* mWorkerPrivate;
nsAutoPtr<WorkerHolder> mWorkerHolder;
Mutex mMutex;
// We use this pointer to keep a live a blobImpl coming from a different // We use this pointer to keep a live a blobImpl coming from a different
// process until this one is fully created. We set it to null when // process until this one is fully created. We set it to null when
// SendCreatedFromKnownBlob() is received. This is used only with KnownBlob // SendCreatedFromKnownBlob() is received. This is used only with KnownBlob
@ -1823,6 +1831,16 @@ public:
mDifferentProcessBlobImpl = nullptr; mDifferentProcessBlobImpl = nullptr;
} }
// Used only by CreateStreamHelper, it dispatches a runnable to the target
// thread. This thread can be the main-thread, the background thread or a
// worker. If the thread is a worker, the aRunnable is wrapper into a
// ControlRunnable in order to avoid to be blocked into a sync event loop.
nsresult
DispatchToTarget(nsIRunnable* aRunnable);
void
WorkerHasNotified();
protected: protected:
// For SliceImpl. // For SliceImpl.
RemoteBlobImpl(const nsAString& aContentType, uint64_t aLength); RemoteBlobImpl(const nsAString& aContentType, uint64_t aLength);
@ -1840,8 +1858,28 @@ protected:
Destroy(); Destroy();
}; };
class BlobChild::RemoteBlobImpl::WorkerHolder final
: public workers::WorkerHolder
{
// Raw pointer because this class is kept alive by the mRemoteBlobImpl.
RemoteBlobImpl* mRemoteBlobImpl;
public:
explicit WorkerHolder(RemoteBlobImpl* aRemoteBlobImpl)
: mRemoteBlobImpl(aRemoteBlobImpl)
{
MOZ_ASSERT(aRemoteBlobImpl);
}
bool Notify(Status aStatus) override
{
mRemoteBlobImpl->WorkerHasNotified();
return true;
}
};
class BlobChild::RemoteBlobImpl::CreateStreamHelper final class BlobChild::RemoteBlobImpl::CreateStreamHelper final
: public Runnable : public CancelableRunnable
{ {
Monitor mMonitor; Monitor mMonitor;
RefPtr<RemoteBlobImpl> mRemoteBlobImpl; RefPtr<RemoteBlobImpl> mRemoteBlobImpl;
@ -1856,8 +1894,7 @@ public:
nsresult nsresult
GetStream(nsIInputStream** aInputStream); GetStream(nsIInputStream** aInputStream);
NS_DECL_ISUPPORTS_INHERITED NS_IMETHOD Run() override;
NS_DECL_NSIRUNNABLE
private: private:
~CreateStreamHelper() ~CreateStreamHelper()
@ -2054,6 +2091,8 @@ RemoteBlobImpl::RemoteBlobImpl(BlobChild* aActor,
BlobImplIsDirectory aIsDirectory, BlobImplIsDirectory aIsDirectory,
bool aIsSameProcessBlob) bool aIsSameProcessBlob)
: BlobImplBase(aName, aContentType, aLength, aModDate) : BlobImplBase(aName, aContentType, aLength, aModDate)
, mWorkerPrivate(nullptr)
, mMutex("BlobChild::RemoteBlobImpl::mMutex")
, mIsSlice(false), mIsDirectory(aIsDirectory == eDirectory) , mIsSlice(false), mIsDirectory(aIsDirectory == eDirectory)
{ {
SetPath(aPath); SetPath(aPath);
@ -2076,6 +2115,8 @@ RemoteBlobImpl::RemoteBlobImpl(BlobChild* aActor,
uint64_t aLength, uint64_t aLength,
bool aIsSameProcessBlob) bool aIsSameProcessBlob)
: BlobImplBase(aContentType, aLength) : BlobImplBase(aContentType, aLength)
, mWorkerPrivate(nullptr)
, mMutex("BlobChild::RemoteBlobImpl::mMutex")
, mIsSlice(false), mIsDirectory(false) , mIsSlice(false), mIsDirectory(false)
{ {
if (aIsSameProcessBlob) { if (aIsSameProcessBlob) {
@ -2092,6 +2133,8 @@ RemoteBlobImpl::RemoteBlobImpl(BlobChild* aActor,
BlobChild:: BlobChild::
RemoteBlobImpl::RemoteBlobImpl(BlobChild* aActor) RemoteBlobImpl::RemoteBlobImpl(BlobChild* aActor)
: BlobImplBase(EmptyString(), EmptyString(), UINT64_MAX, INT64_MAX) : BlobImplBase(EmptyString(), EmptyString(), UINT64_MAX, INT64_MAX)
, mWorkerPrivate(nullptr)
, mMutex("BlobChild::RemoteBlobImpl::mMutex")
, mIsSlice(false), mIsDirectory(false) , mIsSlice(false), mIsDirectory(false)
{ {
CommonInit(aActor); CommonInit(aActor);
@ -2101,6 +2144,8 @@ BlobChild::
RemoteBlobImpl::RemoteBlobImpl(const nsAString& aContentType, uint64_t aLength) RemoteBlobImpl::RemoteBlobImpl(const nsAString& aContentType, uint64_t aLength)
: BlobImplBase(aContentType, aLength) : BlobImplBase(aContentType, aLength)
, mActor(nullptr) , mActor(nullptr)
, mWorkerPrivate(nullptr)
, mMutex("BlobChild::RemoteBlobImpl::mMutex")
, mIsSlice(true) , mIsSlice(true)
, mIsDirectory(false) , mIsDirectory(false)
{ {
@ -2118,6 +2163,22 @@ RemoteBlobImpl::CommonInit(BlobChild* aActor)
mActor = aActor; mActor = aActor;
mActorTarget = aActor->EventTarget(); mActorTarget = aActor->EventTarget();
if (!NS_IsMainThread()) {
mWorkerPrivate = GetCurrentThreadWorkerPrivate();
// We must comunicate via IPC in the owning thread, so, if this BlobImpl has
// been created on a Workerr and then it's sent to a different thread (for
// instance the main-thread), we still need to keep alive that Worker.
if (mWorkerPrivate) {
mWorkerHolder = new RemoteBlobImpl::WorkerHolder(this);
if (NS_WARN_IF(!mWorkerHolder->HoldWorker(mWorkerPrivate, Closing))) {
// We don't care too much if the worker is already going away because no
// sync-event-loop can be created at this point.
mWorkerPrivate = nullptr;
mWorkerHolder = nullptr;
}
}
}
mImmutable = true; mImmutable = true;
} }
@ -2161,6 +2222,13 @@ RemoteBlobImpl::Destroy()
mActor->NoteDyingRemoteBlobImpl(); mActor->NoteDyingRemoteBlobImpl();
} }
if (mWorkerHolder) {
// We are in the worker thread.
MutexAutoLock lock(mMutex);
mWorkerPrivate = nullptr;
mWorkerHolder = nullptr;
}
delete this; delete this;
return; return;
} }
@ -2345,6 +2413,71 @@ RemoteBlobImpl::GetBlobParent()
return nullptr; return nullptr;
} }
class RemoteBlobControlRunnable : public WorkerControlRunnable
{
nsCOMPtr<nsIRunnable> mRunnable;
public:
RemoteBlobControlRunnable(WorkerPrivate* aWorkerPrivate,
nsIRunnable* aRunnable)
: WorkerControlRunnable(aWorkerPrivate, WorkerThreadUnchangedBusyCount)
, mRunnable(aRunnable)
{
MOZ_ASSERT(aRunnable);
}
bool
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
{
mRunnable->Run();
return true;
}
};
nsresult
BlobChild::
RemoteBlobImpl::DispatchToTarget(nsIRunnable* aRunnable)
{
MOZ_ASSERT(aRunnable);
// We have to protected mWorkerPrivate because this method can be called by
// any thread (sort of).
MutexAutoLock lock(mMutex);
if (mWorkerPrivate) {
MOZ_ASSERT(mWorkerHolder);
RefPtr<RemoteBlobControlRunnable> controlRunnable =
new RemoteBlobControlRunnable(mWorkerPrivate, aRunnable);
if (!controlRunnable->Dispatch()) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsCOMPtr<nsIEventTarget> target = BaseRemoteBlobImpl()->GetActorEventTarget();
if (!target) {
target = do_GetMainThread();
}
MOZ_ASSERT(target);
return target->Dispatch(aRunnable, NS_DISPATCH_NORMAL);
}
void
BlobChild::
RemoteBlobImpl::WorkerHasNotified()
{
MutexAutoLock lock(mMutex);
mWorkerHolder->ReleaseWorker();
mWorkerHolder = nullptr;
mWorkerPrivate = nullptr;
}
/******************************************************************************* /*******************************************************************************
* BlobChild::RemoteBlobImpl::CreateStreamHelper * BlobChild::RemoteBlobImpl::CreateStreamHelper
******************************************************************************/ ******************************************************************************/
@ -2382,16 +2515,7 @@ CreateStreamHelper::GetStream(nsIInputStream** aInputStream)
if (EventTargetIsOnCurrentThread(baseRemoteBlobImpl->GetActorEventTarget())) { if (EventTargetIsOnCurrentThread(baseRemoteBlobImpl->GetActorEventTarget())) {
RunInternal(baseRemoteBlobImpl, false); RunInternal(baseRemoteBlobImpl, false);
} else { } else {
MOZ_ASSERT(!NS_IsMainThread()); nsresult rv = baseRemoteBlobImpl->DispatchToTarget(this);
nsCOMPtr<nsIEventTarget> target = baseRemoteBlobImpl->GetActorEventTarget();
if (!target) {
target = do_GetMainThread();
}
MOZ_ASSERT(target);
nsresult rv = target->Dispatch(this, NS_DISPATCH_NORMAL);
if (NS_WARN_IF(NS_FAILED(rv))) { if (NS_WARN_IF(NS_FAILED(rv))) {
return rv; return rv;
} }
@ -2462,9 +2586,6 @@ CreateStreamHelper::RunInternal(RemoteBlobImpl* aBaseRemoteBlobImpl,
} }
} }
NS_IMPL_ISUPPORTS_INHERITED0(BlobChild::RemoteBlobImpl::CreateStreamHelper,
Runnable)
NS_IMETHODIMP NS_IMETHODIMP
BlobChild::RemoteBlobImpl:: BlobChild::RemoteBlobImpl::
CreateStreamHelper::Run() CreateStreamHelper::Run()

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

@ -101,6 +101,13 @@
ok(vremote, "Should have remote video element for pcRemote"); ok(vremote, "Should have remote video element for pcRemote");
return helper.waitForFrames(vremote); return helper.waitForFrames(vremote);
}, },
// For some reason, even though we're getting a 25x25 stream, sometimes
// the resolution isn't updated on the video element on the first frame.
function PC_REMOTE_WAIT_FOR_FRAMES_3() {
var vremote = test.pcRemote.remoteMediaElements[0];
ok(vremote, "Should have remote video element for pcRemote");
return helper.waitForFrames(vremote);
},
function PC_REMOTE_CHECK_SIZE_2() { function PC_REMOTE_CHECK_SIZE_2() {
var vlocal = test.pcLocal.localMediaElements[0]; var vlocal = test.pcLocal.localMediaElements[0];
var vremote = test.pcRemote.remoteMediaElements[0]; var vremote = test.pcRemote.remoteMediaElements[0];

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

@ -130,7 +130,7 @@ interface XMLHttpRequest : XMLHttpRequestEventTarget {
attribute XMLHttpRequestResponseType responseType; attribute XMLHttpRequestResponseType responseType;
[Throws] [Throws]
readonly attribute any response; readonly attribute any response;
[Throws] [Cached, Pure, Throws]
readonly attribute DOMString? responseText; readonly attribute DOMString? responseText;
[Throws, Exposed=Window] [Throws, Exposed=Window]

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

@ -1437,7 +1437,9 @@ GetWorkerPrivateFromContext(JSContext* aCx)
MOZ_ASSERT(aCx); MOZ_ASSERT(aCx);
void* cxPrivate = JS_GetContextPrivate(aCx); void* cxPrivate = JS_GetContextPrivate(aCx);
MOZ_ASSERT(cxPrivate); if (!cxPrivate) {
return nullptr;
}
return return
static_cast<WorkerThreadContextPrivate*>(cxPrivate)->GetWorkerPrivate(); static_cast<WorkerThreadContextPrivate*>(cxPrivate)->GetWorkerPrivate();
@ -1457,7 +1459,13 @@ GetCurrentThreadWorkerPrivate()
MOZ_ASSERT(cx); MOZ_ASSERT(cx);
void* cxPrivate = JS_GetContextPrivate(cx); void* cxPrivate = JS_GetContextPrivate(cx);
MOZ_ASSERT(cxPrivate); if (!cxPrivate) {
// This can happen if the nsCycleCollector_shutdown() in ~WorkerJSRuntime()
// triggers any calls to GetCurrentThreadWorkerPrivate(). At this stage
// CycleCollectedJSRuntime::Get() will still return a runtime, but
// the context private has already been cleared.
return nullptr;
}
return return
static_cast<WorkerThreadContextPrivate*>(cxPrivate)->GetWorkerPrivate(); static_cast<WorkerThreadContextPrivate*>(cxPrivate)->GetWorkerPrivate();

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

@ -103,6 +103,8 @@ support-files =
importScripts_3rdParty_worker.js importScripts_3rdParty_worker.js
worker_bug1278777.js worker_bug1278777.js
worker_setTimeoutWith0.js worker_setTimeoutWith0.js
worker_bug1301094.js
script_bug1301094.js
!/dom/base/test/file_websocket_basic_wsh.py !/dom/base/test/file_websocket_basic_wsh.py
!/dom/base/test/file_websocket_hello_wsh.py !/dom/base/test/file_websocket_hello_wsh.py
!/dom/base/test/file_websocket_http_resource.txt !/dom/base/test/file_websocket_http_resource.txt
@ -227,3 +229,4 @@ skip-if = buildapp == 'b2g' || toolkit == 'android' #bug 982828
[test_navigator_workers_hardwareConcurrency.html] [test_navigator_workers_hardwareConcurrency.html]
[test_bug1278777.html] [test_bug1278777.html]
[test_setTimeoutWith0.html] [test_setTimeoutWith0.html]
[test_bug1301094.html]

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

@ -0,0 +1,15 @@
var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.importGlobalProperties(["File", "Directory"]);
addMessageListener("file.open", function (e) {
var tmpFile = Cc["@mozilla.org/file/directory_service;1"]
.getService(Ci.nsIDirectoryService)
.QueryInterface(Ci.nsIProperties)
.get('TmpD', Ci.nsIFile)
tmpFile.append('file.txt');
tmpFile.createUnique(Components.interfaces.nsIFile.FILE_TYPE, 0o600);
sendAsyncMessage("file.opened", {
data: new File(tmpFile)
});
});

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

@ -0,0 +1,69 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1301094
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1301094</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1301094">Mozilla Bug 1301094</a>
<input id="file" type="file"></input>
<script type="application/javascript">
SimpleTest.waitForExplicitFinish();
var url = SimpleTest.getTestFileURL("script_bug1301094.js");
script = SpecialPowers.loadChromeScript(url);
var mainThreadOk, workerOk;
function maybeFinish() {
if (mainThreadOk & workerOk) {
SimpleTest.finish();
}
}
function onOpened(message) {
var input = document.getElementById('file');
SpecialPowers.wrap(input).mozSetDndFilesAndDirectories([message.data]);
var worker = new Worker('worker_bug1301094.js');
worker.onerror = function() {
ok(false, "We should not see any error.");
SimpleTest.finish();
}
worker.onmessage = function(e) {
ok(e.data, "Everything seems OK on the worker-side.");
workerOk = true;
maybeFinish();
}
is(input.files.length, 1, "We have something");
ok(input.files[0] instanceof Blob, "We have one Blob");
worker.postMessage(input.files[0]);
var xhr = new XMLHttpRequest();
xhr.open("POST", 'worker_bug1301094.js', false);
xhr.onload = function() {
ok(xhr.responseText, "Everything seems OK on the main-thread-side.");
mainThreadOk = true;
maybeFinish();
};
var fd = new FormData();
fd.append('file', input.files[0]);
xhr.send(fd);
}
script.addMessageListener("file.opened", onOpened);
script.sendAsyncMessage("file.open");
</script>
</body>
</html>

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

@ -0,0 +1,11 @@
onmessage = function(e) {
var xhr = new XMLHttpRequest();
xhr.open("POST", 'worker_bug1301094.js', false);
xhr.onload = function() {
self.postMessage("OK");
};
var fd = new FormData();
fd.append('file', e.data);
xhr.send(fd);
}

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

@ -288,7 +288,7 @@ XMLHttpRequestMainThread::ResetResponse()
{ {
mResponseXML = nullptr; mResponseXML = nullptr;
mResponseBody.Truncate(); mResponseBody.Truncate();
mResponseText.Truncate(); TruncateResponseText();
mResponseBlob = nullptr; mResponseBlob = nullptr;
mDOMBlob = nullptr; mDOMBlob = nullptr;
mBlobSet = nullptr; mBlobSet = nullptr;
@ -420,7 +420,7 @@ XMLHttpRequestMainThread::SizeOfEventTargetIncludingThis(
// - Binary extensions, but they're *extremely* unlikely to do any memory // - Binary extensions, but they're *extremely* unlikely to do any memory
// reporting. // reporting.
// //
n += mResponseText.SizeOfExcludingThisEvenIfShared(aMallocSizeOf); n += mResponseText.SizeOfThis(aMallocSizeOf);
return n; return n;
@ -535,35 +535,30 @@ XMLHttpRequestMainThread::AppendToResponseText(const char * aSrcBuffer,
&destBufferLen); &destBufferLen);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
uint32_t size = mResponseText.Length() + destBufferLen; CheckedInt32 size = mResponseText.Length();
if (size < (uint32_t)destBufferLen) { size += destBufferLen;
if (!size.isValid()) {
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
} }
if (!mResponseText.SetCapacity(size, fallible)) { XMLHttpRequestStringWriterHelper helper(mResponseText);
if (!helper.AddCapacity(destBufferLen)) {
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
} }
char16_t* destBuffer = mResponseText.BeginWriting() + mResponseText.Length();
CheckedInt32 totalChars = mResponseText.Length();
// This code here is basically a copy of a similar thing in // This code here is basically a copy of a similar thing in
// nsScanner::Append(const char* aBuffer, uint32_t aLen). // nsScanner::Append(const char* aBuffer, uint32_t aLen).
int32_t srclen = (int32_t)aSrcBufferLen; int32_t srclen = (int32_t)aSrcBufferLen;
int32_t destlen = (int32_t)destBufferLen; int32_t destlen = (int32_t)destBufferLen;
rv = mDecoder->Convert(aSrcBuffer, rv = mDecoder->Convert(aSrcBuffer,
&srclen, &srclen,
destBuffer, helper.EndOfExistingData(),
&destlen); &destlen);
MOZ_ASSERT(NS_SUCCEEDED(rv)); MOZ_ASSERT(NS_SUCCEEDED(rv));
MOZ_ASSERT(destlen <= destBufferLen);
totalChars += destlen; helper.AddLength(destlen);
if (!totalChars.isValid()) {
return NS_ERROR_OUT_OF_MEMORY;
}
mResponseText.SetLength(totalChars.value());
return NS_OK; return NS_OK;
} }
@ -571,9 +566,7 @@ NS_IMETHODIMP
XMLHttpRequestMainThread::GetResponseText(nsAString& aResponseText) XMLHttpRequestMainThread::GetResponseText(nsAString& aResponseText)
{ {
ErrorResult rv; ErrorResult rv;
nsString responseText; GetResponseText(aResponseText, rv);
GetResponseText(responseText, rv);
aResponseText = responseText;
return rv.StealNSResult(); return rv.StealNSResult();
} }
@ -581,7 +574,20 @@ void
XMLHttpRequestMainThread::GetResponseText(nsAString& aResponseText, XMLHttpRequestMainThread::GetResponseText(nsAString& aResponseText,
ErrorResult& aRv) ErrorResult& aRv)
{ {
aResponseText.Truncate(); XMLHttpRequestStringSnapshot snapshot;
GetResponseText(snapshot, aRv);
if (aRv.Failed()) {
return;
}
snapshot.GetAsString(aResponseText);
}
void
XMLHttpRequestMainThread::GetResponseText(XMLHttpRequestStringSnapshot& aSnapshot,
ErrorResult& aRv)
{
aSnapshot.Reset();
if (mResponseType != XMLHttpRequestResponseType::_empty && if (mResponseType != XMLHttpRequestResponseType::_empty &&
mResponseType != XMLHttpRequestResponseType::Text && mResponseType != XMLHttpRequestResponseType::Text &&
@ -592,7 +598,7 @@ XMLHttpRequestMainThread::GetResponseText(nsAString& aResponseText,
if (mResponseType == XMLHttpRequestResponseType::Moz_chunked_text && if (mResponseType == XMLHttpRequestResponseType::Moz_chunked_text &&
!mInLoadProgressEvent) { !mInLoadProgressEvent) {
aResponseText.SetIsVoid(true); aSnapshot.SetVoid();
return; return;
} }
@ -605,7 +611,7 @@ XMLHttpRequestMainThread::GetResponseText(nsAString& aResponseText,
// more. // more.
if ((!mResponseXML && !mErrorParsingXML) || if ((!mResponseXML && !mErrorParsingXML) ||
mResponseBodyDecodedPos == mResponseBody.Length()) { mResponseBodyDecodedPos == mResponseBody.Length()) {
aResponseText = mResponseText; mResponseText.CreateSnapshot(aSnapshot);
return; return;
} }
@ -627,7 +633,7 @@ XMLHttpRequestMainThread::GetResponseText(nsAString& aResponseText,
mResponseBodyDecodedPos = 0; mResponseBodyDecodedPos = 0;
} }
aResponseText = mResponseText; mResponseText.CreateSnapshot(aSnapshot);
} }
nsresult nsresult
@ -637,11 +643,12 @@ XMLHttpRequestMainThread::CreateResponseParsedJSON(JSContext* aCx)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
nsAutoString string;
mResponseText.GetAsString(string);
// The Unicode converter has already zapped the BOM if there was one // The Unicode converter has already zapped the BOM if there was one
JS::Rooted<JS::Value> value(aCx); JS::Rooted<JS::Value> value(aCx);
if (!JS_ParseJSON(aCx, if (!JS_ParseJSON(aCx, string.BeginReading(), string.Length(), &value)) {
static_cast<const char16_t*>(mResponseText.get()), mResponseText.Length(),
&value)) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
@ -749,7 +756,7 @@ XMLHttpRequestMainThread::GetResponse(JSContext* aCx,
case XMLHttpRequestResponseType::Text: case XMLHttpRequestResponseType::Text:
case XMLHttpRequestResponseType::Moz_chunked_text: case XMLHttpRequestResponseType::Moz_chunked_text:
{ {
nsString str; nsAutoString str;
aRv = GetResponseText(str); aRv = GetResponseText(str);
if (aRv.Failed()) { if (aRv.Failed()) {
return; return;
@ -823,7 +830,7 @@ XMLHttpRequestMainThread::GetResponse(JSContext* aCx,
if (mResultJSON.isUndefined()) { if (mResultJSON.isUndefined()) {
aRv = CreateResponseParsedJSON(aCx); aRv = CreateResponseParsedJSON(aCx);
mResponseText.Truncate(); TruncateResponseText();
if (aRv.Failed()) { if (aRv.Failed()) {
// Per spec, errors aren't propagated. null is returned instead. // Per spec, errors aren't propagated. null is returned instead.
aRv = NS_OK; aRv = NS_OK;
@ -1332,7 +1339,7 @@ XMLHttpRequestMainThread::DispatchProgressEvent(DOMEventTargetHelper* aTarget,
if (mResponseType == XMLHttpRequestResponseType::Moz_chunked_text || if (mResponseType == XMLHttpRequestResponseType::Moz_chunked_text ||
mResponseType == XMLHttpRequestResponseType::Moz_chunked_arraybuffer) { mResponseType == XMLHttpRequestResponseType::Moz_chunked_arraybuffer) {
mResponseBody.Truncate(); mResponseBody.Truncate();
mResponseText.Truncate(); TruncateResponseText();
mResultArrayBuffer = nullptr; mResultArrayBuffer = nullptr;
mArrayBufferBuilder.reset(); mArrayBufferBuilder.reset();
} }
@ -1691,6 +1698,7 @@ XMLHttpRequestMainThread::OnDataAvailable(nsIRequest *request,
MOZ_ASSERT(mContext.get() == ctxt,"start context different from OnDataAvailable context"); MOZ_ASSERT(mContext.get() == ctxt,"start context different from OnDataAvailable context");
mProgressSinceLastProgressEvent = true; mProgressSinceLastProgressEvent = true;
XMLHttpRequestBinding::ClearCachedResponseTextValue(this);
bool cancelable = false; bool cancelable = false;
if ((mResponseType == XMLHttpRequestResponseType::Blob || if ((mResponseType == XMLHttpRequestResponseType::Blob ||
@ -2145,7 +2153,7 @@ XMLHttpRequestMainThread::MatchCharsetAndDecoderToResponseDocument()
{ {
if (mResponseXML && mResponseCharset != mResponseXML->GetDocumentCharacterSet()) { if (mResponseXML && mResponseCharset != mResponseXML->GetDocumentCharacterSet()) {
mResponseCharset = mResponseXML->GetDocumentCharacterSet(); mResponseCharset = mResponseXML->GetDocumentCharacterSet();
mResponseText.Truncate(); TruncateResponseText();
mResponseBodyDecodedPos = 0; mResponseBodyDecodedPos = 0;
mDecoder = EncodingUtils::DecoderForEncoding(mResponseCharset); mDecoder = EncodingUtils::DecoderForEncoding(mResponseCharset);
} }
@ -3537,6 +3545,13 @@ XMLHttpRequestMainThread::ShouldBlockAuthPrompt()
return false; return false;
} }
void
XMLHttpRequestMainThread::TruncateResponseText()
{
mResponseText.Truncate();
XMLHttpRequestBinding::ClearCachedResponseTextValue(this);
}
NS_IMPL_ISUPPORTS(XMLHttpRequestMainThread::nsHeaderVisitor, nsIHttpHeaderVisitor) NS_IMPL_ISUPPORTS(XMLHttpRequestMainThread::nsHeaderVisitor, nsIHttpHeaderVisitor)
NS_IMETHODIMP XMLHttpRequestMainThread:: NS_IMETHODIMP XMLHttpRequestMainThread::

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

@ -38,6 +38,7 @@
#include "mozilla/dom/XMLHttpRequest.h" #include "mozilla/dom/XMLHttpRequest.h"
#include "mozilla/dom/XMLHttpRequestBinding.h" #include "mozilla/dom/XMLHttpRequestBinding.h"
#include "mozilla/dom/XMLHttpRequestEventTarget.h" #include "mozilla/dom/XMLHttpRequestEventTarget.h"
#include "mozilla/dom/XMLHttpRequestString.h"
#ifdef Status #ifdef Status
/* Xlib headers insist on this for some reason... Nuke it because /* Xlib headers insist on this for some reason... Nuke it because
@ -469,6 +470,10 @@ public:
virtual void virtual void
GetResponseText(nsAString& aResponseText, ErrorResult& aRv) override; GetResponseText(nsAString& aResponseText, ErrorResult& aRv) override;
void
GetResponseText(XMLHttpRequestStringSnapshot& aSnapshot,
ErrorResult& aRv);
virtual nsIDocument* virtual nsIDocument*
GetResponseXML(ErrorResult& aRv) override; GetResponseXML(ErrorResult& aRv) override;
@ -573,6 +578,8 @@ protected:
already_AddRefed<nsIHttpChannel> GetCurrentHttpChannel(); already_AddRefed<nsIHttpChannel> GetCurrentHttpChannel();
already_AddRefed<nsIJARChannel> GetCurrentJARChannel(); already_AddRefed<nsIJARChannel> GetCurrentJARChannel();
void TruncateResponseText();
bool IsSystemXHR() const; bool IsSystemXHR() const;
bool InUploadPhase() const; bool InUploadPhase() const;
@ -628,7 +635,7 @@ protected:
// lazily decode into this from mResponseBody only when .responseText is // lazily decode into this from mResponseBody only when .responseText is
// accessed. // accessed.
// Only used for DEFAULT and TEXT responseTypes. // Only used for DEFAULT and TEXT responseTypes.
nsString mResponseText; XMLHttpRequestString mResponseText;
// For DEFAULT responseType we use this to keep track of how far we've // For DEFAULT responseType we use this to keep track of how far we've
// lazily decoded from mResponseBody to mResponseText // lazily decoded from mResponseBody to mResponseText

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

@ -0,0 +1,254 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#include "XMLHttpRequestString.h"
#include "mozilla/Mutex.h"
#include "nsISupportsImpl.h"
namespace mozilla {
namespace dom {
class XMLHttpRequestStringBuffer final
{
friend class XMLHttpRequestStringWriterHelper;
friend class XMLHttpRequestStringSnapshotReaderHelper;
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(XMLHttpRequestStringBuffer)
NS_DECL_OWNINGTHREAD
XMLHttpRequestStringBuffer()
: mMutex("XMLHttpRequestStringBuffer::mMutex")
{
}
uint32_t
Length()
{
MutexAutoLock lock(mMutex);
return mData.Length();
}
uint32_t
UnsafeLength() const
{
return mData.Length();
}
void
Append(const nsAString& aString)
{
NS_ASSERT_OWNINGTHREAD(XMLHttpRequestStringBuffer);
MutexAutoLock lock(mMutex);
mData.Append(aString);
}
void
GetAsString(nsAString& aString)
{
MutexAutoLock lock(mMutex);
aString = mData;
}
size_t
SizeOfThis(MallocSizeOf aMallocSizeOf) const
{
return mData.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
}
void
GetAsString(nsAString& aString, uint32_t aLength)
{
MutexAutoLock lock(mMutex);
MOZ_ASSERT(aLength <= mData.Length());
aString.Assign(mData.BeginReading(), aLength);
}
void
CreateSnapshot(XMLHttpRequestStringSnapshot& aSnapshot)
{
MutexAutoLock lock(mMutex);
aSnapshot.Set(this, mData.Length());
}
private:
~XMLHttpRequestStringBuffer()
{}
nsString& UnsafeData()
{
return mData;
}
Mutex mMutex;
// The following member variable is protected by mutex.
nsString mData;
};
// ---------------------------------------------------------------------------
// XMLHttpRequestString
XMLHttpRequestString::XMLHttpRequestString()
: mBuffer(new XMLHttpRequestStringBuffer())
{
}
XMLHttpRequestString::~XMLHttpRequestString()
{
}
void
XMLHttpRequestString::Truncate()
{
mBuffer = new XMLHttpRequestStringBuffer();
}
uint32_t
XMLHttpRequestString::Length() const
{
return mBuffer->Length();
}
void
XMLHttpRequestString::Append(const nsAString& aString)
{
mBuffer->Append(aString);
}
void
XMLHttpRequestString::GetAsString(nsAString& aString) const
{
return mBuffer->GetAsString(aString);
}
size_t
XMLHttpRequestString::SizeOfThis(MallocSizeOf aMallocSizeOf) const
{
return mBuffer->SizeOfThis(aMallocSizeOf);
}
bool
XMLHttpRequestString::IsEmpty() const
{
return !mBuffer->Length();
}
void
XMLHttpRequestString::CreateSnapshot(XMLHttpRequestStringSnapshot& aSnapshot)
{
mBuffer->CreateSnapshot(aSnapshot);
}
// ---------------------------------------------------------------------------
// XMLHttpRequestStringSnapshot
XMLHttpRequestStringSnapshot::XMLHttpRequestStringSnapshot()
: mLength(0)
, mVoid(false)
{
}
XMLHttpRequestStringSnapshot::~XMLHttpRequestStringSnapshot()
{
}
XMLHttpRequestStringSnapshot&
XMLHttpRequestStringSnapshot::operator=(const XMLHttpRequestStringSnapshot& aOther)
{
mBuffer = aOther.mBuffer;
mLength = aOther.mLength;
mVoid = aOther.mVoid;
return *this;
}
void
XMLHttpRequestStringSnapshot::ResetInternal(bool aIsVoid)
{
mBuffer = nullptr;
mLength = 0;
mVoid = aIsVoid;
}
void
XMLHttpRequestStringSnapshot::Set(XMLHttpRequestStringBuffer* aBuffer,
uint32_t aLength)
{
MOZ_ASSERT(aBuffer);
MOZ_ASSERT(aLength <= aBuffer->UnsafeLength());
mBuffer = aBuffer;
mLength = aLength;
mVoid = false;
}
void
XMLHttpRequestStringSnapshot::GetAsString(nsAString& aString) const
{
if (mBuffer) {
MOZ_ASSERT(!mVoid);
mBuffer->GetAsString(aString, mLength);
return;
}
aString.Truncate();
if (mVoid) {
aString.SetIsVoid(true);
}
}
// ---------------------------------------------------------------------------
// XMLHttpRequestStringWriterHelper
XMLHttpRequestStringWriterHelper::XMLHttpRequestStringWriterHelper(XMLHttpRequestString& aString)
: mBuffer(aString.mBuffer)
, mLock(aString.mBuffer->mMutex)
{
}
bool
XMLHttpRequestStringWriterHelper::AddCapacity(int32_t aCapacity)
{
return mBuffer->UnsafeData().SetCapacity(mBuffer->UnsafeLength() + aCapacity, fallible);
}
char16_t*
XMLHttpRequestStringWriterHelper::EndOfExistingData()
{
return mBuffer->UnsafeData().BeginWriting() + mBuffer->UnsafeLength();
}
void
XMLHttpRequestStringWriterHelper::AddLength(int32_t aLength)
{
mBuffer->UnsafeData().SetLength(mBuffer->UnsafeLength() + aLength);
}
// ---------------------------------------------------------------------------
// XMLHttpRequestStringReaderHelper
XMLHttpRequestStringSnapshotReaderHelper::XMLHttpRequestStringSnapshotReaderHelper(XMLHttpRequestStringSnapshot& aSnapshot)
: mBuffer(aSnapshot.mBuffer)
, mLock(aSnapshot.mBuffer->mMutex)
{
}
const char16_t*
XMLHttpRequestStringSnapshotReaderHelper::Buffer() const
{
return mBuffer->UnsafeData().BeginReading();
}
uint32_t
XMLHttpRequestStringSnapshotReaderHelper::Length() const
{
return mBuffer->UnsafeLength();
}
} // dom namespace
} // mozilla namespace

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

@ -0,0 +1,160 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef mozilla_dom_XMLHttpRequestString_h
#define mozilla_dom_XMLHttpRequestString_h
#include "nsString.h"
namespace mozilla {
class Mutex;
namespace dom {
class XMLHttpRequestStringBuffer;
class XMLHttpRequestStringSnapshot;
class XMLHttpRequestStringWriterHelper;
class XMLHttpRequestStringSnapshotReaderHelper;
// We want to avoid the dup of strings when XHR in workers has access to
// responseText for events dispatched during the loading state. For this reason
// we use this class, able to create snapshots of the current size of itself
// without making extra copies.
class XMLHttpRequestString final
{
friend class XMLHttpRequestStringWriterHelper;
public:
XMLHttpRequestString();
~XMLHttpRequestString();
void Truncate();
uint32_t Length() const;
void Append(const nsAString& aString);
// This method should be called only when the string is really needed because
// it can cause the duplication of the strings in case the loading of the XHR
// is not completed yet.
void GetAsString(nsAString& aString) const;
size_t SizeOfThis(MallocSizeOf aMallocSizeOf) const;
const char16_t* Data() const;
bool IsEmpty() const;
void CreateSnapshot(XMLHttpRequestStringSnapshot& aSnapshot);
private:
XMLHttpRequestString(const XMLHttpRequestString&) = delete;
XMLHttpRequestString& operator=(const XMLHttpRequestString&) = delete;
XMLHttpRequestString& operator=(const XMLHttpRequestString&&) = delete;
RefPtr<XMLHttpRequestStringBuffer> mBuffer;
};
// This class locks the buffer and allows the callee to write data into it.
class MOZ_STACK_CLASS XMLHttpRequestStringWriterHelper final
{
public:
explicit XMLHttpRequestStringWriterHelper(XMLHttpRequestString& aString);
bool
AddCapacity(int32_t aCapacity);
char16_t*
EndOfExistingData();
void
AddLength(int32_t aLength);
private:
XMLHttpRequestStringWriterHelper(const XMLHttpRequestStringWriterHelper&) = delete;
XMLHttpRequestStringWriterHelper& operator=(const XMLHttpRequestStringWriterHelper&) = delete;
XMLHttpRequestStringWriterHelper& operator=(const XMLHttpRequestStringWriterHelper&&) = delete;
RefPtr<XMLHttpRequestStringBuffer> mBuffer;
MutexAutoLock mLock;
};
// This class is the internal XMLHttpRequestStringBuffer of the
// XMLHttpRequestString plus the current length. GetAsString will return the
// string with that particular length also if the XMLHttpRequestStringBuffer is
// grown in the meantime.
class XMLHttpRequestStringSnapshot final
{
friend class XMLHttpRequestStringBuffer;
friend class XMLHttpRequestStringSnapshotReaderHelper;
public:
XMLHttpRequestStringSnapshot();
~XMLHttpRequestStringSnapshot();
XMLHttpRequestStringSnapshot& operator=(const XMLHttpRequestStringSnapshot&);
void Reset()
{
ResetInternal(false /* isVoid */);
}
void SetVoid()
{
ResetInternal(true /* isVoid */);
}
bool IsVoid() const
{
return mVoid;
}
bool IsEmpty() const
{
return !mLength;
}
void GetAsString(nsAString& aString) const;
private:
XMLHttpRequestStringSnapshot(const XMLHttpRequestStringSnapshot&) = delete;
XMLHttpRequestStringSnapshot& operator=(const XMLHttpRequestStringSnapshot&&) = delete;
void Set(XMLHttpRequestStringBuffer* aBuffer, uint32_t aLength);
void ResetInternal(bool aIsVoid);
RefPtr<XMLHttpRequestStringBuffer> mBuffer;
uint32_t mLength;
bool mVoid;
};
// This class locks the buffer and allows the callee to read data from it.
class MOZ_STACK_CLASS XMLHttpRequestStringSnapshotReaderHelper final
{
public:
explicit XMLHttpRequestStringSnapshotReaderHelper(XMLHttpRequestStringSnapshot& aSnapshot);
const char16_t*
Buffer() const;
uint32_t
Length() const;
private:
XMLHttpRequestStringSnapshotReaderHelper(const XMLHttpRequestStringSnapshotReaderHelper&) = delete;
XMLHttpRequestStringSnapshotReaderHelper& operator=(const XMLHttpRequestStringSnapshotReaderHelper&) = delete;
XMLHttpRequestStringSnapshotReaderHelper& operator=(const XMLHttpRequestStringSnapshotReaderHelper&&) = delete;
RefPtr<XMLHttpRequestStringBuffer> mBuffer;
MutexAutoLock mLock;
};
} // dom namespace
} // mozilla namespace
#endif // mozilla_dom_XMLHttpRequestString_h

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

@ -476,7 +476,7 @@ class EventRunnable final : public MainThreadProxyRunnable
nsString mType; nsString mType;
nsString mResponseType; nsString mResponseType;
JS::Heap<JS::Value> mResponse; JS::Heap<JS::Value> mResponse;
nsString mResponseText; XMLHttpRequestStringSnapshot mResponseText;
nsString mResponseURL; nsString mResponseURL;
nsCString mStatusText; nsCString mStatusText;
uint64_t mLoaded; uint64_t mLoaded;
@ -1129,7 +1129,10 @@ EventRunnable::PreDispatch(WorkerPrivate* /* unused */)
MOZ_ASSERT(false, "This should never fail!"); MOZ_ASSERT(false, "This should never fail!");
} }
mResponseTextResult = xhr->GetResponseText(mResponseText); ErrorResult rv;
xhr->GetResponseText(mResponseText, rv);
mResponseTextResult = rv.StealNSResult();
if (NS_SUCCEEDED(mResponseTextResult)) { if (NS_SUCCEEDED(mResponseTextResult)) {
mResponseResult = mResponseTextResult; mResponseResult = mResponseTextResult;
if (mResponseText.IsVoid()) { if (mResponseText.IsVoid()) {
@ -1172,7 +1175,6 @@ EventRunnable::PreDispatch(WorkerPrivate* /* unused */)
} }
if (doClone) { if (doClone) {
ErrorResult rv;
Write(cx, response, transferable, rv); Write(cx, response, transferable, rv);
if (NS_WARN_IF(rv.Failed())) { if (NS_WARN_IF(rv.Failed())) {
NS_WARNING("Failed to clone response!"); NS_WARNING("Failed to clone response!");
@ -1186,7 +1188,6 @@ EventRunnable::PreDispatch(WorkerPrivate* /* unused */)
mStatusResult = xhr->GetStatus(&mStatus); mStatusResult = xhr->GetStatus(&mStatus);
ErrorResult rv;
xhr->GetStatusText(mStatusText, rv); xhr->GetStatusText(mStatusText, rv);
MOZ_ASSERT(!rv.Failed()); MOZ_ASSERT(!rv.Failed());
@ -1261,6 +1262,7 @@ EventRunnable::WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
JS::Rooted<UniquePtr<XMLHttpRequestWorker::StateData>> state(aCx, new XMLHttpRequestWorker::StateData()); JS::Rooted<UniquePtr<XMLHttpRequestWorker::StateData>> state(aCx, new XMLHttpRequestWorker::StateData());
state->mResponseTextResult = mResponseTextResult; state->mResponseTextResult = mResponseTextResult;
state->mResponseText = mResponseText; state->mResponseText = mResponseText;
if (NS_SUCCEEDED(mResponseTextResult)) { if (NS_SUCCEEDED(mResponseTextResult)) {
@ -2390,10 +2392,11 @@ XMLHttpRequestWorker::GetResponse(JSContext* /* unused */,
mStateData.mResponse = mStateData.mResponse =
JS_GetEmptyStringValue(mWorkerPrivate->GetJSContext()); JS_GetEmptyStringValue(mWorkerPrivate->GetJSContext());
} else { } else {
XMLHttpRequestStringSnapshotReaderHelper helper(mStateData.mResponseText);
JSString* str = JSString* str =
JS_NewUCStringCopyN(mWorkerPrivate->GetJSContext(), JS_NewUCStringCopyN(mWorkerPrivate->GetJSContext(),
mStateData.mResponseText.get(), helper.Buffer(), helper.Length());
mStateData.mResponseText.Length());
if (!str) { if (!str) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY); aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
@ -2413,7 +2416,13 @@ void
XMLHttpRequestWorker::GetResponseText(nsAString& aResponseText, ErrorResult& aRv) XMLHttpRequestWorker::GetResponseText(nsAString& aResponseText, ErrorResult& aRv)
{ {
aRv = mStateData.mResponseTextResult; aRv = mStateData.mResponseTextResult;
aResponseText = mStateData.mResponseText; if (aRv.Failed()) {
return;
}
nsAutoString foo;
mStateData.mResponseText.GetAsString(foo);
aResponseText.Assign(foo.BeginReading(), foo.Length());
} }
void void
@ -2432,6 +2441,8 @@ XMLHttpRequestWorker::UpdateState(const StateData& aStateData,
else { else {
mStateData = aStateData; mStateData = aStateData;
} }
XMLHttpRequestBinding::ClearCachedResponseTextValue(this);
} }
} // dom namespace } // dom namespace

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

@ -9,6 +9,7 @@
#include "WorkerHolder.h" #include "WorkerHolder.h"
#include "XMLHttpRequest.h" #include "XMLHttpRequest.h"
#include "XMLHttpRequestString.h"
#include "mozilla/dom/TypedArray.h" #include "mozilla/dom/TypedArray.h"
namespace mozilla { namespace mozilla {
@ -27,7 +28,7 @@ class XMLHttpRequestWorker final : public XMLHttpRequest,
public: public:
struct StateData struct StateData
{ {
nsString mResponseText; XMLHttpRequestStringSnapshot mResponseText;
nsString mResponseURL; nsString mResponseURL;
uint32_t mStatus; uint32_t mStatus;
nsCString mStatusText; nsCString mStatusText;
@ -266,7 +267,7 @@ public:
void void
NullResponseText() NullResponseText()
{ {
mStateData.mResponseText.SetIsVoid(true); mStateData.mResponseText.SetVoid();
mStateData.mResponse.setNull(); mStateData.mResponse.setNull();
} }

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

@ -14,6 +14,7 @@ EXPORTS.mozilla.dom += [
'XMLHttpRequest.h', 'XMLHttpRequest.h',
'XMLHttpRequestEventTarget.h', 'XMLHttpRequestEventTarget.h',
'XMLHttpRequestMainThread.h', 'XMLHttpRequestMainThread.h',
'XMLHttpRequestString.h',
'XMLHttpRequestUpload.h', 'XMLHttpRequestUpload.h',
] ]
@ -21,6 +22,7 @@ UNIFIED_SOURCES += [
'XMLHttpRequest.cpp', 'XMLHttpRequest.cpp',
'XMLHttpRequestEventTarget.cpp', 'XMLHttpRequestEventTarget.cpp',
'XMLHttpRequestMainThread.cpp', 'XMLHttpRequestMainThread.cpp',
'XMLHttpRequestString.cpp',
'XMLHttpRequestUpload.cpp', 'XMLHttpRequestUpload.cpp',
'XMLHttpRequestWorker.cpp', 'XMLHttpRequestWorker.cpp',
] ]

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

@ -17,15 +17,27 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1277814
var subframe = document.getElementById('bug1277814-div'); var subframe = document.getElementById('bug1277814-div');
subframe.classList.add('a'); subframe.classList.add('a');
// The transform change is animated, so let's step through 1s of animation
var utils = SpecialPowers.getDOMWindowUtils(window);
for (var i = 0; i < 60; i++) {
utils.advanceTimeAndRefresh(16);
}
utils.restoreNormalRefresh();
// Wait for the layer tree with any updated dispatch-to-content region to
// get pushed over to the APZ
yield waitForAllPaints(function() {
flushApzRepaints(testDriver);
});
// Trigger layerization of the subframe by scrolling the wheel over it // Trigger layerization of the subframe by scrolling the wheel over it
moveMouseAndScrollWheelOver(subframe, 10, 10, testDriver); yield moveMouseAndScrollWheelOver(subframe, 10, 10, testDriver);
// Give APZ the chance to compute a displayport, and content // Give APZ the chance to compute a displayport, and content
// to render based on it. // to render based on it.
yield waitForApzFlushedRepaints(testDriver); yield waitForApzFlushedRepaints(testDriver);
// Examine the content-side APZ test data // Examine the content-side APZ test data
var utils = SpecialPowers.getDOMWindowUtils(window);
var contentTestData = utils.getContentAPZTestData(); var contentTestData = utils.getContentAPZTestData();
// Test that the scroll frame for the div 'bug1277814-div' appears in // Test that the scroll frame for the div 'bug1277814-div' appears in

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

@ -137,6 +137,10 @@ public:
void SetAnimationIndex(uint64_t aIndex) void SetAnimationIndex(uint64_t aIndex)
{ {
MOZ_ASSERT(IsTiedToMarkup()); MOZ_ASSERT(IsTiedToMarkup());
if (IsRelevant() &&
mAnimationIndex != aIndex) {
nsNodeUtils::AnimationChanged(this);
}
mAnimationIndex = aIndex; mAnimationIndex = aIndex;
} }

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

@ -318,19 +318,20 @@ bool nsCSSValue::operator==(const nsCSSValue& aOther) const
return false; return false;
} }
double nsCSSValue::GetAngleValueInRadians() const double
nsCSSValue::GetAngleValueInRadians() const
{ {
double angle = GetFloatValue(); double angle = GetFloatValue();
switch (GetUnit()) { switch (GetUnit()) {
case eCSSUnit_Radian: return angle; case eCSSUnit_Radian: return angle;
case eCSSUnit_Turn: return angle * 2 * M_PI; case eCSSUnit_Turn: return angle * 2 * M_PI;
case eCSSUnit_Degree: return angle * M_PI / 180.0; case eCSSUnit_Degree: return angle * M_PI / 180.0;
case eCSSUnit_Grad: return angle * M_PI / 200.0; case eCSSUnit_Grad: return angle * M_PI / 200.0;
default: default:
MOZ_ASSERT(false, "unrecognized angular unit"); MOZ_ASSERT(false, "unrecognized angular unit");
return 0.0; return 0.0;
} }
} }

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

@ -1 +1 @@
NSPR_4_13_BETA2 NSPR_4_13_BETA3

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

@ -10,3 +10,4 @@
*/ */
#error "Do not include this header file." #error "Do not include this header file."

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

@ -3338,6 +3338,7 @@ static PRFileDesc *pt_SetMethods(
case PR_DESC_PIPE: case PR_DESC_PIPE:
fd->methods = PR_GetPipeMethods(); fd->methods = PR_GetPipeMethods();
pt_MakeFdNonblock(osfd); pt_MakeFdNonblock(osfd);
fd->secret->nonblocking = PR_TRUE;
break; break;
default: default:
break; break;

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

@ -119,7 +119,7 @@ class TcpTransport(object):
""" """
max_packet_length = 4096 max_packet_length = 4096
def __init__(self, addr, port, socket_timeout=360.0): def __init__(self, addr, port, socket_timeout=60.0):
"""If `socket_timeout` is `0` or `0.0`, non-blocking socket mode """If `socket_timeout` is `0` or `0.0`, non-blocking socket mode
will be used. Setting it to `1` or `None` disables timeouts on will be used. Setting it to `1` or `None` disables timeouts on
socket operations altogether. socket operations altogether.

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

@ -243,7 +243,7 @@ class MarionetteTextTestRunner(StructuredTestRunner):
class BaseMarionetteArguments(ArgumentParser): class BaseMarionetteArguments(ArgumentParser):
socket_timeout_default = 360.0 socket_timeout_default = 60.0
def __init__(self, **kwargs): def __init__(self, **kwargs):
ArgumentParser.__init__(self, **kwargs) ArgumentParser.__init__(self, **kwargs)

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

@ -68,7 +68,7 @@ def mach_parsed_kwargs(logger):
'server_root': None, 'server_root': None,
'shuffle': False, 'shuffle': False,
'shuffle_seed': 2276870381009474531, 'shuffle_seed': 2276870381009474531,
'socket_timeout': 360.0, 'socket_timeout': 60.0,
'sources': None, 'sources': None,
'startup_timeout': 60, 'startup_timeout': 60,
'symbols_path': None, 'symbols_path': None,

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

@ -42,9 +42,14 @@ function scheduleNextWindow() {
} }
function calcMedian( numbers ) { function calcMedian( numbers ) {
numbers.sort( function (a,b){ return a-b; } ); // Avoid changing the original array.
var n = Math.floor( numbers.length / 2 ); var sortedNumbers = Array.from(numbers);
return numbers.length % 2 ? numbers[n] : ( numbers[n-1] + numbers[n] ) / 2; sortedNumbers.sort( function (a,b){ return a-b; } );
var n = Math.floor( sortedNumbers.length / 2 );
if (sortedNumbers.length % 2) {
return sortedNumbers[n];
}
return ( sortedNumbers[n-1] + sortedNumbers[n] ) / 2;
} }
function reportTimes() { function reportTimes() {

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

@ -16,6 +16,49 @@ namespace mozilla {
using namespace dom; using namespace dom;
InputData::InputData(InputType aInputType)
: mInputType(aInputType)
, mTime(0)
, modifiers(0)
{
}
InputData::InputData(InputType aInputType, uint32_t aTime, TimeStamp aTimeStamp,
Modifiers aModifiers)
: mInputType(aInputType)
, mTime(aTime)
, mTimeStamp(aTimeStamp)
, modifiers(aModifiers)
{
}
SingleTouchData::SingleTouchData(int32_t aIdentifier, ScreenIntPoint aScreenPoint,
ScreenSize aRadius, float aRotationAngle,
float aForce)
: mIdentifier(aIdentifier)
, mScreenPoint(aScreenPoint)
, mRadius(aRadius)
, mRotationAngle(aRotationAngle)
, mForce(aForce)
{
}
SingleTouchData::SingleTouchData(int32_t aIdentifier,
ParentLayerPoint aLocalScreenPoint,
ScreenSize aRadius, float aRotationAngle,
float aForce)
: mIdentifier(aIdentifier)
, mLocalScreenPoint(aLocalScreenPoint)
, mRadius(aRadius)
, mRotationAngle(aRotationAngle)
, mForce(aForce)
{
}
SingleTouchData::SingleTouchData()
{
}
already_AddRefed<Touch> SingleTouchData::ToNewDOMTouch() const already_AddRefed<Touch> SingleTouchData::ToNewDOMTouch() const
{ {
MOZ_ASSERT(NS_IsMainThread(), MOZ_ASSERT(NS_IsMainThread(),
@ -28,147 +71,26 @@ already_AddRefed<Touch> SingleTouchData::ToNewDOMTouch() const
return touch.forget(); return touch.forget();
} }
MouseInput::MouseInput(const WidgetMouseEventBase& aMouseEvent) MultiTouchInput::MultiTouchInput(MultiTouchType aType, uint32_t aTime,
: InputData(MOUSE_INPUT, aMouseEvent.mTime, aMouseEvent.mTimeStamp, TimeStamp aTimeStamp, Modifiers aModifiers)
aMouseEvent.mModifiers) : InputData(MULTITOUCH_INPUT, aTime, aTimeStamp, aModifiers)
, mType(MOUSE_NONE) , mType(aType)
, mButtonType(NONE) , mHandledByAPZ(false)
, mInputSource(aMouseEvent.inputSource)
, mButtons(aMouseEvent.buttons)
, mHandledByAPZ(aMouseEvent.mFlags.mHandledByAPZ)
{ {
MOZ_ASSERT(NS_IsMainThread(),
"Can only copy from WidgetTouchEvent on main thread");
mButtonType = NONE;
switch (aMouseEvent.button) {
case WidgetMouseEventBase::eLeftButton:
mButtonType = MouseInput::LEFT_BUTTON;
break;
case WidgetMouseEventBase::eMiddleButton:
mButtonType = MouseInput::MIDDLE_BUTTON;
break;
case WidgetMouseEventBase::eRightButton:
mButtonType = MouseInput::RIGHT_BUTTON;
break;
}
switch (aMouseEvent.mMessage) {
case eMouseMove:
mType = MOUSE_MOVE;
break;
case eMouseUp:
mType = MOUSE_UP;
break;
case eMouseDown:
mType = MOUSE_DOWN;
break;
case eDragStart:
mType = MOUSE_DRAG_START;
break;
case eDragEnd:
mType = MOUSE_DRAG_END;
break;
case eMouseEnterIntoWidget:
mType = MOUSE_WIDGET_ENTER;
break;
case eMouseExitFromWidget:
mType = MOUSE_WIDGET_EXIT;
break;
default:
MOZ_ASSERT_UNREACHABLE("Mouse event type not supported");
break;
}
mOrigin =
ScreenPoint(ViewAs<ScreenPixel>(aMouseEvent.mRefPoint,
PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent));
} }
bool MultiTouchInput::MultiTouchInput()
MouseInput::TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform) : InputData(MULTITOUCH_INPUT)
, mHandledByAPZ(false)
{ {
Maybe<ParentLayerPoint> point = UntransformBy(aTransform, mOrigin);
if (!point) {
return false;
}
mLocalOrigin = *point;
return true;
} }
WidgetMouseEvent MultiTouchInput::MultiTouchInput(const MultiTouchInput& aOther)
MouseInput::ToWidgetMouseEvent(nsIWidget* aWidget) const : InputData(MULTITOUCH_INPUT, aOther.mTime, aOther.mTimeStamp, aOther.modifiers)
, mType(aOther.mType)
, mHandledByAPZ(aOther.mHandledByAPZ)
{ {
MOZ_ASSERT(NS_IsMainThread(), mTouches.AppendElements(aOther.mTouches);
"Can only convert To WidgetTouchEvent on main thread");
EventMessage msg = eVoidEvent;
uint32_t clickCount = 0;
switch (mType) {
case MOUSE_MOVE:
msg = eMouseMove;
break;
case MOUSE_UP:
msg = eMouseUp;
clickCount = 1;
break;
case MOUSE_DOWN:
msg = eMouseDown;
clickCount = 1;
break;
case MOUSE_DRAG_START:
msg = eDragStart;
break;
case MOUSE_DRAG_END:
msg = eDragEnd;
break;
case MOUSE_WIDGET_ENTER:
msg = eMouseEnterIntoWidget;
break;
case MOUSE_WIDGET_EXIT:
msg = eMouseExitFromWidget;
break;
default:
MOZ_ASSERT_UNREACHABLE("Did not assign a type to WidgetMouseEvent in MouseInput");
break;
}
WidgetMouseEvent event(true, msg, aWidget, WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal);
if (msg == eVoidEvent) {
return event;
}
switch (mButtonType) {
case MouseInput::LEFT_BUTTON:
event.button = WidgetMouseEventBase::eLeftButton;
break;
case MouseInput::MIDDLE_BUTTON:
event.button = WidgetMouseEventBase::eMiddleButton;
break;
case MouseInput::RIGHT_BUTTON:
event.button = WidgetMouseEventBase::eRightButton;
break;
case MouseInput::NONE:
default:
break;
}
event.buttons = mButtons;
event.mModifiers = modifiers;
event.mTime = mTime;
event.mTimeStamp = mTimeStamp;
event.mFlags.mHandledByAPZ = mHandledByAPZ;
event.mRefPoint =
RoundedToInt(ViewAs<LayoutDevicePixel>(mOrigin,
PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent));
event.mClickCount = clickCount;
event.inputSource = mInputSource;
event.mIgnoreRootScrollFrame = true;
return event;
} }
MultiTouchInput::MultiTouchInput(const WidgetTouchEvent& aTouchEvent) MultiTouchInput::MultiTouchInput(const WidgetTouchEvent& aTouchEvent)
@ -218,6 +140,43 @@ MultiTouchInput::MultiTouchInput(const WidgetTouchEvent& aTouchEvent)
} }
} }
MultiTouchInput::MultiTouchInput(const WidgetMouseEvent& aMouseEvent)
: InputData(MULTITOUCH_INPUT, aMouseEvent.mTime, aMouseEvent.mTimeStamp,
aMouseEvent.mModifiers)
, mHandledByAPZ(aMouseEvent.mFlags.mHandledByAPZ)
{
MOZ_ASSERT(NS_IsMainThread(),
"Can only copy from WidgetMouseEvent on main thread");
switch (aMouseEvent.mMessage) {
case eMouseDown:
mType = MULTITOUCH_START;
break;
case eMouseMove:
mType = MULTITOUCH_MOVE;
break;
case eMouseUp:
mType = MULTITOUCH_END;
break;
// The mouse pointer has been interrupted in an implementation-specific
// manner, such as a synchronous event or action cancelling the touch, or a
// touch point leaving the document window and going into a non-document
// area capable of handling user interactions.
case eMouseExitFromWidget:
mType = MULTITOUCH_CANCEL;
break;
default:
NS_WARNING("Did not assign a type to a MultiTouchInput");
break;
}
mTouches.AppendElement(SingleTouchData(0,
ViewAs<ScreenPixel>(aMouseEvent.mRefPoint,
PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent),
ScreenSize(1, 1),
180.0f,
1.0f));
}
WidgetTouchEvent WidgetTouchEvent
MultiTouchInput::ToWidgetTouchEvent(nsIWidget* aWidget) const MultiTouchInput::ToWidgetTouchEvent(nsIWidget* aWidget) const
{ {
@ -314,49 +273,6 @@ MultiTouchInput::IndexOfTouch(int32_t aTouchIdentifier)
return -1; return -1;
} }
// This conversion from WidgetMouseEvent to MultiTouchInput is needed because on
// the B2G emulator we can only receive mouse events, but we need to be able
// to pan correctly. To do this, we convert the events into a format that the
// panning code can handle. This code is very limited and only supports
// SingleTouchData. It also sends garbage for the identifier, radius, force
// and rotation angle.
MultiTouchInput::MultiTouchInput(const WidgetMouseEvent& aMouseEvent)
: InputData(MULTITOUCH_INPUT, aMouseEvent.mTime, aMouseEvent.mTimeStamp,
aMouseEvent.mModifiers)
, mHandledByAPZ(aMouseEvent.mFlags.mHandledByAPZ)
{
MOZ_ASSERT(NS_IsMainThread(),
"Can only copy from WidgetMouseEvent on main thread");
switch (aMouseEvent.mMessage) {
case eMouseDown:
mType = MULTITOUCH_START;
break;
case eMouseMove:
mType = MULTITOUCH_MOVE;
break;
case eMouseUp:
mType = MULTITOUCH_END;
break;
// The mouse pointer has been interrupted in an implementation-specific
// manner, such as a synchronous event or action cancelling the touch, or a
// touch point leaving the document window and going into a non-document
// area capable of handling user interactions.
case eMouseExitFromWidget:
mType = MULTITOUCH_CANCEL;
break;
default:
NS_WARNING("Did not assign a type to a MultiTouchInput");
break;
}
mTouches.AppendElement(SingleTouchData(0,
ViewAs<ScreenPixel>(aMouseEvent.mRefPoint,
PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent),
ScreenSize(1, 1),
180.0f,
1.0f));
}
bool bool
MultiTouchInput::TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform) MultiTouchInput::TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform)
{ {
@ -370,6 +286,210 @@ MultiTouchInput::TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform
return true; return true;
} }
MouseInput::MouseInput()
: InputData(MOUSE_INPUT)
, mType(MOUSE_NONE)
, mButtonType(NONE)
, mInputSource(0)
, mButtons(0)
, mHandledByAPZ(false)
{
}
MouseInput::MouseInput(MouseType aType, ButtonType aButtonType,
uint16_t aInputSource, int16_t aButtons,
const ScreenPoint& aPoint, uint32_t aTime,
TimeStamp aTimeStamp, Modifiers aModifiers)
: InputData(MOUSE_INPUT, aTime, aTimeStamp, aModifiers)
, mType(aType)
, mButtonType(aButtonType)
, mInputSource(aInputSource)
, mButtons(aButtons)
, mOrigin(aPoint)
, mHandledByAPZ(false)
{
}
MouseInput::MouseInput(const WidgetMouseEventBase& aMouseEvent)
: InputData(MOUSE_INPUT, aMouseEvent.mTime, aMouseEvent.mTimeStamp,
aMouseEvent.mModifiers)
, mType(MOUSE_NONE)
, mButtonType(NONE)
, mInputSource(aMouseEvent.inputSource)
, mButtons(aMouseEvent.buttons)
, mHandledByAPZ(aMouseEvent.mFlags.mHandledByAPZ)
{
MOZ_ASSERT(NS_IsMainThread(),
"Can only copy from WidgetTouchEvent on main thread");
mButtonType = NONE;
switch (aMouseEvent.button) {
case WidgetMouseEventBase::eLeftButton:
mButtonType = MouseInput::LEFT_BUTTON;
break;
case WidgetMouseEventBase::eMiddleButton:
mButtonType = MouseInput::MIDDLE_BUTTON;
break;
case WidgetMouseEventBase::eRightButton:
mButtonType = MouseInput::RIGHT_BUTTON;
break;
}
switch (aMouseEvent.mMessage) {
case eMouseMove:
mType = MOUSE_MOVE;
break;
case eMouseUp:
mType = MOUSE_UP;
break;
case eMouseDown:
mType = MOUSE_DOWN;
break;
case eDragStart:
mType = MOUSE_DRAG_START;
break;
case eDragEnd:
mType = MOUSE_DRAG_END;
break;
case eMouseEnterIntoWidget:
mType = MOUSE_WIDGET_ENTER;
break;
case eMouseExitFromWidget:
mType = MOUSE_WIDGET_EXIT;
break;
default:
MOZ_ASSERT_UNREACHABLE("Mouse event type not supported");
break;
}
mOrigin =
ScreenPoint(ViewAs<ScreenPixel>(aMouseEvent.mRefPoint,
PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent));
}
bool
MouseInput::IsLeftButton() const
{
return mButtonType == LEFT_BUTTON;
}
bool
MouseInput::TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform)
{
Maybe<ParentLayerPoint> point = UntransformBy(aTransform, mOrigin);
if (!point) {
return false;
}
mLocalOrigin = *point;
return true;
}
WidgetMouseEvent
MouseInput::ToWidgetMouseEvent(nsIWidget* aWidget) const
{
MOZ_ASSERT(NS_IsMainThread(),
"Can only convert To WidgetTouchEvent on main thread");
EventMessage msg = eVoidEvent;
uint32_t clickCount = 0;
switch (mType) {
case MOUSE_MOVE:
msg = eMouseMove;
break;
case MOUSE_UP:
msg = eMouseUp;
clickCount = 1;
break;
case MOUSE_DOWN:
msg = eMouseDown;
clickCount = 1;
break;
case MOUSE_DRAG_START:
msg = eDragStart;
break;
case MOUSE_DRAG_END:
msg = eDragEnd;
break;
case MOUSE_WIDGET_ENTER:
msg = eMouseEnterIntoWidget;
break;
case MOUSE_WIDGET_EXIT:
msg = eMouseExitFromWidget;
break;
default:
MOZ_ASSERT_UNREACHABLE("Did not assign a type to WidgetMouseEvent in MouseInput");
break;
}
WidgetMouseEvent event(true, msg, aWidget, WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal);
if (msg == eVoidEvent) {
return event;
}
switch (mButtonType) {
case MouseInput::LEFT_BUTTON:
event.button = WidgetMouseEventBase::eLeftButton;
break;
case MouseInput::MIDDLE_BUTTON:
event.button = WidgetMouseEventBase::eMiddleButton;
break;
case MouseInput::RIGHT_BUTTON:
event.button = WidgetMouseEventBase::eRightButton;
break;
case MouseInput::NONE:
default:
break;
}
event.buttons = mButtons;
event.mModifiers = modifiers;
event.mTime = mTime;
event.mTimeStamp = mTimeStamp;
event.mFlags.mHandledByAPZ = mHandledByAPZ;
event.mRefPoint =
RoundedToInt(ViewAs<LayoutDevicePixel>(mOrigin,
PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent));
event.mClickCount = clickCount;
event.inputSource = mInputSource;
event.mIgnoreRootScrollFrame = true;
return event;
}
PanGestureInput::PanGestureInput()
: InputData(PANGESTURE_INPUT)
, mLineOrPageDeltaX(0)
, mLineOrPageDeltaY(0)
, mUserDeltaMultiplierX(1.0)
, mUserDeltaMultiplierY(1.0)
, mHandledByAPZ(false)
, mFollowedByMomentum(false)
, mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection(false)
{
}
PanGestureInput::PanGestureInput(PanGestureType aType, uint32_t aTime,
TimeStamp aTimeStamp,
const ScreenPoint& aPanStartPoint,
const ScreenPoint& aPanDisplacement,
Modifiers aModifiers)
: InputData(PANGESTURE_INPUT, aTime, aTimeStamp, aModifiers)
, mType(aType)
, mPanStartPoint(aPanStartPoint)
, mPanDisplacement(aPanDisplacement)
, mLineOrPageDeltaX(0)
, mLineOrPageDeltaY(0)
, mUserDeltaMultiplierX(1.0)
, mUserDeltaMultiplierY(1.0)
, mHandledByAPZ(false)
, mFollowedByMomentum(false)
, mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection(false)
{
}
bool bool
PanGestureInput::IsMomentum() const PanGestureInput::IsMomentum() const
{ {
@ -436,6 +556,37 @@ PanGestureInput::UserMultipliedLocalPanDisplacement() const
mLocalPanDisplacement.y * mUserDeltaMultiplierY); mLocalPanDisplacement.y * mUserDeltaMultiplierY);
} }
PinchGestureInput::PinchGestureInput()
: InputData(PINCHGESTURE_INPUT)
{
}
PinchGestureInput::PinchGestureInput(PinchGestureType aType, uint32_t aTime,
TimeStamp aTimeStamp,
const ScreenPoint& aFocusPoint,
float aCurrentSpan, float aPreviousSpan,
Modifiers aModifiers)
: InputData(PINCHGESTURE_INPUT, aTime, aTimeStamp, aModifiers)
, mType(aType)
, mFocusPoint(aFocusPoint)
, mCurrentSpan(aCurrentSpan)
, mPreviousSpan(aPreviousSpan)
{
}
PinchGestureInput::PinchGestureInput(PinchGestureType aType, uint32_t aTime,
TimeStamp aTimeStamp,
const ParentLayerPoint& aLocalFocusPoint,
float aCurrentSpan, float aPreviousSpan,
Modifiers aModifiers)
: InputData(PINCHGESTURE_INPUT, aTime, aTimeStamp, aModifiers)
, mType(aType)
, mLocalFocusPoint(aLocalFocusPoint)
, mCurrentSpan(aCurrentSpan)
, mPreviousSpan(aPreviousSpan)
{
}
bool bool
PinchGestureInput::TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform) PinchGestureInput::TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform)
{ {
@ -447,6 +598,31 @@ PinchGestureInput::TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransfo
return true; return true;
} }
TapGestureInput::TapGestureInput()
: InputData(TAPGESTURE_INPUT)
{
}
TapGestureInput::TapGestureInput(TapGestureType aType, uint32_t aTime,
TimeStamp aTimeStamp,
const ScreenIntPoint& aPoint,
Modifiers aModifiers)
: InputData(TAPGESTURE_INPUT, aTime, aTimeStamp, aModifiers)
, mType(aType)
, mPoint(aPoint)
{
}
TapGestureInput::TapGestureInput(TapGestureType aType, uint32_t aTime,
TimeStamp aTimeStamp,
const ParentLayerPoint& aLocalPoint,
Modifiers aModifiers)
: InputData(TAPGESTURE_INPUT, aTime, aTimeStamp, aModifiers)
, mType(aType)
, mLocalPoint(aLocalPoint)
{
}
bool bool
TapGestureInput::TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform) TapGestureInput::TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform)
{ {
@ -458,24 +634,45 @@ TapGestureInput::TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform
return true; return true;
} }
static uint32_t ScrollWheelInput::ScrollWheelInput()
DeltaModeForDeltaType(ScrollWheelInput::ScrollDeltaType aDeltaType) : InputData(SCROLLWHEEL_INPUT)
, mHandledByAPZ(false)
, mLineOrPageDeltaX(0)
, mLineOrPageDeltaY(0)
, mScrollSeriesNumber(0)
, mUserDeltaMultiplierX(1.0)
, mUserDeltaMultiplierY(1.0)
, mMayHaveMomentum(false)
, mIsMomentum(false)
{
}
ScrollWheelInput::ScrollWheelInput(uint32_t aTime, TimeStamp aTimeStamp,
Modifiers aModifiers, ScrollMode aScrollMode,
ScrollDeltaType aDeltaType,
const ScreenPoint& aOrigin, double aDeltaX,
double aDeltaY,
bool aAllowToOverrideSystemScrollSpeed)
: InputData(SCROLLWHEEL_INPUT, aTime, aTimeStamp, aModifiers)
, mDeltaType(aDeltaType)
, mScrollMode(aScrollMode)
, mOrigin(aOrigin)
, mHandledByAPZ(false)
, mDeltaX(aDeltaX)
, mDeltaY(aDeltaY)
, mLineOrPageDeltaX(0)
, mLineOrPageDeltaY(0)
, mScrollSeriesNumber(0)
, mUserDeltaMultiplierX(1.0)
, mUserDeltaMultiplierY(1.0)
, mMayHaveMomentum(false)
, mIsMomentum(false)
, mAllowToOverrideSystemScrollSpeed(aAllowToOverrideSystemScrollSpeed)
{ {
switch (aDeltaType) {
case ScrollWheelInput::SCROLLDELTA_LINE:
return nsIDOMWheelEvent::DOM_DELTA_LINE;
case ScrollWheelInput::SCROLLDELTA_PAGE:
return nsIDOMWheelEvent::DOM_DELTA_PAGE;
case ScrollWheelInput::SCROLLDELTA_PIXEL:
default:
return nsIDOMWheelEvent::DOM_DELTA_PIXEL;
}
} }
ScrollWheelInput::ScrollWheelInput(const WidgetWheelEvent& aWheelEvent) ScrollWheelInput::ScrollWheelInput(const WidgetWheelEvent& aWheelEvent)
: InputData(SCROLLWHEEL_INPUT, : InputData(SCROLLWHEEL_INPUT, aWheelEvent.mTime, aWheelEvent.mTimeStamp,
aWheelEvent.mTime,
aWheelEvent.mTimeStamp,
aWheelEvent.mModifiers) aWheelEvent.mModifiers)
, mDeltaType(DeltaTypeForDeltaMode(aWheelEvent.mDeltaMode)) , mDeltaType(DeltaTypeForDeltaMode(aWheelEvent.mDeltaMode))
, mScrollMode(SCROLLMODE_INSTANT) , mScrollMode(SCROLLMODE_INSTANT)
@ -497,6 +694,52 @@ ScrollWheelInput::ScrollWheelInput(const WidgetWheelEvent& aWheelEvent)
PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent)); PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent));
} }
ScrollWheelInput::ScrollDeltaType
ScrollWheelInput::DeltaTypeForDeltaMode(uint32_t aDeltaMode)
{
switch (aDeltaMode) {
case nsIDOMWheelEvent::DOM_DELTA_LINE:
return SCROLLDELTA_LINE;
case nsIDOMWheelEvent::DOM_DELTA_PAGE:
return SCROLLDELTA_PAGE;
case nsIDOMWheelEvent::DOM_DELTA_PIXEL:
return SCROLLDELTA_PIXEL;
default:
MOZ_CRASH();
}
return SCROLLDELTA_LINE;
}
uint32_t
ScrollWheelInput::DeltaModeForDeltaType(ScrollDeltaType aDeltaType)
{
switch (aDeltaType) {
case ScrollWheelInput::SCROLLDELTA_LINE:
return nsIDOMWheelEvent::DOM_DELTA_LINE;
case ScrollWheelInput::SCROLLDELTA_PAGE:
return nsIDOMWheelEvent::DOM_DELTA_PAGE;
case ScrollWheelInput::SCROLLDELTA_PIXEL:
default:
return nsIDOMWheelEvent::DOM_DELTA_PIXEL;
}
}
nsIScrollableFrame::ScrollUnit
ScrollWheelInput::ScrollUnitForDeltaType(ScrollDeltaType aDeltaType)
{
switch (aDeltaType) {
case SCROLLDELTA_LINE:
return nsIScrollableFrame::LINES;
case SCROLLDELTA_PAGE:
return nsIScrollableFrame::PAGES;
case SCROLLDELTA_PIXEL:
return nsIScrollableFrame::DEVICE_PIXELS;
default:
MOZ_CRASH();
}
return nsIScrollableFrame::LINES;
}
WidgetWheelEvent WidgetWheelEvent
ScrollWheelInput::ToWidgetWheelEvent(nsIWidget* aWidget) const ScrollWheelInput::ToWidgetWheelEvent(nsIWidget* aWidget) const
{ {

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

@ -94,24 +94,11 @@ public:
INPUTDATA_AS_CHILD_TYPE(TapGestureInput, TAPGESTURE_INPUT) INPUTDATA_AS_CHILD_TYPE(TapGestureInput, TAPGESTURE_INPUT)
INPUTDATA_AS_CHILD_TYPE(ScrollWheelInput, SCROLLWHEEL_INPUT) INPUTDATA_AS_CHILD_TYPE(ScrollWheelInput, SCROLLWHEEL_INPUT)
explicit InputData(InputType aInputType) explicit InputData(InputType aInputType);
: mInputType(aInputType),
mTime(0),
modifiers(0)
{
}
protected: protected:
InputData(InputType aInputType, uint32_t aTime, TimeStamp aTimeStamp, InputData(InputType aInputType, uint32_t aTime, TimeStamp aTimeStamp,
Modifiers aModifiers) Modifiers aModifiers);
: mInputType(aInputType),
mTime(aTime),
mTimeStamp(aTimeStamp),
modifiers(aModifiers)
{
}
}; };
/** /**
@ -138,14 +125,7 @@ public:
ScreenIntPoint aScreenPoint, ScreenIntPoint aScreenPoint,
ScreenSize aRadius, ScreenSize aRadius,
float aRotationAngle, float aRotationAngle,
float aForce) float aForce);
: mIdentifier(aIdentifier),
mScreenPoint(aScreenPoint),
mRadius(aRadius),
mRotationAngle(aRotationAngle),
mForce(aForce)
{
}
// Construct a SingleTouchData from a ParentLayer point. // Construct a SingleTouchData from a ParentLayer point.
// mScreenPoint remains (0,0) unless it's set later. // mScreenPoint remains (0,0) unless it's set later.
@ -155,18 +135,9 @@ public:
ParentLayerPoint aLocalScreenPoint, ParentLayerPoint aLocalScreenPoint,
ScreenSize aRadius, ScreenSize aRadius,
float aRotationAngle, float aRotationAngle,
float aForce) float aForce);
: mIdentifier(aIdentifier),
mLocalScreenPoint(aLocalScreenPoint),
mRadius(aRadius),
mRotationAngle(aRotationAngle),
mForce(aForce)
{
}
SingleTouchData() SingleTouchData();
{
}
already_AddRefed<dom::Touch> ToNewDOMTouch() const; already_AddRefed<dom::Touch> ToNewDOMTouch() const;
@ -225,36 +196,10 @@ public:
}; };
MultiTouchInput(MultiTouchType aType, uint32_t aTime, TimeStamp aTimeStamp, MultiTouchInput(MultiTouchType aType, uint32_t aTime, TimeStamp aTimeStamp,
Modifiers aModifiers) Modifiers aModifiers);
: InputData(MULTITOUCH_INPUT, aTime, aTimeStamp, aModifiers) MultiTouchInput();
, mType(aType) MultiTouchInput(const MultiTouchInput& aOther);
, mHandledByAPZ(false)
{
}
MultiTouchInput()
: InputData(MULTITOUCH_INPUT)
, mHandledByAPZ(false)
{
}
MultiTouchInput(const MultiTouchInput& aOther)
: InputData(MULTITOUCH_INPUT, aOther.mTime,
aOther.mTimeStamp, aOther.modifiers)
, mType(aOther.mType)
, mHandledByAPZ(aOther.mHandledByAPZ)
{
mTouches.AppendElements(aOther.mTouches);
}
explicit MultiTouchInput(const WidgetTouchEvent& aTouchEvent); explicit MultiTouchInput(const WidgetTouchEvent& aTouchEvent);
WidgetTouchEvent ToWidgetTouchEvent(nsIWidget* aWidget) const;
WidgetMouseEvent ToWidgetMouseEvent(nsIWidget* aWidget) const;
// Return the index into mTouches of the SingleTouchData with the given
// identifier, or -1 if there is no such SingleTouchData.
int32_t IndexOfTouch(int32_t aTouchIdentifier);
// This conversion from WidgetMouseEvent to MultiTouchInput is needed because // This conversion from WidgetMouseEvent to MultiTouchInput is needed because
// on the B2G emulator we can only receive mouse events, but we need to be // on the B2G emulator we can only receive mouse events, but we need to be
// able to pan correctly. To do this, we convert the events into a format that // able to pan correctly. To do this, we convert the events into a format that
@ -263,6 +208,13 @@ public:
// and rotation angle. // and rotation angle.
explicit MultiTouchInput(const WidgetMouseEvent& aMouseEvent); explicit MultiTouchInput(const WidgetMouseEvent& aMouseEvent);
WidgetTouchEvent ToWidgetTouchEvent(nsIWidget* aWidget) const;
WidgetMouseEvent ToWidgetMouseEvent(nsIWidget* aWidget) const;
// Return the index into mTouches of the SingleTouchData with the given
// identifier, or -1 if there is no such SingleTouchData.
int32_t IndexOfTouch(int32_t aTouchIdentifier);
bool TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform); bool TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform);
// Warning, this class is serialized and sent over IPC. Any change to its // Warning, this class is serialized and sent over IPC. Any change to its
@ -278,14 +230,7 @@ protected:
friend mozilla::layers::PAPZCTreeManagerParent; friend mozilla::layers::PAPZCTreeManagerParent;
friend mozilla::layers::APZCTreeManagerChild; friend mozilla::layers::APZCTreeManagerChild;
MouseInput() MouseInput();
: InputData(MOUSE_INPUT)
, mType(MOUSE_NONE)
, mButtonType(NONE)
, mInputSource(0)
, mButtons(0)
, mHandledByAPZ(false)
{}
public: public:
enum MouseType enum MouseType
@ -318,20 +263,12 @@ public:
BUTTON_SENTINEL, BUTTON_SENTINEL,
}; };
MouseInput(MouseType aType, ButtonType aButtonType, uint16_t aInputSource, int16_t aButtons, const ScreenPoint& aPoint, MouseInput(MouseType aType, ButtonType aButtonType, uint16_t aInputSource,
uint32_t aTime, TimeStamp aTimeStamp, Modifiers aModifiers) int16_t aButtons, const ScreenPoint& aPoint, uint32_t aTime,
: InputData(MOUSE_INPUT, aTime, aTimeStamp, aModifiers) TimeStamp aTimeStamp, Modifiers aModifiers);
, mType(aType)
, mButtonType(aButtonType)
, mInputSource(aInputSource)
, mButtons(aButtons)
, mOrigin(aPoint)
, mHandledByAPZ(false)
{}
explicit MouseInput(const WidgetMouseEventBase& aMouseEvent); explicit MouseInput(const WidgetMouseEventBase& aMouseEvent);
bool IsLeftButton() const { return mButtonType == LEFT_BUTTON; } bool IsLeftButton() const;
bool TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform); bool TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform);
WidgetMouseEvent ToWidgetMouseEvent(nsIWidget* aWidget) const; WidgetMouseEvent ToWidgetMouseEvent(nsIWidget* aWidget) const;
@ -357,17 +294,7 @@ protected:
friend mozilla::layers::PAPZCTreeManagerParent; friend mozilla::layers::PAPZCTreeManagerParent;
friend mozilla::layers::APZCTreeManagerChild; friend mozilla::layers::APZCTreeManagerChild;
PanGestureInput() PanGestureInput();
: InputData(PANGESTURE_INPUT),
mLineOrPageDeltaX(0),
mLineOrPageDeltaY(0),
mUserDeltaMultiplierX(1.0),
mUserDeltaMultiplierY(1.0),
mHandledByAPZ(false),
mFollowedByMomentum(false),
mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection(false)
{
}
public: public:
enum PanGestureType enum PanGestureType
@ -427,20 +354,7 @@ public:
TimeStamp aTimeStamp, TimeStamp aTimeStamp,
const ScreenPoint& aPanStartPoint, const ScreenPoint& aPanStartPoint,
const ScreenPoint& aPanDisplacement, const ScreenPoint& aPanDisplacement,
Modifiers aModifiers) Modifiers aModifiers);
: InputData(PANGESTURE_INPUT, aTime, aTimeStamp, aModifiers),
mType(aType),
mPanStartPoint(aPanStartPoint),
mPanDisplacement(aPanDisplacement),
mLineOrPageDeltaX(0),
mLineOrPageDeltaY(0),
mUserDeltaMultiplierX(1.0),
mUserDeltaMultiplierY(1.0),
mHandledByAPZ(false),
mFollowedByMomentum(false),
mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection(false)
{
}
bool IsMomentum() const; bool IsMomentum() const;
@ -498,10 +412,7 @@ protected:
friend mozilla::layers::PAPZCTreeManagerParent; friend mozilla::layers::PAPZCTreeManagerParent;
friend mozilla::layers::APZCTreeManagerChild; friend mozilla::layers::APZCTreeManagerChild;
PinchGestureInput() PinchGestureInput();
: InputData(PINCHGESTURE_INPUT)
{
}
public: public:
enum PinchGestureType enum PinchGestureType
@ -518,37 +429,16 @@ public:
// Construct a tap gesture from a Screen point. // Construct a tap gesture from a Screen point.
// mLocalFocusPoint remains (0,0) unless it's set later. // mLocalFocusPoint remains (0,0) unless it's set later.
PinchGestureInput(PinchGestureType aType, PinchGestureInput(PinchGestureType aType, uint32_t aTime,
uint32_t aTime, TimeStamp aTimeStamp, const ScreenPoint& aFocusPoint,
TimeStamp aTimeStamp, float aCurrentSpan, float aPreviousSpan,
const ScreenPoint& aFocusPoint, Modifiers aModifiers);
float aCurrentSpan,
float aPreviousSpan,
Modifiers aModifiers)
: InputData(PINCHGESTURE_INPUT, aTime, aTimeStamp, aModifiers),
mType(aType),
mFocusPoint(aFocusPoint),
mCurrentSpan(aCurrentSpan),
mPreviousSpan(aPreviousSpan)
{
}
// Construct a tap gesture from a ParentLayer point. // Construct a tap gesture from a ParentLayer point.
// mFocusPoint remains (0,0) unless it's set later. // mFocusPoint remains (0,0) unless it's set later.
PinchGestureInput(PinchGestureType aType, PinchGestureInput(PinchGestureType aType, uint32_t aTime, TimeStamp aTimeStamp,
uint32_t aTime, const ParentLayerPoint& aLocalFocusPoint, float aCurrentSpan,
TimeStamp aTimeStamp, float aPreviousSpan, Modifiers aModifiers);
const ParentLayerPoint& aLocalFocusPoint,
float aCurrentSpan,
float aPreviousSpan,
Modifiers aModifiers)
: InputData(PINCHGESTURE_INPUT, aTime, aTimeStamp, aModifiers),
mType(aType),
mLocalFocusPoint(aLocalFocusPoint),
mCurrentSpan(aCurrentSpan),
mPreviousSpan(aPreviousSpan)
{
}
bool TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform); bool TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform);
@ -592,10 +482,7 @@ protected:
friend mozilla::layers::PAPZCTreeManagerParent; friend mozilla::layers::PAPZCTreeManagerParent;
friend mozilla::layers::APZCTreeManagerChild; friend mozilla::layers::APZCTreeManagerChild;
TapGestureInput() TapGestureInput();
: InputData(TAPGESTURE_INPUT)
{
}
public: public:
enum TapGestureType enum TapGestureType
@ -615,29 +502,13 @@ public:
// Construct a tap gesture from a Screen point. // Construct a tap gesture from a Screen point.
// mLocalPoint remains (0,0) unless it's set later. // mLocalPoint remains (0,0) unless it's set later.
TapGestureInput(TapGestureType aType, TapGestureInput(TapGestureType aType, uint32_t aTime, TimeStamp aTimeStamp,
uint32_t aTime, const ScreenIntPoint& aPoint, Modifiers aModifiers);
TimeStamp aTimeStamp,
const ScreenIntPoint& aPoint,
Modifiers aModifiers)
: InputData(TAPGESTURE_INPUT, aTime, aTimeStamp, aModifiers),
mType(aType),
mPoint(aPoint)
{
}
// Construct a tap gesture from a ParentLayer point. // Construct a tap gesture from a ParentLayer point.
// mPoint remains (0,0) unless it's set later. // mPoint remains (0,0) unless it's set later.
TapGestureInput(TapGestureType aType, TapGestureInput(TapGestureType aType, uint32_t aTime, TimeStamp aTimeStamp,
uint32_t aTime, const ParentLayerPoint& aLocalPoint, Modifiers aModifiers);
TimeStamp aTimeStamp,
const ParentLayerPoint& aLocalPoint,
Modifiers aModifiers)
: InputData(TAPGESTURE_INPUT, aTime, aTimeStamp, aModifiers),
mType(aType),
mLocalPoint(aLocalPoint)
{
}
bool TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform); bool TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform);
@ -662,17 +533,7 @@ protected:
friend mozilla::layers::PAPZCTreeManagerParent; friend mozilla::layers::PAPZCTreeManagerParent;
friend mozilla::layers::APZCTreeManagerChild; friend mozilla::layers::APZCTreeManagerChild;
ScrollWheelInput() ScrollWheelInput();
: InputData(SCROLLWHEEL_INPUT)
, mHandledByAPZ(false)
, mLineOrPageDeltaX(0)
, mLineOrPageDeltaY(0)
, mScrollSeriesNumber(0)
, mUserDeltaMultiplierX(1.0)
, mUserDeltaMultiplierY(1.0)
, mMayHaveMomentum(false)
, mIsMomentum(false)
{}
public: public:
enum ScrollDeltaType enum ScrollDeltaType
@ -690,38 +551,6 @@ public:
SCROLLDELTA_SENTINEL, SCROLLDELTA_SENTINEL,
}; };
static ScrollDeltaType
DeltaTypeForDeltaMode(uint32_t aDeltaMode)
{
switch (aDeltaMode) {
case nsIDOMWheelEvent::DOM_DELTA_LINE:
return SCROLLDELTA_LINE;
case nsIDOMWheelEvent::DOM_DELTA_PAGE:
return SCROLLDELTA_PAGE;
case nsIDOMWheelEvent::DOM_DELTA_PIXEL:
return SCROLLDELTA_PIXEL;
default:
MOZ_CRASH();
}
return SCROLLDELTA_LINE;
}
static nsIScrollableFrame::ScrollUnit
ScrollUnitForDeltaType(ScrollDeltaType aDeltaType)
{
switch (aDeltaType) {
case SCROLLDELTA_LINE:
return nsIScrollableFrame::LINES;
case SCROLLDELTA_PAGE:
return nsIScrollableFrame::PAGES;
case SCROLLDELTA_PIXEL:
return nsIScrollableFrame::DEVICE_PIXELS;
default:
MOZ_CRASH();
}
return nsIScrollableFrame::LINES;
}
enum ScrollMode enum ScrollMode
{ {
// Warning, this enum is serialized and sent over IPC. If you reorder, add, // Warning, this enum is serialized and sent over IPC. If you reorder, add,
@ -734,34 +563,16 @@ public:
SCROLLMODE_SENTINEL, SCROLLMODE_SENTINEL,
}; };
ScrollWheelInput(uint32_t aTime, ScrollWheelInput(uint32_t aTime, TimeStamp aTimeStamp, Modifiers aModifiers,
TimeStamp aTimeStamp, ScrollMode aScrollMode, ScrollDeltaType aDeltaType,
Modifiers aModifiers, const ScreenPoint& aOrigin, double aDeltaX, double aDeltaY,
ScrollMode aScrollMode, bool aAllowToOverrideSystemScrollSpeed);
ScrollDeltaType aDeltaType,
const ScreenPoint& aOrigin,
double aDeltaX,
double aDeltaY,
bool aAllowToOverrideSystemScrollSpeed)
: InputData(SCROLLWHEEL_INPUT, aTime, aTimeStamp, aModifiers)
, mDeltaType(aDeltaType)
, mScrollMode(aScrollMode)
, mOrigin(aOrigin)
, mHandledByAPZ(false)
, mDeltaX(aDeltaX)
, mDeltaY(aDeltaY)
, mLineOrPageDeltaX(0)
, mLineOrPageDeltaY(0)
, mScrollSeriesNumber(0)
, mUserDeltaMultiplierX(1.0)
, mUserDeltaMultiplierY(1.0)
, mMayHaveMomentum(false)
, mIsMomentum(false)
, mAllowToOverrideSystemScrollSpeed(aAllowToOverrideSystemScrollSpeed)
{}
explicit ScrollWheelInput(const WidgetWheelEvent& aEvent); explicit ScrollWheelInput(const WidgetWheelEvent& aEvent);
static ScrollDeltaType DeltaTypeForDeltaMode(uint32_t aDeltaMode);
static uint32_t DeltaModeForDeltaType(ScrollDeltaType aDeltaType);
static nsIScrollableFrame::ScrollUnit ScrollUnitForDeltaType(ScrollDeltaType aDeltaType);
WidgetWheelEvent ToWidgetWheelEvent(nsIWidget* aWidget) const; WidgetWheelEvent ToWidgetWheelEvent(nsIWidget* aWidget) const;
bool TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform); bool TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform);