@edifice.io/tiptap-extensions 2.6.10-develop-pedago.20261022145938 → 2.6.10-develop.20261023111140

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 (43) hide show
  1. package/README.md +13 -104
  2. package/dist/conversation-history/conversation-history.cjs +1 -1
  3. package/dist/conversation-history/conversation-history.cjs.map +1 -1
  4. package/dist/conversation-history/conversation-history.js +1 -1
  5. package/dist/conversation-history/conversation-history.js.map +1 -1
  6. package/dist/heading/heading.cjs +1 -1
  7. package/dist/heading/heading.cjs.map +1 -1
  8. package/dist/heading/heading.js +0 -6
  9. package/dist/heading/heading.js.map +1 -1
  10. package/dist/image/image.cjs +1 -1
  11. package/dist/image/image.cjs.map +1 -1
  12. package/dist/image/image.d.ts +7 -0
  13. package/dist/image/image.js +8 -6
  14. package/dist/image/image.js.map +1 -1
  15. package/dist/linker/linker.cjs +1 -1
  16. package/dist/linker/linker.cjs.map +1 -1
  17. package/dist/linker/linker.js +1 -0
  18. package/dist/linker/linker.js.map +1 -1
  19. package/dist/table-cell/table-cell.cjs +1 -1
  20. package/dist/table-cell/table-cell.cjs.map +1 -1
  21. package/dist/table-cell/table-cell.d.ts +1 -1
  22. package/dist/table-cell/table-cell.js +1 -1
  23. package/dist/table-cell/table-cell.js.map +1 -1
  24. package/package.json +34 -55
  25. package/dist/abbr/abbr.spec.d.ts +0 -1
  26. package/dist/alert/alert.spec.d.ts +0 -1
  27. package/dist/attachment/attachment.spec.d.ts +0 -1
  28. package/dist/audio/audio.spec.d.ts +0 -1
  29. package/dist/conversation-history/conversation-history.spec.d.ts +0 -1
  30. package/dist/conversation-history-body/conversation-history-body.spec.d.ts +0 -1
  31. package/dist/font-size/font-size.spec.d.ts +0 -1
  32. package/dist/heading/heading.spec.d.ts +0 -1
  33. package/dist/highlight/highlight.spec.d.ts +0 -1
  34. package/dist/hyperlink/hyperlink.spec.d.ts +0 -1
  35. package/dist/iframe/iframe.spec.d.ts +0 -1
  36. package/dist/image/image.spec.d.ts +0 -1
  37. package/dist/information-pane/information-pane.spec.d.ts +0 -1
  38. package/dist/line-height/line-height.spec.d.ts +0 -1
  39. package/dist/linker/linker.spec.d.ts +0 -1
  40. package/dist/mathjax/mathjax.spec.d.ts +0 -1
  41. package/dist/paragraph/paragraph.spec.d.ts +0 -1
  42. package/dist/table-cell/table-cell.spec.d.ts +0 -1
  43. package/dist/video/video.spec.d.ts +0 -1
package/README.md CHANGED
@@ -3,16 +3,16 @@
3
3
  ![npm](https://img.shields.io/npm/v/@edifice.io/tiptap-extensions?style=flat-square)
4
4
  ![bundlephobia](https://img.shields.io/bundlephobia/min/@edifice.io/tiptap-extensions?style=flat-square)
5
5
 
6
- Extensions basées sur [Tiptap Editor](https://tiptap.dev/). Étend les fonctionnalités de l'éditeur.
6
+ Extensions based on [Tiptap Editor](https://tiptap.dev/). Extends functionalities of the editor.
7
7
 
8
- ## Prérequis
8
+ ## Prerequisites
9
9
 
10
10
  - `pnpm: >= 9`
11
11
  - `node: >= 20`
12
12
 
13
- ## Démarrage
13
+ ## Getting Started
14
14
 
15
- ### Installation
15
+ ### Install
16
16
 
17
17
  ```bash
18
18
  pnpm add @edifice.io/tiptap-extensions
@@ -26,114 +26,23 @@ pnpm add @edifice.io/tiptap-extensions
26
26
  import { Alert, Video } from "@edifice.io/tiptap-extensions"
27
27
  ```
28
28
 
29
- #### Imports ciblés
29
+ #### Sub-imports
30
30
 
31
31
  ```bash
32
32
  import { Alert } from "@edifice.io/tiptap-extensions/alert"
33
33
  ```
34
34
 
35
- ## Tests
36
-
37
- Chaque extension est testée contre les formes HTML réelles qu'elle doit parser et rendre — format
38
- actuel et formats legacy quand c'est pertinent — en utilisant `generateJSON`/`generateHTML` de
39
- `@tiptap/core` (les mêmes fonctions que `src/transform/` expose en production) sous `jsdom`, qui se
40
- comporte comme un vrai navigateur. Les tests sont colocalisés avec leur extension :
41
- `src/<nom>/<nom>.spec.ts`.
42
-
43
- Pour chaque extension, quand c'est pertinent :
44
-
45
- 1. **HTML → JSON** : la ou les formes HTML réelles (actuelle et legacy) se parsent dans le bon type de
46
- nœud/mark avec les bons attributs.
47
- 2. **JSON → HTML** : le rendu d'un document stocké produit le HTML attendu.
48
-
49
- Contrairement à la suite golden-fixture d'`edifice-tiptap-transformer` (qui fige un snapshot JSON v2
50
- externe pour comparer), chaque test ici écrit son HTML/JSON attendu directement en dur dans le fichier :
51
- il n'y a pas de "snapshot v2 navigateur" préexistant à comparer, et tester une extension isolément
52
- (pas 20 combinées) rend une assertion écrite à la main à la fois fiable et facile à lire.
53
-
54
- Un smoke test séparé, `packages/react/src/modules/editor/hooks/useTipTapEditor.spec.tsx`, combine un
55
- exemple de chaque extension réellement branchée dans l'éditeur réel (un "kitchen sink", sur le même
56
- principe que celui du backend) — c'est lui qui attrape les interactions *entre* extensions (ex. un nom
57
- dupliqué entre deux kits) qu'un test par extension isolée ne peut pas voir.
58
-
59
- ### Extensions couvertes
60
-
61
- | Extension | Ce qui est testé |
62
- |---|---|
63
- | `heading`, `hyperlink` | ne sont pas masquées par les `heading`/`link` que StarterKit v3 embarque désormais par défaut |
64
- | `linker` | distinction avec un lien simple via `data-id`+`data-app-prefix` ; sanitization du `href` `javascript:` ; également masqué par le `link` de StarterKit si non désactivé |
65
- | `paragraph` | forme legacy `div[style]:has(> span)` *(exportée, non branchée dans l'éditeur actuellement)* |
66
- | `alert` | balises legacy `p.info`/`div.warning`/`div.info` |
67
- | `highlight` (CustomHighlight) | style `background-color` → attribut `color` |
68
- | `abbr` | mark `<abbr>` |
69
- | `mathjax` | extraction/rendu de l'équation *(exportée pour le contenu legacy ; l'éditeur réel utilise `@tiptap/extension-mathematics` à la place)* |
70
- | `image` (custom-image) | largeur héritée du conteneur legacy `.image-container`, détection "smiley" legacy, attributs standards, URI `data:` ignorées |
71
- | `video` | coercion de `controls` (attribut nu vs chaîne `"true"` vs absent), indicateur de captation |
72
- | `audio` | `src`/`documentId`, balisage du conteneur |
73
- | `iframe` | `width: "100%"` conservé tel quel vs une largeur numérique convertie en nombre, défaut d'`allowfullscreen` |
74
- | `information-pane` | `type` via `data-type`, défaut `info` |
75
- | `attachment` | parse les `<a>` enfants en `links[]`, retombe sur le dernier segment du `href` pour l'identifiant du document |
76
- | `conversation-history` | le plugin ProseMirror qui regroupe tout ce qui suit un `<hr>` (nécessite une vraie instance `Editor`/transaction, pas juste `generateJSON` — le `content` initial seul ne le déclenche pas) |
77
- | `conversation-history-body` | parse/rendu simple |
78
- | `font-size`, `line-height`, `table-cell` | comportement actuel, **y compris** le défaut préexistant `""` au lieu de `null` pour une valeur non définie (même cause racine que `StyleCompat.ts` côté backend, non introduite par cette migration, non corrigée ici — voir le commentaire de chaque spec) |
79
-
80
- `line-height` est exportée mais non branchée actuellement dans `useTipTapEditor.ts`.
81
-
82
- **Volontairement non couvertes** : `speech-recognition` et `speech-synthesis` n'ont aucune logique
83
- `parseHTML`/`renderHTML` — elles ne font que piloter les API navigateur `SpeechRecognition`/
84
- `speechSynthesis` et n'ont aucun effet sur le contenu du document, donc hors du périmètre de cette suite
85
- de sérialisation de contenu. `attachment-transformer.ts` (`AttachmentTransformer`) est backend-only —
86
- l'éditeur réel utilise `Attachment` d'`attachment.ts` (confirmé via `AttachmentNodeView.tsx`).
87
-
88
- ### Ajouter un test pour une nouvelle extension
89
-
90
- 1. Créer `src/<nom>/<nom>.spec.ts` à côté de l'extension.
91
- 2. Écrire le HTML que le `parseHTML` de l'extension est censé reconnaître (format actuel, et tout
92
- format legacy encore supporté), et vérifier le type de nœud/mark et les attributs obtenus avec
93
- `generateJSON`.
94
- 3. Si l'extension produit un rendu non trivial, vérifier que `generateHTML` sur un JSON écrit à la main
95
- produit le HTML attendu.
96
- 4. Si l'extension est branchée dans `useTipTapEditor.ts`, ajouter un court exemple représentatif au
97
- contenu kitchen-sink de `useTipTapEditor.spec.tsx` aussi.
98
-
99
- ### Lancer les tests
35
+ ## New extension
100
36
 
101
- ```bash
102
- pnpm --filter @edifice.io/react test
103
- pnpm --filter @edifice.io/tiptap-extensions test
104
- ```
105
-
106
- ## Régressions de la migration v2 → v3
107
-
108
- Le passage à TipTap v3 a introduit plusieurs régressions dans `packages/extensions` et
109
- `packages/react` (l'éditeur réel), toutes trouvées grâce à la suite de tests ci-dessus et
110
- corrigées. Listées ici pour référence — chaque fichier porte un commentaire court expliquant le
111
- bug précis.
112
-
113
- | Régression | Corrigé dans |
114
- |---|---|
115
- | Import brut `prosemirror-state` au lieu de `@tiptap/pm/state` — risque une seconde instance ProseMirror incompatible | `src/image/image.ts`, `src/conversation-history/conversation-history.ts` |
116
- | `@tiptap/extension-table-header`/`-row` n'existent plus en paquets séparés en v3 (fusionnés dans `@tiptap/extension-table`) | `packages/react/.../test-utils/createTestEditor.ts` |
117
- | `StarterKit` nu entre en collision avec son `heading`/`underline`/`link` embarqués par défaut en v3, masquant nos extensions custom | `useTipTapEditor.ts`, `useCommentEditor.ts`, `createTestEditor.ts`, `EditorToolbar.spec.tsx` |
118
- | `TextStyleKit` nu entre en collision avec les `Color`/`FontFamily`/`FontSize` ajoutés séparément | `useTipTapEditor.ts` |
119
- | L'extension undo/redo de StarterKit a été renommée de `history` à `undoRedo` en v3 — `hasExtension('history', ...)` renvoyait toujours faux | `EditorToolbar.tsx` |
120
- | `TextStyle` de `@tiptap/extension-text-style` a perdu son export par défaut en v3 | plusieurs `EditorToolbar.*.spec.tsx`, `has-text-style.spec.ts` |
121
- | `FloatingMenu`/`BubbleMenu` ont déménagé de `@tiptap/react` vers `@tiptap/react/menus` | `TableToolbar.spec.tsx`, `LinkToolbar.spec.tsx`, `BubbleMenuEditImage.spec.tsx`, `BubbleMenuEditInformationPane.spec.tsx` |
122
- | `setContent` émet désormais `'update'` par défaut (pas en v2), déclenchant `onContentChange` sur une synchronisation programmatique, pas seulement sur une vraie édition | `useTipTapEditor.ts` |
123
- | Le bouton fusionner/scinder de `TableToolbar` restait périmé sur un simple déplacement de sélection : le hook partagé `useEditorState` n'écoutait que `'update'` (changements de contenu), pas les changements de sélection | `useEditorState.ts`, `TableToolbar.tsx` |
124
- | Propriété `keepOnSplit` morte sur une config de `Node` (valide uniquement sur les `Mark`) — inoffensif mais faisait échouer `tsc` | `src/linker/linker.ts` |
125
-
126
- ## Nouvelle extension
127
-
128
- Pour créer une nouvelle extension, procéder comme suit :
37
+ To create a new extension, please do as follow :
129
38
 
130
- - Créer un sous-dossier dans `src` avec le nom de l'extension (ex : `my-extension`)
39
+ - Create a subfolder in `src` with the name of the extension (e.g: `my-extension`)
131
40
 
132
41
  ```
133
42
  my-extension
134
43
  ```
135
44
 
136
- - Créer deux fichiers dans ce nouveau dossier :
45
+ - Create two files inside the new folder:
137
46
  - `index.ts`
138
47
  - `my-extension.ts`
139
48
 
@@ -143,8 +52,8 @@ my-extension
143
52
  └── index.ts
144
53
  ```
145
54
 
146
- - Consulter une extension existante ou se référer à la [documentation officielle](https://tiptap.dev/docs/editor/extensions/custom-extensions) pour développer une extension.
147
- - Ajouter ensuite l'extension dans les sub-exports du `package.json`, par ordre alphabétique.
55
+ - Check one existing extension or refer to the official [documentation](https://tiptap.dev/docs/editor/extensions/custom-extensions) to develop an extension.
56
+ - Then, add your extension in the `package.json` sub-exports in alphabetical order.
148
57
 
149
58
  ```
150
59
  "./my-extension": {
@@ -153,5 +62,5 @@ my-extension
153
62
  }
154
63
  ```
155
64
 
156
- - Lancer `pnpm run build` pour générer un bundle
157
- - Ajouter des tests avant de committer et pousser sur le dépôt distant — voir "Tests" ci-dessus
65
+ - Run `pnpm run build` to generate a bundle
66
+ - Test your extension before committing and pushing to remote
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const core=require("@tiptap/core"),state=require("@tiptap/pm/state"),ConversationHistory=core.Node.create({name:"converstationHistory",group:"block",content:"block+",parseHTML(){return[{tag:"div.conversation-history"}]},renderHTML({HTMLAttributes}){return["div",core.mergeAttributes(HTMLAttributes,{class:"conversation-history"}),0]},addProseMirrorPlugins(){return[new state.Plugin({appendTransaction:(transactions,oldState,newState)=>{const tr=newState.tr;let modified=!1;const nodesAfterHr=[];return newState.doc.descendants((node,pos,parent)=>{if(node.type.name==="horizontalRule"&&parent.type.name==="doc"){const start=pos,end=newState.doc.content.size;if(newState.doc.nodesBetween(start,end,(n,p,parent2)=>{if(n.type.name!=="horizontalRule"&&parent2.type.name==="doc")nodesAfterHr.push({node:n,pos:p});else return!1}),nodesAfterHr.length>0){const groupNode=this.type.create({},nodesAfterHr.map(n=>n.node));tr.replaceWith(start,end,groupNode),modified=!0}return!1}}),modified?tr:null}})]}});exports.ConversationHistory=ConversationHistory;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const core=require("@tiptap/core"),prosemirrorState=require("prosemirror-state"),ConversationHistory=core.Node.create({name:"converstationHistory",group:"block",content:"block+",parseHTML(){return[{tag:"div.conversation-history"}]},renderHTML({HTMLAttributes}){return["div",core.mergeAttributes(HTMLAttributes,{class:"conversation-history"}),0]},addProseMirrorPlugins(){return[new prosemirrorState.Plugin({appendTransaction:(transactions,oldState,newState)=>{const tr=newState.tr;let modified=!1;const nodesAfterHr=[];return newState.doc.descendants((node,pos,parent)=>{if(node.type.name==="horizontalRule"&&parent.type.name==="doc"){const start=pos,end=newState.doc.content.size;if(newState.doc.nodesBetween(start,end,(n,p,parent2)=>{if(n.type.name!=="horizontalRule"&&parent2.type.name==="doc")nodesAfterHr.push({node:n,pos:p});else return!1}),nodesAfterHr.length>0){const groupNode=this.type.create({},nodesAfterHr.map(n=>n.node));tr.replaceWith(start,end,groupNode),modified=!0}return!1}}),modified?tr:null}})]}});exports.ConversationHistory=ConversationHistory;
2
2
  //# sourceMappingURL=conversation-history.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"conversation-history.cjs","sources":["../../src/conversation-history/conversation-history.ts"],"sourcesContent":["/**\n * A Tiptap Node extension that creates a conversation history container.\n * This extension groups content blocks that appear after a horizontal rule\n * into a conversation history section.\n *\n * @extends Node\n *\n * @remarks\n * The node is rendered as a div element with the class 'conversation-history'.\n * It can parse HTML elements that match the same structure.\n *\n * For retrocompatibility, this extension also includes a ProseMirror plugin\n * that handles the grouping all the content after an horizontal rules into the\n * conversation-history children block.\n *\n * Usage:\n * ```\n * // Add to your Tiptap editor extensions\n * import { ConversationHistory } from './conversation-history'\n *\n * new Editor({\n * extensions: [\n * ConversationHistory,\n * // ... other extensions\n * ],\n * })\n * ```\n */\nimport { mergeAttributes, Node } from '@tiptap/core';\nimport { Plugin } from '@tiptap/pm/state';\n\nexport const ConversationHistory = Node.create({\n name: 'converstationHistory',\n group: 'block',\n content: 'block+',\n\n parseHTML() {\n return [\n {\n tag: 'div.conversation-history',\n },\n ];\n },\n\n renderHTML({ HTMLAttributes }) {\n return [\n 'div',\n mergeAttributes(HTMLAttributes, { class: 'conversation-history' }),\n 0,\n ];\n },\n\n /**\n * Adds custom ProseMirror plugins to the editor.\n * When a horizontal rule is encountered, this plugin collects all nodes\n * following the horizontal rule until the end of the document.\n * These nodes are then grouped together and replaced with\n * a single node of the same type as the plugin's type.\n *\n * @returns {Plugin[]} An array of ProseMirror plugins.\n */\n addProseMirrorPlugins() {\n return [\n new Plugin({\n appendTransaction: (transactions, oldState, newState) => {\n const tr = newState.tr;\n let modified = false;\n const nodesAfterHr = [];\n\n newState.doc.descendants((node, pos, parent) => {\n if (\n node.type.name === 'horizontalRule' &&\n parent.type.name === 'doc'\n ) {\n const start = pos;\n const end = newState.doc.content.size;\n\n newState.doc.nodesBetween(start, end, (n, p, parent) => {\n if (\n n.type.name !== 'horizontalRule' &&\n parent.type.name === 'doc'\n ) {\n nodesAfterHr.push({ node: n, pos: p });\n } else {\n return false;\n }\n });\n\n if (nodesAfterHr.length > 0) {\n const groupNode = this.type.create(\n {},\n nodesAfterHr.map((n) => n.node),\n );\n tr.replaceWith(start, end, groupNode);\n modified = true;\n }\n return false;\n }\n });\n\n return modified ? tr : null;\n },\n }),\n ];\n },\n});\n"],"names":["Node","mergeAttributes","Plugin","parent"],"mappings":"qJA+Ba,oBAAsBA,KAAAA,KAAK,OAAO,CAC7C,KAAM,uBACN,MAAO,QACP,QAAS,SAET,WAAY,CACV,MAAO,CACL,CACE,IAAK,0BAAA,CACP,CAEJ,EAEA,WAAW,CAAE,gBAAkB,CAC7B,MAAO,CACL,MACAC,KAAAA,gBAAgB,eAAgB,CAAE,MAAO,uBAAwB,EACjE,CAAA,CAEJ,EAWA,uBAAwB,CACtB,MAAO,CACL,IAAIC,aAAO,CACT,kBAAmB,CAAC,aAAc,SAAU,WAAa,CACvD,MAAM,GAAK,SAAS,GACpB,IAAI,SAAW,GACf,MAAM,aAAe,CAAA,EAErB,gBAAS,IAAI,YAAY,CAAC,KAAM,IAAK,SAAW,CAC9C,GACE,KAAK,KAAK,OAAS,kBACnB,OAAO,KAAK,OAAS,MACrB,CACA,MAAM,MAAQ,IACR,IAAM,SAAS,IAAI,QAAQ,KAajC,GAXA,SAAS,IAAI,aAAa,MAAO,IAAK,CAAC,EAAG,EAAGC,UAAW,CACtD,GACE,EAAE,KAAK,OAAS,kBAChBA,QAAO,KAAK,OAAS,MAErB,aAAa,KAAK,CAAE,KAAM,EAAG,IAAK,EAAG,MAErC,OAAO,EAEX,CAAC,EAEG,aAAa,OAAS,EAAG,CAC3B,MAAM,UAAY,KAAK,KAAK,OAC1B,CAAA,EACA,aAAa,IAAK,GAAM,EAAE,IAAI,CAAA,EAEhC,GAAG,YAAY,MAAO,IAAK,SAAS,EACpC,SAAW,EACb,CACA,MAAO,EACT,CACF,CAAC,EAEM,SAAW,GAAK,IACzB,CAAA,CACD,CAAA,CAEL,CACF,CAAC"}
1
+ {"version":3,"file":"conversation-history.cjs","sources":["../../src/conversation-history/conversation-history.ts"],"sourcesContent":["/**\n * A Tiptap Node extension that creates a conversation history container.\n * This extension groups content blocks that appear after a horizontal rule\n * into a conversation history section.\n *\n * @extends Node\n *\n * @remarks\n * The node is rendered as a div element with the class 'conversation-history'.\n * It can parse HTML elements that match the same structure.\n *\n * For retrocompatibility, this extension also includes a ProseMirror plugin\n * that handles the grouping all the content after an horizontal rules into the\n * conversation-history children block.\n *\n * Usage:\n * ```\n * // Add to your Tiptap editor extensions\n * import { ConversationHistory } from './conversation-history'\n *\n * new Editor({\n * extensions: [\n * ConversationHistory,\n * // ... other extensions\n * ],\n * })\n * ```\n */\nimport { mergeAttributes, Node } from '@tiptap/core';\nimport { Plugin } from 'prosemirror-state';\n\nexport const ConversationHistory = Node.create({\n name: 'converstationHistory',\n group: 'block',\n content: 'block+',\n\n parseHTML() {\n return [\n {\n tag: 'div.conversation-history',\n },\n ];\n },\n\n renderHTML({ HTMLAttributes }) {\n return [\n 'div',\n mergeAttributes(HTMLAttributes, { class: 'conversation-history' }),\n 0,\n ];\n },\n\n /**\n * Adds custom ProseMirror plugins to the editor.\n * When a horizontal rule is encountered, this plugin collects all nodes\n * following the horizontal rule until the end of the document.\n * These nodes are then grouped together and replaced with\n * a single node of the same type as the plugin's type.\n *\n * @returns {Plugin[]} An array of ProseMirror plugins.\n */\n addProseMirrorPlugins() {\n return [\n new Plugin({\n appendTransaction: (transactions, oldState, newState) => {\n const tr = newState.tr;\n let modified = false;\n const nodesAfterHr = [];\n\n newState.doc.descendants((node, pos, parent) => {\n if (\n node.type.name === 'horizontalRule' &&\n parent.type.name === 'doc'\n ) {\n const start = pos;\n const end = newState.doc.content.size;\n\n newState.doc.nodesBetween(start, end, (n, p, parent) => {\n if (\n n.type.name !== 'horizontalRule' &&\n parent.type.name === 'doc'\n ) {\n nodesAfterHr.push({ node: n, pos: p });\n } else {\n return false;\n }\n });\n\n if (nodesAfterHr.length > 0) {\n const groupNode = this.type.create(\n {},\n nodesAfterHr.map((n) => n.node),\n );\n tr.replaceWith(start, end, groupNode);\n modified = true;\n }\n return false;\n }\n });\n\n return modified ? tr : null;\n },\n }),\n ];\n },\n});\n"],"names":["Node","mergeAttributes","Plugin","parent"],"mappings":"iKA+Ba,oBAAsBA,KAAAA,KAAK,OAAO,CAC7C,KAAM,uBACN,MAAO,QACP,QAAS,SAET,WAAY,CACV,MAAO,CACL,CACE,IAAK,0BAAA,CACP,CAEJ,EAEA,WAAW,CAAE,gBAAkB,CAC7B,MAAO,CACL,MACAC,KAAAA,gBAAgB,eAAgB,CAAE,MAAO,uBAAwB,EACjE,CAAA,CAEJ,EAWA,uBAAwB,CACtB,MAAO,CACL,IAAIC,wBAAO,CACT,kBAAmB,CAAC,aAAc,SAAU,WAAa,CACvD,MAAM,GAAK,SAAS,GACpB,IAAI,SAAW,GACf,MAAM,aAAe,CAAA,EAErB,gBAAS,IAAI,YAAY,CAAC,KAAM,IAAK,SAAW,CAC9C,GACE,KAAK,KAAK,OAAS,kBACnB,OAAO,KAAK,OAAS,MACrB,CACA,MAAM,MAAQ,IACR,IAAM,SAAS,IAAI,QAAQ,KAajC,GAXA,SAAS,IAAI,aAAa,MAAO,IAAK,CAAC,EAAG,EAAGC,UAAW,CACtD,GACE,EAAE,KAAK,OAAS,kBAChBA,QAAO,KAAK,OAAS,MAErB,aAAa,KAAK,CAAE,KAAM,EAAG,IAAK,EAAG,MAErC,OAAO,EAEX,CAAC,EAEG,aAAa,OAAS,EAAG,CAC3B,MAAM,UAAY,KAAK,KAAK,OAC1B,CAAA,EACA,aAAa,IAAK,GAAM,EAAE,IAAI,CAAA,EAEhC,GAAG,YAAY,MAAO,IAAK,SAAS,EACpC,SAAW,EACb,CACA,MAAO,EACT,CACF,CAAC,EAEM,SAAW,GAAK,IACzB,CAAA,CACD,CAAA,CAEL,CACF,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { Node, mergeAttributes } from "@tiptap/core";
2
- import { Plugin } from "@tiptap/pm/state";
2
+ import { Plugin } from "prosemirror-state";
3
3
  const ConversationHistory = Node.create({
4
4
  name: "converstationHistory",
5
5
  group: "block",
@@ -1 +1 @@
1
- {"version":3,"file":"conversation-history.js","sources":["../../src/conversation-history/conversation-history.ts"],"sourcesContent":["/**\n * A Tiptap Node extension that creates a conversation history container.\n * This extension groups content blocks that appear after a horizontal rule\n * into a conversation history section.\n *\n * @extends Node\n *\n * @remarks\n * The node is rendered as a div element with the class 'conversation-history'.\n * It can parse HTML elements that match the same structure.\n *\n * For retrocompatibility, this extension also includes a ProseMirror plugin\n * that handles the grouping all the content after an horizontal rules into the\n * conversation-history children block.\n *\n * Usage:\n * ```\n * // Add to your Tiptap editor extensions\n * import { ConversationHistory } from './conversation-history'\n *\n * new Editor({\n * extensions: [\n * ConversationHistory,\n * // ... other extensions\n * ],\n * })\n * ```\n */\nimport { mergeAttributes, Node } from '@tiptap/core';\nimport { Plugin } from '@tiptap/pm/state';\n\nexport const ConversationHistory = Node.create({\n name: 'converstationHistory',\n group: 'block',\n content: 'block+',\n\n parseHTML() {\n return [\n {\n tag: 'div.conversation-history',\n },\n ];\n },\n\n renderHTML({ HTMLAttributes }) {\n return [\n 'div',\n mergeAttributes(HTMLAttributes, { class: 'conversation-history' }),\n 0,\n ];\n },\n\n /**\n * Adds custom ProseMirror plugins to the editor.\n * When a horizontal rule is encountered, this plugin collects all nodes\n * following the horizontal rule until the end of the document.\n * These nodes are then grouped together and replaced with\n * a single node of the same type as the plugin's type.\n *\n * @returns {Plugin[]} An array of ProseMirror plugins.\n */\n addProseMirrorPlugins() {\n return [\n new Plugin({\n appendTransaction: (transactions, oldState, newState) => {\n const tr = newState.tr;\n let modified = false;\n const nodesAfterHr = [];\n\n newState.doc.descendants((node, pos, parent) => {\n if (\n node.type.name === 'horizontalRule' &&\n parent.type.name === 'doc'\n ) {\n const start = pos;\n const end = newState.doc.content.size;\n\n newState.doc.nodesBetween(start, end, (n, p, parent) => {\n if (\n n.type.name !== 'horizontalRule' &&\n parent.type.name === 'doc'\n ) {\n nodesAfterHr.push({ node: n, pos: p });\n } else {\n return false;\n }\n });\n\n if (nodesAfterHr.length > 0) {\n const groupNode = this.type.create(\n {},\n nodesAfterHr.map((n) => n.node),\n );\n tr.replaceWith(start, end, groupNode);\n modified = true;\n }\n return false;\n }\n });\n\n return modified ? tr : null;\n },\n }),\n ];\n },\n});\n"],"names":["parent"],"mappings":";;AA+BO,MAAM,sBAAsB,KAAK,OAAO;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,SAAS;AAAA,EAET,YAAY;AACV,WAAO;AAAA,MACL;AAAA,QACE,KAAK;AAAA,MAAA;AAAA,IACP;AAAA,EAEJ;AAAA,EAEA,WAAW,EAAE,kBAAkB;AAC7B,WAAO;AAAA,MACL;AAAA,MACA,gBAAgB,gBAAgB,EAAE,OAAO,wBAAwB;AAAA,MACjE;AAAA,IAAA;AAAA,EAEJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,wBAAwB;AACtB,WAAO;AAAA,MACL,IAAI,OAAO;AAAA,QACT,mBAAmB,CAAC,cAAc,UAAU,aAAa;AACvD,gBAAM,KAAK,SAAS;AACpB,cAAI,WAAW;AACf,gBAAM,eAAe,CAAA;AAErB,0BAAS,IAAI,YAAY,CAAC,MAAM,KAAK,WAAW;AAC9C,gBACE,KAAK,KAAK,SAAS,oBACnB,OAAO,KAAK,SAAS,OACrB;AACA,oBAAM,QAAQ,KACR,MAAM,SAAS,IAAI,QAAQ;AAajC,kBAXA,SAAS,IAAI,aAAa,OAAO,KAAK,CAAC,GAAG,GAAGA,YAAW;AACtD,oBACE,EAAE,KAAK,SAAS,oBAChBA,QAAO,KAAK,SAAS;AAErB,+BAAa,KAAK,EAAE,MAAM,GAAG,KAAK,GAAG;AAAA;AAErC,yBAAO;AAAA,cAEX,CAAC,GAEG,aAAa,SAAS,GAAG;AAC3B,sBAAM,YAAY,KAAK,KAAK;AAAA,kBAC1B,CAAA;AAAA,kBACA,aAAa,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,gBAAA;AAEhC,mBAAG,YAAY,OAAO,KAAK,SAAS,GACpC,WAAW;AAAA,cACb;AACA,qBAAO;AAAA,YACT;AAAA,UACF,CAAC,GAEM,WAAW,KAAK;AAAA,QACzB;AAAA,MAAA,CACD;AAAA,IAAA;AAAA,EAEL;AACF,CAAC;"}
1
+ {"version":3,"file":"conversation-history.js","sources":["../../src/conversation-history/conversation-history.ts"],"sourcesContent":["/**\n * A Tiptap Node extension that creates a conversation history container.\n * This extension groups content blocks that appear after a horizontal rule\n * into a conversation history section.\n *\n * @extends Node\n *\n * @remarks\n * The node is rendered as a div element with the class 'conversation-history'.\n * It can parse HTML elements that match the same structure.\n *\n * For retrocompatibility, this extension also includes a ProseMirror plugin\n * that handles the grouping all the content after an horizontal rules into the\n * conversation-history children block.\n *\n * Usage:\n * ```\n * // Add to your Tiptap editor extensions\n * import { ConversationHistory } from './conversation-history'\n *\n * new Editor({\n * extensions: [\n * ConversationHistory,\n * // ... other extensions\n * ],\n * })\n * ```\n */\nimport { mergeAttributes, Node } from '@tiptap/core';\nimport { Plugin } from 'prosemirror-state';\n\nexport const ConversationHistory = Node.create({\n name: 'converstationHistory',\n group: 'block',\n content: 'block+',\n\n parseHTML() {\n return [\n {\n tag: 'div.conversation-history',\n },\n ];\n },\n\n renderHTML({ HTMLAttributes }) {\n return [\n 'div',\n mergeAttributes(HTMLAttributes, { class: 'conversation-history' }),\n 0,\n ];\n },\n\n /**\n * Adds custom ProseMirror plugins to the editor.\n * When a horizontal rule is encountered, this plugin collects all nodes\n * following the horizontal rule until the end of the document.\n * These nodes are then grouped together and replaced with\n * a single node of the same type as the plugin's type.\n *\n * @returns {Plugin[]} An array of ProseMirror plugins.\n */\n addProseMirrorPlugins() {\n return [\n new Plugin({\n appendTransaction: (transactions, oldState, newState) => {\n const tr = newState.tr;\n let modified = false;\n const nodesAfterHr = [];\n\n newState.doc.descendants((node, pos, parent) => {\n if (\n node.type.name === 'horizontalRule' &&\n parent.type.name === 'doc'\n ) {\n const start = pos;\n const end = newState.doc.content.size;\n\n newState.doc.nodesBetween(start, end, (n, p, parent) => {\n if (\n n.type.name !== 'horizontalRule' &&\n parent.type.name === 'doc'\n ) {\n nodesAfterHr.push({ node: n, pos: p });\n } else {\n return false;\n }\n });\n\n if (nodesAfterHr.length > 0) {\n const groupNode = this.type.create(\n {},\n nodesAfterHr.map((n) => n.node),\n );\n tr.replaceWith(start, end, groupNode);\n modified = true;\n }\n return false;\n }\n });\n\n return modified ? tr : null;\n },\n }),\n ];\n },\n});\n"],"names":["parent"],"mappings":";;AA+BO,MAAM,sBAAsB,KAAK,OAAO;AAAA,EAC7C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,SAAS;AAAA,EAET,YAAY;AACV,WAAO;AAAA,MACL;AAAA,QACE,KAAK;AAAA,MAAA;AAAA,IACP;AAAA,EAEJ;AAAA,EAEA,WAAW,EAAE,kBAAkB;AAC7B,WAAO;AAAA,MACL;AAAA,MACA,gBAAgB,gBAAgB,EAAE,OAAO,wBAAwB;AAAA,MACjE;AAAA,IAAA;AAAA,EAEJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,wBAAwB;AACtB,WAAO;AAAA,MACL,IAAI,OAAO;AAAA,QACT,mBAAmB,CAAC,cAAc,UAAU,aAAa;AACvD,gBAAM,KAAK,SAAS;AACpB,cAAI,WAAW;AACf,gBAAM,eAAe,CAAA;AAErB,0BAAS,IAAI,YAAY,CAAC,MAAM,KAAK,WAAW;AAC9C,gBACE,KAAK,KAAK,SAAS,oBACnB,OAAO,KAAK,SAAS,OACrB;AACA,oBAAM,QAAQ,KACR,MAAM,SAAS,IAAI,QAAQ;AAajC,kBAXA,SAAS,IAAI,aAAa,OAAO,KAAK,CAAC,GAAG,GAAGA,YAAW;AACtD,oBACE,EAAE,KAAK,SAAS,oBAChBA,QAAO,KAAK,SAAS;AAErB,+BAAa,KAAK,EAAE,MAAM,GAAG,KAAK,GAAG;AAAA;AAErC,yBAAO;AAAA,cAEX,CAAC,GAEG,aAAa,SAAS,GAAG;AAC3B,sBAAM,YAAY,KAAK,KAAK;AAAA,kBAC1B,CAAA;AAAA,kBACA,aAAa,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,gBAAA;AAEhC,mBAAG,YAAY,OAAO,KAAK,SAAS,GACpC,WAAW;AAAA,cACb;AACA,qBAAO;AAAA,YACT;AAAA,UACF,CAAC,GAEM,WAAW,KAAK;AAAA,QACzB;AAAA,MAAA,CACD;AAAA,IAAA;AAAA,EAEL;AACF,CAAC;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const core=require("@tiptap/core"),extensionHeading=require("@tiptap/extension-heading");require("@tiptap/extension-text-style");const CustomHeading=extensionHeading.Heading.extend({name:"customHeading",addOptions(){var _a;return{...(_a=this.parent)==null?void 0:_a.call(this),HTMLAttributes:{}}},parseHTML(){return this.options.levels.map(level=>({tag:`h${level}`,attrs:{level}}))},renderHTML({node,HTMLAttributes}){return[`h${this.options.levels.includes(node.attrs.level)?node.attrs.level:this.options.levels[0]}`,core.mergeAttributes(this.options.HTMLAttributes,HTMLAttributes),0]},addCommands(){var _a;return{...(_a=this.parent)==null?void 0:_a.call(this),setCustomHeading:attributes=>({tr,dispatch,commands})=>{if(!this.options.levels.includes(attributes.level))return!1;const{selection}=tr,{from,to}=selection;return tr.doc.nodesBetween(from,to,(node,pos)=>{node.isBlock&&from>=pos&&to<=pos+node.nodeSize&&node.content.forEach(content=>{content.marks.forEach(mark=>{mark.type.name==="textStyle"&&mark.attrs.fontSize&&mark.attrs.fontSize!==null&&(tr=tr.removeMark(pos,pos+node.nodeSize,mark.type))})})}),dispatch&&dispatch(tr),commands.setHeading({level:attributes.level})}}}});exports.CustomHeading=CustomHeading;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const core=require("@tiptap/core"),extensionHeading=require("@tiptap/extension-heading");require("@tiptap/extension-text-style");const CustomHeading=extensionHeading.Heading.extend({name:"customHeading",addOptions(){var _a;return{...(_a=this.parent)==null?void 0:_a.call(this),HTMLAttributes:{}}},parseHTML(){return this.options.levels.map(level=>({tag:`h${level}`,attrs:{level}}))},renderHTML({node,HTMLAttributes}){return[`h${this.options.levels.includes(node.attrs.level)?node.attrs.level:this.options.levels[0]}`,core.mergeAttributes(this.options.HTMLAttributes,HTMLAttributes),0]},addCommands(){return{setCustomHeading:attributes=>({tr,dispatch,commands})=>{if(!this.options.levels.includes(attributes.level))return!1;const{selection}=tr,{from,to}=selection;return tr.doc.nodesBetween(from,to,(node,pos)=>{node.isBlock&&from>=pos&&to<=pos+node.nodeSize&&node.content.forEach(content=>{content.marks.forEach(mark=>{mark.type.name==="textStyle"&&mark.attrs.fontSize&&mark.attrs.fontSize!==null&&(tr=tr.removeMark(pos,pos+node.nodeSize,mark.type))})})}),dispatch&&dispatch(tr),commands.setHeading({level:attributes.level})}}}});exports.CustomHeading=CustomHeading;
2
2
  //# sourceMappingURL=heading.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"heading.cjs","sources":["../../src/heading/heading.ts"],"sourcesContent":["import { mergeAttributes } from '@tiptap/core';\nimport { Heading } from '@tiptap/extension-heading';\nimport '@tiptap/extension-text-style';\n\nexport declare type Level = 1 | 2;\n\ninterface Options {\n levels: Level[];\n HTMLAttributes: Record<string, any>;\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n customHeading: {\n /**\n * Apply Heading Level\n */\n setCustomHeading: (attributes: { level: Level }) => ReturnType;\n };\n }\n}\n\nexport const CustomHeading = Heading.extend<Options>({\n name: 'customHeading',\n\n addOptions() {\n return {\n ...this.parent?.(),\n HTMLAttributes: {},\n };\n },\n\n parseHTML() {\n return this.options.levels.map((level: Level) => ({\n tag: `h${level}`,\n attrs: { level },\n }));\n },\n\n renderHTML({ node, HTMLAttributes }) {\n const hasLevel = this.options.levels.includes(node.attrs.level);\n const level = hasLevel ? node.attrs.level : this.options.levels[0];\n\n return [\n `h${level}`,\n mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),\n 0,\n ];\n },\n\n addCommands() {\n return {\n // Inherit Heading's own setHeading/toggleHeading (scoped to `this.name`,\n // i.e. 'customHeading') - without this, setCustomHeading below crashes\n // calling commands.setHeading(), which only existed by accident while\n // StarterKit's own (conflicting) heading was still enabled.\n ...this.parent?.(),\n setCustomHeading:\n (attributes) =>\n ({ tr, dispatch, commands }) => {\n if (!this.options.levels.includes(attributes.level)) {\n return false;\n }\n\n const { selection } = tr;\n const { from, to } = selection;\n\n tr.doc.nodesBetween(from, to, (node, pos) => {\n if (node.isBlock && from >= pos && to <= pos + node.nodeSize) {\n /* get node content and iterate through */\n node.content.forEach((content) => {\n /* get content marks and iterate through */\n content.marks.forEach((mark) => {\n /* find textStyle mark and if has fontSize attrs */\n if (\n mark.type.name === 'textStyle' &&\n mark.attrs['fontSize'] &&\n mark.attrs['fontSize'] !== null\n ) {\n /* remove any fontSize attr to reset heading style */\n tr = tr.removeMark(pos, pos + node.nodeSize, mark.type);\n }\n });\n });\n }\n });\n\n if (dispatch) {\n dispatch(tr);\n }\n return commands.setHeading({ level: attributes.level });\n },\n };\n },\n});\n"],"names":["Heading","mergeAttributes"],"mappings":"iNAsBO,MAAM,cAAgBA,iBAAAA,QAAQ,OAAgB,CACnD,KAAM,gBAEN,YAAa,QACX,MAAO,CACL,IAAG,QAAK,SAAL,0BACH,eAAgB,CAAA,CAAC,CAErB,EAEA,WAAY,CACV,OAAO,KAAK,QAAQ,OAAO,IAAK,QAAkB,CAChD,IAAK,IAAI,KAAK,GACd,MAAO,CAAE,KAAA,CAAM,EACf,CACJ,EAEA,WAAW,CAAE,KAAM,gBAAkB,CAInC,MAAO,CACL,IAJe,KAAK,QAAQ,OAAO,SAAS,KAAK,MAAM,KAAK,EACrC,KAAK,MAAM,MAAQ,KAAK,QAAQ,OAAO,CAAC,CAGtD,GACTC,KAAAA,gBAAgB,KAAK,QAAQ,eAAgB,cAAc,EAC3D,CAAA,CAEJ,EAEA,aAAc,QACZ,MAAO,CAKL,IAAG,QAAK,SAAL,0BACH,iBACG,YACD,CAAC,CAAE,GAAI,SAAU,YAAe,CAC9B,GAAI,CAAC,KAAK,QAAQ,OAAO,SAAS,WAAW,KAAK,EAChD,MAAO,GAGT,KAAM,CAAE,WAAc,GAChB,CAAE,KAAM,EAAA,EAAO,UAErB,UAAG,IAAI,aAAa,KAAM,GAAI,CAAC,KAAM,MAAQ,CACvC,KAAK,SAAW,MAAQ,KAAO,IAAM,IAAM,KAAK,UAElD,KAAK,QAAQ,QAAS,SAAY,CAEhC,QAAQ,MAAM,QAAS,MAAS,CAG5B,KAAK,KAAK,OAAS,aACnB,KAAK,MAAM,UACX,KAAK,MAAM,WAAgB,OAG3B,GAAK,GAAG,WAAW,IAAK,IAAM,KAAK,SAAU,KAAK,IAAI,EAE1D,CAAC,CACH,CAAC,CAEL,CAAC,EAEG,UACF,SAAS,EAAE,EAEN,SAAS,WAAW,CAAE,MAAO,WAAW,MAAO,CACxD,CAAA,CAEN,CACF,CAAC"}
1
+ {"version":3,"file":"heading.cjs","sources":["../../src/heading/heading.ts"],"sourcesContent":["import { mergeAttributes } from '@tiptap/core';\nimport { Heading } from '@tiptap/extension-heading';\nimport '@tiptap/extension-text-style';\n\nexport declare type Level = 1 | 2;\n\ninterface Options {\n levels: Level[];\n HTMLAttributes: Record<string, any>;\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n customHeading: {\n /**\n * Apply Heading Level\n */\n setCustomHeading: (attributes: { level: Level }) => ReturnType;\n };\n }\n}\n\nexport const CustomHeading = Heading.extend<Options>({\n name: 'customHeading',\n\n addOptions() {\n return {\n ...this.parent?.(),\n HTMLAttributes: {},\n };\n },\n\n parseHTML() {\n return this.options.levels.map((level: Level) => ({\n tag: `h${level}`,\n attrs: { level },\n }));\n },\n\n renderHTML({ node, HTMLAttributes }) {\n const hasLevel = this.options.levels.includes(node.attrs.level);\n const level = hasLevel ? node.attrs.level : this.options.levels[0];\n\n return [\n `h${level}`,\n mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),\n 0,\n ];\n },\n\n addCommands() {\n return {\n setCustomHeading:\n (attributes) =>\n ({ tr, dispatch, commands }) => {\n if (!this.options.levels.includes(attributes.level)) {\n return false;\n }\n\n const { selection } = tr;\n const { from, to } = selection;\n\n tr.doc.nodesBetween(from, to, (node, pos) => {\n if (node.isBlock && from >= pos && to <= pos + node.nodeSize) {\n /* get node content and iterate through */\n node.content.forEach((content) => {\n /* get content marks and iterate through */\n content.marks.forEach((mark) => {\n /* find textStyle mark and if has fontSize attrs */\n if (\n mark.type.name === 'textStyle' &&\n mark.attrs['fontSize'] &&\n mark.attrs['fontSize'] !== null\n ) {\n /* remove any fontSize attr to reset heading style */\n tr = tr.removeMark(pos, pos + node.nodeSize, mark.type);\n }\n });\n });\n }\n });\n\n if (dispatch) {\n dispatch(tr);\n }\n return commands.setHeading({ level: attributes.level });\n },\n };\n },\n});\n"],"names":["Heading","mergeAttributes"],"mappings":"iNAsBO,MAAM,cAAgBA,iBAAAA,QAAQ,OAAgB,CACnD,KAAM,gBAEN,YAAa,QACX,MAAO,CACL,IAAG,QAAK,SAAL,0BACH,eAAgB,CAAA,CAAC,CAErB,EAEA,WAAY,CACV,OAAO,KAAK,QAAQ,OAAO,IAAK,QAAkB,CAChD,IAAK,IAAI,KAAK,GACd,MAAO,CAAE,KAAA,CAAM,EACf,CACJ,EAEA,WAAW,CAAE,KAAM,gBAAkB,CAInC,MAAO,CACL,IAJe,KAAK,QAAQ,OAAO,SAAS,KAAK,MAAM,KAAK,EACrC,KAAK,MAAM,MAAQ,KAAK,QAAQ,OAAO,CAAC,CAGtD,GACTC,KAAAA,gBAAgB,KAAK,QAAQ,eAAgB,cAAc,EAC3D,CAAA,CAEJ,EAEA,aAAc,CACZ,MAAO,CACL,iBACG,YACD,CAAC,CAAE,GAAI,SAAU,YAAe,CAC9B,GAAI,CAAC,KAAK,QAAQ,OAAO,SAAS,WAAW,KAAK,EAChD,MAAO,GAGT,KAAM,CAAE,WAAc,GAChB,CAAE,KAAM,EAAA,EAAO,UAErB,UAAG,IAAI,aAAa,KAAM,GAAI,CAAC,KAAM,MAAQ,CACvC,KAAK,SAAW,MAAQ,KAAO,IAAM,IAAM,KAAK,UAElD,KAAK,QAAQ,QAAS,SAAY,CAEhC,QAAQ,MAAM,QAAS,MAAS,CAG5B,KAAK,KAAK,OAAS,aACnB,KAAK,MAAM,UACX,KAAK,MAAM,WAAgB,OAG3B,GAAK,GAAG,WAAW,IAAK,IAAM,KAAK,SAAU,KAAK,IAAI,EAE1D,CAAC,CACH,CAAC,CAEL,CAAC,EAEG,UACF,SAAS,EAAE,EAEN,SAAS,WAAW,CAAE,MAAO,WAAW,MAAO,CACxD,CAAA,CAEN,CACF,CAAC"}
@@ -24,13 +24,7 @@ const CustomHeading = Heading.extend({
24
24
  ];
25
25
  },
26
26
  addCommands() {
27
- var _a;
28
27
  return {
29
- // Inherit Heading's own setHeading/toggleHeading (scoped to `this.name`,
30
- // i.e. 'customHeading') - without this, setCustomHeading below crashes
31
- // calling commands.setHeading(), which only existed by accident while
32
- // StarterKit's own (conflicting) heading was still enabled.
33
- ...(_a = this.parent) == null ? void 0 : _a.call(this),
34
28
  setCustomHeading: (attributes) => ({ tr, dispatch, commands }) => {
35
29
  if (!this.options.levels.includes(attributes.level))
36
30
  return !1;
@@ -1 +1 @@
1
- {"version":3,"file":"heading.js","sources":["../../src/heading/heading.ts"],"sourcesContent":["import { mergeAttributes } from '@tiptap/core';\nimport { Heading } from '@tiptap/extension-heading';\nimport '@tiptap/extension-text-style';\n\nexport declare type Level = 1 | 2;\n\ninterface Options {\n levels: Level[];\n HTMLAttributes: Record<string, any>;\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n customHeading: {\n /**\n * Apply Heading Level\n */\n setCustomHeading: (attributes: { level: Level }) => ReturnType;\n };\n }\n}\n\nexport const CustomHeading = Heading.extend<Options>({\n name: 'customHeading',\n\n addOptions() {\n return {\n ...this.parent?.(),\n HTMLAttributes: {},\n };\n },\n\n parseHTML() {\n return this.options.levels.map((level: Level) => ({\n tag: `h${level}`,\n attrs: { level },\n }));\n },\n\n renderHTML({ node, HTMLAttributes }) {\n const hasLevel = this.options.levels.includes(node.attrs.level);\n const level = hasLevel ? node.attrs.level : this.options.levels[0];\n\n return [\n `h${level}`,\n mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),\n 0,\n ];\n },\n\n addCommands() {\n return {\n // Inherit Heading's own setHeading/toggleHeading (scoped to `this.name`,\n // i.e. 'customHeading') - without this, setCustomHeading below crashes\n // calling commands.setHeading(), which only existed by accident while\n // StarterKit's own (conflicting) heading was still enabled.\n ...this.parent?.(),\n setCustomHeading:\n (attributes) =>\n ({ tr, dispatch, commands }) => {\n if (!this.options.levels.includes(attributes.level)) {\n return false;\n }\n\n const { selection } = tr;\n const { from, to } = selection;\n\n tr.doc.nodesBetween(from, to, (node, pos) => {\n if (node.isBlock && from >= pos && to <= pos + node.nodeSize) {\n /* get node content and iterate through */\n node.content.forEach((content) => {\n /* get content marks and iterate through */\n content.marks.forEach((mark) => {\n /* find textStyle mark and if has fontSize attrs */\n if (\n mark.type.name === 'textStyle' &&\n mark.attrs['fontSize'] &&\n mark.attrs['fontSize'] !== null\n ) {\n /* remove any fontSize attr to reset heading style */\n tr = tr.removeMark(pos, pos + node.nodeSize, mark.type);\n }\n });\n });\n }\n });\n\n if (dispatch) {\n dispatch(tr);\n }\n return commands.setHeading({ level: attributes.level });\n },\n };\n },\n});\n"],"names":[],"mappings":";;;AAsBO,MAAM,gBAAgB,QAAQ,OAAgB;AAAA,EACnD,MAAM;AAAA,EAEN,aAAa;;AACX,WAAO;AAAA,MACL,IAAG,UAAK,WAAL;AAAA,MACH,gBAAgB,CAAA;AAAA,IAAC;AAAA,EAErB;AAAA,EAEA,YAAY;AACV,WAAO,KAAK,QAAQ,OAAO,IAAI,CAAC,WAAkB;AAAA,MAChD,KAAK,IAAI,KAAK;AAAA,MACd,OAAO,EAAE,MAAA;AAAA,IAAM,EACf;AAAA,EACJ;AAAA,EAEA,WAAW,EAAE,MAAM,kBAAkB;AAInC,WAAO;AAAA,MACL,IAJe,KAAK,QAAQ,OAAO,SAAS,KAAK,MAAM,KAAK,IACrC,KAAK,MAAM,QAAQ,KAAK,QAAQ,OAAO,CAAC,CAGtD;AAAA,MACT,gBAAgB,KAAK,QAAQ,gBAAgB,cAAc;AAAA,MAC3D;AAAA,IAAA;AAAA,EAEJ;AAAA,EAEA,cAAc;;AACZ,WAAO;AAAA;AAAA;AAAA;AAAA;AAAA,MAKL,IAAG,UAAK,WAAL;AAAA,MACH,kBACE,CAAC,eACD,CAAC,EAAE,IAAI,UAAU,eAAe;AAC9B,YAAI,CAAC,KAAK,QAAQ,OAAO,SAAS,WAAW,KAAK;AAChD,iBAAO;AAGT,cAAM,EAAE,cAAc,IAChB,EAAE,MAAM,GAAA,IAAO;AAErB,kBAAG,IAAI,aAAa,MAAM,IAAI,CAAC,MAAM,QAAQ;AAC3C,UAAI,KAAK,WAAW,QAAQ,OAAO,MAAM,MAAM,KAAK,YAElD,KAAK,QAAQ,QAAQ,CAAC,YAAY;AAEhC,oBAAQ,MAAM,QAAQ,CAAC,SAAS;AAE9B,cACE,KAAK,KAAK,SAAS,eACnB,KAAK,MAAM,YACX,KAAK,MAAM,aAAgB,SAG3B,KAAK,GAAG,WAAW,KAAK,MAAM,KAAK,UAAU,KAAK,IAAI;AAAA,YAE1D,CAAC;AAAA,UACH,CAAC;AAAA,QAEL,CAAC,GAEG,YACF,SAAS,EAAE,GAEN,SAAS,WAAW,EAAE,OAAO,WAAW,OAAO;AAAA,MACxD;AAAA,IAAA;AAAA,EAEN;AACF,CAAC;"}
1
+ {"version":3,"file":"heading.js","sources":["../../src/heading/heading.ts"],"sourcesContent":["import { mergeAttributes } from '@tiptap/core';\nimport { Heading } from '@tiptap/extension-heading';\nimport '@tiptap/extension-text-style';\n\nexport declare type Level = 1 | 2;\n\ninterface Options {\n levels: Level[];\n HTMLAttributes: Record<string, any>;\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n customHeading: {\n /**\n * Apply Heading Level\n */\n setCustomHeading: (attributes: { level: Level }) => ReturnType;\n };\n }\n}\n\nexport const CustomHeading = Heading.extend<Options>({\n name: 'customHeading',\n\n addOptions() {\n return {\n ...this.parent?.(),\n HTMLAttributes: {},\n };\n },\n\n parseHTML() {\n return this.options.levels.map((level: Level) => ({\n tag: `h${level}`,\n attrs: { level },\n }));\n },\n\n renderHTML({ node, HTMLAttributes }) {\n const hasLevel = this.options.levels.includes(node.attrs.level);\n const level = hasLevel ? node.attrs.level : this.options.levels[0];\n\n return [\n `h${level}`,\n mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),\n 0,\n ];\n },\n\n addCommands() {\n return {\n setCustomHeading:\n (attributes) =>\n ({ tr, dispatch, commands }) => {\n if (!this.options.levels.includes(attributes.level)) {\n return false;\n }\n\n const { selection } = tr;\n const { from, to } = selection;\n\n tr.doc.nodesBetween(from, to, (node, pos) => {\n if (node.isBlock && from >= pos && to <= pos + node.nodeSize) {\n /* get node content and iterate through */\n node.content.forEach((content) => {\n /* get content marks and iterate through */\n content.marks.forEach((mark) => {\n /* find textStyle mark and if has fontSize attrs */\n if (\n mark.type.name === 'textStyle' &&\n mark.attrs['fontSize'] &&\n mark.attrs['fontSize'] !== null\n ) {\n /* remove any fontSize attr to reset heading style */\n tr = tr.removeMark(pos, pos + node.nodeSize, mark.type);\n }\n });\n });\n }\n });\n\n if (dispatch) {\n dispatch(tr);\n }\n return commands.setHeading({ level: attributes.level });\n },\n };\n },\n});\n"],"names":[],"mappings":";;;AAsBO,MAAM,gBAAgB,QAAQ,OAAgB;AAAA,EACnD,MAAM;AAAA,EAEN,aAAa;;AACX,WAAO;AAAA,MACL,IAAG,UAAK,WAAL;AAAA,MACH,gBAAgB,CAAA;AAAA,IAAC;AAAA,EAErB;AAAA,EAEA,YAAY;AACV,WAAO,KAAK,QAAQ,OAAO,IAAI,CAAC,WAAkB;AAAA,MAChD,KAAK,IAAI,KAAK;AAAA,MACd,OAAO,EAAE,MAAA;AAAA,IAAM,EACf;AAAA,EACJ;AAAA,EAEA,WAAW,EAAE,MAAM,kBAAkB;AAInC,WAAO;AAAA,MACL,IAJe,KAAK,QAAQ,OAAO,SAAS,KAAK,MAAM,KAAK,IACrC,KAAK,MAAM,QAAQ,KAAK,QAAQ,OAAO,CAAC,CAGtD;AAAA,MACT,gBAAgB,KAAK,QAAQ,gBAAgB,cAAc;AAAA,MAC3D;AAAA,IAAA;AAAA,EAEJ;AAAA,EAEA,cAAc;AACZ,WAAO;AAAA,MACL,kBACE,CAAC,eACD,CAAC,EAAE,IAAI,UAAU,eAAe;AAC9B,YAAI,CAAC,KAAK,QAAQ,OAAO,SAAS,WAAW,KAAK;AAChD,iBAAO;AAGT,cAAM,EAAE,cAAc,IAChB,EAAE,MAAM,GAAA,IAAO;AAErB,kBAAG,IAAI,aAAa,MAAM,IAAI,CAAC,MAAM,QAAQ;AAC3C,UAAI,KAAK,WAAW,QAAQ,OAAO,MAAM,MAAM,KAAK,YAElD,KAAK,QAAQ,QAAQ,CAAC,YAAY;AAEhC,oBAAQ,MAAM,QAAQ,CAAC,SAAS;AAE9B,cACE,KAAK,KAAK,SAAS,eACnB,KAAK,MAAM,YACX,KAAK,MAAM,aAAgB,SAG3B,KAAK,GAAG,WAAW,KAAK,MAAM,KAAK,UAAU,KAAK,IAAI;AAAA,YAE1D,CAAC;AAAA,UACH,CAAC;AAAA,QAEL,CAAC,GAEG,YACF,SAAS,EAAE,GAEN,SAAS,WAAW,EAAE,OAAO,WAAW,OAAO;AAAA,MACxD;AAAA,IAAA;AAAA,EAEN;AACF,CAAC;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const utilities=require("@edifice.io/utilities"),core=require("@tiptap/core"),TiptapImage=require("@tiptap/extension-image"),state=require("@tiptap/pm/state"),IMAGE_INPUT_REGEX=/(?:^|\s)(!\[(.+|:?)]\((\S+)(?:(?:\s+)["'](\S+)["'])?\))$/,Image=TiptapImage.extend({name:"custom-image",draggable:!0,selectable:!0,addOptions(){var _a;return{...(_a=this.parent)==null?void 0:_a.call(this),inline:!0,content:"inline*",sizes:["small","medium","large"],HTMLAttributes:{class:"custom-image"},uploadFile:()=>Promise.resolve(null)}},addAttributes(){var _a;return{...(_a=this.parent)==null?void 0:_a.call(this),size:{default:"medium",rendered:!1},alt:{renderHTML:attributes=>({alt:attributes.alt}),parseHTML:element=>element.getAttribute("alt")},title:{renderHTML:attributes=>({title:attributes.title}),parseHTML:element=>element.getAttribute("title")},width:{default:"350",renderHTML:attributes=>attributes.width!==null&&attributes.width!==void 0&&!Number.isNaN(attributes.width)?{width:parseInt(attributes.width)}:{},parseHTML:element=>element.getAttribute("width")},height:{renderHTML:attributes=>attributes.height!==null&&attributes.height!==void 0&&!Number.isNaN(attributes.height)?{height:parseInt(attributes.height)}:{},parseHTML:element=>element.getAttribute("height")},style:{renderHTML:attributes=>attributes.style?{style:attributes.style}:{},parseHTML:()=>null}}},parseHTML(){return[{tag:'img[src]:not([src^="data:"])',getAttrs:el=>{var _a,_b,_c;const attr={src:el.getAttribute("src")};return(_a=el.parentElement)!=null&&_a.className.includes("image-container")&&(_b=el.parentElement.style)!=null&&_b.width&&(attr.width=el.parentElement.style.width),(_c=el.style)!=null&&_c.width&&(attr.width=el.style.width),["happy","proud","dreamy","love","tired","angry","worried","sick","joker","sad"].filter(smiley=>attr.src.includes(smiley+".png")).length>0&&(attr.style={width:"1.5em",height:"1.5em",fontSize:"16px"},attr.width="null",attr.height="null"),attr}}]},renderHTML({HTMLAttributes}){return["img",core.mergeAttributes(this.options.HTMLAttributes,HTMLAttributes)]},addInputRules(){return[core.nodeInputRule({find:IMAGE_INPUT_REGEX,type:this.type,getAttributes:match=>{const[,,alt,src,title]=match;return{src,alt,title}}})]},addCommands(){var _a;return{...(_a=this.parent)==null?void 0:_a.call(this),setNewImage:attrs=>({tr,dispatch})=>{const{selection}=tr,node=this.type.create(attrs);return dispatch&&tr.replaceRangeWith(selection.from,selection.to,node),!0}}},addProseMirrorPlugins(){const uploadNode=async file=>{const resizedImage=await utilities.ImageResizer.resizeImageFile(file),image=await this.options.uploadFile(resizedImage),imageUrl=`/workspace/${image.public?"pub/":""}document/${image._id}?timestamp=${new Date().getTime()}`;return this.type.create({src:imageUrl,alt:image.alt,title:image.title})},getFilteredFiles=files=>Array.from(files).filter(file=>/image\/(png|jpeg|jpg|gif|webp|heic|avif)/.test(file.type)),handleImageInsert=async(editor,file,position)=>{const node=await uploadNode(file);if(!node)return;const transaction=position!==void 0?editor.state.tr.insert(position,node):editor.state.tr.replaceSelectionWith(node);editor.dispatch(transaction)};return[new state.Plugin({props:{handlePaste:(editor,e)=>{var _a;const files=getFilteredFiles((_a=e.clipboardData)==null?void 0:_a.files);if(files.length===0)return!1;for(const file of files)handleImageInsert(editor,file);return!0},handleDrop:(editor,e,_s,moved)=>{if(moved)return!1;const files=getFilteredFiles(e.dataTransfer.files);if(files.length===0)return!1;const{pos:position}=editor.posAtCoords({left:e.clientX,top:e.clientY});for(const file of files)handleImageInsert(editor,file,position);return!0}}})]}});exports.IMAGE_INPUT_REGEX=IMAGE_INPUT_REGEX;exports.Image=Image;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const utilities=require("@edifice.io/utilities"),core=require("@tiptap/core"),TiptapImage=require("@tiptap/extension-image"),prosemirrorState=require("prosemirror-state"),IMAGE_INPUT_REGEX=/(?:^|\s)(!\[(.+|:?)]\((\S+)(?:(?:\s+)["'](\S+)["'])?\))$/,Image=TiptapImage.extend({name:"custom-image",draggable:!0,selectable:!0,addOptions(){var _a;return{...(_a=this.parent)==null?void 0:_a.call(this),inline:!0,content:"inline*",sizes:["small","medium","large"],HTMLAttributes:{class:"custom-image"},uploadFile:()=>Promise.resolve(null)}},addAttributes(){var _a;return{...(_a=this.parent)==null?void 0:_a.call(this),size:{default:"medium",rendered:!1},alt:{renderHTML:attributes=>({alt:attributes.alt}),parseHTML:element=>element.getAttribute("alt")},title:{renderHTML:attributes=>({title:attributes.title}),parseHTML:element=>element.getAttribute("title")},width:{default:"350",renderHTML:attributes=>attributes.width!==null&&attributes.width!==void 0&&!Number.isNaN(attributes.width)?{width:parseInt(attributes.width)}:{},parseHTML:element=>element.getAttribute("width")},height:{renderHTML:attributes=>attributes.height!==null&&attributes.height!==void 0&&!Number.isNaN(attributes.height)?{height:parseInt(attributes.height)}:{},parseHTML:element=>element.getAttribute("height")},style:{renderHTML:attributes=>attributes.style?{style:attributes.style}:{},parseHTML:()=>null}}},parseHTML(){return[{tag:'img[src]:not([src^="data:"])',getAttrs:el=>{var _a,_b,_c;const attr={src:el.getAttribute("src")};return(_a=el.parentElement)!=null&&_a.className.includes("image-container")&&(_b=el.parentElement.style)!=null&&_b.width&&(attr.width=el.parentElement.style.width),(_c=el.style)!=null&&_c.width&&(attr.width=el.style.width),["happy","proud","dreamy","love","tired","angry","worried","sick","joker","sad"].filter(smiley=>attr.src.includes(smiley+".png")).length>0&&(attr.style={width:"1.5em",height:"1.5em",fontSize:"16px"},attr.width="null",attr.height="null"),attr}}]},renderHTML({HTMLAttributes}){return["img",core.mergeAttributes(this.options.HTMLAttributes,HTMLAttributes)]},addInputRules(){return[core.nodeInputRule({find:IMAGE_INPUT_REGEX,type:this.type,getAttributes:match=>{const[,,alt,src,title]=match;return{src,alt,title}}})]},addCommands(){return{setNewImage:attrs=>({tr,dispatch})=>{const{selection}=tr,node=this.type.create(attrs);return dispatch&&tr.replaceRangeWith(selection.from,selection.to,node),!0},setAttributes:attributes=>({tr,dispatch})=>{const{selection}=tr,options={...tr.doc.nodeAt(tr.selection.from).attrs,...attributes},node=this.type.create(options);return dispatch&&tr.replaceRangeWith(selection.from,selection.to,node),!0}}},addProseMirrorPlugins(){const uploadNode=async file=>{const resizedImage=await utilities.ImageResizer.resizeImageFile(file),image=await this.options.uploadFile(resizedImage),imageUrl=`/workspace/${image.public?"pub/":""}document/${image._id}?timestamp=${new Date().getTime()}`;return this.type.create({src:imageUrl,alt:image.alt,title:image.title})},getFilteredFiles=files=>Array.from(files).filter(file=>/image\/(png|jpeg|jpg|gif|webp|heic|avif)/.test(file.type)),handleImageInsert=async(editor,file,position)=>{const node=await uploadNode(file);if(!node)return;const transaction=position!==void 0?editor.state.tr.insert(position,node):editor.state.tr.replaceSelectionWith(node);editor.dispatch(transaction)};return[new prosemirrorState.Plugin({props:{handlePaste:(editor,e)=>{var _a;const files=getFilteredFiles((_a=e.clipboardData)==null?void 0:_a.files);if(files.length===0)return!1;for(const file of files)handleImageInsert(editor,file);return!0},handleDrop:(editor,e,_s,moved)=>{if(moved)return!1;const files=getFilteredFiles(e.dataTransfer.files);if(files.length===0)return!1;const{pos:position}=editor.posAtCoords({left:e.clientX,top:e.clientY});for(const file of files)handleImageInsert(editor,file,position);return!0}}})]}});exports.IMAGE_INPUT_REGEX=IMAGE_INPUT_REGEX;exports.Image=Image;
2
2
  //# sourceMappingURL=image.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"image.cjs","sources":["../../src/image/image.ts"],"sourcesContent":["import { WorkspaceElement } from '@edifice.io/client';\nimport { ImageResizer } from '@edifice.io/utilities';\nimport { mergeAttributes, nodeInputRule } from '@tiptap/core';\nimport TiptapImage from '@tiptap/extension-image';\nimport { Plugin } from '@tiptap/pm/state';\n\nexport const IMAGE_INPUT_REGEX =\n /(?:^|\\s)(!\\[(.+|:?)]\\((\\S+)(?:(?:\\s+)[\"'](\\S+)[\"'])?\\))$/;\n\nexport interface CustomImageOptions {\n HTMLAttributes: Record<string, string>;\n sizes: string[];\n uploadFile?: (file: File) => Promise<WorkspaceElement | null>;\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n customImage: {\n setNewImage: (options: {\n src: string;\n alt?: string;\n title?: string;\n }) => ReturnType;\n };\n }\n}\n\nexport const Image = TiptapImage.extend<CustomImageOptions>({\n name: 'custom-image',\n draggable: true,\n selectable: true,\n\n addOptions() {\n return {\n ...this.parent?.(),\n inline: true,\n content: 'inline*',\n sizes: ['small', 'medium', 'large'],\n HTMLAttributes: {\n class: 'custom-image',\n },\n uploadFile: () => {\n return Promise.resolve(null);\n },\n };\n },\n\n addAttributes() {\n return {\n ...this.parent?.(),\n size: {\n default: 'medium',\n rendered: false,\n },\n alt: {\n renderHTML: (attributes) => {\n return {\n alt: attributes.alt,\n };\n },\n parseHTML: (element) => element.getAttribute('alt'),\n },\n title: {\n renderHTML: (attributes) => {\n return {\n title: attributes.title,\n };\n },\n parseHTML: (element) => element.getAttribute('title'),\n },\n width: {\n default: '350',\n renderHTML: (attributes) => {\n if (\n attributes.width !== null &&\n attributes.width !== undefined &&\n !Number.isNaN(attributes.width)\n ) {\n return {\n width: parseInt(attributes.width),\n };\n }\n return {};\n },\n parseHTML: (element) => element.getAttribute('width'),\n },\n height: {\n renderHTML: (attributes) => {\n if (\n attributes.height !== null &&\n attributes.height !== undefined &&\n !Number.isNaN(attributes.height)\n ) {\n return {\n height: parseInt(attributes.height),\n };\n }\n return {};\n },\n parseHTML: (element) => element.getAttribute('height'),\n },\n style: {\n renderHTML: (attributes) => {\n return attributes.style\n ? {\n style: attributes.style,\n }\n : {};\n },\n parseHTML: () => {\n return null;\n },\n },\n };\n },\n\n parseHTML() {\n return [\n {\n tag: 'img[src]:not([src^=\"data:\"])',\n getAttrs: (el: HTMLImageElement) => {\n const attr = { src: el.getAttribute('src') };\n // Check old content format and get the width from the parent element\n if (el.parentElement?.className.includes('image-container')) {\n if (el.parentElement.style?.width) {\n attr['width'] = el.parentElement.style.width;\n }\n }\n if (el.style?.width) {\n attr['width'] = el.style.width;\n }\n\n // Check old content smiley\n const oldSmileyList = [\n 'happy',\n 'proud',\n 'dreamy',\n 'love',\n 'tired',\n 'angry',\n 'worried',\n 'sick',\n 'joker',\n 'sad',\n ];\n if (\n oldSmileyList.filter((smiley) => attr.src.includes(smiley + '.png'))\n .length > 0\n ) {\n attr['style'] = {\n width: '1.5em',\n height: '1.5em',\n fontSize: '16px',\n };\n attr['width'] = 'null';\n attr['height'] = 'null';\n }\n\n return attr;\n },\n },\n ];\n },\n\n renderHTML({ HTMLAttributes }) {\n return [\n 'img',\n mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),\n ];\n },\n\n addInputRules() {\n return [\n nodeInputRule({\n find: IMAGE_INPUT_REGEX,\n type: this.type,\n getAttributes: (match) => {\n const [, , alt, src, title] = match;\n\n return {\n src,\n alt,\n title,\n };\n },\n }),\n ];\n },\n\n addCommands() {\n return {\n // Inherit TiptapImage's own setImage (scoped to `this.name`, i.e.\n // 'custom-image') - same bug class as heading.ts: without this spread,\n // addCommands() replaces rather than extends the parent's commands.\n ...this.parent?.(),\n setNewImage:\n (attrs) =>\n ({ tr, dispatch }) => {\n const { selection } = tr;\n const node = this.type.create(attrs);\n\n if (dispatch) {\n tr.replaceRangeWith(selection.from, selection.to, node);\n }\n\n return true;\n },\n };\n },\n\n addProseMirrorPlugins() {\n const uploadNode = async (file: File) => {\n /**\n * Resize the image\n */\n const resizedImage = await ImageResizer.resizeImageFile(file);\n\n /**\n * Upload the image\n */\n const image = await this.options.uploadFile(resizedImage);\n\n /**\n * Get the image url\n */\n const imageUrl = `/workspace/${image.public ? 'pub/' : ''}document/${\n image._id\n }?timestamp=${new Date().getTime()}`;\n\n /**\n * Create the image node\n */\n\n const node = this.type.create({\n src: imageUrl,\n alt: image.alt,\n title: image.title,\n });\n\n return node;\n };\n\n const getFilteredFiles = (files: FileList) => {\n return Array.from(files).filter((file) =>\n /image\\/(png|jpeg|jpg|gif|webp|heic|avif)/.test(file.type),\n );\n };\n\n const handleImageInsert = async (\n editor: any,\n file: File,\n position?: number,\n ) => {\n const node = await uploadNode(file);\n if (!node) return;\n\n const transaction =\n position !== undefined\n ? editor.state.tr.insert(position, node)\n : editor.state.tr.replaceSelectionWith(node);\n\n editor.dispatch(transaction);\n };\n\n return [\n new Plugin({\n props: {\n handlePaste: (editor, e) => {\n const files = getFilteredFiles(e.clipboardData?.files);\n if (files.length === 0) return false;\n\n for (const file of files) {\n handleImageInsert(editor, file);\n }\n\n return true;\n },\n handleDrop: (editor, e, _s, moved) => {\n if (moved) return false;\n\n const files = getFilteredFiles(e.dataTransfer.files);\n if (files.length === 0) return false;\n\n const { pos: position } = editor.posAtCoords({\n left: e.clientX,\n top: e.clientY,\n });\n\n for (const file of files) {\n handleImageInsert(editor, file, position);\n }\n return true;\n },\n },\n }),\n ];\n },\n});\n"],"names":["mergeAttributes","nodeInputRule","ImageResizer","Plugin"],"mappings":"+OAMa,kBACX,2DAoBW,MAAQ,YAAY,OAA2B,CAC1D,KAAM,eACN,UAAW,GACX,WAAY,GAEZ,YAAa,QACX,MAAO,CACL,IAAG,QAAK,SAAL,0BACH,OAAQ,GACR,QAAS,UACT,MAAO,CAAC,QAAS,SAAU,OAAO,EAClC,eAAgB,CACd,MAAO,cAAA,EAET,WAAY,IACH,QAAQ,QAAQ,IAAI,CAC7B,CAEJ,EAEA,eAAgB,QACd,MAAO,CACL,IAAG,QAAK,SAAL,0BACH,KAAM,CACJ,QAAS,SACT,SAAU,EAAA,EAEZ,IAAK,CACH,WAAa,aACJ,CACL,IAAK,WAAW,GAAA,GAGpB,UAAY,SAAY,QAAQ,aAAa,KAAK,CAAA,EAEpD,MAAO,CACL,WAAa,aACJ,CACL,MAAO,WAAW,KAAA,GAGtB,UAAY,SAAY,QAAQ,aAAa,OAAO,CAAA,EAEtD,MAAO,CACL,QAAS,MACT,WAAa,YAET,WAAW,QAAU,MACrB,WAAW,QAAU,QACrB,CAAC,OAAO,MAAM,WAAW,KAAK,EAEvB,CACL,MAAO,SAAS,WAAW,KAAK,CAAA,EAG7B,CAAA,EAET,UAAY,SAAY,QAAQ,aAAa,OAAO,CAAA,EAEtD,OAAQ,CACN,WAAa,YAET,WAAW,SAAW,MACtB,WAAW,SAAW,QACtB,CAAC,OAAO,MAAM,WAAW,MAAM,EAExB,CACL,OAAQ,SAAS,WAAW,MAAM,CAAA,EAG/B,CAAA,EAET,UAAY,SAAY,QAAQ,aAAa,QAAQ,CAAA,EAEvD,MAAO,CACL,WAAa,YACJ,WAAW,MACd,CACE,MAAO,WAAW,KAAA,EAEpB,CAAA,EAEN,UAAW,IACF,IACT,CACF,CAEJ,EAEA,WAAY,CACV,MAAO,CACL,CACE,IAAK,+BACL,SAAW,IAAyB,cAClC,MAAM,KAAO,CAAE,IAAK,GAAG,aAAa,KAAK,CAAA,EAEzC,OAAI,MAAG,gBAAH,SAAkB,UAAU,SAAS,qBACnC,MAAG,cAAc,QAAjB,SAAwB,QAC1B,KAAK,MAAW,GAAG,cAAc,MAAM,QAGvC,MAAG,QAAH,SAAU,QACZ,KAAK,MAAW,GAAG,MAAM,OAIL,CACpB,QACA,QACA,SACA,OACA,QACA,QACA,UACA,OACA,QACA,KAAA,EAGc,OAAQ,QAAW,KAAK,IAAI,SAAS,OAAS,MAAM,CAAC,EAChE,OAAS,IAEZ,KAAK,MAAW,CACd,MAAO,QACP,OAAQ,QACR,SAAU,MAAA,EAEZ,KAAK,MAAW,OAChB,KAAK,OAAY,QAGZ,IACT,CAAA,CACF,CAEJ,EAEA,WAAW,CAAE,gBAAkB,CAC7B,MAAO,CACL,MACAA,KAAAA,gBAAgB,KAAK,QAAQ,eAAgB,cAAc,CAAA,CAE/D,EAEA,eAAgB,CACd,MAAO,CACLC,mBAAc,CACZ,KAAM,kBACN,KAAM,KAAK,KACX,cAAgB,OAAU,CACxB,KAAM,GAAK,IAAK,IAAK,KAAK,EAAI,MAE9B,MAAO,CACL,IACA,IACA,KAAA,CAEJ,CAAA,CACD,CAAA,CAEL,EAEA,aAAc,QACZ,MAAO,CAIL,IAAG,QAAK,SAAL,0BACH,YACG,OACD,CAAC,CAAE,GAAI,YAAe,CACpB,KAAM,CAAE,WAAc,GAChB,KAAO,KAAK,KAAK,OAAO,KAAK,EAEnC,OAAI,UACF,GAAG,iBAAiB,UAAU,KAAM,UAAU,GAAI,IAAI,EAGjD,EACT,CAAA,CAEN,EAEA,uBAAwB,CACtB,MAAM,WAAa,MAAO,MAAe,CAIvC,MAAM,aAAe,MAAMC,uBAAa,gBAAgB,IAAI,EAKtD,MAAQ,MAAM,KAAK,QAAQ,WAAW,YAAY,EAKlD,SAAW,cAAc,MAAM,OAAS,OAAS,EAAE,YACvD,MAAM,GACR,cAAc,IAAI,KAAA,EAAO,SAAS,GAYlC,OANa,KAAK,KAAK,OAAO,CAC5B,IAAK,SACL,IAAK,MAAM,IACX,MAAO,MAAM,KAAA,CACd,CAGH,EAEM,iBAAoB,OACjB,MAAM,KAAK,KAAK,EAAE,OAAQ,MAC/B,2CAA2C,KAAK,KAAK,IAAI,CAAA,EAIvD,kBAAoB,MACxB,OACA,KACA,WACG,CACH,MAAM,KAAO,MAAM,WAAW,IAAI,EAClC,GAAI,CAAC,KAAM,OAEX,MAAM,YACJ,WAAa,OACT,OAAO,MAAM,GAAG,OAAO,SAAU,IAAI,EACrC,OAAO,MAAM,GAAG,qBAAqB,IAAI,EAE/C,OAAO,SAAS,WAAW,CAC7B,EAEA,MAAO,CACL,IAAIC,aAAO,CACT,MAAO,CACL,YAAa,CAAC,OAAQ,IAAM,QAC1B,MAAM,MAAQ,kBAAiB,KAAE,gBAAF,eAAiB,KAAK,EACrD,GAAI,MAAM,SAAW,EAAG,MAAO,GAE/B,UAAW,QAAQ,MACjB,kBAAkB,OAAQ,IAAI,EAGhC,MAAO,EACT,EACA,WAAY,CAAC,OAAQ,EAAG,GAAI,QAAU,CACpC,GAAI,MAAO,MAAO,GAElB,MAAM,MAAQ,iBAAiB,EAAE,aAAa,KAAK,EACnD,GAAI,MAAM,SAAW,EAAG,MAAO,GAE/B,KAAM,CAAE,IAAK,UAAa,OAAO,YAAY,CAC3C,KAAM,EAAE,QACR,IAAK,EAAE,OAAA,CACR,EAED,UAAW,QAAQ,MACjB,kBAAkB,OAAQ,KAAM,QAAQ,EAE1C,MAAO,EACT,CAAA,CACF,CACD,CAAA,CAEL,CACF,CAAC"}
1
+ {"version":3,"file":"image.cjs","sources":["../../src/image/image.ts"],"sourcesContent":["import { WorkspaceElement } from '@edifice.io/client';\nimport { ImageResizer } from '@edifice.io/utilities';\nimport { mergeAttributes, nodeInputRule } from '@tiptap/core';\nimport TiptapImage from '@tiptap/extension-image';\nimport { Plugin } from 'prosemirror-state';\n\nexport const IMAGE_INPUT_REGEX =\n /(?:^|\\s)(!\\[(.+|:?)]\\((\\S+)(?:(?:\\s+)[\"'](\\S+)[\"'])?\\))$/;\n\nexport interface CustomImageOptions {\n HTMLAttributes: Record<string, string>;\n sizes: string[];\n uploadFile?: (file: File) => Promise<WorkspaceElement | null>;\n}\n\ninterface AttributesProps {\n width: number | string;\n height: number | string;\n size: string;\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n customImage: {\n setAttributes: (options: AttributesProps) => ReturnType;\n setNewImage: (options: {\n src: string;\n alt?: string;\n title?: string;\n }) => ReturnType;\n };\n }\n}\n\nexport const Image = TiptapImage.extend<CustomImageOptions>({\n name: 'custom-image',\n draggable: true,\n selectable: true,\n\n addOptions() {\n return {\n ...this.parent?.(),\n inline: true,\n content: 'inline*',\n sizes: ['small', 'medium', 'large'],\n HTMLAttributes: {\n class: 'custom-image',\n },\n uploadFile: () => {\n return Promise.resolve(null);\n },\n };\n },\n\n addAttributes() {\n return {\n ...this.parent?.(),\n size: {\n default: 'medium',\n rendered: false,\n },\n alt: {\n renderHTML: (attributes) => {\n return {\n alt: attributes.alt,\n };\n },\n parseHTML: (element) => element.getAttribute('alt'),\n },\n title: {\n renderHTML: (attributes) => {\n return {\n title: attributes.title,\n };\n },\n parseHTML: (element) => element.getAttribute('title'),\n },\n width: {\n default: '350',\n renderHTML: (attributes) => {\n if (\n attributes.width !== null &&\n attributes.width !== undefined &&\n !Number.isNaN(attributes.width)\n ) {\n return {\n width: parseInt(attributes.width),\n };\n }\n return {};\n },\n parseHTML: (element) => element.getAttribute('width'),\n },\n height: {\n renderHTML: (attributes) => {\n if (\n attributes.height !== null &&\n attributes.height !== undefined &&\n !Number.isNaN(attributes.height)\n ) {\n return {\n height: parseInt(attributes.height),\n };\n }\n return {};\n },\n parseHTML: (element) => element.getAttribute('height'),\n },\n style: {\n renderHTML: (attributes) => {\n return attributes.style\n ? {\n style: attributes.style,\n }\n : {};\n },\n parseHTML: () => {\n return null;\n },\n },\n };\n },\n\n parseHTML() {\n return [\n {\n tag: 'img[src]:not([src^=\"data:\"])',\n getAttrs: (el: HTMLImageElement) => {\n const attr = { src: el.getAttribute('src') };\n // Check old content format and get the width from the parent element\n if (el.parentElement?.className.includes('image-container')) {\n if (el.parentElement.style?.width) {\n attr['width'] = el.parentElement.style.width;\n }\n }\n if (el.style?.width) {\n attr['width'] = el.style.width;\n }\n\n // Check old content smiley\n const oldSmileyList = [\n 'happy',\n 'proud',\n 'dreamy',\n 'love',\n 'tired',\n 'angry',\n 'worried',\n 'sick',\n 'joker',\n 'sad',\n ];\n if (\n oldSmileyList.filter((smiley) => attr.src.includes(smiley + '.png'))\n .length > 0\n ) {\n attr['style'] = {\n width: '1.5em',\n height: '1.5em',\n fontSize: '16px',\n };\n attr['width'] = 'null';\n attr['height'] = 'null';\n }\n\n return attr;\n },\n },\n ];\n },\n\n renderHTML({ HTMLAttributes }) {\n return [\n 'img',\n mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),\n ];\n },\n\n addInputRules() {\n return [\n nodeInputRule({\n find: IMAGE_INPUT_REGEX,\n type: this.type,\n getAttributes: (match) => {\n const [, , alt, src, title] = match;\n\n return {\n src,\n alt,\n title,\n };\n },\n }),\n ];\n },\n\n addCommands() {\n return {\n setNewImage:\n (attrs) =>\n ({ tr, dispatch }) => {\n const { selection } = tr;\n const node = this.type.create(attrs);\n\n if (dispatch) {\n tr.replaceRangeWith(selection.from, selection.to, node);\n }\n\n return true;\n },\n setAttributes:\n (attributes) =>\n ({ tr, dispatch }) => {\n const { selection } = tr;\n\n const nodeAttrs = tr.doc.nodeAt(tr.selection.from);\n const options = {\n ...nodeAttrs.attrs,\n ...attributes,\n };\n const node = this.type.create(options);\n\n if (dispatch) {\n tr.replaceRangeWith(selection.from, selection.to, node);\n }\n\n return true;\n },\n };\n },\n\n addProseMirrorPlugins() {\n const uploadNode = async (file: File) => {\n /**\n * Resize the image\n */\n const resizedImage = await ImageResizer.resizeImageFile(file);\n\n /**\n * Upload the image\n */\n const image = await this.options.uploadFile(resizedImage);\n\n /**\n * Get the image url\n */\n const imageUrl = `/workspace/${image.public ? 'pub/' : ''}document/${\n image._id\n }?timestamp=${new Date().getTime()}`;\n\n /**\n * Create the image node\n */\n\n const node = this.type.create({\n src: imageUrl,\n alt: image.alt,\n title: image.title,\n });\n\n return node;\n };\n\n const getFilteredFiles = (files: FileList) => {\n return Array.from(files).filter((file) =>\n /image\\/(png|jpeg|jpg|gif|webp|heic|avif)/.test(file.type),\n );\n };\n\n const handleImageInsert = async (\n editor: any,\n file: File,\n position?: number,\n ) => {\n const node = await uploadNode(file);\n if (!node) return;\n\n const transaction =\n position !== undefined\n ? editor.state.tr.insert(position, node)\n : editor.state.tr.replaceSelectionWith(node);\n\n editor.dispatch(transaction);\n };\n\n return [\n new Plugin({\n props: {\n handlePaste: (editor, e) => {\n const files = getFilteredFiles(e.clipboardData?.files);\n if (files.length === 0) return false;\n\n for (const file of files) {\n handleImageInsert(editor, file);\n }\n\n return true;\n },\n handleDrop: (editor, e, _s, moved) => {\n if (moved) return false;\n\n const files = getFilteredFiles(e.dataTransfer.files);\n if (files.length === 0) return false;\n\n const { pos: position } = editor.posAtCoords({\n left: e.clientX,\n top: e.clientY,\n });\n\n for (const file of files) {\n handleImageInsert(editor, file, position);\n }\n return true;\n },\n },\n }),\n ];\n },\n});\n"],"names":["mergeAttributes","nodeInputRule","ImageResizer","Plugin"],"mappings":"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"}
@@ -5,9 +5,15 @@ export interface CustomImageOptions {
5
5
  sizes: string[];
6
6
  uploadFile?: (file: File) => Promise<WorkspaceElement | null>;
7
7
  }
8
+ interface AttributesProps {
9
+ width: number | string;
10
+ height: number | string;
11
+ size: string;
12
+ }
8
13
  declare module '@tiptap/core' {
9
14
  interface Commands<ReturnType> {
10
15
  customImage: {
16
+ setAttributes: (options: AttributesProps) => ReturnType;
11
17
  setNewImage: (options: {
12
18
  src: string;
13
19
  alt?: string;
@@ -17,3 +23,4 @@ declare module '@tiptap/core' {
17
23
  }
18
24
  }
19
25
  export declare const Image: import('@tiptap/core').Node<CustomImageOptions, any>;
26
+ export {};
@@ -1,7 +1,7 @@
1
1
  import { ImageResizer } from "@edifice.io/utilities";
2
2
  import { nodeInputRule, mergeAttributes } from "@tiptap/core";
3
3
  import TiptapImage from "@tiptap/extension-image";
4
- import { Plugin } from "@tiptap/pm/state";
4
+ import { Plugin } from "prosemirror-state";
5
5
  const IMAGE_INPUT_REGEX = /(?:^|\s)(!\[(.+|:?)]\((\S+)(?:(?:\s+)["'](\S+)["'])?\))$/, Image = TiptapImage.extend({
6
6
  name: "custom-image",
7
7
  draggable: !0,
@@ -110,15 +110,17 @@ const IMAGE_INPUT_REGEX = /(?:^|\s)(!\[(.+|:?)]\((\S+)(?:(?:\s+)["'](\S+)["'])?\
110
110
  ];
111
111
  },
112
112
  addCommands() {
113
- var _a;
114
113
  return {
115
- // Inherit TiptapImage's own setImage (scoped to `this.name`, i.e.
116
- // 'custom-image') - same bug class as heading.ts: without this spread,
117
- // addCommands() replaces rather than extends the parent's commands.
118
- ...(_a = this.parent) == null ? void 0 : _a.call(this),
119
114
  setNewImage: (attrs) => ({ tr, dispatch }) => {
120
115
  const { selection } = tr, node = this.type.create(attrs);
121
116
  return dispatch && tr.replaceRangeWith(selection.from, selection.to, node), !0;
117
+ },
118
+ setAttributes: (attributes) => ({ tr, dispatch }) => {
119
+ const { selection } = tr, options = {
120
+ ...tr.doc.nodeAt(tr.selection.from).attrs,
121
+ ...attributes
122
+ }, node = this.type.create(options);
123
+ return dispatch && tr.replaceRangeWith(selection.from, selection.to, node), !0;
122
124
  }
123
125
  };
124
126
  },
@@ -1 +1 @@
1
- {"version":3,"file":"image.js","sources":["../../src/image/image.ts"],"sourcesContent":["import { WorkspaceElement } from '@edifice.io/client';\nimport { ImageResizer } from '@edifice.io/utilities';\nimport { mergeAttributes, nodeInputRule } from '@tiptap/core';\nimport TiptapImage from '@tiptap/extension-image';\nimport { Plugin } from '@tiptap/pm/state';\n\nexport const IMAGE_INPUT_REGEX =\n /(?:^|\\s)(!\\[(.+|:?)]\\((\\S+)(?:(?:\\s+)[\"'](\\S+)[\"'])?\\))$/;\n\nexport interface CustomImageOptions {\n HTMLAttributes: Record<string, string>;\n sizes: string[];\n uploadFile?: (file: File) => Promise<WorkspaceElement | null>;\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n customImage: {\n setNewImage: (options: {\n src: string;\n alt?: string;\n title?: string;\n }) => ReturnType;\n };\n }\n}\n\nexport const Image = TiptapImage.extend<CustomImageOptions>({\n name: 'custom-image',\n draggable: true,\n selectable: true,\n\n addOptions() {\n return {\n ...this.parent?.(),\n inline: true,\n content: 'inline*',\n sizes: ['small', 'medium', 'large'],\n HTMLAttributes: {\n class: 'custom-image',\n },\n uploadFile: () => {\n return Promise.resolve(null);\n },\n };\n },\n\n addAttributes() {\n return {\n ...this.parent?.(),\n size: {\n default: 'medium',\n rendered: false,\n },\n alt: {\n renderHTML: (attributes) => {\n return {\n alt: attributes.alt,\n };\n },\n parseHTML: (element) => element.getAttribute('alt'),\n },\n title: {\n renderHTML: (attributes) => {\n return {\n title: attributes.title,\n };\n },\n parseHTML: (element) => element.getAttribute('title'),\n },\n width: {\n default: '350',\n renderHTML: (attributes) => {\n if (\n attributes.width !== null &&\n attributes.width !== undefined &&\n !Number.isNaN(attributes.width)\n ) {\n return {\n width: parseInt(attributes.width),\n };\n }\n return {};\n },\n parseHTML: (element) => element.getAttribute('width'),\n },\n height: {\n renderHTML: (attributes) => {\n if (\n attributes.height !== null &&\n attributes.height !== undefined &&\n !Number.isNaN(attributes.height)\n ) {\n return {\n height: parseInt(attributes.height),\n };\n }\n return {};\n },\n parseHTML: (element) => element.getAttribute('height'),\n },\n style: {\n renderHTML: (attributes) => {\n return attributes.style\n ? {\n style: attributes.style,\n }\n : {};\n },\n parseHTML: () => {\n return null;\n },\n },\n };\n },\n\n parseHTML() {\n return [\n {\n tag: 'img[src]:not([src^=\"data:\"])',\n getAttrs: (el: HTMLImageElement) => {\n const attr = { src: el.getAttribute('src') };\n // Check old content format and get the width from the parent element\n if (el.parentElement?.className.includes('image-container')) {\n if (el.parentElement.style?.width) {\n attr['width'] = el.parentElement.style.width;\n }\n }\n if (el.style?.width) {\n attr['width'] = el.style.width;\n }\n\n // Check old content smiley\n const oldSmileyList = [\n 'happy',\n 'proud',\n 'dreamy',\n 'love',\n 'tired',\n 'angry',\n 'worried',\n 'sick',\n 'joker',\n 'sad',\n ];\n if (\n oldSmileyList.filter((smiley) => attr.src.includes(smiley + '.png'))\n .length > 0\n ) {\n attr['style'] = {\n width: '1.5em',\n height: '1.5em',\n fontSize: '16px',\n };\n attr['width'] = 'null';\n attr['height'] = 'null';\n }\n\n return attr;\n },\n },\n ];\n },\n\n renderHTML({ HTMLAttributes }) {\n return [\n 'img',\n mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),\n ];\n },\n\n addInputRules() {\n return [\n nodeInputRule({\n find: IMAGE_INPUT_REGEX,\n type: this.type,\n getAttributes: (match) => {\n const [, , alt, src, title] = match;\n\n return {\n src,\n alt,\n title,\n };\n },\n }),\n ];\n },\n\n addCommands() {\n return {\n // Inherit TiptapImage's own setImage (scoped to `this.name`, i.e.\n // 'custom-image') - same bug class as heading.ts: without this spread,\n // addCommands() replaces rather than extends the parent's commands.\n ...this.parent?.(),\n setNewImage:\n (attrs) =>\n ({ tr, dispatch }) => {\n const { selection } = tr;\n const node = this.type.create(attrs);\n\n if (dispatch) {\n tr.replaceRangeWith(selection.from, selection.to, node);\n }\n\n return true;\n },\n };\n },\n\n addProseMirrorPlugins() {\n const uploadNode = async (file: File) => {\n /**\n * Resize the image\n */\n const resizedImage = await ImageResizer.resizeImageFile(file);\n\n /**\n * Upload the image\n */\n const image = await this.options.uploadFile(resizedImage);\n\n /**\n * Get the image url\n */\n const imageUrl = `/workspace/${image.public ? 'pub/' : ''}document/${\n image._id\n }?timestamp=${new Date().getTime()}`;\n\n /**\n * Create the image node\n */\n\n const node = this.type.create({\n src: imageUrl,\n alt: image.alt,\n title: image.title,\n });\n\n return node;\n };\n\n const getFilteredFiles = (files: FileList) => {\n return Array.from(files).filter((file) =>\n /image\\/(png|jpeg|jpg|gif|webp|heic|avif)/.test(file.type),\n );\n };\n\n const handleImageInsert = async (\n editor: any,\n file: File,\n position?: number,\n ) => {\n const node = await uploadNode(file);\n if (!node) return;\n\n const transaction =\n position !== undefined\n ? editor.state.tr.insert(position, node)\n : editor.state.tr.replaceSelectionWith(node);\n\n editor.dispatch(transaction);\n };\n\n return [\n new Plugin({\n props: {\n handlePaste: (editor, e) => {\n const files = getFilteredFiles(e.clipboardData?.files);\n if (files.length === 0) return false;\n\n for (const file of files) {\n handleImageInsert(editor, file);\n }\n\n return true;\n },\n handleDrop: (editor, e, _s, moved) => {\n if (moved) return false;\n\n const files = getFilteredFiles(e.dataTransfer.files);\n if (files.length === 0) return false;\n\n const { pos: position } = editor.posAtCoords({\n left: e.clientX,\n top: e.clientY,\n });\n\n for (const file of files) {\n handleImageInsert(editor, file, position);\n }\n return true;\n },\n },\n }),\n ];\n },\n});\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"image.js","sources":["../../src/image/image.ts"],"sourcesContent":["import { WorkspaceElement } from '@edifice.io/client';\nimport { ImageResizer } from '@edifice.io/utilities';\nimport { mergeAttributes, nodeInputRule } from '@tiptap/core';\nimport TiptapImage from '@tiptap/extension-image';\nimport { Plugin } from 'prosemirror-state';\n\nexport const IMAGE_INPUT_REGEX =\n /(?:^|\\s)(!\\[(.+|:?)]\\((\\S+)(?:(?:\\s+)[\"'](\\S+)[\"'])?\\))$/;\n\nexport interface CustomImageOptions {\n HTMLAttributes: Record<string, string>;\n sizes: string[];\n uploadFile?: (file: File) => Promise<WorkspaceElement | null>;\n}\n\ninterface AttributesProps {\n width: number | string;\n height: number | string;\n size: string;\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n customImage: {\n setAttributes: (options: AttributesProps) => ReturnType;\n setNewImage: (options: {\n src: string;\n alt?: string;\n title?: string;\n }) => ReturnType;\n };\n }\n}\n\nexport const Image = TiptapImage.extend<CustomImageOptions>({\n name: 'custom-image',\n draggable: true,\n selectable: true,\n\n addOptions() {\n return {\n ...this.parent?.(),\n inline: true,\n content: 'inline*',\n sizes: ['small', 'medium', 'large'],\n HTMLAttributes: {\n class: 'custom-image',\n },\n uploadFile: () => {\n return Promise.resolve(null);\n },\n };\n },\n\n addAttributes() {\n return {\n ...this.parent?.(),\n size: {\n default: 'medium',\n rendered: false,\n },\n alt: {\n renderHTML: (attributes) => {\n return {\n alt: attributes.alt,\n };\n },\n parseHTML: (element) => element.getAttribute('alt'),\n },\n title: {\n renderHTML: (attributes) => {\n return {\n title: attributes.title,\n };\n },\n parseHTML: (element) => element.getAttribute('title'),\n },\n width: {\n default: '350',\n renderHTML: (attributes) => {\n if (\n attributes.width !== null &&\n attributes.width !== undefined &&\n !Number.isNaN(attributes.width)\n ) {\n return {\n width: parseInt(attributes.width),\n };\n }\n return {};\n },\n parseHTML: (element) => element.getAttribute('width'),\n },\n height: {\n renderHTML: (attributes) => {\n if (\n attributes.height !== null &&\n attributes.height !== undefined &&\n !Number.isNaN(attributes.height)\n ) {\n return {\n height: parseInt(attributes.height),\n };\n }\n return {};\n },\n parseHTML: (element) => element.getAttribute('height'),\n },\n style: {\n renderHTML: (attributes) => {\n return attributes.style\n ? {\n style: attributes.style,\n }\n : {};\n },\n parseHTML: () => {\n return null;\n },\n },\n };\n },\n\n parseHTML() {\n return [\n {\n tag: 'img[src]:not([src^=\"data:\"])',\n getAttrs: (el: HTMLImageElement) => {\n const attr = { src: el.getAttribute('src') };\n // Check old content format and get the width from the parent element\n if (el.parentElement?.className.includes('image-container')) {\n if (el.parentElement.style?.width) {\n attr['width'] = el.parentElement.style.width;\n }\n }\n if (el.style?.width) {\n attr['width'] = el.style.width;\n }\n\n // Check old content smiley\n const oldSmileyList = [\n 'happy',\n 'proud',\n 'dreamy',\n 'love',\n 'tired',\n 'angry',\n 'worried',\n 'sick',\n 'joker',\n 'sad',\n ];\n if (\n oldSmileyList.filter((smiley) => attr.src.includes(smiley + '.png'))\n .length > 0\n ) {\n attr['style'] = {\n width: '1.5em',\n height: '1.5em',\n fontSize: '16px',\n };\n attr['width'] = 'null';\n attr['height'] = 'null';\n }\n\n return attr;\n },\n },\n ];\n },\n\n renderHTML({ HTMLAttributes }) {\n return [\n 'img',\n mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),\n ];\n },\n\n addInputRules() {\n return [\n nodeInputRule({\n find: IMAGE_INPUT_REGEX,\n type: this.type,\n getAttributes: (match) => {\n const [, , alt, src, title] = match;\n\n return {\n src,\n alt,\n title,\n };\n },\n }),\n ];\n },\n\n addCommands() {\n return {\n setNewImage:\n (attrs) =>\n ({ tr, dispatch }) => {\n const { selection } = tr;\n const node = this.type.create(attrs);\n\n if (dispatch) {\n tr.replaceRangeWith(selection.from, selection.to, node);\n }\n\n return true;\n },\n setAttributes:\n (attributes) =>\n ({ tr, dispatch }) => {\n const { selection } = tr;\n\n const nodeAttrs = tr.doc.nodeAt(tr.selection.from);\n const options = {\n ...nodeAttrs.attrs,\n ...attributes,\n };\n const node = this.type.create(options);\n\n if (dispatch) {\n tr.replaceRangeWith(selection.from, selection.to, node);\n }\n\n return true;\n },\n };\n },\n\n addProseMirrorPlugins() {\n const uploadNode = async (file: File) => {\n /**\n * Resize the image\n */\n const resizedImage = await ImageResizer.resizeImageFile(file);\n\n /**\n * Upload the image\n */\n const image = await this.options.uploadFile(resizedImage);\n\n /**\n * Get the image url\n */\n const imageUrl = `/workspace/${image.public ? 'pub/' : ''}document/${\n image._id\n }?timestamp=${new Date().getTime()}`;\n\n /**\n * Create the image node\n */\n\n const node = this.type.create({\n src: imageUrl,\n alt: image.alt,\n title: image.title,\n });\n\n return node;\n };\n\n const getFilteredFiles = (files: FileList) => {\n return Array.from(files).filter((file) =>\n /image\\/(png|jpeg|jpg|gif|webp|heic|avif)/.test(file.type),\n );\n };\n\n const handleImageInsert = async (\n editor: any,\n file: File,\n position?: number,\n ) => {\n const node = await uploadNode(file);\n if (!node) return;\n\n const transaction =\n position !== undefined\n ? editor.state.tr.insert(position, node)\n : editor.state.tr.replaceSelectionWith(node);\n\n editor.dispatch(transaction);\n };\n\n return [\n new Plugin({\n props: {\n handlePaste: (editor, e) => {\n const files = getFilteredFiles(e.clipboardData?.files);\n if (files.length === 0) return false;\n\n for (const file of files) {\n handleImageInsert(editor, file);\n }\n\n return true;\n },\n handleDrop: (editor, e, _s, moved) => {\n if (moved) return false;\n\n const files = getFilteredFiles(e.dataTransfer.files);\n if (files.length === 0) return false;\n\n const { pos: position } = editor.posAtCoords({\n left: e.clientX,\n top: e.clientY,\n });\n\n for (const file of files) {\n handleImageInsert(editor, file, position);\n }\n return true;\n },\n },\n }),\n ];\n },\n});\n"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const core=require("@tiptap/core"),Linker=core.Node.create({name:"linker",content:"text*",marks:"",group:"inline",inline:!0,selectable:!0,atom:!0,draggable:!0,isolating:!0,allowGapCursor:!1,priority:1100,addOptions(){return{openOnClick:!0,HTMLAttributes:{target:null,title:null,class:null,"data-id":null,"data-app-prefix":null},validate:void 0}},addAttributes(){return{href:{default:null},class:{default:this.options.HTMLAttributes.class},target:{default:this.options.HTMLAttributes.target,parseHTML:element=>element.getAttribute("target")!=="_blank"?null:"_blank"},title:{default:this.options.HTMLAttributes.title},"data-id":{default:this.options.HTMLAttributes["data-id"]},"data-app-prefix":{default:this.options.HTMLAttributes["data-app-prefix"]}}},parseHTML(){return[{tag:'a[href]:not([href *= "javascript:" i])[data-id][data-app-prefix]'}]},renderHTML({HTMLAttributes}){var _a;return(_a=HTMLAttributes.href)!=null&&_a.startsWith("javascript:")?["a",core.mergeAttributes(this.options.HTMLAttributes,{...HTMLAttributes,href:""}),0]:["a",core.mergeAttributes(this.options.HTMLAttributes,HTMLAttributes),0]},addCommands(){return{setLinker:attrs=>({commands})=>(commands.insertContent({type:this.name,attrs,content:[{type:"text",text:attrs.title}]}),!0),unsetLinker:()=>({state,tr})=>{const{node,from,to}=state.selection;return(node==null?void 0:node.type.name)==="linker"&&tr.delete(from,to).scrollIntoView(),!0}}}});exports.Linker=Linker;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const core=require("@tiptap/core"),Linker=core.Node.create({name:"linker",content:"text*",marks:"",group:"inline",inline:!0,selectable:!0,atom:!0,draggable:!0,isolating:!0,allowGapCursor:!1,priority:1100,keepOnSplit:!1,addOptions(){return{openOnClick:!0,HTMLAttributes:{target:null,title:null,class:null,"data-id":null,"data-app-prefix":null},validate:void 0}},addAttributes(){return{href:{default:null},class:{default:this.options.HTMLAttributes.class},target:{default:this.options.HTMLAttributes.target,parseHTML:element=>element.getAttribute("target")!=="_blank"?null:"_blank"},title:{default:this.options.HTMLAttributes.title},"data-id":{default:this.options.HTMLAttributes["data-id"]},"data-app-prefix":{default:this.options.HTMLAttributes["data-app-prefix"]}}},parseHTML(){return[{tag:'a[href]:not([href *= "javascript:" i])[data-id][data-app-prefix]'}]},renderHTML({HTMLAttributes}){var _a;return(_a=HTMLAttributes.href)!=null&&_a.startsWith("javascript:")?["a",core.mergeAttributes(this.options.HTMLAttributes,{...HTMLAttributes,href:""}),0]:["a",core.mergeAttributes(this.options.HTMLAttributes,HTMLAttributes),0]},addCommands(){return{setLinker:attrs=>({commands})=>(commands.insertContent({type:this.name,attrs,content:[{type:"text",text:attrs.title}]}),!0),unsetLinker:()=>({state,tr})=>{const{node,from,to}=state.selection;return(node==null?void 0:node.type.name)==="linker"&&tr.delete(from,to).scrollIntoView(),!0}}}});exports.Linker=Linker;
2
2
  //# sourceMappingURL=linker.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"linker.cjs","sources":["../../src/linker/linker.ts"],"sourcesContent":["import { Node, mergeAttributes } from '@tiptap/core';\nimport { NodeSelection } from '@tiptap/pm/state';\n\n/* Our own model of a link in a rich document. */\nexport type LinkerAttributes = {\n 'href': string | null;\n 'target': '_blank' | null;\n 'title': string | null;\n 'data-id': string | null;\n 'data-app-prefix': string | null;\n};\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n linker: {\n /**\n * Set a linker node\n */\n setLinker: (attributes: LinkerAttributes) => ReturnType;\n /**\n * Unset a linker node\n */\n unsetLinker: () => ReturnType;\n };\n }\n}\n\n/**\n * Internal links extension.\n * Reproduces the legacy angularJs \"linker\" directive.\n *\n * Links to internal resources MAY have a `title` and MUST HAVE `data-id` and `data-app-prefix` attributes :\n * `<a href=\"/blog#/view/35fa4198-blog_id/5e654c71-article_id\" data-app-prefix=\"blog\" data-id=\"35fa4198-blog_id\" target=\"_blank\" title=\"Voir ce billet de blog\" class=\"ng-scope\">/blog#/view/35fa4198-57fe-45eb-94f4-a5e4defff305/5e654c71-1e61-4f84-86dc-6fcfaf33f513</a>`\n */\nexport const Linker = Node.create({\n name: 'linker',\n content: 'text*',\n marks: '',\n group: 'inline',\n\n inline: true,\n selectable: true,\n atom: true,\n draggable: true,\n isolating: true,\n allowGapCursor: false,\n\n priority: 1100,\n\n addOptions() {\n return {\n openOnClick: true,\n HTMLAttributes: {\n 'target': null,\n 'title': null,\n 'class': null,\n 'data-id': null,\n 'data-app-prefix': null,\n },\n validate: undefined,\n };\n },\n\n addAttributes() {\n return {\n 'href': {\n default: null,\n },\n 'class': {\n default: this.options.HTMLAttributes.class,\n },\n 'target': {\n default: this.options.HTMLAttributes.target,\n // Sanitize target value\n parseHTML: (element) =>\n element.getAttribute('target') !== '_blank' ? null : '_blank',\n },\n 'title': {\n default: this.options.HTMLAttributes.title,\n },\n 'data-id': {\n default: this.options.HTMLAttributes['data-id'],\n },\n 'data-app-prefix': {\n default: this.options.HTMLAttributes['data-app-prefix'],\n },\n };\n },\n\n parseHTML() {\n return [\n {\n tag: 'a[href]:not([href *= \"javascript:\" i])[data-id][data-app-prefix]',\n },\n ];\n },\n\n renderHTML({ HTMLAttributes }) {\n if (HTMLAttributes.href?.startsWith('javascript:')) {\n return [\n 'a',\n mergeAttributes(this.options.HTMLAttributes, {\n ...HTMLAttributes,\n href: '',\n }),\n 0,\n ];\n }\n return [\n 'a',\n mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),\n 0,\n ];\n },\n\n addCommands() {\n return {\n setLinker:\n (attrs) =>\n ({ commands }) => {\n // Insert a Linker node with inner text node\n commands.insertContent({\n type: this.name,\n attrs,\n content: [\n {\n type: 'text',\n text: attrs.title,\n },\n ],\n });\n return true;\n },\n\n unsetLinker:\n () =>\n ({ state, tr }) => {\n // Which Linker node is actually selected ?\n const { node, from, to } = state.selection as NodeSelection;\n // Delete any selected Linker node\n if (node?.type.name === 'linker') {\n /* The following does not work as one would expected.\n commands.deleteNode(this.name);\n commands.deleteCurrentNode();\n * Replaced by : */\n tr.delete(from, to).scrollIntoView();\n }\n return true;\n },\n };\n },\n});\n"],"names":["Node","mergeAttributes"],"mappings":"mHAkCa,OAASA,KAAAA,KAAK,OAAO,CAChC,KAAM,SACN,QAAS,QACT,MAAO,GACP,MAAO,SAEP,OAAQ,GACR,WAAY,GACZ,KAAM,GACN,UAAW,GACX,UAAW,GACX,eAAgB,GAEhB,SAAU,KAEV,YAAa,CACX,MAAO,CACL,YAAa,GACb,eAAgB,CACd,OAAU,KACV,MAAS,KACT,MAAS,KACT,UAAW,KACX,kBAAmB,IAAA,EAErB,SAAU,MAAA,CAEd,EAEA,eAAgB,CACd,MAAO,CACL,KAAQ,CACN,QAAS,IAAA,EAEX,MAAS,CACP,QAAS,KAAK,QAAQ,eAAe,KAAA,EAEvC,OAAU,CACR,QAAS,KAAK,QAAQ,eAAe,OAErC,UAAY,SACV,QAAQ,aAAa,QAAQ,IAAM,SAAW,KAAO,QAAA,EAEzD,MAAS,CACP,QAAS,KAAK,QAAQ,eAAe,KAAA,EAEvC,UAAW,CACT,QAAS,KAAK,QAAQ,eAAe,SAAS,CAAA,EAEhD,kBAAmB,CACjB,QAAS,KAAK,QAAQ,eAAe,iBAAiB,CAAA,CACxD,CAEJ,EAEA,WAAY,CACV,MAAO,CACL,CACE,IAAK,kEAAA,CACP,CAEJ,EAEA,WAAW,CAAE,gBAAkB,QAC7B,OAAI,kBAAe,OAAf,SAAqB,WAAW,eAC3B,CACL,IACAC,qBAAgB,KAAK,QAAQ,eAAgB,CAC3C,GAAG,eACH,KAAM,EAAA,CACP,EACD,CAAA,EAGG,CACL,IACAA,KAAAA,gBAAgB,KAAK,QAAQ,eAAgB,cAAc,EAC3D,CAAA,CAEJ,EAEA,aAAc,CACZ,MAAO,CACL,UACG,OACD,CAAC,CAAE,aAED,SAAS,cAAc,CACrB,KAAM,KAAK,KACX,MACA,QAAS,CACP,CACE,KAAM,OACN,KAAM,MAAM,KAAA,CACd,CACF,CACD,EACM,IAGX,YACE,IACA,CAAC,CAAE,MAAO,MAAS,CAEjB,KAAM,CAAE,KAAM,KAAM,EAAA,EAAO,MAAM,UAEjC,OAAI,uBAAM,KAAK,QAAS,UAKtB,GAAG,OAAO,KAAM,EAAE,EAAE,eAAA,EAEf,EACT,CAAA,CAEN,CACF,CAAC"}
1
+ {"version":3,"file":"linker.cjs","sources":["../../src/linker/linker.ts"],"sourcesContent":["import { Node, mergeAttributes } from '@tiptap/core';\nimport { NodeSelection } from '@tiptap/pm/state';\n\n/* Our own model of a link in a rich document. */\nexport type LinkerAttributes = {\n 'href': string | null;\n 'target': '_blank' | null;\n 'title': string | null;\n 'data-id': string | null;\n 'data-app-prefix': string | null;\n};\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n linker: {\n /**\n * Set a linker node\n */\n setLinker: (attributes: LinkerAttributes) => ReturnType;\n /**\n * Unset a linker node\n */\n unsetLinker: () => ReturnType;\n };\n }\n}\n\n/**\n * Internal links extension.\n * Reproduces the legacy angularJs \"linker\" directive.\n *\n * Links to internal resources MAY have a `title` and MUST HAVE `data-id` and `data-app-prefix` attributes :\n * `<a href=\"/blog#/view/35fa4198-blog_id/5e654c71-article_id\" data-app-prefix=\"blog\" data-id=\"35fa4198-blog_id\" target=\"_blank\" title=\"Voir ce billet de blog\" class=\"ng-scope\">/blog#/view/35fa4198-57fe-45eb-94f4-a5e4defff305/5e654c71-1e61-4f84-86dc-6fcfaf33f513</a>`\n */\nexport const Linker = Node.create({\n name: 'linker',\n content: 'text*',\n marks: '',\n group: 'inline',\n\n inline: true,\n selectable: true,\n atom: true,\n draggable: true,\n isolating: true,\n allowGapCursor: false,\n\n priority: 1100,\n keepOnSplit: false,\n\n addOptions() {\n return {\n openOnClick: true,\n HTMLAttributes: {\n 'target': null,\n 'title': null,\n 'class': null,\n 'data-id': null,\n 'data-app-prefix': null,\n },\n validate: undefined,\n };\n },\n\n addAttributes() {\n return {\n 'href': {\n default: null,\n },\n 'class': {\n default: this.options.HTMLAttributes.class,\n },\n 'target': {\n default: this.options.HTMLAttributes.target,\n // Sanitize target value\n parseHTML: (element) =>\n element.getAttribute('target') !== '_blank' ? null : '_blank',\n },\n 'title': {\n default: this.options.HTMLAttributes.title,\n },\n 'data-id': {\n default: this.options.HTMLAttributes['data-id'],\n },\n 'data-app-prefix': {\n default: this.options.HTMLAttributes['data-app-prefix'],\n },\n };\n },\n\n parseHTML() {\n return [\n {\n tag: 'a[href]:not([href *= \"javascript:\" i])[data-id][data-app-prefix]',\n },\n ];\n },\n\n renderHTML({ HTMLAttributes }) {\n if (HTMLAttributes.href?.startsWith('javascript:')) {\n return [\n 'a',\n mergeAttributes(this.options.HTMLAttributes, {\n ...HTMLAttributes,\n href: '',\n }),\n 0,\n ];\n }\n return [\n 'a',\n mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),\n 0,\n ];\n },\n\n addCommands() {\n return {\n setLinker:\n (attrs) =>\n ({ commands }) => {\n // Insert a Linker node with inner text node\n commands.insertContent({\n type: this.name,\n attrs,\n content: [\n {\n type: 'text',\n text: attrs.title,\n },\n ],\n });\n return true;\n },\n\n unsetLinker:\n () =>\n ({ state, tr }) => {\n // Which Linker node is actually selected ?\n const { node, from, to } = state.selection as NodeSelection;\n // Delete any selected Linker node\n if (node?.type.name === 'linker') {\n /* The following does not work as one would expected.\n commands.deleteNode(this.name);\n commands.deleteCurrentNode();\n * Replaced by : */\n tr.delete(from, to).scrollIntoView();\n }\n return true;\n },\n };\n },\n});\n"],"names":["Node","mergeAttributes"],"mappings":"mHAkCa,OAASA,KAAAA,KAAK,OAAO,CAChC,KAAM,SACN,QAAS,QACT,MAAO,GACP,MAAO,SAEP,OAAQ,GACR,WAAY,GACZ,KAAM,GACN,UAAW,GACX,UAAW,GACX,eAAgB,GAEhB,SAAU,KACV,YAAa,GAEb,YAAa,CACX,MAAO,CACL,YAAa,GACb,eAAgB,CACd,OAAU,KACV,MAAS,KACT,MAAS,KACT,UAAW,KACX,kBAAmB,IAAA,EAErB,SAAU,MAAA,CAEd,EAEA,eAAgB,CACd,MAAO,CACL,KAAQ,CACN,QAAS,IAAA,EAEX,MAAS,CACP,QAAS,KAAK,QAAQ,eAAe,KAAA,EAEvC,OAAU,CACR,QAAS,KAAK,QAAQ,eAAe,OAErC,UAAY,SACV,QAAQ,aAAa,QAAQ,IAAM,SAAW,KAAO,QAAA,EAEzD,MAAS,CACP,QAAS,KAAK,QAAQ,eAAe,KAAA,EAEvC,UAAW,CACT,QAAS,KAAK,QAAQ,eAAe,SAAS,CAAA,EAEhD,kBAAmB,CACjB,QAAS,KAAK,QAAQ,eAAe,iBAAiB,CAAA,CACxD,CAEJ,EAEA,WAAY,CACV,MAAO,CACL,CACE,IAAK,kEAAA,CACP,CAEJ,EAEA,WAAW,CAAE,gBAAkB,QAC7B,OAAI,kBAAe,OAAf,SAAqB,WAAW,eAC3B,CACL,IACAC,qBAAgB,KAAK,QAAQ,eAAgB,CAC3C,GAAG,eACH,KAAM,EAAA,CACP,EACD,CAAA,EAGG,CACL,IACAA,KAAAA,gBAAgB,KAAK,QAAQ,eAAgB,cAAc,EAC3D,CAAA,CAEJ,EAEA,aAAc,CACZ,MAAO,CACL,UACG,OACD,CAAC,CAAE,aAED,SAAS,cAAc,CACrB,KAAM,KAAK,KACX,MACA,QAAS,CACP,CACE,KAAM,OACN,KAAM,MAAM,KAAA,CACd,CACF,CACD,EACM,IAGX,YACE,IACA,CAAC,CAAE,MAAO,MAAS,CAEjB,KAAM,CAAE,KAAM,KAAM,EAAA,EAAO,MAAM,UAEjC,OAAI,uBAAM,KAAK,QAAS,UAKtB,GAAG,OAAO,KAAM,EAAE,EAAE,eAAA,EAEf,EACT,CAAA,CAEN,CACF,CAAC"}
@@ -11,6 +11,7 @@ const Linker = Node.create({
11
11
  isolating: !0,
12
12
  allowGapCursor: !1,
13
13
  priority: 1100,
14
+ keepOnSplit: !1,
14
15
  addOptions() {
15
16
  return {
16
17
  openOnClick: !0,
@@ -1 +1 @@
1
- {"version":3,"file":"linker.js","sources":["../../src/linker/linker.ts"],"sourcesContent":["import { Node, mergeAttributes } from '@tiptap/core';\nimport { NodeSelection } from '@tiptap/pm/state';\n\n/* Our own model of a link in a rich document. */\nexport type LinkerAttributes = {\n 'href': string | null;\n 'target': '_blank' | null;\n 'title': string | null;\n 'data-id': string | null;\n 'data-app-prefix': string | null;\n};\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n linker: {\n /**\n * Set a linker node\n */\n setLinker: (attributes: LinkerAttributes) => ReturnType;\n /**\n * Unset a linker node\n */\n unsetLinker: () => ReturnType;\n };\n }\n}\n\n/**\n * Internal links extension.\n * Reproduces the legacy angularJs \"linker\" directive.\n *\n * Links to internal resources MAY have a `title` and MUST HAVE `data-id` and `data-app-prefix` attributes :\n * `<a href=\"/blog#/view/35fa4198-blog_id/5e654c71-article_id\" data-app-prefix=\"blog\" data-id=\"35fa4198-blog_id\" target=\"_blank\" title=\"Voir ce billet de blog\" class=\"ng-scope\">/blog#/view/35fa4198-57fe-45eb-94f4-a5e4defff305/5e654c71-1e61-4f84-86dc-6fcfaf33f513</a>`\n */\nexport const Linker = Node.create({\n name: 'linker',\n content: 'text*',\n marks: '',\n group: 'inline',\n\n inline: true,\n selectable: true,\n atom: true,\n draggable: true,\n isolating: true,\n allowGapCursor: false,\n\n priority: 1100,\n\n addOptions() {\n return {\n openOnClick: true,\n HTMLAttributes: {\n 'target': null,\n 'title': null,\n 'class': null,\n 'data-id': null,\n 'data-app-prefix': null,\n },\n validate: undefined,\n };\n },\n\n addAttributes() {\n return {\n 'href': {\n default: null,\n },\n 'class': {\n default: this.options.HTMLAttributes.class,\n },\n 'target': {\n default: this.options.HTMLAttributes.target,\n // Sanitize target value\n parseHTML: (element) =>\n element.getAttribute('target') !== '_blank' ? null : '_blank',\n },\n 'title': {\n default: this.options.HTMLAttributes.title,\n },\n 'data-id': {\n default: this.options.HTMLAttributes['data-id'],\n },\n 'data-app-prefix': {\n default: this.options.HTMLAttributes['data-app-prefix'],\n },\n };\n },\n\n parseHTML() {\n return [\n {\n tag: 'a[href]:not([href *= \"javascript:\" i])[data-id][data-app-prefix]',\n },\n ];\n },\n\n renderHTML({ HTMLAttributes }) {\n if (HTMLAttributes.href?.startsWith('javascript:')) {\n return [\n 'a',\n mergeAttributes(this.options.HTMLAttributes, {\n ...HTMLAttributes,\n href: '',\n }),\n 0,\n ];\n }\n return [\n 'a',\n mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),\n 0,\n ];\n },\n\n addCommands() {\n return {\n setLinker:\n (attrs) =>\n ({ commands }) => {\n // Insert a Linker node with inner text node\n commands.insertContent({\n type: this.name,\n attrs,\n content: [\n {\n type: 'text',\n text: attrs.title,\n },\n ],\n });\n return true;\n },\n\n unsetLinker:\n () =>\n ({ state, tr }) => {\n // Which Linker node is actually selected ?\n const { node, from, to } = state.selection as NodeSelection;\n // Delete any selected Linker node\n if (node?.type.name === 'linker') {\n /* The following does not work as one would expected.\n commands.deleteNode(this.name);\n commands.deleteCurrentNode();\n * Replaced by : */\n tr.delete(from, to).scrollIntoView();\n }\n return true;\n },\n };\n },\n});\n"],"names":[],"mappings":";AAkCO,MAAM,SAAS,KAAK,OAAO;AAAA,EAChC,MAAM;AAAA,EACN,SAAS;AAAA,EACT,OAAO;AAAA,EACP,OAAO;AAAA,EAEP,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,MAAM;AAAA,EACN,WAAW;AAAA,EACX,WAAW;AAAA,EACX,gBAAgB;AAAA,EAEhB,UAAU;AAAA,EAEV,aAAa;AACX,WAAO;AAAA,MACL,aAAa;AAAA,MACb,gBAAgB;AAAA,QACd,QAAU;AAAA,QACV,OAAS;AAAA,QACT,OAAS;AAAA,QACT,WAAW;AAAA,QACX,mBAAmB;AAAA,MAAA;AAAA,MAErB,UAAU;AAAA,IAAA;AAAA,EAEd;AAAA,EAEA,gBAAgB;AACd,WAAO;AAAA,MACL,MAAQ;AAAA,QACN,SAAS;AAAA,MAAA;AAAA,MAEX,OAAS;AAAA,QACP,SAAS,KAAK,QAAQ,eAAe;AAAA,MAAA;AAAA,MAEvC,QAAU;AAAA,QACR,SAAS,KAAK,QAAQ,eAAe;AAAA;AAAA,QAErC,WAAW,CAAC,YACV,QAAQ,aAAa,QAAQ,MAAM,WAAW,OAAO;AAAA,MAAA;AAAA,MAEzD,OAAS;AAAA,QACP,SAAS,KAAK,QAAQ,eAAe;AAAA,MAAA;AAAA,MAEvC,WAAW;AAAA,QACT,SAAS,KAAK,QAAQ,eAAe,SAAS;AAAA,MAAA;AAAA,MAEhD,mBAAmB;AAAA,QACjB,SAAS,KAAK,QAAQ,eAAe,iBAAiB;AAAA,MAAA;AAAA,IACxD;AAAA,EAEJ;AAAA,EAEA,YAAY;AACV,WAAO;AAAA,MACL;AAAA,QACE,KAAK;AAAA,MAAA;AAAA,IACP;AAAA,EAEJ;AAAA,EAEA,WAAW,EAAE,kBAAkB;;AAC7B,YAAI,oBAAe,SAAf,WAAqB,WAAW,iBAC3B;AAAA,MACL;AAAA,MACA,gBAAgB,KAAK,QAAQ,gBAAgB;AAAA,QAC3C,GAAG;AAAA,QACH,MAAM;AAAA,MAAA,CACP;AAAA,MACD;AAAA,IAAA,IAGG;AAAA,MACL;AAAA,MACA,gBAAgB,KAAK,QAAQ,gBAAgB,cAAc;AAAA,MAC3D;AAAA,IAAA;AAAA,EAEJ;AAAA,EAEA,cAAc;AACZ,WAAO;AAAA,MACL,WACE,CAAC,UACD,CAAC,EAAE,gBAED,SAAS,cAAc;AAAA,QACrB,MAAM,KAAK;AAAA,QACX;AAAA,QACA,SAAS;AAAA,UACP;AAAA,YACE,MAAM;AAAA,YACN,MAAM,MAAM;AAAA,UAAA;AAAA,QACd;AAAA,MACF,CACD,GACM;AAAA,MAGX,aACE,MACA,CAAC,EAAE,OAAO,SAAS;AAEjB,cAAM,EAAE,MAAM,MAAM,GAAA,IAAO,MAAM;AAEjC,gBAAI,6BAAM,KAAK,UAAS,YAKtB,GAAG,OAAO,MAAM,EAAE,EAAE,eAAA,GAEf;AAAA,MACT;AAAA,IAAA;AAAA,EAEN;AACF,CAAC;"}
1
+ {"version":3,"file":"linker.js","sources":["../../src/linker/linker.ts"],"sourcesContent":["import { Node, mergeAttributes } from '@tiptap/core';\nimport { NodeSelection } from '@tiptap/pm/state';\n\n/* Our own model of a link in a rich document. */\nexport type LinkerAttributes = {\n 'href': string | null;\n 'target': '_blank' | null;\n 'title': string | null;\n 'data-id': string | null;\n 'data-app-prefix': string | null;\n};\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n linker: {\n /**\n * Set a linker node\n */\n setLinker: (attributes: LinkerAttributes) => ReturnType;\n /**\n * Unset a linker node\n */\n unsetLinker: () => ReturnType;\n };\n }\n}\n\n/**\n * Internal links extension.\n * Reproduces the legacy angularJs \"linker\" directive.\n *\n * Links to internal resources MAY have a `title` and MUST HAVE `data-id` and `data-app-prefix` attributes :\n * `<a href=\"/blog#/view/35fa4198-blog_id/5e654c71-article_id\" data-app-prefix=\"blog\" data-id=\"35fa4198-blog_id\" target=\"_blank\" title=\"Voir ce billet de blog\" class=\"ng-scope\">/blog#/view/35fa4198-57fe-45eb-94f4-a5e4defff305/5e654c71-1e61-4f84-86dc-6fcfaf33f513</a>`\n */\nexport const Linker = Node.create({\n name: 'linker',\n content: 'text*',\n marks: '',\n group: 'inline',\n\n inline: true,\n selectable: true,\n atom: true,\n draggable: true,\n isolating: true,\n allowGapCursor: false,\n\n priority: 1100,\n keepOnSplit: false,\n\n addOptions() {\n return {\n openOnClick: true,\n HTMLAttributes: {\n 'target': null,\n 'title': null,\n 'class': null,\n 'data-id': null,\n 'data-app-prefix': null,\n },\n validate: undefined,\n };\n },\n\n addAttributes() {\n return {\n 'href': {\n default: null,\n },\n 'class': {\n default: this.options.HTMLAttributes.class,\n },\n 'target': {\n default: this.options.HTMLAttributes.target,\n // Sanitize target value\n parseHTML: (element) =>\n element.getAttribute('target') !== '_blank' ? null : '_blank',\n },\n 'title': {\n default: this.options.HTMLAttributes.title,\n },\n 'data-id': {\n default: this.options.HTMLAttributes['data-id'],\n },\n 'data-app-prefix': {\n default: this.options.HTMLAttributes['data-app-prefix'],\n },\n };\n },\n\n parseHTML() {\n return [\n {\n tag: 'a[href]:not([href *= \"javascript:\" i])[data-id][data-app-prefix]',\n },\n ];\n },\n\n renderHTML({ HTMLAttributes }) {\n if (HTMLAttributes.href?.startsWith('javascript:')) {\n return [\n 'a',\n mergeAttributes(this.options.HTMLAttributes, {\n ...HTMLAttributes,\n href: '',\n }),\n 0,\n ];\n }\n return [\n 'a',\n mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),\n 0,\n ];\n },\n\n addCommands() {\n return {\n setLinker:\n (attrs) =>\n ({ commands }) => {\n // Insert a Linker node with inner text node\n commands.insertContent({\n type: this.name,\n attrs,\n content: [\n {\n type: 'text',\n text: attrs.title,\n },\n ],\n });\n return true;\n },\n\n unsetLinker:\n () =>\n ({ state, tr }) => {\n // Which Linker node is actually selected ?\n const { node, from, to } = state.selection as NodeSelection;\n // Delete any selected Linker node\n if (node?.type.name === 'linker') {\n /* The following does not work as one would expected.\n commands.deleteNode(this.name);\n commands.deleteCurrentNode();\n * Replaced by : */\n tr.delete(from, to).scrollIntoView();\n }\n return true;\n },\n };\n },\n});\n"],"names":[],"mappings":";AAkCO,MAAM,SAAS,KAAK,OAAO;AAAA,EAChC,MAAM;AAAA,EACN,SAAS;AAAA,EACT,OAAO;AAAA,EACP,OAAO;AAAA,EAEP,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,MAAM;AAAA,EACN,WAAW;AAAA,EACX,WAAW;AAAA,EACX,gBAAgB;AAAA,EAEhB,UAAU;AAAA,EACV,aAAa;AAAA,EAEb,aAAa;AACX,WAAO;AAAA,MACL,aAAa;AAAA,MACb,gBAAgB;AAAA,QACd,QAAU;AAAA,QACV,OAAS;AAAA,QACT,OAAS;AAAA,QACT,WAAW;AAAA,QACX,mBAAmB;AAAA,MAAA;AAAA,MAErB,UAAU;AAAA,IAAA;AAAA,EAEd;AAAA,EAEA,gBAAgB;AACd,WAAO;AAAA,MACL,MAAQ;AAAA,QACN,SAAS;AAAA,MAAA;AAAA,MAEX,OAAS;AAAA,QACP,SAAS,KAAK,QAAQ,eAAe;AAAA,MAAA;AAAA,MAEvC,QAAU;AAAA,QACR,SAAS,KAAK,QAAQ,eAAe;AAAA;AAAA,QAErC,WAAW,CAAC,YACV,QAAQ,aAAa,QAAQ,MAAM,WAAW,OAAO;AAAA,MAAA;AAAA,MAEzD,OAAS;AAAA,QACP,SAAS,KAAK,QAAQ,eAAe;AAAA,MAAA;AAAA,MAEvC,WAAW;AAAA,QACT,SAAS,KAAK,QAAQ,eAAe,SAAS;AAAA,MAAA;AAAA,MAEhD,mBAAmB;AAAA,QACjB,SAAS,KAAK,QAAQ,eAAe,iBAAiB;AAAA,MAAA;AAAA,IACxD;AAAA,EAEJ;AAAA,EAEA,YAAY;AACV,WAAO;AAAA,MACL;AAAA,QACE,KAAK;AAAA,MAAA;AAAA,IACP;AAAA,EAEJ;AAAA,EAEA,WAAW,EAAE,kBAAkB;;AAC7B,YAAI,oBAAe,SAAf,WAAqB,WAAW,iBAC3B;AAAA,MACL;AAAA,MACA,gBAAgB,KAAK,QAAQ,gBAAgB;AAAA,QAC3C,GAAG;AAAA,QACH,MAAM;AAAA,MAAA,CACP;AAAA,MACD;AAAA,IAAA,IAGG;AAAA,MACL;AAAA,MACA,gBAAgB,KAAK,QAAQ,gBAAgB,cAAc;AAAA,MAC3D;AAAA,IAAA;AAAA,EAEJ;AAAA,EAEA,cAAc;AACZ,WAAO;AAAA,MACL,WACE,CAAC,UACD,CAAC,EAAE,gBAED,SAAS,cAAc;AAAA,QACrB,MAAM,KAAK;AAAA,QACX;AAAA,QACA,SAAS;AAAA,UACP;AAAA,YACE,MAAM;AAAA,YACN,MAAM,MAAM;AAAA,UAAA;AAAA,QACd;AAAA,MACF,CACD,GACM;AAAA,MAGX,aACE,MACA,CAAC,EAAE,OAAO,SAAS;AAEjB,cAAM,EAAE,MAAM,MAAM,GAAA,IAAO,MAAM;AAEjC,gBAAI,6BAAM,KAAK,UAAS,YAKtB,GAAG,OAAO,MAAM,EAAE,EAAE,eAAA,GAEf;AAAA,MACT;AAAA,IAAA;AAAA,EAEN;AACF,CAAC;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const extensionTable=require("@tiptap/extension-table"),TableCell=extensionTable.TableCell.extend({addAttributes(){var _a;return{...(_a=this.parent)==null?void 0:_a.call(this),backgroundColor:{default:null,renderHTML:attributes=>attributes.backgroundColor?{style:`background-color: ${attributes.backgroundColor}`}:{},parseHTML:element=>{var _a2,_b;return(_b=(_a2=element.style)==null?void 0:_a2.backgroundColor)==null?void 0:_b.replace(/['"]+/g,"")}}}}});exports.TableCell=TableCell;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const extensionTableCell=require("@tiptap/extension-table-cell"),TableCell=extensionTableCell.TableCell.extend({addAttributes(){var _a;return{...(_a=this.parent)==null?void 0:_a.call(this),backgroundColor:{default:null,renderHTML:attributes=>attributes.backgroundColor?{style:`background-color: ${attributes.backgroundColor}`}:{},parseHTML:element=>{var _a2,_b;return(_b=(_a2=element.style)==null?void 0:_a2.backgroundColor)==null?void 0:_b.replace(/['"]+/g,"")}}}}});exports.TableCell=TableCell;
2
2
  //# sourceMappingURL=table-cell.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"table-cell.cjs","sources":["../../src/table-cell/table-cell.ts"],"sourcesContent":["import { TableCell as TipTapTableCell } from '@tiptap/extension-table';\n\n/**\n * This custom extension allows setting a background-color to table cells.\n * Apply with ̀`editor.chain().focus().setCellAttribute(\"backgroundColor\", color).run()`\n */\nexport const TableCell = TipTapTableCell.extend({\n addAttributes() {\n return {\n ...this.parent?.(),\n backgroundColor: {\n default: null,\n renderHTML: (attributes: { backgroundColor?: string }) => {\n if (!attributes.backgroundColor) {\n return {};\n }\n\n return {\n style: `background-color: ${attributes.backgroundColor}`,\n };\n },\n parseHTML: (element: { style?: { backgroundColor: string } }) => {\n return element.style?.backgroundColor?.replace(/['\"]+/g, '');\n },\n },\n };\n },\n});\n"],"names":["TipTapTableCell","_a"],"mappings":"wIAMa,UAAYA,eAAAA,UAAgB,OAAO,CAC9C,eAAgB,QACd,MAAO,CACL,IAAG,QAAK,SAAL,0BACH,gBAAiB,CACf,QAAS,KACT,WAAa,YACN,WAAW,gBAIT,CACL,MAAO,qBAAqB,WAAW,eAAe,EAAA,EAJ/C,CAAA,EAOX,UAAY,SAAqD,YAC/D,OAAO,IAAAC,IAAA,QAAQ,QAAR,YAAAA,IAAe,kBAAf,eAAgC,QAAQ,SAAU,GAC3D,CAAA,CACF,CAEJ,CACF,CAAC"}
1
+ {"version":3,"file":"table-cell.cjs","sources":["../../src/table-cell/table-cell.ts"],"sourcesContent":["import { TableCell as TipTapTableCell } from '@tiptap/extension-table-cell';\n\n/**\n * This custom extension allows setting a background-color to table cells.\n * Apply with ̀`editor.chain().focus().setCellAttribute(\"backgroundColor\", color).run()`\n */\nexport const TableCell = TipTapTableCell.extend({\n addAttributes() {\n return {\n ...this.parent?.(),\n backgroundColor: {\n default: null,\n renderHTML: (attributes: { backgroundColor?: string }) => {\n if (!attributes.backgroundColor) {\n return {};\n }\n\n return {\n style: `background-color: ${attributes.backgroundColor}`,\n };\n },\n parseHTML: (element: { style?: { backgroundColor: string } }) => {\n return element.style?.backgroundColor?.replace(/['\"]+/g, '');\n },\n },\n };\n },\n});\n"],"names":["TipTapTableCell","_a"],"mappings":"iJAMa,UAAYA,mBAAAA,UAAgB,OAAO,CAC9C,eAAgB,QACd,MAAO,CACL,IAAG,QAAK,SAAL,0BACH,gBAAiB,CACf,QAAS,KACT,WAAa,YACN,WAAW,gBAIT,CACL,MAAO,qBAAqB,WAAW,eAAe,EAAA,EAJ/C,CAAA,EAOX,UAAY,SAAqD,YAC/D,OAAO,IAAAC,IAAA,QAAQ,QAAR,YAAAA,IAAe,kBAAf,eAAgC,QAAQ,SAAU,GAC3D,CAAA,CACF,CAEJ,CACF,CAAC"}
@@ -2,4 +2,4 @@
2
2
  * This custom extension allows setting a background-color to table cells.
3
3
  * Apply with ̀`editor.chain().focus().setCellAttribute("backgroundColor", color).run()`
4
4
  */
5
- export declare const TableCell: import('@tiptap/core').Node<import('@tiptap/extension-table').TableCellOptions, any>;
5
+ export declare const TableCell: import('@tiptap/core').Node<import('@tiptap/extension-table-cell').TableCellOptions, any>;
@@ -1,4 +1,4 @@
1
- import { TableCell as TableCell$1 } from "@tiptap/extension-table";
1
+ import { TableCell as TableCell$1 } from "@tiptap/extension-table-cell";
2
2
  const TableCell = TableCell$1.extend({
3
3
  addAttributes() {
4
4
  var _a;
@@ -1 +1 @@
1
- {"version":3,"file":"table-cell.js","sources":["../../src/table-cell/table-cell.ts"],"sourcesContent":["import { TableCell as TipTapTableCell } from '@tiptap/extension-table';\n\n/**\n * This custom extension allows setting a background-color to table cells.\n * Apply with ̀`editor.chain().focus().setCellAttribute(\"backgroundColor\", color).run()`\n */\nexport const TableCell = TipTapTableCell.extend({\n addAttributes() {\n return {\n ...this.parent?.(),\n backgroundColor: {\n default: null,\n renderHTML: (attributes: { backgroundColor?: string }) => {\n if (!attributes.backgroundColor) {\n return {};\n }\n\n return {\n style: `background-color: ${attributes.backgroundColor}`,\n };\n },\n parseHTML: (element: { style?: { backgroundColor: string } }) => {\n return element.style?.backgroundColor?.replace(/['\"]+/g, '');\n },\n },\n };\n },\n});\n"],"names":["TipTapTableCell","_a"],"mappings":";AAMO,MAAM,YAAYA,YAAgB,OAAO;AAAA,EAC9C,gBAAgB;;AACd,WAAO;AAAA,MACL,IAAG,UAAK,WAAL;AAAA,MACH,iBAAiB;AAAA,QACf,SAAS;AAAA,QACT,YAAY,CAAC,eACN,WAAW,kBAIT;AAAA,UACL,OAAO,qBAAqB,WAAW,eAAe;AAAA,QAAA,IAJ/C,CAAA;AAAA,QAOX,WAAW,CAAC,YAAqD;;AAC/D,kBAAO,MAAAC,MAAA,QAAQ,UAAR,gBAAAA,IAAe,oBAAf,mBAAgC,QAAQ,UAAU;AAAA,QAC3D;AAAA,MAAA;AAAA,IACF;AAAA,EAEJ;AACF,CAAC;"}
1
+ {"version":3,"file":"table-cell.js","sources":["../../src/table-cell/table-cell.ts"],"sourcesContent":["import { TableCell as TipTapTableCell } from '@tiptap/extension-table-cell';\n\n/**\n * This custom extension allows setting a background-color to table cells.\n * Apply with ̀`editor.chain().focus().setCellAttribute(\"backgroundColor\", color).run()`\n */\nexport const TableCell = TipTapTableCell.extend({\n addAttributes() {\n return {\n ...this.parent?.(),\n backgroundColor: {\n default: null,\n renderHTML: (attributes: { backgroundColor?: string }) => {\n if (!attributes.backgroundColor) {\n return {};\n }\n\n return {\n style: `background-color: ${attributes.backgroundColor}`,\n };\n },\n parseHTML: (element: { style?: { backgroundColor: string } }) => {\n return element.style?.backgroundColor?.replace(/['\"]+/g, '');\n },\n },\n };\n },\n});\n"],"names":["TipTapTableCell","_a"],"mappings":";AAMO,MAAM,YAAYA,YAAgB,OAAO;AAAA,EAC9C,gBAAgB;;AACd,WAAO;AAAA,MACL,IAAG,UAAK,WAAL;AAAA,MACH,iBAAiB;AAAA,QACf,SAAS;AAAA,QACT,YAAY,CAAC,eACN,WAAW,kBAIT;AAAA,UACL,OAAO,qBAAqB,WAAW,eAAe;AAAA,QAAA,IAJ/C,CAAA;AAAA,QAOX,WAAW,CAAC,YAAqD;;AAC/D,kBAAO,MAAAC,MAAA,QAAQ,UAAR,gBAAAA,IAAe,oBAAf,mBAAgC,QAAQ,UAAU;AAAA,QAC3D;AAAA,MAAA;AAAA,IACF;AAAA,EAEJ;AACF,CAAC;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edifice.io/tiptap-extensions",
3
- "version": "2.6.10-develop-pedago.20261022145938",
3
+ "version": "2.6.10-develop.20261023111140",
4
4
  "description": "Edifice Rich Text Editor Extensions",
5
5
  "keywords": [
6
6
  "edifice",
@@ -121,61 +121,41 @@
121
121
  "files": [
122
122
  "dist"
123
123
  ],
124
- "peerDependencies": {
125
- "@tiptap/core": "3.32.0",
126
- "@tiptap/extension-blockquote": "3.32.0",
127
- "@tiptap/extension-bold": "3.32.0",
128
- "@tiptap/extension-list": "3.32.0",
129
- "@tiptap/extension-code": "3.32.0",
130
- "@tiptap/extension-code-block": "3.32.0",
131
- "@tiptap/extension-document": "3.32.0",
132
- "@tiptap/extension-hard-break": "3.32.0",
133
- "@tiptap/extension-heading": "3.32.0",
134
- "@tiptap/extension-highlight": "3.32.0",
135
- "@tiptap/extension-horizontal-rule": "3.32.0",
136
- "@tiptap/extension-image": "3.32.0",
137
- "@tiptap/extension-italic": "3.32.0",
138
- "@tiptap/extension-link": "3.32.0",
139
- "@tiptap/extension-paragraph": "3.32.0",
140
- "@tiptap/extension-strike": "3.32.0",
141
- "@tiptap/extension-table": "3.32.0",
142
- "@tiptap/extension-text": "3.32.0",
143
- "@tiptap/extension-text-style": "3.32.0",
144
- "@tiptap/extensions": "3.32.0",
145
- "@tiptap/html": "3.32.0",
146
- "@tiptap/pm": "3.32.0",
147
- "@tiptap/starter-kit": "3.32.0",
148
- "@edifice.io/utilities": "2.6.10-develop-pedago.20261022145938"
124
+ "dependencies": {
125
+ "@tiptap/core": "2.11.0",
126
+ "@tiptap/extension-bold": "2.11.0",
127
+ "@tiptap/extension-document": "2.11.0",
128
+ "@tiptap/extension-heading": "2.11.0",
129
+ "@tiptap/extension-highlight": "2.11.0",
130
+ "@tiptap/extension-image": "2.11.0",
131
+ "@tiptap/extension-link": "2.11.0",
132
+ "@tiptap/extension-paragraph": "2.11.0",
133
+ "@tiptap/extension-table-cell": "2.11.0",
134
+ "@tiptap/extension-text": "2.11.0",
135
+ "@tiptap/extension-text-style": "2.11.0",
136
+ "@tiptap/extension-blockquote": "2.11.0",
137
+ "@tiptap/extension-bullet-list": "2.11.0",
138
+ "@tiptap/extension-code": "2.11.0",
139
+ "@tiptap/extension-code-block": "2.11.0",
140
+ "@tiptap/extension-dropcursor": "2.11.0",
141
+ "@tiptap/extension-gapcursor": "2.11.0",
142
+ "@tiptap/extension-hard-break": "2.11.0",
143
+ "@tiptap/extension-history": "2.11.0",
144
+ "@tiptap/extension-horizontal-rule": "2.11.0",
145
+ "@tiptap/extension-italic": "2.11.0",
146
+ "@tiptap/extension-ordered-list": "2.11.0",
147
+ "@tiptap/extension-strike": "2.11.0",
148
+ "@tiptap/html": "2.11.0",
149
+ "@tiptap/pm": "2.11.0",
150
+ "@tiptap/starter-kit": "2.11.0",
151
+ "prosemirror-state": "^1.4.3",
152
+ "vite": "5.4.14",
153
+ "vite-plugin-dts": "4.5.4",
154
+ "@edifice.io/utilities": "2.6.10-develop.20261023111140"
149
155
  },
150
156
  "devDependencies": {
151
- "@tiptap/core": "3.32.0",
152
- "@tiptap/extension-blockquote": "3.32.0",
153
- "@tiptap/extension-bold": "3.32.0",
154
- "@tiptap/extension-list": "3.32.0",
155
- "@tiptap/extension-code": "3.32.0",
156
- "@tiptap/extension-code-block": "3.32.0",
157
- "@tiptap/extension-document": "3.32.0",
158
- "@tiptap/extension-hard-break": "3.32.0",
159
- "@tiptap/extension-heading": "3.32.0",
160
- "@tiptap/extension-highlight": "3.32.0",
161
- "@tiptap/extension-horizontal-rule": "3.32.0",
162
- "@tiptap/extension-image": "3.32.0",
163
- "@tiptap/extension-italic": "3.32.0",
164
- "@tiptap/extension-link": "3.32.0",
165
- "@tiptap/extension-paragraph": "3.32.0",
166
- "@tiptap/extension-strike": "3.32.0",
167
- "@tiptap/extension-table": "3.32.0",
168
- "@tiptap/extension-text": "3.32.0",
169
- "@tiptap/extension-text-style": "3.32.0",
170
- "@tiptap/extensions": "3.32.0",
171
- "@tiptap/html": "3.32.0",
172
- "@tiptap/pm": "3.32.0",
173
- "@tiptap/starter-kit": "3.32.0",
174
157
  "@types/dom-speech-recognition": "0.0.1",
175
- "vite": "5.4.14",
176
- "vite-plugin-dts": "4.5.4",
177
- "@edifice.io/client": "2.6.10-develop-pedago.20261022145938",
178
- "@edifice.io/utilities": "2.6.10-develop-pedago.20261022145938"
158
+ "@edifice.io/client": "2.6.10-develop.20261023111140"
179
159
  },
180
160
  "publishConfig": {
181
161
  "access": "public"
@@ -185,7 +165,6 @@
185
165
  "fix": "eslint --fix --report-unused-disable-directives --max-warnings 0",
186
166
  "format": "prettier --check \"src/**/*.ts\"",
187
167
  "format:write": "prettier --write \"src/**/*.ts\"",
188
- "lint": "eslint",
189
- "test": "vitest"
168
+ "lint": "eslint"
190
169
  }
191
170
  }
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};