Merge pull request #2571 from thelounge/xpaw/protocol-handler
Implement irc:// protocol handler
This commit is contained in:
commit
93fcd57b2d
@ -320,4 +320,20 @@ function initialize() {
|
|||||||
// We always ask for synced settings even if it is disabled.
|
// We always ask for synced settings even if it is disabled.
|
||||||
// Settings can be mandatory to sync and it is used to determine sync base state.
|
// Settings can be mandatory to sync and it is used to determine sync base state.
|
||||||
socket.emit("setting:get");
|
socket.emit("setting:get");
|
||||||
|
|
||||||
|
// Protocol handler
|
||||||
|
const defaultClientButton = $("#make-default-client");
|
||||||
|
|
||||||
|
if (window.navigator.registerProtocolHandler) {
|
||||||
|
defaultClientButton.on("click", function() {
|
||||||
|
const uri = document.location.origin + document.location.pathname + "?uri=%s";
|
||||||
|
|
||||||
|
window.navigator.registerProtocolHandler("irc", uri, "The Lounge");
|
||||||
|
window.navigator.registerProtocolHandler("ircs", uri, "The Lounge");
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
defaultClientButton.hide();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,35 +90,95 @@ socket.on("configuration", function(data) {
|
|||||||
utils.togglePasswordField("#connect .reveal-password");
|
utils.togglePasswordField("#connect .reveal-password");
|
||||||
});
|
});
|
||||||
|
|
||||||
if ($(document.body).hasClass("public") && "URLSearchParams" in window) {
|
if ("URLSearchParams" in window) {
|
||||||
const params = new URLSearchParams(document.location.search);
|
const params = new URLSearchParams(document.location.search);
|
||||||
|
|
||||||
for (let [key, value] of params) {
|
if (params.has("uri")) {
|
||||||
// Support `channels` as a compatibility alias with other clients
|
parseIrcUri(params.get("uri") + location.hash, data);
|
||||||
if (key === "channels") {
|
} else if ($(document.body).hasClass("public")) {
|
||||||
key = "join";
|
parseOverrideParams(params, data);
|
||||||
}
|
|
||||||
|
|
||||||
if (!data.defaults.hasOwnProperty(key)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key === "join") {
|
|
||||||
value = value.split(",").map((chan) => {
|
|
||||||
if (!chan.match(/^[#&!+]/)) {
|
|
||||||
return `#${chan}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return chan;
|
|
||||||
}).join(", ");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Override server provided defaults with parameters passed in the URL if they match the data type
|
|
||||||
switch (typeof data.defaults[key]) {
|
|
||||||
case "boolean": data.defaults[key] = value === "1" || value === "true"; break;
|
|
||||||
case "number": data.defaults[key] = Number(value); break;
|
|
||||||
case "string": data.defaults[key] = String(value); break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function parseIrcUri(stringUri, defaults) {
|
||||||
|
const data = Object.assign({}, defaults.defaults);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// https://tools.ietf.org/html/draft-butcher-irc-url-04
|
||||||
|
const uri = new URL(stringUri);
|
||||||
|
|
||||||
|
// Replace protocol with a "special protocol" (that's what it's called in WHATWG spec)
|
||||||
|
// So that the uri can be properly parsed
|
||||||
|
if (uri.protocol === "irc:") {
|
||||||
|
uri.protocol = "http:";
|
||||||
|
|
||||||
|
if (!uri.port) {
|
||||||
|
uri.port = 6667;
|
||||||
|
}
|
||||||
|
|
||||||
|
data.tls = false;
|
||||||
|
} else if (uri.protocol === "ircs:") {
|
||||||
|
uri.protocol = "https:";
|
||||||
|
|
||||||
|
if (!uri.port) {
|
||||||
|
uri.port = 6697;
|
||||||
|
}
|
||||||
|
|
||||||
|
data.tls = true;
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
data.host = data.name = uri.hostname;
|
||||||
|
data.port = uri.port;
|
||||||
|
data.username = window.decodeURIComponent(uri.username) || data.username;
|
||||||
|
data.password = window.decodeURIComponent(uri.password) || data.password;
|
||||||
|
|
||||||
|
let channel = (uri.pathname + uri.hash).substr(1);
|
||||||
|
const index = channel.indexOf(",");
|
||||||
|
|
||||||
|
if (index > -1) {
|
||||||
|
channel = channel.substring(0, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
data.join = channel;
|
||||||
|
|
||||||
|
// TODO: Need to show connect window with uri params without overriding defaults
|
||||||
|
defaults.defaults = data;
|
||||||
|
|
||||||
|
$('button[data-target="#connect"]').trigger("click");
|
||||||
|
} catch (e) {
|
||||||
|
// do nothing on invalid uri
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseOverrideParams(params, data) {
|
||||||
|
for (let [key, value] of params) {
|
||||||
|
// Support `channels` as a compatibility alias with other clients
|
||||||
|
if (key === "channels") {
|
||||||
|
key = "join";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data.defaults.hasOwnProperty(key)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key === "join") {
|
||||||
|
value = value.split(",").map((chan) => {
|
||||||
|
if (!chan.match(/^[#&!+]/)) {
|
||||||
|
return `#${chan}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return chan;
|
||||||
|
}).join(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Override server provided defaults with parameters passed in the URL if they match the data type
|
||||||
|
switch (typeof data.defaults[key]) {
|
||||||
|
case "boolean": data.defaults[key] = value === "1" || value === "true"; break;
|
||||||
|
case "number": data.defaults[key] = Number(value); break;
|
||||||
|
case "string": data.defaults[key] = String(value); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -14,6 +14,10 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<button type="button" class="btn" id="make-default-client">Open irc:// URLs with The Lounge</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
{{#unless public}}
|
{{#unless public}}
|
||||||
<div class="col-sm-12" data-advanced>
|
<div class="col-sm-12" data-advanced>
|
||||||
<h2>
|
<h2>
|
||||||
|
Loading…
Reference in New Issue
Block a user