From 851f473e0cb7f83821c2218584aa2add728c17cd Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sun, 4 May 2014 01:06:52 +0200 Subject: [PATCH] Add more webkit settings --- qutebrowser/config/_conftypes.py | 104 +++++++++++++++++++++++++++++- qutebrowser/config/configdata.py | 71 ++++++++++++++++++++ qutebrowser/config/websettings.py | 43 ++++++++++-- 3 files changed, 210 insertions(+), 8 deletions(-) diff --git a/qutebrowser/config/_conftypes.py b/qutebrowser/config/_conftypes.py index afd9f91b8..ed361e588 100644 --- a/qutebrowser/config/_conftypes.py +++ b/qutebrowser/config/_conftypes.py @@ -268,6 +268,22 @@ class Int(BaseType): self.maxval)) +class NoneInt(BaseType): + + """Int or None.""" + + def transform(self, value): + if value == '': + return None + else: + return super().transform(value) + + def validate(self, value): + if value == '': + return + super().validate(value) + + class Float(BaseType): """Base class for an float setting. @@ -440,6 +456,88 @@ class PercOrInt(BaseType): self.maxint)) +class WebKitBytes(BaseType): + + """A size with an optional suffix. + + Attributes: + maxsize: The maximum size to be used. + + Class attributes: + SUFFIXES: A mapping of size suffixes to multiplicators. + """ + + SUFFIXES = { + 'k': 1024 ** 1, + 'm': 1024 ** 2, + 'g': 1024 ** 3, + 't': 1024 ** 4, + 'p': 1024 ** 5, + 'e': 1024 ** 6, + 'z': 1024 ** 7, + 'y': 1024 ** 8, + } + + def __init__(self, maxsize=None): + self.maxsize = maxsize + + def validate(self, value): + if value == '': + return + try: + val = self.transform(value) + except ValueError: + raise ValidationError(value, "must be a valid integer with " + "optional suffix!") + if self.maxsize is not None and val > self.maxsize: + raise ValidationError(value, "must be {} " + "maximum!".format(self.maxsize)) + + def transform(self, value): + if value == '': + return None + if any(value.lower().endswith(c) for c in self.SUFFIXES): + suffix = value[-1].lower() + val = value[:-1] + multiplicator = self.SUFFIXES[suffix] + else: + val = value + multiplicator = 1 + return int(val) * multiplicator + + +class WebKitBytesList(List): + + """A size with an optional suffix. + + Attributes: + length: The length of the list. + bytestype: The webkit bytes type. + """ + + def __init__(self, maxsize=None, length=None): + self.length = length + self.bytestype = WebKitBytes(maxsize) + + def transform(self, value): + if value == '': + return None + vals = super().transform(value) + return [self.bytestype.transform(val) for val in vals] + + def validate(self, value): + if value == '': + return + vals = super().transform(value) + for val in vals: + self.bytestype.validate(val) + if any(val is None for val in vals): + raise ValidationError(value, "all values need to be set!") + if self.length is not None and len(vals) != self.length: + raise ValidationError(value, "exactly {} values need to be " + "set!".format(self.length)) + + class Command(BaseType): """Base class for a command value with arguments.""" @@ -582,14 +680,14 @@ class WebSettingsFile(File): """QWebSettings file which also can be none.""" def validate(self, value): - if not value: + if value == '': # empty values are okay return super().validate(value) def transform(self, value): - if value is None: - return value + if value == '': + return None else: return QUrl.fromLocalFile(value) diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index 73d9bf05f..41f9c8e5a 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -25,6 +25,7 @@ DATA: The config defaults, an OrderedDict of sections. """ import re +import struct from collections import OrderedDict from qutebrowser.config._value import SettingValue @@ -32,6 +33,10 @@ import qutebrowser.config._conftypes as types import qutebrowser.config._sections as sect +INT_MAX = 2 ** (8 * struct.calcsize('@i')) // 2 - 1 +INT64_MAX = 2 ** 64 // 2 - 1 + + FIRST_COMMENT = r""" # vim: ft=dosini @@ -403,6 +408,72 @@ DATA = OrderedDict([ ('user-stylesheet', SettingValue(types.WebSettingsFile(), ''), "User stylesheet to set."), + + ('css-media-type', + SettingValue(types.String(), ''), + "Set the CSS media type."), + + ('default-encoding', + SettingValue(types.String(), ''), + "Default encoding to use for websites."), + + ('font-family-standard', + SettingValue(types.String(), ''), + "Font family for standard fonts."), + + ('font-family-fixed', + SettingValue(types.String(), ''), + "Font family for fixed fonts."), + + ('font-family-serif', + SettingValue(types.String(), ''), + "Font family for serif fonts."), + + ('font-family-sans-serif', + SettingValue(types.String(), ''), + "Font family for sans-serif fonts."), + + ('font-family-cursive', + SettingValue(types.String(), ''), + "Font family for cursive fonts."), + + ('font-family-fantasy', + SettingValue(types.String(), ''), + "Font family for fantasy fonts."), + + ('font-size-minimum', + SettingValue(types.String(), ''), + "The hard minimum font size."), + + ('font-size-minimum-logical', + SettingValue(types.String(), ''), + "The minimum logical font size that is applied when zooming out."), + + ('font-size-default', + SettingValue(types.String(), ''), + "The default font size for regular text."), + + ('font-size-default-fixed', + SettingValue(types.String(), ''), + "The default font size for fixed-pitch text."), + + ('maximum-pages-in-cache', + SettingValue(types.NoneInt(), ''), + "The default font size for fixed-pitch text."), + + ('object-cache-capacities', + SettingValue(types.WebKitBytesList(length=3, maxsize=INT_MAX), ''), + "Specifies the capacities for the memory cache for dead objects " + "such as stylesheets or scripts. Three values are expected: " + "cacheMinDeadCapacity, cacheMaxDead, totalCapacity"), + + ('offline-storage-default-quota', + SettingValue(types.WebKitBytes(maxsize=INT64_MAX), ''), + "Default quota for new offline storage databases."), + + ('offline-web-application-cache-quota', + SettingValue(types.WebKitBytes(maxsize=INT64_MAX), ''), + "Quota for the offline web application cache>"), )), ('hints', sect.KeyValue( diff --git a/qutebrowser/config/websettings.py b/qutebrowser/config/websettings.py index 1eb2fb043..ce2ea4895 100644 --- a/qutebrowser/config/websettings.py +++ b/qutebrowser/config/websettings.py @@ -66,10 +66,38 @@ ATTRIBUTES = { SETTERS = { - 'user-stylesheet': 'setUserStyleSheetUrl' + 'user-stylesheet': + lambda qws, v: qws.setUserStyleSheetUrl(v), + 'css-media-type': + lambda qws, v: qws.setCSSMediaType(v), + 'default-encoding': + lambda qws, v: qws.setDefaultTextEncoding(v), + 'font-family-standard': + lambda qws, v: qws.setFontFamily(QWebSettings.StandardFont, v), + 'font-family-fixed': + lambda qws, v: qws.setFontFamily(QWebSettings.FixedFont, v), + 'font-family-serif': + lambda qws, v: qws.setFontFamily(QWebSettings.SerifFont, v), + 'font-family-sans-serif': + lambda qws, v: qws.setFontFamily(QWebSettings.SansSerifFont, v), + 'font-family-cursive': + lambda qws, v: qws.setFontFamily(QWebSettings.CursiveFont, v), + 'font-family-fantasy': + lambda qws, v: qws.setFontFamily(QWebSettings.FantasyFont, v), } +STATIC_SETTERS = { + 'maximum-pages-in-cache': + lambda v: QWebSettings.setMaximumPagesInCache(v), + 'object-cache-capacities': + lambda v: QWebSettings.setObjectCacheCapacities(*v), + 'offline-storage-default-quota': + lambda v: QWebSettings.setOfflineStorageDefaultQuota(v), + 'offline-web-application-cache-quota': + lambda v: QWebSettings.setOfflineWebApplicationCacheQuota(v), +} + settings = None @@ -79,10 +107,13 @@ def init(): settings = QWebSettings.globalSettings() for name, item in ATTRIBUTES.items(): settings.setAttribute(item, config.get('webkit', name)) - for name, method in SETTERS.items(): + for name, setter in SETTERS.items(): + value = config.get('webkit', name) + if value is not None: + setter(settings, value) + for name, setter in STATIC_SETTERS.items(): value = config.get('webkit', name) if value is not None: - setter = getattr(settings, method) setter(value) @@ -90,9 +121,11 @@ def init(): def on_config_changed(section, option): """Update global settings when qwebsettings changed.""" if section == 'webkit': + settings = QWebSettings.globalSettings() value = config.get(section, option) if option in ATTRIBUTES: settings.setAttribute(ATTRIBUTES[option], value) elif option in SETTERS and value is not None: - setter = getattr(settings, SETTERS[option]) - setter(value) + SETTERS[option](settings, value) + elif option in STATIC_SETTERS and value is not None: + STATIC_SETTERS[option](value)