Skip to content

Instantly share code, notes, and snippets.

@beerpiss
Last active May 11, 2022 13:51
Show Gist options
  • Save beerpiss/b873d8a21bb5af064cb08a47b9559aa5 to your computer and use it in GitHub Desktop.
Save beerpiss/b873d8a21bb5af064cb08a47b9559aa5 to your computer and use it in GitHub Desktop.
Left sidebar toggler for Facebook Messenger
// SPDX-License-Identifier: 0BSD
// ==UserScript==
// @name Collapse Facebook Messenger's sidebar
// @namespace messenger-collapse-sidebar
// @match https://www.messenger.com/*
// @version 0.1.2
// @author beerpsi
// @description Collapse and expand Messenger's left sidebar
// @downloadURL https://gist.githubusercontent.com/beerpiss/b873d8a21bb5af064cb08a47b9559aa5/raw/messenger-collapse-sidebar.js
// @updateURL https://gist.githubusercontent.com/beerpiss/b873d8a21bb5af064cb08a47b9559aa5/raw/messenger-collapse-sidebar.js
// @homepageURL https://gist.github.com/beerpiss/b873d8a21bb5af064cb08a47b9559aa5
// ==/UserScript==
(function () {
'use strict';
const ARIA_LABEL = 'Toggle sidebar';
const EXPAND_SIDEBAR = 'M880 224H144c-26.5 0-48-21.5-48-48s21.5-48 48-48h736c26.5 0 48 21.5 48 48s-21.5 48-48 48zM144 576h416c26.5 0 48 21.5 48 48s-21.5 48-48 48H144c-26.5 0-48-21.5-48-48s21.5-48 48-48zM144 352h416c26.5 0 48 21.5 48 48s-21.5 48-48 48H144c-26.5 0-48-21.5-48-48s21.5-48 48-48zM880 896H144c-26.5 0-48-21.5-48-48s21.5-48 48-48h736c26.5 0 48 21.5 48 48s-21.5 48-48 48zM917.4 489.4L790.6 362.6c-20.2-20.2-54.6-5.9-54.6 22.6v253.5c0 28.5 34.5 42.8 54.6 22.6l126.7-126.7c12.6-12.5 12.6-32.7 0.1-45.2z';
const HIDE_SIDEBAR = 'M880 224H144c-26.5 0-48-21.5-48-48s21.5-48 48-48h736c26.5 0 48 21.5 48 48s-21.5 48-48 48zM880 448H464c-26.5 0-48-21.5-48-48s21.5-48 48-48h416c26.5 0 48 21.5 48 48s-21.5 48-48 48zM880 672H464c-26.5 0-48-21.5-48-48s21.5-48 48-48h416c26.5 0 48 21.5 48 48s-21.5 48-48 48zM880 896H144c-26.5 0-48-21.5-48-48s21.5-48 48-48h736c26.5 0 48 21.5 48 48s-21.5 48-48 48zM106.6 534.6l126.7 126.7c20.2 20.2 54.6 5.9 54.6-22.6V385.3c0-28.5-34.5-42.8-54.6-22.6L106.6 489.4c-12.5 12.5-12.5 32.7 0 45.2z';
const SIDEBAR_SELECTOR = 'div[role="navigation"].rq0escxv.l9j0dhe7.j83agx80.cbu4d94t.d2edcug0.hpfvmrgz.pfnyh3mw.dp1hu0rb.rek2kq2y.o36gj0jk.tkr6xdv7';
const CHAT_NAME_SELECTOR = 'div.rq0escxv.l9j0dhe7.du4w35lb.j83agx80.rj1gh0hx.buofh1pr.g5gj957u.hpfvmrgz.i1fnvgqd.bp9cbjyn.owycx6da.btwxx1t3.b5q2rw42.lq239pai.mysgfdmx.hddg9phg';
/**
* Waits for an HTML element to appear
* @param {string} selector the selector for the element to wait on
* @returns {Promise<Element>} A promise for the element, that resolves once it appears.
* @copyright https://stackoverflow.com/a/61511955
*/
function waitForElm(selector) {
return new Promise(resolve => {
if (document.querySelector(selector)) {
return resolve(document.querySelector(selector));
}
const observer = new MutationObserver(mutations => {
if (document.querySelector(selector)) {
resolve(document.querySelector(selector));
observer.disconnect();
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});
});
}
/**
* Creates a toggle sidebar button.
* @param {Element} sidebarButtonElem
*/
function setupToggleButton(sidebarButtonElem) {
if (sidebarButtonElem.querySelector(`[aria-label="${ARIA_LABEL}"]`)) {
return;
}
const toggleButton = document.createElement('div');
toggleButton.setAttribute('role', 'button')
toggleButton.setAttribute('tabIndex', '0')
toggleButton.setAttribute('aria-label', ARIA_LABEL)
toggleButton.classList.add(...'oajrlxb2 g5ia77u1 mtkw9kbi tlpljxtp qensuy8j ppp5ayq2 goun2846 ccm00jje s44p3ltw mk2mc5f4 nhd2j8a9 mg4g778l pfnyh3mw p7hjln8o kvgmc6g5 cxmmr5t8 oygrvhab hcukyx3x tgvbjcpo hpfvmrgz i1ao9s8h esuyzwwr f1sip0of du4w35lb btwxx1t3 abiwlrkh p8dawk7l lzcic4wl thwo4zme tv7at329 rq0escxv j83agx80 bp9cbjyn taijpn5t jb3vyjys rz4wbd8a qt6c0cv9 a8nywdso l9j0dhe7 s45kfl79 emlxlaya bkmhp75w spb7xbtv rt8b4zig n8ej3o3l agehan2d sk4xxmp2'.split(' '));
toggleButton.addEventListener('click', () => {
/**
* @param {HTMLElement} e
*/
function toggleElement(e) {
const path = document.querySelector(`[aria-label="${ARIA_LABEL}"] > svg > path`);
if (e.classList.contains('ezfq3ill')) {
e.style.width = '74.71px';
e.classList.remove('ezfq3ill');
path.setAttribute('d', EXPAND_SIDEBAR);
} else {
e.style.width = null;
e.classList.add('ezfq3ill');
path.setAttribute('d', HIDE_SIDEBAR);
}
}
const sidebarElement = document.querySelector(SIDEBAR_SELECTOR);
if (sidebarElement instanceof HTMLElement) {
toggleElement(sidebarElement)
}
});
const toggleButtonIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
toggleButtonIcon.setAttribute('viewBox', '0 0 1024 1024');
toggleButtonIcon.setAttribute('height', '20');
toggleButtonIcon.setAttribute('width', '20');
toggleButtonIcon.setAttribute('fill', 'currentColor');
toggleButtonIcon.classList.add(...'a8c37x1j ms05siws l3qrxjdp b7h9ocf4 rs22bh7c'.split(' '))
const toggleButtonIconIcon = document.createElementNS('http://www.w3.org/2000/svg', 'path');
toggleButtonIconIcon.setAttribute('d', HIDE_SIDEBAR);
toggleButton.appendChild(toggleButtonIcon);
toggleButtonIcon.appendChild(toggleButtonIconIcon);
sidebarButtonElem.prepend(toggleButton);
sidebarButtonElem.classList.remove('i1fnvgqd');
}
waitForElm(CHAT_NAME_SELECTOR).then((sidebarButtonElem) => {
setupToggleButton(sidebarButtonElem);
});
waitForElm(SIDEBAR_SELECTOR).then((sidebarElem) => {
const observer = new MutationObserver((_) => {
waitForElm(CHAT_NAME_SELECTOR).then((sidebarButtonElem) => {
setupToggleButton(sidebarButtonElem);
});
});
observer.observe(sidebarElem, {
childList: true,
subtree: true,
});
});
})();
// SPDX-License-Identifier: 0BSD
// @ts-check
/**
* Left sidebar toggler for Facebook Messenger.
* Made for [Ferdium](https://github.com/ferdium)
*
* Graphics taken from https://www.veryicon.com/icons/miscellaneous/godserver/
* Inspired by James Swandale's https://greasyfork.org/en/scripts/14192-toggle-messenger-sidebar
*/
const ARIA_LABEL = 'Toggle sidebar';
const EXPAND_SIDEBAR = 'M880 224H144c-26.5 0-48-21.5-48-48s21.5-48 48-48h736c26.5 0 48 21.5 48 48s-21.5 48-48 48zM144 576h416c26.5 0 48 21.5 48 48s-21.5 48-48 48H144c-26.5 0-48-21.5-48-48s21.5-48 48-48zM144 352h416c26.5 0 48 21.5 48 48s-21.5 48-48 48H144c-26.5 0-48-21.5-48-48s21.5-48 48-48zM880 896H144c-26.5 0-48-21.5-48-48s21.5-48 48-48h736c26.5 0 48 21.5 48 48s-21.5 48-48 48zM917.4 489.4L790.6 362.6c-20.2-20.2-54.6-5.9-54.6 22.6v253.5c0 28.5 34.5 42.8 54.6 22.6l126.7-126.7c12.6-12.5 12.6-32.7 0.1-45.2z';
const HIDE_SIDEBAR = 'M880 224H144c-26.5 0-48-21.5-48-48s21.5-48 48-48h736c26.5 0 48 21.5 48 48s-21.5 48-48 48zM880 448H464c-26.5 0-48-21.5-48-48s21.5-48 48-48h416c26.5 0 48 21.5 48 48s-21.5 48-48 48zM880 672H464c-26.5 0-48-21.5-48-48s21.5-48 48-48h416c26.5 0 48 21.5 48 48s-21.5 48-48 48zM880 896H144c-26.5 0-48-21.5-48-48s21.5-48 48-48h736c26.5 0 48 21.5 48 48s-21.5 48-48 48zM106.6 534.6l126.7 126.7c20.2 20.2 54.6 5.9 54.6-22.6V385.3c0-28.5-34.5-42.8-54.6-22.6L106.6 489.4c-12.5 12.5-12.5 32.7 0 45.2z';
const SIDEBAR_SELECTOR = 'div[role="navigation"].rq0escxv.l9j0dhe7.j83agx80.cbu4d94t.d2edcug0.hpfvmrgz.pfnyh3mw.dp1hu0rb.rek2kq2y.o36gj0jk.tkr6xdv7';
const CHAT_NAME_SELECTOR = 'div.rq0escxv.l9j0dhe7.du4w35lb.j83agx80.rj1gh0hx.buofh1pr.g5gj957u.hpfvmrgz.i1fnvgqd.bp9cbjyn.owycx6da.btwxx1t3.b5q2rw42.lq239pai.mysgfdmx.hddg9phg';
/**
* Waits for an HTML element to appear
* @param {string} selector the selector for the element to wait on
* @returns {Promise<Element>} A promise for the element, that resolves once it appears.
* @copyright https://stackoverflow.com/a/61511955
*/
function waitForElm(selector) {
return new Promise(resolve => {
if (document.querySelector(selector)) {
return resolve(document.querySelector(selector));
}
const observer = new MutationObserver(mutations => {
if (document.querySelector(selector)) {
resolve(document.querySelector(selector));
observer.disconnect();
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});
});
}
/**
* Creates a toggle sidebar button.
* @param {Element} sidebarButtonElem
*/
function setupToggleButton(sidebarButtonElem) {
if (sidebarButtonElem.querySelector(`[aria-label="${ARIA_LABEL}"]`)) {
return;
}
const toggleButton = document.createElement('div');
toggleButton.setAttribute('role', 'button')
toggleButton.setAttribute('tabIndex', '0')
toggleButton.setAttribute('aria-label', ARIA_LABEL)
toggleButton.classList.add(...'oajrlxb2 g5ia77u1 mtkw9kbi tlpljxtp qensuy8j ppp5ayq2 goun2846 ccm00jje s44p3ltw mk2mc5f4 nhd2j8a9 mg4g778l pfnyh3mw p7hjln8o kvgmc6g5 cxmmr5t8 oygrvhab hcukyx3x tgvbjcpo hpfvmrgz i1ao9s8h esuyzwwr f1sip0of du4w35lb btwxx1t3 abiwlrkh p8dawk7l lzcic4wl thwo4zme tv7at329 rq0escxv j83agx80 bp9cbjyn taijpn5t jb3vyjys rz4wbd8a qt6c0cv9 a8nywdso l9j0dhe7 s45kfl79 emlxlaya bkmhp75w spb7xbtv rt8b4zig n8ej3o3l agehan2d sk4xxmp2'.split(' '));
toggleButton.addEventListener('click', () => {
/**
* @param {HTMLElement} e
*/
function toggleElement(e) {
const path = document.querySelector(`[aria-label="${ARIA_LABEL}"] > svg > path`);
if (e.classList.contains('ezfq3ill')) {
e.style.width = '74.71px';
e.classList.remove('ezfq3ill');
path.setAttribute('d', EXPAND_SIDEBAR);
} else {
e.style.width = null;
e.classList.add('ezfq3ill');
path.setAttribute('d', HIDE_SIDEBAR);
}
}
const sidebarElement = document.querySelector(SIDEBAR_SELECTOR);
if (sidebarElement instanceof HTMLElement) {
toggleElement(sidebarElement)
}
});
const toggleButtonIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
toggleButtonIcon.setAttribute('viewBox', '0 0 1024 1024');
toggleButtonIcon.setAttribute('height', '20');
toggleButtonIcon.setAttribute('width', '20');
toggleButtonIcon.setAttribute('fill', 'currentColor');
toggleButtonIcon.classList.add(...'a8c37x1j ms05siws l3qrxjdp b7h9ocf4 rs22bh7c'.split(' '))
const toggleButtonIconIcon = document.createElementNS('http://www.w3.org/2000/svg', 'path');
toggleButtonIconIcon.setAttribute('d', HIDE_SIDEBAR);
toggleButton.appendChild(toggleButtonIcon);
toggleButtonIcon.appendChild(toggleButtonIconIcon);
sidebarButtonElem.prepend(toggleButton);
sidebarButtonElem.classList.remove('i1fnvgqd');
}
/**
*
* @param {object} _
* @param {*} __
*/
module.exports = (_, __) => {
waitForElm(CHAT_NAME_SELECTOR).then((sidebarButtonElem) => {
setupToggleButton(sidebarButtonElem);
});
waitForElm(SIDEBAR_SELECTOR).then((sidebarElem) => {
const observer = new MutationObserver((_) => {
waitForElm(CHAT_NAME_SELECTOR).then((sidebarButtonElem) => {
setupToggleButton(sidebarButtonElem);
});
});
observer.observe(sidebarElem, {
childList: true,
subtree: true,
});
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment