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-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.
|
||||||
|
@ -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):
|
||||||
|
@ -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 "
|
||||||
|
@ -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.
|
||||||
|
Loading…
Reference in New Issue
Block a user