Skip to content

Commit

Permalink
Add ability to adjust nodes before/after cloning children
Browse files Browse the repository at this point in the history
  • Loading branch information
IDisposable committed Feb 9, 2024
1 parent be3b447 commit 601f708
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 18 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"scripts": {
"format": "eslint src --fix && prettier --write .",
"lint": "eslint --max-warnings=0 src && prettier --check .",
"test": "grunt test",
"test": "grunt test --debug",
"build": "grunt",
"build:ci": "grunt ci",
"beta-version-patch": "npm version $(semver $npm_package_version -i prerelease --preid beta)",
Expand Down
24 changes: 23 additions & 1 deletion spec/dom-to-image-more.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,29 @@
assert.ok(domtoimage);
});

describe('regression', function () {
describe('features', function () {
it('should handle adjustClonedNode', function (done) {
function oncloned(_node, clone, after) {
/* jshint unused:false */
if(!after) {
if (clone.id === 'element') {
clone.style.transform = 'translateY(100px)';
}
}
return clone;
}

loadTestPage(
'eventing/dom-node.html',
'eventing/style.css',
'eventing/control-image'
)
.then(() => renderToPng(domNode(), { adjustClonedNode: oncloned }))
.then(check)
.then(done)
.catch(done);
});

it('should render to svg', function (done) {
loadTestPage(
'small/dom-node.html',
Expand Down
2 changes: 1 addition & 1 deletion spec/resources/background-clip/control-image

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion spec/resources/defaultStyles/control-image

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions spec/resources/eventing/control-image
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
data:image/png;base64,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gAABQXcDBAgQIEAgICDogRE9gQABAgQICLobIECAAAECAQFBD4zoCQQIECBAQNDdAAECBAgQCAgIemBETyBAgAABAoLuBggQIECAQEBA0AMjegIBAgQIEBB0N0CAAAECBAICgh4Y0RMIECBAgICguwECBAgQIBAQEPTAiJ5AgAABAgQE3Q0QIECAAIGAgKAHRvQEAgQIECAg6G6AAAECBAgEBAQ9MKInECBAgAABQXcDBAgQIEAgICDogRE9gQABAgQICLobIECAAAECAQFBD4zoCQQIECBAQNDdAAECBAgQCAgIemBETyBAgAABAoLuBggQIECAQEBA0AMjegIBAgQIEBB0N0CAAAECBAICgh4Y0RMIECBAgICguwECBAgQIBAQEPTAiJ5AgAABAgQE3Q0QIECAAIGAgKAHRvQEAgQIECAg6G6AAAECBAgEBAQ9MKInECBAgAABQXcDBAgQIEAgICDogRE9gQABAgQICLobIECAAAECAQFBD4zoCQQIECBAQNDdAAECBAgQCAgIemBETyBAgAABAoLuBggQIECAQEBA0AMjegIBAgQIEBB0N0CAAAECBAICgh4Y0RMIECBAgICguwECBAgQIBAQEPTAiJ5AgAABAgQE3Q0QIECAAIGAgKAHRvQEAgQIECAg6G6AAAECBAgEBAQ9MKInECBAgAABQXcDBAgQIEAgICDogRE9gQABAgQICLobIECAAAECAQFBD4zoCQQIECBAQNDdAAECBAgQCAgIemBETyBAgAABAoLuBggQIECAQEBA0AMjegIBAgQIEBB0N0CAAAECBAICgh4Y0RMIECBAgICguwECBAgQIBAQEPTAiJ5AgAABAgQE3Q0QIECAAIGAgKAHRvQEAgQIECAg6G6AAAECBAgEBAQ9MKInECBAgAABQXcDBAgQIEAgICDogRE9gQABAgQICLobIECAAAECAQFBD4zoCQQIECBAQNDdAAECBAgQCAgIemBETyBAgAABAoLuBggQIECAQEBA0AMjegIBAgQIEBB0N0CAAAECBAICgh4Y0RMIECBAgICguwECBAgQIBAQEPTAiJ5AgAABAgQE3Q0QIECAAIGAgKAHRvQEAgQIECAg6G6AAAECBAgEBAQ9MKInECBAgAABQXcDBAgQIEAgICDogRE9gQABAgQICLobIECAAAECAQFBD4zoCQQIECBAQNDdAAECBAgQCAgIemBETyBAgAABAoLuBggQIECAQEBA0AMjegIBAgQIEBB0N0CAAAECBAICgh4Y0RMIECBAgICguwECBAgQIBAQEPTAiJ5AgAABAgQE3Q0QIECAAIGAgKAHRvQEAgQIECAg6G6AAAECBAgEBAQ9MKInECBAgAABQXcDBAgQIEAgICDogRE9gQABAgQICLobIECAAAECAQFBD4zoCQQIECBAQNDdAAECBAgQCAgIemBETyBAgAABAoLuBggQIECAQEBA0AMjegIBAgQIEBB0N0CAAAECBAICgh4Y0RMIECBAgICguwECBAgQIBAQEPTAiJ5AgAABAgQE3Q0QIECAAIGAgKAHRvQEAgQIECAg6G6AAAECBAgEBAQ9MKInECBAgAABQXcDBAgQIEAgICDogRE9gQABAgQICLobIECAAAECAQFBD4zoCQQIECBAQNDdAAECBAgQCAgIemBETyBAgAABAoLuBggQIECAQEBA0AMjegIBAgQIEBB0N0CAAAECBAICgh4Y0RMIECBAgICguwECBAgQIBAQEPTAiJ5AgAABAgQE3Q0QIECAAIGAgKAHRvQEAgQIECAg6G6AAAECBAgEBAQ9MKInECBAgAABQXcDBAgQIEAgICDogRE9gQABAgQICLobIECAAAECAQFBD4zoCQQIECBAQNDdAAECBAgQCAgIemBETyBAgAABAoLuBggQIECAQEBA0AMjegIBAgQIEBB0N0CAAAECBAICgh4Y0RMIECBAgICguwECBAgQIBAQEPTAiJ5AgAABAgQE3Q0QIECAAIGAgKAHRvQEAgQIECAg6G6AAAECBAgEBAQ9MKInECBAgAABQXcDBAgQIEAgICDogRE9gQABAgQICLobIECAAAECAQFBD4zoCQQIECBAQNDdAAECBAgQCAgIemBETyBAgAABAoLuBggQIECAQEBA0AMjegIBAgQIEBB0N0CAAAECBAICgh4Y0RMIECBAgICguwECBAgQIBAQEPTAiJ5AgAABAgQE3Q0QIECAAIGAgKAHRvQEAgQIECAg6G6AAAECBAgEBAQ9MKInECBAgAABQXcDBAgQIEAgICDogRE9gQABAgQICLobIECAAAECAQFBD4zoCQQIECBAQNDdAAECBAgQCAgIemBETyBAgAABAoLuBggQIECAQEBA0AMjegIBAgQIEBB0N0CAAAECBAICgh4Y0RMIECBAgICguwECBAgQIBAQEPTAiJ5AgAABAgQE3Q0QIECAAIGAgKAHRvQEAgQIECAg6G6AAAECBAgEBAQ9MKInECBAgAABQXcDBAgQIEAgICDogRE9gQABAgQICLobIECAAAECAQFBD4zoCQQIECBAQNDdAAECBAgQCAgIemBETyBAgAABAoLuBggQIECAQEBA0AMjegIBAgQIEBB0N0CAAAECBAICgh4Y0RMIECBAgICguwECBAgQIBAQEPTAiJ5AgAABAgQE3Q0QIECAAIGAgKAHRvQEAgQIECAg6G6AAAECBAgEBAQ9MKInECBAgAABQXcDBAgQIEAgICDogRE9gQABAgQICLobIECAAAECAQFBD4zoCQQIECBAQNDdAAECBAgQCAgIemBETyBAgAABAoLuBggQIECAQEBA0AMjegIBAgQIEBB0N0CAAAECBAICgh4Y0RMIECBAgICguwECBAgQIBAQEPTAiJ5AgAABAgQE3Q0QIECAAIGAgKAHRvQEAgQIECAg6G6AAAECBAgEBAQ9MKInECBAgAABQXcDBAgQIEAgICDogRE9gQABAgQICLobIECAAAECAQFBD4zoCQQIECBAQNDdAAECBAgQCAgIemBETyBAgAABAoLuBggQIECAQEBA0AMjegIBAgQIEBB0N0CAAAECBAICgh4Y0RMIECBAgICguwECBAgQIBAQEPTAiJ5AgAABAgQE3Q0QIECAAIGAgKAHRvQEAgQIECAg6G6AAAECBAgEBAQ9MKInECBAgAABQXcDBAgQIEAgICDogRE9gQABAgQICLobIECAAAECAQFBD4zoCQQIECBAQNDdAAECBAgQCAgIemBETyBAgAABAoLuBggQIECAQEBA0AMjegIBAgQIEBB0N0CAAAECBAICgh4Y0RMIECBAgICguwECBAgQIBAQEPTAiJ5AgAABAgQE3Q0QIECAAIGAgKAHRvQEAgQIECAg6G6AAAECBAgEBAQ9MKInECBAgAABQXcDBAgQIEAgICDogRE9gQABAgQICLobIECAAAECAQFBD4zoCQQIECBAQNDdAAECBAgQCAgIemBETyBAgAABAoLuBggQIECAQEBA0AMjegIBAgQIEBB0N0CAAAECBAICgh4Y0RMIECBAgICguwECBAgQIBAQEPTAiJ5AgAABAgQE3Q0QIECAAIGAgKAHRvQEAgQIECAg6G6AAAECBAgEBAQ9MKInECBAgAABQXcDBAgQIEAgICDogRE9gQABAgQICLobIECAAAECAQFBD4zoCQQIECBAQNDdAAECBAgQCAgIemBETyBAgAABAoLuBggQIECAQEBA0AMjegIBAgQIEBB0N0CAAAECBAICgh4Y0RMIECBAgICguwECBAgQIBAQEPTAiJ5AgAABAgQE3Q0QIECAAIGAgKAHRvQEAgQIECAg6G6AAAECBAgEBAQ9MKInECBAgAABQXcDBAgQIEAgICDogRE9gQABAgQICLobIECAAAECAQFBD4zoCQQIECBAQNDdAAECBAgQCAgIemBETyBAgAABAoLuBggQIECAQEBA0AMjegIBAgQIEBB0N0CAAAECBAICgh4Y0RMIECBAgICguwECBAgQIBAQEPTAiJ5AgAABAgQE3Q0QIECAAIGAgKAHRvQEAgQIECAg6G6AAAECBAgEBAQ9MKInECBAgAABQXcDBAgQIEAgICDogRE9gQABAgQICLobIECAAAECAQFBD4zoCQQIECBAQNDdAAECBAgQCAj8ArcjSkn3E5VoAAAAAElFTkSuQmCC
1 change: 1 addition & 0 deletions spec/resources/eventing/dom-node.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<div id="element" style="width: 100px; height: 100px; background-color: green"></div>
61 changes: 47 additions & 14 deletions src/dom-to-image-more.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
styleCaching: 'strict',
// Default cors config is to request the image address directly
corsImg: undefined,
// Callback for adjustClonedNode eventing (to allow adjusting clone's properties)
adjustClonedNode: undefined,
};

const domtoimage = {
Expand Down Expand Up @@ -83,6 +85,7 @@
* - @param {Enumerator} method - get, post
* - @param {Object} headers - eg: { "Content-Type", "application/json;charset=UTF-8" }
* - @param {Object} data - post payload
* @param {Function} options.adjustClonedNode - callback for adjustClonedNode eventing (to allow adjusting clone's properties)
* @return {Promise} - A promise that is fulfilled with a SVG image data URL
* */
function toSvg(node, options) {
Expand Down Expand Up @@ -266,7 +269,7 @@
domtoimage.impl.options.cacheBust = options.cacheBust;
}

if (typeof(options.corsImg) === 'undefined') {
if (typeof options.corsImg === 'undefined') {
domtoimage.impl.options.corsImg = defaultOptions.corsImg;
} else {
domtoimage.impl.options.corsImg = options.corsImg;
Expand Down Expand Up @@ -352,9 +355,11 @@

return Promise.resolve(node)
.then(makeNodeCopy)
.then(adjustCloneBefore)
.then(function (clone) {
return cloneChildren(clone, getParentOfChildren(node));
})
.then(adjustCloneAfter)
.then(function (clone) {
return processClone(clone, node);
});
Expand All @@ -366,6 +371,20 @@
return original.cloneNode(false);
}

function adjustCloneBefore(clone) {
if (options.adjustClonedNode) {
options.adjustClonedNode(node, clone, false);
}
return Promise.resolve(clone);
}

function adjustCloneAfter(clone) {
if (options.adjustClonedNode) {
options.adjustClonedNode(node, clone, true);
}
return Promise.resolve(clone);
}

function getParentOfChildren(original) {
if (util.isElementHostForOpenShadowRoot(original)) {
return original.shadowRoot; // jump "down" to #shadow-root
Expand Down Expand Up @@ -804,15 +823,27 @@
request.withCredentials = true;
}

if (domtoimage.impl.options.corsImg
&& url.indexOf('http') === 0
&& url.indexOf(window.location.origin) === -1) {
const method = (domtoimage.impl.options.corsImg.method || 'GET').toUpperCase() === 'POST'
? 'POST'
: 'GET';
if (
domtoimage.impl.options.corsImg &&
url.indexOf('http') === 0 &&
url.indexOf(window.location.origin) === -1
) {
const method =
(
domtoimage.impl.options.corsImg.method || 'GET'
).toUpperCase() === 'POST'
? 'POST'
: 'GET';

request.open(
method,
(domtoimage.impl.options.corsImg.url || '').replace(
'#{cors}',
url
),
true
);

request.open(method, (domtoimage.impl.options.corsImg.url || '').replace('#{cors}', url), true);

let isJson = false;
const headers = domtoimage.impl.options.corsImg.headers || {};
Object.keys(headers).forEach(function (key) {
Expand All @@ -822,10 +853,12 @@
request.setRequestHeader(key, headers[key]);
});

const corsData = handleJson(domtoimage.impl.options.corsImg.data || '');

const corsData = handleJson(
domtoimage.impl.options.corsImg.data || ''
);

Object.keys(corsData).forEach(function (key) {
if (typeof(corsData[key]) === 'string') {
if (typeof corsData[key] === 'string') {
corsData[key] = corsData[key].replace('#{cors}', url);
}
});
Expand Down Expand Up @@ -1371,8 +1404,8 @@
const docType = document.doctype;
const docTypeDeclaration = docType
? `<!DOCTYPE ${escapeHTML(docType.name)} ${escapeHTML(
docType.publicId
)} ${escapeHTML(docType.systemId)}`.trim() + '>'
docType.publicId
)} ${escapeHTML(docType.systemId)}`.trim() + '>'
: '';

// Create a hidden sandbox <iframe> element within we can create default HTML elements and query their
Expand Down

0 comments on commit 601f708

Please sign in to comment.