@burger-editor/client 4.0.0-alpha.44 → 4.0.0-alpha.45

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client.js CHANGED
@@ -620,7 +620,7 @@ var hasRequiredDayjs_min;
620
620
  function requireDayjs_min () {
621
621
  if (hasRequiredDayjs_min) return dayjs_min$1.exports;
622
622
  hasRequiredDayjs_min = 1;
623
- (function (module, exports) {
623
+ (function (module, exports$1) {
624
624
  !function(t,e){module.exports=e();}(dayjs_min,(function(){var t=1e3,e=6e4,n=36e5,r="millisecond",i="second",s="minute",u="hour",a="day",o="week",c="month",f="quarter",h="year",d="date",l="Invalid Date",$=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,y=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,M={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(t){var e=["th","st","nd","rd"],n=t%100;return "["+t+(e[(n-20)%10]||e[n]||e[0])+"]"}},m=function(t,e,n){var r=String(t);return !r||r.length>=e?t:""+Array(e+1-r.length).join(n)+t},v={s:m,z:function(t){var e=-t.utcOffset(),n=Math.abs(e),r=Math.floor(n/60),i=n%60;return (e<=0?"+":"-")+m(r,2,"0")+":"+m(i,2,"0")},m:function t(e,n){if(e.date()<n.date())return -t(n,e);var r=12*(n.year()-e.year())+(n.month()-e.month()),i=e.clone().add(r,c),s=n-i<0,u=e.clone().add(r+(s?-1:1),c);return +(-(r+(n-i)/(s?i-u:u-i))||0)},a:function(t){return t<0?Math.ceil(t)||0:Math.floor(t)},p:function(t){return {M:c,y:h,w:o,d:a,D:d,h:u,m:s,s:i,ms:r,Q:f}[t]||String(t||"").toLowerCase().replace(/s$/,"")},u:function(t){return void 0===t}},g="en",D={};D[g]=M;var p="$isDayjsObject",S=function(t){return t instanceof _||!(!t||!t[p])},w=function t(e,n,r){var i;if(!e)return g;if("string"==typeof e){var s=e.toLowerCase();D[s]&&(i=s),n&&(D[s]=n,i=s);var u=e.split("-");if(!i&&u.length>1)return t(u[0])}else {var a=e.name;D[a]=e,i=a;}return !r&&i&&(g=i),i||!r&&g},O=function(t,e){if(S(t))return t.clone();var n="object"==typeof e?e:{};return n.date=t,n.args=arguments,new _(n)},b=v;b.l=w,b.i=S,b.w=function(t,e){return O(t,{locale:e.$L,utc:e.$u,x:e.$x,$offset:e.$offset})};var _=function(){function M(t){this.$L=w(t.locale,null,true),this.parse(t),this.$x=this.$x||t.x||{},this[p]=true;}var m=M.prototype;return m.parse=function(t){this.$d=function(t){var e=t.date,n=t.utc;if(null===e)return new Date(NaN);if(b.u(e))return new Date;if(e instanceof Date)return new Date(e);if("string"==typeof e&&!/Z$/i.test(e)){var r=e.match($);if(r){var i=r[2]-1||0,s=(r[7]||"0").substring(0,3);return n?new Date(Date.UTC(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,s)):new Date(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,s)}}return new Date(e)}(t),this.init();},m.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds();},m.$utils=function(){return b},m.isValid=function(){return !(this.$d.toString()===l)},m.isSame=function(t,e){var n=O(t);return this.startOf(e)<=n&&n<=this.endOf(e)},m.isAfter=function(t,e){return O(t)<this.startOf(e)},m.isBefore=function(t,e){return this.endOf(e)<O(t)},m.$g=function(t,e,n){return b.u(t)?this[e]:this.set(n,t)},m.unix=function(){return Math.floor(this.valueOf()/1e3)},m.valueOf=function(){return this.$d.getTime()},m.startOf=function(t,e){var n=this,r=!!b.u(e)||e,f=b.p(t),l=function(t,e){var i=b.w(n.$u?Date.UTC(n.$y,e,t):new Date(n.$y,e,t),n);return r?i:i.endOf(a)},$=function(t,e){return b.w(n.toDate()[t].apply(n.toDate("s"),(r?[0,0,0,0]:[23,59,59,999]).slice(e)),n)},y=this.$W,M=this.$M,m=this.$D,v="set"+(this.$u?"UTC":"");switch(f){case h:return r?l(1,0):l(31,11);case c:return r?l(1,M):l(0,M+1);case o:var g=this.$locale().weekStart||0,D=(y<g?y+7:y)-g;return l(r?m-D:m+(6-D),M);case a:case d:return $(v+"Hours",0);case u:return $(v+"Minutes",1);case s:return $(v+"Seconds",2);case i:return $(v+"Milliseconds",3);default:return this.clone()}},m.endOf=function(t){return this.startOf(t,false)},m.$set=function(t,e){var n,o=b.p(t),f="set"+(this.$u?"UTC":""),l=(n={},n[a]=f+"Date",n[d]=f+"Date",n[c]=f+"Month",n[h]=f+"FullYear",n[u]=f+"Hours",n[s]=f+"Minutes",n[i]=f+"Seconds",n[r]=f+"Milliseconds",n)[o],$=o===a?this.$D+(e-this.$W):e;if(o===c||o===h){var y=this.clone().set(d,1);y.$d[l]($),y.init(),this.$d=y.set(d,Math.min(this.$D,y.daysInMonth())).$d;}else l&&this.$d[l]($);return this.init(),this},m.set=function(t,e){return this.clone().$set(t,e)},m.get=function(t){return this[b.p(t)]()},m.add=function(r,f){var d,l=this;r=Number(r);var $=b.p(f),y=function(t){var e=O(l);return b.w(e.date(e.date()+Math.round(t*r)),l)};if($===c)return this.set(c,this.$M+r);if($===h)return this.set(h,this.$y+r);if($===a)return y(1);if($===o)return y(7);var M=(d={},d[s]=e,d[u]=n,d[i]=t,d)[$]||1,m=this.$d.getTime()+r*M;return b.w(m,this)},m.subtract=function(t,e){return this.add(-1*t,e)},m.format=function(t){var e=this,n=this.$locale();if(!this.isValid())return n.invalidDate||l;var r=t||"YYYY-MM-DDTHH:mm:ssZ",i=b.z(this),s=this.$H,u=this.$m,a=this.$M,o=n.weekdays,c=n.months,f=n.meridiem,h=function(t,n,i,s){return t&&(t[n]||t(e,r))||i[n].slice(0,s)},d=function(t){return b.s(s%12||12,t,"0")},$=f||function(t,e,n){var r=t<12?"AM":"PM";return n?r.toLowerCase():r};return r.replace(y,(function(t,r){return r||function(t){switch(t){case "YY":return String(e.$y).slice(-2);case "YYYY":return b.s(e.$y,4,"0");case "M":return a+1;case "MM":return b.s(a+1,2,"0");case "MMM":return h(n.monthsShort,a,c,3);case "MMMM":return h(c,a);case "D":return e.$D;case "DD":return b.s(e.$D,2,"0");case "d":return String(e.$W);case "dd":return h(n.weekdaysMin,e.$W,o,2);case "ddd":return h(n.weekdaysShort,e.$W,o,3);case "dddd":return o[e.$W];case "H":return String(s);case "HH":return b.s(s,2,"0");case "h":return d(1);case "hh":return d(2);case "a":return $(s,u,true);case "A":return $(s,u,false);case "m":return String(u);case "mm":return b.s(u,2,"0");case "s":return String(e.$s);case "ss":return b.s(e.$s,2,"0");case "SSS":return b.s(e.$ms,3,"0");case "Z":return i}return null}(t)||i.replace(":","")}))},m.utcOffset=function(){return 15*-Math.round(this.$d.getTimezoneOffset()/15)},m.diff=function(r,d,l){var $,y=this,M=b.p(d),m=O(r),v=(m.utcOffset()-this.utcOffset())*e,g=this-m,D=function(){return b.m(y,m)};switch(M){case h:$=D()/12;break;case c:$=D();break;case f:$=D()/3;break;case o:$=(g-v)/6048e5;break;case a:$=(g-v)/864e5;break;case u:$=g/n;break;case s:$=g/e;break;case i:$=g/t;break;default:$=g;}return l?$:b.a($)},m.daysInMonth=function(){return this.endOf(c).$D},m.$locale=function(){return D[this.$L]},m.locale=function(t,e){if(!t)return this.$L;var n=this.clone(),r=w(t,e,true);return r&&(n.$L=r),n},m.clone=function(){return b.w(this.$d,this)},m.toDate=function(){return new Date(this.valueOf())},m.toJSON=function(){return this.isValid()?this.toISOString():null},m.toISOString=function(){return this.$d.toISOString()},m.toString=function(){return this.$d.toUTCString()},M}(),k=_.prototype;return O.prototype=k,[["$ms",r],["$s",i],["$m",s],["$H",u],["$W",a],["$M",c],["$y",h],["$D",d]].forEach((function(t){k[t[1]]=function(e){return this.$g(e,t[0],t[1])};})),O.extend=function(t,e){return t.$i||(t(e,_,O),t.$i=true),O},O.locale=w,O.isDayjs=S,O.unix=function(t){return O(1e3*t)},O.en=D[g],O.Ls=D,O.p={},O}));
625
625
  } (dayjs_min$1));
626
626
  return dayjs_min$1.exports;
@@ -2803,12 +2803,13 @@ function isBurgerBlockElement(el) {
2803
2803
  *
2804
2804
  * @param doc
2805
2805
  * @param url
2806
+ * @param id
2806
2807
  */
2807
- function appendStylesheetTo(doc, url) {
2808
+ function appendStylesheetTo(doc, url, id) {
2808
2809
  const link = doc.createElement('link');
2809
2810
  link.rel = 'stylesheet';
2810
2811
  link.crossOrigin = 'anonymous';
2811
- link.href = url;
2812
+ link.href = `${url}#${id}`;
2812
2813
  doc.head.append(link);
2813
2814
  }
2814
2815
 
@@ -2873,7 +2874,7 @@ class EditorUI {
2873
2874
  this.#el.dataset.bgeComponent = name;
2874
2875
  if (options?.stylesheet) {
2875
2876
  const url = createStylesheet(options.stylesheet, CSS_LAYER.ui);
2876
- appendStylesheetTo(this.el.ownerDocument, url);
2877
+ appendStylesheetTo(this.el.ownerDocument, url, `${name}-${CSS_LAYER.ui}`);
2877
2878
  }
2878
2879
  }
2879
2880
  hide() {
@@ -3202,7 +3203,63 @@ async function createStylesheetFromUrl(url, layer) {
3202
3203
  const css = layer ? `@layer ${layer} {${cssContents}}` : cssContents;
3203
3204
  const blob = new Blob([css], { type: 'text/css' });
3204
3205
  const blobUrl = URL.createObjectURL(blob);
3205
- return blobUrl;
3206
+ return {
3207
+ blob: blobUrl,
3208
+ originalUrl: url,
3209
+ };
3210
+ }
3211
+
3212
+ /**
3213
+ * Compare two priority arrays
3214
+ * Smaller numbers have higher priority.
3215
+ * @param a First priority array
3216
+ * @param b Second priority array
3217
+ * @returns 0 if priorities are equal, -1 if a has lower priority than b, 1 if a has higher priority than b
3218
+ */
3219
+ function comparePriority(a, b) {
3220
+ // Empty array has the highest priority (smallest number)
3221
+ if (a.length === 0 && b.length === 0) {
3222
+ return 0;
3223
+ }
3224
+ if (a.length === 0) {
3225
+ return 1; // a has higher priority
3226
+ }
3227
+ if (b.length === 0) {
3228
+ return -1; // a has lower priority
3229
+ }
3230
+ const minLength = Math.min(a.length, b.length);
3231
+ for (let i = 0; i < minLength - 1; i++) {
3232
+ if (a[i] > b[i]) {
3233
+ return -1;
3234
+ }
3235
+ if (a[i] < b[i]) {
3236
+ return 1;
3237
+ }
3238
+ }
3239
+ // If all elements up to minLength - 1 match, compare the last element
3240
+ if (minLength > 0) {
3241
+ const aLast = a[minLength - 1];
3242
+ const bLast = b[minLength - 1];
3243
+ // Special case: if minLength >= 3, all previous elements match, and last elements are both in [0, 1] range,
3244
+ // ignore the last element difference and check length
3245
+ if (minLength >= 3 && aLast >= 0 && aLast <= 1 && bLast >= 0 && bLast <= 1) {
3246
+ // If lengths differ, shorter array's elements are all matched
3247
+ if (a.length !== b.length) {
3248
+ return 0;
3249
+ }
3250
+ // Same length, all elements matched including last (treated as equal)
3251
+ return 0;
3252
+ }
3253
+ // Normal comparison for last element
3254
+ if (aLast > bLast) {
3255
+ return -1;
3256
+ }
3257
+ if (aLast < bLast) {
3258
+ return 1;
3259
+ }
3260
+ }
3261
+ // All elements are equal up to minLength
3262
+ return 0;
3206
3263
  }
3207
3264
 
3208
3265
  /**
@@ -3213,7 +3270,7 @@ async function createStylesheetFromUrl(url, layer) {
3213
3270
  function getCustomProperties(scope, containerType) {
3214
3271
  const categories = new Map();
3215
3272
  const defaultValues = new Map();
3216
- searchCustomProperty(scope, (cssProperty, value) => {
3273
+ searchCustomProperty(scope, (cssProperty, value, layers) => {
3217
3274
  if (!cssProperty.startsWith(BLOCK_OPTION_CSS_CUSTOM_PROPERTY_PREFIX)) {
3218
3275
  return;
3219
3276
  }
@@ -3232,10 +3289,26 @@ function getCustomProperties(scope, containerType) {
3232
3289
  properties: new Map(),
3233
3290
  };
3234
3291
  if (key) {
3235
- currentMap.properties.set(key, { value, isDefault: false });
3292
+ const newProperty = {
3293
+ value,
3294
+ isDefault: false,
3295
+ priority: layers.map((layer) => layer.priority),
3296
+ };
3297
+ const currentProperty = currentMap.properties.get(key);
3298
+ currentMap.properties.set(key, currentProperty
3299
+ ? compareCustomPropertyByLayerPriority(currentProperty, newProperty)
3300
+ : newProperty);
3236
3301
  }
3237
3302
  else {
3238
- defaultValues.set(propName, value);
3303
+ const newDefaultValue = {
3304
+ value,
3305
+ isDefault: true,
3306
+ priority: layers.map((layer) => layer.priority),
3307
+ };
3308
+ const currentDefaultValue = defaultValues.get(propName);
3309
+ defaultValues.set(propName, currentDefaultValue
3310
+ ? compareCustomPropertyByLayerPriority(currentDefaultValue, newDefaultValue)
3311
+ : newDefaultValue);
3239
3312
  }
3240
3313
  categories.set(propName, currentMap);
3241
3314
  });
@@ -3246,13 +3319,14 @@ function getCustomProperties(scope, containerType) {
3246
3319
  }
3247
3320
  }
3248
3321
  }
3249
- for (const [category, value] of defaultValues.entries()) {
3322
+ for (const [category, property] of defaultValues.entries()) {
3250
3323
  const currentMap = categories.get(category);
3251
3324
  if (!currentMap) {
3252
3325
  continue;
3253
3326
  }
3254
3327
  for (const [key, customProperty] of currentMap.properties.entries()) {
3255
- if (value === `var(${BLOCK_OPTION_CSS_CUSTOM_PROPERTY_PREFIX}${category}--${key})`) {
3328
+ if (property.value ===
3329
+ `var(${BLOCK_OPTION_CSS_CUSTOM_PROPERTY_PREFIX}${category}--${key})`) {
3256
3330
  customProperty.isDefault = true;
3257
3331
  }
3258
3332
  }
@@ -3285,10 +3359,11 @@ function getCustomProperty(scope, property) {
3285
3359
  /**
3286
3360
  * Get all CSSStyleRule from CSSRule array recursively
3287
3361
  * @param rules - CSSRule array
3362
+ * @param layers
3288
3363
  * @param scope - Document
3289
3364
  * @returns CSSStyleRule array
3290
3365
  */
3291
- function getStyleRules(rules, scope) {
3366
+ function getStyleRules(rules, layers, scope) {
3292
3367
  const CSSStyleRule = scope.defaultView?.CSSStyleRule;
3293
3368
  if (CSSStyleRule === undefined) {
3294
3369
  throw new Error('CSSStyleRule is not available');
@@ -3297,15 +3372,32 @@ function getStyleRules(rules, scope) {
3297
3372
  if (CSSLayerBlockRule === undefined) {
3298
3373
  throw new Error('CSSLayerBlockRule is not available');
3299
3374
  }
3375
+ const CSSLayerStatementRule = scope.defaultView?.CSSLayerStatementRule;
3376
+ if (CSSLayerStatementRule === undefined) {
3377
+ throw new Error('CSSLayerStatementRule is not available');
3378
+ }
3379
+ const layerPriorities = [...rules].filter((rule) => rule instanceof CSSLayerStatementRule);
3300
3380
  const styleRules = [];
3301
3381
  for (const rule of rules) {
3302
- if (rule instanceof CSSStyleRule && rule.selectorText) {
3303
- styleRules.push(...getStyleRules(rule.cssRules, scope), rule);
3304
- continue;
3382
+ if (rule instanceof CSSStyleRule) {
3383
+ styleRules.push({
3384
+ rule,
3385
+ _cssText: rule.cssText,
3386
+ layers,
3387
+ }, ...getStyleRules(rule.cssRules, layers, scope));
3305
3388
  }
3306
3389
  if (rule instanceof CSSLayerBlockRule) {
3307
- styleRules.push(...getStyleRules(rule.cssRules, scope));
3308
- continue;
3390
+ const layerName = rule.name;
3391
+ const foundPriorityLayerList = layerPriorities.find((priority) => priority.nameList.includes(layerName));
3392
+ const priority = foundPriorityLayerList?.nameList.toReversed().indexOf(layerName) ?? 0;
3393
+ styleRules.push(...getStyleRules(rule.cssRules, [
3394
+ ...layers,
3395
+ {
3396
+ priorityList: foundPriorityLayerList?.nameList ?? [],
3397
+ layerName,
3398
+ priority: 1 + priority,
3399
+ },
3400
+ ], scope));
3309
3401
  }
3310
3402
  }
3311
3403
  return styleRules;
@@ -3318,16 +3410,16 @@ function getStyleRules(rules, scope) {
3318
3410
  function searchCustomProperty(scope, found) {
3319
3411
  for (const styleSheet of scope.styleSheets) {
3320
3412
  try {
3321
- const styleRules = getStyleRules(styleSheet.cssRules, scope);
3413
+ const styleRules = getStyleRules(styleSheet.cssRules, [], scope);
3322
3414
  for (const cssRule of styleRules) {
3323
- const selector = cssRule.selectorText.trim().replace(/^&/, '').trim();
3415
+ const selector = cssRule.rule.selectorText.trim().replace(/^&/, '').trim();
3324
3416
  if (selector === BLOCK_OPTION_SCOPE_SELECTOR) {
3325
- for (const cssProperty of cssRule.style) {
3417
+ for (const cssProperty of cssRule.rule.style) {
3326
3418
  if (!cssProperty.startsWith('--')) {
3327
3419
  continue;
3328
3420
  }
3329
- const value = cssRule.style.getPropertyValue(cssProperty);
3330
- found(cssProperty, value);
3421
+ const value = cssRule.rule.style.getPropertyValue(cssProperty);
3422
+ found(cssProperty, value, cssRule.layers);
3331
3423
  }
3332
3424
  }
3333
3425
  }
@@ -3340,6 +3432,28 @@ function searchCustomProperty(scope, found) {
3340
3432
  }
3341
3433
  }
3342
3434
  }
3435
+ /**
3436
+ * Compare custom property by layer priority
3437
+ *
3438
+ * - レイヤーの数が少ないほど優先度が高い
3439
+ * - レイヤーの数が同じ場合は、レイヤーの優先度の値が小さいほど優先度が高い
3440
+ * - 全てのレイヤーの優先度が同じ場合は、bを返す
3441
+ * @param a
3442
+ * @param b
3443
+ */
3444
+ function compareCustomPropertyByLayerPriority(a, b) {
3445
+ const result = comparePriority(a.priority, b.priority);
3446
+ if (result === 0) {
3447
+ return b;
3448
+ }
3449
+ if (result === -1) {
3450
+ return b;
3451
+ }
3452
+ if (result === 1) {
3453
+ return a;
3454
+ }
3455
+ return b;
3456
+ }
3343
3457
 
3344
3458
  const getCSSPropertyAsNumberCache = new Map();
3345
3459
  /**
@@ -3585,8 +3699,8 @@ class EditableArea extends EditorUI {
3585
3699
  }
3586
3700
  this.#frameElement.contentWindow.document.open();
3587
3701
  this.#frameElement.contentWindow.document.close();
3588
- for (const cssPath of stylesheets) {
3589
- appendStylesheetTo(this.#frameElement.contentWindow.document, cssPath);
3702
+ for (const { path, id } of stylesheets) {
3703
+ appendStylesheetTo(this.#frameElement.contentWindow.document, path, id);
3590
3704
  }
3591
3705
  this.#frameElement.contentWindow.document.body.setAttribute('style', 'margin: 0; border: 0;');
3592
3706
  this.#containerElement =
@@ -4457,7 +4571,20 @@ class BurgerEditorEngine {
4457
4571
  const componentStylesheets = await Promise.all(options.config.stylesheets.map(async (stylesheet) => {
4458
4572
  return createStylesheetFromUrl(stylesheet.path, stylesheet.layer ?? CSS_LAYER.components);
4459
4573
  }));
4460
- const stylesheets = [layers, baseStylesheet, ...componentStylesheets];
4574
+ const stylesheets = [
4575
+ {
4576
+ path: layers,
4577
+ id: 'layers',
4578
+ },
4579
+ {
4580
+ path: baseStylesheet,
4581
+ id: 'base-stylesheet',
4582
+ },
4583
+ ...componentStylesheets.map(({ blob, originalUrl }) => ({
4584
+ path: blob,
4585
+ id: originalUrl,
4586
+ })),
4587
+ ];
4461
4588
  const mainInitialContent = typeof options.initialContents === 'string'
4462
4589
  ? options.initialContents
4463
4590
  : options.initialContents.main;
@@ -5336,9 +5463,11 @@ function removeRange(content, from, to) {
5336
5463
  function insertInto(content, dist, insert, parent) {
5337
5464
  let { index, offset } = content.findIndex(dist), child = content.maybeChild(index);
5338
5465
  if (offset == dist || child.isText) {
5466
+ if (parent && !parent.canReplace(index, index, insert))
5467
+ return null;
5339
5468
  return content.cut(0, dist).append(insert).append(content.cut(dist));
5340
5469
  }
5341
- let inner = insertInto(child.content, dist - offset - 1, insert);
5470
+ let inner = insertInto(child.content, dist - offset - 1, insert, child);
5342
5471
  return inner && content.replaceChild(index, child.copy(inner));
5343
5472
  }
5344
5473
  function replace($from, $to, slice) {
@@ -7451,6 +7580,7 @@ class ParseContext {
7451
7580
  let value = dom.nodeValue;
7452
7581
  let top = this.top, preserveWS = (top.options & OPT_PRESERVE_WS_FULL) ? "full"
7453
7582
  : this.localPreserveWS || (top.options & OPT_PRESERVE_WS) > 0;
7583
+ let { schema } = this.parser;
7454
7584
  if (preserveWS === "full" ||
7455
7585
  top.inlineContext(dom) ||
7456
7586
  /[^ \t\r\n\u000c]/.test(value)) {
@@ -7468,14 +7598,24 @@ class ParseContext {
7468
7598
  value = value.slice(1);
7469
7599
  }
7470
7600
  }
7471
- else if (preserveWS !== "full") {
7472
- value = value.replace(/\r?\n|\r/g, " ");
7601
+ else if (preserveWS === "full") {
7602
+ value = value.replace(/\r\n?/g, "\n");
7603
+ }
7604
+ else if (schema.linebreakReplacement && /[\r\n]/.test(value) && this.top.findWrapping(schema.linebreakReplacement.create())) {
7605
+ let lines = value.split(/\r?\n|\r/);
7606
+ for (let i = 0; i < lines.length; i++) {
7607
+ if (i)
7608
+ this.insertNode(schema.linebreakReplacement.create(), marks, true);
7609
+ if (lines[i])
7610
+ this.insertNode(schema.text(lines[i]), marks, !/\S/.test(lines[i]));
7611
+ }
7612
+ value = "";
7473
7613
  }
7474
7614
  else {
7475
- value = value.replace(/\r\n?/g, "\n");
7615
+ value = value.replace(/\r?\n|\r/g, " ");
7476
7616
  }
7477
7617
  if (value)
7478
- this.insertNode(this.parser.schema.text(value), marks, !/\S/.test(value));
7618
+ this.insertNode(schema.text(value), marks, !/\S/.test(value));
7479
7619
  this.findInText(dom);
7480
7620
  }
7481
7621
  else {
@@ -9088,13 +9228,17 @@ can be lifted. Will not go across
9088
9228
  function liftTarget(range) {
9089
9229
  let parent = range.parent;
9090
9230
  let content = parent.content.cutByIndex(range.startIndex, range.endIndex);
9091
- for (let depth = range.depth;; --depth) {
9231
+ for (let depth = range.depth, contentBefore = 0, contentAfter = 0;; --depth) {
9092
9232
  let node = range.$from.node(depth);
9093
- let index = range.$from.index(depth), endIndex = range.$to.indexAfter(depth);
9233
+ let index = range.$from.index(depth) + contentBefore, endIndex = range.$to.indexAfter(depth) - contentAfter;
9094
9234
  if (depth < range.depth && node.canReplace(index, endIndex, content))
9095
9235
  return depth;
9096
9236
  if (depth == 0 || node.type.spec.isolating || !canCut(node, index, endIndex))
9097
9237
  break;
9238
+ if (index)
9239
+ contentBefore = 1;
9240
+ if (endIndex < node.childCount)
9241
+ contentAfter = 1;
9098
9242
  }
9099
9243
  return null;
9100
9244
  }
@@ -9745,7 +9889,7 @@ function replaceRange(tr, from, to, slice) {
9745
9889
  let $from = tr.doc.resolve(from), $to = tr.doc.resolve(to);
9746
9890
  if (fitsTrivially($from, $to, slice))
9747
9891
  return tr.step(new ReplaceStep(from, to, slice));
9748
- let targetDepths = coveredDepths($from, tr.doc.resolve(to));
9892
+ let targetDepths = coveredDepths($from, $to);
9749
9893
  // Can't replace the whole document, so remove 0 if it's present
9750
9894
  if (targetDepths[targetDepths.length - 1] == 0)
9751
9895
  targetDepths.pop();
@@ -10892,7 +11036,6 @@ class Transaction extends Transform {
10892
11036
  else {
10893
11037
  if (to == null)
10894
11038
  to = from;
10895
- to = to == null ? from : to;
10896
11039
  if (!text)
10897
11040
  return this.deleteRange(from, to);
10898
11041
  let marks = this.storedMarks;
@@ -10901,7 +11044,7 @@ class Transaction extends Transform {
10901
11044
  marks = to == from ? $from.marks() : $from.marksAcross(this.doc.resolve(to));
10902
11045
  }
10903
11046
  this.replaceRangeWith(from, to, schema.text(text, marks));
10904
- if (!this.selection.empty)
11047
+ if (!this.selection.empty && this.selection.to == from + text.length)
10905
11048
  this.setSelection(Selection.near(this.selection.$to));
10906
11049
  return this;
10907
11050
  }
@@ -11097,7 +11240,7 @@ class EditorState {
11097
11240
  return newInstance;
11098
11241
  }
11099
11242
  /**
11100
- Start a [transaction](https://prosemirror.net/docs/ref/#state.Transaction) from this state.
11243
+ Accessor that constructs and returns a new [transaction](https://prosemirror.net/docs/ref/#state.Transaction) from this state.
11101
11244
  */
11102
11245
  get tr() { return new Transaction(this); }
11103
11246
  /**
@@ -12422,17 +12565,20 @@ function findOffsetInNode(node, coords) {
12422
12565
  }
12423
12566
  function findOffsetInText(node, coords) {
12424
12567
  let len = node.nodeValue.length;
12425
- let range = document.createRange();
12568
+ let range = document.createRange(), result;
12426
12569
  for (let i = 0; i < len; i++) {
12427
12570
  range.setEnd(node, i + 1);
12428
12571
  range.setStart(node, i);
12429
12572
  let rect = singleRect(range, 1);
12430
12573
  if (rect.top == rect.bottom)
12431
12574
  continue;
12432
- if (inRect(coords, rect))
12433
- return { node, offset: i + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0) };
12575
+ if (inRect(coords, rect)) {
12576
+ result = { node, offset: i + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0) };
12577
+ break;
12578
+ }
12434
12579
  }
12435
- return { node, offset: 0 };
12580
+ range.detach();
12581
+ return result || { node, offset: 0 };
12436
12582
  }
12437
12583
  function inRect(coords, rect) {
12438
12584
  return coords.left >= rect.left - 1 && coords.left <= rect.right + 1 &&
@@ -13127,7 +13273,7 @@ class ViewDesc {
13127
13273
  // (one where the focus is before the anchor), but not all
13128
13274
  // browsers support it yet.
13129
13275
  let domSelExtended = false;
13130
- if ((domSel.extend || anchor == head) && !brKludge) {
13276
+ if ((domSel.extend || anchor == head) && !(brKludge && gecko)) {
13131
13277
  domSel.collapse(anchorDOM.node, anchorDOM.offset);
13132
13278
  try {
13133
13279
  if (anchor != head)
@@ -13539,17 +13685,18 @@ class NodeViewDesc extends ViewDesc {
13539
13685
  }
13540
13686
  // Mark this node as being the selected node.
13541
13687
  selectNode() {
13542
- if (this.nodeDOM.nodeType == 1)
13688
+ if (this.nodeDOM.nodeType == 1) {
13543
13689
  this.nodeDOM.classList.add("ProseMirror-selectednode");
13544
- if (this.contentDOM || !this.node.type.spec.draggable)
13545
- this.dom.draggable = true;
13690
+ if (this.contentDOM || !this.node.type.spec.draggable)
13691
+ this.nodeDOM.draggable = true;
13692
+ }
13546
13693
  }
13547
13694
  // Remove selected node marking from this node.
13548
13695
  deselectNode() {
13549
13696
  if (this.nodeDOM.nodeType == 1) {
13550
13697
  this.nodeDOM.classList.remove("ProseMirror-selectednode");
13551
13698
  if (this.contentDOM || !this.node.type.spec.draggable)
13552
- this.dom.removeAttribute("draggable");
13699
+ this.nodeDOM.removeAttribute("draggable");
13553
13700
  }
13554
13701
  }
13555
13702
  get domAtom() { return this.node.isAtom; }
@@ -14388,17 +14535,14 @@ function removeClassOnSelectionChange(view) {
14388
14535
  });
14389
14536
  }
14390
14537
  function selectCursorWrapper(view) {
14391
- let domSel = view.domSelection(), range = document.createRange();
14538
+ let domSel = view.domSelection();
14392
14539
  if (!domSel)
14393
14540
  return;
14394
14541
  let node = view.cursorWrapper.dom, img = node.nodeName == "IMG";
14395
14542
  if (img)
14396
- range.setStart(node.parentNode, domIndex(node) + 1);
14543
+ domSel.collapse(node.parentNode, domIndex(node) + 1);
14397
14544
  else
14398
- range.setStart(node, 0);
14399
- range.collapse(true);
14400
- domSel.removeAllRanges();
14401
- domSel.addRange(range);
14545
+ domSel.collapse(node, 0);
14402
14546
  // Kludge to kill 'control selection' in IE11 when selecting an
14403
14547
  // invisible cursor wrapper, since that would result in those weird
14404
14548
  // resize handles and a selection that considers the absolutely
@@ -14876,11 +15020,14 @@ function parseFromClipboard(view, text, html, plainText, $context) {
14876
15020
  let dom, slice;
14877
15021
  if (!html && !text)
14878
15022
  return null;
14879
- let asText = text && (plainText || inCode || !html);
15023
+ let asText = !!text && (plainText || inCode || !html);
14880
15024
  if (asText) {
14881
15025
  view.someProp("transformPastedText", f => { text = f(text, inCode || plainText, view); });
14882
- if (inCode)
14883
- return text ? new Slice(Fragment.from(view.state.schema.text(text.replace(/\r\n?/g, "\n"))), 0, 0) : Slice.empty;
15026
+ if (inCode) {
15027
+ slice = new Slice(Fragment.from(view.state.schema.text(text.replace(/\r\n?/g, "\n"))), 0, 0);
15028
+ view.someProp("transformPasted", f => { slice = f(slice, view, true); });
15029
+ return slice;
15030
+ }
14884
15031
  let parsed = view.someProp("clipboardTextParser", f => f(text, $context, plainText, view));
14885
15032
  if (parsed) {
14886
15033
  slice = parsed;
@@ -14938,7 +15085,7 @@ function parseFromClipboard(view, text, html, plainText, $context) {
14938
15085
  slice = closeSlice(slice, openStart, openEnd);
14939
15086
  }
14940
15087
  }
14941
- view.someProp("transformPasted", f => { slice = f(slice, view); });
15088
+ view.someProp("transformPasted", f => { slice = f(slice, view, asText); });
14942
15089
  return slice;
14943
15090
  }
14944
15091
  const inlineParents = /^(a|abbr|acronym|b|cite|code|del|em|i|ins|kbd|label|output|q|ruby|s|samp|span|strong|sub|sup|time|u|tt|var)$/i;
@@ -15400,7 +15547,7 @@ class MouseDown {
15400
15547
  }
15401
15548
  const target = flushed ? null : event.target;
15402
15549
  const targetDesc = target ? view.docView.nearestDesc(target, true) : null;
15403
- this.target = targetDesc && targetDesc.dom.nodeType == 1 ? targetDesc.dom : null;
15550
+ this.target = targetDesc && targetDesc.nodeDOM.nodeType == 1 ? targetDesc.nodeDOM : null;
15404
15551
  let { selection } = view.state;
15405
15552
  if (event.button == 0 &&
15406
15553
  targetNode.type.spec.draggable && targetNode.type.spec.selectable !== false ||
@@ -15524,7 +15671,8 @@ editHandlers.compositionstart = editHandlers.compositionupdate = view => {
15524
15671
  let { state } = view, $pos = state.selection.$to;
15525
15672
  if (state.selection instanceof TextSelection &&
15526
15673
  (state.storedMarks ||
15527
- (!$pos.textOffset && $pos.parentOffset && $pos.nodeBefore.marks.some(m => m.type.spec.inclusive === false)))) {
15674
+ (!$pos.textOffset && $pos.parentOffset && $pos.nodeBefore.marks.some(m => m.type.spec.inclusive === false)) ||
15675
+ chrome && windows$1 && selectionBeforeUneditable(view))) { // Issue #1500
15528
15676
  // Need to wrap the cursor in mark nodes different from the ones in the DOM context
15529
15677
  view.markCursor = view.state.storedMarks || $pos.marks();
15530
15678
  endComposition(view, true);
@@ -15558,6 +15706,13 @@ editHandlers.compositionstart = editHandlers.compositionupdate = view => {
15558
15706
  }
15559
15707
  scheduleComposeEnd(view, timeoutComposition);
15560
15708
  };
15709
+ function selectionBeforeUneditable(view) {
15710
+ let { focusNode, focusOffset } = view.domSelectionRange();
15711
+ if (!focusNode || focusNode.nodeType != 1 || focusOffset >= focusNode.childNodes.length)
15712
+ return false;
15713
+ let next = focusNode.childNodes[focusOffset];
15714
+ return next.nodeType == 1 && next.contentEditable == "false";
15715
+ }
15561
15716
  editHandlers.compositionend = (view, event) => {
15562
15717
  if (view.composing) {
15563
15718
  view.input.composing = false;
@@ -15785,10 +15940,15 @@ handlers.dragend = view => {
15785
15940
  }, 50);
15786
15941
  };
15787
15942
  editHandlers.dragover = editHandlers.dragenter = (_, e) => e.preventDefault();
15788
- editHandlers.drop = (view, _event) => {
15789
- let event = _event;
15790
- let dragging = view.dragging;
15791
- view.dragging = null;
15943
+ editHandlers.drop = (view, event) => {
15944
+ try {
15945
+ handleDrop(view, event, view.dragging);
15946
+ }
15947
+ finally {
15948
+ view.dragging = null;
15949
+ }
15950
+ };
15951
+ function handleDrop(view, event, dragging) {
15792
15952
  if (!event.dataTransfer)
15793
15953
  return;
15794
15954
  let eventPos = view.posAtCoords(eventCoords(event));
@@ -15797,7 +15957,7 @@ editHandlers.drop = (view, _event) => {
15797
15957
  let $mouse = view.state.doc.resolve(eventPos.pos);
15798
15958
  let slice = dragging && dragging.slice;
15799
15959
  if (slice) {
15800
- view.someProp("transformPasted", f => { slice = f(slice, view); });
15960
+ view.someProp("transformPasted", f => { slice = f(slice, view, false); });
15801
15961
  }
15802
15962
  else {
15803
15963
  slice = parseFromClipboard(view, getText$1(event.dataTransfer), brokenClipboardAPI ? null : event.dataTransfer.getData("text/html"), false, $mouse);
@@ -15842,7 +16002,7 @@ editHandlers.drop = (view, _event) => {
15842
16002
  }
15843
16003
  view.focus();
15844
16004
  view.dispatch(tr.setMeta("uiEvent", "drop"));
15845
- };
16005
+ }
15846
16006
  handlers.focus = view => {
15847
16007
  view.input.lastFocus = Date.now();
15848
16008
  if (!view.focused) {
@@ -16768,6 +16928,17 @@ class DOMObserver {
16768
16928
  }
16769
16929
  }
16770
16930
  }
16931
+ else if ((chrome || safari) && added.some(n => n.nodeName == "BR") &&
16932
+ (view.input.lastKeyCode == 8 || view.input.lastKeyCode == 46)) {
16933
+ // Chrome/Safari sometimes insert a bogus break node if you
16934
+ // backspace out the last bit of text before an inline-flex node (#1552)
16935
+ for (let node of added)
16936
+ if (node.nodeName == "BR" && node.parentNode) {
16937
+ let after = node.nextSibling;
16938
+ if (after && after.nodeType == 1 && after.contentEditable == "false")
16939
+ node.parentNode.removeChild(node);
16940
+ }
16941
+ }
16771
16942
  let readSel = null;
16772
16943
  // If it looks like the browser has reset the selection to the
16773
16944
  // start of the document after focus, restore the selection from
@@ -17082,16 +17253,13 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
17082
17253
  let $to = parse.doc.resolveNoCache(change.endB - parse.from);
17083
17254
  let $fromA = doc.resolve(change.start);
17084
17255
  let inlineChange = $from.sameParent($to) && $from.parent.inlineContent && $fromA.end() >= change.endA;
17085
- let nextSel;
17086
17256
  // If this looks like the effect of pressing Enter (or was recorded
17087
17257
  // as being an iOS enter press), just dispatch an Enter key instead.
17088
17258
  if (((ios && view.input.lastIOSEnter > Date.now() - 225 &&
17089
17259
  (!inlineChange || addedNodes.some(n => n.nodeName == "DIV" || n.nodeName == "P"))) ||
17090
17260
  (!inlineChange && $from.pos < parse.doc.content.size &&
17091
17261
  (!$from.sameParent($to) || !$from.parent.inlineContent) &&
17092
- !/\S/.test(parse.doc.textBetween($from.pos, $to.pos, "", "")) &&
17093
- (nextSel = Selection.findFrom(parse.doc.resolve($from.pos + 1), 1, true)) &&
17094
- nextSel.head > $from.pos)) &&
17262
+ $from.pos < $to.pos && !/\S/.test(parse.doc.textBetween($from.pos, $to.pos, "", "")))) &&
17095
17263
  view.someProp("handleKeyDown", f => f(view, keyEvent(13, "Enter")))) {
17096
17264
  view.input.lastIOSEnter = 0;
17097
17265
  return;
@@ -17177,6 +17345,9 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
17177
17345
  if (!view.someProp("handleTextInput", f => f(view, chFrom, chTo, text, deflt)))
17178
17346
  view.dispatch(deflt());
17179
17347
  }
17348
+ else {
17349
+ view.dispatch(mkTr());
17350
+ }
17180
17351
  }
17181
17352
  else {
17182
17353
  view.dispatch(mkTr());
@@ -28554,6 +28725,9 @@ class GapBookmark {
28554
28725
  return GapCursor.valid($pos) ? new GapCursor($pos) : Selection.near($pos);
28555
28726
  }
28556
28727
  }
28728
+ function needsGap(type) {
28729
+ return type.isAtom || type.spec.isolating || type.spec.createGapCursor;
28730
+ }
28557
28731
  function closedBefore($pos) {
28558
28732
  for (let d = $pos.depth; d >= 0; d--) {
28559
28733
  let index = $pos.index(d), parent = $pos.node(d);
@@ -28565,7 +28739,7 @@ function closedBefore($pos) {
28565
28739
  }
28566
28740
  // See if the node before (or its first ancestor) is closed
28567
28741
  for (let before = parent.child(index - 1);; before = before.lastChild) {
28568
- if ((before.childCount == 0 && !before.inlineContent) || before.isAtom || before.type.spec.isolating)
28742
+ if ((before.childCount == 0 && !before.inlineContent) || needsGap(before.type))
28569
28743
  return true;
28570
28744
  if (before.inlineContent)
28571
28745
  return false;
@@ -28583,7 +28757,7 @@ function closedAfter($pos) {
28583
28757
  continue;
28584
28758
  }
28585
28759
  for (let after = parent.child(index);; after = after.firstChild) {
28586
- if ((after.childCount == 0 && !after.inlineContent) || after.isAtom || after.type.spec.isolating)
28760
+ if ((after.childCount == 0 && !after.inlineContent) || needsGap(after.type))
28587
28761
  return true;
28588
28762
  if (after.inlineContent)
28589
28763
  return false;
@@ -29262,7 +29436,7 @@ function history(config = {}) {
29262
29436
  beforeinput(view, e) {
29263
29437
  let inputType = e.inputType;
29264
29438
  let command = inputType == "historyUndo" ? undo : inputType == "historyRedo" ? redo : null;
29265
- if (!command)
29439
+ if (!command || !view.editable)
29266
29440
  return false;
29267
29441
  e.preventDefault();
29268
29442
  return command(view.state, view.dispatch);
@@ -29871,2156 +30045,2003 @@ var Image$2 = Node3.create({
29871
30045
  }
29872
30046
  });
29873
30047
 
29874
- // src/index.ts
29875
-
29876
- // src/tablemap.ts
29877
- var readFromCache;
29878
- var addToCache;
30048
+ //#region src/tablemap.ts
30049
+ let readFromCache;
30050
+ let addToCache;
29879
30051
  if (typeof WeakMap != "undefined") {
29880
- let cache = /* @__PURE__ */ new WeakMap();
29881
- readFromCache = (key) => cache.get(key);
29882
- addToCache = (key, value) => {
29883
- cache.set(key, value);
29884
- return value;
29885
- };
30052
+ let cache = /* @__PURE__ */ new WeakMap();
30053
+ readFromCache = (key) => cache.get(key);
30054
+ addToCache = (key, value) => {
30055
+ cache.set(key, value);
30056
+ return value;
30057
+ };
29886
30058
  } else {
29887
- const cache = [];
29888
- const cacheSize = 10;
29889
- let cachePos = 0;
29890
- readFromCache = (key) => {
29891
- for (let i = 0; i < cache.length; i += 2)
29892
- if (cache[i] == key) return cache[i + 1];
29893
- };
29894
- addToCache = (key, value) => {
29895
- if (cachePos == cacheSize) cachePos = 0;
29896
- cache[cachePos++] = key;
29897
- return cache[cachePos++] = value;
29898
- };
30059
+ const cache = [];
30060
+ const cacheSize = 10;
30061
+ let cachePos = 0;
30062
+ readFromCache = (key) => {
30063
+ for (let i = 0; i < cache.length; i += 2) if (cache[i] == key) return cache[i + 1];
30064
+ };
30065
+ addToCache = (key, value) => {
30066
+ if (cachePos == cacheSize) cachePos = 0;
30067
+ cache[cachePos++] = key;
30068
+ return cache[cachePos++] = value;
30069
+ };
29899
30070
  }
30071
+ /**
30072
+ * A table map describes the structure of a given table. To avoid
30073
+ * recomputing them all the time, they are cached per table node. To
30074
+ * be able to do that, positions saved in the map are relative to the
30075
+ * start of the table, rather than the start of the document.
30076
+ *
30077
+ * @public
30078
+ */
29900
30079
  var TableMap = class {
29901
- constructor(width, height, map, problems) {
29902
- this.width = width;
29903
- this.height = height;
29904
- this.map = map;
29905
- this.problems = problems;
29906
- }
29907
- // Find the dimensions of the cell at the given position.
29908
- findCell(pos) {
29909
- for (let i = 0; i < this.map.length; i++) {
29910
- const curPos = this.map[i];
29911
- if (curPos != pos) continue;
29912
- const left = i % this.width;
29913
- const top = i / this.width | 0;
29914
- let right = left + 1;
29915
- let bottom = top + 1;
29916
- for (let j = 1; right < this.width && this.map[i + j] == curPos; j++) {
29917
- right++;
29918
- }
29919
- for (let j = 1; bottom < this.height && this.map[i + this.width * j] == curPos; j++) {
29920
- bottom++;
29921
- }
29922
- return { left, top, right, bottom };
29923
- }
29924
- throw new RangeError(`No cell with offset ${pos} found`);
29925
- }
29926
- // Find the left side of the cell at the given position.
29927
- colCount(pos) {
29928
- for (let i = 0; i < this.map.length; i++) {
29929
- if (this.map[i] == pos) {
29930
- return i % this.width;
29931
- }
29932
- }
29933
- throw new RangeError(`No cell with offset ${pos} found`);
29934
- }
29935
- // Find the next cell in the given direction, starting from the cell
29936
- // at `pos`, if any.
29937
- nextCell(pos, axis, dir) {
29938
- const { left, right, top, bottom } = this.findCell(pos);
29939
- if (axis == "horiz") {
29940
- if (dir < 0 ? left == 0 : right == this.width) return null;
29941
- return this.map[top * this.width + (dir < 0 ? left - 1 : right)];
29942
- } else {
29943
- if (dir < 0 ? top == 0 : bottom == this.height) return null;
29944
- return this.map[left + this.width * (dir < 0 ? top - 1 : bottom)];
29945
- }
29946
- }
29947
- // Get the rectangle spanning the two given cells.
29948
- rectBetween(a, b) {
29949
- const {
29950
- left: leftA,
29951
- right: rightA,
29952
- top: topA,
29953
- bottom: bottomA
29954
- } = this.findCell(a);
29955
- const {
29956
- left: leftB,
29957
- right: rightB,
29958
- top: topB,
29959
- bottom: bottomB
29960
- } = this.findCell(b);
29961
- return {
29962
- left: Math.min(leftA, leftB),
29963
- top: Math.min(topA, topB),
29964
- right: Math.max(rightA, rightB),
29965
- bottom: Math.max(bottomA, bottomB)
29966
- };
29967
- }
29968
- // Return the position of all cells that have the top left corner in
29969
- // the given rectangle.
29970
- cellsInRect(rect) {
29971
- const result = [];
29972
- const seen = {};
29973
- for (let row = rect.top; row < rect.bottom; row++) {
29974
- for (let col = rect.left; col < rect.right; col++) {
29975
- const index = row * this.width + col;
29976
- const pos = this.map[index];
29977
- if (seen[pos]) continue;
29978
- seen[pos] = true;
29979
- if (col == rect.left && col && this.map[index - 1] == pos || row == rect.top && row && this.map[index - this.width] == pos) {
29980
- continue;
29981
- }
29982
- result.push(pos);
29983
- }
29984
- }
29985
- return result;
29986
- }
29987
- // Return the position at which the cell at the given row and column
29988
- // starts, or would start, if a cell started there.
29989
- positionAt(row, col, table) {
29990
- for (let i = 0, rowStart = 0; ; i++) {
29991
- const rowEnd = rowStart + table.child(i).nodeSize;
29992
- if (i == row) {
29993
- let index = col + row * this.width;
29994
- const rowEndIndex = (row + 1) * this.width;
29995
- while (index < rowEndIndex && this.map[index] < rowStart) index++;
29996
- return index == rowEndIndex ? rowEnd - 1 : this.map[index];
29997
- }
29998
- rowStart = rowEnd;
29999
- }
30000
- }
30001
- // Find the table map for the given table node.
30002
- static get(table) {
30003
- return readFromCache(table) || addToCache(table, computeMap(table));
30004
- }
30080
+ constructor(width, height, map, problems) {
30081
+ this.width = width;
30082
+ this.height = height;
30083
+ this.map = map;
30084
+ this.problems = problems;
30085
+ }
30086
+ findCell(pos) {
30087
+ for (let i = 0; i < this.map.length; i++) {
30088
+ const curPos = this.map[i];
30089
+ if (curPos != pos) continue;
30090
+ const left = i % this.width;
30091
+ const top = i / this.width | 0;
30092
+ let right = left + 1;
30093
+ let bottom = top + 1;
30094
+ for (let j = 1; right < this.width && this.map[i + j] == curPos; j++) right++;
30095
+ for (let j = 1; bottom < this.height && this.map[i + this.width * j] == curPos; j++) bottom++;
30096
+ return {
30097
+ left,
30098
+ top,
30099
+ right,
30100
+ bottom
30101
+ };
30102
+ }
30103
+ throw new RangeError(`No cell with offset ${pos} found`);
30104
+ }
30105
+ colCount(pos) {
30106
+ for (let i = 0; i < this.map.length; i++) if (this.map[i] == pos) return i % this.width;
30107
+ throw new RangeError(`No cell with offset ${pos} found`);
30108
+ }
30109
+ nextCell(pos, axis, dir) {
30110
+ const { left, right, top, bottom } = this.findCell(pos);
30111
+ if (axis == "horiz") {
30112
+ if (dir < 0 ? left == 0 : right == this.width) return null;
30113
+ return this.map[top * this.width + (dir < 0 ? left - 1 : right)];
30114
+ } else {
30115
+ if (dir < 0 ? top == 0 : bottom == this.height) return null;
30116
+ return this.map[left + this.width * (dir < 0 ? top - 1 : bottom)];
30117
+ }
30118
+ }
30119
+ rectBetween(a, b) {
30120
+ const { left: leftA, right: rightA, top: topA, bottom: bottomA } = this.findCell(a);
30121
+ const { left: leftB, right: rightB, top: topB, bottom: bottomB } = this.findCell(b);
30122
+ return {
30123
+ left: Math.min(leftA, leftB),
30124
+ top: Math.min(topA, topB),
30125
+ right: Math.max(rightA, rightB),
30126
+ bottom: Math.max(bottomA, bottomB)
30127
+ };
30128
+ }
30129
+ cellsInRect(rect) {
30130
+ const result = [];
30131
+ const seen = {};
30132
+ for (let row = rect.top; row < rect.bottom; row++) for (let col = rect.left; col < rect.right; col++) {
30133
+ const index = row * this.width + col;
30134
+ const pos = this.map[index];
30135
+ if (seen[pos]) continue;
30136
+ seen[pos] = true;
30137
+ if (col == rect.left && col && this.map[index - 1] == pos || row == rect.top && row && this.map[index - this.width] == pos) continue;
30138
+ result.push(pos);
30139
+ }
30140
+ return result;
30141
+ }
30142
+ positionAt(row, col, table) {
30143
+ for (let i = 0, rowStart = 0;; i++) {
30144
+ const rowEnd = rowStart + table.child(i).nodeSize;
30145
+ if (i == row) {
30146
+ let index = col + row * this.width;
30147
+ const rowEndIndex = (row + 1) * this.width;
30148
+ while (index < rowEndIndex && this.map[index] < rowStart) index++;
30149
+ return index == rowEndIndex ? rowEnd - 1 : this.map[index];
30150
+ }
30151
+ rowStart = rowEnd;
30152
+ }
30153
+ }
30154
+ static get(table) {
30155
+ return readFromCache(table) || addToCache(table, computeMap(table));
30156
+ }
30005
30157
  };
30006
30158
  function computeMap(table) {
30007
- if (table.type.spec.tableRole != "table")
30008
- throw new RangeError("Not a table node: " + table.type.name);
30009
- const width = findWidth(table), height = table.childCount;
30010
- const map = [];
30011
- let mapPos = 0;
30012
- let problems = null;
30013
- const colWidths = [];
30014
- for (let i = 0, e = width * height; i < e; i++) map[i] = 0;
30015
- for (let row = 0, pos = 0; row < height; row++) {
30016
- const rowNode = table.child(row);
30017
- pos++;
30018
- for (let i = 0; ; i++) {
30019
- while (mapPos < map.length && map[mapPos] != 0) mapPos++;
30020
- if (i == rowNode.childCount) break;
30021
- const cellNode = rowNode.child(i);
30022
- const { colspan, rowspan, colwidth } = cellNode.attrs;
30023
- for (let h = 0; h < rowspan; h++) {
30024
- if (h + row >= height) {
30025
- (problems || (problems = [])).push({
30026
- type: "overlong_rowspan",
30027
- pos,
30028
- n: rowspan - h
30029
- });
30030
- break;
30031
- }
30032
- const start = mapPos + h * width;
30033
- for (let w = 0; w < colspan; w++) {
30034
- if (map[start + w] == 0) map[start + w] = pos;
30035
- else
30036
- (problems || (problems = [])).push({
30037
- type: "collision",
30038
- row,
30039
- pos,
30040
- n: colspan - w
30041
- });
30042
- const colW = colwidth && colwidth[w];
30043
- if (colW) {
30044
- const widthIndex = (start + w) % width * 2, prev = colWidths[widthIndex];
30045
- if (prev == null || prev != colW && colWidths[widthIndex + 1] == 1) {
30046
- colWidths[widthIndex] = colW;
30047
- colWidths[widthIndex + 1] = 1;
30048
- } else if (prev == colW) {
30049
- colWidths[widthIndex + 1]++;
30050
- }
30051
- }
30052
- }
30053
- }
30054
- mapPos += colspan;
30055
- pos += cellNode.nodeSize;
30056
- }
30057
- const expectedPos = (row + 1) * width;
30058
- let missing = 0;
30059
- while (mapPos < expectedPos) if (map[mapPos++] == 0) missing++;
30060
- if (missing)
30061
- (problems || (problems = [])).push({ type: "missing", row, n: missing });
30062
- pos++;
30063
- }
30064
- if (width === 0 || height === 0)
30065
- (problems || (problems = [])).push({ type: "zero_sized" });
30066
- const tableMap = new TableMap(width, height, map, problems);
30067
- let badWidths = false;
30068
- for (let i = 0; !badWidths && i < colWidths.length; i += 2)
30069
- if (colWidths[i] != null && colWidths[i + 1] < height) badWidths = true;
30070
- if (badWidths) findBadColWidths(tableMap, colWidths, table);
30071
- return tableMap;
30159
+ if (table.type.spec.tableRole != "table") throw new RangeError("Not a table node: " + table.type.name);
30160
+ const width = findWidth(table), height = table.childCount;
30161
+ const map = [];
30162
+ let mapPos = 0;
30163
+ let problems = null;
30164
+ const colWidths = [];
30165
+ for (let i = 0, e = width * height; i < e; i++) map[i] = 0;
30166
+ for (let row = 0, pos = 0; row < height; row++) {
30167
+ const rowNode = table.child(row);
30168
+ pos++;
30169
+ for (let i = 0;; i++) {
30170
+ while (mapPos < map.length && map[mapPos] != 0) mapPos++;
30171
+ if (i == rowNode.childCount) break;
30172
+ const cellNode = rowNode.child(i);
30173
+ const { colspan, rowspan, colwidth } = cellNode.attrs;
30174
+ for (let h = 0; h < rowspan; h++) {
30175
+ if (h + row >= height) {
30176
+ (problems || (problems = [])).push({
30177
+ type: "overlong_rowspan",
30178
+ pos,
30179
+ n: rowspan - h
30180
+ });
30181
+ break;
30182
+ }
30183
+ const start = mapPos + h * width;
30184
+ for (let w = 0; w < colspan; w++) {
30185
+ if (map[start + w] == 0) map[start + w] = pos;
30186
+ else (problems || (problems = [])).push({
30187
+ type: "collision",
30188
+ row,
30189
+ pos,
30190
+ n: colspan - w
30191
+ });
30192
+ const colW = colwidth && colwidth[w];
30193
+ if (colW) {
30194
+ const widthIndex = (start + w) % width * 2, prev = colWidths[widthIndex];
30195
+ if (prev == null || prev != colW && colWidths[widthIndex + 1] == 1) {
30196
+ colWidths[widthIndex] = colW;
30197
+ colWidths[widthIndex + 1] = 1;
30198
+ } else if (prev == colW) colWidths[widthIndex + 1]++;
30199
+ }
30200
+ }
30201
+ }
30202
+ mapPos += colspan;
30203
+ pos += cellNode.nodeSize;
30204
+ }
30205
+ const expectedPos = (row + 1) * width;
30206
+ let missing = 0;
30207
+ while (mapPos < expectedPos) if (map[mapPos++] == 0) missing++;
30208
+ if (missing) (problems || (problems = [])).push({
30209
+ type: "missing",
30210
+ row,
30211
+ n: missing
30212
+ });
30213
+ pos++;
30214
+ }
30215
+ if (width === 0 || height === 0) (problems || (problems = [])).push({ type: "zero_sized" });
30216
+ const tableMap = new TableMap(width, height, map, problems);
30217
+ let badWidths = false;
30218
+ for (let i = 0; !badWidths && i < colWidths.length; i += 2) if (colWidths[i] != null && colWidths[i + 1] < height) badWidths = true;
30219
+ if (badWidths) findBadColWidths(tableMap, colWidths, table);
30220
+ return tableMap;
30072
30221
  }
30073
30222
  function findWidth(table) {
30074
- let width = -1;
30075
- let hasRowSpan = false;
30076
- for (let row = 0; row < table.childCount; row++) {
30077
- const rowNode = table.child(row);
30078
- let rowWidth = 0;
30079
- if (hasRowSpan)
30080
- for (let j = 0; j < row; j++) {
30081
- const prevRow = table.child(j);
30082
- for (let i = 0; i < prevRow.childCount; i++) {
30083
- const cell = prevRow.child(i);
30084
- if (j + cell.attrs.rowspan > row) rowWidth += cell.attrs.colspan;
30085
- }
30086
- }
30087
- for (let i = 0; i < rowNode.childCount; i++) {
30088
- const cell = rowNode.child(i);
30089
- rowWidth += cell.attrs.colspan;
30090
- if (cell.attrs.rowspan > 1) hasRowSpan = true;
30091
- }
30092
- if (width == -1) width = rowWidth;
30093
- else if (width != rowWidth) width = Math.max(width, rowWidth);
30094
- }
30095
- return width;
30223
+ let width = -1;
30224
+ let hasRowSpan = false;
30225
+ for (let row = 0; row < table.childCount; row++) {
30226
+ const rowNode = table.child(row);
30227
+ let rowWidth = 0;
30228
+ if (hasRowSpan) for (let j = 0; j < row; j++) {
30229
+ const prevRow = table.child(j);
30230
+ for (let i = 0; i < prevRow.childCount; i++) {
30231
+ const cell = prevRow.child(i);
30232
+ if (j + cell.attrs.rowspan > row) rowWidth += cell.attrs.colspan;
30233
+ }
30234
+ }
30235
+ for (let i = 0; i < rowNode.childCount; i++) {
30236
+ const cell = rowNode.child(i);
30237
+ rowWidth += cell.attrs.colspan;
30238
+ if (cell.attrs.rowspan > 1) hasRowSpan = true;
30239
+ }
30240
+ if (width == -1) width = rowWidth;
30241
+ else if (width != rowWidth) width = Math.max(width, rowWidth);
30242
+ }
30243
+ return width;
30096
30244
  }
30097
30245
  function findBadColWidths(map, colWidths, table) {
30098
- if (!map.problems) map.problems = [];
30099
- const seen = {};
30100
- for (let i = 0; i < map.map.length; i++) {
30101
- const pos = map.map[i];
30102
- if (seen[pos]) continue;
30103
- seen[pos] = true;
30104
- const node = table.nodeAt(pos);
30105
- if (!node) {
30106
- throw new RangeError(`No cell with offset ${pos} found`);
30107
- }
30108
- let updated = null;
30109
- const attrs = node.attrs;
30110
- for (let j = 0; j < attrs.colspan; j++) {
30111
- const col = (i + j) % map.width;
30112
- const colWidth = colWidths[col * 2];
30113
- if (colWidth != null && (!attrs.colwidth || attrs.colwidth[j] != colWidth))
30114
- (updated || (updated = freshColWidth(attrs)))[j] = colWidth;
30115
- }
30116
- if (updated)
30117
- map.problems.unshift({
30118
- type: "colwidth mismatch",
30119
- pos,
30120
- colwidth: updated
30121
- });
30122
- }
30246
+ if (!map.problems) map.problems = [];
30247
+ const seen = {};
30248
+ for (let i = 0; i < map.map.length; i++) {
30249
+ const pos = map.map[i];
30250
+ if (seen[pos]) continue;
30251
+ seen[pos] = true;
30252
+ const node = table.nodeAt(pos);
30253
+ if (!node) throw new RangeError(`No cell with offset ${pos} found`);
30254
+ let updated = null;
30255
+ const attrs = node.attrs;
30256
+ for (let j = 0; j < attrs.colspan; j++) {
30257
+ const colWidth = colWidths[(i + j) % map.width * 2];
30258
+ if (colWidth != null && (!attrs.colwidth || attrs.colwidth[j] != colWidth)) (updated || (updated = freshColWidth(attrs)))[j] = colWidth;
30259
+ }
30260
+ if (updated) map.problems.unshift({
30261
+ type: "colwidth mismatch",
30262
+ pos,
30263
+ colwidth: updated
30264
+ });
30265
+ }
30123
30266
  }
30124
30267
  function freshColWidth(attrs) {
30125
- if (attrs.colwidth) return attrs.colwidth.slice();
30126
- const result = [];
30127
- for (let i = 0; i < attrs.colspan; i++) result.push(0);
30128
- return result;
30268
+ if (attrs.colwidth) return attrs.colwidth.slice();
30269
+ const result = [];
30270
+ for (let i = 0; i < attrs.colspan; i++) result.push(0);
30271
+ return result;
30129
30272
  }
30273
+ /**
30274
+ * @public
30275
+ */
30130
30276
  function tableNodeTypes(schema) {
30131
- let result = schema.cached.tableNodeTypes;
30132
- if (!result) {
30133
- result = schema.cached.tableNodeTypes = {};
30134
- for (const name in schema.nodes) {
30135
- const type = schema.nodes[name], role = type.spec.tableRole;
30136
- if (role) result[role] = type;
30137
- }
30138
- }
30139
- return result;
30277
+ let result = schema.cached.tableNodeTypes;
30278
+ if (!result) {
30279
+ result = schema.cached.tableNodeTypes = {};
30280
+ for (const name in schema.nodes) {
30281
+ const type = schema.nodes[name], role = type.spec.tableRole;
30282
+ if (role) result[role] = type;
30283
+ }
30284
+ }
30285
+ return result;
30140
30286
  }
30141
30287
 
30142
- // src/util.ts
30143
- var tableEditingKey = new PluginKey("selectingCells");
30288
+ //#endregion
30289
+ //#region src/util.ts
30290
+ /**
30291
+ * @public
30292
+ */
30293
+ const tableEditingKey = new PluginKey("selectingCells");
30294
+ /**
30295
+ * @public
30296
+ */
30144
30297
  function cellAround($pos) {
30145
- for (let d = $pos.depth - 1; d > 0; d--)
30146
- if ($pos.node(d).type.spec.tableRole == "row")
30147
- return $pos.node(0).resolve($pos.before(d + 1));
30148
- return null;
30298
+ for (let d = $pos.depth - 1; d > 0; d--) if ($pos.node(d).type.spec.tableRole == "row") return $pos.node(0).resolve($pos.before(d + 1));
30299
+ return null;
30149
30300
  }
30150
30301
  function cellWrapping($pos) {
30151
- for (let d = $pos.depth; d > 0; d--) {
30152
- const role = $pos.node(d).type.spec.tableRole;
30153
- if (role === "cell" || role === "header_cell") return $pos.node(d);
30154
- }
30155
- return null;
30302
+ for (let d = $pos.depth; d > 0; d--) {
30303
+ const role = $pos.node(d).type.spec.tableRole;
30304
+ if (role === "cell" || role === "header_cell") return $pos.node(d);
30305
+ }
30306
+ return null;
30156
30307
  }
30308
+ /**
30309
+ * @public
30310
+ */
30157
30311
  function isInTable(state) {
30158
- const $head = state.selection.$head;
30159
- for (let d = $head.depth; d > 0; d--)
30160
- if ($head.node(d).type.spec.tableRole == "row") return true;
30161
- return false;
30312
+ const $head = state.selection.$head;
30313
+ for (let d = $head.depth; d > 0; d--) if ($head.node(d).type.spec.tableRole == "row") return true;
30314
+ return false;
30162
30315
  }
30316
+ /**
30317
+ * @internal
30318
+ */
30163
30319
  function selectionCell(state) {
30164
- const sel = state.selection;
30165
- if ("$anchorCell" in sel && sel.$anchorCell) {
30166
- return sel.$anchorCell.pos > sel.$headCell.pos ? sel.$anchorCell : sel.$headCell;
30167
- } else if ("node" in sel && sel.node && sel.node.type.spec.tableRole == "cell") {
30168
- return sel.$anchor;
30169
- }
30170
- const $cell = cellAround(sel.$head) || cellNear(sel.$head);
30171
- if ($cell) {
30172
- return $cell;
30173
- }
30174
- throw new RangeError(`No cell found around position ${sel.head}`);
30320
+ const sel = state.selection;
30321
+ if ("$anchorCell" in sel && sel.$anchorCell) return sel.$anchorCell.pos > sel.$headCell.pos ? sel.$anchorCell : sel.$headCell;
30322
+ else if ("node" in sel && sel.node && sel.node.type.spec.tableRole == "cell") return sel.$anchor;
30323
+ const $cell = cellAround(sel.$head) || cellNear(sel.$head);
30324
+ if ($cell) return $cell;
30325
+ throw new RangeError(`No cell found around position ${sel.head}`);
30175
30326
  }
30327
+ /**
30328
+ * @public
30329
+ */
30176
30330
  function cellNear($pos) {
30177
- for (let after = $pos.nodeAfter, pos = $pos.pos; after; after = after.firstChild, pos++) {
30178
- const role = after.type.spec.tableRole;
30179
- if (role == "cell" || role == "header_cell") return $pos.doc.resolve(pos);
30180
- }
30181
- for (let before = $pos.nodeBefore, pos = $pos.pos; before; before = before.lastChild, pos--) {
30182
- const role = before.type.spec.tableRole;
30183
- if (role == "cell" || role == "header_cell")
30184
- return $pos.doc.resolve(pos - before.nodeSize);
30185
- }
30331
+ for (let after = $pos.nodeAfter, pos = $pos.pos; after; after = after.firstChild, pos++) {
30332
+ const role = after.type.spec.tableRole;
30333
+ if (role == "cell" || role == "header_cell") return $pos.doc.resolve(pos);
30334
+ }
30335
+ for (let before = $pos.nodeBefore, pos = $pos.pos; before; before = before.lastChild, pos--) {
30336
+ const role = before.type.spec.tableRole;
30337
+ if (role == "cell" || role == "header_cell") return $pos.doc.resolve(pos - before.nodeSize);
30338
+ }
30186
30339
  }
30340
+ /**
30341
+ * @public
30342
+ */
30187
30343
  function pointsAtCell($pos) {
30188
- return $pos.parent.type.spec.tableRole == "row" && !!$pos.nodeAfter;
30344
+ return $pos.parent.type.spec.tableRole == "row" && !!$pos.nodeAfter;
30189
30345
  }
30346
+ /**
30347
+ * @public
30348
+ */
30190
30349
  function moveCellForward($pos) {
30191
- return $pos.node(0).resolve($pos.pos + $pos.nodeAfter.nodeSize);
30350
+ return $pos.node(0).resolve($pos.pos + $pos.nodeAfter.nodeSize);
30192
30351
  }
30352
+ /**
30353
+ * @internal
30354
+ */
30193
30355
  function inSameTable($cellA, $cellB) {
30194
- return $cellA.depth == $cellB.depth && $cellA.pos >= $cellB.start(-1) && $cellA.pos <= $cellB.end(-1);
30356
+ return $cellA.depth == $cellB.depth && $cellA.pos >= $cellB.start(-1) && $cellA.pos <= $cellB.end(-1);
30195
30357
  }
30358
+ /**
30359
+ * @public
30360
+ */
30196
30361
  function nextCell($pos, axis, dir) {
30197
- const table = $pos.node(-1);
30198
- const map = TableMap.get(table);
30199
- const tableStart = $pos.start(-1);
30200
- const moved = map.nextCell($pos.pos - tableStart, axis, dir);
30201
- return moved == null ? null : $pos.node(0).resolve(tableStart + moved);
30362
+ const table = $pos.node(-1);
30363
+ const map = TableMap.get(table);
30364
+ const tableStart = $pos.start(-1);
30365
+ const moved = map.nextCell($pos.pos - tableStart, axis, dir);
30366
+ return moved == null ? null : $pos.node(0).resolve(tableStart + moved);
30202
30367
  }
30368
+ /**
30369
+ * @public
30370
+ */
30203
30371
  function removeColSpan(attrs, pos, n = 1) {
30204
- const result = { ...attrs, colspan: attrs.colspan - n };
30205
- if (result.colwidth) {
30206
- result.colwidth = result.colwidth.slice();
30207
- result.colwidth.splice(pos, n);
30208
- if (!result.colwidth.some((w) => w > 0)) result.colwidth = null;
30209
- }
30210
- return result;
30372
+ const result = {
30373
+ ...attrs,
30374
+ colspan: attrs.colspan - n
30375
+ };
30376
+ if (result.colwidth) {
30377
+ result.colwidth = result.colwidth.slice();
30378
+ result.colwidth.splice(pos, n);
30379
+ if (!result.colwidth.some((w) => w > 0)) result.colwidth = null;
30380
+ }
30381
+ return result;
30211
30382
  }
30383
+ /**
30384
+ * @public
30385
+ */
30212
30386
  function addColSpan(attrs, pos, n = 1) {
30213
- const result = { ...attrs, colspan: attrs.colspan + n };
30214
- if (result.colwidth) {
30215
- result.colwidth = result.colwidth.slice();
30216
- for (let i = 0; i < n; i++) result.colwidth.splice(pos, 0, 0);
30217
- }
30218
- return result;
30387
+ const result = {
30388
+ ...attrs,
30389
+ colspan: attrs.colspan + n
30390
+ };
30391
+ if (result.colwidth) {
30392
+ result.colwidth = result.colwidth.slice();
30393
+ for (let i = 0; i < n; i++) result.colwidth.splice(pos, 0, 0);
30394
+ }
30395
+ return result;
30219
30396
  }
30397
+ /**
30398
+ * @public
30399
+ */
30220
30400
  function columnIsHeader(map, table, col) {
30221
- const headerCell = tableNodeTypes(table.type.schema).header_cell;
30222
- for (let row = 0; row < map.height; row++)
30223
- if (table.nodeAt(map.map[col + row * map.width]).type != headerCell)
30224
- return false;
30225
- return true;
30401
+ const headerCell = tableNodeTypes(table.type.schema).header_cell;
30402
+ for (let row = 0; row < map.height; row++) if (table.nodeAt(map.map[col + row * map.width]).type != headerCell) return false;
30403
+ return true;
30226
30404
  }
30227
30405
 
30228
- // src/cellselection.ts
30229
- var CellSelection = class _CellSelection extends Selection {
30230
- // A table selection is identified by its anchor and head cells. The
30231
- // positions given to this constructor should point _before_ two
30232
- // cells in the same table. They may be the same, to select a single
30233
- // cell.
30234
- constructor($anchorCell, $headCell = $anchorCell) {
30235
- const table = $anchorCell.node(-1);
30236
- const map = TableMap.get(table);
30237
- const tableStart = $anchorCell.start(-1);
30238
- const rect = map.rectBetween(
30239
- $anchorCell.pos - tableStart,
30240
- $headCell.pos - tableStart
30241
- );
30242
- const doc = $anchorCell.node(0);
30243
- const cells = map.cellsInRect(rect).filter((p) => p != $headCell.pos - tableStart);
30244
- cells.unshift($headCell.pos - tableStart);
30245
- const ranges = cells.map((pos) => {
30246
- const cell = table.nodeAt(pos);
30247
- if (!cell) {
30248
- throw RangeError(`No cell with offset ${pos} found`);
30249
- }
30250
- const from = tableStart + pos + 1;
30251
- return new SelectionRange(
30252
- doc.resolve(from),
30253
- doc.resolve(from + cell.content.size)
30254
- );
30255
- });
30256
- super(ranges[0].$from, ranges[0].$to, ranges);
30257
- this.$anchorCell = $anchorCell;
30258
- this.$headCell = $headCell;
30259
- }
30260
- map(doc, mapping) {
30261
- const $anchorCell = doc.resolve(mapping.map(this.$anchorCell.pos));
30262
- const $headCell = doc.resolve(mapping.map(this.$headCell.pos));
30263
- if (pointsAtCell($anchorCell) && pointsAtCell($headCell) && inSameTable($anchorCell, $headCell)) {
30264
- const tableChanged = this.$anchorCell.node(-1) != $anchorCell.node(-1);
30265
- if (tableChanged && this.isRowSelection())
30266
- return _CellSelection.rowSelection($anchorCell, $headCell);
30267
- else if (tableChanged && this.isColSelection())
30268
- return _CellSelection.colSelection($anchorCell, $headCell);
30269
- else return new _CellSelection($anchorCell, $headCell);
30270
- }
30271
- return TextSelection.between($anchorCell, $headCell);
30272
- }
30273
- // Returns a rectangular slice of table rows containing the selected
30274
- // cells.
30275
- content() {
30276
- const table = this.$anchorCell.node(-1);
30277
- const map = TableMap.get(table);
30278
- const tableStart = this.$anchorCell.start(-1);
30279
- const rect = map.rectBetween(
30280
- this.$anchorCell.pos - tableStart,
30281
- this.$headCell.pos - tableStart
30282
- );
30283
- const seen = {};
30284
- const rows = [];
30285
- for (let row = rect.top; row < rect.bottom; row++) {
30286
- const rowContent = [];
30287
- for (let index = row * map.width + rect.left, col = rect.left; col < rect.right; col++, index++) {
30288
- const pos = map.map[index];
30289
- if (seen[pos]) continue;
30290
- seen[pos] = true;
30291
- const cellRect = map.findCell(pos);
30292
- let cell = table.nodeAt(pos);
30293
- if (!cell) {
30294
- throw RangeError(`No cell with offset ${pos} found`);
30295
- }
30296
- const extraLeft = rect.left - cellRect.left;
30297
- const extraRight = cellRect.right - rect.right;
30298
- if (extraLeft > 0 || extraRight > 0) {
30299
- let attrs = cell.attrs;
30300
- if (extraLeft > 0) {
30301
- attrs = removeColSpan(attrs, 0, extraLeft);
30302
- }
30303
- if (extraRight > 0) {
30304
- attrs = removeColSpan(
30305
- attrs,
30306
- attrs.colspan - extraRight,
30307
- extraRight
30308
- );
30309
- }
30310
- if (cellRect.left < rect.left) {
30311
- cell = cell.type.createAndFill(attrs);
30312
- if (!cell) {
30313
- throw RangeError(
30314
- `Could not create cell with attrs ${JSON.stringify(attrs)}`
30315
- );
30316
- }
30317
- } else {
30318
- cell = cell.type.create(attrs, cell.content);
30319
- }
30320
- }
30321
- if (cellRect.top < rect.top || cellRect.bottom > rect.bottom) {
30322
- const attrs = {
30323
- ...cell.attrs,
30324
- rowspan: Math.min(cellRect.bottom, rect.bottom) - Math.max(cellRect.top, rect.top)
30325
- };
30326
- if (cellRect.top < rect.top) {
30327
- cell = cell.type.createAndFill(attrs);
30328
- } else {
30329
- cell = cell.type.create(attrs, cell.content);
30330
- }
30331
- }
30332
- rowContent.push(cell);
30333
- }
30334
- rows.push(table.child(row).copy(Fragment.from(rowContent)));
30335
- }
30336
- const fragment = this.isColSelection() && this.isRowSelection() ? table : rows;
30337
- return new Slice(Fragment.from(fragment), 1, 1);
30338
- }
30339
- replace(tr, content = Slice.empty) {
30340
- const mapFrom = tr.steps.length, ranges = this.ranges;
30341
- for (let i = 0; i < ranges.length; i++) {
30342
- const { $from, $to } = ranges[i], mapping = tr.mapping.slice(mapFrom);
30343
- tr.replace(
30344
- mapping.map($from.pos),
30345
- mapping.map($to.pos),
30346
- i ? Slice.empty : content
30347
- );
30348
- }
30349
- const sel = Selection.findFrom(
30350
- tr.doc.resolve(tr.mapping.slice(mapFrom).map(this.to)),
30351
- -1
30352
- );
30353
- if (sel) tr.setSelection(sel);
30354
- }
30355
- replaceWith(tr, node) {
30356
- this.replace(tr, new Slice(Fragment.from(node), 0, 0));
30357
- }
30358
- forEachCell(f) {
30359
- const table = this.$anchorCell.node(-1);
30360
- const map = TableMap.get(table);
30361
- const tableStart = this.$anchorCell.start(-1);
30362
- const cells = map.cellsInRect(
30363
- map.rectBetween(
30364
- this.$anchorCell.pos - tableStart,
30365
- this.$headCell.pos - tableStart
30366
- )
30367
- );
30368
- for (let i = 0; i < cells.length; i++) {
30369
- f(table.nodeAt(cells[i]), tableStart + cells[i]);
30370
- }
30371
- }
30372
- // True if this selection goes all the way from the top to the
30373
- // bottom of the table.
30374
- isColSelection() {
30375
- const anchorTop = this.$anchorCell.index(-1);
30376
- const headTop = this.$headCell.index(-1);
30377
- if (Math.min(anchorTop, headTop) > 0) return false;
30378
- const anchorBottom = anchorTop + this.$anchorCell.nodeAfter.attrs.rowspan;
30379
- const headBottom = headTop + this.$headCell.nodeAfter.attrs.rowspan;
30380
- return Math.max(anchorBottom, headBottom) == this.$headCell.node(-1).childCount;
30381
- }
30382
- // Returns the smallest column selection that covers the given anchor
30383
- // and head cell.
30384
- static colSelection($anchorCell, $headCell = $anchorCell) {
30385
- const table = $anchorCell.node(-1);
30386
- const map = TableMap.get(table);
30387
- const tableStart = $anchorCell.start(-1);
30388
- const anchorRect = map.findCell($anchorCell.pos - tableStart);
30389
- const headRect = map.findCell($headCell.pos - tableStart);
30390
- const doc = $anchorCell.node(0);
30391
- if (anchorRect.top <= headRect.top) {
30392
- if (anchorRect.top > 0)
30393
- $anchorCell = doc.resolve(tableStart + map.map[anchorRect.left]);
30394
- if (headRect.bottom < map.height)
30395
- $headCell = doc.resolve(
30396
- tableStart + map.map[map.width * (map.height - 1) + headRect.right - 1]
30397
- );
30398
- } else {
30399
- if (headRect.top > 0)
30400
- $headCell = doc.resolve(tableStart + map.map[headRect.left]);
30401
- if (anchorRect.bottom < map.height)
30402
- $anchorCell = doc.resolve(
30403
- tableStart + map.map[map.width * (map.height - 1) + anchorRect.right - 1]
30404
- );
30405
- }
30406
- return new _CellSelection($anchorCell, $headCell);
30407
- }
30408
- // True if this selection goes all the way from the left to the
30409
- // right of the table.
30410
- isRowSelection() {
30411
- const table = this.$anchorCell.node(-1);
30412
- const map = TableMap.get(table);
30413
- const tableStart = this.$anchorCell.start(-1);
30414
- const anchorLeft = map.colCount(this.$anchorCell.pos - tableStart);
30415
- const headLeft = map.colCount(this.$headCell.pos - tableStart);
30416
- if (Math.min(anchorLeft, headLeft) > 0) return false;
30417
- const anchorRight = anchorLeft + this.$anchorCell.nodeAfter.attrs.colspan;
30418
- const headRight = headLeft + this.$headCell.nodeAfter.attrs.colspan;
30419
- return Math.max(anchorRight, headRight) == map.width;
30420
- }
30421
- eq(other) {
30422
- return other instanceof _CellSelection && other.$anchorCell.pos == this.$anchorCell.pos && other.$headCell.pos == this.$headCell.pos;
30423
- }
30424
- // Returns the smallest row selection that covers the given anchor
30425
- // and head cell.
30426
- static rowSelection($anchorCell, $headCell = $anchorCell) {
30427
- const table = $anchorCell.node(-1);
30428
- const map = TableMap.get(table);
30429
- const tableStart = $anchorCell.start(-1);
30430
- const anchorRect = map.findCell($anchorCell.pos - tableStart);
30431
- const headRect = map.findCell($headCell.pos - tableStart);
30432
- const doc = $anchorCell.node(0);
30433
- if (anchorRect.left <= headRect.left) {
30434
- if (anchorRect.left > 0)
30435
- $anchorCell = doc.resolve(
30436
- tableStart + map.map[anchorRect.top * map.width]
30437
- );
30438
- if (headRect.right < map.width)
30439
- $headCell = doc.resolve(
30440
- tableStart + map.map[map.width * (headRect.top + 1) - 1]
30441
- );
30442
- } else {
30443
- if (headRect.left > 0)
30444
- $headCell = doc.resolve(tableStart + map.map[headRect.top * map.width]);
30445
- if (anchorRect.right < map.width)
30446
- $anchorCell = doc.resolve(
30447
- tableStart + map.map[map.width * (anchorRect.top + 1) - 1]
30448
- );
30449
- }
30450
- return new _CellSelection($anchorCell, $headCell);
30451
- }
30452
- toJSON() {
30453
- return {
30454
- type: "cell",
30455
- anchor: this.$anchorCell.pos,
30456
- head: this.$headCell.pos
30457
- };
30458
- }
30459
- static fromJSON(doc, json) {
30460
- return new _CellSelection(doc.resolve(json.anchor), doc.resolve(json.head));
30461
- }
30462
- static create(doc, anchorCell, headCell = anchorCell) {
30463
- return new _CellSelection(doc.resolve(anchorCell), doc.resolve(headCell));
30464
- }
30465
- getBookmark() {
30466
- return new CellBookmark(this.$anchorCell.pos, this.$headCell.pos);
30467
- }
30406
+ //#endregion
30407
+ //#region src/cellselection.ts
30408
+ /**
30409
+ * A [`Selection`](http://prosemirror.net/docs/ref/#state.Selection)
30410
+ * subclass that represents a cell selection spanning part of a table.
30411
+ * With the plugin enabled, these will be created when the user
30412
+ * selects across cells, and will be drawn by giving selected cells a
30413
+ * `selectedCell` CSS class.
30414
+ *
30415
+ * @public
30416
+ */
30417
+ var CellSelection = class CellSelection extends Selection {
30418
+ constructor($anchorCell, $headCell = $anchorCell) {
30419
+ const table = $anchorCell.node(-1);
30420
+ const map = TableMap.get(table);
30421
+ const tableStart = $anchorCell.start(-1);
30422
+ const rect = map.rectBetween($anchorCell.pos - tableStart, $headCell.pos - tableStart);
30423
+ const doc = $anchorCell.node(0);
30424
+ const cells = map.cellsInRect(rect).filter((p) => p != $headCell.pos - tableStart);
30425
+ cells.unshift($headCell.pos - tableStart);
30426
+ const ranges = cells.map((pos) => {
30427
+ const cell = table.nodeAt(pos);
30428
+ if (!cell) throw new RangeError(`No cell with offset ${pos} found`);
30429
+ const from = tableStart + pos + 1;
30430
+ return new SelectionRange(doc.resolve(from), doc.resolve(from + cell.content.size));
30431
+ });
30432
+ super(ranges[0].$from, ranges[0].$to, ranges);
30433
+ this.$anchorCell = $anchorCell;
30434
+ this.$headCell = $headCell;
30435
+ }
30436
+ map(doc, mapping) {
30437
+ const $anchorCell = doc.resolve(mapping.map(this.$anchorCell.pos));
30438
+ const $headCell = doc.resolve(mapping.map(this.$headCell.pos));
30439
+ if (pointsAtCell($anchorCell) && pointsAtCell($headCell) && inSameTable($anchorCell, $headCell)) {
30440
+ const tableChanged = this.$anchorCell.node(-1) != $anchorCell.node(-1);
30441
+ if (tableChanged && this.isRowSelection()) return CellSelection.rowSelection($anchorCell, $headCell);
30442
+ else if (tableChanged && this.isColSelection()) return CellSelection.colSelection($anchorCell, $headCell);
30443
+ else return new CellSelection($anchorCell, $headCell);
30444
+ }
30445
+ return TextSelection.between($anchorCell, $headCell);
30446
+ }
30447
+ content() {
30448
+ const table = this.$anchorCell.node(-1);
30449
+ const map = TableMap.get(table);
30450
+ const tableStart = this.$anchorCell.start(-1);
30451
+ const rect = map.rectBetween(this.$anchorCell.pos - tableStart, this.$headCell.pos - tableStart);
30452
+ const seen = {};
30453
+ const rows = [];
30454
+ for (let row = rect.top; row < rect.bottom; row++) {
30455
+ const rowContent = [];
30456
+ for (let index = row * map.width + rect.left, col = rect.left; col < rect.right; col++, index++) {
30457
+ const pos = map.map[index];
30458
+ if (seen[pos]) continue;
30459
+ seen[pos] = true;
30460
+ const cellRect = map.findCell(pos);
30461
+ let cell = table.nodeAt(pos);
30462
+ if (!cell) throw new RangeError(`No cell with offset ${pos} found`);
30463
+ const extraLeft = rect.left - cellRect.left;
30464
+ const extraRight = cellRect.right - rect.right;
30465
+ if (extraLeft > 0 || extraRight > 0) {
30466
+ let attrs = cell.attrs;
30467
+ if (extraLeft > 0) attrs = removeColSpan(attrs, 0, extraLeft);
30468
+ if (extraRight > 0) attrs = removeColSpan(attrs, attrs.colspan - extraRight, extraRight);
30469
+ if (cellRect.left < rect.left) {
30470
+ cell = cell.type.createAndFill(attrs);
30471
+ if (!cell) throw new RangeError(`Could not create cell with attrs ${JSON.stringify(attrs)}`);
30472
+ } else cell = cell.type.create(attrs, cell.content);
30473
+ }
30474
+ if (cellRect.top < rect.top || cellRect.bottom > rect.bottom) {
30475
+ const attrs = {
30476
+ ...cell.attrs,
30477
+ rowspan: Math.min(cellRect.bottom, rect.bottom) - Math.max(cellRect.top, rect.top)
30478
+ };
30479
+ if (cellRect.top < rect.top) cell = cell.type.createAndFill(attrs);
30480
+ else cell = cell.type.create(attrs, cell.content);
30481
+ }
30482
+ rowContent.push(cell);
30483
+ }
30484
+ rows.push(table.child(row).copy(Fragment.from(rowContent)));
30485
+ }
30486
+ const fragment = this.isColSelection() && this.isRowSelection() ? table : rows;
30487
+ return new Slice(Fragment.from(fragment), 1, 1);
30488
+ }
30489
+ replace(tr, content = Slice.empty) {
30490
+ const mapFrom = tr.steps.length, ranges = this.ranges;
30491
+ for (let i = 0; i < ranges.length; i++) {
30492
+ const { $from, $to } = ranges[i], mapping = tr.mapping.slice(mapFrom);
30493
+ tr.replace(mapping.map($from.pos), mapping.map($to.pos), i ? Slice.empty : content);
30494
+ }
30495
+ const sel = Selection.findFrom(tr.doc.resolve(tr.mapping.slice(mapFrom).map(this.to)), -1);
30496
+ if (sel) tr.setSelection(sel);
30497
+ }
30498
+ replaceWith(tr, node) {
30499
+ this.replace(tr, new Slice(Fragment.from(node), 0, 0));
30500
+ }
30501
+ forEachCell(f) {
30502
+ const table = this.$anchorCell.node(-1);
30503
+ const map = TableMap.get(table);
30504
+ const tableStart = this.$anchorCell.start(-1);
30505
+ const cells = map.cellsInRect(map.rectBetween(this.$anchorCell.pos - tableStart, this.$headCell.pos - tableStart));
30506
+ for (let i = 0; i < cells.length; i++) f(table.nodeAt(cells[i]), tableStart + cells[i]);
30507
+ }
30508
+ isColSelection() {
30509
+ const anchorTop = this.$anchorCell.index(-1);
30510
+ const headTop = this.$headCell.index(-1);
30511
+ if (Math.min(anchorTop, headTop) > 0) return false;
30512
+ const anchorBottom = anchorTop + this.$anchorCell.nodeAfter.attrs.rowspan;
30513
+ const headBottom = headTop + this.$headCell.nodeAfter.attrs.rowspan;
30514
+ return Math.max(anchorBottom, headBottom) == this.$headCell.node(-1).childCount;
30515
+ }
30516
+ static colSelection($anchorCell, $headCell = $anchorCell) {
30517
+ const table = $anchorCell.node(-1);
30518
+ const map = TableMap.get(table);
30519
+ const tableStart = $anchorCell.start(-1);
30520
+ const anchorRect = map.findCell($anchorCell.pos - tableStart);
30521
+ const headRect = map.findCell($headCell.pos - tableStart);
30522
+ const doc = $anchorCell.node(0);
30523
+ if (anchorRect.top <= headRect.top) {
30524
+ if (anchorRect.top > 0) $anchorCell = doc.resolve(tableStart + map.map[anchorRect.left]);
30525
+ if (headRect.bottom < map.height) $headCell = doc.resolve(tableStart + map.map[map.width * (map.height - 1) + headRect.right - 1]);
30526
+ } else {
30527
+ if (headRect.top > 0) $headCell = doc.resolve(tableStart + map.map[headRect.left]);
30528
+ if (anchorRect.bottom < map.height) $anchorCell = doc.resolve(tableStart + map.map[map.width * (map.height - 1) + anchorRect.right - 1]);
30529
+ }
30530
+ return new CellSelection($anchorCell, $headCell);
30531
+ }
30532
+ isRowSelection() {
30533
+ const table = this.$anchorCell.node(-1);
30534
+ const map = TableMap.get(table);
30535
+ const tableStart = this.$anchorCell.start(-1);
30536
+ const anchorLeft = map.colCount(this.$anchorCell.pos - tableStart);
30537
+ const headLeft = map.colCount(this.$headCell.pos - tableStart);
30538
+ if (Math.min(anchorLeft, headLeft) > 0) return false;
30539
+ const anchorRight = anchorLeft + this.$anchorCell.nodeAfter.attrs.colspan;
30540
+ const headRight = headLeft + this.$headCell.nodeAfter.attrs.colspan;
30541
+ return Math.max(anchorRight, headRight) == map.width;
30542
+ }
30543
+ eq(other) {
30544
+ return other instanceof CellSelection && other.$anchorCell.pos == this.$anchorCell.pos && other.$headCell.pos == this.$headCell.pos;
30545
+ }
30546
+ static rowSelection($anchorCell, $headCell = $anchorCell) {
30547
+ const table = $anchorCell.node(-1);
30548
+ const map = TableMap.get(table);
30549
+ const tableStart = $anchorCell.start(-1);
30550
+ const anchorRect = map.findCell($anchorCell.pos - tableStart);
30551
+ const headRect = map.findCell($headCell.pos - tableStart);
30552
+ const doc = $anchorCell.node(0);
30553
+ if (anchorRect.left <= headRect.left) {
30554
+ if (anchorRect.left > 0) $anchorCell = doc.resolve(tableStart + map.map[anchorRect.top * map.width]);
30555
+ if (headRect.right < map.width) $headCell = doc.resolve(tableStart + map.map[map.width * (headRect.top + 1) - 1]);
30556
+ } else {
30557
+ if (headRect.left > 0) $headCell = doc.resolve(tableStart + map.map[headRect.top * map.width]);
30558
+ if (anchorRect.right < map.width) $anchorCell = doc.resolve(tableStart + map.map[map.width * (anchorRect.top + 1) - 1]);
30559
+ }
30560
+ return new CellSelection($anchorCell, $headCell);
30561
+ }
30562
+ toJSON() {
30563
+ return {
30564
+ type: "cell",
30565
+ anchor: this.$anchorCell.pos,
30566
+ head: this.$headCell.pos
30567
+ };
30568
+ }
30569
+ static fromJSON(doc, json) {
30570
+ return new CellSelection(doc.resolve(json.anchor), doc.resolve(json.head));
30571
+ }
30572
+ static create(doc, anchorCell, headCell = anchorCell) {
30573
+ return new CellSelection(doc.resolve(anchorCell), doc.resolve(headCell));
30574
+ }
30575
+ getBookmark() {
30576
+ return new CellBookmark(this.$anchorCell.pos, this.$headCell.pos);
30577
+ }
30468
30578
  };
30469
30579
  CellSelection.prototype.visible = false;
30470
30580
  Selection.jsonID("cell", CellSelection);
30471
- var CellBookmark = class _CellBookmark {
30472
- constructor(anchor, head) {
30473
- this.anchor = anchor;
30474
- this.head = head;
30475
- }
30476
- map(mapping) {
30477
- return new _CellBookmark(mapping.map(this.anchor), mapping.map(this.head));
30478
- }
30479
- resolve(doc) {
30480
- const $anchorCell = doc.resolve(this.anchor), $headCell = doc.resolve(this.head);
30481
- 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))
30482
- return new CellSelection($anchorCell, $headCell);
30483
- else return Selection.near($headCell, 1);
30484
- }
30581
+ /**
30582
+ * @public
30583
+ */
30584
+ var CellBookmark = class CellBookmark {
30585
+ constructor(anchor, head) {
30586
+ this.anchor = anchor;
30587
+ this.head = head;
30588
+ }
30589
+ map(mapping) {
30590
+ return new CellBookmark(mapping.map(this.anchor), mapping.map(this.head));
30591
+ }
30592
+ resolve(doc) {
30593
+ const $anchorCell = doc.resolve(this.anchor), $headCell = doc.resolve(this.head);
30594
+ 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)) return new CellSelection($anchorCell, $headCell);
30595
+ else return Selection.near($headCell, 1);
30596
+ }
30485
30597
  };
30486
30598
  function drawCellSelection(state) {
30487
- if (!(state.selection instanceof CellSelection)) return null;
30488
- const cells = [];
30489
- state.selection.forEachCell((node, pos) => {
30490
- cells.push(
30491
- Decoration.node(pos, pos + node.nodeSize, { class: "selectedCell" })
30492
- );
30493
- });
30494
- return DecorationSet.create(state.doc, cells);
30599
+ if (!(state.selection instanceof CellSelection)) return null;
30600
+ const cells = [];
30601
+ state.selection.forEachCell((node, pos) => {
30602
+ cells.push(Decoration.node(pos, pos + node.nodeSize, { class: "selectedCell" }));
30603
+ });
30604
+ return DecorationSet.create(state.doc, cells);
30495
30605
  }
30496
30606
  function isCellBoundarySelection({ $from, $to }) {
30497
- if ($from.pos == $to.pos || $from.pos < $to.pos - 6) return false;
30498
- let afterFrom = $from.pos;
30499
- let beforeTo = $to.pos;
30500
- let depth = $from.depth;
30501
- for (; depth >= 0; depth--, afterFrom++)
30502
- if ($from.after(depth + 1) < $from.end(depth)) break;
30503
- for (let d = $to.depth; d >= 0; d--, beforeTo--)
30504
- if ($to.before(d + 1) > $to.start(d)) break;
30505
- return afterFrom == beforeTo && /row|table/.test($from.node(depth).type.spec.tableRole);
30607
+ if ($from.pos == $to.pos || $from.pos < $to.pos - 6) return false;
30608
+ let afterFrom = $from.pos;
30609
+ let beforeTo = $to.pos;
30610
+ let depth = $from.depth;
30611
+ for (; depth >= 0; depth--, afterFrom++) if ($from.after(depth + 1) < $from.end(depth)) break;
30612
+ for (let d = $to.depth; d >= 0; d--, beforeTo--) if ($to.before(d + 1) > $to.start(d)) break;
30613
+ return afterFrom == beforeTo && /row|table/.test($from.node(depth).type.spec.tableRole);
30506
30614
  }
30507
30615
  function isTextSelectionAcrossCells({ $from, $to }) {
30508
- let fromCellBoundaryNode;
30509
- let toCellBoundaryNode;
30510
- for (let i = $from.depth; i > 0; i--) {
30511
- const node = $from.node(i);
30512
- if (node.type.spec.tableRole === "cell" || node.type.spec.tableRole === "header_cell") {
30513
- fromCellBoundaryNode = node;
30514
- break;
30515
- }
30516
- }
30517
- for (let i = $to.depth; i > 0; i--) {
30518
- const node = $to.node(i);
30519
- if (node.type.spec.tableRole === "cell" || node.type.spec.tableRole === "header_cell") {
30520
- toCellBoundaryNode = node;
30521
- break;
30522
- }
30523
- }
30524
- return fromCellBoundaryNode !== toCellBoundaryNode && $to.parentOffset === 0;
30616
+ let fromCellBoundaryNode;
30617
+ let toCellBoundaryNode;
30618
+ for (let i = $from.depth; i > 0; i--) {
30619
+ const node = $from.node(i);
30620
+ if (node.type.spec.tableRole === "cell" || node.type.spec.tableRole === "header_cell") {
30621
+ fromCellBoundaryNode = node;
30622
+ break;
30623
+ }
30624
+ }
30625
+ for (let i = $to.depth; i > 0; i--) {
30626
+ const node = $to.node(i);
30627
+ if (node.type.spec.tableRole === "cell" || node.type.spec.tableRole === "header_cell") {
30628
+ toCellBoundaryNode = node;
30629
+ break;
30630
+ }
30631
+ }
30632
+ return fromCellBoundaryNode !== toCellBoundaryNode && $to.parentOffset === 0;
30525
30633
  }
30526
30634
  function normalizeSelection(state, tr, allowTableNodeSelection) {
30527
- const sel = (tr || state).selection;
30528
- const doc = (tr || state).doc;
30529
- let normalize;
30530
- let role;
30531
- if (sel instanceof NodeSelection && (role = sel.node.type.spec.tableRole)) {
30532
- if (role == "cell" || role == "header_cell") {
30533
- normalize = CellSelection.create(doc, sel.from);
30534
- } else if (role == "row") {
30535
- const $cell = doc.resolve(sel.from + 1);
30536
- normalize = CellSelection.rowSelection($cell, $cell);
30537
- } else if (!allowTableNodeSelection) {
30538
- const map = TableMap.get(sel.node);
30539
- const start = sel.from + 1;
30540
- const lastCell = start + map.map[map.width * map.height - 1];
30541
- normalize = CellSelection.create(doc, start + 1, lastCell);
30542
- }
30543
- } else if (sel instanceof TextSelection && isCellBoundarySelection(sel)) {
30544
- normalize = TextSelection.create(doc, sel.from);
30545
- } else if (sel instanceof TextSelection && isTextSelectionAcrossCells(sel)) {
30546
- normalize = TextSelection.create(doc, sel.$from.start(), sel.$from.end());
30547
- }
30548
- if (normalize) (tr || (tr = state.tr)).setSelection(normalize);
30549
- return tr;
30550
- }
30551
- var fixTablesKey = new PluginKey("fix-tables");
30635
+ const sel = (tr || state).selection;
30636
+ const doc = (tr || state).doc;
30637
+ let normalize;
30638
+ let role;
30639
+ if (sel instanceof NodeSelection && (role = sel.node.type.spec.tableRole)) {
30640
+ if (role == "cell" || role == "header_cell") normalize = CellSelection.create(doc, sel.from);
30641
+ else if (role == "row") {
30642
+ const $cell = doc.resolve(sel.from + 1);
30643
+ normalize = CellSelection.rowSelection($cell, $cell);
30644
+ } else if (!allowTableNodeSelection) {
30645
+ const map = TableMap.get(sel.node);
30646
+ const start = sel.from + 1;
30647
+ const lastCell = start + map.map[map.width * map.height - 1];
30648
+ normalize = CellSelection.create(doc, start + 1, lastCell);
30649
+ }
30650
+ } else if (sel instanceof TextSelection && isCellBoundarySelection(sel)) normalize = TextSelection.create(doc, sel.from);
30651
+ else if (sel instanceof TextSelection && isTextSelectionAcrossCells(sel)) normalize = TextSelection.create(doc, sel.$from.start(), sel.$from.end());
30652
+ if (normalize) (tr || (tr = state.tr)).setSelection(normalize);
30653
+ return tr;
30654
+ }
30655
+
30656
+ //#endregion
30657
+ //#region src/fixtables.ts
30658
+ /**
30659
+ * @public
30660
+ */
30661
+ const fixTablesKey = new PluginKey("fix-tables");
30662
+ /**
30663
+ * Helper for iterating through the nodes in a document that changed
30664
+ * compared to the given previous document. Useful for avoiding
30665
+ * duplicate work on each transaction.
30666
+ *
30667
+ * @public
30668
+ */
30552
30669
  function changedDescendants(old, cur, offset, f) {
30553
- const oldSize = old.childCount, curSize = cur.childCount;
30554
- outer: for (let i = 0, j = 0; i < curSize; i++) {
30555
- const child = cur.child(i);
30556
- for (let scan = j, e = Math.min(oldSize, i + 3); scan < e; scan++) {
30557
- if (old.child(scan) == child) {
30558
- j = scan + 1;
30559
- offset += child.nodeSize;
30560
- continue outer;
30561
- }
30562
- }
30563
- f(child, offset);
30564
- if (j < oldSize && old.child(j).sameMarkup(child))
30565
- changedDescendants(old.child(j), child, offset + 1, f);
30566
- else child.nodesBetween(0, child.content.size, f, offset + 1);
30567
- offset += child.nodeSize;
30568
- }
30670
+ const oldSize = old.childCount, curSize = cur.childCount;
30671
+ outer: for (let i = 0, j = 0; i < curSize; i++) {
30672
+ const child = cur.child(i);
30673
+ for (let scan = j, e = Math.min(oldSize, i + 3); scan < e; scan++) if (old.child(scan) == child) {
30674
+ j = scan + 1;
30675
+ offset += child.nodeSize;
30676
+ continue outer;
30677
+ }
30678
+ f(child, offset);
30679
+ if (j < oldSize && old.child(j).sameMarkup(child)) changedDescendants(old.child(j), child, offset + 1, f);
30680
+ else child.nodesBetween(0, child.content.size, f, offset + 1);
30681
+ offset += child.nodeSize;
30682
+ }
30569
30683
  }
30684
+ /**
30685
+ * Inspect all tables in the given state's document and return a
30686
+ * transaction that fixes them, if necessary. If `oldState` was
30687
+ * provided, that is assumed to hold a previous, known-good state,
30688
+ * which will be used to avoid re-scanning unchanged parts of the
30689
+ * document.
30690
+ *
30691
+ * @public
30692
+ */
30570
30693
  function fixTables(state, oldState) {
30571
- let tr;
30572
- const check = (node, pos) => {
30573
- if (node.type.spec.tableRole == "table")
30574
- tr = fixTable(state, node, pos, tr);
30575
- };
30576
- if (!oldState) state.doc.descendants(check);
30577
- else if (oldState.doc != state.doc)
30578
- changedDescendants(oldState.doc, state.doc, 0, check);
30579
- return tr;
30694
+ let tr;
30695
+ const check = (node, pos) => {
30696
+ if (node.type.spec.tableRole == "table") tr = fixTable(state, node, pos, tr);
30697
+ };
30698
+ if (!oldState) state.doc.descendants(check);
30699
+ else if (oldState.doc != state.doc) changedDescendants(oldState.doc, state.doc, 0, check);
30700
+ return tr;
30580
30701
  }
30581
30702
  function fixTable(state, table, tablePos, tr) {
30582
- const map = TableMap.get(table);
30583
- if (!map.problems) return tr;
30584
- if (!tr) tr = state.tr;
30585
- const mustAdd = [];
30586
- for (let i = 0; i < map.height; i++) mustAdd.push(0);
30587
- for (let i = 0; i < map.problems.length; i++) {
30588
- const prob = map.problems[i];
30589
- if (prob.type == "collision") {
30590
- const cell = table.nodeAt(prob.pos);
30591
- if (!cell) continue;
30592
- const attrs = cell.attrs;
30593
- for (let j = 0; j < attrs.rowspan; j++) mustAdd[prob.row + j] += prob.n;
30594
- tr.setNodeMarkup(
30595
- tr.mapping.map(tablePos + 1 + prob.pos),
30596
- null,
30597
- removeColSpan(attrs, attrs.colspan - prob.n, prob.n)
30598
- );
30599
- } else if (prob.type == "missing") {
30600
- mustAdd[prob.row] += prob.n;
30601
- } else if (prob.type == "overlong_rowspan") {
30602
- const cell = table.nodeAt(prob.pos);
30603
- if (!cell) continue;
30604
- tr.setNodeMarkup(tr.mapping.map(tablePos + 1 + prob.pos), null, {
30605
- ...cell.attrs,
30606
- rowspan: cell.attrs.rowspan - prob.n
30607
- });
30608
- } else if (prob.type == "colwidth mismatch") {
30609
- const cell = table.nodeAt(prob.pos);
30610
- if (!cell) continue;
30611
- tr.setNodeMarkup(tr.mapping.map(tablePos + 1 + prob.pos), null, {
30612
- ...cell.attrs,
30613
- colwidth: prob.colwidth
30614
- });
30615
- } else if (prob.type == "zero_sized") {
30616
- const pos = tr.mapping.map(tablePos);
30617
- tr.delete(pos, pos + table.nodeSize);
30618
- }
30619
- }
30620
- let first, last;
30621
- for (let i = 0; i < mustAdd.length; i++)
30622
- if (mustAdd[i]) {
30623
- if (first == null) first = i;
30624
- last = i;
30625
- }
30626
- for (let i = 0, pos = tablePos + 1; i < map.height; i++) {
30627
- const row = table.child(i);
30628
- const end = pos + row.nodeSize;
30629
- const add = mustAdd[i];
30630
- if (add > 0) {
30631
- let role = "cell";
30632
- if (row.firstChild) {
30633
- role = row.firstChild.type.spec.tableRole;
30634
- }
30635
- const nodes = [];
30636
- for (let j = 0; j < add; j++) {
30637
- const node = tableNodeTypes(state.schema)[role].createAndFill();
30638
- if (node) nodes.push(node);
30639
- }
30640
- const side = (i == 0 || first == i - 1) && last == i ? pos + 1 : end - 1;
30641
- tr.insert(tr.mapping.map(side), nodes);
30642
- }
30643
- pos = end;
30644
- }
30645
- return tr.setMeta(fixTablesKey, { fixTables: true });
30703
+ const map = TableMap.get(table);
30704
+ if (!map.problems) return tr;
30705
+ if (!tr) tr = state.tr;
30706
+ const mustAdd = [];
30707
+ for (let i = 0; i < map.height; i++) mustAdd.push(0);
30708
+ for (let i = 0; i < map.problems.length; i++) {
30709
+ const prob = map.problems[i];
30710
+ if (prob.type == "collision") {
30711
+ const cell = table.nodeAt(prob.pos);
30712
+ if (!cell) continue;
30713
+ const attrs = cell.attrs;
30714
+ for (let j = 0; j < attrs.rowspan; j++) mustAdd[prob.row + j] += prob.n;
30715
+ tr.setNodeMarkup(tr.mapping.map(tablePos + 1 + prob.pos), null, removeColSpan(attrs, attrs.colspan - prob.n, prob.n));
30716
+ } else if (prob.type == "missing") mustAdd[prob.row] += prob.n;
30717
+ else if (prob.type == "overlong_rowspan") {
30718
+ const cell = table.nodeAt(prob.pos);
30719
+ if (!cell) continue;
30720
+ tr.setNodeMarkup(tr.mapping.map(tablePos + 1 + prob.pos), null, {
30721
+ ...cell.attrs,
30722
+ rowspan: cell.attrs.rowspan - prob.n
30723
+ });
30724
+ } else if (prob.type == "colwidth mismatch") {
30725
+ const cell = table.nodeAt(prob.pos);
30726
+ if (!cell) continue;
30727
+ tr.setNodeMarkup(tr.mapping.map(tablePos + 1 + prob.pos), null, {
30728
+ ...cell.attrs,
30729
+ colwidth: prob.colwidth
30730
+ });
30731
+ } else if (prob.type == "zero_sized") {
30732
+ const pos = tr.mapping.map(tablePos);
30733
+ tr.delete(pos, pos + table.nodeSize);
30734
+ }
30735
+ }
30736
+ let first, last;
30737
+ for (let i = 0; i < mustAdd.length; i++) if (mustAdd[i]) {
30738
+ if (first == null) first = i;
30739
+ last = i;
30740
+ }
30741
+ for (let i = 0, pos = tablePos + 1; i < map.height; i++) {
30742
+ const row = table.child(i);
30743
+ const end = pos + row.nodeSize;
30744
+ const add = mustAdd[i];
30745
+ if (add > 0) {
30746
+ let role = "cell";
30747
+ if (row.firstChild) role = row.firstChild.type.spec.tableRole;
30748
+ const nodes = [];
30749
+ for (let j = 0; j < add; j++) {
30750
+ const node = tableNodeTypes(state.schema)[role].createAndFill();
30751
+ if (node) nodes.push(node);
30752
+ }
30753
+ const side = (i == 0 || first == i - 1) && last == i ? pos + 1 : end - 1;
30754
+ tr.insert(tr.mapping.map(side), nodes);
30755
+ }
30756
+ pos = end;
30757
+ }
30758
+ return tr.setMeta(fixTablesKey, { fixTables: true });
30646
30759
  }
30760
+
30761
+ //#endregion
30762
+ //#region src/commands.ts
30763
+ /**
30764
+ * Helper to get the selected rectangle in a table, if any. Adds table
30765
+ * map, table node, and table start offset to the object for
30766
+ * convenience.
30767
+ *
30768
+ * @public
30769
+ */
30647
30770
  function selectedRect(state) {
30648
- const sel = state.selection;
30649
- const $pos = selectionCell(state);
30650
- const table = $pos.node(-1);
30651
- const tableStart = $pos.start(-1);
30652
- const map = TableMap.get(table);
30653
- const rect = sel instanceof CellSelection ? map.rectBetween(
30654
- sel.$anchorCell.pos - tableStart,
30655
- sel.$headCell.pos - tableStart
30656
- ) : map.findCell($pos.pos - tableStart);
30657
- return { ...rect, tableStart, map, table };
30771
+ const sel = state.selection;
30772
+ const $pos = selectionCell(state);
30773
+ const table = $pos.node(-1);
30774
+ const tableStart = $pos.start(-1);
30775
+ const map = TableMap.get(table);
30776
+ return {
30777
+ ...sel instanceof CellSelection ? map.rectBetween(sel.$anchorCell.pos - tableStart, sel.$headCell.pos - tableStart) : map.findCell($pos.pos - tableStart),
30778
+ tableStart,
30779
+ map,
30780
+ table
30781
+ };
30658
30782
  }
30783
+ /**
30784
+ * Add a column at the given position in a table.
30785
+ *
30786
+ * @public
30787
+ */
30659
30788
  function addColumn(tr, { map, tableStart, table }, col) {
30660
- let refColumn = col > 0 ? -1 : 0;
30661
- if (columnIsHeader(map, table, col + refColumn)) {
30662
- refColumn = col == 0 || col == map.width ? null : 0;
30663
- }
30664
- for (let row = 0; row < map.height; row++) {
30665
- const index = row * map.width + col;
30666
- if (col > 0 && col < map.width && map.map[index - 1] == map.map[index]) {
30667
- const pos = map.map[index];
30668
- const cell = table.nodeAt(pos);
30669
- tr.setNodeMarkup(
30670
- tr.mapping.map(tableStart + pos),
30671
- null,
30672
- addColSpan(cell.attrs, col - map.colCount(pos))
30673
- );
30674
- row += cell.attrs.rowspan - 1;
30675
- } else {
30676
- const type = refColumn == null ? tableNodeTypes(table.type.schema).cell : table.nodeAt(map.map[index + refColumn]).type;
30677
- const pos = map.positionAt(row, col, table);
30678
- tr.insert(tr.mapping.map(tableStart + pos), type.createAndFill());
30679
- }
30680
- }
30681
- return tr;
30789
+ let refColumn = col > 0 ? -1 : 0;
30790
+ if (columnIsHeader(map, table, col + refColumn)) refColumn = col == 0 || col == map.width ? null : 0;
30791
+ for (let row = 0; row < map.height; row++) {
30792
+ const index = row * map.width + col;
30793
+ if (col > 0 && col < map.width && map.map[index - 1] == map.map[index]) {
30794
+ const pos = map.map[index];
30795
+ const cell = table.nodeAt(pos);
30796
+ tr.setNodeMarkup(tr.mapping.map(tableStart + pos), null, addColSpan(cell.attrs, col - map.colCount(pos)));
30797
+ row += cell.attrs.rowspan - 1;
30798
+ } else {
30799
+ const type = refColumn == null ? tableNodeTypes(table.type.schema).cell : table.nodeAt(map.map[index + refColumn]).type;
30800
+ const pos = map.positionAt(row, col, table);
30801
+ tr.insert(tr.mapping.map(tableStart + pos), type.createAndFill());
30802
+ }
30803
+ }
30804
+ return tr;
30682
30805
  }
30806
+ /**
30807
+ * Command to add a column before the column with the selection.
30808
+ *
30809
+ * @public
30810
+ */
30683
30811
  function addColumnBefore(state, dispatch) {
30684
- if (!isInTable(state)) return false;
30685
- if (dispatch) {
30686
- const rect = selectedRect(state);
30687
- dispatch(addColumn(state.tr, rect, rect.left));
30688
- }
30689
- return true;
30812
+ if (!isInTable(state)) return false;
30813
+ if (dispatch) {
30814
+ const rect = selectedRect(state);
30815
+ dispatch(addColumn(state.tr, rect, rect.left));
30816
+ }
30817
+ return true;
30690
30818
  }
30819
+ /**
30820
+ * Command to add a column after the column with the selection.
30821
+ *
30822
+ * @public
30823
+ */
30691
30824
  function addColumnAfter(state, dispatch) {
30692
- if (!isInTable(state)) return false;
30693
- if (dispatch) {
30694
- const rect = selectedRect(state);
30695
- dispatch(addColumn(state.tr, rect, rect.right));
30696
- }
30697
- return true;
30825
+ if (!isInTable(state)) return false;
30826
+ if (dispatch) {
30827
+ const rect = selectedRect(state);
30828
+ dispatch(addColumn(state.tr, rect, rect.right));
30829
+ }
30830
+ return true;
30698
30831
  }
30832
+ /**
30833
+ * @public
30834
+ */
30699
30835
  function removeColumn(tr, { map, table, tableStart }, col) {
30700
- const mapStart = tr.mapping.maps.length;
30701
- for (let row = 0; row < map.height; ) {
30702
- const index = row * map.width + col;
30703
- const pos = map.map[index];
30704
- const cell = table.nodeAt(pos);
30705
- const attrs = cell.attrs;
30706
- if (col > 0 && map.map[index - 1] == pos || col < map.width - 1 && map.map[index + 1] == pos) {
30707
- tr.setNodeMarkup(
30708
- tr.mapping.slice(mapStart).map(tableStart + pos),
30709
- null,
30710
- removeColSpan(attrs, col - map.colCount(pos))
30711
- );
30712
- } else {
30713
- const start = tr.mapping.slice(mapStart).map(tableStart + pos);
30714
- tr.delete(start, start + cell.nodeSize);
30715
- }
30716
- row += attrs.rowspan;
30717
- }
30836
+ const mapStart = tr.mapping.maps.length;
30837
+ for (let row = 0; row < map.height;) {
30838
+ const index = row * map.width + col;
30839
+ const pos = map.map[index];
30840
+ const cell = table.nodeAt(pos);
30841
+ const attrs = cell.attrs;
30842
+ if (col > 0 && map.map[index - 1] == pos || col < map.width - 1 && map.map[index + 1] == pos) tr.setNodeMarkup(tr.mapping.slice(mapStart).map(tableStart + pos), null, removeColSpan(attrs, col - map.colCount(pos)));
30843
+ else {
30844
+ const start = tr.mapping.slice(mapStart).map(tableStart + pos);
30845
+ tr.delete(start, start + cell.nodeSize);
30846
+ }
30847
+ row += attrs.rowspan;
30848
+ }
30718
30849
  }
30850
+ /**
30851
+ * Command function that removes the selected columns from a table.
30852
+ *
30853
+ * @public
30854
+ */
30719
30855
  function deleteColumn(state, dispatch) {
30720
- if (!isInTable(state)) return false;
30721
- if (dispatch) {
30722
- const rect = selectedRect(state);
30723
- const tr = state.tr;
30724
- if (rect.left == 0 && rect.right == rect.map.width) return false;
30725
- for (let i = rect.right - 1; ; i--) {
30726
- removeColumn(tr, rect, i);
30727
- if (i == rect.left) break;
30728
- const table = rect.tableStart ? tr.doc.nodeAt(rect.tableStart - 1) : tr.doc;
30729
- if (!table) {
30730
- throw RangeError("No table found");
30731
- }
30732
- rect.table = table;
30733
- rect.map = TableMap.get(table);
30734
- }
30735
- dispatch(tr);
30736
- }
30737
- return true;
30856
+ if (!isInTable(state)) return false;
30857
+ if (dispatch) {
30858
+ const rect = selectedRect(state);
30859
+ const tr = state.tr;
30860
+ if (rect.left == 0 && rect.right == rect.map.width) return false;
30861
+ for (let i = rect.right - 1;; i--) {
30862
+ removeColumn(tr, rect, i);
30863
+ if (i == rect.left) break;
30864
+ const table = rect.tableStart ? tr.doc.nodeAt(rect.tableStart - 1) : tr.doc;
30865
+ if (!table) throw new RangeError("No table found");
30866
+ rect.table = table;
30867
+ rect.map = TableMap.get(table);
30868
+ }
30869
+ dispatch(tr);
30870
+ }
30871
+ return true;
30738
30872
  }
30873
+ /**
30874
+ * @public
30875
+ */
30739
30876
  function rowIsHeader(map, table, row) {
30740
- var _a;
30741
- const headerCell = tableNodeTypes(table.type.schema).header_cell;
30742
- for (let col = 0; col < map.width; col++)
30743
- if (((_a = table.nodeAt(map.map[col + row * map.width])) == null ? void 0 : _a.type) != headerCell)
30744
- return false;
30745
- return true;
30877
+ var _table$nodeAt;
30878
+ const headerCell = tableNodeTypes(table.type.schema).header_cell;
30879
+ for (let col = 0; col < map.width; col++) if (((_table$nodeAt = table.nodeAt(map.map[col + row * map.width])) === null || _table$nodeAt === void 0 ? void 0 : _table$nodeAt.type) != headerCell) return false;
30880
+ return true;
30746
30881
  }
30882
+ /**
30883
+ * @public
30884
+ */
30747
30885
  function addRow(tr, { map, tableStart, table }, row) {
30748
- var _a;
30749
- let rowPos = tableStart;
30750
- for (let i = 0; i < row; i++) rowPos += table.child(i).nodeSize;
30751
- const cells = [];
30752
- let refRow = row > 0 ? -1 : 0;
30753
- if (rowIsHeader(map, table, row + refRow))
30754
- refRow = row == 0 || row == map.height ? null : 0;
30755
- for (let col = 0, index = map.width * row; col < map.width; col++, index++) {
30756
- if (row > 0 && row < map.height && map.map[index] == map.map[index - map.width]) {
30757
- const pos = map.map[index];
30758
- const attrs = table.nodeAt(pos).attrs;
30759
- tr.setNodeMarkup(tableStart + pos, null, {
30760
- ...attrs,
30761
- rowspan: attrs.rowspan + 1
30762
- });
30763
- col += attrs.colspan - 1;
30764
- } else {
30765
- const type = refRow == null ? tableNodeTypes(table.type.schema).cell : (_a = table.nodeAt(map.map[index + refRow * map.width])) == null ? void 0 : _a.type;
30766
- const node = type == null ? void 0 : type.createAndFill();
30767
- if (node) cells.push(node);
30768
- }
30769
- }
30770
- tr.insert(rowPos, tableNodeTypes(table.type.schema).row.create(null, cells));
30771
- return tr;
30886
+ let rowPos = tableStart;
30887
+ for (let i = 0; i < row; i++) rowPos += table.child(i).nodeSize;
30888
+ const cells = [];
30889
+ let refRow = row > 0 ? -1 : 0;
30890
+ if (rowIsHeader(map, table, row + refRow)) refRow = row == 0 || row == map.height ? null : 0;
30891
+ for (let col = 0, index = map.width * row; col < map.width; col++, index++) if (row > 0 && row < map.height && map.map[index] == map.map[index - map.width]) {
30892
+ const pos = map.map[index];
30893
+ const attrs = table.nodeAt(pos).attrs;
30894
+ tr.setNodeMarkup(tableStart + pos, null, {
30895
+ ...attrs,
30896
+ rowspan: attrs.rowspan + 1
30897
+ });
30898
+ col += attrs.colspan - 1;
30899
+ } else {
30900
+ var _table$nodeAt2;
30901
+ const type = refRow == null ? tableNodeTypes(table.type.schema).cell : (_table$nodeAt2 = table.nodeAt(map.map[index + refRow * map.width])) === null || _table$nodeAt2 === void 0 ? void 0 : _table$nodeAt2.type;
30902
+ const node = type === null || type === void 0 ? void 0 : type.createAndFill();
30903
+ if (node) cells.push(node);
30904
+ }
30905
+ tr.insert(rowPos, tableNodeTypes(table.type.schema).row.create(null, cells));
30906
+ return tr;
30772
30907
  }
30908
+ /**
30909
+ * Add a table row before the selection.
30910
+ *
30911
+ * @public
30912
+ */
30773
30913
  function addRowBefore(state, dispatch) {
30774
- if (!isInTable(state)) return false;
30775
- if (dispatch) {
30776
- const rect = selectedRect(state);
30777
- dispatch(addRow(state.tr, rect, rect.top));
30778
- }
30779
- return true;
30914
+ if (!isInTable(state)) return false;
30915
+ if (dispatch) {
30916
+ const rect = selectedRect(state);
30917
+ dispatch(addRow(state.tr, rect, rect.top));
30918
+ }
30919
+ return true;
30780
30920
  }
30921
+ /**
30922
+ * Add a table row after the selection.
30923
+ *
30924
+ * @public
30925
+ */
30781
30926
  function addRowAfter(state, dispatch) {
30782
- if (!isInTable(state)) return false;
30783
- if (dispatch) {
30784
- const rect = selectedRect(state);
30785
- dispatch(addRow(state.tr, rect, rect.bottom));
30786
- }
30787
- return true;
30927
+ if (!isInTable(state)) return false;
30928
+ if (dispatch) {
30929
+ const rect = selectedRect(state);
30930
+ dispatch(addRow(state.tr, rect, rect.bottom));
30931
+ }
30932
+ return true;
30788
30933
  }
30934
+ /**
30935
+ * @public
30936
+ */
30789
30937
  function removeRow(tr, { map, table, tableStart }, row) {
30790
- let rowPos = 0;
30791
- for (let i = 0; i < row; i++) rowPos += table.child(i).nodeSize;
30792
- const nextRow = rowPos + table.child(row).nodeSize;
30793
- const mapFrom = tr.mapping.maps.length;
30794
- tr.delete(rowPos + tableStart, nextRow + tableStart);
30795
- const seen = /* @__PURE__ */ new Set();
30796
- for (let col = 0, index = row * map.width; col < map.width; col++, index++) {
30797
- const pos = map.map[index];
30798
- if (seen.has(pos)) continue;
30799
- seen.add(pos);
30800
- if (row > 0 && pos == map.map[index - map.width]) {
30801
- const attrs = table.nodeAt(pos).attrs;
30802
- tr.setNodeMarkup(tr.mapping.slice(mapFrom).map(pos + tableStart), null, {
30803
- ...attrs,
30804
- rowspan: attrs.rowspan - 1
30805
- });
30806
- col += attrs.colspan - 1;
30807
- } else if (row < map.height && pos == map.map[index + map.width]) {
30808
- const cell = table.nodeAt(pos);
30809
- const attrs = cell.attrs;
30810
- const copy = cell.type.create(
30811
- { ...attrs, rowspan: cell.attrs.rowspan - 1 },
30812
- cell.content
30813
- );
30814
- const newPos = map.positionAt(row + 1, col, table);
30815
- tr.insert(tr.mapping.slice(mapFrom).map(tableStart + newPos), copy);
30816
- col += attrs.colspan - 1;
30817
- }
30818
- }
30938
+ let rowPos = 0;
30939
+ for (let i = 0; i < row; i++) rowPos += table.child(i).nodeSize;
30940
+ const nextRow = rowPos + table.child(row).nodeSize;
30941
+ const mapFrom = tr.mapping.maps.length;
30942
+ tr.delete(rowPos + tableStart, nextRow + tableStart);
30943
+ const seen = /* @__PURE__ */ new Set();
30944
+ for (let col = 0, index = row * map.width; col < map.width; col++, index++) {
30945
+ const pos = map.map[index];
30946
+ if (seen.has(pos)) continue;
30947
+ seen.add(pos);
30948
+ if (row > 0 && pos == map.map[index - map.width]) {
30949
+ const attrs = table.nodeAt(pos).attrs;
30950
+ tr.setNodeMarkup(tr.mapping.slice(mapFrom).map(pos + tableStart), null, {
30951
+ ...attrs,
30952
+ rowspan: attrs.rowspan - 1
30953
+ });
30954
+ col += attrs.colspan - 1;
30955
+ } else if (row < map.height && pos == map.map[index + map.width]) {
30956
+ const cell = table.nodeAt(pos);
30957
+ const attrs = cell.attrs;
30958
+ const copy = cell.type.create({
30959
+ ...attrs,
30960
+ rowspan: cell.attrs.rowspan - 1
30961
+ }, cell.content);
30962
+ const newPos = map.positionAt(row + 1, col, table);
30963
+ tr.insert(tr.mapping.slice(mapFrom).map(tableStart + newPos), copy);
30964
+ col += attrs.colspan - 1;
30965
+ }
30966
+ }
30819
30967
  }
30968
+ /**
30969
+ * Remove the selected rows from a table.
30970
+ *
30971
+ * @public
30972
+ */
30820
30973
  function deleteRow(state, dispatch) {
30821
- if (!isInTable(state)) return false;
30822
- if (dispatch) {
30823
- const rect = selectedRect(state), tr = state.tr;
30824
- if (rect.top == 0 && rect.bottom == rect.map.height) return false;
30825
- for (let i = rect.bottom - 1; ; i--) {
30826
- removeRow(tr, rect, i);
30827
- if (i == rect.top) break;
30828
- const table = rect.tableStart ? tr.doc.nodeAt(rect.tableStart - 1) : tr.doc;
30829
- if (!table) {
30830
- throw RangeError("No table found");
30831
- }
30832
- rect.table = table;
30833
- rect.map = TableMap.get(rect.table);
30834
- }
30835
- dispatch(tr);
30836
- }
30837
- return true;
30974
+ if (!isInTable(state)) return false;
30975
+ if (dispatch) {
30976
+ const rect = selectedRect(state), tr = state.tr;
30977
+ if (rect.top == 0 && rect.bottom == rect.map.height) return false;
30978
+ for (let i = rect.bottom - 1;; i--) {
30979
+ removeRow(tr, rect, i);
30980
+ if (i == rect.top) break;
30981
+ const table = rect.tableStart ? tr.doc.nodeAt(rect.tableStart - 1) : tr.doc;
30982
+ if (!table) throw new RangeError("No table found");
30983
+ rect.table = table;
30984
+ rect.map = TableMap.get(rect.table);
30985
+ }
30986
+ dispatch(tr);
30987
+ }
30988
+ return true;
30838
30989
  }
30839
30990
  function isEmpty(cell) {
30840
- const c = cell.content;
30841
- return c.childCount == 1 && c.child(0).isTextblock && c.child(0).childCount == 0;
30991
+ const c = cell.content;
30992
+ return c.childCount == 1 && c.child(0).isTextblock && c.child(0).childCount == 0;
30842
30993
  }
30843
30994
  function cellsOverlapRectangle({ width, height, map }, rect) {
30844
- let indexTop = rect.top * width + rect.left, indexLeft = indexTop;
30845
- let indexBottom = (rect.bottom - 1) * width + rect.left, indexRight = indexTop + (rect.right - rect.left - 1);
30846
- for (let i = rect.top; i < rect.bottom; i++) {
30847
- if (rect.left > 0 && map[indexLeft] == map[indexLeft - 1] || rect.right < width && map[indexRight] == map[indexRight + 1])
30848
- return true;
30849
- indexLeft += width;
30850
- indexRight += width;
30851
- }
30852
- for (let i = rect.left; i < rect.right; i++) {
30853
- if (rect.top > 0 && map[indexTop] == map[indexTop - width] || rect.bottom < height && map[indexBottom] == map[indexBottom + width])
30854
- return true;
30855
- indexTop++;
30856
- indexBottom++;
30857
- }
30858
- return false;
30995
+ let indexTop = rect.top * width + rect.left, indexLeft = indexTop;
30996
+ let indexBottom = (rect.bottom - 1) * width + rect.left, indexRight = indexTop + (rect.right - rect.left - 1);
30997
+ for (let i = rect.top; i < rect.bottom; i++) {
30998
+ if (rect.left > 0 && map[indexLeft] == map[indexLeft - 1] || rect.right < width && map[indexRight] == map[indexRight + 1]) return true;
30999
+ indexLeft += width;
31000
+ indexRight += width;
31001
+ }
31002
+ for (let i = rect.left; i < rect.right; i++) {
31003
+ if (rect.top > 0 && map[indexTop] == map[indexTop - width] || rect.bottom < height && map[indexBottom] == map[indexBottom + width]) return true;
31004
+ indexTop++;
31005
+ indexBottom++;
31006
+ }
31007
+ return false;
30859
31008
  }
31009
+ /**
31010
+ * Merge the selected cells into a single cell. Only available when
31011
+ * the selected cells' outline forms a rectangle.
31012
+ *
31013
+ * @public
31014
+ */
30860
31015
  function mergeCells(state, dispatch) {
30861
- const sel = state.selection;
30862
- if (!(sel instanceof CellSelection) || sel.$anchorCell.pos == sel.$headCell.pos)
30863
- return false;
30864
- const rect = selectedRect(state), { map } = rect;
30865
- if (cellsOverlapRectangle(map, rect)) return false;
30866
- if (dispatch) {
30867
- const tr = state.tr;
30868
- const seen = {};
30869
- let content = Fragment.empty;
30870
- let mergedPos;
30871
- let mergedCell;
30872
- for (let row = rect.top; row < rect.bottom; row++) {
30873
- for (let col = rect.left; col < rect.right; col++) {
30874
- const cellPos = map.map[row * map.width + col];
30875
- const cell = rect.table.nodeAt(cellPos);
30876
- if (seen[cellPos] || !cell) continue;
30877
- seen[cellPos] = true;
30878
- if (mergedPos == null) {
30879
- mergedPos = cellPos;
30880
- mergedCell = cell;
30881
- } else {
30882
- if (!isEmpty(cell)) content = content.append(cell.content);
30883
- const mapped = tr.mapping.map(cellPos + rect.tableStart);
30884
- tr.delete(mapped, mapped + cell.nodeSize);
30885
- }
30886
- }
30887
- }
30888
- if (mergedPos == null || mergedCell == null) {
30889
- return true;
30890
- }
30891
- tr.setNodeMarkup(mergedPos + rect.tableStart, null, {
30892
- ...addColSpan(
30893
- mergedCell.attrs,
30894
- mergedCell.attrs.colspan,
30895
- rect.right - rect.left - mergedCell.attrs.colspan
30896
- ),
30897
- rowspan: rect.bottom - rect.top
30898
- });
30899
- if (content.size) {
30900
- const end = mergedPos + 1 + mergedCell.content.size;
30901
- const start = isEmpty(mergedCell) ? mergedPos + 1 : end;
30902
- tr.replaceWith(start + rect.tableStart, end + rect.tableStart, content);
30903
- }
30904
- tr.setSelection(
30905
- new CellSelection(tr.doc.resolve(mergedPos + rect.tableStart))
30906
- );
30907
- dispatch(tr);
30908
- }
30909
- return true;
31016
+ const sel = state.selection;
31017
+ if (!(sel instanceof CellSelection) || sel.$anchorCell.pos == sel.$headCell.pos) return false;
31018
+ const rect = selectedRect(state), { map } = rect;
31019
+ if (cellsOverlapRectangle(map, rect)) return false;
31020
+ if (dispatch) {
31021
+ const tr = state.tr;
31022
+ const seen = {};
31023
+ let content = Fragment.empty;
31024
+ let mergedPos;
31025
+ let mergedCell;
31026
+ for (let row = rect.top; row < rect.bottom; row++) for (let col = rect.left; col < rect.right; col++) {
31027
+ const cellPos = map.map[row * map.width + col];
31028
+ const cell = rect.table.nodeAt(cellPos);
31029
+ if (seen[cellPos] || !cell) continue;
31030
+ seen[cellPos] = true;
31031
+ if (mergedPos == null) {
31032
+ mergedPos = cellPos;
31033
+ mergedCell = cell;
31034
+ } else {
31035
+ if (!isEmpty(cell)) content = content.append(cell.content);
31036
+ const mapped = tr.mapping.map(cellPos + rect.tableStart);
31037
+ tr.delete(mapped, mapped + cell.nodeSize);
31038
+ }
31039
+ }
31040
+ if (mergedPos == null || mergedCell == null) return true;
31041
+ tr.setNodeMarkup(mergedPos + rect.tableStart, null, {
31042
+ ...addColSpan(mergedCell.attrs, mergedCell.attrs.colspan, rect.right - rect.left - mergedCell.attrs.colspan),
31043
+ rowspan: rect.bottom - rect.top
31044
+ });
31045
+ if (content.size > 0) {
31046
+ const end = mergedPos + 1 + mergedCell.content.size;
31047
+ const start = isEmpty(mergedCell) ? mergedPos + 1 : end;
31048
+ tr.replaceWith(start + rect.tableStart, end + rect.tableStart, content);
31049
+ }
31050
+ tr.setSelection(new CellSelection(tr.doc.resolve(mergedPos + rect.tableStart)));
31051
+ dispatch(tr);
31052
+ }
31053
+ return true;
30910
31054
  }
31055
+ /**
31056
+ * Split a selected cell, whose rowpan or colspan is greater than one,
31057
+ * into smaller cells. Use the first cell type for the new cells.
31058
+ *
31059
+ * @public
31060
+ */
30911
31061
  function splitCell(state, dispatch) {
30912
- const nodeTypes = tableNodeTypes(state.schema);
30913
- return splitCellWithType(({ node }) => {
30914
- return nodeTypes[node.type.spec.tableRole];
30915
- })(state, dispatch);
31062
+ const nodeTypes = tableNodeTypes(state.schema);
31063
+ return splitCellWithType(({ node }) => {
31064
+ return nodeTypes[node.type.spec.tableRole];
31065
+ })(state, dispatch);
30916
31066
  }
31067
+ /**
31068
+ * Split a selected cell, whose rowpan or colspan is greater than one,
31069
+ * into smaller cells with the cell type (th, td) returned by getType function.
31070
+ *
31071
+ * @public
31072
+ */
30917
31073
  function splitCellWithType(getCellType) {
30918
- return (state, dispatch) => {
30919
- var _a;
30920
- const sel = state.selection;
30921
- let cellNode;
30922
- let cellPos;
30923
- if (!(sel instanceof CellSelection)) {
30924
- cellNode = cellWrapping(sel.$from);
30925
- if (!cellNode) return false;
30926
- cellPos = (_a = cellAround(sel.$from)) == null ? void 0 : _a.pos;
30927
- } else {
30928
- if (sel.$anchorCell.pos != sel.$headCell.pos) return false;
30929
- cellNode = sel.$anchorCell.nodeAfter;
30930
- cellPos = sel.$anchorCell.pos;
30931
- }
30932
- if (cellNode == null || cellPos == null) {
30933
- return false;
30934
- }
30935
- if (cellNode.attrs.colspan == 1 && cellNode.attrs.rowspan == 1) {
30936
- return false;
30937
- }
30938
- if (dispatch) {
30939
- let baseAttrs = cellNode.attrs;
30940
- const attrs = [];
30941
- const colwidth = baseAttrs.colwidth;
30942
- if (baseAttrs.rowspan > 1) baseAttrs = { ...baseAttrs, rowspan: 1 };
30943
- if (baseAttrs.colspan > 1) baseAttrs = { ...baseAttrs, colspan: 1 };
30944
- const rect = selectedRect(state), tr = state.tr;
30945
- for (let i = 0; i < rect.right - rect.left; i++)
30946
- attrs.push(
30947
- colwidth ? {
30948
- ...baseAttrs,
30949
- colwidth: colwidth && colwidth[i] ? [colwidth[i]] : null
30950
- } : baseAttrs
30951
- );
30952
- let lastCell;
30953
- for (let row = rect.top; row < rect.bottom; row++) {
30954
- let pos = rect.map.positionAt(row, rect.left, rect.table);
30955
- if (row == rect.top) pos += cellNode.nodeSize;
30956
- for (let col = rect.left, i = 0; col < rect.right; col++, i++) {
30957
- if (col == rect.left && row == rect.top) continue;
30958
- tr.insert(
30959
- lastCell = tr.mapping.map(pos + rect.tableStart, 1),
30960
- getCellType({ node: cellNode, row, col }).createAndFill(attrs[i])
30961
- );
30962
- }
30963
- }
30964
- tr.setNodeMarkup(
30965
- cellPos,
30966
- getCellType({ node: cellNode, row: rect.top, col: rect.left }),
30967
- attrs[0]
30968
- );
30969
- if (sel instanceof CellSelection)
30970
- tr.setSelection(
30971
- new CellSelection(
30972
- tr.doc.resolve(sel.$anchorCell.pos),
30973
- lastCell ? tr.doc.resolve(lastCell) : void 0
30974
- )
30975
- );
30976
- dispatch(tr);
30977
- }
30978
- return true;
30979
- };
31074
+ return (state, dispatch) => {
31075
+ const sel = state.selection;
31076
+ let cellNode;
31077
+ let cellPos;
31078
+ if (!(sel instanceof CellSelection)) {
31079
+ var _cellAround;
31080
+ cellNode = cellWrapping(sel.$from);
31081
+ if (!cellNode) return false;
31082
+ cellPos = (_cellAround = cellAround(sel.$from)) === null || _cellAround === void 0 ? void 0 : _cellAround.pos;
31083
+ } else {
31084
+ if (sel.$anchorCell.pos != sel.$headCell.pos) return false;
31085
+ cellNode = sel.$anchorCell.nodeAfter;
31086
+ cellPos = sel.$anchorCell.pos;
31087
+ }
31088
+ if (cellNode == null || cellPos == null) return false;
31089
+ if (cellNode.attrs.colspan == 1 && cellNode.attrs.rowspan == 1) return false;
31090
+ if (dispatch) {
31091
+ let baseAttrs = cellNode.attrs;
31092
+ const attrs = [];
31093
+ const colwidth = baseAttrs.colwidth;
31094
+ if (baseAttrs.rowspan > 1) baseAttrs = {
31095
+ ...baseAttrs,
31096
+ rowspan: 1
31097
+ };
31098
+ if (baseAttrs.colspan > 1) baseAttrs = {
31099
+ ...baseAttrs,
31100
+ colspan: 1
31101
+ };
31102
+ const rect = selectedRect(state), tr = state.tr;
31103
+ for (let i = 0; i < rect.right - rect.left; i++) attrs.push(colwidth ? {
31104
+ ...baseAttrs,
31105
+ colwidth: colwidth && colwidth[i] ? [colwidth[i]] : null
31106
+ } : baseAttrs);
31107
+ let lastCell;
31108
+ for (let row = rect.top; row < rect.bottom; row++) {
31109
+ let pos = rect.map.positionAt(row, rect.left, rect.table);
31110
+ if (row == rect.top) pos += cellNode.nodeSize;
31111
+ for (let col = rect.left, i = 0; col < rect.right; col++, i++) {
31112
+ if (col == rect.left && row == rect.top) continue;
31113
+ tr.insert(lastCell = tr.mapping.map(pos + rect.tableStart, 1), getCellType({
31114
+ node: cellNode,
31115
+ row,
31116
+ col
31117
+ }).createAndFill(attrs[i]));
31118
+ }
31119
+ }
31120
+ tr.setNodeMarkup(cellPos, getCellType({
31121
+ node: cellNode,
31122
+ row: rect.top,
31123
+ col: rect.left
31124
+ }), attrs[0]);
31125
+ if (sel instanceof CellSelection) tr.setSelection(new CellSelection(tr.doc.resolve(sel.$anchorCell.pos), lastCell ? tr.doc.resolve(lastCell) : void 0));
31126
+ dispatch(tr);
31127
+ }
31128
+ return true;
31129
+ };
30980
31130
  }
31131
+ /**
31132
+ * Returns a command that sets the given attribute to the given value,
31133
+ * and is only available when the currently selected cell doesn't
31134
+ * already have that attribute set to that value.
31135
+ *
31136
+ * @public
31137
+ */
30981
31138
  function setCellAttr(name, value) {
30982
- return function(state, dispatch) {
30983
- if (!isInTable(state)) return false;
30984
- const $cell = selectionCell(state);
30985
- if ($cell.nodeAfter.attrs[name] === value) return false;
30986
- if (dispatch) {
30987
- const tr = state.tr;
30988
- if (state.selection instanceof CellSelection)
30989
- state.selection.forEachCell((node, pos) => {
30990
- if (node.attrs[name] !== value)
30991
- tr.setNodeMarkup(pos, null, {
30992
- ...node.attrs,
30993
- [name]: value
30994
- });
30995
- });
30996
- else
30997
- tr.setNodeMarkup($cell.pos, null, {
30998
- ...$cell.nodeAfter.attrs,
30999
- [name]: value
31000
- });
31001
- dispatch(tr);
31002
- }
31003
- return true;
31004
- };
31139
+ return function(state, dispatch) {
31140
+ if (!isInTable(state)) return false;
31141
+ const $cell = selectionCell(state);
31142
+ if ($cell.nodeAfter.attrs[name] === value) return false;
31143
+ if (dispatch) {
31144
+ const tr = state.tr;
31145
+ if (state.selection instanceof CellSelection) state.selection.forEachCell((node, pos) => {
31146
+ if (node.attrs[name] !== value) tr.setNodeMarkup(pos, null, {
31147
+ ...node.attrs,
31148
+ [name]: value
31149
+ });
31150
+ });
31151
+ else tr.setNodeMarkup($cell.pos, null, {
31152
+ ...$cell.nodeAfter.attrs,
31153
+ [name]: value
31154
+ });
31155
+ dispatch(tr);
31156
+ }
31157
+ return true;
31158
+ };
31005
31159
  }
31006
31160
  function deprecated_toggleHeader(type) {
31007
- return function(state, dispatch) {
31008
- if (!isInTable(state)) return false;
31009
- if (dispatch) {
31010
- const types = tableNodeTypes(state.schema);
31011
- const rect = selectedRect(state), tr = state.tr;
31012
- const cells = rect.map.cellsInRect(
31013
- type == "column" ? {
31014
- left: rect.left,
31015
- top: 0,
31016
- right: rect.right,
31017
- bottom: rect.map.height
31018
- } : type == "row" ? {
31019
- left: 0,
31020
- top: rect.top,
31021
- right: rect.map.width,
31022
- bottom: rect.bottom
31023
- } : rect
31024
- );
31025
- const nodes = cells.map((pos) => rect.table.nodeAt(pos));
31026
- for (let i = 0; i < cells.length; i++)
31027
- if (nodes[i].type == types.header_cell)
31028
- tr.setNodeMarkup(
31029
- rect.tableStart + cells[i],
31030
- types.cell,
31031
- nodes[i].attrs
31032
- );
31033
- if (tr.steps.length == 0)
31034
- for (let i = 0; i < cells.length; i++)
31035
- tr.setNodeMarkup(
31036
- rect.tableStart + cells[i],
31037
- types.header_cell,
31038
- nodes[i].attrs
31039
- );
31040
- dispatch(tr);
31041
- }
31042
- return true;
31043
- };
31161
+ return function(state, dispatch) {
31162
+ if (!isInTable(state)) return false;
31163
+ if (dispatch) {
31164
+ const types = tableNodeTypes(state.schema);
31165
+ const rect = selectedRect(state), tr = state.tr;
31166
+ const cells = rect.map.cellsInRect(type == "column" ? {
31167
+ left: rect.left,
31168
+ top: 0,
31169
+ right: rect.right,
31170
+ bottom: rect.map.height
31171
+ } : type == "row" ? {
31172
+ left: 0,
31173
+ top: rect.top,
31174
+ right: rect.map.width,
31175
+ bottom: rect.bottom
31176
+ } : rect);
31177
+ const nodes = cells.map((pos) => rect.table.nodeAt(pos));
31178
+ for (let i = 0; i < cells.length; i++) if (nodes[i].type == types.header_cell) tr.setNodeMarkup(rect.tableStart + cells[i], types.cell, nodes[i].attrs);
31179
+ if (tr.steps.length === 0) for (let i = 0; i < cells.length; i++) tr.setNodeMarkup(rect.tableStart + cells[i], types.header_cell, nodes[i].attrs);
31180
+ dispatch(tr);
31181
+ }
31182
+ return true;
31183
+ };
31044
31184
  }
31045
31185
  function isHeaderEnabledByType(type, rect, types) {
31046
- const cellPositions = rect.map.cellsInRect({
31047
- left: 0,
31048
- top: 0,
31049
- right: type == "row" ? rect.map.width : 1,
31050
- bottom: type == "column" ? rect.map.height : 1
31051
- });
31052
- for (let i = 0; i < cellPositions.length; i++) {
31053
- const cell = rect.table.nodeAt(cellPositions[i]);
31054
- if (cell && cell.type !== types.header_cell) {
31055
- return false;
31056
- }
31057
- }
31058
- return true;
31186
+ const cellPositions = rect.map.cellsInRect({
31187
+ left: 0,
31188
+ top: 0,
31189
+ right: type == "row" ? rect.map.width : 1,
31190
+ bottom: type == "column" ? rect.map.height : 1
31191
+ });
31192
+ for (let i = 0; i < cellPositions.length; i++) {
31193
+ const cell = rect.table.nodeAt(cellPositions[i]);
31194
+ if (cell && cell.type !== types.header_cell) return false;
31195
+ }
31196
+ return true;
31059
31197
  }
31198
+ /**
31199
+ * Toggles between row/column header and normal cells (Only applies to first row/column).
31200
+ * For deprecated behavior pass `useDeprecatedLogic` in options with true.
31201
+ *
31202
+ * @public
31203
+ */
31060
31204
  function toggleHeader(type, options) {
31061
- options = options || { useDeprecatedLogic: false };
31062
- if (options.useDeprecatedLogic) return deprecated_toggleHeader(type);
31063
- return function(state, dispatch) {
31064
- if (!isInTable(state)) return false;
31065
- if (dispatch) {
31066
- const types = tableNodeTypes(state.schema);
31067
- const rect = selectedRect(state), tr = state.tr;
31068
- const isHeaderRowEnabled = isHeaderEnabledByType("row", rect, types);
31069
- const isHeaderColumnEnabled = isHeaderEnabledByType(
31070
- "column",
31071
- rect,
31072
- types
31073
- );
31074
- const isHeaderEnabled = type === "column" ? isHeaderRowEnabled : type === "row" ? isHeaderColumnEnabled : false;
31075
- const selectionStartsAt = isHeaderEnabled ? 1 : 0;
31076
- const cellsRect = type == "column" ? {
31077
- left: 0,
31078
- top: selectionStartsAt,
31079
- right: 1,
31080
- bottom: rect.map.height
31081
- } : type == "row" ? {
31082
- left: selectionStartsAt,
31083
- top: 0,
31084
- right: rect.map.width,
31085
- bottom: 1
31086
- } : rect;
31087
- const newType = type == "column" ? isHeaderColumnEnabled ? types.cell : types.header_cell : type == "row" ? isHeaderRowEnabled ? types.cell : types.header_cell : types.cell;
31088
- rect.map.cellsInRect(cellsRect).forEach((relativeCellPos) => {
31089
- const cellPos = relativeCellPos + rect.tableStart;
31090
- const cell = tr.doc.nodeAt(cellPos);
31091
- if (cell) {
31092
- tr.setNodeMarkup(cellPos, newType, cell.attrs);
31093
- }
31094
- });
31095
- dispatch(tr);
31096
- }
31097
- return true;
31098
- };
31205
+ options = options || { useDeprecatedLogic: false };
31206
+ if (options.useDeprecatedLogic) return deprecated_toggleHeader(type);
31207
+ return function(state, dispatch) {
31208
+ if (!isInTable(state)) return false;
31209
+ if (dispatch) {
31210
+ const types = tableNodeTypes(state.schema);
31211
+ const rect = selectedRect(state), tr = state.tr;
31212
+ const isHeaderRowEnabled = isHeaderEnabledByType("row", rect, types);
31213
+ const isHeaderColumnEnabled = isHeaderEnabledByType("column", rect, types);
31214
+ const selectionStartsAt = (type === "column" ? isHeaderRowEnabled : type === "row" ? isHeaderColumnEnabled : false) ? 1 : 0;
31215
+ const cellsRect = type == "column" ? {
31216
+ left: 0,
31217
+ top: selectionStartsAt,
31218
+ right: 1,
31219
+ bottom: rect.map.height
31220
+ } : type == "row" ? {
31221
+ left: selectionStartsAt,
31222
+ top: 0,
31223
+ right: rect.map.width,
31224
+ bottom: 1
31225
+ } : rect;
31226
+ const newType = type == "column" ? isHeaderColumnEnabled ? types.cell : types.header_cell : type == "row" ? isHeaderRowEnabled ? types.cell : types.header_cell : types.cell;
31227
+ rect.map.cellsInRect(cellsRect).forEach((relativeCellPos) => {
31228
+ const cellPos = relativeCellPos + rect.tableStart;
31229
+ const cell = tr.doc.nodeAt(cellPos);
31230
+ if (cell) tr.setNodeMarkup(cellPos, newType, cell.attrs);
31231
+ });
31232
+ dispatch(tr);
31233
+ }
31234
+ return true;
31235
+ };
31099
31236
  }
31100
- toggleHeader("row", {
31101
- useDeprecatedLogic: true
31102
- });
31103
- toggleHeader("column", {
31104
- useDeprecatedLogic: true
31105
- });
31106
- var toggleHeaderCell = toggleHeader("cell", {
31107
- useDeprecatedLogic: true
31108
- });
31237
+ /**
31238
+ * Toggles whether the selected row contains header cells.
31239
+ *
31240
+ * @public
31241
+ */
31242
+ toggleHeader("row", { useDeprecatedLogic: true });
31243
+ /**
31244
+ * Toggles whether the selected column contains header cells.
31245
+ *
31246
+ * @public
31247
+ */
31248
+ toggleHeader("column", { useDeprecatedLogic: true });
31249
+ /**
31250
+ * Toggles whether the selected cells are header cells.
31251
+ *
31252
+ * @public
31253
+ */
31254
+ const toggleHeaderCell = toggleHeader("cell", { useDeprecatedLogic: true });
31109
31255
  function findNextCell($cell, dir) {
31110
- if (dir < 0) {
31111
- const before = $cell.nodeBefore;
31112
- if (before) return $cell.pos - before.nodeSize;
31113
- for (let row = $cell.index(-1) - 1, rowEnd = $cell.before(); row >= 0; row--) {
31114
- const rowNode = $cell.node(-1).child(row);
31115
- const lastChild = rowNode.lastChild;
31116
- if (lastChild) {
31117
- return rowEnd - 1 - lastChild.nodeSize;
31118
- }
31119
- rowEnd -= rowNode.nodeSize;
31120
- }
31121
- } else {
31122
- if ($cell.index() < $cell.parent.childCount - 1) {
31123
- return $cell.pos + $cell.nodeAfter.nodeSize;
31124
- }
31125
- const table = $cell.node(-1);
31126
- for (let row = $cell.indexAfter(-1), rowStart = $cell.after(); row < table.childCount; row++) {
31127
- const rowNode = table.child(row);
31128
- if (rowNode.childCount) return rowStart + 1;
31129
- rowStart += rowNode.nodeSize;
31130
- }
31131
- }
31132
- return null;
31256
+ if (dir < 0) {
31257
+ const before = $cell.nodeBefore;
31258
+ if (before) return $cell.pos - before.nodeSize;
31259
+ for (let row = $cell.index(-1) - 1, rowEnd = $cell.before(); row >= 0; row--) {
31260
+ const rowNode = $cell.node(-1).child(row);
31261
+ const lastChild = rowNode.lastChild;
31262
+ if (lastChild) return rowEnd - 1 - lastChild.nodeSize;
31263
+ rowEnd -= rowNode.nodeSize;
31264
+ }
31265
+ } else {
31266
+ if ($cell.index() < $cell.parent.childCount - 1) return $cell.pos + $cell.nodeAfter.nodeSize;
31267
+ const table = $cell.node(-1);
31268
+ for (let row = $cell.indexAfter(-1), rowStart = $cell.after(); row < table.childCount; row++) {
31269
+ const rowNode = table.child(row);
31270
+ if (rowNode.childCount) return rowStart + 1;
31271
+ rowStart += rowNode.nodeSize;
31272
+ }
31273
+ }
31274
+ return null;
31133
31275
  }
31276
+ /**
31277
+ * Returns a command for selecting the next (direction=1) or previous
31278
+ * (direction=-1) cell in a table.
31279
+ *
31280
+ * @public
31281
+ */
31134
31282
  function goToNextCell(direction) {
31135
- return function(state, dispatch) {
31136
- if (!isInTable(state)) return false;
31137
- const cell = findNextCell(selectionCell(state), direction);
31138
- if (cell == null) return false;
31139
- if (dispatch) {
31140
- const $cell = state.doc.resolve(cell);
31141
- dispatch(
31142
- state.tr.setSelection(TextSelection.between($cell, moveCellForward($cell))).scrollIntoView()
31143
- );
31144
- }
31145
- return true;
31146
- };
31283
+ return function(state, dispatch) {
31284
+ if (!isInTable(state)) return false;
31285
+ const cell = findNextCell(selectionCell(state), direction);
31286
+ if (cell == null) return false;
31287
+ if (dispatch) {
31288
+ const $cell = state.doc.resolve(cell);
31289
+ dispatch(state.tr.setSelection(TextSelection.between($cell, moveCellForward($cell))).scrollIntoView());
31290
+ }
31291
+ return true;
31292
+ };
31147
31293
  }
31294
+ /**
31295
+ * Deletes the table around the selection, if any.
31296
+ *
31297
+ * @public
31298
+ */
31148
31299
  function deleteTable(state, dispatch) {
31149
- const $pos = state.selection.$anchor;
31150
- for (let d = $pos.depth; d > 0; d--) {
31151
- const node = $pos.node(d);
31152
- if (node.type.spec.tableRole == "table") {
31153
- if (dispatch)
31154
- dispatch(
31155
- state.tr.delete($pos.before(d), $pos.after(d)).scrollIntoView()
31156
- );
31157
- return true;
31158
- }
31159
- }
31160
- return false;
31300
+ const $pos = state.selection.$anchor;
31301
+ for (let d = $pos.depth; d > 0; d--) if ($pos.node(d).type.spec.tableRole == "table") {
31302
+ if (dispatch) dispatch(state.tr.delete($pos.before(d), $pos.after(d)).scrollIntoView());
31303
+ return true;
31304
+ }
31305
+ return false;
31161
31306
  }
31307
+ /**
31308
+ * Deletes the content of the selected cells, if they are not empty.
31309
+ *
31310
+ * @public
31311
+ */
31162
31312
  function deleteCellSelection(state, dispatch) {
31163
- const sel = state.selection;
31164
- if (!(sel instanceof CellSelection)) return false;
31165
- if (dispatch) {
31166
- const tr = state.tr;
31167
- const baseContent = tableNodeTypes(state.schema).cell.createAndFill().content;
31168
- sel.forEachCell((cell, pos) => {
31169
- if (!cell.content.eq(baseContent))
31170
- tr.replace(
31171
- tr.mapping.map(pos + 1),
31172
- tr.mapping.map(pos + cell.nodeSize - 1),
31173
- new Slice(baseContent, 0, 0)
31174
- );
31175
- });
31176
- if (tr.docChanged) dispatch(tr);
31177
- }
31178
- return true;
31313
+ const sel = state.selection;
31314
+ if (!(sel instanceof CellSelection)) return false;
31315
+ if (dispatch) {
31316
+ const tr = state.tr;
31317
+ const baseContent = tableNodeTypes(state.schema).cell.createAndFill().content;
31318
+ sel.forEachCell((cell, pos) => {
31319
+ if (!cell.content.eq(baseContent)) tr.replace(tr.mapping.map(pos + 1), tr.mapping.map(pos + cell.nodeSize - 1), new Slice(baseContent, 0, 0));
31320
+ });
31321
+ if (tr.docChanged) dispatch(tr);
31322
+ }
31323
+ return true;
31179
31324
  }
31325
+
31326
+ //#endregion
31327
+ //#region src/copypaste.ts
31328
+ /**
31329
+ * Get a rectangular area of cells from a slice, or null if the outer
31330
+ * nodes of the slice aren't table cells or rows.
31331
+ *
31332
+ * @internal
31333
+ */
31180
31334
  function pastedCells(slice) {
31181
- if (!slice.size) return null;
31182
- let { content, openStart, openEnd } = slice;
31183
- while (content.childCount == 1 && (openStart > 0 && openEnd > 0 || content.child(0).type.spec.tableRole == "table")) {
31184
- openStart--;
31185
- openEnd--;
31186
- content = content.child(0).content;
31187
- }
31188
- const first = content.child(0);
31189
- const role = first.type.spec.tableRole;
31190
- const schema = first.type.schema, rows = [];
31191
- if (role == "row") {
31192
- for (let i = 0; i < content.childCount; i++) {
31193
- let cells = content.child(i).content;
31194
- const left = i ? 0 : Math.max(0, openStart - 1);
31195
- const right = i < content.childCount - 1 ? 0 : Math.max(0, openEnd - 1);
31196
- if (left || right)
31197
- cells = fitSlice(
31198
- tableNodeTypes(schema).row,
31199
- new Slice(cells, left, right)
31200
- ).content;
31201
- rows.push(cells);
31202
- }
31203
- } else if (role == "cell" || role == "header_cell") {
31204
- rows.push(
31205
- openStart || openEnd ? fitSlice(
31206
- tableNodeTypes(schema).row,
31207
- new Slice(content, openStart, openEnd)
31208
- ).content : content
31209
- );
31210
- } else {
31211
- return null;
31212
- }
31213
- return ensureRectangular(schema, rows);
31335
+ if (slice.size === 0) return null;
31336
+ let { content, openStart, openEnd } = slice;
31337
+ while (content.childCount == 1 && (openStart > 0 && openEnd > 0 || content.child(0).type.spec.tableRole == "table")) {
31338
+ openStart--;
31339
+ openEnd--;
31340
+ content = content.child(0).content;
31341
+ }
31342
+ const first = content.child(0);
31343
+ const role = first.type.spec.tableRole;
31344
+ const schema = first.type.schema, rows = [];
31345
+ if (role == "row") for (let i = 0; i < content.childCount; i++) {
31346
+ let cells = content.child(i).content;
31347
+ const left = i ? 0 : Math.max(0, openStart - 1);
31348
+ const right = i < content.childCount - 1 ? 0 : Math.max(0, openEnd - 1);
31349
+ if (left || right) cells = fitSlice(tableNodeTypes(schema).row, new Slice(cells, left, right)).content;
31350
+ rows.push(cells);
31351
+ }
31352
+ else if (role == "cell" || role == "header_cell") rows.push(openStart || openEnd ? fitSlice(tableNodeTypes(schema).row, new Slice(content, openStart, openEnd)).content : content);
31353
+ else return null;
31354
+ return ensureRectangular(schema, rows);
31214
31355
  }
31215
31356
  function ensureRectangular(schema, rows) {
31216
- const widths = [];
31217
- for (let i = 0; i < rows.length; i++) {
31218
- const row = rows[i];
31219
- for (let j = row.childCount - 1; j >= 0; j--) {
31220
- const { rowspan, colspan } = row.child(j).attrs;
31221
- for (let r = i; r < i + rowspan; r++)
31222
- widths[r] = (widths[r] || 0) + colspan;
31223
- }
31224
- }
31225
- let width = 0;
31226
- for (let r = 0; r < widths.length; r++) width = Math.max(width, widths[r]);
31227
- for (let r = 0; r < widths.length; r++) {
31228
- if (r >= rows.length) rows.push(Fragment.empty);
31229
- if (widths[r] < width) {
31230
- const empty = tableNodeTypes(schema).cell.createAndFill();
31231
- const cells = [];
31232
- for (let i = widths[r]; i < width; i++) {
31233
- cells.push(empty);
31234
- }
31235
- rows[r] = rows[r].append(Fragment.from(cells));
31236
- }
31237
- }
31238
- return { height: rows.length, width, rows };
31357
+ const widths = [];
31358
+ for (let i = 0; i < rows.length; i++) {
31359
+ const row = rows[i];
31360
+ for (let j = row.childCount - 1; j >= 0; j--) {
31361
+ const { rowspan, colspan } = row.child(j).attrs;
31362
+ for (let r = i; r < i + rowspan; r++) widths[r] = (widths[r] || 0) + colspan;
31363
+ }
31364
+ }
31365
+ let width = 0;
31366
+ for (let r = 0; r < widths.length; r++) width = Math.max(width, widths[r]);
31367
+ for (let r = 0; r < widths.length; r++) {
31368
+ if (r >= rows.length) rows.push(Fragment.empty);
31369
+ if (widths[r] < width) {
31370
+ const empty = tableNodeTypes(schema).cell.createAndFill();
31371
+ const cells = [];
31372
+ for (let i = widths[r]; i < width; i++) cells.push(empty);
31373
+ rows[r] = rows[r].append(Fragment.from(cells));
31374
+ }
31375
+ }
31376
+ return {
31377
+ height: rows.length,
31378
+ width,
31379
+ rows
31380
+ };
31239
31381
  }
31240
31382
  function fitSlice(nodeType, slice) {
31241
- const node = nodeType.createAndFill();
31242
- const tr = new Transform(node).replace(0, node.content.size, slice);
31243
- return tr.doc;
31383
+ const node = nodeType.createAndFill();
31384
+ return new Transform(node).replace(0, node.content.size, slice).doc;
31244
31385
  }
31386
+ /**
31387
+ * Clip or extend (repeat) the given set of cells to cover the given
31388
+ * width and height. Will clip rowspan/colspan cells at the edges when
31389
+ * they stick out.
31390
+ *
31391
+ * @internal
31392
+ */
31245
31393
  function clipCells({ width, height, rows }, newWidth, newHeight) {
31246
- if (width != newWidth) {
31247
- const added = [];
31248
- const newRows = [];
31249
- for (let row = 0; row < rows.length; row++) {
31250
- const frag = rows[row], cells = [];
31251
- for (let col = added[row] || 0, i = 0; col < newWidth; i++) {
31252
- let cell = frag.child(i % frag.childCount);
31253
- if (col + cell.attrs.colspan > newWidth)
31254
- cell = cell.type.createChecked(
31255
- removeColSpan(
31256
- cell.attrs,
31257
- cell.attrs.colspan,
31258
- col + cell.attrs.colspan - newWidth
31259
- ),
31260
- cell.content
31261
- );
31262
- cells.push(cell);
31263
- col += cell.attrs.colspan;
31264
- for (let j = 1; j < cell.attrs.rowspan; j++)
31265
- added[row + j] = (added[row + j] || 0) + cell.attrs.colspan;
31266
- }
31267
- newRows.push(Fragment.from(cells));
31268
- }
31269
- rows = newRows;
31270
- width = newWidth;
31271
- }
31272
- if (height != newHeight) {
31273
- const newRows = [];
31274
- for (let row = 0, i = 0; row < newHeight; row++, i++) {
31275
- const cells = [], source = rows[i % height];
31276
- for (let j = 0; j < source.childCount; j++) {
31277
- let cell = source.child(j);
31278
- if (row + cell.attrs.rowspan > newHeight)
31279
- cell = cell.type.create(
31280
- {
31281
- ...cell.attrs,
31282
- rowspan: Math.max(1, newHeight - cell.attrs.rowspan)
31283
- },
31284
- cell.content
31285
- );
31286
- cells.push(cell);
31287
- }
31288
- newRows.push(Fragment.from(cells));
31289
- }
31290
- rows = newRows;
31291
- height = newHeight;
31292
- }
31293
- return { width, height, rows };
31394
+ if (width != newWidth) {
31395
+ const added = [];
31396
+ const newRows = [];
31397
+ for (let row = 0; row < rows.length; row++) {
31398
+ const frag = rows[row], cells = [];
31399
+ for (let col = added[row] || 0, i = 0; col < newWidth; i++) {
31400
+ let cell = frag.child(i % frag.childCount);
31401
+ if (col + cell.attrs.colspan > newWidth) cell = cell.type.createChecked(removeColSpan(cell.attrs, cell.attrs.colspan, col + cell.attrs.colspan - newWidth), cell.content);
31402
+ cells.push(cell);
31403
+ col += cell.attrs.colspan;
31404
+ for (let j = 1; j < cell.attrs.rowspan; j++) added[row + j] = (added[row + j] || 0) + cell.attrs.colspan;
31405
+ }
31406
+ newRows.push(Fragment.from(cells));
31407
+ }
31408
+ rows = newRows;
31409
+ width = newWidth;
31410
+ }
31411
+ if (height != newHeight) {
31412
+ const newRows = [];
31413
+ for (let row = 0, i = 0; row < newHeight; row++, i++) {
31414
+ const cells = [], source = rows[i % height];
31415
+ for (let j = 0; j < source.childCount; j++) {
31416
+ let cell = source.child(j);
31417
+ if (row + cell.attrs.rowspan > newHeight) cell = cell.type.create({
31418
+ ...cell.attrs,
31419
+ rowspan: Math.max(1, newHeight - cell.attrs.rowspan)
31420
+ }, cell.content);
31421
+ cells.push(cell);
31422
+ }
31423
+ newRows.push(Fragment.from(cells));
31424
+ }
31425
+ rows = newRows;
31426
+ height = newHeight;
31427
+ }
31428
+ return {
31429
+ width,
31430
+ height,
31431
+ rows
31432
+ };
31294
31433
  }
31295
31434
  function growTable(tr, map, table, start, width, height, mapFrom) {
31296
- const schema = tr.doc.type.schema;
31297
- const types = tableNodeTypes(schema);
31298
- let empty;
31299
- let emptyHead;
31300
- if (width > map.width) {
31301
- for (let row = 0, rowEnd = 0; row < map.height; row++) {
31302
- const rowNode = table.child(row);
31303
- rowEnd += rowNode.nodeSize;
31304
- const cells = [];
31305
- let add;
31306
- if (rowNode.lastChild == null || rowNode.lastChild.type == types.cell)
31307
- add = empty || (empty = types.cell.createAndFill());
31308
- else add = emptyHead || (emptyHead = types.header_cell.createAndFill());
31309
- for (let i = map.width; i < width; i++) cells.push(add);
31310
- tr.insert(tr.mapping.slice(mapFrom).map(rowEnd - 1 + start), cells);
31311
- }
31312
- }
31313
- if (height > map.height) {
31314
- const cells = [];
31315
- for (let i = 0, start2 = (map.height - 1) * map.width; i < Math.max(map.width, width); i++) {
31316
- const header = i >= map.width ? false : table.nodeAt(map.map[start2 + i]).type == types.header_cell;
31317
- cells.push(
31318
- header ? emptyHead || (emptyHead = types.header_cell.createAndFill()) : empty || (empty = types.cell.createAndFill())
31319
- );
31320
- }
31321
- const emptyRow = types.row.create(null, Fragment.from(cells)), rows = [];
31322
- for (let i = map.height; i < height; i++) rows.push(emptyRow);
31323
- tr.insert(tr.mapping.slice(mapFrom).map(start + table.nodeSize - 2), rows);
31324
- }
31325
- return !!(empty || emptyHead);
31435
+ const schema = tr.doc.type.schema;
31436
+ const types = tableNodeTypes(schema);
31437
+ let empty;
31438
+ let emptyHead;
31439
+ if (width > map.width) for (let row = 0, rowEnd = 0; row < map.height; row++) {
31440
+ const rowNode = table.child(row);
31441
+ rowEnd += rowNode.nodeSize;
31442
+ const cells = [];
31443
+ let add;
31444
+ if (rowNode.lastChild == null || rowNode.lastChild.type == types.cell) add = empty || (empty = types.cell.createAndFill());
31445
+ else add = emptyHead || (emptyHead = types.header_cell.createAndFill());
31446
+ for (let i = map.width; i < width; i++) cells.push(add);
31447
+ tr.insert(tr.mapping.slice(mapFrom).map(rowEnd - 1 + start), cells);
31448
+ }
31449
+ if (height > map.height) {
31450
+ const cells = [];
31451
+ for (let i = 0, start$1 = (map.height - 1) * map.width; i < Math.max(map.width, width); i++) {
31452
+ const header = i >= map.width ? false : table.nodeAt(map.map[start$1 + i]).type == types.header_cell;
31453
+ cells.push(header ? emptyHead || (emptyHead = types.header_cell.createAndFill()) : empty || (empty = types.cell.createAndFill()));
31454
+ }
31455
+ const emptyRow = types.row.create(null, Fragment.from(cells)), rows = [];
31456
+ for (let i = map.height; i < height; i++) rows.push(emptyRow);
31457
+ tr.insert(tr.mapping.slice(mapFrom).map(start + table.nodeSize - 2), rows);
31458
+ }
31459
+ return !!(empty || emptyHead);
31326
31460
  }
31327
31461
  function isolateHorizontal(tr, map, table, start, left, right, top, mapFrom) {
31328
- if (top == 0 || top == map.height) return false;
31329
- let found = false;
31330
- for (let col = left; col < right; col++) {
31331
- const index = top * map.width + col, pos = map.map[index];
31332
- if (map.map[index - map.width] == pos) {
31333
- found = true;
31334
- const cell = table.nodeAt(pos);
31335
- const { top: cellTop, left: cellLeft } = map.findCell(pos);
31336
- tr.setNodeMarkup(tr.mapping.slice(mapFrom).map(pos + start), null, {
31337
- ...cell.attrs,
31338
- rowspan: top - cellTop
31339
- });
31340
- tr.insert(
31341
- tr.mapping.slice(mapFrom).map(map.positionAt(top, cellLeft, table)),
31342
- cell.type.createAndFill({
31343
- ...cell.attrs,
31344
- rowspan: cellTop + cell.attrs.rowspan - top
31345
- })
31346
- );
31347
- col += cell.attrs.colspan - 1;
31348
- }
31349
- }
31350
- return found;
31462
+ if (top == 0 || top == map.height) return false;
31463
+ let found = false;
31464
+ for (let col = left; col < right; col++) {
31465
+ const index = top * map.width + col, pos = map.map[index];
31466
+ if (map.map[index - map.width] == pos) {
31467
+ found = true;
31468
+ const cell = table.nodeAt(pos);
31469
+ const { top: cellTop, left: cellLeft } = map.findCell(pos);
31470
+ tr.setNodeMarkup(tr.mapping.slice(mapFrom).map(pos + start), null, {
31471
+ ...cell.attrs,
31472
+ rowspan: top - cellTop
31473
+ });
31474
+ tr.insert(tr.mapping.slice(mapFrom).map(map.positionAt(top, cellLeft, table)), cell.type.createAndFill({
31475
+ ...cell.attrs,
31476
+ rowspan: cellTop + cell.attrs.rowspan - top
31477
+ }));
31478
+ col += cell.attrs.colspan - 1;
31479
+ }
31480
+ }
31481
+ return found;
31351
31482
  }
31352
31483
  function isolateVertical(tr, map, table, start, top, bottom, left, mapFrom) {
31353
- if (left == 0 || left == map.width) return false;
31354
- let found = false;
31355
- for (let row = top; row < bottom; row++) {
31356
- const index = row * map.width + left, pos = map.map[index];
31357
- if (map.map[index - 1] == pos) {
31358
- found = true;
31359
- const cell = table.nodeAt(pos);
31360
- const cellLeft = map.colCount(pos);
31361
- const updatePos = tr.mapping.slice(mapFrom).map(pos + start);
31362
- tr.setNodeMarkup(
31363
- updatePos,
31364
- null,
31365
- removeColSpan(
31366
- cell.attrs,
31367
- left - cellLeft,
31368
- cell.attrs.colspan - (left - cellLeft)
31369
- )
31370
- );
31371
- tr.insert(
31372
- updatePos + cell.nodeSize,
31373
- cell.type.createAndFill(
31374
- removeColSpan(cell.attrs, 0, left - cellLeft)
31375
- )
31376
- );
31377
- row += cell.attrs.rowspan - 1;
31378
- }
31379
- }
31380
- return found;
31484
+ if (left == 0 || left == map.width) return false;
31485
+ let found = false;
31486
+ for (let row = top; row < bottom; row++) {
31487
+ const index = row * map.width + left, pos = map.map[index];
31488
+ if (map.map[index - 1] == pos) {
31489
+ found = true;
31490
+ const cell = table.nodeAt(pos);
31491
+ const cellLeft = map.colCount(pos);
31492
+ const updatePos = tr.mapping.slice(mapFrom).map(pos + start);
31493
+ tr.setNodeMarkup(updatePos, null, removeColSpan(cell.attrs, left - cellLeft, cell.attrs.colspan - (left - cellLeft)));
31494
+ tr.insert(updatePos + cell.nodeSize, cell.type.createAndFill(removeColSpan(cell.attrs, 0, left - cellLeft)));
31495
+ row += cell.attrs.rowspan - 1;
31496
+ }
31497
+ }
31498
+ return found;
31381
31499
  }
31500
+ /**
31501
+ * Insert the given set of cells (as returned by `pastedCells`) into a
31502
+ * table, at the position pointed at by rect.
31503
+ *
31504
+ * @internal
31505
+ */
31382
31506
  function insertCells(state, dispatch, tableStart, rect, cells) {
31383
- let table = tableStart ? state.doc.nodeAt(tableStart - 1) : state.doc;
31384
- if (!table) {
31385
- throw new Error("No table found");
31386
- }
31387
- let map = TableMap.get(table);
31388
- const { top, left } = rect;
31389
- const right = left + cells.width, bottom = top + cells.height;
31390
- const tr = state.tr;
31391
- let mapFrom = 0;
31392
- function recomp() {
31393
- table = tableStart ? tr.doc.nodeAt(tableStart - 1) : tr.doc;
31394
- if (!table) {
31395
- throw new Error("No table found");
31396
- }
31397
- map = TableMap.get(table);
31398
- mapFrom = tr.mapping.maps.length;
31399
- }
31400
- if (growTable(tr, map, table, tableStart, right, bottom, mapFrom)) recomp();
31401
- if (isolateHorizontal(tr, map, table, tableStart, left, right, top, mapFrom))
31402
- recomp();
31403
- if (isolateHorizontal(tr, map, table, tableStart, left, right, bottom, mapFrom))
31404
- recomp();
31405
- if (isolateVertical(tr, map, table, tableStart, top, bottom, left, mapFrom))
31406
- recomp();
31407
- if (isolateVertical(tr, map, table, tableStart, top, bottom, right, mapFrom))
31408
- recomp();
31409
- for (let row = top; row < bottom; row++) {
31410
- const from = map.positionAt(row, left, table), to = map.positionAt(row, right, table);
31411
- tr.replace(
31412
- tr.mapping.slice(mapFrom).map(from + tableStart),
31413
- tr.mapping.slice(mapFrom).map(to + tableStart),
31414
- new Slice(cells.rows[row - top], 0, 0)
31415
- );
31416
- }
31417
- recomp();
31418
- tr.setSelection(
31419
- new CellSelection(
31420
- tr.doc.resolve(tableStart + map.positionAt(top, left, table)),
31421
- tr.doc.resolve(tableStart + map.positionAt(bottom - 1, right - 1, table))
31422
- )
31423
- );
31424
- dispatch(tr);
31425
- }
31426
-
31427
- // src/input.ts
31428
- var handleKeyDown = keydownHandler({
31429
- ArrowLeft: arrow("horiz", -1),
31430
- ArrowRight: arrow("horiz", 1),
31431
- ArrowUp: arrow("vert", -1),
31432
- ArrowDown: arrow("vert", 1),
31433
- "Shift-ArrowLeft": shiftArrow("horiz", -1),
31434
- "Shift-ArrowRight": shiftArrow("horiz", 1),
31435
- "Shift-ArrowUp": shiftArrow("vert", -1),
31436
- "Shift-ArrowDown": shiftArrow("vert", 1),
31437
- Backspace: deleteCellSelection,
31438
- "Mod-Backspace": deleteCellSelection,
31439
- Delete: deleteCellSelection,
31440
- "Mod-Delete": deleteCellSelection
31507
+ let table = tableStart ? state.doc.nodeAt(tableStart - 1) : state.doc;
31508
+ if (!table) throw new Error("No table found");
31509
+ let map = TableMap.get(table);
31510
+ const { top, left } = rect;
31511
+ const right = left + cells.width, bottom = top + cells.height;
31512
+ const tr = state.tr;
31513
+ let mapFrom = 0;
31514
+ function recomp() {
31515
+ table = tableStart ? tr.doc.nodeAt(tableStart - 1) : tr.doc;
31516
+ if (!table) throw new Error("No table found");
31517
+ map = TableMap.get(table);
31518
+ mapFrom = tr.mapping.maps.length;
31519
+ }
31520
+ if (growTable(tr, map, table, tableStart, right, bottom, mapFrom)) recomp();
31521
+ if (isolateHorizontal(tr, map, table, tableStart, left, right, top, mapFrom)) recomp();
31522
+ if (isolateHorizontal(tr, map, table, tableStart, left, right, bottom, mapFrom)) recomp();
31523
+ if (isolateVertical(tr, map, table, tableStart, top, bottom, left, mapFrom)) recomp();
31524
+ if (isolateVertical(tr, map, table, tableStart, top, bottom, right, mapFrom)) recomp();
31525
+ for (let row = top; row < bottom; row++) {
31526
+ const from = map.positionAt(row, left, table), to = map.positionAt(row, right, table);
31527
+ tr.replace(tr.mapping.slice(mapFrom).map(from + tableStart), tr.mapping.slice(mapFrom).map(to + tableStart), new Slice(cells.rows[row - top], 0, 0));
31528
+ }
31529
+ recomp();
31530
+ tr.setSelection(new CellSelection(tr.doc.resolve(tableStart + map.positionAt(top, left, table)), tr.doc.resolve(tableStart + map.positionAt(bottom - 1, right - 1, table))));
31531
+ dispatch(tr);
31532
+ }
31533
+
31534
+ //#endregion
31535
+ //#region src/input.ts
31536
+ const handleKeyDown = keydownHandler({
31537
+ ArrowLeft: arrow("horiz", -1),
31538
+ ArrowRight: arrow("horiz", 1),
31539
+ ArrowUp: arrow("vert", -1),
31540
+ ArrowDown: arrow("vert", 1),
31541
+ "Shift-ArrowLeft": shiftArrow("horiz", -1),
31542
+ "Shift-ArrowRight": shiftArrow("horiz", 1),
31543
+ "Shift-ArrowUp": shiftArrow("vert", -1),
31544
+ "Shift-ArrowDown": shiftArrow("vert", 1),
31545
+ Backspace: deleteCellSelection,
31546
+ "Mod-Backspace": deleteCellSelection,
31547
+ Delete: deleteCellSelection,
31548
+ "Mod-Delete": deleteCellSelection
31441
31549
  });
31442
31550
  function maybeSetSelection(state, dispatch, selection) {
31443
- if (selection.eq(state.selection)) return false;
31444
- if (dispatch) dispatch(state.tr.setSelection(selection).scrollIntoView());
31445
- return true;
31551
+ if (selection.eq(state.selection)) return false;
31552
+ if (dispatch) dispatch(state.tr.setSelection(selection).scrollIntoView());
31553
+ return true;
31446
31554
  }
31555
+ /**
31556
+ * @internal
31557
+ */
31447
31558
  function arrow(axis, dir) {
31448
- return (state, dispatch, view) => {
31449
- if (!view) return false;
31450
- const sel = state.selection;
31451
- if (sel instanceof CellSelection) {
31452
- return maybeSetSelection(
31453
- state,
31454
- dispatch,
31455
- Selection.near(sel.$headCell, dir)
31456
- );
31457
- }
31458
- if (axis != "horiz" && !sel.empty) return false;
31459
- const end = atEndOfCell(view, axis, dir);
31460
- if (end == null) return false;
31461
- if (axis == "horiz") {
31462
- return maybeSetSelection(
31463
- state,
31464
- dispatch,
31465
- Selection.near(state.doc.resolve(sel.head + dir), dir)
31466
- );
31467
- } else {
31468
- const $cell = state.doc.resolve(end);
31469
- const $next = nextCell($cell, axis, dir);
31470
- let newSel;
31471
- if ($next) newSel = Selection.near($next, 1);
31472
- else if (dir < 0)
31473
- newSel = Selection.near(state.doc.resolve($cell.before(-1)), -1);
31474
- else newSel = Selection.near(state.doc.resolve($cell.after(-1)), 1);
31475
- return maybeSetSelection(state, dispatch, newSel);
31476
- }
31477
- };
31559
+ return (state, dispatch, view) => {
31560
+ if (!view) return false;
31561
+ const sel = state.selection;
31562
+ if (sel instanceof CellSelection) return maybeSetSelection(state, dispatch, Selection.near(sel.$headCell, dir));
31563
+ if (axis != "horiz" && !sel.empty) return false;
31564
+ const end = atEndOfCell(view, axis, dir);
31565
+ if (end == null) return false;
31566
+ if (axis == "horiz") return maybeSetSelection(state, dispatch, Selection.near(state.doc.resolve(sel.head + dir), dir));
31567
+ else {
31568
+ const $cell = state.doc.resolve(end);
31569
+ const $next = nextCell($cell, axis, dir);
31570
+ let newSel;
31571
+ if ($next) newSel = Selection.near($next, 1);
31572
+ else if (dir < 0) newSel = Selection.near(state.doc.resolve($cell.before(-1)), -1);
31573
+ else newSel = Selection.near(state.doc.resolve($cell.after(-1)), 1);
31574
+ return maybeSetSelection(state, dispatch, newSel);
31575
+ }
31576
+ };
31478
31577
  }
31479
31578
  function shiftArrow(axis, dir) {
31480
- return (state, dispatch, view) => {
31481
- if (!view) return false;
31482
- const sel = state.selection;
31483
- let cellSel;
31484
- if (sel instanceof CellSelection) {
31485
- cellSel = sel;
31486
- } else {
31487
- const end = atEndOfCell(view, axis, dir);
31488
- if (end == null) return false;
31489
- cellSel = new CellSelection(state.doc.resolve(end));
31490
- }
31491
- const $head = nextCell(cellSel.$headCell, axis, dir);
31492
- if (!$head) return false;
31493
- return maybeSetSelection(
31494
- state,
31495
- dispatch,
31496
- new CellSelection(cellSel.$anchorCell, $head)
31497
- );
31498
- };
31579
+ return (state, dispatch, view) => {
31580
+ if (!view) return false;
31581
+ const sel = state.selection;
31582
+ let cellSel;
31583
+ if (sel instanceof CellSelection) cellSel = sel;
31584
+ else {
31585
+ const end = atEndOfCell(view, axis, dir);
31586
+ if (end == null) return false;
31587
+ cellSel = new CellSelection(state.doc.resolve(end));
31588
+ }
31589
+ const $head = nextCell(cellSel.$headCell, axis, dir);
31590
+ if (!$head) return false;
31591
+ return maybeSetSelection(state, dispatch, new CellSelection(cellSel.$anchorCell, $head));
31592
+ };
31499
31593
  }
31500
31594
  function handleTripleClick(view, pos) {
31501
- const doc = view.state.doc, $cell = cellAround(doc.resolve(pos));
31502
- if (!$cell) return false;
31503
- view.dispatch(view.state.tr.setSelection(new CellSelection($cell)));
31504
- return true;
31595
+ const doc = view.state.doc, $cell = cellAround(doc.resolve(pos));
31596
+ if (!$cell) return false;
31597
+ view.dispatch(view.state.tr.setSelection(new CellSelection($cell)));
31598
+ return true;
31505
31599
  }
31600
+ /**
31601
+ * @public
31602
+ */
31506
31603
  function handlePaste(view, _, slice) {
31507
- if (!isInTable(view.state)) return false;
31508
- let cells = pastedCells(slice);
31509
- const sel = view.state.selection;
31510
- if (sel instanceof CellSelection) {
31511
- if (!cells)
31512
- cells = {
31513
- width: 1,
31514
- height: 1,
31515
- rows: [
31516
- Fragment.from(
31517
- fitSlice(tableNodeTypes(view.state.schema).cell, slice)
31518
- )
31519
- ]
31520
- };
31521
- const table = sel.$anchorCell.node(-1);
31522
- const start = sel.$anchorCell.start(-1);
31523
- const rect = TableMap.get(table).rectBetween(
31524
- sel.$anchorCell.pos - start,
31525
- sel.$headCell.pos - start
31526
- );
31527
- cells = clipCells(cells, rect.right - rect.left, rect.bottom - rect.top);
31528
- insertCells(view.state, view.dispatch, start, rect, cells);
31529
- return true;
31530
- } else if (cells) {
31531
- const $cell = selectionCell(view.state);
31532
- const start = $cell.start(-1);
31533
- insertCells(
31534
- view.state,
31535
- view.dispatch,
31536
- start,
31537
- TableMap.get($cell.node(-1)).findCell($cell.pos - start),
31538
- cells
31539
- );
31540
- return true;
31541
- } else {
31542
- return false;
31543
- }
31544
- }
31545
- function handleMouseDown(view, startEvent) {
31546
- var _a;
31547
- if (startEvent.ctrlKey || startEvent.metaKey) return;
31548
- const startDOMCell = domInCell(view, startEvent.target);
31549
- let $anchor;
31550
- if (startEvent.shiftKey && view.state.selection instanceof CellSelection) {
31551
- setCellSelection(view.state.selection.$anchorCell, startEvent);
31552
- startEvent.preventDefault();
31553
- } else if (startEvent.shiftKey && startDOMCell && ($anchor = cellAround(view.state.selection.$anchor)) != null && ((_a = cellUnderMouse(view, startEvent)) == null ? void 0 : _a.pos) != $anchor.pos) {
31554
- setCellSelection($anchor, startEvent);
31555
- startEvent.preventDefault();
31556
- } else if (!startDOMCell) {
31557
- return;
31558
- }
31559
- function setCellSelection($anchor2, event) {
31560
- let $head = cellUnderMouse(view, event);
31561
- const starting = tableEditingKey.getState(view.state) == null;
31562
- if (!$head || !inSameTable($anchor2, $head)) {
31563
- if (starting) $head = $anchor2;
31564
- else return;
31565
- }
31566
- const selection = new CellSelection($anchor2, $head);
31567
- if (starting || !view.state.selection.eq(selection)) {
31568
- const tr = view.state.tr.setSelection(selection);
31569
- if (starting) tr.setMeta(tableEditingKey, $anchor2.pos);
31570
- view.dispatch(tr);
31571
- }
31572
- }
31573
- function stop() {
31574
- view.root.removeEventListener("mouseup", stop);
31575
- view.root.removeEventListener("dragstart", stop);
31576
- view.root.removeEventListener("mousemove", move);
31577
- if (tableEditingKey.getState(view.state) != null)
31578
- view.dispatch(view.state.tr.setMeta(tableEditingKey, -1));
31579
- }
31580
- function move(_event) {
31581
- const event = _event;
31582
- const anchor = tableEditingKey.getState(view.state);
31583
- let $anchor2;
31584
- if (anchor != null) {
31585
- $anchor2 = view.state.doc.resolve(anchor);
31586
- } else if (domInCell(view, event.target) != startDOMCell) {
31587
- $anchor2 = cellUnderMouse(view, startEvent);
31588
- if (!$anchor2) return stop();
31589
- }
31590
- if ($anchor2) setCellSelection($anchor2, event);
31591
- }
31592
- view.root.addEventListener("mouseup", stop);
31593
- view.root.addEventListener("dragstart", stop);
31594
- view.root.addEventListener("mousemove", move);
31604
+ if (!isInTable(view.state)) return false;
31605
+ let cells = pastedCells(slice);
31606
+ const sel = view.state.selection;
31607
+ if (sel instanceof CellSelection) {
31608
+ if (!cells) cells = {
31609
+ width: 1,
31610
+ height: 1,
31611
+ rows: [Fragment.from(fitSlice(tableNodeTypes(view.state.schema).cell, slice))]
31612
+ };
31613
+ const table = sel.$anchorCell.node(-1);
31614
+ const start = sel.$anchorCell.start(-1);
31615
+ const rect = TableMap.get(table).rectBetween(sel.$anchorCell.pos - start, sel.$headCell.pos - start);
31616
+ cells = clipCells(cells, rect.right - rect.left, rect.bottom - rect.top);
31617
+ insertCells(view.state, view.dispatch, start, rect, cells);
31618
+ return true;
31619
+ } else if (cells) {
31620
+ const $cell = selectionCell(view.state);
31621
+ const start = $cell.start(-1);
31622
+ insertCells(view.state, view.dispatch, start, TableMap.get($cell.node(-1)).findCell($cell.pos - start), cells);
31623
+ return true;
31624
+ } else return false;
31625
+ }
31626
+ function handleMouseDown$1(view, startEvent) {
31627
+ var _cellUnderMouse;
31628
+ if (startEvent.button != 0) return;
31629
+ if (startEvent.ctrlKey || startEvent.metaKey) return;
31630
+ const startDOMCell = domInCell(view, startEvent.target);
31631
+ let $anchor;
31632
+ if (startEvent.shiftKey && view.state.selection instanceof CellSelection) {
31633
+ setCellSelection(view.state.selection.$anchorCell, startEvent);
31634
+ startEvent.preventDefault();
31635
+ } else if (startEvent.shiftKey && startDOMCell && ($anchor = cellAround(view.state.selection.$anchor)) != null && ((_cellUnderMouse = cellUnderMouse(view, startEvent)) === null || _cellUnderMouse === void 0 ? void 0 : _cellUnderMouse.pos) != $anchor.pos) {
31636
+ setCellSelection($anchor, startEvent);
31637
+ startEvent.preventDefault();
31638
+ } else if (!startDOMCell) return;
31639
+ function setCellSelection($anchor$1, event) {
31640
+ let $head = cellUnderMouse(view, event);
31641
+ const starting = tableEditingKey.getState(view.state) == null;
31642
+ if (!$head || !inSameTable($anchor$1, $head)) if (starting) $head = $anchor$1;
31643
+ else return;
31644
+ const selection = new CellSelection($anchor$1, $head);
31645
+ if (starting || !view.state.selection.eq(selection)) {
31646
+ const tr = view.state.tr.setSelection(selection);
31647
+ if (starting) tr.setMeta(tableEditingKey, $anchor$1.pos);
31648
+ view.dispatch(tr);
31649
+ }
31650
+ }
31651
+ function stop() {
31652
+ view.root.removeEventListener("mouseup", stop);
31653
+ view.root.removeEventListener("dragstart", stop);
31654
+ view.root.removeEventListener("mousemove", move);
31655
+ if (tableEditingKey.getState(view.state) != null) view.dispatch(view.state.tr.setMeta(tableEditingKey, -1));
31656
+ }
31657
+ function move(_event) {
31658
+ const event = _event;
31659
+ const anchor = tableEditingKey.getState(view.state);
31660
+ let $anchor$1;
31661
+ if (anchor != null) $anchor$1 = view.state.doc.resolve(anchor);
31662
+ else if (domInCell(view, event.target) != startDOMCell) {
31663
+ $anchor$1 = cellUnderMouse(view, startEvent);
31664
+ if (!$anchor$1) return stop();
31665
+ }
31666
+ if ($anchor$1) setCellSelection($anchor$1, event);
31667
+ }
31668
+ view.root.addEventListener("mouseup", stop);
31669
+ view.root.addEventListener("dragstart", stop);
31670
+ view.root.addEventListener("mousemove", move);
31595
31671
  }
31596
31672
  function atEndOfCell(view, axis, dir) {
31597
- if (!(view.state.selection instanceof TextSelection)) return null;
31598
- const { $head } = view.state.selection;
31599
- for (let d = $head.depth - 1; d >= 0; d--) {
31600
- const parent = $head.node(d), index = dir < 0 ? $head.index(d) : $head.indexAfter(d);
31601
- if (index != (dir < 0 ? 0 : parent.childCount)) return null;
31602
- if (parent.type.spec.tableRole == "cell" || parent.type.spec.tableRole == "header_cell") {
31603
- const cellPos = $head.before(d);
31604
- const dirStr = axis == "vert" ? dir > 0 ? "down" : "up" : dir > 0 ? "right" : "left";
31605
- return view.endOfTextblock(dirStr) ? cellPos : null;
31606
- }
31607
- }
31608
- return null;
31673
+ if (!(view.state.selection instanceof TextSelection)) return null;
31674
+ const { $head } = view.state.selection;
31675
+ for (let d = $head.depth - 1; d >= 0; d--) {
31676
+ const parent = $head.node(d);
31677
+ if ((dir < 0 ? $head.index(d) : $head.indexAfter(d)) != (dir < 0 ? 0 : parent.childCount)) return null;
31678
+ if (parent.type.spec.tableRole == "cell" || parent.type.spec.tableRole == "header_cell") {
31679
+ const cellPos = $head.before(d);
31680
+ const dirStr = axis == "vert" ? dir > 0 ? "down" : "up" : dir > 0 ? "right" : "left";
31681
+ return view.endOfTextblock(dirStr) ? cellPos : null;
31682
+ }
31683
+ }
31684
+ return null;
31609
31685
  }
31610
31686
  function domInCell(view, dom) {
31611
- for (; dom && dom != view.dom; dom = dom.parentNode) {
31612
- if (dom.nodeName == "TD" || dom.nodeName == "TH") {
31613
- return dom;
31614
- }
31615
- }
31616
- return null;
31687
+ for (; dom && dom != view.dom; dom = dom.parentNode) if (dom.nodeName == "TD" || dom.nodeName == "TH") return dom;
31688
+ return null;
31617
31689
  }
31618
31690
  function cellUnderMouse(view, event) {
31619
- const mousePos = view.posAtCoords({
31620
- left: event.clientX,
31621
- top: event.clientY
31622
- });
31623
- if (!mousePos) return null;
31624
- return mousePos ? cellAround(view.state.doc.resolve(mousePos.pos)) : null;
31691
+ const mousePos = view.posAtCoords({
31692
+ left: event.clientX,
31693
+ top: event.clientY
31694
+ });
31695
+ if (!mousePos) return null;
31696
+ let { inside, pos } = mousePos;
31697
+ return inside >= 0 && cellAround(view.state.doc.resolve(inside)) || cellAround(view.state.doc.resolve(pos));
31625
31698
  }
31626
31699
 
31627
- // src/tableview.ts
31700
+ //#endregion
31701
+ //#region src/tableview.ts
31702
+ /**
31703
+ * @public
31704
+ */
31628
31705
  var TableView$1 = class TableView {
31629
- constructor(node, defaultCellMinWidth) {
31630
- this.node = node;
31631
- this.defaultCellMinWidth = defaultCellMinWidth;
31632
- this.dom = document.createElement("div");
31633
- this.dom.className = "tableWrapper";
31634
- this.table = this.dom.appendChild(document.createElement("table"));
31635
- this.table.style.setProperty(
31636
- "--default-cell-min-width",
31637
- `${defaultCellMinWidth}px`
31638
- );
31639
- this.colgroup = this.table.appendChild(document.createElement("colgroup"));
31640
- updateColumnsOnResize(node, this.colgroup, this.table, defaultCellMinWidth);
31641
- this.contentDOM = this.table.appendChild(document.createElement("tbody"));
31642
- }
31643
- update(node) {
31644
- if (node.type != this.node.type) return false;
31645
- this.node = node;
31646
- updateColumnsOnResize(
31647
- node,
31648
- this.colgroup,
31649
- this.table,
31650
- this.defaultCellMinWidth
31651
- );
31652
- return true;
31653
- }
31654
- ignoreMutation(record) {
31655
- return record.type == "attributes" && (record.target == this.table || this.colgroup.contains(record.target));
31656
- }
31706
+ constructor(node, defaultCellMinWidth) {
31707
+ this.node = node;
31708
+ this.defaultCellMinWidth = defaultCellMinWidth;
31709
+ this.dom = document.createElement("div");
31710
+ this.dom.className = "tableWrapper";
31711
+ this.table = this.dom.appendChild(document.createElement("table"));
31712
+ this.table.style.setProperty("--default-cell-min-width", `${defaultCellMinWidth}px`);
31713
+ this.colgroup = this.table.appendChild(document.createElement("colgroup"));
31714
+ updateColumnsOnResize(node, this.colgroup, this.table, defaultCellMinWidth);
31715
+ this.contentDOM = this.table.appendChild(document.createElement("tbody"));
31716
+ }
31717
+ update(node) {
31718
+ if (node.type != this.node.type) return false;
31719
+ this.node = node;
31720
+ updateColumnsOnResize(node, this.colgroup, this.table, this.defaultCellMinWidth);
31721
+ return true;
31722
+ }
31723
+ ignoreMutation(record) {
31724
+ return record.type == "attributes" && (record.target == this.table || this.colgroup.contains(record.target));
31725
+ }
31657
31726
  };
31727
+ /**
31728
+ * @public
31729
+ */
31658
31730
  function updateColumnsOnResize(node, colgroup, table, defaultCellMinWidth, overrideCol, overrideValue) {
31659
- var _a;
31660
- let totalWidth = 0;
31661
- let fixedWidth = true;
31662
- let nextDOM = colgroup.firstChild;
31663
- const row = node.firstChild;
31664
- if (!row) return;
31665
- for (let i = 0, col = 0; i < row.childCount; i++) {
31666
- const { colspan, colwidth } = row.child(i).attrs;
31667
- for (let j = 0; j < colspan; j++, col++) {
31668
- const hasWidth = overrideCol == col ? overrideValue : colwidth && colwidth[j];
31669
- const cssWidth = hasWidth ? hasWidth + "px" : "";
31670
- totalWidth += hasWidth || defaultCellMinWidth;
31671
- if (!hasWidth) fixedWidth = false;
31672
- if (!nextDOM) {
31673
- const col2 = document.createElement("col");
31674
- col2.style.width = cssWidth;
31675
- colgroup.appendChild(col2);
31676
- } else {
31677
- if (nextDOM.style.width != cssWidth) {
31678
- nextDOM.style.width = cssWidth;
31679
- }
31680
- nextDOM = nextDOM.nextSibling;
31681
- }
31682
- }
31683
- }
31684
- while (nextDOM) {
31685
- const after = nextDOM.nextSibling;
31686
- (_a = nextDOM.parentNode) == null ? void 0 : _a.removeChild(nextDOM);
31687
- nextDOM = after;
31688
- }
31689
- if (fixedWidth) {
31690
- table.style.width = totalWidth + "px";
31691
- table.style.minWidth = "";
31692
- } else {
31693
- table.style.width = "";
31694
- table.style.minWidth = totalWidth + "px";
31695
- }
31731
+ let totalWidth = 0;
31732
+ let fixedWidth = true;
31733
+ let nextDOM = colgroup.firstChild;
31734
+ const row = node.firstChild;
31735
+ if (!row) return;
31736
+ for (let i = 0, col = 0; i < row.childCount; i++) {
31737
+ const { colspan, colwidth } = row.child(i).attrs;
31738
+ for (let j = 0; j < colspan; j++, col++) {
31739
+ const hasWidth = overrideCol == col ? overrideValue : colwidth && colwidth[j];
31740
+ const cssWidth = hasWidth ? hasWidth + "px" : "";
31741
+ totalWidth += hasWidth || defaultCellMinWidth;
31742
+ if (!hasWidth) fixedWidth = false;
31743
+ if (!nextDOM) {
31744
+ const col$1 = document.createElement("col");
31745
+ col$1.style.width = cssWidth;
31746
+ colgroup.appendChild(col$1);
31747
+ } else {
31748
+ if (nextDOM.style.width != cssWidth) nextDOM.style.width = cssWidth;
31749
+ nextDOM = nextDOM.nextSibling;
31750
+ }
31751
+ }
31752
+ }
31753
+ while (nextDOM) {
31754
+ var _nextDOM$parentNode;
31755
+ const after = nextDOM.nextSibling;
31756
+ (_nextDOM$parentNode = nextDOM.parentNode) === null || _nextDOM$parentNode === void 0 || _nextDOM$parentNode.removeChild(nextDOM);
31757
+ nextDOM = after;
31758
+ }
31759
+ if (fixedWidth) {
31760
+ table.style.width = totalWidth + "px";
31761
+ table.style.minWidth = "";
31762
+ } else {
31763
+ table.style.width = "";
31764
+ table.style.minWidth = totalWidth + "px";
31765
+ }
31696
31766
  }
31697
31767
 
31698
- // src/columnresizing.ts
31699
- var columnResizingPluginKey = new PluginKey(
31700
- "tableColumnResizing"
31701
- );
31702
- function columnResizing({
31703
- handleWidth = 5,
31704
- cellMinWidth = 25,
31705
- defaultCellMinWidth = 100,
31706
- View = TableView$1,
31707
- lastColumnResizable = true
31708
- } = {}) {
31709
- const plugin = new Plugin({
31710
- key: columnResizingPluginKey,
31711
- state: {
31712
- init(_, state) {
31713
- var _a, _b;
31714
- const nodeViews = (_b = (_a = plugin.spec) == null ? void 0 : _a.props) == null ? void 0 : _b.nodeViews;
31715
- const tableName = tableNodeTypes(state.schema).table.name;
31716
- if (View && nodeViews) {
31717
- nodeViews[tableName] = (node, view) => {
31718
- return new View(node, defaultCellMinWidth, view);
31719
- };
31720
- }
31721
- return new ResizeState(-1, false);
31722
- },
31723
- apply(tr, prev) {
31724
- return prev.apply(tr);
31725
- }
31726
- },
31727
- props: {
31728
- attributes: (state) => {
31729
- const pluginState = columnResizingPluginKey.getState(state);
31730
- return pluginState && pluginState.activeHandle > -1 ? { class: "resize-cursor" } : {};
31731
- },
31732
- handleDOMEvents: {
31733
- mousemove: (view, event) => {
31734
- handleMouseMove(view, event, handleWidth, lastColumnResizable);
31735
- },
31736
- mouseleave: (view) => {
31737
- handleMouseLeave(view);
31738
- },
31739
- mousedown: (view, event) => {
31740
- handleMouseDown2(view, event, cellMinWidth, defaultCellMinWidth);
31741
- }
31742
- },
31743
- decorations: (state) => {
31744
- const pluginState = columnResizingPluginKey.getState(state);
31745
- if (pluginState && pluginState.activeHandle > -1) {
31746
- return handleDecorations(state, pluginState.activeHandle);
31747
- }
31748
- },
31749
- nodeViews: {}
31750
- }
31751
- });
31752
- return plugin;
31768
+ //#endregion
31769
+ //#region src/columnresizing.ts
31770
+ /**
31771
+ * @public
31772
+ */
31773
+ const columnResizingPluginKey = new PluginKey("tableColumnResizing");
31774
+ /**
31775
+ * @public
31776
+ */
31777
+ function columnResizing({ handleWidth = 5, cellMinWidth = 25, defaultCellMinWidth = 100, View = TableView$1, lastColumnResizable = true } = {}) {
31778
+ const plugin = new Plugin({
31779
+ key: columnResizingPluginKey,
31780
+ state: {
31781
+ init(_, state) {
31782
+ var _plugin$spec;
31783
+ const nodeViews = (_plugin$spec = plugin.spec) === null || _plugin$spec === void 0 || (_plugin$spec = _plugin$spec.props) === null || _plugin$spec === void 0 ? void 0 : _plugin$spec.nodeViews;
31784
+ const tableName = tableNodeTypes(state.schema).table.name;
31785
+ if (View && nodeViews) nodeViews[tableName] = (node, view) => {
31786
+ return new View(node, defaultCellMinWidth, view);
31787
+ };
31788
+ return new ResizeState(-1, false);
31789
+ },
31790
+ apply(tr, prev) {
31791
+ return prev.apply(tr);
31792
+ }
31793
+ },
31794
+ props: {
31795
+ attributes: (state) => {
31796
+ const pluginState = columnResizingPluginKey.getState(state);
31797
+ return pluginState && pluginState.activeHandle > -1 ? { class: "resize-cursor" } : {};
31798
+ },
31799
+ handleDOMEvents: {
31800
+ mousemove: (view, event) => {
31801
+ handleMouseMove(view, event, handleWidth, lastColumnResizable);
31802
+ },
31803
+ mouseleave: (view) => {
31804
+ handleMouseLeave(view);
31805
+ },
31806
+ mousedown: (view, event) => {
31807
+ handleMouseDown(view, event, cellMinWidth, defaultCellMinWidth);
31808
+ }
31809
+ },
31810
+ decorations: (state) => {
31811
+ const pluginState = columnResizingPluginKey.getState(state);
31812
+ if (pluginState && pluginState.activeHandle > -1) return handleDecorations(state, pluginState.activeHandle);
31813
+ },
31814
+ nodeViews: {}
31815
+ }
31816
+ });
31817
+ return plugin;
31753
31818
  }
31754
- var ResizeState = class _ResizeState {
31755
- constructor(activeHandle, dragging) {
31756
- this.activeHandle = activeHandle;
31757
- this.dragging = dragging;
31758
- }
31759
- apply(tr) {
31760
- const state = this;
31761
- const action = tr.getMeta(columnResizingPluginKey);
31762
- if (action && action.setHandle != null)
31763
- return new _ResizeState(action.setHandle, false);
31764
- if (action && action.setDragging !== void 0)
31765
- return new _ResizeState(state.activeHandle, action.setDragging);
31766
- if (state.activeHandle > -1 && tr.docChanged) {
31767
- let handle = tr.mapping.map(state.activeHandle, -1);
31768
- if (!pointsAtCell(tr.doc.resolve(handle))) {
31769
- handle = -1;
31770
- }
31771
- return new _ResizeState(handle, state.dragging);
31772
- }
31773
- return state;
31774
- }
31819
+ /**
31820
+ * @public
31821
+ */
31822
+ var ResizeState = class ResizeState {
31823
+ constructor(activeHandle, dragging) {
31824
+ this.activeHandle = activeHandle;
31825
+ this.dragging = dragging;
31826
+ }
31827
+ apply(tr) {
31828
+ const state = this;
31829
+ const action = tr.getMeta(columnResizingPluginKey);
31830
+ if (action && action.setHandle != null) return new ResizeState(action.setHandle, false);
31831
+ if (action && action.setDragging !== void 0) return new ResizeState(state.activeHandle, action.setDragging);
31832
+ if (state.activeHandle > -1 && tr.docChanged) {
31833
+ let handle = tr.mapping.map(state.activeHandle, -1);
31834
+ if (!pointsAtCell(tr.doc.resolve(handle))) handle = -1;
31835
+ return new ResizeState(handle, state.dragging);
31836
+ }
31837
+ return state;
31838
+ }
31775
31839
  };
31776
31840
  function handleMouseMove(view, event, handleWidth, lastColumnResizable) {
31777
- if (!view.editable) return;
31778
- const pluginState = columnResizingPluginKey.getState(view.state);
31779
- if (!pluginState) return;
31780
- if (!pluginState.dragging) {
31781
- const target = domCellAround(event.target);
31782
- let cell = -1;
31783
- if (target) {
31784
- const { left, right } = target.getBoundingClientRect();
31785
- if (event.clientX - left <= handleWidth)
31786
- cell = edgeCell(view, event, "left", handleWidth);
31787
- else if (right - event.clientX <= handleWidth)
31788
- cell = edgeCell(view, event, "right", handleWidth);
31789
- }
31790
- if (cell != pluginState.activeHandle) {
31791
- if (!lastColumnResizable && cell !== -1) {
31792
- const $cell = view.state.doc.resolve(cell);
31793
- const table = $cell.node(-1);
31794
- const map = TableMap.get(table);
31795
- const tableStart = $cell.start(-1);
31796
- const col = map.colCount($cell.pos - tableStart) + $cell.nodeAfter.attrs.colspan - 1;
31797
- if (col == map.width - 1) {
31798
- return;
31799
- }
31800
- }
31801
- updateHandle(view, cell);
31802
- }
31803
- }
31841
+ if (!view.editable) return;
31842
+ const pluginState = columnResizingPluginKey.getState(view.state);
31843
+ if (!pluginState) return;
31844
+ if (!pluginState.dragging) {
31845
+ const target = domCellAround(event.target);
31846
+ let cell = -1;
31847
+ if (target) {
31848
+ const { left, right } = target.getBoundingClientRect();
31849
+ if (event.clientX - left <= handleWidth) cell = edgeCell(view, event, "left", handleWidth);
31850
+ else if (right - event.clientX <= handleWidth) cell = edgeCell(view, event, "right", handleWidth);
31851
+ }
31852
+ if (cell != pluginState.activeHandle) {
31853
+ if (!lastColumnResizable && cell !== -1) {
31854
+ const $cell = view.state.doc.resolve(cell);
31855
+ const table = $cell.node(-1);
31856
+ const map = TableMap.get(table);
31857
+ const tableStart = $cell.start(-1);
31858
+ if (map.colCount($cell.pos - tableStart) + $cell.nodeAfter.attrs.colspan - 1 == map.width - 1) return;
31859
+ }
31860
+ updateHandle(view, cell);
31861
+ }
31862
+ }
31804
31863
  }
31805
31864
  function handleMouseLeave(view) {
31806
- if (!view.editable) return;
31807
- const pluginState = columnResizingPluginKey.getState(view.state);
31808
- if (pluginState && pluginState.activeHandle > -1 && !pluginState.dragging)
31809
- updateHandle(view, -1);
31810
- }
31811
- function handleMouseDown2(view, event, cellMinWidth, defaultCellMinWidth) {
31812
- var _a;
31813
- if (!view.editable) return false;
31814
- const win = (_a = view.dom.ownerDocument.defaultView) != null ? _a : window;
31815
- const pluginState = columnResizingPluginKey.getState(view.state);
31816
- if (!pluginState || pluginState.activeHandle == -1 || pluginState.dragging)
31817
- return false;
31818
- const cell = view.state.doc.nodeAt(pluginState.activeHandle);
31819
- const width = currentColWidth(view, pluginState.activeHandle, cell.attrs);
31820
- view.dispatch(
31821
- view.state.tr.setMeta(columnResizingPluginKey, {
31822
- setDragging: { startX: event.clientX, startWidth: width }
31823
- })
31824
- );
31825
- function finish(event2) {
31826
- win.removeEventListener("mouseup", finish);
31827
- win.removeEventListener("mousemove", move);
31828
- const pluginState2 = columnResizingPluginKey.getState(view.state);
31829
- if (pluginState2 == null ? void 0 : pluginState2.dragging) {
31830
- updateColumnWidth(
31831
- view,
31832
- pluginState2.activeHandle,
31833
- draggedWidth(pluginState2.dragging, event2, cellMinWidth)
31834
- );
31835
- view.dispatch(
31836
- view.state.tr.setMeta(columnResizingPluginKey, { setDragging: null })
31837
- );
31838
- }
31839
- }
31840
- function move(event2) {
31841
- if (!event2.which) return finish(event2);
31842
- const pluginState2 = columnResizingPluginKey.getState(view.state);
31843
- if (!pluginState2) return;
31844
- if (pluginState2.dragging) {
31845
- const dragged = draggedWidth(pluginState2.dragging, event2, cellMinWidth);
31846
- displayColumnWidth(
31847
- view,
31848
- pluginState2.activeHandle,
31849
- dragged,
31850
- defaultCellMinWidth
31851
- );
31852
- }
31853
- }
31854
- displayColumnWidth(
31855
- view,
31856
- pluginState.activeHandle,
31857
- width,
31858
- defaultCellMinWidth
31859
- );
31860
- win.addEventListener("mouseup", finish);
31861
- win.addEventListener("mousemove", move);
31862
- event.preventDefault();
31863
- return true;
31865
+ if (!view.editable) return;
31866
+ const pluginState = columnResizingPluginKey.getState(view.state);
31867
+ if (pluginState && pluginState.activeHandle > -1 && !pluginState.dragging) updateHandle(view, -1);
31868
+ }
31869
+ function handleMouseDown(view, event, cellMinWidth, defaultCellMinWidth) {
31870
+ var _view$dom$ownerDocume;
31871
+ if (!view.editable) return false;
31872
+ const win = (_view$dom$ownerDocume = view.dom.ownerDocument.defaultView) !== null && _view$dom$ownerDocume !== void 0 ? _view$dom$ownerDocume : window;
31873
+ const pluginState = columnResizingPluginKey.getState(view.state);
31874
+ if (!pluginState || pluginState.activeHandle == -1 || pluginState.dragging) return false;
31875
+ const cell = view.state.doc.nodeAt(pluginState.activeHandle);
31876
+ const width = currentColWidth(view, pluginState.activeHandle, cell.attrs);
31877
+ view.dispatch(view.state.tr.setMeta(columnResizingPluginKey, { setDragging: {
31878
+ startX: event.clientX,
31879
+ startWidth: width
31880
+ } }));
31881
+ function finish(event$1) {
31882
+ win.removeEventListener("mouseup", finish);
31883
+ win.removeEventListener("mousemove", move);
31884
+ const pluginState$1 = columnResizingPluginKey.getState(view.state);
31885
+ if (pluginState$1 === null || pluginState$1 === void 0 ? void 0 : pluginState$1.dragging) {
31886
+ updateColumnWidth(view, pluginState$1.activeHandle, draggedWidth(pluginState$1.dragging, event$1, cellMinWidth));
31887
+ view.dispatch(view.state.tr.setMeta(columnResizingPluginKey, { setDragging: null }));
31888
+ }
31889
+ }
31890
+ function move(event$1) {
31891
+ if (!event$1.which) return finish(event$1);
31892
+ const pluginState$1 = columnResizingPluginKey.getState(view.state);
31893
+ if (!pluginState$1) return;
31894
+ if (pluginState$1.dragging) {
31895
+ const dragged = draggedWidth(pluginState$1.dragging, event$1, cellMinWidth);
31896
+ displayColumnWidth(view, pluginState$1.activeHandle, dragged, defaultCellMinWidth);
31897
+ }
31898
+ }
31899
+ displayColumnWidth(view, pluginState.activeHandle, width, defaultCellMinWidth);
31900
+ win.addEventListener("mouseup", finish);
31901
+ win.addEventListener("mousemove", move);
31902
+ event.preventDefault();
31903
+ return true;
31864
31904
  }
31865
31905
  function currentColWidth(view, cellPos, { colspan, colwidth }) {
31866
- const width = colwidth && colwidth[colwidth.length - 1];
31867
- if (width) return width;
31868
- const dom = view.domAtPos(cellPos);
31869
- const node = dom.node.childNodes[dom.offset];
31870
- let domWidth = node.offsetWidth, parts = colspan;
31871
- if (colwidth) {
31872
- for (let i = 0; i < colspan; i++)
31873
- if (colwidth[i]) {
31874
- domWidth -= colwidth[i];
31875
- parts--;
31876
- }
31877
- }
31878
- return domWidth / parts;
31906
+ const width = colwidth && colwidth[colwidth.length - 1];
31907
+ if (width) return width;
31908
+ const dom = view.domAtPos(cellPos);
31909
+ let domWidth = dom.node.childNodes[dom.offset].offsetWidth, parts = colspan;
31910
+ if (colwidth) {
31911
+ for (let i = 0; i < colspan; i++) if (colwidth[i]) {
31912
+ domWidth -= colwidth[i];
31913
+ parts--;
31914
+ }
31915
+ }
31916
+ return domWidth / parts;
31879
31917
  }
31880
31918
  function domCellAround(target) {
31881
- while (target && target.nodeName != "TD" && target.nodeName != "TH")
31882
- target = target.classList && target.classList.contains("ProseMirror") ? null : target.parentNode;
31883
- return target;
31919
+ while (target && target.nodeName != "TD" && target.nodeName != "TH") target = target.classList && target.classList.contains("ProseMirror") ? null : target.parentNode;
31920
+ return target;
31884
31921
  }
31885
31922
  function edgeCell(view, event, side, handleWidth) {
31886
- const offset = side == "right" ? -handleWidth : handleWidth;
31887
- const found = view.posAtCoords({
31888
- left: event.clientX + offset,
31889
- top: event.clientY
31890
- });
31891
- if (!found) return -1;
31892
- const { pos } = found;
31893
- const $cell = cellAround(view.state.doc.resolve(pos));
31894
- if (!$cell) return -1;
31895
- if (side == "right") return $cell.pos;
31896
- const map = TableMap.get($cell.node(-1)), start = $cell.start(-1);
31897
- const index = map.map.indexOf($cell.pos - start);
31898
- return index % map.width == 0 ? -1 : start + map.map[index - 1];
31923
+ const offset = side == "right" ? -handleWidth : handleWidth;
31924
+ const found = view.posAtCoords({
31925
+ left: event.clientX + offset,
31926
+ top: event.clientY
31927
+ });
31928
+ if (!found) return -1;
31929
+ const { pos } = found;
31930
+ const $cell = cellAround(view.state.doc.resolve(pos));
31931
+ if (!$cell) return -1;
31932
+ if (side == "right") return $cell.pos;
31933
+ const map = TableMap.get($cell.node(-1)), start = $cell.start(-1);
31934
+ const index = map.map.indexOf($cell.pos - start);
31935
+ return index % map.width == 0 ? -1 : start + map.map[index - 1];
31899
31936
  }
31900
31937
  function draggedWidth(dragging, event, resizeMinWidth) {
31901
- const offset = event.clientX - dragging.startX;
31902
- return Math.max(resizeMinWidth, dragging.startWidth + offset);
31938
+ const offset = event.clientX - dragging.startX;
31939
+ return Math.max(resizeMinWidth, dragging.startWidth + offset);
31903
31940
  }
31904
31941
  function updateHandle(view, value) {
31905
- view.dispatch(
31906
- view.state.tr.setMeta(columnResizingPluginKey, { setHandle: value })
31907
- );
31942
+ view.dispatch(view.state.tr.setMeta(columnResizingPluginKey, { setHandle: value }));
31908
31943
  }
31909
31944
  function updateColumnWidth(view, cell, width) {
31910
- const $cell = view.state.doc.resolve(cell);
31911
- const table = $cell.node(-1), map = TableMap.get(table), start = $cell.start(-1);
31912
- const col = map.colCount($cell.pos - start) + $cell.nodeAfter.attrs.colspan - 1;
31913
- const tr = view.state.tr;
31914
- for (let row = 0; row < map.height; row++) {
31915
- const mapIndex = row * map.width + col;
31916
- if (row && map.map[mapIndex] == map.map[mapIndex - map.width]) continue;
31917
- const pos = map.map[mapIndex];
31918
- const attrs = table.nodeAt(pos).attrs;
31919
- const index = attrs.colspan == 1 ? 0 : col - map.colCount(pos);
31920
- if (attrs.colwidth && attrs.colwidth[index] == width) continue;
31921
- const colwidth = attrs.colwidth ? attrs.colwidth.slice() : zeroes(attrs.colspan);
31922
- colwidth[index] = width;
31923
- tr.setNodeMarkup(start + pos, null, { ...attrs, colwidth });
31924
- }
31925
- if (tr.docChanged) view.dispatch(tr);
31945
+ const $cell = view.state.doc.resolve(cell);
31946
+ const table = $cell.node(-1), map = TableMap.get(table), start = $cell.start(-1);
31947
+ const col = map.colCount($cell.pos - start) + $cell.nodeAfter.attrs.colspan - 1;
31948
+ const tr = view.state.tr;
31949
+ for (let row = 0; row < map.height; row++) {
31950
+ const mapIndex = row * map.width + col;
31951
+ if (row && map.map[mapIndex] == map.map[mapIndex - map.width]) continue;
31952
+ const pos = map.map[mapIndex];
31953
+ const attrs = table.nodeAt(pos).attrs;
31954
+ const index = attrs.colspan == 1 ? 0 : col - map.colCount(pos);
31955
+ if (attrs.colwidth && attrs.colwidth[index] == width) continue;
31956
+ const colwidth = attrs.colwidth ? attrs.colwidth.slice() : zeroes(attrs.colspan);
31957
+ colwidth[index] = width;
31958
+ tr.setNodeMarkup(start + pos, null, {
31959
+ ...attrs,
31960
+ colwidth
31961
+ });
31962
+ }
31963
+ if (tr.docChanged) view.dispatch(tr);
31926
31964
  }
31927
31965
  function displayColumnWidth(view, cell, width, defaultCellMinWidth) {
31928
- const $cell = view.state.doc.resolve(cell);
31929
- const table = $cell.node(-1), start = $cell.start(-1);
31930
- const col = TableMap.get(table).colCount($cell.pos - start) + $cell.nodeAfter.attrs.colspan - 1;
31931
- let dom = view.domAtPos($cell.start(-1)).node;
31932
- while (dom && dom.nodeName != "TABLE") {
31933
- dom = dom.parentNode;
31934
- }
31935
- if (!dom) return;
31936
- updateColumnsOnResize(
31937
- table,
31938
- dom.firstChild,
31939
- dom,
31940
- defaultCellMinWidth,
31941
- col,
31942
- width
31943
- );
31966
+ const $cell = view.state.doc.resolve(cell);
31967
+ const table = $cell.node(-1), start = $cell.start(-1);
31968
+ const col = TableMap.get(table).colCount($cell.pos - start) + $cell.nodeAfter.attrs.colspan - 1;
31969
+ let dom = view.domAtPos($cell.start(-1)).node;
31970
+ while (dom && dom.nodeName != "TABLE") dom = dom.parentNode;
31971
+ if (!dom) return;
31972
+ updateColumnsOnResize(table, dom.firstChild, dom, defaultCellMinWidth, col, width);
31944
31973
  }
31945
31974
  function zeroes(n) {
31946
- return Array(n).fill(0);
31975
+ return Array(n).fill(0);
31947
31976
  }
31948
31977
  function handleDecorations(state, cell) {
31949
- var _a;
31950
- const decorations = [];
31951
- const $cell = state.doc.resolve(cell);
31952
- const table = $cell.node(-1);
31953
- if (!table) {
31954
- return DecorationSet.empty;
31955
- }
31956
- const map = TableMap.get(table);
31957
- const start = $cell.start(-1);
31958
- const col = map.colCount($cell.pos - start) + $cell.nodeAfter.attrs.colspan - 1;
31959
- for (let row = 0; row < map.height; row++) {
31960
- const index = col + row * map.width;
31961
- if ((col == map.width - 1 || map.map[index] != map.map[index + 1]) && (row == 0 || map.map[index] != map.map[index - map.width])) {
31962
- const cellPos = map.map[index];
31963
- const pos = start + cellPos + table.nodeAt(cellPos).nodeSize - 1;
31964
- const dom = document.createElement("div");
31965
- dom.className = "column-resize-handle";
31966
- if ((_a = columnResizingPluginKey.getState(state)) == null ? void 0 : _a.dragging) {
31967
- decorations.push(
31968
- Decoration.node(
31969
- start + cellPos,
31970
- start + cellPos + table.nodeAt(cellPos).nodeSize,
31971
- {
31972
- class: "column-resize-dragging"
31973
- }
31974
- )
31975
- );
31976
- }
31977
- decorations.push(Decoration.widget(pos, dom));
31978
- }
31979
- }
31980
- return DecorationSet.create(state.doc, decorations);
31981
- }
31982
-
31983
- // src/index.ts
31984
- function tableEditing({
31985
- allowTableNodeSelection = false
31986
- } = {}) {
31987
- return new Plugin({
31988
- key: tableEditingKey,
31989
- // This piece of state is used to remember when a mouse-drag
31990
- // cell-selection is happening, so that it can continue even as
31991
- // transactions (which might move its anchor cell) come in.
31992
- state: {
31993
- init() {
31994
- return null;
31995
- },
31996
- apply(tr, cur) {
31997
- const set = tr.getMeta(tableEditingKey);
31998
- if (set != null) return set == -1 ? null : set;
31999
- if (cur == null || !tr.docChanged) return cur;
32000
- const { deleted, pos } = tr.mapping.mapResult(cur);
32001
- return deleted ? null : pos;
32002
- }
32003
- },
32004
- props: {
32005
- decorations: drawCellSelection,
32006
- handleDOMEvents: {
32007
- mousedown: handleMouseDown
32008
- },
32009
- createSelectionBetween(view) {
32010
- return tableEditingKey.getState(view.state) != null ? view.state.selection : null;
32011
- },
32012
- handleTripleClick,
32013
- handleKeyDown,
32014
- handlePaste
32015
- },
32016
- appendTransaction(_, oldState, state) {
32017
- return normalizeSelection(
32018
- state,
32019
- fixTables(state, oldState),
32020
- allowTableNodeSelection
32021
- );
32022
- }
32023
- });
31978
+ const decorations = [];
31979
+ const $cell = state.doc.resolve(cell);
31980
+ const table = $cell.node(-1);
31981
+ if (!table) return DecorationSet.empty;
31982
+ const map = TableMap.get(table);
31983
+ const start = $cell.start(-1);
31984
+ const col = map.colCount($cell.pos - start) + $cell.nodeAfter.attrs.colspan - 1;
31985
+ for (let row = 0; row < map.height; row++) {
31986
+ const index = col + row * map.width;
31987
+ if ((col == map.width - 1 || map.map[index] != map.map[index + 1]) && (row == 0 || map.map[index] != map.map[index - map.width])) {
31988
+ var _columnResizingPlugin;
31989
+ const cellPos = map.map[index];
31990
+ const pos = start + cellPos + table.nodeAt(cellPos).nodeSize - 1;
31991
+ const dom = document.createElement("div");
31992
+ dom.className = "column-resize-handle";
31993
+ if ((_columnResizingPlugin = columnResizingPluginKey.getState(state)) === null || _columnResizingPlugin === void 0 ? void 0 : _columnResizingPlugin.dragging) decorations.push(Decoration.node(start + cellPos, start + cellPos + table.nodeAt(cellPos).nodeSize, { class: "column-resize-dragging" }));
31994
+ decorations.push(Decoration.widget(pos, dom));
31995
+ }
31996
+ }
31997
+ return DecorationSet.create(state.doc, decorations);
31998
+ }
31999
+
32000
+ //#endregion
32001
+ //#region src/index.ts
32002
+ /**
32003
+ * Creates a [plugin](http://prosemirror.net/docs/ref/#state.Plugin)
32004
+ * that, when added to an editor, enables cell-selection, handles
32005
+ * cell-based copy/paste, and makes sure tables stay well-formed (each
32006
+ * row has the same width, and cells don't overlap).
32007
+ *
32008
+ * You should probably put this plugin near the end of your array of
32009
+ * plugins, since it handles mouse and arrow key events in tables
32010
+ * rather broadly, and other plugins, like the gap cursor or the
32011
+ * column-width dragging plugin, might want to get a turn first to
32012
+ * perform more specific behavior.
32013
+ *
32014
+ * @public
32015
+ */
32016
+ function tableEditing({ allowTableNodeSelection = false } = {}) {
32017
+ return new Plugin({
32018
+ key: tableEditingKey,
32019
+ state: {
32020
+ init() {
32021
+ return null;
32022
+ },
32023
+ apply(tr, cur) {
32024
+ const set = tr.getMeta(tableEditingKey);
32025
+ if (set != null) return set == -1 ? null : set;
32026
+ if (cur == null || !tr.docChanged) return cur;
32027
+ const { deleted, pos } = tr.mapping.mapResult(cur);
32028
+ return deleted ? null : pos;
32029
+ }
32030
+ },
32031
+ props: {
32032
+ decorations: drawCellSelection,
32033
+ handleDOMEvents: { mousedown: handleMouseDown$1 },
32034
+ createSelectionBetween(view) {
32035
+ return tableEditingKey.getState(view.state) != null ? view.state.selection : null;
32036
+ },
32037
+ handleTripleClick,
32038
+ handleKeyDown,
32039
+ handlePaste
32040
+ },
32041
+ appendTransaction(_, oldState, state) {
32042
+ return normalizeSelection(state, fixTables(state, oldState), allowTableNodeSelection);
32043
+ }
32044
+ });
32024
32045
  }
32025
32046
 
32026
32047
  // src/cell/table-cell.ts
@@ -44088,7 +44109,7 @@ function parseConfig(config) {
44088
44109
  }
44089
44110
  }
44090
44111
 
44091
- const version = "4.0.0-alpha.43";
44112
+ const version = "4.0.0-alpha.44";
44092
44113
  function attachDraftSwitcher(engine) {
44093
44114
  if (engine.hasDraft()) {
44094
44115
  const container = document.createElement("div");