@atlaskit/editor-ssr-renderer 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @atlaskit/editor-ssr-renderer
2
2
 
3
+ ## 1.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`c7acfc11f076a`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/c7acfc11f076a) -
8
+ [https://hello.jira.atlassian.cloud/browse/EDITOR-3745](EDITOR-3745) - adopt EditorSSRRenderer to
9
+ ReactEditorView
10
+
11
+ ## 1.2.0
12
+
13
+ ### Minor Changes
14
+
15
+ - [`92ad90cd1d2e8`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/92ad90cd1d2e8) -
16
+ [https://hello.jira.atlassian.cloud/browse/EDITOR-3332] - created EditorSSRRenderer component
17
+
18
+ ### Patch Changes
19
+
20
+ - Updated dependencies
21
+
3
22
  ## 1.1.0
4
23
 
5
24
  ### Minor Changes
@@ -0,0 +1,228 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _typeof = require("@babel/runtime/helpers/typeof");
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.EditorSSRRenderer = EditorSSRRenderer;
9
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
10
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
11
+ var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
12
+ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
13
+ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
14
+ var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
15
+ var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
16
+ var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
17
+ var _react = _interopRequireWildcard(require("react"));
18
+ var _view = require("@atlaskit/editor-prosemirror/view");
19
+ var _state = require("@atlaskit/editor-prosemirror/state");
20
+ var _model = require("@atlaskit/editor-prosemirror/model");
21
+ var _schemaDefault = require("@atlaskit/adf-schema/schema-default");
22
+ var _eventDispatcher = require("@atlaskit/editor-common/event-dispatcher");
23
+ var _providerFactory = require("@atlaskit/editor-common/provider-factory");
24
+ var _excluded = ["preset", "buildDoc", "portalProviderAPI", "intl", "pluginInjectionAPI"];
25
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
26
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
27
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
28
+ function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
29
+ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
30
+ // The copy of type from prosemirror-view.
31
+ // Probably, we need to fix this package exports and add `NodeViewConstructor` and `MarkViewConstructor` types here.
32
+ var SSREditorView = /*#__PURE__*/function (_EditorView) {
33
+ function SSREditorView() {
34
+ (0, _classCallCheck2.default)(this, SSREditorView);
35
+ return _callSuper(this, SSREditorView, arguments);
36
+ }
37
+ (0, _inherits2.default)(SSREditorView, _EditorView);
38
+ return (0, _createClass2.default)(SSREditorView, [{
39
+ key: "update",
40
+ value: function update() {
41
+ // Skip any updates in SSR
42
+ }
43
+ }, {
44
+ key: "setProps",
45
+ value: function setProps() {
46
+ // Skip any updates in SSR
47
+ }
48
+ }, {
49
+ key: "dispatchEvent",
50
+ value: function dispatchEvent() {
51
+ // Don't notify about events in SSR
52
+ }
53
+ }, {
54
+ key: "dispatch",
55
+ value: function dispatch() {
56
+ // Don't notify about events in SSR
57
+ }
58
+ }]);
59
+ }(_view.EditorView);
60
+ var SSREventDispatcher = /*#__PURE__*/function (_EventDispatcher) {
61
+ function SSREventDispatcher() {
62
+ (0, _classCallCheck2.default)(this, SSREventDispatcher);
63
+ return _callSuper(this, SSREventDispatcher, arguments);
64
+ }
65
+ (0, _inherits2.default)(SSREventDispatcher, _EventDispatcher);
66
+ return (0, _createClass2.default)(SSREventDispatcher, [{
67
+ key: "emit",
68
+ value: function emit() {
69
+ // Don't notify about events in SSR
70
+ }
71
+ }]);
72
+ }(_eventDispatcher.EventDispatcher);
73
+ function EditorSSRRenderer(_ref) {
74
+ var preset = _ref.preset,
75
+ buildDoc = _ref.buildDoc,
76
+ portalProviderAPI = _ref.portalProviderAPI,
77
+ intl = _ref.intl,
78
+ pluginInjectionAPI = _ref.pluginInjectionAPI,
79
+ divProps = (0, _objectWithoutProperties2.default)(_ref, _excluded);
80
+ // PMPluginFactoryParams use `getIntl` function to get current intl instance,
81
+ // so we don't need to add `intl` as a dependency to `useMemo`.
82
+ // We will store intl in ref and access to it dynamically in `getIntl` function call.
83
+ var intlRef = (0, _react.useRef)(intl);
84
+ intlRef.current = intl;
85
+ var plugins = (0, _react.useMemo)(function () {
86
+ return preset.build({
87
+ pluginInjectionAPI: pluginInjectionAPI
88
+ });
89
+ }, [pluginInjectionAPI, preset]);
90
+ var pmPlugins = (0, _react.useMemo)(function () {
91
+ var eventDispatcher = new SSREventDispatcher();
92
+ var providerFactory = new _providerFactory.ProviderFactory();
93
+ var pmPluginFactoryParams = {
94
+ dispatch: (0, _eventDispatcher.createDispatch)(eventDispatcher),
95
+ dispatchAnalyticsEvent: function dispatchAnalyticsEvent() {},
96
+ eventDispatcher: eventDispatcher,
97
+ featureFlags: {},
98
+ getIntl: function getIntl() {
99
+ return intlRef.current;
100
+ },
101
+ nodeViewPortalProviderAPI: portalProviderAPI,
102
+ portalProviderAPI: portalProviderAPI,
103
+ providerFactory: providerFactory,
104
+ schema: _schemaDefault.defaultSchema
105
+ };
106
+ return plugins.reduce(function (acc, editorPlugin) {
107
+ var _editorPlugin$pmPlugi;
108
+ (_editorPlugin$pmPlugi = editorPlugin.pmPlugins) === null || _editorPlugin$pmPlugi === void 0 || _editorPlugin$pmPlugi.call(editorPlugin).forEach(function (_ref2) {
109
+ var plugin = _ref2.plugin;
110
+ try {
111
+ var pmPlugin = plugin(pmPluginFactoryParams);
112
+ if (pmPlugin) {
113
+ acc.push(pmPlugin);
114
+ }
115
+ } catch (_unused) {}
116
+ });
117
+ return acc;
118
+ }, []);
119
+ }, [plugins, portalProviderAPI]);
120
+ var nodeViews = (0, _react.useMemo)(function () {
121
+ return pmPlugins.reduce(function (acc, plugin) {
122
+ return Object.assign(acc, plugin.props.nodeViews);
123
+ }, {});
124
+ }, [pmPlugins]);
125
+ var markViews = (0, _react.useMemo)(function () {
126
+ return pmPlugins.reduce(function (acc, plugin) {
127
+ return Object.assign(acc, plugin.props.markViews);
128
+ }, {});
129
+ }, [pmPlugins]);
130
+ var editorView = (0, _react.useMemo)(function () {
131
+ return new SSREditorView(null, {
132
+ state: _state.EditorState.create({
133
+ schema: _schemaDefault.defaultSchema,
134
+ plugins: pmPlugins
135
+ })
136
+ });
137
+ }, [pmPlugins]);
138
+ var serializer = (0, _react.useMemo)(function () {
139
+ var toDomNodeRenderers = Object.fromEntries(Object.entries(_schemaDefault.defaultSchema.nodes).map(function (_ref3) {
140
+ var _ref4 = (0, _slicedToArray2.default)(_ref3, 2),
141
+ nodeName = _ref4[0],
142
+ nodeType = _ref4[1];
143
+ return [nodeName, nodeType.spec.toDOM];
144
+ }).filter(function (_ref5) {
145
+ var _ref6 = (0, _slicedToArray2.default)(_ref5, 2),
146
+ toDOM = _ref6[1];
147
+ return !!toDOM;
148
+ }));
149
+ var toDomMarkRenderers = Object.fromEntries(Object.entries(_schemaDefault.defaultSchema.marks).map(function (_ref7) {
150
+ var _ref8 = (0, _slicedToArray2.default)(_ref7, 2),
151
+ markName = _ref8[0],
152
+ markType = _ref8[1];
153
+ return [markName, markType.spec.toDOM];
154
+ }).filter(function (_ref9) {
155
+ var _ref0 = (0, _slicedToArray2.default)(_ref9, 2),
156
+ toDOM = _ref0[1];
157
+ return !!toDOM;
158
+ }));
159
+ var nodeViewRenderers = Object.fromEntries(Object.entries(nodeViews).map(function (_ref1) {
160
+ var _ref10 = (0, _slicedToArray2.default)(_ref1, 2),
161
+ nodeName = _ref10[0],
162
+ nodeViewFactory = _ref10[1];
163
+ return [nodeName, function (node) {
164
+ var nodeViewInstance = nodeViewFactory(node, editorView, function () {
165
+ return 0;
166
+ }, [], _view.DecorationSet.create(node, []));
167
+ return {
168
+ dom: nodeViewInstance.dom,
169
+ contentDOM: nodeViewInstance.contentDOM
170
+ };
171
+ }];
172
+ }));
173
+ var markViewRenderers = Object.fromEntries(Object.entries(markViews).map(function (_ref11) {
174
+ var _ref12 = (0, _slicedToArray2.default)(_ref11, 2),
175
+ markName = _ref12[0],
176
+ markViewFactory = _ref12[1];
177
+ return [markName, function (mark) {
178
+ var markViewInstance = markViewFactory(mark, editorView, false);
179
+ return {
180
+ dom: markViewInstance.dom,
181
+ contentDOM: markViewInstance.contentDOM
182
+ };
183
+ }];
184
+ }));
185
+ return new _model.DOMSerializer(_objectSpread(_objectSpread(_objectSpread({}, toDomNodeRenderers), nodeViewRenderers), {}, {
186
+ text: renderText
187
+ }), _objectSpread(_objectSpread({}, toDomMarkRenderers), markViewRenderers));
188
+ }, [editorView, markViews, nodeViews]);
189
+ var editorHTML = (0, _react.useMemo)(function () {
190
+ try {
191
+ var pmDoc = buildDoc(editorView.state.schema);
192
+ if (!pmDoc) {
193
+ return undefined;
194
+ }
195
+ return serializer.serializeFragment(pmDoc.content);
196
+ } catch (_unused2) {
197
+ return undefined;
198
+ }
199
+ }, [editorView.state.schema, buildDoc, serializer]);
200
+ var containerRef = (0, _react.useRef)(null);
201
+ (0, _react.useLayoutEffect)(function () {
202
+ if (containerRef.current && editorHTML) {
203
+ containerRef.current.innerHTML = '';
204
+ containerRef.current.appendChild(editorHTML);
205
+ }
206
+ }, [editorHTML]);
207
+ return /*#__PURE__*/_react.default.createElement("div", {
208
+ ref: containerRef,
209
+ id: divProps.id
210
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
211
+ ,
212
+ className: divProps.className,
213
+ "aria-label": divProps['aria-label'],
214
+ "aria-describedby": divProps['aria-describedby'],
215
+ "data-editor-id": divProps['data-editor-id'],
216
+ "data-vc-ignore-if-no-layout-shift": true,
217
+ "aria-multiline": true,
218
+ role: "textbox"
219
+ // @ts-expect-error - contenteditable is not exist in div attributes
220
+ ,
221
+ contenteditable: "true",
222
+ "data-gramm": "false",
223
+ translate: "no"
224
+ });
225
+ }
226
+ function renderText(node) {
227
+ return node.text || '';
228
+ }
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "EditorSSRRenderer", {
7
+ enumerable: true,
8
+ get: function get() {
9
+ return _EditorSSRRenderer.EditorSSRRenderer;
10
+ }
11
+ });
12
+ var _EditorSSRRenderer = require("./editor-ssr-renderer/EditorSSRRenderer");
@@ -0,0 +1,167 @@
1
+ import React, { useMemo, useRef, useLayoutEffect } from 'react';
2
+ import { EditorView, DecorationSet } from '@atlaskit/editor-prosemirror/view';
3
+ import { EditorState } from '@atlaskit/editor-prosemirror/state';
4
+ import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
5
+ import { defaultSchema } from '@atlaskit/adf-schema/schema-default';
6
+ import { EventDispatcher, createDispatch } from '@atlaskit/editor-common/event-dispatcher';
7
+ import { ProviderFactory } from '@atlaskit/editor-common/provider-factory';
8
+
9
+ // The copy of type from prosemirror-view.
10
+ // Probably, we need to fix this package exports and add `NodeViewConstructor` and `MarkViewConstructor` types here.
11
+
12
+ class SSREditorView extends EditorView {
13
+ update() {
14
+ // Skip any updates in SSR
15
+ }
16
+ setProps() {
17
+ // Skip any updates in SSR
18
+ }
19
+ dispatchEvent() {
20
+ // Don't notify about events in SSR
21
+ }
22
+ dispatch() {
23
+ // Don't notify about events in SSR
24
+ }
25
+ }
26
+ class SSREventDispatcher extends EventDispatcher {
27
+ emit() {
28
+ // Don't notify about events in SSR
29
+ }
30
+ }
31
+ export function EditorSSRRenderer({
32
+ preset,
33
+ buildDoc,
34
+ portalProviderAPI,
35
+ intl,
36
+ pluginInjectionAPI,
37
+ ...divProps
38
+ }) {
39
+ // PMPluginFactoryParams use `getIntl` function to get current intl instance,
40
+ // so we don't need to add `intl` as a dependency to `useMemo`.
41
+ // We will store intl in ref and access to it dynamically in `getIntl` function call.
42
+ const intlRef = useRef(intl);
43
+ intlRef.current = intl;
44
+ const plugins = useMemo(() => preset.build({
45
+ pluginInjectionAPI
46
+ }), [pluginInjectionAPI, preset]);
47
+ const pmPlugins = useMemo(() => {
48
+ const eventDispatcher = new SSREventDispatcher();
49
+ const providerFactory = new ProviderFactory();
50
+ const pmPluginFactoryParams = {
51
+ dispatch: createDispatch(eventDispatcher),
52
+ dispatchAnalyticsEvent: () => {},
53
+ eventDispatcher,
54
+ featureFlags: {},
55
+ getIntl: () => intlRef.current,
56
+ nodeViewPortalProviderAPI: portalProviderAPI,
57
+ portalProviderAPI: portalProviderAPI,
58
+ providerFactory,
59
+ schema: defaultSchema
60
+ };
61
+ return plugins.reduce((acc, editorPlugin) => {
62
+ var _editorPlugin$pmPlugi;
63
+ (_editorPlugin$pmPlugi = editorPlugin.pmPlugins) === null || _editorPlugin$pmPlugi === void 0 ? void 0 : _editorPlugin$pmPlugi.call(editorPlugin).forEach(({
64
+ plugin
65
+ }) => {
66
+ try {
67
+ const pmPlugin = plugin(pmPluginFactoryParams);
68
+ if (pmPlugin) {
69
+ acc.push(pmPlugin);
70
+ }
71
+ } catch {}
72
+ });
73
+ return acc;
74
+ }, []);
75
+ }, [plugins, portalProviderAPI]);
76
+ const nodeViews = useMemo(() => {
77
+ return pmPlugins.reduce((acc, plugin) => {
78
+ return Object.assign(acc, plugin.props.nodeViews);
79
+ }, {});
80
+ }, [pmPlugins]);
81
+ const markViews = useMemo(() => {
82
+ return pmPlugins.reduce((acc, plugin) => {
83
+ return Object.assign(acc, plugin.props.markViews);
84
+ }, {});
85
+ }, [pmPlugins]);
86
+ const editorView = useMemo(() => {
87
+ return new SSREditorView(null, {
88
+ state: EditorState.create({
89
+ schema: defaultSchema,
90
+ plugins: pmPlugins
91
+ })
92
+ });
93
+ }, [pmPlugins]);
94
+ const serializer = useMemo(() => {
95
+ const toDomNodeRenderers = Object.fromEntries(Object.entries(defaultSchema.nodes).map(([nodeName, nodeType]) => {
96
+ return [nodeName, nodeType.spec.toDOM];
97
+ }).filter(([, toDOM]) => !!toDOM));
98
+ const toDomMarkRenderers = Object.fromEntries(Object.entries(defaultSchema.marks).map(([markName, markType]) => {
99
+ return [markName, markType.spec.toDOM];
100
+ }).filter(([, toDOM]) => !!toDOM));
101
+ const nodeViewRenderers = Object.fromEntries(Object.entries(nodeViews).map(([nodeName, nodeViewFactory]) => {
102
+ return [nodeName, node => {
103
+ const nodeViewInstance = nodeViewFactory(node, editorView, () => 0, [], DecorationSet.create(node, []));
104
+ return {
105
+ dom: nodeViewInstance.dom,
106
+ contentDOM: nodeViewInstance.contentDOM
107
+ };
108
+ }];
109
+ }));
110
+ const markViewRenderers = Object.fromEntries(Object.entries(markViews).map(([markName, markViewFactory]) => {
111
+ return [markName, mark => {
112
+ const markViewInstance = markViewFactory(mark, editorView, false);
113
+ return {
114
+ dom: markViewInstance.dom,
115
+ contentDOM: markViewInstance.contentDOM
116
+ };
117
+ }];
118
+ }));
119
+ return new DOMSerializer({
120
+ ...toDomNodeRenderers,
121
+ ...nodeViewRenderers,
122
+ text: renderText
123
+ }, {
124
+ ...toDomMarkRenderers,
125
+ ...markViewRenderers
126
+ });
127
+ }, [editorView, markViews, nodeViews]);
128
+ const editorHTML = useMemo(() => {
129
+ try {
130
+ const pmDoc = buildDoc(editorView.state.schema);
131
+ if (!pmDoc) {
132
+ return undefined;
133
+ }
134
+ return serializer.serializeFragment(pmDoc.content);
135
+ } catch {
136
+ return undefined;
137
+ }
138
+ }, [editorView.state.schema, buildDoc, serializer]);
139
+ const containerRef = useRef(null);
140
+ useLayoutEffect(() => {
141
+ if (containerRef.current && editorHTML) {
142
+ containerRef.current.innerHTML = '';
143
+ containerRef.current.appendChild(editorHTML);
144
+ }
145
+ }, [editorHTML]);
146
+ return /*#__PURE__*/React.createElement("div", {
147
+ ref: containerRef,
148
+ id: divProps.id
149
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
150
+ ,
151
+ className: divProps.className,
152
+ "aria-label": divProps['aria-label'],
153
+ "aria-describedby": divProps['aria-describedby'],
154
+ "data-editor-id": divProps['data-editor-id'],
155
+ "data-vc-ignore-if-no-layout-shift": true,
156
+ "aria-multiline": true,
157
+ role: "textbox"
158
+ // @ts-expect-error - contenteditable is not exist in div attributes
159
+ ,
160
+ contenteditable: "true",
161
+ "data-gramm": "false",
162
+ translate: "no"
163
+ });
164
+ }
165
+ function renderText(node) {
166
+ return node.text || '';
167
+ }
@@ -0,0 +1,4 @@
1
+ // Disable no-re-export rule for entry point files
2
+ /* eslint-disable @atlaskit/editor/no-re-export */
3
+
4
+ export { EditorSSRRenderer } from './editor-ssr-renderer/EditorSSRRenderer';
@@ -0,0 +1,220 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
+ import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
4
+ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
5
+ import _createClass from "@babel/runtime/helpers/createClass";
6
+ import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
7
+ import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
8
+ import _inherits from "@babel/runtime/helpers/inherits";
9
+ var _excluded = ["preset", "buildDoc", "portalProviderAPI", "intl", "pluginInjectionAPI"];
10
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
11
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
12
+ function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
13
+ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
14
+ import React, { useMemo, useRef, useLayoutEffect } from 'react';
15
+ import { EditorView, DecorationSet } from '@atlaskit/editor-prosemirror/view';
16
+ import { EditorState } from '@atlaskit/editor-prosemirror/state';
17
+ import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
18
+ import { defaultSchema } from '@atlaskit/adf-schema/schema-default';
19
+ import { EventDispatcher, createDispatch } from '@atlaskit/editor-common/event-dispatcher';
20
+ import { ProviderFactory } from '@atlaskit/editor-common/provider-factory';
21
+
22
+ // The copy of type from prosemirror-view.
23
+ // Probably, we need to fix this package exports and add `NodeViewConstructor` and `MarkViewConstructor` types here.
24
+ var SSREditorView = /*#__PURE__*/function (_EditorView) {
25
+ function SSREditorView() {
26
+ _classCallCheck(this, SSREditorView);
27
+ return _callSuper(this, SSREditorView, arguments);
28
+ }
29
+ _inherits(SSREditorView, _EditorView);
30
+ return _createClass(SSREditorView, [{
31
+ key: "update",
32
+ value: function update() {
33
+ // Skip any updates in SSR
34
+ }
35
+ }, {
36
+ key: "setProps",
37
+ value: function setProps() {
38
+ // Skip any updates in SSR
39
+ }
40
+ }, {
41
+ key: "dispatchEvent",
42
+ value: function dispatchEvent() {
43
+ // Don't notify about events in SSR
44
+ }
45
+ }, {
46
+ key: "dispatch",
47
+ value: function dispatch() {
48
+ // Don't notify about events in SSR
49
+ }
50
+ }]);
51
+ }(EditorView);
52
+ var SSREventDispatcher = /*#__PURE__*/function (_EventDispatcher) {
53
+ function SSREventDispatcher() {
54
+ _classCallCheck(this, SSREventDispatcher);
55
+ return _callSuper(this, SSREventDispatcher, arguments);
56
+ }
57
+ _inherits(SSREventDispatcher, _EventDispatcher);
58
+ return _createClass(SSREventDispatcher, [{
59
+ key: "emit",
60
+ value: function emit() {
61
+ // Don't notify about events in SSR
62
+ }
63
+ }]);
64
+ }(EventDispatcher);
65
+ export function EditorSSRRenderer(_ref) {
66
+ var preset = _ref.preset,
67
+ buildDoc = _ref.buildDoc,
68
+ portalProviderAPI = _ref.portalProviderAPI,
69
+ intl = _ref.intl,
70
+ pluginInjectionAPI = _ref.pluginInjectionAPI,
71
+ divProps = _objectWithoutProperties(_ref, _excluded);
72
+ // PMPluginFactoryParams use `getIntl` function to get current intl instance,
73
+ // so we don't need to add `intl` as a dependency to `useMemo`.
74
+ // We will store intl in ref and access to it dynamically in `getIntl` function call.
75
+ var intlRef = useRef(intl);
76
+ intlRef.current = intl;
77
+ var plugins = useMemo(function () {
78
+ return preset.build({
79
+ pluginInjectionAPI: pluginInjectionAPI
80
+ });
81
+ }, [pluginInjectionAPI, preset]);
82
+ var pmPlugins = useMemo(function () {
83
+ var eventDispatcher = new SSREventDispatcher();
84
+ var providerFactory = new ProviderFactory();
85
+ var pmPluginFactoryParams = {
86
+ dispatch: createDispatch(eventDispatcher),
87
+ dispatchAnalyticsEvent: function dispatchAnalyticsEvent() {},
88
+ eventDispatcher: eventDispatcher,
89
+ featureFlags: {},
90
+ getIntl: function getIntl() {
91
+ return intlRef.current;
92
+ },
93
+ nodeViewPortalProviderAPI: portalProviderAPI,
94
+ portalProviderAPI: portalProviderAPI,
95
+ providerFactory: providerFactory,
96
+ schema: defaultSchema
97
+ };
98
+ return plugins.reduce(function (acc, editorPlugin) {
99
+ var _editorPlugin$pmPlugi;
100
+ (_editorPlugin$pmPlugi = editorPlugin.pmPlugins) === null || _editorPlugin$pmPlugi === void 0 || _editorPlugin$pmPlugi.call(editorPlugin).forEach(function (_ref2) {
101
+ var plugin = _ref2.plugin;
102
+ try {
103
+ var pmPlugin = plugin(pmPluginFactoryParams);
104
+ if (pmPlugin) {
105
+ acc.push(pmPlugin);
106
+ }
107
+ } catch (_unused) {}
108
+ });
109
+ return acc;
110
+ }, []);
111
+ }, [plugins, portalProviderAPI]);
112
+ var nodeViews = useMemo(function () {
113
+ return pmPlugins.reduce(function (acc, plugin) {
114
+ return Object.assign(acc, plugin.props.nodeViews);
115
+ }, {});
116
+ }, [pmPlugins]);
117
+ var markViews = useMemo(function () {
118
+ return pmPlugins.reduce(function (acc, plugin) {
119
+ return Object.assign(acc, plugin.props.markViews);
120
+ }, {});
121
+ }, [pmPlugins]);
122
+ var editorView = useMemo(function () {
123
+ return new SSREditorView(null, {
124
+ state: EditorState.create({
125
+ schema: defaultSchema,
126
+ plugins: pmPlugins
127
+ })
128
+ });
129
+ }, [pmPlugins]);
130
+ var serializer = useMemo(function () {
131
+ var toDomNodeRenderers = Object.fromEntries(Object.entries(defaultSchema.nodes).map(function (_ref3) {
132
+ var _ref4 = _slicedToArray(_ref3, 2),
133
+ nodeName = _ref4[0],
134
+ nodeType = _ref4[1];
135
+ return [nodeName, nodeType.spec.toDOM];
136
+ }).filter(function (_ref5) {
137
+ var _ref6 = _slicedToArray(_ref5, 2),
138
+ toDOM = _ref6[1];
139
+ return !!toDOM;
140
+ }));
141
+ var toDomMarkRenderers = Object.fromEntries(Object.entries(defaultSchema.marks).map(function (_ref7) {
142
+ var _ref8 = _slicedToArray(_ref7, 2),
143
+ markName = _ref8[0],
144
+ markType = _ref8[1];
145
+ return [markName, markType.spec.toDOM];
146
+ }).filter(function (_ref9) {
147
+ var _ref0 = _slicedToArray(_ref9, 2),
148
+ toDOM = _ref0[1];
149
+ return !!toDOM;
150
+ }));
151
+ var nodeViewRenderers = Object.fromEntries(Object.entries(nodeViews).map(function (_ref1) {
152
+ var _ref10 = _slicedToArray(_ref1, 2),
153
+ nodeName = _ref10[0],
154
+ nodeViewFactory = _ref10[1];
155
+ return [nodeName, function (node) {
156
+ var nodeViewInstance = nodeViewFactory(node, editorView, function () {
157
+ return 0;
158
+ }, [], DecorationSet.create(node, []));
159
+ return {
160
+ dom: nodeViewInstance.dom,
161
+ contentDOM: nodeViewInstance.contentDOM
162
+ };
163
+ }];
164
+ }));
165
+ var markViewRenderers = Object.fromEntries(Object.entries(markViews).map(function (_ref11) {
166
+ var _ref12 = _slicedToArray(_ref11, 2),
167
+ markName = _ref12[0],
168
+ markViewFactory = _ref12[1];
169
+ return [markName, function (mark) {
170
+ var markViewInstance = markViewFactory(mark, editorView, false);
171
+ return {
172
+ dom: markViewInstance.dom,
173
+ contentDOM: markViewInstance.contentDOM
174
+ };
175
+ }];
176
+ }));
177
+ return new DOMSerializer(_objectSpread(_objectSpread(_objectSpread({}, toDomNodeRenderers), nodeViewRenderers), {}, {
178
+ text: renderText
179
+ }), _objectSpread(_objectSpread({}, toDomMarkRenderers), markViewRenderers));
180
+ }, [editorView, markViews, nodeViews]);
181
+ var editorHTML = useMemo(function () {
182
+ try {
183
+ var pmDoc = buildDoc(editorView.state.schema);
184
+ if (!pmDoc) {
185
+ return undefined;
186
+ }
187
+ return serializer.serializeFragment(pmDoc.content);
188
+ } catch (_unused2) {
189
+ return undefined;
190
+ }
191
+ }, [editorView.state.schema, buildDoc, serializer]);
192
+ var containerRef = useRef(null);
193
+ useLayoutEffect(function () {
194
+ if (containerRef.current && editorHTML) {
195
+ containerRef.current.innerHTML = '';
196
+ containerRef.current.appendChild(editorHTML);
197
+ }
198
+ }, [editorHTML]);
199
+ return /*#__PURE__*/React.createElement("div", {
200
+ ref: containerRef,
201
+ id: divProps.id
202
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
203
+ ,
204
+ className: divProps.className,
205
+ "aria-label": divProps['aria-label'],
206
+ "aria-describedby": divProps['aria-describedby'],
207
+ "data-editor-id": divProps['data-editor-id'],
208
+ "data-vc-ignore-if-no-layout-shift": true,
209
+ "aria-multiline": true,
210
+ role: "textbox"
211
+ // @ts-expect-error - contenteditable is not exist in div attributes
212
+ ,
213
+ contenteditable: "true",
214
+ "data-gramm": "false",
215
+ translate: "no"
216
+ });
217
+ }
218
+ function renderText(node) {
219
+ return node.text || '';
220
+ }
@@ -0,0 +1,4 @@
1
+ // Disable no-re-export rule for entry point files
2
+ /* eslint-disable @atlaskit/editor/no-re-export */
3
+
4
+ export { EditorSSRRenderer } from './editor-ssr-renderer/EditorSSRRenderer';
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import type { IntlShape } from 'react-intl-next';
3
+ import type { EditorPluginInjectionAPI, EditorPresetBuilder } from '@atlaskit/editor-common/preset';
4
+ import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
5
+ import { type Schema } from '@atlaskit/editor-prosemirror/model';
6
+ import type { PortalProviderAPI } from '@atlaskit/editor-common/portal';
7
+ interface Props {
8
+ 'aria-describedby'?: string;
9
+ 'aria-label': string;
10
+ buildDoc: (schema: Schema) => PMNode | undefined;
11
+ className: string;
12
+ 'data-editor-id': string;
13
+ id: string;
14
+ intl: IntlShape;
15
+ pluginInjectionAPI?: EditorPluginInjectionAPI;
16
+ portalProviderAPI: PortalProviderAPI;
17
+ preset: EditorPresetBuilder<any, any>;
18
+ }
19
+ export declare function EditorSSRRenderer({ preset, buildDoc, portalProviderAPI, intl, pluginInjectionAPI, ...divProps }: Props): React.JSX.Element;
20
+ export {};
@@ -0,0 +1 @@
1
+ export { EditorSSRRenderer } from './editor-ssr-renderer/EditorSSRRenderer';
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import type { IntlShape } from 'react-intl-next';
3
+ import type { EditorPluginInjectionAPI, EditorPresetBuilder } from '@atlaskit/editor-common/preset';
4
+ import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
5
+ import { type Schema } from '@atlaskit/editor-prosemirror/model';
6
+ import type { PortalProviderAPI } from '@atlaskit/editor-common/portal';
7
+ interface Props {
8
+ 'aria-describedby'?: string;
9
+ 'aria-label': string;
10
+ buildDoc: (schema: Schema) => PMNode | undefined;
11
+ className: string;
12
+ 'data-editor-id': string;
13
+ id: string;
14
+ intl: IntlShape;
15
+ pluginInjectionAPI?: EditorPluginInjectionAPI;
16
+ portalProviderAPI: PortalProviderAPI;
17
+ preset: EditorPresetBuilder<any, any>;
18
+ }
19
+ export declare function EditorSSRRenderer({ preset, buildDoc, portalProviderAPI, intl, pluginInjectionAPI, ...divProps }: Props): React.JSX.Element;
20
+ export {};
@@ -0,0 +1 @@
1
+ export { EditorSSRRenderer } from './editor-ssr-renderer/EditorSSRRenderer';
@@ -1,13 +1,55 @@
1
- import React from 'react';
1
+ import React, { useMemo } from 'react';
2
2
 
3
- import { IntlProvider } from 'react-intl-next';
3
+ import type { PortalProviderAPI } from '@atlaskit/editor-common/portal';
4
+ import { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
5
+ import { CardClient, SmartCardProvider } from '@atlaskit/link-provider';
6
+ import { getExamplesProviders } from '@af/editor-examples-helpers/utils';
7
+ import { useConfluenceFullPagePreset } from '@af/editor-examples-helpers/example-presets';
8
+ import { IntlProvider, useIntl } from 'react-intl-next';
4
9
  import type { DocNode } from '@atlaskit/adf-schema';
10
+ import { EditorSSRRenderer } from '../src';
11
+
12
+ class SSRPortalProviderAPI implements PortalProviderAPI {
13
+ destroy() {}
14
+ remove() {}
15
+ render() {}
16
+ }
17
+
18
+ function SSREditor({ adf }: { adf: DocNode }) {
19
+ const intl = useIntl();
20
+ const providers = useMemo(() => getExamplesProviders({ sanitizePrivateContent: true }), []);
21
+
22
+ const { preset } = useConfluenceFullPagePreset({
23
+ editorAppearance: 'full-page',
24
+ overridedFullPagePresetProps: {
25
+ providers,
26
+ },
27
+ });
28
+
29
+ return (
30
+ <EditorSSRRenderer
31
+ intl={intl}
32
+ preset={preset}
33
+ buildDoc={(schema) => PMNode.fromJSON(schema, adf)}
34
+ portalProviderAPI={new SSRPortalProviderAPI()}
35
+ id="ak-editor-textarea"
36
+ data-editor-id="6f03e411-00a8-448b-bbc0-66f350895a5e"
37
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
38
+ className="ProseMirror ua-chrome"
39
+ aria-label="Main content area, start typing to enter text."
40
+ />
41
+ );
42
+ }
5
43
 
6
44
  export function createExample(adf: DocNode) {
7
45
  return () => {
46
+ const smartCardClient = useMemo(() => new CardClient('staging'), []);
47
+
8
48
  return (
9
49
  <IntlProvider locale={'en'}>
10
- <pre>{JSON.stringify(adf, null, 2)}</pre>
50
+ <SmartCardProvider client={smartCardClient}>
51
+ <SSREditor adf={adf} />
52
+ </SmartCardProvider>
11
53
  </IntlProvider>
12
54
  );
13
55
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-ssr-renderer",
3
- "version": "1.1.0",
3
+ "version": "1.3.0",
4
4
  "description": "SSR Renderer based on Editor",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "atlassian": {
@@ -27,14 +27,13 @@
27
27
  "sideEffects": false,
28
28
  "atlaskit:src": "src/index.ts",
29
29
  "dependencies": {
30
+ "@atlaskit/adf-schema": "^51.5.1",
30
31
  "@atlaskit/editor-prosemirror": "7.0.0",
31
- "@babel/runtime": "^7.0.0"
32
- },
33
- "devDependencies": {
34
- "@atlaskit/adf-schema": "^51.4.0",
35
- "@emotion/react": "^11.7.1"
32
+ "@babel/runtime": "^7.0.0",
33
+ "react-intl-next": "npm:react-intl@^5.18.1"
36
34
  },
37
35
  "peerDependencies": {
36
+ "@atlaskit/editor-common": "^110.40.0",
38
37
  "react": "^18.2.0"
39
38
  }
40
39
  }