Long gone are the days when you’d print the contents of digital documents onto dead trees in order to archive them or mail them by letter. Luckily there’s a portable document format (PDF) and documents in this format are widely accepted. While it shouldn’t be a problem to get a PDF document from an office application such as Microsoft Word, getting one from the contents of a website is not always straight forward.
Modern single page applications (SPA) bring the complexity of once stand-alone applications into the browser. In some cases such an application, e.g. for bookkeeping purposes, needs to provide a PDF document that can easily be downloaded or sent by e-mail. However, due to different browsers and browser versions, it is not easy to provide the same layout/quality to all users.
There’s a couple of JS libraries that can generate PDF documents ad hoc, with some hurdles in the implementation or limitations in what they can achieve. For now I only needed a basic website to PDF tool, that provided the same document in every browser.
Google’s Chrome browser has an extensive API. This API is used by the Developer Tools, for debugging and for remote control. For the latter Google’s Node library Puppeteercomes in very handy as it provides methods to access the Chrome browser’s API and programmatically do the things you’d otherwise do manually. There’s even a class that generates a PDF document out of a page. Apply some settings and you’re done.
I’ve created a (very basic) NodeJS application that provides an (very basic) API that accepts URLs and generates a PDF document that is either displayed or offered as a download. The application uses express and Puppeteer and can be run in an, again very basic, environment such as a Docker container.
While this approach is straight forward and in my opinion easily implemented, there are some limitations:
You cannot access restricted resources.
You cannot choose what part of a website is printed.
At work I am currently developing an application that provides some tools and represents aggregated data from different sources to facilitate the workflow in different departments. It basically consists of two applications, a single page application being the front-end, and a RESTful API as back-end.
The applications run in separate Docker containers on a virtual machine in the firm’s intranet, as well as a couple of other dockerized applications. In the beginning that ensemble worked quite well, because those applications were only used by specific persons or systems. So exposing different ports for different applications under the same domain was not that much of a problem. But that changed when the aforementioned SPA & API became more widely used. On one hand it isn’t that great to explain to (technically challenged) users – to use one and the same domain but different ports for their apps -, on the other hand it just ain’t pretty. And since change needed to happen I also wanted to route HTTP traffic over TLS. Because… why not?
È dal duemiladieci che avevo un sogno, quello di andare in barca a vela. Non solo come passeggero ma come comandante. Quest’anno, ovvero l’anno scorso, l’ho incominciato a realizzare e mi sono iscritto a un corso presso una scuola nautica che finisce col esame per “la patente di abilitazione al commando di unità da diporto“.
Il modo migliore per prepararsi all’esame teorico è – come per la patente moto/macchina – quello di fare, e rifare, e rifa.. i quiz. Ma dato il fatto che non solo si tratta di 1.152 domande ma anche che sono una persona un po comoda, non volevo stamparli su carta. Perché da un lato non avrei avuto la voglia di portarmeli dietro ovunque e dal altro perché sarebbe uno spreco di carta (vedi punto uno).
Quindi ho preso il documento PDF con le domande, pubblicato dalla guardia costiera di Genova, e ho estratto tutte le informazioni che mi sono serviti per creare un’applicazione web che mi consentiva di usare qualsiasi browser per fare i quiz.
Alla fine la ho caricata su qnb.davole.com in modo tale che sia accessibile per chiunque.
Shortly after I started my new job, the need for a in-house tool to facilitate some processes and thereby the work of my colleagues became evident. While my predecessor already built a tool for that, he isn’t able to go on with it’s development and maintenance. Enter me with my web-application-development-passion. During my studies and side-projects I’ve already been in bed with AngularJS. Therefore it came only naturally to continue my walk down that road, even though Angular is quite a different story.
In the development process I’ve been and will be confronted with some new challenges, for creating some pipes:
About a month ago I held a presentation about Web Intents at work. But what are Web Intents anyway and what are they good for?
Web Intents handle the Intent of an action, for example sharing content after clicking a button
Web Intents are not applications. They just tell the client, what they want him to do
Web Intents are “blind“, because they don’t know which application will handle the requested action
But who or what does the job then? It’s your browser which knows what to do, because a Web Intent has registered itself, once the web service has been accessed in an earlier moment.
If you’d like to know more about Web Intents – get a quick overview – feel free to take a look at my roughly translated Google Presentation (en – http://bit.ly/MIH1mb), or the original one (de – http://bit.ly/MIICsi).
In my opinion, Web Intents are awesome. The idea of not messing around with Facebook and Google and Twitter and Pinterest (amongst many, many others) no more is wonderful. And users wont have to search their favorite web service for a certain activity anymore.
This bug affects both Chrome 17.0.963.56 and Safari 5.1.2 (reproduced on Windows 7). Even though I’m not the first one to come up with this bug, I’m wondering why it hasn’t been fixed after all those years(!). Reproducing this bug is quite simply, which makes me wonder even more..
The newest version of Chrome (17.0.963.46) is a bit of a trouble maker – at least on Windows 7 x64. Seems like the border-radius property causes a bug, which fills the background of the element with its borders color – not entirely, but partly at a height of height x ~0,50-0,52.
Deactivating the border-radius seems to “fix” it, and scrolling has also some effects on it.