@pixerate/editor 0.6.0 → 0.7.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/extensions/index.cjs +47 -2
- package/dist/extensions/index.cjs.map +1 -1
- package/dist/extensions/index.d.cts +16 -1
- package/dist/extensions/index.d.ts +16 -1
- package/dist/extensions/index.js +46 -2
- package/dist/extensions/index.js.map +1 -1
- package/dist/index.cjs +137 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +45 -2
- package/dist/index.d.ts +45 -2
- package/dist/index.js +133 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -33,6 +33,7 @@ __export(src_exports, {
|
|
|
33
33
|
ColorHighlighter: () => ColorHighlighter,
|
|
34
34
|
DataSourceBinder: () => DataSourceBinder,
|
|
35
35
|
DependencyGraph: () => DependencyGraph,
|
|
36
|
+
DirtyTracker: () => DirtyTracker,
|
|
36
37
|
EditorController: () => EditorController,
|
|
37
38
|
FontSize: () => FontSize,
|
|
38
39
|
FormulaEvaluator: () => FormulaEvaluator,
|
|
@@ -50,9 +51,11 @@ __export(src_exports, {
|
|
|
50
51
|
TemplateSuggestions: () => TemplateSuggestions,
|
|
51
52
|
VARIABLE_REGEX: () => VARIABLE_REGEX,
|
|
52
53
|
colNameToIndex: () => colNameToIndex,
|
|
54
|
+
createDirtyTracker: () => createDirtyTracker,
|
|
53
55
|
createEditor: () => createEditor,
|
|
54
56
|
createMentionExtension: () => createMentionExtension,
|
|
55
57
|
createRichTextPreset: () => createRichTextPreset,
|
|
58
|
+
defaultIsEqual: () => defaultIsEqual,
|
|
56
59
|
escapeHtml: () => escapeHtml,
|
|
57
60
|
extractCellDependencies: () => extractCellDependencies,
|
|
58
61
|
extractInstructionNames: () => extractInstructionNames,
|
|
@@ -76,6 +79,7 @@ __export(src_exports, {
|
|
|
76
79
|
parseFormula: () => parseFormula,
|
|
77
80
|
parseRange: () => parseRange,
|
|
78
81
|
plainTextToTipTapHtml: () => plainTextToTipTapHtml,
|
|
82
|
+
removeImageNode: () => removeImageNode,
|
|
79
83
|
resolveTemplates: () => resolveTemplates,
|
|
80
84
|
resolveTemplatesWithMapping: () => resolveTemplatesWithMapping,
|
|
81
85
|
resolveVariables: () => resolveVariables,
|
|
@@ -2003,6 +2007,22 @@ function updateImageSrc(view, oldSrc, newSrc) {
|
|
|
2003
2007
|
view.dispatch(tr);
|
|
2004
2008
|
}
|
|
2005
2009
|
}
|
|
2010
|
+
function removeImageNode(view, src) {
|
|
2011
|
+
const { doc } = view.state;
|
|
2012
|
+
let foundPos = null;
|
|
2013
|
+
let nodeSize = 0;
|
|
2014
|
+
doc.descendants((node, pos) => {
|
|
2015
|
+
if (node.type.name === "image" && node.attrs.src === src) {
|
|
2016
|
+
foundPos = pos;
|
|
2017
|
+
nodeSize = node.nodeSize;
|
|
2018
|
+
return false;
|
|
2019
|
+
}
|
|
2020
|
+
});
|
|
2021
|
+
if (foundPos !== null) {
|
|
2022
|
+
const tr = view.state.tr.delete(foundPos, foundPos + nodeSize);
|
|
2023
|
+
view.dispatch(tr);
|
|
2024
|
+
}
|
|
2025
|
+
}
|
|
2006
2026
|
function handleImageInsertion(view, file, options) {
|
|
2007
2027
|
if (typeof options.upload === "function") {
|
|
2008
2028
|
const hasObjectUrl = typeof URL !== "undefined" && typeof URL.createObjectURL === "function";
|
|
@@ -2011,7 +2031,9 @@ function handleImageInsertion(view, file, options) {
|
|
|
2011
2031
|
insertImageNode(view, tempUrl, file.name);
|
|
2012
2032
|
}
|
|
2013
2033
|
Promise.resolve(options.upload(file)).then((uploadedUrl) => {
|
|
2014
|
-
if (!uploadedUrl)
|
|
2034
|
+
if (!uploadedUrl) {
|
|
2035
|
+
throw new Error("Upload handler returned empty URL");
|
|
2036
|
+
}
|
|
2015
2037
|
if (tempUrl) {
|
|
2016
2038
|
updateImageSrc(view, tempUrl, uploadedUrl);
|
|
2017
2039
|
if (typeof URL.revokeObjectURL === "function") {
|
|
@@ -2021,9 +2043,32 @@ function handleImageInsertion(view, file, options) {
|
|
|
2021
2043
|
insertImageNode(view, uploadedUrl, file.name);
|
|
2022
2044
|
}
|
|
2023
2045
|
}).catch((err) => {
|
|
2024
|
-
|
|
2046
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
2047
|
+
console.error("Failed to upload pasted image:", error);
|
|
2048
|
+
if (tempUrl) {
|
|
2049
|
+
removeImageNode(view, tempUrl);
|
|
2050
|
+
if (typeof URL.revokeObjectURL === "function") {
|
|
2051
|
+
URL.revokeObjectURL(tempUrl);
|
|
2052
|
+
}
|
|
2053
|
+
}
|
|
2054
|
+
if (typeof options.onUploadError === "function") {
|
|
2055
|
+
options.onUploadError(error, file);
|
|
2056
|
+
}
|
|
2025
2057
|
});
|
|
2026
2058
|
} else if (options.allowBase64 !== false) {
|
|
2059
|
+
const maxBase64Size = options.maxBase64Size ?? 65536;
|
|
2060
|
+
if (file.size > maxBase64Size) {
|
|
2061
|
+
const err = new Error(
|
|
2062
|
+
`Image size (${Math.round(file.size / 1024)}KB) exceeds maxBase64Size (${Math.round(
|
|
2063
|
+
maxBase64Size / 1024
|
|
2064
|
+
)}KB). Provide an upload handler to support large images.`
|
|
2065
|
+
);
|
|
2066
|
+
console.warn(`[Editor] ${err.message}`);
|
|
2067
|
+
if (typeof options.onUploadError === "function") {
|
|
2068
|
+
options.onUploadError(err, file);
|
|
2069
|
+
}
|
|
2070
|
+
return;
|
|
2071
|
+
}
|
|
2027
2072
|
if (typeof FileReader !== "undefined") {
|
|
2028
2073
|
const reader = new FileReader();
|
|
2029
2074
|
reader.onload = () => {
|
|
@@ -2041,9 +2086,11 @@ var Image2 = BaseImage.extend({
|
|
|
2041
2086
|
return {
|
|
2042
2087
|
...this.parent?.(),
|
|
2043
2088
|
allowBase64: true,
|
|
2089
|
+
maxBase64Size: 65536,
|
|
2044
2090
|
enablePaste: true,
|
|
2045
2091
|
enableDrop: true,
|
|
2046
2092
|
upload: void 0,
|
|
2093
|
+
onUploadError: void 0,
|
|
2047
2094
|
HTMLAttributes: {
|
|
2048
2095
|
class: "rounded-md max-w-full h-auto my-2"
|
|
2049
2096
|
}
|
|
@@ -2399,6 +2446,7 @@ var EditorController = class {
|
|
|
2399
2446
|
onMarkdownChange;
|
|
2400
2447
|
onTokensChange;
|
|
2401
2448
|
onSelectionChange;
|
|
2449
|
+
baselineContent;
|
|
2402
2450
|
constructor(options = {}) {
|
|
2403
2451
|
const {
|
|
2404
2452
|
element,
|
|
@@ -2436,6 +2484,7 @@ var EditorController = class {
|
|
|
2436
2484
|
if (plainTextMode) {
|
|
2437
2485
|
this.enforcePlainTextClipboard();
|
|
2438
2486
|
}
|
|
2487
|
+
this.baselineContent = this.getCurrentContentString();
|
|
2439
2488
|
}
|
|
2440
2489
|
enforcePlainTextClipboard() {
|
|
2441
2490
|
this.editor.setOptions({
|
|
@@ -2509,6 +2558,23 @@ var EditorController = class {
|
|
|
2509
2558
|
replaceRange(from, to, text) {
|
|
2510
2559
|
this.editor.chain().focus().deleteRange({ from, to }).insertContentAt(from, text).run();
|
|
2511
2560
|
}
|
|
2561
|
+
getCurrentContentString() {
|
|
2562
|
+
if (this.plainTextMode) return this.getPlainText();
|
|
2563
|
+
if (this.markdownMode) return this.getMarkdown();
|
|
2564
|
+
return this.editor.getHTML();
|
|
2565
|
+
}
|
|
2566
|
+
isDirty() {
|
|
2567
|
+
return this.getCurrentContentString() !== this.baselineContent;
|
|
2568
|
+
}
|
|
2569
|
+
setCheckpoint(content) {
|
|
2570
|
+
this.baselineContent = content !== void 0 ? content : this.getCurrentContentString();
|
|
2571
|
+
}
|
|
2572
|
+
resetDirty() {
|
|
2573
|
+
this.setCheckpoint();
|
|
2574
|
+
}
|
|
2575
|
+
getBaselineContent() {
|
|
2576
|
+
return this.baselineContent;
|
|
2577
|
+
}
|
|
2512
2578
|
destroy() {
|
|
2513
2579
|
this.editor.destroy();
|
|
2514
2580
|
}
|
|
@@ -3791,11 +3857,77 @@ var SpreadsheetController = class {
|
|
|
3791
3857
|
this.onDocumentChange?.(this.document);
|
|
3792
3858
|
}
|
|
3793
3859
|
};
|
|
3860
|
+
|
|
3861
|
+
// src/dirty.ts
|
|
3862
|
+
function defaultIsEqual(a, b) {
|
|
3863
|
+
if (Object.is(a, b)) return true;
|
|
3864
|
+
if (typeof a !== "object" || a === null || typeof b !== "object" || b === null) {
|
|
3865
|
+
return false;
|
|
3866
|
+
}
|
|
3867
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
3868
|
+
if (a.length !== b.length) return false;
|
|
3869
|
+
for (let i = 0; i < a.length; i++) {
|
|
3870
|
+
if (!defaultIsEqual(a[i], b[i])) return false;
|
|
3871
|
+
}
|
|
3872
|
+
return true;
|
|
3873
|
+
}
|
|
3874
|
+
if (Array.isArray(a) !== Array.isArray(b)) {
|
|
3875
|
+
return false;
|
|
3876
|
+
}
|
|
3877
|
+
const keysA = Object.keys(a);
|
|
3878
|
+
const keysB = Object.keys(b);
|
|
3879
|
+
if (keysA.length !== keysB.length) return false;
|
|
3880
|
+
for (const key of keysA) {
|
|
3881
|
+
if (!Object.prototype.hasOwnProperty.call(b, key)) return false;
|
|
3882
|
+
if (!defaultIsEqual(a[key], b[key])) return false;
|
|
3883
|
+
}
|
|
3884
|
+
return true;
|
|
3885
|
+
}
|
|
3886
|
+
var DirtyTracker = class {
|
|
3887
|
+
baseline;
|
|
3888
|
+
isEqual;
|
|
3889
|
+
constructor(initialBaseline, options) {
|
|
3890
|
+
this.baseline = initialBaseline;
|
|
3891
|
+
if (typeof options === "function") {
|
|
3892
|
+
this.isEqual = options;
|
|
3893
|
+
} else {
|
|
3894
|
+
this.isEqual = options?.isEqual ?? defaultIsEqual;
|
|
3895
|
+
}
|
|
3896
|
+
}
|
|
3897
|
+
/**
|
|
3898
|
+
* Returns current baseline value.
|
|
3899
|
+
*/
|
|
3900
|
+
getBaseline() {
|
|
3901
|
+
return this.baseline;
|
|
3902
|
+
}
|
|
3903
|
+
/**
|
|
3904
|
+
* Sets a new baseline value without triggering any dirty state.
|
|
3905
|
+
*/
|
|
3906
|
+
setBaseline(value) {
|
|
3907
|
+
this.baseline = value;
|
|
3908
|
+
}
|
|
3909
|
+
/**
|
|
3910
|
+
* Checks whether the given value differs from the baseline.
|
|
3911
|
+
*/
|
|
3912
|
+
isDirty(current) {
|
|
3913
|
+
return !this.isEqual(this.baseline, current);
|
|
3914
|
+
}
|
|
3915
|
+
/**
|
|
3916
|
+
* Resets the baseline to the provided current value (or clears dirty status).
|
|
3917
|
+
*/
|
|
3918
|
+
reset(current) {
|
|
3919
|
+
this.baseline = current;
|
|
3920
|
+
}
|
|
3921
|
+
};
|
|
3922
|
+
function createDirtyTracker(initialBaseline, options) {
|
|
3923
|
+
return new DirtyTracker(initialBaseline, options);
|
|
3924
|
+
}
|
|
3794
3925
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3795
3926
|
0 && (module.exports = {
|
|
3796
3927
|
ColorHighlighter,
|
|
3797
3928
|
DataSourceBinder,
|
|
3798
3929
|
DependencyGraph,
|
|
3930
|
+
DirtyTracker,
|
|
3799
3931
|
EditorController,
|
|
3800
3932
|
FontSize,
|
|
3801
3933
|
FormulaEvaluator,
|
|
@@ -3813,9 +3945,11 @@ var SpreadsheetController = class {
|
|
|
3813
3945
|
TemplateSuggestions,
|
|
3814
3946
|
VARIABLE_REGEX,
|
|
3815
3947
|
colNameToIndex,
|
|
3948
|
+
createDirtyTracker,
|
|
3816
3949
|
createEditor,
|
|
3817
3950
|
createMentionExtension,
|
|
3818
3951
|
createRichTextPreset,
|
|
3952
|
+
defaultIsEqual,
|
|
3819
3953
|
escapeHtml,
|
|
3820
3954
|
extractCellDependencies,
|
|
3821
3955
|
extractInstructionNames,
|
|
@@ -3839,6 +3973,7 @@ var SpreadsheetController = class {
|
|
|
3839
3973
|
parseFormula,
|
|
3840
3974
|
parseRange,
|
|
3841
3975
|
plainTextToTipTapHtml,
|
|
3976
|
+
removeImageNode,
|
|
3842
3977
|
resolveTemplates,
|
|
3843
3978
|
resolveTemplatesWithMapping,
|
|
3844
3979
|
resolveVariables,
|