From 2ad8fd6f43f9465e495cabb3bee75defa7e078f5 Mon Sep 17 00:00:00 2001
From: Koichi Akabe
Date: Sat, 13 Jul 2024 21:03:16 +0900
Subject: [PATCH 1/6] Support query string Wasm example
---
examples/wasm/Cargo.toml | 22 +++++++++++-----------
examples/wasm/src/lib.rs | 24 ++++++++++++++++++------
vaporetto/src/dict_model.rs | 1 +
3 files changed, 30 insertions(+), 17 deletions(-)
diff --git a/examples/wasm/Cargo.toml b/examples/wasm/Cargo.toml
index b4bea139..067bccb8 100644
--- a/examples/wasm/Cargo.toml
+++ b/examples/wasm/Cargo.toml
@@ -4,20 +4,20 @@ version = "0.1.0"
edition = "2021"
[dependencies]
-gloo-worker = "0.2.1" # MIT or Apache-2.0
-i18n-embed = { version = "0.13.8", features = ["fluent-system", "web-sys-requester"]} # MIT
-i18n-embed-fl = "0.6.5" # MIT
-once_cell = "1.17.0" # MIT or Apache-2.0
-ouroboros = "0.17.2" # MIT or Apache-2.0
-rust-embed = "6.4.2" # MIT
-ruzstd = "0.5.0" # MIT
+gloo-worker = "0.5.0" # MIT or Apache-2.0
+i18n-embed = { version = "0.14.1", features = ["fluent-system", "web-sys-requester"]} # MIT
+i18n-embed-fl = "0.8.0" # MIT
+once_cell = "1.19.0" # MIT or Apache-2.0
+ouroboros = "0.18.4" # MIT or Apache-2.0
+rust-embed = "8.5.0" # MIT
+ruzstd = "0.7.0" # MIT
serde = "1" # MIT or Apache-2.0
-unic-langid = { version = "0.9.1", features = ["macros"] } # MIT or Apache-2.0
+unic-langid = { version = "0.9.5", features = ["macros"] } # MIT or Apache-2.0
vaporetto = { path = "../../vaporetto", default-features = false, features = ["std", "cache-type-score", "fix-weight-length", "tag-prediction"] } # MIT or Apache-2.0
vaporetto_rules = { path = "../../vaporetto_rules" } # MIT or Apache-2.0
-wasm-bindgen = "0.2.83" # MIT or Apache-2.0
-web-sys = { version = "0.3.61", features = ["Event", "EventTarget", "InputEvent"] } # MIT or Apache-2.0
-yew = { version = "0.20", features = ["csr"] } # MIT or Apache-2.0
+wasm-bindgen = "0.2.92" # MIT or Apache-2.0
+web-sys = { version = "0.3.69", features = ["Event", "EventTarget", "InputEvent"] } # MIT or Apache-2.0
+yew = { version = "0.21", features = ["csr"] } # MIT or Apache-2.0
[profile.release]
panic = "abort"
diff --git a/examples/wasm/src/lib.rs b/examples/wasm/src/lib.rs
index 7cece264..f7ca8654 100644
--- a/examples/wasm/src/lib.rs
+++ b/examples/wasm/src/lib.rs
@@ -3,6 +3,7 @@ pub mod i18n;
pub mod text_input;
pub mod token_view;
+use std::borrow::Cow;
use std::io::Read;
use std::rc::Rc;
@@ -14,6 +15,7 @@ use vaporetto_rules::{
string_filters::KyteaFullwidthFilter,
SentenceFilter, StringFilter,
};
+use web_sys::UrlSearchParams;
use yew::{html, Component, Context, Html};
use crate::text_input::TextInput;
@@ -97,10 +99,14 @@ impl Worker for VaporettoWorker {
.boundaries_mut()
.copy_from_slice(fields.sentence_filtered.boundaries());
fields.sentence_orig.reset_tags(n_tags);
- fields
+ for (d, s) in fields
.sentence_orig
.tags_mut()
- .clone_from_slice(fields.sentence_filtered.tags());
+ .iter_mut()
+ .zip(fields.sentence_filtered.tags())
+ {
+ *d = s.as_ref().map(|x| Cow::Owned(x.to_string()));
+ }
});
let tokens = self
@@ -150,13 +156,19 @@ impl Component for App {
})
.spawn("./vaporetto_worker.js");
- // Sends a dummy message.
- // The first response indicates that the worker is ready.
- bridge.send(String::new());
+ let text = web_sys::window()
+ .unwrap()
+ .location()
+ .search()
+ .ok()
+ .and_then(|s| UrlSearchParams::new_with_str(&s).ok())
+ .and_then(|q| q.get("text"))
+ .unwrap_or_else(String::new);
+ bridge.send(text.clone());
Self {
bridge,
- text: String::new().into(),
+ text: text.into(),
tokens: None,
n_tags: 0,
}
diff --git a/vaporetto/src/dict_model.rs b/vaporetto/src/dict_model.rs
index 23b43a21..9c81be03 100644
--- a/vaporetto/src/dict_model.rs
+++ b/vaporetto/src/dict_model.rs
@@ -5,6 +5,7 @@ use bincode::{Decode, Encode};
use crate::errors::{Result, VaporettoError};
+#[cfg(feature = "kytea")]
#[derive(Clone, Copy, Default)]
pub struct DictWeight {
pub right: i32,
From 46923bb9464a820b38c962f02a59d7d72d649c21 Mon Sep 17 00:00:00 2001
From: Koichi Akabe
Date: Sun, 14 Jul 2024 00:11:10 +0900
Subject: [PATCH 2/6] Add copy link button
---
examples/wasm/Cargo.toml | 5 +-
examples/wasm/index.html | 25 +++++++++
examples/wasm/src/lib.rs | 22 +++-----
examples/wasm/src/text_input.rs | 94 ++++++++++++++++++++++++++-------
4 files changed, 110 insertions(+), 36 deletions(-)
diff --git a/examples/wasm/Cargo.toml b/examples/wasm/Cargo.toml
index 067bccb8..3156717f 100644
--- a/examples/wasm/Cargo.toml
+++ b/examples/wasm/Cargo.toml
@@ -4,9 +4,11 @@ version = "0.1.0"
edition = "2021"
[dependencies]
+gloo-timers = "0.3.0" # MIT or Apache-2.0
gloo-worker = "0.5.0" # MIT or Apache-2.0
i18n-embed = { version = "0.14.1", features = ["fluent-system", "web-sys-requester"]} # MIT
i18n-embed-fl = "0.8.0" # MIT
+js-sys = "0.3.69" # MIT or Apache-2.0
once_cell = "1.19.0" # MIT or Apache-2.0
ouroboros = "0.18.4" # MIT or Apache-2.0
rust-embed = "8.5.0" # MIT
@@ -16,7 +18,8 @@ unic-langid = { version = "0.9.5", features = ["macros"] } # MIT or Apache-2.0
vaporetto = { path = "../../vaporetto", default-features = false, features = ["std", "cache-type-score", "fix-weight-length", "tag-prediction"] } # MIT or Apache-2.0
vaporetto_rules = { path = "../../vaporetto_rules" } # MIT or Apache-2.0
wasm-bindgen = "0.2.92" # MIT or Apache-2.0
-web-sys = { version = "0.3.69", features = ["Event", "EventTarget", "InputEvent"] } # MIT or Apache-2.0
+wasm-bindgen-futures = "0.4.42" # MIT or Apache-2.0
+web-sys = { version = "0.3.69", features = ["Clipboard", "Event", "EventTarget", "InputEvent"] } # MIT or Apache-2.0
yew = { version = "0.21", features = ["csr"] } # MIT or Apache-2.0
[profile.release]
diff --git a/examples/wasm/index.html b/examples/wasm/index.html
index cf73ed40..9ca034e6 100644
--- a/examples/wasm/index.html
+++ b/examples/wasm/index.html
@@ -29,6 +29,11 @@
color: #fff;
}
+html {
+ max-width: 1000px;
+ margin: 0 auto;
+}
+
body {
width: calc(100% - 20px);
margin: 10px;
@@ -39,6 +44,26 @@
text-align: right;
}
+.input-bar {
+ display: flex;
+ flex-direction: row;
+}
+
+.input-bar button {
+ font-size: 14pt;
+ align-self: center;
+ background-color: #ffffff;
+ border: 1px solid #000000;
+}
+
+.input-bar button:hover {
+ background-color: #dddddd;
+}
+
+.input-bar button.copied {
+ background-color: #008800;
+}
+
a {
color: #000;
}
diff --git a/examples/wasm/src/lib.rs b/examples/wasm/src/lib.rs
index f7ca8654..5982da45 100644
--- a/examples/wasm/src/lib.rs
+++ b/examples/wasm/src/lib.rs
@@ -198,22 +198,14 @@ impl Component for App {
-
- {
- if self.tokens.is_some() {
- html! {
-
- }
- } else {
- html!{
-
- }
- }
+ {
+ html! {
+
}
-
+ }
{
if let Some(tokens) = &self.tokens {
html! {
diff --git a/examples/wasm/src/text_input.rs b/examples/wasm/src/text_input.rs
index abbf546a..37f324a5 100644
--- a/examples/wasm/src/text_input.rs
+++ b/examples/wasm/src/text_input.rs
@@ -1,19 +1,21 @@
use std::rc::Rc;
-use wasm_bindgen::{JsCast, UnwrapThrowExt};
-use web_sys::{Event, HtmlInputElement, InputEvent};
-use yew::{html, Callback, Component, Context, Html, NodeRef, Properties};
+use gloo_timers::callback::Timeout;
+use wasm_bindgen_futures::JsFuture;
+use web_sys::HtmlInputElement;
+use yew::{html, platform::spawn_local, Callback, Component, Context, Html, NodeRef, Properties};
use crate::fl;
#[derive(Clone, PartialEq, Properties)]
pub struct Props {
- pub value: Rc,
+ pub value: Option>,
pub callback: Callback,
}
pub struct TextInput {
- node_ref: NodeRef,
+ input_ref: NodeRef,
+ button_ref: NodeRef,
}
impl Component for TextInput {
@@ -22,7 +24,8 @@ impl Component for TextInput {
fn create(_ctx: &Context) -> Self {
Self {
- node_ref: NodeRef::default(),
+ input_ref: NodeRef::default(),
+ button_ref: NodeRef::default(),
}
}
@@ -30,21 +33,72 @@ impl Component for TextInput {
let Props { value, callback } = ctx.props();
let callback = callback.clone();
- let oninput = Callback::from(move |e: InputEvent| {
- let event: Event = e.dyn_into().unwrap_throw();
- let event_target = event.target().unwrap_throw();
- let target: HtmlInputElement = event_target.dyn_into().unwrap_throw();
- callback.emit(target.value());
+ let input_ref = self.input_ref.clone();
+ let oninput = Callback::from(move |_| {
+ let input = input_ref.cast::().unwrap();
+ callback.emit(input.value());
});
- html! {
-
+ let input_ref = self.input_ref.clone();
+ let button_ref = self.button_ref.clone();
+ let clipboard_click = Callback::from(move |_| {
+ let input = input_ref.cast::().unwrap();
+ if let Some(clipboard) = web_sys::window().unwrap().navigator().clipboard() {
+ let loc = web_sys::window().unwrap().location();
+ let content = format!(
+ "{}{}?text={}",
+ loc.origin().unwrap(),
+ loc.pathname().unwrap(),
+ js_sys::encode_uri_component(&input.value())
+ );
+ let promise = clipboard.write_text(&content);
+ let button_ref = button_ref.clone();
+ spawn_local(async move {
+ JsFuture::from(promise).await.unwrap();
+ let button = button_ref.cast::().unwrap();
+ button.set_class_name("copied");
+ let button_ref = button_ref.clone();
+ let timeout = Timeout::new(1000, move || {
+ let button = button_ref.cast::().unwrap();
+ button.set_class_name("");
+ });
+ timeout.forget();
+ });
+ }
+ });
+ if let Some(value) = value.as_ref() {
+ html! {
+
+
+
+
+ }
+ } else {
+ html! {
+
+
+
+
+ }
}
}
@@ -54,7 +108,7 @@ impl Component for TextInput {
fn rendered(&mut self, _ctx: &Context, first_render: bool) {
if first_render {
- if let Some(input) = self.node_ref.cast::() {
+ if let Some(input) = self.input_ref.cast::() {
input.focus().unwrap();
}
}
From b1a251203499d18ee1626e566cb23eddb7a4fd95 Mon Sep 17 00:00:00 2001
From: Koichi Akabe
Date: Sun, 14 Jul 2024 00:15:55 +0900
Subject: [PATCH 3/6] Add cargo settings
---
examples/wasm/.cargo/config.toml | 2 ++
1 file changed, 2 insertions(+)
create mode 100644 examples/wasm/.cargo/config.toml
diff --git a/examples/wasm/.cargo/config.toml b/examples/wasm/.cargo/config.toml
new file mode 100644
index 00000000..84671750
--- /dev/null
+++ b/examples/wasm/.cargo/config.toml
@@ -0,0 +1,2 @@
+[build]
+rustflags = ["--cfg=web_sys_unstable_apis"]
From 6577001b957d1ac82396e86ef72709ce2b96a7f3 Mon Sep 17 00:00:00 2001
From: Koichi Akabe
Date: Sun, 14 Jul 2024 13:38:59 +0900
Subject: [PATCH 4/6] Downgrade ouroboros to 0.17.2
---
examples/wasm/Cargo.toml | 2 +-
examples/wasm/src/lib.rs | 11 ++---------
2 files changed, 3 insertions(+), 10 deletions(-)
diff --git a/examples/wasm/Cargo.toml b/examples/wasm/Cargo.toml
index 3156717f..fc1e84e3 100644
--- a/examples/wasm/Cargo.toml
+++ b/examples/wasm/Cargo.toml
@@ -10,7 +10,7 @@ i18n-embed = { version = "0.14.1", features = ["fluent-system", "web-sys-request
i18n-embed-fl = "0.8.0" # MIT
js-sys = "0.3.69" # MIT or Apache-2.0
once_cell = "1.19.0" # MIT or Apache-2.0
-ouroboros = "0.18.4" # MIT or Apache-2.0
+ouroboros = "0.17.2" # MIT or Apache-2.0
rust-embed = "8.5.0" # MIT
ruzstd = "0.7.0" # MIT
serde = "1" # MIT or Apache-2.0
diff --git a/examples/wasm/src/lib.rs b/examples/wasm/src/lib.rs
index 5982da45..d7481d5c 100644
--- a/examples/wasm/src/lib.rs
+++ b/examples/wasm/src/lib.rs
@@ -3,7 +3,6 @@ pub mod i18n;
pub mod text_input;
pub mod token_view;
-use std::borrow::Cow;
use std::io::Read;
use std::rc::Rc;
@@ -93,20 +92,14 @@ impl Worker for VaporettoWorker {
fields.sentence_orig.update_raw(msg).unwrap();
- let n_tags = fields.sentence_filtered.n_tags();
fields
.sentence_orig
.boundaries_mut()
.copy_from_slice(fields.sentence_filtered.boundaries());
- fields.sentence_orig.reset_tags(n_tags);
- for (d, s) in fields
+ fields
.sentence_orig
.tags_mut()
- .iter_mut()
- .zip(fields.sentence_filtered.tags())
- {
- *d = s.as_ref().map(|x| Cow::Owned(x.to_string()));
- }
+ .clone_from_slice(fields.sentence_filtered.tags());
});
let tokens = self
From db5e45af903173779652fe24d8c9286af6e77c7a Mon Sep 17 00:00:00 2001
From: Koichi Akabe
Date: Sun, 14 Jul 2024 13:54:35 +0900
Subject: [PATCH 5/6] Upgrade ouroboros to 0.18.4 with changing variable order
---
examples/wasm/Cargo.toml | 2 +-
examples/wasm/src/lib.rs | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/examples/wasm/Cargo.toml b/examples/wasm/Cargo.toml
index fc1e84e3..3156717f 100644
--- a/examples/wasm/Cargo.toml
+++ b/examples/wasm/Cargo.toml
@@ -10,7 +10,7 @@ i18n-embed = { version = "0.14.1", features = ["fluent-system", "web-sys-request
i18n-embed-fl = "0.8.0" # MIT
js-sys = "0.3.69" # MIT or Apache-2.0
once_cell = "1.19.0" # MIT or Apache-2.0
-ouroboros = "0.17.2" # MIT or Apache-2.0
+ouroboros = "0.18.4" # MIT or Apache-2.0
rust-embed = "8.5.0" # MIT
ruzstd = "0.7.0" # MIT
serde = "1" # MIT or Apache-2.0
diff --git a/examples/wasm/src/lib.rs b/examples/wasm/src/lib.rs
index d7481d5c..458396f5 100644
--- a/examples/wasm/src/lib.rs
+++ b/examples/wasm/src/lib.rs
@@ -39,10 +39,10 @@ pub struct VaporettoWorker {
#[borrows(predictor)]
#[covariant]
- sentence_orig: Sentence<'static, 'this>,
+ sentence_filtered: Sentence<'static, 'this>,
#[borrows(predictor)]
#[covariant]
- sentence_filtered: Sentence<'static, 'this>,
+ sentence_orig: Sentence<'static, 'this>,
}
impl Worker for VaporettoWorker {
From f0ee242007a4f4d05ba8d7524ff1010a58ec4230 Mon Sep 17 00:00:00 2001
From: Koichi Akabe
Date: Sun, 14 Jul 2024 13:56:04 +0900
Subject: [PATCH 6/6] fix
---
examples/wasm/src/lib.rs | 2 ++
1 file changed, 2 insertions(+)
diff --git a/examples/wasm/src/lib.rs b/examples/wasm/src/lib.rs
index 458396f5..be6fbef7 100644
--- a/examples/wasm/src/lib.rs
+++ b/examples/wasm/src/lib.rs
@@ -92,10 +92,12 @@ impl Worker for VaporettoWorker {
fields.sentence_orig.update_raw(msg).unwrap();
+ let n_tags = fields.sentence_filtered.n_tags();
fields
.sentence_orig
.boundaries_mut()
.copy_from_slice(fields.sentence_filtered.boundaries());
+ fields.sentence_orig.reset_tags(n_tags);
fields
.sentence_orig
.tags_mut()