問題
Electronの webContents.executeJavascript は、stringでjavascriptコードを受け取る。
例えば IDとパスワードを渡してログインしたい と思った時にこれがちょっと工夫が必要だった。
結論
こんな関数を用意するだけでいけた!
const wrap = (fn, ...args) => `(${fn.toString()})(${args.map( arg => `"${arg}"` ).join(',')})`
使い方はこんな具合
const webview = document.querySelector("#browser")
// webviewで実行したい関数
const input = (name, pass) => {
document.querySelector("#username").value = name
document.querySelector("#password").value = pass
document.querySelector("#login").click()
}
// wrap!
const scr = wrap(input, "my-name", "my-password")
webview.addEventListener('did-finish-load', (e) => {
// execute!
webview.executeJavaScript(scr, () => {
....
})
}
解説など
ワンライナーって言いたかっただけの理由で一行で書いてみたが、わかりやすく書くとこんな感じになる。
const wrap = (fn, ...args) => {
const callArgs = args.map( arg => `"${arg}"` ).join(',')
const functionString = fn.toString()
return `(${functionString})(${callArgs})`
}
wrapで作られたscr
の変数はこんな感じになっている。
((name, pass) => {
document.querySelector("#username").value = name
document.querySelector("#password").value = pass
document.querySelector("#login").click()
})("my-name", "my-password")
-
(function(){})()
みたいな即時関数で囲む -
Function.toString()
で関数の文字列を取り出している - ES2015構文大活躍
-
...args
でその後の引数をquoteで囲んで、即時関数の引数にしている。- spread演算子で受け取っているのはわりと好み。別に第二引数を配列にしてても良かったとは思う。
- templateリテラリ大活躍
-
下記あたりを参考に思いついた