@sofereditor/core 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +32 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +33 -3
- package/dist/index.d.ts +33 -3
- package/dist/index.js +32 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -138,6 +138,11 @@ interface BlockAttrs {
|
|
|
138
138
|
* Ausente = "all" — documentos existentes não mudam de aparência.
|
|
139
139
|
*/
|
|
140
140
|
borderPreset?: TableBorderPreset;
|
|
141
|
+
/**
|
|
142
|
+
* Só relevante quando `type === "table"`. Cor das linhas da grade.
|
|
143
|
+
* Ausente = `TABLE_BORDER_COLOR` — documentos existentes não mudam.
|
|
144
|
+
*/
|
|
145
|
+
borderColor?: string;
|
|
141
146
|
/**
|
|
142
147
|
* Só relevante quando `type === "paragraph"`. Parágrafo pautado para o aluno
|
|
143
148
|
* escrever a resposta: renderiza com régua inferior de largura total.
|
|
@@ -582,9 +587,9 @@ interface CellBorderColors {
|
|
|
582
587
|
* `:first-child`/`:last-child`, que quebram assim que uma célula `covered` some
|
|
583
588
|
* do DOM por causa de um rowspan.
|
|
584
589
|
*/
|
|
585
|
-
declare function cellBorderColors(preset: TableBorderPreset | undefined, pos: CellBorderPos, variant: "screen" | "print"): CellBorderColors;
|
|
590
|
+
declare function cellBorderColors(preset: TableBorderPreset | undefined, pos: CellBorderPos, variant: "screen" | "print", color?: string): CellBorderColors;
|
|
586
591
|
/** `cellBorderColors` no formato de estilo inline consumido pelos renderizadores. */
|
|
587
|
-
declare function cellBorderStyle(preset: TableBorderPreset | undefined, pos: CellBorderPos, variant: "screen" | "print"): StyleRecord;
|
|
592
|
+
declare function cellBorderStyle(preset: TableBorderPreset | undefined, pos: CellBorderPos, variant: "screen" | "print", color?: string): StyleRecord;
|
|
588
593
|
|
|
589
594
|
/** MIME custom que carrega o slice serializado no clipboard. */
|
|
590
595
|
declare const SOFER_MIME = "application/x-sofer-slice";
|
|
@@ -595,6 +600,20 @@ interface ClipboardSlice {
|
|
|
595
600
|
openStart: boolean;
|
|
596
601
|
/** último bloco é fragmento parcial → conteúdo após o caret continua nele. */
|
|
597
602
|
openEnd: boolean;
|
|
603
|
+
/**
|
|
604
|
+
* Marca explícita: quando presente (`true`) e `blocks.length === 1`, esse
|
|
605
|
+
* único bloco é uma unidade INTEIRA (ex.: um `<h1>`/`<li>`/`<blockquote>`
|
|
606
|
+
* inteiro colado de fora) — `insertSlice` deve adotar o `type`/`attrs` dele
|
|
607
|
+
* em vez de tratá-lo como fragmento de uma seleção.
|
|
608
|
+
*
|
|
609
|
+
* `serializeSelection` NUNCA define este campo — uma cópia interna é sempre
|
|
610
|
+
* um fragmento de seleção, mesmo quando por coincidência cobre o bloco
|
|
611
|
+
* inteiro (nesse caso `openStart`/`openEnd` também saem `false`, mas isso
|
|
612
|
+
* não significa "bloco externo inteiro": significa apenas que a seleção
|
|
613
|
+
* tocou as bordas do bloco). Só produtores de blocos externos inteiros
|
|
614
|
+
* (hoje: `htmlToSlice`) devem marcar `blockLevel: true`.
|
|
615
|
+
*/
|
|
616
|
+
blockLevel?: true;
|
|
598
617
|
}
|
|
599
618
|
/**
|
|
600
619
|
* Lê a seleção e produz um ClipboardSlice, ou null se:
|
|
@@ -673,7 +692,18 @@ declare function setCellAttr<K extends keyof CellAttrs>(ctx: CommandContext, key
|
|
|
673
692
|
declare function deleteSelection(ctx: CommandContext): void;
|
|
674
693
|
/**
|
|
675
694
|
* Replace the current selection with a clipboard slice (A1).
|
|
676
|
-
* - Single-block slice
|
|
695
|
+
* - Single-block slice WITHOUT `blockLevel` → always an inline splice
|
|
696
|
+
* (Dhead + S0 + Dtail), target keeps its type. This is the internal
|
|
697
|
+
* copy/paste shape, including a full-block internal copy (selecting an
|
|
698
|
+
* entire line and copying it also yields `openStart:false, openEnd:false`
|
|
699
|
+
* with one block — that is NOT the same thing as an external whole block;
|
|
700
|
+
* `openStart`/`openEnd` do not carry that distinction, so branching on them
|
|
701
|
+
* here regressed plain in-editor copy/paste. See `ClipboardSlice.blockLevel`.
|
|
702
|
+
* - Single-block slice WITH `blockLevel: true` (e.g. one <h1>/<li>/<blockquote>
|
|
703
|
+
* from an HTML paste via `htmlToSlice`) → adopts S0's type/attrs instead,
|
|
704
|
+
* same rules as the multi-block case below (reuse target in place when the
|
|
705
|
+
* caret is at offset 0, otherwise insert S0 as its own block; any tail
|
|
706
|
+
* becomes a separate block with the target's original type).
|
|
677
707
|
* - Multi-block slice → openStart merges S0 inline; middle/last blocks inserted
|
|
678
708
|
* discretely; openEnd appends the post-caret tail onto the last pasted block.
|
|
679
709
|
* - Target inside a table cell → slice flattened to inline (no block structure).
|
package/dist/index.d.ts
CHANGED
|
@@ -138,6 +138,11 @@ interface BlockAttrs {
|
|
|
138
138
|
* Ausente = "all" — documentos existentes não mudam de aparência.
|
|
139
139
|
*/
|
|
140
140
|
borderPreset?: TableBorderPreset;
|
|
141
|
+
/**
|
|
142
|
+
* Só relevante quando `type === "table"`. Cor das linhas da grade.
|
|
143
|
+
* Ausente = `TABLE_BORDER_COLOR` — documentos existentes não mudam.
|
|
144
|
+
*/
|
|
145
|
+
borderColor?: string;
|
|
141
146
|
/**
|
|
142
147
|
* Só relevante quando `type === "paragraph"`. Parágrafo pautado para o aluno
|
|
143
148
|
* escrever a resposta: renderiza com régua inferior de largura total.
|
|
@@ -582,9 +587,9 @@ interface CellBorderColors {
|
|
|
582
587
|
* `:first-child`/`:last-child`, que quebram assim que uma célula `covered` some
|
|
583
588
|
* do DOM por causa de um rowspan.
|
|
584
589
|
*/
|
|
585
|
-
declare function cellBorderColors(preset: TableBorderPreset | undefined, pos: CellBorderPos, variant: "screen" | "print"): CellBorderColors;
|
|
590
|
+
declare function cellBorderColors(preset: TableBorderPreset | undefined, pos: CellBorderPos, variant: "screen" | "print", color?: string): CellBorderColors;
|
|
586
591
|
/** `cellBorderColors` no formato de estilo inline consumido pelos renderizadores. */
|
|
587
|
-
declare function cellBorderStyle(preset: TableBorderPreset | undefined, pos: CellBorderPos, variant: "screen" | "print"): StyleRecord;
|
|
592
|
+
declare function cellBorderStyle(preset: TableBorderPreset | undefined, pos: CellBorderPos, variant: "screen" | "print", color?: string): StyleRecord;
|
|
588
593
|
|
|
589
594
|
/** MIME custom que carrega o slice serializado no clipboard. */
|
|
590
595
|
declare const SOFER_MIME = "application/x-sofer-slice";
|
|
@@ -595,6 +600,20 @@ interface ClipboardSlice {
|
|
|
595
600
|
openStart: boolean;
|
|
596
601
|
/** último bloco é fragmento parcial → conteúdo após o caret continua nele. */
|
|
597
602
|
openEnd: boolean;
|
|
603
|
+
/**
|
|
604
|
+
* Marca explícita: quando presente (`true`) e `blocks.length === 1`, esse
|
|
605
|
+
* único bloco é uma unidade INTEIRA (ex.: um `<h1>`/`<li>`/`<blockquote>`
|
|
606
|
+
* inteiro colado de fora) — `insertSlice` deve adotar o `type`/`attrs` dele
|
|
607
|
+
* em vez de tratá-lo como fragmento de uma seleção.
|
|
608
|
+
*
|
|
609
|
+
* `serializeSelection` NUNCA define este campo — uma cópia interna é sempre
|
|
610
|
+
* um fragmento de seleção, mesmo quando por coincidência cobre o bloco
|
|
611
|
+
* inteiro (nesse caso `openStart`/`openEnd` também saem `false`, mas isso
|
|
612
|
+
* não significa "bloco externo inteiro": significa apenas que a seleção
|
|
613
|
+
* tocou as bordas do bloco). Só produtores de blocos externos inteiros
|
|
614
|
+
* (hoje: `htmlToSlice`) devem marcar `blockLevel: true`.
|
|
615
|
+
*/
|
|
616
|
+
blockLevel?: true;
|
|
598
617
|
}
|
|
599
618
|
/**
|
|
600
619
|
* Lê a seleção e produz um ClipboardSlice, ou null se:
|
|
@@ -673,7 +692,18 @@ declare function setCellAttr<K extends keyof CellAttrs>(ctx: CommandContext, key
|
|
|
673
692
|
declare function deleteSelection(ctx: CommandContext): void;
|
|
674
693
|
/**
|
|
675
694
|
* Replace the current selection with a clipboard slice (A1).
|
|
676
|
-
* - Single-block slice
|
|
695
|
+
* - Single-block slice WITHOUT `blockLevel` → always an inline splice
|
|
696
|
+
* (Dhead + S0 + Dtail), target keeps its type. This is the internal
|
|
697
|
+
* copy/paste shape, including a full-block internal copy (selecting an
|
|
698
|
+
* entire line and copying it also yields `openStart:false, openEnd:false`
|
|
699
|
+
* with one block — that is NOT the same thing as an external whole block;
|
|
700
|
+
* `openStart`/`openEnd` do not carry that distinction, so branching on them
|
|
701
|
+
* here regressed plain in-editor copy/paste. See `ClipboardSlice.blockLevel`.
|
|
702
|
+
* - Single-block slice WITH `blockLevel: true` (e.g. one <h1>/<li>/<blockquote>
|
|
703
|
+
* from an HTML paste via `htmlToSlice`) → adopts S0's type/attrs instead,
|
|
704
|
+
* same rules as the multi-block case below (reuse target in place when the
|
|
705
|
+
* caret is at offset 0, otherwise insert S0 as its own block; any tail
|
|
706
|
+
* becomes a separate block with the target's original type).
|
|
677
707
|
* - Multi-block slice → openStart merges S0 inline; middle/last blocks inserted
|
|
678
708
|
* discretely; openEnd appends the post-caret tail onto the last pasted block.
|
|
679
709
|
* - Target inside a table cell → slice flattened to inline (no block structure).
|
package/dist/index.js
CHANGED
|
@@ -768,8 +768,8 @@ function kebab(prop) {
|
|
|
768
768
|
// src/table-borders.ts
|
|
769
769
|
var TABLE_BORDER_COLOR = "#cbd5e1";
|
|
770
770
|
var TABLE_GUIDE_COLOR = "var(--ed-guide-color, transparent)";
|
|
771
|
-
function cellBorderColors(preset, pos, variant) {
|
|
772
|
-
const on = TABLE_BORDER_COLOR;
|
|
771
|
+
function cellBorderColors(preset, pos, variant, color) {
|
|
772
|
+
const on = color && color.length > 0 ? color : TABLE_BORDER_COLOR;
|
|
773
773
|
const off = variant === "screen" ? TABLE_GUIDE_COLOR : "transparent";
|
|
774
774
|
switch (preset ?? "all") {
|
|
775
775
|
case "horizontal":
|
|
@@ -795,8 +795,8 @@ function cellBorderColors(preset, pos, variant) {
|
|
|
795
795
|
return { top: on, right: on, bottom: on, left: on };
|
|
796
796
|
}
|
|
797
797
|
}
|
|
798
|
-
function cellBorderStyle(preset, pos, variant) {
|
|
799
|
-
const c = cellBorderColors(preset, pos, variant);
|
|
798
|
+
function cellBorderStyle(preset, pos, variant, color) {
|
|
799
|
+
const c = cellBorderColors(preset, pos, variant, color);
|
|
800
800
|
return {
|
|
801
801
|
borderTopColor: c.top,
|
|
802
802
|
borderRightColor: c.right,
|
|
@@ -1190,6 +1190,34 @@ function insertSlice(ctx, slice) {
|
|
|
1190
1190
|
const tailDelta = sliceDelta(full, offset, deltaLength(full));
|
|
1191
1191
|
targetText.delete(offset, targetText.length - offset);
|
|
1192
1192
|
const blocks = slice.blocks;
|
|
1193
|
+
if (blocks.length === 1 && slice.blockLevel) {
|
|
1194
|
+
const originalType2 = ctx.doc.getBlockType(blockIndex);
|
|
1195
|
+
const originalAttrs2 = ctx.doc.getBlockAttrs(blockIndex);
|
|
1196
|
+
let hostIndex = blockIndex;
|
|
1197
|
+
if (offset === 0) {
|
|
1198
|
+
const blk = ctx.doc.blocks.get(blockIndex);
|
|
1199
|
+
blk.set("type", blocks[0].type);
|
|
1200
|
+
const am = blk.get("attrs");
|
|
1201
|
+
am.clear();
|
|
1202
|
+
for (const [k, v] of Object.entries(blocks[0].attrs)) {
|
|
1203
|
+
if (v !== void 0) am.set(k, v);
|
|
1204
|
+
}
|
|
1205
|
+
writeDeltaInto(targetText, 0, blocks[0].delta);
|
|
1206
|
+
} else {
|
|
1207
|
+
hostIndex = blockIndex + 1;
|
|
1208
|
+
const b = createBlock(blocks[0].type, "", blocks[0].attrs);
|
|
1209
|
+
ctx.doc.blocks.insert(hostIndex, [b]);
|
|
1210
|
+
writeDeltaInto(b.get("text"), 0, blocks[0].delta);
|
|
1211
|
+
}
|
|
1212
|
+
const caretPos = ctx.doc.getBlockText(hostIndex).length;
|
|
1213
|
+
if (tailDelta.length > 0) {
|
|
1214
|
+
const tb = createBlock(originalType2 ?? "paragraph", "", originalAttrs2);
|
|
1215
|
+
ctx.doc.blocks.insert(hostIndex + 1, [tb]);
|
|
1216
|
+
writeDeltaInto(tb.get("text"), 0, tailDelta);
|
|
1217
|
+
}
|
|
1218
|
+
ctx.setSelection(collapsedSelection({ blockIndex: hostIndex, offset: caretPos }));
|
|
1219
|
+
return;
|
|
1220
|
+
}
|
|
1193
1221
|
if (blocks.length === 1) {
|
|
1194
1222
|
const afterS0 = writeDeltaInto(targetText, offset, blocks[0].delta);
|
|
1195
1223
|
writeDeltaInto(targetText, afterS0, tailDelta);
|