const addedElementRootIdentifier = 'boost-branch-id-row'; const addBranchName = () => { // Example URL // https://app.asana.com/0/1201323259943344/1203874541847641 // https://app.asana.com/0/1201323259943344/1203874541847641/f const taskRegex = /^\/\d+\/\d+\/(\d+)/ const taskMatch = taskRegex.exec(window.location.pathname); if (!taskMatch) { return; } if (document.getElementById(addedElementRootIdentifier)) { return; } const taskId = taskMatch[1]; const tableElement = document.querySelector('.TaskPaneFields'); const titleElement = document.querySelector('div.ObjectTitleInput.TaskPane-titleRow.TaskPane-titleRowInput > div > textarea'); if (!tableElement) { throw new Error('Cannot find required DOM elements: tableElement'); } if (!titleElement) { throw new Error('Cannot find required DOM elements: titleElement'); } const title = titleElement.innerHTML; const branchName = [...(title.toLocaleLowerCase().replace(/[^a-z0-9 ]/ig, '').split(' ')), taskId].join('-'); const addedRowElement = document.createElement('div'); addedRowElement.id = addedElementRootIdentifier; addedRowElement.dataset.title = title; addedRowElement.dataset.branch = branchName; addedRowElement.classList.add('LabeledRowStructure'); const labelDiv1 = document.createElement('div'); labelDiv1.classList.add('LabeledRowStructure-left'); labelDiv1.style.width = '120px'; addedRowElement.appendChild(labelDiv1); const labelDiv2 = document.createElement('div'); labelDiv2.classList.add('LabeledRowStructure-labelContainer'); labelDiv1.appendChild(labelDiv2); const labelLabel = document.createElement('label'); labelLabel.classList.add('LabeledRowStructure-label'); labelLabel.innerHTML = 'Canonical branch'; labelDiv2.appendChild(labelLabel); const valueDiv1 = document.createElement('div'); valueDiv1.classList.add('LabeledRowStructure-right'); addedRowElement.appendChild(valueDiv1); const valueDiv2 = document.createElement('div'); valueDiv2.classList.add('LabeledRowStructure-content'); valueDiv2.style.display = 'flex'; valueDiv2.style.gap = '10px'; valueDiv1.appendChild(valueDiv2); const follower = document.createElement('span'); follower.style.color = '#272'; const clickableBranchNameElement = document.createElement('span'); clickableBranchNameElement.style.cursor = 'pointer'; clickableBranchNameElement.style.minWidth = '0px'; clickableBranchNameElement.style.flexShrink = '1'; clickableBranchNameElement.style.textOverflow = 'ellipsis'; clickableBranchNameElement.style.whiteSpace = 'nowrap'; clickableBranchNameElement.style.overflow = 'hidden'; clickableBranchNameElement.innerHTML = branchName; clickableBranchNameElement.onclick = () => { navigator.clipboard.writeText(branchName); follower.innerHTML = 'copied!'; } valueDiv2.appendChild(clickableBranchNameElement); valueDiv2.appendChild(follower); tableElement.insertBefore(addedRowElement, tableElement.childNodes[tableElement.childNodes.length -1]); } window.setInterval(() => { addBranchName(); }, 1000);