Francisco Hodge 2020-09-23 23:06:03 -04:00
parent 548cc8d753
commit 8e2339567d
3 changed files with 118 additions and 143 deletions

View File

@ -380,19 +380,16 @@ class SimpleKeyboard {
* Handles button mouseup
*/
handleButtonMouseUp(button) {
this.dispatch(instance => {
/**
* Remove active class
*/
instance.recurseButtons(buttonElement => {
buttonElement.classList.remove(this.activeButtonClass);
});
instance.isMouseHold = false;
if (instance.holdInteractionTimeout)
clearTimeout(instance.holdInteractionTimeout);
/**
* Remove active class
*/
this.recurseButtons(buttonElement => {
buttonElement.classList.remove(this.activeButtonClass);
});
this.isMouseHold = false;
if (this.holdInteractionTimeout) clearTimeout(this.holdInteractionTimeout);
/**
* Calling onKeyReleased
*/
@ -543,7 +540,6 @@ class SimpleKeyboard {
/**
* inputName changed. This requires a caretPosition reset
*/
// TODO: Review side-effects
if (this.options.debug) {
console.log("inputName changed. caretPosition reset.");
}
@ -741,8 +737,6 @@ class SimpleKeyboard {
* Handles simple-keyboard event listeners
*/
setEventListeners() {
const { useTouchEvents, useMouseEvents } = this.options;
/**
* Only first instance should set the event listeners
*/
@ -754,42 +748,10 @@ class SimpleKeyboard {
/**
* Event Listeners
*/
document.onkeyup = this.handleKeyUp;
document.onkeydown = this.handleKeyDown;
/**
* Pointer events
*/
if (
this.utilities.pointerEventsSupported() &&
!useTouchEvents &&
!useMouseEvents
) {
document.onpointerdown = this.handlePointerDown;
document.onpointerup = this.handlePointerUp;
document.onpointercancel = this.handlePointerUp;
this.keyboardDOM.onpointerdown = this.handleKeyboardContainerMouseDown;
/**
* Touch events
*/
} else if (useTouchEvents) {
document.ontouchstart = this.handlePointerDown;
document.ontouchend = this.handlePointerUp;
document.ontouchcancel = this.handlePointerUp;
this.keyboardDOM.ontouchstart = this.handleKeyboardContainerMouseDown;
/**
* Mouse events
*/
} else if (!useTouchEvents) {
document.onmousedown = this.handlePointerDown;
document.onmouseup = this.handlePointerUp;
this.keyboardDOM.onmousedown = this.handleKeyboardContainerMouseDown;
}
document.addEventListener("keyup", this.handleKeyUp);
document.addEventListener("keydown", this.handleKeyDown);
document.addEventListener("mouseup", this.handleMouseUp);
document.addEventListener("touchend", this.handleTouchEnd);
}
}
@ -814,51 +776,42 @@ class SimpleKeyboard {
}
/**
* Event Handler: PointerDown
* Event Handler: MouseUp
*/
handlePointerDown(event) {
handleMouseUp(event) {
this.caretEventHandler(event);
}
/**
* Event Handler: PointerUp
* Event Handler: TouchEnd
*/
handlePointerUp(event) {
this.handleButtonMouseUp();
// TODO: Will need further investigation
// https://github.com/hodgef/simple-keyboard/issues/54
/* istanbul ignore next */
setTimeout(() => {
this.caretEventHandler(event);
}, 0);
/* istanbul ignore next */
handleTouchEnd(event) {
this.caretEventHandler(event);
}
/**
* Called by {@link setEventListeners} when an event that warrants a cursor position update is triggered
*/
caretEventHandler(event) {
if (this.options.disableCaretPositioning) {
this.setCaretPosition(null);
return;
}
let targetTagName;
if (event.target.tagName) {
targetTagName = event.target.tagName.toLowerCase();
}
/* istanbul ignore next */
this.dispatch(instance => {
const isKeyboard =
event.target === instance.keyboardDOM ||
(event.target && instance.keyboardDOM.contains(event.target));
// if (!this.isMouseHold) {
// instance.isMouseHold = false;
// }
if (instance.isMouseHold) {
instance.isMouseHold = false;
}
if (targetTagName === "textarea" || targetTagName === "input") {
if (
(targetTagName === "textarea" || targetTagName === "input") &&
!instance.options.disableCaretPositioning
) {
/**
* Tracks current cursor position
* As keys are pressed, text will be added/removed at that position within the input.
@ -877,9 +830,10 @@ class SimpleKeyboard {
`(${instance.keyboardDOMClass})`
);
}
// TODO: Review side-effects
} else if (!isKeyboard) {
} else if (instance.options.disableCaretPositioning || !isKeyboard) {
/**
* If we toggled off disableCaretPositioning, we must ensure caretPosition doesn't persist once reactivated.
*/
instance.setCaretPosition(null);
}
});
@ -905,6 +859,18 @@ class SimpleKeyboard {
`Destroying simple-keyboard instance: ${this.currentInstanceName}`
);
/**
* Remove document listeners
*/
document.removeEventListener("keyup", this.handleKeyUp);
document.removeEventListener("keydown", this.handleKeyDown);
document.removeEventListener("mouseup", this.handleMouseUp);
document.removeEventListener("touchend", this.handleTouchEnd);
document.onpointerup = null;
document.ontouchend = null;
document.ontouchcancel = null;
document.onmouseup = null;
/**
* Remove buttons
*/
@ -924,6 +890,8 @@ class SimpleKeyboard {
};
this.recurseButtons(deleteButton);
this.recurseButtons = null;
deleteButton = null;
/**
@ -938,55 +906,12 @@ class SimpleKeyboard {
*/
this.clear();
/**
* Remove timouts
*/
/* istanbul ignore next */
if (this.holdInteractionTimeout) clearTimeout(this.holdInteractionTimeout);
/* istanbul ignore next */
if (this.holdTimeout) clearTimeout(this.holdTimeout);
/**
* Remove instance
*/
window["SimpleKeyboardInstances"][this.currentInstanceName] = null;
delete window["SimpleKeyboardInstances"][this.currentInstanceName];
/**
* Removing document listeners if there are no more instances
*/
if (!Object.keys(window["SimpleKeyboardInstances"]).length) {
/**
* Remove document listeners
*/
document.onkeydown = null;
document.onkeyup = null;
document.onpointerdown = null;
document.onpointerup = null;
document.onmousedown = null;
document.onmouseup = null;
document.ontouchstart = null;
document.ontouchend = null;
document.ontouchcancel = null;
if (this.options.debug) {
console.log(
"Destroy: No instances remaining. Document listeners removed",
window["SimpleKeyboardInstances"]
);
}
} else {
if (this.options.debug) {
console.log(
"Destroy: Instances remaining! Document listeners not removed",
window["SimpleKeyboardInstances"]
);
}
}
/**
* Reset initialized flag
*/
@ -1500,6 +1425,7 @@ class SimpleKeyboard {
* Handle mouse events
*/
buttonDOM.onclick = () => {
this.isMouseHold = false;
this.handleButtonClicked(button);
};
buttonDOM.onmousedown = e => {
@ -1570,6 +1496,36 @@ class SimpleKeyboard {
*/
this.initialized = true;
/**
* Handling parent events
*/
/* istanbul ignore next */
if (
this.utilities.pointerEventsSupported() &&
!useTouchEvents &&
!useMouseEvents
) {
document.onpointerup = () => this.handleButtonMouseUp();
this.keyboardDOM.onpointerdown = e =>
this.handleKeyboardContainerMouseDown(e);
} else if (useTouchEvents) {
/**
* Handling ontouchend, ontouchcancel
*/
document.ontouchend = () => this.handleButtonMouseUp();
document.ontouchcancel = () => this.handleButtonMouseUp();
this.keyboardDOM.ontouchstart = e =>
this.handleKeyboardContainerMouseDown(e);
} else if (!useTouchEvents) {
/**
* Handling mouseup
*/
document.onmouseup = () => this.handleButtonMouseUp();
this.keyboardDOM.onmousedown = e =>
this.handleKeyboardContainerMouseDown(e);
}
/**
* Calling onInit
*/

View File

@ -590,13 +590,15 @@ it('Keyboard will receive physical keyboard events', () => {
physicalKeyboardHighlight: true
});
document.onkeyup({
document.dispatchEvent(new KeyboardEvent('keyup', {
charCode: 0,
code: "KeyF",
key: "f",
which: 70,
target: document.createElement('input')
});
target: {
tagName: "input"
}
}));
});
it('Keyboard caretEventHandler will detect input, textarea focus', () => {
@ -1224,15 +1226,15 @@ it('Keyboard destroy will work', () => {
expect(document.onkeydown).toBe(null);
expect(document.onkeyup).toBe(null);
expect(document.onpointerdown).toBe(null);
expect(document.onpointerup).toBe(null);
// expect(document.onpointerdown).toBe(null);
// expect(document.onpointerup).toBe(null);
expect(document.onmousedown).toBe(null);
expect(document.onmouseup).toBe(null);
// expect(document.onmousedown).toBe(null);
// expect(document.onmouseup).toBe(null);
expect(document.ontouchstart).toBe(null);
expect(document.ontouchend).toBe(null);
expect(document.ontouchcancel).toBe(null);
// expect(document.ontouchstart).toBe(null);
// expect(document.ontouchend).toBe(null);
// expect(document.ontouchcancel).toBe(null);
expect(keyboard.initialized).toBe(false);
});
@ -1262,10 +1264,8 @@ it('Keyboard caretEventHandler will be triggered on mouseup and ontouchend', ()
disableCaretPositioning: true
});
// TODO: Will need further investigation
// https://github.com/hodgef/simple-keyboard/issues/54
// keyboard.setCaretPosition(6);
// expect(keyboard.getCaretPosition()).toBe(6);
keyboard.setCaretPosition(6);
expect(keyboard.getCaretPosition()).toBe(6);
const event = {
target: document.body
@ -1381,17 +1381,32 @@ it('Keyboard handleKeyboardContainerMouseDown will respect preventMouseDownDefau
expect(works).toBe(true);
});
it('Keyboard handlePointerDown will work', () => {
it('Keyboard caret positioning will work', () => {
setDOM();
const keyboard = new Keyboard();
const keyboard = new Keyboard({
onKeyPress: (button) => {
if (button === "{shift}" || button === "{lock}") handleShift();
else if (keyboard.options.layoutName === "shift") handleShift();
}
});
keyboard.setCaretPosition(3);
expect(keyboard.getCaretPosition()).toBe(3);
function handleShift() {
const currentLayout = keyboard.options.layoutName;
const shiftToggle = currentLayout === "default" ? "shift" : "default";
keyboard.setOptions({
layoutName: shiftToggle
});
}
triggerDocumentPointerDown({
target: document.body
})
keyboard.getButtonElement("h").onpointerdown();
keyboard.getButtonElement("o").onpointerdown();
keyboard.setCaretPosition(1);
keyboard.getButtonElement("{shift}")[0].onpointerdown();
keyboard.getButtonElement("E").onpointerdown();
keyboard.getButtonElement("l").onpointerdown();
keyboard.getButtonElement("l").onpointerdown();
expect(keyboard.getCaretPosition()).toBe(null);
expect(keyboard.getInput()).toBe("hEllo");
});

View File

@ -26,13 +26,17 @@
/**
* Trigger pointerup
*/
export const triggerDocumentPointerUp = (e = {}) => (document.onpointerup || document.onmouseup || document.ontouchstart)(e);
export const triggerDocumentPointerUp = (e = {}) => {
document.dispatchEvent(new MouseEvent('mouseup', e));
};
/**
* Trigger pointerdown
*/
export const triggerDocumentPointerDown = (e = {}) => (document.onpointerdown || document.onmousedown || document.ontouchend)(e);
export const triggerDocumentPointerDown = (e = {}) => {
document.dispatchEvent(new MouseEvent('mousedown', e));
};
/**
* Test if standard buttons respect maxLength and do input a value
*/