Happy Pride Month! - Also, GDS v3 is live! 💅

Bookmarklets

These helper tools are to be used as bookmarks in your browser. The link is what you want to bookmark. The code underneath is the abbreviated documentation, indicating what the bookmarklet does. For each actual link, the documented code is wrapped inside additional code, to ensure the functionality is executed for the main window and every iframe on a page.

Some of the bookmarklets shown below change behaviour depending on how often you apply them. E.g., clicking a bookmarklet once modifies the page, clicking it again restores its original form. Read the description to find out how they work.

Trigger debug info

Turns George Design System debug information on.

Trigger GDS debug info

jsif (typeof window['__gdsDebugInfo'] === 'function') {
    window.__gdsDebugInfo();
}

Toggle all styles

Removes/restores all references to stylesheets and all inline styles. (Also adds/removes some smart defaults, i.e. adds table borders, highlights visually hidden text, and makes all inline SVGs 16x16 pixels in size.)

Toggle all styles

jsconst DEFAULTS = 'data-nocss';
let smartDefaults = document.querySelector(`style[${DEFAULTS}]`);
const elements = document.querySelectorAll('link[rel=stylesheet], style, [style]');
Array.from(elements).forEach((node) => {
    const actualAttributeName = ['link', 'style'].includes(node.tagName.toLowerCase())
        ? 'media'
        : 'style';
    const backupAttributeName = `${DEFAULTS}-${actualAttributeName}`;
    if (smartDefaults) {
        const backup = node.getAttribute(backupAttributeName);
        if (backup) {
            node.setAttribute(actualAttributeName, backup);
        } else {
            node.removeAttribute(actualAttributeName);
        }
        node.removeAttribute(backupAttributeName);
    } else {
        const actual = node.getAttribute(actualAttributeName);
        if (actual) {
            node.setAttribute(backupAttributeName, actual);
        }
        node.setAttribute(actualAttributeName, 'inactive');
    }
});
if (smartDefaults) {
    smartDefaults.parentNode.removeChild(smartDefaults);
} else {
    smartDefaults = document.createElement('style');
    smartDefaults.setAttribute(DEFAULTS, elements.length);
    smartDefaults.appendChild(
        document.createTextNode(`
            :root{--sr:#800080;--no-sr:#80008040}
            .g-avatar img,svg{width:16px!important;height:16px!important}
            svg{fill:currentColor}
            table{border:1px outset ButtonFace}
            th,td{padding:4px;border:1px inset ButtonFace}
            .visually-hidden,.sr-only{color:var(--sr)}
            [aria-label]:where(a[href],button,fieldset legend,figure figcaption,input,meter,progress,select,svg,textarea),[aria-hidden="true"]{color:var(--no-sr)}
            [aria-label]{border:1px solid var(--sr);border-radius:4px}
            [aria-label]::before{content:attr(aria-label);background-color:var(--sr);color:#fff}
            [aria-label]:not(a[href],button,fieldset legend,figure figcaption,input,meter,progress,select,svg,textarea,article,aside,audio,details,dialog,dl,footer,form,header,main,nav,ol,section,search,table,ul,video)::before{text-decoration:line-through}
        `),
    );
    document.querySelector('head').appendChild(smartDefaults);
}

Toggle visually hidden text

Shows/hides visually hidden text, i.e. text for assistive technology such as screen readers.

Toggle hidden text

jsconst title = 'Show visually hidden text';
const remove = document.querySelector('style[data-title="$1"]'.replace('$1', title));
if (remove) {
    document.querySelector('head').removeChild(remove);
} else {
    const add = document.createElement('style');
    add.setAttribute('data-title', title);
    const overrides = [
        'position:absolute',
        'top:auto',
        'left:auto',
        'width:auto',
        'height:auto',
        'margin:0',
        'padding:1px',
        'outline-style:dashed',
        'outline-width:1px',
        'background-color:rgba(255,51,153,.05)',
        'color:rgba(255,51,153,.7)',
        'clip:auto',
        '-webkit-clip-path:none',
        'clip-path:none',
    ];
    add.appendChild(
        document.createTextNode(
            `.g-bootstrap.g-bs4 .sr-only{${overrides.concat(['']).join('!important;')}}`,
        ),
    );
    document.querySelector('head').appendChild(add);
}

Toggle enlarged touch targets

Shows/hides touch targets, i.e. adds an outline to links and buttons that have a touch target area larger than the actual element. On focus, the outline style changes, so you can pinpoint which outline belongs to which element.

HINT Might result in false positives on complex elements.

Toggle touch targets

jsconst title = 'Show enlarged touch targets';
const remove = document.querySelector('style[data-title="$1"]'.replace('$1', title));
if (remove) {
    document.querySelector('head').removeChild(remove);
} else {
    const add = document.createElement('style');
    add.setAttribute('data-title', title);
    const makeStyles = function (styles, state) {
        return `.g-bootstrap.g-bs4 :where(a, button, .g-tooltip-touch-target)${state || ''}::before{${styles
            .concat([''])
            .join('!important;')}}`;
    };
    add.appendChild(
        document.createTextNode(
            `${makeStyles(['outline:1px dashed hotpink', 'outline-offset:-1px'])}${makeStyles(
                ['outline-style:dotted'],
                ':focus',
            )}`,
        ),
    );
    document.querySelector('head').appendChild(add);
}

Toggle mouse cursor

Shows/hides the mouse cursor in the current browser window. Use it to prevent cheating when testing keyboard accessibility.

Toggle mouse cursor

jsconst title = 'Hide mouse cursor';
const remove = document.querySelector('style[data-title="$1"]'.replace('$1', title));
if (remove) {
    document.querySelector('head').removeChild(remove);
} else {
    const add = document.createElement('style');
    add.setAttribute('data-title', title);
    add.appendChild(document.createTextNode('*,*::before,*::after{cursor:none!important}'));
    document.querySelector('head').appendChild(add);
}

Toggle PFM badges in transaction list

This is a bookmarklet to show/hide the Finance Manager (PFM) badges on George pages that contain a Transaction list.

Toggle PFM Badges

jsconst title = 'Toggle PFM Badges';
const remove = document.querySelector('style[data-title="$1"]'.replace('$1', title));
if (remove) {
    document.querySelector('head').removeChild(remove);
} else {
    const add = document.createElement('style');
    add.setAttribute('data-title', title);
    add.appendChild(document.createTextNode(`[data-cy="transactions-region"] td div:has(.g-badge){display:none!important}`));
    document.querySelector('head').appendChild(add);
}