Merge remote-tracking branch 'origin/pr/4204'

This commit is contained in:
Florian Bruhin 2018-09-27 16:28:30 +02:00
commit 38a4734b9a
9 changed files with 45 additions and 5 deletions

View File

@ -1659,6 +1659,8 @@ class CommandDispatcher:
""" """
try: try:
elem.set_value(text) elem.set_value(text)
# Kick off js handlers to trick them into thinking there was input.
elem.dispatch_event("input", bubbles=True)
except webelem.OrphanedError: except webelem.OrphanedError:
message.error('Edited element vanished') message.error('Edited element vanished')
ed.backup() ed.backup()

View File

@ -139,6 +139,18 @@ class AbstractWebElement(collections.abc.MutableMapping):
"""Set the element value.""" """Set the element value."""
raise NotImplementedError raise NotImplementedError
def dispatch_event(self, event, bubbles=False,
cancelable=False, composed=False):
"""Dispatch an event to the element.
Args:
bubbles: Whether this event should bubble.
cancelable: Whether this event can be cancelled.
composed: Whether the event will trigger listeners outside of a
shadow root
"""
raise NotImplementedError
def insert_text(self, text): def insert_text(self, text):
"""Insert the given text into the element.""" """Insert the given text into the element."""
raise NotImplementedError raise NotImplementedError

View File

@ -135,6 +135,10 @@ class WebEngineElement(webelem.AbstractWebElement):
def set_value(self, value): def set_value(self, value):
self._js_call('set_value', value) self._js_call('set_value', value)
def dispatch_event(self, event, bubbles=False,
cancelable=False, composed=False):
self._js_call('dispatch_event', event, bubbles, cancelable, composed)
def caret_position(self): def caret_position(self):
"""Get the text caret position for the current element. """Get the text caret position for the current element.

View File

@ -128,6 +128,18 @@ class WebKitElement(webelem.AbstractWebElement):
value = javascript.string_escape(value) value = javascript.string_escape(value)
self._elem.evaluateJavaScript("this.value='{}'".format(value)) self._elem.evaluateJavaScript("this.value='{}'".format(value))
def dispatch_event(self, event, bubbles=False,
cancelable=False, composed=False):
self._check_vanished()
log.webelem.debug("Firing event on {!r} via javascript.".format(self))
self._elem.evaluateJavaScript(
"this.dispatchEvent(new Event({}, "
"{{'bubbles': {}, 'cancelable': {}, 'composed': {}}}))"
.format(javascript.convert_js_arg(event),
javascript.convert_js_arg(bubbles),
javascript.convert_js_arg(cancelable),
javascript.convert_js_arg(composed)))
def caret_position(self): def caret_position(self):
"""Get the text caret position for the current element.""" """Get the text caret position for the current element."""
self._check_vanished() self._check_vanished()

View File

@ -59,3 +59,4 @@ rules:
multiline-ternary: ["error", "always-multiline"] multiline-ternary: ["error", "always-multiline"]
max-lines-per-function: "off" max-lines-per-function: "off"
require-unicode-regexp: "off" require-unicode-regexp: "off"
max-params: "off"

View File

@ -1,5 +1,5 @@
/* eslint-disable max-len, max-statements, complexity, /* eslint-disable max-len, max-statements, complexity,
max-params, default-case, valid-jsdoc */ default-case, valid-jsdoc */
// Copyright 2014 The Chromium Authors. All rights reserved. // Copyright 2014 The Chromium Authors. All rights reserved.
// //

View File

@ -362,6 +362,15 @@ window._qutebrowser.webelem = (function() {
document.execCommand("insertText", false, text); document.execCommand("insertText", false, text);
}; };
funcs.dispatch_event = (id, event, bubbles = false,
cancelable = false, composed = false) => {
const elem = elements[id];
elem.dispatchEvent(
new Event(event, {"bubbles": bubbles,
"cancelable": cancelable,
"composed": composed}));
};
funcs.set_attribute = (id, name, value) => { funcs.set_attribute = (id, name, value) => {
elements[id].setAttribute(name, value); elements[id].setAttribute(name, value);
}; };

View File

@ -49,7 +49,7 @@ def string_escape(text):
return text return text
def _convert_js_arg(arg): def convert_js_arg(arg):
"""Convert the given argument so it's the equivalent in JS.""" """Convert the given argument so it's the equivalent in JS."""
if arg is None: if arg is None:
return 'undefined' return 'undefined'
@ -68,7 +68,7 @@ def _convert_js_arg(arg):
def assemble(module, function, *args): def assemble(module, function, *args):
"""Assemble a javascript file and a function call.""" """Assemble a javascript file and a function call."""
js_args = ', '.join(_convert_js_arg(arg) for arg in args) js_args = ', '.join(convert_js_arg(arg) for arg in args)
if module == 'window': if module == 'window':
parts = ['window', function] parts = ['window', function]
else: else:

View File

@ -89,9 +89,9 @@ class TestStringEscape:
def test_convert_js_arg(arg, expected): def test_convert_js_arg(arg, expected):
if expected is TypeError: if expected is TypeError:
with pytest.raises(TypeError): with pytest.raises(TypeError):
javascript._convert_js_arg(arg) javascript.convert_js_arg(arg)
else: else:
assert javascript._convert_js_arg(arg) == expected assert javascript.convert_js_arg(arg) == expected
@pytest.mark.parametrize('base, expected_base', [ @pytest.mark.parametrize('base, expected_base', [