Add tab.caret.follow_selected()

This commit is contained in:
Florian Bruhin 2016-07-04 13:35:38 +02:00
parent 1148184892
commit 4d650c8dfd
4 changed files with 45 additions and 40 deletions

View File

@ -25,7 +25,6 @@ import sys
import shlex
import posixpath
import functools
import xml.etree.ElementTree
from PyQt5.QtWebKit import QWebSettings
from PyQt5.QtWidgets import QApplication, QTabBar
@ -40,6 +39,7 @@ import pygments.formatters
from qutebrowser.commands import userscripts, cmdexc, cmdutils, runners
from qutebrowser.config import config, configexc
from qutebrowser.browser import urlmarks
from qutebrowser.browser import tab as tabmod
from qutebrowser.browser.webkit import webelem, inspector, downloads, mhtml
from qutebrowser.keyinput import modeman
from qutebrowser.utils import (message, usertypes, log, qtutils, urlutils,
@ -1107,30 +1107,10 @@ class CommandDispatcher:
Args:
tab: Load the selected link in a new tab.
"""
widget = self._current_widget()
if not widget.caret.has_selection():
return
if QWebSettings.globalSettings().testAttribute(
QWebSettings.JavascriptEnabled):
if tab:
widget.set_open_target(usertypes.ClickTarget.tab)
widget.run_js_async(
'window.getSelection().anchorNode.parentNode.click()')
else:
selection = widget.caret.selection(html=True)
try:
selected_element = xml.etree.ElementTree.fromstring(
'<html>{}</html>'.format(selection)).find('a')
except xml.etree.ElementTree.ParseError:
raise cmdexc.CommandError('Could not parse selected element!')
if selected_element is not None:
try:
url = selected_element.attrib['href']
except KeyError:
raise cmdexc.CommandError('Anchor element without href!')
url = self._current_url().resolved(QUrl(url))
self._open(url, tab)
self._current_widget().caret.follow_selected(tab=tab)
except tabmod.WebTabError as e:
raise cmdexc.CommandError(str(e))
@cmdutils.register(instance='command-dispatcher', name='inspector',
scope='window')

View File

@ -32,6 +32,10 @@ from qutebrowser.utils import utils, objreg, usertypes
tab_id_gen = itertools.count(0)
class WebTabError(Exception):
"""Base class for various errors."""
class WrapperLayout(QLayout):
@ -188,8 +192,9 @@ class AbstractCaret(QObject):
"""Attribute of AbstractTab for caret browsing."""
def __init__(self, win_id, parent=None):
def __init__(self, win_id, tab, parent=None):
super().__init__(parent)
self._tab = tab
self._win_id = win_id
self._widget = None
self.selection_enabled = False
@ -261,6 +266,9 @@ class AbstractCaret(QObject):
def selection(self, html=False):
raise NotImplementedError
def follow_selected(self, tab=False):
raise NotImplementedError
class AbstractScroller(QObject):
@ -398,7 +406,7 @@ class AbstractTab(QWidget):
super().__init__(parent)
# self.history = AbstractHistory(self)
# self.scroll = AbstractScroller(parent=self)
# self.caret = AbstractCaret(win_id=win_id, parent=self)
# self.caret = AbstractCaret(win_id=win_id, tab=self, parent=self)
# self.zoom = AbstractZoom(win_id=win_id)
# self.search = AbstractSearch(parent=self)
self._layout = None
@ -462,10 +470,6 @@ class AbstractTab(QWidget):
def icon(self):
raise NotImplementedError
def set_open_target(self, target):
"""Select where the next navigation request should open."""
raise NotImplementedError
def __repr__(self):
url = utils.elide(self.cur_url.toDisplayString(QUrl.EncodeUnicode),
100)

View File

@ -102,7 +102,7 @@ class WebEngineViewTab(tab.AbstractTab):
widget = QWebEngineView()
self.history = WebEngineHistory(self)
self.scroll = WebEngineScroller()
self.caret = WebEngineCaret(win_id=win_id, parent=self)
self.caret = WebEngineCaret(win_id=win_id, tab=self, parent=self)
self.zoom = WebEngineZoom(win_id=win_id, parent=self)
self.search = WebEngineSearch(parent=self)
self._set_widget(widget)
@ -155,9 +155,6 @@ class WebEngineViewTab(tab.AbstractTab):
def icon(self):
return self._widget.icon()
def set_open_target(self, target):
raise NotImplementedError
def _connect_signals(self):
view = self._widget
page = view.page()

View File

@ -20,8 +20,9 @@
"""Wrapper over our (QtWebKit) WebView."""
import sys
import xml.etree.ElementTree
from PyQt5.QtCore import pyqtSlot, Qt, QEvent
from PyQt5.QtCore import pyqtSlot, Qt, QEvent, QUrl
from PyQt5.QtGui import QKeyEvent
from PyQt5.QtWebKitWidgets import QWebPage
from PyQt5.QtWebKit import QWebSettings
@ -260,6 +261,32 @@ class WebViewCaret(tab.AbstractCaret):
return self._widget.selectedHtml()
return self._widget.selectedText()
def follow_selected(self, *, tab=False):
if not self.has_selection():
return
if QWebSettings.globalSettings().testAttribute(
QWebSettings.JavascriptEnabled):
if tab:
self._widget.page().open_target = usertypes.ClickTarget.tab
self._tab.run_js_async(
'window.getSelection().anchorNode.parentNode.click()')
else:
selection = self.selection(html=True)
try:
selected_element = xml.etree.ElementTree.fromstring(
'<html>{}</html>'.format(selection)).find('a')
except xml.etree.ElementTree.ParseError:
raise tab.WebTabError('Could not parse selected element!')
if selected_element is not None:
try:
url = selected_element.attrib['href']
except KeyError:
raise tab.WebTabError('Anchor element without href!')
url = self._tab.cur_url.resolved(QUrl(url))
# FIXME(refactoring) does this open in a new tab?
self._tab.openurl(url)
class WebViewZoom(tab.AbstractZoom):
@ -411,7 +438,7 @@ class WebViewTab(tab.AbstractTab):
widget = webview.WebView(win_id, self.tab_id, tab=self)
self.history = WebViewHistory(self)
self.scroll = WebViewScroller(parent=self)
self.caret = WebViewCaret(win_id=win_id, parent=self)
self.caret = WebViewCaret(win_id=win_id, tab=self, parent=self)
self.zoom = WebViewZoom(win_id=win_id, parent=self)
self.search = WebViewSearch(parent=self)
self._set_widget(widget)
@ -464,9 +491,6 @@ class WebViewTab(tab.AbstractTab):
def title(self):
return self._widget.title()
def set_open_target(self, target):
self._widget.page().open_target = target
def _connect_signals(self):
view = self._widget
page = view.page()