Invalid absolute docBaseUrl "blob" - jspdf

I have a new problem with an old script. The problem is already exist with an old (1.5.3) and the newest (2.5.1) jsPDF version.
Until recently, the Save or View dialog was displayed when creating a PDF in the browser. Now it works only if the browser (Firefox) is disabled to show PDF. In default mode the PDF is displayed as blob and has a URL without the filename specified by the script in jsPDF.
The console displays the message Warning: Invalid absolute docBaseUrl: "blob:https://www.example.com/25dao98-787zhz98-098kiio54". and PDF 7a55842e15bbd5545545114f2211 [1.3 jsPDF 2.5.1 / example.com] (PDF.js: 2.14.13) .
What do I have to do to open the Save or View dialog in the browser again when creating the PDF?
I use the CDN (jspdf.min.js) versions in my website and only uncomplicated draw, text, font and image function.
Here a example from the jsPDF Github page:
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
</head>
<body>
<script>
function myfunc() {
var { jsPDF } = window.jspdf;
var doc = new jsPDF();
doc.setFont(undefined, 'normal');
doc.text("Hello world! " + Date.now(), 10, 10);
doc.setFont(undefined, 'bold');
doc.text("Hello world! " + Date.now(), 10, 20);
doc.save("a4.pdf");
}
</script>
<button onclick="myfunc();">Button</button>
</body>
This as jspdf.html on my webspace and in firefox opens a blob. And the same on jsfiddle save the pdf file in the default download directory with the correct filename and opens it in a new tab.
https://jsfiddle.net/awk6hd7t/
I don't need blob.

Related

Include a pdf in an electron.js window

I have a web app that creates pdf files and shows a preview. Like so
...
<body>
<iframe id="preview" src=""></iframe>
<script src="jspdf.min.js"></script>
<script>
var doc = new jsPDF()
doc.text(5, 5, 'Hello, world!')
document.getElementById("preview").src = doc.output("datauristring")
</script>
</body>
...
Problem is, it doesn't work e.g. in IE. So I want to make a desktop app using electron.js. According to this post: >Electron PDF viewer there is a pdf viewer in electron, but the iframe (or webview) is always empty.
Is it somehow possible?

jsPDF - Error - Failed to load PDF document in Chrome

Trying to build a test pdf with jspdf 1.5.3 and it works fine with jsfiddle. But when I use the exact same script on my apache or iis servers, chrome cannot open the pdf. When I look at the pdf in a text viewer, it appears my version has some additional binary code.
This is the script:
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.min.js"></script>
<script type="text/javascript">
var doc = new jsPDF();
doc.text('Hello world!', 10, 10);
doc.save('xyz.pdf');
</script>
</head>
<body>
</body>
</html>
Working version on jsfiddle:
https://jsfiddle.net/orz3jb4v/
Here is a screenshot of both versions side by side in text editor:
https://i.imgur.com/bLi6f1E.png
(Invalid pdf on left)
Edit: After testing, this only happens with version 1.5.3. Reverting to 1.5.2 works perfectly fine. I can't find why this only happens on certain servers.

How to use html templates in electron framework?

I need to build a cross platform app with multiple windows. So I would like to know how to use html templates in electron.
Based on a similar question and what I've seen, there's no built in html template language in Electron, which is actually great because it allows you to use any other template language.
I'm currently playing with ejs in Electron.
Below is my index.ejs template file:
<html lang="en">
<head>
<title>The Index Page</title>
</head>
<body>
<h1>Welcome, this is the Index page.</h1>
<% if (user) { %>
<h3>Hello there <%= user.name %></h3>
<% } %>
</body>
</html>
And below is a section of my main.js file where the above template is rendered and loaded onto the BrowserWindow. Note that I've left out most of the boilerplate code:
const ejs = require('ejs');
//... Other code
let win = new BrowserWindow({width: 800, height: 600});
//... Other code
// send the data and options to the ejs template
let data = {user: {name: "Jeff"}};
let options = {root: __dirname};
ejs.renderFile('index.ejs', data, options, function (err, str) {
if (err) {
console.log(err);
}
// Load the rendered HTML to the BrowserWindow.
win.loadURL('data:text/html;charset=utf-8,' + encodeURI(str));
});
I'll give some credit to this gist for helping me find the data:text/html;charset=utf-8 part of the url that can be used to load dynamic content.
UPDATE
I'm actually not using this anymore. It's faster to just load the default html and use the native DOM methods. The Electron Quickstart program shows how to do this nicely.
Another option is to do the templating during your build. Here is a simple example using gulp to add nonces to the CSP meta tag and the inline script.
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'nonce-<%= scriptNonce %>';">
<title>Basic Electron App</title>
</head>
<body>
<div id="app"></div>
<script type="application/javascript" nonce=<%= scriptNonce %>>
require('./index.js');
</script>
</body>
</html>
and in gulfile.js add the following to what you already have and make sure this task is included in your pipeline. You can also just update your current html task with the code below.
const template = require('gulp-template');
const uuidv4 = require('uuid/v4');
gulp.task('copy-html', () => {
// Create nonces during the build and pass them to the template for use with inline scripts and styles
const nonceData = {
scriptNonce: new Buffer(uuidv4()).toString('base64'),
styleNonce: new Buffer(uuidv4()).toString('base64')
};
return gulp.src('src/*.html')
.pipe(template(nonceData))
.pipe(gulp.dest('dist/'));
});
This is a very stripped down example. I have a more complete example at https://github.com/NFabrizio/data-entry-electron-app if anyone is interested, though there is still one warning when running the application because one of the packages I am using pulls in react-beautiful-dnd, which adds inline styles but does not currently accept nonces.

Display '⤭' in iOS safari through CSS content property

The html looks like this:
<html>
<head>
<style type="text/css">
h1:before
{
content: '\292d';
}
</style>
</head>
<body>
<h1>Sample Text</h1>
</body>
</html>
So, I've already converted the '⤭' character to ASCII which shows fine in my desktop's browser; however, on iPhone, it's blank!
The problem could be with content: '\292d'; even though they say content is supported with safari 1.0 and up it still does not work properly.
i used it for displaying images and it used to show up in inspect element but not in browser window, the entity '\292d' is infact supported
instead Try putting it directly inside the tag, or use javascipt if you want it to be dynamically inserted

Simple fusioncharts in MonoTouch not working

I'm trying to embed a column3d chart from fusioncharts in my MonoTouch project using UIWebView. I've added the necessary outlets and tested by using loadrequest to load a url and loadHtmlString to format a simple line of text. This works fine. I even tested that fusionchart works correctly on my browser using the below code and it does.
I have a folder named "charts" in my MonoTouch project that contains, Column3d.swf, jquery.min.js, FusionCharts.js, FusionCharts.HC.js and FusionCharts.HC.Charts.js.
In my
ViewDidLoad
string htmlString = "<html>
<head>
<script type=\"text/javascript\"src=\"Charts/jquery.min.js\">
</script>
<script type=\"text/javascript\" src=\"Charts/FusionCharts.js\">
</script>
<script type=\"text/javascript\" src=\"Charts/FusionCharts.HC.js\">
</script>
<script type=\"text/javascript\" src=\"Charts/FusionCharts.HC.Charts.js\">
</script>
</head>
<body>
<div id=\"chartContainer\">FusionCharts will load here!
</div>
<script type=\"text/javascript\"> var myChart = new FusionCharts( \"Charts/Column3D.swf\", \"myChartId\", \"400\", \"300\", \"0\", \"1\" );myChart.setXMLUrl(\"Charts/Data.xml\");
myChart.render(\"chartContainer\");
</script>
</body>
</html>";
this.webView.LoadHtmlString (htmlString, new NSUrl ("./Charts", true));
/*string htmlString = "<html><head></head><body><span style=\"font-weight: bold;\">This</span> " +
"<span style=\"text-decoration: underline;\">is</span> <span style=\"font-style: italic;\">some formatted</span> " +"<span style=\"font-weight: bold;text-decoration: underline;\">text!</span><br></body></html>";*/ //works
//this.webView.LoadHtmlString (htmlString, null); //works
Data.xml
<chart caption='Weekly Sales Summary'
xAxisName='Week' yAxisName='Amount' numberPrefix='$'>
<set label='Week 1' value='14400' />
<set label='Week 2' value='19600' />
<set label='Week 3' value='24000' />
<set label='Week 4' value='15700' />
</chart>
Can someone explain how I can get this working? Thanks in advance.
EDIT: I also tried
string htmlString = "<html><head> <title>Creating Pure JavaScript chart</title><script type=\"text/javascript\" src=\"charts/FusionCharts.js\"></script></head> <body><div id=\"chartContainer\">FusionCharts will load here!</div> <script type=\"text/javascript\">FusionCharts.setCurrentRenderer('javascript');var myChart = new FusionCharts( \"charts/Column3D.swf\", \"myChartId\", \"400\", \"300\", \"0\", \"1\" );myChart.setXMLData(\"<chart><set label='Data1' value='1' /></chart>\"); myChart.render(\"chartContainer\"); </script></body> </html>";
where i force the renderer to use javascript and set the chart parameters in the string to no avail. Anyone?
I solved my issue and thought I would post it should someone run into a similar issue.
The first thing I did was to right click on each of my javscript files ie FusionCharts.js, FusionCharts.HC.js and FusionCharts.HC.Charts.js and set their build type to content.
I then told Monotouch the build path for the charts would be contained in the charts folder by declaring
string path = NSBundle.MainBundle.BundlePath + "/Charts/";
Since I declare i am going to look in the Charts folder for related files, I then had to amend my htmlString by removing the "charts" keyword reference from all the "src" as below (since we are already lo.
string htmlString = "<html>
<head>
<script type=\"text/javascript\" src=\"jquery.min.js\">
</script>
<script type=\"text/javascript\" src=\"/FusionCharts.js\">
</script>
<script type=\"text/javascript\" src=\"/FusionCharts.HC.js\">
</script>
<script type=\"text/javascript\" src=\"FusionCharts.HC.Charts.js\">
</script>
</head>
<body>
<div id=\"chartContainer\">FusionCharts will load here!
</div>
<script type=\"text/javascript\"> var myChart = new FusionCharts(\"Column3D.swf\", \"myChartId\", \"400\", \"300\", \"0\", \"1\" );myChart.setXMLUrl(\"Charts/Data.xml\");
myChart.render(\"chartContainer\");
</script>
</body>
</html>";
I then call the loadHtml string method as below with the second argument pointing to the path that contains the javascript files.
this.webView.LoadHtmlString(htmlString, new NSUrl(path, true));
I even tested that fusionchart works correctly on my browser using the below code and it does.
Did you test this with an iOS device running Safari ?
project that contains, Column3d.swf,
That looks like a Flash file and iOS (and WebKit) does not support flash.
The website hints of an HTML5 version - so if they support flash-less browser then you should be able to do what you want using MonoTouch (or anything in iOS) using FusionChart. Otherwise you might need to look at other charting products (or a server-side solution).
FusionCharts had put out a blog post showing how to get HTML5 charts in iOS devices.
Have a look at it here - http://blog.fusioncharts.com/2012/02/create-charts-for-iphone-and-ipad-apps-using-fusioncharts-xt/

Resources