NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript==
// @name Rebrickable Dark Mode
// @namespace https://fairburn.dev/
// @version 1.3.2
// @description Enable dark mode on rebrickable.com regardless of your account plan.
// @author Garrett Fairburn
// @license Apache-2.0
// @match https://rebrickable.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=rebrickable.com
// @run-at document-start
// ==/UserScript==
(function () {
'use strict';
// Call callback on the child element of parent that passes predicate.
// If no children pass predicate, attach a MutationObserver to parent
// that waits until an added child passes predicate and call callback
// on it.
function callOnceChildExists(parent, predicate, callback) {
// First check if the target child element already exists.
for (const child of parent.childNodes.values()) {
if (child.nodeType === Node.ELEMENT_NODE && predicate(child)) {
// If it does, call callback on it and return early.
callback(child);
return;
}
}
// If the target child element doesn't already exist, attach a
// MutationObserver that waits for it to be added.
new MutationObserver((mutationList, observer) => {
for (const mutation of mutationList) {
for (const child of mutation.addedNodes) {
if (child.nodeType === Node.ELEMENT_NODE && predicate(child)) {
callback(child);
// Observer has served its purpose, so disconnect it.
observer.disconnect();
return;
}
}
}
}).observe(parent, {
// Only interested in modifications to immediate child list,
// not attributes or sub-children.
childList: true,
});
}
// Body element may or may not already exist at this point,
// so use callOnceChildExists.
callOnceChildExists(
// Target element is the body element of the root HTML element.
document.documentElement,
(child) => child.tagName === 'BODY',
// Callback function to enable dark mode on a given body element.
(body) => {
// Apply dark mode CSS to body.
body.classList.add('dark-mode');
// Wrapper element inside body may or may not already exist at this
// point, so use callOnceChildExists.
callOnceChildExists(
// Target element is the child of body with id "wrapper".
body,
(child) => child.id === 'wrapper',
// Callback function to update state of dark mode toggle switch for
// consistency if it exists.
(wrapper) => {
const checkbox = wrapper.querySelector('.js-toggle-dark-mode input');
if (checkbox !== null) {
checkbox.checked = true;
}
},
);
},
);
})();