1 # -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 # ***** BEGIN LICENSE BLOCK *****
3 # Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 # The contents of this file are subject to the Mozilla Public License Version
6 # 1.1 (the "License"); you may not use this file except in compliance with
7 # the License. You may obtain a copy of the License at
8 # http://www.mozilla.org/MPL/
10 # Software distributed under the License is distributed on an "AS IS" basis,
11 # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 # for the specific language governing rights and limitations under the
15 # The Original Code is the Web Content Converter System.
17 # The Initial Developer of the Original Code is Google Inc.
18 # Portions created by the Initial Developer are Copyright (C) 2006
19 # the Initial Developer. All Rights Reserved.
22 # Ben Goodger <beng@google.com>
23 # Asaf Romano <mano@mozilla.com>
24 # Dan Mosedale <dmose@mozilla.org>
26 # Alternatively, the contents of this file may be used under the terms of
27 # either the GNU General Public License Version 2 or later (the "GPL"), or
28 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 # in which case the provisions of the GPL or the LGPL are applicable instead
30 # of those above. If you wish to allow use of your version of this file only
31 # under the terms of either the GPL or the LGPL, and not to allow others to
32 # use your version of this file under the terms of the MPL, indicate your
33 # decision by deleting the provisions above and replace them with the notice
34 # and other provisions required by the GPL or the LGPL. If you do not delete
35 # the provisions above, a recipient may use your version of this file under
36 # the terms of any one of the MPL, the GPL or the LGPL.
38 # ***** END LICENSE BLOCK ***** */
40 Components.utils.import(
"resource://gre/modules/XPCOMUtils.jsm");
42 const Cc = Components.classes;
43 const Ci = Components.interfaces;
44 const Cr = Components.results;
47 dump(
"*** " +
str +
"\n");
50 const WCCR_CONTRACTID =
"@mozilla.org/embeddor.implemented/web-content-handler-registrar;1";
51 const WCCR_CLASSID = Components.ID(
"{792a7e82-06a0-437c-af63-b2d12e808acc}");
54 const WCC_CLASSID = Components.ID(
"{db7ebf28-cc40-415f-8a51-1b111851df1e}");
76 convert:
function WCC_convert() { },
77 asyncConvertData:
function WCC_asyncConvertData() { },
78 onDataAvailable:
function WCC_onDataAvailable() { },
79 onStopRequest:
function WCC_onStopRequest() { },
81 onStartRequest:
function WCC_onStartRequest(request, context) {
85 wccr.loadPreferredHandler(request);
89 if (iid.equals(
Ci.nsIStreamConverter) ||
90 iid.equals(
Ci.nsIStreamListener) ||
91 iid.equals(
Ci.nsISupports))
93 throw Cr.NS_ERROR_NO_INTERFACE;
100 throw Cr.NS_ERROR_NO_AGGREGATION;
105 if (iid.equals(
Ci.nsIFactory) ||
106 iid.equals(
Ci.nsISupports))
108 throw Cr.NS_ERROR_NO_INTERFACE;
113 this._contentType = contentType;
128 equals:
function SI_equals(aHandlerApp) {
130 throw Cr.NS_ERROR_NULL_POINTER;
132 if (aHandlerApp instanceof
Ci.nsIWebContentHandlerInfo &&
133 aHandlerApp.contentType ==
this.contentType &&
134 aHandlerApp.uri ==
this.uri)
144 return this._contentType;
157 getHandlerURI:
function SI_getHandlerURI(
uri) {
162 if (iid.equals(
Ci.nsIWebContentHandlerInfo) ||
163 iid.equals(
Ci.nsISupports))
165 throw Cr.NS_ERROR_NO_INTERFACE;
170 this._contentTypes = { };
171 this._autoHandleContentTypes = { };
176 var sb =
Cc[
"@mozilla.org/intl/stringbundle;1"].
183 _getFormattedString:
function WCCR__getFormattedString(
key, params) {
184 return this.stringBundle.formatStringFromName(
key, params, params.length);
187 _getString:
function WCCR_getString(
key) {
188 return this.stringBundle.GetStringFromName(
key);
195 function WCCR_getAutoHandler(contentType) {
196 contentType = this._resolveContentType(contentType);
197 if (contentType in this._autoHandleContentTypes)
198 return this._autoHandleContentTypes[contentType];
206 function WCCR_setAutoHandler(contentType,
handler) {
208 throw Cr.NS_ERROR_NOT_AVAILABLE;
210 contentType = this._resolveContentType(contentType);
211 this._setAutoHandler(contentType,
handler);
214 Cc[
"@mozilla.org/preferences-service;1"].
218 autoBranch.setCharPref(contentType,
handler.uri);
219 else if (autoBranch.prefHasUserValue(contentType))
220 autoBranch.clearUserPref(contentType);
222 ps.savePrefFile(
null);
229 function WCCR__setAutoHandler(contentType,
handler) {
231 this._autoHandleContentTypes[contentType] =
handler;
232 else if (contentType in this._autoHandleContentTypes)
233 delete this._autoHandleContentTypes[contentType];
239 getWebContentHandlerByURI:
240 function WCCR_getWebContentHandlerByURI(contentType,
uri) {
241 var
handlers = this.getContentHandlers(contentType, { });
242 for (var
i = 0;
i < handlers.length; ++
i) {
252 loadPreferredHandler:
253 function WCCR_loadPreferredHandler(request) {
254 var channel = request.QueryInterface(
Ci.nsIChannel);
255 var contentType = this._resolveContentType(channel.contentType);
256 var
handler = this.getAutoHandler(contentType);
258 request.cancel(
Cr.NS_ERROR_FAILURE);
261 channel.notificationCallbacks.getInterface(
Ci.nsIWebNavigation);
262 webNavigation.loadURI(handler.getHandlerURI(channel.URI.spec),
263 Ci.nsIWebNavigation.LOAD_FLAGS_NONE,
271 removeProtocolHandler:
272 function WCCR_removeProtocolHandler(aProtocol, aURITemplate) {
273 var eps =
Cc[
"@mozilla.org/uriloader/external-protocol-service;1"].
275 var handlerInfo = eps.getProtocolHandlerInfo(aProtocol);
276 var handlers = handlerInfo.possibleApplicationHandlers;
277 for (let
i = 0;
i < handlers.length;
i++) {
279 let handler = handlers.queryElementAt(
i,
Ci.nsIWebHandlerApp);
280 if (handler.uriTemplate == aURITemplate) {
281 handlers.removeElementAt(
i);
282 var
hs =
Cc[
"@mozilla.org/uriloader/handler-service;1"].
284 hs.store(handlerInfo);
294 removeContentHandler:
295 function WCCR_removeContentHandler(contentType,
uri) {
296 function notURI(serviceInfo) {
297 return serviceInfo.uri !=
uri;
300 if (contentType in this._contentTypes) {
301 this._contentTypes[contentType] =
302 this._contentTypes[contentType].filter(notURI);
320 "application/vnd.mozilla.maybe.feed":
true,
329 function WCCR__resolveContentType(contentType) {
330 if (contentType in this._mappings)
331 return this._mappings[contentType];
335 _makeURI:
function(aURL, aOriginCharset, aBaseURI) {
336 var
ioService = Components.classes[
"@mozilla.org/network/io-service;1"]
337 .getService(Components.interfaces.nsIIOService);
338 return ioService.newURI(aURL, aOriginCharset, aBaseURI);
342 function WCCR_checkAndGetURI(aURIString, aContentWindow)
345 var
uri = this._makeURI(aURIString);
355 if (
uri.scheme !=
"http" &&
uri.scheme !=
"https")
356 throw(
"Permission denied to add " +
uri.spec +
" as a content or protocol handler");
360 var
pb =
Cc[
"@mozilla.org/preferences-service;1"].getService(
Ci.nsIPrefBranch);
363 aContentWindow.location.hostname !=
uri.host)
364 throw(
"Permission denied to add " +
uri.spec +
" as a content or protocol handler");
367 if (
uri.spec.indexOf(
"%s") < 0)
382 _protocolHandlerRegistered:
383 function WCCR_protocolHandlerRegistered(aProtocol, aURITemplate) {
384 var eps =
Cc[
"@mozilla.org/uriloader/external-protocol-service;1"].
386 var handlerInfo = eps.getProtocolHandlerInfo(aProtocol);
387 var handlers = handlerInfo.possibleApplicationHandlers;
388 for (let
i = 0;
i < handlers.length;
i++) {
390 let handler = handlers.queryElementAt(
i,
Ci.nsIWebHandlerApp);
391 if (handler.uriTemplate == aURITemplate)
401 registerProtocolHandler:
402 function WCCR_registerProtocolHandler(aProtocol, aURIString, aTitle, aContentWindow) {
403 LOG(
"registerProtocolHandler(" + aProtocol +
"," + aURIString +
"," + aTitle +
")");
407 var
ios =
Cc[
"@mozilla.org/network/io-service;1"].
409 var handler = ios.getProtocolHandler(aProtocol);
410 if (!(handler instanceof
Ci.nsIExternalProtocolHandler)) {
414 throw(
"Permission denied to add " + aURIString +
"as a protocol handler");
418 var pb =
Cc[
"@mozilla.org/preferences-service;1"].getService(
Ci.nsIPrefBranch);
428 throw(
"Not allowed to register a protocol handler for " + aProtocol);
431 var
uri = this._checkAndGetURI(aURIString, aContentWindow);
434 if (this._protocolHandlerRegistered(aProtocol, uri.spec))
435 message = this._getFormattedString(
"protocolHandlerRegistered",
436 [aTitle, aProtocol]);
439 message = this._getFormattedString(
"addProtocolHandler",
440 [aTitle, uri.host, aProtocol]);
441 var fis =
Cc[
"@mozilla.org/browser/favicon-service;1"].
443 var notificationIcon = fis.getFaviconLinkForIcon(uri);
444 var notificationValue =
"Protocol Registration: " + aProtocol;
446 label: this._getString(
"addProtocolHandlerAddButton"),
447 accessKey: this._getString(
"addHandlerAddButtonAccesskey"),
448 protocolInfo: { protocol: aProtocol, uri: uri.spec,
name: aTitle },
451 function WCCR_addProtocolHandlerButtonCallback(aNotification, aButtonInfo) {
452 var protocol = aButtonInfo.protocolInfo.protocol;
453 var uri = aButtonInfo.protocolInfo.uri;
454 var
name = aButtonInfo.protocolInfo.name;
456 var handler =
Cc[
"@mozilla.org/uriloader/web-handler-app;1"].
459 handler.uriTemplate =
uri;
461 var eps =
Cc[
"@mozilla.org/uriloader/external-protocol-service;1"].
463 var handlerInfo = eps.getProtocolHandlerInfo(protocol);
464 handlerInfo.possibleApplicationHandlers.appendElement(handler,
false);
470 handlerInfo.alwaysAskBeforeHandling =
true;
472 var
hs =
Cc[
"@mozilla.org/uriloader/handler-service;1"].
474 hs.store(handlerInfo);
477 buttons = [addButton];
480 var browserWindow = this._getBrowserWindowForContentWindow(aContentWindow);
481 var browserElement = this._getBrowserForContentWindow(browserWindow, aContentWindow);
482 var notificationBox = browserWindow.getBrowser().getNotificationBox(browserElement);
483 notificationBox.appendNotification(message,
486 notificationBox.PRIORITY_INFO_LOW,
495 registerContentHandler:
496 function WCCR_registerContentHandler(aContentType, aURIString, aTitle, aContentWindow) {
497 LOG(
"registerContentHandler(" + aContentType +
"," + aURIString +
"," + aTitle +
")");
502 var contentType = this._resolveContentType(aContentType);
506 if (aContentWindow) {
507 var uri = this._checkAndGetURI(aURIString, aContentWindow);
509 var browserWindow = this._getBrowserWindowForContentWindow(aContentWindow);
510 var browserElement = this._getBrowserForContentWindow(browserWindow, aContentWindow);
511 var notificationBox = browserWindow.getBrowser().getNotificationBox(browserElement);
512 this._appendFeedReaderNotification(uri, aTitle, notificationBox);
515 this._registerContentHandler(contentType, aURIString, aTitle);
521 _getBrowserWindowForContentWindow:
522 function WCCR__getBrowserWindowForContentWindow(aContentWindow) {
523 return aContentWindow.QueryInterface(
Ci.nsIInterfaceRequestor)
524 .getInterface(
Ci.nsIWebNavigation)
525 .QueryInterface(
Ci.nsIDocShellTreeItem)
527 .QueryInterface(
Ci.nsIInterfaceRequestor)
528 .getInterface(
Ci.nsIDOMWindow)
542 _getBrowserForContentWindow:
543 function WCCR__getBrowserForContentWindow(aBrowserWindow, aContentWindow) {
545 aContentWindow = aContentWindow.top;
546 var browsers = aBrowserWindow.getBrowser().browsers;
547 for (var
i = 0;
i < browsers.length; ++
i) {
548 if (browsers[
i].contentWindow == aContentWindow)
574 _appendFeedReaderNotification:
575 function WCCR__appendFeedReaderNotification(aURI,
aName, aNotificationBox) {
576 var uriSpec = aURI.spec;
577 var notificationValue =
"feed reader notification: " + uriSpec;
578 var notificationIcon = aURI.prePath +
"/favicon.ico";
582 if (aNotificationBox.getNotificationWithValue(notificationValue))
587 message = this._getFormattedString(
"handlerRegistered", [
aName]);
589 message = this._getFormattedString(
"addHandler", [
aName, aURI.host]);
593 label:
self._getString(
"addHandlerAddButton"),
594 accessKey:
self._getString(
"addHandlerAddButtonAccesskey"),
595 feedReaderInfo: { uri: uriSpec, name:
aName },
599 function WCCR__addFeedReaderButtonCallback(aNotification, aButtonInfo) {
600 var uri = aButtonInfo.feedReaderInfo.uri;
601 var name = aButtonInfo.feedReaderInfo.name;
602 var outer = aButtonInfo._outer;
609 aButtonInfo._outer =
null;
614 buttons = [addButton];
617 aNotificationBox.appendNotification(message,
620 aNotificationBox.PRIORITY_INFO_LOW,
640 _saveContentHandlerToPrefs:
641 function WCCR__saveContentHandlerToPrefs(contentType, uri, title) {
643 Cc[
"@mozilla.org/preferences-service;1"].
646 var typeBranch =
null;
651 typeBranch.getCharPref(
"type");
660 typeBranch.setCharPref(
"type", contentType);
662 Cc[
"@mozilla.org/pref-localizedstring;1"].
665 typeBranch.setComplexValue(
"uri",
Ci.nsIPrefLocalizedString, pls);
667 typeBranch.setComplexValue(
"title",
Ci.nsIPrefLocalizedString, pls);
669 ps.savePrefFile(
null);
681 _typeIsRegistered:
function WCCR__typeIsRegistered(contentType, uri) {
682 if (!(contentType in this._contentTypes))
685 var services = this._contentTypes[contentType];
686 for (var i = 0; i < services.length; ++
i) {
688 if (services[i].uri == uri)
701 _getConverterContractID:
function WCCR__getConverterContractID(contentType) {
702 const template =
"@mozilla.org/streamconv;1?from=%s&to=*/*";
703 return template.replace(/%s/, contentType);
716 _registerContentHandler:
717 function WCCR__registerContentHandler(contentType, uri, title) {
718 this._updateContentTypeHandlerMap(contentType, uri, title);
719 this._saveContentHandlerToPrefs(contentType, uri, title);
724 var pb =
Cc[
"@mozilla.org/preferences-service;1"].
729 Cc[
"@mozilla.org/supports-string;1"].
731 supportsString.data =
uri;
749 _updateContentTypeHandlerMap:
750 function WCCR__updateContentTypeHandlerMap(contentType, uri, title) {
751 if (!(contentType in this._contentTypes))
752 this._contentTypes[contentType] = [];
755 if (this._typeIsRegistered(contentType, uri))
758 this._contentTypes[contentType].push(
new ServiceInfo(contentType, uri, title));
760 if (!(contentType in this._blockedTypes)) {
761 var converterContractID = this._getConverterContractID(contentType);
762 var
cr = Components.manager.QueryInterface(
Ci.nsIComponentRegistrar);
764 WebContentConverterFactory);
772 function WCCR_getContentHandlers(contentType, countRef) {
774 if (!(contentType in this._contentTypes))
777 var handlers = this._contentTypes[contentType];
778 countRef.value = handlers.length;
785 resetHandlersForType:
786 function WCCR_resetHandlersForType(contentType) {
790 throw Cr.NS_ERROR_NOT_IMPLEMENTED;
800 _registerContentHandlerWithBranch:
function(branch) {
809 var vals = branch.getChildList(
"", {});
810 if (vals.length == 0)
814 var type = branch.getCharPref(
"type");
815 var uri = branch.getComplexValue(
"uri",
Ci.nsIPrefLocalizedString).data;
816 var title = branch.getComplexValue(
"title",
817 Ci.nsIPrefLocalizedString).data;
818 this._updateContentTypeHandlerMap(type, uri, title);
829 _init:
function WCCR__init() {
831 Cc[
"@mozilla.org/preferences-service;1"].
835 .getChildList(
"", {});
839 for (var i = 0; i < kids.length; i++) {
840 var
match = /^(
\d+)\.uri$/.exec(kids[i]);
848 nums.sort(
function(a, b) {
return a - b;});
851 for (var i = 0; i < nums.length; i++) {
853 this._registerContentHandlerWithBranch(branch);
860 var childPrefs = autoBranch.getChildList(
"", { });
861 for (var i = 0; i < childPrefs.length; ++
i) {
862 var type = childPrefs[
i];
863 var uri = autoBranch.getCharPref(type);
865 var handler = this.getWebContentHandlerByURI(type, uri);
866 this._setAutoHandler(type, handler);
881 Cc[
"@mozilla.org/observer-service;1"].
885 os.addObserver(
this,
"browser-ui-startup-complete",
false);
887 case "browser-ui-startup-complete":
888 os.removeObserver(
this,
"browser-ui-startup-complete");
899 throw Cr.NS_ERROR_NO_AGGREGATION;
908 [
Ci.nsIWebContentConverterService,
Ci.nsIWebContentHandlerRegistrar,
909 Ci.nsIObserver,
Ci.nsIClassInfo,
Ci.nsIFactory,
Ci.nsISupports];
910 countRef.value = interfaces.length;
920 flags:
Ci.nsIClassInfo.DOM_OBJECT,
926 [
Ci.nsIWebContentConverterService,
927 Ci.nsIWebContentHandlerRegistrar,
934 category:
"app-startup",
943 #include ../../../../toolkit/content/debug.js
function WebContentConverterRegistrar()
const NS_ERROR_DOM_SYNTAX_ERR
nsString encodeURIComponent(const nsString &c)
sbDeviceFirmwareAutoCheckForUpdate prototype flags
function ServiceInfo(contentType, uri, name)
sbDeviceFirmwareAutoCheckForUpdate prototype contractID
const NS_ERROR_MODULE_DOM
sbOSDControlService prototype QueryInterface
sbDeviceFirmwareAutoCheckForUpdate prototype classDescription
const PREF_SELECTED_ACTION
getService(Ci.sbIFaceplateManager)
sbDeviceFirmwareAutoCheckForUpdate prototype getHelperForLanguage
this _contentSandbox label
const PREF_SELECTED_READER
var WebContentConverterFactory
const PREF_CONTENTHANDLERS_AUTO
function WebContentConverter()
ExtensionSchemeMatcher prototype match
const PREF_HANDLER_EXTERNAL_PREFIX
sbDeviceFirmwareAutoCheckForUpdate prototype classID
sbWindowsAutoPlayServiceCfg _xpcom_categories
sbDeviceFirmwareAutoCheckForUpdate prototype getInterfaces
sbDeviceFirmwareAutoCheckForUpdate prototype interfaces
classDescription implementationLanguage
const PREF_CONTENTHANDLERS_BRANCH
_getSelectedPageStyle s i
const PREF_ALLOW_DIFFERENT_HOST
sbDeviceFirmwareAutoCheckForUpdate prototype observe