зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to fx-team, a=merge
This commit is contained in:
Коммит
5225afcd1a
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
153
dom/ipc/Blob.cpp
153
dom/ipc/Blob.cpp
|
@ -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);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче