Data Structure
Data structure refers to how data is represented in software.
Data structures are programming language-agnostic, which is highly beneficial for data exchange between different programming languages.
Node
The data structure in JuiceEditor is primarily composed of Nodes. A Node is the most fundamental data structure in JuiceEditor, and all content is made up of Nodes.
Definition
Node is a programming language-agnostic data structure. For clarity, we’ll define it using TypeScript.
interface Node {
type: string;
html?: string;
text?: string;
attrs?: Record<string, any>;
content?: Node[];
}
A Node is an object that contains the following properties:
- type: Node type
- html: HTML string corresponding to the node
- text: Text string corresponding to the node
- attrs: Attributes corresponding to the node
- content: Child nodes contained within the node
Node Types
JuiceEditor has many node types, and more may be added. The main ones are:
- root: Root node, contains all other nodes
- text: Text node, the most basic node type, has no child nodes
- paragraph: Paragraph node, contains text nodes
- heading: Heading node, contains text nodes
- list: List node
- quote: Quote node
HTML
Only the root node has the html property; other nodes do not.
For example:
const node: Node = {
type: 'root',
html: '<div data-type="root"><h1>Hello, world!</h1><p>This is a paragraph.</p></div>',
};
HTML stores all document data and can be converted to and from a Root node.
The above example converted to a Root node becomes:
{
type: 'root',
content: [
{
type: 'heading',
attrs: { level: 1 },
content: [{ type: 'text', text: 'Hello, world!' }]
},
{
type: 'paragraph',
content: [{ type: 'text', text: 'This is a paragraph.' }]
}
]
};
When storing this data in a database, sometimes it needs to be flattened into an array of Nodes.
const nodes: Node[] = [
{ type: 'root' },
{ type: 'heading', attrs: { level: 1 } },
{ type: 'text', text: 'Hello, world!' },
{ type: 'paragraph' },
{ type: 'text', text: 'This is a paragraph.' },
];
In the database, it appears as multiple rows:
id | type | text | parent_id |
---|---|---|---|
1 | root | null | null |
2 | heading | null | 1 |
3 | text | ’Hello, world!‘ | 2 |
4 | paragraph | null | 1 |
5 | text | ’This is a paragraph.‘ | 4 |
Data
EditorData contains all the data in the editor.
Definition
EditorData is a programming language-agnostic data structure. For clarity, we’ll define it using TypeScript.
interface EditorData {
title: string;
html: string;
node: Node;
wordCount: number;
characterCount: number;
}
EditorData is an object that contains the following properties:
- title: Document title
- html: Document HTML string
- node: Document node object, an alternative representation of the HTML
- wordCount: Number of words in the document
- characterCount: Number of characters in the document
When document content changes, JuiceEditor automatically updates the data in EditorData and passes it externally.
Example
const editorData: EditorData = {
title: 'Hello, world!',
html: '<div data-type="root"><h1>Hello, world!</h1><p>This is a paragraph.</p></div>',
node: {
type: 'root',
content: [
{
type: 'heading',
attrs: { level: 1 },
content: [{ type: 'text', text: 'Hello, world!' }],
},
{
type: 'paragraph',
content: [{ type: 'text', text: 'This is a paragraph.' }],
},
],
},
wordCount: 1,
characterCount: 1,
};