mirror of https://github.com/zulip/zulip.git
eslint: Fix unicorn/better-regex.
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/master/docs/rules/better-regex.md Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
parent
a37616e8c6
commit
0042cf51c1
|
@ -1487,7 +1487,7 @@ run_test("on_events", () => {
|
||||||
handler(ev);
|
handler(ev);
|
||||||
|
|
||||||
// video link ids consist of 15 random digits
|
// video link ids consist of 15 random digits
|
||||||
let video_link_regex = /\[translated: Click to join video call\]\(https:\/\/meet.jit.si\/\d{15}\)/;
|
let video_link_regex = /\[translated: Click to join video call]\(https:\/\/meet.jit.si\/\d{15}\)/;
|
||||||
assert.match(syntax_to_insert, video_link_regex);
|
assert.match(syntax_to_insert, video_link_regex);
|
||||||
|
|
||||||
page_params.jitsi_server_url = null;
|
page_params.jitsi_server_url = null;
|
||||||
|
@ -1512,7 +1512,7 @@ run_test("on_events", () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
handler(ev);
|
handler(ev);
|
||||||
video_link_regex = /\[translated: Click to join video call\]\(example\.zoom\.com\)/;
|
video_link_regex = /\[translated: Click to join video call]\(example\.zoom\.com\)/;
|
||||||
assert.match(syntax_to_insert, video_link_regex);
|
assert.match(syntax_to_insert, video_link_regex);
|
||||||
|
|
||||||
page_params.realm_video_chat_provider =
|
page_params.realm_video_chat_provider =
|
||||||
|
@ -1527,7 +1527,7 @@ run_test("on_events", () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
handler(ev);
|
handler(ev);
|
||||||
video_link_regex = /\[translated: Click to join video call\]\(\/calls\/bigbluebutton\/join\?meeting_id=%22zulip-1%22&password=%22AAAAAAAAAA%22&checksum=%2232702220bff2a22a44aee72e96cfdb4c4091752e%22\)/;
|
video_link_regex = /\[translated: Click to join video call]\(\/calls\/bigbluebutton\/join\?meeting_id=%22zulip-1%22&password=%22AAAAAAAAAA%22&checksum=%2232702220bff2a22a44aee72e96cfdb4c4091752e%22\)/;
|
||||||
assert.match(syntax_to_insert, video_link_regex);
|
assert.match(syntax_to_insert, video_link_regex);
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
|
@ -676,19 +676,19 @@ run_test("python_to_js_filter", () => {
|
||||||
// to update_realm_filter_rules.
|
// to update_realm_filter_rules.
|
||||||
markdown.update_realm_filter_rules([["/a(?im)a/g"], ["/a(?L)a/g"]]);
|
markdown.update_realm_filter_rules([["/a(?im)a/g"], ["/a(?L)a/g"]]);
|
||||||
let actual_value = marked.InlineLexer.rules.zulip.realm_filters;
|
let actual_value = marked.InlineLexer.rules.zulip.realm_filters;
|
||||||
let expected_value = [/\/aa\/g(?![\w])/gim, /\/aa\/g(?![\w])/g];
|
let expected_value = [/\/aa\/g(?!\w)/gim, /\/aa\/g(?!\w)/g];
|
||||||
assert.deepEqual(actual_value, expected_value);
|
assert.deepEqual(actual_value, expected_value);
|
||||||
// Test case with multiple replacements.
|
// Test case with multiple replacements.
|
||||||
markdown.update_realm_filter_rules([
|
markdown.update_realm_filter_rules([
|
||||||
["#cf(?P<contest>[0-9]+)(?P<problem>[A-Z][0-9A-Z]*)", "http://google.com"],
|
["#cf(?P<contest>\\d+)(?P<problem>[A-Z][\\dA-Z]*)", "http://google.com"],
|
||||||
]);
|
]);
|
||||||
actual_value = marked.InlineLexer.rules.zulip.realm_filters;
|
actual_value = marked.InlineLexer.rules.zulip.realm_filters;
|
||||||
expected_value = [/#cf([0-9]+)([A-Z][0-9A-Z]*)(?![\w])/g];
|
expected_value = [/#cf(\d+)([A-Z][\dA-Z]*)(?!\w)/g];
|
||||||
assert.deepEqual(actual_value, expected_value);
|
assert.deepEqual(actual_value, expected_value);
|
||||||
// Test incorrect syntax.
|
// Test incorrect syntax.
|
||||||
blueslip.expect(
|
blueslip.expect(
|
||||||
"error",
|
"error",
|
||||||
"python_to_js_filter: Invalid regular expression: /!@#@(!#&((!&(@#((?![\\w])/: Unterminated group",
|
"python_to_js_filter: Invalid regular expression: /!@#@(!#&((!&(@#((?!\\w)/: Unterminated group",
|
||||||
);
|
);
|
||||||
markdown.update_realm_filter_rules([["!@#@(!#&((!&(@#(", "http://google.com"]]);
|
markdown.update_realm_filter_rules([["!@#@(!#&((!&(@#(", "http://google.com"]]);
|
||||||
actual_value = marked.InlineLexer.rules.zulip.realm_filters;
|
actual_value = marked.InlineLexer.rules.zulip.realm_filters;
|
||||||
|
|
|
@ -8,7 +8,7 @@ const common = require("../puppeteer_lib/common");
|
||||||
const OUTGOING_WEBHOOK_BOT_TYPE = "3";
|
const OUTGOING_WEBHOOK_BOT_TYPE = "3";
|
||||||
const GENERIC_BOT_TYPE = "1";
|
const GENERIC_BOT_TYPE = "1";
|
||||||
|
|
||||||
const zuliprc_regex = /^data:application\/octet-stream;charset=utf-8,\[api\]\nemail=.+\nkey=.+\nsite=.+\n$/;
|
const zuliprc_regex = /^data:application\/octet-stream;charset=utf-8,\[api]\nemail=.+\nkey=.+\nsite=.+\n$/;
|
||||||
|
|
||||||
async function get_decoded_url_in_selector(page, selector) {
|
async function get_decoded_url_in_selector(page, selector) {
|
||||||
return await page.evaluate(
|
return await page.evaluate(
|
||||||
|
@ -76,7 +76,7 @@ async function test_get_api_key(page) {
|
||||||
|
|
||||||
await page.waitForSelector("#show_api_key", {visible: true});
|
await page.waitForSelector("#show_api_key", {visible: true});
|
||||||
const api_key = await common.get_text_from_selector(page, "#api_key_value");
|
const api_key = await common.get_text_from_selector(page, "#api_key_value");
|
||||||
assert(/[a-zA-Z0-9]{32}/.test(api_key), "Incorrect API key format.");
|
assert(/[\dA-Za-z]{32}/.test(api_key), "Incorrect API key format.");
|
||||||
|
|
||||||
const download_zuliprc_selector = "#download_zuliprc";
|
const download_zuliprc_selector = "#download_zuliprc";
|
||||||
await page.click(download_zuliprc_selector);
|
await page.click(download_zuliprc_selector);
|
||||||
|
@ -97,7 +97,7 @@ async function test_webhook_bot_creation(page) {
|
||||||
|
|
||||||
const bot_email = "1-bot@zulip.testserver";
|
const bot_email = "1-bot@zulip.testserver";
|
||||||
const download_zuliprc_selector = '.download_bot_zuliprc[data-email="' + bot_email + '"]';
|
const download_zuliprc_selector = '.download_bot_zuliprc[data-email="' + bot_email + '"]';
|
||||||
const outgoing_webhook_zuliprc_regex = /^data:application\/octet-stream;charset=utf-8,\[api\]\nemail=.+\nkey=.+\nsite=.+\ntoken=.+\n$/;
|
const outgoing_webhook_zuliprc_regex = /^data:application\/octet-stream;charset=utf-8,\[api]\nemail=.+\nkey=.+\nsite=.+\ntoken=.+\n$/;
|
||||||
|
|
||||||
await page.waitForSelector(download_zuliprc_selector, {visible: true});
|
await page.waitForSelector(download_zuliprc_selector, {visible: true});
|
||||||
await page.click(download_zuliprc_selector);
|
await page.click(download_zuliprc_selector);
|
||||||
|
@ -137,7 +137,7 @@ async function test_botserverrc(page) {
|
||||||
page,
|
page,
|
||||||
"#download_botserverrc",
|
"#download_botserverrc",
|
||||||
);
|
);
|
||||||
const botserverrc_regex = /^data:application\/octet-stream;charset=utf-8,\[\]\nemail=.+\nkey=.+\nsite=.+\ntoken=.+\n$/;
|
const botserverrc_regex = /^data:application\/octet-stream;charset=utf-8,\[]\nemail=.+\nkey=.+\nsite=.+\ntoken=.+\n$/;
|
||||||
assert(botserverrc_regex.test(botserverrc_decoded_url), "Incorrect botserverrc format.");
|
assert(botserverrc_regex.test(botserverrc_decoded_url), "Incorrect botserverrc format.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -121,7 +121,7 @@ function filter_user_ids(user_filter_text, user_ids) {
|
||||||
|
|
||||||
user_ids = user_ids.filter((user_id) => !people.is_my_user_id(user_id));
|
user_ids = user_ids.filter((user_id) => !people.is_my_user_id(user_id));
|
||||||
|
|
||||||
let search_terms = user_filter_text.toLowerCase().split(/[|,]+/);
|
let search_terms = user_filter_text.toLowerCase().split(/[,|]+/);
|
||||||
search_terms = search_terms.map((s) => s.trim());
|
search_terms = search_terms.map((s) => s.trim());
|
||||||
|
|
||||||
const persons = user_ids.map((user_id) => people.get_by_user_id(user_id));
|
const persons = user_ids.map((user_id) => people.get_by_user_id(user_id));
|
||||||
|
|
|
@ -100,7 +100,7 @@ exports.copy_data_attribute_value = function (elem, key) {
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.has_mac_keyboard = function () {
|
exports.has_mac_keyboard = function () {
|
||||||
return /Mac/i.test(navigator.platform);
|
return /mac/i.test(navigator.platform);
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.adjust_mac_shortcuts = function (key_elem_class, require_cmd_style) {
|
exports.adjust_mac_shortcuts = function (key_elem_class, require_cmd_style) {
|
||||||
|
|
|
@ -278,7 +278,7 @@ exports.tokenize_compose_str = function (s) {
|
||||||
case "_":
|
case "_":
|
||||||
if (i === 0) {
|
if (i === 0) {
|
||||||
return s;
|
return s;
|
||||||
} else if (/[\s(){}[\]]/.test(s[i - 1])) {
|
} else if (/[\s()[\]{}]/.test(s[i - 1])) {
|
||||||
return s.slice(i);
|
return s.slice(i);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -612,7 +612,7 @@ exports.get_candidates = function (query) {
|
||||||
// as :P or :-p
|
// as :P or :-p
|
||||||
// Also, if the user has only typed a colon and nothing after,
|
// Also, if the user has only typed a colon and nothing after,
|
||||||
// no need to match yet.
|
// no need to match yet.
|
||||||
if (/^:-.?$/.test(current_token) || /^:[^a-z+]?$/.test(current_token)) {
|
if (/^:-.?$/.test(current_token) || /^:[^+a-z]?$/.test(current_token)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Don't autocomplete if there is a space following a ':'
|
// Don't autocomplete if there is a space following a ':'
|
||||||
|
|
|
@ -317,7 +317,7 @@ exports.paste_handler = function (event) {
|
||||||
const paste_html = clipboardData.getData("text/html");
|
const paste_html = clipboardData.getData("text/html");
|
||||||
if (paste_html && page_params.development_environment) {
|
if (paste_html && page_params.development_environment) {
|
||||||
const text = exports.paste_handler_converter(paste_html);
|
const text = exports.paste_handler_converter(paste_html);
|
||||||
const mdImageRegex = /^!\[.*\]\(.*\)$/;
|
const mdImageRegex = /^!\[.*]\(.*\)$/;
|
||||||
if (text.match(mdImageRegex)) {
|
if (text.match(mdImageRegex)) {
|
||||||
// This block catches cases where we are pasting an
|
// This block catches cases where we are pasting an
|
||||||
// image into Zulip, which is handled by upload.js.
|
// image into Zulip, which is handled by upload.js.
|
||||||
|
|
|
@ -30,12 +30,12 @@ const backend_only_markdown_re = [
|
||||||
// Inline image previews, check for contiguous chars ending in image suffix
|
// Inline image previews, check for contiguous chars ending in image suffix
|
||||||
// To keep the below regexes simple, split them out for the end-of-message case
|
// To keep the below regexes simple, split them out for the end-of-message case
|
||||||
|
|
||||||
/[^\s]*(?:(?:\.bmp|\.gif|\.jpg|\.jpeg|\.png|\.webp)\)?)\s+/m,
|
/\S*(?:\.bmp|\.gif|\.jpg|\.jpeg|\.png|\.webp)\)?\s+/m,
|
||||||
/[^\s]*(?:(?:\.bmp|\.gif|\.jpg|\.jpeg|\.png|\.webp)\)?)$/m,
|
/\S*(?:\.bmp|\.gif|\.jpg|\.jpeg|\.png|\.webp)\)?$/m,
|
||||||
|
|
||||||
// Twitter and youtube links are given previews
|
// Twitter and youtube links are given previews
|
||||||
|
|
||||||
/[^\s]*(?:twitter|youtube).com\/[^\s]*/,
|
/\S*(?:twitter|youtube).com\/\S*/,
|
||||||
];
|
];
|
||||||
|
|
||||||
exports.translate_emoticons_to_names = (text) => {
|
exports.translate_emoticons_to_names = (text) => {
|
||||||
|
@ -88,7 +88,7 @@ exports.contains_backend_only_syntax = function (content) {
|
||||||
// then don't render it locally. It is workaround for the fact that
|
// then don't render it locally. It is workaround for the fact that
|
||||||
// javascript regex doesn't support lookbehind.
|
// javascript regex doesn't support lookbehind.
|
||||||
const false_filter_match = realm_filter_list.find((re) => {
|
const false_filter_match = realm_filter_list.find((re) => {
|
||||||
const pattern = /(?:[^\s'"(,:<])/.source + re[0].source + /(?![\w])/.source;
|
const pattern = /[^\s"'(,:<]/.source + re[0].source + /(?!\w)/.source;
|
||||||
const regex = new RegExp(pattern);
|
const regex = new RegExp(pattern);
|
||||||
return regex.test(content);
|
return regex.test(content);
|
||||||
});
|
});
|
||||||
|
@ -237,7 +237,7 @@ exports.add_topic_links = function (message) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also make raw urls navigable
|
// Also make raw urls navigable
|
||||||
const url_re = /\b(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/g; // Slightly modified from third/marked.js
|
const url_re = /\b(https?:\/\/[^\s<]+[^\s"'),.:;<\]])/g; // Slightly modified from third/marked.js
|
||||||
const match = topic.match(url_re);
|
const match = topic.match(url_re);
|
||||||
if (match) {
|
if (match) {
|
||||||
links = links.concat(match);
|
links = links.concat(match);
|
||||||
|
@ -432,7 +432,7 @@ function python_to_js_filter(pattern, url) {
|
||||||
}
|
}
|
||||||
// Convert any python in-regex flags to RegExp flags
|
// Convert any python in-regex flags to RegExp flags
|
||||||
let js_flags = "g";
|
let js_flags = "g";
|
||||||
const inline_flag_re = /\(\?([iLmsux]+)\)/;
|
const inline_flag_re = /\(\?([Limsux]+)\)/;
|
||||||
match = inline_flag_re.exec(pattern);
|
match = inline_flag_re.exec(pattern);
|
||||||
|
|
||||||
// JS regexes only support i (case insensitivity) and m (multiline)
|
// JS regexes only support i (case insensitivity) and m (multiline)
|
||||||
|
@ -456,7 +456,7 @@ function python_to_js_filter(pattern, url) {
|
||||||
// is rendered locally, otherwise, we return false there and
|
// is rendered locally, otherwise, we return false there and
|
||||||
// message is rendered on the backend which has proper support
|
// message is rendered on the backend which has proper support
|
||||||
// for negative lookbehind.
|
// for negative lookbehind.
|
||||||
pattern = pattern + /(?![\w])/.source;
|
pattern = pattern + /(?!\w)/.source;
|
||||||
let final_regex = null;
|
let final_regex = null;
|
||||||
try {
|
try {
|
||||||
final_regex = new RegExp(pattern, js_flags);
|
final_regex = new RegExp(pattern, js_flags);
|
||||||
|
@ -537,7 +537,7 @@ exports.initialize = function (realm_filters, helper_config) {
|
||||||
disable_markdown_regex(marked.Lexer.rules.tables, "lheading");
|
disable_markdown_regex(marked.Lexer.rules.tables, "lheading");
|
||||||
|
|
||||||
// Disable __strong__ (keeping **strong**)
|
// Disable __strong__ (keeping **strong**)
|
||||||
marked.InlineLexer.rules.zulip.strong = /^\*\*([\s\S]+?)\*\*(?!\*)/;
|
marked.InlineLexer.rules.zulip.strong = /^\*\*([\S\s]+?)\*\*(?!\*)/;
|
||||||
|
|
||||||
// Make sure <del> syntax matches the backend processor
|
// Make sure <del> syntax matches the backend processor
|
||||||
marked.InlineLexer.rules.zulip.del = /^(?!<~)~~([^~]+)~~(?!~)/;
|
marked.InlineLexer.rules.zulip.del = /^(?!<~)~~([^~]+)~~(?!~)/;
|
||||||
|
@ -545,7 +545,7 @@ exports.initialize = function (realm_filters, helper_config) {
|
||||||
// Disable _emphasis_ (keeping *emphasis*)
|
// Disable _emphasis_ (keeping *emphasis*)
|
||||||
// Text inside ** must start and end with a word character
|
// Text inside ** must start and end with a word character
|
||||||
// to prevent mis-parsing things like "char **x = (char **)y"
|
// to prevent mis-parsing things like "char **x = (char **)y"
|
||||||
marked.InlineLexer.rules.zulip.em = /^\*(?!\s+)((?:\*\*|[\s\S])+?)((?:[\S]))\*(?!\*)/;
|
marked.InlineLexer.rules.zulip.em = /^\*(?!\s+)((?:\*\*|[\S\s])+?)(\S)\*(?!\*)/;
|
||||||
|
|
||||||
// Disable autolink as (a) it is not used in our backend and (b) it interferes with @mentions
|
// Disable autolink as (a) it is not used in our backend and (b) it interferes with @mentions
|
||||||
disable_markdown_regex(marked.InlineLexer.rules.zulip, "autolink");
|
disable_markdown_regex(marked.InlineLexer.rules.zulip, "autolink");
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
export function detect_user_os() {
|
export function detect_user_os() {
|
||||||
if (/Android/i.test(navigator.userAgent)) {
|
if (/android/i.test(navigator.userAgent)) {
|
||||||
return "android";
|
return "android";
|
||||||
}
|
}
|
||||||
if (/iPhone|iPad|iPod/i.test(navigator.userAgent)) {
|
if (/iphone|ipad|ipod/i.test(navigator.userAgent)) {
|
||||||
return "ios";
|
return "ios";
|
||||||
}
|
}
|
||||||
if (common.has_mac_keyboard()) {
|
if (common.has_mac_keyboard()) {
|
||||||
return "mac";
|
return "mac";
|
||||||
}
|
}
|
||||||
if (/Win/i.test(navigator.userAgent)) {
|
if (/win/i.test(navigator.userAgent)) {
|
||||||
return "windows";
|
return "windows";
|
||||||
}
|
}
|
||||||
if (/Linux/i.test(navigator.userAgent)) {
|
if (/linux/i.test(navigator.userAgent)) {
|
||||||
return "linux";
|
return "linux";
|
||||||
}
|
}
|
||||||
return "mac"; // if unable to determine OS return Mac by default
|
return "mac"; // if unable to determine OS return Mac by default
|
||||||
|
|
|
@ -68,7 +68,7 @@ function is_local_part(value, element) {
|
||||||
// Adapted from Django's EmailValidator
|
// Adapted from Django's EmailValidator
|
||||||
return (
|
return (
|
||||||
this.optional(element) ||
|
this.optional(element) ||
|
||||||
/^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*$/i.test(value)
|
/^[\w!#$%&'*+/=?^`{|}~-]+(\.[\w!#$%&'*+/=?^`{|}~-]+)*$/i.test(value)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -154,13 +154,13 @@ exports.get_color_class = _.memoize((color) => {
|
||||||
const channel = [0, 0, 0];
|
const channel = [0, 0, 0];
|
||||||
let mult = 1;
|
let mult = 1;
|
||||||
|
|
||||||
match = /^#([\da-fA-F]{2})([\da-fA-F]{2})([\da-fA-F]{2})$/.exec(color);
|
match = /^#([\dA-Fa-f]{2})([\dA-Fa-f]{2})([\dA-Fa-f]{2})$/.exec(color);
|
||||||
if (!match) {
|
if (!match) {
|
||||||
// 3-digit shorthand; Spectrum gives this e.g. for pure black.
|
// 3-digit shorthand; Spectrum gives this e.g. for pure black.
|
||||||
// Multiply each digit by 16+1.
|
// Multiply each digit by 16+1.
|
||||||
mult = 17;
|
mult = 17;
|
||||||
|
|
||||||
match = /^#([\da-fA-F])([\da-fA-F])([\da-fA-F])$/.exec(color);
|
match = /^#([\dA-Fa-f])([\dA-Fa-f])([\dA-Fa-f])$/.exec(color);
|
||||||
if (!match) {
|
if (!match) {
|
||||||
// Can't understand color.
|
// Can't understand color.
|
||||||
return "";
|
return "";
|
||||||
|
|
|
@ -315,7 +315,7 @@ exports.slug_to_name = function (slug) {
|
||||||
GitHub conversations. We migrated to modern slugs in
|
GitHub conversations. We migrated to modern slugs in
|
||||||
early 2018.
|
early 2018.
|
||||||
*/
|
*/
|
||||||
const m = /^([\d]+)(-.*)?/.exec(slug);
|
const m = /^(\d+)(-.*)?/.exec(slug);
|
||||||
if (m) {
|
if (m) {
|
||||||
const stream_id = Number.parseInt(m[1], 10);
|
const stream_id = Number.parseInt(m[1], 10);
|
||||||
const sub = subs_by_stream_id.get(stream_id);
|
const sub = subs_by_stream_id.get(stream_id);
|
||||||
|
|
Loading…
Reference in New Issue