feat(writekit): rename @robonen/editor to @robonen/writekit
Rename the rich-text editor package and all Editor* exports to Writekit*; remove the old vue/editor tree.
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
import type { Attrs, Node } from '../model';
|
||||
import { blockById, isCollapsed, marksAt, nodeInline, orderedSelection, rangeHasMarkType } from '../model';
|
||||
import type { WritekitState } from '../state';
|
||||
|
||||
/** Block id the selection's focus is in (or the first node-selected block). */
|
||||
export function selectionBlockId(state: WritekitState): string | undefined {
|
||||
const sel = state.selection;
|
||||
return sel.kind === 'text' ? sel.focus.blockId : sel.ids[0];
|
||||
}
|
||||
|
||||
/** The block the selection currently focuses, or `null`. */
|
||||
export function focusBlock(state: WritekitState): Node | null {
|
||||
const id = selectionBlockId(state);
|
||||
return id ? blockById(state.doc, id) : null;
|
||||
}
|
||||
|
||||
/** Whether a block type holds inline (text) content. */
|
||||
export function isTextBlockType(state: WritekitState, type: string): boolean {
|
||||
return state.schema.nodeSpec(type)?.content.kind === 'text';
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether a mark is active for the current selection — used by `toggleMark` and
|
||||
* by toolbars (call a command without `dispatch` for the same answer).
|
||||
*/
|
||||
export function isMarkActive(state: WritekitState, type: string): boolean {
|
||||
const sel = state.selection;
|
||||
|
||||
if (sel.kind !== 'text')
|
||||
return false;
|
||||
|
||||
if (isCollapsed(sel)) {
|
||||
if (state.storedMarks)
|
||||
return state.storedMarks.some(mark => mark.type === type);
|
||||
|
||||
const block = blockById(state.doc, sel.focus.blockId);
|
||||
return block ? marksAt(nodeInline(block), sel.focus.offset).some(mark => mark.type === type) : false;
|
||||
}
|
||||
|
||||
if (sel.anchor.blockId !== sel.focus.blockId)
|
||||
return false;
|
||||
|
||||
const { from, to } = orderedSelection(sel, state.doc);
|
||||
const block = blockById(state.doc, sel.focus.blockId);
|
||||
return block ? rangeHasMarkType(nodeInline(block), from.offset, to.offset, type) : false;
|
||||
}
|
||||
|
||||
/** Whether the focused block matches a type (and optionally a subset of attrs). */
|
||||
export function isBlockActive(state: WritekitState, type: string, attrs?: Attrs): boolean {
|
||||
const block = focusBlock(state);
|
||||
|
||||
if (!block || block.type !== type)
|
||||
return false;
|
||||
|
||||
if (!attrs)
|
||||
return true;
|
||||
|
||||
return Object.keys(attrs).every(key => block.attrs[key] === attrs[key]);
|
||||
}
|
||||
Reference in New Issue
Block a user