Merge pull request #2571 from thelounge/xpaw/protocol-handler

Implement irc:// protocol handler
This commit is contained in:
Jérémie Astori 2018-07-05 22:08:07 -04:00 committed by GitHub
commit 93fcd57b2d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 107 additions and 27 deletions

View File

@ -320,4 +320,20 @@ function initialize() {
// 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.
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();
}
}

View File

@ -90,35 +90,95 @@ socket.on("configuration", function(data) {
utils.togglePasswordField("#connect .reveal-password");
});
if ($(document.body).hasClass("public") && "URLSearchParams" in window) {
if ("URLSearchParams" in window) {
const params = new URLSearchParams(document.location.search);
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;
}
if (params.has("uri")) {
parseIrcUri(params.get("uri") + location.hash, data);
} else if ($(document.body).hasClass("public")) {
parseOverrideParams(params, data);
}
}
});
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;
}
}
}

View File

@ -14,6 +14,10 @@
</div>
<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}}
<div class="col-sm-12" data-advanced>
<h2>