diff --git a/README.md b/README.md index 5018569..de570de 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@

users badge rating badge - version badge + version badge


Nopy is also at Product Hunt!💖

diff --git a/package.json b/package.json index 4504143..7051dd2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nopy", - "version": "1.3.4", + "version": "1.4.0", "repository": "git@github.com:ntwigs/nopy.git", "author": "ntwigs ", "license": "MIT", diff --git a/public/manifest.json b/public/manifest.json index d227e01..60de819 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -4,7 +4,7 @@ "name": "Nopy", "short_name": "Nopy", "description": "Copy your npmjs dependencies with ease ❤️‍🔥", - "version": "1.3.4", + "version": "1.4.0", "homepage_url": "https://github.com/ntwigs/nopy", "permissions": ["tabs"], "icons": { diff --git a/src/main/button/get-button.ts b/src/main/button/get-button.ts index 755858b..e286576 100644 --- a/src/main/button/get-button.ts +++ b/src/main/button/get-button.ts @@ -1,66 +1,57 @@ import { getAlert } from '../alert/get-alert' import { getAlertContainer } from '../alert/get-alert-container' -const CODE_POSITION = 1 -const getPackageName = (button: Element | Node): string => { - const buttonText = button.childNodes[CODE_POSITION].textContent - - if (!buttonText) { - throw new Error('Could not find button text') - } - - const [packageName] = buttonText.split(' ').reverse() +const getPackageName = (button: HTMLElement): string => { + const [packageName] = button.textContent.split(' ').reverse() return packageName } -const getButtonSpan = (button: Node): HTMLSpanElement => { - const span = button.childNodes[CODE_POSITION].firstChild - - if (!span) { - throw new Error('Could not get button span') +const getCodeBlock = (button: HTMLDivElement) => { + const code = button.querySelector('code') + if (!code) { + throw new Error('Could not find code block in button') } - - return span as HTMLSpanElement + return code } -const getButtonText = (alternative: string, packageName: string): string => { - return `${alternative} ${packageName}` +const getCopyButton = (button: HTMLDivElement) => { + const copyButton = button.querySelector('button') + if (!copyButton) { + throw new Error('Could not find copy button in button') + } + return copyButton } -const setTextContent = ( - span: Node, - alternative: string, - packageName: string, - button: HTMLDivElement -) => { - span.textContent = getButtonText(alternative, packageName) - return button +const setSelection = (codeBlock: HTMLElement) => () => { + const range = document.createRange() + const selection = window.getSelection() + + range.selectNodeContents(codeBlock) + + selection?.removeAllRanges() + selection?.addRange(range) } -const ALERT_WAIT_IN_MS = 2000 +const clearSelection = () => { + window.getSelection()?.removeAllRanges() +} -const addCopyOnClick = ( - button: Node, - alternative: string, - packageName: string -) => { - button.addEventListener('click', () => { - const alertContainer = getAlertContainer() - const alert = getAlert() - const text = getButtonText(alternative, packageName) - navigator.clipboard.writeText(text) - alertContainer.appendChild(alert) +const copyPackageName = (codeBlock: HTMLElement) => () => { + const alertContainer = getAlertContainer() + const alert = getAlert() + navigator.clipboard.writeText(codeBlock.textContent) + alertContainer.appendChild(alert) - const removeAlert = () => { - alertContainer.removeChild(alert) - } + const removeAlert = () => { + alertContainer.removeChild(alert) + } - const timeout = setTimeout(removeAlert, ALERT_WAIT_IN_MS) + const ALERT_WAIT_IN_MS = 2000 + const timeout = setTimeout(removeAlert, ALERT_WAIT_IN_MS) - alert.addEventListener('click', () => { - clearTimeout(timeout) - removeAlert() - }) + alert.addEventListener('click', () => { + clearTimeout(timeout) + removeAlert() }) } @@ -69,9 +60,17 @@ export const getButton = ( alternative: string, packageName?: string ): HTMLElement => { - const _packageName = packageName ? packageName : getPackageName(button) const buttonClone = button.cloneNode(true) as HTMLDivElement - const buttonSpan = getButtonSpan(buttonClone) - addCopyOnClick(buttonClone, alternative, _packageName) - return setTextContent(buttonSpan, alternative, _packageName, buttonClone) + + const codeBlock = getCodeBlock(buttonClone) + const packageNameWithFallback = packageName + ? packageName + : getPackageName(codeBlock) + codeBlock.textContent = `${alternative} ${packageNameWithFallback}` + + const copyButton = getCopyButton(buttonClone) + copyButton.addEventListener('mouseenter', setSelection(codeBlock)) + copyButton.addEventListener('mouseleave', clearSelection) + copyButton.addEventListener('click', copyPackageName(codeBlock)) + return buttonClone } diff --git a/src/main/text/text-selector.ts b/src/main/text/text-selector.ts index 53fe88b..6d7131e 100644 --- a/src/main/text/text-selector.ts +++ b/src/main/text/text-selector.ts @@ -1 +1 @@ -export const textSelector = '#top > div > h1 > span' +export const textSelector = 'aside > h3'