Add tab.caret.follow_selected()
This commit is contained in:
parent
1148184892
commit
4d650c8dfd
@ -25,7 +25,6 @@ import sys
|
|||||||
import shlex
|
import shlex
|
||||||
import posixpath
|
import posixpath
|
||||||
import functools
|
import functools
|
||||||
import xml.etree.ElementTree
|
|
||||||
|
|
||||||
from PyQt5.QtWebKit import QWebSettings
|
from PyQt5.QtWebKit import QWebSettings
|
||||||
from PyQt5.QtWidgets import QApplication, QTabBar
|
from PyQt5.QtWidgets import QApplication, QTabBar
|
||||||
@ -40,6 +39,7 @@ import pygments.formatters
|
|||||||
from qutebrowser.commands import userscripts, cmdexc, cmdutils, runners
|
from qutebrowser.commands import userscripts, cmdexc, cmdutils, runners
|
||||||
from qutebrowser.config import config, configexc
|
from qutebrowser.config import config, configexc
|
||||||
from qutebrowser.browser import urlmarks
|
from qutebrowser.browser import urlmarks
|
||||||
|
from qutebrowser.browser import tab as tabmod
|
||||||
from qutebrowser.browser.webkit import webelem, inspector, downloads, mhtml
|
from qutebrowser.browser.webkit import webelem, inspector, downloads, mhtml
|
||||||
from qutebrowser.keyinput import modeman
|
from qutebrowser.keyinput import modeman
|
||||||
from qutebrowser.utils import (message, usertypes, log, qtutils, urlutils,
|
from qutebrowser.utils import (message, usertypes, log, qtutils, urlutils,
|
||||||
@ -1107,30 +1107,10 @@ class CommandDispatcher:
|
|||||||
Args:
|
Args:
|
||||||
tab: Load the selected link in a new tab.
|
tab: Load the selected link in a new tab.
|
||||||
"""
|
"""
|
||||||
widget = self._current_widget()
|
try:
|
||||||
if not widget.caret.has_selection():
|
self._current_widget().caret.follow_selected(tab=tab)
|
||||||
return
|
except tabmod.WebTabError as e:
|
||||||
if QWebSettings.globalSettings().testAttribute(
|
raise cmdexc.CommandError(str(e))
|
||||||
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)
|
|
||||||
|
|
||||||
@cmdutils.register(instance='command-dispatcher', name='inspector',
|
@cmdutils.register(instance='command-dispatcher', name='inspector',
|
||||||
scope='window')
|
scope='window')
|
||||||
|
@ -32,6 +32,10 @@ from qutebrowser.utils import utils, objreg, usertypes
|
|||||||
tab_id_gen = itertools.count(0)
|
tab_id_gen = itertools.count(0)
|
||||||
|
|
||||||
|
|
||||||
|
class WebTabError(Exception):
|
||||||
|
|
||||||
|
"""Base class for various errors."""
|
||||||
|
|
||||||
|
|
||||||
class WrapperLayout(QLayout):
|
class WrapperLayout(QLayout):
|
||||||
|
|
||||||
@ -188,8 +192,9 @@ class AbstractCaret(QObject):
|
|||||||
|
|
||||||
"""Attribute of AbstractTab for caret browsing."""
|
"""Attribute of AbstractTab for caret browsing."""
|
||||||
|
|
||||||
def __init__(self, win_id, parent=None):
|
def __init__(self, win_id, tab, parent=None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
|
self._tab = tab
|
||||||
self._win_id = win_id
|
self._win_id = win_id
|
||||||
self._widget = None
|
self._widget = None
|
||||||
self.selection_enabled = False
|
self.selection_enabled = False
|
||||||
@ -261,6 +266,9 @@ class AbstractCaret(QObject):
|
|||||||
def selection(self, html=False):
|
def selection(self, html=False):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def follow_selected(self, tab=False):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
class AbstractScroller(QObject):
|
class AbstractScroller(QObject):
|
||||||
|
|
||||||
@ -398,7 +406,7 @@ class AbstractTab(QWidget):
|
|||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
# self.history = AbstractHistory(self)
|
# self.history = AbstractHistory(self)
|
||||||
# self.scroll = AbstractScroller(parent=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.zoom = AbstractZoom(win_id=win_id)
|
||||||
# self.search = AbstractSearch(parent=self)
|
# self.search = AbstractSearch(parent=self)
|
||||||
self._layout = None
|
self._layout = None
|
||||||
@ -462,10 +470,6 @@ class AbstractTab(QWidget):
|
|||||||
def icon(self):
|
def icon(self):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def set_open_target(self, target):
|
|
||||||
"""Select where the next navigation request should open."""
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
url = utils.elide(self.cur_url.toDisplayString(QUrl.EncodeUnicode),
|
url = utils.elide(self.cur_url.toDisplayString(QUrl.EncodeUnicode),
|
||||||
100)
|
100)
|
||||||
|
@ -102,7 +102,7 @@ class WebEngineViewTab(tab.AbstractTab):
|
|||||||
widget = QWebEngineView()
|
widget = QWebEngineView()
|
||||||
self.history = WebEngineHistory(self)
|
self.history = WebEngineHistory(self)
|
||||||
self.scroll = WebEngineScroller()
|
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.zoom = WebEngineZoom(win_id=win_id, parent=self)
|
||||||
self.search = WebEngineSearch(parent=self)
|
self.search = WebEngineSearch(parent=self)
|
||||||
self._set_widget(widget)
|
self._set_widget(widget)
|
||||||
@ -155,9 +155,6 @@ class WebEngineViewTab(tab.AbstractTab):
|
|||||||
def icon(self):
|
def icon(self):
|
||||||
return self._widget.icon()
|
return self._widget.icon()
|
||||||
|
|
||||||
def set_open_target(self, target):
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
def _connect_signals(self):
|
def _connect_signals(self):
|
||||||
view = self._widget
|
view = self._widget
|
||||||
page = view.page()
|
page = view.page()
|
||||||
|
@ -20,8 +20,9 @@
|
|||||||
"""Wrapper over our (QtWebKit) WebView."""
|
"""Wrapper over our (QtWebKit) WebView."""
|
||||||
|
|
||||||
import sys
|
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.QtGui import QKeyEvent
|
||||||
from PyQt5.QtWebKitWidgets import QWebPage
|
from PyQt5.QtWebKitWidgets import QWebPage
|
||||||
from PyQt5.QtWebKit import QWebSettings
|
from PyQt5.QtWebKit import QWebSettings
|
||||||
@ -260,6 +261,32 @@ class WebViewCaret(tab.AbstractCaret):
|
|||||||
return self._widget.selectedHtml()
|
return self._widget.selectedHtml()
|
||||||
return self._widget.selectedText()
|
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):
|
class WebViewZoom(tab.AbstractZoom):
|
||||||
|
|
||||||
@ -411,7 +438,7 @@ class WebViewTab(tab.AbstractTab):
|
|||||||
widget = webview.WebView(win_id, self.tab_id, tab=self)
|
widget = webview.WebView(win_id, self.tab_id, tab=self)
|
||||||
self.history = WebViewHistory(self)
|
self.history = WebViewHistory(self)
|
||||||
self.scroll = WebViewScroller(parent=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.zoom = WebViewZoom(win_id=win_id, parent=self)
|
||||||
self.search = WebViewSearch(parent=self)
|
self.search = WebViewSearch(parent=self)
|
||||||
self._set_widget(widget)
|
self._set_widget(widget)
|
||||||
@ -464,9 +491,6 @@ class WebViewTab(tab.AbstractTab):
|
|||||||
def title(self):
|
def title(self):
|
||||||
return self._widget.title()
|
return self._widget.title()
|
||||||
|
|
||||||
def set_open_target(self, target):
|
|
||||||
self._widget.page().open_target = target
|
|
||||||
|
|
||||||
def _connect_signals(self):
|
def _connect_signals(self):
|
||||||
view = self._widget
|
view = self._widget
|
||||||
page = view.page()
|
page = view.page()
|
||||||
|
Loading…
Reference in New Issue
Block a user