Auto merge of #22224 - pyfisch:composition-webdriver, r=nox

Forward WebDriver CompositionEvent

Dispatch composition events in JS.
Insert characters from composition events to text input.

CompositionEvents currently can only be
created by WebDriver and not by embedders.

<!-- Please describe your changes on the following line: -->

---
<!-- 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 test-tidy` does not report any errors
- [ ] These changes fix #__ (github issue number if applicable).

<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____

<!-- 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/22224)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2018-11-20 03:32:25 -05:00 committed by GitHub
commit 98527ddb8c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 118 additions and 26 deletions

View file

@ -59,6 +59,10 @@ impl CompositionEvent {
);
Ok(event)
}
pub fn data(&self) -> &str {
&*self.data
}
}
impl CompositionEventMethods for CompositionEvent {

View file

@ -38,6 +38,7 @@ use crate::dom::bindings::xmlname::{
};
use crate::dom::closeevent::CloseEvent;
use crate::dom::comment::Comment;
use crate::dom::compositionevent::CompositionEvent;
use crate::dom::cssstylesheet::CSSStyleSheet;
use crate::dom::customelementregistry::CustomElementDefinition;
use crate::dom::customevent::CustomEvent;
@ -1465,6 +1466,37 @@ impl Document {
self.window.reflow(ReflowGoal::Full, ReflowReason::KeyEvent);
}
pub fn dispatch_composition_event(
&self,
composition_event: ::keyboard_types::CompositionEvent,
) {
// spec: https://w3c.github.io/uievents/#compositionstart
// spec: https://w3c.github.io/uievents/#compositionupdate
// spec: https://w3c.github.io/uievents/#compositionend
// > Event.target : focused element processing the composition
let focused = self.get_focused_element();
let target = if let Some(elem) = &focused {
elem.upcast()
} else {
// Event is only dispatched if there is a focused element.
return;
};
let cancelable = composition_event.state == keyboard_types::CompositionState::Start;
let compositionevent = CompositionEvent::new(
&self.window,
DOMString::from(composition_event.state.to_string()),
true,
cancelable,
Some(&self.window),
0,
DOMString::from(composition_event.data),
);
let event = compositionevent.upcast::<Event>();
event.fire(target);
}
// https://dom.spec.whatwg.org/#converting-nodes-into-a-node
pub fn node_from_nodes_and_strings(
&self,

View file

@ -17,6 +17,7 @@ use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::DomObject;
use crate::dom::bindings::root::{Dom, DomRoot, LayoutDom, MutNullableDom, RootedReference};
use crate::dom::bindings::str::DOMString;
use crate::dom::compositionevent::CompositionEvent;
use crate::dom::document::Document;
use crate::dom::element::{
AttributeMutation, Element, LayoutElementHelpers, RawLayoutElementHelpers,
@ -1526,6 +1527,23 @@ impl VirtualMethods for HTMLInputElement {
&window,
);
}
} else if (event.type_() == atom!("compositionstart") ||
event.type_() == atom!("compositionupdate") ||
event.type_() == atom!("compositionend")) &&
self.input_type().is_textual_or_password()
{
// TODO: Update DOM on start and continue
// and generally do proper CompositionEvent handling.
if let Some(compositionevent) = event.downcast::<CompositionEvent>() {
if event.type_() == atom!("compositionend") {
let _ = self
.textinput
.borrow_mut()
.handle_compositionend(compositionevent);
self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
}
event.mark_as_handled();
}
}
}
}

View file

@ -13,6 +13,7 @@ use crate::dom::bindings::error::ErrorResult;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::root::{DomRoot, LayoutDom, MutNullableDom};
use crate::dom::bindings::str::DOMString;
use crate::dom::compositionevent::CompositionEvent;
use crate::dom::document::Document;
use crate::dom::element::RawLayoutElementHelpers;
use crate::dom::element::{AttributeMutation, Element};
@ -576,6 +577,22 @@ impl VirtualMethods for HTMLTextAreaElement {
&window,
);
}
} else if event.type_() == atom!("compositionstart") ||
event.type_() == atom!("compositionupdate") ||
event.type_() == atom!("compositionend")
{
// TODO: Update DOM on start and continue
// and generally do proper CompositionEvent handling.
if let Some(compositionevent) = event.downcast::<CompositionEvent>() {
if event.type_() == atom!("compositionend") {
let _ = self
.textinput
.borrow_mut()
.handle_compositionend(compositionevent);
self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
}
event.mark_as_handled();
}
}
}