Author: jvloothuis Date: Sat Dec 29 23:14:19 2007 New Revision: 50182 Modified: kukit/kss.base/branches/protocol-data-types/kss/base/__init__.py kukit/kss.base/branches/protocol-data-types/kss/base/commands.py kukit/kss.base/branches/protocol-data-types/kss/base/commands.txt kukit/kss.base/branches/protocol-data-types/kss/base/corecommands.py kukit/kss.base/branches/protocol-data-types/kss/base/corecommands.txt Log:
Added parameter types. These are used when serializing data to the client. We currently have cdata, xml and html support. Changed string representation of KSS commands so that global commands do not show a None selector. Removed automatic conversion to css selector in the add method of commands. The client will decides the selector type if the server has not given any. Modified: kukit/kss.base/branches/protocol-data-types/kss/base/__init__.py ============================================================================== --- kukit/kss.base/branches/protocol-data-types/kss/base/__init__.py (original) +++ kukit/kss.base/branches/protocol-data-types/kss/base/__init__.py Sat Dec 29 23:14:19 2007 @@ -1,3 +1,4 @@ from kss.base.commands import KSSCommands from kss.base.selectors import selectors from kss.base.plugin import load_plugins +from kss.base.commands import xmldata, htmldata, cdatadata Modified: kukit/kss.base/branches/protocol-data-types/kss/base/commands.py ============================================================================== --- kukit/kss.base/branches/protocol-data-types/kss/base/commands.py (original) +++ kukit/kss.base/branches/protocol-data-types/kss/base/commands.py Sat Dec 29 23:14:19 2007 @@ -1,7 +1,6 @@ -from xml.sax.saxutils import quoteattr +from xml.sax.saxutils import quoteattr, escape from kss.base.registry import command_set_registry from kss.base.selectors import Selector -from kss.base.selectors import css kss_response_header = '''<?xml version="1.0" ?> <kukit xmlns="http://www.kukit.org/commands/1.0"><commands> @@ -14,7 +13,23 @@ kss_command_end = '</command>' -kss_param = '<param name=%(name)s><![CDATA[%(value)s]]></param>' +kss_param = '<param name=%(name)s>%(value)s</param>' + +class cdatadata(object): + def __init__(self, value): + self.value = value + + def __str__(self): + return '<![CDATA[%s]]>' % self.value.replace(']]>', ']]>') + + def __repr__(self): + return "%s('%s')" % (self.__class__.__name__, self.value) + +class htmldata(cdatadata): + pass + +class xmldata(cdatadata): + pass class KSSCommands(object): '''Command renderer for creating KSS responses''' @@ -24,9 +39,6 @@ def add(self, action, selector, **kwargs): self._strip_none_parameters(kwargs) - if selector is not None and not isinstance(selector, Selector): - selector = css(selector) - self.commands.append((action, selector, kwargs)) def _strip_none_parameters(self, parameters): @@ -37,11 +49,24 @@ def render(self): output = [kss_response_header] for action, selector, options in self.commands: + try: + selector_type = selector.type + selector = selector.value + except AttributeError: + # It is probably a string or unicode object so we can + # let the client decide the default selector + selector_type = '' + output.append(kss_command_start % dict( - selector=quoteattr(selector.value), - selector_type=quoteattr(selector.type), - action=quoteattr(action))) + selector=quoteattr(selector), + selector_type=quoteattr(selector_type), + action=quoteattr(action))) + for name, value in options.items(): + if isinstance(value, basestring): + value = escape(value) + else: + value = str(value) output.append(kss_param % dict( name=quoteattr(name), value=value)) output.append(kss_command_end) @@ -52,18 +77,21 @@ self.commands = [] def __str__(self): - def format_options(options): - if not options: - return '' - return ', ' + ', '.join( - ["%s='%s'" % item for item in options.items()]) - lines = [] for action, selector, options in self.commands: - lines.append("%(action)s(%(selector)s%(options)s)" % { - 'action': action, - 'selector': selector, - 'options': format_options(options)}) + line = '%s(' % action + if isinstance(selector, Selector): + line += '%s' % selector + elif isinstance(selector, basestring): + line += "'%s'" % selector + + if options: + if selector is not None: + line += ', ' + line += ', '.join( + ["%s=%s" % (key, repr(value)) for + key, value in options.items()]) + lines.append(line + ')') return '\n'.join(lines) def __getattr__(self, name): Modified: kukit/kss.base/branches/protocol-data-types/kss/base/commands.txt ============================================================================== --- kukit/kss.base/branches/protocol-data-types/kss/base/commands.txt (original) +++ kukit/kss.base/branches/protocol-data-types/kss/base/commands.txt Sat Dec 29 23:14:19 2007 @@ -40,9 +40,10 @@ '...some value...some arg...' + + Response format =============== - The response is an XML document. >>> from xml.dom import minidom @@ -55,7 +56,32 @@ [<DOM Element: command at ...>, <DOM Element: command at ...>] Each parameter is represented by a child node in a command. Their name -is stored in the attribute and their value is put within CDATA blocks. +is stored in the attribute and their value is put within text nodes or +CDATA blocks. Which type of node is used depends on the type of +the keyword argument given to the command. + +Depending on the type the serialisation to XML changes. Strings and +unicode objects will be send as text nodes. You can also mark data as +HTML, XML or CDATA blocks. This is used so that these can have special +escaping rules. + + >>> from kss.base import xmldata, htmldata, cdatadata + +Now if we make a command with these types the output will be different. + + >>> commands = KSSCommands() + >>> commands.add('htmlAction', css('#someid'), html=htmldata('some value')) + >>> commands.add('cdataAction', css('#otherid'), arg=cdatadata('some arg')) + >>> commands.add('xmlAction', css('#otherid'), arg=xmldata('some arg')) + >>> commands.add('normalAction', css('#otherid'), arg='normal arg') + >>> doc = minidom.parseString(commands.render()) + >>> for command in doc.getElementsByTagName('command'): + ... params = command.getElementsByTagName('param') + ... print params[0].childNodes[0].nodeType == doc.CDATA_SECTION_NODE + True + True + True + False >>> replace_command = doc.getElementsByTagName('command')[0] @@ -125,12 +151,12 @@ You can also use strings instead of a selector instance as a value for selector. In this case the string will automatically be converted to a -CSS selector. +selector on the client. By default this is the CSS selector. >>> commands.clear() >>> commands.add('replaceHTML', '#someid', html='some value') >>> print commands - replaceHTML(css('#someid'), html='some value') + replaceHTML('#someid', html='some value') Command sets @@ -182,6 +208,6 @@ >>> commands.core.replaceInnerHTML(css('div'), 'example') >>> print commands - replaceInnerHTML(css('div'), html='example') + replaceInnerHTML(css('div'), html=htmldata('example')) >>> command_set_registry.unregister('core') \ No newline at end of file Modified: kukit/kss.base/branches/protocol-data-types/kss/base/corecommands.py ============================================================================== --- kukit/kss.base/branches/protocol-data-types/kss/base/corecommands.py (original) +++ kukit/kss.base/branches/protocol-data-types/kss/base/corecommands.py Sat Dec 29 23:14:19 2007 @@ -1,4 +1,5 @@ from kss.base.commands import KSSCommandSet +from kss.base import htmldata class KSSCoreCommands(KSSCommandSet): @@ -27,7 +28,7 @@ extra_args = {} if not withKssSetup: extra_args['withKssSetup'] = 'False' - self.commands.add('replaceInnerHTML', selector, html=value, + self.commands.add('replaceInnerHTML', selector, html=htmldata(value), **extra_args) def replaceHTML(self, selector, value, withKssSetup=True): Modified: kukit/kss.base/branches/protocol-data-types/kss/base/corecommands.txt ============================================================================== --- kukit/kss.base/branches/protocol-data-types/kss/base/corecommands.txt (original) +++ kukit/kss.base/branches/protocol-data-types/kss/base/corecommands.txt Sat Dec 29 23:14:19 2007 @@ -95,15 +95,15 @@ >>> commands.clear() >>> core.replaceInnerHTML(css('div'), 'some html') >>> print commands - replaceInnerHTML(css('div'), html='some html') + replaceInnerHTML(css('div'), html=htmldata('some html')) You can also avoid KSS event setup. Use this only if you really need the speedup because KSS will not be applied to these new nodes. >>> core.replaceInnerHTML(css('div'), 'some html', withKssSetup=False) >>> print commands - replaceInnerHTML(css('div'), html='some html') - replaceInnerHTML(css('div'), html='some html', withKssSetup='False') + replaceInnerHTML(css('div'), html=htmldata('some html')) + replaceInnerHTML(css('div'), html=htmldata('some html'), withKssSetup='False') Replace HTML @@ -261,7 +261,7 @@ >>> commands.clear() >>> core.setStateVar('varname', 'value') >>> print commands - setStateVar(None, varname='varname', value='value') + setStateVar(varname='varname', value='value') Trigger event ------------- @@ -269,4 +269,4 @@ >>> commands.clear() >>> core.triggerEvent('eventname') >>> print commands - triggerEvent(None, name='eventname') + triggerEvent(name='eventname') _______________________________________________ Kukit-checkins mailing list [email protected] http://codespeak.net/mailman/listinfo/kukit-checkins
