diff options
-rw-r--r-- | components/compositing/compositor_thread.rs | 8 | ||||
-rw-r--r-- | components/constellation/constellation.rs | 8 | ||||
-rw-r--r-- | components/msg/constellation_msg.rs | 20 | ||||
-rw-r--r-- | components/script/dom/document.rs | 10 | ||||
-rw-r--r-- | components/script/dom/element.rs | 17 | ||||
-rwxr-xr-x | components/script/dom/htmlinputelement.rs | 20 | ||||
-rw-r--r-- | components/script_traits/script_msg.rs | 6 | ||||
-rw-r--r-- | ports/servo/browser.rs | 6 |
8 files changed, 93 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, } diff --git a/ports/servo/browser.rs b/ports/servo/browser.rs index 92422388e22..38d61b8d334 100644 --- a/ports/servo/browser.rs +++ b/ports/servo/browser.rs @@ -295,6 +295,12 @@ impl Browser { EmbedderMsg::GetSelectedBluetoothDevice(devices, sender) => { platform_get_selected_devices(devices, sender); } + EmbedderMsg::ShowIME(_browser_id, _kind) => { + debug!("ShowIME received"); + } + EmbedderMsg::HideIME(_browser_id) => { + debug!("HideIME received"); + } } } } |