improve visual/raw editor consistency
This commit is contained in:
parent
5cbc76da68
commit
cba631ba1a
@ -157,6 +157,7 @@
|
||||
"redux-notifications": "^2.1.1",
|
||||
"redux-optimist": "^0.0.2",
|
||||
"redux-thunk": "^1.0.3",
|
||||
"rehype-minify-whitespace": "^2.0.0",
|
||||
"rehype-parse": "^3.1.0",
|
||||
"rehype-raw": "^1.0.0",
|
||||
"rehype-react": "^3.0.0",
|
||||
|
@ -8,6 +8,7 @@ import htmlToRehype from 'rehype-parse';
|
||||
import rehypeToRemark from 'rehype-remark';
|
||||
import remarkToMarkdown from 'remark-stringify';
|
||||
import rehypeSanitize from 'rehype-sanitize';
|
||||
import rehypeMinifyWhitespace from 'rehype-minify-whitespace';
|
||||
import rehypeReparse from 'rehype-raw';
|
||||
import CaretPosition from 'textarea-caret-position';
|
||||
import TextareaAutosize from 'react-textarea-autosize';
|
||||
@ -41,6 +42,8 @@ function cleanupPaste(paste) {
|
||||
.use(rehypeSanitize)
|
||||
.use(rehypeReparse)
|
||||
.use(rehypeToRemark)
|
||||
.use(rehypeSanitize)
|
||||
.use(rehypeMinifyWhitespace)
|
||||
.use(remarkToMarkdown, remarkStringifyConfig)
|
||||
.process(paste);
|
||||
}
|
||||
@ -84,7 +87,7 @@ export default class RawEditor extends React.Component {
|
||||
const plugins = registry.getEditorComponents();
|
||||
this.state = {
|
||||
value: unified()
|
||||
.use(htmlToRehype, rehypeParseConfig)
|
||||
.use(htmlToRehype)
|
||||
.use(rehypeToRemark)
|
||||
.use(remarkToMarkdown, remarkStringifyConfig)
|
||||
.processSync(this.props.value)
|
||||
@ -255,13 +258,17 @@ export default class RawEditor extends React.Component {
|
||||
|
||||
handleChange = (e) => {
|
||||
// handleChange may receive an event or a value
|
||||
const value = get(e, ['target', 'value']) || e;
|
||||
const value = typeof e === 'object' ? e.target.value : e;
|
||||
const html = unified()
|
||||
.use(markdownToRemark, remarkParseConfig)
|
||||
.use(remarkToRehype)
|
||||
.use(rehypeSanitize)
|
||||
.use(rehypeMinifyWhitespace)
|
||||
.use(rehypeToHtml, rehypeStringifyConfig)
|
||||
|
||||
.processSync(value)
|
||||
.contents;
|
||||
console.log(html);
|
||||
this.props.onChange(html);
|
||||
this.updateHeight();
|
||||
this.setState({ value });
|
||||
|
@ -107,7 +107,7 @@ const BLOCK_TAGS = {
|
||||
h3: 'heading-three',
|
||||
h4: 'heading-four',
|
||||
h5: 'heading-five',
|
||||
h6: 'heading-six'
|
||||
h6: 'heading-six',
|
||||
}
|
||||
|
||||
const MARK_TAGS = {
|
||||
@ -115,6 +115,7 @@ const MARK_TAGS = {
|
||||
em: 'italic',
|
||||
u: 'underline',
|
||||
s: 'strikethrough',
|
||||
del: 'strikethrough',
|
||||
code: 'code'
|
||||
}
|
||||
|
||||
@ -131,6 +132,12 @@ const BLOCK_COMPONENTS = {
|
||||
'heading-four': props => <h4 {...props.attributes}>{props.children}</h4>,
|
||||
'heading-five': props => <h5 {...props.attributes}>{props.children}</h5>,
|
||||
'heading-six': props => <h6 {...props.attributes}>{props.children}</h6>,
|
||||
'image': props => {
|
||||
const data = props.node && props.node.get('data');
|
||||
const src = data && data.get('src', props.src);
|
||||
const alt = data && data.get('alt', props.alt);
|
||||
return <img src={src} alt={alt} {...props.attributes}/>;
|
||||
},
|
||||
};
|
||||
|
||||
const NODE_COMPONENTS = {
|
||||
@ -139,8 +146,7 @@ const NODE_COMPONENTS = {
|
||||
const href = props.node && props.node.getIn(['data', 'href']) || props.href;
|
||||
return <a href={href} {...props.attributes}>{props.children}</a>;
|
||||
},
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const MARK_COMPONENTS = {
|
||||
bold: props => <strong>{props.children}</strong>,
|
||||
@ -162,6 +168,9 @@ const RULES = [
|
||||
}
|
||||
},
|
||||
serialize(entity, children) {
|
||||
if (['bulleted-list', 'numbered-list'].includes(entity.type)) {
|
||||
return;
|
||||
}
|
||||
const component = BLOCK_COMPONENTS[entity.type]
|
||||
if (!component) {
|
||||
return;
|
||||
@ -203,6 +212,32 @@ const RULES = [
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
deserialize(el, next) {
|
||||
if (el.tagName != 'img') return
|
||||
return {
|
||||
kind: 'inline',
|
||||
type: 'image',
|
||||
nodes: [],
|
||||
data: {
|
||||
src: el.attribs.src,
|
||||
alt: el.attribs.alt,
|
||||
}
|
||||
}
|
||||
},
|
||||
serialize(entity, children) {
|
||||
if (entity.type !== 'image') {
|
||||
return;
|
||||
}
|
||||
const data = entity.get('data');
|
||||
const props = {
|
||||
src: data.get('src'),
|
||||
alt: data.get('alt'),
|
||||
attributes: data.get('attributes'),
|
||||
};
|
||||
return NODE_COMPONENTS.image(props);
|
||||
}
|
||||
},
|
||||
{
|
||||
// Special case for links, to grab their href.
|
||||
deserialize(el, next) {
|
||||
@ -229,6 +264,15 @@ const RULES = [
|
||||
return NODE_COMPONENTS.link(props);
|
||||
}
|
||||
},
|
||||
{
|
||||
serialize(entity, children) {
|
||||
if (!['bulleted-list', 'unordered-list'].includes(entity.type)) {
|
||||
return;
|
||||
}
|
||||
return NODE_COMPONENTS[entity.type]({ children });
|
||||
}
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
const serializer = new SlateHtml({ rules: RULES });
|
||||
@ -237,6 +281,7 @@ export default class Editor extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const plugins = registry.getEditorComponents();
|
||||
console.log(this.props.value);
|
||||
this.state = {
|
||||
editorState: serializer.deserialize(this.props.value || '<p></p>'),
|
||||
schema: {
|
||||
@ -271,6 +316,7 @@ export default class Editor extends Component {
|
||||
b: 'bold',
|
||||
i: 'italic',
|
||||
u: 'underlined',
|
||||
s: 'strikethrough',
|
||||
'`': 'code',
|
||||
};
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
export const remarkParseConfig = { fences: true };
|
||||
export const remarkStringifyConfig = { fences: true };
|
||||
export const remarkStringifyConfig = { listItemIndent: '1', fences: true };
|
||||
export const rehypeParseConfig = { fragment: true };
|
||||
export const rehypeStringifyConfig = {};
|
||||
|
Loading…
x
Reference in New Issue
Block a user