From 09d59497d1c06f07b1915e34c0110401916231b9 Mon Sep 17 00:00:00 2001 From: Mason Larobina Date: Wed, 23 Dec 2009 21:15:18 +0800 Subject: Added the escaped and quoted %r replace for on_event and bind args. --- examples/data/uzbl/plugins/bind.py | 10 ++++++++++ examples/data/uzbl/plugins/on_event.py | 11 +++++++++++ 2 files changed, 21 insertions(+) diff --git a/examples/data/uzbl/plugins/bind.py b/examples/data/uzbl/plugins/bind.py index 1cba7b2..668b595 100644 --- a/examples/data/uzbl/plugins/bind.py +++ b/examples/data/uzbl/plugins/bind.py @@ -306,9 +306,19 @@ class Bind(object): def expand(cmd, args): '''Replaces "%s %1 %2 %3..." with " ...".''' + # Direct string replace. if '%s' in cmd: cmd = cmd.replace('%s', ' '.join(map(unicode, args))) + # Escaped and quoted string replace. + if '%r' in cmd: + joined = ('%r' % ' '.join(map(unicode, args)))[1:] + for char in ['\\', '@']: + joined = joined.replace(char, '\\'+char) + + cmd = cmd.replace('%r', joined) + + # Arg index string replace. for (index, arg) in enumerate(args): index += 1 if '%%%d' % index in cmd: diff --git a/examples/data/uzbl/plugins/on_event.py b/examples/data/uzbl/plugins/on_event.py index afee4e6..9d2525b 100644 --- a/examples/data/uzbl/plugins/on_event.py +++ b/examples/data/uzbl/plugins/on_event.py @@ -2,6 +2,7 @@ Formatting options: %s = space separated string of the arguments + %r = escaped and quoted version of %s %1 = argument 1 %2 = argument 2 %n = argument n @@ -47,9 +48,19 @@ def get_on_events(uzbl): def expand(cmd, args): '''Replaces "%s %1 %2 %3..." with " ...".''' + # Direct string replace. if '%s' in cmd: cmd = cmd.replace('%s', ' '.join(map(unicode, args))) + # Escaped and quoted string replace. + if '%r' in cmd: + joined = ('%r' % ' '.join(map(unicode, args)))[1:] + for char in ['\\', '@']: + joined = joined.replace(char, '\\'+char) + + cmd = cmd.replace('%r', joined) + + # Arg index string replace. for (index, arg) in enumerate(args): index += 1 if '%%%d' % index in cmd: -- cgit v1.2.3 From f200c865fb8a5daae30ff9c070eb5c929c720a4b Mon Sep 17 00:00:00 2001 From: Mason Larobina Date: Thu, 24 Dec 2009 00:27:19 +0800 Subject: Moved expand function to external plugin to reduce code duplication. --- examples/data/uzbl/plugins/bind.py | 27 ++------------------ examples/data/uzbl/plugins/cmd_expand.py | 43 ++++++++++++++++++++++++++++++++ examples/data/uzbl/plugins/on_event.py | 27 ++------------------ 3 files changed, 47 insertions(+), 50 deletions(-) create mode 100644 examples/data/uzbl/plugins/cmd_expand.py diff --git a/examples/data/uzbl/plugins/bind.py b/examples/data/uzbl/plugins/bind.py index 668b595..9614df6 100644 --- a/examples/data/uzbl/plugins/bind.py +++ b/examples/data/uzbl/plugins/bind.py @@ -303,30 +303,6 @@ class Bind(object): return self._repr_cache -def expand(cmd, args): - '''Replaces "%s %1 %2 %3..." with " ...".''' - - # Direct string replace. - if '%s' in cmd: - cmd = cmd.replace('%s', ' '.join(map(unicode, args))) - - # Escaped and quoted string replace. - if '%r' in cmd: - joined = ('%r' % ' '.join(map(unicode, args)))[1:] - for char in ['\\', '@']: - joined = joined.replace(char, '\\'+char) - - cmd = cmd.replace('%r', joined) - - # Arg index string replace. - for (index, arg) in enumerate(args): - index += 1 - if '%%%d' % index in cmd: - cmd = cmd.replace('%%%d' % index, unicode(arg)) - - return cmd - - def exec_bind(uzbl, bind, *args, **kargs): '''Execute bind objects.''' @@ -342,8 +318,9 @@ def exec_bind(uzbl, bind, *args, **kargs): raise ArgumentError('cannot supply kargs for uzbl commands') commands = [] + cmd_expand = uzbl.cmd_expand for cmd in bind.commands: - cmd = expand(cmd, args) + cmd = cmd_expand(cmd, args) uzbl.send(cmd) diff --git a/examples/data/uzbl/plugins/cmd_expand.py b/examples/data/uzbl/plugins/cmd_expand.py new file mode 100644 index 0000000..a5c279d --- /dev/null +++ b/examples/data/uzbl/plugins/cmd_expand.py @@ -0,0 +1,43 @@ +__export__ = ['cmd_expand',] + + +def escape(str): + for (level, char) in [(3, '\\'), (2, "'"), (2, '"'), (1, '@')]: + str = str.replace(char, (level * '\\') + char) + + return str + + +def cmd_expand(uzbl, cmd, args): + '''Exports a function that provides the following + expansions in any uzbl command string: + + %s = replace('%s', ' '.join(args)) + %r = replace('%r', "'%s'" % escaped(' '.join(args))) + %1 = replace('%1', arg[0]) + %2 = replace('%2', arg[1]) + %n = replace('%n', arg[n-1]) + ''' + + # Ensure (1) all string representable and (2) correct string encoding. + args = map(unicode, args) + + # Direct string replace. + if '%s' in cmd: + cmd = cmd.replace('%s', ' '.join(args)) + + # Escaped and quoted string replace. + if '%r' in cmd: + cmd = cmd.replace('%r', "'%s'" % escape(' '.join(args))) + + # Arg index string replace. + for (index, arg) in enumerate(args): + index += 1 + if '%%%d' % index in cmd: + cmd = cmd.replace('%%%d' % index, unicode(arg)) + + return cmd + + +def init(*args): + pass diff --git a/examples/data/uzbl/plugins/on_event.py b/examples/data/uzbl/plugins/on_event.py index 9d2525b..f1ad0c9 100644 --- a/examples/data/uzbl/plugins/on_event.py +++ b/examples/data/uzbl/plugins/on_event.py @@ -45,30 +45,6 @@ def get_on_events(uzbl): return UZBLS[uzbl] -def expand(cmd, args): - '''Replaces "%s %1 %2 %3..." with " ...".''' - - # Direct string replace. - if '%s' in cmd: - cmd = cmd.replace('%s', ' '.join(map(unicode, args))) - - # Escaped and quoted string replace. - if '%r' in cmd: - joined = ('%r' % ' '.join(map(unicode, args)))[1:] - for char in ['\\', '@']: - joined = joined.replace(char, '\\'+char) - - cmd = cmd.replace('%r', joined) - - # Arg index string replace. - for (index, arg) in enumerate(args): - index += 1 - if '%%%d' % index in cmd: - cmd = cmd.replace('%%%d' % index, unicode(arg)) - - return cmd - - def event_handler(uzbl, *args, **kargs): '''This function handles all the events being watched by various on_event definitions and responds accordingly.''' @@ -79,8 +55,9 @@ def event_handler(uzbl, *args, **kargs): return commands = events[event] + cmd_expand = uzbl.cmd_expand for cmd in commands: - cmd = expand(cmd, args) + cmd = cmd_expand(cmd, args) uzbl.send(cmd) -- cgit v1.2.3 From 92ccf67e010bcff1a153dd67093c23300c2ce47f Mon Sep 17 00:00:00 2001 From: Mason Larobina Date: Sat, 26 Dec 2009 19:27:56 +0800 Subject: URIEncode search string component of web searching binds. --- examples/config/uzbl/config | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/config/uzbl/config b/examples/config/uzbl/config index 9dc4a35..a6be6d6 100644 --- a/examples/config/uzbl/config +++ b/examples/config/uzbl/config @@ -230,9 +230,9 @@ set open_new_window = sh 'uzbl-browser -u \@SELECTED_URI' @cbind N = search_reverse # --- Web searching binds --- -@cbind gg_ = uri http://www.google.com/search?q=%s -@cbind \\awiki_ = uri http://wiki.archlinux.org/index.php/Special:Search?search=%s&go=Go -@cbind \\wiki_ = uri http://en.wikipedia.org/w/index.php?title=Special:Search&search=%s&go=Go +@cbind gg_ = uri http://www.google.com/search?q=\@\@ +@cbind \\awiki_ = uri http://wiki.archlinux.org/index.php/Special:Search?search=\@\@&go=Go +@cbind \\wiki_ = uri http://en.wikipedia.org/w/index.php?title=Special:Search&search=\@\@&go=Go # --- Handy binds --- # Set function shortcut -- cgit v1.2.3 From 3733d86d0d28e072697a17a43eff360dcdac8038 Mon Sep 17 00:00:00 2001 From: Mason Larobina Date: Sat, 26 Dec 2009 20:53:24 +0800 Subject: Keycmd plugin now sets raw_{key,mod}cmd vars and updated title format. --- examples/config/uzbl/config | 2 ++ examples/data/uzbl/plugins/keycmd.py | 25 +++++++++++++++---------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/examples/config/uzbl/config b/examples/config/uzbl/config index a6be6d6..072c045 100644 --- a/examples/config/uzbl/config +++ b/examples/config/uzbl/config @@ -96,6 +96,8 @@ set selected_section = \@[\@SELECTED_URI]\@ set status_format = @mode_section @keycmd_section @progress_section @uri_section @name_section @status_section @scroll_section @selected_section +set title_format_long = \@keycmd_prompt \@raw_modcmd \@raw_keycmd \@TITLE - Uzbl browser <\@NAME> \@SELECTED_URI + # Progress bar config @progress width = 8 # %d = done, %p = pending %c = percent done, %i = int done, %s = spinner, diff --git a/examples/data/uzbl/plugins/keycmd.py b/examples/data/uzbl/plugins/keycmd.py index af6beff..8475c1d 100644 --- a/examples/data/uzbl/plugins/keycmd.py +++ b/examples/data/uzbl/plugins/keycmd.py @@ -10,20 +10,18 @@ UZBLS = {} # Keycmd format which includes the markup for the cursor. KEYCMD_FORMAT = "%s%s%s" +MODCMD_FORMAT = " %s " -def uzbl_escape(str): - '''Prevent outgoing keycmd values from expanding inside the - status_format.''' +def escape(str): + for char in ['\\', '@']: + str = str.replace(char, '\\'+char) - if not str: - return '' + return str - for char in ['\\', '@']: - if char in str: - str = str.replace(char, '\\'+char) - return "@[%s]@" % str +def uzbl_escape(str): + return "@[%s]@" % escape(str) if str else '' class Keylet(object): @@ -261,6 +259,7 @@ def clear_keycmd(uzbl): k.cursor = 0 k._repr_cache = False uzbl.set('keycmd') + uzbl.set('raw_keycmd') uzbl.event('KEYCMD_CLEARED') @@ -276,6 +275,7 @@ def clear_modcmd(uzbl, clear_held=False): k.held = set() uzbl.set('modcmd') + uzbl.set('raw_modcmd') uzbl.event('MODCMD_CLEARED') @@ -314,9 +314,11 @@ def update_event(uzbl, k, execute=True): new_modcmd = k.get_modcmd() if not new_modcmd: uzbl.set('modcmd', config=config) + uzbl.set('raw_modcmd', config=config) elif new_modcmd == modcmd: - uzbl.set('modcmd', ' %s ' % uzbl_escape(new_modcmd), + uzbl.set('raw_modcmd', escape(modcmd), config=config) + uzbl.set('modcmd', MODCMD_FORMAT % uzbl_escape(modcmd), config=config) if 'keycmd_events' in config and config['keycmd_events'] != '1': @@ -325,6 +327,7 @@ def update_event(uzbl, k, execute=True): new_keycmd = k.get_keycmd() if not new_keycmd: uzbl.set('keycmd', config=config) + uzbl.set('raw_keycmd', config=config) elif new_keycmd == keycmd: # Generate the pango markup for the cursor in the keycmd. @@ -332,6 +335,7 @@ def update_event(uzbl, k, execute=True): chunks = [keycmd[:k.cursor], curchar, keycmd[k.cursor+1:]] value = KEYCMD_FORMAT % tuple(map(uzbl_escape, chunks)) uzbl.set('keycmd', value, config=config) + uzbl.set('raw_keycmd', escape(keycmd), config=config) def inject_str(str, index, inj): @@ -391,6 +395,7 @@ def key_press(uzbl, key): k.keycmd = '' k.cursor = 0 uzbl.set('keycmd', config=config) + uzbl.set('raw_keycmd', config=config) return k.keycmd = inject_str(k.keycmd, k.cursor, key) -- cgit v1.2.3 From 3a73a42aae448240211d6d96349f1afb7e4e4996 Mon Sep 17 00:00:00 2001 From: Mason Larobina Date: Fri, 1 Jan 2010 09:29:34 +0800 Subject: Add 'uzbl terminal' binding & remove old example lines. --- examples/config/uzbl/config | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/examples/config/uzbl/config b/examples/config/uzbl/config index 072c045..9d0f710 100644 --- a/examples/config/uzbl/config +++ b/examples/config/uzbl/config @@ -245,6 +245,9 @@ set open_new_window = sh 'uzbl-browser -u \@SELECTED_URI' @cbind !dump = sh "echo dump_config > $4" # Reload config @cbind !reload = sh "sed '/^# === Post-load misc commands/,$d' $1 > $4" +# Uzbl Terminal +@cbind t = sh 'xterm -e "socat unix-connect:$5 -"' +#@cbind t = sh 'urxvt -e socat unix-connect:$5 -' # --- Uri opening prompts --- @cbind o_ = uri %s @@ -287,17 +290,6 @@ set toggle_cmd_ins = @toggle_modes command insert # Or number with strings instead of numbers: @cbind fL* = script @scripts_dir/follow_Numbers_Strings.js %s - -@cbind Xs = js alert("hi"); -# example showing how to use sh -# it sends a command to the fifo, whose path is told via a positional param -# if fifo_dir is not set, it'll echo to a file named (null) somewhere >:) remember to delete it -# The body of the shell command should be one parameter, so if it has spaces like here, -# you must enclose it in quotes. Remember to escape (and double-escape) quotes and backslashes -# in the body. Any additional parameters you use will appear AFTER the default parameters (cfg file -# path, fifo & socket dirs, etc.) -@cbind XS = sh 'echo "js alert (\\"This is sent by the shell via a fifo\\")" > "$4"' - # --- Form filler binds --- # this script allows you to configure (per domain) values to fill in form # fields (eg login information) and to fill in these values automatically -- cgit v1.2.3 From 3d9e04194d816f28621b6f3fdd5c73d58f271545 Mon Sep 17 00:00:00 2001 From: Mason Larobina Date: Fri, 1 Jan 2010 16:55:39 +0800 Subject: Correctness re-write of the export mechanism. Exporting is now done with the following two new functions: 1. `uzbl.export('external_name', function)` 2. `uzbl.export_dict({'name1': func1, 'name2': func2, ...})` This system is preferable to the old `__export__` variable for several reasons. The first being that the exporting system is now very similar to the connect (read: `uzbl.connect(..)` and `uzbl.connect_dict({..})`) system in the event manager. And consider the following: 1. User wishes to write a plugin that doesn't connect to any events but exports a function. 2. It's an arbitrary requirement that a plugin have an `init(uzbl)` function. 3. The user would have done the following (example plugin snippet): __export__ = 'my_function' def my_function(uzbl, ..): # Do something def init(uzbl): # Do nothing pass 4. The user now does the following: def my_function(uzbl, ..): # do something def init(uzbl): uzbl.export('my_function', my_function) Note that the name in `uzbl.export('external_name', function)` doesn't need to match the function name. Example pseudo-python: # In the plugin >>> def hello(uzbl): ... return "Hello, World!" >>> def init(uzbl): ... uzbl.export('say_hello', hello) ... print uzbl.say_hello() # In the event manager >>> plugin.init(uzbl) Hello, World! --- examples/data/uzbl/scripts/uzbl-event-manager | 101 ++++++++++---------------- 1 file changed, 38 insertions(+), 63 deletions(-) diff --git a/examples/data/uzbl/scripts/uzbl-event-manager b/examples/data/uzbl/scripts/uzbl-event-manager index 916259a..afef6fd 100755 --- a/examples/data/uzbl/scripts/uzbl-event-manager +++ b/examples/data/uzbl/scripts/uzbl-event-manager @@ -350,61 +350,23 @@ class UzblInstance(object): def __init__(self, parent, client_socket): # Internal variables. - self._exports = {} - self._handlers = {} - self._parent = parent - self._client_socket = client_socket + self.exports = {} + self.handlers = {} + self.parent = parent + self.client_socket = client_socket self.depth = 0 self.buffer = '' self.pid = None - # Call the init() function in every plugin. Inside the init function - # is where the plugins insert the hooks into the event system. - self._init_plugins() - - - def __getattribute__(self, attr): - '''Expose any exported functions before class functions.''' - - if not attr.startswith('_'): - exports = object.__getattribute__(self, '_exports') - if attr in exports: - return exports[attr] - - return object.__getattribute__(self, attr) - - - def _init_plugins(self): - '''Call the init() function in every plugin and expose all exposable - functions in the plugins root namespace.''' - - plugins = self._parent['plugins'] - - # Map all plugin exports - for (name, plugin) in plugins.items(): - if not hasattr(plugin, '__export__'): - continue - - for export in plugin.__export__: - if export in self._exports: - raise KeyError("conflicting export: %r" % export) - - obj = getattr(plugin, export) - if callable(obj): - obj = partial(obj, self) - - self._exports[export] = obj - - echo("exposed attribute(s): %s" % ', '.join(self._exports.keys())) - - # Now call the init function in all plugins. - for (name, plugin) in plugins.items(): + # Call the init function in every plugin. The init function in each + # plugin is where that plugin connects functions to events and exports + # functions to the uzbl object. + for plugin in self.parent['plugins'].values(): try: plugin.init(self) except: - #print_exc() raise @@ -412,26 +374,43 @@ class UzblInstance(object): '''Send a command to the uzbl instance via the socket file.''' msg = msg.strip() - if self._client_socket: + if self.client_socket: print '%s<-- %s' % (' ' * self.depth, msg) - self._client_socket.send(("%s\n" % msg).encode('utf-8')) + self.client_socket.send(("%s\n" % msg).encode('utf-8')) else: print '%s!-- %s' % (' ' * self.depth, msg) + def export(self, name, function): + '''Export `function(uzbl, *args, ..)` inside a plugin to the uzbl + object like so `uzbl.function(*args, ..)`. This will allow other + plugins to call functions inside the current plugin (which is currently + calling this function) via the uzbl object.''' + + self.__dict__.__setitem__(name, partial(function, self)) + + + def export_dict(self, export_dict): + '''Export multiple (name, function)'s at once inside a dict of the + form `{name1: function1, name2: function2, ...}`.''' + + for (name, function) in export_dict.items(): + self.export(name, function) + + def connect(self, event, handler, *args, **kargs): - '''Connect event with handler and return the newly created handler. - Handlers can either be a function or a uzbl command string.''' + '''Connect a uzbl event with a handler. Handlers can either be a + function or a uzbl command string.''' event = event.upper().strip() assert event and ' ' not in event - if event not in self._handlers.keys(): - self._handlers[event] = [] + if event not in self.handlers.keys(): + self.handlers[event] = [] handlerobj = EventHandler(event, handler, *args, **kargs) - self._handlers[event].append(handlerobj) + self.handlers[event].append(handlerobj) print handlerobj @@ -449,7 +428,7 @@ class UzblInstance(object): def remove_by_id(self, hid): '''Remove connected event handler by unique handler id.''' - for (event, handlers) in self._handlers.items(): + for (event, handlers) in self.handlers.items(): for handler in list(handlers): if hid != handler.hid: continue @@ -464,7 +443,7 @@ class UzblInstance(object): def remove(self, handler): '''Remove connected event handler.''' - for (event, handlers) in self._handlers.items(): + for (event, handlers) in self.handlers.items(): if handler in handlers: echo("removed %r" % handler) handlers.remove(handler) @@ -493,10 +472,10 @@ class UzblInstance(object): if event == "INSTANCE_START" and args: self.pid = int(args[0]) - if event not in self._handlers: + if event not in self.handlers: return - for handler in self._handlers[event]: + for handler in self.handlers[event]: self.depth += 1 try: self.exec_handler(handler, *args, **kargs) @@ -511,19 +490,15 @@ class UzblInstance(object): '''Close the client socket and clean up.''' try: - self._client_socket.close() + self.client_socket.close() except: pass - for (name, plugin) in self._parent['plugins'].items(): + for (name, plugin) in self.parent['plugins'].items(): if hasattr(plugin, 'cleanup'): plugin.cleanup(self) - del self._exports - del self._handlers - del self._client_socket - class UzblEventDaemon(dict): def __init__(self): -- cgit v1.2.3 From b0e7190acd1c266b20d2624051d6932bbf90a3d9 Mon Sep 17 00:00:00 2001 From: Mason Larobina Date: Fri, 1 Jan 2010 17:16:09 +0800 Subject: Use new export mechanism in all plugins. --- examples/data/uzbl/plugins/bind.py | 30 ++++++++------ examples/data/uzbl/plugins/cmd_expand.py | 9 ++-- examples/data/uzbl/plugins/completion.py | 25 ++++++----- examples/data/uzbl/plugins/config.py | 19 ++++++--- examples/data/uzbl/plugins/keycmd.py | 60 ++++++++++++++++----------- examples/data/uzbl/plugins/mode.py | 27 ++++++++---- examples/data/uzbl/plugins/on_event.py | 19 ++++++--- examples/data/uzbl/plugins/plugin_template.py | 25 +++++------ examples/data/uzbl/plugins/progress_bar.py | 15 +++---- 9 files changed, 138 insertions(+), 91 deletions(-) diff --git a/examples/data/uzbl/plugins/bind.py b/examples/data/uzbl/plugins/bind.py index 9614df6..9e09337 100644 --- a/examples/data/uzbl/plugins/bind.py +++ b/examples/data/uzbl/plugins/bind.py @@ -13,9 +13,6 @@ import sys import re import pprint -# Export these functions to uzbl. -__export__ = ['bind', 'mode_bind', 'get_bindlet'] - # Hold the bind dicts for each uzbl instance. UZBLS = {} @@ -504,12 +501,21 @@ def modcmd_exec(uzbl, keylet): def init(uzbl): - connects = {'BIND': parse_bind, - 'MODE_BIND': parse_mode_bind, - 'KEYCMD_UPDATE': keycmd_update, - 'MODCMD_UPDATE': modcmd_update, - 'KEYCMD_EXEC': keycmd_exec, - 'MODCMD_EXEC': modcmd_exec, - 'MODE_CHANGED': mode_changed} - - uzbl.connect_dict(connects) + # Event handling hooks. + uzbl.connect_dict({ + 'BIND': parse_bind, + 'KEYCMD_EXEC': keycmd_exec, + 'KEYCMD_UPDATE': keycmd_update, + 'MODCMD_EXEC': modcmd_exec, + 'MODCMD_UPDATE': modcmd_update, + 'MODE_BIND': parse_mode_bind, + 'MODE_CHANGED': mode_changed, + }) + + # Function exports to the uzbl object, `function(uzbl, *args, ..)` + # becomes `uzbl.function(*args, ..)`. + uzbl.export_dict({ + 'bind': bind, + 'mode_bind': mode_bind, + 'get_bindlet': get_bindlet, + }) diff --git a/examples/data/uzbl/plugins/cmd_expand.py b/examples/data/uzbl/plugins/cmd_expand.py index a5c279d..3f6ae2b 100644 --- a/examples/data/uzbl/plugins/cmd_expand.py +++ b/examples/data/uzbl/plugins/cmd_expand.py @@ -1,6 +1,3 @@ -__export__ = ['cmd_expand',] - - def escape(str): for (level, char) in [(3, '\\'), (2, "'"), (2, '"'), (1, '@')]: str = str.replace(char, (level * '\\') + char) @@ -39,5 +36,7 @@ def cmd_expand(uzbl, cmd, args): return cmd -def init(*args): - pass +def init(uzbl): + # Function exports to the uzbl object, `function(uzbl, *args, ..)` + # becomes `uzbl.function(*args, ..)`. + uzbl.export('cmd_expand', cmd_expand) diff --git a/examples/data/uzbl/plugins/completion.py b/examples/data/uzbl/plugins/completion.py index 8e055e1..8cea203 100644 --- a/examples/data/uzbl/plugins/completion.py +++ b/examples/data/uzbl/plugins/completion.py @@ -185,17 +185,22 @@ def add_config_key(uzbl, key, value): def init(uzbl): - connects = { - 'INSTANCE_START': add_instance, - 'INSTANCE_EXIT': del_instance, + # Event handling hooks. + uzbl.connect_dict({ 'BUILTINS': add_builtins, 'CONFIG_CHANGED': add_config_key, + 'INSTANCE_EXIT': del_instance, + 'INSTANCE_START': add_instance, + 'KEYCMD_CLEARED': stop_completion, + 'KEYCMD_EXEC': stop_completion, 'KEYCMD_UPDATE': update_completion_list, 'START_COMPLETION': start_completion, - } - - # And connect the dicts event handlers to the handler stack. - uzbl.connect_dict(connects) - - for event in ['STOP_COMPLETION', 'KEYCMD_EXEC', 'KEYCMD_CLEARED']: - uzbl.connect(event, stop_completion) + 'STOP_COMPLETION': stop_completion, + }) + + # Function exports to the uzbl object, `function(uzbl, *args, ..)` + # becomes `uzbl.function(*args, ..)`. + uzbl.export_dict({ + 'get_completion_dict': get_completion_dict, + 'start_completion': start_completion, + }) diff --git a/examples/data/uzbl/plugins/config.py b/examples/data/uzbl/plugins/config.py index b43161b..4a848a3 100644 --- a/examples/data/uzbl/plugins/config.py +++ b/examples/data/uzbl/plugins/config.py @@ -82,9 +82,16 @@ def variable_set(uzbl, args): def init(uzbl): - - connects = {'VARIABLE_SET': variable_set, - 'INSTANCE_START': add_instance, - 'INSTANCE_EXIT': del_instance} - - uzbl.connect_dict(connects) + # Event handling hooks. + uzbl.connect_dict({ + 'INSTANCE_EXIT': del_instance, + 'INSTANCE_START': add_instance, + 'VARIABLE_SET': variable_set, + }) + + # Function exports to the uzbl object, `function(uzbl, *args, ..)` + # becomes `uzbl.function(*args, ..)`. + uzbl.export_dict({ + 'get_config': get_config, + 'set': set, + }) diff --git a/examples/data/uzbl/plugins/keycmd.py b/examples/data/uzbl/plugins/keycmd.py index 8475c1d..c119077 100644 --- a/examples/data/uzbl/plugins/keycmd.py +++ b/examples/data/uzbl/plugins/keycmd.py @@ -1,10 +1,5 @@ import re -# Map these functions/variables in the plugins namespace to the uzbl object. -__export__ = ['clear_keycmd', 'set_keycmd', 'set_cursor_pos', 'get_keylet', - 'clear_current', 'clear_modcmd', 'add_modmap', 'add_key_ignore', - 'append_keycmd', 'inject_keycmd', 'add_modkey_addition'] - # Hold the keylets. UZBLS = {} @@ -538,22 +533,39 @@ def set_cursor_pos(uzbl, index): def init(uzbl): '''Connect handlers to uzbl events.''' - connects = {'INSTANCE_START': add_instance, - 'INSTANCE_EXIT': del_instance, - 'KEY_PRESS': key_press, - 'KEY_RELEASE': key_release, - 'SET_KEYCMD': set_keycmd, - 'KEYCMD_STRIP_WORD': keycmd_strip_word, - 'KEYCMD_BACKSPACE': keycmd_backspace, - 'KEYCMD_DELETE': keycmd_delete, - 'KEYCMD_EXEC_CURRENT': keycmd_exec_current, - 'SET_CURSOR_POS': set_cursor_pos, - 'FOCUS_LOST': focus_changed, - 'FOCUS_GAINED': focus_changed, - 'MODMAP': modmap_parse, - 'APPEND_KEYCMD': append_keycmd, - 'INJECT_KEYCMD': inject_keycmd, - 'IGNORE_KEY': add_key_ignore, - 'MODKEY_ADDITION': modkey_addition_parse} - - uzbl.connect_dict(connects) + # Event handling hooks. + uzbl.connect_dict({ + 'APPEND_KEYCMD': append_keycmd, + 'FOCUS_GAINED': focus_changed, + 'FOCUS_LOST': focus_changed, + 'IGNORE_KEY': add_key_ignore, + 'INJECT_KEYCMD': inject_keycmd, + 'INSTANCE_EXIT': del_instance, + 'INSTANCE_START': add_instance, + 'KEYCMD_BACKSPACE': keycmd_backspace, + 'KEYCMD_DELETE': keycmd_delete, + 'KEYCMD_EXEC_CURRENT': keycmd_exec_current, + 'KEYCMD_STRIP_WORD': keycmd_strip_word, + 'KEY_PRESS': key_press, + 'KEY_RELEASE': key_release, + 'MODKEY_ADDITION': modkey_addition_parse, + 'MODMAP': modmap_parse, + 'SET_CURSOR_POS': set_cursor_pos, + 'SET_KEYCMD': set_keycmd, + }) + + # Function exports to the uzbl object, `function(uzbl, *args, ..)` + # becomes `uzbl.function(*args, ..)`. + uzbl.export_dict({ + 'add_key_ignore': add_key_ignore, + 'add_modkey_addition': add_modkey_addition, + 'add_modmap': add_modmap, + 'append_keycmd': append_keycmd, + 'clear_current': clear_current, + 'clear_keycmd': clear_keycmd, + 'clear_modcmd': clear_modcmd, + 'get_keylet': get_keylet, + 'inject_keycmd': inject_keycmd, + 'set_cursor_pos': set_cursor_pos, + 'set_keycmd': set_keycmd, + }) diff --git a/examples/data/uzbl/plugins/mode.py b/examples/data/uzbl/plugins/mode.py index f85d999..54d865a 100644 --- a/examples/data/uzbl/plugins/mode.py +++ b/examples/data/uzbl/plugins/mode.py @@ -156,12 +156,21 @@ def toggle_modes(uzbl, modes): def init(uzbl): - - connects = {'CONFIG_CHANGED': config_changed, - 'INSTANCE_EXIT': del_instance, - 'INSTANCE_START': add_instance, - 'MODE_CONFIG': mode_config, - 'TOGGLE_MODES': toggle_modes, - 'MODE_CHANGED': mode_changed} - - uzbl.connect_dict(connects) + # Event handling hooks. + uzbl.connect_dict({ + 'CONFIG_CHANGED': config_changed, + 'INSTANCE_EXIT': del_instance, + 'INSTANCE_START': add_instance, + 'MODE_CHANGED': mode_changed, + 'MODE_CONFIG': mode_config, + 'TOGGLE_MODES': toggle_modes, + }) + + # Function exports to the uzbl object, `function(uzbl, *args, ..)` + # becomes `uzbl.function(*args, ..)`. + uzbl.export_dict({ + 'get_mode': get_mode, + 'get_mode_config': get_mode_config, + 'set_mode': set_mode, + 'set_mode_config': set_mode_config, + }) diff --git a/examples/data/uzbl/plugins/on_event.py b/examples/data/uzbl/plugins/on_event.py index f1ad0c9..b9c504a 100644 --- a/examples/data/uzbl/plugins/on_event.py +++ b/examples/data/uzbl/plugins/on_event.py @@ -92,9 +92,16 @@ def parse_on_event(uzbl, args): def init(uzbl): - - connects = {'ON_EVENT': parse_on_event, - 'INSTANCE_START': add_instance, - 'INSTANCE_EXIT': del_instance} - - uzbl.connect_dict(connects) + # Event handling hooks. + uzbl.connect_dict({ + 'INSTANCE_EXIT': del_instance, + 'INSTANCE_START': add_instance, + 'ON_EVENT': parse_on_event, + }) + + # Function exports to the uzbl object, `function(uzbl, *args, ..)` + # becomes `uzbl.function(*args, ..)`. + uzbl.export_dict({ + 'get_on_events': get_on_events, + 'on_event': on_event, + }) diff --git a/examples/data/uzbl/plugins/plugin_template.py b/examples/data/uzbl/plugins/plugin_template.py index 03cb748..565a999 100644 --- a/examples/data/uzbl/plugins/plugin_template.py +++ b/examples/data/uzbl/plugins/plugin_template.py @@ -1,8 +1,5 @@ '''Plugin template.''' -# A list of functions this plugin exports to be used via uzbl object. -__export__ = ['myplugin_function',] - # Holds the per-instance data dict. UZBLS = {} @@ -60,16 +57,20 @@ def init(uzbl): # Make a dictionary comprising of {"EVENT_NAME": handler, ..} to the event # handler stack: - connects = { - 'INSTANCE_START': add_instance, - 'INSTANCE_EXIT': del_instance, - 'MYPLUGIN_EVENT': myplugin_event_parser, - } - - # And connect the dicts event handlers to the handler stack. - uzbl.connect_dict(connects) + uzbl.connect_dict({ + # event name function + 'INSTANCE_START': add_instance, + 'INSTANCE_EXIT': del_instance, + 'MYPLUGIN_EVENT': myplugin_event_parser, + }) # Or connect a handler to an event manually and supply additional optional # arguments: - #uzbl.connect("MYOTHER_EVENT", myother_event_parser, True, limit=20) + + # Function exports to the uzbl object, `function(uzbl, *args, ..)` + # becomes `uzbl.function(*args, ..)`. + uzbl.connect_dict({ + # external name function + 'myplugin_function': myplugin_function, + }) diff --git a/examples/data/uzbl/plugins/progress_bar.py b/examples/data/uzbl/plugins/progress_bar.py index b6fcb1b..89ba175 100644 --- a/examples/data/uzbl/plugins/progress_bar.py +++ b/examples/data/uzbl/plugins/progress_bar.py @@ -149,10 +149,11 @@ def reset_progress(uzbl, args): def init(uzbl): - connects = {'LOAD_PROGRESS': update_progress, - 'INSTANCE_START': add_instance, - 'INSTANCE_EXIT': del_instance, - 'PROGRESS_CONFIG': progress_config, - 'LOAD_COMMIT': reset_progress} - - uzbl.connect_dict(connects) + # Event handling hooks. + uzbl.connect_dict({ + 'INSTANCE_EXIT': del_instance, + 'INSTANCE_START': add_instance, + 'LOAD_COMMIT': reset_progress, + 'LOAD_PROGRESS': update_progress, + 'PROGRESS_CONFIG': progress_config, + }) -- cgit v1.2.3 From 759143756ff5ab9076b5d9e1a3839d1e8690ede2 Mon Sep 17 00:00:00 2001 From: Mason Larobina Date: Fri, 1 Jan 2010 21:29:16 +0800 Subject: We don't have support for inline comments. --- examples/config/uzbl/config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/config/uzbl/config b/examples/config/uzbl/config index 9d0f710..bf08c9e 100644 --- a/examples/config/uzbl/config +++ b/examples/config/uzbl/config @@ -45,7 +45,7 @@ set scheme_handler = sync_spawn @scripts_dir/scheme.py # New window handler options #set new_window = sh 'echo uri "$8" > $4' # open in same window -set new_window = sh 'uzbl-browser -u $8' # equivalent to the default behaviour +set new_window = sh 'uzbl-browser -u $8' # Load start handlers @on_event LOAD_START @set_status wait -- cgit v1.2.3 From 0482aae0aed75e333225c45312c260f63a888517 Mon Sep 17 00:00:00 2001 From: Mason Larobina Date: Sat, 2 Jan 2010 20:53:07 +0800 Subject: Updated comments in handlers section and updated the download handler --- examples/config/uzbl/config | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/examples/config/uzbl/config b/examples/config/uzbl/config index bf08c9e..4782a0d 100644 --- a/examples/config/uzbl/config +++ b/examples/config/uzbl/config @@ -39,15 +39,24 @@ set jsh = js var run=Uzbl.run; function get(k){return run("print \\\@"+k)}; func # === Handlers =============================================================== -set download_handler = spawn @scripts_dir/download.sh -set cookie_handler = talk_to_socket $XDG_CACHE_HOME/uzbl/cookie_daemon_socket -set scheme_handler = sync_spawn @scripts_dir/scheme.py +# --- Hardcoded event handlers ----------------------------------------------- -# New window handler options -#set new_window = sh 'echo uri "$8" > $4' # open in same window -set new_window = sh 'uzbl-browser -u $8' +# These handlers can't be moved to the new event system yet as we don't +# support events that can wait for a response from a script. +set cookie_handler = talk_to_socket $XDG_CACHE_HOME/uzbl/cookie_daemon_socket +set scheme_handler = sync_spawn @scripts_dir/scheme.py -# Load start handlers +# Open in the same window. +#set new_window = sh 'echo uri "$8" > $4' +# Open a link in a new window. +set new_window = sh 'uzbl-browser -u $8' + +# --- Optional dynamic event handlers ---------------------------------------- + +# Download handler +@on_event DOWNLOAD_REQUEST spawn @scripts_dir/download.sh %s \@proxy_url + +# Load start handler @on_event LOAD_START @set_status wait # Load commit handlers @@ -69,7 +78,7 @@ set new_window = sh 'uzbl-browser -u $8' # Switch to command mode if anything else is clicked @on_event ROOT_ACTIVE @set_mode command -# Misc on_event handlers +# Example CONFIG_CHANGED event handler #@on_event CONFIG_CHANGED print Config changed: %1 = %2 # === Behaviour and appearance =============================================== -- cgit v1.2.3 From a5f014de5f76169a38ee67e46a0526e5d80a3433 Mon Sep 17 00:00:00 2001 From: Dieter Plaetinck Date: Sat, 2 Jan 2010 18:08:16 +0100 Subject: add notes into example config --- examples/config/uzbl/config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/config/uzbl/config b/examples/config/uzbl/config index 4782a0d..3edb36c 100644 --- a/examples/config/uzbl/config +++ b/examples/config/uzbl/config @@ -48,7 +48,7 @@ set scheme_handler = sync_spawn @scripts_dir/scheme.py # Open in the same window. #set new_window = sh 'echo uri "$8" > $4' -# Open a link in a new window. +# Open a link in a new window. equivalent to default behavior set new_window = sh 'uzbl-browser -u $8' # --- Optional dynamic event handlers ---------------------------------------- @@ -254,7 +254,7 @@ set open_new_window = sh 'uzbl-browser -u \@SELECTED_URI' @cbind !dump = sh "echo dump_config > $4" # Reload config @cbind !reload = sh "sed '/^# === Post-load misc commands/,$d' $1 > $4" -# Uzbl Terminal +# Uzbl Terminal. TODO explain why this is useful @cbind t = sh 'xterm -e "socat unix-connect:$5 -"' #@cbind t = sh 'urxvt -e socat unix-connect:$5 -' -- cgit v1.2.3 From 1958b52d41cba96956dc1995660de49525ed1047 Mon Sep 17 00:00:00 2001 From: Dieter Plaetinck Date: Tue, 5 Jan 2010 20:17:29 +0100 Subject: disable Uzbl javascript object because of security problem. --- README | 21 +-------------------- tests/test-command.c | 5 ----- uzbl-core.c | 10 ---------- 3 files changed, 1 insertion(+), 35 deletions(-) diff --git a/README b/README index 0d6ed04..a22e105 100644 --- a/README +++ b/README @@ -397,7 +397,7 @@ The script specific arguments are this: Custom, userdefined scripts (`spawn foo bar`) get first the arguments as specified in the config and then the above 7 are added at the end. -### JAVASCRIPT HELPER OBJECT +### JAVASCRIPT HELPER OBJECT DISABLED BECAUSE OF SECURITY LEAK Javascript code run from uzbl is given a special object in the global namespace which gives special privileges to these scripts. This object is called `Uzbl`, and it is added and removed before and after the script execution so that it is hidden to web javascripts (There is no race condition, since all the javascript code runs in a single thread) @@ -410,25 +410,6 @@ Currently, the `Uzbl` object provides only one function: * `Uzbl.run("spawn insert_bookmark.sh")` * `uri = Uzbl.run("print @uri")` (see variable expansion below) -### JAVASCRIPT SECURITY - -Since defined variables and functions are set in the global namespace (`window` object) as default, it is recommended to wrap your scripts like this: - - (function(Uzbl) { - ... - })(Uzbl); - -This way, everything is kept private. It also turns Uzbl into a local variable, which can be accessed from callback functions defined inside. However for some situations, isolating everything isn't an option, for example, with binds. You can define them directly in the script body, and use `var Uzbl = window.Uzbl;` to make the Uzbl variable local, as in the following example: - - function f() { - var Uzbl = window.Uzbl; - Uzbl.run(...); - setTimeout(function() { - Uzbl.run(...); - }, 500); - } - -Copying the Uzbl object and creating public functions should be taken with care to avoid creating security holes. Keep in mind that the "f" function above would be defined in the `window` object, and as such any javascript in the current page can call it. ### EVENTS ### diff --git a/tests/test-command.c b/tests/test-command.c index 49f3bb8..fc3b092 100644 --- a/tests/test-command.c +++ b/tests/test-command.c @@ -305,11 +305,6 @@ test_js (void) { parse_cmd_line("js ('x' + 345).toUpperCase()", result); g_assert_cmpstr("X345", ==, result->str); - /* uzbl commands can be run from javascript */ - uzbl.net.useragent = "Test useragent"; - parse_cmd_line("js Uzbl.run('print @useragent').toUpperCase();", result); - g_assert_cmpstr("TEST USERAGENT", ==, result->str); - g_string_free(result, TRUE); } diff --git a/uzbl-core.c b/uzbl-core.c index fd8ee41..fca293c 100644 --- a/uzbl-core.c +++ b/uzbl-core.c @@ -1046,7 +1046,6 @@ eval_js(WebKitWebView * web_view, gchar *script, GString *result) { WebKitWebFrame *frame; JSGlobalContextRef context; JSObjectRef globalobject; - JSStringRef var_name; JSStringRef js_script; JSValueRef js_result; @@ -1059,12 +1058,6 @@ eval_js(WebKitWebView * web_view, gchar *script, GString *result) { context = webkit_web_frame_get_global_context(frame); globalobject = JSContextGetGlobalObject(context); - /* uzbl javascript namespace */ - var_name = JSStringCreateWithUTF8CString("Uzbl"); - JSObjectSetProperty(context, globalobject, var_name, - JSObjectMake(context, uzbl.js.classref, NULL), - kJSClassAttributeNone, NULL); - /* evaluate the script and get return value*/ js_script = JSStringCreateWithUTF8CString(script); js_result = JSEvaluateScript(context, js_script, globalobject, NULL, 0, NULL); @@ -1082,9 +1075,6 @@ eval_js(WebKitWebView * web_view, gchar *script, GString *result) { } /* cleanup */ - JSObjectDeleteProperty(context, globalobject, var_name, NULL); - - JSStringRelease(var_name); JSStringRelease(js_script); } -- cgit v1.2.3