diff --git a/package.json b/package.json index 485e37d0..808d534a 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,7 @@ "babel-plugin-transform-es2015-modules-commonjs": "^6.26.2", "babel-plugin-transform-object-rest-spread": "^6.26.0", "babel-preset-shopify": "^16.5.0", + "canvas": "^1.6.13", "codecov": "^3.0.2", "concurrently": "^3.5.1", "core-js": "^2.5.7", diff --git a/src/Draggable/Draggable.js b/src/Draggable/Draggable.js index 097ff8f1..e1e56359 100644 --- a/src/Draggable/Draggable.js +++ b/src/Draggable/Draggable.js @@ -1,4 +1,4 @@ -import {closest} from 'shared/utils'; +import {closest, cloneNode} from 'shared/utils'; import {Announcement, Focusable, Mirror, Scrollable} from './Plugins'; @@ -374,7 +374,7 @@ export default class Draggable { this.lastPlacedContainer.classList.remove(this.getClassNameFor('container:placed')); } - this.source = this.originalSource.cloneNode(true); + this.source = cloneNode(this.originalSource, true); this.originalSource.parentNode.insertBefore(this.source, this.originalSource); this.originalSource.style.display = 'none'; diff --git a/src/Draggable/Plugins/Mirror/Mirror.js b/src/Draggable/Plugins/Mirror/Mirror.js index 4c82e15c..185cff9c 100644 --- a/src/Draggable/Plugins/Mirror/Mirror.js +++ b/src/Draggable/Plugins/Mirror/Mirror.js @@ -1,4 +1,5 @@ import AbstractPlugin from 'shared/AbstractPlugin'; +import {cloneNode} from 'shared/utils'; import { MirrorCreateEvent, @@ -163,7 +164,7 @@ export default class Mirror extends AbstractPlugin { } const appendableContainer = this[getAppendableContainer](source) || sourceContainer; - this.mirror = source.cloneNode(true); + this.mirror = cloneNode(source, true); const mirrorCreatedEvent = new MirrorCreatedEvent({ source, diff --git a/src/shared/utils/cloneNode/cloneNode.js b/src/shared/utils/cloneNode/cloneNode.js new file mode 100644 index 00000000..ff58fad1 --- /dev/null +++ b/src/shared/utils/cloneNode/cloneNode.js @@ -0,0 +1,23 @@ +/** + * Get the new clone with canvas content cloned for a given node. + * + * @param {Node} node The node to clone + * @param {Boolean} deep equal to the deep parameter of Node.cloneNode(), default false + * @return {Node} new clone with canvas content cloned + */ +export default function cloneNode(node, deep = false) { + const newClone = node.cloneNode(deep); + let canvases; + let newCanvases; + if (node.tagName === 'CANVAS') { + canvases = [node]; + newCanvases = [newClone]; + } else { + canvases = node.querySelectorAll('canvas'); + newCanvases = newClone.querySelectorAll('canvas'); + } + newCanvases.forEach((newCanvas, i) => { + newCanvas.getContext('2d').drawImage(canvases[i], 0, 0); + }); + return newClone; +} diff --git a/src/shared/utils/cloneNode/index.js b/src/shared/utils/cloneNode/index.js new file mode 100644 index 00000000..b5bdd5cb --- /dev/null +++ b/src/shared/utils/cloneNode/index.js @@ -0,0 +1,3 @@ +import cloneNode from './cloneNode'; + +export default cloneNode; diff --git a/src/shared/utils/cloneNode/tests/cloneNode.test.js b/src/shared/utils/cloneNode/tests/cloneNode.test.js new file mode 100644 index 00000000..1a7ad3e2 --- /dev/null +++ b/src/shared/utils/cloneNode/tests/cloneNode.test.js @@ -0,0 +1,65 @@ +import {createSandbox} from 'helper'; +import cloneNode from '../cloneNode'; + +const sampleMarkup = ` +