mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
merge mozilla-inbound to mozilla-central a=merge
This commit is contained in:
commit
135b0588cd
@ -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');
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -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");
|
||||
|
@ -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");
|
||||
|
@ -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:
|
||||
|
@ -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 += [
|
||||
|
@ -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']
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -410,7 +410,6 @@ private:
|
||||
bool mBroken : 1;
|
||||
bool mUserDisabled : 1;
|
||||
bool mSuppressed : 1;
|
||||
bool mFireEventsOnDecode : 1;
|
||||
|
||||
protected:
|
||||
/**
|
||||
|
@ -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));
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -920,5 +920,5 @@
|
||||
};
|
||||
|
||||
if (inNode) module.exports = obj;
|
||||
else window.WebIDL2 = obj;
|
||||
else self.WebIDL2 = obj;
|
||||
}());
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -1,6 +0,0 @@
|
||||
# THIS FILE IS AUTOGENERATED BY parseFailures.py - DO NOT EDIT
|
||||
[DEFAULT]
|
||||
support-files =
|
||||
|
||||
|
||||
[test_interfaces.html.json]
|
@ -1,4 +0,0 @@
|
||||
{
|
||||
"XMLHttpRequestUpload interface: existence and properties of interface object": true,
|
||||
"XMLHttpRequest interface: existence and properties of interface object": true
|
||||
}
|
@ -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
@ -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',
|
||||
]
|
||||
|
@ -14,11 +14,6 @@ html {
|
||||
background: red;
|
||||
}
|
||||
|
||||
#log pre {
|
||||
border: 1px solid black;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
section#summary {
|
||||
margin-bottom:1em;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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(); });
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -506,10 +506,6 @@ child:
|
||||
|
||||
async UpdateServiceWorkerRegistrations();
|
||||
|
||||
async RemoveServiceWorkerRegistrationsForDomain(nsString aDomain);
|
||||
|
||||
async RemoveServiceWorkerRegistrations();
|
||||
|
||||
async DataStoreNotify(uint32_t aAppId, nsString aName,
|
||||
nsString aManifestURL);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -148,6 +148,7 @@ nsPluginTag::nsPluginTag(nsPluginInfo* aPluginInfo,
|
||||
bool fromExtension)
|
||||
: mId(sNextId++),
|
||||
mContentProcessRunningCount(0),
|
||||
mHadLocalInstance(false),
|
||||
mName(aPluginInfo->fName),
|
||||
mDescription(aPluginInfo->fDescription),
|
||||
mLibrary(nullptr),
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
/**
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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__();
|
||||
};
|
||||
|
@ -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.
|
||||
|
@ -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)) {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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)) &&
|
||||
|
@ -1239,6 +1239,13 @@ public:
|
||||
return mPreferences[WORKERPREF_SERVICEWORKERS];
|
||||
}
|
||||
|
||||
bool
|
||||
InterceptionEnabled() const
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
return mPreferences[WORKERPREF_INTERCEPTION_ENABLED];
|
||||
}
|
||||
|
||||
bool
|
||||
OnLine() const
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,4 @@
|
||||
// Only succeeds if onfetch is available.
|
||||
if (!("onfetch" in self)) {
|
||||
throw new Error("Not capable of interception");
|
||||
}
|
@ -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]
|
||||
|
@ -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() {
|
||||
|
@ -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],
|
||||
|
@ -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],
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user