# IController/AController

IController is an interface for what is essentially an event handler.
AController is a minimal abstract class over that interface.
MarkedText will take any object that satisfies this interface for the property 'controller'.

``` ts
interface IController {
  link(mt: IMarkedText): void
  unlink(): void
  onMouseUpText(e: Event, charRange: [number, number]): void
  onMouseUpMark(e: Event, charRange: [number, number], marks: IMark[]): void
  onMouseUpSelection(e: Event, charRange: [number, number]): void
  onMouseUpMetaString(e: Event, charRange: [number, number], metaStringText: string): void
  onMouseUpOther(e: Event): void
}
```

``` ts
abstract class AController implements IController {
  protected markedText: IMarkedText | null = null
  public link(mt: IMarkedText) {
    this.markedText = mt
  }
  public unlink() {
    this.markedText = null
  }
  public abstract onMouseUpText(e: Event, charRange: [number, number]): void
  public abstract onMouseUpMark(e: Event, charRange: [number, number], marks: IMark[]): void
  public abstract onMouseUpSelection(e: Event, charRange: [number, number]): void
  public abstract onMouseUpMetaString(e: Event, charRange: [number, number], metaStringText: string): void
  public abstract onMouseUpOther(e: Event): void
}
```

Your custom controller must implement IController and probably should
 extend AController if you want to be able to directly access the MarkedText
 from your controller, e.g. to modify highlighting.
MarkedText calls link and unlink appropriately so that an AController should
 always have access to the MarkedText it is a property of.

# Reasoning

This allows for callbacks to trigger when there is a mouse up event in:
- plain text spans
- marked spans
- the selection span (internal selection controlled by vue-mark-text)
- meta strings added to the marked text (fragile feature for now)
- anywhere else in the component

e is the actual mouse event triggering the controller.
charRange is the tuple of character indices for the span the up-click
 is triggered in, to allow for easy manipulation of clicked text.
marks is the list of marks under the mouse on mouse up.
metaStringText is the text of the meta-string (foreign to the provided source text)
 that is clicked.
Any of these events can have no callback.

Obviously, the events could be emitted from MarkedText and caught in the
 parent object, but this was deemed a more robust solution.

# Concrete Controllers

Three example controllers are provided in the library and displayed on the
 [Example](example.html) page.

The first is `NullController`, which allows no interactivity and merely
 displays the marked text as initialized.

The second is `TextSelectionController`.
This controller allows selection of text and marks and triggers supplied
 callbacks when selection is changed.
- The selection is managed internally and will not interfere with selection
 on other parts of the window for browsers that allow only one selection.
- If a section of text is selected, a callback
 'selectNewCbk' is triggered with the calculated character range.
- If a mark is clicked and not dragged (which would trigger the above), the
 callback 'selectMarkCbk' is triggered with the marks under the mouse.
- If a selection, meta-string, or other is clicked, the event is consumed
 and selection is reset.
- Selection is automatically set along with the callbacks; this may be
 optional in the future.

The third is `WordSelectionController`.
This controller inherits from `TextSelectionController` with the added
 functionality of expanding and contracting selected text to the nearest
 whitespace/word boundaries.
- If a section of text is selected or a word is clicked, the text is
 expanded or contracted to the nearest word boundary and
 'selectNewCbk' is triggered.
