Skip to content

Commit 99199c6

Browse files
committed
Improve importing files from pasted HTML
1 parent bbbf9e6 commit 99199c6

File tree

1 file changed

+33
-7
lines changed

1 file changed

+33
-7
lines changed

src/gui/gui-import-control.mjs

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ function DropControl(gui, el, cb) {
1717
.on('drop', ondrop)
1818
.on('paste', onpaste);
1919
area.node().addEventListener('paste', onpaste);
20+
// TODO: use same function for drop and paste
2021
function ondrop(e) {
2122
var files = e.dataTransfer.files;
2223
var types = e.dataTransfer.types;
@@ -27,7 +28,7 @@ function DropControl(gui, el, cb) {
2728
cb(e.dataTransfer.getData('text/uri-list').split(','));
2829
} else if (types.includes('text/html')) {
2930
// drag-dropping a highlighted link may pull in a chunk of html
30-
var urls = e.dataTransfer.getData('text/html').match(/https?:[^"']+/);
31+
var urls = pastedHtmlToUrls(e.dataTransfer.getData('text/html'));
3132
if (urls.length) {
3233
cb(urls);
3334
}
@@ -36,7 +37,7 @@ function DropControl(gui, el, cb) {
3637
function onpaste(e) {
3738
var types = Array.from(e.clipboardData.types || []).join(',');
3839
var items = Array.from(e.clipboardData.items || []);
39-
var files;
40+
var files, str, urls;
4041
if (GUI.textIsSelected()) {
4142
// user is probably pasting text into an editable text field
4243
return;
@@ -52,12 +53,22 @@ function DropControl(gui, el, cb) {
5253
// formatted text can be available as both text/plain and text/html (e.g.
5354
// a JSON data object copied from a GitHub issue).
5455
//
56+
57+
// if html is present, it could be data (e.g. from Google Sheets) or a pasted link.
58+
// first we check for a link
59+
if (types.includes('text/html')) {
60+
urls = pastedHtmlToUrls(e.clipboardData.getData('text/html'));
61+
if (urls.length) {
62+
return cb(urls);
63+
}
64+
}
5565
if (types.includes('text/plain')) {
5666
// text from clipboard (supported by Chrome, FF, Safari)
5767
// TODO: handle FF case of string containing multiple file names.
58-
var str = e.clipboardData.getData('text/plain');
59-
if (isUrl(str)) {
60-
return cb(str.split(','));
68+
str = e.clipboardData.getData('text/plain');
69+
urls = pastedTextToUrls(str);
70+
if (urls.length) {
71+
return cb(urls);
6172
}
6273
files = [pastedTextToFile(str)];
6374
} else {
@@ -79,6 +90,21 @@ function DropControl(gui, el, cb) {
7990
}
8091
}
8192

93+
function pastedHtmlToUrls(html) {
94+
var hrefRegex = /href\s*=\s*["']([^"']+)["']/gi;
95+
var matches = html.matchAll(hrefRegex);
96+
var urls = Array.from(matches, match => match[1]);
97+
return urls;
98+
}
99+
100+
function pastedTextToUrls(str) {
101+
if (!looksLikeUrl(str)) return [];
102+
var regex = /https?:\/\/[^\s]+?(?=[\s,]|$)/g;
103+
var matches = str.matchAll(regex);
104+
var urls = Array.from(matches, match => match[0]);
105+
return urls;
106+
}
107+
82108
function pastedTextToFile(str) {
83109
var type = internal.guessInputContentType(str);
84110
var name;
@@ -93,7 +119,7 @@ function pastedTextToFile(str) {
93119
return new File([blob], name);
94120
}
95121

96-
function isUrl(str) {
122+
function looksLikeUrl(str) {
97123
return /^https?:\/\//.test(str);
98124
}
99125

@@ -421,7 +447,7 @@ export function ImportControl(gui, opts) {
421447
function prepFilesForDownload(names) {
422448
var items = names.map(function(name) {
423449
var item = {name: name};
424-
if (isUrl(name)) {
450+
if (looksLikeUrl(name)) {
425451
item.url = name;
426452
item.basename = GUI.getUrlFilename(name);
427453

0 commit comments

Comments
 (0)