mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-07-03 17:48:30 +00:00
4.34.0
* Added: Option to hide channels from the directory based on their title. * Fixed: Issue with FrankerFaceZ failing to initialize correctly due to a change in Twitch's JS layout.
This commit is contained in:
parent
213c2195cc
commit
bcee12a6b3
8 changed files with 158 additions and 25 deletions
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "frankerfacez",
|
"name": "frankerfacez",
|
||||||
"author": "Dan Salvato LLC",
|
"author": "Dan Salvato LLC",
|
||||||
"version": "4.33.6",
|
"version": "4.34.0",
|
||||||
"description": "FrankerFaceZ is a Twitch enhancement suite.",
|
"description": "FrankerFaceZ is a Twitch enhancement suite.",
|
||||||
"private": true,
|
"private": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
|
|
|
@ -8,7 +8,7 @@ import dayjs from 'dayjs';
|
||||||
|
|
||||||
import Module from 'utilities/module';
|
import Module from 'utilities/module';
|
||||||
import {createElement, ManagedStyle} from 'utilities/dom';
|
import {createElement, ManagedStyle} from 'utilities/dom';
|
||||||
import {timeout, has, glob_to_regex, escape_regex, split_chars} from 'utilities/object';
|
import {timeout, has, addWordSeparators, glob_to_regex, escape_regex, split_chars} from 'utilities/object';
|
||||||
import {Color} from 'utilities/color';
|
import {Color} from 'utilities/color';
|
||||||
|
|
||||||
import Badges from './badges';
|
import Badges from './badges';
|
||||||
|
@ -24,8 +24,6 @@ import * as RICH_PROVIDERS from './rich_providers';
|
||||||
import Actions from './actions';
|
import Actions from './actions';
|
||||||
import { getFontsList } from 'src/utilities/fonts';
|
import { getFontsList } from 'src/utilities/fonts';
|
||||||
|
|
||||||
export const SEPARATORS = '[\\s`~<>!-#%-\\x2A,-/:;\\x3F@\\x5B-\\x5D_\\x7B}\\u00A1\\u00A7\\u00AB\\u00B6\\u00B7\\u00BB\\u00BF\\u037E\\u0387\\u055A-\\u055F\\u0589\\u058A\\u05BE\\u05C0\\u05C3\\u05C6\\u05F3\\u05F4\\u0609\\u060A\\u060C\\u060D\\u061B\\u061E\\u061F\\u066A-\\u066D\\u06D4\\u0700-\\u070D\\u07F7-\\u07F9\\u0830-\\u083E\\u085E\\u0964\\u0965\\u0970\\u0AF0\\u0DF4\\u0E4F\\u0E5A\\u0E5B\\u0F04-\\u0F12\\u0F14\\u0F3A-\\u0F3D\\u0F85\\u0FD0-\\u0FD4\\u0FD9\\u0FDA\\u104A-\\u104F\\u10FB\\u1360-\\u1368\\u1400\\u166D\\u166E\\u169B\\u169C\\u16EB-\\u16ED\\u1735\\u1736\\u17D4-\\u17D6\\u17D8-\\u17DA\\u1800-\\u180A\\u1944\\u1945\\u1A1E\\u1A1F\\u1AA0-\\u1AA6\\u1AA8-\\u1AAD\\u1B5A-\\u1B60\\u1BFC-\\u1BFF\\u1C3B-\\u1C3F\\u1C7E\\u1C7F\\u1CC0-\\u1CC7\\u1CD3\\u2010-\\u2027\\u2030-\\u2043\\u2045-\\u2051\\u2053-\\u205E\\u207D\\u207E\\u208D\\u208E\\u2329\\u232A\\u2768-\\u2775\\u27C5\\u27C6\\u27E6-\\u27EF\\u2983-\\u2998\\u29D8-\\u29DB\\u29FC\\u29FD\\u2CF9-\\u2CFC\\u2CFE\\u2CFF\\u2D70\\u2E00-\\u2E2E\\u2E30-\\u2E3B\\u3001-\\u3003\\u3008-\\u3011\\u3014-\\u301F\\u3030\\u303D\\u30A0\\u30FB\\uA4FE\\uA4FF\\uA60D-\\uA60F\\uA673\\uA67E\\uA6F2-\\uA6F7\\uA874-\\uA877\\uA8CE\\uA8CF\\uA8F8-\\uA8FA\\uA92E\\uA92F\\uA95F\\uA9C1-\\uA9CD\\uA9DE\\uA9DF\\uAA5C-\\uAA5F\\uAADE\\uAADF\\uAAF0\\uAAF1\\uABEB\\uFD3E\\uFD3F\\uFE10-\\uFE19\\uFE30-\\uFE52\\uFE54-\\uFE61\\uFE63\\uFE68\\uFE6A\\uFE6B\\uFF01-\\uFF03\\uFF05-\\uFF0A\\uFF0C-\\uFF0F\\uFF1A\\uFF1B\\uFF1F\\uFF20\\uFF3B-\\uFF3D\\uFF3F\\uFF5B\\uFF5D\\uFF5F-\\uFF65]';
|
|
||||||
|
|
||||||
function sortPriorityColorTerms(list) {
|
function sortPriorityColorTerms(list) {
|
||||||
list.sort((a,b) => {
|
list.sort((a,b) => {
|
||||||
if ( a[0] < b[0] ) return 1;
|
if ( a[0] < b[0] ) return 1;
|
||||||
|
@ -37,10 +35,6 @@ function sortPriorityColorTerms(list) {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addSeparators(str) {
|
|
||||||
return `(^|.*?${SEPARATORS})(?:${str})(?=$|${SEPARATORS})`
|
|
||||||
}
|
|
||||||
|
|
||||||
const TERM_FLAGS = ['g', 'gi'];
|
const TERM_FLAGS = ['g', 'gi'];
|
||||||
|
|
||||||
function formatTerms(data) {
|
function formatTerms(data) {
|
||||||
|
@ -49,7 +43,7 @@ function formatTerms(data) {
|
||||||
for(let i=0; i < data.length; i++) {
|
for(let i=0; i < data.length; i++) {
|
||||||
const list = data[i];
|
const list = data[i];
|
||||||
if ( list[0].length )
|
if ( list[0].length )
|
||||||
list[1].push(addSeparators(list[0].join('|')));
|
list[1].push(addWordSeparators(list[0].join('|')));
|
||||||
|
|
||||||
out.push(list[1].length ? new RegExp(list[1].join('|'), TERM_FLAGS[i] || 'gi') : null);
|
out.push(list[1].length ? new RegExp(list[1].join('|'), TERM_FLAGS[i] || 'gi') : null);
|
||||||
}
|
}
|
||||||
|
|
|
@ -249,7 +249,7 @@ Twilight.KNOWN_MODULES = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const VEND_CHUNK = n => n && n.includes('vendor');
|
const VEND_CHUNK = n => ! n || n.includes('vendor');
|
||||||
|
|
||||||
Twilight.KNOWN_MODULES.core.use_result = true;
|
Twilight.KNOWN_MODULES.core.use_result = true;
|
||||||
//Twilight.KNOWN_MODULES.core.chunks = 'core';
|
//Twilight.KNOWN_MODULES.core.chunks = 'core';
|
||||||
|
@ -263,7 +263,7 @@ Twilight.KNOWN_MODULES['gql-printer'].chunks = VEND_CHUNK;
|
||||||
|
|
||||||
Twilight.KNOWN_MODULES.mousetrap.chunks = VEND_CHUNK;
|
Twilight.KNOWN_MODULES.mousetrap.chunks = VEND_CHUNK;
|
||||||
|
|
||||||
const CHAT_CHUNK = n => n && n.includes('chat');
|
const CHAT_CHUNK = n => ! n || n.includes('chat');
|
||||||
|
|
||||||
Twilight.KNOWN_MODULES['chat-types'].use_result = true;
|
Twilight.KNOWN_MODULES['chat-types'].use_result = true;
|
||||||
Twilight.KNOWN_MODULES['chat-types'].chunks = CHAT_CHUNK;
|
Twilight.KNOWN_MODULES['chat-types'].chunks = CHAT_CHUNK;
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
import {SiteModule} from 'utilities/module';
|
import {SiteModule} from 'utilities/module';
|
||||||
import {duration_to_string} from 'utilities/time';
|
import {duration_to_string} from 'utilities/time';
|
||||||
import {createElement} from 'utilities/dom';
|
import {createElement} from 'utilities/dom';
|
||||||
import {get} from 'utilities/object';
|
import {get, glob_to_regex, escape_regex, addWordSeparators} from 'utilities/object';
|
||||||
|
|
||||||
import Game from './game';
|
import Game from './game';
|
||||||
|
|
||||||
|
@ -18,6 +18,15 @@ export const CARD_CONTEXTS = ((e ={}) => {
|
||||||
return e;
|
return e;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
function formatTerms(data, flags) {
|
||||||
|
if ( data[0].length )
|
||||||
|
data[1].push(addWordSeparators(data[0].join('|')));
|
||||||
|
|
||||||
|
if ( ! data[1].length )
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return new RegExp(data[1].join('|'), flags);
|
||||||
|
}
|
||||||
|
|
||||||
//const CREATIVE_ID = 488191;
|
//const CREATIVE_ID = 488191;
|
||||||
|
|
||||||
|
@ -175,6 +184,58 @@ export default class Directory extends SiteModule {
|
||||||
changed: () => this.DirectoryShelf.forceUpdate()
|
changed: () => this.DirectoryShelf.forceUpdate()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.settings.add('directory.block-titles', {
|
||||||
|
default: [],
|
||||||
|
type: 'array_merge',
|
||||||
|
always_inherit: true,
|
||||||
|
ui: {
|
||||||
|
path: 'Directory > Channels >> Block by Title',
|
||||||
|
component: 'basic-terms'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.settings.add('__filter:directory.block-titles', {
|
||||||
|
requires: ['directory.block-titles'],
|
||||||
|
equals: 'requirements',
|
||||||
|
process(ctx) {
|
||||||
|
const val = ctx.get('directory.block-titles');
|
||||||
|
if ( ! val || ! val.length )
|
||||||
|
return null;
|
||||||
|
|
||||||
|
const out = [
|
||||||
|
[ // sensitive
|
||||||
|
[], [] // word
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[], []
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
for(const item of val) {
|
||||||
|
const t = item.t;
|
||||||
|
let v = item.v;
|
||||||
|
|
||||||
|
if ( t === 'glob' )
|
||||||
|
v = glob_to_regex(v);
|
||||||
|
|
||||||
|
else if ( t !== 'raw' )
|
||||||
|
v = escape_regex(v);
|
||||||
|
|
||||||
|
if ( ! v || ! v.length )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
out[item.s ? 0 : 1][item.w ? 0 : 1].push(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
formatTerms(out[0], 'g'),
|
||||||
|
formatTerms(out[1], 'gi')
|
||||||
|
];
|
||||||
|
},
|
||||||
|
|
||||||
|
changed: () => this.updateCards()
|
||||||
|
});
|
||||||
|
|
||||||
/*this.settings.add('directory.hide-viewing-history', {
|
/*this.settings.add('directory.hide-viewing-history', {
|
||||||
default: false,
|
default: false,
|
||||||
ui: {
|
ui: {
|
||||||
|
@ -339,9 +400,23 @@ export default class Directory extends SiteModule {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const should_hide = bad_tag || (props.streamType === 'rerun' && this.settings.get('directory.hide-vodcasts')) ||
|
let should_hide = false;
|
||||||
(props.context != null && props.context !== CARD_CONTEXTS.SingleGameList && this.settings.provider.get('directory.game.blocked-games', []).includes(game)) ||
|
if ( bad_tag )
|
||||||
((props.isPromotion || props.sourceType === 'COMMUNITY_BOOST' || props.sourceType === 'PROMOTION' || props.sourceType === 'SPONSORED') && this.settings.get('directory.hide-promoted'));
|
should_hide = true;
|
||||||
|
else if ( props.streamType === 'rerun' && this.settings.get('directory.hide-vodcasts') )
|
||||||
|
should_hide = true;
|
||||||
|
else if ( props.context != null && props.context !== CARD_CONTEXTS.SingleGameList && this.settings.provider.get('directory.game.blocked-games', []).includes(game) )
|
||||||
|
should_hide = true;
|
||||||
|
else if ( (props.isPromotion || props.sourceType === 'COMMUNITY_BOOST' || props.sourceType === 'PROMOTION' || props.sourceType === 'SPONSORED') && this.settings.get('directory.hide-promoted') )
|
||||||
|
should_hide = true;
|
||||||
|
else {
|
||||||
|
const regexes = this.settings.get('__filter:directory.block-titles');
|
||||||
|
if ( regexes &&
|
||||||
|
(( regexes[0] && regexes[0].test(props.title) ) ||
|
||||||
|
( regexes[1] && regexes[1].test(props.title) ))
|
||||||
|
)
|
||||||
|
should_hide = true;
|
||||||
|
}
|
||||||
|
|
||||||
let hide_container = el.closest('.tw-tower > div');
|
let hide_container = el.closest('.tw-tower > div');
|
||||||
if ( ! hide_container )
|
if ( ! hide_container )
|
||||||
|
|
|
@ -359,9 +359,24 @@ export default class Layout extends Module {
|
||||||
game = stream?.game?.displayName,
|
game = stream?.game?.displayName,
|
||||||
offline = props?.offline ?? false;
|
offline = props?.offline ?? false;
|
||||||
|
|
||||||
|
let should_hide = false;
|
||||||
|
if ( game && blocked_games.includes(game) )
|
||||||
|
should_hide = true;
|
||||||
|
if ( props.isPromoted && this.settings.get('directory.hide-promoted') )
|
||||||
|
should_hide = true;
|
||||||
|
else {
|
||||||
|
const regexes = this.settings.get('__filter:directory.block-titles');
|
||||||
|
const title = stream?.broadcaster?.broadcastSettings?.title;
|
||||||
|
if ( regexes && title &&
|
||||||
|
(( regexes[0] && regexes[0].test(title) ) ||
|
||||||
|
( regexes[1] && regexes[1].test(title) ))
|
||||||
|
)
|
||||||
|
should_hide = true;
|
||||||
|
}
|
||||||
|
|
||||||
card.classList.toggle('ffz--side-nav-card-rerun', rerun);
|
card.classList.toggle('ffz--side-nav-card-rerun', rerun);
|
||||||
card.classList.toggle('ffz--side-nav-card-offline', offline);
|
card.classList.toggle('ffz--side-nav-card-offline', offline);
|
||||||
card.classList.toggle('tw-hide', game ? blocked_games.includes(game) : false);
|
card.classList.toggle('tw-hide', should_hide);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -222,7 +222,12 @@ export default class WebMunch extends Module {
|
||||||
if ( modules )
|
if ( modules )
|
||||||
this.processModulesV4(modules, false);
|
this.processModulesV4(modules, false);
|
||||||
|
|
||||||
this._checked_module = {};
|
for(const [key,val] of Object.entries(this._checked_module)) {
|
||||||
|
if (val == true)
|
||||||
|
this._checked_module[key] = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//this._checked_module = {};
|
||||||
const res = this._original_loader.apply(this._original_store, arguments); // eslint-disable-line prefer-rest-params
|
const res = this._original_loader.apply(this._original_store, arguments); // eslint-disable-line prefer-rest-params
|
||||||
this.emit(':loaded', chunk_ids, names, modules);
|
this.emit(':loaded', chunk_ids, names, modules);
|
||||||
return res;
|
return res;
|
||||||
|
@ -375,7 +380,7 @@ export default class WebMunch extends Module {
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
let ids;
|
let ids;
|
||||||
if ( this._original_store && predicate.chunks ) {
|
if ( this._original_store && predicate.chunks && this._chunk_names && Object.keys(this._chunk_names).length ) {
|
||||||
const chunk_pred = typeof predicate.chunks === 'function';
|
const chunk_pred = typeof predicate.chunks === 'function';
|
||||||
if ( ! chunk_pred && ! Array.isArray(predicate.chunks) )
|
if ( ! chunk_pred && ! Array.isArray(predicate.chunks) )
|
||||||
predicate.chunks = [predicate.chunks];
|
predicate.chunks = [predicate.chunks];
|
||||||
|
@ -429,7 +434,7 @@ export default class WebMunch extends Module {
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
let ids = this._known_ids;
|
let ids = this._known_ids;
|
||||||
if ( this._original_store && predicate.chunks ) {
|
if ( this._original_store && predicate.chunks && this._chunk_names && Object.keys(this._chunk_names).length ) {
|
||||||
const chunk_pred = typeof predicate.chunks === 'function';
|
const chunk_pred = typeof predicate.chunks === 'function';
|
||||||
if ( ! chunk_pred && ! Array.isArray(predicate.chunks) )
|
if ( ! chunk_pred && ! Array.isArray(predicate.chunks) )
|
||||||
predicate.chunks = [predicate.chunks];
|
predicate.chunks = [predicate.chunks];
|
||||||
|
@ -498,9 +503,19 @@ export default class WebMunch extends Module {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_checkModule(id) {
|
_checkModule(id, checked = null) {
|
||||||
const fn = this._require?.m?.[id];
|
if (checked) {
|
||||||
|
if (checked.has(id))
|
||||||
|
return (this._checked_module[id] ?? false);
|
||||||
|
|
||||||
|
checked.add(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
let fn = this._require?.m?.[id];
|
||||||
if ( fn ) {
|
if ( fn ) {
|
||||||
|
if ( fn.original )
|
||||||
|
fn = fn.original;
|
||||||
|
|
||||||
let reqs = fn[Requires],
|
let reqs = fn[Requires],
|
||||||
banned = false;
|
banned = false;
|
||||||
|
|
||||||
|
@ -543,12 +558,40 @@ export default class WebMunch extends Module {
|
||||||
|
|
||||||
} else if ( reqs ) {
|
} else if ( reqs ) {
|
||||||
for(const mod_id of reqs)
|
for(const mod_id of reqs)
|
||||||
if ( ! this._require.m[mod_id] )
|
if ( ! this._require.m[mod_id] ) {
|
||||||
banned = true;
|
banned = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! banned && reqs ) {
|
||||||
|
if ( ! checked ) {
|
||||||
|
checked = new Set();
|
||||||
|
checked.add(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(const mod_id of reqs) {
|
||||||
|
let val = this._checked_module[mod_id];
|
||||||
|
if (val == null && ! checked.has(mod_id))
|
||||||
|
try {
|
||||||
|
val = this._checkModule(mod_id, checked);
|
||||||
|
} catch (err) {
|
||||||
|
this.log.verbose(`Recursion error checking module ${id} (${mod_id})`);
|
||||||
|
val = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( val ) {
|
||||||
|
this.log.verbose(`Unable to load module ${id} due to unable to load dependency ${mod_id}`);
|
||||||
|
banned = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._checked_module[id] = banned;
|
return this._checked_module[id] = banned;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return this._checked_module[id] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -604,7 +647,7 @@ export default class WebMunch extends Module {
|
||||||
const loader = require.e && require.e.toString();
|
const loader = require.e && require.e.toString();
|
||||||
let modules;
|
let modules;
|
||||||
if ( loader && loader.indexOf('Loading chunk') !== -1 ) {
|
if ( loader && loader.indexOf('Loading chunk') !== -1 ) {
|
||||||
const data = this.v4 ? /assets\/"\+\(({1:.*?})/.exec(loader) : /({0:.*?})/.exec(loader);
|
const data = this.v4 ? /assets\/"\+\(?({1:.*?})/.exec(loader) : /({0:.*?})/.exec(loader);
|
||||||
if ( data )
|
if ( data )
|
||||||
try {
|
try {
|
||||||
modules = JSON.parse(data[1].replace(/(\d+):/g, '"$1":'))
|
modules = JSON.parse(data[1].replace(/(\d+):/g, '"$1":'))
|
||||||
|
@ -612,7 +655,7 @@ export default class WebMunch extends Module {
|
||||||
|
|
||||||
} else if ( require.u ) {
|
} else if ( require.u ) {
|
||||||
const builder = require.u.toString(),
|
const builder = require.u.toString(),
|
||||||
match = /assets\/"\+({\d+:.*?})/.exec(builder),
|
match = /assets\/"\+\(?({\d+:.*?})/.exec(builder),
|
||||||
data = match ? match[1].replace(/([\de]+):/g, (_, m) => {
|
data = match ? match[1].replace(/([\de]+):/g, (_, m) => {
|
||||||
if ( /^\d+e\d+$/.test(m) ) {
|
if ( /^\d+e\d+$/.test(m) ) {
|
||||||
const bits = m.split('e');
|
const bits = m.split('e');
|
||||||
|
|
|
@ -17,6 +17,7 @@ export const SENTRY_ID = 'https://74b46b3894114f399d51949c6d237489@sentry.franke
|
||||||
export const LV_SERVER = 'https://cbenni.com/api';
|
export const LV_SERVER = 'https://cbenni.com/api';
|
||||||
export const LV_SOCKET_SERVER = 'wss://cbenni.com/socket.io/';
|
export const LV_SOCKET_SERVER = 'wss://cbenni.com/socket.io/';
|
||||||
|
|
||||||
|
export const WORD_SEPARATORS = '[\\s`~<>!-#%-\\x2A,-/:;\\x3F@\\x5B-\\x5D_\\x7B}\\u00A1\\u00A7\\u00AB\\u00B6\\u00B7\\u00BB\\u00BF\\u037E\\u0387\\u055A-\\u055F\\u0589\\u058A\\u05BE\\u05C0\\u05C3\\u05C6\\u05F3\\u05F4\\u0609\\u060A\\u060C\\u060D\\u061B\\u061E\\u061F\\u066A-\\u066D\\u06D4\\u0700-\\u070D\\u07F7-\\u07F9\\u0830-\\u083E\\u085E\\u0964\\u0965\\u0970\\u0AF0\\u0DF4\\u0E4F\\u0E5A\\u0E5B\\u0F04-\\u0F12\\u0F14\\u0F3A-\\u0F3D\\u0F85\\u0FD0-\\u0FD4\\u0FD9\\u0FDA\\u104A-\\u104F\\u10FB\\u1360-\\u1368\\u1400\\u166D\\u166E\\u169B\\u169C\\u16EB-\\u16ED\\u1735\\u1736\\u17D4-\\u17D6\\u17D8-\\u17DA\\u1800-\\u180A\\u1944\\u1945\\u1A1E\\u1A1F\\u1AA0-\\u1AA6\\u1AA8-\\u1AAD\\u1B5A-\\u1B60\\u1BFC-\\u1BFF\\u1C3B-\\u1C3F\\u1C7E\\u1C7F\\u1CC0-\\u1CC7\\u1CD3\\u2010-\\u2027\\u2030-\\u2043\\u2045-\\u2051\\u2053-\\u205E\\u207D\\u207E\\u208D\\u208E\\u2329\\u232A\\u2768-\\u2775\\u27C5\\u27C6\\u27E6-\\u27EF\\u2983-\\u2998\\u29D8-\\u29DB\\u29FC\\u29FD\\u2CF9-\\u2CFC\\u2CFE\\u2CFF\\u2D70\\u2E00-\\u2E2E\\u2E30-\\u2E3B\\u3001-\\u3003\\u3008-\\u3011\\u3014-\\u301F\\u3030\\u303D\\u30A0\\u30FB\\uA4FE\\uA4FF\\uA60D-\\uA60F\\uA673\\uA67E\\uA6F2-\\uA6F7\\uA874-\\uA877\\uA8CE\\uA8CF\\uA8F8-\\uA8FA\\uA92E\\uA92F\\uA95F\\uA9C1-\\uA9CD\\uA9DE\\uA9DF\\uAA5C-\\uAA5F\\uAADE\\uAADF\\uAAF0\\uAAF1\\uABEB\\uFD3E\\uFD3F\\uFE10-\\uFE19\\uFE30-\\uFE52\\uFE54-\\uFE61\\uFE63\\uFE68\\uFE6A\\uFE6B\\uFF01-\\uFF03\\uFF05-\\uFF0A\\uFF0C-\\uFF0F\\uFF1A\\uFF1B\\uFF1F\\uFF20\\uFF3B-\\uFF3D\\uFF3F\\uFF5B\\uFF5D\\uFF5F-\\uFF65]';
|
||||||
|
|
||||||
export const BAD_HOTKEYS = [
|
export const BAD_HOTKEYS = [
|
||||||
'f',
|
'f',
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import {BAD_HOTKEYS, TWITCH_EMOTE_V2} from 'utilities/constants';
|
import {BAD_HOTKEYS, TWITCH_EMOTE_V2, WORD_SEPARATORS} from 'utilities/constants';
|
||||||
|
|
||||||
const HOP = Object.prototype.hasOwnProperty;
|
const HOP = Object.prototype.hasOwnProperty;
|
||||||
|
|
||||||
|
@ -539,6 +539,11 @@ export const escape_regex = RegExp.escape || function escape_regex(str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function addWordSeparators(str) {
|
||||||
|
return `(^|.*?${WORD_SEPARATORS})(?:${str})(?=$|${WORD_SEPARATORS})`
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const CONTROL_CHARS = '/$^+.()=!|';
|
const CONTROL_CHARS = '/$^+.()=!|';
|
||||||
|
|
||||||
export function glob_to_regex(input) {
|
export function glob_to_regex(input) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue