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