@atlaskit/editor-ssr-renderer 2.0.0 → 2.0.1

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,15 @@
1
1
  # @atlaskit/editor-ssr-renderer
2
2
 
3
+ ## 2.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [`45129df3fb3bb`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/45129df3fb3bb) -
8
+ [EDITOR-4211] Fix missing <br /> in empty paragraphs in SSR renderer
9
+ - [`4741ef2efc866`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/4741ef2efc866) -
10
+ [EDITOR-4212] Fix macros in SSR renderer
11
+ - Updated dependencies
12
+
3
13
  ## 2.0.0
4
14
 
5
15
  ### Patch Changes
@@ -237,6 +237,25 @@ function EditorSSRRenderer(_ref) {
237
237
  }, [editorState]);
238
238
  var _useMemo = (0, _react.useMemo)(function () {
239
239
  var nodePositions = new WeakMap();
240
+
241
+ // ProseMirror View adds <br class="ProseMirror-trailingBreak" /> to empty nodes. Because we are using
242
+ // DOMSerializer, we should simulate the same behaviour to get the same HTML document.
243
+ //
244
+ // There are a lot of conditions that check for adding `<br />` but we could implement only the case when we
245
+ // are adding `<br />` to empty texblock, because if we add `<br />` in other cases it will change order of DOM nodes inside
246
+ // this node (`<br />`) will be the first, after will be other nodes. It's because we are adding `<br />` to root node before
247
+ // we are rendering child node.
248
+ //
249
+ // See: https://discuss.prosemirror.net/t/where-can-i-read-about-prosemirror-trailingbreak/6665
250
+ // See: https://github.com/ProseMirror/prosemirror-view/blob/76c7c47f03730b18397b94bd269ece8a9cb7f486/src/viewdesc.ts#L803
251
+ // See: https://github.com/ProseMirror/prosemirror-view/blob/76c7c47f03730b18397b94bd269ece8a9cb7f486/src/viewdesc.ts#L1365
252
+ var addTrailingBreakIfNeeded = function addTrailingBreakIfNeeded(node, contentDOM) {
253
+ if (contentDOM && node.isTextblock && !node.lastChild) {
254
+ var br = document.createElement('br');
255
+ br.classList.add('ProseMirror-trailingBreak');
256
+ contentDOM.appendChild(br);
257
+ }
258
+ };
240
259
  var toDomNodeRenderers = Object.fromEntries(Object.entries(schema.nodes).map(function (_ref3) {
241
260
  var _ref4 = (0, _slicedToArray2.default)(_ref3, 2),
242
261
  nodeName = _ref4[0],
@@ -266,41 +285,47 @@ function EditorSSRRenderer(_ref) {
266
285
  var _nodePositions$get;
267
286
  return (_nodePositions$get = nodePositions.get(node)) !== null && _nodePositions$get !== void 0 ? _nodePositions$get : 0;
268
287
  }, [], _view.DecorationSet.create(node, []));
269
-
270
- // ProseMirror View adds <br class="ProseMirror-trailingBreak" /> to empty nodes. Because we are using
271
- // DOMSerializer, we should simulate the same behaviour to get the same HTML document.
272
- //
273
- // There are a lot of conditions that check for adding `<br />` but we could implement only the case when we
274
- // are adding `<br />` to empty texblock, because if we add `<br />` in other cases it will change order of DOM nodes inside
275
- // this node (`<br />`) will be the first, after will be other nodes. It's because we are adding `<br />` to root node before
276
- // we are rendering child node.
277
- //
278
- // See: https://discuss.prosemirror.net/t/where-can-i-read-about-prosemirror-trailingbreak/6665
279
- // See: https://github.com/ProseMirror/prosemirror-view/blob/76c7c47f03730b18397b94bd269ece8a9cb7f486/src/viewdesc.ts#L803
280
- // See: https://github.com/ProseMirror/prosemirror-view/blob/76c7c47f03730b18397b94bd269ece8a9cb7f486/src/viewdesc.ts#L1365
281
- if (nodeViewInstance.contentDOM &&
282
- // if (this.node.isTextblock) updater.addTextblockHacks()
283
- node.isTextblock &&
284
- // !lastChild || // Empty textblock
285
- !node.lastChild
286
- // NOT IMPLEMENTED CASE !(lastChild instanceof TextViewDesc) ||
287
- // NOT IMPLEMENTED CASE /\n$/.test(lastChild.node.text!) ||
288
- // NOT IMPLEMENTED CASE (this.view.requiresGeckoHackNode && /\s$/.test(lastChild.node.text!))
289
- ) {
290
- var br = document.createElement('br');
291
- br.classList.add('ProseMirror-trailingBreak');
292
- nodeViewInstance.contentDOM.appendChild(br);
293
- }
288
+ addTrailingBreakIfNeeded(node, nodeViewInstance.contentDOM);
294
289
  return {
295
290
  dom: nodeViewInstance.dom,
296
- contentDOM: nodeViewInstance.contentDOM
291
+ // Leaf nodes have no content, ProseMirror will throw an error if we pass contentDOM
292
+ contentDOM: node.isLeaf ? undefined : nodeViewInstance.contentDOM
297
293
  };
298
294
  }];
299
295
  }));
300
- var markViewRenderers = Object.fromEntries(Object.entries(markViews).map(function (_ref11) {
296
+
297
+ // Create renderers for textblock nodes that don't have custom NodeViews (e.g. paragraph, heading)
298
+ var textblockRenderers = Object.fromEntries(Object.entries(schema.nodes).filter(function (_ref11) {
301
299
  var _ref12 = (0, _slicedToArray2.default)(_ref11, 2),
302
- markName = _ref12[0],
303
- markViewFactory = _ref12[1];
300
+ nodeName = _ref12[0],
301
+ nodeType = _ref12[1];
302
+ // Only handle textblock nodes
303
+ return nodeType.spec.toDOM && nodeType.isTextblock && !nodeViews[nodeName];
304
+ }).map(function (_ref13) {
305
+ var _ref14 = (0, _slicedToArray2.default)(_ref13, 2),
306
+ nodeName = _ref14[0],
307
+ nodeType = _ref14[1];
308
+ var toDOM = nodeType.spec.toDOM;
309
+ if (!toDOM) {
310
+ return [nodeName, undefined];
311
+ }
312
+ return [nodeName, function (node) {
313
+ if (!node.lastChild) {
314
+ var result = _model.DOMSerializer.renderSpec(document, toDOM(node));
315
+ addTrailingBreakIfNeeded(node, result.contentDOM);
316
+ return result;
317
+ }
318
+ return toDOM(node);
319
+ }];
320
+ }).filter(function (_ref15) {
321
+ var _ref16 = (0, _slicedToArray2.default)(_ref15, 2),
322
+ renderer = _ref16[1];
323
+ return !!renderer;
324
+ }));
325
+ var markViewRenderers = Object.fromEntries(Object.entries(markViews).map(function (_ref17) {
326
+ var _ref18 = (0, _slicedToArray2.default)(_ref17, 2),
327
+ markName = _ref18[0],
328
+ markViewFactory = _ref18[1];
304
329
  return [markName, function (mark) {
305
330
  var markViewInstance = markViewFactory(mark, editorView, false);
306
331
  return {
@@ -309,7 +334,7 @@ function EditorSSRRenderer(_ref) {
309
334
  };
310
335
  }];
311
336
  }));
312
- var serializer = new _model.DOMSerializer(_objectSpread(_objectSpread(_objectSpread({}, toDomNodeRenderers), nodeViewRenderers), {}, {
337
+ var serializer = new _model.DOMSerializer(_objectSpread(_objectSpread(_objectSpread(_objectSpread({}, toDomNodeRenderers), textblockRenderers), nodeViewRenderers), {}, {
313
338
  text: renderText
314
339
  }), _objectSpread(_objectSpread({}, toDomMarkRenderers), markViewRenderers));
315
340
  return {
@@ -174,6 +174,25 @@ export function EditorSSRRenderer({
174
174
  nodePositions
175
175
  } = useMemo(() => {
176
176
  const nodePositions = new WeakMap();
177
+
178
+ // ProseMirror View adds <br class="ProseMirror-trailingBreak" /> to empty nodes. Because we are using
179
+ // DOMSerializer, we should simulate the same behaviour to get the same HTML document.
180
+ //
181
+ // There are a lot of conditions that check for adding `<br />` but we could implement only the case when we
182
+ // are adding `<br />` to empty texblock, because if we add `<br />` in other cases it will change order of DOM nodes inside
183
+ // this node (`<br />`) will be the first, after will be other nodes. It's because we are adding `<br />` to root node before
184
+ // we are rendering child node.
185
+ //
186
+ // See: https://discuss.prosemirror.net/t/where-can-i-read-about-prosemirror-trailingbreak/6665
187
+ // See: https://github.com/ProseMirror/prosemirror-view/blob/76c7c47f03730b18397b94bd269ece8a9cb7f486/src/viewdesc.ts#L803
188
+ // See: https://github.com/ProseMirror/prosemirror-view/blob/76c7c47f03730b18397b94bd269ece8a9cb7f486/src/viewdesc.ts#L1365
189
+ const addTrailingBreakIfNeeded = (node, contentDOM) => {
190
+ if (contentDOM && node.isTextblock && !node.lastChild) {
191
+ const br = document.createElement('br');
192
+ br.classList.add('ProseMirror-trailingBreak');
193
+ contentDOM.appendChild(br);
194
+ }
195
+ };
177
196
  const toDomNodeRenderers = Object.fromEntries(Object.entries(schema.nodes).map(([nodeName, nodeType]) => {
178
197
  return [nodeName, nodeType.spec.toDOM];
179
198
  }).filter(([, toDOM]) => !!toDOM));
@@ -186,37 +205,33 @@ export function EditorSSRRenderer({
186
205
  var _nodePositions$get;
187
206
  return (_nodePositions$get = nodePositions.get(node)) !== null && _nodePositions$get !== void 0 ? _nodePositions$get : 0;
188
207
  }, [], DecorationSet.create(node, []));
189
-
190
- // ProseMirror View adds <br class="ProseMirror-trailingBreak" /> to empty nodes. Because we are using
191
- // DOMSerializer, we should simulate the same behaviour to get the same HTML document.
192
- //
193
- // There are a lot of conditions that check for adding `<br />` but we could implement only the case when we
194
- // are adding `<br />` to empty texblock, because if we add `<br />` in other cases it will change order of DOM nodes inside
195
- // this node (`<br />`) will be the first, after will be other nodes. It's because we are adding `<br />` to root node before
196
- // we are rendering child node.
197
- //
198
- // See: https://discuss.prosemirror.net/t/where-can-i-read-about-prosemirror-trailingbreak/6665
199
- // See: https://github.com/ProseMirror/prosemirror-view/blob/76c7c47f03730b18397b94bd269ece8a9cb7f486/src/viewdesc.ts#L803
200
- // See: https://github.com/ProseMirror/prosemirror-view/blob/76c7c47f03730b18397b94bd269ece8a9cb7f486/src/viewdesc.ts#L1365
201
- if (nodeViewInstance.contentDOM &&
202
- // if (this.node.isTextblock) updater.addTextblockHacks()
203
- node.isTextblock &&
204
- // !lastChild || // Empty textblock
205
- !node.lastChild
206
- // NOT IMPLEMENTED CASE !(lastChild instanceof TextViewDesc) ||
207
- // NOT IMPLEMENTED CASE /\n$/.test(lastChild.node.text!) ||
208
- // NOT IMPLEMENTED CASE (this.view.requiresGeckoHackNode && /\s$/.test(lastChild.node.text!))
209
- ) {
210
- const br = document.createElement('br');
211
- br.classList.add('ProseMirror-trailingBreak');
212
- nodeViewInstance.contentDOM.appendChild(br);
213
- }
208
+ addTrailingBreakIfNeeded(node, nodeViewInstance.contentDOM);
214
209
  return {
215
210
  dom: nodeViewInstance.dom,
216
- contentDOM: nodeViewInstance.contentDOM
211
+ // Leaf nodes have no content, ProseMirror will throw an error if we pass contentDOM
212
+ contentDOM: node.isLeaf ? undefined : nodeViewInstance.contentDOM
217
213
  };
218
214
  }];
219
215
  }));
216
+
217
+ // Create renderers for textblock nodes that don't have custom NodeViews (e.g. paragraph, heading)
218
+ const textblockRenderers = Object.fromEntries(Object.entries(schema.nodes).filter(([nodeName, nodeType]) => {
219
+ // Only handle textblock nodes
220
+ return nodeType.spec.toDOM && nodeType.isTextblock && !nodeViews[nodeName];
221
+ }).map(([nodeName, nodeType]) => {
222
+ const toDOM = nodeType.spec.toDOM;
223
+ if (!toDOM) {
224
+ return [nodeName, undefined];
225
+ }
226
+ return [nodeName, node => {
227
+ if (!node.lastChild) {
228
+ const result = DOMSerializer.renderSpec(document, toDOM(node));
229
+ addTrailingBreakIfNeeded(node, result.contentDOM);
230
+ return result;
231
+ }
232
+ return toDOM(node);
233
+ }];
234
+ }).filter(([, renderer]) => !!renderer));
220
235
  const markViewRenderers = Object.fromEntries(Object.entries(markViews).map(([markName, markViewFactory]) => {
221
236
  return [markName, mark => {
222
237
  const markViewInstance = markViewFactory(mark, editorView, false);
@@ -228,6 +243,7 @@ export function EditorSSRRenderer({
228
243
  }));
229
244
  const serializer = new DOMSerializer({
230
245
  ...toDomNodeRenderers,
246
+ ...textblockRenderers,
231
247
  ...nodeViewRenderers,
232
248
  text: renderText
233
249
  }, {
@@ -229,6 +229,25 @@ export function EditorSSRRenderer(_ref) {
229
229
  }, [editorState]);
230
230
  var _useMemo = useMemo(function () {
231
231
  var nodePositions = new WeakMap();
232
+
233
+ // ProseMirror View adds <br class="ProseMirror-trailingBreak" /> to empty nodes. Because we are using
234
+ // DOMSerializer, we should simulate the same behaviour to get the same HTML document.
235
+ //
236
+ // There are a lot of conditions that check for adding `<br />` but we could implement only the case when we
237
+ // are adding `<br />` to empty texblock, because if we add `<br />` in other cases it will change order of DOM nodes inside
238
+ // this node (`<br />`) will be the first, after will be other nodes. It's because we are adding `<br />` to root node before
239
+ // we are rendering child node.
240
+ //
241
+ // See: https://discuss.prosemirror.net/t/where-can-i-read-about-prosemirror-trailingbreak/6665
242
+ // See: https://github.com/ProseMirror/prosemirror-view/blob/76c7c47f03730b18397b94bd269ece8a9cb7f486/src/viewdesc.ts#L803
243
+ // See: https://github.com/ProseMirror/prosemirror-view/blob/76c7c47f03730b18397b94bd269ece8a9cb7f486/src/viewdesc.ts#L1365
244
+ var addTrailingBreakIfNeeded = function addTrailingBreakIfNeeded(node, contentDOM) {
245
+ if (contentDOM && node.isTextblock && !node.lastChild) {
246
+ var br = document.createElement('br');
247
+ br.classList.add('ProseMirror-trailingBreak');
248
+ contentDOM.appendChild(br);
249
+ }
250
+ };
232
251
  var toDomNodeRenderers = Object.fromEntries(Object.entries(schema.nodes).map(function (_ref3) {
233
252
  var _ref4 = _slicedToArray(_ref3, 2),
234
253
  nodeName = _ref4[0],
@@ -258,41 +277,47 @@ export function EditorSSRRenderer(_ref) {
258
277
  var _nodePositions$get;
259
278
  return (_nodePositions$get = nodePositions.get(node)) !== null && _nodePositions$get !== void 0 ? _nodePositions$get : 0;
260
279
  }, [], DecorationSet.create(node, []));
261
-
262
- // ProseMirror View adds <br class="ProseMirror-trailingBreak" /> to empty nodes. Because we are using
263
- // DOMSerializer, we should simulate the same behaviour to get the same HTML document.
264
- //
265
- // There are a lot of conditions that check for adding `<br />` but we could implement only the case when we
266
- // are adding `<br />` to empty texblock, because if we add `<br />` in other cases it will change order of DOM nodes inside
267
- // this node (`<br />`) will be the first, after will be other nodes. It's because we are adding `<br />` to root node before
268
- // we are rendering child node.
269
- //
270
- // See: https://discuss.prosemirror.net/t/where-can-i-read-about-prosemirror-trailingbreak/6665
271
- // See: https://github.com/ProseMirror/prosemirror-view/blob/76c7c47f03730b18397b94bd269ece8a9cb7f486/src/viewdesc.ts#L803
272
- // See: https://github.com/ProseMirror/prosemirror-view/blob/76c7c47f03730b18397b94bd269ece8a9cb7f486/src/viewdesc.ts#L1365
273
- if (nodeViewInstance.contentDOM &&
274
- // if (this.node.isTextblock) updater.addTextblockHacks()
275
- node.isTextblock &&
276
- // !lastChild || // Empty textblock
277
- !node.lastChild
278
- // NOT IMPLEMENTED CASE !(lastChild instanceof TextViewDesc) ||
279
- // NOT IMPLEMENTED CASE /\n$/.test(lastChild.node.text!) ||
280
- // NOT IMPLEMENTED CASE (this.view.requiresGeckoHackNode && /\s$/.test(lastChild.node.text!))
281
- ) {
282
- var br = document.createElement('br');
283
- br.classList.add('ProseMirror-trailingBreak');
284
- nodeViewInstance.contentDOM.appendChild(br);
285
- }
280
+ addTrailingBreakIfNeeded(node, nodeViewInstance.contentDOM);
286
281
  return {
287
282
  dom: nodeViewInstance.dom,
288
- contentDOM: nodeViewInstance.contentDOM
283
+ // Leaf nodes have no content, ProseMirror will throw an error if we pass contentDOM
284
+ contentDOM: node.isLeaf ? undefined : nodeViewInstance.contentDOM
289
285
  };
290
286
  }];
291
287
  }));
292
- var markViewRenderers = Object.fromEntries(Object.entries(markViews).map(function (_ref11) {
288
+
289
+ // Create renderers for textblock nodes that don't have custom NodeViews (e.g. paragraph, heading)
290
+ var textblockRenderers = Object.fromEntries(Object.entries(schema.nodes).filter(function (_ref11) {
293
291
  var _ref12 = _slicedToArray(_ref11, 2),
294
- markName = _ref12[0],
295
- markViewFactory = _ref12[1];
292
+ nodeName = _ref12[0],
293
+ nodeType = _ref12[1];
294
+ // Only handle textblock nodes
295
+ return nodeType.spec.toDOM && nodeType.isTextblock && !nodeViews[nodeName];
296
+ }).map(function (_ref13) {
297
+ var _ref14 = _slicedToArray(_ref13, 2),
298
+ nodeName = _ref14[0],
299
+ nodeType = _ref14[1];
300
+ var toDOM = nodeType.spec.toDOM;
301
+ if (!toDOM) {
302
+ return [nodeName, undefined];
303
+ }
304
+ return [nodeName, function (node) {
305
+ if (!node.lastChild) {
306
+ var result = DOMSerializer.renderSpec(document, toDOM(node));
307
+ addTrailingBreakIfNeeded(node, result.contentDOM);
308
+ return result;
309
+ }
310
+ return toDOM(node);
311
+ }];
312
+ }).filter(function (_ref15) {
313
+ var _ref16 = _slicedToArray(_ref15, 2),
314
+ renderer = _ref16[1];
315
+ return !!renderer;
316
+ }));
317
+ var markViewRenderers = Object.fromEntries(Object.entries(markViews).map(function (_ref17) {
318
+ var _ref18 = _slicedToArray(_ref17, 2),
319
+ markName = _ref18[0],
320
+ markViewFactory = _ref18[1];
296
321
  return [markName, function (mark) {
297
322
  var markViewInstance = markViewFactory(mark, editorView, false);
298
323
  return {
@@ -301,7 +326,7 @@ export function EditorSSRRenderer(_ref) {
301
326
  };
302
327
  }];
303
328
  }));
304
- var serializer = new DOMSerializer(_objectSpread(_objectSpread(_objectSpread({}, toDomNodeRenderers), nodeViewRenderers), {}, {
329
+ var serializer = new DOMSerializer(_objectSpread(_objectSpread(_objectSpread(_objectSpread({}, toDomNodeRenderers), textblockRenderers), nodeViewRenderers), {}, {
305
330
  text: renderText
306
331
  }), _objectSpread(_objectSpread({}, toDomMarkRenderers), markViewRenderers));
307
332
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-ssr-renderer",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "SSR Renderer based on Editor",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "atlassian": {
@@ -33,7 +33,7 @@
33
33
  "react-intl-next": "npm:react-intl@^5.18.1"
34
34
  },
35
35
  "peerDependencies": {
36
- "@atlaskit/editor-common": "^111.0.0",
36
+ "@atlaskit/editor-common": "^111.3.0",
37
37
  "react": "^18.2.0"
38
38
  }
39
39
  }