mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:18:48 +00:00
import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1216751 part 1. Restrict value iterators to interfaces that have indexed properties and pair iterators to interfaces that do not have indexed properties. r=qdot (6519f3f8c5) - Bug 1216751 part 2. For value iterators, "entries", "keys", and "values" must just come from Array.prototype. r=qdot (c0859f945c) - Bug 1216751 part 3. For pair iterators, @@iterator should be an alias for "entries". Similarly for maplikes and "entries" and setlikes and "values". r=qdot (bbe7c04782) - Bug 1216751 part 4. Implement forEach for iterable interfaces. r=qdot (8fdba677a4) - Bug 1216751 part 5. Remove the now-unnecessary value iterator infrastructure, since it's entirely handled via the %ArrayPrototype% methods now. r=qdot (88d3911694) - Bug 1231333 - part 1, JS engine: only allow futexWait in workers. r=luke (28e16fd2f9) - Bug 1231333 - part 2, DOM: only allow futexWait in workers. r=khuey (6c4dc98037) - Bug 1148990 - Don't ship bagheeraclient.js or tokenserverclient.js on Android. r=gps (aa9b22699a) - Bug 1216749 - Land the Firefox Kinto.js client (r=rnewman) (ea8c74e2ea) - Bug 1230221 - Convert JS callsites to use asyncOpen2 within services/ (r=sicking) (07ac8751f1) - Bug 1242965 - Make services/common eslintable. r=rnewman (0c84562750) - Bug 1055616 - Skip addons addons without a sourceURI or from a non-secure domain rather than treating them as errors. r=rnewman (7b8b738be0) - Bug 1229986 - get Sync tps tests starting again. r=whimboo (8cd0bf4f7f) - Bug 1003204: Removed CommonUtils.exceptionStr() in services/sync r=makh r=gfritzsche (830c106a29) - Bug 1003204: Removed CommonUtils.exceptionStr() in services/common/ r=gfritzsche (2c7bd4f8b5) - Bug 1234734 - Replace CommonUtils.stackTrace() with Log.stackTrace(). r=markh (3f0e88f192) - Bug 1241715 - get Sync TPS tests working locally by tweaking observers listened for and the authentication setup. r=whimboo (529b2f3d44) - Bug 1203736 - Convert H264::DecodeSPS assert to error return. r=jya (41c8c34c42) - Bug 1186716: Error if SPS NAL parsing failed. r=rillian (6c158be51e) - Bug 1187076 - Warn at end of SPS buffers. r=jya (2a49671261) - fix broken files (a090aad200) - Bug 1218217: avoid buffersize overflow even if codec is unbounded in dimensions r=pkerr (356140c947) - Bug 1218217: bustage fix for static assert r=bustage (e86dc5bf3a) - Bug 1041882 - Remove Froyo-specific support from libcubeb. r=snorp, r=padenot (e1f2d5283f) - Bug 1073319 - Enable AVX2 for libvpx on linux (update.py). r=rillian (934fd0a896) - Bug 1245027 - Move LOCAL_INCLUDES to moz.build in media/libvpx. r=mshal (7e56797d0e) - parts of Bug 1151175 - Update libvpx update.py for 1.4.0. (0e3f4a470f) - bits of 1178215 (bab7592703) - Bug 1218124 - Add vpx_once patch to update script. r=gerald (7b72a43382) - Bug 1225221 - vpx: Allow 8k video in update.sh. r=kinetik (9ec59f7737) - Bug 1224363 - Upstream update patch - r=rillian (4772921a5f) - Bug 1224361 - Upstream update patch - r=rillian (36ad6f1de4) - Bug 1233983 - Make libvpx build with clang-cl; r=rillian (5d98a8d888) - Bug 1224371 - Upstream update patch. r=jya (25164ba856) - Bug 1237848 - Updated update.py patch - r=rillian (69646eb6dc) - Bug 1184226 - Suppressing received packets when disabled, r=ekr (c8dfdb1a56) - Bug 1184226 - Disabling write on shutdown, r=ekr (d5a810dbe5) - Bug 1184226 - Updating transportlayerdtls logging levels, r=ekr (f3bc4a9889) - Bug 1137932: Unwind the stack before starting the DTLS handshake. r=mt (69dce8243a) - Bug 1214269 - read multiple DTLS packets from NSS if present. r=mt rjesup (e57b1628f5) - Bug 1235235 - Fix -Wimplicit-fallthrough warning in media/mtransport/. r=ekr (d56c9d1244) - Bug 1115483 - Accept a match on any a=fingerprint value. r=ekr (4a58378c09) - Bug 1167274 - Do the right thing when accessing the proxyinfo fails for some reason. r=mt (3ea23173ea) - Bug 1125292 - Sending ALPN header field for WebRTC calls, r=bwc (16fda60c39) - Bug 1167443 - Fix verification of end-of-candidates in mochitests. r=mt (8d74546e68) - Bug 1192813 - update the default candidate as new candidates arrive. r=bwc (490ac80af2) - Bug 1206981 - prevent ICE TCP from being turned off under e10s. r=jesup (a38afd56b8) - Bug 1234578 - Assert if PCM is destroyed improperly. r=rjesup (f1aa0d7cbc) - Bug 1164564 - WorkerDebugger.initialize should not return failure when called more than once;r=khuey (c316c83af7) - Bug 1211903 - WorkerDebugger should live on the main thread;r=khuey (5586888e77) - Bug 1164581 - Adding an overload for NS_ProxyRelease that accepts already_AddRefed, and removing all the others. r=bobbyholley (bc70230689) - Bug 1186750 part 1 - Inlinize trivial constructors and destructors of events in DeviceStorageRequestParent. r=dhylands (0fc6b594b1) - Bug 1186750 part 2 - Remove some unused member fields in events in DeviceStorageRequestParent. r=dhylands (d4be7e7031) - Bug 1186750 part 3 - Abstract CancelableFileEvent in DeviceStorageReqeustParent and use already_AddRefed&& for passing DeviceStorageFile parameter. r=dhylands (cea4df4465) - Bug 1186750 part 4 - Clear runnable list in DeviceStorageRequestParent when being destroyed. r=dhylands (a4d6018ce6) - Bug 1196315 - Ensure MIME service is only accessed on the main thread. r=dhylands (20c07f4baf) - Bug 1186750 part 5 - Convert nsDOMDeviceStorage::CheckPermission to take already_AddRefed&&. r=dhylands (7b2d0b415e) - Bug 1186750 part 6 - Remove unused and unimplemented method nsDOMDeviceStorage::StorePermission. r=dhylands (e6772e7b51) - Bug 1186750 part 7 - Convert DispatchToOwningThread and DispatchOrAbandon to take already_AddRefed&&. r=dhylands (5925568a22) - Bug 1186750 part 8 - Convert DeviceStorageUsedSpaceCache::Dispatch to use already_AddRef&&. r=dhylands (660b44eec7) - Bug 1186750 part 9 - Use already_AddRefed&& to initialize mFile of device storage requests. r=dhylands (c94464f412) - Bug 1186750 part 10 - Simplify code in DeviceStorageRequestParent::Dispatch. r=dhylands (debcc219ca) - Bug 1186750 part 11 - Convert all usage of Dispatch/NS_DispatchToMainThread in dom/devicestorage to pass in either already_AddRefed or raw pointer. r=dhylands (753694d0b5) - Bug 1059469: Part 1 - Add a log module for dump() calls. r=bent (d94c677e49) - Bug 1059469: Part 2 - When rescheduling the interval timer, cancel it first, and refactor things so that actually does something. r=bent (1edc485b0f) - Bug 1243881 - patch 1 - unship performance.translateTime, r=bz (5a4afeea67) - Bug 1243881 - patch 2 - unship performance.translateTime, r=bz (5bf9557cd4) - Bug 1165722 - Replace JS_GetPropertyDescriptor usage in Xray code. r=bholley (e277cbcc78) - Bug 1243824. Add support for static functions and attributes on JSXrays. r=bholley (498d6c6034) - Bug 1228456 - SharedWorker should close the MessagePort in case the connecting runnable is not dispatched, r=smaug (c14a3e212f) - Bug 779707 - Add crashtest. (e86caca48e) - Bug 1228456 - add 'override' to the Cancel() method of a nsICancelableRunnable, rs=me (48db3b97e9) - Bug 1131323 - Enable SharedWorker loads to be intercepted through service workers; r=nsm (b2d972c5e3) - Bug 1173002 - Set worker system principal flag correctly when created from chrome, r=bz, a=kwierso. (ac9fc2980d) - bits of 1113429 backout (a862f16bb7) - bug 1206312 - add IndexedDatabaseManager include to IDBKeyRange. r=bz (bd6663f976) - Bug 1247117: De-namespace much of IndexedDB. r=baku (a996e3b443) - Bug 1196841: Update getAll/getAllKeys to match the spec and expose them. r=baku (7365769e04) - Bug 1196840: Make IDBTransaction::ObjectStoreNames const. r=baku (e7af2b0510) - Bug 1176165 - Fix the exception codes returned from functions that modify the IndexedDB schema, r=janv. (efa4e818d0) - Bug 935753 - Firefox displays the "This is a secure Firefox page" indicator on pages served by addons. r=MattN (77dced27ad) - Bug 925681 - Show identity block and reload icon in awesomebar in Australis' customization mode. ui-r=shorlander, r=Gijs (ffd1b2f6a4) - Bug 970382 - Add about:accounts to the list of chrome UIs with a special identity mode r=gavin (6d2817d087) - Bug 1051847 - Add trusted identity block to about:license and about:rights. r=dao (aa8dfe4d1d) - Bug 1094947 - The trusted identity block is not displayed for the about:downloads page. r=jaws (1c51faa077) - Bug 686281 - Implement CSS mask style; r=dbaron. (2f823c4a49) - Bug 686281 - Mask CSS parsing and Mask DOM API. r=dbaron (f9cc291131) - Bug 686281 - Mask CSS rendering; r=mstange (b26ba7ba7e) - Bug 686281 - Mask CSS animation; r=dbaron. (4ce1ba671e) - Bug 686281 - Mask CSS webkit-alias; r=dbaron. (c27f4023d6) - Bug 686281 - Mask mochitest; r=dbaron. (010fcdfd04) - Bug 686281 - Expands will-change of a shorthand prop to longhand ones; r=dbaron. (f8e4a6dcfd) - Bug 686281 - A static assertion to keep value correctness of NS_RULE_NODE_IS_ANIMATION_RULE; r=dbaron. (5ae87b576b) - Bug 686281 - Remove nsStyleSVGReset::mMask; r=dbaron (1e7a0dfb45) - Bug 686281 - mask-composite reftests; r=dbaron (7f769e196a) - Bug 686281 - Rename nsStyleSVGReset::mLayers to nsStyleSVGReset::mMask; Rename nsStyleBackground::mLayers to nsStyleBackground::mImage. r=dbaron (3bd4fc6e3b) - Bug 1241275 - Change the way -moz-window-dragging works. r=heycam,roc (5691f2dbf5) - Bug 1246892 - pass aCTF as a reference instead of value. r=roc (98b0e45063) - Bug 1234800 - Reinstate code that adjusts dirty rects for fixed-position frames in display ports. r=tn (44e55ebacb) - Bug 1234800 - Move this line to the right place. r=tn (1a86a7fc72) - Bug 1216832 - Handle preserve-3d visible regions during display list building by always transforming from the preserve-3d root each time. r=roc (1887af1172) - Bug 1231243 - In nsDisplayBackgroundImage::GetBoundsInternal(), take the union of the image bounds and the viewport bounds if APZ is enabled. r=mstange (87a1fa0ab4) - Bug 1246622 - Handle nested preserve-3d contexts when hit testing. r=roc (6eed51c734) - Bug 1235945 - Fix assertion error in some cases when running szip when debug flags are enabled for host tools. r=froydnj (3a0aa4f728) - Bug 1224798: Do not produce a clip mask if our context is entirely clipped out anyway. r=jrmuizel (3926a4ef7d) - Bug 1223604 - Disentangle nsSVGClipPathFrame::ApplyClipOrPaintClipMask and make the code easier to understand. r=Bas (c8c19a1b0d) - Bug 1204405: Don't access prefs off main thread in testing ProcessLink::Open(). r=khuey (301aa7259d) - Bug 1248896 - don't conditional compile on config ENABLE_TESTS in Nuwa. r=khuey (4f2fd275fd) - Bug 1232458 - use UniquePtr<T[]> instead of nsAutoArrayPtr<T> in WindowsDllBlocklist.cpp; r=aklotz (292071bdb5) - Bug 1247741 - Additional checks for pointer validity in LdrLoadDLL detour. r=aklotz (8ee48e8cf3) - Bug 1113930 - Move __libc_stack_end related code block from StackWalk.cpp in a non-OSX section. r=froydnj (4f0f9e2e66) - Bug 1113930 - Use the actual stack end address on x86 OSX and Android for the stack walker. r=froydnj (7371d9a508) - missing bit of Bug 1216681 (fdf69e362f) - Bug 1193593 - Test fingerprinting resistance for media queries in picture elements. r=heycam (6155b73c26) - Bug 1232829 - Detach obsolete DocumentTimeline from refresh driver when the document is reset; r=smaug (564680e2a0) - Bug 1075457, part 1 - Implement rendering for |clip-path:polygon()|. r=mstange, r=jwatt (76056caacd) - Bug 1075457, part 2 - Implement circle() and ellipse() for the |clip-path| property. r=mstange, r=jwatt (4b8b39c682) - Bug 1094571 - add unicode-range load tests. r=heycam (3358555411) - Bug 1216695 - Remove the Request.context specific bits from fetch-request-resources.https.html; r=bkelly (2315e50b97) - Bug 1193133 - Disable broken service worker wpt tests. r=bkelly (8f0205d5e7) - Bug 1199831: Fix a bunch of mixed-content violations in imported ServiceWorker WPTs. r=jdm (33f261ce91) - bit of Bug 603201 (325170577f) - Bug 1184798 - same origin, cors and no-cors load tests. r=bkelly (f8549dd0bb) - Bug 1210581: Test controlled worker loads (XHR, fetch, importScripts). r=ehsan (41a436df47) - Bug 1215196 - Fix web-platform-tests iframe scripts to avoid pulling in testharness.js in them; r=bkelly (a2edb0784c) - Bug 1242798 - Don't OSR into Ion on debuggee frames. (r=jandem) (21e17bdd9d) - Bug 1238658 - Allow setElem-accessor optimizations only for native baseHolder objects; r=efaust (12c9766a53) - Bug 1144630 - Follup: Fix review nit. (rs=evilpie) (67b5cc2c7f) - Bug 1182866 - Fix Baseline GETNAME stubs to check for uninitialized lexicals. (r=jandem) (dd47d2025a) - Bug 1189536 - Make fetch-request-xhr.https.html pass; r=bkelly (ce177226bf) - Bug 1188822 - Make service-workers/service-worker/fetch-request-resources.https.html pass. r=bkelly (3a5f3a6660)
This commit is contained in:
@@ -145,7 +145,6 @@ toolbar[printpreview="true"] {
|
||||
visibility: collapse;
|
||||
}
|
||||
|
||||
#wrapper-urlbar-container #urlbar-container > #urlbar > toolbarbutton,
|
||||
#urlbar-container:not([combined]) > #urlbar > toolbarbutton,
|
||||
#urlbar-container[combined] + #reload-button + #stop-button,
|
||||
#urlbar-container[combined] + #reload-button,
|
||||
|
||||
@@ -6404,14 +6404,17 @@ var gIdentityHandler = {
|
||||
let nsIWebProgressListener = Ci.nsIWebProgressListener;
|
||||
|
||||
// For some URIs like data: we can't get a host and so can't do
|
||||
// anything useful here. Chrome URIs however get special treatment.
|
||||
// anything useful here.
|
||||
let unknown = false;
|
||||
try {
|
||||
uri.host;
|
||||
} catch (e) { unknown = true; }
|
||||
|
||||
if ((uri.scheme == "chrome" || uri.scheme == "about") &&
|
||||
uri.spec !== "about:blank") {
|
||||
// Chrome URIs however get special treatment. Some chrome URIs are
|
||||
// whitelisted to provide a positive security signal to the user.
|
||||
let whitelist = /^about:(accounts|addons|app-manager|config|crashes|customizing|downloads|healthreport|home|license|newaddon|permissions|preferences|privatebrowsing|rights|sessionrestore|support|welcomeback)/i;
|
||||
let isChromeUI = uri.schemeIs("about") && whitelist.test(uri.spec);
|
||||
if (isChromeUI) {
|
||||
this.setMode(this.IDENTITY_MODE_CHROMEUI);
|
||||
} else if (unknown) {
|
||||
this.setMode(this.IDENTITY_MODE_UNKNOWN);
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
const DUMMY = "browser/browser/base/content/test/general/dummy_page.html";
|
||||
|
||||
function loadNewTab(aURL, aCallback) {
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.loadURI(aURL);
|
||||
|
||||
gBrowser.selectedBrowser.addEventListener("load", function() {
|
||||
if (gBrowser.selectedBrowser.currentURI.spec != aURL)
|
||||
return;
|
||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
|
||||
aCallback(gBrowser.selectedTab);
|
||||
}, true);
|
||||
}
|
||||
|
||||
function getIdentityMode() {
|
||||
return document.getElementById("identity-box").className;
|
||||
}
|
||||
|
||||
var TESTS = [
|
||||
function test_webpage() {
|
||||
let oldTab = gBrowser.selectedTab;
|
||||
|
||||
loadNewTab("http://example.com/" + DUMMY, function(aNewTab) {
|
||||
is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
|
||||
|
||||
gBrowser.selectedTab = oldTab;
|
||||
is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
|
||||
|
||||
gBrowser.selectedTab = aNewTab;
|
||||
is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
|
||||
|
||||
gBrowser.removeTab(aNewTab);
|
||||
|
||||
runNextTest();
|
||||
});
|
||||
},
|
||||
|
||||
function test_blank() {
|
||||
let oldTab = gBrowser.selectedTab;
|
||||
|
||||
loadNewTab("about:blank", function(aNewTab) {
|
||||
is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
|
||||
|
||||
gBrowser.selectedTab = oldTab;
|
||||
is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
|
||||
|
||||
gBrowser.selectedTab = aNewTab;
|
||||
is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
|
||||
|
||||
gBrowser.removeTab(aNewTab);
|
||||
|
||||
runNextTest();
|
||||
});
|
||||
},
|
||||
|
||||
function test_chrome() {
|
||||
let oldTab = gBrowser.selectedTab;
|
||||
|
||||
// Since users aren't likely to type in full chrome URLs, we won't show
|
||||
// the positive security indicator on it, but we will show it on about:addons.
|
||||
loadNewTab("chrome://mozapps/content/extensions/extensions.xul", function(aNewTab) {
|
||||
is(getIdentityMode(), "unknownIdentity", "Identity should be chrome");
|
||||
|
||||
gBrowser.selectedTab = oldTab;
|
||||
is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
|
||||
|
||||
gBrowser.selectedTab = aNewTab;
|
||||
is(getIdentityMode(), "unknownIdentity", "Identity should be chrome");
|
||||
|
||||
gBrowser.removeTab(aNewTab);
|
||||
|
||||
runNextTest();
|
||||
});
|
||||
},
|
||||
|
||||
function test_https() {
|
||||
let oldTab = gBrowser.selectedTab;
|
||||
|
||||
loadNewTab("https://example.com/" + DUMMY, function(aNewTab) {
|
||||
is(getIdentityMode(), "verifiedDomain", "Identity should be verified");
|
||||
|
||||
gBrowser.selectedTab = oldTab;
|
||||
is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
|
||||
|
||||
gBrowser.selectedTab = aNewTab;
|
||||
is(getIdentityMode(), "verifiedDomain", "Identity should be verified");
|
||||
|
||||
gBrowser.removeTab(aNewTab);
|
||||
|
||||
runNextTest();
|
||||
});
|
||||
},
|
||||
|
||||
function test_addons() {
|
||||
let oldTab = gBrowser.selectedTab;
|
||||
|
||||
loadNewTab("about:addons", function(aNewTab) {
|
||||
is(getIdentityMode(), "chromeUI", "Identity should be chrome");
|
||||
|
||||
gBrowser.selectedTab = oldTab;
|
||||
is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
|
||||
|
||||
gBrowser.selectedTab = aNewTab;
|
||||
is(getIdentityMode(), "chromeUI", "Identity should be chrome");
|
||||
|
||||
gBrowser.removeTab(aNewTab);
|
||||
|
||||
runNextTest();
|
||||
});
|
||||
}
|
||||
];
|
||||
|
||||
var gTestStart = null;
|
||||
|
||||
function runNextTest() {
|
||||
if (gTestStart)
|
||||
info("Test part took " + (Date.now() - gTestStart) + "ms");
|
||||
|
||||
if (TESTS.length == 0) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
info("Running " + TESTS[0].name);
|
||||
gTestStart = Date.now();
|
||||
TESTS.shift()();
|
||||
};
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
runNextTest();
|
||||
}
|
||||
@@ -110,6 +110,8 @@ void
|
||||
DocumentTimeline::WillRefresh(mozilla::TimeStamp aTime)
|
||||
{
|
||||
MOZ_ASSERT(mIsObservingRefreshDriver);
|
||||
MOZ_ASSERT(GetRefreshDriver(),
|
||||
"Should be able to reach refresh driver from within WillRefresh");
|
||||
|
||||
bool needsTicks = false;
|
||||
nsTArray<Animation*> animationsToRemove(mAnimations.Count());
|
||||
@@ -143,10 +145,13 @@ DocumentTimeline::WillRefresh(mozilla::TimeStamp aTime)
|
||||
}
|
||||
|
||||
if (!needsTicks) {
|
||||
// If another refresh driver observer destroys the nsPresContext,
|
||||
// nsRefreshDriver will detect it and we won't be called.
|
||||
// We already assert that GetRefreshDriver() is non-null at the beginning
|
||||
// of this function but we check it again here to be sure that ticking
|
||||
// animations does not have any side effects that cause us to lose the
|
||||
// connection with the refresh driver, such as triggering the destruction
|
||||
// of mDocument's PresShell.
|
||||
MOZ_ASSERT(GetRefreshDriver(),
|
||||
"Refresh driver should still be valid inside WillRefresh");
|
||||
"Refresh driver should still be valid at end of WillRefresh");
|
||||
GetRefreshDriver()->RemoveRefreshObserver(this, Flush_Style);
|
||||
mIsObservingRefreshDriver = false;
|
||||
}
|
||||
|
||||
@@ -49,17 +49,7 @@ ArchiveReaderEvent::ArchiveReaderEvent(ArchiveReader* aArchiveReader)
|
||||
ArchiveReaderEvent::~ArchiveReaderEvent()
|
||||
{
|
||||
if (!NS_IsMainThread()) {
|
||||
nsIMIMEService* mimeService;
|
||||
mMimeService.forget(&mimeService);
|
||||
|
||||
if (mimeService) {
|
||||
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
|
||||
NS_WARN_IF_FALSE(mainThread, "Couldn't get the main thread! Leaking!");
|
||||
|
||||
if (mainThread) {
|
||||
NS_ProxyRelease(mainThread, mimeService);
|
||||
}
|
||||
}
|
||||
NS_ReleaseOnMainThread(mMimeService.forget());
|
||||
}
|
||||
|
||||
MOZ_COUNT_DTOR(ArchiveReaderEvent);
|
||||
|
||||
@@ -778,11 +778,11 @@ Console::~Console()
|
||||
|
||||
if (!NS_IsMainThread()) {
|
||||
if (mStorage) {
|
||||
NS_ReleaseOnMainThread(mStorage);
|
||||
NS_ReleaseOnMainThread(mStorage.forget());
|
||||
}
|
||||
|
||||
if (mSandbox) {
|
||||
NS_ReleaseOnMainThread(mSandbox);
|
||||
NS_ReleaseOnMainThread(mSandbox.forget());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -636,8 +636,8 @@ WebSocketImpl::Disconnect()
|
||||
// until the end of the method.
|
||||
RefPtr<WebSocketImpl> kungfuDeathGrip = this;
|
||||
|
||||
NS_ReleaseOnMainThread(mChannel);
|
||||
NS_ReleaseOnMainThread(static_cast<nsIWebSocketEventService*>(mService.forget().take()));
|
||||
NS_ReleaseOnMainThread(mChannel.forget());
|
||||
NS_ReleaseOnMainThread(mService.forget());
|
||||
|
||||
mWebSocket->DontKeepAliveAnyMore();
|
||||
mWebSocket->mImpl = nullptr;
|
||||
|
||||
@@ -289,6 +289,8 @@ bool nsContentUtils::sFragmentParsingActive = false;
|
||||
bool nsContentUtils::sDOMWindowDumpEnabled;
|
||||
#endif
|
||||
|
||||
mozilla::LazyLogModule nsContentUtils::sDOMDumpLog("Dump");
|
||||
|
||||
// Subset of http://www.whatwg.org/specs/web-apps/current-work/#autofill-field-name
|
||||
enum AutocompleteFieldName
|
||||
{
|
||||
@@ -7161,6 +7163,12 @@ nsContentUtils::DOMWindowDumpEnabled()
|
||||
#endif
|
||||
}
|
||||
|
||||
mozilla::LogModule*
|
||||
nsContentUtils::DOMDumpLog()
|
||||
{
|
||||
return sDOMDumpLog;
|
||||
}
|
||||
|
||||
bool
|
||||
nsContentUtils::GetNodeTextContent(nsINode* aNode, bool aDeep, nsAString& aResult,
|
||||
const fallible_t& aFallible)
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/FloatingPoint.h"
|
||||
#include "mozilla/net/ReferrerPolicy.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "nsIContentPolicy.h"
|
||||
|
||||
#if defined(XP_WIN)
|
||||
@@ -2380,10 +2381,17 @@ public:
|
||||
const nsAString& aVersion);
|
||||
|
||||
/**
|
||||
* Return true if the browser.dom.window.dump.enabled pref is set.
|
||||
* Returns true if the browser.dom.window.dump.enabled pref is set.
|
||||
*/
|
||||
static bool DOMWindowDumpEnabled();
|
||||
|
||||
/**
|
||||
* Returns a LogModule that dump calls from content script are logged to.
|
||||
* This can be enabled with the 'Dump' module, and is useful for synchronizing
|
||||
* content JS to other logging modules.
|
||||
*/
|
||||
static mozilla::LogModule* DOMDumpLog();
|
||||
|
||||
/**
|
||||
* Returns whether a content is an insertion point for XBL
|
||||
* bindings or web components ShadowRoot. In web components,
|
||||
@@ -2733,6 +2741,7 @@ private:
|
||||
#if !(defined(DEBUG) || defined(MOZ_ENABLE_JS_DUMP))
|
||||
static bool sDOMWindowDumpEnabled;
|
||||
#endif
|
||||
static mozilla::LazyLogModule sDOMDumpLog;
|
||||
};
|
||||
|
||||
class MOZ_RAII nsAutoScriptBlocker {
|
||||
|
||||
@@ -77,8 +77,8 @@
|
||||
#include "mozilla/dom/TabChild.h"
|
||||
#include "mozilla/dom/IDBFactoryBinding.h"
|
||||
#include "mozilla/dom/IDBMutableFileBinding.h"
|
||||
#include "mozilla/dom/indexedDB/IDBMutableFile.h"
|
||||
#include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
|
||||
#include "mozilla/dom/IDBMutableFile.h"
|
||||
#include "mozilla/dom/IndexedDatabaseManager.h"
|
||||
#include "mozilla/dom/PermissionMessageUtils.h"
|
||||
#include "mozilla/dom/quota/PersistenceType.h"
|
||||
#include "mozilla/dom/quota/QuotaManager.h"
|
||||
@@ -2989,7 +2989,7 @@ nsDOMWindowUtils::GetFileId(JS::Handle<JS::Value> aFile, JSContext* aCx,
|
||||
|
||||
JSObject* obj = aFile.toObjectOrNull();
|
||||
|
||||
indexedDB::IDBMutableFile* mutableFile = nullptr;
|
||||
IDBMutableFile* mutableFile = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(IDBMutableFile, obj, mutableFile))) {
|
||||
*_retval = mutableFile->GetFileId();
|
||||
return NS_OK;
|
||||
@@ -3061,8 +3061,7 @@ nsDOMWindowUtils::GetFileReferences(const nsAString& aDatabaseName, int64_t aId,
|
||||
quota::PersistenceType persistenceType =
|
||||
quota::PersistenceTypeFromStorage(options.mStorage);
|
||||
|
||||
RefPtr<indexedDB::IndexedDatabaseManager> mgr =
|
||||
indexedDB::IndexedDatabaseManager::Get();
|
||||
RefPtr<IndexedDatabaseManager> mgr = IndexedDatabaseManager::Get();
|
||||
|
||||
if (mgr) {
|
||||
rv = mgr->BlockAndGetFileReferences(persistenceType, origin, aDatabaseName,
|
||||
@@ -3083,8 +3082,6 @@ nsDOMWindowUtils::FlushPendingFileDeletions()
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
|
||||
|
||||
using mozilla::dom::indexedDB::IndexedDatabaseManager;
|
||||
|
||||
RefPtr<IndexedDatabaseManager> mgr = IndexedDatabaseManager::Get();
|
||||
if (mgr) {
|
||||
nsresult rv = mgr->FlushPendingFileDeletions();
|
||||
|
||||
@@ -2133,7 +2133,15 @@ nsDocument::Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup)
|
||||
// Note that, since mTiming does not change during a reset, the
|
||||
// navigationStart time remains unchanged and therefore any future new
|
||||
// timeline will have the same global clock time as the old one.
|
||||
mDocumentTimeline = nullptr;
|
||||
if (mDocumentTimeline) {
|
||||
nsRefreshDriver* rd = mPresShell && mPresShell->GetPresContext() ?
|
||||
mPresShell->GetPresContext()->RefreshDriver() :
|
||||
nullptr;
|
||||
if (rd) {
|
||||
mDocumentTimeline->NotifyRefreshDriverDestroying(rd);
|
||||
}
|
||||
mDocumentTimeline = nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPropertyBag2> bag = do_QueryInterface(aChannel);
|
||||
if (bag) {
|
||||
|
||||
@@ -183,8 +183,8 @@
|
||||
#include "prenv.h"
|
||||
#include "prprf.h"
|
||||
|
||||
#include "mozilla/dom/IDBFactory.h"
|
||||
#include "mozilla/dom/MessageChannel.h"
|
||||
#include "mozilla/dom/indexedDB/IDBFactory.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
|
||||
#ifdef MOZ_GAMEPAD
|
||||
@@ -266,7 +266,6 @@ using mozilla::OriginAttributes;
|
||||
using mozilla::TimeStamp;
|
||||
using mozilla::TimeDuration;
|
||||
using mozilla::dom::cache::CacheStorage;
|
||||
using mozilla::dom::indexedDB::IDBFactory;
|
||||
|
||||
static LazyLogModule gDOMLeakPRLog("DOMLeak");
|
||||
|
||||
@@ -6481,6 +6480,7 @@ nsGlobalWindow::Dump(const nsAString& aStr)
|
||||
#endif
|
||||
|
||||
if (cstr) {
|
||||
MOZ_LOG(nsContentUtils::DOMDumpLog(), LogLevel::Debug, ("[Window.Dump] %s", cstr));
|
||||
#ifdef XP_WIN
|
||||
PrintToDebugger(cstr);
|
||||
#endif
|
||||
|
||||
@@ -124,9 +124,7 @@ class WindowOrientationObserver;
|
||||
namespace cache {
|
||||
class CacheStorage;
|
||||
} // namespace cache
|
||||
namespace indexedDB {
|
||||
class IDBFactory;
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
namespace gfx {
|
||||
class VRDeviceProxy;
|
||||
@@ -953,7 +951,7 @@ public:
|
||||
mozilla::dom::DOMStorage* GetLocalStorage(mozilla::ErrorResult& aError);
|
||||
mozilla::dom::Selection* GetSelectionOuter();
|
||||
mozilla::dom::Selection* GetSelection(mozilla::ErrorResult& aError);
|
||||
mozilla::dom::indexedDB::IDBFactory* GetIndexedDB(mozilla::ErrorResult& aError);
|
||||
mozilla::dom::IDBFactory* GetIndexedDB(mozilla::ErrorResult& aError);
|
||||
already_AddRefed<nsICSSDeclaration>
|
||||
GetComputedStyle(mozilla::dom::Element& aElt, const nsAString& aPseudoElt,
|
||||
mozilla::ErrorResult& aError);
|
||||
@@ -1789,7 +1787,7 @@ protected:
|
||||
// unsuspending it.
|
||||
nsCOMPtr<nsIDocument> mSuspendedDoc;
|
||||
|
||||
RefPtr<mozilla::dom::indexedDB::IDBFactory> mIndexedDB;
|
||||
RefPtr<mozilla::dom::IDBFactory> mIndexedDB;
|
||||
|
||||
// This counts the number of windows that have been opened in rapid succession
|
||||
// (i.e. within dom.successive_dialog_time_limit of each other). It is reset
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "nsDOMNavigationTiming.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsILoadInfo.h"
|
||||
#include "nsIURI.h"
|
||||
@@ -30,8 +29,6 @@
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "SharedWorker.h"
|
||||
#include "ServiceWorker.h"
|
||||
#include "js/HeapAPI.h"
|
||||
#include "GeckoProfiler.h"
|
||||
#include "WorkerPrivate.h"
|
||||
@@ -923,37 +920,6 @@ PerformanceBase::ClearResourceTimings()
|
||||
mResourceEntries.Clear();
|
||||
}
|
||||
|
||||
DOMHighResTimeStamp
|
||||
PerformanceBase::TranslateTime(DOMHighResTimeStamp aTime,
|
||||
const WindowOrWorkerOrSharedWorkerOrServiceWorker& aTimeSource,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
TimeStamp otherCreationTimeStamp;
|
||||
|
||||
if (aTimeSource.IsWindow()) {
|
||||
RefPtr<nsPerformance> performance = aTimeSource.GetAsWindow().GetPerformance();
|
||||
if (NS_WARN_IF(!performance)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
}
|
||||
otherCreationTimeStamp = performance->CreationTimeStamp();
|
||||
} else if (aTimeSource.IsWorker()) {
|
||||
otherCreationTimeStamp = aTimeSource.GetAsWorker().CreationTimeStamp();
|
||||
} else if (aTimeSource.IsSharedWorker()) {
|
||||
SharedWorker& sharedWorker = aTimeSource.GetAsSharedWorker();
|
||||
WorkerPrivate* workerPrivate = sharedWorker.GetWorkerPrivate();
|
||||
otherCreationTimeStamp = workerPrivate->CreationTimeStamp();
|
||||
} else if (aTimeSource.IsServiceWorker()) {
|
||||
ServiceWorker& serviceWorker = aTimeSource.GetAsServiceWorker();
|
||||
WorkerPrivate* workerPrivate = serviceWorker.GetWorkerPrivate();
|
||||
otherCreationTimeStamp = workerPrivate->CreationTimeStamp();
|
||||
} else {
|
||||
MOZ_CRASH("This should not be possible.");
|
||||
}
|
||||
|
||||
return RoundTime(
|
||||
aTime + (otherCreationTimeStamp - CreationTimeStamp()).ToMilliseconds());
|
||||
}
|
||||
|
||||
DOMHighResTimeStamp
|
||||
PerformanceBase::RoundTime(double aTime) const
|
||||
{
|
||||
|
||||
@@ -30,7 +30,6 @@ namespace dom {
|
||||
|
||||
class PerformanceEntry;
|
||||
class PerformanceObserver;
|
||||
class WindowOrWorkerOrSharedWorkerOrServiceWorker;
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
@@ -318,11 +317,6 @@ public:
|
||||
|
||||
virtual DOMHighResTimeStamp Now() const = 0;
|
||||
|
||||
DOMHighResTimeStamp
|
||||
TranslateTime(DOMHighResTimeStamp aTime,
|
||||
const mozilla::dom::WindowOrWorkerOrSharedWorkerOrServiceWorker& aTimeSource,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
void Mark(const nsAString& aName, mozilla::ErrorResult& aRv);
|
||||
void ClearMarks(const mozilla::dom::Optional<nsAString>& aName);
|
||||
void Measure(const nsAString& aName,
|
||||
|
||||
@@ -297,7 +297,9 @@ nsScriptLoader::StartLoad(nsScriptLoadRequest *aRequest, const nsAString &aType,
|
||||
aRequest->mCORSMode == CORS_NONE
|
||||
? nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL
|
||||
: nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS;
|
||||
if (aRequest->mCORSMode == CORS_USE_CREDENTIALS) {
|
||||
if (aRequest->mCORSMode == CORS_ANONYMOUS) {
|
||||
securityFlags |= nsILoadInfo::SEC_COOKIES_SAME_ORIGIN;
|
||||
} else if (aRequest->mCORSMode == CORS_USE_CREDENTIALS) {
|
||||
securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE;
|
||||
}
|
||||
securityFlags |= nsILoadInfo::SEC_ALLOW_CHROME;
|
||||
@@ -803,17 +805,8 @@ nsScriptLoader::ProcessOffThreadRequest(nsScriptLoadRequest* aRequest)
|
||||
NotifyOffThreadScriptLoadCompletedRunnable::~NotifyOffThreadScriptLoadCompletedRunnable()
|
||||
{
|
||||
if (MOZ_UNLIKELY(mRequest || mLoader) && !NS_IsMainThread()) {
|
||||
nsCOMPtr<nsIThread> mainThread;
|
||||
NS_GetMainThread(getter_AddRefs(mainThread));
|
||||
if (mainThread) {
|
||||
NS_ProxyRelease(mainThread, mRequest);
|
||||
NS_ProxyRelease(mainThread, mLoader);
|
||||
} else {
|
||||
MOZ_ASSERT(false, "We really shouldn't leak!");
|
||||
// Better to leak than crash.
|
||||
Unused << mRequest.forget();
|
||||
Unused << mLoader.forget();
|
||||
}
|
||||
NS_ReleaseOnMainThread(mRequest.forget());
|
||||
NS_ReleaseOnMainThread(mLoader.forget());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
/* nothing here */
|
||||
|
||||
@@ -256,7 +256,6 @@ support-files =
|
||||
file_explicit_user_agent.sjs
|
||||
referrer_change_server.sjs
|
||||
file_change_policy_redirect.html
|
||||
empty_worker.js
|
||||
file_bug1198095.js
|
||||
|
||||
[test_anonymousContent_api.html]
|
||||
@@ -847,6 +846,5 @@ skip-if = e10s || os != 'linux' || buildapp != 'browser'
|
||||
[test_change_policy.html]
|
||||
skip-if = buildapp == 'b2g' #no ssl support
|
||||
[test_document.all_iteration.html]
|
||||
[test_performance_translate.html]
|
||||
[test_bug1198095.html]
|
||||
[test_bug1187157.html]
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for performance.translate()</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="test_performance_user_timing.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
function testBasic() {
|
||||
ok("translateTime" in performance, "Performance.translateTime exists.");
|
||||
try {
|
||||
performance.translateTime(0, null);
|
||||
ok(false, "Wrong use of performance.translateTime.");
|
||||
} catch(e) {
|
||||
ok(true, "Wrong use of performance.translateTime.");
|
||||
}
|
||||
|
||||
next();
|
||||
}
|
||||
|
||||
function testWindow() {
|
||||
is(performance.translateTime(42, this), 42, "translating time with the same window.");
|
||||
|
||||
var now = performance.now();
|
||||
|
||||
var ifr = document.createElement('iframe');
|
||||
ifr.src = 'file_empty.html';
|
||||
document.body.appendChild(ifr);
|
||||
|
||||
ifr.onload = function() {
|
||||
var a = performance.translateTime(0, ifr.contentWindow);
|
||||
ok (a >= now, "Time has been translated from a window that started loading later than we did");
|
||||
next();
|
||||
}
|
||||
}
|
||||
|
||||
function testWorker() {
|
||||
var now = performance.now();
|
||||
|
||||
var w = new Worker('empty_worker.js');
|
||||
var a = performance.translateTime(0, w);
|
||||
// bug 1226147
|
||||
ok (a >= now, "Time has been translated from a Worker that started loading later than we did");
|
||||
next();
|
||||
}
|
||||
|
||||
function testSharedWorker() {
|
||||
var now = performance.now();
|
||||
|
||||
var w = new SharedWorker('empty_worker.js');
|
||||
var a = performance.translateTime(0, w);
|
||||
ok (a >= now, "Time has been translated from a SharedWorker that started loading later than we did");
|
||||
next();
|
||||
}
|
||||
|
||||
var tests = [ testBasic, testWindow, testWorker, testSharedWorker ];
|
||||
function next() {
|
||||
if (!tests.length) {
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
var test = tests.shift();
|
||||
test();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(next);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -612,7 +612,6 @@ DOMInterfaces = {
|
||||
},
|
||||
|
||||
'IDBCursor': {
|
||||
'nativeType': 'mozilla::dom::indexedDB::IDBCursor',
|
||||
'implicitJSContext': [ 'delete' ],
|
||||
'binaryNames': {
|
||||
'direction': 'getDirection'
|
||||
@@ -620,27 +619,10 @@ DOMInterfaces = {
|
||||
},
|
||||
|
||||
'IDBCursorWithValue': {
|
||||
'nativeType': 'mozilla::dom::indexedDB::IDBCursor',
|
||||
},
|
||||
|
||||
'IDBDatabase': {
|
||||
'nativeType': 'mozilla::dom::indexedDB::IDBDatabase',
|
||||
},
|
||||
|
||||
'IDBFactory': {
|
||||
'nativeType': 'mozilla::dom::indexedDB::IDBFactory',
|
||||
},
|
||||
|
||||
'IDBFileHandle': {
|
||||
'nativeType': 'mozilla::dom::indexedDB::IDBFileHandle',
|
||||
},
|
||||
|
||||
'IDBFileRequest': {
|
||||
'nativeType': 'mozilla::dom::indexedDB::IDBFileRequest',
|
||||
'nativeType': 'mozilla::dom::IDBCursor',
|
||||
},
|
||||
|
||||
'IDBIndex': {
|
||||
'nativeType': 'mozilla::dom::indexedDB::IDBIndex',
|
||||
'binaryNames': {
|
||||
'mozGetAll': 'getAll',
|
||||
'mozGetAllKeys': 'getAllKeys',
|
||||
@@ -648,43 +630,25 @@ DOMInterfaces = {
|
||||
},
|
||||
|
||||
'IDBKeyRange': {
|
||||
'nativeType': 'mozilla::dom::indexedDB::IDBKeyRange',
|
||||
'headerFile': 'mozilla/dom/indexedDB/IDBKeyRange.h',
|
||||
'wrapperCache': False,
|
||||
},
|
||||
|
||||
'IDBLocaleAwareKeyRange': {
|
||||
'nativeType': 'mozilla::dom::indexedDB::IDBLocaleAwareKeyRange',
|
||||
'headerFile': 'mozilla/dom/indexedDB/IDBKeyRange.h',
|
||||
'headerFile': 'IDBKeyRange.h',
|
||||
'wrapperCache': False,
|
||||
},
|
||||
|
||||
'IDBMutableFile': {
|
||||
'nativeType': 'mozilla::dom::indexedDB::IDBMutableFile',
|
||||
},
|
||||
|
||||
'IDBObjectStore': {
|
||||
'nativeType': 'mozilla::dom::indexedDB::IDBObjectStore',
|
||||
'binaryNames': {
|
||||
'mozGetAll': 'getAll'
|
||||
}
|
||||
},
|
||||
|
||||
'IDBOpenDBRequest': {
|
||||
'nativeType': 'mozilla::dom::indexedDB::IDBOpenDBRequest',
|
||||
'headerFile': 'IDBRequest.h'
|
||||
},
|
||||
|
||||
'IDBRequest': {
|
||||
'nativeType': 'mozilla::dom::indexedDB::IDBRequest',
|
||||
},
|
||||
|
||||
'IDBTransaction': {
|
||||
'nativeType': 'mozilla::dom::indexedDB::IDBTransaction',
|
||||
},
|
||||
|
||||
'IDBVersionChangeEvent': {
|
||||
'nativeType': 'mozilla::dom::indexedDB::IDBVersionChangeEvent',
|
||||
'headerFile': 'IDBEvents.h',
|
||||
},
|
||||
|
||||
|
||||
+78
-35
@@ -1138,11 +1138,13 @@ class CGHeaders(CGWrapper):
|
||||
if desc.interface.maplikeOrSetlikeOrIterable:
|
||||
# We need ToJSValue.h for maplike/setlike type conversions
|
||||
bindingHeaders.add("mozilla/dom/ToJSValue.h")
|
||||
# Add headers for the key and value types of the maplike, since
|
||||
# they'll be needed for convenience functions
|
||||
addHeadersForType((desc.interface.maplikeOrSetlikeOrIterable.keyType,
|
||||
desc, None))
|
||||
if desc.interface.maplikeOrSetlikeOrIterable.valueType:
|
||||
# Add headers for the key and value types of the
|
||||
# maplike/setlike/iterable, since they'll be needed for
|
||||
# convenience functions
|
||||
if desc.interface.maplikeOrSetlikeOrIterable.hasKeyType():
|
||||
addHeadersForType((desc.interface.maplikeOrSetlikeOrIterable.keyType,
|
||||
desc, None))
|
||||
if desc.interface.maplikeOrSetlikeOrIterable.hasValueType():
|
||||
addHeadersForType((desc.interface.maplikeOrSetlikeOrIterable.valueType,
|
||||
desc, None))
|
||||
|
||||
@@ -2271,34 +2273,49 @@ class MethodDefiner(PropertyDefiner):
|
||||
"condition": MemberCondition()
|
||||
})
|
||||
|
||||
# Generate the maplike/setlike iterator, if one wasn't already
|
||||
# generated by a method. If we already have an @@iterator symbol, fail.
|
||||
if descriptor.interface.maplikeOrSetlikeOrIterable:
|
||||
if hasIterator(methods, self.regular):
|
||||
raise TypeError("Cannot have maplike/setlike/iterable interface with "
|
||||
"other members that generate @@iterator "
|
||||
"on interface %s, such as indexed getters "
|
||||
"or aliased functions." %
|
||||
self.descriptor.interface.identifier.name)
|
||||
for m in methods:
|
||||
if (m.isMaplikeOrSetlikeOrIterableMethod() and
|
||||
(((m.maplikeOrSetlikeOrIterable.isMaplike() or
|
||||
(m.maplikeOrSetlikeOrIterable.isIterable() and
|
||||
m.maplikeOrSetlikeOrIterable.hasValueType())) and
|
||||
m.identifier.name == "entries") or
|
||||
(((m.maplikeOrSetlikeOrIterable.isSetlike() or
|
||||
(m.maplikeOrSetlikeOrIterable.isIterable() and
|
||||
not m.maplikeOrSetlikeOrIterable.hasValueType()))) and
|
||||
m.identifier.name == "values"))):
|
||||
self.regular.append({
|
||||
"name": "@@iterator",
|
||||
"methodName": m.identifier.name,
|
||||
"length": methodLength(m),
|
||||
"flags": "0",
|
||||
"condition": PropertyDefiner.getControllingCondition(m,
|
||||
descriptor),
|
||||
})
|
||||
break
|
||||
# Generate the keys/values/entries aliases for value iterables.
|
||||
maplikeOrSetlikeOrIterable = descriptor.interface.maplikeOrSetlikeOrIterable
|
||||
if (not static and
|
||||
maplikeOrSetlikeOrIterable and
|
||||
maplikeOrSetlikeOrIterable.isIterable() and
|
||||
maplikeOrSetlikeOrIterable.isValueIterator()):
|
||||
# Add our keys/values/entries/forEach
|
||||
self.regular.append({
|
||||
"name": "keys",
|
||||
"methodInfo": False,
|
||||
"selfHostedName": "ArrayKeys",
|
||||
"length": 0,
|
||||
"flags": "JSPROP_ENUMERATE",
|
||||
"condition": PropertyDefiner.getControllingCondition(m,
|
||||
descriptor)
|
||||
})
|
||||
self.regular.append({
|
||||
"name": "values",
|
||||
"methodInfo": False,
|
||||
"selfHostedName": "ArrayValues",
|
||||
"length": 0,
|
||||
"flags": "JSPROP_ENUMERATE",
|
||||
"condition": PropertyDefiner.getControllingCondition(m,
|
||||
descriptor)
|
||||
})
|
||||
self.regular.append({
|
||||
"name": "entries",
|
||||
"methodInfo": False,
|
||||
"selfHostedName": "ArrayEntries",
|
||||
"length": 0,
|
||||
"flags": "JSPROP_ENUMERATE",
|
||||
"condition": PropertyDefiner.getControllingCondition(m,
|
||||
descriptor)
|
||||
})
|
||||
self.regular.append({
|
||||
"name": "forEach",
|
||||
"methodInfo": False,
|
||||
"selfHostedName": "ArrayForEach",
|
||||
"length": 0,
|
||||
"flags": "JSPROP_ENUMERATE",
|
||||
"condition": PropertyDefiner.getControllingCondition(m,
|
||||
descriptor)
|
||||
})
|
||||
|
||||
if not static:
|
||||
stringifier = descriptor.operations['Stringifier']
|
||||
@@ -13079,8 +13096,9 @@ class CGForwardDeclarations(CGWrapper):
|
||||
# arguments to helper functions, and they'll need to be forward
|
||||
# declared in the header.
|
||||
if d.interface.maplikeOrSetlikeOrIterable:
|
||||
builder.forwardDeclareForType(d.interface.maplikeOrSetlikeOrIterable.keyType,
|
||||
config)
|
||||
if d.interface.maplikeOrSetlikeOrIterable.hasKeyType():
|
||||
builder.forwardDeclareForType(d.interface.maplikeOrSetlikeOrIterable.keyType,
|
||||
config)
|
||||
if d.interface.maplikeOrSetlikeOrIterable.hasValueType():
|
||||
builder.forwardDeclareForType(d.interface.maplikeOrSetlikeOrIterable.valueType,
|
||||
config)
|
||||
@@ -15808,6 +15826,31 @@ class CGIterableMethodGenerator(CGGeneric):
|
||||
using CGCallGenerator.
|
||||
"""
|
||||
def __init__(self, descriptor, iterable, methodName):
|
||||
if methodName == "forEach":
|
||||
CGGeneric.__init__(self, fill(
|
||||
"""
|
||||
if (!JS::IsCallable(arg0)) {
|
||||
ThrowErrorMessage(cx, MSG_NOT_CALLABLE, "Argument 1 of ${ifaceName}.forEach");
|
||||
return false;
|
||||
}
|
||||
JS::AutoValueArray<3> callArgs(cx);
|
||||
callArgs[2].setObject(*obj);
|
||||
JS::Rooted<JS::Value> ignoredReturnVal(cx);
|
||||
for (size_t i = 0; i < self->GetIterableLength(); ++i) {
|
||||
if (!ToJSValue(cx, self->GetValueAtIndex(i), callArgs[0])) {
|
||||
return false;
|
||||
}
|
||||
if (!ToJSValue(cx, self->GetKeyAtIndex(i), callArgs[1])) {
|
||||
return false;
|
||||
}
|
||||
if (!JS::Call(cx, arg1, arg0, JS::HandleValueArray(callArgs),
|
||||
&ignoredReturnVal)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
""",
|
||||
ifaceName=descriptor.interface.identifier.name))
|
||||
return
|
||||
CGGeneric.__init__(self, fill(
|
||||
"""
|
||||
typedef ${iterClass} itrType;
|
||||
|
||||
@@ -900,8 +900,5 @@ def getAllTypes(descriptors, dictionaries, callbacks):
|
||||
def iteratorNativeType(descriptor):
|
||||
assert descriptor.interface.isIterable()
|
||||
iterableDecl = descriptor.interface.maplikeOrSetlikeOrIterable
|
||||
if iterableDecl.valueType is None:
|
||||
iterClass = "OneTypeIterableIterator"
|
||||
else:
|
||||
iterClass = "TwoTypeIterableIterator"
|
||||
return "mozilla::dom::%s<%s>" % (iterClass, descriptor.nativeType)
|
||||
assert iterableDecl.isPairIterator()
|
||||
return "mozilla::dom::IterableIterator<%s>" % descriptor.nativeType
|
||||
|
||||
+71
-164
@@ -6,19 +6,17 @@
|
||||
|
||||
/**
|
||||
* The IterableIterator class is used for WebIDL interfaces that have a
|
||||
* iterable<> member defined. It handles the ES6 Iterator-like functions that
|
||||
* are generated for the iterable interface.
|
||||
* iterable<> member defined with two types (so a pair iterator). It handles
|
||||
* the ES6 Iterator-like functions that are generated for the iterable
|
||||
* interface.
|
||||
*
|
||||
* For iterable interfaces, the implementation class will need to
|
||||
* implement these two functions:
|
||||
* For iterable interfaces with a pair iterator, the implementation class will
|
||||
* need to implement these two functions:
|
||||
*
|
||||
* - size_t GetIterableLength()
|
||||
* - Returns the number of elements available to iterate over
|
||||
* - [type] GetValueAtIndex(size_t index)
|
||||
* - Returns the value at the requested index.
|
||||
*
|
||||
* If this is a two-type iterator, then the implementation class will also need to implement:
|
||||
*
|
||||
* - [type] GetKeyAtIndex(size_t index)
|
||||
* - Returns the key at the requested index
|
||||
*
|
||||
@@ -60,13 +58,77 @@ protected:
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class IterableIterator : public IterableIteratorBase
|
||||
class IterableIterator final : public IterableIteratorBase
|
||||
{
|
||||
public:
|
||||
explicit IterableIterator(T* aIterableObj)
|
||||
typedef bool (*WrapFunc)(JSContext* aCx,
|
||||
IterableIterator<T>* aObject,
|
||||
JS::Handle<JSObject*> aGivenProto,
|
||||
JS::MutableHandle<JSObject*> aReflector);
|
||||
|
||||
explicit IterableIterator(T* aIterableObj,
|
||||
IterableIteratorType aIteratorType,
|
||||
WrapFunc aWrapFunc)
|
||||
: mIterableObj(aIterableObj)
|
||||
, mIteratorType(aIteratorType)
|
||||
, mWrapFunc(aWrapFunc)
|
||||
, mIndex(0)
|
||||
{
|
||||
MOZ_ASSERT(mIterableObj);
|
||||
MOZ_ASSERT(mWrapFunc);
|
||||
}
|
||||
|
||||
void
|
||||
Next(JSContext* aCx, JS::MutableHandle<JSObject*> aResult, ErrorResult& aRv)
|
||||
{
|
||||
JS::Rooted<JS::Value> value(aCx, JS::UndefinedValue());
|
||||
if (mIndex >= this->mIterableObj->GetIterableLength()) {
|
||||
DictReturn(aCx, aResult, true, value, aRv);
|
||||
return;
|
||||
}
|
||||
switch (mIteratorType) {
|
||||
case IterableIteratorType::Keys:
|
||||
{
|
||||
if (!ToJSValue(aCx, this->mIterableObj->GetKeyAtIndex(mIndex), &value)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
DictReturn(aCx, aResult, false, value, aRv);
|
||||
break;
|
||||
}
|
||||
case IterableIteratorType::Values:
|
||||
{
|
||||
if (!ToJSValue(aCx, this->mIterableObj->GetValueAtIndex(mIndex), &value)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
DictReturn(aCx, aResult, false, value, aRv);
|
||||
break;
|
||||
}
|
||||
case IterableIteratorType::Entries:
|
||||
{
|
||||
JS::Rooted<JS::Value> key(aCx);
|
||||
if (!ToJSValue(aCx, this->mIterableObj->GetKeyAtIndex(mIndex), &key)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
if (!ToJSValue(aCx, this->mIterableObj->GetValueAtIndex(mIndex), &value)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
KeyAndValueReturn(aCx, key, value, aResult, aRv);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MOZ_CRASH("Invalid iterator type!");
|
||||
}
|
||||
++mIndex;
|
||||
}
|
||||
|
||||
bool
|
||||
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aObj)
|
||||
{
|
||||
return (*mWrapFunc)(aCx, this, aGivenProto, aObj);
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -128,161 +190,6 @@ protected:
|
||||
|
||||
// Binding Implementation object that we're iterating over.
|
||||
RefPtr<T> mIterableObj;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class OneTypeIterableIterator final : public IterableIterator<T>
|
||||
{
|
||||
public:
|
||||
typedef typename IterableIterator<T>::IterableIteratorType IterableIteratorType;
|
||||
using IterableIterator<T>::DictReturn;
|
||||
using IterableIterator<T>::KeyAndValueReturn;
|
||||
typedef bool (*WrapFunc)(JSContext* aCx,
|
||||
OneTypeIterableIterator<T>* aObject,
|
||||
JS::Handle<JSObject*> aGivenProto,
|
||||
JS::MutableHandle<JSObject*> aReflector);
|
||||
|
||||
OneTypeIterableIterator(T* aIterableObj,
|
||||
IterableIteratorType aIteratorType,
|
||||
WrapFunc aWrapFunc)
|
||||
: IterableIterator<T>(aIterableObj)
|
||||
, mIteratorType(aIteratorType)
|
||||
, mWrapFunc(aWrapFunc)
|
||||
, mIndex(0)
|
||||
{
|
||||
MOZ_ASSERT(mWrapFunc);
|
||||
}
|
||||
|
||||
void
|
||||
Next(JSContext* aCx, JS::MutableHandle<JSObject*> aResult, ErrorResult& aRv)
|
||||
{
|
||||
JS::Rooted<JS::Value> value(aCx, JS::UndefinedValue());
|
||||
if (mIndex >= this->mIterableObj->GetIterableLength()) {
|
||||
DictReturn(aCx, aResult, true, value, aRv);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (mIteratorType) {
|
||||
case IterableIteratorType::Keys:
|
||||
case IterableIteratorType::Values:
|
||||
{
|
||||
if (!ToJSValue(aCx, this->mIterableObj->GetValueAtIndex(mIndex), &value)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
DictReturn(aCx, aResult, false, value, aRv);
|
||||
break;
|
||||
}
|
||||
case IterableIteratorType::Entries:
|
||||
{
|
||||
if (!ToJSValue(aCx, this->mIterableObj->GetValueAtIndex(mIndex), &value)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
KeyAndValueReturn(aCx, value, value, aResult, aRv);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MOZ_CRASH("Invalid iterator type!");
|
||||
}
|
||||
++mIndex;
|
||||
}
|
||||
|
||||
bool
|
||||
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aObj)
|
||||
{
|
||||
return (*mWrapFunc)(aCx, this, aGivenProto, aObj);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~OneTypeIterableIterator() {}
|
||||
|
||||
// Tells whether this is a key, value, or entries iterator.
|
||||
IterableIteratorType mIteratorType;
|
||||
// Function pointer to binding-type-specific Wrap() call for this iterator.
|
||||
WrapFunc mWrapFunc;
|
||||
// Current index of iteration.
|
||||
uint32_t mIndex;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class TwoTypeIterableIterator final : public IterableIterator<T>
|
||||
{
|
||||
public:
|
||||
typedef typename IterableIterator<T>::IterableIteratorType IterableIteratorType;
|
||||
using IterableIterator<T>::DictReturn;
|
||||
using IterableIterator<T>::KeyAndValueReturn;
|
||||
typedef bool (*WrapFunc)(JSContext* aCx,
|
||||
TwoTypeIterableIterator<T>* aObject,
|
||||
JS::Handle<JSObject*> aGivenProto,
|
||||
JS::MutableHandle<JSObject*> aReflector);
|
||||
|
||||
TwoTypeIterableIterator(T* aIterableObj, IterableIteratorType aIteratorType,
|
||||
WrapFunc aWrapFunc)
|
||||
: IterableIterator<T>(aIterableObj)
|
||||
, mIteratorType(aIteratorType)
|
||||
, mWrapFunc(aWrapFunc)
|
||||
, mIndex(0)
|
||||
{
|
||||
MOZ_ASSERT(mWrapFunc);
|
||||
}
|
||||
|
||||
void
|
||||
Next(JSContext* aCx, JS::MutableHandle<JSObject*> aResult, ErrorResult& aRv)
|
||||
{
|
||||
JS::Rooted<JS::Value> value(aCx, JS::UndefinedValue());
|
||||
if (mIndex >= this->mIterableObj->GetIterableLength()) {
|
||||
DictReturn(aCx, aResult, true, value, aRv);
|
||||
return;
|
||||
}
|
||||
switch (mIteratorType) {
|
||||
case IterableIteratorType::Keys:
|
||||
{
|
||||
if (!ToJSValue(aCx, this->mIterableObj->GetKeyAtIndex(mIndex), &value)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
DictReturn(aCx, aResult, false, value, aRv);
|
||||
break;
|
||||
}
|
||||
case IterableIteratorType::Values:
|
||||
{
|
||||
if (!ToJSValue(aCx, this->mIterableObj->GetValueAtIndex(mIndex), &value)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
DictReturn(aCx, aResult, false, value, aRv);
|
||||
break;
|
||||
}
|
||||
case IterableIteratorType::Entries:
|
||||
{
|
||||
JS::Rooted<JS::Value> key(aCx);
|
||||
if (!ToJSValue(aCx, this->mIterableObj->GetKeyAtIndex(mIndex), &key)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
if (!ToJSValue(aCx, this->mIterableObj->GetValueAtIndex(mIndex), &value)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
KeyAndValueReturn(aCx, key, value, aResult, aRv);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MOZ_CRASH("Invalid iterator type!");
|
||||
}
|
||||
++mIndex;
|
||||
}
|
||||
|
||||
bool
|
||||
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aObj)
|
||||
{
|
||||
return (*mWrapFunc)(aCx, this, aGivenProto, aObj);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~TwoTypeIterableIterator() {}
|
||||
|
||||
// Tells whether this is a key, value, or entries iterator.
|
||||
IterableIteratorType mIteratorType;
|
||||
// Function pointer to binding-type-specific Wrap() call for this iterator.
|
||||
|
||||
+100
-25
@@ -1092,7 +1092,7 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
|
||||
|
||||
def validate(self):
|
||||
# We don't support consequential unforgeable interfaces. Need to check
|
||||
# this here, becaue in finish() an interface might not know yet that
|
||||
# this here, because in finish() an interface might not know yet that
|
||||
# it's consequential.
|
||||
if self.getExtendedAttribute("Unforgeable") and self.isConsequential():
|
||||
raise WebIDLError(
|
||||
@@ -1111,6 +1111,8 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
|
||||
self.identifier.name,
|
||||
locations)
|
||||
|
||||
indexedGetter = None
|
||||
hasLengthAttribute = False
|
||||
for member in self.members:
|
||||
member.validate()
|
||||
|
||||
@@ -1121,8 +1123,13 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
|
||||
[self.location, member.location])
|
||||
|
||||
# Check that PutForwards refers to another attribute and that no
|
||||
# cycles exist in forwarded assignments.
|
||||
# cycles exist in forwarded assignments. Also check for a
|
||||
# integer-typed "length" attribute.
|
||||
if member.isAttr():
|
||||
if (member.identifier.name == "length" and
|
||||
member.type.isInteger()):
|
||||
hasLengthAttribute = True
|
||||
|
||||
iface = self
|
||||
attr = member
|
||||
putForwards = attr.getExtendedAttribute("PutForwards")
|
||||
@@ -1160,8 +1167,11 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
|
||||
putForwards = attr.getExtendedAttribute("PutForwards")
|
||||
|
||||
# Check that the name of an [Alias] doesn't conflict with an
|
||||
# interface member.
|
||||
# interface member and whether we support indexed properties.
|
||||
if member.isMethod():
|
||||
if member.isGetter() and member.isIndexed():
|
||||
indexedGetter = member
|
||||
|
||||
for alias in member.aliases:
|
||||
if self.isOnGlobalProtoChain():
|
||||
raise WebIDLError("[Alias] must not be used on a "
|
||||
@@ -1222,6 +1232,35 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
|
||||
"exposed conditionally",
|
||||
[self.location])
|
||||
|
||||
# Value iterators are only allowed on interfaces with indexed getters,
|
||||
# and pair iterators are only allowed on interfaces without indexed
|
||||
# getters.
|
||||
if self.isIterable():
|
||||
iterableDecl = self.maplikeOrSetlikeOrIterable
|
||||
if iterableDecl.isValueIterator():
|
||||
if not indexedGetter:
|
||||
raise WebIDLError("Interface with value iterator does not "
|
||||
"support indexed properties",
|
||||
[self.location])
|
||||
|
||||
if iterableDecl.valueType != indexedGetter.signatures()[0][0]:
|
||||
raise WebIDLError("Iterable type does not match indexed "
|
||||
"getter type",
|
||||
[iterableDecl.location,
|
||||
indexedGetter.location])
|
||||
|
||||
if not hasLengthAttribute:
|
||||
raise WebIDLError('Interface with value iterator does not '
|
||||
'have an integer-typed "length" attribute',
|
||||
[self.location])
|
||||
else:
|
||||
assert iterableDecl.isPairIterator()
|
||||
if indexedGetter:
|
||||
raise WebIDLError("Interface with pair iterator supports "
|
||||
"indexed properties",
|
||||
[self.location, iterableDecl.location,
|
||||
indexedGetter.location])
|
||||
|
||||
def isInterface(self):
|
||||
return True
|
||||
|
||||
@@ -3420,7 +3459,10 @@ class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember):
|
||||
|
||||
def __init__(self, location, identifier, ifaceType, keyType, valueType, ifaceKind):
|
||||
IDLInterfaceMember.__init__(self, location, identifier, ifaceKind)
|
||||
assert isinstance(keyType, IDLType)
|
||||
if keyType is not None:
|
||||
assert isinstance(keyType, IDLType)
|
||||
else:
|
||||
assert valueType is not None
|
||||
assert ifaceType in ['maplike', 'setlike', 'iterable']
|
||||
if valueType is not None:
|
||||
assert isinstance(valueType, IDLType)
|
||||
@@ -3439,6 +3481,9 @@ class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember):
|
||||
def isIterable(self):
|
||||
return self.maplikeOrSetlikeOrIterableType == "iterable"
|
||||
|
||||
def hasKeyType(self):
|
||||
return self.keyType is not None
|
||||
|
||||
def hasValueType(self):
|
||||
return self.valueType is not None
|
||||
|
||||
@@ -3463,7 +3508,8 @@ class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember):
|
||||
[self.location, member.location])
|
||||
|
||||
def addMethod(self, name, members, allowExistingOperations, returnType, args=[],
|
||||
chromeOnly=False, isPure=False, affectsNothing=False, newObject=False):
|
||||
chromeOnly=False, isPure=False, affectsNothing=False, newObject=False,
|
||||
isIteratorAlias=False):
|
||||
"""
|
||||
Create an IDLMethod based on the parameters passed in.
|
||||
|
||||
@@ -3523,16 +3569,20 @@ class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember):
|
||||
if newObject:
|
||||
method.addExtendedAttributes(
|
||||
[IDLExtendedAttribute(self.location, ("NewObject",))])
|
||||
if isIteratorAlias:
|
||||
method.addExtendedAttributes(
|
||||
[IDLExtendedAttribute(self.location, ("Alias", "@@iterator"))])
|
||||
members.append(method)
|
||||
|
||||
def resolve(self, parentScope):
|
||||
self.keyType.resolveType(parentScope)
|
||||
if self.keyType:
|
||||
self.keyType.resolveType(parentScope)
|
||||
if self.valueType:
|
||||
self.valueType.resolveType(parentScope)
|
||||
|
||||
def finish(self, scope):
|
||||
IDLInterfaceMember.finish(self, scope)
|
||||
if not self.keyType.isComplete():
|
||||
if self.keyType and not self.keyType.isComplete():
|
||||
t = self.keyType.complete(scope)
|
||||
|
||||
assert not isinstance(t, IDLUnresolvedType)
|
||||
@@ -3554,9 +3604,23 @@ class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember):
|
||||
IDLInterfaceMember.handleExtendedAttribute(self, attr)
|
||||
|
||||
def _getDependentObjects(self):
|
||||
deps = set()
|
||||
if self.keyType:
|
||||
deps.add(self.keyType)
|
||||
if self.valueType:
|
||||
return set([self.keyType, self.valueType])
|
||||
return set([self.keyType])
|
||||
deps.add(self.valueType)
|
||||
return deps
|
||||
|
||||
def getForEachArguments(self):
|
||||
return [IDLArgument(self.location,
|
||||
IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"),
|
||||
"callback"),
|
||||
BuiltinTypes[IDLBuiltinType.Types.object]),
|
||||
IDLArgument(self.location,
|
||||
IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"),
|
||||
"thisArg"),
|
||||
BuiltinTypes[IDLBuiltinType.Types.any],
|
||||
optional=True)]
|
||||
|
||||
# Iterable adds ES6 iterator style functions and traits
|
||||
# (keys/values/entries/@@iterator) to an interface.
|
||||
@@ -3577,9 +3641,15 @@ class IDLIterable(IDLMaplikeOrSetlikeOrIterableBase):
|
||||
we generate our functions as if they were part of the interface
|
||||
specification during parsing.
|
||||
"""
|
||||
# We only need to add entries/keys/values here if we're a pair iterator.
|
||||
# Value iterators just copy these from %ArrayPrototype% instead.
|
||||
if not self.isPairIterator():
|
||||
return
|
||||
|
||||
# object entries()
|
||||
self.addMethod("entries", members, False, self.iteratorType,
|
||||
affectsNothing=True, newObject=True)
|
||||
affectsNothing=True, newObject=True,
|
||||
isIteratorAlias=True)
|
||||
# object keys()
|
||||
self.addMethod("keys", members, False, self.iteratorType,
|
||||
affectsNothing=True, newObject=True)
|
||||
@@ -3587,6 +3657,17 @@ class IDLIterable(IDLMaplikeOrSetlikeOrIterableBase):
|
||||
self.addMethod("values", members, False, self.iteratorType,
|
||||
affectsNothing=True, newObject=True)
|
||||
|
||||
# void forEach(callback(valueType, keyType), optional any thisArg)
|
||||
self.addMethod("forEach", members, False,
|
||||
BuiltinTypes[IDLBuiltinType.Types.void],
|
||||
self.getForEachArguments())
|
||||
|
||||
def isValueIterator(self):
|
||||
return not self.isPairIterator()
|
||||
|
||||
def isPairIterator(self):
|
||||
return self.hasKeyType()
|
||||
|
||||
# MaplikeOrSetlike adds ES6 map-or-set-like traits to an interface.
|
||||
class IDLMaplikeOrSetlike(IDLMaplikeOrSetlikeOrIterableBase):
|
||||
|
||||
@@ -3623,26 +3704,17 @@ class IDLMaplikeOrSetlike(IDLMaplikeOrSetlikeOrIterableBase):
|
||||
|
||||
# object entries()
|
||||
self.addMethod("entries", members, False, BuiltinTypes[IDLBuiltinType.Types.object],
|
||||
affectsNothing=True)
|
||||
affectsNothing=True, isIteratorAlias=self.isMaplike())
|
||||
# object keys()
|
||||
self.addMethod("keys", members, False, BuiltinTypes[IDLBuiltinType.Types.object],
|
||||
affectsNothing=True)
|
||||
# object values()
|
||||
self.addMethod("values", members, False, BuiltinTypes[IDLBuiltinType.Types.object],
|
||||
affectsNothing=True)
|
||||
affectsNothing=True, isIteratorAlias=self.isSetlike())
|
||||
|
||||
# void forEach(callback(valueType, keyType), thisVal)
|
||||
foreachArguments = [IDLArgument(self.location,
|
||||
IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"),
|
||||
"callback"),
|
||||
BuiltinTypes[IDLBuiltinType.Types.object]),
|
||||
IDLArgument(self.location,
|
||||
IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"),
|
||||
"thisArg"),
|
||||
BuiltinTypes[IDLBuiltinType.Types.any],
|
||||
optional=True)]
|
||||
self.addMethod("forEach", members, False, BuiltinTypes[IDLBuiltinType.Types.void],
|
||||
foreachArguments)
|
||||
self.getForEachArguments())
|
||||
|
||||
def getKeyArg():
|
||||
return IDLArgument(self.location,
|
||||
@@ -5448,10 +5520,13 @@ class Parser(Tokenizer):
|
||||
location = self.getLocation(p, 2)
|
||||
identifier = IDLUnresolvedIdentifier(location, "__iterable",
|
||||
allowDoubleUnderscore=True)
|
||||
keyType = p[3]
|
||||
valueType = None
|
||||
if (len(p) > 6):
|
||||
keyType = p[3]
|
||||
valueType = p[5]
|
||||
else:
|
||||
keyType = None
|
||||
valueType = p[3]
|
||||
|
||||
p[0] = IDLIterable(location, identifier, keyType, valueType, self.globalScope())
|
||||
|
||||
def p_Setlike(self, p):
|
||||
@@ -6521,7 +6596,7 @@ class Parser(Tokenizer):
|
||||
if isinstance(m, IDLIterable):
|
||||
iterable = m
|
||||
break
|
||||
if iterable:
|
||||
if iterable and iterable.isPairIterator():
|
||||
def simpleExtendedAttr(str):
|
||||
return IDLExtendedAttribute(iface.location, (str, ))
|
||||
nextMethod = IDLMethod(
|
||||
|
||||
@@ -45,8 +45,8 @@ def WebIDLTest(parser, harness):
|
||||
prefix + " - Interface failed but not as a WebIDLError exception: %s" % e)
|
||||
|
||||
iterableMembers = [(x, WebIDL.IDLMethod) for x in ["entries", "keys",
|
||||
"values"]]
|
||||
setROMembers = ([(x, WebIDL.IDLMethod) for x in ["has", "forEach"]] +
|
||||
"values", "forEach"]]
|
||||
setROMembers = ([(x, WebIDL.IDLMethod) for x in ["has"]] +
|
||||
[("__setlike", WebIDL.IDLMaplikeOrSetlike)] +
|
||||
iterableMembers)
|
||||
setROMembers.extend([("size", WebIDL.IDLAttribute)])
|
||||
@@ -62,7 +62,7 @@ def WebIDLTest(parser, harness):
|
||||
"__clear",
|
||||
"__delete"]] +
|
||||
setRWMembers)
|
||||
mapROMembers = ([(x, WebIDL.IDLMethod) for x in ["get", "has", "forEach"]] +
|
||||
mapROMembers = ([(x, WebIDL.IDLMethod) for x in ["get", "has"]] +
|
||||
[("__maplike", WebIDL.IDLMaplikeOrSetlike)] +
|
||||
iterableMembers)
|
||||
mapROMembers.extend([("size", WebIDL.IDLAttribute)])
|
||||
@@ -78,6 +78,10 @@ def WebIDLTest(parser, harness):
|
||||
# __iterable to it for the iterable<> case.
|
||||
iterableMembers.append(("__iterable", WebIDL.IDLIterable))
|
||||
|
||||
valueIterableMembers = [("__iterable", WebIDL.IDLIterable)]
|
||||
valueIterableMembers.append(("__indexedgetter", WebIDL.IDLMethod))
|
||||
valueIterableMembers.append(("length", WebIDL.IDLAttribute))
|
||||
|
||||
disallowedIterableNames = ["keys", "entries", "values"]
|
||||
disallowedMemberNames = ["forEach", "has", "size"] + disallowedIterableNames
|
||||
mapDisallowedMemberNames = ["get"] + disallowedMemberNames
|
||||
@@ -93,10 +97,10 @@ def WebIDLTest(parser, harness):
|
||||
"""
|
||||
interface Foo1 {
|
||||
iterable<long>;
|
||||
readonly attribute unsigned long length;
|
||||
getter long(unsigned long index);
|
||||
};
|
||||
""", iterableMembers,
|
||||
# numProductions == 2 because of the generated iterator iface,
|
||||
numProductions=2)
|
||||
""", valueIterableMembers)
|
||||
|
||||
shouldPass("Iterable (key and value)",
|
||||
"""
|
||||
|
||||
@@ -23,7 +23,7 @@ NS_INTERFACE_MAP_END
|
||||
TestInterfaceIterableSingle::TestInterfaceIterableSingle(nsPIDOMWindow* aParent)
|
||||
: mParent(aParent)
|
||||
{
|
||||
for(int i = 0; i < 3; ++i) {
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
mValues.AppendElement(i);
|
||||
}
|
||||
}
|
||||
@@ -55,17 +55,22 @@ TestInterfaceIterableSingle::GetParentObject() const
|
||||
return mParent;
|
||||
}
|
||||
|
||||
size_t
|
||||
TestInterfaceIterableSingle::GetIterableLength() const
|
||||
uint32_t
|
||||
TestInterfaceIterableSingle::Length() const
|
||||
{
|
||||
return mValues.Length();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
TestInterfaceIterableSingle::GetValueAtIndex(uint32_t index) const
|
||||
int32_t
|
||||
TestInterfaceIterableSingle::IndexedGetter(uint32_t aIndex, bool& aFound) const
|
||||
{
|
||||
MOZ_ASSERT(index < mValues.Length());
|
||||
return mValues.ElementAt(index);
|
||||
if (aIndex >= mValues.Length()) {
|
||||
aFound = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
aFound = true;
|
||||
return mValues[aIndex];
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
|
||||
@@ -36,12 +36,12 @@ public:
|
||||
static already_AddRefed<TestInterfaceIterableSingle>
|
||||
Constructor(const GlobalObject& aGlobal, ErrorResult& rv);
|
||||
|
||||
size_t GetIterableLength() const;
|
||||
uint32_t GetValueAtIndex(uint32_t aIndex) const;
|
||||
uint32_t Length() const;
|
||||
int32_t IndexedGetter(uint32_t aIndex, bool& aFound) const;
|
||||
private:
|
||||
virtual ~TestInterfaceIterableSingle() {}
|
||||
nsCOMPtr<nsPIDOMWindow> mParent;
|
||||
nsTArray<uint32_t> mValues;
|
||||
nsTArray<int32_t> mValues;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
||||
@@ -93,7 +93,8 @@
|
||||
is(e[1], 1, "SimpleMap: iterable second array element should be value");
|
||||
}
|
||||
is(m[Symbol.iterator].length, 0, "SimpleMap: @@iterator symbol is correct length");
|
||||
is(m[Symbol.iterator].name, "[Symbol.iterator]", "SimpleMap: @@iterator symbol has correct name");
|
||||
is(m[Symbol.iterator].name, "entries", "SimpleMap: @@iterator symbol has correct name");
|
||||
is(m[Symbol.iterator], m.entries, 'SimpleMap: @@iterator is an alias for "entries"');
|
||||
ok(iterable, "SimpleMap: @@iterator symbol resolved correctly");
|
||||
for (var k of m.keys()) {
|
||||
is(k, "test", "SimpleMap: first keys element should be 'test'");
|
||||
@@ -139,7 +140,8 @@
|
||||
is(e, "test", "SimpleSet: iterable first array element should be key");
|
||||
}
|
||||
is(m[Symbol.iterator].length, 0, "SimpleSet: @@iterator symbol is correct length");
|
||||
is(m[Symbol.iterator].name, "[Symbol.iterator]", "SimpleSet: @@iterator symbol has correct name");
|
||||
is(m[Symbol.iterator].name, "values", "SimpleSet: @@iterator symbol has correct name");
|
||||
is(m[Symbol.iterator], m.values, 'SimpleSet: @@iterator is an alias for "values"');
|
||||
ok(iterable, "SimpleSet: @@iterator symbol resolved correctly");
|
||||
for (var k of m.keys()) {
|
||||
is(k, "test", "SimpleSet: first keys element should be 'test'");
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
|
||||
base_properties = [["entries", "function", 0],
|
||||
["keys", "function", 0],
|
||||
["values", "function", 0]]
|
||||
["values", "function", 0],
|
||||
["forEach", "function", 1]]
|
||||
var testExistence = function testExistence(prefix, obj, properties) {
|
||||
for (var [name, type, args] of properties) {
|
||||
// Properties are somewhere up the proto chain, hasOwnProperty won't work
|
||||
@@ -50,6 +51,16 @@
|
||||
info("IterableSingle: Testing simple iterable creation and functionality");
|
||||
itr = new TestInterfaceIterableSingle();
|
||||
testExistence("IterableSingle: ", itr, base_properties);
|
||||
is(itr[Symbol.iterator], Array.prototype[Symbol.iterator],
|
||||
"IterableSingle: Should be using %ArrayIterator% for @@iterator");
|
||||
is(itr.keys, Array.prototype.keys,
|
||||
"IterableSingle: Should be using %ArrayIterator% for 'keys'");
|
||||
is(itr.entries, Array.prototype.entries,
|
||||
"IterableSingle: Should be using %ArrayIterator% for 'entries'");
|
||||
is(itr.values, itr[Symbol.iterator],
|
||||
"IterableSingle: Should be using @@iterator for 'values'");
|
||||
is(itr.forEach, Array.prototype.forEach,
|
||||
"IterableSingle: Should be using %ArrayIterator% for 'forEach'");
|
||||
var keys = [...itr.keys()];
|
||||
var values = [...itr.values()];
|
||||
var entries = [...itr.entries()];
|
||||
@@ -73,6 +84,23 @@
|
||||
is(entry.value[1], entries[i][1],
|
||||
"IterableSingle: Entry iterator value 1 should match destructuring " + i);
|
||||
}
|
||||
|
||||
var callsToForEachCallback = 0;
|
||||
var thisArg = {};
|
||||
itr.forEach(function(value, index, obj) {
|
||||
is(index, callsToForEachCallback,
|
||||
`IterableSingle: Should have the right index at ${callsToForEachCallback} calls to forEach callback`);
|
||||
is(value, values[index],
|
||||
`IterableSingle: Should have the right value at ${callsToForEachCallback} calls to forEach callback`);
|
||||
is(this, thisArg,
|
||||
"IterableSingle: Should have the right this value for forEach callback");
|
||||
is(obj, itr,
|
||||
"IterableSingle: Should have the right third arg for forEach callback");
|
||||
++callsToForEachCallback;
|
||||
}, thisArg);
|
||||
is(callsToForEachCallback, 3,
|
||||
"IterableSingle: Should have right total number of calls to forEach callback");
|
||||
|
||||
var key = key_itr.next();
|
||||
var value = value_itr.next();
|
||||
var entry = entries_itr.next();
|
||||
@@ -83,13 +111,15 @@
|
||||
is(entry.value, undefined, "IterableDouble: Entry iterator value should be undefined");
|
||||
is(entry.done, true, "IterableSingle: Entry iterator done should be true");
|
||||
is(Object.prototype.toString.call(Object.getPrototypeOf(key_itr)),
|
||||
"[object TestInterfaceIterableSingleIteratorPrototype]",
|
||||
"[object Array Iterator]",
|
||||
"iterator prototype should have the right brand");
|
||||
|
||||
// Simple dual type iterable creation and functionality test
|
||||
info("IterableDouble: Testing simple iterable creation and functionality");
|
||||
itr = new TestInterfaceIterableDouble();
|
||||
testExistence("IterableDouble: ", itr, base_properties);
|
||||
is(itr.entries, itr[Symbol.iterator],
|
||||
"IterableDouble: Should be using @@iterator for 'entries'");
|
||||
var elements = [["a", "b"], ["c", "d"], ["e", "f"]]
|
||||
var keys = [...itr.keys()];
|
||||
var values = [...itr.values()];
|
||||
@@ -114,6 +144,23 @@
|
||||
is(entry.value[1], entries[i][1],
|
||||
"IterableDouble: Entry iterator value 1 should match destructuring " + i);
|
||||
}
|
||||
|
||||
callsToForEachCallback = 0;
|
||||
thisArg = {};
|
||||
itr.forEach(function(value, key, obj) {
|
||||
is(key, keys[callsToForEachCallback],
|
||||
`IterableDouble: Should have the right key at ${callsToForEachCallback} calls to forEach callback`);
|
||||
is(value, values[callsToForEachCallback],
|
||||
`IterableDouble: Should have the right value at ${callsToForEachCallback} calls to forEach callback`);
|
||||
is(this, thisArg,
|
||||
"IterableDouble: Should have the right this value for forEach callback");
|
||||
is(obj, itr,
|
||||
"IterableSingle: Should have the right third arg for forEach callback");
|
||||
++callsToForEachCallback;
|
||||
}, thisArg);
|
||||
is(callsToForEachCallback, 3,
|
||||
"IterableDouble: Should have right total number of calls to forEach callback");
|
||||
|
||||
var key = key_itr.next();
|
||||
var value = value_itr.next();
|
||||
var entry = entries_itr.next()
|
||||
|
||||
Vendored
+1
-4
@@ -73,10 +73,7 @@ ManagerId::~ManagerId()
|
||||
|
||||
// The PBackground worker thread shouldn't be running after the main thread
|
||||
// is stopped. So main thread is guaranteed to exist here.
|
||||
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
|
||||
MOZ_ASSERT(mainThread);
|
||||
|
||||
NS_ProxyRelease(mainThread, mPrincipal.forget().take());
|
||||
NS_ReleaseOnMainThread(mPrincipal.forget());
|
||||
}
|
||||
|
||||
} // namespace cache
|
||||
|
||||
@@ -9,15 +9,15 @@
|
||||
#include "DataStoreCallbacks.h"
|
||||
#include "jsapi.h"
|
||||
#include "mozilla/dom/IDBDatabaseBinding.h"
|
||||
#include "mozilla/dom/IDBDatabase.h"
|
||||
#include "mozilla/dom/IDBEvents.h"
|
||||
#include "mozilla/dom/IDBFactory.h"
|
||||
#include "mozilla/dom/IDBFactoryBinding.h"
|
||||
#include "mozilla/dom/IDBIndex.h"
|
||||
#include "mozilla/dom/IDBObjectStore.h"
|
||||
#include "mozilla/dom/IDBObjectStoreBinding.h"
|
||||
#include "mozilla/dom/indexedDB/IDBDatabase.h"
|
||||
#include "mozilla/dom/indexedDB/IDBEvents.h"
|
||||
#include "mozilla/dom/indexedDB/IDBFactory.h"
|
||||
#include "mozilla/dom/indexedDB/IDBIndex.h"
|
||||
#include "mozilla/dom/indexedDB/IDBObjectStore.h"
|
||||
#include "mozilla/dom/indexedDB/IDBRequest.h"
|
||||
#include "mozilla/dom/indexedDB/IDBTransaction.h"
|
||||
#include "mozilla/dom/IDBRequest.h"
|
||||
#include "mozilla/dom/IDBTransaction.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIDOMEvent.h"
|
||||
@@ -354,7 +354,7 @@ DataStoreDB::Delete()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
indexedDB::IDBTransaction*
|
||||
IDBTransaction*
|
||||
DataStoreDB::Transaction() const
|
||||
{
|
||||
MOZ_ASSERT(mTransaction);
|
||||
|
||||
@@ -18,14 +18,11 @@
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
namespace indexedDB {
|
||||
class DataStoreDBCallback;
|
||||
class IDBDatabase;
|
||||
class IDBFactory;
|
||||
class IDBOpenDBRequest;
|
||||
class IDBTransaction;
|
||||
} // namespace indexedDB
|
||||
|
||||
class DataStoreDBCallback;
|
||||
|
||||
class DataStoreDB final : public nsIDOMEventListener
|
||||
{
|
||||
@@ -39,7 +36,7 @@ public:
|
||||
|
||||
nsresult Delete();
|
||||
|
||||
indexedDB::IDBTransaction* Transaction() const;
|
||||
IDBTransaction* Transaction() const;
|
||||
|
||||
// nsIDOMEventListener
|
||||
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) override;
|
||||
@@ -59,10 +56,10 @@ private:
|
||||
|
||||
nsString mDatabaseName;
|
||||
|
||||
RefPtr<indexedDB::IDBFactory> mFactory;
|
||||
RefPtr<indexedDB::IDBOpenDBRequest> mRequest;
|
||||
RefPtr<indexedDB::IDBDatabase> mDatabase;
|
||||
RefPtr<indexedDB::IDBTransaction> mTransaction;
|
||||
RefPtr<IDBFactory> mFactory;
|
||||
RefPtr<IDBOpenDBRequest> mRequest;
|
||||
RefPtr<IDBDatabase> mDatabase;
|
||||
RefPtr<IDBTransaction> mTransaction;
|
||||
|
||||
RefPtr<DataStoreDBCallback> mCallback;
|
||||
|
||||
|
||||
@@ -9,16 +9,14 @@
|
||||
#include "DataStoreCallbacks.h"
|
||||
#include "DataStoreService.h"
|
||||
#include "mozilla/dom/DataStoreBinding.h"
|
||||
#include "mozilla/dom/IDBObjectStore.h"
|
||||
#include "mozilla/dom/IDBRequest.h"
|
||||
#include "mozilla/dom/ToJSValue.h"
|
||||
#include "mozilla/dom/indexedDB/IDBObjectStore.h"
|
||||
#include "mozilla/dom/indexedDB/IDBRequest.h"
|
||||
#include "nsIDOMEvent.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
using namespace indexedDB;
|
||||
|
||||
NS_IMPL_ISUPPORTS(DataStoreRevision, nsIDOMEventListener)
|
||||
|
||||
// Note: this code in it must not assume anything about the compartment cx is
|
||||
|
||||
@@ -15,12 +15,9 @@
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
namespace indexedDB {
|
||||
class DataStoreRevisionCallback;
|
||||
class IDBObjectStore;
|
||||
class IDBRequest;
|
||||
} // namespace indexedDB
|
||||
|
||||
class DataStoreRevisionCallback;
|
||||
|
||||
class DataStoreRevision final : public nsIDOMEventListener
|
||||
{
|
||||
@@ -32,7 +29,7 @@ public:
|
||||
};
|
||||
|
||||
nsresult AddRevision(JSContext* aCx,
|
||||
indexedDB::IDBObjectStore* aStore,
|
||||
IDBObjectStore* aStore,
|
||||
uint32_t aObjectId,
|
||||
RevisionType aRevisionType,
|
||||
DataStoreRevisionCallback* aCallback);
|
||||
@@ -43,7 +40,7 @@ public:
|
||||
private:
|
||||
~DataStoreRevision() {}
|
||||
RefPtr<DataStoreRevisionCallback> mCallback;
|
||||
RefPtr<indexedDB::IDBRequest> mRequest;
|
||||
RefPtr<IDBRequest> mRequest;
|
||||
nsString mRevisionID;
|
||||
};
|
||||
|
||||
|
||||
@@ -21,10 +21,10 @@
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/dom/DOMError.h"
|
||||
#include "mozilla/dom/indexedDB/IDBCursor.h"
|
||||
#include "mozilla/dom/indexedDB/IDBObjectStore.h"
|
||||
#include "mozilla/dom/indexedDB/IDBRequest.h"
|
||||
#include "mozilla/dom/indexedDB/IDBTransaction.h"
|
||||
#include "mozilla/dom/IDBCursor.h"
|
||||
#include "mozilla/dom/IDBObjectStore.h"
|
||||
#include "mozilla/dom/IDBRequest.h"
|
||||
#include "mozilla/dom/IDBTransaction.h"
|
||||
#include "mozilla/dom/PermissionMessageUtils.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/unused.h"
|
||||
@@ -63,8 +63,6 @@ using mozilla::OriginAttributes;
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
using namespace indexedDB;
|
||||
|
||||
// This class contains all the information about a DataStore.
|
||||
class DataStoreInfo
|
||||
{
|
||||
|
||||
@@ -87,6 +87,13 @@ public:
|
||||
uint32_t aFileType,
|
||||
uint32_t aFileAttributes);
|
||||
|
||||
static already_AddRefed<DeviceStorageFile>
|
||||
CreateUnique(const nsAString& aStorageType,
|
||||
const nsAString& aStorageName,
|
||||
nsAString& aFileName,
|
||||
uint32_t aFileType,
|
||||
uint32_t aFileAttributes);
|
||||
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
||||
bool IsAvailable();
|
||||
@@ -300,11 +307,10 @@ public:
|
||||
already_AddRefed<DOMRequest> CreateAndRejectDOMRequest(const char *aReason,
|
||||
ErrorResult& aRv);
|
||||
|
||||
nsresult CheckPermission(DeviceStorageRequest* aRequest);
|
||||
void StorePermission(DeviceStorageRequest* aRequest, bool aAllow);
|
||||
nsresult CheckPermission(already_AddRefed<DeviceStorageRequest>&& aRequest);
|
||||
|
||||
bool IsOwningThread();
|
||||
nsresult DispatchToOwningThread(nsIRunnable* aRunnable);
|
||||
nsresult DispatchToOwningThread(already_AddRefed<nsIRunnable>&& aRunnable);
|
||||
|
||||
private:
|
||||
~nsDOMDeviceStorage();
|
||||
|
||||
@@ -36,6 +36,7 @@ DeviceStorageRequestParent::DeviceStorageRequestParent(
|
||||
void
|
||||
DeviceStorageRequestParent::Dispatch()
|
||||
{
|
||||
RefPtr<CancelableRunnable> r;
|
||||
switch (mParams.type()) {
|
||||
case DeviceStorageParams::TDeviceStorageAddParams:
|
||||
{
|
||||
@@ -52,13 +53,8 @@ DeviceStorageRequestParent::Dispatch()
|
||||
blobImpl->GetInternalStream(getter_AddRefs(stream), rv);
|
||||
MOZ_ASSERT(!rv.Failed());
|
||||
|
||||
RefPtr<CancelableRunnable> r = new WriteFileEvent(this, dsf, stream,
|
||||
DEVICE_STORAGE_REQUEST_CREATE);
|
||||
|
||||
nsCOMPtr<nsIEventTarget> target
|
||||
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
||||
MOZ_ASSERT(target);
|
||||
target->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
r = new WriteFileEvent(this, dsf.forget(), stream,
|
||||
DEVICE_STORAGE_REQUEST_CREATE);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -77,13 +73,8 @@ DeviceStorageRequestParent::Dispatch()
|
||||
blobImpl->GetInternalStream(getter_AddRefs(stream), rv);
|
||||
MOZ_ASSERT(!rv.Failed());
|
||||
|
||||
RefPtr<CancelableRunnable> r = new WriteFileEvent(this, dsf, stream,
|
||||
DEVICE_STORAGE_REQUEST_APPEND);
|
||||
|
||||
nsCOMPtr<nsIEventTarget> target
|
||||
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
||||
MOZ_ASSERT(target);
|
||||
target->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
r = new WriteFileEvent(this, dsf.forget(), stream,
|
||||
DEVICE_STORAGE_REQUEST_APPEND);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -94,12 +85,7 @@ DeviceStorageRequestParent::Dispatch()
|
||||
RefPtr<DeviceStorageFile> dsf =
|
||||
new DeviceStorageFile(p.type(), p.storageName(), p.relpath());
|
||||
|
||||
RefPtr<CancelableRunnable> r = new CreateFdEvent(this, dsf);
|
||||
|
||||
nsCOMPtr<nsIEventTarget> target
|
||||
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
||||
MOZ_ASSERT(target);
|
||||
target->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
r = new CreateFdEvent(this, dsf.forget());
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -109,12 +95,7 @@ DeviceStorageRequestParent::Dispatch()
|
||||
RefPtr<DeviceStorageFile> dsf =
|
||||
new DeviceStorageFile(p.type(), p.storageName(),
|
||||
p.rootDir(), p.relpath());
|
||||
RefPtr<CancelableRunnable> r = new ReadFileEvent(this, dsf);
|
||||
|
||||
nsCOMPtr<nsIEventTarget> target
|
||||
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
||||
MOZ_ASSERT(target);
|
||||
target->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
r = new ReadFileEvent(this, dsf.forget());
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -124,12 +105,7 @@ DeviceStorageRequestParent::Dispatch()
|
||||
|
||||
RefPtr<DeviceStorageFile> dsf =
|
||||
new DeviceStorageFile(p.type(), p.storageName(), p.relpath());
|
||||
RefPtr<CancelableRunnable> r = new DeleteFileEvent(this, dsf);
|
||||
|
||||
nsCOMPtr<nsIEventTarget> target
|
||||
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
||||
MOZ_ASSERT(target);
|
||||
target->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
r = new DeleteFileEvent(this, dsf.forget());
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -139,12 +115,7 @@ DeviceStorageRequestParent::Dispatch()
|
||||
|
||||
RefPtr<DeviceStorageFile> dsf =
|
||||
new DeviceStorageFile(p.type(), p.storageName());
|
||||
RefPtr<FreeSpaceFileEvent> r = new FreeSpaceFileEvent(this, dsf);
|
||||
|
||||
nsCOMPtr<nsIEventTarget> target
|
||||
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
||||
MOZ_ASSERT(target);
|
||||
target->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
r = new FreeSpaceFileEvent(this, dsf.forget());
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -158,10 +129,9 @@ DeviceStorageRequestParent::Dispatch()
|
||||
|
||||
RefPtr<DeviceStorageFile> dsf =
|
||||
new DeviceStorageFile(p.type(), p.storageName());
|
||||
RefPtr<UsedSpaceFileEvent> r = new UsedSpaceFileEvent(this, dsf);
|
||||
|
||||
usedSpaceCache->Dispatch(r);
|
||||
break;
|
||||
usedSpaceCache->Dispatch(
|
||||
MakeAndAddRef<UsedSpaceFileEvent>(this, dsf.forget()));
|
||||
return;
|
||||
}
|
||||
|
||||
case DeviceStorageParams::TDeviceStorageFormatParams:
|
||||
@@ -170,11 +140,10 @@ DeviceStorageRequestParent::Dispatch()
|
||||
|
||||
RefPtr<DeviceStorageFile> dsf =
|
||||
new DeviceStorageFile(p.type(), p.storageName());
|
||||
RefPtr<PostFormatResultEvent> r
|
||||
= new PostFormatResultEvent(this, dsf);
|
||||
DebugOnly<nsresult> rv = NS_DispatchToMainThread(r);
|
||||
DebugOnly<nsresult> rv = NS_DispatchToMainThread(
|
||||
new PostFormatResultEvent(this, dsf.forget()));
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
case DeviceStorageParams::TDeviceStorageMountParams:
|
||||
@@ -183,11 +152,10 @@ DeviceStorageRequestParent::Dispatch()
|
||||
|
||||
RefPtr<DeviceStorageFile> dsf =
|
||||
new DeviceStorageFile(p.type(), p.storageName());
|
||||
RefPtr<PostMountResultEvent> r
|
||||
= new PostMountResultEvent(this, dsf);
|
||||
DebugOnly<nsresult> rv = NS_DispatchToMainThread(r);
|
||||
DebugOnly<nsresult> rv = NS_DispatchToMainThread(
|
||||
new PostMountResultEvent(this, dsf.forget()));
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
case DeviceStorageParams::TDeviceStorageUnmountParams:
|
||||
@@ -196,11 +164,10 @@ DeviceStorageRequestParent::Dispatch()
|
||||
|
||||
RefPtr<DeviceStorageFile> dsf =
|
||||
new DeviceStorageFile(p.type(), p.storageName());
|
||||
RefPtr<PostUnmountResultEvent> r
|
||||
= new PostUnmountResultEvent(this, dsf);
|
||||
DebugOnly<nsresult> rv = NS_DispatchToMainThread(r);
|
||||
DebugOnly<nsresult> rv = NS_DispatchToMainThread(
|
||||
new PostUnmountResultEvent(this, dsf.forget()));
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
case DeviceStorageParams::TDeviceStorageEnumerationParams:
|
||||
@@ -209,21 +176,22 @@ DeviceStorageRequestParent::Dispatch()
|
||||
RefPtr<DeviceStorageFile> dsf
|
||||
= new DeviceStorageFile(p.type(), p.storageName(),
|
||||
p.rootdir(), NS_LITERAL_STRING(""));
|
||||
RefPtr<CancelableRunnable> r
|
||||
= new EnumerateFileEvent(this, dsf, p.since());
|
||||
|
||||
nsCOMPtr<nsIEventTarget> target
|
||||
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
||||
MOZ_ASSERT(target);
|
||||
target->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
r = new EnumerateFileEvent(this, dsf.forget(), p.since());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
NS_RUNTIMEABORT("not reached");
|
||||
break;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (r) {
|
||||
nsCOMPtr<nsIEventTarget> target =
|
||||
do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
||||
MOZ_ASSERT(target);
|
||||
target->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -393,10 +361,15 @@ DeviceStorageRequestParent::ActorDestroy(ActorDestroyReason)
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
mActorDestroyed = true;
|
||||
int32_t count = mRunnables.Length();
|
||||
for (int32_t index = 0; index < count; index++) {
|
||||
mRunnables[index]->Cancel();
|
||||
for (auto& runnable : mRunnables) {
|
||||
runnable->Cancel();
|
||||
}
|
||||
// Ensure we clear all references to the runnables so that there won't
|
||||
// be leak due to cyclic reference. Note that it is safe to release
|
||||
// the references here, since if a runnable is not cancelled yet, the
|
||||
// corresponding thread should still hold a reference to it, and thus
|
||||
// the runnable will end up being released in that thread, not here.
|
||||
mRunnables.Clear();
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::PostFreeSpaceResultEvent::PostFreeSpaceResultEvent(
|
||||
@@ -419,19 +392,6 @@ DeviceStorageRequestParent::PostFreeSpaceResultEvent::CancelableRun() {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::PostUsedSpaceResultEvent::
|
||||
PostUsedSpaceResultEvent(DeviceStorageRequestParent* aParent,
|
||||
const nsAString& aType,
|
||||
uint64_t aUsedSpace)
|
||||
: CancelableRunnable(aParent)
|
||||
, mType(aType)
|
||||
, mUsedSpace(aUsedSpace)
|
||||
{
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::PostUsedSpaceResultEvent::
|
||||
~PostUsedSpaceResultEvent() {}
|
||||
|
||||
nsresult
|
||||
DeviceStorageRequestParent::PostUsedSpaceResultEvent::CancelableRun() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
@@ -448,8 +408,6 @@ DeviceStorageRequestParent::PostErrorEvent::
|
||||
CopyASCIItoUTF16(aError, mError);
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::PostErrorEvent::~PostErrorEvent() {}
|
||||
|
||||
nsresult
|
||||
DeviceStorageRequestParent::PostErrorEvent::CancelableRun() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
@@ -459,14 +417,6 @@ DeviceStorageRequestParent::PostErrorEvent::CancelableRun() {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::PostSuccessEvent::
|
||||
PostSuccessEvent(DeviceStorageRequestParent* aParent)
|
||||
: CancelableRunnable(aParent)
|
||||
{
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::PostSuccessEvent::~PostSuccessEvent() {}
|
||||
|
||||
nsresult
|
||||
DeviceStorageRequestParent::PostSuccessEvent::CancelableRun() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
@@ -476,22 +426,6 @@ DeviceStorageRequestParent::PostSuccessEvent::CancelableRun() {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::PostBlobSuccessEvent::
|
||||
PostBlobSuccessEvent(DeviceStorageRequestParent* aParent,
|
||||
DeviceStorageFile* aFile,
|
||||
uint32_t aLength,
|
||||
nsACString& aMimeType,
|
||||
uint64_t aLastModifiedDate)
|
||||
: CancelableRunnable(aParent)
|
||||
, mLength(aLength)
|
||||
, mLastModificationDate(aLastModifiedDate)
|
||||
, mFile(aFile)
|
||||
, mMimeType(aMimeType)
|
||||
{
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::PostBlobSuccessEvent::~PostBlobSuccessEvent() {}
|
||||
|
||||
nsresult
|
||||
DeviceStorageRequestParent::PostBlobSuccessEvent::CancelableRun() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
@@ -520,21 +454,6 @@ DeviceStorageRequestParent::PostBlobSuccessEvent::CancelableRun() {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::PostEnumerationSuccessEvent::
|
||||
PostEnumerationSuccessEvent(DeviceStorageRequestParent* aParent,
|
||||
const nsAString& aStorageType,
|
||||
const nsAString& aRelPath,
|
||||
InfallibleTArray<DeviceStorageFileValue>& aPaths)
|
||||
: CancelableRunnable(aParent)
|
||||
, mStorageType(aStorageType)
|
||||
, mRelPath(aRelPath)
|
||||
, mPaths(aPaths)
|
||||
{
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::PostEnumerationSuccessEvent::
|
||||
~PostEnumerationSuccessEvent() {}
|
||||
|
||||
nsresult
|
||||
DeviceStorageRequestParent::PostEnumerationSuccessEvent::CancelableRun() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
@@ -544,36 +463,23 @@ DeviceStorageRequestParent::PostEnumerationSuccessEvent::CancelableRun() {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::CreateFdEvent::
|
||||
CreateFdEvent(DeviceStorageRequestParent* aParent,
|
||||
DeviceStorageFile* aFile)
|
||||
: CancelableRunnable(aParent)
|
||||
, mFile(aFile)
|
||||
{
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::CreateFdEvent::~CreateFdEvent()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
DeviceStorageRequestParent::CreateFdEvent::CancelableRun()
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsIRunnable> r;
|
||||
|
||||
if (!mFile->mFile) {
|
||||
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(
|
||||
new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN));
|
||||
}
|
||||
bool check = false;
|
||||
mFile->mFile->Exists(&check);
|
||||
if (check) {
|
||||
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_EXISTS);
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(
|
||||
new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_EXISTS));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> r;
|
||||
FileDescriptor fileDescriptor;
|
||||
nsresult rv = mFile->CreateFileDescriptor(fileDescriptor);
|
||||
if (NS_FAILED(rv)) {
|
||||
@@ -585,23 +491,7 @@ DeviceStorageRequestParent::CreateFdEvent::CancelableRun()
|
||||
r = new PostFileDescriptorResultEvent(mParent, fileDescriptor);
|
||||
}
|
||||
|
||||
return NS_DispatchToMainThread(r);
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::WriteFileEvent::
|
||||
WriteFileEvent(DeviceStorageRequestParent* aParent,
|
||||
DeviceStorageFile* aFile,
|
||||
nsIInputStream* aInputStream,
|
||||
int32_t aRequestType)
|
||||
: CancelableRunnable(aParent)
|
||||
, mFile(aFile)
|
||||
, mInputStream(aInputStream)
|
||||
, mRequestType(aRequestType)
|
||||
{
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::WriteFileEvent::~WriteFileEvent()
|
||||
{
|
||||
return NS_DispatchToMainThread(r.forget());
|
||||
}
|
||||
|
||||
nsresult
|
||||
@@ -609,11 +499,9 @@ DeviceStorageRequestParent::WriteFileEvent::CancelableRun()
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsIRunnable> r;
|
||||
|
||||
if (!mInputStream || !mFile->mFile) {
|
||||
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(
|
||||
new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN));
|
||||
}
|
||||
|
||||
bool check = false;
|
||||
@@ -622,21 +510,22 @@ DeviceStorageRequestParent::WriteFileEvent::CancelableRun()
|
||||
|
||||
if (mRequestType == DEVICE_STORAGE_REQUEST_CREATE) {
|
||||
if (check) {
|
||||
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_EXISTS);
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(
|
||||
new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_EXISTS));
|
||||
}
|
||||
rv = mFile->Write(mInputStream);
|
||||
} else if (mRequestType == DEVICE_STORAGE_REQUEST_APPEND) {
|
||||
if (!check) {
|
||||
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST);
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(
|
||||
new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST));
|
||||
}
|
||||
rv = mFile->Append(mInputStream);
|
||||
} else {
|
||||
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(
|
||||
new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> r;
|
||||
if (NS_FAILED(rv)) {
|
||||
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
|
||||
}
|
||||
@@ -644,18 +533,7 @@ DeviceStorageRequestParent::WriteFileEvent::CancelableRun()
|
||||
r = new PostPathResultEvent(mParent, mFile->mPath);
|
||||
}
|
||||
|
||||
return NS_DispatchToMainThread(r);
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::DeleteFileEvent::
|
||||
DeleteFileEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile)
|
||||
: CancelableRunnable(aParent)
|
||||
, mFile(aFile)
|
||||
{
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::DeleteFileEvent::~DeleteFileEvent()
|
||||
{
|
||||
return NS_DispatchToMainThread(r.forget());
|
||||
}
|
||||
|
||||
nsresult
|
||||
@@ -665,12 +543,11 @@ DeviceStorageRequestParent::DeleteFileEvent::CancelableRun()
|
||||
|
||||
mFile->Remove();
|
||||
|
||||
nsCOMPtr<nsIRunnable> r;
|
||||
|
||||
if (!mFile->mFile) {
|
||||
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(
|
||||
new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN));
|
||||
}
|
||||
nsCOMPtr<nsIRunnable> r;
|
||||
bool check = false;
|
||||
mFile->mFile->Exists(&check);
|
||||
if (check) {
|
||||
@@ -680,19 +557,7 @@ DeviceStorageRequestParent::DeleteFileEvent::CancelableRun()
|
||||
r = new PostPathResultEvent(mParent, mFile->mPath);
|
||||
}
|
||||
|
||||
return NS_DispatchToMainThread(r);
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::FreeSpaceFileEvent::
|
||||
FreeSpaceFileEvent(DeviceStorageRequestParent* aParent,
|
||||
DeviceStorageFile* aFile)
|
||||
: CancelableRunnable(aParent)
|
||||
, mFile(aFile)
|
||||
{
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::FreeSpaceFileEvent::~FreeSpaceFileEvent()
|
||||
{
|
||||
return NS_DispatchToMainThread(r.forget());
|
||||
}
|
||||
|
||||
nsresult
|
||||
@@ -705,21 +570,8 @@ DeviceStorageRequestParent::FreeSpaceFileEvent::CancelableRun()
|
||||
mFile->GetStorageFreeSpace(&freeSpace);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> r;
|
||||
r = new PostFreeSpaceResultEvent(mParent, static_cast<uint64_t>(freeSpace));
|
||||
return NS_DispatchToMainThread(r);
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::UsedSpaceFileEvent::
|
||||
UsedSpaceFileEvent(DeviceStorageRequestParent* aParent,
|
||||
DeviceStorageFile* aFile)
|
||||
: CancelableRunnable(aParent)
|
||||
, mFile(aFile)
|
||||
{
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::UsedSpaceFileEvent::~UsedSpaceFileEvent()
|
||||
{
|
||||
return NS_DispatchToMainThread(
|
||||
new PostFreeSpaceResultEvent(mParent, static_cast<uint64_t>(freeSpace)));
|
||||
}
|
||||
|
||||
nsresult
|
||||
@@ -743,13 +595,13 @@ DeviceStorageRequestParent::UsedSpaceFileEvent::CancelableRun()
|
||||
} else {
|
||||
r = new PostUsedSpaceResultEvent(mParent, mFile->mStorageType, totalUsage);
|
||||
}
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(r.forget());
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::ReadFileEvent::
|
||||
ReadFileEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile)
|
||||
: CancelableRunnable(aParent)
|
||||
, mFile(aFile)
|
||||
ReadFileEvent(DeviceStorageRequestParent* aParent,
|
||||
already_AddRefed<DeviceStorageFile>&& aFile)
|
||||
: CancelableFileEvent(aParent, Move(aFile))
|
||||
{
|
||||
nsCOMPtr<nsIMIMEService> mimeService
|
||||
= do_GetService(NS_MIMESERVICE_CONTRACTID);
|
||||
@@ -761,60 +613,41 @@ DeviceStorageRequestParent::ReadFileEvent::
|
||||
}
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::ReadFileEvent::~ReadFileEvent()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
DeviceStorageRequestParent::ReadFileEvent::CancelableRun()
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsIRunnable> r;
|
||||
|
||||
if (!mFile->mFile) {
|
||||
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(
|
||||
new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN));
|
||||
}
|
||||
bool check = false;
|
||||
mFile->mFile->Exists(&check);
|
||||
|
||||
if (!check) {
|
||||
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST);
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(
|
||||
new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST));
|
||||
}
|
||||
|
||||
int64_t fileSize;
|
||||
nsresult rv = mFile->mFile->GetFileSize(&fileSize);
|
||||
if (NS_FAILED(rv)) {
|
||||
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(
|
||||
new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN));
|
||||
}
|
||||
|
||||
PRTime modDate;
|
||||
rv = mFile->mFile->GetLastModifiedTime(&modDate);
|
||||
if (NS_FAILED(rv)) {
|
||||
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(
|
||||
new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN));
|
||||
}
|
||||
|
||||
r = new PostBlobSuccessEvent(mParent, mFile, static_cast<uint64_t>(fileSize),
|
||||
mMimeType, modDate);
|
||||
return NS_DispatchToMainThread(r);
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::EnumerateFileEvent::
|
||||
EnumerateFileEvent(DeviceStorageRequestParent* aParent,
|
||||
DeviceStorageFile* aFile,
|
||||
uint64_t aSince)
|
||||
: CancelableRunnable(aParent)
|
||||
, mFile(aFile)
|
||||
, mSince(aSince)
|
||||
{
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::EnumerateFileEvent::~EnumerateFileEvent()
|
||||
{
|
||||
return NS_DispatchToMainThread(
|
||||
new PostBlobSuccessEvent(mParent, mFile.forget(),
|
||||
static_cast<uint64_t>(fileSize),
|
||||
mMimeType, modDate));
|
||||
}
|
||||
|
||||
nsresult
|
||||
@@ -822,13 +655,12 @@ DeviceStorageRequestParent::EnumerateFileEvent::CancelableRun()
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsIRunnable> r;
|
||||
if (mFile->mFile) {
|
||||
bool check = false;
|
||||
mFile->mFile->Exists(&check);
|
||||
if (!check) {
|
||||
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST);
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(
|
||||
new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -843,22 +675,9 @@ DeviceStorageRequestParent::EnumerateFileEvent::CancelableRun()
|
||||
values.AppendElement(dsvf);
|
||||
}
|
||||
|
||||
r = new PostEnumerationSuccessEvent(mParent, mFile->mStorageType,
|
||||
mFile->mRootDir, values);
|
||||
return NS_DispatchToMainThread(r);
|
||||
}
|
||||
|
||||
|
||||
DeviceStorageRequestParent::PostPathResultEvent::
|
||||
PostPathResultEvent(DeviceStorageRequestParent* aParent,
|
||||
const nsAString& aPath)
|
||||
: CancelableRunnable(aParent)
|
||||
, mPath(aPath)
|
||||
{
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::PostPathResultEvent::~PostPathResultEvent()
|
||||
{
|
||||
return NS_DispatchToMainThread(
|
||||
new PostEnumerationSuccessEvent(mParent, mFile->mStorageType,
|
||||
mFile->mRootDir, values));
|
||||
}
|
||||
|
||||
nsresult
|
||||
@@ -871,19 +690,6 @@ DeviceStorageRequestParent::PostPathResultEvent::CancelableRun()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::PostFileDescriptorResultEvent::
|
||||
PostFileDescriptorResultEvent(DeviceStorageRequestParent* aParent,
|
||||
const FileDescriptor& aFileDescriptor)
|
||||
: CancelableRunnable(aParent)
|
||||
, mFileDescriptor(aFileDescriptor)
|
||||
{
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::PostFileDescriptorResultEvent::
|
||||
~PostFileDescriptorResultEvent()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
DeviceStorageRequestParent::PostFileDescriptorResultEvent::CancelableRun()
|
||||
{
|
||||
@@ -894,19 +700,6 @@ DeviceStorageRequestParent::PostFileDescriptorResultEvent::CancelableRun()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::PostFormatResultEvent::
|
||||
PostFormatResultEvent(DeviceStorageRequestParent* aParent,
|
||||
DeviceStorageFile* aFile)
|
||||
: CancelableRunnable(aParent)
|
||||
, mFile(aFile)
|
||||
{
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::PostFormatResultEvent::
|
||||
~PostFormatResultEvent()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
DeviceStorageRequestParent::PostFormatResultEvent::CancelableRun()
|
||||
{
|
||||
@@ -922,19 +715,6 @@ DeviceStorageRequestParent::PostFormatResultEvent::CancelableRun()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::PostMountResultEvent::
|
||||
PostMountResultEvent(DeviceStorageRequestParent* aParent,
|
||||
DeviceStorageFile* aFile)
|
||||
: CancelableRunnable(aParent)
|
||||
, mFile(aFile)
|
||||
{
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::PostMountResultEvent::
|
||||
~PostMountResultEvent()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
DeviceStorageRequestParent::PostMountResultEvent::CancelableRun()
|
||||
{
|
||||
@@ -950,19 +730,6 @@ DeviceStorageRequestParent::PostMountResultEvent::CancelableRun()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::PostUnmountResultEvent::
|
||||
PostUnmountResultEvent(DeviceStorageRequestParent* aParent,
|
||||
DeviceStorageFile* aFile)
|
||||
: CancelableRunnable(aParent)
|
||||
, mFile(aFile)
|
||||
{
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::PostUnmountResultEvent::
|
||||
~PostUnmountResultEvent()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
DeviceStorageRequestParent::PostUnmountResultEvent::CancelableRun()
|
||||
{
|
||||
|
||||
@@ -74,11 +74,22 @@ private:
|
||||
bool mCanceled;
|
||||
};
|
||||
|
||||
class CancelableFileEvent : public CancelableRunnable
|
||||
{
|
||||
protected:
|
||||
CancelableFileEvent(DeviceStorageRequestParent* aParent,
|
||||
already_AddRefed<DeviceStorageFile>&& aFile)
|
||||
: CancelableRunnable(aParent)
|
||||
, mFile(Move(aFile)) {}
|
||||
|
||||
RefPtr<DeviceStorageFile> mFile;
|
||||
};
|
||||
|
||||
class PostErrorEvent : public CancelableRunnable
|
||||
{
|
||||
public:
|
||||
PostErrorEvent(DeviceStorageRequestParent* aParent, const char* aError);
|
||||
virtual ~PostErrorEvent();
|
||||
virtual ~PostErrorEvent() {}
|
||||
virtual nsresult CancelableRun();
|
||||
private:
|
||||
nsString mError;
|
||||
@@ -87,21 +98,28 @@ private:
|
||||
class PostSuccessEvent : public CancelableRunnable
|
||||
{
|
||||
public:
|
||||
explicit PostSuccessEvent(DeviceStorageRequestParent* aParent);
|
||||
virtual ~PostSuccessEvent();
|
||||
explicit PostSuccessEvent(DeviceStorageRequestParent* aParent)
|
||||
: CancelableRunnable(aParent) {}
|
||||
virtual ~PostSuccessEvent() {}
|
||||
virtual nsresult CancelableRun();
|
||||
};
|
||||
|
||||
class PostBlobSuccessEvent : public CancelableRunnable
|
||||
class PostBlobSuccessEvent : public CancelableFileEvent
|
||||
{
|
||||
public:
|
||||
PostBlobSuccessEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile, uint32_t aLength, nsACString& aMimeType, uint64_t aLastModifiedDate);
|
||||
virtual ~PostBlobSuccessEvent();
|
||||
PostBlobSuccessEvent(DeviceStorageRequestParent* aParent,
|
||||
already_AddRefed<DeviceStorageFile>&& aFile,
|
||||
uint32_t aLength, nsACString& aMimeType,
|
||||
uint64_t aLastModifiedDate)
|
||||
: CancelableFileEvent(aParent, Move(aFile))
|
||||
, mLength(aLength)
|
||||
, mLastModificationDate(aLastModifiedDate)
|
||||
, mMimeType(aMimeType) {}
|
||||
virtual ~PostBlobSuccessEvent() {}
|
||||
virtual nsresult CancelableRun();
|
||||
private:
|
||||
uint32_t mLength;
|
||||
uint64_t mLastModificationDate;
|
||||
RefPtr<DeviceStorageFile> mFile;
|
||||
nsCString mMimeType;
|
||||
};
|
||||
|
||||
@@ -111,8 +129,12 @@ private:
|
||||
PostEnumerationSuccessEvent(DeviceStorageRequestParent* aParent,
|
||||
const nsAString& aStorageType,
|
||||
const nsAString& aRelPath,
|
||||
InfallibleTArray<DeviceStorageFileValue>& aPaths);
|
||||
virtual ~PostEnumerationSuccessEvent();
|
||||
InfallibleTArray<DeviceStorageFileValue>& aPaths)
|
||||
: CancelableRunnable(aParent)
|
||||
, mStorageType(aStorageType)
|
||||
, mRelPath(aRelPath)
|
||||
, mPaths(aPaths) {}
|
||||
virtual ~PostEnumerationSuccessEvent() {}
|
||||
virtual nsresult CancelableRun();
|
||||
private:
|
||||
const nsString mStorageType;
|
||||
@@ -120,89 +142,97 @@ private:
|
||||
InfallibleTArray<DeviceStorageFileValue> mPaths;
|
||||
};
|
||||
|
||||
class CreateFdEvent : public CancelableRunnable
|
||||
class CreateFdEvent : public CancelableFileEvent
|
||||
{
|
||||
public:
|
||||
CreateFdEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile);
|
||||
virtual ~CreateFdEvent();
|
||||
CreateFdEvent(DeviceStorageRequestParent* aParent,
|
||||
already_AddRefed<DeviceStorageFile>&& aFile)
|
||||
: CancelableFileEvent(aParent, Move(aFile)) {}
|
||||
virtual ~CreateFdEvent() {}
|
||||
virtual nsresult CancelableRun();
|
||||
private:
|
||||
RefPtr<DeviceStorageFile> mFile;
|
||||
};
|
||||
|
||||
class WriteFileEvent : public CancelableRunnable
|
||||
class WriteFileEvent : public CancelableFileEvent
|
||||
{
|
||||
public:
|
||||
WriteFileEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile,
|
||||
nsIInputStream* aInputStream, int32_t aRequestType);
|
||||
virtual ~WriteFileEvent();
|
||||
WriteFileEvent(DeviceStorageRequestParent* aParent,
|
||||
already_AddRefed<DeviceStorageFile>&& aFile,
|
||||
nsIInputStream* aInputStream, int32_t aRequestType)
|
||||
: CancelableFileEvent(aParent, Move(aFile))
|
||||
, mInputStream(aInputStream)
|
||||
, mRequestType(aRequestType) {}
|
||||
virtual ~WriteFileEvent() {}
|
||||
virtual nsresult CancelableRun();
|
||||
private:
|
||||
RefPtr<DeviceStorageFile> mFile;
|
||||
nsCOMPtr<nsIInputStream> mInputStream;
|
||||
int32_t mRequestType;
|
||||
};
|
||||
|
||||
class DeleteFileEvent : public CancelableRunnable
|
||||
class DeleteFileEvent : public CancelableFileEvent
|
||||
{
|
||||
public:
|
||||
DeleteFileEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile);
|
||||
virtual ~DeleteFileEvent();
|
||||
DeleteFileEvent(DeviceStorageRequestParent* aParent,
|
||||
already_AddRefed<DeviceStorageFile>&& aFile)
|
||||
: CancelableFileEvent(aParent, Move(aFile)) {}
|
||||
virtual ~DeleteFileEvent() {}
|
||||
virtual nsresult CancelableRun();
|
||||
};
|
||||
|
||||
class FreeSpaceFileEvent : public CancelableFileEvent
|
||||
{
|
||||
public:
|
||||
FreeSpaceFileEvent(DeviceStorageRequestParent* aParent,
|
||||
already_AddRefed<DeviceStorageFile>&& aFile)
|
||||
: CancelableFileEvent(aParent, Move(aFile)) {}
|
||||
virtual ~FreeSpaceFileEvent() {}
|
||||
virtual nsresult CancelableRun();
|
||||
};
|
||||
|
||||
class UsedSpaceFileEvent : public CancelableFileEvent
|
||||
{
|
||||
public:
|
||||
UsedSpaceFileEvent(DeviceStorageRequestParent* aParent,
|
||||
already_AddRefed<DeviceStorageFile>&& aFile)
|
||||
: CancelableFileEvent(aParent, Move(aFile)) {}
|
||||
virtual ~UsedSpaceFileEvent() {}
|
||||
virtual nsresult CancelableRun();
|
||||
};
|
||||
|
||||
class ReadFileEvent : public CancelableFileEvent
|
||||
{
|
||||
public:
|
||||
ReadFileEvent(DeviceStorageRequestParent* aParent,
|
||||
already_AddRefed<DeviceStorageFile>&& aFile);
|
||||
virtual ~ReadFileEvent() {}
|
||||
virtual nsresult CancelableRun();
|
||||
private:
|
||||
RefPtr<DeviceStorageFile> mFile;
|
||||
};
|
||||
|
||||
class FreeSpaceFileEvent : public CancelableRunnable
|
||||
{
|
||||
public:
|
||||
FreeSpaceFileEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile);
|
||||
virtual ~FreeSpaceFileEvent();
|
||||
virtual nsresult CancelableRun();
|
||||
private:
|
||||
RefPtr<DeviceStorageFile> mFile;
|
||||
};
|
||||
|
||||
class UsedSpaceFileEvent : public CancelableRunnable
|
||||
{
|
||||
public:
|
||||
UsedSpaceFileEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile);
|
||||
virtual ~UsedSpaceFileEvent();
|
||||
virtual nsresult CancelableRun();
|
||||
private:
|
||||
RefPtr<DeviceStorageFile> mFile;
|
||||
};
|
||||
|
||||
class ReadFileEvent : public CancelableRunnable
|
||||
{
|
||||
public:
|
||||
ReadFileEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile);
|
||||
virtual ~ReadFileEvent();
|
||||
virtual nsresult CancelableRun();
|
||||
private:
|
||||
RefPtr<DeviceStorageFile> mFile;
|
||||
nsCString mMimeType;
|
||||
};
|
||||
|
||||
class EnumerateFileEvent : public CancelableRunnable
|
||||
class EnumerateFileEvent : public CancelableFileEvent
|
||||
{
|
||||
public:
|
||||
EnumerateFileEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile, uint64_t aSince);
|
||||
virtual ~EnumerateFileEvent();
|
||||
EnumerateFileEvent(DeviceStorageRequestParent* aParent,
|
||||
already_AddRefed<DeviceStorageFile>&& aFile,
|
||||
uint64_t aSince)
|
||||
: CancelableFileEvent(aParent, Move(aFile))
|
||||
, mSince(aSince) {}
|
||||
virtual ~EnumerateFileEvent() {}
|
||||
virtual nsresult CancelableRun();
|
||||
private:
|
||||
RefPtr<DeviceStorageFile> mFile;
|
||||
uint64_t mSince;
|
||||
};
|
||||
|
||||
class PostPathResultEvent : public CancelableRunnable
|
||||
{
|
||||
public:
|
||||
PostPathResultEvent(DeviceStorageRequestParent* aParent, const nsAString& aPath);
|
||||
virtual ~PostPathResultEvent();
|
||||
PostPathResultEvent(DeviceStorageRequestParent* aParent,
|
||||
const nsAString& aPath)
|
||||
: CancelableRunnable(aParent)
|
||||
, mPath(aPath) {}
|
||||
virtual ~PostPathResultEvent() {}
|
||||
virtual nsresult CancelableRun();
|
||||
private:
|
||||
RefPtr<DeviceStorageFile> mFile;
|
||||
nsString mPath;
|
||||
};
|
||||
|
||||
@@ -210,11 +240,12 @@ private:
|
||||
{
|
||||
public:
|
||||
PostFileDescriptorResultEvent(DeviceStorageRequestParent* aParent,
|
||||
const FileDescriptor& aFileDescriptor);
|
||||
virtual ~PostFileDescriptorResultEvent();
|
||||
const FileDescriptor& aFileDescriptor)
|
||||
: CancelableRunnable(aParent)
|
||||
, mFileDescriptor(aFileDescriptor) {}
|
||||
virtual ~PostFileDescriptorResultEvent() {}
|
||||
virtual nsresult CancelableRun();
|
||||
private:
|
||||
RefPtr<DeviceStorageFile> mFile;
|
||||
FileDescriptor mFileDescriptor;
|
||||
};
|
||||
|
||||
@@ -234,42 +265,45 @@ private:
|
||||
public:
|
||||
PostUsedSpaceResultEvent(DeviceStorageRequestParent* aParent,
|
||||
const nsAString& aType,
|
||||
uint64_t aUsedSpace);
|
||||
virtual ~PostUsedSpaceResultEvent();
|
||||
uint64_t aUsedSpace)
|
||||
: CancelableRunnable(aParent)
|
||||
, mType(aType)
|
||||
, mUsedSpace(aUsedSpace) {}
|
||||
virtual ~PostUsedSpaceResultEvent() {}
|
||||
virtual nsresult CancelableRun();
|
||||
private:
|
||||
nsString mType;
|
||||
uint64_t mUsedSpace;
|
||||
};
|
||||
|
||||
class PostFormatResultEvent : public CancelableRunnable
|
||||
class PostFormatResultEvent : public CancelableFileEvent
|
||||
{
|
||||
public:
|
||||
PostFormatResultEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile);
|
||||
virtual ~PostFormatResultEvent();
|
||||
PostFormatResultEvent(DeviceStorageRequestParent* aParent,
|
||||
already_AddRefed<DeviceStorageFile>&& aFile)
|
||||
: CancelableFileEvent(aParent, Move(aFile)) {}
|
||||
virtual ~PostFormatResultEvent() {}
|
||||
virtual nsresult CancelableRun();
|
||||
private:
|
||||
RefPtr<DeviceStorageFile> mFile;
|
||||
};
|
||||
|
||||
class PostMountResultEvent : public CancelableRunnable
|
||||
class PostMountResultEvent : public CancelableFileEvent
|
||||
{
|
||||
public:
|
||||
PostMountResultEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile);
|
||||
virtual ~PostMountResultEvent();
|
||||
PostMountResultEvent(DeviceStorageRequestParent* aParent,
|
||||
already_AddRefed<DeviceStorageFile>&& aFile)
|
||||
: CancelableFileEvent(aParent, Move(aFile)) {}
|
||||
virtual ~PostMountResultEvent() {}
|
||||
virtual nsresult CancelableRun();
|
||||
private:
|
||||
RefPtr<DeviceStorageFile> mFile;
|
||||
};
|
||||
|
||||
class PostUnmountResultEvent : public CancelableRunnable
|
||||
class PostUnmountResultEvent : public CancelableFileEvent
|
||||
{
|
||||
public:
|
||||
PostUnmountResultEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile);
|
||||
virtual ~PostUnmountResultEvent();
|
||||
PostUnmountResultEvent(DeviceStorageRequestParent* aParent,
|
||||
already_AddRefed<DeviceStorageFile>&& aFile)
|
||||
: CancelableFileEvent(aParent, Move(aFile)) {}
|
||||
virtual ~PostUnmountResultEvent() {}
|
||||
virtual nsresult CancelableRun();
|
||||
private:
|
||||
RefPtr<DeviceStorageFile> mFile;
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
@@ -825,7 +825,7 @@ DeviceStorageStatics::ListenerWrapper::ListenerWrapper(nsDOMDeviceStorage* aList
|
||||
DeviceStorageStatics::ListenerWrapper::~ListenerWrapper()
|
||||
{
|
||||
// Even weak pointers are not thread safe
|
||||
NS_ProxyRelease(mOwningThread, mListener);
|
||||
NS_ProxyRelease(mOwningThread, mListener.forget());
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -854,7 +854,7 @@ DeviceStorageStatics::ListenerWrapper::OnFileWatcherUpdate(const nsCString& aDat
|
||||
listener->OnFileWatcherUpdate(data, file);
|
||||
}
|
||||
});
|
||||
mOwningThread->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
mOwningThread->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -867,7 +867,7 @@ DeviceStorageStatics::ListenerWrapper::OnDiskSpaceWatcher(bool aLowDiskSpace)
|
||||
listener->OnDiskSpaceWatcher(aLowDiskSpace);
|
||||
}
|
||||
});
|
||||
mOwningThread->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
mOwningThread->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -880,7 +880,7 @@ DeviceStorageStatics::ListenerWrapper::OnWritableNameChanged()
|
||||
listener->OnWritableNameChanged();
|
||||
}
|
||||
});
|
||||
mOwningThread->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
mOwningThread->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
@@ -895,7 +895,7 @@ DeviceStorageStatics::ListenerWrapper::OnVolumeStateChanged(nsIVolume* aVolume)
|
||||
listener->OnVolumeStateChanged(volume);
|
||||
}
|
||||
});
|
||||
mOwningThread->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
mOwningThread->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -693,8 +693,20 @@ DeviceStorageFile::CreateUnique(nsAString& aFileName,
|
||||
if (storageName.IsEmpty()) {
|
||||
nsDOMDeviceStorage::GetDefaultStorageName(storageType, storageName);
|
||||
}
|
||||
return CreateUnique(storageType, storageName, storagePath,
|
||||
aFileType, aFileAttributes);
|
||||
}
|
||||
|
||||
//static
|
||||
already_AddRefed<DeviceStorageFile>
|
||||
DeviceStorageFile::CreateUnique(const nsAString& aStorageType,
|
||||
const nsAString& aStorageName,
|
||||
nsAString& aFileName,
|
||||
uint32_t aFileType,
|
||||
uint32_t aFileAttributes)
|
||||
{
|
||||
RefPtr<DeviceStorageFile> dsf =
|
||||
new DeviceStorageFile(storageType, storageName, storagePath);
|
||||
new DeviceStorageFile(aStorageType, aStorageName, aFileName);
|
||||
if (!dsf->mFile) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -824,8 +836,7 @@ DeviceStorageFile::Write(nsIInputStream* aInputStream)
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> iocomplete = new IOEventComplete(this, "created");
|
||||
rv = NS_DispatchToMainThread(iocomplete);
|
||||
rv = NS_DispatchToMainThread(new IOEventComplete(this, "created"));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
@@ -852,8 +863,7 @@ DeviceStorageFile::Write(InfallibleTArray<uint8_t>& aBits)
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> iocomplete = new IOEventComplete(this, "created");
|
||||
rv = NS_DispatchToMainThread(iocomplete);
|
||||
rv = NS_DispatchToMainThread(new IOEventComplete(this, "created"));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
@@ -869,8 +879,7 @@ DeviceStorageFile::Write(InfallibleTArray<uint8_t>& aBits)
|
||||
outputStream->Write((char*) aBits.Elements(), aBits.Length(), &wrote);
|
||||
outputStream->Close();
|
||||
|
||||
iocomplete = new IOEventComplete(this, "modified");
|
||||
rv = NS_DispatchToMainThread(iocomplete);
|
||||
rv = NS_DispatchToMainThread(new IOEventComplete(this, "modified"));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
@@ -923,8 +932,7 @@ DeviceStorageFile::Append(nsIInputStream* aInputStream, nsIOutputStream* aOutput
|
||||
bufSize -= wrote;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> iocomplete = new IOEventComplete(this, "modified");
|
||||
rv = NS_DispatchToMainThread(iocomplete);
|
||||
rv = NS_DispatchToMainThread(new IOEventComplete(this, "modified"));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
@@ -961,8 +969,7 @@ DeviceStorageFile::Remove()
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> iocomplete = new IOEventComplete(this, "deleted");
|
||||
return NS_DispatchToMainThread(iocomplete);
|
||||
return NS_DispatchToMainThread(new IOEventComplete(this, "deleted"));
|
||||
}
|
||||
|
||||
nsresult
|
||||
@@ -1499,6 +1506,7 @@ DeviceStorageRequest::DeviceStorageRequest()
|
||||
: mId(DeviceStorageRequestManager::INVALID_ID)
|
||||
, mAccess(DEVICE_STORAGE_ACCESS_UNDEFINED)
|
||||
, mSendToParent(true)
|
||||
, mUseMainThread(false)
|
||||
, mUseStreamTransport(false)
|
||||
, mCheckFile(false)
|
||||
, mCheckBlob(false)
|
||||
@@ -1521,7 +1529,7 @@ DeviceStorageRequest::~DeviceStorageRequest()
|
||||
|
||||
void
|
||||
DeviceStorageRequest::Initialize(DeviceStorageRequestManager* aManager,
|
||||
DeviceStorageFile* aFile,
|
||||
already_AddRefed<DeviceStorageFile>&& aFile,
|
||||
uint32_t aId)
|
||||
{
|
||||
DS_LOG_DEBUG("%p manages %p", aManager, this);
|
||||
@@ -1535,11 +1543,11 @@ DeviceStorageRequest::Initialize(DeviceStorageRequestManager* aManager,
|
||||
|
||||
void
|
||||
DeviceStorageRequest::Initialize(DeviceStorageRequestManager* aManager,
|
||||
DeviceStorageFile* aFile,
|
||||
already_AddRefed<DeviceStorageFile>&& aFile,
|
||||
uint32_t aRequest,
|
||||
BlobImpl* aBlob)
|
||||
{
|
||||
Initialize(aManager, aFile, aRequest);
|
||||
Initialize(aManager, Move(aFile), aRequest);
|
||||
mBlob = aBlob;
|
||||
mCheckBlob = true;
|
||||
mCheckFile = true;
|
||||
@@ -1548,11 +1556,11 @@ DeviceStorageRequest::Initialize(DeviceStorageRequestManager* aManager,
|
||||
|
||||
void
|
||||
DeviceStorageRequest::Initialize(DeviceStorageRequestManager* aManager,
|
||||
DeviceStorageFile* aFile,
|
||||
already_AddRefed<DeviceStorageFile>&& aFile,
|
||||
uint32_t aRequest,
|
||||
DeviceStorageFileDescriptor* aDSFileDescriptor)
|
||||
{
|
||||
Initialize(aManager, aFile, aRequest);
|
||||
Initialize(aManager, Move(aFile), aRequest);
|
||||
mDSFileDescriptor = aDSFileDescriptor;
|
||||
MOZ_ASSERT(mDSFileDescriptor);
|
||||
}
|
||||
@@ -1578,11 +1586,30 @@ DeviceStorageRequest::Cancel()
|
||||
nsresult
|
||||
DeviceStorageRequest::Allow()
|
||||
{
|
||||
if (mUseMainThread && !NS_IsMainThread()) {
|
||||
RefPtr<DeviceStorageRequest> self = this;
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([self] () -> void
|
||||
{
|
||||
self->Allow();
|
||||
});
|
||||
return NS_DispatchToMainThread(r.forget());
|
||||
}
|
||||
|
||||
nsresult rv = AllowInternal();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return Reject(rv == NS_ERROR_ILLEGAL_VALUE
|
||||
? POST_ERROR_EVENT_ILLEGAL_TYPE
|
||||
: POST_ERROR_EVENT_UNKNOWN);
|
||||
const char *reason;
|
||||
switch (rv) {
|
||||
case NS_ERROR_ILLEGAL_VALUE:
|
||||
reason = POST_ERROR_EVENT_ILLEGAL_TYPE;
|
||||
break;
|
||||
case NS_ERROR_DOM_SECURITY_ERR:
|
||||
reason = POST_ERROR_EVENT_PERMISSION_DENIED;
|
||||
break;
|
||||
default:
|
||||
reason = POST_ERROR_EVENT_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
return Reject(reason);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
@@ -1607,9 +1634,10 @@ DeviceStorageRequest::GetManager() const
|
||||
return mManager;
|
||||
}
|
||||
|
||||
void
|
||||
nsresult
|
||||
DeviceStorageRequest::Prepare()
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
@@ -1623,7 +1651,11 @@ nsresult
|
||||
DeviceStorageRequest::AllowInternal()
|
||||
{
|
||||
MOZ_ASSERT(mManager->IsOwningThread() || NS_IsMainThread());
|
||||
Prepare();
|
||||
|
||||
nsresult rv = Prepare();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
DeviceStorageTypeChecker* typeChecker
|
||||
= DeviceStorageTypeChecker::CreateOrGet();
|
||||
@@ -1649,7 +1681,8 @@ DeviceStorageRequest::AllowInternal()
|
||||
nsCOMPtr<nsIEventTarget> target
|
||||
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
||||
MOZ_ASSERT(target);
|
||||
return target->Dispatch(this, NS_DISPATCH_NORMAL);
|
||||
nsCOMPtr<nsIRunnable> self = this;
|
||||
return target->Dispatch(self.forget(), NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
DS_LOG_INFO("run %u", mId);
|
||||
@@ -1669,7 +1702,7 @@ DeviceStorageRequest::SendToParentProcess()
|
||||
self->Reject(POST_ERROR_EVENT_UNKNOWN);
|
||||
}
|
||||
});
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(r.forget());
|
||||
}
|
||||
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
@@ -1699,11 +1732,11 @@ DeviceStorageCursorRequest::DeviceStorageCursorRequest()
|
||||
|
||||
void
|
||||
DeviceStorageCursorRequest::Initialize(DeviceStorageRequestManager* aManager,
|
||||
DeviceStorageFile* aFile,
|
||||
already_AddRefed<DeviceStorageFile>&& aFile,
|
||||
uint32_t aRequest,
|
||||
PRTime aSince)
|
||||
{
|
||||
Initialize(aManager, aFile, aRequest);
|
||||
Initialize(aManager, Move(aFile), aRequest);
|
||||
mStorageType = mFile->mStorageType;
|
||||
mSince = aSince;
|
||||
}
|
||||
@@ -1729,7 +1762,7 @@ DeviceStorageCursorRequest::SendContinueToParentProcess()
|
||||
{
|
||||
self->SendContinueToParentProcess();
|
||||
});
|
||||
return NS_DispatchToMainThread(r);
|
||||
return NS_DispatchToMainThread(r.forget());
|
||||
}
|
||||
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
@@ -1756,7 +1789,7 @@ DeviceStorageCursorRequest::Continue()
|
||||
{
|
||||
self->Continue();
|
||||
});
|
||||
nsresult rv = NS_DispatchToMainThread(r);
|
||||
nsresult rv = NS_DispatchToMainThread(r.forget());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return Reject(POST_ERROR_EVENT_UNKNOWN);
|
||||
}
|
||||
@@ -1869,6 +1902,8 @@ class DeviceStorageCreateRequest final
|
||||
: public DeviceStorageRequest
|
||||
{
|
||||
public:
|
||||
using DeviceStorageRequest::Initialize;
|
||||
|
||||
DeviceStorageCreateRequest()
|
||||
{
|
||||
mAccess = DEVICE_STORAGE_ACCESS_CREATE;
|
||||
@@ -1903,7 +1938,62 @@ public:
|
||||
return Resolve(fullPath);
|
||||
}
|
||||
|
||||
void Initialize(DeviceStorageRequestManager* aManager,
|
||||
already_AddRefed<DeviceStorageFile>&& aFile,
|
||||
uint32_t aRequest) override
|
||||
{
|
||||
DeviceStorageRequest::Initialize(aManager, Move(aFile), aRequest);
|
||||
mUseMainThread = mFile->mPath.IsEmpty();
|
||||
}
|
||||
|
||||
protected:
|
||||
nsresult Prepare() override
|
||||
{
|
||||
if (!mFile->mPath.IsEmpty()) {
|
||||
// Checks have already been performed when request was created
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsIMIMEService> mimeSvc = do_GetService(NS_MIMESERVICE_CONTRACTID);
|
||||
if (!mimeSvc) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// if mimeType or extension are null, the request will be rejected
|
||||
// in DeviceStorageRequest::AllowInternal when the type checker
|
||||
// verifies the file path
|
||||
nsString mimeType;
|
||||
mBlob->GetType(mimeType);
|
||||
|
||||
nsCString extension;
|
||||
mimeSvc->GetPrimaryExtension(NS_LossyConvertUTF16toASCII(mimeType),
|
||||
EmptyCString(), extension);
|
||||
|
||||
char buffer[32];
|
||||
NS_MakeRandomString(buffer, ArrayLength(buffer) - 1);
|
||||
|
||||
nsAutoString path;
|
||||
path.AssignLiteral(buffer);
|
||||
path.Append('.');
|
||||
path.AppendASCII(extension.get());
|
||||
|
||||
RefPtr<DeviceStorageFile> file
|
||||
= DeviceStorageFile::CreateUnique(mFile->mStorageType,
|
||||
mFile->mStorageName, path,
|
||||
nsIFile::NORMAL_FILE_TYPE, 00600);
|
||||
if (!file) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (!file->IsSafePath()) {
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
|
||||
mFile = file.forget();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult CreateSendParams(DeviceStorageParams& aParams) override
|
||||
{
|
||||
BlobChild* actor
|
||||
@@ -1986,16 +2076,17 @@ public:
|
||||
|
||||
DeviceStorageOpenRequest()
|
||||
{
|
||||
mUseMainThread = true;
|
||||
mUseStreamTransport = true;
|
||||
mCheckFile = true;
|
||||
DS_LOG_INFO("");
|
||||
}
|
||||
|
||||
void Initialize(DeviceStorageRequestManager* aManager,
|
||||
DeviceStorageFile* aFile,
|
||||
already_AddRefed<DeviceStorageFile>&& aFile,
|
||||
uint32_t aRequest) override
|
||||
{
|
||||
DeviceStorageRequest::Initialize(aManager, aFile, aRequest);
|
||||
DeviceStorageRequest::Initialize(aManager, Move(aFile), aRequest);
|
||||
mAccess = mFile->mEditable ? DEVICE_STORAGE_ACCESS_WRITE
|
||||
: DEVICE_STORAGE_ACCESS_READ;
|
||||
}
|
||||
@@ -2019,10 +2110,11 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
void Prepare() override
|
||||
nsresult Prepare() override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mFile->CalculateMimeType();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult CreateSendParams(DeviceStorageParams& aParams) override
|
||||
@@ -2121,7 +2213,8 @@ public:
|
||||
DeviceStorageUsedSpaceCache* usedSpaceCache
|
||||
= DeviceStorageUsedSpaceCache::CreateOrGet();
|
||||
MOZ_ASSERT(usedSpaceCache);
|
||||
usedSpaceCache->Dispatch(this);
|
||||
nsCOMPtr<nsIRunnable> self = this;
|
||||
usedSpaceCache->Dispatch(self.forget());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -2306,10 +2399,10 @@ public:
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(DeviceStoragePermissionCheck,
|
||||
nsIContentPermissionRequest)
|
||||
|
||||
DeviceStoragePermissionCheck(DeviceStorageRequest* aRequest,
|
||||
uint64_t aWindowID,
|
||||
const PrincipalInfo &aPrincipalInfo)
|
||||
: mRequest(aRequest)
|
||||
DeviceStoragePermissionCheck(
|
||||
already_AddRefed<DeviceStorageRequest>&& aRequest,
|
||||
uint64_t aWindowID, const PrincipalInfo &aPrincipalInfo)
|
||||
: mRequest(Move(aRequest))
|
||||
, mWindowID(aWindowID)
|
||||
, mPrincipalInfo(aPrincipalInfo)
|
||||
{
|
||||
@@ -2461,37 +2554,31 @@ nsDOMDeviceStorage::nsDOMDeviceStorage(nsPIDOMWindow* aWindow)
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMDeviceStorage::CheckPermission(DeviceStorageRequest* aRequest)
|
||||
nsDOMDeviceStorage::CheckPermission(
|
||||
already_AddRefed<DeviceStorageRequest>&& aRequest)
|
||||
{
|
||||
MOZ_ASSERT(mManager);
|
||||
uint32_t cache = mManager->CheckPermission(aRequest->GetAccess());
|
||||
RefPtr<DeviceStorageRequest> request(aRequest);
|
||||
uint32_t cache = mManager->CheckPermission(request->GetAccess());
|
||||
switch (cache) {
|
||||
case nsIPermissionManager::ALLOW_ACTION:
|
||||
return aRequest->Allow();
|
||||
return request->Allow();
|
||||
case nsIPermissionManager::DENY_ACTION:
|
||||
return aRequest->Cancel();
|
||||
return request->Cancel();
|
||||
case nsIPermissionManager::PROMPT_ACTION:
|
||||
default:
|
||||
{
|
||||
nsCOMPtr<nsIThread> mainThread;
|
||||
nsresult rv = NS_GetMainThread(getter_AddRefs(mainThread));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return aRequest->Reject(POST_ERROR_EVENT_UNKNOWN);
|
||||
return request->Reject(POST_ERROR_EVENT_UNKNOWN);
|
||||
}
|
||||
|
||||
/* We need to do a bit of a song and dance here to release the object
|
||||
because while we can initially increment the ownership count (no one
|
||||
else is using it), we cannot safely decrement after dispatching because
|
||||
it uses cycle collection and requires the main thread to free it. */
|
||||
nsCOMPtr<nsIRunnable> r
|
||||
= new DeviceStoragePermissionCheck(aRequest, mInnerWindowID,
|
||||
*mPrincipalInfo);
|
||||
rv = mainThread->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
rv = aRequest->Reject(POST_ERROR_EVENT_UNKNOWN);
|
||||
}
|
||||
NS_ProxyRelease(mainThread, r.forget().take());
|
||||
return rv;
|
||||
return mainThread->Dispatch(
|
||||
MakeAndAddRef<DeviceStoragePermissionCheck>(request.forget(),
|
||||
mInnerWindowID,
|
||||
*mPrincipalInfo),
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2505,9 +2592,10 @@ nsDOMDeviceStorage::IsOwningThread()
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMDeviceStorage::DispatchToOwningThread(nsIRunnable* aRunnable)
|
||||
nsDOMDeviceStorage::DispatchToOwningThread(
|
||||
already_AddRefed<nsIRunnable>&& aRunnable)
|
||||
{
|
||||
return mOwningThread->Dispatch(aRunnable, NS_DISPATCH_NORMAL);
|
||||
return mOwningThread->Dispatch(Move(aRunnable), NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
/* virtual */ JSObject*
|
||||
@@ -2910,45 +2998,18 @@ nsDOMDeviceStorage::IsAvailable()
|
||||
already_AddRefed<DOMRequest>
|
||||
nsDOMDeviceStorage::Add(Blob* aBlob, ErrorResult& aRv)
|
||||
{
|
||||
if (!aBlob) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIMIMEService> mimeSvc = do_GetService(NS_MIMESERVICE_CONTRACTID);
|
||||
if (!mimeSvc) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// if mimeType isn't set, we will not get a correct
|
||||
// extension, and AddNamed() will fail. This will post an
|
||||
// onerror to the requestee.
|
||||
nsString mimeType;
|
||||
aBlob->GetType(mimeType);
|
||||
|
||||
nsCString extension;
|
||||
mimeSvc->GetPrimaryExtension(NS_LossyConvertUTF16toASCII(mimeType),
|
||||
EmptyCString(), extension);
|
||||
// if extension is null here, we will ignore it for now.
|
||||
// AddNamed() will check the file path and fail. This
|
||||
// will post an onerror to the requestee.
|
||||
|
||||
// possible race here w/ unique filename
|
||||
char buffer[32];
|
||||
NS_MakeRandomString(buffer, ArrayLength(buffer) - 1);
|
||||
|
||||
nsAutoCString path;
|
||||
path.Assign(nsDependentCString(buffer));
|
||||
path.Append('.');
|
||||
path.Append(extension);
|
||||
|
||||
return AddNamed(aBlob, NS_ConvertASCIItoUTF16(path), aRv);
|
||||
nsString path;
|
||||
return AddOrAppendNamed(aBlob, path, true, aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<DOMRequest>
|
||||
nsDOMDeviceStorage::AddNamed(Blob* aBlob, const nsAString& aPath,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (aPath.IsEmpty()) {
|
||||
aRv.Throw(NS_ERROR_ILLEGAL_VALUE);
|
||||
return nullptr;
|
||||
}
|
||||
return AddOrAppendNamed(aBlob, aPath, true, aRv);
|
||||
}
|
||||
|
||||
@@ -2956,6 +3017,10 @@ already_AddRefed<DOMRequest>
|
||||
nsDOMDeviceStorage::AppendNamed(Blob* aBlob, const nsAString& aPath,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (aPath.IsEmpty()) {
|
||||
aRv.Throw(NS_ERROR_ILLEGAL_VALUE);
|
||||
return nullptr;
|
||||
}
|
||||
return AddOrAppendNamed(aBlob, aPath, false, aRv);
|
||||
}
|
||||
|
||||
@@ -3001,19 +3066,13 @@ nsDOMDeviceStorage::AddOrAppendNamed(Blob* aBlob, const nsAString& aPath,
|
||||
bool aCreate, ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(IsOwningThread());
|
||||
MOZ_ASSERT(aCreate || !aPath.IsEmpty());
|
||||
|
||||
// if the blob is null here, bail
|
||||
if (!aBlob) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DeviceStorageTypeChecker* typeChecker
|
||||
= DeviceStorageTypeChecker::CreateOrGet();
|
||||
if (!typeChecker) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> r;
|
||||
|
||||
if (IsFullPath(aPath)) {
|
||||
@@ -3032,25 +3091,25 @@ nsDOMDeviceStorage::AddOrAppendNamed(Blob* aBlob, const nsAString& aPath,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mStorageType,
|
||||
mStorageName,
|
||||
aPath);
|
||||
if (!dsf->IsSafePath()) {
|
||||
aRv = mManager->Reject(id, POST_ERROR_EVENT_PERMISSION_DENIED);
|
||||
} else if (!typeChecker->Check(mStorageType, dsf->mFile) ||
|
||||
!typeChecker->Check(mStorageType, aBlob->Impl())) {
|
||||
aRv = mManager->Reject(id, POST_ERROR_EVENT_ILLEGAL_TYPE);
|
||||
RefPtr<DeviceStorageFile> dsf;
|
||||
if (aPath.IsEmpty()) {
|
||||
dsf = new DeviceStorageFile(mStorageType, mStorageName);
|
||||
} else {
|
||||
RefPtr<DeviceStorageRequest> request;
|
||||
if (aCreate) {
|
||||
request = new DeviceStorageCreateRequest();
|
||||
} else {
|
||||
request = new DeviceStorageAppendRequest();
|
||||
dsf = new DeviceStorageFile(mStorageType, mStorageName, aPath);
|
||||
if (!dsf->IsSafePath()) {
|
||||
aRv = mManager->Reject(id, POST_ERROR_EVENT_PERMISSION_DENIED);
|
||||
return domRequest.forget();
|
||||
}
|
||||
request->Initialize(mManager, dsf, id, aBlob->Impl());
|
||||
aRv = CheckPermission(request);
|
||||
}
|
||||
|
||||
RefPtr<DeviceStorageRequest> request;
|
||||
if (aCreate) {
|
||||
request = new DeviceStorageCreateRequest();
|
||||
} else {
|
||||
request = new DeviceStorageAppendRequest();
|
||||
}
|
||||
request->Initialize(mManager, dsf.forget(), id, aBlob->Impl());
|
||||
aRv = CheckPermission(request.forget());
|
||||
return domRequest.forget();
|
||||
}
|
||||
|
||||
@@ -3084,9 +3143,9 @@ nsDOMDeviceStorage::GetInternal(const nsAString& aPath, bool aEditable,
|
||||
}
|
||||
|
||||
RefPtr<DeviceStorageRequest> request = new DeviceStorageOpenRequest();
|
||||
request->Initialize(mManager, dsf, id);
|
||||
request->Initialize(mManager, dsf.forget(), id);
|
||||
|
||||
aRv = CheckPermission(request);
|
||||
aRv = CheckPermission(request.forget());
|
||||
return domRequest.forget();
|
||||
}
|
||||
|
||||
@@ -3118,9 +3177,9 @@ nsDOMDeviceStorage::Delete(const nsAString& aPath, ErrorResult& aRv)
|
||||
}
|
||||
|
||||
RefPtr<DeviceStorageRequest> request = new DeviceStorageDeleteRequest();
|
||||
request->Initialize(mManager, dsf, id);
|
||||
request->Initialize(mManager, dsf.forget(), id);
|
||||
|
||||
aRv = CheckPermission(request);
|
||||
aRv = CheckPermission(request.forget());
|
||||
return domRequest.forget();
|
||||
}
|
||||
|
||||
@@ -3139,9 +3198,9 @@ nsDOMDeviceStorage::FreeSpace(ErrorResult& aRv)
|
||||
}
|
||||
|
||||
RefPtr<DeviceStorageRequest> request = new DeviceStorageFreeSpaceRequest();
|
||||
request->Initialize(mManager, dsf, id);
|
||||
request->Initialize(mManager, dsf.forget(), id);
|
||||
|
||||
aRv = CheckPermission(request);
|
||||
aRv = CheckPermission(request.forget());
|
||||
return domRequest.forget();
|
||||
}
|
||||
|
||||
@@ -3164,9 +3223,9 @@ nsDOMDeviceStorage::UsedSpace(ErrorResult& aRv)
|
||||
}
|
||||
|
||||
RefPtr<DeviceStorageRequest> request = new DeviceStorageUsedSpaceRequest();
|
||||
request->Initialize(mManager, dsf, id);
|
||||
request->Initialize(mManager, dsf.forget(), id);
|
||||
|
||||
aRv = CheckPermission(request);
|
||||
aRv = CheckPermission(request.forget());
|
||||
return domRequest.forget();
|
||||
}
|
||||
|
||||
@@ -3185,9 +3244,9 @@ nsDOMDeviceStorage::Available(ErrorResult& aRv)
|
||||
}
|
||||
|
||||
RefPtr<DeviceStorageRequest> request = new DeviceStorageAvailableRequest();
|
||||
request->Initialize(mManager, dsf, id);
|
||||
request->Initialize(mManager, dsf.forget(), id);
|
||||
|
||||
aRv = CheckPermission(request);
|
||||
aRv = CheckPermission(request.forget());
|
||||
return domRequest.forget();
|
||||
}
|
||||
|
||||
@@ -3206,9 +3265,9 @@ nsDOMDeviceStorage::StorageStatus(ErrorResult& aRv)
|
||||
}
|
||||
|
||||
RefPtr<DeviceStorageRequest> request = new DeviceStorageStatusRequest();
|
||||
request->Initialize(mManager, dsf, id);
|
||||
request->Initialize(mManager, dsf.forget(), id);
|
||||
|
||||
aRv = CheckPermission(request);
|
||||
aRv = CheckPermission(request.forget());
|
||||
return domRequest.forget();
|
||||
}
|
||||
|
||||
@@ -3227,9 +3286,9 @@ nsDOMDeviceStorage::Format(ErrorResult& aRv)
|
||||
}
|
||||
|
||||
RefPtr<DeviceStorageRequest> request = new DeviceStorageFormatRequest();
|
||||
request->Initialize(mManager, dsf, id);
|
||||
request->Initialize(mManager, dsf.forget(), id);
|
||||
|
||||
aRv = CheckPermission(request);
|
||||
aRv = CheckPermission(request.forget());
|
||||
return domRequest.forget();
|
||||
}
|
||||
|
||||
@@ -3248,9 +3307,9 @@ nsDOMDeviceStorage::Mount(ErrorResult& aRv)
|
||||
}
|
||||
|
||||
RefPtr<DeviceStorageRequest> request = new DeviceStorageMountRequest();
|
||||
request->Initialize(mManager, dsf, id);
|
||||
request->Initialize(mManager, dsf.forget(), id);
|
||||
|
||||
aRv = CheckPermission(request);
|
||||
aRv = CheckPermission(request.forget());
|
||||
return domRequest.forget();
|
||||
}
|
||||
|
||||
@@ -3270,9 +3329,9 @@ nsDOMDeviceStorage::Unmount(ErrorResult& aRv)
|
||||
|
||||
|
||||
RefPtr<DeviceStorageRequest> request = new DeviceStorageUnmountRequest();
|
||||
request->Initialize(mManager, dsf, id);
|
||||
request->Initialize(mManager, dsf.forget(), id);
|
||||
|
||||
aRv = CheckPermission(request);
|
||||
aRv = CheckPermission(request.forget());
|
||||
return domRequest.forget();
|
||||
}
|
||||
|
||||
@@ -3318,9 +3377,9 @@ nsDOMDeviceStorage::CreateFileDescriptor(const nsAString& aPath,
|
||||
}
|
||||
|
||||
RefPtr<DeviceStorageRequest> request = new DeviceStorageCreateFdRequest();
|
||||
request->Initialize(mManager, dsf, id, aDSFileDescriptor);
|
||||
request->Initialize(mManager, dsf.forget(), id, aDSFileDescriptor);
|
||||
|
||||
aRv = CheckPermission(request);
|
||||
aRv = CheckPermission(request.forget());
|
||||
return domRequest.forget();
|
||||
}
|
||||
|
||||
@@ -3425,8 +3484,8 @@ nsDOMDeviceStorage::EnumerateInternal(const nsAString& aPath,
|
||||
if (!dsf->IsSafePath()) {
|
||||
aRv = mManager->Reject(id, POST_ERROR_EVENT_PERMISSION_DENIED);
|
||||
} else {
|
||||
request->Initialize(mManager, dsf, id, since);
|
||||
aRv = CheckPermission(request);
|
||||
request->Initialize(mManager, dsf.forget(), id, since);
|
||||
aRv = CheckPermission(request.forget());
|
||||
}
|
||||
|
||||
return cursor.forget();
|
||||
@@ -3628,8 +3687,8 @@ nsDOMDeviceStorage::EventListenerWasAdded(const nsAString& aType,
|
||||
RefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mStorageType,
|
||||
mStorageName);
|
||||
RefPtr<DeviceStorageRequest> request = new DeviceStorageWatchRequest();
|
||||
request->Initialize(mManager, dsf, id);
|
||||
aRv = CheckPermission(request);
|
||||
request->Initialize(mManager, dsf.forget(), id);
|
||||
aRv = CheckPermission(request.forget());
|
||||
}
|
||||
|
||||
Atomic<uint32_t> DeviceStorageRequestManager::sLastRequestId(0);
|
||||
@@ -3655,8 +3714,7 @@ DeviceStorageRequestManager::~DeviceStorageRequestManager()
|
||||
while (i > 0) {
|
||||
--i;
|
||||
DS_LOG_ERROR("terminate %u", mPending[i].mId);
|
||||
NS_ProxyRelease(mOwningThread,
|
||||
NS_ISUPPORTS_CAST(EventTarget*, mPending[i].mRequest.forget().take()));
|
||||
NS_ProxyRelease(mOwningThread, mPending[i].mRequest.forget());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3693,14 +3751,15 @@ DeviceStorageRequestManager::IsOwningThread()
|
||||
}
|
||||
|
||||
nsresult
|
||||
DeviceStorageRequestManager::DispatchToOwningThread(nsIRunnable* aRunnable)
|
||||
DeviceStorageRequestManager::DispatchToOwningThread(
|
||||
already_AddRefed<nsIRunnable>&& aRunnable)
|
||||
{
|
||||
return mOwningThread->Dispatch(aRunnable, NS_DISPATCH_NORMAL);
|
||||
return mOwningThread->Dispatch(Move(aRunnable), NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
nsresult
|
||||
DeviceStorageRequestManager::DispatchOrAbandon(uint32_t aId,
|
||||
nsIRunnable* aRunnable)
|
||||
DeviceStorageRequestManager::DispatchOrAbandon(
|
||||
uint32_t aId, already_AddRefed<nsIRunnable>&& aRunnable)
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
if (mShutdown) {
|
||||
@@ -3709,10 +3768,11 @@ DeviceStorageRequestManager::DispatchOrAbandon(uint32_t aId,
|
||||
safe to be freed off the owner thread but the dispatch method
|
||||
does not know that. */
|
||||
DS_LOG_DEBUG("shutdown %u", aId);
|
||||
nsCOMPtr<nsIRunnable> runnable(aRunnable);
|
||||
return NS_ERROR_ILLEGAL_DURING_SHUTDOWN;
|
||||
}
|
||||
|
||||
nsresult rv = DispatchToOwningThread(aRunnable);
|
||||
nsresult rv = DispatchToOwningThread(Move(aRunnable));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
DS_LOG_ERROR("abandon %u", aId);
|
||||
}
|
||||
@@ -3779,7 +3839,7 @@ DeviceStorageRequestManager::Resolve(uint32_t aId, bool aForceDispatch)
|
||||
{
|
||||
self->Resolve(aId, false);
|
||||
});
|
||||
return DispatchOrAbandon(aId, r);
|
||||
return DispatchOrAbandon(aId, r.forget());
|
||||
}
|
||||
|
||||
DS_LOG_INFO("posted %u", aId);
|
||||
@@ -3811,7 +3871,7 @@ DeviceStorageRequestManager::Resolve(uint32_t aId, const nsString& aResult,
|
||||
{
|
||||
self->Resolve(aId, result, false);
|
||||
});
|
||||
return DispatchOrAbandon(aId, r);
|
||||
return DispatchOrAbandon(aId, r.forget());
|
||||
}
|
||||
|
||||
DS_LOG_INFO("posted %u w/ %s", aId,
|
||||
@@ -3856,7 +3916,7 @@ DeviceStorageRequestManager::Resolve(uint32_t aId, uint64_t aValue,
|
||||
{
|
||||
self->Resolve(aId, aValue, false);
|
||||
});
|
||||
return DispatchOrAbandon(aId, r);
|
||||
return DispatchOrAbandon(aId, r.forget());
|
||||
}
|
||||
|
||||
DS_LOG_INFO("posted %u w/ %" PRIu64, aId, aValue);
|
||||
@@ -3936,7 +3996,7 @@ DeviceStorageRequestManager::Resolve(uint32_t aId, BlobImpl* aBlobImpl,
|
||||
{
|
||||
self->Resolve(aId, blobImpl, false);
|
||||
});
|
||||
return DispatchOrAbandon(aId, r);
|
||||
return DispatchOrAbandon(aId, r.forget());
|
||||
}
|
||||
|
||||
DS_LOG_INFO("posted %u w/ %p", aId, aBlobImpl);
|
||||
@@ -4064,7 +4124,7 @@ DeviceStorageRequestManager::Reject(uint32_t aId, const nsString& aReason)
|
||||
|
||||
self->RejectInternal(i, reason);
|
||||
});
|
||||
return DispatchOrAbandon(aId, r);
|
||||
return DispatchOrAbandon(aId, r.forget());
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
||||
@@ -130,16 +130,16 @@ public:
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mIOThread);
|
||||
|
||||
RefPtr<InvalidateRunnable> r = new InvalidateRunnable(this, aStorageName);
|
||||
mIOThread->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
mIOThread->Dispatch(new InvalidateRunnable(this, aStorageName),
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
void Dispatch(nsIRunnable* aRunnable)
|
||||
void Dispatch(already_AddRefed<nsIRunnable>&& aRunnable)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mIOThread);
|
||||
|
||||
mIOThread->Dispatch(aRunnable, NS_DISPATCH_NORMAL);
|
||||
mIOThread->Dispatch(mozilla::Move(aRunnable), NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
nsresult AccumUsedSizes(const nsAString& aStorageName,
|
||||
@@ -245,7 +245,7 @@ public:
|
||||
DeviceStorageRequestManager();
|
||||
|
||||
bool IsOwningThread();
|
||||
nsresult DispatchToOwningThread(nsIRunnable* aRunnable);
|
||||
nsresult DispatchToOwningThread(already_AddRefed<nsIRunnable>&& aRunnable);
|
||||
|
||||
void StorePermission(size_t aAccess, bool aAllow);
|
||||
uint32_t CheckPermission(size_t aAccess);
|
||||
@@ -290,7 +290,8 @@ private:
|
||||
uint32_t CreateInternal(mozilla::dom::DOMRequest* aRequest, bool aCursor);
|
||||
nsresult ResolveInternal(ListIndex aIndex, JS::HandleValue aResult);
|
||||
nsresult RejectInternal(ListIndex aIndex, const nsString& aReason);
|
||||
nsresult DispatchOrAbandon(uint32_t aId, nsIRunnable* aRunnable);
|
||||
nsresult DispatchOrAbandon(uint32_t aId,
|
||||
already_AddRefed<nsIRunnable>&& aRunnable);
|
||||
ListType::index_type Find(uint32_t aId);
|
||||
|
||||
nsCOMPtr<nsIThread> mOwningThread;
|
||||
@@ -311,16 +312,16 @@ protected:
|
||||
|
||||
public:
|
||||
virtual void Initialize(DeviceStorageRequestManager* aManager,
|
||||
DeviceStorageFile* aFile,
|
||||
already_AddRefed<DeviceStorageFile>&& aFile,
|
||||
uint32_t aRequest);
|
||||
|
||||
virtual void Initialize(DeviceStorageRequestManager* aManager,
|
||||
DeviceStorageFile* aFile,
|
||||
already_AddRefed<DeviceStorageFile>&& aFile,
|
||||
uint32_t aRequest,
|
||||
mozilla::dom::BlobImpl* aBlob);
|
||||
|
||||
virtual void Initialize(DeviceStorageRequestManager* aManager,
|
||||
DeviceStorageFile* aFile,
|
||||
already_AddRefed<DeviceStorageFile>&& aFile,
|
||||
uint32_t aRequest,
|
||||
DeviceStorageFileDescriptor* aDSFileDescriptor);
|
||||
|
||||
@@ -378,7 +379,7 @@ protected:
|
||||
}
|
||||
|
||||
virtual ~DeviceStorageRequest();
|
||||
virtual void Prepare();
|
||||
virtual nsresult Prepare();
|
||||
virtual nsresult CreateSendParams(mozilla::dom::DeviceStorageParams& aParams);
|
||||
nsresult AllowInternal();
|
||||
nsresult SendToParentProcess();
|
||||
@@ -390,6 +391,7 @@ protected:
|
||||
RefPtr<DeviceStorageFileDescriptor> mDSFileDescriptor;
|
||||
DeviceStorageAccessType mAccess;
|
||||
bool mSendToParent;
|
||||
bool mUseMainThread;
|
||||
bool mUseStreamTransport;
|
||||
bool mCheckFile;
|
||||
bool mCheckBlob;
|
||||
@@ -410,7 +412,7 @@ public:
|
||||
using DeviceStorageRequest::Initialize;
|
||||
|
||||
virtual void Initialize(DeviceStorageRequestManager* aManager,
|
||||
DeviceStorageFile* aFile,
|
||||
already_AddRefed<DeviceStorageFile>&& aFile,
|
||||
uint32_t aRequest,
|
||||
PRTime aSince);
|
||||
|
||||
|
||||
@@ -1128,7 +1128,7 @@ Event::TimeStamp() const
|
||||
MOZ_ASSERT(workerPrivate);
|
||||
|
||||
TimeDuration duration =
|
||||
mEvent->timeStamp - workerPrivate->CreationTimeStamp();
|
||||
mEvent->timeStamp - workerPrivate->NowBaseTimeStamp();
|
||||
return duration.ToMilliseconds();
|
||||
}
|
||||
|
||||
|
||||
@@ -74,9 +74,8 @@ function testWorkerEvents() {
|
||||
var worker = new Worker(window.URL.createObjectURL(blob));
|
||||
worker.onmessage = function(evt) {
|
||||
var timeAfterEvent = window.performance.now();
|
||||
var time = window.performance.translateTime(evt.data, worker);
|
||||
ok(time >= timeBeforeEvent &&
|
||||
time <= timeAfterEvent,
|
||||
ok(evt.data > timeBeforeEvent &&
|
||||
evt.data < timeAfterEvent,
|
||||
"Event timestamp in dedicated worker (" + evt.data +
|
||||
") is in expected range: (" +
|
||||
timeBeforeEvent + ", " + timeAfterEvent + ")");
|
||||
|
||||
@@ -324,5 +324,50 @@ InternalRequest::MapChannelToRequestMode(nsIChannel* aChannel)
|
||||
return static_cast<RequestMode>(corsMode);
|
||||
}
|
||||
|
||||
// static
|
||||
RequestCredentials
|
||||
InternalRequest::MapChannelToRequestCredentials(nsIChannel* aChannel)
|
||||
{
|
||||
MOZ_ASSERT(aChannel);
|
||||
|
||||
nsCOMPtr<nsILoadInfo> loadInfo;
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(aChannel->GetLoadInfo(getter_AddRefs(loadInfo))));
|
||||
|
||||
uint32_t securityMode;
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(loadInfo->GetSecurityMode(&securityMode)));
|
||||
|
||||
// TODO: Remove following code after stylesheet and image support cookie policy
|
||||
if (securityMode == nsILoadInfo::SEC_NORMAL) {
|
||||
uint32_t loadFlags;
|
||||
aChannel->GetLoadFlags(&loadFlags);
|
||||
|
||||
if (loadFlags & nsIRequest::LOAD_ANONYMOUS) {
|
||||
return RequestCredentials::Omit;
|
||||
} else {
|
||||
bool includeCrossOrigin;
|
||||
nsCOMPtr<nsIHttpChannelInternal> internalChannel = do_QueryInterface(aChannel);
|
||||
|
||||
internalChannel->GetCorsIncludeCredentials(&includeCrossOrigin);
|
||||
if (includeCrossOrigin) {
|
||||
return RequestCredentials::Include;
|
||||
}
|
||||
}
|
||||
return RequestCredentials::Same_origin;
|
||||
}
|
||||
|
||||
uint32_t cookiePolicy = loadInfo->GetCookiePolicy();
|
||||
|
||||
if (cookiePolicy == nsILoadInfo::SEC_COOKIES_INCLUDE) {
|
||||
return RequestCredentials::Include;
|
||||
} else if (cookiePolicy == nsILoadInfo::SEC_COOKIES_OMIT) {
|
||||
return RequestCredentials::Omit;
|
||||
} else if (cookiePolicy == nsILoadInfo::SEC_COOKIES_SAME_ORIGIN) {
|
||||
return RequestCredentials::Same_origin;
|
||||
}
|
||||
|
||||
MOZ_ASSERT_UNREACHABLE("Unexpected cookie policy!");
|
||||
return RequestCredentials::Same_origin;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -376,6 +376,9 @@ public:
|
||||
static RequestMode
|
||||
MapChannelToRequestMode(nsIChannel* aChannel);
|
||||
|
||||
static RequestCredentials
|
||||
MapChannelToRequestCredentials(nsIChannel* aChannel);
|
||||
|
||||
private:
|
||||
// Does not copy mBodyStream. Use fallible Clone() for complete copy.
|
||||
explicit InternalRequest(const InternalRequest& aOther);
|
||||
|
||||
@@ -36,7 +36,6 @@ class BackgroundChildImpl;
|
||||
} // namespace ipc
|
||||
|
||||
namespace dom {
|
||||
namespace indexedDB {
|
||||
|
||||
class IDBCursor;
|
||||
class IDBDatabase;
|
||||
@@ -44,6 +43,9 @@ class IDBFactory;
|
||||
class IDBMutableFile;
|
||||
class IDBOpenDBRequest;
|
||||
class IDBRequest;
|
||||
|
||||
namespace indexedDB {
|
||||
|
||||
class Key;
|
||||
class PermissionRequestChild;
|
||||
class PermissionRequestParent;
|
||||
@@ -52,7 +54,7 @@ class SerializedStructuredCloneReadInfo;
|
||||
class ThreadLocal
|
||||
{
|
||||
friend class nsAutoPtr<ThreadLocal>;
|
||||
friend class IDBFactory;
|
||||
friend IDBFactory;
|
||||
|
||||
LoggingInfo mLoggingInfo;
|
||||
IDBTransaction* mCurrentTransaction;
|
||||
@@ -147,7 +149,7 @@ class BackgroundFactoryChild final
|
||||
: public PBackgroundIDBFactoryChild
|
||||
{
|
||||
friend class mozilla::ipc::BackgroundChildImpl;
|
||||
friend class IDBFactory;
|
||||
friend IDBFactory;
|
||||
|
||||
IDBFactory* mFactory;
|
||||
|
||||
@@ -240,7 +242,7 @@ class BackgroundFactoryRequestChild final
|
||||
{
|
||||
typedef mozilla::dom::quota::PersistenceType PersistenceType;
|
||||
|
||||
friend class IDBFactory;
|
||||
friend IDBFactory;
|
||||
friend class BackgroundFactoryChild;
|
||||
friend class BackgroundDatabaseChild;
|
||||
friend class PermissionRequestChild;
|
||||
@@ -292,7 +294,7 @@ class BackgroundDatabaseChild final
|
||||
{
|
||||
friend class BackgroundFactoryChild;
|
||||
friend class BackgroundFactoryRequestChild;
|
||||
friend class IDBDatabase;
|
||||
friend IDBDatabase;
|
||||
|
||||
nsAutoPtr<DatabaseSpec> mSpec;
|
||||
RefPtr<IDBDatabase> mTemporaryStrongDatabase;
|
||||
@@ -424,7 +426,7 @@ class BackgroundDatabaseRequestChild final
|
||||
, public PBackgroundIDBDatabaseRequestChild
|
||||
{
|
||||
friend class BackgroundDatabaseChild;
|
||||
friend class IDBDatabase;
|
||||
friend IDBDatabase;
|
||||
|
||||
RefPtr<IDBDatabase> mDatabase;
|
||||
|
||||
@@ -504,7 +506,7 @@ class BackgroundTransactionChild final
|
||||
, public PBackgroundIDBTransactionChild
|
||||
{
|
||||
friend class BackgroundDatabaseChild;
|
||||
friend class IDBDatabase;
|
||||
friend IDBDatabase;
|
||||
|
||||
public:
|
||||
#ifdef DEBUG
|
||||
@@ -631,7 +633,7 @@ class BackgroundRequestChild final
|
||||
{
|
||||
friend class BackgroundTransactionChild;
|
||||
friend class BackgroundVersionChangeTransactionChild;
|
||||
friend class IDBTransaction;
|
||||
friend IDBTransaction;
|
||||
|
||||
RefPtr<IDBTransaction> mTransaction;
|
||||
|
||||
|
||||
@@ -29,10 +29,11 @@ NS_DEFINE_STATIC_IID_ACCESSOR(PIBlobImplSnapshot, FILEIMPLSNAPSHOT_IID)
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace indexedDB {
|
||||
|
||||
class IDBFileHandle;
|
||||
|
||||
namespace indexedDB {
|
||||
|
||||
class BlobImplSnapshot final
|
||||
: public BlobImpl
|
||||
, public PIBlobImplSnapshot
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace indexedDB {
|
||||
|
||||
using namespace indexedDB;
|
||||
|
||||
IDBCursor::IDBCursor(Type aType,
|
||||
BackgroundCursorChild* aBackgroundActor,
|
||||
@@ -896,6 +897,5 @@ IDBCursor::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
+17
-15
@@ -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/. */
|
||||
|
||||
#ifndef mozilla_dom_indexeddb_idbcursor_h__
|
||||
#define mozilla_dom_indexeddb_idbcursor_h__
|
||||
#ifndef mozilla_dom_idbcursor_h__
|
||||
#define mozilla_dom_idbcursor_h__
|
||||
|
||||
#include "IndexedDatabase.h"
|
||||
#include "js/RootingAPI.h"
|
||||
@@ -24,21 +24,24 @@ class ErrorResult;
|
||||
|
||||
namespace dom {
|
||||
|
||||
class OwningIDBObjectStoreOrIDBIndex;
|
||||
|
||||
namespace indexedDB {
|
||||
|
||||
class BackgroundCursorChild;
|
||||
class IDBIndex;
|
||||
class IDBObjectStore;
|
||||
class IDBRequest;
|
||||
class IDBTransaction;
|
||||
class OwningIDBObjectStoreOrIDBIndex;
|
||||
|
||||
namespace indexedDB {
|
||||
class BackgroundCursorChild;
|
||||
}
|
||||
|
||||
class IDBCursor final
|
||||
: public nsISupports
|
||||
, public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
typedef indexedDB::Key Key;
|
||||
typedef indexedDB::StructuredCloneReadInfo StructuredCloneReadInfo;
|
||||
|
||||
enum Direction
|
||||
{
|
||||
NEXT = 0,
|
||||
@@ -59,7 +62,7 @@ private:
|
||||
Type_IndexKey,
|
||||
};
|
||||
|
||||
BackgroundCursorChild* mBackgroundActor;
|
||||
indexedDB::BackgroundCursorChild* mBackgroundActor;
|
||||
|
||||
RefPtr<IDBRequest> mRequest;
|
||||
RefPtr<IDBObjectStore> mSourceObjectStore;
|
||||
@@ -92,23 +95,23 @@ private:
|
||||
|
||||
public:
|
||||
static already_AddRefed<IDBCursor>
|
||||
Create(BackgroundCursorChild* aBackgroundActor,
|
||||
Create(indexedDB::BackgroundCursorChild* aBackgroundActor,
|
||||
const Key& aKey,
|
||||
StructuredCloneReadInfo&& aCloneInfo);
|
||||
|
||||
static already_AddRefed<IDBCursor>
|
||||
Create(BackgroundCursorChild* aBackgroundActor,
|
||||
Create(indexedDB::BackgroundCursorChild* aBackgroundActor,
|
||||
const Key& aKey);
|
||||
|
||||
static already_AddRefed<IDBCursor>
|
||||
Create(BackgroundCursorChild* aBackgroundActor,
|
||||
Create(indexedDB::BackgroundCursorChild* aBackgroundActor,
|
||||
const Key& aKey,
|
||||
const Key& aSortKey,
|
||||
const Key& aPrimaryKey,
|
||||
StructuredCloneReadInfo&& aCloneInfo);
|
||||
|
||||
static already_AddRefed<IDBCursor>
|
||||
Create(BackgroundCursorChild* aBackgroundActor,
|
||||
Create(indexedDB::BackgroundCursorChild* aBackgroundActor,
|
||||
const Key& aKey,
|
||||
const Key& aSortKey,
|
||||
const Key& aPrimaryKey);
|
||||
@@ -194,7 +197,7 @@ public:
|
||||
|
||||
private:
|
||||
IDBCursor(Type aType,
|
||||
BackgroundCursorChild* aBackgroundActor,
|
||||
indexedDB::BackgroundCursorChild* aBackgroundActor,
|
||||
const Key& aKey);
|
||||
|
||||
~IDBCursor();
|
||||
@@ -212,8 +215,7 @@ private:
|
||||
IsSourceDeleted() const;
|
||||
};
|
||||
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_indexeddb_idbcursor_h__
|
||||
#endif // mozilla_dom_idbcursor_h__
|
||||
|
||||
@@ -56,7 +56,6 @@
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace indexedDB {
|
||||
|
||||
using namespace mozilla::dom::quota;
|
||||
using namespace mozilla::ipc;
|
||||
@@ -469,7 +468,6 @@ IDBDatabase::CreateObjectStore(
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
IDBTransaction* transaction = IDBTransaction::GetCurrent();
|
||||
|
||||
if (!transaction ||
|
||||
transaction->Database() != this ||
|
||||
transaction->GetMode() != IDBTransaction::VERSION_CHANGE) {
|
||||
@@ -477,7 +475,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))) {
|
||||
@@ -545,7 +546,6 @@ IDBDatabase::DeleteObjectStore(const nsAString& aName, ErrorResult& aRv)
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
IDBTransaction* transaction = IDBTransaction::GetCurrent();
|
||||
|
||||
if (!transaction ||
|
||||
transaction->Database() != this ||
|
||||
transaction->GetMode() != IDBTransaction::VERSION_CHANGE) {
|
||||
@@ -553,7 +553,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();
|
||||
|
||||
@@ -1482,6 +1485,5 @@ Observer::Observe(nsISupports* aSubject,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
+18
-18
@@ -4,13 +4,13 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_indexeddb_idbdatabase_h__
|
||||
#define mozilla_dom_indexeddb_idbdatabase_h__
|
||||
#ifndef mozilla_dom_idbdatabase_h__
|
||||
#define mozilla_dom_idbdatabase_h__
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/dom/IDBTransactionBinding.h"
|
||||
#include "mozilla/dom/StorageTypeBinding.h"
|
||||
#include "mozilla/dom/indexedDB/IDBWrapperCache.h"
|
||||
#include "mozilla/dom/IDBWrapperCache.h"
|
||||
#include "mozilla/dom/quota/PersistenceType.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsDataHashtable.h"
|
||||
@@ -30,25 +30,26 @@ namespace dom {
|
||||
|
||||
class Blob;
|
||||
class DOMStringList;
|
||||
class IDBFactory;
|
||||
class IDBMutableFile;
|
||||
class IDBObjectStore;
|
||||
struct IDBObjectStoreParameters;
|
||||
class IDBOpenDBRequest;
|
||||
class IDBRequest;
|
||||
class IDBTransaction;
|
||||
template <class> class Optional;
|
||||
class StringOrStringSequence;
|
||||
|
||||
namespace indexedDB {
|
||||
|
||||
class BackgroundDatabaseChild;
|
||||
class DatabaseSpec;
|
||||
class IDBFactory;
|
||||
class IDBMutableFile;
|
||||
class IDBObjectStore;
|
||||
class IDBOpenDBRequest;
|
||||
class IDBRequest;
|
||||
class IDBTransaction;
|
||||
class PBackgroundIDBDatabaseFileChild;
|
||||
}
|
||||
|
||||
class IDBDatabase final
|
||||
: public IDBWrapperCache
|
||||
{
|
||||
typedef mozilla::dom::indexedDB::DatabaseSpec DatabaseSpec;
|
||||
typedef mozilla::dom::StorageType StorageType;
|
||||
typedef mozilla::dom::quota::PersistenceType PersistenceType;
|
||||
|
||||
@@ -68,11 +69,11 @@ class IDBDatabase final
|
||||
// Normally null except during a versionchange transaction.
|
||||
nsAutoPtr<DatabaseSpec> mPreviousSpec;
|
||||
|
||||
BackgroundDatabaseChild* mBackgroundActor;
|
||||
indexedDB::BackgroundDatabaseChild* mBackgroundActor;
|
||||
|
||||
nsTHashtable<nsPtrHashKey<IDBTransaction>> mTransactions;
|
||||
|
||||
nsDataHashtable<nsISupportsHashKey, PBackgroundIDBDatabaseFileChild*>
|
||||
nsDataHashtable<nsISupportsHashKey, indexedDB::PBackgroundIDBDatabaseFileChild*>
|
||||
mFileActors;
|
||||
|
||||
nsTHashtable<nsISupportsHashKey> mReceivedBlobs;
|
||||
@@ -90,7 +91,7 @@ public:
|
||||
static already_AddRefed<IDBDatabase>
|
||||
Create(IDBOpenDBRequest* aRequest,
|
||||
IDBFactory* aFactory,
|
||||
BackgroundDatabaseChild* aActor,
|
||||
indexedDB::BackgroundDatabaseChild* aActor,
|
||||
DatabaseSpec* aSpec);
|
||||
|
||||
#ifdef DEBUG
|
||||
@@ -179,11 +180,11 @@ public:
|
||||
void
|
||||
AbortTransactions(bool aShouldWarn);
|
||||
|
||||
PBackgroundIDBDatabaseFileChild*
|
||||
indexedDB::PBackgroundIDBDatabaseFileChild*
|
||||
GetOrCreateFileActorForBlob(Blob* aBlob);
|
||||
|
||||
void
|
||||
NoteFinishedFileActor(PBackgroundIDBDatabaseFileChild* aFileActor);
|
||||
NoteFinishedFileActor(indexedDB::PBackgroundIDBDatabaseFileChild* aFileActor);
|
||||
|
||||
void
|
||||
NoteReceivedBlob(Blob* aBlob);
|
||||
@@ -285,7 +286,7 @@ public:
|
||||
private:
|
||||
IDBDatabase(IDBOpenDBRequest* aRequest,
|
||||
IDBFactory* aFactory,
|
||||
BackgroundDatabaseChild* aActor,
|
||||
indexedDB::BackgroundDatabaseChild* aActor,
|
||||
DatabaseSpec* aSpec);
|
||||
|
||||
~IDBDatabase();
|
||||
@@ -320,8 +321,7 @@ private:
|
||||
uint32_t aColumnNumber);
|
||||
};
|
||||
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_indexeddb_idbdatabase_h__
|
||||
#endif // mozilla_dom_idbdatabase_h__
|
||||
|
||||
@@ -44,6 +44,8 @@ CreateGenericEvent(EventTarget* aOwner,
|
||||
return event.forget();
|
||||
}
|
||||
|
||||
} // namespace indexedDB
|
||||
|
||||
// static
|
||||
already_AddRefed<IDBVersionChangeEvent>
|
||||
IDBVersionChangeEvent::CreateInternal(EventTarget* aOwner,
|
||||
@@ -91,6 +93,5 @@ IDBVersionChangeEvent::WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*>
|
||||
return IDBVersionChangeEventBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -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/. */
|
||||
|
||||
#ifndef mozilla_dom_indexeddb_idbevents_h__
|
||||
#define mozilla_dom_indexeddb_idbevents_h__
|
||||
#ifndef mozilla_dom_idbevents_h__
|
||||
#define mozilla_dom_idbevents_h__
|
||||
|
||||
#include "js/RootingAPI.h"
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
@@ -54,6 +54,8 @@ CreateGenericEvent(EventTarget* aOwner,
|
||||
Bubbles aBubbles,
|
||||
Cancelable aCancelable);
|
||||
|
||||
} // namespace indexedDB
|
||||
|
||||
class IDBVersionChangeEvent final : public Event
|
||||
{
|
||||
uint64_t mOldVersion;
|
||||
@@ -125,8 +127,7 @@ private:
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(IDBVersionChangeEvent, IDBVERSIONCHANGEEVENT_IID)
|
||||
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_indexeddb_idbevents_h__
|
||||
#endif // mozilla_dom_idbevents_h__
|
||||
|
||||
@@ -43,7 +43,6 @@
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace indexedDB {
|
||||
|
||||
using namespace mozilla::dom::quota;
|
||||
using namespace mozilla::ipc;
|
||||
@@ -956,6 +955,5 @@ IDBFactory::BackgroundCreateCallback::ActorFailed()
|
||||
factory->BackgroundActorFailed();
|
||||
}
|
||||
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -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/. */
|
||||
|
||||
#ifndef mozilla_dom_indexeddb_idbfactory_h__
|
||||
#define mozilla_dom_indexeddb_idbfactory_h__
|
||||
#ifndef mozilla_dom_idbfactory_h__
|
||||
#define mozilla_dom_idbfactory_h__
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/dom/StorageTypeBinding.h"
|
||||
@@ -35,15 +35,15 @@ class PrincipalInfo;
|
||||
namespace dom {
|
||||
|
||||
struct IDBOpenDBOptions;
|
||||
class IDBOpenDBRequest;
|
||||
template <typename> class Optional;
|
||||
class TabChild;
|
||||
|
||||
namespace indexedDB {
|
||||
|
||||
class BackgroundFactoryChild;
|
||||
class FactoryRequestParams;
|
||||
class IDBOpenDBRequest;
|
||||
class LoggingInfo;
|
||||
}
|
||||
|
||||
class IDBFactory final
|
||||
: public nsISupports
|
||||
@@ -69,7 +69,7 @@ class IDBFactory final
|
||||
|
||||
nsTArray<nsAutoPtr<PendingRequestInfo>> mPendingRequests;
|
||||
|
||||
BackgroundFactoryChild* mBackgroundActor;
|
||||
indexedDB::BackgroundFactoryChild* mBackgroundActor;
|
||||
|
||||
#ifdef DEBUG
|
||||
PRThread* mOwningThread;
|
||||
@@ -240,18 +240,17 @@ private:
|
||||
|
||||
nsresult
|
||||
BackgroundActorCreated(PBackgroundChild* aBackgroundActor,
|
||||
const LoggingInfo& aLoggingInfo);
|
||||
const indexedDB::LoggingInfo& aLoggingInfo);
|
||||
|
||||
void
|
||||
BackgroundActorFailed();
|
||||
|
||||
nsresult
|
||||
InitiateRequest(IDBOpenDBRequest* aRequest,
|
||||
const FactoryRequestParams& aParams);
|
||||
const indexedDB::FactoryRequestParams& aParams);
|
||||
};
|
||||
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_indexeddb_idbfactory_h__
|
||||
#endif // mozilla_dom_idbfactory_h__
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace indexedDB {
|
||||
|
||||
using namespace mozilla::dom::indexedDB;
|
||||
|
||||
IDBFileHandle::IDBFileHandle(FileMode aMode,
|
||||
IDBMutableFile* aMutableFile)
|
||||
@@ -194,6 +195,5 @@ IDBFileHandle::GenerateFileRequest()
|
||||
/* aWrapAsDOMRequest */ false);
|
||||
}
|
||||
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -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/. */
|
||||
|
||||
#ifndef mozilla_dom_indexeddb_idbfilehandle_h__
|
||||
#define mozilla_dom_indexeddb_idbfilehandle_h__
|
||||
#ifndef mozilla_dom_idbfilehandle_h__
|
||||
#define mozilla_dom_idbfilehandle_h__
|
||||
|
||||
#include "IDBFileRequest.h"
|
||||
#include "js/TypeDecls.h"
|
||||
@@ -22,9 +22,6 @@ namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
struct IDBFileMetadataParameters;
|
||||
|
||||
namespace indexedDB {
|
||||
|
||||
class IDBFileRequest;
|
||||
class IDBMutableFile;
|
||||
|
||||
@@ -146,8 +143,7 @@ private:
|
||||
GenerateFileRequest() override;
|
||||
};
|
||||
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_indexeddb_idbfilehandle_h__
|
||||
#endif // mozilla_dom_idbfilehandle_h__
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace indexedDB {
|
||||
|
||||
using namespace mozilla::dom::indexedDB;
|
||||
|
||||
IDBFileRequest::IDBFileRequest(nsPIDOMWindow* aWindow,
|
||||
IDBFileHandle* aFileHandle,
|
||||
@@ -152,6 +153,5 @@ IDBFileRequest::FireProgressEvent(uint64_t aLoaded, uint64_t aTotal)
|
||||
DispatchTrustedEvent(event);
|
||||
}
|
||||
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -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/. */
|
||||
|
||||
#ifndef mozilla_dom_indexeddb_idbfilerequest_h__
|
||||
#define mozilla_dom_indexeddb_idbfilerequest_h__
|
||||
#ifndef mozilla_dom_idbfilerequest_h__
|
||||
#define mozilla_dom_idbfilerequest_h__
|
||||
|
||||
#include "DOMRequest.h"
|
||||
#include "js/TypeDecls.h"
|
||||
@@ -22,7 +22,6 @@ namespace mozilla {
|
||||
class EventChainPreVisitor;
|
||||
|
||||
namespace dom {
|
||||
namespace indexedDB {
|
||||
|
||||
class IDBFileHandle;
|
||||
|
||||
@@ -90,8 +89,7 @@ private:
|
||||
FireProgressEvent(uint64_t aLoaded, uint64_t aTotal);
|
||||
};
|
||||
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_indexeddb_idbfilerequest_h__
|
||||
#endif // mozilla_dom_idbfilerequest_h__
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace indexedDB {
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -177,7 +176,7 @@ IDBIndex::LocaleAware() const
|
||||
return mMetadata->locale().IsEmpty();
|
||||
}
|
||||
|
||||
const KeyPath&
|
||||
const indexedDB::KeyPath&
|
||||
IDBIndex::GetKeyPath() const
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
@@ -621,6 +620,5 @@ IDBIndex::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
return IDBIndexBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
+11
-13
@@ -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/. */
|
||||
|
||||
#ifndef mozilla_dom_indexeddb_idbindex_h__
|
||||
#define mozilla_dom_indexeddb_idbindex_h__
|
||||
#ifndef mozilla_dom_idbindex_h__
|
||||
#define mozilla_dom_idbindex_h__
|
||||
|
||||
#include "js/RootingAPI.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
@@ -24,15 +24,14 @@ class ErrorResult;
|
||||
|
||||
namespace dom {
|
||||
|
||||
class IDBObjectStore;
|
||||
class IDBRequest;
|
||||
template <typename> class Sequence;
|
||||
|
||||
namespace indexedDB {
|
||||
|
||||
class IDBObjectStore;
|
||||
class IDBRequest;
|
||||
class IndexMetadata;
|
||||
class Key;
|
||||
class KeyPath;
|
||||
} // namespace indexedDB
|
||||
|
||||
class IDBIndex final
|
||||
: public nsISupports
|
||||
@@ -46,8 +45,8 @@ class IDBIndex final
|
||||
// object. However, if this index is part of a versionchange transaction and
|
||||
// it gets deleted then the metadata is copied into mDeletedMetadata and
|
||||
// mMetadata is set to point at mDeletedMetadata.
|
||||
const IndexMetadata* mMetadata;
|
||||
nsAutoPtr<IndexMetadata> mDeletedMetadata;
|
||||
const indexedDB::IndexMetadata* mMetadata;
|
||||
nsAutoPtr<indexedDB::IndexMetadata> mDeletedMetadata;
|
||||
|
||||
const int64_t mId;
|
||||
bool mRooted;
|
||||
@@ -57,7 +56,7 @@ public:
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(IDBIndex)
|
||||
|
||||
static already_AddRefed<IDBIndex>
|
||||
Create(IDBObjectStore* aObjectStore, const IndexMetadata& aMetadata);
|
||||
Create(IDBObjectStore* aObjectStore, const indexedDB::IndexMetadata& aMetadata);
|
||||
|
||||
int64_t
|
||||
Id() const
|
||||
@@ -79,7 +78,7 @@ public:
|
||||
bool
|
||||
LocaleAware() const;
|
||||
|
||||
const KeyPath&
|
||||
const indexedDB::KeyPath&
|
||||
GetKeyPath() const;
|
||||
|
||||
void
|
||||
@@ -201,7 +200,7 @@ public:
|
||||
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
private:
|
||||
IDBIndex(IDBObjectStore* aObjectStore, const IndexMetadata* aMetadata);
|
||||
IDBIndex(IDBObjectStore* aObjectStore, const indexedDB::IndexMetadata* aMetadata);
|
||||
|
||||
~IDBIndex();
|
||||
|
||||
@@ -226,8 +225,7 @@ private:
|
||||
ErrorResult& aRv);
|
||||
};
|
||||
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_indexeddb_idbindex_h__
|
||||
#endif // mozilla_dom_idbindex_h__
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace indexedDB {
|
||||
|
||||
using namespace mozilla::dom::indexedDB;
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -447,6 +448,5 @@ IDBLocaleAwareKeyRange::Bound(const GlobalObject& aGlobal,
|
||||
return keyRange.forget();
|
||||
}
|
||||
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
+13
-13
@@ -4,12 +4,13 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_indexeddb_idbkeyrange_h__
|
||||
#define mozilla_dom_indexeddb_idbkeyrange_h__
|
||||
#ifndef mozilla_dom_idbkeyrange_h__
|
||||
#define mozilla_dom_idbkeyrange_h__
|
||||
|
||||
#include "js/RootingAPI.h"
|
||||
#include "js/Value.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/dom/IndexedDatabaseManager.h"
|
||||
#include "mozilla/dom/indexedDB/Key.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
@@ -28,16 +29,16 @@ namespace dom {
|
||||
class GlobalObject;
|
||||
|
||||
namespace indexedDB {
|
||||
|
||||
class SerializedKeyRange;
|
||||
} // namespace indexedDB
|
||||
|
||||
class IDBKeyRange
|
||||
: public nsISupports
|
||||
{
|
||||
protected:
|
||||
nsCOMPtr<nsISupports> mGlobal;
|
||||
Key mLower;
|
||||
Key mUpper;
|
||||
indexedDB::Key mLower;
|
||||
indexedDB::Key mUpper;
|
||||
JS::Heap<JS::Value> mCachedLowerVal;
|
||||
JS::Heap<JS::Value> mCachedUpperVal;
|
||||
|
||||
@@ -62,7 +63,7 @@ public:
|
||||
IDBKeyRange** aKeyRange);
|
||||
|
||||
static already_AddRefed<IDBKeyRange>
|
||||
FromSerialized(const SerializedKeyRange& aKeyRange);
|
||||
FromSerialized(const indexedDB::SerializedKeyRange& aKeyRange);
|
||||
|
||||
static already_AddRefed<IDBKeyRange>
|
||||
Only(const GlobalObject& aGlobal,
|
||||
@@ -98,27 +99,27 @@ public:
|
||||
#endif
|
||||
|
||||
void
|
||||
ToSerialized(SerializedKeyRange& aKeyRange) const;
|
||||
ToSerialized(indexedDB::SerializedKeyRange& aKeyRange) const;
|
||||
|
||||
const Key&
|
||||
const indexedDB::Key&
|
||||
Lower() const
|
||||
{
|
||||
return mLower;
|
||||
}
|
||||
|
||||
Key&
|
||||
indexedDB::Key&
|
||||
Lower()
|
||||
{
|
||||
return mLower;
|
||||
}
|
||||
|
||||
const Key&
|
||||
const indexedDB::Key&
|
||||
Upper() const
|
||||
{
|
||||
return mIsOnly ? mLower : mUpper;
|
||||
}
|
||||
|
||||
Key&
|
||||
indexedDB::Key&
|
||||
Upper()
|
||||
{
|
||||
return mIsOnly ? mLower : mUpper;
|
||||
@@ -205,8 +206,7 @@ public:
|
||||
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector);
|
||||
};
|
||||
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_indexeddb_idbkeyrange_h__
|
||||
#endif // mozilla_dom_idbkeyrange_h__
|
||||
|
||||
@@ -34,8 +34,8 @@
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace indexedDB {
|
||||
|
||||
using namespace mozilla::dom::indexedDB;
|
||||
using namespace mozilla::dom::quota;
|
||||
|
||||
IDBMutableFile::IDBMutableFile(IDBDatabase* aDatabase,
|
||||
@@ -279,6 +279,5 @@ IDBMutableFile::CreateFileFor(BlobImpl* aBlobImpl,
|
||||
return file.forget();
|
||||
}
|
||||
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -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/. */
|
||||
|
||||
#ifndef mozilla_dom_indexeddb_idbmutablefile_h__
|
||||
#define mozilla_dom_indexeddb_idbmutablefile_h__
|
||||
#ifndef mozilla_dom_idbmutablefile_h__
|
||||
#define mozilla_dom_idbmutablefile_h__
|
||||
|
||||
#include "js/TypeDecls.h"
|
||||
#include "mozilla/Atomics.h"
|
||||
@@ -29,13 +29,13 @@ namespace dom {
|
||||
|
||||
class DOMRequest;
|
||||
class File;
|
||||
|
||||
namespace indexedDB {
|
||||
|
||||
class BackgroundMutableFileChild;
|
||||
class IDBDatabase;
|
||||
class IDBFileHandle;
|
||||
|
||||
namespace indexedDB {
|
||||
class BackgroundMutableFileChild;
|
||||
}
|
||||
|
||||
class IDBMutableFile final
|
||||
: public DOMEventTargetHelper
|
||||
, public MutableFileBase
|
||||
@@ -51,7 +51,7 @@ class IDBMutableFile final
|
||||
|
||||
public:
|
||||
IDBMutableFile(IDBDatabase* aDatabase,
|
||||
BackgroundMutableFileChild* aActor,
|
||||
indexedDB::BackgroundMutableFileChild* aActor,
|
||||
const nsAString& aName,
|
||||
const nsAString& aType);
|
||||
|
||||
@@ -134,8 +134,7 @@ private:
|
||||
~IDBMutableFile();
|
||||
};
|
||||
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_indexeddb_idbmutablefile_h__
|
||||
#endif // mozilla_dom_idbmutablefile_h__
|
||||
|
||||
@@ -54,7 +54,6 @@
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace indexedDB {
|
||||
|
||||
using namespace mozilla::dom::quota;
|
||||
using namespace mozilla::dom::workers;
|
||||
@@ -1865,16 +1864,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());
|
||||
@@ -1960,16 +1961,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());
|
||||
@@ -2275,7 +2278,7 @@ IDBObjectStore::AutoIncrement() const
|
||||
return mSpec->metadata().autoIncrement();
|
||||
}
|
||||
|
||||
const KeyPath&
|
||||
const indexedDB::KeyPath&
|
||||
IDBObjectStore::GetKeyPath() const
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
@@ -2293,6 +2296,5 @@ IDBObjectStore::HasValidKeyPath() const
|
||||
return GetKeyPath().IsValid();
|
||||
}
|
||||
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -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/. */
|
||||
|
||||
#ifndef mozilla_dom_indexeddb_idbobjectstore_h__
|
||||
#define mozilla_dom_indexeddb_idbobjectstore_h__
|
||||
#ifndef mozilla_dom_idbobjectstore_h__
|
||||
#define mozilla_dom_idbobjectstore_h__
|
||||
|
||||
#include "js/RootingAPI.h"
|
||||
#include "mozilla/dom/IDBCursorBinding.h"
|
||||
@@ -27,25 +27,31 @@ class ErrorResult;
|
||||
namespace dom {
|
||||
|
||||
class DOMStringList;
|
||||
template <typename> class Sequence;
|
||||
|
||||
namespace indexedDB {
|
||||
|
||||
class IDBCursor;
|
||||
class IDBRequest;
|
||||
class IDBTransaction;
|
||||
class IndexUpdateInfo;
|
||||
template <typename> class Sequence;
|
||||
|
||||
namespace indexedDB {
|
||||
class Key;
|
||||
class KeyPath;
|
||||
class IndexUpdateInfo;
|
||||
class ObjectStoreSpec;
|
||||
struct StructuredCloneReadInfo;
|
||||
} // namespace indexedDB
|
||||
|
||||
class IDBObjectStore final
|
||||
: public nsISupports
|
||||
, public nsWrapperCache
|
||||
{
|
||||
typedef indexedDB::IndexUpdateInfo IndexUpdateInfo;
|
||||
typedef indexedDB::Key Key;
|
||||
typedef indexedDB::KeyPath KeyPath;
|
||||
typedef indexedDB::ObjectStoreSpec ObjectStoreSpec;
|
||||
typedef indexedDB::StructuredCloneReadInfo StructuredCloneReadInfo;
|
||||
|
||||
// For AddOrPut() and DeleteInternal().
|
||||
friend class IDBCursor;
|
||||
friend class IDBCursor;
|
||||
|
||||
static const JSClass sDummyPropJSClass;
|
||||
|
||||
@@ -339,8 +345,7 @@ private:
|
||||
ErrorResult& aRv);
|
||||
};
|
||||
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_indexeddb_idbobjectstore_h__
|
||||
#endif // mozilla_dom_idbobjectstore_h__
|
||||
|
||||
@@ -38,8 +38,8 @@
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace indexedDB {
|
||||
|
||||
using namespace mozilla::dom::indexedDB;
|
||||
using namespace mozilla::dom::workers;
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
@@ -660,6 +660,5 @@ WorkerFeature::Notify(JSContext* aCx, Status aStatus)
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_indexeddb_idbrequest_h__
|
||||
#define mozilla_dom_indexeddb_idbrequest_h__
|
||||
#ifndef mozilla_dom_idbrequest_h__
|
||||
#define mozilla_dom_idbrequest_h__
|
||||
|
||||
#include "js/RootingAPI.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/EventForwards.h"
|
||||
#include "mozilla/dom/IDBRequestBinding.h"
|
||||
#include "mozilla/dom/indexedDB/IDBWrapperCache.h"
|
||||
#include "mozilla/dom/IDBWrapperCache.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
|
||||
@@ -28,17 +28,14 @@ class ErrorResult;
|
||||
namespace dom {
|
||||
|
||||
class DOMError;
|
||||
template <typename> struct Nullable;
|
||||
class OwningIDBObjectStoreOrIDBIndexOrIDBCursor;
|
||||
|
||||
namespace indexedDB {
|
||||
|
||||
class IDBCursor;
|
||||
class IDBDatabase;
|
||||
class IDBFactory;
|
||||
class IDBIndex;
|
||||
class IDBObjectStore;
|
||||
class IDBTransaction;
|
||||
template <typename> struct Nullable;
|
||||
class OwningIDBObjectStoreOrIDBIndexOrIDBCursor;
|
||||
|
||||
class IDBRequest
|
||||
: public IDBWrapperCache
|
||||
@@ -285,8 +282,7 @@ private:
|
||||
~IDBOpenDBRequest();
|
||||
};
|
||||
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_indexeddb_idbrequest_h__
|
||||
#endif // mozilla_dom_idbrequest_h__
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace indexedDB {
|
||||
|
||||
using namespace mozilla::dom::indexedDB;
|
||||
using namespace mozilla::dom::workers;
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
@@ -279,7 +279,7 @@ IDBTransaction::AssertIsOnOwningThread() const
|
||||
#endif // DEBUG
|
||||
|
||||
void
|
||||
IDBTransaction::SetBackgroundActor(BackgroundTransactionChild* aBackgroundActor)
|
||||
IDBTransaction::SetBackgroundActor(indexedDB::BackgroundTransactionChild* aBackgroundActor)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aBackgroundActor);
|
||||
@@ -570,7 +570,7 @@ IDBTransaction::DeleteObjectStore(int64_t aObjectStoreId)
|
||||
|
||||
void
|
||||
IDBTransaction::CreateIndex(IDBObjectStore* aObjectStore,
|
||||
const IndexMetadata& aMetadata)
|
||||
const indexedDB::IndexMetadata& aMetadata)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aObjectStore);
|
||||
@@ -859,7 +859,7 @@ IDBTransaction::GetError() const
|
||||
}
|
||||
|
||||
already_AddRefed<DOMStringList>
|
||||
IDBTransaction::ObjectStoreNames()
|
||||
IDBTransaction::ObjectStoreNames() const
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
@@ -1012,6 +1012,5 @@ WorkerFeature::Notify(JSContext* aCx, Status aStatus)
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_indexeddb_idbtransaction_h__
|
||||
#define mozilla_dom_indexeddb_idbtransaction_h__
|
||||
#ifndef mozilla_dom_idbtransaction_h__
|
||||
#define mozilla_dom_idbtransaction_h__
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/dom/IDBTransactionBinding.h"
|
||||
#include "mozilla/dom/indexedDB/IDBWrapperCache.h"
|
||||
#include "mozilla/dom/IDBWrapperCache.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsIRunnable.h"
|
||||
@@ -27,28 +27,28 @@ namespace dom {
|
||||
|
||||
class DOMError;
|
||||
class DOMStringList;
|
||||
|
||||
namespace indexedDB {
|
||||
|
||||
class BackgroundCursorChild;
|
||||
class BackgroundRequestChild;
|
||||
class BackgroundTransactionChild;
|
||||
class BackgroundVersionChangeTransactionChild;
|
||||
class IDBDatabase;
|
||||
class IDBObjectStore;
|
||||
class IDBOpenDBRequest;
|
||||
class IDBRequest;
|
||||
|
||||
namespace indexedDB {
|
||||
class BackgroundCursorChild;
|
||||
class BackgroundRequestChild;
|
||||
class BackgroundTransactionChild;
|
||||
class BackgroundVersionChangeTransactionChild;
|
||||
class IndexMetadata;
|
||||
class ObjectStoreSpec;
|
||||
class OpenCursorParams;
|
||||
class RequestParams;
|
||||
}
|
||||
|
||||
class IDBTransaction final
|
||||
: public IDBWrapperCache
|
||||
, public nsIRunnable
|
||||
{
|
||||
friend class BackgroundCursorChild;
|
||||
friend class BackgroundRequestChild;
|
||||
friend class indexedDB::BackgroundCursorChild;
|
||||
friend class indexedDB::BackgroundRequestChild;
|
||||
|
||||
class WorkerFeature;
|
||||
friend class WorkerFeature;
|
||||
@@ -85,8 +85,8 @@ private:
|
||||
// a BackgroundVersionChangeTransactionChild. Otherwise it will be a
|
||||
// BackgroundTransactionChild.
|
||||
union {
|
||||
BackgroundTransactionChild* mNormalBackgroundActor;
|
||||
BackgroundVersionChangeTransactionChild* mVersionChangeBackgroundActor;
|
||||
indexedDB::BackgroundTransactionChild* mNormalBackgroundActor;
|
||||
indexedDB::BackgroundVersionChangeTransactionChild* mVersionChangeBackgroundActor;
|
||||
} mBackgroundActor;
|
||||
|
||||
const int64_t mLoggingSerialNumber;
|
||||
@@ -117,7 +117,7 @@ private:
|
||||
public:
|
||||
static already_AddRefed<IDBTransaction>
|
||||
CreateVersionChange(IDBDatabase* aDatabase,
|
||||
BackgroundVersionChangeTransactionChild* aActor,
|
||||
indexedDB::BackgroundVersionChangeTransactionChild* aActor,
|
||||
IDBOpenDBRequest* aOpenRequest,
|
||||
int64_t aNextObjectStoreId,
|
||||
int64_t aNextIndexId);
|
||||
@@ -139,7 +139,7 @@ public:
|
||||
#endif
|
||||
|
||||
void
|
||||
SetBackgroundActor(BackgroundTransactionChild* aBackgroundActor);
|
||||
SetBackgroundActor(indexedDB::BackgroundTransactionChild* aBackgroundActor);
|
||||
|
||||
void
|
||||
ClearBackgroundActor()
|
||||
@@ -153,12 +153,12 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
BackgroundRequestChild*
|
||||
StartRequest(IDBRequest* aRequest, const RequestParams& aParams);
|
||||
indexedDB::BackgroundRequestChild*
|
||||
StartRequest(IDBRequest* aRequest, const indexedDB::RequestParams& aParams);
|
||||
|
||||
void
|
||||
OpenCursor(BackgroundCursorChild* aBackgroundActor,
|
||||
const OpenCursorParams& aParams);
|
||||
OpenCursor(indexedDB::BackgroundCursorChild* aBackgroundActor,
|
||||
const indexedDB::OpenCursorParams& aParams);
|
||||
|
||||
void
|
||||
RefreshSpec(bool aMayDelete);
|
||||
@@ -238,13 +238,13 @@ public:
|
||||
}
|
||||
|
||||
already_AddRefed<IDBObjectStore>
|
||||
CreateObjectStore(const ObjectStoreSpec& aSpec);
|
||||
CreateObjectStore(const indexedDB::ObjectStoreSpec& aSpec);
|
||||
|
||||
void
|
||||
DeleteObjectStore(int64_t aObjectStoreId);
|
||||
|
||||
void
|
||||
CreateIndex(IDBObjectStore* aObjectStore, const IndexMetadata& aMetadata);
|
||||
CreateIndex(IDBObjectStore* aObjectStore, const indexedDB::IndexMetadata& aMetadata);
|
||||
|
||||
void
|
||||
DeleteIndex(IDBObjectStore* aObjectStore, int64_t aIndexId);
|
||||
@@ -283,7 +283,7 @@ public:
|
||||
IMPL_EVENT_HANDLER(error)
|
||||
|
||||
already_AddRefed<DOMStringList>
|
||||
ObjectStoreNames();
|
||||
ObjectStoreNames() const;
|
||||
|
||||
void
|
||||
FireCompleteOrAbortEvents(nsresult aResult);
|
||||
@@ -330,8 +330,7 @@ private:
|
||||
OnRequestFinished(bool aActorDestroyedNormally);
|
||||
};
|
||||
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_indexeddb_idbtransaction_h__
|
||||
#endif // mozilla_dom_idbtransaction_h__
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace indexedDB {
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(IDBWrapperCache)
|
||||
|
||||
@@ -77,6 +76,5 @@ IDBWrapperCache::AssertIsRooted() const
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -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/. */
|
||||
|
||||
#ifndef mozilla_dom_indexeddb_idbwrappercache_h__
|
||||
#define mozilla_dom_indexeddb_idbwrappercache_h__
|
||||
#ifndef mozilla_dom_idbwrappercache_h__
|
||||
#define mozilla_dom_idbwrappercache_h__
|
||||
|
||||
#include "js/RootingAPI.h"
|
||||
#include "mozilla/DOMEventTargetHelper.h"
|
||||
@@ -16,7 +16,6 @@ class nsPIDOMWindow;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace indexedDB {
|
||||
|
||||
class IDBWrapperCache : public DOMEventTargetHelper
|
||||
{
|
||||
@@ -50,8 +49,7 @@ protected:
|
||||
virtual ~IDBWrapperCache();
|
||||
};
|
||||
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_indexeddb_idbwrappercache_h__
|
||||
#endif // mozilla_dom_idbwrappercache_h__
|
||||
|
||||
@@ -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/. */
|
||||
|
||||
#ifndef mozilla_dom_indexeddb_indexeddatabase_h__
|
||||
#define mozilla_dom_indexeddb_indexeddatabase_h__
|
||||
#ifndef mozilla_dom_indexeddatabase_h__
|
||||
#define mozilla_dom_indexeddatabase_h__
|
||||
|
||||
#include "js/StructuredClone.h"
|
||||
#include "nsAutoPtr.h"
|
||||
@@ -16,12 +16,12 @@ namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class Blob;
|
||||
class IDBDatabase;
|
||||
class IDBMutableFile;
|
||||
|
||||
namespace indexedDB {
|
||||
|
||||
class FileInfo;
|
||||
class IDBDatabase;
|
||||
class IDBMutableFile;
|
||||
class SerializedStructuredCloneReadInfo;
|
||||
|
||||
struct StructuredCloneFile
|
||||
@@ -74,4 +74,4 @@ struct StructuredCloneReadInfo
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_indexeddb_indexeddatabase_h__
|
||||
#endif // mozilla_dom_indexeddatabase_h__
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#ifndef IndexedDatabaseInlines_h
|
||||
#define IndexedDatabaseInlines_h
|
||||
|
||||
#ifndef mozilla_dom_indexeddb_indexeddatabase_h__
|
||||
#ifndef mozilla_dom_indexeddatabase_h__
|
||||
#error Must include IndexedDatabase.h first
|
||||
#endif
|
||||
|
||||
|
||||
@@ -118,6 +118,10 @@ private:
|
||||
nsTArray<RefPtr<FileManager> > mDefaultStorageFileManagers;
|
||||
};
|
||||
|
||||
} // namespace indexedDB
|
||||
|
||||
using namespace mozilla::dom::indexedDB;
|
||||
|
||||
namespace {
|
||||
|
||||
NS_DEFINE_IID(kIDBRequestIID, PRIVATE_IDBREQUEST_IID);
|
||||
@@ -1422,6 +1426,5 @@ GetFileReferencesHelper::Run()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -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/. */
|
||||
|
||||
#ifndef mozilla_dom_indexeddb_indexeddatabasemanager_h__
|
||||
#define mozilla_dom_indexeddb_indexeddatabasemanager_h__
|
||||
#ifndef mozilla_dom_indexeddatabasemanager_h__
|
||||
#define mozilla_dom_indexeddatabasemanager_h__
|
||||
|
||||
#include "nsIObserver.h"
|
||||
|
||||
@@ -24,17 +24,22 @@ class EventChainPostVisitor;
|
||||
|
||||
namespace dom {
|
||||
|
||||
class IDBFactory;
|
||||
|
||||
namespace indexedDB {
|
||||
|
||||
class FileManager;
|
||||
class FileManagerInfo;
|
||||
class IDBFactory;
|
||||
|
||||
} // namespace indexedDB
|
||||
|
||||
class IndexedDatabaseManager final
|
||||
: public nsIObserver
|
||||
, public nsITimerCallback
|
||||
{
|
||||
typedef mozilla::dom::quota::PersistenceType PersistenceType;
|
||||
typedef mozilla::dom::indexedDB::FileManager FileManager;
|
||||
typedef mozilla::dom::indexedDB::FileManagerInfo FileManagerInfo;
|
||||
|
||||
public:
|
||||
enum LoggingMode
|
||||
@@ -217,8 +222,7 @@ private:
|
||||
static mozilla::Atomic<bool> sLowDiskSpaceMode;
|
||||
};
|
||||
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_indexeddb_indexeddatabasemanager_h__
|
||||
#endif // mozilla_dom_indexeddatabasemanager_h__
|
||||
|
||||
@@ -18,8 +18,8 @@ include "mozilla/dom/indexedDB/SerializationHelpers.h";
|
||||
using struct mozilla::null_t
|
||||
from "ipc/IPCMessageUtils.h";
|
||||
|
||||
using mozilla::dom::indexedDB::IDBTransaction::Mode
|
||||
from "mozilla/dom/indexedDB/IDBTransaction.h";
|
||||
using mozilla::dom::IDBTransaction::Mode
|
||||
from "mozilla/dom/IDBTransaction.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
@@ -17,8 +17,8 @@ using struct mozilla::null_t
|
||||
using struct mozilla::void_t
|
||||
from "ipc/IPCMessageUtils.h";
|
||||
|
||||
using mozilla::dom::indexedDB::IDBCursor::Direction
|
||||
from "mozilla/dom/indexedDB/IDBCursor.h";
|
||||
using mozilla::dom::IDBCursor::Direction
|
||||
from "mozilla/dom/IDBCursor.h";
|
||||
|
||||
using class mozilla::dom::indexedDB::Key
|
||||
from "mozilla/dom/indexedDB/Key.h";
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
|
||||
#include "mozilla/dom/indexedDB/Key.h"
|
||||
#include "mozilla/dom/indexedDB/KeyPath.h"
|
||||
#include "mozilla/dom/indexedDB/IDBCursor.h"
|
||||
#include "mozilla/dom/indexedDB/IDBTransaction.h"
|
||||
#include "mozilla/dom/IDBCursor.h"
|
||||
#include "mozilla/dom/IDBTransaction.h"
|
||||
|
||||
namespace IPC {
|
||||
|
||||
@@ -68,19 +68,19 @@ struct ParamTraits<mozilla::dom::indexedDB::KeyPath>
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ParamTraits<mozilla::dom::indexedDB::IDBCursor::Direction> :
|
||||
struct ParamTraits<mozilla::dom::IDBCursor::Direction> :
|
||||
public ContiguousEnumSerializer<
|
||||
mozilla::dom::indexedDB::IDBCursor::Direction,
|
||||
mozilla::dom::indexedDB::IDBCursor::NEXT,
|
||||
mozilla::dom::indexedDB::IDBCursor::DIRECTION_INVALID>
|
||||
mozilla::dom::IDBCursor::Direction,
|
||||
mozilla::dom::IDBCursor::NEXT,
|
||||
mozilla::dom::IDBCursor::DIRECTION_INVALID>
|
||||
{ };
|
||||
|
||||
template <>
|
||||
struct ParamTraits<mozilla::dom::indexedDB::IDBTransaction::Mode> :
|
||||
struct ParamTraits<mozilla::dom::IDBTransaction::Mode> :
|
||||
public ContiguousEnumSerializer<
|
||||
mozilla::dom::indexedDB::IDBTransaction::Mode,
|
||||
mozilla::dom::indexedDB::IDBTransaction::READ_ONLY,
|
||||
mozilla::dom::indexedDB::IDBTransaction::MODE_INVALID>
|
||||
mozilla::dom::IDBTransaction::Mode,
|
||||
mozilla::dom::IDBTransaction::READ_ONLY,
|
||||
mozilla::dom::IDBTransaction::MODE_INVALID>
|
||||
{ };
|
||||
|
||||
} // namespace IPC
|
||||
|
||||
@@ -20,9 +20,7 @@ XPCSHELL_TESTS_MANIFESTS += [
|
||||
if CONFIG['ENABLE_INTL_API']:
|
||||
MOCHITEST_MANIFESTS += ['test/mochitest-intl-api.ini']
|
||||
|
||||
EXPORTS.mozilla.dom.indexedDB += [
|
||||
'ActorsParent.h',
|
||||
'FileSnapshot.h',
|
||||
EXPORTS.mozilla.dom += [
|
||||
'IDBCursor.h',
|
||||
'IDBDatabase.h',
|
||||
'IDBEvents.h',
|
||||
@@ -38,6 +36,11 @@ EXPORTS.mozilla.dom.indexedDB += [
|
||||
'IDBWrapperCache.h',
|
||||
'IndexedDatabase.h',
|
||||
'IndexedDatabaseManager.h',
|
||||
]
|
||||
|
||||
EXPORTS.mozilla.dom.indexedDB += [
|
||||
'ActorsParent.h',
|
||||
'FileSnapshot.h',
|
||||
'Key.h',
|
||||
'KeyPath.h',
|
||||
'SerializationHelpers.h',
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
#include "mozilla/dom/PBlobStreamChild.h"
|
||||
#include "mozilla/dom/PBlobStreamParent.h"
|
||||
#include "mozilla/dom/indexedDB/FileSnapshot.h"
|
||||
#include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
|
||||
#include "mozilla/dom/IndexedDatabaseManager.h"
|
||||
#include "mozilla/ipc/InputStreamUtils.h"
|
||||
#include "mozilla/ipc/PBackgroundChild.h"
|
||||
#include "mozilla/ipc/PBackgroundParent.h"
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
#include "mozilla/dom/cellbroadcast/CellBroadcastParent.h"
|
||||
#include "mozilla/dom/devicestorage/DeviceStorageRequestParent.h"
|
||||
#include "mozilla/dom/icc/IccParent.h"
|
||||
#include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
|
||||
#include "mozilla/dom/IndexedDatabaseManager.h"
|
||||
#include "mozilla/dom/mobileconnection/MobileConnectionParent.h"
|
||||
#include "mozilla/dom/mobilemessage/SmsParent.h"
|
||||
#include "mozilla/dom/power/PowerManagerService.h"
|
||||
|
||||
@@ -13,6 +13,7 @@ support-files =
|
||||
NetworkPreparationChromeScript.js
|
||||
blacksilence.js
|
||||
turnConfig.js
|
||||
sdpUtils.js
|
||||
|
||||
[test_dataChannel_basicAudio.html]
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' # Bug 962984 for debug, bug 963244 for opt
|
||||
@@ -61,12 +62,18 @@ skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g(Bug 1021776, too --ing
|
||||
[test_peerConnection_addIceCandidate.html]
|
||||
[test_peerConnection_basicAudio.html]
|
||||
skip-if = toolkit == 'gonk' # B2G emulator is too slow to handle a two-way audio call reliably
|
||||
[test_peerConnection_basicAudioRequireEOC.html]
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g (Bug 1059867)
|
||||
[test_peerConnection_basicAudioVideo.html]
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' || (android_version == '18' && debug) # b2g(Bug 960442, video support for WebRTC is disabled on b2g), android(Bug 1189784, timeouts on 4.3 emulator)
|
||||
[test_peerConnection_basicAudioVideoCombined.html]
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' || (android_version == '18' && debug) # b2g(Bug 960442, video support for WebRTC is disabled on b2g), android(Bug 1189784, timeouts on 4.3 emulator)
|
||||
[test_peerConnection_basicAudioVideoNoBundle.html]
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' || (android_version == '18' && debug) # b2g(Bug 960442, video support for WebRTC is disabled on b2g), android(Bug 1189784, timeouts on 4.3 emulator)
|
||||
[test_peerConnection_basicAudioVideoNoBundleNoRtcpMux.html]
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' || android_version == '18' # b2g(Bug 960442, video support for WebRTC is disabled on b2g), android(Bug 1189784, timeouts on 4.3 emulator)
|
||||
[test_peerConnection_basicAudioVideoNoRtcpMux.html]
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' || android_version == '18' # b2g(Bug 960442, video support for WebRTC is disabled on b2g), android(Bug 1189784, timeouts on 4.3 emulator)
|
||||
[test_peerConnection_basicVideo.html]
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
|
||||
[test_peerConnection_basicScreenshare.html]
|
||||
|
||||
+93
-127
@@ -99,19 +99,6 @@ MediaElementChecker.prototype = {
|
||||
}
|
||||
};
|
||||
|
||||
// Also remove mode 0 if it's offered
|
||||
// Note, we don't bother removing the fmtp lines, which makes a good test
|
||||
// for some SDP parsing issues.
|
||||
function removeVP8(sdp) {
|
||||
var updated_sdp = sdp.replace("a=rtpmap:120 VP8/90000\r\n","");
|
||||
updated_sdp = updated_sdp.replace("RTP/SAVPF 120 126 97\r\n","RTP/SAVPF 126 97\r\n");
|
||||
updated_sdp = updated_sdp.replace("RTP/SAVPF 120 126\r\n","RTP/SAVPF 126\r\n");
|
||||
updated_sdp = updated_sdp.replace("a=rtcp-fb:120 nack\r\n","");
|
||||
updated_sdp = updated_sdp.replace("a=rtcp-fb:120 nack pli\r\n","");
|
||||
updated_sdp = updated_sdp.replace("a=rtcp-fb:120 ccm fir\r\n","");
|
||||
return updated_sdp;
|
||||
}
|
||||
|
||||
var makeDefaultCommands = () => {
|
||||
return [].concat(commandsPeerConnectionInitial,
|
||||
commandsGetUserMedia,
|
||||
@@ -143,6 +130,10 @@ function PeerConnectionTest(options) {
|
||||
options.is_local = "is_local" in options ? options.is_local : true;
|
||||
options.is_remote = "is_remote" in options ? options.is_remote : true;
|
||||
|
||||
options.h264 = "h264" in options ? options.h264 : false;
|
||||
options.bundle = "bundle" in options ? options.bundle : true;
|
||||
options.rtcpmux = "rtcpmux" in options ? options.rtcpmux : true;
|
||||
|
||||
if (typeof turnServers !== "undefined") {
|
||||
if ((!options.turn_disabled_local) && (turnServers.local)) {
|
||||
if (!options.hasOwnProperty("config_local")) {
|
||||
@@ -162,26 +153,24 @@ function PeerConnectionTest(options) {
|
||||
}
|
||||
}
|
||||
|
||||
if (options.is_local)
|
||||
this.pcLocal = new PeerConnectionWrapper('pcLocal', options.config_local, options.h264);
|
||||
else
|
||||
if (options.is_local) {
|
||||
this.pcLocal = new PeerConnectionWrapper('pcLocal', options.config_local);
|
||||
} else {
|
||||
this.pcLocal = null;
|
||||
}
|
||||
|
||||
if (options.is_remote)
|
||||
this.pcRemote = new PeerConnectionWrapper('pcRemote', options.config_remote || options.config_local, options.h264);
|
||||
else
|
||||
if (options.is_remote) {
|
||||
this.pcRemote = new PeerConnectionWrapper('pcRemote', options.config_remote || options.config_local);
|
||||
} else {
|
||||
this.pcRemote = null;
|
||||
}
|
||||
|
||||
this.steeplechase = this.pcLocal === null || this.pcRemote === null;
|
||||
options.steeplechase = !options.is_local || !options.is_remote;
|
||||
|
||||
// Create command chain instance and assign default commands
|
||||
this.chain = new CommandChain(this, options.commands);
|
||||
if (!options.is_local) {
|
||||
this.chain.filterOut(/^PC_LOCAL/);
|
||||
}
|
||||
if (!options.is_remote) {
|
||||
this.chain.filterOut(/^PC_REMOTE/);
|
||||
}
|
||||
|
||||
this.testOptions = options;
|
||||
}
|
||||
|
||||
/** TODO: consider removing this dependency on timeouts */
|
||||
@@ -406,6 +395,14 @@ function(peer, desc, stateExpected) {
|
||||
peer.setLocalDescDate = new Date();
|
||||
});
|
||||
|
||||
peer.endOfTrickleSdp = peer.endOfTrickleIce.then(() => {
|
||||
if (this.testOptions.steeplechase) {
|
||||
send_message({"type": "end_of_trickle_ice"});
|
||||
}
|
||||
return peer._pc.localDescription;
|
||||
})
|
||||
.catch(e => ok(false, "Sending EOC message failed: " + e));
|
||||
|
||||
return Promise.all([eventFired, stateChanged]);
|
||||
};
|
||||
|
||||
@@ -470,10 +467,41 @@ function(peer, desc, stateExpected) {
|
||||
return Promise.all([eventFired, stateChanged]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds and removes steps to/from the execution chain based on the configured
|
||||
* testOptions.
|
||||
*/
|
||||
PeerConnectionTest.prototype.updateChainSteps = function() {
|
||||
if (this.testOptions.h264) {
|
||||
this.chain.insertAfterEach(
|
||||
'PC_LOCAL_CREATE_OFFER',
|
||||
[PC_LOCAL_REMOVE_VP8_FROM_OFFER]);
|
||||
}
|
||||
if (!this.testOptions.bundle) {
|
||||
this.chain.insertAfterEach(
|
||||
'PC_LOCAL_CREATE_OFFER',
|
||||
[PC_LOCAL_REMOVE_BUNDLE_FROM_OFFER]);
|
||||
}
|
||||
if (!this.testOptions.rtcpmux) {
|
||||
this.chain.insertAfterEach(
|
||||
'PC_LOCAL_CREATE_OFFER',
|
||||
[PC_LOCAL_REMOVE_RTCPMUX_FROM_OFFER]);
|
||||
}
|
||||
if (!this.testOptions.is_local) {
|
||||
this.chain.filterOut(/^PC_LOCAL/);
|
||||
}
|
||||
if (!this.testOptions.is_remote) {
|
||||
this.chain.filterOut(/^PC_REMOTE/);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Start running the tests as assigned to the command chain.
|
||||
*/
|
||||
PeerConnectionTest.prototype.run = function() {
|
||||
/* We have to modify the chain here to allow tests which modify the default
|
||||
* test chain instantiating a PeerConnectionTest() */
|
||||
this.updateChainSteps();
|
||||
return this.chain.execute()
|
||||
.then(() => this.close())
|
||||
.then(() => {
|
||||
@@ -725,7 +753,7 @@ DataChannelWrapper.prototype = {
|
||||
* @param {object} configuration
|
||||
* Configuration for the peer connection instance
|
||||
*/
|
||||
function PeerConnectionWrapper(label, configuration, h264) {
|
||||
function PeerConnectionWrapper(label, configuration) {
|
||||
this.configuration = configuration;
|
||||
if (configuration && configuration.label_suffix) {
|
||||
label = label + "_" + configuration.label_suffix;
|
||||
@@ -754,8 +782,6 @@ function PeerConnectionWrapper(label, configuration, h264) {
|
||||
|
||||
this.iceCheckingRestartExpected = false;
|
||||
|
||||
this.h264 = typeof h264 !== "undefined" ? true : false;
|
||||
|
||||
info("Creating " + this);
|
||||
this._pc = new RTCPeerConnection(this.configuration);
|
||||
|
||||
@@ -995,10 +1021,6 @@ PeerConnectionWrapper.prototype = {
|
||||
info("Got offer: " + JSON.stringify(offer));
|
||||
// note: this might get updated through ICE gathering
|
||||
this._latest_offer = offer;
|
||||
if (this.h264) {
|
||||
isnot(offer.sdp.search("H264/90000"), -1, "H.264 should be present in the SDP offer");
|
||||
offer.sdp = removeVP8(offer.sdp);
|
||||
}
|
||||
return offer;
|
||||
});
|
||||
},
|
||||
@@ -1292,18 +1314,16 @@ PeerConnectionWrapper.prototype = {
|
||||
this.endOfTrickleIce = new Promise(r => resolveEndOfTrickle = r);
|
||||
this.holdIceCandidates = new Promise(r => this.releaseIceCandidates = r);
|
||||
|
||||
this.endOfTrickleIce.then(() => {
|
||||
this._pc.onicecandidate = () =>
|
||||
ok(false, this.label + " received ICE candidate after end of trickle");
|
||||
var localSdp = this._pc.getLocalDescription();
|
||||
ok(localSdp.includes("a=end-of-candidates"));
|
||||
ok(localSdp.includes("a=rtcp:"));
|
||||
ok(!localSdp.includes("c=IN IP4 0.0.0.0"));
|
||||
});
|
||||
|
||||
this._pc.onicecandidate = anEvent => {
|
||||
if (!anEvent.candidate) {
|
||||
this._pc.onicecandidate = () =>
|
||||
ok(false, this.label + " received ICE candidate after end of trickle");
|
||||
info(this.label + ": received end of trickle ICE event");
|
||||
/* Bug 1193731. Accroding to WebRTC spec 4.3.1 the ICE Agent first sets
|
||||
* the gathering state to completed (step 3.) before sending out the
|
||||
* null newCandidate in step 4. */
|
||||
todo(this._pc.iceGatheringState === 'completed',
|
||||
"ICE gathering state has reached completed");
|
||||
resolveEndOfTrickle(this.label);
|
||||
return;
|
||||
}
|
||||
@@ -1312,25 +1332,19 @@ PeerConnectionWrapper.prototype = {
|
||||
ok(anEvent.candidate.candidate.length > 0, "ICE candidate contains candidate");
|
||||
ok(anEvent.candidate.sdpMid.length > 0, "SDP mid not empty");
|
||||
|
||||
// only check the m-section for the updated default addr that corresponds
|
||||
// with this candidate.
|
||||
var mSections = this.localDescription.sdp.split("\r\nm=");
|
||||
sdputils.checkSdpCLineNotDefault(
|
||||
mSections[anEvent.candidate.sdpMLineIndex+1], this.label
|
||||
);
|
||||
|
||||
ok(typeof anEvent.candidate.sdpMLineIndex === 'number', "SDP MLine Index needs to exist");
|
||||
this._local_ice_candidates.push(anEvent.candidate);
|
||||
candidateHandler(this.label, anEvent.candidate);
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Counts the amount of audio tracks in a given media constraint.
|
||||
*
|
||||
* @param constraints
|
||||
* The contraint to be examined.
|
||||
*/
|
||||
countTracksInConstraint : function(type, constraints) {
|
||||
if (!Array.isArray(constraints)) {
|
||||
return 0;
|
||||
}
|
||||
return constraints.reduce((sum, c) => sum + (c[type] ? 1 : 0), 0);
|
||||
},
|
||||
|
||||
checkLocalMediaTracks : function() {
|
||||
var observed = {};
|
||||
info(this + " Checking local tracks " + JSON.stringify(this.expectedLocalTrackInfoById));
|
||||
@@ -1379,66 +1393,6 @@ PeerConnectionWrapper.prototype = {
|
||||
"remote");
|
||||
},
|
||||
|
||||
verifySdp: function(desc, expectedType, offerConstraintsList, offerOptions, isLocal) {
|
||||
info("Examining this SessionDescription: " + JSON.stringify(desc));
|
||||
info("offerConstraintsList: " + JSON.stringify(offerConstraintsList));
|
||||
info("offerOptions: " + JSON.stringify(offerOptions));
|
||||
ok(desc, "SessionDescription is not null");
|
||||
is(desc.type, expectedType, "SessionDescription type is " + expectedType);
|
||||
ok(desc.sdp.length > 10, "SessionDescription body length is plausible");
|
||||
ok(desc.sdp.includes("a=ice-ufrag"), "ICE username is present in SDP");
|
||||
ok(desc.sdp.includes("a=ice-pwd"), "ICE password is present in SDP");
|
||||
ok(desc.sdp.includes("a=fingerprint"), "ICE fingerprint is present in SDP");
|
||||
//TODO: update this for loopback support bug 1027350
|
||||
ok(!desc.sdp.includes(LOOPBACK_ADDR), "loopback interface is absent from SDP");
|
||||
var requiresTrickleIce = !desc.sdp.includes("a=candidate");
|
||||
if (requiresTrickleIce) {
|
||||
info("at least one ICE candidate is present in SDP");
|
||||
} else {
|
||||
info("No ICE candidate in SDP -> requiring trickle ICE");
|
||||
}
|
||||
if (isLocal) {
|
||||
this.localRequiresTrickleIce = requiresTrickleIce;
|
||||
} else {
|
||||
this.remoteRequiresTrickleIce = requiresTrickleIce;
|
||||
}
|
||||
|
||||
//TODO: how can we check for absence/presence of m=application?
|
||||
|
||||
var audioTracks =
|
||||
this.countTracksInConstraint('audio', offerConstraintsList) ||
|
||||
((offerOptions && offerOptions.offerToReceiveAudio) ? 1 : 0);
|
||||
|
||||
info("expected audio tracks: " + audioTracks);
|
||||
if (audioTracks == 0) {
|
||||
ok(!desc.sdp.includes("m=audio"), "audio m-line is absent from SDP");
|
||||
} else {
|
||||
ok(desc.sdp.includes("m=audio"), "audio m-line is present in SDP");
|
||||
ok(desc.sdp.includes("a=rtpmap:109 opus/48000/2"), "OPUS codec is present in SDP");
|
||||
//TODO: ideally the rtcp-mux should be for the m=audio, and not just
|
||||
// anywhere in the SDP (JS SDP parser bug 1045429)
|
||||
ok(desc.sdp.includes("a=rtcp-mux"), "RTCP Mux is offered in SDP");
|
||||
}
|
||||
|
||||
var videoTracks =
|
||||
this.countTracksInConstraint('video', offerConstraintsList) ||
|
||||
((offerOptions && offerOptions.offerToReceiveVideo) ? 1 : 0);
|
||||
|
||||
info("expected video tracks: " + videoTracks);
|
||||
if (videoTracks == 0) {
|
||||
ok(!desc.sdp.includes("m=video"), "video m-line is absent from SDP");
|
||||
} else {
|
||||
ok(desc.sdp.includes("m=video"), "video m-line is present in SDP");
|
||||
if (this.h264) {
|
||||
ok(desc.sdp.includes("a=rtpmap:126 H264/90000"), "H.264 codec is present in SDP");
|
||||
} else {
|
||||
ok(desc.sdp.includes("a=rtpmap:120 VP8/90000"), "VP8 codec is present in SDP");
|
||||
}
|
||||
ok(desc.sdp.includes("a=rtcp-mux"), "RTCP Mux is offered in SDP");
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Check that media flow is present on the given media element by waiting for
|
||||
* it to reach ready state HAVE_ENOUGH_DATA and progress time further than
|
||||
@@ -1763,11 +1717,11 @@ PeerConnectionWrapper.prototype = {
|
||||
* The stats to check for ICE candidate pairs
|
||||
* @param {object} counters
|
||||
* The counters for media and data tracks based on constraints
|
||||
* @param {object} answer
|
||||
* The SDP answer to check for SDP bundle support
|
||||
* @param {object} testOptions
|
||||
* The test options object from the PeerConnectionTest
|
||||
*/
|
||||
checkStatsIceConnections : function(stats,
|
||||
offerConstraintsList, offerOptions, answer) {
|
||||
offerConstraintsList, offerOptions, testOptions) {
|
||||
var numIceConnections = 0;
|
||||
Object.keys(stats).forEach(key => {
|
||||
if ((stats[key].type === "candidatepair") && stats[key].selected) {
|
||||
@@ -1775,24 +1729,35 @@ PeerConnectionWrapper.prototype = {
|
||||
}
|
||||
});
|
||||
info("ICE connections according to stats: " + numIceConnections);
|
||||
if (answer.sdp.includes('a=group:BUNDLE')) {
|
||||
is(numIceConnections, 1, "stats reports exactly 1 ICE connection");
|
||||
isnot(numIceConnections, 0, "Number of ICE connections according to stats is not zero");
|
||||
if (testOptions.bundle) {
|
||||
if (testOptions.rtcpmux) {
|
||||
is(numIceConnections, 1, "stats reports exactly 1 ICE connection");
|
||||
} else {
|
||||
is(numIceConnections, 2, "stats report exactly 2 ICE connections for media and RTCP");
|
||||
}
|
||||
} else {
|
||||
// This code assumes that no media sections have been rejected due to
|
||||
// codec mismatch or other unrecoverable negotiation failures.
|
||||
var numAudioTracks =
|
||||
this.countTracksInConstraint('audio', offerConstraintsList) ||
|
||||
sdputils.countTracksInConstraint('audio', offerConstraintsList) ||
|
||||
((offerOptions && offerOptions.offerToReceiveAudio) ? 1 : 0);
|
||||
|
||||
var numVideoTracks =
|
||||
this.countTracksInConstraint('video', offerConstraintsList) ||
|
||||
sdputils.countTracksInConstraint('video', offerConstraintsList) ||
|
||||
((offerOptions && offerOptions.offerToReceiveVideo) ? 1 : 0);
|
||||
|
||||
var numDataTracks = this.dataChannels.length;
|
||||
var numExpectedTransports = numAudioTracks + numVideoTracks;
|
||||
if (!testOptions.rtcpmux) {
|
||||
numExpectedTransports *= 2;
|
||||
}
|
||||
|
||||
var numAudioVideoDataTracks = numAudioTracks + numVideoTracks + numDataTracks;
|
||||
info("expected audio + video + data tracks: " + numAudioVideoDataTracks);
|
||||
is(numAudioVideoDataTracks, numIceConnections, "stats ICE connections matches expected A/V tracks");
|
||||
if (this.dataChannels.length) {
|
||||
++numExpectedTransports;
|
||||
}
|
||||
|
||||
info("expected audio + video + data transports: " + numExpectedTransports);
|
||||
is(numIceConnections, numExpectedTransports, "stats ICE connections matches expected A/V transports");
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1860,7 +1825,8 @@ var scriptsReady = Promise.all([
|
||||
"templates.js",
|
||||
"turnConfig.js",
|
||||
"dataChannel.js",
|
||||
"network.js"
|
||||
"network.js",
|
||||
"sdpUtils.js"
|
||||
].map(script => {
|
||||
var el = document.createElement("script");
|
||||
if (typeof scriptRelativePath === 'string' && script.charAt(0) !== '/') {
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
/* 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/. */
|
||||
|
||||
var sdputils = {
|
||||
|
||||
checkSdpAfterEndOfTrickle: function(sdp, testOptions, label) {
|
||||
info("EOC-SDP: " + JSON.stringify(sdp));
|
||||
|
||||
ok(sdp.sdp.includes("a=end-of-candidates"), label + ": SDP contains end-of-candidates");
|
||||
sdputils.checkSdpCLineNotDefault(sdp.sdp, label);
|
||||
|
||||
if (testOptions.rtcpmux) {
|
||||
ok(sdp.sdp.includes("a=rtcp-mux"), label + ": SDP contains rtcp-mux");
|
||||
} else {
|
||||
ok(sdp.sdp.includes("a=rtcp:"), label + ": SDP contains rtcp port");
|
||||
}
|
||||
},
|
||||
|
||||
// takes sdp in string form (or possibly a fragment, say an m-section), and
|
||||
// verifies that the default 0.0.0.0 addr is not present.
|
||||
checkSdpCLineNotDefault: function(sdpStr, label) {
|
||||
info("CLINE-NO-DEFAULT-ADDR-SDP: " + JSON.stringify(sdpStr));
|
||||
ok(!sdpStr.includes("c=IN IP4 0.0.0.0"), label + ": SDP contains non-zero IP c line");
|
||||
},
|
||||
|
||||
// Also remove mode 0 if it's offered
|
||||
// Note, we don't bother removing the fmtp lines, which makes a good test
|
||||
// for some SDP parsing issues.
|
||||
removeVP8: function(sdp) {
|
||||
var updated_sdp = sdp.replace("a=rtpmap:120 VP8/90000\r\n","");
|
||||
updated_sdp = updated_sdp.replace("RTP/SAVPF 120 126 97\r\n","RTP/SAVPF 126 97\r\n");
|
||||
updated_sdp = updated_sdp.replace("RTP/SAVPF 120 126\r\n","RTP/SAVPF 126\r\n");
|
||||
updated_sdp = updated_sdp.replace("a=rtcp-fb:120 nack\r\n","");
|
||||
updated_sdp = updated_sdp.replace("a=rtcp-fb:120 nack pli\r\n","");
|
||||
updated_sdp = updated_sdp.replace("a=rtcp-fb:120 ccm fir\r\n","");
|
||||
return updated_sdp;
|
||||
},
|
||||
|
||||
removeRtcpMux: function(sdp) {
|
||||
return sdp.replace(/a=rtcp-mux\r\n/g,"");
|
||||
},
|
||||
|
||||
removeBundle: function(sdp) {
|
||||
return sdp.replace(/a=group:BUNDLE .*\r\n/g, "");
|
||||
},
|
||||
|
||||
verifySdp: function(desc, expectedType, offerConstraintsList, offerOptions,
|
||||
testOptions) {
|
||||
info("Examining this SessionDescription: " + JSON.stringify(desc));
|
||||
info("offerConstraintsList: " + JSON.stringify(offerConstraintsList));
|
||||
info("offerOptions: " + JSON.stringify(offerOptions));
|
||||
ok(desc, "SessionDescription is not null");
|
||||
is(desc.type, expectedType, "SessionDescription type is " + expectedType);
|
||||
ok(desc.sdp.length > 10, "SessionDescription body length is plausible");
|
||||
ok(desc.sdp.includes("a=ice-ufrag"), "ICE username is present in SDP");
|
||||
ok(desc.sdp.includes("a=ice-pwd"), "ICE password is present in SDP");
|
||||
ok(desc.sdp.includes("a=fingerprint"), "ICE fingerprint is present in SDP");
|
||||
//TODO: update this for loopback support bug 1027350
|
||||
ok(!desc.sdp.includes(LOOPBACK_ADDR), "loopback interface is absent from SDP");
|
||||
var requiresTrickleIce = !desc.sdp.includes("a=candidate");
|
||||
if (requiresTrickleIce) {
|
||||
info("at least one ICE candidate is present in SDP");
|
||||
} else {
|
||||
info("No ICE candidate in SDP -> requiring trickle ICE");
|
||||
}
|
||||
|
||||
//TODO: how can we check for absence/presence of m=application?
|
||||
|
||||
var audioTracks =
|
||||
sdputils.countTracksInConstraint('audio', offerConstraintsList) ||
|
||||
((offerOptions && offerOptions.offerToReceiveAudio) ? 1 : 0);
|
||||
|
||||
info("expected audio tracks: " + audioTracks);
|
||||
if (audioTracks == 0) {
|
||||
ok(!desc.sdp.includes("m=audio"), "audio m-line is absent from SDP");
|
||||
} else {
|
||||
ok(desc.sdp.includes("m=audio"), "audio m-line is present in SDP");
|
||||
ok(desc.sdp.includes("a=rtpmap:109 opus/48000/2"), "OPUS codec is present in SDP");
|
||||
//TODO: ideally the rtcp-mux should be for the m=audio, and not just
|
||||
// anywhere in the SDP (JS SDP parser bug 1045429)
|
||||
is(testOptions.rtcpmux, desc.sdp.includes("a=rtcp-mux"), "RTCP Mux is offered in SDP");
|
||||
}
|
||||
|
||||
var videoTracks =
|
||||
sdputils.countTracksInConstraint('video', offerConstraintsList) ||
|
||||
((offerOptions && offerOptions.offerToReceiveVideo) ? 1 : 0);
|
||||
|
||||
info("expected video tracks: " + videoTracks);
|
||||
if (videoTracks == 0) {
|
||||
ok(!desc.sdp.includes("m=video"), "video m-line is absent from SDP");
|
||||
} else {
|
||||
ok(desc.sdp.includes("m=video"), "video m-line is present in SDP");
|
||||
if (testOptions.h264) {
|
||||
ok(desc.sdp.includes("a=rtpmap:126 H264/90000"), "H.264 codec is present in SDP");
|
||||
} else {
|
||||
ok(desc.sdp.includes("a=rtpmap:120 VP8/90000"), "VP8 codec is present in SDP");
|
||||
}
|
||||
is(testOptions.rtcpmux, desc.sdp.includes("a=rtcp-mux"), "RTCP Mux is offered in SDP");
|
||||
}
|
||||
|
||||
return requiresTrickleIce;
|
||||
},
|
||||
|
||||
/**
|
||||
* Counts the amount of audio tracks in a given media constraint.
|
||||
*
|
||||
* @param constraints
|
||||
* The contraint to be examined.
|
||||
*/
|
||||
countTracksInConstraint: function(type, constraints) {
|
||||
if (!Array.isArray(constraints)) {
|
||||
return 0;
|
||||
}
|
||||
return constraints.reduce((sum, c) => sum + (c[type] ? 1 : 0), 0);
|
||||
},
|
||||
|
||||
};
|
||||
@@ -208,20 +208,10 @@ var commandsGetUserMedia = [
|
||||
var commandsPeerConnectionOfferAnswer = [
|
||||
function PC_LOCAL_SETUP_ICE_HANDLER(test) {
|
||||
test.pcLocal.setupIceCandidateHandler(test);
|
||||
if (test.steeplechase) {
|
||||
test.pcLocal.endOfTrickleIce.then(() => {
|
||||
send_message({"type": "end_of_trickle_ice"});
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
function PC_REMOTE_SETUP_ICE_HANDLER(test) {
|
||||
test.pcRemote.setupIceCandidateHandler(test);
|
||||
if (test.steeplechase) {
|
||||
test.pcRemote.endOfTrickleIce.then(() => {
|
||||
send_message({"type": "end_of_trickle_ice"});
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
function PC_LOCAL_STEEPLECHASE_SIGNAL_EXPECTED_LOCAL_TRACKS(test) {
|
||||
@@ -316,15 +306,17 @@ var commandsPeerConnectionOfferAnswer = [
|
||||
},
|
||||
|
||||
function PC_LOCAL_SANE_LOCAL_SDP(test) {
|
||||
test.pcLocal.verifySdp(test._local_offer, "offer",
|
||||
test._offer_constraints, test._offer_options,
|
||||
true);
|
||||
test.pcLocal.localRequiresTrickleIce =
|
||||
sdputils.verifySdp(test._local_offer, "offer",
|
||||
test._offer_constraints, test._offer_options,
|
||||
test.testOptions);
|
||||
},
|
||||
|
||||
function PC_REMOTE_SANE_REMOTE_SDP(test) {
|
||||
test.pcRemote.verifySdp(test._local_offer, "offer",
|
||||
test._offer_constraints, test._offer_options,
|
||||
false);
|
||||
test.pcRemote.remoteRequiresTrickleIce =
|
||||
sdputils.verifySdp(test._local_offer, "offer",
|
||||
test._offer_constraints, test._offer_options,
|
||||
test.testOptions);
|
||||
},
|
||||
|
||||
function PC_REMOTE_CREATE_ANSWER(test) {
|
||||
@@ -342,46 +334,6 @@ var commandsPeerConnectionOfferAnswer = [
|
||||
});
|
||||
},
|
||||
|
||||
function PC_REMOTE_CHECK_FOR_DUPLICATED_PORTS_IN_SDP(test) {
|
||||
var re = /a=candidate.* (UDP|TCP) [\d]+ ([\d\.]+) ([\d]+) typ host/g;
|
||||
|
||||
var _sdpCandidatesIntoArray = sdp => {
|
||||
var regexArray = [];
|
||||
var resultArray = [];
|
||||
while ((regexArray = re.exec(sdp)) !== null) {
|
||||
info("regexArray: " + regexArray);
|
||||
if ((regexArray[1] === "TCP") && (regexArray[3] === "9")) {
|
||||
// As both sides can advertise TCP active connection on port 9 lets
|
||||
// ignore them all together
|
||||
info("Ignoring TCP candidate on port 9");
|
||||
continue;
|
||||
}
|
||||
var triple = regexArray[1] + ":" + regexArray[2] + ":" + regexArray[3];
|
||||
info("triple: " + triple);
|
||||
if (resultArray.indexOf(triple) !== -1) {
|
||||
dump("SDP: " + sdp.replace(/[\r]/g, '') + "\n");
|
||||
ok(false, "This Transport:IP:Port " + triple + " appears twice in the SDP above!");
|
||||
}
|
||||
resultArray.push(triple);
|
||||
}
|
||||
return resultArray;
|
||||
};
|
||||
|
||||
var offerTriples = _sdpCandidatesIntoArray(test._local_offer.sdp);
|
||||
info("Offer ICE host candidates: " + JSON.stringify(offerTriples));
|
||||
|
||||
var answerTriples = _sdpCandidatesIntoArray(test.originalAnswer.sdp);
|
||||
info("Answer ICE host candidates: " + JSON.stringify(answerTriples));
|
||||
|
||||
offerTriples.forEach(o => {
|
||||
if (answerTriples.indexOf(o) !== -1) {
|
||||
dump("SDP offer: " + test._local_offer.sdp.replace(/[\r]/g, '') + "\n");
|
||||
dump("SDP answer: " + test.originalAnswer.sdp.replace(/[\r]/g, '') + "\n");
|
||||
ok(false, "This IP:Port " + o + " appears in SDP offer and answer!");
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
function PC_REMOTE_SET_LOCAL_DESCRIPTION(test) {
|
||||
return test.setLocalDescription(test.pcRemote, test.originalAnswer, STABLE)
|
||||
.then(() => {
|
||||
@@ -412,14 +364,16 @@ var commandsPeerConnectionOfferAnswer = [
|
||||
});
|
||||
},
|
||||
function PC_REMOTE_SANE_LOCAL_SDP(test) {
|
||||
test.pcRemote.verifySdp(test._remote_answer, "answer",
|
||||
test._offer_constraints, test._offer_options,
|
||||
true);
|
||||
test.pcRemote.localRequiresTrickleIce =
|
||||
sdputils.verifySdp(test._remote_answer, "answer",
|
||||
test._offer_constraints, test._offer_options,
|
||||
test.testOptions);
|
||||
},
|
||||
function PC_LOCAL_SANE_REMOTE_SDP(test) {
|
||||
test.pcLocal.verifySdp(test._remote_answer, "answer",
|
||||
test._offer_constraints, test._offer_options,
|
||||
false);
|
||||
test.pcLocal.remoteRequiresTrickleIce =
|
||||
sdputils.verifySdp(test._remote_answer, "answer",
|
||||
test._offer_constraints, test._offer_options,
|
||||
test.testOptions);
|
||||
},
|
||||
|
||||
function PC_LOCAL_WAIT_FOR_ICE_CONNECTED(test) {
|
||||
@@ -483,7 +437,7 @@ var commandsPeerConnectionOfferAnswer = [
|
||||
test.pcLocal.checkStatsIceConnections(stats,
|
||||
test._offer_constraints,
|
||||
test._offer_options,
|
||||
test._remote_answer);
|
||||
test.testOptions);
|
||||
});
|
||||
},
|
||||
|
||||
@@ -492,7 +446,7 @@ var commandsPeerConnectionOfferAnswer = [
|
||||
test.pcRemote.checkStatsIceConnections(stats,
|
||||
test._offer_constraints,
|
||||
test._offer_options,
|
||||
test.originalAnswer);
|
||||
test.testOptions);
|
||||
});
|
||||
},
|
||||
|
||||
@@ -509,22 +463,46 @@ var commandsPeerConnectionOfferAnswer = [
|
||||
function PC_REMOTE_CHECK_STATS(test) {
|
||||
return checkAllTrackStats(test.pcRemote);
|
||||
},
|
||||
function PC_LOCAL_WAIT_FOR_END_OF_TRICKLE(test) {
|
||||
return test.pcLocal.endOfTrickleIce;
|
||||
function PC_LOCAL_VERIFY_SDP_AFTER_END_OF_TRICKLE(test) {
|
||||
/* In case the endOfTrickleSdp promise is resolved already it will win the
|
||||
* race because it gets evaluated first. But if endOfTrickleSdp is still
|
||||
* pending the rejection will win the race. */
|
||||
return Promise.race([
|
||||
test.pcLocal.endOfTrickleSdp,
|
||||
Promise.reject("No SDP")
|
||||
])
|
||||
.then(sdp => sdputils.checkSdpAfterEndOfTrickle(sdp, test.testOptions, test.pcLocal.label),
|
||||
() => info("pcLocal: Gathering is not complete yet, skipping post-gathering SDP check"));
|
||||
},
|
||||
function PC_REMOTE_WAIT_FOR_END_OF_TRICKLE(test) {
|
||||
return test.pcRemote.endOfTrickleIce;
|
||||
function PC_REMOTE_VERIFY_SDP_AFTER_END_OF_TRICKLE(test) {
|
||||
/* In case the endOfTrickleSdp promise is resolved already it will win the
|
||||
* race because it gets evaluated first. But if endOfTrickleSdp is still
|
||||
* pending the rejection will win the race. */
|
||||
return Promise.race([
|
||||
test.pcRemote.endOfTrickleSdp,
|
||||
Promise.reject("No SDP")
|
||||
])
|
||||
.then(sdp => sdputils.checkSdpAfterEndOfTrickle(sdp, test.testOptions, test.pcRemote.label),
|
||||
() => info("pcRemote: Gathering is not complete yet, skipping post-gathering SDP check"));
|
||||
}
|
||||
];
|
||||
|
||||
function PC_LOCAL_REMOVE_VP8_FROM_OFFER(test) {
|
||||
isnot(test.originalOffer.sdp.search("H264/90000"), -1, "H.264 should be present in the SDP offer");
|
||||
test.originalOffer.sdp = sdputils.removeVP8(test.originalOffer.sdp);
|
||||
info("Updated H264 only offer: " + JSON.stringify(test.originalOffer));
|
||||
};
|
||||
|
||||
function PC_LOCAL_REMOVE_BUNDLE_FROM_OFFER(test) {
|
||||
test.originalOffer.sdp = test.originalOffer.sdp.replace(
|
||||
/a=group:BUNDLE .*\r\n/g,
|
||||
""
|
||||
);
|
||||
test.originalOffer.sdp = sdputils.removeBundle(test.originalOffer.sdp);
|
||||
info("Updated no bundle offer: " + JSON.stringify(test.originalOffer));
|
||||
};
|
||||
|
||||
function PC_LOCAL_REMOVE_RTCPMUX_FROM_OFFER(test) {
|
||||
test.originalOffer.sdp = sdputils.removeRtcpMux(test.originalOffer.sdp);
|
||||
info("Updated no RTCP-Mux offer: " + JSON.stringify(test.originalOffer));
|
||||
};
|
||||
|
||||
var addRenegotiation = (chain, commands, checks) => {
|
||||
chain.append(commands);
|
||||
chain.append(commandsPeerConnectionOfferAnswer);
|
||||
|
||||
@@ -12,17 +12,11 @@
|
||||
});
|
||||
|
||||
var test;
|
||||
runNetworkTest(function () {
|
||||
test = new PeerConnectionTest();
|
||||
runNetworkTest(function (options) {
|
||||
options = options || { };
|
||||
options.bundle = false;
|
||||
test = new PeerConnectionTest(options);
|
||||
addInitialDataChannel(test.chain);
|
||||
test.chain.insertAfter("PC_LOCAL_CREATE_OFFER", [
|
||||
function PC_LOCAL_REMOVE_BUNDLE_FROM_OFFER(test) {
|
||||
// Just replace a=group:BUNDLE with something that will be ignored.
|
||||
test.originalOffer.sdp = test.originalOffer.sdp.replace(
|
||||
"a=group:BUNDLE",
|
||||
"a=foo:");
|
||||
}
|
||||
]);
|
||||
test.setMediaConstraints([{audio: true}, {video: true}],
|
||||
[{audio: true}, {video: true}]);
|
||||
test.run();
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
|
||||
var test;
|
||||
runNetworkTest(function (options) {
|
||||
options = options || { };
|
||||
options.bundle = false;
|
||||
test = new PeerConnectionTest(options);
|
||||
addRenegotiation(test.chain,
|
||||
commandsCreateDataChannel.concat(
|
||||
@@ -27,9 +29,6 @@
|
||||
),
|
||||
commandsCheckDataChannel);
|
||||
|
||||
test.chain.insertAfterEach('PC_LOCAL_CREATE_OFFER',
|
||||
PC_LOCAL_REMOVE_BUNDLE_FROM_OFFER);
|
||||
|
||||
// Insert before the second PC_LOCAL_CHECK_MEDIA_TRACKS
|
||||
test.chain.insertBefore('PC_LOCAL_CHECK_MEDIA_TRACKS',
|
||||
commandsWaitForDataChannel,
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
|
||||
var test;
|
||||
runNetworkTest(function (options) {
|
||||
options = options || { };
|
||||
options.bundle = false;
|
||||
test = new PeerConnectionTest(options);
|
||||
addRenegotiation(test.chain,
|
||||
[
|
||||
@@ -30,9 +32,6 @@
|
||||
]
|
||||
);
|
||||
|
||||
test.chain.insertAfterEach('PC_LOCAL_CREATE_OFFER',
|
||||
PC_LOCAL_REMOVE_BUNDLE_FROM_OFFER);
|
||||
|
||||
// TODO(bug 1093835): figure out how to verify if media flows through the new stream
|
||||
test.setMediaConstraints([{audio: true}], [{audio: true}]);
|
||||
test.run();
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
|
||||
var test;
|
||||
runNetworkTest(function (options) {
|
||||
options = options || { };
|
||||
options.bundle = false;
|
||||
test = new PeerConnectionTest(options);
|
||||
addRenegotiation(test.chain,
|
||||
[
|
||||
@@ -30,9 +32,6 @@
|
||||
]
|
||||
);
|
||||
|
||||
test.chain.insertAfterEach('PC_LOCAL_CREATE_OFFER',
|
||||
PC_LOCAL_REMOVE_BUNDLE_FROM_OFFER);
|
||||
|
||||
// TODO(bug 1093835): figure out how to verify if media flows through the new stream
|
||||
test.setMediaConstraints([{video: true}], [{video: true}]);
|
||||
test.run();
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
createHTML({
|
||||
bug: "1167443",
|
||||
title: "Basic audio-only peer connection which waits for end-of-candidates"
|
||||
});
|
||||
|
||||
var test;
|
||||
runNetworkTest(function (options) {
|
||||
test = new PeerConnectionTest(options);
|
||||
test.chain.replace("PC_LOCAL_VERIFY_SDP_AFTER_END_OF_TRICKLE", [
|
||||
function PC_LOCAL_REQUIRE_SDP_AFTER_END_OF_TRICKLE(test) {
|
||||
return test.pcLocal.endOfTrickleSdp.then(sdp =>
|
||||
sdputils.checkSdpAfterEndOfTrickle(sdp, test.testOptions, test.pcLocal.label));
|
||||
}
|
||||
]);
|
||||
test.chain.replace("PC_REMOTE_VERIFY_SDP_AFTER_END_OF_TRICKLE", [
|
||||
function PC_REMOTE_REQUIRE_SDP_AFTER_END_OF_TRICKLE(test) {
|
||||
return test.pcRemote.endOfTrickleSdp.then(sdp =>
|
||||
sdputils.checkSdpAfterEndOfTrickle(sdp, test.testOptions, test.pcRemote.label));
|
||||
}
|
||||
]);
|
||||
test.setMediaConstraints([{audio: true}], [{audio: true}]);
|
||||
test.run();
|
||||
});
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
@@ -12,10 +12,9 @@
|
||||
});
|
||||
|
||||
runNetworkTest(options => {
|
||||
options = options || { };
|
||||
options.bundle = false;
|
||||
var test = new PeerConnectionTest(options);
|
||||
test.chain.insertAfter(
|
||||
'PC_LOCAL_CREATE_OFFER',
|
||||
[PC_LOCAL_REMOVE_BUNDLE_FROM_OFFER]);
|
||||
test.setMediaConstraints([{audio: true}, {video: true}],
|
||||
[{audio: true}, {video: true}]);
|
||||
test.run();
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
createHTML({
|
||||
bug: "1167443",
|
||||
title: "Basic audio & video call with disabled bundle and disbaled RTCP-Mux"
|
||||
});
|
||||
|
||||
var test;
|
||||
runNetworkTest(function (options) {
|
||||
options = options || { };
|
||||
options.bundle = false;
|
||||
options.rtcpmux = false;
|
||||
test = new PeerConnectionTest(options);
|
||||
test.chain.replace("PC_LOCAL_VERIFY_SDP_AFTER_END_OF_TRICKLE", [
|
||||
function PC_LOCAL_REQUIRE_SDP_AFTER_END_OF_TRICKLE(test) {
|
||||
return test.pcLocal.endOfTrickleSdp .then(sdp =>
|
||||
sdputils.checkSdpAfterEndOfTrickle(sdp, test.testOptions, test.pcLocal.label));
|
||||
}
|
||||
]);
|
||||
test.chain.replace("PC_REMOTE_VERIFY_SDP_AFTER_END_OF_TRICKLE", [
|
||||
function PC_REMOTE_REQUIRE_SDP_AFTER_END_OF_TRICKLE(test) {
|
||||
return test.pcRemote.endOfTrickleSdp .then(sdp =>
|
||||
sdputils.checkSdpAfterEndOfTrickle(sdp, test.testOptions, test.pcRemote.label));
|
||||
}
|
||||
]);
|
||||
test.setMediaConstraints([{audio: true}, {video: true}],
|
||||
[{audio: true}, {video: true}]);
|
||||
test.run();
|
||||
});
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,38 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
createHTML({
|
||||
bug: "1167443",
|
||||
title: "Basic audio & video call with disabled RTCP-Mux"
|
||||
});
|
||||
|
||||
var test;
|
||||
runNetworkTest(function (options) {
|
||||
options = options || { };
|
||||
options.rtcpmux = false;
|
||||
test = new PeerConnectionTest(options);
|
||||
test.chain.replace("PC_LOCAL_VERIFY_SDP_AFTER_END_OF_TRICKLE", [
|
||||
function PC_LOCAL_REQUIRE_SDP_AFTER_END_OF_TRICKLE(test) {
|
||||
return test.pcLocal.endOfTrickleSdp .then(sdp =>
|
||||
sdputils.checkSdpAfterEndOfTrickle(sdp, test.testOptions, test.pcLocal.label));
|
||||
}
|
||||
]);
|
||||
test.chain.replace("PC_REMOTE_VERIFY_SDP_AFTER_END_OF_TRICKLE", [
|
||||
function PC_REMOTE_REQUIRE_SDP_AFTER_END_OF_TRICKLE(test) {
|
||||
return test.pcRemote.endOfTrickleSdp .then(sdp =>
|
||||
sdputils.checkSdpAfterEndOfTrickle(sdp, test.testOptions, test.pcRemote.label));
|
||||
}
|
||||
]);
|
||||
test.setMediaConstraints([{audio: true}, {video: true}],
|
||||
[{audio: true}, {video: true}]);
|
||||
test.run();
|
||||
});
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
@@ -22,10 +22,7 @@ SpeechStreamListener::~SpeechStreamListener()
|
||||
nsCOMPtr<nsIThread> mainThread;
|
||||
NS_GetMainThread(getter_AddRefs(mainThread));
|
||||
|
||||
SpeechRecognition* forgottenRecognition = nullptr;
|
||||
mRecognition.swap(forgottenRecognition);
|
||||
NS_ProxyRelease(mainThread,
|
||||
static_cast<DOMEventTargetHelper*>(forgottenRecognition));
|
||||
NS_ProxyRelease(mainThread, mRecognition.forget());
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -35,7 +35,7 @@ interface IDBDatabase : EventTarget {
|
||||
};
|
||||
|
||||
partial interface IDBDatabase {
|
||||
[Func="mozilla::dom::indexedDB::IndexedDatabaseManager::ExperimentalFeaturesEnabled"]
|
||||
[Func="mozilla::dom::IndexedDatabaseManager::ExperimentalFeaturesEnabled"]
|
||||
readonly attribute StorageType storage;
|
||||
|
||||
[Exposed=Window, Throws]
|
||||
|
||||
@@ -32,10 +32,10 @@ interface IDBIndex {
|
||||
// <null>: Not locale-aware, uses normal JS sorting.
|
||||
// <string>: Sorted based on the rules of the specified locale.
|
||||
// Note: never returns "auto", only the current locale.
|
||||
[Func="mozilla::dom::indexedDB::IndexedDatabaseManager::ExperimentalFeaturesEnabled"]
|
||||
[Func="mozilla::dom::IndexedDatabaseManager::ExperimentalFeaturesEnabled"]
|
||||
readonly attribute DOMString? locale;
|
||||
|
||||
[Func="mozilla::dom::indexedDB::IndexedDatabaseManager::ExperimentalFeaturesEnabled"]
|
||||
[Func="mozilla::dom::IndexedDatabaseManager::ExperimentalFeaturesEnabled"]
|
||||
readonly attribute boolean isAutoLocale;
|
||||
|
||||
[Throws]
|
||||
@@ -56,16 +56,14 @@ interface IDBIndex {
|
||||
|
||||
partial interface IDBIndex {
|
||||
[Throws]
|
||||
IDBRequest mozGetAll (optional any key, optional unsigned long limit);
|
||||
IDBRequest mozGetAll (optional any key, [EnforceRange] optional unsigned long limit);
|
||||
|
||||
[Throws]
|
||||
IDBRequest mozGetAllKeys (optional any key, optional unsigned long limit);
|
||||
IDBRequest mozGetAllKeys (optional any key, [EnforceRange] optional unsigned long limit);
|
||||
|
||||
[Throws,
|
||||
Func="mozilla::dom::indexedDB::IndexedDatabaseManager::ExperimentalFeaturesEnabled"]
|
||||
IDBRequest getAll (optional any key, optional unsigned long limit);
|
||||
[Throws]
|
||||
IDBRequest getAll (optional any key, [EnforceRange] optional unsigned long limit);
|
||||
|
||||
[Throws,
|
||||
Func="mozilla::dom::indexedDB::IndexedDatabaseManager::ExperimentalFeaturesEnabled"]
|
||||
IDBRequest getAllKeys (optional any key, optional unsigned long limit);
|
||||
[Throws]
|
||||
IDBRequest getAllKeys (optional any key, [EnforceRange] optional unsigned long limit);
|
||||
};
|
||||
|
||||
@@ -30,7 +30,7 @@ interface IDBKeyRange {
|
||||
};
|
||||
|
||||
[Exposed=(Window,Worker),
|
||||
Func="mozilla::dom::indexedDB::IndexedDatabaseManager::ExperimentalFeaturesEnabled"]
|
||||
Func="mozilla::dom::IndexedDatabaseManager::ExperimentalFeaturesEnabled"]
|
||||
interface IDBLocaleAwareKeyRange : IDBKeyRange {
|
||||
[NewObject, Throws]
|
||||
static IDBLocaleAwareKeyRange bound (any lower, any upper, optional boolean lowerOpen = false, optional boolean upperOpen = false);
|
||||
|
||||
@@ -63,17 +63,14 @@ interface IDBObjectStore {
|
||||
partial interface IDBObjectStore {
|
||||
// Success fires IDBTransactionEvent, result == array of values for given keys
|
||||
[Throws]
|
||||
IDBRequest mozGetAll (optional any key, optional unsigned long limit);
|
||||
IDBRequest mozGetAll (optional any key, [EnforceRange] optional unsigned long limit);
|
||||
|
||||
[Throws,
|
||||
Func="mozilla::dom::indexedDB::IndexedDatabaseManager::ExperimentalFeaturesEnabled"]
|
||||
IDBRequest getAll (optional any key, optional unsigned long limit);
|
||||
[Throws]
|
||||
IDBRequest getAll (optional any key, [EnforceRange] optional unsigned long limit);
|
||||
|
||||
[Throws,
|
||||
Func="mozilla::dom::indexedDB::IndexedDatabaseManager::ExperimentalFeaturesEnabled"]
|
||||
IDBRequest getAllKeys (optional any key, optional unsigned long limit);
|
||||
[Throws]
|
||||
IDBRequest getAllKeys (optional any key, [EnforceRange] optional unsigned long limit);
|
||||
|
||||
[Throws,
|
||||
Func="mozilla::dom::indexedDB::IndexedDatabaseManager::ExperimentalFeaturesEnabled"]
|
||||
[Throws]
|
||||
IDBRequest openKeyCursor (optional any range, optional IDBCursorDirection direction = "next");
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user