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

This commit is contained in:
Florian Bruhin 2017-12-06 06:51:03 +01:00
commit dcb4448594
7 changed files with 124 additions and 9 deletions

View File

@ -1083,7 +1083,7 @@ Syntax: +:session-save [*--current*] [*--quiet*] [*--force*] [*--only-active-win
Save a session.
==== positional arguments
* +'name'+: The name of the session. If not given, the session configured in session_default_name is saved.
* +'name'+: The name of the session. If not given, the session configured in session.default_name is saved.
==== optional arguments

View File

@ -222,7 +222,7 @@
|<<qt.highdpi,qt.highdpi>>|Turn on Qt HighDPI scaling.
|<<scrolling.bar,scrolling.bar>>|Show a scrollbar.
|<<scrolling.smooth,scrolling.smooth>>|Enable smooth scrolling for web pages.
|<<session_default_name,session_default_name>>|Name of the session to save by default.
|<<session.default_name,session.default_name>>|Name of the session to save by default.
|<<spellcheck.languages,spellcheck.languages>>|Languages to use for spell checking.
|<<statusbar.hide,statusbar.hide>>|Hide the statusbar unless a message is shown.
|<<statusbar.padding,statusbar.padding>>|Padding (in pixels) for the statusbar.
@ -2556,8 +2556,8 @@ Type: <<types,Bool>>
Default: +pass:[false]+
[[session_default_name]]
=== session_default_name
[[session.default_name]]
=== session.default_name
Name of the session to save by default.
If this is set to null, the session which was last loaded is saved.

View File

@ -29,6 +29,7 @@ import os
import time
import textwrap
import mimetypes
import urllib
import pkg_resources
from PyQt5.QtCore import QUrlQuery, QUrl
@ -425,6 +426,18 @@ def qute_settings(url):
return 'text/html', html
@add_handler('back')
def qute_back(url):
"""Handler for qute://back.
Simple page to free ram / lazy load a site, goes back on focusing the tab.
"""
html = jinja.render(
'back.html',
title='Suspended: ' + urllib.parse.unquote(url.fragment()))
return 'text/html', html
@add_handler('configdiff')
def qute_configdiff(url):
"""Handler for qute://configdiff."""

View File

@ -79,6 +79,9 @@ new_instance_open_target_window:
When `new_instance_open_target` is not set to `window`, this is ignored.
session_default_name:
renamed: session.default_name
session.default_name:
type:
name: SessionName
none_ok: true
@ -88,6 +91,11 @@ session_default_name:
If this is set to null, the session which was last loaded is saved.
session.lazy_restore:
type: Bool
default: false
desc: Load a restored tab as soon as it takes focus.
backend:
type:
name: String

View File

@ -0,0 +1,60 @@
{% extends "base.html" %}
{% block script %}
const STATE_BACK = "back";
const STATE_FORWARD = "forward";
function switch_state(new_state) {
history.replaceState(
new_state,
document.title,
location.pathname + location.hash);
}
function go_back() {
switch_state(STATE_FORWARD);
history.back();
}
function go_forward() {
switch_state(STATE_BACK);
history.forward();
}
function prepare_restore() {
if (!document.hidden) {
go_back();
return;
}
document.addEventListener("visibilitychange", go_back);
}
// there are three states
// default: register focus listener,
// on focus: go back and switch to the state forward
// back: user came from a later history entry
// -> switch to the state forward,
// forward him to the previous history entry
// forward: user came from a previous history entry
// -> switch to the state back,
// forward him to the next history entry
switch (history.state) {
case STATE_BACK:
go_back();
break;
case STATE_FORWARD:
go_forward();
break;
default:
setTimeout(prepare_restore, 1000);
break;
}
{% endblock %}
{% block content %}
<noscript><p>Javascript isn't enabled. So you need to manually go back in history to restore this tab.</p></noscript>
<p>Loading suspended page...<br>
<br>
If nothing happens, something went wrong or you disabled JavaScript.</p>
{% endblock %}

View File

@ -21,6 +21,8 @@
import os
import os.path
import itertools
import urllib
import sip
from PyQt5.QtCore import QUrl, QObject, QPoint, QTimer
@ -205,7 +207,13 @@ class SessionManager(QObject):
for idx, item in enumerate(tab.history):
qtutils.ensure_valid(item)
item_data = self._save_tab_item(tab, idx, item)
data['history'].append(item_data)
if item.url().scheme() == 'qute' and item.url().host() == 'back':
# don't add qute://back to the session file
if item_data.get('active', False) and data['history']:
# mark entry before qute://back as active
data['history'][-1]['active'] = True
else:
data['history'].append(item_data)
return data
def _save_all(self, *, only_window=None, with_private=False):
@ -251,7 +259,7 @@ class SessionManager(QObject):
object.
"""
if name is default:
name = config.val.session_default_name
name = config.val.session.default_name
if name is None:
if self._current is not None:
name = self._current
@ -323,7 +331,18 @@ class SessionManager(QObject):
def _load_tab(self, new_tab, data):
"""Load yaml data into a newly opened tab."""
entries = []
for histentry in data['history']:
lazy_load = []
# use len(data['history'])
# -> dropwhile empty if not session.lazy_session
lazy_index = len(data['history'])
gen = itertools.chain(
itertools.takewhile(lambda _: not lazy_load,
enumerate(data['history'])),
enumerate(lazy_load),
itertools.dropwhile(lambda i: i[0] < lazy_index,
enumerate(data['history'])))
for i, histentry in gen:
user_data = {}
if 'zoom' in data:
@ -347,6 +366,20 @@ class SessionManager(QObject):
if 'pinned' in histentry:
new_tab.data.pinned = histentry['pinned']
if (config.val.session.lazy_restore and
histentry.get('active', False) and
not histentry['url'].startswith('qute://back')):
# remove "active" mark and insert back page marked as active
lazy_index = i + 1
lazy_load.append({
'title': histentry['title'],
'url':
'qute://back#' +
urllib.parse.quote(histentry['title']),
'active': True
})
histentry['active'] = False
active = histentry.get('active', False)
url = QUrl.fromEncoded(histentry['url'].encode('ascii'))
if 'original-url' in histentry:
@ -360,6 +393,7 @@ class SessionManager(QObject):
entries.append(entry)
if active:
new_tab.title_changed.emit(histentry['title'])
try:
new_tab.history.load_items(entries)
except ValueError as e:
@ -460,7 +494,7 @@ class SessionManager(QObject):
Args:
name: The name of the session. If not given, the session configured
in session_default_name is saved.
in session.default_name is saved.
current: Save the current session instead of the default.
quiet: Don't show confirmation message.
force: Force saving internal sessions (starting with an underline).

View File

@ -170,7 +170,7 @@ class TestSaveAll:
])
def test_get_session_name(config_stub, sess_man, arg, config, current,
expected):
config_stub.val.session_default_name = config
config_stub.val.session.default_name = config
sess_man._current = current
assert sess_man._get_session_name(arg) == expected