opencoweb / coweb

Open Cooperative Web Framework
Other
232 stars 29 forks source link

Create RichTextEditor Widget #95

Closed bitpshr closed 12 years ago

bitpshr commented 13 years ago

This issue should serve as a running discussion on how to implement basic rich text functions for the coweb editor widget.

I've begun the basic implementation, and my thinking is as follows:

I'll keep updating this with progress I make. Feel free to post any ideas, corrections, etc.

bitpshr commented 13 years ago

As of commit 3ae14ef996dce8206993 :

TODO:

bitpshr commented 13 years ago

We now have ops being queued, and we are operating on a string copy of the current textarea's value attr, then blasting this copy into the DOM only once for each cycle of iterate( ). Cursor position is holding strong even in some pretty extreme cases.

The problem: In toying around with switching from a textarea to a contentEditable div, cursor position getting/setting is horrendous. Even solutions that (somewhat) work are blown out the water as soon as html tags are entered into the mix.

bitpshr commented 13 years ago

Proposed solution: use dijit.editor instead of textarea.

Anything we do with a contentEditable div is a hack, and even that's an extreme understatement.

Let's bite the bullet and use dijit.editor? Why reinvent the wheel? Coweb is about making things collaborative, not building rich text editors. Plus, we ARE a part of the Dojo Foundation, right? :) I will begin experimenting with this now.

bitpshr commented 13 years ago

Dijit.editor is definitely the way to go; we have all rich text functionality syncing beautifully: bold, italic, underline, center justify, left justify, right justify, strikethrough, etc.

Unfortunately, we hit the same problem: caret position is a pain. Why are there no native dijit.Editor functions to programmatically get / set caret position?

Toying with dijit.range currently.

parente commented 13 years ago

Two comments:

This should be a second widget, RichTextEditor, not replace the simple one which is useful in its own right.

When I last looked at dijit.Editor and others, none of thm offered the caret tracking and control needed for a collab editor.

bitpshr commented 13 years ago

You're definitely correct, no caret tracking or control on the dijit.Editor, or with a content editable div. I've got to research this one a little more if we can't pull in any other open source library.

bitpshr commented 13 years ago

As Pete suggested and Dan confirmed, I began independently developing the RichTextEditor widget.

Due to caret position woes with contentEditable divs and time constraints, the decision was to wrap the current Editor widget with basic rich text functionality, and apply styling to the whole textarea, since we can't selectively style this type of html tag.

bitpshr commented 13 years ago

As of 0bf2e87ab3c70fc7b1ff :

Will add any further functionality we desire

parente commented 13 years ago

Not sure I understand the last commit. It's syncing style over the whole area? Or span of text within it?

bitpshr commented 13 years ago

@parente :

For time's sake and for sanity's sake we decided to demonstrate rich text functionality over the textarea as a whole, so we don't have to dig into contentEditable div's or the like, since caret tracking is a shoddy hack.

The last commit should include a new widget, RichTextEditor, that extends the Editor widget, wrapping it with a dijit.Toolbar, and the basic functions above. When a user uses any of these functions it's respective style is applied to the textarea as a whole, collaboratively.

bitpshr commented 13 years ago

Was the final decision to keep the RichTextEditor even though it risks looking incomplete? If so, as discussed, I feel we should change the name.

I still say if we do the RTE, we should do it right, built on top of a canvas element or something similar. It will be an in depth project, but a strong application with actual user appeal. I'm in the process of implementing visible remote carets, aka who wrote what, who's editing where, etc. on the plain Editor, and this may make that widget powerful enough for most users for collab text editing and render the current RichTextEditor widget pretty useless.

vinomaster commented 13 years ago

* DESIGN REDIRECTION * Issue #56 allowed us to capture two very basic cooperative web enabled text editors based on the HTML Textbox element. As noted in this issue and in issue #56 the textbook element has several limitations. Given that we have captured and demonstrated the basic editor functionality, we will now use this issue to explore the creation of a proper Cooperative Web enabled Rich Text Editor based on an HTML

element.

The resulting widget from this effort will represent a 3rd entry in our cowebx widgets pertinent to Cooperative Editors:

  1. BasicTextboxEditor
  2. EnhancedTextboxEditor
  3. RichTextEditor

All three editors will provide support for persistence via emailing snapshots of the editor content. As such, analogous to how Issue #91 updated the Basic and Enhanced textbook Editors, the widget produced for this issue (#95) should have an export/share button.

bitpshr commented 13 years ago

Update to RTE progress:

  • Actual text values within our own DIV are staying in sync and functioning properly with our previous Iteration LD method for touching the OT engine.
  • Caret movement is a different monster than with the textarea: with the textarea, we had to change the position of the caret when remote text was entered depending on its position relative to the local caret, because the caret wouldn't move. With our DIV implementation, the caret position does move and stay within the flow of the text, which is a good thing and makes our life easier.
  • The tricky part to all of this is mimicking moving the caret up / down, since wrapped spans within a div don't provide BR tags to let us know where wrap points in the text are. I came up with an algorithm that gets pretty darn close to the real behavior, and I've been hammering away on this currently.

Once we get the caret movement up-to-snuff, RTE functions are next...

bitpshr commented 13 years ago

As of 36146089697102781faf :

  • Click to reposition implemented using Point in Polygon logic, highly optimized for our case (always a rectangle)
  • Code changed to allow correct cross-browser compatibility. Works with Webkit now too.

TODO:

  • Cut, copy, paste solution that works in Webkit too (the hiddenDiv trick only working in FF)
  • RTE functions
bitpshr commented 13 years ago

As of d89c35b89b9f11fbf2f5 :

  • Click to reposition
  • Click to highlight / select (double Point in Polygon...)
  • Cut
  • Copy
  • Paste

All cross browser. Cleaning things up now, making things look clean. Optimizing.

bitpshr commented 13 years ago

As of 6b7a233dd8573ff614be :

  • Code heavily cleaned
  • value.string converted to an array of objects to support rich text function implementation
  • Bold, italic, underline implemented, syncing, working cross-browser
  • Dijit.toolbar and dijit.form.ToggleButtons used for the UI
  • Implemented styling algorithm (determines what styles the majority of the selected text has, etc.)

TODO:

  • Fix LD bug, talk with @parente about a solution when he's free
  • Fix click-to-reposition bug where you can't click on a linebreak
  • Add more rich text functions
bitpshr commented 13 years ago

As of 005c63f6506cb37cc80f :

  • TimeSlider widget added and implementation working
  • Code cleaned up
  • Experimentation with partialRender vs. render and performance improvements

TODO:

  • Add a "Restore" and "Play" button to TimeSlider, sync on "Restore" or unFocus
  • Make all classes blind of one another
bitpshr commented 13 years ago

As of 4020c0925c1af948ac01 :

  • Play and Revert button added to TimeSlider, implementation working for each
  • Classes are more blind to one another. Still some work we can do here. Anything that's dependent on another class in the app fails silently; for now this is OK.
  • Document title, collaborative
  • Line / Column info box in footer
  • A bunch of border case fixes via unit testing catches
bitpshr commented 13 years ago

As of 388f05776bff2013ead6 :

  • Determined and implemented model for TimeSlider sharing / undo
  • Stopped rogue sync on timeslider onBlur
  • Remote styling type implementation (user pushes BOLD, types, remote users see bold text)
  • space causing new line bug fixed with pastes
  • contentEditable / sandbox title backspace bug fix
  • synced title

TODO:

  • ld bug
  • basic (and rte?) three user bug
  • Support click ANYWHERE (even BRs)
  • demodev server issues
  • large document handling
bitpshr commented 13 years ago

Implemented pseudo-session control. Parses relative url of app, if not unique, makes unique and hides splash screen:

Splash Screen

bitpshr commented 13 years ago

Application facelift, progress:

Coedt State

bitpshr commented 13 years ago

As of d89d855a9cffb618e27b :

  • Strikethrough: implemented successfully. Though I think this is pointless, *therpad touts it as a huge feature that sets them apart?
  • Colors: Foreground and background, began implementation. This one is a little more heavyweight in terms of creating hidden palettes, etc. But should be OK by the end of today. No other RTCE has these features.
  • Line numbers implemented
  • Home screen button
  • New document button
  • Warning dialogs when leaving a document
  • Title in lower left icon + click to edit
  • Major code / readability cleanup: light doc throughout, instance vars all explicit, etc.
bitpshr commented 13 years ago

Application progress:

Coedt State

bitpshr commented 13 years ago

Just to note the main TODOs:

  • ld bug
  • attendee list of some sort
  • basic (and rte?) three user bug
  • click to reposition fix
  • demodev server issue
  • large document handling / heavy optimization
bitpshr commented 13 years ago

As of 1db60e28fb99287b43a3 :

In this commit

  • Large documents optimization - basically never do a full render(), instead, render selectively
  • Send styling as single atom with char fixed
  • no longer join session on splash screen
  • cleaned splash screen
  • home button & alert dialog when leaving document added
  • title bug fixed
  • min-width for line numbers
  • alert before new document in case loss of data
  • fullscreen by default
  • line numbers fixed
  • Scrolls to stay with typing by default
  • font color, highlight color, strike-through added

Remaining bugs:

  • basic (and rte?) three user: mistyping occurs, possibly ping-pong
  • historySlider: as we slide, we do full render( )s, which is slow with large documents
  • style on refresh: when we refresh, something with the DOM lingers and messes up styling
  • ld bug: " |abc " with an insert of an "a" at the cursor position 0, results in an insert at 1
  • Demodev server issue

Remaining features:

  • Fallback in case Point in Polygon fails: go to end of closest line?
  • Attendee list with attendance API
bitpshr commented 13 years ago

As of bbcfa06fa6f1c5bf8dbb :

In this commit

  • Scroll to stay with typing working cross-browser
  • Large documents Optimization finalized
  • cut now syncs, wasn't before
  • cleaned up copy/paste, added support for keeping newLines
  • ShareButton moved into RTE for now, got too specific. Generalizing and pulling out...
  • Go to end of line if PiP test fails on click to reposition

Remaining features:

  • Click to reposition on empty lines
  • Slim attendee list with attendance API
  • Optimize onRemoteStyle and do away with last remaining full render( )

Remaining bugs:

  • history slider intentionally broken atm
  • shift+moveDown/Up to highlight
  • basic (and rte?) three user bug
  • ld bug
bitpshr commented 12 years ago

As of 6dbe1eaf5ae38150d085de0eaa5a2f39b044ede7 , the RTE widget first pass is complete, with the following features / improvements / bugs still remaining for the future:

  • optimize slider
  • add play button back to slider
  • ld bug

Any new errors experienced when using the Editor should be filed as a new issue.