eKoopmans / html2pdf.js

Client-side HTML-to-PDF rendering using pure JS.
MIT License
4.13k stars 1.39k forks source link

TypeError: executor did not take a resolve function on Safari #178

Open witpok opened 5 years ago

witpok commented 5 years ago

Hi, Thanks for providing all of us with this bundle. It works well on all browsers except on Safari, where there is an error when trying to print the page TypeError: executor did not take a resolve function, newPromiseCapability html2pdf.bundle.js:8970:40 which is return Promise.prototype.then.call(this, function then_pre(val) { v 0.9.1

full function used for printing:

function print(title) {
            if (!title) title = "print";
            var element = document.querySelector('.for-print');
            console.log("printing");
            var opt = {
              filename:     title+".pdf",
              // margin:10,
              pagebreak: { mode: ['css', 'legacy'], avoid:['li','p','h1','h2','h3'] },
              image:        { type: 'jpeg', quality: 1 },
              html2canvas:  { scale: 2 },
              jsPDF:        { unit: 'mm', format: [420, 594], orientation: 'portrait',pagesplit: true, margin: {top: 10, right: 10, bottom: 10, left: 10, useFor: 'page'} }
            };
            html2pdf(element,opt);

        }

Let me know if you need more info. Thanks for looking into it!

pjowens commented 5 years ago

Hello, I'll take a stab... // I'd recommend changing your function name away from using print() - thats a built-in function in many browsers and etc.
function makePDF(title) {

// Your line of code that has: "document.querySelector('.for-print');".....I'd use an ID instead of a class. Also, querySelector only gets the first element in the document with class you specify. // I'd suggest wrapping your desired HTML you want to turn into a PDF in a div tag with an asigned ID (example:

..html code you want made into a pdf
) instead of using querySelector. var pdfHtmlString = document.getElementById("html_For_PDF")

var options = { filename: title+".pdf", image: { type: 'jpeg', quality: 0.98 }, html2canvas: { scale: 2 }, jsPDF: { unit: 'mm', format: [420, 594], orientation: 'portrait',pagesplit: true, margin: {top: 10, right: 10, bottom: 10, left: 10, useFor: 'page'} } };

// Updated process for geting things to work.

html2pdf().from(pdfHtmlString).set(options).toPdf('pdf').save();

}

I used your code to setup the code above, and its working good for me - was not getting any errors on Chrome, Safari, or Firefox.

AlexPernot commented 5 years ago

Can confirm, it doesn't work on Safari 9, I get the same error : TypeError: executor did not take a resolve function. Here's a code sample: html2pdf(document.getElementById("contract"))

Thanks for this project, it works perfectly on modern browsers!

eKoopmans commented 5 years ago

Hi, I don't have much set up for testing on older browsers, I'll have to sort something out eventually. This issue looks related to Promises, which is surprising because Safari 7.1+ has native Promise support. @AlexPernot could you provide a simple example that doesn't work in Safari 9 (and/or other browsers) so I can reproduce and test? Ideally a fork of this template jsFiddle.

Thanks for identifying the issue!

AlexPernot commented 5 years ago

Yes, there must be something up with Safari's old Promise implementations, but I don't know what it is. Here's a jsFiddle that triggers the error. Note that you should test on a local script, since jsFiddle itself doesn't seem to run on Safari 9. :upside_down_face:

eKoopmans commented 5 years ago

Thanks again! So even the most basic html2pdf command doesn't work - good to know. I'll have to get some cross-browser testing and automation set up, not sure when that will happen though.

Synchro commented 3 years ago

FWIW that fiddle works fine in Safari 14 on macOS Big Sur