Simplify check for orphaned editor.

Instead of rewiring signals on tab.shutting_down, have the webelem check
if its parent tab is deleted, and throw a specific exception.

This is only necessary in WebEngine, Webkit does not crash when the
editor is orphaned.

I tried to write a test for is_deleted, but could not get it to pass:
```
def test_is_deleted(qtbot, view, config_stub, tab_registry, mode_manager):
    tab_w = Tab(win_id=0, mode_manager=mode_manager)
    qtbot.add_widget(tab_w)
    tab_w._set_widget(view)
    assert not tab_w.is_deleted()
    sip.delete(view)
    #assert tab_w.is_deleted()
```

The qtbot post-test cleanup would error due to the deleted view.
This commit is contained in:
Ryan Roden-Corrent 2017-11-29 07:01:48 -05:00
parent 01a9405391
commit e09a8c77e9
4 changed files with 15 additions and 8 deletions

View File

@ -22,6 +22,7 @@
import enum
import itertools
import sip
import attr
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QUrl, QObject, QSizeF, Qt
from PyQt5.QtGui import QIcon
@ -864,3 +865,6 @@ class AbstractTab(QWidget):
except (AttributeError, RuntimeError) as exc:
url = '<{}>'.format(exc.__class__.__name__)
return utils.get_repr(self, tab_id=self.tab_id, url=url)
def is_deleted(self):
return sip.isdeleted(self._widget)

View File

@ -1621,9 +1621,6 @@ class CommandDispatcher:
ed = editor.ExternalEditor(self._tabbed_browser)
ed.editing_finished.connect(functools.partial(
self.on_editing_finished, elem))
tab = self._current_widget()
tab.shutting_down.connect(functools.partial(
self.on_editor_orphaned, ed))
ed.edit(text, caret_position)
@cmdutils.register(instance='command-dispatcher', scope='window')
@ -1647,14 +1644,11 @@ class CommandDispatcher:
"""
try:
elem.set_value(text)
except webelem.OrphanedError as e:
message.warning('Edited element vanished')
except webelem.Error as e:
raise cmdexc.CommandError(str(e))
def on_editor_orphaned(self, ed):
ed.editing_finished.disconnect()
ed.editing_finished.connect(
lambda: message.warning('Edited element vanished'))
@cmdutils.register(instance='command-dispatcher', maxsplit=0,
scope='window')
def insert_text(self, text):

View File

@ -60,6 +60,13 @@ class Error(Exception):
pass
class OrphanedError(Exception):
"""Raised when a webelement's parent has vanished."""
pass
class AbstractWebElement(collections.abc.MutableMapping):
"""A wrapper around QtWebKit/QtWebEngine web element.

View File

@ -100,6 +100,8 @@ class WebEngineElement(webelem.AbstractWebElement):
def _js_call(self, name, *args, callback=None):
"""Wrapper to run stuff from webelem.js."""
if self._tab.is_deleted():
raise webelem.OrphanedError("Tab containing element vanished")
js_code = javascript.assemble('webelem', name, self._id, *args)
self._tab.run_js_async(js_code, callback=callback)