I made a script that allows you to chat, and to click links in the Melonland chat when in Rout 66 mode.
Some people wanted to be able to click links, and I personally wanted to be able to chat - both without leaving Rout 66 mode. So I made this userscript to allow you to do both.
If you don't have it already, you'll need to use a plugin for your browser called ViolentMonkey, which can be found here:
https://violentmonkey.github.io/Quick little tutorial on how to use:
- To send a chat message in the normal chat, use the /chat command with your message added
- To click links, hold your Control key or Command key (on macOS) and click a link
This script took me an embarrassingly long time to make, primarily cause I had no idea how keyboard input was handled with iframes - something I wish browsers had documentation for!
Anyways, here's the userscript:
// ==UserScript==
// @name Rout 66 chat enhancer
// @namespace Violentmonkey Scripts
// @icon https://forum.melonland.net/apple-touch-icon.png
// @version 1.0.1
//
// @match https://forum.melonland.net/chat.php*
// @grant none
//
// @author mrparker
// @description Allows you to still chat and click links in the melonland chat when in Rout 66 mode
// ==/UserScript==
const chatBarSelector = `input[placeholder="Send a chat message... or /help"]` // chatbar inside the route frame
const inputBarInFrame = `div.shoutbox_input_bar` // inside chat iframe (contains chat box and submit buttons)
const melonStreetPaneId = "melon-street-plane" // overlay that prevents clicking links
const keyCode = navigator.platform.indexOf("Mac") == -1 ? "Control" : "MetaLeft" // Customize the key to press to allow links to be clicked
// Shouldn't ever need to edit anything below
const chatBar = document.querySelector(chatBarSelector)
const melonStreetPane = document.getElementById(melonStreetPaneId)
const setPointerEvents = (enabled) => {
const autoOrNot = enabled == true ? "auto" : "none"
const currentlyEnabled = autoOrNot == "auto" ? "none" : "auto"
melonStreetPane.setAttribute("style", melonStreetPane.getAttribute("style").replace(`pointer-events: ${currentlyEnabled};`, `pointer-events: ${autoOrNot};`))
}
const handleInputEvent = (event) => {
if (event.code != keyCode)
return;
setPointerEvents(melonStreetPane.getAttribute("style").indexOf("pointer-events: none;") != -1 ? true : false)
}
window.addEventListener("keydown", handleInputEvent)
window.addEventListener("keyup", handleInputEvent)
document.getElementById("chat-window").addEventListener("load", (e) => {
const contentDocument = e.target.contentDocument
const contentWindow = e.target.contentWindow
const chatBarSubmit = contentDocument.querySelector(`${inputBarInFrame} input[type="submit"]`)
const chatBarTextBox = contentDocument.querySelector(`${inputBarInFrame} input[type="text"]`)
// This took me an embarassingly long time to figure out
// note: just because it's an iframe, doesn't mean it can't
// capture events from it's parent document
contentWindow.addEventListener("keydown", handleInputEvent)
contentWindow.addEventListener("keyup", handleInputEvent)
Street.registerCommand("chat", (message) => {
chatBarTextBox.value = message
chatBarSubmit.click()
chatBar.focus()
})
})
Enjoy!