Skip to content

Commit e2e1e36

Browse files
committed
Create KeyItem struct for send_keys
Signed-off-by: PotatoCP <[email protected]>
1 parent 7634834 commit e2e1e36

File tree

1 file changed

+84
-37
lines changed

1 file changed

+84
-37
lines changed

src/webdriver.rs

Lines changed: 84 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -373,46 +373,29 @@ impl KeyInputState {
373373
is_composing: false,
374374
})
375375
}
376+
}
376377

377-
fn clear(&mut self, undo_actions: &mut HashSet<char>, result: &mut Vec<Event>) {
378-
let mut actions: Vec<_> = undo_actions.drain().collect();
379-
actions.sort_unstable();
380-
for action in actions {
381-
result.push(self.dispatch_keyup(action).unwrap().into());
382-
}
383-
assert!(undo_actions.is_empty());
384-
}
385-
386-
fn dispatch_typeable(&mut self, text: &mut String, result: &mut Vec<Event>) {
387-
for character in text.chars() {
388-
let shifted = self.modifiers.contains(Modifiers::SHIFT);
389-
if is_shifted_character(character) && !shifted {
390-
// dispatch left shift down
391-
result.push(self.dispatch_keydown('\u{E008}').into());
392-
}
393-
if !is_shifted_character(character) && shifted {
394-
// dispatch left shift up
395-
result.push(self.dispatch_keyup('\u{E008}').unwrap().into());
396-
}
397-
result.push(self.dispatch_keydown(character).into());
398-
result.push(self.dispatch_keyup(character).unwrap().into());
399-
}
400-
text.clear();
401-
}
378+
/// Give user the key state and char of the key event.
379+
/// User must then send the key event through `dispatch_actions`
380+
#[derive(Clone, Eq, PartialEq, Hash, Debug, PartialOrd, Ord)]
381+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
382+
pub struct KeyItem {
383+
state: KeyState,
384+
raw_char: char,
402385
}
403386

404-
/// Either a [`KeyboardEvent`] or a [`CompositionEvent`].
387+
/// Either a [`KeyItem`] or a [`CompositionEvent`].
405388
///
406389
/// Returned by the [`send_keys`] function.
407390
#[derive(Clone, Eq, PartialEq, Hash, Debug, PartialOrd, Ord)]
408391
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
409392
pub enum Event {
410-
Keyboard(KeyboardEvent),
393+
Keyboard(KeyItem),
411394
Composition(CompositionEvent),
412395
}
413396

414-
impl From<KeyboardEvent> for Event {
415-
fn from(v: KeyboardEvent) -> Event {
397+
impl From<KeyItem> for Event {
398+
fn from(v: KeyItem) -> Event {
416399
Event::Keyboard(v)
417400
}
418401
}
@@ -459,25 +442,89 @@ pub fn send_keys(text: &str) -> Vec<Event> {
459442
text.chars().count() == 1
460443
}
461444

445+
fn clear(undo_actions: &mut HashSet<char>, result: &mut Vec<Event>, shifted: &mut bool) {
446+
let mut actions: Vec<_> = undo_actions.drain().collect();
447+
actions.sort_unstable();
448+
for action in actions {
449+
result.push(
450+
KeyItem {
451+
state: KeyState::Up,
452+
raw_char: action,
453+
}
454+
.into(),
455+
);
456+
}
457+
*shifted = false;
458+
assert!(undo_actions.is_empty());
459+
}
460+
461+
fn dispatch_typeable(text: &mut String, result: &mut Vec<Event>, shifted: &mut bool) {
462+
for character in text.chars() {
463+
if is_shifted_character(character) && !(*shifted) {
464+
// dispatch left shift down
465+
result.push(
466+
KeyItem {
467+
state: KeyState::Down,
468+
raw_char: '\u{E008}',
469+
}
470+
.into(),
471+
);
472+
*shifted = true;
473+
}
474+
if !is_shifted_character(character) && *shifted {
475+
// dispatch left shift up
476+
result.push(
477+
KeyItem {
478+
state: KeyState::Up,
479+
raw_char: '\u{E008}',
480+
}
481+
.into(),
482+
);
483+
*shifted = false;
484+
}
485+
result.push(
486+
KeyItem {
487+
state: KeyState::Down,
488+
raw_char: character,
489+
}
490+
.into(),
491+
);
492+
result.push(
493+
KeyItem {
494+
state: KeyState::Up,
495+
raw_char: character,
496+
}
497+
.into(),
498+
);
499+
}
500+
text.clear();
501+
}
502+
462503
let mut result = Vec::new();
463504
let mut typeable_text = String::new();
464-
let mut state = KeyInputState::new();
465505
let mut undo_actions = HashSet::new();
506+
let mut shifted = false;
466507
for cluster in UnicodeSegmentation::graphemes(text, true) {
467508
match cluster {
468509
"\u{E000}" => {
469-
state.dispatch_typeable(&mut typeable_text, &mut result);
470-
state.clear(&mut undo_actions, &mut result);
510+
dispatch_typeable(&mut typeable_text, &mut result, &mut shifted);
511+
clear(&mut undo_actions, &mut result, &mut shifted);
471512
}
472513
s if is_modifier(s) => {
473-
state.dispatch_typeable(&mut typeable_text, &mut result);
514+
dispatch_typeable(&mut typeable_text, &mut result, &mut shifted);
474515
let raw_modifier = first_char(s);
475-
result.push(state.dispatch_keydown(raw_modifier).into());
516+
result.push(
517+
KeyItem {
518+
state: KeyState::Down,
519+
raw_char: raw_modifier,
520+
}
521+
.into(),
522+
);
476523
undo_actions.insert(raw_modifier);
477524
}
478525
s if is_typeable(s) => typeable_text.push_str(s),
479526
s => {
480-
state.dispatch_typeable(&mut typeable_text, &mut result);
527+
dispatch_typeable(&mut typeable_text, &mut result, &mut shifted);
481528
// FIXME: Spec says undefined instead of empty string
482529
result.push(
483530
CompositionEvent {
@@ -503,7 +550,7 @@ pub fn send_keys(text: &str) -> Vec<Event> {
503550
}
504551
}
505552
}
506-
state.dispatch_typeable(&mut typeable_text, &mut result);
507-
state.clear(&mut undo_actions, &mut result);
553+
dispatch_typeable(&mut typeable_text, &mut result, &mut shifted);
554+
clear(&mut undo_actions, &mut result, &mut shifted);
508555
result
509556
}

0 commit comments

Comments
 (0)