inkpen 0.8.3 → 0.9.1
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.
- checksums.yaml +4 -4
- data/app/assets/javascripts/inkpen/controllers/editor_controller.js +214 -148
- data/app/assets/javascripts/inkpen/index.js +36 -73
- data/app/assets/javascripts/inkpen.bundle.js +103 -103
- data/app/assets/javascripts/inkpen.bundle.js.map +4 -4
- data/lib/inkpen/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 82ea78d50df5410aabd191ea25e49c9ab48af1eef675730800c9da56da7334e3
|
|
4
|
+
data.tar.gz: 8548b3d724fb90ffe29425f21d05262456668ddb3a1de61dd294167b0df1bbc5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bf1b3f8eeff1b7473d36404621c9786447a8dec4298838c4257f666ba3249f0f6000999d39dc8c0876ee0017422d9f18799e57376e0f5ff71e998f756cf635a7
|
|
7
|
+
data.tar.gz: '09ae1684455de6530e3deb50f75c36a853ff8067640c1b9ade012089c2a8595e1f49869e04b5aaeb86d03c327fb8d01e9e74850a32dc6d928b92f43a2c21e129'
|
|
@@ -1,158 +1,224 @@
|
|
|
1
1
|
import { Controller } from "@hotwired/stimulus"
|
|
2
2
|
|
|
3
3
|
// ============================================
|
|
4
|
-
// LAZY LOADING
|
|
4
|
+
// LAZY LOADING — gated by enabled extensions (spec 02 slice B, 0.9.1)
|
|
5
5
|
// ============================================
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
underlineExt,
|
|
36
|
-
subscriptExt,
|
|
37
|
-
superscriptExt,
|
|
38
|
-
youtubeExt,
|
|
39
|
-
characterCountExt,
|
|
40
|
-
bubbleMenuExt,
|
|
41
|
-
// Inkpen custom extensions
|
|
42
|
-
sectionMod,
|
|
43
|
-
preformattedMod,
|
|
44
|
-
slashCommandsMod,
|
|
45
|
-
blockGutterMod,
|
|
46
|
-
dragHandleMod,
|
|
47
|
-
toggleBlockMod,
|
|
48
|
-
columnsMod,
|
|
49
|
-
calloutMod,
|
|
50
|
-
blockCommandsMod,
|
|
51
|
-
enhancedImageMod,
|
|
52
|
-
fileAttachmentMod,
|
|
53
|
-
embedMod,
|
|
54
|
-
advancedTableMod,
|
|
55
|
-
tableOfContentsMod,
|
|
56
|
-
databaseMod,
|
|
57
|
-
documentSectionMod,
|
|
58
|
-
contentEmbedMod
|
|
59
|
-
] = await Promise.all([
|
|
60
|
-
import("@tiptap/core"),
|
|
61
|
-
import("@tiptap/pm/model"),
|
|
62
|
-
import("@tiptap/extension-document"),
|
|
63
|
-
import("@tiptap/starter-kit"),
|
|
64
|
-
import("@tiptap/extension-link"),
|
|
65
|
-
import("@tiptap/extension-placeholder"),
|
|
66
|
-
import("@tiptap/extension-image"),
|
|
67
|
-
import("@tiptap/extension-table"),
|
|
68
|
-
import("@tiptap/extension-table-row"),
|
|
69
|
-
import("@tiptap/extension-table-cell"),
|
|
70
|
-
import("@tiptap/extension-table-header"),
|
|
71
|
-
import("@tiptap/extension-task-list"),
|
|
72
|
-
import("@tiptap/extension-task-item"),
|
|
73
|
-
import("@tiptap/extension-mention"),
|
|
74
|
-
import("@tiptap/extension-code-block-lowlight"),
|
|
75
|
-
import("lowlight"),
|
|
76
|
-
import("@tiptap/extension-typography"),
|
|
77
|
-
import("@tiptap/extension-highlight"),
|
|
78
|
-
import("@tiptap/extension-underline"),
|
|
79
|
-
import("@tiptap/extension-subscript"),
|
|
80
|
-
import("@tiptap/extension-superscript"),
|
|
81
|
-
import("@tiptap/extension-youtube"),
|
|
82
|
-
import("@tiptap/extension-character-count"),
|
|
83
|
-
import("@tiptap/extension-bubble-menu"),
|
|
84
|
-
// Inkpen custom extensions
|
|
85
|
-
import("inkpen/extensions/section"),
|
|
86
|
-
import("inkpen/extensions/preformatted"),
|
|
87
|
-
import("inkpen/extensions/slash_commands"),
|
|
88
|
-
import("inkpen/extensions/block_gutter"),
|
|
89
|
-
import("inkpen/extensions/drag_handle"),
|
|
90
|
-
import("inkpen/extensions/toggle_block"),
|
|
91
|
-
import("inkpen/extensions/columns"),
|
|
92
|
-
import("inkpen/extensions/callout"),
|
|
93
|
-
import("inkpen/extensions/block_commands"),
|
|
94
|
-
import("inkpen/extensions/enhanced_image"),
|
|
95
|
-
import("inkpen/extensions/file_attachment"),
|
|
96
|
-
import("inkpen/extensions/embed"),
|
|
97
|
-
import("inkpen/extensions/advanced_table"),
|
|
98
|
-
import("inkpen/extensions/table_of_contents"),
|
|
99
|
-
import("inkpen/extensions/database"),
|
|
100
|
-
import("inkpen/extensions/document_section"),
|
|
101
|
-
import("inkpen/extensions/content_embed")
|
|
102
|
-
])
|
|
103
|
-
|
|
104
|
-
cachedModules = {
|
|
6
|
+
// TipTap/ProseMirror modules are dynamically imported when the editor
|
|
7
|
+
// connects. Slice A (0.9.0) dropped static-imports from index.js; this
|
|
8
|
+
// slice (B, 0.9.1) gates the dynamic-import set on the editor's
|
|
9
|
+
// `extensions-value` configuration.
|
|
10
|
+
//
|
|
11
|
+
// Module objects returned by this loader still expose every extension
|
|
12
|
+
// class name as a key — buildExtensions destructures all of them and
|
|
13
|
+
// each conditional (`if (enabledExtensions.includes("X"))`) reads the
|
|
14
|
+
// destructured local. If a gated extension is disabled, its key is
|
|
15
|
+
// simply absent (undefined), the conditional is false, and the local
|
|
16
|
+
// is never used.
|
|
17
|
+
//
|
|
18
|
+
// Real byte savings need esbuild `splitting: true` — slice C. This
|
|
19
|
+
// slice trims runtime extension-construction cost only; the bundle
|
|
20
|
+
// still inlines every module the dynamic imports can reach.
|
|
21
|
+
|
|
22
|
+
const cachedModules = new Map()
|
|
23
|
+
|
|
24
|
+
// Always loaded — required by every editor regardless of enabled set.
|
|
25
|
+
async function loadCoreModules() {
|
|
26
|
+
const [tiptapCore, tiptapPmModel, starterKit, placeholderExt, bubbleMenuExt] =
|
|
27
|
+
await Promise.all([
|
|
28
|
+
import("@tiptap/core"),
|
|
29
|
+
import("@tiptap/pm/model"),
|
|
30
|
+
import("@tiptap/starter-kit"),
|
|
31
|
+
import("@tiptap/extension-placeholder"),
|
|
32
|
+
import("@tiptap/extension-bubble-menu")
|
|
33
|
+
])
|
|
34
|
+
return {
|
|
105
35
|
Editor: tiptapCore.Editor,
|
|
106
36
|
DOMSerializer: tiptapPmModel.DOMSerializer,
|
|
107
|
-
Document: documentExt.default,
|
|
108
37
|
StarterKit: starterKit.default,
|
|
109
|
-
Link: linkExt.default,
|
|
110
38
|
Placeholder: placeholderExt.default,
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
39
|
+
BubbleMenu: bubbleMenuExt.default
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// One loader per gated extension name. Each returns the subset of
|
|
44
|
+
// keys it contributes to the merged modules object. Adding a new
|
|
45
|
+
// extension means: (1) add its name + loader here, (2) destructure
|
|
46
|
+
// the new key in buildExtensions, (3) gate its usage there.
|
|
47
|
+
const EXTENSION_LOADERS = {
|
|
48
|
+
forced_document: async () => {
|
|
49
|
+
const m = await import("@tiptap/extension-document")
|
|
50
|
+
return { Document: m.default }
|
|
51
|
+
},
|
|
52
|
+
link: async () => {
|
|
53
|
+
const m = await import("@tiptap/extension-link")
|
|
54
|
+
return { Link: m.default }
|
|
55
|
+
},
|
|
56
|
+
image: async () => {
|
|
57
|
+
const m = await import("@tiptap/extension-image")
|
|
58
|
+
return { Image: m.default }
|
|
59
|
+
},
|
|
60
|
+
table: async () => {
|
|
61
|
+
const [t, tr, tc, th] = await Promise.all([
|
|
62
|
+
import("@tiptap/extension-table"),
|
|
63
|
+
import("@tiptap/extension-table-row"),
|
|
64
|
+
import("@tiptap/extension-table-cell"),
|
|
65
|
+
import("@tiptap/extension-table-header")
|
|
66
|
+
])
|
|
67
|
+
return {
|
|
68
|
+
Table: t.default,
|
|
69
|
+
TableRow: tr.default,
|
|
70
|
+
TableCell: tc.default,
|
|
71
|
+
TableHeader: th.default
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
task_list: async () => {
|
|
75
|
+
const [tl, ti] = await Promise.all([
|
|
76
|
+
import("@tiptap/extension-task-list"),
|
|
77
|
+
import("@tiptap/extension-task-item")
|
|
78
|
+
])
|
|
79
|
+
return { TaskList: tl.default, TaskItem: ti.default }
|
|
80
|
+
},
|
|
81
|
+
mention: async () => {
|
|
82
|
+
const m = await import("@tiptap/extension-mention")
|
|
83
|
+
return { Mention: m.default }
|
|
84
|
+
},
|
|
85
|
+
code_block_syntax: async () => {
|
|
86
|
+
const [cb, low] = await Promise.all([
|
|
87
|
+
import("@tiptap/extension-code-block-lowlight"),
|
|
88
|
+
import("lowlight")
|
|
89
|
+
])
|
|
90
|
+
return {
|
|
91
|
+
CodeBlockLowlight: cb.default,
|
|
92
|
+
common: low.common,
|
|
93
|
+
createLowlight: low.createLowlight
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
typography: async () => {
|
|
97
|
+
const m = await import("@tiptap/extension-typography")
|
|
98
|
+
return { Typography: m.default }
|
|
99
|
+
},
|
|
100
|
+
highlight: async () => {
|
|
101
|
+
const m = await import("@tiptap/extension-highlight")
|
|
102
|
+
return { Highlight: m.default }
|
|
103
|
+
},
|
|
104
|
+
underline: async () => {
|
|
105
|
+
const m = await import("@tiptap/extension-underline")
|
|
106
|
+
return { Underline: m.default }
|
|
107
|
+
},
|
|
108
|
+
subscript: async () => {
|
|
109
|
+
const m = await import("@tiptap/extension-subscript")
|
|
110
|
+
return { Subscript: m.default }
|
|
111
|
+
},
|
|
112
|
+
superscript: async () => {
|
|
113
|
+
const m = await import("@tiptap/extension-superscript")
|
|
114
|
+
return { Superscript: m.default }
|
|
115
|
+
},
|
|
116
|
+
youtube: async () => {
|
|
117
|
+
const m = await import("@tiptap/extension-youtube")
|
|
118
|
+
return { Youtube: m.default }
|
|
119
|
+
},
|
|
120
|
+
character_count: async () => {
|
|
121
|
+
const m = await import("@tiptap/extension-character-count")
|
|
122
|
+
return { CharacterCount: m.default }
|
|
123
|
+
},
|
|
124
|
+
section: async () => {
|
|
125
|
+
const m = await import("inkpen/extensions/section")
|
|
126
|
+
return { Section: m.Section }
|
|
127
|
+
},
|
|
128
|
+
preformatted: async () => {
|
|
129
|
+
const m = await import("inkpen/extensions/preformatted")
|
|
130
|
+
return { Preformatted: m.Preformatted }
|
|
131
|
+
},
|
|
132
|
+
slash_commands: async () => {
|
|
133
|
+
const m = await import("inkpen/extensions/slash_commands")
|
|
134
|
+
return { SlashCommands: m.SlashCommands }
|
|
135
|
+
},
|
|
136
|
+
block_gutter: async () => {
|
|
137
|
+
const m = await import("inkpen/extensions/block_gutter")
|
|
138
|
+
return { BlockGutter: m.BlockGutter }
|
|
139
|
+
},
|
|
140
|
+
drag_handle: async () => {
|
|
141
|
+
const m = await import("inkpen/extensions/drag_handle")
|
|
142
|
+
return { DragHandle: m.DragHandle }
|
|
143
|
+
},
|
|
144
|
+
toggle_block: async () => {
|
|
145
|
+
const m = await import("inkpen/extensions/toggle_block")
|
|
146
|
+
return { ToggleBlock: m.ToggleBlock, ToggleSummary: m.ToggleSummary }
|
|
147
|
+
},
|
|
148
|
+
columns: async () => {
|
|
149
|
+
const m = await import("inkpen/extensions/columns")
|
|
150
|
+
return { Columns: m.Columns, Column: m.Column }
|
|
151
|
+
},
|
|
152
|
+
callout: async () => {
|
|
153
|
+
const m = await import("inkpen/extensions/callout")
|
|
154
|
+
return { Callout: m.Callout }
|
|
155
|
+
},
|
|
156
|
+
block_commands: async () => {
|
|
157
|
+
const m = await import("inkpen/extensions/block_commands")
|
|
158
|
+
return { BlockCommands: m.BlockCommands }
|
|
159
|
+
},
|
|
160
|
+
enhanced_image: async () => {
|
|
161
|
+
const m = await import("inkpen/extensions/enhanced_image")
|
|
162
|
+
return { EnhancedImage: m.EnhancedImage }
|
|
163
|
+
},
|
|
164
|
+
file_attachment: async () => {
|
|
165
|
+
const m = await import("inkpen/extensions/file_attachment")
|
|
166
|
+
return { FileAttachment: m.FileAttachment }
|
|
167
|
+
},
|
|
168
|
+
embed: async () => {
|
|
169
|
+
const m = await import("inkpen/extensions/embed")
|
|
170
|
+
return { Embed: m.Embed }
|
|
171
|
+
},
|
|
172
|
+
advanced_table: async () => {
|
|
173
|
+
const m = await import("inkpen/extensions/advanced_table")
|
|
174
|
+
return {
|
|
175
|
+
AdvancedTable: m.AdvancedTable,
|
|
176
|
+
AdvancedTableRow: m.AdvancedTableRow,
|
|
177
|
+
AdvancedTableCell: m.AdvancedTableCell,
|
|
178
|
+
AdvancedTableHeader: m.AdvancedTableHeader
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
table_of_contents: async () => {
|
|
182
|
+
const m = await import("inkpen/extensions/table_of_contents")
|
|
183
|
+
return { TableOfContents: m.TableOfContents }
|
|
184
|
+
},
|
|
185
|
+
database: async () => {
|
|
186
|
+
const m = await import("inkpen/extensions/database")
|
|
187
|
+
return { Database: m.Database }
|
|
188
|
+
},
|
|
189
|
+
document_section: async () => {
|
|
190
|
+
const m = await import("inkpen/extensions/document_section")
|
|
191
|
+
return { DocumentSection: m.DocumentSection }
|
|
192
|
+
},
|
|
193
|
+
content_embed: async () => {
|
|
194
|
+
const m = await import("inkpen/extensions/content_embed")
|
|
195
|
+
return { ContentEmbed: m.ContentEmbed }
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Exported for tests so they can mock loaders or assert the registry's
|
|
200
|
+
// surface. Not part of the public gem API; the controller is the only
|
|
201
|
+
// production consumer.
|
|
202
|
+
export const __EXTENSION_LOADER_NAMES__ = Object.keys(EXTENSION_LOADERS)
|
|
203
|
+
|
|
204
|
+
async function loadEditorModules(enabledExtensions = []) {
|
|
205
|
+
const enabledSet = new Set(enabledExtensions)
|
|
206
|
+
const cacheKey = [...enabledSet].sort().join(",") || "(empty)"
|
|
207
|
+
if (cachedModules.has(cacheKey)) return cachedModules.get(cacheKey)
|
|
208
|
+
|
|
209
|
+
const core = await loadCoreModules()
|
|
210
|
+
|
|
211
|
+
const gatedPromises = []
|
|
212
|
+
for (const [name, loader] of Object.entries(EXTENSION_LOADERS)) {
|
|
213
|
+
if (enabledSet.has(name)) {
|
|
214
|
+
gatedPromises.push(loader())
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
const gatedResults = await Promise.all(gatedPromises)
|
|
218
|
+
|
|
219
|
+
const modules = Object.assign({}, core, ...gatedResults)
|
|
220
|
+
cachedModules.set(cacheKey, modules)
|
|
221
|
+
return modules
|
|
156
222
|
}
|
|
157
223
|
|
|
158
224
|
// Extensions loaded lazily to prevent import failures from breaking the editor
|
|
@@ -332,7 +398,7 @@ export default class extends Controller {
|
|
|
332
398
|
|
|
333
399
|
async initializeEditor() {
|
|
334
400
|
// Lazy-load all TipTap modules
|
|
335
|
-
this.modules = await loadEditorModules()
|
|
401
|
+
this.modules = await loadEditorModules(this.extensionsValue)
|
|
336
402
|
const { Editor } = this.modules
|
|
337
403
|
|
|
338
404
|
const extensions = await this.buildExtensions()
|
|
@@ -1,87 +1,50 @@
|
|
|
1
|
-
// Inkpen
|
|
2
|
-
//
|
|
1
|
+
// Inkpen — TipTap-based rich text editor for Rails.
|
|
2
|
+
//
|
|
3
|
+
// This is the entry the host's importmap pins as `inkpen`. The host
|
|
4
|
+
// does `import "inkpen"` from its application.js; the side effect of
|
|
5
|
+
// that import is registering the three Stimulus controllers below.
|
|
6
|
+
// Everything else (TipTap core, every extension, ProseMirror, etc.)
|
|
7
|
+
// is loaded LAZILY by the EditorController via gated dynamic imports,
|
|
8
|
+
// not statically here.
|
|
9
|
+
//
|
|
10
|
+
// Spec 02 (2026-05-17, gem 0.9.0): the previous index.js statically
|
|
11
|
+
// imported 17 custom extensions and re-exported them as named exports.
|
|
12
|
+
// That made every consumer pay the full extension graph at module-eval
|
|
13
|
+
// time, even when their editor enabled only a subset. Those static
|
|
14
|
+
// imports are gone. Extension classes are now loaded on demand by
|
|
15
|
+
// editor_controller.js#loadEditorModules based on the editor instance's
|
|
16
|
+
// `extensions-value`. Hosts that previously did `import { Section }
|
|
17
|
+
// from "inkpen"` must now either:
|
|
18
|
+
//
|
|
19
|
+
// a) Configure the editor's extensions-value to include "section"
|
|
20
|
+
// (preferred — the controller manages the extension lifecycle)
|
|
21
|
+
// b) Import the extension's path directly through a custom importmap
|
|
22
|
+
// pin (advanced; only if you need direct programmatic access)
|
|
23
|
+
//
|
|
24
|
+
// InventList today only does `import "inkpen"` and configures
|
|
25
|
+
// extensions-value on the data-controller element — the supported and
|
|
26
|
+
// recommended pattern.
|
|
3
27
|
|
|
4
28
|
import { Application } from "@hotwired/stimulus"
|
|
5
29
|
import EditorController from "inkpen/controllers/editor_controller"
|
|
6
30
|
import ToolbarController from "inkpen/controllers/toolbar_controller"
|
|
7
31
|
import StickyToolbarController from "inkpen/controllers/sticky_toolbar_controller"
|
|
8
32
|
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
// ============================================
|
|
33
|
+
// Register controllers IMMEDIATELY at module-eval. Stimulus scans the
|
|
34
|
+
// DOM as soon as it boots; controllers not registered by then won't
|
|
35
|
+
// connect to their elements.
|
|
13
36
|
const application = window.Stimulus || Application.start()
|
|
14
37
|
|
|
15
38
|
application.register("inkpen--editor", EditorController)
|
|
16
39
|
application.register("inkpen--toolbar", ToolbarController)
|
|
17
40
|
application.register("inkpen--sticky-toolbar", StickyToolbarController)
|
|
18
41
|
|
|
19
|
-
//
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
import { SlashCommands } from "inkpen/extensions/slash_commands"
|
|
23
|
-
import { BlockGutter } from "inkpen/extensions/block_gutter"
|
|
24
|
-
import { DragHandle } from "inkpen/extensions/drag_handle"
|
|
25
|
-
import { ToggleBlock, ToggleSummary } from "inkpen/extensions/toggle_block"
|
|
26
|
-
import { Columns, Column } from "inkpen/extensions/columns"
|
|
27
|
-
import { Callout } from "inkpen/extensions/callout"
|
|
28
|
-
import { BlockCommands } from "inkpen/extensions/block_commands"
|
|
29
|
-
import { EnhancedImage } from "inkpen/extensions/enhanced_image"
|
|
30
|
-
import { FileAttachment } from "inkpen/extensions/file_attachment"
|
|
31
|
-
import { Embed } from "inkpen/extensions/embed"
|
|
32
|
-
import { AdvancedTable, AdvancedTableRow, AdvancedTableCell, AdvancedTableHeader } from "inkpen/extensions/advanced_table"
|
|
33
|
-
import { TableOfContents } from "inkpen/extensions/table_of_contents"
|
|
34
|
-
import { Database } from "inkpen/extensions/database"
|
|
35
|
-
import { DocumentSection } from "inkpen/extensions/document_section"
|
|
36
|
-
import { SectionTitle } from "inkpen/extensions/section_title"
|
|
37
|
-
|
|
38
|
-
// InkpenTable is loaded lazily to prevent import failures from breaking the library
|
|
39
|
-
let InkpenTable, InkpenTableRow, InkpenTableCell, InkpenTableHeader
|
|
40
|
-
try {
|
|
41
|
-
const mod = await import("inkpen/extensions/inkpen_table")
|
|
42
|
-
InkpenTable = mod.InkpenTable
|
|
43
|
-
InkpenTableRow = mod.InkpenTableRow
|
|
44
|
-
InkpenTableCell = mod.InkpenTableCell
|
|
45
|
-
InkpenTableHeader = mod.InkpenTableHeader
|
|
46
|
-
} catch (e) {
|
|
47
|
-
console.warn("Inkpen: InkpenTable extension not available:", e.message)
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Export controllers
|
|
42
|
+
// Re-export the controller classes for hosts that want to wire them
|
|
43
|
+
// to their own Stimulus application instance (rare; most consumers
|
|
44
|
+
// just use the side-effect registration above).
|
|
51
45
|
export { EditorController, ToolbarController, StickyToolbarController }
|
|
52
46
|
|
|
53
|
-
//
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
SectionTitle,
|
|
58
|
-
Preformatted,
|
|
59
|
-
SlashCommands,
|
|
60
|
-
BlockGutter,
|
|
61
|
-
DragHandle,
|
|
62
|
-
ToggleBlock,
|
|
63
|
-
ToggleSummary,
|
|
64
|
-
Columns,
|
|
65
|
-
Column,
|
|
66
|
-
Callout,
|
|
67
|
-
BlockCommands,
|
|
68
|
-
EnhancedImage,
|
|
69
|
-
FileAttachment,
|
|
70
|
-
Embed,
|
|
71
|
-
// InkpenTable - Notion-style enhanced tables (recommended)
|
|
72
|
-
InkpenTable,
|
|
73
|
-
InkpenTableRow,
|
|
74
|
-
InkpenTableCell,
|
|
75
|
-
InkpenTableHeader,
|
|
76
|
-
// AdvancedTable - Legacy (use InkpenTable instead)
|
|
77
|
-
AdvancedTable,
|
|
78
|
-
AdvancedTableRow,
|
|
79
|
-
AdvancedTableCell,
|
|
80
|
-
AdvancedTableHeader,
|
|
81
|
-
TableOfContents,
|
|
82
|
-
Database
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// Export functionality is available separately:
|
|
86
|
-
// import { ExportCommands } from "inkpen/extensions/export_commands"
|
|
87
|
-
// import { exportToMarkdown, ... } from "inkpen/export"
|
|
47
|
+
// Extension classes are no longer exported from this entry. Configure
|
|
48
|
+
// them via the `data-inkpen--editor-extensions-value` attribute on the
|
|
49
|
+
// editor element; editor_controller.js loads each one lazily. See the
|
|
50
|
+
// README "Stimulus Controller" + "Public events" sections.
|