electron12対応へ、前回は
右クリックメニュー(ContextMenu)カスタム処理をmain-processへ移動した(electron 12対応)
まで。
nodeIntegrationはともかくmoduleは将来廃止になるとのこと。
npmパッケージで逃げることもできるが、まとめて移行することに。
つまりいろいろなものをrender-processからmain-processへ移動することになり、ContextBridgeの導入を避けることができない。
# electron11まで使えたdialog呼び出しコード
これまではrender-process側の適当なjsファイル内で完結する下記2行程度の記述で ダイアログを表示することができたのだが、ようはこれが使えなくなる。
``` js/mypage.js
const {dialog} = require("electron").remote;
dialog.showMessageBoxSync(null)
```
# contextIsolationを有効化
エラーメッセージによると、ContextBridgeを使うには、contextIsolationを有効化しなければならない
(electron12からデフォルトでtrue)
# ページ上のjsでdialogは呼べない(renderer-process)
ContextBridgeでmain-processへ飛ばしてそこからrequest('electron').dialogを呼ばなければならない。
```
MN@daisy-bell:lina_dicto/$ git diff lina_dicto/js/index.js }catch(err){
- message_dialog('error', 'user preference error', "user preference load error:\n" + err.message);
+ window.myApi.message_dialog('error', 'user preference error', "user preference load error:\n" + err.message);
}
}, false)
```
# preload.js内でdialogは呼べない
最初はpreload.js内でdialogを呼ぼうとしたのだが、なぜかrequire('electron')からcontextBridge, ipcRendererのようにdialogを取り出すことができない。
(preload.js内でcontextBridge, ipcRenderer以外が使えないということかもしれない。
後のContextBridgeのサンプルコードなども、見る限りpreload.js自体はrender-process側ということのように見えるし。)
# ContextBridgeでdialogを呼び出す
諸々の非同期を経由で呼び出しているが、 dialog.showMessageBoxSync()はウィンドウを渡せばウィンドウはモーダルに動作する(意図どおりブロックする)ように見える。
(まあとりあえずエラー通知にしか使ってないのでそこはどちらでもよしとする。 )
ページ上のjs -> preload.js上のcontextBridge -> main-processのjs と飛ばす。
``` js/index.js (renderer-process)
window.myApi.message_dialog('error', 'HELLO', 'hello!');
```
```preload.js
const { contextBridge, ipcRenderer, } = require("electron");
contextBridge.exposeInMainWorld(
"myApi", {
message_dialog: (strtype, strtitle, strmessage) => {
ipcRenderer.invoke('tomain-message-dialog', strtype, strtitle, strmessage);
```
``` index.js(main-process)
const { ipcMain } = require('electron');
ipcMain.handle('tomain-message-dialog', async (event, strtype, strtitle, strmessage) => {
const { dialog } = require('electron');
dialog.showMessageBoxSync(
// win, // ここmain-processで生成したwindowを指定できる
{
type: strtype,
buttons: ['OK'],
title: strtitle,
message: strmessage,
});
});
```
TODO: 確認ダイアログを出してOK,NGを同期で返す。
(現行の互換動作。あるいはこれは諦めてもいい。今は不要なので)
TODO: ファイル読み出し結果を戻す
TODO: ところでcontextIsolationが有効な時に nodeIntegration: trueが 無効になってない?