Permalink
Browse files

Implement :insert-text for QtWebEngine

  • Loading branch information...
The-Compiler committed Sep 7, 2016
1 parent ee5a972 commit 948fa033c7339d6648af2141e88283105ffbaa31
@@ -1525,32 +1525,28 @@ def paste_primary(self):
self.insert_text(utils.get_clipboard())
@cmdutils.register(instance='command-dispatcher', maxsplit=0,
- scope='window', backend=usertypes.Backend.QtWebKit)
+ scope='window')
def insert_text(self, text):
"""Insert text at cursor position.
Args:
text: The text to insert.
"""
- # FIXME:qtwebengine have a proper API for this
tab = self._current_widget()
if not tab.has_js():
raise cmdexc.CommandError("This command needs javascript enabled.")
- page = tab._widget.page() # pylint: disable=protected-access
- try:
- elem = webkitelem.focus_elem(page.currentFrame())
- except webkitelem.IsNullError:
- raise cmdexc.CommandError("No element focused!")
- if not elem.is_editable(strict=True):
- raise cmdexc.CommandError("Focused element is not editable!")
- log.misc.debug("Inserting text into element {}".format(
- elem.debug_text()))
- elem.run_js_async("""
- var text = '{}';
- var event = document.createEvent('TextEvent');
- event.initTextEvent('textInput', true, true, null, text);
- this.dispatchEvent(event);
- """.format(javascript.string_escape(text)))
+
+ def _insert_text_cb(elem):
+ if elem is None:
+ message.error(self._win_id, "No element focused!")
+ return
+ try:
+ elem.insert_text(text)
+ except webelem.Error as e:
+ message.error(self._win_id, str(e))
+ return
+
+ tab.elements.find_focused(_insert_text_cb)
@cmdutils.register(instance='command-dispatcher', scope='window',
hide=True)
@@ -158,6 +158,10 @@ def set_text(self, text, *, use_js=False):
# FIXME:qtwebengine what to do about use_js with WebEngine?
raise NotImplementedError
+ def insert_text(self, text):
+ """Insert the given text into the element."""
+ raise NotImplementedError
+
def run_js_async(self, code, callback=None):
"""Run the given JS snippet async on the element."""
# FIXME:qtwebengine get rid of this?
@@ -108,6 +108,13 @@ def set_text(self, text, *, use_js=False):
js_code = javascript.assemble('webelem', 'set_text', self._id, text)
self._tab.run_js_async(js_code)
+ def insert_text(self, text):
+ if not self.is_editable(strict=True):
+ raise webelem.Error("Element is not editable!")
+ log.misc.debug("Inserting text into element {!r}".format(self))
+ js_code = javascript.assemble('webelem', 'insert_text', self._id, text)
+ self._tab.run_js_async(js_code)
+
def run_js_async(self, code, callback=None):
"""Run the given JS snippet async on the element."""
# FIXME:qtwebengine get rid of this?
@@ -135,6 +135,17 @@ def set_text(self, text, *, use_js=False):
text = javascript.string_escape(text)
self._elem.evaluateJavaScript("this.value='{}'".format(text))
+ def insert_text(self, text):
+ if not self.is_editable(strict=True):
+ raise webelem.Error("Element is not editable!")
+ log.misc.debug("Inserting text into element {!r}".format(self))
+ self.run_js_async("""
+ var text = '{}';
+ var event = document.createEvent('TextEvent');
+ event.initTextEvent('textInput', true, true, null, text);
+ this.dispatchEvent(event);
+ """.format(javascript.string_escape(text)))
+
def run_js_async(self, code, callback=None):
"""Run the given JS snippet async on the element."""
self._check_vanished()
@@ -132,6 +132,13 @@ window._qutebrowser.webelem = (function() {
elements[id].value = text;
};
+ funcs.insert_text = function(id, text) {
+ var elem = elements[id];
+ var event = document.createEvent("TextEvent");
+ event.initTextEvent("textInput", true, true, null, text);
+ elem.dispatchEvent(event);
+ };
+
funcs.element_at_pos = function(x, y) {
// FIXME:qtwebengine
// If the element at the specified point belongs to another document
@@ -229,7 +229,6 @@ Feature: Yanking and pasting.
#### :insert-text
- @qtwebengine_todo: :insert-text is not implemented yet
Scenario: Inserting text into an empty text field
When I open data/paste_primary.html
And I run :click-element id qute-textarea
@@ -238,7 +237,6 @@ Feature: Yanking and pasting.
# Compare
Then the text field should contain "Hello world"
- @qtwebengine_todo: :insert-text is not implemented yet
Scenario: Inserting text into a text field at specific position
When I open data/paste_primary.html
And I set the text field to "one two three four"
@@ -252,7 +250,6 @@ Feature: Yanking and pasting.
# Compare
Then the text field should contain "onHello worlde two three four"
- @qtwebengine_todo: :insert-text is not implemented yet
Scenario: Inserting text into a text field with undo
When I open data/paste_primary.html
And I run :click-element id qute-textarea
@@ -265,18 +262,16 @@ Feature: Yanking and pasting.
# Compare
Then the text field should contain "This text should stay"
- @qtwebengine_todo: :insert-text is not implemented yet
Scenario: Inserting text without a focused field
When I open data/paste_primary.html
And I run :enter-mode insert
And I run :insert-text test
Then the error "No element focused!" should be shown
- @qtwebengine_todo: :insert-text is not implemented yet
Scenario: Inserting text with a read-only field
When I open data/paste_primary.html
And I run :click-element id qute-textarea-noedit
And I wait for "Clicked non-editable element!" in the log
And I run :enter-mode insert
And I run :insert-text test
- Then the error "Focused element is not editable!" should be shown
+ Then the error "Element is not editable!" should be shown
@@ -49,8 +49,11 @@ def test_insert_mode(file_name, elem_id, source, input_text, auto_insert,
quteproc.press_keys(input_text)
elif source == 'clipboard':
if request.config.webengine:
- pytest.xfail(reason="QtWebEngine TODO: :insert-text is not "
+ pytest.xfail(reason="QtWebEngine TODO: caret mode is not "
"implemented")
+ # Note we actually run the keypress tests with QtWebEngine, as for
+ # some reason it selects all the text when clicking the field the
+ # second time.
quteproc.send_cmd(':debug-set-fake-clipboard "{}"'.format(input_text))
quteproc.send_cmd(':insert-text {clipboard}')

0 comments on commit 948fa03

Please sign in to comment.