@blankdotpage/cake 0.1.13 → 0.1.15
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/core/runtime.d.ts +4 -1
- package/dist/cake/core/runtime.d.ts.map +1 -1
- package/dist/cake/core/runtime.js +167 -168
- package/dist/cake/extensions/index.d.ts +2 -1
- package/dist/cake/extensions/index.d.ts.map +1 -1
- package/dist/cake/extensions/index.js +3 -1
- package/dist/cake/extensions/underline/index.d.ts +2 -0
- package/dist/cake/extensions/underline/index.d.ts.map +1 -0
- package/dist/cake/extensions/underline/index.js +1 -0
- package/dist/cake/extensions/underline/underline.d.ts +2 -0
- package/dist/cake/extensions/underline/underline.d.ts.map +1 -0
- package/dist/cake/extensions/underline/underline.js +71 -0
- package/package.json +1 -1
|
@@ -115,7 +115,10 @@ export type CakeExtension = {
|
|
|
115
115
|
*/
|
|
116
116
|
toggleInline?: {
|
|
117
117
|
kind: string;
|
|
118
|
-
markers: string
|
|
118
|
+
markers: Array<string | {
|
|
119
|
+
open: string;
|
|
120
|
+
close: string;
|
|
121
|
+
}>;
|
|
119
122
|
};
|
|
120
123
|
parseBlock?: (source: string, start: number, context: ExtensionContext) => ParseBlockResult;
|
|
121
124
|
parseInline?: (source: string, start: number, end: number, context: ExtensionContext) => ParseInlineResult;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/cake/core/runtime.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/cake/core/runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -38,14 +38,17 @@ export function defineExtension(extension) {
|
|
|
38
38
|
}
|
|
39
39
|
const defaultSelection = { start: 0, end: 0, affinity: "forward" };
|
|
40
40
|
export function createRuntime(extensions) {
|
|
41
|
-
const
|
|
41
|
+
const toggleMarkerToSpec = new Map();
|
|
42
42
|
for (const extension of extensions) {
|
|
43
43
|
const toggle = extension.toggleInline;
|
|
44
44
|
if (!toggle) {
|
|
45
45
|
continue;
|
|
46
46
|
}
|
|
47
47
|
for (const marker of toggle.markers) {
|
|
48
|
-
|
|
48
|
+
const spec = typeof marker === "string"
|
|
49
|
+
? { kind: toggle.kind, open: marker, close: marker }
|
|
50
|
+
: { kind: toggle.kind, open: marker.open, close: marker.close };
|
|
51
|
+
toggleMarkerToSpec.set(spec.open, spec);
|
|
49
52
|
}
|
|
50
53
|
}
|
|
51
54
|
const inclusiveAtEndByKind = new Map();
|
|
@@ -466,6 +469,45 @@ export function createRuntime(extensions) {
|
|
|
466
469
|
if (!startLine || !endLine) {
|
|
467
470
|
return null;
|
|
468
471
|
}
|
|
472
|
+
if (command.type === "delete-backward" &&
|
|
473
|
+
cursorStart === cursorEnd &&
|
|
474
|
+
endLoc.offsetInLine === 0 &&
|
|
475
|
+
endLoc.lineIndex > 0) {
|
|
476
|
+
const prevLine = lines[endLoc.lineIndex - 1];
|
|
477
|
+
if (prevLine &&
|
|
478
|
+
!pathsEqual(prevLine.parentPath, endLine.parentPath)) {
|
|
479
|
+
const prevBlock = getBlockAtPath(doc.blocks, prevLine.path);
|
|
480
|
+
const currentBlock = getBlockAtPath(doc.blocks, endLine.path);
|
|
481
|
+
if (prevBlock &&
|
|
482
|
+
prevBlock.type === "paragraph" &&
|
|
483
|
+
currentBlock &&
|
|
484
|
+
currentBlock.type === "paragraph") {
|
|
485
|
+
const prevRuns = paragraphToRuns(prevBlock);
|
|
486
|
+
const currentRuns = paragraphToRuns(currentBlock);
|
|
487
|
+
const mergedRuns = normalizeRuns([...prevRuns, ...currentRuns]);
|
|
488
|
+
const nextPrevBlock = {
|
|
489
|
+
...prevBlock,
|
|
490
|
+
content: runsToInlines(mergedRuns),
|
|
491
|
+
};
|
|
492
|
+
let nextBlocks = updateBlocksAtPath(doc.blocks, prevLine.parentPath, (blocks) => blocks.map((block, index) => index === prevLine.indexInParent ? nextPrevBlock : block));
|
|
493
|
+
nextBlocks = updateBlocksAtPath(nextBlocks, endLine.parentPath, (blocks) => blocks.filter((_, index) => index !== endLine.indexInParent));
|
|
494
|
+
const nextDoc = { ...doc, blocks: nextBlocks };
|
|
495
|
+
const nextLines = flattenDocToLines(nextDoc);
|
|
496
|
+
const lineStarts = getLineStartOffsets(nextLines);
|
|
497
|
+
const mergedLineIndex = nextLines.findIndex((line) => pathsEqual(line.path, prevLine.path));
|
|
498
|
+
const mergedLine = nextLines[mergedLineIndex];
|
|
499
|
+
const nextCursor = mergedLineIndex >= 0
|
|
500
|
+
? (lineStarts[mergedLineIndex] ?? 0) +
|
|
501
|
+
(mergedLine?.cursorLength ?? 0)
|
|
502
|
+
: 0;
|
|
503
|
+
return {
|
|
504
|
+
doc: nextDoc,
|
|
505
|
+
nextCursor,
|
|
506
|
+
nextAffinity: "forward",
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
469
511
|
if (!pathsEqual(startLine.parentPath, endLine.parentPath) ||
|
|
470
512
|
startLine.indexInParent > endLine.indexInParent) {
|
|
471
513
|
return null;
|
|
@@ -1213,53 +1255,56 @@ export function createRuntime(extensions) {
|
|
|
1213
1255
|
const selection = normalizeSelection(state.selection);
|
|
1214
1256
|
const source = state.source;
|
|
1215
1257
|
const map = state.map;
|
|
1258
|
+
const markerSpec = toggleMarkerToSpec.get(marker);
|
|
1259
|
+
if (!markerSpec) {
|
|
1260
|
+
return state;
|
|
1261
|
+
}
|
|
1262
|
+
const { kind: markerKind, open: openMarker, close: closeMarker } = markerSpec;
|
|
1263
|
+
const openLen = openMarker.length;
|
|
1264
|
+
const closeLen = closeMarker.length;
|
|
1216
1265
|
if (selection.start === selection.end) {
|
|
1217
1266
|
const caret = selection.start;
|
|
1218
|
-
const markerLen = marker.length;
|
|
1219
1267
|
// When the caret is at the end boundary of an inline wrapper, toggling the
|
|
1220
1268
|
// wrapper should "exit" it (so the next character types outside). This is
|
|
1221
1269
|
// best expressed in cursor space by flipping affinity to "forward" when we
|
|
1222
1270
|
// are leaving a wrapper of the requested kind.
|
|
1223
|
-
const
|
|
1224
|
-
if (
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
const
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
},
|
|
1251
|
-
};
|
|
1252
|
-
}
|
|
1271
|
+
const around = marksAroundCursor(state.doc, caret);
|
|
1272
|
+
if (isMarksPrefix(around.right, around.left) &&
|
|
1273
|
+
around.left.length > around.right.length) {
|
|
1274
|
+
const exiting = around.left.slice(around.right.length);
|
|
1275
|
+
if (exiting.some((mark) => mark.kind === markerKind)) {
|
|
1276
|
+
if (exiting.length > 1) {
|
|
1277
|
+
const placeholder = "\u200B";
|
|
1278
|
+
const insertAtForward = map.cursorToSource(caret, "forward");
|
|
1279
|
+
const insertAtBackward = map.cursorToSource(caret, "backward");
|
|
1280
|
+
const between = source.slice(insertAtBackward, insertAtForward);
|
|
1281
|
+
const markerIndex = between.indexOf(closeMarker);
|
|
1282
|
+
if (markerIndex !== -1) {
|
|
1283
|
+
const insertAt = insertAtBackward + markerIndex + closeLen;
|
|
1284
|
+
const nextSource = source.slice(0, insertAt) +
|
|
1285
|
+
placeholder +
|
|
1286
|
+
source.slice(insertAt);
|
|
1287
|
+
const next = createState(nextSource);
|
|
1288
|
+
const placeholderStart = insertAt;
|
|
1289
|
+
const startCursor = next.map.sourceToCursor(placeholderStart, "forward");
|
|
1290
|
+
return {
|
|
1291
|
+
...next,
|
|
1292
|
+
selection: {
|
|
1293
|
+
start: startCursor.cursorOffset,
|
|
1294
|
+
end: startCursor.cursorOffset,
|
|
1295
|
+
affinity: "forward",
|
|
1296
|
+
},
|
|
1297
|
+
};
|
|
1253
1298
|
}
|
|
1254
|
-
return {
|
|
1255
|
-
...state,
|
|
1256
|
-
selection: {
|
|
1257
|
-
start: caret,
|
|
1258
|
-
end: caret,
|
|
1259
|
-
affinity: "forward",
|
|
1260
|
-
},
|
|
1261
|
-
};
|
|
1262
1299
|
}
|
|
1300
|
+
return {
|
|
1301
|
+
...state,
|
|
1302
|
+
selection: {
|
|
1303
|
+
start: caret,
|
|
1304
|
+
end: caret,
|
|
1305
|
+
affinity: "forward",
|
|
1306
|
+
},
|
|
1307
|
+
};
|
|
1263
1308
|
}
|
|
1264
1309
|
}
|
|
1265
1310
|
// Otherwise, insert an empty marker pair with a zero-width placeholder
|
|
@@ -1287,17 +1332,17 @@ export function createRuntime(extensions) {
|
|
|
1287
1332
|
map.cursorToSource(caret, selection.affinity ?? "forward");
|
|
1288
1333
|
const nextSource = placeholderPos !== null
|
|
1289
1334
|
? source.slice(0, insertAt) +
|
|
1290
|
-
|
|
1335
|
+
openMarker +
|
|
1291
1336
|
placeholder +
|
|
1292
|
-
|
|
1337
|
+
closeMarker +
|
|
1293
1338
|
source.slice(insertAt + placeholder.length)
|
|
1294
1339
|
: source.slice(0, insertAt) +
|
|
1295
|
-
|
|
1340
|
+
openMarker +
|
|
1296
1341
|
placeholder +
|
|
1297
|
-
|
|
1342
|
+
closeMarker +
|
|
1298
1343
|
source.slice(insertAt);
|
|
1299
1344
|
const next = createState(nextSource);
|
|
1300
|
-
const placeholderStart = insertAt +
|
|
1345
|
+
const placeholderStart = insertAt + openLen;
|
|
1301
1346
|
const startCursor = next.map.sourceToCursor(placeholderStart, "forward");
|
|
1302
1347
|
return {
|
|
1303
1348
|
...next,
|
|
@@ -1310,143 +1355,97 @@ export function createRuntime(extensions) {
|
|
|
1310
1355
|
}
|
|
1311
1356
|
const cursorStart = Math.min(selection.start, selection.end);
|
|
1312
1357
|
const cursorEnd = Math.max(selection.start, selection.end);
|
|
1313
|
-
const from = map.cursorToSource(cursorStart, "forward");
|
|
1314
|
-
const to = map.cursorToSource(cursorEnd, "backward");
|
|
1315
|
-
const selectedText = source.slice(from, to);
|
|
1316
|
-
const markerLen = marker.length;
|
|
1317
|
-
const markerKind = toggleMarkerToKind.get(marker) ?? null;
|
|
1318
1358
|
const linesForSelection = flattenDocToLines(state.doc);
|
|
1319
|
-
const commonMarks =
|
|
1320
|
-
|
|
1321
|
-
: [];
|
|
1322
|
-
const hasCommonMark = markerKind !== null && commonMarks.some((mark) => mark.kind === markerKind);
|
|
1323
|
-
const canUnwrap = markerKind ? hasCommonMark : true;
|
|
1359
|
+
const commonMarks = commonMarksAcrossSelection(linesForSelection, cursorStart, cursorEnd, state.doc);
|
|
1360
|
+
const canUnwrap = commonMarks.some((mark) => mark.kind === markerKind);
|
|
1324
1361
|
const startLoc = resolveCursorToLine(linesForSelection, cursorStart);
|
|
1325
1362
|
const endLoc = resolveCursorToLine(linesForSelection, cursorEnd);
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
if (!line) {
|
|
1336
|
-
continue;
|
|
1337
|
-
}
|
|
1338
|
-
const lineStart = lineOffsets[lineIndex] ?? 0;
|
|
1339
|
-
const startInLine = lineIndex === startLoc.lineIndex ? startLoc.offsetInLine : 0;
|
|
1340
|
-
const endInLine = lineIndex === endLoc.lineIndex
|
|
1341
|
-
? endLoc.offsetInLine
|
|
1342
|
-
: line.cursorLength;
|
|
1343
|
-
if (startInLine === endInLine) {
|
|
1344
|
-
continue;
|
|
1345
|
-
}
|
|
1346
|
-
const segmentStartCursor = lineStart + startInLine;
|
|
1347
|
-
const segmentEndCursor = lineStart + endInLine;
|
|
1348
|
-
const segmentFrom = map.cursorToSource(segmentStartCursor, "forward");
|
|
1349
|
-
const segmentTo = map.cursorToSource(segmentEndCursor, "backward");
|
|
1350
|
-
if (segmentFrom === segmentTo) {
|
|
1351
|
-
continue;
|
|
1352
|
-
}
|
|
1353
|
-
byCursorLines.push({ from: segmentFrom, to: segmentTo });
|
|
1354
|
-
}
|
|
1355
|
-
return byCursorLines;
|
|
1363
|
+
const markerMark = {
|
|
1364
|
+
kind: markerKind,
|
|
1365
|
+
data: undefined,
|
|
1366
|
+
key: markKey(markerKind, undefined),
|
|
1367
|
+
};
|
|
1368
|
+
const removeMark = (marks) => {
|
|
1369
|
+
for (let i = marks.length - 1; i >= 0; i -= 1) {
|
|
1370
|
+
if (marks[i]?.kind === markerKind) {
|
|
1371
|
+
return [...marks.slice(0, i), ...marks.slice(i + 1)];
|
|
1356
1372
|
}
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
}
|
|
1367
|
-
if (newlineIndex === -1) {
|
|
1368
|
-
break;
|
|
1369
|
-
}
|
|
1370
|
-
sliceOffset = newlineIndex + 1;
|
|
1373
|
+
}
|
|
1374
|
+
return marks;
|
|
1375
|
+
};
|
|
1376
|
+
const splitRunsOnNewlines = (runs) => {
|
|
1377
|
+
const split = [];
|
|
1378
|
+
for (const run of runs) {
|
|
1379
|
+
if (!run.text.includes("\n")) {
|
|
1380
|
+
split.push(run);
|
|
1381
|
+
continue;
|
|
1371
1382
|
}
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
if (canUnwrap) {
|
|
1378
|
-
if (segmentFrom >= markerLen &&
|
|
1379
|
-
source.slice(segmentFrom - markerLen, segmentFrom) === marker) {
|
|
1380
|
-
edits.push({
|
|
1381
|
-
from: segmentFrom - markerLen,
|
|
1382
|
-
to: segmentFrom,
|
|
1383
|
-
insert: "",
|
|
1384
|
-
});
|
|
1383
|
+
const parts = run.text.split("\n");
|
|
1384
|
+
for (let i = 0; i < parts.length; i += 1) {
|
|
1385
|
+
const part = parts[i] ?? "";
|
|
1386
|
+
if (part) {
|
|
1387
|
+
split.push({ ...run, text: part });
|
|
1385
1388
|
}
|
|
1386
|
-
if (
|
|
1387
|
-
|
|
1388
|
-
from: segmentTo,
|
|
1389
|
-
to: segmentTo + markerLen,
|
|
1390
|
-
insert: "",
|
|
1391
|
-
});
|
|
1389
|
+
if (i < parts.length - 1) {
|
|
1390
|
+
split.push({ ...run, text: "\n" });
|
|
1392
1391
|
}
|
|
1393
1392
|
}
|
|
1394
|
-
else {
|
|
1395
|
-
edits.push({ from: segmentFrom, to: segmentFrom, insert: marker });
|
|
1396
|
-
edits.push({ from: segmentTo, to: segmentTo, insert: marker });
|
|
1397
|
-
}
|
|
1398
1393
|
}
|
|
1399
|
-
|
|
1400
|
-
|
|
1394
|
+
return split;
|
|
1395
|
+
};
|
|
1396
|
+
let nextDoc = state.doc;
|
|
1397
|
+
let didChange = false;
|
|
1398
|
+
for (let lineIndex = startLoc.lineIndex; lineIndex <= endLoc.lineIndex; lineIndex += 1) {
|
|
1399
|
+
const line = linesForSelection[lineIndex];
|
|
1400
|
+
if (!line) {
|
|
1401
|
+
continue;
|
|
1401
1402
|
}
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
newSource.slice(0, edit.from) +
|
|
1407
|
-
edit.insert +
|
|
1408
|
-
newSource.slice(edit.to);
|
|
1403
|
+
const startInLine = lineIndex === startLoc.lineIndex ? startLoc.offsetInLine : 0;
|
|
1404
|
+
const endInLine = lineIndex === endLoc.lineIndex ? endLoc.offsetInLine : line.cursorLength;
|
|
1405
|
+
if (startInLine === endInLine) {
|
|
1406
|
+
continue;
|
|
1409
1407
|
}
|
|
1410
|
-
const
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
selection: {
|
|
1414
|
-
start: cursorStart,
|
|
1415
|
-
end: cursorEnd,
|
|
1416
|
-
affinity: selection.affinity ?? "forward",
|
|
1417
|
-
},
|
|
1418
|
-
};
|
|
1419
|
-
}
|
|
1420
|
-
const isSelectionWrappedByAdjacentMarkers = markerLen > 0 &&
|
|
1421
|
-
from >= markerLen &&
|
|
1422
|
-
source.slice(from - markerLen, from) === marker &&
|
|
1423
|
-
source.slice(to, to + markerLen) === marker;
|
|
1424
|
-
const isWrappedBySelectionText = selectedText.startsWith(marker) &&
|
|
1425
|
-
selectedText.endsWith(marker) &&
|
|
1426
|
-
selectedText.length >= markerLen * 2;
|
|
1427
|
-
const isWrapped = canUnwrap &&
|
|
1428
|
-
(isSelectionWrappedByAdjacentMarkers ||
|
|
1429
|
-
(markerKind ? isWrappedBySelectionText : isWrappedBySelectionText));
|
|
1430
|
-
let newSource;
|
|
1431
|
-
if (isWrapped) {
|
|
1432
|
-
// Unwrap
|
|
1433
|
-
if (isSelectionWrappedByAdjacentMarkers) {
|
|
1434
|
-
newSource =
|
|
1435
|
-
source.slice(0, from - markerLen) +
|
|
1436
|
-
selectedText +
|
|
1437
|
-
source.slice(to + markerLen);
|
|
1408
|
+
const block = getBlockAtPath(nextDoc.blocks, line.path);
|
|
1409
|
+
if (!block || block.type !== "paragraph") {
|
|
1410
|
+
continue;
|
|
1438
1411
|
}
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1412
|
+
const runs = paragraphToRuns(block);
|
|
1413
|
+
const { before, selected, after } = sliceRuns(runs, startInLine, endInLine);
|
|
1414
|
+
if (selected.length === 0) {
|
|
1415
|
+
continue;
|
|
1442
1416
|
}
|
|
1417
|
+
const updatedSelected = splitRunsOnNewlines(selected).map((run) => {
|
|
1418
|
+
const isNewline = run.text === "\n";
|
|
1419
|
+
const nextMarks = canUnwrap
|
|
1420
|
+
? removeMark(run.marks)
|
|
1421
|
+
: isNewline
|
|
1422
|
+
? run.marks
|
|
1423
|
+
: [...run.marks, markerMark];
|
|
1424
|
+
if (!marksEqual(run.marks, nextMarks)) {
|
|
1425
|
+
didChange = true;
|
|
1426
|
+
}
|
|
1427
|
+
return { ...run, marks: nextMarks };
|
|
1428
|
+
});
|
|
1429
|
+
const mergedRuns = normalizeRuns([
|
|
1430
|
+
...before,
|
|
1431
|
+
...updatedSelected,
|
|
1432
|
+
...after,
|
|
1433
|
+
]);
|
|
1434
|
+
const nextBlock = {
|
|
1435
|
+
...block,
|
|
1436
|
+
content: runsToInlines(mergedRuns),
|
|
1437
|
+
};
|
|
1438
|
+
const parentPath = line.path.slice(0, -1);
|
|
1439
|
+
const indexInParent = line.path[line.path.length - 1] ?? 0;
|
|
1440
|
+
nextDoc = {
|
|
1441
|
+
...nextDoc,
|
|
1442
|
+
blocks: updateBlocksAtPath(nextDoc.blocks, parentPath, (blocks) => blocks.map((child, index) => index === indexInParent ? nextBlock : child)),
|
|
1443
|
+
};
|
|
1443
1444
|
}
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
const wrapped = marker + selectedText + marker;
|
|
1447
|
-
newSource = source.slice(0, from) + wrapped + source.slice(to);
|
|
1445
|
+
if (!didChange) {
|
|
1446
|
+
return state;
|
|
1448
1447
|
}
|
|
1449
|
-
const next =
|
|
1448
|
+
const next = createStateFromDoc(nextDoc);
|
|
1450
1449
|
return {
|
|
1451
1450
|
...next,
|
|
1452
1451
|
selection: {
|
|
@@ -8,7 +8,8 @@ import { imageExtension } from "./image/image";
|
|
|
8
8
|
import { plainTextListExtension } from "./list/list";
|
|
9
9
|
import { scrollbarExtension } from "./scrollbar";
|
|
10
10
|
import { strikethroughExtension } from "./strikethrough/strikethrough";
|
|
11
|
-
|
|
11
|
+
import { underlineExtension } from "./underline/underline";
|
|
12
|
+
export { boldExtension, combinedEmphasisExtension, linkExtension, blockquoteExtension, italicExtension, headingExtension, imageExtension, plainTextListExtension, scrollbarExtension, strikethroughExtension, underlineExtension, };
|
|
12
13
|
export declare const bundledExtensionsWithoutImage: import("../..").CakeExtension[];
|
|
13
14
|
export declare const bundledExtensions: import("../..").CakeExtension[];
|
|
14
15
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cake/extensions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,yBAAyB,EAAE,MAAM,uCAAuC,CAAC;AAClF,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cake/extensions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,yBAAyB,EAAE,MAAM,uCAAuC,CAAC;AAClF,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE3D,OAAO,EACL,aAAa,EACb,yBAAyB,EACzB,aAAa,EACb,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,sBAAsB,EACtB,kBAAkB,EAClB,sBAAsB,EACtB,kBAAkB,GACnB,CAAC;AAEF,eAAO,MAAM,6BAA6B,iCAUzC,CAAC;AAEF,eAAO,MAAM,iBAAiB,iCAG7B,CAAC"}
|
|
@@ -8,7 +8,8 @@ import { imageExtension } from "./image/image";
|
|
|
8
8
|
import { plainTextListExtension } from "./list/list";
|
|
9
9
|
import { scrollbarExtension } from "./scrollbar";
|
|
10
10
|
import { strikethroughExtension } from "./strikethrough/strikethrough";
|
|
11
|
-
|
|
11
|
+
import { underlineExtension } from "./underline/underline";
|
|
12
|
+
export { boldExtension, combinedEmphasisExtension, linkExtension, blockquoteExtension, italicExtension, headingExtension, imageExtension, plainTextListExtension, scrollbarExtension, strikethroughExtension, underlineExtension, };
|
|
12
13
|
export const bundledExtensionsWithoutImage = [
|
|
13
14
|
blockquoteExtension,
|
|
14
15
|
headingExtension,
|
|
@@ -17,6 +18,7 @@ export const bundledExtensionsWithoutImage = [
|
|
|
17
18
|
boldExtension,
|
|
18
19
|
italicExtension,
|
|
19
20
|
strikethroughExtension,
|
|
21
|
+
underlineExtension,
|
|
20
22
|
linkExtension,
|
|
21
23
|
];
|
|
22
24
|
export const bundledExtensions = [
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/cake/extensions/underline/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./underline";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"underline.d.ts","sourceRoot":"","sources":["../../../../src/cake/extensions/underline/underline.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,kBAAkB,kCAyE7B,CAAC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { defineExtension, } from "../../core/runtime";
|
|
2
|
+
import { CursorSourceBuilder } from "../../core/mapping/cursor-source-map";
|
|
3
|
+
const UNDERLINE_KIND = "underline";
|
|
4
|
+
export const underlineExtension = defineExtension({
|
|
5
|
+
name: "underline",
|
|
6
|
+
toggleInline: { kind: UNDERLINE_KIND, markers: [{ open: "<u>", close: "</u>" }] },
|
|
7
|
+
keybindings: [
|
|
8
|
+
{ key: "u", meta: true, shift: false, command: { type: "toggle-underline" } },
|
|
9
|
+
{ key: "u", ctrl: true, shift: false, command: { type: "toggle-underline" } },
|
|
10
|
+
],
|
|
11
|
+
inlineWrapperAffinity: [{ kind: UNDERLINE_KIND, inclusive: true }],
|
|
12
|
+
onEdit(command) {
|
|
13
|
+
if (command.type === "toggle-underline") {
|
|
14
|
+
return { type: "toggle-inline", marker: "<u>" };
|
|
15
|
+
}
|
|
16
|
+
return null;
|
|
17
|
+
},
|
|
18
|
+
parseInline(source, start, end, context) {
|
|
19
|
+
if (source.slice(start, start + 3) !== "<u>") {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
const close = source.indexOf("</u>", start + 3);
|
|
23
|
+
if (close === -1 || close >= end) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
const children = context.parseInline(source, start + 3, close);
|
|
27
|
+
return {
|
|
28
|
+
inline: {
|
|
29
|
+
type: "inline-wrapper",
|
|
30
|
+
kind: UNDERLINE_KIND,
|
|
31
|
+
children,
|
|
32
|
+
},
|
|
33
|
+
nextPos: close + 4,
|
|
34
|
+
};
|
|
35
|
+
},
|
|
36
|
+
serializeInline(inline, context) {
|
|
37
|
+
if (inline.type !== "inline-wrapper" || inline.kind !== UNDERLINE_KIND) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
const builder = new CursorSourceBuilder();
|
|
41
|
+
builder.appendSourceOnly("<u>");
|
|
42
|
+
for (const child of inline.children) {
|
|
43
|
+
const serialized = context.serializeInline(child);
|
|
44
|
+
builder.appendSerialized(serialized);
|
|
45
|
+
}
|
|
46
|
+
builder.appendSourceOnly("</u>");
|
|
47
|
+
return builder.build();
|
|
48
|
+
},
|
|
49
|
+
normalizeInline(inline) {
|
|
50
|
+
if (inline.type !== "inline-wrapper" || inline.kind !== UNDERLINE_KIND) {
|
|
51
|
+
return inline;
|
|
52
|
+
}
|
|
53
|
+
if (inline.children.length === 0) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
return inline;
|
|
57
|
+
},
|
|
58
|
+
renderInline(inline, context) {
|
|
59
|
+
if (inline.type !== "inline-wrapper" || inline.kind !== UNDERLINE_KIND) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
const element = document.createElement("u");
|
|
63
|
+
element.className = "cake-underline";
|
|
64
|
+
for (const child of inline.children) {
|
|
65
|
+
for (const node of context.renderInline(child)) {
|
|
66
|
+
element.append(node);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return element;
|
|
70
|
+
},
|
|
71
|
+
});
|