Stillcollab-surface : an Open Source wysiwyg editor written for and with GWT

222 views
Skip to first unread message

Damien Picard

unread,
Mar 7, 2012, 5:45:45 AM3/7/12
to google-web-toolkit
I'm pleased to announce the creation of a new Open Source project called stillcollab-surface : http://code.google.com/p/stillcollab-surface/

Surface is a wysiwyg editing surface that doesn't rely on browser's execCommand and queryCommandState commands.

Because of using these commands leads to output differences, this is not a good behavior for products that need to compute produced HTML elsewhere than in a browser.

Furthermore, table, list, paragraph, etc. manipulation can differ from a browser to another one, so this wysiwyg try to handle these differences to provide the same look and feel for every browser.

To finish, this editor is, as possible as it could be, developed in Java/GWT, so it can be easily embedded in every GWT application, debugged and improved.


This project is very young (about 1 month), and I hope to have a lot of feedback in order to handle every bugs for every browsers. Furthermore, a lot of basics functionalities are not implemented (subscript, superscript, etc.) but this project is designed to allow everyone to easily add customs inserters etc. So I hope there will be some contributions around these functionnalities ;).
To finish, there is, at this time, absolutely no design for buttons, controls etc. If someone can provide a good look and feel, I will gladly use it.

Thank you.

--
Damien Picard
Axeiya Services : http://axeiya.com/
stillcollab-surface : http://code.google.com/p/stillcollab-surface/
Mon livre sur GWT : http://axeiya.com/index.php/ouvrage-gwt.html

Thomas Broyer

unread,
Mar 7, 2012, 6:53:55 AM3/7/12
to google-we...@googlegroups.com, google-web-toolkit

On Wednesday, March 7, 2012 11:45:45 AM UTC+1, Damien Picard wrote:
I'm pleased to announce the creation of a new Open Source project called stillcollab-surface : http://code.google.com/p/stillcollab-surface/

Surface is a wysiwyg editing surface that doesn't rely on browser's execCommand and queryCommandState commands.

Because of using these commands leads to output differences, this is not a good behavior for products that need to compute produced HTML elsewhere than in a browser.

Furthermore, table, list, paragraph, etc. manipulation can differ from a browser to another one, so this wysiwyg try to handle these differences to provide the same look and feel for every browser.


Looks great but:
  • is there a live demo somewhere?
  • it looks like you're kind-of reinventing the wheel, as Apache Wave already has that kind of editor. Wave's one is based on an XML-like document whose schema is not (X)HTML; the added flexible obviously translates into a more complex design but it works quite well (I've used it in a project where we had to constrain the input –e.g. no image in a title–, and handle "semantic links", among other things; and FWIW, the Wave editor powers the new Blogger comment form), and has already been heavily tested on many browsers (at Google, before being donated to Apache; though given its use in Blogger, it's highly probably that it's still heavily tested at Google, and I guess they'd contribute back to Apache if/when they fix things)

Damien Picard

unread,
Mar 7, 2012, 8:07:38 AM3/7/12
to google-we...@googlegroups.com
Hi,

You can find a demo here : http://surface-sample.elasticbeanstalk.com/
Indeed, I'm reinventing the wheel. I did not known the Wave editor, I will take a look at it, but I'm not sure that handling something else than HTML is the right thing to do in my use case. There is some existing wysiwyg editors that uses the same idea of creating inserters instead of using execCommand (Aloha, as an example).
But there is always something missing to me :
  • I need a GWT based wysiwyg (Wave editor, XWiki editor are candidates)
  • I need to create specific inserters
  • I need to control strictly the HTML output (because the HTML is exported with XSLT processors in my use case)
  • I need to process the HTML "in-place", by DOM manipulation
  • and some other things...
Firstly, I did not want to reinvent the wheel, but every existing wysiwyg solution always lead me to embarrassing limitations in my use cases. But I repeat, I've not tried Wave editor, and I will do it quickly ; I wish it could be a solution for me.

Thank you for your feedback.

--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To view this discussion on the web visit https://groups.google.com/d/msg/google-web-toolkit/-/mZlUn62KEwgJ.
To post to this group, send email to google-we...@googlegroups.com.
To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.

Thomas Broyer

unread,
Mar 7, 2012, 9:54:54 AM3/7/12
to google-we...@googlegroups.com

On Wednesday, March 7, 2012 2:07:38 PM UTC+1, Damien Picard wrote:
Hi,

You can find a demo here : http://surface-sample.elasticbeanstalk.com/

Thanks.

It's indeed a very young project: you cannot apply style across paragraphs or other styles' boundaries (typical example: "fo<b>o b<i>a</b>r b</i>az" → foo bar baz)
That's one of the hardest things to handle in an editor, and the very first thing I try out ;-)
 
Indeed, I'm reinventing the wheel. I did not known the Wave editor, I will take a look at it, but I'm not sure that handling something else than HTML is the right thing to do in my use case. There is some existing wysiwyg editors that uses the same idea of creating inserters instead of using execCommand (Aloha, as an example).
But there is always something missing to me :
  • I need a GWT based wysiwyg (Wave editor, XWiki editor are candidates)
  • I need to create specific inserters
  • I need to control strictly the HTML output (because the HTML is exported with XSLT processors in my use case)
Wave is based on documents that can easily be serialized as XML (that's what we use for persistence).
Because it has to to handle "operational transformation", inline styling (bold, italic, links, etc.) and paragraphs are represented by "markers". Styling is represented by "annotations", so the markers are "annotation boundaries", serialized in XML as processing instructions. Paragraph boundaries are representing by <line/> elements (similar to <br> in HTML except a <line/> marks the beginning of a paragraph, and can have a "type" and "level": title, ordered list, unordered list). These are just the built-in representations though, you're free to implement whatever you want (it'd just require a bit more work).
The "persistent document" is first processed to build a "local document" (<line/>xxx is transformed to <l:p>xxx</l:p>, annotations are transformed to <l:s> spans, etc.), then each element of this document is rendered into HTML. Each modification made on the document (either persistent or local) is passed to the renderer to update the view.
Have a look at http://www.waveprotocol.org/code/tutorials/writing-a-doodad and http://www.waveprotocol.org/wave-protocol-summit/wave-summit-talks (particularly “Wave model deep dive” by Alex North, and “Wave panel and rendering” and “Real-time editor & Doodads” by Dave Hearnden), and search for my mails on the Wave mailing lists, where people answered with many valuable information and links. Re. the code, start with the EditorHarness GWT app.

In our case, we chose to keep the paragraphs-via-<line/> and styling-via-annotations (because it was easier), and added table rendering, links (handled as elements so we can easily make sure we don't nest them), "semantic annotations" (same as links), and illustrations (similar to an image, but links to an entity that carries both the image and legend, among many other things).
In some "rich text areas", we're able to limit available features: some areas a "single paragraph" with only styling a "semantic markup", others allow several paragraphs but no titles, etc.
Finally, by listening to document changes, we keep a document outline, index of "semantic markup" (as CellTree widgets), and lists of tables and illustrations (as CellList widgets) in real-time.

The only thing needing real work is the copy/paste handling, which in Wave is tightly bound to Wave's "wavelet" document schema. In our case, we simply shadowed the class to strip every formatting and paste as plain text.

Overall, the code is complex but very well thought out, so once you grasped the concepts, it reads fairly easily.
  • I need to process the HTML "in-place", by DOM manipulation

Not sure what you mean by that, but Wave uses DOM manipulations exclusively (see above).

Damien Picard

unread,
Mar 7, 2012, 10:41:20 AM3/7/12
to google-we...@googlegroups.com
Le 7 mars 2012 15:54, Thomas Broyer <t.br...@gmail.com> a écrit :

On Wednesday, March 7, 2012 2:07:38 PM UTC+1, Damien Picard wrote:
Hi,

You can find a demo here : http://surface-sample.elasticbeanstalk.com/

Thanks.

It's indeed a very young project: you cannot apply style across paragraphs or other styles' boundaries (typical example: "fo<b>o b<i>a</b>r b</i>az" → foo bar baz)
That's one of the hardest things to handle in an editor, and the very first thing I try out ;-)

Thank you to notice this problem ; in fact this is a selection range bug (sometimes the range is not set correctly, but only in prod mode :(  I think I will spent a long time on this...) But the behavior you notice works fine, when the Range works... This is also the first thing I've implemented

 
Indeed, I'm reinventing the wheel. I did not known the Wave editor, I will take a look at it, but I'm not sure that handling something else than HTML is the right thing to do in my use case. There is some existing wysiwyg editors that uses the same idea of creating inserters instead of using execCommand (Aloha, as an example).
But there is always something missing to me :
  • I need a GWT based wysiwyg (Wave editor, XWiki editor are candidates)
  • I need to create specific inserters
  • I need to control strictly the HTML output (because the HTML is exported with XSLT processors in my use case)
Wave is based on documents that can easily be serialized as XML (that's what we use for persistence).
Because it has to to handle "operational transformation", inline styling (bold, italic, links, etc.) and paragraphs are represented by "markers". Styling is represented by "annotations", so the markers are "annotation boundaries", serialized in XML as processing instructions. Paragraph boundaries are representing by <line/> elements (similar to <br> in HTML except a <line/> marks the beginning of a paragraph, and can have a "type" and "level": title, ordered list, unordered list). These are just the built-in representations though, you're free to implement whatever you want (it'd just require a bit more work).
The "persistent document" is first processed to build a "local document" (<line/>xxx is transformed to <l:p>xxx</l:p>, annotations are transformed to <l:s> spans, etc.), then each element of this document is rendered into HTML. Each modification made on the document (either persistent or local) is passed to the renderer to update the view.
Have a look at http://www.waveprotocol.org/code/tutorials/writing-a-doodad and http://www.waveprotocol.org/wave-protocol-summit/wave-summit-talks (particularly “Wave model deep dive” by Alex North, and “Wave panel and rendering” and “Real-time editor & Doodads” by Dave Hearnden), and search for my mails on the Wave mailing lists, where people answered with many valuable information and links. Re. the code, start with the EditorHarness GWT app.

In our case, we chose to keep the paragraphs-via-<line/> and styling-via-annotations (because it was easier), and added table rendering, links (handled as elements so we can easily make sure we don't nest them), "semantic annotations" (same as links), and illustrations (similar to an image, but links to an entity that carries both the image and legend, among many other things).
In some "rich text areas", we're able to limit available features: some areas a "single paragraph" with only styling a "semantic markup", others allow several paragraphs but no titles, etc.
Finally, by listening to document changes, we keep a document outline, index of "semantic markup" (as CellTree widgets), and lists of tables and illustrations (as CellList widgets) in real-time.

The only thing needing real work is the copy/paste handling, which in Wave is tightly bound to Wave's "wavelet" document schema. In our case, we simply shadowed the class to strip every formatting and paste as plain text.

I've checked out the code ; I will try to extract and use only the editor in a sample project. Maybe you've already done this work ?
 
Overall, the code is complex but very well thought out, so once you grasped the concepts, it reads fairly easily.
  • I need to process the HTML "in-place", by DOM manipulation

Not sure what you mean by that, but Wave uses DOM manipulations exclusively (see above).
In fact, I want to launch a command that make some changes on the currently editing content. If this is the only thing missing in Wave editor, I think I can do it. This is not really difficult.

Thank you very much.

--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.

To post to this group, send email to google-we...@googlegroups.com.
To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.

Thomas Broyer

unread,
Mar 7, 2012, 12:53:45 PM3/7/12
to google-we...@googlegroups.com


On Wednesday, March 7, 2012 4:41:20 PM UTC+1, Damien Picard wrote:


Le 7 mars 2012 15:54, Thomas Broyer a écrit :

On Wednesday, March 7, 2012 2:07:38 PM UTC+1, Damien Picard wrote:
Hi,

You can find a demo here : http://surface-sample.elasticbeanstalk.com/

Thanks.

It's indeed a very young project: you cannot apply style across paragraphs or other styles' boundaries (typical example: "fo<b>o b<i>a</b>r b</i>az" → foo bar baz)
That's one of the hardest things to handle in an editor, and the very first thing I try out ;-)

Thank you to notice this problem ; in fact this is a selection range bug (sometimes the range is not set correctly, but only in prod mode :(  I think I will spent a long time on this...) But the behavior you notice works fine, when the Range works... This is also the first thing I've implemented

 
Indeed, I'm reinventing the wheel. I did not known the Wave editor, I will take a look at it, but I'm not sure that handling something else than HTML is the right thing to do in my use case. There is some existing wysiwyg editors that uses the same idea of creating inserters instead of using execCommand (Aloha, as an example).
But there is always something missing to me :
  • I need a GWT based wysiwyg (Wave editor, XWiki editor are candidates)
  • I need to create specific inserters
  • I need to control strictly the HTML output (because the HTML is exported with XSLT processors in my use case)
Wave is based on documents that can easily be serialized as XML (that's what we use for persistence).
Because it has to to handle "operational transformation", inline styling (bold, italic, links, etc.) and paragraphs are represented by "markers". Styling is represented by "annotations", so the markers are "annotation boundaries", serialized in XML as processing instructions. Paragraph boundaries are representing by <line/> elements (similar to <br> in HTML except a <line/> marks the beginning of a paragraph, and can have a "type" and "level": title, ordered list, unordered list). These are just the built-in representations though, you're free to implement whatever you want (it'd just require a bit more work).
The "persistent document" is first processed to build a "local document" (<line/>xxx is transformed to <l:p>xxx</l:p>, annotations are transformed to <l:s> spans, etc.), then each element of this document is rendered into HTML. Each modification made on the document (either persistent or local) is passed to the renderer to update the view.
Have a look at http://www.waveprotocol.org/code/tutorials/writing-a-doodad and http://www.waveprotocol.org/wave-protocol-summit/wave-summit-talks (particularly “Wave model deep dive” by Alex North, and “Wave panel and rendering” and “Real-time editor & Doodads” by Dave Hearnden), and search for my mails on the Wave mailing lists, where people answered with many valuable information and links. Re. the code, start with the EditorHarness GWT app.

In our case, we chose to keep the paragraphs-via-<line/> and styling-via-annotations (because it was easier), and added table rendering, links (handled as elements so we can easily make sure we don't nest them), "semantic annotations" (same as links), and illustrations (similar to an image, but links to an entity that carries both the image and legend, among many other things).
In some "rich text areas", we're able to limit available features: some areas a "single paragraph" with only styling a "semantic markup", others allow several paragraphs but no titles, etc.
Finally, by listening to document changes, we keep a document outline, index of "semantic markup" (as CellTree widgets), and lists of tables and illustrations (as CellList widgets) in real-time.

The only thing needing real work is the copy/paste handling, which in Wave is tightly bound to Wave's "wavelet" document schema. In our case, we simply shadowed the class to strip every formatting and paste as plain text.

I've checked out the code ; I will try to extract and use only the editor in a sample project. Maybe you've already done this work ?

I'm building Wave out-of-the-box ("ant dist-libraries" IIRC) and then picking the client, client-common, client-scheduler, common, media, model, and util JARs.
Maybe some of them are only needed for the EditorToolbar which we're also using, but I doubt so.
 
 
Overall, the code is complex but very well thought out, so once you grasped the concepts, it reads fairly easily.
  • I need to process the HTML "in-place", by DOM manipulation

Not sure what you mean by that, but Wave uses DOM manipulations exclusively (see above).
In fact, I want to launch a command that make some changes on the currently editing content. If this is the only thing missing in Wave editor, I think I can do it. This is not really difficult.

If you're thinking along the way of your "add line" and "drop line" for the table, then that can already be done (and we did it). If you look at the EditorToolbar and how it's used in Wave, you'll see that various buttons (bold, italic, heading level, etc.) are selected/unselected depending on selection in near-real-time.

Damien Picard

unread,
Mar 7, 2012, 1:12:38 PM3/7/12
to google-we...@googlegroups.com
Le 7 mars 2012 18:53, Thomas Broyer <t.br...@gmail.com> a écrit :


On Wednesday, March 7, 2012 4:41:20 PM UTC+1, Damien Picard wrote:


Le 7 mars 2012 15:54, Thomas Broyer a écrit :


On Wednesday, March 7, 2012 2:07:38 PM UTC+1, Damien Picard wrote:
Hi,

You can find a demo here : http://surface-sample.elasticbeanstalk.com/

Thanks.

It's indeed a very young project: you cannot apply style across paragraphs or other styles' boundaries (typical example: "fo<b>o b<i>a</b>r b</i>az" → foo bar baz)
That's one of the hardest things to handle in an editor, and the very first thing I try out ;-)

Thank you to notice this problem ; in fact this is a selection range bug (sometimes the range is not set correctly, but only in prod mode :(  I think I will spent a long time on this...) But the behavior you notice works fine, when the Range works... This is also the first thing I've implemented
 I've fixed the problem, you can play with it ;) (there is some other bugs, but there are all dues to Ranges)

 
Indeed, I'm reinventing the wheel. I did not known the Wave editor, I will take a look at it, but I'm not sure that handling something else than HTML is the right thing to do in my use case. There is some existing wysiwyg editors that uses the same idea of creating inserters instead of using execCommand (Aloha, as an example).
But there is always something missing to me :
  • I need a GWT based wysiwyg (Wave editor, XWiki editor are candidates)
  • I need to create specific inserters
  • I need to control strictly the HTML output (because the HTML is exported with XSLT processors in my use case)
Wave is based on documents that can easily be serialized as XML (that's what we use for persistence).
Because it has to to handle "operational transformation", inline styling (bold, italic, links, etc.) and paragraphs are represented by "markers". Styling is represented by "annotations", so the markers are "annotation boundaries", serialized in XML as processing instructions. Paragraph boundaries are representing by <line/> elements (similar to <br> in HTML except a <line/> marks the beginning of a paragraph, and can have a "type" and "level": title, ordered list, unordered list). These are just the built-in representations though, you're free to implement whatever you want (it'd just require a bit more work).
The "persistent document" is first processed to build a "local document" (<line/>xxx is transformed to <l:p>xxx</l:p>, annotations are transformed to <l:s> spans, etc.), then each element of this document is rendered into HTML. Each modification made on the document (either persistent or local) is passed to the renderer to update the view.
Have a look at http://www.waveprotocol.org/code/tutorials/writing-a-doodad and http://www.waveprotocol.org/wave-protocol-summit/wave-summit-talks (particularly “Wave model deep dive” by Alex North, and “Wave panel and rendering” and “Real-time editor & Doodads” by Dave Hearnden), and search for my mails on the Wave mailing lists, where people answered with many valuable information and links. Re. the code, start with the EditorHarness GWT app.

In our case, we chose to keep the paragraphs-via-<line/> and styling-via-annotations (because it was easier), and added table rendering, links (handled as elements so we can easily make sure we don't nest them), "semantic annotations" (same as links), and illustrations (similar to an image, but links to an entity that carries both the image and legend, among many other things).
In some "rich text areas", we're able to limit available features: some areas a "single paragraph" with only styling a "semantic markup", others allow several paragraphs but no titles, etc.
Finally, by listening to document changes, we keep a document outline, index of "semantic markup" (as CellTree widgets), and lists of tables and illustrations (as CellList widgets) in real-time.

The only thing needing real work is the copy/paste handling, which in Wave is tightly bound to Wave's "wavelet" document schema. In our case, we simply shadowed the class to strip every formatting and paste as plain text.

I've checked out the code ; I will try to extract and use only the editor in a sample project. Maybe you've already done this work ?

I'm building Wave out-of-the-box ("ant dist-libraries" IIRC) and then picking the client, client-common, client-scheduler, common, media, model, and util JARs.
Maybe some of them are only needed for the EditorToolbar which we're also using, but I doubt so.
 
 
Overall, the code is complex but very well thought out, so once you grasped the concepts, it reads fairly easily.
  • I need to process the HTML "in-place", by DOM manipulation

Not sure what you mean by that, but Wave uses DOM manipulations exclusively (see above).
In fact, I want to launch a command that make some changes on the currently editing content. If this is the only thing missing in Wave editor, I think I can do it. This is not really difficult.

If you're thinking along the way of your "add line" and "drop line" for the table, then that can already be done (and we did it). If you look at the EditorToolbar and how it's used in Wave, you'll see that various buttons (bold, italic, heading level, etc.) are selected/unselected depending on selection in near-real-time.

In fact I would like to add Table, Images, etc. facilities, as Aloha uses (The table UI is very useful in Aloha) . And I want to add such behaviours.

--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.

To post to this group, send email to google-we...@googlegroups.com.
To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
Reply all
Reply to author
Forward
0 new messages