@dxos/react-ui-editor 0.5.9-main.17d92ec → 0.5.9-main.1c50f63

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.
@@ -3588,13 +3588,6 @@ var markdownHighlightStyle = (readonly) => {
3588
3588
  tag: tags.strikethrough,
3589
3589
  class: strikethrough
3590
3590
  },
3591
- // Naked URLs.
3592
- {
3593
- tag: [
3594
- markdownTags.URL
3595
- ],
3596
- class: inlineUrl
3597
- },
3598
3591
  // NOTE: The `markdown` extension configures extensions for `lezer` to parse markdown tokens (incl. below).
3599
3592
  // However, since `codeLanguages` is also defined, the `lezer` will not parse fenced code blocks,
3600
3593
  // when a language is specified. In this case, the syntax highlighting extensions will colorize
@@ -3627,6 +3620,101 @@ var markdownHighlightStyle = (readonly) => {
3627
3620
  });
3628
3621
  };
3629
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
+
3630
3718
  // packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
3631
3719
  var createMarkdownExtensions = ({ themeMode } = {}) => {
3632
3720
  return [
@@ -3652,6 +3740,7 @@ var createMarkdownExtensions = ({ themeMode } = {}) => {
3652
3740
  themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle),
3653
3741
  // Custom styles.
3654
3742
  syntaxHighlighting(markdownHighlightStyle()),
3743
+ linkPastePlugin,
3655
3744
  keymap7.of([
3656
3745
  // https://codemirror.net/docs/ref/#commands.indentWithTab
3657
3746
  indentWithTab2,
@@ -3664,9 +3753,9 @@ var createMarkdownExtensions = ({ themeMode } = {}) => {
3664
3753
  };
3665
3754
 
3666
3755
  // packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
3667
- import { syntaxTree as syntaxTree2 } from "@codemirror/language";
3756
+ import { syntaxTree as syntaxTree3 } from "@codemirror/language";
3668
3757
  import { RangeSetBuilder as RangeSetBuilder2, StateEffect as StateEffect4 } from "@codemirror/state";
3669
- 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";
3670
3759
  import { mx as mx2 } from "@dxos/react-ui-theme";
3671
3760
  var HorizontalRuleWidget = class extends WidgetType3 {
3672
3761
  toDOM() {
@@ -3765,7 +3854,7 @@ var buildDecorations = (view, options, focus) => {
3765
3854
  const atomicDeco = new RangeSetBuilder2();
3766
3855
  const { state: state2 } = view;
3767
3856
  for (const { from, to } of view.visibleRanges) {
3768
- syntaxTree2(state2).iterate({
3857
+ syntaxTree3(state2).iterate({
3769
3858
  from,
3770
3859
  to,
3771
3860
  enter: (node) => {
@@ -3882,7 +3971,7 @@ var buildDecorations = (view, options, focus) => {
3882
3971
  var forceUpdate = StateEffect4.define();
3883
3972
  var decorateMarkdown = (options = {}) => {
3884
3973
  return [
3885
- ViewPlugin4.fromClass(class {
3974
+ ViewPlugin5.fromClass(class {
3886
3975
  constructor(view) {
3887
3976
  ({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations(view, options, view.hasFocus));
3888
3977
  }
@@ -3971,7 +4060,7 @@ var formattingStyles = EditorView12.baseTheme({
3971
4060
  });
3972
4061
 
3973
4062
  // packages/ui/react-ui-editor/src/extensions/markdown/image.ts
3974
- import { syntaxTree as syntaxTree3 } from "@codemirror/language";
4063
+ import { syntaxTree as syntaxTree4 } from "@codemirror/language";
3975
4064
  import { StateField as StateField5 } from "@codemirror/state";
3976
4065
  import { Decoration as Decoration6, EditorView as EditorView13, WidgetType as WidgetType4 } from "@codemirror/view";
3977
4066
  var image = (options = {}) => {
@@ -4014,7 +4103,7 @@ var preloadImage = (url) => {
4014
4103
  var buildDecorations2 = (from, to, state2) => {
4015
4104
  const decorations = [];
4016
4105
  const cursor = state2.selection.main.head;
4017
- syntaxTree3(state2).iterate({
4106
+ syntaxTree4(state2).iterate({
4018
4107
  enter: (node) => {
4019
4108
  if (node.name === "Image") {
4020
4109
  const urlNode = node.node.getChild("URL");
@@ -4054,11 +4143,11 @@ var imageUpload = (options = {}) => {
4054
4143
  };
4055
4144
 
4056
4145
  // packages/ui/react-ui-editor/src/extensions/markdown/link.ts
4057
- import { syntaxTree as syntaxTree4 } from "@codemirror/language";
4146
+ import { syntaxTree as syntaxTree5 } from "@codemirror/language";
4058
4147
  import { hoverTooltip as hoverTooltip2 } from "@codemirror/view";
4059
4148
  import { tooltipContent } from "@dxos/react-ui-theme";
4060
4149
  var linkTooltip = (render) => hoverTooltip2((view, pos, side) => {
4061
- const syntax = syntaxTree4(view.state).resolveInner(pos, side);
4150
+ const syntax = syntaxTree5(view.state).resolveInner(pos, side);
4062
4151
  let link = null;
4063
4152
  for (let i = 0, node = syntax; !link && node && i < 5; node = node.parent, i++) {
4064
4153
  link = node.name === "Link" ? node : null;
@@ -4088,7 +4177,7 @@ var linkTooltip = (render) => hoverTooltip2((view, pos, side) => {
4088
4177
  });
4089
4178
 
4090
4179
  // packages/ui/react-ui-editor/src/extensions/markdown/table.ts
4091
- import { syntaxTree as syntaxTree5 } from "@codemirror/language";
4180
+ import { syntaxTree as syntaxTree6 } from "@codemirror/language";
4092
4181
  import { RangeSetBuilder as RangeSetBuilder3, StateField as StateField6 } from "@codemirror/state";
4093
4182
  import { Decoration as Decoration7, EditorView as EditorView14, WidgetType as WidgetType5 } from "@codemirror/view";
4094
4183
  var table = (options = {}) => {
@@ -4107,7 +4196,7 @@ var update = (state2, options) => {
4107
4196
  const table2 = getTable();
4108
4197
  return table2.rows?.[table2.rows.length - 1];
4109
4198
  };
4110
- syntaxTree5(state2).iterate({
4199
+ syntaxTree6(state2).iterate({
4111
4200
  enter: (node) => {
4112
4201
  switch (node.name) {
4113
4202
  case "Table": {
@@ -4267,7 +4356,7 @@ var EditorModes = {
4267
4356
  };
4268
4357
 
4269
4358
  // packages/ui/react-ui-editor/src/extensions/state.ts
4270
- import { Transaction } from "@codemirror/state";
4359
+ import { Transaction as Transaction2 } from "@codemirror/state";
4271
4360
  import { EditorView as EditorView15, keymap as keymap9 } from "@codemirror/view";
4272
4361
  import { debounce as debounce2 } from "@dxos/async";
4273
4362
  import { invariant as invariant4 } from "@dxos/invariant";
@@ -4343,7 +4432,7 @@ var state = ({ getState, setState } = {}) => {
4343
4432
  yMargin: 0
4344
4433
  }),
4345
4434
  selection: state2.selection,
4346
- annotations: Transaction.userEvent.of(scrollAnnotation)
4435
+ annotations: Transaction2.userEvent.of(scrollAnnotation)
4347
4436
  });
4348
4437
  }
4349
4438
  return true;