-
Notifications
You must be signed in to change notification settings - Fork 20
/
protocolRedirect.html
112 lines (109 loc) · 3.53 KB
/
protocolRedirect.html
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
<!DOCTYPE HTML>
<meta charset="utf-8" />
<title>Private Tab: Redirect…</title>
<div id="output"></div>
<div id="usage" style="display: none;">
Usage example: <a href="private:https://addons.mozilla.org/">private:https://addons.mozilla.org/</a>
</div>
<script>
try {
Components.utils.import("resource://gre/modules/Services.jsm");
// Example: private:///#http://example.com/ (legacy) or private:http://example.com/
// Note: we use protocolRedirect.html#http://..., but we never (?) have it here
var spec = location.protocol == "private:"
? location.href.replace(/^\w+:\/*#?/, "")
: location.hash.substr(1);
try {
updateUI();
}
catch(e2) {
Components.utils.reportError(e2);
}
if(!spec)
throw new Error("No URI");
if(!/^[^:]+:/.test(spec))
spec = "http://" + spec;
var isValid = isValidURI(spec);
if(!isValid)
throw new Error("Invalid URI: " + spec);
document.title = getLoadingTitle() || spec;
location.replace(spec);
}
catch(e) {
document.title = "Private Tab: Can't redirect";
var out;
if(!("Services" in window)) // We can open this file directly using jar:file:///...
out = "Not enough permissions";
else {
setFavicon("chrome://global/skin/icons/warning-16.png");
if(!spec)
out = "Missing URI";
else if(!isValid)
out = "Malformed URI: " + spec;
}
out && document.getElementById("output").appendChild(document.createTextNode(out));
document.getElementById("usage").style.display = "";
throw e;
}
function updateUI() {
var dwu = "inIDOMUtils" in Components.interfaces
? Components.classes["@mozilla.org/inspector/dom-utils;1"]
.getService(Components.interfaces.inIDOMUtils)
: InspectorUtils; // Firefox 59+
var browser = dwu.getParentForNode(document, true);
if(
isXULElement(browser)
&& browser.localName.toLowerCase() == "browser"
) {
var win = browser.ownerDocument.defaultView;
if("privateTab" in win)
win.privateTab._handleProtocolBrowser(browser, document.documentURIObject);
return;
}
// Looks like multi-process mode
var mm = "nsIContentFrameMessageManager" in Components.interfaces
? window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDocShell)
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIContentFrameMessageManager)
: window.docShell.messageManager; // Firefox 63+
mm.sendAsyncMessage("PrivateTab:ProtocolURILoaded", {
URI: document.documentURI
});
}
function isXULElement(node) {
// https://bugzilla.mozilla.org/show_bug.cgi?format=default&id=1452185
return "nsIDOMXULElement" in Components.interfaces
? node instanceof Components.interfaces.nsIDOMXULElement
: node && ChromeUtils.getClassName(node) == "XULElement"; // Firefox 61+
}
function isValidURI(spec) {
try {
Services.io.newURI(spec, null, null); // Forbid relative URIs
var req = new XMLHttpRequest();
req.open("head", spec, true); // Simple way to try create nsIChannel instance
return !!req.channel;
}
catch(e) {
}
return false;
}
function getLoadingTitle() {
function string(file, id) {
try {
return Services.strings.createBundle(file).GetStringFromName(id);
}
catch(e) {
}
return "";
}
return string("chrome://browser/locale/tabbrowser.properties", "tabs.connecting") // Firefox
|| string("chrome://navigator/locale/tabbrowser.properties", "tabs.loading"); // SeaMonkey
}
function setFavicon(iconURL) {
var icon = document.createElement("link");
icon.href = iconURL;
icon.rel = "shortcut icon";
document.documentElement.insertBefore(icon, document.documentElement.firstChild);
}
</script>