Last active
March 23, 2020 22:55
-
-
Save majido/2e8ad5623edb0f98b8a105ccdb9b6361 to your computer and use it in GitHub Desktop.
Gerrit CL to Markdown
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Small bookmarklet to pring CLs from gerrit in Markdown format. | |
// Used and tested on https://chromium-review.googlesource.com | |
// To make this a bookmarklet put the content below into a | |
// bookmark's link field. | |
javascript:(function() { | |
const cls = getCLs(); | |
const desc = Array.prototype.map.call(cls, format); | |
console.log(desc.join('\n')); | |
function format(a) { | |
return `* ${a.textContent.trim()} [CL](${a.href})`; | |
} | |
function getCLs() { | |
if (true || document.body.querySelector('gr-app-p2')) { | |
/* v2 uses shadow DOM so we cannot use regular shodow piercing selector*/ | |
const items = querySelectorAllDeep('gr-change-list-item', document.body ); | |
let cls = []; | |
items.forEach((i) => { | |
cls.push(i.shadowRoot.querySelector('.cell.subject a')) | |
}); | |
return cls; | |
} else { | |
/* Use a simple selector for v1*/ | |
return document.querySelectorAll("gr-change-list-item td.subject a.gr-change-list-item"); | |
} | |
} | |
/* Using deep selector to help with shadow dom https://github.com/Georgegriff/query-selector-shadow-dom/blob/master/src/querySelectorDeep.js */ | |
function querySelectorAllDeep(selector, root = document) { | |
return _querySelectorDeep(selector, true, root); | |
} | |
function querySelectorDeep(selector, root = document) { | |
return _querySelectorDeep(selector, false, root); | |
} | |
function _querySelectorDeep(selector, findMany, root) { | |
let lightElement = root.querySelector(selector); | |
if (document.head.createShadowRoot || document.head.attachShadow) { | |
if (!findMany && lightElement) { | |
return lightElement; | |
} | |
const selectionsToMake = splitByCharacterUnlessQuoted(selector, ','); | |
return selectionsToMake.reduce((acc, minimalSelector) => { | |
if (!findMany && acc) { | |
return acc; | |
} | |
const splitSelector = splitByCharacterUnlessQuoted(minimalSelector | |
.replace(/^\s+/g, '') | |
.replace(/\s*([>+~]+)\s*/g, '$1'), ' ') | |
.filter((entry) => !!entry); | |
const possibleElementsIndex = splitSelector.length - 1; | |
const possibleElements = collectAllElementsDeep(splitSelector[possibleElementsIndex], root); | |
const findElements = findMatchingElement(splitSelector, possibleElementsIndex, root); | |
if (findMany) { | |
acc = acc.concat(possibleElements.filter(findElements)); | |
return acc; | |
} else { | |
acc = possibleElements.find(findElements); | |
return acc || null; | |
} | |
}, findMany ? [] : null); | |
} else { | |
if (!findMany) { | |
return lightElement; | |
} else { | |
return root.querySelectorAll(selector); | |
} | |
} | |
} | |
function findMatchingElement(splitSelector, possibleElementsIndex, root) { | |
return (element) => { | |
let position = possibleElementsIndex; | |
let parent = element; | |
let foundElement = false; | |
while (parent && !isDocumentNode(parent)) { | |
const foundMatch = parent.matches(splitSelector[position]); | |
if (foundMatch && position === 0) { | |
foundElement = true; | |
break; | |
} | |
if (foundMatch) { | |
position--; | |
} | |
parent = findParentOrHost(parent, root); | |
} | |
return foundElement; | |
}; | |
} | |
function splitByCharacterUnlessQuoted(selector, character) { | |
return selector.match(/\\?.|^$/g).reduce((p, c) => { | |
if (c === '"' && !p.sQuote) { | |
p.quote ^= 1; | |
p.a[p.a.length - 1] += c; | |
} else if (c === '\'' && !p.quote) { | |
p.sQuote ^= 1; | |
p.a[p.a.length - 1] += c; | |
} else if (!p.quote && !p.sQuote && c === character) { | |
p.a.push(''); | |
} else { | |
p.a[p.a.length - 1] += c; | |
} | |
return p; | |
}, { a: [''] }).a; | |
} | |
function isDocumentNode(node) { | |
return node.nodeType === Node.DOCUMENT_FRAGMENT_NODE || node.nodeType === Node.DOCUMENT_NODE; | |
} | |
function findParentOrHost(element, root) { | |
const parentNode = element.parentNode; | |
return (parentNode && parentNode.host && parentNode.nodeType === 11) ? parentNode.host : parentNode === root ? null : parentNode; | |
} | |
function collectAllElementsDeep(selector = null, root) { | |
const allElements = []; | |
const findAllElements = function(nodes) { | |
for (let i = 0, el; el = nodes[i]; ++i) { | |
allElements.push(el); | |
if (el.shadowRoot) { | |
findAllElements(el.shadowRoot.querySelectorAll('*')); | |
} | |
} | |
}; | |
if(root.shadowRoot) { | |
findAllElements(root.shadowRoot.querySelectorAll('*')); | |
} | |
findAllElements(root.querySelectorAll('*')); | |
return selector ? allElements.filter(el => el.matches(selector)) : allElements; | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment