Bug 1699099 - Support a prefix to the chat account name and split account when pasting a full identifier. r=clokep

Differential Revision: https://phabricator.services.mozilla.com/D118045

--HG--
extra : amend_source : eccf8bd1d5c326efaa3cde8b7caf71d2b7b7665b
This commit is contained in:
Martin Giger 2021-06-23 13:49:24 +03:00
Родитель 383d1860fd
Коммит 8449c90171
5 изменённых файлов: 112 добавлений и 5 удалений

Просмотреть файл

@ -51,11 +51,23 @@ interface prplIProtocol: nsISupports {
*/
Array<prplIPref> getOptions();
/**
* String to put in front of the full account username identifier. Usually
* an empty string.
*/
readonly attribute AUTF8String usernamePrefix;
/**
* @returns an array of prplIUsernameSplit
*/
Array<prplIUsernameSplit> getUsernameSplit();
/**
* Split a username into its parts without separators (or prefix).
* Returns an empty array if the username can not be split.
*/
Array<AUTF8String> splitUsername(in AUTF8String aName);
/**
* Descriptive text used in the account wizard to describe the username.
*/

Просмотреть файл

@ -108,6 +108,9 @@ UnknownProtocol.prototype = {
getOptions() {
return [];
},
get usernamePrefix() {
return "";
},
getUsernameSplit() {
return [];
},

Просмотреть файл

@ -1169,6 +1169,7 @@ var GenericProtocolPrototype = {
}
return purplePrefs;
},
usernamePrefix: "",
getUsernameSplit() {
if (!this.usernameSplits || !this.usernameSplits.length) {
return [];
@ -1176,6 +1177,41 @@ var GenericProtocolPrototype = {
return this.usernameSplits.map(split => new UsernameSplit(split));
},
/**
* Protocol agnostic implementation that splits the username by the pattern
* defined with |usernamePrefix| and |usernameSplits| on the protocol.
* Prefers the first occurence of a separator.
*
* @param {string} aName - Username to split.
* @returns {string[]} Parts of the username or empty array if the username
* doesn't match the splitting format.
*/
splitUsername(aName) {
let remainingName = aName;
if (this.usernamePrefix) {
if (!remainingName.startsWith(this.usernamePrefix)) {
return [];
}
remainingName = remainingName.slice(this.usernamePrefix.length);
}
if (!this.usernameSplits || !this.usernameSplits.length) {
return [remainingName];
}
const parts = [];
for (const split of this.usernameSplits) {
if (!remainingName.includes(split.separator)) {
return [];
}
const separatorIndex = remainingName.indexOf(split.separator);
parts.push(remainingName.slice(0, separatorIndex));
remainingName = remainingName.slice(
separatorIndex + split.separator.length
);
}
parts.push(remainingName);
return parts;
},
registerCommands() {
if (!this.commands) {
return;

Просмотреть файл

@ -995,9 +995,9 @@ function ircAccount(aProtocol, aImAccount) {
this.conversations = new NormalizedMap(this.normalize.bind(this));
// Split the account name into usable parts.
let splitter = this.name.lastIndexOf("@");
this._accountNickname = this.name.slice(0, splitter);
this._server = this.name.slice(splitter + 1);
const [accountNickname, server] = this.protocol.splitUsername(this.name);
this._accountNickname = accountNickname;
this._server = server;
// To avoid _currentServerName being null, initialize it to the server being
// connected to. This will also get overridden during the 001 response from
// the server.
@ -2362,6 +2362,11 @@ ircProtocol.prototype = {
},
],
splitUsername(aName) {
let splitter = aName.lastIndexOf("@");
return [aName.slice(0, splitter), aName.slice(splitter + 1)];
},
options: {
port: {
get label() {

Просмотреть файл

@ -91,16 +91,29 @@ var accountWizard = {
}
},
/**
* Builds the full username from the username boxes.
*
* @returns {string} assembled username
*/
getUsername() {
let usernameBoxIndex = 0;
if (this.proto.usernamePrefix) {
usernameBoxIndex = 1;
}
// If the first username input is empty, make sure we return an empty
// string so that it blocks the 'next' button of the wizard.
if (!this.userNameBoxes[0].value) {
if (!this.userNameBoxes[usernameBoxIndex].value) {
return "";
}
return this.userNameBoxes.reduce((prev, elt) => prev + elt.value, "");
},
/**
* Check that the username fields generate a new username, and if it is valid
* allow advancing the wizard.
*/
checkUsername() {
var wizard = document.querySelector("wizard");
var name = accountWizard.getUsername();
@ -116,6 +129,28 @@ var accountWizard = {
duplicateWarning.hidden = !exists;
},
/**
* Takes the value of the primary username field and splits it if the value
* matches the split field syntax.
*/
splitUsername() {
let usernameBoxIndex = 0;
if (this.proto.usernamePrefix) {
usernameBoxIndex = 1;
}
let username = this.userNameBoxes[usernameBoxIndex].value;
let splitValues = this.proto.splitUsername(username);
if (!splitValues.length) {
return;
}
for (const box of this.userNameBoxes) {
if (box instanceof Element) {
box.value = splitValues.shift();
}
}
this.checkUsername();
},
selectProtocol() {
var protoList = document.getElementById("protolist");
var id = protoList.selectedItem.value;
@ -153,11 +188,21 @@ var accountWizard = {
input.addEventListener("input", event => {
this.checkUsername();
});
// Only add the split logic to the first input field
if (!this.userNameBoxes) {
input.addEventListener("blur", event => {
this.splitUsername();
});
}
grid.appendChild(input);
return input;
},
/**
* Builds the username input boxes from the username split defined by the
* protocol.
*/
showUsernamePage() {
var proto = this.proto.id;
if ("userNameBoxes" in this && this.userNameProto == proto) {
@ -191,6 +236,12 @@ var accountWizard = {
var label = bundle.getString("accountUsername");
this.userNameBoxes = [this.insertUsernameField("name", label, grid)];
this.userNameBoxes[0].emptyText = emptyText;
let usernameBoxIndex = 0;
if (this.proto.usernamePrefix) {
this.userNameBoxes.unshift({ value: this.proto.usernamePrefix });
usernameBoxIndex = 1;
}
for (let i = 0; i < splits.length; ++i) {
this.userNameBoxes.push({ value: splits[i].separator });
@ -200,7 +251,7 @@ var accountWizard = {
this.insertUsernameField("username-split-" + i, label, grid, defaultVal)
);
}
this.userNameBoxes[0].focus();
this.userNameBoxes[usernameBoxIndex].focus();
this.userNameProto = proto;
this.checkUsername();
},