Skip to content

Commit

Permalink
Release v1.1.2
Browse files Browse the repository at this point in the history
Squashed commit of the following:

commit bb283c2
Author: John Dunning <[email protected]>
Date:   Sat Sep 7 18:41:55 2019 -0700

    Fix issue #9

    Update version to 1.1.2.
    Show webstore token in console during upload.

commit 34eb09c
Merge: ee2c69a 65e4ffa
Author: John Dunning <[email protected]>
Date:   Sat Sep 7 18:28:17 2019 -0700

    Merge branch 'feature/show-tab-index-2' into dev

commit 65e4ffa
Author: John Dunning <[email protected]>
Date:   Sat Sep 7 18:10:55 2019 -0700

    Update docs to describe index number on tabs with same titles

    Add tooltip to tab index number.
    Tweak hover state of index number.
    Add badges to the README.md.

commit 2e834cc
Author: John Dunning <[email protected]>
Date:   Tue Sep 3 12:55:36 2019 -0700

    Make index lozenge flat on top and bottom when it's > 1 digit

commit ebc2cbe
Author: John Dunning <[email protected]>
Date:   Mon Sep 2 17:55:23 2019 -0700

    Restart the extension immediately when an update is available

commit d86a689
Author: John Dunning <[email protected]>
Date:   Mon Sep 2 17:16:51 2019 -0700

    Show styled left to right index in front of title

    Distinguish same titles from different domains.
    Move indexing of titles to a function inside getTabs(), so the index doesn't build up if the function is called multiple times.
    Make MatchedString a span.
    Make the close button hover state circular.
    ES6ify results-list-item.js.

commit 578b384
Author: John Dunning <[email protected]>
Date:   Sun Sep 1 19:01:41 2019 -0700

    Add a left to right index to tabs with identical titles
  • Loading branch information
fwextensions committed Sep 8, 2019
1 parent 46f923b commit ea58a2a
Show file tree
Hide file tree
Showing 11 changed files with 163 additions and 54 deletions.
2 changes: 2 additions & 0 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,8 @@ module.exports = function(grunt) {

return webstore.fetchToken()
.then(token => {
console.log(`Fetched webstore token (${token}).`);

return webstore.uploadExisting(zipStream, token)
.then((response) => {
if (response.uploadState == "SUCCESS") {
Expand Down
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

# *QuicKey*

[![Rating][rating-badge]][rating]
[![Version][version-badge]][version]


#### *QuicKey* lets you navigate all of your Chrome tabs by typing just part of a page's title or URL. No mouse needed!

* Press <b><kbd>alt</kbd><kbd>Q</kbd></b> (<b><kbd>ctrl</kbd><kbd>Q</kbd></b> on macOS).
Expand Down Expand Up @@ -88,7 +92,7 @@ To close the selected tab, press <b><kbd>ctrl</kbd><kbd>W</kbd></b> (<b><kbd>cmd

<img src="docs/img/close-button.png" width="624" alt="Close button">

When you open *QuicKey*, the 25 most recently closed tabs are listed below the recent tabs and shown in a faded state with an <img src="docs/img/clear.svg" height="19"> icon. They are also returned when you type a query, though they're scored lower than open tabs:
When you open *QuicKey*, the 25 most recently closed tabs are listed below the recent tabs and shown in a faded state with a <img src="docs/img/history.svg" height="19"> icon. They are also returned when you type a query, though they're scored lower than open tabs:

<img src="docs/img/closed-tab.png" width="624" alt="Closed tab">

Expand Down Expand Up @@ -177,3 +181,9 @@ If you find a bug in *QuicKey* or have a suggestion for a new feature, please [c
The <img src="docs/img/search.svg" height="13"> and <img src="docs/img/clear.svg" height="16"> icons are from the [Octicons](https://octicons.github.com/) set, used under the [MIT License](http://opensource.org/licenses/MIT).

The string ranking algorithm is modeled on [Quicksilver](https://github.com/quicksilver/Quicksilver/blob/master/Quicksilver/Code-QuickStepCore/QSense.m)'s code.


[rating-badge]: https://img.shields.io/chrome-web-store/stars/ldlghkoiihaelfnggonhjnfiabmaficg.svg?style=flat-square&label=Rating
[rating]: https://chrome.google.com/webstore/detail/quickey-–-the-quick-tab-s/ldlghkoiihaelfnggonhjnfiabmaficg
[version-badge]: https://img.shields.io/chrome-web-store/v/ldlghkoiihaelfnggonhjnfiabmaficg.svg?style=flat-square&label=Version
[version]: https://chrome.google.com/webstore/detail/quickey-–-the-quick-tab-s/ldlghkoiihaelfnggonhjnfiabmaficg
5 changes: 5 additions & 0 deletions docs/chrome-store-description.txt
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,11 @@ You can move tabs to the left or right of the current tab, making it easy to pul
Include SHIFT in the shortcut to also unsuspend the tab while moving it. The CTRL key should be used on both Windows and macOS. Note that you cannot move tabs between normal and incognito windows.


★ Tabs with identical titles

A tab that has the same title as other open tabs will display a number to indicate its left-to-right position among those other tabs. For instance, if you open tabs for two different Google Drive accounts, they'll both be titled "My Drive - Google Drive". But the one on the left will show a "1" next to its title in the menu and the one on the right will show a "2". This makes it easier for you to select the tab you want when you know how they're organized in your window.


★ Search bookmarks

To find a bookmark, type "/b" in the search box, then a space, and then part of the bookmark's name or URL.
Expand Down
5 changes: 5 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,11 @@ You can move tabs to the left or right of the current tab, making it easy to pul
Include <kbd>shift</kbd> in the shortcut to also unsuspend the tab while moving it. The <kbd>ctrl</kbd> key should be used on both Windows and macOS. Note that you cannot move tabs between normal and incognito windows.


## Tabs with identical titles

A tab that has the same title as other open tabs will display a number to indicate its left-to-right position among those other tabs. For instance, if you open tabs for two different Google Drive accounts, they'll both be titled *My Drive - Google Drive*. But the one on the left will show a **1** next to its title in the menu and the one on the right will show a **2**. This makes it easier for you to select the tab you want when you know how they're organized in your window.


## <a name="bookmarks"></a>Search bookmarks

To find a bookmark, type <b><kbd>/</kbd><kbd>b</kbd><kbd>space</kbd></b> in the search box, and then part of the bookmark's name or URL.
Expand Down
7 changes: 7 additions & 0 deletions docs/releases/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ comments: true
# Release history


## 1.1.2 - 2019-09-07

### Added

* A tab that has the same title as other open tabs will display a number to indicate its left-to-right position among those other tabs, making it easier to find the tab you want.


## 1.1.1 - 2019-08-31

### Fixed
Expand Down
23 changes: 22 additions & 1 deletion src/css/popup.css
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ input.search-box::-webkit-search-cancel-button {
opacity: 0.4;
}

.results-list-item div {
.results-list-item div.title, .results-list-item div.url {
width: 100%;
height: 19px;
text-overflow: ellipsis;
Expand Down Expand Up @@ -186,6 +186,26 @@ input.search-box::-webkit-search-cancel-button {
opacity: 0.45;
}

.results-list-item div.title-index {
font-size: 0.75em;
font-weight: bold;
text-align: center;
color: #666;
min-width: 1.5em;
height: 1.5em;
top: -0.1em;
background: #efefef;
border-radius: .75em;
padding: .05em 0.4em 0 0.4em;
margin: 0 .5em 0 0;
display: inline-block;
position: relative;
}

.results-list-item.selected div.title-index {
background: #fafafa;
}

.results-list-item.tabs.selected:not(.closed):hover {
padding-right: 36px;
}
Expand All @@ -208,6 +228,7 @@ input.search-box::-webkit-search-cancel-button {
background-color: transparent;
border: none;
opacity: .6;
border-radius: 50%;
position: absolute;
display: block;
}
Expand Down
13 changes: 13 additions & 0 deletions src/js/background/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const MaxPopupLifetime = 450;
const TabActivatedOnStartupDelay = 750;
const TabRemovedDelay = 1000;
const MinTabDwellTime = 750;
const RestartDelay = 10 * 1000;
const IconPaths = {
path: {
"19": "img/icon-19.png",
Expand Down Expand Up @@ -269,12 +270,24 @@ require([


chrome.runtime.onUpdateAvailable.addListener(details => {
function restartExtension()
{
if (!popupIsOpen) {
DEBUG && console.log("=== reloading");
chrome.runtime.reload();
} else {
setTimeout(restartExtension, RestartDelay);
}
}

try {
backgroundTracker.event("extension", "update-available",
details && details.version);
} catch (e) {
console.log(e);
}

restartExtension();
});


Expand Down
53 changes: 47 additions & 6 deletions src/js/popup/data/get-tabs.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,38 @@ define([
return function getTabs(
tabsPromise)
{
let tabsByTitle = {};


function indexDuplicateTitles(
tab)
{
// don't include closed tabs, because there's no sense in which
// they have a left to right index
if (typeof tab.sessionId == "undefined") {
const {title, displayURL} = tab;
// the domain has already been stripped out of displayURL and
// if the URL doesn't contain "/", [0] will be the whole URL
const domainAndTitle = displayURL.split("/")[0] + title;
const tabsWithSameTitle = (tabsByTitle[domainAndTitle] =
tabsByTitle[domainAndTitle] || []);
const {length} = tabsWithSameTitle;

if (length) {
if (length == 1) {
// go back and set the titleIndex on the first tab,
// now that we know other tabs have the same title
tabsWithSameTitle[0].titleIndex = length;
}

tab.titleIndex = length + 1;
}

tabsWithSameTitle.push(tab);
}
}


return Promise.all([
tabsPromise,
cp.tabs.query({
Expand All @@ -48,12 +80,8 @@ define([
// return a normal active tab in Chrome pre-65. default to
// an empty object so the .id access below won't throw
// an exception.
var activeTab = activeTabs[0] || {},
match;

// remove the active tab from the array so it doesn't show up in
// the results, making it clearer if you have duplicate tabs open
_.remove(tabs, { id: activeTab.id });
const activeTab = activeTabs[0] || {};
let match;

tabs.forEach(function(tab) {
addURLs(tab);
Expand All @@ -73,8 +101,21 @@ define([
tab.title = decode(match[1]);
}
}

indexDuplicateTitles(tab);
});

// remove the active tab from the array so it doesn't show
// up in the results, making it clearer if you have duplicate
// tabs open. but do this after processing all the tabs, so
// that if the current tab has the same title as another in
// the same window, the indexes displayed for the other tabs
// will be correct.
_.remove(tabs, { id: activeTab.id });

// make sure this index of tabs gets GC'd
tabsByTitle = null;

return tabs;
});
}
Expand Down
5 changes: 2 additions & 3 deletions src/js/popup/matched-string.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,10 @@ define([
return function MatchedString(
props)
{
return <div
className={props.className}
return <span
data-score={props.score}
>
{wrapMatches(props.query, props.text, props.hitMask)}
</div>
</span>
}
});
90 changes: 48 additions & 42 deletions src/js/popup/results-list-item.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ define([
React,
_
) {
const MaxTitleLength = 70,
MaxURLLength = 75,
MinMouseMoveCount = 1,
SuspendedFaviconOpacity = .5,
FaviconURL = "chrome://favicon/";
const MaxTitleLength = 70;
const MaxURLLength = 75;
const MinMouseMoveCount = 1;
const SuspendedFaviconOpacity = .5;
const FaviconURL = "chrome://favicon/";

var IsDevMode = false;
let IsDevMode = false;


cp.management.getSelf()
Expand All @@ -26,14 +26,14 @@ define([
});


var ResultsListItem = React.createClass({
const ResultsListItem = React.createClass({
mouseMoveCount: 0,


onClick: function(
event)
{
var item = this.props.item;
const {item} = this.props;

if (IsDevMode && event.altKey) {
// copy some debug info to the clipboard
Expand Down Expand Up @@ -63,7 +63,7 @@ define([
onMouseMove: function(
event)
{
var props = this.props;
const {props} = this;

if ((props.selectedIndex > 0 || this.mouseMoveCount > MinMouseMoveCount)
&& !props.isSelected) {
Expand All @@ -89,7 +89,7 @@ define([
onMouseEnter: function(
event)
{
var props = this.props;
const {props} = this;

if (props.selectedIndex > 0 || this.mouseMoveCount > MinMouseMoveCount) {
props.setSelectedIndex(props.index);
Expand All @@ -99,26 +99,24 @@ define([

render: function()
{
var props = this.props,
item = props.item,
query = props.query,
scores = item.scores,
hitMasks = item.hitMasks,
tooltip = [
item.title.length > MaxTitleLength ? item.title : "",
item.displayURL.length > MaxURLLength ? item.displayURL : ""
].join("\n"),
className = [
"results-list-item",
props.mode,
(props.isSelected ? "selected" : ""),
(item.unsuspendURL ? "suspended" : ""),
(item.incognito ? "incognito" : ""),
(item.sessionId ? "closed" : "")
].join(" "),
faviconStyle = {
backgroundImage: "url(" + item.faviconURL + ")"
};
const {props} = this;
const {item, query} = props;
const {scores, hitMasks, title, displayURL, titleIndex} = item;
const className = [
"results-list-item",
props.mode,
(props.isSelected ? "selected" : ""),
(item.unsuspendURL ? "suspended" : ""),
(item.incognito ? "incognito" : ""),
(item.sessionId ? "closed" : "")
].join(" ");
const faviconStyle = {
backgroundImage: "url(" + item.faviconURL + ")"
};
let tooltip = [
title.length > MaxTitleLength ? title : "",
displayURL.length > MaxURLLength ? displayURL : ""
].join("\n");

if (IsDevMode) {
tooltip = _.toPairs(item.scores).concat([["recentBoost", item.recentBoost], ["id", item.id]])
Expand Down Expand Up @@ -149,18 +147,26 @@ define([
<span className="favicon"
style={faviconStyle}
/>
<MatchedString className="title"
query={query}
text={item.title}
score={scores.title}
hitMask={hitMasks.title}
/>
<MatchedString className="url"
query={query}
text={item.displayURL}
score={scores.displayURL}
hitMask={hitMasks.displayURL}
/>
<div className="title">
{titleIndex &&
<div className="title-index"
title="Position among tabs with the same title"
>{titleIndex}</div>}
<MatchedString
query={query}
text={title}
score={scores.title}
hitMask={hitMasks.title}
/>
</div>
<div className="url">
<MatchedString
query={query}
text={displayURL}
score={scores.displayURL}
hitMask={hitMasks.displayURL}
/>
</div>
<button className="close-button"
title="Close tab"
onClick={this.onClose}
Expand Down
2 changes: 1 addition & 1 deletion src/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"manifest_version": 2,
"name": "QuicKey DEV",
"short_name": "QuicKey",
"version": "1.1.1",
"version": "1.1.2",
"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'",
Expand Down

0 comments on commit ea58a2a

Please sign in to comment.