@dxos/react-ui-editor 0.4.5-main.181e1ed → 0.4.5-main.2a3f55f
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 +334 -537
- 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 +7 -5
- package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts +2 -0
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/automerge.stories.d.ts +2 -0
- package/dist/types/src/components/TextEditor/automerge.stories.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/hooks.stories.d.ts +2 -0
- package/dist/types/src/components/TextEditor/hooks.stories.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +2 -0
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/decorate.d.ts +5 -0
- package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/index.d.ts +1 -4
- package/dist/types/src/extensions/markdown/index.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/link.d.ts +1 -11
- package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +2 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +2 -0
- package/dist/types/src/translations.d.ts.map +1 -1
- package/package.json +24 -24
- package/src/components/TextEditor/MarkdownEditor.stories.tsx +29 -37
- package/src/components/TextEditor/hooks.stories.tsx +2 -10
- package/src/components/Toolbar/Toolbar.stories.tsx +2 -6
- package/src/components/Toolbar/Toolbar.tsx +79 -46
- package/src/extensions/markdown/decorate.ts +301 -0
- package/src/extensions/markdown/formatting.ts +1 -64
- package/src/extensions/markdown/index.ts +1 -4
- package/src/extensions/markdown/link.ts +23 -185
- package/src/index.ts +2 -0
- package/src/translations.ts +5 -3
- package/dist/types/src/extensions/markdown/code.d.ts +0 -2
- package/dist/types/src/extensions/markdown/code.d.ts.map +0 -1
- package/dist/types/src/extensions/markdown/heading.d.ts +0 -6
- package/dist/types/src/extensions/markdown/heading.d.ts.map +0 -1
- package/dist/types/src/extensions/markdown/hr.d.ts +0 -2
- package/dist/types/src/extensions/markdown/hr.d.ts.map +0 -1
- package/dist/types/src/extensions/markdown/tasklist.d.ts +0 -3
- package/dist/types/src/extensions/markdown/tasklist.d.ts.map +0 -1
- package/src/extensions/markdown/code.ts +0 -162
- package/src/extensions/markdown/heading.ts +0 -59
- package/src/extensions/markdown/hr.ts +0 -71
- package/src/extensions/markdown/tasklist.ts +0 -110
|
@@ -1,3 +1,27 @@
|
|
|
1
|
+
// packages/ui/react-ui-editor/src/translations.ts
|
|
2
|
+
var translationKey = "react-ui-editor";
|
|
3
|
+
var translations_default = [
|
|
4
|
+
{
|
|
5
|
+
"en-US": {
|
|
6
|
+
[translationKey]: {
|
|
7
|
+
"strong label": "Bold",
|
|
8
|
+
"emphasis label": "Italics",
|
|
9
|
+
"strikethrough label": "Strikethrough",
|
|
10
|
+
"code label": "Code",
|
|
11
|
+
"link label": "Link",
|
|
12
|
+
"list-bullet label": "Bullet list",
|
|
13
|
+
"list-ordered label": "Numbered list",
|
|
14
|
+
"list-task label": "Task list",
|
|
15
|
+
"blockquote label": "Block quote",
|
|
16
|
+
"codeblock label": "Code block",
|
|
17
|
+
"comment label": "Create comment",
|
|
18
|
+
"heading label": "Heading level",
|
|
19
|
+
"table label": "Create table"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
];
|
|
24
|
+
|
|
1
25
|
// packages/ui/react-ui-editor/src/index.ts
|
|
2
26
|
import { keymap as keymap8 } from "@codemirror/view";
|
|
3
27
|
import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
|
|
@@ -8,7 +32,7 @@ import { tags as tags2 } from "@lezer/highlight";
|
|
|
8
32
|
|
|
9
33
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
10
34
|
import { EditorState as EditorState2 } from "@codemirror/state";
|
|
11
|
-
import { EditorView as
|
|
35
|
+
import { EditorView as EditorView14 } from "@codemirror/view";
|
|
12
36
|
import { useFocusableGroup } from "@fluentui/react-tabster";
|
|
13
37
|
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
14
38
|
import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useRef, useState as useState2, useMemo as useMemo2 } from "react";
|
|
@@ -765,10 +789,10 @@ var blast = (options = defaultOptions) => {
|
|
|
765
789
|
const getPoint = (view, pos) => {
|
|
766
790
|
const { left: x = 0, top: y = 0 } = view.coordsForChar(pos) ?? {};
|
|
767
791
|
const element = document.elementFromPoint(x, y);
|
|
768
|
-
const { offsetLeft: left = 0, offsetTop:
|
|
792
|
+
const { offsetLeft: left = 0, offsetTop: top = 0 } = view.scrollDOM.parentElement ?? {};
|
|
769
793
|
const point = {
|
|
770
794
|
x: x - left,
|
|
771
|
-
y: y -
|
|
795
|
+
y: y - top
|
|
772
796
|
};
|
|
773
797
|
return {
|
|
774
798
|
element,
|
|
@@ -1871,12 +1895,207 @@ var createMarkdownExtensions = ({ themeMode, placeholder: _placeholder, lineWrap
|
|
|
1871
1895
|
].filter(isNotFalsy3);
|
|
1872
1896
|
};
|
|
1873
1897
|
|
|
1874
|
-
// packages/ui/react-ui-editor/src/extensions/markdown/
|
|
1898
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
|
|
1875
1899
|
import { syntaxTree } from "@codemirror/language";
|
|
1876
1900
|
import { RangeSetBuilder } from "@codemirror/state";
|
|
1877
|
-
import {
|
|
1901
|
+
import { EditorView as EditorView10, Decoration as Decoration4, WidgetType as WidgetType2, ViewPlugin as ViewPlugin3 } from "@codemirror/view";
|
|
1878
1902
|
import { mx as mx2 } from "@dxos/react-ui-theme";
|
|
1879
|
-
var
|
|
1903
|
+
var FencedCodeBoundary = class extends WidgetType2 {
|
|
1904
|
+
constructor(_className) {
|
|
1905
|
+
super();
|
|
1906
|
+
this._className = _className;
|
|
1907
|
+
}
|
|
1908
|
+
toDOM() {
|
|
1909
|
+
const el = document.createElement("span");
|
|
1910
|
+
el.innerHTML = " ";
|
|
1911
|
+
el.className = mx2("cm-code cm-codeblock", this._className);
|
|
1912
|
+
return el;
|
|
1913
|
+
}
|
|
1914
|
+
};
|
|
1915
|
+
var HorizontalRuleWidget = class extends WidgetType2 {
|
|
1916
|
+
toDOM() {
|
|
1917
|
+
const el = document.createElement("span");
|
|
1918
|
+
el.className = "cm-hr";
|
|
1919
|
+
return el;
|
|
1920
|
+
}
|
|
1921
|
+
};
|
|
1922
|
+
var LinkButton = class extends WidgetType2 {
|
|
1923
|
+
constructor(url, render) {
|
|
1924
|
+
super();
|
|
1925
|
+
this.url = url;
|
|
1926
|
+
this.render = render;
|
|
1927
|
+
}
|
|
1928
|
+
eq(other) {
|
|
1929
|
+
return this.url === other.url;
|
|
1930
|
+
}
|
|
1931
|
+
toDOM(view) {
|
|
1932
|
+
const el = document.createElement("span");
|
|
1933
|
+
this.render(el, this.url);
|
|
1934
|
+
return el;
|
|
1935
|
+
}
|
|
1936
|
+
};
|
|
1937
|
+
var CheckboxWidget = class extends WidgetType2 {
|
|
1938
|
+
constructor(_checked) {
|
|
1939
|
+
super();
|
|
1940
|
+
this._checked = _checked;
|
|
1941
|
+
}
|
|
1942
|
+
eq(other) {
|
|
1943
|
+
return this._checked === other._checked;
|
|
1944
|
+
}
|
|
1945
|
+
toDOM(view) {
|
|
1946
|
+
const input = document.createElement("input");
|
|
1947
|
+
input.className = "cm-task-checkbox";
|
|
1948
|
+
input.type = "checkbox";
|
|
1949
|
+
input.checked = this._checked;
|
|
1950
|
+
if (view.state.readOnly) {
|
|
1951
|
+
input.setAttribute("disabled", "true");
|
|
1952
|
+
} else {
|
|
1953
|
+
input.onmousedown = (event) => {
|
|
1954
|
+
const pos = view.posAtDOM(input);
|
|
1955
|
+
const text = view.state.sliceDoc(pos, pos + 3);
|
|
1956
|
+
if (text === (this._checked ? "[x]" : "[ ]")) {
|
|
1957
|
+
view.dispatch({
|
|
1958
|
+
changes: {
|
|
1959
|
+
from: pos + 1,
|
|
1960
|
+
to: pos + 2,
|
|
1961
|
+
insert: this._checked ? " " : "x"
|
|
1962
|
+
}
|
|
1963
|
+
});
|
|
1964
|
+
event.preventDefault();
|
|
1965
|
+
}
|
|
1966
|
+
};
|
|
1967
|
+
}
|
|
1968
|
+
return input;
|
|
1969
|
+
}
|
|
1970
|
+
ignoreEvent() {
|
|
1971
|
+
return false;
|
|
1972
|
+
}
|
|
1973
|
+
};
|
|
1974
|
+
var hide = Decoration4.replace({});
|
|
1975
|
+
var fencedCodeTop = Decoration4.replace({
|
|
1976
|
+
widget: new FencedCodeBoundary("cm-codeblock-end cm-codeblock-first")
|
|
1977
|
+
});
|
|
1978
|
+
var fencedCodeBottom = Decoration4.replace({
|
|
1979
|
+
widget: new FencedCodeBoundary("cm-codeblock-end cm-codeblock-last")
|
|
1980
|
+
});
|
|
1981
|
+
var horizontalRule = Decoration4.replace({
|
|
1982
|
+
widget: new HorizontalRuleWidget()
|
|
1983
|
+
});
|
|
1984
|
+
var checkedTask = Decoration4.replace({
|
|
1985
|
+
widget: new CheckboxWidget(true)
|
|
1986
|
+
});
|
|
1987
|
+
var uncheckedTask = Decoration4.replace({
|
|
1988
|
+
widget: new CheckboxWidget(false)
|
|
1989
|
+
});
|
|
1990
|
+
var editingRange = (state, range) => {
|
|
1991
|
+
const { readOnly, selection: { main: { head } } } = state;
|
|
1992
|
+
return !readOnly && head >= range.from && head <= range.to;
|
|
1993
|
+
};
|
|
1994
|
+
var MarksByParent = /* @__PURE__ */ new Set([
|
|
1995
|
+
"CodeMark",
|
|
1996
|
+
"EmphasisMark",
|
|
1997
|
+
"StrikethroughMark",
|
|
1998
|
+
"SubscriptMark",
|
|
1999
|
+
"SuperscriptMark"
|
|
2000
|
+
]);
|
|
2001
|
+
var buildDecorations = (view, options) => {
|
|
2002
|
+
const builder = new RangeSetBuilder();
|
|
2003
|
+
const { state } = view;
|
|
2004
|
+
for (const { from, to } of view.visibleRanges) {
|
|
2005
|
+
syntaxTree(state).iterate({
|
|
2006
|
+
from,
|
|
2007
|
+
to,
|
|
2008
|
+
enter: (node) => {
|
|
2009
|
+
if (node.name === "FencedCode") {
|
|
2010
|
+
const editing = editingRange(state, node);
|
|
2011
|
+
for (const block of view.viewportLineBlocks) {
|
|
2012
|
+
if (block.to < node.from) {
|
|
2013
|
+
continue;
|
|
2014
|
+
}
|
|
2015
|
+
if (block.from > node.to) {
|
|
2016
|
+
break;
|
|
2017
|
+
}
|
|
2018
|
+
const first = block.from <= node.from;
|
|
2019
|
+
const last = block.to >= node.to;
|
|
2020
|
+
if (!editing && (first || last)) {
|
|
2021
|
+
builder.add(block.from, block.to, first ? fencedCodeTop : fencedCodeBottom);
|
|
2022
|
+
} else {
|
|
2023
|
+
builder.add(block.from, block.from, Decoration4.line({
|
|
2024
|
+
class: mx2("cm-code cm-codeblock-line", first && "cm-codeblock-first", last && "cm-codeblock-last")
|
|
2025
|
+
}));
|
|
2026
|
+
}
|
|
2027
|
+
}
|
|
2028
|
+
return false;
|
|
2029
|
+
} else if (node.name === "Link") {
|
|
2030
|
+
const marks = node.node.getChildren("LinkMark");
|
|
2031
|
+
const urlNode = node.node.getChild("URL");
|
|
2032
|
+
const editing = editingRange(state, node);
|
|
2033
|
+
if (urlNode && marks.length >= 2) {
|
|
2034
|
+
const url = state.sliceDoc(urlNode.from, urlNode.to);
|
|
2035
|
+
if (!editing) {
|
|
2036
|
+
builder.add(node.from, marks[0].to, hide);
|
|
2037
|
+
}
|
|
2038
|
+
builder.add(marks[0].to, marks[1].from, Decoration4.mark({
|
|
2039
|
+
tagName: "a",
|
|
2040
|
+
attributes: {
|
|
2041
|
+
class: "cm-link",
|
|
2042
|
+
href: url,
|
|
2043
|
+
rel: "noreferrer",
|
|
2044
|
+
target: "_blank"
|
|
2045
|
+
}
|
|
2046
|
+
}));
|
|
2047
|
+
if (!editing) {
|
|
2048
|
+
builder.add(marks[1].from, node.to, options.renderLinkButton ? Decoration4.replace({
|
|
2049
|
+
widget: new LinkButton(url, options.renderLinkButton)
|
|
2050
|
+
}) : hide);
|
|
2051
|
+
}
|
|
2052
|
+
}
|
|
2053
|
+
} else if (node.name === "HeaderMark") {
|
|
2054
|
+
const parent = node.node.parent;
|
|
2055
|
+
if (/^ATX/.test(parent.name) && !editingRange(state, state.doc.lineAt(node.from))) {
|
|
2056
|
+
const next = state.doc.sliceString(node.to, node.to + 1);
|
|
2057
|
+
builder.add(node.from, node.to + (next === " " ? 1 : 0), hide);
|
|
2058
|
+
}
|
|
2059
|
+
} else if (node.name === "HorizontalRule") {
|
|
2060
|
+
if (!editingRange(state, node)) {
|
|
2061
|
+
builder.add(node.from, node.to, horizontalRule);
|
|
2062
|
+
}
|
|
2063
|
+
} else if (node.name === "TaskMarker") {
|
|
2064
|
+
if (!editingRange(state, node)) {
|
|
2065
|
+
const checked = state.doc.sliceString(node.from + 1, node.to - 1) === "x";
|
|
2066
|
+
builder.add(node.from - 2, node.from - 1, Decoration4.mark({
|
|
2067
|
+
class: "cm-task"
|
|
2068
|
+
}));
|
|
2069
|
+
builder.add(node.from, node.to, checked ? checkedTask : uncheckedTask);
|
|
2070
|
+
}
|
|
2071
|
+
} else if (MarksByParent.has(node.name)) {
|
|
2072
|
+
if (!editingRange(state, node.node.parent)) {
|
|
2073
|
+
builder.add(node.from, node.to, hide);
|
|
2074
|
+
}
|
|
2075
|
+
}
|
|
2076
|
+
}
|
|
2077
|
+
});
|
|
2078
|
+
}
|
|
2079
|
+
return builder.finish();
|
|
2080
|
+
};
|
|
2081
|
+
var decorateMarkdown = (options = {}) => {
|
|
2082
|
+
return [
|
|
2083
|
+
ViewPlugin3.fromClass(class {
|
|
2084
|
+
constructor(view) {
|
|
2085
|
+
this.decorations = buildDecorations(view, options);
|
|
2086
|
+
}
|
|
2087
|
+
update(update2) {
|
|
2088
|
+
if (update2.docChanged || update2.selectionSet || update2.viewportChanged) {
|
|
2089
|
+
this.decorations = buildDecorations(update2.view, options);
|
|
2090
|
+
}
|
|
2091
|
+
}
|
|
2092
|
+
}, {
|
|
2093
|
+
decorations: (value) => value.decorations
|
|
2094
|
+
}),
|
|
2095
|
+
formattingStyles
|
|
2096
|
+
];
|
|
2097
|
+
};
|
|
2098
|
+
var formattingStyles = EditorView10.baseTheme({
|
|
1880
2099
|
"& .cm-code": {
|
|
1881
2100
|
fontFamily: getToken("fontFamily.mono", []).join(",")
|
|
1882
2101
|
},
|
|
@@ -1924,82 +2143,28 @@ var styles4 = EditorView10.baseTheme({
|
|
|
1924
2143
|
"&::after": {
|
|
1925
2144
|
background: getToken("extend.semanticColors.input.dark")
|
|
1926
2145
|
}
|
|
2146
|
+
},
|
|
2147
|
+
"& .cm-hr": {
|
|
2148
|
+
display: "inline-block",
|
|
2149
|
+
width: "100%",
|
|
2150
|
+
height: "0",
|
|
2151
|
+
verticalAlign: "middle",
|
|
2152
|
+
borderTop: `1px solid ${getToken("extend.colors.neutral.200")}`
|
|
2153
|
+
},
|
|
2154
|
+
"& .cm-task": {
|
|
2155
|
+
color: getToken("extend.colors.blue.500")
|
|
2156
|
+
},
|
|
2157
|
+
"& .cm-task-checkbox": {
|
|
2158
|
+
marginLeft: "4px",
|
|
2159
|
+
marginRight: "4px"
|
|
1927
2160
|
}
|
|
1928
2161
|
});
|
|
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
|
-
};
|
|
1997
2162
|
|
|
1998
2163
|
// packages/ui/react-ui-editor/src/extensions/markdown/formatting.ts
|
|
1999
2164
|
import { snippet } from "@codemirror/autocomplete";
|
|
2000
2165
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
2001
|
-
import {
|
|
2002
|
-
import {
|
|
2166
|
+
import { EditorSelection } from "@codemirror/state";
|
|
2167
|
+
import { EditorView as EditorView11, keymap as keymap5 } from "@codemirror/view";
|
|
2003
2168
|
import { useState, useMemo } from "react";
|
|
2004
2169
|
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;
|
|
2005
2170
|
var Inline;
|
|
@@ -2876,56 +3041,7 @@ var formatting = (options = {}) => {
|
|
|
2876
3041
|
key: "meta-b",
|
|
2877
3042
|
run: toggleStrong
|
|
2878
3043
|
}
|
|
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
|
-
})
|
|
3044
|
+
])
|
|
2929
3045
|
];
|
|
2930
3046
|
};
|
|
2931
3047
|
var InlineMarker = {
|
|
@@ -2975,7 +3091,7 @@ var getFormatting = (state) => {
|
|
|
2975
3091
|
null,
|
|
2976
3092
|
null
|
|
2977
3093
|
];
|
|
2978
|
-
let
|
|
3094
|
+
let link = false;
|
|
2979
3095
|
let blockQuote = null;
|
|
2980
3096
|
let listStyle = null;
|
|
2981
3097
|
const stack = [];
|
|
@@ -3037,7 +3153,7 @@ var getFormatting = (state) => {
|
|
|
3037
3153
|
if (name === "BulletList" || name === "OrderedList" || name === "Blockquote") {
|
|
3038
3154
|
stack.push(name);
|
|
3039
3155
|
} else if (name === "Link") {
|
|
3040
|
-
|
|
3156
|
+
link = true;
|
|
3041
3157
|
} else if (Object.hasOwn(Textblocks, name) && (range.empty || node.to > range.from || node.from < range.to)) {
|
|
3042
3158
|
if (name === "Task" && stack[stack.length - 1] === "BulletList") {
|
|
3043
3159
|
stack[stack.length - 1] = "TaskList";
|
|
@@ -3112,7 +3228,7 @@ var getFormatting = (state) => {
|
|
|
3112
3228
|
emphasis: inline[1] ?? false,
|
|
3113
3229
|
strong: inline[0] ?? false,
|
|
3114
3230
|
strikethrough: inline[2] ?? false,
|
|
3115
|
-
link
|
|
3231
|
+
link,
|
|
3116
3232
|
listStyle: listStyle || null
|
|
3117
3233
|
};
|
|
3118
3234
|
};
|
|
@@ -3132,117 +3248,14 @@ var useFormattingState = () => {
|
|
|
3132
3248
|
];
|
|
3133
3249
|
};
|
|
3134
3250
|
|
|
3135
|
-
// packages/ui/react-ui-editor/src/extensions/markdown/heading.ts
|
|
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
3251
|
// packages/ui/react-ui-editor/src/extensions/markdown/image.ts
|
|
3239
|
-
import { syntaxTree as
|
|
3252
|
+
import { syntaxTree as syntaxTree3 } from "@codemirror/language";
|
|
3240
3253
|
import { StateField as StateField4 } from "@codemirror/state";
|
|
3241
|
-
import { Decoration as
|
|
3254
|
+
import { Decoration as Decoration5, EditorView as EditorView12, WidgetType as WidgetType3 } from "@codemirror/view";
|
|
3242
3255
|
var image = (options = {}) => {
|
|
3243
3256
|
return StateField4.define({
|
|
3244
3257
|
create: (state) => {
|
|
3245
|
-
return
|
|
3258
|
+
return Decoration5.set(buildDecorations2(0, state.doc.length, state));
|
|
3246
3259
|
},
|
|
3247
3260
|
update: (value, tr) => {
|
|
3248
3261
|
if (!tr.docChanged && !tr.selection) {
|
|
@@ -3262,26 +3275,26 @@ var image = (options = {}) => {
|
|
|
3262
3275
|
filterFrom: from,
|
|
3263
3276
|
filterTo: to,
|
|
3264
3277
|
filter: () => false,
|
|
3265
|
-
add:
|
|
3278
|
+
add: buildDecorations2(from, to, tr.state)
|
|
3266
3279
|
});
|
|
3267
3280
|
},
|
|
3268
|
-
provide: (field) =>
|
|
3281
|
+
provide: (field) => EditorView12.decorations.from(field)
|
|
3269
3282
|
});
|
|
3270
3283
|
};
|
|
3271
|
-
var
|
|
3284
|
+
var buildDecorations2 = (from, to, state) => {
|
|
3272
3285
|
const decorations = [];
|
|
3273
3286
|
const cursor = state.selection.main.head;
|
|
3274
|
-
|
|
3287
|
+
syntaxTree3(state).iterate({
|
|
3275
3288
|
enter: (node) => {
|
|
3276
3289
|
if (node.name === "Image") {
|
|
3277
3290
|
const urlNode = node.node.getChild("URL");
|
|
3278
3291
|
if (urlNode) {
|
|
3279
|
-
const
|
|
3292
|
+
const hide2 = state.readOnly || cursor < node.from || cursor > node.to;
|
|
3280
3293
|
const url = state.sliceDoc(urlNode.from, urlNode.to);
|
|
3281
|
-
decorations.push(
|
|
3294
|
+
decorations.push(Decoration5.replace({
|
|
3282
3295
|
block: true,
|
|
3283
3296
|
widget: new ImageWidget(url)
|
|
3284
|
-
}).range(
|
|
3297
|
+
}).range(hide2 ? node.from : node.to, node.to));
|
|
3285
3298
|
}
|
|
3286
3299
|
}
|
|
3287
3300
|
},
|
|
@@ -3290,7 +3303,7 @@ var buildDecorations4 = (from, to, state) => {
|
|
|
3290
3303
|
});
|
|
3291
3304
|
return decorations;
|
|
3292
3305
|
};
|
|
3293
|
-
var ImageWidget = class extends
|
|
3306
|
+
var ImageWidget = class extends WidgetType3 {
|
|
3294
3307
|
constructor(_url) {
|
|
3295
3308
|
super();
|
|
3296
3309
|
this._url = _url;
|
|
@@ -3308,155 +3321,52 @@ var ImageWidget = class extends WidgetType4 {
|
|
|
3308
3321
|
};
|
|
3309
3322
|
|
|
3310
3323
|
// packages/ui/react-ui-editor/src/extensions/markdown/link.ts
|
|
3311
|
-
import { syntaxTree as
|
|
3312
|
-
import {
|
|
3313
|
-
import { hoverTooltip as hoverTooltip2, Decoration as Decoration9, ViewPlugin as ViewPlugin7, WidgetType as WidgetType5 } from "@codemirror/view";
|
|
3324
|
+
import { syntaxTree as syntaxTree4 } from "@codemirror/language";
|
|
3325
|
+
import { hoverTooltip as hoverTooltip2 } from "@codemirror/view";
|
|
3314
3326
|
import { tooltipContent } from "@dxos/react-ui-theme";
|
|
3315
|
-
var
|
|
3316
|
-
const
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
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;
|
|
3327
|
+
var linkTooltip = (render) => hoverTooltip2((view, pos, side) => {
|
|
3328
|
+
const syntax = syntaxTree4(view.state).resolveInner(pos, side);
|
|
3329
|
+
let link = null;
|
|
3330
|
+
for (let i = 0, node = syntax; !link && node && i < 5; node = node.parent, i++) {
|
|
3331
|
+
link = node.name === "Link" ? node : null;
|
|
3332
|
+
}
|
|
3333
|
+
const url = link && link.getChild("URL");
|
|
3334
|
+
if (!url || !link) {
|
|
3335
|
+
return null;
|
|
3391
3336
|
}
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
}
|
|
3337
|
+
const urlText = view.state.sliceDoc(url.from, url.to);
|
|
3338
|
+
return {
|
|
3339
|
+
pos: link.from,
|
|
3340
|
+
end: link.to,
|
|
3341
|
+
above: true,
|
|
3342
|
+
create: () => {
|
|
3343
|
+
const el = document.createElement("div");
|
|
3344
|
+
el.className = tooltipContent({}, "pli-2 plb-1");
|
|
3345
|
+
render(el, urlText);
|
|
3346
|
+
return {
|
|
3347
|
+
dom: el,
|
|
3348
|
+
offset: {
|
|
3349
|
+
x: 0,
|
|
3350
|
+
y: 4
|
|
3351
|
+
}
|
|
3407
3352
|
};
|
|
3408
3353
|
}
|
|
3409
|
-
|
|
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
|
-
};
|
|
3354
|
+
};
|
|
3355
|
+
});
|
|
3446
3356
|
|
|
3447
3357
|
// packages/ui/react-ui-editor/src/extensions/markdown/table.ts
|
|
3448
|
-
import { syntaxTree as
|
|
3449
|
-
import { RangeSetBuilder as
|
|
3450
|
-
import { Decoration as
|
|
3358
|
+
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
|
3359
|
+
import { RangeSetBuilder as RangeSetBuilder2, StateField as StateField5 } from "@codemirror/state";
|
|
3360
|
+
import { Decoration as Decoration6, EditorView as EditorView13, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
3451
3361
|
var table = (options = {}) => {
|
|
3452
3362
|
return StateField5.define({
|
|
3453
3363
|
create: (state) => update(state, options),
|
|
3454
3364
|
update: (_, tr) => update(tr.state, options),
|
|
3455
|
-
provide: (field) =>
|
|
3365
|
+
provide: (field) => EditorView13.decorations.from(field)
|
|
3456
3366
|
});
|
|
3457
3367
|
};
|
|
3458
3368
|
var update = (state, options) => {
|
|
3459
|
-
const builder = new
|
|
3369
|
+
const builder = new RangeSetBuilder2();
|
|
3460
3370
|
const cursor = state.selection.main.head;
|
|
3461
3371
|
const tables = [];
|
|
3462
3372
|
const getTable = () => tables[tables.length - 1];
|
|
@@ -3464,7 +3374,7 @@ var update = (state, options) => {
|
|
|
3464
3374
|
const table2 = getTable();
|
|
3465
3375
|
return table2.rows?.[table2.rows.length - 1];
|
|
3466
3376
|
};
|
|
3467
|
-
|
|
3377
|
+
syntaxTree5(state).iterate({
|
|
3468
3378
|
enter: (node) => {
|
|
3469
3379
|
switch (node.name) {
|
|
3470
3380
|
case "Table": {
|
|
@@ -3495,17 +3405,17 @@ var update = (state, options) => {
|
|
|
3495
3405
|
}
|
|
3496
3406
|
});
|
|
3497
3407
|
tables.forEach((table2) => {
|
|
3498
|
-
const
|
|
3499
|
-
|
|
3408
|
+
const hide2 = state.readOnly || cursor < table2.from || cursor > table2.to;
|
|
3409
|
+
hide2 && builder.add(table2.from, table2.to, Decoration6.replace({
|
|
3500
3410
|
widget: new TableWidget(table2)
|
|
3501
3411
|
}));
|
|
3502
|
-
builder.add(table2.from, table2.to,
|
|
3412
|
+
builder.add(table2.from, table2.to, Decoration6.mark({
|
|
3503
3413
|
class: "cm-table"
|
|
3504
3414
|
}));
|
|
3505
3415
|
});
|
|
3506
3416
|
return builder.finish();
|
|
3507
3417
|
};
|
|
3508
|
-
var TableWidget = class extends
|
|
3418
|
+
var TableWidget = class extends WidgetType4 {
|
|
3509
3419
|
constructor(_table) {
|
|
3510
3420
|
super();
|
|
3511
3421
|
this._table = _table;
|
|
@@ -3542,103 +3452,6 @@ var TableWidget = class extends WidgetType6 {
|
|
|
3542
3452
|
}
|
|
3543
3453
|
};
|
|
3544
3454
|
|
|
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
|
-
|
|
3642
3455
|
// packages/ui/react-ui-editor/src/extensions/mention.ts
|
|
3643
3456
|
import { autocompletion as autocompletion2 } from "@codemirror/autocomplete";
|
|
3644
3457
|
var mention = ({ onSearch }) => {
|
|
@@ -4036,7 +3849,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
4036
3849
|
selection,
|
|
4037
3850
|
extensions: [
|
|
4038
3851
|
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
4039
|
-
|
|
3852
|
+
EditorView14.exceptionSink.of((err) => {
|
|
4040
3853
|
log3.catch(err, void 0, {
|
|
4041
3854
|
F: __dxlog_file4,
|
|
4042
3855
|
L: 113,
|
|
@@ -4046,17 +3859,17 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
4046
3859
|
}),
|
|
4047
3860
|
// Theme.
|
|
4048
3861
|
// TODO(burdon): Make configurable.
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
|
|
4052
|
-
|
|
3862
|
+
EditorView14.baseTheme(defaultTheme),
|
|
3863
|
+
EditorView14.theme(theme ?? {}),
|
|
3864
|
+
EditorView14.darkTheme.of(themeMode === "dark"),
|
|
3865
|
+
EditorView14.editorAttributes.of({
|
|
4053
3866
|
class: slots.editor?.className ?? ""
|
|
4054
3867
|
}),
|
|
4055
|
-
|
|
3868
|
+
EditorView14.contentAttributes.of({
|
|
4056
3869
|
class: slots.content?.className ?? ""
|
|
4057
3870
|
}),
|
|
4058
3871
|
// Focus.
|
|
4059
|
-
|
|
3872
|
+
EditorView14.updateListener.of((update2) => {
|
|
4060
3873
|
update2.transactions.forEach((transaction) => {
|
|
4061
3874
|
if (transaction.isUserEvent("focus.container")) {
|
|
4062
3875
|
rootRef.current?.focus();
|
|
@@ -4064,7 +3877,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
4064
3877
|
});
|
|
4065
3878
|
}),
|
|
4066
3879
|
// State.
|
|
4067
|
-
|
|
3880
|
+
EditorView14.editable.of(!readonly),
|
|
4068
3881
|
EditorState2.readOnly.of(!!readonly),
|
|
4069
3882
|
// Storage and replication.
|
|
4070
3883
|
// NOTE: This must come before user extensions.
|
|
@@ -4073,7 +3886,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
4073
3886
|
...extensions
|
|
4074
3887
|
].filter(isNotFalsy4)
|
|
4075
3888
|
});
|
|
4076
|
-
const newView = new
|
|
3889
|
+
const newView = new EditorView14({
|
|
4077
3890
|
state,
|
|
4078
3891
|
parent: rootRef.current,
|
|
4079
3892
|
scrollTo,
|
|
@@ -4190,32 +4003,12 @@ var defaultMarkdownSlots = {
|
|
|
4190
4003
|
import { ChatText, Code, CodeBlock, Link, ListBullets, ListChecks, ListNumbers, Paragraph, TextStrikethrough, Table as Table2, TextB, TextHOne, TextHTwo, TextHThree, TextHFour, TextHFive, TextHSix, TextItalic, Quotes } from "@phosphor-icons/react";
|
|
4191
4004
|
import { createContext } from "@radix-ui/react-context";
|
|
4192
4005
|
import React2 from "react";
|
|
4193
|
-
import { DensityProvider, ElevationProvider, Select, Toolbar as NaturalToolbar, useTranslation } from "@dxos/react-ui";
|
|
4006
|
+
import { DensityProvider, ElevationProvider, Select, Toolbar as NaturalToolbar, Tooltip, useTranslation } from "@dxos/react-ui";
|
|
4194
4007
|
import { getSize } from "@dxos/react-ui-theme";
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
{
|
|
4200
|
-
"en-US": {
|
|
4201
|
-
[translationKey]: {
|
|
4202
|
-
"strong label": "Strong",
|
|
4203
|
-
"emphasis label": "Emphasis",
|
|
4204
|
-
"strikethrough label": "Strike-through",
|
|
4205
|
-
"code label": "Code",
|
|
4206
|
-
"list-bullet label": "Bullet list",
|
|
4207
|
-
"list-ordered label": "Numbered list",
|
|
4208
|
-
"list-task label": "Task list",
|
|
4209
|
-
"blockquote label": "Block quote",
|
|
4210
|
-
"codeblock label": "Code block",
|
|
4211
|
-
"comment label": "Create comment",
|
|
4212
|
-
"heading label": "Heading level"
|
|
4213
|
-
}
|
|
4214
|
-
}
|
|
4215
|
-
}
|
|
4216
|
-
];
|
|
4217
|
-
|
|
4218
|
-
// packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
|
|
4008
|
+
var tooltipProps = {
|
|
4009
|
+
side: "top",
|
|
4010
|
+
classNames: "z-10"
|
|
4011
|
+
};
|
|
4219
4012
|
var HeadingIcons = {
|
|
4220
4013
|
"0": Paragraph,
|
|
4221
4014
|
"1": TextHOne,
|
|
@@ -4244,7 +4037,9 @@ var ToolbarRoot = ({ children, onAction, classNames, state }) => {
|
|
|
4244
4037
|
var buttonStyles = "min-bs-0 p-2";
|
|
4245
4038
|
var iconStyles = getSize(5);
|
|
4246
4039
|
var ToolbarButton = ({ Icon, children, ...props }) => {
|
|
4247
|
-
return /* @__PURE__ */ React2.createElement(
|
|
4040
|
+
return /* @__PURE__ */ React2.createElement(Tooltip.Root, null, /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
|
|
4041
|
+
asChild: true
|
|
4042
|
+
}, /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroupItem, {
|
|
4248
4043
|
variant: "ghost",
|
|
4249
4044
|
...props,
|
|
4250
4045
|
classNames: buttonStyles
|
|
@@ -4252,7 +4047,7 @@ var ToolbarButton = ({ Icon, children, ...props }) => {
|
|
|
4252
4047
|
className: iconStyles
|
|
4253
4048
|
}), /* @__PURE__ */ React2.createElement("span", {
|
|
4254
4049
|
className: "sr-only"
|
|
4255
|
-
}, children));
|
|
4050
|
+
}, children))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, tooltipProps, children, /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))));
|
|
4256
4051
|
};
|
|
4257
4052
|
var ToolbarSeparator = () => /* @__PURE__ */ React2.createElement("div", {
|
|
4258
4053
|
role: "separator",
|
|
@@ -4265,13 +4060,15 @@ var MarkdownHeading = () => {
|
|
|
4265
4060
|
const header = blockType && /heading(\d)/.exec(blockType);
|
|
4266
4061
|
const value = header ? header[1] : blockType === "paragraph" || !blockType ? "0" : void 0;
|
|
4267
4062
|
const HeadingIcon = HeadingIcons[value ?? "0"];
|
|
4268
|
-
return /* @__PURE__ */ React2.createElement(Select.Root, {
|
|
4063
|
+
return /* @__PURE__ */ React2.createElement(Tooltip.Root, null, /* @__PURE__ */ React2.createElement(Select.Root, {
|
|
4269
4064
|
disabled: value === null,
|
|
4270
4065
|
value: value ?? "0",
|
|
4271
4066
|
onValueChange: (value2) => onAction?.({
|
|
4272
4067
|
type: "heading",
|
|
4273
4068
|
data: parseInt(value2)
|
|
4274
4069
|
})
|
|
4070
|
+
}, /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
|
|
4071
|
+
asChild: true
|
|
4275
4072
|
}, /* @__PURE__ */ React2.createElement(NaturalToolbar.Button, {
|
|
4276
4073
|
asChild: true
|
|
4277
4074
|
}, /* @__PURE__ */ React2.createElement(Select.TriggerButton, {
|
|
@@ -4281,7 +4078,7 @@ var MarkdownHeading = () => {
|
|
|
4281
4078
|
className: "sr-only"
|
|
4282
4079
|
}, t("heading label")), /* @__PURE__ */ React2.createElement(HeadingIcon, {
|
|
4283
4080
|
className: iconStyles
|
|
4284
|
-
}))), /* @__PURE__ */ React2.createElement(Select.Portal, null, /* @__PURE__ */ React2.createElement(Select.Content, null, /* @__PURE__ */ React2.createElement(Select.ScrollUpButton, null), /* @__PURE__ */ React2.createElement(Select.Viewport, null, /* @__PURE__ */ React2.createElement(Select.Option, {
|
|
4081
|
+
})))), /* @__PURE__ */ React2.createElement(Select.Portal, null, /* @__PURE__ */ React2.createElement(Select.Content, null, /* @__PURE__ */ React2.createElement(Select.ScrollUpButton, null), /* @__PURE__ */ React2.createElement(Select.Viewport, null, /* @__PURE__ */ React2.createElement(Select.Option, {
|
|
4285
4082
|
value: "0"
|
|
4286
4083
|
}, /* @__PURE__ */ React2.createElement(Paragraph, {
|
|
4287
4084
|
className: iconStyles
|
|
@@ -4307,7 +4104,7 @@ var MarkdownHeading = () => {
|
|
|
4307
4104
|
className: iconStyles
|
|
4308
4105
|
}), level === 6 && /* @__PURE__ */ React2.createElement(TextHSix, {
|
|
4309
4106
|
className: iconStyles
|
|
4310
|
-
})))), /* @__PURE__ */ React2.createElement(Select.ScrollDownButton, null), /* @__PURE__ */ React2.createElement(Select.Arrow, null))));
|
|
4107
|
+
})))), /* @__PURE__ */ React2.createElement(Select.ScrollDownButton, null), /* @__PURE__ */ React2.createElement(Select.Arrow, null)))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, tooltipProps, t("heading label"), /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))));
|
|
4311
4108
|
};
|
|
4312
4109
|
var markdownStyles = [
|
|
4313
4110
|
{
|
|
@@ -4426,7 +4223,9 @@ var MarkdownStandard = () => /* @__PURE__ */ React2.createElement(React2.Fragmen
|
|
|
4426
4223
|
var MarkdownExtended = () => {
|
|
4427
4224
|
const { onAction } = useToolbarContext("MarkdownStyles");
|
|
4428
4225
|
const { t } = useTranslation(translationKey);
|
|
4429
|
-
return /* @__PURE__ */ React2.createElement(
|
|
4226
|
+
return /* @__PURE__ */ React2.createElement(Tooltip.Root, null, /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
|
|
4227
|
+
asChild: true
|
|
4228
|
+
}, /* @__PURE__ */ React2.createElement(NaturalToolbar.Button, {
|
|
4430
4229
|
variant: "ghost",
|
|
4431
4230
|
"data-testid": "editor.toolbar.comment",
|
|
4432
4231
|
onClick: () => onAction?.({
|
|
@@ -4437,7 +4236,7 @@ var MarkdownExtended = () => {
|
|
|
4437
4236
|
className: iconStyles
|
|
4438
4237
|
}), /* @__PURE__ */ React2.createElement("span", {
|
|
4439
4238
|
className: "sr-only"
|
|
4440
|
-
}, t("comment label")));
|
|
4239
|
+
}, t("comment label")))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, tooltipProps, t("comment label"), /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))));
|
|
4441
4240
|
};
|
|
4442
4241
|
var Toolbar = {
|
|
4443
4242
|
Root: ToolbarRoot,
|
|
@@ -4628,7 +4427,7 @@ var useEditorView = (id) => {
|
|
|
4628
4427
|
|
|
4629
4428
|
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
|
4630
4429
|
import { EditorSelection as EditorSelection2, EditorState as EditorState3 } from "@codemirror/state";
|
|
4631
|
-
import { EditorView as
|
|
4430
|
+
import { EditorView as EditorView15 } from "@codemirror/view";
|
|
4632
4431
|
import { useEffect as useEffect3, useRef as useRef3, useState as useState4 } from "react";
|
|
4633
4432
|
import { log as log5 } from "@dxos/log";
|
|
4634
4433
|
import { isNotFalsy as isNotFalsy5 } from "@dxos/util";
|
|
@@ -4645,7 +4444,7 @@ var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions }
|
|
|
4645
4444
|
selection,
|
|
4646
4445
|
extensions: [
|
|
4647
4446
|
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
4648
|
-
|
|
4447
|
+
EditorView15.exceptionSink.of((err) => {
|
|
4649
4448
|
log5.catch(err, void 0, {
|
|
4650
4449
|
F: __dxlog_file6,
|
|
4651
4450
|
L: 60,
|
|
@@ -4654,12 +4453,12 @@ var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions }
|
|
|
4654
4453
|
});
|
|
4655
4454
|
}),
|
|
4656
4455
|
extensions,
|
|
4657
|
-
|
|
4456
|
+
EditorView15.updateListener.of(() => {
|
|
4658
4457
|
onUpdate.current?.();
|
|
4659
4458
|
})
|
|
4660
4459
|
].filter(isNotFalsy5)
|
|
4661
4460
|
});
|
|
4662
|
-
view2 = new
|
|
4461
|
+
view2 = new EditorView15({
|
|
4663
4462
|
parent: parentRef.current,
|
|
4664
4463
|
scrollTo,
|
|
4665
4464
|
state,
|
|
@@ -4717,19 +4516,19 @@ var createDataExtensions = ({ readonly = false } = {}) => {
|
|
|
4717
4516
|
return [
|
|
4718
4517
|
//
|
|
4719
4518
|
EditorState3.readOnly.of(readonly),
|
|
4720
|
-
|
|
4519
|
+
EditorView15.editable.of(!readonly)
|
|
4721
4520
|
];
|
|
4722
4521
|
};
|
|
4723
4522
|
var createThemeExtensions = ({ theme, themeMode, slots } = {}) => {
|
|
4724
4523
|
return [
|
|
4725
4524
|
//
|
|
4726
|
-
|
|
4727
|
-
theme &&
|
|
4728
|
-
|
|
4729
|
-
|
|
4525
|
+
EditorView15.baseTheme(defaultTheme),
|
|
4526
|
+
theme && EditorView15.theme(theme),
|
|
4527
|
+
EditorView15.darkTheme.of(themeMode === "dark"),
|
|
4528
|
+
EditorView15.editorAttributes.of({
|
|
4730
4529
|
class: slots?.editor?.className ?? ""
|
|
4731
4530
|
}),
|
|
4732
|
-
|
|
4531
|
+
EditorView15.contentAttributes.of({
|
|
4733
4532
|
class: slots?.content?.className ?? ""
|
|
4734
4533
|
})
|
|
4735
4534
|
].filter(isNotFalsy5);
|
|
@@ -4829,7 +4628,6 @@ export {
|
|
|
4829
4628
|
awarenessProvider,
|
|
4830
4629
|
blast,
|
|
4831
4630
|
callbackWrapper,
|
|
4832
|
-
code2 as code,
|
|
4833
4631
|
codeTheme,
|
|
4834
4632
|
comments,
|
|
4835
4633
|
compareFormatting,
|
|
@@ -4840,6 +4638,7 @@ export {
|
|
|
4840
4638
|
createThemeExtensions,
|
|
4841
4639
|
cursorLineMargin,
|
|
4842
4640
|
cursorLineMarginFacet,
|
|
4641
|
+
decorateMarkdown,
|
|
4843
4642
|
defaultMarkdownSlots,
|
|
4844
4643
|
defaultOptions,
|
|
4845
4644
|
defaultSlots,
|
|
@@ -4854,12 +4653,10 @@ export {
|
|
|
4854
4653
|
formatting,
|
|
4855
4654
|
getFormatting,
|
|
4856
4655
|
getToken,
|
|
4857
|
-
heading2 as heading,
|
|
4858
|
-
hr,
|
|
4859
4656
|
image,
|
|
4860
4657
|
insertTable,
|
|
4861
4658
|
keymap8 as keymap,
|
|
4862
|
-
|
|
4659
|
+
linkTooltip,
|
|
4863
4660
|
listener,
|
|
4864
4661
|
logChanges,
|
|
4865
4662
|
markdownHighlightStyle,
|
|
@@ -4881,7 +4678,6 @@ export {
|
|
|
4881
4678
|
setStyle,
|
|
4882
4679
|
table,
|
|
4883
4680
|
tags2 as tags,
|
|
4884
|
-
tasklist,
|
|
4885
4681
|
textTheme,
|
|
4886
4682
|
toggleBlockquote,
|
|
4887
4683
|
toggleCodeblock,
|
|
@@ -4891,6 +4687,7 @@ export {
|
|
|
4891
4687
|
toggleStrikethrough,
|
|
4892
4688
|
toggleStrong,
|
|
4893
4689
|
toggleStyle,
|
|
4690
|
+
translations_default as translations,
|
|
4894
4691
|
typewriter,
|
|
4895
4692
|
useActionHandler,
|
|
4896
4693
|
useComments,
|