Last active
June 19, 2020 01:50
-
-
Save w4-hojin/7b46d33472a65cfe3510059ab25bf1da to your computer and use it in GitHub Desktop.
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
// ==UserScript== | |
// @name Gerrit_Helper | |
// @namespace https://skelterlabs.com/ | |
// @homepage https://gist.github.com/w4-hojin/7b46d33472a65cfe3510059ab25bf1da | |
// @version 0.22 | |
// @description Gerrit Helper. | |
// @author hojin <hojin@wisefour.com> | |
// @require https://code.jquery.com/jquery-3.4.1.min.js | |
// @require https://cdn.jsdelivr.net/ally.js/1.4.1/ally.min.js | |
// @require https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js | |
// @downLoadUrl https://gist.githubusercontent.com/w4-hojin/7b46d33472a65cfe3510059ab25bf1da/raw/Gerrit_Helper.user.js | |
// @updateUrl https://gist.githubusercontent.com/w4-hojin/7b46d33472a65cfe3510059ab25bf1da/raw/Gerrit_Helper.user.js | |
// @match https://gerrit.wisefour.com/* | |
// @match https://youtrack.corp.skelterlabs.com/* | |
// @match https://skelterlabs.atlassian.net/* | |
// @match https://cs.corp.skelterlabs.com/* | |
// @grant GM_xmlhttpRequest | |
// @grant GM_setClipboard | |
// @grant GM_openInTab | |
// @connect localhost | |
// ==/UserScript== | |
/* | |
릴리즈 노트 | |
0.22 | |
Open in CS 버튼 추가 | |
**/ | |
(function($) { | |
'use strict'; | |
const debug = console.log; | |
function setupWatcher(parent, selector, handler, options = {}) { | |
if (!parent || parent.nodeName === '#comment' || parent.nodeName === '#text' || parent.nodeName === 'STYLE' || parent.nodeName==='SCRIPT') { | |
return | |
} | |
debug(`Watching.. (${selector})`, parent, options); | |
const handled = [] | |
const handle = (index, element) => { | |
debug('Cheking need to handle...', selector, element) | |
if ($.inArray(element, handled) !== -1) { | |
return | |
} | |
if (options.contains) { | |
const text = $(element).text() | |
if (options.contains instanceof RegExp) { | |
if (!options.contains.test(text)) { | |
return | |
} | |
} else { | |
if (!text.includes(options.contains)) { | |
return | |
} | |
} | |
} | |
debug('Handle!', selector, element) | |
handled.push(element) | |
handler(index, element) | |
} | |
$(selector).each(handle) | |
// ally.observe.shadowMutations({ | |
// context: parent, | |
// callback: function(mutations) { | |
// const addedNodes = _.flatMap(mutations, 'addedNodes') | |
// addedNodes.forEach(addedNode => { | |
// addedNode.forEach(node => { | |
// //console.log('shadowMutations', node) | |
// if (!node.parentNode || !node.shadowRoot) return | |
// //for (const child of node.shadowRoot.children) console.log(child) | |
// //for (const child of node.shadowRoot.children) setupWatcher(child, selector, handler, options) | |
// //console.log(node.parentNode) | |
// //console.log(node) | |
// setupWatcher(node.shadowRoot, selector, handler, options) | |
// }) | |
// }) | |
// //console.log(mutations) | |
// //console.log(_.map(nodes, 'localName')) | |
// //_.forEach(nodes, (node) => setupWatcher(node, selector, handler, options)) | |
// }, | |
// config: { | |
// childList: true, | |
// subtree: true, | |
// }, | |
// }) | |
const insertedNodes = [] | |
const observer = new MutationObserver((mutations) => { | |
mutations.forEach((mutation) => { | |
const tagets = $(mutation.target).find($(parent).find(selector)) | |
tagets.each(handle) | |
//console.log(mutation) | |
mutation.addedNodes.forEach(node => { | |
if (node.shadowRoot) { | |
//console.log(_.map(node.shadowRoot.children, 'id')) | |
observer.observe(node.shadowRoot, { subtree: true, childList: true }) | |
//setupWatcher(node.shadowRoot, selector, handler, options) | |
} | |
if (node.nodeName === '#comment' || node.nodeName === '#text' || node.nodeName === 'STYLE' || node.id ==='diffHost') { | |
return | |
} | |
observer.observe(node, { subtree: true, childList: true }) | |
const nodes = $(node).find($(parent).find(selector)) | |
nodes.each(handle) | |
}) | |
}) | |
}) | |
observer.observe(parent, { subtree: true, childList: true }) | |
_.forEach(parent.children, child => setupWatcher(child, selector, handler, options)) | |
// const interval = setInterval(() => { | |
// if (parent.shadowRoot) { | |
// clearInterval(interval) | |
// // observer.observe(parent.shadowRoot, { subtree: true, childList: true }) | |
// setupWatcher(parent.shadowRoot, selector, handler, options) | |
// //_.forEach(parent.shadowRoot.children, child => setupWatcher(child, selector, handler, options)) | |
// } | |
// }, 3000) | |
} | |
function setupWatcher2(parent, selector, handler, options = {}) { | |
debug(parent, selector, handler, options) | |
const installed = [] | |
const handled = [] | |
const handle = (index, element) => { | |
if ($.inArray(element, handled) !== -1) { | |
return | |
} | |
debug('Cheking need to handle...', selector, element) | |
if (options.contains) { | |
const text = $(element).text() | |
if (options.contains instanceof RegExp) { | |
if (!options.contains.test(text)) { | |
return | |
} | |
} else { | |
if (!text.includes(options.contains)) { | |
return | |
} | |
} | |
} | |
debug('Handle!', selector, element) | |
handled.push(element) | |
handler(index, element) | |
} | |
const install = (parent) => { | |
if ($.inArray(parent, installed) !== -1) { | |
return | |
} | |
installed.push(parent) | |
const tryHandle = () => { | |
if ($(parent).is(selector)) { | |
handle(null, parent) | |
} | |
$(parent).find(selector).each(handle) | |
for (let el of [parent, ...parent.getElementsByTagName('*')]) { | |
if (el.shadowRoot) { | |
_.forEach(el.shadowRoot.children, element => { | |
install(element) | |
}) | |
} | |
} | |
} | |
tryHandle() | |
setInterval(() => { | |
tryHandle() | |
}, 5000) | |
} | |
install (parent, selector, handler, options) | |
} | |
function requestOpenEditor(filePath) { | |
console.log(`Opening ${filePath}...`) | |
// GM_xmlhttpRequest({ | |
// method: 'GET', | |
// url: 'http://localhost:63342/api/file/'+ filePath, | |
// onload: function(response) { | |
// console.debug(response) | |
// } | |
// }) | |
GM_xmlhttpRequest({ | |
method: 'GET', | |
url: 'http://localhost:8091?'+$.param({message: filePath}), | |
onload: function(response) { | |
console.debug(response) | |
} | |
}) | |
GM_xmlhttpRequest({ | |
method: 'GET', | |
url: 'http://localhost:8092?'+$.param({message: filePath}), | |
onload: function(response) { | |
console.debug(response) | |
} | |
}) | |
} | |
const issuRegex = /\(#?(\w+-\d+)\)/g | |
const changeIdRegex = /Change-Id: (I\w+)/g | |
// To Issue Link | |
if (location.href.startsWith('https://gerrit.wisefour.com/')) { | |
setupWatcher2(document.body.firstElementChild, '.headerSubject', (index, element) => { | |
const commitMsg = $(element).text() | |
issuRegex.lastIndex=0 | |
const test = issuRegex.exec(commitMsg) | |
const issueNum = test[1] | |
const youtrackLink = `https://youtrack.corp.skelterlabs.com/youtrack/issue/${issueNum}` | |
const jiraLink = `https://skelterlabs.atlassian.net/browse/${issueNum}` | |
// <span >Go to Youtrack <a href="${youtrackLink}" target="_blank">${issueNum}</a></span> | |
$(element).after($(` | |
<div style="margin-left: 12px;"> | |
<span><a href="${jiraLink}" target="_blank">TO JIRA(${issueNum})</a></span> | |
</div> | |
`)) | |
}, {contains: issuRegex}) | |
} | |
// Topic clip copy | |
if (location.href.startsWith('https://gerrit.wisefour.com/')) { | |
setupWatcher2(document, 'gr-linked-chip', (index, element) => { | |
$(element).after( | |
$(`<button>Copy</button>`) | |
.click((event)=> { | |
GM_setClipboard(element.shadowRoot.querySelector('gr-limited-text').shadowRoot.textContent.trim()) | |
})) | |
}) | |
} | |
// File name copy button & Open button | |
if (location.href.startsWith('https://gerrit.wisefour.com/')) { | |
setupWatcher2(document.body.firstElementChild, '.jumpToFileContainer', (index, element) => { | |
const textElement = $(element) | |
$(element).after( | |
$(`<gr-button>Open in CS</gr-button>`) | |
.click((event)=> { | |
const filePath = $(element.firstElementChild.shadowRoot).find('#trigger').text().trim() | |
GM_openInTab(`https://cs.corp.skelterlabs.com/gerrit.wisefour.com/a/w4/-/blob/${filePath}`) | |
})) | |
$(element).after( | |
$(`<gr-button>Open</gr-button>`) | |
.click((event)=> { | |
const filePath = $(element.firstElementChild.shadowRoot).find('#trigger').text().trim() + location.hash | |
requestOpenEditor(filePath) | |
})) | |
$(element).after( | |
$(`<gr-button>Copy</gr-button>`) | |
.click((event)=> { | |
const filePath = $(element.firstElementChild.shadowRoot).find('#trigger').text().trim() | |
console.log(`Copying ${filePath}...`) | |
GM_setClipboard(filePath) | |
})) | |
}) | |
} | |
// To Gerrit Link | |
// if (false && location.href.startsWith('https://youtrack.')) { | |
// setupWatcher(document, 'div.wiki.text.prewrapped', (index, element) => { | |
// const commitMsg = $(element).text() | |
// changeIdRegex.lastIndex=0 | |
// const test = changeIdRegex.exec(commitMsg) | |
// const changeId = test[1] | |
// $(element).append($(`<br><a href="https://gerrit.wisefour.com/#/q/${changeId}" target=_blank>gerrit>></a>`)) | |
// }, {contains: changeIdRegex}) | |
// } | |
// Branch command | |
if (location.href.startsWith('https://skelterlabs.atlassian.net/')) { | |
setupWatcher2(document, "span[data-test-id='issue.issue-view.views.issue-base.foundation.quick-add.quick-add-item.link-page']", (index, element) => { | |
const param = window.location.search.replace(/^\?/,'').split('&').reduce((s,c) => {var t=c.split('=');s[t[0]]=t[1];return s;}, {}) | |
let issue = param.selectedIssue | |
// https://skelterlabs.atlassian.net/browse/SS-174 | |
if (!issue) { | |
issue = window.location.pathname.split('/').pop() | |
} | |
$(`<button>Copy</button>`) | |
.click((event)=> { | |
GM_setClipboard(`git fetch && gc -b ${issue} origin/master`) | |
}).insertAfter($(element).parent().parent()) | |
}) | |
} | |
// Storybook open link (not used) | |
if (location.href.startsWith('http://localhost:9009/')) { | |
setupWatcher2(document, "button[title='Open canvas in new tab']", (index, element) => { | |
$(element).parent().prepend($(`<button>Open</button>`) | |
.click((event)=> { | |
let path = window.location.href.split('/').pop() | |
path = path.split('--') | |
requestOpenEditor(path[0].replace(/-/g, '/') + '.story.jsx') | |
})) | |
}) | |
} | |
// Sourcegraph open link | |
if (location.href.startsWith('https://cs.corp.skelterlabs.com/')) { | |
setupWatcher2(document, "li.nav-item>button.copy-link-action", (index, element) => { | |
const button = $(`<button class="btn btn-link btn-link-sm"><svg class="mdi-icon icon-inline" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h4v-2H5V8h14v10h-4v2h4c1.1 0 2-.9 2-2V6c0-1.1-.89-2-2-2zm-7 6l-4 4h3v6h2v-6h3l-4-4z"/></svg></button>`) | |
button.click((event)=> { | |
let path = window.location.href.split('-/blob/').pop().replace("#L", ":") | |
requestOpenEditor(path) | |
}) | |
$(element).after(button) | |
}) | |
} | |
})(jQuery.noConflict(true)) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment