зеркало из https://github.com/mozilla/gecko-dev.git
Bug 621158 - make appcache use messaging for quota management, r=mayhemer,jaws
MozReview-Commit-ID: GfHbERuzuW8 --HG-- extra : rebase_source : 343aab5cb460641d4fb0dd21760ec40cc68e9c28 extra : amend_source : 4609109ca8cd686fae51956cca960b5f94656e34
This commit is contained in:
Родитель
6be7372f93
Коммит
7ded129f86
|
@ -1049,16 +1049,9 @@ var gBrowserInit = {
|
|||
|
||||
this._cancelDelayedStartup();
|
||||
|
||||
// We need to set the MozApplicationManifest event listeners up
|
||||
// before we start loading the home pages in case a document has
|
||||
// a "manifest" attribute, in which the MozApplicationManifest event
|
||||
// will be fired.
|
||||
gBrowser.addEventListener("MozApplicationManifest",
|
||||
OfflineApps, false);
|
||||
// listen for offline apps on social
|
||||
let socialBrowser = document.getElementById("social-sidebar-browser");
|
||||
socialBrowser.addEventListener("MozApplicationManifest",
|
||||
OfflineApps, false);
|
||||
// We need to set the OfflineApps message listeners up before we
|
||||
// load homepages, which might need them.
|
||||
OfflineApps.init();
|
||||
|
||||
// This pageshow listener needs to be registered before we may call
|
||||
// swapBrowsersAndCloseOther() to receive pageshow events fired by that.
|
||||
|
@ -1176,7 +1169,6 @@ var gBrowserInit = {
|
|||
window.messageManager.addMessageListener("Browser:URIFixup", gKeywordURIFixup);
|
||||
|
||||
BrowserOffline.init();
|
||||
OfflineApps.init();
|
||||
IndexedDBPromptHelper.init();
|
||||
|
||||
if (AppConstants.E10S_TESTING_ONLY)
|
||||
|
@ -1498,7 +1490,6 @@ var gBrowserInit = {
|
|||
}
|
||||
|
||||
BrowserOffline.uninit();
|
||||
OfflineApps.uninit();
|
||||
IndexedDBPromptHelper.uninit();
|
||||
LightweightThemeListener.uninit();
|
||||
PanelUI.uninit();
|
||||
|
@ -5745,141 +5736,49 @@ var BrowserOffline = {
|
|||
};
|
||||
|
||||
var OfflineApps = {
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// OfflineApps Public Methods
|
||||
init: function ()
|
||||
{
|
||||
Services.obs.addObserver(this, "offline-cache-update-completed", false);
|
||||
},
|
||||
|
||||
uninit: function ()
|
||||
{
|
||||
Services.obs.removeObserver(this, "offline-cache-update-completed");
|
||||
},
|
||||
|
||||
handleEvent: function(event) {
|
||||
if (event.type == "MozApplicationManifest") {
|
||||
this.offlineAppRequested(event.originalTarget.defaultView);
|
||||
}
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// OfflineApps Implementation Methods
|
||||
|
||||
// XXX: _getBrowserWindowForContentWindow and _getBrowserForContentWindow
|
||||
// were taken from browser/components/feeds/WebContentConverter.
|
||||
_getBrowserWindowForContentWindow: function(aContentWindow) {
|
||||
return aContentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShellTreeItem)
|
||||
.rootTreeItem
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindow)
|
||||
.wrappedJSObject;
|
||||
},
|
||||
|
||||
_getBrowserForContentWindow: function(aBrowserWindow, aContentWindow) {
|
||||
// This depends on pseudo APIs of browser.js and tabbrowser.xml
|
||||
aContentWindow = aContentWindow.top;
|
||||
var browsers = aBrowserWindow.gBrowser.browsers;
|
||||
for (let browser of browsers) {
|
||||
if (browser.contentWindow == aContentWindow)
|
||||
return browser;
|
||||
}
|
||||
// handle other browser/iframe elements that may need popupnotifications
|
||||
let browser = aContentWindow
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShell)
|
||||
.chromeEventHandler;
|
||||
if (browser.getAttribute("popupnotificationanchor"))
|
||||
return browser;
|
||||
return null;
|
||||
},
|
||||
|
||||
_getManifestURI: function(aWindow) {
|
||||
if (!aWindow.document.documentElement)
|
||||
return null;
|
||||
|
||||
var attr = aWindow.document.documentElement.getAttribute("manifest");
|
||||
if (!attr)
|
||||
return null;
|
||||
|
||||
try {
|
||||
var contentURI = makeURI(aWindow.location.href, null, null);
|
||||
return makeURI(attr, aWindow.document.characterSet, contentURI);
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
// A cache update isn't tied to a specific window. Try to find
|
||||
// the best browser in which to warn the user about space usage
|
||||
_getBrowserForCacheUpdate: function(aCacheUpdate) {
|
||||
// Prefer the current browser
|
||||
var uri = this._getManifestURI(content);
|
||||
if (uri && uri.equals(aCacheUpdate.manifestURI)) {
|
||||
return gBrowser.selectedBrowser;
|
||||
}
|
||||
|
||||
var browsers = gBrowser.browsers;
|
||||
for (let browser of browsers) {
|
||||
uri = this._getManifestURI(browser.contentWindow);
|
||||
if (uri && uri.equals(aCacheUpdate.manifestURI)) {
|
||||
return browser;
|
||||
}
|
||||
}
|
||||
|
||||
// is this from a non-tab browser/iframe?
|
||||
browsers = document.querySelectorAll("iframe[popupnotificationanchor] | browser[popupnotificationanchor]");
|
||||
for (let browser of browsers) {
|
||||
uri = this._getManifestURI(browser.contentWindow);
|
||||
if (uri && uri.equals(aCacheUpdate.manifestURI)) {
|
||||
return browser;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
_warnUsage: function(aBrowser, aURI) {
|
||||
if (!aBrowser)
|
||||
warnUsage(browser, uri) {
|
||||
if (!browser)
|
||||
return;
|
||||
|
||||
let mainAction = {
|
||||
label: gNavigatorBundle.getString("offlineApps.manageUsage"),
|
||||
accessKey: gNavigatorBundle.getString("offlineApps.manageUsageAccessKey"),
|
||||
callback: OfflineApps.manage
|
||||
callback: this.manage
|
||||
};
|
||||
|
||||
let warnQuota = gPrefService.getIntPref("offline-apps.quota.warn");
|
||||
let warnQuotaKB = Services.prefs.getIntPref("offline-apps.quota.warn");
|
||||
// This message shows the quota in MB, and so we divide the quota (in kb) by 1024.
|
||||
let message = gNavigatorBundle.getFormattedString("offlineApps.usage",
|
||||
[ aURI.host,
|
||||
warnQuota / 1024 ]);
|
||||
[ uri.host,
|
||||
warnQuotaKB / 1024 ]);
|
||||
|
||||
let anchorID = "indexedDB-notification-icon";
|
||||
PopupNotifications.show(aBrowser, "offline-app-usage", message,
|
||||
PopupNotifications.show(browser, "offline-app-usage", message,
|
||||
anchorID, mainAction);
|
||||
|
||||
// Now that we've warned once, prevent the warning from showing up
|
||||
// again.
|
||||
Services.perms.add(aURI, "offline-app",
|
||||
Services.perms.add(uri, "offline-app",
|
||||
Ci.nsIOfflineCacheUpdateService.ALLOW_NO_WARN);
|
||||
},
|
||||
|
||||
// XXX: duplicated in preferences/advanced.js
|
||||
_getOfflineAppUsage: function (host, groups)
|
||||
{
|
||||
var cacheService = Cc["@mozilla.org/network/application-cache-service;1"].
|
||||
_getOfflineAppUsage(host, groups) {
|
||||
let cacheService = Cc["@mozilla.org/network/application-cache-service;1"].
|
||||
getService(Ci.nsIApplicationCacheService);
|
||||
if (!groups)
|
||||
if (!groups) {
|
||||
try {
|
||||
groups = cacheService.getGroups();
|
||||
} catch (ex) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
var usage = 0;
|
||||
let usage = 0;
|
||||
for (let group of groups) {
|
||||
var uri = Services.io.newURI(group, null, null);
|
||||
let uri = Services.io.newURI(group, null, null);
|
||||
if (uri.asciiHost == host) {
|
||||
var cache = cacheService.getActiveCache(group);
|
||||
let cache = cacheService.getActiveCache(group);
|
||||
usage += cache.usage;
|
||||
}
|
||||
}
|
||||
|
@ -5887,13 +5786,15 @@ var OfflineApps = {
|
|||
return usage;
|
||||
},
|
||||
|
||||
_checkUsage: function(aURI) {
|
||||
_usedMoreThanWarnQuota(uri) {
|
||||
// if the user has already allowed excessive usage, don't bother checking
|
||||
if (Services.perms.testExactPermission(aURI, "offline-app") !=
|
||||
if (Services.perms.testExactPermission(uri, "offline-app") !=
|
||||
Ci.nsIOfflineCacheUpdateService.ALLOW_NO_WARN) {
|
||||
var usage = this._getOfflineAppUsage(aURI.asciiHost);
|
||||
var warnQuota = gPrefService.getIntPref("offline-apps.quota.warn");
|
||||
if (usage >= warnQuota * 1024) {
|
||||
let usageBytes = this._getOfflineAppUsage(uri.asciiHost);
|
||||
let warnQuotaKB = Services.prefs.getIntPref("offline-apps.quota.warn");
|
||||
// The pref is in kb, the usage we get is in bytes, so multiply the quota
|
||||
// to compare correctly:
|
||||
if (usageBytes >= warnQuotaKB * 1024) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -5901,43 +5802,22 @@ var OfflineApps = {
|
|||
return false;
|
||||
},
|
||||
|
||||
offlineAppRequested: function(aContentWindow) {
|
||||
if (!gPrefService.getBoolPref("browser.offline-apps.notify")) {
|
||||
return;
|
||||
}
|
||||
|
||||
let browserWindow = this._getBrowserWindowForContentWindow(aContentWindow);
|
||||
let browser = this._getBrowserForContentWindow(browserWindow,
|
||||
aContentWindow);
|
||||
|
||||
let currentURI = aContentWindow.document.documentURIObject;
|
||||
|
||||
// don't bother showing UI if the user has already made a decision
|
||||
if (Services.perms.testExactPermission(currentURI, "offline-app") != Services.perms.UNKNOWN_ACTION)
|
||||
return;
|
||||
|
||||
try {
|
||||
if (gPrefService.getBoolPref("offline-apps.allow_by_default")) {
|
||||
// all pages can use offline capabilities, no need to ask the user
|
||||
return;
|
||||
}
|
||||
} catch(e) {
|
||||
// this pref isn't set by default, ignore failures
|
||||
}
|
||||
|
||||
let host = currentURI.asciiHost;
|
||||
requestPermission(browser, docId, uri) {
|
||||
let host = uri.asciiHost;
|
||||
let notificationID = "offline-app-requested-" + host;
|
||||
let notification = PopupNotifications.getNotification(notificationID, browser);
|
||||
|
||||
if (notification) {
|
||||
notification.options.documents.push(aContentWindow.document);
|
||||
notification.options.controlledItems.push([
|
||||
Cu.getWeakReference(browser), docId, uri
|
||||
]);
|
||||
} else {
|
||||
let mainAction = {
|
||||
label: gNavigatorBundle.getString("offlineApps.allow"),
|
||||
accessKey: gNavigatorBundle.getString("offlineApps.allowAccessKey"),
|
||||
callback: function() {
|
||||
for (let document of notification.options.documents) {
|
||||
OfflineApps.allowSite(document);
|
||||
for (let [browser, docId, uri] of notification.options.controlledItems) {
|
||||
OfflineApps.allowSite(browser, docId, uri);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -5945,16 +5825,16 @@ var OfflineApps = {
|
|||
label: gNavigatorBundle.getString("offlineApps.never"),
|
||||
accessKey: gNavigatorBundle.getString("offlineApps.neverAccessKey"),
|
||||
callback: function() {
|
||||
for (let document of notification.options.documents) {
|
||||
OfflineApps.disallowSite(document);
|
||||
for (let [, , uri] of notification.options.controlledItems) {
|
||||
OfflineApps.disallowSite(uri);
|
||||
}
|
||||
}
|
||||
}];
|
||||
let message = gNavigatorBundle.getFormattedString("offlineApps.available",
|
||||
[ host ]);
|
||||
[host]);
|
||||
let anchorID = "indexedDB-notification-icon";
|
||||
let options= {
|
||||
documents : [ aContentWindow.document ]
|
||||
let options = {
|
||||
controlledItems : [[Cu.getWeakReference(browser), docId, uri]]
|
||||
};
|
||||
notification = PopupNotifications.show(browser, notificationID, message,
|
||||
anchorID, mainAction,
|
||||
|
@ -5962,56 +5842,47 @@ var OfflineApps = {
|
|||
}
|
||||
},
|
||||
|
||||
allowSite: function(aDocument) {
|
||||
Services.perms.add(aDocument.documentURIObject, "offline-app", Services.perms.ALLOW_ACTION);
|
||||
disallowSite(uri) {
|
||||
Services.perms.add(uri, "offline-app", Services.perms.DENY_ACTION);
|
||||
},
|
||||
|
||||
allowSite(browserRef, docId, uri) {
|
||||
Services.perms.add(uri, "offline-app", Services.perms.ALLOW_ACTION);
|
||||
|
||||
// When a site is enabled while loading, manifest resources will
|
||||
// start fetching immediately. This one time we need to do it
|
||||
// ourselves.
|
||||
this._startFetching(aDocument);
|
||||
let browser = browserRef.get();
|
||||
if (browser && browser.messageManager) {
|
||||
browser.messageManager.sendAsyncMessage("OfflineApps:StartFetching", {
|
||||
docId,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
disallowSite: function(aDocument) {
|
||||
Services.perms.add(aDocument.documentURIObject, "offline-app", Services.perms.DENY_ACTION);
|
||||
},
|
||||
|
||||
manage: function() {
|
||||
manage() {
|
||||
openAdvancedPreferences("networkTab");
|
||||
},
|
||||
|
||||
_startFetching: function(aDocument) {
|
||||
if (!aDocument.documentElement)
|
||||
return;
|
||||
|
||||
var manifest = aDocument.documentElement.getAttribute("manifest");
|
||||
if (!manifest)
|
||||
return;
|
||||
|
||||
var manifestURI = makeURI(manifest, aDocument.characterSet,
|
||||
aDocument.documentURIObject);
|
||||
|
||||
var updateService = Cc["@mozilla.org/offlinecacheupdate-service;1"].
|
||||
getService(Ci.nsIOfflineCacheUpdateService);
|
||||
updateService.scheduleUpdate(manifestURI, aDocument.documentURIObject,
|
||||
aDocument.nodePrincipal, window);
|
||||
receiveMessage(msg) {
|
||||
switch (msg.name) {
|
||||
case "OfflineApps:CheckUsage":
|
||||
let uri = makeURI(msg.data.uri);
|
||||
if (this._usedMoreThanWarnQuota(uri)) {
|
||||
this.warnUsage(msg.target, uri);
|
||||
}
|
||||
break;
|
||||
case "OfflineApps:RequestPermission":
|
||||
this.requestPermission(msg.target, msg.data.docId, makeURI(msg.data.uri));
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// nsIObserver
|
||||
observe: function (aSubject, aTopic, aState)
|
||||
{
|
||||
if (aTopic == "offline-cache-update-completed") {
|
||||
var cacheUpdate = aSubject.QueryInterface(Ci.nsIOfflineCacheUpdate);
|
||||
|
||||
var uri = cacheUpdate.manifestURI;
|
||||
if (OfflineApps._checkUsage(uri)) {
|
||||
var browser = this._getBrowserForCacheUpdate(cacheUpdate);
|
||||
if (browser) {
|
||||
OfflineApps._warnUsage(browser, cacheUpdate.manifestURI);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
init() {
|
||||
let mm = window.messageManager;
|
||||
mm.addMessageListener("OfflineApps:CheckUsage", this);
|
||||
mm.addMessageListener("OfflineApps:RequestPermission", this);
|
||||
},
|
||||
};
|
||||
|
||||
var IndexedDBPromptHelper = {
|
||||
|
|
|
@ -1318,3 +1318,110 @@ var PageInfoListener = {
|
|||
}
|
||||
};
|
||||
PageInfoListener.init();
|
||||
|
||||
let OfflineApps = {
|
||||
_docId: 0,
|
||||
_docIdMap: new Map(),
|
||||
|
||||
_docManifestSet: new Set(),
|
||||
|
||||
_observerAdded: false,
|
||||
registerWindow(aWindow) {
|
||||
if (!this._observerAdded) {
|
||||
this._observerAdded = true;
|
||||
Services.obs.addObserver(this, "offline-cache-update-completed", true);
|
||||
}
|
||||
let manifestURI = this._getManifestURI(aWindow);
|
||||
this._docManifestSet.add(manifestURI.spec);
|
||||
},
|
||||
|
||||
handleEvent(event) {
|
||||
if (event.type == "MozApplicationManifest") {
|
||||
this.offlineAppRequested(event.originalTarget.defaultView);
|
||||
}
|
||||
},
|
||||
|
||||
_getManifestURI(aWindow) {
|
||||
if (!aWindow.document.documentElement)
|
||||
return null;
|
||||
|
||||
var attr = aWindow.document.documentElement.getAttribute("manifest");
|
||||
if (!attr)
|
||||
return null;
|
||||
|
||||
try {
|
||||
var contentURI = BrowserUtils.makeURI(aWindow.location.href, null, null);
|
||||
return BrowserUtils.makeURI(attr, aWindow.document.characterSet, contentURI);
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
offlineAppRequested(aContentWindow) {
|
||||
this.registerWindow(aContentWindow);
|
||||
if (!Services.prefs.getBoolPref("browser.offline-apps.notify")) {
|
||||
return;
|
||||
}
|
||||
|
||||
let currentURI = aContentWindow.document.documentURIObject;
|
||||
// don't bother showing UI if the user has already made a decision
|
||||
if (Services.perms.testExactPermission(currentURI, "offline-app") != Services.perms.UNKNOWN_ACTION)
|
||||
return;
|
||||
|
||||
try {
|
||||
if (Services.prefs.getBoolPref("offline-apps.allow_by_default")) {
|
||||
// all pages can use offline capabilities, no need to ask the user
|
||||
return;
|
||||
}
|
||||
} catch(e) {
|
||||
// this pref isn't set by default, ignore failures
|
||||
}
|
||||
let docId = ++this._docId;
|
||||
this._docIdMap.set(docId, Cu.getWeakReference(aContentWindow.document));
|
||||
sendAsyncMessage("OfflineApps:RequestPermission", {
|
||||
uri: currentURI.spec,
|
||||
docId,
|
||||
});
|
||||
},
|
||||
|
||||
_startFetching(aDocument) {
|
||||
if (!aDocument.documentElement)
|
||||
return;
|
||||
|
||||
let manifestURI = this._getManifestURI(aDocument.defaultView);
|
||||
if (!manifestURI)
|
||||
return;
|
||||
|
||||
var updateService = Cc["@mozilla.org/offlinecacheupdate-service;1"].
|
||||
getService(Ci.nsIOfflineCacheUpdateService);
|
||||
updateService.scheduleUpdate(manifestURI, aDocument.documentURIObject,
|
||||
aDocument.nodePrincipal, aDocument.defaultView);
|
||||
},
|
||||
|
||||
receiveMessage(aMessage) {
|
||||
if (aMessage.name == "OfflineApps:StartFetching") {
|
||||
let doc = this._docIdMap.get(aMessage.data.docId);
|
||||
doc = doc && doc.get();
|
||||
if (doc) {
|
||||
this._startFetching(doc);
|
||||
}
|
||||
this._docIdMap.delete(aMessage.data.docId);
|
||||
}
|
||||
},
|
||||
|
||||
observe(aSubject, aTopic, aState) {
|
||||
if (aTopic == "offline-cache-update-completed") {
|
||||
let cacheUpdate = aSubject.QueryInterface(Ci.nsIOfflineCacheUpdate);
|
||||
let uri = cacheUpdate.manifestURI;
|
||||
if (uri && this._docManifestSet.has(uri.spec)) {
|
||||
sendAsyncMessage("OfflineApps:CheckUsage", {uri: uri.spec});
|
||||
}
|
||||
}
|
||||
},
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
|
||||
Ci.nsISupportsWeakReference]),
|
||||
};
|
||||
|
||||
addEventListener("MozApplicationManifest", OfflineApps, false);
|
||||
addMessageListener("OfflineApps:StartFetching", OfflineApps);
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@ registerCleanupFunction(function() {
|
|||
Services.perms.removeFromPrincipal(principal, "offline-app");
|
||||
Services.prefs.clearUserPref("offline-apps.quota.warn");
|
||||
Services.prefs.clearUserPref("offline-apps.allow_by_default");
|
||||
let {OfflineAppCacheHelper} = Components.utils.import("resource:///modules/offlineAppCache.jsm", {});
|
||||
OfflineAppCacheHelper.clear();
|
||||
});
|
||||
|
||||
// Same as the other one, but for in-content preferences
|
||||
|
@ -44,10 +46,21 @@ function test() {
|
|||
// Wait for a notification that asks whether to allow offline storage.
|
||||
promiseNotification(),
|
||||
// Wait for the tab to load.
|
||||
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser)
|
||||
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser),
|
||||
]).then(() => {
|
||||
gBrowser.selectedBrowser.contentWindow.applicationCache.oncached = function() {
|
||||
executeSoon(function() {
|
||||
info("Loaded page, adding onCached handler");
|
||||
// Need a promise to keep track of when we've added our handler.
|
||||
let mm = gBrowser.selectedBrowser.messageManager;
|
||||
let onCachedAttached = BrowserTestUtils.waitForMessage(mm, "Test:OnCachedAttached");
|
||||
let gotCached = ContentTask.spawn(gBrowser.selectedBrowser, null, function*() {
|
||||
return new Promise(resolve => {
|
||||
content.window.applicationCache.oncached = function() {
|
||||
setTimeout(resolve, 0);
|
||||
};
|
||||
sendAsyncMessage("Test:OnCachedAttached");
|
||||
});
|
||||
});
|
||||
gotCached.then(function() {
|
||||
// We got cached - now we should have provoked the quota warning.
|
||||
let notification = PopupNotifications.getNotification('offline-app-usage');
|
||||
ok(notification, "have offline-app-usage notification");
|
||||
|
@ -62,13 +75,14 @@ function test() {
|
|||
})
|
||||
}, true);
|
||||
});
|
||||
};
|
||||
onCachedAttached.then(function() {
|
||||
Services.prefs.setIntPref("offline-apps.quota.warn", 1);
|
||||
|
||||
// Click the notification panel's "Allow" button. This should kick
|
||||
// off updates which will call our oncached handler above.
|
||||
PopupNotifications.panel.firstElementChild.button.click();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function promiseNotification() {
|
||||
|
|
|
@ -503,18 +503,22 @@ var gAdvancedPane = {
|
|||
},
|
||||
|
||||
// XXX: duplicated in browser.js
|
||||
_getOfflineAppUsage: function (perm, groups)
|
||||
{
|
||||
var cacheService = Components.classes["@mozilla.org/network/application-cache-service;1"].
|
||||
getService(Components.interfaces.nsIApplicationCacheService);
|
||||
var ios = Components.classes["@mozilla.org/network/io-service;1"].
|
||||
getService(Components.interfaces.nsIIOService);
|
||||
_getOfflineAppUsage(perm, groups) {
|
||||
let cacheService = Cc["@mozilla.org/network/application-cache-service;1"].
|
||||
getService(Ci.nsIApplicationCacheService);
|
||||
if (!groups) {
|
||||
try {
|
||||
groups = cacheService.getGroups();
|
||||
} catch (ex) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
var usage = 0;
|
||||
for (var i = 0; i < groups.length; i++) {
|
||||
var uri = ios.newURI(groups[i], null, null);
|
||||
let usage = 0;
|
||||
for (let group of groups) {
|
||||
let uri = Services.io.newURI(group, null, null);
|
||||
if (perm.matchesURI(uri, true)) {
|
||||
var cache = cacheService.getActiveCache(groups[i]);
|
||||
let cache = cacheService.getActiveCache(groups);
|
||||
usage += cache.usage;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1130,3 +1130,15 @@ var ViewSelectionSource = {
|
|||
};
|
||||
|
||||
ViewSelectionSource.init();
|
||||
|
||||
addEventListener("MozApplicationManifest", function(e) {
|
||||
let doc = e.target;
|
||||
let info = {
|
||||
uri: doc.documentURI,
|
||||
characterSet: doc.characterSet,
|
||||
manifest: doc.documentElement.getAttribute("manifest"),
|
||||
principal: doc.nodePrincipal,
|
||||
};
|
||||
sendAsyncMessage("MozApplicationManifest", info);
|
||||
}, false);
|
||||
|
||||
|
|
|
@ -498,6 +498,13 @@
|
|||
return val;"
|
||||
onget="return this.getAttribute('showresizer') == 'true';"/>
|
||||
|
||||
<property name="manifestURI"
|
||||
readonly="true">
|
||||
<getter><![CDATA[
|
||||
return this.contentDocument.documentElement &&
|
||||
this.contentDocument.documentElement.getAttribute("manifest");
|
||||
]]></getter>
|
||||
</property>
|
||||
|
||||
<property name="fullZoom">
|
||||
<getter><![CDATA[
|
||||
|
@ -1219,6 +1226,7 @@
|
|||
"_textZoom",
|
||||
"_isSyntheticDocument",
|
||||
"_innerWindowID",
|
||||
"_manifestURI",
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
@ -259,6 +259,11 @@
|
|||
]]></body>
|
||||
</method>
|
||||
|
||||
<field name="_manifestURI"/>
|
||||
<property name="manifestURI"
|
||||
onget="return this._manifestURI"
|
||||
readonly="true"/>
|
||||
|
||||
<field name="mDestroyed">false</field>
|
||||
|
||||
<field name="_permitUnloadId">0</field>
|
||||
|
@ -363,6 +368,7 @@
|
|||
this.messageManager.addMessageListener("ZoomChangeUsingMouseWheel", this);
|
||||
this.messageManager.addMessageListener("DOMFullscreen:RequestExit", this);
|
||||
this.messageManager.addMessageListener("DOMFullscreen:RequestRollback", this);
|
||||
this.messageManager.addMessageListener("MozApplicationManifest", this);
|
||||
this.messageManager.loadFrameScript("chrome://global/content/browser-child.js", true);
|
||||
|
||||
if (this.hasAttribute("selectmenulist")) {
|
||||
|
@ -497,6 +503,10 @@
|
|||
break;
|
||||
}
|
||||
|
||||
case "MozApplicationManifest":
|
||||
this._manifestURI = aMessage.data.manifest;
|
||||
break;
|
||||
|
||||
default:
|
||||
// Delegate to browser.xml.
|
||||
return this._receiveMessage(aMessage);
|
||||
|
|
Загрузка…
Ссылка в новой задаче