@nerd-bible/wordgard 0.5.3-beta7 → 0.6.2-beta10
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/collab.js +3 -0
- package/dist/command.d.ts +15 -7
- package/dist/command.js +38 -18
- package/dist/doc.d.ts +58 -50
- package/dist/doc.js +224 -169
- package/dist/editor.d.ts +212 -111
- package/dist/editor.js +2263 -1767
- package/dist/highlight-code.d.ts +249 -0
- package/dist/highlight-code.js +264 -0
- package/dist/history.js +7 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/phrases.d.ts +3 -2
- package/dist/phrases.js +21 -1
- package/dist/schema.d.ts +37 -1
- package/dist/schema.js +164 -134
- package/dist/set.d.ts +3 -2
- package/dist/set.js +19 -13
- package/dist/state.d.ts +120 -29
- package/dist/state.js +224 -136
- package/dist/table.d.ts +114 -3
- package/dist/table.js +64 -36
- package/package.json +3 -2
package/dist/schema.d.ts
CHANGED
|
@@ -240,6 +240,42 @@ declare namespace codeBlock {
|
|
|
240
240
|
language, converts the block into a code block.
|
|
241
241
|
*/
|
|
242
242
|
const createOnBackticks: GardState.Extension;
|
|
243
|
+
/**
|
|
244
|
+
Simple style that gives code blocks a background and slightly
|
|
245
|
+
rounded corners.
|
|
246
|
+
*/
|
|
247
|
+
const theme: GardState.Extension;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
Add support for the code block {@link CodeBlockLanguage language
|
|
251
|
+
mark}.
|
|
252
|
+
*/
|
|
253
|
+
declare function codeBlockLanguage(options?: {
|
|
254
|
+
/**
|
|
255
|
+
When given, show a drop-down menu in the corner of code blocks
|
|
256
|
+
that allows the user to choose a language for block from the
|
|
257
|
+
given list of strings. The actual mark value will be the
|
|
258
|
+
lower-case form of the selected language name.
|
|
259
|
+
*/
|
|
260
|
+
languages?: readonly string[];
|
|
261
|
+
}): GardState.Extension;
|
|
262
|
+
declare namespace codeBlockLanguage {
|
|
263
|
+
/**
|
|
264
|
+
If the selection is in a code block, and language selection is
|
|
265
|
+
enabled, this command focuses the language field to allow
|
|
266
|
+
selection via the keyboard.
|
|
267
|
+
*/
|
|
268
|
+
const selectLanguage: Command;
|
|
269
|
+
/**
|
|
270
|
+
Key binding that binds Shift-Ctrl-l (Shift-Cmd-l on MacOS) to
|
|
271
|
+
{@link codeBlockLanguage.selectLanguage `selectLanguage`}.
|
|
272
|
+
*/
|
|
273
|
+
const selectLanguageBinding: KeyBinding;
|
|
274
|
+
/**
|
|
275
|
+
A facet that allows you to add options to the language selection
|
|
276
|
+
drop-down.
|
|
277
|
+
*/
|
|
278
|
+
const options: GardState.Facet<readonly string[], readonly string[]>;
|
|
243
279
|
}
|
|
244
280
|
|
|
245
281
|
/**
|
|
@@ -576,4 +612,4 @@ declare namespace image {
|
|
|
576
612
|
const uploader: GardState.Facet<(file: File, wg: Wordgard, progress: (percent: number) => void) => Promise<string>, readonly ((file: File, wg: Wordgard, progress: (percent: number) => void) => Promise<string>)[]>;
|
|
577
613
|
}
|
|
578
614
|
|
|
579
|
-
export { ColorPicker, alignment, backgroundColor, basicMarks, basicSchema, blockDoc, blockquote, bulletList, code, codeBlock, color, direction, emphasis, figure, fullSchema, heading, horizontalRule, image, imageResizing, inlineDoc, inlineMarks, inlineSchema, lineBreak, link, orderedList, paragraph, strikethrough, strong, subscript, superscript, underline };
|
|
615
|
+
export { ColorPicker, alignment, backgroundColor, basicMarks, basicSchema, blockDoc, blockquote, bulletList, code, codeBlock, codeBlockLanguage, color, direction, emphasis, figure, fullSchema, heading, horizontalRule, image, imageResizing, inlineDoc, inlineMarks, inlineSchema, lineBreak, link, orderedList, paragraph, strikethrough, strong, subscript, superscript, underline };
|
package/dist/schema.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { ChangeSet, Leaf, Plot, Elt } from 'wordgard/doc';
|
|
2
2
|
import { GardState, GardSelection, BidiSpan, Transaction } from 'wordgard/state';
|
|
3
|
-
import { Paragraph, Heading, Direction, Blockquote, HorizontalRule, Alignment, Doc, InlineDoc, BulletList, OrderedList, InlineListItem, ListItem, CodeBlock, CodeBlockLanguage, Strong, Emphasis, Code, Underline, Strikethrough, Superscript, Subscript,
|
|
3
|
+
import { Paragraph, Heading, Direction, Blockquote, HorizontalRule, Alignment, Doc, InlineDoc, BulletList, OrderedList, InlineListItem, ListItem, CodeBlock, CodeBlockLanguage, Strong, Emphasis, Code, Underline, Strikethrough, Superscript, Subscript, Image, Figure, CaptionedFigure, ImageSize, ImageAlt, Color, BackgroundColor, Link, LineBreak } from 'wordgard/types';
|
|
4
4
|
import { phrases, imagePhrases, colorNames } from 'wordgard/phrases';
|
|
5
5
|
import { Command, setTextblockType, Menu, setAlignment, setDirection, toggleBlock, listIsActive, toggleList, enter, toggleMark } from 'wordgard/command';
|
|
6
6
|
import { history } from 'wordgard/history';
|
|
7
|
-
import { KeyBinding, InputRule, Wordgard, Widget, Decoration,
|
|
7
|
+
import { KeyBinding, InputRule, Wordgard, Widget, Decoration, Dialog, Tooltip } from 'wordgard/editor';
|
|
8
8
|
import cr from 'crelt';
|
|
9
9
|
|
|
10
10
|
function blockDoc() {
|
|
@@ -25,6 +25,8 @@ function paragraph() {
|
|
|
25
25
|
;paragraph = /*@__PURE__*/(function (paragraph) {
|
|
26
26
|
paragraph.keyBinding = KeyBinding.of({
|
|
27
27
|
key: "Ctrl-Shift-0",
|
|
28
|
+
description: phrases.ref("paragraph"),
|
|
29
|
+
group: KeyBinding.Group.Block,
|
|
28
30
|
run: Command.bind(setTextblockType, Paragraph)
|
|
29
31
|
});
|
|
30
32
|
paragraph.button = Menu.Button.define({
|
|
@@ -43,12 +45,18 @@ function heading() {
|
|
|
43
45
|
}
|
|
44
46
|
;heading = /*@__PURE__*/(function (heading) {
|
|
45
47
|
heading.keyBindings = [
|
|
46
|
-
KeyBinding.of({ key: "Ctrl-Shift-1", run: Command.bind(setTextblockType, Heading.of(1))
|
|
47
|
-
|
|
48
|
-
KeyBinding.of({ key: "Ctrl-Shift-
|
|
49
|
-
|
|
50
|
-
KeyBinding.of({ key: "Ctrl-Shift-
|
|
51
|
-
|
|
48
|
+
KeyBinding.of({ key: "Ctrl-Shift-1", run: Command.bind(setTextblockType, Heading.of(1)),
|
|
49
|
+
description: phrases.ref("heading_1"), group: KeyBinding.Group.Block }),
|
|
50
|
+
KeyBinding.of({ key: "Ctrl-Shift-2", run: Command.bind(setTextblockType, Heading.of(2)),
|
|
51
|
+
description: phrases.ref("heading_2"), group: KeyBinding.Group.Block }),
|
|
52
|
+
KeyBinding.of({ key: "Ctrl-Shift-3", run: Command.bind(setTextblockType, Heading.of(3)),
|
|
53
|
+
description: phrases.ref("heading_3"), group: KeyBinding.Group.Block }),
|
|
54
|
+
KeyBinding.of({ key: "Ctrl-Shift-4", run: Command.bind(setTextblockType, Heading.of(4)),
|
|
55
|
+
description: phrases.ref("heading_4"), group: KeyBinding.Group.Block }),
|
|
56
|
+
KeyBinding.of({ key: "Ctrl-Shift-5", run: Command.bind(setTextblockType, Heading.of(5)),
|
|
57
|
+
description: phrases.ref("heading_5"), group: KeyBinding.Group.Block }),
|
|
58
|
+
KeyBinding.of({ key: "Ctrl-Shift-6", run: Command.bind(setTextblockType, Heading.of(6)),
|
|
59
|
+
description: phrases.ref("heading_6"), group: KeyBinding.Group.Block })
|
|
52
60
|
];
|
|
53
61
|
heading.button1 = Menu.Button.define({
|
|
54
62
|
run: Command.bind(setTextblockType, Heading.of(1)),
|
|
@@ -85,9 +93,12 @@ function alignmentAtCursor(state) {
|
|
|
85
93
|
}
|
|
86
94
|
;alignment = /*@__PURE__*/(function (alignment) {
|
|
87
95
|
alignment.keyBindings = [
|
|
88
|
-
KeyBinding.of({ key: "Mod-Shift-l", run: Command.bind(setAlignment, "left")
|
|
89
|
-
|
|
90
|
-
KeyBinding.of({ key: "Mod-Shift-
|
|
96
|
+
KeyBinding.of({ key: "Mod-Shift-l", run: Command.bind(setAlignment, "left"),
|
|
97
|
+
description: phrases.ref("align_left"), group: KeyBinding.Group.Block }),
|
|
98
|
+
KeyBinding.of({ key: "Mod-Shift-r", run: Command.bind(setAlignment, "right"),
|
|
99
|
+
description: phrases.ref("align_right"), group: KeyBinding.Group.Block }),
|
|
100
|
+
KeyBinding.of({ key: "Mod-Shift-e", run: Command.bind(setAlignment, "center"),
|
|
101
|
+
description: phrases.ref("align_center"), group: KeyBinding.Group.Block })
|
|
91
102
|
];
|
|
92
103
|
alignment.buttonStart = Menu.Button.define({
|
|
93
104
|
run: Command.bind(setAlignment, null),
|
|
@@ -277,13 +288,20 @@ function orderedList(config = {}) {
|
|
|
277
288
|
;return orderedList})(orderedList);
|
|
278
289
|
|
|
279
290
|
function codeBlock() {
|
|
280
|
-
return [
|
|
281
|
-
|
|
291
|
+
return [
|
|
292
|
+
GardState.schemaElement.of(CodeBlock),
|
|
293
|
+
codeBlock.button,
|
|
294
|
+
codeBlock.keyBinding,
|
|
295
|
+
codeBlock.createOnBackticks,
|
|
296
|
+
codeBlock.theme
|
|
297
|
+
];
|
|
282
298
|
}
|
|
283
299
|
;codeBlock = /*@__PURE__*/(function (codeBlock) {
|
|
284
300
|
codeBlock.keyBinding = KeyBinding.of({
|
|
285
301
|
key: "Ctrl-Shift-\\",
|
|
286
|
-
run: Command.bind(setTextblockType, CodeBlock)
|
|
302
|
+
run: Command.bind(setTextblockType, CodeBlock),
|
|
303
|
+
description: phrases.ref("code_block"),
|
|
304
|
+
group: KeyBinding.Group.Block
|
|
287
305
|
});
|
|
288
306
|
codeBlock.button = Menu.Button.define({
|
|
289
307
|
run: Command.bind(setTextblockType, CodeBlock),
|
|
@@ -312,6 +330,13 @@ function codeBlock() {
|
|
|
312
330
|
scrollIntoView: true
|
|
313
331
|
};
|
|
314
332
|
}));
|
|
333
|
+
codeBlock.theme = Wordgard.theme({
|
|
334
|
+
pre: {
|
|
335
|
+
padding: "8px 12px",
|
|
336
|
+
borderRadius: "4px",
|
|
337
|
+
background: "#88888819"
|
|
338
|
+
}
|
|
339
|
+
});
|
|
315
340
|
;return codeBlock})(codeBlock);
|
|
316
341
|
function codeBlockLanguage(options = {}) {
|
|
317
342
|
return [
|
|
@@ -331,15 +356,24 @@ const languageStyles = /*@__PURE__*/Wordgard.styles({
|
|
|
331
356
|
font: "var(--wg-dialog-font)",
|
|
332
357
|
fontSize: "70%",
|
|
333
358
|
position: "absolute",
|
|
334
|
-
top: "
|
|
335
|
-
right: "
|
|
359
|
+
top: "5px",
|
|
360
|
+
right: "5px",
|
|
336
361
|
border: "none",
|
|
337
|
-
borderRadius: "4px"
|
|
362
|
+
borderRadius: "4px",
|
|
363
|
+
background: "#88888827"
|
|
338
364
|
}
|
|
339
365
|
}
|
|
340
366
|
});
|
|
341
367
|
const languageOptions = /*@__PURE__*/GardState.Facet.define({
|
|
342
|
-
|
|
368
|
+
name: "languageOptions",
|
|
369
|
+
combine: input => {
|
|
370
|
+
let options = [];
|
|
371
|
+
for (let arr of input)
|
|
372
|
+
for (let opt of arr)
|
|
373
|
+
if (!options.includes(opt))
|
|
374
|
+
options.push(opt);
|
|
375
|
+
return options;
|
|
376
|
+
}
|
|
343
377
|
});
|
|
344
378
|
function option(text, selected, value) {
|
|
345
379
|
let node = document.createElement("option");
|
|
@@ -381,7 +415,7 @@ const languageWidget = /*@__PURE__*/Widget.define({
|
|
|
381
415
|
},
|
|
382
416
|
inFlow: false
|
|
383
417
|
});
|
|
384
|
-
const languageSelect = /*@__PURE__*/Decoration.Tag.widget.
|
|
418
|
+
const languageSelect = /*@__PURE__*/Decoration.Tag.widget.derived(CodeBlock, "end", state => {
|
|
385
419
|
let options = state.facet(languageOptions);
|
|
386
420
|
return tag => {
|
|
387
421
|
return languageWidget.of({ options, value: tag.mark(CodeBlockLanguage) });
|
|
@@ -401,8 +435,11 @@ const languageSelect = /*@__PURE__*/Decoration.Tag.widget.dynamic(CodeBlock, "en
|
|
|
401
435
|
};
|
|
402
436
|
codeBlockLanguage.selectLanguageBinding = KeyBinding.of({
|
|
403
437
|
key: "Shift-Mod-l",
|
|
404
|
-
run: codeBlockLanguage.selectLanguage
|
|
438
|
+
run: codeBlockLanguage.selectLanguage,
|
|
439
|
+
description: phrases.ref("code_block_language"),
|
|
440
|
+
group: KeyBinding.Group.Block
|
|
405
441
|
});
|
|
442
|
+
codeBlockLanguage.options = languageOptions;
|
|
406
443
|
;return codeBlockLanguage})(codeBlockLanguage);
|
|
407
444
|
|
|
408
445
|
function strong() {
|
|
@@ -412,6 +449,8 @@ function strong() {
|
|
|
412
449
|
strong.keyBinding = KeyBinding.of({
|
|
413
450
|
key: "Mod-b",
|
|
414
451
|
run: Command.bind(toggleMark, Strong),
|
|
452
|
+
description: phrases.ref("toggle_strong"),
|
|
453
|
+
group: KeyBinding.Group.Inline
|
|
415
454
|
});
|
|
416
455
|
strong.button = Menu.Button.toggleMark({
|
|
417
456
|
mark: Strong,
|
|
@@ -430,6 +469,8 @@ function emphasis() {
|
|
|
430
469
|
emphasis.keyBinding = KeyBinding.of({
|
|
431
470
|
key: "Mod-i",
|
|
432
471
|
run: Command.bind(toggleMark, Emphasis),
|
|
472
|
+
description: phrases.ref("toggle_em"),
|
|
473
|
+
group: KeyBinding.Group.Inline
|
|
433
474
|
});
|
|
434
475
|
emphasis.button = Menu.Button.toggleMark({
|
|
435
476
|
mark: Emphasis,
|
|
@@ -448,6 +489,8 @@ function code() {
|
|
|
448
489
|
code.keyBinding = KeyBinding.of({
|
|
449
490
|
key: "Mod-`",
|
|
450
491
|
run: Command.bind(toggleMark, Code),
|
|
492
|
+
description: phrases.ref("toggle_code"),
|
|
493
|
+
group: KeyBinding.Group.Inline
|
|
451
494
|
});
|
|
452
495
|
code.button = Menu.Button.toggleMark({
|
|
453
496
|
mark: Code,
|
|
@@ -465,7 +508,9 @@ function underline() {
|
|
|
465
508
|
;underline = /*@__PURE__*/(function (underline) {
|
|
466
509
|
underline.keyBinding = KeyBinding.of({
|
|
467
510
|
key: "Mod-u",
|
|
468
|
-
run: Command.bind(toggleMark, Underline)
|
|
511
|
+
run: Command.bind(toggleMark, Underline),
|
|
512
|
+
description: phrases.ref("toggle_underline"),
|
|
513
|
+
group: KeyBinding.Group.Inline
|
|
469
514
|
});
|
|
470
515
|
underline.button = Menu.Button.toggleMark({
|
|
471
516
|
mark: Underline,
|
|
@@ -484,6 +529,8 @@ function strikethrough() {
|
|
|
484
529
|
strikethrough.keyBinding = KeyBinding.of({
|
|
485
530
|
key: "Mod-/",
|
|
486
531
|
run: Command.bind(toggleMark, Strikethrough),
|
|
532
|
+
description: phrases.ref("toggle_strikethrough"),
|
|
533
|
+
group: KeyBinding.Group.Inline
|
|
487
534
|
});
|
|
488
535
|
strikethrough.button = Menu.Button.toggleMark({
|
|
489
536
|
mark: Strikethrough,
|
|
@@ -502,6 +549,8 @@ function superscript() {
|
|
|
502
549
|
superscript.keyBinding = KeyBinding.of({
|
|
503
550
|
key: "Mod-.",
|
|
504
551
|
run: Command.bind(toggleMark, Superscript),
|
|
552
|
+
description: phrases.ref("toggle_super"),
|
|
553
|
+
group: KeyBinding.Group.Inline
|
|
505
554
|
});
|
|
506
555
|
superscript.button = Menu.Button.toggleMark({
|
|
507
556
|
mark: Superscript,
|
|
@@ -520,6 +569,8 @@ function subscript() {
|
|
|
520
569
|
subscript.keyBinding = KeyBinding.of({
|
|
521
570
|
key: "Mod-,",
|
|
522
571
|
run: Command.bind(toggleMark, Subscript),
|
|
572
|
+
description: phrases.ref("toggle_sub"),
|
|
573
|
+
group: KeyBinding.Group.Inline
|
|
523
574
|
});
|
|
524
575
|
subscript.button = Menu.Button.toggleMark({
|
|
525
576
|
mark: Subscript,
|
|
@@ -532,7 +583,7 @@ function subscript() {
|
|
|
532
583
|
});
|
|
533
584
|
;return subscript})(subscript);
|
|
534
585
|
|
|
535
|
-
const imageUploader = /*@__PURE__*/GardState.Facet.define();
|
|
586
|
+
const imageUploader = /*@__PURE__*/GardState.Facet.define({ name: "imageUploader" });
|
|
536
587
|
const imageTypes = [Image, Figure, CaptionedFigure];
|
|
537
588
|
function activeImage(sel) {
|
|
538
589
|
if (sel.selection instanceof GardSelection.Node && imageTypes.includes(sel.selection.node.type))
|
|
@@ -598,22 +649,6 @@ function imageTypeButtons(state, active) {
|
|
|
598
649
|
}
|
|
599
650
|
return [cr("span", { class: "wg-label" }, imagePhrases.get(state, "image_style"), ":"), cr("span", buttons)];
|
|
600
651
|
}
|
|
601
|
-
const setImageDialog = /*@__PURE__*/Transaction.Effect.define();
|
|
602
|
-
const createImagePanel = wg => {
|
|
603
|
-
let dom = buildImagePanel(wg), mustFocus = true;
|
|
604
|
-
return {
|
|
605
|
-
top: true,
|
|
606
|
-
dom,
|
|
607
|
-
connect() {
|
|
608
|
-
if (mustFocus) {
|
|
609
|
-
mustFocus = false;
|
|
610
|
-
let target = dom.querySelector("input[name=src]");
|
|
611
|
-
if (target)
|
|
612
|
-
target.focus();
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
};
|
|
616
|
-
};
|
|
617
652
|
function startUpload(wg, file, set) {
|
|
618
653
|
let imageFile = file.files?.[0], handler = wg.state.facet(imageUploader)[0];
|
|
619
654
|
if (!imageFile || !handler)
|
|
@@ -635,9 +670,8 @@ function startUpload(wg, file, set) {
|
|
|
635
670
|
Dialog.show(wg, { label: imagePhrases.get(wg.state, "upload_failed") + ": " + err });
|
|
636
671
|
});
|
|
637
672
|
}
|
|
638
|
-
function
|
|
639
|
-
let { state } = wg;
|
|
640
|
-
let sel = (state.field(imageDialog) || state.selection).resolve(state.doc);
|
|
673
|
+
function buildImageDialog(wg, close) {
|
|
674
|
+
let { state } = wg, { sel } = state;
|
|
641
675
|
let active = activeImage(sel);
|
|
642
676
|
let size = !wg.state.schema.has(ImageSize) ? null :
|
|
643
677
|
[cr("label", { for: "wg-img-size" }, imagePhrases.get(state, "width"), ":"),
|
|
@@ -650,90 +684,78 @@ function buildImagePanel(wg) {
|
|
|
650
684
|
file = cr("input", { type: "file", id: "wg-img-file", name: "file", "aria-label": imagePhrases.get(state, "upload_image"),
|
|
651
685
|
onchange: (e) => startUpload(wg, e.target, url => src.value = url) });
|
|
652
686
|
}
|
|
653
|
-
|
|
687
|
+
return cr("form", { class: "wg-img-form", onkeydown }, cr("h3", { class: "wg-dialog-title" }, imagePhrases.get(state, active ? "update_image" : "insert_image")), cr("label", { for: "wg-img-src" }, imagePhrases.get(state, "image_source"), ":"), cr("span", { class: "wg-img-src-line" }, src, file), cr("label", { for: "wg-img-alt" }, imagePhrases.get(state, "alt_text"), ":"), cr("input", { type: "text", id: "wg-img-alt", name: "alt",
|
|
654
688
|
value: active && active.mark(ImageAlt) || "",
|
|
655
689
|
placeholder: imagePhrases.get(state, "describe_image") }), imageTypeButtons(state, active), size, cr("div", { class: "wg-img-buttons" }, cr("button", { type: "submit", class: "wg-dialog-button" }, imagePhrases.get(state, active ? "update" : "insert")), " ", cr("button", { type: "button", class: "wg-dialog-button", onclick: close }, imagePhrases.get(state, "cancel"))));
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
change = { from: sel.from.pos, to: sel.to.pos, insert: [tag instanceof Plot.Tag ? tag.create() : tag], fit: true };
|
|
683
|
-
}
|
|
684
|
-
wg.focus();
|
|
685
|
-
let changes = ChangeSet.create(state.doc, change), pos = changes.findInserted(t => t == tag) ?? change.from;
|
|
686
|
-
wg.dispatch({
|
|
687
|
-
changes: change,
|
|
688
|
-
effects: setImageDialog.of(false),
|
|
689
|
-
userEvent: "insert.image",
|
|
690
|
-
selection: tag instanceof Plot.Tag ? { anchor: pos + 1 } : GardSelection.node(pos, tag)
|
|
691
|
-
});
|
|
692
|
-
}
|
|
693
|
-
function close() {
|
|
694
|
-
wg.focus();
|
|
695
|
-
wg.dispatch({ effects: setImageDialog.of(false) });
|
|
690
|
+
}
|
|
691
|
+
function finishInsertImage(wg, form) {
|
|
692
|
+
if (!form)
|
|
693
|
+
return;
|
|
694
|
+
let { state } = wg, { sel } = state;
|
|
695
|
+
let data = new FormData(form);
|
|
696
|
+
let src = data.get("src");
|
|
697
|
+
if (!src)
|
|
698
|
+
return;
|
|
699
|
+
let type = data.get("type") ?? (state.schema.has(Image) ? "inline" : "start");
|
|
700
|
+
let cap = !!data.get("caption") || !state.schema.has(Figure);
|
|
701
|
+
let marks = [];
|
|
702
|
+
if (type == "center" || type == "end")
|
|
703
|
+
marks = Alignment.of(type).addToSet(marks);
|
|
704
|
+
if (data.get("alt"))
|
|
705
|
+
marks = ImageAlt.of(data.get("alt")).addToSet(marks);
|
|
706
|
+
if (data.get("size"))
|
|
707
|
+
marks = ImageSize.of(Number(data.get("size"))).addToSet(marks);
|
|
708
|
+
let tag = type == "inline" ? Image.of(src, marks) : cap ? CaptionedFigure.of(src, marks) : Figure.of(src, marks);
|
|
709
|
+
let change;
|
|
710
|
+
if (sel.from.parent.node.type == CaptionedFigure && sel.to.parent.start == sel.from.parent.start) {
|
|
711
|
+
let from = sel.from.parent.before;
|
|
712
|
+
if (tag instanceof Plot.Tag)
|
|
713
|
+
change = { from, to: from + 1, insert: [tag] };
|
|
714
|
+
else
|
|
715
|
+
change = { from, to: sel.from.parent.after, insert: [tag], fit: true };
|
|
696
716
|
}
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
e.preventDefault();
|
|
700
|
-
close();
|
|
701
|
-
}
|
|
717
|
+
else {
|
|
718
|
+
change = { from: sel.from.pos, to: sel.to.pos, insert: [tag instanceof Plot.Tag ? tag.create() : tag], fit: true };
|
|
702
719
|
}
|
|
703
|
-
|
|
720
|
+
let changes = ChangeSet.create(state.doc, change), pos = changes.findInserted(t => t == tag) ?? change.from;
|
|
721
|
+
wg.dispatch({
|
|
722
|
+
changes: change,
|
|
723
|
+
userEvent: "insert.image",
|
|
724
|
+
selection: tag instanceof Plot.Tag ? { anchor: pos + 1 } : GardSelection.node(pos, tag)
|
|
725
|
+
});
|
|
704
726
|
}
|
|
705
727
|
const insertImage = wg => {
|
|
706
|
-
let
|
|
707
|
-
if (
|
|
708
|
-
|
|
728
|
+
let open = Dialog.get(wg, insertImage);
|
|
729
|
+
if (open) {
|
|
730
|
+
open.close();
|
|
709
731
|
}
|
|
710
732
|
else {
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
733
|
+
Dialog.show(wg, {
|
|
734
|
+
key: insertImage,
|
|
735
|
+
content: buildImageDialog,
|
|
736
|
+
closedBy: tr => !!tr.selection,
|
|
737
|
+
focus: "input[name=src]",
|
|
738
|
+
class: "wg-img-dialog",
|
|
739
|
+
tooltip: { pos: wg.state.selection.from },
|
|
740
|
+
positioningHint: true
|
|
741
|
+
}).result.then(form => finishInsertImage(wg, form));
|
|
715
742
|
}
|
|
716
743
|
return true;
|
|
717
744
|
};
|
|
718
745
|
const imageDialogTheme = /*@__PURE__*/Wordgard.styles({
|
|
719
|
-
".wg-img-dialog": {
|
|
720
|
-
borderBottom: "1px solid var(--wg-border-color)"
|
|
721
|
-
},
|
|
746
|
+
".wg-img-dialog": {},
|
|
722
747
|
".wg-img-form": {
|
|
723
|
-
padding: "5px 3px",
|
|
724
748
|
display: "grid",
|
|
725
749
|
gap: "8px",
|
|
726
750
|
alignItems: "center",
|
|
727
751
|
gridTemplateColumns: "max-content auto",
|
|
728
752
|
"& label, & .wg-label": {
|
|
729
|
-
textAlign: "
|
|
753
|
+
textAlign: "end"
|
|
730
754
|
}
|
|
731
755
|
},
|
|
732
|
-
".wg-dialog-title": {
|
|
756
|
+
".wg-img-form .wg-dialog-title": {
|
|
733
757
|
gridColumn: "span 2",
|
|
734
|
-
|
|
735
|
-
fontWeight: "bold",
|
|
736
|
-
textAlign: "center"
|
|
758
|
+
margin: "0"
|
|
737
759
|
},
|
|
738
760
|
".wg-img-buttons": {
|
|
739
761
|
gridColumn: "2"
|
|
@@ -773,23 +795,11 @@ const imageDialogTheme = /*@__PURE__*/Wordgard.styles({
|
|
|
773
795
|
fontSize: "80%"
|
|
774
796
|
}
|
|
775
797
|
});
|
|
776
|
-
const imageDialog = /*@__PURE__*/GardState.Field.define({
|
|
777
|
-
create: () => null,
|
|
778
|
-
update(value, tr) {
|
|
779
|
-
for (let e of tr.effects)
|
|
780
|
-
if (e.is(setImageDialog))
|
|
781
|
-
return e.value ? tr.state.selection : null;
|
|
782
|
-
return value && value.map(tr.changes, tr.state);
|
|
783
|
-
},
|
|
784
|
-
provide: f => [
|
|
785
|
-
GardState.prec.lowest(Panel.show.from(f, val => val && createImagePanel)),
|
|
786
|
-
imageDialogTheme
|
|
787
|
-
]
|
|
788
|
-
});
|
|
789
798
|
|
|
790
799
|
function baseSupport() {
|
|
791
|
-
return [GardState.schemaElement.of(ImageAlt), image.button,
|
|
800
|
+
return [GardState.schemaElement.of(ImageAlt), image.button, imageDialogTheme, image.keyBinding, image.dropHandler];
|
|
792
801
|
}
|
|
802
|
+
const ImageGroup = /*@__PURE__*/(() => KeyBinding.Group.define({ description: imagePhrases.ref("group_image"), rank: 90 }))();
|
|
793
803
|
function image() {
|
|
794
804
|
return [GardState.schemaElement.of(Image), baseSupport()];
|
|
795
805
|
}
|
|
@@ -816,6 +826,7 @@ const resizeTheme = /*@__PURE__*/Wordgard.theme({
|
|
|
816
826
|
}
|
|
817
827
|
});
|
|
818
828
|
const setResizing = /*@__PURE__*/Transaction.Effect.define({
|
|
829
|
+
name: "setImageResize",
|
|
819
830
|
map: (value, mapping) => {
|
|
820
831
|
let newPos = mapping.mapPos(value.target, 1, "after");
|
|
821
832
|
return newPos == null ? undefined : { target: newPos, resizing: value.resizing };
|
|
@@ -827,6 +838,7 @@ const handleElt = /*@__PURE__*/(() => Elt.mk("svg:svg", { class: "wg-resize-hand
|
|
|
827
838
|
]))();
|
|
828
839
|
const resizeWrapper = /*@__PURE__*/(() => Decoration.Point.wrapper(Elt.mk("span", { class: "wg-resize-hover" }, [handleElt, 0]), { target: "img" }))();
|
|
829
840
|
const resizeState = /*@__PURE__*/GardState.Field.define({
|
|
841
|
+
name: "imageResize",
|
|
830
842
|
create: () => ({ target: -1, resizing: -1, deco: Decoration.Point.none }),
|
|
831
843
|
update: (value, tr) => {
|
|
832
844
|
for (let e of tr.effects) {
|
|
@@ -910,8 +922,18 @@ const resizeHandlers = /*@__PURE__*/(() => [
|
|
|
910
922
|
return false;
|
|
911
923
|
};
|
|
912
924
|
imageResizing.keyBindings = [
|
|
913
|
-
KeyBinding.of({
|
|
914
|
-
|
|
925
|
+
KeyBinding.of({
|
|
926
|
+
key: "Ctrl-Alt-l", mac: "Ctrl-Cmd-l",
|
|
927
|
+
run: imageResizing.resizeCommand(1.1, true),
|
|
928
|
+
description: imagePhrases.ref("resize_up"),
|
|
929
|
+
group: ImageGroup
|
|
930
|
+
}),
|
|
931
|
+
KeyBinding.of({
|
|
932
|
+
key: "Ctrl-Alt-k", mac: "Ctrl-Cmd-k",
|
|
933
|
+
run: imageResizing.resizeCommand(0.9091, true),
|
|
934
|
+
description: imagePhrases.ref("resize_down"),
|
|
935
|
+
group: ImageGroup
|
|
936
|
+
}),
|
|
915
937
|
];
|
|
916
938
|
imageResizing.dragHandle = [
|
|
917
939
|
GardState.prec.high(resizeHandlers),
|
|
@@ -921,7 +943,12 @@ const resizeHandlers = /*@__PURE__*/(() => [
|
|
|
921
943
|
];
|
|
922
944
|
;return imageResizing})(imageResizing);
|
|
923
945
|
;image = /*@__PURE__*/(function (image) {
|
|
924
|
-
image.keyBinding = KeyBinding.of({
|
|
946
|
+
image.keyBinding = KeyBinding.of({
|
|
947
|
+
key: "Ctrl-Alt-i", mac: "Ctrl-Cmd-i",
|
|
948
|
+
run: insertImage,
|
|
949
|
+
description: imagePhrases.ref("insert_image"),
|
|
950
|
+
group: ImageGroup
|
|
951
|
+
});
|
|
925
952
|
image.button = Menu.Button.define({
|
|
926
953
|
run: insertImage,
|
|
927
954
|
active: state => !!activeImage(state.sel),
|
|
@@ -1164,9 +1191,11 @@ class ColorPicker {
|
|
|
1164
1191
|
];
|
|
1165
1192
|
}
|
|
1166
1193
|
ColorPicker.width = GardState.Facet.define({
|
|
1194
|
+
name: "colorPickerWidth",
|
|
1167
1195
|
combine: values => values.length ? values[0] : 10
|
|
1168
1196
|
});
|
|
1169
1197
|
ColorPicker.options = GardState.Facet.define({
|
|
1198
|
+
name: "colorPickerOptions",
|
|
1170
1199
|
combine: values => values.length ? values[0] : defaultColors()
|
|
1171
1200
|
});
|
|
1172
1201
|
ColorPicker.theme = Wordgard.styles({
|
|
@@ -1247,11 +1276,9 @@ const backgroundPicker = /*@__PURE__*/Menu.CustomControl.define({
|
|
|
1247
1276
|
function toggleLink(wg) {
|
|
1248
1277
|
if (wg.state.readOnly)
|
|
1249
1278
|
return false;
|
|
1250
|
-
let open = Dialog.get(wg,
|
|
1279
|
+
let open = Dialog.get(wg, toggleLink);
|
|
1251
1280
|
if (open) {
|
|
1252
|
-
|
|
1253
|
-
wg.focus();
|
|
1254
|
-
Dialog.close(wg, "wg-link-dialog");
|
|
1281
|
+
open.close();
|
|
1255
1282
|
return true;
|
|
1256
1283
|
}
|
|
1257
1284
|
let { selection, doc } = wg.state;
|
|
@@ -1269,11 +1296,14 @@ function toggleLink(wg) {
|
|
|
1269
1296
|
}
|
|
1270
1297
|
else {
|
|
1271
1298
|
Dialog.show(wg, {
|
|
1299
|
+
key: toggleLink,
|
|
1272
1300
|
label: phrases.get(wg.state, "link_target"),
|
|
1273
1301
|
input: { type: "text", name: "url" },
|
|
1274
1302
|
submitLabel: phrases.get(wg.state, "create_link"),
|
|
1275
1303
|
class: "wg-link-dialog",
|
|
1276
|
-
focus: true
|
|
1304
|
+
focus: true,
|
|
1305
|
+
closedBy: tr => !!tr.selection,
|
|
1306
|
+
tooltip: { pos: wg.state.selection.from }
|
|
1277
1307
|
}).result.then(form => {
|
|
1278
1308
|
wg.focus();
|
|
1279
1309
|
let url = form && form.elements.namedItem("url")?.value;
|
|
@@ -1304,8 +1334,9 @@ function computeLinkTooltip(state) {
|
|
|
1304
1334
|
create: () => renderLinkTooltip(link.value)
|
|
1305
1335
|
};
|
|
1306
1336
|
}
|
|
1307
|
-
const closeLinkTooltip = /*@__PURE__*/Transaction.Effect.define();
|
|
1337
|
+
const closeLinkTooltip = /*@__PURE__*/Transaction.Effect.define({ name: "closeLinkTooltip" });
|
|
1308
1338
|
const linkTooltipField = /*@__PURE__*/GardState.Field.define({
|
|
1339
|
+
name: "linkTooltip",
|
|
1309
1340
|
create: computeLinkTooltip,
|
|
1310
1341
|
update(value, tr) {
|
|
1311
1342
|
if (tr.effects.some(e => e.is(closeLinkTooltip)))
|
|
@@ -1347,6 +1378,8 @@ function link() {
|
|
|
1347
1378
|
link_1.keyBinding = KeyBinding.of({
|
|
1348
1379
|
key: "Mod-k",
|
|
1349
1380
|
run: toggleLink,
|
|
1381
|
+
description: phrases.ref("create_link"),
|
|
1382
|
+
group: KeyBinding.Group.Inline
|
|
1350
1383
|
});
|
|
1351
1384
|
link_1.button = Menu.Button.define({
|
|
1352
1385
|
run: toggleLink,
|
|
@@ -1385,12 +1418,9 @@ function link() {
|
|
|
1385
1418
|
})),
|
|
1386
1419
|
linkTooltipTheme
|
|
1387
1420
|
];
|
|
1388
|
-
link_1.pasteOver = Wordgard.pasteHandler.of((wg, event) => {
|
|
1389
|
-
let { selection } = wg.state
|
|
1390
|
-
if (
|
|
1391
|
-
return false;
|
|
1392
|
-
let text = data.getData("text/plain") || data.getData("Text") || data.getData("text/uri-list");
|
|
1393
|
-
if (!text || !/^(https?|mailto|xmpp|data):[^ ]+$/.test(text))
|
|
1421
|
+
link_1.pasteOver = Wordgard.pasteHandler.of((wg, event, slice, html, text) => {
|
|
1422
|
+
let { selection } = wg.state;
|
|
1423
|
+
if (selection.empty || !/^(https?|mailto|xmpp|data):[^ ]+$/.test(text))
|
|
1394
1424
|
return false;
|
|
1395
1425
|
let link = Link.of(text);
|
|
1396
1426
|
let changes = ChangeSet.create(wg.state.doc, { from: selection.from, to: selection.to, add: link });
|
|
@@ -1429,4 +1459,4 @@ function fullSchema() {
|
|
|
1429
1459
|
];
|
|
1430
1460
|
}
|
|
1431
1461
|
|
|
1432
|
-
export { ColorPicker, alignment, backgroundColor, basicMarks, basicSchema, blockDoc, blockquote, bulletList, code, codeBlock, color, direction, emphasis, figure, fullSchema, heading, horizontalRule, image, imageResizing, inlineDoc, inlineMarks, inlineSchema, lineBreak, link, orderedList, paragraph, strikethrough, strong, subscript, superscript, underline };
|
|
1462
|
+
export { ColorPicker, alignment, backgroundColor, basicMarks, basicSchema, blockDoc, blockquote, bulletList, code, codeBlock, codeBlockLanguage, color, direction, emphasis, figure, fullSchema, heading, horizontalRule, image, imageResizing, inlineDoc, inlineMarks, inlineSchema, lineBreak, link, orderedList, paragraph, strikethrough, strong, subscript, superscript, underline };
|
package/dist/set.d.ts
CHANGED
|
@@ -195,9 +195,10 @@ declare class PointSet<T extends PointSet.Value> implements Set<T> {
|
|
|
195
195
|
/**
|
|
196
196
|
Get the value at the given position, if any. If there's multiple
|
|
197
197
|
values at that position, the one with the lowest side is
|
|
198
|
-
returned.
|
|
198
|
+
returned. If a predicate is given, only points that satisfy it
|
|
199
|
+
are returned.
|
|
199
200
|
*/
|
|
200
|
-
at(pos: number): T | undefined;
|
|
201
|
+
at(pos: number, pred?: (value: T) => boolean): T | undefined;
|
|
201
202
|
/**
|
|
202
203
|
Adjust the points for a set of document changes. Returns a new
|
|
203
204
|
set with the adjusted points. May delete points when the content
|