@squiz/formatted-text-editor 1.66.3 → 1.67.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,19 @@
1
1
  # Change Log
2
2
 
3
+ ## 1.67.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 6867717: Changed output of FTE to use semantic HTML where applicable
8
+
9
+ ## 1.66.4
10
+
11
+ ### Patch Changes
12
+
13
+ - 8421756: Selected image assets in the resource browser will now display the actual image instead of just the image asset icon if they have a URL specified
14
+ - Updated dependencies [8421756]
15
+ - @squiz/resource-browser@1.66.3
16
+
3
17
  ## 1.66.3
4
18
 
5
19
  ### Patch Changes
@@ -48,12 +48,6 @@ const resolveFontOptions = (node) => {
48
48
  const fontOptions = {};
49
49
  node.marks.forEach((mark) => {
50
50
  switch (mark.type.name) {
51
- case 'bold':
52
- fontOptions.bold = true;
53
- break;
54
- case 'italic':
55
- fontOptions.italics = true;
56
- break;
57
51
  case 'underline':
58
52
  fontOptions.underline = true;
59
53
  break;
@@ -109,14 +103,7 @@ const transformNode = (node) => {
109
103
  };
110
104
  }
111
105
  node.marks.forEach((mark) => {
112
- switch (mark.type.name) {
113
- case 'bold':
114
- case 'italic':
115
- case 'underline':
116
- break;
117
- default:
118
- transformedNode = transformMark(mark, transformedNode);
119
- }
106
+ transformedNode = transformMark(mark, transformedNode);
120
107
  });
121
108
  if (node.type.name === Extensions_1.NodeName.Unsupported) {
122
109
  const unsupportedNode = node.attrs?.originalNode;
@@ -133,7 +120,7 @@ const transformNode = (node) => {
133
120
  *
134
121
  * @return {FormattedNode}
135
122
  */
136
- const wrapNodeIfNeeded = (node, wrappingNode) => {
123
+ const wrapNodeIfNeeded = (node, wrappingNode, copyFont = true) => {
137
124
  if (node.type === 'tag' && wrappingNode.type === 'tag' && (node.tag === 'span' || node.tag === wrappingNode.tag)) {
138
125
  // if the node we are wrapping with is a DOM node, and the node being wrapped is
139
126
  // a plain looking DOM node merge the 2 nodes.
@@ -148,10 +135,12 @@ const wrapNodeIfNeeded = (node, wrappingNode) => {
148
135
  ...node.attributes,
149
136
  ...wrappingNode.attributes,
150
137
  }),
151
- font: (0, undefinedIfEmpty_1.undefinedIfEmpty)({
152
- ...node.font,
153
- ...wrappingNode.font,
154
- }),
138
+ font: (0, undefinedIfEmpty_1.undefinedIfEmpty)(copyFont
139
+ ? {
140
+ ...node.font,
141
+ ...wrappingNode.font,
142
+ }
143
+ : {}),
155
144
  children: [...node.children, ...wrappingNode.children],
156
145
  };
157
146
  }
@@ -163,13 +152,34 @@ const wrapNodeIfNeeded = (node, wrappingNode) => {
163
152
  };
164
153
  const transformMark = (mark, node) => {
165
154
  switch (mark.type.name) {
155
+ case 'bold':
156
+ return wrapNodeIfNeeded(node, {
157
+ type: 'tag',
158
+ tag: 'strong',
159
+ children: [],
160
+ }, false);
161
+ case 'italic':
162
+ return wrapNodeIfNeeded(node, {
163
+ type: 'tag',
164
+ tag: 'em',
165
+ children: [],
166
+ }, false);
167
+ case 'underline':
168
+ return wrapNodeIfNeeded(node, {
169
+ type: 'tag',
170
+ tag: 'span',
171
+ children: [],
172
+ font: {
173
+ underline: mark.type.name === 'underline',
174
+ },
175
+ });
166
176
  case 'link':
167
177
  return wrapNodeIfNeeded(node, {
168
178
  type: 'tag',
169
179
  tag: 'a',
170
180
  attributes: transformAttributes(mark.attrs),
171
181
  children: [],
172
- });
182
+ }, false);
173
183
  case 'assetLink':
174
184
  return wrapNodeIfNeeded(node, {
175
185
  type: 'link-to-matrix-asset',
@@ -24,7 +24,9 @@ const getNodeType = (node) => {
24
24
  ul: 'bulletList',
25
25
  hr: 'horizontalRule',
26
26
  a: Extensions_1.NodeName.Text,
27
+ em: Extensions_1.NodeName.Text,
27
28
  span: Extensions_1.NodeName.Text,
29
+ strong: Extensions_1.NodeName.Text,
28
30
  code: Extensions_1.NodeName.CodeBlock,
29
31
  };
30
32
  if (typeMap[node.type]) {
@@ -96,6 +98,12 @@ const getNodeMarks = (node) => {
96
98
  },
97
99
  });
98
100
  }
101
+ else if (node.type === 'tag' && node.tag === 'strong') {
102
+ marks.push({ type: 'bold' });
103
+ }
104
+ else if (node.type === 'tag' && node.tag === 'em') {
105
+ marks.push({ type: 'italic' });
106
+ }
99
107
  // Handle font formatting
100
108
  if ('font' in node && node.font !== undefined) {
101
109
  for (const [type, enabled] of Object.entries(node.font)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@squiz/formatted-text-editor",
3
- "version": "1.66.3",
3
+ "version": "1.67.0",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "private": false,
@@ -24,7 +24,7 @@
24
24
  "@mui/icons-material": "5.11.16",
25
25
  "@remirror/react": "2.0.25",
26
26
  "@squiz/dx-json-schema-lib": "^1.65.0",
27
- "@squiz/resource-browser": "^1.65.0",
27
+ "@squiz/resource-browser": "^1.66.3",
28
28
  "clsx": "1.2.1",
29
29
  "react-hook-form": "7.43.2",
30
30
  "react-image-size": "2.0.0",
@@ -74,16 +74,13 @@ describe('htmlToSquizNode', () => {
74
74
  children: [
75
75
  {
76
76
  type: 'tag',
77
- tag: 'span',
77
+ tag: 'em',
78
78
  children: [
79
79
  {
80
80
  type: 'text',
81
81
  value: 'Italicised text',
82
82
  },
83
83
  ],
84
- font: {
85
- italics: true,
86
- },
87
84
  },
88
85
  {
89
86
  type: 'text',
@@ -91,16 +88,13 @@ describe('htmlToSquizNode', () => {
91
88
  },
92
89
  {
93
90
  type: 'tag',
94
- tag: 'span',
91
+ tag: 'strong',
95
92
  children: [
96
93
  {
97
94
  type: 'text',
98
95
  value: 'Bold text',
99
96
  },
100
97
  ],
101
- font: {
102
- bold: true,
103
- },
104
98
  },
105
99
  ],
106
100
  tag: 'p',
@@ -116,7 +116,6 @@ export const sharedNodeExamples: NodeExample[] = [
116
116
  type: 'text',
117
117
  text: 'Hello',
118
118
  marks: [
119
- { type: 'bold' },
120
119
  {
121
120
  type: 'assetLink',
122
121
  attrs: {
@@ -126,20 +125,20 @@ export const sharedNodeExamples: NodeExample[] = [
126
125
  matrixIdentifier: 'matrix-api-identifier',
127
126
  },
128
127
  },
128
+ { type: 'bold' },
129
129
  ],
130
130
  },
131
131
  squizNode: [
132
132
  {
133
- type: 'link-to-matrix-asset',
134
- target: '_blank',
135
- matrixAssetId: '123',
136
- matrixDomain: 'https://my-matrix.squiz.net',
137
- matrixIdentifier: 'matrix-api-identifier',
133
+ type: 'tag',
134
+ tag: 'strong',
138
135
  children: [
139
136
  {
140
- type: 'tag',
141
- tag: 'span',
142
- font: { bold: true },
137
+ type: 'link-to-matrix-asset',
138
+ target: '_blank',
139
+ matrixAssetId: '123',
140
+ matrixDomain: 'https://my-matrix.squiz.net',
141
+ matrixIdentifier: 'matrix-api-identifier',
143
142
  children: [{ type: 'text', value: 'Hello' }],
144
143
  },
145
144
  ],
@@ -329,10 +329,7 @@ describe('remirrorNodeToSquizNode', () => {
329
329
  value: ' click',
330
330
  },
331
331
  ],
332
- font: {
333
- bold: true,
334
- },
335
- tag: 'span',
332
+ tag: 'strong',
336
333
  type: 'tag',
337
334
  },
338
335
  {
@@ -342,18 +339,22 @@ describe('remirrorNodeToSquizNode', () => {
342
339
  {
343
340
  children: [
344
341
  {
345
- type: 'text',
346
- value: 'here',
342
+ type: 'tag',
343
+ tag: 'a',
344
+ children: [
345
+ {
346
+ type: 'text',
347
+ value: 'here',
348
+ },
349
+ ],
350
+ attributes: {
351
+ href: 'https://www.google.com/',
352
+ title: '',
353
+ },
347
354
  },
348
355
  ],
349
- attributes: {
350
- href: 'https://www.google.com/',
351
- title: '',
352
- },
353
- font: {
354
- italics: true,
355
- },
356
- tag: 'a',
356
+
357
+ tag: 'em',
357
358
  type: 'tag',
358
359
  },
359
360
  {
@@ -363,10 +364,7 @@ describe('remirrorNodeToSquizNode', () => {
363
364
  value: ' ',
364
365
  },
365
366
  ],
366
- font: {
367
- italics: true,
368
- },
369
- tag: 'span',
367
+ tag: 'em',
370
368
  type: 'tag',
371
369
  },
372
370
  {
@@ -376,13 +374,23 @@ describe('remirrorNodeToSquizNode', () => {
376
374
  {
377
375
  children: [
378
376
  {
379
- type: 'text',
380
- value: ' GOOGLE!',
377
+ type: 'tag',
378
+ tag: 'em',
379
+ children: [
380
+ {
381
+ type: 'tag',
382
+ tag: 'strong',
383
+ children: [
384
+ {
385
+ type: 'text',
386
+ value: ' GOOGLE!',
387
+ },
388
+ ],
389
+ },
390
+ ],
381
391
  },
382
392
  ],
383
393
  font: {
384
- bold: true,
385
- italics: true,
386
394
  underline: true,
387
395
  },
388
396
  tag: 'span',
@@ -71,12 +71,6 @@ const resolveFontOptions = (node: ProsemirrorNode): FormattedNodeFontProperties
71
71
 
72
72
  node.marks.forEach((mark) => {
73
73
  switch (mark.type.name) {
74
- case 'bold':
75
- fontOptions.bold = true;
76
- break;
77
- case 'italic':
78
- fontOptions.italics = true;
79
- break;
80
74
  case 'underline':
81
75
  fontOptions.underline = true;
82
76
  break;
@@ -145,14 +139,7 @@ const transformNode = (node: ProsemirrorNode): FormattedNode => {
145
139
  }
146
140
 
147
141
  node.marks.forEach((mark) => {
148
- switch (mark.type.name) {
149
- case 'bold':
150
- case 'italic':
151
- case 'underline':
152
- break;
153
- default:
154
- transformedNode = transformMark(mark, transformedNode);
155
- }
142
+ transformedNode = transformMark(mark, transformedNode);
156
143
  });
157
144
 
158
145
  if (node.type.name === NodeName.Unsupported) {
@@ -172,7 +159,11 @@ const transformNode = (node: ProsemirrorNode): FormattedNode => {
172
159
  *
173
160
  * @return {FormattedNode}
174
161
  */
175
- const wrapNodeIfNeeded = (node: FormattedNode, wrappingNode: FormattedNodeWithChildren): FormattedNode => {
162
+ const wrapNodeIfNeeded = (
163
+ node: FormattedNode,
164
+ wrappingNode: FormattedNodeWithChildren,
165
+ copyFont: boolean = true,
166
+ ): FormattedNode => {
176
167
  if (node.type === 'tag' && wrappingNode.type === 'tag' && (node.tag === 'span' || node.tag === wrappingNode.tag)) {
177
168
  // if the node we are wrapping with is a DOM node, and the node being wrapped is
178
169
  // a plain looking DOM node merge the 2 nodes.
@@ -187,10 +178,14 @@ const wrapNodeIfNeeded = (node: FormattedNode, wrappingNode: FormattedNodeWithCh
187
178
  ...node.attributes,
188
179
  ...wrappingNode.attributes,
189
180
  }),
190
- font: undefinedIfEmpty({
191
- ...node.font,
192
- ...wrappingNode.font,
193
- }),
181
+ font: undefinedIfEmpty(
182
+ copyFont
183
+ ? {
184
+ ...node.font,
185
+ ...wrappingNode.font,
186
+ }
187
+ : {},
188
+ ),
194
189
  children: [...node.children, ...wrappingNode.children],
195
190
  };
196
191
  }
@@ -204,13 +199,46 @@ const wrapNodeIfNeeded = (node: FormattedNode, wrappingNode: FormattedNodeWithCh
204
199
 
205
200
  const transformMark = (mark: Mark, node: FormattedNode): FormattedNode => {
206
201
  switch (mark.type.name) {
207
- case 'link':
202
+ case 'bold':
203
+ return wrapNodeIfNeeded(
204
+ node,
205
+ {
206
+ type: 'tag',
207
+ tag: 'strong',
208
+ children: [],
209
+ },
210
+ false,
211
+ );
212
+ case 'italic':
213
+ return wrapNodeIfNeeded(
214
+ node,
215
+ {
216
+ type: 'tag',
217
+ tag: 'em',
218
+ children: [],
219
+ },
220
+ false,
221
+ );
222
+ case 'underline':
208
223
  return wrapNodeIfNeeded(node, {
209
224
  type: 'tag',
210
- tag: 'a',
211
- attributes: transformAttributes(mark.attrs),
225
+ tag: 'span',
212
226
  children: [],
227
+ font: {
228
+ underline: mark.type.name === 'underline',
229
+ },
213
230
  });
231
+ case 'link':
232
+ return wrapNodeIfNeeded(
233
+ node,
234
+ {
235
+ type: 'tag',
236
+ tag: 'a',
237
+ attributes: transformAttributes(mark.attrs),
238
+ children: [],
239
+ },
240
+ false,
241
+ );
214
242
  case 'assetLink':
215
243
  return wrapNodeIfNeeded(node, {
216
244
  type: 'link-to-matrix-asset',
@@ -29,7 +29,9 @@ const getNodeType = (node: FormattedNodes): string => {
29
29
  ul: 'bulletList',
30
30
  hr: 'horizontalRule',
31
31
  a: NodeName.Text,
32
+ em: NodeName.Text,
32
33
  span: NodeName.Text,
34
+ strong: NodeName.Text,
33
35
  code: NodeName.CodeBlock,
34
36
  };
35
37
 
@@ -105,6 +107,10 @@ const getNodeMarks = (node: FormattedNodes): ObjectMark[] => {
105
107
  target: node.target,
106
108
  },
107
109
  });
110
+ } else if (node.type === 'tag' && node.tag === 'strong') {
111
+ marks.push({ type: 'bold' });
112
+ } else if (node.type === 'tag' && node.tag === 'em') {
113
+ marks.push({ type: 'italic' });
108
114
  }
109
115
 
110
116
  // Handle font formatting