@codemirror/view 6.22.3 → 6.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -871,7 +871,8 @@ class WidgetView extends ContentView {
871
871
  this.prevWidget.destroy(this.dom);
872
872
  this.prevWidget = null;
873
873
  this.setDOM(this.widget.toDOM(view));
874
- this.dom.contentEditable = "false";
874
+ if (!this.widget.editable)
875
+ this.dom.contentEditable = "false";
875
876
  }
876
877
  }
877
878
  getSide() { return this.side; }
@@ -1294,7 +1295,8 @@ class BlockWidgetView extends ContentView {
1294
1295
  this.prevWidget.destroy(this.dom);
1295
1296
  this.prevWidget = null;
1296
1297
  this.setDOM(this.widget.toDOM(view));
1297
- this.dom.contentEditable = "false";
1298
+ if (!this.widget.editable)
1299
+ this.dom.contentEditable = "false";
1298
1300
  }
1299
1301
  }
1300
1302
  get overrideDOMText() {
@@ -1399,6 +1401,10 @@ class WidgetType {
1399
1401
  */
1400
1402
  get isHidden() { return false; }
1401
1403
  /**
1404
+ @internal
1405
+ */
1406
+ get editable() { return false; }
1407
+ /**
1402
1408
  This is called when the an instance of the widget is removed
1403
1409
  from the editor view.
1404
1410
  */
@@ -1785,487 +1791,124 @@ class NullWidget extends WidgetType {
1785
1791
  get isHidden() { return true; }
1786
1792
  }
1787
1793
 
1788
- const clickAddsSelectionRange = state.Facet.define();
1789
- const dragMovesSelection$1 = state.Facet.define();
1790
- const mouseSelectionStyle = state.Facet.define();
1791
- const exceptionSink = state.Facet.define();
1792
- const updateListener = state.Facet.define();
1793
- const inputHandler = state.Facet.define();
1794
- const focusChangeEffect = state.Facet.define();
1795
- const perLineTextDirection = state.Facet.define({
1796
- combine: values => values.some(x => x)
1797
- });
1798
- const nativeSelectionHidden = state.Facet.define({
1799
- combine: values => values.some(x => x)
1800
- });
1801
- class ScrollTarget {
1802
- constructor(range, y = "nearest", x = "nearest", yMargin = 5, xMargin = 5,
1803
- // This data structure is abused to also store precise scroll
1804
- // snapshots, instead of a `scrollIntoView` request. When this
1805
- // flag is `true`, `range` points at a position in the reference
1806
- // line, `yMargin` holds the difference between the top of that
1807
- // line and the top of the editor, and `xMargin` holds the
1808
- // editor's `scrollLeft`.
1809
- isSnapshot = false) {
1810
- this.range = range;
1811
- this.y = y;
1812
- this.x = x;
1813
- this.yMargin = yMargin;
1814
- this.xMargin = xMargin;
1815
- this.isSnapshot = isSnapshot;
1816
- }
1817
- map(changes) {
1818
- return changes.empty ? this :
1819
- new ScrollTarget(this.range.map(changes), this.y, this.x, this.yMargin, this.xMargin, this.isSnapshot);
1820
- }
1821
- clip(state$1) {
1822
- return this.range.to <= state$1.doc.length ? this :
1823
- new ScrollTarget(state.EditorSelection.cursor(state$1.doc.length), this.y, this.x, this.yMargin, this.xMargin, this.isSnapshot);
1824
- }
1825
- }
1826
- const scrollIntoView = state.StateEffect.define({ map: (t, ch) => t.map(ch) });
1827
1794
  /**
1828
- Log or report an unhandled exception in client code. Should
1829
- probably only be used by extension code that allows client code to
1830
- provide functions, and calls those functions in a context where an
1831
- exception can't be propagated to calling code in a reasonable way
1832
- (for example when in an event handler).
1833
-
1834
- Either calls a handler registered with
1835
- [`EditorView.exceptionSink`](https://codemirror.net/6/docs/ref/#view.EditorView^exceptionSink),
1836
- `window.onerror`, if defined, or `console.error` (in which case
1837
- it'll pass `context`, when given, as first argument).
1795
+ Used to indicate [text direction](https://codemirror.net/6/docs/ref/#view.EditorView.textDirection).
1838
1796
  */
1839
- function logException(state, exception, context) {
1840
- let handler = state.facet(exceptionSink);
1841
- if (handler.length)
1842
- handler[0](exception);
1843
- else if (window.onerror)
1844
- window.onerror(String(exception), context, undefined, undefined, exception);
1845
- else if (context)
1846
- console.error(context + ":", exception);
1847
- else
1848
- console.error(exception);
1797
+ exports.Direction = void 0;
1798
+ (function (Direction) {
1799
+ // (These are chosen to match the base levels, in bidi algorithm
1800
+ // terms, of spans in that direction.)
1801
+ /**
1802
+ Left-to-right.
1803
+ */
1804
+ Direction[Direction["LTR"] = 0] = "LTR";
1805
+ /**
1806
+ Right-to-left.
1807
+ */
1808
+ Direction[Direction["RTL"] = 1] = "RTL";
1809
+ })(exports.Direction || (exports.Direction = {}));
1810
+ const LTR = exports.Direction.LTR, RTL = exports.Direction.RTL;
1811
+ // Decode a string with each type encoded as log2(type)
1812
+ function dec(str) {
1813
+ let result = [];
1814
+ for (let i = 0; i < str.length; i++)
1815
+ result.push(1 << +str[i]);
1816
+ return result;
1849
1817
  }
1850
- const editable = state.Facet.define({ combine: values => values.length ? values[0] : true });
1851
- let nextPluginID = 0;
1852
- const viewPlugin = state.Facet.define();
1818
+ // Character types for codepoints 0 to 0xf8
1819
+ const LowTypes = dec("88888888888888888888888888888888888666888888787833333333337888888000000000000000000000000008888880000000000000000000000000088888888888888888888888888888888888887866668888088888663380888308888800000000000000000000000800000000000000000000000000000008");
1820
+ // Character types for codepoints 0x600 to 0x6f9
1821
+ const ArabicTypes = dec("4444448826627288999999999992222222222222222222222222222222222222222222222229999999999999999999994444444444644222822222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222999999949999999229989999223333333333");
1822
+ const Brackets = Object.create(null), BracketStack = [];
1823
+ // There's a lot more in
1824
+ // https://www.unicode.org/Public/UCD/latest/ucd/BidiBrackets.txt,
1825
+ // which are left out to keep code size down.
1826
+ for (let p of ["()", "[]", "{}"]) {
1827
+ let l = p.charCodeAt(0), r = p.charCodeAt(1);
1828
+ Brackets[l] = r;
1829
+ Brackets[r] = -l;
1830
+ }
1831
+ function charType(ch) {
1832
+ return ch <= 0xf7 ? LowTypes[ch] :
1833
+ 0x590 <= ch && ch <= 0x5f4 ? 2 /* T.R */ :
1834
+ 0x600 <= ch && ch <= 0x6f9 ? ArabicTypes[ch - 0x600] :
1835
+ 0x6ee <= ch && ch <= 0x8ac ? 4 /* T.AL */ :
1836
+ 0x2000 <= ch && ch <= 0x200c ? 256 /* T.NI */ :
1837
+ 0xfb50 <= ch && ch <= 0xfdff ? 4 /* T.AL */ : 1 /* T.L */;
1838
+ }
1839
+ const BidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac\ufb50-\ufdff]/;
1853
1840
  /**
1854
- View plugins associate stateful values with a view. They can
1855
- influence the way the content is drawn, and are notified of things
1856
- that happen in the view.
1841
+ Represents a contiguous range of text that has a single direction
1842
+ (as in left-to-right or right-to-left).
1857
1843
  */
1858
- class ViewPlugin {
1859
- constructor(
1844
+ class BidiSpan {
1860
1845
  /**
1861
- @internal
1846
+ The direction of this span.
1862
1847
  */
1863
- id,
1848
+ get dir() { return this.level % 2 ? RTL : LTR; }
1864
1849
  /**
1865
1850
  @internal
1866
1851
  */
1867
- create,
1852
+ constructor(
1868
1853
  /**
1869
- @internal
1854
+ The start of the span (relative to the start of the line).
1870
1855
  */
1871
- domEventHandlers,
1856
+ from,
1872
1857
  /**
1873
- @internal
1858
+ The end of the span.
1874
1859
  */
1875
- domEventObservers, buildExtensions) {
1876
- this.id = id;
1877
- this.create = create;
1878
- this.domEventHandlers = domEventHandlers;
1879
- this.domEventObservers = domEventObservers;
1880
- this.extension = buildExtensions(this);
1881
- }
1860
+ to,
1882
1861
  /**
1883
- Define a plugin from a constructor function that creates the
1884
- plugin's value, given an editor view.
1862
+ The ["bidi
1863
+ level"](https://unicode.org/reports/tr9/#Basic_Display_Algorithm)
1864
+ of the span (in this context, 0 means
1865
+ left-to-right, 1 means right-to-left, 2 means left-to-right
1866
+ number inside right-to-left text).
1885
1867
  */
1886
- static define(create, spec) {
1887
- const { eventHandlers, eventObservers, provide, decorations: deco } = spec || {};
1888
- return new ViewPlugin(nextPluginID++, create, eventHandlers, eventObservers, plugin => {
1889
- let ext = [viewPlugin.of(plugin)];
1890
- if (deco)
1891
- ext.push(decorations.of(view => {
1892
- let pluginInst = view.plugin(plugin);
1893
- return pluginInst ? deco(pluginInst) : Decoration.none;
1894
- }));
1895
- if (provide)
1896
- ext.push(provide(plugin));
1897
- return ext;
1898
- });
1868
+ level) {
1869
+ this.from = from;
1870
+ this.to = to;
1871
+ this.level = level;
1899
1872
  }
1900
1873
  /**
1901
- Create a plugin for a class whose constructor takes a single
1902
- editor view as argument.
1874
+ @internal
1903
1875
  */
1904
- static fromClass(cls, spec) {
1905
- return ViewPlugin.define(view => new cls(view), spec);
1906
- }
1907
- }
1908
- class PluginInstance {
1909
- constructor(spec) {
1910
- this.spec = spec;
1911
- // When starting an update, all plugins have this field set to the
1912
- // update object, indicating they need to be updated. When finished
1913
- // updating, it is set to `false`. Retrieving a plugin that needs to
1914
- // be updated with `view.plugin` forces an eager update.
1915
- this.mustUpdate = null;
1916
- // This is null when the plugin is initially created, but
1917
- // initialized on the first update.
1918
- this.value = null;
1919
- }
1920
- update(view) {
1921
- if (!this.value) {
1922
- if (this.spec) {
1923
- try {
1924
- this.value = this.spec.create(view);
1925
- }
1926
- catch (e) {
1927
- logException(view.state, e, "CodeMirror plugin crashed");
1928
- this.deactivate();
1929
- }
1930
- }
1931
- }
1932
- else if (this.mustUpdate) {
1933
- let update = this.mustUpdate;
1934
- this.mustUpdate = null;
1935
- if (this.value.update) {
1936
- try {
1937
- this.value.update(update);
1938
- }
1939
- catch (e) {
1940
- logException(update.state, e, "CodeMirror plugin crashed");
1941
- if (this.value.destroy)
1942
- try {
1943
- this.value.destroy();
1944
- }
1945
- catch (_) { }
1946
- this.deactivate();
1947
- }
1948
- }
1949
- }
1950
- return this;
1951
- }
1952
- destroy(view) {
1953
- var _a;
1954
- if ((_a = this.value) === null || _a === void 0 ? void 0 : _a.destroy) {
1955
- try {
1956
- this.value.destroy();
1957
- }
1958
- catch (e) {
1959
- logException(view.state, e, "CodeMirror plugin crashed");
1876
+ side(end, dir) { return (this.dir == dir) == end ? this.to : this.from; }
1877
+ /**
1878
+ @internal
1879
+ */
1880
+ forward(forward, dir) { return forward == (this.dir == dir); }
1881
+ /**
1882
+ @internal
1883
+ */
1884
+ static find(order, index, level, assoc) {
1885
+ let maybe = -1;
1886
+ for (let i = 0; i < order.length; i++) {
1887
+ let span = order[i];
1888
+ if (span.from <= index && span.to >= index) {
1889
+ if (span.level == level)
1890
+ return i;
1891
+ // When multiple spans match, if assoc != 0, take the one that
1892
+ // covers that side, otherwise take the one with the minimum
1893
+ // level.
1894
+ if (maybe < 0 || (assoc != 0 ? (assoc < 0 ? span.from < index : span.to > index) : order[maybe].level > span.level))
1895
+ maybe = i;
1960
1896
  }
1961
1897
  }
1898
+ if (maybe < 0)
1899
+ throw new RangeError("Index out of range");
1900
+ return maybe;
1962
1901
  }
1963
- deactivate() {
1964
- this.spec = this.value = null;
1902
+ }
1903
+ function isolatesEq(a, b) {
1904
+ if (a.length != b.length)
1905
+ return false;
1906
+ for (let i = 0; i < a.length; i++) {
1907
+ let iA = a[i], iB = b[i];
1908
+ if (iA.from != iB.from || iA.to != iB.to || iA.direction != iB.direction || !isolatesEq(iA.inner, iB.inner))
1909
+ return false;
1965
1910
  }
1966
- }
1967
- const editorAttributes = state.Facet.define();
1968
- const contentAttributes = state.Facet.define();
1969
- // Provide decorations
1970
- const decorations = state.Facet.define();
1971
- const atomicRanges = state.Facet.define();
1972
- const bidiIsolatedRanges = state.Facet.define();
1973
- function getIsolatedRanges(view, from, to) {
1974
- let isolates = view.state.facet(bidiIsolatedRanges);
1975
- if (!isolates.length)
1976
- return isolates;
1977
- let sets = isolates.map(i => i instanceof Function ? i(view) : i);
1978
- let result = [];
1979
- state.RangeSet.spans(sets, from, to, {
1980
- point() { },
1981
- span(from, to, active, open) {
1982
- let level = result;
1983
- for (let i = active.length - 1; i >= 0; i--, open--) {
1984
- let iso = active[i].spec.bidiIsolate, update;
1985
- if (iso == null)
1986
- continue;
1987
- if (open > 0 && level.length &&
1988
- (update = level[level.length - 1]).to == from && update.direction == iso) {
1989
- update.to = to;
1990
- level = update.inner;
1991
- }
1992
- else {
1993
- let add = { from, to, direction: iso, inner: [] };
1994
- level.push(add);
1995
- level = add.inner;
1996
- }
1997
- }
1998
- }
1999
- });
2000
- return result;
2001
- }
2002
- const scrollMargins = state.Facet.define();
2003
- function getScrollMargins(view) {
2004
- let left = 0, right = 0, top = 0, bottom = 0;
2005
- for (let source of view.state.facet(scrollMargins)) {
2006
- let m = source(view);
2007
- if (m) {
2008
- if (m.left != null)
2009
- left = Math.max(left, m.left);
2010
- if (m.right != null)
2011
- right = Math.max(right, m.right);
2012
- if (m.top != null)
2013
- top = Math.max(top, m.top);
2014
- if (m.bottom != null)
2015
- bottom = Math.max(bottom, m.bottom);
2016
- }
2017
- }
2018
- return { left, right, top, bottom };
2019
- }
2020
- const styleModule = state.Facet.define();
2021
- class ChangedRange {
2022
- constructor(fromA, toA, fromB, toB) {
2023
- this.fromA = fromA;
2024
- this.toA = toA;
2025
- this.fromB = fromB;
2026
- this.toB = toB;
2027
- }
2028
- join(other) {
2029
- return new ChangedRange(Math.min(this.fromA, other.fromA), Math.max(this.toA, other.toA), Math.min(this.fromB, other.fromB), Math.max(this.toB, other.toB));
2030
- }
2031
- addToSet(set) {
2032
- let i = set.length, me = this;
2033
- for (; i > 0; i--) {
2034
- let range = set[i - 1];
2035
- if (range.fromA > me.toA)
2036
- continue;
2037
- if (range.toA < me.fromA)
2038
- break;
2039
- me = me.join(range);
2040
- set.splice(i - 1, 1);
2041
- }
2042
- set.splice(i, 0, me);
2043
- return set;
2044
- }
2045
- static extendWithRanges(diff, ranges) {
2046
- if (ranges.length == 0)
2047
- return diff;
2048
- let result = [];
2049
- for (let dI = 0, rI = 0, posA = 0, posB = 0;; dI++) {
2050
- let next = dI == diff.length ? null : diff[dI], off = posA - posB;
2051
- let end = next ? next.fromB : 1e9;
2052
- while (rI < ranges.length && ranges[rI] < end) {
2053
- let from = ranges[rI], to = ranges[rI + 1];
2054
- let fromB = Math.max(posB, from), toB = Math.min(end, to);
2055
- if (fromB <= toB)
2056
- new ChangedRange(fromB + off, toB + off, fromB, toB).addToSet(result);
2057
- if (to > end)
2058
- break;
2059
- else
2060
- rI += 2;
2061
- }
2062
- if (!next)
2063
- return result;
2064
- new ChangedRange(next.fromA, next.toA, next.fromB, next.toB).addToSet(result);
2065
- posA = next.toA;
2066
- posB = next.toB;
2067
- }
2068
- }
2069
- }
2070
- /**
2071
- View [plugins](https://codemirror.net/6/docs/ref/#view.ViewPlugin) are given instances of this
2072
- class, which describe what happened, whenever the view is updated.
2073
- */
2074
- class ViewUpdate {
2075
- constructor(
2076
- /**
2077
- The editor view that the update is associated with.
2078
- */
2079
- view,
2080
- /**
2081
- The new editor state.
2082
- */
2083
- state$1,
2084
- /**
2085
- The transactions involved in the update. May be empty.
2086
- */
2087
- transactions) {
2088
- this.view = view;
2089
- this.state = state$1;
2090
- this.transactions = transactions;
2091
- /**
2092
- @internal
2093
- */
2094
- this.flags = 0;
2095
- this.startState = view.state;
2096
- this.changes = state.ChangeSet.empty(this.startState.doc.length);
2097
- for (let tr of transactions)
2098
- this.changes = this.changes.compose(tr.changes);
2099
- let changedRanges = [];
2100
- this.changes.iterChangedRanges((fromA, toA, fromB, toB) => changedRanges.push(new ChangedRange(fromA, toA, fromB, toB)));
2101
- this.changedRanges = changedRanges;
2102
- }
2103
- /**
2104
- @internal
2105
- */
2106
- static create(view, state, transactions) {
2107
- return new ViewUpdate(view, state, transactions);
2108
- }
2109
- /**
2110
- Tells you whether the [viewport](https://codemirror.net/6/docs/ref/#view.EditorView.viewport) or
2111
- [visible ranges](https://codemirror.net/6/docs/ref/#view.EditorView.visibleRanges) changed in this
2112
- update.
2113
- */
2114
- get viewportChanged() {
2115
- return (this.flags & 4 /* UpdateFlag.Viewport */) > 0;
2116
- }
2117
- /**
2118
- Indicates whether the height of a block element in the editor
2119
- changed in this update.
2120
- */
2121
- get heightChanged() {
2122
- return (this.flags & 2 /* UpdateFlag.Height */) > 0;
2123
- }
2124
- /**
2125
- Returns true when the document was modified or the size of the
2126
- editor, or elements within the editor, changed.
2127
- */
2128
- get geometryChanged() {
2129
- return this.docChanged || (this.flags & (8 /* UpdateFlag.Geometry */ | 2 /* UpdateFlag.Height */)) > 0;
2130
- }
2131
- /**
2132
- True when this update indicates a focus change.
2133
- */
2134
- get focusChanged() {
2135
- return (this.flags & 1 /* UpdateFlag.Focus */) > 0;
2136
- }
2137
- /**
2138
- Whether the document changed in this update.
2139
- */
2140
- get docChanged() {
2141
- return !this.changes.empty;
2142
- }
2143
- /**
2144
- Whether the selection was explicitly set in this update.
2145
- */
2146
- get selectionSet() {
2147
- return this.transactions.some(tr => tr.selection);
2148
- }
2149
- /**
2150
- @internal
2151
- */
2152
- get empty() { return this.flags == 0 && this.transactions.length == 0; }
2153
- }
2154
-
2155
- /**
2156
- Used to indicate [text direction](https://codemirror.net/6/docs/ref/#view.EditorView.textDirection).
2157
- */
2158
- exports.Direction = void 0;
2159
- (function (Direction) {
2160
- // (These are chosen to match the base levels, in bidi algorithm
2161
- // terms, of spans in that direction.)
2162
- /**
2163
- Left-to-right.
2164
- */
2165
- Direction[Direction["LTR"] = 0] = "LTR";
2166
- /**
2167
- Right-to-left.
2168
- */
2169
- Direction[Direction["RTL"] = 1] = "RTL";
2170
- })(exports.Direction || (exports.Direction = {}));
2171
- const LTR = exports.Direction.LTR, RTL = exports.Direction.RTL;
2172
- // Decode a string with each type encoded as log2(type)
2173
- function dec(str) {
2174
- let result = [];
2175
- for (let i = 0; i < str.length; i++)
2176
- result.push(1 << +str[i]);
2177
- return result;
2178
- }
2179
- // Character types for codepoints 0 to 0xf8
2180
- const LowTypes = dec("88888888888888888888888888888888888666888888787833333333337888888000000000000000000000000008888880000000000000000000000000088888888888888888888888888888888888887866668888088888663380888308888800000000000000000000000800000000000000000000000000000008");
2181
- // Character types for codepoints 0x600 to 0x6f9
2182
- const ArabicTypes = dec("4444448826627288999999999992222222222222222222222222222222222222222222222229999999999999999999994444444444644222822222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222999999949999999229989999223333333333");
2183
- const Brackets = Object.create(null), BracketStack = [];
2184
- // There's a lot more in
2185
- // https://www.unicode.org/Public/UCD/latest/ucd/BidiBrackets.txt,
2186
- // which are left out to keep code size down.
2187
- for (let p of ["()", "[]", "{}"]) {
2188
- let l = p.charCodeAt(0), r = p.charCodeAt(1);
2189
- Brackets[l] = r;
2190
- Brackets[r] = -l;
2191
- }
2192
- function charType(ch) {
2193
- return ch <= 0xf7 ? LowTypes[ch] :
2194
- 0x590 <= ch && ch <= 0x5f4 ? 2 /* T.R */ :
2195
- 0x600 <= ch && ch <= 0x6f9 ? ArabicTypes[ch - 0x600] :
2196
- 0x6ee <= ch && ch <= 0x8ac ? 4 /* T.AL */ :
2197
- 0x2000 <= ch && ch <= 0x200c ? 256 /* T.NI */ :
2198
- 0xfb50 <= ch && ch <= 0xfdff ? 4 /* T.AL */ : 1 /* T.L */;
2199
- }
2200
- const BidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac\ufb50-\ufdff]/;
2201
- /**
2202
- Represents a contiguous range of text that has a single direction
2203
- (as in left-to-right or right-to-left).
2204
- */
2205
- class BidiSpan {
2206
- /**
2207
- The direction of this span.
2208
- */
2209
- get dir() { return this.level % 2 ? RTL : LTR; }
2210
- /**
2211
- @internal
2212
- */
2213
- constructor(
2214
- /**
2215
- The start of the span (relative to the start of the line).
2216
- */
2217
- from,
2218
- /**
2219
- The end of the span.
2220
- */
2221
- to,
2222
- /**
2223
- The ["bidi
2224
- level"](https://unicode.org/reports/tr9/#Basic_Display_Algorithm)
2225
- of the span (in this context, 0 means
2226
- left-to-right, 1 means right-to-left, 2 means left-to-right
2227
- number inside right-to-left text).
2228
- */
2229
- level) {
2230
- this.from = from;
2231
- this.to = to;
2232
- this.level = level;
2233
- }
2234
- /**
2235
- @internal
2236
- */
2237
- side(end, dir) { return (this.dir == dir) == end ? this.to : this.from; }
2238
- /**
2239
- @internal
2240
- */
2241
- static find(order, index, level, assoc) {
2242
- let maybe = -1;
2243
- for (let i = 0; i < order.length; i++) {
2244
- let span = order[i];
2245
- if (span.from <= index && span.to >= index) {
2246
- if (span.level == level)
2247
- return i;
2248
- // When multiple spans match, if assoc != 0, take the one that
2249
- // covers that side, otherwise take the one with the minimum
2250
- // level.
2251
- if (maybe < 0 || (assoc != 0 ? (assoc < 0 ? span.from < index : span.to > index) : order[maybe].level > span.level))
2252
- maybe = i;
2253
- }
2254
- }
2255
- if (maybe < 0)
2256
- throw new RangeError("Index out of range");
2257
- return maybe;
2258
- }
2259
- }
2260
- function isolatesEq(a, b) {
2261
- if (a.length != b.length)
2262
- return false;
2263
- for (let i = 0; i < a.length; i++) {
2264
- let iA = a[i], iB = b[i];
2265
- if (iA.from != iB.from || iA.to != iB.to || iA.direction != iB.direction || !isolatesEq(iA.inner, iB.inner))
2266
- return false;
2267
- }
2268
- return true;
1911
+ return true;
2269
1912
  }
2270
1913
  // Reused array of character types
2271
1914
  const types = [];
@@ -2469,161 +2112,536 @@ function emitSpans(line, from, to, level, baseLevel, isolates, order) {
2469
2112
  for (let upto = iso.to, jI = iI + 1;;) {
2470
2113
  if (upto == to)
2471
2114
  break run;
2472
- if (jI < isolates.length && isolates[jI].from == upto)
2473
- upto = isolates[jI++].to;
2474
- else if (types[upto] == ourType)
2115
+ if (jI < isolates.length && isolates[jI].from == upto)
2116
+ upto = isolates[jI++].to;
2117
+ else if (types[upto] == ourType)
2118
+ break run;
2119
+ else
2120
+ break;
2121
+ }
2122
+ iI++;
2123
+ if (recurse) {
2124
+ recurse.push(iso);
2125
+ }
2126
+ else {
2127
+ if (iso.from > iCh)
2128
+ order.push(new BidiSpan(iCh, iso.from, localLevel));
2129
+ let dirSwap = (iso.direction == LTR) != !(localLevel % 2);
2130
+ computeSectionOrder(line, dirSwap ? level + 1 : level, baseLevel, iso.inner, iso.from, iso.to, order);
2131
+ iCh = iso.to;
2132
+ }
2133
+ iScan = iso.to;
2134
+ }
2135
+ else if (iScan == to || (sameDir ? types[iScan] != ourType : types[iScan] == ourType)) {
2136
+ break;
2137
+ }
2138
+ else {
2139
+ iScan++;
2140
+ }
2141
+ }
2142
+ if (recurse)
2143
+ emitSpans(line, iCh, iScan, level + 1, baseLevel, recurse, order);
2144
+ else if (iCh < iScan)
2145
+ order.push(new BidiSpan(iCh, iScan, localLevel));
2146
+ iCh = iScan;
2147
+ }
2148
+ }
2149
+ else {
2150
+ // Iterate in reverse to flip the span order. Same code again, but
2151
+ // going from the back of the section to the front
2152
+ for (let iCh = to, iI = isolates.length; iCh > from;) {
2153
+ let sameDir = true, isNum = false;
2154
+ if (!iI || iCh > isolates[iI - 1].to) {
2155
+ let next = types[iCh - 1];
2156
+ if (next != ourType) {
2157
+ sameDir = false;
2158
+ isNum = next == 16 /* T.AN */;
2159
+ }
2160
+ }
2161
+ let recurse = !sameDir && ourType == 1 /* T.L */ ? [] : null;
2162
+ let localLevel = sameDir ? level : level + 1;
2163
+ let iScan = iCh;
2164
+ run: for (;;) {
2165
+ if (iI && iScan == isolates[iI - 1].to) {
2166
+ if (isNum)
2167
+ break run;
2168
+ let iso = isolates[--iI];
2169
+ // Scan ahead to verify that there is another char in this dir after the isolate(s)
2170
+ if (!sameDir)
2171
+ for (let upto = iso.from, jI = iI;;) {
2172
+ if (upto == from)
2173
+ break run;
2174
+ if (jI && isolates[jI - 1].to == upto)
2175
+ upto = isolates[--jI].from;
2176
+ else if (types[upto - 1] == ourType)
2475
2177
  break run;
2476
2178
  else
2477
2179
  break;
2478
2180
  }
2479
- iI++;
2480
2181
  if (recurse) {
2481
2182
  recurse.push(iso);
2482
2183
  }
2483
2184
  else {
2484
- if (iso.from > iCh)
2485
- order.push(new BidiSpan(iCh, iso.from, localLevel));
2185
+ if (iso.to < iCh)
2186
+ order.push(new BidiSpan(iso.to, iCh, localLevel));
2486
2187
  let dirSwap = (iso.direction == LTR) != !(localLevel % 2);
2487
2188
  computeSectionOrder(line, dirSwap ? level + 1 : level, baseLevel, iso.inner, iso.from, iso.to, order);
2488
- iCh = iso.to;
2189
+ iCh = iso.from;
2489
2190
  }
2490
- iScan = iso.to;
2191
+ iScan = iso.from;
2491
2192
  }
2492
- else if (iScan == to || (sameDir ? types[iScan] != ourType : types[iScan] == ourType)) {
2193
+ else if (iScan == from || (sameDir ? types[iScan - 1] != ourType : types[iScan - 1] == ourType)) {
2493
2194
  break;
2494
2195
  }
2495
2196
  else {
2496
- iScan++;
2197
+ iScan--;
2198
+ }
2199
+ }
2200
+ if (recurse)
2201
+ emitSpans(line, iScan, iCh, level + 1, baseLevel, recurse, order);
2202
+ else if (iScan < iCh)
2203
+ order.push(new BidiSpan(iScan, iCh, localLevel));
2204
+ iCh = iScan;
2205
+ }
2206
+ }
2207
+ }
2208
+ function computeSectionOrder(line, level, baseLevel, isolates, from, to, order) {
2209
+ let outerType = (level % 2 ? 2 /* T.R */ : 1 /* T.L */);
2210
+ computeCharTypes(line, from, to, isolates, outerType);
2211
+ processBracketPairs(line, from, to, isolates, outerType);
2212
+ processNeutrals(from, to, isolates, outerType);
2213
+ emitSpans(line, from, to, level, baseLevel, isolates, order);
2214
+ }
2215
+ function computeOrder(line, direction, isolates) {
2216
+ if (!line)
2217
+ return [new BidiSpan(0, 0, direction == RTL ? 1 : 0)];
2218
+ if (direction == LTR && !isolates.length && !BidiRE.test(line))
2219
+ return trivialOrder(line.length);
2220
+ if (isolates.length)
2221
+ while (line.length > types.length)
2222
+ types[types.length] = 256 /* T.NI */; // Make sure types array has no gaps
2223
+ let order = [], level = direction == LTR ? 0 : 1;
2224
+ computeSectionOrder(line, level, level, isolates, 0, line.length, order);
2225
+ return order;
2226
+ }
2227
+ function trivialOrder(length) {
2228
+ return [new BidiSpan(0, length, 0)];
2229
+ }
2230
+ let movedOver = "";
2231
+ // This implementation moves strictly visually, without concern for a
2232
+ // traversal visiting every logical position in the string. It will
2233
+ // still do so for simple input, but situations like multiple isolates
2234
+ // with the same level next to each other, or text going against the
2235
+ // main dir at the end of the line, will make some positions
2236
+ // unreachable with this motion. Each visible cursor position will
2237
+ // correspond to the lower-level bidi span that touches it.
2238
+ //
2239
+ // The alternative would be to solve an order globally for a given
2240
+ // line, making sure that it includes every position, but that would
2241
+ // require associating non-canonical (higher bidi span level)
2242
+ // positions with a given visual position, which is likely to confuse
2243
+ // people. (And would generally be a lot more complicated.)
2244
+ function moveVisually(line, order, dir, start, forward) {
2245
+ var _a;
2246
+ let startIndex = start.head - line.from;
2247
+ let spanI = BidiSpan.find(order, startIndex, (_a = start.bidiLevel) !== null && _a !== void 0 ? _a : -1, start.assoc);
2248
+ let span = order[spanI], spanEnd = span.side(forward, dir);
2249
+ // End of span
2250
+ if (startIndex == spanEnd) {
2251
+ let nextI = spanI += forward ? 1 : -1;
2252
+ if (nextI < 0 || nextI >= order.length)
2253
+ return null;
2254
+ span = order[spanI = nextI];
2255
+ startIndex = span.side(!forward, dir);
2256
+ spanEnd = span.side(forward, dir);
2257
+ }
2258
+ let nextIndex = state.findClusterBreak(line.text, startIndex, span.forward(forward, dir));
2259
+ if (nextIndex < span.from || nextIndex > span.to)
2260
+ nextIndex = spanEnd;
2261
+ movedOver = line.text.slice(Math.min(startIndex, nextIndex), Math.max(startIndex, nextIndex));
2262
+ let nextSpan = spanI == (forward ? order.length - 1 : 0) ? null : order[spanI + (forward ? 1 : -1)];
2263
+ if (nextSpan && nextIndex == spanEnd && nextSpan.level + (forward ? 0 : 1) < span.level)
2264
+ return state.EditorSelection.cursor(nextSpan.side(!forward, dir) + line.from, nextSpan.forward(forward, dir) ? 1 : -1, nextSpan.level);
2265
+ return state.EditorSelection.cursor(nextIndex + line.from, span.forward(forward, dir) ? -1 : 1, span.level);
2266
+ }
2267
+ function autoDirection(text, from, to) {
2268
+ for (let i = from; i < to; i++) {
2269
+ let type = charType(text.charCodeAt(i));
2270
+ if (type == 1 /* T.L */)
2271
+ return LTR;
2272
+ if (type == 2 /* T.R */ || type == 4 /* T.AL */)
2273
+ return RTL;
2274
+ }
2275
+ return LTR;
2276
+ }
2277
+
2278
+ const clickAddsSelectionRange = state.Facet.define();
2279
+ const dragMovesSelection$1 = state.Facet.define();
2280
+ const mouseSelectionStyle = state.Facet.define();
2281
+ const exceptionSink = state.Facet.define();
2282
+ const updateListener = state.Facet.define();
2283
+ const inputHandler = state.Facet.define();
2284
+ const focusChangeEffect = state.Facet.define();
2285
+ const perLineTextDirection = state.Facet.define({
2286
+ combine: values => values.some(x => x)
2287
+ });
2288
+ const nativeSelectionHidden = state.Facet.define({
2289
+ combine: values => values.some(x => x)
2290
+ });
2291
+ class ScrollTarget {
2292
+ constructor(range, y = "nearest", x = "nearest", yMargin = 5, xMargin = 5,
2293
+ // This data structure is abused to also store precise scroll
2294
+ // snapshots, instead of a `scrollIntoView` request. When this
2295
+ // flag is `true`, `range` points at a position in the reference
2296
+ // line, `yMargin` holds the difference between the top of that
2297
+ // line and the top of the editor, and `xMargin` holds the
2298
+ // editor's `scrollLeft`.
2299
+ isSnapshot = false) {
2300
+ this.range = range;
2301
+ this.y = y;
2302
+ this.x = x;
2303
+ this.yMargin = yMargin;
2304
+ this.xMargin = xMargin;
2305
+ this.isSnapshot = isSnapshot;
2306
+ }
2307
+ map(changes) {
2308
+ return changes.empty ? this :
2309
+ new ScrollTarget(this.range.map(changes), this.y, this.x, this.yMargin, this.xMargin, this.isSnapshot);
2310
+ }
2311
+ clip(state$1) {
2312
+ return this.range.to <= state$1.doc.length ? this :
2313
+ new ScrollTarget(state.EditorSelection.cursor(state$1.doc.length), this.y, this.x, this.yMargin, this.xMargin, this.isSnapshot);
2314
+ }
2315
+ }
2316
+ const scrollIntoView = state.StateEffect.define({ map: (t, ch) => t.map(ch) });
2317
+ /**
2318
+ Log or report an unhandled exception in client code. Should
2319
+ probably only be used by extension code that allows client code to
2320
+ provide functions, and calls those functions in a context where an
2321
+ exception can't be propagated to calling code in a reasonable way
2322
+ (for example when in an event handler).
2323
+
2324
+ Either calls a handler registered with
2325
+ [`EditorView.exceptionSink`](https://codemirror.net/6/docs/ref/#view.EditorView^exceptionSink),
2326
+ `window.onerror`, if defined, or `console.error` (in which case
2327
+ it'll pass `context`, when given, as first argument).
2328
+ */
2329
+ function logException(state, exception, context) {
2330
+ let handler = state.facet(exceptionSink);
2331
+ if (handler.length)
2332
+ handler[0](exception);
2333
+ else if (window.onerror)
2334
+ window.onerror(String(exception), context, undefined, undefined, exception);
2335
+ else if (context)
2336
+ console.error(context + ":", exception);
2337
+ else
2338
+ console.error(exception);
2339
+ }
2340
+ const editable = state.Facet.define({ combine: values => values.length ? values[0] : true });
2341
+ let nextPluginID = 0;
2342
+ const viewPlugin = state.Facet.define();
2343
+ /**
2344
+ View plugins associate stateful values with a view. They can
2345
+ influence the way the content is drawn, and are notified of things
2346
+ that happen in the view.
2347
+ */
2348
+ class ViewPlugin {
2349
+ constructor(
2350
+ /**
2351
+ @internal
2352
+ */
2353
+ id,
2354
+ /**
2355
+ @internal
2356
+ */
2357
+ create,
2358
+ /**
2359
+ @internal
2360
+ */
2361
+ domEventHandlers,
2362
+ /**
2363
+ @internal
2364
+ */
2365
+ domEventObservers, buildExtensions) {
2366
+ this.id = id;
2367
+ this.create = create;
2368
+ this.domEventHandlers = domEventHandlers;
2369
+ this.domEventObservers = domEventObservers;
2370
+ this.extension = buildExtensions(this);
2371
+ }
2372
+ /**
2373
+ Define a plugin from a constructor function that creates the
2374
+ plugin's value, given an editor view.
2375
+ */
2376
+ static define(create, spec) {
2377
+ const { eventHandlers, eventObservers, provide, decorations: deco } = spec || {};
2378
+ return new ViewPlugin(nextPluginID++, create, eventHandlers, eventObservers, plugin => {
2379
+ let ext = [viewPlugin.of(plugin)];
2380
+ if (deco)
2381
+ ext.push(decorations.of(view => {
2382
+ let pluginInst = view.plugin(plugin);
2383
+ return pluginInst ? deco(pluginInst) : Decoration.none;
2384
+ }));
2385
+ if (provide)
2386
+ ext.push(provide(plugin));
2387
+ return ext;
2388
+ });
2389
+ }
2390
+ /**
2391
+ Create a plugin for a class whose constructor takes a single
2392
+ editor view as argument.
2393
+ */
2394
+ static fromClass(cls, spec) {
2395
+ return ViewPlugin.define(view => new cls(view), spec);
2396
+ }
2397
+ }
2398
+ class PluginInstance {
2399
+ constructor(spec) {
2400
+ this.spec = spec;
2401
+ // When starting an update, all plugins have this field set to the
2402
+ // update object, indicating they need to be updated. When finished
2403
+ // updating, it is set to `false`. Retrieving a plugin that needs to
2404
+ // be updated with `view.plugin` forces an eager update.
2405
+ this.mustUpdate = null;
2406
+ // This is null when the plugin is initially created, but
2407
+ // initialized on the first update.
2408
+ this.value = null;
2409
+ }
2410
+ update(view) {
2411
+ if (!this.value) {
2412
+ if (this.spec) {
2413
+ try {
2414
+ this.value = this.spec.create(view);
2415
+ }
2416
+ catch (e) {
2417
+ logException(view.state, e, "CodeMirror plugin crashed");
2418
+ this.deactivate();
2419
+ }
2420
+ }
2421
+ }
2422
+ else if (this.mustUpdate) {
2423
+ let update = this.mustUpdate;
2424
+ this.mustUpdate = null;
2425
+ if (this.value.update) {
2426
+ try {
2427
+ this.value.update(update);
2428
+ }
2429
+ catch (e) {
2430
+ logException(update.state, e, "CodeMirror plugin crashed");
2431
+ if (this.value.destroy)
2432
+ try {
2433
+ this.value.destroy();
2434
+ }
2435
+ catch (_) { }
2436
+ this.deactivate();
2437
+ }
2438
+ }
2439
+ }
2440
+ return this;
2441
+ }
2442
+ destroy(view) {
2443
+ var _a;
2444
+ if ((_a = this.value) === null || _a === void 0 ? void 0 : _a.destroy) {
2445
+ try {
2446
+ this.value.destroy();
2447
+ }
2448
+ catch (e) {
2449
+ logException(view.state, e, "CodeMirror plugin crashed");
2450
+ }
2451
+ }
2452
+ }
2453
+ deactivate() {
2454
+ this.spec = this.value = null;
2455
+ }
2456
+ }
2457
+ const editorAttributes = state.Facet.define();
2458
+ const contentAttributes = state.Facet.define();
2459
+ // Provide decorations
2460
+ const decorations = state.Facet.define();
2461
+ const outerDecorations = state.Facet.define();
2462
+ const atomicRanges = state.Facet.define();
2463
+ const bidiIsolatedRanges = state.Facet.define();
2464
+ function getIsolatedRanges(view, line) {
2465
+ let isolates = view.state.facet(bidiIsolatedRanges);
2466
+ if (!isolates.length)
2467
+ return isolates;
2468
+ let sets = isolates.map(i => i instanceof Function ? i(view) : i);
2469
+ let result = [];
2470
+ state.RangeSet.spans(sets, line.from, line.to, {
2471
+ point() { },
2472
+ span(fromDoc, toDoc, active, open) {
2473
+ let from = fromDoc - line.from, to = toDoc - line.from;
2474
+ let level = result;
2475
+ for (let i = active.length - 1; i >= 0; i--, open--) {
2476
+ let direction = active[i].spec.bidiIsolate, update;
2477
+ if (direction == null)
2478
+ direction = autoDirection(line.text, from, to);
2479
+ if (open > 0 && level.length &&
2480
+ (update = level[level.length - 1]).to == from && update.direction == direction) {
2481
+ update.to = to;
2482
+ level = update.inner;
2483
+ }
2484
+ else {
2485
+ let add = { from, to, direction, inner: [] };
2486
+ level.push(add);
2487
+ level = add.inner;
2497
2488
  }
2498
2489
  }
2499
- if (recurse)
2500
- emitSpans(line, iCh, iScan, level + 1, baseLevel, recurse, order);
2501
- else if (iCh < iScan)
2502
- order.push(new BidiSpan(iCh, iScan, localLevel));
2503
- iCh = iScan;
2490
+ }
2491
+ });
2492
+ return result;
2493
+ }
2494
+ const scrollMargins = state.Facet.define();
2495
+ function getScrollMargins(view) {
2496
+ let left = 0, right = 0, top = 0, bottom = 0;
2497
+ for (let source of view.state.facet(scrollMargins)) {
2498
+ let m = source(view);
2499
+ if (m) {
2500
+ if (m.left != null)
2501
+ left = Math.max(left, m.left);
2502
+ if (m.right != null)
2503
+ right = Math.max(right, m.right);
2504
+ if (m.top != null)
2505
+ top = Math.max(top, m.top);
2506
+ if (m.bottom != null)
2507
+ bottom = Math.max(bottom, m.bottom);
2504
2508
  }
2505
2509
  }
2506
- else {
2507
- // Iterate in reverse to flip the span order. Same code again, but
2508
- // going from the back of the section to the front
2509
- for (let iCh = to, iI = isolates.length; iCh > from;) {
2510
- let sameDir = true, isNum = false;
2511
- if (!iI || iCh > isolates[iI - 1].to) {
2512
- let next = types[iCh - 1];
2513
- if (next != ourType) {
2514
- sameDir = false;
2515
- isNum = next == 16 /* T.AN */;
2516
- }
2517
- }
2518
- let recurse = !sameDir && ourType == 1 /* T.L */ ? [] : null;
2519
- let localLevel = sameDir ? level : level + 1;
2520
- let iScan = iCh;
2521
- run: for (;;) {
2522
- if (iI && iScan == isolates[iI - 1].to) {
2523
- if (isNum)
2524
- break run;
2525
- let iso = isolates[--iI];
2526
- // Scan ahead to verify that there is another char in this dir after the isolate(s)
2527
- if (!sameDir)
2528
- for (let upto = iso.from, jI = iI;;) {
2529
- if (upto == from)
2530
- break run;
2531
- if (jI && isolates[jI - 1].to == upto)
2532
- upto = isolates[--jI].from;
2533
- else if (types[upto - 1] == ourType)
2534
- break run;
2535
- else
2536
- break;
2537
- }
2538
- if (recurse) {
2539
- recurse.push(iso);
2540
- }
2541
- else {
2542
- if (iso.to < iCh)
2543
- order.push(new BidiSpan(iso.to, iCh, localLevel));
2544
- let dirSwap = (iso.direction == LTR) != !(localLevel % 2);
2545
- computeSectionOrder(line, dirSwap ? level + 1 : level, baseLevel, iso.inner, iso.from, iso.to, order);
2546
- iCh = iso.from;
2547
- }
2548
- iScan = iso.from;
2549
- }
2550
- else if (iScan == from || (sameDir ? types[iScan - 1] != ourType : types[iScan - 1] == ourType)) {
2510
+ return { left, right, top, bottom };
2511
+ }
2512
+ const styleModule = state.Facet.define();
2513
+ class ChangedRange {
2514
+ constructor(fromA, toA, fromB, toB) {
2515
+ this.fromA = fromA;
2516
+ this.toA = toA;
2517
+ this.fromB = fromB;
2518
+ this.toB = toB;
2519
+ }
2520
+ join(other) {
2521
+ return new ChangedRange(Math.min(this.fromA, other.fromA), Math.max(this.toA, other.toA), Math.min(this.fromB, other.fromB), Math.max(this.toB, other.toB));
2522
+ }
2523
+ addToSet(set) {
2524
+ let i = set.length, me = this;
2525
+ for (; i > 0; i--) {
2526
+ let range = set[i - 1];
2527
+ if (range.fromA > me.toA)
2528
+ continue;
2529
+ if (range.toA < me.fromA)
2530
+ break;
2531
+ me = me.join(range);
2532
+ set.splice(i - 1, 1);
2533
+ }
2534
+ set.splice(i, 0, me);
2535
+ return set;
2536
+ }
2537
+ static extendWithRanges(diff, ranges) {
2538
+ if (ranges.length == 0)
2539
+ return diff;
2540
+ let result = [];
2541
+ for (let dI = 0, rI = 0, posA = 0, posB = 0;; dI++) {
2542
+ let next = dI == diff.length ? null : diff[dI], off = posA - posB;
2543
+ let end = next ? next.fromB : 1e9;
2544
+ while (rI < ranges.length && ranges[rI] < end) {
2545
+ let from = ranges[rI], to = ranges[rI + 1];
2546
+ let fromB = Math.max(posB, from), toB = Math.min(end, to);
2547
+ if (fromB <= toB)
2548
+ new ChangedRange(fromB + off, toB + off, fromB, toB).addToSet(result);
2549
+ if (to > end)
2551
2550
  break;
2552
- }
2553
- else {
2554
- iScan--;
2555
- }
2551
+ else
2552
+ rI += 2;
2556
2553
  }
2557
- if (recurse)
2558
- emitSpans(line, iScan, iCh, level + 1, baseLevel, recurse, order);
2559
- else if (iScan < iCh)
2560
- order.push(new BidiSpan(iScan, iCh, localLevel));
2561
- iCh = iScan;
2554
+ if (!next)
2555
+ return result;
2556
+ new ChangedRange(next.fromA, next.toA, next.fromB, next.toB).addToSet(result);
2557
+ posA = next.toA;
2558
+ posB = next.toB;
2562
2559
  }
2563
2560
  }
2564
2561
  }
2565
- function computeSectionOrder(line, level, baseLevel, isolates, from, to, order) {
2566
- let outerType = (level % 2 ? 2 /* T.R */ : 1 /* T.L */);
2567
- computeCharTypes(line, from, to, isolates, outerType);
2568
- processBracketPairs(line, from, to, isolates, outerType);
2569
- processNeutrals(from, to, isolates, outerType);
2570
- emitSpans(line, from, to, level, baseLevel, isolates, order);
2571
- }
2572
- function computeOrder(line, direction, isolates) {
2573
- if (!line)
2574
- return [new BidiSpan(0, 0, direction == RTL ? 1 : 0)];
2575
- if (direction == LTR && !isolates.length && !BidiRE.test(line))
2576
- return trivialOrder(line.length);
2577
- if (isolates.length)
2578
- while (line.length > types.length)
2579
- types[types.length] = 256 /* T.NI */; // Make sure types array has no gaps
2580
- let order = [], level = direction == LTR ? 0 : 1;
2581
- computeSectionOrder(line, level, level, isolates, 0, line.length, order);
2582
- return order;
2583
- }
2584
- function trivialOrder(length) {
2585
- return [new BidiSpan(0, length, 0)];
2586
- }
2587
- let movedOver = "";
2588
- function moveVisually(line, order, dir, start, forward) {
2589
- var _a;
2590
- let startIndex = start.head - line.from, spanI = -1;
2591
- if (startIndex == 0) {
2592
- if (!forward || !line.length)
2593
- return null;
2594
- if (order[0].level != dir) {
2595
- startIndex = order[0].side(false, dir);
2596
- spanI = 0;
2597
- }
2562
+ /**
2563
+ View [plugins](https://codemirror.net/6/docs/ref/#view.ViewPlugin) are given instances of this
2564
+ class, which describe what happened, whenever the view is updated.
2565
+ */
2566
+ class ViewUpdate {
2567
+ constructor(
2568
+ /**
2569
+ The editor view that the update is associated with.
2570
+ */
2571
+ view,
2572
+ /**
2573
+ The new editor state.
2574
+ */
2575
+ state$1,
2576
+ /**
2577
+ The transactions involved in the update. May be empty.
2578
+ */
2579
+ transactions) {
2580
+ this.view = view;
2581
+ this.state = state$1;
2582
+ this.transactions = transactions;
2583
+ /**
2584
+ @internal
2585
+ */
2586
+ this.flags = 0;
2587
+ this.startState = view.state;
2588
+ this.changes = state.ChangeSet.empty(this.startState.doc.length);
2589
+ for (let tr of transactions)
2590
+ this.changes = this.changes.compose(tr.changes);
2591
+ let changedRanges = [];
2592
+ this.changes.iterChangedRanges((fromA, toA, fromB, toB) => changedRanges.push(new ChangedRange(fromA, toA, fromB, toB)));
2593
+ this.changedRanges = changedRanges;
2598
2594
  }
2599
- else if (startIndex == line.length) {
2600
- if (forward)
2601
- return null;
2602
- let last = order[order.length - 1];
2603
- if (last.level != dir) {
2604
- startIndex = last.side(true, dir);
2605
- spanI = order.length - 1;
2606
- }
2607
- }
2608
- if (spanI < 0)
2609
- spanI = BidiSpan.find(order, startIndex, (_a = start.bidiLevel) !== null && _a !== void 0 ? _a : -1, start.assoc);
2610
- let span = order[spanI];
2611
- // End of span. (But not end of line--that was checked for above.)
2612
- if (startIndex == span.side(forward, dir)) {
2613
- span = order[spanI += forward ? 1 : -1];
2614
- startIndex = span.side(!forward, dir);
2595
+ /**
2596
+ @internal
2597
+ */
2598
+ static create(view, state, transactions) {
2599
+ return new ViewUpdate(view, state, transactions);
2615
2600
  }
2616
- let indexForward = forward == (span.dir == dir);
2617
- let nextIndex = state.findClusterBreak(line.text, startIndex, indexForward);
2618
- movedOver = line.text.slice(Math.min(startIndex, nextIndex), Math.max(startIndex, nextIndex));
2619
- if (nextIndex > span.from && nextIndex < span.to)
2620
- return state.EditorSelection.cursor(nextIndex + line.from, indexForward ? -1 : 1, span.level);
2621
- let nextSpan = spanI == (forward ? order.length - 1 : 0) ? null : order[spanI + (forward ? 1 : -1)];
2622
- if (!nextSpan && span.level != dir)
2623
- return state.EditorSelection.cursor(forward ? line.to : line.from, forward ? -1 : 1, dir);
2624
- if (nextSpan && nextSpan.level < span.level)
2625
- return state.EditorSelection.cursor(nextSpan.side(!forward, dir) + line.from, forward ? 1 : -1, nextSpan.level);
2626
- return state.EditorSelection.cursor(nextIndex + line.from, forward ? -1 : 1, span.level);
2601
+ /**
2602
+ Tells you whether the [viewport](https://codemirror.net/6/docs/ref/#view.EditorView.viewport) or
2603
+ [visible ranges](https://codemirror.net/6/docs/ref/#view.EditorView.visibleRanges) changed in this
2604
+ update.
2605
+ */
2606
+ get viewportChanged() {
2607
+ return (this.flags & 4 /* UpdateFlag.Viewport */) > 0;
2608
+ }
2609
+ /**
2610
+ Indicates whether the height of a block element in the editor
2611
+ changed in this update.
2612
+ */
2613
+ get heightChanged() {
2614
+ return (this.flags & 2 /* UpdateFlag.Height */) > 0;
2615
+ }
2616
+ /**
2617
+ Returns true when the document was modified or the size of the
2618
+ editor, or elements within the editor, changed.
2619
+ */
2620
+ get geometryChanged() {
2621
+ return this.docChanged || (this.flags & (8 /* UpdateFlag.Geometry */ | 2 /* UpdateFlag.Height */)) > 0;
2622
+ }
2623
+ /**
2624
+ True when this update indicates a focus change.
2625
+ */
2626
+ get focusChanged() {
2627
+ return (this.flags & 1 /* UpdateFlag.Focus */) > 0;
2628
+ }
2629
+ /**
2630
+ Whether the document changed in this update.
2631
+ */
2632
+ get docChanged() {
2633
+ return !this.changes.empty;
2634
+ }
2635
+ /**
2636
+ Whether the selection was explicitly set in this update.
2637
+ */
2638
+ get selectionSet() {
2639
+ return this.transactions.some(tr => tr.selection);
2640
+ }
2641
+ /**
2642
+ @internal
2643
+ */
2644
+ get empty() { return this.flags == 0 && this.transactions.length == 0; }
2627
2645
  }
2628
2646
 
2629
2647
  class DocView extends ContentView {
@@ -2833,9 +2851,8 @@ class DocView extends ContentView {
2833
2851
  }
2834
2852
  let domSel = this.view.observer.selectionRange;
2835
2853
  // If the selection is already here, or in an equivalent position, don't touch it
2836
- if (force || !domSel.focusNode ||
2837
- !isEquivalentPosition(anchor.node, anchor.offset, domSel.anchorNode, domSel.anchorOffset) ||
2838
- !isEquivalentPosition(head.node, head.offset, domSel.focusNode, domSel.focusOffset)) {
2854
+ if (force || !domSel.focusNode || (!isEquivalentPosition(anchor.node, anchor.offset, domSel.anchorNode, domSel.anchorOffset) ||
2855
+ !isEquivalentPosition(head.node, head.offset, domSel.focusNode, domSel.focusOffset)) && !this.suppressWidgetCursorChange(domSel, main)) {
2839
2856
  this.view.observer.ignore(() => {
2840
2857
  // Chrome Android will hide the virtual keyboard when tapping
2841
2858
  // inside an uneditable node, and not bring it back when we
@@ -2896,6 +2913,14 @@ class DocView extends ContentView {
2896
2913
  this.impreciseAnchor = anchor.precise ? null : new DOMPos(domSel.anchorNode, domSel.anchorOffset);
2897
2914
  this.impreciseHead = head.precise ? null : new DOMPos(domSel.focusNode, domSel.focusOffset);
2898
2915
  }
2916
+ // If a zero-length widget is inserted next to the cursor during
2917
+ // composition, avoid moving it across it and disrupting the
2918
+ // composition.
2919
+ suppressWidgetCursorChange(sel, cursor) {
2920
+ return this.hasComposition && cursor.empty &&
2921
+ isEquivalentPosition(sel.focusNode, sel.focusOffset, sel.anchorNode, sel.anchorOffset) &&
2922
+ this.posFromDOM(sel.focusNode, sel.focusOffset) == cursor.head;
2923
+ }
2899
2924
  enforceCursorAssoc() {
2900
2925
  if (this.hasComposition)
2901
2926
  return;
@@ -3104,6 +3129,16 @@ class DocView extends ContentView {
3104
3129
  let dynamic = this.dynamicDecorationMap[i] = typeof d == "function";
3105
3130
  return dynamic ? d(this.view) : d;
3106
3131
  });
3132
+ let dynamicOuter = false, outerDeco = this.view.state.facet(outerDecorations).map((d, i) => {
3133
+ let dynamic = typeof d == "function";
3134
+ if (dynamic)
3135
+ dynamicOuter = true;
3136
+ return dynamic ? d(this.view) : d;
3137
+ });
3138
+ if (outerDeco.length) {
3139
+ this.dynamicDecorationMap[allDeco.length] = dynamicOuter;
3140
+ allDeco.push(state.RangeSet.join(outerDeco));
3141
+ }
3107
3142
  for (let i = allDeco.length; i < allDeco.length + 3; i++)
3108
3143
  this.dynamicDecorationMap[i] = false;
3109
3144
  return this.decorations = [
@@ -3147,6 +3182,7 @@ class BlockGapWidget extends WidgetType {
3147
3182
  }
3148
3183
  toDOM() {
3149
3184
  let elt = document.createElement("div");
3185
+ elt.className = "cm-gap";
3150
3186
  this.updateDOM(elt);
3151
3187
  return elt;
3152
3188
  }
@@ -3155,6 +3191,7 @@ class BlockGapWidget extends WidgetType {
3155
3191
  elt.style.height = this.height + "px";
3156
3192
  return true;
3157
3193
  }
3194
+ get editable() { return true; }
3158
3195
  get estimatedHeight() { return this.height; }
3159
3196
  }
3160
3197
  function findCompositionNode(view, headPos) {
@@ -3551,7 +3588,7 @@ function moveByChar(view, start, forward, by) {
3551
3588
  char = "\n";
3552
3589
  line = view.state.doc.line(line.number + (forward ? 1 : -1));
3553
3590
  spans = view.bidiSpans(line);
3554
- next = state.EditorSelection.cursor(forward ? line.from : line.to);
3591
+ next = view.visualLineSide(line, !forward);
3555
3592
  }
3556
3593
  if (!check) {
3557
3594
  if (!by)
@@ -3956,8 +3993,7 @@ class MouseSelection {
3956
3993
  }
3957
3994
  select(event) {
3958
3995
  let { view } = this, selection = this.skipAtoms(this.style.get(event, this.extend, this.multiple));
3959
- if (this.mustSelect || !selection.eq(view.state.selection) ||
3960
- selection.main.assoc != view.state.selection.main.assoc && this.dragging === false)
3996
+ if (this.mustSelect || !selection.eq(view.state.selection, this.dragging === false))
3961
3997
  this.view.dispatch({
3962
3998
  selection,
3963
3999
  userEvent: "select.pointer"
@@ -5886,6 +5922,9 @@ const baseTheme$1 = buildTheme("." + baseThemeID, {
5886
5922
  "&.cm-focused > .cm-scroller > .cm-cursorLayer .cm-cursor": {
5887
5923
  display: "block"
5888
5924
  },
5925
+ ".cm-iso": {
5926
+ unicodeBidi: "isolate"
5927
+ },
5889
5928
  ".cm-announced": {
5890
5929
  position: "fixed",
5891
5930
  top: "-10000px"
@@ -6169,6 +6208,16 @@ class DOMChange {
6169
6208
  !contains(view.contentDOM, domSel.anchorNode)
6170
6209
  ? view.state.selection.main.anchor
6171
6210
  : view.docView.posFromDOM(domSel.anchorNode, domSel.anchorOffset);
6211
+ // iOS will refuse to select the block gaps when doing select-all
6212
+ let vp = view.viewport;
6213
+ if (browser.ios && view.state.selection.main.empty && head != anchor &&
6214
+ (vp.from > 0 || vp.to < view.state.doc.length)) {
6215
+ let offFrom = vp.from - Math.min(head, anchor), offTo = vp.to - Math.max(head, anchor);
6216
+ if ((offFrom == 0 || offFrom == 1) && (offTo == 0 || offTo == -1)) {
6217
+ head = 0;
6218
+ anchor = view.state.doc.length;
6219
+ }
6220
+ }
6172
6221
  this.newSel = state.EditorSelection.single(anchor, head);
6173
6222
  }
6174
6223
  }
@@ -7458,6 +7507,17 @@ class EditorView {
7458
7507
  return skipAtoms(this, start, moveByChar(this, start, forward, initial => byGroup(this, start.head, initial)));
7459
7508
  }
7460
7509
  /**
7510
+ Get the cursor position visually at the start or end of a line.
7511
+ Note that this may differ from the _logical_ position at its
7512
+ start or end (which is simply at `line.from`/`line.to`) if text
7513
+ at the start or end goes against the line's base text direction.
7514
+ */
7515
+ visualLineSide(line, end) {
7516
+ let order = this.bidiSpans(line), dir = this.textDirectionAt(line.from);
7517
+ let span = order[end ? order.length - 1 : 0];
7518
+ return state.EditorSelection.cursor(span.side(end, dir) + line.from, span.forward(!end, dir) ? 1 : -1);
7519
+ }
7520
+ /**
7461
7521
  Move to the next line boundary in the given direction. If
7462
7522
  `includeWrap` is true, line wrapping is on, and there is a
7463
7523
  further wrap point on the current line, the wrap point will be
@@ -7589,11 +7649,11 @@ class EditorView {
7589
7649
  let dir = this.textDirectionAt(line.from), isolates;
7590
7650
  for (let entry of this.bidiCache) {
7591
7651
  if (entry.from == line.from && entry.dir == dir &&
7592
- (entry.fresh || isolatesEq(entry.isolates, isolates = getIsolatedRanges(this, line.from, line.to))))
7652
+ (entry.fresh || isolatesEq(entry.isolates, isolates = getIsolatedRanges(this, line))))
7593
7653
  return entry.order;
7594
7654
  }
7595
7655
  if (!isolates)
7596
- isolates = getIsolatedRanges(this, line.from, line.to);
7656
+ isolates = getIsolatedRanges(this, line);
7597
7657
  let order = computeOrder(line.text, dir, isolates);
7598
7658
  this.bidiCache.push(new CachedOrder(line.from, line.to, dir, isolates, true, order));
7599
7659
  return order;
@@ -7838,6 +7898,16 @@ containing the decorations to
7838
7898
  */
7839
7899
  EditorView.decorations = decorations;
7840
7900
  /**
7901
+ Facet that works much like
7902
+ [`decorations`](https://codemirror.net/6/docs/ref/#view.EditorView^decorations), but puts its
7903
+ inputs at the very bottom of the precedence stack, meaning mark
7904
+ decorations provided here will only be split by other, partially
7905
+ overlapping \`outerDecorations\` ranges, and wrap around all
7906
+ regular decorations. Use this for mark elements that should, as
7907
+ much as possible, remain in one piece.
7908
+ */
7909
+ EditorView.outerDecorations = outerDecorations;
7910
+ /**
7841
7911
  Used to provide ranges that should be treated as atoms as far as
7842
7912
  cursor motion is concerned. This causes methods like
7843
7913
  [`moveByChar`](https://codemirror.net/6/docs/ref/#view.EditorView.moveByChar) and