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) if (!mDocument)
return; return;
// Wait until an update, we have started, or an interruptible reflow is
// finished.
if (mObservingState == eRefreshProcessing || if (mObservingState == eRefreshProcessing ||
mObservingState == eRefreshProcessingForUpdate) mObservingState == eRefreshProcessingForUpdate ||
mPresShell->IsReflowInterrupted()) {
return; return;
}
// Any generic notifications should be queued if we're processing content // Any generic notifications should be queued if we're processing content
// insertions or generic notifications. // insertions or generic notifications.

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

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

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

@ -5,7 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
pref("startup.homepage_override_url", ""); 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", ""); pref("startup.homepage_welcome_url.additional", "");
// The time interval between checks for a new version (in seconds) // The time interval between checks for a new version (in seconds)
pref("app.update.interval", 28800); // 8 hours pref("app.update.interval", 28800); // 8 hours

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

@ -12,6 +12,10 @@ var Cu = Components.utils;
const DISTRIBUTION_CUSTOMIZATION_COMPLETE_TOPIC = const DISTRIBUTION_CUSTOMIZATION_COMPLETE_TOPIC =
"distribution-customization-complete"; "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/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Preferences", XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
@ -20,37 +24,65 @@ XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
"resource://gre/modules/PlacesUtils.jsm"); "resource://gre/modules/PlacesUtils.jsm");
this.DistributionCustomizer = function DistributionCustomizer() { 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 = { 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() { get _ini() {
let ini = null; let ini = null;
try { try {
if (this._iniFile) { if (this._hasDistributionIni) {
ini = Cc["@mozilla.org/xpcom/ini-parser-factory;1"]. ini = Cc["@mozilla.org/xpcom/ini-parser-factory;1"].
getService(Ci.nsIINIParserFactory). getService(Ci.nsIINIParserFactory).
createINIParser(this._iniFile); createINIParser(this._iniFile);
} }
} catch (e) { } catch (e) {
// Unable to parse INI. if (e.result == Cr.NS_ERROR_FILE_NOT_FOUND) {
Cu.reportError("Unable to parse distribution.ini"); // 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); this.__defineGetter__("_ini", () => ini);
return this._ini; return this._ini;

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

@ -86,6 +86,7 @@ do_register_cleanup(function() {
distDir.append("distribution"); distDir.append("distribution");
distDir.remove(true); distDir.remove(true);
Assert.ok(!distDir.exists()); Assert.ok(!distDir.exists());
Services.prefs.clearUserPref("distribution.testing.loadFromProfile");
}); });
add_task(async function() { 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 distribution.ini
data/engine-de-DE.xml data/engine-de-DE.xml
[test_distribution.js]
[test_browserGlue_migration_loop_cleanup.js] [test_browserGlue_migration_loop_cleanup.js]
[test_distribution.js]
[test_distribution_cachedexistence.js]

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

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

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

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

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

@ -747,4 +747,3 @@ var WasmDisassembler = (function () {
return WasmDisassembler; return WasmDisassembler;
}()); }());
exports.WasmDisassembler = 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)); 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. * Returns a grip for this actor for returning in a protocol message.
*/ */
grip: function () { grip: function () {
this.hooks.incrementGripDepth();
let g = { let g = {
"type": "object", "type": "object",
"actor": this.actorID "actor": this.actorID
}; };
// If it's a proxy, lie and tell that it belongs to an invented "Proxy" class. // Check if the object has a wrapper which denies access. It may be a CPOW or a
// The `isProxy` function detects them even behind non-opaque security wrappers, // security wrapper. Change the class so that this will be visible in the UI.
// which is useful to avoid running proxy traps through transparent wrappers. let unwrapped = unwrap(this.obj);
if (isProxy(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"; g.class = "Proxy";
} else { } else {
try { g.class = this.obj.class;
g.class = this.obj.class; g.extensible = this.obj.isExtensible();
g.extensible = this.obj.isExtensible(); g.frozen = this.obj.isFrozen();
g.frozen = this.obj.isFrozen(); g.sealed = this.obj.isSealed();
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.
}
} }
// Changing the class so that CPOWs will be visible in the UI if (g.class == "Promise") {
let isCPOW = DevToolsUtils.isCPOW(this.obj); g.promiseState = this._createPromiseState();
if (isCPOW) {
g.class = "CPOW: " + g.class;
} }
if (g.class != "DeadObject" && !isCPOW) { // FF40+: Allow to know how many properties an object has to lazily display them
if (g.class == "Promise") { // when there is a bunch.
g.promiseState = this._createPromiseState(); 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 let raw = this.obj.unsafeDereference();
// to lazily display them when there is a bunch.
// Throws on some MouseEvent object in tests. // 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 { try {
if (TYPED_ARRAY_CLASSES.indexOf(g.class) != -1) { if (fn(this, g, raw)) {
// Bug 1348761: getOwnPropertyNames is unecessary slow on TypedArrays break;
let length = DevToolsUtils.getProperty(this.obj, "length");
g.ownPropertyLength = length;
} else if (g.class != "Proxy") {
g.ownPropertyLength = this.obj.getOwnPropertyNames().length;
} }
} catch (e) { } catch (e) {
// ignored let msg = "ObjectActor.prototype.grip previewer function";
} DevToolsUtils.reportException(msg, e);
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);
}
} }
} }
@ -290,20 +289,20 @@ ObjectActor.prototype = {
onPrototypeAndProperties: function () { onPrototypeAndProperties: function () {
let ownProperties = Object.create(null); let ownProperties = Object.create(null);
let ownSymbols = []; let ownSymbols = [];
let names;
let symbols; // Inaccessible, proxy and dead objects should not be accessed.
try { let unwrapped = unwrap(this.obj);
names = this.obj.getOwnPropertyNames(); if (!unwrapped || unwrapped.isProxy || this.obj.class == "DeadObject") {
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.
return { from: this.actorID, return { from: this.actorID,
prototype: this.hooks.createValueGrip(null), prototype: this.hooks.createValueGrip(null),
ownProperties, ownProperties,
ownSymbols, ownSymbols,
safeGetterValues: Object.create(null) }; safeGetterValues: Object.create(null) };
} }
let names = this.obj.getOwnPropertyNames();
let symbols = this.obj.getOwnPropertySymbols();
for (let name of names) { for (let name of names) {
ownProperties[name] = this._propertyDescriptor(name); ownProperties[name] = this._propertyDescriptor(name);
} }
@ -340,8 +339,9 @@ ObjectActor.prototype = {
let obj = this.obj; let obj = this.obj;
let level = 0, i = 0; let level = 0, i = 0;
// Do not search safe getters in proxy objects. // Do not search safe getters in inaccessible nor proxy objects.
if (isProxy(obj)) { let unwrapped = unwrap(obj);
if (!unwrapped || unwrapped.isProxy) {
return safeGetterValues; return safeGetterValues;
} }
@ -355,8 +355,13 @@ ObjectActor.prototype = {
level++; level++;
} }
// Stop iterating when the prototype chain ends or a proxy is found. while (obj) {
while (obj && !isProxy(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); let getters = this._findSafeGetters(obj);
for (let name of getters) { for (let name of getters) {
// Avoid overwriting properties from prototypes closer to this.obj. Also // 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. * Removes all the non-opaque security wrappers of a debuggee object.
* Non-opaque security wrappers are unwrapped first before the check. * Returns null if some wrapper can't be removed.
* *
* @param obj Debugger.Object * @param obj Debugger.Object
* The debuggee object to be checked. * The debuggee object to be unwrapped.
*/ */
function isProxy(obj) { function unwrap(obj) {
// Check if the object is a proxy without security wrappers. // Check if `obj` has an opaque wrapper.
if (obj.isProxy) {
return true;
}
// No need to remove opaque wrappers since they prevent proxy traps from running.
if (obj.class === "Opaque") { if (obj.class === "Opaque") {
return false; return obj;
} }
// Attempt to unwrap. If the debugger can't unwrap, then proxy traps won't be // Attempt to unwrap. If this operation is not allowed, it may return null or throw.
// allowed to run either, so the object can be safely assumed to not be a proxy.
let unwrapped; let unwrapped;
try { try {
unwrapped = obj.unwrap(); unwrapped = obj.unwrap();
} catch (err) { } catch (err) {
return false; unwrapped = null;
} }
// Check if further unwrapping is not possible.
if (!unwrapped || unwrapped === obj) { if (!unwrapped || unwrapped === obj) {
return false; return unwrapped;
} }
// Recursively check whether the unwrapped object is a proxy. // Recursively remove additional security wrappers.
return isProxy(unwrapped); return unwrap(unwrapped);
} }
exports.ObjectActor = ObjectActor; exports.ObjectActor = ObjectActor;

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

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

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

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

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

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

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

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

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

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

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

@ -22,44 +22,6 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AbortController)
NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END 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> /* static */ already_AddRefed<AbortController>
AbortController::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv) AbortController::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
{ {

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

@ -26,12 +26,6 @@ public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(AbortController) 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> static already_AddRefed<AbortController>
Constructor(const GlobalObject& aGlobal, ErrorResult& aRv); 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] [DEFAULT]
support-files = support-files =
file_abort_controller.html
file_abort_controller_fetch.html
worker_abort_controller_fetch.js worker_abort_controller_fetch.js
slow.sjs slow.sjs

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

@ -12,27 +12,61 @@
<body> <body>
<script class="testbody" type="text/javascript"> <script class="testbody" type="text/javascript">
SpecialPowers.pushPrefEnv({"set": [["dom.abortController.enabled", true ]]}, () => { function testWebIDL() {
let ifr = document.createElement("iframe"); ok("AbortController" in self, "We have a AbortController prototype");
ifr.src = "file_abort_controller.html"; ok("AbortSignal" in self, "We have a AbortSignal prototype");
document.body.appendChild(ifr);
window.onmessage = function(e) { var ac = new AbortController();
if (e.data.type == "finish") { ok(!!ac, "AbortController can be created");
SimpleTest.finish(); ok(ac instanceof AbortController, "AbortController is a AbortController");
return;
}
if (e.data.type == "check") { ok(!!ac.signal, "AbortController has a signal");
ok(e.data.status, e.data.message); ok(ac.signal instanceof AbortSignal, "abortSignal is a AbortSignal");
return; 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(); SimpleTest.waitForExplicitFinish();
next();
</script> </script>
</body> </body>

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

@ -12,28 +12,68 @@
<body> <body>
<script class="testbody" type="text/javascript"> <script class="testbody" type="text/javascript">
SpecialPowers.pushPrefEnv({"set": [["dom.abortController.enabled", true ], function testAbortedFetch() {
["dom.abortController.fetch.enabled", true]]}, () => { var ac = new AbortController();
let ifr = document.createElement("iframe"); ac.abort();
ifr.src = "file_abort_controller_fetch.html";
document.body.appendChild(ifr);
window.onmessage = function(e) { fetch("slow.sjs", { signal: ac.signal }).then(() => {
if (e.data.type == "finish") { ok(false, "Fetch should not return a resolved promise");
SimpleTest.finish(); }, e => {
return; is(e.name, "AbortError", "We have an abort error");
} }).then(next);
}
if (e.data.type == "check") { function testFetchAndAbort() {
ok(e.data.status, e.data.message); var ac = new AbortController();
return;
}
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(); SimpleTest.waitForExplicitFinish();
next();
</script> </script>
</body> </body>

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

@ -244,16 +244,6 @@ DoesNotParticipateInAutoDirection(const Element* aElement)
aElement->IsInAnonymousSubtree()); 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 * 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 * affect the direction of ancestors with dir=auto (though it may affect its own
@ -263,7 +253,7 @@ static bool
DoesNotAffectDirectionOfAncestors(const Element* aElement) DoesNotAffectDirectionOfAncestors(const Element* aElement)
{ {
return (DoesNotParticipateInAutoDirection(aElement) || return (DoesNotParticipateInAutoDirection(aElement) ||
IsBdiWithoutDirAuto(aElement) || aElement->IsHTMLElement(nsGkAtoms::bdi) ||
aElement->HasFixedDir()); 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 load 1383780.html
pref(clipboard.autocopy,true) load 1385272-1.html pref(clipboard.autocopy,true) load 1385272-1.html
load 1393806.html load 1393806.html
load 1400701.html

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

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

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

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

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

@ -8,10 +8,11 @@
#include "IPCBlobInputStreamChild.h" #include "IPCBlobInputStreamChild.h"
#include "IPCBlobInputStreamStorage.h" #include "IPCBlobInputStreamStorage.h"
#include "mozilla/ipc/InputStreamParams.h" #include "mozilla/ipc/InputStreamParams.h"
#include "IPCBlobInputStreamThread.h"
#include "nsIAsyncInputStream.h" #include "nsIAsyncInputStream.h"
#include "nsIStreamTransportService.h" #include "nsIAsyncOutputStream.h"
#include "nsITransport.h" #include "nsIPipe.h"
#include "nsNetCID.h" #include "nsStreamUtils.h"
#include "nsStringStream.h" #include "nsStringStream.h"
#include "SlicedInputStream.h" #include "SlicedInputStream.h"
@ -20,8 +21,6 @@ namespace dom {
namespace { namespace {
static NS_DEFINE_CID(kStreamTransportServiceCID, NS_STREAMTRANSPORTSERVICE_CID);
class InputStreamCallbackRunnable final : public CancelableRunnable class InputStreamCallbackRunnable final : public CancelableRunnable
{ {
public: public:
@ -247,7 +246,7 @@ IPCBlobInputStream::Close()
} }
if (mAsyncRemoteStream) { if (mAsyncRemoteStream) {
mAsyncRemoteStream->Close(); mAsyncRemoteStream->CloseWithStatus(NS_BASE_STREAM_CLOSED);
mAsyncRemoteStream = nullptr; mAsyncRemoteStream = nullptr;
} }
@ -503,7 +502,7 @@ IPCBlobInputStream::OnInputStreamReady(nsIAsyncInputStream* aStream)
nsCOMPtr<nsIEventTarget> callbackEventTarget; nsCOMPtr<nsIEventTarget> callbackEventTarget;
callbackEventTarget.swap(mInputStreamCallbackEventTarget); callbackEventTarget.swap(mInputStreamCallbackEventTarget);
// This must be the last operation because the execution of the callback can // This must be the last operation because the execution of the callback can
// be synchronous. // be synchronous.
InputStreamCallbackRunnable::Execute(callback, callbackEventTarget, this); InputStreamCallbackRunnable::Execute(callback, callbackEventTarget, this);
@ -643,30 +642,29 @@ IPCBlobInputStream::EnsureAsyncRemoteStream()
nsCOMPtr<nsIAsyncInputStream> asyncStream = do_QueryInterface(mRemoteStream); nsCOMPtr<nsIAsyncInputStream> asyncStream = do_QueryInterface(mRemoteStream);
if (!asyncStream || !nonBlocking) { if (!asyncStream || !nonBlocking) {
nsCOMPtr<nsIStreamTransportService> sts = // Let's make the stream async using the DOMFile thread.
do_GetService(kStreamTransportServiceCID, &rv); nsCOMPtr<nsIAsyncInputStream> pipeIn;
nsCOMPtr<nsIAsyncOutputStream> pipeOut;
rv = NS_NewPipe2(getter_AddRefs(pipeIn),
getter_AddRefs(pipeOut),
true, true);
if (NS_WARN_IF(NS_FAILED(rv))) { if (NS_WARN_IF(NS_FAILED(rv))) {
return rv; return rv;
} }
nsCOMPtr<nsITransport> transport; RefPtr<IPCBlobInputStreamThread> thread =
rv = sts->CreateInputTransport(mRemoteStream, IPCBlobInputStreamThread::GetOrCreate();
/* aCloseWhenDone */ true, if (NS_WARN_IF(!thread)) {
getter_AddRefs(transport)); return NS_ERROR_FAILURE;
}
rv = NS_AsyncCopy(mRemoteStream, pipeOut, thread,
NS_ASYNCCOPY_VIA_WRITESEGMENTS);
if (NS_WARN_IF(NS_FAILED(rv))) { if (NS_WARN_IF(NS_FAILED(rv))) {
return rv; return rv;
} }
nsCOMPtr<nsIInputStream> wrapper; asyncStream = pipeIn;
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);
} }
MOZ_ASSERT(asyncStream); MOZ_ASSERT(asyncStream);

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

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

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

@ -36,7 +36,7 @@ public:
{ {
mozilla::StaticMutexAutoLock lock(gIPCBlobThreadMutex); mozilla::StaticMutexAutoLock lock(gIPCBlobThreadMutex);
MOZ_ASSERT(gIPCBlobThread); MOZ_ASSERT(gIPCBlobThread);
gIPCBlobThread->Initialize(); gIPCBlobThread->InitializeOnMainThread();
return NS_OK; return NS_OK;
} }
}; };
@ -93,7 +93,7 @@ NS_IMPL_ISUPPORTS_INHERITED(MigrateActorRunnable, Runnable,
} // anonymous } // anonymous
NS_IMPL_ISUPPORTS(IPCBlobInputStreamThread, nsIObserver) NS_IMPL_ISUPPORTS(IPCBlobInputStreamThread, nsIObserver, nsIEventTarget)
/* static */ bool /* static */ bool
IPCBlobInputStreamThread::IsOnFileEventTarget(nsIEventTarget* aEventTarget) IPCBlobInputStreamThread::IsOnFileEventTarget(nsIEventTarget* aEventTarget)
@ -115,36 +115,21 @@ IPCBlobInputStreamThread::GetOrCreate()
if (!gIPCBlobThread) { if (!gIPCBlobThread) {
gIPCBlobThread = new IPCBlobInputStreamThread(); gIPCBlobThread = new IPCBlobInputStreamThread();
gIPCBlobThread->Initialize(); if (!gIPCBlobThread->Initialize()) {
return nullptr;
}
} }
return gIPCBlobThread; return gIPCBlobThread;
} }
void bool
IPCBlobInputStreamThread::Initialize() 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; 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))) { if (NS_WARN_IF(NS_FAILED(rv))) {
return; return false;
} }
mThread = thread; mThread = thread;
@ -156,6 +141,32 @@ IPCBlobInputStreamThread::Initialize()
mPendingActors.Clear(); 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 NS_IMETHODIMP
@ -205,5 +216,48 @@ IPCBlobInputStreamThread::MigrateActorInternal(IPCBlobInputStreamChild* aActor)
mThread->Dispatch(runnable, NS_DISPATCH_NORMAL); 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 } // dom namespace
} // mozilla namespace } // mozilla namespace

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

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

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

@ -58,10 +58,13 @@ HTMLAnchorElement::IsInteractiveHTMLContent(bool aIgnoreTabindex) const
nsGenericHTMLElement::IsInteractiveHTMLContent(aIgnoreTabindex); nsGenericHTMLElement::IsInteractiveHTMLContent(aIgnoreTabindex);
} }
NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED(HTMLAnchorElement, NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLAnchorElement)
nsGenericHTMLElement, NS_INTERFACE_TABLE_INHERITED(HTMLAnchorElement,
nsIDOMHTMLAnchorElement, Link)
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) NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLAnchorElement)
@ -83,17 +86,6 @@ HTMLAnchorElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
return HTMLAnchorElementBinding::Wrap(aCx, this, 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 int32_t
HTMLAnchorElement::TabIndexDefault() HTMLAnchorElement::TabIndexDefault()
{ {
@ -268,19 +260,12 @@ HTMLAnchorElement::GetLinkTarget(nsAString& aTarget)
} }
} }
NS_IMETHODIMP void
HTMLAnchorElement::GetTarget(nsAString& aValue) HTMLAnchorElement::GetTarget(nsAString& aValue)
{ {
if (!GetAttr(kNameSpaceID_None, nsGkAtoms::target, aValue)) { if (!GetAttr(kNameSpaceID_None, nsGkAtoms::target, aValue)) {
GetBaseTarget(aValue); GetBaseTarget(aValue);
} }
return NS_OK;
}
NS_IMETHODIMP
HTMLAnchorElement::SetTarget(const nsAString& aValue)
{
return SetAttr(kNameSpaceID_None, nsGkAtoms::target, aValue, true);
} }
nsDOMTokenList* nsDOMTokenList*
@ -292,64 +277,26 @@ HTMLAnchorElement::RelList()
return mRelList; return mRelList;
} }
#define IMPL_URI_PART(_part) \ void
NS_IMETHODIMP \ HTMLAnchorElement::GetText(nsAString& aText, mozilla::ErrorResult& aRv)
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)
{ {
if(!nsContentUtils::GetNodeTextContent(this, true, aText, fallible)) { if (NS_WARN_IF(!nsContentUtils::GetNodeTextContent(this, true, aText, fallible))) {
return NS_ERROR_OUT_OF_MEMORY; aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
} }
return NS_OK;
} }
NS_IMETHODIMP void
HTMLAnchorElement::SetText(const nsAString& aText) 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) HTMLAnchorElement::ToString(nsAString& aSource)
{ {
return GetHref(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> already_AddRefed<nsIURI>
HTMLAnchorElement::GetHrefURI() const HTMLAnchorElement::GetHrefURI() const
{ {

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

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

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

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

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

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

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

@ -8,7 +8,6 @@ with Files("**"):
BUG_COMPONENT = ("Core", "DOM") BUG_COMPONENT = ("Core", "DOM")
XPIDL_SOURCES += [ XPIDL_SOURCES += [
'nsIDOMHTMLAnchorElement.idl',
'nsIDOMHTMLAreaElement.idl', 'nsIDOMHTMLAreaElement.idl',
'nsIDOMHTMLBaseElement.idl', 'nsIDOMHTMLBaseElement.idl',
'nsIDOMHTMLButtonElement.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) #if defined(XP_WIN) && defined(ACCESSIBILITY)
#include "mozilla/a11y/AccessibleWrap.h" #include "mozilla/a11y/AccessibleWrap.h"
#include "mozilla/a11y/Compatibility.h"
#include "mozilla/a11y/nsWinUtils.h" #include "mozilla/a11y/nsWinUtils.h"
#endif #endif
@ -2894,6 +2895,23 @@ TabParent::SetDocShellIsActive(bool isActive)
mDocShellIsActive = isActive; mDocShellIsActive = isActive;
Unused << SendSetDocShellIsActive(isActive, mPreserveLayers, mLayerTreeEpoch); 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 // Let's inform the priority manager. This operation can end up with the
// changing of the process priority. // changing of the process priority.
ProcessPriorityManager::TabActivityChanged(this, isActive); ProcessPriorityManager::TabActivityChanged(this, isActive);

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

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

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

@ -49,7 +49,7 @@ skip-if = toolkit == 'android' # android(Bug 1189784, timeouts on 4.3 emulator),
[test_getUserMedia_addTrackRemoveTrack.html] [test_getUserMedia_addTrackRemoveTrack.html]
skip-if = android_version == '18' || os == 'linux' # android(Bug 1189784, timeouts on 4.3 emulator), linux bug 1377450 skip-if = android_version == '18' || os == 'linux' # android(Bug 1189784, timeouts on 4.3 emulator), linux bug 1377450
[test_getUserMedia_addtrack_removetrack_events.html] [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_basicAudio.html]
[test_getUserMedia_basicVideo.html] [test_getUserMedia_basicVideo.html]
[test_getUserMedia_basicVideo_playAfterLoadedmetadata.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-1.svg
load 1347617-2.svg load 1347617-2.svg
load 1347617-3.svg load 1347617-3.svg
load 1402798.html

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

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

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

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

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

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

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

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

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

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

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

@ -27,8 +27,7 @@ interface Request {
readonly attribute RequestRedirect redirect; readonly attribute RequestRedirect redirect;
readonly attribute DOMString integrity; readonly attribute DOMString integrity;
[Func="AbortController::IsEnabledInFetch", [BinaryName="getOrCreateSignal"]
BinaryName="getOrCreateSignal"]
readonly attribute AbortSignal signal; readonly attribute AbortSignal signal;
[Throws, [Throws,
@ -52,7 +51,6 @@ dictionary RequestInit {
RequestRedirect redirect; RequestRedirect redirect;
DOMString integrity; DOMString integrity;
[Func="AbortController::IsEnabledInFetch"]
AbortSignal? signal; AbortSignal? signal;
[Func="FetchObserver::IsEnabled"] [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("gfx.offscreencanvas.enabled", OffscreenCanvasEnabled, OFFSCREENCANVAS_ENABLED)
WORKER_SIMPLE_PREF("dom.webkitBlink.dirPicker.enabled", WebkitBlinkDirectoryPickerEnabled, DOM_WEBKITBLINK_DIRPICKER_WEBKITBLINK) 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.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("dom.fetchObserver.enabled", FetchObserverEnabled, FETCHOBSERVER_ENABLED)
WORKER_SIMPLE_PREF("privacy.resistFingerprinting", ResistFingerprintingEnabled, RESISTFINGERPRINTING_ENABLED) WORKER_SIMPLE_PREF("privacy.resistFingerprinting", ResistFingerprintingEnabled, RESISTFINGERPRINTING_ENABLED)
WORKER_SIMPLE_PREF("devtools.enabled", DevToolsEnabled, DEVTOOLS_ENABLED) WORKER_SIMPLE_PREF("devtools.enabled", DevToolsEnabled, DEVTOOLS_ENABLED)

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

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

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

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

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

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

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

@ -608,10 +608,6 @@ GLBlitHelper::BlitImageToFramebuffer(layers::Image* srcImage,
case ImageFormat::SURFACE_TEXTURE: case ImageFormat::SURFACE_TEXTURE:
return BlitImage(static_cast<layers::SurfaceTextureImage*>(srcImage), destSize, return BlitImage(static_cast<layers::SurfaceTextureImage*>(srcImage), destSize,
destOrigin); destOrigin);
case ImageFormat::EGLIMAGE:
return BlitImage(static_cast<layers::EGLImageImage*>(srcImage), destSize,
destOrigin);
#endif #endif
#ifdef XP_MACOSX #ifdef XP_MACOSX
case ImageFormat::MAC_IOSURFACE: case ImageFormat::MAC_IOSURFACE:
@ -647,41 +643,6 @@ GLBlitHelper::BlitImage(layers::SurfaceTextureImage* srcImage, const gfx::IntSiz
gfxCriticalError() << "BlitImage(SurfaceTextureImage) not implemented."; gfxCriticalError() << "BlitImage(SurfaceTextureImage) not implemented.";
return false; 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 #endif
// ------------------------------------- // -------------------------------------

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

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

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

@ -16,35 +16,6 @@ namespace layers {
static RefPtr<GLContext> sSnapshotContext; 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> already_AddRefed<gfx::SourceSurface>
GLImage::GetAsSourceSurface() 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 #ifdef MOZ_WIDGET_ANDROID
class SurfaceTextureImage : public GLImage { class SurfaceTextureImage : public GLImage {

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

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

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

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

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

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

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

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

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

@ -17,62 +17,6 @@ namespace layers {
class CompositableForwarder; 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 // AndroidSurface

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

@ -20,34 +20,6 @@ namespace mozilla {
namespace layers { 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 #ifdef MOZ_WIDGET_ANDROID
class AndroidSurfaceTextureData : public TextureData class AndroidSurfaceTextureData : public TextureData

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

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

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

@ -600,7 +600,7 @@ UnknownPropertyStub(JSContext* cx, HandleObject obj, HandleId id, MutableHandleV
} }
bool bool
UnknownStrictPropertyStub(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp, UnknownStrictPropertyStub(JSContext* cx, HandleObject obj, HandleId id, HandleValue v,
ObjectOpResult& result) ObjectOpResult& result)
{ {
JS_ReportErrorASCII(cx, "setter could not be wrapped via CPOWs"); 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 * 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 * 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 * (Unicode property identifier) or an int (element index).
* parameter, on success, is the new property value after the
* set.
*/ */
typedef bool typedef bool
(* JSSetterOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, (* 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. * Delete a property named by id in obj.

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

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

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

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

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

@ -613,13 +613,6 @@ struct JSContext : public JS::RootingContext,
js::ThreadLocalData<uint32_t> debuggerMutations; 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(). // Cache for jit::GetPcScript().
js::ThreadLocalData<js::jit::PcScriptCache*> ionPcScriptCache; js::ThreadLocalData<js::jit::PcScriptCache*> ionPcScriptCache;

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

@ -365,14 +365,14 @@ CallJSGetterOp(JSContext* cx, GetterOp op, HandleObject obj, HandleId id,
} }
MOZ_ALWAYS_INLINE bool 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) ObjectOpResult& result)
{ {
if (!CheckRecursionLimit(cx)) if (!CheckRecursionLimit(cx))
return false; return false;
assertSameCompartment(cx, obj, id, vp); assertSameCompartment(cx, obj, id, v);
return op(cx, obj, id, vp, result); return op(cx, obj, id, v, result);
} }
inline bool inline bool

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

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

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

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

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

@ -2503,22 +2503,8 @@ NativeSetExistingDataProperty(JSContext* cx, HandleNativeObject obj, HandleShape
MOZ_ASSERT(!obj->is<WithEnvironmentObject>()); // See bug 1128681. MOZ_ASSERT(!obj->is<WithEnvironmentObject>()); // See bug 1128681.
uint32_t sample = cx->propertyRemovals;
RootedId id(cx, shape->propid()); RootedId id(cx, shape->propid());
RootedValue value(cx, v); return CallJSSetterOp(cx, shape->setterOp(), obj, id, v, result);
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.
} }
/* /*
@ -2729,8 +2715,7 @@ SetExistingProperty(JSContext* cx, HandleNativeObject obj, HandleId id, HandleVa
if (shape->hasDefaultSetter()) if (shape->hasDefaultSetter())
return result.succeed(); return result.succeed();
RootedValue valCopy(cx, v); return CallJSSetterOp(cx, shape->setterOp(), obj, id, v, result);
return CallJSSetterOp(cx, shape->setterOp(), obj, id, &valCopy, result);
} }
// Shadow pobj[id] by defining a new data property receiver[id]. // 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 * to will botch an assertion in JSObject::freeSlot) if the new last
* property (shape here) has a slotSpan that does not cover it. * property (shape here) has a slotSpan that does not cover it.
*/ */
if (hadSlot && !shape->hasSlot()) { if (hadSlot && !shape->hasSlot() && oldSlot < obj->slotSpan())
if (oldSlot < obj->slotSpan()) obj->freeSlot(cx, oldSlot);
obj->freeSlot(cx, oldSlot);
/* Note: The optimization based on propertyRemovals is only relevant to the active thread. */
if (!cx->helperThread())
++cx->propertyRemovals;
}
obj->checkShapeConsistency(); 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 has a slot, free its slot number. */
if (shape->hasSlot()) { if (shape->hasSlot())
obj->freeSlot(cx, shape->slot()); obj->freeSlot(cx, shape->slot());
if (!cx->helperThread())
++cx->propertyRemovals;
}
/* /*
* A dictionary-mode object owns mutable, unique shapes on a non-circular * 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)); JS_ALWAYS_TRUE(obj->setLastProperty(cx, shape));
if (!cx->helperThread())
++cx->propertyRemovals;
obj->checkShapeConsistency(); obj->checkShapeConsistency();
} }

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

@ -440,14 +440,14 @@ sandbox_moved(JSObject* obj, JSObject* old)
static bool static bool
writeToProto_setProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, 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); RootedObject proto(cx);
if (!JS_GetPrototype(cx, obj, &proto)) if (!JS_GetPrototype(cx, obj, &proto))
return false; return false;
RootedValue receiver(cx, ObjectValue(*proto)); 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 static bool

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

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

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

@ -1581,6 +1581,21 @@ public:
mFontSizeInflationEnabledIsDirty = true; 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. // Approximate frame visibility tracking public API.
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -1794,7 +1809,8 @@ protected:
bool mIsFirstPaint : 1; bool mIsFirstPaint : 1;
bool mObservesMutationsForPrint : 1; bool mObservesMutationsForPrint : 1;
bool mSuppressInterruptibleReflows : 1; // Whether the most recent interruptible reflow was actually interrupted:
bool mWasLastReflowInterrupted : 1;
bool mScrollPositionClampingScrollPortSizeSet : 1; bool mScrollPositionClampingScrollPortSizeSet : 1;
// True if a layout flush might not be a no-op // 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); nsCOMPtr<nsIPresShell> shellKungFuDeathGrip(shell);
shell->mObservingLayoutFlushes = false; shell->mObservingLayoutFlushes = false;
shell->mSuppressInterruptibleReflows = false; shell->mWasLastReflowInterrupted = false;
FlushType flushType = HasPendingAnimations(shell) FlushType flushType = HasPendingAnimations(shell)
? FlushType::Layout ? FlushType::Layout
: FlushType::InterruptibleLayout; : FlushType::InterruptibleLayout;

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

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

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

@ -104,7 +104,6 @@ static const char kPrintingPromptService[] = "@mozilla.org/embedcomp/printingpro
#include "nsILayoutHistoryState.h" #include "nsILayoutHistoryState.h"
#include "nsFrameManager.h" #include "nsFrameManager.h"
#include "mozilla/ReflowInput.h" #include "mozilla/ReflowInput.h"
#include "nsIDOMHTMLAnchorElement.h"
#include "nsIDOMHTMLAreaElement.h" #include "nsIDOMHTMLAreaElement.h"
#include "nsIDOMHTMLLinkElement.h" #include "nsIDOMHTMLLinkElement.h"
#include "nsIDOMHTMLImageElement.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 == 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 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 == 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 == 508919-1.xhtml 508919-1-ref.xhtml
== 509155-1.xhtml 509155-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 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 include ../../toolkit/content/tests/reftests/reftest.list
# -moz-transform/ # -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 # 3d transforms
include transform-3d/reftest.list include transform-3d/reftest.list

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

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

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

@ -429,9 +429,9 @@ class RefTest(object):
self._populate_logger(options) self._populate_logger(options)
# Number of times to repeat test(s) when running with --repeat # 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 # 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(): def step1():
stepOptions = copy.deepcopy(options) stepOptions = copy.deepcopy(options)
@ -448,12 +448,34 @@ class RefTest(object):
break break
return result 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 = [ steps = [
("1. Run each test %d times in one browser." % VERIFY_REPEAT, ("1. Run each test %d times in one browser." % VERIFY_REPEAT,
step1), step1),
("2. Run each test %d times in a new browser each time." % ("2. Run each test %d times in a new browser each time." %
VERIFY_REPEAT_SINGLE_BROWSER, VERIFY_REPEAT_SINGLE_BROWSER,
step2), 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 = {} stepResults = {}

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

@ -484,10 +484,13 @@ public final class IntentHelper implements BundleEventListener {
*/ */
private void openNoHandler(final GeckoBundle msg, final EventCallback callback) { private void openNoHandler(final GeckoBundle msg, final EventCallback callback) {
final String uri = msg.getString("uri"); final String uri = msg.getString("uri");
final GeckoBundle errorResponse = new GeckoBundle();
if (TextUtils.isEmpty(uri)) { if (TextUtils.isEmpty(uri)) {
Log.w(LOGTAG, "Received empty URL - loading about:neterror"); Log.w(LOGTAG, "Received empty URL - loading about:neterror");
callback.sendError(getUnknownProtocolErrorPageUri("")); errorResponse.putString("uri", getUnknownProtocolErrorPageUri(""));
errorResponse.putBoolean("isFallback", false);
callback.sendError(errorResponse);
return; return;
} }
@ -505,7 +508,9 @@ public final class IntentHelper implements BundleEventListener {
// Don't log the exception to prevent leaking URIs. // Don't log the exception to prevent leaking URIs.
Log.w(LOGTAG, "Unable to parse Intent URI - loading about:neterror"); 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; return;
} }
@ -513,9 +518,10 @@ public final class IntentHelper implements BundleEventListener {
// https://developer.chrome.com/multidevice/android/intents // https://developer.chrome.com/multidevice/android/intents
final String fallbackUrl = intent.getStringExtra(EXTRA_BROWSER_FALLBACK_URL); final String fallbackUrl = intent.getStringExtra(EXTRA_BROWSER_FALLBACK_URL);
if (isFallbackUrlValid(fallbackUrl)) { if (isFallbackUrlValid(fallbackUrl)) {
errorResponse.putString("uri", fallbackUrl);
errorResponse.putBoolean("isFallback", true);
// Opens the page in JS. // Opens the page in JS.
callback.sendError(fallbackUrl); callback.sendError(errorResponse);
} else if (intent.getPackage() != null) { } else if (intent.getPackage() != null) {
// Note on alternative flows: we could get the intent package from a component, however, for // 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 // 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. // Don't log the URI to prevent leaking it.
Log.w(LOGTAG, "Unable to open URI, maybe showing neterror"); 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) { _getContextType: function(element) {
// For anchor nodes, we try to use the scheme to pick a string // 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)); let uri = this.makeURI(this._getLinkURL(element));
try { try {
return Strings.browser.GetStringFromName("browser.menu.context." + uri.scheme); return Strings.browser.GetStringFromName("browser.menu.context." + uri.scheme);
@ -2820,7 +2820,7 @@ var NativeWindow = {
// Returns a url associated with a node // Returns a url associated with a node
_getUrl: function(node) { _getUrl: function(node) {
if ((node instanceof Ci.nsIDOMHTMLAnchorElement && node.href) || if ((ChromeUtils.getClassName(node) === "HTMLAnchorElement" && node.href) ||
(node instanceof Ci.nsIDOMHTMLAreaElement && node.href)) { (node instanceof Ci.nsIDOMHTMLAreaElement && node.href)) {
return this._getLinkURL(node); return this._getLinkURL(node);
} else if (node instanceof Ci.nsIImageLoadingContent && node.currentURI) { } else if (node instanceof Ci.nsIImageLoadingContent && node.currentURI) {
@ -3051,7 +3051,7 @@ var NativeWindow = {
_getLink: function(aElement) { _getLink: function(aElement) {
if (aElement.nodeType == Ci.nsIDOMNode.ELEMENT_NODE && 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.nsIDOMHTMLAreaElement && aElement.href) ||
aElement instanceof Ci.nsIDOMHTMLLinkElement || aElement instanceof Ci.nsIDOMHTMLLinkElement ||
aElement.getAttributeNS(kXLinkNamespace, "type") == "simple")) { aElement.getAttributeNS(kXLinkNamespace, "type") == "simple")) {
@ -4775,7 +4775,7 @@ var BrowserEventHandler = {
_getLinkURI: function(aElement) { _getLinkURI: function(aElement) {
if (aElement.nodeType == Ci.nsIDOMNode.ELEMENT_NODE && 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.nsIDOMHTMLAreaElement && aElement.href))) {
try { try {
return Services.io.newURI(aElement.href); return Services.io.newURI(aElement.href);

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

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

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

@ -65,15 +65,20 @@ ContentDispatchChooser.prototype =
EventDispatcher.instance.sendRequestForResult(msg).then(() => { EventDispatcher.instance.sendRequestForResult(msg).then(() => {
// Java opens an app on success: take no action. // 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 // 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, // want this to fail silently. If the user entered this on the address bar, though,
// we want to show the neterror page. // we want to show the neterror page.
let dwu = window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils); let dwu = window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
let millis = dwu.millisSinceLastUserInput; let millis = dwu.millisSinceLastUserInput;
if (millis > 0 && millis >= 1000) { if (millis > 0 && millis >= 1000) {
window.location.href = uri; window.location.href = data.uri;
} }
}); });
} }

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

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

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

@ -65,6 +65,11 @@ public final class GeckoViewSettings {
public static final Key<Integer> DISPLAY_MODE = public static final Key<Integer> DISPLAY_MODE =
new Key<Integer>("displayMode"); 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 EventDispatcher mEventDispatcher;
private final GeckoBundle mBundle; private final GeckoBundle mBundle;
@ -81,6 +86,9 @@ public final class GeckoViewSettings {
setBoolean(USE_PRIVATE_MODE, false); setBoolean(USE_PRIVATE_MODE, false);
setBoolean(USE_MULTIPROCESS, true); setBoolean(USE_MULTIPROCESS, true);
setInt(DISPLAY_MODE, DisplayMode.BROWSER.value()); 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) { /* 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() { /* package */ GeckoBundle asBundle() {
return mBundle; return mBundle;
} }

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

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

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

@ -443,10 +443,8 @@
@BINPATH@/features/* @BINPATH@/features/*
; DevTools ; DevTools
#ifndef MOZ_GECKOVIEW_JAR
@BINPATH@/chrome/devtools@JAREXT@ @BINPATH@/chrome/devtools@JAREXT@
@BINPATH@/chrome/devtools.manifest @BINPATH@/chrome/devtools.manifest
#endif
; [Default Preferences] ; [Default Preferences]
; All the pref files must be part of base to prevent migration bugs ; 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. // Stub BrowserApp implementation for WebExtensions support.
class GeckoViewTab extends GeckoViewModule { class GeckoViewTab extends GeckoViewModule {
init() { 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], tabs: [this.browser.tab],
selectedTab: this.browser.tab, selectedTab: this.browser.tab,

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

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

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

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

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

@ -2326,9 +2326,9 @@ toolbar#nav-bar {
""" """
# Number of times to repeat test(s) when running with --repeat # 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 # Number of times to repeat test(s) when running test in
VERIFY_REPEAT_SINGLE_BROWSER = 10 VERIFY_REPEAT_SINGLE_BROWSER = 5
def step1(): def step1():
stepOptions = copy.deepcopy(options) stepOptions = copy.deepcopy(options)
@ -2352,12 +2352,41 @@ toolbar#nav-bar {
break break
return result 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 = [ steps = [
("1. Run each test %d times in one browser." % VERIFY_REPEAT, ("1. Run each test %d times in one browser." % VERIFY_REPEAT,
step1), step1),
("2. Run each test %d times in a new browser each time." % ("2. Run each test %d times in a new browser each time." %
VERIFY_REPEAT_SINGLE_BROWSER, VERIFY_REPEAT_SINGLE_BROWSER,
step2), 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 = {} stepResults = {}

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

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

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

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

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