Skip to content

Commit

Permalink
feat: exporter done
Browse files Browse the repository at this point in the history
  • Loading branch information
afeiship committed Feb 3, 2021
1 parent 66fd957 commit fd8f8ab
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 18 deletions.
17 changes: 12 additions & 5 deletions public/plugins/bold.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
import React from 'react';
import { jsx } from 'slate-hyperscript';

export default {
name: 'bold',
importer: (el, children) => {
const nodeName = el.nodeName.toLowerCase();
if (nodeName === 'span' && el.style.fontStyle === 'bold') {
return jsx('text', { bold: true }, children);
}
},
exporter: (el) => {
el.style.fontWeight = 'bold';
return el;
},
hooks: {
leaf: (_, { attributes, children, leaf }) => {
return (
<strong {...attributes} data-component="bold">
{children}
</strong>
);
return <strong {...attributes}>{children}</strong>;
}
}
};
17 changes: 12 additions & 5 deletions public/plugins/italic.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
import React from 'react';
import { jsx } from 'slate-hyperscript';

export default {
name: 'italic',
importer: (el, children) => {
const nodeName = el.nodeName.toLowerCase();
if (nodeName === 'span' && el.style.fontStyle === 'italic') {
return jsx('text', { italic: true }, children);
}
},
exporter: (el) => {
el.style.fontStyle = 'italic';
return el;
},
hooks: {
leaf: (_, { attributes, children, leaf }) => {
return (
<em {...attributes} data-component="italic">
{children}
</em>
);
return <em {...attributes}>{children}</em>;
}
}
};
41 changes: 33 additions & 8 deletions src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import noop from '@jswork/noop';
import classNames from 'classnames';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { createEditor, Editor } from 'slate';
import { createEditor, Editor, Text } from 'slate';
import nxCompose from '@jswork/next-compose';
import NxSlateSerialize from '@jswork/next-slate-serialize';
import NxDeslateSerialize from '@jswork/next-slate-deserialize';
Expand Down Expand Up @@ -83,11 +83,14 @@ export default class ReactRteSlate extends Component {
this.editor = composite(createEditor());
this.state = { value };
onInit({ target: { value: this.editor } });

window.editor = this.editor;
window.Editor = Editor;
}

shouldComponentUpdate(inProps) {
const html = inProps.value;
const value = this.handleSerialize('exporter', this.state.value);
const value = this.handleExporter(this.state.value);
if (html !== value) {
this.setState({ value: this.handleSerialize('importer', html) });
}
Expand All @@ -104,28 +107,30 @@ export default class ReactRteSlate extends Component {

renderLeaf = (inProps) => {
const { attributes, children, leaf } = inProps;
const activeMarks = this.getActiveMarks(inProps);
const activePlugins = this.getActivePlugins(leaf);

return (
<span {...attributes}>
{activeMarks.reduce((child, mark) => {
{activePlugins.reduce((child, mark) => {
const { name, fn } = mark;
return leaf[name] && fn(this, { ...inProps, children: child });
}, children)}
</span>
);
};

getActiveMarks(inProps) {
getActivePlugins(inNode) {
const { plugins } = this.props;
const results = [];
for (let key in inProps.leaf) {
for (let key in inNode) {
if (key === 'text') continue;
const plugin = plugins.find((plugin) => plugin.name === key);
plugin &&
results.push({
name: plugin.name,
fn: plugin.hooks.leaf
fn: plugin.hooks.leaf,
exporter: plugin.exporter,
importer: plugin.importer
});
}
return results;
Expand All @@ -145,9 +150,29 @@ export default class ReactRteSlate extends Component {
return Parser.parse(inValue, { process });
}

handleExporter = (inValue) => {
return NxSlateSerialize.parse(inValue, {
process: (node, children) => {
const activePlugins = this.getActivePlugins(node);
// textNode
if (!children) {
// pure text:
if (!activePlugins.length) return node.text;
const el = document.createElement('span'); /** props: serialze:{ tag:'span' } */
el.innerText = node.text;
activePlugins.reduce((el, mark) => {
const { exporter, name } = mark;
return node[name] && exporter(el);
}, el);
return el.outerHTML;
}
return NxSlateDefaults.exporter(node, children);
}
});
};
handleChange = (inEvent) => {
const { onChange } = this.props;
const value = this.handleSerialize('exporter', inEvent);
const value = this.handleExporter(inEvent);
const target = { value: inEvent };
this.setState(target, () => {
onChange({ target: { value } });
Expand Down

0 comments on commit fd8f8ab

Please sign in to comment.