@ampless/plugin-x-embed 1.0.0-alpha.7 → 1.0.0-alpha.8

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/dist/editor.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Node } from '@tiptap/core';
2
- import { TiptapNodeMarkdownAdapters } from 'ampless';
2
+ import { TiptapNodeHtmlAdapters, TiptapNodeMarkdownAdapters } from 'ampless';
3
3
 
4
4
  declare module '@tiptap/core' {
5
5
  interface Commands<ReturnType> {
@@ -47,4 +47,22 @@ declare const editorExtension: Node<any, any>;
47
47
  */
48
48
  declare const tiptapNodeToMarkdown: TiptapNodeMarkdownAdapters;
49
49
 
50
- export { AmplessTweetNode, editorExtension, tiptapNodeToMarkdown, tweetEditor };
50
+ /**
51
+ * tiptap → html adapter map. Serialises `amplessTweet` nodes to the
52
+ * canonical placeholder div `<div data-ampless-tweet data-tweet-id="..."
53
+ * class="ampless-tweet-placeholder">…</div>` so the admin's
54
+ * "format: tiptap → html" body switch is lossless. The div is what
55
+ * `Node.parseHTML`'s `tag: 'div[data-ampless-tweet]'` rule restores
56
+ * from. It is an admin format-switch interchange form; public rendering
57
+ * expands tweet embeds from the `tiptap` / `markdown` walkers, while
58
+ * `format: 'html'` preserves the div literally.
59
+ *
60
+ * `markdown → html` is a 2-hop via `generateJSON` (in admin format-switch);
61
+ * this adapter is reused by that path — no duplicate logic needed.
62
+ *
63
+ * `update-ampless` reads this export (via namespace import `* as`) and
64
+ * wires it into `installAdminTiptapNodeHtml`.
65
+ */
66
+ declare const tiptapNodeToHtml: TiptapNodeHtmlAdapters;
67
+
68
+ export { AmplessTweetNode, editorExtension, tiptapNodeToHtml, tiptapNodeToMarkdown, tweetEditor };
package/dist/editor.js CHANGED
@@ -23,6 +23,19 @@ function getBareUrlLinkHref(el) {
23
23
  if (el.textContent?.trim() !== linkText) return null;
24
24
  return href;
25
25
  }
26
+ function placeholderAttrs(attrs) {
27
+ return {
28
+ "data-ampless-tweet": "",
29
+ "data-tweet-id": String(attrs.tweetId ?? ""),
30
+ class: "ampless-tweet-placeholder"
31
+ };
32
+ }
33
+ function escapeAttr(v) {
34
+ return v.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
35
+ }
36
+ function attrsToHtmlString(attrs) {
37
+ return Object.entries(attrs).map(([k, v]) => v === "" ? k : `${k}="${escapeAttr(v)}"`).join(" ");
38
+ }
26
39
  var AmplessTweetNode = Node.create({
27
40
  name: "amplessTweet",
28
41
  group: "block",
@@ -98,10 +111,9 @@ var AmplessTweetNode = Node.create({
98
111
  renderHTML({ HTMLAttributes }) {
99
112
  return [
100
113
  "div",
101
- mergeAttributes(HTMLAttributes, {
102
- "data-ampless-tweet": "",
103
- class: "ampless-tweet-placeholder"
104
- }),
114
+ mergeAttributes(HTMLAttributes, placeholderAttrs({
115
+ tweetId: HTMLAttributes["data-tweet-id"]
116
+ })),
105
117
  ["span", {}, `Tweet: ${HTMLAttributes["data-tweet-id"] ?? ""}`]
106
118
  ];
107
119
  },
@@ -158,9 +170,18 @@ var tiptapNodeToMarkdown = {
158
170
  return `https://x.com/i/status/${tweetId}`;
159
171
  }
160
172
  };
173
+ var tiptapNodeToHtml = {
174
+ amplessTweet: (node) => {
175
+ const tweetId = String(node.attrs?.tweetId ?? "").trim();
176
+ if (!tweetId) return null;
177
+ const attrs = placeholderAttrs(node.attrs ?? {});
178
+ return `<div ${attrsToHtmlString(attrs)}><span>Tweet: ${escapeAttr(tweetId)}</span></div>`;
179
+ }
180
+ };
161
181
  export {
162
182
  AmplessTweetNode,
163
183
  editorExtension,
184
+ tiptapNodeToHtml,
164
185
  tiptapNodeToMarkdown,
165
186
  tweetEditor
166
187
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ampless/plugin-x-embed",
3
- "version": "1.0.0-alpha.7",
3
+ "version": "1.0.0-alpha.8",
4
4
  "description": "x.com (Twitter) embed plugin for ampless — renders tweet URLs inline as blockquotes hydrated by widgets.js",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -32,7 +32,7 @@
32
32
  "peerDependencies": {
33
33
  "@tiptap/core": "^3",
34
34
  "react": "^18 || ^19",
35
- "ampless": "1.0.0-alpha.46"
35
+ "ampless": "1.0.0-alpha.47"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@tiptap/core": "^3.23.6",