Instantly share code, notes, and snippets.

Embed
What would you like to do?
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

This comment has been minimized.

Show comment
Hide comment
@Volker-E

Volker-E Apr 30, 2013

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?

Volker-E commented Apr 30, 2013

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

This comment has been minimized.

Show comment
Hide comment
@zerho

zerho May 7, 2013

@Volker-E maybe something like this would be better

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

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

This comment has been minimized.

Show comment
Hide comment
@gr2m

gr2m 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()
Owner

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

This comment has been minimized.

Show comment
Hide comment
@stuartlangridge

stuartlangridge May 10, 2013

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?

stuartlangridge commented May 10, 2013

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

This comment has been minimized.

Show comment
Hide comment
@gr2m

gr2m 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

Owner

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

This comment has been minimized.

Show comment
Hide comment
@BigWillie

BigWillie Aug 30, 2013

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?

BigWillie commented Aug 30, 2013

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

This comment has been minimized.

Show comment
Hide comment
@gr2m

gr2m 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

Owner

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

This comment has been minimized.

Show comment
Hide comment
@kishaningithub

kishaningithub Oct 8, 2015

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

kishaningithub commented Oct 8, 2015

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