Skip to content

Instantly share code, notes, and snippets.

@shaenr
Last active September 4, 2021 00:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shaenr/1b700907cbebc987b4d0dd5cae455707 to your computer and use it in GitHub Desktop.
Save shaenr/1b700907cbebc987b4d0dd5cae455707 to your computer and use it in GitHub Desktop.
Prototype to modify discord client by toggling elements that are in the way.
// Prototype to modify discord client by toggling elements that are in the way.
// TestUsage: 1) paste the entire code into the devtools console, accessed
// by CTRL + SHIFT + I. (at your own risk :P)
// 2) Select the main chat screen you want to keep open.
// 3) Use "l33t_t0g" button to toggle the elements off and on.
// 3) You can also use `window.toggleShowHide()` from the console if
// button is not working.
// 4) reset any problems by pressing F5 from the dev tools window
// or simply restart discord if necessary.
// ISSUES: 1) It is possible these selectors will only work with my version of
// discord on my device. Selector compatability may need to be
// worked out.
// 2) TODO: Fix broken height scroll on channel lists
// after calling show.
/** Define Default Selectors */
function getDefaultSelectors() {
const friendsListSelector = '#app-mount > div.app-1q1i1E > div > div.layers-3iHuyZ.layers-3q14ss > div > div > div > div > div.sidebar-2K8pFh';
const serverListSelector = '#app-mount > div.app-1q1i1E > div > div.layers-3iHuyZ.layers-3q14ss > div > div > nav > ul > div.scroller-1Bvpku.none-2Eo-qx.scrollerBase-289Jih';
const serverListContainerSelector = '#app-mount > div.app-1q1i1E > div > div.layers-3iHuyZ.layers-3q14ss > div > div > nav';
return [friendsListSelector, serverListSelector, serverListContainerSelector]
}
/** Get Elements Nodes Using Default Selectors or
* @param {Array} selectorsArr - strings to be passed to document.querySelector
*/
function getElementNodes(selctorsArr) {
// use default selectors if array is not passed.
const selectors = typeof selectorsArr !== null ?
getDefaultSelectors() : selctorsArr instanceof Array ?
selctorsArr : null;
if (typeof selectors === null) {
throw new Error(
"selectors not properly passed or found by getElementNodes"
)
}
let nodes = {
"selectors": selectors,
"valid": [],
"failed": []
};
let node;
for (let selector of selectors) {
node = document.querySelector(selector);
if (node instanceof HTMLElement) {
nodes['valid'].push(node);
} else {
nodes['failed'].push(selector)
}
}
return nodes
}
/** DEPREACATED, use insertToggleBtnToContainerNode
*
* Select an anchor element in the DOM and modify its behaviour to toggle state.
* @param {string} oldBtnSelector - the selector for an anchor element.
*/
function useNodeAsToggleBtn (oldBtnSelector) {
const btn = document.querySelector(oldBtnSelector);
if (!btn instanceof HTMLAnchorElement) {
throw new Error("oldBtnSelector did not resolve into valid anchor node.")
}
btn.removeAttribute("href");
btn.removeAttribute("_target");
btn.removeAttribute("rel");
btn.setAttribute('aria-label', "l33t_t0gglez");
btn.setAttribute('onclick', "window.toggleShowHide()");
}
/** Use this to Insert a Button with an Event Handler for toggleShowHide
* @param {string} containerSelector - selector for the container for buttons
*/
function insertToggleBtnToContainerNode (containerSelector) {
const btnToolbar = document.querySelector(containerSelector);
const oldBtnSvgIcon = document.querySelector('#app-mount > div.app-1q1i1E > div > div.layers-3iHuyZ.layers-3q14ss > div > div > div > div > div.chat-3bRxxu > section > div.toolbar-1t6TWx > a > div > svg');
const myBtnSvgIcon = oldBtnSvgIcon.cloneNode(true);
let myBtnIconWrapper = document.createElement('div');
myBtnIconWrapper.class = "iconWrapper-2OrFZ1 clickable-3rdHwn";
myBtnIconWrapper.role = "button";
myBtnIconWrapper.ariaLabel = "l33t_t0gglez";
let myDiscordBtn = document.createElement('a');
myDiscordBtn.onclick = () => window.toggleShowHide()
myDiscordBtn.ariaLabel = "l33t_t0gglez";
// myDiscordBtn.setAttribute('aria-label', "l33t_t0gglez");
myDiscordBtn.href = "#";
myDiscordBtn.innerHTML = "l33t_t0g";
myDiscordBtn.className = "anchor-3Z-8Bb anchorUnderlineOnHover-2ESHQB";
myDiscordBtn.role = "button";
myDiscordBtn.tabindex = "-1";
myBtnIconWrapper.appendChild(myBtnSvgIcon)
myDiscordBtn.appendChild(myBtnIconWrapper)
btnToolbar.appendChild(myDiscordBtn)
}
/** Itterate through all nodes and set their style.display prop
* @param {Object} nodesObj - returned from getElementNodes
* @param {string} value - display property value, use "none" or "block"
*/
function setDisplayPropertyOnNodes(nodesObj, value) {
const nodes = nodesObj['valid'];
for (let node of nodes) {
node.style.display = value;
console.log(`${node} set to ${value}`);
}
}
/** Event handle for the button hijacked by useNodeAsToggleBtn */
function toggleShowHide () {
console.log("Test");
if (!toggleState) {
hide()
} else {
show()
}
toggleState = !toggleState;
}
/** Main */
window.toggleShowHide = toggleShowHide;
let toggleState = false;
const toggleNodes = getElementNodes() // can override default by passing array
const btnToolbarSelector = '#app-mount > div.app-1q1i1E > div > div.layers-3iHuyZ.layers-3q14ss > div > div > div > div > div.chat-3bRxxu > section > div.toolbar-1t6TWx';
insertToggleBtnToContainerNode(btnToolbarSelector);
const hide = () => setDisplayPropertyOnNodes(toggleNodes, "none");
const show = () => setDisplayPropertyOnNodes(toggleNodes, "block");
@shaenr
Copy link
Author

shaenr commented Sep 3, 2021

The reason why the button doesn't work is this

Refused to execute inline event handler because it violates the following Content Security Policy directive: "script-src 'self' 'unsafe-eval' 'unsafe-inline' 'nonce-MTM1LDIwOSwzMSw2NSwxMzcsMTE3LDczLDIy' https://cdn.discordapp.com/animations/ https://www.gstatic.com/recaptcha/ https://www.google.com/recaptcha/ https://recaptcha.net/recaptcha/ https://*.hcaptcha.com https://hcaptcha.com https://js.stripe.com https://js.braintreegateway.com https://assets.braintreegateway.com https://www.paypalobjects.com https://checkout.paypal.com". Note that 'unsafe-inline' is ignored if either a hash or nonce value is present in the source list.

They cant stop me from registering an event handler in my own browser can they...?

Should probably just insert my own elem rather than reuse theirs. Most likely will have same problem tho.

@shaenr
Copy link
Author

shaenr commented Sep 3, 2021

This works, just needed to create my own button instead of trying to modify their button.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment