Skip to content

Instantly share code, notes, and snippets.

@zhantongz
Created July 10, 2026 04:15
Show Gist options
  • Select an option

  • Save zhantongz/1086d2f483959dca920ff8f083c49dae to your computer and use it in GitHub Desktop.

Select an option

Save zhantongz/1086d2f483959dca920ff8f083c49dae to your computer and use it in GitHub Desktop.
CanLII monkey scripts
// ==UserScript==
// @name My CanLII scripts
// @namespace https://github.com/violentmonkey/scripts
// @version 2.2
// @description Some useful scripts for CanLII
// @author You
// @match https://www.canlii.org/en/*
// @match https://www.canlii.org/fr/*
// @grant GM_setClipboard
// @run-at document-idle
// ==/UserScript==
(function () {
'use strict';
function getCleanUrl() {
const url = new URL(window.location.href);
url.search = '';
url.hash = '';
return url.toString();
}
function getCitationText() {
const title = document.title || '';
let citation = title.split('|')[0].trim();
if (citation.endsWith('(CanLII)')) {
citation = citation.slice(0, -'(CanLII)'.length).trim();
}
return citation;
}
function flash(button, message, revertTo) {
button.textContent = message;
setTimeout(() => {
button.textContent = revertTo;
}, 1200);
}
function copyPlainText(text, button, label) {
navigator.clipboard.writeText(text).then(
() => flash(button, '✓', label),
() => {
if (typeof GM_setClipboard === 'function') {
GM_setClipboard(text, 'text');
flash(button, '✓', label);
} else {
flash(button, '✗', label);
}
}
);
}
function copyRichLink(url, text, button, label) {
const html = `<a href="${url}">${text}</a>`;
if (navigator.clipboard && window.ClipboardItem) {
const item = new ClipboardItem({
'text/html': new Blob([html], { type: 'text/html' }),
'text/plain': new Blob([text], { type: 'text/plain' }),
});
navigator.clipboard.write([item]).then(
() => flash(button, '✓', label),
() => fallbackCopy()
);
} else {
fallbackCopy();
}
function fallbackCopy() {
if (typeof GM_setClipboard === 'function') {
GM_setClipboard(html, 'html');
flash(button, '✓', label);
} else {
flash(button, '✗', label);
}
}
}
function makeButton(id, label, bottomOffset, rightOffset, onClick) {
const button = document.createElement('button');
button.id = id;
button.textContent = label;
button.style.position = 'fixed';
button.style.bottom = bottomOffset;
button.style.right = rightOffset;
button.style.zIndex = '99';
button.style.padding = '8px 12px';
button.style.fontSize = '15px';
button.style.backgroundColor = '#f9f5e6';
button.style.color = '#fff';
button.style.border = 'none';
button.style.borderRadius = '8px';
button.style.cursor = 'pointer';
button.style.boxShadow = '0 2px 2px rgba(0,0,0,0.3)';
button.style.opacity = '0.7';
button.addEventListener('mouseenter', () => (button.style.opacity = '1'));
button.addEventListener('mouseleave', () => (button.style.opacity = '0.7'));
button.addEventListener('click', onClick);
return button;
}
function createButtons() {
const linkButton = makeButton('copyCleanLink', '🔗', '5rem', 'calc(var(--gar-chat-width, 0px) + 2.5rem)', () =>
copyPlainText(getCleanUrl(), linkButton, '🔗')
);
const citeButton = makeButton('copyCitationLink', '📋', '5rem', 'calc(var(--gar-chat-width, 0px) + 5rem)', () =>
copyRichLink(getCleanUrl(), getCitationText(), citeButton, '📋')
);
document.body.appendChild(linkButton);
document.body.appendChild(citeButton);
}
function getPseudoMcGillText() {
const parts = (document.title || '').split('|');
const firstPart = (parts[0] || '').trim();
const caseStyle = (parts[1] || '').trim().replace(/\./g, '');
return `<i>${caseStyle}</i>, ${firstPart}`;
}
function insertPseudoMcGillRow() {
const container = document.getElementById('metas-container');
if (!container) return;
// Avoid inserting twice if the script re-runs
if (container.querySelector('.pseudo-mcgill-row')) return;
const citationLabel = container.querySelector('.documentMeta-citation');
const citationRow = citationLabel ? citationLabel.closest('.row') : null;
if (!citationRow) return;
const pseudoMcGill = getPseudoMcGillText();
const rowHtml = `
<div class="row py-1 pseudo-mcgill-row">
<div class="col-3">Pseudo-McGill:</div>
<div class="col">${pseudoMcGill}</div>
</div>
`;
citationRow.insertAdjacentHTML('afterend', rowHtml);
}
function init() {
createButtons();
insertPseudoMcGillRow();
}
if (document.body) {
init();
} else {
window.addEventListener('DOMContentLoaded', init);
}
})();
@zhantongz

Copy link
Copy Markdown
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment