Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion doc/Sources/user-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ toc-own-page: true
WEBサイトをリロードした際に「フォームを再送信しますか?」ダイアログが表示されたとき、自動でキャンセルしリロードを中止するソリューションです。
誤操作によるフォーム再送信の防止を目的としています。 

また、「フォームを再送信しますか?」というエラーページ(ERR_CACHE_MISS)が表示された場合に、自動でそのエラーページを閉じます。

\newpage
# システム要件

Expand Down Expand Up @@ -381,7 +383,7 @@ https://example.com/*

#### @WARNING_WHEN_CLOSE_DIALOG

フォームを再送信しますか?」ダイアログをキャンセルしたとき、以下のような追加の警告ダイアログを表示します。
フォームを再送信しますか?」ダイアログをキャンセルしたとき、以下のような追加の警告ダイアログを表示します。

![](user-guide/media/image31.png)

Expand All @@ -392,6 +394,8 @@ https://example.com/*
@WARNING_WHEN_CLOSE_DIALOG
```

「フォームを再送信しますか?」のエラーページ(ERR_CACHE_MISS)が表示され、自動でそのエラーページを閉じるケースでは、この警告ダイアログは表示されません。

### 対象URL一覧

対象URL一覧については、`[TARGETS]`セクションに記載します。
Expand Down
114 changes: 104 additions & 10 deletions doc/verify/sources/PreReleaseTests.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,31 @@

#### 検証

* https://www.google.com/ を開く
* すべてのURLを対象としている場合も、http/httpsのサイトを開いていないとアドインが動作しないため
##### ダイアログを自動でキャンセルするケース

* `powershell doc\verify\sources\TestTools\http_server.ps1`でローカルのWebサーバーを起動する
* `http://localhost:8080`で簡易Webサーバーが起動する
* `doc\verify\sources\TestTools\form.html` を開く
* フォームに「test」と入力して、「送信」ボタンを押す
* 「form.html」 をリロードする
* 遷移先の http://localhost:8080 をリロードする
* [ ] 「フォームを再送信しますか?」ダイアログ一瞬表示され、キャンセルされること
* この状態で、2分程待機する(時間経過で拡張機能が停止しないことの確認)
* 「form.html」 をリロードする
* http://localhost:8080 をリロードする
* [ ] 「フォームを再送信しますか?」ダイアログ一瞬表示され、キャンセルされること

### すべてのURLを対象にした時の動作確認(警告ダイアログ無)
##### ERR_CACHE_MISSページを自動で閉じるケース

* `powershell doc\verify\sources\TestTools\http_server.ps1`でローカルのWebサーバーを起動する
* `http://localhost:8080`で簡易Webサーバーが起動する
* `doc\verify\sources\TestTools\form.html` を開く
* 「フォームをダイアログで開くボタン」を押す
* ポップアップダイアログが開く
* フォームに「test」と入力して、「送信」ボタンを押す
* 遷移先の http://localhost:8080 で右クリックし、「戻る」を押す
* 遷移先の 「form.html」 で右クリックし、「進む」を押す
* [ ] ポップアップダイアログが閉じること

### すべてのURLを対象にした時の動作確認(警告ダイアログ有)

#### 準備

Expand All @@ -55,8 +69,10 @@

#### 検証

* https://www.google.com/ を開く
* すべてのURLを対象としている場合も、http/httpsのサイトを開いていないとアドインが動作しないため
##### ダイアログを自動でキャンセルするケース

* `powershell doc\verify\sources\TestTools\http_server.ps1`でローカルのWebサーバーを起動する
* `http://localhost:8080`で簡易Webサーバーが起動する
* `doc\verify\sources\TestTools\form.html` を開く
* フォームに「test」と入力して、「送信」ボタンを押す
* 「form.html」 をリロードする
Expand All @@ -72,11 +88,25 @@
* [ ] 警告ダイアログが前面に表示されること(Edgeの後ろに隠れないこと)
* すべての警告ダイアログをOKで閉じる

### 特定のURLを対象にした時の動作確認(警告ダイアログ無)
##### ERR_CACHE_MISSページを自動で閉じるケース

* `powershell doc\verify\sources\TestTools\http_server.ps1`でローカルのWebサーバーを起動する
* `http://localhost:8080`で簡易Webサーバーが起動する
* `doc\verify\sources\TestTools\form.html` を開く
* 「フォームをダイアログで開くボタン」を押す
* ポップアップダイアログが開く
* フォームに「test」と入力して、「送信」ボタンを押す
* 遷移先の http://localhost:8080 で右クリックし、「戻る」を押す
* 遷移先の 「form.html」 で右クリックし、「進む」を押す
* [ ] 「フォームの再送信が発生するため、このサイトでのリロードは禁止されています。\n\nリロードはキャンセルされました。」という警告ダイアログが表示**されない**こと
* このケースは非サポート。警告を出しているネイティブアプリ側ではなく、拡張機能側が閉じていることと、そもそもキャンセルされているので。
* [ ] ポップアップダイアログが閉じること

### ダイアログを閉じる機能で特定のURLを対象にした時の動作確認(警告ダイアログ無)

#### 補足

本アドオンは、現在のタブが指定したURLを開いていなくても、いずれかのタブで指定したURLが開いている場合に動作する。
本アドオンのダイアログを自動でキャンセルする機能は、現在のタブが指定したURLを開いていなくても、いずれかのタブで指定したURLが開いている場合に動作する。
これは、ネイティブアプリ側で現在開いているタブを判定するのが難しいためである。

#### 準備
Expand All @@ -95,6 +125,10 @@

#### 検証

##### ダイアログを自動でキャンセルするケース

* `powershell doc\verify\sources\TestTools\http_server.ps1`でローカルのWebサーバーを起動する
* `http://localhost:8080`で簡易Webサーバーが起動する
* `https://example.com/jp/exclude` を開く
* `doc\verify\sources\TestTools\form.html` を開く
* フォームに「test」と入力して、「送信」ボタンを押す
Expand Down Expand Up @@ -123,4 +157,64 @@
* `doc\verify\sources\TestTools\form.html` を開く
* フォームに「test」と入力して、「送信」ボタンを押す
* 「form.html」 をリロードする
* [ ] 「フォームを再送信しますか?」ダイアログ一瞬表示され、キャンセルされること
* [ ] 「フォームを再送信しますか?」ダイアログ一瞬表示され、キャンセルされること

### ERR_CACHE_MISSページを閉じる機能で特定のURLを対象にした時の動作確認

#### 補足

ERR_CACHE_MISSページを閉じる機能は指定したURLでのみ動作する。

#### 対象のページではない場合

##### 準備

以下の通り設定して検証を行う。

* [doc\verify\sources\TestTools/Scenarios/scenario3.ini](../TestTools/Scenarios/scenario3.ini) を `C:\Program Files\RepostConfirmationCanceler\RepostConfirmationCanceler.ini` に配置する。
* 設定の内容は以下の通り
* 以下のサイトを対象とする
* `*://example.com/jp*`
* `*://example.com/us/??/`
* `https://www.clear-code.com/`
* 以下のサイトを除外する
* `*://example.com/jp/exclude*`
* 念のためEdgeを再起動する

##### 検証

* `powershell doc\verify\sources\TestTools\http_server.ps1`でローカルのWebサーバーを起動する
* `http://localhost:8080`で簡易Webサーバーが起動する
* `doc\verify\sources\TestTools\form.html` を開く
* 「フォームをダイアログで開くボタン」を押す
* ポップアップダイアログが開く
* フォームに「test」と入力して、「送信」ボタンを押す
* 遷移先の http://localhost:8080 で右クリックし、「戻る」を押す
* 遷移先の 「form.html」 で右クリックし、「進む」を押す
* [ ] ERR_CACHE_MISS(フォームの再送信しますか?)エラーページが表示されること

#### 対象のページの場合

##### 準備

以下の通り設定して検証を行う。

* [doc\verify\sources\TestTools/Scenarios/scenario4.ini](../TestTools/Scenarios/scenario4.ini) を `C:\Program Files\RepostConfirmationCanceler\RepostConfirmationCanceler.ini` に配置する。
* 設定の内容は以下の通り
* 以下のサイトを対象とする
* `*://localhost:8080*`
* 念のためEdgeを再起動する

補足: マッチング処理の実装はダイアログキャンセルと同様であるため、ここでは詳しいマッチング処理の判定まではテストしない。

##### 検証

* `powershell doc\verify\sources\TestTools\http_server.ps1`でローカルのWebサーバーを起動する
* `http://localhost:8080`で簡易Webサーバーが起動する
* `doc\verify\sources\TestTools\form.html` を開く
* 「フォームをダイアログで開くボタン」を押す
* ポップアップダイアログが開く
* フォームに「test」と入力して、「送信」ボタンを押す
* 遷移先の http://localhost:8080 で右クリックし、「戻る」を押す
* 遷移先の 「form.html」 で右クリックし、「進む」を押す
* [ ] ダイアログが閉じること
2 changes: 2 additions & 0 deletions doc/verify/sources/TestTools/Senarios/scenario4.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[TARGETS]
*://localhost:8080*
14 changes: 12 additions & 2 deletions doc/verify/sources/TestTools/form.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,20 @@
<body>
<h1>フォーム再送信サンプル</h1>
<p>送信ボタンを押下後、リロードすると「フォームを再送信しますか?」ダイアログが表示されます。</p>
<form method="POST">
<p>送信ボタンを押下後、ブラウザの「戻る」「進む」を実行すると、「フォームを再送信しますか?」(ERR_CACHE_MISS)エラーページが表示されます。</p>
<form method="POST" action="http://localhost:8080">
<label>名前: <input type="text" name="name"></label>
<button type="submit">送信</button>
</form>
<p>本フォームは自分自身にデータ送信するため、外部にはデータ送信はしません。</p>
<p>本フォームは外部にはデータ送信しません。</p>
<button id="openFormBtn">フォームをダイアログで開く</button>

<script>
document.getElementById('openFormBtn').addEventListener('click', function() {
window.open('form.html',
'formWindow',
'width=500,height=400,resizable=yes,scrollbars=yes'
);});
</script>
</body>
</html>
37 changes: 37 additions & 0 deletions doc/verify/sources/TestTools/http_server.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
Add-Type -AssemblyName System.Net

$listener = New-Object System.Net.HttpListener
$listener.Prefixes.Add("http://localhost:8080/")
$listener.Start()
Write-Host "HTTP server running: http://localhost:8080/"

while ($listener.IsListening) {
try {
$context = $listener.GetContext()
$response = $context.Response
$request = $context.Request

# Disable cache in order to cause ERR_CACHE_MISS
$response.Headers.Add("Cache-Control", "no-store, no-cache, must-revalidate")
$response.Headers.Add("Pragma", "no-cache")
$response.ContentType = "text/html"

$html = @"
<!DOCTYPE html>
<html>
<head><title>PowerShell HTTP Server</title></head>
<body>
<h1>No cached page</h1>
<p>This page is not cached</p>
</body>
</html>
"@

$buffer = [System.Text.Encoding]::UTF8.GetBytes($html)
$response.ContentLength64 = $buffer.Length
$response.OutputStream.Write($buffer, 0, $buffer.Length)
$response.OutputStream.Close()
} catch {
Write-Warning "Error: $_"
}
}
54 changes: 42 additions & 12 deletions webextensions/edge/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ function wildcardToRegexp(source) {
* ]
* }
*/
const RepostConfirmationCancelerTalkClient = {
const RepostConfirmationCanceler = {
Copy link
Contributor Author

@HashidaTKS HashidaTKS Aug 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

このオブジェクトの中にERR_CACHE_MISSのページだったらタブを閉じる、という処理を追加した。
そのため単なるTalkClientではなくなったのでリネームした。

cached: null,

init() {
this.cached = null;
this.ensureLoadedAndConfigured();
console.log('Running as RepostConfirmationCancelerTalkClient Talk client');
console.log('Running RepostConfirmationCanceler');
},

async ensureLoadedAndConfigured() {
Expand Down Expand Up @@ -114,7 +114,7 @@ const RepostConfirmationCancelerTalkClient = {
return false;
},

handleURL(config, url){
handleURL(config, url, callbackWhenMatch){
if (!url) {
console.log(`* Empty URL found`);
return false;
Expand All @@ -135,7 +135,7 @@ const RepostConfirmationCancelerTalkClient = {
console.log(`handleURL: check for section ${section.Name} (${JSON.stringify(section)})`);
if (this.match(section, urlToMatch)) {
console.log(` => unmatched`);
this.startMonitoring();
callbackWhenMatch();
Copy link
Contributor Author

@HashidaTKS HashidaTKS Aug 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

今回の機能追加で、このメソッドを流用したい。ただ、今回追加した部分と従来の部分でマッチした場合にさせたい動作が異なる。

  • ERR_CACHE_MISSページのURLが合致していた場合はタブを閉じたい。
  • それ以外の場合は、RepostConfirmationCanceler.exeを起動したい。

マッチ時にさせたい動作が異なるので、コールバック化して外部から渡せるようにした。

return true;
}
else {
Expand All @@ -153,7 +153,7 @@ const RepostConfirmationCancelerTalkClient = {
for (const tab of tabs) {
const url = tab.url ?? tab.pendingUrl;
console.log(`handleAllTabs ${url} (tab=${tab.id})`);
if(this.handleURL(config, url)){
if(this.handleURL(config, url, this.startMonitoring)){
break;
}
};
Expand All @@ -169,15 +169,40 @@ const RepostConfirmationCancelerTalkClient = {

const config = this.cached;
const url = tab.pendingUrl || tab.url;
this.handleURL(config, url);
this.handleURL(config, url, this.startMonitoring);
},

onNavigationCommitted(details) {
const url = details.url;
console.log(`onNavigationCommitted: ${url}`);
const config = this.cached;
this.handleURL(config, url);
this.handleURL(config, url, this.startMonitoring);
},

onErrorOccurred(details) {
console.log('onErrorOccurred:', details);
if (details.error === 'net::ERR_CACHE_MISS') {
const url = details.url;
const tabId = details.tabId;
const config = this.cached;
this.handleURL(config, url, () => {
this.closeTab(tabId);
});
}
},

closeTab(tabId) {
if (tabId !== -1) {
console.log("Closing tab:", tabId);
chrome.tabs.remove(tabId, () => {
if (chrome.runtime.lastError) {
console.log("Error while closing tab:", chrome.runtime.lastError.message)
} else {
console.log("Tab closed");
}
});
}
}
};

/* Refresh config for every N minute */
Expand All @@ -186,14 +211,19 @@ chrome.alarms.create('poll-config', {'periodInMinutes': ALARM_MINUTES});

chrome.alarms.onAlarm.addListener((alarm) => {
if (alarm.name === 'poll-config') {
RepostConfirmationCancelerTalkClient.configure();
RepostConfirmationCancelerTalkClient.handleAllTabs();
RepostConfirmationCanceler.configure();
RepostConfirmationCanceler.handleAllTabs();
//handleURL for all url in tabs.
}
});

chrome.webRequest.onErrorOccurred.addListener(
RepostConfirmationCanceler.onErrorOccurred.bind(RepostConfirmationCanceler),
{urls: ["<all_urls>"]}
);

/* Tab book-keeping for intelligent tab handlings */
chrome.tabs.onUpdated.addListener(RepostConfirmationCancelerTalkClient.onTabUpdated.bind(RepostConfirmationCancelerTalkClient));
chrome.webNavigation.onCommitted.addListener(RepostConfirmationCancelerTalkClient.onNavigationCommitted.bind(RepostConfirmationCancelerTalkClient));
chrome.tabs.onUpdated.addListener(RepostConfirmationCanceler.onTabUpdated.bind(RepostConfirmationCanceler));
chrome.webNavigation.onCommitted.addListener(RepostConfirmationCanceler.onNavigationCommitted.bind(RepostConfirmationCanceler));

RepostConfirmationCancelerTalkClient.init();
RepostConfirmationCanceler.init();
3 changes: 2 additions & 1 deletion webextensions/edge/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"nativeMessaging",
"alarms",
"tabs",
"webNavigation"
"webNavigation",
"webRequest"
],
"host_permissions": [
"<all_urls>"
Expand Down
Loading