From a51b5bbbfe4285334fcf18fa429decdb2a7358d8 Mon Sep 17 00:00:00 2001 From: John Dunning Date: Wed, 26 Oct 2022 12:51:41 -0700 Subject: [PATCH] Release v1.8.0 Add support for Firefox. No changes to other browsers. Allow menu height to grow in Firefox, so it's displayed correctly. Add support for the search box cancel button in FF by rendering it with React, since FF doesn't render the pseudo element. Fix flash of scrollbar when menu is initially shown. Use scrollbar-width and -color to style the scrollbar in FF, since it doesn't support as many options as Webkit. Don't show a favicon for some internal FF pages, since it generates console errors. Add a .firefox class to the root. Add IsFirefox constant. Make background.html a full page instead of just scripts. Remove right-click info from store description. Update built popup.html. Prevent private browsing use in FF. Hide private browsing section in options. Make tab count background darker so the text shows as white. Add firefox-store-description.txt. Add default favicons for Firefox bookmarks and history items. The extension API doesn't provide them, use the same icon from the bookmark and history windows in FF. Fix dark mode colors in FF. Position the scrollbar on the right edge of the popup. Handle getting the moved tab as an array instead of a bare object. Close the menu explicitly in FF, including after opening options. Add a closeWindow() method. Prevent textarea in clipboard copy util from changing the page height. Disable esc shortcut options on Firefox. Default the esc behavior to close and the close window shortcut to ctrl-alt-W on FF. Add favicon to Options page, since FF doesn't seem to render it automatically. Map IncognitoIcon to the appropriate icon, so every place that uses it doesn't have to check the browser. Refactor incognito instructions into a constant so they can be different for FF. Add IncognitoPermission constant. Add private-option.png screenshot, and its dark version. Update icons and strings for Firefox private windows, though we don't end up using them. --- build/prod/background.html | 18 +- build/prod/options.html | 2 + docs/firefox-store-description.txt | 292 ++++++++++++++++++++++ docs/releases/index.md | 7 + package-lock.json | 22 +- package.json | 2 +- src/background.html | 18 +- src/css/options.css | 12 +- src/css/popup.css | 66 ++++- src/img/default-favicon.svg | 3 + src/img/private-option-dark.png | Bin 0 -> 28662 bytes src/img/private-option.png | Bin 0 -> 28135 bytes src/js/background/background.js | 6 + src/js/background/constants.js | 19 +- src/js/background/get-default-settings.js | 8 +- src/js/common/icons.js | 80 +++--- src/js/lib/copy-to-clipboard.js | 3 + src/js/options/app.js | 65 +++-- src/js/popup/app.js | 40 ++- src/js/popup/data/add-urls.js | 27 +- src/js/popup/results-list-item.js | 7 +- src/js/popup/results-list.js | 13 +- src/js/popup/search-box.js | 22 +- src/manifest.json | 4 +- src/options.html | 4 +- src/popup.html | 2 +- 26 files changed, 620 insertions(+), 122 deletions(-) create mode 100644 docs/firefox-store-description.txt create mode 100644 src/img/default-favicon.svg create mode 100644 src/img/private-option-dark.png create mode 100644 src/img/private-option.png diff --git a/build/prod/background.html b/build/prod/background.html index 0db47cdf..593d8c2a 100644 --- a/build/prod/background.html +++ b/build/prod/background.html @@ -1,6 +1,12 @@ - - - - - - + + + + + + + + + + + + diff --git a/build/prod/options.html b/build/prod/options.html index a6af5270..1948d2da 100644 --- a/build/prod/options.html +++ b/build/prod/options.html @@ -7,6 +7,8 @@ QuicKey Options + + diff --git a/docs/firefox-store-description.txt b/docs/firefox-store-description.txt new file mode 100644 index 00000000..42287f17 --- /dev/null +++ b/docs/firefox-store-description.txt @@ -0,0 +1,292 @@ +# Tag line + + +## Chrome store description from manifest + +Add keyboard shortcuts to switch tabs with a Quicksilver-style search or a most recently used menu + + +## Website title + +QuicKey | Jump between recent tabs in Chrome via keyboard or menu +QuicKey | Quickly jump to recent tabs in Chrome via keyboard or menu +QuicKey | Jump to recent tabs via keyboard or menu +QuicKey | Jump to recent tabs in Chrome via keyboard or menu +QuicKey | The fastest way to find recent tabs in Chrome via keyboard or menu +QuicKey | The fastest way to jump to recent tabs via keyboard or menu + +QuicKey – The quick tab switcher +QuicKey – The quick tab manager + + +## Website description + +Have dozens of tabs open? Quickly jump between them with QuicKey, a Chrome extension that adds keyboard shortcuts to switch tabs using a Quicksilver-style search or a most recently used (MRU) menu. +Have dozens of tabs open? Quickly jump between them with QuicKey, a Chrome extension that adds keyboard shortcuts to switch tabs with a Quicksilver-style search or a most recently used (MRU) menu. + +Quickly navigate all your open tabs with QuicKey, a Chrome extension that adds keyboard shortcuts to switch tabs with a Quicksilver-style search or a most recently used (MRU) menu. +Switch tabs instantly! + +A Chrome extension that adds keyboard shortcuts to switch tabs with a Quicksilver-style search or a most recently used (MRU) menu. + + +## Search result + +QuicKey | Jump bewteen recent tabs in Chrome via keyboard or menu +https://fwextensions.github.io/QuicKey/ +Have dozens of open tabs? Quickly jump between them with QuicKey, a Chrome extension that adds keyboard shortcuts to switch tabs with a Quicksilver-style search or a most recently used (MRU) menu. + +Stop hunting for that tab and start jumping! + + +## Old + +Switch tabs with a Quicksilver-style search or a most-recently-used menu + +Add keyboard shortcuts to switch tabs with a Quicksilver-style search or a most recently used menu +Add keyboard shortcuts in Chrome to switch tabs with a Quicksilver-style search or a most recently used menu + +Switch tabs using the keyboard and a Quicksilver-style search or a most-recently-used menu +Use keyboard shortcuts to switch tabs using a Quicksilver-style search or a most-recently-used menu +Keep your hands on the keyboard and switch tabs using a Quicksilver search or a most-recently-used menu + +Keep your hands on the keyboard and switch tabs using a Quicksilver-style search or a most-recently-used menu +Switch tabs via the keyboard and a Quicksilver-style search or a most-recently-used menu + +Keyboard-centric tab-switcher +Switch tabs using the keyboard and a Quicksilver search or a most-recently-used menu +Switch tabs with the keyboard and a Quicksilver-style search or an MRU menu +Switch tabs via the keyboard using a Quicksilver-style search or an MRU menu + +Switch tabs with a Quicksilver-style search or a visual MRU tab list + +Switch tabs or access bookmarks and history with a Quicksilver-style search! Also supports tabs suspended by The Great Suspender. + +Quickly switch tabs or access bookmarks and history with a Quicksilver-style search and MRU tab navigation +Switch tabs or access bookmarks and history with a Quicksilver-style search or a most recently used (MRU) tab list +Switch tabs with a Quicksilver-style search or a most recently used (MRU) tab list + + +# Search terms in Edge store + +tab switcher +tab manager +MRU tab menu +most recently used tabs menu +recent tabs menu +tab search +ctrl-tab navigation + + +Any open tab can be searched immediately after installation. The list of recent tabs will be empty immediately after the extension is installed, but tabs will be added to the list as you switch between them. Switching the OS to dark mode will update the colors in the menu and options page. + + + + +★ New options in v1.7.0 + + • Limit recent tab navigation to the current browser window + • Limit tab search results to the current browser window + + +★ Use CTRL-TAB to switch between recent tabs + +With a little extra work, you can make QuicKey respond to the Holy Grail of keyboard shortcuts: CTRL-TAB. + +Learn how at https://fwextensions.github.io/QuicKey/ctrl-tab/ + +You can customize the shortcut keys (other than CTRL-TAB) by right-clicking the QuicKey icon and selecting Options. + + +★ InPrivate mode + +To switch to InPrivate tabs as well as normal ones, right-click the QuicKey icon and select "Extension options" from the menu. Scroll to the very bottom of the QuicKey options page and then click the "Change InPrivate settings" button. On the extensions page that opens, scroll down to the "Allow in InPrivate" option and click the toggle button next to it. + +Tabs in InPrivate mode display the InPrivate icon under the page's favicon, so you can distinguish a normal tab from an InPrivate one with the same title. + + + + +★ +➤ +↑ ↓ + +https://addons.mozilla.org/en-US/firefox/addon/quickey-the-quick-tab-switcher/ + + +# Description + +Add keyboard shortcuts to switch tabs with a Quicksilver-style search or a most recently used menu. No mouse needed! + + • Press ALT-Q (CTRL-Q on macOS) + • Type a few letters + • Press ENTER to switch to the selected tab + + +★ Switch between the most recently used tabs + + ➤ NOTE: When first installed, QuicKey doesn't know which tabs have been + recently used, but as you use the browser, tabs will get added to the + most recently used (MRU) list. + +Opening QuicKey displays a list of the last 50 tabs you've visited, in order of recency. Click a tab to switch to it, or use one of the keyboard shortcuts below to navigate the recently used tab history: + + ➤ To switch between the two most recent tabs: + • Press ALT-Z (CTRL-Z on macOS). + OR: + • Quickly double-press ALT-Q (CTRL-Q on macOS). + + ➤ To navigate farther back in the MRU list: + • Press ALT-A (CTRL-A on macOS) once to switch to the previous tab. + The QuicKey icon will invert for .75 seconds. + • Press ALT-A while the icon is inverted to switch to older tabs, once + for each tab. + • Press ALT-S to move to newer tabs. + • Pause to let the icon revert to normal. + • Press ALT-A again to switch back to the tab you initially started on. + + ➤ To pick a recent tab from the MRU list: + • Press the shortcut but keep holding the ALT key (CTRL key on macOS). + • Press W or ↓ to move down through the list of recent tabs. + • Press SHIFT-W or ↑ to move up. + • Release ALT to switch to the selected tab. + • You can also highlight an item with the mouse, then release ALT to + go to that tab. + +Which shortcuts to use is up to you. Double-pressing ALT-Q is nice because there's just one shortcut to remember, while ALT-Z lets you switch between the two most recently used tabs very rapidly. (You can also double-click the QuicKey icon to toggle between the most recent tabs.) + +ALT-A lets you navigate to even older tabs, though the timing can sometimes be finicky. + +Selecting from the MRU menu by holding down the ALT key provides the closest experience to a typical ALT-TAB menu, but you need to use W instead of TAB to navigate while the menu is open. + +You can change any of these shortcuts by clicking the gear icon in the menu or by right-clicking the QuicKey icon and selecting Options. Then scroll down and click "Change browser shortcuts". Look for the "Switch to the previous/next tab" shortcuts. + +If you enable the option to show the number of open tabs on the QuicKey icon, the badge containing that number will change color while you navigate to older tabs, rather than the icon inverting. + + +★ Search for a tab quickly + +Unlike other tab switchers, QuicKey uses a Quicksilver-style search algorithm to rank the results, where contiguous matches at the beginning of words are higher in the list, as are matches against capital letters. So you only have to type a few letters to quickly find the right tab. + +Use keyboard shortcuts to navigate the list: + + • ENTER: switch to the selected tab + • ↓, SPACE or CTRL-N/J: move down the list + • ↑, SHIFT-SPACE or CTRL-P/K: move up the list + • PG DN: page down the list + • PG UP: page up the list + • END: go to the bottom of the list + • HOME: go to the top of the list + • ESC: close the menu + +Recently used tabs get a slight boost in the search results ranking, so getting back to a tab you were just using should require typing fewer letters. + + +★ Customize shortcuts and other options + +To customize how QuicKey behaves, click the gear icon in the menu, or right-click its icon on the toolbar and select Options. There you can: + + • Customize keyboard shortcuts + • Hide closed tabs from the search results + • Limit navigating recent tabs or searching to the current browser window + • Mark tabs in other browser windows with an icon + • Show the number of open tabs + • Use pinyin to search for Chinese characters + +If you change the keyboard shortcut for showing the QuicKey menu to something other than the default ALT-Q or if you have a non-US keyboard, you'll probably want to also change the key that's used to navigate down the list of recently used tabs (which defaults to W). For instance, if you change the menu shortcut to ALT-Z, you might want to change the navigation key to X, which is right next door. To change it, go to the Options page, click the "Select the next tab" keyboard shortcut picker, and press X. + +When new settings have been added to QuicKey, the gear icon will display a red dot to let you know. + + +★ Limit navigation to the current browser window + +If you have multiple browser windows open, you may want to navigate among only the recent tabs that are in the current window. To enable this behavior, open the Options page and select "Limit recent tabs to the current browser window". Pressing the shortcuts for "Switch instantly between the two most recent tabs" or "Switch to the previous tab" will then switch only between recent tabs in the current window. + +You can also limit searching for tabs to the current browser window. + + +★ Close and reopen tabs + +To close the selected tab, press CTRL-ALT-W (CMD-CTRL-W on macOS, CTRL-ALT-W on Linux). Or hover over a tab and click the X button on the right side of the menu. + +When you open QuicKey, the 25 most recently closed tabs are listed below the recent tabs and shown in a faded state with a clock icon. They are also returned when you type a query, though their rank in the list of results is lower than open tabs. Click a closed tab to reopen it in its original location and with all of its browsing history intact. + +If you don't want any closed tabs to be shown, open the QuicKey options page and uncheck "Include recently closed tabs in the search results". You can also remove the selected closed tab from the browser's history by pressing CTRL-W (CMD-CTRL-W on macOS) or by clicking its X button on the right side of the menu. + + +★ Move tabs + +You can move tabs to the left or right of the current tab, making it easy to pull tabs from other windows into the current one, or to rearrange tabs without using the mouse. + + • Press CTRL-[ to move the selected tab to the left of the current one. + • Press CTRL-] to move it to the right. + +The CTRL key should be used on both Windows and macOS. Note that you cannot move tabs between normal and InPrivate windows. + + +★ Search bookmarks + +To find a bookmark, type "/b" and a space in the search box, then part of the bookmark's name or URL. + + • Press ENTER to open it in the current tab. + • Press CTRL-ENTER (CMD-ENTER on macOS) to open it in a new tab in + the current window. + • Press SHIFT-ENTER to open it in a new window. + + +★ Search the browser history + +To find something in the last 2000 pages of your browser history, type "/h" and a space in the search box, then part of the page's name or URL. + +The same CTRL-ENTER (CMD-ENTER on macOS) and SHIFT-ENTER shortcuts will open the visited page in a new tab or window. + + +★ Delete bookmarks and history items + +To delete the selected bookmark or history item, press CTRL-W (CMD-CTRL-W on macOS). Or hover over an item and click the X button on the right side of the menu. You'll be asked to confirm the deletion of bookmarks. + + +★ Copy a URL or title + +You can also copy the URL and title of the selected tab, bookmark or history item: + + • Press CTRL-C (CMD-C on macOS) to copy just the URL. + • Press CTRL-SHIFT-C (CMD-SHIFT-C on macOS) to copy both the item's + title and its URL, one per line. + + +★ Private browsing + +QuicKey does not currently support running in windows that are set to private browsing mode. + + +★ Privacy policy + +When first installed, QuicKey asks for these permissions: + + ➤ "Read and modify your browsing history on all your signed-in devices" + + QuicKey uses this permission to let you search the titles and URLs of + the open tabs, as well as pages from your history. The "all your + signed-in devices" part is there only so that recently closed tabs can be + restored with their full history. The only time QuicKey changes your + browsing history is when you choose to delete a history item. + + ➤ "Read and change your favorites" + + QuicKey uses this permission to let you search the titles and URLs of + pages in your favorites. The only time it changes your favorites is + when you choose to delete one. + +QuicKey can't access or manipulate the content of any pages you visit and doesn't transmit any information other than some anonymized diagnostic data. + + +★ Support and source code + +Get more information at https://fwextensions.github.io/QuicKey/ + +Report a bug or request a feature at https://fwextensions.github.io/QuicKey/support/ + +View the release history at https://fwextensions.github.io/QuicKey/releases + +See the source code at https://github.com/fwextensions/QuicKey diff --git a/docs/releases/index.md b/docs/releases/index.md index 60db9e97..4ba505bb 100644 --- a/docs/releases/index.md +++ b/docs/releases/index.md @@ -8,6 +8,13 @@ comments: true # Release history +## 1.8.0 - 2022-10-26 + +### Added + +* Added support for Firefox and added it to the [Mozilla add-ons store](https://addons.mozilla.org/en-US/firefox/addon/quickey-the-quick-tab-switcher/). No changes for other browsers. + + ## 1.7.4 - 2022-06-18 ### Fixed diff --git a/package-lock.json b/package-lock.json index 0a7da857..199b46f5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,13 +8,13 @@ "name": "QuicKey", "version": "0.0.0", "dependencies": { + "fast-memoize": "^2.5.2", "pinyin": "^2.11.2" }, "devDependencies": { "chrome-webstore-upload": "^0.5.0", "deepmerge": "^4.2.2", - "fast-memoize": "^2.5.2", - "grunt": "^1.5.2", + "grunt": "^1.5.3", "grunt-cli": "^1.4.3", "grunt-confirm": "^1.0.8", "grunt-contrib-clean": "^2.0.1", @@ -2455,8 +2455,7 @@ "node_modules/fast-memoize": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/fast-memoize/-/fast-memoize-2.5.2.tgz", - "integrity": "sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw==", - "dev": true + "integrity": "sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw==" }, "node_modules/fbjs": { "version": "0.8.18", @@ -3025,9 +3024,9 @@ "dev": true }, "node_modules/grunt": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.5.2.tgz", - "integrity": "sha512-XCtfaIu72OyDqK24MjWiGC9SwlkuhkS1mrULr1xzuJ2XqAFhP3ZAchZGHJeSCY6mkaOXU4F7SbmmCF7xIVoC9w==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.5.3.tgz", + "integrity": "sha512-mKwmo4X2d8/4c/BmcOETHek675uOqw0RuA/zy12jaspWqvTp4+ZeQF1W+OTpcbncnaBsfbQJ6l0l4j+Sn/GmaQ==", "dev": true, "dependencies": { "dateformat": "~3.0.3", @@ -9759,8 +9758,7 @@ "fast-memoize": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/fast-memoize/-/fast-memoize-2.5.2.tgz", - "integrity": "sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw==", - "dev": true + "integrity": "sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw==" }, "fbjs": { "version": "0.8.18", @@ -10245,9 +10243,9 @@ "dev": true }, "grunt": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.5.2.tgz", - "integrity": "sha512-XCtfaIu72OyDqK24MjWiGC9SwlkuhkS1mrULr1xzuJ2XqAFhP3ZAchZGHJeSCY6mkaOXU4F7SbmmCF7xIVoC9w==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.5.3.tgz", + "integrity": "sha512-mKwmo4X2d8/4c/BmcOETHek675uOqw0RuA/zy12jaspWqvTp4+ZeQF1W+OTpcbncnaBsfbQJ6l0l4j+Sn/GmaQ==", "dev": true, "requires": { "dateformat": "~3.0.3", diff --git a/package.json b/package.json index 3ef7845d..2de26cd3 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "devDependencies": { "chrome-webstore-upload": "^0.5.0", "deepmerge": "^4.2.2", - "grunt": "^1.5.2", + "grunt": "^1.5.3", "grunt-cli": "^1.4.3", "grunt-confirm": "^1.0.8", "grunt-contrib-clean": "^2.0.1", diff --git a/src/background.html b/src/background.html index c264efe2..1569b648 100644 --- a/src/background.html +++ b/src/background.html @@ -1,6 +1,12 @@ - - - - - - + + + + + + + + + + + + diff --git a/src/css/options.css b/src/css/options.css index cf0821f6..775c6692 100644 --- a/src/css/options.css +++ b/src/css/options.css @@ -141,6 +141,10 @@ .edge .incognito-screenshot { content: url("/img/inprivate-option-dark.png"); } + + .firefox .incognito-screenshot { + content: url("/img/private-option-dark.png"); + } } @@ -298,7 +302,7 @@ main { fill: var(--fill, #999); } -.incognito.icon { +.incognito.icon, .ff-private.icon { fill: var(--fill, #a9a9a9); } @@ -307,7 +311,7 @@ main { opacity: .6; } -.history.icon, .window.icon, .incognito.icon, .inprivate.icon { +.history.icon, .window.icon, .incognito.icon, .inprivate.icon, .ff-private.icon { height: 1.2em; vertical-align: bottom; } @@ -445,6 +449,10 @@ main { font-size: .9em; } +.control .subtitle kbd { + line-height: 1.1; +} + .control-group { margin: 1em 0 2em 0; } diff --git a/src/css/popup.css b/src/css/popup.css index 69c016d4..17c1e0c2 100644 --- a/src/css/popup.css +++ b/src/css/popup.css @@ -12,7 +12,7 @@ --fill: #aaa; } - .history.icon, .window.icon, .incognito.icon { + .history.icon, .window.icon, .incognito.icon, .ff-private.icon { --fill: #777; } @@ -25,22 +25,35 @@ --border-color: #555; } - .search-box input::-webkit-input-placeholder, .command-placeholder { + .search-box input::-webkit-input-placeholder, + .search-box input::placeholder, + .command-placeholder { --color: rgb(139, 139, 139); } - .search-box input::-webkit-search-cancel-button { + .search-box input::-webkit-search-cancel-button, + .firefox .search-box .cancel-button { background-image: url(/img/clear-dark.svg) !important; } - .search-box input::-webkit-search-cancel-button:hover, + .search-box input::-webkit-search-cancel-button:hover { + --background: #535457; + } + + .search-box input::-webkit-search-cancel-button:hover:active { + --background: #5d5e61; + } + + /* group together the selectors that Firefox will parse, while leaving the + pseudo-element+pseudo-class selector that FF ignores by itself above */ .options-button:hover, + .firefox .search-box .cancel-button:hover, .results-list-item.selected:hover .close-button:hover { --background: #535457; } - .search-box input::-webkit-search-cancel-button:hover:active, .options-button:hover:active, + .firefox .search-box .cancel-button:hover:active, .results-list-item.selected:hover .close-button:hover:active { --background: #5d5e61; } @@ -62,7 +75,7 @@ --background: #666; } - ::-webkit-scrollbar-thumb { + ::-webkit-scrollbar-thumb, .firefox .results-list { --background: rgba(255, 255, 255, .1); } @@ -84,9 +97,11 @@ html, body { width: 500px; - height: 35px; margin: 0; padding: 0; + /* prevent the flash of a scrollbar that briefly appears when the popup + is opened on Firefox */ + scrollbar-width: none; } body { @@ -112,7 +127,7 @@ img { fill: var(--fill, #888); } -.history.icon, .window.icon, .incognito.icon { +.history.icon, .window.icon, .incognito.icon, .ff-private.icon { fill: var(--fill, #bbb); } @@ -159,13 +174,27 @@ img { position: absolute; } -.search-box input::-webkit-input-placeholder, .command-placeholder { +.search-box input::-webkit-input-placeholder, +.search-box input::placeholder, +.command-placeholder { font-weight: normal; font-style: italic; color: var(--color, rgb(117, 117, 117)); } -.search-box input::-webkit-search-cancel-button { +.search-box .cancel-button { + display: none; +} + +.firefox .search-box .cancel-button { + display: block; + top: 5px; + right: 27px; + position: absolute; +} + +.search-box input::-webkit-search-cancel-button, +.firefox .search-box .cancel-button { -webkit-appearance: none; height: 22px; width: 22px; @@ -185,6 +214,18 @@ img { background-color: var(--background, #bbb); } + /* maddeningly, FF will ignore the entire rule set when it contains both a + prefixed pseudo element it doesn't support AND a pseudo class. so we have + to repeat these rules for hover when we don't have to repeat them for the + basic styling above. */ +.firefox .search-box .cancel-button:hover { + background-color: var(--background, #dcdcdc); +} + +.firefox .search-box .cancel-button:hover:active { + background-color: var(--background, #bbb); +} + .command-placeholder { top: 0; left: 0; @@ -462,3 +503,8 @@ img { ::-webkit-scrollbar-corner { background: transparent; } + +.firefox .results-list { + scrollbar-width: thin; + scrollbar-color: var(--background, rgba(0, 0, 0, 0.15)) none; +} diff --git a/src/img/default-favicon.svg b/src/img/default-favicon.svg new file mode 100644 index 00000000..e7c090f4 --- /dev/null +++ b/src/img/default-favicon.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/img/private-option-dark.png b/src/img/private-option-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..f4aa00a5224260c2350b9f474abf76932cf54563 GIT binary patch literal 28662 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 literal 0 HcmV?d00001 diff --git a/src/img/private-option.png b/src/img/private-option.png new file mode 100644 index 0000000000000000000000000000000000000000..537f31bb2be84e50f923c47c3cc91144e5f39616 GIT binary patch literal 28135 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 aM> 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 KQe_e*U;h^}Ol-3N literal 0 HcmV?d00001 diff --git a/src/js/background/background.js b/src/js/background/background.js index 155c03dc..ec30ddcc 100644 --- a/src/js/background/background.js +++ b/src/js/background/background.js @@ -148,6 +148,12 @@ require([ let usePinyin; + if (k.IsFirefox) { + // make the count background slightly darker in FF so the text is + // rendered in white instead of black + BadgeColors.light.normal = "#666"; + } + const addTab = debounce(({tabId}) => cp.tabs.get(tabId) .then(recentTabs.add) .catch(error => { diff --git a/src/js/background/constants.js b/src/js/background/constants.js index b4fd67ce..bb1b53b2 100644 --- a/src/js/background/constants.js +++ b/src/js/background/constants.js @@ -9,6 +9,19 @@ define([ const IsMac = /Mac/i.test(platform); const IsLinux = /Linux/i.test(platform); const IsEdge = /Edg\//i.test(userAgent); + const IsFirefox = /Firefox\//i.test(userAgent); + + const IncognitoNameUC = IsFirefox + ? "Private" + : IsEdge + ? "InPrivate" + : "Incognito"; + const IncognitoNameLC = IsEdge + ? "InPrivate" + : IncognitoNameUC.toLowerCase(); + const IncognitoPermission = IsFirefox + ? "Run in Private Windows" + : `Allow in ${IncognitoNameLC}`; const languagePattern = /^(?[-a-z]+)-(?[a-z]+)$/i; const primaryLanguage = languages[0]; @@ -22,8 +35,10 @@ define([ // this will get overridden in background.js if we're in dev mode IsDev: false, IsEdge, - IncognitoNameUC: IsEdge ? "InPrivate" : "Incognito", - IncognitoNameLC: IsEdge ? "InPrivate" : "incognito", + IsFirefox, + IncognitoNameUC, + IncognitoNameLC, + IncognitoPermission, SpaceBehavior: { Key: "spaceBehavior", Select: "select", diff --git a/src/js/background/get-default-settings.js b/src/js/background/get-default-settings.js index e94389f2..f8eb4584 100644 --- a/src/js/background/get-default-settings.js +++ b/src/js/background/get-default-settings.js @@ -6,8 +6,9 @@ define([ const DefaultShortcuts = { [k.Shortcuts.MRUSelect]: "w", // on Linux, the extension menu can't seem to capture ctrl-W, like - // macOS, so default to a different shortcut - [k.Shortcuts.CloseTab]: k.IsLinux ? "ctrl+alt+w" : "ctrl+w", + // macOS, so default to a different shortcut. same with Firefox on + // any platform. + [k.Shortcuts.CloseTab]: (k.IsLinux || k.IsFirefox) ? "ctrl+alt+w" : "ctrl+w", [k.Shortcuts.MoveTabLeft]: "ctrl+[", [k.Shortcuts.MoveTabRight]: "ctrl+]", [k.Shortcuts.CopyURL]: "mod+c", @@ -20,7 +21,8 @@ define([ { [k.Shortcuts.CloseTab]: "cmd+ctrl+w" }); const DefaultSettings = { [k.SpaceBehavior.Key]: k.SpaceBehavior.Select, - [k.EscBehavior.Key]: k.EscBehavior.Clear, + // on FF, pressing esc always closes the menu and can't be prevented + [k.EscBehavior.Key]: k.IsFirefox ? k.EscBehavior.Close : k.EscBehavior.Clear, [k.HomeEndBehavior.Key]: k.HomeEndBehavior.ResultsList, [k.MarkTabsInOtherWindows.Key]: true, [k.IncludeClosedTabs.Key]: true, diff --git a/src/js/common/icons.js b/src/js/common/icons.js index c5fa06aa..e747348e 100644 --- a/src/js/common/icons.js +++ b/src/js/common/icons.js @@ -1,9 +1,55 @@ define([ - "react" + "react", + "background/constants" ], function( - React + React, + {IsEdge, IsFirefox} ) { + const ChromeIncognitoIcon = () => ( + + + + + + + + + + ); + + + const InPrivateIcon = () => ( + + + + + + + + + + + + + + ); + + + const FFPrivateIcon = () => ( + + + + ); + + return { + IncognitoIcon: IsFirefox + ? FFPrivateIcon + : IsEdge + ? InPrivateIcon + : ChromeIncognitoIcon, + + SearchIcon: () => ( @@ -25,36 +71,6 @@ define([ ), - IncognitoIcon: () => ( - - - - - - - - - - ), - - - InPrivateIcon: () => ( - - - - - - - - - - - - - - ), - - HistoryIcon: () => ( diff --git a/src/js/lib/copy-to-clipboard.js b/src/js/lib/copy-to-clipboard.js index 26fce586..b6311749 100644 --- a/src/js/lib/copy-to-clipboard.js +++ b/src/js/lib/copy-to-clipboard.js @@ -7,6 +7,9 @@ define(function() { const activeElement = document.activeElement; let result; + // prevent the textarea from causing the height to change when it's + // added, which is visible in FF + copyFrom.style.cssText = "position: absolute; top: -100px;"; copyFrom.textContent = text; body.appendChild(copyFrom); copyFrom.focus(); diff --git a/src/js/options/app.js b/src/js/options/app.js index 0eb6ed48..a35bc265 100644 --- a/src/js/options/app.js +++ b/src/js/options/app.js @@ -13,15 +13,25 @@ define([ {IncognitoIcon, InPrivateIcon, HistoryIcon, WindowIcon}, k ) { - const {IncognitoNameUC, IncognitoNameLC} = k; + const {IncognitoNameUC, IncognitoNameLC, IncognitoPermission} = k; const IncognitoAction = k.IsEdge ? "click the checkbox" : "toggle it on"; - const IncognitoIndicator = k.IsEdge ? : ; + const IncognitoInstructions = k.IsFirefox + ? right-click the QuicKey toolbar icon, select Manage + Extension, and then click Allow next to the Run in + Private Windows option + : click the button below, then scroll down to + the {IncognitoPermission} setting and {IncognitoAction}; const UpdateMessage =

现在,您可以使用拼音在网页标题和URL中搜索中文字符。

您始终可以通过单击QuicKey菜单中的齿轮图标来重新打开此页面。

; + const BrowserClassName = k.IsFirefox + ? "firefox" + : k.IsEdge + ? "edge" + : "chrome"; function NewSetting({ @@ -71,8 +81,11 @@ define([ handleChangeIncognitoClick: function() { - this.openExtensionsTab("?id=" + chrome.runtime.id); - this.props.tracker.event("extension", "options-incognito"); + // FF doesn't support opening the settings tab directly + if (!k.IsFirefox) { + this.openExtensionsTab("?id=" + chrome.runtime.id); + this.props.tracker.event("extension", "options-incognito"); + } }, @@ -137,7 +150,7 @@ define([ onResetShortcuts } = this.props; - return
+ return
{ showPinyinUpdateMessage && UpdateMessage } @@ -285,11 +298,19 @@ define([ + disabled={k.IsFirefox} + > + {k.IsFirefox && +
+ Firefox always closes the menu when esc is pressed. +
+ } +
{IncognitoNameUC} windows + {!k.IsFirefox &&
+

{IncognitoNameUC} windows

-

By default, QuicKey can't switch to tabs in {IncognitoNameLC} windows. - To enable this functionality, click the button below, then - scroll down to the Allow in {IncognitoNameLC} setting - and {IncognitoAction}. {IncognitoNameUC} tabs are marked - with {IncognitoIndicator}. -

- {`${IncognitoNameUC} - +

By default, QuicKey can't switch to tabs in {IncognitoNameLC} windows. + To enable this functionality, {IncognitoInstructions}. {IncognitoNameUC} tabs + are marked with . +

+ {`${IncognitoNameUC} + +
}

Feedback and support

diff --git a/src/js/popup/app.js b/src/js/popup/app.js index 5cf71351..24fec92d 100644 --- a/src/js/popup/app.js +++ b/src/js/popup/app.js @@ -84,6 +84,7 @@ define("popup/app", [ resultsList: null, settings: settings.getDefaults(), settingsPromise: null, + className: "", getInitialState: function() @@ -139,6 +140,13 @@ define("popup/app", [ componentWillMount: function() { + // we're saving the initial value of this prop instead of + // getting it every time in render, which is normally bad, but + // the platform will never change during the life of the app + this.className = [ + this.props.platform, + k.IsFirefox ? "firefox" : "" + ].join(" "); this.loadTabs() .then(tabs => { // by the time we get here, the settings promise will @@ -447,9 +455,7 @@ define("popup/app", [ this.props.tracker.event(this.mode, "open"); } - // we seem to have to close the window in a timeout so that - // the hover state of the button gets cleared - setTimeout(function() { window.close(); }, 0); + this.closeWindow(); } }, @@ -575,8 +581,7 @@ define("popup/app", [ active: true, currentWindow: true }) - .bind(this) - .then(function(activeTabs) { + .then(activeTabs => { const activeTab = activeTabs[0]; // if the active tab is at 0, and we want to move // another tab to the left of it, force that index @@ -612,7 +617,12 @@ define("popup/app", [ index: index }) }) - .then(function(movedTab) { + .then(movedTab => { + if (Array.isArray(movedTab)) { + // annoyingly, this is returned as an array in FF + movedTab = movedTab[0]; + } + // use the movedTab from this callback, since // the tab reference we had to it from before is // likely stale. we also have to call addURLs() @@ -624,6 +634,10 @@ define("popup/app", [ this.focusTab(movedTab, unsuspend); this.props.tracker.event(this.state.query.length ? "tabs" : "recents", "move-" + (direction ? "right" : "left")); + + // focusing the tab doesn't close the menu in FF, so + // close it explicitly just in case + this.closeWindow(); }); }, @@ -670,6 +684,14 @@ define("popup/app", [ }, + closeWindow: function() + { + // we seem to have to close the window in a timeout so that + // the hover state of the button gets cleared + setTimeout(window.close, 0); + }, + + handleListRef: handleRef("resultsList"), @@ -731,6 +753,10 @@ define("popup/app", [ url: chrome.extension.getURL("options.html") }); this.props.tracker.event("extension", "open-options"); + + // opening the options tab doesn't automatically close the menu + // on Firefox + this.closeWindow(); }, @@ -744,7 +770,7 @@ define("popup/app", [ newSettingsAvailable } = this.state; - return
+ return
MaxTitleLength ? title : "", @@ -186,7 +185,7 @@ define([ } if (incognito) { - badge = IsEdge ? : ; + badge = ; badgeTooltip = IncognitoTooltip; } else if (otherWindow) { badge = ; diff --git a/src/js/popup/results-list.js b/src/js/popup/results-list.js index 1c61a234..b6f2655c 100644 --- a/src/js/popup/results-list.js +++ b/src/js/popup/results-list.js @@ -1,14 +1,19 @@ define([ "react", "react-virtualized", - "lib/handle-ref" + "lib/handle-ref", + "background/constants" ], function( React, ReactVirtualized, - handleRef + handleRef, + {IsFirefox} ) { - const RowHeight = 45, - Width = 490; + const RowHeight = 45; + // in FF, the scrollbar appears inside the right edge of the scrolling + // area, instead on the outside. so make the virtual list go right to + // the edge of the popup, so the scrollbar doesn't cover the content. + const Width = IsFirefox ? 495 : 490; var ResultsList = React.createClass({ diff --git a/src/js/popup/search-box.js b/src/js/popup/search-box.js index 09ba723b..be462337 100644 --- a/src/js/popup/search-box.js +++ b/src/js/popup/search-box.js @@ -2,12 +2,14 @@ define([ "jsx!./input", "jsx!common/icons", "lib/handle-ref", - "react" + "react", + "background/constants" ], function( Input, {SearchIcon}, handleRef, - React + React, + {IsFirefox} ) { function Placeholder({ mode, @@ -46,6 +48,15 @@ define([ handleRef: handleRef("searchBox"), + handleCancelButtonClick: function() + { + // unlike the cancel button in Chrome, clicking the one in FF + // steals the focus, so set it back in the input + this.focus(); + this.props.onChange({ target: { value: "" } }); + }, + + render: function() { const { @@ -86,6 +97,13 @@ define([ } {mode == "command" && } + {(IsFirefox && query.length > 0) && +
+ }
} }); diff --git a/src/manifest.json b/src/manifest.json index a45f50f4..d2ff7735 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 2, "name": "QuicKey DEV", "short_name": "QuicKey DEV", - "version": "1.7.4", + "version": "1.8.0", "description": "Add keyboard shortcuts to switch tabs with a Quicksilver-style search or a most recently used menu", "author": "John Dunning", "content_security_policy": "script-src 'self' 'unsafe-eval' https://www.google-analytics.com; object-src 'self'", @@ -66,4 +66,4 @@ } }, "offline_enabled": true -} \ No newline at end of file +} diff --git a/src/options.html b/src/options.html index 93e4dd4e..a632721d 100644 --- a/src/options.html +++ b/src/options.html @@ -7,6 +7,8 @@ QuicKey Options + + @@ -19,4 +21,4 @@
- \ No newline at end of file + diff --git a/src/popup.html b/src/popup.html index c9bca131..6f66c63a 100644 --- a/src/popup.html +++ b/src/popup.html @@ -19,7 +19,7 @@
-
+