append-to-clipboard
Advanced tools
Comparing version 2.1.0 to 2.2.0
@@ -21,2 +21,11 @@ { | ||
}, | ||
"append_no_separator_linktext": { | ||
"message": "Append to Clipboard - Link Text (no separator)" | ||
}, | ||
"append_line_break_linktext": { | ||
"message": "Append to Clipboard - Link Text (Line break separator)" | ||
}, | ||
"append_double_line_break_linktext": { | ||
"message": "Append to Clipboard - Link Text (Double line break separator)" | ||
}, | ||
"clear_clipboard": { | ||
@@ -45,2 +54,20 @@ "message": "Clear Clipboard", | ||
}, | ||
"noSeparatorLinkText_title": { | ||
"message": "No separator (link text)" | ||
}, | ||
"noSeparatorLinkText_description": { | ||
"message": "Enable context menu for appending link text to clipboard without a separator between pasted items?" | ||
}, | ||
"lineBreakSeparatorLinkText_title": { | ||
"message": "Line break separator (link text)" | ||
}, | ||
"lineBreakSeparatorLinkText_description": { | ||
"message": "Enable context menu for appending link text to clipboard with a line break separator between pasted items (\"\\n\" for text and \"<br />\\n\" for HTML)?" | ||
}, | ||
"doubleLineBreakSeparatorLinkText_title": { | ||
"message": "Double line break separator (link text)" | ||
}, | ||
"doubleLineBreakSeparatorLinkText_description": { | ||
"message": "Enable context menu for appending link text to clipboard with a double line break separator between pasted items (\"\\n\\n\" for text and \"<br /><br />\\n\\n\" for HTML)?" | ||
}, | ||
"clearClipboard_title": { | ||
@@ -47,0 +74,0 @@ "message": "Clear Clipboard", |
@@ -0,1 +1,6 @@ | ||
# 2.2.0 | ||
- Enhancement: Support appending link text or location (or | ||
both for `text/html` format) | ||
# 2.1.0 | ||
@@ -2,0 +7,0 @@ |
@@ -35,2 +35,5 @@ /* eslint-env browser */ | ||
}; | ||
clipboardMethodMap.noSeparatorLinkText = clipboardMethodMap.noSeparator; | ||
clipboardMethodMap.lineBreakSeparatorLinkText = clipboardMethodMap.lineBreakSeparator; | ||
clipboardMethodMap.doubleLineBreakSeparatorLinkText = clipboardMethodMap.doubleLineBreakSeparator; | ||
@@ -129,23 +132,35 @@ // Adapted from MIT-licensed: https://github.com/NiklasGollenstede/es6lib/blob/master/dom.js#L162 | ||
async function append (typesToSeparators) { | ||
async function append (typesToSeparators, linkText, linkUrl, menuItemId) { | ||
// Due to https://bugzilla.mozilla.org/show_bug.cgi?id=85686 , we cannot | ||
// use `getSelection` alone | ||
let typeToSelection; | ||
const activeElem = document.activeElement; | ||
if (['textarea', 'input'].includes(activeElem.nodeName.toLowerCase())) { | ||
const sel = activeElem.value.slice(activeElem.selectionStart, activeElem.selectionEnd); | ||
if (linkText && menuItemId.endsWith('LinkText')) { | ||
typeToSelection = { | ||
'text/plain': sel, | ||
'text/html': sel | ||
'text/plain': linkText, | ||
'text/html': linkText | ||
}; | ||
} else if (linkUrl) { | ||
typeToSelection = { | ||
'text/plain': linkUrl, | ||
'text/html': `<a href="${linkUrl}">${linkText || linkUrl}</a>` | ||
}; | ||
} else { | ||
const sel = window.getSelection(); | ||
const container = document.createElement('div'); | ||
for (let i = 0; i < sel.rangeCount; i++) { | ||
container.append(sel.getRangeAt(i).cloneContents()); | ||
const activeElem = document.activeElement; | ||
if (['textarea', 'input'].includes(activeElem.nodeName.toLowerCase())) { | ||
const sel = activeElem.value.slice(activeElem.selectionStart, activeElem.selectionEnd); | ||
typeToSelection = { | ||
'text/plain': sel, | ||
'text/html': sel | ||
}; | ||
} else { | ||
const sel = window.getSelection(); | ||
const container = document.createElement('div'); | ||
for (let i = 0; i < sel.rangeCount; i++) { | ||
container.append(sel.getRangeAt(i).cloneContents()); | ||
} | ||
typeToSelection = { | ||
'text/plain': sel.toString(), | ||
'text/html': container.innerHTML | ||
}; | ||
} | ||
typeToSelection = { | ||
'text/plain': sel.toString(), | ||
'text/html': container.innerHTML | ||
}; | ||
} | ||
@@ -164,3 +179,3 @@ | ||
// https://github.com/standard/standard/issues/614 | ||
window.appendToClipboard = async function appendToClipboard (menuItemId) { | ||
window.appendToClipboard = async function appendToClipboard (menuItemId, linkText, linkUrl) { | ||
switch (menuItemId) { | ||
@@ -171,3 +186,3 @@ case 'clearClipboard': | ||
try { | ||
await append(clipboardMethodMap[menuItemId]); | ||
await append(clipboardMethodMap[menuItemId], linkText, linkUrl, menuItemId); | ||
} catch (err) { | ||
@@ -174,0 +189,0 @@ // Timed out |
@@ -11,8 +11,17 @@ /* eslint-env webextensions */ | ||
['doubleLineBreakSeparator', 'append_double_line_break'], | ||
['noSeparatorLinkText', 'append_no_separator_linktext', { | ||
contexts: ['link'] | ||
}], | ||
['lineBreakSeparatorLinkText', 'append_line_break_linktext', { | ||
contexts: ['link'] | ||
}], | ||
['doubleLineBreakSeparatorLinkText', 'append_double_line_break_linktext', { | ||
contexts: ['link'] | ||
}], | ||
['clearClipboard', 'clear_clipboard', { | ||
context: 'all' | ||
contexts: ['all'] | ||
}] | ||
]; | ||
async function updateContextMenus () { | ||
await Promise.all(contextMenus.map(async ([menuID, menuI18nKey, {context} = {context: 'selection'}]) => { | ||
await Promise.all(contextMenus.map(async ([menuID, menuI18nKey, {contexts} = {contexts: ['selection', 'link']}]) => { | ||
try { // Errs at least in Chrome when not present | ||
@@ -29,3 +38,3 @@ await browser.contextMenus.remove(menuID); | ||
title: _(menuI18nKey), | ||
contexts: [context] | ||
contexts | ||
}); | ||
@@ -47,3 +56,7 @@ } | ||
browser.contextMenus.onClicked.addListener(async ({menuItemId}, tab) => { | ||
const esc = (str) => { | ||
return str.replace(/"/g, '\\"').replace(/\r|\n/g, ''); | ||
}; | ||
browser.contextMenus.onClicked.addListener(async ({menuItemId, linkText, linkUrl}, tab) => { | ||
// Unfortunately, Firefox doesn't allow clipboard APIs (except image | ||
@@ -63,5 +76,5 @@ // setting) from background scripts, so we have to go through this | ||
allFrames: true, | ||
code: `appendToClipboard("${menuItemId}");`, | ||
code: `appendToClipboard("${menuItemId}", "${esc(linkText || '')}", "${esc(linkUrl || '')}");`, | ||
runAt: 'document_end' | ||
}); | ||
}); |
/* eslint-env browser, webextensions */ | ||
/* globals jml */ | ||
'use strict'; | ||
import jml from './jml.js'; | ||
@@ -15,2 +14,5 @@ function _ (...args) { | ||
['doubleLineBreakSeparator'], | ||
['noSeparatorLinkText'], | ||
['lineBreakSeparatorLinkText'], | ||
['doubleLineBreakSeparatorLinkText'], | ||
['clearClipboard'] | ||
@@ -17,0 +19,0 @@ ].map(async ([preferenceKey]) => { |
@@ -7,3 +7,3 @@ { | ||
"license": "MIT", | ||
"version": "2.1.0", | ||
"version": "2.2.0", | ||
"keywords": [ | ||
@@ -28,3 +28,3 @@ "webextension", | ||
"eslint-plugin-standard": "3.1.0", | ||
"jamilih": "0.34.0", | ||
"jamilih": "0.35.0", | ||
"webextension-polyfill": "^0.2.1" | ||
@@ -41,5 +41,5 @@ }, | ||
"eslint": "eslint .", | ||
"copy-jamilih": "cp node_modules/jamilih/dist/jml-noinnerh.js options/jml.js", | ||
"copy-jamilih": "cp node_modules/jamilih/dist/jml-es-noinnerh.js options/jml.js", | ||
"copy-polyfill": "cp node_modules/webextension-polyfill/dist/browser-polyfill.min.js polyfills/browser-polyfill.min.js" | ||
} | ||
} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1899
94296