merge mozilla-inbound to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2015-06-22 14:03:17 +02:00
commit 135b0588cd
361 changed files with 6517 additions and 4054 deletions

View File

@ -247,11 +247,11 @@ Object.defineProperties(Buffer.prototype, {
value: function(string, offset, length, encoding = 'utf8') {
// write(string, encoding);
if (typeof(offset) === 'string' && Number.isNaN(parseInt(offset))) {
([offset, length, encoding]) = [0, null, offset];
[offset, length, encoding] = [0, null, offset];
}
// write(string, offset, encoding);
else if (typeof(length) === 'string')
([length, encoding]) = [null, length];
[length, encoding] = [null, length];
if (offset < 0 || offset > this.length)
throw new RangeError('offset is outside of valid range');

View File

@ -129,7 +129,7 @@ function display(panel, options, anchor) {
let viewportRect = document.defaultView.gBrowser.getBoundingClientRect();
({x, y, width, height}) = calculateRegion(options, viewportRect);
({x, y, width, height} = calculateRegion(options, viewportRect));
}
else {
// The XUL Panel has an arrow, so the margin needs to be reset
@ -145,7 +145,7 @@ function display(panel, options, anchor) {
// chrome browser window, and therefore there is no need for this check.
if (CustomizableUI) {
let node = anchor;
({anchor}) = CustomizableUI.getWidget(anchor.id).forWindow(window);
({anchor} = CustomizableUI.getWidget(anchor.id).forWindow(window));
// if `node` is not the `anchor` itself, it means the widget is
// positioned in a panel, therefore we have to hide it before show

View File

@ -245,7 +245,7 @@ const map = (f, ...sequences) => seq(function* () {
let index = 0;
let value = void(0);
while (index < count && !done) {
({ done, value }) = inputs[index].next();
({ done, value } = inputs[index].next());
// If input is not exhausted yet store value in args.
if (!done) {
@ -273,10 +273,10 @@ const reductions = (...params) => {
let hasInitial = false;
let f, initial, source;
if (count === 2) {
([f, source]) = params;
[f, source] = params;
}
else if (count === 3) {
([f, initial, source]) = params;
[f, initial, source] = params;
hasInitial = true;
}
else {

View File

@ -222,6 +222,10 @@ pref("dom.max_script_run_time", 0);
pref("dom.max_chrome_script_run_time", 0);
pref("dom.max_child_script_run_time", 0);
// Temporarily disable support for offsetX/Y to work around Google Maps bug
// (bug 1150284)
pref("dom.mouseEvent.offsetXY.enabled", false);
// plugins
pref("plugin.disable", true);
pref("dom.ipc.plugins.enabled", true);

View File

@ -629,7 +629,7 @@ pref("browser.xul.error_pages.enabled", true);
pref("browser.xul.error_pages.expert_bad_cert", false);
// If true, network link events will change the value of navigator.onLine
pref("network.manage-offline-status", false);
pref("network.manage-offline-status", true);
// We want to make sure mail URLs are handled externally...
pref("network.protocol-handler.external.mailto", true); // for mail
@ -1952,4 +1952,5 @@ pref("view_source.tab", true);
// Enable Service Workers for desktop on non-release builds
#ifndef RELEASE_BUILD
pref("dom.serviceWorkers.enabled", true);
pref("dom.serviceWorkers.interception.enabled", true);
#endif

View File

@ -206,6 +206,10 @@ function onIndexedDBClear()
.getService(nsIQuotaManager)
.clearStoragesForURI(gPermURI);
Components.classes["@mozilla.org/serviceworkers/manager;1"]
.getService(Components.interfaces.nsIServiceWorkerManager)
.removeAndPropagate(gPermURI.host);
SitePermissions.remove(gPermURI, "indexedDB");
initIndexedDBRow();
}

View File

@ -1,4 +1,4 @@
<!DOCTYPE HTML>
<!DOCTYPE HTML>
<html>
<!--
Bug 970517 - Storage inspector front end - tests
@ -41,6 +41,7 @@ function success(event) {
window.idbGenerator = function*(callback) {
let request = indexedDB.open("idb1", 1);
request.onupgradeneeded = success;
request.onsuccess = success;
request.onerror = function(e) {
throw new Error("error opening db connection");
};
@ -60,18 +61,18 @@ window.idbGenerator = function*(callback) {
store2.add({id2: 1, name: "foo", email: "foo@bar.com", extra: "baz"}).onsuccess = success;
yield undefined;
store1.transaction.oncomplete = success;
yield undefined;
db.close();
request = indexedDB.open("idb2", 1);
request.onupgradeneeded = success;
request.onsuccess = success;
event = yield undefined;
let db2 = event.target.result;
let store3 = db2.createObjectStore("obj3", { keyPath: "id3" });
store3.createIndex("name2", "name2", { unique: true });
store3.transaction.oncomplete = success;
yield undefined;
db2.close();
console.log("added cookies and stuff from main page");

View File

@ -1,4 +1,4 @@
<!DOCTYPE HTML>
<!DOCTYPE HTML>
<html>
<!--
Bug 970517 - Storage inspector front end - tests
@ -35,6 +35,7 @@ function success(event) {
window.idbGenerator = function*(callback) {
let request = indexedDB.open("idb1", 1);
request.onupgradeneeded = success;
request.onsuccess = success;
request.onerror = function(e) {
throw new Error("error opening db connection");
};
@ -54,18 +55,18 @@ window.idbGenerator = function*(callback) {
store2.add({id2: 1, name: "foo", email: "foo@bar.com", extra: "baz"}).onsuccess = success;
yield undefined;
store1.transaction.oncomplete = success;
yield undefined;
db.close();
request = indexedDB.open("idb2", 1);
request.onupgradeneeded = success;
request.onsuccess = success;
event = yield undefined;
let db2 = event.target.result;
let store3 = db2.createObjectStore("obj3", { keyPath: "id3" });
store3.createIndex("name2", "name2", { unique: true });
store3.transaction.oncomplete = success;
yield undefined;
db2.close();
console.log("added cookies and stuff from main page");

View File

@ -1,4 +1,4 @@
<!DOCTYPE HTML>
<!DOCTYPE HTML>
<html>
<!--
Iframe for testing multiple host detetion in storage actor
@ -20,6 +20,7 @@ function success(event) {
window.idbGenerator = function*(callback) {
let request = indexedDB.open("idb-s1", 1);
request.onupgradeneeded = success;
request.onsuccess = success;
request.onerror = function(e) {
throw new Error("error opening db connection");
};
@ -31,12 +32,13 @@ window.idbGenerator = function*(callback) {
yield undefined;
store1.add({id: 7, name: "foo2", email: "foo2@bar.com"}).onsuccess = success;
yield undefined;
store1.transaction.oncomplete = success;
yield undefined;
db.close();
request = indexedDB.open("idb-s2", 1);
request.onupgradeneeded = success;
request.onsuccess = success;
event = yield undefined;
let db2 = event.target.result;
@ -44,7 +46,7 @@ window.idbGenerator = function*(callback) {
store3.createIndex("name2", "name2", { unique: true });
store3.add({id3: 16, name2: "foo", email: "foo@bar.com"}).onsuccess = success;
yield undefined;
store3.transaction.oncomplete = success;
yield undefined;
db2.close();
console.log("added cookies and stuff from secured iframe");

View File

@ -12,7 +12,7 @@ import subprocess
import sys
from automation import Automation
from devicemanager import DMError
from devicemanager import DMError, DeviceManager
from mozlog.structured import get_default_logger
import mozcrash
@ -124,8 +124,10 @@ class RemoteAutomation(Automation):
# we make it empty and writable so we can test the ANR reporter later
traces = "/data/anr/traces.txt"
try:
self._devicemanager.shellCheckOutput(['echo', '', '>', traces], root=True)
self._devicemanager.shellCheckOutput(['chmod', '666', traces], root=True)
self._devicemanager.shellCheckOutput(['echo', '', '>', traces], root=True,
timeout=DeviceManager.short_timeout)
self._devicemanager.shellCheckOutput(['chmod', '666', traces], root=True,
timeout=DeviceManager.short_timeout)
except DMError:
print "Error deleting %s" % traces
pass
@ -150,7 +152,8 @@ class RemoteAutomation(Automation):
# delete any existing tombstone files from device
remoteDir = "/data/tombstones"
try:
self._devicemanager.shellCheckOutput(['rm', '-r', remoteDir], root=True)
self._devicemanager.shellCheckOutput(['rm', '-r', remoteDir], root=True,
timeout=DeviceManager.short_timeout)
except DMError:
# This may just indicate that the tombstone directory is missing
pass
@ -165,8 +168,10 @@ class RemoteAutomation(Automation):
if self._devicemanager.dirExists(remoteDir):
# copy tombstone files from device to local blobber upload directory
try:
self._devicemanager.shellCheckOutput(['chmod', '777', remoteDir], root=True)
self._devicemanager.shellCheckOutput(['chmod', '666', os.path.join(remoteDir, '*')], root=True)
self._devicemanager.shellCheckOutput(['chmod', '777', remoteDir], root=True,
timeout=DeviceManager.short_timeout)
self._devicemanager.shellCheckOutput(['chmod', '666', os.path.join(remoteDir, '*')], root=True,
timeout=DeviceManager.short_timeout)
self._devicemanager.getDirectory(remoteDir, blobberUploadDir, False)
except DMError:
# This may just indicate that no tombstone files are present
@ -192,12 +197,7 @@ class RemoteAutomation(Automation):
self.checkForANRs()
self.checkForTombstones()
try:
logcat = self._devicemanager.getLogcat(filterOutRegexps=fennecLogcatFilters)
except DMError:
print "getLogcat threw DMError; re-trying just once..."
time.sleep(1)
logcat = self._devicemanager.getLogcat(filterOutRegexps=fennecLogcatFilters)
logcat = self._devicemanager.getLogcat(filterOutRegexps=fennecLogcatFilters)
javaException = mozcrash.check_for_java_exception(logcat)
if javaException:

View File

@ -4,8 +4,8 @@
# 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/.
TEST_DIRS += ['tests/mochitest']
MOCHITEST_MANIFESTS += ['tests/mochitest/mochitest.ini']
MOCHITEST_CHROME_MANIFESTS += ['tests/mochitest/chrome.ini']
XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
XPIDL_SOURCES += [

View File

@ -1,9 +0,0 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
MOCHITEST_MANIFESTS += ['mochitest.ini']
MOCHITEST_CHROME_MANIFESTS += ['chrome.ini']

View File

@ -107,6 +107,7 @@ EXPORTS
sqlite3_result_double
sqlite3_result_error
sqlite3_result_error16
sqlite3_result_error_code
sqlite3_result_error_nomem
sqlite3_result_int
sqlite3_result_int64

View File

@ -224,10 +224,12 @@ using namespace mozilla;
using namespace mozilla::dom;
using mozilla::dom::workers::ServiceWorkerManager;
// True means sUseErrorPages has been added to preferences var cache.
// True means sUseErrorPages and sInterceptionEnabled has been added to
// preferences var cache.
static bool gAddedPreferencesVarCache = false;
bool nsDocShell::sUseErrorPages = false;
bool nsDocShell::sInterceptionEnabled = false;
// Number of documents currently loading
static int32_t gNumberOfDocumentsLoading = 0;
@ -5741,6 +5743,9 @@ nsDocShell::Create()
Preferences::AddBoolVarCache(&sUseErrorPages,
"browser.xul.error_pages.enabled",
mUseErrorPages);
Preferences::AddBoolVarCache(&sInterceptionEnabled,
"dom.serviceWorkers.interception.enabled",
false);
gAddedPreferencesVarCache = true;
}
@ -14047,6 +14052,11 @@ nsDocShell::ShouldPrepareForIntercept(nsIURI* aURI, bool aIsNavigate,
bool* aShouldIntercept)
{
*aShouldIntercept = false;
// Preffed off.
if (!sInterceptionEnabled) {
return NS_OK;
}
if (mSandboxFlags) {
// If we're sandboxed, don't intercept.
return NS_OK;

View File

@ -903,6 +903,9 @@ protected:
// Cached value of the "browser.xul.error_pages.enabled" preference.
static bool sUseErrorPages;
// Cached value of the "dom.serviceWorkers.interception.enabled" preference.
static bool sInterceptionEnabled;
bool mCreated;
bool mAllowSubframes;
bool mAllowPlugins;

View File

@ -444,7 +444,7 @@ Link::GetHash(nsAString &_hash, ErrorResult& aError)
nsresult rv = uri->GetRef(ref);
if (NS_SUCCEEDED(rv) && !ref.IsEmpty()) {
_hash.Assign(char16_t('#'));
if (nsContentUtils::EncodeDecodeURLHash()) {
if (nsContentUtils::GettersDecodeURLHash()) {
NS_UnescapeURL(ref); // XXX may result in random non-ASCII bytes!
}
AppendUTF8toUTF16(ref, _hash);

View File

@ -525,7 +525,7 @@ URL::GetHash(nsAString& aHash, ErrorResult& aRv) const
nsresult rv = mURI->GetRef(ref);
if (NS_SUCCEEDED(rv) && !ref.IsEmpty()) {
aHash.Assign(char16_t('#'));
if (nsContentUtils::EncodeDecodeURLHash()) {
if (nsContentUtils::GettersDecodeURLHash()) {
NS_UnescapeURL(ref); // XXX may result in random non-ASCII bytes!
}
AppendUTF8toUTF16(ref, aHash);

View File

@ -256,6 +256,7 @@ bool nsContentUtils::sIsResourceTimingEnabled = false;
bool nsContentUtils::sIsUserTimingLoggingEnabled = false;
bool nsContentUtils::sIsExperimentalAutocompleteEnabled = false;
bool nsContentUtils::sEncodeDecodeURLHash = false;
bool nsContentUtils::sGettersDecodeURLHash = false;
bool nsContentUtils::sPrivacyResistFingerprinting = false;
uint32_t nsContentUtils::sHandlingInputTimeout = 1000;
@ -538,6 +539,9 @@ nsContentUtils::Init()
Preferences::AddBoolVarCache(&sEncodeDecodeURLHash,
"dom.url.encode_decode_hash", false);
Preferences::AddBoolVarCache(&sGettersDecodeURLHash,
"dom.url.getters_decode_hash", false);
Preferences::AddBoolVarCache(&sPrivacyResistFingerprinting,
"privacy.resistFingerprinting", false);
@ -6313,10 +6317,7 @@ nsContentUtils::FlushLayoutForTree(nsIDOMWindow* aWindow)
// is O(N^2) in docshell tree depth. However, the docshell tree is
// usually pretty shallow.
nsCOMPtr<nsIDOMDocument> domDoc;
aWindow->GetDocument(getter_AddRefs(domDoc));
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
if (doc) {
if (nsCOMPtr<nsIDocument> doc = piWin->GetDoc()) {
doc->FlushPendingNotifications(Flush_Layout);
}

View File

@ -1948,6 +1948,14 @@ public:
return sEncodeDecodeURLHash;
}
/*
* Returns true if URL getters should percent decode the value of the segment
*/
static bool GettersDecodeURLHash()
{
return sGettersDecodeURLHash && sEncodeDecodeURLHash;
}
/*
* Returns true if the browser should attempt to prevent content scripts
* from collecting distinctive information about the browser that could
@ -2499,6 +2507,7 @@ private:
static bool sIsUserTimingLoggingEnabled;
static bool sIsExperimentalAutocompleteEnabled;
static bool sEncodeDecodeURLHash;
static bool sGettersDecodeURLHash;
static bool sPrivacyResistFingerprinting;
static nsHtml5StringParser* sHTMLFragmentParser;

View File

@ -1785,8 +1785,7 @@ nsMessageManagerScriptExecutor::TryCacheLoadAndCompileScript(
}
} else {
// We're going to run these against some non-global scope.
options.setHasPollutedScope(true);
if (!JS::Compile(cx, options, srcBuf, &script)) {
if (!JS::CompileForNonSyntacticScope(cx, options, srcBuf, &script)) {
return;
}
}

View File

@ -87,7 +87,6 @@ nsImageLoadingContent::nsImageLoadingContent()
mBroken(true),
mUserDisabled(false),
mSuppressed(false),
mFireEventsOnDecode(false),
mNewRequestsWillNeedAnimationReset(false),
mStateChangerDepth(0),
mCurrentRequestRegistered(false),
@ -186,18 +185,6 @@ nsImageLoadingContent::Notify(imgIRequest* aRequest,
}
if (aType == imgINotificationObserver::DECODE_COMPLETE) {
if (mFireEventsOnDecode) {
mFireEventsOnDecode = false;
uint32_t reqStatus;
aRequest->GetImageStatus(&reqStatus);
if (reqStatus & imgIRequest::STATUS_ERROR) {
FireEvent(NS_LITERAL_STRING("error"));
} else {
FireEvent(NS_LITERAL_STRING("load"));
}
}
UpdateImageState(true);
}
@ -277,23 +264,11 @@ nsImageLoadingContent::OnLoadComplete(imgIRequest* aRequest, nsresult aStatus)
}
}
// We want to give the decoder a chance to find errors. If we haven't found
// an error yet and we've started decoding, either from the above
// StartDecoding or from some other place, we must only fire these events
// after we finish decoding.
uint32_t reqStatus;
aRequest->GetImageStatus(&reqStatus);
if (NS_SUCCEEDED(aStatus) && !(reqStatus & imgIRequest::STATUS_ERROR) &&
(reqStatus & imgIRequest::STATUS_DECODE_STARTED) &&
!(reqStatus & imgIRequest::STATUS_DECODE_COMPLETE)) {
mFireEventsOnDecode = true;
// Fire the appropriate DOM event.
if (NS_SUCCEEDED(aStatus)) {
FireEvent(NS_LITERAL_STRING("load"));
} else {
// Fire the appropriate DOM event.
if (NS_SUCCEEDED(aStatus)) {
FireEvent(NS_LITERAL_STRING("load"));
} else {
FireEvent(NS_LITERAL_STRING("error"));
}
FireEvent(NS_LITERAL_STRING("error"));
}
nsCOMPtr<nsINode> thisNode = do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));

View File

@ -410,7 +410,6 @@ private:
bool mBroken : 1;
bool mUserDisabled : 1;
bool mSuppressed : 1;
bool mFireEventsOnDecode : 1;
protected:
/**

View File

@ -299,7 +299,7 @@ nsLocation::GetHash(nsAString& aHash)
rv = uri->GetRef(ref);
if (nsContentUtils::EncodeDecodeURLHash()) {
if (nsContentUtils::GettersDecodeURLHash()) {
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsITextToSubURI> textToSubURI(
do_GetService(NS_ITEXTTOSUBURI_CONTRACTID, &rv));

View File

@ -116,7 +116,7 @@
{ url: 'http://example.com/carrot#question%3f',
base: undefined,
error: false,
hash: '#question?'
hash: '#question%3f'
},
{ url: 'https://example.com:4443?',
base: undefined,

View File

@ -189,6 +189,7 @@ skip-if = buildapp == 'b2g' || e10s
support-files =
bug1096146_embedded.html
[test_offsetxy.html]
skip-if = toolkit == 'android' || buildapp == 'b2g' || buildapp == 'mulet'
[test_eventhandler_scoping.html]
[test_bug1013412.html]
skip-if = buildapp == 'b2g' # no wheel events on b2g

View File

@ -920,5 +920,5 @@
};
if (inNode) module.exports = obj;
else window.WebIDL2 = obj;
else self.WebIDL2 = obj;
}());

View File

@ -1,27 +1,21 @@
{
"DOMException exception: existence and properties of exception interface prototype object's \"name\" property": true,
"CustomEvent interface: existence and properties of interface object": true,
"EventListener interface: existence and properties of interface prototype object": true,
"EventListener interface: existence and properties of interface prototype object's \"constructor\" property": true,
"EventListener interface: operation handleEvent(Event)": true,
"MutationObserver interface: operation observe(Node,MutationObserverInit)": true,
"Node interface: existence and properties of interface object": true,
"Document interface: existence and properties of interface object": true,
"Document interface: operation prepend([object Object],[object Object])": true,
"Document interface: operation append([object Object],[object Object])": true,
"XMLDocument interface: existence and properties of interface object": true,
"Document interface: xmlDoc must inherit property \"prepend\" with the proper type (28)": true,
"Document interface: calling prepend([object Object],[object Object]) on xmlDoc with too few arguments must throw TypeError": true,
"Document interface: xmlDoc must inherit property \"append\" with the proper type (29)": true,
"Document interface: calling append([object Object],[object Object]) on xmlDoc with too few arguments must throw TypeError": true,
"DocumentFragment interface: existence and properties of interface object": true,
"DocumentFragment interface: operation prepend([object Object],[object Object])": true,
"DocumentFragment interface: operation append([object Object],[object Object])": true,
"DocumentFragment interface: document.createDocumentFragment() must inherit property \"prepend\" with the proper type (4)": true,
"DocumentFragment interface: calling prepend([object Object],[object Object]) on document.createDocumentFragment() with too few arguments must throw TypeError": true,
"DocumentFragment interface: document.createDocumentFragment() must inherit property \"append\" with the proper type (5)": true,
"DocumentFragment interface: calling append([object Object],[object Object]) on document.createDocumentFragment() with too few arguments must throw TypeError": true,
"DocumentType interface: existence and properties of interface object": true,
"DocumentType interface: operation before([object Object],[object Object])": true,
"DocumentType interface: operation after([object Object],[object Object])": true,
"DocumentType interface: operation replace([object Object],[object Object])": true,
@ -31,7 +25,6 @@
"DocumentType interface: calling after([object Object],[object Object]) on document.doctype with too few arguments must throw TypeError": true,
"DocumentType interface: document.doctype must inherit property \"replace\" with the proper type (5)": true,
"DocumentType interface: calling replace([object Object],[object Object]) on document.doctype with too few arguments must throw TypeError": true,
"Element interface: existence and properties of interface object": true,
"Element interface: attribute namespaceURI": true,
"Element interface: attribute prefix": true,
"Element interface: attribute localName": true,
@ -52,36 +45,48 @@
"Element interface: calling replace([object Object],[object Object]) on element with too few arguments must throw TypeError": true,
"Attr interface: existence and properties of interface object": true,
"Attr interface: existence and properties of interface prototype object": true,
"CharacterData interface: existence and properties of interface object": true,
"CharacterData interface: operation before([object Object],[object Object])": true,
"CharacterData interface: operation after([object Object],[object Object])": true,
"CharacterData interface: operation replace([object Object],[object Object])": true,
"Text interface: existence and properties of interface object": true,
"CharacterData interface: document.createTextNode(\"abc\") must inherit property \"before\" with the proper type (7)": true,
"CharacterData interface: calling before([object Object],[object Object]) on document.createTextNode(\"abc\") with too few arguments must throw TypeError": true,
"CharacterData interface: document.createTextNode(\"abc\") must inherit property \"after\" with the proper type (8)": true,
"CharacterData interface: calling after([object Object],[object Object]) on document.createTextNode(\"abc\") with too few arguments must throw TypeError": true,
"CharacterData interface: document.createTextNode(\"abc\") must inherit property \"replace\" with the proper type (9)": true,
"CharacterData interface: calling replace([object Object],[object Object]) on document.createTextNode(\"abc\") with too few arguments must throw TypeError": true,
"ProcessingInstruction interface: existence and properties of interface object": true,
"CharacterData interface: xmlDoc.createProcessingInstruction(\"abc\", \"def\") must inherit property \"before\" with the proper type (7)": true,
"CharacterData interface: calling before([object Object],[object Object]) on xmlDoc.createProcessingInstruction(\"abc\", \"def\") with too few arguments must throw TypeError": true,
"CharacterData interface: xmlDoc.createProcessingInstruction(\"abc\", \"def\") must inherit property \"after\" with the proper type (8)": true,
"CharacterData interface: calling after([object Object],[object Object]) on xmlDoc.createProcessingInstruction(\"abc\", \"def\") with too few arguments must throw TypeError": true,
"CharacterData interface: xmlDoc.createProcessingInstruction(\"abc\", \"def\") must inherit property \"replace\" with the proper type (9)": true,
"CharacterData interface: calling replace([object Object],[object Object]) on xmlDoc.createProcessingInstruction(\"abc\", \"def\") with too few arguments must throw TypeError": true,
"Comment interface: existence and properties of interface object": true,
"CharacterData interface: document.createComment(\"abc\") must inherit property \"before\" with the proper type (7)": true,
"CharacterData interface: calling before([object Object],[object Object]) on document.createComment(\"abc\") with too few arguments must throw TypeError": true,
"CharacterData interface: document.createComment(\"abc\") must inherit property \"after\" with the proper type (8)": true,
"CharacterData interface: calling after([object Object],[object Object]) on document.createComment(\"abc\") with too few arguments must throw TypeError": true,
"CharacterData interface: document.createComment(\"abc\") must inherit property \"replace\" with the proper type (9)": true,
"CharacterData interface: calling replace([object Object],[object Object]) on document.createComment(\"abc\") with too few arguments must throw TypeError": true,
"NodeFilter interface: existence and properties of interface object": true,
"NodeList interface: existence and properties of interface prototype object": true,
"DOMTokenList interface: operation add(DOMString)": true,
"DOMTokenList interface: operation remove(DOMString)": true,
"DOMTokenList interface: calling add(DOMString) on document.body.classList with too few arguments must throw TypeError": true,
"DOMTokenList interface: calling remove(DOMString) on document.body.classList with too few arguments must throw TypeError": true,
"DOMSettableTokenList interface: existence and properties of interface object": true
"NodeFilter interface: existence and properties of interface prototype object": true,
"NodeFilter interface: existence and properties of interface prototype object": true,
"NodeFilter interface: existence and properties of interface prototype object's \"constructor\" property": true,
"EventListener interface: existence and properties of interface object": true,
"EventListener interface object length": true,
"NodeFilter interface: constant FILTER_ACCEPT on interface prototype object": true,
"NodeFilter interface: constant FILTER_REJECT on interface prototype object": true,
"NodeFilter interface: constant FILTER_SKIP on interface prototype object": true,
"NodeFilter interface: constant SHOW_ALL on interface prototype object": true,
"NodeFilter interface: constant SHOW_ELEMENT on interface prototype object": true,
"NodeFilter interface: constant SHOW_ATTRIBUTE on interface prototype object": true,
"NodeFilter interface: constant SHOW_TEXT on interface prototype object": true,
"NodeFilter interface: constant SHOW_CDATA_SECTION on interface prototype object": true,
"NodeFilter interface: constant SHOW_ENTITY_REFERENCE on interface prototype object": true,
"NodeFilter interface: constant SHOW_ENTITY on interface prototype object": true,
"NodeFilter interface: constant SHOW_PROCESSING_INSTRUCTION on interface prototype object": true,
"NodeFilter interface: constant SHOW_COMMENT on interface prototype object": true,
"NodeFilter interface: constant SHOW_DOCUMENT on interface prototype object": true,
"NodeFilter interface: constant SHOW_DOCUMENT_TYPE on interface prototype object": true,
"NodeFilter interface: constant SHOW_DOCUMENT_FRAGMENT on interface prototype object": true,
"NodeFilter interface: constant SHOW_NOTATION on interface prototype object": true,
"NodeFilter interface: operation acceptNode(Node)": true,
"NodeList interface: existence and properties of interface prototype object": true
}

View File

@ -1,6 +0,0 @@
# THIS FILE IS AUTOGENERATED BY parseFailures.py - DO NOT EDIT
[DEFAULT]
support-files =
[test_interfaces.html.json]

View File

@ -1,4 +0,0 @@
{
"XMLHttpRequestUpload interface: existence and properties of interface object": true,
"XMLHttpRequest interface: existence and properties of interface object": true
}

View File

@ -10,35 +10,6 @@
<div id=log></div>
<script type=text/plain>
exception DOMException {
const unsigned short INDEX_SIZE_ERR = 1;
const unsigned short DOMSTRING_SIZE_ERR = 2; // historical
const unsigned short HIERARCHY_REQUEST_ERR = 3;
const unsigned short WRONG_DOCUMENT_ERR = 4;
const unsigned short INVALID_CHARACTER_ERR = 5;
const unsigned short NO_DATA_ALLOWED_ERR = 6; // historical
const unsigned short NO_MODIFICATION_ALLOWED_ERR = 7;
const unsigned short NOT_FOUND_ERR = 8;
const unsigned short NOT_SUPPORTED_ERR = 9;
const unsigned short INUSE_ATTRIBUTE_ERR = 10; // historical
const unsigned short INVALID_STATE_ERR = 11;
const unsigned short SYNTAX_ERR = 12;
const unsigned short INVALID_MODIFICATION_ERR = 13;
const unsigned short NAMESPACE_ERR = 14;
const unsigned short INVALID_ACCESS_ERR = 15;
const unsigned short VALIDATION_ERR = 16; // historical
const unsigned short TYPE_MISMATCH_ERR = 17; // historical; use TypeError instead
const unsigned short SECURITY_ERR = 18;
const unsigned short NETWORK_ERR = 19;
const unsigned short ABORT_ERR = 20;
const unsigned short URL_MISMATCH_ERR = 21;
const unsigned short QUOTA_EXCEEDED_ERR = 22;
const unsigned short TIMEOUT_ERR = 23;
const unsigned short INVALID_NODE_TYPE_ERR = 24;
const unsigned short DATA_CLONE_ERR = 25;
unsigned short code;
};
[Constructor(DOMString name)]
interface DOMError {
readonly attribute DOMString name;
@ -451,11 +422,10 @@ interface DOMSettableTokenList : DOMTokenList {
</script>
<script>
"use strict";
var xmlDoc, domException, detachedRange, element;
var xmlDoc, detachedRange, element;
var idlArray;
setup(function() {
xmlDoc = document.implementation.createDocument(null, "", null);
try { document.appendChild(document); } catch(e) { domException = e; }
detachedRange = document.createRange();
detachedRange.detach();
element = xmlDoc.createElementNS(null, "test");
@ -464,7 +434,6 @@ setup(function() {
idlArray = new IdlArray();
idlArray.add_idls(document.querySelector("script[type=text\\/plain]").textContent);
idlArray.add_objects({
DOMException: ['domException'],
Event: ['document.createEvent("Event")', 'new Event("foo")'],
CustomEvent: ['new CustomEvent("foo")'],
XMLDocument: ['xmlDoc'],

File diff suppressed because it is too large Load Diff

View File

@ -32,5 +32,4 @@ MOCHITEST_MANIFESTS += [
'failures/html/microdata/microdata-dom-api/mochitest.ini',
'failures/html/typedarrays/mochitest.ini',
'failures/webapps/WebStorage/tests/submissions/Infraware/mochitest.ini',
'failures/webapps/XMLHttpRequest/tests/submissions/Ms2ger/mochitest.ini',
]

View File

@ -14,11 +14,6 @@ html {
background: red;
}
#log pre {
border: 1px solid black;
padding: 1em;
}
section#summary {
margin-bottom:1em;
}

View File

@ -22,7 +22,8 @@ policies and contribution forms [3].
"normal":10000,
"long":60000
},
test_timeout:null
test_timeout:null,
message_events: ["start", "test_state", "result", "completion"]
};
var xhtml_ns = "http://www.w3.org/1999/xhtml";
@ -64,6 +65,40 @@ policies and contribution forms [3].
this.output_handler = null;
this.all_loaded = false;
var this_obj = this;
this.message_events = [];
this.message_functions = {
start: [add_start_callback, remove_start_callback,
function (properties) {
this_obj._dispatch("start_callback", [properties],
{type: "start", properties: properties});
}],
test_state: [add_test_state_callback, remove_test_state_callback,
function(test) {
this_obj._dispatch("test_state_callback", [test],
{type: "test_state",
test: test.structured_clone()});
}],
result: [add_result_callback, remove_result_callback,
function (test) {
this_obj.output_handler.show_status();
this_obj._dispatch("result_callback", [test],
{type: "result",
test: test.structured_clone()});
}],
completion: [add_completion_callback, remove_completion_callback,
function (tests, harness_status) {
var cloned_tests = map(tests, function(test) {
return test.structured_clone();
});
this_obj._dispatch("completion_callback", [tests, harness_status],
{type: "complete",
tests: cloned_tests,
status: harness_status.structured_clone()});
}]
}
on_event(window, 'load', function() {
this_obj.all_loaded = true;
});
@ -71,13 +106,22 @@ policies and contribution forms [3].
WindowTestEnvironment.prototype._dispatch = function(selector, callback_args, message_arg) {
this._forEach_windows(
function(w, is_same_origin) {
if (is_same_origin && selector in w) {
function(w, same_origin) {
if (same_origin) {
try {
w[selector].apply(undefined, callback_args);
} catch (e) {
if (debug) {
throw e;
var has_selector = selector in w;
} catch(e) {
// If document.domain was set at some point same_origin can be
// wrong and the above will fail.
has_selector = false;
}
if (has_selector) {
try {
w[selector].apply(undefined, callback_args);
} catch (e) {
if (debug) {
throw e;
}
}
}
}
@ -141,30 +185,39 @@ policies and contribution forms [3].
this.output_handler = output;
var this_obj = this;
add_start_callback(function (properties) {
this_obj.output_handler.init(properties);
this_obj._dispatch("start_callback", [properties],
{ type: "start", properties: properties });
});
add_test_state_callback(function(test) {
this_obj.output_handler.show_status();
this_obj._dispatch("test_state_callback", [test],
{ type: "test_state", test: test.structured_clone() });
});
add_result_callback(function (test) {
this_obj.output_handler.show_status();
this_obj._dispatch("result_callback", [test],
{ type: "result", test: test.structured_clone() });
});
add_completion_callback(function (tests, harness_status) {
this_obj.output_handler.show_results(tests, harness_status);
var cloned_tests = map(tests, function(test) { return test.structured_clone(); });
this_obj._dispatch("completion_callback", [tests, harness_status],
{ type: "complete", tests: cloned_tests,
status: harness_status.structured_clone() });
});
this.setup_messages(settings.message_events);
};
WindowTestEnvironment.prototype.setup_messages = function(new_events) {
var this_obj = this;
forEach(settings.message_events, function(x) {
var current_dispatch = this_obj.message_events.indexOf(x) !== -1;
var new_dispatch = new_events.indexOf(x) !== -1;
if (!current_dispatch && new_dispatch) {
this_obj.message_functions[x][0](this_obj.message_functions[x][2]);
} else if (current_dispatch && !new_dispatch) {
this_obj.message_functions[x][1](this_obj.message_functions[x][2]);
}
});
this.message_events = new_events;
}
WindowTestEnvironment.prototype.next_default_test_name = function() {
//Don't use document.title to work around an Opera bug in XHTML documents
var title = document.getElementsByTagName("title")[0];
@ -176,6 +229,9 @@ policies and contribution forms [3].
WindowTestEnvironment.prototype.on_new_harness_properties = function(properties) {
this.output_handler.setup(properties);
if (properties.hasOwnProperty("message_events")) {
this.setup_messages(properties.message_events);
}
};
WindowTestEnvironment.prototype.add_on_loaded_callback = function(callback) {
@ -359,8 +415,20 @@ policies and contribution forms [3].
self.addEventListener("message",
function(event) {
if (event.data.type && event.data.type === "connect") {
this_obj._add_message_port(event.ports[0]);
event.ports[0].start();
if (event.ports && event.ports[0]) {
// If a MessageChannel was passed, then use it to
// send results back to the main window. This
// allows the tests to work even if the browser
// does not fully support MessageEvent.source in
// ServiceWorkers yet.
this_obj._add_message_port(event.ports[0]);
event.ports[0].start();
} else {
// If there is no MessageChannel, then attempt to
// use the MessageEvent.source to send results
// back to the main window.
this_obj._add_message_port(event.source);
}
}
});
@ -464,6 +532,12 @@ policies and contribution forms [3].
}));
}
function promise_rejects(test, expected, promise) {
return promise.then(test.unreached_func("Should have rejected.")).catch(function(e) {
assert_throws(expected, function() { throw e });
});
}
/**
* This constructor helper allows DOM events to be handled using Promises,
* which can make it a lot easier to test a very specific series of events,
@ -579,6 +653,7 @@ policies and contribution forms [3].
expose(test, 'test');
expose(async_test, 'async_test');
expose(promise_test, 'promise_test');
expose(promise_rejects, 'promise_rejects');
expose(generate_tests, 'generate_tests');
expose(setup, 'setup');
expose(done, 'done');
@ -842,7 +917,7 @@ policies and contribution forms [3].
for (var i = 0; i < actual.length; i++) {
assert(actual.hasOwnProperty(i) === expected.hasOwnProperty(i),
"assert_array_equals", description,
"property ${i}, property expected to be $expected but was $actual",
"property ${i}, property expected to be ${expected} but was ${actual}",
{i:i, expected:expected.hasOwnProperty(i) ? "present" : "missing",
actual:actual.hasOwnProperty(i) ? "present" : "missing"});
assert(same_value(expected[i], actual[i]),
@ -933,7 +1008,7 @@ policies and contribution forms [3].
{type_actual:typeof actual});
assert(actual <= expected,
"assert_less_than", description,
"assert_less_than_equal", description,
"expected a number less than or equal to ${expected} but got ${actual}",
{expected:expected, actual:actual});
}
@ -1125,12 +1200,15 @@ policies and contribution forms [3].
InvalidNodeTypeError: 24,
DataCloneError: 25,
EncodingError: 0,
NotReadableError: 0,
UnknownError: 0,
ConstraintError: 0,
DataError: 0,
TransactionInactiveError: 0,
ReadOnlyError: 0,
VersionError: 0
VersionError: 0,
OperationError: 0,
};
if (!(name in name_code_map)) {
@ -1140,7 +1218,10 @@ policies and contribution forms [3].
var required_props = { code: name_code_map[name] };
if (required_props.code === 0 ||
("name" in e && e.name !== e.name.toUpperCase() && e.name !== "DOMException")) {
(typeof e == "object" &&
"name" in e &&
e.name !== e.name.toUpperCase() &&
e.name !== "DOMException")) {
// New style exception: also test the name property.
required_props.name = name;
}
@ -1214,6 +1295,7 @@ policies and contribution forms [3].
}
this.message = null;
this.stack = null;
this.steps = [];
@ -1250,6 +1332,7 @@ policies and contribution forms [3].
}
this._structured_clone.status = this.status;
this._structured_clone.message = this.message;
this._structured_clone.stack = this.stack;
this._structured_clone.index = this.index;
return this._structured_clone;
};
@ -1282,15 +1365,10 @@ policies and contribution forms [3].
if (this.phase >= this.phases.HAS_RESULT) {
return;
}
var message = (typeof e === "object" && e !== null) ? e.message : e;
if (typeof e.stack != "undefined" && typeof e.message == "string") {
//Try to make it more informative for some exceptions, at least
//in Gecko and WebKit. This results in a stack dump instead of
//just errors like "Cannot read property 'parentNode' of null"
//or "root is null". Makes it a lot longer, of course.
message += "(stack: " + e.stack + ")";
}
this.set_status(this.FAIL, message);
var message = String((typeof e === "object" && e !== null) ? e.message : e);
var stack = e.stack ? e.stack : null;
this.set_status(this.FAIL, message, stack);
this.phase = this.phases.HAS_RESULT;
this.done();
}
@ -1356,10 +1434,11 @@ policies and contribution forms [3].
}
};
Test.prototype.set_status = function(status, message)
Test.prototype.set_status = function(status, message, stack)
{
this.status = status;
this.message = message;
this.stack = stack ? stack : null;
};
Test.prototype.timeout = function()
@ -1416,13 +1495,13 @@ policies and contribution forms [3].
RemoteTest.prototype.structured_clone = function() {
var clone = {};
Object.keys(this).forEach(
function(key) {
(function(key) {
if (typeof(this[key]) === "object") {
clone[key] = merge({}, this[key]);
} else {
clone[key] = this[key];
}
});
}).bind(this));
clone.phases = merge({}, this.phases);
return clone;
};
@ -1432,6 +1511,7 @@ policies and contribution forms [3].
RemoteTest.prototype.update_state_from = function(clone) {
this.status = clone.status;
this.message = clone.message;
this.stack = clone.stack;
if (this.phase === this.phases.INITIAL) {
this.phase = this.phases.STARTED;
}
@ -1455,15 +1535,24 @@ policies and contribution forms [3].
var message_port;
if (is_service_worker(worker)) {
// The ServiceWorker's implicit MessagePort is currently not
// reliably accessible from the ServiceWorkerGlobalScope due to
// Blink setting MessageEvent.source to null for messages sent via
// ServiceWorker.postMessage(). Until that's resolved, create an
// explicit MessageChannel and pass one end to the worker.
var message_channel = new MessageChannel();
message_port = message_channel.port1;
message_port.start();
worker.postMessage({type: "connect"}, [message_channel.port2]);
if (window.MessageChannel) {
// The ServiceWorker's implicit MessagePort is currently not
// reliably accessible from the ServiceWorkerGlobalScope due to
// Blink setting MessageEvent.source to null for messages sent
// via ServiceWorker.postMessage(). Until that's resolved,
// create an explicit MessageChannel and pass one end to the
// worker.
var message_channel = new MessageChannel();
message_port = message_channel.port1;
message_port.start();
worker.postMessage({type: "connect"}, [message_channel.port2]);
} else {
// If MessageChannel is not available, then try the
// ServiceWorker.postMessage() approach using MessageEvent.source
// on the other end.
message_port = navigator.serviceWorker;
worker.postMessage({type: "connect"});
}
} else if (is_shared_worker(worker)) {
message_port = worker.port;
} else {
@ -1491,7 +1580,8 @@ policies and contribution forms [3].
this.worker_done({
status: {
status: tests.status.ERROR,
message: "Error in worker" + filename + ": " + message
message: "Error in worker" + filename + ": " + message,
stack: error.stack
}
});
error.preventDefault();
@ -1519,6 +1609,7 @@ policies and contribution forms [3].
data.status.status !== data.status.OK) {
tests.status.status = data.status.status;
tests.status.message = data.status.message;
tests.status.stack = data.status.stack;
}
this.running = false;
this.worker = null;
@ -1541,6 +1632,7 @@ policies and contribution forms [3].
{
this.status = null;
this.message = null;
this.stack = null;
}
TestsStatus.statuses = {
@ -1558,7 +1650,8 @@ policies and contribution forms [3].
msg = msg ? String(msg) : msg;
this._structured_clone = merge({
status:this.status,
message:msg
message:msg,
stack:this.stack
}, TestsStatus.statuses);
}
return this._structured_clone;
@ -1648,6 +1741,7 @@ policies and contribution forms [3].
} catch (e) {
this.status.status = this.status.ERROR;
this.status.message = String(e);
this.status.stack = e.stack ? e.stack : null;
}
}
this.set_timeout();
@ -1811,14 +1905,12 @@ policies and contribution forms [3].
tests.test_state_callbacks.push(callback);
}
function add_result_callback(callback)
{
function add_result_callback(callback) {
tests.test_done_callbacks.push(callback);
}
function add_completion_callback(callback)
{
tests.all_done_callbacks.push(callback);
function add_completion_callback(callback) {
tests.all_done_callbacks.push(callback);
}
expose(add_start_callback, 'add_start_callback');
@ -1826,6 +1918,29 @@ policies and contribution forms [3].
expose(add_result_callback, 'add_result_callback');
expose(add_completion_callback, 'add_completion_callback');
function remove(array, item) {
var index = array.indexOf(item);
if (index > -1) {
array.splice(index, 1);
}
}
function remove_start_callback(callback) {
remove(tests.start_callbacks, callback);
}
function remove_test_state_callback(callback) {
remove(tests.test_state_callbacks, callback);
}
function remove_result_callback(callback) {
remove(tests.test_done_callbacks, callback);
}
function remove_completion_callback(callback) {
remove(tests.all_done_callbacks, callback);
}
/*
* Output listener
*/
@ -2005,6 +2120,9 @@ policies and contribution forms [3].
if (harness_status.status === harness_status.ERROR) {
rv[0].push(["pre", {}, harness_status.message]);
if (harness_status.stack) {
rv[0].push(["pre", {}, harness_status.stack]);
}
}
return rv;
},
@ -2102,6 +2220,9 @@ policies and contribution forms [3].
"</td><td>" +
(assertions ? escape_html(get_assertion(tests[i])) + "</td><td>" : "") +
escape_html(tests[i].message ? tests[i].message : " ") +
(tests[i].stack ? "<pre>" +
escape_html(tests[i].stack) +
"</pre>": "") +
"</td></tr>";
}
html += "</tbody></table>";
@ -2297,11 +2418,34 @@ policies and contribution forms [3].
function AssertionError(message)
{
this.message = message;
this.stack = this.get_stack();
}
AssertionError.prototype.toString = function() {
return this.message;
};
AssertionError.prototype = Object.create(Error.prototype);
AssertionError.prototype.get_stack = function() {
var stack = new Error().stack;
if (!stack) {
try {
throw new Error();
} catch (e) {
stack = e.stack;
}
}
var lines = stack.split("\n");
var rv = [];
var re = /\/resources\/testharness\.js/;
var i = 0;
// Fire remove any preamble that doesn't match the regexp
while (!re.test(lines[i])) {
i++
}
// Then remove top frames in testharness.js itself
while (re.test(lines[i])) {
i++
}
return lines.slice(i).join("\n");
}
function make_message(function_name, description, error, substitutions)
{
@ -2440,14 +2584,14 @@ policies and contribution forms [3].
if (test.phase >= test.phases.HAS_RESULT) {
return;
}
var message = e.message;
test.set_status(test.FAIL, message);
test.set_status(test.FAIL, e.message, e.stack);
test.phase = test.phases.HAS_RESULT;
test.done();
done();
} else if (!tests.allow_uncaught_exception) {
tests.status.status = tests.status.ERROR;
tests.status.message = e.message;
tests.status.stack = e.stack;
}
});

View File

@ -1262,14 +1262,26 @@ BackgroundFactoryRequestChild::HandleResponse(
static_cast<BackgroundDatabaseChild*>(aResponse.databaseChild());
MOZ_ASSERT(databaseActor);
databaseActor->EnsureDOMObject();
IDBDatabase* database = databaseActor->GetDOMObject();
MOZ_ASSERT(database);
if (!database) {
databaseActor->EnsureDOMObject();
ResultHelper helper(mRequest, nullptr, database);
database = databaseActor->GetDOMObject();
MOZ_ASSERT(database);
DispatchSuccessEvent(&helper);
MOZ_ASSERT(!database->IsClosed());
}
if (database->IsClosed()) {
// If the database was closed already, which is only possible if we fired an
// "upgradeneeded" event, then we shouldn't fire a "success" event here.
// Instead we fire an error event with AbortErr.
DispatchErrorEvent(mRequest, NS_ERROR_DOM_INDEXEDDB_ABORT_ERR);
} else {
ResultHelper helper(mRequest, nullptr, database);
DispatchSuccessEvent(&helper);
}
databaseActor->ReleaseDOMObject();

View File

@ -5343,11 +5343,10 @@ protected:
const Key& aObjectStoreKey,
const FallibleTArray<IndexDataValue>& aIndexValues);
#ifdef DEBUG
static bool
static nsresult
ObjectStoreHasIndexes(DatabaseConnection* aConnection,
const int64_t aObjectStoreId);
#endif
const int64_t aObjectStoreId,
bool* aHasIndexes);
private:
template <typename T>
@ -6941,7 +6940,6 @@ class DeleteObjectStoreOp final
const nsRefPtr<FullObjectStoreMetadata> mMetadata;
const bool mIsLastObjectStore;
const bool mObjectStoreHasIndexes;
private:
// Only created by VersionChangeTransaction.
@ -6951,7 +6949,6 @@ private:
: VersionChangeTransactionOp(aTransaction)
, mMetadata(aMetadata)
, mIsLastObjectStore(aIsLastObjectStore)
, mObjectStoreHasIndexes(aMetadata->HasLiveIndexes())
{
MOZ_ASSERT(aMetadata->mCommonMetadata.id());
}
@ -7138,6 +7135,15 @@ protected:
~NormalTransactionOp()
{ }
// An overload of DatabaseOperationBase's function that can avoid doing extra
// work on non-versionchange transactions.
static nsresult
ObjectStoreHasIndexes(NormalTransactionOp* aOp,
DatabaseConnection* aConnection,
const int64_t aObjectStoreId,
const bool aMayHaveIndexes,
bool* aHasIndexes);
// Subclasses use this override to set the IPDL response value.
virtual void
GetResponse(RequestResponse& aResponse) = 0;
@ -7179,7 +7185,7 @@ class ObjectStoreAddOrPutRequestOp final
const nsCString mOrigin;
const PersistenceType mPersistenceType;
const bool mOverwrite;
const bool mObjectStoreHasIndexes;
const bool mObjectStoreMayHaveIndexes;
private:
// Only created by TransactionBase.
@ -7297,7 +7303,7 @@ class ObjectStoreDeleteRequestOp final
const ObjectStoreDeleteParams mParams;
ObjectStoreDeleteResponse mResponse;
const bool mObjectStoreHasIndexes;
const bool mObjectStoreMayHaveIndexes;
private:
ObjectStoreDeleteRequestOp(TransactionBase* aTransaction,
@ -7323,7 +7329,7 @@ class ObjectStoreClearRequestOp final
const ObjectStoreClearParams mParams;
ObjectStoreClearResponse mResponse;
const bool mObjectStoreHasIndexes;
const bool mObjectStoreMayHaveIndexes;
private:
ObjectStoreClearRequestOp(TransactionBase* aTransaction,
@ -13060,12 +13066,12 @@ TransactionBase::GetMetadataForObjectStoreId(int64_t aObjectStoreId) const
nsRefPtr<FullObjectStoreMetadata> metadata;
if (!mDatabase->Metadata()->mObjectStores.Get(aObjectStoreId,
getter_AddRefs(metadata))) {
getter_AddRefs(metadata)) ||
metadata->mDeleted) {
return nullptr;
}
MOZ_ASSERT(metadata->mCommonMetadata.id() == aObjectStoreId);
MOZ_ASSERT(!metadata->mDeleted);
return metadata.forget();
}
@ -13083,12 +13089,12 @@ TransactionBase::GetMetadataForIndexId(
}
nsRefPtr<FullIndexMetadata> metadata;
if (!aObjectStoreMetadata->mIndexes.Get(aIndexId, getter_AddRefs(metadata))) {
if (!aObjectStoreMetadata->mIndexes.Get(aIndexId, getter_AddRefs(metadata)) ||
metadata->mDeleted) {
return nullptr;
}
MOZ_ASSERT(metadata->mCommonMetadata.id() == aIndexId);
MOZ_ASSERT(!metadata->mDeleted);
return metadata.forget();
}
@ -18063,8 +18069,16 @@ DatabaseOperationBase::DeleteObjectStoreDataTableRowsWithIndexes(
MOZ_ASSERT(aConnection);
aConnection->AssertIsOnConnectionThread();
MOZ_ASSERT(aObjectStoreId);
MOZ_ASSERT(ObjectStoreHasIndexes(aConnection, aObjectStoreId),
"Don't use this slow method if there are no indexes!");
#ifdef DEBUG
{
bool hasIndexes = false;
MOZ_ASSERT(NS_SUCCEEDED(
ObjectStoreHasIndexes(aConnection, aObjectStoreId, &hasIndexes)));
MOZ_ASSERT(hasIndexes,
"Don't use this slow method if there are no indexes!");
}
#endif
PROFILER_LABEL("IndexedDB",
"DatabaseOperationBase::"
@ -18272,38 +18286,45 @@ DatabaseOperationBase::UpdateIndexValues(
return NS_OK;
}
#ifdef DEBUG
// static
bool
nsresult
DatabaseOperationBase::ObjectStoreHasIndexes(DatabaseConnection* aConnection,
const int64_t aObjectStoreId)
const int64_t aObjectStoreId,
bool* aHasIndexes)
{
MOZ_ASSERT(aConnection);
aConnection->AssertIsOnConnectionThread();
MOZ_ASSERT(aObjectStoreId);
MOZ_ASSERT(aHasIndexes);
DatabaseConnection::CachedStatement stmt;
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
aConnection->GetCachedStatement(NS_LITERAL_CSTRING(
"SELECT id "
"FROM object_store_index "
"WHERE object_store_id = :object_store_id;"),
&stmt)));
nsresult rv = aConnection->GetCachedStatement(NS_LITERAL_CSTRING(
"SELECT id "
"FROM object_store_index "
"WHERE object_store_id = :object_store_id "
"LIMIT 1;"),
&stmt);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
stmt->BindInt64ByName(NS_LITERAL_CSTRING("object_store_id"),
aObjectStoreId)));
rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("object_store_id"),
aObjectStoreId);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
bool hasResult;
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(stmt->ExecuteStep(&hasResult)));
rv = stmt->ExecuteStep(&hasResult);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return hasResult;
*aHasIndexes = hasResult;
return NS_OK;
}
#endif // DEBUG
NS_IMPL_ISUPPORTS_INHERITED(DatabaseOperationBase,
nsRunnable,
mozIStorageProgressHandler)
@ -19669,7 +19690,18 @@ void
OpenDatabaseOp::NoteDatabaseClosed(Database* aDatabase)
{
AssertIsOnOwningThread();
MOZ_ASSERT(mState == State_WaitingForOtherDatabasesToClose);
MOZ_ASSERT(aDatabase);
MOZ_ASSERT(mState == State_WaitingForOtherDatabasesToClose ||
mState == State_DatabaseWorkVersionChange);
if (mState == State_DatabaseWorkVersionChange) {
MOZ_ASSERT(mMaybeBlockedDatabases.IsEmpty());
MOZ_ASSERT(mRequestedVersion >
aDatabase->Metadata()->mCommonMetadata.version(),
"Must only be closing databases for a previous version!");
return;
}
MOZ_ASSERT(!mMaybeBlockedDatabases.IsEmpty());
bool actorDestroyed = IsActorDestroyed() || mDatabase->IsActorDestroyed();
@ -21635,11 +21667,6 @@ DeleteObjectStoreOp::DoDatabaseWork(DatabaseConnection* aConnection)
foundThisObjectStore && !foundOtherObjectStore);
MOZ_ASSERT_IF(!mIsLastObjectStore,
foundThisObjectStore && foundOtherObjectStore);
// Make sure |hasIndexes| is telling the truth.
MOZ_ASSERT(mObjectStoreHasIndexes ==
ObjectStoreHasIndexes(aConnection,
mMetadata->mCommonMetadata.id()));
}
#endif
@ -21712,7 +21739,15 @@ DeleteObjectStoreOp::DoDatabaseWork(DatabaseConnection* aConnection)
return rv;
}
} else {
if (mObjectStoreHasIndexes) {
bool hasIndexes;
rv = ObjectStoreHasIndexes(aConnection,
mMetadata->mCommonMetadata.id(),
&hasIndexes);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (hasIndexes) {
rv = DeleteObjectStoreDataTableRowsWithIndexes(
aConnection,
mMetadata->mCommonMetadata.id(),
@ -22790,6 +22825,48 @@ DeleteIndexOp::DoDatabaseWork(DatabaseConnection* aConnection)
return NS_OK;
}
// static
nsresult
NormalTransactionOp::ObjectStoreHasIndexes(NormalTransactionOp* aOp,
DatabaseConnection* aConnection,
const int64_t aObjectStoreId,
const bool aMayHaveIndexes,
bool* aHasIndexes)
{
MOZ_ASSERT(aOp);
MOZ_ASSERT(aConnection);
aConnection->AssertIsOnConnectionThread();
MOZ_ASSERT(aObjectStoreId);
MOZ_ASSERT(aHasIndexes);
bool hasIndexes;
if (aOp->Transaction()->GetMode() == IDBTransaction::VERSION_CHANGE &&
aMayHaveIndexes) {
// If this is a version change transaction then mObjectStoreMayHaveIndexes
// could be wrong (e.g. if a unique index failed to be created due to a
// constraint error). We have to check on this thread by asking the database
// directly.
nsresult rv =
DatabaseOperationBase::ObjectStoreHasIndexes(aConnection,
aObjectStoreId,
&hasIndexes);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
} else {
MOZ_ASSERT(NS_SUCCEEDED(
DatabaseOperationBase::ObjectStoreHasIndexes(aConnection,
aObjectStoreId,
&hasIndexes)));
MOZ_ASSERT(aMayHaveIndexes == hasIndexes);
hasIndexes = aMayHaveIndexes;
}
*aHasIndexes = hasIndexes;
return NS_OK;
}
nsresult
NormalTransactionOp::SendSuccessResult()
{
@ -22866,7 +22943,7 @@ ObjectStoreAddOrPutRequestOp::ObjectStoreAddOrPutRequestOp(
, mOrigin(aTransaction->GetDatabase()->Origin())
, mPersistenceType(aTransaction->GetDatabase()->Type())
, mOverwrite(aParams.type() == RequestParams::TObjectStorePutParams)
, mObjectStoreHasIndexes(false)
, mObjectStoreMayHaveIndexes(false)
{
MOZ_ASSERT(aParams.type() == RequestParams::TObjectStoreAddParams ||
aParams.type() == RequestParams::TObjectStorePutParams);
@ -22875,7 +22952,7 @@ ObjectStoreAddOrPutRequestOp::ObjectStoreAddOrPutRequestOp(
aTransaction->GetMetadataForObjectStoreId(mParams.objectStoreId());
MOZ_ASSERT(mMetadata);
const_cast<bool&>(mObjectStoreHasIndexes) = mMetadata->HasLiveIndexes();
const_cast<bool&>(mObjectStoreMayHaveIndexes) = mMetadata->HasLiveIndexes();
}
nsresult
@ -22886,7 +22963,18 @@ ObjectStoreAddOrPutRequestOp::RemoveOldIndexDataValues(
MOZ_ASSERT(aConnection);
MOZ_ASSERT(mOverwrite);
MOZ_ASSERT(!mResponse.IsUnset());
MOZ_ASSERT(mObjectStoreHasIndexes);
#ifdef DEBUG
{
bool hasIndexes = false;
MOZ_ASSERT(NS_SUCCEEDED(
DatabaseOperationBase::ObjectStoreHasIndexes(aConnection,
mParams.objectStoreId(),
&hasIndexes)));
MOZ_ASSERT(hasIndexes,
"Don't use this slow method if there are no indexes!");
}
#endif
DatabaseConnection::CachedStatement indexValuesStmt;
nsresult rv = aConnection->GetCachedStatement(NS_LITERAL_CSTRING(
@ -23098,8 +23186,6 @@ ObjectStoreAddOrPutRequestOp::DoDatabaseWork(DatabaseConnection* aConnection)
aConnection->AssertIsOnConnectionThread();
MOZ_ASSERT(aConnection->GetStorageConnection());
MOZ_ASSERT_IF(mFileManager, !mStoredFileInfos.IsEmpty());
MOZ_ASSERT(mObjectStoreHasIndexes ==
ObjectStoreHasIndexes(aConnection, mParams.objectStoreId()));
PROFILER_LABEL("IndexedDB",
"ObjectStoreAddOrPutRequestOp::DoDatabaseWork",
@ -23115,6 +23201,16 @@ ObjectStoreAddOrPutRequestOp::DoDatabaseWork(DatabaseConnection* aConnection)
return rv;
}
bool objectStoreHasIndexes;
rv = ObjectStoreHasIndexes(this,
aConnection,
mParams.objectStoreId(),
mObjectStoreMayHaveIndexes,
&objectStoreHasIndexes);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// This will be the final key we use.
Key& key = mResponse;
key = mParams.key();
@ -23125,7 +23221,7 @@ ObjectStoreAddOrPutRequestOp::DoDatabaseWork(DatabaseConnection* aConnection)
// First delete old index_data_values if we're overwriting something and we
// have indexes.
if (mOverwrite && !keyUnset && mObjectStoreHasIndexes) {
if (mOverwrite && !keyUnset && objectStoreHasIndexes) {
rv = RemoveOldIndexDataValues(aConnection);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
@ -23779,7 +23875,7 @@ ObjectStoreDeleteRequestOp::ObjectStoreDeleteRequestOp(
const ObjectStoreDeleteParams& aParams)
: NormalTransactionOp(aTransaction)
, mParams(aParams)
, mObjectStoreHasIndexes(false)
, mObjectStoreMayHaveIndexes(false)
{
AssertIsOnBackgroundThread();
MOZ_ASSERT(aTransaction);
@ -23788,7 +23884,7 @@ ObjectStoreDeleteRequestOp::ObjectStoreDeleteRequestOp(
aTransaction->GetMetadataForObjectStoreId(mParams.objectStoreId());
MOZ_ASSERT(metadata);
const_cast<bool&>(mObjectStoreHasIndexes) = metadata->HasLiveIndexes();
const_cast<bool&>(mObjectStoreMayHaveIndexes) = metadata->HasLiveIndexes();
}
nsresult
@ -23796,9 +23892,6 @@ ObjectStoreDeleteRequestOp::DoDatabaseWork(DatabaseConnection* aConnection)
{
MOZ_ASSERT(aConnection);
aConnection->AssertIsOnConnectionThread();
MOZ_ASSERT(mObjectStoreHasIndexes ==
ObjectStoreHasIndexes(aConnection, mParams.objectStoreId()));
PROFILER_LABEL("IndexedDB",
"ObjectStoreDeleteRequestOp::DoDatabaseWork",
js::ProfileEntry::Category::STORAGE);
@ -23809,7 +23902,17 @@ ObjectStoreDeleteRequestOp::DoDatabaseWork(DatabaseConnection* aConnection)
return rv;
}
if (mObjectStoreHasIndexes) {
bool objectStoreHasIndexes;
rv = ObjectStoreHasIndexes(this,
aConnection,
mParams.objectStoreId(),
mObjectStoreMayHaveIndexes,
&objectStoreHasIndexes);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (objectStoreHasIndexes) {
rv = DeleteObjectStoreDataTableRowsWithIndexes(aConnection,
mParams.objectStoreId(),
mParams.keyRange());
@ -23864,7 +23967,7 @@ ObjectStoreClearRequestOp::ObjectStoreClearRequestOp(
const ObjectStoreClearParams& aParams)
: NormalTransactionOp(aTransaction)
, mParams(aParams)
, mObjectStoreHasIndexes(false)
, mObjectStoreMayHaveIndexes(false)
{
AssertIsOnBackgroundThread();
MOZ_ASSERT(aTransaction);
@ -23873,7 +23976,7 @@ ObjectStoreClearRequestOp::ObjectStoreClearRequestOp(
aTransaction->GetMetadataForObjectStoreId(mParams.objectStoreId());
MOZ_ASSERT(metadata);
const_cast<bool&>(mObjectStoreHasIndexes) = metadata->HasLiveIndexes();
const_cast<bool&>(mObjectStoreMayHaveIndexes) = metadata->HasLiveIndexes();
}
nsresult
@ -23881,8 +23984,6 @@ ObjectStoreClearRequestOp::DoDatabaseWork(DatabaseConnection* aConnection)
{
MOZ_ASSERT(aConnection);
aConnection->AssertIsOnConnectionThread();
MOZ_ASSERT(mObjectStoreHasIndexes ==
ObjectStoreHasIndexes(aConnection, mParams.objectStoreId()));
PROFILER_LABEL("IndexedDB",
"ObjectStoreClearRequestOp::DoDatabaseWork",
@ -23894,7 +23995,17 @@ ObjectStoreClearRequestOp::DoDatabaseWork(DatabaseConnection* aConnection)
return rv;
}
if (mObjectStoreHasIndexes) {
bool objectStoreHasIndexes;
rv = ObjectStoreHasIndexes(this,
aConnection,
mParams.objectStoreId(),
mObjectStoreMayHaveIndexes,
&objectStoreHasIndexes);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (objectStoreHasIndexes) {
rv = DeleteObjectStoreDataTableRowsWithIndexes(aConnection,
mParams.objectStoreId(),
void_t());

View File

@ -520,7 +520,6 @@ IDBDatabase::CreateObjectStore(
AssertIsOnOwningThread();
IDBTransaction* transaction = IDBTransaction::GetCurrent();
if (!transaction ||
transaction->Database() != this ||
transaction->GetMode() != IDBTransaction::VERSION_CHANGE) {
@ -528,7 +527,10 @@ IDBDatabase::CreateObjectStore(
return nullptr;
}
MOZ_ASSERT(transaction->IsOpen());
if (!transaction->IsOpen()) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
return nullptr;
}
KeyPath keyPath(0);
if (NS_FAILED(KeyPath::Parse(aOptionalParameters.mKeyPath, &keyPath))) {
@ -596,7 +598,6 @@ IDBDatabase::DeleteObjectStore(const nsAString& aName, ErrorResult& aRv)
AssertIsOnOwningThread();
IDBTransaction* transaction = IDBTransaction::GetCurrent();
if (!transaction ||
transaction->Database() != this ||
transaction->GetMode() != IDBTransaction::VERSION_CHANGE) {
@ -604,7 +605,10 @@ IDBDatabase::DeleteObjectStore(const nsAString& aName, ErrorResult& aRv)
return;
}
MOZ_ASSERT(transaction->IsOpen());
if (!transaction->IsOpen()) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
return;
}
nsTArray<ObjectStoreSpec>& specArray = mSpec->objectStores();

View File

@ -223,6 +223,11 @@ IDBIndex::GetInternal(bool aKeyOnly,
{
AssertIsOnOwningThread();
if (mDeletedMetadata) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
return nullptr;
}
IDBTransaction* transaction = mObjectStore->Transaction();
if (!transaction->IsOpen()) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
@ -306,6 +311,11 @@ IDBIndex::GetAllInternal(bool aKeysOnly,
{
AssertIsOnOwningThread();
if (mDeletedMetadata) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
return nullptr;
}
IDBTransaction* transaction = mObjectStore->Transaction();
if (!transaction->IsOpen()) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
@ -387,6 +397,11 @@ IDBIndex::OpenCursorInternal(bool aKeysOnly,
{
AssertIsOnOwningThread();
if (mDeletedMetadata) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
return nullptr;
}
IDBTransaction* transaction = mObjectStore->Transaction();
if (!transaction->IsOpen()) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
@ -483,6 +498,11 @@ IDBIndex::Count(JSContext* aCx,
{
AssertIsOnOwningThread();
if (mDeletedMetadata) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
return nullptr;
}
IDBTransaction* transaction = mObjectStore->Transaction();
if (!transaction->IsOpen()) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);

View File

@ -1160,6 +1160,11 @@ IDBObjectStore::AddOrPut(JSContext* aCx,
MOZ_ASSERT(aCx);
MOZ_ASSERT_IF(aFromCursor, aOverwrite);
if (mDeletedSpec) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
return nullptr;
}
if (!mTransaction->IsOpen()) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
return nullptr;
@ -1314,6 +1319,11 @@ IDBObjectStore::GetAllInternal(bool aKeysOnly,
{
AssertIsOnOwningThread();
if (mDeletedSpec) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
return nullptr;
}
if (!mTransaction->IsOpen()) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
return nullptr;
@ -1386,6 +1396,11 @@ IDBObjectStore::Clear(ErrorResult& aRv)
{
AssertIsOnOwningThread();
if (mDeletedSpec) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
return nullptr;
}
if (!mTransaction->IsOpen()) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
return nullptr;
@ -1572,6 +1587,11 @@ IDBObjectStore::Get(JSContext* aCx,
{
AssertIsOnOwningThread();
if (mDeletedSpec) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
return nullptr;
}
if (!mTransaction->IsOpen()) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
return nullptr;
@ -1620,6 +1640,11 @@ IDBObjectStore::DeleteInternal(JSContext* aCx,
{
AssertIsOnOwningThread();
if (mDeletedSpec) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
return nullptr;
}
if (!mTransaction->IsOpen()) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
return nullptr;
@ -1713,15 +1738,18 @@ IDBObjectStore::CreateIndexInternal(
{
AssertIsOnOwningThread();
IDBTransaction* transaction = IDBTransaction::GetCurrent();
if (!transaction ||
transaction != mTransaction ||
mTransaction->GetMode() != IDBTransaction::VERSION_CHANGE) {
if (mTransaction->GetMode() != IDBTransaction::VERSION_CHANGE ||
mDeletedSpec) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
return nullptr;
}
IDBTransaction* transaction = IDBTransaction::GetCurrent();
if (!transaction || transaction != mTransaction) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
return nullptr;
}
MOZ_ASSERT(transaction->IsOpen());
auto& indexes = const_cast<nsTArray<IndexMetadata>&>(mSpec->indexes());
@ -1793,15 +1821,18 @@ IDBObjectStore::DeleteIndex(const nsAString& aName, ErrorResult& aRv)
{
AssertIsOnOwningThread();
IDBTransaction* transaction = IDBTransaction::GetCurrent();
if (!transaction ||
transaction != mTransaction ||
mTransaction->GetMode() != IDBTransaction::VERSION_CHANGE) {
if (mTransaction->GetMode() != IDBTransaction::VERSION_CHANGE ||
mDeletedSpec) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
return;
}
IDBTransaction* transaction = IDBTransaction::GetCurrent();
if (!transaction || transaction != mTransaction) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
return;
}
MOZ_ASSERT(transaction->IsOpen());
auto& metadataArray = const_cast<nsTArray<IndexMetadata>&>(mSpec->indexes());
@ -1866,6 +1897,13 @@ IDBObjectStore::Count(JSContext* aCx,
JS::Handle<JS::Value> aKey,
ErrorResult& aRv)
{
AssertIsOnOwningThread();
if (mDeletedSpec) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
return nullptr;
}
if (!mTransaction->IsOpen()) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
return nullptr;
@ -1916,6 +1954,11 @@ IDBObjectStore::OpenCursorInternal(bool aKeysOnly,
{
AssertIsOnOwningThread();
if (mDeletedSpec) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
return nullptr;
}
if (!mTransaction->IsOpen()) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
return nullptr;

View File

@ -58,6 +58,9 @@
let event = yield undefined;
let db = event.target.result;
db.onversionchange = function(event) {
event.target.close();
};
is(db.version, 1, "Correct version");
is(db.objectStoreNames.length, 0, "Correct objectStoreNames length");
@ -104,6 +107,9 @@
event = yield undefined;
db = event.target.result;
db.onversionchange = function(event) {
event.target.close();
};
event.target.transaction.oncomplete = grabEventAndContinueHandler;
event.target.transaction.onabort = unexpectedSuccessHandler;
@ -153,14 +159,15 @@
ok(db.objectStoreNames.contains("foo"), "Has correct objectStore");
ok(db.objectStoreNames.contains("bar"), "Has correct objectStore");
db.close();
request = indexedDB.open(window.location.pathname, 2);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
event = yield undefined;
db = event.target.result;
db.onversionchange = function(event) {
event.target.close();
};
trans = event.target.transaction;
trans.oncomplete = unexpectedSuccessHandler;

View File

@ -12,6 +12,7 @@ function testSteps()
let request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let db = request.result;
@ -33,6 +34,9 @@ function testSteps()
request.onsuccess = unexpectedSuccessHandler;
yield undefined;
// Wait for success.
yield undefined;
finishTest();
yield undefined;
}

View File

@ -29,6 +29,7 @@ function testSteps()
request = indexedDB.open(name, i + 1);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
let db = event.target.result;
@ -85,6 +86,10 @@ function testSteps()
ok(true, "7");
ok(obj.data, event.target.result.data,
"Unique index was properly updated.");
// Wait for success
yield undefined;
db.close();
}

View File

@ -16,6 +16,7 @@ function testSteps()
let request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let db = event.target.result;
@ -372,6 +373,11 @@ function testSteps()
is(keyIndex, -1, "Saw all added items");
// Wait for success
yield undefined;
db.close();
finishTest();
yield undefined;
}

View File

@ -13,6 +13,7 @@ function testSteps()
var request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
var event = yield undefined;
is(event.target.source, null, "correct event.target.source");
@ -27,6 +28,9 @@ function testSteps()
ok(event.target.source === objectStore, "correct event.source");
// Wait for success
yield undefined;
finishTest();
yield undefined;
}

View File

@ -12,6 +12,7 @@ function testSteps()
let request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let db = event.target.result;
@ -276,6 +277,9 @@ function testSteps()
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
// Wait for success
yield undefined;
finishTest();
yield undefined;
}
}

View File

@ -27,6 +27,9 @@ function testSteps()
let event = yield undefined;
let db = event.target.result;
db.onversionchange = function(event) {
event.target.close();
};
let objectStore =
db.createObjectStore(objectStores[i].name,
@ -48,7 +51,6 @@ function testSteps()
event = yield undefined;
ok(event.target.result == 1 || event.target.result == 2, "Good id");
db.close();
}
executeSoon(function() { testGenerator.next(); });

View File

@ -12,6 +12,7 @@ function testSteps()
var request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
var event = yield undefined;
var db = event.target.result;
@ -45,6 +46,9 @@ function testSteps()
// Ensure that the id was also stored on the object.
is(event.target.result.id, id, "The object had the id stored on it.");
// Wait for success
yield undefined;
finishTest();
yield undefined;
}

View File

@ -42,9 +42,13 @@ function testSteps()
let request = indexedDB.open(name, i+1);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let db = event.target.result;
db.onversionchange = function(event) {
event.target.close();
};
let objectStore = db.createObjectStore(test.name,
{ keyPath: test.keyName,
@ -77,7 +81,9 @@ function testSteps()
event = yield undefined;
ok(event.target.result === undefined, "Object was deleted");
db.close();
// Wait for success
yield undefined;
}
finishTest();

View File

@ -16,6 +16,7 @@ function testSteps()
let request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let db = event.target.result;
@ -42,10 +43,13 @@ function testSteps()
request.onerror = errorHandler;
request.onsuccess = function(event) {
is(event.target.result, testInt.value, "Got the right value");
finishTest();
};
}
// Wait for success
yield undefined;
finishTest();
yield undefined;
}

View File

@ -16,6 +16,7 @@ function testSteps()
let request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let db = event.target.result;
@ -42,9 +43,12 @@ function testSteps()
request.onerror = errorHandler;
request.onsuccess = function(event) {
is(event.target.result, testInt.value, "Got the right value");
finishTest();
};
}
// Wait for success
yield undefined;
}
finishTest();
yield undefined;
}

View File

@ -13,8 +13,12 @@ function testSteps()
let request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = unexpectedSuccessHandler;
let event = yield undefined;
request.onupgradeneeded = unexpectedSuccessHandler;
request.onsuccess = grabEventAndContinueHandler;
let db = event.target.result;
is(db.objectStoreNames.length, 0, "Correct objectStoreNames list");
@ -40,13 +44,20 @@ function testSteps()
event.target.transaction.oncomplete = grabEventAndContinueHandler;
event = yield undefined;
// Wait for success.
event = yield undefined;
db.close();
request = indexedDB.open(name, 2);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = unexpectedSuccessHandler;
event = yield undefined;
request.onupgradeneeded = unexpectedSuccessHandler;
request.onsuccess = grabEventAndContinueHandler;
db = event.target.result;
let trans = event.target.transaction;
@ -87,6 +98,9 @@ function testSteps()
trans.oncomplete = grabEventAndContinueHandler;
event = yield undefined;
// Wait for success.
event = yield undefined;
db.close();
request = indexedDB.open(name, 3);

View File

@ -14,6 +14,7 @@ function testSteps()
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
is(request.readyState, "done", "Correct readyState");
@ -42,6 +43,9 @@ function testSteps()
ok(event.target.result, "Got something");
is(request.readyState, "done", "Correct readyState");
// Wait for success
yield undefined;
finishTest();
yield undefined;
}

View File

@ -15,6 +15,7 @@ function testSteps()
let event = yield undefined;
let db = event.target.result;
db.close();
// Check default state.
is(db.version, 1, "Correct default version for a new database.");
@ -24,14 +25,13 @@ function testSteps()
42,
];
db.close();
for (let i = 0; i < versions.length; i++) {
let version = versions[i];
let request = indexedDB.open(name, version);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let db = event.target.result;
@ -39,8 +39,9 @@ function testSteps()
is(db.version, version, "Database version number updated correctly");
is(event.target.transaction.mode, "versionchange", "Correct mode");
executeSoon(function() { testGenerator.next(); });
// Wait for success
yield undefined;
db.close();
}

View File

@ -33,7 +33,7 @@ interface nsIServiceWorkerInfo : nsISupports
readonly attribute DOMString waitingCacheName;
};
[scriptable, builtinclass, uuid(5e112a42-df4c-4ae9-bc71-e6e681ab5f38)]
[scriptable, builtinclass, uuid(aee94712-9adb-4c0b-80a7-a8df34dfa2e8)]
interface nsIServiceWorkerManager : nsISupports
{
/**
@ -105,12 +105,7 @@ interface nsIServiceWorkerManager : nsISupports
* - Unregister jobs will be queued for all registrations.
* This eventually results in the registration being deleted from disk too.
*/
void remove(in AUTF8String aHost);
/*
* Clear all registrations for all hosts. See remove().
*/
void removeAll();
void removeAndPropagate(in AUTF8String aHost);
// Testing
DOMString getScopeForUrl(in nsIPrincipal aPrincipal, in DOMString aPath);

View File

@ -1244,26 +1244,6 @@ ContentChild::RecvUpdateServiceWorkerRegistrations()
return true;
}
bool
ContentChild::RecvRemoveServiceWorkerRegistrationsForDomain(const nsString& aDomain)
{
nsCOMPtr<nsIServiceWorkerManager> swm = mozilla::services::GetServiceWorkerManager();
if (swm) {
swm->Remove(NS_ConvertUTF16toUTF8(aDomain));
}
return true;
}
bool
ContentChild::RecvRemoveServiceWorkerRegistrations()
{
nsCOMPtr<nsIServiceWorkerManager> swm = mozilla::services::GetServiceWorkerManager();
if (swm) {
swm->RemoveAll();
}
return true;
}
static CancelableTask* sFirstIdleTask;
static void FirstIdle(void)

View File

@ -305,10 +305,6 @@ public:
virtual bool RecvUpdateServiceWorkerRegistrations() override;
virtual bool RecvRemoveServiceWorkerRegistrationsForDomain(const nsString& aDomain) override;
virtual bool RecvRemoveServiceWorkerRegistrations() override;
virtual bool RecvNotifyVisited(const URIParams& aURI) override;
// auto remove when alertfinished is received.
nsresult AddRemoteAlertObserver(const nsString& aData, nsIObserver* aObserver);

View File

@ -506,10 +506,6 @@ child:
async UpdateServiceWorkerRegistrations();
async RemoveServiceWorkerRegistrationsForDomain(nsString aDomain);
async RemoveServiceWorkerRegistrations();
async DataStoreNotify(uint32_t aAppId, nsString aName,
nsString aManifestURL);

View File

@ -156,7 +156,7 @@ public:
NS_IMETHOD IsReportForBrowser(nsIFrameLoader* aFrameLoader, bool* aResult) override;
// Called on xpcom shutdown
// Called when a content process shuts down.
void Clear() {
mContentParent = nullptr;
mActor = nullptr;
@ -456,11 +456,25 @@ HangMonitorParent::HangMonitorParent(ProcessHangMonitor* aMonitor)
mReportHangs = mozilla::Preferences::GetBool("dom.ipc.reportProcessHangs", false);
}
static PLDHashOperator
DeleteMinidump(const uint32_t& aPluginId, nsString aCrashId, void* aUserData)
{
#ifdef MOZ_CRASHREPORTER
if (!aCrashId.IsEmpty()) {
CrashReporter::DeleteMinidumpFilesForID(aCrashId);
}
#endif
return PL_DHASH_NEXT;
}
HangMonitorParent::~HangMonitorParent()
{
// For some reason IPDL doesn't autmatically delete the channel for a
// bridged protocol (bug 1090570). So we have to do it ourselves.
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new DeleteTask<Transport>(GetTransport()));
MutexAutoLock lock(mBrowserCrashDumpHashLock);
mBrowserCrashDumpIds.EnumerateRead(DeleteMinidump, nullptr);
}
void
@ -805,7 +819,9 @@ HangMonitoredProcess::TerminatePlugin()
uint32_t id = mHangData.get_PluginHangData().pluginId();
plugins::TerminatePlugin(id, mBrowserDumpId);
mActor->CleanupPluginHang(id, false);
if (mActor) {
mActor->CleanupPluginHang(id, false);
}
return NS_OK;
}
@ -818,7 +834,7 @@ HangMonitoredProcess::TerminateProcess()
return NS_ERROR_UNEXPECTED;
}
if (mHangData.type() == HangData::TPluginHangData) {
if (mActor && mHangData.type() == HangData::TPluginHangData) {
uint32_t id = mHangData.get_PluginHangData().pluginId();
mActor->CleanupPluginHang(id, true);
}
@ -855,8 +871,10 @@ HangMonitoredProcess::UserCanceled()
return NS_OK;
}
uint32_t id = mHangData.get_PluginHangData().pluginId();
mActor->CleanupPluginHang(id, true);
if (mActor) {
uint32_t id = mHangData.get_PluginHangData().pluginId();
mActor->CleanupPluginHang(id, true);
}
return NS_OK;
}

View File

@ -2146,6 +2146,13 @@ TabChild::RecvNotifyAPZStateChange(const ViewID& aViewId,
const int& aArg)
{
mAPZEventState->ProcessAPZStateChange(GetDocument(), aViewId, aChange, aArg);
if (aChange == APZStateChange::TransformEnd) {
// This is used by tests to determine when the APZ is done doing whatever
// it's doing. XXX generify this as needed when writing additional tests.
DispatchMessageManagerMessage(
NS_LITERAL_STRING("APZ:TransformEnd"),
NS_LITERAL_STRING("{}"));
}
return true;
}

View File

@ -488,11 +488,13 @@ SourceBuffer::AppendDataCompletedWithSuccess(bool aHasActiveTracks)
}
}
}
if (mActive) {
if (mActive && mIsUsingFormatReader) {
// Tell our parent decoder that we have received new data.
// The information provided do not matter much so long as it is monotonically
// increasing.
mMediaSource->GetDecoder()->NotifyDataArrived(nullptr, 1, mReportedOffset++);
// Send progress event.
mMediaSource->GetDecoder()->NotifyBytesDownloaded();
}
CheckEndTime();

View File

@ -123,6 +123,7 @@ public:
gfxContext* aCtx, const nsIntRect&) override;
virtual void GetLibraryPath(nsACString& aPath) { aPath.Assign(mFilePath); }
virtual nsresult GetRunID(uint32_t* aRunID) override { return NS_ERROR_NOT_IMPLEMENTED; }
virtual void SetHasLocalInstance() override { }
private:
NP_InitializeFunc mNP_Initialize;

View File

@ -955,6 +955,8 @@ nsPluginHost::TrySetUpPluginInstance(const nsACString &aMimeType,
NS_ASSERTION(pluginTag, "Must have plugin tag here!");
plugin->GetLibrary()->SetHasLocalInstance();
#if defined(MOZ_WIDGET_ANDROID) && defined(MOZ_CRASHREPORTER)
if (pluginTag->mIsFlashPlugin) {
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("FlashVersion"), pluginTag->mVersion);

View File

@ -148,6 +148,7 @@ nsPluginTag::nsPluginTag(nsPluginInfo* aPluginInfo,
bool fromExtension)
: mId(sNextId++),
mContentProcessRunningCount(0),
mHadLocalInstance(false),
mName(aPluginInfo->fName),
mDescription(aPluginInfo->fDescription),
mLibrary(nullptr),

View File

@ -90,6 +90,10 @@ public:
// Number of PluginModuleParents living in all content processes.
size_t mContentProcessRunningCount;
// True if we've ever created an instance of this plugin in the current process.
bool mHadLocalInstance;
nsCString mName; // UTF-8
nsCString mDescription; // UTF-8
nsTArray<nsCString> mMimeTypes; // UTF-8

View File

@ -353,8 +353,7 @@ PluginHangUIParent::RecvUserResponse(const unsigned int& aResponse)
int responseCode;
if (aResponse & HANGUI_USER_RESPONSE_STOP) {
// User clicked Stop
nsString dummy;
mModule->TerminateChildProcess(mMainThreadMessageLoop, &dummy);
mModule->TerminateChildProcess(mMainThreadMessageLoop, EmptyString());
responseCode = 1;
} else if(aResponse & HANGUI_USER_RESPONSE_CONTINUE) {
mModule->OnHangUIContinue();

View File

@ -85,6 +85,7 @@ public:
virtual nsresult EndUpdateBackground(NPP instance,
gfxContext*, const nsIntRect&) = 0;
virtual nsresult GetRunID(uint32_t* aRunID) = 0;
virtual void SetHasLocalInstance() = 0;
};

View File

@ -67,7 +67,6 @@ const wchar_t * kMozillaWindowClass = L"MozillaWindowClass";
namespace {
// see PluginModuleChild::GetChrome()
PluginModuleChild* gChromeInstance = nullptr;
nsTArray<PluginModuleChild*>* gAllInstances;
}
#ifdef MOZ_WIDGET_QT
@ -127,6 +126,7 @@ PluginModuleChild::PluginModuleChild(bool aIsChrome)
, mPluginFilename("")
, mQuirks(QUIRKS_NOT_INITIALIZED)
, mIsChrome(aIsChrome)
, mHasShutdown(false)
, mTransport(nullptr)
, mShutdownFunc(0)
, mInitializeFunc(0)
@ -142,17 +142,12 @@ PluginModuleChild::PluginModuleChild(bool aIsChrome)
, mGlobalCallWndProcHook(nullptr)
#endif
{
if (!gAllInstances) {
gAllInstances = new nsTArray<PluginModuleChild*>(1);
}
gAllInstances->AppendElement(this);
memset(&mFunctions, 0, sizeof(mFunctions));
if (mIsChrome) {
MOZ_ASSERT(!gChromeInstance);
gChromeInstance = this;
}
mUserAgent.SetIsVoid(true);
#ifdef XP_MACOSX
if (aIsChrome) {
mac_plugin_interposing::child::SetUpCocoaInterposing();
@ -170,13 +165,6 @@ PluginModuleChild::~PluginModuleChild()
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new DeleteTask<Transport>(mTransport));
}
gAllInstances->RemoveElement(this);
MOZ_ASSERT_IF(mIsChrome, gAllInstances->Length() == 0);
if (gAllInstances->IsEmpty()) {
delete gAllInstances;
gAllInstances = nullptr;
}
if (mIsChrome) {
MOZ_ASSERT(gChromeInstance == this);
@ -694,12 +682,16 @@ PluginModuleChild::DeinitGraphics()
#endif
}
bool
PluginModuleChild::AnswerNP_Shutdown(NPError *rv)
NPError
PluginModuleChild::NP_Shutdown()
{
AssertPluginThread();
MOZ_ASSERT(mIsChrome);
if (mHasShutdown) {
return NPERR_NO_ERROR;
}
#if defined XP_WIN
mozilla::widget::StopAudioSession();
#endif
@ -707,7 +699,7 @@ PluginModuleChild::AnswerNP_Shutdown(NPError *rv)
// the PluginModuleParent shuts down this process after this interrupt
// call pops off its stack
*rv = mShutdownFunc ? mShutdownFunc() : NPERR_NO_ERROR;
NPError rv = mShutdownFunc ? mShutdownFunc() : NPERR_NO_ERROR;
// weakly guard against re-entry after NP_Shutdown
memset(&mFunctions, 0, sizeof(mFunctions));
@ -718,6 +710,15 @@ PluginModuleChild::AnswerNP_Shutdown(NPError *rv)
GetIPCChannel()->SetAbortOnError(false);
mHasShutdown = true;
return rv;
}
bool
PluginModuleChild::AnswerNP_Shutdown(NPError *rv)
{
*rv = NP_Shutdown();
return true;
}
@ -839,6 +840,11 @@ PluginModuleChild::ActorDestroy(ActorDestroyReason why)
QuickExit();
}
if (!mHasShutdown) {
MOZ_ASSERT(gChromeInstance == this);
NP_Shutdown();
}
// doesn't matter why we're being destroyed; it's up to us to
// initiate (clean) shutdown
XRE_ShutdownChildProcess();

View File

@ -177,6 +177,8 @@ public:
void CleanUp();
NPError NP_Shutdown();
const char* GetUserAgent();
static const NPNetscapeFuncs sBrowserFuncs;
@ -323,10 +325,10 @@ private:
PRLibrary* mLibrary;
nsCString mPluginFilename; // UTF8
nsCString mUserAgent;
int mQuirks;
bool mIsChrome;
bool mHasShutdown; // true if NP_Shutdown has run
Transport* mTransport;
// we get this from the plugin

View File

@ -359,10 +359,9 @@ mozilla::plugins::TerminatePlugin(uint32_t aPluginId, const nsString& aBrowserDu
if (!pluginTag || !pluginTag->mPlugin) {
return;
}
nsAutoString dumpId(aBrowserDumpId);
nsRefPtr<nsNPAPIPlugin> plugin = pluginTag->mPlugin;
PluginModuleChromeParent* chromeParent = static_cast<PluginModuleChromeParent*>(plugin->GetLibrary());
chromeParent->TerminateChildProcess(MessageLoop::current(), &dumpId);
chromeParent->TerminateChildProcess(MessageLoop::current(), aBrowserDumpId);
}
/* static */ PluginLibrary*
@ -622,6 +621,7 @@ PluginModuleChromeParent::WaitForIPCConnection()
PluginModuleParent::PluginModuleParent(bool aIsChrome)
: mIsChrome(aIsChrome)
, mShutdown(false)
, mHadLocalInstance(false)
, mClearSiteDataSupported(false)
, mGetSitesWithDataSupported(false)
, mNPNIface(nullptr)
@ -1154,8 +1154,7 @@ PluginModuleChromeParent::ShouldContinueFromReplyTimeout()
// original plugin hang behaviour and kill the plugin container.
FinishHangUI();
#endif // XP_WIN
nsString dummy;
TerminateChildProcess(MessageLoop::current(), &dummy);
TerminateChildProcess(MessageLoop::current(), EmptyString());
GetIPCChannel()->CloseWithTimeout();
return false;
}
@ -1179,7 +1178,7 @@ PluginModuleContentParent::OnExitedSyncSend()
void
PluginModuleChromeParent::TerminateChildProcess(MessageLoop* aMsgLoop,
nsAString* aBrowserDumpId)
const nsAString& aBrowserDumpId)
{
#ifdef MOZ_CRASHREPORTER
#ifdef XP_WIN
@ -1215,8 +1214,8 @@ PluginModuleChromeParent::TerminateChildProcess(MessageLoop* aMsgLoop,
// since the posted message will trash our browser stack state.
bool exists;
nsCOMPtr<nsIFile> browserDumpFile;
if (aBrowserDumpId && !aBrowserDumpId->IsEmpty() &&
CrashReporter::GetMinidumpForID(*aBrowserDumpId, getter_AddRefs(browserDumpFile)) &&
if (!aBrowserDumpId.IsEmpty() &&
CrashReporter::GetMinidumpForID(aBrowserDumpId, getter_AddRefs(browserDumpFile)) &&
browserDumpFile &&
NS_SUCCEEDED(browserDumpFile->Exists(&exists)) && exists)
{
@ -1226,7 +1225,7 @@ PluginModuleChromeParent::TerminateChildProcess(MessageLoop* aMsgLoop,
NS_LITERAL_CSTRING("browser"));
if (!reportsReady) {
browserDumpFile = nullptr;
CrashReporter::DeleteMinidumpFilesForID(*aBrowserDumpId);
CrashReporter::DeleteMinidumpFilesForID(aBrowserDumpId);
}
}
@ -2387,7 +2386,12 @@ bool
PluginModuleParent::DoShutdown(NPError* error)
{
bool ok = true;
if (IsChrome()) {
if (IsChrome() && mHadLocalInstance) {
// We synchronously call NP_Shutdown if the chrome process was using
// plugins itself. That way we can service any requests the plugin
// makes. If we're in e10s, though, the content processes will have
// already shut down and there's no one to talk to. So we shut down
// asynchronously in PluginModuleChild::ActorDestroy.
ok = CallNP_Shutdown(error);
}

View File

@ -133,6 +133,9 @@ public:
}
virtual nsresult GetRunID(uint32_t* aRunID) override;
virtual void SetHasLocalInstance() override {
mHadLocalInstance = true;
}
protected:
virtual mozilla::ipc::RacyInterruptPolicy
@ -284,6 +287,7 @@ protected:
bool mIsChrome;
bool mShutdown;
bool mHadLocalInstance;
bool mClearSiteDataSupported;
bool mGetSitesWithDataSupported;
NPNetscapeFuncs* mNPNIface;
@ -387,7 +391,7 @@ class PluginModuleChromeParent
* generating a multi-process crash report. If not provided a browser
* dump will be taken at the time of this call.
*/
void TerminateChildProcess(MessageLoop* aMsgLoop, nsAString* aBrowserDumpId);
void TerminateChildProcess(MessageLoop* aMsgLoop, const nsAString& aBrowserDumpId);
#ifdef XP_WIN
/**

View File

@ -16,7 +16,9 @@ interface MouseEvent : UIEvent {
readonly attribute long screenY;
readonly attribute long clientX;
readonly attribute long clientY;
[Pref="dom.mouseEvent.offsetXY.enabled"]
readonly attribute long offsetX;
[Pref="dom.mouseEvent.offsetXY.enabled"]
readonly attribute long offsetY;
readonly attribute boolean ctrlKey;
readonly attribute boolean shiftKey;

View File

@ -21,6 +21,8 @@ interface ServiceWorkerGlobalScope : WorkerGlobalScope {
attribute EventHandler oninstall;
attribute EventHandler onactivate;
[Func="mozilla::dom::workers::ServiceWorkerGlobalScope::InterceptionEnabled"]
attribute EventHandler onfetch;
attribute EventHandler onbeforeevicted;
attribute EventHandler onevicted;

View File

@ -25,12 +25,18 @@ parent:
nsString scope);
PropagateUnregister(PrincipalInfo principalInfo, nsString scope);
PropagateRemove(nsCString host);
PropagateRemoveAll();
Shutdown();
child:
NotifyRegister(ServiceWorkerRegistrationData data);
NotifySoftUpdate(OriginAttributes originAttributes, nsString scope);
NotifyUnregister(PrincipalInfo principalInfo, nsString scope);
NotifyRemove(nsCString host);
NotifyRemoveAll();
__delete__();
};

View File

@ -161,6 +161,7 @@ static_assert(MAX_WORKERS_PER_DOMAIN >= 1,
#define PREF_WORKERS_LATEST_JS_VERSION "dom.workers.latestJSVersion"
#define PREF_INTL_ACCEPT_LANGUAGES "intl.accept_languages"
#define PREF_SERVICEWORKERS_ENABLED "dom.serviceWorkers.enabled"
#define PREF_INTERCEPTION_ENABLED "dom.serviceWorkers.interception.enabled"
namespace {
@ -1905,6 +1906,10 @@ RuntimeService::Init()
WorkerPrefChanged,
PREF_SERVICEWORKERS_ENABLED,
reinterpret_cast<void *>(WORKERPREF_SERVICEWORKERS))) ||
NS_FAILED(Preferences::RegisterCallbackAndCall(
WorkerPrefChanged,
PREF_INTERCEPTION_ENABLED,
reinterpret_cast<void *>(WORKERPREF_INTERCEPTION_ENABLED))) ||
NS_FAILED(Preferences::RegisterCallback(LoadRuntimeOptions,
PREF_JS_OPTIONS_PREFIX,
nullptr)) ||
@ -2100,6 +2105,10 @@ RuntimeService::Cleanup()
NS_FAILED(Preferences::UnregisterCallback(LoadRuntimeOptions,
PREF_WORKERS_OPTIONS_PREFIX,
nullptr)) ||
NS_FAILED(Preferences::UnregisterCallback(
WorkerPrefChanged,
PREF_INTERCEPTION_ENABLED,
reinterpret_cast<void *>(WORKERPREF_INTERCEPTION_ENABLED))) ||
NS_FAILED(Preferences::UnregisterCallback(
WorkerPrefChanged,
PREF_SERVICEWORKERS_ENABLED,
@ -2656,6 +2665,10 @@ RuntimeService::WorkerPrefChanged(const char* aPrefName, void* aClosure)
key = WORKERPREF_SERVICEWORKERS;
sDefaultPreferences[WORKERPREF_SERVICEWORKERS] =
Preferences::GetBool(PREF_SERVICEWORKERS_ENABLED, false);
} else if (key == WORKERPREF_INTERCEPTION_ENABLED) {
key = WORKERPREF_INTERCEPTION_ENABLED;
sDefaultPreferences[key] =
Preferences::GetBool(PREF_INTERCEPTION_ENABLED, false);
}
// This function should never be registered as a callback for a preference it
// does not handle.

View File

@ -740,7 +740,7 @@ public:
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
MOZ_ASSERT(swm);
swm->PropagateSoftUpdate(mOriginAttributes,mScope);
swm->PropagateSoftUpdate(mOriginAttributes, mScope);
return NS_OK;
}
@ -789,6 +789,76 @@ private:
const nsString mScope;
};
class RemoveRunnable final : public nsRunnable
{
public:
explicit RemoveRunnable(const nsACString& aHost)
{}
NS_IMETHOD Run() override
{
MOZ_ASSERT(NS_IsMainThread());
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
MOZ_ASSERT(swm);
swm->Remove(mHost);
return NS_OK;
}
private:
~RemoveRunnable()
{}
const nsCString mHost;
};
class PropagateRemoveRunnable final : public nsRunnable
{
public:
explicit PropagateRemoveRunnable(const nsACString& aHost)
{}
NS_IMETHOD Run() override
{
MOZ_ASSERT(NS_IsMainThread());
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
MOZ_ASSERT(swm);
swm->PropagateRemove(mHost);
return NS_OK;
}
private:
~PropagateRemoveRunnable()
{}
const nsCString mHost;
};
class PropagateRemoveAllRunnable final : public nsRunnable
{
public:
PropagateRemoveAllRunnable()
{}
NS_IMETHOD Run() override
{
MOZ_ASSERT(NS_IsMainThread());
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
MOZ_ASSERT(swm);
swm->PropagateRemoveAll();
return NS_OK;
}
private:
~PropagateRemoveAllRunnable()
{}
};
} // anonymous namespace
class ServiceWorkerRegisterJob final : public ServiceWorkerJob,
@ -2313,6 +2383,9 @@ private:
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
MOZ_ASSERT(swm->mActor);
swm->mActor->SendUnregister(principalInfo, NS_ConvertUTF8toUTF16(mScope));
nsAutoCString scopeKey;
nsresult rv = swm->PrincipalToScopeKey(mPrincipal, scopeKey);
if (NS_WARN_IF(NS_FAILED(rv))) {
@ -2355,9 +2428,6 @@ private:
swm->RemoveRegistration(registration);
}
MOZ_ASSERT(swm->mActor);
swm->mActor->SendUnregister(principalInfo, NS_ConvertUTF8toUTF16(mScope));
return NS_OK;
}
@ -4322,20 +4392,64 @@ ServiceWorkerManager::ForceUnregister(RegistrationDataPerPrincipal* aRegistratio
}
NS_IMETHODIMP
ServiceWorkerManager::Remove(const nsACString& aHost)
ServiceWorkerManager::RemoveAndPropagate(const nsACString& aHost)
{
AssertIsOnMainThread();
mRegistrationInfos.EnumerateRead(UnregisterIfMatchesHostPerPrincipal,
&const_cast<nsACString&>(aHost));
Remove(aHost);
PropagateRemove(aHost);
return NS_OK;
}
NS_IMETHODIMP
void
ServiceWorkerManager::Remove(const nsACString& aHost)
{
AssertIsOnMainThread();
// We need to postpone this operation in case we don't have an actor because
// this is needed by the ForceUnregister.
if (!mActor) {
nsRefPtr<nsIRunnable> runnable = new RemoveRunnable(aHost);
AppendPendingOperation(runnable);
return;
}
mRegistrationInfos.EnumerateRead(UnregisterIfMatchesHostPerPrincipal,
&const_cast<nsACString&>(aHost));
}
void
ServiceWorkerManager::PropagateRemove(const nsACString& aHost)
{
AssertIsOnMainThread();
if (!mActor) {
nsRefPtr<nsIRunnable> runnable = new PropagateRemoveRunnable(aHost);
AppendPendingOperation(runnable);
return;
}
mActor->SendPropagateRemove(nsCString(aHost));
}
void
ServiceWorkerManager::RemoveAll()
{
AssertIsOnMainThread();
mRegistrationInfos.EnumerateRead(UnregisterIfMatchesHostPerPrincipal, nullptr);
return NS_OK;
}
void
ServiceWorkerManager::PropagateRemoveAll()
{
AssertIsOnMainThread();
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
if (!mActor) {
nsRefPtr<nsIRunnable> runnable = new PropagateRemoveAllRunnable();
AppendPendingOperation(runnable);
return;
}
mActor->SendPropagateRemoveAll();
}
static PLDHashOperator
@ -4385,23 +4499,19 @@ ServiceWorkerManager::Observe(nsISupports* aSubject,
{
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
nsAutoTArray<ContentParent*,1> children;
ContentParent::GetAll(children);
if (strcmp(aTopic, PURGE_SESSION_HISTORY) == 0) {
for (uint32_t i = 0; i < children.Length(); i++) {
unused << children[i]->SendRemoveServiceWorkerRegistrations();
}
RemoveAll();
} else if (strcmp(aTopic, PURGE_DOMAIN_DATA) == 0) {
nsAutoString domain(aData);
for (uint32_t i = 0; i < children.Length(); i++) {
unused << children[i]->SendRemoveServiceWorkerRegistrationsForDomain(domain);
}
PropagateRemoveAll();
return NS_OK;
}
Remove(NS_ConvertUTF16toUTF8(domain));
} else if (strcmp(aTopic, WEBAPPS_CLEAR_DATA) == 0) {
if (strcmp(aTopic, PURGE_DOMAIN_DATA) == 0) {
nsAutoString domain(aData);
RemoveAndPropagate(NS_ConvertUTF16toUTF8(domain));
return NS_OK;
}
if (strcmp(aTopic, WEBAPPS_CLEAR_DATA) == 0) {
nsCOMPtr<mozIApplicationClearPrivateDataParams> params =
do_QueryInterface(aSubject);
if (NS_WARN_IF(!params)) {

View File

@ -308,6 +308,18 @@ public:
PropagateSoftUpdate(const OriginAttributes& aOriginAttributes,
const nsAString& aScope);
void
PropagateRemove(const nsACString& aHost);
void
Remove(const nsACString& aHost);
void
PropagateRemoveAll();
void
RemoveAll();
already_AddRefed<ServiceWorkerRegistrationInfo>
GetRegistration(nsIPrincipal* aPrincipal, const nsACString& aScope) const;

View File

@ -67,6 +67,34 @@ ServiceWorkerManagerChild::RecvNotifyUnregister(const PrincipalInfo& aPrincipalI
return true;
}
bool
ServiceWorkerManagerChild::RecvNotifyRemove(const nsCString& aHost)
{
if (mShuttingDown) {
return true;
}
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
MOZ_ASSERT(swm);
swm->Remove(aHost);
return true;
}
bool
ServiceWorkerManagerChild::RecvNotifyRemoveAll()
{
if (mShuttingDown) {
return true;
}
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
MOZ_ASSERT(swm);
swm->RemoveAll();
return true;
}
} // workers namespace
} // dom namespace
} // mozilla namespace

View File

@ -42,6 +42,10 @@ public:
virtual bool RecvNotifyUnregister(const PrincipalInfo& aPrincipalInfo,
const nsString& aScope) override;
virtual bool RecvNotifyRemove(const nsCString& aHost) override;
virtual bool RecvNotifyRemoveAll() override;
private:
ServiceWorkerManagerChild()
: mShuttingDown(false)

View File

@ -256,6 +256,32 @@ ServiceWorkerManagerParent::RecvPropagateUnregister(const PrincipalInfo& aPrinci
return true;
}
bool
ServiceWorkerManagerParent::RecvPropagateRemove(const nsCString& aHost)
{
AssertIsOnBackgroundThread();
if (NS_WARN_IF(!mService)) {
return false;
}
mService->PropagateRemove(mID, aHost);
return true;
}
bool
ServiceWorkerManagerParent::RecvPropagateRemoveAll()
{
AssertIsOnBackgroundThread();
if (NS_WARN_IF(!mService)) {
return false;
}
mService->PropagateRemoveAll(mID);
return true;
}
bool
ServiceWorkerManagerParent::RecvShutdown()
{

View File

@ -48,6 +48,10 @@ private:
virtual bool RecvPropagateUnregister(const PrincipalInfo& aPrincipalInfo,
const nsString& aScope) override;
virtual bool RecvPropagateRemove(const nsCString& aHost) override;
virtual bool RecvPropagateRemoveAll() override;
virtual bool RecvShutdown() override;
virtual void ActorDestroy(ActorDestroyReason aWhy) override;

View File

@ -227,6 +227,93 @@ UnregisterEnumerator(nsPtrHashKey<ServiceWorkerManagerParent>* aKey, void* aPtr)
return PL_DHASH_NEXT;
}
struct MOZ_STACK_CLASS RemoveAllData final
{
explicit RemoveAllData(uint64_t aParentID)
: mParentID(aParentID)
#ifdef DEBUG
, mParentFound(false)
#endif
{
MOZ_COUNT_CTOR(RemoveAllData);
}
~RemoveAllData()
{
MOZ_COUNT_DTOR(RemoveAllData);
}
const uint64_t mParentID;
#ifdef DEBUG
bool mParentFound;
#endif
};
PLDHashOperator
RemoveAllEnumerator(nsPtrHashKey<ServiceWorkerManagerParent>* aKey, void* aPtr)
{
AssertIsOnBackgroundThread();
auto* data = static_cast<RemoveAllData*>(aPtr);
ServiceWorkerManagerParent* parent = aKey->GetKey();
MOZ_ASSERT(parent);
if (parent->ID() != data->mParentID) {
unused << parent->SendNotifyRemoveAll();
#ifdef DEBUG
} else {
data->mParentFound = true;
#endif
}
return PL_DHASH_NEXT;
}
struct MOZ_STACK_CLASS RemoveData final
{
RemoveData(const nsACString& aHost,
uint64_t aParentID)
: mHost(aHost)
, mParentID(aParentID)
#ifdef DEBUG
, mParentFound(false)
#endif
{
MOZ_COUNT_CTOR(RemoveData);
}
~RemoveData()
{
MOZ_COUNT_DTOR(RemoveData);
}
const nsCString mHost;
const uint64_t mParentID;
#ifdef DEBUG
bool mParentFound;
#endif
};
PLDHashOperator
RemoveEnumerator(nsPtrHashKey<ServiceWorkerManagerParent>* aKey, void* aPtr)
{
AssertIsOnBackgroundThread();
auto* data = static_cast<RemoveData*>(aPtr);
ServiceWorkerManagerParent* parent = aKey->GetKey();
MOZ_ASSERT(parent);
if (parent->ID() != data->mParentID) {
unused << parent->SendNotifyRemove(data->mHost);
#ifdef DEBUG
} else {
data->mParentFound = true;
#endif
}
return PL_DHASH_NEXT;
}
} // anonymous namespce
void
@ -285,6 +372,39 @@ ServiceWorkerManagerService::PropagateUnregister(
#endif
}
void
ServiceWorkerManagerService::PropagateRemove(uint64_t aParentID,
const nsACString& aHost)
{
AssertIsOnBackgroundThread();
RemoveData data(aHost, aParentID);
mAgents.EnumerateEntries(RemoveEnumerator, &data);
#ifdef DEBUG
MOZ_ASSERT(data.mParentFound);
#endif
}
void
ServiceWorkerManagerService::PropagateRemoveAll(uint64_t aParentID)
{
AssertIsOnBackgroundThread();
nsRefPtr<dom::ServiceWorkerRegistrar> service =
dom::ServiceWorkerRegistrar::Get();
MOZ_ASSERT(service);
service->RemoveAll();
RemoveAllData data(aParentID);
mAgents.EnumerateEntries(RemoveAllEnumerator, &data);
#ifdef DEBUG
MOZ_ASSERT(data.mParentFound);
#endif
}
} // workers namespace
} // dom namespace
} // mozilla namespace

View File

@ -49,6 +49,10 @@ public:
const mozilla::ipc::PrincipalInfo& aPrincipalInfo,
const nsAString& aScope);
void PropagateRemove(uint64_t aParentID, const nsACString& aHost);
void PropagateRemoveAll(uint64_t aParentID);
private:
ServiceWorkerManagerService();
~ServiceWorkerManagerService();

View File

@ -213,6 +213,31 @@ ServiceWorkerRegistrar::UnregisterServiceWorker(
}
}
void
ServiceWorkerRegistrar::RemoveAll()
{
AssertIsOnBackgroundThread();
if (mShuttingDown) {
NS_WARNING("Failed to remove all the serviceWorkers during shutting down.");
return;
}
bool deleted = false;
{
MonitorAutoLock lock(mMonitor);
MOZ_ASSERT(mDataLoaded);
deleted = !mData.IsEmpty();
mData.Clear();
}
if (deleted) {
ScheduleSaveData();
}
}
void
ServiceWorkerRegistrar::LoadData()
{

View File

@ -54,6 +54,7 @@ public:
void RegisterServiceWorker(const ServiceWorkerRegistrationData& aData);
void UnregisterServiceWorker(const mozilla::ipc::PrincipalInfo& aPrincipalInfo,
const nsACString& aScope);
void RemoveAll();
protected:
// These methods are protected because we test this class using gTest

View File

@ -4095,7 +4095,7 @@ WorkerPrivateParent<Derived>::SetBaseURI(nsIURI* aBaseURI)
if (NS_SUCCEEDED(aBaseURI->GetRef(temp)) && !temp.IsEmpty()) {
nsCOMPtr<nsITextToSubURI> converter =
do_GetService(NS_ITEXTTOSUBURI_CONTRACTID);
if (converter && nsContentUtils::EncodeDecodeURLHash()) {
if (converter && nsContentUtils::GettersDecodeURLHash()) {
nsCString charset;
nsAutoString unicodeRef;
if (NS_SUCCEEDED(aBaseURI->GetOriginCharset(charset)) &&

View File

@ -1239,6 +1239,13 @@ public:
return mPreferences[WORKERPREF_SERVICEWORKERS];
}
bool
InterceptionEnabled() const
{
AssertIsOnWorkerThread();
return mPreferences[WORKERPREF_INTERCEPTION_ENABLED];
}
bool
OnLine() const
{

View File

@ -621,6 +621,16 @@ ServiceWorkerGlobalScope::SkipWaiting(ErrorResult& aRv)
return promise.forget();
}
// static
bool
ServiceWorkerGlobalScope::InterceptionEnabled(JSContext* aCx, JSObject* aObj)
{
WorkerPrivate* worker = GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(worker);
worker->AssertIsOnWorkerThread();
return worker->InterceptionEnabled();
}
WorkerDebuggerGlobalScope::WorkerDebuggerGlobalScope(
WorkerPrivate* aWorkerPrivate)
: mWorkerPrivate(aWorkerPrivate)

View File

@ -215,6 +215,9 @@ public:
WrapGlobalObject(JSContext* aCx,
JS::MutableHandle<JSObject*> aReflector) override;
static bool
InterceptionEnabled(JSContext* aCx, JSObject* aObj);
void
GetScope(nsString& aScope) const
{

View File

@ -198,6 +198,7 @@ enum WorkerPreference
WORKERPREF_DUMP = 0, // browser.dom.window.dump.enabled
WORKERPREF_DOM_CACHES, // dom.caches.enabled
WORKERPREF_SERVICEWORKERS, // dom.serviceWorkers.enabled
WORKERPREF_INTERCEPTION_ENABLED, // dom.serviceWorkers.interception.enabled
WORKERPREF_COUNT
};

View File

@ -0,0 +1,4 @@
// Only succeeds if onfetch is available.
if (!("onfetch" in self)) {
throw new Error("Not capable of interception");
}

View File

@ -129,6 +129,7 @@ support-files =
strict_mode_error.js
skip_waiting_installed_worker.js
skip_waiting_scope/index.html
interception_featuredetect.js
thirdparty/iframe1.html
thirdparty/iframe2.html
thirdparty/register.html
@ -140,57 +141,59 @@ support-files =
eval_worker.js
test_eval_not_allowed.html^headers^
[test_unregister.html]
[test_installation_simple.html]
[test_app_protocol.html]
[test_bug1151916.html]
[test_claim.html]
[test_claim_fetch.html]
[test_claim_oninstall.html]
[test_client_focus.html]
[test_close.html]
[test_controller.html]
[test_cross_origin_url_after_redirect.html]
[test_empty_serviceworker.html]
[test_eval_allowed.html]
[test_eval_not_allowed.html]
[test_fetch_event.html]
[test_force_refresh.html]
[test_gzip_redirect.html]
[test_https_fetch.html]
[test_https_fetch_cloned_response.html]
[test_https_origin_after_redirect.html]
[test_https_origin_after_redirect_cached.html]
[test_https_synth_fetch_from_cached_sw.html]
[test_importscript.html]
[test_install_event.html]
[test_installation_simple.html]
[test_interception_featuredetect.html]
[test_match_all.html]
[test_match_all_advanced.html]
[test_install_event.html]
[test_navigator.html]
[test_scopes.html]
[test_controller.html]
[test_workerUnregister.html]
[test_workerUpdate.html]
[test_post_message.html]
[test_post_message_advanced.html]
[test_post_message_source.html]
[test_match_all_client_properties.html]
[test_close.html]
[test_serviceworker_interfaces.html]
[test_serviceworker_not_sharedworker.html]
[test_match_all_client_id.html]
[test_sandbox_intercept.html]
[test_request_context.html]
[test_importscript.html]
[test_client_focus.html]
[test_bug1151916.html]
[test_workerupdatefoundevent.html]
[test_empty_serviceworker.html]
[test_periodic_update.html]
[test_claim_oninstall.html]
[test_claim.html]
[test_periodic_https_update.html]
[test_sanitize.html]
[test_sanitize_domain.html]
[test_service_worker_allowed.html]
[test_app_protocol.html]
[test_third_party_iframes.html]
[test_claim_fetch.html]
[test_force_refresh.html]
[test_skip_waiting.html]
[test_strict_mode_error.html]
[test_cross_origin_url_after_redirect.html]
[test_match_all_client_properties.html]
[test_navigator.html]
[test_origin_after_redirect.html]
[test_origin_after_redirect_cached.html]
[test_origin_after_redirect_to_https.html]
[test_origin_after_redirect_to_https_cached.html]
[test_https_origin_after_redirect.html]
[test_https_origin_after_redirect_cached.html]
[test_gzip_redirect.html]
[test_periodic_https_update.html]
[test_periodic_update.html]
[test_post_message.html]
[test_post_message_advanced.html]
[test_post_message_source.html]
[test_register_base.html]
[test_register_https_in_http.html]
[test_eval_allowed.html]
[test_eval_not_allowed.html]
[test_request_context.html]
skip-if = toolkit == 'android' # Bug 1163410
[test_scopes.html]
[test_sandbox_intercept.html]
[test_sanitize.html]
[test_sanitize_domain.html]
[test_service_worker_allowed.html]
[test_serviceworker_interfaces.html]
[test_serviceworker_not_sharedworker.html]
[test_skip_waiting.html]
[test_strict_mode_error.html]
[test_third_party_iframes.html]
[test_unregister.html]
[test_workerUnregister.html]
[test_workerUpdate.html]
[test_workerupdatefoundevent.html]

View File

@ -65,6 +65,7 @@ function runTheTest() {
SpecialPowers.pushPrefEnv({"set": [
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.serviceWorkers.interception.enabled", true],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true],
]}, function() {

View File

@ -27,6 +27,7 @@ function setup() {
SpecialPowers.pushPrefEnv({'set': [
['dom.mozBrowserFramesEnabled', true],
['dom.serviceWorkers.exemptFromPerDomainMax', true],
["dom.serviceWorkers.interception.enabled", true],
['dom.serviceWorkers.enabled', true],
['dom.serviceWorkers.testing.enabled', true],
['dom.caches.enabled', true],

View File

@ -94,6 +94,7 @@
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.serviceWorkers.interception.enabled", true],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true],
["dom.caches.enabled", true],

View File

@ -162,6 +162,7 @@
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.serviceWorkers.interception.enabled", true],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true]
]}, runTest);

View File

@ -88,6 +88,7 @@
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.serviceWorkers.interception.enabled", true],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true]
]}, runTest);

View File

@ -63,6 +63,7 @@
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.serviceWorkers.interception.enabled", true],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true]
]}, runTest);

View File

@ -86,6 +86,7 @@
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.serviceWorkers.interception.enabled", true],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true],
]}, runTest);

View File

@ -54,6 +54,7 @@
onload = function() {
SpecialPowers.pushPrefEnv({"set": [
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.serviceWorkers.interception.enabled", true],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true],
]}, runTest);

View File

@ -74,6 +74,7 @@
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.serviceWorkers.interception.enabled", true],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true]
]}, runTest);

Some files were not shown because too many files have changed in this diff Show More