Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serializing contents to HTML in Quill 1.0 #774

Closed
shaunr0b opened this issue Jun 25, 2016 · 22 comments
Closed

Serializing contents to HTML in Quill 1.0 #774

shaunr0b opened this issue Jun 25, 2016 · 22 comments

Comments

@shaunr0b
Copy link

In Quill 0.x, exporting HTML is easy via the getHtml() API. In Quill 1.x, with richer structures under the hood, has any work been done in exporting the contents as HTML?

https://quilljs.com/docs/api/#quillprototypegethtml

In the 1.0 docs getContents is there but nothing related to HTML. Is the intention that implementations would need to export their own HTML?

http://beta.quilljs.com/docs/api/#getcontents

As background, the application I'm working on involves serializing Quill's contents to HTML for email, so I'm working through of the issues involved in getting what's rendered in the Quill editor to match some HTML output as closely as possible.

Thanks!

@benbro
Copy link
Contributor

benbro commented Jun 25, 2016

getHTML in 0.20.1 was:
https://github.com/quilljs/quill/blob/0.20.1/src/core/document.coffee#L48

getHTML: ->
    # Preserve spaces between tags
    return @root.innerHTML.replace(/\>\s+\</g, '>&nbsp;<')

So maybe this can work in 1.0-beta?
quill.container.firstChild.innerHTML

@jhchen
Copy link
Member

jhchen commented Jun 27, 2016

Yes getHTML has been removed.

@jhchen jhchen closed this as completed Jun 27, 2016
@beeterry
Copy link

@jhchen What is the new solution for getting the HTML string? Right now, I'm trying to target innerHTML and it doesn't seem to be working right. Am I just doing it wrong or is there a better way?

@jhchen
Copy link
Member

jhchen commented Jul 27, 2016

Can you elaborate?

@beeterry
Copy link

beeterry commented Jul 27, 2016

@jhchen Well, we have an instance of the text editor and when the user clicks "save," we want to extract the html and store it in our DB so that another app can use the html. The way I'm extracting the HTML is by
this.editor.container.innerHTML.replace(/\>\s+\</g, '>&nbsp;<')

So basically I'm diving into the editor object and accessing the innerHTML property. That pulls something from the editor and puts it in the database fine. It also works fine when we pull that string from the database and .pasteHTML into the editor. The issue is when I try to paste that html string into my other application, it's not keeping the format. For example, we have an image and some text that we used the editor for and extracted the html, then stored it in the DB (from quill). Now, when we use that same html string in our other application, the image is pretty small and not aligned properly, and the text is surrounded by a white box/background. This is an example of the string we are getting from Quill.

@beeterry
Copy link

@jhchen Disregard this. I figured it out. I was targeting quill.container.innerHTML instead of quill.container.firstChild.innerHTML

@kodewithchirag
Copy link

kodewithchirag commented Sep 3, 2016

hi, i have a question that how can i get content from quill with html tags so that i can store it to DB and use it for other thing. i'd tried getContent but it's giving JSON output, and i want output in HTML format like when i store it to database Quill should give me output like <h1<b>DEMO</b></h1>'. and so on. so please guide me with it @jhchen

@benbro
Copy link
Contributor

benbro commented Sep 3, 2016

@chirag4396 please see the answer above
Use quill.container.innerHTML or quill.container.firstChild.innerHTML to get the HTML

@kodewithchirag
Copy link

Thank you very much @benbro, my problem is solved but there is arise of new one is when i'm trying to insert any image to quill editor, it gives me base64 string which is quite irritating. Could you help me for getting store that image to server and just get a <img> tag of it.

@Oikio
Copy link

Oikio commented Sep 5, 2016

@chirag4396 Trying to figure out same thing too, I guess good starting point should be here.

You write custom image handler which:

  1. saves images on server
  2. adds them into the editor.
  3. then you can save html content with images with urls

Or:
1.you parse all images on save
2. save them
3. replace img tags
4. save html.

Or:

  1. Save as is
  2. Replace img with urls on server, parsing and saving images
  3. Get response from server and replace quill content.

I'm just started adding quill on my project and new to it. So, I'm figuring out how to save images, too. Maybe some more expirienced developers can look at my solutions and help to find better way to handle this?

@willdady
Copy link

willdady commented Sep 7, 2016

From the upgrade guide:

a custom API call no longer adds any value on top of the DOM’s existing innerHTML.

I disagree. Having a getHTML method provides syntactic sugar over innerHTML and keeps the API for dealing with Quill consistent. Also, getHTML should convert the Delta to HTML when it's called, it should not trust what's in the DOM as a user can easily inject malicious markup. Yes submitting unexpected markup to the server would be easy to do regardless but at least a proper getHTML method would treat the Delta as the source of truth and not the DOM.

@themaxmarchuk
Copy link

Hello guys, I'm working on a single page chrome application which uses quill for text editing. Currently I am planning on saving everything as a quill delta object, and using setContents to load the saved data. This works great, however, I also need to convert what was edited in quill into a Microsoft Word Document when the user request an "export". I've found a library which allows me to convert an html string into a .docx blob, and it works.

https://github.com/evidenceprime/html-docx-js

So currently, I am planning on just using setContents to load the delta object, and then grab the inner html and run it through the docx generator. The issue is that sometimes I want them to export a file without ever opening an instance of the quill editor. So I was wondering what I should do? Theoretically I could create a hidden instance of quill and just use that to convert my deltas into html. How should I go about doing this?

If anyone has a better way of getting quill js content into .docx format, I would really appreciate your advice.

@jessejamesrich
Copy link

Seems like an obvious omission to not get the contents with an API call. Isn't that precisely what the library is designed for?

@jhchen
Copy link
Member

jhchen commented Sep 15, 2016

@willdady Creating an API for syntactic sugar is not enough. Quill's favors substantive APIs, which is a departure from most WYSIWYG editors where most of their APIs are just syntactic sugar. Quill is also consistent in not allowing users to touch the HTML directly. Freeing users from the need or desire to do this is the whole point of Quill. The two exceptions I can think of is on initialization and paste since in both scenarios the only input is often HTML, so Quill has no choice.

If the user can inject malicious markup, they can inject malicious scripts and you are already owned.

Delta are an easy to use and read output format. It is not and can not be the source of truth. For one it alone does not contain enough information to produce valid HTML that Quill would produce. For example attributes in Deltas are flat, whereas Quill enforces a hierarchical ordering for tags.

@jessejamesrichard You can use getContents.

For those passionate about this topic, I would suggest creating a fleshed out proposal including implementation challenges and tradeoffs. A lot of ideas will fall apart under once one thinks through these details. They can be discussed here or a new Issue if you want its own space for the proposal.

@egeersoz
Copy link

@jhchen How does Quill handle scenarios where other people have to consume the contents a user generates using Quill? For example, a simple blog or wiki application where I type in some rich text, and it has to be rendered on the page later when others want to read it. It's probably the most common application of rich text editors.

As far as I can tell, getContents() returns a Delta object. How is that object then converted to HTML markup to embed into the page?

@jhchen
Copy link
Member

jhchen commented Sep 15, 2016

@egeersoz The best thing to do is to load Quill in readonly mode with the saved Delta. That provides the highest guarantee that the content as it was being written looks the same and being read.

You can also use quill.root.innerHTML or querySelector('ql-editor').innerHTML. Quill is just not going to have an explicit API to just to add sugar. Literally the implementation of getHTML in 0.20.1 one line of code retrieving innerHTML and passing it through a regex replace that is no longer necessary.

@themaxmarchuk
Copy link

@jhchen since quill has specific css classes for formatting, would it makes sense to replace all of those divs which have quill specific classes with plain html tags such as <center> and <b>? Because the html-docx library I am using to generate .docx blobs requires that those tags be present in order to achieve the desired formatting. So I'm just curious, if you needed to convert a quill delta into .docx file without losing basic text formatting, how would you do it?

@tinyinstance
Copy link

@jhchen I feel like your suggestion for @egeersoz's question is not good enough (or I'm missing something). If we're using Quill for editorial, then we need a way (preferably an easy way) to display that content to users.

Current situation leaves us two options:

  1. Creating read-only editors to display content. But, think of a page with multiple posts and/or other parts that are written in Quill. Do we need to keep creating read-only editors to display the different contents on the same page? This doesn't seem right to me. Or, is it?
  2. Save the contents of quill.root.innerHTML as escaped HTML during editorial save and render that back on the user pages. From backend point of view, this is like using most of the other richtext editors, we handle escaping, cleaning and reversing of the generated html code. Which works, but defeats the whole purpose of deltas.

I think, a way to convert deltas to html without the editor would be helpful. However, from your responses I guess this is not the intended use case for Quill or the deltas? Am I right saying that:

  1. They are tightly dependent? (I'm new to Quill)
  2. If we are using Quill for the admin/editorial and want to store deltas, then our user's front-end will be Quill editor dependent as well?

Thanks!

@jhchen
Copy link
Member

jhchen commented Sep 19, 2016

The purpose of Deltas is to provide a simple and expressive format to describe content and changes. It would be just as useful in a world where HTML did not exist. Users have used Deltas to convert to HTML, plain text, markdown, rtf and others. The Working with Deltas guide shows how easy this is on the Delta side.

This particular Issue was opened inquiring about the removed getHTML API. As already stated it was removed because it did little more than return quill.root.innerHTML.

If there is a desire to add a Delta -> HTML API, please open a separate issue with a proposal of how this would work, including examples of input Deltas and corresponding output HTML demonstrating this.

There are existing third party Delta -> HTML libraries on Github and NPM each with differing opinions and implementations of what Delta maps to what HTML. They might serve as good inspiration for your proposal or an example of how to write your own converter if you do not want to generalize it for all Quill users.


To answer @tinyinstance question specifically:

If you do not feel good about quill.root.innerHTML you will probably not feel good about HTML a Delta->HTML converter spits out either.

For my own application that has a preview of documents shown in a list, I have simple converter that just extracts text and bold from Deltas.

html = delta.slice(0, 500).ops.map(function(op) {
   if (typeof op.insert !== 'string') return '';
   let html = op.insert;
   if (op.attributes.bold) {
      html = '<strong>' + html + '</strong>';
   }
   return html;
}).join('');

This has the added benefit of being able to just the first 500 characters for example, whereas with HTML, html.slice(0, 500) will not get you what you want. If you look the Delta format in the guide, you can see how trivial this is to write such a converter.

A lot of people will not agree with this conversion and want to extract other formats. And then they might disagree on how to represent formats with regards to tag ordering, using tags vs styles vs classes. That is one challenge of a generalized solution which is why I ask for those interested, for a specific proposal.

@tinyinstance
Copy link

@jhchen Thanks a lot for detailed response. Sorry for mixing up the issues. I understand it better now, that it would be complicated to create a generalised solution for everybody. I'm planning to integrate Quill to my app, and I'll definitely work on this conversion. If I come up with a good way to generalise it, I sure will share it in a separate issue. Thanks again.

@nmnuckols
Copy link

I also came to this thread looking for a getHtml() function. As a developer who has worked on dozens of applications using WYSIWYG editors, 100% of the time we needed to store the content in a database and output it to a web page. jhchen, based on your comments in this thread, it sounds like you did not intend the editor to be used this way. Is that true? I also believe that the answer of using a read-only version of the editor to display back the content has many flaws. Such as the fact that the content is loaded via javascript, thus requiring js to run on the page, and more importantly and it's not SEO friendly. Just take a look at the comment box on this page. It's a great example of an editor that stores the content as HTML and outputs the comments to the page server-side (likely not with javascript). If this is not the intended use of the editor, I fear that it's failing to meet the needs of the majority of use cases for WYSIWYG editors on the web. The reason I'm looking at Quill is because of its simplicity and consistency, but I want to be sure that using it for my application will not lead to problems down the road because I'm using it in a way that it's not intended.

@slab slab locked and limited conversation to collaborators Sep 28, 2016
@jhchen
Copy link
Member

jhchen commented Sep 28, 2016

Just take a look at the comment box on this page. It's a great example of an editor that stores the content as HTML...

This is pure uninformed speculation and is in no way a supporting example. Github may very well storing comments in markdown, not HTML.

I have explained in depth multiple times why getHTML was removed. Please read the abundance of information above.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests