@codemirror/view 6.10.1 → 6.11.1

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/CHANGELOG.md CHANGED
@@ -1,3 +1,14 @@
1
+ ## 6.11.1 (2023-05-09)
2
+
3
+ ### Bug fixes
4
+
5
+ Don't preserve the DOM around a composition that spans multiple lines.
6
+ ## 6.11.0 (2023-05-03)
7
+
8
+ ### New features
9
+
10
+ Gutters now support a `widgetMarker` option that can be used to add markers next to block widgets.
11
+
1
12
  ## 6.10.1 (2023-05-01)
2
13
 
3
14
  ### Bug fixes
package/dist/index.cjs CHANGED
@@ -3019,15 +3019,17 @@ function computeCompositionDeco(view, changes) {
3019
3019
  let newFrom = changes.mapPos(from, 1), newTo = Math.max(newFrom, changes.mapPos(to, -1));
3020
3020
  let { state } = view, text = node.nodeType == 3 ? node.nodeValue :
3021
3021
  new DOMReader([], state).readRange(node.firstChild, null).text;
3022
+ if (text.indexOf(LineBreakPlaceholder) > -1)
3023
+ return Decoration.none; // Don't try to preserve multi-line compositions
3022
3024
  if (newTo - newFrom < text.length) {
3023
- if (state.doc.sliceString(newFrom, Math.min(state.doc.length, newFrom + text.length), LineBreakPlaceholder) == text)
3025
+ if (state.doc.sliceString(newFrom, Math.min(state.doc.length, newFrom + text.length)) == text)
3024
3026
  newTo = newFrom + text.length;
3025
- else if (state.doc.sliceString(Math.max(0, newTo - text.length), newTo, LineBreakPlaceholder) == text)
3027
+ else if (state.doc.sliceString(Math.max(0, newTo - text.length), newTo) == text)
3026
3028
  newFrom = newTo - text.length;
3027
3029
  else
3028
3030
  return Decoration.none;
3029
3031
  }
3030
- else if (state.doc.sliceString(newFrom, newTo, LineBreakPlaceholder) != text) {
3032
+ else if (state.doc.sliceString(newFrom, newTo) != text) {
3031
3033
  return Decoration.none;
3032
3034
  }
3033
3035
  let topView = ContentView.get(node);
@@ -4337,15 +4339,34 @@ class BlockInfo {
4337
4339
  */
4338
4340
  height,
4339
4341
  /**
4340
- The type of element this is. When querying lines, this may be
4341
- an array of all the blocks that make up the line.
4342
+ @internal
4343
+ */
4344
+ children,
4345
+ /**
4346
+ @internal
4342
4347
  */
4343
- type) {
4348
+ deco) {
4344
4349
  this.from = from;
4345
4350
  this.length = length;
4346
4351
  this.top = top;
4347
4352
  this.height = height;
4348
- this.type = type;
4353
+ this.children = children;
4354
+ this.deco = deco;
4355
+ }
4356
+ /**
4357
+ The type of element this is. When querying lines, this may be
4358
+ an array of all the blocks that make up the line.
4359
+ */
4360
+ get type() {
4361
+ var _a, _b, _c;
4362
+ return (_c = (_a = this.children) !== null && _a !== void 0 ? _a : (_b = this.deco) === null || _b === void 0 ? void 0 : _b.type) !== null && _c !== void 0 ? _c : exports.BlockType.Text;
4363
+ }
4364
+ /**
4365
+ If this is a widget block, this will return the widget
4366
+ associated with it.
4367
+ */
4368
+ get widget() {
4369
+ return this.deco && this.deco.widget;
4349
4370
  }
4350
4371
  /**
4351
4372
  The end of the element as a document position.
@@ -4359,9 +4380,8 @@ class BlockInfo {
4359
4380
  @internal
4360
4381
  */
4361
4382
  join(other) {
4362
- let detail = (Array.isArray(this.type) ? this.type : [this])
4363
- .concat(Array.isArray(other.type) ? other.type : [other]);
4364
- return new BlockInfo(this.from, this.length + other.length, this.top, this.height + other.height, detail);
4383
+ let children = (this.children || [this]).concat(other.children || [other]);
4384
+ return new BlockInfo(this.from, this.length + other.length, this.top, this.height + other.height, children, null);
4365
4385
  }
4366
4386
  }
4367
4387
  var QueryType;
@@ -4477,12 +4497,12 @@ class HeightMap {
4477
4497
  }
4478
4498
  HeightMap.prototype.size = 1;
4479
4499
  class HeightMapBlock extends HeightMap {
4480
- constructor(length, height, type) {
4500
+ constructor(length, height, deco) {
4481
4501
  super(length, height);
4482
- this.type = type;
4502
+ this.deco = deco;
4483
4503
  }
4484
4504
  blockAt(_height, _oracle, top, offset) {
4485
- return new BlockInfo(offset, this.length, top, this.height, this.type);
4505
+ return new BlockInfo(offset, this.length, top, this.height, null, this.deco);
4486
4506
  }
4487
4507
  lineAt(_value, _type, oracle, top, offset) {
4488
4508
  return this.blockAt(0, oracle, top, offset);
@@ -4501,7 +4521,7 @@ class HeightMapBlock extends HeightMap {
4501
4521
  }
4502
4522
  class HeightMapText extends HeightMapBlock {
4503
4523
  constructor(length, height) {
4504
- super(length, height, exports.BlockType.Text);
4524
+ super(length, height, null);
4505
4525
  this.collapsed = 0; // Amount of collapsed content in the line
4506
4526
  this.widgetHeight = 0; // Maximum inline widget height
4507
4527
  }
@@ -4556,12 +4576,12 @@ class HeightMapGap extends HeightMap {
4556
4576
  let guess = offset + Math.round(Math.max(0, Math.min(1, (height - top) / this.height)) * this.length);
4557
4577
  let line = oracle.doc.lineAt(guess), lineHeight = perLine + line.length * perChar;
4558
4578
  let lineTop = Math.max(top, height - lineHeight / 2);
4559
- return new BlockInfo(line.from, line.length, lineTop, lineHeight, exports.BlockType.Text);
4579
+ return new BlockInfo(line.from, line.length, lineTop, lineHeight, null, null);
4560
4580
  }
4561
4581
  else {
4562
4582
  let line = Math.max(0, Math.min(lastLine - firstLine, Math.floor((height - top) / perLine)));
4563
4583
  let { from, length } = oracle.doc.line(firstLine + line);
4564
- return new BlockInfo(from, length, top + perLine * line, perLine, exports.BlockType.Text);
4584
+ return new BlockInfo(from, length, top + perLine * line, perLine, null, null);
4565
4585
  }
4566
4586
  }
4567
4587
  lineAt(value, type, oracle, top, offset) {
@@ -4569,13 +4589,13 @@ class HeightMapGap extends HeightMap {
4569
4589
  return this.blockAt(value, oracle, top, offset);
4570
4590
  if (type == QueryType.ByPosNoHeight) {
4571
4591
  let { from, to } = oracle.doc.lineAt(value);
4572
- return new BlockInfo(from, to - from, 0, 0, exports.BlockType.Text);
4592
+ return new BlockInfo(from, to - from, 0, 0, null, null);
4573
4593
  }
4574
4594
  let { firstLine, perLine, perChar } = this.heightMetrics(oracle, offset);
4575
4595
  let line = oracle.doc.lineAt(value), lineHeight = perLine + line.length * perChar;
4576
4596
  let linesAbove = line.number - firstLine;
4577
4597
  let lineTop = top + perLine * linesAbove + perChar * (line.from - offset - linesAbove);
4578
- return new BlockInfo(line.from, line.length, Math.max(top, Math.min(lineTop, top + this.height - lineHeight)), lineHeight, exports.BlockType.Text);
4598
+ return new BlockInfo(line.from, line.length, Math.max(top, Math.min(lineTop, top + this.height - lineHeight)), lineHeight, null, null);
4579
4599
  }
4580
4600
  forEachLine(from, to, oracle, top, offset, f) {
4581
4601
  from = Math.max(from, offset);
@@ -4588,7 +4608,7 @@ class HeightMapGap extends HeightMap {
4588
4608
  lineTop += perLine * linesAbove + perChar * (from - offset - linesAbove);
4589
4609
  }
4590
4610
  let lineHeight = perLine + perChar * line.length;
4591
- f(new BlockInfo(line.from, line.length, lineTop, lineHeight, exports.BlockType.Text));
4611
+ f(new BlockInfo(line.from, line.length, lineTop, lineHeight, null, null));
4592
4612
  lineTop += lineHeight;
4593
4613
  pos = line.to + 1;
4594
4614
  }
@@ -4818,7 +4838,7 @@ class NodeBuilder {
4818
4838
  height = this.oracle.lineHeight;
4819
4839
  let len = to - from;
4820
4840
  if (deco.block) {
4821
- this.addBlock(new HeightMapBlock(len, height, deco.type));
4841
+ this.addBlock(new HeightMapBlock(len, height, deco));
4822
4842
  }
4823
4843
  else if (len || height >= relevantWidgetHeight) {
4824
4844
  this.addLineDeco(height, len);
@@ -4861,12 +4881,14 @@ class NodeBuilder {
4861
4881
  return line;
4862
4882
  }
4863
4883
  addBlock(block) {
4884
+ var _a;
4864
4885
  this.enterLine();
4865
- if (block.type == exports.BlockType.WidgetAfter && !this.isCovered)
4886
+ let type = (_a = block.deco) === null || _a === void 0 ? void 0 : _a.type;
4887
+ if (type == exports.BlockType.WidgetAfter && !this.isCovered)
4866
4888
  this.ensureLine();
4867
4889
  this.nodes.push(block);
4868
4890
  this.writtenTo = this.pos = this.pos + block.length;
4869
- if (block.type != exports.BlockType.WidgetBefore)
4891
+ if (type != exports.BlockType.WidgetBefore)
4870
4892
  this.covering = block;
4871
4893
  }
4872
4894
  addLineDeco(height, length) {
@@ -5469,7 +5491,7 @@ function scaleBlock(block, scaler) {
5469
5491
  if (scaler.scale == 1)
5470
5492
  return block;
5471
5493
  let bTop = scaler.toDOM(block.top), bBottom = scaler.toDOM(block.bottom);
5472
- return new BlockInfo(block.from, block.length, bTop, bBottom - bTop, Array.isArray(block.type) ? block.type.map(b => scaleBlock(b, scaler)) : block.type);
5494
+ return new BlockInfo(block.from, block.length, bTop, bBottom - bTop, block.children && block.children.map(b => scaleBlock(b, scaler)), block.deco);
5473
5495
  }
5474
5496
 
5475
5497
  const theme = state.Facet.define({ combine: strs => strs.join(" ") });
@@ -9299,6 +9321,7 @@ const defaults = {
9299
9321
  elementStyle: "",
9300
9322
  markers: () => state.RangeSet.empty,
9301
9323
  lineMarker: () => null,
9324
+ widgetMarker: () => null,
9302
9325
  lineMarkerChange: null,
9303
9326
  initialSpacer: null,
9304
9327
  updateSpacer: null,
@@ -9379,24 +9402,28 @@ const gutterView = ViewPlugin.fromClass(class {
9379
9402
  let classSet = [];
9380
9403
  let contexts = this.gutters.map(gutter => new UpdateContext(gutter, this.view.viewport, -this.view.documentPadding.top));
9381
9404
  for (let line of this.view.viewportLineBlocks) {
9382
- let text;
9405
+ if (classSet.length)
9406
+ classSet = [];
9383
9407
  if (Array.isArray(line.type)) {
9384
- for (let b of line.type)
9385
- if (b.type == exports.BlockType.Text) {
9386
- text = b;
9387
- break;
9408
+ let first = true;
9409
+ for (let b of line.type) {
9410
+ if (b.type == exports.BlockType.Text && first) {
9411
+ advanceCursor(lineClasses, classSet, b.from);
9412
+ for (let cx of contexts)
9413
+ cx.line(this.view, b, classSet);
9414
+ first = false;
9388
9415
  }
9416
+ else if (b.widget) {
9417
+ for (let cx of contexts)
9418
+ cx.widget(this.view, b);
9419
+ }
9420
+ }
9389
9421
  }
9390
- else {
9391
- text = line.type == exports.BlockType.Text ? line : undefined;
9422
+ else if (line.type == exports.BlockType.Text) {
9423
+ advanceCursor(lineClasses, classSet, line.from);
9424
+ for (let cx of contexts)
9425
+ cx.line(this.view, line, classSet);
9392
9426
  }
9393
- if (!text)
9394
- continue;
9395
- if (classSet.length)
9396
- classSet = [];
9397
- advanceCursor(lineClasses, classSet, line.from);
9398
- for (let cx of contexts)
9399
- cx.line(this.view, text, classSet);
9400
9427
  }
9401
9428
  for (let cx of contexts)
9402
9429
  cx.finish();
@@ -9464,6 +9491,19 @@ class UpdateContext {
9464
9491
  this.i = 0;
9465
9492
  this.cursor = state.RangeSet.iter(gutter.markers, viewport.from);
9466
9493
  }
9494
+ addElement(view, block, markers) {
9495
+ let { gutter } = this, above = block.top - this.height;
9496
+ if (this.i == gutter.elements.length) {
9497
+ let newElt = new GutterElement(view, block.height, above, markers);
9498
+ gutter.elements.push(newElt);
9499
+ gutter.dom.appendChild(newElt.dom);
9500
+ }
9501
+ else {
9502
+ gutter.elements[this.i].update(view, block.height, above, markers);
9503
+ }
9504
+ this.height = block.bottom;
9505
+ this.i++;
9506
+ }
9467
9507
  line(view, line, extraMarkers) {
9468
9508
  let localMarkers = [];
9469
9509
  advanceCursor(this.cursor, localMarkers, line.from);
@@ -9475,17 +9515,12 @@ class UpdateContext {
9475
9515
  let gutter = this.gutter;
9476
9516
  if (localMarkers.length == 0 && !gutter.config.renderEmptyElements)
9477
9517
  return;
9478
- let above = line.top - this.height;
9479
- if (this.i == gutter.elements.length) {
9480
- let newElt = new GutterElement(view, line.height, above, localMarkers);
9481
- gutter.elements.push(newElt);
9482
- gutter.dom.appendChild(newElt.dom);
9483
- }
9484
- else {
9485
- gutter.elements[this.i].update(view, line.height, above, localMarkers);
9486
- }
9487
- this.height = line.bottom;
9488
- this.i++;
9518
+ this.addElement(view, line, localMarkers);
9519
+ }
9520
+ widget(view, block) {
9521
+ let marker = this.gutter.config.widgetMarker(view, block.widget, block);
9522
+ if (marker)
9523
+ this.addElement(view, block, [marker]);
9489
9524
  }
9490
9525
  finish() {
9491
9526
  let gutter = this.gutter;
@@ -9653,6 +9688,7 @@ const lineNumberGutter = activeGutters.compute([lineNumberConfig], state => ({
9653
9688
  return null;
9654
9689
  return new NumberMarker(formatNumber(view, view.state.doc.lineAt(line.from).number));
9655
9690
  },
9691
+ widgetMarker: () => null,
9656
9692
  lineMarkerChange: update => update.startState.facet(lineNumberConfig) != update.state.facet(lineNumberConfig),
9657
9693
  initialSpacer(view) {
9658
9694
  return new NumberMarker(formatNumber(view, maxLineNumber(view.state.doc.lines)));
package/dist/index.d.ts CHANGED
@@ -516,7 +516,12 @@ declare class BlockInfo {
516
516
  The type of element this is. When querying lines, this may be
517
517
  an array of all the blocks that make up the line.
518
518
  */
519
- readonly type: BlockType | readonly BlockInfo[];
519
+ get type(): BlockType | readonly BlockInfo[];
520
+ /**
521
+ If this is a widget block, this will return the widget
522
+ associated with it.
523
+ */
524
+ get widget(): WidgetType | null;
520
525
  /**
521
526
  The end of the element as a document position.
522
527
  */
@@ -1864,8 +1869,12 @@ interface GutterConfig {
1864
1869
  */
1865
1870
  lineMarker?: (view: EditorView, line: BlockInfo, otherMarkers: readonly GutterMarker[]) => GutterMarker | null;
1866
1871
  /**
1867
- If line markers depend on additional state, and should be
1868
- updated when that changes, pass a predicate here that checks
1872
+ Associate markers with block widgets in the document.
1873
+ */
1874
+ widgetMarker?: (view: EditorView, widget: WidgetType, block: BlockInfo) => GutterMarker | null;
1875
+ /**
1876
+ If line or widget markers depend on additional state, and should
1877
+ be updated when that changes, pass a predicate here that checks
1869
1878
  whether a given view update might change the line markers.
1870
1879
  */
1871
1880
  lineMarkerChange?: null | ((update: ViewUpdate) => boolean);
package/dist/index.js CHANGED
@@ -3013,15 +3013,17 @@ function computeCompositionDeco(view, changes) {
3013
3013
  let newFrom = changes.mapPos(from, 1), newTo = Math.max(newFrom, changes.mapPos(to, -1));
3014
3014
  let { state } = view, text = node.nodeType == 3 ? node.nodeValue :
3015
3015
  new DOMReader([], state).readRange(node.firstChild, null).text;
3016
+ if (text.indexOf(LineBreakPlaceholder) > -1)
3017
+ return Decoration.none; // Don't try to preserve multi-line compositions
3016
3018
  if (newTo - newFrom < text.length) {
3017
- if (state.doc.sliceString(newFrom, Math.min(state.doc.length, newFrom + text.length), LineBreakPlaceholder) == text)
3019
+ if (state.doc.sliceString(newFrom, Math.min(state.doc.length, newFrom + text.length)) == text)
3018
3020
  newTo = newFrom + text.length;
3019
- else if (state.doc.sliceString(Math.max(0, newTo - text.length), newTo, LineBreakPlaceholder) == text)
3021
+ else if (state.doc.sliceString(Math.max(0, newTo - text.length), newTo) == text)
3020
3022
  newFrom = newTo - text.length;
3021
3023
  else
3022
3024
  return Decoration.none;
3023
3025
  }
3024
- else if (state.doc.sliceString(newFrom, newTo, LineBreakPlaceholder) != text) {
3026
+ else if (state.doc.sliceString(newFrom, newTo) != text) {
3025
3027
  return Decoration.none;
3026
3028
  }
3027
3029
  let topView = ContentView.get(node);
@@ -4331,15 +4333,34 @@ class BlockInfo {
4331
4333
  */
4332
4334
  height,
4333
4335
  /**
4334
- The type of element this is. When querying lines, this may be
4335
- an array of all the blocks that make up the line.
4336
+ @internal
4337
+ */
4338
+ children,
4339
+ /**
4340
+ @internal
4336
4341
  */
4337
- type) {
4342
+ deco) {
4338
4343
  this.from = from;
4339
4344
  this.length = length;
4340
4345
  this.top = top;
4341
4346
  this.height = height;
4342
- this.type = type;
4347
+ this.children = children;
4348
+ this.deco = deco;
4349
+ }
4350
+ /**
4351
+ The type of element this is. When querying lines, this may be
4352
+ an array of all the blocks that make up the line.
4353
+ */
4354
+ get type() {
4355
+ var _a, _b, _c;
4356
+ return (_c = (_a = this.children) !== null && _a !== void 0 ? _a : (_b = this.deco) === null || _b === void 0 ? void 0 : _b.type) !== null && _c !== void 0 ? _c : BlockType.Text;
4357
+ }
4358
+ /**
4359
+ If this is a widget block, this will return the widget
4360
+ associated with it.
4361
+ */
4362
+ get widget() {
4363
+ return this.deco && this.deco.widget;
4343
4364
  }
4344
4365
  /**
4345
4366
  The end of the element as a document position.
@@ -4353,9 +4374,8 @@ class BlockInfo {
4353
4374
  @internal
4354
4375
  */
4355
4376
  join(other) {
4356
- let detail = (Array.isArray(this.type) ? this.type : [this])
4357
- .concat(Array.isArray(other.type) ? other.type : [other]);
4358
- return new BlockInfo(this.from, this.length + other.length, this.top, this.height + other.height, detail);
4377
+ let children = (this.children || [this]).concat(other.children || [other]);
4378
+ return new BlockInfo(this.from, this.length + other.length, this.top, this.height + other.height, children, null);
4359
4379
  }
4360
4380
  }
4361
4381
  var QueryType = /*@__PURE__*/(function (QueryType) {
@@ -4470,12 +4490,12 @@ class HeightMap {
4470
4490
  }
4471
4491
  HeightMap.prototype.size = 1;
4472
4492
  class HeightMapBlock extends HeightMap {
4473
- constructor(length, height, type) {
4493
+ constructor(length, height, deco) {
4474
4494
  super(length, height);
4475
- this.type = type;
4495
+ this.deco = deco;
4476
4496
  }
4477
4497
  blockAt(_height, _oracle, top, offset) {
4478
- return new BlockInfo(offset, this.length, top, this.height, this.type);
4498
+ return new BlockInfo(offset, this.length, top, this.height, null, this.deco);
4479
4499
  }
4480
4500
  lineAt(_value, _type, oracle, top, offset) {
4481
4501
  return this.blockAt(0, oracle, top, offset);
@@ -4494,7 +4514,7 @@ class HeightMapBlock extends HeightMap {
4494
4514
  }
4495
4515
  class HeightMapText extends HeightMapBlock {
4496
4516
  constructor(length, height) {
4497
- super(length, height, BlockType.Text);
4517
+ super(length, height, null);
4498
4518
  this.collapsed = 0; // Amount of collapsed content in the line
4499
4519
  this.widgetHeight = 0; // Maximum inline widget height
4500
4520
  }
@@ -4549,12 +4569,12 @@ class HeightMapGap extends HeightMap {
4549
4569
  let guess = offset + Math.round(Math.max(0, Math.min(1, (height - top) / this.height)) * this.length);
4550
4570
  let line = oracle.doc.lineAt(guess), lineHeight = perLine + line.length * perChar;
4551
4571
  let lineTop = Math.max(top, height - lineHeight / 2);
4552
- return new BlockInfo(line.from, line.length, lineTop, lineHeight, BlockType.Text);
4572
+ return new BlockInfo(line.from, line.length, lineTop, lineHeight, null, null);
4553
4573
  }
4554
4574
  else {
4555
4575
  let line = Math.max(0, Math.min(lastLine - firstLine, Math.floor((height - top) / perLine)));
4556
4576
  let { from, length } = oracle.doc.line(firstLine + line);
4557
- return new BlockInfo(from, length, top + perLine * line, perLine, BlockType.Text);
4577
+ return new BlockInfo(from, length, top + perLine * line, perLine, null, null);
4558
4578
  }
4559
4579
  }
4560
4580
  lineAt(value, type, oracle, top, offset) {
@@ -4562,13 +4582,13 @@ class HeightMapGap extends HeightMap {
4562
4582
  return this.blockAt(value, oracle, top, offset);
4563
4583
  if (type == QueryType.ByPosNoHeight) {
4564
4584
  let { from, to } = oracle.doc.lineAt(value);
4565
- return new BlockInfo(from, to - from, 0, 0, BlockType.Text);
4585
+ return new BlockInfo(from, to - from, 0, 0, null, null);
4566
4586
  }
4567
4587
  let { firstLine, perLine, perChar } = this.heightMetrics(oracle, offset);
4568
4588
  let line = oracle.doc.lineAt(value), lineHeight = perLine + line.length * perChar;
4569
4589
  let linesAbove = line.number - firstLine;
4570
4590
  let lineTop = top + perLine * linesAbove + perChar * (line.from - offset - linesAbove);
4571
- return new BlockInfo(line.from, line.length, Math.max(top, Math.min(lineTop, top + this.height - lineHeight)), lineHeight, BlockType.Text);
4591
+ return new BlockInfo(line.from, line.length, Math.max(top, Math.min(lineTop, top + this.height - lineHeight)), lineHeight, null, null);
4572
4592
  }
4573
4593
  forEachLine(from, to, oracle, top, offset, f) {
4574
4594
  from = Math.max(from, offset);
@@ -4581,7 +4601,7 @@ class HeightMapGap extends HeightMap {
4581
4601
  lineTop += perLine * linesAbove + perChar * (from - offset - linesAbove);
4582
4602
  }
4583
4603
  let lineHeight = perLine + perChar * line.length;
4584
- f(new BlockInfo(line.from, line.length, lineTop, lineHeight, BlockType.Text));
4604
+ f(new BlockInfo(line.from, line.length, lineTop, lineHeight, null, null));
4585
4605
  lineTop += lineHeight;
4586
4606
  pos = line.to + 1;
4587
4607
  }
@@ -4811,7 +4831,7 @@ class NodeBuilder {
4811
4831
  height = this.oracle.lineHeight;
4812
4832
  let len = to - from;
4813
4833
  if (deco.block) {
4814
- this.addBlock(new HeightMapBlock(len, height, deco.type));
4834
+ this.addBlock(new HeightMapBlock(len, height, deco));
4815
4835
  }
4816
4836
  else if (len || height >= relevantWidgetHeight) {
4817
4837
  this.addLineDeco(height, len);
@@ -4854,12 +4874,14 @@ class NodeBuilder {
4854
4874
  return line;
4855
4875
  }
4856
4876
  addBlock(block) {
4877
+ var _a;
4857
4878
  this.enterLine();
4858
- if (block.type == BlockType.WidgetAfter && !this.isCovered)
4879
+ let type = (_a = block.deco) === null || _a === void 0 ? void 0 : _a.type;
4880
+ if (type == BlockType.WidgetAfter && !this.isCovered)
4859
4881
  this.ensureLine();
4860
4882
  this.nodes.push(block);
4861
4883
  this.writtenTo = this.pos = this.pos + block.length;
4862
- if (block.type != BlockType.WidgetBefore)
4884
+ if (type != BlockType.WidgetBefore)
4863
4885
  this.covering = block;
4864
4886
  }
4865
4887
  addLineDeco(height, length) {
@@ -5462,7 +5484,7 @@ function scaleBlock(block, scaler) {
5462
5484
  if (scaler.scale == 1)
5463
5485
  return block;
5464
5486
  let bTop = scaler.toDOM(block.top), bBottom = scaler.toDOM(block.bottom);
5465
- return new BlockInfo(block.from, block.length, bTop, bBottom - bTop, Array.isArray(block.type) ? block.type.map(b => scaleBlock(b, scaler)) : block.type);
5487
+ return new BlockInfo(block.from, block.length, bTop, bBottom - bTop, block.children && block.children.map(b => scaleBlock(b, scaler)), block.deco);
5466
5488
  }
5467
5489
 
5468
5490
  const theme = /*@__PURE__*/Facet.define({ combine: strs => strs.join(" ") });
@@ -9292,6 +9314,7 @@ const defaults = {
9292
9314
  elementStyle: "",
9293
9315
  markers: () => RangeSet.empty,
9294
9316
  lineMarker: () => null,
9317
+ widgetMarker: () => null,
9295
9318
  lineMarkerChange: null,
9296
9319
  initialSpacer: null,
9297
9320
  updateSpacer: null,
@@ -9372,24 +9395,28 @@ const gutterView = /*@__PURE__*/ViewPlugin.fromClass(class {
9372
9395
  let classSet = [];
9373
9396
  let contexts = this.gutters.map(gutter => new UpdateContext(gutter, this.view.viewport, -this.view.documentPadding.top));
9374
9397
  for (let line of this.view.viewportLineBlocks) {
9375
- let text;
9398
+ if (classSet.length)
9399
+ classSet = [];
9376
9400
  if (Array.isArray(line.type)) {
9377
- for (let b of line.type)
9378
- if (b.type == BlockType.Text) {
9379
- text = b;
9380
- break;
9401
+ let first = true;
9402
+ for (let b of line.type) {
9403
+ if (b.type == BlockType.Text && first) {
9404
+ advanceCursor(lineClasses, classSet, b.from);
9405
+ for (let cx of contexts)
9406
+ cx.line(this.view, b, classSet);
9407
+ first = false;
9381
9408
  }
9409
+ else if (b.widget) {
9410
+ for (let cx of contexts)
9411
+ cx.widget(this.view, b);
9412
+ }
9413
+ }
9382
9414
  }
9383
- else {
9384
- text = line.type == BlockType.Text ? line : undefined;
9415
+ else if (line.type == BlockType.Text) {
9416
+ advanceCursor(lineClasses, classSet, line.from);
9417
+ for (let cx of contexts)
9418
+ cx.line(this.view, line, classSet);
9385
9419
  }
9386
- if (!text)
9387
- continue;
9388
- if (classSet.length)
9389
- classSet = [];
9390
- advanceCursor(lineClasses, classSet, line.from);
9391
- for (let cx of contexts)
9392
- cx.line(this.view, text, classSet);
9393
9420
  }
9394
9421
  for (let cx of contexts)
9395
9422
  cx.finish();
@@ -9457,6 +9484,19 @@ class UpdateContext {
9457
9484
  this.i = 0;
9458
9485
  this.cursor = RangeSet.iter(gutter.markers, viewport.from);
9459
9486
  }
9487
+ addElement(view, block, markers) {
9488
+ let { gutter } = this, above = block.top - this.height;
9489
+ if (this.i == gutter.elements.length) {
9490
+ let newElt = new GutterElement(view, block.height, above, markers);
9491
+ gutter.elements.push(newElt);
9492
+ gutter.dom.appendChild(newElt.dom);
9493
+ }
9494
+ else {
9495
+ gutter.elements[this.i].update(view, block.height, above, markers);
9496
+ }
9497
+ this.height = block.bottom;
9498
+ this.i++;
9499
+ }
9460
9500
  line(view, line, extraMarkers) {
9461
9501
  let localMarkers = [];
9462
9502
  advanceCursor(this.cursor, localMarkers, line.from);
@@ -9468,17 +9508,12 @@ class UpdateContext {
9468
9508
  let gutter = this.gutter;
9469
9509
  if (localMarkers.length == 0 && !gutter.config.renderEmptyElements)
9470
9510
  return;
9471
- let above = line.top - this.height;
9472
- if (this.i == gutter.elements.length) {
9473
- let newElt = new GutterElement(view, line.height, above, localMarkers);
9474
- gutter.elements.push(newElt);
9475
- gutter.dom.appendChild(newElt.dom);
9476
- }
9477
- else {
9478
- gutter.elements[this.i].update(view, line.height, above, localMarkers);
9479
- }
9480
- this.height = line.bottom;
9481
- this.i++;
9511
+ this.addElement(view, line, localMarkers);
9512
+ }
9513
+ widget(view, block) {
9514
+ let marker = this.gutter.config.widgetMarker(view, block.widget, block);
9515
+ if (marker)
9516
+ this.addElement(view, block, [marker]);
9482
9517
  }
9483
9518
  finish() {
9484
9519
  let gutter = this.gutter;
@@ -9646,6 +9681,7 @@ const lineNumberGutter = /*@__PURE__*/activeGutters.compute([lineNumberConfig],
9646
9681
  return null;
9647
9682
  return new NumberMarker(formatNumber(view, view.state.doc.lineAt(line.from).number));
9648
9683
  },
9684
+ widgetMarker: () => null,
9649
9685
  lineMarkerChange: update => update.startState.facet(lineNumberConfig) != update.state.facet(lineNumberConfig),
9650
9686
  initialSpacer(view) {
9651
9687
  return new NumberMarker(formatNumber(view, maxLineNumber(view.state.doc.lines)));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemirror/view",
3
- "version": "6.10.1",
3
+ "version": "6.11.1",
4
4
  "description": "DOM view component for the CodeMirror code editor",
5
5
  "scripts": {
6
6
  "test": "cm-runtests",