@dxos/react-ui-editor 0.5.9-main.f099efe → 0.5.9-next.73dcc17

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.
@@ -3163,6 +3163,10 @@ var formattingKeymap = (options = {}) => {
3163
3163
  {
3164
3164
  key: "meta-b",
3165
3165
  run: toggleStrong
3166
+ },
3167
+ {
3168
+ key: "meta-i",
3169
+ run: toggleEmphasis
3166
3170
  }
3167
3171
  ])
3168
3172
  ];
@@ -3584,13 +3588,6 @@ var markdownHighlightStyle = (readonly) => {
3584
3588
  tag: tags.strikethrough,
3585
3589
  class: strikethrough
3586
3590
  },
3587
- // Naked URLs.
3588
- {
3589
- tag: [
3590
- markdownTags.URL
3591
- ],
3592
- class: inlineUrl
3593
- },
3594
3591
  // NOTE: The `markdown` extension configures extensions for `lezer` to parse markdown tokens (incl. below).
3595
3592
  // However, since `codeLanguages` is also defined, the `lezer` will not parse fenced code blocks,
3596
3593
  // when a language is specified. In this case, the syntax highlighting extensions will colorize
@@ -3623,6 +3620,101 @@ var markdownHighlightStyle = (readonly) => {
3623
3620
  });
3624
3621
  };
3625
3622
 
3623
+ // packages/ui/react-ui-editor/src/extensions/markdown/linkPaste.ts
3624
+ import { syntaxTree as syntaxTree2 } from "@codemirror/language";
3625
+ import { Transaction } from "@codemirror/state";
3626
+ import { ViewPlugin as ViewPlugin4 } from "@codemirror/view";
3627
+ var VALID_PROTOCOLS = [
3628
+ "http:",
3629
+ "https:",
3630
+ "mailto:",
3631
+ "tel:"
3632
+ ];
3633
+ var createTextLink = (text, url) => `[${text}](${url})`;
3634
+ var createUrlLink = (url) => {
3635
+ const displayUrl = formatUrlForDisplay(url);
3636
+ return `[${displayUrl}](${url})`;
3637
+ };
3638
+ var formatUrlForDisplay = (url) => {
3639
+ const withoutProtocol = url.replace(/^https?:\/\//, "");
3640
+ return truncateQueryParams(withoutProtocol);
3641
+ };
3642
+ var truncateQueryParams = (url, maxQueryLength = 15) => {
3643
+ const [urlBase, queryString] = url.split("?");
3644
+ if (!queryString) {
3645
+ return urlBase;
3646
+ }
3647
+ if (queryString.length > maxQueryLength) {
3648
+ const truncatedQuery = queryString.slice(0, maxQueryLength) + "...";
3649
+ return `${urlBase}?${truncatedQuery}`;
3650
+ } else {
3651
+ return `${urlBase}?${queryString}`;
3652
+ }
3653
+ };
3654
+ var isValidUrl = (str) => {
3655
+ try {
3656
+ const url = new URL(str);
3657
+ return VALID_PROTOCOLS.includes(url.protocol);
3658
+ } catch (e) {
3659
+ return false;
3660
+ }
3661
+ };
3662
+ var onNextUpdate = (callback) => setTimeout(callback, 0);
3663
+ var linkPastePlugin = ViewPlugin4.fromClass(class {
3664
+ constructor(view) {
3665
+ this.view = view;
3666
+ }
3667
+ update(update2) {
3668
+ for (const tr of update2.transactions) {
3669
+ const event = tr.annotation(Transaction.userEvent);
3670
+ if (event === "input.paste") {
3671
+ this.handleInputRead(this.view, tr);
3672
+ }
3673
+ }
3674
+ }
3675
+ handleInputRead(view, tr) {
3676
+ const changes = tr.changes;
3677
+ if (changes.empty) {
3678
+ return;
3679
+ }
3680
+ changes.iterChangedRanges((fromA, toA, fromB, toB) => {
3681
+ const insertedText = view.state.sliceDoc(fromB, toB);
3682
+ if (isValidUrl(insertedText) && !this.isInCodeBlock(view.state, fromB)) {
3683
+ const replacedText = tr.startState.sliceDoc(fromA, toA);
3684
+ onNextUpdate(() => {
3685
+ view.dispatch(this.createLinkTransaction(view.state, fromA, toB, insertedText, replacedText));
3686
+ });
3687
+ }
3688
+ });
3689
+ }
3690
+ /**
3691
+ * Determines if a given position is within a code block.
3692
+ * Traverses the syntax tree upwards from the position,
3693
+ * checking for CodeBlock or FencedCode nodes.
3694
+ */
3695
+ isInCodeBlock(state2, pos) {
3696
+ const tree = syntaxTree2(state2);
3697
+ let node = tree.resolveInner(pos, -1);
3698
+ while (node) {
3699
+ if (node.name.includes("Code") || node.name.includes("FencedCode")) {
3700
+ return true;
3701
+ }
3702
+ node = node.parent;
3703
+ }
3704
+ return false;
3705
+ }
3706
+ createLinkTransaction(state2, from, to, url, text) {
3707
+ const linkText = text.trim() ? createTextLink(text, url) : createUrlLink(url);
3708
+ return state2.update({
3709
+ changes: {
3710
+ from,
3711
+ to,
3712
+ insert: linkText
3713
+ }
3714
+ });
3715
+ }
3716
+ });
3717
+
3626
3718
  // packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
3627
3719
  var createMarkdownExtensions = ({ themeMode } = {}) => {
3628
3720
  return [
@@ -3648,6 +3740,7 @@ var createMarkdownExtensions = ({ themeMode } = {}) => {
3648
3740
  themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle),
3649
3741
  // Custom styles.
3650
3742
  syntaxHighlighting(markdownHighlightStyle()),
3743
+ linkPastePlugin,
3651
3744
  keymap7.of([
3652
3745
  // https://codemirror.net/docs/ref/#commands.indentWithTab
3653
3746
  indentWithTab2,
@@ -3660,9 +3753,9 @@ var createMarkdownExtensions = ({ themeMode } = {}) => {
3660
3753
  };
3661
3754
 
3662
3755
  // packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
3663
- import { syntaxTree as syntaxTree2 } from "@codemirror/language";
3756
+ import { syntaxTree as syntaxTree3 } from "@codemirror/language";
3664
3757
  import { RangeSetBuilder as RangeSetBuilder2, StateEffect as StateEffect4 } from "@codemirror/state";
3665
- import { EditorView as EditorView12, Decoration as Decoration5, WidgetType as WidgetType3, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
3758
+ import { EditorView as EditorView12, Decoration as Decoration5, WidgetType as WidgetType3, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
3666
3759
  import { mx as mx2 } from "@dxos/react-ui-theme";
3667
3760
  var HorizontalRuleWidget = class extends WidgetType3 {
3668
3761
  toDOM() {
@@ -3761,7 +3854,7 @@ var buildDecorations = (view, options, focus) => {
3761
3854
  const atomicDeco = new RangeSetBuilder2();
3762
3855
  const { state: state2 } = view;
3763
3856
  for (const { from, to } of view.visibleRanges) {
3764
- syntaxTree2(state2).iterate({
3857
+ syntaxTree3(state2).iterate({
3765
3858
  from,
3766
3859
  to,
3767
3860
  enter: (node) => {
@@ -3878,7 +3971,7 @@ var buildDecorations = (view, options, focus) => {
3878
3971
  var forceUpdate = StateEffect4.define();
3879
3972
  var decorateMarkdown = (options = {}) => {
3880
3973
  return [
3881
- ViewPlugin4.fromClass(class {
3974
+ ViewPlugin5.fromClass(class {
3882
3975
  constructor(view) {
3883
3976
  ({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations(view, options, view.hasFocus));
3884
3977
  }
@@ -3967,7 +4060,7 @@ var formattingStyles = EditorView12.baseTheme({
3967
4060
  });
3968
4061
 
3969
4062
  // packages/ui/react-ui-editor/src/extensions/markdown/image.ts
3970
- import { syntaxTree as syntaxTree3 } from "@codemirror/language";
4063
+ import { syntaxTree as syntaxTree4 } from "@codemirror/language";
3971
4064
  import { StateField as StateField5 } from "@codemirror/state";
3972
4065
  import { Decoration as Decoration6, EditorView as EditorView13, WidgetType as WidgetType4 } from "@codemirror/view";
3973
4066
  var image = (options = {}) => {
@@ -4010,7 +4103,7 @@ var preloadImage = (url) => {
4010
4103
  var buildDecorations2 = (from, to, state2) => {
4011
4104
  const decorations = [];
4012
4105
  const cursor = state2.selection.main.head;
4013
- syntaxTree3(state2).iterate({
4106
+ syntaxTree4(state2).iterate({
4014
4107
  enter: (node) => {
4015
4108
  if (node.name === "Image") {
4016
4109
  const urlNode = node.node.getChild("URL");
@@ -4050,11 +4143,11 @@ var imageUpload = (options = {}) => {
4050
4143
  };
4051
4144
 
4052
4145
  // packages/ui/react-ui-editor/src/extensions/markdown/link.ts
4053
- import { syntaxTree as syntaxTree4 } from "@codemirror/language";
4146
+ import { syntaxTree as syntaxTree5 } from "@codemirror/language";
4054
4147
  import { hoverTooltip as hoverTooltip2 } from "@codemirror/view";
4055
4148
  import { tooltipContent } from "@dxos/react-ui-theme";
4056
4149
  var linkTooltip = (render) => hoverTooltip2((view, pos, side) => {
4057
- const syntax = syntaxTree4(view.state).resolveInner(pos, side);
4150
+ const syntax = syntaxTree5(view.state).resolveInner(pos, side);
4058
4151
  let link = null;
4059
4152
  for (let i = 0, node = syntax; !link && node && i < 5; node = node.parent, i++) {
4060
4153
  link = node.name === "Link" ? node : null;
@@ -4084,7 +4177,7 @@ var linkTooltip = (render) => hoverTooltip2((view, pos, side) => {
4084
4177
  });
4085
4178
 
4086
4179
  // packages/ui/react-ui-editor/src/extensions/markdown/table.ts
4087
- import { syntaxTree as syntaxTree5 } from "@codemirror/language";
4180
+ import { syntaxTree as syntaxTree6 } from "@codemirror/language";
4088
4181
  import { RangeSetBuilder as RangeSetBuilder3, StateField as StateField6 } from "@codemirror/state";
4089
4182
  import { Decoration as Decoration7, EditorView as EditorView14, WidgetType as WidgetType5 } from "@codemirror/view";
4090
4183
  var table = (options = {}) => {
@@ -4103,7 +4196,7 @@ var update = (state2, options) => {
4103
4196
  const table2 = getTable();
4104
4197
  return table2.rows?.[table2.rows.length - 1];
4105
4198
  };
4106
- syntaxTree5(state2).iterate({
4199
+ syntaxTree6(state2).iterate({
4107
4200
  enter: (node) => {
4108
4201
  switch (node.name) {
4109
4202
  case "Table": {
@@ -4263,7 +4356,7 @@ var EditorModes = {
4263
4356
  };
4264
4357
 
4265
4358
  // packages/ui/react-ui-editor/src/extensions/state.ts
4266
- import { Transaction } from "@codemirror/state";
4359
+ import { Transaction as Transaction2 } from "@codemirror/state";
4267
4360
  import { EditorView as EditorView15, keymap as keymap9 } from "@codemirror/view";
4268
4361
  import { debounce as debounce2 } from "@dxos/async";
4269
4362
  import { invariant as invariant4 } from "@dxos/invariant";
@@ -4339,7 +4432,7 @@ var state = ({ getState, setState } = {}) => {
4339
4432
  yMargin: 0
4340
4433
  }),
4341
4434
  selection: state2.selection,
4342
- annotations: Transaction.userEvent.of(scrollAnnotation)
4435
+ annotations: Transaction2.userEvent.of(scrollAnnotation)
4343
4436
  });
4344
4437
  }
4345
4438
  return true;