@sofereditor/core 0.3.2 → 0.4.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 +132 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +156 -2
- package/dist/index.d.ts +156 -2
- package/dist/index.js +119 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -91,6 +91,13 @@ type ListKind = "bullet" | "ordered";
|
|
|
91
91
|
type ListStyleType = "decimal" | "lower-alpha" | "upper-alpha" | "lower-roman" | "upper-roman";
|
|
92
92
|
/** Maximum supported list nesting (0 = top level). */
|
|
93
93
|
declare const MAX_LIST_LEVEL = 5;
|
|
94
|
+
/** Entrelinha de uma linha de resposta: simples, 1,5 ou dupla. */
|
|
95
|
+
type AnswerLineSpacing = 1 | 1.5 | 2;
|
|
96
|
+
/**
|
|
97
|
+
* Onde as linhas da grade de uma tabela aparecem.
|
|
98
|
+
* Vocabulário nativo de `w:tblBorders` (top/left/bottom/right/insideH/insideV).
|
|
99
|
+
*/
|
|
100
|
+
type TableBorderPreset = "all" | "outer" | "horizontal" | "vertical" | "none";
|
|
94
101
|
interface BlockAttrs {
|
|
95
102
|
align?: AlignValue;
|
|
96
103
|
dir?: DirValue;
|
|
@@ -126,6 +133,24 @@ interface BlockAttrs {
|
|
|
126
133
|
* an auto distribution at render time.
|
|
127
134
|
*/
|
|
128
135
|
colWidths?: number[];
|
|
136
|
+
/**
|
|
137
|
+
* Só relevante quando `type === "table"`. Onde as linhas da grade aparecem.
|
|
138
|
+
* Ausente = "all" — documentos existentes não mudam de aparência.
|
|
139
|
+
*/
|
|
140
|
+
borderPreset?: TableBorderPreset;
|
|
141
|
+
/**
|
|
142
|
+
* Só relevante quando `type === "paragraph"`. Parágrafo pautado para o aluno
|
|
143
|
+
* escrever a resposta: renderiza com régua inferior de largura total.
|
|
144
|
+
*/
|
|
145
|
+
answerLine?: true;
|
|
146
|
+
/**
|
|
147
|
+
* Só relevante quando `answerLine`. Entrelinha. Ausente = 1.
|
|
148
|
+
*
|
|
149
|
+
* Deliberadamente escopado a linhas de resposta em vez de um `lineSpacing`
|
|
150
|
+
* genérico de parágrafo: entrelinha geral mudaria a medição de paginação de
|
|
151
|
+
* TODO parágrafo do documento, o que é outra feature com outro raio de impacto.
|
|
152
|
+
*/
|
|
153
|
+
answerLineSpacing?: AnswerLineSpacing;
|
|
129
154
|
}
|
|
130
155
|
interface CellAttrs {
|
|
131
156
|
/**
|
|
@@ -165,7 +190,7 @@ interface Selection {
|
|
|
165
190
|
anchor: Position;
|
|
166
191
|
focus: Position;
|
|
167
192
|
}
|
|
168
|
-
type MarkName = "bold" | "italic" | "underline" | "strike" | "color" | "fontFamily" | "fontSize" | "link" | "comment";
|
|
193
|
+
type MarkName = "bold" | "italic" | "underline" | "strike" | "color" | "highlight" | "fontFamily" | "fontSize" | "link" | "comment";
|
|
169
194
|
interface LinkAttr {
|
|
170
195
|
href: string;
|
|
171
196
|
title?: string;
|
|
@@ -180,6 +205,8 @@ interface MarkAttrs {
|
|
|
180
205
|
underline?: true;
|
|
181
206
|
strike?: true;
|
|
182
207
|
color?: string;
|
|
208
|
+
/** Cor de fundo do texto (marca-texto). CSS color, ex. `#fff176`. */
|
|
209
|
+
highlight?: string;
|
|
183
210
|
fontFamily?: string;
|
|
184
211
|
fontSize?: string;
|
|
185
212
|
link?: LinkAttr;
|
|
@@ -450,6 +477,115 @@ declare function deltaLength(delta: DeltaOp[]): number;
|
|
|
450
477
|
*/
|
|
451
478
|
declare function sliceDelta(delta: DeltaOp[], start: number, end: number): DeltaOp[];
|
|
452
479
|
|
|
480
|
+
/**
|
|
481
|
+
* Helpers puros de decoração visual, compartilhados pelos DOIS renderizadores
|
|
482
|
+
* (`@sofereditor/react` e `@sofereditor/export-pdf`).
|
|
483
|
+
*
|
|
484
|
+
* Ficam aqui, e não dentro de cada renderizador, porque decoração divergente
|
|
485
|
+
* entre editor e PDF é exatamente o modo de falha que a fidelidade de impressão
|
|
486
|
+
* do projeto existe para impedir.
|
|
487
|
+
*/
|
|
488
|
+
|
|
489
|
+
/** Estilo CSS em camelCase — compatível com `CSSProperties` do React. */
|
|
490
|
+
type StyleRecord = Record<string, string>;
|
|
491
|
+
/** Mínimo de underlines consecutivos que viram lacuna. */
|
|
492
|
+
declare const BLANK_MIN_RUN = 3;
|
|
493
|
+
/**
|
|
494
|
+
* Segmenta um texto em trechos normais e corridas de `BLANK_MIN_RUN`+ underlines.
|
|
495
|
+
*
|
|
496
|
+
* INVARIANTE: a concatenação dos segmentos reconstrói o texto original
|
|
497
|
+
* caractere a caractere. Os offsets do modelo dependem disso — `dom-bridge`
|
|
498
|
+
* mapeia posição de DOM para offset somando `textContent.length`, então dividir
|
|
499
|
+
* uma run em sub-spans é seguro, mas introduzir ou remover caracteres não é.
|
|
500
|
+
*/
|
|
501
|
+
declare function splitUnderscoreRuns(text: string): Array<{
|
|
502
|
+
text: string;
|
|
503
|
+
blank: boolean;
|
|
504
|
+
}>;
|
|
505
|
+
/**
|
|
506
|
+
* Estilo da lacuna: uma corrida de underlines vira um traço contínuo, sem
|
|
507
|
+
* serrilhado, com a largura exata da sequência digitada.
|
|
508
|
+
*
|
|
509
|
+
* `-webkit-text-fill-color` apaga o GLIFO mas preserva `color`.
|
|
510
|
+
*
|
|
511
|
+
* O traço é `border-bottom`, e NÃO `text-decoration: underline`: no Chrome o
|
|
512
|
+
* `-webkit-text-fill-color` também apaga a decoração de texto — inclusive com
|
|
513
|
+
* `text-decoration-color: currentColor`, que resolve para a cor de
|
|
514
|
+
* PREENCHIMENTO, não para `color`. Verificado no navegador: a variante com
|
|
515
|
+
* `underline` renderiza uma lacuna completamente invisível. `border-bottom`
|
|
516
|
+
* com `currentColor` resolve para `color` e acompanha a mark de cor do run.
|
|
517
|
+
*
|
|
518
|
+
* PROIBIDO acrescentar aqui: `display`, `padding`, `margin`, `letterSpacing`,
|
|
519
|
+
* `width`. Qualquer um desloca métricas e a paginação diverge do PDF. Bordas de
|
|
520
|
+
* elemento inline não afetam a altura da linha — medido: linha com e sem
|
|
521
|
+
* lacuna tem exatamente a mesma altura e a mesma largura.
|
|
522
|
+
*/
|
|
523
|
+
declare const BLANK_STYLE: StyleRecord;
|
|
524
|
+
/** Cor da régua da linha de resposta. Preto: é uma linha para escrever à caneta. */
|
|
525
|
+
declare const ANSWER_LINE_COLOR = "#000000";
|
|
526
|
+
/**
|
|
527
|
+
* Estilo do parágrafo pautado. `undefined` quando o bloco não é linha de
|
|
528
|
+
* resposta, para o renderizador não emitir atributo `style` à toa.
|
|
529
|
+
*
|
|
530
|
+
* Diferente das bordas de tabela (cuja geometria é invariante por construção),
|
|
531
|
+
* `lineHeight` muda a altura medida do bloco DE PROPÓSITO — a paginação precisa
|
|
532
|
+
* medir o resultado, não presumir a entrelinha.
|
|
533
|
+
*/
|
|
534
|
+
declare function answerLineStyle(attrs: BlockAttrs): StyleRecord | undefined;
|
|
535
|
+
/** Converte um `StyleRecord` camelCase em texto CSS (`a:b;c:d`). */
|
|
536
|
+
declare function styleToCssText(style: StyleRecord): string;
|
|
537
|
+
|
|
538
|
+
/** Cor da grade. Mesmo valor que o CSS de `.ed-cell` já usa. */
|
|
539
|
+
declare const TABLE_BORDER_COLOR = "#cbd5e1";
|
|
540
|
+
/**
|
|
541
|
+
* Guia de tela para lados de borda desligados por preset.
|
|
542
|
+
*
|
|
543
|
+
* É uma custom property com fallback `transparent`: sem a variável definida
|
|
544
|
+
* (consumidor sem CSS próprio, ou dentro de `@media print`), o lado
|
|
545
|
+
* simplesmente não aparece — que é o correto para impressão. Nunca muda a
|
|
546
|
+
* geometria: o lado continua com 1px, só sem cor.
|
|
547
|
+
*/
|
|
548
|
+
declare const TABLE_GUIDE_COLOR = "var(--ed-guide-color, transparent)";
|
|
549
|
+
interface CellBorderPos {
|
|
550
|
+
/** Linha absoluta da célula na tabela lógica. */
|
|
551
|
+
row: number;
|
|
552
|
+
/** Coluna absoluta. */
|
|
553
|
+
col: number;
|
|
554
|
+
rowspan: number;
|
|
555
|
+
colspan: number;
|
|
556
|
+
/** Total de colunas da tabela. */
|
|
557
|
+
cols: number;
|
|
558
|
+
/** Primeira linha do fragmento renderizado. Tabela inteira = 0. */
|
|
559
|
+
rowStart: number;
|
|
560
|
+
/** Fim exclusivo do fragmento. Tabela inteira = `rows`. */
|
|
561
|
+
rowEnd: number;
|
|
562
|
+
}
|
|
563
|
+
interface CellBorderColors {
|
|
564
|
+
top: string;
|
|
565
|
+
right: string;
|
|
566
|
+
bottom: string;
|
|
567
|
+
left: string;
|
|
568
|
+
}
|
|
569
|
+
/**
|
|
570
|
+
* Cor de cada lado da célula segundo o preset.
|
|
571
|
+
*
|
|
572
|
+
* NUNCA devolve espessura. Trocar de preset muda só cor, então nenhuma linha
|
|
573
|
+
* reflui e a paginação já validada não se mexe. Como todas as bordas têm a
|
|
574
|
+
* mesma espessura e o mesmo estilo em toda a tabela, também não há conflito de
|
|
575
|
+
* `border-collapse` para resolver.
|
|
576
|
+
*
|
|
577
|
+
* As bordas externas seguem os limites do FRAGMENTO, não da tabela lógica: numa
|
|
578
|
+
* tabela quebrada entre páginas, cada página fecha a própria caixa — o
|
|
579
|
+
* comportamento do Word.
|
|
580
|
+
*
|
|
581
|
+
* O teste de "toca a borda" usa row/col + spans em vez dos seletores CSS
|
|
582
|
+
* `:first-child`/`:last-child`, que quebram assim que uma célula `covered` some
|
|
583
|
+
* do DOM por causa de um rowspan.
|
|
584
|
+
*/
|
|
585
|
+
declare function cellBorderColors(preset: TableBorderPreset | undefined, pos: CellBorderPos, variant: "screen" | "print"): CellBorderColors;
|
|
586
|
+
/** `cellBorderColors` no formato de estilo inline consumido pelos renderizadores. */
|
|
587
|
+
declare function cellBorderStyle(preset: TableBorderPreset | undefined, pos: CellBorderPos, variant: "screen" | "print"): StyleRecord;
|
|
588
|
+
|
|
453
589
|
/** MIME custom que carrega o slice serializado no clipboard. */
|
|
454
590
|
declare const SOFER_MIME = "application/x-sofer-slice";
|
|
455
591
|
interface ClipboardSlice {
|
|
@@ -515,6 +651,14 @@ declare function setBlockType(ctx: CommandContext, type: BlockType, attrs?: Bloc
|
|
|
515
651
|
* Passing `value === null` deletes the key.
|
|
516
652
|
*/
|
|
517
653
|
declare function setBlockAttr<K extends keyof BlockAttrs>(ctx: CommandContext, key: K, value: BlockAttrs[K] | null): void;
|
|
654
|
+
/**
|
|
655
|
+
* Como `setBlockAttr`, mas em um bloco específico por índice.
|
|
656
|
+
*
|
|
657
|
+
* Existe porque `setBlockAttr` opera sobre a seleção e é INERTE quando o caret
|
|
658
|
+
* está dentro de uma célula — que é exatamente a situação em que se quer mudar
|
|
659
|
+
* um atributo da tabela (ex.: preset de borda).
|
|
660
|
+
*/
|
|
661
|
+
declare function setBlockAttrAtIndex<K extends keyof BlockAttrs>(ctx: CommandContext, blockIndex: number, key: K, value: BlockAttrs[K] | null): void;
|
|
518
662
|
/**
|
|
519
663
|
* Set a single attribute on the table cell(s) under the selection.
|
|
520
664
|
* - Caret numa única célula → essa célula (tableRectSelection retorna null
|
|
@@ -567,6 +711,16 @@ declare function splitListItem(ctx: CommandContext): boolean;
|
|
|
567
711
|
* preceding paragraph. Callers can clean that up themselves; an extra empty
|
|
568
712
|
* paragraph above a table is a small price for predictable behavior.
|
|
569
713
|
*/
|
|
714
|
+
/** Teto de linhas por inserção — protege contra digitar 5000 no popover. */
|
|
715
|
+
declare const ANSWER_LINE_MAX = 50;
|
|
716
|
+
/**
|
|
717
|
+
* Insere `count` parágrafos pautados depois do bloco focado, numa única
|
|
718
|
+
* transação (um passo de undo desfaz todos).
|
|
719
|
+
*
|
|
720
|
+
* Se o caret estiver dentro de uma célula, `focus.blockIndex` já aponta para a
|
|
721
|
+
* TABELA, então as linhas entram depois dela — nunca dentro.
|
|
722
|
+
*/
|
|
723
|
+
declare function insertAnswerLines(ctx: CommandContext, count: number, spacing: AnswerLineSpacing): void;
|
|
570
724
|
declare function insertTable(ctx: CommandContext, rows: number, cols: number): void;
|
|
571
725
|
/** Remove the entire table at `blockIndex` and place the caret at the start of the next block (or the previous one if removal would leave the doc empty). */
|
|
572
726
|
declare function deleteTable(ctx: CommandContext, blockIndex: number): void;
|
|
@@ -732,4 +886,4 @@ declare class EditorHistory {
|
|
|
732
886
|
destroy(): void;
|
|
733
887
|
}
|
|
734
888
|
|
|
735
|
-
export { type AlignValue, BLOCK_SPECS, type BlockAttrs, type BlockType, CLEAR_ALL_MARKS, COMMAND_ORIGIN, type CellAttrs, type ClipboardSlice, type CommandContext, type CommentAttr, DEFAULT_PAGE_SETTINGS, type DeltaOp, type DirValue, EditorDocument, EditorHistory, type EmbedLoc, type EncodedCursor, type EncodedCursorPoint, type ImageEmbed, type ImageLayout, type InsertContent, type LegacySerializedDocument, type LinkAttr, type ListKind, type ListStyleType, MARGIN_PRESETS, MAX_LIST_LEVEL, type MarkAttrs, type MarkName, type MarkValue, PAGE_PRESETS, type PagePreset, type PageSettings, type Position, SOFER_MIME, type Selection, type SerializedBlock, type SerializedCell, type SerializedDocument, TRACKED_ORIGINS, type TableLocation, type TableRect, cellsInRect, clearRectCells, collapsedSelection, comparePositions, createBlock, createCell, createTableBlock, decodeSelection, dedentList, defaultAttrsFor, deleteBackward, deleteForward, deleteSelection, deleteTable, deleteTableColumn, deleteTableRow, deltaLength, detectPreset, encodeSelection, expandTableRect, getBlockId, getMarksInRange, indentList, insertImage, insertParagraph, insertSlice, insertTable, insertTableColumn, insertTableRow, insertText, isCollapsed, isCommandOrigin, isImageEmbed, isKnownBlockType, isLegacySerializedDocument, isMarkUniformInRange, mergeDown, mergeRight, mergeSelection, mmToPx, moveEmbedAnchor, moveToNextCell, moveToPrevCell, newBlockId, orderedRange, positionsEqual, pxToMm, removeMark, sameTextRun, serializeSelection, setBlockAttr, setBlockType, setCellAttr, setColumnWidth, setImageAttrs, setMark, sliceDelta, sliceToInlineDelta, sliceToText, spanOf, splitCell, splitListItem, tableLocationOf, tableRectSelection, toggleList, toggleMark, withDefaults };
|
|
889
|
+
export { ANSWER_LINE_COLOR, ANSWER_LINE_MAX, type AlignValue, type AnswerLineSpacing, BLANK_MIN_RUN, BLANK_STYLE, BLOCK_SPECS, type BlockAttrs, type BlockType, CLEAR_ALL_MARKS, COMMAND_ORIGIN, type CellAttrs, type CellBorderColors, type CellBorderPos, type ClipboardSlice, type CommandContext, type CommentAttr, DEFAULT_PAGE_SETTINGS, type DeltaOp, type DirValue, EditorDocument, EditorHistory, type EmbedLoc, type EncodedCursor, type EncodedCursorPoint, type ImageEmbed, type ImageLayout, type InsertContent, type LegacySerializedDocument, type LinkAttr, type ListKind, type ListStyleType, MARGIN_PRESETS, MAX_LIST_LEVEL, type MarkAttrs, type MarkName, type MarkValue, PAGE_PRESETS, type PagePreset, type PageSettings, type Position, SOFER_MIME, type Selection, type SerializedBlock, type SerializedCell, type SerializedDocument, type StyleRecord, TABLE_BORDER_COLOR, TABLE_GUIDE_COLOR, TRACKED_ORIGINS, type TableBorderPreset, type TableLocation, type TableRect, answerLineStyle, cellBorderColors, cellBorderStyle, cellsInRect, clearRectCells, collapsedSelection, comparePositions, createBlock, createCell, createTableBlock, decodeSelection, dedentList, defaultAttrsFor, deleteBackward, deleteForward, deleteSelection, deleteTable, deleteTableColumn, deleteTableRow, deltaLength, detectPreset, encodeSelection, expandTableRect, getBlockId, getMarksInRange, indentList, insertAnswerLines, insertImage, insertParagraph, insertSlice, insertTable, insertTableColumn, insertTableRow, insertText, isCollapsed, isCommandOrigin, isImageEmbed, isKnownBlockType, isLegacySerializedDocument, isMarkUniformInRange, mergeDown, mergeRight, mergeSelection, mmToPx, moveEmbedAnchor, moveToNextCell, moveToPrevCell, newBlockId, orderedRange, positionsEqual, pxToMm, removeMark, sameTextRun, serializeSelection, setBlockAttr, setBlockAttrAtIndex, setBlockType, setCellAttr, setColumnWidth, setImageAttrs, setMark, sliceDelta, sliceToInlineDelta, sliceToText, spanOf, splitCell, splitListItem, splitUnderscoreRuns, styleToCssText, tableLocationOf, tableRectSelection, toggleList, toggleMark, withDefaults };
|
package/dist/index.d.ts
CHANGED
|
@@ -91,6 +91,13 @@ type ListKind = "bullet" | "ordered";
|
|
|
91
91
|
type ListStyleType = "decimal" | "lower-alpha" | "upper-alpha" | "lower-roman" | "upper-roman";
|
|
92
92
|
/** Maximum supported list nesting (0 = top level). */
|
|
93
93
|
declare const MAX_LIST_LEVEL = 5;
|
|
94
|
+
/** Entrelinha de uma linha de resposta: simples, 1,5 ou dupla. */
|
|
95
|
+
type AnswerLineSpacing = 1 | 1.5 | 2;
|
|
96
|
+
/**
|
|
97
|
+
* Onde as linhas da grade de uma tabela aparecem.
|
|
98
|
+
* Vocabulário nativo de `w:tblBorders` (top/left/bottom/right/insideH/insideV).
|
|
99
|
+
*/
|
|
100
|
+
type TableBorderPreset = "all" | "outer" | "horizontal" | "vertical" | "none";
|
|
94
101
|
interface BlockAttrs {
|
|
95
102
|
align?: AlignValue;
|
|
96
103
|
dir?: DirValue;
|
|
@@ -126,6 +133,24 @@ interface BlockAttrs {
|
|
|
126
133
|
* an auto distribution at render time.
|
|
127
134
|
*/
|
|
128
135
|
colWidths?: number[];
|
|
136
|
+
/**
|
|
137
|
+
* Só relevante quando `type === "table"`. Onde as linhas da grade aparecem.
|
|
138
|
+
* Ausente = "all" — documentos existentes não mudam de aparência.
|
|
139
|
+
*/
|
|
140
|
+
borderPreset?: TableBorderPreset;
|
|
141
|
+
/**
|
|
142
|
+
* Só relevante quando `type === "paragraph"`. Parágrafo pautado para o aluno
|
|
143
|
+
* escrever a resposta: renderiza com régua inferior de largura total.
|
|
144
|
+
*/
|
|
145
|
+
answerLine?: true;
|
|
146
|
+
/**
|
|
147
|
+
* Só relevante quando `answerLine`. Entrelinha. Ausente = 1.
|
|
148
|
+
*
|
|
149
|
+
* Deliberadamente escopado a linhas de resposta em vez de um `lineSpacing`
|
|
150
|
+
* genérico de parágrafo: entrelinha geral mudaria a medição de paginação de
|
|
151
|
+
* TODO parágrafo do documento, o que é outra feature com outro raio de impacto.
|
|
152
|
+
*/
|
|
153
|
+
answerLineSpacing?: AnswerLineSpacing;
|
|
129
154
|
}
|
|
130
155
|
interface CellAttrs {
|
|
131
156
|
/**
|
|
@@ -165,7 +190,7 @@ interface Selection {
|
|
|
165
190
|
anchor: Position;
|
|
166
191
|
focus: Position;
|
|
167
192
|
}
|
|
168
|
-
type MarkName = "bold" | "italic" | "underline" | "strike" | "color" | "fontFamily" | "fontSize" | "link" | "comment";
|
|
193
|
+
type MarkName = "bold" | "italic" | "underline" | "strike" | "color" | "highlight" | "fontFamily" | "fontSize" | "link" | "comment";
|
|
169
194
|
interface LinkAttr {
|
|
170
195
|
href: string;
|
|
171
196
|
title?: string;
|
|
@@ -180,6 +205,8 @@ interface MarkAttrs {
|
|
|
180
205
|
underline?: true;
|
|
181
206
|
strike?: true;
|
|
182
207
|
color?: string;
|
|
208
|
+
/** Cor de fundo do texto (marca-texto). CSS color, ex. `#fff176`. */
|
|
209
|
+
highlight?: string;
|
|
183
210
|
fontFamily?: string;
|
|
184
211
|
fontSize?: string;
|
|
185
212
|
link?: LinkAttr;
|
|
@@ -450,6 +477,115 @@ declare function deltaLength(delta: DeltaOp[]): number;
|
|
|
450
477
|
*/
|
|
451
478
|
declare function sliceDelta(delta: DeltaOp[], start: number, end: number): DeltaOp[];
|
|
452
479
|
|
|
480
|
+
/**
|
|
481
|
+
* Helpers puros de decoração visual, compartilhados pelos DOIS renderizadores
|
|
482
|
+
* (`@sofereditor/react` e `@sofereditor/export-pdf`).
|
|
483
|
+
*
|
|
484
|
+
* Ficam aqui, e não dentro de cada renderizador, porque decoração divergente
|
|
485
|
+
* entre editor e PDF é exatamente o modo de falha que a fidelidade de impressão
|
|
486
|
+
* do projeto existe para impedir.
|
|
487
|
+
*/
|
|
488
|
+
|
|
489
|
+
/** Estilo CSS em camelCase — compatível com `CSSProperties` do React. */
|
|
490
|
+
type StyleRecord = Record<string, string>;
|
|
491
|
+
/** Mínimo de underlines consecutivos que viram lacuna. */
|
|
492
|
+
declare const BLANK_MIN_RUN = 3;
|
|
493
|
+
/**
|
|
494
|
+
* Segmenta um texto em trechos normais e corridas de `BLANK_MIN_RUN`+ underlines.
|
|
495
|
+
*
|
|
496
|
+
* INVARIANTE: a concatenação dos segmentos reconstrói o texto original
|
|
497
|
+
* caractere a caractere. Os offsets do modelo dependem disso — `dom-bridge`
|
|
498
|
+
* mapeia posição de DOM para offset somando `textContent.length`, então dividir
|
|
499
|
+
* uma run em sub-spans é seguro, mas introduzir ou remover caracteres não é.
|
|
500
|
+
*/
|
|
501
|
+
declare function splitUnderscoreRuns(text: string): Array<{
|
|
502
|
+
text: string;
|
|
503
|
+
blank: boolean;
|
|
504
|
+
}>;
|
|
505
|
+
/**
|
|
506
|
+
* Estilo da lacuna: uma corrida de underlines vira um traço contínuo, sem
|
|
507
|
+
* serrilhado, com a largura exata da sequência digitada.
|
|
508
|
+
*
|
|
509
|
+
* `-webkit-text-fill-color` apaga o GLIFO mas preserva `color`.
|
|
510
|
+
*
|
|
511
|
+
* O traço é `border-bottom`, e NÃO `text-decoration: underline`: no Chrome o
|
|
512
|
+
* `-webkit-text-fill-color` também apaga a decoração de texto — inclusive com
|
|
513
|
+
* `text-decoration-color: currentColor`, que resolve para a cor de
|
|
514
|
+
* PREENCHIMENTO, não para `color`. Verificado no navegador: a variante com
|
|
515
|
+
* `underline` renderiza uma lacuna completamente invisível. `border-bottom`
|
|
516
|
+
* com `currentColor` resolve para `color` e acompanha a mark de cor do run.
|
|
517
|
+
*
|
|
518
|
+
* PROIBIDO acrescentar aqui: `display`, `padding`, `margin`, `letterSpacing`,
|
|
519
|
+
* `width`. Qualquer um desloca métricas e a paginação diverge do PDF. Bordas de
|
|
520
|
+
* elemento inline não afetam a altura da linha — medido: linha com e sem
|
|
521
|
+
* lacuna tem exatamente a mesma altura e a mesma largura.
|
|
522
|
+
*/
|
|
523
|
+
declare const BLANK_STYLE: StyleRecord;
|
|
524
|
+
/** Cor da régua da linha de resposta. Preto: é uma linha para escrever à caneta. */
|
|
525
|
+
declare const ANSWER_LINE_COLOR = "#000000";
|
|
526
|
+
/**
|
|
527
|
+
* Estilo do parágrafo pautado. `undefined` quando o bloco não é linha de
|
|
528
|
+
* resposta, para o renderizador não emitir atributo `style` à toa.
|
|
529
|
+
*
|
|
530
|
+
* Diferente das bordas de tabela (cuja geometria é invariante por construção),
|
|
531
|
+
* `lineHeight` muda a altura medida do bloco DE PROPÓSITO — a paginação precisa
|
|
532
|
+
* medir o resultado, não presumir a entrelinha.
|
|
533
|
+
*/
|
|
534
|
+
declare function answerLineStyle(attrs: BlockAttrs): StyleRecord | undefined;
|
|
535
|
+
/** Converte um `StyleRecord` camelCase em texto CSS (`a:b;c:d`). */
|
|
536
|
+
declare function styleToCssText(style: StyleRecord): string;
|
|
537
|
+
|
|
538
|
+
/** Cor da grade. Mesmo valor que o CSS de `.ed-cell` já usa. */
|
|
539
|
+
declare const TABLE_BORDER_COLOR = "#cbd5e1";
|
|
540
|
+
/**
|
|
541
|
+
* Guia de tela para lados de borda desligados por preset.
|
|
542
|
+
*
|
|
543
|
+
* É uma custom property com fallback `transparent`: sem a variável definida
|
|
544
|
+
* (consumidor sem CSS próprio, ou dentro de `@media print`), o lado
|
|
545
|
+
* simplesmente não aparece — que é o correto para impressão. Nunca muda a
|
|
546
|
+
* geometria: o lado continua com 1px, só sem cor.
|
|
547
|
+
*/
|
|
548
|
+
declare const TABLE_GUIDE_COLOR = "var(--ed-guide-color, transparent)";
|
|
549
|
+
interface CellBorderPos {
|
|
550
|
+
/** Linha absoluta da célula na tabela lógica. */
|
|
551
|
+
row: number;
|
|
552
|
+
/** Coluna absoluta. */
|
|
553
|
+
col: number;
|
|
554
|
+
rowspan: number;
|
|
555
|
+
colspan: number;
|
|
556
|
+
/** Total de colunas da tabela. */
|
|
557
|
+
cols: number;
|
|
558
|
+
/** Primeira linha do fragmento renderizado. Tabela inteira = 0. */
|
|
559
|
+
rowStart: number;
|
|
560
|
+
/** Fim exclusivo do fragmento. Tabela inteira = `rows`. */
|
|
561
|
+
rowEnd: number;
|
|
562
|
+
}
|
|
563
|
+
interface CellBorderColors {
|
|
564
|
+
top: string;
|
|
565
|
+
right: string;
|
|
566
|
+
bottom: string;
|
|
567
|
+
left: string;
|
|
568
|
+
}
|
|
569
|
+
/**
|
|
570
|
+
* Cor de cada lado da célula segundo o preset.
|
|
571
|
+
*
|
|
572
|
+
* NUNCA devolve espessura. Trocar de preset muda só cor, então nenhuma linha
|
|
573
|
+
* reflui e a paginação já validada não se mexe. Como todas as bordas têm a
|
|
574
|
+
* mesma espessura e o mesmo estilo em toda a tabela, também não há conflito de
|
|
575
|
+
* `border-collapse` para resolver.
|
|
576
|
+
*
|
|
577
|
+
* As bordas externas seguem os limites do FRAGMENTO, não da tabela lógica: numa
|
|
578
|
+
* tabela quebrada entre páginas, cada página fecha a própria caixa — o
|
|
579
|
+
* comportamento do Word.
|
|
580
|
+
*
|
|
581
|
+
* O teste de "toca a borda" usa row/col + spans em vez dos seletores CSS
|
|
582
|
+
* `:first-child`/`:last-child`, que quebram assim que uma célula `covered` some
|
|
583
|
+
* do DOM por causa de um rowspan.
|
|
584
|
+
*/
|
|
585
|
+
declare function cellBorderColors(preset: TableBorderPreset | undefined, pos: CellBorderPos, variant: "screen" | "print"): CellBorderColors;
|
|
586
|
+
/** `cellBorderColors` no formato de estilo inline consumido pelos renderizadores. */
|
|
587
|
+
declare function cellBorderStyle(preset: TableBorderPreset | undefined, pos: CellBorderPos, variant: "screen" | "print"): StyleRecord;
|
|
588
|
+
|
|
453
589
|
/** MIME custom que carrega o slice serializado no clipboard. */
|
|
454
590
|
declare const SOFER_MIME = "application/x-sofer-slice";
|
|
455
591
|
interface ClipboardSlice {
|
|
@@ -515,6 +651,14 @@ declare function setBlockType(ctx: CommandContext, type: BlockType, attrs?: Bloc
|
|
|
515
651
|
* Passing `value === null` deletes the key.
|
|
516
652
|
*/
|
|
517
653
|
declare function setBlockAttr<K extends keyof BlockAttrs>(ctx: CommandContext, key: K, value: BlockAttrs[K] | null): void;
|
|
654
|
+
/**
|
|
655
|
+
* Como `setBlockAttr`, mas em um bloco específico por índice.
|
|
656
|
+
*
|
|
657
|
+
* Existe porque `setBlockAttr` opera sobre a seleção e é INERTE quando o caret
|
|
658
|
+
* está dentro de uma célula — que é exatamente a situação em que se quer mudar
|
|
659
|
+
* um atributo da tabela (ex.: preset de borda).
|
|
660
|
+
*/
|
|
661
|
+
declare function setBlockAttrAtIndex<K extends keyof BlockAttrs>(ctx: CommandContext, blockIndex: number, key: K, value: BlockAttrs[K] | null): void;
|
|
518
662
|
/**
|
|
519
663
|
* Set a single attribute on the table cell(s) under the selection.
|
|
520
664
|
* - Caret numa única célula → essa célula (tableRectSelection retorna null
|
|
@@ -567,6 +711,16 @@ declare function splitListItem(ctx: CommandContext): boolean;
|
|
|
567
711
|
* preceding paragraph. Callers can clean that up themselves; an extra empty
|
|
568
712
|
* paragraph above a table is a small price for predictable behavior.
|
|
569
713
|
*/
|
|
714
|
+
/** Teto de linhas por inserção — protege contra digitar 5000 no popover. */
|
|
715
|
+
declare const ANSWER_LINE_MAX = 50;
|
|
716
|
+
/**
|
|
717
|
+
* Insere `count` parágrafos pautados depois do bloco focado, numa única
|
|
718
|
+
* transação (um passo de undo desfaz todos).
|
|
719
|
+
*
|
|
720
|
+
* Se o caret estiver dentro de uma célula, `focus.blockIndex` já aponta para a
|
|
721
|
+
* TABELA, então as linhas entram depois dela — nunca dentro.
|
|
722
|
+
*/
|
|
723
|
+
declare function insertAnswerLines(ctx: CommandContext, count: number, spacing: AnswerLineSpacing): void;
|
|
570
724
|
declare function insertTable(ctx: CommandContext, rows: number, cols: number): void;
|
|
571
725
|
/** Remove the entire table at `blockIndex` and place the caret at the start of the next block (or the previous one if removal would leave the doc empty). */
|
|
572
726
|
declare function deleteTable(ctx: CommandContext, blockIndex: number): void;
|
|
@@ -732,4 +886,4 @@ declare class EditorHistory {
|
|
|
732
886
|
destroy(): void;
|
|
733
887
|
}
|
|
734
888
|
|
|
735
|
-
export { type AlignValue, BLOCK_SPECS, type BlockAttrs, type BlockType, CLEAR_ALL_MARKS, COMMAND_ORIGIN, type CellAttrs, type ClipboardSlice, type CommandContext, type CommentAttr, DEFAULT_PAGE_SETTINGS, type DeltaOp, type DirValue, EditorDocument, EditorHistory, type EmbedLoc, type EncodedCursor, type EncodedCursorPoint, type ImageEmbed, type ImageLayout, type InsertContent, type LegacySerializedDocument, type LinkAttr, type ListKind, type ListStyleType, MARGIN_PRESETS, MAX_LIST_LEVEL, type MarkAttrs, type MarkName, type MarkValue, PAGE_PRESETS, type PagePreset, type PageSettings, type Position, SOFER_MIME, type Selection, type SerializedBlock, type SerializedCell, type SerializedDocument, TRACKED_ORIGINS, type TableLocation, type TableRect, cellsInRect, clearRectCells, collapsedSelection, comparePositions, createBlock, createCell, createTableBlock, decodeSelection, dedentList, defaultAttrsFor, deleteBackward, deleteForward, deleteSelection, deleteTable, deleteTableColumn, deleteTableRow, deltaLength, detectPreset, encodeSelection, expandTableRect, getBlockId, getMarksInRange, indentList, insertImage, insertParagraph, insertSlice, insertTable, insertTableColumn, insertTableRow, insertText, isCollapsed, isCommandOrigin, isImageEmbed, isKnownBlockType, isLegacySerializedDocument, isMarkUniformInRange, mergeDown, mergeRight, mergeSelection, mmToPx, moveEmbedAnchor, moveToNextCell, moveToPrevCell, newBlockId, orderedRange, positionsEqual, pxToMm, removeMark, sameTextRun, serializeSelection, setBlockAttr, setBlockType, setCellAttr, setColumnWidth, setImageAttrs, setMark, sliceDelta, sliceToInlineDelta, sliceToText, spanOf, splitCell, splitListItem, tableLocationOf, tableRectSelection, toggleList, toggleMark, withDefaults };
|
|
889
|
+
export { ANSWER_LINE_COLOR, ANSWER_LINE_MAX, type AlignValue, type AnswerLineSpacing, BLANK_MIN_RUN, BLANK_STYLE, BLOCK_SPECS, type BlockAttrs, type BlockType, CLEAR_ALL_MARKS, COMMAND_ORIGIN, type CellAttrs, type CellBorderColors, type CellBorderPos, type ClipboardSlice, type CommandContext, type CommentAttr, DEFAULT_PAGE_SETTINGS, type DeltaOp, type DirValue, EditorDocument, EditorHistory, type EmbedLoc, type EncodedCursor, type EncodedCursorPoint, type ImageEmbed, type ImageLayout, type InsertContent, type LegacySerializedDocument, type LinkAttr, type ListKind, type ListStyleType, MARGIN_PRESETS, MAX_LIST_LEVEL, type MarkAttrs, type MarkName, type MarkValue, PAGE_PRESETS, type PagePreset, type PageSettings, type Position, SOFER_MIME, type Selection, type SerializedBlock, type SerializedCell, type SerializedDocument, type StyleRecord, TABLE_BORDER_COLOR, TABLE_GUIDE_COLOR, TRACKED_ORIGINS, type TableBorderPreset, type TableLocation, type TableRect, answerLineStyle, cellBorderColors, cellBorderStyle, cellsInRect, clearRectCells, collapsedSelection, comparePositions, createBlock, createCell, createTableBlock, decodeSelection, dedentList, defaultAttrsFor, deleteBackward, deleteForward, deleteSelection, deleteTable, deleteTableColumn, deleteTableRow, deltaLength, detectPreset, encodeSelection, expandTableRect, getBlockId, getMarksInRange, indentList, insertAnswerLines, insertImage, insertParagraph, insertSlice, insertTable, insertTableColumn, insertTableRow, insertText, isCollapsed, isCommandOrigin, isImageEmbed, isKnownBlockType, isLegacySerializedDocument, isMarkUniformInRange, mergeDown, mergeRight, mergeSelection, mmToPx, moveEmbedAnchor, moveToNextCell, moveToPrevCell, newBlockId, orderedRange, positionsEqual, pxToMm, removeMark, sameTextRun, serializeSelection, setBlockAttr, setBlockAttrAtIndex, setBlockType, setCellAttr, setColumnWidth, setImageAttrs, setMark, sliceDelta, sliceToInlineDelta, sliceToText, spanOf, splitCell, splitListItem, splitUnderscoreRuns, styleToCssText, tableLocationOf, tableRectSelection, toggleList, toggleMark, withDefaults };
|
package/dist/index.js
CHANGED
|
@@ -591,6 +591,7 @@ var ALL_MARKS = {
|
|
|
591
591
|
underline: true,
|
|
592
592
|
strike: true,
|
|
593
593
|
color: true,
|
|
594
|
+
highlight: true,
|
|
594
595
|
fontFamily: true,
|
|
595
596
|
fontSize: true,
|
|
596
597
|
link: true,
|
|
@@ -722,6 +723,88 @@ function sameMarkValue(a, b) {
|
|
|
722
723
|
return false;
|
|
723
724
|
}
|
|
724
725
|
|
|
726
|
+
// src/decorations.ts
|
|
727
|
+
var BLANK_MIN_RUN = 3;
|
|
728
|
+
function splitUnderscoreRuns(text) {
|
|
729
|
+
if (text.length === 0) return [];
|
|
730
|
+
const re = new RegExp(`_{${BLANK_MIN_RUN},}`, "g");
|
|
731
|
+
const out = [];
|
|
732
|
+
let last = 0;
|
|
733
|
+
let match;
|
|
734
|
+
while ((match = re.exec(text)) !== null) {
|
|
735
|
+
if (match.index > last) out.push({ text: text.slice(last, match.index), blank: false });
|
|
736
|
+
out.push({ text: match[0], blank: true });
|
|
737
|
+
last = match.index + match[0].length;
|
|
738
|
+
}
|
|
739
|
+
if (last < text.length) out.push({ text: text.slice(last), blank: false });
|
|
740
|
+
return out;
|
|
741
|
+
}
|
|
742
|
+
var BLANK_STYLE = {
|
|
743
|
+
WebkitTextFillColor: "transparent",
|
|
744
|
+
borderBottom: "1px solid currentColor"
|
|
745
|
+
};
|
|
746
|
+
var ANSWER_LINE_COLOR = "#000000";
|
|
747
|
+
function answerLineStyle(attrs) {
|
|
748
|
+
if (attrs.answerLine !== true) return void 0;
|
|
749
|
+
const spacing = attrs.answerLineSpacing ?? 1;
|
|
750
|
+
return {
|
|
751
|
+
borderBottom: `1px solid ${ANSWER_LINE_COLOR}`,
|
|
752
|
+
lineHeight: String(spacing),
|
|
753
|
+
// `minHeight` casado com a entrelinha, e NÃO redundante: o CSS do
|
|
754
|
+
// consumidor costuma trazer `min-height` em parágrafo (o playground usa
|
|
755
|
+
// 1.5em "para manter parágrafo vazio visível"). Sem esta linha, "Simples"
|
|
756
|
+
// e "1,5" renderizariam com a mesma altura.
|
|
757
|
+
minHeight: `${spacing}em`
|
|
758
|
+
};
|
|
759
|
+
}
|
|
760
|
+
function styleToCssText(style) {
|
|
761
|
+
return Object.entries(style).map(([k, v]) => `${kebab(k)}:${v}`).join(";");
|
|
762
|
+
}
|
|
763
|
+
function kebab(prop) {
|
|
764
|
+
if (prop.startsWith("--")) return prop;
|
|
765
|
+
return prop.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
// src/table-borders.ts
|
|
769
|
+
var TABLE_BORDER_COLOR = "#cbd5e1";
|
|
770
|
+
var TABLE_GUIDE_COLOR = "var(--ed-guide-color, transparent)";
|
|
771
|
+
function cellBorderColors(preset, pos, variant) {
|
|
772
|
+
const on = TABLE_BORDER_COLOR;
|
|
773
|
+
const off = variant === "screen" ? TABLE_GUIDE_COLOR : "transparent";
|
|
774
|
+
switch (preset ?? "all") {
|
|
775
|
+
case "horizontal":
|
|
776
|
+
return { top: on, right: off, bottom: on, left: off };
|
|
777
|
+
case "vertical":
|
|
778
|
+
return { top: off, right: on, bottom: off, left: on };
|
|
779
|
+
case "none":
|
|
780
|
+
return { top: off, right: off, bottom: off, left: off };
|
|
781
|
+
case "outer": {
|
|
782
|
+
const isTop = pos.row === pos.rowStart;
|
|
783
|
+
const isBottom = pos.row + Math.max(1, pos.rowspan) - 1 === pos.rowEnd - 1;
|
|
784
|
+
const isLeft = pos.col === 0;
|
|
785
|
+
const isRight = pos.col + Math.max(1, pos.colspan) - 1 === pos.cols - 1;
|
|
786
|
+
return {
|
|
787
|
+
top: isTop ? on : off,
|
|
788
|
+
right: isRight ? on : off,
|
|
789
|
+
bottom: isBottom ? on : off,
|
|
790
|
+
left: isLeft ? on : off
|
|
791
|
+
};
|
|
792
|
+
}
|
|
793
|
+
case "all":
|
|
794
|
+
default:
|
|
795
|
+
return { top: on, right: on, bottom: on, left: on };
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
function cellBorderStyle(preset, pos, variant) {
|
|
799
|
+
const c = cellBorderColors(preset, pos, variant);
|
|
800
|
+
return {
|
|
801
|
+
borderTopColor: c.top,
|
|
802
|
+
borderRightColor: c.right,
|
|
803
|
+
borderBottomColor: c.bottom,
|
|
804
|
+
borderLeftColor: c.left
|
|
805
|
+
};
|
|
806
|
+
}
|
|
807
|
+
|
|
725
808
|
// src/commands.ts
|
|
726
809
|
import * as Y3 from "yjs";
|
|
727
810
|
|
|
@@ -1046,6 +1129,16 @@ function setBlockAttr(ctx, key, value) {
|
|
|
1046
1129
|
ctx.setSelection(sel);
|
|
1047
1130
|
});
|
|
1048
1131
|
}
|
|
1132
|
+
function setBlockAttrAtIndex(ctx, blockIndex, key, value) {
|
|
1133
|
+
transact(ctx.doc, () => {
|
|
1134
|
+
const block = ctx.doc.getBlock(blockIndex);
|
|
1135
|
+
if (!block) return;
|
|
1136
|
+
const attrsMap = block.get("attrs") ?? new Y3.Map();
|
|
1137
|
+
if (!block.get("attrs")) block.set("attrs", attrsMap);
|
|
1138
|
+
if (value === null || value === void 0) attrsMap.delete(key);
|
|
1139
|
+
else attrsMap.set(key, value);
|
|
1140
|
+
});
|
|
1141
|
+
}
|
|
1049
1142
|
function setCellAttr(ctx, key, value) {
|
|
1050
1143
|
transact(ctx.doc, () => {
|
|
1051
1144
|
const sel = ctx.getSelection();
|
|
@@ -1314,6 +1407,19 @@ function clampLevel(l) {
|
|
|
1314
1407
|
if (typeof l !== "number" || !Number.isFinite(l)) return 0;
|
|
1315
1408
|
return Math.max(0, Math.min(MAX_LIST_LEVEL, Math.trunc(l)));
|
|
1316
1409
|
}
|
|
1410
|
+
var ANSWER_LINE_MAX = 50;
|
|
1411
|
+
function insertAnswerLines(ctx, count, spacing) {
|
|
1412
|
+
const n = Math.max(1, Math.min(ANSWER_LINE_MAX, Math.trunc(count)));
|
|
1413
|
+
transact(ctx.doc, () => {
|
|
1414
|
+
const sel = ctx.getSelection();
|
|
1415
|
+
const focusBlock = Math.max(0, Math.min(sel.focus.blockIndex, ctx.doc.blockCount() - 1));
|
|
1416
|
+
const insertAt = focusBlock + 1;
|
|
1417
|
+
const attrs = { answerLine: true, answerLineSpacing: spacing };
|
|
1418
|
+
const blocks = Array.from({ length: n }, () => createBlock("paragraph", "", attrs));
|
|
1419
|
+
ctx.doc.blocks.insert(insertAt, blocks);
|
|
1420
|
+
ctx.setSelection(collapsedSelection({ blockIndex: insertAt, offset: 0 }));
|
|
1421
|
+
});
|
|
1422
|
+
}
|
|
1317
1423
|
function insertTable(ctx, rows, cols) {
|
|
1318
1424
|
const r = Math.max(1, Math.trunc(rows));
|
|
1319
1425
|
const c = Math.max(1, Math.trunc(cols));
|
|
@@ -2061,6 +2167,10 @@ var EditorHistory = class {
|
|
|
2061
2167
|
}
|
|
2062
2168
|
};
|
|
2063
2169
|
export {
|
|
2170
|
+
ANSWER_LINE_COLOR,
|
|
2171
|
+
ANSWER_LINE_MAX,
|
|
2172
|
+
BLANK_MIN_RUN,
|
|
2173
|
+
BLANK_STYLE,
|
|
2064
2174
|
BLOCK_SPECS,
|
|
2065
2175
|
CLEAR_ALL_MARKS,
|
|
2066
2176
|
COMMAND_ORIGIN,
|
|
@@ -2071,8 +2181,13 @@ export {
|
|
|
2071
2181
|
MAX_LIST_LEVEL,
|
|
2072
2182
|
PAGE_PRESETS,
|
|
2073
2183
|
SOFER_MIME,
|
|
2184
|
+
TABLE_BORDER_COLOR,
|
|
2185
|
+
TABLE_GUIDE_COLOR,
|
|
2074
2186
|
TRACKED_ORIGINS,
|
|
2075
2187
|
Y3 as Y,
|
|
2188
|
+
answerLineStyle,
|
|
2189
|
+
cellBorderColors,
|
|
2190
|
+
cellBorderStyle,
|
|
2076
2191
|
cellsInRect,
|
|
2077
2192
|
clearRectCells,
|
|
2078
2193
|
collapsedSelection,
|
|
@@ -2096,6 +2211,7 @@ export {
|
|
|
2096
2211
|
getBlockId,
|
|
2097
2212
|
getMarksInRange,
|
|
2098
2213
|
indentList,
|
|
2214
|
+
insertAnswerLines,
|
|
2099
2215
|
insertImage,
|
|
2100
2216
|
insertParagraph,
|
|
2101
2217
|
insertSlice,
|
|
@@ -2124,6 +2240,7 @@ export {
|
|
|
2124
2240
|
sameTextRun,
|
|
2125
2241
|
serializeSelection,
|
|
2126
2242
|
setBlockAttr,
|
|
2243
|
+
setBlockAttrAtIndex,
|
|
2127
2244
|
setBlockType,
|
|
2128
2245
|
setCellAttr,
|
|
2129
2246
|
setColumnWidth,
|
|
@@ -2135,6 +2252,8 @@ export {
|
|
|
2135
2252
|
spanOf,
|
|
2136
2253
|
splitCell,
|
|
2137
2254
|
splitListItem,
|
|
2255
|
+
splitUnderscoreRuns,
|
|
2256
|
+
styleToCssText,
|
|
2138
2257
|
tableLocationOf,
|
|
2139
2258
|
tableRectSelection,
|
|
2140
2259
|
toggleList,
|