render plugins on visual editor load

This commit is contained in:
Shawn Erquhart 2017-05-23 14:15:00 -04:00
parent e401f7ef9b
commit 514fbb30b8
3 changed files with 110 additions and 2 deletions

View File

@ -1075,6 +1075,26 @@ Object {
}
`;
exports[`Compile markdown to Prosemirror document structure should compile plugins 1`] = `
Object {
"content": Array [
Object {
"type": "paragraph",
},
Object {
"content": Array [
Object {
"text": "{{< test >}}",
"type": "text",
},
],
"type": "paragraph",
},
],
"type": "doc",
}
`;
exports[`Compile markdown to Prosemirror document structure should compile simple markdown 1`] = `
Object {
"content": Array [

View File

@ -1,3 +1,4 @@
import { fromJS } from 'immutable';
import { Schema } from "prosemirror-model";
import { schema } from "prosemirror-markdown";
@ -7,7 +8,51 @@ const testSchema = new Schema({
nodes: schema.nodeSpec,
marks: schema.markSpec,
});
const parser = makeParser(testSchema);
// Temporary plugins test, uses preloaded plugins from ../parser
// TODO: make the parser more testable
const testPlugins = fromJS([
{
label: 'Image',
id: 'image',
fromBlock: match => match && {
image: match[2],
alt: match[1],
},
toBlock: data => `![${ data.alt }](${ data.image })`,
toPreview: data => <img src={data.image} alt={data.alt} />,
pattern: /^!\[([^\]]+)]\(([^)]+)\)$/,
fields: [{
label: 'Image',
name: 'image',
widget: 'image',
}, {
label: 'Alt Text',
name: 'alt',
}],
},
{
id: "youtube",
label: "Youtube",
fields: [{name: 'id', label: 'Youtube Video ID'}],
pattern: /^{{<\s?youtube (\S+)\s?>}}/,
fromBlock: function(match) {
return {
id: match[1]
};
},
toBlock: function(obj) {
return '{{< youtube ' + obj.id + ' >}}';
},
toPreview: function(obj) {
return (
'<img src="http://img.youtube.com/vi/' + obj.id + '/maxresdefault.jpg" alt="Youtube Video"/>'
);
}
},
]);
const parser = makeParser(testSchema, testPlugins);
describe("Compile markdown to Prosemirror document structure", () => {
it("should compile simple markdown", () => {
@ -127,6 +172,15 @@ How far is it to [Google](https://google.com) land?
expect(parser(value)).toMatchSnapshot();
});
it("should compile plugins", () => {
const value = `
![test](test.png)
{{< test >}}
`;
expect(parser(value)).toMatchSnapshot();
});
it("should compile kitchen sink example", () => {
const value = `
# An exhibit of Markdown

View File

@ -9,6 +9,7 @@ const visit = require("unist-util-visit");
const { Mark } = require("prosemirror-model");
let schema;
let plugins
let activeMarks = Mark.none;
let textsArray = [];
@ -36,6 +37,38 @@ const processMdastNode = node => {
textsArray = [];
return pNode;
} else if (node.type === "paragraph") {
// TODO: improve plugin handling
// Handle externally defined plugins (they'll be wrapped in paragraphs)
if (node.children.length === 1 && node.children[0].type === 'text') {
const value = node.children[0].value;
const plugin = plugins.find(plugin => plugin.get('pattern').test(value));
if (plugin) {
const nodeType = schema.nodes[`plugin_${plugin.get('id')}`];
const data = plugin.get('fromBlock').call(plugin, value.match(plugin.get('pattern')));
return nodeType.create(data);
}
}
// Handle the internally defined image plugin. At this point the token has
// already been parsed as an image by Remark, so we have to catch it by
// checking for the 'image' type.
if (node.children.length === 1 && node.children[0].type === 'image') {
const { url, alt } = node.children[0];
// Until we improve the editor components API for built in components,
// we'll mock the result of String.prototype.match to pass in to the image
// plugin's fromBlock method.
const matches = [ , alt, url ];
const plugin = plugins.find(plugin => plugin.id === 'image');
if (plugin) {
const nodeType = schema.nodes.plugin_image;
const data = plugin.get('fromBlock').call(plugin, matches);
return nodeType.create(data);
}
}
node.children.forEach(childNode => processMdastNode(childNode));
const pNode = schema.node("paragraph", {}, textsArray);
textsArray = [];
@ -121,9 +154,10 @@ const compileMarkdownToProseMirror = src => {
return doc;
};
module.exports = (s, plugins) => {
module.exports = (s, p) => {
//console.log(s)
//console.log(s.nodes.code_block.create({ params: { language: 'javascript' } }))
schema = s;
plugins = p;
return compileMarkdownToProseMirror;
};