@fiduswriter/editor 0.1.78 → 0.1.79
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/citations/index.js +3 -3
- package/dist/citations/index.js.map +1 -1
- package/dist/collab/chat.js +1 -1
- package/dist/collab/chat.js.map +1 -1
- package/dist/collab/colors.js +1 -1
- package/dist/collab/colors.js.map +1 -1
- package/dist/comments/interactions.js +1 -1
- package/dist/comments/interactions.js.map +1 -1
- package/dist/exporter/native/file.d.ts +1 -1
- package/dist/exporter/native/file.d.ts.map +1 -1
- package/dist/exporter/native/file.js +2 -2
- package/dist/exporter/native/file.js.map +1 -1
- package/dist/footnotes/layout.js +1 -1
- package/dist/footnotes/layout.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -4
- package/dist/index.js.map +1 -1
- package/dist/marginboxes/index.js +8 -8
- package/dist/marginboxes/index.js.map +1 -1
- package/dist/menus/headerbar/view.js +12 -12
- package/dist/menus/headerbar/view.js.map +1 -1
- package/dist/menus/selection/view.js +2 -2
- package/dist/menus/selection/view.js.map +1 -1
- package/dist/menus/toolbar/view.js +4 -4
- package/dist/menus/toolbar/view.js.map +1 -1
- package/dist/navigator/index.js +9 -9
- package/dist/navigator/index.js.map +1 -1
- package/dist/state_plugins/settings.js +2 -2
- package/dist/state_plugins/settings.js.map +1 -1
- package/dist/static_app.d.ts +26 -1
- package/dist/static_app.d.ts.map +1 -1
- package/dist/static_app.js +3 -2
- package/dist/static_app.js.map +1 -1
- package/dist/static_editor.d.ts +5 -0
- package/dist/static_editor.d.ts.map +1 -1
- package/dist/static_editor.js +11 -1
- package/dist/static_editor.js.map +1 -1
- package/dist/track/mod.js +1 -1
- package/dist/track/mod.js.map +1 -1
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/citations/index.ts +3 -3
- package/src/collab/chat.ts +1 -1
- package/src/collab/colors.ts +1 -1
- package/src/comments/interactions.ts +1 -1
- package/src/exporter/native/file.ts +4 -2
- package/src/footnotes/layout.ts +1 -1
- package/src/index.ts +18 -4
- package/src/marginboxes/index.ts +8 -8
- package/src/menus/headerbar/view.ts +12 -12
- package/src/menus/selection/view.ts +2 -2
- package/src/menus/toolbar/view.ts +4 -4
- package/src/navigator/index.ts +9 -9
- package/src/state_plugins/settings.ts +2 -2
- package/src/static_app.ts +26 -2
- package/src/static_editor.ts +19 -1
- package/src/track/mod.ts +1 -1
- package/src/types.ts +6 -0
|
@@ -132,23 +132,23 @@ export class HeaderbarView {
|
|
|
132
132
|
|
|
133
133
|
bindEvents(): void {
|
|
134
134
|
this.listeners.onclick = event => this.onclick(event)
|
|
135
|
-
|
|
135
|
+
this.editor.dom.addEventListener("click", this.listeners.onclick)
|
|
136
136
|
this.listeners.onKeydown = event => this.onKeydown(event)
|
|
137
|
-
|
|
137
|
+
this.editor.dom.addEventListener("keydown", this.listeners.onKeydown)
|
|
138
138
|
this.listeners.onKeyup = event => this.onKeyup(event)
|
|
139
|
-
|
|
139
|
+
this.editor.dom.addEventListener("keyup", this.listeners.onKeyup)
|
|
140
140
|
this.listeners.onFocusout = event => this.onFocusout(event)
|
|
141
|
-
|
|
141
|
+
this.editor.dom.addEventListener("focusout", this.listeners.onFocusout)
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
destroy(): void {
|
|
145
145
|
if (document.activeElement?.id === "document-title") {
|
|
146
146
|
this.saveFileName()
|
|
147
147
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
148
|
+
this.editor.dom.removeEventListener("click", this.listeners.onclick!)
|
|
149
|
+
this.editor.dom.removeEventListener("keydown", this.listeners.onKeydown!)
|
|
150
|
+
this.editor.dom.removeEventListener("keyup", this.listeners.onKeyup!)
|
|
151
|
+
this.editor.dom.removeEventListener("focusout", this.listeners.onFocusout!)
|
|
152
152
|
}
|
|
153
153
|
|
|
154
154
|
onclick(event: MouseEvent): void {
|
|
@@ -425,7 +425,7 @@ export class HeaderbarView {
|
|
|
425
425
|
if (!findTarget(event, "h1#document-title")) {
|
|
426
426
|
return
|
|
427
427
|
}
|
|
428
|
-
const docTitleEl =
|
|
428
|
+
const docTitleEl = this.editor.dom.querySelector("h1#document-title")
|
|
429
429
|
if (
|
|
430
430
|
!docTitleEl?.childNodes.length ||
|
|
431
431
|
(docTitleEl.childNodes.length === 1 &&
|
|
@@ -537,7 +537,7 @@ export class HeaderbarView {
|
|
|
537
537
|
// We are offline. Just reset.
|
|
538
538
|
return this.update()
|
|
539
539
|
}
|
|
540
|
-
const docTitleEl =
|
|
540
|
+
const docTitleEl = this.editor.dom.querySelector("h1#document-title") as HTMLElement | null
|
|
541
541
|
if (!docTitleEl) {
|
|
542
542
|
return
|
|
543
543
|
}
|
|
@@ -589,9 +589,9 @@ export class HeaderbarView {
|
|
|
589
589
|
this.dd.apply(this.headerEl, diff)
|
|
590
590
|
const model = this.editor.menu.headerbarModel as HeaderbarModel
|
|
591
591
|
if (model.open) {
|
|
592
|
-
|
|
592
|
+
this.editor.dom.classList.remove("header-closed")
|
|
593
593
|
} else {
|
|
594
|
-
|
|
594
|
+
this.editor.dom.classList.add("header-closed")
|
|
595
595
|
}
|
|
596
596
|
}
|
|
597
597
|
|
|
@@ -78,11 +78,11 @@ export class SelectionMenuView {
|
|
|
78
78
|
|
|
79
79
|
bindEvents(): void {
|
|
80
80
|
this.listeners.onclick = event => this.onclick(event)
|
|
81
|
-
|
|
81
|
+
this.editor.dom.addEventListener("click", this.listeners.onclick as EventListener)
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
destroy(): void {
|
|
85
|
-
|
|
85
|
+
this.editor.dom.removeEventListener(
|
|
86
86
|
"click",
|
|
87
87
|
this.listeners.onclick as EventListener
|
|
88
88
|
)
|
|
@@ -95,14 +95,14 @@ export class ToolbarView {
|
|
|
95
95
|
|
|
96
96
|
bindEvents(): void {
|
|
97
97
|
this.listeners.onclick = event => this.onclick(event)
|
|
98
|
-
|
|
98
|
+
this.editor.dom.addEventListener("click", this.listeners.onclick)
|
|
99
99
|
this.listeners.onmousedown = event => this.onmousedown(event)
|
|
100
|
-
|
|
100
|
+
this.editor.dom.addEventListener("mousedown", this.listeners.onmousedown)
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
destroy(): void {
|
|
104
|
-
|
|
105
|
-
|
|
104
|
+
this.editor.dom.removeEventListener("click", this.listeners.onclick!)
|
|
105
|
+
this.editor.dom.removeEventListener(
|
|
106
106
|
"mousedown",
|
|
107
107
|
this.listeners.onmousedown!
|
|
108
108
|
)
|
package/src/navigator/index.ts
CHANGED
|
@@ -46,7 +46,7 @@ export class ModNavigator {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
bindEvents(): void {
|
|
49
|
-
|
|
49
|
+
this.editor.dom.addEventListener("click", event => {
|
|
50
50
|
const el: {target?: HTMLElement} = {}
|
|
51
51
|
switch (true) {
|
|
52
52
|
case findTarget(event, "#navigator-button", el):
|
|
@@ -139,17 +139,17 @@ export class ModNavigator {
|
|
|
139
139
|
}
|
|
140
140
|
})
|
|
141
141
|
|
|
142
|
-
|
|
142
|
+
this.editor.dom
|
|
143
143
|
.querySelector("#navigator-list")
|
|
144
144
|
?.addEventListener("mouseover", () => {
|
|
145
|
-
|
|
145
|
+
this.editor.dom.classList.add("no-scroll")
|
|
146
146
|
})
|
|
147
|
-
|
|
147
|
+
this.editor.dom
|
|
148
148
|
.querySelector("#navigator-list")
|
|
149
149
|
?.addEventListener("mouseout", () => {
|
|
150
|
-
|
|
150
|
+
this.editor.dom.classList.remove("no-scroll")
|
|
151
151
|
})
|
|
152
|
-
|
|
152
|
+
this.editor.dom.addEventListener("keydown", event => {
|
|
153
153
|
// Alt+n shortcut to toggle navigator
|
|
154
154
|
if (event.altKey && event.key.toLowerCase() === "n") {
|
|
155
155
|
event.preventDefault()
|
|
@@ -368,8 +368,8 @@ export class ModNavigator {
|
|
|
368
368
|
if (this.lastSelectedTarget) {
|
|
369
369
|
const target =
|
|
370
370
|
this.lastSelectedTarget == "title"
|
|
371
|
-
?
|
|
372
|
-
:
|
|
371
|
+
? this.editor.dom.querySelector(`div.doc-title`)
|
|
372
|
+
: this.editor.dom.querySelector(`#${this.lastSelectedTarget}`)
|
|
373
373
|
if (target) {
|
|
374
374
|
// Set selection at end of target.
|
|
375
375
|
const range = document.createRange()
|
|
@@ -437,7 +437,7 @@ export class ModNavigator {
|
|
|
437
437
|
populateNavigator(): string | false {
|
|
438
438
|
const currentPos = this.editor.view.state.selection.$head.pos
|
|
439
439
|
const title =
|
|
440
|
-
|
|
440
|
+
this.editor.dom.querySelector("div.doc-title")?.textContent ||
|
|
441
441
|
gettext("Untitled Document")
|
|
442
442
|
const items: NavigatorItem[] = [
|
|
443
443
|
{
|
|
@@ -131,7 +131,7 @@ export const settingsPlugin = (options: SettingsOptions) => {
|
|
|
131
131
|
if (!docStyleEl) {
|
|
132
132
|
docStyleEl = document.createElement("style")
|
|
133
133
|
docStyleEl.id = "document-style"
|
|
134
|
-
|
|
134
|
+
options.editor.dom.appendChild(docStyleEl)
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
docStyleEl.innerHTML = docStyleCSS
|
|
@@ -149,7 +149,7 @@ export const settingsPlugin = (options: SettingsOptions) => {
|
|
|
149
149
|
if (!langStyleEl) {
|
|
150
150
|
langStyleEl = document.createElement("style")
|
|
151
151
|
langStyleEl.id = "language-style"
|
|
152
|
-
|
|
152
|
+
options.editor.dom.appendChild(langStyleEl)
|
|
153
153
|
}
|
|
154
154
|
|
|
155
155
|
langStyleEl.innerHTML = `
|
package/src/static_app.ts
CHANGED
|
@@ -77,6 +77,29 @@ export interface StaticAppConfig {
|
|
|
77
77
|
json: Record<string, unknown>
|
|
78
78
|
status: number
|
|
79
79
|
}>
|
|
80
|
+
/**
|
|
81
|
+
* Editor save mode:
|
|
82
|
+
* - "external" (default): the host drives saving through
|
|
83
|
+
* `onSaveDocument`; no autosave runs inside the editor.
|
|
84
|
+
* - "direct": the editor autosaves (every 10 s and on page hide) via the
|
|
85
|
+
* `saveDocument` connector. `onSaveDocument` is used as the save
|
|
86
|
+
* connector and should return `{json: {version}, status}` (or
|
|
87
|
+
* `{json, status: 409}` on version conflict, which triggers the
|
|
88
|
+
* built-in merge).
|
|
89
|
+
*/
|
|
90
|
+
saveMode?: "external" | "direct"
|
|
91
|
+
/**
|
|
92
|
+
* Optional API connector overrides. When provided, these replace the
|
|
93
|
+
* corresponding in-memory connectors, letting the editor talk to a real
|
|
94
|
+
* backend (e.g. Django) instead of the static in-memory stores.
|
|
95
|
+
*/
|
|
96
|
+
apiConnectors?: Partial<{
|
|
97
|
+
document: EditorDocumentApi
|
|
98
|
+
documentImport: EditorDocumentImportApi
|
|
99
|
+
image: ImageApi
|
|
100
|
+
bibliography: BibliographyApi
|
|
101
|
+
contacts: EditorContactsApi
|
|
102
|
+
}>
|
|
80
103
|
/**
|
|
81
104
|
* Optional user preferences that control inline editing helpers.
|
|
82
105
|
* Recognized keys include `inline_references` and `inline_math`.
|
|
@@ -341,7 +364,7 @@ export async function createStaticApp(
|
|
|
341
364
|
isOffline: () => false,
|
|
342
365
|
settings: {
|
|
343
366
|
APPS: [appName],
|
|
344
|
-
EDITOR_SAVE_MODE: "external",
|
|
367
|
+
EDITOR_SAVE_MODE: config.saveMode ?? "external",
|
|
345
368
|
EDITOR_ONLY_MODE: true,
|
|
346
369
|
E2EE_MODE: "disabled",
|
|
347
370
|
LANGUAGE: config.locale
|
|
@@ -357,7 +380,8 @@ export async function createStaticApp(
|
|
|
357
380
|
documentImport: documentImportApi,
|
|
358
381
|
image: imageApi,
|
|
359
382
|
bibliography: bibliographyApi,
|
|
360
|
-
contacts: contactsApi
|
|
383
|
+
contacts: contactsApi,
|
|
384
|
+
...config.apiConnectors
|
|
361
385
|
}
|
|
362
386
|
} as unknown as EditorApp
|
|
363
387
|
|
package/src/static_editor.ts
CHANGED
|
@@ -71,6 +71,11 @@ export interface StaticEditorConfig
|
|
|
71
71
|
}>
|
|
72
72
|
/** Optional extra editor plugins. */
|
|
73
73
|
plugins?: Array<[string, Record<string, unknown>]>
|
|
74
|
+
/**
|
|
75
|
+
* Optional container element (or selector) to mount the editor into.
|
|
76
|
+
* When omitted, the editor replaces `document.body` (full-page mode).
|
|
77
|
+
*/
|
|
78
|
+
mount?: HTMLElement | string
|
|
74
79
|
/**
|
|
75
80
|
* Optional user preferences that control inline editing helpers.
|
|
76
81
|
* Recognized keys include `inline_references` and `inline_math`.
|
|
@@ -242,8 +247,21 @@ export async function createStaticEditor(
|
|
|
242
247
|
// exports and printing use the latest edits.
|
|
243
248
|
plugins.push([app.name, {ConfirmedDocEditorPlugin}])
|
|
244
249
|
|
|
250
|
+
let mount: HTMLElement | undefined
|
|
251
|
+
if (config.mount) {
|
|
252
|
+
mount =
|
|
253
|
+
typeof config.mount === "string"
|
|
254
|
+
? (document.querySelector(config.mount) as HTMLElement)
|
|
255
|
+
: config.mount
|
|
256
|
+
if (!mount) {
|
|
257
|
+
throw new Error(
|
|
258
|
+
`createStaticEditor: mount element not found (${String(config.mount)})`
|
|
259
|
+
)
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
245
263
|
const editor = new Editor(
|
|
246
|
-
{app, user},
|
|
264
|
+
{app, user, mount},
|
|
247
265
|
docPath,
|
|
248
266
|
String(docId),
|
|
249
267
|
plugins
|
package/src/track/mod.ts
CHANGED
|
@@ -30,7 +30,7 @@ export class ModTrack {
|
|
|
30
30
|
|
|
31
31
|
bindEvents(): void {
|
|
32
32
|
// Bind all the click events related to track changes
|
|
33
|
-
|
|
33
|
+
this.editor.dom.addEventListener("click", event => {
|
|
34
34
|
const el: {target?: HTMLElement} = {}
|
|
35
35
|
switch (true) {
|
|
36
36
|
case findTarget(event, ".track-accept", el): {
|
package/src/types.ts
CHANGED
|
@@ -337,6 +337,11 @@ export interface EditorUser {
|
|
|
337
337
|
export interface EditorOptions {
|
|
338
338
|
app: EditorApp
|
|
339
339
|
user: EditorUser
|
|
340
|
+
/**
|
|
341
|
+
* Optional container element to mount the editor into. When omitted, the
|
|
342
|
+
* editor replaces `document.body` (full-page mode).
|
|
343
|
+
*/
|
|
344
|
+
mount?: HTMLElement
|
|
340
345
|
}
|
|
341
346
|
|
|
342
347
|
/** Editor plugin tuple used to build the ProseMirror state. */
|
|
@@ -366,6 +371,7 @@ export interface Editor {
|
|
|
366
371
|
view: EditorView
|
|
367
372
|
currentView: EditorView
|
|
368
373
|
dom: HTMLElement
|
|
374
|
+
mount?: HTMLElement
|
|
369
375
|
ws?: {
|
|
370
376
|
connectionCount?: number
|
|
371
377
|
online?: boolean
|