fix(web): unit test breakers, osk input emulation (partial)

This commit is contained in:
Joshua A. Horton 2023-10-06 13:02:30 +07:00
parent 7c81fc6bac
commit 2d6a74bc04
4 changed files with 26 additions and 23 deletions

View file

@ -130,7 +130,9 @@ export class GestureSequence<Type> extends EventEmitter<EventMap<Type>> {
}
public get allSourceIds(): string[] {
return this.stageReports[this.stageReports.length - 1]?.allSourceIds;
// Note: there is a brief window of time - between construction & the deferred first
// 'stage' event - during which this array may be of length 0.
return this.stageReports[this.stageReports.length - 1]?.allSourceIds ?? [];
}
private get baseGestureSetId(): string {

View file

@ -221,7 +221,10 @@ export class MatcherSelector<Type> extends EventEmitter<EventMap<Type>> {
matcher: null,
result: {
matched: false,
action: null
action: {
type: 'complete',
item: null
}
}
});
}

View file

@ -104,28 +104,17 @@ export default class OSKLayerGroup {
private nearestKey(coord: Omit<InputSample<KeyElement>, 'item'>, layer: OSKLayer): KeyElement {
const baseRect = this.element.getBoundingClientRect();
/**
* Transforms the client rect of child elements to use a coordinate system where the top-left
* of the layer group's bounding rectangle serves as the origin - the same coordinate
* system output by the gesture engine.
* @param childRect
* @returns
*/
const translation = (childRect: DOMRect) => {
return new DOMRect(childRect.x - baseRect.x, childRect.y - baseRect.y, childRect.width, childRect.height);
}
let row: OSKRow = null;
let bestMatchDistance = Number.MAX_VALUE;
// Find the row that the touch-coordinate lies within.
for(const r of layer.rows) {
const rowRect = translation(r.element.getBoundingClientRect());
if(rowRect.top <= coord.targetY && coord.targetY < rowRect.bottom) {
const rowRect = r.element.getBoundingClientRect();
if(rowRect.top <= coord.clientY && coord.clientY < rowRect.bottom) {
row = r;
break;
} else {
const distance = rowRect.top > coord.targetY ? rowRect.top - coord.targetY : coord.targetY - rowRect.bottom;
const distance = rowRect.top > coord.clientY ? rowRect.top - coord.clientY : coord.clientY - rowRect.bottom;
if(distance < bestMatchDistance) {
bestMatchDistance = distance;
@ -144,12 +133,12 @@ export default class OSKLayerGroup {
let dxMax = 24;
let dxMin = 100000;
const x = coord.targetX;
const x = coord.clientX;
for (let k = 0; k < row.keys.length; k++) {
// Second-biggest, though documentation suggests this is probably right.
const keySquare = row.keys[k].square as HTMLElement; // gets the .kmw-key-square containing a key
const squareRect = translation(keySquare.getBoundingClientRect());
const squareRect = keySquare.getBoundingClientRect();
// Find the actual key element.
let childNode = keySquare.firstChild ? keySquare.firstChild as HTMLElement : keySquare;
@ -179,7 +168,7 @@ export default class OSKLayerGroup {
if (dxMin < 100000) {
const t = <HTMLElement>row.keys[closestKeyIndex].square;
const squareRect = translation(t.getBoundingClientRect());
const squareRect = t.getBoundingClientRect();
const x1 = squareRect.left;
const x2 = squareRect.right;

View file

@ -52,6 +52,11 @@ export class BrowserDriver {
simulateOSKEvent(eventSpec: OSKInputEventSpec) {
let target = this.target;
let oskKeyElement = document.getElementById(eventSpec.keyID);
const boundingBox = oskKeyElement.getBoundingClientRect();
const center = {
clientX: boundingBox.left + boundingBox.width/2,
clientY: boundingBox.top + boundingBox.height/2
}
if(!oskKeyElement) {
console.error('Could not find OSK key "' + eventSpec.keyID + '"!');
@ -65,14 +70,18 @@ export class BrowserDriver {
if(keyman.config.hostDevice.touchable) {
downEvent = new Event(BrowserDriver.oskDownTouchType);
upEvent = new Event(BrowserDriver.oskUpTouchType);
downEvent['touches'] = [{"target": oskKeyElement}];
upEvent['touches'] = [{"target": oskKeyElement}];
downEvent['changedTouches'] = [{"target": oskKeyElement}];
upEvent['changedTouches'] = [{"target": oskKeyElement}];
downEvent['touches'] = [{"target": oskKeyElement, ...center}];
upEvent['touches'] = [{"target": oskKeyElement, ...center}];
downEvent['changedTouches'] = [{"target": oskKeyElement, ...center}];
upEvent['changedTouches'] = [{"target": oskKeyElement, ...center}];
} else {
downEvent = new Event(BrowserDriver.oskDownMouseType);
upEvent = new Event(BrowserDriver.oskUpMouseType);
downEvent.clientX = center.clientX;
downEvent.clientY = center.clientY;
downEvent['relatedTarget'] = target;
upEvent.clientX = center.clientX;
upEvent.clientY = center.clientY;
upEvent['relatedTarget'] = target;
// Mouse-click driven OSK use involves use of at least one mouse button.
downEvent['button'] = upEvent['button'] = 0;