From 2908884202c38144e3104cbce11a2018c3852cb3 Mon Sep 17 00:00:00 2001 From: Baptiste Augrain Date: Sun, 25 Nov 2018 15:56:11 +0100 Subject: [PATCH 1/8] drag and drop image from browser --- .../main/lib/dataApi/attachmentManagement.js | 88 ++++++++++++++----- 1 file changed, 65 insertions(+), 23 deletions(-) diff --git a/browser/main/lib/dataApi/attachmentManagement.js b/browser/main/lib/dataApi/attachmentManagement.js index c193eaf2..fa2283f4 100644 --- a/browser/main/lib/dataApi/attachmentManagement.js +++ b/browser/main/lib/dataApi/attachmentManagement.js @@ -18,15 +18,23 @@ const PATH_SEPARATORS = escapeStringRegexp(path.posix.sep) + escapeStringRegexp( * @returns {Promise} Image element created */ function getImage (file) { - return new Promise((resolve) => { - const reader = new FileReader() - const img = new Image() - img.onload = () => resolve(img) - reader.onload = e => { - img.src = e.target.result - } - reader.readAsDataURL(file) - }) + if (_.isString(file)) { + return new Promise(resolve => { + const img = new Image() + img.onload = () => resolve(img) + img.src = file + }) + } else { + return new Promise(resolve => { + const reader = new FileReader() + const img = new Image() + img.onload = () => resolve(img) + reader.onload = e => { + img.src = e.target.result + } + reader.readAsDataURL(file) + }) + } } /** @@ -253,23 +261,57 @@ function generateAttachmentMarkdown (fileName, path, showPreview) { * @param {Event} dropEvent DropEvent */ function handleAttachmentDrop (codeEditor, storageKey, noteKey, dropEvent) { - const file = dropEvent.dataTransfer.files[0] - const filePath = file.path - const originalFileName = path.basename(filePath) - const fileType = file['type'] - const isImage = fileType.startsWith('image') - let promise - if (isImage) { - promise = fixRotate(file).then(base64data => { - return copyAttachment({type: 'base64', data: base64data, sourceFilePath: filePath}, storageKey, noteKey) + if (dropEvent.dataTransfer.files.length > 0) { + const file = dropEvent.dataTransfer.files[0] + const filePath = file.path + const originalFileName = path.basename(filePath) + const fileType = file['type'] + const isImage = fileType.startsWith('image') + let promise + if (isImage) { + console.log(file) + promise = fixRotate(file).then(base64data => { + return copyAttachment({type: 'base64', data: base64data, sourceFilePath: filePath}, storageKey, noteKey) + }) + } else { + promise = copyAttachment(filePath, storageKey, noteKey) + } + promise.then((fileName) => { + const imageMd = generateAttachmentMarkdown(originalFileName, path.join(STORAGE_FOLDER_PLACEHOLDER, noteKey, fileName), isImage) + codeEditor.insertAttachmentMd(imageMd) }) } else { - promise = copyAttachment(filePath, storageKey, noteKey) + for (let i = 0; i < dropEvent.dataTransfer.items.length; i++) { + const item = dropEvent.dataTransfer.items[i] + + if (item.type === 'text/html') { + const html = dropEvent.dataTransfer.getData('text/html') + + const match = /]*src="([^"]+)"/.exec(html) + if (match) { + const imageURL = match[1] + + getImage(imageURL) + .then(image => { + const canvas = document.createElement('canvas') + const context = canvas.getContext('2d') + canvas.width = image.width + canvas.height = image.height + context.drawImage(image, 0, 0) + + return copyAttachment({type: 'base64', data: canvas.toDataURL(), sourceFilePath: imageURL}, storageKey, noteKey) + }) + .then(fileName => { + const imageMd = generateAttachmentMarkdown(imageURL, path.join(STORAGE_FOLDER_PLACEHOLDER, noteKey, fileName), true) + + codeEditor.insertAttachmentMd(imageMd) + }) + + break + } + } + } } - promise.then((fileName) => { - const imageMd = generateAttachmentMarkdown(originalFileName, path.join(STORAGE_FOLDER_PLACEHOLDER, noteKey, fileName), isImage) - codeEditor.insertAttachmentMd(imageMd) - }) } /** From c2e4bae9ddf6a247077e2d41af5137e98710953d Mon Sep 17 00:00:00 2001 From: Baptiste Augrain Date: Wed, 28 Nov 2018 15:00:29 +0100 Subject: [PATCH 2/8] fix regex to correctly match the `src` attribute when there is a `data-src` attribute --- browser/main/lib/dataApi/attachmentManagement.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/main/lib/dataApi/attachmentManagement.js b/browser/main/lib/dataApi/attachmentManagement.js index fa2283f4..a2bc023a 100644 --- a/browser/main/lib/dataApi/attachmentManagement.js +++ b/browser/main/lib/dataApi/attachmentManagement.js @@ -287,7 +287,7 @@ function handleAttachmentDrop (codeEditor, storageKey, noteKey, dropEvent) { if (item.type === 'text/html') { const html = dropEvent.dataTransfer.getData('text/html') - const match = /]*src="([^"]+)"/.exec(html) + const match = /]*[\s"']src="([^"]+)"/.exec(html) if (match) { const imageURL = match[1] From 900f20f164276166046000e8875bdf3bdee258df Mon Sep 17 00:00:00 2001 From: Baptiste Augrain Date: Wed, 28 Nov 2018 15:58:58 +0100 Subject: [PATCH 3/8] handle all dropped images --- .../main/lib/dataApi/attachmentManagement.js | 63 ++++++++++--------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/browser/main/lib/dataApi/attachmentManagement.js b/browser/main/lib/dataApi/attachmentManagement.js index a2bc023a..dca82c7a 100644 --- a/browser/main/lib/dataApi/attachmentManagement.js +++ b/browser/main/lib/dataApi/attachmentManagement.js @@ -261,29 +261,28 @@ function generateAttachmentMarkdown (fileName, path, showPreview) { * @param {Event} dropEvent DropEvent */ function handleAttachmentDrop (codeEditor, storageKey, noteKey, dropEvent) { + let promise if (dropEvent.dataTransfer.files.length > 0) { - const file = dropEvent.dataTransfer.files[0] - const filePath = file.path - const originalFileName = path.basename(filePath) - const fileType = file['type'] - const isImage = fileType.startsWith('image') - let promise - if (isImage) { - console.log(file) - promise = fixRotate(file).then(base64data => { - return copyAttachment({type: 'base64', data: base64data, sourceFilePath: filePath}, storageKey, noteKey) - }) - } else { - promise = copyAttachment(filePath, storageKey, noteKey) - } - promise.then((fileName) => { - const imageMd = generateAttachmentMarkdown(originalFileName, path.join(STORAGE_FOLDER_PLACEHOLDER, noteKey, fileName), isImage) - codeEditor.insertAttachmentMd(imageMd) - }) + promise = Promise.all(Array.from(dropEvent.dataTransfer.files).map(file => { + if (file['type'].startsWith('image')) { + return fixRotate(file) + .then(data => copyAttachment({type: 'base64', data: data, sourceFilePath: file.path}, storageKey, noteKey) + .then(fileName => ({ + fileName, + title: path.basename(file.path), + isImage: true + })) + ) + } else { + return copyAttachment(file.path, storageKey, noteKey).then(fileName => ({ + fileName, + title: path.basename(file.path), + isImage: false + })) + } + })) } else { - for (let i = 0; i < dropEvent.dataTransfer.items.length; i++) { - const item = dropEvent.dataTransfer.items[i] - + promise = Promise.all(Array.from(dropEvent.dataTransfer.items).map(item => { if (item.type === 'text/html') { const html = dropEvent.dataTransfer.getData('text/html') @@ -291,7 +290,7 @@ function handleAttachmentDrop (codeEditor, storageKey, noteKey, dropEvent) { if (match) { const imageURL = match[1] - getImage(imageURL) + return getImage(imageURL) .then(image => { const canvas = document.createElement('canvas') const context = canvas.getContext('2d') @@ -301,17 +300,21 @@ function handleAttachmentDrop (codeEditor, storageKey, noteKey, dropEvent) { return copyAttachment({type: 'base64', data: canvas.toDataURL(), sourceFilePath: imageURL}, storageKey, noteKey) }) - .then(fileName => { - const imageMd = generateAttachmentMarkdown(imageURL, path.join(STORAGE_FOLDER_PLACEHOLDER, noteKey, fileName), true) - - codeEditor.insertAttachmentMd(imageMd) - }) - - break + .then(fileName => ({ + fileName, + title: imageURL, + isImage: true + })) } } - } + })) } + + promise.then(files => { + const attachments = files.filter(file => !!file).map(file => generateAttachmentMarkdown(file.title, path.join(STORAGE_FOLDER_PLACEHOLDER, noteKey, file.fileName), file.isImage)) + + codeEditor.insertAttachmentMd(attachments.join('\n')) + }) } /** From 851d3ba159eb5aa1fe38fb60aca9408b4c8692d6 Mon Sep 17 00:00:00 2001 From: Baptiste Augrain Date: Thu, 31 Jan 2019 23:26:31 +0100 Subject: [PATCH 4/8] fix image path when the dropped image's url contains a query --- browser/main/lib/dataApi/attachmentManagement.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/browser/main/lib/dataApi/attachmentManagement.js b/browser/main/lib/dataApi/attachmentManagement.js index dca82c7a..12e6eb31 100644 --- a/browser/main/lib/dataApi/attachmentManagement.js +++ b/browser/main/lib/dataApi/attachmentManagement.js @@ -6,6 +6,7 @@ const mdurl = require('mdurl') const fse = require('fs-extra') const escapeStringRegexp = require('escape-string-regexp') const sander = require('sander') +const url = require('url') import i18n from 'browser/lib/i18n' const STORAGE_FOLDER_PLACEHOLDER = ':storage' @@ -159,16 +160,21 @@ function copyAttachment (sourceFilePath, storageKey, noteKey, useRandomName = tr try { const isBase64 = typeof sourceFilePath === 'object' && sourceFilePath.type === 'base64' - if (!fs.existsSync(sourceFilePath) && !isBase64) { + if (!isBase64 && !fs.existsSync(sourceFilePath)) { return reject('source file does not exist') } - const targetStorage = findStorage.findStorage(storageKey) + + const sourcePath = sourceFilePath.sourceFilePath || sourceFilePath + const sourceURL = url.parse(/^\w+:\/\//.test(sourcePath) ? sourcePath : 'file:///' + sourcePath) + let destinationName if (useRandomName) { - destinationName = `${uniqueSlug()}${path.extname(sourceFilePath.sourceFilePath || sourceFilePath)}` + destinationName = `${uniqueSlug()}${path.extname(sourceURL.pathname) || '.png'}` } else { - destinationName = path.basename(sourceFilePath.sourceFilePath || sourceFilePath) + destinationName = path.basename(sourceURL.pathname) } + + const targetStorage = findStorage.findStorage(storageKey) const destinationDir = path.join(targetStorage.path, DESTINATION_FOLDER, noteKey) createAttachmentDestinationFolder(targetStorage.path, noteKey) const outputFile = fs.createWriteStream(path.join(destinationDir, destinationName)) From 215484c19ae09f4109de889af494301659367daf Mon Sep 17 00:00:00 2001 From: Baptiste Augrain Date: Fri, 1 Feb 2019 16:27:47 +0100 Subject: [PATCH 5/8] add tests --- .../main/lib/dataApi/attachmentManagement.js | 2 +- tests/dataApi/attachmentManagement.test.js | 152 +++++++++++++++++- 2 files changed, 147 insertions(+), 7 deletions(-) diff --git a/browser/main/lib/dataApi/attachmentManagement.js b/browser/main/lib/dataApi/attachmentManagement.js index 12e6eb31..56af58ed 100644 --- a/browser/main/lib/dataApi/attachmentManagement.js +++ b/browser/main/lib/dataApi/attachmentManagement.js @@ -181,7 +181,7 @@ function copyAttachment (sourceFilePath, storageKey, noteKey, useRandomName = tr if (isBase64) { const base64Data = sourceFilePath.data.replace(/^data:image\/\w+;base64,/, '') - const dataBuffer = new Buffer(base64Data, 'base64') + const dataBuffer = Buffer.from(base64Data, 'base64') outputFile.write(dataBuffer, () => { resolve(destinationName) }) diff --git a/tests/dataApi/attachmentManagement.test.js b/tests/dataApi/attachmentManagement.test.js index a4cc8082..38b863de 100644 --- a/tests/dataApi/attachmentManagement.test.js +++ b/tests/dataApi/attachmentManagement.test.js @@ -38,7 +38,7 @@ it('should test that copyAttachment should throw an error if sourcePath dosen\'t fs.existsSync = jest.fn() fs.existsSync.mockReturnValue(false) - systemUnderTest.copyAttachment('path', 'storageKey', 'noteKey').then(() => {}, error => { + return systemUnderTest.copyAttachment('path', 'storageKey', 'noteKey').then(() => {}, error => { expect(error).toBe('source file does not exist') expect(fs.existsSync).toHaveBeenCalledWith('path') }) @@ -64,7 +64,7 @@ it('should test that copyAttachment works correctly assuming correct working of findStorage.findStorage.mockReturnValue(dummyStorage) uniqueSlug.mockReturnValue(dummyUniquePath) - systemUnderTest.copyAttachment(sourcePath, storageKey, noteKey).then( + return systemUnderTest.copyAttachment(sourcePath, storageKey, noteKey).then( function (newFileName) { expect(findStorage.findStorage).toHaveBeenCalledWith(storageKey) expect(fs.createReadStream).toHaveBeenCalledWith(sourcePath) @@ -83,7 +83,7 @@ it('should test that copyAttachment creates a new folder if the attachment folde const dummyReadStream = {} dummyReadStream.pipe = jest.fn() - dummyReadStream.on = jest.fn() + dummyReadStream.on = jest.fn((event, callback) => { callback() }) fs.createReadStream = jest.fn(() => dummyReadStream) fs.existsSync = jest.fn() fs.existsSync.mockReturnValueOnce(true) @@ -95,7 +95,7 @@ it('should test that copyAttachment creates a new folder if the attachment folde findStorage.findStorage.mockReturnValue(dummyStorage) uniqueSlug.mockReturnValue('dummyPath') - systemUnderTest.copyAttachment('path', 'storageKey', 'noteKey').then( + return systemUnderTest.copyAttachment('path', 'storageKey', 'noteKey').then( function () { expect(fs.existsSync).toHaveBeenCalledWith(attachmentFolderPath) expect(fs.mkdirSync).toHaveBeenCalledWith(attachmentFolderPath) @@ -109,7 +109,7 @@ it('should test that copyAttachment don\'t uses a random file name if not intend const dummyReadStream = {} dummyReadStream.pipe = jest.fn() - dummyReadStream.on = jest.fn() + dummyReadStream.on = jest.fn((event, callback) => { callback() }) fs.createReadStream = jest.fn(() => dummyReadStream) fs.existsSync = jest.fn() fs.existsSync.mockReturnValueOnce(true) @@ -120,12 +120,152 @@ it('should test that copyAttachment don\'t uses a random file name if not intend findStorage.findStorage.mockReturnValue(dummyStorage) uniqueSlug.mockReturnValue('dummyPath') - systemUnderTest.copyAttachment('path', 'storageKey', 'noteKey', false).then( + return systemUnderTest.copyAttachment('path', 'storageKey', 'noteKey', false).then( function (newFileName) { expect(newFileName).toBe('path') }) }) +it('should test that copyAttachment with url (with extension, without query)', function () { + const dummyStorage = {path: 'dummyStoragePath'} + + const dummyReadStream = { + pipe: jest.fn(), + on: jest.fn((event, callback) => { callback() }) + } + fs.createReadStream = jest.fn(() => dummyReadStream) + + const dummyWriteStream = { + write: jest.fn((data, callback) => { callback() }) + } + fs.createWriteStream = jest.fn(() => dummyWriteStream) + + fs.existsSync = jest.fn() + fs.existsSync.mockReturnValueOnce(true) + fs.existsSync.mockReturnValueOnce(false) + fs.mkdirSync = jest.fn() + + findStorage.findStorage = jest.fn() + findStorage.findStorage.mockReturnValue(dummyStorage) + uniqueSlug.mockReturnValue('dummyPath') + + const sourcePath = { + sourceFilePath: 'http://www.foo.bar/baz/qux.jpg', + type: 'base64', + data: 'data:image/jpeg;base64,Ym9vc3Rub3Rl' + } + + return systemUnderTest.copyAttachment(sourcePath, 'storageKey', 'noteKey').then( + function (newFileName) { + expect(newFileName).toBe('dummyPath.jpg') + }) +}) + +it('should test that copyAttachment with url (with extension, with query)', function () { + const dummyStorage = {path: 'dummyStoragePath'} + + const dummyReadStream = { + pipe: jest.fn(), + on: jest.fn((event, callback) => { callback() }) + } + fs.createReadStream = jest.fn(() => dummyReadStream) + + const dummyWriteStream = { + write: jest.fn((data, callback) => { callback() }) + } + fs.createWriteStream = jest.fn(() => dummyWriteStream) + + fs.existsSync = jest.fn() + fs.existsSync.mockReturnValueOnce(true) + fs.existsSync.mockReturnValueOnce(false) + fs.mkdirSync = jest.fn() + + findStorage.findStorage = jest.fn() + findStorage.findStorage.mockReturnValue(dummyStorage) + uniqueSlug.mockReturnValue('dummyPath') + + const sourcePath = { + sourceFilePath: 'http://www.foo.bar/baz/qux.jpg?h=1080', + type: 'base64', + data: 'data:image/jpeg;base64,Ym9vc3Rub3Rl' + } + + return systemUnderTest.copyAttachment(sourcePath, 'storageKey', 'noteKey').then( + function (newFileName) { + expect(newFileName).toBe('dummyPath.jpg') + }) +}) + +it('should test that copyAttachment with url (without extension, without query)', function () { + const dummyStorage = {path: 'dummyStoragePath'} + + const dummyReadStream = { + pipe: jest.fn(), + on: jest.fn((event, callback) => { callback() }) + } + fs.createReadStream = jest.fn(() => dummyReadStream) + + const dummyWriteStream = { + write: jest.fn((data, callback) => { callback() }) + } + fs.createWriteStream = jest.fn(() => dummyWriteStream) + + fs.existsSync = jest.fn() + fs.existsSync.mockReturnValueOnce(true) + fs.existsSync.mockReturnValueOnce(false) + fs.mkdirSync = jest.fn() + + findStorage.findStorage = jest.fn() + findStorage.findStorage.mockReturnValue(dummyStorage) + uniqueSlug.mockReturnValue('dummyPath') + + const sourcePath = { + sourceFilePath: 'http://www.foo.bar/baz/qux', + type: 'base64', + data: 'data:image/jpeg;base64,Ym9vc3Rub3Rl' + } + + return systemUnderTest.copyAttachment(sourcePath, 'storageKey', 'noteKey').then( + function (newFileName) { + expect(newFileName).toBe('dummyPath.png') + }) +}) + +it('should test that copyAttachment with url (without extension, with query)', function () { + const dummyStorage = {path: 'dummyStoragePath'} + + const dummyReadStream = { + pipe: jest.fn(), + on: jest.fn((event, callback) => { callback() }) + } + fs.createReadStream = jest.fn(() => dummyReadStream) + + const dummyWriteStream = { + write: jest.fn((data, callback) => { callback() }) + } + fs.createWriteStream = jest.fn(() => dummyWriteStream) + + fs.existsSync = jest.fn() + fs.existsSync.mockReturnValueOnce(true) + fs.existsSync.mockReturnValueOnce(false) + fs.mkdirSync = jest.fn() + + findStorage.findStorage = jest.fn() + findStorage.findStorage.mockReturnValue(dummyStorage) + uniqueSlug.mockReturnValue('dummyPath') + + const sourcePath = { + sourceFilePath: 'http://www.foo.bar/baz/qux?h=1080', + type: 'base64', + data: 'data:image/jpeg;base64,Ym9vc3Rub3Rl' + } + + return systemUnderTest.copyAttachment(sourcePath, 'storageKey', 'noteKey').then( + function (newFileName) { + expect(newFileName).toBe('dummyPath.png') + }) +}) + it('should replace the all ":storage" path with the actual storage path', function () { const storageFolder = systemUnderTest.DESTINATION_FOLDER const testInput = From de76f55fe26f608b837b52349e2ba7e6848f967a Mon Sep 17 00:00:00 2001 From: Baptiste Augrain Date: Mon, 4 Feb 2019 13:54:45 +0100 Subject: [PATCH 6/8] fix gif --- .../main/lib/dataApi/attachmentManagement.js | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/browser/main/lib/dataApi/attachmentManagement.js b/browser/main/lib/dataApi/attachmentManagement.js index 5206e9ea..ff3621f0 100644 --- a/browser/main/lib/dataApi/attachmentManagement.js +++ b/browser/main/lib/dataApi/attachmentManagement.js @@ -278,15 +278,23 @@ function handleAttachmentDrop (codeEditor, storageKey, noteKey, dropEvent) { let promise if (dropEvent.dataTransfer.files.length > 0) { promise = Promise.all(Array.from(dropEvent.dataTransfer.files).map(file => { - if (file['type'].startsWith('image') && !file['type'].endsWith('gif')) { - return fixRotate(file) - .then(data => copyAttachment({type: 'base64', data: data, sourceFilePath: file.path}, storageKey, noteKey) - .then(fileName => ({ - fileName, - title: path.basename(file.path), - isImage: true - })) - ) + if (file.type.startsWith('image')) { + if (file.type.endsWith('gif')) { + return copyAttachment(file.path, storageKey, noteKey).then(fileName => ({ + fileName, + title: path.basename(file.path), + isImage: true + })) + } else { + return fixRotate(file) + .then(data => copyAttachment({type: 'base64', data: data, sourceFilePath: file.path}, storageKey, noteKey) + .then(fileName => ({ + fileName, + title: path.basename(file.path), + isImage: true + })) + ) + } } else { return copyAttachment(file.path, storageKey, noteKey).then(fileName => ({ fileName, From 10ea5d00eb2065ca936348e364c76769180dbdc7 Mon Sep 17 00:00:00 2001 From: Baptiste Augrain Date: Mon, 4 Feb 2019 14:09:11 +0100 Subject: [PATCH 7/8] avoid converting SVG --- browser/main/lib/dataApi/attachmentManagement.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/main/lib/dataApi/attachmentManagement.js b/browser/main/lib/dataApi/attachmentManagement.js index ff3621f0..c173845d 100644 --- a/browser/main/lib/dataApi/attachmentManagement.js +++ b/browser/main/lib/dataApi/attachmentManagement.js @@ -279,7 +279,7 @@ function handleAttachmentDrop (codeEditor, storageKey, noteKey, dropEvent) { if (dropEvent.dataTransfer.files.length > 0) { promise = Promise.all(Array.from(dropEvent.dataTransfer.files).map(file => { if (file.type.startsWith('image')) { - if (file.type.endsWith('gif')) { + if (file.type === 'image/gif' || file.type === 'image/svg+xml') { return copyAttachment(file.path, storageKey, noteKey).then(fileName => ({ fileName, title: path.basename(file.path), From e0d9cf7f5c2e7fa7da943f38d508662ef1c34b9a Mon Sep 17 00:00:00 2001 From: Baptiste Augrain Date: Mon, 4 Feb 2019 18:22:10 +0100 Subject: [PATCH 8/8] fix dropping image from Firefox on Linux --- .../main/lib/dataApi/attachmentManagement.js | 50 ++++++++++--------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/browser/main/lib/dataApi/attachmentManagement.js b/browser/main/lib/dataApi/attachmentManagement.js index c173845d..6fa3b51f 100644 --- a/browser/main/lib/dataApi/attachmentManagement.js +++ b/browser/main/lib/dataApi/attachmentManagement.js @@ -304,32 +304,34 @@ function handleAttachmentDrop (codeEditor, storageKey, noteKey, dropEvent) { } })) } else { - promise = Promise.all(Array.from(dropEvent.dataTransfer.items).map(item => { - if (item.type === 'text/html') { - const html = dropEvent.dataTransfer.getData('text/html') + let imageURL = dropEvent.dataTransfer.getData('text/plain') - const match = /]*[\s"']src="([^"]+)"/.exec(html) - if (match) { - const imageURL = match[1] - - return getImage(imageURL) - .then(image => { - const canvas = document.createElement('canvas') - const context = canvas.getContext('2d') - canvas.width = image.width - canvas.height = image.height - context.drawImage(image, 0, 0) - - return copyAttachment({type: 'base64', data: canvas.toDataURL(), sourceFilePath: imageURL}, storageKey, noteKey) - }) - .then(fileName => ({ - fileName, - title: imageURL, - isImage: true - })) - } + if (!imageURL) { + const match = /]*[\s"']src="([^"]+)"/.exec(dropEvent.dataTransfer.getData('text/html')) + if (match) { + imageURL = match[1] } - })) + } + + if (!imageURL) { + return + } + + promise = Promise.all([getImage(imageURL) + .then(image => { + const canvas = document.createElement('canvas') + const context = canvas.getContext('2d') + canvas.width = image.width + canvas.height = image.height + context.drawImage(image, 0, 0) + + return copyAttachment({type: 'base64', data: canvas.toDataURL(), sourceFilePath: imageURL}, storageKey, noteKey) + }) + .then(fileName => ({ + fileName, + title: imageURL, + isImage: true + }))]) } promise.then(files => {