From c15b09bf891fc318ac5444ee3b90a20d9f94b410 Mon Sep 17 00:00:00 2001 From: hmuronaka <> Date: Wed, 14 Oct 2020 23:33:55 +0900 Subject: [PATCH 1/5] support japanese --- .gitignore | 1 + _locales/en/messages.json | 129 +++++++++++++++++++++++++++++++ _locales/ja/messages.json | 129 +++++++++++++++++++++++++++++++ content_scripts/sheet_actions.js | 101 +++++++++++++----------- manifest.json | 1 + 5 files changed, 315 insertions(+), 46 deletions(-) create mode 100644 _locales/en/messages.json create mode 100644 _locales/ja/messages.json diff --git a/.gitignore b/.gitignore index 9b36de6..0e18234 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.crx node_modules/* .cake_task_cache +*.swp diff --git a/_locales/en/messages.json b/_locales/en/messages.json new file mode 100644 index 0000000..b09483e --- /dev/null +++ b/_locales/en/messages.json @@ -0,0 +1,129 @@ +{ + "MenuItemsCopy": { + "message": "Copy" + }, + "MenuItemsDeleteRow": { + "message": "Delete row" + }, + "MenuItemsDeleteColumn": { + "message": "Delete column" + }, + "MenuItemsDeleteValues": { + "message": "Delete values" + }, + "MenuItemsRowAbove": { + "message": "Row above" + }, + "MenuItemsRowBelow": { + "message": "Row below" + }, + "MenuItemsFreeze": { + "message": "Freeze" + }, + "MenuItemsUpToCurrentRow": { + "message": "Up to current row" + }, + "MenuItemsUpToCurrentColumn": { + "message": "Up to current column" + }, + "MenuItemsMoveRowUp": { + "message": "Move row up" + }, + "MenuItemsMoveRowDown": { + "message": "Move row down" + }, + "MenuItemsMoveRowsUp": { + "message": "Move rows up" + }, + "MenuItemsMoveRowsDown": { + "message": "Move rows down" + }, + "MenuItemsMoveColumnLeft": { + "message": "Move column left" + }, + "MenuItemsMoveColumnRight": { + "message": "Move column right" + }, + "MenuItemsMoveColumnsLeft": { + "message": "Move columns left" + }, + "MenuItemsMoveColumnsRight": { + "message": "Move columns right" + }, + "MenuItemsPaste": { + "message": "Paste" + }, + "MenuItemsUndo": { + "message": "Undo" + }, + "MenuItemsRedo": { + "message": "Redo" + }, + "MenuItemsFullScreen": { + "message": "Full screen" + }, + "MenuItemsMergeAll": { + "message": "Merge all" + }, + "MenuItemsMergeHorizontally": { + "message": "Merge horizontally" + }, + "MenuItemsMergeVertically": { + "message": "Merge vertically" + }, + "MenuItemsUnmerge": { + "message": "Unmerge" + }, + "ButtonsHorizontalAlign": { + "message": "Horizontal align" + }, + "ButtonsTextWrapping": { + "message": "Text wrapping" + }, + "ButtonsFillColor": { + "message": "Fill color" + }, + "ButtonsTextColor": { + "message": "Text color" + }, + "Center": { + "message": "Center" + }, + "Clip": { + "message": "Clip" + }, + "Left": { + "message": "Left" + }, + "Right": { + "message": "Right" + }, + "Overflow": { + "message": "Overflow" + }, + "Wrap": { + "message": "Wrap" + }, + "ColorWhite": { + "message": "white" + }, + "ColorLightYellow3": { + "message": "light yellow 3" + }, + "ColorLightCornflowerBlue3": { + "message": "light cornflower blue 3" + }, + "ColorLightPurple3": { + "message": "light purple 3" + }, + "ColorLightRed3": { + "message": "light red 3" + }, + "ColorLightGray2": { + "message": "light gray 2" + }, + "FontSize": { + "message": "Font size" + } +} + diff --git a/_locales/ja/messages.json b/_locales/ja/messages.json new file mode 100644 index 0000000..645ddc8 --- /dev/null +++ b/_locales/ja/messages.json @@ -0,0 +1,129 @@ +{ + "MenuItemsCopy": { + "message": "^コピー\\(" + }, + "MenuItemsDeleteRow": { + "message": "^行\\s+\\d+\\s+を削除" + }, + "MenuItemsDeleteColumn": { + "message": "^列\\s+\\w+\\s+を削除" + }, + "MenuItemsDeleteValues": { + "message": "値を削除" + }, + "MenuItemsRowAbove": { + "message": "上に 1 行" + }, + "MenuItemsRowBelow": { + "message": "下に 1 行" + }, + "MenuItemsFreeze": { + "message": "固定" + }, + "MenuItemsUpToCurrentRow": { + "message": "^現在の行(\\d+)まで" + }, + "MenuItemsUpToCurrentColumn": { + "message": "^現在の列(\\w+)まで" + }, + "MenuItemsMoveRowUp": { + "message": "行を上に移動" + }, + "MenuItemsMoveRowDown": { + "message": "行を下に移動" + }, + "MenuItemsMoveRowsUp": { + "message": "複数の行を上に移動" + }, + "MenuItemsMoveRowsDown": { + "message": "複数の行を下に移動" + }, + "MenuItemsMoveColumnLeft": { + "message": "列を左に移動" + }, + "MenuItemsMoveColumnRight": { + "message": "列を右に移動" + }, + "MenuItemsMoveColumnsLeft": { + "message": "列を左に移動" + }, + "MenuItemsMoveColumnsRight": { + "message": "列を右に移動" + }, + "MenuItemsPaste": { + "message": "貼り付け" + }, + "MenuItemsUndo": { + "message": "元に戻す" + }, + "MenuItemsRedo": { + "message": "やり直し" + }, + "MenuItemsFullScreen": { + "message": "全画面" + }, + "MenuItemsMergeAll": { + "message": "すべて結合" + }, + "MenuItemsMergeHorizontally": { + "message": "横方向に結合" + }, + "MenuItemsMergeVertically": { + "message": "縦方向に結合" + }, + "MenuItemsUnmerge": { + "message": "結合を解除" + }, + "ButtonsHorizontalAlign": { + "message": "水平方向の配置" + }, + "ButtonsTextWrapping": { + "message": "テキストを折り返す" + }, + "ButtonsFillColor": { + "message": "塗りつぶしの色" + }, + "ButtonsTextColor": { + "message": "テキストの色" + }, + "Center": { + "message": "中央" + }, + "Clip": { + "message": "切り詰める" + }, + "Left": { + "message": "左" + }, + "Right": { + "message": "右" + }, + "Overflow": { + "message": "はみ出す" + }, + "Wrap": { + "message": "折り返す" + }, + "ColorWhite": { + "message": "白" + }, + "ColorLightYellow3": { + "message": "明るい黄 3" + }, + "ColorLightCornflowerBlue3": { + "message": "明るいコーンフラワー ブルー 3" + }, + "ColorLightPurple3": { + "message": "明るい紫 3" + }, + "ColorLightRed3": { + "message": "明るい赤 3" + }, + "ColorLightGray2": { + "message": "明るいグレー 2" + }, + "FontSize": { + "message": "フォント サイズ" + } + +} diff --git a/content_scripts/sheet_actions.js b/content_scripts/sheet_actions.js index 2ca3a48..55908ef 100644 --- a/content_scripts/sheet_actions.js +++ b/content_scripts/sheet_actions.js @@ -1,61 +1,62 @@ SheetActions = { menuItems: { - copy: "Copy", + copy: "MenuItemsCopy", // This string with a space at the end is meant to match the button "Delete row X" where x is some number. // There is also a "Delete rows/columns" button which we do not want to match. - deleteRow: "Delete row ", - deleteColumn: "Delete column ", - deleteValues: "Delete values", - rowAbove: "Row above", - rowBelow: "Row below", - freeze: "Freeze", // Clicking this creates a sub-menu. - freezeRow: "Up to current row", // This is a sub-item of the "Freeze" menu. - freezeColumn: "Up to current column", // This is a sub-item of the "Freeze" menu. + deleteRow: "MenuItemsDeleteRow", + deleteColumn: "MenuItemsDeleteColumn", + deleteValues: "MenuItemsDeleteValues", + rowAbove: "MenuItemsRowAbove", + rowBelow: "MenuItemsRowBelow", + freeze: "MenuItemsFreeze", + freezeRow: "MenuItemsUpToCurrentRow", + freezeColumn: "MenuItemsUpToCurrentColumn", // The "moveRowUp" menu item won't yet exist if multiple rows are selected. - moveRowUp: "Move row up", - moveRowDown: "Move row down", - moveRowsUp: "Move rows up", - moveRowsDown: "Move rows down", - moveColumnLeft: "Move column left", - moveColumnRight: "Move column right", - moveColumnsLeft: "Move columns left", - moveColumnsRight: "Move columns right", - paste: "Paste", - undo: "Undo", - redo: "Redo", - fullScreen: "Full screen", - mergeAll: "Merge all", - mergeHorizontally: "Merge horizontally", - mergeVertically: "Merge vertically", - unmerge: "Unmerge" + moveRowUp: "MenuItemsMoveRowUp", + moveRowDown: "MenuItemsMoveRowDown", + moveRowsUp: "MenuItemsMoveRowsUp", + moveRowsDown: "MenuItemsMoveRowsDown", + moveColumnLeft: "MenuItemsMoveColumnLeft", + moveColumnRight: "MenuItemsMoveColumnRight", + moveColumnsLeft: "MenuItemsMoveColumnsLeft", + moveColumnsRight: "MenuItemsMoveColumnsRight", + paste: "MenuItemsPaste", + undo: "MenuItemsUndo", + redo: "MenuItemsRedo", + fullScreen: "MenuItemsFullScreen", + mergeAll: "MenuItemsMergeAll", + mergeHorizontally: "MenuItemsMergeHorizontally", + mergeVertically: "MenuItemsMergeVertically", + unmerge: "MenuItemsUnmerge", }, buttons: { - center: ["Horizontal align", "Center"], - clip: ["Text wrapping", "Clip"], - left: ["Horizontal align", "Left"], - right: ["Horizontal align", "Right"], - overflow: ["Text wrapping", "Overflow"], - wrap: ["Text wrapping", "Wrap"] + center: ["ButtonsHorizontalAlign", "Center"], + clip: ["ButtonsTextWrapping", "Clip"], + left: ["ButtonsHorizontalAlign", "Left"], + right: ["ButtonsHorizontalAlign", "Right"], + overflow: ["ButtonsTextWrapping", "Overflow"], + wrap: ["ButtonsTextWrapping", "Wrap"] }, // You can find the names of these color swatches by hoverig over the swatches and seeing the tooltip. colors: { - white: "white", - lightYellow3: "light yellow 3", - lightCornflowBlue3: "light cornflower blue 3", - lightPurple3: "light purple 3", - lightRed3: "light red 3", - lightGray2: "light gray 2" + white: "ColorWhite", + lightYellow3: "ColorLightYellow3", + lightCornflowBlue3: "ColorLightCornflowerBlue3", + lightPurple3: "ColorLightPurple3", + lightRed3: "ColorLightRed3", + lightGray2: "ColorLightGray2" }, // A mapping of button-caption to DOM element. menuItemElements: {}, - + clickToolbarButton(captionList) { // Sometimes a toolbar button won't exist in the DOM until its parent has been clicked, so we click all of // its parents in sequence. - for (let caption of Array.from(captionList)) { + for (let captionOrI18nMessage of Array.from(captionList)) { + const caption = this.getI18nMessag(captionOrI18nMessage); const el = document.querySelector(`*[aria-label='${caption}']`); if (!el) { console.log(`Couldn't find the element for the button labeled ${caption}.`); @@ -68,7 +69,8 @@ SheetActions = { // Returns the DOM element of the menu item with the given caption. Prints a warning if a menu item isn't // found (since this is a common source of errors in SheetKeys) unless silenceWarning = true. - getMenuItem(caption, silenceWarning) { + getMenuItem(captionOrI18nMessageKey, silenceWarning) { + const caption = this.getI18nMessag(captionOrI18nMessageKey); if (silenceWarning == null) { silenceWarning = false; } let item = this.menuItemElements[caption]; if (item) { return item; } @@ -82,9 +84,10 @@ SheetActions = { findMenuItem(caption) { const menuItems = document.querySelectorAll(".goog-menuitem"); + const regexp = new RegExp(caption); for (let menuItem of Array.from(menuItems)) { const label = menuItem.innerText; - if (label && label.indexOf(caption) === 0) { + if( label && label.search(regexp) === 0 ) { return menuItem; } } @@ -94,11 +97,12 @@ SheetActions = { // Returns the color palette button corresponding to the given color name. // type: either "font" or "cell", depending on which color you want to change. // Note that the availability and use of the color palette buttons is a bit finicky. - getColorButton(color, type) { + getColorButton(colorOrI18nMessageKey, type) { + const color = this.getI18nMessag(colorOrI18nMessageKey); // First we must open the palette; only then can we reliably get the color button that pertains to that // color palette. const paletteButton = document.querySelector( - (type == "cell") ? "*[aria-label='Fill color']": "*[aria-label='Text color']"); + (type == "cell") ? `*[aria-label='${this.getI18nMessag("ButtonsFillColor")}']`: `*[aria-label='${this.getI18nMessag("ButtonsTextColor")}']`); KeyboardUtils.simulateClick(paletteButton); const rect = paletteButton.getBoundingClientRect(); @@ -449,19 +453,19 @@ SheetActions = { // implement increaes font / decrease font commands. getFontSizeMenu() { return this.getMenuItem("6").parentNode; }, activateFontSizeMenu() { - KeyboardUtils.simulateClick(this.getMenuItem("Font size")); + KeyboardUtils.simulateClick(this.getMenuItem("FontSize")); // It's been shown; hide it again. this.getFontSizeMenu().style.display = "none"; }, setFontSize10() { this.activateFontSizeMenu(); - KeyboardUtils.simulateClick(this.getMenuItem("10")); + KeyboardUtils.simulateClick(this.getMenuItem("^10$")); }, setFontSize8() { this.activateFontSizeMenu(); - KeyboardUtils.simulateClick(this.getMenuItem("8")); + KeyboardUtils.simulateClick(this.getMenuItem("^8$")); }, wrap() { this.clickToolbarButton(this.buttons.wrap); }, @@ -527,5 +531,10 @@ SheetActions = { const match = url.match(/HYPERLINK\("(.+?)"[^"]+".+?"\)/i); if (match) { url = match[1]; } window.open(url, "_blank"); + }, + + getI18nMessag(captionOrKey) { + return chrome.i18n.getMessage(captionOrKey) || captionOrKey } + }; diff --git a/manifest.json b/manifest.json index 6cc6265..276ab7b 100644 --- a/manifest.json +++ b/manifest.json @@ -3,6 +3,7 @@ "name": "Sheetkeys", "version": "0.1", "description": "TODO", + "default_locale": "en", "permissions": [ "storage" ], From 284abfc6c6445ea949d86e3f72681f90044f5452 Mon Sep 17 00:00:00 2001 From: hmuronaka <> Date: Sat, 17 Oct 2020 12:49:30 +0900 Subject: [PATCH 2/5] refactor add findItem --- content_scripts/sheet_actions.js | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/content_scripts/sheet_actions.js b/content_scripts/sheet_actions.js index 55908ef..8c6053c 100644 --- a/content_scripts/sheet_actions.js +++ b/content_scripts/sheet_actions.js @@ -83,7 +83,11 @@ SheetActions = { }, findMenuItem(caption) { - const menuItems = document.querySelectorAll(".goog-menuitem"); + return this.findItem(".goog-menuitem", caption); + }, + + findItem(selector, caption) { + const menuItems = document.querySelectorAll(selector); const regexp = new RegExp(caption); for (let menuItem of Array.from(menuItems)) { const label = menuItem.innerText; @@ -421,14 +425,7 @@ SheetActions = { // This tab menu element gets created the first time the user clicks on it, so it may not yet be available // in the DOM. if (!menu) { this.activateTabMenu(); } - const menuItems = document.querySelectorAll(".docs-sheet-tab-menu .goog-menuitem"); - let result = null; - for (let item of Array.from(menuItems)) { - if (item.innerText.indexOf(buttonCaption) === 0) { - result = item; - break; - } - } + const result = this.findItem(".docs-sheet-tab-menu .goog-menuitem", buttonCaption); if (!result) { console.log(`Couldn't find a tab menu item with the caption ${buttonCaption}`); return; From 8b275cfe821641fea72fe415842b198e2c668336 Mon Sep 17 00:00:00 2001 From: hmuronaka <> Date: Sat, 17 Oct 2020 12:52:26 +0900 Subject: [PATCH 3/5] add getTabButton --- content_scripts/sheet_actions.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/content_scripts/sheet_actions.js b/content_scripts/sheet_actions.js index 8c6053c..59267d5 100644 --- a/content_scripts/sheet_actions.js +++ b/content_scripts/sheet_actions.js @@ -420,17 +420,22 @@ SheetActions = { KeyboardUtils.simulateClick(tabs[next]); }, - clickTabButton(buttonCaption) { + clickTabButton(captionOrI18nMessageKey) { + KeyboardUtils.simulateClick(this.getTabButton(captionOrI18nMessageKey)); + }, + + getTabButton(captionOrI18nMessageKey) { + const caption = this.getI18nMessag(captionOrI18nMessageKey); const menu = document.querySelector(".docs-sheet-tab-menu"); // This tab menu element gets created the first time the user clicks on it, so it may not yet be available // in the DOM. if (!menu) { this.activateTabMenu(); } - const result = this.findItem(".docs-sheet-tab-menu .goog-menuitem", buttonCaption); + const result = this.findItem(".docs-sheet-tab-menu .goog-menuitem", caption); if (!result) { console.log(`Couldn't find a tab menu item with the caption ${buttonCaption}`); return; } - KeyboardUtils.simulateClick(result); + return result; }, // Shows and then hides the tab menu for the currently selected tab. From 5d322871c109e2c2f543cd28b03e470ce9eef261 Mon Sep 17 00:00:00 2001 From: hmuronaka <> Date: Sun, 18 Oct 2020 10:14:12 +0900 Subject: [PATCH 4/5] tab move right / left --- _locales/en/messages.json | 6 ++++++ _locales/ja/messages.json | 7 ++++++- content_scripts/sheet_actions.js | 4 ++-- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index b09483e..373bfd3 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -124,6 +124,12 @@ }, "FontSize": { "message": "Font size" + }, + "TabMoveRight": { + "message": "Move right" + }, + "TabMoveLeft": { + "message": "Move left" } } diff --git a/_locales/ja/messages.json b/_locales/ja/messages.json index 645ddc8..31ad161 100644 --- a/_locales/ja/messages.json +++ b/_locales/ja/messages.json @@ -124,6 +124,11 @@ }, "FontSize": { "message": "フォント サイズ" + }, + "TabMoveRight": { + "message": "右に移動" + }, + "TabMoveLeft": { + "message": "左に移動" } - } diff --git a/content_scripts/sheet_actions.js b/content_scripts/sheet_actions.js index 59267d5..a2ce79d 100644 --- a/content_scripts/sheet_actions.js +++ b/content_scripts/sheet_actions.js @@ -403,8 +403,8 @@ SheetActions = { return null; }, - moveTabRight() { this.clickTabButton("Move right"); }, - moveTabLeft() { this.clickTabButton("Move left"); }, + moveTabRight() { this.clickTabButton("TabMoveRight"); }, + moveTabLeft() { this.clickTabButton("TabMoveLeft"); }, prevTab() { const tabs = this.getTabEls(); From 48f121ea45a19c8871a5373c486006a77a9078f0 Mon Sep 17 00:00:00 2001 From: hmuronaka <> Date: Sun, 18 Oct 2020 12:19:24 +0900 Subject: [PATCH 5/5] recover comments --- content_scripts/sheet_actions.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/content_scripts/sheet_actions.js b/content_scripts/sheet_actions.js index a2ce79d..29225a7 100644 --- a/content_scripts/sheet_actions.js +++ b/content_scripts/sheet_actions.js @@ -8,9 +8,12 @@ SheetActions = { deleteValues: "MenuItemsDeleteValues", rowAbove: "MenuItemsRowAbove", rowBelow: "MenuItemsRowBelow", - freeze: "MenuItemsFreeze", - freezeRow: "MenuItemsUpToCurrentRow", - freezeColumn: "MenuItemsUpToCurrentColumn", + freeze: "MenuItemsFreeze", // Clicking this creates a sub-menu. + + freezeRow: "MenuItemsUpToCurrentRow", // This is a sub-item of the "Freeze" menu. + + freezeColumn: "MenuItemsUpToCurrentColumn", // This is a sub-item of the "Freeze" menu. + // The "moveRowUp" menu item won't yet exist if multiple rows are selected. moveRowUp: "MenuItemsMoveRowUp", moveRowDown: "MenuItemsMoveRowDown",