// ==UserScript== // @name MiGerritPlus // @namespace thbeliefNameSpace // @icon https://cnbj1.fds.api.xiaomi.com/info-app-webfile/common-resource/ico/favicon.ico // @version 1.3.0 // @description some extention for miui gerrit // @author thbelief // @match *://gerrit.pt.mioffice.cn/* // @require https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js // @grant GM_setValue // @grant GM_getValue // @grant GM_registerMenuCommand // @grant GM_deleteValue // @grant GM_xmlhttpRequest // @grant GM_notification // @grant GM_setClipboard // @grant GM.setValue // @grant GM.getValue // @grant GM.registerMenuCommand // @grant GM.deleteValue // @grant GM.xmlHttpRequest // @grant GM.notification // @grant GM.setClipboard // @grant unsafeWindow // @run-at document-end // @license AGPL // @downloadURL none // ==/UserScript== (function () { 'use strict' // code region start /** * some config */ var TAG = "MiGerritPlus" // control is print log var isDebug = true var dashBoardSelf = "https://gerrit.pt.mioffice.cn/dashboard/self" var intervalTime = 150 var checkboxInsertIndex = 3 // need hide group array var hideGroupArray = new Array("Your Turn", "Incoming reviews", "CCed on", "Recently closed") print("origin start") $(document).ready(function () { main() }) // cur url var curHerf = window.location.href // reload because not success sometimes var isNeedReloadMain = false // save checkbox and change var selectChangeMap = new Map() // copyButton var copyButton = createClipIcon() /** * History and window.hashchange is not role * so use interval */ setInterval(function () { if (curHerf != window.location.href || isNeedReloadMain) { isNeedReloadMain = false; curHerf = window.location.href print("cur url = " + curHerf) if (curHerf != dashBoardSelf) { copyButton.remove() print("Not dashBoardSelf.Remove copy button") } if (curHerf === dashBoardSelf) { main() } } }, intervalTime); function print(content) { if (!isDebug) { return; } console.log(TAG + ": " + content) } function main() { print("main") var rootDom = document.body.querySelector("gr-app").shadowRoot.getElementById("app-element").shadowRoot.getRootNode(); var mainHeader = rootDom.querySelector("gr-main-header").shadowRoot.getRootNode() // insert copy button insertClipIcon(mainHeader.querySelector(".links")) // remove footer var footerDom = rootDom.querySelector("footer") if (footerDom != null) { print("remove footer") footerDom.remove() } var mainDom = rootDom.querySelector("main") if (mainDom === null) { print("main is null") return } var changeDom = mainDom.querySelector("gr-dashboard-view") if (changeDom === null) { isNeedReloadMain = true return } var changeList = changeDom.shadowRoot.getRootNode().querySelector("gr-change-list").shadowRoot.getRootNode().querySelectorAll("gr-change-list-section") // cardArray is per change card var cardArray = new Array() for (var i = 0; i < changeList.length; i++) { cardArray[i] = changeList[i].shadowRoot.getRootNode() } if (cardArray.length === 0) { isNeedReloadMain = true } print("cardArray = " + cardArray) for (var i = 0; i < cardArray.length; i++) { var curGroupDom = cardArray[i].querySelector(".section-name") var groupHeaderDom = cardArray[i].querySelector(".groupHeader") // hide which need to hide group if (curGroupDom != null && hideGroupArray.includes(curGroupDom.innerText)) { print("remove " + curGroupDom.innerText) if (groupHeaderDom !== null) { groupHeaderDom.remove() } var groupContentDom = cardArray[i].querySelector(".groupContent") if (groupContentDom !== null) { groupContentDom.remove() } // remove noChanges item var noChangesDom = cardArray[i].querySelector(".noChanges") if (noChangesDom !== null) { noChangesDom.remove() } // remove group title if (i != 0) { var groupTitleDom = cardArray[i].querySelector(".groupTitle") if (groupTitleDom !== null) { groupTitleDom.remove() } } } var groupContentDom = cardArray[i].querySelector(".groupContent") if (groupContentDom !== null) { var groupTitleDom = groupContentDom.querySelector(".groupTitle") if(groupTitleDom.querySelectorAll(".subject").length <= 1){ insertCheckBoxTitle(groupTitleDom) var list = groupContentDom.querySelectorAll("gr-change-list-item") insertCheckBox(list) } } } } /** * insert checkbox title * @param list */ function insertCheckBoxTitle(groupTitle) { var tdList = groupTitle.querySelectorAll("td") groupTitle.insertBefore(createCheckBoxTitle(), tdList[checkboxInsertIndex]) } /** * create checkbox title * @returns */ function createCheckBoxTitle() { var td = document.createElement("td") td.className = "subject" td.innerText = "Select" return td } /** * insert checkbox to every change * @param {*} list */ function insertCheckBox(list) { for (var i = 0; i < list.length; i++) { var tdList = list[i].shadowRoot.getRootNode().querySelectorAll("td") var cellNumberNode = list[i].shadowRoot.getRootNode().querySelector(".number") var titleNode = list[i].shadowRoot.getRootNode().querySelector(".content") var repoNode = list[i].shadowRoot.getRootNode().querySelector(".fullRepo") var branchNode = list[i].shadowRoot.getRootNode().querySelector(".branch") const change = new Change(cellNumberNode.querySelector("a").innerText, titleNode.innerText, cellNumberNode.querySelector("a").href, repoNode.innerText, branchNode.querySelector("a").innerText) list[i].shadowRoot.getRootNode().insertBefore(createCheckBox(change), tdList[checkboxInsertIndex]) } } /** * create checkbox * @param {*} change * @returns */ function createCheckBox(change) { var td = document.createElement("td") var input = document.createElement("input") input.type = "checkbox" input.setAttribute("style", "width:20px;height:20px;") input.onclick = function () { selectChangeMap.get(this).setIsChecked(this.checked) //console.log(selectChangeMap.get(this)) } td.setAttribute("display", "table-cell") td.setAttribute("vertical-align", "middle") td.setAttribute("white-space", "nowrap") td.appendChild(input) selectChangeMap.set(input, change) return td } /** * insert copy button * @param {*} links */ function insertClipIcon(links) { if (links == null) { return } var button = links.querySelector(".copyToClipboard") // just need one if (button == null) { links.appendChild(copyButton) } } /** * get changes which checked by myselef * @returns */ function getCheckedChange() { var changes = new Array() var index = 0 selectChangeMap.forEach(function (value, key) { if (value.isChecked()) { key.checked = false changes[index++] = value } }) return changes } /** * create copy button * @returns */ function createClipIcon() { /** * * * * * * * * * * */ var path = document.createElement("path") path.setAttribute("d", "M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z") var g = document.createElement("g") g.appendChild(path) var svg = document.createElement('svg'); svg.setAttribute("viewBox", "0 0 24 24") svg.setAttribute("preserveAspectRatio", "xMidYMid meet") svg.setAttribute("focusable", "false") svg.setAttribute("style", "pointer-events: none; display: block; width: 100%; height: 100%;") svg.appendChild(g) var icon = document.createElement("iron-icon") icon.setAttribute("icon", "gr-icons:content-copy") icon.appendChild(svg) var button = document.createElement("gr-button") button.setAttribute("class", "copyToClipboard") button.setAttribute("role", "button") button.setAttribute("aria-disabled", "false") button.appendChild(icon) button.onclick = function () { var array = getCheckedChange() if (array.length == 0) { print("not select any change") return } var result = ""; for (var i = 0; i < array.length; i++) { var extra = "" if (i != 0) { extra += "\n" } extra += "index = " + i + "\n" result += extra + array[i].getString() if (i != array.length - 1) { result += "\n" } } print("copy \n" + result) GM_setClipboard(result) } var li = document.createElement("li") li.appendChild(button) return li; } /** * change class * save information about change */ class Change { constructor(id, title, url, repo, branch) { this.id = id.trim() this.title = title.trim() this.url = url.trim() this.repo = repo.trim() this.branch = branch.trim() this.ischecked = false } isChecked() { return this.ischecked } setIsChecked(ischecked) { this.ischecked = ischecked } getString() { var result = "ChangeId: " + this.id + "\nTitle: " + this.title + "\nRepo: " + this.repo + "\nBranch: " + this.branch + "\nUrl: " + this.url return result } } // code region end })();