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

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;
@@ -4486,11 +4613,11 @@ class BurgerEditorEngine {
4486
4613
  }
4487
4614
  }
4488
4615
 
4489
- const IconAlignBoxCenterStretch = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class=\"icon icon-tabler icons-tabler-outline icon-tabler-align-box-center-stretch\"\n>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M3 19v-14a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2z\" />\n <path d=\"M11 17h2\" />\n <path d=\"M9 12h6\" />\n <path d=\"M10 7h4\" />\n</svg>";
4616
+ const IconAlignBoxCenterStretch = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class=\"icon icon-tabler icons-tabler-outline icon-tabler-align-box-center-stretch\"\n>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M3 19v-14a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2\" />\n <path d=\"M11 17h2\" />\n <path d=\"M9 12h6\" />\n <path d=\"M10 7h4\" />\n</svg>";
4490
4617
 
4491
4618
  const IconBlockquote = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class=\"icon icon-tabler icons-tabler-outline icon-tabler-blockquote\"\n>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M6 15h15\" />\n <path d=\"M21 19h-15\" />\n <path d=\"M15 11h6\" />\n <path d=\"M21 7h-6\" />\n <path d=\"M9 9h1a1 1 0 1 1 -1 1v-2.5a2 2 0 0 1 2 -2\" />\n <path d=\"M3 9h1a1 1 0 1 1 -1 1v-2.5a2 2 0 0 1 2 -2\" />\n</svg>";
4492
4619
 
4493
- const IconBold = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class=\"icon icon-tabler icons-tabler-outline icon-tabler-bold\"\n>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M7 5h6a3.5 3.5 0 0 1 0 7h-6z\" />\n <path d=\"M13 12h1a3.5 3.5 0 0 1 0 7h-7v-7\" />\n</svg>";
4620
+ const IconBold = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class=\"icon icon-tabler icons-tabler-outline icon-tabler-bold\"\n>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M7 5h6a3.5 3.5 0 0 1 0 7h-6l0 -7\" />\n <path d=\"M13 12h1a3.5 3.5 0 0 1 0 7h-7v-7\" />\n</svg>";
4494
4621
 
4495
4622
  const IconCloud = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class=\"icon icon-tabler icons-tabler-outline icon-tabler-cloud\"\n>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M6.657 18c-2.572 0 -4.657 -2.007 -4.657 -4.483c0 -2.475 2.085 -4.482 4.657 -4.482c.393 -1.762 1.794 -3.2 3.675 -3.773c1.88 -.572 3.956 -.193 5.444 1c1.488 1.19 2.162 3.007 1.77 4.769h.99c1.913 0 3.464 1.56 3.464 3.486c0 1.927 -1.551 3.487 -3.465 3.487h-11.878\" />\n</svg>";
4496
4623
 
@@ -4506,7 +4633,7 @@ const IconH4 = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n
4506
4633
 
4507
4634
  const IconH5 = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class=\"icon icon-tabler icons-tabler-outline icon-tabler-h-5\"\n>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M17 18h2a2 2 0 1 0 0 -4h-2v-4h4\" />\n <path d=\"M4 6v12\" />\n <path d=\"M12 6v12\" />\n <path d=\"M11 18h2\" />\n <path d=\"M3 18h2\" />\n <path d=\"M4 12h8\" />\n <path d=\"M3 6h2\" />\n <path d=\"M11 6h2\" />\n</svg>";
4508
4635
 
4509
- const IconH6 = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class=\"icon icon-tabler icons-tabler-outline icon-tabler-h-6\"\n>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M19 14a2 2 0 1 0 0 4a2 2 0 0 0 0 -4z\" />\n <path d=\"M21 12a2 2 0 1 0 -4 0v4\" />\n <path d=\"M4 6v12\" />\n <path d=\"M12 6v12\" />\n <path d=\"M11 18h2\" />\n <path d=\"M3 18h2\" />\n <path d=\"M4 12h8\" />\n <path d=\"M3 6h2\" />\n <path d=\"M11 6h2\" />\n</svg>";
4636
+ const IconH6 = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class=\"icon icon-tabler icons-tabler-outline icon-tabler-h-6\"\n>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M19 14a2 2 0 1 0 0 4a2 2 0 0 0 0 -4\" />\n <path d=\"M21 12a2 2 0 1 0 -4 0v4\" />\n <path d=\"M4 6v12\" />\n <path d=\"M12 6v12\" />\n <path d=\"M11 18h2\" />\n <path d=\"M3 18h2\" />\n <path d=\"M4 12h8\" />\n <path d=\"M3 6h2\" />\n <path d=\"M11 6h2\" />\n</svg>";
4510
4637
 
4511
4638
  const IconItalic = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class=\"icon icon-tabler icons-tabler-outline icon-tabler-italic\"\n>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M11 5l6 0\" />\n <path d=\"M7 19l6 0\" />\n <path d=\"M14 5l-4 14\" />\n</svg>";
4512
4639
 
@@ -4516,7 +4643,7 @@ const IconOrderedList = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\
4516
4643
 
4517
4644
  const IconBulletList = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class=\"icon icon-tabler icons-tabler-outline icon-tabler-list\"\n>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M9 6l11 0\" />\n <path d=\"M9 12l11 0\" />\n <path d=\"M9 18l11 0\" />\n <path d=\"M5 6l0 .01\" />\n <path d=\"M5 12l0 .01\" />\n <path d=\"M5 18l0 .01\" />\n</svg>";
4518
4645
 
4519
- const IconNotes = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class=\"icon icon-tabler icons-tabler-outline icon-tabler-notes\"\n>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M5 3m0 2a2 2 0 0 1 2 -2h10a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2z\" />\n <path d=\"M9 7l6 0\" />\n <path d=\"M9 11l6 0\" />\n <path d=\"M9 15l4 0\" />\n</svg>";
4646
+ const IconNotes = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class=\"icon icon-tabler icons-tabler-outline icon-tabler-notes\"\n>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M5 5a2 2 0 0 1 2 -2h10a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2l0 -14\" />\n <path d=\"M9 7l6 0\" />\n <path d=\"M9 11l6 0\" />\n <path d=\"M9 15l4 0\" />\n</svg>";
4520
4647
 
4521
4648
  const IconStrikethrough = "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class=\"icon icon-tabler icons-tabler-outline icon-tabler-strikethrough\"\n>\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n <path d=\"M5 12l14 0\" />\n <path d=\"M16 6.5a4 2 0 0 0 -4 -1.5h-1a3.5 3.5 0 0 0 0 7h2a3.5 3.5 0 0 1 0 7h-1.5a4 2 0 0 1 -4 -1.5\" />\n</svg>";
4522
4649
 
@@ -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());
@@ -21420,6 +21591,35 @@ var ExtensionManager = class {
21420
21591
  })
21421
21592
  );
21422
21593
  }
21594
+ /**
21595
+ * Get the composed dispatchTransaction function from all extensions.
21596
+ * @param baseDispatch The base dispatch function (e.g. from the editor or user props)
21597
+ * @returns A composed dispatch function
21598
+ */
21599
+ dispatchTransaction(baseDispatch) {
21600
+ const { editor } = this;
21601
+ const extensions = sortExtensions([...this.extensions].reverse());
21602
+ return extensions.reduceRight((next, extension) => {
21603
+ const context = {
21604
+ name: extension.name,
21605
+ options: extension.options,
21606
+ storage: this.editor.extensionStorage[extension.name],
21607
+ editor,
21608
+ type: getSchemaTypeByName(extension.name, this.schema)
21609
+ };
21610
+ const dispatchTransaction = getExtensionField(
21611
+ extension,
21612
+ "dispatchTransaction",
21613
+ context
21614
+ );
21615
+ if (!dispatchTransaction) {
21616
+ return next;
21617
+ }
21618
+ return (transaction) => {
21619
+ dispatchTransaction.call(context, { transaction, next });
21620
+ };
21621
+ }, baseDispatch);
21622
+ }
21423
21623
  get markViews() {
21424
21624
  const { editor } = this;
21425
21625
  const { markExtensions } = splitExtensions(this.extensions);
@@ -22254,7 +22454,8 @@ var Editor = class extends EventEmitter {
22254
22454
  },
22255
22455
  onPaste: () => null,
22256
22456
  onDrop: () => null,
22257
- onDelete: () => null
22457
+ onDelete: () => null,
22458
+ enableExtensionDispatchTransaction: true
22258
22459
  };
22259
22460
  this.isCapturingTransaction = false;
22260
22461
  this.capturedTransaction = null;
@@ -22578,15 +22779,17 @@ var Editor = class extends EventEmitter {
22578
22779
  * Creates a ProseMirror view.
22579
22780
  */
22580
22781
  createView(element) {
22581
- var _a;
22782
+ const { editorProps, enableExtensionDispatchTransaction } = this.options;
22783
+ const baseDispatch = editorProps.dispatchTransaction || this.dispatchTransaction.bind(this);
22784
+ const dispatch = enableExtensionDispatchTransaction ? this.extensionManager.dispatchTransaction(baseDispatch) : baseDispatch;
22582
22785
  this.editorView = new EditorView(element, {
22583
- ...this.options.editorProps,
22786
+ ...editorProps,
22584
22787
  attributes: {
22585
22788
  // add `role="textbox"` to the editor element
22586
22789
  role: "textbox",
22587
- ...(_a = this.options.editorProps) == null ? void 0 : _a.attributes
22790
+ ...editorProps == null ? void 0 : editorProps.attributes
22588
22791
  },
22589
- dispatchTransaction: this.dispatchTransaction.bind(this),
22792
+ dispatchTransaction: dispatch,
22590
22793
  state: this.editorState,
22591
22794
  markViews: this.extensionManager.markViews,
22592
22795
  nodeViews: this.extensionManager.nodeViews
@@ -28554,6 +28757,9 @@ class GapBookmark {
28554
28757
  return GapCursor.valid($pos) ? new GapCursor($pos) : Selection.near($pos);
28555
28758
  }
28556
28759
  }
28760
+ function needsGap(type) {
28761
+ return type.isAtom || type.spec.isolating || type.spec.createGapCursor;
28762
+ }
28557
28763
  function closedBefore($pos) {
28558
28764
  for (let d = $pos.depth; d >= 0; d--) {
28559
28765
  let index = $pos.index(d), parent = $pos.node(d);
@@ -28565,7 +28771,7 @@ function closedBefore($pos) {
28565
28771
  }
28566
28772
  // See if the node before (or its first ancestor) is closed
28567
28773
  for (let before = parent.child(index - 1);; before = before.lastChild) {
28568
- if ((before.childCount == 0 && !before.inlineContent) || before.isAtom || before.type.spec.isolating)
28774
+ if ((before.childCount == 0 && !before.inlineContent) || needsGap(before.type))
28569
28775
  return true;
28570
28776
  if (before.inlineContent)
28571
28777
  return false;
@@ -28583,7 +28789,7 @@ function closedAfter($pos) {
28583
28789
  continue;
28584
28790
  }
28585
28791
  for (let after = parent.child(index);; after = after.firstChild) {
28586
- if ((after.childCount == 0 && !after.inlineContent) || after.isAtom || after.type.spec.isolating)
28792
+ if ((after.childCount == 0 && !after.inlineContent) || needsGap(after.type))
28587
28793
  return true;
28588
28794
  if (after.inlineContent)
28589
28795
  return false;
@@ -29262,7 +29468,7 @@ function history(config = {}) {
29262
29468
  beforeinput(view, e) {
29263
29469
  let inputType = e.inputType;
29264
29470
  let command = inputType == "historyUndo" ? undo : inputType == "historyRedo" ? redo : null;
29265
- if (!command)
29471
+ if (!command || !view.editable)
29266
29472
  return false;
29267
29473
  e.preventDefault();
29268
29474
  return command(view.state, view.dispatch);
@@ -29871,2156 +30077,2003 @@ var Image$2 = Node3.create({
29871
30077
  }
29872
30078
  });
29873
30079
 
29874
- // src/index.ts
29875
-
29876
- // src/tablemap.ts
29877
- var readFromCache;
29878
- var addToCache;
30080
+ //#region src/tablemap.ts
30081
+ let readFromCache;
30082
+ let addToCache;
29879
30083
  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
- };
30084
+ let cache = /* @__PURE__ */ new WeakMap();
30085
+ readFromCache = (key) => cache.get(key);
30086
+ addToCache = (key, value) => {
30087
+ cache.set(key, value);
30088
+ return value;
30089
+ };
29886
30090
  } 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
- };
30091
+ const cache = [];
30092
+ const cacheSize = 10;
30093
+ let cachePos = 0;
30094
+ readFromCache = (key) => {
30095
+ for (let i = 0; i < cache.length; i += 2) if (cache[i] == key) return cache[i + 1];
30096
+ };
30097
+ addToCache = (key, value) => {
30098
+ if (cachePos == cacheSize) cachePos = 0;
30099
+ cache[cachePos++] = key;
30100
+ return cache[cachePos++] = value;
30101
+ };
29899
30102
  }
30103
+ /**
30104
+ * A table map describes the structure of a given table. To avoid
30105
+ * recomputing them all the time, they are cached per table node. To
30106
+ * be able to do that, positions saved in the map are relative to the
30107
+ * start of the table, rather than the start of the document.
30108
+ *
30109
+ * @public
30110
+ */
29900
30111
  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
- }
30112
+ constructor(width, height, map, problems) {
30113
+ this.width = width;
30114
+ this.height = height;
30115
+ this.map = map;
30116
+ this.problems = problems;
30117
+ }
30118
+ findCell(pos) {
30119
+ for (let i = 0; i < this.map.length; i++) {
30120
+ const curPos = this.map[i];
30121
+ if (curPos != pos) continue;
30122
+ const left = i % this.width;
30123
+ const top = i / this.width | 0;
30124
+ let right = left + 1;
30125
+ let bottom = top + 1;
30126
+ for (let j = 1; right < this.width && this.map[i + j] == curPos; j++) right++;
30127
+ for (let j = 1; bottom < this.height && this.map[i + this.width * j] == curPos; j++) bottom++;
30128
+ return {
30129
+ left,
30130
+ top,
30131
+ right,
30132
+ bottom
30133
+ };
30134
+ }
30135
+ throw new RangeError(`No cell with offset ${pos} found`);
30136
+ }
30137
+ colCount(pos) {
30138
+ for (let i = 0; i < this.map.length; i++) if (this.map[i] == pos) return i % this.width;
30139
+ throw new RangeError(`No cell with offset ${pos} found`);
30140
+ }
30141
+ nextCell(pos, axis, dir) {
30142
+ const { left, right, top, bottom } = this.findCell(pos);
30143
+ if (axis == "horiz") {
30144
+ if (dir < 0 ? left == 0 : right == this.width) return null;
30145
+ return this.map[top * this.width + (dir < 0 ? left - 1 : right)];
30146
+ } else {
30147
+ if (dir < 0 ? top == 0 : bottom == this.height) return null;
30148
+ return this.map[left + this.width * (dir < 0 ? top - 1 : bottom)];
30149
+ }
30150
+ }
30151
+ rectBetween(a, b) {
30152
+ const { left: leftA, right: rightA, top: topA, bottom: bottomA } = this.findCell(a);
30153
+ const { left: leftB, right: rightB, top: topB, bottom: bottomB } = this.findCell(b);
30154
+ return {
30155
+ left: Math.min(leftA, leftB),
30156
+ top: Math.min(topA, topB),
30157
+ right: Math.max(rightA, rightB),
30158
+ bottom: Math.max(bottomA, bottomB)
30159
+ };
30160
+ }
30161
+ cellsInRect(rect) {
30162
+ const result = [];
30163
+ const seen = {};
30164
+ for (let row = rect.top; row < rect.bottom; row++) for (let col = rect.left; col < rect.right; col++) {
30165
+ const index = row * this.width + col;
30166
+ const pos = this.map[index];
30167
+ if (seen[pos]) continue;
30168
+ seen[pos] = true;
30169
+ if (col == rect.left && col && this.map[index - 1] == pos || row == rect.top && row && this.map[index - this.width] == pos) continue;
30170
+ result.push(pos);
30171
+ }
30172
+ return result;
30173
+ }
30174
+ positionAt(row, col, table) {
30175
+ for (let i = 0, rowStart = 0;; i++) {
30176
+ const rowEnd = rowStart + table.child(i).nodeSize;
30177
+ if (i == row) {
30178
+ let index = col + row * this.width;
30179
+ const rowEndIndex = (row + 1) * this.width;
30180
+ while (index < rowEndIndex && this.map[index] < rowStart) index++;
30181
+ return index == rowEndIndex ? rowEnd - 1 : this.map[index];
30182
+ }
30183
+ rowStart = rowEnd;
30184
+ }
30185
+ }
30186
+ static get(table) {
30187
+ return readFromCache(table) || addToCache(table, computeMap(table));
30188
+ }
30005
30189
  };
30006
30190
  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;
30191
+ if (table.type.spec.tableRole != "table") throw new RangeError("Not a table node: " + table.type.name);
30192
+ const width = findWidth(table), height = table.childCount;
30193
+ const map = [];
30194
+ let mapPos = 0;
30195
+ let problems = null;
30196
+ const colWidths = [];
30197
+ for (let i = 0, e = width * height; i < e; i++) map[i] = 0;
30198
+ for (let row = 0, pos = 0; row < height; row++) {
30199
+ const rowNode = table.child(row);
30200
+ pos++;
30201
+ for (let i = 0;; i++) {
30202
+ while (mapPos < map.length && map[mapPos] != 0) mapPos++;
30203
+ if (i == rowNode.childCount) break;
30204
+ const cellNode = rowNode.child(i);
30205
+ const { colspan, rowspan, colwidth } = cellNode.attrs;
30206
+ for (let h = 0; h < rowspan; h++) {
30207
+ if (h + row >= height) {
30208
+ (problems || (problems = [])).push({
30209
+ type: "overlong_rowspan",
30210
+ pos,
30211
+ n: rowspan - h
30212
+ });
30213
+ break;
30214
+ }
30215
+ const start = mapPos + h * width;
30216
+ for (let w = 0; w < colspan; w++) {
30217
+ if (map[start + w] == 0) map[start + w] = pos;
30218
+ else (problems || (problems = [])).push({
30219
+ type: "collision",
30220
+ row,
30221
+ pos,
30222
+ n: colspan - w
30223
+ });
30224
+ const colW = colwidth && colwidth[w];
30225
+ if (colW) {
30226
+ const widthIndex = (start + w) % width * 2, prev = colWidths[widthIndex];
30227
+ if (prev == null || prev != colW && colWidths[widthIndex + 1] == 1) {
30228
+ colWidths[widthIndex] = colW;
30229
+ colWidths[widthIndex + 1] = 1;
30230
+ } else if (prev == colW) colWidths[widthIndex + 1]++;
30231
+ }
30232
+ }
30233
+ }
30234
+ mapPos += colspan;
30235
+ pos += cellNode.nodeSize;
30236
+ }
30237
+ const expectedPos = (row + 1) * width;
30238
+ let missing = 0;
30239
+ while (mapPos < expectedPos) if (map[mapPos++] == 0) missing++;
30240
+ if (missing) (problems || (problems = [])).push({
30241
+ type: "missing",
30242
+ row,
30243
+ n: missing
30244
+ });
30245
+ pos++;
30246
+ }
30247
+ if (width === 0 || height === 0) (problems || (problems = [])).push({ type: "zero_sized" });
30248
+ const tableMap = new TableMap(width, height, map, problems);
30249
+ let badWidths = false;
30250
+ for (let i = 0; !badWidths && i < colWidths.length; i += 2) if (colWidths[i] != null && colWidths[i + 1] < height) badWidths = true;
30251
+ if (badWidths) findBadColWidths(tableMap, colWidths, table);
30252
+ return tableMap;
30072
30253
  }
30073
30254
  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;
30255
+ let width = -1;
30256
+ let hasRowSpan = false;
30257
+ for (let row = 0; row < table.childCount; row++) {
30258
+ const rowNode = table.child(row);
30259
+ let rowWidth = 0;
30260
+ if (hasRowSpan) for (let j = 0; j < row; j++) {
30261
+ const prevRow = table.child(j);
30262
+ for (let i = 0; i < prevRow.childCount; i++) {
30263
+ const cell = prevRow.child(i);
30264
+ if (j + cell.attrs.rowspan > row) rowWidth += cell.attrs.colspan;
30265
+ }
30266
+ }
30267
+ for (let i = 0; i < rowNode.childCount; i++) {
30268
+ const cell = rowNode.child(i);
30269
+ rowWidth += cell.attrs.colspan;
30270
+ if (cell.attrs.rowspan > 1) hasRowSpan = true;
30271
+ }
30272
+ if (width == -1) width = rowWidth;
30273
+ else if (width != rowWidth) width = Math.max(width, rowWidth);
30274
+ }
30275
+ return width;
30096
30276
  }
30097
30277
  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
- }
30278
+ if (!map.problems) map.problems = [];
30279
+ const seen = {};
30280
+ for (let i = 0; i < map.map.length; i++) {
30281
+ const pos = map.map[i];
30282
+ if (seen[pos]) continue;
30283
+ seen[pos] = true;
30284
+ const node = table.nodeAt(pos);
30285
+ if (!node) throw new RangeError(`No cell with offset ${pos} found`);
30286
+ let updated = null;
30287
+ const attrs = node.attrs;
30288
+ for (let j = 0; j < attrs.colspan; j++) {
30289
+ const colWidth = colWidths[(i + j) % map.width * 2];
30290
+ if (colWidth != null && (!attrs.colwidth || attrs.colwidth[j] != colWidth)) (updated || (updated = freshColWidth(attrs)))[j] = colWidth;
30291
+ }
30292
+ if (updated) map.problems.unshift({
30293
+ type: "colwidth mismatch",
30294
+ pos,
30295
+ colwidth: updated
30296
+ });
30297
+ }
30123
30298
  }
30124
30299
  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;
30300
+ if (attrs.colwidth) return attrs.colwidth.slice();
30301
+ const result = [];
30302
+ for (let i = 0; i < attrs.colspan; i++) result.push(0);
30303
+ return result;
30129
30304
  }
30305
+ /**
30306
+ * @public
30307
+ */
30130
30308
  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;
30309
+ let result = schema.cached.tableNodeTypes;
30310
+ if (!result) {
30311
+ result = schema.cached.tableNodeTypes = {};
30312
+ for (const name in schema.nodes) {
30313
+ const type = schema.nodes[name], role = type.spec.tableRole;
30314
+ if (role) result[role] = type;
30315
+ }
30316
+ }
30317
+ return result;
30140
30318
  }
30141
30319
 
30142
- // src/util.ts
30143
- var tableEditingKey = new PluginKey("selectingCells");
30320
+ //#endregion
30321
+ //#region src/util.ts
30322
+ /**
30323
+ * @public
30324
+ */
30325
+ const tableEditingKey = new PluginKey("selectingCells");
30326
+ /**
30327
+ * @public
30328
+ */
30144
30329
  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;
30330
+ 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));
30331
+ return null;
30149
30332
  }
30150
30333
  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;
30334
+ for (let d = $pos.depth; d > 0; d--) {
30335
+ const role = $pos.node(d).type.spec.tableRole;
30336
+ if (role === "cell" || role === "header_cell") return $pos.node(d);
30337
+ }
30338
+ return null;
30156
30339
  }
30340
+ /**
30341
+ * @public
30342
+ */
30157
30343
  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;
30344
+ const $head = state.selection.$head;
30345
+ for (let d = $head.depth; d > 0; d--) if ($head.node(d).type.spec.tableRole == "row") return true;
30346
+ return false;
30162
30347
  }
30348
+ /**
30349
+ * @internal
30350
+ */
30163
30351
  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}`);
30352
+ const sel = state.selection;
30353
+ if ("$anchorCell" in sel && sel.$anchorCell) return sel.$anchorCell.pos > sel.$headCell.pos ? sel.$anchorCell : sel.$headCell;
30354
+ else if ("node" in sel && sel.node && sel.node.type.spec.tableRole == "cell") return sel.$anchor;
30355
+ const $cell = cellAround(sel.$head) || cellNear(sel.$head);
30356
+ if ($cell) return $cell;
30357
+ throw new RangeError(`No cell found around position ${sel.head}`);
30175
30358
  }
30359
+ /**
30360
+ * @public
30361
+ */
30176
30362
  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
- }
30363
+ for (let after = $pos.nodeAfter, pos = $pos.pos; after; after = after.firstChild, pos++) {
30364
+ const role = after.type.spec.tableRole;
30365
+ if (role == "cell" || role == "header_cell") return $pos.doc.resolve(pos);
30366
+ }
30367
+ for (let before = $pos.nodeBefore, pos = $pos.pos; before; before = before.lastChild, pos--) {
30368
+ const role = before.type.spec.tableRole;
30369
+ if (role == "cell" || role == "header_cell") return $pos.doc.resolve(pos - before.nodeSize);
30370
+ }
30186
30371
  }
30372
+ /**
30373
+ * @public
30374
+ */
30187
30375
  function pointsAtCell($pos) {
30188
- return $pos.parent.type.spec.tableRole == "row" && !!$pos.nodeAfter;
30376
+ return $pos.parent.type.spec.tableRole == "row" && !!$pos.nodeAfter;
30189
30377
  }
30378
+ /**
30379
+ * @public
30380
+ */
30190
30381
  function moveCellForward($pos) {
30191
- return $pos.node(0).resolve($pos.pos + $pos.nodeAfter.nodeSize);
30382
+ return $pos.node(0).resolve($pos.pos + $pos.nodeAfter.nodeSize);
30192
30383
  }
30384
+ /**
30385
+ * @internal
30386
+ */
30193
30387
  function inSameTable($cellA, $cellB) {
30194
- return $cellA.depth == $cellB.depth && $cellA.pos >= $cellB.start(-1) && $cellA.pos <= $cellB.end(-1);
30388
+ return $cellA.depth == $cellB.depth && $cellA.pos >= $cellB.start(-1) && $cellA.pos <= $cellB.end(-1);
30195
30389
  }
30390
+ /**
30391
+ * @public
30392
+ */
30196
30393
  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);
30394
+ const table = $pos.node(-1);
30395
+ const map = TableMap.get(table);
30396
+ const tableStart = $pos.start(-1);
30397
+ const moved = map.nextCell($pos.pos - tableStart, axis, dir);
30398
+ return moved == null ? null : $pos.node(0).resolve(tableStart + moved);
30202
30399
  }
30400
+ /**
30401
+ * @public
30402
+ */
30203
30403
  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;
30404
+ const result = {
30405
+ ...attrs,
30406
+ colspan: attrs.colspan - n
30407
+ };
30408
+ if (result.colwidth) {
30409
+ result.colwidth = result.colwidth.slice();
30410
+ result.colwidth.splice(pos, n);
30411
+ if (!result.colwidth.some((w) => w > 0)) result.colwidth = null;
30412
+ }
30413
+ return result;
30211
30414
  }
30415
+ /**
30416
+ * @public
30417
+ */
30212
30418
  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;
30419
+ const result = {
30420
+ ...attrs,
30421
+ colspan: attrs.colspan + n
30422
+ };
30423
+ if (result.colwidth) {
30424
+ result.colwidth = result.colwidth.slice();
30425
+ for (let i = 0; i < n; i++) result.colwidth.splice(pos, 0, 0);
30426
+ }
30427
+ return result;
30219
30428
  }
30429
+ /**
30430
+ * @public
30431
+ */
30220
30432
  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;
30433
+ const headerCell = tableNodeTypes(table.type.schema).header_cell;
30434
+ for (let row = 0; row < map.height; row++) if (table.nodeAt(map.map[col + row * map.width]).type != headerCell) return false;
30435
+ return true;
30226
30436
  }
30227
30437
 
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
- }
30438
+ //#endregion
30439
+ //#region src/cellselection.ts
30440
+ /**
30441
+ * A [`Selection`](http://prosemirror.net/docs/ref/#state.Selection)
30442
+ * subclass that represents a cell selection spanning part of a table.
30443
+ * With the plugin enabled, these will be created when the user
30444
+ * selects across cells, and will be drawn by giving selected cells a
30445
+ * `selectedCell` CSS class.
30446
+ *
30447
+ * @public
30448
+ */
30449
+ var CellSelection = class CellSelection extends Selection {
30450
+ constructor($anchorCell, $headCell = $anchorCell) {
30451
+ const table = $anchorCell.node(-1);
30452
+ const map = TableMap.get(table);
30453
+ const tableStart = $anchorCell.start(-1);
30454
+ const rect = map.rectBetween($anchorCell.pos - tableStart, $headCell.pos - tableStart);
30455
+ const doc = $anchorCell.node(0);
30456
+ const cells = map.cellsInRect(rect).filter((p) => p != $headCell.pos - tableStart);
30457
+ cells.unshift($headCell.pos - tableStart);
30458
+ const ranges = cells.map((pos) => {
30459
+ const cell = table.nodeAt(pos);
30460
+ if (!cell) throw new RangeError(`No cell with offset ${pos} found`);
30461
+ const from = tableStart + pos + 1;
30462
+ return new SelectionRange(doc.resolve(from), doc.resolve(from + cell.content.size));
30463
+ });
30464
+ super(ranges[0].$from, ranges[0].$to, ranges);
30465
+ this.$anchorCell = $anchorCell;
30466
+ this.$headCell = $headCell;
30467
+ }
30468
+ map(doc, mapping) {
30469
+ const $anchorCell = doc.resolve(mapping.map(this.$anchorCell.pos));
30470
+ const $headCell = doc.resolve(mapping.map(this.$headCell.pos));
30471
+ if (pointsAtCell($anchorCell) && pointsAtCell($headCell) && inSameTable($anchorCell, $headCell)) {
30472
+ const tableChanged = this.$anchorCell.node(-1) != $anchorCell.node(-1);
30473
+ if (tableChanged && this.isRowSelection()) return CellSelection.rowSelection($anchorCell, $headCell);
30474
+ else if (tableChanged && this.isColSelection()) return CellSelection.colSelection($anchorCell, $headCell);
30475
+ else return new CellSelection($anchorCell, $headCell);
30476
+ }
30477
+ return TextSelection.between($anchorCell, $headCell);
30478
+ }
30479
+ content() {
30480
+ const table = this.$anchorCell.node(-1);
30481
+ const map = TableMap.get(table);
30482
+ const tableStart = this.$anchorCell.start(-1);
30483
+ const rect = map.rectBetween(this.$anchorCell.pos - tableStart, this.$headCell.pos - tableStart);
30484
+ const seen = {};
30485
+ const rows = [];
30486
+ for (let row = rect.top; row < rect.bottom; row++) {
30487
+ const rowContent = [];
30488
+ for (let index = row * map.width + rect.left, col = rect.left; col < rect.right; col++, index++) {
30489
+ const pos = map.map[index];
30490
+ if (seen[pos]) continue;
30491
+ seen[pos] = true;
30492
+ const cellRect = map.findCell(pos);
30493
+ let cell = table.nodeAt(pos);
30494
+ if (!cell) throw new RangeError(`No cell with offset ${pos} found`);
30495
+ const extraLeft = rect.left - cellRect.left;
30496
+ const extraRight = cellRect.right - rect.right;
30497
+ if (extraLeft > 0 || extraRight > 0) {
30498
+ let attrs = cell.attrs;
30499
+ if (extraLeft > 0) attrs = removeColSpan(attrs, 0, extraLeft);
30500
+ if (extraRight > 0) attrs = removeColSpan(attrs, attrs.colspan - extraRight, extraRight);
30501
+ if (cellRect.left < rect.left) {
30502
+ cell = cell.type.createAndFill(attrs);
30503
+ if (!cell) throw new RangeError(`Could not create cell with attrs ${JSON.stringify(attrs)}`);
30504
+ } else cell = cell.type.create(attrs, cell.content);
30505
+ }
30506
+ if (cellRect.top < rect.top || cellRect.bottom > rect.bottom) {
30507
+ const attrs = {
30508
+ ...cell.attrs,
30509
+ rowspan: Math.min(cellRect.bottom, rect.bottom) - Math.max(cellRect.top, rect.top)
30510
+ };
30511
+ if (cellRect.top < rect.top) cell = cell.type.createAndFill(attrs);
30512
+ else cell = cell.type.create(attrs, cell.content);
30513
+ }
30514
+ rowContent.push(cell);
30515
+ }
30516
+ rows.push(table.child(row).copy(Fragment.from(rowContent)));
30517
+ }
30518
+ const fragment = this.isColSelection() && this.isRowSelection() ? table : rows;
30519
+ return new Slice(Fragment.from(fragment), 1, 1);
30520
+ }
30521
+ replace(tr, content = Slice.empty) {
30522
+ const mapFrom = tr.steps.length, ranges = this.ranges;
30523
+ for (let i = 0; i < ranges.length; i++) {
30524
+ const { $from, $to } = ranges[i], mapping = tr.mapping.slice(mapFrom);
30525
+ tr.replace(mapping.map($from.pos), mapping.map($to.pos), i ? Slice.empty : content);
30526
+ }
30527
+ const sel = Selection.findFrom(tr.doc.resolve(tr.mapping.slice(mapFrom).map(this.to)), -1);
30528
+ if (sel) tr.setSelection(sel);
30529
+ }
30530
+ replaceWith(tr, node) {
30531
+ this.replace(tr, new Slice(Fragment.from(node), 0, 0));
30532
+ }
30533
+ forEachCell(f) {
30534
+ const table = this.$anchorCell.node(-1);
30535
+ const map = TableMap.get(table);
30536
+ const tableStart = this.$anchorCell.start(-1);
30537
+ const cells = map.cellsInRect(map.rectBetween(this.$anchorCell.pos - tableStart, this.$headCell.pos - tableStart));
30538
+ for (let i = 0; i < cells.length; i++) f(table.nodeAt(cells[i]), tableStart + cells[i]);
30539
+ }
30540
+ isColSelection() {
30541
+ const anchorTop = this.$anchorCell.index(-1);
30542
+ const headTop = this.$headCell.index(-1);
30543
+ if (Math.min(anchorTop, headTop) > 0) return false;
30544
+ const anchorBottom = anchorTop + this.$anchorCell.nodeAfter.attrs.rowspan;
30545
+ const headBottom = headTop + this.$headCell.nodeAfter.attrs.rowspan;
30546
+ return Math.max(anchorBottom, headBottom) == this.$headCell.node(-1).childCount;
30547
+ }
30548
+ static colSelection($anchorCell, $headCell = $anchorCell) {
30549
+ const table = $anchorCell.node(-1);
30550
+ const map = TableMap.get(table);
30551
+ const tableStart = $anchorCell.start(-1);
30552
+ const anchorRect = map.findCell($anchorCell.pos - tableStart);
30553
+ const headRect = map.findCell($headCell.pos - tableStart);
30554
+ const doc = $anchorCell.node(0);
30555
+ if (anchorRect.top <= headRect.top) {
30556
+ if (anchorRect.top > 0) $anchorCell = doc.resolve(tableStart + map.map[anchorRect.left]);
30557
+ if (headRect.bottom < map.height) $headCell = doc.resolve(tableStart + map.map[map.width * (map.height - 1) + headRect.right - 1]);
30558
+ } else {
30559
+ if (headRect.top > 0) $headCell = doc.resolve(tableStart + map.map[headRect.left]);
30560
+ if (anchorRect.bottom < map.height) $anchorCell = doc.resolve(tableStart + map.map[map.width * (map.height - 1) + anchorRect.right - 1]);
30561
+ }
30562
+ return new CellSelection($anchorCell, $headCell);
30563
+ }
30564
+ isRowSelection() {
30565
+ const table = this.$anchorCell.node(-1);
30566
+ const map = TableMap.get(table);
30567
+ const tableStart = this.$anchorCell.start(-1);
30568
+ const anchorLeft = map.colCount(this.$anchorCell.pos - tableStart);
30569
+ const headLeft = map.colCount(this.$headCell.pos - tableStart);
30570
+ if (Math.min(anchorLeft, headLeft) > 0) return false;
30571
+ const anchorRight = anchorLeft + this.$anchorCell.nodeAfter.attrs.colspan;
30572
+ const headRight = headLeft + this.$headCell.nodeAfter.attrs.colspan;
30573
+ return Math.max(anchorRight, headRight) == map.width;
30574
+ }
30575
+ eq(other) {
30576
+ return other instanceof CellSelection && other.$anchorCell.pos == this.$anchorCell.pos && other.$headCell.pos == this.$headCell.pos;
30577
+ }
30578
+ static rowSelection($anchorCell, $headCell = $anchorCell) {
30579
+ const table = $anchorCell.node(-1);
30580
+ const map = TableMap.get(table);
30581
+ const tableStart = $anchorCell.start(-1);
30582
+ const anchorRect = map.findCell($anchorCell.pos - tableStart);
30583
+ const headRect = map.findCell($headCell.pos - tableStart);
30584
+ const doc = $anchorCell.node(0);
30585
+ if (anchorRect.left <= headRect.left) {
30586
+ if (anchorRect.left > 0) $anchorCell = doc.resolve(tableStart + map.map[anchorRect.top * map.width]);
30587
+ if (headRect.right < map.width) $headCell = doc.resolve(tableStart + map.map[map.width * (headRect.top + 1) - 1]);
30588
+ } else {
30589
+ if (headRect.left > 0) $headCell = doc.resolve(tableStart + map.map[headRect.top * map.width]);
30590
+ if (anchorRect.right < map.width) $anchorCell = doc.resolve(tableStart + map.map[map.width * (anchorRect.top + 1) - 1]);
30591
+ }
30592
+ return new CellSelection($anchorCell, $headCell);
30593
+ }
30594
+ toJSON() {
30595
+ return {
30596
+ type: "cell",
30597
+ anchor: this.$anchorCell.pos,
30598
+ head: this.$headCell.pos
30599
+ };
30600
+ }
30601
+ static fromJSON(doc, json) {
30602
+ return new CellSelection(doc.resolve(json.anchor), doc.resolve(json.head));
30603
+ }
30604
+ static create(doc, anchorCell, headCell = anchorCell) {
30605
+ return new CellSelection(doc.resolve(anchorCell), doc.resolve(headCell));
30606
+ }
30607
+ getBookmark() {
30608
+ return new CellBookmark(this.$anchorCell.pos, this.$headCell.pos);
30609
+ }
30468
30610
  };
30469
30611
  CellSelection.prototype.visible = false;
30470
30612
  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
- }
30613
+ /**
30614
+ * @public
30615
+ */
30616
+ var CellBookmark = class CellBookmark {
30617
+ constructor(anchor, head) {
30618
+ this.anchor = anchor;
30619
+ this.head = head;
30620
+ }
30621
+ map(mapping) {
30622
+ return new CellBookmark(mapping.map(this.anchor), mapping.map(this.head));
30623
+ }
30624
+ resolve(doc) {
30625
+ const $anchorCell = doc.resolve(this.anchor), $headCell = doc.resolve(this.head);
30626
+ 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);
30627
+ else return Selection.near($headCell, 1);
30628
+ }
30485
30629
  };
30486
30630
  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);
30631
+ if (!(state.selection instanceof CellSelection)) return null;
30632
+ const cells = [];
30633
+ state.selection.forEachCell((node, pos) => {
30634
+ cells.push(Decoration.node(pos, pos + node.nodeSize, { class: "selectedCell" }));
30635
+ });
30636
+ return DecorationSet.create(state.doc, cells);
30495
30637
  }
30496
30638
  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);
30639
+ if ($from.pos == $to.pos || $from.pos < $to.pos - 6) return false;
30640
+ let afterFrom = $from.pos;
30641
+ let beforeTo = $to.pos;
30642
+ let depth = $from.depth;
30643
+ for (; depth >= 0; depth--, afterFrom++) if ($from.after(depth + 1) < $from.end(depth)) break;
30644
+ for (let d = $to.depth; d >= 0; d--, beforeTo--) if ($to.before(d + 1) > $to.start(d)) break;
30645
+ return afterFrom == beforeTo && /row|table/.test($from.node(depth).type.spec.tableRole);
30506
30646
  }
30507
30647
  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;
30648
+ let fromCellBoundaryNode;
30649
+ let toCellBoundaryNode;
30650
+ for (let i = $from.depth; i > 0; i--) {
30651
+ const node = $from.node(i);
30652
+ if (node.type.spec.tableRole === "cell" || node.type.spec.tableRole === "header_cell") {
30653
+ fromCellBoundaryNode = node;
30654
+ break;
30655
+ }
30656
+ }
30657
+ for (let i = $to.depth; i > 0; i--) {
30658
+ const node = $to.node(i);
30659
+ if (node.type.spec.tableRole === "cell" || node.type.spec.tableRole === "header_cell") {
30660
+ toCellBoundaryNode = node;
30661
+ break;
30662
+ }
30663
+ }
30664
+ return fromCellBoundaryNode !== toCellBoundaryNode && $to.parentOffset === 0;
30525
30665
  }
30526
30666
  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");
30667
+ const sel = (tr || state).selection;
30668
+ const doc = (tr || state).doc;
30669
+ let normalize;
30670
+ let role;
30671
+ if (sel instanceof NodeSelection && (role = sel.node.type.spec.tableRole)) {
30672
+ if (role == "cell" || role == "header_cell") normalize = CellSelection.create(doc, sel.from);
30673
+ else if (role == "row") {
30674
+ const $cell = doc.resolve(sel.from + 1);
30675
+ normalize = CellSelection.rowSelection($cell, $cell);
30676
+ } else if (!allowTableNodeSelection) {
30677
+ const map = TableMap.get(sel.node);
30678
+ const start = sel.from + 1;
30679
+ const lastCell = start + map.map[map.width * map.height - 1];
30680
+ normalize = CellSelection.create(doc, start + 1, lastCell);
30681
+ }
30682
+ } else if (sel instanceof TextSelection && isCellBoundarySelection(sel)) normalize = TextSelection.create(doc, sel.from);
30683
+ else if (sel instanceof TextSelection && isTextSelectionAcrossCells(sel)) normalize = TextSelection.create(doc, sel.$from.start(), sel.$from.end());
30684
+ if (normalize) (tr || (tr = state.tr)).setSelection(normalize);
30685
+ return tr;
30686
+ }
30687
+
30688
+ //#endregion
30689
+ //#region src/fixtables.ts
30690
+ /**
30691
+ * @public
30692
+ */
30693
+ const fixTablesKey = new PluginKey("fix-tables");
30694
+ /**
30695
+ * Helper for iterating through the nodes in a document that changed
30696
+ * compared to the given previous document. Useful for avoiding
30697
+ * duplicate work on each transaction.
30698
+ *
30699
+ * @public
30700
+ */
30552
30701
  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
- }
30702
+ const oldSize = old.childCount, curSize = cur.childCount;
30703
+ outer: for (let i = 0, j = 0; i < curSize; i++) {
30704
+ const child = cur.child(i);
30705
+ for (let scan = j, e = Math.min(oldSize, i + 3); scan < e; scan++) if (old.child(scan) == child) {
30706
+ j = scan + 1;
30707
+ offset += child.nodeSize;
30708
+ continue outer;
30709
+ }
30710
+ f(child, offset);
30711
+ if (j < oldSize && old.child(j).sameMarkup(child)) changedDescendants(old.child(j), child, offset + 1, f);
30712
+ else child.nodesBetween(0, child.content.size, f, offset + 1);
30713
+ offset += child.nodeSize;
30714
+ }
30569
30715
  }
30716
+ /**
30717
+ * Inspect all tables in the given state's document and return a
30718
+ * transaction that fixes them, if necessary. If `oldState` was
30719
+ * provided, that is assumed to hold a previous, known-good state,
30720
+ * which will be used to avoid re-scanning unchanged parts of the
30721
+ * document.
30722
+ *
30723
+ * @public
30724
+ */
30570
30725
  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;
30726
+ let tr;
30727
+ const check = (node, pos) => {
30728
+ if (node.type.spec.tableRole == "table") tr = fixTable(state, node, pos, tr);
30729
+ };
30730
+ if (!oldState) state.doc.descendants(check);
30731
+ else if (oldState.doc != state.doc) changedDescendants(oldState.doc, state.doc, 0, check);
30732
+ return tr;
30580
30733
  }
30581
30734
  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 });
30735
+ const map = TableMap.get(table);
30736
+ if (!map.problems) return tr;
30737
+ if (!tr) tr = state.tr;
30738
+ const mustAdd = [];
30739
+ for (let i = 0; i < map.height; i++) mustAdd.push(0);
30740
+ for (let i = 0; i < map.problems.length; i++) {
30741
+ const prob = map.problems[i];
30742
+ if (prob.type == "collision") {
30743
+ const cell = table.nodeAt(prob.pos);
30744
+ if (!cell) continue;
30745
+ const attrs = cell.attrs;
30746
+ for (let j = 0; j < attrs.rowspan; j++) mustAdd[prob.row + j] += prob.n;
30747
+ tr.setNodeMarkup(tr.mapping.map(tablePos + 1 + prob.pos), null, removeColSpan(attrs, attrs.colspan - prob.n, prob.n));
30748
+ } else if (prob.type == "missing") mustAdd[prob.row] += prob.n;
30749
+ else if (prob.type == "overlong_rowspan") {
30750
+ const cell = table.nodeAt(prob.pos);
30751
+ if (!cell) continue;
30752
+ tr.setNodeMarkup(tr.mapping.map(tablePos + 1 + prob.pos), null, {
30753
+ ...cell.attrs,
30754
+ rowspan: cell.attrs.rowspan - prob.n
30755
+ });
30756
+ } else if (prob.type == "colwidth mismatch") {
30757
+ const cell = table.nodeAt(prob.pos);
30758
+ if (!cell) continue;
30759
+ tr.setNodeMarkup(tr.mapping.map(tablePos + 1 + prob.pos), null, {
30760
+ ...cell.attrs,
30761
+ colwidth: prob.colwidth
30762
+ });
30763
+ } else if (prob.type == "zero_sized") {
30764
+ const pos = tr.mapping.map(tablePos);
30765
+ tr.delete(pos, pos + table.nodeSize);
30766
+ }
30767
+ }
30768
+ let first, last;
30769
+ for (let i = 0; i < mustAdd.length; i++) if (mustAdd[i]) {
30770
+ if (first == null) first = i;
30771
+ last = i;
30772
+ }
30773
+ for (let i = 0, pos = tablePos + 1; i < map.height; i++) {
30774
+ const row = table.child(i);
30775
+ const end = pos + row.nodeSize;
30776
+ const add = mustAdd[i];
30777
+ if (add > 0) {
30778
+ let role = "cell";
30779
+ if (row.firstChild) role = row.firstChild.type.spec.tableRole;
30780
+ const nodes = [];
30781
+ for (let j = 0; j < add; j++) {
30782
+ const node = tableNodeTypes(state.schema)[role].createAndFill();
30783
+ if (node) nodes.push(node);
30784
+ }
30785
+ const side = (i == 0 || first == i - 1) && last == i ? pos + 1 : end - 1;
30786
+ tr.insert(tr.mapping.map(side), nodes);
30787
+ }
30788
+ pos = end;
30789
+ }
30790
+ return tr.setMeta(fixTablesKey, { fixTables: true });
30646
30791
  }
30792
+
30793
+ //#endregion
30794
+ //#region src/commands.ts
30795
+ /**
30796
+ * Helper to get the selected rectangle in a table, if any. Adds table
30797
+ * map, table node, and table start offset to the object for
30798
+ * convenience.
30799
+ *
30800
+ * @public
30801
+ */
30647
30802
  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 };
30803
+ const sel = state.selection;
30804
+ const $pos = selectionCell(state);
30805
+ const table = $pos.node(-1);
30806
+ const tableStart = $pos.start(-1);
30807
+ const map = TableMap.get(table);
30808
+ return {
30809
+ ...sel instanceof CellSelection ? map.rectBetween(sel.$anchorCell.pos - tableStart, sel.$headCell.pos - tableStart) : map.findCell($pos.pos - tableStart),
30810
+ tableStart,
30811
+ map,
30812
+ table
30813
+ };
30658
30814
  }
30815
+ /**
30816
+ * Add a column at the given position in a table.
30817
+ *
30818
+ * @public
30819
+ */
30659
30820
  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;
30821
+ let refColumn = col > 0 ? -1 : 0;
30822
+ if (columnIsHeader(map, table, col + refColumn)) refColumn = col == 0 || col == map.width ? null : 0;
30823
+ for (let row = 0; row < map.height; row++) {
30824
+ const index = row * map.width + col;
30825
+ if (col > 0 && col < map.width && map.map[index - 1] == map.map[index]) {
30826
+ const pos = map.map[index];
30827
+ const cell = table.nodeAt(pos);
30828
+ tr.setNodeMarkup(tr.mapping.map(tableStart + pos), null, addColSpan(cell.attrs, col - map.colCount(pos)));
30829
+ row += cell.attrs.rowspan - 1;
30830
+ } else {
30831
+ const type = refColumn == null ? tableNodeTypes(table.type.schema).cell : table.nodeAt(map.map[index + refColumn]).type;
30832
+ const pos = map.positionAt(row, col, table);
30833
+ tr.insert(tr.mapping.map(tableStart + pos), type.createAndFill());
30834
+ }
30835
+ }
30836
+ return tr;
30682
30837
  }
30838
+ /**
30839
+ * Command to add a column before the column with the selection.
30840
+ *
30841
+ * @public
30842
+ */
30683
30843
  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;
30844
+ if (!isInTable(state)) return false;
30845
+ if (dispatch) {
30846
+ const rect = selectedRect(state);
30847
+ dispatch(addColumn(state.tr, rect, rect.left));
30848
+ }
30849
+ return true;
30690
30850
  }
30851
+ /**
30852
+ * Command to add a column after the column with the selection.
30853
+ *
30854
+ * @public
30855
+ */
30691
30856
  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;
30857
+ if (!isInTable(state)) return false;
30858
+ if (dispatch) {
30859
+ const rect = selectedRect(state);
30860
+ dispatch(addColumn(state.tr, rect, rect.right));
30861
+ }
30862
+ return true;
30698
30863
  }
30864
+ /**
30865
+ * @public
30866
+ */
30699
30867
  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
- }
30868
+ const mapStart = tr.mapping.maps.length;
30869
+ for (let row = 0; row < map.height;) {
30870
+ const index = row * map.width + col;
30871
+ const pos = map.map[index];
30872
+ const cell = table.nodeAt(pos);
30873
+ const attrs = cell.attrs;
30874
+ 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)));
30875
+ else {
30876
+ const start = tr.mapping.slice(mapStart).map(tableStart + pos);
30877
+ tr.delete(start, start + cell.nodeSize);
30878
+ }
30879
+ row += attrs.rowspan;
30880
+ }
30718
30881
  }
30882
+ /**
30883
+ * Command function that removes the selected columns from a table.
30884
+ *
30885
+ * @public
30886
+ */
30719
30887
  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;
30888
+ if (!isInTable(state)) return false;
30889
+ if (dispatch) {
30890
+ const rect = selectedRect(state);
30891
+ const tr = state.tr;
30892
+ if (rect.left == 0 && rect.right == rect.map.width) return false;
30893
+ for (let i = rect.right - 1;; i--) {
30894
+ removeColumn(tr, rect, i);
30895
+ if (i == rect.left) break;
30896
+ const table = rect.tableStart ? tr.doc.nodeAt(rect.tableStart - 1) : tr.doc;
30897
+ if (!table) throw new RangeError("No table found");
30898
+ rect.table = table;
30899
+ rect.map = TableMap.get(table);
30900
+ }
30901
+ dispatch(tr);
30902
+ }
30903
+ return true;
30738
30904
  }
30905
+ /**
30906
+ * @public
30907
+ */
30739
30908
  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;
30909
+ var _table$nodeAt;
30910
+ const headerCell = tableNodeTypes(table.type.schema).header_cell;
30911
+ 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;
30912
+ return true;
30746
30913
  }
30914
+ /**
30915
+ * @public
30916
+ */
30747
30917
  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;
30918
+ let rowPos = tableStart;
30919
+ for (let i = 0; i < row; i++) rowPos += table.child(i).nodeSize;
30920
+ const cells = [];
30921
+ let refRow = row > 0 ? -1 : 0;
30922
+ if (rowIsHeader(map, table, row + refRow)) refRow = row == 0 || row == map.height ? null : 0;
30923
+ 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]) {
30924
+ const pos = map.map[index];
30925
+ const attrs = table.nodeAt(pos).attrs;
30926
+ tr.setNodeMarkup(tableStart + pos, null, {
30927
+ ...attrs,
30928
+ rowspan: attrs.rowspan + 1
30929
+ });
30930
+ col += attrs.colspan - 1;
30931
+ } else {
30932
+ var _table$nodeAt2;
30933
+ 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;
30934
+ const node = type === null || type === void 0 ? void 0 : type.createAndFill();
30935
+ if (node) cells.push(node);
30936
+ }
30937
+ tr.insert(rowPos, tableNodeTypes(table.type.schema).row.create(null, cells));
30938
+ return tr;
30772
30939
  }
30940
+ /**
30941
+ * Add a table row before the selection.
30942
+ *
30943
+ * @public
30944
+ */
30773
30945
  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;
30946
+ if (!isInTable(state)) return false;
30947
+ if (dispatch) {
30948
+ const rect = selectedRect(state);
30949
+ dispatch(addRow(state.tr, rect, rect.top));
30950
+ }
30951
+ return true;
30780
30952
  }
30953
+ /**
30954
+ * Add a table row after the selection.
30955
+ *
30956
+ * @public
30957
+ */
30781
30958
  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;
30959
+ if (!isInTable(state)) return false;
30960
+ if (dispatch) {
30961
+ const rect = selectedRect(state);
30962
+ dispatch(addRow(state.tr, rect, rect.bottom));
30963
+ }
30964
+ return true;
30788
30965
  }
30966
+ /**
30967
+ * @public
30968
+ */
30789
30969
  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
- }
30970
+ let rowPos = 0;
30971
+ for (let i = 0; i < row; i++) rowPos += table.child(i).nodeSize;
30972
+ const nextRow = rowPos + table.child(row).nodeSize;
30973
+ const mapFrom = tr.mapping.maps.length;
30974
+ tr.delete(rowPos + tableStart, nextRow + tableStart);
30975
+ const seen = /* @__PURE__ */ new Set();
30976
+ for (let col = 0, index = row * map.width; col < map.width; col++, index++) {
30977
+ const pos = map.map[index];
30978
+ if (seen.has(pos)) continue;
30979
+ seen.add(pos);
30980
+ if (row > 0 && pos == map.map[index - map.width]) {
30981
+ const attrs = table.nodeAt(pos).attrs;
30982
+ tr.setNodeMarkup(tr.mapping.slice(mapFrom).map(pos + tableStart), null, {
30983
+ ...attrs,
30984
+ rowspan: attrs.rowspan - 1
30985
+ });
30986
+ col += attrs.colspan - 1;
30987
+ } else if (row < map.height && pos == map.map[index + map.width]) {
30988
+ const cell = table.nodeAt(pos);
30989
+ const attrs = cell.attrs;
30990
+ const copy = cell.type.create({
30991
+ ...attrs,
30992
+ rowspan: cell.attrs.rowspan - 1
30993
+ }, cell.content);
30994
+ const newPos = map.positionAt(row + 1, col, table);
30995
+ tr.insert(tr.mapping.slice(mapFrom).map(tableStart + newPos), copy);
30996
+ col += attrs.colspan - 1;
30997
+ }
30998
+ }
30819
30999
  }
31000
+ /**
31001
+ * Remove the selected rows from a table.
31002
+ *
31003
+ * @public
31004
+ */
30820
31005
  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;
31006
+ if (!isInTable(state)) return false;
31007
+ if (dispatch) {
31008
+ const rect = selectedRect(state), tr = state.tr;
31009
+ if (rect.top == 0 && rect.bottom == rect.map.height) return false;
31010
+ for (let i = rect.bottom - 1;; i--) {
31011
+ removeRow(tr, rect, i);
31012
+ if (i == rect.top) break;
31013
+ const table = rect.tableStart ? tr.doc.nodeAt(rect.tableStart - 1) : tr.doc;
31014
+ if (!table) throw new RangeError("No table found");
31015
+ rect.table = table;
31016
+ rect.map = TableMap.get(rect.table);
31017
+ }
31018
+ dispatch(tr);
31019
+ }
31020
+ return true;
30838
31021
  }
30839
31022
  function isEmpty(cell) {
30840
- const c = cell.content;
30841
- return c.childCount == 1 && c.child(0).isTextblock && c.child(0).childCount == 0;
31023
+ const c = cell.content;
31024
+ return c.childCount == 1 && c.child(0).isTextblock && c.child(0).childCount == 0;
30842
31025
  }
30843
31026
  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;
31027
+ let indexTop = rect.top * width + rect.left, indexLeft = indexTop;
31028
+ let indexBottom = (rect.bottom - 1) * width + rect.left, indexRight = indexTop + (rect.right - rect.left - 1);
31029
+ for (let i = rect.top; i < rect.bottom; i++) {
31030
+ if (rect.left > 0 && map[indexLeft] == map[indexLeft - 1] || rect.right < width && map[indexRight] == map[indexRight + 1]) return true;
31031
+ indexLeft += width;
31032
+ indexRight += width;
31033
+ }
31034
+ for (let i = rect.left; i < rect.right; i++) {
31035
+ if (rect.top > 0 && map[indexTop] == map[indexTop - width] || rect.bottom < height && map[indexBottom] == map[indexBottom + width]) return true;
31036
+ indexTop++;
31037
+ indexBottom++;
31038
+ }
31039
+ return false;
30859
31040
  }
31041
+ /**
31042
+ * Merge the selected cells into a single cell. Only available when
31043
+ * the selected cells' outline forms a rectangle.
31044
+ *
31045
+ * @public
31046
+ */
30860
31047
  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;
31048
+ const sel = state.selection;
31049
+ if (!(sel instanceof CellSelection) || sel.$anchorCell.pos == sel.$headCell.pos) return false;
31050
+ const rect = selectedRect(state), { map } = rect;
31051
+ if (cellsOverlapRectangle(map, rect)) return false;
31052
+ if (dispatch) {
31053
+ const tr = state.tr;
31054
+ const seen = {};
31055
+ let content = Fragment.empty;
31056
+ let mergedPos;
31057
+ let mergedCell;
31058
+ for (let row = rect.top; row < rect.bottom; row++) for (let col = rect.left; col < rect.right; col++) {
31059
+ const cellPos = map.map[row * map.width + col];
31060
+ const cell = rect.table.nodeAt(cellPos);
31061
+ if (seen[cellPos] || !cell) continue;
31062
+ seen[cellPos] = true;
31063
+ if (mergedPos == null) {
31064
+ mergedPos = cellPos;
31065
+ mergedCell = cell;
31066
+ } else {
31067
+ if (!isEmpty(cell)) content = content.append(cell.content);
31068
+ const mapped = tr.mapping.map(cellPos + rect.tableStart);
31069
+ tr.delete(mapped, mapped + cell.nodeSize);
31070
+ }
31071
+ }
31072
+ if (mergedPos == null || mergedCell == null) return true;
31073
+ tr.setNodeMarkup(mergedPos + rect.tableStart, null, {
31074
+ ...addColSpan(mergedCell.attrs, mergedCell.attrs.colspan, rect.right - rect.left - mergedCell.attrs.colspan),
31075
+ rowspan: rect.bottom - rect.top
31076
+ });
31077
+ if (content.size > 0) {
31078
+ const end = mergedPos + 1 + mergedCell.content.size;
31079
+ const start = isEmpty(mergedCell) ? mergedPos + 1 : end;
31080
+ tr.replaceWith(start + rect.tableStart, end + rect.tableStart, content);
31081
+ }
31082
+ tr.setSelection(new CellSelection(tr.doc.resolve(mergedPos + rect.tableStart)));
31083
+ dispatch(tr);
31084
+ }
31085
+ return true;
30910
31086
  }
31087
+ /**
31088
+ * Split a selected cell, whose rowpan or colspan is greater than one,
31089
+ * into smaller cells. Use the first cell type for the new cells.
31090
+ *
31091
+ * @public
31092
+ */
30911
31093
  function splitCell(state, dispatch) {
30912
- const nodeTypes = tableNodeTypes(state.schema);
30913
- return splitCellWithType(({ node }) => {
30914
- return nodeTypes[node.type.spec.tableRole];
30915
- })(state, dispatch);
31094
+ const nodeTypes = tableNodeTypes(state.schema);
31095
+ return splitCellWithType(({ node }) => {
31096
+ return nodeTypes[node.type.spec.tableRole];
31097
+ })(state, dispatch);
30916
31098
  }
31099
+ /**
31100
+ * Split a selected cell, whose rowpan or colspan is greater than one,
31101
+ * into smaller cells with the cell type (th, td) returned by getType function.
31102
+ *
31103
+ * @public
31104
+ */
30917
31105
  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
- };
31106
+ return (state, dispatch) => {
31107
+ const sel = state.selection;
31108
+ let cellNode;
31109
+ let cellPos;
31110
+ if (!(sel instanceof CellSelection)) {
31111
+ var _cellAround;
31112
+ cellNode = cellWrapping(sel.$from);
31113
+ if (!cellNode) return false;
31114
+ cellPos = (_cellAround = cellAround(sel.$from)) === null || _cellAround === void 0 ? void 0 : _cellAround.pos;
31115
+ } else {
31116
+ if (sel.$anchorCell.pos != sel.$headCell.pos) return false;
31117
+ cellNode = sel.$anchorCell.nodeAfter;
31118
+ cellPos = sel.$anchorCell.pos;
31119
+ }
31120
+ if (cellNode == null || cellPos == null) return false;
31121
+ if (cellNode.attrs.colspan == 1 && cellNode.attrs.rowspan == 1) return false;
31122
+ if (dispatch) {
31123
+ let baseAttrs = cellNode.attrs;
31124
+ const attrs = [];
31125
+ const colwidth = baseAttrs.colwidth;
31126
+ if (baseAttrs.rowspan > 1) baseAttrs = {
31127
+ ...baseAttrs,
31128
+ rowspan: 1
31129
+ };
31130
+ if (baseAttrs.colspan > 1) baseAttrs = {
31131
+ ...baseAttrs,
31132
+ colspan: 1
31133
+ };
31134
+ const rect = selectedRect(state), tr = state.tr;
31135
+ for (let i = 0; i < rect.right - rect.left; i++) attrs.push(colwidth ? {
31136
+ ...baseAttrs,
31137
+ colwidth: colwidth && colwidth[i] ? [colwidth[i]] : null
31138
+ } : baseAttrs);
31139
+ let lastCell;
31140
+ for (let row = rect.top; row < rect.bottom; row++) {
31141
+ let pos = rect.map.positionAt(row, rect.left, rect.table);
31142
+ if (row == rect.top) pos += cellNode.nodeSize;
31143
+ for (let col = rect.left, i = 0; col < rect.right; col++, i++) {
31144
+ if (col == rect.left && row == rect.top) continue;
31145
+ tr.insert(lastCell = tr.mapping.map(pos + rect.tableStart, 1), getCellType({
31146
+ node: cellNode,
31147
+ row,
31148
+ col
31149
+ }).createAndFill(attrs[i]));
31150
+ }
31151
+ }
31152
+ tr.setNodeMarkup(cellPos, getCellType({
31153
+ node: cellNode,
31154
+ row: rect.top,
31155
+ col: rect.left
31156
+ }), attrs[0]);
31157
+ if (sel instanceof CellSelection) tr.setSelection(new CellSelection(tr.doc.resolve(sel.$anchorCell.pos), lastCell ? tr.doc.resolve(lastCell) : void 0));
31158
+ dispatch(tr);
31159
+ }
31160
+ return true;
31161
+ };
30980
31162
  }
31163
+ /**
31164
+ * Returns a command that sets the given attribute to the given value,
31165
+ * and is only available when the currently selected cell doesn't
31166
+ * already have that attribute set to that value.
31167
+ *
31168
+ * @public
31169
+ */
30981
31170
  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
- };
31171
+ return function(state, dispatch) {
31172
+ if (!isInTable(state)) return false;
31173
+ const $cell = selectionCell(state);
31174
+ if ($cell.nodeAfter.attrs[name] === value) return false;
31175
+ if (dispatch) {
31176
+ const tr = state.tr;
31177
+ if (state.selection instanceof CellSelection) state.selection.forEachCell((node, pos) => {
31178
+ if (node.attrs[name] !== value) tr.setNodeMarkup(pos, null, {
31179
+ ...node.attrs,
31180
+ [name]: value
31181
+ });
31182
+ });
31183
+ else tr.setNodeMarkup($cell.pos, null, {
31184
+ ...$cell.nodeAfter.attrs,
31185
+ [name]: value
31186
+ });
31187
+ dispatch(tr);
31188
+ }
31189
+ return true;
31190
+ };
31005
31191
  }
31006
31192
  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
- };
31193
+ return function(state, dispatch) {
31194
+ if (!isInTable(state)) return false;
31195
+ if (dispatch) {
31196
+ const types = tableNodeTypes(state.schema);
31197
+ const rect = selectedRect(state), tr = state.tr;
31198
+ const cells = rect.map.cellsInRect(type == "column" ? {
31199
+ left: rect.left,
31200
+ top: 0,
31201
+ right: rect.right,
31202
+ bottom: rect.map.height
31203
+ } : type == "row" ? {
31204
+ left: 0,
31205
+ top: rect.top,
31206
+ right: rect.map.width,
31207
+ bottom: rect.bottom
31208
+ } : rect);
31209
+ const nodes = cells.map((pos) => rect.table.nodeAt(pos));
31210
+ 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);
31211
+ 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);
31212
+ dispatch(tr);
31213
+ }
31214
+ return true;
31215
+ };
31044
31216
  }
31045
31217
  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;
31218
+ const cellPositions = rect.map.cellsInRect({
31219
+ left: 0,
31220
+ top: 0,
31221
+ right: type == "row" ? rect.map.width : 1,
31222
+ bottom: type == "column" ? rect.map.height : 1
31223
+ });
31224
+ for (let i = 0; i < cellPositions.length; i++) {
31225
+ const cell = rect.table.nodeAt(cellPositions[i]);
31226
+ if (cell && cell.type !== types.header_cell) return false;
31227
+ }
31228
+ return true;
31059
31229
  }
31230
+ /**
31231
+ * Toggles between row/column header and normal cells (Only applies to first row/column).
31232
+ * For deprecated behavior pass `useDeprecatedLogic` in options with true.
31233
+ *
31234
+ * @public
31235
+ */
31060
31236
  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
- };
31237
+ options = options || { useDeprecatedLogic: false };
31238
+ if (options.useDeprecatedLogic) return deprecated_toggleHeader(type);
31239
+ return function(state, dispatch) {
31240
+ if (!isInTable(state)) return false;
31241
+ if (dispatch) {
31242
+ const types = tableNodeTypes(state.schema);
31243
+ const rect = selectedRect(state), tr = state.tr;
31244
+ const isHeaderRowEnabled = isHeaderEnabledByType("row", rect, types);
31245
+ const isHeaderColumnEnabled = isHeaderEnabledByType("column", rect, types);
31246
+ const selectionStartsAt = (type === "column" ? isHeaderRowEnabled : type === "row" ? isHeaderColumnEnabled : false) ? 1 : 0;
31247
+ const cellsRect = type == "column" ? {
31248
+ left: 0,
31249
+ top: selectionStartsAt,
31250
+ right: 1,
31251
+ bottom: rect.map.height
31252
+ } : type == "row" ? {
31253
+ left: selectionStartsAt,
31254
+ top: 0,
31255
+ right: rect.map.width,
31256
+ bottom: 1
31257
+ } : rect;
31258
+ const newType = type == "column" ? isHeaderColumnEnabled ? types.cell : types.header_cell : type == "row" ? isHeaderRowEnabled ? types.cell : types.header_cell : types.cell;
31259
+ rect.map.cellsInRect(cellsRect).forEach((relativeCellPos) => {
31260
+ const cellPos = relativeCellPos + rect.tableStart;
31261
+ const cell = tr.doc.nodeAt(cellPos);
31262
+ if (cell) tr.setNodeMarkup(cellPos, newType, cell.attrs);
31263
+ });
31264
+ dispatch(tr);
31265
+ }
31266
+ return true;
31267
+ };
31099
31268
  }
31100
- toggleHeader("row", {
31101
- useDeprecatedLogic: true
31102
- });
31103
- toggleHeader("column", {
31104
- useDeprecatedLogic: true
31105
- });
31106
- var toggleHeaderCell = toggleHeader("cell", {
31107
- useDeprecatedLogic: true
31108
- });
31269
+ /**
31270
+ * Toggles whether the selected row contains header cells.
31271
+ *
31272
+ * @public
31273
+ */
31274
+ toggleHeader("row", { useDeprecatedLogic: true });
31275
+ /**
31276
+ * Toggles whether the selected column contains header cells.
31277
+ *
31278
+ * @public
31279
+ */
31280
+ toggleHeader("column", { useDeprecatedLogic: true });
31281
+ /**
31282
+ * Toggles whether the selected cells are header cells.
31283
+ *
31284
+ * @public
31285
+ */
31286
+ const toggleHeaderCell = toggleHeader("cell", { useDeprecatedLogic: true });
31109
31287
  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;
31288
+ if (dir < 0) {
31289
+ const before = $cell.nodeBefore;
31290
+ if (before) return $cell.pos - before.nodeSize;
31291
+ for (let row = $cell.index(-1) - 1, rowEnd = $cell.before(); row >= 0; row--) {
31292
+ const rowNode = $cell.node(-1).child(row);
31293
+ const lastChild = rowNode.lastChild;
31294
+ if (lastChild) return rowEnd - 1 - lastChild.nodeSize;
31295
+ rowEnd -= rowNode.nodeSize;
31296
+ }
31297
+ } else {
31298
+ if ($cell.index() < $cell.parent.childCount - 1) return $cell.pos + $cell.nodeAfter.nodeSize;
31299
+ const table = $cell.node(-1);
31300
+ for (let row = $cell.indexAfter(-1), rowStart = $cell.after(); row < table.childCount; row++) {
31301
+ const rowNode = table.child(row);
31302
+ if (rowNode.childCount) return rowStart + 1;
31303
+ rowStart += rowNode.nodeSize;
31304
+ }
31305
+ }
31306
+ return null;
31133
31307
  }
31308
+ /**
31309
+ * Returns a command for selecting the next (direction=1) or previous
31310
+ * (direction=-1) cell in a table.
31311
+ *
31312
+ * @public
31313
+ */
31134
31314
  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
- };
31315
+ return function(state, dispatch) {
31316
+ if (!isInTable(state)) return false;
31317
+ const cell = findNextCell(selectionCell(state), direction);
31318
+ if (cell == null) return false;
31319
+ if (dispatch) {
31320
+ const $cell = state.doc.resolve(cell);
31321
+ dispatch(state.tr.setSelection(TextSelection.between($cell, moveCellForward($cell))).scrollIntoView());
31322
+ }
31323
+ return true;
31324
+ };
31147
31325
  }
31326
+ /**
31327
+ * Deletes the table around the selection, if any.
31328
+ *
31329
+ * @public
31330
+ */
31148
31331
  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;
31332
+ const $pos = state.selection.$anchor;
31333
+ for (let d = $pos.depth; d > 0; d--) if ($pos.node(d).type.spec.tableRole == "table") {
31334
+ if (dispatch) dispatch(state.tr.delete($pos.before(d), $pos.after(d)).scrollIntoView());
31335
+ return true;
31336
+ }
31337
+ return false;
31161
31338
  }
31339
+ /**
31340
+ * Deletes the content of the selected cells, if they are not empty.
31341
+ *
31342
+ * @public
31343
+ */
31162
31344
  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;
31345
+ const sel = state.selection;
31346
+ if (!(sel instanceof CellSelection)) return false;
31347
+ if (dispatch) {
31348
+ const tr = state.tr;
31349
+ const baseContent = tableNodeTypes(state.schema).cell.createAndFill().content;
31350
+ sel.forEachCell((cell, pos) => {
31351
+ if (!cell.content.eq(baseContent)) tr.replace(tr.mapping.map(pos + 1), tr.mapping.map(pos + cell.nodeSize - 1), new Slice(baseContent, 0, 0));
31352
+ });
31353
+ if (tr.docChanged) dispatch(tr);
31354
+ }
31355
+ return true;
31179
31356
  }
31357
+
31358
+ //#endregion
31359
+ //#region src/copypaste.ts
31360
+ /**
31361
+ * Get a rectangular area of cells from a slice, or null if the outer
31362
+ * nodes of the slice aren't table cells or rows.
31363
+ *
31364
+ * @internal
31365
+ */
31180
31366
  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);
31367
+ if (slice.size === 0) return null;
31368
+ let { content, openStart, openEnd } = slice;
31369
+ while (content.childCount == 1 && (openStart > 0 && openEnd > 0 || content.child(0).type.spec.tableRole == "table")) {
31370
+ openStart--;
31371
+ openEnd--;
31372
+ content = content.child(0).content;
31373
+ }
31374
+ const first = content.child(0);
31375
+ const role = first.type.spec.tableRole;
31376
+ const schema = first.type.schema, rows = [];
31377
+ if (role == "row") for (let i = 0; i < content.childCount; i++) {
31378
+ let cells = content.child(i).content;
31379
+ const left = i ? 0 : Math.max(0, openStart - 1);
31380
+ const right = i < content.childCount - 1 ? 0 : Math.max(0, openEnd - 1);
31381
+ if (left || right) cells = fitSlice(tableNodeTypes(schema).row, new Slice(cells, left, right)).content;
31382
+ rows.push(cells);
31383
+ }
31384
+ else if (role == "cell" || role == "header_cell") rows.push(openStart || openEnd ? fitSlice(tableNodeTypes(schema).row, new Slice(content, openStart, openEnd)).content : content);
31385
+ else return null;
31386
+ return ensureRectangular(schema, rows);
31214
31387
  }
31215
31388
  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 };
31389
+ const widths = [];
31390
+ for (let i = 0; i < rows.length; i++) {
31391
+ const row = rows[i];
31392
+ for (let j = row.childCount - 1; j >= 0; j--) {
31393
+ const { rowspan, colspan } = row.child(j).attrs;
31394
+ for (let r = i; r < i + rowspan; r++) widths[r] = (widths[r] || 0) + colspan;
31395
+ }
31396
+ }
31397
+ let width = 0;
31398
+ for (let r = 0; r < widths.length; r++) width = Math.max(width, widths[r]);
31399
+ for (let r = 0; r < widths.length; r++) {
31400
+ if (r >= rows.length) rows.push(Fragment.empty);
31401
+ if (widths[r] < width) {
31402
+ const empty = tableNodeTypes(schema).cell.createAndFill();
31403
+ const cells = [];
31404
+ for (let i = widths[r]; i < width; i++) cells.push(empty);
31405
+ rows[r] = rows[r].append(Fragment.from(cells));
31406
+ }
31407
+ }
31408
+ return {
31409
+ height: rows.length,
31410
+ width,
31411
+ rows
31412
+ };
31239
31413
  }
31240
31414
  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;
31415
+ const node = nodeType.createAndFill();
31416
+ return new Transform(node).replace(0, node.content.size, slice).doc;
31244
31417
  }
31418
+ /**
31419
+ * Clip or extend (repeat) the given set of cells to cover the given
31420
+ * width and height. Will clip rowspan/colspan cells at the edges when
31421
+ * they stick out.
31422
+ *
31423
+ * @internal
31424
+ */
31245
31425
  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 };
31426
+ if (width != newWidth) {
31427
+ const added = [];
31428
+ const newRows = [];
31429
+ for (let row = 0; row < rows.length; row++) {
31430
+ const frag = rows[row], cells = [];
31431
+ for (let col = added[row] || 0, i = 0; col < newWidth; i++) {
31432
+ let cell = frag.child(i % frag.childCount);
31433
+ if (col + cell.attrs.colspan > newWidth) cell = cell.type.createChecked(removeColSpan(cell.attrs, cell.attrs.colspan, col + cell.attrs.colspan - newWidth), cell.content);
31434
+ cells.push(cell);
31435
+ col += cell.attrs.colspan;
31436
+ for (let j = 1; j < cell.attrs.rowspan; j++) added[row + j] = (added[row + j] || 0) + cell.attrs.colspan;
31437
+ }
31438
+ newRows.push(Fragment.from(cells));
31439
+ }
31440
+ rows = newRows;
31441
+ width = newWidth;
31442
+ }
31443
+ if (height != newHeight) {
31444
+ const newRows = [];
31445
+ for (let row = 0, i = 0; row < newHeight; row++, i++) {
31446
+ const cells = [], source = rows[i % height];
31447
+ for (let j = 0; j < source.childCount; j++) {
31448
+ let cell = source.child(j);
31449
+ if (row + cell.attrs.rowspan > newHeight) cell = cell.type.create({
31450
+ ...cell.attrs,
31451
+ rowspan: Math.max(1, newHeight - cell.attrs.rowspan)
31452
+ }, cell.content);
31453
+ cells.push(cell);
31454
+ }
31455
+ newRows.push(Fragment.from(cells));
31456
+ }
31457
+ rows = newRows;
31458
+ height = newHeight;
31459
+ }
31460
+ return {
31461
+ width,
31462
+ height,
31463
+ rows
31464
+ };
31294
31465
  }
31295
31466
  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);
31467
+ const schema = tr.doc.type.schema;
31468
+ const types = tableNodeTypes(schema);
31469
+ let empty;
31470
+ let emptyHead;
31471
+ if (width > map.width) for (let row = 0, rowEnd = 0; row < map.height; row++) {
31472
+ const rowNode = table.child(row);
31473
+ rowEnd += rowNode.nodeSize;
31474
+ const cells = [];
31475
+ let add;
31476
+ if (rowNode.lastChild == null || rowNode.lastChild.type == types.cell) add = empty || (empty = types.cell.createAndFill());
31477
+ else add = emptyHead || (emptyHead = types.header_cell.createAndFill());
31478
+ for (let i = map.width; i < width; i++) cells.push(add);
31479
+ tr.insert(tr.mapping.slice(mapFrom).map(rowEnd - 1 + start), cells);
31480
+ }
31481
+ if (height > map.height) {
31482
+ const cells = [];
31483
+ for (let i = 0, start$1 = (map.height - 1) * map.width; i < Math.max(map.width, width); i++) {
31484
+ const header = i >= map.width ? false : table.nodeAt(map.map[start$1 + i]).type == types.header_cell;
31485
+ cells.push(header ? emptyHead || (emptyHead = types.header_cell.createAndFill()) : empty || (empty = types.cell.createAndFill()));
31486
+ }
31487
+ const emptyRow = types.row.create(null, Fragment.from(cells)), rows = [];
31488
+ for (let i = map.height; i < height; i++) rows.push(emptyRow);
31489
+ tr.insert(tr.mapping.slice(mapFrom).map(start + table.nodeSize - 2), rows);
31490
+ }
31491
+ return !!(empty || emptyHead);
31326
31492
  }
31327
31493
  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;
31494
+ if (top == 0 || top == map.height) return false;
31495
+ let found = false;
31496
+ for (let col = left; col < right; col++) {
31497
+ const index = top * map.width + col, pos = map.map[index];
31498
+ if (map.map[index - map.width] == pos) {
31499
+ found = true;
31500
+ const cell = table.nodeAt(pos);
31501
+ const { top: cellTop, left: cellLeft } = map.findCell(pos);
31502
+ tr.setNodeMarkup(tr.mapping.slice(mapFrom).map(pos + start), null, {
31503
+ ...cell.attrs,
31504
+ rowspan: top - cellTop
31505
+ });
31506
+ tr.insert(tr.mapping.slice(mapFrom).map(map.positionAt(top, cellLeft, table)), cell.type.createAndFill({
31507
+ ...cell.attrs,
31508
+ rowspan: cellTop + cell.attrs.rowspan - top
31509
+ }));
31510
+ col += cell.attrs.colspan - 1;
31511
+ }
31512
+ }
31513
+ return found;
31351
31514
  }
31352
31515
  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;
31516
+ if (left == 0 || left == map.width) return false;
31517
+ let found = false;
31518
+ for (let row = top; row < bottom; row++) {
31519
+ const index = row * map.width + left, pos = map.map[index];
31520
+ if (map.map[index - 1] == pos) {
31521
+ found = true;
31522
+ const cell = table.nodeAt(pos);
31523
+ const cellLeft = map.colCount(pos);
31524
+ const updatePos = tr.mapping.slice(mapFrom).map(pos + start);
31525
+ tr.setNodeMarkup(updatePos, null, removeColSpan(cell.attrs, left - cellLeft, cell.attrs.colspan - (left - cellLeft)));
31526
+ tr.insert(updatePos + cell.nodeSize, cell.type.createAndFill(removeColSpan(cell.attrs, 0, left - cellLeft)));
31527
+ row += cell.attrs.rowspan - 1;
31528
+ }
31529
+ }
31530
+ return found;
31381
31531
  }
31532
+ /**
31533
+ * Insert the given set of cells (as returned by `pastedCells`) into a
31534
+ * table, at the position pointed at by rect.
31535
+ *
31536
+ * @internal
31537
+ */
31382
31538
  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
31539
+ let table = tableStart ? state.doc.nodeAt(tableStart - 1) : state.doc;
31540
+ if (!table) throw new Error("No table found");
31541
+ let map = TableMap.get(table);
31542
+ const { top, left } = rect;
31543
+ const right = left + cells.width, bottom = top + cells.height;
31544
+ const tr = state.tr;
31545
+ let mapFrom = 0;
31546
+ function recomp() {
31547
+ table = tableStart ? tr.doc.nodeAt(tableStart - 1) : tr.doc;
31548
+ if (!table) throw new Error("No table found");
31549
+ map = TableMap.get(table);
31550
+ mapFrom = tr.mapping.maps.length;
31551
+ }
31552
+ if (growTable(tr, map, table, tableStart, right, bottom, mapFrom)) recomp();
31553
+ if (isolateHorizontal(tr, map, table, tableStart, left, right, top, mapFrom)) recomp();
31554
+ if (isolateHorizontal(tr, map, table, tableStart, left, right, bottom, mapFrom)) recomp();
31555
+ if (isolateVertical(tr, map, table, tableStart, top, bottom, left, mapFrom)) recomp();
31556
+ if (isolateVertical(tr, map, table, tableStart, top, bottom, right, mapFrom)) recomp();
31557
+ for (let row = top; row < bottom; row++) {
31558
+ const from = map.positionAt(row, left, table), to = map.positionAt(row, right, table);
31559
+ tr.replace(tr.mapping.slice(mapFrom).map(from + tableStart), tr.mapping.slice(mapFrom).map(to + tableStart), new Slice(cells.rows[row - top], 0, 0));
31560
+ }
31561
+ recomp();
31562
+ tr.setSelection(new CellSelection(tr.doc.resolve(tableStart + map.positionAt(top, left, table)), tr.doc.resolve(tableStart + map.positionAt(bottom - 1, right - 1, table))));
31563
+ dispatch(tr);
31564
+ }
31565
+
31566
+ //#endregion
31567
+ //#region src/input.ts
31568
+ const handleKeyDown = keydownHandler({
31569
+ ArrowLeft: arrow("horiz", -1),
31570
+ ArrowRight: arrow("horiz", 1),
31571
+ ArrowUp: arrow("vert", -1),
31572
+ ArrowDown: arrow("vert", 1),
31573
+ "Shift-ArrowLeft": shiftArrow("horiz", -1),
31574
+ "Shift-ArrowRight": shiftArrow("horiz", 1),
31575
+ "Shift-ArrowUp": shiftArrow("vert", -1),
31576
+ "Shift-ArrowDown": shiftArrow("vert", 1),
31577
+ Backspace: deleteCellSelection,
31578
+ "Mod-Backspace": deleteCellSelection,
31579
+ Delete: deleteCellSelection,
31580
+ "Mod-Delete": deleteCellSelection
31441
31581
  });
31442
31582
  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;
31583
+ if (selection.eq(state.selection)) return false;
31584
+ if (dispatch) dispatch(state.tr.setSelection(selection).scrollIntoView());
31585
+ return true;
31446
31586
  }
31587
+ /**
31588
+ * @internal
31589
+ */
31447
31590
  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
- };
31591
+ return (state, dispatch, view) => {
31592
+ if (!view) return false;
31593
+ const sel = state.selection;
31594
+ if (sel instanceof CellSelection) return maybeSetSelection(state, dispatch, Selection.near(sel.$headCell, dir));
31595
+ if (axis != "horiz" && !sel.empty) return false;
31596
+ const end = atEndOfCell(view, axis, dir);
31597
+ if (end == null) return false;
31598
+ if (axis == "horiz") return maybeSetSelection(state, dispatch, Selection.near(state.doc.resolve(sel.head + dir), dir));
31599
+ else {
31600
+ const $cell = state.doc.resolve(end);
31601
+ const $next = nextCell($cell, axis, dir);
31602
+ let newSel;
31603
+ if ($next) newSel = Selection.near($next, 1);
31604
+ else if (dir < 0) newSel = Selection.near(state.doc.resolve($cell.before(-1)), -1);
31605
+ else newSel = Selection.near(state.doc.resolve($cell.after(-1)), 1);
31606
+ return maybeSetSelection(state, dispatch, newSel);
31607
+ }
31608
+ };
31478
31609
  }
31479
31610
  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
- };
31611
+ return (state, dispatch, view) => {
31612
+ if (!view) return false;
31613
+ const sel = state.selection;
31614
+ let cellSel;
31615
+ if (sel instanceof CellSelection) cellSel = sel;
31616
+ else {
31617
+ const end = atEndOfCell(view, axis, dir);
31618
+ if (end == null) return false;
31619
+ cellSel = new CellSelection(state.doc.resolve(end));
31620
+ }
31621
+ const $head = nextCell(cellSel.$headCell, axis, dir);
31622
+ if (!$head) return false;
31623
+ return maybeSetSelection(state, dispatch, new CellSelection(cellSel.$anchorCell, $head));
31624
+ };
31499
31625
  }
31500
31626
  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;
31627
+ const doc = view.state.doc, $cell = cellAround(doc.resolve(pos));
31628
+ if (!$cell) return false;
31629
+ view.dispatch(view.state.tr.setSelection(new CellSelection($cell)));
31630
+ return true;
31505
31631
  }
31632
+ /**
31633
+ * @public
31634
+ */
31506
31635
  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);
31636
+ if (!isInTable(view.state)) return false;
31637
+ let cells = pastedCells(slice);
31638
+ const sel = view.state.selection;
31639
+ if (sel instanceof CellSelection) {
31640
+ if (!cells) cells = {
31641
+ width: 1,
31642
+ height: 1,
31643
+ rows: [Fragment.from(fitSlice(tableNodeTypes(view.state.schema).cell, slice))]
31644
+ };
31645
+ const table = sel.$anchorCell.node(-1);
31646
+ const start = sel.$anchorCell.start(-1);
31647
+ const rect = TableMap.get(table).rectBetween(sel.$anchorCell.pos - start, sel.$headCell.pos - start);
31648
+ cells = clipCells(cells, rect.right - rect.left, rect.bottom - rect.top);
31649
+ insertCells(view.state, view.dispatch, start, rect, cells);
31650
+ return true;
31651
+ } else if (cells) {
31652
+ const $cell = selectionCell(view.state);
31653
+ const start = $cell.start(-1);
31654
+ insertCells(view.state, view.dispatch, start, TableMap.get($cell.node(-1)).findCell($cell.pos - start), cells);
31655
+ return true;
31656
+ } else return false;
31657
+ }
31658
+ function handleMouseDown$1(view, startEvent) {
31659
+ var _cellUnderMouse;
31660
+ if (startEvent.button != 0) return;
31661
+ if (startEvent.ctrlKey || startEvent.metaKey) return;
31662
+ const startDOMCell = domInCell(view, startEvent.target);
31663
+ let $anchor;
31664
+ if (startEvent.shiftKey && view.state.selection instanceof CellSelection) {
31665
+ setCellSelection(view.state.selection.$anchorCell, startEvent);
31666
+ startEvent.preventDefault();
31667
+ } 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) {
31668
+ setCellSelection($anchor, startEvent);
31669
+ startEvent.preventDefault();
31670
+ } else if (!startDOMCell) return;
31671
+ function setCellSelection($anchor$1, event) {
31672
+ let $head = cellUnderMouse(view, event);
31673
+ const starting = tableEditingKey.getState(view.state) == null;
31674
+ if (!$head || !inSameTable($anchor$1, $head)) if (starting) $head = $anchor$1;
31675
+ else return;
31676
+ const selection = new CellSelection($anchor$1, $head);
31677
+ if (starting || !view.state.selection.eq(selection)) {
31678
+ const tr = view.state.tr.setSelection(selection);
31679
+ if (starting) tr.setMeta(tableEditingKey, $anchor$1.pos);
31680
+ view.dispatch(tr);
31681
+ }
31682
+ }
31683
+ function stop() {
31684
+ view.root.removeEventListener("mouseup", stop);
31685
+ view.root.removeEventListener("dragstart", stop);
31686
+ view.root.removeEventListener("mousemove", move);
31687
+ if (tableEditingKey.getState(view.state) != null) view.dispatch(view.state.tr.setMeta(tableEditingKey, -1));
31688
+ }
31689
+ function move(_event) {
31690
+ const event = _event;
31691
+ const anchor = tableEditingKey.getState(view.state);
31692
+ let $anchor$1;
31693
+ if (anchor != null) $anchor$1 = view.state.doc.resolve(anchor);
31694
+ else if (domInCell(view, event.target) != startDOMCell) {
31695
+ $anchor$1 = cellUnderMouse(view, startEvent);
31696
+ if (!$anchor$1) return stop();
31697
+ }
31698
+ if ($anchor$1) setCellSelection($anchor$1, event);
31699
+ }
31700
+ view.root.addEventListener("mouseup", stop);
31701
+ view.root.addEventListener("dragstart", stop);
31702
+ view.root.addEventListener("mousemove", move);
31595
31703
  }
31596
31704
  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;
31705
+ if (!(view.state.selection instanceof TextSelection)) return null;
31706
+ const { $head } = view.state.selection;
31707
+ for (let d = $head.depth - 1; d >= 0; d--) {
31708
+ const parent = $head.node(d);
31709
+ if ((dir < 0 ? $head.index(d) : $head.indexAfter(d)) != (dir < 0 ? 0 : parent.childCount)) return null;
31710
+ if (parent.type.spec.tableRole == "cell" || parent.type.spec.tableRole == "header_cell") {
31711
+ const cellPos = $head.before(d);
31712
+ const dirStr = axis == "vert" ? dir > 0 ? "down" : "up" : dir > 0 ? "right" : "left";
31713
+ return view.endOfTextblock(dirStr) ? cellPos : null;
31714
+ }
31715
+ }
31716
+ return null;
31609
31717
  }
31610
31718
  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;
31719
+ for (; dom && dom != view.dom; dom = dom.parentNode) if (dom.nodeName == "TD" || dom.nodeName == "TH") return dom;
31720
+ return null;
31617
31721
  }
31618
31722
  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;
31723
+ const mousePos = view.posAtCoords({
31724
+ left: event.clientX,
31725
+ top: event.clientY
31726
+ });
31727
+ if (!mousePos) return null;
31728
+ let { inside, pos } = mousePos;
31729
+ return inside >= 0 && cellAround(view.state.doc.resolve(inside)) || cellAround(view.state.doc.resolve(pos));
31625
31730
  }
31626
31731
 
31627
- // src/tableview.ts
31732
+ //#endregion
31733
+ //#region src/tableview.ts
31734
+ /**
31735
+ * @public
31736
+ */
31628
31737
  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
- }
31738
+ constructor(node, defaultCellMinWidth) {
31739
+ this.node = node;
31740
+ this.defaultCellMinWidth = defaultCellMinWidth;
31741
+ this.dom = document.createElement("div");
31742
+ this.dom.className = "tableWrapper";
31743
+ this.table = this.dom.appendChild(document.createElement("table"));
31744
+ this.table.style.setProperty("--default-cell-min-width", `${defaultCellMinWidth}px`);
31745
+ this.colgroup = this.table.appendChild(document.createElement("colgroup"));
31746
+ updateColumnsOnResize(node, this.colgroup, this.table, defaultCellMinWidth);
31747
+ this.contentDOM = this.table.appendChild(document.createElement("tbody"));
31748
+ }
31749
+ update(node) {
31750
+ if (node.type != this.node.type) return false;
31751
+ this.node = node;
31752
+ updateColumnsOnResize(node, this.colgroup, this.table, this.defaultCellMinWidth);
31753
+ return true;
31754
+ }
31755
+ ignoreMutation(record) {
31756
+ return record.type == "attributes" && (record.target == this.table || this.colgroup.contains(record.target));
31757
+ }
31657
31758
  };
31759
+ /**
31760
+ * @public
31761
+ */
31658
31762
  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
- }
31763
+ let totalWidth = 0;
31764
+ let fixedWidth = true;
31765
+ let nextDOM = colgroup.firstChild;
31766
+ const row = node.firstChild;
31767
+ if (!row) return;
31768
+ for (let i = 0, col = 0; i < row.childCount; i++) {
31769
+ const { colspan, colwidth } = row.child(i).attrs;
31770
+ for (let j = 0; j < colspan; j++, col++) {
31771
+ const hasWidth = overrideCol == col ? overrideValue : colwidth && colwidth[j];
31772
+ const cssWidth = hasWidth ? hasWidth + "px" : "";
31773
+ totalWidth += hasWidth || defaultCellMinWidth;
31774
+ if (!hasWidth) fixedWidth = false;
31775
+ if (!nextDOM) {
31776
+ const col$1 = document.createElement("col");
31777
+ col$1.style.width = cssWidth;
31778
+ colgroup.appendChild(col$1);
31779
+ } else {
31780
+ if (nextDOM.style.width != cssWidth) nextDOM.style.width = cssWidth;
31781
+ nextDOM = nextDOM.nextSibling;
31782
+ }
31783
+ }
31784
+ }
31785
+ while (nextDOM) {
31786
+ var _nextDOM$parentNode;
31787
+ const after = nextDOM.nextSibling;
31788
+ (_nextDOM$parentNode = nextDOM.parentNode) === null || _nextDOM$parentNode === void 0 || _nextDOM$parentNode.removeChild(nextDOM);
31789
+ nextDOM = after;
31790
+ }
31791
+ if (fixedWidth) {
31792
+ table.style.width = totalWidth + "px";
31793
+ table.style.minWidth = "";
31794
+ } else {
31795
+ table.style.width = "";
31796
+ table.style.minWidth = totalWidth + "px";
31797
+ }
31696
31798
  }
31697
31799
 
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;
31800
+ //#endregion
31801
+ //#region src/columnresizing.ts
31802
+ /**
31803
+ * @public
31804
+ */
31805
+ const columnResizingPluginKey = new PluginKey("tableColumnResizing");
31806
+ /**
31807
+ * @public
31808
+ */
31809
+ function columnResizing({ handleWidth = 5, cellMinWidth = 25, defaultCellMinWidth = 100, View = TableView$1, lastColumnResizable = true } = {}) {
31810
+ const plugin = new Plugin({
31811
+ key: columnResizingPluginKey,
31812
+ state: {
31813
+ init(_, state) {
31814
+ var _plugin$spec;
31815
+ 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;
31816
+ const tableName = tableNodeTypes(state.schema).table.name;
31817
+ if (View && nodeViews) nodeViews[tableName] = (node, view) => {
31818
+ return new View(node, defaultCellMinWidth, view);
31819
+ };
31820
+ return new ResizeState(-1, false);
31821
+ },
31822
+ apply(tr, prev) {
31823
+ return prev.apply(tr);
31824
+ }
31825
+ },
31826
+ props: {
31827
+ attributes: (state) => {
31828
+ const pluginState = columnResizingPluginKey.getState(state);
31829
+ return pluginState && pluginState.activeHandle > -1 ? { class: "resize-cursor" } : {};
31830
+ },
31831
+ handleDOMEvents: {
31832
+ mousemove: (view, event) => {
31833
+ handleMouseMove(view, event, handleWidth, lastColumnResizable);
31834
+ },
31835
+ mouseleave: (view) => {
31836
+ handleMouseLeave(view);
31837
+ },
31838
+ mousedown: (view, event) => {
31839
+ handleMouseDown(view, event, cellMinWidth, defaultCellMinWidth);
31840
+ }
31841
+ },
31842
+ decorations: (state) => {
31843
+ const pluginState = columnResizingPluginKey.getState(state);
31844
+ if (pluginState && pluginState.activeHandle > -1) return handleDecorations(state, pluginState.activeHandle);
31845
+ },
31846
+ nodeViews: {}
31847
+ }
31848
+ });
31849
+ return plugin;
31753
31850
  }
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
- }
31851
+ /**
31852
+ * @public
31853
+ */
31854
+ var ResizeState = class ResizeState {
31855
+ constructor(activeHandle, dragging) {
31856
+ this.activeHandle = activeHandle;
31857
+ this.dragging = dragging;
31858
+ }
31859
+ apply(tr) {
31860
+ const state = this;
31861
+ const action = tr.getMeta(columnResizingPluginKey);
31862
+ if (action && action.setHandle != null) return new ResizeState(action.setHandle, false);
31863
+ if (action && action.setDragging !== void 0) return new ResizeState(state.activeHandle, action.setDragging);
31864
+ if (state.activeHandle > -1 && tr.docChanged) {
31865
+ let handle = tr.mapping.map(state.activeHandle, -1);
31866
+ if (!pointsAtCell(tr.doc.resolve(handle))) handle = -1;
31867
+ return new ResizeState(handle, state.dragging);
31868
+ }
31869
+ return state;
31870
+ }
31775
31871
  };
31776
31872
  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
- }
31873
+ if (!view.editable) return;
31874
+ const pluginState = columnResizingPluginKey.getState(view.state);
31875
+ if (!pluginState) return;
31876
+ if (!pluginState.dragging) {
31877
+ const target = domCellAround(event.target);
31878
+ let cell = -1;
31879
+ if (target) {
31880
+ const { left, right } = target.getBoundingClientRect();
31881
+ if (event.clientX - left <= handleWidth) cell = edgeCell(view, event, "left", handleWidth);
31882
+ else if (right - event.clientX <= handleWidth) cell = edgeCell(view, event, "right", handleWidth);
31883
+ }
31884
+ if (cell != pluginState.activeHandle) {
31885
+ if (!lastColumnResizable && cell !== -1) {
31886
+ const $cell = view.state.doc.resolve(cell);
31887
+ const table = $cell.node(-1);
31888
+ const map = TableMap.get(table);
31889
+ const tableStart = $cell.start(-1);
31890
+ if (map.colCount($cell.pos - tableStart) + $cell.nodeAfter.attrs.colspan - 1 == map.width - 1) return;
31891
+ }
31892
+ updateHandle(view, cell);
31893
+ }
31894
+ }
31804
31895
  }
31805
31896
  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;
31897
+ if (!view.editable) return;
31898
+ const pluginState = columnResizingPluginKey.getState(view.state);
31899
+ if (pluginState && pluginState.activeHandle > -1 && !pluginState.dragging) updateHandle(view, -1);
31900
+ }
31901
+ function handleMouseDown(view, event, cellMinWidth, defaultCellMinWidth) {
31902
+ var _view$dom$ownerDocume;
31903
+ if (!view.editable) return false;
31904
+ const win = (_view$dom$ownerDocume = view.dom.ownerDocument.defaultView) !== null && _view$dom$ownerDocume !== void 0 ? _view$dom$ownerDocume : window;
31905
+ const pluginState = columnResizingPluginKey.getState(view.state);
31906
+ if (!pluginState || pluginState.activeHandle == -1 || pluginState.dragging) return false;
31907
+ const cell = view.state.doc.nodeAt(pluginState.activeHandle);
31908
+ const width = currentColWidth(view, pluginState.activeHandle, cell.attrs);
31909
+ view.dispatch(view.state.tr.setMeta(columnResizingPluginKey, { setDragging: {
31910
+ startX: event.clientX,
31911
+ startWidth: width
31912
+ } }));
31913
+ function finish(event$1) {
31914
+ win.removeEventListener("mouseup", finish);
31915
+ win.removeEventListener("mousemove", move);
31916
+ const pluginState$1 = columnResizingPluginKey.getState(view.state);
31917
+ if (pluginState$1 === null || pluginState$1 === void 0 ? void 0 : pluginState$1.dragging) {
31918
+ updateColumnWidth(view, pluginState$1.activeHandle, draggedWidth(pluginState$1.dragging, event$1, cellMinWidth));
31919
+ view.dispatch(view.state.tr.setMeta(columnResizingPluginKey, { setDragging: null }));
31920
+ }
31921
+ }
31922
+ function move(event$1) {
31923
+ if (!event$1.which) return finish(event$1);
31924
+ const pluginState$1 = columnResizingPluginKey.getState(view.state);
31925
+ if (!pluginState$1) return;
31926
+ if (pluginState$1.dragging) {
31927
+ const dragged = draggedWidth(pluginState$1.dragging, event$1, cellMinWidth);
31928
+ displayColumnWidth(view, pluginState$1.activeHandle, dragged, defaultCellMinWidth);
31929
+ }
31930
+ }
31931
+ displayColumnWidth(view, pluginState.activeHandle, width, defaultCellMinWidth);
31932
+ win.addEventListener("mouseup", finish);
31933
+ win.addEventListener("mousemove", move);
31934
+ event.preventDefault();
31935
+ return true;
31864
31936
  }
31865
31937
  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;
31938
+ const width = colwidth && colwidth[colwidth.length - 1];
31939
+ if (width) return width;
31940
+ const dom = view.domAtPos(cellPos);
31941
+ let domWidth = dom.node.childNodes[dom.offset].offsetWidth, parts = colspan;
31942
+ if (colwidth) {
31943
+ for (let i = 0; i < colspan; i++) if (colwidth[i]) {
31944
+ domWidth -= colwidth[i];
31945
+ parts--;
31946
+ }
31947
+ }
31948
+ return domWidth / parts;
31879
31949
  }
31880
31950
  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;
31951
+ while (target && target.nodeName != "TD" && target.nodeName != "TH") target = target.classList && target.classList.contains("ProseMirror") ? null : target.parentNode;
31952
+ return target;
31884
31953
  }
31885
31954
  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];
31955
+ const offset = side == "right" ? -handleWidth : handleWidth;
31956
+ const found = view.posAtCoords({
31957
+ left: event.clientX + offset,
31958
+ top: event.clientY
31959
+ });
31960
+ if (!found) return -1;
31961
+ const { pos } = found;
31962
+ const $cell = cellAround(view.state.doc.resolve(pos));
31963
+ if (!$cell) return -1;
31964
+ if (side == "right") return $cell.pos;
31965
+ const map = TableMap.get($cell.node(-1)), start = $cell.start(-1);
31966
+ const index = map.map.indexOf($cell.pos - start);
31967
+ return index % map.width == 0 ? -1 : start + map.map[index - 1];
31899
31968
  }
31900
31969
  function draggedWidth(dragging, event, resizeMinWidth) {
31901
- const offset = event.clientX - dragging.startX;
31902
- return Math.max(resizeMinWidth, dragging.startWidth + offset);
31970
+ const offset = event.clientX - dragging.startX;
31971
+ return Math.max(resizeMinWidth, dragging.startWidth + offset);
31903
31972
  }
31904
31973
  function updateHandle(view, value) {
31905
- view.dispatch(
31906
- view.state.tr.setMeta(columnResizingPluginKey, { setHandle: value })
31907
- );
31974
+ view.dispatch(view.state.tr.setMeta(columnResizingPluginKey, { setHandle: value }));
31908
31975
  }
31909
31976
  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);
31977
+ const $cell = view.state.doc.resolve(cell);
31978
+ const table = $cell.node(-1), map = TableMap.get(table), start = $cell.start(-1);
31979
+ const col = map.colCount($cell.pos - start) + $cell.nodeAfter.attrs.colspan - 1;
31980
+ const tr = view.state.tr;
31981
+ for (let row = 0; row < map.height; row++) {
31982
+ const mapIndex = row * map.width + col;
31983
+ if (row && map.map[mapIndex] == map.map[mapIndex - map.width]) continue;
31984
+ const pos = map.map[mapIndex];
31985
+ const attrs = table.nodeAt(pos).attrs;
31986
+ const index = attrs.colspan == 1 ? 0 : col - map.colCount(pos);
31987
+ if (attrs.colwidth && attrs.colwidth[index] == width) continue;
31988
+ const colwidth = attrs.colwidth ? attrs.colwidth.slice() : zeroes(attrs.colspan);
31989
+ colwidth[index] = width;
31990
+ tr.setNodeMarkup(start + pos, null, {
31991
+ ...attrs,
31992
+ colwidth
31993
+ });
31994
+ }
31995
+ if (tr.docChanged) view.dispatch(tr);
31926
31996
  }
31927
31997
  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
- );
31998
+ const $cell = view.state.doc.resolve(cell);
31999
+ const table = $cell.node(-1), start = $cell.start(-1);
32000
+ const col = TableMap.get(table).colCount($cell.pos - start) + $cell.nodeAfter.attrs.colspan - 1;
32001
+ let dom = view.domAtPos($cell.start(-1)).node;
32002
+ while (dom && dom.nodeName != "TABLE") dom = dom.parentNode;
32003
+ if (!dom) return;
32004
+ updateColumnsOnResize(table, dom.firstChild, dom, defaultCellMinWidth, col, width);
31944
32005
  }
31945
32006
  function zeroes(n) {
31946
- return Array(n).fill(0);
32007
+ return Array(n).fill(0);
31947
32008
  }
31948
32009
  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
- });
32010
+ const decorations = [];
32011
+ const $cell = state.doc.resolve(cell);
32012
+ const table = $cell.node(-1);
32013
+ if (!table) return DecorationSet.empty;
32014
+ const map = TableMap.get(table);
32015
+ const start = $cell.start(-1);
32016
+ const col = map.colCount($cell.pos - start) + $cell.nodeAfter.attrs.colspan - 1;
32017
+ for (let row = 0; row < map.height; row++) {
32018
+ const index = col + row * map.width;
32019
+ if ((col == map.width - 1 || map.map[index] != map.map[index + 1]) && (row == 0 || map.map[index] != map.map[index - map.width])) {
32020
+ var _columnResizingPlugin;
32021
+ const cellPos = map.map[index];
32022
+ const pos = start + cellPos + table.nodeAt(cellPos).nodeSize - 1;
32023
+ const dom = document.createElement("div");
32024
+ dom.className = "column-resize-handle";
32025
+ 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" }));
32026
+ decorations.push(Decoration.widget(pos, dom));
32027
+ }
32028
+ }
32029
+ return DecorationSet.create(state.doc, decorations);
32030
+ }
32031
+
32032
+ //#endregion
32033
+ //#region src/index.ts
32034
+ /**
32035
+ * Creates a [plugin](http://prosemirror.net/docs/ref/#state.Plugin)
32036
+ * that, when added to an editor, enables cell-selection, handles
32037
+ * cell-based copy/paste, and makes sure tables stay well-formed (each
32038
+ * row has the same width, and cells don't overlap).
32039
+ *
32040
+ * You should probably put this plugin near the end of your array of
32041
+ * plugins, since it handles mouse and arrow key events in tables
32042
+ * rather broadly, and other plugins, like the gap cursor or the
32043
+ * column-width dragging plugin, might want to get a turn first to
32044
+ * perform more specific behavior.
32045
+ *
32046
+ * @public
32047
+ */
32048
+ function tableEditing({ allowTableNodeSelection = false } = {}) {
32049
+ return new Plugin({
32050
+ key: tableEditingKey,
32051
+ state: {
32052
+ init() {
32053
+ return null;
32054
+ },
32055
+ apply(tr, cur) {
32056
+ const set = tr.getMeta(tableEditingKey);
32057
+ if (set != null) return set == -1 ? null : set;
32058
+ if (cur == null || !tr.docChanged) return cur;
32059
+ const { deleted, pos } = tr.mapping.mapResult(cur);
32060
+ return deleted ? null : pos;
32061
+ }
32062
+ },
32063
+ props: {
32064
+ decorations: drawCellSelection,
32065
+ handleDOMEvents: { mousedown: handleMouseDown$1 },
32066
+ createSelectionBetween(view) {
32067
+ return tableEditingKey.getState(view.state) != null ? view.state.selection : null;
32068
+ },
32069
+ handleTripleClick,
32070
+ handleKeyDown,
32071
+ handlePaste
32072
+ },
32073
+ appendTransaction(_, oldState, state) {
32074
+ return normalizeSelection(state, fixTables(state, oldState), allowTableNodeSelection);
32075
+ }
32076
+ });
32024
32077
  }
32025
32078
 
32026
32079
  // src/cell/table-cell.ts
@@ -41400,7 +41453,7 @@ function Arrow_big_down_line($$anchor, $$props) {
41400
41453
  "path",
41401
41454
 
41402
41455
  {
41403
- "d": "M15 12h3.586a1 1 0 0 1 .707 1.707l-6.586 6.586a1 1 0 0 1 -1.414 0l-6.586 -6.586a1 1 0 0 1 .707 -1.707h3.586v-6h6v6z"
41456
+ "d": "M15 12h3.586a1 1 0 0 1 .707 1.707l-6.586 6.586a1 1 0 0 1 -1.414 0l-6.586 -6.586a1 1 0 0 1 .707 -1.707h3.586v-6h6v6"
41404
41457
  }
41405
41458
  ],
41406
41459
 
@@ -41432,7 +41485,7 @@ function Arrow_big_up_line($$anchor, $$props) {
41432
41485
  "path",
41433
41486
 
41434
41487
  {
41435
- "d": "M9 12h-3.586a1 1 0 0 1 -.707 -1.707l6.586 -6.586a1 1 0 0 1 1.414 0l6.586 6.586a1 1 0 0 1 -.707 1.707h-3.586v6h-6v-6z"
41488
+ "d": "M9 12h-3.586a1 1 0 0 1 -.707 -1.707l6.586 -6.586a1 1 0 0 1 1.414 0l6.586 6.586a1 1 0 0 1 -.707 1.707h-3.586v6h-6v-6"
41436
41489
  }
41437
41490
  ],
41438
41491
 
@@ -41472,7 +41525,7 @@ function Clipboard_plus($$anchor, $$props) {
41472
41525
  "path",
41473
41526
 
41474
41527
  {
41475
- "d": "M9 3m0 2a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v0a2 2 0 0 1 -2 2h-2a2 2 0 0 1 -2 -2z"
41528
+ "d": "M9 5a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2a2 2 0 0 1 -2 2h-2a2 2 0 0 1 -2 -2"
41476
41529
  }
41477
41530
  ],
41478
41531
 
@@ -41505,7 +41558,7 @@ function Layout_grid_add($$anchor, $$props) {
41505
41558
  "path",
41506
41559
 
41507
41560
  {
41508
- "d": "M4 4m0 1a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1z"
41561
+ "d": "M4 5a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1l0 -4"
41509
41562
  }
41510
41563
  ],
41511
41564
 
@@ -41513,7 +41566,7 @@ function Layout_grid_add($$anchor, $$props) {
41513
41566
  "path",
41514
41567
 
41515
41568
  {
41516
- "d": "M14 4m0 1a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1z"
41569
+ "d": "M14 5a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1l0 -4"
41517
41570
  }
41518
41571
  ],
41519
41572
 
@@ -41521,7 +41574,7 @@ function Layout_grid_add($$anchor, $$props) {
41521
41574
  "path",
41522
41575
 
41523
41576
  {
41524
- "d": "M4 14m0 1a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1z"
41577
+ "d": "M4 15a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1l0 -4"
41525
41578
  }
41526
41579
  ],
41527
41580
 
@@ -41553,7 +41606,7 @@ function Layout_grid_remove($$anchor, $$props) {
41553
41606
  "path",
41554
41607
 
41555
41608
  {
41556
- "d": "M4 5a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1v-4z"
41609
+ "d": "M4 5a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1v-4"
41557
41610
  }
41558
41611
  ],
41559
41612
 
@@ -41561,7 +41614,7 @@ function Layout_grid_remove($$anchor, $$props) {
41561
41614
  "path",
41562
41615
 
41563
41616
  {
41564
- "d": "M14 5a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1v-4z"
41617
+ "d": "M14 5a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1v-4"
41565
41618
  }
41566
41619
  ],
41567
41620
 
@@ -41569,7 +41622,7 @@ function Layout_grid_remove($$anchor, $$props) {
41569
41622
  "path",
41570
41623
 
41571
41624
  {
41572
- "d": "M4 15a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1v-4z"
41625
+ "d": "M4 15a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1v-4"
41573
41626
  }
41574
41627
  ],
41575
41628
 
@@ -41601,7 +41654,7 @@ function Row_insert_bottom($$anchor, $$props) {
41601
41654
  "path",
41602
41655
 
41603
41656
  {
41604
- "d": "M20 6v4a1 1 0 0 1 -1 1h-14a1 1 0 0 1 -1 -1v-4a1 1 0 0 1 1 -1h14a1 1 0 0 1 1 1z"
41657
+ "d": "M20 6v4a1 1 0 0 1 -1 1h-14a1 1 0 0 1 -1 -1v-4a1 1 0 0 1 1 -1h14a1 1 0 0 1 1 1"
41605
41658
  }
41606
41659
  ],
41607
41660
 
@@ -41634,7 +41687,7 @@ function Row_insert_top($$anchor, $$props) {
41634
41687
  "path",
41635
41688
 
41636
41689
  {
41637
- "d": "M4 18v-4a1 1 0 0 1 1 -1h14a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-14a1 1 0 0 1 -1 -1z"
41690
+ "d": "M4 18v-4a1 1 0 0 1 1 -1h14a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-14a1 1 0 0 1 -1 -1"
41638
41691
  }
41639
41692
  ],
41640
41693
 
@@ -41667,7 +41720,7 @@ function Settings($$anchor, $$props) {
41667
41720
  "path",
41668
41721
 
41669
41722
  {
41670
- "d": "M10.325 4.317c.426 -1.756 2.924 -1.756 3.35 0a1.724 1.724 0 0 0 2.573 1.066c1.543 -.94 3.31 .826 2.37 2.37a1.724 1.724 0 0 0 1.065 2.572c1.756 .426 1.756 2.924 0 3.35a1.724 1.724 0 0 0 -1.066 2.573c.94 1.543 -.826 3.31 -2.37 2.37a1.724 1.724 0 0 0 -2.572 1.065c-.426 1.756 -2.924 1.756 -3.35 0a1.724 1.724 0 0 0 -2.573 -1.066c-1.543 .94 -3.31 -.826 -2.37 -2.37a1.724 1.724 0 0 0 -1.065 -2.572c-1.756 -.426 -1.756 -2.924 0 -3.35a1.724 1.724 0 0 0 1.066 -2.573c-.94 -1.543 .826 -3.31 2.37 -2.37c1 .608 2.296 .07 2.572 -1.065z"
41723
+ "d": "M10.325 4.317c.426 -1.756 2.924 -1.756 3.35 0a1.724 1.724 0 0 0 2.573 1.066c1.543 -.94 3.31 .826 2.37 2.37a1.724 1.724 0 0 0 1.065 2.572c1.756 .426 1.756 2.924 0 3.35a1.724 1.724 0 0 0 -1.066 2.573c.94 1.543 -.826 3.31 -2.37 2.37a1.724 1.724 0 0 0 -2.572 1.065c-.426 1.756 -2.924 1.756 -3.35 0a1.724 1.724 0 0 0 -2.573 -1.066c-1.543 .94 -3.31 -.826 -2.37 -2.37a1.724 1.724 0 0 0 -1.065 -2.572c-1.756 -.426 -1.756 -2.924 0 -3.35a1.724 1.724 0 0 0 1.066 -2.573c-.94 -1.543 .826 -3.31 2.37 -2.37c1 .608 2.296 .07 2.572 -1.065"
41671
41724
  }
41672
41725
  ],
41673
41726
 
@@ -42645,7 +42698,7 @@ function File($$anchor, $$props) {
42645
42698
  "path",
42646
42699
 
42647
42700
  {
42648
- "d": "M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z"
42701
+ "d": "M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2"
42649
42702
  }
42650
42703
  ]
42651
42704
  ];
@@ -42676,7 +42729,7 @@ function File_type_doc($$anchor, $$props) {
42676
42729
 
42677
42730
  [
42678
42731
  "path",
42679
- { "d": "M5 15v6h1a2 2 0 0 0 2 -2v-2a2 2 0 0 0 -2 -2h-1z" }
42732
+ { "d": "M5 15v6h1a2 2 0 0 0 2 -2v-2a2 2 0 0 0 -2 -2h-1" }
42680
42733
  ],
42681
42734
 
42682
42735
  [
@@ -42688,7 +42741,7 @@ function File_type_doc($$anchor, $$props) {
42688
42741
  "path",
42689
42742
 
42690
42743
  {
42691
- "d": "M12.5 15a1.5 1.5 0 0 1 1.5 1.5v3a1.5 1.5 0 0 1 -3 0v-3a1.5 1.5 0 0 1 1.5 -1.5z"
42744
+ "d": "M12.5 15a1.5 1.5 0 0 1 1.5 1.5v3a1.5 1.5 0 0 1 -3 0v-3a1.5 1.5 0 0 1 1.5 -1.5"
42692
42745
  }
42693
42746
  ]
42694
42747
  ];
@@ -42722,7 +42775,7 @@ function File_type_pdf($$anchor, $$props) {
42722
42775
 
42723
42776
  [
42724
42777
  "path",
42725
- { "d": "M11 15v6h1a2 2 0 0 0 2 -2v-2a2 2 0 0 0 -2 -2h-1z" }
42778
+ { "d": "M11 15v6h1a2 2 0 0 0 2 -2v-2a2 2 0 0 0 -2 -2h-1" }
42726
42779
  ]
42727
42780
  ];
42728
42781
 
@@ -42818,7 +42871,7 @@ function Headphones($$anchor, $$props) {
42818
42871
  "path",
42819
42872
 
42820
42873
  {
42821
- "d": "M4 13m0 2a2 2 0 0 1 2 -2h1a2 2 0 0 1 2 2v3a2 2 0 0 1 -2 2h-1a2 2 0 0 1 -2 -2z"
42874
+ "d": "M4 15a2 2 0 0 1 2 -2h1a2 2 0 0 1 2 2v3a2 2 0 0 1 -2 2h-1a2 2 0 0 1 -2 -2l0 -3"
42822
42875
  }
42823
42876
  ],
42824
42877
 
@@ -42826,7 +42879,7 @@ function Headphones($$anchor, $$props) {
42826
42879
  "path",
42827
42880
 
42828
42881
  {
42829
- "d": "M15 13m0 2a2 2 0 0 1 2 -2h1a2 2 0 0 1 2 2v3a2 2 0 0 1 -2 2h-1a2 2 0 0 1 -2 -2z"
42882
+ "d": "M15 15a2 2 0 0 1 2 -2h1a2 2 0 0 1 2 2v3a2 2 0 0 1 -2 2h-1a2 2 0 0 1 -2 -2l0 -3"
42830
42883
  }
42831
42884
  ],
42832
42885
 
@@ -42858,7 +42911,7 @@ function Video($$anchor, $$props) {
42858
42911
  "path",
42859
42912
 
42860
42913
  {
42861
- "d": "M15 10l4.553 -2.276a1 1 0 0 1 1.447 .894v6.764a1 1 0 0 1 -1.447 .894l-4.553 -2.276v-4z"
42914
+ "d": "M15 10l4.553 -2.276a1 1 0 0 1 1.447 .894v6.764a1 1 0 0 1 -1.447 .894l-4.553 -2.276v-4"
42862
42915
  }
42863
42916
  ],
42864
42917
 
@@ -42866,7 +42919,7 @@ function Video($$anchor, $$props) {
42866
42919
  "path",
42867
42920
 
42868
42921
  {
42869
- "d": "M3 6m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z"
42922
+ "d": "M3 8a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2l0 -8"
42870
42923
  }
42871
42924
  ]
42872
42925
  ];
@@ -44088,7 +44141,7 @@ function parseConfig(config) {
44088
44141
  }
44089
44142
  }
44090
44143
 
44091
- const version = "4.0.0-alpha.43";
44144
+ const version = "4.0.0-alpha.45";
44092
44145
  function attachDraftSwitcher(engine) {
44093
44146
  if (engine.hasDraft()) {
44094
44147
  const container = document.createElement("div");