Skip to content
Snippets Groups Projects
Unverified Commit 9fa944ef authored by Tom Robinson's avatar Tom Robinson
Browse files

Add forward delete support

parent 9b33465b
No related branches found
No related tags found
No related merge requests found
......@@ -6,8 +6,10 @@ import TokenizedExpression from "./TokenizedExpression.jsx";
import { getCaretPosition, saveSelection, getSelectionPosition } from "metabase/lib/dom"
const KEYCODE_LEFT = 37;
const KEYCODE_BACKSPACE = 8;
const KEYCODE_BACKSPACE = 8;
const KEYCODE_LEFT = 37;
const KEYCODE_RIGHT = 39;
const KEYCODE_FORWARD_DELETE = 46;
export default class TokenizedInput extends Component {
constructor(props) {
......@@ -60,43 +62,53 @@ export default class TokenizedInput extends Component {
const input = ReactDOM.findDOMNode(this);
const [start, end] = getSelectionPosition(input);
const hasSelection = start !== end;
const hasModifierKey = !e.altKey && !e.ctrlKey && !e.metaKey
if (!hasSelection && !hasModifierKey) {
let element = window.getSelection().focusNode;
while (element && element !== input) {
// check ancestors of the focused node for "Expression-tokenized"
// if the element is marked as "tokenized" we might want to intercept keypresses
if (element.classList && element.classList.contains("Expression-tokenized") && getCaretPosition(element) === element.textContent.length) {
const isSelected = element.classList.contains("Expression-selected");
if (e.keyCode === KEYCODE_BACKSPACE && !isSelected && !isTyping) {
// not selected, not "typging", and hit backspace, so mark as "selected"
element.classList.add("Expression-selected");
e.stopPropagation();
e.preventDefault();
return;
} else if (e.keyCode === KEYCODE_BACKSPACE && isSelected) {
// selected and hit backspace, so delete it
element.parentNode.removeChild(element);
this._setValue(input.textContent);
e.stopPropagation();
e.preventDefault();
return;
} else if (e.keyCode === KEYCODE_LEFT && isSelected) {
// selected and hit left arrow, so enter "typing" mode and unselect it
element.classList.remove("Expression-selected");
this._isTyping = true;
e.stopPropagation();
e.preventDefault();
return;
}
let [start, end] = getSelectionPosition(input);
if (start !== end) {
return;
}
let element = window.getSelection().focusNode;
while (element && element !== input) {
// check ancestors of the focused node for "Expression-tokenized"
// if the element is marked as "tokenized" we might want to intercept keypresses
if (element.classList && element.classList.contains("Expression-tokenized")) {
const positionInElement = getCaretPosition(element);
const atStart = positionInElement === 0;
const atEnd = positionInElement === element.textContent.length;
const isSelected = element.classList.contains("Expression-selected");
if (!isSelected && !isTyping && (
atEnd && e.keyCode === KEYCODE_BACKSPACE ||
atStart && e.keyCode === KEYCODE_FORWARD_DELETE
)) {
// not selected, not "typging", and hit backspace, so mark as "selected"
element.classList.add("Expression-selected");
e.stopPropagation();
e.preventDefault();
return;
} else if (isSelected && (
atEnd && e.keyCode === KEYCODE_BACKSPACE ||
atStart && e.keyCode === KEYCODE_FORWARD_DELETE
)) {
// selected and hit backspace, so delete it
element.parentNode.removeChild(element);
this._setValue(input.textContent);
e.stopPropagation();
e.preventDefault();
return;
} else if (isSelected && (
atEnd && e.keyCode === KEYCODE_LEFT ||
atStart && e.keyCode === KEYCODE_RIGHT
)) {
// selected and hit left arrow, so enter "typing" mode and unselect it
element.classList.remove("Expression-selected");
this._isTyping = true;
e.stopPropagation();
e.preventDefault();
return;
}
// nada, try the next ancestor
element = element.parentNode;
}
// nada, try the next ancestor
element = element.parentNode;
}
// if we haven't handled the event yet, pass it on to our parent
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment