Skip to content

Commit

Permalink
Add option to open Treetop in a new tab
Browse files Browse the repository at this point in the history
  • Loading branch information
msmolens committed Dec 29, 2023
1 parent 9558ef8 commit 5f81c33
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 28 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Added

- Add Google Chrome support.
- Add option to open Treetop in a new tab.

### Changed

Expand Down
4 changes: 4 additions & 0 deletions _locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@
"message": "Appearance",
"description": "Title of group for appearance options."
},
"optionOpenInNewTab": {
"message": "Open Treetop in a new tab",
"description": "Title of option to open Treetop in a new tab."
},
"optionTruncateLongTitles": {
"message": "Truncate long titles",
"description": "Title of option to truncate long bookmark titles."
Expand Down
4 changes: 1 addition & 3 deletions src/background_script/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ export const init = async (): Promise<void> => {

// Set default options
const options = {
showBookmarksToolbar: true,
showBookmarksMenu: true,
showOtherBookmarks: true,
openInNewTab: true,
truncate: true,
tooltips: true,
showRecentlyVisited: true,
Expand Down
71 changes: 50 additions & 21 deletions src/background_script/open-treetop.test.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,60 @@
import faker from 'faker';
import { expect, it, vi } from 'vitest';
import { beforeEach, describe, expect, it, vi } from 'vitest';

import { openTreetop } from '@Treetop/background_script/open-treetop';

it('opens in current tab', () => {
const tab: chrome.tabs.Tab = {
active: false,
autoDiscardable: false,
discarded: false,
groupId: 0,
highlighted: false,
incognito: false,
index: 0,
pinned: false,
selected: false,
windowId: 0,
};
describe('open-treetop', () => {
let tab: chrome.tabs.Tab;
let url: string;

const url = faker.internet.url();
beforeEach(() => {
tab = {
active: false,
autoDiscardable: false,
discarded: false,
groupId: 0,
highlighted: false,
incognito: false,
index: 0,
pinned: false,
selected: false,
windowId: 0,
};

const update = vi.fn();
vi.spyOn(chrome.tabs, 'update').mockImplementation(update);
url = faker.internet.url();
});

vi.spyOn(chrome.runtime, 'getURL').mockReturnValue(url);
it('opens in current tab', async () => {
const get = vi.fn().mockResolvedValue({ openInNewTab: false });
vi.spyOn(chrome.storage.local, 'get').mockImplementation(get);

openTreetop(tab);
const update = vi.fn();
vi.spyOn(chrome.tabs, 'update').mockImplementation(update);

expect(update).toHaveBeenCalledOnce();
expect(update).toHaveBeenCalledWith({ url });
vi.spyOn(chrome.runtime, 'getURL').mockReturnValue(url);

openTreetop(tab);

await new Promise((resolve) => setTimeout(resolve));

expect(update).toHaveBeenCalledOnce();
expect(update).toHaveBeenCalledWith({ url });
});

it('opens in new tab', async () => {
const get = vi.fn().mockResolvedValue({ openInNewTab: true });
vi.spyOn(chrome.storage.local, 'get').mockImplementation(get);

const create = vi.fn();
vi.spyOn(chrome.tabs, 'create').mockImplementation(create);

vi.spyOn(chrome.runtime, 'getURL').mockReturnValue(url);

openTreetop(tab);

await new Promise((resolve) => setTimeout(resolve));

expect(create).toHaveBeenCalledOnce();
expect(create).toHaveBeenCalledWith({ url });
});
});
18 changes: 15 additions & 3 deletions src/background_script/open-treetop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,22 @@

import type { ChromeEventCallback } from '@Treetop/treetop/types';

const asyncOpenTreetop = async (): Promise<void> => {
const url = chrome.runtime.getURL('treetop.html');

const { openInNewTab } = await chrome.storage.local.get('openInNewTab');

if (openInNewTab) {
await chrome.tabs.create({ url });
} else {
await chrome.tabs.update({ url });
}
};

export const openTreetop: ChromeEventCallback<
typeof chrome.action.onClicked
> = () => {
const url = chrome.runtime.getURL('treetop.html');

void chrome.tabs.update({ url });
asyncOpenTreetop().catch((err) => {
console.error(err);
});
};
13 changes: 13 additions & 0 deletions src/options/Options.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
let options: Record<string, any>;
const strings = {
general: chrome.i18n.getMessage('optionHeadingGeneral'),
bookmarks: chrome.i18n.getMessage('optionHeadingBookmarks'),
appearance: chrome.i18n.getMessage('optionHeadingAppearance'),
openInNewTab: chrome.i18n.getMessage('optionOpenInNewTab'),
truncate: chrome.i18n.getMessage('optionTruncateLongTitles'),
tooltips: chrome.i18n.getMessage('optionDisplayTooltips'),
showRecentlyVisited: chrome.i18n.getMessage('optionShowRecentlyVisited'),
Expand Down Expand Up @@ -114,6 +116,17 @@

{#if options}
<main>
<h3>{strings.general}</h3>
<div>
<label>
<input
type="checkbox"
bind:checked={options.openInNewTab}
on:change={handleCheckboxChange}
data-option-name="openInNewTab" />
{strings.openInNewTab}
</label>
</div>
<h3>{strings.bookmarks}</h3>
<div>
<label>
Expand Down
10 changes: 9 additions & 1 deletion src/options/Options.svelte.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,14 @@ describe('Options', () => {
beforeEach(() => {
vi.spyOn(chrome.i18n, 'getMessage').mockImplementation((messageName) => {
switch (messageName) {
case 'optionHeadingGeneral':
return 'general';
case 'optionHeadingBookmarks':
return 'bookmarks';
case 'optionHeadingAppearance':
return 'appearance';
case 'optionOpenInNewTab':
return 'open in new tab';
case 'optionTruncateLongTitles':
return 'truncate';
case 'optionDisplayTooltips':
Expand All @@ -52,6 +56,7 @@ describe('Options', () => {
});

const get = vi.fn().mockResolvedValue({
openInNewTab: true,
truncate: false,
tooltips: true,
showRecentlyVisited: true,
Expand All @@ -64,8 +69,10 @@ describe('Options', () => {
setup();

await waitFor(() => {
expect(screen.getByText(/^general/i)).toBeInTheDocument();
expect(screen.getByText(/^bookmarks/i)).toBeInTheDocument();
expect(screen.getByText(/^appearance/i)).toBeInTheDocument();
expect(screen.getByLabelText(/^open in new tab/i)).toBeInTheDocument();
expect(screen.getByLabelText(/^truncate/i)).toBeInTheDocument();
expect(screen.getByLabelText(/^tooltips/i)).toBeInTheDocument();
expect(
Expand All @@ -86,9 +93,10 @@ describe('Options', () => {
setup();

await waitFor(() => {
expect(screen.getByText(/^bookmarks/i)).toBeInTheDocument();
expect(screen.getByText(/^general/i)).toBeInTheDocument();
});

expect(screen.getByLabelText(/^open in new tab/i)).toBeChecked();
expect(screen.getByLabelText(/^truncate/i)).not.toBeChecked();
expect(screen.getByLabelText(/^tooltips/i)).toBeChecked();
expect(screen.getByLabelText(/^show recently visited/i)).toBeChecked();
Expand Down

0 comments on commit 5f81c33

Please sign in to comment.