Add config options for geolocation/notifications.

This commit is contained in:
Florian Bruhin 2015-02-10 21:09:08 +01:00
parent 43c9d69295
commit e44c5aee5b
4 changed files with 109 additions and 42 deletions

View File

@ -121,6 +121,8 @@
|<<content-allow-images,allow-images>>|Whether images are automatically loaded in web pages. |<<content-allow-images,allow-images>>|Whether images are automatically loaded in web pages.
|<<content-allow-javascript,allow-javascript>>|Enables or disables the running of JavaScript programs. |<<content-allow-javascript,allow-javascript>>|Enables or disables the running of JavaScript programs.
|<<content-allow-plugins,allow-plugins>>|Enables or disables plugins in Web pages. |<<content-allow-plugins,allow-plugins>>|Enables or disables plugins in Web pages.
|<<content-geolocation,geolocation>>|Allow websites to request geolocations.
|<<content-notifications,notifications>>|Allow websites to show notifications.
|<<content-javascript-can-open-windows,javascript-can-open-windows>>|Whether JavaScript programs can open new windows. |<<content-javascript-can-open-windows,javascript-can-open-windows>>|Whether JavaScript programs can open new windows.
|<<content-javascript-can-close-windows,javascript-can-close-windows>>|Whether JavaScript programs can close windows. |<<content-javascript-can-close-windows,javascript-can-close-windows>>|Whether JavaScript programs can close windows.
|<<content-javascript-can-access-clipboard,javascript-can-access-clipboard>>|Whether JavaScript programs can read or write to the clipboard. |<<content-javascript-can-access-clipboard,javascript-can-access-clipboard>>|Whether JavaScript programs can read or write to the clipboard.
@ -995,6 +997,30 @@ Valid values:
Default: +pass:[false]+ Default: +pass:[false]+
[[content-geolocation]]
=== geolocation
Allow websites to request geolocations.
Valid values:
* +true+
* +false+
* +ask+
Default: +pass:[ask]+
[[content-notifications]]
=== notifications
Allow websites to show notifications.
Valid values:
* +true+
* +false+
* +ask+
Default: +pass:[ask]+
[[content-javascript-can-open-windows]] [[content-javascript-can-open-windows]]
=== javascript-can-open-windows === javascript-can-open-windows
Whether JavaScript programs can open new windows. Whether JavaScript programs can open new windows.

View File

@ -285,39 +285,48 @@ class BrowserPage(QWebPage):
@pyqtSlot('QWebFrame', 'QWebPage::Feature') @pyqtSlot('QWebFrame', 'QWebPage::Feature')
def on_feature_permission_requested(self, frame, feature): def on_feature_permission_requested(self, frame, feature):
"""Ask the user for approval for geolocation/notifications.""" """Ask the user for approval for geolocation/notifications."""
bridge = objreg.get('message-bridge', scope='window', options = {
window=self._win_id) QWebPage.Notifications: ('content', 'notifications'),
q = usertypes.Question(bridge) QWebPage.Geolocation: ('content', 'geolocation'),
q.mode = usertypes.PromptMode.yesno
msgs = {
QWebPage.Notifications: 'show notifications',
QWebPage.Geolocation: 'access your location',
} }
host = frame.url().host() if config.get(*options[feature]) == 'ask':
if host: bridge = objreg.get('message-bridge', scope='window',
q.text = "Allow the website at {} to {}?".format( window=self._win_id)
frame.url().host(), msgs[feature]) q = usertypes.Question(bridge)
q.mode = usertypes.PromptMode.yesno
msgs = {
QWebPage.Notifications: 'show notifications',
QWebPage.Geolocation: 'access your location',
}
host = frame.url().host()
if host:
q.text = "Allow the website at {} to {}?".format(
frame.url().host(), msgs[feature])
else:
q.text = "Allow the website to {}?".format(msgs[feature])
yes_action = functools.partial(
self.setFeaturePermission, frame, feature,
QWebPage.PermissionGrantedByUser)
q.answered_yes.connect(yes_action)
no_action = functools.partial(
self.setFeaturePermission, frame, feature,
QWebPage.PermissionDeniedByUser)
q.answered_no.connect(no_action)
q.completed.connect(q.deleteLater)
self.featurePermissionRequestCanceled.connect(functools.partial(
self.on_feature_permission_cancelled, q, frame, feature))
self.loadStarted.connect(q.abort)
bridge.ask(q, blocking=False)
else: else:
q.text = "Allow the website to {}?".format(msgs[feature]) self.setFeaturePermission(frame, feature,
QWebPage.PermissionDeniedByUser)
yes_action = functools.partial(
self.setFeaturePermission, frame, feature,
QWebPage.PermissionGrantedByUser)
q.answered_yes.connect(yes_action)
no_action = functools.partial(
self.setFeaturePermission, frame, feature,
QWebPage.PermissionDeniedByUser)
q.answered_no.connect(no_action)
q.completed.connect(q.deleteLater)
self.featurePermissionRequestCanceled.connect(functools.partial(
self.on_feature_permission_cancelled, q, frame, feature))
self.loadStarted.connect(q.abort)
bridge.ask(q, blocking=False)
def on_feature_permission_cancelled(self, question, frame, feature, def on_feature_permission_cancelled(self, question, frame, feature,
cancelled_frame, cancelled_feature): cancelled_frame, cancelled_feature):

View File

@ -498,6 +498,14 @@ DATA = collections.OrderedDict([
'Qt plugins with a mimetype such as "application/x-qt-plugin" are ' 'Qt plugins with a mimetype such as "application/x-qt-plugin" are '
"not affected by this setting."), "not affected by this setting."),
('geolocation',
SettingValue(typ.NoAsk(), 'ask'),
"Allow websites to request geolocations."),
('notifications',
SettingValue(typ.NoAsk(), 'ask'),
"Allow websites to show notifications."),
#('allow-java', #('allow-java',
# SettingValue(typ.Bool(), 'true'), # SettingValue(typ.Bool(), 'true'),
# "Enables or disables Java applets. Currently Java applets are " # "Enables or disables Java applets. Currently Java applets are "

View File

@ -38,6 +38,10 @@ from qutebrowser.config import configexc
SYSTEM_PROXY = object() # Return value for Proxy type SYSTEM_PROXY = object() # Return value for Proxy type
# Taken from configparser
BOOLEAN_STATES = {'1': True, 'yes': True, 'true': True, 'on': True,
'0': False, 'no': False, 'false': False, 'off': False}
class ValidValues: class ValidValues:
@ -221,25 +225,17 @@ class List(BaseType):
class Bool(BaseType): class Bool(BaseType):
"""Base class for a boolean setting. """Base class for a boolean setting."""
Class attributes:
_BOOLEAN_STATES: A dictionary of strings mapped to their bool meanings.
"""
typestr = 'bool' typestr = 'bool'
# Taken from configparser
_BOOLEAN_STATES = {'1': True, 'yes': True, 'true': True, 'on': True,
'0': False, 'no': False, 'false': False, 'off': False}
valid_values = ValidValues('true', 'false') valid_values = ValidValues('true', 'false')
def transform(self, value): def transform(self, value):
if not value: if not value:
return None return None
else: else:
return Bool._BOOLEAN_STATES[value.lower()] return BOOLEAN_STATES[value.lower()]
def validate(self, value): def validate(self, value):
if not value: if not value:
@ -247,7 +243,7 @@ class Bool(BaseType):
return return
else: else:
raise configexc.ValidationError(value, "may not be empty!") raise configexc.ValidationError(value, "may not be empty!")
if value.lower() not in Bool._BOOLEAN_STATES: if value.lower() not in BOOLEAN_STATES:
raise configexc.ValidationError(value, "must be a boolean!") raise configexc.ValidationError(value, "must be a boolean!")
@ -270,6 +266,34 @@ class BoolAsk(Bool):
super().validate(value) super().validate(value)
class NoAsk(BaseType):
"""A no/ask question."""
valid_values = ValidValues('false', 'ask')
def transform(self, value):
if value.lower() == 'ask':
return 'ask'
else:
return BOOLEAN_STATES[value.lower()]
def validate(self, value):
if not value:
if self._none_ok:
return
else:
raise configexc.ValidationError(value, "may not be empty!")
if value.lower() == 'ask':
return
try:
v = BOOLEAN_STATES[value.lower()]
if v:
raise configexc.ValidationError(value, "must be ask/false!")
except KeyError:
raise configexc.ValidationError(value, "must be ask/false!")
class Int(BaseType): class Int(BaseType):
"""Base class for an integer setting. """Base class for an integer setting.