Files
browser-scripts/scripts/ttv-obfuscated-names/dom.ts
T
2026-04-18 23:44:01 -05:00

194 lines
5.5 KiB
TypeScript

import { obfuscator } from './obfuscator'
import { NameConfigInstance, nameImages } from './options'
import {
ChatMessage,
innermostElement,
usernameImageTemplateSuffix,
usernameTemplateSuffix,
} from './util'
export function loadChatMessage(chatboxMessage: Element) {
// only chat messages
const chatboxMessageInner = chatboxMessage.querySelector(
'.chat-line__message'
)
if (!chatboxMessageInner) {
return
}
// get chatbox details
const chatboxBadgeContainer = chatboxMessage.querySelector<HTMLSpanElement>(
'.chat-line__message--badges'
)
if (!chatboxBadgeContainer) {
console.error("found message, couldn't find badges")
return
}
const chatboxUser = chatboxMessage.querySelector<HTMLSpanElement>(
'.chat-line__username'
)
if (!chatboxUser) {
console.error("found message, couldn't find user")
return
}
const chatboxUserInner = chatboxUser.querySelector<HTMLSpanElement>(
'.chat-author__display-name'
)
if (!chatboxUserInner) {
console.error("found message, couldn't find userInner")
return
}
// got the data, so we're loaded
chatboxMessage.classList.add('obf-loaded')
// hide 7tv extra colors
if (chatboxUser.classList.contains('seventv-paint')) {
chatboxUser.classList.remove('seventv-paint')
}
// check if mod
let isMod = false
for (const badge of chatboxBadgeContainer.children) {
if (
badge.hasAttribute('data-badge') &&
(badge.getAttribute('data-badge') === 'moderator' ||
badge.getAttribute('data-badge') === 'broadcaster')
) {
isMod = true
chatboxMessage.classList.add('ismod')
}
}
// combine details into object
const chatMessage: ChatMessage = {
username: chatboxUserInner.textContent,
isMod,
}
// run main script (process chatMessage), return new ChatMessage
const newChatMessage = obfuscator(chatMessage)
if (newChatMessage !== null) {
setUsernameDetails(newChatMessage, chatboxUserInner, chatboxUser)
}
loadReplyLine(chatboxMessage)
loadMessageMentions(chatboxMessage)
}
function loadReplyLine(chatboxMessage: Element) {
const replyline = chatboxMessage.querySelector('.ffz--fix-reply-line')
const replyUsername = replyline?.querySelector<HTMLElement>(
'p > span:nth-child(1)'
)
if (!replyUsername) {
return
}
const chatMessage: ChatMessage = {
username: replyUsername.textContent.replace(/^@/, ''),
isMod: false,
}
// run main script (process chatMessage), return new ChatMessage
const newChatMessage = obfuscator(chatMessage)
if (newChatMessage !== null) {
setUsernameDetails(newChatMessage, replyUsername, undefined, '@')
}
}
function loadMessageMentions(chatboxMessage: Element) {
function eachMention(messageMention: HTMLElement) {
const chatMessage: ChatMessage = {
username: messageMention.textContent.replace(/^@/, ''),
isMod: false,
}
// run main script (process chatMessage), return new ChatMessage
const newChatMessage = obfuscator(chatMessage)
if (newChatMessage !== null) {
setUsernameDetails(newChatMessage, messageMention, undefined, '@')
}
}
const messageMentions = chatboxMessage.querySelectorAll<HTMLElement>(
'.chat-line__message-mention'
)
for (const messageMention of messageMentions) {
eachMention(messageMention)
}
}
export function loadAdditionalUserNames(chatboxMessage: Element) {
// look for additional chat member names
const chatterNames =
chatboxMessage.querySelectorAll<HTMLElement>('.chatter-name')
for (const chatterName of chatterNames) {
chatboxMessage.classList.add('obf-loaded')
const chatterNameBox = innermostElement(chatterName)
const username = chatterNameBox.textContent
if (!username) {
continue
}
// combine details into object
const chatMessage: ChatMessage = {
username,
isMod: false,
}
// run main script (process chatMessage), return new ChatMessage
const newChatMessage = obfuscator(chatMessage)
if (newChatMessage !== null) {
setUsernameDetails(newChatMessage, chatterNameBox)
}
}
}
function setUsernameDetails(
newChatMessage: NameConfigInstance,
textbox: HTMLElement,
colorbox?: HTMLElement,
prefixStr: string = ''
) {
const username = `${newChatMessage.username}${usernameTemplateSuffix(newChatMessage)}`
const imageName = newChatMessage.image
if (imageName) {
// image name
const image = nameImages[imageName]
const img = document.createElement('img')
img.classList.add('obf-image', 'ffz--pointer-events', 'ffz-tooltip')
img.setAttribute('data-tooltip-type', 'html')
img.setAttribute('data-title', username)
img.setAttribute('alt', username)
img.setAttribute('src', image)
const prefix = document.createElement('span')
prefix.textContent = prefixStr
const suffix = document.createElement('span')
suffix.textContent = usernameImageTemplateSuffix(newChatMessage)
textbox.replaceChildren(prefix, img, suffix)
} else {
// text name only
textbox.textContent = `${prefixStr}${username}`
}
if (colorbox) {
colorbox.style.color = newChatMessage.color
}
}