您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Add BetterTV smilies to editor autocomplete
// ==UserScript== // @name LZT BetterTV AC // @namespace lzt-bettertv-ac // @description Add BetterTV smilies to editor autocomplete // @version 1.0.0 // @author Toil // @homepageURL https://t.me/lzt_upgrade // @icon https://cdn.lztup.net/brand/logo-mini.png // @license MIT // @match *://lolz.guru/* // @match *://lolz.live/* // @match *://zelenka.guru/* // @match *://zelenka.market/* // @match *://lzt.market/* // @match *://lolz.market/* // @supportURL https://t.me/lzt_upgrade // ==/UserScript== // Generated by LZT Upgrade extension bundler. Telegram: https://t.me/lzt_upgrade Github: https://github.com/lzt-upgrade var __legacyDecorateClassTS = function(decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1;i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; // __style_helper__ function injectStyle(text, hash) { if (typeof document === "undefined") { return; } const style = document.createElement("style"); style.id = `lztup_${hash}`; style.innerText = text; document.head.appendChild(style); } // lzt-bettertv-ac/style.css injectStyle(".fe-ac-BetterTV{flex-direction:row;display:flex}.fe-ac-smilie-image.lztup-smilie{margin:0!important}", "fa4e12cb0f2f32d4"); // lzt-bettertv-ac/index.js function registerBetterTVAC(froala) { new CustomEditorAutoCompleter(froala.$el, { insertMode: "html" }, froala); } if (typeof Lolzteam.ACProvider !== "function") { console.log("[BetterTVAC] FroalaEditor isn't loaded"); return; } class BetterTVACProvider extends Lolzteam.ACProvider { constructor(froala) { super(froala, "BetterTV"); this.froala = froala; this.apiUrl = "https://api.betterttv.net/3/"; this.cdnUrl = "https://cdn.betterttv.net/"; this.limit = 5; this.debounceTime = 300; } debounceShow(text) { if (this.debounceTimer) { clearTimeout(this.debounceTimer); } this.debounceTimer = setTimeout(async () => { let results = await this.searchSmilies(text[0] === ":" ? text.slice(1) : text); if (!results?.length) { return false; } this.state = { text, textNode: this.froala.selection.get().anchorNode }; this.popup.html(""); const prioritySmilies = $(".fe-ac-smilie > .fe-ac-smilie-result").toArray(); for (const prioritySmilie of prioritySmilies) { $(prioritySmilie).appendTo(this.popup); } for (const result of results) { if (this.popup.find(".fe-ac-smilie-result").length >= this.limit) { continue; } $('<div class="fe-ac-smilie-result fe-ac-result"/>').append($("<img/>", { class: "fe-ac-smilie-image fr-draggable lztup-smilie", alt: result.name, title: result.name, src: result.image })).appendTo(this.popup); } this.debounceTimeout = null; this.showPopup(); }, this.debounceTime); } async searchSmilies(text) { if (text.length < 3) { return []; } try { const res = await fetch(`${this.apiUrl}emotes/shared/search?query=${text}&offset=0&limit=${this.limit}`); const data = await res.json(); return data.map((smilie) => ({ aliases: [], image: `${this.cdnUrl}emote/${smilie.id}/1x.webp`, name: smilie.code, value: `:${smilie.code}:` })); } catch (err) { console.error(`[BetterTVAC] Failed to search BetterTV smilies by text: ${err.message}`); } } async trigger() { let text = this.getSelectedText(", "); let selectedNode = this.froala.selection.get().anchorNode; let previousSibling = selectedNode.previousSibling || selectedNode.parentNode.previousSibling; selectedNode = selectedNode?.cloneNode(true); previousSibling = previousSibling?.cloneNode(true); if (!text || text.indexOf("@") !== -1 || selectedNode.textContent.startsWith(text) && previousSibling && previousSibling?.textContent.length !== 0 && !previousSibling?.textContent.endsWith(" ")) { return false; } text = text?.trim(); this.hide(); this.debounceShow(text); return true; } insertResult() { if (!this.popup.find(".active").length) { this.hide(); return false; } this.froala.selection.save(); this.state.textNode.textContent = this.state.textNode.textContent.trimEnd().slice(0, -this.state.text.length); this.froala.selection.restore(); this.froala.html.insert(this.popup.find(".active").html()); $("#lzt-fe-eb-smilie").trigger("ac-picked-smilie"); this.hide(); return true; } } class CustomEditorAutoCompleter extends Lolzteam.EditorAutoCompleter { constructor(el, n, froala) { super(el, n, froala); this.froala = froala; this.providers = [new BetterTVACProvider(froala)]; froala.events.on("keydown", this.onKeydown.bind(this), true); froala.events.on("keyup", this.onKeyup.bind(this), true); froala.events.on("focus", this.onFocus.bind(this), true); } } FroalaEditor.MODULES.smilieBetterTVAC = function(e) { return { _init: registerBetterTVAC(e) }; };