Deficient Complex Boundary Behaviour
Closed this issue · 2 comments
@neilius encountered an issue where it's impossible to insert text between two adjacent annotations, and have the text not covered by either.
What do you expect to happen?
Given two annotations, { start: 10, end: 20 }
and { start: 20, end: 30 }
, it should be possible to insert text at position 20
and have the resulting annotations be { start: 10, end: 20 }
and { start: 21, end: 31 }
This is not the default insertion behaviour, but it should be an option.
What happened instead?
Instead, we're able to modify the boundary behaviour for one or the other annotations, but not both. The default behaviour of insertText
results in { start: 10, end: 21 }
and { start: 21, end: 31 }
(the first annotation is extended right, and the second annotation's coverage is unmodified), and the AdjacentBoundaryBehaviour.preserve
behaviour results in { start: 10, end: 20 }
and { start: 20, end: 31 }
(i.e., the first annotation is unmodified and second annotation is extended left to include the new text).
📓 Example Document
Before: https://files.slack.com/files-pri/T5Y8VC3HU-FT9GKNJ9M/before.json
After (with preserve
): https://files.slack.com/files-pri/T5Y8VC3HU-FT7MA4HMK/after.json
Proposal
@tim-evans @neilius and I discussed, and agreed that a good possible solution is to add a (backwards-compatible) way to specify boundary behaviour for text insertion for adjacent annotations both before and after the insertion. This should clarify the relevant bit of code, since currently both before and after boundaries are handled in the same method, despite being subtly different in their handling.
Suggestion for this:
-
Add a new enum option for
AdjacentBoundaryBehaviour
to handle the case provided above -
Add a function overload to
insertText
,deleteText
, andcut
that take either anAdjacentBoundaryBehaviour
option or an object that specifies abefore
/after
(orleading
/trailing
option)For an example of operator overloads:
function insertText(text: string, behaviour: { before: "modify"| "preserve", after: "modify" | "preserve"}): void; function insertText(text: string, behaviour: "modify" | "preserve" | "default"): void; function insertText(text: string, behaviour: { before: "modify"| "preserve", after: "modify" | "preserve"} | "modify" | "preserve") { // Implementation goes here }
-
Update
Change
(Insertion
andDeletion
) withbefore
andafter
behavior instead of a collapsed joint behaviour. -
Update
handleInsert
/handleDelete
code inannotation.ts