diff options
Diffstat (limited to 'toolkit/components/thumbnails/PageThumbsProtocol.js')
-rw-r--r-- | toolkit/components/thumbnails/PageThumbsProtocol.js | 154 |
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; +} |