1
0
mirror of https://github.com/BookStackApp/BookStack.git synced 2025-07-30 04:23:11 +03:00

Lexical: Wired table properties, and other buttons

This commit is contained in:
Dan Brown
2024-08-10 13:14:55 +01:00
parent abbfd42a6c
commit ebf95f637a
9 changed files with 243 additions and 79 deletions

View File

@ -29,4 +29,29 @@ export function formatSizeValue(size: number | string, defaultSuffix: string = '
}
return size;
}
export type StyleMap = Map<string, string>;
/**
* Creates a map from an element's styles.
* Uses direct attribute value string handling since attempting to iterate
* over .style will expand out any shorthand properties (like 'padding') making
* rather than being representative of the actual properties set.
*/
export function extractStyleMapFromElement(element: HTMLElement): StyleMap {
const map: StyleMap = new Map();
const styleText= element.getAttribute('style') || '';
const rules = styleText.split(';');
for (const rule of rules) {
const [name, value] = rule.split(':');
if (!name || !value) {
continue;
}
map.set(name.trim().toLowerCase(), value.trim());
}
return map;
}

View File

@ -1,11 +0,0 @@
export type StyleMap = Map<string, string>;
export function createStyleMapFromDomStyles(domStyles: CSSStyleDeclaration): StyleMap {
const styleMap: StyleMap = new Map();
const styleNames: string[] = Array.from(domStyles);
for (const style of styleNames) {
styleMap.set(style, domStyles.getPropertyValue(style));
}
return styleMap;
}

View File

@ -206,8 +206,107 @@ export function $getTableRowsFromSelection(selection: BaseSelection|null): Custo
return Object.values(rowsByKey);
}
export function $getTableFromSelection(selection: BaseSelection|null): CustomTableNode|null {
const cells = $getTableCellsFromSelection(selection);
if (cells.length === 0) {
return null;
}
const table = $getParentOfType(cells[0], $isCustomTableNode);
if ($isCustomTableNode(table)) {
return table;
}
return null;
}
export function $clearTableSizes(table: CustomTableNode): void {
table.setColWidths([]);
// TODO - Extra form things once table properties and extra things
// are supported
for (const row of table.getChildren()) {
if (!$isCustomTableRowNode(row)) {
continue;
}
const rowStyles = row.getStyles();
rowStyles.delete('height');
rowStyles.delete('width');
row.setStyles(rowStyles);
const cells = row.getChildren().filter(c => $isCustomTableCellNode(c));
for (const cell of cells) {
const cellStyles = cell.getStyles();
cellStyles.delete('height');
cellStyles.delete('width');
cell.setStyles(cellStyles);
cell.clearWidth();
}
}
}
export function $clearTableFormatting(table: CustomTableNode): void {
table.setColWidths([]);
table.setStyles(new Map);
for (const row of table.getChildren()) {
if (!$isCustomTableRowNode(row)) {
continue;
}
row.setStyles(new Map);
row.setFormat('');
const cells = row.getChildren().filter(c => $isCustomTableCellNode(c));
for (const cell of cells) {
cell.setStyles(new Map);
cell.clearWidth();
cell.setFormat('');
}
}
}
/**
* Perform the given callback for each cell in the given table.
* Returning false from the callback stops the function early.
*/
export function $forEachTableCell(table: CustomTableNode, callback: (c: CustomTableCellNode) => void|false): void {
outer: for (const row of table.getChildren()) {
if (!$isCustomTableRowNode(row)) {
continue;
}
const cells = row.getChildren();
for (const cell of cells) {
if (!$isCustomTableCellNode(cell)) {
return;
}
const result = callback(cell);
if (result === false) {
break outer;
}
}
}
}
export function $getCellPaddingForTable(table: CustomTableNode): string {
let padding: string|null = null;
$forEachTableCell(table, (cell: CustomTableCellNode) => {
const cellPadding = cell.getStyles().get('padding') || ''
if (padding === null) {
padding = cellPadding;
}
if (cellPadding !== padding) {
padding = null;
return false;
}
});
return padding || '';
}