Skip to content

Commit 9c34738

Browse files
authored
Merge pull request #1 from PRGfx/fix-plugin
2 parents c301d04 + 49f0b22 commit 9c34738

File tree

8 files changed

+340
-9138
lines changed

8 files changed

+340
-9138
lines changed

.editorconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
end_of_line = lf
6+
indent_size = 4
7+
indent_style = space
8+
insert_final_newline = true
9+
max_line_length = 120
10+
tab_width = 4
11+
trim_trailing_whitespace = true

Resources/Private/build.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
const build = require('esbuild');
2+
const extensibilityMap = require("@neos-project/neos-ui-extensibility/extensibilityMap.json");
3+
const isWatch = process.argv.includes('--watch');
4+
5+
/** @type {import("esbuild").BuildOptions} */
6+
const options = {
7+
logLevel: "info",
8+
bundle: true,
9+
target: "es2020",
10+
entryPoints: { "Plugin": "src/index.js" },
11+
outdir: "../Public/JavaScript",
12+
alias: extensibilityMap
13+
}
14+
15+
if (isWatch) {
16+
build.context(options).then((ctx) => ctx.watch())
17+
} else {
18+
build.build(options)
19+
}

Resources/Private/package.json

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,11 @@
33
"license": "GNU GPLv3",
44
"private": true,
55
"scripts": {
6-
"build": "neos-react-scripts build",
7-
"watch": "neos-react-scripts watch"
6+
"build": "node build.js",
7+
"watch": "node build.js --watch"
88
},
99
"devDependencies": {
10-
"@neos-project/neos-ui-extensibility": "*"
11-
},
12-
"neos": {
13-
"buildTargetDirectory": "../Public/JavaScript"
10+
"@neos-project/neos-ui-extensibility": "~8.3",
11+
"esbuild": "^0.25.5"
1412
}
1513
}

Resources/Private/src/manifest.js

Lines changed: 42 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
import manifest from '@neos-project/neos-ui-extensibility';
22
import { selectors } from '@neos-project/neos-ui-redux-store';
33

4+
/**
5+
* from @neos-project/utils-helpers
6+
* @param {string} value
7+
* @return {string}
8+
*/
9+
const stripTags = (value) => value.replace(/<\/?[^>]+(>|$)/g, '');
10+
411
/**
512
* Evaluates a ClientEval: expression with node and editorOptions in scope
613
* @param {string} input The ClientEval expression
@@ -9,63 +16,51 @@ import { selectors } from '@neos-project/neos-ui-redux-store';
916
* @returns {any}
1017
*/
1118
const clientEval = (input, node, editorOptions) => {
12-
return eval(input);
19+
const evaluateFn = new Function('node,editorOptions', 'return ' + input);
20+
return evaluateFn(node, editorOptions);
1321
}
1422

15-
/**
16-
* Augments the NeosPlaceholder plugin
17-
* @param {Function} plugin The original plugin
18-
* @param {(contextPath: string) => object} findNode A helper to find the node data for evaluation
19-
* @param {object} editorOptions The inline editorOptions
20-
* @returns {Function} A decorated version of the plugin
21-
*/
22-
const decoratePlaceholderPlugin = (plugin, findNode, editorOptions) => {
23-
const originalGetPlaceholder = plugin.prototype.getPlaceholder;
24-
plugin.prototype.getPlaceholder = function () {
25-
const originalPlaceholder = originalGetPlaceholder.apply(this);
26-
if (originalPlaceholder.startsWith('ClientEval:')) {
27-
if (this.editor && this.editor.neos && this.editor.neos.contextPath) {
23+
manifest('Prgfx.Neos.DynamicPlaceholder', {}, (globalRegistry, {store}) => {
24+
const ckeRegistry = globalRegistry.get('ckEditor5');
25+
const ckeConfig = ckeRegistry.get('config');
26+
const existingConfig = ckeConfig.get('baseConfiguration');
27+
if (!existingConfig) return;
28+
29+
const getNodeByContextPath = path => selectors.CR.Nodes.makeGetNodeByContextPathSelector(path)(store.getState());
30+
31+
const decoratedConfig = (ckEditorConfiguration, options) => {
32+
const {editorOptions, propertyDomNode} = options;
33+
const baseConfig = existingConfig(ckEditorConfiguration, options);
34+
const contextPath = propertyDomNode?.getAttribute('data-__neos-editable-node-contextpath')
35+
?? propertyDomNode?.getAttribute('data-__neos-node-contextpath');
36+
const originalPlaceholder = baseConfig.placeholder ?? editorOptions.placeholder;
37+
38+
if (originalPlaceholder && originalPlaceholder.startsWith('ClientEval:')) {
39+
if (contextPath) {
40+
const i18nRegistry = globalRegistry.get('i18n');
2841
try {
29-
const node = findNode(this.editor.neos.contextPath);
42+
const node = getNodeByContextPath(contextPath);
3043
if (node) {
31-
return clientEval(originalPlaceholder.substring(11), node, editorOptions).toString();
44+
let evaluatedPlaceholder = clientEval(originalPlaceholder.substring(11), node, editorOptions).toString();
45+
evaluatedPlaceholder = stripTags(i18nRegistry.translate(evaluatedPlaceholder));
46+
47+
if (evaluatedPlaceholder) {
48+
return {
49+
...baseConfig,
50+
placeholder: evaluatedPlaceholder,
51+
};
52+
}
3253
}
3354
} catch (e) {
55+
console.warn('[Prgfx.Neos.DynamicPlaceholder] Could not evaluate ClientEval placeholder', originalPlaceholder, e);
3456
}
57+
} else {
58+
console.warn('[Prgfx.Neos.DynamicPlaceholder] Could not find contextPath for ClientEval placeholder', originalPlaceholder);
3559
}
3660
}
37-
return originalPlaceholder;
38-
};
3961

40-
// for some reason editor.neos is not yet available when initializing the plugin
41-
const originalInit = plugin.prototype.init;
42-
plugin.prototype.init = function() {
43-
const init = originalInit.bind(this);
44-
if (!this.editor || !this.editor.neos) {
45-
setTimeout(() => init(), 100);
46-
} else {
47-
init();
48-
}
62+
return baseConfig;
4963
};
5064

51-
return plugin;
52-
}
53-
54-
manifest('Prgfx.Neos.DynamicPlaceholder', {}, (globalRegistry, { store }) => {
55-
const ckeRegistry = globalRegistry.get('ckEditor5');
56-
const ckeConfig = ckeRegistry.get('config');
57-
const addExistingPlugin = ckeConfig.get('neosPlaceholder');
58-
if (!addExistingPlugin) return;
59-
60-
const getNodeByContextPath = path => selectors.CR.Nodes.makeGetNodeByContextPathSelector(path)(store.getState());
61-
62-
const decorateAddedPlugin = (ckEditorConfiguration, options) => {
63-
const r = addExistingPlugin(ckEditorConfiguration, options);
64-
const index = r.plugins.findIndex(p => p.pluginName === 'NeosPlaceholder');
65-
if (index >= 0) {
66-
r.plugins[index] = decoratePlaceholderPlugin(r.plugins[index], getNodeByContextPath, options.editorOptions);
67-
}
68-
return r;
69-
};
70-
ckeConfig.set('neosPlaceholder', decorateAddedPlugin);
65+
ckeConfig.set('baseConfiguration', decoratedConfig);
7166
});

0 commit comments

Comments
 (0)