Add single-line text input with no visible cursor.

This commit is contained in:
Josh Matthews 2014-10-06 11:51:44 -04:00
parent 84bc17e7ad
commit 80764f65e3
8 changed files with 776 additions and 63 deletions

View file

@ -26,7 +26,7 @@ use dom::document::{Document, DocumentHelpers, LayoutDocumentHelpers};
use dom::domtokenlist::DOMTokenList;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlcollection::HTMLCollection;
use dom::htmlinputelement::{HTMLInputElement, LayoutHTMLInputElementHelpers};
use dom::htmlinputelement::{HTMLInputElement, RawLayoutHTMLInputElementHelpers};
use dom::htmlserializer::serialize;
use dom::htmltablecellelement::{HTMLTableCellElement, HTMLTableCellElementHelpers};
use dom::node::{ElementNodeTypeId, Node, NodeHelpers, NodeIterator, document_from_node};
@ -231,17 +231,24 @@ pub trait RawLayoutElementHelpers {
-> Option<i32>;
}
#[inline]
#[allow(unrooted_must_root)]
unsafe fn get_attr_for_layout<'a>(elem: &'a Element, namespace: &Namespace, name: &Atom) -> Option<&'a JS<Attr>> {
// cast to point to T in RefCell<T> directly
let attrs: *const Vec<JS<Attr>> = mem::transmute(&elem.attrs);
(*attrs).iter().find(|attr: & &JS<Attr>| {
let attr = attr.unsafe_get();
*name == (*attr).local_name_atom_forever() &&
(*attr).namespace() == namespace
})
}
impl RawLayoutElementHelpers for Element {
#[inline]
#[allow(unrooted_must_root)]
unsafe fn get_attr_val_for_layout<'a>(&'a self, namespace: &Namespace, name: &Atom)
-> Option<&'a str> {
let attrs = self.attrs.borrow_for_layout();
(*attrs).iter().find(|attr: & &JS<Attr>| {
let attr = attr.unsafe_get();
*name == (*attr).local_name_atom_forever() &&
(*attr).namespace() == namespace
}).map(|attr| {
get_attr_for_layout(self, namespace, name).map(|attr| {
let attr = attr.unsafe_get();
(*attr).value_ref_forever()
})
@ -337,6 +344,7 @@ impl RawLayoutElementHelpers for Element {
pub trait LayoutElementHelpers {
unsafe fn html_element_in_html_document_for_layout(&self) -> bool;
unsafe fn has_attr_for_layout(&self, namespace: &Namespace, name: &Atom) -> bool;
}
impl LayoutElementHelpers for JS<Element> {
@ -349,6 +357,10 @@ impl LayoutElementHelpers for JS<Element> {
let node: JS<Node> = self.transmute_copy();
node.owner_doc_for_layout().is_html_document_for_layout()
}
unsafe fn has_attr_for_layout(&self, namespace: &Namespace, name: &Atom) -> bool {
get_attr_for_layout(&*self.unsafe_get(), namespace, name).is_some()
}
}
pub trait ElementHelpers<'a> {

View file

@ -13,16 +13,20 @@ use dom::bindings::codegen::Bindings::HTMLInputElementBinding::HTMLInputElementM
use dom::bindings::codegen::Bindings::NodeListBinding::NodeListMethods;
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, HTMLFormElementCast, HTMLInputElementCast, NodeCast};
use dom::bindings::codegen::InheritTypes::{HTMLInputElementDerived, HTMLFieldSetElementDerived};
use dom::bindings::codegen::InheritTypes::KeyboardEventCast;
use dom::bindings::js::{JS, JSRef, Temporary, OptionalRootable, ResultRootable};
use dom::bindings::utils::{Reflectable, Reflector};
use dom::document::{Document, DocumentHelpers};
use dom::element::{AttributeHandlers, Element, HTMLInputElementTypeId};
use dom::element::{AttributeHandlers, Element, HTMLInputElementTypeId, LayoutElementHelpers};
use dom::element::RawLayoutElementHelpers;
use dom::event::Event;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement;
use dom::keyboardevent::KeyboardEvent;
use dom::htmlformelement::{InputElement, FormOwner, HTMLFormElement, HTMLFormElementHelpers, NotFromFormSubmitMethod};
use dom::node::{DisabledStateHelpers, Node, NodeHelpers, ElementNodeTypeId, document_from_node, window_from_node};
use dom::virtualmethods::VirtualMethods;
use textinput::{TextInput, TriggerDefaultAction, DispatchInput, Nothing};
use servo_util::str::DOMString;
use string_cache::Atom;
@ -51,9 +55,8 @@ pub struct HTMLInputElement {
htmlelement: HTMLElement,
input_type: Cell<InputType>,
checked: Cell<bool>,
uncommitted_value: DOMRefCell<Option<String>>,
value: DOMRefCell<Option<String>>,
size: Cell<u32>,
textinput: DOMRefCell<TextInput>,
}
impl HTMLInputElementDerived for EventTarget {
@ -70,9 +73,8 @@ impl HTMLInputElement {
htmlelement: HTMLElement::new_inherited(HTMLInputElementTypeId, localName, prefix, document),
input_type: Cell::new(InputText),
checked: Cell::new(false),
uncommitted_value: DOMRefCell::new(None),
value: DOMRefCell::new(None),
size: Cell::new(DEFAULT_INPUT_SIZE),
textinput: DOMRefCell::new(TextInput::new(false, "".to_string())),
}
}
@ -84,40 +86,55 @@ impl HTMLInputElement {
}
pub trait LayoutHTMLInputElementHelpers {
unsafe fn get_value_for_layout(&self) -> String;
unsafe fn get_value_for_layout(self) -> String;
unsafe fn get_size_for_layout(self) -> u32;
}
pub trait RawLayoutHTMLInputElementHelpers {
unsafe fn get_size_for_layout(&self) -> u32;
}
impl LayoutHTMLInputElementHelpers for HTMLInputElement {
impl LayoutHTMLInputElementHelpers for JS<HTMLInputElement> {
#[allow(unrooted_must_root)]
unsafe fn get_value_for_layout(&self) -> String {
match self.input_type.get() {
unsafe fn get_value_for_layout(self) -> String {
unsafe fn get_raw_textinput_value(input: JS<HTMLInputElement>) -> Option<String> {
let elem: JS<Element> = input.transmute_copy();
if !elem.has_attr_for_layout(&ns!(""), &atom!("value")) {
return None;
}
Some((*input.unsafe_get()).textinput.borrow_for_layout().get_content())
}
unsafe fn get_raw_attr_value(input: JS<HTMLInputElement>) -> Option<String> {
let elem: JS<Element> = input.transmute_copy();
(*elem.unsafe_get()).get_attr_val_for_layout(&ns!(""), &atom!("value"))
.map(|s| s.to_string())
}
match (*self.unsafe_get()).input_type.get() {
InputCheckbox | InputRadio => "".to_string(),
InputFile | InputImage => "".to_string(),
InputButton(ref default) => self.value.borrow_for_layout().clone()
InputButton(ref default) => get_raw_attr_value(self)
.or_else(|| default.map(|v| v.to_string()))
.unwrap_or_else(|| "".to_string()),
InputPassword => {
let raw = self.value.borrow_for_layout().clone().unwrap_or_else(|| "".to_string());
String::from_char(raw.len(), '*')
let raw = get_raw_textinput_value(self).unwrap_or_else(|| "".to_string());
String::from_char(raw.len(), '')
}
_ => self.value.borrow_for_layout().clone().unwrap_or_else(|| "".to_string()),
_ => get_raw_textinput_value(self).unwrap_or_else(|| "".to_string()),
}
}
#[allow(unrooted_must_root)]
unsafe fn get_size_for_layout(&self) -> u32 {
self.size.get()
unsafe fn get_size_for_layout(self) -> u32 {
(*self.unsafe_get()).get_size_for_layout()
}
}
impl LayoutHTMLInputElementHelpers for JS<HTMLInputElement> {
unsafe fn get_value_for_layout(&self) -> String {
(*self.unsafe_get()).get_value_for_layout()
}
impl RawLayoutHTMLInputElementHelpers for HTMLInputElement {
#[allow(unrooted_must_root)]
unsafe fn get_size_for_layout(&self) -> u32 {
(*self.unsafe_get()).get_size_for_layout()
self.size.get()
}
}
@ -156,7 +173,7 @@ impl<'a> HTMLInputElementMethods for JSRef<'a, HTMLInputElement> {
// https://html.spec.whatwg.org/multipage/forms.html#dom-input-value
fn Value(self) -> DOMString {
self.value.borrow().clone().unwrap_or("".to_string())
self.textinput.borrow().get_content()
}
// https://html.spec.whatwg.org/multipage/forms.html#dom-input-value
@ -309,7 +326,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLInputElement> {
self.force_relayout();
}
&atom!("value") => {
*self.value.borrow_mut() = Some(attr.value().as_slice().to_string());
self.textinput.borrow_mut().set_content(attr.value().as_slice().to_string());
self.force_relayout();
}
&atom!("name") => {
@ -353,7 +370,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLInputElement> {
self.force_relayout();
}
&atom!("value") => {
*self.value.borrow_mut() = None;
self.textinput.borrow_mut().set_content("".to_string());
self.force_relayout();
}
&atom!("name") => {
@ -418,6 +435,18 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLInputElement> {
let doc = document_from_node(*self).root();
doc.request_focus(ElementCast::from_ref(*self));
} else if "keydown" == event.Type().as_slice() && !event.DefaultPrevented() &&
(self.input_type.get() == InputText|| self.input_type.get() == InputPassword) {
let keyevent: Option<JSRef<KeyboardEvent>> = KeyboardEventCast::to_ref(event);
keyevent.map(|event| {
match self.textinput.borrow_mut().handle_keydown(event) {
TriggerDefaultAction => (),
DispatchInput => {
self.force_relayout();
}
Nothing => (),
}
});
}
}
}

View file

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::Bindings::KeyboardEventBinding;
use dom::bindings::codegen::Bindings::KeyboardEventBinding::KeyboardEventMethods;
use dom::bindings::codegen::Bindings::KeyboardEventBinding::{KeyboardEventMethods, KeyboardEventConstants};
use dom::bindings::codegen::Bindings::UIEventBinding::UIEventMethods;
use dom::bindings::codegen::InheritTypes::{UIEventCast, KeyboardEventDerived};
use dom::bindings::error::Fallible;
@ -111,22 +111,431 @@ impl KeyboardEvent {
Ok(event)
}
pub fn key_properties(key: constellation_msg::Key) -> KeyEventProperties {
match key {
_ => KeyEventProperties {
key: "".to_string(),
code: "".to_string(),
location: 0,
char_code: None,
key_code: 0,
pub fn key_properties(key: constellation_msg::Key, mods: constellation_msg::KeyModifiers)
-> KeyEventProperties {
KeyEventProperties {
key: key_value(key, mods),
code: code_value(key),
location: key_location(key),
char_code: key_char_code(key, mods),
key_code: key_key_code(key),
}
}
}
}
// https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3Events-key.html
fn key_value(key: constellation_msg::Key, mods: constellation_msg::KeyModifiers) -> &'static str {
let shift = mods.contains(constellation_msg::SHIFT);
match key {
constellation_msg::KeySpace => " ",
constellation_msg::KeyApostrophe if shift => "\"",
constellation_msg::KeyApostrophe => "'",
constellation_msg::KeyComma if shift => "<",
constellation_msg::KeyComma => ",",
constellation_msg::KeyMinus if shift => "_",
constellation_msg::KeyMinus => "-",
constellation_msg::KeyPeriod if shift => ">",
constellation_msg::KeyPeriod => ".",
constellation_msg::KeySlash if shift => "?",
constellation_msg::KeySlash => "/",
constellation_msg::Key0 if shift => ")",
constellation_msg::Key0 => "0",
constellation_msg::Key1 if shift => "!",
constellation_msg::Key1 => "1",
constellation_msg::Key2 if shift => "@",
constellation_msg::Key2 => "2",
constellation_msg::Key3 if shift => "#",
constellation_msg::Key3 => "3",
constellation_msg::Key4 if shift => "$",
constellation_msg::Key4 => "4",
constellation_msg::Key5 if shift => "%",
constellation_msg::Key5 => "5",
constellation_msg::Key6 if shift => "^",
constellation_msg::Key6 => "6",
constellation_msg::Key7 if shift => "&",
constellation_msg::Key7 => "7",
constellation_msg::Key8 if shift => "*",
constellation_msg::Key8 => "8",
constellation_msg::Key9 if shift => "(",
constellation_msg::Key9 => "9",
constellation_msg::KeySemicolon if shift => ":",
constellation_msg::KeySemicolon => ";",
constellation_msg::KeyEqual if shift => "+",
constellation_msg::KeyEqual => "=",
constellation_msg::KeyA if shift => "A",
constellation_msg::KeyA => "a",
constellation_msg::KeyB if shift => "B",
constellation_msg::KeyB => "b",
constellation_msg::KeyC if shift => "C",
constellation_msg::KeyC => "c",
constellation_msg::KeyD if shift => "D",
constellation_msg::KeyD => "d",
constellation_msg::KeyE if shift => "E",
constellation_msg::KeyE => "e",
constellation_msg::KeyF if shift => "F",
constellation_msg::KeyF => "f",
constellation_msg::KeyG if shift => "G",
constellation_msg::KeyG => "g",
constellation_msg::KeyH if shift => "H",
constellation_msg::KeyH => "h",
constellation_msg::KeyI if shift => "I",
constellation_msg::KeyI => "i",
constellation_msg::KeyJ if shift => "J",
constellation_msg::KeyJ => "j",
constellation_msg::KeyK if shift => "K",
constellation_msg::KeyK => "k",
constellation_msg::KeyL if shift => "L",
constellation_msg::KeyL => "l",
constellation_msg::KeyM if shift => "M",
constellation_msg::KeyM => "m",
constellation_msg::KeyN if shift => "N",
constellation_msg::KeyN => "n",
constellation_msg::KeyO if shift => "O",
constellation_msg::KeyO => "o",
constellation_msg::KeyP if shift => "P",
constellation_msg::KeyP => "p",
constellation_msg::KeyQ if shift => "Q",
constellation_msg::KeyQ => "q",
constellation_msg::KeyR if shift => "R",
constellation_msg::KeyR => "r",
constellation_msg::KeyS if shift => "S",
constellation_msg::KeyS => "s",
constellation_msg::KeyT if shift => "T",
constellation_msg::KeyT => "t",
constellation_msg::KeyU if shift => "U",
constellation_msg::KeyU => "u",
constellation_msg::KeyV if shift => "V",
constellation_msg::KeyV => "v",
constellation_msg::KeyW if shift => "W",
constellation_msg::KeyW => "w",
constellation_msg::KeyX if shift => "X",
constellation_msg::KeyX => "x",
constellation_msg::KeyY if shift => "Y",
constellation_msg::KeyY => "y",
constellation_msg::KeyZ if shift => "Z",
constellation_msg::KeyZ => "z",
constellation_msg::KeyLeftBracket if shift => "{",
constellation_msg::KeyLeftBracket => "{",
constellation_msg::KeyBackslash if shift => "|",
constellation_msg::KeyBackslash => "\\",
constellation_msg::KeyRightBracket if shift => "}",
constellation_msg::KeyRightBracket => "]",
constellation_msg::KeyGraveAccent => "Dead",
constellation_msg::KeyWorld1 => "Unidentified",
constellation_msg::KeyWorld2 => "Unidentified",
constellation_msg::KeyEscape => "Escape",
constellation_msg::KeyEnter => "Enter",
constellation_msg::KeyTab => "Tab",
constellation_msg::KeyBackspace => "Backspace",
constellation_msg::KeyInsert => "Insert",
constellation_msg::KeyDelete => "Delete",
constellation_msg::KeyRight => "ArrowRight",
constellation_msg::KeyLeft => "ArrowLeft",
constellation_msg::KeyDown => "ArrowDown",
constellation_msg::KeyUp => "ArrowUp",
constellation_msg::KeyPageUp => "PageUp",
constellation_msg::KeyPageDown => "PageDown",
constellation_msg::KeyHome => "Home",
constellation_msg::KeyEnd => "End",
constellation_msg::KeyCapsLock => "CapsLock",
constellation_msg::KeyScrollLock => "ScrollLock",
constellation_msg::KeyNumLock => "NumLock",
constellation_msg::KeyPrintScreen => "PrintScreen",
constellation_msg::KeyPause => "Pause",
constellation_msg::KeyF1 => "F1",
constellation_msg::KeyF2 => "F2",
constellation_msg::KeyF3 => "F3",
constellation_msg::KeyF4 => "F4",
constellation_msg::KeyF5 => "F5",
constellation_msg::KeyF6 => "F6",
constellation_msg::KeyF7 => "F7",
constellation_msg::KeyF8 => "F8",
constellation_msg::KeyF9 => "F9",
constellation_msg::KeyF10 => "F10",
constellation_msg::KeyF11 => "F11",
constellation_msg::KeyF12 => "F12",
constellation_msg::KeyF13 => "F13",
constellation_msg::KeyF14 => "F14",
constellation_msg::KeyF15 => "F15",
constellation_msg::KeyF16 => "F16",
constellation_msg::KeyF17 => "F17",
constellation_msg::KeyF18 => "F18",
constellation_msg::KeyF19 => "F19",
constellation_msg::KeyF20 => "F20",
constellation_msg::KeyF21 => "F21",
constellation_msg::KeyF22 => "F22",
constellation_msg::KeyF23 => "F23",
constellation_msg::KeyF24 => "F24",
constellation_msg::KeyF25 => "F25",
constellation_msg::KeyKp0 => "0",
constellation_msg::KeyKp1 => "1",
constellation_msg::KeyKp2 => "2",
constellation_msg::KeyKp3 => "3",
constellation_msg::KeyKp4 => "4",
constellation_msg::KeyKp5 => "5",
constellation_msg::KeyKp6 => "6",
constellation_msg::KeyKp7 => "7",
constellation_msg::KeyKp8 => "8",
constellation_msg::KeyKp9 => "9",
constellation_msg::KeyKpDecimal => ".",
constellation_msg::KeyKpDivide => "/",
constellation_msg::KeyKpMultiply => "*",
constellation_msg::KeyKpSubtract => "-",
constellation_msg::KeyKpAdd => "+",
constellation_msg::KeyKpEnter => "Enter",
constellation_msg::KeyKpEqual => "=",
constellation_msg::KeyLeftShift => "Shift",
constellation_msg::KeyLeftControl => "Control",
constellation_msg::KeyLeftAlt => "Alt",
constellation_msg::KeyLeftSuper => "Super",
constellation_msg::KeyRightShift => "Shift",
constellation_msg::KeyRightControl => "Control",
constellation_msg::KeyRightAlt => "Alt",
constellation_msg::KeyRightSuper => "Super",
constellation_msg::KeyMenu => "ContextMenu",
}
}
// https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3Events-code.html
fn code_value(key: constellation_msg::Key) -> &'static str {
match key {
constellation_msg::KeySpace => "Space",
constellation_msg::KeyApostrophe => "Quote",
constellation_msg::KeyComma => "Comma",
constellation_msg::KeyMinus => "Minus",
constellation_msg::KeyPeriod => "Period",
constellation_msg::KeySlash => "Slash",
constellation_msg::Key0 => "Digit0",
constellation_msg::Key1 => "Digit1",
constellation_msg::Key2 => "Digit2",
constellation_msg::Key3 => "Digit3",
constellation_msg::Key4 => "Digit4",
constellation_msg::Key5 => "Digit5",
constellation_msg::Key6 => "Digit6",
constellation_msg::Key7 => "Digit7",
constellation_msg::Key8 => "Digit8",
constellation_msg::Key9 => "Digit9",
constellation_msg::KeySemicolon => "Semicolon",
constellation_msg::KeyEqual => "Equals",
constellation_msg::KeyA => "KeyA",
constellation_msg::KeyB => "KeyB",
constellation_msg::KeyC => "KeyC",
constellation_msg::KeyD => "KeyD",
constellation_msg::KeyE => "KeyE",
constellation_msg::KeyF => "KeyF",
constellation_msg::KeyG => "KeyG",
constellation_msg::KeyH => "KeyH",
constellation_msg::KeyI => "KeyI",
constellation_msg::KeyJ => "KeyJ",
constellation_msg::KeyK => "KeyK",
constellation_msg::KeyL => "KeyL",
constellation_msg::KeyM => "KeyM",
constellation_msg::KeyN => "KeyN",
constellation_msg::KeyO => "KeyO",
constellation_msg::KeyP => "KeyP",
constellation_msg::KeyQ => "KeyQ",
constellation_msg::KeyR => "KeyR",
constellation_msg::KeyS => "KeyS",
constellation_msg::KeyT => "KeyT",
constellation_msg::KeyU => "KeyU",
constellation_msg::KeyV => "KeyV",
constellation_msg::KeyW => "KeyW",
constellation_msg::KeyX => "KeyX",
constellation_msg::KeyY => "KeyY",
constellation_msg::KeyZ => "KeyZ",
constellation_msg::KeyLeftBracket => "BracketLeft",
constellation_msg::KeyBackslash => "Backslash",
constellation_msg::KeyRightBracket => "BracketRight",
constellation_msg::KeyGraveAccent |
constellation_msg::KeyWorld1 |
constellation_msg::KeyWorld2 => panic!("unknown char code for {}", key),
constellation_msg::KeyEscape => "Escape",
constellation_msg::KeyEnter => "Enter",
constellation_msg::KeyTab => "Tab",
constellation_msg::KeyBackspace => "Backspace",
constellation_msg::KeyInsert => "Insert",
constellation_msg::KeyDelete => "Delete",
constellation_msg::KeyRight => "ArrowRight",
constellation_msg::KeyLeft => "ArrowLeft",
constellation_msg::KeyDown => "ArrowDown",
constellation_msg::KeyUp => "ArrowUp",
constellation_msg::KeyPageUp => "PageUp",
constellation_msg::KeyPageDown => "PageDown",
constellation_msg::KeyHome => "Home",
constellation_msg::KeyEnd => "End",
constellation_msg::KeyCapsLock => "CapsLock",
constellation_msg::KeyScrollLock => "ScrollLock",
constellation_msg::KeyNumLock => "NumLock",
constellation_msg::KeyPrintScreen => "PrintScreen",
constellation_msg::KeyPause => "Pause",
constellation_msg::KeyF1 => "F1",
constellation_msg::KeyF2 => "F2",
constellation_msg::KeyF3 => "F3",
constellation_msg::KeyF4 => "F4",
constellation_msg::KeyF5 => "F5",
constellation_msg::KeyF6 => "F6",
constellation_msg::KeyF7 => "F7",
constellation_msg::KeyF8 => "F8",
constellation_msg::KeyF9 => "F9",
constellation_msg::KeyF10 => "F10",
constellation_msg::KeyF11 => "F11",
constellation_msg::KeyF12 => "F12",
constellation_msg::KeyF13 => "F13",
constellation_msg::KeyF14 => "F14",
constellation_msg::KeyF15 => "F15",
constellation_msg::KeyF16 => "F16",
constellation_msg::KeyF17 => "F17",
constellation_msg::KeyF18 => "F18",
constellation_msg::KeyF19 => "F19",
constellation_msg::KeyF20 => "F20",
constellation_msg::KeyF21 => "F21",
constellation_msg::KeyF22 => "F22",
constellation_msg::KeyF23 => "F23",
constellation_msg::KeyF24 => "F24",
constellation_msg::KeyF25 => "F25",
constellation_msg::KeyKp0 => "Numpad0",
constellation_msg::KeyKp1 => "Numpad1",
constellation_msg::KeyKp2 => "Numpad2",
constellation_msg::KeyKp3 => "Numpad3",
constellation_msg::KeyKp4 => "Numpad4",
constellation_msg::KeyKp5 => "Numpad5",
constellation_msg::KeyKp6 => "Numpad6",
constellation_msg::KeyKp7 => "Numpad7",
constellation_msg::KeyKp8 => "Numpad8",
constellation_msg::KeyKp9 => "Numpad9",
constellation_msg::KeyKpDecimal => "NumpadDecimal",
constellation_msg::KeyKpDivide => "NumpadDivide",
constellation_msg::KeyKpMultiply => "NumpadMultiply",
constellation_msg::KeyKpSubtract => "NumpadSubtract",
constellation_msg::KeyKpAdd => "NumpadAdd",
constellation_msg::KeyKpEnter => "NumpadEnter",
constellation_msg::KeyKpEqual => "NumpadEquals",
constellation_msg::KeyLeftShift | constellation_msg::KeyRightShift => "Shift",
constellation_msg::KeyLeftControl | constellation_msg::KeyRightControl => "Control",
constellation_msg::KeyLeftAlt | constellation_msg::KeyRightAlt => "Alt",
constellation_msg::KeyLeftSuper | constellation_msg::KeyRightSuper => "Super",
constellation_msg::KeyMenu => "Menu",
}
}
fn key_location(key: constellation_msg::Key) -> u32 {
match key {
constellation_msg::KeyKp0 | constellation_msg::KeyKp1 | constellation_msg::KeyKp2 |
constellation_msg::KeyKp3 | constellation_msg::KeyKp4 | constellation_msg::KeyKp5 |
constellation_msg::KeyKp6 | constellation_msg::KeyKp7 | constellation_msg::KeyKp8 |
constellation_msg::KeyKp9 | constellation_msg::KeyKpDecimal |
constellation_msg::KeyKpDivide | constellation_msg::KeyKpMultiply |
constellation_msg::KeyKpSubtract | constellation_msg::KeyKpAdd |
constellation_msg::KeyKpEnter | constellation_msg::KeyKpEqual =>
KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD,
constellation_msg::KeyLeftShift | constellation_msg::KeyLeftAlt |
constellation_msg::KeyLeftControl | constellation_msg::KeyLeftSuper =>
KeyboardEventConstants::DOM_KEY_LOCATION_LEFT,
constellation_msg::KeyRightShift | constellation_msg::KeyRightAlt |
constellation_msg::KeyRightControl | constellation_msg::KeyRightSuper =>
KeyboardEventConstants::DOM_KEY_LOCATION_RIGHT,
_ => KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD,
}
}
// https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#widl-KeyboardEvent-charCode
fn key_char_code(key: constellation_msg::Key, mods: constellation_msg::KeyModifiers) -> Option<u32> {
let key = key_value(key, mods);
if key.len() == 1 {
Some(key.char_at(0) as u32)
} else {
None
}
}
// https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#legacy-key-models
fn key_key_code(key: constellation_msg::Key) -> u32 {
match key {
// https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#legacy-key-models
constellation_msg::KeyBackspace => 8,
constellation_msg::KeyTab => 9,
constellation_msg::KeyEnter => 13,
constellation_msg::KeyLeftShift | constellation_msg::KeyRightShift => 16,
constellation_msg::KeyLeftControl | constellation_msg::KeyRightControl => 17,
constellation_msg::KeyLeftAlt | constellation_msg::KeyRightAlt => 18,
constellation_msg::KeyCapsLock => 20,
constellation_msg::KeyEscape => 27,
constellation_msg::KeySpace => 32,
constellation_msg::KeyPageUp => 33,
constellation_msg::KeyPageDown => 34,
constellation_msg::KeyEnd => 35,
constellation_msg::KeyHome => 36,
constellation_msg::KeyLeft => 37,
constellation_msg::KeyUp => 38,
constellation_msg::KeyRight => 39,
constellation_msg::KeyDown => 40,
constellation_msg::KeyDelete => 46,
// https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#optionally-fixed-virtual-key-codes
constellation_msg::KeySemicolon => 186,
constellation_msg::KeyEqual => 187,
constellation_msg::KeyComma => 188,
constellation_msg::KeyMinus => 189,
constellation_msg::KeyPeriod => 190,
constellation_msg::KeySlash => 191,
constellation_msg::KeyLeftBracket => 219,
constellation_msg::KeyBackslash => 220,
constellation_msg::KeyRightBracket => 221,
constellation_msg::KeyApostrophe => 222,
//§ B.2.1.3
constellation_msg::Key0 |
constellation_msg::Key1 |
constellation_msg::Key2 |
constellation_msg::Key3 |
constellation_msg::Key4 |
constellation_msg::Key5 |
constellation_msg::Key6 |
constellation_msg::Key7 |
constellation_msg::Key8 |
constellation_msg::Key9 => key as u32 - constellation_msg::Key0 as u32 + '0' as u32,
//§ B.2.1.4
constellation_msg::KeyA |
constellation_msg::KeyB |
constellation_msg::KeyC |
constellation_msg::KeyD |
constellation_msg::KeyE |
constellation_msg::KeyF |
constellation_msg::KeyG |
constellation_msg::KeyH |
constellation_msg::KeyI |
constellation_msg::KeyJ |
constellation_msg::KeyK |
constellation_msg::KeyL |
constellation_msg::KeyM |
constellation_msg::KeyN |
constellation_msg::KeyO |
constellation_msg::KeyP |
constellation_msg::KeyQ |
constellation_msg::KeyR |
constellation_msg::KeyS |
constellation_msg::KeyT |
constellation_msg::KeyU |
constellation_msg::KeyV |
constellation_msg::KeyW |
constellation_msg::KeyX |
constellation_msg::KeyY |
constellation_msg::KeyZ => key as u32 - constellation_msg::KeyA as u32 + 'A' as u32,
//§ B.2.1.8
_ => 0
}
}
pub struct KeyEventProperties {
pub key: DOMString,
pub code: DOMString,
pub key: &'static str,
pub code: &'static str,
pub location: u32,
pub char_code: Option<u32>,
pub key_code: u32,