summaryrefslogtreecommitdiffstats
path: root/toolkit/components/thumbnails/PageThumbsProtocol.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/thumbnails/PageThumbsProtocol.js')
-rw-r--r--toolkit/components/thumbnails/PageThumbsProtocol.js154
1 files changed, 154 insertions, 0 deletions
diff --git a/toolkit/components/thumbnails/PageThumbsProtocol.js b/toolkit/components/thumbnails/PageThumbsProtocol.js
new file mode 100644
index 000000000..41dfe96be
--- /dev/null
+++ b/toolkit/components/thumbnails/PageThumbsProtocol.js
@@ -0,0 +1,154 @@
+/* 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/. */
+
+/**
+ * PageThumbsProtocol.js
+ *
+ * This file implements the moz-page-thumb:// protocol and the corresponding
+ * channel delivering cached thumbnails.
+ *
+ * URL structure:
+ *
+ * moz-page-thumb://thumbnail/?url=http%3A%2F%2Fwww.mozilla.org%2F&revision=XX
+ *
+ * This URL requests an image for 'http://www.mozilla.org/'.
+ * The value of the revision key may change when the stored thumbnail changes.
+ */
+
+"use strict";
+
+const Cu = Components.utils;
+const Cc = Components.classes;
+const Cr = Components.results;
+const Ci = Components.interfaces;
+
+Cu.import("resource://gre/modules/PageThumbs.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/osfile.jsm", this);
+
+XPCOMUtils.defineLazyModuleGetter(this, "Services",
+ "resource://gre/modules/Services.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
+ "resource://gre/modules/FileUtils.jsm");
+
+const SUBSTITUTING_URL_CID = "{dea9657c-18cf-4984-bde9-ccef5d8ab473}";
+
+/**
+ * Implements the thumbnail protocol handler responsible for moz-page-thumb: URLs.
+ */
+function Protocol() {
+}
+
+Protocol.prototype = {
+ /**
+ * The scheme used by this protocol.
+ */
+ get scheme() {
+ return PageThumbs.scheme;
+ },
+
+ /**
+ * The default port for this protocol (we don't support ports).
+ */
+ get defaultPort() {
+ return -1;
+ },
+
+ /**
+ * The flags specific to this protocol implementation.
+ */
+ get protocolFlags() {
+ return Ci.nsIProtocolHandler.URI_DANGEROUS_TO_LOAD |
+ Ci.nsIProtocolHandler.URI_IS_LOCAL_RESOURCE |
+ Ci.nsIProtocolHandler.URI_NORELATIVE |
+ Ci.nsIProtocolHandler.URI_NOAUTH;
+ },
+
+ /**
+ * Creates a new URI object that is suitable for loading by this protocol.
+ * @param aSpec The URI string in UTF8 encoding.
+ * @param aOriginCharset The charset of the document from which the URI originated.
+ * @return The newly created URI.
+ */
+ newURI: function Proto_newURI(aSpec, aOriginCharset) {
+ let uri = Components.classesByID[SUBSTITUTING_URL_CID].createInstance(Ci.nsIURL);
+ uri.spec = aSpec;
+ return uri;
+ },
+
+ /**
+ * Constructs a new channel from the given URI for this protocol handler.
+ * @param aURI The URI for which to construct a channel.
+ * @param aLoadInfo The Loadinfo which to use on the channel.
+ * @return The newly created channel.
+ */
+ newChannel2: function Proto_newChannel2(aURI, aLoadInfo) {
+ let {file} = aURI.QueryInterface(Ci.nsIFileURL);
+ let fileuri = Services.io.newFileURI(file);
+ let channel = Services.io.newChannelFromURIWithLoadInfo(fileuri, aLoadInfo);
+ channel.originalURI = aURI;
+ return channel;
+ },
+
+ newChannel: function Proto_newChannel(aURI) {
+ return this.newChannel2(aURI, null);
+ },
+
+ /**
+ * Decides whether to allow a blacklisted port.
+ * @return Always false, we'll never allow ports.
+ */
+ allowPort: () => false,
+
+ // nsISubstitutingProtocolHandler methods
+
+ /*
+ * Substituting the scheme and host isn't enough, we also transform the path.
+ * So declare no-op implementations for (get|set|has)Substitution methods and
+ * do all the work in resolveURI.
+ */
+
+ setSubstitution(root, baseURI) {},
+
+ getSubstitution(root) {
+ throw Cr.NS_ERROR_NOT_AVAILABLE;
+ },
+
+ hasSubstitution(root) {
+ return false;
+ },
+
+ resolveURI(resURI) {
+ let {url} = parseURI(resURI);
+ let path = PageThumbsStorage.getFilePathForURL(url);
+ return OS.Path.toFileURI(path);
+ },
+
+ // xpcom machinery
+ classID: Components.ID("{5a4ae9b5-f475-48ae-9dce-0b4c1d347884}"),
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIProtocolHandler,
+ Ci.nsISubstitutingProtocolHandler])
+};
+
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory([Protocol]);
+
+/**
+ * Parses a given URI and extracts all parameters relevant to this protocol.
+ * @param aURI The URI to parse.
+ * @return The parsed parameters.
+ */
+function parseURI(aURI) {
+ if (aURI.host != PageThumbs.staticHost)
+ throw Cr.NS_ERROR_NOT_AVAILABLE;
+
+ let {query} = aURI.QueryInterface(Ci.nsIURL);
+ let params = {};
+
+ query.split("&").forEach(function (aParam) {
+ let [key, value] = aParam.split("=").map(decodeURIComponent);
+ params[key.toLowerCase()] = value;
+ });
+
+ return params;
+}