Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ==UserScript==
- // @name OS chatEmbedFixer 2
- // @namespace eepic
- // @description (Violentmonkey) Fixes embeds on OnlineSequencer chat. Hides duplicate embeds / discord messages. Supports Tenor + Vocaroo embeds.
- // @icon https://onlinesequencer.net/favicon.ico
- // @version 2.0.1
- // @match *://onlinesequencer.net/*
- // @grant GM_xmlhttpRequest
- // @run-at document-end
- // ==/UserScript==
- // Log
- // 2025/07/18 - 1.0.0 - Script is finished
- // 2025/07/19 - 1.1.0 - Duplicate discord messages/embeds will now hide
- // ... - 1.1.1 - Supports startpage proxy images
- // 2026/01/20 - 1.2.0 - Since my change was finally merged, there is no need for the minifed ajaxChat function now :D
- // 2026/01/23 - 1.2.1 - document-start -> document-end -_- .. also, hide overflow-x (because of pooo)
- // 2026/01/26 - 2.0.0 - MAJOR REFACTOR - properly fetches URLs this time, and also works in the comments section.
- // 2026/01/27 - 2.0.1 - i am only adding 0.0.1 because its midnight and i bugfixed. it was a pain in the
- let mode;
- let observeElement; //asdokfjnpalhp,uawehjlcfmsndjkbonksmalfghdsxzdfghvjkgfdertfgvxcdzswretghgterwe3
- let loadedTime = Date.now();
- const allowed_types = new Set([
- 'image/png', 'image/jpeg', 'image/jpg', 'image/gif', 'image/webp',
- 'audio/wav', 'audio/x-wav', 'audio/flac', 'audio/mpeg', 'audio/ogg', 'audio/webm', 'audio/mp4', 'audio/x-m4a',
- 'video/mp4', 'video/x-matroska', 'video/webm', 'video/ogg'
- ]);
- // properly fetch this time
- function getEmbedType(url, callback) {
- GM_xmlhttpRequest({
- method: 'HEAD',
- url: url,
- timeout: 677,
- onload: function(res) {
- if (res.status >= 200 && res.status < 300) { // should be ok
- let headers = res.responseHeaders;
- let matchAll = headers.matchAll(/^content-type: ([^\n\r;]+)/gmi);
- let allowed = true;
- let firstType;
- for (const i of matchAll) {
- let thisType = i[1]?.toLowerCase().trim();
- if (!firstType) firstType = thisType;
- if (!allowed_types.has(thisType)) {
- allowed = false;
- break;
- }
- }
- callback(allowed ? firstType : undefined);
- }
- },
- onerror: function(e) {
- console.warn('Failed to fetch url:', e);
- callback();
- },
- ontimeout: () => callback()
- });
- }
- function embedElement(parent, type, callback, doTheThingAtTheEndBecauseItHasSrcOkayPlease) {
- const wrapper = document.createElement('div');
- const element = document.createElement(type);
- wrapper.style.left = '0';
- wrapper.style.width = '100%';
- wrapper.style.height = '100%';
- wrapper.style.position = 'relative';
- // apparently you have to do this *before* setting src. lol!
- // lululu luflan pa ☆~~ lalalala
- if (doTheThingAtTheEndBecauseItHasSrcOkayPlease && mode === 'chat') {
- element.onload = () => {
- queueMicrotask(() => { // don't ask why this works, it just works. probably
- observeElement.scrollTop = observeElement.scrollHeight;
- });
- }
- }
- callback(wrapper, element);
- wrapper.appendChild(element);
- parent.appendChild(wrapper);
- }
- function replaceMessageWithSmall(message, text) {
- message.innerHTML = '';
- const wrapper = document.createElement('div');
- wrapper.textContent = text;
- wrapper.style.color = '#9e9e9e';
- wrapper.style.fontSize = '12px';
- const outer = document.createElement('div');
- outer.style.textAlign = 'left';
- outer.appendChild(wrapper);
- message.appendChild(outer);
- }
- function checkForEmbeds(chat) {
- if (chat.classList.contains('embed-checked')) return;
- chat.classList.add('embed-checked');
- let message = chat.querySelector('.message');
- // if already has an image, fix, return
- const img = message.querySelector('.mycode_img')
- if (img) {
- // ensure img is not video
- getEmbedType(img.src, embedType => {
- if (embedType?.includes('video')) {
- embedElement(message, 'video', (wrapper, video) => {
- video.src = img.src;
- img.remove();
- video.controls = true;
- video.style.maxWidth = '100%';
- video.style.maxHeight = '300px';
- video.style.objectFit = 'contain';
- })
- } else {
- img.style.maxWidth = '100%';
- img.style.maxHeight = '300px';
- img.style.objectFit = 'contain';
- }
- });
- return;
- }
- // check each url, only embed one
- let allcodeUrl = Array.from(message.querySelectorAll('a'));
- function checkThis(i) {
- let thisUrl = allcodeUrl[i]?.href;
- if (!thisUrl) return;
- // ignore sequence urls
- if (/https?:\/\/(?:t?e?s?t?\.?onlinesequener.net|seq\.onl)\/\d+\/?$/.exec(thisUrl)) { // i dont think seq.onl is even working at the time of writing this lmfao
- return;
- }
- function onCheckFinished(embedType, url, ...args) {
- let shouldScroll = Math.abs(observeElement.scrollTop + observeElement.clientHeight - observeElement.scrollHeight) <= 3;
- if (!shouldScroll && Date.now() - loadedTime < 5000) shouldScroll = true; // hacky but it works(?) and im happy
- // check dupe
- if (mode == 'chat') {
- let lastChat = chat.previousElementSibling;
- if (lastChat) {
- chat.__CEF_embedded = url;
- const lastEmbedded = lastChat.__CEF_embedded == url;
- const lastDupe = lastChat.__CEF_isDupeOf?.__CEF_embedded == url;
- const thisChatSender = chat.querySelector('.name a')?.textContent || '!self';
- const lastChatSender = lastChat.querySelector('.name a')?.textContent || '!self';
- // all this just to detect if user whispered to themself ... FML
- _goAwayNoob = (() => { // i hate nesting if statements
- if (thisChatSender !== '!self' || lastChatSender == '!self') return;
- const lastMessageChildren = lastChat.querySelector('.message')?.children;
- if (!lastMessageChildren) return;
- const lastMessageFirstChild = lastMessageChildren[0];
- if (lastMessageFirstChild?.classList.contains('mycode_i') && lastMessageFirstChild?.textContent == '(whisper)') { // can be spoofed but whatever idc
- let whisperSentTo = message.children[0]?.textContent
- if (!whisperSentTo) return;
- whisperSentTo = /-> (.*(?!$))/g.exec(whisperSentTo);
- if (whisperSentTo[1] == lastChatSender) {
- chat.__CEF_isDupeOf = lastChat;
- replaceMessageWithSmall(message, '[Duplicate embed hidden. How dare you whisper to yourself!]');
- return true;
- }
- }
- })()
- if (_goAwayNoob) return;
- if ((lastEmbedded || lastDupe) && thisChatSender == lastChatSender) {
- chat.__CEF_isDupeOf = lastEmbedded ? lastChat : lastChat.__CEF_isDupeOf;
- replaceMessageWithSmall(message, '[Duplicate embed hidden]');
- return;
- }
- }
- }
- switch(embedType) {
- case 'vocaroo':
- embedElement(message, 'iframe', (wrapper, iframe) => {
- wrapper.style.height = '60px';
- iframe.src = url;
- iframe.style.position = 'absolute';
- iframe.style.top = '0';
- iframe.style.left = '0';
- iframe.style.width = '90%';
- iframe.style.height = '100%';
- iframe.style.border = '0';
- iframe.allowFullscreen = true;
- }, shouldScroll)
- break;
- case 'tenor':
- embedElement(message, 'img', (wrapper, img) => {
- img.src = url;
- img.alt = 'Embedded Tenor GIF';
- img.style.maxWidth = '100%';
- img.style.maxHeight = '300px';
- img.style.objectFit = 'contain';
- wrapper.style.textAlign = 'left';
- }, shouldScroll);
- break;
- case 'default':
- let embedType2 = args[0];
- let elementType = embedType2.includes('video') ? 'video' : embedType2.includes('audio') ? 'audio' : 'img';
- embedElement(message, elementType, (wrapper, element) => {
- element.style.maxWidth = '100%';
- element.style.maxHeight = '300px';
- element.style.objectFit = 'contain';
- element.src = url;
- if (elementType == 'video' || elementType == 'audio') {
- element.controls = true;
- }
- }, shouldScroll)
- break;
- }
- // don't ask if *this* one works because i have no clue im so done with this lol
- if (shouldScroll) {
- setTimeout(() => {observeElement.scrollTop = observeElement.scrollHeight + 10000}, 0);
- }
- }
- // trusted urls
- if (thisUrl.includes('vocaroo.com/') || thisUrl.includes('voca.ro/')) {
- const vocarooIdMatch = thisUrl.match(/(?:vocaroo\.com|voca\.ro)\/([a-zA-Z0-9]+)/);
- if (vocarooIdMatch && vocarooIdMatch[1]) {
- const vocarooId = vocarooIdMatch[1];
- const embedUrl = `https://vocaroo.com/embed/${vocarooId}`;
- onCheckFinished('vocaroo', embedUrl);
- }
- } else if (thisUrl.includes('tenor.com/view')) {
- // zzzzzzz
- GM_xmlhttpRequest({
- method: 'GET',
- url: thisUrl,
- onload: function (response) {
- const imgMatch = response.responseText.match(/<meta[^>]+property="og:image"[^>]+content="([^"]+)"/i);
- if (imgMatch && imgMatch[1]) {
- const imgUrl = imgMatch[1];
- onCheckFinished('tenor', imgUrl);
- }
- },
- onerror: function (err) {
- console.warn('Failed to fetch Tenor embed:', err);
- }
- });
- return;
- } else {
- let thisType = getEmbedType(thisUrl, thisType => {
- if (thisType) {
- onCheckFinished('default',thisUrl,thisType);
- } else {
- checkThis(i+1);
- }
- })
- }
- }
- checkThis(0);
- }
- function startObserve() {
- let comments = document.querySelector('#comments');
- if (window.location.href.includes('/forum/chat_frame.php')) {
- mode = 'chat';
- } else if (comments) {
- if (!document.querySelector('#sequencer_main_row')) {
- console.log('sequencer not found ono');
- return;
- }
- mode = 'comments';
- }
- if (!mode) return;
- console.log(`chatEmbedFixer running mode ${mode}`);
- observeElement = mode === 'chat' ? document.querySelector('#chat_table') : comments;
- if (!observeElement) {
- setTimeout(startObserve, 250);
- return;
- }
- if (mode === 'chat') observeElement.style.overflowX = 'hidden';
- const observer = new MutationObserver((mutationsList) => {
- for (const mutation of mutationsList) {
- for (const node of mutation.addedNodes) {
- if (node.className === 'chat') {
- checkForEmbeds(node);
- }
- }
- }
- });
- observer.observe(observeElement, {childList: true});
- observeElement.querySelectorAll('.chat').forEach(checkForEmbeds);
- }
- startObserve();
Advertisement
Add Comment
Please, Sign In to add comment