From 5763d2ceb269bb829974f6cac7e3d7ffa317b66b Mon Sep 17 00:00:00 2001 From: Honza Bambas Date: Fri, 16 Aug 2013 11:34:21 +0200 Subject: [PATCH] Bug 892488 - Get rid of the offline application cache prompt, r=ehsan+jonas --- browser/base/content/test/Makefile.in | 1 + .../test/browser_offlineQuotaNotification.js | 2 + browser/base/content/test/offlineByDefault.js | 17 +++ .../test/test_offlineNotification.html | 3 + .../base/content/test/test_offline_gzip.html | 2 + content/base/public/nsContentUtils.h | 6 + content/base/src/nsContentSink.cpp | 7 +- content/base/src/nsContentUtils.cpp | 32 +++++ dom/src/offline/nsDOMOfflineResourceList.cpp | 48 +++++-- dom/src/offline/nsDOMOfflineResourceList.h | 1 - .../offline/460353_iframe_samemanifest.html | 4 + dom/tests/mochitest/ajax/offline/bypass.html | 3 +- .../mochitest/ajax/offline/foreign2.html | 36 +++-- .../mochitest/ajax/offline/offlineChild.html | 2 +- .../mochitest/ajax/offline/offlineTests.js | 135 ++++++++++++++---- .../ajax/offline/test_badManifestMagic.html | 3 +- .../ajax/offline/test_bug445544.html | 3 +- .../ajax/offline/test_bug460353.html | 23 ++- .../ajax/offline/test_bug474696.html | 7 +- .../ajax/offline/test_bug544462.html | 3 +- .../ajax/offline/test_bug744719-cancel.html | 70 +++++---- .../ajax/offline/test_bug744719.html | 8 +- .../ajax/offline/test_bug765203.html | 3 +- .../ajax/offline/test_cancelOfflineCache.html | 7 +- .../ajax/offline/test_changingManifest.html | 3 +- .../mochitest/ajax/offline/test_fallback.html | 3 +- .../mochitest/ajax/offline/test_foreign.html | 12 +- .../ajax/offline/test_identicalManifest.html | 3 +- .../ajax/offline/test_lowDeviceStorage.html | 4 +- .../test_lowDeviceStorageDuringUpdate.html | 3 +- .../ajax/offline/test_missingFile.html | 3 +- .../ajax/offline/test_offlineIFrame.html | 3 +- .../ajax/offline/test_offlineMode.html | 3 +- .../mochitest/ajax/offline/test_overlap.html | 3 +- .../ajax/offline/test_redirectManifest.html | 3 +- .../ajax/offline/test_redirectUpdateItem.html | 3 +- .../ajax/offline/test_refetchManifest.html | 3 +- .../ajax/offline/test_simpleManifest.html | 3 +- .../ajax/offline/test_updateCheck.html | 3 +- .../ajax/offline/test_updatingManifest.html | 19 +-- .../ajax/offline/test_xhtmlManifest.xhtml | 3 +- .../android/base/tests/testDoorHanger.java.in | 61 ++++++++ modules/libpref/src/init/all.js | 2 + .../prefetch/nsOfflineCacheUpdateService.cpp | 14 +- 44 files changed, 400 insertions(+), 180 deletions(-) create mode 100644 browser/base/content/test/offlineByDefault.js diff --git a/browser/base/content/test/Makefile.in b/browser/base/content/test/Makefile.in index 079740754707..cefbe50bfdd5 100644 --- a/browser/base/content/test/Makefile.in +++ b/browser/base/content/test/Makefile.in @@ -36,6 +36,7 @@ MOCHITEST_FILES = \ test_offline_gzip.html \ test_offlineNotification.html \ video.ogg \ + offlineByDefault.js \ $(NULL) # test_contextmenu.html and test_contextmenu_input are disabled on Linux due to bug 513558 diff --git a/browser/base/content/test/browser_offlineQuotaNotification.js b/browser/base/content/test/browser_offlineQuotaNotification.js index a8aba6b9730f..507600d30499 100644 --- a/browser/base/content/test/browser_offlineQuotaNotification.js +++ b/browser/base/content/test/browser_offlineQuotaNotification.js @@ -14,6 +14,7 @@ registerCleanupFunction(function() { var principal = Services.scriptSecurityManager.getNoAppCodebasePrincipal(uri); Services.perms.removeFromPrincipal(principal, "offline-app"); Services.prefs.clearUserPref("offline-apps.quota.warn"); + Services.prefs.clearUserPref("offline-apps.allow_by_default"); }); // Check that the "preferences" UI is opened and showing which websites have @@ -70,5 +71,6 @@ function test() { PopupNotifications.panel.firstElementChild.button.click(); }, true); + Services.prefs.setBoolPref("offline-apps.allow_by_default", false); gBrowser.contentWindow.location = URL; } diff --git a/browser/base/content/test/offlineByDefault.js b/browser/base/content/test/offlineByDefault.js new file mode 100644 index 000000000000..72f7e52a01bc --- /dev/null +++ b/browser/base/content/test/offlineByDefault.js @@ -0,0 +1,17 @@ +var offlineByDefault = { + defaultValue: false, + prefBranch: SpecialPowers.Cc["@mozilla.org/preferences-service;1"].getService(SpecialPowers.Ci.nsIPrefBranch), + set: function(allow) { + try { + this.defaultValue = this.prefBranch.getBoolPref("offline-apps.allow_by_default"); + } catch (e) { + this.defaultValue = false + } + this.prefBranch.setBoolPref("offline-apps.allow_by_default", allow); + }, + reset: function() { + this.prefBranch.setBoolPref("offline-apps.allow_by_default", this.defaultValue); + } +} + +offlineByDefault.set(false); diff --git a/browser/base/content/test/test_offlineNotification.html b/browser/base/content/test/test_offlineNotification.html index 8c603f15061e..ad015a8623eb 100644 --- a/browser/base/content/test/test_offlineNotification.html +++ b/browser/base/content/test/test_offlineNotification.html @@ -6,6 +6,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=462856 Test offline app notification + @@ -52,6 +53,8 @@ window.addEventListener("message", function(event) { pm.removeFromPrincipal(principal1, "offline-app"); pm.removeFromPrincipal(principal2, "offline-app"); + offlineByDefault.reset(); + SimpleTest.finish(); } }, false); diff --git a/browser/base/content/test/test_offline_gzip.html b/browser/base/content/test/test_offline_gzip.html index 09713da92ed9..1b4a6129961e 100644 --- a/browser/base/content/test/test_offline_gzip.html +++ b/browser/base/content/test/test_offline_gzip.html @@ -13,6 +13,7 @@ cache, it can be fetched from the cache successfully. src="/MochiKit/MochiKit.js"> + @@ -46,6 +47,7 @@ function finishTest() { window.removeEventListener("message", handleMessageEvents, false); + offlineByDefault.reset(); SimpleTest.finish(); } diff --git a/content/base/public/nsContentUtils.h b/content/base/public/nsContentUtils.h index 3044829a7f8c..383c1fdb84ca 100644 --- a/content/base/public/nsContentUtils.h +++ b/content/base/public/nsContentUtils.h @@ -1503,6 +1503,12 @@ public: */ static bool OfflineAppAllowed(nsIPrincipal *aPrincipal); + /** + * If offline-apps.allow_by_default is true, we set offline-app permission + * for the principal and return true. Otherwise false. + */ + static bool MaybeAllowOfflineAppByDefault(nsIPrincipal *aPrincipal); + /** * Increases the count of blockers preventing scripts from running. * NOTE: You might want to use nsAutoScriptBlocker rather than calling diff --git a/content/base/src/nsContentSink.cpp b/content/base/src/nsContentSink.cpp index af7deb997d20..ad4c1c843e09 100644 --- a/content/base/src/nsContentSink.cpp +++ b/content/base/src/nsContentSink.cpp @@ -1061,8 +1061,11 @@ nsContentSink::ProcessOfflineManifest(const nsAString& aManifestSpec) action = CACHE_SELECTION_RESELECT_WITHOUT_MANIFEST; } else { - // Only continue if the document has permission to use offline APIs. - if (!nsContentUtils::OfflineAppAllowed(mDocument->NodePrincipal())) { + // Only continue if the document has permission to use offline APIs or + // when preferences indicate to permit it automatically. + if (!nsContentUtils::OfflineAppAllowed(mDocument->NodePrincipal()) && + !nsContentUtils::MaybeAllowOfflineAppByDefault(mDocument->NodePrincipal()) && + !nsContentUtils::OfflineAppAllowed(mDocument->NodePrincipal())) { return; } diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp index c39ef5b8b6db..9f40892233fe 100644 --- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -1405,6 +1405,38 @@ nsContentUtils::OfflineAppAllowed(nsIPrincipal *aPrincipal) return NS_SUCCEEDED(rv) && allowed; } +bool +nsContentUtils::MaybeAllowOfflineAppByDefault(nsIPrincipal *aPrincipal) +{ + if (!Preferences::GetRootBranch()) + return false; + + nsresult rv; + + bool allowedByDefault; + rv = Preferences::GetRootBranch()->GetBoolPref( + "offline-apps.allow_by_default", &allowedByDefault); + if (NS_FAILED(rv)) + return false; + + if (!allowedByDefault) + return false; + + nsCOMPtr permissionManager = + do_GetService(NS_PERMISSIONMANAGER_CONTRACTID); + if (!permissionManager) + return false; + + rv = permissionManager->AddFromPrincipal( + aPrincipal, "offline-app", nsIPermissionManager::ALLOW_ACTION, + nsIPermissionManager::EXPIRE_NEVER, 0); + if (NS_FAILED(rv)) + return false; + + // We have added the permission + return true; +} + // static void nsContentUtils::Shutdown() diff --git a/dom/src/offline/nsDOMOfflineResourceList.cpp b/dom/src/offline/nsDOMOfflineResourceList.cpp index fa4811db5b5f..e6de4f4babce 100644 --- a/dom/src/offline/nsDOMOfflineResourceList.cpp +++ b/dom/src/offline/nsDOMOfflineResourceList.cpp @@ -84,7 +84,6 @@ nsDOMOfflineResourceList::nsDOMOfflineResourceList(nsIURI *aManifestURI, , mManifestURI(aManifestURI) , mDocumentURI(aDocumentURI) , mExposeCacheUpdateStatus(true) - , mDontSetDocumentCache(false) , mStatus(nsIDOMOfflineResourceList::IDLE) , mCachedKeys(nullptr) , mCachedKeysCount(0) @@ -429,6 +428,11 @@ nsDOMOfflineResourceList::GetStatus(uint16_t *aStatus) } } + if (mAvailableApplicationCache) { + *aStatus = nsIDOMOfflineResourceList::UPDATEREADY; + return NS_OK; + } + *aStatus = mStatus; return NS_OK; } @@ -455,10 +459,6 @@ nsDOMOfflineResourceList::Update() window, getter_AddRefs(update)); NS_ENSURE_SUCCESS(rv, rv); - // Since we are invoking the cache update, cache on the document must not - // be updated until swapCache() method is called on applicationCache object. - mDontSetDocumentCache = true; - return NS_OK; } @@ -488,6 +488,8 @@ nsDOMOfflineResourceList::SwapCache() mAvailableApplicationCache->GetClientID(availClientId); if (availClientId == currClientId) return NS_ERROR_DOM_INVALID_STATE_ERR; + } else if (mStatus != OBSOLETE) { + return NS_ERROR_DOM_INVALID_STATE_ERR; } ClearCachedKeys(); @@ -629,16 +631,36 @@ nsDOMOfflineResourceList::UpdateStateChanged(nsIOfflineCacheUpdate *aUpdate, NS_IMETHODIMP nsDOMOfflineResourceList::ApplicationCacheAvailable(nsIApplicationCache *aApplicationCache) { - mAvailableApplicationCache = aApplicationCache; + nsCOMPtr currentAppCache = GetDocumentAppCache(); + if (currentAppCache) { + // Document already has a cache, we cannot override it. swapCache is + // here to do it on demand. - if (!mDontSetDocumentCache) { - nsCOMPtr appCacheContainer = - GetDocumentAppCacheContainer(); + // If the newly available cache is identical to the current cache, then + // just ignore this event. + if (aApplicationCache == currentAppCache) { + return NS_OK; + } - if (appCacheContainer) - appCacheContainer->SetApplicationCache(aApplicationCache); + nsCString currClientId, availClientId; + currentAppCache->GetClientID(currClientId); + aApplicationCache->GetClientID(availClientId); + if (availClientId == currClientId) { + return NS_OK; + } + + mAvailableApplicationCache = aApplicationCache; + return NS_OK; } + nsCOMPtr appCacheContainer = + GetDocumentAppCacheContainer(); + + if (appCacheContainer) { + appCacheContainer->SetApplicationCache(aApplicationCache); + } + + mAvailableApplicationCache = nullptr; return NS_OK; } @@ -737,14 +759,12 @@ nsDOMOfflineResourceList::UpdateCompleted(nsIOfflineCacheUpdate *aUpdate) mCacheUpdate->RemoveObserver(this); mCacheUpdate = nullptr; - mDontSetDocumentCache = false; if (NS_SUCCEEDED(rv) && succeeded && !partial) { + mStatus = nsIDOMOfflineResourceList::IDLE; if (isUpgrade) { - mStatus = nsIDOMOfflineResourceList::UPDATEREADY; SendEvent(NS_LITERAL_STRING(UPDATEREADY_STR)); } else { - mStatus = nsIDOMOfflineResourceList::IDLE; SendEvent(NS_LITERAL_STRING(CACHED_STR)); } } diff --git a/dom/src/offline/nsDOMOfflineResourceList.h b/dom/src/offline/nsDOMOfflineResourceList.h index eeb63d2c3a05..40858869cf76 100644 --- a/dom/src/offline/nsDOMOfflineResourceList.h +++ b/dom/src/offline/nsDOMOfflineResourceList.h @@ -157,7 +157,6 @@ private: nsCOMPtr mAvailableApplicationCache; nsCOMPtr mCacheUpdate; bool mExposeCacheUpdateStatus; - bool mDontSetDocumentCache; uint16_t mStatus; // The set of dynamic keys for this application cache object. diff --git a/dom/tests/mochitest/ajax/offline/460353_iframe_samemanifest.html b/dom/tests/mochitest/ajax/offline/460353_iframe_samemanifest.html index 556789792bed..de357827b6a2 100644 --- a/dom/tests/mochitest/ajax/offline/460353_iframe_samemanifest.html +++ b/dom/tests/mochitest/ajax/offline/460353_iframe_samemanifest.html @@ -12,6 +12,10 @@ applicationCache.oncached = function() { parent.frameOnUpdate("same", true, applicationCache.status); } +applicationCache.onnoupdate = function() { + parent.frameOnUpdate("same", true, applicationCache.status); +} + diff --git a/dom/tests/mochitest/ajax/offline/bypass.html b/dom/tests/mochitest/ajax/offline/bypass.html index 6e6e39a64d53..f5bf71e9e3d6 100644 --- a/dom/tests/mochitest/ajax/offline/bypass.html +++ b/dom/tests/mochitest/ajax/offline/bypass.html @@ -28,8 +28,7 @@ function startTest() testScriptPresence("namespace1/sub2/script2.js", "scriptNo2Function();", true); testScriptPresence("namespace2/script3.js", "scriptNo3Function();", true); - opener.OfflineTest.teardown(); - opener.OfflineTest.finish(); + opener.OfflineTest.teardownAndFinish(); window.close(window); } diff --git a/dom/tests/mochitest/ajax/offline/foreign2.html b/dom/tests/mochitest/ajax/offline/foreign2.html index 133c1748e10a..d1116eee5c11 100644 --- a/dom/tests/mochitest/ajax/offline/foreign2.html +++ b/dom/tests/mochitest/ajax/offline/foreign2.html @@ -16,16 +16,15 @@ function manifestUpdated() var foreign2cache = appCacheService.chooseApplicationCache( "http://mochi.test:8888/tests/dom/tests/mochitest/ajax/offline/foreign2.html", OfflineTest.loadContext()); - OfflineTest.ok(foreign2cache, "Foreign 2 cache present, chosen for foreign2.html"); - OfflineTest.is(foreign2cache.manifestURI.asciiSpec, "http://mochi.test:8888/tests/dom/tests/mochitest/ajax/offline/foreign2.cacheManifest") + window.opener.OfflineTest.ok(foreign2cache, "Foreign 2 cache present, chosen for foreign2.html"); + window.opener.OfflineTest.is(foreign2cache.manifestURI.asciiSpec, "http://mochi.test:8888/tests/dom/tests/mochitest/ajax/offline/foreign2.cacheManifest") var foreign1cache = OfflineTest.getActiveCache( "http://mochi.test:8888/tests/dom/tests/mochitest/ajax/offline/foreign1.cacheManifest"); - OfflineTest.ok(foreign1cache, "Foreign 1 cache loaded"); + window.opener.OfflineTest.ok(foreign1cache, "Foreign 1 cache loaded"); foreign1cache.discard(); - OfflineTest.teardown(); - OfflineTest.finish(); + window.opener.onDone(); } function onLoaded() @@ -33,36 +32,33 @@ function onLoaded() var appCacheService = SpecialPowers.Components.classes["@mozilla.org/network/application-cache-service;1"] .getService(SpecialPowers.Ci.nsIApplicationCacheService); - var foreign1cache = OfflineTest.getActiveCache( + var foreign1cache = window.opener.OfflineTest.getActiveCache( "http://mochi.test:8888/tests/dom/tests/mochitest/ajax/offline/foreign1.cacheManifest"); - OfflineTest.ok(foreign1cache, "Foreign 1 cache loaded"); + window.opener.OfflineTest.ok(foreign1cache, "Foreign 1 cache loaded"); - var foreign2cache = OfflineTest.getActiveCache( + var foreign2cache = window.opener.OfflineTest.getActiveCache( "http://mochi.test:8888/tests/dom/tests/mochitest/ajax/offline/foreign2.cacheManifest"); - OfflineTest.ok(!foreign2cache, "Foreign 2 cache not present"); + window.opener.OfflineTest.ok(!foreign2cache, "Foreign 2 cache not present"); foreign1cache = appCacheService.chooseApplicationCache( - "http://mochi.test:8888/tests/dom/tests/mochitest/ajax/offline/foreign2.html", OfflineTest.loadContext()); - OfflineTest.ok(!foreign1cache, "foreign2.html not chosen from foreign1 cache"); + "http://mochi.test:8888/tests/dom/tests/mochitest/ajax/offline/foreign2.html", window.opener.OfflineTest.loadContext()); + window.opener.OfflineTest.ok(!foreign1cache, "foreign2.html not chosen from foreign1 cache"); try { - OfflineTest.ok(applicationCache.status == SpecialPowers.Ci.nsIDOMOfflineResourceList.UNCACHED, + window.opener.OfflineTest.ok(applicationCache.status == SpecialPowers.Ci.nsIDOMOfflineResourceList.UNCACHED, "there is no associated application cache"); } catch (ex) { - OfflineTest.ok(false, "applicationCache.status must not throw an exception"); + window.opener.OfflineTest.ok(false, "applicationCache.status must not throw an exception"); } } -if (OfflineTest.setup()) -{ - applicationCache.onerror = OfflineTest.failEvent; - applicationCache.onupdateready = OfflineTest.failEvent; - applicationCache.onnoupdate = OfflineTest.failEvent; - applicationCache.oncached = OfflineTest.priv(manifestUpdated); -} +applicationCache.onerror = window.opener.OfflineTest.failEvent; +applicationCache.onupdateready = window.opener.OfflineTest.failEvent; +applicationCache.onnoupdate = window.opener.OfflineTest.failEvent; +applicationCache.oncached = window.opener.OfflineTest.priv(manifestUpdated); diff --git a/dom/tests/mochitest/ajax/offline/offlineChild.html b/dom/tests/mochitest/ajax/offline/offlineChild.html index 38b6fae9ac04..d70a060a1641 100644 --- a/dom/tests/mochitest/ajax/offline/offlineChild.html +++ b/dom/tests/mochitest/ajax/offline/offlineChild.html @@ -12,7 +12,7 @@ // (since we don't get those events) function doneLoading() { - window.top.childFinished(); + window.parent.childFinished(); } if (OfflineTest.setupChild()) { diff --git a/dom/tests/mochitest/ajax/offline/offlineTests.js b/dom/tests/mochitest/ajax/offline/offlineTests.js index a39de0a77f71..70823e0f7186 100644 --- a/dom/tests/mochitest/ajax/offline/offlineTests.js +++ b/dom/tests/mochitest/ajax/offline/offlineTests.js @@ -58,6 +58,8 @@ fetch: function(callback) var OfflineTest = { +_allowedByDefault: false, + _hasSlave: false, // The window where test results should be sent. @@ -71,6 +73,11 @@ _SJSsStated: [], setupChild: function() { + if (this._allowedByDefault) { + this._masterWindow = window; + return true; + } + if (window.parent.OfflineTest._hasSlave) { return false; } @@ -91,6 +98,17 @@ setup: function() { netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); + var prefBranch = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch); + try { + this._allowedByDefault = prefBranch.getBoolPref("offline-apps.allow_by_default"); + } catch (e) {} + + if (this._allowedByDefault) { + this._masterWindow = window; + + return true; + } + if (!window.opener || !window.opener.OfflineTest || !window.opener.OfflineTest._hasSlave) { // Offline applications must be toplevel windows and have the @@ -126,35 +144,46 @@ setup: function() return true; }, -teardown: function() +teardownAndFinish: function() { - // Remove the offline-app permission we gave ourselves. + this.teardown(function(self) { self.finish(); }); +}, - netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); +teardown: function(callback) +{ + // First wait for any pending scheduled updates to finish + this.waitForUpdates(function(self) { + // Remove the offline-app permission we gave ourselves. - var pm = Cc["@mozilla.org/permissionmanager;1"] - .getService(Ci.nsIPermissionManager); - var uri = Cc["@mozilla.org/network/io-service;1"] - .getService(Ci.nsIIOService) - .newURI(window.location.href, null, null); - var principal = Components.classes["@mozilla.org/scriptsecuritymanager;1"] - .getService(Ci.nsIScriptSecurityManager) - .getNoAppCodebasePrincipal(uri); + netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); - pm.removeFromPrincipal(principal, "offline-app"); + var pm = Cc["@mozilla.org/permissionmanager;1"] + .getService(Ci.nsIPermissionManager); + var uri = Cc["@mozilla.org/network/io-service;1"] + .getService(Ci.nsIIOService) + .newURI(window.location.href, null, null); + var principal = Components.classes["@mozilla.org/scriptsecuritymanager;1"] + .getService(Ci.nsIScriptSecurityManager) + .getNoAppCodebasePrincipal(uri); - // Clear all overrides on the server - for (override in this._pathOverrides) - this.deleteData(this._pathOverrides[override]); - for (statedSJS in this._SJSsStated) - this.setSJSState(this._SJSsStated[statedSJS], ""); + pm.removeFromPrincipal(principal, "offline-app"); - this.clear(); + // Clear all overrides on the server + for (override in self._pathOverrides) + self.deleteData(self._pathOverrides[override]); + for (statedSJS in self._SJSsStated) + self.setSJSState(self._SJSsStated[statedSJS], ""); + + self.clear(); + callback(self); + }); }, finish: function() { - if (this._masterWindow) { + if (this._allowedByDefault) { + SimpleTest.executeSoon(SimpleTest.finish); + } else if (this._masterWindow) { // Slave window: pass control back to master window, close itself. this._masterWindow.SimpleTest.executeSoon(this._masterWindow.OfflineTest.finish); window.close(); @@ -196,6 +225,48 @@ clear: function() } }, +waitForUpdates: function(callback) +{ + netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); + + var self = this; + var observer = { + notified: false, + observe: function(subject, topic, data) { + if (subject) { + subject.QueryInterface(SpecialPowers.Ci.nsIOfflineCacheUpdate); + dump("Update of " + subject.manifestURI.spec + " finished\n"); + } + + SimpleTest.executeSoon(function() { + if (observer.notified) { + return; + } + + var updateservice = SpecialPowers.Cc["@mozilla.org/offlinecacheupdate-service;1"] + .getService(SpecialPowers.Ci.nsIOfflineCacheUpdateService); + var updatesPending = updateservice.numUpdates; + if (updatesPending == 0) { + try { + SpecialPowers.removeObserver(observer, "offline-cache-update-completed"); + } catch(ex) {} + dump("All pending updates done\n"); + observer.notified = true; + callback(self); + return; + } + + dump("Waiting for " + updateservice.numUpdates + " update(s) to finish\n"); + }); + } + } + + SpecialPowers.addObserver(observer, "offline-cache-update-completed", false); + + // Call now to check whether there are some updates scheduled + observer.observe(); +}, + failEvent: function(e) { OfflineTest.ok(false, "Unexpected event: " + e.type); @@ -237,7 +308,19 @@ waitForAdd: function(url, onFinished) { manifestURL: function(overload) { - var manifestURLspec = overload || window.top.document.documentElement.getAttribute("manifest"); + var manifestURLspec; + if (overload) { + manifestURLspec = overload; + } else { + var win = window; + while (win && !win.document.documentElement.getAttribute("manifest")) { + if (win == win.parent) + break; + win = win.parent; + } + if (win) + manifestURLspec = win.document.documentElement.getAttribute("manifest"); + } var ios = Cc["@mozilla.org/network/io-service;1"] .getService(Ci.nsIIOService) @@ -267,8 +350,9 @@ getActiveCache: function(overload) getActiveSession: function() { var cache = this.getActiveCache(); - if (!cache) + if (!cache) { return null; + } var cacheService = Cc["@mozilla.org/network/cache-service;1"] .getService(Ci.nsICacheService); @@ -302,6 +386,7 @@ checkCacheEntries: function(entries, callback) checkCache: function(url, expectEntry, callback) { + netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); var cacheSession = this.getActiveSession(); this._checkCache(cacheSession, url, expectEntry, callback); }, @@ -310,11 +395,11 @@ _checkCache: function(cacheSession, url, expectEntry, callback) { if (!cacheSession) { if (expectEntry) { - this.ok(false, url + " should exist in the offline cache"); + this.ok(false, url + " should exist in the offline cache (no session)"); } else { - this.ok(true, url + " should not exist in the offline cache"); + this.ok(true, url + " should not exist in the offline cache (no session)"); } - setTimeout(this.priv(callback), 0); + if (callback) setTimeout(this.priv(callback), 0); return; } @@ -346,7 +431,7 @@ _checkCache: function(cacheSession, url, expectEntry, callback) OfflineTest.ok(false, "got invalid error for " + url); } } - setTimeout(OfflineTest.priv(callback), 0); + if (callback) setTimeout(OfflineTest.priv(callback), 0); } }; diff --git a/dom/tests/mochitest/ajax/offline/test_badManifestMagic.html b/dom/tests/mochitest/ajax/offline/test_badManifestMagic.html index 090ef3f493f8..f7811bcd5fb5 100644 --- a/dom/tests/mochitest/ajax/offline/test_badManifestMagic.html +++ b/dom/tests/mochitest/ajax/offline/test_badManifestMagic.html @@ -11,8 +11,7 @@ var gGotChecking = false; function finishTest() { - OfflineTest.teardown(); - OfflineTest.finish(); + OfflineTest.teardownAndFinish(); } function handleError() { diff --git a/dom/tests/mochitest/ajax/offline/test_bug445544.html b/dom/tests/mochitest/ajax/offline/test_bug445544.html index 408f3e7c8dfb..68fc0b90abd2 100644 --- a/dom/tests/mochitest/ajax/offline/test_bug445544.html +++ b/dom/tests/mochitest/ajax/offline/test_bug445544.html @@ -17,8 +17,7 @@ var gTimeoutId; function finish() { gTestWin.close(); - OfflineTest.teardown(); - OfflineTest.finish(); + OfflineTest.teardownAndFinish(); } function error() diff --git a/dom/tests/mochitest/ajax/offline/test_bug460353.html b/dom/tests/mochitest/ajax/offline/test_bug460353.html index c0ba51aa9678..3c89df1a5a94 100644 --- a/dom/tests/mochitest/ajax/offline/test_bug460353.html +++ b/dom/tests/mochitest/ajax/offline/test_bug460353.html @@ -16,10 +16,16 @@