@blankdotpage/cake 0.1.1 → 0.1.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/cake/clipboard.d.ts +1 -1
- package/dist/cake/core/runtime.d.ts +1 -0
- package/dist/cake/dom/render.d.ts +1 -1
- package/dist/cake/engine/selection/selection-geometry.d.ts +1 -0
- package/dist/index.cjs +803 -246
- package/dist/index.js +803 -246
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,44 +1,53 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const require$$0 = require("react");
|
|
4
|
-
const reactDom = require("react-dom");
|
|
5
4
|
const lucideReact = require("lucide-react");
|
|
6
5
|
const TurndownService = require("turndown");
|
|
7
6
|
const state = require("@codemirror/state");
|
|
8
|
-
var
|
|
9
|
-
var
|
|
7
|
+
var jsxRuntime = { exports: {} };
|
|
8
|
+
var reactJsxRuntime_production_min = {};
|
|
10
9
|
/**
|
|
11
10
|
* @license React
|
|
12
|
-
* react-jsx-
|
|
11
|
+
* react-jsx-runtime.production.min.js
|
|
13
12
|
*
|
|
14
13
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
15
14
|
*
|
|
16
15
|
* This source code is licensed under the MIT license found in the
|
|
17
16
|
* LICENSE file in the root directory of this source tree.
|
|
18
17
|
*/
|
|
19
|
-
var
|
|
20
|
-
function
|
|
21
|
-
if (
|
|
22
|
-
|
|
23
|
-
var
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
18
|
+
var hasRequiredReactJsxRuntime_production_min;
|
|
19
|
+
function requireReactJsxRuntime_production_min() {
|
|
20
|
+
if (hasRequiredReactJsxRuntime_production_min) return reactJsxRuntime_production_min;
|
|
21
|
+
hasRequiredReactJsxRuntime_production_min = 1;
|
|
22
|
+
var f = require$$0, k = Symbol.for("react.element"), l = Symbol.for("react.fragment"), m = Object.prototype.hasOwnProperty, n = f.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner, p = { key: true, ref: true, __self: true, __source: true };
|
|
23
|
+
function q(c, a, g) {
|
|
24
|
+
var b, d = {}, e = null, h = null;
|
|
25
|
+
void 0 !== g && (e = "" + g);
|
|
26
|
+
void 0 !== a.key && (e = "" + a.key);
|
|
27
|
+
void 0 !== a.ref && (h = a.ref);
|
|
28
|
+
for (b in a) m.call(a, b) && !p.hasOwnProperty(b) && (d[b] = a[b]);
|
|
29
|
+
if (c && c.defaultProps) for (b in a = c.defaultProps, a) void 0 === d[b] && (d[b] = a[b]);
|
|
30
|
+
return { $$typeof: k, type: c, key: e, ref: h, props: d, _owner: n.current };
|
|
31
|
+
}
|
|
32
|
+
reactJsxRuntime_production_min.Fragment = l;
|
|
33
|
+
reactJsxRuntime_production_min.jsx = q;
|
|
34
|
+
reactJsxRuntime_production_min.jsxs = q;
|
|
35
|
+
return reactJsxRuntime_production_min;
|
|
36
|
+
}
|
|
37
|
+
var reactJsxRuntime_development = {};
|
|
29
38
|
/**
|
|
30
39
|
* @license React
|
|
31
|
-
* react-jsx-
|
|
40
|
+
* react-jsx-runtime.development.js
|
|
32
41
|
*
|
|
33
42
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
34
43
|
*
|
|
35
44
|
* This source code is licensed under the MIT license found in the
|
|
36
45
|
* LICENSE file in the root directory of this source tree.
|
|
37
46
|
*/
|
|
38
|
-
var
|
|
39
|
-
function
|
|
40
|
-
if (
|
|
41
|
-
|
|
47
|
+
var hasRequiredReactJsxRuntime_development;
|
|
48
|
+
function requireReactJsxRuntime_development() {
|
|
49
|
+
if (hasRequiredReactJsxRuntime_development) return reactJsxRuntime_development;
|
|
50
|
+
hasRequiredReactJsxRuntime_development = 1;
|
|
42
51
|
if (process.env.NODE_ENV !== "production") {
|
|
43
52
|
(function() {
|
|
44
53
|
var React = require$$0;
|
|
@@ -525,10 +534,6 @@ function requireReactJsxDevRuntime_development() {
|
|
|
525
534
|
};
|
|
526
535
|
var specialPropKeyWarningShown;
|
|
527
536
|
var specialPropRefWarningShown;
|
|
528
|
-
var didWarnAboutStringRefs;
|
|
529
|
-
{
|
|
530
|
-
didWarnAboutStringRefs = {};
|
|
531
|
-
}
|
|
532
537
|
function hasValidRef(config) {
|
|
533
538
|
{
|
|
534
539
|
if (hasOwnProperty.call(config, "ref")) {
|
|
@@ -553,13 +558,7 @@ function requireReactJsxDevRuntime_development() {
|
|
|
553
558
|
}
|
|
554
559
|
function warnIfStringRefCannotBeAutoConverted(config, self) {
|
|
555
560
|
{
|
|
556
|
-
if (typeof config.ref === "string" && ReactCurrentOwner.current && self
|
|
557
|
-
var componentName = getComponentNameFromType(ReactCurrentOwner.current.type);
|
|
558
|
-
if (!didWarnAboutStringRefs[componentName]) {
|
|
559
|
-
error('Component "%s" contains the string ref "%s". Support for string refs will be removed in a future major release. This case cannot be automatically converted to an arrow function. We ask you to manually fix this case by using useRef() or createRef() instead. Learn more about using refs safely here: https://reactjs.org/link/strict-mode-string-ref', getComponentNameFromType(ReactCurrentOwner.current.type), config.ref);
|
|
560
|
-
didWarnAboutStringRefs[componentName] = true;
|
|
561
|
-
}
|
|
562
|
-
}
|
|
561
|
+
if (typeof config.ref === "string" && ReactCurrentOwner.current && self) ;
|
|
563
562
|
}
|
|
564
563
|
}
|
|
565
564
|
function defineKeyPropWarningGetter(props, displayName) {
|
|
@@ -713,11 +712,6 @@ function requireReactJsxDevRuntime_development() {
|
|
|
713
712
|
}
|
|
714
713
|
function getSourceInfoErrorAddendum(source) {
|
|
715
714
|
{
|
|
716
|
-
if (source !== void 0) {
|
|
717
|
-
var fileName = source.fileName.replace(/^.*[\\\/]/, "");
|
|
718
|
-
var lineNumber = source.lineNumber;
|
|
719
|
-
return "\n\nCheck your code at " + fileName + ":" + lineNumber + ".";
|
|
720
|
-
}
|
|
721
715
|
return "";
|
|
722
716
|
}
|
|
723
717
|
}
|
|
@@ -843,7 +837,7 @@ function requireReactJsxDevRuntime_development() {
|
|
|
843
837
|
if (type === void 0 || typeof type === "object" && type !== null && Object.keys(type).length === 0) {
|
|
844
838
|
info += " You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.";
|
|
845
839
|
}
|
|
846
|
-
var sourceInfo = getSourceInfoErrorAddendum(
|
|
840
|
+
var sourceInfo = getSourceInfoErrorAddendum();
|
|
847
841
|
if (sourceInfo) {
|
|
848
842
|
info += sourceInfo;
|
|
849
843
|
} else {
|
|
@@ -907,19 +901,31 @@ function requireReactJsxDevRuntime_development() {
|
|
|
907
901
|
return element;
|
|
908
902
|
}
|
|
909
903
|
}
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
904
|
+
function jsxWithValidationStatic(type, props, key) {
|
|
905
|
+
{
|
|
906
|
+
return jsxWithValidation(type, props, key, true);
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
function jsxWithValidationDynamic(type, props, key) {
|
|
910
|
+
{
|
|
911
|
+
return jsxWithValidation(type, props, key, false);
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
var jsx = jsxWithValidationDynamic;
|
|
915
|
+
var jsxs = jsxWithValidationStatic;
|
|
916
|
+
reactJsxRuntime_development.Fragment = REACT_FRAGMENT_TYPE;
|
|
917
|
+
reactJsxRuntime_development.jsx = jsx;
|
|
918
|
+
reactJsxRuntime_development.jsxs = jsxs;
|
|
913
919
|
})();
|
|
914
920
|
}
|
|
915
|
-
return
|
|
921
|
+
return reactJsxRuntime_development;
|
|
916
922
|
}
|
|
917
923
|
if (process.env.NODE_ENV === "production") {
|
|
918
|
-
|
|
924
|
+
jsxRuntime.exports = requireReactJsxRuntime_production_min();
|
|
919
925
|
} else {
|
|
920
|
-
|
|
926
|
+
jsxRuntime.exports = requireReactJsxRuntime_development();
|
|
921
927
|
}
|
|
922
|
-
var
|
|
928
|
+
var jsxRuntimeExports = jsxRuntime.exports;
|
|
923
929
|
const graphemeSegmenter = new Intl.Segmenter(void 0, {
|
|
924
930
|
granularity: "grapheme"
|
|
925
931
|
});
|
|
@@ -2411,13 +2417,150 @@ function createRuntime(extensions) {
|
|
|
2411
2417
|
const endInLine = lineIndex === endLoc.lineIndex ? endLoc.offsetInLine : line.cursorLength;
|
|
2412
2418
|
const selectedRuns = sliceRuns(runs, startInLine, endInLine).selected;
|
|
2413
2419
|
const content = runsToInlines(normalizeRuns(selectedRuns));
|
|
2414
|
-
|
|
2420
|
+
const paragraph = { type: "paragraph", content };
|
|
2421
|
+
if (line.path.length > 1) {
|
|
2422
|
+
const wrapperPath = line.path.slice(0, -1);
|
|
2423
|
+
const wrapper = getBlockAtPath(state2.doc.blocks, wrapperPath);
|
|
2424
|
+
if (wrapper && wrapper.type === "block-wrapper") {
|
|
2425
|
+
blocks.push({
|
|
2426
|
+
type: "block-wrapper",
|
|
2427
|
+
kind: wrapper.kind,
|
|
2428
|
+
data: wrapper.data,
|
|
2429
|
+
blocks: [paragraph]
|
|
2430
|
+
});
|
|
2431
|
+
continue;
|
|
2432
|
+
}
|
|
2433
|
+
}
|
|
2434
|
+
blocks.push(paragraph);
|
|
2415
2435
|
}
|
|
2416
2436
|
const sliceDoc = {
|
|
2417
2437
|
blocks: blocks.length > 0 ? blocks : [{ type: "paragraph", content: [] }]
|
|
2418
2438
|
};
|
|
2419
2439
|
return serialize(normalize(sliceDoc)).source;
|
|
2420
2440
|
}
|
|
2441
|
+
function escapeHtml(text) {
|
|
2442
|
+
return text.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
2443
|
+
}
|
|
2444
|
+
function runsToHtml(runs) {
|
|
2445
|
+
var _a;
|
|
2446
|
+
let html = "";
|
|
2447
|
+
for (const run of runs) {
|
|
2448
|
+
let content = escapeHtml(run.text);
|
|
2449
|
+
const sortedMarks = [...run.marks].reverse();
|
|
2450
|
+
for (const mark of sortedMarks) {
|
|
2451
|
+
if (mark.kind === "bold") {
|
|
2452
|
+
content = `<strong>${content}</strong>`;
|
|
2453
|
+
} else if (mark.kind === "italic") {
|
|
2454
|
+
content = `<em>${content}</em>`;
|
|
2455
|
+
} else if (mark.kind === "strikethrough") {
|
|
2456
|
+
content = `<s>${content}</s>`;
|
|
2457
|
+
} else if (mark.kind === "link") {
|
|
2458
|
+
const url = ((_a = mark.data) == null ? void 0 : _a.url) ?? "";
|
|
2459
|
+
content = `<a href="${escapeHtml(url)}">${content}</a>`;
|
|
2460
|
+
}
|
|
2461
|
+
}
|
|
2462
|
+
html += content;
|
|
2463
|
+
}
|
|
2464
|
+
return html;
|
|
2465
|
+
}
|
|
2466
|
+
function serializeSelectionToHtml(state2, selection) {
|
|
2467
|
+
const normalized = normalizeSelection$1(selection);
|
|
2468
|
+
const lines = flattenDocToLines(state2.doc);
|
|
2469
|
+
const docCursorLength = cursorLengthForLines(lines);
|
|
2470
|
+
const cursorStart = Math.max(
|
|
2471
|
+
0,
|
|
2472
|
+
Math.min(docCursorLength, Math.min(normalized.start, normalized.end))
|
|
2473
|
+
);
|
|
2474
|
+
const cursorEnd = Math.max(
|
|
2475
|
+
0,
|
|
2476
|
+
Math.min(docCursorLength, Math.max(normalized.start, normalized.end))
|
|
2477
|
+
);
|
|
2478
|
+
if (cursorStart === cursorEnd) {
|
|
2479
|
+
return "";
|
|
2480
|
+
}
|
|
2481
|
+
const startLoc = resolveCursorToLine(lines, cursorStart);
|
|
2482
|
+
const endLoc = resolveCursorToLine(lines, cursorEnd);
|
|
2483
|
+
let html = "";
|
|
2484
|
+
let activeList = null;
|
|
2485
|
+
const closeList = () => {
|
|
2486
|
+
if (activeList) {
|
|
2487
|
+
html += `</${activeList.type}>`;
|
|
2488
|
+
activeList = null;
|
|
2489
|
+
}
|
|
2490
|
+
};
|
|
2491
|
+
const openList = (type, indent) => {
|
|
2492
|
+
if (activeList && activeList.type === type && activeList.indent === indent) {
|
|
2493
|
+
return;
|
|
2494
|
+
}
|
|
2495
|
+
closeList();
|
|
2496
|
+
html += `<${type}>`;
|
|
2497
|
+
activeList = { type, indent };
|
|
2498
|
+
};
|
|
2499
|
+
for (let lineIndex = startLoc.lineIndex; lineIndex <= endLoc.lineIndex; lineIndex += 1) {
|
|
2500
|
+
const line = lines[lineIndex];
|
|
2501
|
+
if (!line) {
|
|
2502
|
+
continue;
|
|
2503
|
+
}
|
|
2504
|
+
const block = getBlockAtPath(state2.doc.blocks, line.path);
|
|
2505
|
+
if (!block || block.type !== "paragraph") {
|
|
2506
|
+
continue;
|
|
2507
|
+
}
|
|
2508
|
+
const runs = paragraphToRuns(block);
|
|
2509
|
+
const startInLine = lineIndex === startLoc.lineIndex ? startLoc.offsetInLine : 0;
|
|
2510
|
+
const endInLine = lineIndex === endLoc.lineIndex ? endLoc.offsetInLine : line.cursorLength;
|
|
2511
|
+
const selectedRuns = sliceRuns(runs, startInLine, endInLine).selected;
|
|
2512
|
+
let wrapperKind = null;
|
|
2513
|
+
let wrapperData;
|
|
2514
|
+
if (line.path.length > 1) {
|
|
2515
|
+
const wrapperPath = line.path.slice(0, -1);
|
|
2516
|
+
const wrapper = getBlockAtPath(state2.doc.blocks, wrapperPath);
|
|
2517
|
+
if (wrapper && wrapper.type === "block-wrapper") {
|
|
2518
|
+
wrapperKind = wrapper.kind;
|
|
2519
|
+
wrapperData = wrapper.data;
|
|
2520
|
+
}
|
|
2521
|
+
}
|
|
2522
|
+
const plainText = runs.map((r) => r.text).join("");
|
|
2523
|
+
const listMatch = plainText.match(/^(\s*)([-*+]|\d+\.)( )(.*)$/);
|
|
2524
|
+
let lineHtml;
|
|
2525
|
+
if (listMatch && !wrapperKind) {
|
|
2526
|
+
const prefixLength = listMatch[1].length + listMatch[2].length + listMatch[3].length;
|
|
2527
|
+
const contentRuns = sliceRuns(runs, prefixLength, runs.reduce((sum, r) => sum + r.text.length, 0)).selected;
|
|
2528
|
+
lineHtml = runsToHtml(normalizeRuns(contentRuns));
|
|
2529
|
+
} else {
|
|
2530
|
+
lineHtml = runsToHtml(normalizeRuns(selectedRuns));
|
|
2531
|
+
}
|
|
2532
|
+
if (wrapperKind === "heading") {
|
|
2533
|
+
closeList();
|
|
2534
|
+
const level = Math.min(
|
|
2535
|
+
(wrapperData == null ? void 0 : wrapperData.level) ?? 1,
|
|
2536
|
+
6
|
|
2537
|
+
);
|
|
2538
|
+
html += `<h${level} style="margin:0">${lineHtml}</h${level}>`;
|
|
2539
|
+
} else if (wrapperKind === "bullet-list") {
|
|
2540
|
+
openList("ul", 0);
|
|
2541
|
+
html += `<li>${lineHtml}</li>`;
|
|
2542
|
+
} else if (wrapperKind === "numbered-list") {
|
|
2543
|
+
openList("ol", 0);
|
|
2544
|
+
html += `<li>${lineHtml}</li>`;
|
|
2545
|
+
} else if (wrapperKind === "blockquote") {
|
|
2546
|
+
closeList();
|
|
2547
|
+
html += `<blockquote>${lineHtml}</blockquote>`;
|
|
2548
|
+
} else if (listMatch) {
|
|
2549
|
+
const isNumbered = /^\d+\.$/.test(listMatch[2]);
|
|
2550
|
+
const indent = Math.floor(listMatch[1].length / 2);
|
|
2551
|
+
openList(isNumbered ? "ol" : "ul", indent);
|
|
2552
|
+
html += `<li>${lineHtml}</li>`;
|
|
2553
|
+
} else {
|
|
2554
|
+
closeList();
|
|
2555
|
+
html += `<div>${lineHtml}</div>`;
|
|
2556
|
+
}
|
|
2557
|
+
}
|
|
2558
|
+
closeList();
|
|
2559
|
+
if (!html) {
|
|
2560
|
+
return "";
|
|
2561
|
+
}
|
|
2562
|
+
return `<div>${html}</div>`;
|
|
2563
|
+
}
|
|
2421
2564
|
const runtime = {
|
|
2422
2565
|
extensions,
|
|
2423
2566
|
parse,
|
|
@@ -2425,6 +2568,7 @@ function createRuntime(extensions) {
|
|
|
2425
2568
|
createState,
|
|
2426
2569
|
updateSelection,
|
|
2427
2570
|
serializeSelection,
|
|
2571
|
+
serializeSelectionToHtml,
|
|
2428
2572
|
applyEdit
|
|
2429
2573
|
};
|
|
2430
2574
|
return runtime;
|
|
@@ -2579,7 +2723,7 @@ function normalizeNodes(result) {
|
|
|
2579
2723
|
}
|
|
2580
2724
|
return Array.isArray(result) ? result : [result];
|
|
2581
2725
|
}
|
|
2582
|
-
function renderDocContent(doc, extensions,
|
|
2726
|
+
function renderDocContent(doc, extensions, root) {
|
|
2583
2727
|
const runs = [];
|
|
2584
2728
|
let cursorOffset = 0;
|
|
2585
2729
|
let lineIndex = 0;
|
|
@@ -2599,7 +2743,60 @@ function renderDocContent(doc, extensions, _root) {
|
|
|
2599
2743
|
lineIndex += 1;
|
|
2600
2744
|
}
|
|
2601
2745
|
};
|
|
2602
|
-
function
|
|
2746
|
+
function getBlockKey(block) {
|
|
2747
|
+
if (block.type === "paragraph") {
|
|
2748
|
+
return "paragraph";
|
|
2749
|
+
}
|
|
2750
|
+
if (block.type === "block-wrapper") {
|
|
2751
|
+
return `block-wrapper:${block.kind}`;
|
|
2752
|
+
}
|
|
2753
|
+
if (block.type === "block-atom") {
|
|
2754
|
+
return `block-atom:${block.kind}`;
|
|
2755
|
+
}
|
|
2756
|
+
return "unknown";
|
|
2757
|
+
}
|
|
2758
|
+
function getElementKey(element) {
|
|
2759
|
+
if (element.hasAttribute("data-block")) {
|
|
2760
|
+
const blockType = element.getAttribute("data-block") ?? "unknown";
|
|
2761
|
+
const lineKind = element instanceof HTMLElement ? element.dataset.lineKind : null;
|
|
2762
|
+
if (lineKind && lineKind !== blockType) {
|
|
2763
|
+
return lineKind;
|
|
2764
|
+
}
|
|
2765
|
+
return blockType;
|
|
2766
|
+
}
|
|
2767
|
+
if (element.hasAttribute("data-block-wrapper")) {
|
|
2768
|
+
return `block-wrapper:${element.getAttribute("data-block-wrapper")}`;
|
|
2769
|
+
}
|
|
2770
|
+
if (element.hasAttribute("data-block-atom")) {
|
|
2771
|
+
return `block-atom:${element.getAttribute("data-block-atom")}`;
|
|
2772
|
+
}
|
|
2773
|
+
return "unknown";
|
|
2774
|
+
}
|
|
2775
|
+
function getInlineKey(inline) {
|
|
2776
|
+
if (inline.type === "text") {
|
|
2777
|
+
return "text";
|
|
2778
|
+
}
|
|
2779
|
+
if (inline.type === "inline-wrapper") {
|
|
2780
|
+
return `inline-wrapper:${inline.kind}`;
|
|
2781
|
+
}
|
|
2782
|
+
if (inline.type === "inline-atom") {
|
|
2783
|
+
return `inline-atom:${inline.kind}`;
|
|
2784
|
+
}
|
|
2785
|
+
return "unknown";
|
|
2786
|
+
}
|
|
2787
|
+
function getInlineElementKey(element) {
|
|
2788
|
+
if (element.classList.contains("cake-text")) {
|
|
2789
|
+
return "text";
|
|
2790
|
+
}
|
|
2791
|
+
if (element.hasAttribute("data-inline")) {
|
|
2792
|
+
return `inline-wrapper:${element.getAttribute("data-inline")}`;
|
|
2793
|
+
}
|
|
2794
|
+
if (element.hasAttribute("data-inline-atom")) {
|
|
2795
|
+
return `inline-atom:${element.getAttribute("data-inline-atom")}`;
|
|
2796
|
+
}
|
|
2797
|
+
return "unknown";
|
|
2798
|
+
}
|
|
2799
|
+
function reconcileInline(inline, existing) {
|
|
2603
2800
|
for (const extension of extensions) {
|
|
2604
2801
|
const render = extension.renderInline;
|
|
2605
2802
|
if (!render) {
|
|
@@ -2611,6 +2808,17 @@ function renderDocContent(doc, extensions, _root) {
|
|
|
2611
2808
|
}
|
|
2612
2809
|
}
|
|
2613
2810
|
if (inline.type === "text") {
|
|
2811
|
+
const canReuse = existing && existing instanceof HTMLSpanElement && getInlineElementKey(existing) === "text";
|
|
2812
|
+
if (canReuse) {
|
|
2813
|
+
const textNode = existing.firstChild;
|
|
2814
|
+
if (textNode instanceof Text) {
|
|
2815
|
+
if (textNode.textContent !== inline.text) {
|
|
2816
|
+
textNode.textContent = inline.text;
|
|
2817
|
+
}
|
|
2818
|
+
createTextRun$1(textNode);
|
|
2819
|
+
return [existing];
|
|
2820
|
+
}
|
|
2821
|
+
}
|
|
2614
2822
|
const element = document.createElement("span");
|
|
2615
2823
|
element.className = "cake-text";
|
|
2616
2824
|
const node = document.createTextNode(inline.text);
|
|
@@ -2619,16 +2827,29 @@ function renderDocContent(doc, extensions, _root) {
|
|
|
2619
2827
|
return [element];
|
|
2620
2828
|
}
|
|
2621
2829
|
if (inline.type === "inline-wrapper") {
|
|
2830
|
+
const canReuse = existing && existing instanceof HTMLSpanElement && getInlineElementKey(existing) === getInlineKey(inline);
|
|
2831
|
+
if (canReuse) {
|
|
2832
|
+
reconcileInlineChildren(existing, inline.children);
|
|
2833
|
+
return [existing];
|
|
2834
|
+
}
|
|
2622
2835
|
const element = document.createElement("span");
|
|
2623
2836
|
element.setAttribute("data-inline", inline.kind);
|
|
2624
2837
|
for (const child of inline.children) {
|
|
2625
|
-
for (const node of
|
|
2838
|
+
for (const node of reconcileInline(child, null)) {
|
|
2626
2839
|
element.append(node);
|
|
2627
2840
|
}
|
|
2628
2841
|
}
|
|
2629
2842
|
return [element];
|
|
2630
2843
|
}
|
|
2631
2844
|
if (inline.type === "inline-atom") {
|
|
2845
|
+
const canReuse = existing && existing instanceof HTMLSpanElement && getInlineElementKey(existing) === getInlineKey(inline);
|
|
2846
|
+
if (canReuse) {
|
|
2847
|
+
const textNode = existing.firstChild;
|
|
2848
|
+
if (textNode instanceof Text) {
|
|
2849
|
+
createTextRun$1(textNode);
|
|
2850
|
+
return [existing];
|
|
2851
|
+
}
|
|
2852
|
+
}
|
|
2632
2853
|
const element = document.createElement("span");
|
|
2633
2854
|
element.setAttribute("data-inline-atom", inline.kind);
|
|
2634
2855
|
const node = document.createTextNode(" ");
|
|
@@ -2638,7 +2859,25 @@ function renderDocContent(doc, extensions, _root) {
|
|
|
2638
2859
|
}
|
|
2639
2860
|
return [];
|
|
2640
2861
|
}
|
|
2641
|
-
function
|
|
2862
|
+
function reconcileInlineChildren(parent, inlines) {
|
|
2863
|
+
const mergedInlines = mergeInlineForRender(inlines);
|
|
2864
|
+
const existingChildren2 = Array.from(parent.children);
|
|
2865
|
+
const newChildren = [];
|
|
2866
|
+
mergedInlines.forEach((inline, i) => {
|
|
2867
|
+
const existingChild = existingChildren2[i] ?? null;
|
|
2868
|
+
const canReuse = existingChild && getInlineElementKey(existingChild) === getInlineKey(inline);
|
|
2869
|
+
const nodes = reconcileInline(inline, canReuse ? existingChild : null);
|
|
2870
|
+
newChildren.push(...nodes);
|
|
2871
|
+
});
|
|
2872
|
+
if (newChildren.length === existingChildren2.length && newChildren.every((node, i) => node === existingChildren2[i])) {
|
|
2873
|
+
return;
|
|
2874
|
+
}
|
|
2875
|
+
parent.replaceChildren(...newChildren);
|
|
2876
|
+
}
|
|
2877
|
+
function renderInline(inline) {
|
|
2878
|
+
return reconcileInline(inline, null);
|
|
2879
|
+
}
|
|
2880
|
+
function reconcileBlock(block, existing) {
|
|
2642
2881
|
for (const extension of extensions) {
|
|
2643
2882
|
const render = extension.renderBlock;
|
|
2644
2883
|
if (!render) {
|
|
@@ -2650,12 +2889,35 @@ function renderDocContent(doc, extensions, _root) {
|
|
|
2650
2889
|
}
|
|
2651
2890
|
}
|
|
2652
2891
|
if (block.type === "paragraph") {
|
|
2892
|
+
const canReuse = existing && existing instanceof HTMLDivElement && getElementKey(existing) === "paragraph";
|
|
2893
|
+
const currentLineIndex = context.getLineIndex();
|
|
2894
|
+
context.incrementLineIndex();
|
|
2895
|
+
if (canReuse) {
|
|
2896
|
+
existing.setAttribute("data-line-index", String(currentLineIndex));
|
|
2897
|
+
if (block.content.length === 0) {
|
|
2898
|
+
const firstChild = existing.firstChild;
|
|
2899
|
+
if (firstChild instanceof Text && existing.querySelector("br")) {
|
|
2900
|
+
if (firstChild.textContent !== "") {
|
|
2901
|
+
firstChild.textContent = "";
|
|
2902
|
+
}
|
|
2903
|
+
createTextRun$1(firstChild);
|
|
2904
|
+
return [existing];
|
|
2905
|
+
}
|
|
2906
|
+
existing.replaceChildren();
|
|
2907
|
+
const textNode = document.createTextNode("");
|
|
2908
|
+
createTextRun$1(textNode);
|
|
2909
|
+
existing.append(textNode);
|
|
2910
|
+
existing.append(document.createElement("br"));
|
|
2911
|
+
return [existing];
|
|
2912
|
+
}
|
|
2913
|
+
reconcileInlineChildren(existing, block.content);
|
|
2914
|
+
return [existing];
|
|
2915
|
+
}
|
|
2653
2916
|
const element = document.createElement("div");
|
|
2654
2917
|
element.setAttribute("data-block", "paragraph");
|
|
2655
|
-
element.setAttribute("data-line-index", String(
|
|
2918
|
+
element.setAttribute("data-line-index", String(currentLineIndex));
|
|
2656
2919
|
element.classList.add("cake-line");
|
|
2657
2920
|
element.dataset.lineKind = "paragraph";
|
|
2658
|
-
context.incrementLineIndex();
|
|
2659
2921
|
if (block.content.length === 0) {
|
|
2660
2922
|
const textNode = document.createTextNode("");
|
|
2661
2923
|
createTextRun$1(textNode);
|
|
@@ -2664,7 +2926,7 @@ function renderDocContent(doc, extensions, _root) {
|
|
|
2664
2926
|
} else {
|
|
2665
2927
|
const mergedContent = mergeInlineForRender(block.content);
|
|
2666
2928
|
for (const inline of mergedContent) {
|
|
2667
|
-
for (const node of
|
|
2929
|
+
for (const node of reconcileInline(inline, null)) {
|
|
2668
2930
|
element.append(node);
|
|
2669
2931
|
}
|
|
2670
2932
|
}
|
|
@@ -2672,6 +2934,11 @@ function renderDocContent(doc, extensions, _root) {
|
|
|
2672
2934
|
return [element];
|
|
2673
2935
|
}
|
|
2674
2936
|
if (block.type === "block-wrapper") {
|
|
2937
|
+
const canReuse = existing && existing instanceof HTMLDivElement && getElementKey(existing) === getBlockKey(block);
|
|
2938
|
+
if (canReuse) {
|
|
2939
|
+
reconcileBlockChildren(existing, block.blocks);
|
|
2940
|
+
return [existing];
|
|
2941
|
+
}
|
|
2675
2942
|
const element = document.createElement("div");
|
|
2676
2943
|
element.setAttribute("data-block-wrapper", block.kind);
|
|
2677
2944
|
for (const node of renderBlocks(block.blocks)) {
|
|
@@ -2680,15 +2947,41 @@ function renderDocContent(doc, extensions, _root) {
|
|
|
2680
2947
|
return [element];
|
|
2681
2948
|
}
|
|
2682
2949
|
if (block.type === "block-atom") {
|
|
2950
|
+
const canReuse = existing && existing instanceof HTMLDivElement && getElementKey(existing) === getBlockKey(block);
|
|
2951
|
+
const currentLineIndex = context.getLineIndex();
|
|
2952
|
+
context.incrementLineIndex();
|
|
2953
|
+
if (canReuse) {
|
|
2954
|
+
existing.setAttribute("data-line-index", String(currentLineIndex));
|
|
2955
|
+
return [existing];
|
|
2956
|
+
}
|
|
2683
2957
|
const element = document.createElement("div");
|
|
2684
2958
|
element.setAttribute("data-block-atom", block.kind);
|
|
2685
|
-
element.setAttribute("data-line-index", String(
|
|
2959
|
+
element.setAttribute("data-line-index", String(currentLineIndex));
|
|
2686
2960
|
element.classList.add("cake-line");
|
|
2687
|
-
context.incrementLineIndex();
|
|
2688
2961
|
return [element];
|
|
2689
2962
|
}
|
|
2690
2963
|
return [];
|
|
2691
2964
|
}
|
|
2965
|
+
function reconcileBlockChildren(parent, blocks) {
|
|
2966
|
+
const existingChildren2 = Array.from(parent.children);
|
|
2967
|
+
const newChildren = [];
|
|
2968
|
+
blocks.forEach((block, index) => {
|
|
2969
|
+
const existingChild = existingChildren2[index] ?? null;
|
|
2970
|
+
const canReuse = existingChild && getElementKey(existingChild) === getBlockKey(block);
|
|
2971
|
+
const nodes = reconcileBlock(block, canReuse ? existingChild : null);
|
|
2972
|
+
newChildren.push(...nodes);
|
|
2973
|
+
if (index < blocks.length - 1) {
|
|
2974
|
+
cursorOffset += 1;
|
|
2975
|
+
}
|
|
2976
|
+
});
|
|
2977
|
+
if (newChildren.length === existingChildren2.length && newChildren.every((node, i) => node === existingChildren2[i])) {
|
|
2978
|
+
return;
|
|
2979
|
+
}
|
|
2980
|
+
parent.replaceChildren(...newChildren);
|
|
2981
|
+
}
|
|
2982
|
+
function renderBlock(block) {
|
|
2983
|
+
return reconcileBlock(block, null);
|
|
2984
|
+
}
|
|
2692
2985
|
function renderBlocks(blocks) {
|
|
2693
2986
|
const nodes = [];
|
|
2694
2987
|
blocks.forEach((block, index) => {
|
|
@@ -2699,10 +2992,17 @@ function renderDocContent(doc, extensions, _root) {
|
|
|
2699
2992
|
});
|
|
2700
2993
|
return nodes;
|
|
2701
2994
|
}
|
|
2995
|
+
const existingChildren = root ? Array.from(root.children) : [];
|
|
2702
2996
|
const contentNodes = [];
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2997
|
+
doc.blocks.forEach((block, index) => {
|
|
2998
|
+
const existingChild = existingChildren[index] ?? null;
|
|
2999
|
+
const canReuse = existingChild && getElementKey(existingChild) === getBlockKey(block);
|
|
3000
|
+
const nodes = reconcileBlock(block, canReuse ? existingChild : null);
|
|
3001
|
+
contentNodes.push(...nodes);
|
|
3002
|
+
if (index < doc.blocks.length - 1) {
|
|
3003
|
+
cursorOffset += 1;
|
|
3004
|
+
}
|
|
3005
|
+
});
|
|
2706
3006
|
return { content: contentNodes, map: createDomMap(runs) };
|
|
2707
3007
|
}
|
|
2708
3008
|
function mergeInlineForRender(inlines) {
|
|
@@ -3224,13 +3524,13 @@ function CakeLinkPopover(params) {
|
|
|
3224
3524
|
if (state2.status !== "open") {
|
|
3225
3525
|
return;
|
|
3226
3526
|
}
|
|
3227
|
-
container.addEventListener("scroll",
|
|
3527
|
+
container.addEventListener("scroll", close, { passive: true });
|
|
3228
3528
|
window.addEventListener("resize", reposition);
|
|
3229
3529
|
return () => {
|
|
3230
|
-
container.removeEventListener("scroll",
|
|
3530
|
+
container.removeEventListener("scroll", close);
|
|
3231
3531
|
window.removeEventListener("resize", reposition);
|
|
3232
3532
|
};
|
|
3233
|
-
}, [container, reposition, state2.status]);
|
|
3533
|
+
}, [close, container, reposition, state2.status]);
|
|
3234
3534
|
const handleMouseDown = require$$0.useCallback(
|
|
3235
3535
|
(event) => {
|
|
3236
3536
|
event.stopPropagation();
|
|
@@ -3299,7 +3599,7 @@ function CakeLinkPopover(params) {
|
|
|
3299
3599
|
handleCancel();
|
|
3300
3600
|
}
|
|
3301
3601
|
};
|
|
3302
|
-
return /* @__PURE__ */
|
|
3602
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3303
3603
|
"div",
|
|
3304
3604
|
{
|
|
3305
3605
|
className: "cake-link-popover",
|
|
@@ -3312,7 +3612,7 @@ function CakeLinkPopover(params) {
|
|
|
3312
3612
|
},
|
|
3313
3613
|
onMouseDown: handleMouseDown,
|
|
3314
3614
|
onClick: (event) => event.stopPropagation(),
|
|
3315
|
-
children: state2.isEditing ? /* @__PURE__ */
|
|
3615
|
+
children: state2.isEditing ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
3316
3616
|
"form",
|
|
3317
3617
|
{
|
|
3318
3618
|
className: "cake-link-editor",
|
|
@@ -3321,7 +3621,7 @@ function CakeLinkPopover(params) {
|
|
|
3321
3621
|
handleSave();
|
|
3322
3622
|
},
|
|
3323
3623
|
children: [
|
|
3324
|
-
/* @__PURE__ */
|
|
3624
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3325
3625
|
"input",
|
|
3326
3626
|
{
|
|
3327
3627
|
className: "cake-link-input",
|
|
@@ -3338,56 +3638,24 @@ function CakeLinkPopover(params) {
|
|
|
3338
3638
|
},
|
|
3339
3639
|
onKeyDown: handleInputKeyDown,
|
|
3340
3640
|
placeholder: "https://"
|
|
3341
|
-
}
|
|
3342
|
-
void 0,
|
|
3343
|
-
false,
|
|
3344
|
-
{
|
|
3345
|
-
fileName: "/Users/moboudra/dev/blankpage/cake/src/cake/extensions/link/link-popover.tsx",
|
|
3346
|
-
lineNumber: 281,
|
|
3347
|
-
columnNumber: 11
|
|
3348
|
-
},
|
|
3349
|
-
this
|
|
3641
|
+
}
|
|
3350
3642
|
),
|
|
3351
|
-
/* @__PURE__ */
|
|
3352
|
-
|
|
3353
|
-
lineNumber: 297,
|
|
3354
|
-
columnNumber: 11
|
|
3355
|
-
}, this),
|
|
3356
|
-
/* @__PURE__ */ jsxDevRuntimeExports.jsxDEV(
|
|
3643
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "submit", className: "cake-link-save", children: "Save" }),
|
|
3644
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3357
3645
|
"button",
|
|
3358
3646
|
{
|
|
3359
3647
|
type: "button",
|
|
3360
3648
|
className: "cake-link-cancel",
|
|
3361
3649
|
onClick: handleCancel,
|
|
3362
3650
|
children: "Cancel"
|
|
3363
|
-
}
|
|
3364
|
-
void 0,
|
|
3365
|
-
false,
|
|
3366
|
-
{
|
|
3367
|
-
fileName: "/Users/moboudra/dev/blankpage/cake/src/cake/extensions/link/link-popover.tsx",
|
|
3368
|
-
lineNumber: 300,
|
|
3369
|
-
columnNumber: 11
|
|
3370
|
-
},
|
|
3371
|
-
this
|
|
3651
|
+
}
|
|
3372
3652
|
)
|
|
3373
3653
|
]
|
|
3374
|
-
}
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
{
|
|
3378
|
-
|
|
3379
|
-
lineNumber: 274,
|
|
3380
|
-
columnNumber: 9
|
|
3381
|
-
},
|
|
3382
|
-
this
|
|
3383
|
-
) : /* @__PURE__ */ jsxDevRuntimeExports.jsxDEV(jsxDevRuntimeExports.Fragment, { children: [
|
|
3384
|
-
/* @__PURE__ */ jsxDevRuntimeExports.jsxDEV("div", { className: "cake-link-url", title: displayUrl, children: displayUrl }, void 0, false, {
|
|
3385
|
-
fileName: "/Users/moboudra/dev/blankpage/cake/src/cake/extensions/link/link-popover.tsx",
|
|
3386
|
-
lineNumber: 310,
|
|
3387
|
-
columnNumber: 11
|
|
3388
|
-
}, this),
|
|
3389
|
-
/* @__PURE__ */ jsxDevRuntimeExports.jsxDEV("div", { className: "cake-link-actions", children: [
|
|
3390
|
-
/* @__PURE__ */ jsxDevRuntimeExports.jsxDEV(
|
|
3654
|
+
}
|
|
3655
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
3656
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "cake-link-url", title: displayUrl, children: displayUrl }),
|
|
3657
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "cake-link-actions", children: [
|
|
3658
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3391
3659
|
"button",
|
|
3392
3660
|
{
|
|
3393
3661
|
type: "button",
|
|
@@ -3395,22 +3663,10 @@ function CakeLinkPopover(params) {
|
|
|
3395
3663
|
onClick: handleEdit,
|
|
3396
3664
|
title: "Edit link",
|
|
3397
3665
|
"aria-label": "Edit link",
|
|
3398
|
-
children: /* @__PURE__ */
|
|
3399
|
-
|
|
3400
|
-
lineNumber: 321,
|
|
3401
|
-
columnNumber: 15
|
|
3402
|
-
}, this)
|
|
3403
|
-
},
|
|
3404
|
-
void 0,
|
|
3405
|
-
false,
|
|
3406
|
-
{
|
|
3407
|
-
fileName: "/Users/moboudra/dev/blankpage/cake/src/cake/extensions/link/link-popover.tsx",
|
|
3408
|
-
lineNumber: 314,
|
|
3409
|
-
columnNumber: 13
|
|
3410
|
-
},
|
|
3411
|
-
this
|
|
3666
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(lucideReact.Pencil, { className: "cake-link-icon" })
|
|
3667
|
+
}
|
|
3412
3668
|
),
|
|
3413
|
-
/* @__PURE__ */
|
|
3669
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3414
3670
|
"button",
|
|
3415
3671
|
{
|
|
3416
3672
|
type: "button",
|
|
@@ -3418,22 +3674,10 @@ function CakeLinkPopover(params) {
|
|
|
3418
3674
|
onClick: handleOpen,
|
|
3419
3675
|
title: "Open link",
|
|
3420
3676
|
"aria-label": "Open link",
|
|
3421
|
-
children: /* @__PURE__ */
|
|
3422
|
-
|
|
3423
|
-
lineNumber: 330,
|
|
3424
|
-
columnNumber: 15
|
|
3425
|
-
}, this)
|
|
3426
|
-
},
|
|
3427
|
-
void 0,
|
|
3428
|
-
false,
|
|
3429
|
-
{
|
|
3430
|
-
fileName: "/Users/moboudra/dev/blankpage/cake/src/cake/extensions/link/link-popover.tsx",
|
|
3431
|
-
lineNumber: 323,
|
|
3432
|
-
columnNumber: 13
|
|
3433
|
-
},
|
|
3434
|
-
this
|
|
3677
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(lucideReact.ExternalLink, { className: "cake-link-icon" })
|
|
3678
|
+
}
|
|
3435
3679
|
),
|
|
3436
|
-
/* @__PURE__ */
|
|
3680
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3437
3681
|
"button",
|
|
3438
3682
|
{
|
|
3439
3683
|
type: "button",
|
|
@@ -3441,40 +3685,12 @@ function CakeLinkPopover(params) {
|
|
|
3441
3685
|
onClick: handleUnlink,
|
|
3442
3686
|
title: "Remove link",
|
|
3443
3687
|
"aria-label": "Remove link",
|
|
3444
|
-
children: /* @__PURE__ */
|
|
3445
|
-
|
|
3446
|
-
lineNumber: 339,
|
|
3447
|
-
columnNumber: 15
|
|
3448
|
-
}, this)
|
|
3449
|
-
},
|
|
3450
|
-
void 0,
|
|
3451
|
-
false,
|
|
3452
|
-
{
|
|
3453
|
-
fileName: "/Users/moboudra/dev/blankpage/cake/src/cake/extensions/link/link-popover.tsx",
|
|
3454
|
-
lineNumber: 332,
|
|
3455
|
-
columnNumber: 13
|
|
3456
|
-
},
|
|
3457
|
-
this
|
|
3688
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(lucideReact.Unlink, { className: "cake-link-icon" })
|
|
3689
|
+
}
|
|
3458
3690
|
)
|
|
3459
|
-
] }
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
columnNumber: 11
|
|
3463
|
-
}, this)
|
|
3464
|
-
] }, void 0, true, {
|
|
3465
|
-
fileName: "/Users/moboudra/dev/blankpage/cake/src/cake/extensions/link/link-popover.tsx",
|
|
3466
|
-
lineNumber: 309,
|
|
3467
|
-
columnNumber: 9
|
|
3468
|
-
}, this)
|
|
3469
|
-
},
|
|
3470
|
-
void 0,
|
|
3471
|
-
false,
|
|
3472
|
-
{
|
|
3473
|
-
fileName: "/Users/moboudra/dev/blankpage/cake/src/cake/extensions/link/link-popover.tsx",
|
|
3474
|
-
lineNumber: 261,
|
|
3475
|
-
columnNumber: 5
|
|
3476
|
-
},
|
|
3477
|
-
this
|
|
3691
|
+
] })
|
|
3692
|
+
] })
|
|
3693
|
+
}
|
|
3478
3694
|
);
|
|
3479
3695
|
}
|
|
3480
3696
|
function buildLayoutModel(lines, measurer) {
|
|
@@ -3823,21 +4039,13 @@ const linkExtension = {
|
|
|
3823
4039
|
if (!context.contentRoot || !context.toOverlayRect) {
|
|
3824
4040
|
return null;
|
|
3825
4041
|
}
|
|
3826
|
-
return /* @__PURE__ */
|
|
4042
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3827
4043
|
CakeLinkPopover,
|
|
3828
4044
|
{
|
|
3829
4045
|
container: context.container,
|
|
3830
4046
|
contentRoot: context.contentRoot,
|
|
3831
4047
|
toOverlayRect: context.toOverlayRect
|
|
3832
|
-
}
|
|
3833
|
-
void 0,
|
|
3834
|
-
false,
|
|
3835
|
-
{
|
|
3836
|
-
fileName: "/Users/moboudra/dev/blankpage/cake/src/cake/extensions/link/link.tsx",
|
|
3837
|
-
lineNumber: 179,
|
|
3838
|
-
columnNumber: 7
|
|
3839
|
-
},
|
|
3840
|
-
this
|
|
4048
|
+
}
|
|
3841
4049
|
);
|
|
3842
4050
|
}
|
|
3843
4051
|
};
|
|
@@ -5337,6 +5545,7 @@ function ScrollbarOverlay({ container }) {
|
|
|
5337
5545
|
const [isDragging, setIsDragging] = require$$0.useState(false);
|
|
5338
5546
|
const [isHovered, setIsHovered] = require$$0.useState(false);
|
|
5339
5547
|
const [isScrolling, setIsScrolling] = require$$0.useState(false);
|
|
5548
|
+
const [isDarkMode, setIsDarkMode] = require$$0.useState(false);
|
|
5340
5549
|
const dragStartRef = require$$0.useRef(
|
|
5341
5550
|
null
|
|
5342
5551
|
);
|
|
@@ -5351,6 +5560,24 @@ function ScrollbarOverlay({ container }) {
|
|
|
5351
5560
|
);
|
|
5352
5561
|
const maxScrollTop = scrollHeight - clientHeight;
|
|
5353
5562
|
const thumbTop = maxScrollTop > 0 ? TRACK_PADDING + scrollTop / maxScrollTop * (trackHeight - thumbHeight) : TRACK_PADDING;
|
|
5563
|
+
require$$0.useEffect(() => {
|
|
5564
|
+
function checkDarkMode() {
|
|
5565
|
+
const html = document.documentElement;
|
|
5566
|
+
setIsDarkMode(html.classList.contains("dark"));
|
|
5567
|
+
}
|
|
5568
|
+
checkDarkMode();
|
|
5569
|
+
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
5570
|
+
mediaQuery.addEventListener("change", checkDarkMode);
|
|
5571
|
+
const observer = new MutationObserver(checkDarkMode);
|
|
5572
|
+
observer.observe(document.documentElement, {
|
|
5573
|
+
attributes: true,
|
|
5574
|
+
attributeFilter: ["class"]
|
|
5575
|
+
});
|
|
5576
|
+
return () => {
|
|
5577
|
+
mediaQuery.removeEventListener("change", checkDarkMode);
|
|
5578
|
+
observer.disconnect();
|
|
5579
|
+
};
|
|
5580
|
+
}, []);
|
|
5354
5581
|
require$$0.useEffect(() => {
|
|
5355
5582
|
function update() {
|
|
5356
5583
|
setState({
|
|
@@ -5488,6 +5715,13 @@ function ScrollbarOverlay({ container }) {
|
|
|
5488
5715
|
return null;
|
|
5489
5716
|
}
|
|
5490
5717
|
const isVisible = isDragging || isHovered || isScrolling;
|
|
5718
|
+
const wrapperStyle = {
|
|
5719
|
+
position: "absolute",
|
|
5720
|
+
inset: 0,
|
|
5721
|
+
pointerEvents: "none",
|
|
5722
|
+
overflow: "hidden",
|
|
5723
|
+
zIndex: 50
|
|
5724
|
+
};
|
|
5491
5725
|
const trackStyle = {
|
|
5492
5726
|
position: "absolute",
|
|
5493
5727
|
top: 0,
|
|
@@ -5497,6 +5731,12 @@ function ScrollbarOverlay({ container }) {
|
|
|
5497
5731
|
height: clientHeight,
|
|
5498
5732
|
pointerEvents: "auto"
|
|
5499
5733
|
};
|
|
5734
|
+
const getThumbColor = () => {
|
|
5735
|
+
if (isDarkMode) {
|
|
5736
|
+
return isDragging ? "rgba(255, 255, 255, 0.5)" : "rgba(255, 255, 255, 0.3)";
|
|
5737
|
+
}
|
|
5738
|
+
return isDragging ? "rgba(0, 0, 0, 0.5)" : "rgba(0, 0, 0, 0.3)";
|
|
5739
|
+
};
|
|
5500
5740
|
const thumbStyle = {
|
|
5501
5741
|
position: "absolute",
|
|
5502
5742
|
right: "2px",
|
|
@@ -5504,54 +5744,35 @@ function ScrollbarOverlay({ container }) {
|
|
|
5504
5744
|
borderRadius: "9999px",
|
|
5505
5745
|
height: thumbHeight,
|
|
5506
5746
|
top: thumbTop,
|
|
5507
|
-
opacity: isVisible ? 1 : 0
|
|
5747
|
+
opacity: isVisible ? 1 : 0,
|
|
5748
|
+
backgroundColor: getThumbColor(),
|
|
5749
|
+
transition: "opacity 150ms",
|
|
5750
|
+
cursor: "pointer"
|
|
5508
5751
|
};
|
|
5509
|
-
return /* @__PURE__ */
|
|
5752
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: wrapperStyle, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5510
5753
|
"div",
|
|
5511
5754
|
{
|
|
5512
5755
|
"data-testid": "custom-scrollbar",
|
|
5513
5756
|
"aria-hidden": "true",
|
|
5514
|
-
className: "pointer-events-auto absolute top-0 right-0 bottom-0 z-50 w-3",
|
|
5515
5757
|
style: trackStyle,
|
|
5516
5758
|
onClick: handleTrackClick,
|
|
5517
5759
|
onMouseEnter: () => setIsHovered(true),
|
|
5518
5760
|
onMouseLeave: () => setIsHovered(false),
|
|
5519
|
-
children: /* @__PURE__ */
|
|
5761
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5520
5762
|
"div",
|
|
5521
5763
|
{
|
|
5522
5764
|
"data-testid": "scrollbar-thumb",
|
|
5523
|
-
className: `absolute right-0.5 w-1.5 cursor-pointer rounded-full transition-opacity duration-150 ${isDragging ? "bg-black/50 dark:bg-white/50" : "bg-black/30 dark:bg-white/30"}`,
|
|
5524
5765
|
style: thumbStyle,
|
|
5525
5766
|
onMouseDown: handleThumbMouseDown
|
|
5526
|
-
}
|
|
5527
|
-
void 0,
|
|
5528
|
-
false,
|
|
5529
|
-
{
|
|
5530
|
-
fileName: "/Users/moboudra/dev/blankpage/cake/src/cake/extensions/scrollbar/index.tsx",
|
|
5531
|
-
lineNumber: 230,
|
|
5532
|
-
columnNumber: 7
|
|
5533
|
-
},
|
|
5534
|
-
this
|
|
5767
|
+
}
|
|
5535
5768
|
)
|
|
5536
|
-
}
|
|
5537
|
-
|
|
5538
|
-
false,
|
|
5539
|
-
{
|
|
5540
|
-
fileName: "/Users/moboudra/dev/blankpage/cake/src/cake/extensions/scrollbar/index.tsx",
|
|
5541
|
-
lineNumber: 221,
|
|
5542
|
-
columnNumber: 5
|
|
5543
|
-
},
|
|
5544
|
-
this
|
|
5545
|
-
);
|
|
5769
|
+
}
|
|
5770
|
+
) });
|
|
5546
5771
|
}
|
|
5547
5772
|
const scrollbarExtension = {
|
|
5548
5773
|
name: "scrollbar",
|
|
5549
5774
|
renderOverlay(context) {
|
|
5550
|
-
return /* @__PURE__ */
|
|
5551
|
-
fileName: "/Users/moboudra/dev/blankpage/cake/src/cake/extensions/scrollbar/index.tsx",
|
|
5552
|
-
lineNumber: 247,
|
|
5553
|
-
columnNumber: 12
|
|
5554
|
-
}, this);
|
|
5775
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollbarOverlay, { container: context.container });
|
|
5555
5776
|
}
|
|
5556
5777
|
};
|
|
5557
5778
|
const STRIKE_KIND = "strikethrough";
|
|
@@ -6069,7 +6290,7 @@ function computeSelectionRects(layout, selection, measurer) {
|
|
|
6069
6290
|
return rects;
|
|
6070
6291
|
}
|
|
6071
6292
|
function computeCaretRect(caret) {
|
|
6072
|
-
const height = caret.
|
|
6293
|
+
const height = caret.fontSize * 1.2;
|
|
6073
6294
|
const contentHeight = caret.lineRect.height > 0 ? Math.max(
|
|
6074
6295
|
0,
|
|
6075
6296
|
caret.lineRect.height - caret.padding.top - caret.padding.bottom
|
|
@@ -6123,6 +6344,7 @@ function getSelectionGeometry(params) {
|
|
|
6123
6344
|
scroll
|
|
6124
6345
|
}),
|
|
6125
6346
|
lineLength: lineInfo.cursorLength,
|
|
6347
|
+
fontSize: getComputedFontSize(lineElement),
|
|
6126
6348
|
padding: getComputedVerticalPadding(lineElement)
|
|
6127
6349
|
};
|
|
6128
6350
|
const caretRect = computeCaretRect(caretMeasurement);
|
|
@@ -6166,6 +6388,7 @@ function getSelectionGeometry(params) {
|
|
|
6166
6388
|
scroll
|
|
6167
6389
|
}),
|
|
6168
6390
|
lineLength: lineInfo.cursorLength,
|
|
6391
|
+
fontSize: getComputedFontSize(focusLineElement),
|
|
6169
6392
|
padding: getComputedVerticalPadding(focusLineElement)
|
|
6170
6393
|
};
|
|
6171
6394
|
focusRect = computeCaretRect(caretMeasurement);
|
|
@@ -6292,6 +6515,11 @@ function getComputedVerticalPadding(lineElement) {
|
|
|
6292
6515
|
bottom: Number.isFinite(bottom) ? bottom : 0
|
|
6293
6516
|
};
|
|
6294
6517
|
}
|
|
6518
|
+
function getComputedFontSize(lineElement) {
|
|
6519
|
+
const fontSize = window.getComputedStyle(lineElement).fontSize;
|
|
6520
|
+
const parsed = Number.parseFloat(fontSize);
|
|
6521
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : 16;
|
|
6522
|
+
}
|
|
6295
6523
|
function rectRight(rect) {
|
|
6296
6524
|
return rect.left + rect.width;
|
|
6297
6525
|
}
|
|
@@ -6689,6 +6917,36 @@ function nextWordBreak(text, offset) {
|
|
|
6689
6917
|
}
|
|
6690
6918
|
return text.length;
|
|
6691
6919
|
}
|
|
6920
|
+
const MAX_HTML_INPUT_LENGTH = 5e5;
|
|
6921
|
+
const MAX_MARKDOWN_OUTPUT_LENGTH = 1e5;
|
|
6922
|
+
function isHTMLElement(node) {
|
|
6923
|
+
return node !== null && node.nodeType === Node.ELEMENT_NODE;
|
|
6924
|
+
}
|
|
6925
|
+
function isElement(node) {
|
|
6926
|
+
return node !== null && node.nodeType === Node.ELEMENT_NODE;
|
|
6927
|
+
}
|
|
6928
|
+
const CLEANUP_PATTERNS = {
|
|
6929
|
+
unescapeHeaders: /^\\(#{1,6})\s+/gm,
|
|
6930
|
+
unescapeBlockquote: /^\\>/gm,
|
|
6931
|
+
unescapeMarkdown: /\\([*_`~[\]])/g,
|
|
6932
|
+
unescapeListBullets: /^(\s*)\\([-*+])(\s+)/gm,
|
|
6933
|
+
unescapeListNumbers: /^(\s*)(\d+)\\\.(\s+)/gm,
|
|
6934
|
+
normalizeBullets: /^(\s*)[-*+](\s{2,})/gm,
|
|
6935
|
+
normalizeNumbers: /^[\s]*\d+\.[\s]+/gm,
|
|
6936
|
+
normalizeHeaders: /^(#{1,6})[\s]{2,}/gm,
|
|
6937
|
+
removeTrailingSpaces: /[ \t]+$/gm,
|
|
6938
|
+
headersInBlockquotes: /^>\s*(#{1,6}\s+.*)/gm,
|
|
6939
|
+
excessiveNewlines: /\n{3,}/g,
|
|
6940
|
+
interlacedTableGaps: /(\|[^\n]*\|)\s*\n\s*\n+\s*(\|[^\n]*\|)/g,
|
|
6941
|
+
complexTableGaps: /(\|[^\n]*\|)(\s*\n){2,}(\|[^\n]*\|)/g
|
|
6942
|
+
};
|
|
6943
|
+
const HTML_PREPROCESSING_PATTERNS = {
|
|
6944
|
+
removeStyleAndDataAttrs: /\s(?:style|data-[^=]*|id)="[^"]*"/gi,
|
|
6945
|
+
removeNonCodeClasses: /\sclass="(?![^"]*(?:language-|hljs))[^"]*"/gi,
|
|
6946
|
+
removeEmptyElements: /<(\w+)[^>]*>\s*<\/\1>/gi,
|
|
6947
|
+
normalizeSpaces: /[ \t]{2,}/g,
|
|
6948
|
+
reduceBlankLines: /\n\s*\n/g
|
|
6949
|
+
};
|
|
6692
6950
|
const turndownService = new TurndownService({
|
|
6693
6951
|
headingStyle: "atx",
|
|
6694
6952
|
bulletListMarker: "-",
|
|
@@ -6706,6 +6964,13 @@ turndownService.addRule("strikethrough", {
|
|
|
6706
6964
|
turndownService.addRule("codeBlock", {
|
|
6707
6965
|
filter: "pre",
|
|
6708
6966
|
replacement: (content, node) => {
|
|
6967
|
+
if (!isHTMLElement(node)) {
|
|
6968
|
+
return `
|
|
6969
|
+
\`\`\`
|
|
6970
|
+
${content}
|
|
6971
|
+
\`\`\`
|
|
6972
|
+
`;
|
|
6973
|
+
}
|
|
6709
6974
|
const codeElement = node.querySelector("code");
|
|
6710
6975
|
if (codeElement) {
|
|
6711
6976
|
const className = codeElement.className || "";
|
|
@@ -6724,12 +6989,308 @@ ${content}
|
|
|
6724
6989
|
`;
|
|
6725
6990
|
}
|
|
6726
6991
|
});
|
|
6727
|
-
|
|
6728
|
-
|
|
6729
|
-
|
|
6992
|
+
turndownService.addRule("tableRow", {
|
|
6993
|
+
filter: "tr",
|
|
6994
|
+
replacement: (_content, node) => {
|
|
6995
|
+
var _a;
|
|
6996
|
+
if (!isHTMLElement(node)) {
|
|
6997
|
+
return "";
|
|
6998
|
+
}
|
|
6999
|
+
const isHeaderRow = ((_a = node.parentNode) == null ? void 0 : _a.nodeName) === "THEAD";
|
|
7000
|
+
const cells = Array.from(node.querySelectorAll("td, th"));
|
|
7001
|
+
const cellContents = cells.map((cell) => {
|
|
7002
|
+
const text = cell.textContent || "";
|
|
7003
|
+
return text.replace(/\|/g, "\\|").trim();
|
|
7004
|
+
});
|
|
7005
|
+
let result = "| " + cellContents.join(" | ") + " |\n";
|
|
7006
|
+
if (isHeaderRow) {
|
|
7007
|
+
const separators = cells.map((cell) => {
|
|
7008
|
+
const align = cell.getAttribute("align");
|
|
7009
|
+
if (align === "center") {
|
|
7010
|
+
return ":-------------:";
|
|
7011
|
+
}
|
|
7012
|
+
if (align === "right") {
|
|
7013
|
+
return "-------------:";
|
|
7014
|
+
}
|
|
7015
|
+
return "-------------";
|
|
7016
|
+
});
|
|
7017
|
+
result += "| " + separators.join(" | ") + " |\n";
|
|
7018
|
+
}
|
|
7019
|
+
return result;
|
|
7020
|
+
}
|
|
7021
|
+
});
|
|
7022
|
+
turndownService.addRule("taskList", {
|
|
7023
|
+
filter: (node) => {
|
|
7024
|
+
if (!isHTMLElement(node)) {
|
|
7025
|
+
return false;
|
|
7026
|
+
}
|
|
7027
|
+
if (node.nodeName !== "LI") {
|
|
7028
|
+
return false;
|
|
7029
|
+
}
|
|
7030
|
+
if (node.querySelector('input[type="checkbox"]') !== null) {
|
|
7031
|
+
return true;
|
|
7032
|
+
}
|
|
7033
|
+
const textContent = node.textContent || "";
|
|
7034
|
+
const hasCheckboxSymbols = /^[\s]*[☐☑✓✗[\]]/m.test(textContent) || /^[\s]*\[[ x]\]/m.test(textContent);
|
|
7035
|
+
const hasCheckboxClass = Boolean(
|
|
7036
|
+
node.className && (node.className.includes("task") || node.className.includes("checkbox") || node.className.includes("todo"))
|
|
7037
|
+
);
|
|
7038
|
+
return hasCheckboxSymbols || hasCheckboxClass;
|
|
7039
|
+
},
|
|
7040
|
+
replacement: (content, node) => {
|
|
7041
|
+
if (!isHTMLElement(node)) {
|
|
7042
|
+
return content;
|
|
7043
|
+
}
|
|
7044
|
+
const checkbox = node.querySelector('input[type="checkbox"]');
|
|
7045
|
+
const isCheckbox = checkbox instanceof HTMLInputElement && checkbox.type === "checkbox";
|
|
7046
|
+
let isChecked = false;
|
|
7047
|
+
if (isCheckbox) {
|
|
7048
|
+
isChecked = checkbox.checked;
|
|
7049
|
+
} else {
|
|
7050
|
+
const textContent2 = node.textContent || "";
|
|
7051
|
+
isChecked = /^[\s]*[☑✓✗]/.test(textContent2) || /^[\s]*\[x\]/i.test(textContent2);
|
|
7052
|
+
}
|
|
7053
|
+
const prefix = isChecked ? "- [x] " : "- [ ] ";
|
|
7054
|
+
let textContent = content;
|
|
7055
|
+
textContent = textContent.replace(/^\s*\[[ x]\]\s*/gi, "");
|
|
7056
|
+
textContent = textContent.replace(/^\s*[☐☑✓✗]\s*/g, "");
|
|
7057
|
+
textContent = textContent.replace(/^\s*\[[x ]\]\s*/gi, "");
|
|
7058
|
+
textContent = textContent.replace(/^\s*\\?\[[ x]\\?\]\s*/gi, "");
|
|
7059
|
+
textContent = textContent.replace(/\\?\[\\?\s*\\?\]\\?\s*/g, "");
|
|
7060
|
+
return prefix + textContent.trim() + "\n";
|
|
7061
|
+
}
|
|
7062
|
+
});
|
|
7063
|
+
turndownService.addRule("list", {
|
|
7064
|
+
filter: ["ul", "ol"],
|
|
7065
|
+
replacement: (content, node) => {
|
|
7066
|
+
const parent = node.parentNode;
|
|
7067
|
+
const isNested = isElement(parent) && parent.tagName === "LI";
|
|
7068
|
+
if (isNested) {
|
|
7069
|
+
return "\n" + content;
|
|
7070
|
+
}
|
|
7071
|
+
return "\n" + content + "\n";
|
|
7072
|
+
}
|
|
7073
|
+
});
|
|
7074
|
+
turndownService.addRule("blockquote", {
|
|
7075
|
+
filter: "blockquote",
|
|
7076
|
+
replacement: (content) => {
|
|
7077
|
+
const lines = content.trim().split("\n");
|
|
7078
|
+
const processedLines = lines.map((line) => {
|
|
7079
|
+
const trimmed = line.trim();
|
|
7080
|
+
if (!trimmed) {
|
|
7081
|
+
return ">";
|
|
7082
|
+
}
|
|
7083
|
+
const existingQuotes = trimmed.match(/^(>\s*)+/);
|
|
7084
|
+
if (existingQuotes) {
|
|
7085
|
+
return existingQuotes[0] + " " + trimmed;
|
|
7086
|
+
}
|
|
7087
|
+
return "> " + trimmed;
|
|
7088
|
+
});
|
|
7089
|
+
return "\n" + processedLines.join("\n") + "\n";
|
|
7090
|
+
}
|
|
7091
|
+
});
|
|
7092
|
+
turndownService.addRule("horizontalRule", {
|
|
7093
|
+
filter: "hr",
|
|
7094
|
+
replacement: () => "\n---\n"
|
|
7095
|
+
});
|
|
7096
|
+
turndownService.addRule("inlineCode", {
|
|
7097
|
+
filter: (node) => {
|
|
7098
|
+
const parent = node.parentNode;
|
|
7099
|
+
return node.nodeName === "CODE" && !(isElement(parent) && parent.tagName === "PRE");
|
|
7100
|
+
},
|
|
7101
|
+
replacement: (content) => {
|
|
7102
|
+
const backtickCount = Math.max(
|
|
7103
|
+
1,
|
|
7104
|
+
(content.match(/`+/g) || []).reduce(
|
|
7105
|
+
(max, match) => Math.max(max, match.length),
|
|
7106
|
+
0
|
|
7107
|
+
) + 1
|
|
7108
|
+
);
|
|
7109
|
+
const delimiter = "`".repeat(backtickCount);
|
|
7110
|
+
return delimiter + content + delimiter;
|
|
7111
|
+
}
|
|
7112
|
+
});
|
|
7113
|
+
turndownService.addRule("image", {
|
|
7114
|
+
filter: "img",
|
|
7115
|
+
replacement: (_content, node) => {
|
|
7116
|
+
if (!isHTMLElement(node)) {
|
|
7117
|
+
return "";
|
|
7118
|
+
}
|
|
7119
|
+
const src = node.getAttribute("src") || "";
|
|
7120
|
+
const alt = node.getAttribute("alt") || "";
|
|
7121
|
+
const title = node.getAttribute("title");
|
|
7122
|
+
if (title) {
|
|
7123
|
+
return ``;
|
|
7124
|
+
}
|
|
7125
|
+
return ``;
|
|
7126
|
+
}
|
|
7127
|
+
});
|
|
7128
|
+
turndownService.addRule("highlight", {
|
|
7129
|
+
filter: (node) => {
|
|
7130
|
+
var _a, _b;
|
|
7131
|
+
if (!isHTMLElement(node)) {
|
|
7132
|
+
return false;
|
|
7133
|
+
}
|
|
7134
|
+
return node.nodeName === "MARK" || node.nodeName === "SPAN" && (((_a = node.style) == null ? void 0 : _a.backgroundColor) === "yellow" || ((_b = node.className) == null ? void 0 : _b.includes("highlight")));
|
|
7135
|
+
},
|
|
7136
|
+
replacement: (content) => `==${content}==`
|
|
7137
|
+
});
|
|
7138
|
+
turndownService.addRule("headerWithId", {
|
|
7139
|
+
filter: ["h1", "h2", "h3", "h4", "h5", "h6"],
|
|
7140
|
+
replacement: (content, node) => {
|
|
7141
|
+
if (!isHTMLElement(node)) {
|
|
7142
|
+
return content;
|
|
7143
|
+
}
|
|
7144
|
+
const rawLevel = parseInt(node.nodeName.charAt(1));
|
|
7145
|
+
const level = Math.min(rawLevel, 3);
|
|
7146
|
+
const hashes = "#".repeat(level);
|
|
7147
|
+
const id = node.getAttribute("id");
|
|
7148
|
+
if (id) {
|
|
7149
|
+
return `
|
|
7150
|
+
${hashes} ${content} {#${id}}
|
|
7151
|
+
`;
|
|
7152
|
+
}
|
|
7153
|
+
return `
|
|
7154
|
+
${hashes} ${content}
|
|
7155
|
+
`;
|
|
7156
|
+
}
|
|
7157
|
+
});
|
|
7158
|
+
function processTextNodes(element) {
|
|
7159
|
+
const spans = Array.from(element.querySelectorAll("span"));
|
|
7160
|
+
spans.forEach((span) => {
|
|
7161
|
+
var _a;
|
|
7162
|
+
const textContent = span.textContent || "";
|
|
7163
|
+
const textNode = document.createTextNode(textContent);
|
|
7164
|
+
(_a = span.parentNode) == null ? void 0 : _a.replaceChild(textNode, span);
|
|
7165
|
+
});
|
|
7166
|
+
}
|
|
7167
|
+
function detectSourceApp(html) {
|
|
7168
|
+
const detectionPatterns = {
|
|
7169
|
+
notion: ["notion-", "notranslate"],
|
|
7170
|
+
github: ["github.com", "js-file-line-container"],
|
|
7171
|
+
slack: ["slack-", "c-message"],
|
|
7172
|
+
"google-docs": ["docs.google.com", "kix-"]
|
|
7173
|
+
};
|
|
7174
|
+
for (const [app, patterns] of Object.entries(detectionPatterns)) {
|
|
7175
|
+
if (patterns.some((pattern) => html.includes(pattern))) {
|
|
7176
|
+
return app;
|
|
7177
|
+
}
|
|
7178
|
+
}
|
|
7179
|
+
return "unknown";
|
|
7180
|
+
}
|
|
7181
|
+
function preprocessForApp(html, app) {
|
|
7182
|
+
switch (app) {
|
|
7183
|
+
case "notion":
|
|
7184
|
+
return html.replace(/<div[^>]*class="[^"]*notion-[^"]*"[^>]*>/gi, "<div>").replace(/<span[^>]*class="[^"]*notion-[^"]*"[^>]*>/gi, "<span>").replace(/<details[^>]*>/gi, "<div>").replace(/<\/details>/gi, "</div>").replace(/<summary[^>]*>/gi, "<strong>").replace(/<\/summary>/gi, "</strong>");
|
|
7185
|
+
case "github":
|
|
7186
|
+
return html.replace(/<td[^>]*class="[^"]*blob-num[^"]*"[^>]*>.*?<\/td>/gi, "").replace(/<span[^>]*class="[^"]*pl-[^"]*"[^>]*>/gi, "<span>").replace(/<span[^>]*class="[^"]*highlight[^"]*"[^>]*>/gi, "<span>");
|
|
7187
|
+
case "slack":
|
|
7188
|
+
return html.replace(/<span[^>]*class="[^"]*c-member[^"]*"[^>]*>/gi, "<span>").replace(/<span[^>]*data-stringify-type="mention"[^>]*>/gi, "<span>").replace(
|
|
7189
|
+
/<span[^>]*class="[^"]*c-emoji[^"]*"[^>]*>([^<]*)<\/span>/gi,
|
|
7190
|
+
"$1"
|
|
7191
|
+
);
|
|
7192
|
+
case "google-docs":
|
|
7193
|
+
return html.replace(
|
|
7194
|
+
/<span[^>]*style="[^"]*font-weight:[^;"]*bold[^"]*"[^>]*>/gi,
|
|
7195
|
+
"<strong>"
|
|
7196
|
+
).replace(
|
|
7197
|
+
/<span[^>]*style="[^"]*font-style:[^;"]*italic[^"]*"[^>]*>/gi,
|
|
7198
|
+
"<em>"
|
|
7199
|
+
).replace(/<\/span>/gi, "").replace(/<p[^>]*style="[^"]*"[^>]*>/gi, "<p>");
|
|
7200
|
+
default:
|
|
7201
|
+
return html;
|
|
7202
|
+
}
|
|
7203
|
+
}
|
|
7204
|
+
function cleanupMarkdown(markdown) {
|
|
7205
|
+
return markdown.replace(CLEANUP_PATTERNS.unescapeHeaders, "$1 ").replace(CLEANUP_PATTERNS.unescapeBlockquote, ">").replace(CLEANUP_PATTERNS.unescapeMarkdown, "$1").replace(CLEANUP_PATTERNS.unescapeListBullets, "$1$2$3").replace(CLEANUP_PATTERNS.unescapeListNumbers, "$1$2.$3").replace(CLEANUP_PATTERNS.normalizeBullets, "$1- ").replace(CLEANUP_PATTERNS.normalizeNumbers, (match) => {
|
|
7206
|
+
var _a;
|
|
7207
|
+
const num = ((_a = match.match(/\d+/)) == null ? void 0 : _a[0]) || "1";
|
|
7208
|
+
return `${num}. `;
|
|
7209
|
+
}).replace(CLEANUP_PATTERNS.normalizeHeaders, "$1 ").replace(CLEANUP_PATTERNS.removeTrailingSpaces, "").replace(CLEANUP_PATTERNS.headersInBlockquotes, "\n$1").replace(CLEANUP_PATTERNS.excessiveNewlines, "\n\n").replace(CLEANUP_PATTERNS.interlacedTableGaps, "$1\n$2").replace(CLEANUP_PATTERNS.complexTableGaps, "$1\n$3").replace(/\*\*\[([^\]]+?)\]\(([^)]+?)\)\*\*/g, "[**$1**]($2)").replace(/__\[([^\]]+?)\]\(([^)]+?)\)__/g, "[**$1**]($2)").replace(/\*\[([^\]]+?)\]\(([^)]+?)\)\*/g, "[*$1*]($2)").replace(/_\[([^\]]+?)\]\(([^)]+?)\)_/g, "[*$1*]($2)").trim();
|
|
7210
|
+
}
|
|
7211
|
+
function preprocessHtml(html) {
|
|
7212
|
+
const sourceApp = detectSourceApp(html);
|
|
7213
|
+
let processedHtml = preprocessForApp(html, sourceApp);
|
|
7214
|
+
const parser = new DOMParser();
|
|
7215
|
+
const doc = parser.parseFromString(processedHtml, "text/html");
|
|
7216
|
+
if (doc.body) {
|
|
7217
|
+
processTextNodes(doc.body);
|
|
7218
|
+
processedHtml = doc.body.innerHTML;
|
|
7219
|
+
}
|
|
7220
|
+
return processedHtml.replace(HTML_PREPROCESSING_PATTERNS.removeStyleAndDataAttrs, "").replace(HTML_PREPROCESSING_PATTERNS.removeNonCodeClasses, "").replace(HTML_PREPROCESSING_PATTERNS.removeEmptyElements, "").replace(HTML_PREPROCESSING_PATTERNS.normalizeSpaces, " ").replace(HTML_PREPROCESSING_PATTERNS.reduceBlankLines, "\n\n").trim();
|
|
7221
|
+
}
|
|
7222
|
+
function sanitizeContent(content) {
|
|
7223
|
+
return content.replace(/<script[^>]*>.*?<\/script>/gi, "").replace(
|
|
7224
|
+
/<(?:iframe|object|embed)[^>]*>.*?<\/(?:iframe|object|embed)>/gi,
|
|
7225
|
+
""
|
|
7226
|
+
);
|
|
7227
|
+
}
|
|
7228
|
+
function limitContentLength(content, maxLength = MAX_MARKDOWN_OUTPUT_LENGTH) {
|
|
7229
|
+
return content.substring(0, maxLength);
|
|
7230
|
+
}
|
|
7231
|
+
function sanitizeMarkdown(markdown) {
|
|
7232
|
+
return limitContentLength(sanitizeContent(markdown));
|
|
7233
|
+
}
|
|
7234
|
+
function shouldProcessPaste(htmlContent) {
|
|
7235
|
+
if (htmlContent.length > MAX_HTML_INPUT_LENGTH) {
|
|
7236
|
+
console.warn("HTML content too large for paste processing");
|
|
7237
|
+
return false;
|
|
7238
|
+
}
|
|
7239
|
+
const hasFormatting = /<(?:strong|b|em|i|u|s|del|strike|code|pre|h[1-6]|blockquote|ul|ol|li|table|tr|td|th|a|img|mark|span|div)[\s>]/i.test(
|
|
7240
|
+
htmlContent
|
|
7241
|
+
);
|
|
7242
|
+
if (!hasFormatting) {
|
|
7243
|
+
return false;
|
|
7244
|
+
}
|
|
7245
|
+
if (/<img\s/i.test(htmlContent)) {
|
|
7246
|
+
return true;
|
|
7247
|
+
}
|
|
7248
|
+
const strippedContent = htmlContent.replace(/<[^>]*>/g, "").trim();
|
|
7249
|
+
if (!strippedContent || strippedContent.length < 3) {
|
|
7250
|
+
return false;
|
|
7251
|
+
}
|
|
7252
|
+
return true;
|
|
7253
|
+
}
|
|
7254
|
+
function normalizeListPrefixes(content) {
|
|
7255
|
+
const lines = content.split("\n");
|
|
7256
|
+
let currentListType = null;
|
|
7257
|
+
let currentNumber = 1;
|
|
7258
|
+
return lines.map((line) => {
|
|
7259
|
+
const match = line.match(/^(\s*)([-*+]|\d+\.)( +)(.*)$/);
|
|
7260
|
+
if (match) {
|
|
7261
|
+
const [, indent, marker, , listContent] = match;
|
|
7262
|
+
if (currentListType === null) {
|
|
7263
|
+
currentListType = /\d+\./.test(marker) ? "numbered" : "bullet";
|
|
7264
|
+
}
|
|
7265
|
+
const newMarker = currentListType === "bullet" ? "-" : `${currentNumber}.`;
|
|
7266
|
+
if (currentListType === "numbered") {
|
|
7267
|
+
currentNumber += 1;
|
|
7268
|
+
}
|
|
7269
|
+
return `${indent}${newMarker} ${listContent}`;
|
|
7270
|
+
}
|
|
7271
|
+
return line;
|
|
7272
|
+
}).join("\n");
|
|
7273
|
+
}
|
|
7274
|
+
function convertHtmlToMarkdown(html) {
|
|
7275
|
+
try {
|
|
7276
|
+
const processedHtml = preprocessHtml(html);
|
|
7277
|
+
const markdown = turndownService.turndown(processedHtml);
|
|
7278
|
+
return cleanupMarkdown(markdown);
|
|
7279
|
+
} catch (error) {
|
|
7280
|
+
console.error("Error converting HTML to markdown:", error);
|
|
6730
7281
|
return "";
|
|
6731
7282
|
}
|
|
6732
|
-
|
|
7283
|
+
}
|
|
7284
|
+
function htmlToMarkdownForPaste(htmlContent) {
|
|
7285
|
+
if (!shouldProcessPaste(htmlContent)) {
|
|
7286
|
+
return null;
|
|
7287
|
+
}
|
|
7288
|
+
const markdown = convertHtmlToMarkdown(htmlContent);
|
|
7289
|
+
if (!markdown.trim()) {
|
|
7290
|
+
return null;
|
|
7291
|
+
}
|
|
7292
|
+
const normalizedMarkdown = normalizeListPrefixes(markdown);
|
|
7293
|
+
return sanitizeMarkdown(normalizedMarkdown).replace(/\r\n?/g, "\n");
|
|
6733
7294
|
}
|
|
6734
7295
|
const defaultSelection = { start: 0, end: 0, affinity: "forward" };
|
|
6735
7296
|
const COMPOSITION_COMMIT_CLEAR_DELAY_MS = 50;
|
|
@@ -6908,10 +7469,15 @@ class CakeEngine {
|
|
|
6908
7469
|
}
|
|
6909
7470
|
}
|
|
6910
7471
|
setValue({ value, selection }) {
|
|
6911
|
-
const
|
|
6912
|
-
if (
|
|
7472
|
+
const valueChanged = value !== this.state.source;
|
|
7473
|
+
if (!valueChanged && selection === void 0) {
|
|
6913
7474
|
return;
|
|
6914
7475
|
}
|
|
7476
|
+
if (!valueChanged && selection !== void 0) {
|
|
7477
|
+
this.setSelection(selection);
|
|
7478
|
+
return;
|
|
7479
|
+
}
|
|
7480
|
+
const nextSelection = selection ?? this.state.selection;
|
|
6915
7481
|
this.state = this.runtime.createState(value, nextSelection);
|
|
6916
7482
|
this.render();
|
|
6917
7483
|
}
|
|
@@ -7171,7 +7737,11 @@ class CakeEngine {
|
|
|
7171
7737
|
this.extensions,
|
|
7172
7738
|
this.contentRoot
|
|
7173
7739
|
);
|
|
7174
|
-
this.contentRoot.
|
|
7740
|
+
const existingChildren = Array.from(this.contentRoot.childNodes);
|
|
7741
|
+
const needsUpdate = content.length !== existingChildren.length || content.some((node, i) => node !== existingChildren[i]);
|
|
7742
|
+
if (needsUpdate) {
|
|
7743
|
+
this.contentRoot.replaceChildren(...content);
|
|
7744
|
+
}
|
|
7175
7745
|
this.domMap = map;
|
|
7176
7746
|
this.updateExtensionsOverlayPosition();
|
|
7177
7747
|
if (!this.isComposing) {
|
|
@@ -7767,6 +8337,13 @@ class CakeEngine {
|
|
|
7767
8337
|
}
|
|
7768
8338
|
event.preventDefault();
|
|
7769
8339
|
clipboardData.setData("text/plain", text);
|
|
8340
|
+
const html = this.runtime.serializeSelectionToHtml(
|
|
8341
|
+
this.state,
|
|
8342
|
+
this.state.selection
|
|
8343
|
+
);
|
|
8344
|
+
if (html) {
|
|
8345
|
+
clipboardData.setData("text/html", html);
|
|
8346
|
+
}
|
|
7770
8347
|
}
|
|
7771
8348
|
handleCut(event) {
|
|
7772
8349
|
if (this.readOnly) {
|
|
@@ -9076,8 +9653,8 @@ class CakeEngine {
|
|
|
9076
9653
|
if (!this.extensionsRoot) {
|
|
9077
9654
|
return;
|
|
9078
9655
|
}
|
|
9079
|
-
const scrollTop = this.container.scrollTop;
|
|
9080
|
-
const scrollLeft = this.container.scrollLeft;
|
|
9656
|
+
const scrollTop = Math.max(0, this.container.scrollTop);
|
|
9657
|
+
const scrollLeft = Math.max(0, this.container.scrollLeft);
|
|
9081
9658
|
if (scrollTop === 0 && scrollLeft === 0) {
|
|
9082
9659
|
this.extensionsRoot.style.transform = "";
|
|
9083
9660
|
return;
|
|
@@ -10740,10 +11317,10 @@ const CakeEditor = require$$0.forwardRef(
|
|
|
10740
11317
|
containerStyle.position = "relative";
|
|
10741
11318
|
}
|
|
10742
11319
|
const containerClassName = props.className ? `cake ${props.className}` : "cake";
|
|
10743
|
-
const overlayContext =
|
|
11320
|
+
const overlayContext = containerRef.current && contentRoot ? {
|
|
10744
11321
|
container: containerRef.current,
|
|
10745
11322
|
contentRoot,
|
|
10746
|
-
overlayRoot,
|
|
11323
|
+
overlayRoot: overlayRoot ?? void 0,
|
|
10747
11324
|
toOverlayRect: (rect) => {
|
|
10748
11325
|
var _a;
|
|
10749
11326
|
const containerRect = (_a = containerRef.current) == null ? void 0 : _a.getBoundingClientRect();
|
|
@@ -10780,8 +11357,11 @@ const CakeEditor = require$$0.forwardRef(
|
|
|
10780
11357
|
return { start: focus, end: focus };
|
|
10781
11358
|
}
|
|
10782
11359
|
} : null;
|
|
10783
|
-
|
|
10784
|
-
|
|
11360
|
+
const hasOverlayExtensions = allExtensionsRef.current.some(
|
|
11361
|
+
(ext) => ext.renderOverlay
|
|
11362
|
+
);
|
|
11363
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { position: "relative", height: "100%" }, children: [
|
|
11364
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
10785
11365
|
"div",
|
|
10786
11366
|
{
|
|
10787
11367
|
ref: containerRef,
|
|
@@ -10792,35 +11372,12 @@ const CakeEditor = require$$0.forwardRef(
|
|
|
10792
11372
|
var _a;
|
|
10793
11373
|
(_a = props.onBlur) == null ? void 0 : _a.call(props, event.nativeEvent);
|
|
10794
11374
|
}
|
|
10795
|
-
}
|
|
10796
|
-
void 0,
|
|
10797
|
-
false,
|
|
10798
|
-
{
|
|
10799
|
-
fileName: "/Users/moboudra/dev/blankpage/cake/src/cake/react/CakeEditor.tsx",
|
|
10800
|
-
lineNumber: 351,
|
|
10801
|
-
columnNumber: 9
|
|
10802
|
-
},
|
|
10803
|
-
this
|
|
11375
|
+
}
|
|
10804
11376
|
),
|
|
10805
|
-
|
|
10806
|
-
/* @__PURE__ */
|
|
10807
|
-
(extension) => extension.renderOverlay ? /* @__PURE__ */ jsxDevRuntimeExports.jsxDEV(require$$0.Fragment, { children: extension.renderOverlay(overlayContext) }, extension.name, false, {
|
|
10808
|
-
fileName: "/Users/moboudra/dev/blankpage/cake/src/cake/react/CakeEditor.tsx",
|
|
10809
|
-
lineNumber: 365,
|
|
10810
|
-
columnNumber: 21
|
|
10811
|
-
}, this) : null
|
|
10812
|
-
) }, void 0, false, {
|
|
10813
|
-
fileName: "/Users/moboudra/dev/blankpage/cake/src/cake/react/CakeEditor.tsx",
|
|
10814
|
-
lineNumber: 362,
|
|
10815
|
-
columnNumber: 15
|
|
10816
|
-
}, this),
|
|
10817
|
-
overlayRoot
|
|
11377
|
+
overlayContext && hasOverlayExtensions ? allExtensionsRef.current.map(
|
|
11378
|
+
(extension) => extension.renderOverlay ? /* @__PURE__ */ jsxRuntimeExports.jsx(require$$0.Fragment, { children: extension.renderOverlay(overlayContext) }, extension.name) : null
|
|
10818
11379
|
) : null
|
|
10819
|
-
] }
|
|
10820
|
-
fileName: "/Users/moboudra/dev/blankpage/cake/src/cake/react/CakeEditor.tsx",
|
|
10821
|
-
lineNumber: 350,
|
|
10822
|
-
columnNumber: 7
|
|
10823
|
-
}, this);
|
|
11380
|
+
] });
|
|
10824
11381
|
}
|
|
10825
11382
|
);
|
|
10826
11383
|
CakeEditor.displayName = "CakeEditor";
|