Merge pull request #170 from JsSucks/emote-changes-and-minor-stuff
Emote changes and minor stuff
This commit is contained in:
commit
ae63213809
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<span class="bd-emotewrapper" v-tooltip="name">
|
||||
<img class="bd-emote" :src="src" :alt="name"/>
|
||||
<img class="bd-emote" :src="src" :alt="`;${name};`"/>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -21,34 +21,34 @@ export default class {
|
|||
static processMarkup(markup) {
|
||||
if (!emotesEnabled) return markup; // TODO Get it from setttings
|
||||
const newMarkup = [];
|
||||
for (const [ti, t] of markup.entries()) {
|
||||
if ('string' !== typeof t) {
|
||||
newMarkup.push(t);
|
||||
for (const child of markup) {
|
||||
if ('string' !== typeof child) {
|
||||
newMarkup.push(child);
|
||||
continue;
|
||||
}
|
||||
|
||||
const words = t.split(/([^\s]+)([\s]|$)/g);
|
||||
if (!this.testWord(child)) {
|
||||
newMarkup.push(child);
|
||||
continue;
|
||||
}
|
||||
const words = child.split(/([^\s]+)([\s]|$)/g);
|
||||
if (!words) continue;
|
||||
let text = null;
|
||||
for (const [wi, word] of words.entries()) {
|
||||
let isEmote = false;
|
||||
if (this.testWord(word)) {
|
||||
isEmote = true;
|
||||
}
|
||||
for (const [wordIndex, word] of words.entries()) {
|
||||
const isEmote = this.isEmote(word);
|
||||
if (isEmote) {
|
||||
if (text !== null) {
|
||||
newMarkup.push(text);
|
||||
text = null;
|
||||
}
|
||||
newMarkup.push(this.React.createElement('span', { className: 'bd-emote-outer' }, word));
|
||||
newMarkup.push(this.React.createElement('span', { className: 'bd-emote-outer', 'data-bdemote-name': isEmote.name, 'data-bdemote-src': isEmote.src }));
|
||||
continue;
|
||||
}
|
||||
if (text === null) {
|
||||
text = `${word}`;
|
||||
text = word;
|
||||
} else {
|
||||
text += `${word}`;
|
||||
text += word;
|
||||
}
|
||||
if (wi === words.length - 1) {
|
||||
if (wordIndex === words.length - 1) {
|
||||
newMarkup.push(text);
|
||||
}
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ export default class {
|
|||
}
|
||||
|
||||
static testWord(word) {
|
||||
if (!/:[\w]+:/gmi.test(word)) return false;
|
||||
if (!/;[\w]+;/gmi.test(word)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -84,17 +84,17 @@ export default class {
|
|||
}
|
||||
}
|
||||
|
||||
static injectEmote(e) {
|
||||
static injectEmote(root) {
|
||||
if (!emotesEnabled) return;
|
||||
const isEmote = this.isEmote(e.textContent);
|
||||
if (!isEmote) return;
|
||||
const { bdemoteName, bdemoteSrc } = root.dataset;
|
||||
if (!bdemoteName || !bdemoteSrc) return;
|
||||
VueInjector.inject(
|
||||
e,
|
||||
root,
|
||||
DOM.createElement('span'),
|
||||
{ EmoteComponent },
|
||||
`<EmoteComponent src="${isEmote.src}" name="${isEmote.name}"/>`
|
||||
`<EmoteComponent src="${bdemoteSrc}" name="${bdemoteName}"/>`
|
||||
);
|
||||
e.classList.add('bd-is-emote');
|
||||
root.classList.add('bd-is-emote');
|
||||
}
|
||||
|
||||
static injectEmotes(element) {
|
||||
|
@ -104,7 +104,7 @@ export default class {
|
|||
|
||||
static isEmote(word) {
|
||||
if (!emotes) return null;
|
||||
const name = word.replace(/:/g, '');
|
||||
const name = word.replace(/;/g, '');
|
||||
const emote = emotes.find(emote => emote.id === name);
|
||||
if (!emote) return null;
|
||||
let { id, value } = emote;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import WebpackModules from './webpackmodules';
|
||||
import { WebpackModules } from './webpackmodules';
|
||||
import { $ } from 'vendor';
|
||||
|
||||
class List extends Array {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
import EventListener from './eventlistener';
|
||||
import { Utils } from 'common';
|
||||
import Events from './events';
|
||||
import WebpackModules from './webpackmodules';
|
||||
import { WebpackModules } from './webpackmodules';
|
||||
|
||||
import * as SocketStructs from '../structs/socketstructs';
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ export { default as PluginManager } from './pluginmanager';
|
|||
export { default as ThemeManager } from './thememanager';
|
||||
export { default as Globals } from './globals';
|
||||
export { default as Vendor } from './vendor';
|
||||
export { default as WebpackModules } from './webpackmodules';
|
||||
export * from './webpackmodules';
|
||||
export { default as ModuleManager } from './modulemanager';
|
||||
export { default as EventListener } from './eventlistener';
|
||||
export { default as SocketProxy } from './socketproxy';
|
||||
|
|
|
@ -8,86 +8,95 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import WebpackModules from './webpackmodules';
|
||||
import { WebpackModules } from './webpackmodules';
|
||||
import { ClientLogger as Logger } from 'common';
|
||||
|
||||
export default class Patcher {
|
||||
static get patches() { return this._patches || (this._patches = {}) }
|
||||
static resolveModule(mn) {
|
||||
if (mn instanceof Function || (mn instanceof Object && !(mn instanceof Array))) return mn;
|
||||
if ('string' === typeof mn) return WebpackModules.getModuleByName(mn);
|
||||
if (mn instanceof Array) return WebpackModules.getModuleByProps(mn);
|
||||
static resolveModule(module) {
|
||||
if (module instanceof Function || (module instanceof Object && !(module instanceof Array))) return module;
|
||||
if ('string' === typeof module) return WebpackModules.getModuleByName(module);
|
||||
if (module instanceof Array) return WebpackModules.getModuleByProps(module);
|
||||
return null;
|
||||
}
|
||||
static overrideFn(patch) {
|
||||
return function () {
|
||||
for (const s of patch.supers) {
|
||||
for (const superPatch of patch.supers) {
|
||||
try {
|
||||
s.fn.apply(this, arguments);
|
||||
} catch (err) { }
|
||||
superPatch.callback.apply(this, arguments);
|
||||
} catch (err) {
|
||||
Logger.err('Patcher', err);
|
||||
}
|
||||
}
|
||||
const retVal = patch.ofn.apply(this, arguments);
|
||||
for (const s of patch.slaves) {
|
||||
const retVal = patch.originalFunction.apply(this, arguments);
|
||||
for (const slavePatch of patch.slaves) {
|
||||
try {
|
||||
s.fn.apply(this, [arguments, { patch, retVal }]);
|
||||
} catch (err) { }
|
||||
slavePatch.callback.apply(this, [arguments, { patch, retVal }]);
|
||||
} catch (err) {
|
||||
Logger.err('Patcher', err);
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
|
||||
static rePatch(po) {
|
||||
po.patch = po.module[po.fnn] = this.overrideFn(po);
|
||||
static rePatch(patch) {
|
||||
patch.proxyFunction = patch.module[patch.functionName] = this.overrideFn(patch);
|
||||
}
|
||||
|
||||
static pushPatch(id, module, fnn) {
|
||||
static pushPatch(id, module, functionName) {
|
||||
const patch = {
|
||||
module,
|
||||
fnn,
|
||||
ofn: module[fnn],
|
||||
functionName,
|
||||
originalFunction: module[functionName],
|
||||
proxyFunction: null,
|
||||
revert: () => {
|
||||
patch.module[patch.fnn] = patch.ofn;
|
||||
patch.patch = null;
|
||||
patch.module[patch.functionName] = patch.originalFunction;
|
||||
patch.proxyFunction = null;
|
||||
patch.slaves = patch.supers = [];
|
||||
},
|
||||
supers: [],
|
||||
slaves: [],
|
||||
patch: null
|
||||
slaves: []
|
||||
};
|
||||
patch.patch = module[fnn] = this.overrideFn(patch);
|
||||
patch.proxyFunction = module[functionName] = this.overrideFn(patch);
|
||||
return this.patches[id] = patch;
|
||||
}
|
||||
|
||||
static superpatch(mn, fnn, cb, dn) {
|
||||
const module = this.resolveModule(mn);
|
||||
if (!module || !module[fnn] || !(module[fnn] instanceof Function)) return null;
|
||||
const displayName = 'string' === typeof mn ? mn : dn || module.displayName || module.name || module.constructor.displayName || module.constructor.name;
|
||||
const patchId = `${displayName}:${fnn}`;
|
||||
const patchObject = this.patches[patchId] || this.pushPatch(patchId, module, fnn);
|
||||
if (!patchObject.patch) this.rePatch(patchObject);
|
||||
const id = patchObject.supers.length + 1;
|
||||
const patch = {
|
||||
static superpatch(unresolveModule, functionName, callback, displayName) {
|
||||
const module = this.resolveModule(unresolveModule);
|
||||
if (!module || !module[functionName] || !(module[functionName] instanceof Function)) return null;
|
||||
displayName = 'string' === typeof unresolveModule ? unresolveModule : displayName || module.displayName || module.name || module.constructor.displayName || module.constructor.name;
|
||||
const patchId = `${displayName}:${functionName}`;
|
||||
|
||||
const patch = this.patches[patchId] || this.pushPatch(patchId, module, functionName);
|
||||
if (!patch.proxyFunction) this.rePatch(patch);
|
||||
const id = patch.supers.length + 1;
|
||||
const superPatch = {
|
||||
id,
|
||||
fn: cb,
|
||||
unpatch: () => patchObject.supers.splice(patchObject.supers.findIndex(slave => slave.id === id), 1)
|
||||
callback,
|
||||
unpactch: () => patch.slaves.splice(patch.slaves.findIndex(slave => slave.id === id), 1) // This doesn't actually work correctly not, fix in a moment
|
||||
};
|
||||
patchObject.supers.push(patch);
|
||||
return patch;
|
||||
|
||||
patch.supers.push(superPatch);
|
||||
return superPatch;
|
||||
}
|
||||
|
||||
static slavepatch(mn, fnn, cb, dn) {
|
||||
const module = this.resolveModule(mn);
|
||||
if (!module || !module[fnn] || !(module[fnn] instanceof Function)) return null;
|
||||
const displayName = 'string' === typeof mn ? mn : dn || module.displayName || module.name || module.constructor.displayName || module.constructor.name;
|
||||
const patchId = `${displayName}:${fnn}`;
|
||||
const patchObject = this.patches[patchId] || this.pushPatch(patchId, module, fnn);
|
||||
if (!patchObject.patch) this.rePatch(patchObject);
|
||||
const id = patchObject.slaves.length + 1;
|
||||
const patch = {
|
||||
static slavepatch(unresolveModule, functionName, callback, displayName) {
|
||||
const module = this.resolveModule(unresolveModule);
|
||||
if (!module || !module[functionName] || !(module[functionName] instanceof Function)) return null;
|
||||
displayName = 'string' === typeof unresolveModule ? unresolveModule : displayName || module.displayName || module.name || module.constructor.displayName || module.constructor.name;
|
||||
const patchId = `${displayName}:${functionName}`;
|
||||
|
||||
const patch = this.patches[patchId] || this.pushPatch(patchId, module, functionName);
|
||||
if (!patch.proxyFunction) this.rePatch(patch);
|
||||
const id = patch.slaves.length + 1;
|
||||
const slavePatch = {
|
||||
id,
|
||||
fn: cb,
|
||||
unpatch: () => patchObject.slaves.splice(patchObject.slaves.findIndex(slave => slave.id === id), 1)
|
||||
callback,
|
||||
unpactch: () => patch.slaves.splice(patch.slaves.findIndex(slave => slave.id === id), 1) // This doesn't actually work correctly not, fix in a moment
|
||||
};
|
||||
patchObject.slaves.push(patch);
|
||||
return patch;
|
||||
|
||||
patch.slaves.push(slavePatch);
|
||||
return slavePatch;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ import PluginManager from './pluginmanager';
|
|||
import ThemeManager from './thememanager';
|
||||
import Events from './events';
|
||||
import EventsWrapper from './eventswrapper';
|
||||
import WebpackModules from './webpackmodules';
|
||||
import { WebpackModules } from './webpackmodules';
|
||||
import { SettingsSet, SettingsCategory, Setting, SettingsScheme } from 'structs';
|
||||
import { BdMenuItems, Modals, DOM, Reflection } from 'ui';
|
||||
import DiscordApi from './discordapi';
|
||||
|
|
|
@ -10,40 +10,11 @@
|
|||
*/
|
||||
|
||||
import Patcher from './patcher';
|
||||
import WebpackModules from './webpackmodules';
|
||||
import { WebpackModules, Filters } from './webpackmodules';
|
||||
import DiscordApi from './discordapi';
|
||||
import { EmoteModule } from 'builtin';
|
||||
import { Reflection } from 'ui';
|
||||
|
||||
class Filters {
|
||||
static get byPrototypeFields() {
|
||||
return (fields, selector = x => x) => (module) => {
|
||||
const component = selector(module);
|
||||
if (!component) return false;
|
||||
if (!component.prototype) return false;
|
||||
for (const field of fields) {
|
||||
if (!component.prototype[field]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
static get byCode() {
|
||||
return (search, selector = x => x) => (module) => {
|
||||
const method = selector(module);
|
||||
if (!method) return false;
|
||||
return method.toString().search(search) !== -1;
|
||||
}
|
||||
}
|
||||
static get and() {
|
||||
return (...filters) => (module) => {
|
||||
for (const filter of filters) {
|
||||
if (!filter(module)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Helpers {
|
||||
static get plannedActions() {
|
||||
return this._plannedActions || (this._plannedActions = new Map());
|
||||
|
@ -231,32 +202,6 @@ class ReactComponent {
|
|||
return this._retVal;
|
||||
}
|
||||
|
||||
unpatchRender() {
|
||||
|
||||
}
|
||||
/*
|
||||
patchRender(actions, updateOthers) {
|
||||
const self = this;
|
||||
if (!(actions instanceof Array)) actions = [actions];
|
||||
Patcher.slavepatch(this.component.prototype, 'render', function (args, obj) {
|
||||
console.log('obj', obj);
|
||||
for (const action of actions) {
|
||||
let { selector, method, fn } = action;
|
||||
if ('string' === typeof selector) selector = Helpers.parseSelector(selector);
|
||||
const { item, parent, key } = Helpers.getFirstChild(obj, 'retVal', selector);
|
||||
console.log('item2', item);
|
||||
if (!item) continue;
|
||||
const content = fn.apply(this, [item]);
|
||||
switch (method) {
|
||||
case 'replace':
|
||||
parent[key] = content;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (updateOthers) self.forceUpdateOthers();
|
||||
});
|
||||
}
|
||||
*/
|
||||
forceUpdateOthers() {
|
||||
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import WebpackModules from './webpackmodules';
|
||||
import { WebpackModules } from './webpackmodules';
|
||||
import jQuery from 'jquery';
|
||||
import lodash from 'lodash';
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
class Filters {
|
||||
export class Filters {
|
||||
static byProperties(props, selector = m => m) {
|
||||
return module => {
|
||||
const component = selector(module);
|
||||
|
@ -205,7 +205,7 @@ const KnownModules = {
|
|||
ExternalLink: Filters.byCode(/\.trusted\b/)
|
||||
};
|
||||
|
||||
export default class WebpackModules {
|
||||
export class WebpackModules {
|
||||
|
||||
/**
|
||||
* Finds a module using a filter function.
|
||||
|
|
|
@ -68,7 +68,8 @@
|
|||
methods: {
|
||||
prevents(e) {
|
||||
if (!this.open) return;
|
||||
if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp' && e.key !== 'Tab') return;
|
||||
if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp' && e.key !== 'Tab' && e.key !== 'Enter') return;
|
||||
this.traverse(e);
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
},
|
||||
|
@ -82,38 +83,42 @@
|
|||
return uri.replace(':id', value);
|
||||
},
|
||||
searchEmotes(e) {
|
||||
if (this.traverse(e)) return;
|
||||
if (e.key === 'Tab' && this.open) {
|
||||
if (e.key === 'ArrowDown' || e.key === 'ArrowUp') return;
|
||||
if (e.key === 'Tab' || e.key === 'Enter' && this.open) {
|
||||
const selected = this.emotes[this.selectedIndex];
|
||||
if (!selected) return;
|
||||
this.inject(selected);
|
||||
this.reset();
|
||||
return;
|
||||
}
|
||||
if (e.key === 'Tab' && !this.open) this.open = true;
|
||||
if (!this.open) return;
|
||||
|
||||
const { selectionEnd, value } = e.target;
|
||||
this.sterm = value.substr(0, selectionEnd).split(/\s+/g).pop();
|
||||
|
||||
if (this.sterm.length < 3) {
|
||||
if (!this.sterm.startsWith(';')) {
|
||||
this.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.sterm.length < 4) {
|
||||
this.reset();
|
||||
return;
|
||||
}
|
||||
this.title = this.sterm;
|
||||
this.emotes = EmoteModule.filter(new RegExp(this.sterm, ''), 10);
|
||||
this.emotes = EmoteModule.filter(new RegExp(this.sterm.substr(1), ''), 10);
|
||||
this.open = this.emotes.length;
|
||||
},
|
||||
traverse(e) {
|
||||
if (!this.open) return false;
|
||||
if (!this.open) return;
|
||||
if (e.key === 'ArrowUp') {
|
||||
this.selectedIndex = (this.selectedIndex - 1) < 0 ? 9 : this.selectedIndex - 1;
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
if (e.key === 'ArrowDown') {
|
||||
this.selectedIndex = (this.selectedIndex + 1) >= 10 ? 0 : this.selectedIndex + 1;
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
return false;
|
||||
return;
|
||||
},
|
||||
reset() {
|
||||
this.emotes = [];
|
||||
|
@ -128,7 +133,7 @@
|
|||
const ta = document.querySelector('.chat textarea');
|
||||
if (!ta) return;
|
||||
const { selectionEnd, value } = ta;
|
||||
const en = `:${emote.id}:`;
|
||||
const en = `;${emote.id};`;
|
||||
let substr = value.substr(0, selectionEnd);
|
||||
substr = substr.replace(new RegExp(this.sterm + '$'), en);
|
||||
|
||||
|
|
Loading…
Reference in New Issue