import { bttv_get_url } from "./bttv_api"; import { map_concurrent } from "./helpers"; const emote_regex = /bttv:([^\s]+)/gi; /** * Process "bttv:*" emotes in a string * * @param text the input string * @returns new string with existing "bttv:*" emotes replaced by "[not]" BBCodes */ async function process_text(text: string): Promise { // find "bttv:*" emotes const matches = [...text.matchAll(emote_regex)]; // unique emote codes (the "*" parts) const codes = new Set(matches.map(([_, code]) => code)); // find emote pics using BTTV API console.log("[lmlfc-bttv]", `searching ${[...codes].length} emotes`); const emotes = await map_concurrent(codes, bttv_get_url); // replace emotes with BBCodes for (const emote of matches.reverse()) { const [match, code] = emote; // ensure emote exists const url = emotes.get(code); if (url == null) continue; // ensure position in input string is known const index = emote.index; if (index == undefined) continue; text = text.substring(0, index) + `[not]${url}[/not]` + text.substring(index + match.length); } // remove space between adjacent emotes // (maybe do this in emote_regex instead?) return text.replace(/\[\/not\]\s+\[not\]/g, "[/not][not]"); } (() => { // find chatbox elements const cb_form = document.querySelector("#mgc_cb_evo_form"); const cb_send = document.querySelector( "#mgc_cb_evo_form > input[type=image]:nth-child(2)", ); const cb_input = document.querySelector("#mgc_cb_evo_input"); // check chatbox elements if (!(cb_form instanceof HTMLFormElement)) return; if (!(cb_send instanceof HTMLInputElement)) return; if (!(cb_input instanceof HTMLInputElement)) return; // create "bttv" button const bttv_btn = (() => { const btn = document.createElement("a"); btn.style.setProperty("cursor", "pointer"); btn.style.setProperty("margin-right", "4px"); const img = document.createElement("img"); img.setAttribute("src", chrome.runtime.getURL("img/sb_button.png")); img.setAttribute("alt", "bttv emotes ersetzen und absenden"); img.setAttribute("title", "bttv:* emotes ersetzen und absenden"); img.style.setProperty("vertical-align", "middle"); // ****************** // * business logic * // ****************** btn.addEventListener("click", async () => { cb_input.value = await process_text(cb_input.value); cb_input.focus(); cb_send.click(); }); btn.appendChild(img); return btn; })(); cb_form.insertBefore(bttv_btn, cb_send); console.log("[lmlfc-bttv]", `loaded`); })();