Make it possible to use CSS strings in ui->user-stylesheet.

This commit is contained in:
Florian Bruhin 2014-09-19 00:35:17 +02:00
parent 36e916e247
commit 1bc5160453
3 changed files with 44 additions and 11 deletions

View File

@ -268,7 +268,7 @@ DATA = collections.OrderedDict([
"This will flatten all the frames to become one scrollable page."), "This will flatten all the frames to become one scrollable page."),
('user-stylesheet', ('user-stylesheet',
SettingValue(typ.WebSettingsFile(), ''), SettingValue(typ.UserStyleSheet(), ''),
"User stylesheet to use."), "User stylesheet to use."),
('css-media-type', ('css-media-type',

View File

@ -21,6 +21,7 @@
import re import re
import shlex import shlex
import base64
import codecs import codecs
import os.path import os.path
import sre_constants import sre_constants
@ -1082,20 +1083,43 @@ class Encoding(BaseType):
raise ValidationError(value, "is not a valid encoding!") raise ValidationError(value, "is not a valid encoding!")
class WebSettingsFile(File): class UserStyleSheet(File):
"""QWebSettings file.""" """QWebSettings UserStyleSheet."""
typestr = 'file' typestr = 'user-stylesheet'
def __init__(self): def __init__(self):
super().__init__(none_ok=True) super().__init__(none_ok=True)
def validate(self, value):
if not value:
if self.none_ok:
return
else:
raise ValidationError(value, "may not be empty!")
value = os.path.expanduser(value)
if not os.path.isabs(value):
# probably a CSS, so we don't handle it as filename.
# FIXME We just try if it is encodable, maybe we should validate
# CSS?
try:
value.encode('utf-8')
except UnicodeEncodeError as e:
raise ValidationError(value, str(e))
return
elif not os.path.isfile(value):
raise ValidationError(value, "must be a valid file!")
def transform(self, value): def transform(self, value):
path = os.path.expanduser(value)
if not value: if not value:
return None return None
elif os.path.isabs(path):
return QUrl.fromLocalFile(path)
else: else:
return QUrl.fromLocalFile(value) data = base64.b64encode(value.encode('utf-8')).decode('ascii')
return QUrl("data:text/css;charset=utf-8;base64,{}".format(data))
class AutoSearch(BaseType): class AutoSearch(BaseType):

View File

@ -21,6 +21,8 @@
import unittest import unittest
import re import re
import collections import collections
import os.path
import base64
from unittest import mock from unittest import mock
from qutebrowser.config import configtypes from qutebrowser.config import configtypes
@ -1759,20 +1761,27 @@ class KeyBindingNameTests(unittest.TestCase):
self.assertEqual(self.t.transform("foobar"), "foobar") self.assertEqual(self.t.transform("foobar"), "foobar")
class WebSettingsFileTests(unittest.TestCase): class UserStyleSheetTests(unittest.TestCase):
"""Test WebSettingsFile.""" """Test UserStyleSheet."""
def setUp(self): def setUp(self):
self.t = configtypes.WebSettingsFile() self.t = configtypes.UserStyleSheet()
def test_transform_empty(self): def test_transform_empty(self):
"""Test transform with an empty value.""" """Test transform with an empty value."""
self.assertIsNone(self.t.transform('')) self.assertIsNone(self.t.transform(''))
def test_transform(self): def test_transform_file(self):
"""Test transform with a value.""" """Test transform with a filename."""
self.assertEqual(self.t.transform("/foo/bar"), QUrl("file:///foo/bar")) path = os.path.join(os.path.sep, 'foo', 'bar')
self.assertEqual(self.t.transform(path), QUrl("file:///foo/bar"))
def test_transform_base64(self):
"""Test transform with a data string."""
b64 = base64.b64encode(b"test").decode('ascii')
url = QUrl("data:text/css;charset=utf-8;base64,{}".format(b64))
self.assertEqual(self.t.transform("test"), url)
class AutoSearchTests(unittest.TestCase): class AutoSearchTests(unittest.TestCase):