mirror of
https://github.com/teampoltergeist/poltergeist.git
synced 2022-11-09 12:05:00 -05:00
Use native keyboard events to fill inputs
This means that WebKit generates the DOM events itself which should prevent bugs and edge case problems. It also drastically simplifies the implementation. Closes #162, #131
This commit is contained in:
parent
332f80a696
commit
c7ba561411
4 changed files with 30 additions and 180 deletions
|
@ -110,32 +110,6 @@ class PoltergeistAgent.Node
|
|||
event.initEvent('change', true, false)
|
||||
@element.dispatchEvent(event)
|
||||
|
||||
input: ->
|
||||
event = document.createEvent('HTMLEvents')
|
||||
event.initEvent('input', true, false)
|
||||
@element.dispatchEvent(event)
|
||||
|
||||
keyupdowned: (eventName, keyCode) ->
|
||||
event = document.createEvent('UIEvents')
|
||||
event.initEvent(eventName, true, true)
|
||||
event.keyCode = keyCode
|
||||
event.which = keyCode
|
||||
event.charCode = 0
|
||||
@element.dispatchEvent(event)
|
||||
|
||||
keypressed: (altKey, ctrlKey, shiftKey, metaKey, keyCode, charCode) ->
|
||||
event = document.createEvent('UIEvents')
|
||||
event.initEvent('keypress', true, true)
|
||||
event.window = @agent.window
|
||||
event.altKey = altKey
|
||||
event.ctrlKey = ctrlKey
|
||||
event.shiftKey = shiftKey
|
||||
event.metaKey = metaKey
|
||||
event.keyCode = keyCode
|
||||
event.charCode = charCode
|
||||
event.which = keyCode
|
||||
@element.dispatchEvent(event)
|
||||
|
||||
insideBody: ->
|
||||
@element == @agent.document.body ||
|
||||
@agent.document.evaluate('ancestor::body', @element, null, XPathResult.BOOLEAN_TYPE, null).booleanValue
|
||||
|
@ -161,25 +135,6 @@ class PoltergeistAgent.Node
|
|||
else
|
||||
@element.value
|
||||
|
||||
set: (value) ->
|
||||
if (@element.maxLength >= 0)
|
||||
value = value.substr(0, @element.maxLength)
|
||||
|
||||
@element.value = ''
|
||||
this.trigger('focus')
|
||||
|
||||
for char in value
|
||||
keyCode = this.characterToKeyCode(char)
|
||||
this.keyupdowned('keydown', keyCode)
|
||||
@element.value += char
|
||||
|
||||
this.keypressed(false, false, false, false, char.charCodeAt(0), char.charCodeAt(0))
|
||||
this.keyupdowned('keyup', keyCode)
|
||||
|
||||
this.changed()
|
||||
this.input()
|
||||
this.trigger('blur')
|
||||
|
||||
isMultiple: ->
|
||||
@element.multiple
|
||||
|
||||
|
@ -238,6 +193,13 @@ class PoltergeistAgent.Node
|
|||
|
||||
@element.dispatchEvent(event)
|
||||
|
||||
focusAndHighlight: ->
|
||||
@element.focus()
|
||||
@element.select()
|
||||
|
||||
blur: ->
|
||||
@element.blur()
|
||||
|
||||
clickTest: (x, y) ->
|
||||
el = origEl = document.elementFromPoint(x, y)
|
||||
|
||||
|
@ -257,45 +219,6 @@ class PoltergeistAgent.Node
|
|||
selector += ".#{className}"
|
||||
selector
|
||||
|
||||
characterToKeyCode: (character) ->
|
||||
code = character.toUpperCase().charCodeAt(0)
|
||||
specialKeys =
|
||||
96: 192 #`
|
||||
45: 189 #-
|
||||
61: 187 #=
|
||||
91: 219 #[
|
||||
93: 221 #]
|
||||
92: 220 #\
|
||||
59: 186 #;
|
||||
39: 222 #'
|
||||
44: 188 #,
|
||||
46: 190 #.
|
||||
47: 191 #/
|
||||
127: 46 #delete
|
||||
126: 192 #~
|
||||
33: 49 #!
|
||||
64: 50 #@
|
||||
35: 51 ##
|
||||
36: 52 #$
|
||||
37: 53 #%
|
||||
94: 54 #^
|
||||
38: 55 #&
|
||||
42: 56 #*
|
||||
40: 57 #(
|
||||
41: 48 #)
|
||||
95: 189 #_
|
||||
43: 187 #+
|
||||
123: 219 #{
|
||||
125: 221 #}
|
||||
124: 220 #|
|
||||
58: 186 #:
|
||||
34: 222 #"
|
||||
60: 188 #<
|
||||
62: 190 #>
|
||||
63: 191 #?
|
||||
|
||||
specialKeys[code] || code
|
||||
|
||||
isDOMEqual: (other_id) ->
|
||||
@element == @agent.get(other_id).element
|
||||
|
||||
|
|
|
@ -167,38 +167,6 @@ PoltergeistAgent.Node = (function() {
|
|||
return this.element.dispatchEvent(event);
|
||||
};
|
||||
|
||||
Node.prototype.input = function() {
|
||||
var event;
|
||||
event = document.createEvent('HTMLEvents');
|
||||
event.initEvent('input', true, false);
|
||||
return this.element.dispatchEvent(event);
|
||||
};
|
||||
|
||||
Node.prototype.keyupdowned = function(eventName, keyCode) {
|
||||
var event;
|
||||
event = document.createEvent('UIEvents');
|
||||
event.initEvent(eventName, true, true);
|
||||
event.keyCode = keyCode;
|
||||
event.which = keyCode;
|
||||
event.charCode = 0;
|
||||
return this.element.dispatchEvent(event);
|
||||
};
|
||||
|
||||
Node.prototype.keypressed = function(altKey, ctrlKey, shiftKey, metaKey, keyCode, charCode) {
|
||||
var event;
|
||||
event = document.createEvent('UIEvents');
|
||||
event.initEvent('keypress', true, true);
|
||||
event.window = this.agent.window;
|
||||
event.altKey = altKey;
|
||||
event.ctrlKey = ctrlKey;
|
||||
event.shiftKey = shiftKey;
|
||||
event.metaKey = metaKey;
|
||||
event.keyCode = keyCode;
|
||||
event.charCode = charCode;
|
||||
event.which = keyCode;
|
||||
return this.element.dispatchEvent(event);
|
||||
};
|
||||
|
||||
Node.prototype.insideBody = function() {
|
||||
return this.element === this.agent.document.body || this.agent.document.evaluate('ancestor::body', this.element, null, XPathResult.BOOLEAN_TYPE, null).booleanValue;
|
||||
};
|
||||
|
@ -240,26 +208,6 @@ PoltergeistAgent.Node = (function() {
|
|||
}
|
||||
};
|
||||
|
||||
Node.prototype.set = function(value) {
|
||||
var char, keyCode, _i, _len;
|
||||
if (this.element.maxLength >= 0) {
|
||||
value = value.substr(0, this.element.maxLength);
|
||||
}
|
||||
this.element.value = '';
|
||||
this.trigger('focus');
|
||||
for (_i = 0, _len = value.length; _i < _len; _i++) {
|
||||
char = value[_i];
|
||||
keyCode = this.characterToKeyCode(char);
|
||||
this.keyupdowned('keydown', keyCode);
|
||||
this.element.value += char;
|
||||
this.keypressed(false, false, false, false, char.charCodeAt(0), char.charCodeAt(0));
|
||||
this.keyupdowned('keyup', keyCode);
|
||||
}
|
||||
this.changed();
|
||||
this.input();
|
||||
return this.trigger('blur');
|
||||
};
|
||||
|
||||
Node.prototype.isMultiple = function() {
|
||||
return this.element.multiple;
|
||||
};
|
||||
|
@ -329,6 +277,15 @@ PoltergeistAgent.Node = (function() {
|
|||
return this.element.dispatchEvent(event);
|
||||
};
|
||||
|
||||
Node.prototype.focusAndHighlight = function() {
|
||||
this.element.focus();
|
||||
return this.element.select();
|
||||
};
|
||||
|
||||
Node.prototype.blur = function() {
|
||||
return this.element.blur();
|
||||
};
|
||||
|
||||
Node.prototype.clickTest = function(x, y) {
|
||||
var el, origEl;
|
||||
el = origEl = document.elementFromPoint(x, y);
|
||||
|
@ -362,47 +319,6 @@ PoltergeistAgent.Node = (function() {
|
|||
return selector;
|
||||
};
|
||||
|
||||
Node.prototype.characterToKeyCode = function(character) {
|
||||
var code, specialKeys;
|
||||
code = character.toUpperCase().charCodeAt(0);
|
||||
specialKeys = {
|
||||
96: 192,
|
||||
45: 189,
|
||||
61: 187,
|
||||
91: 219,
|
||||
93: 221,
|
||||
92: 220,
|
||||
59: 186,
|
||||
39: 222,
|
||||
44: 188,
|
||||
46: 190,
|
||||
47: 191,
|
||||
127: 46,
|
||||
126: 192,
|
||||
33: 49,
|
||||
64: 50,
|
||||
35: 51,
|
||||
36: 52,
|
||||
37: 53,
|
||||
94: 54,
|
||||
38: 55,
|
||||
42: 56,
|
||||
40: 57,
|
||||
41: 48,
|
||||
95: 189,
|
||||
43: 187,
|
||||
123: 219,
|
||||
125: 221,
|
||||
124: 220,
|
||||
58: 186,
|
||||
34: 222,
|
||||
60: 188,
|
||||
62: 190,
|
||||
63: 191
|
||||
};
|
||||
return specialKeys[code] || code;
|
||||
};
|
||||
|
||||
Node.prototype.isDOMEqual = function(other_id) {
|
||||
return this.element === this.agent.get(other_id).element;
|
||||
};
|
||||
|
|
|
@ -4,7 +4,7 @@ Poltergeist.Node = (function() {
|
|||
var name, _fn, _i, _len, _ref,
|
||||
_this = this;
|
||||
|
||||
Node.DELEGATES = ['text', 'getAttribute', 'value', 'set', 'setAttribute', 'isObsolete', 'removeAttribute', 'isMultiple', 'select', 'tagName', 'find', 'isVisible', 'position', 'trigger', 'parentId', 'clickTest', 'scrollIntoView', 'isDOMEqual'];
|
||||
Node.DELEGATES = ['text', 'getAttribute', 'value', 'setAttribute', 'isObsolete', 'removeAttribute', 'isMultiple', 'select', 'tagName', 'find', 'isVisible', 'position', 'trigger', 'parentId', 'clickTest', 'scrollIntoView', 'isDOMEqual', 'focusAndHighlight', 'blur'];
|
||||
|
||||
function Node(page, id) {
|
||||
this.page = page;
|
||||
|
@ -67,6 +67,12 @@ Poltergeist.Node = (function() {
|
|||
return this.page === other.page && this.isDOMEqual(other.id);
|
||||
};
|
||||
|
||||
Node.prototype.set = function(value) {
|
||||
this.focusAndHighlight();
|
||||
this.page.sendEvent('keypress', value.toString());
|
||||
return this.blur();
|
||||
};
|
||||
|
||||
return Node;
|
||||
|
||||
}).call(this);
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
# Proxy object for forwarding method calls to the node object inside the page.
|
||||
|
||||
class Poltergeist.Node
|
||||
@DELEGATES = ['text', 'getAttribute', 'value', 'set', 'setAttribute', 'isObsolete',
|
||||
@DELEGATES = ['text', 'getAttribute', 'value', 'setAttribute', 'isObsolete',
|
||||
'removeAttribute', 'isMultiple', 'select', 'tagName', 'find',
|
||||
'isVisible', 'position', 'trigger', 'parentId', 'clickTest',
|
||||
'scrollIntoView', 'isDOMEqual']
|
||||
'scrollIntoView', 'isDOMEqual', 'focusAndHighlight', 'blur']
|
||||
|
||||
constructor: (@page, @id) ->
|
||||
|
||||
|
@ -51,3 +51,8 @@ class Poltergeist.Node
|
|||
|
||||
isEqual: (other) ->
|
||||
@page == other.page && this.isDOMEqual(other.id)
|
||||
|
||||
set: (value) ->
|
||||
this.focusAndHighlight()
|
||||
@page.sendEvent('keypress', value.toString())
|
||||
this.blur()
|
||||
|
|
Loading…
Add table
Reference in a new issue