Skip to content

Commit 2e3e2d3

Browse files
authored
Merge pull request #13 from satoryu/show-count-of-selected-tabs
Show the count of selected tabs on the button
2 parents 649c2cf + fc2298c commit 2e3e2d3

7 files changed

Lines changed: 99 additions & 40 deletions

File tree

popup.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<div id="message-box"></div>
1111

1212
<button id="copy-current-tab-button">Copy Current Tab</button>
13-
<button id="copy-selected-tabs-button">Copy Selected Tab</button>
13+
<button id="copy-selected-tabs-button">Copy Selected Tabs (<span id="count-of-selected-tabs">0</span>)</button>
1414
<button id="copy-all-tabs-button">Copy All Tabs</button>
1515
</div>
1616
<script src="popup.js" type="module"></script>

popup.js

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { writeTextToClipboard } from './src/clipboard.js';
2-
import { findTabs } from './src/chrome.js';
2+
import { getCurrentTab, getSelectedTabs, getAllTabsOnCurrentWindow } from './src/chrome.js';
33
import { createLinkForTab, createLinksForTabs } from './src/link.js';
44

55
let messageBox = document.getElementById('message-box');
@@ -14,36 +14,30 @@ function appendMessage(messageText) {
1414
}
1515

1616
copyCurrentTabButton.addEventListener('click', () => {
17-
findTabs({ active: true, currentWindow: true })
18-
.then(([tab]) => {
19-
let linkText = createLinkForTab(tab)
20-
21-
writeTextToClipboard(linkText).then(() => {
22-
appendMessage('Copied')
23-
})
24-
})
17+
getCurrentTab()
18+
.then(([tab]) => (createLinkForTab(tab)))
19+
.then(writeTextToClipboard)
20+
.then(() => { appendMessage('Copied') })
2521
.catch((err) => console.error(err))
2622
});
2723

2824
copySelectedTabsButton.addEventListener('click', () => {
29-
findTabs({ highlighted: true, currentWindow: true })
30-
.then(tabs => {
31-
let linkText = createLinksForTabs(tabs)
32-
33-
writeTextToClipboard(linkText).then(() => {
34-
appendMessage('Copied Selected Tabs!')
35-
})
36-
})
25+
getSelectedTabs()
26+
.then(createLinksForTabs)
27+
.then(writeTextToClipboard)
28+
.then(() => { appendMessage('Copied Selected Tabs!') })
3729
.catch((err) => console.error(err))
3830
})
31+
const countOfSelectedTabs = document.getElementById('count-of-selected-tabs')
32+
if (countOfSelectedTabs) {
33+
getSelectedTabs().then(tabs => {
34+
countOfSelectedTabs.textContent = tabs.length
35+
})
36+
}
3937

4038
copyAllTabsButton.addEventListener('click', () => {
41-
findTabs({currentWindow: true})
42-
.then(tabs => {
43-
let linkText = createLinksForTabs(tabs)
44-
45-
writeTextToClipboard(linkText).then(() => {
46-
appendMessage('Copied All Tabs!')
47-
})
48-
})
39+
getAllTabsOnCurrentWindow()
40+
.then(createLinksForTabs)
41+
.then(writeTextToClipboard)
42+
.then(() => { appendMessage('Copied All Tabs!') })
4943
})

src/chrome.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,16 @@ function findTabs(queryOption) {
22
return chrome.tabs.query(queryOption)
33
}
44

5-
export { findTabs }
5+
function getCurrentTab() {
6+
return findTabs({active: true, currentWindow: true})
7+
}
8+
9+
function getSelectedTabs() {
10+
return findTabs({highlighted: true, currentWindow: true})
11+
}
12+
13+
function getAllTabsOnCurrentWindow() {
14+
return findTabs({ currentWindow: true })
15+
}
16+
17+
export { findTabs, getCurrentTab, getSelectedTabs, getAllTabsOnCurrentWindow }

src/link.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
function createLinkForTab(tab) {
1+
async function createLinkForTab(tab) {
22
const title = tab.title.replaceAll(/[\[\]]/g, '').replaceAll(/`(.*)`/g, '$1')
33

44
return `[${tab.url} ${title}]`
55
}
66

7-
function createLinksForTabs(tabs) {
8-
return tabs.map(createLinkForTab).map((link) => (` ${link}`)).join("\n")
7+
async function createLinksForTabs(tabs) {
8+
return Promise.all(tabs.map(createLinkForTab))
9+
.then((links) => (links.map((link) => (` ${link}`)).join("\n")))
910
}
1011

1112
export { createLinksForTabs, createLinkForTab }

test/chrome.test.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { findTabs, getCurrentTab, getSelectedTabs, getAllTabsOnCurrentWindow } from '../src/chrome.js'
2+
3+
global.chrome = {
4+
tabs: {
5+
query: jest.fn(options => (options))
6+
}
7+
}
8+
9+
beforeEach(() => {
10+
chrome.tabs.query.mockClear()
11+
})
12+
13+
describe("findTabs", () => {
14+
it("passes given options to chrome.tabs.query()", async () => {
15+
const expectedOptions = { active: true, currentWindow: true }
16+
17+
await findTabs(expectedOptions)
18+
19+
expect(chrome.tabs.query.mock.calls[0][0]).toEqual(expectedOptions)
20+
})
21+
})
22+
23+
describe("getCurrentTab", () => {
24+
it("passes a specific option to findTabs to get the current tab", async () => {
25+
const expectedOptions = { active: true, currentWindow: true }
26+
27+
await getCurrentTab()
28+
29+
expect(chrome.tabs.query.mock.calls[0][0]).toEqual(expectedOptions)
30+
})
31+
})
32+
33+
describe("getSelectedTabs", () => {
34+
it("passes a specific option to findTabs to get the selected tabs", async () => {
35+
const expectedOptions = { highlighted: true, currentWindow: true }
36+
37+
await getSelectedTabs()
38+
39+
expect(chrome.tabs.query.mock.calls[0][0]).toEqual(expectedOptions)
40+
})
41+
})
42+
43+
describe("getAllTabsOnCurrentWindow", () => {
44+
it("passes a specific option to findTabs to get the selected tabs", async () => {
45+
const expectedOptions = { currentWindow: true }
46+
47+
await getAllTabsOnCurrentWindow()
48+
49+
expect(chrome.tabs.query.mock.calls[0][0]).toEqual(expectedOptions)
50+
})
51+
})

test/link.test.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
import { createLinkForTab } from "../src/link.js";
22

33
describe("createLinkForTab", () => {
4-
test("creates a link from a given tab's title and url", () => {
5-
const link = createLinkForTab({
4+
test("creates a link from a given tab's title and url", async () => {
5+
const link = await createLinkForTab({
66
title: "title",
77
url: "https://example.com",
88
});
99

1010
expect(link).toEqual("[https://example.com title]");
1111
});
1212

13-
test("omits square brackets in title", () => {
14-
const link = createLinkForTab({
13+
test("omits square brackets in title", async () => {
14+
const link = await createLinkForTab({
1515
title: "[title]",
1616
url: "https://example.com",
1717
});

test/popup.test.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@ describe("appendMessage", () => {
99
<div id="message-box"></div>
1010
1111
<button id="copy-current-tab-button">Copy Current Tab</button>
12-
<button id="copy-selected-tabs-button">Copy Selected Tabs</button>
12+
<button id="copy-selected-tabs-button">Copy Selected Tabs (<span id="count-of-selected-tabs">0</span>)</button>
1313
<button id="copy-all-tabs-button">Copy All Tabs</button>
1414
`;
1515

1616
jest.mock("../src/chrome.js", () => mockChrome)
17+
mockChrome.getSelectedTabs = jest.fn(() => (Promise.resolve([])))
1718

1819
require("./../popup.js");
1920
})
@@ -22,11 +23,11 @@ describe("appendMessage", () => {
2223
let user
2324

2425
beforeEach(async () => {
25-
mockChrome.findTabs = jest.fn(() => {
26+
mockChrome.getCurrentTab = jest.fn(() => {
2627
return Promise.resolve([
2728
{ title: "hoge", url: "https://www.example.com" },
2829
]);
29-
}),
30+
})
3031

3132
user = userEvent.setup()
3233
const button = screen.getByRole('button', { name: 'Copy Current Tab' })
@@ -50,14 +51,14 @@ describe("appendMessage", () => {
5051
let user
5152

5253
beforeEach(async () => {
53-
mockChrome.findTabs = jest.fn(() => {
54+
mockChrome.getSelectedTabs = jest.fn(() => {
5455
return Promise.resolve([
5556
{ title: "hoge", url: "https://www.example.com" },
5657
{ title: "fuga", url: "https://fuga.example.com" },
5758
]);
5859
})
5960
user = userEvent.setup()
60-
const button = screen.getByRole('button', { name: 'Copy Selected Tabs' })
61+
const button = screen.getByRole('button', { name: 'Copy Selected Tabs ( 0 )' })
6162
await user.click(button)
6263
})
6364

@@ -78,7 +79,7 @@ describe("appendMessage", () => {
7879
let user
7980

8081
beforeEach(async () => {
81-
mockChrome.findTabs = jest.fn(() => {
82+
mockChrome.getAllTabsOnCurrentWindow = jest.fn(() => {
8283
return Promise.resolve([
8384
{ title: "foo", url: "https://www.foo.com" },
8485
{ title: "bar", url: "https://www.bar.com" },

0 commit comments

Comments
 (0)