@harbour-enterprises/superdoc 1.6.0-next.1 → 1.6.0-next.2
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/chunks/{PdfViewer-Dr4K1JKD.cjs → PdfViewer-D_YseVgi.cjs} +2 -2
- package/dist/chunks/{PdfViewer-DzppMlfu.es.js → PdfViewer-Djd4zd7C.es.js} +2 -2
- package/dist/chunks/{SuperConverter-Cyn9peRO.es.js → SuperConverter-BAUfsE-s.es.js} +1 -1
- package/dist/chunks/{SuperConverter-DpKjVrPl.cjs → SuperConverter-DrhNM5Cd.cjs} +1 -1
- package/dist/chunks/{index-CmZ15rIJ.cjs → index-CyiEB9wO.cjs} +4 -4
- package/dist/chunks/{index-Cto-XsBE.cjs → index-D-7HfDnq.cjs} +636 -54
- package/dist/chunks/{index-DrcLOCfC.es.js → index-ajHpG3f-.es.js} +4 -4
- package/dist/chunks/{index-C7KECpDt.es.js → index-fbohTSaQ.es.js} +636 -54
- package/dist/super-editor/converter.cjs +1 -1
- package/dist/super-editor/converter.es.js +1 -1
- package/dist/super-editor.cjs +2 -2
- package/dist/super-editor.es.js +3 -3
- package/dist/superdoc/src/dev/components/sidebar/SidebarSearch.vue.d.ts +5 -0
- package/dist/superdoc/src/dev/components/sidebar/SidebarSearch.vue.d.ts.map +1 -0
- package/dist/superdoc.cjs +3 -3
- package/dist/superdoc.es.js +3 -3
- package/dist/superdoc.umd.js +637 -55
- package/dist/superdoc.umd.js.map +1 -1
- package/package.json +3 -3
package/dist/superdoc.umd.js
CHANGED
|
@@ -38097,7 +38097,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
38097
38097
|
static getStoredSuperdocVersion(docx) {
|
|
38098
38098
|
return SuperConverter.getStoredCustomProperty(docx, "SuperdocVersion");
|
|
38099
38099
|
}
|
|
38100
|
-
static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.6.0-next.
|
|
38100
|
+
static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.6.0-next.2") {
|
|
38101
38101
|
return SuperConverter.setStoredCustomProperty(docx, "SuperdocVersion", version2, false);
|
|
38102
38102
|
}
|
|
38103
38103
|
/**
|
|
@@ -47391,6 +47391,158 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
47391
47391
|
return Object.fromEntries(markEntries);
|
|
47392
47392
|
}
|
|
47393
47393
|
};
|
|
47394
|
+
const positionTrackerKey = new PluginKey("positionTracker");
|
|
47395
|
+
function createPositionTrackerPlugin() {
|
|
47396
|
+
return new Plugin({
|
|
47397
|
+
key: positionTrackerKey,
|
|
47398
|
+
state: {
|
|
47399
|
+
init() {
|
|
47400
|
+
return {
|
|
47401
|
+
decorations: DecorationSet.empty,
|
|
47402
|
+
generation: 0
|
|
47403
|
+
};
|
|
47404
|
+
},
|
|
47405
|
+
apply(tr, state) {
|
|
47406
|
+
let { decorations, generation } = state;
|
|
47407
|
+
const meta2 = tr.getMeta(positionTrackerKey);
|
|
47408
|
+
if (meta2?.action === "add") {
|
|
47409
|
+
decorations = decorations.add(tr.doc, meta2.decorations);
|
|
47410
|
+
} else if (meta2?.action === "remove") {
|
|
47411
|
+
const toRemove = decorations.find().filter((decoration) => meta2.ids.includes(decoration.spec.id));
|
|
47412
|
+
decorations = decorations.remove(toRemove);
|
|
47413
|
+
} else if (meta2?.action === "removeByType") {
|
|
47414
|
+
const toRemove = decorations.find().filter((decoration) => decoration.spec.type === meta2.type);
|
|
47415
|
+
decorations = decorations.remove(toRemove);
|
|
47416
|
+
}
|
|
47417
|
+
if (tr.docChanged) {
|
|
47418
|
+
decorations = decorations.map(tr.mapping, tr.doc);
|
|
47419
|
+
generation += 1;
|
|
47420
|
+
}
|
|
47421
|
+
return { decorations, generation };
|
|
47422
|
+
}
|
|
47423
|
+
},
|
|
47424
|
+
props: {
|
|
47425
|
+
decorations() {
|
|
47426
|
+
return DecorationSet.empty;
|
|
47427
|
+
}
|
|
47428
|
+
}
|
|
47429
|
+
});
|
|
47430
|
+
}
|
|
47431
|
+
class PositionTracker {
|
|
47432
|
+
#editor;
|
|
47433
|
+
constructor(editor) {
|
|
47434
|
+
this.#editor = editor;
|
|
47435
|
+
}
|
|
47436
|
+
#getState() {
|
|
47437
|
+
if (!this.#editor?.state) return null;
|
|
47438
|
+
return positionTrackerKey.getState(this.#editor.state) ?? null;
|
|
47439
|
+
}
|
|
47440
|
+
track(from2, to, spec) {
|
|
47441
|
+
const id = v4();
|
|
47442
|
+
if (!this.#editor?.state) return id;
|
|
47443
|
+
const fullSpec = { kind: "range", ...spec, id };
|
|
47444
|
+
const deco = Decoration.inline(from2, to, {}, fullSpec);
|
|
47445
|
+
const tr = this.#editor.state.tr.setMeta(positionTrackerKey, {
|
|
47446
|
+
action: "add",
|
|
47447
|
+
decorations: [deco]
|
|
47448
|
+
}).setMeta("addToHistory", false);
|
|
47449
|
+
this.#editor.dispatch(tr);
|
|
47450
|
+
return id;
|
|
47451
|
+
}
|
|
47452
|
+
trackMany(ranges) {
|
|
47453
|
+
if (!this.#editor?.state) {
|
|
47454
|
+
return ranges.map(() => v4());
|
|
47455
|
+
}
|
|
47456
|
+
const ids = [];
|
|
47457
|
+
const decorations = [];
|
|
47458
|
+
for (const { from: from2, to, spec } of ranges) {
|
|
47459
|
+
const id = v4();
|
|
47460
|
+
ids.push(id);
|
|
47461
|
+
const fullSpec = { kind: "range", ...spec, id };
|
|
47462
|
+
decorations.push(Decoration.inline(from2, to, {}, fullSpec));
|
|
47463
|
+
}
|
|
47464
|
+
const tr = this.#editor.state.tr.setMeta(positionTrackerKey, {
|
|
47465
|
+
action: "add",
|
|
47466
|
+
decorations
|
|
47467
|
+
}).setMeta("addToHistory", false);
|
|
47468
|
+
this.#editor.dispatch(tr);
|
|
47469
|
+
return ids;
|
|
47470
|
+
}
|
|
47471
|
+
untrack(id) {
|
|
47472
|
+
if (!this.#editor?.state) return;
|
|
47473
|
+
const tr = this.#editor.state.tr.setMeta(positionTrackerKey, {
|
|
47474
|
+
action: "remove",
|
|
47475
|
+
ids: [id]
|
|
47476
|
+
}).setMeta("addToHistory", false);
|
|
47477
|
+
this.#editor.dispatch(tr);
|
|
47478
|
+
}
|
|
47479
|
+
untrackMany(ids) {
|
|
47480
|
+
if (!this.#editor?.state || ids.length === 0) return;
|
|
47481
|
+
const tr = this.#editor.state.tr.setMeta(positionTrackerKey, {
|
|
47482
|
+
action: "remove",
|
|
47483
|
+
ids
|
|
47484
|
+
}).setMeta("addToHistory", false);
|
|
47485
|
+
this.#editor.dispatch(tr);
|
|
47486
|
+
}
|
|
47487
|
+
untrackByType(type) {
|
|
47488
|
+
if (!this.#editor?.state) return;
|
|
47489
|
+
const tr = this.#editor.state.tr.setMeta(positionTrackerKey, {
|
|
47490
|
+
action: "removeByType",
|
|
47491
|
+
type
|
|
47492
|
+
}).setMeta("addToHistory", false);
|
|
47493
|
+
this.#editor.dispatch(tr);
|
|
47494
|
+
}
|
|
47495
|
+
resolve(id) {
|
|
47496
|
+
const state = this.#getState();
|
|
47497
|
+
if (!state) return null;
|
|
47498
|
+
const found2 = state.decorations.find().find((decoration) => decoration.spec.id === id);
|
|
47499
|
+
if (!found2) return null;
|
|
47500
|
+
const spec = found2.spec;
|
|
47501
|
+
return {
|
|
47502
|
+
id: spec.id,
|
|
47503
|
+
from: found2.from,
|
|
47504
|
+
to: found2.to,
|
|
47505
|
+
spec
|
|
47506
|
+
};
|
|
47507
|
+
}
|
|
47508
|
+
resolveMany(ids) {
|
|
47509
|
+
const result = /* @__PURE__ */ new Map();
|
|
47510
|
+
for (const id of ids) {
|
|
47511
|
+
result.set(id, null);
|
|
47512
|
+
}
|
|
47513
|
+
const state = this.#getState();
|
|
47514
|
+
if (!state || ids.length === 0) return result;
|
|
47515
|
+
const idSet = new Set(ids);
|
|
47516
|
+
for (const decoration of state.decorations.find()) {
|
|
47517
|
+
const spec = decoration.spec;
|
|
47518
|
+
if (idSet.has(spec.id)) {
|
|
47519
|
+
result.set(spec.id, {
|
|
47520
|
+
id: spec.id,
|
|
47521
|
+
from: decoration.from,
|
|
47522
|
+
to: decoration.to,
|
|
47523
|
+
spec
|
|
47524
|
+
});
|
|
47525
|
+
}
|
|
47526
|
+
}
|
|
47527
|
+
return result;
|
|
47528
|
+
}
|
|
47529
|
+
findByType(type) {
|
|
47530
|
+
const state = this.#getState();
|
|
47531
|
+
if (!state) return [];
|
|
47532
|
+
return state.decorations.find().filter((decoration) => decoration.spec.type === type).map((decoration) => {
|
|
47533
|
+
const spec = decoration.spec;
|
|
47534
|
+
return {
|
|
47535
|
+
id: spec.id,
|
|
47536
|
+
from: decoration.from,
|
|
47537
|
+
to: decoration.to,
|
|
47538
|
+
spec
|
|
47539
|
+
};
|
|
47540
|
+
});
|
|
47541
|
+
}
|
|
47542
|
+
get generation() {
|
|
47543
|
+
return this.#getState()?.generation ?? 0;
|
|
47544
|
+
}
|
|
47545
|
+
}
|
|
47394
47546
|
class OxmlNode extends Node$2 {
|
|
47395
47547
|
constructor(config2) {
|
|
47396
47548
|
super(config2);
|
|
@@ -49751,6 +49903,34 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
49751
49903
|
return [editorFocusPlugin];
|
|
49752
49904
|
}
|
|
49753
49905
|
});
|
|
49906
|
+
const PositionTrackerExtension = Extension.create({
|
|
49907
|
+
name: "positionTracker",
|
|
49908
|
+
addStorage() {
|
|
49909
|
+
return {
|
|
49910
|
+
tracker: null
|
|
49911
|
+
};
|
|
49912
|
+
},
|
|
49913
|
+
addPmPlugins() {
|
|
49914
|
+
return [createPositionTrackerPlugin()];
|
|
49915
|
+
},
|
|
49916
|
+
onCreate() {
|
|
49917
|
+
const existing = this.editor?.positionTracker ?? this.storage.tracker;
|
|
49918
|
+
if (existing) {
|
|
49919
|
+
this.storage.tracker = existing;
|
|
49920
|
+
this.editor.positionTracker = existing;
|
|
49921
|
+
return;
|
|
49922
|
+
}
|
|
49923
|
+
const tracker = new PositionTracker(this.editor);
|
|
49924
|
+
this.storage.tracker = tracker;
|
|
49925
|
+
this.editor.positionTracker = tracker;
|
|
49926
|
+
},
|
|
49927
|
+
onDestroy() {
|
|
49928
|
+
if (this.editor?.positionTracker === this.storage.tracker) {
|
|
49929
|
+
this.editor.positionTracker = null;
|
|
49930
|
+
}
|
|
49931
|
+
this.storage.tracker = null;
|
|
49932
|
+
}
|
|
49933
|
+
});
|
|
49754
49934
|
let EventEmitter$1 = class EventEmitter {
|
|
49755
49935
|
#events = /* @__PURE__ */ new Map();
|
|
49756
49936
|
/**
|
|
@@ -64003,7 +64183,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
64003
64183
|
return false;
|
|
64004
64184
|
}
|
|
64005
64185
|
};
|
|
64006
|
-
const summaryVersion = "1.6.0-next.
|
|
64186
|
+
const summaryVersion = "1.6.0-next.2";
|
|
64007
64187
|
const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
|
|
64008
64188
|
const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
|
|
64009
64189
|
function mapAttributes(attrs) {
|
|
@@ -65497,7 +65677,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
65497
65677
|
*/
|
|
65498
65678
|
#createExtensionService() {
|
|
65499
65679
|
const allowedExtensions = ["extension", "node", "mark"];
|
|
65500
|
-
const coreExtensions = [Editable, Commands, EditorFocus, Keymap];
|
|
65680
|
+
const coreExtensions = [Editable, Commands, EditorFocus, Keymap, PositionTrackerExtension];
|
|
65501
65681
|
const externalExtensions = this.options.externalExtensions || [];
|
|
65502
65682
|
const allExtensions = [...coreExtensions, ...this.options.extensions].filter((extension) => {
|
|
65503
65683
|
const extensionType = typeof extension?.type === "string" ? extension.type : void 0;
|
|
@@ -66671,7 +66851,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
66671
66851
|
* Process collaboration migrations
|
|
66672
66852
|
*/
|
|
66673
66853
|
processCollaborationMigrations() {
|
|
66674
|
-
console.debug("[checkVersionMigrations] Current editor version", "1.6.0-next.
|
|
66854
|
+
console.debug("[checkVersionMigrations] Current editor version", "1.6.0-next.2");
|
|
66675
66855
|
if (!this.options.ydoc) return;
|
|
66676
66856
|
const metaMap = this.options.ydoc.getMap("meta");
|
|
66677
66857
|
let docVersion = metaMap.get("version");
|
|
@@ -123801,14 +123981,317 @@ ${o}
|
|
|
123801
123981
|
let search2 = searchKey.getState(state);
|
|
123802
123982
|
return search2 ? search2.deco : DecorationSet.empty;
|
|
123803
123983
|
}
|
|
123804
|
-
|
|
123805
|
-
|
|
123806
|
-
|
|
123984
|
+
const BLOCK_SEPARATOR = "\n";
|
|
123985
|
+
const ATOM_PLACEHOLDER = "";
|
|
123986
|
+
class SearchIndex {
|
|
123987
|
+
/** @type {string} */
|
|
123988
|
+
text = "";
|
|
123989
|
+
/** @type {Segment[]} */
|
|
123990
|
+
segments = [];
|
|
123991
|
+
/** @type {boolean} */
|
|
123992
|
+
valid = false;
|
|
123993
|
+
/** @type {number} */
|
|
123994
|
+
docSize = 0;
|
|
123995
|
+
/**
|
|
123996
|
+
* Build the search index from a ProseMirror document.
|
|
123997
|
+
* Uses doc.textBetween for the flattened string and walks
|
|
123998
|
+
* the document to build the segment offset map.
|
|
123999
|
+
*
|
|
124000
|
+
* @param {import('prosemirror-model').Node} doc - The ProseMirror document
|
|
124001
|
+
*/
|
|
124002
|
+
build(doc2) {
|
|
124003
|
+
this.text = doc2.textBetween(0, doc2.content.size, BLOCK_SEPARATOR, ATOM_PLACEHOLDER);
|
|
124004
|
+
this.segments = [];
|
|
124005
|
+
this.docSize = doc2.content.size;
|
|
124006
|
+
let offset2 = 0;
|
|
124007
|
+
this.#walkNodeContent(doc2, 0, offset2, (segment) => {
|
|
124008
|
+
this.segments.push(segment);
|
|
124009
|
+
offset2 = segment.offsetEnd;
|
|
124010
|
+
});
|
|
124011
|
+
this.valid = true;
|
|
124012
|
+
}
|
|
124013
|
+
/**
|
|
124014
|
+
* Walk the content of a node to build segments.
|
|
124015
|
+
* This method processes the children of a node, given the position
|
|
124016
|
+
* where the node's content starts.
|
|
124017
|
+
*
|
|
124018
|
+
* @param {import('prosemirror-model').Node} node - Current node
|
|
124019
|
+
* @param {number} contentStart - Document position where this node's content starts
|
|
124020
|
+
* @param {number} offset - Current offset in flattened string
|
|
124021
|
+
* @param {(segment: Segment) => void} addSegment - Callback to add a segment
|
|
124022
|
+
* @returns {number} The new offset after processing this node's content
|
|
124023
|
+
*/
|
|
124024
|
+
#walkNodeContent(node2, contentStart, offset2, addSegment) {
|
|
124025
|
+
let currentOffset = offset2;
|
|
124026
|
+
let isFirstChild = true;
|
|
124027
|
+
node2.forEach((child, childContentOffset) => {
|
|
124028
|
+
const childDocPos = contentStart + childContentOffset;
|
|
124029
|
+
if (child.isBlock && !isFirstChild) {
|
|
124030
|
+
addSegment({
|
|
124031
|
+
offsetStart: currentOffset,
|
|
124032
|
+
offsetEnd: currentOffset + 1,
|
|
124033
|
+
docFrom: childDocPos,
|
|
124034
|
+
docTo: childDocPos,
|
|
124035
|
+
kind: "blockSep"
|
|
124036
|
+
});
|
|
124037
|
+
currentOffset += 1;
|
|
124038
|
+
}
|
|
124039
|
+
currentOffset = this.#walkNode(child, childDocPos, currentOffset, addSegment);
|
|
124040
|
+
isFirstChild = false;
|
|
124041
|
+
});
|
|
124042
|
+
return currentOffset;
|
|
124043
|
+
}
|
|
124044
|
+
/**
|
|
124045
|
+
* Recursively walk a node and its descendants to build segments.
|
|
124046
|
+
*
|
|
124047
|
+
* @param {import('prosemirror-model').Node} node - Current node
|
|
124048
|
+
* @param {number} docPos - Document position at start of this node
|
|
124049
|
+
* @param {number} offset - Current offset in flattened string
|
|
124050
|
+
* @param {(segment: Segment) => void} addSegment - Callback to add a segment
|
|
124051
|
+
* @returns {number} The new offset after processing this node
|
|
124052
|
+
*/
|
|
124053
|
+
#walkNode(node2, docPos, offset2, addSegment) {
|
|
124054
|
+
if (node2.isText) {
|
|
124055
|
+
const text2 = node2.text || "";
|
|
124056
|
+
if (text2.length > 0) {
|
|
124057
|
+
addSegment({
|
|
124058
|
+
offsetStart: offset2,
|
|
124059
|
+
offsetEnd: offset2 + text2.length,
|
|
124060
|
+
docFrom: docPos,
|
|
124061
|
+
docTo: docPos + text2.length,
|
|
124062
|
+
kind: "text"
|
|
124063
|
+
});
|
|
124064
|
+
return offset2 + text2.length;
|
|
124065
|
+
}
|
|
124066
|
+
return offset2;
|
|
124067
|
+
}
|
|
124068
|
+
if (node2.isLeaf) {
|
|
124069
|
+
if (node2.type.name === "hard_break") {
|
|
124070
|
+
addSegment({
|
|
124071
|
+
offsetStart: offset2,
|
|
124072
|
+
offsetEnd: offset2 + 1,
|
|
124073
|
+
docFrom: docPos,
|
|
124074
|
+
docTo: docPos + node2.nodeSize,
|
|
124075
|
+
kind: "hardBreak"
|
|
124076
|
+
});
|
|
124077
|
+
return offset2 + 1;
|
|
124078
|
+
}
|
|
124079
|
+
addSegment({
|
|
124080
|
+
offsetStart: offset2,
|
|
124081
|
+
offsetEnd: offset2 + 1,
|
|
124082
|
+
docFrom: docPos,
|
|
124083
|
+
docTo: docPos + node2.nodeSize,
|
|
124084
|
+
kind: "atom"
|
|
124085
|
+
});
|
|
124086
|
+
return offset2 + 1;
|
|
124087
|
+
}
|
|
124088
|
+
return this.#walkNodeContent(node2, docPos + 1, offset2, addSegment);
|
|
124089
|
+
}
|
|
124090
|
+
/**
|
|
124091
|
+
* Mark the index as stale. It will be rebuilt on next search.
|
|
124092
|
+
*/
|
|
124093
|
+
invalidate() {
|
|
124094
|
+
this.valid = false;
|
|
124095
|
+
}
|
|
124096
|
+
/**
|
|
124097
|
+
* Check if the index needs rebuilding for the given document.
|
|
124098
|
+
*
|
|
124099
|
+
* @param {import('prosemirror-model').Node} doc - The document to check against
|
|
124100
|
+
* @returns {boolean} True if index is stale and needs rebuilding
|
|
124101
|
+
*/
|
|
124102
|
+
isStale(doc2) {
|
|
124103
|
+
return !this.valid || doc2.content.size !== this.docSize;
|
|
124104
|
+
}
|
|
124105
|
+
/**
|
|
124106
|
+
* Ensure the index is valid for the given document.
|
|
124107
|
+
* Rebuilds if stale.
|
|
124108
|
+
*
|
|
124109
|
+
* @param {import('prosemirror-model').Node} doc - The document
|
|
124110
|
+
*/
|
|
124111
|
+
ensureValid(doc2) {
|
|
124112
|
+
if (this.isStale(doc2)) {
|
|
124113
|
+
this.build(doc2);
|
|
124114
|
+
}
|
|
124115
|
+
}
|
|
124116
|
+
/**
|
|
124117
|
+
* Convert an offset range in the flattened string to document ranges.
|
|
124118
|
+
* Skips separator/atom segments and returns only text ranges.
|
|
124119
|
+
*
|
|
124120
|
+
* @param {number} start - Start offset in flattened string
|
|
124121
|
+
* @param {number} end - End offset in flattened string
|
|
124122
|
+
* @returns {DocRange[]} Array of document ranges (text segments only)
|
|
124123
|
+
*/
|
|
124124
|
+
offsetRangeToDocRanges(start2, end2) {
|
|
124125
|
+
const ranges = [];
|
|
124126
|
+
for (const segment of this.segments) {
|
|
124127
|
+
if (segment.offsetEnd <= start2) continue;
|
|
124128
|
+
if (segment.offsetStart >= end2) break;
|
|
124129
|
+
if (segment.kind !== "text") continue;
|
|
124130
|
+
const overlapStart = Math.max(start2, segment.offsetStart);
|
|
124131
|
+
const overlapEnd = Math.min(end2, segment.offsetEnd);
|
|
124132
|
+
if (overlapStart < overlapEnd) {
|
|
124133
|
+
const startInSegment = overlapStart - segment.offsetStart;
|
|
124134
|
+
const endInSegment = overlapEnd - segment.offsetStart;
|
|
124135
|
+
ranges.push({
|
|
124136
|
+
from: segment.docFrom + startInSegment,
|
|
124137
|
+
to: segment.docFrom + endInSegment
|
|
124138
|
+
});
|
|
124139
|
+
}
|
|
124140
|
+
}
|
|
124141
|
+
return ranges;
|
|
124142
|
+
}
|
|
124143
|
+
/**
|
|
124144
|
+
* Find the document position for a given offset in the flattened string.
|
|
124145
|
+
*
|
|
124146
|
+
* @param {number} offset - Offset in flattened string
|
|
124147
|
+
* @returns {number|null} Document position, or null if not found
|
|
124148
|
+
*/
|
|
124149
|
+
offsetToDocPos(offset2) {
|
|
124150
|
+
for (const segment of this.segments) {
|
|
124151
|
+
if (offset2 >= segment.offsetStart && offset2 < segment.offsetEnd) {
|
|
124152
|
+
if (segment.kind === "text") {
|
|
124153
|
+
return segment.docFrom + (offset2 - segment.offsetStart);
|
|
124154
|
+
}
|
|
124155
|
+
return segment.docFrom;
|
|
124156
|
+
}
|
|
124157
|
+
}
|
|
124158
|
+
if (this.segments.length > 0 && offset2 === this.segments[this.segments.length - 1].offsetEnd) {
|
|
124159
|
+
const lastSeg = this.segments[this.segments.length - 1];
|
|
124160
|
+
return lastSeg.docTo;
|
|
124161
|
+
}
|
|
124162
|
+
return null;
|
|
124163
|
+
}
|
|
124164
|
+
/**
|
|
124165
|
+
* Escape special regex characters in a string.
|
|
124166
|
+
*
|
|
124167
|
+
* @param {string} str - String to escape
|
|
124168
|
+
* @returns {string} Escaped string safe for use in RegExp
|
|
124169
|
+
*/
|
|
124170
|
+
static escapeRegex(str) {
|
|
124171
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
124172
|
+
}
|
|
124173
|
+
/**
|
|
124174
|
+
* Convert a plain search string to a whitespace-flexible regex pattern.
|
|
124175
|
+
* This allows matching across paragraph boundaries.
|
|
124176
|
+
*
|
|
124177
|
+
* @param {string} searchString - The search string
|
|
124178
|
+
* @returns {string} Regex pattern string
|
|
124179
|
+
*/
|
|
124180
|
+
static toFlexiblePattern(searchString) {
|
|
124181
|
+
const parts = searchString.split(/\s+/).filter((part) => part.length > 0);
|
|
124182
|
+
if (parts.length === 0) return "";
|
|
124183
|
+
return parts.map((part) => SearchIndex.escapeRegex(part)).join("\\s+");
|
|
124184
|
+
}
|
|
124185
|
+
/**
|
|
124186
|
+
* Search the index for matches.
|
|
124187
|
+
*
|
|
124188
|
+
* @param {string | RegExp} pattern - Search pattern (string or regex)
|
|
124189
|
+
* @param {Object} options - Search options
|
|
124190
|
+
* @param {boolean} [options.caseSensitive=false] - Case sensitive search
|
|
124191
|
+
* @param {number} [options.maxMatches=1000] - Maximum number of matches to return
|
|
124192
|
+
* @returns {Array<{start: number, end: number, text: string}>} Array of matches with offsets
|
|
124193
|
+
*/
|
|
124194
|
+
search(pattern, options = {}) {
|
|
124195
|
+
const { caseSensitive = false, maxMatches = 1e3 } = options;
|
|
124196
|
+
const matches2 = [];
|
|
124197
|
+
let regex;
|
|
124198
|
+
if (pattern instanceof RegExp) {
|
|
124199
|
+
const flags = pattern.flags.includes("g") ? pattern.flags : pattern.flags + "g";
|
|
124200
|
+
regex = new RegExp(pattern.source, flags);
|
|
124201
|
+
} else if (typeof pattern === "string") {
|
|
124202
|
+
if (pattern.length === 0) return matches2;
|
|
124203
|
+
const flexiblePattern = SearchIndex.toFlexiblePattern(pattern);
|
|
124204
|
+
if (flexiblePattern.length === 0) return matches2;
|
|
124205
|
+
const flags = caseSensitive ? "g" : "gi";
|
|
124206
|
+
regex = new RegExp(flexiblePattern, flags);
|
|
124207
|
+
} else {
|
|
124208
|
+
return matches2;
|
|
124209
|
+
}
|
|
124210
|
+
let match;
|
|
124211
|
+
while ((match = regex.exec(this.text)) !== null && matches2.length < maxMatches) {
|
|
124212
|
+
matches2.push({
|
|
124213
|
+
start: match.index,
|
|
124214
|
+
end: match.index + match[0].length,
|
|
124215
|
+
text: match[0]
|
|
124216
|
+
});
|
|
124217
|
+
if (match[0].length === 0) {
|
|
124218
|
+
regex.lastIndex++;
|
|
124219
|
+
}
|
|
124220
|
+
}
|
|
124221
|
+
return matches2;
|
|
123807
124222
|
}
|
|
123808
|
-
const highlight = typeof options?.highlight === "boolean" ? options.highlight : true;
|
|
123809
|
-
return tr.setMeta(searchKey, { query, range: range2, highlight });
|
|
123810
124223
|
}
|
|
124224
|
+
const customSearchHighlightsKey = new PluginKey("customSearchHighlights");
|
|
123811
124225
|
const isRegExp = (value) => Object.prototype.toString.call(value) === "[object RegExp]";
|
|
124226
|
+
const resolveInlineTextPosition = (doc2, position2, direction) => {
|
|
124227
|
+
const docSize = doc2.content.size;
|
|
124228
|
+
if (!Number.isFinite(position2) || position2 < 0 || position2 > docSize) {
|
|
124229
|
+
return position2;
|
|
124230
|
+
}
|
|
124231
|
+
const step = direction === "forward" ? 1 : -1;
|
|
124232
|
+
let current = position2;
|
|
124233
|
+
let iterations = 0;
|
|
124234
|
+
while (iterations < 8) {
|
|
124235
|
+
iterations += 1;
|
|
124236
|
+
const resolved = doc2.resolve(current);
|
|
124237
|
+
const boundaryNode = direction === "forward" ? resolved.nodeAfter : resolved.nodeBefore;
|
|
124238
|
+
if (!boundaryNode) break;
|
|
124239
|
+
if (boundaryNode.isText) break;
|
|
124240
|
+
if (!boundaryNode.isInline || boundaryNode.isAtom || boundaryNode.content.size === 0) break;
|
|
124241
|
+
const next2 = current + step;
|
|
124242
|
+
if (next2 < 0 || next2 > docSize) break;
|
|
124243
|
+
current = next2;
|
|
124244
|
+
const adjacent = doc2.resolve(current);
|
|
124245
|
+
const checkNode = direction === "forward" ? adjacent.nodeAfter : adjacent.nodeBefore;
|
|
124246
|
+
if (checkNode && checkNode.isText) break;
|
|
124247
|
+
}
|
|
124248
|
+
return current;
|
|
124249
|
+
};
|
|
124250
|
+
const resolveSearchRange = ({ doc: doc2, from: from2, to, expectedText, highlights }) => {
|
|
124251
|
+
const docSize = doc2.content.size;
|
|
124252
|
+
let resolvedFrom = Math.max(0, Math.min(from2, docSize));
|
|
124253
|
+
let resolvedTo = Math.max(0, Math.min(to, docSize));
|
|
124254
|
+
if (highlights) {
|
|
124255
|
+
const windowStart = Math.max(0, resolvedFrom - 4);
|
|
124256
|
+
const windowEnd = Math.min(docSize, resolvedTo + 4);
|
|
124257
|
+
const candidates = highlights.find(windowStart, windowEnd);
|
|
124258
|
+
if (candidates.length > 0) {
|
|
124259
|
+
let chosen = candidates[0];
|
|
124260
|
+
if (expectedText) {
|
|
124261
|
+
const matching = candidates.filter(
|
|
124262
|
+
(decoration) => doc2.textBetween(decoration.from, decoration.to) === expectedText
|
|
124263
|
+
);
|
|
124264
|
+
if (matching.length > 0) {
|
|
124265
|
+
chosen = matching[0];
|
|
124266
|
+
}
|
|
124267
|
+
}
|
|
124268
|
+
resolvedFrom = chosen.from;
|
|
124269
|
+
resolvedTo = chosen.to;
|
|
124270
|
+
}
|
|
124271
|
+
}
|
|
124272
|
+
const normalizedFrom = resolveInlineTextPosition(doc2, resolvedFrom, "forward");
|
|
124273
|
+
const normalizedTo = resolveInlineTextPosition(doc2, resolvedTo, "backward");
|
|
124274
|
+
if (Number.isFinite(normalizedFrom) && Number.isFinite(normalizedTo) && normalizedFrom <= normalizedTo) {
|
|
124275
|
+
resolvedFrom = normalizedFrom;
|
|
124276
|
+
resolvedTo = normalizedTo;
|
|
124277
|
+
}
|
|
124278
|
+
return { from: resolvedFrom, to: resolvedTo };
|
|
124279
|
+
};
|
|
124280
|
+
const getPositionTracker = (editor) => {
|
|
124281
|
+
if (!editor) return null;
|
|
124282
|
+
if (editor.positionTracker) return editor.positionTracker;
|
|
124283
|
+
const storageTracker = editor.storage?.positionTracker?.tracker;
|
|
124284
|
+
if (storageTracker) {
|
|
124285
|
+
editor.positionTracker = storageTracker;
|
|
124286
|
+
return storageTracker;
|
|
124287
|
+
}
|
|
124288
|
+
const tracker = new PositionTracker(editor);
|
|
124289
|
+
if (editor.storage?.positionTracker) {
|
|
124290
|
+
editor.storage.positionTracker.tracker = tracker;
|
|
124291
|
+
}
|
|
124292
|
+
editor.positionTracker = tracker;
|
|
124293
|
+
return tracker;
|
|
124294
|
+
};
|
|
123812
124295
|
const Search = Extension.create({
|
|
123813
124296
|
// @ts-expect-error - Storage type mismatch will be fixed in TS migration
|
|
123814
124297
|
addStorage() {
|
|
@@ -123817,29 +124300,58 @@ ${o}
|
|
|
123817
124300
|
* @private
|
|
123818
124301
|
* @type {SearchMatch[]|null}
|
|
123819
124302
|
*/
|
|
123820
|
-
searchResults: []
|
|
124303
|
+
searchResults: [],
|
|
124304
|
+
/**
|
|
124305
|
+
* @private
|
|
124306
|
+
* @type {boolean}
|
|
124307
|
+
* Whether to apply CSS highlight classes to matches
|
|
124308
|
+
*/
|
|
124309
|
+
highlightEnabled: true,
|
|
124310
|
+
/**
|
|
124311
|
+
* @private
|
|
124312
|
+
* @type {SearchIndex}
|
|
124313
|
+
* Lazily-built search index for cross-paragraph matching
|
|
124314
|
+
*/
|
|
124315
|
+
searchIndex: new SearchIndex()
|
|
123821
124316
|
};
|
|
123822
124317
|
},
|
|
123823
124318
|
addPmPlugins() {
|
|
123824
124319
|
const editor = this.editor;
|
|
123825
124320
|
const storage = this.storage;
|
|
124321
|
+
const searchIndexInvalidatorPlugin = new Plugin({
|
|
124322
|
+
key: new PluginKey("searchIndexInvalidator"),
|
|
124323
|
+
appendTransaction(transactions, oldState, newState) {
|
|
124324
|
+
const docChanged = transactions.some((tr) => tr.docChanged);
|
|
124325
|
+
if (docChanged && storage?.searchIndex) {
|
|
124326
|
+
storage.searchIndex.invalidate();
|
|
124327
|
+
}
|
|
124328
|
+
return null;
|
|
124329
|
+
}
|
|
124330
|
+
});
|
|
123826
124331
|
const searchHighlightWithIdPlugin = new Plugin({
|
|
123827
|
-
key:
|
|
124332
|
+
key: customSearchHighlightsKey,
|
|
123828
124333
|
props: {
|
|
123829
124334
|
decorations(state) {
|
|
123830
124335
|
if (!editor) return null;
|
|
123831
124336
|
const matches2 = storage?.searchResults;
|
|
123832
124337
|
if (!matches2?.length) return null;
|
|
123833
|
-
const
|
|
123834
|
-
|
|
123835
|
-
|
|
123836
|
-
}
|
|
123837
|
-
|
|
124338
|
+
const highlightEnabled = storage?.highlightEnabled !== false;
|
|
124339
|
+
const decorations = [];
|
|
124340
|
+
for (const match of matches2) {
|
|
124341
|
+
const attrs = highlightEnabled ? { id: `search-match-${match.id}`, class: "ProseMirror-search-match" } : { id: `search-match-${match.id}` };
|
|
124342
|
+
if (match.ranges && match.ranges.length > 0) {
|
|
124343
|
+
for (const range2 of match.ranges) {
|
|
124344
|
+
decorations.push(Decoration.inline(range2.from, range2.to, attrs));
|
|
124345
|
+
}
|
|
124346
|
+
} else {
|
|
124347
|
+
decorations.push(Decoration.inline(match.from, match.to, attrs));
|
|
124348
|
+
}
|
|
124349
|
+
}
|
|
123838
124350
|
return DecorationSet.create(state.doc, decorations);
|
|
123839
124351
|
}
|
|
123840
124352
|
}
|
|
123841
124353
|
});
|
|
123842
|
-
return [search$1(), searchHighlightWithIdPlugin];
|
|
124354
|
+
return [search$1(), searchIndexInvalidatorPlugin, searchHighlightWithIdPlugin];
|
|
123843
124355
|
},
|
|
123844
124356
|
addCommands() {
|
|
123845
124357
|
return {
|
|
@@ -123853,21 +124365,51 @@ ${o}
|
|
|
123853
124365
|
goToFirstMatch: () => (
|
|
123854
124366
|
/** @returns {boolean} */
|
|
123855
124367
|
({ state, editor, dispatch }) => {
|
|
124368
|
+
const searchResults = this.storage?.searchResults;
|
|
124369
|
+
if (Array.isArray(searchResults) && searchResults.length > 0) {
|
|
124370
|
+
const firstMatch = searchResults[0];
|
|
124371
|
+
const from2 = firstMatch.ranges?.[0]?.from ?? firstMatch.from;
|
|
124372
|
+
const to = firstMatch.ranges?.[0]?.to ?? firstMatch.to;
|
|
124373
|
+
if (typeof from2 !== "number" || typeof to !== "number") {
|
|
124374
|
+
return false;
|
|
124375
|
+
}
|
|
124376
|
+
editor.view.focus();
|
|
124377
|
+
const tr2 = state.tr.setSelection(TextSelection$1.create(state.doc, from2, to)).scrollIntoView();
|
|
124378
|
+
if (dispatch) dispatch(tr2);
|
|
124379
|
+
const presentationEditor2 = editor.presentationEditor;
|
|
124380
|
+
if (presentationEditor2 && typeof presentationEditor2.scrollToPosition === "function") {
|
|
124381
|
+
const didScroll = presentationEditor2.scrollToPosition(from2, { block: "center" });
|
|
124382
|
+
if (didScroll) return true;
|
|
124383
|
+
}
|
|
124384
|
+
try {
|
|
124385
|
+
const domPos = editor.view.domAtPos(from2);
|
|
124386
|
+
if (domPos?.node?.scrollIntoView) {
|
|
124387
|
+
domPos.node.scrollIntoView(true);
|
|
124388
|
+
}
|
|
124389
|
+
} catch {
|
|
124390
|
+
}
|
|
124391
|
+
return true;
|
|
124392
|
+
}
|
|
123856
124393
|
const highlights = getMatchHighlights(state);
|
|
123857
124394
|
if (!highlights) return false;
|
|
123858
124395
|
const decorations = highlights.find();
|
|
123859
124396
|
if (!decorations?.length) return false;
|
|
123860
|
-
const
|
|
124397
|
+
const firstDeco = decorations[0];
|
|
123861
124398
|
editor.view.focus();
|
|
123862
|
-
const tr = state.tr.setSelection(TextSelection$1.create(state.doc,
|
|
124399
|
+
const tr = state.tr.setSelection(TextSelection$1.create(state.doc, firstDeco.from, firstDeco.to)).scrollIntoView();
|
|
123863
124400
|
if (dispatch) dispatch(tr);
|
|
123864
124401
|
const presentationEditor = editor.presentationEditor;
|
|
123865
124402
|
if (presentationEditor && typeof presentationEditor.scrollToPosition === "function") {
|
|
123866
|
-
const didScroll = presentationEditor.scrollToPosition(
|
|
124403
|
+
const didScroll = presentationEditor.scrollToPosition(firstDeco.from, { block: "center" });
|
|
123867
124404
|
if (didScroll) return true;
|
|
123868
124405
|
}
|
|
123869
|
-
|
|
123870
|
-
|
|
124406
|
+
try {
|
|
124407
|
+
const domPos = editor.view.domAtPos(firstDeco.from);
|
|
124408
|
+
if (domPos?.node?.scrollIntoView) {
|
|
124409
|
+
domPos.node.scrollIntoView(true);
|
|
124410
|
+
}
|
|
124411
|
+
} catch {
|
|
124412
|
+
}
|
|
123871
124413
|
return true;
|
|
123872
124414
|
}
|
|
123873
124415
|
),
|
|
@@ -123885,53 +124427,57 @@ ${o}
|
|
|
123885
124427
|
*
|
|
123886
124428
|
* // Search without visual highlighting
|
|
123887
124429
|
* const silentMatches = editor.commands.search('test', { highlight: false })
|
|
123888
|
-
*
|
|
124430
|
+
*
|
|
124431
|
+
* // Cross-paragraph search (works by default for plain strings)
|
|
124432
|
+
* const crossParagraphMatches = editor.commands.search('end of paragraph start of next')
|
|
124433
|
+
* @note Returns array of SearchMatch objects with positions and IDs.
|
|
124434
|
+
* Plain string searches are whitespace-flexible and match across paragraphs.
|
|
124435
|
+
* Regex searches match exactly as specified.
|
|
123889
124436
|
*/
|
|
123890
124437
|
search: (patternInput, options = {}) => (
|
|
123891
124438
|
/** @returns {SearchMatch[]} */
|
|
123892
|
-
({ state, dispatch }) => {
|
|
124439
|
+
({ state, dispatch, editor }) => {
|
|
123893
124440
|
if (options != null && (typeof options !== "object" || Array.isArray(options))) {
|
|
123894
124441
|
throw new TypeError("Search options must be an object");
|
|
123895
124442
|
}
|
|
123896
124443
|
const highlight = typeof options?.highlight === "boolean" ? options.highlight : true;
|
|
123897
|
-
|
|
124444
|
+
const maxMatches = typeof options?.maxMatches === "number" ? options.maxMatches : 1e3;
|
|
123898
124445
|
let caseSensitive = false;
|
|
123899
|
-
let
|
|
123900
|
-
const wholeWord = false;
|
|
124446
|
+
let searchPattern = patternInput;
|
|
123901
124447
|
if (isRegExp(patternInput)) {
|
|
123902
|
-
|
|
123903
|
-
|
|
123904
|
-
patternInput
|
|
123905
|
-
);
|
|
123906
|
-
regexp = true;
|
|
123907
|
-
pattern = regexPattern.source;
|
|
123908
|
-
caseSensitive = !regexPattern.flags.includes("i");
|
|
124448
|
+
caseSensitive = !patternInput.flags.includes("i");
|
|
124449
|
+
searchPattern = patternInput;
|
|
123909
124450
|
} else if (typeof patternInput === "string" && /^\/(.+)\/([gimsuy]*)$/.test(patternInput)) {
|
|
123910
124451
|
const [, body, flags] = patternInput.match(/^\/(.+)\/([gimsuy]*)$/);
|
|
123911
|
-
regexp = true;
|
|
123912
|
-
pattern = body;
|
|
123913
124452
|
caseSensitive = !flags.includes("i");
|
|
124453
|
+
searchPattern = new RegExp(body, flags.includes("g") ? flags : flags + "g");
|
|
123914
124454
|
} else {
|
|
123915
|
-
|
|
124455
|
+
searchPattern = String(patternInput);
|
|
123916
124456
|
}
|
|
123917
|
-
const
|
|
123918
|
-
|
|
124457
|
+
const searchIndex = this.storage.searchIndex;
|
|
124458
|
+
searchIndex.ensureValid(state.doc);
|
|
124459
|
+
const indexMatches = searchIndex.search(searchPattern, {
|
|
123919
124460
|
caseSensitive,
|
|
123920
|
-
|
|
123921
|
-
wholeWord
|
|
124461
|
+
maxMatches
|
|
123922
124462
|
});
|
|
123923
|
-
const
|
|
123924
|
-
|
|
123925
|
-
|
|
123926
|
-
|
|
123927
|
-
|
|
123928
|
-
|
|
123929
|
-
|
|
123930
|
-
|
|
123931
|
-
|
|
123932
|
-
|
|
123933
|
-
|
|
124463
|
+
const resultMatches = [];
|
|
124464
|
+
for (const indexMatch of indexMatches) {
|
|
124465
|
+
const ranges = searchIndex.offsetRangeToDocRanges(indexMatch.start, indexMatch.end);
|
|
124466
|
+
if (ranges.length === 0) continue;
|
|
124467
|
+
const matchTexts = ranges.map((r2) => state.doc.textBetween(r2.from, r2.to));
|
|
124468
|
+
const combinedText = matchTexts.join("");
|
|
124469
|
+
const match = {
|
|
124470
|
+
from: ranges[0].from,
|
|
124471
|
+
to: ranges[ranges.length - 1].to,
|
|
124472
|
+
text: combinedText,
|
|
124473
|
+
id: v4(),
|
|
124474
|
+
ranges,
|
|
124475
|
+
trackerIds: []
|
|
124476
|
+
};
|
|
124477
|
+
resultMatches.push(match);
|
|
124478
|
+
}
|
|
123934
124479
|
this.storage.searchResults = resultMatches;
|
|
124480
|
+
this.storage.highlightEnabled = highlight;
|
|
123935
124481
|
return resultMatches;
|
|
123936
124482
|
}
|
|
123937
124483
|
),
|
|
@@ -123942,12 +124488,48 @@ ${o}
|
|
|
123942
124488
|
* @example
|
|
123943
124489
|
* const searchResults = editor.commands.search('test string')
|
|
123944
124490
|
* editor.commands.goToSearchResult(searchResults[3])
|
|
123945
|
-
* @note Scrolls to match and selects it
|
|
124491
|
+
* @note Scrolls to match and selects it. For multi-range matches (cross-paragraph),
|
|
124492
|
+
* selects the first range and scrolls to it.
|
|
123946
124493
|
*/
|
|
123947
124494
|
goToSearchResult: (match) => (
|
|
123948
124495
|
/** @returns {boolean} */
|
|
123949
124496
|
({ state, dispatch, editor }) => {
|
|
123950
|
-
const
|
|
124497
|
+
const positionTracker = getPositionTracker(editor);
|
|
124498
|
+
const doc2 = state.doc;
|
|
124499
|
+
const highlights = getMatchHighlights(state);
|
|
124500
|
+
let from2, to;
|
|
124501
|
+
if (match?.ranges && match.ranges.length > 0 && match?.trackerIds && match.trackerIds.length > 0) {
|
|
124502
|
+
if (positionTracker?.resolve && match.trackerIds[0]) {
|
|
124503
|
+
const resolved = positionTracker.resolve(match.trackerIds[0]);
|
|
124504
|
+
if (resolved) {
|
|
124505
|
+
from2 = resolved.from;
|
|
124506
|
+
to = resolved.to;
|
|
124507
|
+
}
|
|
124508
|
+
}
|
|
124509
|
+
if (from2 === void 0) {
|
|
124510
|
+
from2 = match.ranges[0].from;
|
|
124511
|
+
to = match.ranges[0].to;
|
|
124512
|
+
}
|
|
124513
|
+
} else {
|
|
124514
|
+
from2 = match.from;
|
|
124515
|
+
to = match.to;
|
|
124516
|
+
if (positionTracker?.resolve && match?.id) {
|
|
124517
|
+
const resolved = positionTracker.resolve(match.id);
|
|
124518
|
+
if (resolved) {
|
|
124519
|
+
from2 = resolved.from;
|
|
124520
|
+
to = resolved.to;
|
|
124521
|
+
}
|
|
124522
|
+
}
|
|
124523
|
+
}
|
|
124524
|
+
const normalized = resolveSearchRange({
|
|
124525
|
+
doc: doc2,
|
|
124526
|
+
from: from2,
|
|
124527
|
+
to,
|
|
124528
|
+
expectedText: match?.text ?? null,
|
|
124529
|
+
highlights
|
|
124530
|
+
});
|
|
124531
|
+
from2 = normalized.from;
|
|
124532
|
+
to = normalized.to;
|
|
123951
124533
|
editor.view.focus();
|
|
123952
124534
|
const tr = state.tr.setSelection(TextSelection$1.create(state.doc, from2, to)).scrollIntoView();
|
|
123953
124535
|
if (dispatch) dispatch(tr);
|
|
@@ -149687,7 +150269,7 @@ ${reason}`);
|
|
|
149687
150269
|
this.config.colors = shuffleArray(this.config.colors);
|
|
149688
150270
|
this.userColorMap = /* @__PURE__ */ new Map();
|
|
149689
150271
|
this.colorIndex = 0;
|
|
149690
|
-
this.version = "1.6.0-next.
|
|
150272
|
+
this.version = "1.6.0-next.2";
|
|
149691
150273
|
this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
|
|
149692
150274
|
this.superdocId = config2.superdocId || v4();
|
|
149693
150275
|
this.colors = this.config.colors;
|