This repository has been archived on 2022-08-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
outline/frontend/scenes/Document/components/Editor/schema.js
Jori Lallo ff17047791 Slate editor (#38)
* WIP: Slate editor

* WIP

* Focus at start / end working

* ah ha

* Super basic floating toolbar

* Nested list editing

* Pulling more logic into plugins

* inline code markdown

* Backspace at end of code block should remove mark

* Ensure there is always an empty line at editor end

* Add keyboard shortcuts for bold, italic, underline

* Add strikethrough shortcode and toolbar

* Toolbar to declarative
Fixed paragraph styling
Removed unused stuffs

* Super basic link editing

* Split Toolbar, now possible to edit and remove links

* Add new link to selection from toolbar working

* Ensure toolbar doesn't extend off screen

* Fix minor js issues, disable formatting of document title

* Boom, icons

* Remove codemirror, fix MD parsing issues

* CMD+S now saves inplace

* Add --- shortcut for horizontal rule

* Improved styling for link editor

* Add header anchors in readOnly

* More readable core text color

* Restored image file uploading 🎉

* Add support for inline md syntax, ** __ etc

* Centered

* Flooooow

* Checklist support

* Upgrade edit list plugin

* Finally. Allow keydown within rich textarea

* Update Markdown serializer

* Cleanup, remove async editor loading

* Editor > MarkdownEditor
Fixed unsaved changes warning triggered when all changes are saved

* MOAR typing

* Combine edit and view

* Fixed checkboxes still editable in readOnly

* wip

* Breadcrumb
Restored scroll

* Move document scene actions to menu

* Added: Support for code blocks, syntax highlighting

* Cleanup

*  > styled component

* Prevent CMD+Enter from adding linebreak

* Show image uploading in layout activity indicator

* Upgrade editor deps

* Improve link toolbar. Only one scenario where it's not working now
2017-05-17 19:36:31 -07:00

95 lines
3.2 KiB
JavaScript

// @flow
import React from 'react';
import Code from './components/Code';
import Image from './components/Image';
import Link from './components/Link';
import ListItem from './components/ListItem';
import Heading from './components/Heading';
import type { Props, Node, Transform } from './types';
import styles from './Editor.scss';
const schema = {
marks: {
bold: (props: Props) => <strong>{props.children}</strong>,
code: (props: Props) => <code>{props.children}</code>,
italic: (props: Props) => <em>{props.children}</em>,
underlined: (props: Props) => <u>{props.children}</u>,
deleted: (props: Props) => <del>{props.children}</del>,
added: (props: Props) => <mark>{props.children}</mark>,
},
nodes: {
paragraph: (props: Props) => <p>{props.children}</p>,
'block-quote': (props: Props) => <blockquote>{props.children}</blockquote>,
'horizontal-rule': (props: Props) => <hr />,
'bulleted-list': (props: Props) => <ul>{props.children}</ul>,
'ordered-list': (props: Props) => <ol>{props.children}</ol>,
'todo-list': (props: Props) => (
<ul className={styles.todoList}>{props.children}</ul>
),
table: (props: Props) => <table>{props.children}</table>,
'table-row': (props: Props) => <tr>{props.children}</tr>,
'table-head': (props: Props) => <th>{props.children}</th>,
'table-cell': (props: Props) => <td>{props.children}</td>,
code: Code,
image: Image,
link: Link,
'list-item': ListItem,
heading1: (props: Props) => <Heading placeholder {...props} />,
heading2: (props: Props) => <Heading component="h2" {...props} />,
heading3: (props: Props) => <Heading component="h3" {...props} />,
heading4: (props: Props) => <Heading component="h4" {...props} />,
heading5: (props: Props) => <Heading component="h5" {...props} />,
heading6: (props: Props) => <Heading component="h6" {...props} />,
},
rules: [
// ensure first node is a heading
{
match: (node: Node) => {
return node.kind === 'document';
},
validate: (document: Node) => {
const firstNode = document.nodes.first();
return firstNode && firstNode.type === 'heading1' ? null : firstNode;
},
normalize: (transform: Transform, document: Node, firstNode: Node) => {
transform.setBlock({ type: 'heading1' });
},
},
// remove any marks in first heading
{
match: (node: Node) => {
return node.kind === 'heading1';
},
validate: (heading: Node) => {
const hasMarks = heading.getMarks().isEmpty();
const hasInlines = heading.getInlines().isEmpty();
return !(hasMarks && hasInlines);
},
normalize: (transform: Transform, heading: Node) => {
transform.unwrapInlineByKey(heading.key);
heading.getMarks().forEach(mark => {
heading.nodes.forEach(textNode => {
if (textNode.kind === 'text') {
transform.removeMarkByKey(
textNode.key,
0,
textNode.text.length,
mark
);
}
});
});
return transform;
},
},
],
};
export default schema;