Skip to content

Commit

Permalink
Merge pull request #31 from onozaty/12-supports-manifest-v3
Browse files Browse the repository at this point in the history
#12 Support Manifest V3
  • Loading branch information
onozaty authored May 25, 2024
2 parents d619597 + ce529ad commit 4fa80d7
Show file tree
Hide file tree
Showing 13 changed files with 306 additions and 115 deletions.
51 changes: 51 additions & 0 deletions README.ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ ShortcutKey2URL for Chromeは、ショートカットキーを使用してURLを
* シークレットウインドウに指定のURLを開く。
* シークレットウインドウに現在のタブと同じURLを開く。

**Manifest V3 の制限により、文字列としてJavaScriptを指定できなくなりました。**
**拡張機能がインストールされたフォルダ配下にある`user-script.js`にて、実行したいJavaScriptをあらかじめ記載しておく必要があります。**
**詳しくは [Scriptの指定方法](#scriptの設定方法) をご参照ください。**

## インストール

下記からインストールします。
Expand Down Expand Up @@ -99,3 +103,50 @@ ShortcutKey2URL for Chromeは、ショートカットキーを使用してURLを

ショートカットキーの一覧は、エクスポート / インポートが可能です。
これによりバックアップを取ったり、移行を行うことができます。(FirefoxとChrome間での移行など)

## Scriptの設定方法

`Script`で選択するものは、拡張機能がインストールされたフォルダ配下にある`user-script.js`にて定義しておく必要があります。
**これは Manifest V3 の制限により、文字列としてJavaScriptを指定できなくなったためです。**

拡張機能のインストールフォルダの探し方は、下記を参考にしてください。

* [Where does Chrome store extensions? \- Stack Overflow](https://stackoverflow.com/questions/14543896/where-does-chrome-store-extensions/14544700#14544700)

`user-script.js``USER_SCRIPT`として定義した内容が、`Script`の選択肢として表示されます。
`user-script.js`には、あらかじめ例となるコードが記載されています。

```js
const USER_SCRIPTS = [
{
id: 'scroll-to-bottom',
title: '(Example) Scroll to bottom',
func: () => {
window.scrollTo({
top: document.body.scrollHeight,
behavior: 'smooth'
});
}
},
{
id: 'save-to-pinboard',
title: '(Example) Save to Pinboard',
func: () => {
// https://pinboard.in/howto/#saving
q = location.href; if (document.getSelection) { d = document.getSelection(); } else { d = ''; }; p = document.title; void (open('https://pinboard.in/add?url=' + encodeURIComponent(q) + '&description=' + encodeURIComponent(d) + '&title=' + encodeURIComponent(p), 'Pinboard', 'toolbar=no,width=700,height=350'));
}
}
];
```

![Screenshot of script](screenshots/script.png)

1つのスクリプトは、下記の3つのプロパティから構成されます。

* `id` : 一意に識別するためのIDです。画面には表示されませんが、設定値としてこの値が保存されます。
* `title` : 設定画面で選択肢として表示される名前です。
* `func` : 実際に実行される関数です。

新しいスクリプトを用意する際には、ここに追記してください。

拡張機能のバージョンアップ時に本ファイルはリセットされてしまいますので、バックアップを取っておいたうえで、バージョンアップ後に再度修正するようお願いします。
50 changes: 50 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ The items that can be set as actions are as follows.
* Open specified URL in incognito window.
* Open same URL as the current tab in incognito window.

**Due to a limitation in Manifest V3, it is no longer possible to specify JavaScript as a string.**
**You must specify the JavaScript you wish to execute in advance in the `user-script.js` file under the folder where the extension is installed. For details, please refer to [How to Specify Script](#how-to-specify-script).**

## Installation

Install from the following.
Expand Down Expand Up @@ -99,3 +102,50 @@ However, if the size of the settings is too large to be saved by synchronization

The list of shortcut keys can be exported / imported.
This allows you to take backups and perform migrations. (E.g. migration between Firefox and Chrome)

## How to Specify Script

The `Script` to be selected must be defined in `user-script.js` under the folder in which the extension is installed.
**This is due to a restriction in Manifest V3 that no longer allows JavaScript to be specified as a string.**

Please refer to the following for information on how to locate the extension installation folder.

* [Where does Chrome store extensions? \- Stack Overflow](https://stackoverflow.com/questions/14543896/where-does-chrome-store-extensions/14544700#14544700)

The content defined as `USER_SCRIPT` in `user-script.js` will be displayed as the `Script` options.
The `user-script.js` contains an example code in advance.

```js
const USER_SCRIPTS = [
{
id: 'scroll-to-bottom',
title: '(Example) Scroll to bottom',
func: () => {
window.scrollTo({
top: document.body.scrollHeight,
behavior: 'smooth'
});
}
},
{
id: 'save-to-pinboard',
title: '(Example) Save to Pinboard',
func: () => {
// https://pinboard.in/howto/#saving
q = location.href; if (document.getSelection) { d = document.getSelection(); } else { d = ''; }; p = document.title; void (open('https://pinboard.in/add?url=' + encodeURIComponent(q) + '&description=' + encodeURIComponent(d) + '&title=' + encodeURIComponent(p), 'Pinboard', 'toolbar=no,width=700,height=350'));
}
}
];
```

![Screenshot of script](screenshots/script.png)

A single script consists of the following three properties.

* `id` : ID for unique identification. This value is not displayed on the screen, but is stored as a configuration value.
* `title` : This is the name that appears as an option on the settings screen.
* `func` : The function that is actually executed.

When preparing new scripts, please add here.

This file will be reset when the extension is upgraded, so please make a backup and modify it again after the upgrade.
Binary file modified screenshots/add_current_page_setting.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/script.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions src/background-wrapper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
importScripts('actions.js');
importScripts('settings.js');
importScripts('user-scripts.js');
importScripts('handler.js');
importScripts('background.js');
143 changes: 80 additions & 63 deletions src/background.js
Original file line number Diff line number Diff line change
@@ -1,74 +1,91 @@
Settings.newAsync().then((settings) => {
const addCurrentPage = () => {
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
const tab = tabs[0];
chrome.runtime.openOptionsPage(() => {
// It takes time to open the option page
setTimeout(() => {
chrome.runtime.sendMessage(
{
target: 'options',
name: 'add',
data: {
title: tab.title,
action: ActionId.JUMP_URL,
url: tab.url
}
});
}, 500);
});
});
}

const handler = new Handler(settings);
chrome.runtime.onInstalled.addListener(() => {
chrome.contextMenus.create({
id: 'add-shortcutkey2url',
title: 'Add to ShortcutKey2URL',
contexts: ['all'],
type: 'normal',
});
});

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
console.log(message);
chrome.runtime.onStartup.addListener(() => {
Settings.initialize();
});

switch(message.target) {
case 'background-handler':
const result = handler.handle(message);
chrome.contextMenus.onClicked.addListener(function (info, tab) {
if (info.menuItemId == 'add-shortcutkey2url') {
addCurrentPage();
}
});

console.log(result);
sendResponse(result);
return;
const handleMessage = (message, sendResponse, handler, settings) => {

case 'background-settings':
if (message.name == 'load') {
// load
settings.reload().then(() => {
sendResponse(settings.data());
});
} else {
// save
settings.update(message.settings).then(() => {
sendResponse(settings.data());
});
}
return true;
switch (message.target) {
case 'background-handler':
const result = handler.handle(message, settings);

case 'background-options':
// Message name is 'add' only
addCurrentPage();
return;
console.log(result);
sendResponse(result);
return;

/** Chrome only */
case 'background-shortcuts':
// Message name is 'open' only
chrome.tabs.create({url: 'chrome://extensions/shortcuts'});
return;
case 'background-settings':
if (message.name == 'load') {
// load
settings.reload().then(() => {
sendResponse(settings.data());
});
} else {
// save
settings.update(message.settings).then(() => {
sendResponse(settings.data());
});
}
/*--------------*/
});
return;

const addCurrentPage = function() {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
const tab = tabs[0];
chrome.runtime.openOptionsPage(() => {
// It takes time to open the option page
setTimeout(() => {
chrome.runtime.sendMessage(
{
target: 'options',
name: 'add',
data: {
title: tab.title,
action: ActionId.JUMP_URL,
url: tab.url
}
});
},
500);
});
});
case 'background-options':
// Message name is 'add' only
addCurrentPage();
return;

/** Chrome only */
case 'background-shortcuts':
// Message name is 'open' only
chrome.tabs.create({ url: 'chrome://extensions/shortcuts' });
return;
}
}

chrome.contextMenus.create({
title: 'Add to ShortcutKey2URL',
contexts: ['all'],
type: 'normal',
onclick: () => {
addCurrentPage();
}
});
});
let handler;
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
console.log(message);

if (handler == null) {
handler = new Handler();
}

Settings.getCache().then((settings) => {
handleMessage(message, sendResponse, handler, settings);
})

return true;
});
Loading

0 comments on commit 4fa80d7

Please sign in to comment.