toolkit/forgetaboutsite/ForgetAboutSite.jsm

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 Components.utils.import("resource://gre/modules/Services.jsm");
     6 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
     7 Components.utils.import("resource://gre/modules/NetUtil.jsm");
     8 Components.utils.import("resource://gre/modules/Task.jsm");
     9 XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
    10                                   "resource://gre/modules/PlacesUtils.jsm");
    11 XPCOMUtils.defineLazyModuleGetter(this, "Downloads",
    12                                   "resource://gre/modules/Downloads.jsm");
    14 this.EXPORTED_SYMBOLS = ["ForgetAboutSite"];
    16 /**
    17  * Returns true if the string passed in is part of the root domain of the
    18  * current string.  For example, if this is "www.mozilla.org", and we pass in
    19  * "mozilla.org", this will return true.  It would return false the other way
    20  * around.
    21  */
    22 function hasRootDomain(str, aDomain)
    23 {
    24   let index = str.indexOf(aDomain);
    25   // If aDomain is not found, we know we do not have it as a root domain.
    26   if (index == -1)
    27     return false;
    29   // If the strings are the same, we obviously have a match.
    30   if (str == aDomain)
    31     return true;
    33   // Otherwise, we have aDomain as our root domain iff the index of aDomain is
    34   // aDomain.length subtracted from our length and (since we do not have an
    35   // exact match) the character before the index is a dot or slash.
    36   let prevChar = str[index - 1];
    37   return (index == (str.length - aDomain.length)) &&
    38          (prevChar == "." || prevChar == "/");
    39 }
    41 const Cc = Components.classes;
    42 const Ci = Components.interfaces;
    43 const Cu = Components.utils;
    45 this.ForgetAboutSite = {
    46   removeDataFromDomain: function CRH_removeDataFromDomain(aDomain)
    47   {
    48     PlacesUtils.history.removePagesFromHost(aDomain, true);
    50     // Cache
    51     let (cs = Cc["@mozilla.org/netwerk/cache-storage-service;1"].
    52               getService(Ci.nsICacheStorageService)) {
    53       // NOTE: there is no way to clear just that domain, so we clear out
    54       //       everything)
    55       try {
    56         cs.clear();
    57       } catch (ex) {
    58         Cu.reportError("Exception thrown while clearing the cache: " +
    59           ex.toString());
    60       }
    61     }
    63     // Image Cache
    64     let (imageCache = Cc["@mozilla.org/image/tools;1"].
    65                       getService(Ci.imgITools).getImgCacheForDocument(null)) {
    66       try {
    67         imageCache.clearCache(false); // true=chrome, false=content
    68       } catch (ex) {
    69         Cu.reportError("Exception thrown while clearing the image cache: " +
    70           ex.toString());
    71       }
    72     }
    74     // Cookies
    75     let (cm = Cc["@mozilla.org/cookiemanager;1"].
    76               getService(Ci.nsICookieManager2)) {
    77       let enumerator = cm.getCookiesFromHost(aDomain);
    78       while (enumerator.hasMoreElements()) {
    79         let cookie = enumerator.getNext().QueryInterface(Ci.nsICookie);
    80         cm.remove(cookie.host, cookie.name, cookie.path, false);
    81       }
    82     }
    84     // Plugin data
    85     const phInterface = Ci.nsIPluginHost;
    86     const FLAG_CLEAR_ALL = phInterface.FLAG_CLEAR_ALL;
    87     let (ph = Cc["@mozilla.org/plugin/host;1"].getService(phInterface)) {
    88       let tags = ph.getPluginTags();
    89       for (let i = 0; i < tags.length; i++) {
    90         try {
    91           ph.clearSiteData(tags[i], aDomain, FLAG_CLEAR_ALL, -1);
    92         } catch (e) {
    93           // Ignore errors from the plugin
    94         }
    95       }
    96     }
    98     // Downloads
    99     let useJSTransfer = false;
   100     try {
   101       // This method throws an exception if the old Download Manager is disabled.
   102       Services.downloads.activeDownloadCount;
   103     } catch (ex) {
   104       useJSTransfer = true;
   105     }
   107     if (useJSTransfer) {
   108       Task.spawn(function() {
   109         let list = yield Downloads.getList(Downloads.ALL);
   110         list.removeFinished(download => hasRootDomain(
   111              NetUtil.newURI(download.source.url).host, aDomain));
   112       }).then(null, Cu.reportError);
   113     }
   114     else {
   115       let (dm = Cc["@mozilla.org/download-manager;1"].
   116                 getService(Ci.nsIDownloadManager)) {
   117         // Active downloads
   118         for (let enumerator of [dm.activeDownloads, dm.activePrivateDownloads]) {
   119           while (enumerator.hasMoreElements()) {
   120             let dl = enumerator.getNext().QueryInterface(Ci.nsIDownload);
   121             if (hasRootDomain(dl.source.host, aDomain)) {
   122               dl.cancel();
   123               dl.remove();
   124             }
   125           }
   126         }
   128         function deleteAllLike(db) {
   129           // NOTE: This is lossy, but we feel that it is OK to be lossy here and not
   130           //       invoke the cost of creating a URI for each download entry and
   131           //       ensure that the hostname matches.
   132           let stmt = db.createStatement(
   133             "DELETE FROM moz_downloads " +
   134             "WHERE source LIKE ?1 ESCAPE '/' " +
   135             "AND state NOT IN (?2, ?3, ?4)"
   136           );
   137           let pattern = stmt.escapeStringForLIKE(aDomain, "/");
   138           stmt.bindByIndex(0, "%" + pattern + "%");
   139           stmt.bindByIndex(1, Ci.nsIDownloadManager.DOWNLOAD_DOWNLOADING);
   140           stmt.bindByIndex(2, Ci.nsIDownloadManager.DOWNLOAD_PAUSED);
   141           stmt.bindByIndex(3, Ci.nsIDownloadManager.DOWNLOAD_QUEUED);
   142           try {
   143             stmt.execute();
   144           }
   145           finally {
   146             stmt.finalize();
   147           }
   148         }
   150         // Completed downloads
   151         deleteAllLike(dm.DBConnection);
   152         deleteAllLike(dm.privateDBConnection);
   154         // We want to rebuild the list if the UI is showing, so dispatch the
   155         // observer topic
   156         let os = Cc["@mozilla.org/observer-service;1"].
   157                  getService(Ci.nsIObserverService);
   158         os.notifyObservers(null, "download-manager-remove-download", null);
   159       }
   160     }
   162     // Passwords
   163     let (lm = Cc["@mozilla.org/login-manager;1"].
   164               getService(Ci.nsILoginManager)) {
   165       // Clear all passwords for domain
   166       try {
   167         let logins = lm.getAllLogins();
   168         for (let i = 0; i < logins.length; i++)
   169           if (hasRootDomain(logins[i].hostname, aDomain))
   170             lm.removeLogin(logins[i]);
   171       }
   172       // XXXehsan: is there a better way to do this rather than this
   173       // hacky comparison?
   174       catch (ex if ex.message.indexOf("User canceled Master Password entry") != -1) { }
   176       // Clear any "do not save for this site" for this domain
   177       let disabledHosts = lm.getAllDisabledHosts();
   178       for (let i = 0; i < disabledHosts.length; i++)
   179         if (hasRootDomain(disabledHosts[i], aDomain))
   180           lm.setLoginSavingEnabled(disabledHosts, true);
   181     }
   183     // Permissions
   184     let (pm = Cc["@mozilla.org/permissionmanager;1"].
   185               getService(Ci.nsIPermissionManager)) {
   186       // Enumerate all of the permissions, and if one matches, remove it
   187       let enumerator = pm.enumerator;
   188       while (enumerator.hasMoreElements()) {
   189         let perm = enumerator.getNext().QueryInterface(Ci.nsIPermission);
   190         if (hasRootDomain(perm.host, aDomain))
   191           pm.remove(perm.host, perm.type);
   192       }
   193     }
   195     // Offline Storages
   196     let (qm = Cc["@mozilla.org/dom/quota/manager;1"].
   197               getService(Ci.nsIQuotaManager)) {
   198       // delete data from both HTTP and HTTPS sites
   199       let caUtils = {};
   200       let scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
   201                          getService(Ci.mozIJSSubScriptLoader);
   202       scriptLoader.loadSubScript("chrome://global/content/contentAreaUtils.js",
   203                                  caUtils);
   204       let httpURI = caUtils.makeURI("http://" + aDomain);
   205       let httpsURI = caUtils.makeURI("https://" + aDomain);
   206       qm.clearStoragesForURI(httpURI);
   207       qm.clearStoragesForURI(httpsURI);
   208     }
   210     function onContentPrefsRemovalFinished() {
   211       // Everybody else (including extensions)
   212       Services.obs.notifyObservers(null, "browser:purge-domain-data", aDomain);
   213     }
   215     // Content Preferences
   216     let cps2 = Cc["@mozilla.org/content-pref/service;1"].
   217                getService(Ci.nsIContentPrefService2);
   218     cps2.removeBySubdomain(aDomain, null, {
   219       handleCompletion: function() onContentPrefsRemovalFinished(),
   220       handleError: function() {}
   221     });
   223     // Predictive network data - like cache, no way to clear this per
   224     // domain, so just trash it all
   225     let ns = Cc["@mozilla.org/network/seer;1"].
   226              getService(Ci.nsINetworkSeer);
   227     ns.reset();
   228   }
   229 };

mercurial