Skip to content

Commit

Permalink
Merge pull request #109 from marduke182/export-utils-over-0.9.5
Browse files Browse the repository at this point in the history
Export utils over 0.x branch
  • Loading branch information
marduke182 authored Apr 30, 2020
2 parents e9572ad + 199ffa7 commit 578b3f1
Show file tree
Hide file tree
Showing 10 changed files with 129 additions and 49 deletions.
41 changes: 41 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,12 @@ export interface Rect {
bottom: number;
}

export interface TableRect extends Rect {
tableStart: number;
map: TableMap;
table: ProsemirrorNode;
}

export class TableMap {
width: number;
height: number;
Expand Down Expand Up @@ -192,6 +198,16 @@ export function deleteRow<S extends Schema = any>(
dispatch?: (tr: Transaction<S>) => void
): boolean;

export function selectedRect<S extends Schema = any>(
state: EditorState<S>
): TableRect;

export function rowIsHeader<S extends Schema = any>(
map: TableMap,
table: ProsemirrorNode<S>,
row: number
): boolean;

export function addRowAfter<S extends Schema = any>(
state: EditorState<S>,
dispatch?: (tr: Transaction<S>) => void
Expand All @@ -202,6 +218,12 @@ export function addRowBefore<S extends Schema = any>(
dispatch?: (tr: Transaction<S>) => void
): boolean;

export function addRow<S extends Schema = any>(
transaction: Transaction<S>,
rect: TableRect,
row: number
): Transaction<S>;

export function deleteColumn<S extends Schema = any>(
state: EditorState<S>,
dispatch?: (tr: Transaction<S>) => void
Expand All @@ -217,6 +239,12 @@ export function addColumnBefore<S extends Schema = any>(
dispatch?: (tr: Transaction<S>) => void
): boolean;

export function addColumn<S extends Schema = any>(
transaction: Transaction<S>,
rect: TableRect,
row: number
): Transaction<S>;

export function columnResizing<S extends Schema = any>(props: {
handleWidth?: number;
cellMinWidth?: number;
Expand All @@ -243,6 +271,14 @@ export function cellAround<S extends Schema = any>(

export function isInTable(state: EditorState): boolean;

export function removeColSpan<T extends {}>(attrs: T, pos: number, n?: number): T;
export function addColSpan<T extends {}>(attrs: T, pos: number, n?: number): T;

type TableRoles = 'table' | 'row' | 'cell' | 'header_cell';

export function columnIsHeader(map: TableMap, table: ProsemirrorNode, col: number): boolean;
export function tableNodeTypes(schema: Schema): Record<TableRoles, NodeType>;

export function selectionCell<S extends Schema = any>(
state: EditorState<S>
): ResolvedPos<S> | null | undefined;
Expand All @@ -267,3 +303,8 @@ export function nextCell<S extends Schema = any>(
axis: string,
dir: number
): null | ResolvedPos<S>;

export function fixTables<S extends Schema = any>(
state: EditorState<S>,
oldState?: EditorState<S>
): null | Transaction<S>;
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"typings-tester": "^0.3.2"
},
"scripts": {
"typecheck": "tsc --noEmit",
"test": "mocha test/test-*.js",
"build_demo": "rollup -c rollup.demo.config.js",
"watch_demo": "rollup -w -c rollup.demo.config.js",
Expand Down
6 changes: 3 additions & 3 deletions src/cellselection.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {Decoration, DecorationSet} from "prosemirror-view"
import {Fragment, Slice} from "prosemirror-model"


import {inSameTable, pointsAtCell, setAttr, rmColSpan} from "./util"
import {inSameTable, pointsAtCell, setAttr, removeColSpan} from "./util"
import {TableMap} from "./tablemap"

// ::- A [`Selection`](http://prosemirror.net/docs/ref/#state.Selection)
Expand Down Expand Up @@ -77,8 +77,8 @@ export class CellSelection extends Selection {
let extraLeft = rect.left - cellRect.left, extraRight = cellRect.right - rect.right
if (extraLeft > 0 || extraRight > 0) {
let attrs = cell.attrs
if (extraLeft > 0) attrs = rmColSpan(attrs, 0, extraLeft)
if (extraRight > 0) attrs = rmColSpan(attrs, attrs.colspan - extraRight, extraRight)
if (extraLeft > 0) attrs = removeColSpan(attrs, 0, extraLeft)
if (extraRight > 0) attrs = removeColSpan(attrs, attrs.colspan - extraRight, extraRight)
if (cellRect.left < rect.left) cell = cell.type.createAndFill(attrs)
else cell = cell.type.create(attrs, cell.content)
}
Expand Down
45 changes: 15 additions & 30 deletions src/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,21 @@
import {TextSelection} from "prosemirror-state"
import {Fragment} from "prosemirror-model"

import {TableMap, Rect} from "./tablemap"
import {Rect, TableMap} from "./tablemap"
import {CellSelection} from "./cellselection"
import {setAttr, addColSpan, rmColSpan, moveCellForward, isInTable, selectionCell} from "./util"
import {
addColSpan,
cellAround,
cellWrapping,
columnIsHeader,
isInTable,
moveCellForward,
removeColSpan,
selectedRect,
selectionCell,
setAttr
} from "./util"
import {tableNodeTypes} from "./schema"
import {cellWrapping, cellAround} from './util'

// Helper to get the selected rectangle in a table, if any. Adds table
// map, table node, and table start offset to the object for
// convenience.
function selectedRect(state) {
let sel = state.selection, $pos = selectionCell(state)
let table = $pos.node(-1), tableStart = $pos.start(-1), map = TableMap.get(table)
let rect
if (sel instanceof CellSelection)
rect = map.rectBetween(sel.$anchorCell.pos - tableStart, sel.$headCell.pos - tableStart)
else
rect = map.findCell($pos.pos - tableStart)
rect.tableStart = tableStart
rect.map = map
rect.table = table
return rect
}

function columnIsHeader(map, table, col) {
let headerCell = tableNodeTypes(table.type.schema).header_cell
for (let row = 0; row < map.height; row++)
if (table.nodeAt(map.map[col + row * map.width]).type != headerCell)
return false
return true
}

// Add a column at the given position in a table.
export function addColumn(tr, {map, tableStart, table}, col) {
Expand Down Expand Up @@ -88,7 +73,7 @@ export function removeColumn(tr, {map, table, tableStart}, col) {
// If this is part of a col-spanning cell
if ((col > 0 && map.map[index - 1] == pos) || (col < map.width - 1 && map.map[index + 1] == pos)) {
tr.setNodeMarkup(tr.mapping.slice(mapStart).map(tableStart + pos), null,
rmColSpan(cell.attrs, col - map.colCount(pos)))
removeColSpan(cell.attrs, col - map.colCount(pos)))
} else {
let start = tr.mapping.slice(mapStart).map(tableStart + pos)
tr.delete(start, start + cell.nodeSize)
Expand All @@ -115,7 +100,7 @@ export function deleteColumn(state, dispatch) {
return true
}

function rowIsHeader(map, table, row) {
export function rowIsHeader(map, table, row) {
let headerCell = tableNodeTypes(table.type.schema).header_cell
for (let col = 0; col < map.width; col++)
if (table.nodeAt(map.map[col + row * map.width]).type != headerCell)
Expand Down
8 changes: 4 additions & 4 deletions src/copypaste.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import {Slice, Fragment} from "prosemirror-model"
import {Transform} from "prosemirror-transform"

import {setAttr, rmColSpan} from "./util"
import {setAttr, removeColSpan} from "./util"
import {TableMap} from "./tablemap"
import {CellSelection} from "./cellselection"
import {tableNodeTypes} from "./schema"
Expand Down Expand Up @@ -93,7 +93,7 @@ export function clipCells({width, height, rows}, newWidth, newHeight) {
for (let col = added[row] || 0, i = 0; col < newWidth; i++) {
let cell = frag.child(i % frag.childCount)
if (col + cell.attrs.colspan > newWidth)
cell = cell.type.create(rmColSpan(cell.attrs, cell.attrs.colspan, col + cell.attrs.colspan - newWidth), cell.content)
cell = cell.type.create(removeColSpan(cell.attrs, cell.attrs.colspan, col + cell.attrs.colspan - newWidth), cell.content)
cells.push(cell)
col += cell.attrs.colspan
for (let j = 1; j < cell.attrs.rowspan; j++)
Expand Down Expand Up @@ -191,8 +191,8 @@ function isolateVertical(tr, map, table, start, top, bottom, left, mapFrom) {
found = true
let cell = table.nodeAt(pos), cellLeft = map.colCount(pos)
let updatePos = tr.mapping.slice(mapFrom).map(pos + start)
tr.setNodeMarkup(updatePos, null, rmColSpan(cell.attrs, left - cellLeft, cell.attrs.colspan - (left - cellLeft)))
tr.insert(updatePos + cell.nodeSize, cell.type.createAndFill(rmColSpan(cell.attrs, 0, left - cellLeft)))
tr.setNodeMarkup(updatePos, null, removeColSpan(cell.attrs, left - cellLeft, cell.attrs.colspan - (left - cellLeft)))
tr.insert(updatePos + cell.nodeSize, cell.type.createAndFill(removeColSpan(cell.attrs, 0, left - cellLeft)))
row += cell.attrs.rowspan - 1
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/fixtables.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import {PluginKey} from "prosemirror-state"
import {TableMap} from "./tablemap"
import {setAttr, rmColSpan} from "./util"
import {setAttr, removeColSpan} from "./util"
import {tableNodeTypes} from "./schema"
import {key} from "./util"

Expand Down Expand Up @@ -66,7 +66,7 @@ export function fixTable(state, table, tablePos, tr) {
if (prob.type == "collision") {
let cell = table.nodeAt(prob.pos)
for (let j = 0; j < cell.attrs.rowspan; j++) mustAdd[prob.row + j] += prob.n
tr.setNodeMarkup(tr.mapping.map(tablePos + 1 + prob.pos), null, rmColSpan(cell.attrs, cell.attrs.colspan - prob.n, prob.n))
tr.setNodeMarkup(tr.mapping.map(tablePos + 1 + prob.pos), null, removeColSpan(cell.attrs, cell.attrs.colspan - prob.n, prob.n))
} else if (prob.type == "missing") {
mustAdd[prob.row] += prob.n
} else if (prob.type == "overlong_rowspan") {
Expand Down
4 changes: 2 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ export function tableEditing({ allowTableNodeSelection = false } = {}) {
}

export {fixTables, handlePaste, fixTablesKey}
export {cellAround, isInTable, selectionCell, moveCellForward, inSameTable, findCell, colCount, nextCell} from "./util";
export {tableNodes} from "./schema"
export {cellAround, isInTable, selectionCell, moveCellForward, inSameTable, findCell, colCount, nextCell, removeColSpan, addColSpan, columnIsHeader, selectedRect} from "./util";
export {tableNodes, tableNodeTypes} from "./schema"
export {CellSelection} from "./cellselection"
export {TableMap} from "./tablemap"
export {tableEditingKey};
Expand Down
30 changes: 29 additions & 1 deletion src/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import {PluginKey} from "prosemirror-state"

import {TableMap} from "./tablemap"
import {tableNodeTypes} from "./schema";
import {CellSelection} from "./cellselection";

export const key = new PluginKey("selectingCells")

Expand Down Expand Up @@ -80,7 +82,7 @@ export function setAttr(attrs, name, value) {
return result
}

export function rmColSpan(attrs, pos, n=1) {
export function removeColSpan(attrs, pos, n=1) {
let result = setAttr(attrs, "colspan", attrs.colspan - n)
if (result.colwidth) {
result.colwidth = result.colwidth.slice()
Expand All @@ -98,3 +100,29 @@ export function addColSpan(attrs, pos, n=1) {
}
return result
}

export function columnIsHeader(map, table, col) {
let headerCell = tableNodeTypes(table.type.schema).header_cell
for (let row = 0; row < map.height; row++)
if (table.nodeAt(map.map[col + row * map.width]).type != headerCell)
return false
return true
}


// Helper to get the selected rectangle in a table, if any. Adds table
// map, table node, and table start offset to the object for
// convenience.
export function selectedRect(state) {
let sel = state.selection, $pos = selectionCell(state)
let table = $pos.node(-1), tableStart = $pos.start(-1), map = TableMap.get(table)
let rect
if (sel instanceof CellSelection)
rect = map.rectBetween(sel.$anchorCell.pos - tableStart, sel.$headCell.pos - tableStart)
else
rect = map.findCell($pos.pos - tableStart)
rect.tableStart = tableStart
rect.map = map
rect.table = table
return rect
}
28 changes: 21 additions & 7 deletions test/typescript/prosemirror-tables.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
import * as tables from '../../';
import {TableMap, toggleHeader, TableRect, tableEditing} from '../../';
import {Node as ProsemirrorNode} from "prosemirror-model";

const table = tables.tableEditing();
const tableWithNodeSelection = tables.tableEditing({allowTableNodeSelection: true});
const tableEditing1 = tableEditing();
const tableWithNodeSelection = tableEditing({allowTableNodeSelection: true});

tables.toggleHeader('column');
tables.toggleHeader('row');
tables.toggleHeader('row', { useDeprecatedLogic: false });
tables.toggleHeader('row', { useDeprecatedLogic: true });
const map = new TableMap();
const table = new ProsemirrorNode();

toggleHeader('column');
toggleHeader('row');
toggleHeader('row', { useDeprecatedLogic: false });
toggleHeader('row', { useDeprecatedLogic: true });

const tableRect: TableRect = {
left: 10,
top: 20,
right: 30,
bottom: 40,
tableStart: 20,
map,
table,
};
11 changes: 11 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": ["es6", "dom"],
"baseUrl": "../",
"typeRoots": ["../"],
"types": [],
"noEmit": true
},
"files": ["index.d.ts", "test/typescript/prosemirror-tables.ts"]
}

0 comments on commit 578b3f1

Please sign in to comment.