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.
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.)
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.
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.
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.
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.
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);
}