NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name JIRA Quick Navigation Ext // @description A GD JIRA quick navigation extension. // @version 1.41 // @author Darren Teng // @license MIT // @include * // @match https://pd.nextestate.com/* // @run-at document-end // @grant none // ==/UserScript== (function () { //'use strict'; console.log('Tampermonkey JIRA ext loaded...'); String.prototype.replaceAll = function (search, replacement) { var target = this; return target.replace(new RegExp(search, 'g'), replacement); }; window.extUtil = { isTop: true, pannelIsOpen: true, pageInfo: null, render() { this.id = Date.now(); this['pannel' + this.id] = {}; this.pageInfo = this.getPageInfo(); this.isDivReady(0, 60, () => { this.renderPannel(); this.renderRocket(); this.hideApprovals(); }); }, handleDetailPage() { if (extUtil.pageInfo.page == 'story-detail') { extUtil.listenActivityClick(); } }, isDivReady(tryTime, maxTryTime, callback) { console.log('check isDivReady') tryTime++; if (tryTime > maxTryTime) { console.log('isDivReady exceed max try ' + maxTryTime); return; } if (this.pageInfo.scrollElement) { console.log('div is ready.'); callback && callback(); } else { setTimeout(() => { this.loadScollBox(this.pageInfo.scrollWinId); this.isDivReady(tryTime, maxTryTime, callback); }, 50); } }, showHidedRow(id) { (function (e, id) { console.log('showId:' + id); console.log(e); debugger var ele = document.getElementById(id); if (ele.display != 'none') { e.target.innerText = 'Hide'; ele.style.display = 'none'; } else { e.target.innerText = 'Show'; ele.style.display = 'block'; } })(e, id); }, hideApprovals() { setTimeout(()=>{ var content = document.querySelector('#approvalsmodule .mod-content'); if(content.offsetHeight>10){ var approvalTitle = document.querySelector('#approvalsmodule_heading .toggle-title'); approvalTitle.click(); approvalTitle.innerText="Approvals (click to toggle hide/show)"; } },100); }, renderPannel() { var items = this.getPageHeaders(); var renderFunc = () => { items = this.getPageHeaders(); items = this.filterQuickLinks(items); var htmlContent = this.buildTab(items); //render pannel var pannelDiv = document.createElement('div'); pannelDiv.innerHTML = htmlContent; document.getElementsByTagName('body')[0].appendChild(pannelDiv); this.pageInfo.onPannelReady && this.pageInfo.onPannelReady(); $('.collspanClz').on('click', function () { extUtil.toggolePannel(); }); //default show the panel. so if it set to not display the panel, hide it. if (!this.pannelIsOpen) { extUtil.pannelIsOpen = true; extUtil.toggolePannel(); } } if (!items || !items.length) { var firstRetryTime = 500; console.log('No items found, delay ' + firstRetryTime + ' ms and retry.') extUtil.delayDo(firstRetryTime, renderFunc); } else { renderFunc(); } }, changeRocketDirection(fire, rocket) { if (extUtil.isTop && (extUtil.direction == "up")) { extUtil.direction = "down"; fire.classList.remove("burn"); rocket.classList.add("rotate"); } if (extUtil.isBottom && (extUtil.direction == "down" || !extUtil.direction)) { extUtil.direction = "up"; fire.classList.remove("burn"); rocket.classList.remove("rotate"); } }, updateRocketStatus(ele) { extUtil.isTop = ele.scrollTop <= 100; extUtil.isBottom = ele.clientHeight + ele.scrollTop >= ele.scrollHeight; }, renderRocket() { //render rocket var rocket = document.createElement('div'); rocket.setAttribute("class", "rocketOutbox rotate"); rocket.innerHTML = this.buildRocket(); document.getElementsByTagName('body')[0].appendChild(rocket); var fire = document.querySelector(".fire"); document.getElementsByClassName('spaceship')[0].onclick = function () { fire.classList.add("burn"); const pageInfo = extUtil.pageInfo; if (extUtil.direction == "up") { //go to top pageInfo.scrollElement.scrollTo(0, 0); } else { //go to bottom var ele = pageInfo.scrollElement; if (!ele) return; pageInfo.scrollElement.scrollTo(0, 100000); } extUtil.updateRocketStatus(extUtil.pageInfo.scrollElement); extUtil.changeRocketDirection(fire, rocket); }; var scrollWindow = document.querySelector(this.pageInfo.scrollWinId); var d = extUtil.debounce(() => { console.log('isRocketStatusChanged?'); extUtil.updateRocketStatus(scrollWindow); if (extUtil.isTop || extUtil.isBottom) { fire.classList.add("burn"); setTimeout(() => { extUtil.changeRocketDirection(fire, rocket); console.log('isRocketStatusChanged:true'); }, 300); } }, 100); scrollWindow.addEventListener('scroll', () => { d(); console.log('scroll...'); }); }, debounce(func, time, tag) { var store = {}; return function () { var context = this; var args = arguments; tag = tag ? tag : func.name; var timeoutId = store[tag]; if (timeoutId) { clearTimeout(timeoutId); } store[tag] = setTimeout(() => { func(args); }, time); } }, filterQuickLinks(items) { if (items && this.pageInfo) { items.forEach(v => { if (this.pageInfo.list && this.pageInfo.list.length > 0) { var it = this.pageInfo.list.find(p => p.name == v.text.trim() || (p.id && ("#" + p.id) == v.link)); if (it) { v.order = it.order; v.desc = it.desc; v.type = it.type; v.text = it.desc ? it.desc : v.text; }; } else { v.order = 0; v.desc = v.text; v.type = "left"; } }) } return items; }, loadScollBox(selecter) { this.pageInfo.scrollElement = document.querySelector(selecter); }, getPageInfo() { var url = window.location.href; var isBacklogBoardViewPage = (url) => { return /pd\.nextestate\.com\/secure\/RapidBoard\.jspa\?.*/.test(url) && url.indexOf('view=planning') < 0;; } var isStoryDetailPage = (url) => { return /pd\.nextestate\.com\/browse\/.*/.test(url); } var isBacklogListViewPage = (url) => { return /pd\.nextestate\.com\/secure\/RapidBoard\.jspa\?.*/.test(url) && url.indexOf('view=planning') > 0; } var isReportPage = (url) => { return url.indexOf('pd\.nextestate\.com/projects/') > -1 && url.indexOf('selectedItem=com.atlassian.jira.jira-projects-plugin:report-page') >= 0; } var isReleasePage = (url) => { return url.indexOf('pd\.nextestate\.com/projects/') > -1 && url.indexOf('selectedItem=com.atlassian.jira.jira-projects-plugin:release-page') >= 0; } //event listener for tab change between backlog list view and backlog board view. var onStateChange = () => { console.log('onStateChange...'); if (!extUtil.hasAddedPushState) { var _wr = function (type) { var orig = history[type]; return function () { var rv = orig.apply(this, arguments); var e = new Event(type); e.arguments = arguments; window.dispatchEvent(e); return rv; }; }; history.pushState = _wr('pushState'); history.replaceState = _wr('replaceState'); window.addEventListener('pushState', function (e) { var span = (Date.now() - extUtil.id) / 1000; //only re-render the panel if timespan larger than 1s. if (span > 1) { setTimeout(() => { console.log('re-render pannel...'); var extPopupPage = document.querySelector('.extPopupPage'); if (extPopupPage && extPopupPage.parentNode) { extPopupPage.parentNode.remove(); } var rocket = document.querySelector('.rocketOutbox'); if (rocket) rocket.remove(); setTimeout(() => extUtil.render(), 100); }, 200); } else { console.log('pannel' + extUtil.id + ' hasReRenderedPanel.'); } }); extUtil.hasAddedPushState = true; } } var map = [{ page: "story-detail", isCurrentPage: isStoryDetailPage, scrollWinId: ".issue-view", listItemFilter: { itemTextFilter: "", // the filter to get the text content. if it's empty, just use the box as the text container. itemBoxFilter: ".mod-header" // the filter to navigate to }, buildFastLinkFunc: this.buildFastLinkForDetailPage, onPannelReady: this.handleDetailPage, list: [{ type: "left", name: "Details", desc: "Details", order: 1 }, { type: "left", name: "Description", desc: "Description", order: 2 }, { type: "left", name: "Approvals", desc: "Approvals", order: 3 }, { type: "left", name: "Smart Checklist", desc: "Smart Checklist", order: 4 }, { type: "left", name: "Attachments", desc: "Attachments", order: 5, id: "attachmentmodule_heading" }, { type: "left", name: "Issue Links", desc: "Issue Links", id:"linkingmodule_heading", order: 6 }, { type: "left", name: "Sub-Tasks", desc: "Sub-Tasks", order: 7 }, { type: "left", name: "Activity", desc: "Activity", order: 8 }, { type: "right", name: "People", desc: "People", order: 1 }, { type: "right", name: "Dates", desc: "Dates", order: 2 }, { type: "fast", name: "Comments", desc: "Comments", order: 2, id: "comment-tabpanel" }, { type: "fast", name: "History", desc: "History", order: 2, id: "changehistory-tabpanel" }, { type: "fast", name: "Story Points", desc: "Story Points", order: 3, id: "customfield_10002", onclick: (id) => { extUtil.popupToEdit(id, "'Story point' not found, try again."); } }, { type: "fast", name: "Dev Lead", desc: "Dev Lead", order: 4, id: "customfield_13211", onclick: (id) => { extUtil.popupToEdit(id, "'Development Lead' not found, try again."); } }, { type: "fast", name: "QA Engineer", desc: "QA Engineer", order: 5, id: "customfield_13213", onclick: (id) => { extUtil.popupToEdit(id, "'QA Engineer' not found, try again."); } }, { type: "fast", name: "Dev ETA", desc: "Dev ETA", order: 5, id: "customfield_13400", onclick: (id) => { extUtil.popupToEdit(id, "'Development ETA' not found, try again."); } }, ] }, { page: "backlog-list-view", isCurrentPage: isBacklogListViewPage, scrollWinId: "#ghx-backlog", listItemFilter: { itemTextFilter: ".ghx-name", itemBoxFilter: ".ghx-backlog-container" }, additionalCss: `.extPopupPage{ overflow-y: scroll;} .rocketOutbox {right:10px !important;} .extContent li { width: 240px; } .extContent { width: 240px; }`, onPannelReady: onStateChange, list: [] }, { page: "backlog-board-view", isCurrentPage: isBacklogBoardViewPage, scrollWinId: "#ghx-pool-column", //"ghx-rabid", listItemFilter: { itemTextFilter: "span[role=button]", itemBoxFilter: ".ghx-swimlane-header" }, additionalCss: `.extPopupPage{ overflow-y: scroll;}`, onPannelReady: onStateChange, list: [] }, { page: "report", isCurrentPage: isReportPage, scrollWinId: "report-page", list: [] }, { page: "release", isCurrentPage: isReleasePage, scrollWinId: "release-page", list: [] }, ]; var pageInfo = null; map.forEach((p) => { if (p.isCurrentPage(url)) { pageInfo = p; pageInfo.scrollElement = document.querySelector(p.scrollWinId); return; } }); return pageInfo; }, getPageHeaders() { var headers = document.querySelectorAll(this.pageInfo.listItemFilter.itemBoxFilter); var items = []; const exculedeIds = ['dnd-metadata_heading']; var autoId = 100; headers.forEach(node => { if (exculedeIds.indexOf(node.id) > -1) return; if (!node.id) { node.id = "autoId" + autoId++; node.setAttribute('id', node.id); } var textEle = this.pageInfo.listItemFilter.itemTextFilter ? node.querySelector(this.pageInfo.listItemFilter.itemTextFilter) : node; items.push({ link: '#' + node.id, text: textEle ? textEle.innerText : "-", anchor: '^' }); }); return items; }, changeSelectedFastlinkTab(id) { document.querySelectorAll('.extFastLinks li').forEach(p => { p.setAttribute('class', p.getAttribute('class').replaceAll('fastlink_actived', '')); }); var selectedItems = document.getElementsByClassName('fast_' + id); if (selectedItems && selectedItems[0]) { var selectedItemClzs = selectedItems[0].getAttribute("class"); selectedItems[0].setAttribute("class", selectedItemClzs + ' fastlink_actived') } }, delayDo(time, callback) { setTimeout(function () { callback && callback(); }, time <= 0 ? 10 : time); }, buildRocket() { //#region var style = `<style> .rotate{transform: rotate(180deg);} .rocketOutbox { /*border: 1px solid green;*/ width: 90px; position: fixed; right: 30px; bottom: 200px; height: 90px; z-index: 999; zoom: 0.7; } .spaceship { zoom:0.3; width: 300px; height: 300px; display: flex; justify-content: center; align-items: center; position: absolute; transition: all 2s ease; cursor:pointer; z-index:999; animation: float 2s ease infinite alternate; } @keyframes float { 0% { transform: translateY(10px); } 100% { transform: translateY(0px); } } .spaceship.launch { bottom: 120%; animation: launch 3s ease; } @keyframes launch { 0% { bottom: 130px; transform: translatex(2px); } 10% { transform: translatex(-2px); } 20% { transform: translatex(2px); } 30% { transform: translatex(-2px); } 60% { transform: translatex(0px); bottom: 150px; } 100% { bottom: 120%; } } .spaceship.land { bottom: 130px; animation: land 3s ease; } @keyframes land { 0% { bottom: 120%; } 50% { bottom: 180px; } 100% { bottom: 130px; } } .spaceship .spaceshipBody { width: 35%; height: 80%; background-color: white; border-bottom-left-radius: 100%; border-bottom-right-radius: 100%; border-top-left-radius: 100%; border-top-right-radius: 100%; display: flex; justify-content: center; position: relative; z-index: 1; box-shadow: inset 0px -173px 0px -80px white, inset 0px -213px 0px -60px #e4e4e4; } .spaceship .spaceshipBody:before { content: ""; position: absolute; width: calc(100% - 36px); height: 42%; background-color: inherit; bottom: -30px; transform: perspective(10em) rotateX(-50deg); border-bottom-left-radius: 50px; border-bottom-right-radius: 50px; box-shadow: inset 0px -33px 0px 0px rgba(0, 0, 0, 0.1); } .spaceship .spaceshipBody:after { content: ""; position: absolute; width: 45%; height: 40px; background-color: #f95959; bottom: -20px; transform: perspective(10em) rotateX(-50deg); border-bottom-left-radius: 50px; border-bottom-right-radius: 50px; z-index: -1; } .spaceship .spaceshipBody .spaceshipTop { width: 100%; height: 240px; border-radius: 100%; overflow: hidden; position: relative; box-shadow: inset -12px 17px 0px -7px rgba(0, 0, 0, 0.15); } .spaceship .spaceshipBody .spaceshipTop:before { content: ""; background-color: #4ba3b7; position: absolute; width: 100%; height: 100px; left: calc(50% - 54%); border-radius: 100%; top: -55px; border: 2px solid white; box-shadow: inset -18px 56px 0px 3px rgba(0, 0, 0, 0.1), 0px 0px 0px 6px #f95959; } .spaceship .spaceshipBody .spaceshipWindows { display: flex; justify-content: center; align-items: center; width: 300px; height: 300px; position: absolute; } .spaceship .spaceshipBody .spaceshipWindows span { background-color: #ace7ef; box-shadow: inset -4px 4px 0px 0px rgba(0, 0, 0, 0.3), inset 0px 0px 0px 2px white; border: 4px solid #f95959; z-index: 2; position: absolute; border-radius: 100%; overflow: hidden; } .spaceship .spaceshipBody .spaceshipWindows span:before { position: absolute; content: ""; background-color: white; width: 200%; height: 100%; transform: rotate(45deg); opacity: 0.4; } .spaceship .spaceshipBody .spaceshipWindows span:nth-child(1) { width: 30px; height: 30px; top: 23%; } .spaceship .spaceshipBody .spaceshipWindows span:nth-child(1):before { top: 10px; right: 0px; } .spaceship .spaceshipBody .spaceshipWindows span:nth-child(2) { width: 45px; height: 45px; top: 40%; } .spaceship .spaceshipBody .spaceshipWindows span:nth-child(2):before { top: 12px; right: 0px; } .spaceship .spaceshipBottom { display: flex; justify-content: center; align-items: center; width: 300px; height: 300px; position: absolute; } .spaceship .spaceshipBottom span { background-color: #4ba3b7; border-radius: 10px; position: absolute; overflow: hidden; } .spaceship .spaceshipBottom span:before { content: ""; position: absolute; background-color: white; width: 2px; height: 120%; border-radius: 20px; } .spaceship .spaceshipBottom span:nth-child(1) { width: 15px; height: 80px; z-index: 2; bottom: 2%; box-shadow: inset -5px -3px 0px 0px rgba(0, 0, 0, 0.18); } .spaceship .spaceshipBottom span:nth-child(1):before { display: none; } .spaceship .spaceshipBottom span:nth-child(2) { width: 50px; height: 130px; left: 32%; bottom: 6%; transform: perspective(10em) rotateX(60deg) translateZ(-1px); box-shadow: inset -5px -3px 0px 0px rgba(0, 0, 0, 0.2); } .spaceship .spaceshipBottom span:nth-child(2):before { left: 0px; border-right: 2px solid #f95959; } .spaceship .spaceshipBottom span:nth-child(3) { width: 50px; height: 130px; right: 32%; bottom: 6%; transform: perspective(10em) rotateX(60deg) translateZ(-1px); box-shadow: inset -5px -3px 0px 0px rgba(0, 0, 0, 0.2); } .spaceship .spaceshipBottom span:nth-child(3):before { right: 0px; border-left: 2px solid #f95959; } .spaceship .fire { display: flex; justify-content: center; align-items: center; width: 300px; height: 100px; position: absolute; bottom: -50px; } .spaceship .fire.burn span { border-radius: 50px; top: 0; position: absolute; background-color: #ffd460; height: inherit; animation: fire 0.8s ease infinite alternate; } .spaceship .fire.burn span:nth-child(1) { width: 6px; height: 40px; left: 44%; transform: translateY(27px); box-shadow: inset 0px -7px 10px #ea5455, inset 0px -19px 10px #ffc175, 0px -7px 10px #ea5455; animation-delay: 0.2s; } .spaceship .fire.burn span:nth-child(1):after { position: absolute; content: ""; width: 4px; height: 60%; border-radius: 50px; background-color: #ffd460; bottom: 0; transform: translate(8px, 15px); box-shadow: inset 0px -5px 10px #ea5455, inset 0px -19px 10px #ffc175, 0px -7px 10px #ea5455; } .spaceship .fire.burn span:nth-child(2) { width: 10px; height: 60px; left: calc(50% - 8px); transform: translateY(35px); box-shadow: inset 0px -10px 10px #ea5455, inset 0px -30px 10px #ffc175, 0px -7px 10px #ea5455; } .spaceship .fire.burn span:nth-child(2):after { position: absolute; content: ""; width: 10px; height: 100%; border-radius: 10px; background-color: #ffd460; top: 0; transform: translate(-6px, -25px); box-shadow: inset 0px -5px 10px #ea5455, inset 0px -15px 10px #ffc175, 0px -7px 10px #ea5455; } .spaceship .fire.burn span:nth-child(3) { width: 10px; height: 40px; right: 45%; transform: translateY(27px); box-shadow: inset 0px -5px 10px #ea5455, inset 0px -30px 10px #ffc175, 0px -7px 10px #ea5455; animation-delay: 0.4s; } .spaceship .fire.burn span:nth-child(3):after { position: absolute; content: ""; width: 6px; height: 180%; border-radius: 10px; background-color: #ffd460; top: 0; transform: translate(-6px, -15px); box-shadow: inset 0px -5px 10px #ea5455, inset 0px -20px 10px #ffc175, 0px -7px 10px #ea5455; } @keyframes fire { 0% { height: 10px; bottom: 0; 50% { top: 0; } 100% { height: 20px; bottom: 0; } } } .spaceship .fire.burn .glow { position: absolute; width: 0px; height: 0px; border-radius: 100%; box-shadow: 0px 0px 50px 20px #ea5455; opacity: 1; animation: glow 0.8s ease infinite alternate; } @keyframes glow { 0% { box-shadow: 0px 0px 50px 20px #ea5455; } 100% { box-shadow: 0px 0px 50px 25px #ea5455; } } .shadow { width: 50px; height: 10px; background-color: black; position: absolute; border-radius: 100%; opacity: 0.2; top: 96px; z-index: 99; left:25px; animation: shadow 2s ease infinite alternate; transition: all 0.5s ease; } @keyframes shadow { 0% { width: 40px; } 100% { width: 46px; } } ${navigator.userAgent.indexOf('Firefox') > -1 ? `.spaceship{ -moz-transform: scale(0.3) !important; margin-left: -104px !important; margin-top: -104px !important; }`: ''} </style>`; var html = ` <div class="spaceship"> <div class="spaceshipBody"> <div class="spaceshipTop"></div> <div class="spaceshipWindows"> <span></span> <span></span> </div> </div> <div class="spaceshipBottom"> <span></span> <span></span> <span></span> </div> <div class="fire"> <span></span> <span></span> <span></span> <div class="glow"></div> </div> </div><div class="shadow" style="opacity: 0.2;"></div>`; //#endregion return style + html; }, buildFastLinkForDetailPage(template, data) { if (data) { var content = data.map(d => `<li class='fast_${d.id}'><a href='javascript:void(0)' class='fastNavItem' onclick='extUtil.fastLinkClick("${d.id}")' fastid='"${d.id}"'>${d.desc}</a></li>`) return template.replace('$content', content.join(' ')); } return template; }, buildTab(items) { var templateCss = `<style> .extPopupPage { position: fixed; top: 200px; right: 20px; opacity: 0.8; background-color: #ece4f5; border-radius: 4px; width: 300px; height: 240px; z-index: 999; } .extTitle{ font-weight:bold; margin:10px; } .extContent { width: 140px; float: left; } .ext-list-left{ padding-left: 10px; } .ext-list-right{ width: 140px; padding-left: 10px; } .extContent li { width: 140px; list-style-type: none; } .extFastLinks { width: 290px; float: left; background: #e2e0e0; padding: 4px; } .extFastLinks li{ list-style-type: none; float: left; width: 80px; } .fastlink_actived a{ color: green; font-weight:bold; } .left { width: 50%; float: left; } .collspanClz{ background:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNiAxNiI+CiAgPHBhdGggZD0iTTcuNyAzLjdMMy40IDhsNC4zIDQuM2MuNC40LjQgMSAwIDEuNC0uNC40LTEgLjQtMS40IDBsLTUtNWMtLjQtLjQtLjQtMSAwLTEuNGw1LTVjLjQtLjQgMS0uNCAxLjQgMCAuNC40LjQgMSAwIDEuNHptNyAwTDEwLjQgOGw0LjMgNC4zYy40LjQuNCAxIDAgMS40LS40LjQtMSAuNC0xLjQgMGwtNS01Yy0uNC0uNC0uNC0xIDAtMS40bDUtNWMuNC0uNCAxLS40IDEuNCAwIC40LjQuNCAxIDAgMS40eiIgZmlsbD0iIzUwNWY3OSIvPgo8L3N2Zz4K); width: 24px; position: absolute; height: 24px; cursor: pointer; font-weight: bold; text-align: center; color: green; top: 206px; right: 36px; z-index: 1000; line-height:36px; } .collspanOpen{ transform: rotate(0deg); } .collspanClose{ transform: rotate(180deg); } ${this.pageInfo.additionalCss ? this.pageInfo.additionalCss : ""} </style>`; var htmlContentTemplate = ` <div class="extPopupPage"> <div class="extPannel"> <p class='extTitle'>Quick links</p> $content $fastContent </div> </div> <div class='collspanClz ${this.pannelIsOpen ? 'collspanClose' : 'collspanOpen'}' title="Click to show/hide the quick nav panel."></div> `; var htmlLeftListContentTemplate = ` <ul class="extContent ext-list-left"> $items </ul>`; var itemLeftItemContentTemplate = ` <li class="extitem"> <div class="">$item</div> </li>`; var htmlRightListContentTemplate = ` <ul class="extContent ext-list-right"> $items </ul>`; var itemRightItemContentTemplate = ` <li class="extitem"> <div class="">$item</div> </li>`; var htmlFastTemplate = `<ul class='extFastLinks'>$content</ul>`; var leftList = items.filter(p => p.type == "left").sort((a, b) => a - b); var rightList = items.filter(p => p.type == "right").sort((a, b) => a - b); var fastList = this.pageInfo.list.filter(p => p.type == "fast").sort((a, b) => a - b); var textLeft = leftList && leftList.map(i => { return itemLeftItemContentTemplate.replace('$item', `<a href='javascript:void(0);' class='link${i.anchor}' onclick='extUtil.anchorLinkClick("${i.link}")'>${i.text}</a>\r\n`); }).join(''); var textRight = rightList && rightList.map(i => { return itemRightItemContentTemplate.replace('$item', `<a href='javascript:void(0);' class='link${i.anchor}' onclick='extUtil.anchorLinkClick("${i.link}")'>${i.text}</a>\r\n`); }).join(''); htmlFastTemplate = this.pageInfo.buildFastLinkFunc ? this.pageInfo.buildFastLinkFunc(htmlFastTemplate, fastList) : ""; this.injectFuncs = this.injectFuncs ? this.injectFuncs : []; this.injectFuncs.push({ selector: '.extFastLinks li', func: function clickFastLinkItem() { var id = this.getAttribute('fastid') id && document.getElementById(id).click(); } }); var content = htmlLeftListContentTemplate.replace('$items', textLeft) + htmlRightListContentTemplate.replace('$items', textRight); text = templateCss + htmlContentTemplate.replace('$content', content).replace('$fastContent', htmlFastTemplate); return text; }, popupToEdit(id, errorMsg) { var edit = document.getElementById('edit-issue'); if (edit) { edit.click(); setTimeout(function () { var ele = document.getElementById(id); if (!ele) { alert(errorMsg) return; } ele.scrollIntoView(); ele.focus(); extUtil.shrinkDiv(id); }, 1400); } }, fastLinkClick(id) { id = id.replace("#", ''); var curEle = document.getElementById(id); curEle && curEle.scrollIntoView(); if (document.querySelector('#issue-tabs .active-tab').id == id) { console.log('same id, no action') return; } if (!document.getElementById(id) && !document.getElementById(id + '-val')) { //id == 'rowForcustomfield_10002' && !document.getElementById(id) var item = extUtil.pageInfo.list.find(i => i.id == id); if (item && item.onclick) { item.onclick(id); } } else { //check the actual id var ele = document.querySelector('#' + id + ' a'); //check extend id if (!ele) { ele = document.querySelector('#' + id + '-val'); } ele && ele.click(); extUtil.shrinkDiv(id); } console.log('click ' + id) }, anchorLinkClick(anchor) { var id = anchor.replace('#', ''); document.getElementById(id).scrollIntoView(); this.shrinkDiv(id); }, shrinkDiv(id) { var ele = document.getElementById(id); if (!ele) return; ele.style.border = '3px solid green'; this.delayDo(200, function () { ele.style.border = '2px solid green'; extUtil.delayDo(100, function () { ele.style.border = 'none'; }) }); }, toggolePannel() { var $elPannel = $(document.querySelector('.extPopupPage')); var $elCollspan = $(document.querySelector('.collspanClz')); if (this.pannelIsOpen) { $elPannel.hide(); $elCollspan.removeClass('collspanClose'); $elCollspan.addClass('collspanOpen'); } else { $elPannel.show(); $elCollspan.removeClass('collspanOpen'); $elCollspan.addClass('collspanClose'); } this.pannelIsOpen = !this.pannelIsOpen; }, delayDo(time, callback) { setTimeout(function () { callback && callback(); }, time <= 0 ? 10 : time); }, listenActivityClick() { $('#activitymodule').on('click', function (e) { extUtil.changeSelectedFastlinkTab(e.srcElement.id) console.log('try to postMessage to content.js'); }) } }; setTimeout(() => { extUtil.render(); }, 100); })();