@vonage/vivid 4.23.0 → 4.24.0

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 (49) hide show
  1. package/custom-elements.json +574 -642
  2. package/lib/file-picker/file-picker.d.ts +2 -2
  3. package/lib/file-picker/locale.d.ts +1 -0
  4. package/lib/rich-text-editor/locale.d.ts +9 -0
  5. package/lib/rich-text-editor/menubar/menubar.d.ts +334 -1
  6. package/lib/searchable-select/locale.d.ts +1 -0
  7. package/lib/searchable-select/searchable-select.d.ts +1 -0
  8. package/lib/tabs/tabs.d.ts +5 -21
  9. package/locales/de-DE.cjs +15 -1
  10. package/locales/de-DE.js +15 -1
  11. package/locales/en-GB.cjs +15 -1
  12. package/locales/en-GB.js +15 -1
  13. package/locales/en-US.cjs +15 -1
  14. package/locales/en-US.js +15 -1
  15. package/locales/ja-JP.cjs +15 -1
  16. package/locales/ja-JP.js +15 -1
  17. package/locales/zh-CN.cjs +15 -1
  18. package/locales/zh-CN.js +15 -1
  19. package/package.json +1 -1
  20. package/shared/button.cjs +6 -3
  21. package/shared/button.js +6 -3
  22. package/shared/definition12.cjs +1 -1
  23. package/shared/definition12.js +1 -1
  24. package/shared/definition17.cjs +4 -1
  25. package/shared/definition17.js +4 -1
  26. package/shared/definition22.cjs +8 -2
  27. package/shared/definition22.js +8 -2
  28. package/shared/definition26.cjs +13 -2
  29. package/shared/definition26.js +13 -2
  30. package/shared/definition43.cjs +96 -32
  31. package/shared/definition43.js +96 -32
  32. package/shared/definition44.cjs +74 -4
  33. package/shared/definition44.js +74 -4
  34. package/shared/definition45.cjs +7 -1
  35. package/shared/definition45.js +7 -1
  36. package/shared/definition50.cjs +1 -1
  37. package/shared/definition50.js +1 -1
  38. package/shared/definition53.cjs +219 -297
  39. package/shared/definition53.js +221 -299
  40. package/shared/localization/Locale.d.ts +2 -0
  41. package/shared/vivid-element.cjs +1 -1
  42. package/shared/vivid-element.js +1 -1
  43. package/styles/core/all.css +1 -1
  44. package/styles/core/theme.css +1 -1
  45. package/styles/core/typography.css +1 -1
  46. package/styles/tokens/theme-dark.css +4 -4
  47. package/styles/tokens/theme-light.css +4 -4
  48. package/styles/tokens/vivid-2-compat.css +1 -1
  49. package/vivid.api.json +33 -3
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const vividElement = require('./vivid-element.cjs');
4
+ const localized = require('./localized.cjs');
4
5
  const definition$2 = require('./definition11.cjs');
5
6
  const definition = require('./definition23.cjs');
6
7
  const definition$3 = require('./definition60.cjs');
@@ -24,7 +25,7 @@ var __decorateClass$1 = (decorators, target, key, kind) => {
24
25
  if (result) __defProp$1(target, key, result);
25
26
  return result;
26
27
  };
27
- class MenuBar extends vividElement.VividElement {
28
+ class MenuBar extends localized.Localized(vividElement.VividElement) {
28
29
  get #textEditorElement() {
29
30
  return this.parentElement;
30
31
  }
@@ -162,7 +163,7 @@ const MENU_BAR_ITEMS = {
162
163
  const optionTag = context.tagFor(option.ListboxOption);
163
164
  const tooltipTag = context.tagFor(definition$3.Tooltip);
164
165
  return vividElement.html`
165
- <${tooltipTag} text="Text Block Type" placement="top">
166
+ <${tooltipTag} text="${(_, { parent }) => parent.locale.richTextEditor.textBlockType}" placement="top">
166
167
  <${selectTag}
167
168
  scale="condensed"
168
169
  shape="rounded"
@@ -220,11 +221,11 @@ const MENU_BAR_ITEMS = {
220
221
  ${repeat.repeat(
221
222
  (_) => TEXT_DECORATION_ITEMS,
222
223
  vividElement.html`
223
- <${tooltipTag} text="${(x) => x.text}" placement="top">
224
+ <${tooltipTag} text="${(x, { parentContext: { parent } }) => parent.locale.richTextEditor[x.value]}" placement="top">
224
225
  <${buttonTag}
225
226
  class="selection-button"
226
227
  slot="anchor"
227
- aria-label="${(x) => x.text}"
228
+ aria-label="${(x, { parentContext: { parent } }) => parent.locale.richTextEditor[x.value]}"
228
229
  size="super-condensed"
229
230
  appearance="ghost-light"
230
231
  shape="rounded"
@@ -259,7 +260,7 @@ const MENU_BAR_ITEMS = {
259
260
  aria-label="Text Size"
260
261
  placement="bottom-end"
261
262
  >
262
- <${tooltipTag} slot="anchor" text="Text Size" placement="top">
263
+ <${tooltipTag} slot="anchor" text="${(_, { parent }) => parent.locale.richTextEditor.textSize}" placement="top">
263
264
  <${buttonTag}
264
265
  slot="anchor"
265
266
  aria-label="Open text size menu"
@@ -3319,7 +3320,7 @@ class ParseContext {
3319
3320
  value = value.replace(/\r\n?/g, "\n");
3320
3321
  }
3321
3322
  if (value)
3322
- this.insertNode(this.parser.schema.text(value), marks);
3323
+ this.insertNode(this.parser.schema.text(value), marks, !/\S/.test(value));
3323
3324
  this.findInText(dom);
3324
3325
  }
3325
3326
  else {
@@ -3383,7 +3384,7 @@ class ParseContext {
3383
3384
  ignoreFallback(dom, marks) {
3384
3385
  // Ignored BR nodes should at least create an inline context
3385
3386
  if (dom.nodeName == "BR" && (!this.top.type || !this.top.type.inlineContent))
3386
- this.findPlace(this.parser.schema.text("-"), marks);
3387
+ this.findPlace(this.parser.schema.text("-"), marks, true);
3387
3388
  }
3388
3389
  // Run any style parser associated with the node's styles. Either
3389
3390
  // return an updated array of marks, or null to indicate some of the
@@ -3431,7 +3432,7 @@ class ParseContext {
3431
3432
  marks = inner;
3432
3433
  }
3433
3434
  }
3434
- else if (!this.insertNode(nodeType.create(rule.attrs), marks)) {
3435
+ else if (!this.insertNode(nodeType.create(rule.attrs), marks, dom.nodeName == "BR")) {
3435
3436
  this.leafFallback(dom, marks);
3436
3437
  }
3437
3438
  }
@@ -3448,7 +3449,7 @@ class ParseContext {
3448
3449
  }
3449
3450
  else if (rule.getContent) {
3450
3451
  this.findInside(dom);
3451
- rule.getContent(dom, this.parser.schema).forEach(node => this.insertNode(node, marks));
3452
+ rule.getContent(dom, this.parser.schema).forEach(node => this.insertNode(node, marks, false));
3452
3453
  }
3453
3454
  else {
3454
3455
  let contentDOM = dom;
@@ -3479,19 +3480,22 @@ class ParseContext {
3479
3480
  // Try to find a way to fit the given node type into the current
3480
3481
  // context. May add intermediate wrappers and/or leave non-solid
3481
3482
  // nodes that we're in.
3482
- findPlace(node, marks) {
3483
+ findPlace(node, marks, cautious) {
3483
3484
  let route, sync;
3484
- for (let depth = this.open; depth >= 0; depth--) {
3485
+ for (let depth = this.open, penalty = 0; depth >= 0; depth--) {
3485
3486
  let cx = this.nodes[depth];
3486
3487
  let found = cx.findWrapping(node);
3487
- if (found && (!route || route.length > found.length)) {
3488
+ if (found && (!route || route.length > found.length + penalty)) {
3488
3489
  route = found;
3489
3490
  sync = cx;
3490
3491
  if (!found.length)
3491
3492
  break;
3492
3493
  }
3493
- if (cx.solid)
3494
- break;
3494
+ if (cx.solid) {
3495
+ if (cautious)
3496
+ break;
3497
+ penalty += 2;
3498
+ }
3495
3499
  }
3496
3500
  if (!route)
3497
3501
  return null;
@@ -3501,13 +3505,13 @@ class ParseContext {
3501
3505
  return marks;
3502
3506
  }
3503
3507
  // Try to insert the given node, adjusting the context when needed.
3504
- insertNode(node, marks) {
3508
+ insertNode(node, marks, cautious) {
3505
3509
  if (node.isInline && this.needsBlock && !this.top.type) {
3506
3510
  let block = this.textblockFromContext();
3507
3511
  if (block)
3508
3512
  marks = this.enterInner(block, null, marks);
3509
3513
  }
3510
- let innerMarks = this.findPlace(node, marks);
3514
+ let innerMarks = this.findPlace(node, marks, cautious);
3511
3515
  if (innerMarks) {
3512
3516
  this.closeExtra();
3513
3517
  let top = this.top;
@@ -3525,7 +3529,7 @@ class ParseContext {
3525
3529
  // Try to start a node of the given type, adjusting the context when
3526
3530
  // necessary.
3527
3531
  enter(type, attrs, marks, preserveWS) {
3528
- let innerMarks = this.findPlace(type.create(attrs), marks);
3532
+ let innerMarks = this.findPlace(type.create(attrs), marks, false);
3529
3533
  if (innerMarks)
3530
3534
  innerMarks = this.enterInner(type, attrs, marks, true, preserveWS);
3531
3535
  return innerMarks;
@@ -4659,7 +4663,7 @@ class ReplaceStep extends Step {
4659
4663
  let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1);
4660
4664
  if (from.deletedAcross && to.deletedAcross)
4661
4665
  return null;
4662
- return new ReplaceStep(from.pos, Math.max(from.pos, to.pos), this.slice);
4666
+ return new ReplaceStep(from.pos, Math.max(from.pos, to.pos), this.slice, this.structure);
4663
4667
  }
4664
4668
  merge(other) {
4665
4669
  if (!(other instanceof ReplaceStep) || other.structure || this.structure)
@@ -5967,19 +5971,26 @@ class Transform {
5967
5971
  return this;
5968
5972
  }
5969
5973
  /**
5970
- Remove a mark (or a mark of the given type) from the node at
5974
+ Remove a mark (or all marks of the given type) from the node at
5971
5975
  position `pos`.
5972
5976
  */
5973
5977
  removeNodeMark(pos, mark) {
5974
- if (!(mark instanceof Mark)) {
5975
- let node = this.doc.nodeAt(pos);
5976
- if (!node)
5977
- throw new RangeError("No node at position " + pos);
5978
- mark = mark.isInSet(node.marks);
5979
- if (!mark)
5980
- return this;
5978
+ let node = this.doc.nodeAt(pos);
5979
+ if (!node)
5980
+ throw new RangeError("No node at position " + pos);
5981
+ if (mark instanceof Mark) {
5982
+ if (mark.isInSet(node.marks))
5983
+ this.step(new RemoveNodeMarkStep(pos, mark));
5984
+ }
5985
+ else {
5986
+ let set = node.marks, found, steps = [];
5987
+ while (found = mark.isInSet(set)) {
5988
+ steps.push(new RemoveNodeMarkStep(pos, found));
5989
+ set = found.removeFromSet(set);
5990
+ }
5991
+ for (let i = steps.length - 1; i >= 0; i--)
5992
+ this.step(steps[i]);
5981
5993
  }
5982
- this.step(new RemoveNodeMarkStep(pos, mark));
5983
5994
  return this;
5984
5995
  }
5985
5996
  /**
@@ -10003,7 +10014,7 @@ function maybeWrapTrusted(html) {
10003
10014
  // innerHTML, even on a detached document. This wraps the string in
10004
10015
  // a way that makes the browser allow us to use its parser again.
10005
10016
  if (!_policy)
10006
- _policy = trustedTypes.createPolicy("ProseMirrorClipboard", { createHTML: (s) => s });
10017
+ _policy = trustedTypes.defaultPolicy || trustedTypes.createPolicy("ProseMirrorClipboard", { createHTML: (s) => s });
10007
10018
  return _policy.createHTML(html);
10008
10019
  }
10009
10020
  function readHTML(html) {
@@ -10694,6 +10705,10 @@ class Dragging {
10694
10705
  }
10695
10706
  }
10696
10707
  const dragCopyModifier = mac$3 ? "altKey" : "ctrlKey";
10708
+ function dragMoves(view, event) {
10709
+ let moves = view.someProp("dragCopies", test => !test(event));
10710
+ return moves != null ? moves : !event[dragCopyModifier];
10711
+ }
10697
10712
  handlers.dragstart = (view, _event) => {
10698
10713
  let event = _event;
10699
10714
  let mouseDown = view.input.mouseDown;
@@ -10723,7 +10738,7 @@ handlers.dragstart = (view, _event) => {
10723
10738
  event.dataTransfer.effectAllowed = "copyMove";
10724
10739
  if (!brokenClipboardAPI)
10725
10740
  event.dataTransfer.setData("text/plain", text);
10726
- view.dragging = new Dragging(slice, !event[dragCopyModifier], node);
10741
+ view.dragging = new Dragging(slice, dragMoves(view, event), node);
10727
10742
  };
10728
10743
  handlers.dragend = view => {
10729
10744
  let dragging = view.dragging;
@@ -10750,7 +10765,7 @@ editHandlers.drop = (view, _event) => {
10750
10765
  else {
10751
10766
  slice = parseFromClipboard(view, getText(event.dataTransfer), brokenClipboardAPI ? null : event.dataTransfer.getData("text/html"), false, $mouse);
10752
10767
  }
10753
- let move = !!(dragging && !event[dragCopyModifier]);
10768
+ let move = !!(dragging && dragMoves(view, event));
10754
10769
  if (view.someProp("handleDrop", f => f(view, event, slice || Slice.empty, move))) {
10755
10770
  event.preventDefault();
10756
10771
  return;
@@ -12035,9 +12050,11 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
12035
12050
  // as being an iOS enter press), just dispatch an Enter key instead.
12036
12051
  if (((ios && view.input.lastIOSEnter > Date.now() - 225 &&
12037
12052
  (!inlineChange || addedNodes.some(n => n.nodeName == "DIV" || n.nodeName == "P"))) ||
12038
- (!inlineChange && $from.pos < parse.doc.content.size && !$from.sameParent($to) &&
12053
+ (!inlineChange && $from.pos < parse.doc.content.size &&
12054
+ (!$from.sameParent($to) || !$from.parent.inlineContent) &&
12055
+ !/\S/.test(parse.doc.textBetween($from.pos, $to.pos, "", "")) &&
12039
12056
  (nextSel = Selection.findFrom(parse.doc.resolve($from.pos + 1), 1, true)) &&
12040
- nextSel.head == $to.pos)) &&
12057
+ nextSel.head > $from.pos)) &&
12041
12058
  view.someProp("handleKeyDown", f => f(view, keyEvent(13, "Enter")))) {
12042
12059
  view.input.lastIOSEnter = 0;
12043
12060
  return;
@@ -13378,6 +13395,8 @@ function splitBlockAs(splitNode) {
13378
13395
  types[0] = deflt ? { type: deflt } : null;
13379
13396
  can = canSplit(tr.doc, splitPos, types.length, types);
13380
13397
  }
13398
+ if (!can)
13399
+ return false;
13381
13400
  tr.split(splitPos, types.length, types);
13382
13401
  if (!atEnd && atStart && $from.node(splitDepth).type != deflt) {
13383
13402
  let first = tr.mapping.map($from.before(splitDepth)), $first = tr.doc.resolve(first);
@@ -13889,6 +13908,50 @@ function setTextBlockType(styles, type) {
13889
13908
  styles.textBlockType = type;
13890
13909
  }
13891
13910
  }
13911
+ function createEnterKeymapPlugin() {
13912
+ return keymap({
13913
+ ["Shift-Enter"]: (state, dispatch) => {
13914
+ const { schema } = state;
13915
+ const br = schema.nodes.hard_break;
13916
+ const { $from, $to } = state.selection;
13917
+ if ($from.sameParent($to)) {
13918
+ dispatch && dispatch(state.tr.replaceSelectionWith(br.create()).scrollIntoView());
13919
+ } else {
13920
+ if (dispatch) {
13921
+ const tr = state.tr;
13922
+ const lastSelectionBlock = state.doc.resolve($to.end());
13923
+ tr.delete(lastSelectionBlock.start(), $to.pos);
13924
+ tr.delete($from.pos, lastSelectionBlock.start() - 1);
13925
+ tr.insert($from.pos, br.create());
13926
+ const newSelection = TextSelection.create(tr.doc, $from.pos + 1);
13927
+ tr.setSelection(newSelection);
13928
+ dispatch(tr.scrollIntoView());
13929
+ }
13930
+ }
13931
+ return true;
13932
+ },
13933
+ Enter: (state, dispatch) => {
13934
+ const { schema } = state;
13935
+ const paragraph = schema.nodes.paragraph;
13936
+ const { $from, empty } = state.selection;
13937
+ if (!empty || $from.parent.type !== paragraph) {
13938
+ return false;
13939
+ }
13940
+ const tr = state.tr;
13941
+ const marks = $from.marks();
13942
+ tr.split($from.pos);
13943
+ if (marks.length > 0) {
13944
+ const newParaStart = $from.pos + 1;
13945
+ const zeroWidthSpace = "​";
13946
+ const content = schema.text(zeroWidthSpace, marks);
13947
+ tr.insert(newParaStart, content);
13948
+ tr.setSelection(TextSelection.create(tr.doc, newParaStart + 1));
13949
+ }
13950
+ dispatch && dispatch(tr.scrollIntoView());
13951
+ return true;
13952
+ }
13953
+ });
13954
+ }
13892
13955
  function createSelectionChangePlugin(onSelectionChange) {
13893
13956
  return new Plugin({
13894
13957
  view: () => ({
@@ -13969,6 +14032,7 @@ class ProseMirrorFacade {
13969
14032
  const plugins = [
13970
14033
  createPlaceholderPlugin(),
13971
14034
  createSelectionChangePlugin(this.#onSelectionChange),
14035
+ createEnterKeymapPlugin(),
13972
14036
  keymap(baseKeymap)
13973
14037
  ];
13974
14038
  const state = EditorState.create({
@@ -1,4 +1,5 @@
1
1
  import { V as VividElement, a as attr, h as html, i as defineVividComponent, n as nullableNumberConverter, g as createRegisterFunction } from './vivid-element.js';
2
+ import { L as Localized } from './localized.js';
2
3
  import { B as Button, b as buttonDefinition } from './definition11.js';
3
4
  import { D as Divider, d as dividerDefinition } from './definition23.js';
4
5
  import { T as Tooltip, t as tooltipDefinition } from './definition60.js';
@@ -22,7 +23,7 @@ var __decorateClass$1 = (decorators, target, key, kind) => {
22
23
  if (result) __defProp$1(target, key, result);
23
24
  return result;
24
25
  };
25
- class MenuBar extends VividElement {
26
+ class MenuBar extends Localized(VividElement) {
26
27
  get #textEditorElement() {
27
28
  return this.parentElement;
28
29
  }
@@ -160,7 +161,7 @@ const MENU_BAR_ITEMS = {
160
161
  const optionTag = context.tagFor(ListboxOption);
161
162
  const tooltipTag = context.tagFor(Tooltip);
162
163
  return html`
163
- <${tooltipTag} text="Text Block Type" placement="top">
164
+ <${tooltipTag} text="${(_, { parent }) => parent.locale.richTextEditor.textBlockType}" placement="top">
164
165
  <${selectTag}
165
166
  scale="condensed"
166
167
  shape="rounded"
@@ -218,11 +219,11 @@ const MENU_BAR_ITEMS = {
218
219
  ${repeat(
219
220
  (_) => TEXT_DECORATION_ITEMS,
220
221
  html`
221
- <${tooltipTag} text="${(x) => x.text}" placement="top">
222
+ <${tooltipTag} text="${(x, { parentContext: { parent } }) => parent.locale.richTextEditor[x.value]}" placement="top">
222
223
  <${buttonTag}
223
224
  class="selection-button"
224
225
  slot="anchor"
225
- aria-label="${(x) => x.text}"
226
+ aria-label="${(x, { parentContext: { parent } }) => parent.locale.richTextEditor[x.value]}"
226
227
  size="super-condensed"
227
228
  appearance="ghost-light"
228
229
  shape="rounded"
@@ -257,7 +258,7 @@ const MENU_BAR_ITEMS = {
257
258
  aria-label="Text Size"
258
259
  placement="bottom-end"
259
260
  >
260
- <${tooltipTag} slot="anchor" text="Text Size" placement="top">
261
+ <${tooltipTag} slot="anchor" text="${(_, { parent }) => parent.locale.richTextEditor.textSize}" placement="top">
261
262
  <${buttonTag}
262
263
  slot="anchor"
263
264
  aria-label="Open text size menu"
@@ -3317,7 +3318,7 @@ class ParseContext {
3317
3318
  value = value.replace(/\r\n?/g, "\n");
3318
3319
  }
3319
3320
  if (value)
3320
- this.insertNode(this.parser.schema.text(value), marks);
3321
+ this.insertNode(this.parser.schema.text(value), marks, !/\S/.test(value));
3321
3322
  this.findInText(dom);
3322
3323
  }
3323
3324
  else {
@@ -3381,7 +3382,7 @@ class ParseContext {
3381
3382
  ignoreFallback(dom, marks) {
3382
3383
  // Ignored BR nodes should at least create an inline context
3383
3384
  if (dom.nodeName == "BR" && (!this.top.type || !this.top.type.inlineContent))
3384
- this.findPlace(this.parser.schema.text("-"), marks);
3385
+ this.findPlace(this.parser.schema.text("-"), marks, true);
3385
3386
  }
3386
3387
  // Run any style parser associated with the node's styles. Either
3387
3388
  // return an updated array of marks, or null to indicate some of the
@@ -3429,7 +3430,7 @@ class ParseContext {
3429
3430
  marks = inner;
3430
3431
  }
3431
3432
  }
3432
- else if (!this.insertNode(nodeType.create(rule.attrs), marks)) {
3433
+ else if (!this.insertNode(nodeType.create(rule.attrs), marks, dom.nodeName == "BR")) {
3433
3434
  this.leafFallback(dom, marks);
3434
3435
  }
3435
3436
  }
@@ -3446,7 +3447,7 @@ class ParseContext {
3446
3447
  }
3447
3448
  else if (rule.getContent) {
3448
3449
  this.findInside(dom);
3449
- rule.getContent(dom, this.parser.schema).forEach(node => this.insertNode(node, marks));
3450
+ rule.getContent(dom, this.parser.schema).forEach(node => this.insertNode(node, marks, false));
3450
3451
  }
3451
3452
  else {
3452
3453
  let contentDOM = dom;
@@ -3477,19 +3478,22 @@ class ParseContext {
3477
3478
  // Try to find a way to fit the given node type into the current
3478
3479
  // context. May add intermediate wrappers and/or leave non-solid
3479
3480
  // nodes that we're in.
3480
- findPlace(node, marks) {
3481
+ findPlace(node, marks, cautious) {
3481
3482
  let route, sync;
3482
- for (let depth = this.open; depth >= 0; depth--) {
3483
+ for (let depth = this.open, penalty = 0; depth >= 0; depth--) {
3483
3484
  let cx = this.nodes[depth];
3484
3485
  let found = cx.findWrapping(node);
3485
- if (found && (!route || route.length > found.length)) {
3486
+ if (found && (!route || route.length > found.length + penalty)) {
3486
3487
  route = found;
3487
3488
  sync = cx;
3488
3489
  if (!found.length)
3489
3490
  break;
3490
3491
  }
3491
- if (cx.solid)
3492
- break;
3492
+ if (cx.solid) {
3493
+ if (cautious)
3494
+ break;
3495
+ penalty += 2;
3496
+ }
3493
3497
  }
3494
3498
  if (!route)
3495
3499
  return null;
@@ -3499,13 +3503,13 @@ class ParseContext {
3499
3503
  return marks;
3500
3504
  }
3501
3505
  // Try to insert the given node, adjusting the context when needed.
3502
- insertNode(node, marks) {
3506
+ insertNode(node, marks, cautious) {
3503
3507
  if (node.isInline && this.needsBlock && !this.top.type) {
3504
3508
  let block = this.textblockFromContext();
3505
3509
  if (block)
3506
3510
  marks = this.enterInner(block, null, marks);
3507
3511
  }
3508
- let innerMarks = this.findPlace(node, marks);
3512
+ let innerMarks = this.findPlace(node, marks, cautious);
3509
3513
  if (innerMarks) {
3510
3514
  this.closeExtra();
3511
3515
  let top = this.top;
@@ -3523,7 +3527,7 @@ class ParseContext {
3523
3527
  // Try to start a node of the given type, adjusting the context when
3524
3528
  // necessary.
3525
3529
  enter(type, attrs, marks, preserveWS) {
3526
- let innerMarks = this.findPlace(type.create(attrs), marks);
3530
+ let innerMarks = this.findPlace(type.create(attrs), marks, false);
3527
3531
  if (innerMarks)
3528
3532
  innerMarks = this.enterInner(type, attrs, marks, true, preserveWS);
3529
3533
  return innerMarks;
@@ -4657,7 +4661,7 @@ class ReplaceStep extends Step {
4657
4661
  let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1);
4658
4662
  if (from.deletedAcross && to.deletedAcross)
4659
4663
  return null;
4660
- return new ReplaceStep(from.pos, Math.max(from.pos, to.pos), this.slice);
4664
+ return new ReplaceStep(from.pos, Math.max(from.pos, to.pos), this.slice, this.structure);
4661
4665
  }
4662
4666
  merge(other) {
4663
4667
  if (!(other instanceof ReplaceStep) || other.structure || this.structure)
@@ -5965,19 +5969,26 @@ class Transform {
5965
5969
  return this;
5966
5970
  }
5967
5971
  /**
5968
- Remove a mark (or a mark of the given type) from the node at
5972
+ Remove a mark (or all marks of the given type) from the node at
5969
5973
  position `pos`.
5970
5974
  */
5971
5975
  removeNodeMark(pos, mark) {
5972
- if (!(mark instanceof Mark)) {
5973
- let node = this.doc.nodeAt(pos);
5974
- if (!node)
5975
- throw new RangeError("No node at position " + pos);
5976
- mark = mark.isInSet(node.marks);
5977
- if (!mark)
5978
- return this;
5976
+ let node = this.doc.nodeAt(pos);
5977
+ if (!node)
5978
+ throw new RangeError("No node at position " + pos);
5979
+ if (mark instanceof Mark) {
5980
+ if (mark.isInSet(node.marks))
5981
+ this.step(new RemoveNodeMarkStep(pos, mark));
5982
+ }
5983
+ else {
5984
+ let set = node.marks, found, steps = [];
5985
+ while (found = mark.isInSet(set)) {
5986
+ steps.push(new RemoveNodeMarkStep(pos, found));
5987
+ set = found.removeFromSet(set);
5988
+ }
5989
+ for (let i = steps.length - 1; i >= 0; i--)
5990
+ this.step(steps[i]);
5979
5991
  }
5980
- this.step(new RemoveNodeMarkStep(pos, mark));
5981
5992
  return this;
5982
5993
  }
5983
5994
  /**
@@ -10001,7 +10012,7 @@ function maybeWrapTrusted(html) {
10001
10012
  // innerHTML, even on a detached document. This wraps the string in
10002
10013
  // a way that makes the browser allow us to use its parser again.
10003
10014
  if (!_policy)
10004
- _policy = trustedTypes.createPolicy("ProseMirrorClipboard", { createHTML: (s) => s });
10015
+ _policy = trustedTypes.defaultPolicy || trustedTypes.createPolicy("ProseMirrorClipboard", { createHTML: (s) => s });
10005
10016
  return _policy.createHTML(html);
10006
10017
  }
10007
10018
  function readHTML(html) {
@@ -10692,6 +10703,10 @@ class Dragging {
10692
10703
  }
10693
10704
  }
10694
10705
  const dragCopyModifier = mac$3 ? "altKey" : "ctrlKey";
10706
+ function dragMoves(view, event) {
10707
+ let moves = view.someProp("dragCopies", test => !test(event));
10708
+ return moves != null ? moves : !event[dragCopyModifier];
10709
+ }
10695
10710
  handlers.dragstart = (view, _event) => {
10696
10711
  let event = _event;
10697
10712
  let mouseDown = view.input.mouseDown;
@@ -10721,7 +10736,7 @@ handlers.dragstart = (view, _event) => {
10721
10736
  event.dataTransfer.effectAllowed = "copyMove";
10722
10737
  if (!brokenClipboardAPI)
10723
10738
  event.dataTransfer.setData("text/plain", text);
10724
- view.dragging = new Dragging(slice, !event[dragCopyModifier], node);
10739
+ view.dragging = new Dragging(slice, dragMoves(view, event), node);
10725
10740
  };
10726
10741
  handlers.dragend = view => {
10727
10742
  let dragging = view.dragging;
@@ -10748,7 +10763,7 @@ editHandlers.drop = (view, _event) => {
10748
10763
  else {
10749
10764
  slice = parseFromClipboard(view, getText(event.dataTransfer), brokenClipboardAPI ? null : event.dataTransfer.getData("text/html"), false, $mouse);
10750
10765
  }
10751
- let move = !!(dragging && !event[dragCopyModifier]);
10766
+ let move = !!(dragging && dragMoves(view, event));
10752
10767
  if (view.someProp("handleDrop", f => f(view, event, slice || Slice.empty, move))) {
10753
10768
  event.preventDefault();
10754
10769
  return;
@@ -12033,9 +12048,11 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
12033
12048
  // as being an iOS enter press), just dispatch an Enter key instead.
12034
12049
  if (((ios && view.input.lastIOSEnter > Date.now() - 225 &&
12035
12050
  (!inlineChange || addedNodes.some(n => n.nodeName == "DIV" || n.nodeName == "P"))) ||
12036
- (!inlineChange && $from.pos < parse.doc.content.size && !$from.sameParent($to) &&
12051
+ (!inlineChange && $from.pos < parse.doc.content.size &&
12052
+ (!$from.sameParent($to) || !$from.parent.inlineContent) &&
12053
+ !/\S/.test(parse.doc.textBetween($from.pos, $to.pos, "", "")) &&
12037
12054
  (nextSel = Selection.findFrom(parse.doc.resolve($from.pos + 1), 1, true)) &&
12038
- nextSel.head == $to.pos)) &&
12055
+ nextSel.head > $from.pos)) &&
12039
12056
  view.someProp("handleKeyDown", f => f(view, keyEvent(13, "Enter")))) {
12040
12057
  view.input.lastIOSEnter = 0;
12041
12058
  return;
@@ -13376,6 +13393,8 @@ function splitBlockAs(splitNode) {
13376
13393
  types[0] = deflt ? { type: deflt } : null;
13377
13394
  can = canSplit(tr.doc, splitPos, types.length, types);
13378
13395
  }
13396
+ if (!can)
13397
+ return false;
13379
13398
  tr.split(splitPos, types.length, types);
13380
13399
  if (!atEnd && atStart && $from.node(splitDepth).type != deflt) {
13381
13400
  let first = tr.mapping.map($from.before(splitDepth)), $first = tr.doc.resolve(first);
@@ -13887,6 +13906,50 @@ function setTextBlockType(styles, type) {
13887
13906
  styles.textBlockType = type;
13888
13907
  }
13889
13908
  }
13909
+ function createEnterKeymapPlugin() {
13910
+ return keymap({
13911
+ ["Shift-Enter"]: (state, dispatch) => {
13912
+ const { schema } = state;
13913
+ const br = schema.nodes.hard_break;
13914
+ const { $from, $to } = state.selection;
13915
+ if ($from.sameParent($to)) {
13916
+ dispatch && dispatch(state.tr.replaceSelectionWith(br.create()).scrollIntoView());
13917
+ } else {
13918
+ if (dispatch) {
13919
+ const tr = state.tr;
13920
+ const lastSelectionBlock = state.doc.resolve($to.end());
13921
+ tr.delete(lastSelectionBlock.start(), $to.pos);
13922
+ tr.delete($from.pos, lastSelectionBlock.start() - 1);
13923
+ tr.insert($from.pos, br.create());
13924
+ const newSelection = TextSelection.create(tr.doc, $from.pos + 1);
13925
+ tr.setSelection(newSelection);
13926
+ dispatch(tr.scrollIntoView());
13927
+ }
13928
+ }
13929
+ return true;
13930
+ },
13931
+ Enter: (state, dispatch) => {
13932
+ const { schema } = state;
13933
+ const paragraph = schema.nodes.paragraph;
13934
+ const { $from, empty } = state.selection;
13935
+ if (!empty || $from.parent.type !== paragraph) {
13936
+ return false;
13937
+ }
13938
+ const tr = state.tr;
13939
+ const marks = $from.marks();
13940
+ tr.split($from.pos);
13941
+ if (marks.length > 0) {
13942
+ const newParaStart = $from.pos + 1;
13943
+ const zeroWidthSpace = "​";
13944
+ const content = schema.text(zeroWidthSpace, marks);
13945
+ tr.insert(newParaStart, content);
13946
+ tr.setSelection(TextSelection.create(tr.doc, newParaStart + 1));
13947
+ }
13948
+ dispatch && dispatch(tr.scrollIntoView());
13949
+ return true;
13950
+ }
13951
+ });
13952
+ }
13890
13953
  function createSelectionChangePlugin(onSelectionChange) {
13891
13954
  return new Plugin({
13892
13955
  view: () => ({
@@ -13967,6 +14030,7 @@ class ProseMirrorFacade {
13967
14030
  const plugins = [
13968
14031
  createPlaceholderPlugin(),
13969
14032
  createSelectionChangePlugin(this.#onSelectionChange),
14033
+ createEnterKeymapPlugin(),
13970
14034
  keymap(baseKeymap)
13971
14035
  ];
13972
14036
  const state = EditorState.create({