5htp-core 0.5.1-2 → 0.5.1-4

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "5htp-core",
3
3
  "description": "Convenient TypeScript framework designed for Performance and Productivity.",
4
- "version": "0.5.1-2",
4
+ "version": "0.5.1-4",
5
5
  "author": "Gaetan Le Gac (https://github.com/gaetanlegac)",
6
6
  "repository": "git://github.com/gaetanlegac/5htp-core.git",
7
7
  "license": "MIT",
@@ -43,12 +43,12 @@
43
43
  align-items: center;
44
44
  justify-content: center;
45
45
  vertical-align: middle;
46
- border-radius: @radius;
46
+ border-radius: 1rem;
47
47
 
48
48
  line-height: 1.5;
49
49
  text-align: left;
50
50
 
51
- padding: 0.4em @spacing;
51
+ padding: 0.4em 0.8em;
52
52
 
53
53
  background: var(--cBgActive);
54
54
  }
@@ -124,6 +124,7 @@ export class ImageNode extends DecoratorNode<React.JSX.Element> {
124
124
 
125
125
  const img = document.createElement('img');
126
126
  figure.appendChild(img);
127
+ img.setAttribute('loading', "lazy");
127
128
  img.setAttribute('src', this.__src);
128
129
  img.setAttribute('alt', this.__altText);
129
130
  img.setAttribute('width', this.__width.toString());
@@ -0,0 +1,56 @@
1
+
2
+ import { HeadingNode, HeadingTagType } from '@lexical/rich-text';
3
+ import { AutoLinkNode, LinkNode } from '@lexical/link';
4
+
5
+ export default class ReferenceLinkNode extends LinkNode {
6
+
7
+ public referenceTo?: string;
8
+
9
+ // Adding a static method to register the custom node
10
+ static getType() {
11
+ return 'reference-link';
12
+ }
13
+
14
+ static clone(node) {
15
+ return new ReferenceLinkNode(node.__url, {
16
+ rel: node.__rel,
17
+ target: node.__target,
18
+ title: node.__title
19
+ }, node.__key);
20
+ }
21
+
22
+ // Add a `referenceTo` attribute to the serialized JSON
23
+ static importJSON(serializedNode) {
24
+ const node = new ReferenceLinkNode(serializedNode.url);
25
+ node.referenceTo = serializedNode.referenceTo;
26
+ return node;
27
+ }
28
+
29
+ // Ensure the `referenceTo` attribute is serialized in JSON
30
+ exportJSON() {
31
+ return {
32
+ ...super.exportJSON(),
33
+ type: ReferenceLinkNode.getType(),
34
+ referenceTo: this.referenceTo
35
+ };
36
+ }
37
+
38
+ // Override createDOM to set the `referenceTo` attribute
39
+ createDOM(config) {
40
+ const dom = super.createDOM(config);
41
+ if (this.referenceTo) {
42
+ dom.setAttribute('class', this.referenceTo);
43
+ }
44
+ return dom;
45
+ }
46
+
47
+ // Update the DOM to reflect changes in the `referenceTo` attribute
48
+ updateDOM(prevNode, dom, config) {
49
+ const updated = super.updateDOM(prevNode, dom, config);
50
+ if (this.referenceTo !== prevNode.referenceTo) {
51
+ dom.setAttribute('class', this.referenceTo);
52
+ return true;
53
+ }
54
+ return updated;
55
+ }
56
+ }
@@ -36,6 +36,7 @@ import { TweetNode } from '@client/components/inputv3/Rte/nodes/TweetNode';
36
36
  import { YouTubeNode } from '@client/components/inputv3/Rte/nodes/YouTubeNode';
37
37
 
38
38
  import HeadingWithAnchorNode from '@client/components/inputv3/Rte/nodes/HeadingNode';
39
+ import ReferenceLinkNode from '@client/components/inputv3/Rte/nodes/ReferenceLinkNode';
39
40
 
40
41
  const PlaygroundNodes: Array<Klass<LexicalNode>> = [
41
42
  /*HeadingNode, */HeadingWithAnchorNode,
@@ -74,6 +75,9 @@ const PlaygroundNodes: Array<Klass<LexicalNode>> = [
74
75
  PageBreakNode,
75
76
  LayoutContainerNode,
76
77
  LayoutItemNode,
78
+
79
+ // Custom
80
+ ReferenceLinkNode
77
81
  ];
78
82
 
79
83
  export default PlaygroundNodes;
@@ -42,6 +42,15 @@ type LexicalNode = {
42
42
  }
43
43
 
44
44
  type TRenderOptions = {
45
+
46
+ transform?: RteUtils["transformNode"],
47
+
48
+ render?: (
49
+ node: LexicalNode,
50
+ parent: LexicalNode | null,
51
+ options: TRenderOptions
52
+ ) => Promise<LexicalNode>,
53
+
45
54
  attachements?: {
46
55
  disk: Driver,
47
56
  directory: string,
@@ -103,8 +112,8 @@ export class RteUtils {
103
112
  }
104
113
  }
105
114
 
106
- const root = await this.processContent(json.root, async (node) => {
107
- return await this.transformNode(node, assets, options);
115
+ const root = await this.processContent(json.root, null, async (node, parent) => {
116
+ return await this.transformNode(node, parent, assets, options);
108
117
  });
109
118
 
110
119
  json = { ...json, root };
@@ -113,29 +122,30 @@ export class RteUtils {
113
122
  const attachementOptions = options?.attachements;
114
123
  if (attachementOptions && attachementOptions.prevVersion !== undefined) {
115
124
 
116
- await this.processContent(root, async (node) => {
125
+ await this.processContent(root, null, async (node) => {
117
126
  return await this.deleteUnusedFile(node, assets, attachementOptions);
118
127
  });
119
128
  }
120
129
 
121
130
  // Convert json to HTML
122
- const html = await this.jsonToHtml( json );
131
+ const html = await this.jsonToHtml( json, options );
123
132
 
124
133
  return { html, json: content, ...assets };
125
134
  }
126
135
 
127
136
  private async processContent(
128
137
  node: LexicalNode,
129
- callback: (node: LexicalNode) => Promise<LexicalNode>
138
+ parent: LexicalNode | null,
139
+ callback: (node: LexicalNode, parent: LexicalNode | null) => Promise<LexicalNode>
130
140
  ) {
131
141
 
132
- node = await callback(node);
142
+ node = await callback(node, parent);
133
143
 
134
144
  // Recursion
135
145
  if (node.children) {
136
146
  for (let i = 0; i < node.children.length; i++) {
137
147
 
138
- node.children[ i ] = await this.processContent( node.children[ i ], callback );
148
+ node.children[ i ] = await this.processContent( node.children[ i ], node, callback );
139
149
 
140
150
  }
141
151
  }
@@ -143,23 +153,34 @@ export class RteUtils {
143
153
  return node;
144
154
  }
145
155
 
146
- private async transformNode(node: LexicalNode, assets: TContentAssets, options: TRenderOptions) {
156
+ private async transformNode(
157
+ node: LexicalNode,
158
+ parent: LexicalNode | null,
159
+ assets: TContentAssets,
160
+ options: TRenderOptions
161
+ ): Promise<LexicalNode> {
147
162
 
148
- // Attachment: Upload attachments and replace blobs by URLs
163
+ // Images and files
149
164
  if (node.type === 'image' || node.type === 'file') {
150
165
 
166
+ // Upload images and files and replace blobs by URLs
151
167
  await this.processAttachement(
152
168
  node as With<LexicalNode, 'src'>,
153
169
  assets,
154
170
  options,
155
171
  );
156
172
 
173
+ // Headings
157
174
  } else if (node.type === 'anchored-heading') {
158
175
 
176
+ // Create skeleton
159
177
  await this.processHeading(node, assets);
160
178
 
161
179
  }
162
180
 
181
+ if (options.transform)
182
+ node = await options.transform(node, parent, assets, options);
183
+
163
184
  return node;
164
185
  }
165
186
 
@@ -261,7 +282,17 @@ export class RteUtils {
261
282
  return node;
262
283
  }
263
284
 
264
- public async jsonToHtml( json: LexicalState ) {
285
+ public async jsonToHtml( json: LexicalState, options: TRenderOptions = {} ) {
286
+
287
+ // Transform before rendering
288
+ const renderTransform = options.render;
289
+ if (renderTransform)
290
+ json = {
291
+ ...json,
292
+ root: await this.processContent(json.root, null, async (node, parent) => {
293
+ return await renderTransform(node, parent, options);
294
+ })
295
+ }
265
296
 
266
297
  // Server side: simulate DOM environment
267
298
  const dom = new JSDOM(`<!DOCTYPE html><body></body>`);