@pubann/textae 14.0.1 → 14.1.0

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.
@@ -48257,26 +48257,6 @@
48257
48257
  }
48258
48258
 
48259
48259
  return null
48260
- } // ./src/lib/Editor/AnnotationModel/SpanInstanceContainer/createRangeToSpan/getRenderingPosition/getOffset.js
48261
-
48262
- /* harmony default export */ function getOffset(span, startOfTextNode) {
48263
- const start = span.begin - startOfTextNode
48264
- const end = span.end - startOfTextNode
48265
-
48266
- return {
48267
- start,
48268
- end
48269
- }
48270
- } // ./src/lib/Editor/AnnotationModel/SpanInstanceContainer/createRangeToSpan/getRenderingPosition/getRenderingPositionFromParent.js
48271
-
48272
- /* harmony default export */ function getRenderingPositionFromParent(span) {
48273
- const { start, end } = getOffset(span, span.parent.begin)
48274
-
48275
- return {
48276
- textNode: span.parent.element.firstChild,
48277
- start,
48278
- end
48279
- }
48280
48260
  } // ./src/lib/Editor/isBoundaryCrossing.js
48281
48261
 
48282
48262
  /* harmony default export */ function isBoundaryCrossing(
@@ -48294,19 +48274,31 @@
48294
48274
  isStartOfCandidateSpanBetweenExistsSpan ||
48295
48275
  isEndOfCandidateSpanBetweenExistSpan
48296
48276
  )
48277
+ } // ./src/lib/Editor/AnnotationModel/SpanInstanceContainer/createRangeToSpan/getRenderingPosition/getOffset.js
48278
+
48279
+ function getOffset(begin, end, beginOfParent) {
48280
+ return {
48281
+ start: begin - beginOfParent,
48282
+ end: end - beginOfParent
48283
+ }
48297
48284
  } // ./src/lib/Editor/AnnotationModel/SpanInstanceContainer/createRangeToSpan/getRenderingPosition/getRenderingPositionFromBigBrother.js
48298
48285
 
48299
- /* harmony default export */ function getRenderingPositionFromBigBrother(
48300
- span,
48286
+ function getRenderingPositionFromBigBrother(
48287
+ originalBegin,
48288
+ originalEnd,
48301
48289
  bigBrotherSpan
48302
48290
  ) {
48303
- if (isBoundaryCrossing(span.begin, span.end, bigBrotherSpan)) {
48291
+ if (isBoundaryCrossing(originalBegin, originalEnd, bigBrotherSpan)) {
48304
48292
  throw new Error(
48305
- `span ${span.begin}:${span.end} is crossing with ${bigBrotherSpan.begin}:${bigBrotherSpan.end}`
48293
+ `span ${originalBegin}:${originalEnd} is crossing with ${bigBrotherSpan.begin}:${bigBrotherSpan.end}`
48306
48294
  )
48307
48295
  }
48308
48296
 
48309
- let { start, end } = getOffset(span, bigBrotherSpan.end)
48297
+ let { start, end } = getOffset(
48298
+ originalBegin,
48299
+ originalEnd,
48300
+ bigBrotherSpan.end
48301
+ )
48310
48302
  let textNode = bigBrotherSpan.element.nextSibling
48311
48303
 
48312
48304
  // Google chrome and Safari have a 65536 character limit on the text node.
@@ -48326,44 +48318,42 @@
48326
48318
  }
48327
48319
  } // ./src/lib/Editor/AnnotationModel/SpanInstanceContainer/createRangeToSpan/getRenderingPosition/index.js
48328
48320
 
48329
- /* harmony default export */ function getRenderingPosition(span) {
48330
- const bigBrotherSpan = span.bigBrother
48331
-
48321
+ function getRenderingPosition(begin, end, parent, bigBrotherSpan) {
48332
48322
  if (bigBrotherSpan) {
48333
48323
  // The target text enclosed by span is in a textNode after the bigBrotherSpan
48334
48324
  // if bigBrotherSpan exists.
48335
- return getRenderingPositionFromBigBrother(span, bigBrotherSpan)
48325
+ return getRenderingPositionFromBigBrother(begin, end, bigBrotherSpan)
48336
48326
  } else {
48337
48327
  // There is no big brother if the span is first in the text.
48338
48328
  // The target text enclosed by span is the first child of parent
48339
48329
  // unless bigBrotherSpan exists.
48340
- return getRenderingPositionFromParent(span)
48330
+ return {
48331
+ textNode: parent.element.firstChild,
48332
+ ...getOffset(begin, end, parent.begin)
48333
+ }
48341
48334
  }
48342
- } // ./src/lib/Editor/AnnotationModel/SpanInstanceContainer/createRangeToSpan/createRange.js
48343
-
48344
- /* harmony default export */ function createRange(textNode, start, end) {
48345
- const range = document.createRange()
48346
-
48347
- range.setStart(textNode, start)
48348
- range.setEnd(textNode, end)
48349
-
48350
- return range
48351
48335
  } // ./src/lib/Editor/AnnotationModel/SpanInstanceContainer/createRangeToSpan/index.js
48352
48336
 
48353
48337
  // Get the Range to that new span tag insert.
48354
48338
  // This function works well when no child span is rendered.
48355
48339
  /* harmony default export */ function createRangeToSpan(span) {
48356
- const { textNode, start, end } = getRenderingPosition(span)
48340
+ const { begin, end: originalEnd, parent, bigBrother } = span
48341
+ const { textNode, start, end } = getRenderingPosition(
48342
+ begin,
48343
+ originalEnd,
48344
+ parent,
48345
+ bigBrother
48346
+ )
48357
48347
 
48358
48348
  if (!textNode) {
48359
48349
  throw new Error(
48360
- `The textNode on to create a span ${span.begin}:${span.end} is not found. `
48350
+ `The textNode on to create a span ${begin}:${originalEnd} is not found. `
48361
48351
  )
48362
48352
  }
48363
48353
 
48364
48354
  if (start < 0) {
48365
48355
  throw new Error(
48366
- `start must be positive, but ${start} for ${span.begin}:${span.end}.`
48356
+ `start must be positive, but ${start} for ${begin}:${originalEnd}.`
48367
48357
  )
48368
48358
  }
48369
48359
 
@@ -48378,7 +48368,10 @@
48378
48368
  )
48379
48369
  }
48380
48370
 
48381
- return createRange(textNode, start, end)
48371
+ const range = document.createRange()
48372
+ range.setStart(textNode, start)
48373
+ range.setEnd(textNode, end)
48374
+ return range
48382
48375
  } // ./src/lib/Editor/AnnotationModel/SpanInstanceContainer/SpanInstance/index.js
48383
48376
 
48384
48377
  class SpanInstance {
@@ -48694,10 +48687,9 @@
48694
48687
  getShortenInAnchorNodeToFocusNodeDirection(
48695
48688
  textSelectionAdjuster,
48696
48689
  sourceDoc,
48697
- spanInstanceContainer,
48698
48690
  spanConfig
48699
48691
  ) {
48700
- const { anchor, focus } = spanInstanceContainer.textSelection
48692
+ const { anchor, focus } = this._spanInstanceContainer.textSelection
48701
48693
 
48702
48694
  if (anchor < focus) {
48703
48695
  // shorten the left boundary
@@ -48726,10 +48718,9 @@
48726
48718
  getShortenInFocusNodeToAnchorNodeDirection(
48727
48719
  textSelectionAdjuster,
48728
48720
  sourceDoc,
48729
- spanInstanceContainer,
48730
48721
  spanConfig
48731
48722
  ) {
48732
- const { anchor, focus } = spanInstanceContainer.textSelection
48723
+ const { anchor, focus } = this._spanInstanceContainer.textSelection
48733
48724
 
48734
48725
  if (focus < anchor) {
48735
48726
  // shorten the left boundary
@@ -48758,10 +48749,9 @@
48758
48749
  getExpandedInAnchorNodeToFocusNodeDirection(
48759
48750
  textSelectionAdjuster,
48760
48751
  sourceDoc,
48761
- spanInstanceContainer,
48762
48752
  spanConfig
48763
48753
  ) {
48764
- const { anchor, focus } = spanInstanceContainer.textSelection
48754
+ const { anchor, focus } = this._spanInstanceContainer.textSelection
48765
48755
 
48766
48756
  if (anchor < focus) {
48767
48757
  // expand to the right
@@ -48790,10 +48780,9 @@
48790
48780
  getExpandedInFocusNodeToAnchorNodeDirection(
48791
48781
  textSelectionAdjuster,
48792
48782
  sourceDoc,
48793
- spanInstanceContainer,
48794
48783
  spanConfig
48795
48784
  ) {
48796
- const { anchor, focus } = spanInstanceContainer.textSelection
48785
+ const { anchor, focus } = this._spanInstanceContainer.textSelection
48797
48786
 
48798
48787
  if (focus < anchor) {
48799
48788
  // expand to the right
@@ -55234,6 +55223,28 @@
55234
55223
  this._textBox.updateLineHeight()
55235
55224
  }
55236
55225
  }
55226
+ } // ./src/lib/Editor/forwardMethods.js
55227
+
55228
+ /* harmony default export */ function forwardMethods(
55229
+ delegator,
55230
+ getTargetFunction,
55231
+ methods
55232
+ ) {
55233
+ for (const method of methods) {
55234
+ delegator[method] = (...args) => {
55235
+ // Determine the target when executing the method
55236
+ const target = getTargetFunction()
55237
+ console.assert(
55238
+ target[method],
55239
+ `No ${method} method to forward`,
55240
+ target
55241
+ )
55242
+
55243
+ return target[method].apply(target, args)
55244
+ }
55245
+ }
55246
+
55247
+ return delegator
55237
55248
  } // ./src/lib/Editor/AnnotationModel/index.js
55238
55249
 
55239
55250
  class AnnotationModel {
@@ -55331,6 +55342,15 @@
55331
55342
  this.#textBox
55332
55343
  )
55333
55344
 
55345
+ forwardMethods(this, () => this.#spanInstanceContainer, [
55346
+ 'getDenotationSpan',
55347
+ 'isBoundaryCrossingWithOtherSpans',
55348
+ 'hasParentOf',
55349
+ 'validateNewDenotationSpan',
55350
+ 'validateNewBlockSpan',
55351
+ 'validateEditableText'
55352
+ ])
55353
+
55334
55354
  this.denotationDefinitionContainer = new DefinitionContainer(
55335
55355
  eventEmitter,
55336
55356
  'entity',
@@ -55519,6 +55539,14 @@
55519
55539
  return this.#spanInstanceContainer.textSelection
55520
55540
  }
55521
55541
 
55542
+ findDenotation(begin, end) {
55543
+ return this.#spanInstanceContainer.find('denotation', begin, end)
55544
+ }
55545
+
55546
+ findBlock(begin, end) {
55547
+ return this.#spanInstanceContainer.find('block', begin, end)
55548
+ }
55549
+
55522
55550
  getTextBetween(begin, end) {
55523
55551
  return this.sourceDoc.substring(begin, end)
55524
55552
  }
@@ -55540,13 +55568,10 @@
55540
55568
  return effectedSpans
55541
55569
  }
55542
55570
 
55543
- get #selectedText() {
55544
- const { begin, end } = this.textSelection
55545
- return this.getTextBetween(begin, end)
55546
- }
55547
-
55548
55571
  hasCharacters(spanConfig) {
55549
- return spanConfig.removeBlankCharacters(this.#selectedText).length > 0
55572
+ const { begin, end } = this.textSelection
55573
+ const selectedText = this.getTextBetween(begin, end)
55574
+ return spanConfig.removeBlankCharacters(selectedText).length > 0
55550
55575
  }
55551
55576
 
55552
55577
  getTextSelection(spanConfig, textSelectionAdjuster) {
@@ -55567,22 +55592,6 @@
55567
55592
  }
55568
55593
  }
55569
55594
 
55570
- validateNewDenotationSpan(begin, end) {
55571
- return this.#spanInstanceContainer.validateNewDenotationSpan(begin, end)
55572
- }
55573
-
55574
- validateNewBlockSpan(begin, end, spanID) {
55575
- return this.#spanInstanceContainer.validateNewBlockSpan(
55576
- begin,
55577
- end,
55578
- spanID
55579
- )
55580
- }
55581
-
55582
- validateEditableText(begin, end) {
55583
- return this.#spanInstanceContainer.validateEditableText(begin, end)
55584
- }
55585
-
55586
55595
  getInstanceContainerFor(annotationType) {
55587
55596
  switch (annotationType) {
55588
55597
  case 'span':
@@ -58606,12 +58615,8 @@
58606
58615
  }
58607
58616
  } // ./src/lib/Editor/UseCase/Presenter/EditModeSwitch/shrinkSpan/shrinkSpanToSelection.js
58608
58617
 
58609
- /**
58610
- *
58611
- * @param {import('../../../../AnnotationModel/SpanInstanceContainer').default} spanInstanceContainer
58612
- */
58613
58618
  function shrinkSpanToSelection(
58614
- spanInstanceContainer,
58619
+ annotationModel,
58615
58620
  sourceDoc,
58616
58621
  commander,
58617
58622
  textSelectionAdjuster,
@@ -58619,24 +58624,23 @@
58619
58624
  spanConfig,
58620
58625
  moveHandler
58621
58626
  ) {
58622
- const { begin, end } = spanInstanceContainer
58623
- .get(spanId)
58627
+ const { begin, end } = annotationModel
58628
+ .getSpan(spanId)
58624
58629
  .getShortenInAnchorNodeToFocusNodeDirection(
58625
58630
  textSelectionAdjuster,
58626
58631
  sourceDoc,
58627
- spanInstanceContainer,
58628
58632
  spanConfig
58629
58633
  )
58630
58634
 
58631
58635
  // The span cross exists spans.
58632
- if (spanInstanceContainer.isBoundaryCrossingWithOtherSpans(begin, end)) {
58636
+ if (annotationModel.isBoundaryCrossingWithOtherSpans(begin, end)) {
58633
58637
  alertify_default().warning(
58634
58638
  'A span cannot be shrunken to make a boundary crossing.'
58635
58639
  )
58636
58640
  return false
58637
58641
  }
58638
58642
 
58639
- const doesExists = spanInstanceContainer.find('denotation', begin, end)
58643
+ const doesExists = annotationModel.findDenotation(begin, end)
58640
58644
 
58641
58645
  if (begin < end && !doesExists) {
58642
58646
  moveHandler(begin, end)
@@ -58650,7 +58654,7 @@
58650
58654
 
58651
58655
  /* harmony default export */ function shrinkSpan(
58652
58656
  editorHTMLElement,
58653
- spanInstanceContainer,
58657
+ annotationModel,
58654
58658
  sourceDoc,
58655
58659
  selectionModel,
58656
58660
  commander,
@@ -58665,7 +58669,7 @@
58665
58669
  // Get the next span before removing the old span.
58666
58670
  const nextSpan = getRightSpanElement(editorHTMLElement, spanId)
58667
58671
  const removed = shrinkSpanToSelection(
58668
- spanInstanceContainer,
58672
+ annotationModel,
58669
58673
  sourceDoc,
58670
58674
  commander,
58671
58675
  textSelectionAdjuster,
@@ -58801,7 +58805,6 @@
58801
58805
  class SpanEditor {
58802
58806
  #editorHTMLElement
58803
58807
  #annotationModel
58804
- #spanInstanceContainer
58805
58808
  #selectionModel
58806
58809
  #commander
58807
58810
  #menuState
@@ -58817,7 +58820,6 @@
58817
58820
  ) {
58818
58821
  this.#editorHTMLElement = editorHTMLElement
58819
58822
  this.#annotationModel = annotationModel
58820
- this.#spanInstanceContainer = annotationModel.spanInstanceContainer
58821
58823
  this.#selectionModel = selectionModel
58822
58824
  this.#commander = commander
58823
58825
  this.#menuState = menuState
@@ -58829,7 +58831,7 @@
58829
58831
 
58830
58832
  if (selectionWrapper.isParentOfAnchorNodeTextBox) {
58831
58833
  if (selectionWrapper.isParentOfFocusNodeTextBox) {
58832
- this.#anchorNodeInTextBoxFocusNodeInTextBox(selectionWrapper)
58834
+ this.#anchorNodeInTextBoxFocusNodeInTextBox()
58833
58835
  return
58834
58836
  }
58835
58837
  if (selectionWrapper.isParentOfFocusNodeDenotationSpan) {
@@ -58926,16 +58928,13 @@
58926
58928
 
58927
58929
  // The span cross exists spans.
58928
58930
  if (
58929
- this.#spanInstanceContainer.isBoundaryCrossingWithOtherSpans(
58930
- begin,
58931
- end
58932
- )
58931
+ this.#annotationModel.isBoundaryCrossingWithOtherSpans(begin, end)
58933
58932
  ) {
58934
58933
  return
58935
58934
  }
58936
58935
 
58937
58936
  // A span cannot be expanded a span to the same as an existing span.
58938
- if (this.#spanInstanceContainer.find('denotation', begin, end)) {
58937
+ if (this.#annotationModel.findDenotation(begin, end)) {
58939
58938
  return
58940
58939
  }
58941
58940
 
@@ -58957,10 +58956,7 @@
58957
58956
 
58958
58957
  // The span cross exists spans.
58959
58958
  if (
58960
- this.#spanInstanceContainer.isBoundaryCrossingWithOtherSpans(
58961
- begin,
58962
- end
58963
- )
58959
+ this.#annotationModel.isBoundaryCrossingWithOtherSpans(begin, end)
58964
58960
  ) {
58965
58961
  alertify_default().warning(
58966
58962
  'A span cannot be shrunken to make a boundary crossing.'
@@ -58968,11 +58964,7 @@
58968
58964
  return
58969
58965
  }
58970
58966
 
58971
- const doesExists = this.#spanInstanceContainer.find(
58972
- 'denotation',
58973
- begin,
58974
- end
58975
- )
58967
+ const doesExists = this.#annotationModel.findDenotation(begin, end)
58976
58968
  if (begin < end && !doesExists) {
58977
58969
  this.#commander.invoke(
58978
58970
  this.#commander.factory.moveDenotationSpanCommand(
@@ -59016,12 +59008,11 @@
59016
59008
 
59017
59009
  return {
59018
59010
  spanID,
59019
- ...this.#spanInstanceContainer
59020
- .get(spanID)
59011
+ ...this.#annotationModel
59012
+ .getSpan(spanID)
59021
59013
  .getExpandedInAnchorNodeToFocusNodeDirection(
59022
59014
  this.#menuState.textSelectionAdjuster,
59023
59015
  this.#annotationModel.sourceDoc,
59024
- this.#annotationModel.spanInstanceContainer,
59025
59016
  this.#spanConfig
59026
59017
  )
59027
59018
  }
@@ -59038,12 +59029,11 @@
59038
59029
 
59039
59030
  return {
59040
59031
  spanID,
59041
- ...this.#spanInstanceContainer
59042
- .get(spanID)
59032
+ ...this.#annotationModel
59033
+ .getSpan(spanID)
59043
59034
  .getExpandedInFocusNodeToAnchorNodeDirection(
59044
59035
  this.#menuState.textSelectionAdjuster,
59045
59036
  this.#annotationModel.sourceDoc,
59046
- this.#annotationModel.spanInstanceContainer,
59047
59037
  this.#spanConfig
59048
59038
  )
59049
59039
  }
@@ -59083,12 +59073,11 @@
59083
59073
 
59084
59074
  return {
59085
59075
  spanID,
59086
- ...this.#spanInstanceContainer
59087
- .get(spanID)
59076
+ ...this.#annotationModel
59077
+ .getSpan(spanID)
59088
59078
  .getShortenInFocusNodeToAnchorNodeDirection(
59089
59079
  this.#menuState.textSelectionAdjuster,
59090
59080
  this.#annotationModel.sourceDoc,
59091
- this.#annotationModel.spanInstanceContainer,
59092
59081
  this.#spanConfig
59093
59082
  )
59094
59083
  }
@@ -59105,19 +59094,18 @@
59105
59094
 
59106
59095
  return {
59107
59096
  spanID,
59108
- ...this.#spanInstanceContainer
59109
- .get(spanID)
59097
+ ...this.#annotationModel
59098
+ .getSpan(spanID)
59110
59099
  .getShortenInAnchorNodeToFocusNodeDirection(
59111
59100
  this.#menuState.textSelectionAdjuster,
59112
59101
  this.#annotationModel.sourceDoc,
59113
- this.#annotationModel.spanInstanceContainer,
59114
59102
  this.#spanConfig
59115
59103
  )
59116
59104
  }
59117
59105
  }
59118
59106
  }
59119
59107
 
59120
- #anchorNodeInTextBoxFocusNodeInTextBox(selectionWrapper) {
59108
+ #anchorNodeInTextBoxFocusNodeInTextBox() {
59121
59109
  // The parent of the focusNode is the text.
59122
59110
  this.#create()
59123
59111
  }
@@ -59333,9 +59321,9 @@
59333
59321
 
59334
59322
  #getShrinkableEndSpanID(selectionWrapper) {
59335
59323
  if (selectionWrapper.ancestorDenotationSpanOfAnchorNode) {
59336
- const { anchor } = this.#spanInstanceContainer.textSelection
59324
+ const { anchor } = this.#annotationModel.textSelection
59337
59325
 
59338
- const { begin, end } = this.#spanInstanceContainer.getDenotationSpan(
59326
+ const { begin, end } = this.#annotationModel.getDenotationSpan(
59339
59327
  selectionWrapper.ancestorDenotationSpanOfAnchorNode.id
59340
59328
  )
59341
59329
  if (anchor === begin || anchor === end) {
@@ -59432,16 +59420,15 @@
59432
59420
  #expand(spanID) {
59433
59421
  this.#selectionModel.removeAll()
59434
59422
 
59435
- const { begin, end } = this.#spanInstanceContainer
59436
- .get(spanID)
59423
+ const { begin, end } = this.#annotationModel
59424
+ .getSpan(spanID)
59437
59425
  .getExpandedInAnchorNodeToFocusNodeDirection(
59438
59426
  this.#menuState.textSelectionAdjuster,
59439
59427
  this.#annotationModel.sourceDoc,
59440
- this.#annotationModel.spanInstanceContainer,
59441
59428
  this.#spanConfig
59442
59429
  )
59443
59430
 
59444
- if (this.#spanInstanceContainer.validateNewDenotationSpan(begin, end)) {
59431
+ if (this.#annotationModel.validateNewDenotationSpan(begin, end)) {
59445
59432
  this.#commander.invoke(
59446
59433
  this.#commander.factory.moveDenotationSpanCommand(
59447
59434
  spanID,
@@ -59457,7 +59444,7 @@
59457
59444
  #shrink(spanID) {
59458
59445
  shrinkSpan(
59459
59446
  this.#editorHTMLElement,
59460
- this.#spanInstanceContainer,
59447
+ this.#annotationModel,
59461
59448
  this.#annotationModel.sourceDoc,
59462
59449
  this.#selectionModel,
59463
59450
  this.#commander,
@@ -59481,7 +59468,7 @@
59481
59468
  get #isReplicateAuto() {
59482
59469
  return this.#menuState.isPushed('auto replicate')
59483
59470
  }
59484
- } // ./src/lib/Editor/UseCase/Presenter/EditModeSwitch/EditMode/index.js
59471
+ } // ./src/lib/Editor/UseCase/Presenter/EditModeSwitch/EditMode.js
59485
59472
 
59486
59473
  class EditMode {
59487
59474
  // Interface methods
@@ -61103,7 +61090,7 @@
61103
61090
  onRender: (item) => `${item.id} ${item.label}`
61104
61091
  })
61105
61092
  }
61106
- } // ./src/lib/Editor/UseCase/Presenter/EditModeSwitch/EditMode/PropertyEditor.js
61093
+ } // ./src/lib/Editor/UseCase/Presenter/EditModeSwitch/PropertyEditor.js
61107
61094
 
61108
61095
  class PropertyEditor {
61109
61096
  #editorHTMLElement
@@ -61168,27 +61155,6 @@
61168
61155
  this.#mousePoint
61169
61156
  )
61170
61157
  }
61171
- } // ./src/lib/Editor/forwardMethods.js
61172
-
61173
- /* harmony default export */ function forwardMethods(
61174
- delegator,
61175
- getTargetFunction,
61176
- methods
61177
- ) {
61178
- for (const method of methods) {
61179
- delegator[method] = (...args) => {
61180
- const target = getTargetFunction()
61181
- console.assert(
61182
- target[method],
61183
- `No ${method} method to forward`,
61184
- target
61185
- )
61186
-
61187
- return target[method].apply(target, args)
61188
- }
61189
- }
61190
-
61191
- return delegator
61192
61158
  } // ./src/lib/component/TypeDefinitionDialog/template.js
61193
61159
 
61194
61160
  function template_template(context) {
@@ -63391,7 +63357,7 @@
63391
63357
  #mouseEventHandler
63392
63358
  #spanEditor
63393
63359
  #textBox
63394
- #spanInstanceContainer
63360
+ #annotationModel
63395
63361
  #propertyEditor
63396
63362
  #selectionModel
63397
63363
  #menuState
@@ -63460,7 +63426,7 @@
63460
63426
  this.#textBox = editorHTMLElement.querySelector(
63461
63427
  '.textae-editor__text-box'
63462
63428
  )
63463
- this.#spanInstanceContainer = annotationModel.spanInstanceContainer
63429
+ this.#annotationModel = annotationModel
63464
63430
  this.#menuState = menuState
63465
63431
 
63466
63432
  const attributeEditor = new AttributeEditor(
@@ -63500,12 +63466,9 @@
63500
63466
 
63501
63467
  applyTextSelectionWithTouchDevice() {
63502
63468
  if (isTextSelectionInTextBox(this.#textBox)) {
63503
- const { begin, end } = this.#spanInstanceContainer.textSelection
63469
+ const { begin, end } = this.#annotationModel.textSelection
63504
63470
  const isSelectionTextCrossingAnySpan =
63505
- this.#spanInstanceContainer.isBoundaryCrossingWithOtherSpans(
63506
- begin,
63507
- end
63508
- )
63471
+ this.#annotationModel.isBoundaryCrossingWithOtherSpans(begin, end)
63509
63472
 
63510
63473
  const { isParentOfBothNodesSame } = new SelectionWrapper()
63511
63474
  this.#menuState.updateButtonsToOperateSpanWithTouchDevice(
@@ -63720,10 +63683,7 @@
63720
63683
 
63721
63684
  // The span cross exists spans.
63722
63685
  if (
63723
- this.#annotationModel.spanInstanceContainer.isBoundaryCrossingWithOtherSpans(
63724
- begin,
63725
- end
63726
- )
63686
+ this.#annotationModel.isBoundaryCrossingWithOtherSpans(begin, end)
63727
63687
  ) {
63728
63688
  alertify_default().warning(
63729
63689
  'A span cannot be modified to make a boundary crossing.'
@@ -63732,21 +63692,11 @@
63732
63692
  }
63733
63693
 
63734
63694
  // There is parent span.
63735
- if (
63736
- this.#annotationModel.spanInstanceContainer.hasParentOf(
63737
- begin,
63738
- end,
63739
- spanID
63740
- )
63741
- ) {
63695
+ if (this.#annotationModel.hasParentOf(begin, end, spanID)) {
63742
63696
  return
63743
63697
  }
63744
63698
 
63745
- const doesExists = this.#annotationModel.spanInstanceContainer.find(
63746
- 'block',
63747
- begin,
63748
- end
63749
- )
63699
+ const doesExists = this.#annotationModel.findBlock(begin, end)
63750
63700
  if (begin < end && !doesExists) {
63751
63701
  this.#commander.invoke(
63752
63702
  this.#commander.factory.moveBlockSpanCommand(spanID, begin, end)
@@ -63780,12 +63730,11 @@
63780
63730
 
63781
63731
  this.#selectionModel.removeAll()
63782
63732
 
63783
- const { begin, end } = this.#annotationModel.spanInstanceContainer
63784
- .get(spanID)
63733
+ const { begin, end } = this.#annotationModel
63734
+ .getSpan(spanID)
63785
63735
  .getExpandedInAnchorNodeToFocusNodeDirection(
63786
63736
  this.#menuState.textSelectionAdjuster,
63787
63737
  this.#annotationModel.sourceDoc,
63788
- this.#annotationModel.spanInstanceContainer,
63789
63738
  this.#spanConfig
63790
63739
  )
63791
63740
 
@@ -63803,7 +63752,7 @@
63803
63752
 
63804
63753
  shrinkSpan(
63805
63754
  this.#editorHTMLElement,
63806
- this.#annotationModel.spanInstanceContainer,
63755
+ this.#annotationModel,
63807
63756
  this.#annotationModel.sourceDoc,
63808
63757
  this.#selectionModel,
63809
63758
  this.#commander,
@@ -63844,12 +63793,11 @@
63844
63793
 
63845
63794
  return {
63846
63795
  spanID,
63847
- ...this.#annotationModel.spanInstanceContainer
63848
- .get(spanID)
63796
+ ...this.#annotationModel
63797
+ .getSpan(spanID)
63849
63798
  .getExpandedInAnchorNodeToFocusNodeDirection(
63850
63799
  this.#menuState.textSelectionAdjuster,
63851
63800
  this.#annotationModel.sourceDoc,
63852
- this.#annotationModel.spanInstanceContainer,
63853
63801
  this.#spanConfig
63854
63802
  )
63855
63803
  }
@@ -63866,12 +63814,11 @@
63866
63814
 
63867
63815
  return {
63868
63816
  spanID,
63869
- ...this.#annotationModel.spanInstanceContainer
63870
- .get(spanID)
63817
+ ...this.#annotationModel
63818
+ .getSpan(spanID)
63871
63819
  .getExpandedInFocusNodeToAnchorNodeDirection(
63872
63820
  this.#menuState.textSelectionAdjuster,
63873
63821
  this.#annotationModel.sourceDoc,
63874
- this.#annotationModel.spanInstanceContainer,
63875
63822
  this.#spanConfig
63876
63823
  )
63877
63824
  }
@@ -63911,12 +63858,11 @@
63911
63858
 
63912
63859
  return {
63913
63860
  spanID,
63914
- ...this.#annotationModel.spanInstanceContainer
63915
- .get(spanID)
63861
+ ...this.#annotationModel
63862
+ .getSpan(spanID)
63916
63863
  .getShortenInFocusNodeToAnchorNodeDirection(
63917
63864
  this.#menuState.textSelectionAdjuster,
63918
63865
  this.#annotationModel.sourceDoc,
63919
- this.#annotationModel.spanInstanceContainer,
63920
63866
  this.#spanConfig
63921
63867
  )
63922
63868
  }
@@ -63933,12 +63879,11 @@
63933
63879
 
63934
63880
  return {
63935
63881
  spanID,
63936
- ...this.#annotationModel.spanInstanceContainer
63937
- .get(spanID)
63882
+ ...this.#annotationModel
63883
+ .getSpan(spanID)
63938
63884
  .getShortenInAnchorNodeToFocusNodeDirection(
63939
63885
  this.#menuState.textSelectionAdjuster,
63940
63886
  this.#annotationModel.sourceDoc,
63941
- this.#annotationModel.spanInstanceContainer,
63942
63887
  this.#spanConfig
63943
63888
  )
63944
63889
  }
@@ -64225,8 +64170,8 @@
64225
64170
  #mouseEventHandler
64226
64171
  #spanEditor
64227
64172
  #textBox
64228
- #spanInstanceContainer
64229
64173
  #propertyEditor
64174
+ #annotationModel
64230
64175
  #selectionModel
64231
64176
  #menuState
64232
64177
  #pallet
@@ -64294,7 +64239,7 @@
64294
64239
  this.#textBox = editorHTMLElement.querySelector(
64295
64240
  '.textae-editor__text-box'
64296
64241
  )
64297
- this.#spanInstanceContainer = annotationModel.spanInstanceContainer
64242
+ this.#annotationModel = annotationModel
64298
64243
  this.#menuState = menuState
64299
64244
 
64300
64245
  const attributeEditor = new AttributeEditor(
@@ -64335,12 +64280,9 @@
64335
64280
 
64336
64281
  applyTextSelectionWithTouchDevice() {
64337
64282
  if (isTextSelectionInTextBox(this.#textBox)) {
64338
- const { begin, end } = this.#spanInstanceContainer.textSelection
64283
+ const { begin, end } = this.#annotationModel.textSelection
64339
64284
  const isSelectionTextCrossingAnySpan =
64340
- this.#spanInstanceContainer.isBoundaryCrossingWithOtherSpans(
64341
- begin,
64342
- end
64343
- )
64285
+ this.#annotationModel.isBoundaryCrossingWithOtherSpans(begin, end)
64344
64286
 
64345
64287
  const { isParentOfBothNodesTextBox } = new SelectionWrapper()
64346
64288
  this.#menuState.updateButtonsToOperateSpanWithTouchDevice(
@@ -64867,6 +64809,78 @@
64867
64809
  get #textBox() {
64868
64810
  return this.#editorHTMLElement.querySelector('.textae-editor__text-box')
64869
64811
  }
64812
+ } // ./src/lib/debounce300.js
64813
+
64814
+ /* harmony default export */ function debounce300(func) {
64815
+ return debounce_default()(func, 300)
64816
+ } // ./src/lib/Editor/UseCase/Presenter/EditModeSwitch/ViewMode.js
64817
+
64818
+ class ViewMode extends EditMode {
64819
+ #editorHTMLElement
64820
+ #annotationModel
64821
+ #startOffset
64822
+ #endOffset
64823
+
64824
+ constructor(editorHTMLElement, eventEmitter, annotationModel) {
64825
+ super()
64826
+
64827
+ this.#editorHTMLElement = editorHTMLElement
64828
+ this.#annotationModel = annotationModel
64829
+
64830
+ const emitSelectedTextChange = debounce300(() => {
64831
+ this.#updateSelectedTextOffsets()
64832
+
64833
+ eventEmitter.emit('textae-event.editor.selected-text.change')
64834
+ })
64835
+
64836
+ document.addEventListener('selectionchange', emitSelectedTextChange)
64837
+ }
64838
+
64839
+ get selectedText() {
64840
+ if (this.#startOffset === undefined || this.#endOffset === undefined) {
64841
+ return {
64842
+ status: 'unselected'
64843
+ }
64844
+ }
64845
+
64846
+ if (
64847
+ this.#annotationModel.isBoundaryCrossingWithOtherSpans(
64848
+ this.#startOffset,
64849
+ this.#endOffset
64850
+ )
64851
+ ) {
64852
+ return {
64853
+ status: 'cross boundary detected'
64854
+ }
64855
+ }
64856
+
64857
+ return {
64858
+ begin: this.#startOffset,
64859
+ end: this.#endOffset,
64860
+ status: 'selected'
64861
+ }
64862
+ }
64863
+
64864
+ #updateSelectedTextOffsets() {
64865
+ const selection = document.getSelection()
64866
+ if (selection && selection.rangeCount > 0) {
64867
+ const range = selection.getRangeAt(0)
64868
+ const textBox = this.#editorHTMLElement.querySelector(
64869
+ '.textae-editor__text-box'
64870
+ )
64871
+
64872
+ if (
64873
+ textBox.contains(range.startContainer) &&
64874
+ textBox.contains(range.endContainer)
64875
+ ) {
64876
+ this.#startOffset = this.#annotationModel.textSelection.begin
64877
+ this.#endOffset = this.#annotationModel.textSelection.end
64878
+ }
64879
+ } else {
64880
+ this.#startOffset = undefined
64881
+ this.#endOffset = undefined
64882
+ }
64883
+ }
64870
64884
  } // ./src/lib/Editor/UseCase/Presenter/EditModeSwitch/index.js
64871
64885
 
64872
64886
  class EditModeSwitch {
@@ -64874,6 +64888,7 @@
64874
64888
  #blockEditMode
64875
64889
  #relationEditMode
64876
64890
  #textEditMode
64891
+ #viewMode
64877
64892
  #editModeState
64878
64893
  #annotationModel
64879
64894
  #startUpOptions
@@ -64934,6 +64949,12 @@
64934
64949
  commander
64935
64950
  )
64936
64951
 
64952
+ this.#viewMode = new ViewMode(
64953
+ editorHTMLElement,
64954
+ eventEmitter,
64955
+ annotationModel
64956
+ )
64957
+
64937
64958
  new ModeTransitionReactor(
64938
64959
  editorHTMLElement,
64939
64960
  eventEmitter,
@@ -64952,7 +64973,7 @@
64952
64973
  .on('textae-event.editor.relation.click', (event, relation) =>
64953
64974
  this.currentMode.relationClicked(event, relation)
64954
64975
  )
64955
- .on('textae-event.editor.relation-bollard.click', (event, entity) =>
64976
+ .on('textae-event.editor.relation-bollard.click', (_, entity) =>
64956
64977
  this.currentMode.relationBollardClicked(entity)
64957
64978
  )
64958
64979
  }
@@ -65060,7 +65081,17 @@
65060
65081
  case MODE.EDIT_TEXT:
65061
65082
  return this.#textEditMode
65062
65083
  default:
65063
- return new EditMode()
65084
+ return this.#viewMode
65085
+ }
65086
+ }
65087
+
65088
+ getSelectedText() {
65089
+ if (this.#editModeState.currentState === MODE.VIEW) {
65090
+ return this.#viewMode.selectedText
65091
+ } else {
65092
+ return {
65093
+ status: 'unselected'
65094
+ }
65064
65095
  }
65065
65096
  }
65066
65097
  } // ./src/lib/Editor/UseCase/Presenter/Horizontal.js
@@ -65174,10 +65205,6 @@
65174
65205
  this._selectionModel.selectSpan(spanId)
65175
65206
  }
65176
65207
  }
65177
- } // ./src/lib/component/SettingDialog/reflectImmediately/debounce300.js
65178
-
65179
- /* harmony default export */ function debounce300(func) {
65180
- return debounce_default()(func, 300)
65181
65208
  } // ./src/lib/component/SettingDialog/reflectImmediately/bindChangeLockConfig.js
65182
65209
 
65183
65210
  /* harmony default export */ function bindChangeLockConfig(
@@ -65282,7 +65309,7 @@
65282
65309
  )
65283
65310
  } // ./package.json
65284
65311
 
65285
- const package_namespaceObject = { rE: '14.0.1' } // ./src/lib/component/SettingDialog/EscapeSequence.js
65312
+ const package_namespaceObject = { rE: '14.1.0' } // ./src/lib/component/SettingDialog/EscapeSequence.js
65286
65313
  class EscapeSequence {
65287
65314
  static escape(str) {
65288
65315
  return str
@@ -65728,7 +65755,8 @@
65728
65755
  'toRelationEditMode',
65729
65756
  'toTextEditMode',
65730
65757
  'toggleSimpleMode',
65731
- 'changeModeByShortcut'
65758
+ 'changeModeByShortcut',
65759
+ 'getSelectedText'
65732
65760
  ])
65733
65761
  forwardMethods(this, () => this.#editModeSwitch.currentMode, [
65734
65762
  'createSpanWithTouchDevice',
@@ -75176,16 +75204,11 @@ class, which describe what happened, whenever the view is updated.
75176
75204
  closestRect = rect
75177
75205
  closestX = dx
75178
75206
  closestY = dy
75179
- let side = dy
75180
- ? y < rect.top
75181
- ? -1
75182
- : 1
75183
- : dx
75184
- ? x < rect.left
75185
- ? -1
75186
- : 1
75187
- : 0
75188
- closestOverlap = !side || (side > 0 ? i < rects.length - 1 : i > 0)
75207
+ closestOverlap = !dx
75208
+ ? true
75209
+ : x < rect.left
75210
+ ? i > 0
75211
+ : i < rects.length - 1
75189
75212
  }
75190
75213
  if (dx == 0) {
75191
75214
  if (
@@ -75390,12 +75413,23 @@ class, which describe what happened, whenever the view is updated.
75390
75413
  // line before. This is used to detect such a result so that it can be
75391
75414
  // ignored (issue #401).
75392
75415
  function isSuspiciousSafariCaretResult(node, offset, x) {
75393
- let len
75416
+ let len,
75417
+ scan = node
75394
75418
  if (node.nodeType != 3 || offset != (len = node.nodeValue.length))
75395
75419
  return false
75396
- for (let next = node.nextSibling; next; next = next.nextSibling)
75397
- if (next.nodeType != 1 || next.nodeName != 'BR') return false
75398
- return textRange(node, len - 1, len).getBoundingClientRect().left > x
75420
+ for (;;) {
75421
+ // Check that there is no content after this node
75422
+ let next = scan.nextSibling
75423
+ if (next) {
75424
+ if (next.nodeName == 'BR') break
75425
+ return false
75426
+ } else {
75427
+ let parent = scan.parentNode
75428
+ if (!parent || parent.nodeName == 'DIV') break
75429
+ scan = parent
75430
+ }
75431
+ }
75432
+ return textRange(node, len - 1, len).getBoundingClientRect().right > x
75399
75433
  }
75400
75434
  // Chrome will move positions between lines to the start of the next line
75401
75435
  function isSuspiciousChromeCaretResult(node, offset, x) {
@@ -79167,13 +79201,16 @@ in the editor view.
79167
79201
  display: 'flex',
79168
79202
  height: '100%',
79169
79203
  boxSizing: 'border-box',
79170
- insetInlineStart: 0,
79171
79204
  zIndex: 200
79172
79205
  },
79206
+ '.cm-gutters-before': { insetInlineStart: 0 },
79207
+ '.cm-gutters-after': { insetInlineEnd: 0 },
79173
79208
  '&light .cm-gutters': {
79174
79209
  backgroundColor: '#f5f5f5',
79175
79210
  color: '#6c6c6c',
79176
- borderRight: '1px solid #ddd'
79211
+ border: '0px solid #ddd',
79212
+ '&.cm-gutters-before': { borderRightWidth: '1px' },
79213
+ '&.cm-gutters-after': { borderLeftWidth: '1px' }
79177
79214
  },
79178
79215
  '&dark .cm-gutters': {
79179
79216
  backgroundColor: '#333338',
@@ -79374,6 +79411,7 @@ in the editor view.
79374
79411
  })
79375
79412
  if (
79376
79413
  window.EditContext &&
79414
+ browser.android &&
79377
79415
  view.constructor.EDIT_CONTEXT !== false &&
79378
79416
  // Chrome <126 doesn't support inverted selections in edit context (#1392)
79379
79417
  !(browser.chrome && browser.chrome_version < 126)
@@ -84346,7 +84384,8 @@ Should not provide widgets with a `toDOM` method.
84346
84384
  lineMarkerChange: null,
84347
84385
  initialSpacer: null,
84348
84386
  updateSpacer: null,
84349
- domEventHandlers: {}
84387
+ domEventHandlers: {},
84388
+ side: 'before'
84350
84389
  }
84351
84390
  const activeGutters = /*@__PURE__*/ Facet.define()
84352
84391
  /**
@@ -84378,17 +84417,22 @@ sticky`](https://developer.mozilla.org/en-US/docs/Web/CSS/position#sticky)).
84378
84417
  class {
84379
84418
  constructor(view) {
84380
84419
  this.view = view
84420
+ this.domAfter = null
84381
84421
  this.prevViewport = view.viewport
84382
84422
  this.dom = document.createElement('div')
84383
- this.dom.className = 'cm-gutters'
84423
+ this.dom.className = 'cm-gutters cm-gutters-before'
84384
84424
  this.dom.setAttribute('aria-hidden', 'true')
84385
84425
  this.dom.style.minHeight =
84386
84426
  this.view.contentHeight / this.view.scaleY + 'px'
84387
84427
  this.gutters = view.state
84388
84428
  .facet(activeGutters)
84389
84429
  .map((conf) => new SingleGutterView(view, conf))
84390
- for (let gutter of this.gutters) this.dom.appendChild(gutter.dom)
84391
84430
  this.fixed = !view.state.facet(unfixGutters)
84431
+ for (let gutter of this.gutters) {
84432
+ if (gutter.config.side == 'after')
84433
+ this.getDOMAfter().appendChild(gutter.dom)
84434
+ else this.dom.appendChild(gutter.dom)
84435
+ }
84392
84436
  if (this.fixed) {
84393
84437
  // FIXME IE11 fallback, which doesn't support position: sticky,
84394
84438
  // by using position: relative + event handlers that realign the
@@ -84398,6 +84442,18 @@ sticky`](https://developer.mozilla.org/en-US/docs/Web/CSS/position#sticky)).
84398
84442
  this.syncGutters(false)
84399
84443
  view.scrollDOM.insertBefore(this.dom, view.contentDOM)
84400
84444
  }
84445
+ getDOMAfter() {
84446
+ if (!this.domAfter) {
84447
+ this.domAfter = document.createElement('div')
84448
+ this.domAfter.className = 'cm-gutters cm-gutters-after'
84449
+ this.domAfter.setAttribute('aria-hidden', 'true')
84450
+ this.domAfter.style.minHeight =
84451
+ this.view.contentHeight / this.view.scaleY + 'px'
84452
+ this.domAfter.style.position = this.fixed ? 'sticky' : ''
84453
+ this.view.scrollDOM.appendChild(this.domAfter)
84454
+ }
84455
+ return this.domAfter
84456
+ }
84401
84457
  update(update) {
84402
84458
  if (this.updateGutters(update)) {
84403
84459
  // Detach during sync when the viewport changed significantly
@@ -84410,18 +84466,24 @@ sticky`](https://developer.mozilla.org/en-US/docs/Web/CSS/position#sticky)).
84410
84466
  this.syncGutters(vpOverlap < (vpB.to - vpB.from) * 0.8)
84411
84467
  }
84412
84468
  if (update.geometryChanged) {
84413
- this.dom.style.minHeight =
84414
- this.view.contentHeight / this.view.scaleY + 'px'
84469
+ let min = this.view.contentHeight / this.view.scaleY + 'px'
84470
+ this.dom.style.minHeight = min
84471
+ if (this.domAfter) this.domAfter.style.minHeight = min
84415
84472
  }
84416
84473
  if (this.view.state.facet(unfixGutters) != !this.fixed) {
84417
84474
  this.fixed = !this.fixed
84418
84475
  this.dom.style.position = this.fixed ? 'sticky' : ''
84476
+ if (this.domAfter)
84477
+ this.domAfter.style.position = this.fixed ? 'sticky' : ''
84419
84478
  }
84420
84479
  this.prevViewport = update.view.viewport
84421
84480
  }
84422
84481
  syncGutters(detach) {
84423
84482
  let after = this.dom.nextSibling
84424
- if (detach) this.dom.remove()
84483
+ if (detach) {
84484
+ this.dom.remove()
84485
+ if (this.domAfter) this.domAfter.remove()
84486
+ }
84425
84487
  let lineClasses = dist_RangeSet.iter(
84426
84488
  this.view.state.facet(gutterLineClass),
84427
84489
  this.view.viewport.from
@@ -84456,7 +84518,10 @@ sticky`](https://developer.mozilla.org/en-US/docs/Web/CSS/position#sticky)).
84456
84518
  }
84457
84519
  }
84458
84520
  for (let cx of contexts) cx.finish()
84459
- if (detach) this.view.scrollDOM.insertBefore(this.dom, after)
84521
+ if (detach) {
84522
+ this.view.scrollDOM.insertBefore(this.dom, after)
84523
+ if (this.domAfter) this.view.scrollDOM.appendChild(this.domAfter)
84524
+ }
84460
84525
  }
84461
84526
  updateGutters(update) {
84462
84527
  let prev = update.startState.facet(activeGutters),
@@ -84490,7 +84555,11 @@ sticky`](https://developer.mozilla.org/en-US/docs/Web/CSS/position#sticky)).
84490
84555
  g.dom.remove()
84491
84556
  if (gutters.indexOf(g) < 0) g.destroy()
84492
84557
  }
84493
- for (let g of gutters) this.dom.appendChild(g.dom)
84558
+ for (let g of gutters) {
84559
+ if (g.config.side == 'after')
84560
+ this.getDOMAfter().appendChild(g.dom)
84561
+ else this.dom.appendChild(g.dom)
84562
+ }
84494
84563
  this.gutters = gutters
84495
84564
  }
84496
84565
  return change
@@ -84498,6 +84567,7 @@ sticky`](https://developer.mozilla.org/en-US/docs/Web/CSS/position#sticky)).
84498
84567
  destroy() {
84499
84568
  for (let view of this.gutters) view.destroy()
84500
84569
  this.dom.remove()
84570
+ if (this.domAfter) this.domAfter.remove()
84501
84571
  }
84502
84572
  },
84503
84573
  {
@@ -84505,9 +84575,13 @@ sticky`](https://developer.mozilla.org/en-US/docs/Web/CSS/position#sticky)).
84505
84575
  EditorView.scrollMargins.of((view) => {
84506
84576
  let value = view.plugin(plugin)
84507
84577
  if (!value || value.gutters.length == 0 || !value.fixed) return null
84578
+ let before = value.dom.offsetWidth * view.scaleX,
84579
+ after = value.domAfter
84580
+ ? value.domAfter.offsetWidth * view.scaleX
84581
+ : 0
84508
84582
  return view.textDirection == Direction.LTR
84509
- ? { left: value.dom.offsetWidth * view.scaleX }
84510
- : { right: value.dom.offsetWidth * view.scaleX }
84583
+ ? { left: before, right: after }
84584
+ : { right: before, left: after }
84511
84585
  })
84512
84586
  }
84513
84587
  )
@@ -84772,7 +84846,8 @@ Facet used to create markers in the line number gutter next to widgets.
84772
84846
  )
84773
84847
  return max == spacer.number ? spacer : new NumberMarker(max)
84774
84848
  },
84775
- domEventHandlers: state.facet(lineNumberConfig).domEventHandlers
84849
+ domEventHandlers: state.facet(lineNumberConfig).domEventHandlers,
84850
+ side: 'before'
84776
84851
  })
84777
84852
  )
84778
84853
  /**
@@ -90201,6 +90276,10 @@ state.
90201
90276
  return Decoration.none
90202
90277
  },
90203
90278
  update(folded, tr) {
90279
+ if (tr.isUserEvent('delete'))
90280
+ tr.changes.iterChangedRanges(
90281
+ (fromA, toA) => (folded = clearTouchedFolds(folded, fromA, toA))
90282
+ )
90204
90283
  folded = folded.map(tr.changes)
90205
90284
  for (let e of tr.effects) {
90206
90285
  if (
@@ -90227,19 +90306,8 @@ state.
90227
90306
  }
90228
90307
  }
90229
90308
  // Clear folded ranges that cover the selection head
90230
- if (tr.selection) {
90231
- let onSelection = false,
90232
- { head } = tr.selection.main
90233
- folded.between(head, head, (a, b) => {
90234
- if (a < head && b > head) onSelection = true
90235
- })
90236
- if (onSelection)
90237
- folded = folded.update({
90238
- filterFrom: head,
90239
- filterTo: head,
90240
- filter: (a, b) => b <= head || a >= head
90241
- })
90242
- }
90309
+ if (tr.selection)
90310
+ folded = clearTouchedFolds(folded, tr.selection.main.head)
90243
90311
  return folded
90244
90312
  },
90245
90313
  provide: (f) => EditorView.decorations.from(f),
@@ -90264,6 +90332,19 @@ state.
90264
90332
  return Decoration.set(ranges, true)
90265
90333
  }
90266
90334
  })
90335
+ function clearTouchedFolds(folded, from, to = from) {
90336
+ let touched = false
90337
+ folded.between(from, to, (a, b) => {
90338
+ if (a < to && b > from) touched = true
90339
+ })
90340
+ return !touched
90341
+ ? folded
90342
+ : folded.update({
90343
+ filterFrom: from,
90344
+ filterTo: to,
90345
+ filter: (a, b) => a >= to || b <= from
90346
+ })
90347
+ }
90267
90348
  /**
90268
90349
  Get a [range set](https://codemirror.net/6/docs/ref/#state.RangeSet) containing the folded ranges
90269
90350
  in the given state.
@@ -109763,14 +109844,16 @@ data-button-type="${type}">
109763
109844
  denotations = [],
109764
109845
  attributes = [],
109765
109846
  relations = [],
109766
- blocks = []
109847
+ blocks = [],
109848
+ selectedText
109767
109849
  }) {
109768
109850
  return {
109769
109851
  text,
109770
109852
  denotations: denotations.sort(byID),
109771
109853
  attributes: attributes.sort(byID),
109772
109854
  relations: relations.sort(byID),
109773
- blocks: blocks.sort(byID)
109855
+ blocks: blocks.sort(byID),
109856
+ selectedText
109774
109857
  }
109775
109858
  } // ./src/lib/Editor/diffOfAnnotation/index.js
109776
109859
 
@@ -110904,7 +110987,8 @@ data-button-type="${type}">
110904
110987
  'pasteEntitiesFromSystemClipboard',
110905
110988
  'activate',
110906
110989
  'deactivate',
110907
- 'applyTextSelectionWithTouchDevice'
110990
+ 'applyTextSelectionWithTouchDevice',
110991
+ 'getSelectedText'
110908
110992
  ])
110909
110993
 
110910
110994
  this.#contextMenu = contextMenu
@@ -111735,19 +111819,23 @@ data-button-type="${type}">
111735
111819
 
111736
111820
  class EditorEventListener {
111737
111821
  #eventEmitter
111738
- #event
111822
+ #events
111739
111823
  #listener
111740
111824
 
111741
- constructor(eventEmitter, event, listener) {
111825
+ constructor(eventEmitter, events, listener) {
111742
111826
  this.#eventEmitter = eventEmitter
111743
- this.#event = event
111827
+ this.#events = events
111744
111828
  this.#listener = listener
111745
111829
 
111746
- eventEmitter.on(event, this.#listener)
111830
+ for (const e of events) {
111831
+ eventEmitter.on(e, this.#listener)
111832
+ }
111747
111833
  }
111748
111834
 
111749
111835
  dispose() {
111750
- this.#eventEmitter.off(this.#event, this.#listener)
111836
+ for (const e of this.#events) {
111837
+ this.#eventEmitter.off(e, this.#listener)
111838
+ }
111751
111839
  }
111752
111840
  } // ./src/lib/Editor/BrowserEventListener.js
111753
111841
 
@@ -112055,22 +112143,15 @@ data-button-type="${type}">
112055
112143
  #isDenotation(id) {
112056
112144
  return this.#annotationModel.entityInstanceContainer.hasDenotation(id)
112057
112145
  }
112058
- } // ./src/lib/Editor/filterIfModelModified.js
112146
+ } // ./src/lib/Editor/filterIfModified.js
112059
112147
 
112060
- function filterIfModelModified(annotationModel, callback) {
112061
- let previous = annotationModel.externalFormat
112148
+ function filterIfModified(initialAnnotation) {
112149
+ let previous = initialAnnotation
112062
112150
 
112063
- return function (annotationModel) {
112064
- // TextAE's internal data treats spans and entities separately.
112065
- // On the other hand, in the external data, they are treated together as denotation.
112066
- // For example, when a Span is added, an event is fired twice,
112067
- // once for the addition of the Span and once for the addition of the Entity.
112068
- // There is no change in denotation between these two events;
112069
- // we want to be notified only when there is a change in denotation.
112070
- // Notify only when there is a change by comparing with external data format.
112071
- if (diffOfAnnotation(previous, annotationModel.externalFormat)) {
112072
- previous = annotationModel.externalFormat
112073
- callback(annotationModel.externalFormat)
112151
+ return function (currentAnnotation, callback) {
112152
+ if (diffOfAnnotation(previous, currentAnnotation)) {
112153
+ previous = currentAnnotation
112154
+ callback(currentAnnotation)
112074
112155
  }
112075
112156
  }
112076
112157
  } // ./src/lib/Editor/index.js
@@ -112125,6 +112206,18 @@ data-button-type="${type}">
112125
112206
  this.#annotationModel = annotationModel
112126
112207
  this.#eventEmitter = eventEmitter
112127
112208
 
112209
+ // A container of selection state.
112210
+ const selectionModel = new SelectionModel(eventEmitter, annotationModel)
112211
+ this.#useCase = new UseCase(
112212
+ element,
112213
+ editorID,
112214
+ mousePoint,
112215
+ eventEmitter,
112216
+ annotationModel,
112217
+ startUpOptions,
112218
+ selectionModel
112219
+ )
112220
+
112128
112221
  if (startUpOptions.inspect) {
112129
112222
  const callback = (annotation) => {
112130
112223
  const destinationElement = document.querySelector(
@@ -112145,20 +112238,7 @@ data-button-type="${type}">
112145
112238
  element
112146
112239
  )
112147
112240
 
112148
- // A container of selection state.
112149
- const selectionModel = new SelectionModel(eventEmitter, annotationModel)
112150
- const useCase = new UseCase(
112151
- element,
112152
- editorID,
112153
- mousePoint,
112154
- eventEmitter,
112155
- annotationModel,
112156
- startUpOptions,
112157
- selectionModel
112158
- )
112159
- this.#useCase = useCase
112160
-
112161
- forwardMethods(this, () => useCase, [
112241
+ forwardMethods(this, () => this.#useCase, [
112162
112242
  'copyEntitiesToSystemClipboard',
112163
112243
  'cutEntitiesToSystemClipboard',
112164
112244
  'pasteEntitiesFromSystemClipboard',
@@ -112207,7 +112287,7 @@ data-button-type="${type}">
112207
112287
  if (typeof callback == 'function') {
112208
112288
  this.#lastSelectedDenotationIDCallback = new EditorEventListener(
112209
112289
  this.#eventEmitter,
112210
- 'textae-event.selection-model.last-selected-denotation-id.change',
112290
+ ['textae-event.selection-model.last-selected-denotation-id.change'],
112211
112291
  callback
112212
112292
  )
112213
112293
  }
@@ -112268,12 +112348,31 @@ data-button-type="${type}">
112268
112348
  }
112269
112349
 
112270
112350
  #newInspector(callback) {
112351
+ // TextAE's internal data treats spans and entities separately.
112352
+ // On the other hand, in the external data, they are treated together as denotation.
112353
+ // For example, when a Span is added, an event is fired twice,
112354
+ // once for the addition of the Span and once for the addition of the Entity.
112355
+ // There is no change in denotation between these two events;
112356
+ // we want to be notified only when there is a change in denotation.
112357
+ // Notify only when there is a change by comparing with external data format.
112358
+ const filter = filterIfModified(this.#inspectReport)
112359
+
112271
112360
  return new EditorEventListener(
112272
112361
  this.#eventEmitter,
112273
- 'textae-event.annotation-data.events-observer.change',
112274
- filterIfModelModified(this.#annotationModel, callback)
112362
+ [
112363
+ 'textae-event.annotation-data.events-observer.change',
112364
+ 'textae-event.editor.selected-text.change'
112365
+ ],
112366
+ () => filter(this.#inspectReport, callback)
112275
112367
  )
112276
112368
  }
112369
+
112370
+ get #inspectReport() {
112371
+ return {
112372
+ ...this.#annotationModel.externalFormat,
112373
+ selectedText: this.#useCase.getSelectedText()
112374
+ }
112375
+ }
112277
112376
  } // ./src/lib/createEditor.js
112278
112377
 
112279
112378
  function createEditor(element, tool) {