index.cjs 81 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493
  1. "use strict";
  2. var __defProp = Object.defineProperty;
  3. var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
  4. var __getOwnPropNames = Object.getOwnPropertyNames;
  5. var __hasOwnProp = Object.prototype.hasOwnProperty;
  6. var __export = (target, all) => {
  7. for (var name in all)
  8. __defProp(target, name, { get: all[name], enumerable: true });
  9. };
  10. var __copyProps = (to, from, except, desc) => {
  11. if (from && typeof from === "object" || typeof from === "function") {
  12. for (let key of __getOwnPropNames(from))
  13. if (!__hasOwnProp.call(to, key) && key !== except)
  14. __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  15. }
  16. return to;
  17. };
  18. var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
  19. // src/index.ts
  20. var src_exports = {};
  21. __export(src_exports, {
  22. CellBookmark: () => CellBookmark,
  23. CellSelection: () => CellSelection,
  24. ResizeState: () => ResizeState,
  25. TableMap: () => TableMap,
  26. TableView: () => TableView,
  27. __clipCells: () => clipCells,
  28. __insertCells: () => insertCells,
  29. __pastedCells: () => pastedCells,
  30. addColSpan: () => addColSpan,
  31. addColumn: () => addColumn,
  32. addColumnAfter: () => addColumnAfter,
  33. addColumnBefore: () => addColumnBefore,
  34. addRow: () => addRow,
  35. addRowAfter: () => addRowAfter,
  36. addRowBefore: () => addRowBefore,
  37. cellAround: () => cellAround,
  38. colCount: () => colCount,
  39. columnIsHeader: () => columnIsHeader,
  40. columnResizing: () => columnResizing,
  41. columnResizingPluginKey: () => columnResizingPluginKey,
  42. deleteColumn: () => deleteColumn,
  43. deleteRow: () => deleteRow,
  44. deleteTable: () => deleteTable,
  45. findCell: () => findCell,
  46. fixTables: () => fixTables,
  47. fixTablesKey: () => fixTablesKey,
  48. goToNextCell: () => goToNextCell,
  49. handlePaste: () => handlePaste,
  50. inSameTable: () => inSameTable,
  51. isInTable: () => isInTable,
  52. mergeCells: () => mergeCells,
  53. moveCellForward: () => moveCellForward,
  54. nextCell: () => nextCell,
  55. pointsAtCell: () => pointsAtCell,
  56. removeColSpan: () => removeColSpan,
  57. removeColumn: () => removeColumn,
  58. removeRow: () => removeRow,
  59. rowIsHeader: () => rowIsHeader,
  60. selectedRect: () => selectedRect,
  61. selectionCell: () => selectionCell,
  62. setCellAttr: () => setCellAttr,
  63. splitCell: () => splitCell,
  64. splitCellWithType: () => splitCellWithType,
  65. tableEditing: () => tableEditing,
  66. tableEditingKey: () => tableEditingKey,
  67. tableNodeTypes: () => tableNodeTypes,
  68. tableNodes: () => tableNodes,
  69. toggleHeader: () => toggleHeader,
  70. toggleHeaderCell: () => toggleHeaderCell,
  71. toggleHeaderColumn: () => toggleHeaderColumn,
  72. toggleHeaderRow: () => toggleHeaderRow,
  73. updateColumnsOnResize: () => updateColumnsOnResize
  74. });
  75. module.exports = __toCommonJS(src_exports);
  76. var import_prosemirror_state7 = require("prosemirror-state");
  77. // src/cellselection.ts
  78. var import_prosemirror_model = require("prosemirror-model");
  79. var import_prosemirror_state2 = require("prosemirror-state");
  80. var import_prosemirror_view = require("prosemirror-view");
  81. // src/tablemap.ts
  82. var readFromCache;
  83. var addToCache;
  84. if (typeof WeakMap != "undefined") {
  85. let cache = /* @__PURE__ */ new WeakMap();
  86. readFromCache = (key) => cache.get(key);
  87. addToCache = (key, value) => {
  88. cache.set(key, value);
  89. return value;
  90. };
  91. } else {
  92. const cache = [];
  93. const cacheSize = 10;
  94. let cachePos = 0;
  95. readFromCache = (key) => {
  96. for (let i = 0; i < cache.length; i += 2)
  97. if (cache[i] == key)
  98. return cache[i + 1];
  99. };
  100. addToCache = (key, value) => {
  101. if (cachePos == cacheSize)
  102. cachePos = 0;
  103. cache[cachePos++] = key;
  104. return cache[cachePos++] = value;
  105. };
  106. }
  107. var TableMap = class {
  108. constructor(width, height, map, problems) {
  109. this.width = width;
  110. this.height = height;
  111. this.map = map;
  112. this.problems = problems;
  113. }
  114. // Find the dimensions of the cell at the given position.
  115. findCell(pos) {
  116. for (let i = 0; i < this.map.length; i++) {
  117. const curPos = this.map[i];
  118. if (curPos != pos)
  119. continue;
  120. const left = i % this.width;
  121. const top = i / this.width | 0;
  122. let right = left + 1;
  123. let bottom = top + 1;
  124. for (let j = 1; right < this.width && this.map[i + j] == curPos; j++) {
  125. right++;
  126. }
  127. for (let j = 1; bottom < this.height && this.map[i + this.width * j] == curPos; j++) {
  128. bottom++;
  129. }
  130. return { left, top, right, bottom };
  131. }
  132. throw new RangeError(`No cell with offset ${pos} found`);
  133. }
  134. // Find the left side of the cell at the given position.
  135. colCount(pos) {
  136. for (let i = 0; i < this.map.length; i++) {
  137. if (this.map[i] == pos) {
  138. return i % this.width;
  139. }
  140. }
  141. throw new RangeError(`No cell with offset ${pos} found`);
  142. }
  143. // Find the next cell in the given direction, starting from the cell
  144. // at `pos`, if any.
  145. nextCell(pos, axis, dir) {
  146. const { left, right, top, bottom } = this.findCell(pos);
  147. if (axis == "horiz") {
  148. if (dir < 0 ? left == 0 : right == this.width)
  149. return null;
  150. return this.map[top * this.width + (dir < 0 ? left - 1 : right)];
  151. } else {
  152. if (dir < 0 ? top == 0 : bottom == this.height)
  153. return null;
  154. return this.map[left + this.width * (dir < 0 ? top - 1 : bottom)];
  155. }
  156. }
  157. // Get the rectangle spanning the two given cells.
  158. rectBetween(a, b) {
  159. const {
  160. left: leftA,
  161. right: rightA,
  162. top: topA,
  163. bottom: bottomA
  164. } = this.findCell(a);
  165. const {
  166. left: leftB,
  167. right: rightB,
  168. top: topB,
  169. bottom: bottomB
  170. } = this.findCell(b);
  171. return {
  172. left: Math.min(leftA, leftB),
  173. top: Math.min(topA, topB),
  174. right: Math.max(rightA, rightB),
  175. bottom: Math.max(bottomA, bottomB)
  176. };
  177. }
  178. // Return the position of all cells that have the top left corner in
  179. // the given rectangle.
  180. cellsInRect(rect) {
  181. const result = [];
  182. const seen = {};
  183. for (let row = rect.top; row < rect.bottom; row++) {
  184. for (let col = rect.left; col < rect.right; col++) {
  185. const index = row * this.width + col;
  186. const pos = this.map[index];
  187. if (seen[pos])
  188. continue;
  189. seen[pos] = true;
  190. if (col == rect.left && col && this.map[index - 1] == pos || row == rect.top && row && this.map[index - this.width] == pos) {
  191. continue;
  192. }
  193. result.push(pos);
  194. }
  195. }
  196. return result;
  197. }
  198. // Return the position at which the cell at the given row and column
  199. // starts, or would start, if a cell started there.
  200. positionAt(row, col, table) {
  201. for (let i = 0, rowStart = 0; ; i++) {
  202. const rowEnd = rowStart + table.child(i).nodeSize;
  203. if (i == row) {
  204. let index = col + row * this.width;
  205. const rowEndIndex = (row + 1) * this.width;
  206. while (index < rowEndIndex && this.map[index] < rowStart)
  207. index++;
  208. return index == rowEndIndex ? rowEnd - 1 : this.map[index];
  209. }
  210. rowStart = rowEnd;
  211. }
  212. }
  213. // Find the table map for the given table node.
  214. static get(table) {
  215. return readFromCache(table) || addToCache(table, computeMap(table));
  216. }
  217. };
  218. function computeMap(table) {
  219. if (table.type.spec.tableRole != "table")
  220. throw new RangeError("Not a table node: " + table.type.name);
  221. const width = findWidth(table), height = table.childCount;
  222. const map = [];
  223. let mapPos = 0;
  224. let problems = null;
  225. const colWidths = [];
  226. for (let i = 0, e = width * height; i < e; i++)
  227. map[i] = 0;
  228. for (let row = 0, pos = 0; row < height; row++) {
  229. const rowNode = table.child(row);
  230. pos++;
  231. for (let i = 0; ; i++) {
  232. while (mapPos < map.length && map[mapPos] != 0)
  233. mapPos++;
  234. if (i == rowNode.childCount)
  235. break;
  236. const cellNode = rowNode.child(i);
  237. const { colspan, rowspan, colwidth } = cellNode.attrs;
  238. for (let h = 0; h < rowspan; h++) {
  239. if (h + row >= height) {
  240. (problems || (problems = [])).push({
  241. type: "overlong_rowspan",
  242. pos,
  243. n: rowspan - h
  244. });
  245. break;
  246. }
  247. const start = mapPos + h * width;
  248. for (let w = 0; w < colspan; w++) {
  249. if (map[start + w] == 0)
  250. map[start + w] = pos;
  251. else
  252. (problems || (problems = [])).push({
  253. type: "collision",
  254. row,
  255. pos,
  256. n: colspan - w
  257. });
  258. const colW = colwidth && colwidth[w];
  259. if (colW) {
  260. const widthIndex = (start + w) % width * 2, prev = colWidths[widthIndex];
  261. if (prev == null || prev != colW && colWidths[widthIndex + 1] == 1) {
  262. colWidths[widthIndex] = colW;
  263. colWidths[widthIndex + 1] = 1;
  264. } else if (prev == colW) {
  265. colWidths[widthIndex + 1]++;
  266. }
  267. }
  268. }
  269. }
  270. mapPos += colspan;
  271. pos += cellNode.nodeSize;
  272. }
  273. const expectedPos = (row + 1) * width;
  274. let missing = 0;
  275. while (mapPos < expectedPos)
  276. if (map[mapPos++] == 0)
  277. missing++;
  278. if (missing)
  279. (problems || (problems = [])).push({ type: "missing", row, n: missing });
  280. pos++;
  281. }
  282. const tableMap = new TableMap(width, height, map, problems);
  283. let badWidths = false;
  284. for (let i = 0; !badWidths && i < colWidths.length; i += 2)
  285. if (colWidths[i] != null && colWidths[i + 1] < height)
  286. badWidths = true;
  287. if (badWidths)
  288. findBadColWidths(tableMap, colWidths, table);
  289. return tableMap;
  290. }
  291. function findWidth(table) {
  292. let width = -1;
  293. let hasRowSpan = false;
  294. for (let row = 0; row < table.childCount; row++) {
  295. const rowNode = table.child(row);
  296. let rowWidth = 0;
  297. if (hasRowSpan)
  298. for (let j = 0; j < row; j++) {
  299. const prevRow = table.child(j);
  300. for (let i = 0; i < prevRow.childCount; i++) {
  301. const cell = prevRow.child(i);
  302. if (j + cell.attrs.rowspan > row)
  303. rowWidth += cell.attrs.colspan;
  304. }
  305. }
  306. for (let i = 0; i < rowNode.childCount; i++) {
  307. const cell = rowNode.child(i);
  308. rowWidth += cell.attrs.colspan;
  309. if (cell.attrs.rowspan > 1)
  310. hasRowSpan = true;
  311. }
  312. if (width == -1)
  313. width = rowWidth;
  314. else if (width != rowWidth)
  315. width = Math.max(width, rowWidth);
  316. }
  317. return width;
  318. }
  319. function findBadColWidths(map, colWidths, table) {
  320. if (!map.problems)
  321. map.problems = [];
  322. const seen = {};
  323. for (let i = 0; i < map.map.length; i++) {
  324. const pos = map.map[i];
  325. if (seen[pos])
  326. continue;
  327. seen[pos] = true;
  328. const node = table.nodeAt(pos);
  329. if (!node) {
  330. throw new RangeError(`No cell with offset ${pos} found`);
  331. }
  332. let updated = null;
  333. const attrs = node.attrs;
  334. for (let j = 0; j < attrs.colspan; j++) {
  335. const col = (i + j) % map.width;
  336. const colWidth = colWidths[col * 2];
  337. if (colWidth != null && (!attrs.colwidth || attrs.colwidth[j] != colWidth))
  338. (updated || (updated = freshColWidth(attrs)))[j] = colWidth;
  339. }
  340. if (updated)
  341. map.problems.unshift({
  342. type: "colwidth mismatch",
  343. pos,
  344. colwidth: updated
  345. });
  346. }
  347. }
  348. function freshColWidth(attrs) {
  349. if (attrs.colwidth)
  350. return attrs.colwidth.slice();
  351. const result = [];
  352. for (let i = 0; i < attrs.colspan; i++)
  353. result.push(0);
  354. return result;
  355. }
  356. // src/util.ts
  357. var import_prosemirror_state = require("prosemirror-state");
  358. // src/schema.ts
  359. function getCellAttrs(dom, extraAttrs) {
  360. if (typeof dom === "string") {
  361. return {};
  362. }
  363. const widthAttr = dom.getAttribute("data-colwidth");
  364. const widths = widthAttr && /^\d+(,\d+)*$/.test(widthAttr) ? widthAttr.split(",").map((s) => Number(s)) : null;
  365. const colspan = Number(dom.getAttribute("colspan") || 1);
  366. const result = {
  367. colspan,
  368. rowspan: Number(dom.getAttribute("rowspan") || 1),
  369. colwidth: widths && widths.length == colspan ? widths : null
  370. };
  371. for (const prop in extraAttrs) {
  372. const getter = extraAttrs[prop].getFromDOM;
  373. const value = getter && getter(dom);
  374. if (value != null) {
  375. result[prop] = value;
  376. }
  377. }
  378. return result;
  379. }
  380. function setCellAttrs(node, extraAttrs) {
  381. const attrs = {};
  382. if (node.attrs.colspan != 1)
  383. attrs.colspan = node.attrs.colspan;
  384. if (node.attrs.rowspan != 1)
  385. attrs.rowspan = node.attrs.rowspan;
  386. if (node.attrs.colwidth)
  387. attrs["data-colwidth"] = node.attrs.colwidth.join(",");
  388. for (const prop in extraAttrs) {
  389. const setter = extraAttrs[prop].setDOMAttr;
  390. if (setter)
  391. setter(node.attrs[prop], attrs);
  392. }
  393. return attrs;
  394. }
  395. function tableNodes(options) {
  396. const extraAttrs = options.cellAttributes || {};
  397. const cellAttrs = {
  398. colspan: { default: 1 },
  399. rowspan: { default: 1 },
  400. colwidth: { default: null }
  401. };
  402. for (const prop in extraAttrs)
  403. cellAttrs[prop] = { default: extraAttrs[prop].default };
  404. return {
  405. table: {
  406. content: "table_row+",
  407. tableRole: "table",
  408. isolating: true,
  409. group: options.tableGroup,
  410. parseDOM: [{ tag: "table" }],
  411. toDOM() {
  412. return ["table", ["tbody", 0]];
  413. }
  414. },
  415. table_row: {
  416. content: "(table_cell | table_header)*",
  417. tableRole: "row",
  418. parseDOM: [{ tag: "tr" }],
  419. toDOM() {
  420. return ["tr", 0];
  421. }
  422. },
  423. table_cell: {
  424. content: options.cellContent,
  425. attrs: cellAttrs,
  426. tableRole: "cell",
  427. isolating: true,
  428. parseDOM: [
  429. { tag: "td", getAttrs: (dom) => getCellAttrs(dom, extraAttrs) }
  430. ],
  431. toDOM(node) {
  432. return ["td", setCellAttrs(node, extraAttrs), 0];
  433. }
  434. },
  435. table_header: {
  436. content: options.cellContent,
  437. attrs: cellAttrs,
  438. tableRole: "header_cell",
  439. isolating: true,
  440. parseDOM: [
  441. { tag: "th", getAttrs: (dom) => getCellAttrs(dom, extraAttrs) }
  442. ],
  443. toDOM(node) {
  444. return ["th", setCellAttrs(node, extraAttrs), 0];
  445. }
  446. }
  447. };
  448. }
  449. function tableNodeTypes(schema) {
  450. let result = schema.cached.tableNodeTypes;
  451. if (!result) {
  452. result = schema.cached.tableNodeTypes = {};
  453. for (const name in schema.nodes) {
  454. const type = schema.nodes[name], role = type.spec.tableRole;
  455. if (role)
  456. result[role] = type;
  457. }
  458. }
  459. return result;
  460. }
  461. // src/util.ts
  462. var tableEditingKey = new import_prosemirror_state.PluginKey("selectingCells");
  463. function cellAround($pos) {
  464. for (let d = $pos.depth - 1; d > 0; d--)
  465. if ($pos.node(d).type.spec.tableRole == "row")
  466. return $pos.node(0).resolve($pos.before(d + 1));
  467. return null;
  468. }
  469. function cellWrapping($pos) {
  470. for (let d = $pos.depth; d > 0; d--) {
  471. const role = $pos.node(d).type.spec.tableRole;
  472. if (role === "cell" || role === "header_cell")
  473. return $pos.node(d);
  474. }
  475. return null;
  476. }
  477. function isInTable(state) {
  478. const $head = state.selection.$head;
  479. for (let d = $head.depth; d > 0; d--)
  480. if ($head.node(d).type.spec.tableRole == "row")
  481. return true;
  482. return false;
  483. }
  484. function selectionCell(state) {
  485. const sel = state.selection;
  486. if ("$anchorCell" in sel && sel.$anchorCell) {
  487. return sel.$anchorCell.pos > sel.$headCell.pos ? sel.$anchorCell : sel.$headCell;
  488. } else if ("node" in sel && sel.node && sel.node.type.spec.tableRole == "cell") {
  489. return sel.$anchor;
  490. }
  491. const $cell = cellAround(sel.$head) || cellNear(sel.$head);
  492. if ($cell) {
  493. return $cell;
  494. }
  495. throw new RangeError(`No cell found around position ${sel.head}`);
  496. }
  497. function cellNear($pos) {
  498. for (let after = $pos.nodeAfter, pos = $pos.pos; after; after = after.firstChild, pos++) {
  499. const role = after.type.spec.tableRole;
  500. if (role == "cell" || role == "header_cell")
  501. return $pos.doc.resolve(pos);
  502. }
  503. for (let before = $pos.nodeBefore, pos = $pos.pos; before; before = before.lastChild, pos--) {
  504. const role = before.type.spec.tableRole;
  505. if (role == "cell" || role == "header_cell")
  506. return $pos.doc.resolve(pos - before.nodeSize);
  507. }
  508. }
  509. function pointsAtCell($pos) {
  510. return $pos.parent.type.spec.tableRole == "row" && !!$pos.nodeAfter;
  511. }
  512. function moveCellForward($pos) {
  513. return $pos.node(0).resolve($pos.pos + $pos.nodeAfter.nodeSize);
  514. }
  515. function inSameTable($cellA, $cellB) {
  516. return $cellA.depth == $cellB.depth && $cellA.pos >= $cellB.start(-1) && $cellA.pos <= $cellB.end(-1);
  517. }
  518. function findCell($pos) {
  519. return TableMap.get($pos.node(-1)).findCell($pos.pos - $pos.start(-1));
  520. }
  521. function colCount($pos) {
  522. return TableMap.get($pos.node(-1)).colCount($pos.pos - $pos.start(-1));
  523. }
  524. function nextCell($pos, axis, dir) {
  525. const table = $pos.node(-1);
  526. const map = TableMap.get(table);
  527. const tableStart = $pos.start(-1);
  528. const moved = map.nextCell($pos.pos - tableStart, axis, dir);
  529. return moved == null ? null : $pos.node(0).resolve(tableStart + moved);
  530. }
  531. function removeColSpan(attrs, pos, n = 1) {
  532. const result = { ...attrs, colspan: attrs.colspan - n };
  533. if (result.colwidth) {
  534. result.colwidth = result.colwidth.slice();
  535. result.colwidth.splice(pos, n);
  536. if (!result.colwidth.some((w) => w > 0))
  537. result.colwidth = null;
  538. }
  539. return result;
  540. }
  541. function addColSpan(attrs, pos, n = 1) {
  542. const result = { ...attrs, colspan: attrs.colspan + n };
  543. if (result.colwidth) {
  544. result.colwidth = result.colwidth.slice();
  545. for (let i = 0; i < n; i++)
  546. result.colwidth.splice(pos, 0, 0);
  547. }
  548. return result;
  549. }
  550. function columnIsHeader(map, table, col) {
  551. const headerCell = tableNodeTypes(table.type.schema).header_cell;
  552. for (let row = 0; row < map.height; row++)
  553. if (table.nodeAt(map.map[col + row * map.width]).type != headerCell)
  554. return false;
  555. return true;
  556. }
  557. // src/cellselection.ts
  558. var CellSelection = class _CellSelection extends import_prosemirror_state2.Selection {
  559. // A table selection is identified by its anchor and head cells. The
  560. // positions given to this constructor should point _before_ two
  561. // cells in the same table. They may be the same, to select a single
  562. // cell.
  563. constructor($anchorCell, $headCell = $anchorCell) {
  564. const table = $anchorCell.node(-1);
  565. const map = TableMap.get(table);
  566. const tableStart = $anchorCell.start(-1);
  567. const rect = map.rectBetween(
  568. $anchorCell.pos - tableStart,
  569. $headCell.pos - tableStart
  570. );
  571. const doc = $anchorCell.node(0);
  572. const cells = map.cellsInRect(rect).filter((p) => p != $headCell.pos - tableStart);
  573. cells.unshift($headCell.pos - tableStart);
  574. const ranges = cells.map((pos) => {
  575. const cell = table.nodeAt(pos);
  576. if (!cell) {
  577. throw RangeError(`No cell with offset ${pos} found`);
  578. }
  579. const from = tableStart + pos + 1;
  580. return new import_prosemirror_state2.SelectionRange(
  581. doc.resolve(from),
  582. doc.resolve(from + cell.content.size)
  583. );
  584. });
  585. super(ranges[0].$from, ranges[0].$to, ranges);
  586. this.$anchorCell = $anchorCell;
  587. this.$headCell = $headCell;
  588. }
  589. map(doc, mapping) {
  590. const $anchorCell = doc.resolve(mapping.map(this.$anchorCell.pos));
  591. const $headCell = doc.resolve(mapping.map(this.$headCell.pos));
  592. if (pointsAtCell($anchorCell) && pointsAtCell($headCell) && inSameTable($anchorCell, $headCell)) {
  593. const tableChanged = this.$anchorCell.node(-1) != $anchorCell.node(-1);
  594. if (tableChanged && this.isRowSelection())
  595. return _CellSelection.rowSelection($anchorCell, $headCell);
  596. else if (tableChanged && this.isColSelection())
  597. return _CellSelection.colSelection($anchorCell, $headCell);
  598. else
  599. return new _CellSelection($anchorCell, $headCell);
  600. }
  601. return import_prosemirror_state2.TextSelection.between($anchorCell, $headCell);
  602. }
  603. // Returns a rectangular slice of table rows containing the selected
  604. // cells.
  605. content() {
  606. const table = this.$anchorCell.node(-1);
  607. const map = TableMap.get(table);
  608. const tableStart = this.$anchorCell.start(-1);
  609. const rect = map.rectBetween(
  610. this.$anchorCell.pos - tableStart,
  611. this.$headCell.pos - tableStart
  612. );
  613. const seen = {};
  614. const rows = [];
  615. for (let row = rect.top; row < rect.bottom; row++) {
  616. const rowContent = [];
  617. for (let index = row * map.width + rect.left, col = rect.left; col < rect.right; col++, index++) {
  618. const pos = map.map[index];
  619. if (seen[pos])
  620. continue;
  621. seen[pos] = true;
  622. const cellRect = map.findCell(pos);
  623. let cell = table.nodeAt(pos);
  624. if (!cell) {
  625. throw RangeError(`No cell with offset ${pos} found`);
  626. }
  627. const extraLeft = rect.left - cellRect.left;
  628. const extraRight = cellRect.right - rect.right;
  629. if (extraLeft > 0 || extraRight > 0) {
  630. let attrs = cell.attrs;
  631. if (extraLeft > 0) {
  632. attrs = removeColSpan(attrs, 0, extraLeft);
  633. }
  634. if (extraRight > 0) {
  635. attrs = removeColSpan(
  636. attrs,
  637. attrs.colspan - extraRight,
  638. extraRight
  639. );
  640. }
  641. if (cellRect.left < rect.left) {
  642. cell = cell.type.createAndFill(attrs);
  643. if (!cell) {
  644. throw RangeError(
  645. `Could not create cell with attrs ${JSON.stringify(attrs)}`
  646. );
  647. }
  648. } else {
  649. cell = cell.type.create(attrs, cell.content);
  650. }
  651. }
  652. if (cellRect.top < rect.top || cellRect.bottom > rect.bottom) {
  653. const attrs = {
  654. ...cell.attrs,
  655. rowspan: Math.min(cellRect.bottom, rect.bottom) - Math.max(cellRect.top, rect.top)
  656. };
  657. if (cellRect.top < rect.top) {
  658. cell = cell.type.createAndFill(attrs);
  659. } else {
  660. cell = cell.type.create(attrs, cell.content);
  661. }
  662. }
  663. rowContent.push(cell);
  664. }
  665. rows.push(table.child(row).copy(import_prosemirror_model.Fragment.from(rowContent)));
  666. }
  667. const fragment = this.isColSelection() && this.isRowSelection() ? table : rows;
  668. return new import_prosemirror_model.Slice(import_prosemirror_model.Fragment.from(fragment), 1, 1);
  669. }
  670. replace(tr, content = import_prosemirror_model.Slice.empty) {
  671. const mapFrom = tr.steps.length, ranges = this.ranges;
  672. for (let i = 0; i < ranges.length; i++) {
  673. const { $from, $to } = ranges[i], mapping = tr.mapping.slice(mapFrom);
  674. tr.replace(
  675. mapping.map($from.pos),
  676. mapping.map($to.pos),
  677. i ? import_prosemirror_model.Slice.empty : content
  678. );
  679. }
  680. const sel = import_prosemirror_state2.Selection.findFrom(
  681. tr.doc.resolve(tr.mapping.slice(mapFrom).map(this.to)),
  682. -1
  683. );
  684. if (sel)
  685. tr.setSelection(sel);
  686. }
  687. replaceWith(tr, node) {
  688. this.replace(tr, new import_prosemirror_model.Slice(import_prosemirror_model.Fragment.from(node), 0, 0));
  689. }
  690. forEachCell(f) {
  691. const table = this.$anchorCell.node(-1);
  692. const map = TableMap.get(table);
  693. const tableStart = this.$anchorCell.start(-1);
  694. const cells = map.cellsInRect(
  695. map.rectBetween(
  696. this.$anchorCell.pos - tableStart,
  697. this.$headCell.pos - tableStart
  698. )
  699. );
  700. for (let i = 0; i < cells.length; i++) {
  701. f(table.nodeAt(cells[i]), tableStart + cells[i]);
  702. }
  703. }
  704. // True if this selection goes all the way from the top to the
  705. // bottom of the table.
  706. isColSelection() {
  707. const anchorTop = this.$anchorCell.index(-1);
  708. const headTop = this.$headCell.index(-1);
  709. if (Math.min(anchorTop, headTop) > 0)
  710. return false;
  711. const anchorBottom = anchorTop + this.$anchorCell.nodeAfter.attrs.rowspan;
  712. const headBottom = headTop + this.$headCell.nodeAfter.attrs.rowspan;
  713. return Math.max(anchorBottom, headBottom) == this.$headCell.node(-1).childCount;
  714. }
  715. // Returns the smallest column selection that covers the given anchor
  716. // and head cell.
  717. static colSelection($anchorCell, $headCell = $anchorCell) {
  718. const table = $anchorCell.node(-1);
  719. const map = TableMap.get(table);
  720. const tableStart = $anchorCell.start(-1);
  721. const anchorRect = map.findCell($anchorCell.pos - tableStart);
  722. const headRect = map.findCell($headCell.pos - tableStart);
  723. const doc = $anchorCell.node(0);
  724. if (anchorRect.top <= headRect.top) {
  725. if (anchorRect.top > 0)
  726. $anchorCell = doc.resolve(tableStart + map.map[anchorRect.left]);
  727. if (headRect.bottom < map.height)
  728. $headCell = doc.resolve(
  729. tableStart + map.map[map.width * (map.height - 1) + headRect.right - 1]
  730. );
  731. } else {
  732. if (headRect.top > 0)
  733. $headCell = doc.resolve(tableStart + map.map[headRect.left]);
  734. if (anchorRect.bottom < map.height)
  735. $anchorCell = doc.resolve(
  736. tableStart + map.map[map.width * (map.height - 1) + anchorRect.right - 1]
  737. );
  738. }
  739. return new _CellSelection($anchorCell, $headCell);
  740. }
  741. // True if this selection goes all the way from the left to the
  742. // right of the table.
  743. isRowSelection() {
  744. const table = this.$anchorCell.node(-1);
  745. const map = TableMap.get(table);
  746. const tableStart = this.$anchorCell.start(-1);
  747. const anchorLeft = map.colCount(this.$anchorCell.pos - tableStart);
  748. const headLeft = map.colCount(this.$headCell.pos - tableStart);
  749. if (Math.min(anchorLeft, headLeft) > 0)
  750. return false;
  751. const anchorRight = anchorLeft + this.$anchorCell.nodeAfter.attrs.colspan;
  752. const headRight = headLeft + this.$headCell.nodeAfter.attrs.colspan;
  753. return Math.max(anchorRight, headRight) == map.width;
  754. }
  755. eq(other) {
  756. return other instanceof _CellSelection && other.$anchorCell.pos == this.$anchorCell.pos && other.$headCell.pos == this.$headCell.pos;
  757. }
  758. // Returns the smallest row selection that covers the given anchor
  759. // and head cell.
  760. static rowSelection($anchorCell, $headCell = $anchorCell) {
  761. const table = $anchorCell.node(-1);
  762. const map = TableMap.get(table);
  763. const tableStart = $anchorCell.start(-1);
  764. const anchorRect = map.findCell($anchorCell.pos - tableStart);
  765. const headRect = map.findCell($headCell.pos - tableStart);
  766. const doc = $anchorCell.node(0);
  767. if (anchorRect.left <= headRect.left) {
  768. if (anchorRect.left > 0)
  769. $anchorCell = doc.resolve(
  770. tableStart + map.map[anchorRect.top * map.width]
  771. );
  772. if (headRect.right < map.width)
  773. $headCell = doc.resolve(
  774. tableStart + map.map[map.width * (headRect.top + 1) - 1]
  775. );
  776. } else {
  777. if (headRect.left > 0)
  778. $headCell = doc.resolve(tableStart + map.map[headRect.top * map.width]);
  779. if (anchorRect.right < map.width)
  780. $anchorCell = doc.resolve(
  781. tableStart + map.map[map.width * (anchorRect.top + 1) - 1]
  782. );
  783. }
  784. return new _CellSelection($anchorCell, $headCell);
  785. }
  786. toJSON() {
  787. return {
  788. type: "cell",
  789. anchor: this.$anchorCell.pos,
  790. head: this.$headCell.pos
  791. };
  792. }
  793. static fromJSON(doc, json) {
  794. return new _CellSelection(doc.resolve(json.anchor), doc.resolve(json.head));
  795. }
  796. static create(doc, anchorCell, headCell = anchorCell) {
  797. return new _CellSelection(doc.resolve(anchorCell), doc.resolve(headCell));
  798. }
  799. getBookmark() {
  800. return new CellBookmark(this.$anchorCell.pos, this.$headCell.pos);
  801. }
  802. };
  803. CellSelection.prototype.visible = false;
  804. import_prosemirror_state2.Selection.jsonID("cell", CellSelection);
  805. var CellBookmark = class _CellBookmark {
  806. constructor(anchor, head) {
  807. this.anchor = anchor;
  808. this.head = head;
  809. }
  810. map(mapping) {
  811. return new _CellBookmark(mapping.map(this.anchor), mapping.map(this.head));
  812. }
  813. resolve(doc) {
  814. const $anchorCell = doc.resolve(this.anchor), $headCell = doc.resolve(this.head);
  815. if ($anchorCell.parent.type.spec.tableRole == "row" && $headCell.parent.type.spec.tableRole == "row" && $anchorCell.index() < $anchorCell.parent.childCount && $headCell.index() < $headCell.parent.childCount && inSameTable($anchorCell, $headCell))
  816. return new CellSelection($anchorCell, $headCell);
  817. else
  818. return import_prosemirror_state2.Selection.near($headCell, 1);
  819. }
  820. };
  821. function drawCellSelection(state) {
  822. if (!(state.selection instanceof CellSelection))
  823. return null;
  824. const cells = [];
  825. state.selection.forEachCell((node, pos) => {
  826. cells.push(
  827. import_prosemirror_view.Decoration.node(pos, pos + node.nodeSize, { class: "selectedCell" })
  828. );
  829. });
  830. return import_prosemirror_view.DecorationSet.create(state.doc, cells);
  831. }
  832. function isCellBoundarySelection({ $from, $to }) {
  833. if ($from.pos == $to.pos || $from.pos < $from.pos - 6)
  834. return false;
  835. let afterFrom = $from.pos;
  836. let beforeTo = $to.pos;
  837. let depth = $from.depth;
  838. for (; depth >= 0; depth--, afterFrom++)
  839. if ($from.after(depth + 1) < $from.end(depth))
  840. break;
  841. for (let d = $to.depth; d >= 0; d--, beforeTo--)
  842. if ($to.before(d + 1) > $to.start(d))
  843. break;
  844. return afterFrom == beforeTo && /row|table/.test($from.node(depth).type.spec.tableRole);
  845. }
  846. function isTextSelectionAcrossCells({ $from, $to }) {
  847. let fromCellBoundaryNode;
  848. let toCellBoundaryNode;
  849. for (let i = $from.depth; i > 0; i--) {
  850. const node = $from.node(i);
  851. if (node.type.spec.tableRole === "cell" || node.type.spec.tableRole === "header_cell") {
  852. fromCellBoundaryNode = node;
  853. break;
  854. }
  855. }
  856. for (let i = $to.depth; i > 0; i--) {
  857. const node = $to.node(i);
  858. if (node.type.spec.tableRole === "cell" || node.type.spec.tableRole === "header_cell") {
  859. toCellBoundaryNode = node;
  860. break;
  861. }
  862. }
  863. return fromCellBoundaryNode !== toCellBoundaryNode && $to.parentOffset === 0;
  864. }
  865. function normalizeSelection(state, tr, allowTableNodeSelection) {
  866. const sel = (tr || state).selection;
  867. const doc = (tr || state).doc;
  868. let normalize;
  869. let role;
  870. if (sel instanceof import_prosemirror_state2.NodeSelection && (role = sel.node.type.spec.tableRole)) {
  871. if (role == "cell" || role == "header_cell") {
  872. normalize = CellSelection.create(doc, sel.from);
  873. } else if (role == "row") {
  874. const $cell = doc.resolve(sel.from + 1);
  875. normalize = CellSelection.rowSelection($cell, $cell);
  876. } else if (!allowTableNodeSelection) {
  877. const map = TableMap.get(sel.node);
  878. const start = sel.from + 1;
  879. const lastCell = start + map.map[map.width * map.height - 1];
  880. normalize = CellSelection.create(doc, start + 1, lastCell);
  881. }
  882. } else if (sel instanceof import_prosemirror_state2.TextSelection && isCellBoundarySelection(sel)) {
  883. normalize = import_prosemirror_state2.TextSelection.create(doc, sel.from);
  884. } else if (sel instanceof import_prosemirror_state2.TextSelection && isTextSelectionAcrossCells(sel)) {
  885. normalize = import_prosemirror_state2.TextSelection.create(doc, sel.$from.start(), sel.$from.end());
  886. }
  887. if (normalize)
  888. (tr || (tr = state.tr)).setSelection(normalize);
  889. return tr;
  890. }
  891. // src/fixtables.ts
  892. var import_prosemirror_state3 = require("prosemirror-state");
  893. var fixTablesKey = new import_prosemirror_state3.PluginKey("fix-tables");
  894. function changedDescendants(old, cur, offset, f) {
  895. const oldSize = old.childCount, curSize = cur.childCount;
  896. outer:
  897. for (let i = 0, j = 0; i < curSize; i++) {
  898. const child = cur.child(i);
  899. for (let scan = j, e = Math.min(oldSize, i + 3); scan < e; scan++) {
  900. if (old.child(scan) == child) {
  901. j = scan + 1;
  902. offset += child.nodeSize;
  903. continue outer;
  904. }
  905. }
  906. f(child, offset);
  907. if (j < oldSize && old.child(j).sameMarkup(child))
  908. changedDescendants(old.child(j), child, offset + 1, f);
  909. else
  910. child.nodesBetween(0, child.content.size, f, offset + 1);
  911. offset += child.nodeSize;
  912. }
  913. }
  914. function fixTables(state, oldState) {
  915. let tr;
  916. const check = (node, pos) => {
  917. if (node.type.spec.tableRole == "table")
  918. tr = fixTable(state, node, pos, tr);
  919. };
  920. if (!oldState)
  921. state.doc.descendants(check);
  922. else if (oldState.doc != state.doc)
  923. changedDescendants(oldState.doc, state.doc, 0, check);
  924. return tr;
  925. }
  926. function fixTable(state, table, tablePos, tr) {
  927. const map = TableMap.get(table);
  928. if (!map.problems)
  929. return tr;
  930. if (!tr)
  931. tr = state.tr;
  932. const mustAdd = [];
  933. for (let i = 0; i < map.height; i++)
  934. mustAdd.push(0);
  935. for (let i = 0; i < map.problems.length; i++) {
  936. const prob = map.problems[i];
  937. if (prob.type == "collision") {
  938. const cell = table.nodeAt(prob.pos);
  939. if (!cell)
  940. continue;
  941. const attrs = cell.attrs;
  942. for (let j = 0; j < attrs.rowspan; j++)
  943. mustAdd[prob.row + j] += prob.n;
  944. tr.setNodeMarkup(
  945. tr.mapping.map(tablePos + 1 + prob.pos),
  946. null,
  947. removeColSpan(attrs, attrs.colspan - prob.n, prob.n)
  948. );
  949. } else if (prob.type == "missing") {
  950. mustAdd[prob.row] += prob.n;
  951. } else if (prob.type == "overlong_rowspan") {
  952. const cell = table.nodeAt(prob.pos);
  953. if (!cell)
  954. continue;
  955. tr.setNodeMarkup(tr.mapping.map(tablePos + 1 + prob.pos), null, {
  956. ...cell.attrs,
  957. rowspan: cell.attrs.rowspan - prob.n
  958. });
  959. } else if (prob.type == "colwidth mismatch") {
  960. const cell = table.nodeAt(prob.pos);
  961. if (!cell)
  962. continue;
  963. tr.setNodeMarkup(tr.mapping.map(tablePos + 1 + prob.pos), null, {
  964. ...cell.attrs,
  965. colwidth: prob.colwidth
  966. });
  967. }
  968. }
  969. let first, last;
  970. for (let i = 0; i < mustAdd.length; i++)
  971. if (mustAdd[i]) {
  972. if (first == null)
  973. first = i;
  974. last = i;
  975. }
  976. for (let i = 0, pos = tablePos + 1; i < map.height; i++) {
  977. const row = table.child(i);
  978. const end = pos + row.nodeSize;
  979. const add = mustAdd[i];
  980. if (add > 0) {
  981. let role = "cell";
  982. if (row.firstChild) {
  983. role = row.firstChild.type.spec.tableRole;
  984. }
  985. const nodes = [];
  986. for (let j = 0; j < add; j++) {
  987. const node = tableNodeTypes(state.schema)[role].createAndFill();
  988. if (node)
  989. nodes.push(node);
  990. }
  991. const side = (i == 0 || first == i - 1) && last == i ? pos + 1 : end - 1;
  992. tr.insert(tr.mapping.map(side), nodes);
  993. }
  994. pos = end;
  995. }
  996. return tr.setMeta(fixTablesKey, { fixTables: true });
  997. }
  998. // src/input.ts
  999. var import_prosemirror_model3 = require("prosemirror-model");
  1000. var import_prosemirror_state4 = require("prosemirror-state");
  1001. var import_prosemirror_keymap = require("prosemirror-keymap");
  1002. // src/copypaste.ts
  1003. var import_prosemirror_model2 = require("prosemirror-model");
  1004. var import_prosemirror_transform = require("prosemirror-transform");
  1005. function pastedCells(slice) {
  1006. if (!slice.size)
  1007. return null;
  1008. let { content, openStart, openEnd } = slice;
  1009. while (content.childCount == 1 && (openStart > 0 && openEnd > 0 || content.child(0).type.spec.tableRole == "table")) {
  1010. openStart--;
  1011. openEnd--;
  1012. content = content.child(0).content;
  1013. }
  1014. const first = content.child(0);
  1015. const role = first.type.spec.tableRole;
  1016. const schema = first.type.schema, rows = [];
  1017. if (role == "row") {
  1018. for (let i = 0; i < content.childCount; i++) {
  1019. let cells = content.child(i).content;
  1020. const left = i ? 0 : Math.max(0, openStart - 1);
  1021. const right = i < content.childCount - 1 ? 0 : Math.max(0, openEnd - 1);
  1022. if (left || right)
  1023. cells = fitSlice(
  1024. tableNodeTypes(schema).row,
  1025. new import_prosemirror_model2.Slice(cells, left, right)
  1026. ).content;
  1027. rows.push(cells);
  1028. }
  1029. } else if (role == "cell" || role == "header_cell") {
  1030. rows.push(
  1031. openStart || openEnd ? fitSlice(
  1032. tableNodeTypes(schema).row,
  1033. new import_prosemirror_model2.Slice(content, openStart, openEnd)
  1034. ).content : content
  1035. );
  1036. } else {
  1037. return null;
  1038. }
  1039. return ensureRectangular(schema, rows);
  1040. }
  1041. function ensureRectangular(schema, rows) {
  1042. const widths = [];
  1043. for (let i = 0; i < rows.length; i++) {
  1044. const row = rows[i];
  1045. for (let j = row.childCount - 1; j >= 0; j--) {
  1046. const { rowspan, colspan } = row.child(j).attrs;
  1047. for (let r = i; r < i + rowspan; r++)
  1048. widths[r] = (widths[r] || 0) + colspan;
  1049. }
  1050. }
  1051. let width = 0;
  1052. for (let r = 0; r < widths.length; r++)
  1053. width = Math.max(width, widths[r]);
  1054. for (let r = 0; r < widths.length; r++) {
  1055. if (r >= rows.length)
  1056. rows.push(import_prosemirror_model2.Fragment.empty);
  1057. if (widths[r] < width) {
  1058. const empty = tableNodeTypes(schema).cell.createAndFill();
  1059. const cells = [];
  1060. for (let i = widths[r]; i < width; i++) {
  1061. cells.push(empty);
  1062. }
  1063. rows[r] = rows[r].append(import_prosemirror_model2.Fragment.from(cells));
  1064. }
  1065. }
  1066. return { height: rows.length, width, rows };
  1067. }
  1068. function fitSlice(nodeType, slice) {
  1069. const node = nodeType.createAndFill();
  1070. const tr = new import_prosemirror_transform.Transform(node).replace(0, node.content.size, slice);
  1071. return tr.doc;
  1072. }
  1073. function clipCells({ width, height, rows }, newWidth, newHeight) {
  1074. if (width != newWidth) {
  1075. const added = [];
  1076. const newRows = [];
  1077. for (let row = 0; row < rows.length; row++) {
  1078. const frag = rows[row], cells = [];
  1079. for (let col = added[row] || 0, i = 0; col < newWidth; i++) {
  1080. let cell = frag.child(i % frag.childCount);
  1081. if (col + cell.attrs.colspan > newWidth)
  1082. cell = cell.type.createChecked(
  1083. removeColSpan(
  1084. cell.attrs,
  1085. cell.attrs.colspan,
  1086. col + cell.attrs.colspan - newWidth
  1087. ),
  1088. cell.content
  1089. );
  1090. cells.push(cell);
  1091. col += cell.attrs.colspan;
  1092. for (let j = 1; j < cell.attrs.rowspan; j++)
  1093. added[row + j] = (added[row + j] || 0) + cell.attrs.colspan;
  1094. }
  1095. newRows.push(import_prosemirror_model2.Fragment.from(cells));
  1096. }
  1097. rows = newRows;
  1098. width = newWidth;
  1099. }
  1100. if (height != newHeight) {
  1101. const newRows = [];
  1102. for (let row = 0, i = 0; row < newHeight; row++, i++) {
  1103. const cells = [], source = rows[i % height];
  1104. for (let j = 0; j < source.childCount; j++) {
  1105. let cell = source.child(j);
  1106. if (row + cell.attrs.rowspan > newHeight)
  1107. cell = cell.type.create(
  1108. {
  1109. ...cell.attrs,
  1110. rowspan: Math.max(1, newHeight - cell.attrs.rowspan)
  1111. },
  1112. cell.content
  1113. );
  1114. cells.push(cell);
  1115. }
  1116. newRows.push(import_prosemirror_model2.Fragment.from(cells));
  1117. }
  1118. rows = newRows;
  1119. height = newHeight;
  1120. }
  1121. return { width, height, rows };
  1122. }
  1123. function growTable(tr, map, table, start, width, height, mapFrom) {
  1124. const schema = tr.doc.type.schema;
  1125. const types = tableNodeTypes(schema);
  1126. let empty;
  1127. let emptyHead;
  1128. if (width > map.width) {
  1129. for (let row = 0, rowEnd = 0; row < map.height; row++) {
  1130. const rowNode = table.child(row);
  1131. rowEnd += rowNode.nodeSize;
  1132. const cells = [];
  1133. let add;
  1134. if (rowNode.lastChild == null || rowNode.lastChild.type == types.cell)
  1135. add = empty || (empty = types.cell.createAndFill());
  1136. else
  1137. add = emptyHead || (emptyHead = types.header_cell.createAndFill());
  1138. for (let i = map.width; i < width; i++)
  1139. cells.push(add);
  1140. tr.insert(tr.mapping.slice(mapFrom).map(rowEnd - 1 + start), cells);
  1141. }
  1142. }
  1143. if (height > map.height) {
  1144. const cells = [];
  1145. for (let i = 0, start2 = (map.height - 1) * map.width; i < Math.max(map.width, width); i++) {
  1146. const header = i >= map.width ? false : table.nodeAt(map.map[start2 + i]).type == types.header_cell;
  1147. cells.push(
  1148. header ? emptyHead || (emptyHead = types.header_cell.createAndFill()) : empty || (empty = types.cell.createAndFill())
  1149. );
  1150. }
  1151. const emptyRow = types.row.create(null, import_prosemirror_model2.Fragment.from(cells)), rows = [];
  1152. for (let i = map.height; i < height; i++)
  1153. rows.push(emptyRow);
  1154. tr.insert(tr.mapping.slice(mapFrom).map(start + table.nodeSize - 2), rows);
  1155. }
  1156. return !!(empty || emptyHead);
  1157. }
  1158. function isolateHorizontal(tr, map, table, start, left, right, top, mapFrom) {
  1159. if (top == 0 || top == map.height)
  1160. return false;
  1161. let found = false;
  1162. for (let col = left; col < right; col++) {
  1163. const index = top * map.width + col, pos = map.map[index];
  1164. if (map.map[index - map.width] == pos) {
  1165. found = true;
  1166. const cell = table.nodeAt(pos);
  1167. const { top: cellTop, left: cellLeft } = map.findCell(pos);
  1168. tr.setNodeMarkup(tr.mapping.slice(mapFrom).map(pos + start), null, {
  1169. ...cell.attrs,
  1170. rowspan: top - cellTop
  1171. });
  1172. tr.insert(
  1173. tr.mapping.slice(mapFrom).map(map.positionAt(top, cellLeft, table)),
  1174. cell.type.createAndFill({
  1175. ...cell.attrs,
  1176. rowspan: cellTop + cell.attrs.rowspan - top
  1177. })
  1178. );
  1179. col += cell.attrs.colspan - 1;
  1180. }
  1181. }
  1182. return found;
  1183. }
  1184. function isolateVertical(tr, map, table, start, top, bottom, left, mapFrom) {
  1185. if (left == 0 || left == map.width)
  1186. return false;
  1187. let found = false;
  1188. for (let row = top; row < bottom; row++) {
  1189. const index = row * map.width + left, pos = map.map[index];
  1190. if (map.map[index - 1] == pos) {
  1191. found = true;
  1192. const cell = table.nodeAt(pos);
  1193. const cellLeft = map.colCount(pos);
  1194. const updatePos = tr.mapping.slice(mapFrom).map(pos + start);
  1195. tr.setNodeMarkup(
  1196. updatePos,
  1197. null,
  1198. removeColSpan(
  1199. cell.attrs,
  1200. left - cellLeft,
  1201. cell.attrs.colspan - (left - cellLeft)
  1202. )
  1203. );
  1204. tr.insert(
  1205. updatePos + cell.nodeSize,
  1206. cell.type.createAndFill(
  1207. removeColSpan(cell.attrs, 0, left - cellLeft)
  1208. )
  1209. );
  1210. row += cell.attrs.rowspan - 1;
  1211. }
  1212. }
  1213. return found;
  1214. }
  1215. function insertCells(state, dispatch, tableStart, rect, cells) {
  1216. let table = tableStart ? state.doc.nodeAt(tableStart - 1) : state.doc;
  1217. if (!table) {
  1218. throw new Error("No table found");
  1219. }
  1220. let map = TableMap.get(table);
  1221. const { top, left } = rect;
  1222. const right = left + cells.width, bottom = top + cells.height;
  1223. const tr = state.tr;
  1224. let mapFrom = 0;
  1225. function recomp() {
  1226. table = tableStart ? tr.doc.nodeAt(tableStart - 1) : tr.doc;
  1227. if (!table) {
  1228. throw new Error("No table found");
  1229. }
  1230. map = TableMap.get(table);
  1231. mapFrom = tr.mapping.maps.length;
  1232. }
  1233. if (growTable(tr, map, table, tableStart, right, bottom, mapFrom))
  1234. recomp();
  1235. if (isolateHorizontal(tr, map, table, tableStart, left, right, top, mapFrom))
  1236. recomp();
  1237. if (isolateHorizontal(tr, map, table, tableStart, left, right, bottom, mapFrom))
  1238. recomp();
  1239. if (isolateVertical(tr, map, table, tableStart, top, bottom, left, mapFrom))
  1240. recomp();
  1241. if (isolateVertical(tr, map, table, tableStart, top, bottom, right, mapFrom))
  1242. recomp();
  1243. for (let row = top; row < bottom; row++) {
  1244. const from = map.positionAt(row, left, table), to = map.positionAt(row, right, table);
  1245. tr.replace(
  1246. tr.mapping.slice(mapFrom).map(from + tableStart),
  1247. tr.mapping.slice(mapFrom).map(to + tableStart),
  1248. new import_prosemirror_model2.Slice(cells.rows[row - top], 0, 0)
  1249. );
  1250. }
  1251. recomp();
  1252. tr.setSelection(
  1253. new CellSelection(
  1254. tr.doc.resolve(tableStart + map.positionAt(top, left, table)),
  1255. tr.doc.resolve(tableStart + map.positionAt(bottom - 1, right - 1, table))
  1256. )
  1257. );
  1258. dispatch(tr);
  1259. }
  1260. // src/input.ts
  1261. var handleKeyDown = (0, import_prosemirror_keymap.keydownHandler)({
  1262. ArrowLeft: arrow("horiz", -1),
  1263. ArrowRight: arrow("horiz", 1),
  1264. ArrowUp: arrow("vert", -1),
  1265. ArrowDown: arrow("vert", 1),
  1266. "Shift-ArrowLeft": shiftArrow("horiz", -1),
  1267. "Shift-ArrowRight": shiftArrow("horiz", 1),
  1268. "Shift-ArrowUp": shiftArrow("vert", -1),
  1269. "Shift-ArrowDown": shiftArrow("vert", 1),
  1270. Backspace: deleteCellSelection,
  1271. "Mod-Backspace": deleteCellSelection,
  1272. Delete: deleteCellSelection,
  1273. "Mod-Delete": deleteCellSelection
  1274. });
  1275. function maybeSetSelection(state, dispatch, selection) {
  1276. if (selection.eq(state.selection))
  1277. return false;
  1278. if (dispatch)
  1279. dispatch(state.tr.setSelection(selection).scrollIntoView());
  1280. return true;
  1281. }
  1282. function arrow(axis, dir) {
  1283. return (state, dispatch, view) => {
  1284. if (!view)
  1285. return false;
  1286. const sel = state.selection;
  1287. if (sel instanceof CellSelection) {
  1288. return maybeSetSelection(
  1289. state,
  1290. dispatch,
  1291. import_prosemirror_state4.Selection.near(sel.$headCell, dir)
  1292. );
  1293. }
  1294. if (axis != "horiz" && !sel.empty)
  1295. return false;
  1296. const end = atEndOfCell(view, axis, dir);
  1297. if (end == null)
  1298. return false;
  1299. if (axis == "horiz") {
  1300. return maybeSetSelection(
  1301. state,
  1302. dispatch,
  1303. import_prosemirror_state4.Selection.near(state.doc.resolve(sel.head + dir), dir)
  1304. );
  1305. } else {
  1306. const $cell = state.doc.resolve(end);
  1307. const $next = nextCell($cell, axis, dir);
  1308. let newSel;
  1309. if ($next)
  1310. newSel = import_prosemirror_state4.Selection.near($next, 1);
  1311. else if (dir < 0)
  1312. newSel = import_prosemirror_state4.Selection.near(state.doc.resolve($cell.before(-1)), -1);
  1313. else
  1314. newSel = import_prosemirror_state4.Selection.near(state.doc.resolve($cell.after(-1)), 1);
  1315. return maybeSetSelection(state, dispatch, newSel);
  1316. }
  1317. };
  1318. }
  1319. function shiftArrow(axis, dir) {
  1320. return (state, dispatch, view) => {
  1321. if (!view)
  1322. return false;
  1323. const sel = state.selection;
  1324. let cellSel;
  1325. if (sel instanceof CellSelection) {
  1326. cellSel = sel;
  1327. } else {
  1328. const end = atEndOfCell(view, axis, dir);
  1329. if (end == null)
  1330. return false;
  1331. cellSel = new CellSelection(state.doc.resolve(end));
  1332. }
  1333. const $head = nextCell(cellSel.$headCell, axis, dir);
  1334. if (!$head)
  1335. return false;
  1336. return maybeSetSelection(
  1337. state,
  1338. dispatch,
  1339. new CellSelection(cellSel.$anchorCell, $head)
  1340. );
  1341. };
  1342. }
  1343. function deleteCellSelection(state, dispatch) {
  1344. const sel = state.selection;
  1345. if (!(sel instanceof CellSelection))
  1346. return false;
  1347. if (dispatch) {
  1348. const tr = state.tr;
  1349. const baseContent = tableNodeTypes(state.schema).cell.createAndFill().content;
  1350. sel.forEachCell((cell, pos) => {
  1351. if (!cell.content.eq(baseContent))
  1352. tr.replace(
  1353. tr.mapping.map(pos + 1),
  1354. tr.mapping.map(pos + cell.nodeSize - 1),
  1355. new import_prosemirror_model3.Slice(baseContent, 0, 0)
  1356. );
  1357. });
  1358. if (tr.docChanged)
  1359. dispatch(tr);
  1360. }
  1361. return true;
  1362. }
  1363. function handleTripleClick(view, pos) {
  1364. const doc = view.state.doc, $cell = cellAround(doc.resolve(pos));
  1365. if (!$cell)
  1366. return false;
  1367. view.dispatch(view.state.tr.setSelection(new CellSelection($cell)));
  1368. return true;
  1369. }
  1370. function handlePaste(view, _, slice) {
  1371. if (!isInTable(view.state))
  1372. return false;
  1373. let cells = pastedCells(slice);
  1374. const sel = view.state.selection;
  1375. if (sel instanceof CellSelection) {
  1376. if (!cells)
  1377. cells = {
  1378. width: 1,
  1379. height: 1,
  1380. rows: [
  1381. import_prosemirror_model3.Fragment.from(
  1382. fitSlice(tableNodeTypes(view.state.schema).cell, slice)
  1383. )
  1384. ]
  1385. };
  1386. const table = sel.$anchorCell.node(-1);
  1387. const start = sel.$anchorCell.start(-1);
  1388. const rect = TableMap.get(table).rectBetween(
  1389. sel.$anchorCell.pos - start,
  1390. sel.$headCell.pos - start
  1391. );
  1392. cells = clipCells(cells, rect.right - rect.left, rect.bottom - rect.top);
  1393. insertCells(view.state, view.dispatch, start, rect, cells);
  1394. return true;
  1395. } else if (cells) {
  1396. const $cell = selectionCell(view.state);
  1397. const start = $cell.start(-1);
  1398. insertCells(
  1399. view.state,
  1400. view.dispatch,
  1401. start,
  1402. TableMap.get($cell.node(-1)).findCell($cell.pos - start),
  1403. cells
  1404. );
  1405. return true;
  1406. } else {
  1407. return false;
  1408. }
  1409. }
  1410. function handleMouseDown(view, startEvent) {
  1411. var _a;
  1412. if (startEvent.ctrlKey || startEvent.metaKey)
  1413. return;
  1414. const startDOMCell = domInCell(view, startEvent.target);
  1415. let $anchor;
  1416. if (startEvent.shiftKey && view.state.selection instanceof CellSelection) {
  1417. setCellSelection(view.state.selection.$anchorCell, startEvent);
  1418. startEvent.preventDefault();
  1419. } else if (startEvent.shiftKey && startDOMCell && ($anchor = cellAround(view.state.selection.$anchor)) != null && ((_a = cellUnderMouse(view, startEvent)) == null ? void 0 : _a.pos) != $anchor.pos) {
  1420. setCellSelection($anchor, startEvent);
  1421. startEvent.preventDefault();
  1422. } else if (!startDOMCell) {
  1423. return;
  1424. }
  1425. function setCellSelection($anchor2, event) {
  1426. let $head = cellUnderMouse(view, event);
  1427. const starting = tableEditingKey.getState(view.state) == null;
  1428. if (!$head || !inSameTable($anchor2, $head)) {
  1429. if (starting)
  1430. $head = $anchor2;
  1431. else
  1432. return;
  1433. }
  1434. const selection = new CellSelection($anchor2, $head);
  1435. if (starting || !view.state.selection.eq(selection)) {
  1436. const tr = view.state.tr.setSelection(selection);
  1437. if (starting)
  1438. tr.setMeta(tableEditingKey, $anchor2.pos);
  1439. view.dispatch(tr);
  1440. }
  1441. }
  1442. function stop() {
  1443. view.root.removeEventListener("mouseup", stop);
  1444. view.root.removeEventListener("dragstart", stop);
  1445. view.root.removeEventListener("mousemove", move);
  1446. if (tableEditingKey.getState(view.state) != null)
  1447. view.dispatch(view.state.tr.setMeta(tableEditingKey, -1));
  1448. }
  1449. function move(_event) {
  1450. const event = _event;
  1451. const anchor = tableEditingKey.getState(view.state);
  1452. let $anchor2;
  1453. if (anchor != null) {
  1454. $anchor2 = view.state.doc.resolve(anchor);
  1455. } else if (domInCell(view, event.target) != startDOMCell) {
  1456. $anchor2 = cellUnderMouse(view, startEvent);
  1457. if (!$anchor2)
  1458. return stop();
  1459. }
  1460. if ($anchor2)
  1461. setCellSelection($anchor2, event);
  1462. }
  1463. view.root.addEventListener("mouseup", stop);
  1464. view.root.addEventListener("dragstart", stop);
  1465. view.root.addEventListener("mousemove", move);
  1466. }
  1467. function atEndOfCell(view, axis, dir) {
  1468. if (!(view.state.selection instanceof import_prosemirror_state4.TextSelection))
  1469. return null;
  1470. const { $head } = view.state.selection;
  1471. for (let d = $head.depth - 1; d >= 0; d--) {
  1472. const parent = $head.node(d), index = dir < 0 ? $head.index(d) : $head.indexAfter(d);
  1473. if (index != (dir < 0 ? 0 : parent.childCount))
  1474. return null;
  1475. if (parent.type.spec.tableRole == "cell" || parent.type.spec.tableRole == "header_cell") {
  1476. const cellPos = $head.before(d);
  1477. const dirStr = axis == "vert" ? dir > 0 ? "down" : "up" : dir > 0 ? "right" : "left";
  1478. return view.endOfTextblock(dirStr) ? cellPos : null;
  1479. }
  1480. }
  1481. return null;
  1482. }
  1483. function domInCell(view, dom) {
  1484. for (; dom && dom != view.dom; dom = dom.parentNode) {
  1485. if (dom.nodeName == "TD" || dom.nodeName == "TH") {
  1486. return dom;
  1487. }
  1488. }
  1489. return null;
  1490. }
  1491. function cellUnderMouse(view, event) {
  1492. const mousePos = view.posAtCoords({
  1493. left: event.clientX,
  1494. top: event.clientY
  1495. });
  1496. if (!mousePos)
  1497. return null;
  1498. return mousePos ? cellAround(view.state.doc.resolve(mousePos.pos)) : null;
  1499. }
  1500. // src/columnresizing.ts
  1501. var import_prosemirror_state5 = require("prosemirror-state");
  1502. var import_prosemirror_view2 = require("prosemirror-view");
  1503. // src/tableview.ts
  1504. var TableView = class {
  1505. constructor(node, cellMinWidth) {
  1506. this.node = node;
  1507. this.cellMinWidth = cellMinWidth;
  1508. this.dom = document.createElement("div");
  1509. this.dom.className = "tableWrapper";
  1510. this.table = this.dom.appendChild(document.createElement("table"));
  1511. this.colgroup = this.table.appendChild(document.createElement("colgroup"));
  1512. updateColumnsOnResize(node, this.colgroup, this.table, cellMinWidth);
  1513. this.contentDOM = this.table.appendChild(document.createElement("tbody"));
  1514. }
  1515. update(node) {
  1516. if (node.type != this.node.type)
  1517. return false;
  1518. this.node = node;
  1519. updateColumnsOnResize(node, this.colgroup, this.table, this.cellMinWidth);
  1520. return true;
  1521. }
  1522. ignoreMutation(record) {
  1523. return record.type == "attributes" && (record.target == this.table || this.colgroup.contains(record.target));
  1524. }
  1525. };
  1526. function updateColumnsOnResize(node, colgroup, table, cellMinWidth, overrideCol, overrideValue) {
  1527. var _a;
  1528. let totalWidth = 0;
  1529. let fixedWidth = true;
  1530. let nextDOM = colgroup.firstChild;
  1531. const row = node.firstChild;
  1532. if (!row)
  1533. return;
  1534. for (let i = 0, col = 0; i < row.childCount; i++) {
  1535. const { colspan, colwidth } = row.child(i).attrs;
  1536. for (let j = 0; j < colspan; j++, col++) {
  1537. const hasWidth = overrideCol == col ? overrideValue : colwidth && colwidth[j];
  1538. const cssWidth = hasWidth ? hasWidth + "px" : "";
  1539. totalWidth += hasWidth || cellMinWidth;
  1540. if (!hasWidth)
  1541. fixedWidth = false;
  1542. if (!nextDOM) {
  1543. colgroup.appendChild(document.createElement("col")).style.width = cssWidth;
  1544. } else {
  1545. if (nextDOM.style.width != cssWidth)
  1546. nextDOM.style.width = cssWidth;
  1547. nextDOM = nextDOM.nextSibling;
  1548. }
  1549. }
  1550. }
  1551. while (nextDOM) {
  1552. const after = nextDOM.nextSibling;
  1553. (_a = nextDOM.parentNode) == null ? void 0 : _a.removeChild(nextDOM);
  1554. nextDOM = after;
  1555. }
  1556. if (fixedWidth) {
  1557. table.style.width = totalWidth + "px";
  1558. table.style.minWidth = "";
  1559. } else {
  1560. table.style.width = "";
  1561. table.style.minWidth = totalWidth + "px";
  1562. }
  1563. }
  1564. // src/columnresizing.ts
  1565. var columnResizingPluginKey = new import_prosemirror_state5.PluginKey(
  1566. "tableColumnResizing"
  1567. );
  1568. function columnResizing({
  1569. handleWidth = 5,
  1570. cellMinWidth = 25,
  1571. View = TableView,
  1572. lastColumnResizable = true
  1573. } = {}) {
  1574. const plugin = new import_prosemirror_state5.Plugin({
  1575. key: columnResizingPluginKey,
  1576. state: {
  1577. init(_, state) {
  1578. plugin.spec.props.nodeViews[tableNodeTypes(state.schema).table.name] = (node, view) => new View(node, cellMinWidth, view);
  1579. return new ResizeState(-1, false);
  1580. },
  1581. apply(tr, prev) {
  1582. return prev.apply(tr);
  1583. }
  1584. },
  1585. props: {
  1586. attributes: (state) => {
  1587. const pluginState = columnResizingPluginKey.getState(state);
  1588. return pluginState && pluginState.activeHandle > -1 ? { class: "resize-cursor" } : {};
  1589. },
  1590. handleDOMEvents: {
  1591. mousemove: (view, event) => {
  1592. handleMouseMove(
  1593. view,
  1594. event,
  1595. handleWidth,
  1596. cellMinWidth,
  1597. lastColumnResizable
  1598. );
  1599. },
  1600. mouseleave: (view) => {
  1601. handleMouseLeave(view);
  1602. },
  1603. mousedown: (view, event) => {
  1604. handleMouseDown2(view, event, cellMinWidth);
  1605. }
  1606. },
  1607. decorations: (state) => {
  1608. const pluginState = columnResizingPluginKey.getState(state);
  1609. if (pluginState && pluginState.activeHandle > -1) {
  1610. return handleDecorations(state, pluginState.activeHandle);
  1611. }
  1612. },
  1613. nodeViews: {}
  1614. }
  1615. });
  1616. return plugin;
  1617. }
  1618. var ResizeState = class _ResizeState {
  1619. constructor(activeHandle, dragging) {
  1620. this.activeHandle = activeHandle;
  1621. this.dragging = dragging;
  1622. }
  1623. apply(tr) {
  1624. const state = this;
  1625. const action = tr.getMeta(columnResizingPluginKey);
  1626. if (action && action.setHandle != null)
  1627. return new _ResizeState(action.setHandle, false);
  1628. if (action && action.setDragging !== void 0)
  1629. return new _ResizeState(state.activeHandle, action.setDragging);
  1630. if (state.activeHandle > -1 && tr.docChanged) {
  1631. let handle = tr.mapping.map(state.activeHandle, -1);
  1632. if (!pointsAtCell(tr.doc.resolve(handle))) {
  1633. handle = -1;
  1634. }
  1635. return new _ResizeState(handle, state.dragging);
  1636. }
  1637. return state;
  1638. }
  1639. };
  1640. function handleMouseMove(view, event, handleWidth, cellMinWidth, lastColumnResizable) {
  1641. const pluginState = columnResizingPluginKey.getState(view.state);
  1642. if (!pluginState)
  1643. return;
  1644. if (!pluginState.dragging) {
  1645. const target = domCellAround(event.target);
  1646. let cell = -1;
  1647. if (target) {
  1648. const { left, right } = target.getBoundingClientRect();
  1649. if (event.clientX - left <= handleWidth)
  1650. cell = edgeCell(view, event, "left", handleWidth);
  1651. else if (right - event.clientX <= handleWidth)
  1652. cell = edgeCell(view, event, "right", handleWidth);
  1653. }
  1654. if (cell != pluginState.activeHandle) {
  1655. if (!lastColumnResizable && cell !== -1) {
  1656. const $cell = view.state.doc.resolve(cell);
  1657. const table = $cell.node(-1);
  1658. const map = TableMap.get(table);
  1659. const tableStart = $cell.start(-1);
  1660. const col = map.colCount($cell.pos - tableStart) + $cell.nodeAfter.attrs.colspan - 1;
  1661. if (col == map.width - 1) {
  1662. return;
  1663. }
  1664. }
  1665. updateHandle(view, cell);
  1666. }
  1667. }
  1668. }
  1669. function handleMouseLeave(view) {
  1670. const pluginState = columnResizingPluginKey.getState(view.state);
  1671. if (pluginState && pluginState.activeHandle > -1 && !pluginState.dragging)
  1672. updateHandle(view, -1);
  1673. }
  1674. function handleMouseDown2(view, event, cellMinWidth) {
  1675. const pluginState = columnResizingPluginKey.getState(view.state);
  1676. if (!pluginState || pluginState.activeHandle == -1 || pluginState.dragging)
  1677. return false;
  1678. const cell = view.state.doc.nodeAt(pluginState.activeHandle);
  1679. const width = currentColWidth(view, pluginState.activeHandle, cell.attrs);
  1680. view.dispatch(
  1681. view.state.tr.setMeta(columnResizingPluginKey, {
  1682. setDragging: { startX: event.clientX, startWidth: width }
  1683. })
  1684. );
  1685. function finish(event2) {
  1686. window.removeEventListener("mouseup", finish);
  1687. window.removeEventListener("mousemove", move);
  1688. const pluginState2 = columnResizingPluginKey.getState(view.state);
  1689. if (pluginState2 == null ? void 0 : pluginState2.dragging) {
  1690. updateColumnWidth(
  1691. view,
  1692. pluginState2.activeHandle,
  1693. draggedWidth(pluginState2.dragging, event2, cellMinWidth)
  1694. );
  1695. view.dispatch(
  1696. view.state.tr.setMeta(columnResizingPluginKey, { setDragging: null })
  1697. );
  1698. }
  1699. }
  1700. function move(event2) {
  1701. if (!event2.which)
  1702. return finish(event2);
  1703. const pluginState2 = columnResizingPluginKey.getState(view.state);
  1704. if (!pluginState2)
  1705. return;
  1706. if (pluginState2.dragging) {
  1707. const dragged = draggedWidth(pluginState2.dragging, event2, cellMinWidth);
  1708. displayColumnWidth(view, pluginState2.activeHandle, dragged, cellMinWidth);
  1709. }
  1710. }
  1711. window.addEventListener("mouseup", finish);
  1712. window.addEventListener("mousemove", move);
  1713. event.preventDefault();
  1714. return true;
  1715. }
  1716. function currentColWidth(view, cellPos, { colspan, colwidth }) {
  1717. const width = colwidth && colwidth[colwidth.length - 1];
  1718. if (width)
  1719. return width;
  1720. const dom = view.domAtPos(cellPos);
  1721. const node = dom.node.childNodes[dom.offset];
  1722. let domWidth = node.offsetWidth, parts = colspan;
  1723. if (colwidth) {
  1724. for (let i = 0; i < colspan; i++)
  1725. if (colwidth[i]) {
  1726. domWidth -= colwidth[i];
  1727. parts--;
  1728. }
  1729. }
  1730. return domWidth / parts;
  1731. }
  1732. function domCellAround(target) {
  1733. while (target && target.nodeName != "TD" && target.nodeName != "TH")
  1734. target = target.classList && target.classList.contains("ProseMirror") ? null : target.parentNode;
  1735. return target;
  1736. }
  1737. function edgeCell(view, event, side, handleWidth) {
  1738. const offset = side == "right" ? -handleWidth : handleWidth;
  1739. const found = view.posAtCoords({
  1740. left: event.clientX + offset,
  1741. top: event.clientY
  1742. });
  1743. if (!found)
  1744. return -1;
  1745. const { pos } = found;
  1746. const $cell = cellAround(view.state.doc.resolve(pos));
  1747. if (!$cell)
  1748. return -1;
  1749. if (side == "right")
  1750. return $cell.pos;
  1751. const map = TableMap.get($cell.node(-1)), start = $cell.start(-1);
  1752. const index = map.map.indexOf($cell.pos - start);
  1753. return index % map.width == 0 ? -1 : start + map.map[index - 1];
  1754. }
  1755. function draggedWidth(dragging, event, cellMinWidth) {
  1756. const offset = event.clientX - dragging.startX;
  1757. return Math.max(cellMinWidth, dragging.startWidth + offset);
  1758. }
  1759. function updateHandle(view, value) {
  1760. view.dispatch(
  1761. view.state.tr.setMeta(columnResizingPluginKey, { setHandle: value })
  1762. );
  1763. }
  1764. function updateColumnWidth(view, cell, width) {
  1765. const $cell = view.state.doc.resolve(cell);
  1766. const table = $cell.node(-1), map = TableMap.get(table), start = $cell.start(-1);
  1767. const col = map.colCount($cell.pos - start) + $cell.nodeAfter.attrs.colspan - 1;
  1768. const tr = view.state.tr;
  1769. for (let row = 0; row < map.height; row++) {
  1770. const mapIndex = row * map.width + col;
  1771. if (row && map.map[mapIndex] == map.map[mapIndex - map.width])
  1772. continue;
  1773. const pos = map.map[mapIndex];
  1774. const attrs = table.nodeAt(pos).attrs;
  1775. const index = attrs.colspan == 1 ? 0 : col - map.colCount(pos);
  1776. if (attrs.colwidth && attrs.colwidth[index] == width)
  1777. continue;
  1778. const colwidth = attrs.colwidth ? attrs.colwidth.slice() : zeroes(attrs.colspan);
  1779. colwidth[index] = width;
  1780. tr.setNodeMarkup(start + pos, null, { ...attrs, colwidth });
  1781. }
  1782. if (tr.docChanged)
  1783. view.dispatch(tr);
  1784. }
  1785. function displayColumnWidth(view, cell, width, cellMinWidth) {
  1786. const $cell = view.state.doc.resolve(cell);
  1787. const table = $cell.node(-1), start = $cell.start(-1);
  1788. const col = TableMap.get(table).colCount($cell.pos - start) + $cell.nodeAfter.attrs.colspan - 1;
  1789. let dom = view.domAtPos($cell.start(-1)).node;
  1790. while (dom && dom.nodeName != "TABLE") {
  1791. dom = dom.parentNode;
  1792. }
  1793. if (!dom)
  1794. return;
  1795. updateColumnsOnResize(
  1796. table,
  1797. dom.firstChild,
  1798. dom,
  1799. cellMinWidth,
  1800. col,
  1801. width
  1802. );
  1803. }
  1804. function zeroes(n) {
  1805. return Array(n).fill(0);
  1806. }
  1807. function handleDecorations(state, cell) {
  1808. const decorations = [];
  1809. const $cell = state.doc.resolve(cell);
  1810. const table = $cell.node(-1);
  1811. if (!table) {
  1812. return import_prosemirror_view2.DecorationSet.empty;
  1813. }
  1814. const map = TableMap.get(table);
  1815. const start = $cell.start(-1);
  1816. const col = map.colCount($cell.pos - start) + $cell.nodeAfter.attrs.colspan;
  1817. for (let row = 0; row < map.height; row++) {
  1818. const index = col + row * map.width - 1;
  1819. if ((col == map.width || map.map[index] != map.map[index + 1]) && (row == 0 || map.map[index] != map.map[index - map.width])) {
  1820. const cellPos = map.map[index];
  1821. const pos = start + cellPos + table.nodeAt(cellPos).nodeSize - 1;
  1822. const dom = document.createElement("div");
  1823. dom.className = "column-resize-handle";
  1824. decorations.push(import_prosemirror_view2.Decoration.widget(pos, dom));
  1825. }
  1826. }
  1827. return import_prosemirror_view2.DecorationSet.create(state.doc, decorations);
  1828. }
  1829. // src/commands.ts
  1830. var import_prosemirror_model4 = require("prosemirror-model");
  1831. var import_prosemirror_state6 = require("prosemirror-state");
  1832. function selectedRect(state) {
  1833. const sel = state.selection;
  1834. const $pos = selectionCell(state);
  1835. const table = $pos.node(-1);
  1836. const tableStart = $pos.start(-1);
  1837. const map = TableMap.get(table);
  1838. const rect = sel instanceof CellSelection ? map.rectBetween(
  1839. sel.$anchorCell.pos - tableStart,
  1840. sel.$headCell.pos - tableStart
  1841. ) : map.findCell($pos.pos - tableStart);
  1842. return { ...rect, tableStart, map, table };
  1843. }
  1844. function addColumn(tr, { map, tableStart, table }, col) {
  1845. let refColumn = col > 0 ? -1 : 0;
  1846. if (columnIsHeader(map, table, col + refColumn)) {
  1847. refColumn = col == 0 || col == map.width ? null : 0;
  1848. }
  1849. for (let row = 0; row < map.height; row++) {
  1850. const index = row * map.width + col;
  1851. if (col > 0 && col < map.width && map.map[index - 1] == map.map[index]) {
  1852. const pos = map.map[index];
  1853. const cell = table.nodeAt(pos);
  1854. tr.setNodeMarkup(
  1855. tr.mapping.map(tableStart + pos),
  1856. null,
  1857. addColSpan(cell.attrs, col - map.colCount(pos))
  1858. );
  1859. row += cell.attrs.rowspan - 1;
  1860. } else {
  1861. const type = refColumn == null ? tableNodeTypes(table.type.schema).cell : table.nodeAt(map.map[index + refColumn]).type;
  1862. const pos = map.positionAt(row, col, table);
  1863. tr.insert(tr.mapping.map(tableStart + pos), type.createAndFill());
  1864. }
  1865. }
  1866. return tr;
  1867. }
  1868. function addColumnBefore(state, dispatch) {
  1869. if (!isInTable(state))
  1870. return false;
  1871. if (dispatch) {
  1872. const rect = selectedRect(state);
  1873. dispatch(addColumn(state.tr, rect, rect.left));
  1874. }
  1875. return true;
  1876. }
  1877. function addColumnAfter(state, dispatch) {
  1878. if (!isInTable(state))
  1879. return false;
  1880. if (dispatch) {
  1881. const rect = selectedRect(state);
  1882. dispatch(addColumn(state.tr, rect, rect.right));
  1883. }
  1884. return true;
  1885. }
  1886. function removeColumn(tr, { map, table, tableStart }, col) {
  1887. const mapStart = tr.mapping.maps.length;
  1888. for (let row = 0; row < map.height; ) {
  1889. const index = row * map.width + col;
  1890. const pos = map.map[index];
  1891. const cell = table.nodeAt(pos);
  1892. const attrs = cell.attrs;
  1893. if (col > 0 && map.map[index - 1] == pos || col < map.width - 1 && map.map[index + 1] == pos) {
  1894. tr.setNodeMarkup(
  1895. tr.mapping.slice(mapStart).map(tableStart + pos),
  1896. null,
  1897. removeColSpan(attrs, col - map.colCount(pos))
  1898. );
  1899. } else {
  1900. const start = tr.mapping.slice(mapStart).map(tableStart + pos);
  1901. tr.delete(start, start + cell.nodeSize);
  1902. }
  1903. row += attrs.rowspan;
  1904. }
  1905. }
  1906. function deleteColumn(state, dispatch) {
  1907. if (!isInTable(state))
  1908. return false;
  1909. if (dispatch) {
  1910. const rect = selectedRect(state);
  1911. const tr = state.tr;
  1912. if (rect.left == 0 && rect.right == rect.map.width)
  1913. return false;
  1914. for (let i = rect.right - 1; ; i--) {
  1915. removeColumn(tr, rect, i);
  1916. if (i == rect.left)
  1917. break;
  1918. const table = rect.tableStart ? tr.doc.nodeAt(rect.tableStart - 1) : tr.doc;
  1919. if (!table) {
  1920. throw RangeError("No table found");
  1921. }
  1922. rect.table = table;
  1923. rect.map = TableMap.get(table);
  1924. }
  1925. dispatch(tr);
  1926. }
  1927. return true;
  1928. }
  1929. function rowIsHeader(map, table, row) {
  1930. var _a;
  1931. const headerCell = tableNodeTypes(table.type.schema).header_cell;
  1932. for (let col = 0; col < map.width; col++)
  1933. if (((_a = table.nodeAt(map.map[col + row * map.width])) == null ? void 0 : _a.type) != headerCell)
  1934. return false;
  1935. return true;
  1936. }
  1937. function addRow(tr, { map, tableStart, table }, row) {
  1938. var _a;
  1939. let rowPos = tableStart;
  1940. for (let i = 0; i < row; i++)
  1941. rowPos += table.child(i).nodeSize;
  1942. const cells = [];
  1943. let refRow = row > 0 ? -1 : 0;
  1944. if (rowIsHeader(map, table, row + refRow))
  1945. refRow = row == 0 || row == map.height ? null : 0;
  1946. for (let col = 0, index = map.width * row; col < map.width; col++, index++) {
  1947. if (row > 0 && row < map.height && map.map[index] == map.map[index - map.width]) {
  1948. const pos = map.map[index];
  1949. const attrs = table.nodeAt(pos).attrs;
  1950. tr.setNodeMarkup(tableStart + pos, null, {
  1951. ...attrs,
  1952. rowspan: attrs.rowspan + 1
  1953. });
  1954. col += attrs.colspan - 1;
  1955. } else {
  1956. const type = refRow == null ? tableNodeTypes(table.type.schema).cell : (_a = table.nodeAt(map.map[index + refRow * map.width])) == null ? void 0 : _a.type;
  1957. const node = type == null ? void 0 : type.createAndFill();
  1958. if (node)
  1959. cells.push(node);
  1960. }
  1961. }
  1962. tr.insert(rowPos, tableNodeTypes(table.type.schema).row.create(null, cells));
  1963. return tr;
  1964. }
  1965. function addRowBefore(state, dispatch) {
  1966. if (!isInTable(state))
  1967. return false;
  1968. if (dispatch) {
  1969. const rect = selectedRect(state);
  1970. dispatch(addRow(state.tr, rect, rect.top));
  1971. }
  1972. return true;
  1973. }
  1974. function addRowAfter(state, dispatch) {
  1975. if (!isInTable(state))
  1976. return false;
  1977. if (dispatch) {
  1978. const rect = selectedRect(state);
  1979. dispatch(addRow(state.tr, rect, rect.bottom));
  1980. }
  1981. return true;
  1982. }
  1983. function removeRow(tr, { map, table, tableStart }, row) {
  1984. let rowPos = 0;
  1985. for (let i = 0; i < row; i++)
  1986. rowPos += table.child(i).nodeSize;
  1987. const nextRow = rowPos + table.child(row).nodeSize;
  1988. const mapFrom = tr.mapping.maps.length;
  1989. tr.delete(rowPos + tableStart, nextRow + tableStart);
  1990. const seen = /* @__PURE__ */ new Set();
  1991. for (let col = 0, index = row * map.width; col < map.width; col++, index++) {
  1992. const pos = map.map[index];
  1993. if (seen.has(pos))
  1994. continue;
  1995. seen.add(pos);
  1996. if (row > 0 && pos == map.map[index - map.width]) {
  1997. const attrs = table.nodeAt(pos).attrs;
  1998. tr.setNodeMarkup(tr.mapping.slice(mapFrom).map(pos + tableStart), null, {
  1999. ...attrs,
  2000. rowspan: attrs.rowspan - 1
  2001. });
  2002. col += attrs.colspan - 1;
  2003. } else if (row < map.height && pos == map.map[index + map.width]) {
  2004. const cell = table.nodeAt(pos);
  2005. const attrs = cell.attrs;
  2006. const copy = cell.type.create(
  2007. { ...attrs, rowspan: cell.attrs.rowspan - 1 },
  2008. cell.content
  2009. );
  2010. const newPos = map.positionAt(row + 1, col, table);
  2011. tr.insert(tr.mapping.slice(mapFrom).map(tableStart + newPos), copy);
  2012. col += attrs.colspan - 1;
  2013. }
  2014. }
  2015. }
  2016. function deleteRow(state, dispatch) {
  2017. if (!isInTable(state))
  2018. return false;
  2019. if (dispatch) {
  2020. const rect = selectedRect(state), tr = state.tr;
  2021. if (rect.top == 0 && rect.bottom == rect.map.height)
  2022. return false;
  2023. for (let i = rect.bottom - 1; ; i--) {
  2024. removeRow(tr, rect, i);
  2025. if (i == rect.top)
  2026. break;
  2027. const table = rect.tableStart ? tr.doc.nodeAt(rect.tableStart - 1) : tr.doc;
  2028. if (!table) {
  2029. throw RangeError("No table found");
  2030. }
  2031. rect.table = table;
  2032. rect.map = TableMap.get(rect.table);
  2033. }
  2034. dispatch(tr);
  2035. }
  2036. return true;
  2037. }
  2038. function isEmpty(cell) {
  2039. const c = cell.content;
  2040. return c.childCount == 1 && c.child(0).isTextblock && c.child(0).childCount == 0;
  2041. }
  2042. function cellsOverlapRectangle({ width, height, map }, rect) {
  2043. let indexTop = rect.top * width + rect.left, indexLeft = indexTop;
  2044. let indexBottom = (rect.bottom - 1) * width + rect.left, indexRight = indexTop + (rect.right - rect.left - 1);
  2045. for (let i = rect.top; i < rect.bottom; i++) {
  2046. if (rect.left > 0 && map[indexLeft] == map[indexLeft - 1] || rect.right < width && map[indexRight] == map[indexRight + 1])
  2047. return true;
  2048. indexLeft += width;
  2049. indexRight += width;
  2050. }
  2051. for (let i = rect.left; i < rect.right; i++) {
  2052. if (rect.top > 0 && map[indexTop] == map[indexTop - width] || rect.bottom < height && map[indexBottom] == map[indexBottom + width])
  2053. return true;
  2054. indexTop++;
  2055. indexBottom++;
  2056. }
  2057. return false;
  2058. }
  2059. function mergeCells(state, dispatch) {
  2060. const sel = state.selection;
  2061. if (!(sel instanceof CellSelection) || sel.$anchorCell.pos == sel.$headCell.pos)
  2062. return false;
  2063. const rect = selectedRect(state), { map } = rect;
  2064. if (cellsOverlapRectangle(map, rect))
  2065. return false;
  2066. if (dispatch) {
  2067. const tr = state.tr;
  2068. const seen = {};
  2069. let content = import_prosemirror_model4.Fragment.empty;
  2070. let mergedPos;
  2071. let mergedCell;
  2072. for (let row = rect.top; row < rect.bottom; row++) {
  2073. for (let col = rect.left; col < rect.right; col++) {
  2074. const cellPos = map.map[row * map.width + col];
  2075. const cell = rect.table.nodeAt(cellPos);
  2076. if (seen[cellPos] || !cell)
  2077. continue;
  2078. seen[cellPos] = true;
  2079. if (mergedPos == null) {
  2080. mergedPos = cellPos;
  2081. mergedCell = cell;
  2082. } else {
  2083. if (!isEmpty(cell))
  2084. content = content.append(cell.content);
  2085. const mapped = tr.mapping.map(cellPos + rect.tableStart);
  2086. tr.delete(mapped, mapped + cell.nodeSize);
  2087. }
  2088. }
  2089. }
  2090. if (mergedPos == null || mergedCell == null) {
  2091. return true;
  2092. }
  2093. tr.setNodeMarkup(mergedPos + rect.tableStart, null, {
  2094. ...addColSpan(
  2095. mergedCell.attrs,
  2096. mergedCell.attrs.colspan,
  2097. rect.right - rect.left - mergedCell.attrs.colspan
  2098. ),
  2099. rowspan: rect.bottom - rect.top
  2100. });
  2101. if (content.size) {
  2102. const end = mergedPos + 1 + mergedCell.content.size;
  2103. const start = isEmpty(mergedCell) ? mergedPos + 1 : end;
  2104. tr.replaceWith(start + rect.tableStart, end + rect.tableStart, content);
  2105. }
  2106. tr.setSelection(
  2107. new CellSelection(tr.doc.resolve(mergedPos + rect.tableStart))
  2108. );
  2109. dispatch(tr);
  2110. }
  2111. return true;
  2112. }
  2113. function splitCell(state, dispatch) {
  2114. const nodeTypes = tableNodeTypes(state.schema);
  2115. return splitCellWithType(({ node }) => {
  2116. return nodeTypes[node.type.spec.tableRole];
  2117. })(state, dispatch);
  2118. }
  2119. function splitCellWithType(getCellType) {
  2120. return (state, dispatch) => {
  2121. var _a;
  2122. const sel = state.selection;
  2123. let cellNode;
  2124. let cellPos;
  2125. if (!(sel instanceof CellSelection)) {
  2126. cellNode = cellWrapping(sel.$from);
  2127. if (!cellNode)
  2128. return false;
  2129. cellPos = (_a = cellAround(sel.$from)) == null ? void 0 : _a.pos;
  2130. } else {
  2131. if (sel.$anchorCell.pos != sel.$headCell.pos)
  2132. return false;
  2133. cellNode = sel.$anchorCell.nodeAfter;
  2134. cellPos = sel.$anchorCell.pos;
  2135. }
  2136. if (cellNode == null || cellPos == null) {
  2137. return false;
  2138. }
  2139. if (cellNode.attrs.colspan == 1 && cellNode.attrs.rowspan == 1) {
  2140. return false;
  2141. }
  2142. if (dispatch) {
  2143. let baseAttrs = cellNode.attrs;
  2144. const attrs = [];
  2145. const colwidth = baseAttrs.colwidth;
  2146. if (baseAttrs.rowspan > 1)
  2147. baseAttrs = { ...baseAttrs, rowspan: 1 };
  2148. if (baseAttrs.colspan > 1)
  2149. baseAttrs = { ...baseAttrs, colspan: 1 };
  2150. const rect = selectedRect(state), tr = state.tr;
  2151. for (let i = 0; i < rect.right - rect.left; i++)
  2152. attrs.push(
  2153. colwidth ? {
  2154. ...baseAttrs,
  2155. colwidth: colwidth && colwidth[i] ? [colwidth[i]] : null
  2156. } : baseAttrs
  2157. );
  2158. let lastCell;
  2159. for (let row = rect.top; row < rect.bottom; row++) {
  2160. let pos = rect.map.positionAt(row, rect.left, rect.table);
  2161. if (row == rect.top)
  2162. pos += cellNode.nodeSize;
  2163. for (let col = rect.left, i = 0; col < rect.right; col++, i++) {
  2164. if (col == rect.left && row == rect.top)
  2165. continue;
  2166. tr.insert(
  2167. lastCell = tr.mapping.map(pos + rect.tableStart, 1),
  2168. getCellType({ node: cellNode, row, col }).createAndFill(attrs[i])
  2169. );
  2170. }
  2171. }
  2172. tr.setNodeMarkup(
  2173. cellPos,
  2174. getCellType({ node: cellNode, row: rect.top, col: rect.left }),
  2175. attrs[0]
  2176. );
  2177. if (sel instanceof CellSelection)
  2178. tr.setSelection(
  2179. new CellSelection(
  2180. tr.doc.resolve(sel.$anchorCell.pos),
  2181. lastCell ? tr.doc.resolve(lastCell) : void 0
  2182. )
  2183. );
  2184. dispatch(tr);
  2185. }
  2186. return true;
  2187. };
  2188. }
  2189. function setCellAttr(name, value) {
  2190. return function(state, dispatch) {
  2191. if (!isInTable(state))
  2192. return false;
  2193. const $cell = selectionCell(state);
  2194. if ($cell.nodeAfter.attrs[name] === value)
  2195. return false;
  2196. if (dispatch) {
  2197. const tr = state.tr;
  2198. if (state.selection instanceof CellSelection)
  2199. state.selection.forEachCell((node, pos) => {
  2200. if (node.attrs[name] !== value)
  2201. tr.setNodeMarkup(pos, null, {
  2202. ...node.attrs,
  2203. [name]: value
  2204. });
  2205. });
  2206. else
  2207. tr.setNodeMarkup($cell.pos, null, {
  2208. ...$cell.nodeAfter.attrs,
  2209. [name]: value
  2210. });
  2211. dispatch(tr);
  2212. }
  2213. return true;
  2214. };
  2215. }
  2216. function deprecated_toggleHeader(type) {
  2217. return function(state, dispatch) {
  2218. if (!isInTable(state))
  2219. return false;
  2220. if (dispatch) {
  2221. const types = tableNodeTypes(state.schema);
  2222. const rect = selectedRect(state), tr = state.tr;
  2223. const cells = rect.map.cellsInRect(
  2224. type == "column" ? {
  2225. left: rect.left,
  2226. top: 0,
  2227. right: rect.right,
  2228. bottom: rect.map.height
  2229. } : type == "row" ? {
  2230. left: 0,
  2231. top: rect.top,
  2232. right: rect.map.width,
  2233. bottom: rect.bottom
  2234. } : rect
  2235. );
  2236. const nodes = cells.map((pos) => rect.table.nodeAt(pos));
  2237. for (let i = 0; i < cells.length; i++)
  2238. if (nodes[i].type == types.header_cell)
  2239. tr.setNodeMarkup(
  2240. rect.tableStart + cells[i],
  2241. types.cell,
  2242. nodes[i].attrs
  2243. );
  2244. if (tr.steps.length == 0)
  2245. for (let i = 0; i < cells.length; i++)
  2246. tr.setNodeMarkup(
  2247. rect.tableStart + cells[i],
  2248. types.header_cell,
  2249. nodes[i].attrs
  2250. );
  2251. dispatch(tr);
  2252. }
  2253. return true;
  2254. };
  2255. }
  2256. function isHeaderEnabledByType(type, rect, types) {
  2257. const cellPositions = rect.map.cellsInRect({
  2258. left: 0,
  2259. top: 0,
  2260. right: type == "row" ? rect.map.width : 1,
  2261. bottom: type == "column" ? rect.map.height : 1
  2262. });
  2263. for (let i = 0; i < cellPositions.length; i++) {
  2264. const cell = rect.table.nodeAt(cellPositions[i]);
  2265. if (cell && cell.type !== types.header_cell) {
  2266. return false;
  2267. }
  2268. }
  2269. return true;
  2270. }
  2271. function toggleHeader(type, options) {
  2272. options = options || { useDeprecatedLogic: false };
  2273. if (options.useDeprecatedLogic)
  2274. return deprecated_toggleHeader(type);
  2275. return function(state, dispatch) {
  2276. if (!isInTable(state))
  2277. return false;
  2278. if (dispatch) {
  2279. const types = tableNodeTypes(state.schema);
  2280. const rect = selectedRect(state), tr = state.tr;
  2281. const isHeaderRowEnabled = isHeaderEnabledByType("row", rect, types);
  2282. const isHeaderColumnEnabled = isHeaderEnabledByType(
  2283. "column",
  2284. rect,
  2285. types
  2286. );
  2287. const isHeaderEnabled = type === "column" ? isHeaderRowEnabled : type === "row" ? isHeaderColumnEnabled : false;
  2288. const selectionStartsAt = isHeaderEnabled ? 1 : 0;
  2289. const cellsRect = type == "column" ? {
  2290. left: 0,
  2291. top: selectionStartsAt,
  2292. right: 1,
  2293. bottom: rect.map.height
  2294. } : type == "row" ? {
  2295. left: selectionStartsAt,
  2296. top: 0,
  2297. right: rect.map.width,
  2298. bottom: 1
  2299. } : rect;
  2300. const newType = type == "column" ? isHeaderColumnEnabled ? types.cell : types.header_cell : type == "row" ? isHeaderRowEnabled ? types.cell : types.header_cell : types.cell;
  2301. rect.map.cellsInRect(cellsRect).forEach((relativeCellPos) => {
  2302. const cellPos = relativeCellPos + rect.tableStart;
  2303. const cell = tr.doc.nodeAt(cellPos);
  2304. if (cell) {
  2305. tr.setNodeMarkup(cellPos, newType, cell.attrs);
  2306. }
  2307. });
  2308. dispatch(tr);
  2309. }
  2310. return true;
  2311. };
  2312. }
  2313. var toggleHeaderRow = toggleHeader("row", {
  2314. useDeprecatedLogic: true
  2315. });
  2316. var toggleHeaderColumn = toggleHeader("column", {
  2317. useDeprecatedLogic: true
  2318. });
  2319. var toggleHeaderCell = toggleHeader("cell", {
  2320. useDeprecatedLogic: true
  2321. });
  2322. function findNextCell($cell, dir) {
  2323. if (dir < 0) {
  2324. const before = $cell.nodeBefore;
  2325. if (before)
  2326. return $cell.pos - before.nodeSize;
  2327. for (let row = $cell.index(-1) - 1, rowEnd = $cell.before(); row >= 0; row--) {
  2328. const rowNode = $cell.node(-1).child(row);
  2329. const lastChild = rowNode.lastChild;
  2330. if (lastChild) {
  2331. return rowEnd - 1 - lastChild.nodeSize;
  2332. }
  2333. rowEnd -= rowNode.nodeSize;
  2334. }
  2335. } else {
  2336. if ($cell.index() < $cell.parent.childCount - 1) {
  2337. return $cell.pos + $cell.nodeAfter.nodeSize;
  2338. }
  2339. const table = $cell.node(-1);
  2340. for (let row = $cell.indexAfter(-1), rowStart = $cell.after(); row < table.childCount; row++) {
  2341. const rowNode = table.child(row);
  2342. if (rowNode.childCount)
  2343. return rowStart + 1;
  2344. rowStart += rowNode.nodeSize;
  2345. }
  2346. }
  2347. return null;
  2348. }
  2349. function goToNextCell(direction) {
  2350. return function(state, dispatch) {
  2351. if (!isInTable(state))
  2352. return false;
  2353. const cell = findNextCell(selectionCell(state), direction);
  2354. if (cell == null)
  2355. return false;
  2356. if (dispatch) {
  2357. const $cell = state.doc.resolve(cell);
  2358. dispatch(
  2359. state.tr.setSelection(import_prosemirror_state6.TextSelection.between($cell, moveCellForward($cell))).scrollIntoView()
  2360. );
  2361. }
  2362. return true;
  2363. };
  2364. }
  2365. function deleteTable(state, dispatch) {
  2366. const $pos = state.selection.$anchor;
  2367. for (let d = $pos.depth; d > 0; d--) {
  2368. const node = $pos.node(d);
  2369. if (node.type.spec.tableRole == "table") {
  2370. if (dispatch)
  2371. dispatch(
  2372. state.tr.delete($pos.before(d), $pos.after(d)).scrollIntoView()
  2373. );
  2374. return true;
  2375. }
  2376. }
  2377. return false;
  2378. }
  2379. // src/index.ts
  2380. function tableEditing({
  2381. allowTableNodeSelection = false
  2382. } = {}) {
  2383. return new import_prosemirror_state7.Plugin({
  2384. key: tableEditingKey,
  2385. // This piece of state is used to remember when a mouse-drag
  2386. // cell-selection is happening, so that it can continue even as
  2387. // transactions (which might move its anchor cell) come in.
  2388. state: {
  2389. init() {
  2390. return null;
  2391. },
  2392. apply(tr, cur) {
  2393. const set = tr.getMeta(tableEditingKey);
  2394. if (set != null)
  2395. return set == -1 ? null : set;
  2396. if (cur == null || !tr.docChanged)
  2397. return cur;
  2398. const { deleted, pos } = tr.mapping.mapResult(cur);
  2399. return deleted ? null : pos;
  2400. }
  2401. },
  2402. props: {
  2403. decorations: drawCellSelection,
  2404. handleDOMEvents: {
  2405. mousedown: handleMouseDown
  2406. },
  2407. createSelectionBetween(view) {
  2408. return tableEditingKey.getState(view.state) != null ? view.state.selection : null;
  2409. },
  2410. handleTripleClick,
  2411. handleKeyDown,
  2412. handlePaste
  2413. },
  2414. appendTransaction(_, oldState, state) {
  2415. return normalizeSelection(
  2416. state,
  2417. fixTables(state, oldState),
  2418. allowTableNodeSelection
  2419. );
  2420. }
  2421. });
  2422. }
  2423. // Annotate the CommonJS export names for ESM import in node:
  2424. 0 && (module.exports = {
  2425. CellBookmark,
  2426. CellSelection,
  2427. ResizeState,
  2428. TableMap,
  2429. TableView,
  2430. __clipCells,
  2431. __insertCells,
  2432. __pastedCells,
  2433. addColSpan,
  2434. addColumn,
  2435. addColumnAfter,
  2436. addColumnBefore,
  2437. addRow,
  2438. addRowAfter,
  2439. addRowBefore,
  2440. cellAround,
  2441. colCount,
  2442. columnIsHeader,
  2443. columnResizing,
  2444. columnResizingPluginKey,
  2445. deleteColumn,
  2446. deleteRow,
  2447. deleteTable,
  2448. findCell,
  2449. fixTables,
  2450. fixTablesKey,
  2451. goToNextCell,
  2452. handlePaste,
  2453. inSameTable,
  2454. isInTable,
  2455. mergeCells,
  2456. moveCellForward,
  2457. nextCell,
  2458. pointsAtCell,
  2459. removeColSpan,
  2460. removeColumn,
  2461. removeRow,
  2462. rowIsHeader,
  2463. selectedRect,
  2464. selectionCell,
  2465. setCellAttr,
  2466. splitCell,
  2467. splitCellWithType,
  2468. tableEditing,
  2469. tableEditingKey,
  2470. tableNodeTypes,
  2471. tableNodes,
  2472. toggleHeader,
  2473. toggleHeaderCell,
  2474. toggleHeaderColumn,
  2475. toggleHeaderRow,
  2476. updateColumnsOnResize
  2477. });