Coder Social home page Coder Social logo

ritzy's Introduction

Ritzy Editor

Join%20Chat license Apache blue ritzy ritzy

About

Demo / Short Introduction (TL;DR)

Finally, a good, open source, cross-browser [1], rich text, real-time, embeddable, collaborative editor for the web! Here is a demo:

[1] IE10+ and evergreen browsers supported, perhaps earlier browsers will work too.

Note that the code is alpha quality.

Longer Introduction

The Ritzy editor is a rich text, real-time character-by-character collaborative embeddable browser-based editor. It shuns use of the contentEditable attribute in favor of a custom editor surface and layout engine, exactly like the approach implemented by Google Docs.

In addition, and also like Google Docs, Ritzy is built with real-time collaborative editing support from the ground up, unlike most browser-based editors that require third-party plugins or that do not support it at all. The underlying mechanism for this is a causal tree CRDT.

Ritzy implements all the basic expected text editing functionality, such as bold, underline, strikethrough, superscript, subscript, selection via keyboard and mouse, cut, copy, and paste. More capabilities will be added as needed or as third-party contributions are received.

Features

  • Real-time collaborative text editing just like Google Docs, with all the basic standard editing features and shortcuts.

  • Multiple author colored/labeled cursor and selection tracking in real-time.

  • Paragraph flow control, including wrapping support for long words/URLs.

  • Selection and keyboard navigation behavior mimicking common platforms like Microsoft Word and Google Docs.

  • Cursor decorations such as blinking with focus and idle, slant when traversing italic text, and invisible when there is no focus.

  • Selection decorations such as gray-out when editor does not have focus.

  • Automatically scrolling the document window horizontally and vertically to keep the cursor visible.

  • Cut/copy/paste of clipboard data, including conversion between rich text and HTML, including support for copy/paste to/from Microsoft Word.

  • API to control the editor and to obtain selections as rich text, HTML, or plain text.

  • Input handling and support for non-english languages.

  • Offline simultaneous editing.

Limitations and Target Audience

Unlike Google Docs, Ritzy does not (currently) support complex page-based layout needed to build a word processor. It will be most useful for those developers who wish to add collaborative rich-text data entry fields to their browser applications. However, some layout capabilities are planned to be added over time, such as bulleted and numbered lists, styles, and other such features.

Mobile Support

Mobile is partially supported. On a Nexus 5 and Nexus 7 with a recent Chrome, the following seem to work:

  • basic text entry (though there are some quirks – for some reason the phone wants to capitalize every word and not enter spaces automatically),

  • cursor positioning, and

  • real-time view of other people’s cursors, selections, and typing.

Ritzy has not yet been tested on any iOS devices, but it is likely with some tweaking similar capabilities as noted above will be possible on any recent model.

Selections do not work at all. It is possible that this is an intractable problem with the editor as it exists today, given how selections on mobile work. One possible solution is to take the same approach that Google appears to have taken with Docs – for editing, create a native component that talks the same underlying data exchange language for collaboration, but with native rendering of the editor and interaction with the user. There are no immediate plans to work on this.

As an aside, similar integration could be done for native desktop editors.

Production Readiness

The code is alpha quality. Lots of real-world testing is needed. While the client side is pretty performant once the editor is loaded, lots of optimization work remains to be done, especially on the underlying CRDT data structures.

Supported Data Formats

Ritzy can import and export data in JSON, HTML, and text. See API Content and API Selection.

Rich Text JSON

Ritzy can import and export a JSON structure containing an array of text chunks with associated attributes. These attributes are currently boolean values for bold, italics, and so forth, but could in the future include other values such as style names.

Tip
This format is "full fidelity" i.e. exported rich text data is guaranteed to be imported exactly. Here is an example:
let content = [
  { 'text': 'This is some ', 'attrs': null },
  { 'text': 'bold', 'attrs': {'bold': true} },
  { 'text': ' text.', 'attrs': null }
]

HTML

Ritzy can import and export HTML. This is used internally by the editor when copying/pasting rich text to external applications such as Word or Google Docs.

Plain Text

Ritzy can import and export plain text. This is used internally by the editor when copying/pasting plain text to external applications such as text editors.

Native Causal Tree CRDT

The internal data model for the editor is a causal tree CRDT described in the DESIGN.

In addition to the formats described above which will be used most often, this data is also accessible via the API.

Warning
This format is not final, and is subject to change in future versions.

Usage

Ritzy is an ES6 React component with an optional API wrapper. Currently, it does require a server-side implementation to support collaborative editing. In the future, this will be optional.

See the INSTALLATION document for information about how to integrate Ritzy into your client and server-side infrastructure.

Roadmap

The following is a tentative list of features and capabilities that will be added over time. Contributions are welcome.

  • Tests (many, see GitHub issue xx) (hard!).

  • Once tests are in place, refactoring to make the editor code more modular / easier to understand (hard).

  • Undo/redo (hard).

  • Make Ritzy work without a shared replica and server implementation — create a local-only replica with the same API (medium).

  • Performance improvements. Performance is pretty good right now, but much can be done to improve it further. Some ideas:

    • Use immutable collections as much as possible e.g. http://facebook.github.io/immutable-js/

    • Implement some type of compression and/or indexing for characters within the causal tree CRDT.

    • Clear stale data from the causal tree CRDT, such as deletions (but keep enough for revision history).

    • Cache frequently used / slow operations where possible.

    • Server-side performance improvements. Currently the initial load can become very slow as the replica continues to grow.

  • Styles for content e.g. headings, lists, etc. (medium).

  • Add to the API (easy):

    • Insert HTML at a particular position specified by the native data model

    • Command and status support for text attributes e.g. to support a toolbar

    • See Historic Editing APIs for comparison/implementation with contentEditable-based APIs.

  • A skinnable and/or replaceable toolbar that leverages the editor API (medium).

  • Test and support editor fonts other than OpenSans (easy to medium?).

  • Handle font size as a character attribute (medium to hard).

  • Reduce the number of dependencies and lower download size as much as is possible without sacrificing clarity and maintainability.

  • Search/replace (TODO).

  • Figures and tables (TODO).

  • Bullets and numbering (TODO).

  • Inline images (TODO).

  • Right-click menu support (medium).

  • Color-coded authoring display (medium).

  • Text highlighting (easy to medium?).

  • History/timeline/revision view (hard).

  • Drag and drop support (medium).

Commercial Features (Future)

In addition to the editor which will remain free and open source, VIVO Systems, the organization behind Ritzy, is considering offering the Ritzy editor as a service. A server-side component is required for real-time collaboration.

Note
A simple but working server-side component is bundled. See the INSTALLATION documentation.

The commercial server-side solution will handle storage, communications, security, availability, and provide a simple but powerful server-side API for developers to interact with the editors under their control, and the data they contain. Some of the features of this API may include:

  • Create, archive, and destroy text replicas.

  • User identification and specification of authoring labels.

  • Set and modify access control.

  • Get editor contents (snapshot + real-time bidirectional push).

    • Integration with various server-side libraries e.g. Akka, Vert.X, RxJava, Kafka, etc.

  • Set or modify editor contents.

  • Show server feedback on editor surface e.g. comments/errors/word highlights.

  • Get revision history.

  • Get editing statistics e.g. authors, character count overall and by author, word count overall and by author, time spent editing overall and by author, and so forth.

  • Isomorphic rendering of editor’s server-side and client-side for performance.

Please let us know if your company or startup may be interested in such a service.

Developers

Support

Support is provided on an as-available basis via GitHub issues.

Contact [email protected] @ VIVO Systems for paid support or enhancements.

ritzy's People

Contributors

rocketraman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ritzy's Issues

Concurrent insertions do not result in correct replica state

When two or more sessions are doing a concurrent insertion at the same position, the replica state does not include all of the inserted chars. One editor (incorrectly) shows all the typed text, but upon a refresh or upon receiving updated ops from the server, the editor state becomes invalid.

Question about style conflicts

If it is not a big problem, I would have a small question about the CRDT of the editor: How did you solve attribute update conflicts?

Scenario:

  1. User A and user B both offline.
  2. User A makes atom X bold.
  3. User B makes atom X bold.
  4. User B makes atom X non-bold.
  5. User A and user B both go online.
  6. User A have to following operations for atom X: (bold) + (bold + not-bold) => (not-bold)
  7. User B have to following operations for atom X: (bold + not-bold) + (bold) => (bold)
  8. User A and user B have a different version of atom X after they have received every operation.

Arabic Scripts

I know RTL languages are currently not supported, but just as a note for the isOpenTypeJsReliable function: The OpenType char-by-char approach is not viable for some scripts (like arabic), because characters are different depending on whether they are standalone, or merged together.

Was the canvas measuring a speed concern, or why was the OpenType measuring mechanism chosen?

Npm error while installing packages :npm i

npm i

[email protected] install
gulp build

fs.js:43
} = primordials;
^

ReferenceError: primordials is not defined
at fs.js:43:5
at req_ (/home/rohit/Desktop/ritzy-demo/node_modules/natives/index.js:143:24)
at Object.req [as require] (/home/rohit/Desktop/ritzy-demo/node_modules/natives/index.js:55:10)
at Object. (/home/rohit/Desktop/ritzy-demo/node_modules/vinyl-fs/node_modules/graceful-fs/fs.js:1:37)
at Module._compile (node:internal/modules/cjs/loader:1356:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1414:10)
at Module.load (node:internal/modules/cjs/loader:1197:32)
at Module._load (node:internal/modules/cjs/loader:1013:12)
at Module.require (node:internal/modules/cjs/loader:1225:19)
at require (node:internal/modules/helpers:177:18)

Node.js v18.19.1
npm error code 1
npm error path /home/rohit/Desktop/ritzy-demo
npm error command failed
npm error command sh -c gulp build
npm error A complete log of this run can be found in: /home/rohit/.npm/_logs/2024-06-07T07_38_35_754Z-debug-0.log

When inserting characters with no font glyph match cursor positioning incorrect

If characters are inserted for which the Opentype font has no glyph, the code assigns a default width of 0 to the character. This causes the line wrapping and cursor positioning logic to be incorrect.

Instead of assigning a default width of 0, fallback to a canvas-based measurement to see the width the browser will use when rendering the character.

Local operations intersecting with a remote selection handled poorly

If a remote selection overlaps some local operations (inserts, deletes, etc.) this is handled poorly -- the selection becomes invalid and the editor sometimes blows up, or just destroys the selection completely.

All peers should modify their local selections based on any insert/delete operations arriving from remote peers. In addition, peers should locally modify remote selections as well -- even though these remote selections will be corrected by the remotes soon, there is a brief period during which the remote selection will be invalid (which can cause flashing of the selection and other odd UX behaviors).

dist directory missing

INSTALLATION instructions mention a dist/ directory with pre-compiled client-side files. I cannot find this, could you please advise?

Normally in this case I would go download the resources off the demo site instead, but the demo site is down (serving 503). Could you take a look?

Cheers,
Tom

white-space: pre instead of  

Is there a good reason you're not using white-space: pre instead of replacing all spaces with  ? (  isn't enough to cover all cases anyway)

Scroll to cursor function is too greedy

When the editor is re-rendered (could be because a remote change was received, or for some other reason like a focus change), if the local editor has been scrolled via the scroll bar so that the local cursor is invisible, the rerender causes the local editor to modify the scroll position so that the local cursor is visible.

The automatic scroll behavior should only be enabled for cursor-based navigation or editing.

On large insert (e.g. paste), client-side method execution failed

Paste a large block of text into the editor. An error similar to the following will occur in Swarm.js and the insertion fails:

method execution failed Spec {value: "/Text#10!2y4wk+A0017r~0.insert", index: 23} Object {2y4wj+A0017r~0: Object} Error: malformed timestamp value: 2y4wk1T0

Demo website down

hi, just wanted to let you know that the demo website seems to have a problem.
http://demo-ritzy.rhcloud.com

Service Temporarily Unavailable

The server is temporarily unable to service your request due to maintenance downtime or capacity problems. Please try again later.

Apache/2.2.15 (Red Hat) Server at demo-ritzy.rhcloud.com Port 80

Inline media assets (images, etc.)

I'd like to contribute with the ability to include inline assets (such as images, youtube videos, etc). Is the level of effort on this unrealistically high? I see that the data model focuses on individuals characters syncing over Swarm, but has the door been left open for non-text elements?

Need global error handler / refresh advice

In case of errors, the state of the editor can be corrupted and weird things subsequently happen. Need to create a global error handler such that such errors can be captured, logged (to a remote server also?), and then the user is prompted to refresh the editor so that they can resume editing on a known good state.

how to build and run ritzy-demo

Hi,

I have tried to see the demo online, but it is not working at the moment.

I have tried to run from the source but there is no instructions.

I did:

npm install

npm run start

but the start command does: "start": "node build/server.js"

but there is no build folder.. and there is no build script in the package.json.. and no instruction as how to build..

I have also tried: babel-node src/server.js

but gives an error:

babel-node src/server.js
/Volumes/DevCard/Developer/react-stuff/ritzy-demo/node_modules/babel-core/lib/polyfill.js:8
throw new Error("only one instance of babel/polyfill is allowed");

.. would appreciate build/run instructions in the demo project..

Thanks and keep up with the great work.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.