Skip to content

Commit 1d55a35

Browse files
committed
initialize plugin
0 parents  commit 1d55a35

File tree

13 files changed

+30201
-0
lines changed

13 files changed

+30201
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules/

Configuration/Settings.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Neos:
2+
Neos:
3+
Ui:
4+
resources:
5+
javascript:
6+
'Prgfx.Neos.MarkdownView':
7+
resource: resource://Prgfx.Neos.MarkdownView/Public/JavaScript/Plugin/Plugin.js

LICENSE

Lines changed: 674 additions & 0 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
[![Version](https://poser.pugx.org/prgfx/neos-markdown-view/version)](//packagist.org/packages/prgfx/neos-markdown-view)
2+
3+
# Prgfx.Neos.MarkdownView
4+
5+
> composer require prgfx/neos-markdown-view
6+
7+
Provides an inspector view to render markdown text, e.g. for rendering static help text.
8+
9+
## Options
10+
```yaml
11+
ui:
12+
inspector:
13+
views:
14+
helpText:
15+
group: helpText
16+
view: Prgfx.Neos.MarkdownView/MarkdownView
17+
viewOptions:
18+
content: |
19+
**Markdown goes here**
20+
# optional css class for the element in case you want to add custom styling
21+
# (include stylesheets in the Neos.Neos.Ui.resources.stylesheets setting)
22+
className: '...'
23+
# see react-markdown options
24+
# tag names of elements that may get converted, defaults to all
25+
allowedElements: []
26+
# tag names of elements that should not be converted
27+
disallowedElements: []
28+
```
29+
30+
## Notes
31+
32+
### Newlines
33+
The script replaces trailing `\\` with trailing double spaces on your content, so newlines work if trailing spaces are removed from your yaml.
34+
35+
### ClientEval
36+
`ClientEval:` is implemented for the (translated) content.
37+
You can use `node` and `parentNode` in the context.
38+
39+
### Asynchronous Content
40+
If [ClientEval](#clienteval) returns a Promise, the resolved value will be loaded as content.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"compilerOptions": {
3+
"experimentalDecorators": true
4+
}
5+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"private": true,
3+
"scripts": {
4+
"build": "neos-react-scripts build",
5+
"watch": "neos-react-scripts watch"
6+
},
7+
"devDependencies": {
8+
"@neos-project/neos-ui-extensibility": "*"
9+
},
10+
"neos": {
11+
"buildTargetDirectory": "../../Public/JavaScript/Plugin"
12+
},
13+
"dependencies": {
14+
"@neos-project/react-ui-components": "^7.3.3",
15+
"prop-type": "^0.0.1",
16+
"react-markdown": "^8.0.1"
17+
}
18+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import './manifest.js';
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import manifest from '@neos-project/neos-ui-extensibility';
2+
import MarkdownView from './view';
3+
4+
manifest('Prgfx.Neos.MarkdownView', {}, (globalRegistry) => {
5+
const viewsRegistry = globalRegistry.get('inspector').get('views');
6+
viewsRegistry.set('Prgfx.Neos.MarkdownView/MarkdownView', {
7+
component: MarkdownView,
8+
});
9+
});
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import React, { PureComponent } from 'react';
2+
import { connect } from 'react-redux';
3+
import PropTypes from 'prop-types';
4+
import ReactMarkdown from 'react-markdown';
5+
import { neos } from '@neos-project/neos-ui-decorators';
6+
import { selectors } from '@neos-project/neos-ui-redux-store';
7+
8+
const evaluate = (context, _expression) => {
9+
const { node, parentNode } = context; // jshint ignore:line
10+
return eval(_expression.replace('ClientEval:', '')); // jshint ignore:line
11+
}
12+
13+
@neos((globalRegistry) => ({
14+
i18nRegistry: globalRegistry.get('i18n'),
15+
}))
16+
@connect(state => {
17+
const focusedNode = selectors.CR.Nodes.focusedSelector(state);
18+
const parentNode = selectors.CR.Nodes.nodeByContextPath(state)(focusedNode.parent);
19+
20+
return {
21+
focusedNode,
22+
parentNode,
23+
};
24+
})
25+
export default class MarkdownView extends PureComponent {
26+
27+
static propTypes = {
28+
options: PropTypes.shape({
29+
content: PropTypes.string,
30+
className: PropTypes.string,
31+
allowedElements: PropTypes.arrayOf(PropTypes.string),
32+
disallowedElements: PropTypes.arrayOf(PropTypes.string),
33+
focusedNode: PropTypes.object,
34+
parentNode: PropTypes.object,
35+
}).isRequired,
36+
i18nRegistry: PropTypes.object.isRequired,
37+
}
38+
39+
state = {
40+
content: '',
41+
}
42+
43+
constructor(props) {
44+
super(props);
45+
}
46+
47+
componentDidMount() {
48+
this.generateContent();
49+
}
50+
51+
generateContent() {
52+
let content = this.props.options.content || '';
53+
console.log('transient values', this.props.transientValues);
54+
55+
if (content.startsWith('ClientEval:')) {
56+
const context = {
57+
node: this.props.focusedNode,
58+
parentNode: this.props.parentNode,
59+
};
60+
content = evaluate(context, content.replace('ClientEval:', ''));
61+
}
62+
try {
63+
content = this.props.i18nRegistry.translate(content);
64+
} catch (e) {
65+
}
66+
67+
68+
if (typeof content === 'object'
69+
&& 'then' in content
70+
&& typeof content.then === 'function'
71+
) {
72+
content.then(content => {
73+
this.setState({ content });
74+
})
75+
} else {
76+
if (typeof content === 'string') {
77+
content = content
78+
// replace trailing \\ with double spaces to allow for line breaks lost in yaml
79+
.replace(/\\\\\n/g, ' \n');
80+
}
81+
this.setState({ content });
82+
}
83+
}
84+
85+
render() {
86+
const {
87+
className,
88+
allowedElements,
89+
disallowedElements,
90+
} = this.props.options;
91+
92+
return (
93+
<ReactMarkdown
94+
className={className}
95+
allowedElements={allowedElements}
96+
disallowedElements={disallowedElements}
97+
>
98+
{this.state.content}
99+
</ReactMarkdown>
100+
);
101+
}
102+
};

0 commit comments

Comments
 (0)