aboutsummaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2018-04-23 11:55:27 -0400
committerGitHub <noreply@github.com>2018-04-23 11:55:27 -0400
commitc5f7c9ccf33fac4bf2c1750e7040b76216fc912c (patch)
treef04f4b80566b6acea2323e9fceedbd2aab9a97b2 /components
parent05fe8fa08d507836ce5659ff56f83022a90b241a (diff)
parent42886613d32f2daff25f1f3ce7a7328bcc2306f7 (diff)
downloadservo-c5f7c9ccf33fac4bf2c1750e7040b76216fc912c.tar.gz
servo-c5f7c9ccf33fac4bf2c1750e7040b76216fc912c.zip
Auto merge of #20676 - fabricedesre:ime-embedding, r=cbrewster
Notify the embedder when it should display or hide an IME <!-- Please describe your changes on the following line: --> This adds a couple of embedder messages triggered when an editable element is focused or blured. The embedder also gets the type of data to edit so it can display a different keyboard type or a custom input method eg. for color choosing. This is a partial fix for issue #12127 --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach build-geckolib` does not report any errors - [X] `./mach test-tidy` does not report any errors - [ ] These changes fix #__ (github issue number if applicable). <!-- Either: --> - [ ] There are tests for these changes OR - [X] These changes do not require tests because there are no tests for the embedding api :( <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/20676) <!-- Reviewable:end -->
Diffstat (limited to 'components')
-rw-r--r--components/compositing/compositor_thread.rs8
-rw-r--r--components/constellation/constellation.rs8
-rw-r--r--components/msg/constellation_msg.rs20
-rw-r--r--components/script/dom/document.rs10
-rw-r--r--components/script/dom/element.rs17
-rwxr-xr-xcomponents/script/dom/htmlinputelement.rs20
-rw-r--r--components/script_traits/script_msg.rs6
7 files changed, 87 insertions, 2 deletions
diff --git a/components/compositing/compositor_thread.rs b/components/compositing/compositor_thread.rs
index 3d9a320c897..0b042ec5350 100644
--- a/components/compositing/compositor_thread.rs
+++ b/components/compositing/compositor_thread.rs
@@ -8,7 +8,7 @@ use SendableFrameTree;
use compositor::CompositingReason;
use gfx_traits::Epoch;
use ipc_channel::ipc::IpcSender;
-use msg::constellation_msg::{Key, KeyModifiers, KeyState, PipelineId, TopLevelBrowsingContextId};
+use msg::constellation_msg::{InputMethodType, Key, KeyModifiers, KeyState, PipelineId, TopLevelBrowsingContextId};
use net_traits::image::base::Image;
use profile_traits::mem;
use profile_traits::time;
@@ -143,6 +143,10 @@ pub enum EmbedderMsg {
Panic(TopLevelBrowsingContextId, String, Option<String>),
/// Open dialog to select bluetooth device.
GetSelectedBluetoothDevice(Vec<String>, IpcSender<Option<String>>),
+ /// Request to present an IME to the user when an editable element is focused.
+ ShowIME(TopLevelBrowsingContextId, InputMethodType),
+ /// Request to hide the IME when the editable element is blurred.
+ HideIME(TopLevelBrowsingContextId),
/// Servo has shut down
Shutdown,
}
@@ -244,6 +248,8 @@ impl Debug for EmbedderMsg {
EmbedderMsg::LoadComplete(..) => write!(f, "LoadComplete"),
EmbedderMsg::Panic(..) => write!(f, "Panic"),
EmbedderMsg::GetSelectedBluetoothDevice(..) => write!(f, "GetSelectedBluetoothDevice"),
+ EmbedderMsg::ShowIME(..) => write!(f, "ShowIME"),
+ EmbedderMsg::HideIME(..) => write!(f, "HideIME"),
EmbedderMsg::Shutdown => write!(f, "Shutdown"),
}
}
diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs
index 261ed6e265b..cea098f310c 100644
--- a/components/constellation/constellation.rs
+++ b/components/constellation/constellation.rs
@@ -1247,6 +1247,14 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
FromScriptMsg::SetFullscreenState(state) => {
self.embedder_proxy.send(EmbedderMsg::SetFullscreenState(source_top_ctx_id, state));
}
+ FromScriptMsg::ShowIME(kind) => {
+ debug!("constellation got ShowIME message");
+ self.embedder_proxy.send(EmbedderMsg::ShowIME(source_top_ctx_id, kind));
+ }
+ FromScriptMsg::HideIME => {
+ debug!("constellation got HideIME message");
+ self.embedder_proxy.send(EmbedderMsg::HideIME(source_top_ctx_id));
+ }
}
}
diff --git a/components/msg/constellation_msg.rs b/components/msg/constellation_msg.rs
index f7dab637298..1197341d308 100644
--- a/components/msg/constellation_msg.rs
+++ b/components/msg/constellation_msg.rs
@@ -401,3 +401,23 @@ pub const TEST_BROWSING_CONTEXT_INDEX: BrowsingContextIndex =
#[cfg(feature = "unstable")]
pub const TEST_BROWSING_CONTEXT_ID: BrowsingContextId =
BrowsingContextId { namespace_id: TEST_NAMESPACE, index: TEST_BROWSING_CONTEXT_INDEX };
+
+// Used to specify the kind of input method editor appropriate to edit a field.
+// This is a subset of htmlinputelement::InputType because some variants of InputType
+// don't make sense in this context.
+#[derive(Deserialize, Serialize)]
+pub enum InputMethodType {
+ Color,
+ Date,
+ DatetimeLocal,
+ Email,
+ Month,
+ Number,
+ Password,
+ Search,
+ Tel,
+ Text,
+ Time,
+ Url,
+ Week,
+}
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index 71df0e70356..5c9cd57b128 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -812,6 +812,11 @@ impl Document {
elem.set_focus_state(false);
// FIXME: pass appropriate relatedTarget
self.fire_focus_event(FocusEventType::Blur, node, None);
+
+ // Notify the embedder to hide the input method.
+ if elem.input_method_type().is_some() {
+ self.send_to_constellation(ScriptMsg::HideIME);
+ }
}
self.focused.set(self.possibly_focused.get().r());
@@ -826,6 +831,11 @@ impl Document {
if focus_type == FocusType::Element {
self.send_to_constellation(ScriptMsg::Focus);
}
+
+ // Notify the embedder to display an input method.
+ if let Some(kind) = elem.input_method_type() {
+ self.send_to_constellation(ScriptMsg::ShowIME(kind));
+ }
}
}
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs
index a53446fd4a3..11b9168eb41 100644
--- a/components/script/dom/element.rs
+++ b/components/script/dom/element.rs
@@ -83,6 +83,7 @@ use html5ever::serialize::TraversalScope;
use html5ever::serialize::TraversalScope::{ChildrenOnly, IncludeNode};
use js::jsapi::Heap;
use js::jsval::JSVal;
+use msg::constellation_msg::InputMethodType;
use net_traits::request::CorsSettings;
use ref_filter_map::ref_filter_map;
use script_layout_interface::message::ReflowGoal;
@@ -1087,6 +1088,22 @@ impl Element {
None
}
+ // Returns the kind of IME control needed for a focusable element, if any.
+ pub fn input_method_type(&self) -> Option<InputMethodType> {
+ if !self.is_focusable_area() {
+ return None;
+ }
+
+ if let Some(input) = self.downcast::<HTMLInputElement>() {
+ input.input_type().as_ime_type()
+ } else if self.is::<HTMLTextAreaElement>() {
+ Some(InputMethodType::Text)
+ } else {
+ // Other focusable elements that are not input fields.
+ None
+ }
+ }
+
pub fn is_focusable_area(&self) -> bool {
if self.is_actually_disabled() {
return false;
diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs
index 5618b366702..ab7d55d5b9a 100755
--- a/components/script/dom/htmlinputelement.rs
+++ b/components/script/dom/htmlinputelement.rs
@@ -40,6 +40,7 @@ use dom::virtualmethods::VirtualMethods;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use mime_guess;
+use msg::constellation_msg::InputMethodType;
use net_traits::{CoreResourceMsg, IpcSend};
use net_traits::blob_url_store::get_blob_origin;
use net_traits::filemanager_thread::{FileManagerThreadMsg, FilterPattern};
@@ -137,6 +138,25 @@ impl InputType {
InputType::Week => "week",
}
}
+
+ pub fn as_ime_type(&self) -> Option<InputMethodType> {
+ match *self {
+ InputType::Color => Some(InputMethodType::Color),
+ InputType::Date => Some(InputMethodType::Date),
+ InputType::DatetimeLocal => Some(InputMethodType::DatetimeLocal),
+ InputType::Email => Some(InputMethodType::Email),
+ InputType::Month => Some(InputMethodType::Month),
+ InputType::Number => Some(InputMethodType::Number),
+ InputType::Password => Some(InputMethodType::Password),
+ InputType::Search => Some(InputMethodType::Search),
+ InputType::Tel => Some(InputMethodType::Tel),
+ InputType::Text => Some(InputMethodType::Text),
+ InputType::Time => Some(InputMethodType::Time),
+ InputType::Url => Some(InputMethodType::Url),
+ InputType::Week => Some(InputMethodType::Week),
+ _ => None,
+ }
+ }
}
impl<'a> From<&'a Atom> for InputType {
diff --git a/components/script_traits/script_msg.rs b/components/script_traits/script_msg.rs
index 43812ad097a..d263753c7de 100644
--- a/components/script_traits/script_msg.rs
+++ b/components/script_traits/script_msg.rs
@@ -17,7 +17,7 @@ use euclid::{Size2D, TypedSize2D};
use gfx_traits::Epoch;
use ipc_channel::ipc::{IpcReceiver, IpcSender};
use msg::constellation_msg::{BrowsingContextId, HistoryStateId, PipelineId, TraversalDirection};
-use msg::constellation_msg::{Key, KeyModifiers, KeyState};
+use msg::constellation_msg::{InputMethodType, Key, KeyModifiers, KeyState};
use net_traits::CoreResourceMsg;
use net_traits::request::RequestInit;
use net_traits::storage_thread::StorageType;
@@ -163,6 +163,10 @@ pub enum ScriptMsg {
GetScreenSize(IpcSender<(DeviceUintSize)>),
/// Get the available screen size (pixel)
GetScreenAvailSize(IpcSender<(DeviceUintSize)>),
+ /// Request to present an IME to the user when an editable element is focused.
+ ShowIME(InputMethodType),
+ /// Request to hide the IME when the editable element is blurred.
+ HideIME,
/// Requests that the compositor shut down.
Exit,
}