michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /** michael@0: * PageThumbsProtocol.js michael@0: * michael@0: * This file implements the moz-page-thumb:// protocol and the corresponding michael@0: * channel delivering cached thumbnails. michael@0: * michael@0: * URL structure: michael@0: * michael@0: * moz-page-thumb://thumbnail?url=http%3A%2F%2Fwww.mozilla.org%2F michael@0: * michael@0: * This URL requests an image for 'http://www.mozilla.org/'. michael@0: */ michael@0: michael@0: "use strict"; michael@0: michael@0: const Cu = Components.utils; michael@0: const Cc = Components.classes; michael@0: const Cr = Components.results; michael@0: const Ci = Components.interfaces; michael@0: michael@0: Cu.import("resource://gre/modules/PageThumbs.jsm"); michael@0: Cu.import("resource://gre/modules/XPCOMUtils.jsm"); michael@0: michael@0: XPCOMUtils.defineLazyModuleGetter(this, "Services", michael@0: "resource://gre/modules/Services.jsm"); michael@0: XPCOMUtils.defineLazyModuleGetter(this, "FileUtils", michael@0: "resource://gre/modules/FileUtils.jsm"); michael@0: michael@0: /** michael@0: * Implements the thumbnail protocol handler responsible for moz-page-thumb: URIs. michael@0: */ michael@0: function Protocol() { michael@0: } michael@0: michael@0: Protocol.prototype = { michael@0: /** michael@0: * The scheme used by this protocol. michael@0: */ michael@0: get scheme() PageThumbs.scheme, michael@0: michael@0: /** michael@0: * The default port for this protocol (we don't support ports). michael@0: */ michael@0: get defaultPort() -1, michael@0: michael@0: /** michael@0: * The flags specific to this protocol implementation. michael@0: */ michael@0: get protocolFlags() { michael@0: return Ci.nsIProtocolHandler.URI_DANGEROUS_TO_LOAD | michael@0: Ci.nsIProtocolHandler.URI_NORELATIVE | michael@0: Ci.nsIProtocolHandler.URI_NOAUTH; michael@0: }, michael@0: michael@0: /** michael@0: * Creates a new URI object that is suitable for loading by this protocol. michael@0: * @param aSpec The URI string in UTF8 encoding. michael@0: * @param aOriginCharset The charset of the document from which the URI originated. michael@0: * @return The newly created URI. michael@0: */ michael@0: newURI: function Proto_newURI(aSpec, aOriginCharset) { michael@0: let uri = Cc["@mozilla.org/network/simple-uri;1"].createInstance(Ci.nsIURI); michael@0: uri.spec = aSpec; michael@0: return uri; michael@0: }, michael@0: michael@0: /** michael@0: * Constructs a new channel from the given URI for this protocol handler. michael@0: * @param aURI The URI for which to construct a channel. michael@0: * @return The newly created channel. michael@0: */ michael@0: newChannel: function Proto_newChannel(aURI) { michael@0: let {url} = parseURI(aURI); michael@0: let file = PageThumbsStorage.getFilePathForURL(url); michael@0: let fileuri = Services.io.newFileURI(new FileUtils.File(file)); michael@0: return Services.io.newChannelFromURI(fileuri); michael@0: }, michael@0: michael@0: /** michael@0: * Decides whether to allow a blacklisted port. michael@0: * @return Always false, we'll never allow ports. michael@0: */ michael@0: allowPort: function () false, michael@0: michael@0: classID: Components.ID("{5a4ae9b5-f475-48ae-9dce-0b4c1d347884}"), michael@0: QueryInterface: XPCOMUtils.generateQI([Ci.nsIProtocolHandler]) michael@0: }; michael@0: michael@0: this.NSGetFactory = XPCOMUtils.generateNSGetFactory([Protocol]); michael@0: michael@0: /** michael@0: * Parses a given URI and extracts all parameters relevant to this protocol. michael@0: * @param aURI The URI to parse. michael@0: * @return The parsed parameters. michael@0: */ michael@0: function parseURI(aURI) { michael@0: let {scheme, staticHost} = PageThumbs; michael@0: let re = new RegExp("^" + scheme + "://" + staticHost + ".*?\\?"); michael@0: let query = aURI.spec.replace(re, ""); michael@0: let params = {}; michael@0: michael@0: query.split("&").forEach(function (aParam) { michael@0: let [key, value] = aParam.split("=").map(decodeURIComponent); michael@0: params[key.toLowerCase()] = value; michael@0: }); michael@0: michael@0: return params; michael@0: }