web-view の login form test
html から 文字を入力し rust に渡すだけのプログラム
html 側のデータは javascript側から JSONで rustに送る
rust からは webview.evalで javascript側に データを送る
ただ bindingするだけなら swiftや Kotlinのほうが楽ちん
IntelliJの tabnineが強力すぎる...
cargo.toml
[package] name = "testlogin" version = "0.1.0" edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] web-view = { version = "0.7" } serde = { version = "1.0", features = ["derive"] } serde_json="1.0" regex="1"
lib.js
var Login = {}; Login.doLogin = function doLogin(loginForm) { if(loginForm.username.value == '') { return Login.doError('ユーザー名を入力してください。'); } if(loginForm.password.value == '') { return Login.doError('パスワードを入力してください。'); } var ans_data = { login: loginForm.username.value, password: loginForm.password.value }; external.invoke( JSON.stringify(ans_data)); return false; } Login.doError = function doError(msg) { document.getElementById('display').innerHTML = msg; return false; }
main.rs
use regex::Regex; use serde::{Deserialize, Serialize}; use web_view::*; //参考:https://zenn.dev/yukit/articles/02a02ef025feff //jsonを色々考えないでいい文字列に変換する pub fn json_to_encodestr(s: &str) -> String { let _quote = Regex::new("\"").unwrap(); _quote.replace_all(s, "&q;").to_string() } //色々考えないでいい文字列からjsonに戻す pub fn encodestr_to_json(s: &str) -> String { let _quote = Regex::new("&q;").unwrap(); _quote.replace_all(s, "\"").to_string() } #[derive(Serialize, Deserialize, Debug)] struct LoginForm { login: String, password: String, } fn main() { let html_content = std::format!( r#"<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <script> {} </script> </head> <body> <form id="loginform" action="" method="post" onsubmit="return Login.doLogin(this)"> <label>login: <input type="text" name="username" value="" /></label> <br /> <label>password: <input type="password" name="password" value="" /></label> <br /> <input type="submit" value="login" /> </form> <br /> <div id="display">not logged in</div> </body> </html>"#, include_str!("lib.js") ); // 動作確認; macOS 11.5(64bit arm/intel), Windows 10(64bit) Windows 7 (32bit), 起動不可; Windows 2000 let webview = web_view::builder() .title("Login Demo") .content(Content::Html(html_content)) .size(320, 240) .user_data(()) .invoke_handler(|_webview, arg| { let decode_arg = encodestr_to_json(arg); if let Ok(res) = serde_json::from_str(&decode_arg) as Result<LoginForm, _> { println!( "===> invoke_handler : login:{} pass:{}", res.login, res.password ); } Ok(()) }) .build() .unwrap(); webview.run().unwrap(); }