Skip to content

Instantly share code, notes, and snippets.

@gr2m
Last active August 29, 2016 09:01
Show Gist options
  • Save gr2m/5463605 to your computer and use it in GitHub Desktop.
Save gr2m/5463605 to your computer and use it in GitHub Desktop.
Imagine you could convert all kind of things to all kind of different things, e.g. taking a screenshot of a dom element or converting another website to a screenshot. Forks & comments much appreciated! #nobackend #dreamcode
// convert a dom element to a PDF and download it
convert( $('.invoice') ).to( 'invoice.pdf' ).download()
// alternatively
download( convert( $('.invoice') ).to( 'invoice.pdf' ) )
// convert another website to a png and show it on the page
convert( 'http://exam.pl/page' ).toImage().then( $('.screenshots').append )
// attach a file to an email
sendEmail({
subject: "Hello, World!",
text: "This mail has been sent from the frontend",
to: "joe@exam.pl",
attachments: [
convert( 'http://exam.pl/page' ).to("screenshot.png")
]
})
@Volker-E
Copy link

This looks particularly weak to me, as (just to give two examples)

  • how does the application tell the server libs what binary file output settings are wanted?

    PNG might be not a big problem, but already a PDF has lots of different output options

  • how does it know which file type it should output -- via the .fileextension? What about container formats like .mov then?

@zerho
Copy link

zerho commented May 7, 2013

@Volker-E maybe something like this would be better

var settings = {
  compression: ""
  filters: ""
};
convert( $('.invoice') ).to( 'invoice.pdf', settings ).prependTo( $('.screenshots') )

@gr2m
Copy link
Author

gr2m commented May 10, 2013

Great thoughts!

Why not go with this

// simple API, works for most cases
convert( $('.invoice') ).to( 'invoice.pdf' ).download()

// for more complex use cases
convert( $('.invoice') ).to( {
  filename: 'invoice.jpg',
  filetype: 'image/jpeg',
  compression: 0.80,
  etc: 'etc'
} ).download()

@stuartlangridge
Copy link

What would you do other than download() ? That is: if I do convert( $('.invoice') ).to( 'invoice.pdf', {filetype: "pdf"} ), what happens? Does it store on the server? That rather assumes that there is storage on the server. I suspect that that should return a promise, and invoking .download() (or .prependTo(), or similar) cashes in the promise and actually does the work. (Using @gr2m's suggestion, which seems obviously correct.)

var later = convert( $('.invoice') ).to( 'invoice.pdf', 
    {filetype: "pdf"} ); // line 1
// nothing has happened yet. line 2
later.download(); // now the conversion happens: lazy evaluation. line 3

Question for the audience: should convert "freeze" the DOM on line 1? Or should it all be evaluated on line 3? That is: what if div.invoice changes on line 2?

@gr2m
Copy link
Author

gr2m commented May 11, 2013

Thanks for the input @stuartlangridge!

My expectiations would be that the moment you call later = convert( $('.invoice') ) it makes an internal copy / snapshot of the DOM element. So if you change the dom afterwards, but before calling later.download(), the DOM change should not affect the output.

To answer your question: convert( $('.invoice') ).to( 'invoice.pdf' ) returns a promise. I've learned that this is a Monad ( https://en.wikipedia.org/wiki/Monad_(functional_programming) ), what ever that is ;-)

The idea is, that you can do several things with the promise, representing the conversion task. You can download it, but you could also pass it to other functions, for example as attachment to an email:

sendEmail({
  subject: "Hello, World!",
  text: "This mail has been sent from the frontend",
  html: "<p>This mail has been sent from the frontend</p>",
  to: "joe@example.com",
  attachments: [ 
    convert( $('.invoice') ).to( 'invoice.pdf' ),
  ]
})

or imagine there would be a method to build archives

zip([
  convert( $('.invoice') ).to( 'invoice.pdf' ),
  convert( $('.time-sheet') ).to( 'time-sheet.pdf' )
]).download()

Does that make sense? I personally find it a very beautiful API, that hides away the asynchronous nature of the code in a very elegant way. But I haven't discussed these things with many other developers yet, so I'm very much looking forward to your thoughts on it

@BigWillie
Copy link

I like that - looks really clean. So download() and save()

How does it handle different MIME types, or is that not applicable in a node.js scenario?

@gr2m
Copy link
Author

gr2m commented Sep 2, 2013

not sure about a node.js scenario, I did it all with a browser environment in mind, and there I expect the right mime types to be sent as headers

@kishaningithub
Copy link

I would suggest https://www.filepicker.com for file format conversions and anything to do with pictures and files. All the above functional abstractions are covered using REST API

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment