@dxos/react-ui-editor 0.4.5-main.519e45d → 0.4.5-main.5fcdf8d
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/lib/browser/index.mjs +505 -291
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts +5 -5
- package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/hooks.stories.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/code.d.ts +2 -0
- package/dist/types/src/extensions/markdown/code.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/heading.d.ts +6 -0
- package/dist/types/src/extensions/markdown/heading.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/hr.d.ts +2 -0
- package/dist/types/src/extensions/markdown/hr.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/index.d.ts +4 -1
- package/dist/types/src/extensions/markdown/index.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/link.d.ts +11 -1
- package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/tasklist.d.ts +3 -0
- package/dist/types/src/extensions/markdown/tasklist.d.ts.map +1 -0
- package/package.json +24 -24
- package/src/components/TextEditor/MarkdownEditor.stories.tsx +37 -29
- package/src/components/TextEditor/hooks.stories.tsx +10 -2
- package/src/components/Toolbar/Toolbar.stories.tsx +6 -2
- package/src/extensions/markdown/code.ts +162 -0
- package/src/extensions/markdown/formatting.ts +64 -1
- package/src/extensions/markdown/heading.ts +59 -0
- package/src/extensions/markdown/hr.ts +71 -0
- package/src/extensions/markdown/index.ts +4 -1
- package/src/extensions/markdown/link.ts +185 -23
- package/src/extensions/markdown/tasklist.ts +110 -0
- package/dist/types/src/extensions/markdown/decorate.d.ts +0 -5
- package/dist/types/src/extensions/markdown/decorate.d.ts.map +0 -1
- package/src/extensions/markdown/decorate.ts +0 -301
|
@@ -8,7 +8,7 @@ import { tags as tags2 } from "@lezer/highlight";
|
|
|
8
8
|
|
|
9
9
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
10
10
|
import { EditorState as EditorState2 } from "@codemirror/state";
|
|
11
|
-
import { EditorView as
|
|
11
|
+
import { EditorView as EditorView16 } from "@codemirror/view";
|
|
12
12
|
import { useFocusableGroup } from "@fluentui/react-tabster";
|
|
13
13
|
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
14
14
|
import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useRef, useState as useState2, useMemo as useMemo2 } from "react";
|
|
@@ -765,10 +765,10 @@ var blast = (options = defaultOptions) => {
|
|
|
765
765
|
const getPoint = (view, pos) => {
|
|
766
766
|
const { left: x = 0, top: y = 0 } = view.coordsForChar(pos) ?? {};
|
|
767
767
|
const element = document.elementFromPoint(x, y);
|
|
768
|
-
const { offsetLeft: left = 0, offsetTop:
|
|
768
|
+
const { offsetLeft: left = 0, offsetTop: top2 = 0 } = view.scrollDOM.parentElement ?? {};
|
|
769
769
|
const point = {
|
|
770
770
|
x: x - left,
|
|
771
|
-
y: y -
|
|
771
|
+
y: y - top2
|
|
772
772
|
};
|
|
773
773
|
return {
|
|
774
774
|
element,
|
|
@@ -1871,207 +1871,12 @@ var createMarkdownExtensions = ({ themeMode, placeholder: _placeholder, lineWrap
|
|
|
1871
1871
|
].filter(isNotFalsy3);
|
|
1872
1872
|
};
|
|
1873
1873
|
|
|
1874
|
-
// packages/ui/react-ui-editor/src/extensions/markdown/
|
|
1874
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/code.ts
|
|
1875
1875
|
import { syntaxTree } from "@codemirror/language";
|
|
1876
1876
|
import { RangeSetBuilder } from "@codemirror/state";
|
|
1877
|
-
import { EditorView as EditorView10, Decoration as Decoration4, WidgetType as WidgetType2
|
|
1877
|
+
import { ViewPlugin as ViewPlugin3, EditorView as EditorView10, Decoration as Decoration4, WidgetType as WidgetType2 } from "@codemirror/view";
|
|
1878
1878
|
import { mx as mx2 } from "@dxos/react-ui-theme";
|
|
1879
|
-
var
|
|
1880
|
-
constructor(_className) {
|
|
1881
|
-
super();
|
|
1882
|
-
this._className = _className;
|
|
1883
|
-
}
|
|
1884
|
-
toDOM() {
|
|
1885
|
-
const el = document.createElement("span");
|
|
1886
|
-
el.innerHTML = " ";
|
|
1887
|
-
el.className = mx2("cm-code cm-codeblock", this._className);
|
|
1888
|
-
return el;
|
|
1889
|
-
}
|
|
1890
|
-
};
|
|
1891
|
-
var HorizontalRuleWidget = class extends WidgetType2 {
|
|
1892
|
-
toDOM() {
|
|
1893
|
-
const el = document.createElement("span");
|
|
1894
|
-
el.className = "cm-hr";
|
|
1895
|
-
return el;
|
|
1896
|
-
}
|
|
1897
|
-
};
|
|
1898
|
-
var LinkButton = class extends WidgetType2 {
|
|
1899
|
-
constructor(url, render) {
|
|
1900
|
-
super();
|
|
1901
|
-
this.url = url;
|
|
1902
|
-
this.render = render;
|
|
1903
|
-
}
|
|
1904
|
-
eq(other) {
|
|
1905
|
-
return this.url === other.url;
|
|
1906
|
-
}
|
|
1907
|
-
toDOM(view) {
|
|
1908
|
-
const el = document.createElement("span");
|
|
1909
|
-
this.render(el, this.url);
|
|
1910
|
-
return el;
|
|
1911
|
-
}
|
|
1912
|
-
};
|
|
1913
|
-
var CheckboxWidget = class extends WidgetType2 {
|
|
1914
|
-
constructor(_checked) {
|
|
1915
|
-
super();
|
|
1916
|
-
this._checked = _checked;
|
|
1917
|
-
}
|
|
1918
|
-
eq(other) {
|
|
1919
|
-
return this._checked === other._checked;
|
|
1920
|
-
}
|
|
1921
|
-
toDOM(view) {
|
|
1922
|
-
const input = document.createElement("input");
|
|
1923
|
-
input.className = "cm-task-checkbox";
|
|
1924
|
-
input.type = "checkbox";
|
|
1925
|
-
input.checked = this._checked;
|
|
1926
|
-
if (view.state.readOnly) {
|
|
1927
|
-
input.setAttribute("disabled", "true");
|
|
1928
|
-
} else {
|
|
1929
|
-
input.onmousedown = (event) => {
|
|
1930
|
-
const pos = view.posAtDOM(input);
|
|
1931
|
-
const text = view.state.sliceDoc(pos, pos + 3);
|
|
1932
|
-
if (text === (this._checked ? "[x]" : "[ ]")) {
|
|
1933
|
-
view.dispatch({
|
|
1934
|
-
changes: {
|
|
1935
|
-
from: pos + 1,
|
|
1936
|
-
to: pos + 2,
|
|
1937
|
-
insert: this._checked ? " " : "x"
|
|
1938
|
-
}
|
|
1939
|
-
});
|
|
1940
|
-
event.preventDefault();
|
|
1941
|
-
}
|
|
1942
|
-
};
|
|
1943
|
-
}
|
|
1944
|
-
return input;
|
|
1945
|
-
}
|
|
1946
|
-
ignoreEvent() {
|
|
1947
|
-
return false;
|
|
1948
|
-
}
|
|
1949
|
-
};
|
|
1950
|
-
var hide = Decoration4.replace({});
|
|
1951
|
-
var fencedCodeTop = Decoration4.replace({
|
|
1952
|
-
widget: new FencedCodeBoundary("cm-codeblock-end cm-codeblock-first")
|
|
1953
|
-
});
|
|
1954
|
-
var fencedCodeBottom = Decoration4.replace({
|
|
1955
|
-
widget: new FencedCodeBoundary("cm-codeblock-end cm-codeblock-last")
|
|
1956
|
-
});
|
|
1957
|
-
var horizontalRule = Decoration4.replace({
|
|
1958
|
-
widget: new HorizontalRuleWidget()
|
|
1959
|
-
});
|
|
1960
|
-
var checkedTask = Decoration4.replace({
|
|
1961
|
-
widget: new CheckboxWidget(true)
|
|
1962
|
-
});
|
|
1963
|
-
var uncheckedTask = Decoration4.replace({
|
|
1964
|
-
widget: new CheckboxWidget(false)
|
|
1965
|
-
});
|
|
1966
|
-
var editingRange = (state, range) => {
|
|
1967
|
-
const { readOnly, selection: { main: { head } } } = state;
|
|
1968
|
-
return !readOnly && head >= range.from && head <= range.to;
|
|
1969
|
-
};
|
|
1970
|
-
var MarksByParent = /* @__PURE__ */ new Set([
|
|
1971
|
-
"CodeMark",
|
|
1972
|
-
"EmphasisMark",
|
|
1973
|
-
"StrikethroughMark",
|
|
1974
|
-
"SubscriptMark",
|
|
1975
|
-
"SuperscriptMark"
|
|
1976
|
-
]);
|
|
1977
|
-
var buildDecorations = (view, options) => {
|
|
1978
|
-
const builder = new RangeSetBuilder();
|
|
1979
|
-
const { state } = view;
|
|
1980
|
-
for (const { from, to } of view.visibleRanges) {
|
|
1981
|
-
syntaxTree(state).iterate({
|
|
1982
|
-
from,
|
|
1983
|
-
to,
|
|
1984
|
-
enter: (node) => {
|
|
1985
|
-
if (node.name === "FencedCode") {
|
|
1986
|
-
const editing = editingRange(state, node);
|
|
1987
|
-
for (const block of view.viewportLineBlocks) {
|
|
1988
|
-
if (block.to < node.from) {
|
|
1989
|
-
continue;
|
|
1990
|
-
}
|
|
1991
|
-
if (block.from > node.to) {
|
|
1992
|
-
break;
|
|
1993
|
-
}
|
|
1994
|
-
const first = block.from <= node.from;
|
|
1995
|
-
const last = block.to >= node.to;
|
|
1996
|
-
if (!editing && (first || last)) {
|
|
1997
|
-
builder.add(block.from, block.to, first ? fencedCodeTop : fencedCodeBottom);
|
|
1998
|
-
} else {
|
|
1999
|
-
builder.add(block.from, block.from, Decoration4.line({
|
|
2000
|
-
class: mx2("cm-code cm-codeblock-line", first && "cm-codeblock-first", last && "cm-codeblock-last")
|
|
2001
|
-
}));
|
|
2002
|
-
}
|
|
2003
|
-
}
|
|
2004
|
-
return false;
|
|
2005
|
-
} else if (node.name === "Link") {
|
|
2006
|
-
const marks = node.node.getChildren("LinkMark");
|
|
2007
|
-
const urlNode = node.node.getChild("URL");
|
|
2008
|
-
const editing = editingRange(state, node);
|
|
2009
|
-
if (urlNode && marks.length >= 2) {
|
|
2010
|
-
const url = state.sliceDoc(urlNode.from, urlNode.to);
|
|
2011
|
-
if (!editing) {
|
|
2012
|
-
builder.add(node.from, marks[0].to, hide);
|
|
2013
|
-
}
|
|
2014
|
-
builder.add(marks[0].to, marks[1].from, Decoration4.mark({
|
|
2015
|
-
tagName: "a",
|
|
2016
|
-
attributes: {
|
|
2017
|
-
class: "cm-link",
|
|
2018
|
-
href: url,
|
|
2019
|
-
rel: "noreferrer",
|
|
2020
|
-
target: "_blank"
|
|
2021
|
-
}
|
|
2022
|
-
}));
|
|
2023
|
-
if (!editing) {
|
|
2024
|
-
builder.add(marks[1].from, node.to, options.renderLinkButton ? Decoration4.replace({
|
|
2025
|
-
widget: new LinkButton(url, options.renderLinkButton)
|
|
2026
|
-
}) : hide);
|
|
2027
|
-
}
|
|
2028
|
-
}
|
|
2029
|
-
} else if (node.name === "HeaderMark") {
|
|
2030
|
-
const parent = node.node.parent;
|
|
2031
|
-
if (/^ATX/.test(parent.name) && !editingRange(state, state.doc.lineAt(node.from))) {
|
|
2032
|
-
const next = state.doc.sliceString(node.to, node.to + 1);
|
|
2033
|
-
builder.add(node.from, node.to + (next === " " ? 1 : 0), hide);
|
|
2034
|
-
}
|
|
2035
|
-
} else if (node.name === "HorizontalRule") {
|
|
2036
|
-
if (!editingRange(state, node)) {
|
|
2037
|
-
builder.add(node.from, node.to, horizontalRule);
|
|
2038
|
-
}
|
|
2039
|
-
} else if (node.name === "TaskMarker") {
|
|
2040
|
-
if (!editingRange(state, node)) {
|
|
2041
|
-
const checked = state.doc.sliceString(node.from + 1, node.to - 1) === "x";
|
|
2042
|
-
builder.add(node.from - 2, node.from - 1, Decoration4.mark({
|
|
2043
|
-
class: "cm-task"
|
|
2044
|
-
}));
|
|
2045
|
-
builder.add(node.from, node.to, checked ? checkedTask : uncheckedTask);
|
|
2046
|
-
}
|
|
2047
|
-
} else if (MarksByParent.has(node.name)) {
|
|
2048
|
-
if (!editingRange(state, node.node.parent)) {
|
|
2049
|
-
builder.add(node.from, node.to, hide);
|
|
2050
|
-
}
|
|
2051
|
-
}
|
|
2052
|
-
}
|
|
2053
|
-
});
|
|
2054
|
-
}
|
|
2055
|
-
return builder.finish();
|
|
2056
|
-
};
|
|
2057
|
-
var decorateMarkdown = (options = {}) => {
|
|
2058
|
-
return [
|
|
2059
|
-
ViewPlugin3.fromClass(class {
|
|
2060
|
-
constructor(view) {
|
|
2061
|
-
this.decorations = buildDecorations(view, options);
|
|
2062
|
-
}
|
|
2063
|
-
update(update2) {
|
|
2064
|
-
if (update2.docChanged || update2.selectionSet || update2.viewportChanged) {
|
|
2065
|
-
this.decorations = buildDecorations(update2.view, options);
|
|
2066
|
-
}
|
|
2067
|
-
}
|
|
2068
|
-
}, {
|
|
2069
|
-
decorations: (value) => value.decorations
|
|
2070
|
-
}),
|
|
2071
|
-
formattingStyles
|
|
2072
|
-
];
|
|
2073
|
-
};
|
|
2074
|
-
var formattingStyles = EditorView10.baseTheme({
|
|
1879
|
+
var styles4 = EditorView10.baseTheme({
|
|
2075
1880
|
"& .cm-code": {
|
|
2076
1881
|
fontFamily: getToken("fontFamily.mono", []).join(",")
|
|
2077
1882
|
},
|
|
@@ -2119,28 +1924,82 @@ var formattingStyles = EditorView10.baseTheme({
|
|
|
2119
1924
|
"&::after": {
|
|
2120
1925
|
background: getToken("extend.semanticColors.input.dark")
|
|
2121
1926
|
}
|
|
2122
|
-
},
|
|
2123
|
-
"& .cm-hr": {
|
|
2124
|
-
display: "inline-block",
|
|
2125
|
-
width: "100%",
|
|
2126
|
-
height: "0",
|
|
2127
|
-
verticalAlign: "middle",
|
|
2128
|
-
borderTop: `1px solid ${getToken("extend.colors.neutral.200")}`
|
|
2129
|
-
},
|
|
2130
|
-
"& .cm-task": {
|
|
2131
|
-
color: getToken("extend.colors.blue.500")
|
|
2132
|
-
},
|
|
2133
|
-
"& .cm-task-checkbox": {
|
|
2134
|
-
marginLeft: "4px",
|
|
2135
|
-
marginRight: "4px"
|
|
2136
1927
|
}
|
|
2137
1928
|
});
|
|
1929
|
+
var getLineRange = (lines, from, to) => {
|
|
1930
|
+
const start = lines.findIndex((line) => line.from >= from);
|
|
1931
|
+
const end = lines.findIndex((line) => line.to >= to);
|
|
1932
|
+
return [
|
|
1933
|
+
start,
|
|
1934
|
+
end
|
|
1935
|
+
];
|
|
1936
|
+
};
|
|
1937
|
+
var LineWidget = class extends WidgetType2 {
|
|
1938
|
+
constructor(_className) {
|
|
1939
|
+
super();
|
|
1940
|
+
this._className = _className;
|
|
1941
|
+
}
|
|
1942
|
+
toDOM() {
|
|
1943
|
+
const el = document.createElement("span");
|
|
1944
|
+
el.innerHTML = " ";
|
|
1945
|
+
el.className = mx2("cm-code cm-codeblock", this._className);
|
|
1946
|
+
return el;
|
|
1947
|
+
}
|
|
1948
|
+
};
|
|
1949
|
+
var top = new LineWidget("cm-codeblock-end cm-codeblock-first");
|
|
1950
|
+
var bottom = new LineWidget("cm-codeblock-end cm-codeblock-last");
|
|
1951
|
+
var buildDecorations = (view) => {
|
|
1952
|
+
const builder = new RangeSetBuilder();
|
|
1953
|
+
const { state } = view;
|
|
1954
|
+
const blocks = view.viewportLineBlocks;
|
|
1955
|
+
const cursor = state.selection.main.head;
|
|
1956
|
+
for (const { from, to } of view.visibleRanges) {
|
|
1957
|
+
syntaxTree(state).iterate({
|
|
1958
|
+
enter: (node) => {
|
|
1959
|
+
if (node.name === "FencedCode") {
|
|
1960
|
+
const editing = !view.state.readOnly && cursor >= node.from && cursor <= node.to;
|
|
1961
|
+
const range = getLineRange(blocks, node.from, node.to);
|
|
1962
|
+
for (let i = range[0]; i <= range[1]; i++) {
|
|
1963
|
+
const block = blocks[i];
|
|
1964
|
+
if (!editing && (i === range[0] || i === range[1])) {
|
|
1965
|
+
builder.add(block.from, block.to, Decoration4.replace({
|
|
1966
|
+
widget: i === range[0] ? top : bottom
|
|
1967
|
+
}));
|
|
1968
|
+
} else {
|
|
1969
|
+
builder.add(block.from, block.from, Decoration4.line({
|
|
1970
|
+
class: mx2("cm-code cm-codeblock-line", i === range[0] && "cm-codeblock-first", i === range[1] && "cm-codeblock-last")
|
|
1971
|
+
}));
|
|
1972
|
+
}
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1975
|
+
},
|
|
1976
|
+
from,
|
|
1977
|
+
to
|
|
1978
|
+
});
|
|
1979
|
+
}
|
|
1980
|
+
return builder.finish();
|
|
1981
|
+
};
|
|
1982
|
+
var code2 = () => {
|
|
1983
|
+
return [
|
|
1984
|
+
ViewPlugin3.fromClass(class {
|
|
1985
|
+
constructor(view) {
|
|
1986
|
+
this.decorations = buildDecorations(view);
|
|
1987
|
+
}
|
|
1988
|
+
update(update2) {
|
|
1989
|
+
this.decorations = buildDecorations(update2.view);
|
|
1990
|
+
}
|
|
1991
|
+
}, {
|
|
1992
|
+
decorations: (value) => value.decorations
|
|
1993
|
+
}),
|
|
1994
|
+
styles4
|
|
1995
|
+
];
|
|
1996
|
+
};
|
|
2138
1997
|
|
|
2139
1998
|
// packages/ui/react-ui-editor/src/extensions/markdown/formatting.ts
|
|
2140
1999
|
import { snippet } from "@codemirror/autocomplete";
|
|
2141
2000
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
2142
|
-
import { EditorSelection } from "@codemirror/state";
|
|
2143
|
-
import { EditorView as EditorView11, keymap as keymap5 } from "@codemirror/view";
|
|
2001
|
+
import { RangeSetBuilder as RangeSetBuilder2, EditorSelection } from "@codemirror/state";
|
|
2002
|
+
import { Decoration as Decoration5, EditorView as EditorView11, keymap as keymap5, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
|
|
2144
2003
|
import { useState, useMemo } from "react";
|
|
2145
2004
|
var compareFormatting = (a, b) => a.blockType === b.blockType && a.strong === b.strong && a.emphasis === b.emphasis && a.strikethrough === b.strikethrough && a.code === b.code && a.link === b.link && a.listStyle === b.listStyle && a.blockQuote === b.blockQuote;
|
|
2146
2005
|
var Inline;
|
|
@@ -3017,7 +2876,56 @@ var formatting = (options = {}) => {
|
|
|
3017
2876
|
key: "meta-b",
|
|
3018
2877
|
run: toggleStrong
|
|
3019
2878
|
}
|
|
3020
|
-
])
|
|
2879
|
+
]),
|
|
2880
|
+
styling()
|
|
2881
|
+
];
|
|
2882
|
+
};
|
|
2883
|
+
var styling = () => {
|
|
2884
|
+
const buildDecorations7 = (view) => {
|
|
2885
|
+
const builder = new RangeSetBuilder2();
|
|
2886
|
+
const { state } = view;
|
|
2887
|
+
const cursor = state.selection.main.head;
|
|
2888
|
+
const replace = (node, marks) => {
|
|
2889
|
+
if (cursor <= node.from || cursor >= node.to) {
|
|
2890
|
+
for (const mark2 of marks) {
|
|
2891
|
+
builder.add(mark2.from, mark2.to, Decoration5.replace({}));
|
|
2892
|
+
}
|
|
2893
|
+
}
|
|
2894
|
+
};
|
|
2895
|
+
for (const { from, to } of view.visibleRanges) {
|
|
2896
|
+
syntaxTree2(state).iterate({
|
|
2897
|
+
enter: (node) => {
|
|
2898
|
+
switch (node.name) {
|
|
2899
|
+
case "Emphasis":
|
|
2900
|
+
case "StrongEmphasis": {
|
|
2901
|
+
const marks = node.node.getChildren("EmphasisMark");
|
|
2902
|
+
replace(node, marks);
|
|
2903
|
+
break;
|
|
2904
|
+
}
|
|
2905
|
+
case "Strikethrough": {
|
|
2906
|
+
const marks = node.node.getChildren("StrikethroughMark");
|
|
2907
|
+
replace(node, marks);
|
|
2908
|
+
break;
|
|
2909
|
+
}
|
|
2910
|
+
}
|
|
2911
|
+
},
|
|
2912
|
+
from,
|
|
2913
|
+
to
|
|
2914
|
+
});
|
|
2915
|
+
}
|
|
2916
|
+
return builder.finish();
|
|
2917
|
+
};
|
|
2918
|
+
return [
|
|
2919
|
+
ViewPlugin4.fromClass(class {
|
|
2920
|
+
constructor(view) {
|
|
2921
|
+
this.decorations = buildDecorations7(view);
|
|
2922
|
+
}
|
|
2923
|
+
update(update2) {
|
|
2924
|
+
this.decorations = buildDecorations7(update2.view);
|
|
2925
|
+
}
|
|
2926
|
+
}, {
|
|
2927
|
+
decorations: (value) => value.decorations
|
|
2928
|
+
})
|
|
3021
2929
|
];
|
|
3022
2930
|
};
|
|
3023
2931
|
var InlineMarker = {
|
|
@@ -3067,7 +2975,7 @@ var getFormatting = (state) => {
|
|
|
3067
2975
|
null,
|
|
3068
2976
|
null
|
|
3069
2977
|
];
|
|
3070
|
-
let
|
|
2978
|
+
let link2 = false;
|
|
3071
2979
|
let blockQuote = null;
|
|
3072
2980
|
let listStyle = null;
|
|
3073
2981
|
const stack = [];
|
|
@@ -3129,7 +3037,7 @@ var getFormatting = (state) => {
|
|
|
3129
3037
|
if (name === "BulletList" || name === "OrderedList" || name === "Blockquote") {
|
|
3130
3038
|
stack.push(name);
|
|
3131
3039
|
} else if (name === "Link") {
|
|
3132
|
-
|
|
3040
|
+
link2 = true;
|
|
3133
3041
|
} else if (Object.hasOwn(Textblocks, name) && (range.empty || node.to > range.from || node.from < range.to)) {
|
|
3134
3042
|
if (name === "Task" && stack[stack.length - 1] === "BulletList") {
|
|
3135
3043
|
stack[stack.length - 1] = "TaskList";
|
|
@@ -3204,7 +3112,7 @@ var getFormatting = (state) => {
|
|
|
3204
3112
|
emphasis: inline[1] ?? false,
|
|
3205
3113
|
strong: inline[0] ?? false,
|
|
3206
3114
|
strikethrough: inline[2] ?? false,
|
|
3207
|
-
link,
|
|
3115
|
+
link: link2,
|
|
3208
3116
|
listStyle: listStyle || null
|
|
3209
3117
|
};
|
|
3210
3118
|
};
|
|
@@ -3224,14 +3132,117 @@ var useFormattingState = () => {
|
|
|
3224
3132
|
];
|
|
3225
3133
|
};
|
|
3226
3134
|
|
|
3227
|
-
// packages/ui/react-ui-editor/src/extensions/markdown/
|
|
3135
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/heading.ts
|
|
3228
3136
|
import { syntaxTree as syntaxTree3 } from "@codemirror/language";
|
|
3137
|
+
import { RangeSetBuilder as RangeSetBuilder3 } from "@codemirror/state";
|
|
3138
|
+
import { Decoration as Decoration6, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
|
|
3139
|
+
var buildDecorations2 = (view) => {
|
|
3140
|
+
const builder = new RangeSetBuilder3();
|
|
3141
|
+
const { state } = view;
|
|
3142
|
+
const cursor = state.selection.main.head;
|
|
3143
|
+
for (const { from, to } of view.visibleRanges) {
|
|
3144
|
+
syntaxTree3(state).iterate({
|
|
3145
|
+
enter: (node) => {
|
|
3146
|
+
switch (node.name) {
|
|
3147
|
+
case "ATXHeading1":
|
|
3148
|
+
case "ATXHeading2":
|
|
3149
|
+
case "ATXHeading3":
|
|
3150
|
+
case "ATXHeading4":
|
|
3151
|
+
case "ATXHeading5":
|
|
3152
|
+
case "ATXHeading6": {
|
|
3153
|
+
const mark2 = node.node.getChild("HeaderMark");
|
|
3154
|
+
if (mark2) {
|
|
3155
|
+
if (!view.hasFocus || view.state.readOnly || cursor < node.from || cursor > node.to) {
|
|
3156
|
+
builder.add(mark2.from, mark2.to + 1, Decoration6.replace({}));
|
|
3157
|
+
}
|
|
3158
|
+
}
|
|
3159
|
+
}
|
|
3160
|
+
}
|
|
3161
|
+
},
|
|
3162
|
+
from,
|
|
3163
|
+
to
|
|
3164
|
+
});
|
|
3165
|
+
}
|
|
3166
|
+
return builder.finish();
|
|
3167
|
+
};
|
|
3168
|
+
var heading2 = () => {
|
|
3169
|
+
return [
|
|
3170
|
+
ViewPlugin5.fromClass(class {
|
|
3171
|
+
constructor(view) {
|
|
3172
|
+
this.decorations = buildDecorations2(view);
|
|
3173
|
+
}
|
|
3174
|
+
update(update2) {
|
|
3175
|
+
this.decorations = buildDecorations2(update2.view);
|
|
3176
|
+
}
|
|
3177
|
+
}, {
|
|
3178
|
+
decorations: (value) => value.decorations
|
|
3179
|
+
})
|
|
3180
|
+
];
|
|
3181
|
+
};
|
|
3182
|
+
|
|
3183
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/hr.ts
|
|
3184
|
+
import { syntaxTree as syntaxTree4 } from "@codemirror/language";
|
|
3185
|
+
import { RangeSetBuilder as RangeSetBuilder4 } from "@codemirror/state";
|
|
3186
|
+
import { Decoration as Decoration7, EditorView as EditorView12, ViewPlugin as ViewPlugin6, WidgetType as WidgetType3 } from "@codemirror/view";
|
|
3187
|
+
var styles5 = EditorView12.baseTheme({
|
|
3188
|
+
"& .cm-hr": {
|
|
3189
|
+
// Note that block-level decorations should not have vertical margins,
|
|
3190
|
+
borderTop: `1px solid ${getToken("extend.colors.neutral.200")}`
|
|
3191
|
+
}
|
|
3192
|
+
});
|
|
3193
|
+
var HorizontalRuleWidget = class extends WidgetType3 {
|
|
3194
|
+
toDOM() {
|
|
3195
|
+
const el = document.createElement("div");
|
|
3196
|
+
el.className = "cm-hr";
|
|
3197
|
+
return el;
|
|
3198
|
+
}
|
|
3199
|
+
};
|
|
3200
|
+
var decoration = Decoration7.replace({
|
|
3201
|
+
widget: new HorizontalRuleWidget()
|
|
3202
|
+
});
|
|
3203
|
+
var buildDecorations3 = (view) => {
|
|
3204
|
+
const builder = new RangeSetBuilder4();
|
|
3205
|
+
const { state } = view;
|
|
3206
|
+
const cursor = state.selection.main.head;
|
|
3207
|
+
for (const { from, to } of view.visibleRanges) {
|
|
3208
|
+
syntaxTree4(state).iterate({
|
|
3209
|
+
enter: (node) => {
|
|
3210
|
+
if (node.name === "HorizontalRule") {
|
|
3211
|
+
if (cursor <= node.from || cursor >= node.to) {
|
|
3212
|
+
builder.add(node.from, node.to, decoration);
|
|
3213
|
+
}
|
|
3214
|
+
}
|
|
3215
|
+
},
|
|
3216
|
+
from,
|
|
3217
|
+
to
|
|
3218
|
+
});
|
|
3219
|
+
}
|
|
3220
|
+
return builder.finish();
|
|
3221
|
+
};
|
|
3222
|
+
var hr = () => {
|
|
3223
|
+
return [
|
|
3224
|
+
ViewPlugin6.fromClass(class {
|
|
3225
|
+
constructor(view) {
|
|
3226
|
+
this.decorations = buildDecorations3(view);
|
|
3227
|
+
}
|
|
3228
|
+
update(update2) {
|
|
3229
|
+
this.decorations = buildDecorations3(update2.view);
|
|
3230
|
+
}
|
|
3231
|
+
}, {
|
|
3232
|
+
decorations: (value) => value.decorations
|
|
3233
|
+
}),
|
|
3234
|
+
styles5
|
|
3235
|
+
];
|
|
3236
|
+
};
|
|
3237
|
+
|
|
3238
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/image.ts
|
|
3239
|
+
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
|
3229
3240
|
import { StateField as StateField4 } from "@codemirror/state";
|
|
3230
|
-
import { Decoration as
|
|
3241
|
+
import { Decoration as Decoration8, EditorView as EditorView13, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
3231
3242
|
var image = (options = {}) => {
|
|
3232
3243
|
return StateField4.define({
|
|
3233
3244
|
create: (state) => {
|
|
3234
|
-
return
|
|
3245
|
+
return Decoration8.set(buildDecorations4(0, state.doc.length, state));
|
|
3235
3246
|
},
|
|
3236
3247
|
update: (value, tr) => {
|
|
3237
3248
|
if (!tr.docChanged && !tr.selection) {
|
|
@@ -3251,26 +3262,26 @@ var image = (options = {}) => {
|
|
|
3251
3262
|
filterFrom: from,
|
|
3252
3263
|
filterTo: to,
|
|
3253
3264
|
filter: () => false,
|
|
3254
|
-
add:
|
|
3265
|
+
add: buildDecorations4(from, to, tr.state)
|
|
3255
3266
|
});
|
|
3256
3267
|
},
|
|
3257
|
-
provide: (field) =>
|
|
3268
|
+
provide: (field) => EditorView13.decorations.from(field)
|
|
3258
3269
|
});
|
|
3259
3270
|
};
|
|
3260
|
-
var
|
|
3271
|
+
var buildDecorations4 = (from, to, state) => {
|
|
3261
3272
|
const decorations = [];
|
|
3262
3273
|
const cursor = state.selection.main.head;
|
|
3263
|
-
|
|
3274
|
+
syntaxTree5(state).iterate({
|
|
3264
3275
|
enter: (node) => {
|
|
3265
3276
|
if (node.name === "Image") {
|
|
3266
3277
|
const urlNode = node.node.getChild("URL");
|
|
3267
3278
|
if (urlNode) {
|
|
3268
|
-
const
|
|
3279
|
+
const hide = state.readOnly || cursor < node.from || cursor > node.to;
|
|
3269
3280
|
const url = state.sliceDoc(urlNode.from, urlNode.to);
|
|
3270
|
-
decorations.push(
|
|
3281
|
+
decorations.push(Decoration8.replace({
|
|
3271
3282
|
block: true,
|
|
3272
3283
|
widget: new ImageWidget(url)
|
|
3273
|
-
}).range(
|
|
3284
|
+
}).range(hide ? node.from : node.to, node.to));
|
|
3274
3285
|
}
|
|
3275
3286
|
}
|
|
3276
3287
|
},
|
|
@@ -3279,7 +3290,7 @@ var buildDecorations2 = (from, to, state) => {
|
|
|
3279
3290
|
});
|
|
3280
3291
|
return decorations;
|
|
3281
3292
|
};
|
|
3282
|
-
var ImageWidget = class extends
|
|
3293
|
+
var ImageWidget = class extends WidgetType4 {
|
|
3283
3294
|
constructor(_url) {
|
|
3284
3295
|
super();
|
|
3285
3296
|
this._url = _url;
|
|
@@ -3297,52 +3308,155 @@ var ImageWidget = class extends WidgetType3 {
|
|
|
3297
3308
|
};
|
|
3298
3309
|
|
|
3299
3310
|
// packages/ui/react-ui-editor/src/extensions/markdown/link.ts
|
|
3300
|
-
import { syntaxTree as
|
|
3301
|
-
import {
|
|
3311
|
+
import { syntaxTree as syntaxTree6 } from "@codemirror/language";
|
|
3312
|
+
import { RangeSetBuilder as RangeSetBuilder5 } from "@codemirror/state";
|
|
3313
|
+
import { hoverTooltip as hoverTooltip2, Decoration as Decoration9, ViewPlugin as ViewPlugin7, WidgetType as WidgetType5 } from "@codemirror/view";
|
|
3302
3314
|
import { tooltipContent } from "@dxos/react-ui-theme";
|
|
3303
|
-
var
|
|
3304
|
-
const
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
}
|
|
3313
|
-
const urlText = view.state.sliceDoc(url.from, url.to);
|
|
3314
|
-
return {
|
|
3315
|
-
pos: link.from,
|
|
3316
|
-
end: link.to,
|
|
3317
|
-
above: true,
|
|
3318
|
-
create: () => {
|
|
3319
|
-
const el = document.createElement("div");
|
|
3320
|
-
el.className = tooltipContent({}, "pli-2 plb-1");
|
|
3321
|
-
render(el, urlText);
|
|
3322
|
-
return {
|
|
3323
|
-
dom: el,
|
|
3324
|
-
offset: {
|
|
3325
|
-
x: 0,
|
|
3326
|
-
y: 4
|
|
3315
|
+
var link = (options = {}) => {
|
|
3316
|
+
const extensions = [
|
|
3317
|
+
ViewPlugin7.fromClass(class {
|
|
3318
|
+
constructor(view) {
|
|
3319
|
+
this.decorations = buildDecorations5(view, options);
|
|
3320
|
+
}
|
|
3321
|
+
update(update2) {
|
|
3322
|
+
if (update2.docChanged || update2.viewportChanged || update2.selectionSet) {
|
|
3323
|
+
this.decorations = buildDecorations5(update2.view, options);
|
|
3327
3324
|
}
|
|
3325
|
+
}
|
|
3326
|
+
}, {
|
|
3327
|
+
decorations: (value) => value.decorations
|
|
3328
|
+
})
|
|
3329
|
+
];
|
|
3330
|
+
if (options.onHover) {
|
|
3331
|
+
extensions.push(
|
|
3332
|
+
// https://codemirror.net/examples/tooltip
|
|
3333
|
+
// https://codemirror.net/docs/ref/#view.hoverTooltip
|
|
3334
|
+
// https://github.com/codemirror/view/blob/main/src/tooltip.ts
|
|
3335
|
+
hoverTooltip2((view, pos, side) => {
|
|
3336
|
+
const syntax = syntaxTree6(view.state).resolveInner(pos, side);
|
|
3337
|
+
let link2 = null;
|
|
3338
|
+
for (let i = 0, node = syntax; !link2 && node && i < 5; node = node.parent, i++) {
|
|
3339
|
+
link2 = node.name === "Link" ? node : null;
|
|
3340
|
+
}
|
|
3341
|
+
const url = link2 && link2.getChild("URL");
|
|
3342
|
+
if (!url || !link2) {
|
|
3343
|
+
return null;
|
|
3344
|
+
}
|
|
3345
|
+
const urlText = view.state.sliceDoc(url.from, url.to);
|
|
3346
|
+
return {
|
|
3347
|
+
pos: link2.from,
|
|
3348
|
+
end: link2.to,
|
|
3349
|
+
above: true,
|
|
3350
|
+
create: () => {
|
|
3351
|
+
const el = document.createElement("div");
|
|
3352
|
+
el.className = tooltipContent({}, "pli-2 plb-1");
|
|
3353
|
+
options.onHover(el, urlText);
|
|
3354
|
+
return {
|
|
3355
|
+
dom: el,
|
|
3356
|
+
offset: {
|
|
3357
|
+
x: 0,
|
|
3358
|
+
y: 4
|
|
3359
|
+
}
|
|
3360
|
+
};
|
|
3361
|
+
}
|
|
3362
|
+
};
|
|
3363
|
+
})
|
|
3364
|
+
);
|
|
3365
|
+
}
|
|
3366
|
+
return extensions;
|
|
3367
|
+
};
|
|
3368
|
+
var LinkButton = class extends WidgetType5 {
|
|
3369
|
+
constructor(_url, _onAttach) {
|
|
3370
|
+
super();
|
|
3371
|
+
this._url = _url;
|
|
3372
|
+
this._onAttach = _onAttach;
|
|
3373
|
+
}
|
|
3374
|
+
eq(other) {
|
|
3375
|
+
return this._url === other._url;
|
|
3376
|
+
}
|
|
3377
|
+
toDOM(view) {
|
|
3378
|
+
const el = document.createElement("span");
|
|
3379
|
+
this._onAttach(el, this._url);
|
|
3380
|
+
return el;
|
|
3381
|
+
}
|
|
3382
|
+
};
|
|
3383
|
+
var LinkText = class extends WidgetType5 {
|
|
3384
|
+
constructor(_text, _url) {
|
|
3385
|
+
super();
|
|
3386
|
+
this._text = _text;
|
|
3387
|
+
this._url = _url;
|
|
3388
|
+
}
|
|
3389
|
+
eq(other) {
|
|
3390
|
+
return this._url === other._url;
|
|
3391
|
+
}
|
|
3392
|
+
toDOM(view) {
|
|
3393
|
+
const link2 = document.createElement("a");
|
|
3394
|
+
link2.setAttribute("class", "cm-link");
|
|
3395
|
+
link2.textContent = this._text;
|
|
3396
|
+
if (this._url) {
|
|
3397
|
+
link2.setAttribute("rel", "noreferrer");
|
|
3398
|
+
link2.setAttribute("target", "_blank");
|
|
3399
|
+
link2.href = this._url;
|
|
3400
|
+
} else {
|
|
3401
|
+
link2.onclick = () => {
|
|
3402
|
+
view.dispatch({
|
|
3403
|
+
selection: {
|
|
3404
|
+
anchor: view.posAtDOM(link2)
|
|
3405
|
+
}
|
|
3406
|
+
});
|
|
3328
3407
|
};
|
|
3329
3408
|
}
|
|
3330
|
-
|
|
3331
|
-
}
|
|
3409
|
+
return link2;
|
|
3410
|
+
}
|
|
3411
|
+
};
|
|
3412
|
+
var buildDecorations5 = (view, options) => {
|
|
3413
|
+
const builder = new RangeSetBuilder5();
|
|
3414
|
+
const { state } = view;
|
|
3415
|
+
const cursor = state.selection.main.head;
|
|
3416
|
+
for (const { from, to } of view.visibleRanges) {
|
|
3417
|
+
syntaxTree6(state).iterate({
|
|
3418
|
+
enter: (node) => {
|
|
3419
|
+
if (node.name === "Link") {
|
|
3420
|
+
const marks = node.node.getChildren("LinkMark");
|
|
3421
|
+
const text = marks.length >= 2 ? state.sliceDoc(marks[0].to, marks[1].from) : "";
|
|
3422
|
+
const urlNode = node.node.getChild("URL");
|
|
3423
|
+
const url = urlNode ? state.sliceDoc(urlNode.from, urlNode.to) : "";
|
|
3424
|
+
if (!url) {
|
|
3425
|
+
return false;
|
|
3426
|
+
}
|
|
3427
|
+
if (!view.hasFocus || state.readOnly || cursor < node.from || cursor > node.to) {
|
|
3428
|
+
builder.add(node.from, node.to, Decoration9.replace({
|
|
3429
|
+
widget: new LinkText(text, options.link ? url : void 0)
|
|
3430
|
+
}));
|
|
3431
|
+
}
|
|
3432
|
+
if (options.onRender) {
|
|
3433
|
+
builder.add(node.to, node.to, Decoration9.replace({
|
|
3434
|
+
widget: new LinkButton(url, options.onRender)
|
|
3435
|
+
}));
|
|
3436
|
+
}
|
|
3437
|
+
return false;
|
|
3438
|
+
}
|
|
3439
|
+
},
|
|
3440
|
+
from,
|
|
3441
|
+
to
|
|
3442
|
+
});
|
|
3443
|
+
}
|
|
3444
|
+
return builder.finish();
|
|
3445
|
+
};
|
|
3332
3446
|
|
|
3333
3447
|
// packages/ui/react-ui-editor/src/extensions/markdown/table.ts
|
|
3334
|
-
import { syntaxTree as
|
|
3335
|
-
import { RangeSetBuilder as
|
|
3336
|
-
import { Decoration as
|
|
3448
|
+
import { syntaxTree as syntaxTree7 } from "@codemirror/language";
|
|
3449
|
+
import { RangeSetBuilder as RangeSetBuilder6, StateField as StateField5 } from "@codemirror/state";
|
|
3450
|
+
import { Decoration as Decoration10, EditorView as EditorView14, WidgetType as WidgetType6 } from "@codemirror/view";
|
|
3337
3451
|
var table = (options = {}) => {
|
|
3338
3452
|
return StateField5.define({
|
|
3339
3453
|
create: (state) => update(state, options),
|
|
3340
3454
|
update: (_, tr) => update(tr.state, options),
|
|
3341
|
-
provide: (field) =>
|
|
3455
|
+
provide: (field) => EditorView14.decorations.from(field)
|
|
3342
3456
|
});
|
|
3343
3457
|
};
|
|
3344
3458
|
var update = (state, options) => {
|
|
3345
|
-
const builder = new
|
|
3459
|
+
const builder = new RangeSetBuilder6();
|
|
3346
3460
|
const cursor = state.selection.main.head;
|
|
3347
3461
|
const tables = [];
|
|
3348
3462
|
const getTable = () => tables[tables.length - 1];
|
|
@@ -3350,7 +3464,7 @@ var update = (state, options) => {
|
|
|
3350
3464
|
const table2 = getTable();
|
|
3351
3465
|
return table2.rows?.[table2.rows.length - 1];
|
|
3352
3466
|
};
|
|
3353
|
-
|
|
3467
|
+
syntaxTree7(state).iterate({
|
|
3354
3468
|
enter: (node) => {
|
|
3355
3469
|
switch (node.name) {
|
|
3356
3470
|
case "Table": {
|
|
@@ -3381,17 +3495,17 @@ var update = (state, options) => {
|
|
|
3381
3495
|
}
|
|
3382
3496
|
});
|
|
3383
3497
|
tables.forEach((table2) => {
|
|
3384
|
-
const
|
|
3385
|
-
|
|
3498
|
+
const hide = state.readOnly || cursor < table2.from || cursor > table2.to;
|
|
3499
|
+
hide && builder.add(table2.from, table2.to, Decoration10.replace({
|
|
3386
3500
|
widget: new TableWidget(table2)
|
|
3387
3501
|
}));
|
|
3388
|
-
builder.add(table2.from, table2.to,
|
|
3502
|
+
builder.add(table2.from, table2.to, Decoration10.mark({
|
|
3389
3503
|
class: "cm-table"
|
|
3390
3504
|
}));
|
|
3391
3505
|
});
|
|
3392
3506
|
return builder.finish();
|
|
3393
3507
|
};
|
|
3394
|
-
var TableWidget = class extends
|
|
3508
|
+
var TableWidget = class extends WidgetType6 {
|
|
3395
3509
|
constructor(_table) {
|
|
3396
3510
|
super();
|
|
3397
3511
|
this._table = _table;
|
|
@@ -3428,6 +3542,103 @@ var TableWidget = class extends WidgetType4 {
|
|
|
3428
3542
|
}
|
|
3429
3543
|
};
|
|
3430
3544
|
|
|
3545
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/tasklist.ts
|
|
3546
|
+
import { syntaxTree as syntaxTree8 } from "@codemirror/language";
|
|
3547
|
+
import { RangeSetBuilder as RangeSetBuilder7 } from "@codemirror/state";
|
|
3548
|
+
import { EditorView as EditorView15, Decoration as Decoration11, WidgetType as WidgetType7, ViewPlugin as ViewPlugin8 } from "@codemirror/view";
|
|
3549
|
+
var styles6 = EditorView15.baseTheme({
|
|
3550
|
+
"& .cm-task": {
|
|
3551
|
+
color: getToken("extend.colors.blue.500")
|
|
3552
|
+
},
|
|
3553
|
+
"& .cm-task-checkbox": {
|
|
3554
|
+
marginLeft: "4px",
|
|
3555
|
+
marginRight: "4px"
|
|
3556
|
+
}
|
|
3557
|
+
});
|
|
3558
|
+
var CheckboxWidget = class extends WidgetType7 {
|
|
3559
|
+
constructor(_checked) {
|
|
3560
|
+
super();
|
|
3561
|
+
this._checked = _checked;
|
|
3562
|
+
}
|
|
3563
|
+
eq(other) {
|
|
3564
|
+
return this._checked === other._checked;
|
|
3565
|
+
}
|
|
3566
|
+
toDOM(view) {
|
|
3567
|
+
const input = document.createElement("input");
|
|
3568
|
+
input.className = "cm-task-checkbox";
|
|
3569
|
+
input.type = "checkbox";
|
|
3570
|
+
input.checked = this._checked;
|
|
3571
|
+
if (view.state.readOnly) {
|
|
3572
|
+
input.setAttribute("disabled", "true");
|
|
3573
|
+
} else {
|
|
3574
|
+
input.onmousedown = (event) => {
|
|
3575
|
+
const pos = view.posAtDOM(input);
|
|
3576
|
+
const text = view.state.sliceDoc(pos, pos + 3);
|
|
3577
|
+
if (text === (this._checked ? "[x]" : "[ ]")) {
|
|
3578
|
+
view.dispatch({
|
|
3579
|
+
changes: {
|
|
3580
|
+
from: pos + 1,
|
|
3581
|
+
to: pos + 2,
|
|
3582
|
+
insert: this._checked ? " " : "x"
|
|
3583
|
+
}
|
|
3584
|
+
});
|
|
3585
|
+
event.preventDefault();
|
|
3586
|
+
}
|
|
3587
|
+
};
|
|
3588
|
+
}
|
|
3589
|
+
return input;
|
|
3590
|
+
}
|
|
3591
|
+
ignoreEvent() {
|
|
3592
|
+
return false;
|
|
3593
|
+
}
|
|
3594
|
+
};
|
|
3595
|
+
var checkedDecoration = Decoration11.replace({
|
|
3596
|
+
widget: new CheckboxWidget(true)
|
|
3597
|
+
});
|
|
3598
|
+
var uncheckedDecoration = Decoration11.replace({
|
|
3599
|
+
widget: new CheckboxWidget(false)
|
|
3600
|
+
});
|
|
3601
|
+
var buildDecorations6 = (view) => {
|
|
3602
|
+
const builder = new RangeSetBuilder7();
|
|
3603
|
+
const { state } = view;
|
|
3604
|
+
const cursor = state.selection.main.head;
|
|
3605
|
+
for (const { from, to } of view.visibleRanges) {
|
|
3606
|
+
syntaxTree8(state).iterate({
|
|
3607
|
+
enter: (node) => {
|
|
3608
|
+
if (node.name === "TaskMarker") {
|
|
3609
|
+
if (cursor < node.from || cursor > node.to) {
|
|
3610
|
+
const checked = state.doc.sliceString(node.from + 1, node.to - 1) === "x";
|
|
3611
|
+
builder.add(node.from - 2, node.from - 1, Decoration11.mark({
|
|
3612
|
+
class: "cm-task"
|
|
3613
|
+
}));
|
|
3614
|
+
builder.add(node.from, node.to, checked ? checkedDecoration : uncheckedDecoration);
|
|
3615
|
+
}
|
|
3616
|
+
}
|
|
3617
|
+
},
|
|
3618
|
+
from,
|
|
3619
|
+
to
|
|
3620
|
+
});
|
|
3621
|
+
}
|
|
3622
|
+
return builder.finish();
|
|
3623
|
+
};
|
|
3624
|
+
var tasklist = (options = {}) => {
|
|
3625
|
+
return [
|
|
3626
|
+
ViewPlugin8.fromClass(class {
|
|
3627
|
+
constructor(view) {
|
|
3628
|
+
this.decorations = buildDecorations6(view);
|
|
3629
|
+
}
|
|
3630
|
+
update(update2) {
|
|
3631
|
+
if (update2.docChanged || update2.viewportChanged || update2.selectionSet) {
|
|
3632
|
+
this.decorations = buildDecorations6(update2.view);
|
|
3633
|
+
}
|
|
3634
|
+
}
|
|
3635
|
+
}, {
|
|
3636
|
+
decorations: (value) => value.decorations
|
|
3637
|
+
}),
|
|
3638
|
+
styles6
|
|
3639
|
+
];
|
|
3640
|
+
};
|
|
3641
|
+
|
|
3431
3642
|
// packages/ui/react-ui-editor/src/extensions/mention.ts
|
|
3432
3643
|
import { autocompletion as autocompletion2 } from "@codemirror/autocomplete";
|
|
3433
3644
|
var mention = ({ onSearch }) => {
|
|
@@ -3825,7 +4036,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
3825
4036
|
selection,
|
|
3826
4037
|
extensions: [
|
|
3827
4038
|
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
3828
|
-
|
|
4039
|
+
EditorView16.exceptionSink.of((err) => {
|
|
3829
4040
|
log3.catch(err, void 0, {
|
|
3830
4041
|
F: __dxlog_file4,
|
|
3831
4042
|
L: 113,
|
|
@@ -3835,17 +4046,17 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
3835
4046
|
}),
|
|
3836
4047
|
// Theme.
|
|
3837
4048
|
// TODO(burdon): Make configurable.
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
4049
|
+
EditorView16.baseTheme(defaultTheme),
|
|
4050
|
+
EditorView16.theme(theme ?? {}),
|
|
4051
|
+
EditorView16.darkTheme.of(themeMode === "dark"),
|
|
4052
|
+
EditorView16.editorAttributes.of({
|
|
3842
4053
|
class: slots.editor?.className ?? ""
|
|
3843
4054
|
}),
|
|
3844
|
-
|
|
4055
|
+
EditorView16.contentAttributes.of({
|
|
3845
4056
|
class: slots.content?.className ?? ""
|
|
3846
4057
|
}),
|
|
3847
4058
|
// Focus.
|
|
3848
|
-
|
|
4059
|
+
EditorView16.updateListener.of((update2) => {
|
|
3849
4060
|
update2.transactions.forEach((transaction) => {
|
|
3850
4061
|
if (transaction.isUserEvent("focus.container")) {
|
|
3851
4062
|
rootRef.current?.focus();
|
|
@@ -3853,7 +4064,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
3853
4064
|
});
|
|
3854
4065
|
}),
|
|
3855
4066
|
// State.
|
|
3856
|
-
|
|
4067
|
+
EditorView16.editable.of(!readonly),
|
|
3857
4068
|
EditorState2.readOnly.of(!!readonly),
|
|
3858
4069
|
// Storage and replication.
|
|
3859
4070
|
// NOTE: This must come before user extensions.
|
|
@@ -3862,7 +4073,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
3862
4073
|
...extensions
|
|
3863
4074
|
].filter(isNotFalsy4)
|
|
3864
4075
|
});
|
|
3865
|
-
const newView = new
|
|
4076
|
+
const newView = new EditorView16({
|
|
3866
4077
|
state,
|
|
3867
4078
|
parent: rootRef.current,
|
|
3868
4079
|
scrollTo,
|
|
@@ -4417,7 +4628,7 @@ var useEditorView = (id) => {
|
|
|
4417
4628
|
|
|
4418
4629
|
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
|
4419
4630
|
import { EditorSelection as EditorSelection2, EditorState as EditorState3 } from "@codemirror/state";
|
|
4420
|
-
import { EditorView as
|
|
4631
|
+
import { EditorView as EditorView17 } from "@codemirror/view";
|
|
4421
4632
|
import { useEffect as useEffect3, useRef as useRef3, useState as useState4 } from "react";
|
|
4422
4633
|
import { log as log5 } from "@dxos/log";
|
|
4423
4634
|
import { isNotFalsy as isNotFalsy5 } from "@dxos/util";
|
|
@@ -4434,7 +4645,7 @@ var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions }
|
|
|
4434
4645
|
selection,
|
|
4435
4646
|
extensions: [
|
|
4436
4647
|
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
4437
|
-
|
|
4648
|
+
EditorView17.exceptionSink.of((err) => {
|
|
4438
4649
|
log5.catch(err, void 0, {
|
|
4439
4650
|
F: __dxlog_file6,
|
|
4440
4651
|
L: 60,
|
|
@@ -4443,12 +4654,12 @@ var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions }
|
|
|
4443
4654
|
});
|
|
4444
4655
|
}),
|
|
4445
4656
|
extensions,
|
|
4446
|
-
|
|
4657
|
+
EditorView17.updateListener.of(() => {
|
|
4447
4658
|
onUpdate.current?.();
|
|
4448
4659
|
})
|
|
4449
4660
|
].filter(isNotFalsy5)
|
|
4450
4661
|
});
|
|
4451
|
-
view2 = new
|
|
4662
|
+
view2 = new EditorView17({
|
|
4452
4663
|
parent: parentRef.current,
|
|
4453
4664
|
scrollTo,
|
|
4454
4665
|
state,
|
|
@@ -4506,19 +4717,19 @@ var createDataExtensions = ({ readonly = false } = {}) => {
|
|
|
4506
4717
|
return [
|
|
4507
4718
|
//
|
|
4508
4719
|
EditorState3.readOnly.of(readonly),
|
|
4509
|
-
|
|
4720
|
+
EditorView17.editable.of(!readonly)
|
|
4510
4721
|
];
|
|
4511
4722
|
};
|
|
4512
4723
|
var createThemeExtensions = ({ theme, themeMode, slots } = {}) => {
|
|
4513
4724
|
return [
|
|
4514
4725
|
//
|
|
4515
|
-
|
|
4516
|
-
theme &&
|
|
4517
|
-
|
|
4518
|
-
|
|
4726
|
+
EditorView17.baseTheme(defaultTheme),
|
|
4727
|
+
theme && EditorView17.theme(theme),
|
|
4728
|
+
EditorView17.darkTheme.of(themeMode === "dark"),
|
|
4729
|
+
EditorView17.editorAttributes.of({
|
|
4519
4730
|
class: slots?.editor?.className ?? ""
|
|
4520
4731
|
}),
|
|
4521
|
-
|
|
4732
|
+
EditorView17.contentAttributes.of({
|
|
4522
4733
|
class: slots?.content?.className ?? ""
|
|
4523
4734
|
})
|
|
4524
4735
|
].filter(isNotFalsy5);
|
|
@@ -4618,6 +4829,7 @@ export {
|
|
|
4618
4829
|
awarenessProvider,
|
|
4619
4830
|
blast,
|
|
4620
4831
|
callbackWrapper,
|
|
4832
|
+
code2 as code,
|
|
4621
4833
|
codeTheme,
|
|
4622
4834
|
comments,
|
|
4623
4835
|
compareFormatting,
|
|
@@ -4628,7 +4840,6 @@ export {
|
|
|
4628
4840
|
createThemeExtensions,
|
|
4629
4841
|
cursorLineMargin,
|
|
4630
4842
|
cursorLineMarginFacet,
|
|
4631
|
-
decorateMarkdown,
|
|
4632
4843
|
defaultMarkdownSlots,
|
|
4633
4844
|
defaultOptions,
|
|
4634
4845
|
defaultSlots,
|
|
@@ -4643,10 +4854,12 @@ export {
|
|
|
4643
4854
|
formatting,
|
|
4644
4855
|
getFormatting,
|
|
4645
4856
|
getToken,
|
|
4857
|
+
heading2 as heading,
|
|
4858
|
+
hr,
|
|
4646
4859
|
image,
|
|
4647
4860
|
insertTable,
|
|
4648
4861
|
keymap8 as keymap,
|
|
4649
|
-
|
|
4862
|
+
link,
|
|
4650
4863
|
listener,
|
|
4651
4864
|
logChanges,
|
|
4652
4865
|
markdownHighlightStyle,
|
|
@@ -4668,6 +4881,7 @@ export {
|
|
|
4668
4881
|
setStyle,
|
|
4669
4882
|
table,
|
|
4670
4883
|
tags2 as tags,
|
|
4884
|
+
tasklist,
|
|
4671
4885
|
textTheme,
|
|
4672
4886
|
toggleBlockquote,
|
|
4673
4887
|
toggleCodeblock,
|