From d784b357f1c6a19859d7ef16b7776eef0f1bdc09 Mon Sep 17 00:00:00 2001 From: htrinter Date: Mon, 29 Apr 2024 19:52:03 +0200 Subject: [PATCH] wip: url extraction --- src/browseraction/components/ActionBar.vue | 17 ++-- src/clipper/content-script.ts | 109 ++++++++++++--------- 2 files changed, 70 insertions(+), 56 deletions(-) diff --git a/src/browseraction/components/ActionBar.vue b/src/browseraction/components/ActionBar.vue index 3e904f0..31154dc 100644 --- a/src/browseraction/components/ActionBar.vue +++ b/src/browseraction/components/ActionBar.vue @@ -21,8 +21,10 @@
- The page clipper works by enabling you to select areas of a web page to extract links from. To do this, the extension - requires permission to access page contents of {{ currentPermissionTabHost }}. + The page clipper works by enabling you to select areas of a web page to extract links from. To + do this, the extension requires permission to access page contents of + {{ currentPermissionTabHost }}.
- +
@@ -87,9 +84,7 @@ export default { let hasPermissions = false try { - hasPermissions = await browser.permissions.contains( - this.buildClipperPermissionsObject() - ) + hasPermissions = await browser.permissions.contains(this.buildClipperPermissionsObject()) } catch (e) { console.error(e) alert(NO_CLIP_MESSAGE) diff --git a/src/clipper/content-script.ts b/src/clipper/content-script.ts index 3d5d759..45dcd74 100644 --- a/src/clipper/content-script.ts +++ b/src/clipper/content-script.ts @@ -1,7 +1,8 @@ if (!document.body.hasAttribute('omu-clipper-initialized')) { console.log('initialize clipper') let collectedUrls: string[] = [] - let selectedElement: HTMLElement | null = null + let hoveredElement: HTMLElement | null = null + const selectedElements: HTMLElement[] = [] const setCollectedCount = () => { const collectedCountEl = document.querySelector('#collected-count') @@ -10,63 +11,76 @@ if (!document.body.hasAttribute('omu-clipper-initialized')) { } } - const addUrlsToCollection = (element: HTMLElement) => { + const extractLinksFromElement = (selectedElement: HTMLElement): string[] => { + const inspectedElement = + selectedElement.parentElement?.tagName.toLowerCase() === 'a' + ? selectedElement.parentElement.cloneNode(true) + : selectedElement.cloneNode(true) + const wrapper = document.createElement('div') - wrapper.appendChild(element.cloneNode(true)) - - Array.from(wrapper.querySelectorAll('a')).forEach((link) => { - const href = link.getAttribute('href') - if (href) { - const prependProtocol = !href.startsWith(window.location.protocol) - const prependHost = prependProtocol && !href.startsWith(window.location.host) - const prependPath = prependHost && !href.startsWith('/') - - const url = `${prependProtocol ? `${window.location.protocol}//` : ''}${ - prependHost ? window.location.host : '' - }${ - prependPath - ? `${window.location.pathname}${!window.location.pathname.endsWith('/') ? '/' : ''}` - : '' - }${href}` - - collectedUrls.push(url) - } - }) + wrapper.appendChild(inspectedElement) + + return Array.from(wrapper.querySelectorAll('a')) + .map((link) => { + const href = link.getAttribute('href') + if (href) { + const prependProtocol = !href.startsWith(window.location.protocol) + const prependHost = prependProtocol && !href.startsWith(window.location.host) + const prependPath = prependHost && !href.startsWith('/') + + return `${prependProtocol ? `${window.location.protocol}//` : ''}${ + prependHost ? window.location.host : '' + }${ + prependPath + ? `${window.location.pathname}${!window.location.pathname.endsWith('/') ? '/' : ''}` + : '' + }${href}` + } + }) + .filter((u) => u !== undefined) as string[] + } + const addUrlsToCollection = (element: HTMLElement) => { + const urls = extractLinksFromElement(element) + collectedUrls.push(...urls) setCollectedCount() } - const copyCollectionToClipboard = () => { - navigator.clipboard.writeText(collectedUrls.join('\n')) + const removeUrlsFromCollection = (element: HTMLElement) => { + const urls = extractLinksFromElement(element) + urls.forEach((url) => { + delete collectedUrls[collectedUrls.indexOf(url)] + }) + collectedUrls = collectedUrls.filter((u) => u) + setCollectedCount() } - const clearCollection = () => { - collectedUrls = [] - setCollectedCount() + const copyCollectionToClipboard = () => { + navigator.clipboard.writeText(collectedUrls.join('\n')) } const handleMouseOver = (event: MouseEvent) => { if ( - selectedElement !== event.target && + hoveredElement !== event.target && !(event.target as HTMLElement).classList.contains('opmurls') ) { - if (selectedElement) { - selectedElement.style.outline = '' + if (hoveredElement) { + hoveredElement.style.outline = '' } - selectedElement = event.target as HTMLElement - selectedElement.style.outline = '4px solid red' + hoveredElement = event.target as HTMLElement + hoveredElement.style.outline = '4px solid blue' } event.stopPropagation() } const handleMouseOut = (event: MouseEvent) => { if ( - selectedElement && - selectedElement === event.target && + hoveredElement && + hoveredElement === event.target && !(event.target as HTMLElement).classList.contains('opmurls') ) { - selectedElement.style.outline = '' - selectedElement = null + hoveredElement.style.outline = '' + hoveredElement = null } event.stopPropagation() } @@ -75,7 +89,16 @@ if (!document.body.hasAttribute('omu-clipper-initialized')) { const clickedElement = event.target as HTMLElement if (clickedElement && !clickedElement.classList.contains('opmurls')) { console.log('element chosen', clickedElement) - addUrlsToCollection(clickedElement) + + if (selectedElements.includes(clickedElement)) { + removeUrlsFromCollection(clickedElement) + delete selectedElements[selectedElements.indexOf(clickedElement)] + clickedElement.style.border = 'none' + } else { + addUrlsToCollection(clickedElement) + selectedElements.push(clickedElement) + clickedElement.style.border = '5px solid green' + } event.preventDefault() event.stopPropagation() @@ -96,8 +119,8 @@ if (!document.body.hasAttribute('omu-clipper-initialized')) { document.removeEventListener('mouseout', handleMouseOut, true) document.removeEventListener('click', handleClick, true) - if (selectedElement) { - selectedElement.style.outline = '' + if (hoveredElement) { + hoveredElement.style.outline = '' } document.querySelector('#opmurls-overlay')?.remove() @@ -109,10 +132,10 @@ if (!document.body.hasAttribute('omu-clipper-initialized')) {
0 URLs - Clear + Copy to clipboard
- Select an element and click on it to extract links. Press escape to finish and copy to clipboard. + Select elements by clicking on them to extract links. Click again for deselect. Press escape to finish and copy to clipboard.
` @@ -121,10 +144,6 @@ if (!document.body.hasAttribute('omu-clipper-initialized')) { alert('URLs copied to clipboard.') }) - document.querySelector('.opmurls #clear')?.addEventListener('click', () => { - clearCollection() - }) - document.body.setAttribute('omu-clipper-initialized', '') } else { console.log('clipper already initialized')