NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript==
// @name BitBoxes
// @namespace https://scriptspry.com/
// @version 0.1
// @license MIT
// @description Checkboxes for bitbucket cause we need them! ☐☑☒
// @author You
// @match https://bitbucket.org/*
// @grant none
// ==/UserScript==
((() => {
/**
* Gets an array of the matching text nodes contained by the specified element.
* @param {!Element} elem
* The DOM element which will be traversed.
* @param {function(!Node,!Element):boolean} opt_fnFilter
* Optional function that if a true-ish value is returned will cause the
* text node in question to be added to the array to be returned from
* getTextNodesIn(). The first argument passed will be the text node in
* question while the second will be the parent of the text node.
* @return {!Array.<!--Node-->}
* Array of the matching text nodes contained by the specified element.
*
* // Source & Thanks to: http://cwestblog.com/2014/03/14/javascript-getting-all-text-nodes/
*
**/
function getTextNodesIn(elem, opt_fnFilter) {
let textNodes = [];
if (elem) {
for (let nodes = elem.childNodes, i = nodes.length; i--;) {
const node = nodes[i];
const nodeType = node.nodeType;
if (nodeType == 3) {
if (!opt_fnFilter || opt_fnFilter(node, elem)) {
textNodes.push(node);
}
}
else if (nodeType == 1 || nodeType == 9 || nodeType == 11) {
textNodes = textNodes.concat(getTextNodesIn(node, opt_fnFilter));
}
}
}
return textNodes;
}
const replacements = new Map([
[new RegExp('\\[_\\]', 'igm'), '☐'],
[new RegExp('\\[x\\]', 'igm'), '☒'],
[new RegExp('\\[-\\]', 'igm'), '☑'],
[new RegExp('\\[v\\]', 'igm'), '☑'],
[new RegExp('\\[\\*\\]', 'igm'), '☑']
]);
const regexes = Array.from(replacements.keys());
const hasSymbol = node => regexes.find(s => node.textContent.match(s));
const boxify = () => {
document.querySelectorAll('li').forEach(li => {
getTextNodesIn(li, hasSymbol).forEach(textNode => {
for (const [symbol, replacement] of replacements)
textNode.textContent = textNode.textContent.replace(symbol, replacement);
});
});
};
if (jQuery !== undefined)
jQuery(boxify);
else
window.addEventListener('load', 'DOMContentLoaded', boxify, false);
}))();