Add config options for geolocation/notifications.
This commit is contained in:
parent
43c9d69295
commit
e44c5aee5b
@ -121,6 +121,8 @@
|
||||
|<<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-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-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.
|
||||
@ -995,6 +997,30 @@ Valid values:
|
||||
|
||||
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]]
|
||||
=== javascript-can-open-windows
|
||||
Whether JavaScript programs can open new windows.
|
||||
|
@ -285,39 +285,48 @@ class BrowserPage(QWebPage):
|
||||
@pyqtSlot('QWebFrame', 'QWebPage::Feature')
|
||||
def on_feature_permission_requested(self, frame, feature):
|
||||
"""Ask the user for approval for geolocation/notifications."""
|
||||
bridge = objreg.get('message-bridge', scope='window',
|
||||
window=self._win_id)
|
||||
q = usertypes.Question(bridge)
|
||||
q.mode = usertypes.PromptMode.yesno
|
||||
|
||||
msgs = {
|
||||
QWebPage.Notifications: 'show notifications',
|
||||
QWebPage.Geolocation: 'access your location',
|
||||
options = {
|
||||
QWebPage.Notifications: ('content', 'notifications'),
|
||||
QWebPage.Geolocation: ('content', 'geolocation'),
|
||||
}
|
||||
host = frame.url().host()
|
||||
if host:
|
||||
q.text = "Allow the website at {} to {}?".format(
|
||||
frame.url().host(), msgs[feature])
|
||||
if config.get(*options[feature]) == 'ask':
|
||||
bridge = objreg.get('message-bridge', scope='window',
|
||||
window=self._win_id)
|
||||
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:
|
||||
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)
|
||||
self.setFeaturePermission(frame, feature,
|
||||
QWebPage.PermissionDeniedByUser)
|
||||
|
||||
def on_feature_permission_cancelled(self, question, frame, feature,
|
||||
cancelled_frame, cancelled_feature):
|
||||
|
@ -498,6 +498,14 @@ DATA = collections.OrderedDict([
|
||||
'Qt plugins with a mimetype such as "application/x-qt-plugin" are '
|
||||
"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',
|
||||
# SettingValue(typ.Bool(), 'true'),
|
||||
# "Enables or disables Java applets. Currently Java applets are "
|
||||
|
@ -38,6 +38,10 @@ from qutebrowser.config import configexc
|
||||
|
||||
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:
|
||||
|
||||
@ -221,25 +225,17 @@ class List(BaseType):
|
||||
|
||||
class Bool(BaseType):
|
||||
|
||||
"""Base class for a boolean setting.
|
||||
|
||||
Class attributes:
|
||||
_BOOLEAN_STATES: A dictionary of strings mapped to their bool meanings.
|
||||
"""
|
||||
"""Base class for a boolean setting."""
|
||||
|
||||
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')
|
||||
|
||||
def transform(self, value):
|
||||
if not value:
|
||||
return None
|
||||
else:
|
||||
return Bool._BOOLEAN_STATES[value.lower()]
|
||||
return BOOLEAN_STATES[value.lower()]
|
||||
|
||||
def validate(self, value):
|
||||
if not value:
|
||||
@ -247,7 +243,7 @@ class Bool(BaseType):
|
||||
return
|
||||
else:
|
||||
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!")
|
||||
|
||||
|
||||
@ -270,6 +266,34 @@ class BoolAsk(Bool):
|
||||
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):
|
||||
|
||||
"""Base class for an integer setting.
|
||||
|
Loading…
Reference in New Issue
Block a user