1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
|
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* 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/. */
var EXPORTED_SYMBOLS = ["WebProtocolHandlerRegistrar"];
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
const STRING_BUNDLE_URI = "chrome://browser/locale/feeds/subscribe.properties";
function WebProtocolHandlerRegistrar() {}
WebProtocolHandlerRegistrar.prototype = {
get stringBundle() {
let sb = Services.strings.createBundle(STRING_BUNDLE_URI);
delete WebProtocolHandlerRegistrar.prototype.stringBundle;
return (WebProtocolHandlerRegistrar.prototype.stringBundle = sb);
},
_getFormattedString(key, params) {
return this.stringBundle.formatStringFromName(key, params);
},
_getString(key) {
return this.stringBundle.GetStringFromName(key);
},
/**
* See nsIWebProtocolHandlerRegistrar
*/
removeProtocolHandler(aProtocol, aURITemplate) {
let eps = Cc[
"@mozilla.org/uriloader/external-protocol-service;1"
].getService(Ci.nsIExternalProtocolService);
let handlerInfo = eps.getProtocolHandlerInfo(aProtocol);
let handlers = handlerInfo.possibleApplicationHandlers;
for (let i = 0; i < handlers.length; i++) {
try {
// We only want to test web handlers
let handler = handlers.queryElementAt(i, Ci.nsIWebHandlerApp);
if (handler.uriTemplate == aURITemplate) {
handlers.removeElementAt(i);
let hs = Cc["@mozilla.org/uriloader/handler-service;1"].getService(
Ci.nsIHandlerService
);
hs.store(handlerInfo);
return;
}
} catch (e) {
/* it wasn't a web handler */
}
}
},
/**
* Determines if a web handler is already registered.
*
* @param aProtocol
* The scheme of the web handler we are checking for.
* @param aURITemplate
* The URI template that the handler uses to handle the protocol.
* @return true if it is already registered, false otherwise.
*/
_protocolHandlerRegistered(aProtocol, aURITemplate) {
let eps = Cc[
"@mozilla.org/uriloader/external-protocol-service;1"
].getService(Ci.nsIExternalProtocolService);
let handlerInfo = eps.getProtocolHandlerInfo(aProtocol);
let handlers = handlerInfo.possibleApplicationHandlers;
for (let i = 0; i < handlers.length; i++) {
try {
// We only want to test web handlers
let handler = handlers.queryElementAt(i, Ci.nsIWebHandlerApp);
if (handler.uriTemplate == aURITemplate) {
return true;
}
} catch (e) {
/* it wasn't a web handler */
}
}
return false;
},
/**
* See nsIWebProtocolHandlerRegistrar
*/
registerProtocolHandler(
aProtocol,
aURI,
aTitle,
aDocumentURI,
aBrowserOrWindow
) {
aProtocol = (aProtocol || "").toLowerCase();
if (!aURI || !aDocumentURI) {
return;
}
let browser = aBrowserOrWindow; // This is the e10s case.
if (aBrowserOrWindow instanceof Ci.nsIDOMWindow) {
// In the non-e10s case, grab the browser off the same-process window.
let rootDocShell = aBrowserOrWindow.docShell.sameTypeRootTreeItem;
browser = rootDocShell.QueryInterface(Ci.nsIDocShell).chromeEventHandler;
}
let browserWindow = browser.ownerGlobal;
try {
browserWindow.navigator.checkProtocolHandlerAllowed(
aProtocol,
aURI,
aDocumentURI
);
} catch (ex) {
// We should have already shown the user an error.
return;
}
// If the protocol handler is already registered, just return early.
if (this._protocolHandlerRegistered(aProtocol, aURI.spec)) {
return;
}
// Now Ask the user and provide the proper callback
let message = this._getFormattedString("addProtocolHandlerMessage", [
aURI.host,
aProtocol,
]);
let notificationIcon = aURI.prePath + "/favicon.ico";
let notificationValue = "Protocol Registration: " + aProtocol;
let addButton = {
label: this._getString("addProtocolHandlerAddButton"),
accessKey: this._getString("addProtocolHandlerAddButtonAccesskey"),
protocolInfo: { protocol: aProtocol, uri: aURI.spec, name: aTitle },
callback(aNotification, aButtonInfo) {
let protocol = aButtonInfo.protocolInfo.protocol;
let name = aButtonInfo.protocolInfo.name;
let handler = Cc[
"@mozilla.org/uriloader/web-handler-app;1"
].createInstance(Ci.nsIWebHandlerApp);
handler.name = name;
handler.uriTemplate = aButtonInfo.protocolInfo.uri;
let eps = Cc[
"@mozilla.org/uriloader/external-protocol-service;1"
].getService(Ci.nsIExternalProtocolService);
let handlerInfo = eps.getProtocolHandlerInfo(protocol);
handlerInfo.possibleApplicationHandlers.appendElement(handler);
// Since the user has agreed to add a new handler, chances are good
// that the next time they see a handler of this type, they're going
// to want to use it. Reset the handlerInfo to ask before the next
// use.
handlerInfo.alwaysAskBeforeHandling = true;
let hs = Cc["@mozilla.org/uriloader/handler-service;1"].getService(
Ci.nsIHandlerService
);
hs.store(handlerInfo);
},
};
let notificationBox = browser.getTabBrowser().getNotificationBox(browser);
notificationBox.appendNotification(
message,
notificationValue,
notificationIcon,
notificationBox.PRIORITY_INFO_LOW,
[addButton]
);
},
/**
* See nsISupports
*/
QueryInterface: ChromeUtils.generateQI(["nsIWebProtocolHandlerRegistrar"]),
};
|