payload-richtext-tiptap 0.0.157 → 0.0.159

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.
Files changed (30) hide show
  1. package/dist/src/fields/TiptapEditor/extensions/BlockquoteFigure/BlockquoteFigure.d.ts +1 -1
  2. package/dist/src/fields/TiptapEditor/extensions/BlockquoteFigure/BlockquoteFigure.d.ts.map +1 -1
  3. package/dist/src/fields/TiptapEditor/extensions/BlockquoteFigure/BlockquoteFigure.js +61 -15
  4. package/dist/src/fields/TiptapEditor/extensions/BlockquoteFigure/BlockquoteFigure.js.map +1 -1
  5. package/dist/src/fields/TiptapEditor/extensions/BlockquoteFigure/Quote/Quote.d.ts.map +1 -1
  6. package/dist/src/fields/TiptapEditor/extensions/BlockquoteFigure/Quote/Quote.js +1 -3
  7. package/dist/src/fields/TiptapEditor/extensions/BlockquoteFigure/Quote/Quote.js.map +1 -1
  8. package/dist/src/fields/TiptapEditor/extensions/BlockquoteFigure/QuoteCaption/QuoteCaption.js.map +1 -1
  9. package/dist/src/fields/TiptapEditor/extensions/ImageBlock/components/GifPlayer.d.ts +12 -0
  10. package/dist/src/fields/TiptapEditor/extensions/ImageBlock/components/GifPlayer.d.ts.map +1 -0
  11. package/dist/src/fields/TiptapEditor/extensions/ImageBlock/components/GifPlayer.js +152 -0
  12. package/dist/src/fields/TiptapEditor/extensions/ImageBlock/components/GifPlayer.js.map +1 -0
  13. package/dist/src/fields/TiptapEditor/extensions/ImageBlock/components/SmartImage.d.ts +12 -0
  14. package/dist/src/fields/TiptapEditor/extensions/ImageBlock/components/SmartImage.d.ts.map +1 -0
  15. package/dist/src/fields/TiptapEditor/extensions/ImageBlock/components/SmartImage.js +55 -0
  16. package/dist/src/fields/TiptapEditor/extensions/ImageBlock/components/SmartImage.js.map +1 -0
  17. package/dist/src/fields/TiptapEditor/extensions/ImageBlock/components/TestImage.d.ts +4 -0
  18. package/dist/src/fields/TiptapEditor/extensions/ImageBlock/components/TestImage.d.ts.map +1 -0
  19. package/dist/src/fields/TiptapEditor/extensions/ImageBlock/components/TestImage.js +26 -0
  20. package/dist/src/fields/TiptapEditor/extensions/ImageBlock/components/TestImage.js.map +1 -0
  21. package/dist/src/fields/TiptapEditor/extensions/ImageBlock/utils/gifUtils.d.ts +31 -0
  22. package/dist/src/fields/TiptapEditor/extensions/ImageBlock/utils/gifUtils.d.ts.map +1 -0
  23. package/dist/src/fields/TiptapEditor/extensions/ImageBlock/utils/gifUtils.js +62 -0
  24. package/dist/src/fields/TiptapEditor/extensions/ImageBlock/utils/gifUtils.js.map +1 -0
  25. package/dist/src/fields/TiptapEditor/features/menus/TextMenu/TextMenu.d.ts +2 -2
  26. package/dist/src/fields/TiptapEditor/features/menus/TextMenu/TextMenu.d.ts.map +1 -1
  27. package/dist/src/fields/TiptapEditor/features/menus/TextMenu/TextMenu.js +63 -58
  28. package/dist/src/fields/TiptapEditor/features/menus/TextMenu/TextMenu.js.map +1 -1
  29. package/dist/tsconfig.tsbuildinfo +1 -1
  30. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- declare module "@tiptap/core" {
1
+ declare module '@tiptap/core' {
2
2
  interface Commands<ReturnType> {
3
3
  blockquoteFigure: {
4
4
  setBlockquote: () => ReturnType;
@@ -1 +1 @@
1
- {"version":3,"file":"BlockquoteFigure.d.ts","sourceRoot":"","sources":["../../../../../../src/fields/TiptapEditor/extensions/BlockquoteFigure/BlockquoteFigure.ts"],"names":[],"mappings":"AAKA,OAAO,QAAQ,cAAc,CAAC;IAE5B,UAAU,QAAQ,CAAC,UAAU;QAC3B,gBAAgB,EAAE;YAChB,aAAa,EAAE,MAAM,UAAU,CAAC;SACjC,CAAC;KACH;CACF;AAED,eAAO,MAAM,gBAAgB,uCAmE3B,CAAC;AAEH,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"BlockquoteFigure.d.ts","sourceRoot":"","sources":["../../../../../../src/fields/TiptapEditor/extensions/BlockquoteFigure/BlockquoteFigure.ts"],"names":[],"mappings":"AAKA,OAAO,QAAQ,cAAc,CAAC;IAE5B,UAAU,QAAQ,CAAC,UAAU;QAC3B,gBAAgB,EAAE;YAChB,aAAa,EAAE,MAAM,UAAU,CAAA;SAChC,CAAA;KACF;CACF;AAED,eAAO,MAAM,gBAAgB,uCA4H3B,CAAA;AAEF,eAAe,gBAAgB,CAAA"}
@@ -1,11 +1,11 @@
1
- import { mergeAttributes } from "@tiptap/core";
2
- import { Figure } from "../Figure/Figure.js";
3
- import { Quote } from "./Quote/Quote.js";
4
- import { QuoteCaption } from "./QuoteCaption/QuoteCaption.js";
1
+ import { mergeAttributes } from '@tiptap/core';
2
+ import { Figure } from '../Figure/Figure.js';
3
+ import { Quote } from './Quote/Quote.js';
4
+ import { QuoteCaption } from './QuoteCaption/QuoteCaption.js';
5
5
  export const BlockquoteFigure = Figure.extend({
6
- name: "blockquoteFigure",
7
- group: "block",
8
- content: "quote quoteCaption",
6
+ name: 'blockquoteFigure',
7
+ group: 'block',
8
+ content: 'quote quoteCaption',
9
9
  isolating: true,
10
10
  addExtensions () {
11
11
  return [
@@ -15,12 +15,12 @@ export const BlockquoteFigure = Figure.extend({
15
15
  },
16
16
  renderHTML ({ HTMLAttributes }) {
17
17
  return [
18
- "figure",
18
+ 'figure',
19
19
  mergeAttributes(HTMLAttributes, {
20
- "data-type": this.name
20
+ 'data-type': this.name
21
21
  }),
22
22
  [
23
- "div",
23
+ 'div',
24
24
  {},
25
25
  0
26
26
  ]
@@ -28,7 +28,53 @@ export const BlockquoteFigure = Figure.extend({
28
28
  },
29
29
  addKeyboardShortcuts () {
30
30
  return {
31
- Enter: ()=>false
31
+ Enter: ()=>false,
32
+ Backspace: ({ editor })=>{
33
+ const { state } = editor;
34
+ const { selection } = state;
35
+ const { $from } = selection;
36
+ let blockquoteFigureNode = null;
37
+ let blockquoteFigureDepth = -1;
38
+ // Look deeper in the hierarchy - the BlockquoteFigure might be at a higher level
39
+ for(let i = $from.depth; i >= 0; i--){
40
+ const node = $from.node(i);
41
+ if (node.type.name === 'blockquoteFigure') {
42
+ blockquoteFigureNode = node;
43
+ blockquoteFigureDepth = i;
44
+ break;
45
+ }
46
+ }
47
+ if (!blockquoteFigureNode) {
48
+ // Also check parent nodes that might not be in the depth range
49
+ let pos = $from.pos;
50
+ while(pos > 0){
51
+ const node = editor.state.doc.nodeAt(pos);
52
+ if (node && node.type.name === 'blockquoteFigure') {
53
+ blockquoteFigureNode = node;
54
+ break;
55
+ }
56
+ pos = editor.state.doc.resolve(pos).before();
57
+ if (pos === 0) break;
58
+ }
59
+ }
60
+ if (!blockquoteFigureNode) {
61
+ return false;
62
+ }
63
+ // Check if we're at the start of the current node
64
+ const isAtStart = $from.parentOffset === 0;
65
+ // Find the quote and caption nodes within the BlockquoteFigure
66
+ const quoteNode = blockquoteFigureNode.firstChild;
67
+ const captionNode = blockquoteFigureNode.lastChild;
68
+ // Check if both quote and caption are empty
69
+ const isQuoteEmpty = quoteNode && (quoteNode.content.size === 0 || quoteNode.content.size === 2 && quoteNode.firstChild?.type.name === 'paragraph' && quoteNode.firstChild.content.size === 0);
70
+ const isCaptionEmpty = captionNode && captionNode.content.size === 0;
71
+ // Delete if we're at the start and both quote and caption are empty
72
+ if (isAtStart && isQuoteEmpty && isCaptionEmpty) {
73
+ const pos = $from.before(blockquoteFigureDepth);
74
+ return editor.chain().setNodeSelection(pos).deleteSelection().run();
75
+ }
76
+ return false;
77
+ }
32
78
  };
33
79
  },
34
80
  addAttributes () {
@@ -45,18 +91,18 @@ export const BlockquoteFigure = Figure.extend({
45
91
  type: this.name,
46
92
  content: [
47
93
  {
48
- type: "quote",
94
+ type: 'quote',
49
95
  content: selectionContent.content.toJSON() || [
50
96
  {
51
- type: "paragraph",
97
+ type: 'paragraph',
52
98
  attrs: {
53
- textAlign: "left"
99
+ textAlign: 'left'
54
100
  }
55
101
  }
56
102
  ]
57
103
  },
58
104
  {
59
- type: "quoteCaption"
105
+ type: 'quoteCaption'
60
106
  }
61
107
  ]
62
108
  }).focus(position + 1).run();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../src/fields/TiptapEditor/extensions/BlockquoteFigure/BlockquoteFigure.ts"],"sourcesContent":["import { mergeAttributes } from \"@tiptap/core\";\r\nimport { Figure } from \"../Figure/Figure.js\";\r\nimport { Quote } from \"./Quote/Quote.js\";\r\nimport { QuoteCaption } from \"./QuoteCaption/QuoteCaption.js\";\r\n\r\ndeclare module \"@tiptap/core\" {\r\n // eslint-disable-next-line no-unused-vars\r\n interface Commands<ReturnType> {\r\n blockquoteFigure: {\r\n setBlockquote: () => ReturnType;\r\n };\r\n }\r\n}\r\n\r\nexport const BlockquoteFigure = Figure.extend({\r\n name: \"blockquoteFigure\",\r\n\r\n group: \"block\",\r\n\r\n content: \"quote quoteCaption\",\r\n\r\n isolating: true,\r\n\r\n addExtensions() {\r\n return [Quote, QuoteCaption];\r\n },\r\n\r\n renderHTML({ HTMLAttributes }) {\r\n return [\r\n \"figure\",\r\n mergeAttributes(HTMLAttributes, { \"data-type\": this.name }),\r\n [\"div\", {}, 0],\r\n ];\r\n },\r\n\r\n addKeyboardShortcuts() {\r\n return {\r\n Enter: () => false,\r\n };\r\n },\r\n\r\n addAttributes() {\r\n return {\r\n ...this.parent?.(),\r\n };\r\n },\r\n\r\n addCommands() {\r\n return {\r\n setBlockquote:\r\n () =>\r\n ({ state, chain }) => {\r\n const position = state.selection.$from.start();\r\n const selectionContent = state.selection.content();\r\n\r\n return chain()\r\n .focus()\r\n .insertContent({\r\n type: this.name,\r\n content: [\r\n {\r\n type: \"quote\",\r\n content: selectionContent.content.toJSON() || [\r\n {\r\n type: \"paragraph\",\r\n attrs: {\r\n textAlign: \"left\",\r\n },\r\n },\r\n ],\r\n },\r\n {\r\n type: \"quoteCaption\",\r\n },\r\n ],\r\n })\r\n .focus(position + 1)\r\n .run();\r\n },\r\n };\r\n },\r\n});\r\n\r\nexport default BlockquoteFigure;\r\n"],"names":["mergeAttributes","Figure","Quote","QuoteCaption","BlockquoteFigure","extend","name","group","content","isolating","addExtensions","renderHTML","HTMLAttributes","addKeyboardShortcuts","Enter","addAttributes","parent","addCommands","setBlockquote","state","chain","position","selection","$from","start","selectionContent","focus","insertContent","type","toJSON","attrs","textAlign","run"],"mappings":"AAAA,SAASA,eAAe,QAAQ,eAAe;AAC/C,SAASC,MAAM,QAAQ,sBAAsB;AAC7C,SAASC,KAAK,QAAQ,mBAAmB;AACzC,SAASC,YAAY,QAAQ,iCAAiC;AAW9D,OAAO,MAAMC,mBAAmBH,OAAOI,MAAM,CAAC;IAC5CC,MAAM;IAENC,OAAO;IAEPC,SAAS;IAETC,WAAW;IAEXC;QACE,OAAO;YAACR;YAAOC;SAAa;IAC9B;IAEAQ,YAAW,EAAEC,cAAc,EAAE;QAC3B,OAAO;YACL;YACAZ,gBAAgBY,gBAAgB;gBAAE,aAAa,IAAI,CAACN,IAAI;YAAC;YACzD;gBAAC;gBAAO,CAAC;gBAAG;aAAE;SACf;IACH;IAEAO;QACE,OAAO;YACLC,OAAO,IAAM;QACf;IACF;IAEAC;QACE,OAAO;YACL,GAAG,IAAI,CAACC,MAAM,IAAI;QACpB;IACF;IAEAC;QACE,OAAO;YACLC,eACE,IACA,CAAC,EAAEC,KAAK,EAAEC,KAAK,EAAE;oBACf,MAAMC,WAAWF,MAAMG,SAAS,CAACC,KAAK,CAACC,KAAK;oBAC5C,MAAMC,mBAAmBN,MAAMG,SAAS,CAACd,OAAO;oBAEhD,OAAOY,QACJM,KAAK,GACLC,aAAa,CAAC;wBACbC,MAAM,IAAI,CAACtB,IAAI;wBACfE,SAAS;4BACP;gCACEoB,MAAM;gCACNpB,SAASiB,iBAAiBjB,OAAO,CAACqB,MAAM,MAAM;oCAC5C;wCACED,MAAM;wCACNE,OAAO;4CACLC,WAAW;wCACb;oCACF;iCACD;4BACH;4BACA;gCACEH,MAAM;4BACR;yBACD;oBACH,GACCF,KAAK,CAACL,WAAW,GACjBW,GAAG;gBACR;QACJ;IACF;AACF,GAAG;AAEH,eAAe5B,iBAAiB"}
1
+ {"version":3,"sources":["../../../../../../src/fields/TiptapEditor/extensions/BlockquoteFigure/BlockquoteFigure.ts"],"sourcesContent":["import { mergeAttributes } from '@tiptap/core'\nimport { Figure } from '../Figure/Figure.js'\nimport { Quote } from './Quote/Quote.js'\nimport { QuoteCaption } from './QuoteCaption/QuoteCaption.js'\n\ndeclare module '@tiptap/core' {\n // eslint-disable-next-line no-unused-vars\n interface Commands<ReturnType> {\n blockquoteFigure: {\n setBlockquote: () => ReturnType\n }\n }\n}\n\nexport const BlockquoteFigure = Figure.extend({\n name: 'blockquoteFigure',\n\n group: 'block',\n\n content: 'quote quoteCaption',\n\n isolating: true,\n\n addExtensions() {\n return [Quote, QuoteCaption]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['figure', mergeAttributes(HTMLAttributes, { 'data-type': this.name }), ['div', {}, 0]]\n },\n\n addKeyboardShortcuts() {\n return {\n Enter: () => false,\n Backspace: ({ editor }) => {\n const { state } = editor\n const { selection } = state\n const { $from } = selection\n\n let blockquoteFigureNode = null\n let blockquoteFigureDepth = -1\n\n // Look deeper in the hierarchy - the BlockquoteFigure might be at a higher level\n for (let i = $from.depth; i >= 0; i--) {\n const node = $from.node(i)\n if (node.type.name === 'blockquoteFigure') {\n blockquoteFigureNode = node\n blockquoteFigureDepth = i\n break\n }\n }\n\n if (!blockquoteFigureNode) {\n // Also check parent nodes that might not be in the depth range\n let pos = $from.pos\n while (pos > 0) {\n const node = editor.state.doc.nodeAt(pos)\n if (node && node.type.name === 'blockquoteFigure') {\n blockquoteFigureNode = node\n break\n }\n pos = editor.state.doc.resolve(pos).before()\n if (pos === 0) break\n }\n }\n\n if (!blockquoteFigureNode) {\n return false\n }\n\n // Check if we're at the start of the current node\n const isAtStart = $from.parentOffset === 0\n\n // Find the quote and caption nodes within the BlockquoteFigure\n const quoteNode = blockquoteFigureNode.firstChild\n const captionNode = blockquoteFigureNode.lastChild\n\n // Check if both quote and caption are empty\n const isQuoteEmpty =\n quoteNode &&\n (quoteNode.content.size === 0 ||\n (quoteNode.content.size === 2 &&\n quoteNode.firstChild?.type.name === 'paragraph' &&\n quoteNode.firstChild.content.size === 0))\n\n const isCaptionEmpty = captionNode && captionNode.content.size === 0\n\n // Delete if we're at the start and both quote and caption are empty\n if (isAtStart && isQuoteEmpty && isCaptionEmpty) {\n const pos = $from.before(blockquoteFigureDepth)\n return editor.chain().setNodeSelection(pos).deleteSelection().run()\n }\n\n return false\n },\n }\n },\n\n addAttributes() {\n return {\n ...this.parent?.(),\n }\n },\n\n addCommands() {\n return {\n setBlockquote:\n () =>\n ({ state, chain }) => {\n const position = state.selection.$from.start()\n const selectionContent = state.selection.content()\n\n return chain()\n .focus()\n .insertContent({\n type: this.name,\n content: [\n {\n type: 'quote',\n content: selectionContent.content.toJSON() || [\n {\n type: 'paragraph',\n attrs: {\n textAlign: 'left',\n },\n },\n ],\n },\n {\n type: 'quoteCaption',\n },\n ],\n })\n .focus(position + 1)\n .run()\n },\n }\n },\n})\n\nexport default BlockquoteFigure\n"],"names":["mergeAttributes","Figure","Quote","QuoteCaption","BlockquoteFigure","extend","name","group","content","isolating","addExtensions","renderHTML","HTMLAttributes","addKeyboardShortcuts","Enter","Backspace","editor","state","selection","$from","blockquoteFigureNode","blockquoteFigureDepth","i","depth","node","type","pos","doc","nodeAt","resolve","before","isAtStart","parentOffset","quoteNode","firstChild","captionNode","lastChild","isQuoteEmpty","size","isCaptionEmpty","chain","setNodeSelection","deleteSelection","run","addAttributes","parent","addCommands","setBlockquote","position","start","selectionContent","focus","insertContent","toJSON","attrs","textAlign"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Quote.d.ts","sourceRoot":"","sources":["../../../../../../../src/fields/TiptapEditor/extensions/BlockquoteFigure/Quote/Quote.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AAEnC,eAAO,MAAM,KAAK,gBA0BhB,CAAA;AAEF,eAAe,KAAK,CAAA"}
1
+ {"version":3,"file":"Quote.d.ts","sourceRoot":"","sources":["../../../../../../../src/fields/TiptapEditor/extensions/BlockquoteFigure/Quote/Quote.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AAEnC,eAAO,MAAM,KAAK,gBAwBhB,CAAA;AAEF,eAAe,KAAK,CAAA"}
@@ -19,9 +19,7 @@ export const Quote = Node.create({
19
19
  ];
20
20
  },
21
21
  addKeyboardShortcuts () {
22
- return {
23
- Backspace: ()=>false
24
- };
22
+ return {};
25
23
  }
26
24
  });
27
25
  export default Quote;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../src/fields/TiptapEditor/extensions/BlockquoteFigure/Quote/Quote.ts"],"sourcesContent":["import { Node } from '@tiptap/core'\r\n\r\nexport const Quote = Node.create({\r\n name: 'quote',\r\n\r\n content: 'paragraph+',\r\n\r\n defining: true,\r\n\r\n marks: '',\r\n\r\n parseHTML() {\r\n return [\r\n {\r\n tag: 'blockquote',\r\n },\r\n ]\r\n },\r\n\r\n renderHTML({ HTMLAttributes }) {\r\n return ['blockquote', HTMLAttributes, 0]\r\n },\r\n\r\n addKeyboardShortcuts() {\r\n return {\r\n Backspace: () => false,\r\n }\r\n },\r\n})\r\n\r\nexport default Quote\r\n"],"names":["Node","Quote","create","name","content","defining","marks","parseHTML","tag","renderHTML","HTMLAttributes","addKeyboardShortcuts","Backspace"],"mappings":"AAAA,SAASA,IAAI,QAAQ,eAAc;AAEnC,OAAO,MAAMC,QAAQD,KAAKE,MAAM,CAAC;IAC/BC,MAAM;IAENC,SAAS;IAETC,UAAU;IAEVC,OAAO;IAEPC;QACE,OAAO;YACL;gBACEC,KAAK;YACP;SACD;IACH;IAEAC,YAAW,EAAEC,cAAc,EAAE;QAC3B,OAAO;YAAC;YAAcA;YAAgB;SAAE;IAC1C;IAEAC;QACE,OAAO;YACLC,WAAW,IAAM;QACnB;IACF;AACF,GAAE;AAEF,eAAeX,MAAK"}
1
+ {"version":3,"sources":["../../../../../../../src/fields/TiptapEditor/extensions/BlockquoteFigure/Quote/Quote.ts"],"sourcesContent":["import { Node } from '@tiptap/core'\n\nexport const Quote = Node.create({\n name: 'quote',\n\n content: 'paragraph+',\n\n defining: true,\n\n marks: '',\n\n parseHTML() {\n return [\n {\n tag: 'blockquote',\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['blockquote', HTMLAttributes, 0]\n },\n\n addKeyboardShortcuts() {\n return {}\n },\n})\n\nexport default Quote\n"],"names":["Node","Quote","create","name","content","defining","marks","parseHTML","tag","renderHTML","HTMLAttributes","addKeyboardShortcuts"],"mappings":"AAAA,SAASA,IAAI,QAAQ,eAAc;AAEnC,OAAO,MAAMC,QAAQD,KAAKE,MAAM,CAAC;IAC/BC,MAAM;IAENC,SAAS;IAETC,UAAU;IAEVC,OAAO;IAEPC;QACE,OAAO;YACL;gBACEC,KAAK;YACP;SACD;IACH;IAEAC,YAAW,EAAEC,cAAc,EAAE;QAC3B,OAAO;YAAC;YAAcA;YAAgB;SAAE;IAC1C;IAEAC;QACE,OAAO,CAAC;IACV;AACF,GAAE;AAEF,eAAeV,MAAK"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../src/fields/TiptapEditor/extensions/BlockquoteFigure/QuoteCaption/QuoteCaption.ts"],"sourcesContent":["import { Node } from '@tiptap/core'\r\n\r\nexport const QuoteCaption = Node.create({\r\n name: 'quoteCaption',\r\n\r\n group: 'block',\r\n\r\n content: 'text*',\r\n\r\n defining: true,\r\n\r\n isolating: true,\r\n\r\n parseHTML() {\r\n return [\r\n {\r\n tag: 'figcaption',\r\n },\r\n ]\r\n },\r\n\r\n renderHTML({ HTMLAttributes }) {\r\n return ['figcaption', HTMLAttributes, 0]\r\n },\r\n\r\n addKeyboardShortcuts() {\r\n return {\r\n // On Enter at the end of line, create new paragraph and focus\r\n Enter: ({ editor }) => {\r\n const {\r\n state: {\r\n selection: { $from, empty },\r\n },\r\n } = editor\r\n\r\n if (!empty || $from.parent.type !== this.type) {\r\n return false\r\n }\r\n\r\n const isAtEnd = $from.parentOffset === $from.parent.nodeSize - 2\r\n\r\n if (!isAtEnd) {\r\n return false\r\n }\r\n\r\n const pos = editor.state.selection.$from.end()\r\n\r\n return editor.chain().focus(pos).insertContentAt(pos, { type: 'paragraph' }).run()\r\n },\r\n }\r\n },\r\n})\r\n\r\nexport default QuoteCaption\r\n"],"names":["Node","QuoteCaption","create","name","group","content","defining","isolating","parseHTML","tag","renderHTML","HTMLAttributes","addKeyboardShortcuts","Enter","editor","state","selection","$from","empty","parent","type","isAtEnd","parentOffset","nodeSize","pos","end","chain","focus","insertContentAt","run"],"mappings":"AAAA,SAASA,IAAI,QAAQ,eAAc;AAEnC,OAAO,MAAMC,eAAeD,KAAKE,MAAM,CAAC;IACtCC,MAAM;IAENC,OAAO;IAEPC,SAAS;IAETC,UAAU;IAEVC,WAAW;IAEXC;QACE,OAAO;YACL;gBACEC,KAAK;YACP;SACD;IACH;IAEAC,YAAW,EAAEC,cAAc,EAAE;QAC3B,OAAO;YAAC;YAAcA;YAAgB;SAAE;IAC1C;IAEAC;QACE,OAAO;YACL,8DAA8D;YAC9DC,OAAO,CAAC,EAAEC,MAAM,EAAE;gBAChB,MAAM,EACJC,OAAO,EACLC,WAAW,EAAEC,KAAK,EAAEC,KAAK,EAAE,EAC5B,EACF,GAAGJ;gBAEJ,IAAI,CAACI,SAASD,MAAME,MAAM,CAACC,IAAI,KAAK,IAAI,CAACA,IAAI,EAAE;oBAC7C,OAAO;gBACT;gBAEA,MAAMC,UAAUJ,MAAMK,YAAY,KAAKL,MAAME,MAAM,CAACI,QAAQ,GAAG;gBAE/D,IAAI,CAACF,SAAS;oBACZ,OAAO;gBACT;gBAEA,MAAMG,MAAMV,OAAOC,KAAK,CAACC,SAAS,CAACC,KAAK,CAACQ,GAAG;gBAE5C,OAAOX,OAAOY,KAAK,GAAGC,KAAK,CAACH,KAAKI,eAAe,CAACJ,KAAK;oBAAEJ,MAAM;gBAAY,GAAGS,GAAG;YAClF;QACF;IACF;AACF,GAAE;AAEF,eAAe5B,aAAY"}
1
+ {"version":3,"sources":["../../../../../../../src/fields/TiptapEditor/extensions/BlockquoteFigure/QuoteCaption/QuoteCaption.ts"],"sourcesContent":["import { Node } from '@tiptap/core'\n\nexport const QuoteCaption = Node.create({\n name: 'quoteCaption',\n\n group: 'block',\n\n content: 'text*',\n\n defining: true,\n\n isolating: true,\n\n parseHTML() {\n return [\n {\n tag: 'figcaption',\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['figcaption', HTMLAttributes, 0]\n },\n\n addKeyboardShortcuts() {\n return {\n // On Enter at the end of line, create new paragraph and focus\n Enter: ({ editor }) => {\n const {\n state: {\n selection: { $from, empty },\n },\n } = editor\n\n if (!empty || $from.parent.type !== this.type) {\n return false\n }\n\n const isAtEnd = $from.parentOffset === $from.parent.nodeSize - 2\n\n if (!isAtEnd) {\n return false\n }\n\n const pos = editor.state.selection.$from.end()\n\n return editor.chain().focus(pos).insertContentAt(pos, { type: 'paragraph' }).run()\n },\n }\n },\n})\n\nexport default QuoteCaption\n"],"names":["Node","QuoteCaption","create","name","group","content","defining","isolating","parseHTML","tag","renderHTML","HTMLAttributes","addKeyboardShortcuts","Enter","editor","state","selection","$from","empty","parent","type","isAtEnd","parentOffset","nodeSize","pos","end","chain","focus","insertContentAt","run"],"mappings":"AAAA,SAASA,IAAI,QAAQ,eAAc;AAEnC,OAAO,MAAMC,eAAeD,KAAKE,MAAM,CAAC;IACtCC,MAAM;IAENC,OAAO;IAEPC,SAAS;IAETC,UAAU;IAEVC,WAAW;IAEXC;QACE,OAAO;YACL;gBACEC,KAAK;YACP;SACD;IACH;IAEAC,YAAW,EAAEC,cAAc,EAAE;QAC3B,OAAO;YAAC;YAAcA;YAAgB;SAAE;IAC1C;IAEAC;QACE,OAAO;YACL,8DAA8D;YAC9DC,OAAO,CAAC,EAAEC,MAAM,EAAE;gBAChB,MAAM,EACJC,OAAO,EACLC,WAAW,EAAEC,KAAK,EAAEC,KAAK,EAAE,EAC5B,EACF,GAAGJ;gBAEJ,IAAI,CAACI,SAASD,MAAME,MAAM,CAACC,IAAI,KAAK,IAAI,CAACA,IAAI,EAAE;oBAC7C,OAAO;gBACT;gBAEA,MAAMC,UAAUJ,MAAMK,YAAY,KAAKL,MAAME,MAAM,CAACI,QAAQ,GAAG;gBAE/D,IAAI,CAACF,SAAS;oBACZ,OAAO;gBACT;gBAEA,MAAMG,MAAMV,OAAOC,KAAK,CAACC,SAAS,CAACC,KAAK,CAACQ,GAAG;gBAE5C,OAAOX,OAAOY,KAAK,GAAGC,KAAK,CAACH,KAAKI,eAAe,CAACJ,KAAK;oBAAEJ,MAAM;gBAAY,GAAGS,GAAG;YAClF;QACF;IACF;AACF,GAAE;AAEF,eAAe5B,aAAY"}
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ interface GifPlayerProps {
3
+ src: string;
4
+ alt?: string;
5
+ className?: string;
6
+ onClick?: () => void;
7
+ width?: number;
8
+ height?: number;
9
+ }
10
+ export declare const GifPlayer: React.FC<GifPlayerProps>;
11
+ export default GifPlayer;
12
+ //# sourceMappingURL=GifPlayer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GifPlayer.d.ts","sourceRoot":"","sources":["../../../../../../../src/fields/TiptapEditor/extensions/ImageBlock/components/GifPlayer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAA;AAG1D,UAAU,cAAc;IACtB,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAmL9C,CAAA;AAED,eAAe,SAAS,CAAA"}
@@ -0,0 +1,152 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import React, { useEffect, useRef, useState } from 'react';
3
+ import { decompressFrames, parseGIF } from 'gifuct-js';
4
+ export const GifPlayer = ({ src, alt = '', className = '', onClick, width, height })=>{
5
+ const canvasRef = useRef(null);
6
+ const [isLoading, setIsLoading] = useState(true);
7
+ const [error, setError] = useState(null);
8
+ const animationRef = useRef(undefined);
9
+ const framesRef = useRef([]);
10
+ const currentFrameRef = useRef(0);
11
+ const startTimeRef = useRef(0);
12
+ useEffect(()=>{
13
+ let isMounted = true;
14
+ const loadGif = async ()=>{
15
+ try {
16
+ setIsLoading(true);
17
+ setError(null);
18
+ console.log('GifPlayer: Loading GIF from:', src);
19
+ // Fetch the GIF data
20
+ const response = await fetch(src);
21
+ if (!response.ok) {
22
+ throw new Error(`Failed to fetch GIF: ${response.statusText}`);
23
+ }
24
+ const arrayBuffer = await response.arrayBuffer();
25
+ console.log('GifPlayer: GIF loaded, size:', arrayBuffer.byteLength);
26
+ // Parse and decompress the GIF
27
+ const gif = parseGIF(arrayBuffer);
28
+ const frames = decompressFrames(gif, true);
29
+ console.log('GifPlayer: GIF parsed, frames:', frames.length);
30
+ if (!isMounted) return;
31
+ framesRef.current = frames;
32
+ setIsLoading(false);
33
+ // Set canvas dimensions
34
+ const canvas = canvasRef.current;
35
+ if (canvas && frames.length > 0) {
36
+ const firstFrame = frames[0];
37
+ canvas.width = width || firstFrame.dims.width;
38
+ canvas.height = height || firstFrame.dims.height;
39
+ console.log('GifPlayer: Canvas dimensions set:', canvas.width, 'x', canvas.height);
40
+ }
41
+ // Start animation
42
+ startAnimation();
43
+ } catch (err) {
44
+ console.error('GifPlayer: Error loading GIF:', err);
45
+ if (isMounted) {
46
+ setError(err instanceof Error ? err.message : 'Failed to load GIF');
47
+ setIsLoading(false);
48
+ }
49
+ }
50
+ };
51
+ const startAnimation = ()=>{
52
+ const canvas = canvasRef.current;
53
+ if (!canvas || framesRef.current.length === 0) return;
54
+ const ctx = canvas.getContext('2d');
55
+ if (!ctx) return;
56
+ startTimeRef.current = performance.now();
57
+ const animate = (currentTime)=>{
58
+ if (!isMounted) return;
59
+ const frames = framesRef.current;
60
+ if (frames.length === 0) return;
61
+ // Calculate which frame to show based on elapsed time
62
+ let elapsed = currentTime - startTimeRef.current;
63
+ let frameIndex = 0;
64
+ let frameTime = 0;
65
+ // Find the current frame based on timing
66
+ for(let i = 0; i < frames.length; i++){
67
+ const frame = frames[i];
68
+ const delay = frame.delay || 100 // Default 100ms if no delay specified
69
+ ;
70
+ if (elapsed < frameTime + delay) {
71
+ frameIndex = i;
72
+ break;
73
+ }
74
+ frameTime += delay;
75
+ }
76
+ // If we've gone through all frames, restart the loop (infinite loop)
77
+ if (elapsed >= frameTime) {
78
+ startTimeRef.current = currentTime;
79
+ frameIndex = 0;
80
+ elapsed = 0;
81
+ }
82
+ // Only update if frame changed
83
+ if (frameIndex !== currentFrameRef.current) {
84
+ currentFrameRef.current = frameIndex;
85
+ const frame = frames[frameIndex];
86
+ // Clear canvas
87
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
88
+ // Draw the frame
89
+ if (frame.patch) {
90
+ try {
91
+ const imageData = new ImageData(frame.patch, frame.dims.width, frame.dims.height);
92
+ ctx.putImageData(imageData, frame.dims.left, frame.dims.top);
93
+ } catch (err) {
94
+ console.error('Error drawing frame:', err);
95
+ }
96
+ }
97
+ }
98
+ animationRef.current = requestAnimationFrame(animate);
99
+ };
100
+ animationRef.current = requestAnimationFrame(animate);
101
+ };
102
+ loadGif();
103
+ return ()=>{
104
+ isMounted = false;
105
+ if (animationRef.current) {
106
+ cancelAnimationFrame(animationRef.current);
107
+ }
108
+ };
109
+ }, [
110
+ src,
111
+ width,
112
+ height
113
+ ]);
114
+ if (error) {
115
+ // Fallback to regular img tag if GIF parsing fails
116
+ return /*#__PURE__*/ _jsx("img", {
117
+ className: className,
118
+ src: src,
119
+ alt: alt,
120
+ onClick: onClick,
121
+ style: {
122
+ width: width ? `${width}px` : '100%',
123
+ height: height ? `${height}px` : 'auto',
124
+ maxWidth: '100%',
125
+ display: 'block'
126
+ }
127
+ });
128
+ }
129
+ if (isLoading) {
130
+ return /*#__PURE__*/ _jsx("div", {
131
+ className: `flex items-center justify-center bg-gray-100 ${className}`,
132
+ children: /*#__PURE__*/ _jsx("span", {
133
+ className: "text-gray-500 text-sm",
134
+ children: "Loading GIF..."
135
+ })
136
+ });
137
+ }
138
+ return /*#__PURE__*/ _jsx("canvas", {
139
+ ref: canvasRef,
140
+ className: className,
141
+ onClick: onClick,
142
+ style: {
143
+ width: width ? `${width}px` : '100%',
144
+ height: height ? `${height}px` : 'auto',
145
+ maxWidth: '100%',
146
+ display: 'block'
147
+ }
148
+ });
149
+ };
150
+ export default GifPlayer;
151
+
152
+ //# sourceMappingURL=GifPlayer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../src/fields/TiptapEditor/extensions/ImageBlock/components/GifPlayer.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react'\r\nimport { decompressFrames, parseGIF } from 'gifuct-js'\r\n\r\ninterface GifPlayerProps {\r\n src: string\r\n alt?: string\r\n className?: string\r\n onClick?: () => void\r\n width?: number\r\n height?: number\r\n}\r\n\r\nexport const GifPlayer: React.FC<GifPlayerProps> = ({\r\n src,\r\n alt = '',\r\n className = '',\r\n onClick,\r\n width,\r\n height,\r\n}) => {\r\n const canvasRef = useRef<HTMLCanvasElement>(null)\r\n const [isLoading, setIsLoading] = useState(true)\r\n const [error, setError] = useState<string | null>(null)\r\n const animationRef = useRef<number | undefined>(undefined)\r\n const framesRef = useRef<any[]>([])\r\n const currentFrameRef = useRef(0)\r\n const startTimeRef = useRef(0)\r\n\r\n useEffect(() => {\r\n let isMounted = true\r\n\r\n const loadGif = async () => {\r\n try {\r\n setIsLoading(true)\r\n setError(null)\r\n\r\n console.log('GifPlayer: Loading GIF from:', src)\r\n\r\n // Fetch the GIF data\r\n const response = await fetch(src)\r\n if (!response.ok) {\r\n throw new Error(`Failed to fetch GIF: ${response.statusText}`)\r\n }\r\n\r\n const arrayBuffer = await response.arrayBuffer()\r\n console.log('GifPlayer: GIF loaded, size:', arrayBuffer.byteLength)\r\n\r\n // Parse and decompress the GIF\r\n const gif = parseGIF(arrayBuffer)\r\n const frames = decompressFrames(gif, true)\r\n\r\n console.log('GifPlayer: GIF parsed, frames:', frames.length)\r\n\r\n if (!isMounted) return\r\n\r\n framesRef.current = frames\r\n setIsLoading(false)\r\n\r\n // Set canvas dimensions\r\n const canvas = canvasRef.current\r\n if (canvas && frames.length > 0) {\r\n const firstFrame = frames[0]\r\n canvas.width = width || firstFrame.dims.width\r\n canvas.height = height || firstFrame.dims.height\r\n console.log('GifPlayer: Canvas dimensions set:', canvas.width, 'x', canvas.height)\r\n }\r\n\r\n // Start animation\r\n startAnimation()\r\n } catch (err) {\r\n console.error('GifPlayer: Error loading GIF:', err)\r\n if (isMounted) {\r\n setError(err instanceof Error ? err.message : 'Failed to load GIF')\r\n setIsLoading(false)\r\n }\r\n }\r\n }\r\n\r\n const startAnimation = () => {\r\n const canvas = canvasRef.current\r\n if (!canvas || framesRef.current.length === 0) return\r\n\r\n const ctx = canvas.getContext('2d')\r\n if (!ctx) return\r\n\r\n startTimeRef.current = performance.now()\r\n\r\n const animate = (currentTime: number) => {\r\n if (!isMounted) return\r\n\r\n const frames = framesRef.current\r\n if (frames.length === 0) return\r\n\r\n // Calculate which frame to show based on elapsed time\r\n let elapsed = currentTime - startTimeRef.current\r\n let frameIndex = 0\r\n let frameTime = 0\r\n\r\n // Find the current frame based on timing\r\n for (let i = 0; i < frames.length; i++) {\r\n const frame = frames[i]\r\n const delay = frame.delay || 100 // Default 100ms if no delay specified\r\n\r\n if (elapsed < frameTime + delay) {\r\n frameIndex = i\r\n break\r\n }\r\n frameTime += delay\r\n }\r\n\r\n // If we've gone through all frames, restart the loop (infinite loop)\r\n if (elapsed >= frameTime) {\r\n startTimeRef.current = currentTime\r\n frameIndex = 0\r\n elapsed = 0\r\n }\r\n\r\n // Only update if frame changed\r\n if (frameIndex !== currentFrameRef.current) {\r\n currentFrameRef.current = frameIndex\r\n const frame = frames[frameIndex]\r\n\r\n // Clear canvas\r\n ctx.clearRect(0, 0, canvas.width, canvas.height)\r\n\r\n // Draw the frame\r\n if (frame.patch) {\r\n try {\r\n const imageData = new ImageData(frame.patch, frame.dims.width, frame.dims.height)\r\n ctx.putImageData(imageData, frame.dims.left, frame.dims.top)\r\n } catch (err) {\r\n console.error('Error drawing frame:', err)\r\n }\r\n }\r\n }\r\n\r\n animationRef.current = requestAnimationFrame(animate)\r\n }\r\n\r\n animationRef.current = requestAnimationFrame(animate)\r\n }\r\n\r\n loadGif()\r\n\r\n return () => {\r\n isMounted = false\r\n if (animationRef.current) {\r\n cancelAnimationFrame(animationRef.current)\r\n }\r\n }\r\n }, [src, width, height])\r\n\r\n if (error) {\r\n // Fallback to regular img tag if GIF parsing fails\r\n return (\r\n <img\r\n className={className}\r\n src={src}\r\n alt={alt}\r\n onClick={onClick}\r\n style={{\r\n width: width ? `${width}px` : '100%',\r\n height: height ? `${height}px` : 'auto',\r\n maxWidth: '100%',\r\n display: 'block',\r\n }}\r\n />\r\n )\r\n }\r\n\r\n if (isLoading) {\r\n return (\r\n <div className={`flex items-center justify-center bg-gray-100 ${className}`}>\r\n <span className='text-gray-500 text-sm'>Loading GIF...</span>\r\n </div>\r\n )\r\n }\r\n\r\n return (\r\n <canvas\r\n ref={canvasRef}\r\n className={className}\r\n onClick={onClick}\r\n style={{\r\n width: width ? `${width}px` : '100%',\r\n height: height ? `${height}px` : 'auto',\r\n maxWidth: '100%',\r\n display: 'block',\r\n }}\r\n />\r\n )\r\n}\r\n\r\nexport default GifPlayer\r\n"],"names":["React","useEffect","useRef","useState","decompressFrames","parseGIF","GifPlayer","src","alt","className","onClick","width","height","canvasRef","isLoading","setIsLoading","error","setError","animationRef","undefined","framesRef","currentFrameRef","startTimeRef","isMounted","loadGif","console","log","response","fetch","ok","Error","statusText","arrayBuffer","byteLength","gif","frames","length","current","canvas","firstFrame","dims","startAnimation","err","message","ctx","getContext","performance","now","animate","currentTime","elapsed","frameIndex","frameTime","i","frame","delay","clearRect","patch","imageData","ImageData","putImageData","left","top","requestAnimationFrame","cancelAnimationFrame","img","style","maxWidth","display","div","span","ref"],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ interface SmartImageProps {
3
+ src: string;
4
+ alt?: string;
5
+ className?: string;
6
+ onClick?: () => void;
7
+ width?: number;
8
+ height?: number;
9
+ }
10
+ export declare const SmartImage: React.FC<SmartImageProps>;
11
+ export default SmartImage;
12
+ //# sourceMappingURL=SmartImage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SmartImage.d.ts","sourceRoot":"","sources":["../../../../../../../src/fields/TiptapEditor/extensions/ImageBlock/components/SmartImage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAA;AAIvC,UAAU,eAAe;IACvB,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CA2DhD,CAAA;AAED,eAAe,UAAU,CAAA"}
@@ -0,0 +1,55 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React, { useState } from 'react';
3
+ import { GifPlayer } from './GifPlayer.js';
4
+ import { shouldRenderAsGif } from '../utils/gifUtils.js';
5
+ export const SmartImage = ({ src, alt = '', className = '', onClick, width, height })=>{
6
+ const [gifPlayerFailed, setGifPlayerFailed] = useState(false);
7
+ const isGif = shouldRenderAsGif(src);
8
+ // If it's not a GIF or GIF player failed, use regular img
9
+ if (!isGif || gifPlayerFailed) {
10
+ return /*#__PURE__*/ _jsx("img", {
11
+ className: className,
12
+ src: src,
13
+ alt: alt,
14
+ onClick: onClick,
15
+ style: {
16
+ width: width ? `${width}px` : '100%',
17
+ height: height ? `${height}px` : 'auto',
18
+ maxWidth: '100%',
19
+ display: 'block'
20
+ }
21
+ });
22
+ }
23
+ // Try GIF player, with fallback to img if it fails
24
+ return /*#__PURE__*/ _jsxs("div", {
25
+ children: [
26
+ /*#__PURE__*/ _jsx(GifPlayer, {
27
+ src: src,
28
+ alt: alt,
29
+ className: className,
30
+ onClick: onClick,
31
+ width: width,
32
+ height: height
33
+ }),
34
+ /*#__PURE__*/ _jsx("img", {
35
+ className: className,
36
+ src: src,
37
+ alt: alt,
38
+ onClick: onClick,
39
+ style: {
40
+ width: width ? `${width}px` : '100%',
41
+ height: height ? `${height}px` : 'auto',
42
+ maxWidth: '100%',
43
+ display: 'none'
44
+ },
45
+ onError: ()=>{
46
+ console.log('GIF player failed, falling back to img');
47
+ setGifPlayerFailed(true);
48
+ }
49
+ })
50
+ ]
51
+ });
52
+ };
53
+ export default SmartImage;
54
+
55
+ //# sourceMappingURL=SmartImage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../src/fields/TiptapEditor/extensions/ImageBlock/components/SmartImage.tsx"],"sourcesContent":["import React, { useState } from 'react'\r\nimport { GifPlayer } from './GifPlayer.js'\r\nimport { shouldRenderAsGif } from '../utils/gifUtils.js'\r\n\r\ninterface SmartImageProps {\r\n src: string\r\n alt?: string\r\n className?: string\r\n onClick?: () => void\r\n width?: number\r\n height?: number\r\n}\r\n\r\nexport const SmartImage: React.FC<SmartImageProps> = ({\r\n src,\r\n alt = '',\r\n className = '',\r\n onClick,\r\n width,\r\n height,\r\n}) => {\r\n const [gifPlayerFailed, setGifPlayerFailed] = useState(false)\r\n const isGif = shouldRenderAsGif(src)\r\n\r\n // If it's not a GIF or GIF player failed, use regular img\r\n if (!isGif || gifPlayerFailed) {\r\n return (\r\n <img\r\n className={className}\r\n src={src}\r\n alt={alt}\r\n onClick={onClick}\r\n style={{\r\n width: width ? `${width}px` : '100%',\r\n height: height ? `${height}px` : 'auto',\r\n maxWidth: '100%',\r\n display: 'block',\r\n }}\r\n />\r\n )\r\n }\r\n\r\n // Try GIF player, with fallback to img if it fails\r\n return (\r\n <div>\r\n <GifPlayer\r\n src={src}\r\n alt={alt}\r\n className={className}\r\n onClick={onClick}\r\n width={width}\r\n height={height}\r\n />\r\n {/* Hidden fallback img that will show if GIF player fails */}\r\n <img\r\n className={className}\r\n src={src}\r\n alt={alt}\r\n onClick={onClick}\r\n style={{\r\n width: width ? `${width}px` : '100%',\r\n height: height ? `${height}px` : 'auto',\r\n maxWidth: '100%',\r\n display: 'none', // Hidden by default\r\n }}\r\n onError={() => {\r\n console.log('GIF player failed, falling back to img')\r\n setGifPlayerFailed(true)\r\n }}\r\n />\r\n </div>\r\n )\r\n}\r\n\r\nexport default SmartImage\r\n"],"names":["React","useState","GifPlayer","shouldRenderAsGif","SmartImage","src","alt","className","onClick","width","height","gifPlayerFailed","setGifPlayerFailed","isGif","img","style","maxWidth","display","div","onError","console","log"],"mappings":";AAAA,OAAOA,SAASC,QAAQ,QAAQ,QAAO;AACvC,SAASC,SAAS,QAAQ,iBAAgB;AAC1C,SAASC,iBAAiB,QAAQ,uBAAsB;AAWxD,OAAO,MAAMC,aAAwC,CAAC,EACpDC,GAAG,EACHC,MAAM,EAAE,EACRC,YAAY,EAAE,EACdC,OAAO,EACPC,KAAK,EACLC,MAAM,EACP;IACC,MAAM,CAACC,iBAAiBC,mBAAmB,GAAGX,SAAS;IACvD,MAAMY,QAAQV,kBAAkBE;IAEhC,0DAA0D;IAC1D,IAAI,CAACQ,SAASF,iBAAiB;QAC7B,qBACE,KAACG;YACCP,WAAWA;YACXF,KAAKA;YACLC,KAAKA;YACLE,SAASA;YACTO,OAAO;gBACLN,OAAOA,QAAQ,GAAGA,MAAM,EAAE,CAAC,GAAG;gBAC9BC,QAAQA,SAAS,GAAGA,OAAO,EAAE,CAAC,GAAG;gBACjCM,UAAU;gBACVC,SAAS;YACX;;IAGN;IAEA,mDAAmD;IACnD,qBACE,MAACC;;0BACC,KAAChB;gBACCG,KAAKA;gBACLC,KAAKA;gBACLC,WAAWA;gBACXC,SAASA;gBACTC,OAAOA;gBACPC,QAAQA;;0BAGV,KAACI;gBACCP,WAAWA;gBACXF,KAAKA;gBACLC,KAAKA;gBACLE,SAASA;gBACTO,OAAO;oBACLN,OAAOA,QAAQ,GAAGA,MAAM,EAAE,CAAC,GAAG;oBAC9BC,QAAQA,SAAS,GAAGA,OAAO,EAAE,CAAC,GAAG;oBACjCM,UAAU;oBACVC,SAAS;gBACX;gBACAE,SAAS;oBACPC,QAAQC,GAAG,CAAC;oBACZT,mBAAmB;gBACrB;;;;AAIR,EAAC;AAED,eAAeR,WAAU"}
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ export declare const TestImage: React.FC;
3
+ export default TestImage;
4
+ //# sourceMappingURL=TestImage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TestImage.d.ts","sourceRoot":"","sources":["../../../../../../../src/fields/TiptapEditor/extensions/ImageBlock/components/TestImage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAY7B,CAAA;AAED,eAAe,SAAS,CAAA"}
@@ -0,0 +1,26 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React from 'react';
3
+ export const TestImage = ()=>{
4
+ return /*#__PURE__*/ _jsxs("div", {
5
+ children: [
6
+ /*#__PURE__*/ _jsx("h3", {
7
+ children: "Test Image Component"
8
+ }),
9
+ /*#__PURE__*/ _jsx("img", {
10
+ src: "https://via.placeholder.com/300x200/0000FF/FFFFFF?text=Test+Image",
11
+ alt: "Test Image",
12
+ style: {
13
+ width: '300px',
14
+ height: '200px',
15
+ border: '1px solid #ccc'
16
+ }
17
+ }),
18
+ /*#__PURE__*/ _jsx("p", {
19
+ children: "If you can see this image, the basic image functionality is working."
20
+ })
21
+ ]
22
+ });
23
+ };
24
+ export default TestImage;
25
+
26
+ //# sourceMappingURL=TestImage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../src/fields/TiptapEditor/extensions/ImageBlock/components/TestImage.tsx"],"sourcesContent":["import React from 'react'\r\n\r\nexport const TestImage: React.FC = () => {\r\n return (\r\n <div>\r\n <h3>Test Image Component</h3>\r\n <img\r\n src='https://via.placeholder.com/300x200/0000FF/FFFFFF?text=Test+Image'\r\n alt='Test Image'\r\n style={{ width: '300px', height: '200px', border: '1px solid #ccc' }}\r\n />\r\n <p>If you can see this image, the basic image functionality is working.</p>\r\n </div>\r\n )\r\n}\r\n\r\nexport default TestImage\r\n"],"names":["React","TestImage","div","h3","img","src","alt","style","width","height","border","p"],"mappings":";AAAA,OAAOA,WAAW,QAAO;AAEzB,OAAO,MAAMC,YAAsB;IACjC,qBACE,MAACC;;0BACC,KAACC;0BAAG;;0BACJ,KAACC;gBACCC,KAAI;gBACJC,KAAI;gBACJC,OAAO;oBAAEC,OAAO;oBAASC,QAAQ;oBAASC,QAAQ;gBAAiB;;0BAErE,KAACC;0BAAE;;;;AAGT,EAAC;AAED,eAAeV,UAAS"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Utility functions for GIF handling
3
+ */
4
+ /**
5
+ * Checks if a URL or file path points to a GIF file
6
+ * @param src - The source URL or file path
7
+ * @returns true if the source is a GIF file
8
+ */
9
+ export declare const isGifFile: (src: string) => boolean;
10
+ /**
11
+ * Checks if a URL is a data URL containing a GIF
12
+ * @param src - The source URL
13
+ * @returns true if the source is a data URL with GIF data
14
+ */
15
+ export declare const isGifDataUrl: (src: string) => boolean;
16
+ /**
17
+ * Determines if an image source should be rendered as a GIF
18
+ * @param src - The image source URL
19
+ * @returns true if the source should be rendered as a GIF
20
+ */
21
+ export declare const shouldRenderAsGif: (src: string) => boolean;
22
+ /**
23
+ * Extracts dimensions from a GIF source for proper canvas sizing
24
+ * @param src - The GIF source URL
25
+ * @returns Promise resolving to width and height, or null if extraction fails
26
+ */
27
+ export declare const getGifDimensions: (src: string) => Promise<{
28
+ width: number;
29
+ height: number;
30
+ } | null>;
31
+ //# sourceMappingURL=gifUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gifUtils.d.ts","sourceRoot":"","sources":["../../../../../../../src/fields/TiptapEditor/extensions/ImageBlock/utils/gifUtils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;GAIG;AACH,eAAO,MAAM,SAAS,QAAS,MAAM,KAAG,OAgBvC,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY,QAAS,MAAM,KAAG,OAK1C,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,QAAS,MAAM,KAAG,OAE/C,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,QACtB,MAAM,KACV,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAoBlD,CAAA"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Utility functions for GIF handling
3
+ */ /**
4
+ * Checks if a URL or file path points to a GIF file
5
+ * @param src - The source URL or file path
6
+ * @returns true if the source is a GIF file
7
+ */ export const isGifFile = (src)=>{
8
+ if (!src) return false;
9
+ // Check file extension
10
+ const extension = src.toLowerCase().split('.').pop();
11
+ if (extension === 'gif') {
12
+ return true;
13
+ }
14
+ // Check for GIF in URL path (even without extension)
15
+ const urlPath = src.toLowerCase();
16
+ if (urlPath.includes('.gif') || urlPath.includes('gif')) {
17
+ return true;
18
+ }
19
+ return false;
20
+ };
21
+ /**
22
+ * Checks if a URL is a data URL containing a GIF
23
+ * @param src - The source URL
24
+ * @returns true if the source is a data URL with GIF data
25
+ */ export const isGifDataUrl = (src)=>{
26
+ if (!src || !src.startsWith('data:')) return false;
27
+ // Check for GIF MIME type in data URL
28
+ return src.includes('data:image/gif') || src.includes('image/gif');
29
+ };
30
+ /**
31
+ * Determines if an image source should be rendered as a GIF
32
+ * @param src - The image source URL
33
+ * @returns true if the source should be rendered as a GIF
34
+ */ export const shouldRenderAsGif = (src)=>{
35
+ return isGifFile(src) || isGifDataUrl(src);
36
+ };
37
+ /**
38
+ * Extracts dimensions from a GIF source for proper canvas sizing
39
+ * @param src - The GIF source URL
40
+ * @returns Promise resolving to width and height, or null if extraction fails
41
+ */ export const getGifDimensions = async (src)=>{
42
+ try {
43
+ const response = await fetch(src);
44
+ if (!response.ok) return null;
45
+ const arrayBuffer = await response.arrayBuffer();
46
+ const uint8Array = new Uint8Array(arrayBuffer);
47
+ // Parse GIF header to get dimensions
48
+ if (uint8Array.length < 10) return null;
49
+ // GIF header: 6 bytes signature + 2 bytes width + 2 bytes height
50
+ const width = uint8Array[6] | uint8Array[7] << 8;
51
+ const height = uint8Array[8] | uint8Array[9] << 8;
52
+ return {
53
+ width,
54
+ height
55
+ };
56
+ } catch (error) {
57
+ console.warn('Failed to extract GIF dimensions:', error);
58
+ return null;
59
+ }
60
+ };
61
+
62
+ //# sourceMappingURL=gifUtils.js.map