Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When specifying filter option, get error in embedFonts #26

Closed
kirilledelman opened this issue Mar 21, 2016 · 6 comments
Closed

When specifying filter option, get error in embedFonts #26

kirilledelman opened this issue Mar 21, 2016 · 6 comments

Comments

@kirilledelman
Copy link

Hi, first of all, thanks for making this library public. You are a saint.

Testing on Chrome 49.0.2623.87 (64-bit) / Mac. My document has embedded fonts ( Google Fonts )
I'm having a problem when specifying filter function to .toSvg - it fails when encounters a filtered out node.

var filterFunc = function( node ) {
    if ( node.id == 'background' ) return true;
    return false;
};

domtoimage.toSvg( container, { filter: filterFunc } )
                        .then( domtoimage.impl.util.makeImage )
                        .then( domtoimage.impl.util.delay( 100 ) )
                        .then( drawToCanvas )
                        .catch( function ( error ) { console.error( error ); } );

It fails / dies with the following error:

dom-to-image.js:198 Uncaught (in promise) TypeError: Cannot read property 'appendChild' of undefined
    at dom-to-image.js:198:21
(anonymous function) @ dom-to-image.js:198
Promise.resolve (async)readAll @ dom-to-image.js:516
resolveAll @ dom-to-image.js:501
embedFonts @ dom-to-image.js:195
Promise.resolve (async)toSvg @ dom-to-image.js:32

On line 198 inside embedFonts, node is undefined. Because of all the Promises, I'm having a hard time actually debugging this. Do you have any ideas what could be causing this?

@tsayen
Copy link
Owner

tsayen commented Mar 21, 2016

Looks like you're filtering out the node you want to render. Make sure your filter matches that node.

@kirilledelman
Copy link
Author

It doesn't matter what I'm actually trying to filter out - returning false from filter in any case results in node being undefined later in Promise chain. Maybe I misunderstand how the library is designed - but what I'm trying to do is give it a container with mixed dom objects in it, and filter function would return true or false for those I want included in resulting svg/foreignobject sandwich, and skip all the others.

I "fixed" it by changing this line:
From:
if (filter && !filter(node)) return Promise.resolve();
To:
if (filter && !filter(node)) return Promise.resolve(document.createElement( 'b' ));

Now there's no exception, and it ends up rendering empty/invisible <b/> instead. But it seems to be a deeper problem here - promise.resolve requires node to be defined later.

@tsayen
Copy link
Owner

tsayen commented Mar 21, 2016

Take a look at this test to see how filter should be used. When calling toSvg, you should provide the node you want to render. If your filter does not return true for the node you've provided as first argument, then you'll get this error. Perhaps this situation should be handled better. But if you give right arguments (and make sure that root node passes the filter), your problem should be fixed

@kirilledelman
Copy link
Author

Now it makes sense! My filter should've included the container node as well as the things I'm filtering in / out.

Thank you for clearing this up.

@tsayen
Copy link
Owner

tsayen commented Mar 21, 2016

welcome :)

@tsayen tsayen closed this as completed Mar 21, 2016
@tsayen
Copy link
Owner

tsayen commented Mar 28, 2016

FYI, starting from 2.1.0 this issue is handled better, the filter is no longer applied to the root node.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants