diff --git a/content_scripts/commands.js b/content_scripts/commands.js index 96f8f6f..d9e06d0 100644 --- a/content_scripts/commands.js +++ b/content_scripts/commands.js @@ -5,6 +5,14 @@ Commands = { moveDown: { fn: SheetActions.moveDown.bind(SheetActions) }, moveLeft: { fn: SheetActions.moveLeft.bind(SheetActions) }, moveRight: { fn: SheetActions.moveRight.bind(SheetActions) }, + + // Word movement + moveRightward: { fn: SheetActions.moveRightward.bind(SheetActions) }, + moveLeftward: { fn: SheetActions.moveLeftward.bind(SheetActions) }, + + // Jump movement + jumpStart: { fn: SheetActions.jumpStart.bind(SheetActions) }, + jumpStartward: { fn: SheetActions.jumpStartward.bind(SheetActions) }, // Row & column movement moveRowsDown: { fn: SheetActions.moveRowsDown.bind(SheetActions) }, @@ -93,6 +101,14 @@ Commands = { "h": "moveLeft", "l": "moveRight", + // Word-level movement + "w": "moveRightward", + "W": "moveRightward", + "b": "moveLeftward", + "B": "moveLeftward", + "0": "jumpStart", + "^": "jumpStartward", + // Row & column movement "": "moveRowsDown", "": "moveRowsUp", diff --git a/content_scripts/sheet_actions.js b/content_scripts/sheet_actions.js index d162ed4..8e14945 100644 --- a/content_scripts/sheet_actions.js +++ b/content_scripts/sheet_actions.js @@ -1,3 +1,7 @@ + +const DEFAULT_MAX_RIGHTWARD_MOVES = 3; +const DEFAULT_MAX_LEFTWARD_MOVES = DEFAULT_MAX_RIGHTWARD_MOVES; + SheetActions = { // NOTE(philc): When developing, you can use this snippet to preview all available menu items: // Array.from(document.querySelectorAll(".goog-menuitem")).forEach((i) => console.log(i.innerText)) @@ -199,6 +203,21 @@ SheetActions = { return document.querySelector(".autofill-cover").getBoundingClientRect().top; }, + cellContent() { + return document.querySelector(".cell-input").innerText.trim(); + }, + + cellPosition() { + let cellPos = /* AE5, B2, etc.*/ document.querySelector('.jfk-textinput.waffle-name-box').value; + let match = /([A-Z]+)(\d+)/.exec(cellPos); + + // TODO(Johnny): Handle range for 'A:A', '1:1', and 'A1:B2'. + if (match < 3) return {row: 'A', column: '1'}; + + let [_, row, column] = match; + return {row: row, column: column}; + }, + // // Movement // @@ -207,6 +226,48 @@ SheetActions = { moveLeft() { UI.typeKey(KeyboardUtils.keyCodes.leftArrow); }, moveRight() { UI.typeKey(KeyboardUtils.keyCodes.rightArrow); }, + moveRightward: function(max_runs) { + max_runs = undefined === max_runs + ? DEFAULT_MAX_RIGHTWARD_MOVES + : max_runs; + + // Move right. + this.moveRight(); + + // If the cell is empty, content: '\n' + if (this.cellContent().length) return; + if (! max_runs) return; + + this.moveRightward(max_runs - 1); + }, + + moveLeftward: function(max_runs) { + max_runs = undefined === max_runs + ? DEFAULT_MAX_LEFTWARD_MOVES + : max_runs; + + // Move right. + this.moveLeft(); + + // If the cell is empty, content: '\n' + if (this.cellContent().length) return; + if (! max_runs) return; + + this.moveLeftward(max_runs - 1); + }, + + + jumpStart() { + // Johnny: Hacky but it works. + this.selectRow(); + this.moveLeft(); + }, + + jumpStartward() { + this.jumpStart(); + this.moveRightward(5); + }, + moveDownAndSelect() { UI.typeKey(KeyboardUtils.keyCodes.downArrow, {shift: true}); }, moveUpAndSelect() { UI.typeKey(KeyboardUtils.keyCodes.upArrow, {shift: true}); }, moveLeftAndSelect() { UI.typeKey(KeyboardUtils.keyCodes.leftArrow, {shift: true}); }, @@ -371,8 +432,8 @@ SheetActions = { // The approximate number of visible rows. It's probably possible to compute this precisely. visibleRowCount() { - return Math.ceil(document.querySelector(".grid-scrollable-wrapper").offsetHeight / this.rowHeight()); - }, + return Math.ceil(document.querySelector(".grid-scrollable-wrapper").offsetHeight / this.rowHeight()); + }, // NOTE(philc): It would be nice to improve these scrolling commands. They're somewhat slow and imprecise. scrollHalfPageDown() { @@ -481,10 +542,10 @@ SheetActions = { // implement increaes font / decrease font commands. getFontSizeMenu() { return this.getMenuItem("6").parentNode; }, activateFontSizeMenu() { - KeyboardUtils.simulateClick(this.getMenuItem("Font size")); - // It's been shown; hide it again. - this.getFontSizeMenu().style.display = "none"; - }, + KeyboardUtils.simulateClick(this.getMenuItem("Font size")); + // It's been shown; hide it again. + this.getFontSizeMenu().style.display = "none"; + }, setFontSize10() { this.activateFontSizeMenu(); @@ -557,7 +618,7 @@ SheetActions = { let url = this.getCellValue().trim(); // Some cells can contain a HYPERLINK("url", "caption") value. If so, assume that's the URL to open. const match = url.match(/HYPERLINK\("(.+?)"[^"]+".+?"\)/i); - if (match) { url = match[1]; } - window.open(url, "_blank"); - } + if (match) { url = match[1]; } + window.open(url, "_blank"); + } }; diff --git a/content_scripts/ui.js b/content_scripts/ui.js index f990756..9c24ce5 100644 --- a/content_scripts/ui.js +++ b/content_scripts/ui.js @@ -192,7 +192,7 @@ UI = { onKeydown(e) { const keyString = KeyboardUtils.getKeyString(e); - // console.log "keydown event. keyString:", keyString, e.keyCode, e.keyIdentifier, e + // console.log("keydown event. keyString:", keyString, e.keyCode, e.keyIdentifier, e); if (this.ignoreKeys) { return; } if (!keyString) { return; } // Ignore key presses which are just modifiers.