merge mozilla-inbound to mozilla-central. r=merge a=merge

MozReview-Commit-ID: BGCq2q6xO1S
This commit is contained in:
Sebastian Hengst 2017-09-27 11:47:52 +02:00
Родитель 5e148c52b0 d432f7bf8f
Коммит a3b6b15cef
112 изменённых файлов: 1070 добавлений и 1026 удалений

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

@ -601,9 +601,13 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
if (!mDocument)
return;
// Wait until an update, we have started, or an interruptible reflow is
// finished.
if (mObservingState == eRefreshProcessing ||
mObservingState == eRefreshProcessingForUpdate)
mObservingState == eRefreshProcessingForUpdate ||
mPresShell->IsReflowInterrupted()) {
return;
}
// Any generic notifications should be queued if we're processing content
// insertions or generic notifications.

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

@ -87,6 +87,8 @@ RootAccessibleWrap::GetInternalUnknown()
void
RootAccessibleWrap::DocumentActivated(DocAccessible* aDocument)
{
// This check will never work with e10s enabled, in other words, as of
// Firefox 57.
if (Compatibility::IsDolphin() &&
nsCoreUtils::IsTabDocument(aDocument->DocumentNode())) {
uint32_t count = mChildDocuments.Length();

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

@ -5,7 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
pref("startup.homepage_override_url", "");
pref("startup.homepage_welcome_url", "https://www.mozilla.org/%LOCALE%/firefox/%VERSION%/firstrun/");
pref("startup.homepage_welcome_url", "https://www.mozilla.org/%LOCALE%/firefox/%VERSION%a2/firstrun/");
pref("startup.homepage_welcome_url.additional", "");
// The time interval between checks for a new version (in seconds)
pref("app.update.interval", 28800); // 8 hours

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

@ -12,6 +12,10 @@ var Cu = Components.utils;
const DISTRIBUTION_CUSTOMIZATION_COMPLETE_TOPIC =
"distribution-customization-complete";
const PREF_CACHED_FILE_EXISTENCE = "distribution.iniFile.exists.value";
const PREF_CACHED_FILE_APPVERSION = "distribution.iniFile.exists.appversion";
Cu.import("resource://gre/modules/AppConstants.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
@ -20,37 +24,65 @@ XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
"resource://gre/modules/PlacesUtils.jsm");
this.DistributionCustomizer = function DistributionCustomizer() {
// For parallel xpcshell testing purposes allow loading the distribution.ini
// file from the profile folder through an hidden pref.
let loadFromProfile = Services.prefs.getBoolPref("distribution.testing.loadFromProfile", false);
let dirSvc = Cc["@mozilla.org/file/directory_service;1"].
getService(Ci.nsIProperties);
try {
let iniFile = loadFromProfile ? dirSvc.get("ProfD", Ci.nsIFile)
: dirSvc.get("XREAppDist", Ci.nsIFile);
if (loadFromProfile) {
iniFile.leafName = "distribution";
}
iniFile.append("distribution.ini");
if (iniFile.exists())
this._iniFile = iniFile;
} catch (ex) {}
}
DistributionCustomizer.prototype = {
_iniFile: null,
get _iniFile() {
// For parallel xpcshell testing purposes allow loading the distribution.ini
// file from the profile folder through an hidden pref.
let loadFromProfile = Services.prefs.getBoolPref("distribution.testing.loadFromProfile", false);
let dirSvc = Cc["@mozilla.org/file/directory_service;1"].
getService(Ci.nsIProperties);
let iniFile;
try {
iniFile = loadFromProfile ? dirSvc.get("ProfD", Ci.nsIFile)
: dirSvc.get("XREAppDist", Ci.nsIFile);
if (loadFromProfile) {
iniFile.leafName = "distribution";
}
iniFile.append("distribution.ini");
} catch (ex) {}
this.__defineGetter__("_iniFile", () => iniFile);
return iniFile;
},
get _hasDistributionIni() {
if (Services.prefs.prefHasUserValue(PREF_CACHED_FILE_EXISTENCE)) {
let knownForVersion = Services.prefs.getStringPref(PREF_CACHED_FILE_APPVERSION, "unknown");
if (knownForVersion == AppConstants.MOZ_APP_VERSION) {
return Services.prefs.getBoolPref(PREF_CACHED_FILE_EXISTENCE);
}
}
let fileExists = this._iniFile.exists();
Services.prefs.setBoolPref(PREF_CACHED_FILE_EXISTENCE, fileExists);
Services.prefs.setStringPref(PREF_CACHED_FILE_APPVERSION, AppConstants.MOZ_APP_VERSION);
this.__defineGetter__("_hasDistributionIni", () => fileExists);
return fileExists;
},
get _ini() {
let ini = null;
try {
if (this._iniFile) {
if (this._hasDistributionIni) {
ini = Cc["@mozilla.org/xpcom/ini-parser-factory;1"].
getService(Ci.nsIINIParserFactory).
createINIParser(this._iniFile);
}
} catch (e) {
// Unable to parse INI.
Cu.reportError("Unable to parse distribution.ini");
if (e.result == Cr.NS_ERROR_FILE_NOT_FOUND) {
// We probably had cached the file existence as true,
// but it no longer exists. We could set the new cache
// value here, but let's just invalidate the cache and
// let it be cached by a single code path on the next check.
Services.prefs.clearUserPref(PREF_CACHED_FILE_EXISTENCE);
} else {
// Unable to parse INI.
Cu.reportError("Unable to parse distribution.ini");
}
}
this.__defineGetter__("_ini", () => ini);
return this._ini;

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

@ -86,6 +86,7 @@ do_register_cleanup(function() {
distDir.append("distribution");
distDir.remove(true);
Assert.ok(!distDir.exists());
Services.prefs.clearUserPref("distribution.testing.loadFromProfile");
});
add_task(async function() {

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

@ -0,0 +1,118 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that DistributionCustomizer correctly caches the existence
* of the distribution.ini file and just rechecks it after a version
* update.
*/
const PREF_CACHED_FILE_EXISTENCE = "distribution.iniFile.exists.value";
const PREF_CACHED_FILE_APPVERSION = "distribution.iniFile.exists.appversion";
const PREF_LOAD_FROM_PROFILE = "distribution.testing.loadFromProfile";
const gTestDir = do_get_cwd();
Cu.import("resource://gre/modules/AppConstants.jsm");
add_task(async function() {
// Start with a clean slate of the prefs that control this feature.
Services.prefs.clearUserPref(PREF_CACHED_FILE_APPVERSION);
Services.prefs.clearUserPref(PREF_CACHED_FILE_EXISTENCE);
setupTest();
let {DistributionCustomizer} = Cu.import("resource:///modules/distribution.js", {});
let distribution = new DistributionCustomizer();
copyDistributionToProfile();
// Check that checking for distribution.ini returns the right value and sets up
// the cached prefs.
let exists = distribution._hasDistributionIni;
Assert.ok(exists);
Assert.equal(Services.prefs.getBoolPref(PREF_CACHED_FILE_EXISTENCE, undefined),
true);
Assert.equal(Services.prefs.getStringPref(PREF_CACHED_FILE_APPVERSION, "unknown"),
AppConstants.MOZ_APP_VERSION);
// Check that calling _hasDistributionIni again will use the cached value. We do
// this by deleting the file and expecting it to still return true instead of false.
// Also, we need to delete _hasDistributionIni from the object because the getter
// was replaced with a stored value.
deleteDistribution();
delete distribution._hasDistributionIni;
exists = distribution._hasDistributionIni;
Assert.ok(exists);
// Now let's invalidate the PREF_CACHED_FILE_EXISTENCE pref to make sure the
// value gets recomputed correctly.
Services.prefs.clearUserPref(PREF_CACHED_FILE_EXISTENCE);
delete distribution._hasDistributionIni;
exists = distribution._hasDistributionIni;
// It now should return false, as well as storing false in the pref.
Assert.ok(!exists);
Assert.equal(Services.prefs.getBoolPref(PREF_CACHED_FILE_EXISTENCE, undefined),
false);
// Check now that it will use the new cached value instead of returning true in
// the presence of the file.
copyDistributionToProfile();
delete distribution._hasDistributionIni;
exists = distribution._hasDistributionIni;
Assert.ok(!exists);
// Now let's do the same, but invalidating the App Version, as if a version
// update occurred.
Services.prefs.setStringPref(PREF_CACHED_FILE_APPVERSION, "older version");
delete distribution._hasDistributionIni;
exists = distribution._hasDistributionIni;
Assert.ok(exists);
Assert.equal(Services.prefs.getBoolPref(PREF_CACHED_FILE_EXISTENCE, undefined),
true);
Assert.equal(Services.prefs.getStringPref(PREF_CACHED_FILE_APPVERSION, "unknown"),
AppConstants.MOZ_APP_VERSION);
});
/*
* Helper functions
*/
function copyDistributionToProfile() {
// Copy distribution.ini file to the profile dir.
let distroDir = gProfD.clone();
distroDir.leafName = "distribution";
let iniFile = distroDir.clone();
iniFile.append("distribution.ini");
if (iniFile.exists()) {
iniFile.remove(false);
print("distribution.ini already exists, did some test forget to cleanup?");
}
let testDistributionFile = gTestDir.clone();
testDistributionFile.append("distribution.ini");
testDistributionFile.copyTo(distroDir, "distribution.ini");
Assert.ok(testDistributionFile.exists());
}
function deleteDistribution() {
let distroDir = gProfD.clone();
distroDir.leafName = "distribution";
let iniFile = distroDir.clone();
iniFile.append("distribution.ini");
iniFile.remove(false);
}
function setupTest() {
// Set special pref to load distribution.ini from the profile folder.
Services.prefs.setBoolPref(PREF_LOAD_FROM_PROFILE, true);
}
do_register_cleanup(function() {
deleteDistribution();
Services.prefs.clearUserPref(PREF_LOAD_FROM_PROFILE);
});

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

@ -6,5 +6,6 @@ support-files =
distribution.ini
data/engine-de-DE.xml
[test_distribution.js]
[test_browserGlue_migration_loop_cleanup.js]
[test_distribution.js]
[test_distribution_cachedexistence.js]

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

@ -175,7 +175,7 @@ PluginContent.prototype = {
},
_getPluginInfo(pluginElement) {
if (pluginElement instanceof Ci.nsIDOMHTMLAnchorElement) {
if (ChromeUtils.getClassName(pluginElement) === "HTMLAnchorElement") {
// Anchor elements are our place holders, and we only have them for Flash
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
return {
@ -649,7 +649,7 @@ PluginContent.prototype = {
let doc = plugin.ownerDocument;
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
let permissionString;
if (plugin instanceof Ci.nsIDOMHTMLAnchorElement) {
if (ChromeUtils.getClassName(plugin) === "HTMLAnchorElement") {
// We only have replacement content for Flash installs
permissionString = pluginHost.getPermissionStringForType(FLASH_MIME_TYPE);
} else {
@ -681,10 +681,9 @@ PluginContent.prototype = {
onOverlayClick(event) {
let document = event.target.ownerDocument;
let plugin = document.getBindingParent(event.target);
let contentWindow = plugin.ownerGlobal.top;
let overlay = this.getPluginUI(plugin, "main");
// Have to check that the target is not the link to update the plugin
if (!(event.originalTarget instanceof contentWindow.HTMLAnchorElement) &&
if (!(ChromeUtils.getClassName(event.originalTarget) === "HTMLAnchorElement") &&
(event.originalTarget.getAttribute("anonid") != "closeIcon") &&
!overlay.hasAttribute("dismissed") &&
event.button == 0 &&
@ -730,7 +729,7 @@ PluginContent.prototype = {
}
if (pluginInfo.permissionString == pluginHost.getPermissionStringForType(plugin.actualType)) {
let overlay = this.getPluginUI(plugin, "main");
if (plugin instanceof Ci.nsIDOMHTMLAnchorElement) {
if (ChromeUtils.getClassName(plugin) === "HTMLAnchorElement") {
placeHolderFound = true;
} else {
pluginFound = true;

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

@ -39,8 +39,6 @@
const Services = require("Services");
const DEFAULT_HTTP_VERSION = "HTTP/1.1";
const Curl = {
/**
* Generates a cURL command string which can be used from the command line etc.
@ -106,11 +104,6 @@ const Curl = {
command.push("-I");
}
// Add http version.
if (data.httpVersion && data.httpVersion != DEFAULT_HTTP_VERSION) {
command.push("--" + data.httpVersion.split("/")[1]);
}
// Add request headers.
let headers = data.headers;
if (multipartRequest) {

1
devtools/client/shared/vendor/WasmDis.js поставляемый
Просмотреть файл

@ -747,4 +747,3 @@ var WasmDisassembler = (function () {
return WasmDisassembler;
}());
exports.WasmDisassembler = WasmDisassembler;
//# sourceMappingURL=WasmDis.js.map

1
devtools/client/shared/vendor/WasmParser.js поставляемый
Просмотреть файл

@ -1400,4 +1400,3 @@ if (!exports.bytesToString) {
return decodeURIComponent(escape(str));
};
}
//# sourceMappingURL=WasmParser.js.map

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

@ -77,80 +77,79 @@ ObjectActor.prototype = {
* Returns a grip for this actor for returning in a protocol message.
*/
grip: function () {
this.hooks.incrementGripDepth();
let g = {
"type": "object",
"actor": this.actorID
};
// If it's a proxy, lie and tell that it belongs to an invented "Proxy" class.
// The `isProxy` function detects them even behind non-opaque security wrappers,
// which is useful to avoid running proxy traps through transparent wrappers.
if (isProxy(this.obj)) {
// Check if the object has a wrapper which denies access. It may be a CPOW or a
// security wrapper. Change the class so that this will be visible in the UI.
let unwrapped = unwrap(this.obj);
if (!unwrapped) {
if (DevToolsUtils.isCPOW(this.obj)) {
g.class = "CPOW: " + g.class;
} else {
g.class = "Inaccessible";
}
return g;
}
// Dead objects also deny access.
if (this.obj.class == "DeadObject") {
g.class = "DeadObject";
return g;
}
// Otherwise, increment grip depth and attempt to create a preview.
this.hooks.incrementGripDepth();
// The `isProxy` getter is called on `unwrapped` instead of `this.obj` in order
// to detect proxies behind transparent wrappers, and thus avoid running traps.
if (unwrapped.isProxy) {
g.class = "Proxy";
} else {
try {
g.class = this.obj.class;
g.extensible = this.obj.isExtensible();
g.frozen = this.obj.isFrozen();
g.sealed = this.obj.isSealed();
} catch (e) {
// Handle cases where the underlying object's calls to isExtensible, etc throw.
// This is possible with ProxyObjects like CPOWs. Note these are different from
// scripted Proxies created via `new Proxy`, which match isProxy(this.obj) above.
}
g.class = this.obj.class;
g.extensible = this.obj.isExtensible();
g.frozen = this.obj.isFrozen();
g.sealed = this.obj.isSealed();
}
// Changing the class so that CPOWs will be visible in the UI
let isCPOW = DevToolsUtils.isCPOW(this.obj);
if (isCPOW) {
g.class = "CPOW: " + g.class;
if (g.class == "Promise") {
g.promiseState = this._createPromiseState();
}
if (g.class != "DeadObject" && !isCPOW) {
if (g.class == "Promise") {
g.promiseState = this._createPromiseState();
}
// FF40+: Allow to know how many properties an object has to lazily display them
// when there is a bunch.
if (TYPED_ARRAY_CLASSES.indexOf(g.class) != -1) {
// Bug 1348761: getOwnPropertyNames is unnecessary slow on TypedArrays
let length = DevToolsUtils.getProperty(this.obj, "length");
g.ownPropertyLength = length;
} else if (g.class != "Proxy") {
g.ownPropertyLength = this.obj.getOwnPropertyNames().length;
}
// FF40+: Allow to know how many properties an object has
// to lazily display them when there is a bunch.
// Throws on some MouseEvent object in tests.
let raw = this.obj.unsafeDereference();
// If Cu is not defined, we are running on a worker thread, where xrays
// don't exist.
if (Cu) {
raw = Cu.unwaiveXrays(raw);
}
if (!DevToolsUtils.isSafeJSObject(raw)) {
raw = null;
}
let previewers = DebuggerServer.ObjectActorPreviewers[g.class] ||
DebuggerServer.ObjectActorPreviewers.Object;
for (let fn of previewers) {
try {
if (TYPED_ARRAY_CLASSES.indexOf(g.class) != -1) {
// Bug 1348761: getOwnPropertyNames is unecessary slow on TypedArrays
let length = DevToolsUtils.getProperty(this.obj, "length");
g.ownPropertyLength = length;
} else if (g.class != "Proxy") {
g.ownPropertyLength = this.obj.getOwnPropertyNames().length;
if (fn(this, g, raw)) {
break;
}
} catch (e) {
// ignored
}
let raw = this.obj.unsafeDereference();
// If Cu is not defined, we are running on a worker thread, where xrays
// don't exist.
if (Cu) {
raw = Cu.unwaiveXrays(raw);
}
if (!DevToolsUtils.isSafeJSObject(raw)) {
raw = null;
}
let previewers = DebuggerServer.ObjectActorPreviewers[g.class] ||
DebuggerServer.ObjectActorPreviewers.Object;
for (let fn of previewers) {
try {
if (fn(this, g, raw)) {
break;
}
} catch (e) {
let msg = "ObjectActor.prototype.grip previewer function";
DevToolsUtils.reportException(msg, e);
}
let msg = "ObjectActor.prototype.grip previewer function";
DevToolsUtils.reportException(msg, e);
}
}
@ -290,20 +289,20 @@ ObjectActor.prototype = {
onPrototypeAndProperties: function () {
let ownProperties = Object.create(null);
let ownSymbols = [];
let names;
let symbols;
try {
names = this.obj.getOwnPropertyNames();
symbols = this.obj.getOwnPropertySymbols();
} catch (ex) {
// The above can throw if this.obj points to a dead object.
// TODO: we should use Cu.isDeadWrapper() - see bug 885800.
// Inaccessible, proxy and dead objects should not be accessed.
let unwrapped = unwrap(this.obj);
if (!unwrapped || unwrapped.isProxy || this.obj.class == "DeadObject") {
return { from: this.actorID,
prototype: this.hooks.createValueGrip(null),
ownProperties,
ownSymbols,
safeGetterValues: Object.create(null) };
}
let names = this.obj.getOwnPropertyNames();
let symbols = this.obj.getOwnPropertySymbols();
for (let name of names) {
ownProperties[name] = this._propertyDescriptor(name);
}
@ -340,8 +339,9 @@ ObjectActor.prototype = {
let obj = this.obj;
let level = 0, i = 0;
// Do not search safe getters in proxy objects.
if (isProxy(obj)) {
// Do not search safe getters in inaccessible nor proxy objects.
let unwrapped = unwrap(obj);
if (!unwrapped || unwrapped.isProxy) {
return safeGetterValues;
}
@ -355,8 +355,13 @@ ObjectActor.prototype = {
level++;
}
// Stop iterating when the prototype chain ends or a proxy is found.
while (obj && !isProxy(obj)) {
while (obj) {
// Stop iterating when an inaccessible or a proxy object is found.
unwrapped = unwrap(obj);
if (!unwrapped || unwrapped.isProxy) {
break;
}
let getters = this._findSafeGetters(obj);
for (let name of getters) {
// Avoid overwriting properties from prototypes closer to this.obj. Also
@ -2455,38 +2460,33 @@ function arrayBufferGrip(buffer, pool) {
}
/**
* Determines whether the referent of a debuggee object is a scripted proxy.
* Non-opaque security wrappers are unwrapped first before the check.
* Removes all the non-opaque security wrappers of a debuggee object.
* Returns null if some wrapper can't be removed.
*
* @param obj Debugger.Object
* The debuggee object to be checked.
* The debuggee object to be unwrapped.
*/
function isProxy(obj) {
// Check if the object is a proxy without security wrappers.
if (obj.isProxy) {
return true;
}
// No need to remove opaque wrappers since they prevent proxy traps from running.
function unwrap(obj) {
// Check if `obj` has an opaque wrapper.
if (obj.class === "Opaque") {
return false;
return obj;
}
// Attempt to unwrap. If the debugger can't unwrap, then proxy traps won't be
// allowed to run either, so the object can be safely assumed to not be a proxy.
// Attempt to unwrap. If this operation is not allowed, it may return null or throw.
let unwrapped;
try {
unwrapped = obj.unwrap();
} catch (err) {
return false;
unwrapped = null;
}
// Check if further unwrapping is not possible.
if (!unwrapped || unwrapped === obj) {
return false;
return unwrapped;
}
// Recursively check whether the unwrapped object is a proxy.
return isProxy(unwrapped);
// Recursively remove additional security wrappers.
return unwrap(unwrapped);
}
exports.ObjectActor = ObjectActor;

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

@ -167,7 +167,7 @@ var DebuggerServer = {
* window (i.e the global style editor). Set this to your main window type,
* for example "navigator:browser".
*/
chromeWindowType: null,
chromeWindowType: "navigator:browser",
/**
* Allow debugging chrome of (parent or child) processes.
@ -266,11 +266,13 @@ var DebuggerServer = {
* actors to retrieve them.
*/
registerActors({ root = true, browser = true, tab = true,
windowType = "navigator:browser" }) {
this.chromeWindowType = windowType;
windowType = null }) {
if (windowType) {
this.chromeWindowType = windowType;
}
if (browser) {
this.addBrowserActors(windowType);
this.addBrowserActors(this.chromeWindowType);
}
if (root) {
@ -420,8 +422,10 @@ var DebuggerServer = {
* restrictPrivileges=true, to prevent exposing them on b2g parent process's
* root actor.
*/
addBrowserActors(windowType = "navigator:browser", restrictPrivileges = false) {
this.chromeWindowType = windowType;
addBrowserActors(windowType = null, restrictPrivileges = false) {
if (windowType) {
this.chromeWindowType = windowType;
}
this.registerModule("devtools/server/actors/webbrowser");
if (!restrictPrivileges) {

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

@ -6,10 +6,13 @@
var gServer;
var gDebuggee;
var gDebuggeeHasXrays;
var gClient;
var gThreadClient;
var gGlobal;
var gHasXrays;
var gGlobalIsInvisible;
var gSubsumes;
var gIsOpaque;
function run_test() {
run_test_with_server(DebuggerServer, function () {
@ -31,63 +34,95 @@ async function run_test_with_server(server, callback) {
callback();
}
async function run_tests_in_principal(principal, title) {
// Prepare the debuggee.
gDebuggee = Cu.Sandbox(principal);
gDebuggee.__name = title;
gServer.addTestGlobal(gDebuggee);
gDebuggee.eval(function stopMe(arg1, arg2) {
debugger;
}.toString());
gClient = new DebuggerClient(gServer.connectPipe());
await gClient.connect();
const [,, threadClient] = await attachTestTabAndResume(gClient, title);
gThreadClient = threadClient;
async function run_tests_in_principal(debuggeePrincipal, title) {
for (gDebuggeeHasXrays of [true, false]) {
// Prepare the debuggee.
let fullTitle = gDebuggeeHasXrays ? title + "-with-xrays" : title;
gDebuggee = Cu.Sandbox(debuggeePrincipal, {wantXrays: gDebuggeeHasXrays});
gDebuggee.__name = fullTitle;
gServer.addTestGlobal(gDebuggee);
gDebuggee.eval(function stopMe() {
debugger;
}.toString());
gClient = new DebuggerClient(gServer.connectPipe());
await gClient.connect();
const [,, threadClient] = await attachTestTabAndResume(gClient, fullTitle);
gThreadClient = threadClient;
// Test objects created in the debuggee.
await testPrincipal(undefined, false);
// Test objects created in the debuggee.
await testPrincipal(undefined);
// Test objects created in a new system principal with Xrays.
await testPrincipal(systemPrincipal, true);
// Test objects created in a system principal new global.
await testPrincipal(systemPrincipal);
// Test objects created in a new system principal without Xrays.
await testPrincipal(systemPrincipal, false);
// Test objects created in a cross-origin null principal new global.
await testPrincipal(null);
// Test objects created in a new null principal with Xrays.
await testPrincipal(null, true);
if (debuggeePrincipal === null) {
// Test objects created in a same-origin null principal new global.
await testPrincipal(Cu.getObjectPrincipal(gDebuggee));
}
// Test objects created in a new null principal without Xrays.
await testPrincipal(null, false);
// Finish.
await gClient.close();
// Finish.
await gClient.close();
}
}
function testPrincipal(principal, wantXrays = true) {
async function testPrincipal(globalPrincipal) {
// Create a global object with the specified security principal.
// If none is specified, use the debuggee.
if (principal !== undefined) {
gGlobal = Cu.Sandbox(principal, {wantXrays});
gHasXrays = wantXrays;
} else {
if (globalPrincipal === undefined) {
gGlobal = gDebuggee;
gHasXrays = false;
gSubsumes = true;
gIsOpaque = false;
gGlobalIsInvisible = false;
await test();
return;
}
let debuggeePrincipal = Cu.getObjectPrincipal(gDebuggee);
let sameOrigin = debuggeePrincipal === globalPrincipal;
gSubsumes = sameOrigin || debuggeePrincipal === systemPrincipal;
for (let globalHasXrays of [true, false]) {
gIsOpaque = gSubsumes && globalPrincipal !== systemPrincipal
&& (sameOrigin && gDebuggeeHasXrays || globalHasXrays);
for (gGlobalIsInvisible of [true, false]) {
gGlobal = Cu.Sandbox(globalPrincipal, {
wantXrays: globalHasXrays,
invisibleToDebugger: gGlobalIsInvisible
});
await test();
}
}
}
function test() {
return new Promise(function (resolve) {
gThreadClient.addOneTimeListener("paused", async function (event, packet) {
// Get the grips.
let [proxyGrip, inheritsProxyGrip] = packet.frame.arguments;
let [proxyGrip, inheritsProxyGrip, inheritsProxy2Grip] = packet.frame.arguments;
// Check the grip of the proxy object.
check_proxy_grip(proxyGrip);
// Retrieve the properties of the object which inherits from a proxy,
// and check the grip of its prototype.
let objClient = gThreadClient.pauseGrip(inheritsProxyGrip);
let response = await objClient.getPrototypeAndProperties();
check_properties(response.ownProperties);
check_prototype(response.prototype);
// Check the prototype and properties of the proxy object.
let proxyClient = gThreadClient.pauseGrip(proxyGrip);
let proxyResponse = await proxyClient.getPrototypeAndProperties();
check_properties(proxyResponse.ownProperties, true, false);
check_prototype(proxyResponse.prototype, true, false);
// Check the prototype and properties of the object which inherits from the proxy.
let inheritsProxyClient = gThreadClient.pauseGrip(inheritsProxyGrip);
let inheritsProxyResponse = await inheritsProxyClient.getPrototypeAndProperties();
check_properties(inheritsProxyResponse.ownProperties, false, false);
check_prototype(inheritsProxyResponse.prototype, false, false);
// The prototype chain was not iterated if the object was inaccessible, so now check
// another object which inherits from the proxy, but was created in the debuggee.
let inheritsProxy2Client = gThreadClient.pauseGrip(inheritsProxy2Grip);
let inheritsProxy2Response = await inheritsProxy2Client.getPrototypeAndProperties();
check_properties(inheritsProxy2Response.ownProperties, false, true);
check_prototype(inheritsProxy2Response.prototype, false, true);
// Check that none of the above ran proxy traps.
strictEqual(gGlobal.trapDidRun, false, "No proxy trap did run.");
@ -105,24 +140,21 @@ function testPrincipal(principal, wantXrays = true) {
gGlobal.eval(`
var trapDidRun = false;
var proxy = new Proxy({}, new Proxy({}, {get: (_, trap) => {
return function(_, arg) {
trapDidRun = true;
throw new Error("proxy trap '" + trap + "' was called.");
}
trapDidRun = true;
throw new Error("proxy trap '" + trap + "' was called.");
}}));
var inheritsProxy = Object.create(proxy, {x:{value:1}});
`);
let data = Cu.createObjectIn(gDebuggee, {defineAs: "data"});
data.proxy = gGlobal.proxy;
data.inheritsProxy = gGlobal.inheritsProxy;
gDebuggee.eval("stopMe(data.proxy, data.inheritsProxy);");
gDebuggee.eval(`
var inheritsProxy2 = Object.create(data.proxy, {x:{value:1}});
stopMe(data.proxy, data.inheritsProxy, inheritsProxy2);
`);
});
}
function isSystemPrincipal(obj) {
return Cu.getObjectPrincipal(obj) === systemPrincipal;
}
function check_proxy_grip(grip) {
const {preview} = grip;
@ -136,11 +168,11 @@ function check_proxy_grip(grip) {
strictEqual(target, grip.proxyTarget, "<target> contains the [[ProxyTarget]].");
let handler = preview.ownProperties["<handler>"].value;
strictEqual(handler, grip.proxyHandler, "<handler> contains the [[ProxyHandler]].");
} else if (!isSystemPrincipal(gDebuggee)) {
// The debuggee is not allowed to remove the security wrappers.
strictEqual(grip.class, "Object", "The grip has an Object class.");
ok(!("ownPropertyLength" in grip), "The grip doesn't know the number of properties.");
} else if (!gHasXrays || isSystemPrincipal(gGlobal)) {
} else if (gIsOpaque) {
// The proxy has opaque security wrappers.
strictEqual(grip.class, "Opaque", "The grip has an Opaque class.");
strictEqual(grip.ownPropertyLength, 0, "The grip has no properties.");
} else if (gSubsumes && !gGlobalIsInvisible) {
// The proxy has non-opaque security wrappers.
strictEqual(grip.class, "Proxy", "The grip has a Proxy class.");
ok(!("proxyTarget" in grip), "There is no [[ProxyTarget]] grip.");
@ -149,37 +181,40 @@ function check_proxy_grip(grip) {
ok(!("<target>" in preview), "The preview has no <target> property.");
ok(!("<handler>" in preview), "The preview has no <handler> property.");
} else {
// The proxy has opaque security wrappers.
strictEqual(grip.class, "Opaque", "The grip has an Opaque class.");
strictEqual(grip.ownPropertyLength, 0, "The grip has no properties.");
// The debuggee is not allowed to remove the security wrappers.
strictEqual(grip.class, "Inaccessible", "The grip has an Inaccessible class.");
ok(!("ownPropertyLength" in grip), "The grip doesn't know the number of properties.");
}
}
function check_properties(props) {
function check_properties(props, isProxy, createdInDebuggee) {
let ownPropertiesLength = Reflect.ownKeys(props).length;
if (!isSystemPrincipal(gDebuggee) && gDebuggee !== gGlobal) {
// The debuggee is not allowed to access the object.
strictEqual(ownPropertiesLength, 0, "No own property could be retrieved.");
} else {
if (createdInDebuggee || !isProxy && gSubsumes && !gGlobalIsInvisible) {
// The debuggee can access the properties.
strictEqual(ownPropertiesLength, 1, "1 own property was retrieved.");
strictEqual(props.x.value, 1, "The property has the right value.");
} else {
// The debuggee is not allowed to access the object.
strictEqual(ownPropertiesLength, 0, "No own property could be retrieved.");
}
}
function check_prototype(proto) {
if (!isSystemPrincipal(gDebuggee) && gDebuggee !== gGlobal) {
// The debuggee is not allowed to access the object. It sees a null prototype.
strictEqual(proto.type, "null", "The prototype is null.");
} else if (!gHasXrays || isSystemPrincipal(gGlobal)) {
// The object has no security wrappers or non-opaque ones.
function check_prototype(proto, isProxy, createdInDebuggee) {
if (gIsOpaque && !gGlobalIsInvisible && !createdInDebuggee) {
// The object is or inherits from a proxy with opaque security wrappers.
// The debuggee sees `Object.prototype` when retrieving the prototype.
strictEqual(proto.class, "Object", "The prototype has a Object class.");
} else if (isProxy && gIsOpaque && gGlobalIsInvisible) {
// The object is a proxy with opaque security wrappers in an invisible global.
// The debuggee sees an inaccessible `Object.prototype` when retrieving the prototype.
strictEqual(proto.class, "Inaccessible", "The prototype has an Inaccessible class.");
} else if (createdInDebuggee || !isProxy && gSubsumes && !gGlobalIsInvisible) {
// The object inherits from a proxy and has no security wrappers or non-opaque ones.
// The debuggee sees the proxy when retrieving the prototype.
check_proxy_grip(proto);
} else {
// The object has opaque security wrappers.
// The debuggee sees `Object.prototype` when retrieving the prototype.
strictEqual(proto.class, "Object", "The prototype has a Object class.");
// The debuggee is not allowed to access the object. It sees a null prototype.
strictEqual(proto.type, "null", "The prototype is null.");
}
}

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

@ -149,7 +149,7 @@ function doConsoleCalls(aState)
{
type: "object",
actor: /[a-z]/,
class: "Object",
class: "Inaccessible",
},
],
},

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

@ -12,10 +12,7 @@
#include "nsIDOMHTMLDocument.h"
#include "nsIDOMHTMLElement.h"
#include "nsIDOMHTMLHtmlElement.h"
#include "nsIDOMHTMLAnchorElement.h"
#include "nsIDOMHTMLImageElement.h"
#include "nsIDOMHTMLAreaElement.h"
#include "nsIDOMHTMLLinkElement.h"
#include "nsIDOMWindow.h"
#include "nsICSSDeclaration.h"
#include "nsIDOMCSSValue.h"
@ -27,7 +24,13 @@
#include "nsIContentSecurityPolicy.h"
#include "nsIContentPolicy.h"
#include "imgRequestProxy.h"
#include "mozilla/dom/HTMLAnchorElement.h"
#include "mozilla/dom/HTMLAreaElement.h"
#include "mozilla/dom/HTMLLinkElement.h"
using mozilla::dom::HTMLAnchorElement;
using mozilla::dom::HTMLAreaElement;
using mozilla::dom::HTMLLinkElement;
using mozilla::dom::Element;
using mozilla::ErrorResult;
@ -63,30 +66,24 @@ nsContextMenuInfo::GetAssociatedLink(nsAString& aHRef)
NS_ENSURE_STATE(mAssociatedLink);
aHRef.Truncate(0);
nsCOMPtr<nsIDOMElement> content(do_QueryInterface(mAssociatedLink));
nsAutoString localName;
if (content) {
content->GetLocalName(localName);
}
nsCOMPtr<nsIDOMElement> linkContent;
ToLowerCase(localName);
if (localName.EqualsLiteral("a") ||
localName.EqualsLiteral("area") ||
localName.EqualsLiteral("link")) {
bool hasAttr;
content->HasAttribute(NS_LITERAL_STRING("href"), &hasAttr);
nsCOMPtr<nsIContent> content(do_QueryInterface(mAssociatedLink));
nsCOMPtr<nsIContent> linkContent;
if (content &&
content->IsAnyOfHTMLElements(nsGkAtoms::a,
nsGkAtoms::area,
nsGkAtoms::link)) {
bool hasAttr = content->HasAttr(kNameSpaceID_None, nsGkAtoms::href);
if (hasAttr) {
linkContent = content;
nsCOMPtr<nsIDOMHTMLAnchorElement> anchor(do_QueryInterface(linkContent));
RefPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::FromContent(linkContent);
if (anchor) {
anchor->GetHref(aHRef);
} else {
nsCOMPtr<nsIDOMHTMLAreaElement> area(do_QueryInterface(linkContent));
RefPtr<HTMLAreaElement> area = HTMLAreaElement::FromContent(linkContent);
if (area) {
area->GetHref(aHRef);
} else {
nsCOMPtr<nsIDOMHTMLLinkElement> link(do_QueryInterface(linkContent));
RefPtr<HTMLLinkElement> link = HTMLLinkElement::FromContent(linkContent);
if (link) {
link->GetHref(aHRef);
}
@ -101,15 +98,12 @@ nsContextMenuInfo::GetAssociatedLink(nsAString& aHRef)
if (!content) {
break;
}
content->GetLocalName(localName);
ToLowerCase(localName);
if (localName.EqualsLiteral("a")) {
if (content->IsHTMLElement(nsGkAtoms::a)) {
bool hasAttr;
content->HasAttribute(NS_LITERAL_STRING("href"), &hasAttr);
hasAttr = content->HasAttr(kNameSpaceID_None, nsGkAtoms::href);
if (hasAttr) {
linkContent = content;
nsCOMPtr<nsIDOMHTMLAnchorElement> anchor(
do_QueryInterface(linkContent));
RefPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::FromContent(linkContent);
if (anchor) {
anchor->GetHref(aHRef);
}

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

@ -135,7 +135,6 @@
#include "nsStreamUtils.h"
#include "nsIController.h"
#include "nsPICommandUpdater.h"
#include "nsIDOMHTMLAnchorElement.h"
#include "nsIWebBrowserChrome3.h"
#include "nsITabChild.h"
#include "nsISiteSecurityService.h"
@ -14435,7 +14434,7 @@ nsDocShell::OnLinkClickSync(nsIContent* aContent,
// If this is an anchor element, grab its type property to use as a hint
nsAutoString typeHint;
nsCOMPtr<nsIDOMHTMLAnchorElement> anchor(do_QueryInterface(aContent));
RefPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::FromContent(aContent);
if (anchor) {
anchor->GetType(typeHint);
NS_ConvertUTF16toUTF8 utf8Hint(typeHint);

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

@ -22,44 +22,6 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AbortController)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
/* static */ bool
AbortController::IsEnabled(JSContext* aCx, JSObject* aGlobal)
{
if (NS_IsMainThread()) {
return Preferences::GetBool("dom.abortController.enabled", false);
}
using namespace workers;
// Otherwise, check the pref via the WorkerPrivate
WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(aCx);
if (!workerPrivate) {
return false;
}
return workerPrivate->AbortControllerEnabled();
}
/* static */ bool
AbortController::IsEnabledInFetch(JSContext* aCx, JSObject* aGlobal)
{
if (NS_IsMainThread()) {
return IsEnabled(aCx, aGlobal) &&
Preferences::GetBool("dom.abortController.fetch.enabled", false);
}
using namespace workers;
// Otherwise, check the pref via the WorkerPrivate
WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(aCx);
if (!workerPrivate) {
return false;
}
return workerPrivate->AbortControllerEnabled() &&
workerPrivate->AbortControllerEnabledInFetch();
}
/* static */ already_AddRefed<AbortController>
AbortController::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
{

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

@ -26,12 +26,6 @@ public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(AbortController)
static bool
IsEnabled(JSContext* aCx, JSObject* aGlobal);
static bool
IsEnabledInFetch(JSContext* aCx, JSObject* aGlobal);
static already_AddRefed<AbortController>
Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);

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

@ -1,65 +0,0 @@
<script>
function ok(a, msg) {
parent.postMessage({ type: "check", status: !!a, message: msg }, "*");
}
function is(a, b, msg) {
ok(a === b, msg);
}
function testWebIDL() {
ok("AbortController" in self, "We have a AbortController prototype");
ok("AbortSignal" in self, "We have a AbortSignal prototype");
var ac = new AbortController();
ok(!!ac, "AbortController can be created");
ok(ac instanceof AbortController, "AbortController is a AbortController");
ok(!!ac.signal, "AbortController has a signal");
ok(ac.signal instanceof AbortSignal, "abortSignal is a AbortSignal");
is(ac.signal.aborted, false, "By default AbortSignal.aborted is false");
next();
}
function testUpdateData() {
var ac = new AbortController();
is(ac.signal.aborted, false, "By default AbortSignal.aborted is false");
ac.abort();
is(ac.signal.aborted, true, "Signal is aborted");
next();
}
function testAbortEvent() {
var ac = new AbortController();
ac.signal.onabort = function(e) {
is(e.type, "abort", "Abort received");
next();
}
ac.abort();
}
var steps = [
// Simple stuff
testWebIDL,
testUpdateData,
// Event propagation
testAbortEvent,
];
function next() {
if (!steps.length) {
parent.postMessage({ type: "finish" }, "*");
return;
}
var step = steps.shift();
step();
}
next();
</script>

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

@ -1,72 +0,0 @@
<script>
function ok(a, msg) {
parent.postMessage({ type: "check", status: !!a, message: msg }, "*");
}
function is(a, b, msg) {
ok(a === b, msg);
}
function testAbortedFetch() {
var ac = new AbortController();
ac.abort();
fetch("slow.sjs", { signal: ac.signal }).then(() => {
ok(false, "Fetch should not return a resolved promise");
}, e => {
is(e.name, "AbortError", "We have an abort error");
}).then(next);
}
function testFetchAndAbort() {
var ac = new AbortController();
var p = fetch("slow.sjs", { signal: ac.signal });
ac.abort();
p.then(() => {
ok(false, "Fetch should not return a resolved promise");
}, e => {
is(e.name, "AbortError", "We have an abort error");
}).then(next);
}
function testWorkerAbortedFetch() {
var w = new Worker("worker_abort_controller_fetch.js");
w.onmessage = function(e) {
ok(e.data, "Abort + Fetch works in workers");
next();
}
w.postMessage("testWorkerAbortedFetch");
}
function testWorkerFetchAndAbort() {
var w = new Worker("worker_abort_controller_fetch.js");
w.onmessage = function(e) {
ok(e.data, "Abort + Fetch works in workers");
next();
}
w.postMessage("testWorkerFetchAndAbort");
}
var steps = [
// fetch + signaling
testAbortedFetch,
testFetchAndAbort,
testWorkerAbortedFetch,
testWorkerFetchAndAbort,
];
function next() {
if (!steps.length) {
parent.postMessage({ type: "finish" }, "*");
return;
}
var step = steps.shift();
step();
}
next();
</script>

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

@ -1,7 +1,5 @@
[DEFAULT]
support-files =
file_abort_controller.html
file_abort_controller_fetch.html
worker_abort_controller_fetch.js
slow.sjs

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

@ -12,27 +12,61 @@
<body>
<script class="testbody" type="text/javascript">
SpecialPowers.pushPrefEnv({"set": [["dom.abortController.enabled", true ]]}, () => {
let ifr = document.createElement("iframe");
ifr.src = "file_abort_controller.html";
document.body.appendChild(ifr);
function testWebIDL() {
ok("AbortController" in self, "We have a AbortController prototype");
ok("AbortSignal" in self, "We have a AbortSignal prototype");
window.onmessage = function(e) {
if (e.data.type == "finish") {
SimpleTest.finish();
return;
}
var ac = new AbortController();
ok(!!ac, "AbortController can be created");
ok(ac instanceof AbortController, "AbortController is a AbortController");
if (e.data.type == "check") {
ok(e.data.status, e.data.message);
return;
}
ok(!!ac.signal, "AbortController has a signal");
ok(ac.signal instanceof AbortSignal, "abortSignal is a AbortSignal");
is(ac.signal.aborted, false, "By default AbortSignal.aborted is false");
next();
}
ok(false, "Something when wrong.");
function testUpdateData() {
var ac = new AbortController();
is(ac.signal.aborted, false, "By default AbortSignal.aborted is false");
ac.abort();
is(ac.signal.aborted, true, "Signal is aborted");
next();
}
function testAbortEvent() {
var ac = new AbortController();
ac.signal.onabort = function(e) {
is(e.type, "abort", "Abort received");
next();
}
});
ac.abort();
}
var steps = [
// Simple stuff
testWebIDL,
testUpdateData,
// Event propagation
testAbortEvent,
];
function next() {
if (!steps.length) {
SimpleTest.finish();
return;
}
var step = steps.shift();
step();
}
SimpleTest.waitForExplicitFinish();
next();
</script>
</body>

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

@ -12,28 +12,68 @@
<body>
<script class="testbody" type="text/javascript">
SpecialPowers.pushPrefEnv({"set": [["dom.abortController.enabled", true ],
["dom.abortController.fetch.enabled", true]]}, () => {
let ifr = document.createElement("iframe");
ifr.src = "file_abort_controller_fetch.html";
document.body.appendChild(ifr);
function testAbortedFetch() {
var ac = new AbortController();
ac.abort();
window.onmessage = function(e) {
if (e.data.type == "finish") {
SimpleTest.finish();
return;
}
fetch("slow.sjs", { signal: ac.signal }).then(() => {
ok(false, "Fetch should not return a resolved promise");
}, e => {
is(e.name, "AbortError", "We have an abort error");
}).then(next);
}
if (e.data.type == "check") {
ok(e.data.status, e.data.message);
return;
}
function testFetchAndAbort() {
var ac = new AbortController();
ok(false, "Something when wrong.");
var p = fetch("slow.sjs", { signal: ac.signal });
ac.abort();
p.then(() => {
ok(false, "Fetch should not return a resolved promise");
}, e => {
is(e.name, "AbortError", "We have an abort error");
}).then(next);
}
function testWorkerAbortedFetch() {
var w = new Worker("worker_abort_controller_fetch.js");
w.onmessage = function(e) {
ok(e.data, "Abort + Fetch works in workers");
next();
}
});
w.postMessage("testWorkerAbortedFetch");
}
function testWorkerFetchAndAbort() {
var w = new Worker("worker_abort_controller_fetch.js");
w.onmessage = function(e) {
ok(e.data, "Abort + Fetch works in workers");
next();
}
w.postMessage("testWorkerFetchAndAbort");
}
var steps = [
// fetch + signaling
testAbortedFetch,
testFetchAndAbort,
testWorkerAbortedFetch,
testWorkerFetchAndAbort,
];
function next() {
if (!steps.length) {
SimpleTest.finish();
return;
}
var step = steps.shift();
step();
}
SimpleTest.waitForExplicitFinish();
next();
</script>
</body>

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

@ -244,16 +244,6 @@ DoesNotParticipateInAutoDirection(const Element* aElement)
aElement->IsInAnonymousSubtree());
}
static inline bool
IsBdiWithoutDirAuto(const Element* aElement)
{
// We are testing for bdi elements without explicit dir="auto", so we can't
// use the HasDirAuto() flag, since that will return true for bdi element with
// no dir attribute or an invalid dir attribute
return (aElement->IsHTMLElement(nsGkAtoms::bdi) &&
(!aElement->HasValidDir() || aElement->HasFixedDir()));
}
/**
* Returns true if aElement is one of the element whose text content should not
* affect the direction of ancestors with dir=auto (though it may affect its own
@ -263,7 +253,7 @@ static bool
DoesNotAffectDirectionOfAncestors(const Element* aElement)
{
return (DoesNotParticipateInAutoDirection(aElement) ||
IsBdiWithoutDirAuto(aElement) ||
aElement->IsHTMLElement(nsGkAtoms::bdi) ||
aElement->HasFixedDir());
}

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

@ -0,0 +1,15 @@
<html>
<script>
window.onload=function(){
document.getElementById('b').textContent='Or';
document.getElementById('a').insertBefore(document.getElementById('c'), undefined);
document.getElementById('b').dir='ltr';
let o=document.getElementById('b');
o.parentNode.replaceChild(document.createElement('code'), o);
}
</script>
<body dir='auto' id='a'>
<bdi id='b' dir='auto'>
</bdi>
<q id='c'>
</html>

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

@ -224,3 +224,4 @@ load 1383478.html
load 1383780.html
pref(clipboard.autocopy,true) load 1385272-1.html
load 1393806.html
load 1400701.html

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

@ -25,7 +25,6 @@
#include "nsIDOMRange.h"
#include "nsIFormControl.h"
#include "nsIDOMHTMLAreaElement.h"
#include "nsIDOMHTMLAnchorElement.h"
#include "nsITransferable.h"
#include "nsComponentManagerUtils.h"
#include "nsXPCOM.h"
@ -57,6 +56,7 @@
#include "TabParent.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/HTMLAreaElement.h"
#include "mozilla/dom/HTMLAnchorElement.h"
#include "nsVariant.h"
using namespace mozilla::dom;
@ -474,9 +474,7 @@ DragDataProducer::Produce(DataTransfer* aDataTransfer,
draggedNode = mTarget;
}
nsCOMPtr<nsIDOMHTMLAreaElement> area; // client-side image map
nsCOMPtr<nsIImageLoadingContent> image;
nsCOMPtr<nsIDOMHTMLAnchorElement> link;
nsCOMPtr<nsIContent> selectedImageOrLinkNode;
GetDraggableSelectionData(selection, mSelectionTargetNode,
@ -501,19 +499,16 @@ DragDataProducer::Produce(DataTransfer* aDataTransfer,
*aCanDrag = false;
return NS_OK;
}
area = do_QueryInterface(draggedNode);
image = do_QueryInterface(draggedNode);
link = do_QueryInterface(draggedNode);
}
{
// set for linked images, and links
nsCOMPtr<nsIContent> linkNode;
if (area) {
RefPtr<HTMLAreaElement> areaElem = HTMLAreaElement::FromContentOrNull(draggedNode);
if (areaElem) {
// use the alt text (or, if missing, the href) as the title
HTMLAreaElement* areaElem = static_cast<HTMLAreaElement*>(area.get());
areaElem->GetAttribute(NS_LITERAL_STRING("alt"), mTitleString);
if (mTitleString.IsEmpty()) {
// this can be a relative link
@ -638,9 +633,9 @@ DragDataProducer::Produce(DataTransfer* aDataTransfer,
nodeToSerialize = do_QueryInterface(draggedNode);
}
dragNode = nodeToSerialize;
} else if (link) {
} else if (draggedNode && draggedNode->IsHTMLElement(nsGkAtoms::a)) {
// set linkNode. The code below will handle this
linkNode = do_QueryInterface(link); // XXX test this
linkNode = do_QueryInterface(draggedNode); // XXX test this
GetNodeString(draggedNode, mTitleString);
} else if (parentLink) {
// parentLink will always be null if there's selected content

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

@ -666,7 +666,7 @@ BrowserElementChild.prototype = {
_ClickHandler: function(e) {
let isHTMLLink = node =>
((node instanceof Ci.nsIDOMHTMLAnchorElement && node.href) ||
((ChromeUtils.getClassName(node) === "HTMLAnchorElement" && node.href) ||
(node instanceof Ci.nsIDOMHTMLAreaElement && node.href) ||
node instanceof Ci.nsIDOMHTMLLinkElement);
@ -855,7 +855,7 @@ BrowserElementChild.prototype = {
_getSystemCtxMenuData: function(elem) {
let documentURI =
docShell.QueryInterface(Ci.nsIWebNavigation).currentURI.spec;
if ((elem instanceof Ci.nsIDOMHTMLAnchorElement && elem.href) ||
if ((ChromeUtils.getClassName(elem) === "HTMLAnchorElement" && elem.href) ||
(elem instanceof Ci.nsIDOMHTMLAreaElement && elem.href)) {
return {uri: elem.href,
documentURI: documentURI,

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

@ -8,10 +8,11 @@
#include "IPCBlobInputStreamChild.h"
#include "IPCBlobInputStreamStorage.h"
#include "mozilla/ipc/InputStreamParams.h"
#include "IPCBlobInputStreamThread.h"
#include "nsIAsyncInputStream.h"
#include "nsIStreamTransportService.h"
#include "nsITransport.h"
#include "nsNetCID.h"
#include "nsIAsyncOutputStream.h"
#include "nsIPipe.h"
#include "nsStreamUtils.h"
#include "nsStringStream.h"
#include "SlicedInputStream.h"
@ -20,8 +21,6 @@ namespace dom {
namespace {
static NS_DEFINE_CID(kStreamTransportServiceCID, NS_STREAMTRANSPORTSERVICE_CID);
class InputStreamCallbackRunnable final : public CancelableRunnable
{
public:
@ -247,7 +246,7 @@ IPCBlobInputStream::Close()
}
if (mAsyncRemoteStream) {
mAsyncRemoteStream->Close();
mAsyncRemoteStream->CloseWithStatus(NS_BASE_STREAM_CLOSED);
mAsyncRemoteStream = nullptr;
}
@ -643,30 +642,29 @@ IPCBlobInputStream::EnsureAsyncRemoteStream()
nsCOMPtr<nsIAsyncInputStream> asyncStream = do_QueryInterface(mRemoteStream);
if (!asyncStream || !nonBlocking) {
nsCOMPtr<nsIStreamTransportService> sts =
do_GetService(kStreamTransportServiceCID, &rv);
// Let's make the stream async using the DOMFile thread.
nsCOMPtr<nsIAsyncInputStream> pipeIn;
nsCOMPtr<nsIAsyncOutputStream> pipeOut;
rv = NS_NewPipe2(getter_AddRefs(pipeIn),
getter_AddRefs(pipeOut),
true, true);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsCOMPtr<nsITransport> transport;
rv = sts->CreateInputTransport(mRemoteStream,
/* aCloseWhenDone */ true,
getter_AddRefs(transport));
RefPtr<IPCBlobInputStreamThread> thread =
IPCBlobInputStreamThread::GetOrCreate();
if (NS_WARN_IF(!thread)) {
return NS_ERROR_FAILURE;
}
rv = NS_AsyncCopy(mRemoteStream, pipeOut, thread,
NS_ASYNCCOPY_VIA_WRITESEGMENTS);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsCOMPtr<nsIInputStream> wrapper;
rv = transport->OpenInputStream(/* aFlags */ 0,
/* aSegmentSize */ 0,
/* aSegmentCount */ 0,
getter_AddRefs(wrapper));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
asyncStream = do_QueryInterface(wrapper);
asyncStream = pipeIn;
}
MOZ_ASSERT(asyncStream);

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

@ -187,6 +187,8 @@ IPCBlobInputStreamChild::ActorDestroy(IProtocol::ActorDestroyReason aReason)
// thread.
RefPtr<IPCBlobInputStreamThread> thread =
IPCBlobInputStreamThread::GetOrCreate();
MOZ_ASSERT(thread, "We cannot continue without DOMFile thread.");
ResetManager();
thread->MigrateActor(this);
return;

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

@ -36,7 +36,7 @@ public:
{
mozilla::StaticMutexAutoLock lock(gIPCBlobThreadMutex);
MOZ_ASSERT(gIPCBlobThread);
gIPCBlobThread->Initialize();
gIPCBlobThread->InitializeOnMainThread();
return NS_OK;
}
};
@ -93,7 +93,7 @@ NS_IMPL_ISUPPORTS_INHERITED(MigrateActorRunnable, Runnable,
} // anonymous
NS_IMPL_ISUPPORTS(IPCBlobInputStreamThread, nsIObserver)
NS_IMPL_ISUPPORTS(IPCBlobInputStreamThread, nsIObserver, nsIEventTarget)
/* static */ bool
IPCBlobInputStreamThread::IsOnFileEventTarget(nsIEventTarget* aEventTarget)
@ -115,36 +115,21 @@ IPCBlobInputStreamThread::GetOrCreate()
if (!gIPCBlobThread) {
gIPCBlobThread = new IPCBlobInputStreamThread();
gIPCBlobThread->Initialize();
if (!gIPCBlobThread->Initialize()) {
return nullptr;
}
}
return gIPCBlobThread;
}
void
bool
IPCBlobInputStreamThread::Initialize()
{
if (!NS_IsMainThread()) {
RefPtr<Runnable> runnable = new ThreadInitializeRunnable();
SystemGroup::Dispatch(TaskCategory::Other, runnable.forget());
return;
}
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (NS_WARN_IF(!obs)) {
return;
}
nsresult rv =
obs->AddObserver(this, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID, false);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
nsCOMPtr<nsIThread> thread;
rv = NS_NewNamedThread("DOM File", getter_AddRefs(thread));
nsresult rv = NS_NewNamedThread("DOM File", getter_AddRefs(thread));
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
return false;
}
mThread = thread;
@ -156,6 +141,32 @@ IPCBlobInputStreamThread::Initialize()
mPendingActors.Clear();
}
if (!NS_IsMainThread()) {
RefPtr<Runnable> runnable = new ThreadInitializeRunnable();
SystemGroup::Dispatch(TaskCategory::Other, runnable.forget());
return true;
}
InitializeOnMainThread();
return true;
}
void
IPCBlobInputStreamThread::InitializeOnMainThread()
{
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (NS_WARN_IF(!obs)) {
return;
}
nsresult rv =
obs->AddObserver(this, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID, false);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
}
NS_IMETHODIMP
@ -205,5 +216,48 @@ IPCBlobInputStreamThread::MigrateActorInternal(IPCBlobInputStreamChild* aActor)
mThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
}
// nsIEventTarget
NS_IMETHODIMP_(bool)
IPCBlobInputStreamThread::IsOnCurrentThreadInfallible()
{
return mThread->IsOnCurrentThread();
}
NS_IMETHODIMP
IPCBlobInputStreamThread::IsOnCurrentThread(bool* aRetval)
{
return mThread->IsOnCurrentThread(aRetval);
}
NS_IMETHODIMP
IPCBlobInputStreamThread::Dispatch(already_AddRefed<nsIRunnable> aRunnable,
uint32_t aFlags)
{
nsCOMPtr<nsIRunnable> runnable(aRunnable);
mozilla::StaticMutexAutoLock lock(gIPCBlobThreadMutex);
if (gShutdownHasStarted) {
return NS_ERROR_NOT_INITIALIZED;
}
return mThread->Dispatch(runnable.forget(), aFlags);
}
NS_IMETHODIMP
IPCBlobInputStreamThread::DispatchFromScript(nsIRunnable* aRunnable,
uint32_t aFlags)
{
nsCOMPtr<nsIRunnable> runnable(aRunnable);
return Dispatch(runnable.forget(), aFlags);
}
NS_IMETHODIMP
IPCBlobInputStreamThread::DelayedDispatch(already_AddRefed<nsIRunnable>, uint32_t)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
} // dom namespace
} // mozilla namespace

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

@ -8,6 +8,7 @@
#define mozilla_dom_IPCBlobInputStreamThread_h
#include "nsIObserverService.h"
#include "nsIEventTarget.h"
class nsIThread;
@ -17,10 +18,12 @@ namespace dom {
class IPCBlobInputStreamChild;
class IPCBlobInputStreamThread final : public nsIObserver
, public nsIEventTarget
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIOBSERVER
NS_DECL_NSIEVENTTARGET
static bool
IsOnFileEventTarget(nsIEventTarget* aEventTarget);
@ -31,9 +34,12 @@ public:
void
MigrateActor(IPCBlobInputStreamChild* aActor);
void
bool
Initialize();
void
InitializeOnMainThread();
private:
~IPCBlobInputStreamThread() = default;

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

@ -58,10 +58,13 @@ HTMLAnchorElement::IsInteractiveHTMLContent(bool aIgnoreTabindex) const
nsGenericHTMLElement::IsInteractiveHTMLContent(aIgnoreTabindex);
}
NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED(HTMLAnchorElement,
nsGenericHTMLElement,
nsIDOMHTMLAnchorElement,
Link)
NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLAnchorElement)
NS_INTERFACE_TABLE_INHERITED(HTMLAnchorElement,
Link)
NS_INTERFACE_TABLE_TAIL_INHERITING(nsGenericHTMLElement)
NS_IMPL_ADDREF_INHERITED(HTMLAnchorElement, Element)
NS_IMPL_RELEASE_INHERITED(HTMLAnchorElement, Element)
NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLAnchorElement)
@ -83,17 +86,6 @@ HTMLAnchorElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
return HTMLAnchorElementBinding::Wrap(aCx, this, aGivenProto);
}
NS_IMPL_STRING_ATTR(HTMLAnchorElement, Charset, charset)
NS_IMPL_STRING_ATTR(HTMLAnchorElement, Coords, coords)
NS_IMPL_URI_ATTR(HTMLAnchorElement, Href, href)
NS_IMPL_STRING_ATTR(HTMLAnchorElement, Hreflang, hreflang)
NS_IMPL_STRING_ATTR(HTMLAnchorElement, Name, name)
NS_IMPL_STRING_ATTR(HTMLAnchorElement, Rel, rel)
NS_IMPL_STRING_ATTR(HTMLAnchorElement, Rev, rev)
NS_IMPL_STRING_ATTR(HTMLAnchorElement, Shape, shape)
NS_IMPL_STRING_ATTR(HTMLAnchorElement, Type, type)
NS_IMPL_STRING_ATTR(HTMLAnchorElement, Download, download)
int32_t
HTMLAnchorElement::TabIndexDefault()
{
@ -268,19 +260,12 @@ HTMLAnchorElement::GetLinkTarget(nsAString& aTarget)
}
}
NS_IMETHODIMP
void
HTMLAnchorElement::GetTarget(nsAString& aValue)
{
if (!GetAttr(kNameSpaceID_None, nsGkAtoms::target, aValue)) {
GetBaseTarget(aValue);
}
return NS_OK;
}
NS_IMETHODIMP
HTMLAnchorElement::SetTarget(const nsAString& aValue)
{
return SetAttr(kNameSpaceID_None, nsGkAtoms::target, aValue, true);
}
nsDOMTokenList*
@ -292,64 +277,26 @@ HTMLAnchorElement::RelList()
return mRelList;
}
#define IMPL_URI_PART(_part) \
NS_IMETHODIMP \
HTMLAnchorElement::Get##_part(nsAString& a##_part) \
{ \
Link::Get##_part(a##_part); \
return NS_OK; \
} \
NS_IMETHODIMP \
HTMLAnchorElement::Set##_part(const nsAString& a##_part) \
{ \
Link::Set##_part(a##_part); \
return NS_OK; \
}
IMPL_URI_PART(Protocol)
IMPL_URI_PART(Host)
IMPL_URI_PART(Hostname)
IMPL_URI_PART(Pathname)
IMPL_URI_PART(Search)
IMPL_URI_PART(Port)
IMPL_URI_PART(Hash)
#undef IMPL_URI_PART
NS_IMETHODIMP
HTMLAnchorElement::GetText(nsAString& aText)
void
HTMLAnchorElement::GetText(nsAString& aText, mozilla::ErrorResult& aRv)
{
if(!nsContentUtils::GetNodeTextContent(this, true, aText, fallible)) {
return NS_ERROR_OUT_OF_MEMORY;
if (NS_WARN_IF(!nsContentUtils::GetNodeTextContent(this, true, aText, fallible))) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
}
return NS_OK;
}
NS_IMETHODIMP
HTMLAnchorElement::SetText(const nsAString& aText)
void
HTMLAnchorElement::SetText(const nsAString& aText, ErrorResult& aRv)
{
return nsContentUtils::SetNodeTextContent(this, aText, false);
aRv = nsContentUtils::SetNodeTextContent(this, aText, false);
}
NS_IMETHODIMP
void
HTMLAnchorElement::ToString(nsAString& aSource)
{
return GetHref(aSource);
}
NS_IMETHODIMP
HTMLAnchorElement::GetPing(nsAString& aValue)
{
GetAttr(kNameSpaceID_None, nsGkAtoms::ping, aValue);
return NS_OK;
}
NS_IMETHODIMP
HTMLAnchorElement::SetPing(const nsAString& aValue)
{
return SetAttr(kNameSpaceID_None, nsGkAtoms::ping, aValue, true);
}
already_AddRefed<nsIURI>
HTMLAnchorElement::GetHrefURI() const
{

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

@ -10,7 +10,6 @@
#include "mozilla/Attributes.h"
#include "mozilla/dom/Link.h"
#include "nsGenericHTMLElement.h"
#include "nsIDOMHTMLAnchorElement.h"
#include "nsDOMTokenList.h"
namespace mozilla {
@ -19,7 +18,6 @@ class EventChainPreVisitor;
namespace dom {
class HTMLAnchorElement final : public nsGenericHTMLElement,
public nsIDOMHTMLAnchorElement,
public Link
{
public:
@ -39,15 +37,15 @@ public:
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLAnchorElement,
nsGenericHTMLElement)
NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLAnchorElement, a);
virtual int32_t TabIndexDefault() override;
virtual bool Draggable() const override;
// Element
virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const override;
// nsIDOMHTMLAnchorElement
NS_DECL_NSIDOMHTMLANCHORELEMENT
// DOM memory reporter participant
NS_DECL_ADDSIZEOFEXCLUDINGTHIS
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
@ -84,12 +82,15 @@ public:
// WebIDL API
// The XPCOM GetHref is OK for us
void GetHref(nsAString& aValue)
{
GetURIAttr(nsGkAtoms::href, nullptr, aValue);
}
void SetHref(const nsAString& aValue, mozilla::ErrorResult& rv)
{
SetHTMLAttr(nsGkAtoms::href, aValue, rv);
}
// The XPCOM GetTarget is OK for us
void GetTarget(nsAString& aValue);
void SetTarget(const nsAString& aValue, mozilla::ErrorResult& rv)
{
SetHTMLAttr(nsGkAtoms::target, aValue, rv);
@ -102,7 +103,10 @@ public:
{
SetHTMLAttr(nsGkAtoms::download, aValue, rv);
}
// The XPCOM GetPing is OK for us
void GetPing(DOMString& aValue)
{
GetHTMLAttr(nsGkAtoms::ping, aValue);
}
void SetPing(const nsAString& aValue, mozilla::ErrorResult& rv)
{
SetHTMLAttr(nsGkAtoms::ping, aValue, rv);
@ -119,9 +123,9 @@ public:
{
SetHTMLAttr(nsGkAtoms::referrerpolicy, aValue, rv);
}
void GetReferrerPolicy(nsAString& aReferrer)
void GetReferrerPolicy(DOMString& aPolicy)
{
GetEnumAttr(nsGkAtoms::referrerpolicy, EmptyCString().get(), aReferrer);
GetEnumAttr(nsGkAtoms::referrerpolicy, EmptyCString().get(), aPolicy);
}
nsDOMTokenList* RelList();
void GetHreflang(DOMString& aValue)
@ -132,6 +136,11 @@ public:
{
SetHTMLAttr(nsGkAtoms::hreflang, aValue, rv);
}
// Needed for docshell
void GetType(nsAString& aValue)
{
GetHTMLAttr(nsGkAtoms::type, aValue);
}
void GetType(DOMString& aValue)
{
GetHTMLAttr(nsGkAtoms::type, aValue);
@ -140,11 +149,8 @@ public:
{
SetHTMLAttr(nsGkAtoms::type, aValue, rv);
}
// The XPCOM GetText is OK for us
void SetText(const nsAString& aValue, mozilla::ErrorResult& rv)
{
rv = SetText(aValue);
}
void GetText(nsAString& aValue, mozilla::ErrorResult& rv);
void SetText(const nsAString& aValue, mozilla::ErrorResult& rv);
// Link::GetOrigin is OK for us
@ -175,7 +181,6 @@ public:
// Link::Link::GetHash is OK for us
// Link::Link::SetHash is OK for us
// The XPCOM URI decomposition attributes are fine for us
void GetCoords(DOMString& aValue)
{
GetHTMLAttr(nsGkAtoms::coords, aValue);
@ -220,6 +225,7 @@ public:
{
GetHref(aResult);
}
void ToString(nsAString& aSource);
virtual void NodeInfoChanged(nsIDocument* aOldDoc) final override
{

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

@ -42,6 +42,7 @@ public:
// nsIDOMHTMLAreaElement
NS_DECL_NSIDOMHTMLAREAELEMENT
NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLAreaElement, area);
virtual nsresult GetEventTargetParent(
EventChainPreVisitor& aVisitor) override;

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

@ -35,7 +35,7 @@ public:
// nsIDOMHTMLLinkElement
NS_DECL_NSIDOMHTMLLINKELEMENT
NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLLinkElement, link);
NS_DECL_ADDSIZEOFEXCLUDINGTHIS
void LinkAdded();

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

@ -8,7 +8,6 @@ with Files("**"):
BUG_COMPONENT = ("Core", "DOM")
XPIDL_SOURCES += [
'nsIDOMHTMLAnchorElement.idl',
'nsIDOMHTMLAreaElement.idl',
'nsIDOMHTMLBaseElement.idl',
'nsIDOMHTMLButtonElement.idl',

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

@ -1,55 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 "nsIDOMHTMLElement.idl"
/**
* The nsIDOMHTMLAnchorElement interface is the interface to a [X]HTML
* a element.
*
* This interface is trying to follow the DOM Level 2 HTML specification:
* http://www.w3.org/TR/DOM-Level-2-HTML/
*
* with changes from the work-in-progress WHATWG HTML specification:
* http://www.whatwg.org/specs/web-apps/current-work/
*/
[uuid(339c01c8-2d41-4626-b231-eec63f0241b6)]
interface nsIDOMHTMLAnchorElement : nsISupports
{
attribute DOMString href;
attribute DOMString target;
attribute DOMString ping;
attribute DOMString download;
attribute DOMString rel;
attribute DOMString hreflang;
attribute DOMString type;
/**
* An alias for the textContent attribute.
*/
[Null(Stringify)]
attribute DOMString text;
// URL decomposition IDL attributes
attribute DOMString protocol;
attribute DOMString host;
attribute DOMString hostname;
attribute DOMString port;
attribute DOMString pathname;
attribute DOMString search;
attribute DOMString hash;
attribute DOMString charset;
attribute DOMString coords;
attribute DOMString name;
attribute DOMString rev;
attribute DOMString shape;
DOMString toString();
};

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

@ -110,6 +110,7 @@
#if defined(XP_WIN) && defined(ACCESSIBILITY)
#include "mozilla/a11y/AccessibleWrap.h"
#include "mozilla/a11y/Compatibility.h"
#include "mozilla/a11y/nsWinUtils.h"
#endif
@ -2894,6 +2895,23 @@ TabParent::SetDocShellIsActive(bool isActive)
mDocShellIsActive = isActive;
Unused << SendSetDocShellIsActive(isActive, mPreserveLayers, mLayerTreeEpoch);
// update active accessible documents on windows
#if defined(XP_WIN) && defined(ACCESSIBILITY)
if (a11y::Compatibility::IsDolphin()) {
if (a11y::DocAccessibleParent* tabDoc = GetTopLevelDocAccessible()) {
HWND window = tabDoc->GetEmulatedWindowHandle();
MOZ_ASSERT(window);
if (window) {
if (isActive) {
a11y::nsWinUtils::ShowNativeWindow(window);
} else {
a11y::nsWinUtils::HideNativeWindow(window);
}
}
}
}
#endif
// Let's inform the priority manager. This operation can end up with the
// changing of the process priority.
ProcessPriorityManager::TabActivityChanged(this, isActive);

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

@ -26,7 +26,7 @@ var dshell = content.QueryInterface(Ci.nsIInterfaceRequestor)
addEventListener("click",
function(e) {
dump(e.target + "\n");
if (e.target instanceof Components.interfaces.nsIDOMHTMLAnchorElement &&
if (ChromeUtils.getClassName(e.target) === "HTMLAnchorElement" &&
dshell == docShell) {
var retval = docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
getInterface(Components.interfaces.nsIContentFrameMessageManager).

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

@ -49,7 +49,7 @@ skip-if = toolkit == 'android' # android(Bug 1189784, timeouts on 4.3 emulator),
[test_getUserMedia_addTrackRemoveTrack.html]
skip-if = android_version == '18' || os == 'linux' # android(Bug 1189784, timeouts on 4.3 emulator), linux bug 1377450
[test_getUserMedia_addtrack_removetrack_events.html]
skip-if os == 'linux' && debug # Bug 1389983
skip-if = os == 'linux' && debug # Bug 1389983
[test_getUserMedia_basicAudio.html]
[test_getUserMedia_basicVideo.html]
[test_getUserMedia_basicVideo_playAfterLoadedmetadata.html]

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

@ -0,0 +1,11 @@
<style>
text::first-letter {}
</style>
<script>
function js() {
a.setAttribute("fill", "url()");
}
</script>
<body onload=js()>
<svg>
<text id="a">aa</text>

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

@ -93,3 +93,4 @@ load 1329093-2.html
load 1347617-1.svg
load 1347617-2.svg
load 1347617-3.svg
load 1402798.html

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

@ -12,9 +12,7 @@
<body>
<script class="testbody" type="text/javascript">
SpecialPowers.pushPrefEnv({"set": [["dom.fetchObserver.enabled", true ],
["dom.abortController.enabled", true ],
["dom.abortController.fetch.enabled", true ]]}, () => {
SpecialPowers.pushPrefEnv({"set": [["dom.fetchObserver.enabled", true ]]}, () => {
let ifr = document.createElement('iframe');
ifr.src = "file_fetch_observer.html";
document.body.appendChild(ifr);

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

@ -6,6 +6,7 @@
#include "WebBrowserPersistLocalDocument.h"
#include "WebBrowserPersistDocumentParent.h"
#include "mozilla/dom/HTMLAnchorElement.h"
#include "mozilla/dom/HTMLInputElement.h"
#include "mozilla/dom/HTMLObjectElement.h"
#include "mozilla/dom/HTMLSharedElement.h"
@ -20,7 +21,6 @@
#include "nsIDOMAttr.h"
#include "nsIDOMComment.h"
#include "nsIDOMDocument.h"
#include "nsIDOMHTMLAnchorElement.h"
#include "nsIDOMHTMLAreaElement.h"
#include "nsIDOMHTMLBaseElement.h"
#include "nsIDOMHTMLCollection.h"
@ -941,7 +941,7 @@ PersistNodeFixup::FixupNode(nsIDOMNode *aNodeIn,
}
// Fix up href and file links in the elements
nsCOMPtr<nsIDOMHTMLAnchorElement> nodeAsAnchor = do_QueryInterface(aNodeIn);
RefPtr<dom::HTMLAnchorElement> nodeAsAnchor = dom::HTMLAnchorElement::FromContent(content);
if (nodeAsAnchor) {
rv = GetNodeToFixup(aNodeIn, aNodeOut);
if (NS_SUCCEEDED(rv) && *aNodeOut) {

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

@ -7,8 +7,7 @@
* https://dom.spec.whatwg.org/#abortcontroller
*/
[Constructor(), Exposed=(Window,Worker),
Func="AbortController::IsEnabled"]
[Constructor(), Exposed=(Window,Worker)]
interface AbortController {
readonly attribute AbortSignal signal;

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

@ -7,8 +7,7 @@
* https://dom.spec.whatwg.org/#abortsignal
*/
[Exposed=(Window,Worker),
Func="AbortController::IsEnabled"]
[Exposed=(Window,Worker)]
interface AbortSignal : EventTarget {
readonly attribute boolean aborted;

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

@ -31,7 +31,7 @@ interface HTMLAnchorElement : HTMLElement {
[CEReactions, SetterThrows]
attribute DOMString type;
[CEReactions, SetterThrows]
[CEReactions, Throws]
attribute DOMString text;
};

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

@ -27,8 +27,7 @@ interface Request {
readonly attribute RequestRedirect redirect;
readonly attribute DOMString integrity;
[Func="AbortController::IsEnabledInFetch",
BinaryName="getOrCreateSignal"]
[BinaryName="getOrCreateSignal"]
readonly attribute AbortSignal signal;
[Throws,
@ -52,7 +51,6 @@ dictionary RequestInit {
RequestRedirect redirect;
DOMString integrity;
[Func="AbortController::IsEnabledInFetch"]
AbortSignal? signal;
[Func="FetchObserver::IsEnabled"]

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

@ -42,8 +42,6 @@ WORKER_SIMPLE_PREF("dom.requestcontext.enabled", RequestContextEnabled, REQUESTC
WORKER_SIMPLE_PREF("gfx.offscreencanvas.enabled", OffscreenCanvasEnabled, OFFSCREENCANVAS_ENABLED)
WORKER_SIMPLE_PREF("dom.webkitBlink.dirPicker.enabled", WebkitBlinkDirectoryPickerEnabled, DOM_WEBKITBLINK_DIRPICKER_WEBKITBLINK)
WORKER_SIMPLE_PREF("dom.netinfo.enabled", NetworkInformationEnabled, NETWORKINFORMATION_ENABLED)
WORKER_SIMPLE_PREF("dom.abortController.enabled", AbortControllerEnabled, ABORTCONTROLLER_ENABLED)
WORKER_SIMPLE_PREF("dom.abortController.fetch.enabled", AbortControllerEnabledInFetch, ABORTCONTROLLER_FETCH_ENABLED)
WORKER_SIMPLE_PREF("dom.fetchObserver.enabled", FetchObserverEnabled, FETCHOBSERVER_ENABLED)
WORKER_SIMPLE_PREF("privacy.resistFingerprinting", ResistFingerprintingEnabled, RESISTFINGERPRINTING_ENABLED)
WORKER_SIMPLE_PREF("devtools.enabled", DevToolsEnabled, DEVTOOLS_ENABLED)

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

@ -18,11 +18,11 @@
#include "nsGkAtoms.h" // for nsGkAtoms, nsGkAtoms::a, etc.
#include "nsHTMLTags.h"
#include "nsIAtom.h" // for nsIAtom
#include "nsIDOMHTMLAnchorElement.h" // for nsIDOMHTMLAnchorElement
#include "nsIDOMNode.h" // for nsIDOMNode
#include "nsNameSpaceManager.h" // for kNameSpaceID_None
#include "nsLiteralString.h" // for NS_LITERAL_STRING
#include "nsString.h" // for nsAutoString
#include "mozilla/dom/HTMLAnchorElement.h"
namespace mozilla {
@ -336,14 +336,18 @@ HTMLEditUtils::IsLink(nsINode* aNode)
{
MOZ_ASSERT(aNode);
nsCOMPtr<nsIDOMHTMLAnchorElement> anchor = do_QueryInterface(aNode);
if (anchor) {
nsAutoString tmpText;
if (NS_SUCCEEDED(anchor->GetHref(tmpText)) && !tmpText.IsEmpty()) {
return true;
}
if (!aNode->IsContent()) {
return false;
}
return false;
RefPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::FromContentOrNull(aNode->AsContent());
if (!anchor) {
return false;
}
nsAutoString tmpText;
anchor->GetHref(tmpText);
return !tmpText.IsEmpty();
}
bool

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

@ -27,7 +27,6 @@
#include "nsIDocumentInlines.h"
#include "nsIDOMEventTarget.h"
#include "nsIDOMMouseEvent.h"
#include "nsIDOMHTMLAnchorElement.h"
#include "nsISelectionController.h"
#include "nsIDOMHTMLDocument.h"
#include "nsILinkHandler.h"
@ -2594,19 +2593,21 @@ HTMLEditor::InsertLinkAroundSelection(nsIDOMElement* aAnchorElement)
return NS_OK;
}
// Be sure we were given an anchor element
nsCOMPtr<nsIDOMHTMLAnchorElement> anchor = do_QueryInterface(aAnchorElement);
nsCOMPtr<nsIContent> content = do_QueryInterface(aAnchorElement);
RefPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::FromContentOrNull(content);
if (!anchor) {
return NS_OK;
}
nsAutoString href;
nsresult rv = anchor->GetHref(href);
NS_ENSURE_SUCCESS(rv, rv);
anchor->GetHref(href);
if (href.IsEmpty()) {
return NS_OK;
}
nsresult rv;
AutoPlaceholderBatch beginBatching(this);
// Set all attributes found on the supplied anchor element

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

@ -39,7 +39,6 @@
#include "nsIDOMDocument.h"
#include "nsIDOMDocumentFragment.h"
#include "nsIDOMElement.h"
#include "nsIDOMHTMLAnchorElement.h"
#include "nsIDOMHTMLFrameElement.h"
#include "nsIDOMHTMLIFrameElement.h"
#include "nsIDOMHTMLImageElement.h"

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

@ -608,10 +608,6 @@ GLBlitHelper::BlitImageToFramebuffer(layers::Image* srcImage,
case ImageFormat::SURFACE_TEXTURE:
return BlitImage(static_cast<layers::SurfaceTextureImage*>(srcImage), destSize,
destOrigin);
case ImageFormat::EGLIMAGE:
return BlitImage(static_cast<layers::EGLImageImage*>(srcImage), destSize,
destOrigin);
#endif
#ifdef XP_MACOSX
case ImageFormat::MAC_IOSURFACE:
@ -647,41 +643,6 @@ GLBlitHelper::BlitImage(layers::SurfaceTextureImage* srcImage, const gfx::IntSiz
gfxCriticalError() << "BlitImage(SurfaceTextureImage) not implemented.";
return false;
}
bool
GLBlitHelper::BlitImage(layers::EGLImageImage* const srcImage,
const gfx::IntSize& destSize, const OriginPos destOrigin) const
{
const EGLImage eglImage = srcImage->GetImage();
const EGLSync eglSync = srcImage->GetSync();
if (eglSync) {
EGLint status = sEGLLibrary.fClientWaitSync(EGL_DISPLAY(), eglSync, 0, LOCAL_EGL_FOREVER);
if (status != LOCAL_EGL_CONDITION_SATISFIED) {
return false;
}
}
GLuint tex = 0;
mGL->fGenTextures(1, &tex);
const ScopedSaveMultiTex saveTex(mGL, 1, LOCAL_GL_TEXTURE_2D);
mGL->fBindTexture(LOCAL_GL_TEXTURE_2D, tex);
mGL->TexParams_SetClampNoMips();
mGL->fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_2D, eglImage);
const auto& srcOrigin = srcImage->GetOriginPos();
const bool yFlip = destOrigin != srcOrigin;
const gfx::IntRect srcRect(0, 0, 1, 1);
const gfx::IntSize srcSize(1, 1);
const DrawBlitProg::BaseArgs baseArgs = { destSize, yFlip, srcRect, srcSize };
const auto& prog = GetDrawBlitProg({kFragHeader_Tex2D, kFragBody_RGBA});
MOZ_RELEASE_ASSERT(prog);
prog->Draw(baseArgs);
mGL->fDeleteTextures(1, &tex);
return true;
}
#endif
// -------------------------------------

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

@ -28,7 +28,6 @@ class GPUVideoImage;
class PlanarYCbCrImage;
class SurfaceTextureImage;
class MacIOSurfaceImage;
class EGLImageImage;
class SurfaceDescriptorD3D10;
class SurfaceDescriptorDXGIYCbCr;
} // namespace layers
@ -133,8 +132,6 @@ public:
// Blit onto the current FB.
bool BlitImage(layers::SurfaceTextureImage* stImage, const gfx::IntSize& destSize,
OriginPos destOrigin) const;
bool BlitImage(layers::EGLImageImage* eglImage, const gfx::IntSize& destSize,
OriginPos destOrigin) const;
#endif
#ifdef XP_MACOSX
bool BlitImage(layers::MacIOSurfaceImage* srcImage, const gfx::IntSize& destSize,

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

@ -16,35 +16,6 @@ namespace layers {
static RefPtr<GLContext> sSnapshotContext;
EGLImageImage::EGLImageImage(EGLImage aImage, EGLSync aSync,
const gfx::IntSize& aSize, const gl::OriginPos& aOrigin,
bool aOwns)
: GLImage(ImageFormat::EGLIMAGE),
mImage(aImage),
mSync(aSync),
mSize(aSize),
mPos(aOrigin),
mOwns(aOwns)
{
}
EGLImageImage::~EGLImageImage()
{
if (!mOwns) {
return;
}
if (mImage) {
sEGLLibrary.fDestroyImage(EGL_DISPLAY(), mImage);
mImage = nullptr;
}
if (mSync) {
sEGLLibrary.fDestroySync(EGL_DISPLAY(), mSync);
mSync = nullptr;
}
}
already_AddRefed<gfx::SourceSurface>
GLImage::GetAsSourceSurface()
{

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

@ -28,38 +28,6 @@ public:
}
};
class EGLImageImage : public GLImage {
public:
EGLImageImage(EGLImage aImage, EGLSync aSync,
const gfx::IntSize& aSize, const gl::OriginPos& aOrigin,
bool aOwns);
gfx::IntSize GetSize() override { return mSize; }
gl::OriginPos GetOriginPos() const {
return mPos;
}
EGLImage GetImage() const {
return mImage;
}
EGLSync GetSync() const {
return mSync;
}
EGLImageImage* AsEGLImageImage() override {
return this;
}
protected:
virtual ~EGLImageImage();
private:
EGLImage mImage;
EGLSync mSync;
gfx::IntSize mSize;
gl::OriginPos mPos;
bool mOwns;
};
#ifdef MOZ_WIDGET_ANDROID
class SurfaceTextureImage : public GLImage {

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

@ -174,7 +174,6 @@ protected:
/* Forward declarations for Image derivatives. */
class GLImage;
class EGLImageImage;
class SharedRGBImage;
#ifdef MOZ_WIDGET_ANDROID
class SurfaceTextureImage;
@ -233,7 +232,6 @@ public:
virtual TextureClient* GetTextureClient(KnowsCompositor* aForwarder) { return nullptr; }
/* Access to derived classes. */
virtual EGLImageImage* AsEGLImageImage() { return nullptr; }
virtual GLImage* AsGLImage() { return nullptr; }
#ifdef MOZ_WIDGET_ANDROID
virtual SurfaceTextureImage* AsSurfaceTextureImage() { return nullptr; }

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

@ -55,11 +55,6 @@ enum class ImageFormat {
*/
SURFACE_TEXTURE,
/**
* An EGL Image that can be shared across threads.
*/
EGLIMAGE,
/**
* The D3D9_RGB32_TEXTURE format creates a D3D9SurfaceImage, and wraps a
* IDirect3DTexture9 in RGB32 layout.

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

@ -400,8 +400,6 @@ AppendToString(std::stringstream& aStream, ImageFormat format,
aStream << "ImageFormat::MAC_IOSURFACE"; break;
case ImageFormat::SURFACE_TEXTURE:
aStream << "ImageFormat::SURFACE_TEXTURE"; break;
case ImageFormat::EGLIMAGE:
aStream << "ImageFormat::EGLIMAGE"; break;
case ImageFormat::D3D9_RGB32_TEXTURE:
aStream << "ImageFormat::D3D9_RBG32_TEXTURE"; break;
case ImageFormat::OVERLAY_IMAGE:

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

@ -118,24 +118,14 @@ ImageClient::CreateTextureClientForImage(Image* aImage, KnowsCompositor* aForwar
if (!status) {
return nullptr;
}
} else if (aImage->GetFormat() == ImageFormat::SURFACE_TEXTURE ||
aImage->GetFormat() == ImageFormat::EGLIMAGE) {
gfx::IntSize size = aImage->GetSize();
if (aImage->GetFormat() == ImageFormat::EGLIMAGE) {
EGLImageImage* typedImage = aImage->AsEGLImageImage();
texture = EGLImageTextureData::CreateTextureClient(
typedImage, size, aForwarder->GetTextureForwarder(), TextureFlags::DEFAULT);
#ifdef MOZ_WIDGET_ANDROID
} else if (aImage->GetFormat() == ImageFormat::SURFACE_TEXTURE) {
SurfaceTextureImage* typedImage = aImage->AsSurfaceTextureImage();
texture = AndroidSurfaceTextureData::CreateTextureClient(
typedImage->GetHandle(), size, typedImage->GetContinuous(), typedImage->GetOriginPos(),
aForwarder->GetTextureForwarder(), TextureFlags::DEFAULT);
} else if (aImage->GetFormat() == ImageFormat::SURFACE_TEXTURE) {
gfx::IntSize size = aImage->GetSize();
SurfaceTextureImage* typedImage = aImage->AsSurfaceTextureImage();
texture = AndroidSurfaceTextureData::CreateTextureClient(
typedImage->GetHandle(), size, typedImage->GetContinuous(), typedImage->GetOriginPos(),
aForwarder->GetTextureForwarder(), TextureFlags::DEFAULT);
#endif
} else {
MOZ_ASSERT(false, "Bad ImageFormat.");
}
} else {
RefPtr<gfx::SourceSurface> surface = aImage->GetAsSourceSurface();
MOZ_ASSERT(surface);

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

@ -17,62 +17,6 @@ namespace layers {
class CompositableForwarder;
////////////////////////////////////////////////////////////////////////
// EGLImage
EGLImageTextureData::EGLImageTextureData(EGLImageImage* aImage, gfx::IntSize aSize)
: mImage(aImage)
, mSize(aSize)
{
MOZ_ASSERT(aImage);
}
already_AddRefed<TextureClient>
EGLImageTextureData::CreateTextureClient(EGLImageImage* aImage, gfx::IntSize aSize,
LayersIPCChannel* aAllocator, TextureFlags aFlags)
{
MOZ_ASSERT(XRE_IsParentProcess(),
"Can't pass an `EGLImage` between processes.");
if (!aImage || !XRE_IsParentProcess()) {
return nullptr;
}
// XXX - This is quite sad and slow.
aFlags |= TextureFlags::DEALLOCATE_CLIENT;
if (aImage->GetOriginPos() == gl::OriginPos::BottomLeft) {
aFlags |= TextureFlags::ORIGIN_BOTTOM_LEFT;
}
return TextureClient::CreateWithData(
new EGLImageTextureData(aImage, aSize),
aFlags, aAllocator
);
}
void
EGLImageTextureData::FillInfo(TextureData::Info& aInfo) const
{
aInfo.size = mSize;
aInfo.format = gfx::SurfaceFormat::UNKNOWN;
aInfo.hasIntermediateBuffer = false;
aInfo.hasSynchronization = false;
aInfo.supportsMoz2D = false;
aInfo.canExposeMappedData = false;
}
bool
EGLImageTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
{
const bool hasAlpha = true;
aOutDescriptor =
EGLImageDescriptor((uintptr_t)mImage->GetImage(),
(uintptr_t)mImage->GetSync(),
mImage->GetSize(), hasAlpha);
return true;
}
////////////////////////////////////////////////////////////////////////
// AndroidSurface

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

@ -20,34 +20,6 @@ namespace mozilla {
namespace layers {
class EGLImageTextureData : public TextureData
{
public:
static already_AddRefed<TextureClient>
CreateTextureClient(EGLImageImage* aImage, gfx::IntSize aSize,
LayersIPCChannel* aAllocator, TextureFlags aFlags);
virtual void FillInfo(TextureData::Info& aInfo) const override;
virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
virtual void Deallocate(LayersIPCChannel*) override { mImage = nullptr; }
virtual void Forget(LayersIPCChannel*) override { mImage = nullptr; }
// Unused functions.
virtual bool Lock(OpenMode) override { return true; }
virtual void Unlock() override {}
protected:
EGLImageTextureData(EGLImageImage* aImage, gfx::IntSize aSize);
RefPtr<EGLImageImage> mImage;
const gfx::IntSize mSize;
};
#ifdef MOZ_WIDGET_ANDROID
class AndroidSurfaceTextureData : public TextureData

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

@ -608,12 +608,15 @@ WebRenderDebugPrefChangeCallback(const char* aPrefName, void*)
if (Preferences::GetBool(WR_DEBUG_PREF".profiler", false)) {
flags |= (1 << 0);
}
if (Preferences::GetBool(WR_DEBUG_PREF".texture-cache", false)) {
if (Preferences::GetBool(WR_DEBUG_PREF".render-targets", false)) {
flags |= (1 << 1);
}
if (Preferences::GetBool(WR_DEBUG_PREF".render-targets", false)) {
if (Preferences::GetBool(WR_DEBUG_PREF".texture-cache", false)) {
flags |= (1 << 2);
}
if (Preferences::GetBool(WR_DEBUG_PREF".alpha-primitives", false)) {
flags |= (1 << 3);
}
gfx::gfxVars::SetWebRenderDebugFlags(flags);
}

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

@ -600,7 +600,7 @@ UnknownPropertyStub(JSContext* cx, HandleObject obj, HandleId id, MutableHandleV
}
bool
UnknownStrictPropertyStub(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp,
UnknownStrictPropertyStub(JSContext* cx, HandleObject obj, HandleId id, HandleValue v,
ObjectOpResult& result)
{
JS_ReportErrorASCII(cx, "setter could not be wrapped via CPOWs");

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

@ -379,13 +379,11 @@ typedef bool
/**
* Set a property named by id in obj, treating the assignment as strict
* mode code if strict is true. Note the jsid id type -- id may be a string
* (Unicode property identifier) or an int (element index). The *vp out
* parameter, on success, is the new property value after the
* set.
* (Unicode property identifier) or an int (element index).
*/
typedef bool
(* JSSetterOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
JS::MutableHandleValue vp, JS::ObjectOpResult& result);
JS::HandleValue v, JS::ObjectOpResult& result);
/**
* Delete a property named by id in obj.

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

@ -642,7 +642,7 @@ array_length_getter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleV
}
static bool
array_length_setter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp,
array_length_setter(JSContext* cx, HandleObject obj, HandleId id, HandleValue v,
ObjectOpResult& result)
{
MOZ_ASSERT(id == NameToId(cx->names().length));
@ -651,14 +651,14 @@ array_length_setter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleV
// This array .length property was found on the prototype
// chain. Ideally the setter should not have been called, but since
// we're here, do an impression of SetPropertyByDefining.
return DefineDataProperty(cx, obj, id, vp, JSPROP_ENUMERATE, result);
return DefineDataProperty(cx, obj, id, v, JSPROP_ENUMERATE, result);
}
Rooted<ArrayObject*> arr(cx, &obj->as<ArrayObject>());
MOZ_ASSERT(arr->lengthIsWritable(),
"setter shouldn't be called if property is non-writable");
return ArraySetLength(cx, arr, id, JSPROP_PERMANENT, vp, result);
return ArraySetLength(cx, arr, id, JSPROP_PERMANENT, v, result);
}
struct ReverseIndexComparator

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

@ -1327,7 +1327,6 @@ JSContext::JSContext(JSRuntime* runtime, const JS::ContextOptions& options)
suppressProfilerSampling(false),
tempLifoAlloc_((size_t)TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE),
debuggerMutations(0),
propertyRemovals(0),
ionPcScriptCache(nullptr),
throwing(false),
overRecursed_(false),

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

@ -613,13 +613,6 @@ struct JSContext : public JS::RootingContext,
js::ThreadLocalData<uint32_t> debuggerMutations;
/*
* The propertyRemovals counter is incremented for every JSObject::clear,
* and for each JSObject::remove method call that frees a slot in the given
* object. See js_NativeGet and js_NativeSet in jsobj.cpp.
*/
js::ThreadLocalData<uint32_t> propertyRemovals;
// Cache for jit::GetPcScript().
js::ThreadLocalData<js::jit::PcScriptCache*> ionPcScriptCache;

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

@ -365,14 +365,14 @@ CallJSGetterOp(JSContext* cx, GetterOp op, HandleObject obj, HandleId id,
}
MOZ_ALWAYS_INLINE bool
CallJSSetterOp(JSContext* cx, SetterOp op, HandleObject obj, HandleId id, MutableHandleValue vp,
CallJSSetterOp(JSContext* cx, SetterOp op, HandleObject obj, HandleId id, HandleValue v,
ObjectOpResult& result)
{
if (!CheckRecursionLimit(cx))
return false;
assertSameCompartment(cx, obj, id, vp);
return op(cx, obj, id, vp, result);
assertSameCompartment(cx, obj, id, v);
return op(cx, obj, id, v, result);
}
inline bool

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

@ -195,10 +195,8 @@ js::SetPropertyIgnoringNamedGetter(JSContext* cx, HandleObject obj, HandleId id,
RootedObject receiverObj(cx, &receiver.toObject());
// Nonstandard SpiderMonkey special case: setter ops.
if (SetterOp setter = ownDesc.setter()) {
RootedValue valCopy(cx, v);
return CallJSSetterOp(cx, setter, receiverObj, id, &valCopy, result);
}
if (SetterOp setter = ownDesc.setter())
return CallJSSetterOp(cx, setter, receiverObj, id, v, result);
// Steps 5.c-d.
Rooted<PropertyDescriptor> existingDescriptor(cx);

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

@ -476,7 +476,7 @@ MappedArgGetter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue
}
static bool
MappedArgSetter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp,
MappedArgSetter(JSContext* cx, HandleObject obj, HandleId id, HandleValue v,
ObjectOpResult& result)
{
if (!obj->is<MappedArgumentsObject>())
@ -499,9 +499,9 @@ MappedArgSetter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue
if (JSID_IS_INT(id)) {
unsigned arg = unsigned(JSID_TO_INT(id));
if (arg < argsobj->initialLength() && !argsobj->isElementDeleted(arg)) {
argsobj->setElement(cx, arg, vp);
argsobj->setElement(cx, arg, v);
if (arg < script->functionNonDelazifying()->nargs())
TypeScript::SetArgument(cx, script, arg, vp);
TypeScript::SetArgument(cx, script, arg, v);
return result.succeed();
}
} else {
@ -518,7 +518,7 @@ MappedArgSetter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue
*/
ObjectOpResult ignored;
return NativeDeleteProperty(cx, argsobj, id, ignored) &&
NativeDefineDataProperty(cx, argsobj, id, vp, attrs, result);
NativeDefineDataProperty(cx, argsobj, id, v, attrs, result);
}
static bool
@ -726,7 +726,7 @@ UnmappedArgGetter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleVal
}
static bool
UnmappedArgSetter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp,
UnmappedArgSetter(JSContext* cx, HandleObject obj, HandleId id, HandleValue v,
ObjectOpResult& result)
{
if (!obj->is<UnmappedArgumentsObject>())
@ -744,7 +744,7 @@ UnmappedArgSetter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleVal
if (JSID_IS_INT(id)) {
unsigned arg = unsigned(JSID_TO_INT(id));
if (arg < argsobj->initialLength()) {
argsobj->setElement(cx, arg, vp);
argsobj->setElement(cx, arg, v);
return result.succeed();
}
} else {
@ -758,7 +758,7 @@ UnmappedArgSetter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleVal
*/
ObjectOpResult ignored;
return NativeDeleteProperty(cx, argsobj, id, ignored) &&
NativeDefineDataProperty(cx, argsobj, id, vp, attrs, result);
NativeDefineDataProperty(cx, argsobj, id, v, attrs, result);
}
/* static */ bool

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

@ -2503,22 +2503,8 @@ NativeSetExistingDataProperty(JSContext* cx, HandleNativeObject obj, HandleShape
MOZ_ASSERT(!obj->is<WithEnvironmentObject>()); // See bug 1128681.
uint32_t sample = cx->propertyRemovals;
RootedId id(cx, shape->propid());
RootedValue value(cx, v);
if (!CallJSSetterOp(cx, shape->setterOp(), obj, id, &value, result))
return false;
// Update any slot for the shape with the value produced by the setter,
// unless the setter deleted the shape.
if (shape->hasSlot() &&
(MOZ_LIKELY(cx->propertyRemovals == sample) ||
obj->contains(cx, shape)))
{
obj->setSlot(shape->slot(), value);
}
return true; // result is populated by CallJSSetterOp above.
return CallJSSetterOp(cx, shape->setterOp(), obj, id, v, result);
}
/*
@ -2729,8 +2715,7 @@ SetExistingProperty(JSContext* cx, HandleNativeObject obj, HandleId id, HandleVa
if (shape->hasDefaultSetter())
return result.succeed();
RootedValue valCopy(cx, v);
return CallJSSetterOp(cx, shape->setterOp(), obj, id, &valCopy, result);
return CallJSSetterOp(cx, shape->setterOp(), obj, id, v, result);
}
// Shadow pobj[id] by defining a new data property receiver[id].

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

@ -855,13 +855,8 @@ NativeObject::putProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
* to will botch an assertion in JSObject::freeSlot) if the new last
* property (shape here) has a slotSpan that does not cover it.
*/
if (hadSlot && !shape->hasSlot()) {
if (oldSlot < obj->slotSpan())
obj->freeSlot(cx, oldSlot);
/* Note: The optimization based on propertyRemovals is only relevant to the active thread. */
if (!cx->helperThread())
++cx->propertyRemovals;
}
if (hadSlot && !shape->hasSlot() && oldSlot < obj->slotSpan())
obj->freeSlot(cx, oldSlot);
obj->checkShapeConsistency();
@ -959,11 +954,8 @@ NativeObject::removeProperty(JSContext* cx, HandleNativeObject obj, jsid id_)
}
/* If shape has a slot, free its slot number. */
if (shape->hasSlot()) {
if (shape->hasSlot())
obj->freeSlot(cx, shape->slot());
if (!cx->helperThread())
++cx->propertyRemovals;
}
/*
* A dictionary-mode object owns mutable, unique shapes on a non-circular
@ -1042,8 +1034,6 @@ NativeObject::clear(JSContext* cx, HandleNativeObject obj)
JS_ALWAYS_TRUE(obj->setLastProperty(cx, shape));
if (!cx->helperThread())
++cx->propertyRemovals;
obj->checkShapeConsistency();
}

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

@ -440,14 +440,14 @@ sandbox_moved(JSObject* obj, JSObject* old)
static bool
writeToProto_setProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
JS::MutableHandleValue vp, JS::ObjectOpResult& result)
JS::HandleValue v, JS::ObjectOpResult& result)
{
RootedObject proto(cx);
if (!JS_GetPrototype(cx, obj, &proto))
return false;
RootedValue receiver(cx, ObjectValue(*proto));
return JS_ForwardSetPropertyTo(cx, proto, id, vp, receiver, result);
return JS_ForwardSetPropertyTo(cx, proto, id, v, receiver, result);
}
static bool

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

@ -762,7 +762,7 @@ nsIPresShell::nsIPresShell()
, mFrozen(false)
, mIsFirstPaint(false)
, mObservesMutationsForPrint(false)
, mSuppressInterruptibleReflows(false)
, mWasLastReflowInterrupted(false)
, mScrollPositionClampingScrollPortSizeSet(false)
, mNeedLayoutFlush(true)
, mNeedStyleFlush(true)
@ -4197,7 +4197,7 @@ PresShell::DoFlushPendingNotifications(mozilla::ChangesToFlush aFlush)
// worry about them. They can't be triggered during reflow, so we should
// be good.
if (flushType >= (mSuppressInterruptibleReflows
if (flushType >= (SuppressInterruptibleReflows()
? FlushType::Layout
: FlushType::InterruptibleLayout) &&
!mIsDestroying) {
@ -4232,7 +4232,7 @@ PresShell::DoFlushPendingNotifications(mozilla::ChangesToFlush aFlush)
if (!didLayoutFlush && flushType >= FlushType::InterruptibleLayout &&
!mIsDestroying) {
// We suppressed this flush either due to it not being safe to flush,
// or due to mSuppressInterruptibleReflows. Either way, the
// or due to SuppressInterruptibleReflows(). Either way, the
// mNeedLayoutFlush flag needs to be re-set.
SetNeedLayoutFlush();
}
@ -9457,7 +9457,7 @@ PresShell::DoReflow(nsIFrame* target, bool aInterruptible)
// Any FlushPendingNotifications with interruptible reflows
// should be suppressed now. We don't want to do extra reflow work
// before our reflow event happens.
mSuppressInterruptibleReflows = true;
mWasLastReflowInterrupted = true;
MaybeScheduleReflow();
}

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

@ -1581,6 +1581,21 @@ public:
mFontSizeInflationEnabledIsDirty = true;
}
/**
* Return true if the most recent interruptible reflow was interrupted.
*/
bool IsReflowInterrupted() const {
return mWasLastReflowInterrupted;
}
/**
* Return true if the the interruptible reflows have to be suppressed.
* This may happen only if if the most recent reflow was interrupted.
*/
bool SuppressInterruptibleReflows() const {
return mWasLastReflowInterrupted;
}
//////////////////////////////////////////////////////////////////////////////
// Approximate frame visibility tracking public API.
//////////////////////////////////////////////////////////////////////////////
@ -1794,7 +1809,8 @@ protected:
bool mIsFirstPaint : 1;
bool mObservesMutationsForPrint : 1;
bool mSuppressInterruptibleReflows : 1;
// Whether the most recent interruptible reflow was actually interrupted:
bool mWasLastReflowInterrupted : 1;
bool mScrollPositionClampingScrollPortSizeSet : 1;
// True if a layout flush might not be a no-op

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

@ -1949,7 +1949,7 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime)
nsCOMPtr<nsIPresShell> shellKungFuDeathGrip(shell);
shell->mObservingLayoutFlushes = false;
shell->mSuppressInterruptibleReflows = false;
shell->mWasLastReflowInterrupted = false;
FlushType flushType = HasPendingAnimations(shell)
? FlushType::Layout
: FlushType::InterruptibleLayout;

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

@ -43,7 +43,6 @@
#include "nsNetUtil.h"
#include "nsNetCID.h"
#include "nsCSSRendering.h"
#include "nsIDOMHTMLAnchorElement.h"
#include "nsNameSpaceManager.h"
#include <algorithm>
#ifdef ACCESSIBILITY
@ -81,6 +80,7 @@
#include "mozilla/dom/Link.h"
#include "SVGImageContext.h"
#include "mozilla/dom/HTMLAnchorElement.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -1993,7 +1993,7 @@ nsImageFrame::GetAnchorHREFTargetAndNode(nsIURI** aHref, nsString& aTarget,
}
status = (*aHref != nullptr);
nsCOMPtr<nsIDOMHTMLAnchorElement> anchor(do_QueryInterface(content));
RefPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::FromContent(content);
if (anchor) {
anchor->GetTarget(aTarget);
}

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

@ -104,7 +104,6 @@ static const char kPrintingPromptService[] = "@mozilla.org/embedcomp/printingpro
#include "nsILayoutHistoryState.h"
#include "nsFrameManager.h"
#include "mozilla/ReflowInput.h"
#include "nsIDOMHTMLAnchorElement.h"
#include "nsIDOMHTMLAreaElement.h"
#include "nsIDOMHTMLLinkElement.h"
#include "nsIDOMHTMLImageElement.h"

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

@ -1413,7 +1413,7 @@ fuzzy-if(Android,5,2800) == 506481-1.html 506481-1-ref.html
== 507762-4.html 507762-2-ref.html
random-if(cocoaWidget||(gtkWidget&&webrender)||winWidget) == 508816-1.xul 508816-1-ref.xul # Bug 631982 and bug 1375012
== 508816-2.html 508816-2-ref.html
== 508908-1.xul 508908-1-ref.xul
skip-if(isDebugBuild) == 508908-1.xul 508908-1-ref.xul
== 508919-1.xhtml 508919-1-ref.xhtml
== 509155-1.xhtml 509155-1-ref.xhtml
fuzzy-if(Android,5,1656) fuzzy-if(skiaContent,1,1200) == 512410.html 512410-ref.html

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

@ -372,7 +372,8 @@ include ../../toolkit/themes/osx/reftests/reftest.list
include ../../toolkit/content/tests/reftests/reftest.list
# -moz-transform/
include transform/reftest.list
# skipping on non-e10s windows because of assertion in bug 1401228
skip-if(winWidget&&!browserIsRemote) include transform/reftest.list
# 3d transforms
include transform-3d/reftest.list

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

@ -356,6 +356,9 @@ class RemoteReftest(RefTest):
debuggerInfo=debuggerInfo,
symbolsPath=symbolsPath,
timeout=timeout)
if status == 1:
# when max run time exceeded, avoid restart
lastTestSeen = RefTest.TEST_SEEN_FINAL
return status, lastTestSeen
def cleanup(self, profileDir):

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

@ -429,9 +429,9 @@ class RefTest(object):
self._populate_logger(options)
# Number of times to repeat test(s) when running with --repeat
VERIFY_REPEAT = 20
VERIFY_REPEAT = 10
# Number of times to repeat test(s) when running test in separate browser
VERIFY_REPEAT_SINGLE_BROWSER = 10
VERIFY_REPEAT_SINGLE_BROWSER = 5
def step1():
stepOptions = copy.deepcopy(options)
@ -448,12 +448,34 @@ class RefTest(object):
break
return result
def step3():
stepOptions = copy.deepcopy(options)
stepOptions.repeat = VERIFY_REPEAT
stepOptions.runUntilFailure = True
stepOptions.environment.append("MOZ_CHAOSMODE=3")
result = self.runTests(tests, stepOptions)
return result
def step4():
stepOptions = copy.deepcopy(options)
stepOptions.environment.append("MOZ_CHAOSMODE=3")
for i in xrange(VERIFY_REPEAT_SINGLE_BROWSER):
result = self.runTests(tests, stepOptions)
if result != 0:
break
return result
steps = [
("1. Run each test %d times in one browser." % VERIFY_REPEAT,
step1),
("2. Run each test %d times in a new browser each time." %
VERIFY_REPEAT_SINGLE_BROWSER,
step2),
("3. Run each test %d times in one browser, in chaos mode." % VERIFY_REPEAT,
step3),
("4. Run each test %d times in a new browser each time, in chaos mode." %
VERIFY_REPEAT_SINGLE_BROWSER,
step4),
]
stepResults = {}

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

@ -484,10 +484,13 @@ public final class IntentHelper implements BundleEventListener {
*/
private void openNoHandler(final GeckoBundle msg, final EventCallback callback) {
final String uri = msg.getString("uri");
final GeckoBundle errorResponse = new GeckoBundle();
if (TextUtils.isEmpty(uri)) {
Log.w(LOGTAG, "Received empty URL - loading about:neterror");
callback.sendError(getUnknownProtocolErrorPageUri(""));
errorResponse.putString("uri", getUnknownProtocolErrorPageUri(""));
errorResponse.putBoolean("isFallback", false);
callback.sendError(errorResponse);
return;
}
@ -505,7 +508,9 @@ public final class IntentHelper implements BundleEventListener {
// Don't log the exception to prevent leaking URIs.
Log.w(LOGTAG, "Unable to parse Intent URI - loading about:neterror");
callback.sendError(errorUri);
errorResponse.putString("uri", errorUri);
errorResponse.putBoolean("isFallback", false);
callback.sendError(errorResponse);
return;
}
@ -513,9 +518,10 @@ public final class IntentHelper implements BundleEventListener {
// https://developer.chrome.com/multidevice/android/intents
final String fallbackUrl = intent.getStringExtra(EXTRA_BROWSER_FALLBACK_URL);
if (isFallbackUrlValid(fallbackUrl)) {
errorResponse.putString("uri", fallbackUrl);
errorResponse.putBoolean("isFallback", true);
// Opens the page in JS.
callback.sendError(fallbackUrl);
callback.sendError(errorResponse);
} else if (intent.getPackage() != null) {
// Note on alternative flows: we could get the intent package from a component, however, for
// security reasons, components are ignored when opening URIs (bug 1168998) so we should
@ -552,7 +558,9 @@ public final class IntentHelper implements BundleEventListener {
//
// Don't log the URI to prevent leaking it.
Log.w(LOGTAG, "Unable to open URI, maybe showing neterror");
callback.sendError(getUnknownProtocolErrorPageUri(intent.getData().toString()));
errorResponse.putString("uri", getUnknownProtocolErrorPageUri(intent.getData().toString()));
errorResponse.putBoolean("isFallback", false);
callback.sendError(errorResponse);
}
}

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

@ -2735,7 +2735,7 @@ var NativeWindow = {
*/
_getContextType: function(element) {
// For anchor nodes, we try to use the scheme to pick a string
if (element instanceof Ci.nsIDOMHTMLAnchorElement) {
if (ChromeUtils.getClassName(element) === "HTMLAnchorElement") {
let uri = this.makeURI(this._getLinkURL(element));
try {
return Strings.browser.GetStringFromName("browser.menu.context." + uri.scheme);
@ -2820,7 +2820,7 @@ var NativeWindow = {
// Returns a url associated with a node
_getUrl: function(node) {
if ((node instanceof Ci.nsIDOMHTMLAnchorElement && node.href) ||
if ((ChromeUtils.getClassName(node) === "HTMLAnchorElement" && node.href) ||
(node instanceof Ci.nsIDOMHTMLAreaElement && node.href)) {
return this._getLinkURL(node);
} else if (node instanceof Ci.nsIImageLoadingContent && node.currentURI) {
@ -3051,7 +3051,7 @@ var NativeWindow = {
_getLink: function(aElement) {
if (aElement.nodeType == Ci.nsIDOMNode.ELEMENT_NODE &&
((aElement instanceof Ci.nsIDOMHTMLAnchorElement && aElement.href) ||
((ChromeUtils.getClassName(aElement) === "HTMLAnchorElement" && aElement.href) ||
(aElement instanceof Ci.nsIDOMHTMLAreaElement && aElement.href) ||
aElement instanceof Ci.nsIDOMHTMLLinkElement ||
aElement.getAttributeNS(kXLinkNamespace, "type") == "simple")) {
@ -4775,7 +4775,7 @@ var BrowserEventHandler = {
_getLinkURI: function(aElement) {
if (aElement.nodeType == Ci.nsIDOMNode.ELEMENT_NODE &&
((aElement instanceof Ci.nsIDOMHTMLAnchorElement && aElement.href) ||
((ChromeUtils.getClassName(aElement) === "HTMLAnchorElement" && aElement.href) ||
(aElement instanceof Ci.nsIDOMHTMLAreaElement && aElement.href))) {
try {
return Services.io.newURI(aElement.href);

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

@ -64,6 +64,8 @@ function startup() {
"GeckoViewScroll");
ModuleManager.add("resource://gre/modules/GeckoViewTab.jsm",
"GeckoViewTab");
ModuleManager.add("resource://gre/modules/GeckoViewRemoteDebugger.jsm",
"GeckoViewRemoteDebugger");
// Move focus to the content window at the end of startup,
// so things like text selection can work properly.

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

@ -65,15 +65,20 @@ ContentDispatchChooser.prototype =
EventDispatcher.instance.sendRequestForResult(msg).then(() => {
// Java opens an app on success: take no action.
}, (uri) => {
}, (data) => {
if (data.isFallback) {
// We always want to open a fallback url
window.location.href = data.uri;
return;
}
// We couldn't open this. If this was from a click, it's likely that we just
// want this to fail silently. If the user entered this on the address bar, though,
// we want to show the neterror page.
let dwu = window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
let millis = dwu.millisSinceLastUserInput;
if (millis > 0 && millis >= 1000) {
window.location.href = uri;
window.location.href = data.uri;
}
});
}

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

@ -496,6 +496,9 @@ public class GeckoView extends LayerView {
} else {
mSettings = settings;
}
mSettings.setString(GeckoViewSettings.DEBUGGER_SOCKET_DIR,
context.getApplicationInfo().dataDir);
}
@Override

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

@ -65,6 +65,11 @@ public final class GeckoViewSettings {
public static final Key<Integer> DISPLAY_MODE =
new Key<Integer>("displayMode");
public static final Key<Boolean> USE_REMOTE_DEBUGGER =
new Key<Boolean>("useRemoteDebugger");
public static final Key<String> DEBUGGER_SOCKET_DIR =
new Key<String>("debuggerSocketDir");
private final EventDispatcher mEventDispatcher;
private final GeckoBundle mBundle;
@ -81,6 +86,9 @@ public final class GeckoViewSettings {
setBoolean(USE_PRIVATE_MODE, false);
setBoolean(USE_MULTIPROCESS, true);
setInt(DISPLAY_MODE, DisplayMode.BROWSER.value());
setBoolean(USE_REMOTE_DEBUGGER, false);
// Set in GeckoView.init().
setString(DEBUGGER_SOCKET_DIR, "");
}
/* package */ GeckoViewSettings(GeckoViewSettings settings, EventDispatcher eventDispatcher) {
@ -122,6 +130,23 @@ public final class GeckoViewSettings {
}
}
public void setString(final Key<String> key, final String value) {
synchronized (mBundle) {
final Object old = mBundle.get(key.text);
if (old != null && old.equals(value)) {
return;
}
mBundle.putString(key.text, value);
}
dispatchUpdate();
}
public String getString(final Key<String> key) {
synchronized (mBundle) {
return mBundle.getString(key.text);
}
}
/* package */ GeckoBundle asBundle() {
return mBundle;
}

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

@ -26,6 +26,7 @@ public class GeckoViewActivity extends Activity {
private static final String LOGTAG = "GeckoViewActivity";
private static final String DEFAULT_URL = "https://mozilla.org";
private static final String USE_MULTIPROCESS_EXTRA = "use_multiprocess";
private static final String USE_REMOTE_DEBUGGER_EXTRA = "use_remote_debugger";
/* package */ static final int REQUEST_FILE_PICKER = 1;
private static final int REQUEST_PERMISSIONS = 2;
@ -95,6 +96,9 @@ public class GeckoViewActivity extends Activity {
mGeckoView.getSettings().setBoolean(
GeckoViewSettings.USE_MULTIPROCESS,
intent.getBooleanExtra(USE_MULTIPROCESS_EXTRA, true));
mGeckoView.getSettings().setBoolean(
GeckoViewSettings.USE_REMOTE_DEBUGGER,
intent.getBooleanExtra(USE_REMOTE_DEBUGGER_EXTRA, false));
}
@Override

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

@ -443,10 +443,8 @@
@BINPATH@/features/*
; DevTools
#ifndef MOZ_GECKOVIEW_JAR
@BINPATH@/chrome/devtools@JAREXT@
@BINPATH@/chrome/devtools.manifest
#endif
; [Default Preferences]
; All the pref files must be part of base to prevent migration bugs

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

@ -0,0 +1,110 @@
/* 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/. */
"use strict";
this.EXPORTED_SYMBOLS = ["GeckoViewRemoteDebugger"];
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
Cu.import("resource://gre/modules/GeckoViewModule.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyGetter(this, "dump", () =>
Cu.import("resource://gre/modules/AndroidLog.jsm", {})
.AndroidLog.d.bind(null, "ViewRemoteDebugger"));
XPCOMUtils.defineLazyGetter(this, "DebuggerServer", () => {
const { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
const { DebuggerServer } = require("devtools/server/main");
return DebuggerServer;
});
function debug(aMsg) {
// dump(aMsg);
}
class GeckoViewRemoteDebugger extends GeckoViewModule {
init() {
this._isEnabled = false;
this._usbDebugger = new USBRemoteDebugger();
}
onSettingsUpdate() {
let enabled = this.settings.useRemoteDebugger;
if (enabled && !this._isEnabled) {
this.register();
} else if (!enabled) {
this.unregister();
}
}
register() {
if (!DebuggerServer.initialized) {
DebuggerServer.init();
DebuggerServer.addBrowserActors("navigator:geckoview");
DebuggerServer.registerModule(
"resource://gre/modules/dbg-browser-actors.js");
DebuggerServer.allowChromeProcess = true;
}
this._isEnabled = true;
this._usbDebugger.stop();
let windowId = this.window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils)
.outerWindowID;
let portOrPath = this.settings.debuggerSocketDir +
"/firefox-debugger-socket-" +
windowId;
this._usbDebugger.start(portOrPath);
}
unregister() {
this._isEnabled = false;
this._usbDebugger.stop();
}
}
class USBRemoteDebugger {
start(aPortOrPath) {
try {
let AuthenticatorType = DebuggerServer.Authenticators.get("PROMPT");
let authenticator = new AuthenticatorType.Server();
authenticator.allowConnection = this.allowConnection.bind(this);
this._listener = DebuggerServer.createListener();
this._listener.portOrPath = aPortOrPath;
this._listener.authenticator = authenticator;
this._listener.open();
debug(`USB remote debugger - listening on ${aPortOrPath}`);
} catch (e) {
debug("Unable to start USB debugger server: " + e);
}
}
stop() {
if (!this._listener) {
return;
}
try {
this._listener.close();
this._listener = null;
} catch (e) {
debug("Unable to stop USB debugger server: " + e);
}
}
allowConnection(aSession) {
if (!this._listener) {
return DebuggerServer.AuthenticationResult.DENY;
}
if (aSession.server.port) {
return DebuggerServer.AuthenticationResult.DENY;
}
return DebuggerServer.AuthenticationResult.ALLOW;
}
}

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

@ -22,9 +22,10 @@ function debug(aMsg) {
// Stub BrowserApp implementation for WebExtensions support.
class GeckoViewTab extends GeckoViewModule {
init() {
this.browser.tab = { id: 0 };
this.browser.tab = { id: 0, browser: this.browser };
this.window.BrowserApp = {
this.window.gBrowser = this.window.BrowserApp = {
selectedBrowser: this.browser,
tabs: [this.browser.tab],
selectedTab: this.browser.tab,

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

@ -11,6 +11,7 @@ EXTRA_JS_MODULES += [
'GeckoViewModule.jsm',
'GeckoViewNavigation.jsm',
'GeckoViewProgress.jsm',
'GeckoViewRemoteDebugger.jsm',
'GeckoViewScroll.jsm',
'GeckoViewSettings.jsm',
'GeckoViewTab.jsm',

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

@ -880,6 +880,7 @@ pref("gfx.webrender.blob-images", false);
// WebRender debugging utilities.
pref("gfx.webrender.debug.texture-cache", false);
pref("gfx.webrender.debug.render-targets", false);
pref("gfx.webrender.debug.alpha-primitives", false);
pref("gfx.webrender.debug.profiler", false);
// Whether webrender should be used as much as possible.
@ -5075,12 +5076,6 @@ pref("dom.battery.enabled", true);
// Streams API
pref("dom.streams.enabled", false);
// Abort API
pref("dom.abortController.enabled", true);
// Fetch + Abort API
pref("dom.abortController.fetch.enabled", true);
// Push
pref("dom.push.enabled", false);

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

@ -2326,9 +2326,9 @@ toolbar#nav-bar {
"""
# Number of times to repeat test(s) when running with --repeat
VERIFY_REPEAT = 20
VERIFY_REPEAT = 10
# Number of times to repeat test(s) when running test in
VERIFY_REPEAT_SINGLE_BROWSER = 10
VERIFY_REPEAT_SINGLE_BROWSER = 5
def step1():
stepOptions = copy.deepcopy(options)
@ -2352,12 +2352,41 @@ toolbar#nav-bar {
break
return result
def step3():
stepOptions = copy.deepcopy(options)
stepOptions.repeat = VERIFY_REPEAT
stepOptions.keep_open = False
stepOptions.environment.append("MOZ_CHAOSMODE=3")
result = self.runTests(stepOptions)
result = result or (-2 if self.countfail > 0 else 0)
self.message_logger.finish()
return result
def step4():
stepOptions = copy.deepcopy(options)
stepOptions.repeat = 0
stepOptions.keep_open = False
stepOptions.environment.append("MOZ_CHAOSMODE=3")
for i in xrange(VERIFY_REPEAT_SINGLE_BROWSER):
result = self.runTests(stepOptions)
result = result or (-2 if self.countfail > 0 else 0)
self.message_logger.finish()
if result != 0:
break
return result
steps = [
("1. Run each test %d times in one browser." % VERIFY_REPEAT,
step1),
("2. Run each test %d times in a new browser each time." %
VERIFY_REPEAT_SINGLE_BROWSER,
step2),
("3. Run each test %d times in one browser, in chaos mode." %
VERIFY_REPEAT,
step3),
("4. Run each test %d times in a new browser each time, "
"in chaos mode." % VERIFY_REPEAT_SINGLE_BROWSER,
step4),
]
stepResults = {}

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

@ -101,8 +101,8 @@ def create_parser(mach_interface=False):
add_arg('--geckoProfileEntries', dest="gecko_profile_entries", type=int,
help="How many samples to take with the profiler")
add_arg('--extension', dest='extensions', action='append',
default=['${talos}/talos-powers/talos-powers-signed.xpi',
'${talos}/pageloader/pageloader-signed.xpi'],
default=['${talos}/talos-powers',
'${talos}/pageloader'],
help="Extension to install while running")
add_arg('--fast', action='store_true',
help="Run tp tests as tp_fast")

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

@ -194,7 +194,9 @@ DEFAULTS = dict(
'identity.fxaccounts.migrateToDevEdition': False,
'plugin.state.flash': 0,
'media.libavcodec.allow-obsolete': True,
'extensions.legacy.enabled': True
'extensions.legacy.enabled': True,
'xpinstall.signatures.required': False,
'extensions.allow-non-mpc-extensions': True
}
)

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