2016-02-29 14:08:40 +08:00
|
|
|
import React from 'react';
|
2016-03-04 15:19:23 +08:00
|
|
|
import ReactDOM from 'react-dom';
|
2016-03-07 17:33:38 +08:00
|
|
|
import { Link } from 'react-router';
|
2016-04-13 16:48:56 +08:00
|
|
|
import { getTagName, getAttributes, getChildren, isElement } from 'jsonml.js/lib/utils';
|
2016-04-01 16:52:47 +08:00
|
|
|
import toReactComponent from 'jsonml-to-react-component';
|
2016-04-13 16:48:56 +08:00
|
|
|
import VideoPlayer from './VideoPlayer';
|
|
|
|
import ImagePreview from './ImagePreview';
|
2016-02-29 14:08:40 +08:00
|
|
|
|
2016-03-01 16:20:32 +08:00
|
|
|
function isHeading(type) {
|
|
|
|
return /h[1-6]/i.test(type);
|
|
|
|
}
|
|
|
|
|
2016-04-01 16:52:47 +08:00
|
|
|
export function jsonmlToComponent(pathname, jsonml) {
|
2016-04-11 10:12:48 +08:00
|
|
|
return toReactComponent(jsonml, [
|
2016-04-01 16:52:47 +08:00
|
|
|
[(node) => React.isValidElement(node), (node, index) => {
|
|
|
|
return React.cloneElement(node, { key: index });
|
|
|
|
}],
|
|
|
|
[(node) => typeof node === 'function', (node, index) => {
|
|
|
|
return React.cloneElement(node(React, ReactDOM), { key: index });
|
|
|
|
}],
|
2016-04-06 16:14:00 +08:00
|
|
|
[(node) => isHeading(getTagName(node)), (node, index) => {
|
|
|
|
const children = getChildren(node);
|
|
|
|
return React.createElement(getTagName(node), {
|
2016-04-01 16:52:47 +08:00
|
|
|
key: index,
|
2016-04-06 16:14:00 +08:00
|
|
|
id: children,
|
|
|
|
...getAttributes(node),
|
2016-04-01 16:52:47 +08:00
|
|
|
}, [
|
2016-04-29 12:13:27 +08:00
|
|
|
<span key="title">{children.map((child) => toReactComponent(child))}</span>,
|
2016-04-06 16:14:00 +08:00
|
|
|
<Link to={{ pathname, query: { scrollTo: children } }} className="anchor" key="anchor">#</Link>,
|
2016-04-01 16:52:47 +08:00
|
|
|
]);
|
|
|
|
}],
|
2016-04-13 10:13:07 +08:00
|
|
|
[(node) => getTagName(node) === 'pre' && getAttributes(node).highlighted, (node, index) => {
|
|
|
|
return React.createElement('pre', { key: index, lang: getAttributes(node).lang }, React.createElement(
|
|
|
|
'code',
|
|
|
|
{ dangerouslySetInnerHTML: { __html: getChildren(getChildren(node)[0])[0] } }
|
|
|
|
));
|
|
|
|
}],
|
2016-04-13 16:48:56 +08:00
|
|
|
[(node) => getTagName(node) === 'video', (node, index) =>
|
|
|
|
<VideoPlayer video={getAttributes(node)} key={index} />
|
|
|
|
],
|
2016-05-08 17:03:43 +08:00
|
|
|
[(node) => isElement(node) && getTagName(node) === 'a', (node, index) => {
|
|
|
|
if (getAttributes(node).class ||
|
|
|
|
(getAttributes(node).href && getAttributes(node).href.indexOf('http') === 0)) {
|
|
|
|
return toReactComponent(node);
|
|
|
|
}
|
|
|
|
return <Link to={getAttributes(node).href} key={index}>{toReactComponent(getChildren(node)[0])}</Link>;
|
|
|
|
}],
|
2016-04-13 16:48:56 +08:00
|
|
|
[(node) => {
|
2016-04-13 16:55:27 +08:00
|
|
|
return isElement(node) &&
|
|
|
|
getTagName(node) === 'p' &&
|
2016-04-13 16:48:56 +08:00
|
|
|
getTagName(getChildren(node)[0]) === 'img' &&
|
|
|
|
/preview-img/gi.test(getAttributes(getChildren(node)[0]).class);
|
|
|
|
}, (node, index) => {
|
|
|
|
const imgs = getChildren(node)
|
|
|
|
.filter((img) => isElement(img) && Object.keys(getAttributes(img)).length > 0)
|
|
|
|
.map((img) => getAttributes(img));
|
|
|
|
return <ImagePreview imgs={imgs} key={index} />;
|
|
|
|
}],
|
2016-04-11 10:12:48 +08:00
|
|
|
]);
|
2016-02-29 14:08:40 +08:00
|
|
|
}
|
2016-03-23 14:15:00 +08:00
|
|
|
|
|
|
|
export function setTitle(title) {
|
2016-03-23 14:29:16 +08:00
|
|
|
document.title = title;
|
2016-03-23 14:15:00 +08:00
|
|
|
}
|