mirror of
https://github.com/keymanapp/keyman.git
synced 2026-09-21 23:27:39 +00:00
For Suggestion application: OutputTarget.restoreTo
This commit is contained in:
parent
75fb17fb90
commit
66bf2856f5
10 changed files with 147 additions and 4 deletions
7
common/predictive-text/message.d.ts
vendored
7
common/predictive-text/message.d.ts
vendored
|
|
@ -216,6 +216,13 @@ interface Context {
|
|||
* A concrete suggestion
|
||||
*/
|
||||
interface Suggestion {
|
||||
/**
|
||||
* Indicates the externally-supplied id of the Transform that prompted
|
||||
* the Suggestion. Automatically handled by the LMLayer; models should
|
||||
* not handle this field.
|
||||
*/
|
||||
transformId?: number;
|
||||
|
||||
/**
|
||||
* The suggested update to the buffer. Note that this transform should
|
||||
* be applied AFTER the instigating transform, if any.
|
||||
|
|
|
|||
|
|
@ -233,9 +233,17 @@ class LMLayerWorker {
|
|||
switch(payload.message) {
|
||||
case 'predict':
|
||||
let {transform, context} = payload;
|
||||
|
||||
// Let's not rely on the model to copy transform IDs.
|
||||
let suggestions = model.predict(transform, context);
|
||||
suggestions.forEach(function(s: Suggestion) {
|
||||
s.transformId = transform.id;
|
||||
});
|
||||
|
||||
// Now that the suggestions are ready, send them out!
|
||||
this.cast('suggestions', {
|
||||
token: payload.token,
|
||||
suggestions: model.predict(transform, context)
|
||||
suggestions: suggestions
|
||||
});
|
||||
break;
|
||||
case 'unload':
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ namespace com.keyman.dom {
|
|||
var n = start.node.ownerDocument.createTextNode(s);
|
||||
|
||||
let range = this.root.ownerDocument.createRange();
|
||||
range.setStart(start.node, s.length);
|
||||
range.setStart(start.node, start.offset);
|
||||
range.collapse(true);
|
||||
range.insertNode(n);
|
||||
}
|
||||
|
|
@ -207,5 +207,35 @@ namespace com.keyman.dom {
|
|||
}
|
||||
Lsel.collapseToEnd();
|
||||
}
|
||||
|
||||
protected setTextAfterCaret(s: string) {
|
||||
if(!this.hasSelection()) {
|
||||
return;
|
||||
}
|
||||
|
||||
let caret = this.getCarets().end;
|
||||
let delta = s._kmwLength();
|
||||
let Lsel = this.root.ownerDocument.getSelection();
|
||||
|
||||
if(delta == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This is designed explicitly for use in direct-setting operations; deadkeys
|
||||
// will be handled after this method.
|
||||
|
||||
if(caret.node.nodeType == 3) {
|
||||
let textStart = <Text> caret.node;
|
||||
textStart.replaceData(caret.offset, textStart.length, s);
|
||||
} else {
|
||||
// Create a new text node - empty control
|
||||
var n = caret.node.ownerDocument.createTextNode(s);
|
||||
|
||||
let range = this.root.ownerDocument.createRange();
|
||||
range.setStart(caret.node, caret.offset);
|
||||
range.collapse(true);
|
||||
range.insertNode(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -196,7 +196,7 @@ namespace com.keyman.dom {
|
|||
var n = this.doc.createTextNode(s);
|
||||
|
||||
let range = this.doc.createRange();
|
||||
range.setStart(start.node, s.length);
|
||||
range.setStart(start.node, start.offset);
|
||||
range.collapse(true);
|
||||
range.insertNode(n);
|
||||
}
|
||||
|
|
@ -214,6 +214,36 @@ namespace com.keyman.dom {
|
|||
Lsel.collapseToEnd();
|
||||
}
|
||||
|
||||
protected setTextAfterCaret(s: string) {
|
||||
if(!this.hasSelection()) {
|
||||
return;
|
||||
}
|
||||
|
||||
let caret = this.getCarets().end;
|
||||
let delta = s._kmwLength();
|
||||
let Lsel = this.doc.getSelection();
|
||||
|
||||
if(delta == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This is designed explicitly for use in direct-setting operations; deadkeys
|
||||
// will be handled after this method.
|
||||
|
||||
if(caret.node.nodeType == 3) {
|
||||
let textStart = <Text> caret.node;
|
||||
textStart.replaceData(caret.offset, textStart.length, s);
|
||||
} else {
|
||||
// Create a new text node - empty control
|
||||
var n = caret.node.ownerDocument.createTextNode(s);
|
||||
|
||||
let range = this.root.ownerDocument.createRange();
|
||||
range.setStart(caret.node, caret.offset);
|
||||
range.collapse(true);
|
||||
range.insertNode(n);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function saveProperties
|
||||
* Scope Private
|
||||
|
|
|
|||
|
|
@ -92,6 +92,13 @@ namespace com.keyman.dom {
|
|||
this.setCaret(newCaret);
|
||||
}
|
||||
|
||||
protected setTextAfterCaret(s: string) {
|
||||
let c = this.getCaret();
|
||||
|
||||
this.root.value = this.getTextBeforeCaret() + s;
|
||||
this.setCaret(c);
|
||||
}
|
||||
|
||||
getTextAfterCaret(): string {
|
||||
this.getCaret();
|
||||
return this.getText()._kmwSubstring(this.processedSelectionEnd);
|
||||
|
|
|
|||
|
|
@ -99,6 +99,13 @@ namespace com.keyman.dom {
|
|||
this.setCaret(newCaret);
|
||||
}
|
||||
|
||||
protected setTextAfterCaret(s: string) {
|
||||
let c = this.getCaret();
|
||||
|
||||
this.root.value = this.getTextBeforeCaret() + s;
|
||||
this.setCaret(c);
|
||||
}
|
||||
|
||||
getTextAfterCaret(): string {
|
||||
this.getCaret();
|
||||
return this.getText()._kmwSubstring(this.processedSelectionEnd);
|
||||
|
|
|
|||
|
|
@ -59,5 +59,9 @@ namespace com.keyman.dom {
|
|||
this.adjustDeadkeys(s._kmwLength());
|
||||
this.root.setTextBeforeCaret(this.root.getTextBeforeCaret() + s);
|
||||
}
|
||||
|
||||
protected setTextAfterCaret(s: string) {
|
||||
this.root.setText(this.getTextBeforeCaret() + s, this.getTextBeforeCaret()._kmwLength());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -295,7 +295,7 @@ namespace com.keyman.dom {
|
|||
this.setText(textValue, null);
|
||||
}
|
||||
|
||||
private setText(t?: string, cp?: number): void {
|
||||
setText(t?: string, cp?: number): void {
|
||||
var tLen=0;
|
||||
var t1: string, t2: string;
|
||||
|
||||
|
|
|
|||
|
|
@ -162,6 +162,37 @@ namespace com.keyman.text {
|
|||
return new Transcription(keyEvent, transform, Mock.from(original), removedDks, insertedDks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the `OutputTarget` to the indicated state. Designed for use with `Transcription.preInput`.
|
||||
* @param original An `OutputTarget` (usually a `Mock`).
|
||||
*/
|
||||
restoreTo(original: OutputTarget) {
|
||||
//
|
||||
this.setTextBeforeCaret(original.getTextBeforeCaret());
|
||||
this.setTextAfterCaret(original.getTextAfterCaret());
|
||||
|
||||
// Also, restore the deadkeys!
|
||||
this._dks = original._dks.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to `restoreTo` - allows directly setting the 'before' context to that of another
|
||||
* `OutputTarget`.
|
||||
* @param s
|
||||
*/
|
||||
protected setTextBeforeCaret(s: string): void {
|
||||
// This one's easy enough to provide a default implementation for.
|
||||
this.deleteCharsBeforeCaret(this.getTextBeforeCaret()._kmwLength());
|
||||
this.insertTextBeforeCaret(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to `restoreTo` - allows directly setting the 'after' context to that of another
|
||||
* `OutputTarget`.
|
||||
* @param s
|
||||
*/
|
||||
protected abstract setTextAfterCaret(s: string): void;
|
||||
|
||||
/**
|
||||
* Returns the underlying element / document modeled by the wrapper.
|
||||
*/
|
||||
|
|
@ -317,5 +348,9 @@ namespace com.keyman.text {
|
|||
this.text = this.getTextBeforeCaret() + s + this.getTextAfterCaret();
|
||||
this.caretIndex += s.kmwLength();
|
||||
}
|
||||
|
||||
protected setTextAfterCaret(s: string): void {
|
||||
this.text = this.getTextBeforeCaret() + s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -251,6 +251,21 @@ namespace com.keyman.text.prediction {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the context and output state of KMW immediately before the prediction with
|
||||
* token `id` was generated. Must correspond to a 'recent' one, as only so many are stored
|
||||
* in `ModelManager`'s history buffer.
|
||||
* @param id A unique identifier corresponding to a recent `Transcription`.
|
||||
* @returns The matching `Transcription`, or `null` none is found.
|
||||
*/
|
||||
public getPredictionState(id: number): Transcription {
|
||||
let match = this.recentTranscriptions.filter(function(t: Transcription) {
|
||||
return t.token == id;
|
||||
})
|
||||
|
||||
return match.length == 0 ? null : match[0];
|
||||
}
|
||||
|
||||
public shutdown() {
|
||||
this.lmEngine.shutdown();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue