PK2i7#kss/__init__.py# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages try: __import__('pkg_resources').declare_namespace(__name__) except ImportError: from pkgutil import extend_path __path__ = extend_path(__path__, __name__) PK i7ɴDzzkss/__init__.pyc; %4Gc@sMyedieWn/ej o#dklZeeeZnXdS(s pkg_resources(s extend_pathN(s __import__sdeclare_namespaces__name__s ImportErrorspkgutils extend_paths__path__(s__path__s extend_path((s*build/bdist.linux-i686/egg/kss/__init__.pys?s PK2i7ǵkss/core/kssview.py# Copyright (c) 2005-2007 # Authors: KSS Project Contributors (see docs/CREDITS.txt) # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as published # by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. '''\ KSS Base view class All the implementations should create a specialization of this class when building their browser views. The policy is that a method should build up a command set on available methods and then return self.render(). The default command set is implemented in the base class as well. ''' import warnings try: from Products.Five import BrowserView except ImportError: from zope.publisher.browser import BrowserView from kss.core.commands import KSSCommands from kss.core.interfaces import IKSSView, ICommandSet from kss.core.pluginregistry.commandset import getRegisteredCommandSet from zope import component, interface, event from zope.interface.adapter import VerifyingAdapterRegistry from zope.component.globalregistry import BaseGlobalComponents from zope.component.interfaces import IObjectEvent from zope.app.component.interfaces import ISite from zope.app.publication.zopepublication import BeforeTraverseEvent HAS_FIVE_LSM = True try: from five.localsitemanager import registry from zope.component.registry import UtilityRegistration except ImportError: HAS_FIVE_LSM = False class SiteViewComponents(BaseGlobalComponents): def _init_registries(self): # This is why this class is needed: we can't work with a # regular AdapterRegistry because it wants to do funny things # with __bases__. self.adapters = VerifyingAdapterRegistry() self.utilities = VerifyingAdapterRegistry() if HAS_FIVE_LSM: self.utilities.LookupClass = registry.FiveVerifyingAdapterLookup self.utilities._createLookup() self.utilities.__parent__ = self if HAS_FIVE_LSM: def registeredUtilities(self): for ((provided, name), (component, info) ) in self._utility_registrations.iteritems(): yield UtilityRegistration(self, provided, name, registry._wrap(component, self), info) class SiteView(BrowserView): """A browser view that is its own site """ interface.implements(ISite) def __init__(self, context, request): super(SiteView, self).__init__(context, request) next = component.getSiteManager() self._sitemanager = SiteViewComponents('siteview') self._sitemanager.__bases__ = (next, ) if HAS_FIVE_LSM: self._sitemanager.__parent__ = self # On Five, we should wrap it in the acquisition context # see, if self has aq_parent, it is done obligatoraly try: self.context.aq_parent except AttributeError: # Zope3 - No problem. wrapped_view = self else: wrapped_view = self.__of__(self.context) # register object event handler self._sitemanager.registerHandler(wrapped_view._eventRedispatcher) # Zope 2.10 doesn't send BeforeTraverseEvents for all objects, # only the ones for which you explicitly enable a before traverse # hook available from Five.component. Hence, this view won't # become the current site when it's traversed. This is bad, # hopefully Zope 2.11 will fix this. For now, we'll just take # care of it ourselves... def __before_publishing_traverse__(self, obj, request): event.notify(BeforeTraverseEvent(self, request)) # ISite interface def getSiteManager(self): return self._sitemanager def setSiteManager(self, sm): raise TypeError("Site manager of SiteView can't be changed.") @component.adapter(IObjectEvent) def _eventRedispatcher(self, event): """This works similar to zope.component.event.objectEventNotify: It dispatches object events to subscribers that listen to (object, view, event).""" adapters = component.subscribers((event.object, self, event), None) for adapter in adapters: pass # getting them does the work class KSSView(SiteView): """KSS view This allows setting up the content of the response, and then generate it out. """ interface.implements(IKSSView) def __init__(self, context, request): super(KSSView, self).__init__(context, request) self._initcommands() def _initcommands(self): self.commands = KSSCommands() # XXX avoid weird acquisition behaviour in Zope 2... this should # go away when Five views aren't Acquisition objects anymore. def _set_context(self, context): self._context = [context] def _get_context(self): return self._context[0] context = property(_get_context, _set_context) def render(self): """Views can use this to return their command set.""" return self.commands.render(self.request) def cancelRedirect(self): if self.request.response.getStatus() in (302, 303): # Try to not redirect if requested self.request.response.setStatus(200) def getCommands(self): return self.commands def getCommandSet(self, name): commandset = getRegisteredCommandSet(name) # return the adapted view return commandset.provides(self) class CommandSet: interface.implements(ICommandSet) def __init__(self, view): self.view = view self.context = self.view.context self.request = self.view.request self.commands = self.view.commands def getCommandSet(self, name): return self.view.getCommandSet(name) # BBB deprecated class AzaxBaseView(KSSView): def __init__(self, *args, **kw): message = "'AzaxBaseView' is deprecated," \ "use 'KSSView' instead." warnings.warn(message, DeprecationWarning, 2) KSSView.__init__(self, *args, **kw) class AzaxViewAdapter(CommandSet): def __init__(self, *args, **kw): message = "'AzaxViewAdapter' is deprecated," \ "use 'CommandSet' instead." warnings.warn(message, DeprecationWarning, 2) CommandSet.__init__(self, *args, **kw) PK2i75llkss/core/__init__.py# Copyright (c) 2005-2007 # Authors: KSS Project Contributors (see docs/CREDITS.txt) # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as published # by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. __all__ = ('force_unicode', 'KSSUnicodeError', 'KSSExplicitError', 'kssaction', 'KSSView', 'CommandSet', 'ICommandSet', #BBB 'AzaxBaseView', 'KssExplicitError', ) import mimetypes mimetypes.types_map['.kkt'] = 'text/xml' # BBB legacy! mimetypes.types_map['.kukit'] = 'text/xml' from kss.core.kssview import KSSView, CommandSet from kss.core.actionwrapper import KSSExplicitError, kssaction from kss.core.unicode_quirks import force_unicode, KSSUnicodeError from kss.core.interfaces import ICommandSet # BBB from kss.core.kssview import AzaxBaseView from kss.core.actionwrapper import KssExplicitError import sys, kssview sys.modules['kss.core.azaxview'] = kssview try: import Products.Five except ImportError: pass else: # Allow API to build commands from restricted code from AccessControl import allow_module allow_module('kss.core.ttwapi') PK2i7u>n]kss/core/deprecated.py# -*- coding: ISO-8859-15 -*- # Copyright (c) 2005-2007 # Authors: KSS Project Contributors (see docs/CREDITS.txt) # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as published # by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. import warnings, textwrap def deprecated_warning(message): warnings.warn(message, DeprecationWarning, 2) def deprecated(method, message): def deprecated_method(self, *args, **kw): warnings.warn(message, DeprecationWarning, 2) return method(self, *args, **kw) return deprecated_method def deprecated_directive(method, directive, message): def deprecated_method(_context, *args, **kw): warnings.warn(message, DeprecationWarning, 2) warnings.warn(textwrap.dedent('''\ %s The directive %s is deprecated and will be removed any time, %s ''' % (_context.info, directive, message)), DeprecationWarning, 2) return method(_context, *args, **kw) return deprecated_method PK2i7xҒkss/core/commands.py# Copyright (c) 2005-2007 # Authors: KSS Project Contributors (see docs/CREDITS.txt) # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as published # by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. '''\ Marshal objects These build up the response and get marshalled to the client in the defined format ''' from zope.interface import implements from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile from interfaces import IKSSCommands, IKSSCommand, IKSSParam, IKSSCommandView from unicode_quirks import force_unicode import zope.component from parsers import XmlParser, HtmlParser from pluginregistry import checkRegisteredCommand_old from pluginregistry import checkRegisteredCommand, checkRegisteredSelector, \ KSSPluginError class KSSCommands(list): implements(IKSSCommands) def addCommand(self, command_name, selector=None, **kw): command = KSSCommand(command_name, selector=selector, **kw) self.append(command) return command def render(self, request): '''All methods must use this to return their command set ''' adapter = zope.component.getMultiAdapter((self, request), IKSSCommandView) return adapter.render() class KSSParam: implements(IKSSParam) def __init__(self, name, content=''): self.name = name self.content = content def force_content_unicode(self): # Content must be str with ascii encoding, or unicode! self.content = force_unicode(self.content) def getName(self): return self.name def getContent(self): return self.content class KSSCommand: implements(IKSSCommand) def __init__(self, command_name, selector=None, **kw): try: checkRegisteredCommand_old(command_name) except KSSPluginError: # we expect this is not registered as command, anyway # so check it as an action. checkRegisteredCommand(command_name) else: # ok. XXX this will be deprecated # All registerCommand commands are obsolete, by default import warnings, textwrap warnings.warn(textwrap.dedent('''\ The usage of the kss command "%s" is deprecated''' % (command_name, )), DeprecationWarning, 2) if selector is not None: if isinstance(selector, basestring): # the default selector - given just as a string self.selector = selector self.selectorType = '' else: checkRegisteredSelector(selector.type) self.selector = selector.value self.selectorType = selector.type else: self.selector = None self.selectorType = None self.name = command_name self.params = [] # Add parameters passed in **kw for key, value in kw.iteritems(): self.addParam(key, value) # -- # Different parameter conversions # -- # REMARK: with the jsonserver product present, you can # just send complex data types directly with AddParam def addParam(self, name, content=''): 'Add the param as is' param = KSSParam(name, content) self.params.append(param) return param # # Some helpers # def addUnicodeParam(self, name, content=''): 'Add the param as unicode' self.addParam(name, content=content) def addStringParam(self, name, content='', encoding='utf'): 'Add the param as an encoded string, by default UTF-8' content = unicode(content, 'utf') self.addParam(name, content=content) def addHtmlParam(self, name, content=''): 'Add the param as an HTML content.' content = HtmlParser(content)().encode('ascii', 'xmlcharrefreplace') self.addParam(name, content=content) def addXmlParam(self, name, content=''): 'Add the param as XML content' content = XmlParser(content)().encode('ascii', 'xmlcharrefreplace') self.addParam(name, content=content) def addCdataParam(self, name, content=''): 'Add the param as a CDATA node' content = '' % (content, ) self.addParam(name, content=content) # -- # Accessors, not sure if we need them # -- def getName(self): return self.name def getSelector(self): return self.selector def getSelectorType(self): return self.selectorType def getParams(self): return self.params class CommandView(object): '''View of a command. The render method does actual marshalling of the commands to be sent to the client. ''' implements(IKSSCommandView) def __init__(self, context, request): self.context = context self.request = request # XXX From Zope2.9 we need this. # Note: We don't use proper views for Five. As our context object # is not even a proper Zope content. There would be a way to: # # - use ZopeTwoPageTemplateFile # - and, make the object to be proper zope content. # # This would be two much ado for nothing, so we just use barefoot # rendering but as a consequence no path expression, only python: # is available from the page template. if not hasattr(self.request, 'debug'): self.request.debug = None # Force parameters content to be unicode for command in context: for param in command.getParams(): param.force_content_unicode() # XML output gets rendered via a page template # XXX note: barefoot rendering, use python: only after zope2.9 # XXX we must have the content type set both here and below _render = ViewPageTemplateFile('browser/kukitresponse.pt', content_type='text/xml;charset=utf-8') def render(self): result = self._render() # Always output text/xml to make sure browsers but the data in the # responseXML instead of responseText attribute of the # XMLHttpRequestobject. self.request.response.setHeader('Content-type', 'text/xml;charset=utf-8') return result PK2i7V|kss/core/selectors.py# Copyright (c) 2006-2007 # Authors: KSS Project Contributors (see docs/CREDITS.txt) # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as published # by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. CSS_SELECTOR = 'css' HTMLID_SELECTOR = 'htmlid' PARENTNODE_SELECTOR = 'parentnode' SAMENODE_SELECTOR = 'samenode' class SelectorBase(object): def __init__(self, selector): self.value = selector class CssSelector(SelectorBase): type = CSS_SELECTOR class HtmlIdSelector(SelectorBase): type = HTMLID_SELECTOR class ParentNodeSelector(SelectorBase): type = PARENTNODE_SELECTOR class SameNodeSelector(SelectorBase): def __init__(self): super(SameNodeSelector, self).__init__('') type = SAMENODE_SELECTOR # A generic (pluggable) selector class Selector(SelectorBase): def __init__(self, type, selector): self.type = type SelectorBase.__init__(self, selector) PK2i72kss/core/config.py PK2i7yRDDkss/core/ttwapi.pyfrom zope.app.component.hooks import getSite, setSite from zope import event from zope.app.publication.zopepublication import BeforeTraverseEvent from kss.core import KSSView from kss.core.interfaces import IKSSView from kss.core.unicode_quirks import force_unicode def startKSSCommands(context, request): view = KSSView(context, request) # Alec suggested we should fire the BeforeTraverseEvent, but after # debugging for a while I stopped caring about the event and think # that setSite() is the only thing we're interested in. setSite(view) return view def getKSSCommandSet(name): view = retrieveView() cs = view.getCommandSet(name) return cs def renderKSSCommands(): view = retrieveView() return view.render() def retrieveView(): #because the view registers itself as a site, #we can retrieve it... site = getSite() if not IKSSView.providedBy(site): raise LookupError( "You haven't initialized the KSS response yet, " "do so by calling startKSSCommands(context, request).") return site PK2i7p?kss/core/browserview.py# Copyright (c) 2006-2007 # Authors: KSS Project Contributors (see docs/CREDITS.txt) # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as published # by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # import cgi, warnings try: from Products.Five import BrowserView except ImportError: from zope.app.publisher.browser import BrowserView from zope.pagetemplate.pagetemplatefile import PageTemplateFile class KSSBrowserView(BrowserView): # XML output gets rendered via a page template # XXX note: barefoot rendering, use python: only after zope2.9 render_error = PageTemplateFile('browser/errorresponse.pt') def attach_error(self, err_type, err_value): 'Attach the error payload on the response' message = '%s: %s' % (err_type, err_value) message = cgi.escape(message) payload = self.render_error(type='system', message=message) self.attach_payload(payload) def attach_payload(self, payload, header_name='X-KSSCOMMANDS'): 'Attach the commands on the response' # get rid of newlines payload = payload.replace('\n', ' ') self.request.response.setHeader(header_name, payload) # coherent naming KSS # deprecate Kss class KssBrowserView(KSSBrowserView): def __init__(self, *args, **kw): message = "'KssBrowserView' is deprecated," \ "use 'KSSBrowserView'- KSS uppercase instead." warnings.warn(message, DeprecationWarning, 2) KSSBrowserView.__init__(self, *args, **kw) PK2i7W#b#b#kss/core/actionwrapper.py# Copyright (c) 2005-2007 # Authors: KSS Project Contributors (see docs/CREDITS.txt) # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as published # by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. from textwrap import dedent from inspect import formatargspec, getargspec, getargvalues, \ formatargvalues, currentframe from zope.interface import implements class KSSExplicitError(Exception): 'Explicit error to be raised' class kssaction(object): '''Descriptor to bundle kss server actions. - render() will be called automatically if there is no return value - if KSSExplicitError is raised, a normal response is returned, containing a single command:error KSS command. Let's say we have a class here - that is supposed to be a kss view. >>> from kss.core import kssaction, KSSExplicitError, KSSView >>> class MyView(KSSView): ... def ok(self, a, b, c=0): ... return 'OK %s %s %s' % (a, b, c) ... def notok(self, a, b, c=0): ... pass ... def error(self, a, b, c=0): ... raise KSSExplicitError, 'The error' ... def exception(self, a, b, c=0): ... raise Exception, 'Unknown exception' Now we try qualifying with kssaction. We overwrite render too, just to enable sensible testing of the output: >>> class MyView(KSSView): ... def render(self): ... return 'Rendered' ... @kssaction ... def ok(self, a, b, c=3): ... return 'OK %s %s %s' % (a, b, c) ... @kssaction ... def notok(self, a, b, c=3): ... pass ... @kssaction ... def error(self, a, b, c=3): ... raise KSSExplicitError, 'The error' ... @kssaction ... def exception(self, a, b, c=3): ... raise Exception, 'Unknown exception' Instantiate a view. >>> view = MyView(None, None) Now, of course ok renders well. >>> view.ok(1, b=2) 'OK 1 2 3' Not ok will have implicit rendering. >>> view.notok(1, b=2) 'Rendered' The third type will return an error action. But it will render instead of an error. >>> view.error(1, b=2) 'Rendered' The fourth type will be a real error. >>> view.exception(1, b=2) Traceback (most recent call last): ... Exception: Unknown exception Now for the sake of it, let's test the rendered kukit response. So, we don't overwrite render like as we did in the previous tests. >>> from zope.publisher.browser import TestRequest >>> class MyView(KSSView): ... @kssaction ... def error(self, a, b, c=3): ... raise KSSExplicitError, 'The error' ... @kssaction ... def with_docstring(self, a, b, c=3): ... "Docstring" ... raise KSSExplicitError, 'The error' >>> request = TestRequest() >>> view = MyView(None, request) Set debug-mode command rendering so we can see the results in a more structured form. >>> from zope import interface as iapi >>> from kss.core.tests.base import IDebugRequest >>> iapi.directlyProvides(request, iapi.directlyProvidedBy(request) + IDebugRequest) See the results: >>> view.error(1, b=2) [{'selectorType': None, 'params': {'message': u'The error'}, 'name': 'error', 'selector': None}] Usage of the method wrapped in browser view ------------------------------------------- Finally, let's check if the method appears if defined on a browser view. Since there could be a thousand reasons why Five's magic could fail, it's good to check this. (XXX Note that this must be adjusted to run on Zope3.) >>> try: ... import Products.Five ... except ImportError: ... # probably zope 3, not supported ... raise 'Zope3 not supported in this test' ... else: ... from Products.Five.zcml import load_string, load_config >>> import kss.core.tests >>> kss.core.tests.MyView = MyView We check for two basic types of declaration. The first one declares a view with different attributes. The second one declares a dedicated view with the method as the view default method. This is how we use it in several places. >>> load_string(""" ... ... ... ... ... ... ... """) Let's check it now: >>> self.folder.restrictedTraverse('/@@my_view/error') >> v = self.folder.restrictedTraverse('/my_view2') >>> isinstance(v, MyView) True >>> hasattr(v, 'error') True >>> v(1, b=2) [{'selectorType': None, 'params': {'message': u'The error'}, 'name': 'error', 'selector': None}] In addition, to be publishable, the docstring must exist. Let's see if the wrapper actually does this. If the method had a docstring, it will be reused, but a docstring is provided in any case. >>> v = self.folder.restrictedTraverse('/@@my_view') >>> bool(v.error.__doc__) True >>> v.with_docstring.__doc__ 'Docstring' ''' def __init__(self, f): self.f = f # Now this is a solution I don't like, but we need the same # function signature, otherwise the ZPublisher won't marshall # the parameters. *arg, **kw would not suffice since no parameters # would be marshalled at all. argspec = getargspec(f) orig_args = formatargspec(*argspec)[1:-1] if argspec[3] is None: fixed_args_num = len(argspec[0]) else: fixed_args_num = len(argspec[0]) - len(argspec[3]) values_list = [v for v in argspec[0][:fixed_args_num]] values_list.extend(['%s=%s' % (v, v) for v in argspec[0][fixed_args_num:]]) values_args = ', '.join(values_list) # provide a docstring in any case. if self.f.__doc__ is not None: docstring = repr(f.__doc__) else: docstring = '"XXX"' # orig_args: "a, b, c=2" # values_args: "a, b, c=c" code = dedent('''\n def wrapper(%s): %s return descr.apply(%s) ''' % (orig_args, docstring, values_args)) self.wrapper_code = compile(code, '', 'exec') def __get__(self, obj, cls=None): d = {'descr': self, 'self': obj} exec(self.wrapper_code, d) wrapper = d['wrapper'].__get__(obj, cls) return wrapper def apply(self, obj, *arg, **kw): try: result = self.f(obj, *arg, **kw) except KSSExplicitError, exc: # Clear all the commands, and emit an error command obj._initcommands() obj.commands.addCommand('error', message=str(exc)) result = None if result is None: # render not returned - so we do it. result = obj.render() return result # backward compatibility class KssExplicitError(KSSExplicitError): def __init__(self, *args, **kw): message = "'KssExplicitError' is deprecated," \ "use 'KSSExplicitError'- KSS uppercase instead." warnings.warn(message, DeprecationWarning, 2) KSSExplicitError.__init__(self, *args, **kw) PK2i7wx kss/core/parsers.py# -*- coding: ISO-8859-15 -*- # Copyright (c) 2006-2007 # Authors: KSS Project Contributors (see docs/CREDITS.txt) # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as published # by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. '''\ Parser implementations These assure that output is valid XML or HTML and fix the code or raise an exception. The wrapping makes it possible to change the parser transparently if necessary. ''' from unicode_quirks import force_unicode import re, htmlentitydefs class replace_html_named_entities(object): _entity_regexp = re.compile(r'&([A-Za-z]+);') def _entity_replacer(m): value = htmlentitydefs.name2codepoint.get(m.group(1)) if value is None: return m.group(0) return "&#%i;" % value _entity_replacer = staticmethod(_entity_replacer) def _replace(cls, value): return cls._entity_regexp.sub(cls._entity_replacer, value) _replace = classmethod(_replace) def __new__(cls, value): return cls._replace(value) class XmlParser(object): '''Custom XML parser wraps the parser implementation ''' from BeautifulSoup import BeautifulStoneSoup def __init__(self, value): value = force_unicode(value) self.soup = self.BeautifulStoneSoup(value) def __call__(self): return unicode(self.soup) class HtmlParser(object): '''Custom HTML parser wraps the parser implementation ''' from BeautifulSoup import BeautifulSoup def __init__(self, value): value = force_unicode(value) self.soup = self.BeautifulSoup(value) # # XXX ree: I think these are not needed any more. See # kukit patches r25865, r25866 that IMO fix this on IE. # #for tag in self.soup.fetch(recursive=False): # tag['xmlns'] = "http://www.w3.org/1999/xhtml" def __call__(self): value = unicode(self.soup) # Replace named HTML entitied in each case. # This is necessary for two reasons: # 1. Fixes an IE bug. # 2. Needed for the alternate transport mechanism to work. value = replace_html_named_entities(value) return value PK2i7bkss/core/unicode_quirks.py# Copyright (c) 2005-2007 # Authors: KSS Project Contributors (see docs/CREDITS.txt) # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as published # by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. class KSSUnicodeError(RuntimeError): pass def force_unicode(value, encoding='ascii'): 'Force value to be unicode - allow also value in a specific encoding (by default, ascii).' if isinstance(value, str): try: value = unicode(value, encoding) except UnicodeDecodeError, exc: raise KSSUnicodeError, 'Content must be unicode or ascii string, original exception: %s' % (exc, ) else: assert isinstance(value, unicode) return value PK2i7- kss/core/interfaces.py# Copyright (c) 2005-2007 # Authors: KSS Project Contributors (see docs/CREDITS.txt) # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as published # by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. from zope.interface import Interface, Attribute class IKSSCommands(Interface): 'KSS commands' def addCommand(self, name, selector=None): 'Add a command' def render(self, request): 'All methods must use this to return their command set' def getSelector(self, type, selector): 'Return selector' # more helpers for the basic selectors def getCssSelector(self, selector): 'Return selector' def getHtmlIdSelector(self, selector): 'Return selector' class IKSSCommand(Interface): 'An KSS command' def addParam(self, name, content=''): 'Add the param as is' # # Some helpers # def addUnicodeParam(self, name, content=''): 'Add the param as unicode' def addStringParam(self, name, content='', encoding='utf'): 'Add the param as an encoded string, by default UTF-8' def addHtmlParam(self, name, content=''): 'Add the param as an HTML content.' def addXmlParam(self, name, content=''): 'Add the param as XML content' def addCdataParam(self, name, content=''): 'Add the param as a CDATA node' # -- # Accessors, not sure if we need them # -- def getName(self): '' def getSelector(self): '' def getSelectorType(self): '' def getParams(self): '' class IKSSCommandView(Interface): 'View of a command set' def render(): 'This renders the command set' class IKSSParam(Interface): 'An KSS parameter' def force_content_unicode(self): 'Content must be str with ascii encoding, or unicode' def getName(self): '' def getContent(self): '' class IKSSView(Interface): commands = Attribute('An IKSSCommands object that keeps track of ' 'all commands that are sent to the browser') def render(self): """Return a string representation of all KSS commands issued so far.""" def getCommandSet(name): """Return the commandset called ``name`` bound to the current view.""" # BBB deprecated IAzaxView = IKSSView class ICommandSet(Interface): 'Methods of this class implement a command set' def getCommandSet(self, name): 'Returns the command set for a given name' PK2i7yykss/core/BeautifulSoup.py"""Beautiful Soup Elixir and Tonic "The Screen-Scraper's Friend" http://www.crummy.com/software/BeautifulSoup/ Beautiful Soup parses a (possibly invalid) XML or HTML document into a tree representation. It provides methods and Pythonic idioms that make it easy to navigate, search, and modify the tree. A well-structured XML/HTML document yields a well-behaved data structure. An ill-structured XML/HTML document yields a correspondingly ill-behaved data structure. If your document is only locally well-structured, you can use this library to find and process the well-structured part of it. Beautiful Soup works with Python 2.2 and up. It has no external dependencies, but you'll have more success at converting data to UTF-8 if you also install these three packages: * chardet, for auto-detecting character encodings http://chardet.feedparser.org/ * cjkcodecs and iconv_codec, which add more encodings to the ones supported by stock Python. http://cjkpython.i18n.org/ Beautiful Soup defines classes for two main parsing strategies: * BeautifulStoneSoup, for parsing XML, SGML, or your domain-specific language that kind of looks like XML. * BeautifulSoup, for parsing run-of-the-mill HTML code, be it valid or invalid. This class has web browser-like heuristics for obtaining a sensible parse tree in the face of common HTML errors. Beautiful Soup also defines a class (UnicodeDammit) for autodetecting the encoding of an HTML or XML document, and converting it to Unicode. Much of this code is taken from Mark Pilgrim's Universal Feed Parser. For more than you ever wanted to know about Beautiful Soup, see the documentation: http://www.crummy.com/software/BeautifulSoup/documentation.html """ from __future__ import generators __author__ = "Leonard Richardson (crummy.com)" __contributors__ = ["Sam Ruby (intertwingly.net)", "the unwitting Mark Pilgrim (diveintomark.org)", "http://www.crummy.com/software/BeautifulSoup/AUTHORS.html"] __version__ = "3.0.3" __copyright__ = "Copyright (c) 2004-2006 Leonard Richardson" __license__ = "PSF" from sgmllib import SGMLParser, SGMLParseError import codecs import types import re import sgmllib from htmlentitydefs import name2codepoint # This RE makes Beautiful Soup able to parse XML with namespaces. sgmllib.tagfind = re.compile('[a-zA-Z][-_.:a-zA-Z0-9]*') # This RE makes Beautiful Soup capable of recognizing numeric character # references that use hexadecimal. sgmllib.charref = re.compile('&#(\d+|x[0-9a-fA-F]+);') DEFAULT_OUTPUT_ENCODING = "utf-8" # First, the classes that represent markup elements. class PageElement: """Contains the navigational information for some part of the page (either a tag or a piece of text)""" def setup(self, parent=None, previous=None): """Sets up the initial relations between this element and other elements.""" self.parent = parent self.previous = previous self.next = None self.previousSibling = None self.nextSibling = None if self.parent and self.parent.contents: self.previousSibling = self.parent.contents[-1] self.previousSibling.nextSibling = self def replaceWith(self, replaceWith): oldParent = self.parent myIndex = self.parent.contents.index(self) if hasattr(replaceWith, 'parent') and replaceWith.parent == self.parent: # We're replacing this element with one of its siblings. index = self.parent.contents.index(replaceWith) if index and index < myIndex: # Furthermore, it comes before this element. That # means that when we extract it, the index of this # element will change. myIndex = myIndex - 1 self.extract() oldParent.insert(myIndex, replaceWith) def extract(self): """Destructively rips this element out of the tree.""" if self.parent: try: self.parent.contents.remove(self) except ValueError: pass #Find the two elements that would be next to each other if #this element (and any children) hadn't been parsed. Connect #the two. lastChild = self._lastRecursiveChild() nextElement = lastChild.next if self.previous: self.previous.next = nextElement if nextElement: nextElement.previous = self.previous self.previous = None lastChild.next = None self.parent = None if self.previousSibling: self.previousSibling.nextSibling = self.nextSibling if self.nextSibling: self.nextSibling.previousSibling = self.previousSibling self.previousSibling = self.nextSibling = None def _lastRecursiveChild(self): "Finds the last element beneath this object to be parsed." lastChild = self while hasattr(lastChild, 'contents') and lastChild.contents: lastChild = lastChild.contents[-1] return lastChild def insert(self, position, newChild): if (isinstance(newChild, basestring) or isinstance(newChild, unicode)) \ and not isinstance(newChild, NavigableString): newChild = NavigableString(newChild) position = min(position, len(self.contents)) if hasattr(newChild, 'parent') and newChild.parent != None: # We're 'inserting' an element that's already one # of this object's children. if newChild.parent == self: index = self.find(newChild) if index and index < position: # Furthermore we're moving it further down the # list of this object's children. That means that # when we extract this element, our target index # will jump down one. position = position - 1 newChild.extract() newChild.parent = self previousChild = None if position == 0: newChild.previousSibling = None newChild.previous = self else: previousChild = self.contents[position-1] newChild.previousSibling = previousChild newChild.previousSibling.nextSibling = newChild newChild.previous = previousChild._lastRecursiveChild() if newChild.previous: newChild.previous.next = newChild newChildsLastElement = newChild._lastRecursiveChild() if position >= len(self.contents): newChild.nextSibling = None parent = self parentsNextSibling = None while not parentsNextSibling: parentsNextSibling = parent.nextSibling parent = parent.parent if not parent: # This is the last element in the document. break if parentsNextSibling: newChildsLastElement.next = parentsNextSibling else: newChildsLastElement.next = None else: nextChild = self.contents[position] newChild.nextSibling = nextChild if newChild.nextSibling: newChild.nextSibling.previousSibling = newChild newChildsLastElement.next = nextChild if newChildsLastElement.next: newChildsLastElement.next.previous = newChildsLastElement self.contents.insert(position, newChild) def findNext(self, name=None, attrs={}, text=None, **kwargs): """Returns the first item that matches the given criteria and appears after this Tag in the document.""" return self._findOne(self.findAllNext, name, attrs, text, **kwargs) def findAllNext(self, name=None, attrs={}, text=None, limit=None, **kwargs): """Returns all items that match the given criteria and appear before after Tag in the document.""" return self._findAll(name, attrs, text, limit, self.nextGenerator) def findNextSibling(self, name=None, attrs={}, text=None, **kwargs): """Returns the closest sibling to this Tag that matches the given criteria and appears after this Tag in the document.""" return self._findOne(self.findNextSiblings, name, attrs, text, **kwargs) def findNextSiblings(self, name=None, attrs={}, text=None, limit=None, **kwargs): """Returns the siblings of this Tag that match the given criteria and appear after this Tag in the document.""" return self._findAll(name, attrs, text, limit, self.nextSiblingGenerator, **kwargs) fetchNextSiblings = findNextSiblings # Compatibility with pre-3.x def findPrevious(self, name=None, attrs={}, text=None, **kwargs): """Returns the first item that matches the given criteria and appears before this Tag in the document.""" return self._findOne(self.findAllPrevious, name, attrs, text, **kwargs) def findAllPrevious(self, name=None, attrs={}, text=None, limit=None, **kwargs): """Returns all items that match the given criteria and appear before this Tag in the document.""" return self._findAll(name, attrs, text, limit, self.previousGenerator, **kwargs) fetchPrevious = findAllPrevious # Compatibility with pre-3.x def findPreviousSibling(self, name=None, attrs={}, text=None, **kwargs): """Returns the closest sibling to this Tag that matches the given criteria and appears before this Tag in the document.""" return self._findOne(self.findPreviousSiblings, name, attrs, text, **kwargs) def findPreviousSiblings(self, name=None, attrs={}, text=None, limit=None, **kwargs): """Returns the siblings of this Tag that match the given criteria and appear before this Tag in the document.""" return self._findAll(name, attrs, text, limit, self.previousSiblingGenerator, **kwargs) fetchPreviousSiblings = findPreviousSiblings # Compatibility with pre-3.x def findParent(self, name=None, attrs={}, **kwargs): """Returns the closest parent of this Tag that matches the given criteria.""" # NOTE: We can't use _findOne because findParents takes a different # set of arguments. r = None l = self.findParents(name, attrs, 1) if l: r = l[0] return r def findParents(self, name=None, attrs={}, limit=None, **kwargs): """Returns the parents of this Tag that match the given criteria.""" return self._findAll(name, attrs, None, limit, self.parentGenerator, **kwargs) fetchParents = findParents # Compatibility with pre-3.x #These methods do the real heavy lifting. def _findOne(self, method, name, attrs, text, **kwargs): r = None l = method(name, attrs, text, 1, **kwargs) if l: r = l[0] return r def _findAll(self, name, attrs, text, limit, generator, **kwargs): "Iterates over a generator looking for things that match." if isinstance(name, SoupStrainer): strainer = name else: # Build a SoupStrainer strainer = SoupStrainer(name, attrs, text, **kwargs) results = ResultSet(strainer) g = generator() while True: try: i = g.next() except StopIteration: break if i: found = strainer.search(i) if found: results.append(found) if limit and len(results) >= limit: break return results #These Generators can be used to navigate starting from both #NavigableStrings and Tags. def nextGenerator(self): i = self while i: i = i.next yield i def nextSiblingGenerator(self): i = self while i: i = i.nextSibling yield i def previousGenerator(self): i = self while i: i = i.previous yield i def previousSiblingGenerator(self): i = self while i: i = i.previousSibling yield i def parentGenerator(self): i = self while i: i = i.parent yield i # Utility methods def substituteEncoding(self, str, encoding=None): encoding = encoding or "utf-8" return str.replace("%SOUP-ENCODING%", encoding) def toEncoding(self, s, encoding=None): """Encodes an object to a string in some encoding, or to Unicode. .""" if isinstance(s, unicode): if encoding: s = s.encode(encoding) elif isinstance(s, str): if encoding: s = s.encode(encoding) else: s = unicode(s) else: if encoding: s = self.toEncoding(str(s), encoding) else: s = unicode(s) return s class NavigableString(unicode, PageElement): def __getattr__(self, attr): """text.string gives you text. This is for backwards compatibility for Navigable*String, but for CData* it lets you get the string without the CData wrapper.""" if attr == 'string': return self else: raise AttributeError, "'%s' object has no attribute '%s'" % (self.__class__.__name__, attr) def __unicode__(self): return __str__(self, None) def __str__(self, encoding=DEFAULT_OUTPUT_ENCODING): if encoding: return self.encode(encoding) else: return self class CData(NavigableString): def __str__(self, encoding=DEFAULT_OUTPUT_ENCODING): return "" % NavigableString.__str__(self, encoding) class ProcessingInstruction(NavigableString): def __str__(self, encoding=DEFAULT_OUTPUT_ENCODING): output = self if "%SOUP-ENCODING%" in output: output = self.substituteEncoding(output, encoding) return "" % self.toEncoding(output, encoding) class Comment(NavigableString): def __str__(self, encoding=DEFAULT_OUTPUT_ENCODING): return "" % NavigableString.__str__(self, encoding) class Declaration(NavigableString): def __str__(self, encoding=DEFAULT_OUTPUT_ENCODING): return "" % NavigableString.__str__(self, encoding) class Tag(PageElement): """Represents a found HTML tag with its attributes and contents.""" XML_ENTITIES_TO_CHARS = { 'apos' : "'", "quot" : '"', "amp" : "&", "lt" : "<", "gt" : ">" } # An RE for finding ampersands that aren't the start of of a # numeric entity. BARE_AMPERSAND = re.compile("&(?!#\d+;|#x[0-9a-fA-F]+;|\w+;)") def __init__(self, parser, name, attrs=None, parent=None, previous=None): "Basic constructor." # We don't actually store the parser object: that lets extracted # chunks be garbage-collected self.parserClass = parser.__class__ self.isSelfClosing = parser.isSelfClosingTag(name) self.convertHTMLEntities = parser.convertHTMLEntities self.name = name if attrs == None: attrs = [] self.attrs = attrs self.contents = [] self.setup(parent, previous) self.hidden = False self.containsSubstitutions = False def get(self, key, default=None): """Returns the value of the 'key' attribute for the tag, or the value given for 'default' if it doesn't have that attribute.""" return self._getAttrMap().get(key, default) def has_key(self, key): return self._getAttrMap().has_key(key) def __getitem__(self, key): """tag[key] returns the value of the 'key' attribute for the tag, and throws an exception if it's not there.""" return self._getAttrMap()[key] def __iter__(self): "Iterating over a tag iterates over its contents." return iter(self.contents) def __len__(self): "The length of a tag is the length of its list of contents." return len(self.contents) def __contains__(self, x): return x in self.contents def __nonzero__(self): "A tag is non-None even if it has no contents." return True def __setitem__(self, key, value): """Setting tag[key] sets the value of the 'key' attribute for the tag.""" self._getAttrMap() self.attrMap[key] = value found = False for i in range(0, len(self.attrs)): if self.attrs[i][0] == key: self.attrs[i] = (key, value) found = True if not found: self.attrs.append((key, value)) self._getAttrMap()[key] = value def __delitem__(self, key): "Deleting tag[key] deletes all 'key' attributes for the tag." for item in self.attrs: if item[0] == key: self.attrs.remove(item) #We don't break because bad HTML can define the same #attribute multiple times. self._getAttrMap() if self.attrMap.has_key(key): del self.attrMap[key] def __call__(self, *args, **kwargs): """Calling a tag like a function is the same as calling its findAll() method. Eg. tag('a') returns a list of all the A tags found within this tag.""" return apply(self.findAll, args, kwargs) def __getattr__(self, tag): #print "Getattr %s.%s" % (self.__class__, tag) if len(tag) > 3 and tag.rfind('Tag') == len(tag)-3: return self.find(tag[:-3]) elif tag.find('__') != 0: return self.find(tag) def __eq__(self, other): """Returns true iff this tag has the same name, the same attributes, and the same contents (recursively) as the given tag. NOTE: right now this will return false if two tags have the same attributes in a different order. Should this be fixed?""" if not hasattr(other, 'name') or not hasattr(other, 'attrs') or not hasattr(other, 'contents') or self.name != other.name or self.attrs != other.attrs or len(self) != len(other): return False for i in range(0, len(self.contents)): if self.contents[i] != other.contents[i]: return False return True def __ne__(self, other): """Returns true iff this tag is not identical to the other tag, as defined in __eq__.""" return not self == other def __repr__(self, encoding=DEFAULT_OUTPUT_ENCODING): """Renders this tag as a string.""" return self.__str__(encoding) def __unicode__(self): return self.__str__(None) def _convertEntities(self, match): x = match.group(1) if x in name2codepoint: return unichr(name2codepoint[x]) elif "&" + x + ";" in self.XML_ENTITIES_TO_CHARS: return '&%s;' % x else: return '&%s;' % x def __str__(self, encoding=DEFAULT_OUTPUT_ENCODING, prettyPrint=False, indentLevel=0): """Returns a string or Unicode representation of this tag and its contents. To get Unicode, pass None for encoding. NOTE: since Python's HTML parser consumes whitespace, this method is not certain to reproduce the whitespace present in the original string.""" encodedName = self.toEncoding(self.name, encoding) attrs = [] if self.attrs: for key, val in self.attrs: fmt = '%s="%s"' if isString(val): if self.containsSubstitutions and '%SOUP-ENCODING%' in val: val = self.substituteEncoding(val, encoding) # The attribute value either: # # * Contains no embedded double quotes or single quotes. # No problem: we enclose it in double quotes. # * Contains embedded single quotes. No problem: # double quotes work here too. # * Contains embedded double quotes. No problem: # we enclose it in single quotes. # * Embeds both single _and_ double quotes. This # can't happen naturally, but it can happen if # you modify an attribute value after parsing # the document. Now we have a bit of a # problem. We solve it by enclosing the # attribute in single quotes, and escaping any # embedded single quotes to XML entities. if '"' in val: # This can't happen naturally, but it can happen # if you modify an attribute value after parsing. if "'" in val: val = val.replace('"', """) else: fmt = "%s='%s'" # Optionally convert any HTML entities if self.convertHTMLEntities: val = re.sub("&(\w+);", self._convertEntities, val) # Now we're okay w/r/t quotes. But the attribute # value might also contain angle brackets, or # ampersands that aren't part of entities. We need # to escape those to XML entities too. val = val.replace("<", "<").replace(">", ">") val = self.BARE_AMPERSAND.sub("&", val) attrs.append(fmt % (self.toEncoding(key, encoding), self.toEncoding(val, encoding))) close = '' closeTag = '' if self.isSelfClosing: close = ' /' else: closeTag = '' % encodedName indentTag, indentContents = 0, 0 if prettyPrint: indentTag = indentLevel space = (' ' * (indentTag-1)) indentContents = indentTag + 1 contents = self.renderContents(encoding, prettyPrint, indentContents) if self.hidden: s = contents else: s = [] attributeString = '' if attrs: attributeString = ' ' + ' '.join(attrs) if prettyPrint: s.append(space) s.append('<%s%s%s>' % (encodedName, attributeString, close)) if prettyPrint: s.append("\n") s.append(contents) if prettyPrint and contents and contents[-1] != "\n": s.append("\n") if prettyPrint and closeTag: s.append(space) s.append(closeTag) if prettyPrint and closeTag and self.nextSibling: s.append("\n") s = ''.join(s) return s def prettify(self, encoding=DEFAULT_OUTPUT_ENCODING): return self.__str__(encoding, True) def renderContents(self, encoding=DEFAULT_OUTPUT_ENCODING, prettyPrint=False, indentLevel=0): """Renders the contents of this tag as a string in the given encoding. If encoding is None, returns a Unicode string..""" s=[] for c in self: text = None if isinstance(c, NavigableString): text = c.__str__(encoding) elif isinstance(c, Tag): s.append(c.__str__(encoding, prettyPrint, indentLevel)) if text and prettyPrint: text = text.strip() if text: if prettyPrint: s.append(" " * (indentLevel-1)) s.append(text) if prettyPrint: s.append("\n") return ''.join(s) #Soup methods def find(self, name=None, attrs={}, recursive=True, text=None, **kwargs): """Return only the first child of this Tag matching the given criteria.""" r = None l = self.findAll(name, attrs, recursive, text, 1, **kwargs) if l: r = l[0] return r findChild = find def findAll(self, name=None, attrs={}, recursive=True, text=None, limit=None, **kwargs): """Extracts a list of Tag objects that match the given criteria. You can specify the name of the Tag and any attributes you want the Tag to have. The value of a key-value pair in the 'attrs' map can be a string, a list of strings, a regular expression object, or a callable that takes a string and returns whether or not the string matches for some custom definition of 'matches'. The same is true of the tag name.""" generator = self.recursiveChildGenerator if not recursive: generator = self.childGenerator return self._findAll(name, attrs, text, limit, generator, **kwargs) findChildren = findAll # Pre-3.x compatibility methods first = find fetch = findAll def fetchText(self, text=None, recursive=True, limit=None): return self.findAll(text=text, recursive=recursive, limit=limit) def firstText(self, text=None, recursive=True): return self.find(text=text, recursive=recursive) #Utility methods def append(self, tag): """Appends the given tag to the contents of this tag.""" self.contents.append(tag) #Private methods def _getAttrMap(self): """Initializes a map representation of this tag's attributes, if not already initialized.""" if not getattr(self, 'attrMap'): self.attrMap = {} for (key, value) in self.attrs: self.attrMap[key] = value return self.attrMap #Generator methods def childGenerator(self): for i in range(0, len(self.contents)): yield self.contents[i] raise StopIteration def recursiveChildGenerator(self): stack = [(self, 0)] while stack: tag, start = stack.pop() if isinstance(tag, Tag): for i in range(start, len(tag.contents)): a = tag.contents[i] yield a if isinstance(a, Tag) and tag.contents: if i < len(tag.contents) - 1: stack.append((tag, i+1)) stack.append((a, 0)) break raise StopIteration # Next, a couple classes to represent queries and their results. class SoupStrainer: """Encapsulates a number of ways of matching a markup element (tag or text).""" def __init__(self, name=None, attrs={}, text=None, **kwargs): self.name = name if isString(attrs): kwargs['class'] = attrs attrs = None if kwargs: if attrs: attrs = attrs.copy() attrs.update(kwargs) else: attrs = kwargs self.attrs = attrs self.text = text def __str__(self): if self.text: return self.text else: return "%s|%s" % (self.name, self.attrs) def searchTag(self, markupName=None, markupAttrs={}): found = None markup = None if isinstance(markupName, Tag): markup = markupName markupAttrs = markup callFunctionWithTagData = callable(self.name) \ and not isinstance(markupName, Tag) if (not self.name) \ or callFunctionWithTagData \ or (markup and self._matches(markup, self.name)) \ or (not markup and self._matches(markupName, self.name)): if callFunctionWithTagData: match = self.name(markupName, markupAttrs) else: match = True markupAttrMap = None for attr, matchAgainst in self.attrs.items(): if not markupAttrMap: if hasattr(markupAttrs, 'get'): markupAttrMap = markupAttrs else: markupAttrMap = {} for k,v in markupAttrs: markupAttrMap[k] = v attrValue = markupAttrMap.get(attr) if not self._matches(attrValue, matchAgainst): match = False break if match: if markup: found = markup else: found = markupName return found def search(self, markup): #print 'looking for %s in %s' % (self, markup) found = None # If given a list of items, scan it for a text element that # matches. if isList(markup) and not isinstance(markup, Tag): for element in markup: if isinstance(element, NavigableString) \ and self.search(element): found = element break # If it's a Tag, make sure its name or attributes match. # Don't bother with Tags if we're searching for text. elif isinstance(markup, Tag): if not self.text: found = self.searchTag(markup) # If it's text, make sure the text matches. elif isinstance(markup, NavigableString) or \ isString(markup): if self._matches(markup, self.text): found = markup else: raise Exception, "I don't know how to match against a %s" \ % markup.__class__ return found def _matches(self, markup, matchAgainst): #print "Matching %s against %s" % (markup, matchAgainst) result = False if matchAgainst == True and type(matchAgainst) == types.BooleanType: result = markup != None elif callable(matchAgainst): result = matchAgainst(markup) else: #Custom match methods take the tag as an argument, but all #other ways of matching match the tag name as a string. if isinstance(markup, Tag): markup = markup.name if markup and not isString(markup): markup = unicode(markup) #Now we know that chunk is either a string, or None. if hasattr(matchAgainst, 'match'): # It's a regexp object. result = markup and matchAgainst.search(markup) elif isList(matchAgainst): result = markup in matchAgainst elif hasattr(matchAgainst, 'items'): result = markup.has_key(matchAgainst) elif matchAgainst and isString(markup): if isinstance(markup, unicode): matchAgainst = unicode(matchAgainst) else: matchAgainst = str(matchAgainst) if not result: result = matchAgainst == markup return result class ResultSet(list): """A ResultSet is just a list that keeps track of the SoupStrainer that created it.""" def __init__(self, source): list.__init__([]) self.source = source # Now, some helper functions. def isList(l): """Convenience method that works with all 2.x versions of Python to determine whether or not something is listlike.""" return hasattr(l, '__iter__') \ or (type(l) in (types.ListType, types.TupleType)) def isString(s): """Convenience method that works with all 2.x versions of Python to determine whether or not something is stringlike.""" try: return isinstance(s, unicode) or isinstance(s, basestring) except NameError: return isinstance(s, str) def buildTagMap(default, *args): """Turns a list of maps, lists, or scalars into a single map. Used to build the SELF_CLOSING_TAGS, NESTABLE_TAGS, and NESTING_RESET_TAGS maps out of lists and partial maps.""" built = {} for portion in args: if hasattr(portion, 'items'): #It's a map. Merge it. for k,v in portion.items(): built[k] = v elif isList(portion): #It's a list. Map each item to the default. for k in portion: built[k] = default else: #It's a scalar. Map it to the default. built[portion] = default return built # Now, the parser classes. class BeautifulStoneSoup(Tag, SGMLParser): """This class contains the basic parser and search code. It defines a parser that knows nothing about tag behavior except for the following: You can't close a tag without closing all the tags it encloses. That is, "" actually means "". [Another possible explanation is "", but since this class defines no SELF_CLOSING_TAGS, it will never use that explanation.] This class is useful for parsing XML or made-up markup languages, or when BeautifulSoup makes an assumption counter to what you were expecting.""" SELF_CLOSING_TAGS = {} NESTABLE_TAGS = {} RESET_NESTING_TAGS = {} QUOTE_TAGS = {} MARKUP_MASSAGE = [(re.compile('(<[^<>]*)/>'), lambda x: x.group(1) + ' />'), (re.compile(']*)>'), lambda x: '') ] ROOT_TAG_NAME = u'[document]' HTML_ENTITIES = "html" XML_ENTITIES = "xml" ALL_ENTITIES = [HTML_ENTITIES, XML_ENTITIES] def __init__(self, markup="", parseOnlyThese=None, fromEncoding=None, markupMassage=True, smartQuotesTo=XML_ENTITIES, convertEntities=None, selfClosingTags=None): """The Soup object is initialized as the 'root tag', and the provided markup (which can be a string or a file-like object) is fed into the underlying parser. sgmllib will process most bad HTML, and the BeautifulSoup class has some tricks for dealing with some HTML that kills sgmllib, but Beautiful Soup can nonetheless choke or lose data if your data uses self-closing tags or declarations incorrectly. By default, Beautiful Soup uses regexes to sanitize input, avoiding the vast majority of these problems. If the problems don't apply to you, pass in False for markupMassage, and you'll get better performance. The default parser massage techniques fix the two most common instances of invalid HTML that choke sgmllib:
(No space between name of closing tag and tag close) (Extraneous whitespace in declaration) You can pass in a custom list of (RE object, replace method) tuples to get Beautiful Soup to scrub your input the way you want.""" self.parseOnlyThese = parseOnlyThese self.fromEncoding = fromEncoding self.smartQuotesTo = smartQuotesTo if convertEntities: # It doesn't make sense to convert encoded characters to # entities even while you're converting entities to Unicode. # Just convert it all to Unicode. self.smartQuotesTo = None if isList(convertEntities): self.convertHTMLEntities = self.HTML_ENTITIES in convertEntities self.convertXMLEntities = self.XML_ENTITIES in convertEntities else: self.convertHTMLEntities = self.HTML_ENTITIES == convertEntities self.convertXMLEntities = self.XML_ENTITIES == convertEntities self.instanceSelfClosingTags = buildTagMap(None, selfClosingTags) SGMLParser.__init__(self) if hasattr(markup, 'read'): # It's a file-type object. markup = markup.read() self.markup = markup self.markupMassage = markupMassage try: self._feed() except StopParsing: pass self.markup = None # The markup can now be GCed def _feed(self, inDocumentEncoding=None): # Convert the document to Unicode. markup = self.markup if isinstance(markup, unicode): if not hasattr(self, 'originalEncoding'): self.originalEncoding = None else: dammit = UnicodeDammit\ (markup, [self.fromEncoding, inDocumentEncoding], smartQuotesTo=self.smartQuotesTo) markup = dammit.unicode self.originalEncoding = dammit.originalEncoding if markup: if self.markupMassage: if not isList(self.markupMassage): self.markupMassage = self.MARKUP_MASSAGE for fix, m in self.markupMassage: markup = fix.sub(m, markup) self.reset() SGMLParser.feed(self, markup or "") SGMLParser.close(self) # Close out any unfinished strings and close all the open tags. self.endData() while self.currentTag.name != self.ROOT_TAG_NAME: self.popTag() def __getattr__(self, methodName): """This method routes method call requests to either the SGMLParser superclass or the Tag superclass, depending on the method name.""" #print "__getattr__ called on %s.%s" % (self.__class__, methodName) if methodName.find('start_') == 0 or methodName.find('end_') == 0 \ or methodName.find('do_') == 0: return SGMLParser.__getattr__(self, methodName) elif methodName.find('__') != 0: return Tag.__getattr__(self, methodName) else: raise AttributeError def isSelfClosingTag(self, name): """Returns true iff the given string is the name of a self-closing tag according to this parser.""" return self.SELF_CLOSING_TAGS.has_key(name) \ or self.instanceSelfClosingTags.has_key(name) def reset(self): Tag.__init__(self, self, self.ROOT_TAG_NAME) self.hidden = 1 SGMLParser.reset(self) self.currentData = [] self.currentTag = None self.tagStack = [] self.quoteStack = [] self.pushTag(self) def popTag(self): tag = self.tagStack.pop() # Tags with just one string-owning child get the child as a # 'string' property, so that soup.tag.string is shorthand for # soup.tag.contents[0] if len(self.currentTag.contents) == 1 and \ isinstance(self.currentTag.contents[0], NavigableString): self.currentTag.string = self.currentTag.contents[0] #print "Pop", tag.name if self.tagStack: self.currentTag = self.tagStack[-1] return self.currentTag def pushTag(self, tag): #print "Push", tag.name if self.currentTag: self.currentTag.append(tag) self.tagStack.append(tag) self.currentTag = self.tagStack[-1] def endData(self, containerClass=NavigableString): if self.currentData: currentData = ''.join(self.currentData) if currentData.endswith('<') and self.convertHTMLEntities: currentData = currentData[:-1] + '<' if not currentData.strip(): if '\n' in currentData: currentData = '\n' else: currentData = ' ' self.currentData = [] if self.parseOnlyThese and len(self.tagStack) <= 1 and \ (not self.parseOnlyThese.text or \ not self.parseOnlyThese.search(currentData)): return o = containerClass(currentData) o.setup(self.currentTag, self.previous) if self.previous: self.previous.next = o self.previous = o self.currentTag.contents.append(o) def _popToTag(self, name, inclusivePop=True): """Pops the tag stack up to and including the most recent instance of the given tag. If inclusivePop is false, pops the tag stack up to but *not* including the most recent instqance of the given tag.""" #print "Popping to %s" % name if name == self.ROOT_TAG_NAME: return numPops = 0 mostRecentTag = None for i in range(len(self.tagStack)-1, 0, -1): if name == self.tagStack[i].name: numPops = len(self.tagStack)-i break if not inclusivePop: numPops = numPops - 1 for i in range(0, numPops): mostRecentTag = self.popTag() return mostRecentTag def _smartPop(self, name): """We need to pop up to the previous tag of this type, unless one of this tag's nesting reset triggers comes between this tag and the previous tag of this type, OR unless this tag is a generic nesting trigger and another generic nesting trigger comes between this tag and the previous tag of this type. Examples:

FooBar

should pop to 'p', not 'b'.

FooBar

should pop to 'table', not 'p'.

Foo

Bar

should pop to 'tr', not 'p'.

FooBar

should pop to 'p', not 'b'.

    • *
    • * should pop to 'ul', not the first 'li'.
  • ** should pop to 'table', not the first 'tr' tag should implicitly close the previous tag within the same
    ** should pop to 'tr', not the first 'td' """ nestingResetTriggers = self.NESTABLE_TAGS.get(name) isNestable = nestingResetTriggers != None isResetNesting = self.RESET_NESTING_TAGS.has_key(name) popTo = None inclusive = True for i in range(len(self.tagStack)-1, 0, -1): p = self.tagStack[i] if (not p or p.name == name) and not isNestable: #Non-nestable tags get popped to the top or to their #last occurance. popTo = name break if (nestingResetTriggers != None and p.name in nestingResetTriggers) \ or (nestingResetTriggers == None and isResetNesting and self.RESET_NESTING_TAGS.has_key(p.name)): #If we encounter one of the nesting reset triggers #peculiar to this tag, or we encounter another tag #that causes nesting to reset, pop up to but not #including that tag. popTo = p.name inclusive = False break p = p.parent if popTo: self._popToTag(popTo, inclusive) def unknown_starttag(self, name, attrs, selfClosing=0): #print "Start tag %s: %s" % (name, attrs) if self.quoteStack: #This is not a real tag. #print "<%s> is not real!" % name attrs = ''.join(map(lambda(x, y): ' %s="%s"' % (x, y), attrs)) self.currentData.append('<%s%s>' % (name, attrs)) return self.endData() if not self.isSelfClosingTag(name) and not selfClosing: self._smartPop(name) if self.parseOnlyThese and len(self.tagStack) <= 1 \ and (self.parseOnlyThese.text or not self.parseOnlyThese.searchTag(name, attrs)): return tag = Tag(self, name, attrs, self.currentTag, self.previous) if self.previous: self.previous.next = tag self.previous = tag self.pushTag(tag) if selfClosing or self.isSelfClosingTag(name): self.popTag() if name in self.QUOTE_TAGS: #print "Beginning quote (%s)" % name self.quoteStack.append(name) self.literal = 1 return tag def unknown_endtag(self, name): #print "End tag %s" % name if self.quoteStack and self.quoteStack[-1] != name: #This is not a real end tag. #print " is not real!" % name self.currentData.append('' % name) return self.endData() self._popToTag(name) if self.quoteStack and self.quoteStack[-1] == name: self.quoteStack.pop() self.literal = (len(self.quoteStack) > 0) def handle_data(self, data): if self.convertHTMLEntities: if data[0] == '&': data = self.BARE_AMPERSAND.sub("&",data) else: data = data.replace('&','&') \ .replace('<','<') \ .replace('>','>') self.currentData.append(data) def _toStringSubclass(self, text, subclass): """Adds a certain piece of text to the tree as a NavigableString subclass.""" self.endData() self.handle_data(text) self.endData(subclass) def handle_pi(self, text): """Handle a processing instruction as a ProcessingInstruction object, possibly one with a %SOUP-ENCODING% slot into which an encoding will be plugged later.""" if text[:3] == "xml": text = "xml version='1.0' encoding='%SOUP-ENCODING%'" self._toStringSubclass(text, ProcessingInstruction) def handle_comment(self, text): "Handle comments as Comment objects." self._toStringSubclass(text, Comment) def handle_charref(self, ref): "Handle character references as data." if ref[0] == 'x': data = unichr(int(ref[1:],16)) else: data = unichr(int(ref)) if u'\x80' <= data <= u'\x9F': data = UnicodeDammit.subMSChar(chr(ord(data)), self.smartQuotesTo) elif not self.convertHTMLEntities and not self.convertXMLEntities: data = '&#%s;' % ref self.handle_data(data) def handle_entityref(self, ref): """Handle entity references as data, possibly converting known HTML entity references to the corresponding Unicode characters.""" replaceWithXMLEntity = self.convertXMLEntities and \ self.XML_ENTITIES_TO_CHARS.has_key(ref) if self.convertHTMLEntities or replaceWithXMLEntity: try: data = unichr(name2codepoint[ref]) except KeyError: if replaceWithXMLEntity: data = self.XML_ENTITIES_TO_CHARS.get(ref) else: data="&%s" % ref else: data = '&%s;' % ref self.handle_data(data) def handle_decl(self, data): "Handle DOCTYPEs and the like as Declaration objects." self._toStringSubclass(data, Declaration) def parse_declaration(self, i): """Treat a bogus SGML declaration as raw data. Treat a CDATA declaration as a CData object.""" j = None if self.rawdata[i:i+9] == '', i) if k == -1: k = len(self.rawdata) data = self.rawdata[i+9:k] j = k+3 self._toStringSubclass(data, CData) else: try: j = SGMLParser.parse_declaration(self, i) except SGMLParseError: toHandle = self.rawdata[i:] self.handle_data(toHandle) j = i + len(toHandle) return j class BeautifulSoup(BeautifulStoneSoup): """This parser knows the following facts about HTML: * Some tags have no closing tag and should be interpreted as being closed as soon as they are encountered. * The text inside some tags (ie. 'script') may contain tags which are not really part of the document and which should be parsed as text, not tags. If you want to parse the text as tags, you can always fetch it and parse it explicitly. * Tag nesting rules: Most tags can't be nested at all. For instance, the occurance of a

    tag should implicitly close the previous

    tag.

    Para1

    Para2 should be transformed into:

    Para1

    Para2 Some tags can be nested arbitrarily. For instance, the occurance of a

    tag should _not_ implicitly close the previous
    tag. Alice said:
    Bob said:
    Blah should NOT be transformed into: Alice said:
    Bob said:
    Blah Some tags can be nested, but the nesting is reset by the interposition of other tags. For instance, a
    , but not close a tag in another table.
    BlahBlah should be transformed into:
    BlahBlah but, Blah
    Blah should NOT be transformed into Blah
    Blah Differing assumptions about tag nesting rules are a major source of problems with the BeautifulSoup class. If BeautifulSoup is not treating as nestable a tag your page author treats as nestable, try ICantBelieveItsBeautifulSoup, MinimalSoup, or BeautifulStoneSoup before writing your own subclass.""" def __init__(self, *args, **kwargs): if not kwargs.has_key('smartQuotesTo'): kwargs['smartQuotesTo'] = self.HTML_ENTITIES BeautifulStoneSoup.__init__(self, *args, **kwargs) SELF_CLOSING_TAGS = buildTagMap(None, ['br' , 'hr', 'input', 'img', 'meta', 'spacer', 'link', 'frame', 'base']) QUOTE_TAGS = {'script': None} #According to the HTML standard, each of these inline tags can #contain another tag of the same type. Furthermore, it's common #to actually use these tags this way. NESTABLE_INLINE_TAGS = ['span', 'font', 'q', 'object', 'bdo', 'sub', 'sup', 'center'] #According to the HTML standard, these block tags can contain #another tag of the same type. Furthermore, it's common #to actually use these tags this way. NESTABLE_BLOCK_TAGS = ['blockquote', 'div', 'fieldset', 'ins', 'del'] #Lists can contain other lists, but there are restrictions. NESTABLE_LIST_TAGS = { 'ol' : [], 'ul' : [], 'li' : ['ul', 'ol'], 'dl' : [], 'dd' : ['dl'], 'dt' : ['dl'] } #Tables can contain other tables, but there are restrictions. NESTABLE_TABLE_TAGS = {'table' : [], 'tr' : ['table', 'tbody', 'tfoot', 'thead'], 'td' : ['tr'], 'th' : ['tr'], 'thead' : ['table'], 'tbody' : ['table'], 'tfoot' : ['table'], } NON_NESTABLE_BLOCK_TAGS = ['address', 'form', 'p', 'pre'] #If one of these tags is encountered, all tags up to the next tag of #this type are popped. RESET_NESTING_TAGS = buildTagMap(None, NESTABLE_BLOCK_TAGS, 'noscript', NON_NESTABLE_BLOCK_TAGS, NESTABLE_LIST_TAGS, NESTABLE_TABLE_TAGS) NESTABLE_TAGS = buildTagMap([], NESTABLE_INLINE_TAGS, NESTABLE_BLOCK_TAGS, NESTABLE_LIST_TAGS, NESTABLE_TABLE_TAGS) # Used to detect the charset in a META tag; see start_meta CHARSET_RE = re.compile("((^|;)\s*charset=)([^;]*)") def start_meta(self, attrs): """Beautiful Soup can detect a charset included in a META tag, try to convert the document to that charset, and re-parse the document from the beginning.""" httpEquiv = None contentType = None contentTypeIndex = None tagNeedsEncodingSubstitution = False for i in range(0, len(attrs)): key, value = attrs[i] key = key.lower() if key == 'http-equiv': httpEquiv = value elif key == 'content': contentType = value contentTypeIndex = i if httpEquiv and contentType: # It's an interesting meta tag. match = self.CHARSET_RE.search(contentType) if match: if getattr(self, 'declaredHTMLEncoding') or \ (self.originalEncoding == self.fromEncoding): # This is our second pass through the document, or # else an encoding was specified explicitly and it # worked. Rewrite the meta tag. newAttr = self.CHARSET_RE.sub\ (lambda(match):match.group(1) + "%SOUP-ENCODING%", value) attrs[contentTypeIndex] = (attrs[contentTypeIndex][0], newAttr) tagNeedsEncodingSubstitution = True else: # This is our first pass through the document. # Go through it again with the new information. newCharset = match.group(3) if newCharset and newCharset != self.originalEncoding: self.declaredHTMLEncoding = newCharset self._feed(self.declaredHTMLEncoding) raise StopParsing tag = self.unknown_starttag("meta", attrs) if tag and tagNeedsEncodingSubstitution: tag.containsSubstitutions = True class StopParsing(Exception): pass class ICantBelieveItsBeautifulSoup(BeautifulSoup): """The BeautifulSoup class is oriented towards skipping over common HTML errors like unclosed tags. However, sometimes it makes errors of its own. For instance, consider this fragment: FooBar This is perfectly valid (if bizarre) HTML. However, the BeautifulSoup class will implicitly close the first b tag when it encounters the second 'b'. It will think the author wrote "FooBar", and didn't close the first 'b' tag, because there's no real-world reason to bold something that's already bold. When it encounters '' it will close two more 'b' tags, for a grand total of three tags closed instead of two. This can throw off the rest of your document structure. The same is true of a number of other tags, listed below. It's much more common for someone to forget to close a 'b' tag than to actually use nested 'b' tags, and the BeautifulSoup class handles the common case. This class handles the not-co-common case: where you can't believe someone wrote what they did, but it's valid HTML and BeautifulSoup screwed up by assuming it wouldn't be.""" I_CANT_BELIEVE_THEYRE_NESTABLE_INLINE_TAGS = \ ['em', 'big', 'i', 'small', 'tt', 'abbr', 'acronym', 'strong', 'cite', 'code', 'dfn', 'kbd', 'samp', 'strong', 'var', 'b', 'big'] I_CANT_BELIEVE_THEYRE_NESTABLE_BLOCK_TAGS = ['noscript'] NESTABLE_TAGS = buildTagMap([], BeautifulSoup.NESTABLE_TAGS, I_CANT_BELIEVE_THEYRE_NESTABLE_BLOCK_TAGS, I_CANT_BELIEVE_THEYRE_NESTABLE_INLINE_TAGS) class MinimalSoup(BeautifulSoup): """The MinimalSoup class is for parsing HTML that contains pathologically bad markup. It makes no assumptions about tag nesting, but it does know which tags are self-closing, that

    Kss development mode browser setup

    Different browser side parameters can be set up.

    @@kss_devel_mode/ison on the current context

    Kss development mode is on off

    Set kss development mode cookie

    The cookie is global to the site and may be overridden by a local utility (eg. ResourceRegistries, in Plone)

    Click the button here.
    PK i7Le͡-kss/core/pluginregistry/browser/develview.pyc; %4Gc@sydklZeWn ej odklZnXdklZdklZdkl Z dk l Z dk l Z dZdefdYZd S( (s BrowserView(sViewPageTemplateFile(s IDevelView(s implements(s ITraverser(sNotFounds __kss_devels DevelViewcBstZeedZdZdZedZdZ dZ e ddd Z d Z d Zd Zd ZRS(NcCs@yt||SWn(tj ot|i||nXdS(N(sgetattrsselfsnamesAttributeErrorsNotFoundscontextsrequest(sselfsrequestsname((sGbuild/bdist.linux-i686/egg/kss/core/pluginregistry/browser/develview.pyspublishTraversescCs|dffSdS(Nsui(sself(sselfsrequest((sGbuild/bdist.linux-i686/egg/kss/core/pluginregistry/browser/develview.pysbrowserDefault#scCsnt|iij}| o@y2dkl}||iid}|i }WqZqZXnt |}|SdS(sChecks if running in development mode Two ways to induce development mode: - set the cookie on the request - switch portal_js tool into debug mode, this will select development mode without the cookie (s getToolByNamesportal_javascriptsN( s COOKIE_NAMEsselfsrequestscookiessisonsProducts.CMFCore.utilss getToolByNamescontextsaq_innersjs_tools getDebugModesboolsresult(sselfsisonsjs_toolsresults getToolByName((sGbuild/bdist.linux-i686/egg/kss/core/pluginregistry/browser/develview.pysison+s   cCs2|i }|tj ot|}n|SdS(s#Check if running in production modeN(sselfsisonsresultsREQUESTsNonesstr(sselfsREQUESTsresult((sGbuild/bdist.linux-i686/egg/kss/core/pluginregistry/browser/develview.pysisoffFs   cCs |iiitddddS(sSets development mode cookies1spaths/N(sselfsrequestsresponses setCookies COOKIE_NAME(sself((sGbuild/bdist.linux-i686/egg/kss/core/pluginregistry/browser/develview.pyssetMscCs|iiitdddS(sUnsets development mode cookiespaths/N(sselfsrequestsresponses expireCookies COOKIE_NAME(sself((sGbuild/bdist.linux-i686/egg/kss/core/pluginregistry/browser/develview.pysunsetQss develui.pts content_typestext/html;charset=utf-8cCsh}d|iijo|it|d PK i741kss/core/pluginregistry/deprecated/directives.pyc; %4Gc@sxdklZdklZlZdklZlZlZl Z defdYZ dk l Z l Z lZlZdS((s Interface(sTextLinesChoice(sPathsTokenssPythonIdentifiersGlobalInterfacesIRegisterCommandDirectivecBsDtZdZedddddeZedddddeZRS(sRegister a KSS command pluginstitleuNames descriptionuThe name of the command plugin.srequireduJavascript fileu7The path of the javascript file that defines the plugin( s__name__s __module__s__doc__sTextLinesTruesnamesPathsFalsesjsfile(((sKbuild/bdist.linux-i686/egg/kss/core/pluginregistry/deprecated/directives.pysIRegisterCommandDirectives    (sIRegisterEventTypeDirectivesIRegisterActionDirectivesIRegisterSelectorTypeDirectivesIRegisterCommandSetDirectiveN(szope.interfaces Interfaces zope.schemasTextLinesChoiceszope.configuration.fieldssPathsTokenssPythonIdentifiersGlobalInterfacesIRegisterCommandDirectives"kss.core.pluginregistry.directivessIRegisterEventTypeDirectivesIRegisterActionDirectivesIRegisterSelectorTypeDirectivesIRegisterCommandSetDirective( sIRegisterCommandSetDirectivesIRegisterCommandDirectivesIRegisterSelectorTypeDirectivesChoicesTokenssPythonIdentifiers InterfacesPathsTextLinesGlobalInterfacesIRegisterEventTypeDirectivesIRegisterActionDirective((sKbuild/bdist.linux-i686/egg/kss/core/pluginregistry/deprecated/directives.pys?s PK i7' /kss/core/pluginregistry/deprecated/__init__.pyc; %4Gc@s dZdS(s Module init N(s__doc__(((sIbuild/bdist.linux-i686/egg/kss/core/pluginregistry/deprecated/__init__.pys?sPK i720kss/core/pluginregistry/deprecated/configure.pyc; %4Gc@sdkZdklZdklZdklZdkl Z dk l Z e dZe eddZe e id d Ze e id d Ze e id dZe e iddZdS(N(sICommand(sCommand(sregisterPlugin(sdeprecated_directive(s configurec CsY|tj ot|din|idd||fdtdtt ||fdS(s"Directive that registers a commandsrbs discriminatorsregisterKssCommandscallablesargsN( sjsfilesNonesfilescloses_contextsactionsnamesregisterPluginsCommandsICommand(s_contextsnamesjsfile((sJbuild/bdist.linux-i686/egg/kss/core/pluginregistry/deprecated/configure.pysregisterCommand s  sazax:registerCommandsBuse kss:registerAction with command_factory="selector" or "global"sazax:registerEventTypes!use kss:registerEventType insteadsazax:registerActionsuse kss:registerAction insteadsazax:registerSelectorTypes$use kss:registerSelectorType insteadsazax:registerCommandSets"use kss:registerCommandSet instead(sos.pathsoss"kss.core.pluginregistry.interfacessICommandskss.core.pluginregistry.commandsCommandskss.core.pluginregistry.pluginsregisterPluginskss.core.deprecatedsdeprecated_directiveskss.core.pluginregistrys configures _configuresNonesregisterCommandsregisterEventTypesregisterActionsregisterSelectorTypesregisterCommandSet( sICommandsregisterSelectorTypesregisterEventTypesdeprecated_directivesregisterCommandsregisterCommandSetsCommandsregisterActionsregisterPlugins _configuresos((sJbuild/bdist.linux-i686/egg/kss/core/pluginregistry/deprecated/configure.pys?s        PK2i785%::(kss/core/pluginregistry/json/__init__.py'''\ Module init ''' from utils import getJsonAddonFiles PK2i7D %kss/core/pluginregistry/json/utils.py'''\ Supplemental support for json plugins ''' import os.path, logging import zope.component as capi from zope.interface import implements, Interface from zope.publisher.browser import TestRequest from interfaces import IJSONStreamWriteable logger = logging.getLogger('kss.core') def getJsonAddonFiles(): 'Gets the addon javascript files for json' files = [] # Try adding the jsonserver files request = TestRequest() try: # use the files already registered to that concat resource jsonrpc = capi.getAdapter(request, Interface, 'jsonrpc.js') except capi.ComponentLookupError: pass # JSON not present. else: # JSON present. files.extend(jsonrpc.context.context.getPathList()) # add the json kukit support file plugins_dir = os.path.split(globals()['__file__'])[0] files.append(os.path.join(plugins_dir, 'browser', 'jsonkukit.js')) logger.info('Lazy plugin construction: Installed support for JSON-RPC transport.') return files class JsonCommandView(object): '''View of a command for JSON requests. We siply return the commands since they will be transparently rendered for JSON, via the writer adapter hooks. ''' def __init__(self, context, request): self.context = context self.request = request def render(self): return self.context class KSSCommandWriter(object): 'Writes a command to JSON' implements(IJSONStreamWriteable) def __init__(self, context, writer): self.context = context self.writer = writer def __jsonwrite__(self): writer = self.writer # All is written as a dict d = dict(self.context.__dict__) # params are converted to a dict from a list. # Also get rid of "none" params that were only a hack for xml d['params'] = dict([(param.name, param.content) for param in d['params'] if param.name != 'none']) writer.write_repr(d) PK2i7.*kss/core/pluginregistry/json/interfaces.py# -*- coding: ISO-8859-15 -*- # Copyright (c) 2005-2007 # Authors: KSS Project Contributors (see docs/CREDITS.txt) # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as published # by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. import config from zope.interface import Interface if config.HAS_JSON: IJSONRPCRequest = config.IJSONRPCRequest IJSONStreamWriteable = config.IJSONStreamWriteable IJSONWriter = config.IJSONWriter else: # If jsonserver is not present, we just define interfaces # that noone implements so the adapters will never be looked up. # This is because the zcml will try to import these. # XXX occasionally this should be done from the zcml, # via features/conditionals! class IJSONRPCRequest(Interface): 'Interface never to be implemented' class IJSONStreamWriteable(Interface): 'Interface never to be implemented' class IJSONWriter(Interface): 'Interface never to be implemented' PK2i7u&kss/core/pluginregistry/json/config.py try: import jsonserver from jsonserver.interfaces import IJSONRPCRequest from jsonserver.minjson.interfaces import IJSONStreamWriteable, IJSONWriter except ImportError: try: import Products.jsonserver from Products.jsonserver.interfaces import IJSONRPCRequest from Products.jsonserver.minjson.interfaces import IJSONStreamWriteable, IJSONWriter except ImportError: HAS_JSON = False else: HAS_JSON = True else: HAS_JSON = True PK2i7K4J+kss/core/pluginregistry/json/configure.zcml PK i7)kss/core/pluginregistry/json/__init__.pyc; %4Gc@sdZdklZdS(s Module init (sgetJsonAddonFilesN(s__doc__sutilssgetJsonAddonFiles(sgetJsonAddonFiles((sCbuild/bdist.linux-i686/egg/kss/core/pluginregistry/json/__init__.pys?sPK i7:1>SS&kss/core/pluginregistry/json/utils.pyc; %4Gc@sdZdkZdkZdkiZdklZl Z dk l Z dk l Z eidZdZdefdYZd efd YZdS( s&Supplemental support for json plugins N(s implementss Interface(s TestRequest(sIJSONStreamWriteableskss.corecCsg}t}yti|td}Wntij ondX|i|i i i t i i tdd}|it i i|ddtid|SdS(s(Gets the addon javascript files for jsons jsonrpc.jss__file__isbrowsers jsonkukit.jssCLazy plugin construction: Installed support for JSON-RPC transport.N(sfiless TestRequestsrequestscapis getAdapters InterfacesjsonrpcsComponentLookupErrorsextendscontexts getPathListsosspathssplitsglobalss plugins_dirsappendsjoinsloggersinfo(sfilessrequests plugins_dirsjsonrpc((s@build/bdist.linux-i686/egg/kss/core/pluginregistry/json/utils.pysgetJsonAddonFiles s  sJsonCommandViewcBs tZdZdZdZRS(sView of a command for JSON requests. We siply return the commands since they will be transparently rendered for JSON, via the writer adapter hooks. cCs||_||_dS(N(scontextsselfsrequest(sselfscontextsrequest((s@build/bdist.linux-i686/egg/kss/core/pluginregistry/json/utils.pys__init__(s cCs |iSdS(N(sselfscontext(sself((s@build/bdist.linux-i686/egg/kss/core/pluginregistry/json/utils.pysrender,s(s__name__s __module__s__doc__s__init__srender(((s@build/bdist.linux-i686/egg/kss/core/pluginregistry/json/utils.pysJsonCommandView s  sKSSCommandWritercBs*tZdZeedZdZRS(sWrites a command to JSONcCs||_||_dS(N(scontextsselfswriter(sselfscontextswriter((s@build/bdist.linux-i686/egg/kss/core/pluginregistry/json/utils.pys__init__3s cCs|i}t|ii}tgi}|dD]0}|i djo||i |i fq0q0~|d<|i |dS(Nsparamssnone( sselfswritersdictscontexts__dict__sdsappends_[1]sparamsnamescontents write_repr(sselfsdswritersparams_[1]((s@build/bdist.linux-i686/egg/kss/core/pluginregistry/json/utils.pys __jsonwrite__7s U(s__name__s __module__s__doc__s implementssIJSONStreamWriteables__init__s __jsonwrite__(((s@build/bdist.linux-i686/egg/kss/core/pluginregistry/json/utils.pysKSSCommandWriter/s   (s__doc__sos.pathsossloggingszope.components componentscapiszope.interfaces implementss Interfaceszope.publisher.browsers TestRequests interfacessIJSONStreamWriteables getLoggersloggersgetJsonAddonFilessobjectsJsonCommandViewsKSSCommandWriter( s implementssloggingsKSSCommandWritersgetJsonAddonFilessIJSONStreamWriteablescapis Interfaces TestRequestsloggersossJsonCommandView((s@build/bdist.linux-i686/egg/kss/core/pluginregistry/json/utils.pys?s    PK i7]+kss/core/pluginregistry/json/interfaces.pyc; %4Gc@sdkZdklZeioeiZeiZeiZnCdefdYZdefdYZdefdYZdS(N(s InterfacesIJSONRPCRequestcBstZdZRS(s!Interface never to be implemented(s__name__s __module__s__doc__(((sEbuild/bdist.linux-i686/egg/kss/core/pluginregistry/json/interfaces.pysIJSONRPCRequest!s sIJSONStreamWriteablecBstZdZRS(s!Interface never to be implemented(s__name__s __module__s__doc__(((sEbuild/bdist.linux-i686/egg/kss/core/pluginregistry/json/interfaces.pysIJSONStreamWriteable$s s IJSONWritercBstZdZRS(s!Interface never to be implemented(s__name__s __module__s__doc__(((sEbuild/bdist.linux-i686/egg/kss/core/pluginregistry/json/interfaces.pys IJSONWriter's (sconfigszope.interfaces InterfacesHAS_JSONsIJSONRPCRequestsIJSONStreamWriteables IJSONWriter(s InterfacesIJSONRPCRequestsIJSONStreamWriteablesconfigs IJSONWriter((sEbuild/bdist.linux-i686/egg/kss/core/pluginregistry/json/interfaces.pys?s      PK i7OC'kss/core/pluginregistry/json/config.pyc; %4Gc@sy-dkZdklZdklZlZWnbej oVy-dkZdk lZdk lZlZWnej o e Z qXe Z nXe Z dS(N(sIJSONRPCRequest(sIJSONStreamWriteables IJSONWriter(s jsonserversjsonserver.interfacessIJSONRPCRequestsjsonserver.minjson.interfacessIJSONStreamWriteables IJSONWriters ImportErrorsProducts.jsonserversProductssProducts.jsonserver.interfacess&Products.jsonserver.minjson.interfacessFalsesHAS_JSONsTrue(sIJSONRPCRequests IJSONWritersIJSONStreamWriteablesHAS_JSONsProductss jsonserver((sAbuild/bdist.linux-i686/egg/kss/core/pluginregistry/json/config.pys?s      PK1i7>F   1kss/core/pluginregistry/json/browser/jsonkukit.js /* * Copyright (c) 2005-2006 * Authors: * Balázs Reé * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ /* * Supplemental script for json * * This gets included when json plugins are registered. * * This transparently replaces the normal transport with JSON. * To do this, we overwrite notifyServer and at one point we * return to the normal execution chain (after results are received). * (We need to do this because even an old style event plugin may * invoke new style command plugins as a response.) * * To manually call the server from an event plugin, the * makeJSONKukitMethod function should be used to create a * proxy method. */ kukit.makeJSONKukitMethod = function(url, methodName, supplement) { // url and methodName can be used, // or methodName can be set to null and url will be used as a full url. if (typeof(supplement) == 'undefined') { // default timeout is 4 sec... a sane choice supplement = null; } // XXX RequestManager of json is not compatible with kukit's at the moment. return new JSONRPCMethod(url, methodName, kukit.jsonCallback, kukit.jsonError, null, supplement, null, null); } // OVERWRITE kukit.js kukit.notifyServer = function(url, params, oper) { var f = function(queueItem) { // store the queue reception on the oper oper.queueItem = queueItem; // sending form, with standard form parameters. var method = kukit.makeJSONKukitMethod(url, null, oper); method(params); }; kukit.requestManager.notifyServer(f, url); } kukit.jsonCallback = function(result, oper) { // notify the queue that we are done var success = oper.queueItem.receivedResult() // We only process if the response has not been timed // out by the queue in the meantime. if (success) { try { var command_processor = new kukit.CommandProcessor(); // Transport parm is same as result (although we don't use it) command_processor.parseCommands(result, result); command_processor.executeCommands(oper); } catch(e) { kukit.logError('Error during command execution: ' + e); throw e; } } } kukit.jsonError = function(result, oper) { // XXX at the moment timeouts don't arrive here... // notify the queue that we are done var success = oper.queueItem.receivedResult() kukit.logError('JSON call failed: ' + result); } /* Command execution */ // OVERWRITE kukit.js kukit.CommandProcessor.prototype.parseCommand = function(command, transport) { // Add the command. var command = new kukit.cr.makeCommand(command.selector, command.name, command.selectorType, command.params, transport); this.addCommand(command); } PK7i7<;;=kss/core/pluginregistry/_concatresource/concatfileresource.py'''\ Support for concatenation and compression of resources We concatenate first and compress afterwards, giving a better chance for the compressor to optimize ''' from zope.interface import implements from interfaces import IContextFile # we are aliased to Products, hence the following absolute import from concatresource.interfaces import IConcatResourceAddon from fileresource import File from compression import compress import time import zope.component try: from zope.component.interfaces import ComponentLookupError except ImportError: # Zope < 2.10 from zope.component.exceptions import ComponentLookupError class ConcatFiles(object): '''A resource that concatenates files and compresses the result It is also possible to extend the statically given list via a utility. ''' implements(IContextFile) def __init__(self, pathlist, name, compress_level, caching, lmt_check_period): # Path is now a list. assert isinstance(pathlist, (list, tuple)) # check all files, just to raise error if don't exist for path in pathlist: file(path, 'rb').close() # self.pathlist_base = pathlist self.__name__ = name self.compress_level = compress_level self.caching = caching self.lmt_check_period = lmt_check_period # markers for pathlist modification self.pathlist = [] self.fileslist_changed = None self.fileslist = [] def getPathList(self): 'Gets the extended pathlist' # we allow the list to be extended via an utility try: registry = zope.component.getUtility(IConcatResourceAddon, self.__name__) except ComponentLookupError: extend = [] else: extend = registry.getAddonFiles() pathlist = self.pathlist_base + extend return pathlist def getFilesList(self): 'Gets the list of files' ## # XXX We have two choices: ## # 1. We only calculate the list once, on startup ## # that is, we suppose that the file resource is ## # called up after the extension reg has been finished ## # and that it never changes later. ## # 2. but it also could be like this to allow changes later: pathlist = self.getPathList() if pathlist != self.pathlist: ##if not self.pathlist: ##pathlist = self.getPathList() # mark pathlist modification self.pathlist = pathlist self.fileslist_changed = time.time() fileslist = self.fileslist = [File(path, self.__name__) for path in pathlist] else: fileslist = self.fileslist return fileslist def getLastMod(self): # We take in consideration that the pathlist # itself could have changed too. return max([f.getLastMod() for f in self.getFilesList()] + [self.fileslist_changed]) def getContents(self): fileslist = self.getFilesList() assert fileslist, 'Must contain at least one resource.' result = fileslist[0].getContents() content_type = result['content_type'] data = [result['data']] for subres in fileslist[1:]: d = subres.getContents() # all elements must have the same content type. assert d['content_type'] == content_type data.append(d['data']) result['data'] = '\n'.join(data) result['compress_level'] = self.compress_level # Do compression on the result result['data'] = compress(**result) return result PK7i7ْ339kss/core/pluginregistry/_concatresource/cachingadapter.pyfrom time import time from interfaces import ICachedResource from zope.interface import implements try: from zope.datetime import rfc1123_date except ImportError: # Zope < 2.10 from zope.app.datetimeutils import rfc1123_date class CachedResource(object): 'Adapts a ContextFile to a cached resource' implements(ICachedResource) def __init__(self, context): self.context = context self.lmt_last_checked = 0 self.data_last_fetched = 0 def _fetchdata(self): try: result = self._contents ##print "*****Resource from cached" except AttributeError: result = self._contents = self.context.getContents() self.data_last_fetched = time() ##print "*****Resource kooked" return result def _deldata(self): del self._contents def purgeData(self): 'Force file contents to be reloaded' ##print "***** PURGE", self.context.__name__ try: self._deldata() except AttributeError: pass # Once fetched, data is cached in the object until # explicitely deleted. data = property(lambda self: self._fetchdata()['data'], None, _deldata) content_type = property(lambda self: self._fetchdata()['content_type'], None, _deldata) # Last modified time is calculated on demand # but never more often then lmt_check_period def _fetchlm(self): now = time() if now - self.lmt_last_checked > self.lmt_check_period: self.lmt_last_checked = now lmt = float(self.context.getLastMod()) or now lmh = rfc1123_date(lmt) d = self._last_mod = dict(lmt = lmt, lmh = lmh) ##print "***** LMT reread", d else: d = self._last_mod return d lmt = property(lambda self: self._fetchlm()['lmt']) lmh = property(lambda self: self._fetchlm()['lmh']) caching = property(lambda self: self.context.caching) lmt_check_period = property(lambda self: self.context.lmt_check_period) PK7i7,3kss/core/pluginregistry/_concatresource/__init__.py'''\ Product init ''' # alias myself to python import root, directly try: import sys if not 'concatresource' in sys.modules: # only 1st import is aliased. sys.modules['concatresource'] = sys.modules[globals()['__name__']] except ImportError: pass PK7i7 Z5kss/core/pluginregistry/_concatresource/directives.pyfrom zope.interface import Interface from zope.configuration.fields import GlobalObject, Tokens, Path, \ PythonIdentifier, MessageID from zope.schema import TextLine, Text, Id, Choice, Float from fields import PathList from zope.app.component.metadirectives import IBasicViewInformation from zope.app.publisher.browser.metadirectives import IBasicResourceInformation try: from zope.security.zcml import Permission except ImportError: # Zope < 2.10 from zope.app.security.fields import Permission class IConcatResourceDirective(IBasicResourceInformation): """ Defines a concatenated browser resource """ name = TextLine( title=u"The name of the resource", description=u""" This is the name used in resource urls. Resource urls are of the form site/@@/resourcename, where site is the url of "site", a folder with a service manager. We make resource urls site-relative (as opposed to content-relative) so as not to defeat caches.""", required=True ) files = PathList( title=u"Files", description=u"A space separated list of resource files", required=True ) compress_level = Choice( title=u"Compress level", description=u"Level of compression applied, by default 'safe'.", values=(u'none', u'safe', u'full', u'stripped', u'devel', u'safe-devel', u'full-devel'), required=False, ) caching = Choice( title=u"Caching strategy", description=u"Enables caching in memory for faster debugging, by default not enabled.", values=(u'default', u'memory'), required=False, ) lmt_check_period = Float( title=u"Last modification time checking", description=u"""Sets a grace period in seconds, until which the last modification times are never fetched again from the filesystem. In other words, the system will react after this time for recent changes. For debugging, it is best to set this to 0, for production it can be left to the default 60.0""", required=False, ) PK7i7dE1kss/core/pluginregistry/_concatresource/fields.py from zope.schema import Text from zope.schema.interfaces import IFromUnicode from zope.interface import implements import os.path class PathList(Text): implements(IFromUnicode) def fromUnicode(self, u): result = [] for u in u.split(): if os.path.isabs(u): path = os.path.normpath(u) else: path = self.context.path(u) result.append(path) return result PK7i7ms95kss/core/pluginregistry/_concatresource/interfaces.py from zope.interface import Interface from zope.schema import Bytes, TextLine, Float class IContextFile(Interface): def getLastMod(self): 'Returns last modification time of the file' def getContents(): 'Reads the data and content type of the file' class ICachedResource(Interface): data = Bytes(title = u'The content data of the file') content_type = TextLine(title = u'The mime content type of the file') lmt = Float(title = u'Last modification timestamp') lmh = Float(title = u'Last modification in human readable form') def purgeData(self): 'Purges the cached data' class IConcatResourceAddon(Interface): '''Utility to register addons This can be used to dynamically extend components for a given resource. We don't provide implementation for this here, but other components can implement this to provide dynamic add-ons. The name of the utility should be the name of the resource. ''' def getAddonFiles(request): '''Returns a list of addon files. This will be concatenated to the end of the static list. ''' PK7i7A% /kss/core/pluginregistry/_concatresource/meta.py import os from zope.security.checker import CheckerPublic, NamesChecker from zope.configuration.exceptions import ConfigurationError from zope.publisher.interfaces.browser import IBrowserRequest from zope.app.component.metaconfigure import handler from zope.interface import Interface from resource import ConcatResourceFactory try: import Products.Five except ImportError: __five__ = False else: __five__ = True from Products.Five.metaclass import makeClass from Products.Five.security import getSecurityInfo, protectClass, protectName,\ initializeClass try: from zope.publisher.interfaces.browser import IDefaultBrowserLayer _layer = IDefaultBrowserLayer __pre_3_2__ = False except ImportError: from zope.app.servicenames import Presentation _layer = 'default' __pre_3_2__ = True try: from zope.component import zcml __pre_3_3__ = False except: __pre_3_3__ = True # z3 only allowed_names = ('GET', 'HEAD', 'publishTraverse', 'browserDefault', 'request', '__call__') # We keep this in order to allow an occasional merge to browser:resource _factory_map = { 'files': { 'prefix': 'ConcatResource', 'count': 0, 'factory': ConcatResourceFactory }, } def concatresource(_context, name, files=None, compress_level='safe', caching='default', lmt_check_period=60.0, layer=_layer, permission='zope.Public'): if not files: raise ConfigurationError( "Must use a files" " attribute for concatresource directives, with at least" " one file contained." ) res = files res_type = 'files' factory_info = _factory_map.get(res_type) factory_info['count'] += 1 res_factory = factory_info['factory'] if __five__: checker = None _class_name = '%s%s' % (factory_info['prefix'], factory_info['count']) new_class = makeClass(_class_name, (res_factory.resource,), {}) _context.action( discriminator = ('five:protectClass', new_class), callable = protectClass, args = (new_class, permission) ) _context.action( discriminator = ('five:initialize:class', new_class), callable = initializeClass, args = (new_class,) ) else: new_class = res_factory.resource if permission == 'zope.Public': permission = CheckerPublic checker = NamesChecker(allowed_names, permission) factory = res_factory(res, name, compress_level, caching, lmt_check_period, resource_factory=new_class, checker=checker) if __pre_3_2__: _context.action( discriminator = ('resource', name, IBrowserRequest, layer), callable = handler, args = (Presentation, 'provideResource', name, IBrowserRequest, factory, layer), ) else: if __pre_3_3__: _context.action( discriminator = ('resource', name, IBrowserRequest, layer), callable = handler, args = ('provideAdapter', (layer,), Interface, name, factory, _context.info), ) else: _context.action( discriminator = ('resource', name, IBrowserRequest, layer), callable = handler, args = ('registerAdapter', factory, (layer,), Interface, name, _context.info), ) PK7i7Hgsŀ3kss/core/pluginregistry/_concatresource/resource.pyfrom zope.publisher.interfaces.browser import IBrowserPublisher from zope.interface import implements from concatfileresource import ConcatFiles from interfaces import ICachedResource import cachingadapter # force adapter registration try: from zope.publisher.browser import BrowserView from zope.datetime import time as timeFromDateTimeString except ImportError: # Zope < 2.10 from zope.app.publisher.browser import BrowserView from zope.app.datetimeutils import time as timeFromDateTimeString try: import Products.Five except ImportError: __five__ = False from zope.app.publisher.browser.resource import Resource else: __five__ = True try: # Zope 2.8 / Five 1.0.2 from Products.Five.resource import Resource __five_pre_1_3_ = True except ImportError: # Zope 2.9 / Five 1.3 from Products.Five.browser.resource import Resource __five_pre_1_3__ = False class GenericResource(BrowserView, Resource): """A publishable resource""" if __five__: #implements(IBrowserPublisher) def __browser_default__(self, request): return self, (request.REQUEST_METHOD,) else: implements(IBrowserPublisher) def publishTraverse(self, request, name): '''See interface IBrowserPublisher''' raise LookupError(name) def browserDefault(self, request): '''See interface IBrowserPublisher''' return getattr(self, request.method), () # for unit tests def _testData(self): return self.context.data def chooseContext(self): """Choose the appropriate context""" return self.context def GET(self): """Default document""" file = self.chooseContext() request = self.request response = request.response # Control in-memory caching cache_in_memory = file.caching == 'memory' if cache_in_memory: last_mod = file.lmt if last_mod > file.data_last_fetched: # force delete file contents file.purgeData() # HTTP If-Modified-Since header handling. This is duplicated # from OFS.Image.Image - it really should be consolidated # somewhere... if __five__: header = request.get_header('If-Modified-Since') else: header = request.getHeader('If-Modified-Since', None) if header is not None: header = header.split(';')[0] # Some proxies seem to send invalid date strings for this # header. If the date string is not valid, we ignore it # rather than raise an error to be generally consistent # with common servers such as Apache (which can usually # understand the screwy date string as a lucky side effect # of the way they parse it). try: mod_since=long(timeFromDateTimeString(header)) except: mod_since=None if mod_since is not None: if not cache_in_memory: last_mod = file.lmt if last_mod > 0 and int(last_mod) <= mod_since: response.setStatus(304) return '' response.setHeader('Content-Type', file.content_type) response.setHeader('Last-Modified', file.lmh) # Cache for one day response.setHeader('Cache-Control', 'public,max-age=86400') data = file.data if not cache_in_memory: # force delete file contents file.purgeData() return data def HEAD(self): file = self.chooseContext() response = self.request.response response.setHeader('Content-Type', file.content_type) response.setHeader('Last-Modified', file.lmh) # Cache for one day response.setHeader('Cache-Control', 'public,max-age=86400') return '' class ResourceFactory(object): factory = None resource = None def __init__(self, path, name, compress_level, caching, lmt_check_period, resource_factory=None, checker=None): self.__name = name self.__path = path self.__compress_level = compress_level self.__caching = caching self.__lmt_check_period = lmt_check_period if resource_factory is not None: self.resource = resource_factory # z3 only self.__checker = checker def __call__(self, request): try: rsrc = self.__rsrc except AttributeError: # Delayed creation. That assures that registry is set up by this time. rsrc = self.__rsrc = ICachedResource(self.factory(self.__path, self.__name, self.__compress_level, self.__caching, self.__lmt_check_period)) resource = self.resource(rsrc, request) # z3 only resource.__name__ = self.__name if self.__checker is not None: # z3 only resource.__Security_checker__ = self.__checker return resource class ConcatResourceFactory(ResourceFactory): """A factory for concat resources""" factory = ConcatFiles resource = GenericResource PK7i7[NN7kss/core/pluginregistry/_concatresource/fileresource.py'''\ this is a fixture of zope app's fileresource It correctly handles cache expiration headers and rereads files when needed only. ''' from zope.interface import implements try: from zope.contenttype import guess_content_type except ImportError: # BBB: Zope < 2.10 try: # XXX ??? What zope version needs this? from zope.app.contenttypes import guess_content_type except ImportError: from zope.app.content_types import guess_content_type import os from interfaces import IContextFile class File(object): implements(IContextFile) def __init__(self, path, name): self.path = path self.__name__ = name def getLastMod(self): return os.path.getmtime(self.path) def getContents(self): ##print "***** READ", self.path f = open(self.path, 'rb') data = f.read() f.close() content_type, enc = guess_content_type(self.path, data) return dict(data = data, content_type = content_type) class Image(File): """Image objects stored in external files.""" def getContents(self): d = super(Image, self).getContens() if d ['content_type'] in (None, 'application/octet-stream'): ext = os.path.splitext(self.path)[1] if ext: d['content_type'] = 'image/%s' % ext[1:] return d PK7i7ˠ"446kss/core/pluginregistry/_concatresource/configure.zcml PK7i7tߋ))Ikss/core/pluginregistry/_concatresource/kss.concatresource-configure.zcml PK7i7::Dkss/core/pluginregistry/_concatresource/kss.concatresource-meta.zcml PK7i7g$ii1kss/core/pluginregistry/_concatresource/meta.zcml PK7i7D3kss/core/pluginregistry/_concatresource/version.txt1.2.3 released 2007-11-08 PK i7V& s>kss/core/pluginregistry/_concatresource/concatfileresource.pyc; %4Gc@sdZdklZdklZdklZdklZdk l Z dk Z dk Z ydklZWn ej odklZnXdefd YZdS( s Support for concatenation and compression of resources We concatenate first and compress afterwards, giving a better chance for the compressor to optimize (s implements(s IContextFile(sIConcatResourceAddon(sFile(scompressN(sComponentLookupErrors ConcatFilescBsEtZdZeedZdZdZdZdZ RS(sA resource that concatenates files and compresses the result It is also possible to extend the statically given list via a utility. cCst|ttfptx!|D]}t|diq$W||_ ||_ ||_ ||_ ||_g|_t|_g|_dS(Nsrb(s isinstancespathlistsliststuplesAssertionErrorspathsfilesclosesselfs pathlist_basesnames__name__scompress_levelscachingslmt_check_periodsNonesfileslist_changeds fileslist(sselfspathlistsnamescompress_levelscachingslmt_check_periodspath((sXbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/concatfileresource.pys__init__s       cCsYytiit|i}Wntj o g}nX|i }|i |}|SdS(sGets the extended pathlistN( szopes components getUtilitysIConcatResourceAddonsselfs__name__sregistrysComponentLookupErrorsextends getAddonFiless pathlist_basespathlist(sselfsextendspathlistsregistry((sXbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/concatfileresource.pys getPathList0s   cCs|i}||ijoV||_ti|_gi}|D]}|t||i qB~}|_ n |i }|SdS(sGets the list of filesN( sselfs getPathListspathliststimesfileslist_changedsappends_[1]spathsFiles__name__s fileslist(sselfs fileslistspathlists_[1]spath((sXbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/concatfileresource.pys getFilesList<s  > cCsEtgi}|iD]}||iq~|igSdS(N(smaxsappends_[1]sselfs getFilesListsfs getLastModsfileslist_changed(sselfs_[1]sf((sXbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/concatfileresource.pys getLastModPscCs|i}|p td|di}|d}|dg}xG|dD];}|i}|d|jpt|i |dqOWdi ||d<|i |d,scCs|idS(Ns content_type(sselfs _fetchdata(sself((sTbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/cachingadapter.pys-scCst}||i|ijoQ||_t|iip|}t |}t d|d|}|_ n |i }|SdS(Nslmtslmh(stimesnowsselfslmt_last_checkedslmt_check_periodsfloatscontexts getLastModslmts rfc1123_dateslmhsdictsds _last_mod(sselfsdslmtslmhsnow((sTbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/cachingadapter.pys_fetchlm1s     cCs|idS(Nslmt(sselfs_fetchlm(sself((sTbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/cachingadapter.pys=scCs|idS(Nslmh(sselfs_fetchlm(sself((sTbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/cachingadapter.pys>scCs |iiS(N(sselfscontextscaching(sself((sTbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/cachingadapter.pys@scCs |iiS(N(sselfscontextslmt_check_period(sself((sTbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/cachingadapter.pysAs(s__name__s __module__s__doc__s implementssICachedResources__init__s _fetchdatas_deldatas purgeDataspropertysNonesdatas content_types_fetchlmslmtslmhscachingslmt_check_period(((sTbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/cachingadapter.pysCachedResource s      N( stimes interfacessICachedResourceszope.interfaces implementss zope.datetimes rfc1123_dates ImportErrorszope.app.datetimeutilssobjectsCachedResource(s implementss rfc1123_datesCachedResourcesICachedResourcestime((sTbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/cachingadapter.pys?s   PK i7ePyy4kss/core/pluginregistry/_concatresource/__init__.pyc; %4Gc@s]dZy=dkZdeij oeiedeid|idd|t|fd td t d|t| |fnt!oD|idd|t|fd td d|ft"|| |i#fnA|idd|t|fd td d| |ft"||i#fdS(Ns[Must use a files attribute for concatresource directives, with at least one file contained.sfilesscountisfactorys%s%ssprefixs discriminatorsfive:protectClassscallablesargssfive:initialize:classs zope.Publicsresource_factoryscheckersresourcesprovideResourcesprovideAdaptersregisterAdapter($sfilessConfigurationErrorsressres_types _factory_mapsgets factory_infos res_factorys__five__sNonescheckers _class_names makeClasssresources new_classs_contextsactions protectClasss permissionsinitializeClasss CheckerPublics NamesCheckers allowed_namessnamescompress_levelscachingslmt_check_periodsfactorys __pre_3_2__sIBrowserRequestslayershandlers Presentations __pre_3_3__s Interfacesinfo(s_contextsnamesfilesscompress_levelscachingslmt_check_periodslayers permissions factory_infosfactorys res_factorys new_classsres_types _class_namesresschecker((sJbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/meta.pysconcatresource0sD     &('sosszope.security.checkers CheckerPublics NamesCheckerszope.configuration.exceptionssConfigurationErrors!zope.publisher.interfaces.browsersIBrowserRequests zope.app.component.metaconfigureshandlerszope.interfaces InterfacesresourcesConcatResourceFactorys Products.FivesProductss ImportErrorsFalses__five__sTruesProducts.Five.metaclasss makeClasssProducts.Five.securitysgetSecurityInfos protectClasss protectNamesinitializeClasssIDefaultBrowserLayers_layers __pre_3_2__szope.app.servicenamess Presentationszope.componentszcmls __pre_3_3__s allowed_namess _factory_mapsNonesconcatresource(s makeClasss NamesCheckersIDefaultBrowserLayers allowed_namess _factory_mapsconcatresources PresentationsIBrowserRequestsinitializeClasss protectNameshandlers InterfacesgetSecurityInfos __pre_3_3__s __pre_3_2__s_layers CheckerPublicsProductss protectClasssossConcatResourceFactorysConfigurationErrorszcmls__five__((sJbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/meta.pys?s:                *PK i7uX  4kss/core/pluginregistry/_concatresource/resource.pyc; %4Gc@sPdklZdklZdklZdklZdkZydk l Z dk l Z Wn-ej o!dkl Z dkl Z nXy dkZWn&ej oeZdklZnHXeZydklZeZWn&ej odklZeZnXde efd YZd efd YZd efd YZdS((sIBrowserPublisher(s implements(s ConcatFiles(sICachedResourceN(s BrowserView(stime(sResourcesGenericResourcecBsbtZdZeo dZneedZdZdZ dZ dZ dZ RS(sA publishable resourcecCs||iffSdS(N(sselfsrequestsREQUEST_METHOD(sselfsrequest((sNbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/resource.pys__browser_default__%scCst|dS(sSee interface IBrowserPublisherN(s LookupErrorsname(sselfsrequestsname((sNbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/resource.pyspublishTraverse+scCst||iffSdS(sSee interface IBrowserPublisherN(sgetattrsselfsrequestsmethod(sselfsrequest((sNbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/resource.pysbrowserDefault/scCs|iiSdS(N(sselfscontextsdata(sself((sNbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/resource.pys _testData4scCs |iSdS(sChoose the appropriate contextN(sselfscontext(sself((sNbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/resource.pys chooseContext7sc Cs|i}|i}|i}|idj}|o+|i}||i jo|i q_nt o|i d}n|idt}|tj o|idd}ytt|}Wn t}nX|tj oN| o |i}n|djot||jo|iddSq,q0n|id|i|id|i|id d |i}| o|i n|Sd S( sDefault documentsmemorysIf-Modified-Sinces;ii0ss Content-Types Last-Modifieds Cache-Controlspublic,max-age=86400N(sselfs chooseContextsfilesrequestsresponsescachingscache_in_memoryslmtslast_modsdata_last_fetcheds purgeDatas__five__s get_headersheaders getHeadersNonessplitslongstimeFromDateTimeStrings mod_sincesints setStatuss setHeaders content_typeslmhsdata( sselfslast_modsrequests mod_sincesdatascache_in_memorysfilesheadersresponse((sNbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/resource.pysGET;s>           cCsV|i}|ii}|id|i|id|i|idddSdS(Ns Content-Types Last-Modifieds Cache-Controlspublic,max-age=86400s(sselfs chooseContextsfilesrequestsresponses setHeaders content_typeslmh(sselfsresponsesfile((sNbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/resource.pysHEADns   ( s__name__s __module__s__doc__s__five__s__browser_default__s implementssIBrowserPublisherspublishTraversesbrowserDefaults _testDatas chooseContextsGETsHEAD(((sNbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/resource.pysGenericResources        3sResourceFactorycBs,tZeZeZeedZdZRS(NcCsT||_||_||_||_||_ |t j o ||_ n||_dS(N(snamesselfs_ResourceFactory__namespaths_ResourceFactory__pathscompress_levels _ResourceFactory__compress_levelscachings_ResourceFactory__cachingslmt_check_periods"_ResourceFactory__lmt_check_periodsresource_factorysNonesresourcescheckers_ResourceFactory__checker(sselfspathsnamescompress_levelscachingslmt_check_periodsresource_factoryschecker((sNbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/resource.pys__init__|s       cCsy |i}WnJtj o>t|i|i|i|i|i |i }|_nX|i ||}|i|_ |itj o|i|_n|SdS(N(sselfs_ResourceFactory__rsrcsrsrcsAttributeErrorsICachedResourcesfactorys_ResourceFactory__paths_ResourceFactory__names _ResourceFactory__compress_levels_ResourceFactory__cachings"_ResourceFactory__lmt_check_periodsresourcesrequests__name__s_ResourceFactory__checkersNones__Security_checker__(sselfsrequestsresourcesrsrc((sNbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/resource.pys__call__s ' (s__name__s __module__sNonesfactorysresources__init__s__call__(((sNbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/resource.pysResourceFactoryws sConcatResourceFactorycBstZdZeZeZRS(sA factory for concat resources(s__name__s __module__s__doc__s ConcatFilessfactorysGenericResourcesresource(((sNbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/resource.pysConcatResourceFactorys ( s!zope.publisher.interfaces.browsersIBrowserPublisherszope.interfaces implementssconcatfileresources ConcatFiless interfacessICachedResourcescachingadapterszope.publisher.browsers BrowserViews zope.datetimestimestimeFromDateTimeStrings ImportErrorszope.app.publisher.browserszope.app.datetimeutilss Products.FivesProductssFalses__five__s#zope.app.publisher.browser.resourcesResourcesTruesProducts.Five.resources__five_pre_1_3_sProducts.Five.browser.resources__five_pre_1_3__sGenericResourcesobjectsResourceFactorysConcatResourceFactory(s implementssGenericResourcesConcatResourceFactorys ConcatFilessIBrowserPublisherstimeFromDateTimeStringscachingadaptersResources__five_pre_1_3__s BrowserViewsICachedResourcesResourceFactorysProductss__five_pre_1_3_s__five__((sNbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/resource.pys?s2            X PK i7fF F 8kss/core/pluginregistry/_concatresource/fileresource.pyc; %4Gc@sdZdklZydklZWnGej o;ydklZWqnej odklZqnXnXdkZdk l Z de fdYZ de fdYZ dS( sthis is a fixture of zope app's fileresource It correctly handles cache expiration headers and rereads files when needed only. (s implements(sguess_content_typeN(s IContextFilesFilecBs-tZeedZdZdZRS(NcCs||_||_dS(N(spathsselfsnames__name__(sselfspathsname((sRbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/fileresource.pys__init__s cCstii|iSdS(N(sosspathsgetmtimesself(sself((sRbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/fileresource.pys getLastModscCsWt|id}|i}|it|i|\}}t d|d|SdS(Nsrbsdatas content_type( sopensselfspathsfsreadsdatasclosesguess_content_types content_typesencsdict(sselfsencsfs content_typesdata((sRbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/fileresource.pys getContentss   (s__name__s __module__s implementss IContextFiles__init__s getLastMods getContents(((sRbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/fileresource.pysFiles   sImagecBstZdZdZRS(s'Image objects stored in external files.cCsntt|i}|dtdfjo:tii|id}|od|d|d PK7i7S'5kss/core/pluginregistry/_concatresource/test/test1.js _PythonKw = function(kw) { this.kw = kw; } _PythonKw.prototype.toJSON = function() { var pack = {"pythonKwMaRkEr": this.kw}; return toJSON(pack); } function PythonKw(kw) { return new _PythonKw(kw); } PK7i7Sq}}5kss/core/pluginregistry/_concatresource/test/test2.js/* A 2nd js file */ /* * * * */ var someContents = "Some content here, too."; var someMoreContents = "Some more content."; PK i79kss/core/pluginregistry/_concatresource/test/__init__.pyc; %4Gc@s dZdS(s Module init N(s__doc__(((sSbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/test/__init__.pys?sPK7i7h099?kss/core/pluginregistry/_concatresource/compression/__init__.py'''\ Preprocess resource files by applying compression on them ''' __all__ = ('compress', ) from javascript import compress as compress_javascript from css import compress as compress_css compress_methods = { 'application/x-javascript': compress_javascript, 'text/css': compress_css, } default_compress_method = lambda text: text def compress(data, content_type, compress_level): 'Returns compressed text for a given content type' method = compress_methods.get(content_type, default_compress_method) return method(data, compress_level) PK7i7v:kss/core/pluginregistry/_concatresource/compression/css.py'''\ The css compressor uses the 3rdparty packer module that is taken from Plone's ResourceRegistries. ''' from thirdparty.packer import CSSPacker # Packer needs to be created for each packing def compress(data, compress_level): if compress_level == "safe": csspacker_safe = CSSPacker('safe') return csspacker_safe.pack(data) elif compress_level == "full": csspacker_full = CSSPacker('full') return csspacker_full.pack(data) else: # none return data PK7i7*VkkAkss/core/pluginregistry/_concatresource/compression/javascript.py'''\ The javascript compressor uses the 3rdparty packer module that is taken from Plone's ResourceRegistries.''' from thirdparty.packer import JavascriptPacker # Packer needs to be created for each packing def stripout_comments(data): 'Strips out ;;; lines from the data.' result = [] for line in data.splitlines(True): if not line.lstrip().startswith(';;;'): result.append(line) return ''.join(result) def remove_markers(data): 'Replaces the ;;; markers by spaces but leaves the lines.' result = [] for line in data.splitlines(True): if line.lstrip().startswith(';;;'): line = line.lstrip()[3:] result.append(' ') result.append(line) return ''.join(result) def compress(data, compress_level): if compress_level == "devel": return remove_markers(data) elif compress_level == "stripped": return stripout_comments(data) elif compress_level == "safe": data = stripout_comments(data) jspacker_safe = JavascriptPacker('safe') return jspacker_safe.pack(data) elif compress_level == "full": data = stripout_comments(data) jspacker_full = JavascriptPacker('full') return jspacker_full.pack(data) elif compress_level == "safe-devel": date = remove_markers(data) jspacker_safe = JavascriptPacker('safe') return jspacker_safe.pack(data) elif compress_level == "full-devel": date = remove_markers(data) jspacker_full = JavascriptPacker('full') return jspacker_full.pack(data) else: # none return data PK i7*@kss/core/pluginregistry/_concatresource/compression/__init__.pyc; %4Gc@sWdZdfZdklZdklZhde<descCs#ti|t}|||SdS(s0Returns compressed text for a given content typeN(scompress_methodssgets content_typesdefault_compress_methodsmethodsdatascompress_level(sdatas content_typescompress_levelsmethod((sZbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/compression/__init__.pyscompresssN( s__doc__s__all__s javascriptscompressscompress_javascriptscsss compress_cssscompress_methodssdefault_compress_method(s__all__s compress_cssscompresssdefault_compress_methodscompress_javascriptscompress_methods((sZbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/compression/__init__.pys?s     PK i7NN;kss/core/pluginregistry/_concatresource/compression/css.pyc; %4Gc@s dZdklZdZdS(sbThe css compressor uses the 3rdparty packer module that is taken from Plone's ResourceRegistries. (s CSSPackercCs\|djotd}|i|Sn/|djotd}|i|Sn|SdS(Nssafesfull(scompress_levels CSSPackerscsspacker_safespacksdatascsspacker_full(sdatascompress_levelscsspacker_fullscsspacker_safe((sUbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/compression/css.pyscompress s    N(s__doc__sthirdparty.packers CSSPackerscompress(scompresss CSSPacker((sUbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/compression/css.pys?s PK i7.țBkss/core/pluginregistry/_concatresource/compression/javascript.pyc; %4Gc@s2dZdklZdZdZdZdS(shThe javascript compressor uses the 3rdparty packer module that is taken from Plone's ResourceRegistries.(sJavascriptPackercCsYg}x?|itD].}|iid o|i|qqWdi|SdS(s#Strips out ;;; lines from the data.s;;;sN( sresultsdatas splitlinessTrueslineslstrips startswithsappendsjoin(sdataslinesresult((s\build/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/compression/javascript.pysstripout_commentsscCsug}x[|itD]J}|iido!|id}|idn|i|qWdi|SdS(s8Replaces the ;;; markers by spaces but leaves the lines.s;;;is sN( sresultsdatas splitlinessTrueslineslstrips startswithsappendsjoin(sdataslinesresult((s\build/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/compression/javascript.pysremove_markersscCs|djot|Sn|djot|Sn|djo)t|}td}|i|Sn|djo)t|}td}|i|Snq|djo)t|}td}|i|Sn;|djo)t|}td}|i|Sn|SdS(Nsdevelsstrippedssafesfulls safe-devels full-devel( scompress_levelsremove_markerssdatasstripout_commentssJavascriptPackers jspacker_safespacks jspacker_fullsdate(sdatascompress_levels jspacker_fulls jspacker_safesdate((s\build/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/compression/javascript.pyscompresss*              N(s__doc__sthirdparty.packersJavascriptPackersstripout_commentssremove_markersscompress(sstripout_commentssJavascriptPackerscompresssremove_markers((s\build/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/compression/javascript.pys?s   PK7i7@pJkss/core/pluginregistry/_concatresource/compression/thirdparty/__init__.py'''\ Module init ''' PK7i7TWllHkss/core/pluginregistry/_concatresource/compression/thirdparty/packer.py# # packer.py # # Copyright (c) 2006-2007 Florian Schulze # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. import re, unittest, textwrap class KeywordMapper: def __init__(self, regexp, encoder): if isinstance(regexp, (str, unicode)): self.regexp = re.compile(regexp) else: self.regexp = regexp self.encoder = encoder self.mapping = {} def analyseKeywords(self, input): matches = self.regexp.findall(input) protected = {} keyword_count = {} index = 0 for match in matches: if match not in keyword_count: keyword_count[match] = 0 protected[self.encoder(index)] = index index = index + 1 keyword_count[match] = keyword_count[match] + 1 for match in matches: if match in protected and keyword_count[match]: keyword_count[match] = 0 protected = {} for match in keyword_count: if not keyword_count[match]: protected[match] = None ## sorted_matches = [(c,len(v),v) for v,c in keyword_count.iteritems()] # the above line implements the original behaviour, the code below # removes keywords which have not enough weight to be encoded, in total # this saves some bytes, because the total length of the generated # codes is a bit smaller. This needs corresponding code in the # fast_decode javascript function of the decoder, see comment there sorted_matches = [] for value, count in keyword_count.iteritems(): weight = count * len(value) if len(value) >= weight: keyword_count[value] = 0 sorted_matches.append((0, value)) else: sorted_matches.append((weight, value)) sorted_matches.sort() sorted_matches.reverse() sorted_matches = [x[-1] for x in sorted_matches] index = 0 mapping = {} for match in sorted_matches: if not keyword_count[match]: if match not in protected: mapping[match] = (-1, match) continue while 1: encoded = self.encoder(index) index = index + 1 if encoded in protected: mapping[encoded] = (index-1, encoded) continue else: break mapping[match] = (index-1, encoded) return mapping def analyse(self, input): self.mapping = self.analyseKeywords(input) def getKeywords(self): sorted = zip(self.mapping.itervalues(), self.mapping.iterkeys()) sorted.sort() keywords = [] for (index, encoded), value in sorted: if index >= 0: if encoded != value: keywords.append(value) else: keywords.append('') return keywords def sub(self, input): def repl(m): return self.mapping.get(m.group(0), ('', m.group(0)))[1] return self.regexp.sub(repl, input) class JavascriptKeywordMapper(KeywordMapper): def __init__(self, regexp=None, encoder=None): if regexp is None: self.regexp = re.compile(r'\w+') elif isinstance(regexp, (str, unicode)): self.regexp = re.compile(regexp) else: self.regexp = regexp if encoder is None: self.encoder = self._encode else: self.encoder = encoder self.mapping = {} def _encode(self, charCode, mapping="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"): result = [] quotient = charCode while quotient or not len(result): quotient, remainder = divmod(quotient, 62) result.append(mapping[remainder]) result.reverse() return "".join(result) def getDecodeFunction(self, fast=True, name=None): jspacker = JavascriptPacker('full') # fast boot function fast_decoder = r""" // does the browser support String.replace where the // replacement value is a function? if (!''.replace(/^/, String)) { // decode all the values we need // we have to add the dollar prefix, because $encoded can be // any keyword in the decode function below. For example // 'constructor' is an attribute of any object and it would // return a false positive match in that case. while ($count--) $decode["$"+$encode($count)] = $keywords[$count] || $encode($count); // global replacement function $keywords = [function($encoded){$result = $decode["$"+$encoded]; return $result!=undefined?$result:$encoded}]; // generic match $encode = function(){return'\\w+'}; // reset the loop counter - we are now doing a global replace $count = 1; };""" if name is None: # boot function decoder = r""" function($packed, $ascii, $count, $keywords, $encode, $decode) { $encode = function($charCode) { return ($charCode < $ascii ? "" : $encode(parseInt($charCode / $ascii))) + (($charCode = $charCode % $ascii) > 35 ? String.fromCharCode($charCode + 29) : $charCode.toString(36)); }; // fastDecodePlaceholder while ($count--) if ($keywords[$count]) $packed = $packed.replace(new RegExp("\\b" + $encode($count) + "\\b", "g"), $keywords[$count]); return $packed; }""" if fast: decoder = decoder.replace('// fastDecodePlaceholder', fast_decoder) decoder = jspacker.pack(decoder) else: decoder = r""" var %s = function($ascii, $count, $keywords, $encode, $decode) { $encode = function($charCode) { return ($charCode < $ascii ? "" : $encode(parseInt($charCode / $ascii))) + (($charCode = $charCode %% $ascii) > 35 ? String.fromCharCode($charCode + 29) : $charCode.toString(36)); }; // fastDecodePlaceholder var decoder = function($packed, $ascii1, $count1, $keywords1, $encode1, $decode1) { $count1 = $count; while ($count1--) if ($keywords[$count1]) $packed = $packed.replace(new RegExp("\\b" + $encode($count1) + "\\b", "g"), $keywords[$count1]); return $packed; }; return decoder; }""" % name if fast: decoder = decoder.replace('// fastDecodePlaceholder', fast_decoder) decoder = jspacker.pack(decoder) keywords = self.getKeywords() decoder = "%s(62, %i, '%s'.split('|'), 0, {});" % (decoder, len(keywords), "|".join(keywords)) return decoder def getDecoder(self, input, keyword_var=None, decode_func=None): if keyword_var is None: keywords = self.getKeywords() num_keywords = len(keywords) keywords = "|".join(keywords) keywords = "'%s'.split('|')" % keywords else: keywords = keyword_var num_keywords = len(self.getKeywords()) if decode_func is None: decode_func = self.getDecodeFunction() escaped_single = input.replace("\\","\\\\").replace("'","\\'").replace('\n','\\n') escaped_double = input.replace("\\","\\\\").replace('"','\\"').replace('\n','\\n') if len(escaped_single) < len(escaped_double): script = "'%s'" % escaped_single else: script = '"%s"' % escaped_double return "eval(%s(%s,62,%i,%s,0,{}))" % (decode_func, script, num_keywords, keywords) class Packer: def __init__(self): self.patterns = [] def copy(self): result = Packer() result.patterns = self.patterns[:] return result def _repl(self, match): # store protected part self.replacelist.append(match.group(1)) # return escaped index return "\x00%i" % len(self.replacelist) def pack(self, input): # list of protected parts self.replacelist = [] # escape the escapechar output = input.replace('\x00','\x00\x00') for regexp, replacement, keyword_encoder in self.patterns: if replacement is None: if keyword_encoder is None: # protect the matched parts output = regexp.sub(self._repl, output) else: mapper = KeywordMapper(regexp=regexp, encoder=keyword_encoder) # get keywords mapper.analyse(output) # replace keywords output = mapper.sub(output) else: # substitute output = regexp.sub(replacement, output) # restore protected parts replacelist = list(enumerate(self.replacelist)) replacelist.reverse() # from back to front, so 1 doesn't break 10 etc. for index, replacement in replacelist: # we use lambda in here, so the real string is used and no escaping # is done on it before = len(output) regexp = re.compile('(? n, $$name -> na, $top1 -> t1, $top2 -> t2 def _dollar_replacement(match): length = len(match.group(2)) start = length - max(length - len(match.group(3)), 0) result = match.group(1)[start:start+length] + match.group(4) return result self.sub(r"""((\$+)([a-zA-Z\$_]+))(\d*)\b""", _dollar_replacement) self.keywordSub(r"""\b_[A-Za-z\d]\w*""", lambda i: "_%i" % i) # protect strings # this is more correct, but needs more testing # it has to be more accurate because of the more aggresive packing later self.protect(r"""(?<=return|..case|.....[=\[|(,?:+])\s*((?P['"])(?:\\(?P=quote)|\\\n|.)*?(?P=quote))""", re.DOTALL) else: # protect strings # these sometimes catch to much, but in safe mode this doesn't hurt self.protect(r"""('(?:\\'|\\\n|.)*?')""") self.protect(r'''("(?:\\"|\\\n|.)*?")''') # protect regular expressions self.protect(r"""\s+(\/[^\/\n\r\*][^\/\n\r]*\/g?i?)""") self.protect(r"""([^\w\$\/'"*)\?:]\/[^\/\n\r\*][^\/\n\r]*\/g?i?)""") # multiline comments self.sub(r'/\*(?!@).*?\*/', '', re.DOTALL) # one line comments self.sub(r'\s*//.*$', '', re.MULTILINE) # strip whitespace at the beginning and end of each line self.sub(r'^[ \t\r\f\v]*(.*?)[ \t\r\f\v]*$', r'\1', re.MULTILINE) # whitespace after some special chars but not # before function declaration self.sub(r'([{;\[(,=&|\?:<>%!/])\s+(?!function)', r'\1') # after an equal sign a function definition is ok self.sub(r'=\s+(?=function)', r'=') if level == 'full': # whitespace after some more special chars self.sub(r'([};\):,])\s+', r'\1') # whitespace before some special chars self.sub(r'\s+([={},&|\?:\.()<>%!/\]])', r'\1') # whitespace before plus chars if no other plus char before it self.sub(r'(? b) { do something } else { do something else }; }; next_instr; """, """\ function dummy(a,b){if(a>b){do something} else{do something else}};next_instr;""", 'safe' ), ( 'nestedCurlyBracketsWithSemicolons', """\ function dummy(a, b) { if (a > b) { do something } else { do something else }; }; next_instr; """, """\ function dummy(a,b){if(a>b){do something}else{do something else}};next_instr;""", 'full' ), ) css_safe_compression_tests = ( ( 'commentCompression', """ /* this is a comment */ #testElement { property: value; /* another comment */ } /**********/ /* this is a multi line comment */ #testElement { /* yet another comment */ property: value; } """, """\ /* */ #testElement { property: value; /* */ } /* */ #testElement { /* */ property: value; } """ ), ( 'newlineCompression', """ /* this is a comment */ #testElement { property: value; /* another comment */ } /* this is a multi line comment */ #testElement { /* yet another comment */ property: value; } """, """\ /* */ #testElement { property: value; /* */ } /* */ #testElement { /* */ property: value; } """ ), # see http://www.dithered.com/css_filters/index.html ( 'commentHacks1', """ #testElement { property/**/: value; property/* */: value; property /**/: value; property: /**/value; } """, """\ #testElement { property/**/: value; property/* */: value; property /**/: value; property: /**/value; } """ ), ( 'commentHacks2', """ selector/* */ { } """, """\ selector/* */ { } """ ), ( 'commentHacks3', """ selector/* foobar */ { } """, """\ selector/* */ { } """ ), ( 'commentHacks4', """ selector/**/ { } """, """\ selector/**/ { } """ ), ( 'commentHacks5', """ /* \*/ rules /* */ """, """\ /* \*/ rules /* */ """ ), ( 'commentHacks6', """ /* foobar \*/ rules /* */ """, """\ /* \*/ rules /* */ """ ), ( 'commentHacks7', """ /*/*/ rules /* */ """, """\ /*/*/ rules /* */ """ ), ( 'commentHacks8', """ /*/*//*/ rules /* */ """, """\ /*/*//*/ rules /* */ """ ), ( 'stringProtection', """ /* test string protection */ #selector, #another { content: 'foo; bar'; } """, """\ /* */ #selector, #another { content: 'foo; bar'; } """ ), ) css_full_compression_tests = ( ( 'commentCompression', """ /* this is a comment */ #testElement { property: value; /* another comment */ } /**********/ /* this is a multi line comment */ #testElement { /* yet another comment */ property: value; } """, """\ #testElement{property:value;} #testElement{property:value;} """ ), ( 'newlineCompression', """ /* this is a comment */ #testElement { property: value; /* another comment */ } /* this is a multi line comment */ #testElement { /* yet another comment */ property: value; } """, """\ #testElement{property:value;} #testElement{property:value;} """ ), # see http://www.dithered.com/css_filters/index.html # in full compression all hacks get removed ( 'commentHacks1', """ #testElement { property/**/: value; property/* */: value; property /**/: value; property: /**/value; } """, """\ #testElement{property:value;property:value;property:value;property:value;} """ ), ( 'commentHacks2', """ selector/* */ { } """, """\ selector{} """ ), ( 'commentHacks3', """ selector/* foobar */ { } """, """\ selector{} """ ), ( 'commentHacks4', """ selector/**/ { } """, """\ selector{} """ ), ( 'commentHacks5', """ /* \*/ rules /* */ """, """\ rules """ ), ( 'commentHacks6', """ /* foobar \*/ rules /* */ """, """\ rules """ ), ( 'commentHacks7', """ /*/*/ rules /* */ """, """\ rules """ ), ( 'commentHacks8', """ /*/*//*/ rules /* */ """, """\ rules """ ), ( 'stringProtection', """ /* test string protection and full compression */ #selector, #another { content: 'foo; bar'; } """, """\ #selector,#another{content:'foo; bar';} """ ), ) class PackerTestCase(unittest.TestCase): def __init__(self, name, input, output, packer): unittest.TestCase.__init__(self) self.name = name self.input = input self.output = output self.packer = packer def __str__(self): return self.name def runTest(self): self.assertEqual(self.packer.pack(self.input), self.output) def test_suite(): suite = unittest.TestSuite() jspacker = { 'safe': JavascriptPacker('safe'), 'full': JavascriptPacker('full'), } csspacker = { 'safe': CSSPacker('safe'), 'full': CSSPacker('full'), } for info in js_compression_tests: name = info[0] input = textwrap.dedent(info[1]) output = textwrap.dedent(info[2]) if (len(info) == 4): compression = info[3].split(",") else: compression = ("safe", "full") for packer in compression: suite.addTest(PackerTestCase("%s (%s)" % (name, packer), input, output, jspacker[packer])) packer = "safe" for name, input, output in css_safe_compression_tests: input = textwrap.dedent(input) output = textwrap.dedent(output) suite.addTest(PackerTestCase("%s (%s)" % (name, packer), input, output, csspacker[packer])) packer = "full" for name, input, output in css_full_compression_tests: input = textwrap.dedent(input) output = textwrap.dedent(output) suite.addTest(PackerTestCase("%s (%s)" % (name, packer), input, output, csspacker[packer])) return suite if __name__ == '__main__': unittest.main(defaultTest='test_suite') PK7i7ОFkss/core/pluginregistry/_concatresource/compression/thirdparty/LICENSE packer.py is released under the MIT license. # packer.py # # Copyright (c) 2006 Florian Schulze # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. PK i7DKkss/core/pluginregistry/_concatresource/compression/thirdparty/__init__.pyc; %4Gc@s dZdS(s Module init N(s__doc__(((sebuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/compression/thirdparty/__init__.pys?sPK i7eaaIkss/core/pluginregistry/_concatresource/compression/thirdparty/packer.pyc; %4Gc@szdkZdkZdkZdfdYZdefdYZdfdYZdefdYZd efd YZd d d dfd d ddfdddfdddfdddfdddfdddfd d!d"dfd d!d#dfd$d%d&dfd$d%d'dff Zd(d)d*fd+d,d*fd-d.d/fd0d1d2fd3d4d2fd5d6d7fd8d9d:fd;d<d:fd=d>d?fd@dAdBfddCdDff Z d(d)dEfd+d,dEfd-d.dFfd0d1dGfd3d4dGfd5d6dGfd8d9dHfd;d<dHfd=d>dHfd@dAdHfddIdJff Z dKei fdLYZ dMZ edNjoeidOdPndS(QNs KeywordMappercBs5tZdZdZdZdZdZRS(NcCsKt|ttfoti||_n ||_||_h|_dS(N( s isinstancesregexpsstrsunicodesrescompilesselfsencodersmapping(sselfsregexpsencoder((scbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/compression/thirdparty/packer.pys__init__s   cCs^|ii|}h} h} d}xX|D]P}|| jo+d| |<|| |i |<|d}n| |d| |0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZcCsjg}|}x@|p t| o*t|d\}}|i||qW|idi |SdS(Ni>s( sresultscharCodesquotientslensdivmods remaindersappendsmappingsreversesjoin(sselfscharCodesmappingsresults remaindersquotient((scbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/compression/thirdparty/packer.pys_encodes cCstd}d}|tjo6d}|o|id|}n|i|}ned|}|o|id|}n|i|}|i }d|t |di |f}|SdS(Nsfulls // does the browser support String.replace where the // replacement value is a function? if (!''.replace(/^/, String)) { // decode all the values we need // we have to add the dollar prefix, because $encoded can be // any keyword in the decode function below. For example // 'constructor' is an attribute of any object and it would // return a false positive match in that case. while ($count--) $decode["$"+$encode($count)] = $keywords[$count] || $encode($count); // global replacement function $keywords = [function($encoded){$result = $decode["$"+$encoded]; return $result!=undefined?$result:$encoded}]; // generic match $encode = function(){return'\\w+'}; // reset the loop counter - we are now doing a global replace $count = 1; };s function($packed, $ascii, $count, $keywords, $encode, $decode) { $encode = function($charCode) { return ($charCode < $ascii ? "" : $encode(parseInt($charCode / $ascii))) + (($charCode = $charCode % $ascii) > 35 ? String.fromCharCode($charCode + 29) : $charCode.toString(36)); }; // fastDecodePlaceholder while ($count--) if ($keywords[$count]) $packed = $packed.replace(new RegExp("\\b" + $encode($count) + "\\b", "g"), $keywords[$count]); return $packed; }s// fastDecodePlaceholders var %s = function($ascii, $count, $keywords, $encode, $decode) { $encode = function($charCode) { return ($charCode < $ascii ? "" : $encode(parseInt($charCode / $ascii))) + (($charCode = $charCode %% $ascii) > 35 ? String.fromCharCode($charCode + 29) : $charCode.toString(36)); }; // fastDecodePlaceholder var decoder = function($packed, $ascii1, $count1, $keywords1, $encode1, $decode1) { $count1 = $count; while ($count1--) if ($keywords[$count1]) $packed = $packed.replace(new RegExp("\\b" + $encode($count1) + "\\b", "g"), $keywords[$count1]); return $packed; }; return decoder; }s#%s(62, %i, '%s'.split('|'), 0, {});s|(sJavascriptPackersjspackers fast_decodersnamesNonesdecodersfastsreplacespacksselfs getKeywordsskeywordsslensjoin(sselfsfastsnamesdecoderskeywordss fast_decodersjspacker((scbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/compression/thirdparty/packer.pysgetDecodeFunctions     "c Cs|tjo5|i}t|}di|}d|}n|}t|i}|tjo|i }n|i ddi ddi dd}|i ddi d d i dd}t|t|jod |}n d |}d ||||fSdS(Ns|s'%s'.split('|')s\s\\s's\'s s\ns"s\"s'%s's"%s"seval(%s(%s,62,%i,%s,0,{}))(s keyword_varsNonesselfs getKeywordsskeywordsslens num_keywordssjoins decode_funcsgetDecodeFunctionsinputsreplacesescaped_singlesescaped_doublesscript( sselfsinputs keyword_vars decode_funcsscriptsescaped_singles num_keywordsskeywordssescaped_double((scbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/compression/thirdparty/packer.pys getDecoders    ** (s__name__s __module__sNones__init__s_encodesTruesgetDecodeFunctions getDecoder(((scbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/compression/thirdparty/packer.pysJavascriptKeywordMapperts FsPackercBsPtZdZdZdZdZedZedZedZ RS(NcCs g|_dS(N(sselfspatterns(sself((scbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/compression/thirdparty/packer.pys__init__scCst}|i|_|SdS(N(sPackersresultsselfspatterns(sselfsresult((scbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/compression/thirdparty/packer.pyscopys  cCs.|ii|iddt|iSdS(Nis%i(sselfs replacelistsappendsmatchsgroupslen(sselfsmatch((scbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/compression/thirdparty/packer.pys_replsc s=g|_|idd}x|iD]\}}t jo[|t jo|i |i |}qt d|d|}|i||i |}q%|i |}q%Wtt|i}|ixO|D]G\}t|}tid|d}|i d|}qW|idd}|SdS(Nsssregexpsencoders (?s(sselfs replacelistsinputsreplacesoutputspatternssregexps replacementskeyword_encodersNonessubs_repls KeywordMappersmappersanalyseslists enumeratesreversesindexslensbeforesrescompile( sselfsinputsmappers replacelistsoutputsindexskeyword_encodersregexpsbefores replacement((s replacementscbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/compression/thirdparty/packer.pyspacks*          cCs|i|t|dS(N(sselfs keywordSubspatternsNonesflags(sselfspatternsflags((scbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/compression/thirdparty/packer.pysprotectscCs\|tjo&|iiti||tfn&|iiti|||tfdS(N( sflagssNonesselfspatternssappendsrescompilespatterns replacement(sselfspatterns replacementsflags((scbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/compression/thirdparty/packer.pyssubs &cCs\|tjo&|iiti|t|fn&|iiti||t|fdS(N( sflagssNonesselfspatternssappendsrescompilespatternskeyword_encoder(sselfspatternskeyword_encodersflags((scbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/compression/thirdparty/packer.pys keywordSub$s &( s__name__s __module__s__init__scopys_replspacksNonesprotectssubs keywordSub(((scbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/compression/thirdparty/packer.pysPackers    "  sJavascriptPackercBstZddZRS(NssafecCsti||djoCd}|id||idd|idti n|id|id|id |id |id d ti |id d ti |iddti |idd|idd|djo|iddn|idd|idd|idd|idd|idd|idd|idd|idd|id d dS(!NsfullcCsjt|id}|t|t|idd}|id|||!|id}|SdS(Niiiii(slensmatchsgroupslengthsmaxsstartsresult(smatchsstartslengthsresult((scbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/compression/thirdparty/packer.pys_dollar_replacement3s&'s((\$+)([a-zA-Z\$_]+))(\d*)\bs\b_[A-Za-z\d]\w*cCsd|S(Ns_%i(si(si((scbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/compression/thirdparty/packer.pys:ssZ(?<=return|..case|.....[=\[|(,?:+])\s*((?P['"])(?:\\(?P=quote)|\\\n|.)*?(?P=quote))s('(?:\\'|\\\n|.)*?')s("(?:\\"|\\\n|.)*?")s"\s+(\/[^\/\n\r\*][^\/\n\r]*\/g?i?)s/([^\w\$\/'"*)\?:]\/[^\/\n\r\*][^\/\n\r]*\/g?i?)s/\*(?!@).*?\*/ss\s*//.*$s^[ \t\r\f\v]*(.*?)[ \t\r\f\v]*$s\1s$([{;\[(,=&|\?:<>%!/])\s+(?!function)s=\s+(?=function)s=s ([};\):,])\s+s\s+([={},&|\?:\.()<>%!/\]])s (? b) { do something } else { do something else }; }; next_instr; sZ function dummy(a,b){if(a>b){do something} else{do something else}};next_instr;sY function dummy(a,b){if(a>b){do something}else{do something else}};next_instr;scommentCompressionsX /* this is a comment */ #testElement { property: value; /* another comment */ } /**********/ /* this is a multi line comment */ #testElement { /* yet another comment */ property: value; } s /* */ #testElement { property: value; /* */ } /* */ #testElement { /* */ property: value; } snewlineCompressionsc /* this is a comment */ #testElement { property: value; /* another comment */ } /* this is a multi line comment */ #testElement { /* yet another comment */ property: value; } s commentHacks1s #testElement { property/**/: value; property/* */: value; property /**/: value; property: /**/value; } s #testElement { property/**/: value; property/* */: value; property /**/: value; property: /**/value; } s commentHacks2s( selector/* */ { } s' selector/* */ { } s commentHacks3s/ selector/* foobar */ { } s commentHacks4s' selector/**/ { } s& selector/**/ { } s commentHacks5s@ /* \*/ rules /* */ s? /* \*/ rules /* */ s commentHacks6sG /* foobar \*/ rules /* */ s commentHacks7s? /*/*/ rules /* */ s> /*/*/ rules /* */ s commentHacks8sB /*/*//*/ rules /* */ sA /*/*//*/ rules /* */ s /* test string protection */ #selector, #another { content: 'foo; bar'; } sw /* */ #selector, #another { content: 'foo; bar'; } s\ #testElement{property:value;} #testElement{property:value;} s_ #testElement{property:value;property:value;property:value;property:value;} s selector{} s rules s /* test string protection and full compression */ #selector, #another { content: 'foo; bar'; } s< #selector,#another{content:'foo; bar';} sPackerTestCasecBs#tZdZdZdZRS(NcCs8tii|||_||_||_||_dS(N(sunittestsTestCases__init__sselfsnamesinputsoutputspacker(sselfsnamesinputsoutputspacker((scbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/compression/thirdparty/packer.pys__init__\s    cCs |iSdS(N(sselfsname(sself((scbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/compression/thirdparty/packer.pys__str__cscCs&|i|ii|i|idS(N(sselfs assertEqualspackerspacksinputsoutput(sself((scbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/compression/thirdparty/packer.pysrunTestfs(s__name__s __module__s__init__s__str__srunTest(((scbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/compression/thirdparty/packer.pysPackerTestCase[s  c Csti}hdtd<dtd<}hdtd<dtd<}xtD]}|d}t i |d}t i |d}t|djo|did}n ddf}x8|D]0}|itd ||f||||qWq[Wd}x_tD]W\}}}t i |}t i |}|itd ||f||||qWd}x_tD]W\}}}t i |}t i |}|itd ||f||||q{W|SdS( Nssafesfulliiiiis,s%s (%s)(sunittests TestSuitessuitesJavascriptPackersjspackers CSSPackers csspackersjs_compression_testssinfosnamestextwrapsdedentsinputsoutputslenssplits compressionspackersaddTestsPackerTestCasescss_safe_compression_testsscss_full_compression_tests( sinfosnamesoutputspackers compressions csspackersinputssuitesjspacker((scbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/compression/thirdparty/packer.pys test_suitejsB $$  s__main__s defaultTests test_suite(sresunitteststextwraps KeywordMappersJavascriptKeywordMappersPackersJavascriptPackers CSSPackersjs_compression_testsscss_safe_compression_testsscss_full_compression_testssTestCasesPackerTestCases test_suites__name__smain( sJavascriptKeywordMappersjs_compression_testssPackersPackerTestCasesunittestscss_safe_compression_testsstextwraps CSSPackersresJavascriptPackers test_suitescss_full_compression_testss KeywordMapper((scbuild/bdist.linux-i686/egg/kss/core/pluginregistry/_concatresource/compression/thirdparty/packer.pys?sYvA? . PK2i7C߈4kss/core/tests/__init__.py PK2i7ܺlkss/core/tests/base.py# -*- coding: latin-1 -*- # Copyright (c) 2005-2007 # Authors: KSS Project Contributors (see docs/CREDITS.txt) # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as published # by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. from textwrap import dedent import warnings from Testing.ZopeTestCase import ZopeTestCase, FunctionalTestCase from zope import interface from zope.publisher.interfaces.browser import IBrowserRequest #from zope.app.testing import placelesssetup import kss.core from kss.core import KSSView class KSSCoreLayer: @classmethod def setUp(cls): try: import Products.Five except ImportError: # probably zope 3 pass # XXX TODO fix this?? --- never run yet on Z3 from zope.configuration.xmlconfig import XMLConfig XMLConfig('tests/configure-unittest.zcml', kss.core)() else: from Products.Five.zcml import load_string, load_config load_config('meta.zcml', package=Products.Five) try: load_config('traversing.zcml', package=Products.Five) except IOError: # Let's try the Zope 2.9 way (zope.app.traversing is # moved in 2.10) load_string(dedent('''\ ''')) # Load the permissions config, if it's there try: load_config('permissions.zcml', package=Products.Five) except IOError: # Zope 2.10 / Five 1.3.6 does not have it pass load_config('configure-unittest.zcml', package=kss.core.tests) @classmethod def tearDown(cls): pass # placelesssetup.tearDown() class KSSLayer(KSSCoreLayer): @classmethod def setUp(cls): try: from Products.Five.zcml import load_config except ImportError: raise ImportError("KSSLayer requires Five to be installed.") load_config('meta.zcml', package=kss.core) load_config('configure.zcml', package=kss.core) # Test view class TestView(KSSView): def testMethod(self): 'Yes.' # Debug request # This has a modified render. class IDebugRequest(IBrowserRequest): 'The debug request' class KSSViewTestCaseMixin: def loadCoreConfig(self, kss_core=True): warnings.warn( "KSS tests are now using layers. Please do not use " "loadCoreConfig anymore.", DeprecationWarning) def createView(self): "Set up a fake view (with no content)" self.view = self.folder.restrictedTraverse('testMethod') return self.view def setDebugRequest(self): 'commands will be rendered as test friendly data structures' request = self.folder.REQUEST interface.directlyProvides( request, interface.directlyProvidedBy(request) + IDebugRequest) class KSSViewTestCase(ZopeTestCase, KSSViewTestCaseMixin): layer = KSSLayer class KSSViewFunctionalTestCase(FunctionalTestCase, KSSViewTestCase): 'Functional test base' # backward compatibility class AzaxViewTestCase(KSSViewTestCase): def __init__(self, *args, **kw): message = "'AzaxViewTestCase' is deprecated," \ "use 'KSSViewTestCase'- KSS uppercase instead." warnings.warn(message, DeprecationWarning, 2) KSSViewTestCase.__init__(self, *args, **kw) class KssViewTestCase(KSSViewTestCase): def __init__(self, *args, **kw): message = "'KssViewTestCase' is deprecated," \ "use 'KSSViewTestCase'- KSS uppercase instead." warnings.warn(message, DeprecationWarning, 2) KSSViewTestCase.__init__(self, *args, **kw) class KssViewFunctionalTestCase(KSSViewFunctionalTestCase): def __init__(self, *args, **kw): message = "'KssViewFunctionalTestCase' is deprecated," \ "use 'KSSViewFunctionalTestCase'- KSS uppercase instead." warnings.warn(message, DeprecationWarning, 2) KSSViewFunctionalTestCase.__init__(self, *args, **kw) PK2i7PYWW"kss/core/tests/test_browserview.py# Copyright (c) 2005-2007 # Authors: KSS Project Contributors (see docs/CREDITS.txt) # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as published # by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. import unittest from base import KSSViewTestCase class TestBrowserView(KSSViewTestCase): def test_attach_error(self): 'Test if errors are attached properly' # just render any page context = self.folder view = context.restrictedTraverse('@@kss_view') self.assert_(view is not None) view.attach_error(err_type='TheError', err_value='the_<>message\n\n') response = view.request.response header = response.getHeader('x-ksscommands') self.assert_('the_&lt;&gt;message' in header) # no < > in the message self.assert_('\n' not in header) # no /n in the payload: would destroy the page self.assertEqual(header, ' \t \t\tsystem \t\tTheError: the_&lt;&gt;message \t ') def test_suite(): suites = [] suites.append(unittest.makeSuite(TestBrowserView)) return unittest.TestSuite(suites) PK2i7 kss/core/tests/test_kssview.py# -*- coding: latin-1 -*- # Copyright (c) 2005-2007 # Authors: KSS Project Contributors (see docs/CREDITS.txt) # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as published # by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. import unittest from kss.core.interfaces import IKSSView, IKSSCommands from kss.core.plugins.core.interfaces import IKSSCoreCommands from kss.core.plugins.core.commands import KSSCoreCommands from kss.core.pluginregistry.interfaces import IAction, ICommandSet from kss.core.pluginregistry.action import Action from kss.core.pluginregistry.plugin import registerPlugin from kss.core.pluginregistry.commandset import CommandSet from kss.core.tests.commandinspector import CommandInspectorView import zope.component.event from zope.testing import doctest, cleanup from zope.publisher.interfaces.browser import IBrowserRequest from zope.app.component.hooks import setHooks def setUpAjaxView(test=None): setHooks() zope.component.provideAdapter(CommandInspectorView, adapts=(IKSSCommands, IBrowserRequest)) registerPlugin(Action, IAction, 'replaceInnerHTML', None, 'selector', 'html', [], None) zope.component.provideAdapter(KSSCoreCommands, adapts=(IKSSView,), provides=IKSSCoreCommands) registerPlugin(CommandSet, ICommandSet, 'core', IKSSCoreCommands) def tearDownAjaxView(test=None): cleanup.cleanUp() def test_suite(): return unittest.TestSuite([ doctest.DocTestSuite('kss.core.kssview'), doctest.DocFileSuite('kssview.txt', package='kss.core', setUp=setUpAjaxView, tearDown=tearDownAjaxView), ]) PK2i7ъ )kss/core/tests/test_kssview_functional.py# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as published # by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # import unittest import Products.Five from Products.Five import zcml from Testing.ZopeTestCase import FunctionalDocTestSuite from zope import event, component from zope.testing.cleanup import cleanUp from zope.lifecycleevent import ObjectModifiedEvent from zope.app.component.hooks import getSite, setHooks from kss.core import KSSView class TestKSSView(KSSView): def __call__(self): self.messages = [] if getSite() == self: self.messages.append("I'm the current site.") if component.getSiteManager() == self.getSiteManager(): self.messages.append("I have the current site manager.") event.notify(ObjectModifiedEvent(self.context)) return "\n".join(self.messages) @component.adapter(None, KSSView, ObjectModifiedEvent) def objectModifiedThruKSSView(obj, view, event): view.messages.append("Event subscriber was here.") def setUp(test=None): configure_zcml = '''\ ''' zcml.load_config('configure.zcml', Products.Five) zcml.load_string(configure_zcml) setHooks() def tearDown(test=None): cleanUp() def ftest_kssview(): """ Let's verify that a KSSView actually is the current site when it's being traversed to. Also, let's make sure that if in the course of this view, an object event is fired, the view will dispatch to KSS-specific subscribers: >>> from Products.Five.testbrowser import Browser >>> browser = Browser('http://localhost:8080/testkssview') >>> print browser.contents I'm the current site. I have the current site manager. Event subscriber was here. """ def test_suite(): return unittest.TestSuite([ FunctionalDocTestSuite(setUp=setUp, tearDown=tearDown), ]) PK2i7Z$Ũ#kss/core/tests/test_kssview_core.py# -*- coding: latin-1 -*- # Copyright (c) 2005-2007 # Authors: KSS Project Contributors (see docs/CREDITS.txt) # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as published # by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. import unittest import textwrap from kss.core import KSSUnicodeError from kss.core.tests.base import KSSViewTestCase from Testing.ZopeTestCase import FunctionalDocFileSuite class TestKSSViewCoreCommandSet(KSSViewTestCase): def test_empty(self): view = self.createView() commands = view.getCommands() self.assertEqual(len(commands), 0) def test_addCommand(self): view = self.createView() commands = view.getCommands() command = commands.addCommand('replaceInnerHTML', 'selector') self.assertEqual(len(commands), 1) self.assertEqual(command.getName(), 'replaceInnerHTML') self.assertEqual(command.getSelector(), 'selector') params = command.getParams() self.assertEqual(len(params), 0) # XXX since lxml is gone, the next cases are no problem anymore # Nevertheless, we test all these cases def _checkSetHtmlResult(self, content, content2=None): view = self.createView() view.getCommandSet('core').replaceInnerHTML('div.class', content) commands = view.getCommands() self.assertEqual(len(commands), 1) command = commands[0] self.assertEqual(command.getName(), 'replaceInnerHTML') self.assertEqual(command.getSelector(), 'div.class') params = command.getParams() self.assertEqual(len(params), 2) self.assertEqual(params[0].getName(), 'html') self.assertEqual(params[1].getName(), 'withKssSetup') if content2 == None: content2 = content self.assertEqual(params[0].getContent().encode('ascii', 'xmlcharrefreplace'), content2.encode('ascii', 'xmlcharrefreplace')) def test_replaceInnerHTMLTextPlusEntity(self): 'See if non breaking space entity works' ##self._checkSetHtmlResult(' ') # XXX we remove html named entities now self._checkSetHtmlResult(' ', ' ') def test_replaceInnerHTMLTextPlusEntityOthers(self): 'See if the other HTML entities work as well' # XXX we remove html named entities now self._checkSetHtmlResult('

    »Hello world!«

    ', '

    »Hello world!«

    ') def test_replaceInnerHTMLTextOnly(self): self._checkSetHtmlResult('new content') def test_replaceInnerHTMLTagOnly(self): self._checkSetHtmlResult('

    new_content

    ') def test_replaceInnerHTMLTagPlusText(self): self._checkSetHtmlResult('

    new_content

    after') def test_replaceInnerHTMLTextTagPlusText(self): self._checkSetHtmlResult('before

    new_content

    after') def test_setHtmlAcceptsUnicode(self): 'Test that it accepts unicode' self._checkSetHtmlResult(u'abc') def test_setHtmlChecksForNonUnicode(self): 'Test that it does not accept non unicode (unless pure ascii)' self.assertRaises(KSSUnicodeError, self._checkSetHtmlResult, 'abc') class FTestKSSViewCoreCommandSet(KSSViewTestCase): 'Functional tests' def _wrapped_commands(self, inline): header = textwrap.dedent(u'''\ ''') footer = textwrap.dedent('''\ ''') return header + inline + footer def assertXMLEquals(self, a, b): self.assertEqual(a, b) def assertCommandsEqual(self, a, b): self.assertXMLEquals(a, self._wrapped_commands(b)) def test_empty(self): view = self.createView() result = view.render() self.assertEquals(view.request.response.getHeader('content-type'), 'text/xml;charset=utf-8') self.assertCommandsEqual(result, '') def test_replaceInnerHTML(self): view = self.createView() view.getCommandSet('core').replaceInnerHTML('div.class', 'new content') result = view.render() awaited = u'''\ new content True ''' self.assertCommandsEqual(result, awaited) def test_setCommandSet(self): view = self.createView() cs = view.getCommandSet('core') cs.replaceInnerHTML('div.class', 'new content') result = view.render() awaited = u'''\ new content True ''' self.assertCommandsEqual(result, awaited) def afterSetUp(self): KSSViewTestCase.afterSetUp(self) self.setDebugRequest() def test_suite(): suites = [] suites.append(unittest.makeSuite(TestKSSViewCoreCommandSet)) suites.append(unittest.makeSuite(FTestKSSViewCoreCommandSet)) suites.append(FunctionalDocFileSuite('../actionwrapper.py', test_class=KSSViewTestCase, setUp=afterSetUp, tearDown=KSSViewTestCase.beforeTearDown.im_func)) return unittest.TestSuite(suites) PK2i7fkss/core/tests/test_siteview.pyimport unittest import zope.component.event # import does the trick from zope.testing import doctest from zope.testing.cleanup import cleanUp from zope.app.component.hooks import setHooks def setUp(test=None): setHooks() def tearDown(test=None): cleanUp() def test_suite(): return unittest.TestSuite([ doctest.DocFileSuite('siteview.txt', package='kss.core', setUp=setUp, tearDown=tearDown) ]) PK2i7}1Okss/core/tests/ecmaview.py# Copyright (c) 2005-2007 # Authors: KSS Project Contributors (see docs/CREDITS.txt) # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as published # by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. try: from Products.Five import BrowserView except ImportError: from zope.app.publisher.browser import BrowserView from zope.interface import Interface, implements from zope.app import zapi from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile import os.path from zope.publisher.interfaces.browser import IBrowserPublisher from zope.publisher.interfaces import NotFound # Oh well... file resource has different import locations in zope and five, # the factories take different parameters order, # plus these are not "entirely clean" as far as caching is concerned... # Instead, use the resources implemented from concatresource: # this is version free and has properly implemented cache control. from kss.core.pluginregistry._concatresource.resource import ConcatResourceFactory _marker = object() # z3 only from zope.security.checker import CheckerPublic, NamesChecker allowed_names = ('GET', 'HEAD', 'publishTraverse', 'browserDefault', 'request', '__call__') permission = CheckerPublic checker = NamesChecker(allowed_names, permission) class ViewFile(object): '''A wrapper for file resources that can be used in a view Similar to ViewPageTemplate in usage. (We only use the FileResource here, no distinction on content types like in the resourceDirectory code.) ''' def __init__(self, name, path): # Create the resource with cache control most proper for debugging. self.resource_factory = ConcatResourceFactory([path], name, compress_level='none', caching='memory', lmt_check_period=0.0, checker=checker) self.name = name def __get__(self, obj, cls=None): 'The view wants a method only.' request = obj.request resource = self.resource_factory(request) resource.__parent__ = obj resource.__name__ = self.name return resource def absolute_dir(path): here = os.path.split(globals()['__file__'])[0] return os.path.abspath(os.path.join(here, path)) class EcmaView(BrowserView): '''Kukit test view This allows the runner.html to be used on this view. This provides the tests run with the compiled kukit.js resource, in the same way as they would be run in production with kss. ''' implements(IBrowserPublisher) _testdir = absolute_dir('../kukit/tests') _runner = ViewPageTemplateFile('../kukit/tests/runner.html', content_type='text/html; charset=utf-8') # The next is only necessary on Zope (<=) 2.9, # provides a docstring to the method def _runner_proxy(self, *arg, **kw): 'Publishable method' return self._runner(*arg, **kw) def publishTraverse(self, request, name): '''See interface IBrowserPublisher''' return self.get(name) def browserDefault(self, request): '''See interface IBrowserPublisher''' return self, () def __getitem__(self, name): res = self.get(name, None) if res is None: raise KeyError(name) return res def get(self, name, default=_marker): # runner.html is compiled as a pagetemplate if name == 'runner.html': # XXX For Zope2.9 we need this. if not hasattr(self.request, 'debug'): self.request.debug = None # proxy is used to make it publishable, on Zope <= 2.9 return self._runner_proxy # We store them on the view on demand. # Is it there yet? if name[0] != '_': try: return getattr(self, name) except AttributeError: pass # See the file we need path = os.path.join(self._testdir, name) if os.path.isfile(path): # Ok, this is a file. Cook it. resource = ViewFile(name, path) setattr(self.__class__, name, resource) # important: return accessed *from* the view. return getattr(self, name) # Not found. if default is _marker: raise NotFound(None, name) return default def __call__(self): 'By default we redirect to runner.html.' # on Zope3, the url is of zope.publisher.http.URLGetter class, so we must stringify it return self.request.response.redirect(str(self.request.URL) + '/runner.html') PK2i7Ypkss/core/tests/help_ttwapi.pyfrom zope import event from zope.lifecycleevent import ObjectModifiedEvent def objectModified(context): event.notify(ObjectModifiedEvent(context)) PK2i7̗"kss/core/tests/commandinspector.py# Copyright (c) 2006-2007 # Authors: KSS Project Contributors (see docs/CREDITS.txt) # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as published # by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. from zope.interface import implements from kss.core.interfaces import IKSSCommandView class CommandInspectorView(object): '''Inspector view of a command. This enables debugging checks. Returns commands as a list of dicts. Look at the tests to see what checks this makes possible. ''' implements(IKSSCommandView) def __init__(self, context, request): self.context = context self.request = request # Force parameters content to be unicode for command in context: for param in command.getParams(): param.force_content_unicode() def render(self): result = [] for command in self.context: d = dict(command.__dict__) # params are converted to a dict from a list. # Also get rid of "none" params that were only a hack for xml d['params'] = dict([(param.name, param.content) for param in d['params'] if param.name != 'none']) result.append(d) return result PK2i7jkss/core/tests/test_ttwapi.pyimport unittest from Testing import ZopeTestCase ZopeTestCase.installProduct('PythonScripts') from AccessControl import allow_module allow_module('kss.core.tests.help_ttwapi') import Products.Five.component from Products.Five import zcml from zope import component from zope.lifecycleevent import ObjectModifiedEvent from zope.app.component.hooks import setHooks from kss.core import KSSView from kss.core.tests.base import KSSViewTestCase class TTWTestCase(KSSViewTestCase): class layer(KSSViewTestCase.layer): @classmethod def setUp(cls): configure_zcml = '''\ ''' zcml.load_string(configure_zcml) def afterSetUp(self): KSSViewTestCase.afterSetUp(self) setHooks() self.app.manage_addProduct['PythonScripts'].manage_addPythonScript( 'kss_test') self.setDebugRequest() def test_scriptWithCore(self): pythonScriptCode = ''' from kss.core.ttwapi import startKSSCommands from kss.core.ttwapi import getKSSCommandSet from kss.core.ttwapi import renderKSSCommands startKSSCommands(context, context.REQUEST) core = getKSSCommandSet('core') core.replaceInnerHTML('#test', '

    Done

    ') return renderKSSCommands() ''' self.app.kss_test.ZPythonScript_edit('', pythonScriptCode) result = self.app.kss_test() self.assertEquals(len(result), 1) command = result[0] self.assertEquals(command['selector'], '#test') self.assertEquals(command['name'], 'replaceInnerHTML') def test_scriptWithEffect(self): pythonScriptCode = ''' from kss.core.ttwapi import startKSSCommands from kss.core.ttwapi import getKSSCommandSet from kss.core.ttwapi import renderKSSCommands startKSSCommands(context, context.REQUEST) commandSet = getKSSCommandSet('effects') commandSet.effect('#test', 'fade') return renderKSSCommands() ''' self.app.kss_test.ZPythonScript_edit('', pythonScriptCode) result = self.app.kss_test() self.assertEquals(len(result), 1) command = result[0] self.assertEquals(command['selector'], '#test') self.assertEquals(command['name'], 'effect') self.assertEquals(command['params']['type'], 'fade') def test_scriptWithEvents(self): pythonScriptCode = ''' from kss.core.ttwapi import startKSSCommands from kss.core.ttwapi import getKSSCommandSet from kss.core.ttwapi import renderKSSCommands from kss.core.tests.help_ttwapi import objectModified startKSSCommands(context, context.REQUEST) core = getKSSCommandSet('core') core.replaceInnerHTML('#test', '

    Done

    ') objectModified(context) return renderKSSCommands() ''' self.app.kss_test.ZPythonScript_edit('', pythonScriptCode) result = self.app.kss_test() self.assertEquals(len(result), 2) command = result[0] self.assertEquals(command['selector'], '#test') self.assertEquals(command['name'], 'replaceInnerHTML') command = result[1] self.assertEquals(command['selector'], '#event') self.assertEquals(command['name'], 'replaceInnerHTML') @component.adapter(None, KSSView, ObjectModifiedEvent) def objectModifiedThruKSSView(obj, view, event): view.getCommandSet('core').replaceInnerHTML( "#event", "Event subscriber was here.") def test_suite(): suites = [] suites.append(unittest.makeSuite(TTWTestCase)) return unittest.TestSuite(suites) PK2i7xu$kss/core/tests/configure-online.zcml PK2i7ކgVV&kss/core/tests/configure-unittest.zcml PK2i7Ayy$kss/core/tests/kukitresponse_test.pt

    it worked

    it worked again (test)

    PK i7Ȁkss/core/tests/__init__.pyc; %4Gc@sdS(N((((s5build/bdist.linux-i686/egg/kss/core/tests/__init__.pys?sPK i7 kk#kss/core/tests/test_browserview.pyc; %4Gc@s9dkZdklZdefdYZdZdS(N(sKSSViewTestCasesTestBrowserViewcBstZdZRS(NcCs|i}|id}|i|tj |idddd|ii }|i d}|id|j|id|j|i |d d S( s$Test if errors are attached properlys @@kss_viewserr_typesTheErrors err_valuesthe_<>message s x-ksscommandssthe_&lt;&gt;messages s, system TheError: the_&lt;&gt;message N( sselfsfolderscontextsrestrictedTraversesviewsassert_sNones attach_errorsrequestsresponses getHeadersheaders assertEqual(sselfsheaderscontextsresponsesview((s=build/bdist.linux-i686/egg/kss/core/tests/test_browserview.pystest_attach_errors  (s__name__s __module__stest_attach_error(((s=build/bdist.linux-i686/egg/kss/core/tests/test_browserview.pysTestBrowserViewscCs-g}|ititti|SdS(N(ssuitessappendsunittests makeSuitesTestBrowserViews TestSuite(ssuites((s=build/bdist.linux-i686/egg/kss/core/tests/test_browserview.pys test_suite$s(sunittestsbasesKSSViewTestCasesTestBrowserViews test_suite(sTestBrowserViewsunittests test_suitesKSSViewTestCase((s=build/bdist.linux-i686/egg/kss/core/tests/test_browserview.pys?s  PK i7&c. . kss/core/tests/test_kssview.pyc; %4Gc@sdkZdklZlZdklZdklZdkl Z l Z dk l Z dk lZdklZdklZdkZd klZlZd klZd klZed Zed ZdZdS(N(sIKSSViews IKSSCommands(sIKSSCoreCommands(sKSSCoreCommands(sIActions ICommandSet(sAction(sregisterPlugin(s CommandSet(sCommandInspectorView(sdoctestscleanup(sIBrowserRequest(ssetHooksc Csxttiitdttfttt dt ddgt tiit dt fdt tttdt dS(NsadaptssreplaceInnerHTMLsselectorshtmlsprovidesscore(ssetHooksszopes componentsprovideAdaptersCommandInspectorViews IKSSCommandssIBrowserRequestsregisterPluginsActionsIActionsNonesKSSCoreCommandssIKSSViewsIKSSCoreCommandss CommandSets ICommandSet(stest((s9build/bdist.linux-i686/egg/kss/core/tests/test_kssview.pys setUpAjaxView#s    cCstidS(N(scleanupscleanUp(stest((s9build/bdist.linux-i686/egg/kss/core/tests/test_kssview.pystearDownAjaxView.sc Cs;titidtiddddtdtgSdS(Nskss.core.kssviews kssview.txtspackageskss.coressetUpstearDown(sunittests TestSuitesdoctests DocTestSuites DocFileSuites setUpAjaxViewstearDownAjaxView(((s9build/bdist.linux-i686/egg/kss/core/tests/test_kssview.pys test_suite1s( sunittestskss.core.interfacessIKSSViews IKSSCommandss kss.core.plugins.core.interfacessIKSSCoreCommandsskss.core.plugins.core.commandssKSSCoreCommandss"kss.core.pluginregistry.interfacessIActions ICommandSetskss.core.pluginregistry.actionsActionskss.core.pluginregistry.pluginsregisterPlugins"kss.core.pluginregistry.commandsets CommandSetskss.core.tests.commandinspectorsCommandInspectorViewszope.component.eventszopes zope.testingsdoctestscleanups!zope.publisher.interfaces.browsersIBrowserRequestszope.app.component.hooksssetHookssNones setUpAjaxViewstearDownAjaxViews test_suite(sIBrowserRequestscleanupszopessetHookssCommandInspectorViews setUpAjaxViewstearDownAjaxViewsunittestsIKSSViews CommandSets IKSSCommandssKSSCoreCommandss ICommandSetsIActionsdoctests test_suitesActionsregisterPluginsIKSSCoreCommands((s9build/bdist.linux-i686/egg/kss/core/tests/test_kssview.pys?s           PK i7 &&$kss/core/tests/test_kssview_core.pyc; %4Gc@s{dkZdkZdklZdklZdklZdefdYZdefdYZ dZ d Z dS( N(sKSSUnicodeError(sKSSViewTestCase(sFunctionalDocFileSuitesTestKSSViewCoreCommandSetcBsntZdZdZedZdZdZdZdZ dZ d Z d Z d Z RS( NcCs2|i}|i}|it|ddS(Ni(sselfs createViewsviews getCommandsscommandss assertEqualslen(sselfscommandssview((s>build/bdist.linux-i686/egg/kss/core/tests/test_kssview_core.pys test_emptys  cCs|i}|i}|idd}|it|d|i|i d|i|i d|i }|it|ddS(NsreplaceInnerHTMLsselectorii( sselfs createViewsviews getCommandsscommandss addCommandscommands assertEqualslensgetNames getSelectors getParamssparams(sselfscommandssparamsscommandsview((s>build/bdist.linux-i686/egg/kss/core/tests/test_kssview_core.pystest_addCommand s   cCs |i}|idid||i}|it |d|d}|i|i d|i|i d|i }|it |d|i|di d|i|di d|tjo |}n|i|diid d |id d dS( Nscores div.classiisreplaceInnerHTMLishtmls withKssSetupsasciisxmlcharrefreplace(sselfs createViewsviews getCommandSetsreplaceInnerHTMLscontents getCommandsscommandss assertEqualslenscommandsgetNames getSelectors getParamssparamsscontent2sNones getContentsencode(sselfscontentscontent2scommandsscommandsparamssview((s>build/bdist.linux-i686/egg/kss/core/tests/test_kssview_core.pys_checkSetHtmlResult-s      cCs|idddS(s&See if non breaking space entity workss s N(sselfs_checkSetHtmlResult(sself((s>build/bdist.linux-i686/egg/kss/core/tests/test_kssview_core.pys#test_replaceInnerHTMLTextPlusEntity=scCs|idddS(s+See if the other HTML entities work as wellsF

    »Hello world!«

    sD

    »Hello world!«

    N(sselfs_checkSetHtmlResult(sself((s>build/bdist.linux-i686/egg/kss/core/tests/test_kssview_core.pys)test_replaceInnerHTMLTextPlusEntityOthersCs cCs|iddS(Ns new content(sselfs_checkSetHtmlResult(sself((s>build/bdist.linux-i686/egg/kss/core/tests/test_kssview_core.pystest_replaceInnerHTMLTextOnlyIscCs|iddS(Ns7

    new_content

    (sselfs_checkSetHtmlResult(sself((s>build/bdist.linux-i686/egg/kss/core/tests/test_kssview_core.pystest_replaceInnerHTMLTagOnlyLscCs|iddS(Ns<

    new_content

    after(sselfs_checkSetHtmlResult(sself((s>build/bdist.linux-i686/egg/kss/core/tests/test_kssview_core.pys test_replaceInnerHTMLTagPlusTextOscCs|iddS(NsBbefore

    new_content

    after(sselfs_checkSetHtmlResult(sself((s>build/bdist.linux-i686/egg/kss/core/tests/test_kssview_core.pys$test_replaceInnerHTMLTextTagPlusTextRscCs|iddS(sTest that it accepts unicodeuabcáN(sselfs_checkSetHtmlResult(sself((s>build/bdist.linux-i686/egg/kss/core/tests/test_kssview_core.pystest_setHtmlAcceptsUnicodeUscCs|it|iddS(s<Test that it does not accept non unicode (unless pure ascii)sabcN(sselfs assertRaisessKSSUnicodeErrors_checkSetHtmlResult(sself((s>build/bdist.linux-i686/egg/kss/core/tests/test_kssview_core.pystest_setHtmlChecksForNonUnicodeYs(s__name__s __module__s test_emptystest_addCommandsNones_checkSetHtmlResults#test_replaceInnerHTMLTextPlusEntitys)test_replaceInnerHTMLTextPlusEntityOthersstest_replaceInnerHTMLTextOnlystest_replaceInnerHTMLTagOnlys test_replaceInnerHTMLTagPlusTexts$test_replaceInnerHTMLTextTagPlusTextstest_setHtmlAcceptsUnicodestest_setHtmlChecksForNonUnicode(((s>build/bdist.linux-i686/egg/kss/core/tests/test_kssview_core.pysTestKSSViewCoreCommandSets         sFTestKSSViewCoreCommandSetcBsDtZdZdZdZdZdZdZdZRS(sFunctional testscCs.tid}tid}|||SdS(NuC sQ (stextwrapsdedentsheadersfootersinline(sselfsinlinesfootersheader((s>build/bdist.linux-i686/egg/kss/core/tests/test_kssview_core.pys_wrapped_commands`scCs|i||dS(N(sselfs assertEqualsasb(sselfsasb((s>build/bdist.linux-i686/egg/kss/core/tests/test_kssview_core.pysassertXMLEqualsmscCs|i||i|dS(N(sselfsassertXMLEqualssas_wrapped_commandssb(sselfsasb((s>build/bdist.linux-i686/egg/kss/core/tests/test_kssview_core.pysassertCommandsEqualpscCsK|i}|i}|i|iiidd|i |ddS(Ns content-typestext/xml;charset=utf-8s( sselfs createViewsviewsrendersresults assertEqualssrequestsresponses getHeadersassertCommandsEqual(sselfsresultsview((s>build/bdist.linux-i686/egg/kss/core/tests/test_kssview_core.pys test_emptyss  cCsK|i}|ididd|i}d}|i||dS(Nscores div.classs new contentu new content True ( sselfs createViewsviews getCommandSetsreplaceInnerHTMLsrendersresultsawaitedsassertCommandsEqual(sselfsresultsawaitedsview((s>build/bdist.linux-i686/egg/kss/core/tests/test_kssview_core.pystest_replaceInnerHTMLys   cCsQ|i}|id}|idd|i}d}|i ||dS(Nscores div.classs new contentu new content True ( sselfs createViewsviews getCommandSetscssreplaceInnerHTMLsrendersresultsawaitedsassertCommandsEqual(sselfscssresultsawaitedsview((s>build/bdist.linux-i686/egg/kss/core/tests/test_kssview_core.pystest_setCommandSets   ( s__name__s __module__s__doc__s_wrapped_commandssassertXMLEqualssassertCommandsEquals test_emptystest_replaceInnerHTMLstest_setCommandSet(((s>build/bdist.linux-i686/egg/kss/core/tests/test_kssview_core.pysFTestKSSViewCoreCommandSet]s     cCsti||idS(N(sKSSViewTestCases afterSetUpsselfssetDebugRequest(sself((s>build/bdist.linux-i686/egg/kss/core/tests/test_kssview_core.pys afterSetUps c Csng}|itit|itit|itddtdtdti i ti |SdS(Ns../actionwrapper.pys test_classssetUpstearDown( ssuitessappendsunittests makeSuitesTestKSSViewCoreCommandSetsFTestKSSViewCoreCommandSetsFunctionalDocFileSuitesKSSViewTestCases afterSetUpsbeforeTearDownsim_funcs TestSuite(ssuites((s>build/bdist.linux-i686/egg/kss/core/tests/test_kssview_core.pys test_suites ( sunitteststextwrapskss.coresKSSUnicodeErrorskss.core.tests.basesKSSViewTestCasesTesting.ZopeTestCasesFunctionalDocFileSuitesTestKSSViewCoreCommandSetsFTestKSSViewCoreCommandSets afterSetUps test_suite( sFunctionalDocFileSuitesFTestKSSViewCoreCommandSetsunitteststextwrapsKSSUnicodeErrors afterSetUpsTestKSSViewCoreCommandSets test_suitesKSSViewTestCase((s>build/bdist.linux-i686/egg/kss/core/tests/test_kssview_core.pys?s     D7 PK i7 kss/core/tests/test_siteview.pyc; %4Gc@s^dkZdkZdklZdklZdklZe dZ e dZ dZ dS(N(sdoctest(scleanUp(ssetHookscCs tdS(N(ssetHooks(stest((s:build/bdist.linux-i686/egg/kss/core/tests/test_siteview.pyssetUpscCs tdS(N(scleanUp(stest((s:build/bdist.linux-i686/egg/kss/core/tests/test_siteview.pystearDown sc Cs/titiddddtdtgSdS(Ns siteview.txtspackageskss.coressetUpstearDown(sunittests TestSuitesdoctests DocFileSuitessetUpstearDown(((s:build/bdist.linux-i686/egg/kss/core/tests/test_siteview.pys test_suite s( sunittestszope.component.eventszopes zope.testingsdoctestszope.testing.cleanupscleanUpszope.app.component.hooksssetHookssNonessetUpstearDowns test_suite(ssetHooksstearDownsunittestscleanUpsdoctests test_suiteszopessetUp((s:build/bdist.linux-i686/egg/kss/core/tests/test_siteview.pys?s       PK i7Ƶkss/core/tests/ecmaview.pyc; %4Gc@sydklZWn ej odklZnXdklZlZdklZdk l Z dk Z dk lZdklZdklZeZdklZlZd d d d d dfZeZeeeZdefdYZdZdefdYZdS((s BrowserView(s Interfaces implements(szapi(sViewPageTemplateFileN(sIBrowserPublisher(sNotFound(sConcatResourceFactory(s CheckerPublics NamesCheckersGETsHEADspublishTraversesbrowserDefaultsrequests__call__sViewFilecBs#tZdZdZedZRS(sA wrapper for file resources that can be used in a view Similar to ViewPageTemplate in usage. (We only use the FileResource here, no distinction on content types like in the resourceDirectory code.) c Cs:t|g|dddddddt|_||_dS(Nscompress_levelsnonescachingsmemoryslmt_check_periodf0.0schecker(sConcatResourceFactoryspathsnamescheckersselfsresource_factory(sselfsnamespath((s5build/bdist.linux-i686/egg/kss/core/tests/ecmaview.pys__init__6s cCs5|i}|i|}||_|i|_|SdS(sThe view wants a method only.N(sobjsrequestsselfsresource_factorysresources __parent__snames__name__(sselfsobjsclssresourcesrequest((s5build/bdist.linux-i686/egg/kss/core/tests/ecmaview.pys__get__=s    (s__name__s __module__s__doc__s__init__sNones__get__(((s5build/bdist.linux-i686/egg/kss/core/tests/ecmaview.pysViewFile.s  cCs@tiitdd}tiitii||SdS(Ns__file__i(sosspathssplitsglobalssheresabspathsjoin(spathshere((s5build/bdist.linux-i686/egg/kss/core/tests/ecmaview.pys absolute_dirEssEcmaViewcBsotZdZeeedZedddZdZ dZ dZ dZ e d Zd ZRS( sKukit test view This allows the runner.html to be used on this view. This provides the tests run with the compiled kukit.js resource, in the same way as they would be run in production with kss. s../kukit/testss../kukit/tests/runner.htmls content_typestext/html; charset=utf-8cOs|i||SdS(sPublishable methodN(sselfs_runnersargskw(sselfsargskw((s5build/bdist.linux-i686/egg/kss/core/tests/ecmaview.pys _runner_proxy[scCs|i|SdS(sSee interface IBrowserPublisherN(sselfsgetsname(sselfsrequestsname((s5build/bdist.linux-i686/egg/kss/core/tests/ecmaview.pyspublishTraverse_scCs|ffSdS(sSee interface IBrowserPublisherN(sself(sselfsrequest((s5build/bdist.linux-i686/egg/kss/core/tests/ecmaview.pysbrowserDefaultcscCs7|i|t}|tjot|n|SdS(N(sselfsgetsnamesNonesressKeyError(sselfsnamesres((s5build/bdist.linux-i686/egg/kss/core/tests/ecmaview.pys __getitem__gs cCs|djo/t|id ot|i_n|iSn|ddjo+yt||SWqxtj oqxXnt i i |i |}t i i |o3t||}t|i||t||Sn|tjott|n|SdS(Ns runner.htmlsdebugis_(snameshasattrsselfsrequestsNonesdebugs _runner_proxysgetattrsAttributeErrorsosspathsjoins_testdirsisfilesViewFilesresourcessetattrs __class__sdefaults_markersNotFound(sselfsnamesdefaultsresourcespath((s5build/bdist.linux-i686/egg/kss/core/tests/ecmaview.pysgetms"    cCs'|iiit|iidSdS(s&By default we redirect to runner.html.s /runner.htmlN(sselfsrequestsresponsesredirectsstrsURL(sself((s5build/bdist.linux-i686/egg/kss/core/tests/ecmaview.pys__call__s(s__name__s __module__s__doc__s implementssIBrowserPublishers absolute_dirs_testdirsViewPageTemplateFiles_runners _runner_proxyspublishTraversesbrowserDefaults __getitem__s_markersgets__call__(((s5build/bdist.linux-i686/egg/kss/core/tests/ecmaview.pysEcmaViewIs        (s Products.Fives BrowserViews ImportErrorszope.app.publisher.browserszope.interfaces Interfaces implementsszope.appszapis*zope.app.pagetemplate.viewpagetemplatefilesViewPageTemplateFilesos.pathsoss!zope.publisher.interfaces.browsersIBrowserPublisherszope.publisher.interfacessNotFounds0kss.core.pluginregistry._concatresource.resourcesConcatResourceFactorysobjects_markerszope.security.checkers CheckerPublics NamesCheckers allowed_namess permissionscheckersViewFiles absolute_dirsEcmaView(s implementssNotFounds_markers permissions BrowserViews NamesCheckersConcatResourceFactorysIBrowserPublisherscheckersEcmaViews allowed_namessViewPageTemplateFiles CheckerPublicsViewFiles Interfaceszapis absolute_dirsos((s5build/bdist.linux-i686/egg/kss/core/tests/ecmaview.pys?s$        PK i7r MMkss/core/tests/help_ttwapi.pyc; %4Gc@s'dklZdklZdZdS((sevent(sObjectModifiedEventcCstit|dS(N(seventsnotifysObjectModifiedEventscontext(scontext((s8build/bdist.linux-i686/egg/kss/core/tests/help_ttwapi.pysobjectModifiedsN(szopeseventszope.lifecycleeventsObjectModifiedEventsobjectModified(sobjectModifiedseventsObjectModifiedEvent((s8build/bdist.linux-i686/egg/kss/core/tests/help_ttwapi.pys?s  PK i72<#kss/core/tests/commandinspector.pyc; %4Gc@s4dklZdklZdefdYZdS((s implements(sIKSSCommandViewsCommandInspectorViewcBs*tZdZeedZdZRS(sInspector view of a command. This enables debugging checks. Returns commands as a list of dicts. Look at the tests to see what checks this makes possible. cCsH||_||_x/|D]'}x|iD]}|iq,WqWdS(N(scontextsselfsrequestscommands getParamssparamsforce_content_unicode(sselfscontextsrequestscommandsparam((s=build/bdist.linux-i686/egg/kss/core/tests/commandinspector.pys__init__s   cCsg}x|iD]w}t|i}tgi}|dD]0}|i djo||i |i fq:q:~|d<|i|qW|SdS(Nsparamssnone( sresultsselfscontextscommandsdicts__dict__sdsappends_[1]sparamsnamescontent(sselfsdsparams_[1]sresultscommand((s=build/bdist.linux-i686/egg/kss/core/tests/commandinspector.pysrender(s U(s__name__s __module__s__doc__s implementssIKSSCommandViews__init__srender(((s=build/bdist.linux-i686/egg/kss/core/tests/commandinspector.pysCommandInspectorViews   N(szope.interfaces implementsskss.core.interfacessIKSSCommandViewsobjectsCommandInspectorView(s implementssIKSSCommandViewsCommandInspectorView((s=build/bdist.linux-i686/egg/kss/core/tests/commandinspector.pys?s  PK1i7 !kss/core/browser/errorresponse.pt system Exception: reason PK1i780]!kss/core/browser/kukitresponse.pt

    it worked

    PK2i7QUY;;kss/core/doc/tutorial_part2.rstThis tutorial is the direct continuation of the `first part`_. We will learn how to specify server side actions and finally complete our first useful AJAX example. .. _first part: http://kukit.org/documentation/tutorials/begin-with-kss Creating a server action ------------------------ Until now, we called a client action (alert) from our event. This was good to test if our event was triggered. However, in a typical AJAX pattern, we want to call a server action. Server actions are implemented as methods on the server. They could be any kind of callable methods, including python scripts, and this is what we will do first. Besides doing whatever is necessary for the business logic, the task of the server method is to assemble a sequence of commands. These commands are marshalled back to the client to be executed there. A command is a call to DOM manipulation client code. A command can (in most cases, should) have a selector, to set the scope of nodes on which the command is executed, and a set of parameters for execution. Although existing components come with implemented server action methods, it is easy to create a custom one since it requires only python skills. Let's create a python script (`response1`) in the custom skin : :: # import Through-The-Web(TTW) API from kss.core.ttwapi import startKSSCommands from kss.core.ttwapi import getKSSCommandSet from kss.core.ttwapi import renderKSSCommands # start a view for commands startKSSCommands(context, context.REQUEST) # add a command core = getKSSCommandSet('core') core.replaceInnerHTML('#portal-siteactions', '

    We did it!

    ') # render the commands return renderKSSCommands() After the imports, we initialize the view that will hold the KSS commands that we want to send back to the client. Then we add a command. The name of the command is `replaceInnerHTML`. This is one of our most useful commands : it simply replaces the contents of the selected html nodes with some html string. To specify which nodes will be selected, the command also needs a selector: in this example, a standard CSS selector. We choose to replace the portal actions of a Plone portal that are on the top of the page - but we could choose any other element as well. The `replaceInnerHTML` method is accessed through a command set. Since we have a pluggable system, we need to refer to the component that defines the methods, in this case, the `'core'` command set. In the last line, the `renderKSSCommands` call is mandatory : it will generate the response payload from the accumulated commands. To look at this payload, let's access this method directly from the browser : `http://localhost:8080/plone/front-page/response1`. We will see "We did it!" on the screen, but let's have a more careful look at the source of the response : ::

    We did it!

    This is an XML response, where we can see how commands and parameters are actually marshalled. When the response is interpreted by the kss engine, it will execute the commands with the given parameters. Calling the server action ------------------------- Now, we have finished to build our server action; we want to call it from our kss style sheet. We replace our previous kss event rule with the following one : :: a.navTreeCurrentItem:click { evt-click-preventdefault: True; action-server: response1; } The `action-server` line specifies the name of the remote method to call : `response1` (since this is how we named our python script). The script will be called on the context url of the page we are at. Let's reload the page so that the new kss comes into effect. Open the loggingpane. Then press the "Home" line in the navtree portlet. It works! We can see the site actions replaced with our text. Also notice that a few things have been logged to the loggingpane : :: ... DEBUG: RequestManager Notify server http://localhost:8080/plone/front-page/response1, rid=0 (RQ: 1 OUT, 0 WAI) DEBUG: RequestManager Received result with rid=0 (RQ: 0 OUT, 0 WAI) INFO: Parse commands DEBUG: Number of commands: 1 DEBUG: Selector type: default (css), selector : "#portal-siteactions", selected nodes:1 DEBUG: Command Name: replaceInnerHTML ... This gives a lot of information about what happened in the client : - the server is notified, - the response is received, - it is parsed successfully, - it contains one command, - the command selects 1 node to act on. Now let's change our command response in the following way : :: ... from DateTime import DateTime # add a command core = getKSSCommandSet('core') content = '

    We did it!

    %s' % DateTime() core.replaceInnerHTML('#portal-siteactions', content) ... This way, the current time is sent back by the server on each click and we can see that something happens. It is interesting to note that we did not need to reload the page in order to see the effect of this change. Because we only made changes on the server, we did not need to load anything new on the client side. So we can continue to debug from the already loaded page and this will work even through server restarts. What happens if the server-side script has an error, or the client does not get a correct response for some reason ? In this case, we will see this in the loggingpane : :: DEBUG: RequestManager Notify server http://localhost:8080/tutorial/front-page/response1, rid=3 (RQ: 1 OUT, 0 WAI) DEBUG: RequestManager Received result with rid=3 (RQ: 0 OUT, 0 WAI) ERROR: Request failed at url http://localhost:8080/tutorial/front-page/response1, rid=3 The error `Request failed` indicates that we have to turn to the server to debug the problem. Our best friend, the zope error log will tell us about the actual problem. Server action parameters ------------------------ Like client actions, server actions can also accept parameters. The parameters will be sent to the server as form variables. Zope publisher can then pass them as usual keyword parameters to our python script. Let's render a parameter coming from the client. We add parameter `mymessage` to the python script. Then modify the script : :: ... # add a command core = getKSSCommandSet('core') content = '

    We did it!

    %s at %s' % (mymessage, DateTime())) core.replaceInnerHTML('#portal-siteactions', content) ... We modify our kss rule to actually send the parameter from the client : :: a.navTreeCurrentItem:click { evt-click-preventdefault: True; action-server: response1; response1-mymessage: "Hello Plone!"; } The key `response1-mymessage` is built identically to how we did it with the client action. We use the name of the action first and then, following the dash, the name of the parameter. This time, because we change the stylesheet, we need to reload the page before testing by clicking on the bound node. To understand better how all this is working, let's enter a second rule in the kss : :: ul#portal-globalnav li a:click { evt-click-preventdefault: True; action-server: response1; response1-mymessage: "clicked on global nav"; } This shows some new things. First, you can see that you can use any css selector in a rule. In this case, the selector will select all globalnav tab links. If you reload the page, you will notice that if you click on any of those links, different content is replaced because different parameter are passed to the server. If you take a look at the loggingpane after the page reload, you can see something like this : :: INFO: Initializing kss ... INFO: Count of KSS links: 1 INFO: Start loading and processing http://localhost:8080/plone/portal_css/Plone%20Default/tutor-cachekey9967.kss resource type kss DEBUG: EventRule #0: a.navTreeCurrentItem EVENT=click DEBUG: EventRule #1: ul#portal-globalnav li a EVENT=click INFO: Finished loading and processing http://localhost:8080/plone/portal_css/Plone%20Default/tutor-cachekey9967.kss resource type kss in 35 + 29 ms INFO: Starting setting up events for document DEBUG: EventRule #0 mergeid @@0@@click selected 1 nodes DEBUG: EventRule #1 mergeid @@0@@click selected 4 nodes DEBUG: Binding 0 special rules in grand total DEBUG: instantiating event id=@@0, classname=0, namespace=null DEBUG: Binding to 5 nodes in grand total ... This shows that the second rule is also in effect now. Moreover, it has selected 4 nodes (or however many globalnav tabs you have). A lot of other information is also logged, it should not worry you at the moment. Different command selector -------------------------- Until now, in our command, we used the default css selector. It is possible to use other types of selectors, like a html id selector. Let's modify our command in the following way : :: ... # add a command core = getKSSCommandSet('core') content = '

    We did it!

    %s at %s' % (mymessage, DateTime())) selector = core.getHtmlIdSelector('portal-personaltools'), core.replaceInnerHTML(selector, content) ... What an HTML id selector selects should be obvious. Reload the page and exercise... Commands can also select multiple nodes : :: ... # add a command core = getKSSCommandSet('core') content = '

    We did it!

    %s at %s' % (mymessage, DateTime())) selector = core.getCssSelector('dt.portletHeader a'), core.replaceInnerHTML(selector, content) ... The css selector `dt.portletHeader a` selects all portlet headers in the page, so the replacement will be executed not on one node but on many nodes (as can also be seen in the loggingpane). Try clicking the `Home` link in the navtree, or any of the globalnav tabs to see the effect. You can also add multiple commands : each of them will be executed, in the order they have within the payload. One thing is important to note. If a command selects no nodes, it is not an error : the behaviour designed in this case is that nothing happens. This is in line with the usual logic of css selectors in style sheets. Using a different event ----------------------- So far we have only used the `click` event: let's try with another one, `timeout`. The `timeout` event does not directly map to a browser event but it is a (conceptual) kss event. This shows that in kss anything can be an event and how an event binds itself is freely implementable. Let's add the following rule to the end of our kss file (altogether we will have 3 rules then) : :: document:timeout { evt-timeout-delay: 8000; action-server: response1; response1-mymessage: "from timeout"; } The `timeout` event implements a recurring timeout tick. It has a `delay` parameter that specifies the time in milliseconds. In this case, the event will be triggered each 8 seconds over and over again. The event calls the server action that we already have but with a different parameter. The `timeout` event does not really need a node as binding scope. This is why we use `document` instead of a css selector as we did until now. This is a special kss selector that is an extension to css and simply means : bind this event exactly once when the document loads, with a scope of no nodes but the document itself. If you reload the page you will notice that clicks work as before, however, every 8 seconds, the timeout event will trigger and do a replacement on the required nodes. There are some more advanced issues that this example opens and we will show more about them in the next tutorials. *Congratulations!* You have completed your first kss tutorial, learned the basics and now you are able to start some experimentation on your own. Or, just sit back and relax. Server-side commands - the zope3 way ------------------------------------ A python script may not be the most proper implementation of a server method. Plone community is moving towards zope3 style development : the suggested way is to use a browser view (multiadapter). Previously, you have created a demo product, now create a python module `demoview.py` in the product root directory on the filesystem : :: from kss.core import KSSView from datetime import datetime class DemoView(KSSView): def response1(self, mymessage): # build HTML content = '

    We did it!

    %s at %s

    ' date = str(datetime.now()) content = content % (mymessage, date) # KSS specific calls core = self.getCommandSet('core') core.replaceInnerHTML('#portal-siteactions', content) return self.render() We inherit our view from `KSSView`. It inherits from Five's `BrowserView`. It is maybe time to explain how the `ttwapi` uses those views. - `startKSSCommands` does the instantiation of a `KSSView`. - `getKSSCommandSet` is the call equivalent to `self.getCommandSet`. - `renderKSSCommands` calls `self.render`. To be able to use the method, you need to add the following to your `configure.zcml` file : :: The interface that the view is bound to is one setup by `kss.core` on all portal objects. You could also use directly the interfaces defined by Plone 2.5 directly, however that would not work on Plone 2.1 so we offer a few "wrapper interfaces" like the one in this example. If you still have the `response1` python script from the begin of this tutorial, do not forget to rename it. Now it is time to restart Zope. If everything goes well, the page functions as previously but you can see from the replacement message that the new method is operating on your page. Remember, when you are working with browser views, you must restart Zope each time you want to test the changes made in the view code. PK2i7--kss/core/dtds/xhtml-lat1.ent PK2i7B.##kss/core/dtds/xhtml-special.ent PK2i766kss/core/dtds/xhtml-symbol.ent PK2i7 o}o}%kss/core/dtds/xhtml1-transitional.dtd %HTMLlat1; %HTMLsymbol; %HTMLspecial; PK5i7.kss/core/kukit/tests.batjava -cp ../rhino1_6R2/js.jar org.mozilla.javascript.tools.shell.Main -f tests/ecmaunit.js -f kukit/kukit.Utils.js -f kukit/kukit.Parser.js -f kukit/kukit.BsStringParser.js -f kukit/kukit.BsCommentParser.js -f kukit/kukit.BsMethodParser.js -f kukit/kukit.BsPropertyParser.js -f kukit/kukit.BsParser.js -f tests/kukit.BsParserTestCase.js -f kukit/kukit.BsSelector.js -f tests/runtests.js PK5i7Dkss/core/kukit/version.txt1.2.3 released 2007-11-08 PK4i7n$kss/core/kukit/3rd_party/LICENSE.txt Third party modules come with different licenses, see individual files Firebug Lite is licensed under Mozilla Public License 1.1 PK4i7fy,x,x$kss/core/kukit/3rd_party/MochiKit.js/*** MochiKit.MochiKit 1.2 : PACKED VERSION THIS FILE IS AUTOMATICALLY GENERATED. If creating patches, please diff against the source tree, not this file. See for documentation, downloads, license, etc. (c) 2005 Bob Ippolito. All rights Reserved. ***/ if(typeof (dojo)!="undefined"){ dojo.provide("MochiKit.Base"); } if(typeof (MochiKit)=="undefined"){ MochiKit={}; } if(typeof (MochiKit.Base)=="undefined"){ MochiKit.Base={}; } MochiKit.Base.VERSION="1.2"; MochiKit.Base.NAME="MochiKit.Base"; MochiKit.Base.update=function(_1,_2){ if(_1==null){ _1={}; } for(var i=1;i>b; },zrshift:function(a,b){ return a>>>b; },eq:function(a,b){ return a==b; },ne:function(a,b){ return a!=b; },gt:function(a,b){ return a>b; },ge:function(a,b){ return a>=b; },lt:function(a,b){ return al){ _37=l; } } _36=[]; for(i=0;i<_37;i++){ var _38=[]; for(var j=1;j0){ _51=m.concat(me.im_preargs,_51); } var _46=me.im_self; if(!_46){ _46=this; } return me.im_func.apply(_46,_51); }; _50.im_self=_49; _50.im_func=_47; _50.im_preargs=_48; return _50; },bindMethods:function(_52){ var _53=MochiKit.Base.bind; for(var k in _52){ var _54=_52[k]; if(typeof (_54)=="function"){ _52[k]=_53(_54,_52); } } },registerComparator:function(_55,_56,_57,_58){ MochiKit.Base.comparatorRegistry.register(_55,_56,_57,_58); },_primitives:{"bool":true,"string":true,"number":true},compare:function(a,b){ if(a==b){ return 0; } var _59=(typeof (a)=="undefined"||a==null); var _60=(typeof (b)=="undefined"||b==null); if(_59&&_60){ return 0; }else{ if(_59){ return -1; }else{ if(_60){ return 1; } } } var m=MochiKit.Base; var _61=m._primitives; if(!(typeof (a) in _61&&typeof (b) in _61)){ try{ return m.comparatorRegistry.match(a,b); } catch(e){ if(e!=m.NotFound){ throw e; } } } if(ab){ return 1; } } var _62=m.repr; throw new TypeError(_62(a)+" and "+_62(b)+" can not be compared"); },compareDateLike:function(a,b){ return MochiKit.Base.compare(a.getTime(),b.getTime()); },compareArrayLike:function(a,b){ var _63=MochiKit.Base.compare; var _64=a.length; var _65=0; if(_64>b.length){ _65=1; _64=b.length; }else{ if(_640))){ var kv=MochiKit.DOM.formContents(_108); _108=kv[0]; _109=kv[1]; }else{ if(arguments.length==1){ var o=_108; _108=[]; _109=[]; for(var k in o){ var v=o[k]; if(typeof (v)!="function"){ _108.push(k); _109.push(v); } } } } var rval=[]; var len=Math.min(_108.length,_109.length); var _113=MochiKit.Base.urlEncode; for(var i=0;i=stop){ throw self.StopIteration; } _142+=step; return rval; }}; },imap:function(fun,p,q){ var m=MochiKit.Base; var self=MochiKit.Iter; var _146=m.map(self.iter,m.extend(null,arguments,1)); var map=m.map; var next=self.next; return {repr:function(){ return "imap(...)"; },toString:m.forward("repr"),next:function(){ return fun.apply(this,map(next,_146)); }}; },applymap:function(fun,seq,self){ seq=MochiKit.Iter.iter(seq); var m=MochiKit.Base; return {repr:function(){ return "applymap(...)"; },toString:m.forward("repr"),next:function(){ return fun.apply(self,seq.next()); }}; },chain:function(p,q){ var self=MochiKit.Iter; var m=MochiKit.Base; if(arguments.length==1){ return self.iter(arguments[0]); } var _148=m.map(self.iter,arguments); return {repr:function(){ return "chain(...)"; },toString:m.forward("repr"),next:function(){ while(_148.length>1){ try{ return _148[0].next(); } catch(e){ if(e!=self.StopIteration){ throw e; } _148.shift(); } } if(_148.length==1){ var arg=_148.shift(); this.next=m.bind("next",arg); return this.next(); } throw self.StopIteration; }}; },takewhile:function(pred,seq){ var self=MochiKit.Iter; seq=self.iter(seq); return {repr:function(){ return "takewhile(...)"; },toString:MochiKit.Base.forward("repr"),next:function(){ var rval=seq.next(); if(!pred(rval)){ this.next=function(){ throw self.StopIteration; }; this.next(); } return rval; }}; },dropwhile:function(pred,seq){ seq=MochiKit.Iter.iter(seq); var m=MochiKit.Base; var bind=m.bind; return {"repr":function(){ return "dropwhile(...)"; },"toString":m.forward("repr"),"next":function(){ while(true){ var rval=seq.next(); if(!pred(rval)){ break; } } this.next=bind("next",seq); return rval; }}; },_tee:function(_150,sync,_152){ sync.pos[_150]=-1; var m=MochiKit.Base; var _153=m.listMin; return {repr:function(){ return "tee("+_150+", ...)"; },toString:m.forward("repr"),next:function(){ var rval; var i=sync.pos[_150]; if(i==sync.max){ rval=_152.next(); sync.deque.push(rval); sync.max+=1; sync.pos[_150]+=1; }else{ rval=sync.deque[i-sync.min]; sync.pos[_150]+=1; if(i==sync.min&&_153(sync.pos)!=sync.min){ sync.min+=1; sync.deque.shift(); } } return rval; }}; },tee:function(_154,n){ var rval=[]; var sync={"pos":[],"deque":[],"max":-1,"min":-1}; if(arguments.length==1){ n=2; } var self=MochiKit.Iter; _154=self.iter(_154); var _tee=self._tee; for(var i=0;i0&&_160>=stop)||(step<0&&_160<=stop)){ throw MochiKit.Iter.StopIteration; } var rval=_160; _160+=step; return rval; },repr:function(){ return "range("+[_160,stop,step].join(", ")+")"; },toString:MochiKit.Base.forward("repr")}; },sum:function(_161,_162){ var x=_162||0; var self=MochiKit.Iter; _161=self.iter(_161); try{ while(true){ x+=_161.next(); } } catch(e){ if(e!=self.StopIteration){ throw e; } } return x; },exhaust:function(_163){ var self=MochiKit.Iter; _163=self.iter(_163); try{ while(true){ _163.next(); } } catch(e){ if(e!=self.StopIteration){ throw e; } } },forEach:function(_164,func,self){ var m=MochiKit.Base; if(arguments.length>2){ func=m.bind(func,self); } if(m.isArrayLike(_164)){ try{ for(var i=0;i<_164.length;i++){ func(_164[i]); } } catch(e){ if(e!=MochiKit.Iter.StopIteration){ throw e; } } }else{ self=MochiKit.Iter; self.exhaust(self.imap(func,_164)); } },every:function(_166,func){ var self=MochiKit.Iter; try{ self.ifilterfalse(func,_166).next(); return false; } catch(e){ if(e!=self.StopIteration){ throw e; } return true; } },sorted:function(_167,cmp){ var rval=MochiKit.Iter.list(_167); if(arguments.length==1){ cmp=MochiKit.Base.compare; } rval.sort(cmp); return rval; },reversed:function(_168){ var rval=MochiKit.Iter.list(_168); rval.reverse(); return rval; },some:function(_169,func){ var self=MochiKit.Iter; try{ self.ifilter(func,_169).next(); return true; } catch(e){ if(e!=self.StopIteration){ throw e; } return false; } },iextend:function(lst,_170){ if(MochiKit.Base.isArrayLike(_170)){ for(var i=0;i<_170.length;i++){ lst.push(_170[i]); } }else{ var self=MochiKit.Iter; _170=self.iter(_170); try{ while(true){ lst.push(_170.next()); } } catch(e){ if(e!=self.StopIteration){ throw e; } } } return lst; },groupby:function(_171,_172){ var m=MochiKit.Base; var self=MochiKit.Iter; if(arguments.length<2){ _172=m.operator.identity; } _171=self.iter(_171); var pk=undefined; var k=undefined; var v; function fetch(){ v=_171.next(); k=_172(v); } function eat(){ var ret=v; v=undefined; return ret; } var _175=true; return {repr:function(){ return "groupby(...)"; },next:function(){ while(k==pk){ fetch(); if(_175){ _175=false; break; } } pk=k; return [k,{next:function(){ if(v==undefined){ fetch(); } if(k!=pk){ throw self.StopIteration; } return eat(); }}]; }}; },groupby_as_array:function(_176,_177){ var m=MochiKit.Base; var self=MochiKit.Iter; if(arguments.length<2){ _177=m.operator.identity; } _176=self.iter(_176); var _178=[]; var _179=true; var _180; while(true){ try{ var _181=_176.next(); var key=_177(_181); } catch(e){ if(e==self.StopIteration){ break; } throw e; } if(_179||key!=_180){ var _182=[]; _178.push([key,_182]); } _182.push(_181); _179=false; _180=key; } return _178; },arrayLikeIter:function(_183){ var i=0; return {repr:function(){ return "arrayLikeIter(...)"; },toString:MochiKit.Base.forward("repr"),next:function(){ if(i>=_183.length){ throw MochiKit.Iter.StopIteration; } return _183[i++]; }}; },hasIterateNext:function(_184){ return (_184&&typeof (_184.iterateNext)=="function"); },iterateNextIter:function(_185){ return {repr:function(){ return "iterateNextIter(...)"; },toString:MochiKit.Base.forward("repr"),next:function(){ var rval=_185.iterateNext(); if(rval===null||rval===undefined){ throw MochiKit.Iter.StopIteration; } return rval; }}; }}); MochiKit.Iter.EXPORT_OK=["iteratorRegistry","arrayLikeIter","hasIterateNext","iterateNextIter",]; MochiKit.Iter.EXPORT=["StopIteration","registerIteratorFactory","iter","count","cycle","repeat","next","izip","ifilter","ifilterfalse","islice","imap","applymap","chain","takewhile","dropwhile","tee","list","reduce","range","sum","exhaust","forEach","every","sorted","reversed","some","iextend","groupby","groupby_as_array"]; MochiKit.Iter.__new__=function(){ var m=MochiKit.Base; this.StopIteration=new m.NamedError("StopIteration"); this.iteratorRegistry=new m.AdapterRegistry(); this.registerIteratorFactory("arrayLike",m.isArrayLike,this.arrayLikeIter); this.registerIteratorFactory("iterateNext",this.hasIterateNext,this.iterateNextIter); this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)}; m.nameFunctions(this); }; MochiKit.Iter.__new__(); reduce=MochiKit.Iter.reduce; MochiKit.Base._exportSymbols(this,MochiKit.Iter); if(typeof (dojo)!="undefined"){ dojo.provide("MochiKit.Logging"); dojo.require("MochiKit.Base"); } if(typeof (JSAN)!="undefined"){ JSAN.use("MochiKit.Base",[]); } try{ if(typeof (MochiKit.Base)=="undefined"){ throw ""; } } catch(e){ throw "MochiKit.Logging depends on MochiKit.Base!"; } if(typeof (MochiKit.Logging)=="undefined"){ MochiKit.Logging={}; } MochiKit.Logging.NAME="MochiKit.Logging"; MochiKit.Logging.VERSION="1.2"; MochiKit.Logging.__repr__=function(){ return "["+this.NAME+" "+this.VERSION+"]"; }; MochiKit.Logging.toString=function(){ return this.__repr__(); }; MochiKit.Logging.EXPORT=["LogLevel","LogMessage","Logger","alertListener","logger","log","logError","logDebug","logFatal","logWarning"]; MochiKit.Logging.EXPORT_OK=["logLevelAtLeast","isLogMessage","compareLogMessage"]; MochiKit.Logging.LogMessage=function(num,_187,info){ this.num=num; this.level=_187; this.info=info; this.timestamp=new Date(); }; MochiKit.Logging.LogMessage.prototype={repr:function(){ var m=MochiKit.Base; return "LogMessage("+m.map(m.repr,[this.num,this.level,this.info]).join(", ")+")"; },toString:MochiKit.Base.forward("repr")}; MochiKit.Base.update(MochiKit.Logging,{logLevelAtLeast:function(_189){ var self=MochiKit.Logging; if(typeof (_189)=="string"){ _189=self.LogLevel[_189]; } return function(msg){ var _191=msg.level; if(typeof (_191)=="string"){ _191=self.LogLevel[_191]; } return _191>=_189; }; },isLogMessage:function(){ var _192=MochiKit.Logging.LogMessage; for(var i=0;i=0&&this._messages.length>this.maxSize){ this._messges.shift(); } },getMessages:function(_201){ var _202=0; if(!(typeof (_201)=="undefined"||_201==null)){ _202=Math.max(0,this._messages.length-_201); } return this._messages.slice(_202); },getMessageText:function(_203){ if(typeof (_203)=="undefined"||_203==null){ _203=30; } var _204=this.getMessages(_203); if(_204.length){ var lst=map(function(m){ return "\n ["+m.num+"] "+m.level+": "+m.info.join(" "); },_204); lst.unshift("LAST "+_204.length+" MESSAGES:"); return lst.join(""); } return ""; },debuggingBookmarklet:function(_205){ if(typeof (MochiKit.LoggingPane)=="undefined"){ alert(this.getMessageText()); }else{ MochiKit.LoggingPane.createLoggingPane(_205||false); } }}; MochiKit.Logging.__new__=function(){ this.LogLevel={ERROR:40,FATAL:50,WARNING:30,INFO:20,DEBUG:10}; var m=MochiKit.Base; m.registerComparator("LogMessage",this.isLogMessage,this.compareLogMessage); var _206=m.partial; var _207=this.Logger; var _208=_207.prototype.baseLog; m.update(this.Logger.prototype,{debug:_206(_208,"DEBUG"),log:_206(_208,"INFO"),error:_206(_208,"ERROR"),fatal:_206(_208,"FATAL"),warning:_206(_208,"WARNING")}); var self=this; var _209=function(name){ return function(){ self.logger[name].apply(self.logger,arguments); }; }; this.log=_209("log"); this.logError=_209("error"); this.logDebug=_209("debug"); this.logFatal=_209("fatal"); this.logWarning=_209("warning"); this.logger=new _207(); this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)}; m.nameFunctions(this); }; MochiKit.Logging.__new__(); MochiKit.Base._exportSymbols(this,MochiKit.Logging); if(typeof (dojo)!="undefined"){ dojo.provide("MochiKit.DateTime"); } if(typeof (MochiKit)=="undefined"){ MochiKit={}; } if(typeof (MochiKit.DateTime)=="undefined"){ MochiKit.DateTime={}; } MochiKit.DateTime.NAME="MochiKit.DateTime"; MochiKit.DateTime.VERSION="1.2"; MochiKit.DateTime.__repr__=function(){ return "["+this.NAME+" "+this.VERSION+"]"; }; MochiKit.DateTime.toString=function(){ return this.__repr__(); }; MochiKit.DateTime.isoDate=function(str){ str=str+""; if(typeof (str)!="string"||str.length==0){ return null; } var iso=str.split("-"); if(iso.length==0){ return null; } return new Date(iso[0],iso[1]-1,iso[2]); }; MochiKit.DateTime._isoRegexp=/(\d{4,})(?:-(\d{1,2})(?:-(\d{1,2})(?:[T ](\d{1,2}):(\d{1,2})(?::(\d{1,2})(?:\.(\d+))?)?(?:(Z)|([+-])(\d{1,2})(?::(\d{1,2}))?)?)?)?)?/; MochiKit.DateTime.isoTimestamp=function(str){ str=str+""; if(typeof (str)!="string"||str.length==0){ return null; } var res=str.match(MochiKit.DateTime._isoRegexp); if(typeof (res)=="undefined"||res==null){ return null; } var year,month,day,hour,min,sec,msec; year=parseInt(res[1],10); if(typeof (res[2])=="undefined"||res[2]==""){ return new Date(year); } month=parseInt(res[2],10)-1; day=parseInt(res[3],10); if(typeof (res[4])=="undefined"||res[4]==""){ return new Date(year,month,day); } hour=parseInt(res[4],10); min=parseInt(res[5],10); sec=(typeof (res[6])!="undefined"&&res[6]!="")?parseInt(res[6],10):0; if(typeof (res[7])!="undefined"&&res[7]!=""){ msec=Math.round(1000*parseFloat("0."+res[7])); }else{ msec=0; } if((typeof (res[8])=="undefined"||res[8]=="")&&(typeof (res[9])=="undefined"||res[9]=="")){ return new Date(year,month,day,hour,min,sec,msec); } var ofs; if(typeof (res[9])!="undefined"&&res[9]!=""){ ofs=parseInt(res[10],10)*3600000; if(typeof (res[11])!="undefined"&&res[11]!=""){ ofs+=parseInt(res[11],10)*60000; } if(res[9]=="-"){ ofs=-ofs; } }else{ ofs=0; } return new Date(Date.UTC(year,month,day,hour,min,sec,msec)-ofs); }; MochiKit.DateTime.toISOTime=function(date,_215){ if(typeof (date)=="undefined"||date==null){ return null; } var hh=date.getHours(); var mm=date.getMinutes(); var ss=date.getSeconds(); var lst=[((_215&&(hh<10))?"0"+hh:hh),((mm<10)?"0"+mm:mm),((ss<10)?"0"+ss:ss)]; return lst.join(":"); }; MochiKit.DateTime.toISOTimestamp=function(date,_219){ if(typeof (date)=="undefined"||date==null){ return null; } var sep=_219?"T":" "; var foot=_219?"Z":""; if(_219){ date=new Date(date.getTime()+(date.getTimezoneOffset()*60000)); } return MochiKit.DateTime.toISODate(date)+sep+MochiKit.DateTime.toISOTime(date,_219)+foot; }; MochiKit.DateTime.toISODate=function(date){ if(typeof (date)=="undefined"||date==null){ return null; } var _222=MochiKit.DateTime._padTwo; return [date.getFullYear(),_222(date.getMonth()+1),_222(date.getDate())].join("-"); }; MochiKit.DateTime.americanDate=function(d){ d=d+""; if(typeof (d)!="string"||d.length==0){ return null; } var a=d.split("/"); return new Date(a[2],a[0]-1,a[1]); }; MochiKit.DateTime._padTwo=function(n){ return (n>9)?n:"0"+n; }; MochiKit.DateTime.toPaddedAmericanDate=function(d){ if(typeof (d)=="undefined"||d==null){ return null; } var _224=MochiKit.DateTime._padTwo; return [_224(d.getMonth()+1),_224(d.getDate()),d.getFullYear()].join("/"); }; MochiKit.DateTime.toAmericanDate=function(d){ if(typeof (d)=="undefined"||d==null){ return null; } return [d.getMonth()+1,d.getDate(),d.getFullYear()].join("/"); }; MochiKit.DateTime.EXPORT=["isoDate","isoTimestamp","toISOTime","toISOTimestamp","toISODate","americanDate","toPaddedAmericanDate","toAmericanDate"]; MochiKit.DateTime.EXPORT_OK=[]; MochiKit.DateTime.EXPORT_TAGS={":common":MochiKit.DateTime.EXPORT,":all":MochiKit.DateTime.EXPORT}; MochiKit.DateTime.__new__=function(){ var base=this.NAME+"."; for(var k in this){ var o=this[k]; if(typeof (o)=="function"&&typeof (o.NAME)=="undefined"){ try{ o.NAME=base+k; } catch(e){ } } } }; MochiKit.DateTime.__new__(); if(typeof (MochiKit.Base)!="undefined"){ MochiKit.Base._exportSymbols(this,MochiKit.DateTime); }else{ (function(_225,_226){ if((typeof (JSAN)=="undefined"&&typeof (dojo)=="undefined")||(typeof (MochiKit.__compat__)=="boolean"&&MochiKit.__compat__)){ var all=_226.EXPORT_TAGS[":all"]; for(var i=0;i_234){ var i=_240.length-_234; res=fmt.separator+_240.substring(i,_240.length)+res; _240=_240.substring(0,i); } } res=_240+res; if(_232>0){ while(frac.length<_235){ frac=frac+"0"; } res=res+fmt.decimal+frac; } return _236+res+_237; }; }; MochiKit.Format.numberFormatter=function(_242,_243,_244){ if(typeof (_243)=="undefined"){ _243=""; } var _245=_242.match(/((?:[0#]+,)?[0#]+)(?:\.([0#]+))?(%)?/); if(!_245){ throw TypeError("Invalid pattern"); } var _246=_242.substr(0,_245.index); var _247=_242.substr(_245.index+_245[0].length); if(_246.search(/-/)==-1){ _246=_246+"-"; } var _248=_245[1]; var frac=(typeof (_245[2])=="string"&&_245[2]!="")?_245[2]:""; var _249=(typeof (_245[3])=="string"&&_245[3]!=""); var tmp=_248.split(/,/); var _251; if(typeof (_244)=="undefined"){ _244="default"; } if(tmp.length==1){ _251=null; }else{ _251=tmp[1].length; } var _252=_248.length-_248.replace(/0/g,"").length; var _253=frac.length-frac.replace(/0/g,"").length; var _254=frac.length; var rval=MochiKit.Format._numberFormatter(_243,_246,_247,_244,_249,_254,_252,_251,_253); var m=MochiKit.Base; if(m){ var fn=arguments.callee; var args=m.concat(arguments); rval.repr=function(){ return [self.NAME,"(",map(m.repr,args).join(", "),")"].join(""); }; } return rval; }; MochiKit.Format.formatLocale=function(_256){ if(typeof (_256)=="undefined"||_256==null){ _256="default"; } if(typeof (_256)=="string"){ var rval=MochiKit.Format.LOCALE[_256]; if(typeof (rval)=="string"){ rval=arguments.callee(rval); MochiKit.Format.LOCALE[_256]=rval; } return rval; }else{ return _256; } }; MochiKit.Format.twoDigitAverage=function(_257,_258){ if(_258){ var res=_257/_258; if(!isNaN(res)){ return MochiKit.Format.twoDigitFloat(_257/_258); } } return "0"; }; MochiKit.Format.twoDigitFloat=function(_259){ var sign=(_259<0?"-":""); var s=Math.floor(Math.abs(_259)*100).toString(); if(s=="0"){ return s; } if(s.length<3){ while(s.charAt(s.length-1)=="0"){ s=s.substring(0,s.length-1); } return sign+"0."+s; } var head=sign+s.substring(0,s.length-2); var tail=s.substring(s.length-2,s.length); if(tail=="00"){ return head; }else{ if(tail.charAt(1)=="0"){ return head+"."+tail.charAt(0); }else{ return head+"."+tail; } } }; MochiKit.Format.lstrip=function(str,_264){ str=str+""; if(typeof (str)!="string"){ return null; } if(!_264){ return str.replace(/^\s+/,""); }else{ return str.replace(new RegExp("^["+_264+"]+"),""); } }; MochiKit.Format.rstrip=function(str,_265){ str=str+""; if(typeof (str)!="string"){ return null; } if(!_265){ return str.replace(/\s+$/,""); }else{ return str.replace(new RegExp("["+_265+"]+$"),""); } }; MochiKit.Format.strip=function(str,_266){ var self=MochiKit.Format; return self.rstrip(self.lstrip(str,_266),_266); }; MochiKit.Format.truncToFixed=function(_267,_268){ _267=Math.floor(_267*Math.pow(10,_268)); var res=(_267*Math.pow(10,-_268)).toFixed(_268); if(res.charAt(0)=="."){ res="0"+res; } return res; }; MochiKit.Format.roundToFixed=function(_269,_270){ return MochiKit.Format.truncToFixed(_269+0.5*Math.pow(10,-_270),_270); }; MochiKit.Format.percentFormat=function(_271){ return MochiKit.Format.twoDigitFloat(100*_271)+"%"; }; MochiKit.Format.EXPORT=["truncToFixed","roundToFixed","numberFormatter","formatLocale","twoDigitAverage","twoDigitFloat","percentFormat","lstrip","rstrip","strip"]; MochiKit.Format.LOCALE={en_US:{separator:",",decimal:".",percent:"%"},de_DE:{separator:".",decimal:",",percent:"%"},fr_FR:{separator:" ",decimal:",",percent:"%"},"default":"en_US"}; MochiKit.Format.EXPORT_OK=[]; MochiKit.Format.EXPORT_TAGS={":all":MochiKit.Format.EXPORT,":common":MochiKit.Format.EXPORT}; MochiKit.Format.__new__=function(){ var base=this.NAME+"."; var k,v,o; for(k in this.LOCALE){ o=this.LOCALE[k]; if(typeof (o)=="object"){ o.repr=function(){ return this.NAME; }; o.NAME=base+"LOCALE."+k; } } for(k in this){ o=this[k]; if(typeof (o)=="function"&&typeof (o.NAME)=="undefined"){ try{ o.NAME=base+k; } catch(e){ } } } }; MochiKit.Format.__new__(); if(typeof (MochiKit.Base)!="undefined"){ MochiKit.Base._exportSymbols(this,MochiKit.Format); }else{ (function(_272,_273){ if((typeof (JSAN)=="undefined"&&typeof (dojo)=="undefined")||(typeof (MochiKit.__compat__)=="boolean"&&MochiKit.__compat__)){ var all=_273.EXPORT_TAGS[":all"]; for(var i=0;i=0)){ this._fire(); } },_continue:function(res){ this._resback(res); this._unpause(); },_resback:function(res){ this.fired=((res instanceof Error)?1:0); this.results[this.fired]=res; this._fire(); },_check:function(){ if(this.fired!=-1){ if(!this.silentlyCancelled){ throw new MochiKit.Async.AlreadyCalledError(this); } this.silentlyCancelled=false; return; } },callback:function(res){ this._check(); this._resback(res); },errback:function(res){ this._check(); if(!(res instanceof Error)){ res=new MochiKit.Async.GenericError(res); } this._resback(res); },addBoth:function(fn){ if(arguments.length>1){ fn=MochiKit.Base.partial.apply(null,arguments); } return this.addCallbacks(fn,fn); },addCallback:function(fn){ if(arguments.length>1){ fn=MochiKit.Base.partial.apply(null,arguments); } return this.addCallbacks(fn,null); },addErrback:function(fn){ if(arguments.length>1){ fn=MochiKit.Base.partial.apply(null,arguments); } return this.addCallbacks(null,fn); },addCallbacks:function(cb,eb){ this.chain.push([cb,eb]); if(this.fired>=0){ this._fire(); } return this; },_fire:function(){ var _278=this.chain; var _279=this.fired; var res=this.results[_279]; var self=this; var cb=null; while(_278.length>0&&this.paused==0){ var pair=_278.shift(); var f=pair[_279]; if(f==null){ continue; } try{ res=f(res); _279=((res instanceof Error)?1:0); if(res instanceof MochiKit.Async.Deferred){ cb=function(res){ self._continue(res); }; this._pause(); } } catch(err){ _279=1; res=err; } } this.fired=_279; this.results[_279]=res; if(cb&&this.paused){ res.addBoth(cb); } }}; MochiKit.Base.update(MochiKit.Async,{evalJSONRequest:function(){ return eval("("+arguments[0].responseText+")"); },succeed:function(_281){ var d=new MochiKit.Async.Deferred(); d.callback.apply(d,arguments); return d; },fail:function(_282){ var d=new MochiKit.Async.Deferred(); d.errback.apply(d,arguments); return d; },getXMLHttpRequest:function(){ var self=arguments.callee; if(!self.XMLHttpRequest){ var _283=[function(){ return new XMLHttpRequest(); },function(){ return new ActiveXObject("Msxml2.XMLHTTP"); },function(){ return new ActiveXObject("Microsoft.XMLHTTP"); },function(){ return new ActiveXObject("Msxml2.XMLHTTP.4.0"); },function(){ throw new MochiKit.Async.BrowserComplianceError("Browser does not support XMLHttpRequest"); }]; for(var i=0;i<_283.length;i++){ var func=_283[i]; try{ self.XMLHttpRequest=func; return func(); } catch(e){ } } } return self.XMLHttpRequest(); },sendXMLHttpRequest:function(req,_285){ if(typeof (_285)=="undefined"){ _285=null; } var _286=function(){ try{ req.onreadystatechange=null; } catch(e){ try{ req.onreadystatechange=function(){ }; } catch(e){ } } req.abort(); }; var self=MochiKit.Async; var d=new self.Deferred(_286); var _287=function(){ if(req.readyState==4){ try{ req.onreadystatechange=null; } catch(e){ try{ req.onreadystatechange=function(){ }; } catch(e){ } } var _288=null; try{ _288=req.status; if(!_288&&MochiKit.Base.isNotEmpty(req.responseText)){ _288=304; } } catch(e){ } if(_288==200||_288==304){ d.callback(req); }else{ var err=new self.XMLHttpRequestError(req,"Request failed"); if(err.number){ d.errback(err); }else{ d.errback(err); } } } }; try{ req.onreadystatechange=_287; req.send(_285); } catch(e){ try{ req.onreadystatechange=null; } catch(ignore){ } d.errback(e); } return d; },doSimpleXMLHttpRequest:function(url){ var self=MochiKit.Async; var req=self.getXMLHttpRequest(); if(arguments.length>1){ var m=MochiKit.Base; var qs=m.queryString.apply(null,m.extend(null,arguments,1)); if(qs){ url+="?"+qs; } } req.open("GET",url,true); return self.sendXMLHttpRequest(req); },loadJSONDoc:function(url){ var self=MochiKit.Async; var d=self.doSimpleXMLHttpRequest.apply(self,arguments); d=d.addCallback(self.evalJSONRequest); return d; },wait:function(_292,_293){ var d=new MochiKit.Async.Deferred(); var m=MochiKit.Base; if(typeof (_293)!="undefined"){ d.addCallback(function(){ return _293; }); } var _294=setTimeout(m.bind("callback",d),Math.floor(_292*1000)); d.canceller=function(){ try{ clearTimeout(_294); } catch(e){ } }; return d; },callLater:function(_295,func){ var m=MochiKit.Base; var _296=m.partial.apply(m,m.extend(null,arguments,1)); return MochiKit.Async.wait(_295).addCallback(function(res){ return _296(); }); }}); MochiKit.Async.DeferredLock=function(){ this.waiting=[]; this.locked=false; this.id=this._nextId(); }; MochiKit.Async.DeferredLock.prototype={__class__:MochiKit.Async.DeferredLock,acquire:function(){ d=new MochiKit.Async.Deferred(); if(this.locked){ this.waiting.push(d); }else{ this.locked=true; d.callback(this); } return d; },release:function(){ if(!this.locked){ throw TypeError("Tried to release an unlocked DeferredLock"); } this.locked=false; if(this.waiting.length>0){ this.locked=true; this.waiting.shift().callback(this); } },_nextId:MochiKit.Base.counter(),repr:function(){ var _297; if(this.locked){ _297="locked, "+this.waiting.length+" waiting"; }else{ _297="unlocked"; } return "DeferredLock("+this.id+", "+_297+")"; },toString:MochiKit.Base.forward("repr")}; MochiKit.Async.EXPORT=["AlreadyCalledError","CancelledError","BrowserComplianceError","GenericError","XMLHttpRequestError","Deferred","succeed","fail","getXMLHttpRequest","doSimpleXMLHttpRequest","loadJSONDoc","wait","callLater","sendXMLHttpRequest","DeferredLock"]; MochiKit.Async.EXPORT_OK=["evalJSONRequest"]; MochiKit.Async.__new__=function(){ var m=MochiKit.Base; var ne=m.partial(m._newNamedError,this); ne("AlreadyCalledError",function(_299){ this.deferred=_299; }); ne("CancelledError",function(_300){ this.deferred=_300; }); ne("BrowserComplianceError",function(msg){ this.message=msg; }); ne("GenericError",function(msg){ this.message=msg; }); ne("XMLHttpRequestError",function(req,msg){ this.req=req; this.message=msg; try{ this.number=req.status; } catch(e){ } }); this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)}; m.nameFunctions(this); }; MochiKit.Async.__new__(); MochiKit.Base._exportSymbols(this,MochiKit.Async); if(typeof (dojo)!="undefined"){ dojo.provide("MochiKit.DOM"); dojo.require("MochiKit.Iter"); } if(typeof (JSAN)!="undefined"){ JSAN.use("MochiKit.Iter",[]); } try{ if(typeof (MochiKit.Iter)=="undefined"){ throw ""; } } catch(e){ throw "MochiKit.DOM depends on MochiKit.Iter!"; } if(typeof (MochiKit.DOM)=="undefined"){ MochiKit.DOM={}; } MochiKit.DOM.NAME="MochiKit.DOM"; MochiKit.DOM.VERSION="1.2"; MochiKit.DOM.__repr__=function(){ return "["+this.NAME+" "+this.VERSION+"]"; }; MochiKit.DOM.toString=function(){ return this.__repr__(); }; MochiKit.DOM.EXPORT=["elementDimensions","formContents","currentWindow","currentDocument","withWindow","withDocument","registerDOMConverter","coerceToDOM","createDOM","createDOMFunc","getNodeAttribute","setNodeAttribute","updateNodeAttributes","appendChildNodes","replaceChildNodes","removeElement","swapDOM","BUTTON","TT","PRE","H1","H2","H3","BR","CANVAS","HR","LABEL","TEXTAREA","FORM","STRONG","SELECT","OPTION","OPTGROUP","LEGEND","FIELDSET","P","UL","OL","LI","TD","TR","THEAD","TBODY","TFOOT","TABLE","TH","INPUT","SPAN","A","DIV","IMG","getElement","$","computedStyle","getElementsByTagAndClassName","addToCallStack","addLoadEvent","focusOnLoad","setElementClass","toggleElementClass","addElementClass","removeElementClass","swapElementClass","hasElementClass","escapeHTML","toHTML","emitHTML","setDisplayForElement","hideElement","showElement","scrapeText","elementPosition"]; MochiKit.DOM.EXPORT_OK=["domConverters"]; MochiKit.DOM.Dimensions=function(w,h){ this.w=w; this.h=h; }; MochiKit.DOM.Dimensions.prototype.repr=function(){ var repr=MochiKit.Base.repr; return "{w: "+repr(this.w)+", h: "+repr(this.h)+"}"; }; MochiKit.DOM.Coordinates=function(x,y){ this.x=x; this.y=y; }; MochiKit.DOM.Coordinates.prototype.repr=function(){ var repr=MochiKit.Base.repr; return "{x: "+repr(this.x)+", y: "+repr(this.y)+"}"; }; MochiKit.DOM.elementDimensions=function(elem){ var self=MochiKit.DOM; if(typeof (elem.w)=="number"||typeof (elem.h)=="number"){ return new self.Dimensions(elem.w||0,elem.h||0); } elem=self.getElement(elem); if(!elem){ return undefined; } if(self.computedStyle(elem,"display")!="none"){ return new self.Dimensions(elem.w||0,elem.h||0); } var s=elem.style; var _305=s.visibility; var _306=s.position; s.visibility="hidden"; s.position="absolute"; s.display=""; var _307=elem.clientWidth; var _308=elem.clientHeight; s.display="none"; s.position=_306; s.visibility=_305; return new self.Dimensions(_307,_308); }; MochiKit.DOM.elementPosition=function(elem,_309){ var self=MochiKit.DOM; elem=self.getElement(elem); if(!elem){ return undefined; } var x=0; var y=0; if(elem.offsetParent){ while(elem.offsetParent){ x+=elem.offsetLeft; y+=elem.offsetTop; elem=elem.offsetParent; } }else{ x=elem.x||x; y=elem.y||y; } if(_309){ _309=arguments.callee(_309); if(_309){ x-=(_309.x||0); y-=(_309.y||0); } } return new self.Coordinates(x,y); }; MochiKit.DOM.currentWindow=function(){ return MochiKit.DOM._window; }; MochiKit.DOM.currentDocument=function(){ return MochiKit.DOM._document; }; MochiKit.DOM.withWindow=function(win,func){ var self=MochiKit.DOM; var _311=self._document; var _312=self._win; var rval; try{ self._window=win; self._document=win.document; rval=func(); } catch(e){ self._window=_312; self._document=_311; throw e; } self._window=_312; self._document=_311; return rval; }; MochiKit.DOM.formContents=function(elem){ var _313=[]; var _314=[]; var m=MochiKit.Base; var self=MochiKit.DOM; if(typeof (elem)=="undefined"||elem==null){ elem=self._document; }else{ elem=self.getElement(elem); } m.nodeWalk(elem,function(elem){ var name=elem.name; if(m.isNotEmpty(name)){ if(elem.tagName=="INPUT"&&(elem.type=="radio"||elem.type=="checkbox")&&!elem.checked){ return null; } if(elem.tagName=="SELECT"){ var opts=elem.options; for(var i=0;i0){ return node; } if(typeof (node)=="number"||typeof (node)=="bool"){ node=node.toString(); } if(typeof (node)=="string"){ return self._document.createTextNode(node); } if(typeof (node.toDOM)=="function"){ node=node.toDOM(ctx); continue; } if(typeof (node)=="function"){ node=node(ctx); continue; } var _329=null; try{ _329=iter(node); } catch(e){ } if(_329){ return imap(_327,_329,_324(ctx)); } try{ node=_326.match(node,ctx); continue; } catch(e){ if(e!=_328){ throw e; } } return self._document.createTextNode(node.toString()); } return undefined; }; MochiKit.DOM.setNodeAttribute=function(node,attr,_331){ var o={}; o[attr]=_331; try{ return MochiKit.DOM.updateNodeAttributes(node,o); } catch(e){ } return null; }; MochiKit.DOM.getNodeAttribute=function(node,attr){ var self=MochiKit.DOM; var _332=self.attributeArray.renames[attr]; node=self.getElement(node); try{ if(_332){ return node[_332]; } return node.getAttribute(attr); } catch(e){ } return null; }; MochiKit.DOM.updateNodeAttributes=function(node,_333){ var elem=node; var self=MochiKit.DOM; if(typeof (node)=="string"){ elem=self.getElement(node); } if(_333){ var _334=MochiKit.Base.updatetree; if(self.attributeArray.compliant){ for(var k in _333){ var v=_333[k]; if(typeof (v)=="object"&&typeof (elem[k])=="object"){ _334(elem[k],v); }else{ if(k.substring(0,2)=="on"){ if(typeof (v)=="string"){ v=new Function(v); } elem[k]=v; }else{ elem.setAttribute(k,v); } } } }else{ var _335=self.attributeArray.renames; for(k in _333){ v=_333[k]; var _336=_335[k]; if(k=="style"&&typeof (v)=="string"){ elem.style.cssText=v; }else{ if(typeof (_336)=="string"){ elem[_336]=v; }else{ if(typeof (elem[k])=="object"&&typeof (v)=="object"){ _334(elem[k],v); }else{ if(k.substring(0,2)=="on"){ if(typeof (v)=="string"){ v=new Function(v); } elem[k]=v; }else{ elem.setAttribute(k,v); } } } } } } } return elem; }; MochiKit.DOM.appendChildNodes=function(node){ var elem=node; var self=MochiKit.DOM; if(typeof (node)=="string"){ elem=self.getElement(node); } var _337=[self.coerceToDOM(MochiKit.Base.extend(null,arguments,1),elem)]; var _338=MochiKit.Iter.iextend; while(_337.length){ var n=_337.shift(); if(typeof (n)=="undefined"||n==null){ }else{ if(typeof (n.nodeType)=="number"){ elem.appendChild(n); }else{ _338(_337,n); } } } return elem; }; MochiKit.DOM.replaceChildNodes=function(node){ var elem=node; var self=MochiKit.DOM; if(typeof (node)=="string"){ elem=self.getElement(node); arguments[0]=elem; } var _339; while((_339=elem.firstChild)){ elem.removeChild(_339); } if(arguments.length<2){ return elem; }else{ return self.appendChildNodes.apply(this,arguments); } }; MochiKit.DOM.createDOM=function(name,_340){ var elem; var self=MochiKit.DOM; if(typeof (name)=="string"){ if(_340&&"name" in _340&&!self.attributeArray.compliant){ name="<"+name+" name=\""+self.escapeHTML(_340.name)+"\">"; } elem=self._document.createElement(name); }else{ elem=name; } if(_340){ self.updateNodeAttributes(elem,_340); } if(arguments.length<=2){ return elem; }else{ var args=MochiKit.Base.extend([elem],arguments,2); return self.appendChildNodes.apply(this,args); } }; MochiKit.DOM.createDOMFunc=function(){ var m=MochiKit.Base; return m.partial.apply(this,m.extend([MochiKit.DOM.createDOM],arguments)); }; MochiKit.DOM.swapDOM=function(dest,src){ var self=MochiKit.DOM; dest=self.getElement(dest); var _343=dest.parentNode; if(src){ src=self.getElement(src); _343.replaceChild(src,dest); }else{ _343.removeChild(dest); } return src; }; MochiKit.DOM.getElement=function(id){ var self=MochiKit.DOM; if(arguments.length==1){ return ((typeof (id)=="string")?self._document.getElementById(id):id); }else{ return MochiKit.Base.map(self.getElement,arguments); } }; MochiKit.DOM.computedStyle=function(_345,_346,_347){ if(arguments.length==2){ _347=_346; } var self=MochiKit.DOM; var el=self.getElement(_345); var _349=self._document; if(!el||el==_349){ return undefined; } if(el.currentStyle){ return el.currentStyle[_346]; } if(typeof (_349.defaultView)=="undefined"){ return undefined; } if(_349.defaultView==null){ return undefined; } var _350=_349.defaultView.getComputedStyle(el,null); if(typeof (_350)=="undefined"||_350==null){ return undefined; } return _350.getPropertyValue(_347); }; MochiKit.DOM.getElementsByTagAndClassName=function(_351,_352,_353){ var self=MochiKit.DOM; if(typeof (_351)=="undefined"||_351==null){ _351="*"; } if(typeof (_353)=="undefined"||_353==null){ _353=self._document; } _353=self.getElement(_353); var _354=_353.getElementsByTagName(_351)||self._document.all; if(typeof (_352)=="undefined"||_352==null){ return MochiKit.Base.extend(null,_354); } var _355=[]; for(var i=0;i<_354.length;i++){ var _356=_354[i]; var _357=_356.className.split(" "); for(var j=0;j<_357.length;j++){ if(_357[j]==_352){ _355.push(_356); break; } } } return _355; }; MochiKit.DOM._newCallStack=function(path,once){ var rval=function(){ var _360=arguments.callee.callStack; for(var i=0;i<_360.length;i++){ if(_360[i].apply(this,arguments)===false){ break; } } if(once){ try{ this[path]=null; } catch(e){ } } }; rval.callStack=[]; return rval; }; MochiKit.DOM.addToCallStack=function(_361,path,func,once){ var self=MochiKit.DOM; var _362=_361[path]; var _363=_362; if(!(typeof (_362)=="function"&&typeof (_362.callStack)=="object"&&_362.callStack!=null)){ _363=self._newCallStack(path,once); if(typeof (_362)=="function"){ _363.callStack.push(_362); } _361[path]=_363; } _363.callStack.push(func); }; MochiKit.DOM.addLoadEvent=function(func){ var self=MochiKit.DOM; self.addToCallStack(self._window,"onload",func,true); }; MochiKit.DOM.focusOnLoad=function(_364){ var self=MochiKit.DOM; self.addLoadEvent(function(){ _364=self.getElement(_364); if(_364){ _364.focus(); } }); }; MochiKit.DOM.setElementClass=function(_365,_366){ var self=MochiKit.DOM; var obj=self.getElement(_365); if(self.attributeArray.compliant){ obj.setAttribute("class",_366); }else{ obj.setAttribute("className",_366); } }; MochiKit.DOM.toggleElementClass=function(_367){ var self=MochiKit.DOM; for(var i=1;i/g,">"); }; MochiKit.DOM.toHTML=function(dom){ return MochiKit.DOM.emitHTML(dom).join(""); }; MochiKit.DOM.emitHTML=function(dom,lst){ if(typeof (lst)=="undefined"||lst==null){ lst=[]; } var _383=[dom]; var self=MochiKit.DOM; var _384=self.escapeHTML; var _385=self.attributeArray; while(_383.length){ dom=_383.pop(); if(typeof (dom)=="string"){ lst.push(dom); }else{ if(dom.nodeType==1){ lst.push("<"+dom.nodeName.toLowerCase()); var _386=[]; var _387=_385(dom); for(var i=0;i<_387.length;i++){ var a=_387[i]; _386.push([" ",a.name,"=\"",_384(a.value),"\""]); } _386.sort(); for(i=0;i<_386.length;i++){ var _388=_386[i]; for(var j=0;j<_388.length;j++){ lst.push(_388[j]); } } if(dom.hasChildNodes()){ lst.push(">"); _383.push(""); var _389=dom.childNodes; for(i=_389.length-1;i>=0;i--){ _383.push(_389[i]); } }else{ lst.push("/>"); } }else{ if(dom.nodeType==3){ lst.push(_384(dom.nodeValue)); } } } } return lst; }; MochiKit.DOM.setDisplayForElement=function(_390,_391){ var m=MochiKit.Base; var _392=m.extend(null,arguments,1); MochiKit.Iter.forEach(m.filter(null,m.map(MochiKit.DOM.getElement,_392)),function(_391){ _391.style.display=_390; }); }; MochiKit.DOM.scrapeText=function(node,_393){ var rval=[]; (function(node){ var cn=node.childNodes; if(cn){ for(var i=0;i0){ var _398=m.filter; _397=function(node){ return _398(_397.ignoreAttrFilter,node.attributes); }; _397.ignoreAttr={}; MochiKit.Iter.forEach(_396.attributes,function(a){ _397.ignoreAttr[a.name]=a.value; }); _397.ignoreAttrFilter=function(a){ return (_397.ignoreAttr[a.name]!=a.value); }; _397.compliant=false; _397.renames={"class":"className","checked":"defaultChecked","usemap":"useMap","for":"htmlFor"}; }else{ _397=function(node){ return node.attributes; }; _397.compliant=true; _397.renames={}; } this.attributeArray=_397; var _399=this.createDOMFunc; this.UL=_399("ul"); this.OL=_399("ol"); this.LI=_399("li"); this.TD=_399("td"); this.TR=_399("tr"); this.TBODY=_399("tbody"); this.THEAD=_399("thead"); this.TFOOT=_399("tfoot"); this.TABLE=_399("table"); this.TH=_399("th"); this.INPUT=_399("input"); this.SPAN=_399("span"); this.A=_399("a"); this.DIV=_399("div"); this.IMG=_399("img"); this.BUTTON=_399("button"); this.TT=_399("tt"); this.PRE=_399("pre"); this.H1=_399("h1"); this.H2=_399("h2"); this.H3=_399("h3"); this.BR=_399("br"); this.HR=_399("hr"); this.LABEL=_399("label"); this.TEXTAREA=_399("textarea"); this.FORM=_399("form"); this.P=_399("p"); this.SELECT=_399("select"); this.OPTION=_399("option"); this.OPTGROUP=_399("optgroup"); this.LEGEND=_399("legend"); this.FIELDSET=_399("fieldset"); this.STRONG=_399("strong"); this.CANVAS=_399("canvas"); this.hideElement=m.partial(this.setDisplayForElement,"none"); this.showElement=m.partial(this.setDisplayForElement,"block"); this.removeElement=this.swapDOM; this.$=this.getElement; this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)}; m.nameFunctions(this); }; MochiKit.DOM.__new__(this); withWindow=MochiKit.DOM.withWindow; withDocument=MochiKit.DOM.withDocument; MochiKit.Base._exportSymbols(this,MochiKit.DOM); if(typeof (dojo)!="undefined"){ dojo.provide("MochiKit.LoggingPane"); dojo.require("MochiKit.Logging"); dojo.require("MochiKit.Base"); } if(typeof (JSAN)!="undefined"){ JSAN.use("MochiKit.Logging",[]); JSAN.use("MochiKit.Base",[]); } try{ if(typeof (MochiKit.Base)=="undefined"||typeof (MochiKit.Logging)=="undefined"){ throw ""; } } catch(e){ throw "MochiKit.LoggingPane depends on MochiKit.Base and MochiKit.Logging!"; } if(typeof (MochiKit.LoggingPane)=="undefined"){ MochiKit.LoggingPane={}; } MochiKit.LoggingPane.NAME="MochiKit.LoggingPane"; MochiKit.LoggingPane.VERSION="1.2"; MochiKit.LoggingPane.__repr__=function(){ return "["+this.NAME+" "+this.VERSION+"]"; }; MochiKit.LoggingPane.toString=function(){ return this.__repr__(); }; MochiKit.LoggingPane.createLoggingPane=function(_400){ var m=MochiKit.LoggingPane; _400=!(!_400); if(m._loggingPane&&m._loggingPane.inline!=_400){ m._loggingPane.closePane(); m._loggingPane=null; } if(!m._loggingPane||m._loggingPane.closed){ m._loggingPane=new m.LoggingPane(_400,MochiKit.Logging.logger); } return m._loggingPane; }; MochiKit.LoggingPane.LoggingPane=function(_401,_402){ if(typeof (_402)=="undefined"||_402==null){ _402=MochiKit.Logging.logger; } this.logger=_402; var _403=MochiKit.Base.update; var _404=MochiKit.Base.updatetree; var bind=MochiKit.Base.bind; var _405=MochiKit.Base.clone; var win=window; var uid="_MochiKit_LoggingPane"; if(typeof (MochiKit.DOM)!="undefined"){ win=MochiKit.DOM.currentWindow(); } if(!_401){ var url=win.location.href.split("?")[0].replace(/[:\/.><&]/g,"_"); var name=uid+"_"+url; var nwin=win.open("",name,"dependent,resizable,height=200"); if(!nwin){ alert("Not able to open debugging window due to pop-up blocking."); return undefined; } nwin.document.write(""+"[MochiKit.LoggingPane]"+""); nwin.document.close(); nwin.document.title+=" "+win.document.title; win=nwin; } var doc=win.document; this.doc=doc; var _408=doc.getElementById(uid); var _409=!!_408; if(_408&&typeof (_408.loggingPane)!="undefined"){ _408.loggingPane.logger=this.logger; _408.loggingPane.buildAndApplyFilter(); return _408.loggingPane; } if(_409){ var _410; while((_410=_408.firstChild)){ _408.removeChild(_410); } }else{ _408=doc.createElement("div"); _408.id=uid; } _408.loggingPane=this; var _411=doc.createElement("input"); var _412=doc.createElement("input"); var _413=doc.createElement("button"); var _414=doc.createElement("button"); var _415=doc.createElement("button"); var _416=doc.createElement("button"); var _417=doc.createElement("div"); var _418=doc.createElement("div"); var _419=uid+"_Listener"; this.colorTable=_405(this.colorTable); var _420=[]; var _421=null; var _422=function(msg){ var _423=msg.level; if(typeof (_423)=="number"){ _423=MochiKit.Logging.LogLevel[_423]; } return _423; }; var _424=function(msg){ return msg.info.join(" "); }; var _425=bind(function(msg){ var _426=_422(msg); var text=_424(msg); var c=this.colorTable[_426]; var p=doc.createElement("span"); p.className="MochiKit-LogMessage MochiKit-LogLevel-"+_426; p.style.cssText="margin: 0px; white-space: -moz-pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; white-space: pre-line; word-wrap: break-word; wrap-option: emergency; color: "+c; p.appendChild(doc.createTextNode(_426+": "+text)); _418.appendChild(p); _418.appendChild(doc.createElement("br")); if(_417.offsetHeight>_417.scrollHeight){ _417.scrollTop=0; }else{ _417.scrollTop=_417.scrollHeight; } },this); var _429=function(msg){ _420[_420.length]=msg; _425(msg); }; var _430=function(){ var _431,infore; try{ _431=new RegExp(_411.value); infore=new RegExp(_412.value); } catch(e){ logDebug("Error in filter regex: "+e.message); return null; } return function(msg){ return (_431.test(_422(msg))&&infore.test(_424(msg))); }; }; var _432=function(){ while(_418.firstChild){ _418.removeChild(_418.firstChild); } }; var _433=function(){ _420=[]; _432(); }; var _434=bind(function(){ if(this.closed){ return; } this.closed=true; if(MochiKit.LoggingPane._loggingPane==this){ MochiKit.LoggingPane._loggingPane=null; } this.logger.removeListener(_419); _408.loggingPane=null; if(_401){ _408.parentNode.removeChild(_408); }else{ this.win.close(); } },this); var _435=function(){ _432(); for(var i=0;i<_420.length;i++){ var msg=_420[i]; if(_421==null||_421(msg)){ _425(msg); } } }; this.buildAndApplyFilter=function(){ _421=_430(); _435(); this.logger.removeListener(_419); this.logger.addListener(_419,_421,_429); }; var _436=bind(function(){ _420=this.logger.getMessages(); _435(); },this); var _437=bind(function(_438){ _438=_438||window.event; key=_438.which||_438.keyCode; if(key==13){ this.buildAndApplyFilter(); } },this); var _439="display: block; left: 0px; bottom: 0px; position: fixed; width: 100%; background-color: white; font: "+this.logFont; if(_401){ _439+="; height: 10em; border-top: 2px solid black"; }else{ _439+="; height: 100%;"; } _408.style.cssText=_439; if(!_409){ doc.body.appendChild(_408); } _439={"cssText":"width: 33%; display: inline; font: "+this.logFont}; _404(_411,{"value":"FATAL|ERROR|WARNING|INFO|DEBUG","onkeypress":_437,"style":_439}); _408.appendChild(_411); _404(_412,{"value":".*","onkeypress":_437,"style":_439}); _408.appendChild(_412); _439="width: 8%; display:inline; font: "+this.logFont; _413.appendChild(doc.createTextNode("Filter")); _413.onclick=bind("buildAndApplyFilter",this); _413.style.cssText=_439; _408.appendChild(_413); _414.appendChild(doc.createTextNode("Load")); _414.onclick=_436; _414.style.cssText=_439; _408.appendChild(_414); _415.appendChild(doc.createTextNode("Clear")); _415.onclick=_433; _415.style.cssText=_439; _408.appendChild(_415); _416.appendChild(doc.createTextNode("Close")); _416.onclick=_434; _416.style.cssText=_439; _408.appendChild(_416); _417.style.cssText="overflow: auto; width: 100%"; _418.style.cssText="width: 100%; height: "+(_401?"8em":"100%"); _417.appendChild(_418); _408.appendChild(_417); this.buildAndApplyFilter(); _436(); if(_401){ this.win=undefined; }else{ this.win=win; } this.inline=_401; this.closePane=_434; this.closed=false; return this; }; MochiKit.LoggingPane.LoggingPane.prototype={"logFont":"8pt Verdana,sans-serif","colorTable":{"ERROR":"red","FATAL":"darkred","WARNING":"blue","INFO":"black","DEBUG":"green"}}; MochiKit.LoggingPane.EXPORT_OK=["LoggingPane"]; MochiKit.LoggingPane.EXPORT=["createLoggingPane"]; MochiKit.LoggingPane.__new__=function(){ this.EXPORT_TAGS={":common":this.EXPORT,":all":MochiKit.Base.concat(this.EXPORT,this.EXPORT_OK)}; MochiKit.Base.nameFunctions(this); MochiKit.LoggingPane._loggingPane=null; }; MochiKit.LoggingPane.__new__(); MochiKit.Base._exportSymbols(this,MochiKit.LoggingPane); if(typeof (dojo)!="undefined"){ dojo.provide("MochiKit.Color"); dojo.require("MochiKit.Base"); } if(typeof (JSAN)!="undefined"){ JSAN.use("MochiKit.Base",[]); } try{ if(typeof (MochiKit.Base)=="undefined"){ throw ""; } } catch(e){ throw "MochiKit.Color depends on MochiKit.Base"; } if(typeof (MochiKit.Color)=="undefined"){ MochiKit.Color={}; } MochiKit.Color.NAME="MochiKit.Color"; MochiKit.Color.VERSION="1.2"; MochiKit.Color.__repr__=function(){ return "["+this.NAME+" "+this.VERSION+"]"; }; MochiKit.Color.toString=function(){ return this.__repr__(); }; MochiKit.Color.Color=function(red,_441,blue,_443){ if(typeof (_443)=="undefined"||_443==null){ _443=1; } this.rgb={r:red,g:_441,b:blue,a:_443}; }; MochiKit.Color.Color.prototype={__class__:MochiKit.Color.Color,colorWithAlpha:function(_444){ var rgb=this.rgb; var m=MochiKit.Color; return m.Color.fromRGB(rgb.r,rgb.g,rgb.b,_444); },colorWithHue:function(hue){ var hsl=this.asHSL(); hsl.h=hue; var m=MochiKit.Color; return m.Color.fromHSL(hsl); },colorWithSaturation:function(_448){ var hsl=this.asHSL(); hsl.s=_448; var m=MochiKit.Color; return m.Color.fromHSL(hsl); },colorWithLightness:function(_449){ var hsl=this.asHSL(); hsl.l=_449; var m=MochiKit.Color; return m.Color.fromHSL(hsl); },darkerColorWithLevel:function(_450){ var hsl=this.asHSL(); hsl.l=Math.max(hsl.l-_450,0); var m=MochiKit.Color; return m.Color.fromHSL(hsl); },lighterColorWithLevel:function(_451){ var hsl=this.asHSL(); hsl.l=Math.min(hsl.l+_451,1); var m=MochiKit.Color; return m.Color.fromHSL(hsl); },blendedColor:function(_452,_453){ if(typeof (_453)=="undefined"||_453==null){ _453=0.5; } var sf=1-_453; var s=this.rgb; var d=_452.rgb; var df=_453; return MochiKit.Color.Color.fromRGB((s.r*sf)+(d.r*df),(s.g*sf)+(d.g*df),(s.b*sf)+(d.b*df),(s.a*sf)+(d.a*df)); },compareRGB:function(_456){ var a=this.asRGB(); var b=_456.asRGB(); return MochiKit.Base.compare([a.r,a.g,a.b,a.a],[b.r,b.g,b.b,b.a]); },isLight:function(){ return this.asHSL().b>0.5; },isDark:function(){ return (!this.isLight()); },toHSLString:function(){ var c=this.asHSL(); var ccc=MochiKit.Color.clampColorComponent; var rval=this._hslString; if(!rval){ var mid=(ccc(c.h,360).toFixed(0)+","+ccc(c.s,100).toPrecision(4)+"%"+","+ccc(c.l,100).toPrecision(4)+"%"); var a=c.a; if(a>=1){ a=1; rval="hsl("+mid+")"; }else{ if(a<=0){ a=0; } rval="hsla("+mid+","+a+")"; } this._hslString=rval; } return rval; },toRGBString:function(){ var c=this.rgb; var ccc=MochiKit.Color.clampColorComponent; var rval=this._rgbString; if(!rval){ var mid=(ccc(c.r,255).toFixed(0)+","+ccc(c.g,255).toFixed(0)+","+ccc(c.b,255).toFixed(0)); if(c.a!=1){ rval="rgba("+mid+","+c.a+")"; }else{ rval="rgb("+mid+")"; } this._rgbString=rval; } return rval; },asRGB:function(){ return MochiKit.Base.clone(this.rgb); },toHexString:function(){ var m=MochiKit.Color; var c=this.rgb; var ccc=MochiKit.Color.clampColorComponent; var rval=this._hexString; if(!rval){ rval=("#"+m.toColorPart(ccc(c.r,255))+m.toColorPart(ccc(c.g,255))+m.toColorPart(ccc(c.b,255))); this._hexString=rval; } return rval; },asHSV:function(){ var hsv=this.hsv; var c=this.rgb; if(typeof (hsv)=="undefined"||hsv==null){ hsv=MochiKit.Color.rgbToHSV(this.rgb); this.hsv=hsv; } return MochiKit.Base.clone(hsv); },asHSL:function(){ var hsl=this.hsl; var c=this.rgb; if(typeof (hsl)=="undefined"||hsl==null){ hsl=MochiKit.Color.rgbToHSL(this.rgb); this.hsl=hsl; } return MochiKit.Base.clone(hsl); },toString:function(){ return this.toRGBString(); },repr:function(){ var c=this.rgb; var col=[c.r,c.g,c.b,c.a]; return this.__class__.NAME+"("+col.join(", ")+")"; }}; MochiKit.Base.update(MochiKit.Color.Color,{fromRGB:function(red,_461,blue,_462){ var _463=MochiKit.Color.Color; if(arguments.length==1){ var rgb=red; red=rgb.r; _461=rgb.g; blue=rgb.b; if(typeof (rgb.a)=="undefined"){ _462=undefined; }else{ _462=rgb.a; } } return new _463(red,_461,blue,_462); },fromHSL:function(hue,_464,_465,_466){ var m=MochiKit.Color; return m.Color.fromRGB(m.hslToRGB.apply(m,arguments)); },fromHSV:function(hue,_467,_468,_469){ var m=MochiKit.Color; return m.Color.fromRGB(m.hsvToRGB.apply(m,arguments)); },fromName:function(name){ var _470=MochiKit.Color.Color; var _471=_470._namedColors[name.toLowerCase()]; if(typeof (_471)=="string"){ return _470.fromHexString(_471); }else{ if(name=="transparent"){ return _470.transparentColor(); } } return null; },fromString:function(_472){ var self=MochiKit.Color.Color; var _473=_472.substr(0,3); if(_473=="rgb"){ return self.fromRGBString(_472); }else{ if(_473=="hsl"){ return self.fromHSLString(_472); }else{ if(_472.charAt(0)=="#"){ return self.fromHexString(_472); } } } return self.fromName(_472); },fromHexString:function(_474){ if(_474.charAt(0)=="#"){ _474=_474.substring(1); } var _475=[]; var i,hex; if(_474.length==3){ for(i=0;i<3;i++){ hex=_474.substr(i,1); _475.push(parseInt(hex+hex,16)/255); } }else{ for(i=0;i<6;i+=2){ hex=_474.substr(i,2); _475.push(parseInt(hex,16)/255); } } var _476=MochiKit.Color.Color; return _476.fromRGB.apply(_476,_475); },_fromColorString:function(pre,_478,_479,_480){ if(_480.indexOf(pre)==0){ _480=_480.substring(_480.indexOf("(",3)+1,_480.length-1); } var _481=_480.split(/\s*,\s*/); var _482=[]; for(var i=0;i<_481.length;i++){ var c=_481[i]; var val; var _483=c.substring(c.length-3); if(c.charAt(c.length-1)=="%"){ val=0.01*parseFloat(c.substring(0,c.length-1)); }else{ if(_483=="deg"){ val=parseFloat(c)/360; }else{ if(_483=="rad"){ val=parseFloat(c)/(Math.PI*2); }else{ val=_479[i]*parseFloat(c); } } } _482.push(val); } return this[_478].apply(this,_482); },fromComputedStyle:function(elem,_484,_485){ var d=MochiKit.DOM; var cls=MochiKit.Color.Color; for(elem=d.getElement(elem);elem;elem=elem.parentNode){ var _486=d.computedStyle.apply(d,arguments); if(!_486){ continue; } var _487=cls.fromString(_486); if(!_487){ break; } if(_487.asRGB().a>0){ return _487; } } return null; },fromBackground:function(elem){ var cls=MochiKit.Color.Color; return cls.fromComputedStyle(elem,"backgroundColor","background-color")||cls.whiteColor(); },fromText:function(elem){ var cls=MochiKit.Color.Color; return cls.fromComputedStyle(elem,"color","color")||cls.blackColor(); },namedColors:function(){ return MochiKit.Base.clone(MochiKit.Color.Color._namedColors); }}); MochiKit.Base.update(MochiKit.Color,{clampColorComponent:function(v,_488){ v*=_488; if(v<0){ return 0; }else{ if(v>_488){ return _488; }else{ return v; } } },_hslValue:function(n1,n2,hue){ if(hue>6){ hue-=6; }else{ if(hue<0){ hue+=6; } } var val; if(hue<1){ val=n1+(n2-n1)*hue; }else{ if(hue<3){ val=n2; }else{ if(hue<4){ val=n1+(n2-n1)*(4-hue); }else{ val=n1; } } } return val; },hsvToRGB:function(hue,_491,_492,_493){ if(arguments.length==1){ var hsv=hue; hue=hsv.h; _491=hsv.s; _492=hsv.v; _493=hsv.a; } var red; var _494; var blue; if(_491==0){ red=0; _494=0; blue=0; }else{ var i=Math.floor(hue*6); var f=(hue*6)-i; var p=_492*(1-_491); var q=_492*(1-(_491*f)); var t=_492*(1-(_491*(1-f))); switch(i){ case 1: red=q; _494=_492; blue=p; break; case 2: red=p; _494=_492; blue=t; break; case 3: red=p; _494=q; blue=_492; break; case 4: red=t; _494=p; blue=_492; break; case 5: red=_492; _494=p; blue=q; break; case 6: case 0: red=_492; _494=t; blue=p; break; } } return {r:red,g:_494,b:blue,a:_493}; },hslToRGB:function(hue,_496,_497,_498){ if(arguments.length==1){ var hsl=hue; hue=hsl.h; _496=hsl.s; _497=hsl.l; _498=hsl.a; } var red; var _499; var blue; if(_496==0){ red=_497; _499=_497; blue=_497; }else{ var m2; if(_497<=0.5){ m2=_497*(1+_496); }else{ m2=_497+_496-(_497*_496); } var m1=(2*_497)-m2; var f=MochiKit.Color._hslValue; var h6=hue*6; red=f(m1,m2,h6+2); _499=f(m1,m2,h6); blue=f(m1,m2,h6-2); } return {r:red,g:_499,b:blue,a:_498}; },rgbToHSV:function(red,_503,blue,_504){ if(arguments.length==1){ var rgb=red; red=rgb.r; _503=rgb.g; blue=rgb.b; _504=rgb.a; } var max=Math.max(Math.max(red,_503),blue); var min=Math.min(Math.min(red,_503),blue); var hue; var _507; var _508=max; if(min==max){ hue=0; _507=0; }else{ var _509=(max-min); _507=_509/max; if(red==max){ hue=(_503-blue)/_509; }else{ if(_503==max){ hue=2+((blue-red)/_509); }else{ hue=4+((red-_503)/_509); } } hue/=6; if(hue<0){ hue+=1; } if(hue>1){ hue-=1; } } return {h:hue,s:_507,v:_508,a:_504}; },rgbToHSL:function(red,_510,blue,_511){ if(arguments.length==1){ var rgb=red; red=rgb.r; _510=rgb.g; blue=rgb.b; _511=rgb.a; } var max=Math.max(red,Math.max(_510,blue)); var min=Math.min(red,Math.min(_510,blue)); var hue; var _512; var _513=(max+min)/2; var _514=max-min; if(_514==0){ hue=0; _512=0; }else{ if(_513<=0.5){ _512=_514/(max+min); }else{ _512=_514/(2-max-min); } if(red==max){ hue=(_510-blue)/_514; }else{ if(_510==max){ hue=2+((blue-red)/_514); }else{ hue=4+((red-_510)/_514); } } hue/=6; if(hue<0){ hue+=1; } if(hue>1){ hue-=1; } } return {h:hue,s:_512,l:_513,a:_511}; },toColorPart:function(num){ var _515=Math.round(num).toString(16); if(num<16){ return "0"+_515; } return _515; },__new__:function(){ var m=MochiKit.Base; this.Color.fromRGBString=m.bind(this.Color._fromColorString,this.Color,"rgb","fromRGB",[1/255,1/255,1/255,1]); this.Color.fromHSLString=m.bind(this.Color._fromColorString,this.Color,"hsl","fromHSL",[1/360,0.01,0.01,1]); var _516=1/3; var _517={black:[0,0,0],blue:[0,0,1],brown:[0.6,0.4,0.2],cyan:[0,1,1],darkGray:[_516,_516,_516],gray:[0.5,0.5,0.5],green:[0,1,0],lightGray:[2*_516,2*_516,2*_516],magenta:[1,0,1],orange:[1,0.5,0],purple:[0.5,0,0.5],red:[1,0,0],transparent:[0,0,0,0],white:[1,1,1],yellow:[1,1,0]}; var _518=function(name,r,g,b,a){ var rval=this.fromRGB(r,g,b,a); this[name]=function(){ return rval; }; return rval; }; for(var k in _517){ var name=k+"Color"; var _521=m.concat([_518,this.Color,name],_517[k]); this.Color[name]=m.bind.apply(null,_521); } var _522=function(){ for(var i=0;i"+el.innerHTML+""; },_roundTopCorners:function(el,_538,_539){ var _540=this._createCorner(_539); for(var i=0;i=0;i--){ _543.appendChild(this._createCornerSlice(_541,_542,i,"bottom")); } el.style.paddingBottom=0; el.appendChild(_543); },_createCorner:function(_544){ var dom=MochiKit.DOM; return dom.DIV({style:{backgroundColor:_544.toString()}}); },_createCornerSlice:function(_545,_546,n,_547){ var _548=MochiKit.DOM.SPAN(); var _549=_548.style; _549.backgroundColor=_545.toString(); _549.display="block"; _549.height="1px"; _549.overflow="hidden"; _549.fontSize="1px"; var _550=this._borderColor(_545,_546); if(this.options.border&&n==0){ _549.borderTopStyle="solid"; _549.borderTopWidth="1px"; _549.borderLeftWidth="0px"; _549.borderRightWidth="0px"; _549.borderBottomWidth="0px"; _549.height="0px"; _549.borderColor=_550.toString(); }else{ if(_550){ _549.borderColor=_550.toString(); _549.borderStyle="solid"; _549.borderWidth="0px 1px"; } } if(!this.options.compact&&(n==(this.options.numSlices-1))){ _549.height="2px"; } this._setMargin(_548,n,_547); this._setBorder(_548,n,_547); return _548; },_setOptions:function(_551){ this.options={corners:"all",color:"fromElement",bgColor:"fromParent",blend:true,border:false,compact:false,__unstable__wrapElement:false}; MochiKit.Base.update(this.options,_551); this.options.numSlices=(this.options.compact?2:4); },_whichSideTop:function(){ var _552=this.options.corners; if(this._hasString(_552,"all","top")){ return ""; } var _553=(_552.indexOf("tl")!=-1); var _554=(_552.indexOf("tr")!=-1); if(_553&&_554){ return ""; } if(_553){ return "left"; } if(_554){ return "right"; } return ""; },_whichSideBottom:function(){ var _555=this.options.corners; if(this._hasString(_555,"all","bottom")){ return ""; } var _556=(_555.indexOf("bl")!=-1); var _557=(_555.indexOf("br")!=-1); if(_556&&_557){ return ""; } if(_556){ return "left"; } if(_557){ return "right"; } return ""; },_borderColor:function(_558,_559){ if(_558=="transparent"){ return _559; }else{ if(this.options.border){ return this.options.border; }else{ if(this.options.blend){ return _559.blendedColor(_558); } } } return ""; },_setMargin:function(el,n,_560){ var _561=this._marginSize(n)+"px"; var _562=(_560=="top"?this._whichSideTop():this._whichSideBottom()); var _563=el.style; if(_562=="left"){ _563.marginLeft=_561; _563.marginRight="0px"; }else{ if(_562=="right"){ _563.marginRight=_561; _563.marginLeft="0px"; }else{ _563.marginLeft=_561; _563.marginRight=_561; } } },_setBorder:function(el,n,_564){ var _565=this._borderSize(n)+"px"; var _566=(_564=="top"?this._whichSideTop():this._whichSideBottom()); var _567=el.style; if(_566=="left"){ _567.borderLeftWidth=_565; _567.borderRightWidth="0px"; }else{ if(_566=="right"){ _567.borderRightWidth=_565; _567.borderLeftWidth="0px"; }else{ _567.borderLeftWidth=_565; _567.borderRightWidth=_565; } } },_marginSize:function(n){ if(this.isTransparent){ return 0; } var o=this.options; if(o.compact&&o.blend){ var _568=[1,0]; return _568[n]; }else{ if(o.compact){ var _569=[2,1]; return _569[n]; }else{ if(o.blend){ var _570=[3,2,1,0]; return _570[n]; }else{ var _571=[5,3,2,1]; return _571[n]; } } } },_borderSize:function(n){ var o=this.options; var _572; if(o.compact&&(o.blend||this.isTransparent)){ return 1; }else{ if(o.compact){ _572=[1,0]; }else{ if(o.blend){ _572=[2,1,1,1]; }else{ if(o.border){ _572=[0,2,0,0]; }else{ if(this.isTransparent){ _572=[5,3,2,1]; }else{ return 0; } } } } } return _572[n]; },_hasString:function(str){ for(var i=1;i"+"<"+"/script"+">"; document.write(tag); } } })(); } PK4i7 Y Y(kss/core/kukit/3rd_party/base2-dom-fp.jseval(function(p,a,c,k,e,r){var b,e=function(c){return(c<62?'':e(parseInt(c/62)))+((c=c%62)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)a[c]=(r[b=e(c)]=k[c])?b:'\\x0';e=function(){return a.join('|')||'^'};k=[function(e){return r[e]}];c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b('+e(c)+')\\b','g'),k[c]);return p}('u U={1v:"U",4I:"0.9 (4J)",2c:q,1h:C o(1w){u 2c=1w;u 4K/*@3S=@3T@*/;u 30=1w.30;v(1w.31){u 1l=10.3U("span");u 1U=31.1U+" "+31.userAgent;v(!4K)1U=1U.D(/1m\\s[\\d.]+/,"");1U=1U.D(/([a-z])[\\s\\/](\\d)/4L,"$1$2");30=31.javaEnabled()&&30}t o(a){u r=L;u b=a.1V(0)=="!";v(b)a=a.J(1);a=a.D(/^([^\\(].*)$/,"/($1)/i.P(1U)");32{1W("r=!!"+a)}33(2d){}t!!(b^r)}}(q)};C o(1w){u 1h=U.1h;u J=2e.J||o(a){t 3V.X(a,3V.15(A,1))};u 34=1;u 3W=/^[1w$]/;u _3=/%([1-9])/g;u 4M=/^\\s\\s*/;u 4N=/\\s\\s*$/;u 4O=/([\\/()[\\]{}|*+-.,^$?\\\\])/g;u 3X=/1W/.P(1h)?/\\bbase\\b/:/./;u 4P=["V","1X","35"];u 4Q=R(C 19);u 3V=2e.M.J;u 2x=4R();o N(){v(q.V==N){q.x(A[0])}E{t x(A[0],N.M)}};N.M={V:N,y:o(){},x:1F(x)};N.2f=2g;N.36=1F(3Y);N.y=N.M.y;N.x=o(a,b){U.37=11;u c=C q;x(c,a);2y U.37;u d=c.V;o 1p(){v(!U.37){v(q.V==A.1G||q.3Z){q.3Z=11;d.X(q,A);2y q.3Z}E{t x(A[0],c)}}};c.V=1p;13(u i 1Y N)1p[i]=q[i];1p.2f=q;1p.y=1Z;1p.14=1Z;1p.M=c;x(1p,b);1p.14();t 1p};N.F=1F(2x),N.1a=o(a){v(1b(a,1H)){v(N.36(a)){a(q.M)}}E{x(q.M,a)}t q};N.14=1Z;u 2z=N.x({V:o(c,d){q.x(d);v(G q.14=="o")q.14();v(q.1v!="U"){U.40(q.1v,q);q.2h=H("u %1=U.%1;",q.1v)}u e=/[^\\s,]+/g;c.38=20.2A(q.38.1I(e),o(a,b){21(U[b],H("2z 18 found: \'%1\'.",b));t a+=U[b].2h},U.2h);c.1J=20.2A(q.1J.1I(e),o(a,b){q.2h+=H("u %2=%1.%2;",q.1v,b);t a+=H("v(!%1.%2)%1.%2=%2;",q.1v,b)},"",q)},1J:"",38:"",2h:"",1v:"",40:o(a,b){q[a]=b;q.1J+=","+a;q.2h+=H("u %1=%2.%1;",a,q.1v)}});u 41=N.x({V:o(){1K C 4S("Class cannot be instantiated.");}});u 1i=41.x(I,{x:o(c,d){u e=q.y();F(q,o(a,b){v(!1i[b]&&G a=="o"&&!3W.P(b)){x(e,b,a)}});e.1a(c);x(e,d);e.14();t e},1a:o(c){u d=q;v(G c=="o"){d.y(c);v(1i.36(c)){F(c,o(a,b){v(!1i[b]&&G a=="o"&&!3W.P(b)){x(d,b,a)}})}}E{2x(2g,c,o(a,b){v(b.1V(0)=="@"){v(1h(b.J(1))){F(a,A.1G)}}E v(!1i[b]&&G a=="o"){o 42(){t d[b].X(d,[q].1n(J(A)))};42.39=3X.P(a);x(d.M,b,42)}});x(d,c)}t d}});u 22=1i.x({4T:o(c,d,e){u f=11;32{q.F(c,o(a,b){f=d.15(e,a,b,c);v(!f)1K 2B;})}33(2d){v(2d!=2B)1K 2d;}t!!f},filter:o(d,e,f){u i=0;t q.2A(d,o(a,b,c){v(e.15(f,b,c,d)){a[i++]=b}t a},[])},invoke:o(b,c){u d=J(A,2);t q.2C(b,(G c=="o")?o(a){v(a!=I)t c.X(a,d)}:o(a){v(a!=I)t a[c].X(a,d)})},2C:o(c,d,e){u f=[],i=0;q.F(c,o(a,b){f[i++]=d.15(e,a,b,c)});t f},pluck:o(b,c){t q.2C(b,o(a){v(a!=I)t a[c]})},2A:o(c,d,e,f){u g=A.B>2;q.F(c,o(a,b){v(g){e=d.15(f,e,a,b,c)}E{e=a;g=11}});t e},some:o(c,d,e){t!q.4T(c,o(a,b){t!d.15(e,a,b,c)})}},{F:F});u 1c="#";u 3a=N.x({V:o(a){q.43(a)},1x:1F(1x),23:o(a){/*@3S@*//*@v(@3T<5.5)t $4U.23(q,1c+a);@E@*/t 1c+a 1Y q;/*@4V@*/},4W:o(a){t q[1c+a]},F:o(a,b){13(u c 1Y q)v(c.1V(0)==1c){a.15(b,q[c],c.J(1),q)}},43:o(d){F(A,o(c){F(c,o(a,b){q.24(b,a)},q)},q);t q},2i:o(a){u b=q[1c+a];2y q[1c+a];t b},24:o(a,b){v(A.B==1)b=a;t q[1c+a]=b},union:o(a){t q.43.X(q.1x(),A)}});3a.1a(22);u S="~";u 44=3a.x({V:o(a){q[S]=C 20;q.y(a)},3b:o(a,b){21(!q.23(a),"4X 4Y \'"+a+"\'.");t q.24.X(q,A)},1x:o(){u a=q.y();a[S]=q[S].1x();t a},2j:o(){t q[S].B},4Z:o(a){v(a<0)a+=q[S].B;u b=q[S][a];v(b!==1j)t q[1c+b]},F:o(a,b){u c=q[S];u d=c.B,i;13(i=0;i=0;i--){v(a[i]===b)t i}t-1},2C:o(c,d,e){u f=[];q.F(c,o(a,b){f[b]=d.15(e,a,b,c)});t f},2i:o(a,b){u c=q.25(a,b);v(c!=-1)q.3e(a,c);t b},3e:o(a,b){t q.3l(a,b,1)}}]);20.M.F=1F(3m);u String2=4b(R,"1V,charCodeAt,1n,25,5d,1I,D,search,J,1y,substr,5e,4c,3n",[{2k:2k}]);o 4b(c,d,e){u f=1i.x();F(d.1y(","),o(a){f[a]=3o(c.M[a])});F(e,f.1a,f);u g=o(){t f(q.V==f?c.X(c,A):A[0])};g.M=f.M;F(f,o(a,b){v(c[b]){f[b]=c[b];2y f.M[b]}g[b]=f[b]});t g};o y(a,b){t a.y.X(a,b)};o x(c,d){u e=A.1G;v(c!=I){v(A.B>2){u f=R(d);u g=A[2];v(f.1V(0)=="@"){t 1h(f.J(1))?e(c,g):c}v(c.x==e&&/^(y|x)$/.P(f)){t c}v(G g=="o"){u h=c[f];v(g!=h&&!3Y(g,h)){v(g.39||3X.P(g)){u i=g;o 39(){u a=q.y;q.y=h;u b=i.X(q,A);q.y=a;t b};g=39;g.method=i;g.2f=h}c[f]=g}}E{c[f]=g}}E v(d){u j=1b(d,1H)?1H:2g;v(U.37){F(4P,o(a){v(d[a]!=j.M[a]){e(c,a,d[a])}})}E{v(G c.x=="o"&&G c!="o"&&c.x!=e){e=3o(c.x)}}2x(j,d,o(a,b){e(c,b,a)})}}t c};o 3Y(a,b){1o(b&&b.2f!=a)b=b.2f;t!!b};v(G 2B=="1j"){2B=C 5f("2B")}o F(a,b,c,d){v(a==I)t;v(!d){v(1b(a,1H)){d=1H}E v(G a.F=="o"&&a.F!=A.1G){a.F(b,c);t}E v(G a.B=="49"){3m(a,b,c);t}}2x(d||2g,a,b,c)};o 3m(a,b,c){v(a==I)t;u d=a.B,i;v(G a=="27"){13(i=0;i1)?o(a,b,c,d){u e={};13(u f 1Y b){v(!e[f]&&a.M[f]===1j){e[f]=11;c.15(d,b[f],f,b)}}}:o(a,b,c,d){13(u e 1Y b){v(a.M[e]===1j){c.15(d,b[e],e,b)}}}};o 1b(a,b){4d(b,"o","5g \'1b\' operand.");/*@3S@*//*@v(@3T<5.1)v($4U.1b(a,b))t 11;@E@*/v(a instanceof b)t 11;/*@4V@*/v(4e(b))t L;v(4e(a.V))t b==2g;v(a!=I)3d(b){1d 2e:t!!(G a=="3i"&&a.2E&&a.3l);1d 1H:t!!(G a=="o"&&a.15);1d 19:t a.V.M.1X()==4Q;1d Date:t!!a.getTimezoneOffset;1d R:1d 57:1d Boolean:t G a==G b.M.35();1d 2g:t G a=="3i"&&G a.V=="o"}t L};o 4e(a){t a==N||N.36(a)};o 21(a,b,c){v(!a){1K C(c||5f)(b||"Assertion failed.");}};o 5h(a,b,c){v(b==I)b=a.1G.B;v(a.B<\\/5y>");10.1B.5z.onreadystatechange=o(){v(q.5A=="5B"){q.removeNode();1S.2t()}}}},"@4w":{14:o(){q.y();u a=setInterval(o(){v(/loaded|5B/.P(10.5A)){clearInterval(a);1S.2t()}},100)}}});u 4j=2p.x({"@!(10.2I.5C)":{5C:o(a,b,c){t b.currentStyle}}},{toCamelCase:o(c){t R(c).D(/\\-([a-z])/g,o(a,b){t b.3n()})}});u 3E=2p.x({"@!(1l.5D)":{5D:o(a,b){v(1b(b,2e)){b=b.2E(".")}t q.4x(a,"."+b)}},"@!(1l.4y)":{4x:o(a,b){t C Y(b).1e(a)},4y:o(a,b){t C Y(b).1e(a,1)}}});x(3E.M,{4x:o(b){t x(q.y(b),"1q",o(a){t 1N.O(q.y(a))})},4y:o(a){t 1N.O(q.y(a))}});u 4h=3E.x();u 4i=3E.x({"@!(1l.5E)":{5E:o(a,b){t C Y(b).P(a)}}});u 3s=N.x({V:o(b){b=b||[];q.B=b.B;q.1q=o(a){t b[a]}},B:0,F:o(a,b){u c=q.B;13(u i=0;i](\\*|[\\w-]+))([^: >+~]*)(:\\w+-Z(\\([^)]+\\))?)([^: >+~]*)/,"$1$3$6$4")},3G:I,3h:11,3H:o(b){u c=/\'/g;u d=q.5I=[];t q.5J(q.H(R(b).D(1s.5K,o(a){d.2D(a.J(1,-1).D(c,"\\\\\'"));t"\\5L"+d.B})))},H:o(a){t a.D(1s.5M,"$1").D(1s.5N,"$1 $2").D(1s.5O,"$1*$2")},5J:o(a){t q.2O.1e(a.D(1s.5P,">* "))},3F:o(a){t q.3G[a]||(q.3G[a]=q.2u(q.1e(q.3H(a))))},2u:o(c){u d=q.5I;t c.D(/\\5L(\\d+)/g,o(a,b){t d[b-1]})}},{5K:/(["\'])[^\\1]*\\1/g,5O:/([\\s>+~,]|[^(]\\+|^)([#.:@])/g,5N:/(^|,)([^\\s>+~])/g,5M:/\\s*([\\s>+~(),]|^|$)\\s*/g,5P:/\\s\\*\\s/g,2a:o(c,d,e,f,g,h,i,j){f=/1k/i.P(c)?f+"+1-":"";v(!isNaN(d))d="0n+"+d;E v(d=="even")d="2n";E v(d=="odd")d="2n+1";d=d.1y(/n\\+?/);u a=d[0]?(d[0]=="-")?-1:4a(d[0]):1;u b=4a(d[1])||0;u g=a<0;v(g){a=-a;v(a==1)b++}u l=H(a==0?"%3%7"+(f+b):"(%4%3-%2)%6%1%70%5%4%3>=%2",a,b,e,f,h,i,j);v(g)l=g+"("+l+")";t l}});Y.4A={"=":"%1==\'%2\'","!=":"%1!=\'%2\'","~=":/(^| )%1( |$)/,"|=":/^%1(-|$)/,"^=":/^%1/,"$=":/%1$/,"*=":/%1/};Y.4A[""]="%1!=I";Y.1t={"3I":"e%1.3I","17":"e%1[T.$2K].25(\'%2\')!=-1","2P":"e%1.2P","5Q":"T.5o(e%1)","4B":"e%1.2P===L","4C-Z":"!T.4o(e%1)","1k-Z":"!T.3w(e%1)","2Q-Z":"!T.4o(e%1)&&!T.3w(e%1)","4D":"e%1==T.2q(e%1).4q"};C o(1w){u 2b=1h("2b");u 2R=1h("2R");u 5R=1h("(1l.3J)");u 4E="u p%2=0,i%2,e%2,n%2=e%1.";u 34=5R?"e%1.3J":"1M(e%1)";u 5S="u g="+34+";v(!p[g]){p[g]=1;";u 5T="r[r.B]=e%1;v(s)t e%1;";u 5U="1Q=o(5V,s){2v++;u r=[],p={},1u=[%1],"+"d=T.2q(5V),c=d.body?\'3n\':\'1X\';";u 5W=2b?o(a,b){u c=a.1B[b]||I;v(!c||c.2M==b)t c;13(u i=0;i(\\\\*|[\\\\w-]+)":o(a,b){u c=2b&&1D;12=b=="*";u d=4E;d+=c?"children":"childNodes";v(!12&&c)d+=".4F(\'%3\')";d+=";13(i%2=0;(e%2=n%2[i%2]);i%2++){";v(12){d+="v(e%2.1A==1){";12=2R}E{v(!c)d+="v(e%2.2T==\'%3\'[c]()){"}t H(d,W++,1D=W,b)},"\\\\+(\\\\*|[\\\\w-]+)":o(a,b){u c="";v(12&&2b)c+="v(e%1.29!=\'!\'){";12=L;c+="e%1=T.3w(e%1);v(e%1";v(b!="*")c+="&&e%1.2T==\'%2\'[c]()";c+="){";t H(c,W,b)},"~(\\\\*|[\\\\w-]+)":o(a,b){u c="";v(12&&2b)c+="v(e%1.29!=\'!\'){";12=L;2S=2;c+="1o(e%1=e%1.3x){v(e%1.61==2v)2F;e%1.61=2v;v(";v(b=="*"){c+="e%1.1A==1";v(2R)c+="&&e%1.29!=\'!\'"}E c+="e%1.2T==\'%2\'[c]()";c+="){";t H(c,W,b)},"#([\\\\w-]+)":o(a,b){12=L;u c="v(e%1.2M==\'%2\'){";v(1D)c+=H("i%1=n%1.B;",1D);t H(c,W,b)},"\\\\.([\\\\w-]+)":o(a,b){12=L;1u.2D(C 19("(^|\\\\s)"+1L(b)+"(\\\\s|$)"));t H("v(1u[%2].P(e%1.1r)){",W,1u.B-1)},":18\\\\((\\\\*|[\\\\w-]+)?([^)]*)\\\\)":o(a,b,c){u d=(b&&b!="*")?H("v(e%1.2T==\'%2\'[c]()){",W,b):"";d+=2w.1e(c);t"v(!"+d.J(2,-1).D(/\\)\\{v\\(/g,"&&")+"){"},":2U(-1k)?-Z\\\\(([^)]+)\\\\)":o(a,b,c){12=L;b=H("e%1.2L.60",W);u d="v(p%1!==e%1.2L)";d+="p%1=5X(e%1.2L);u i=e%1.5Z;v(";t H(d,W)+1s.2a(a,c,"i",b,"!","&&","%","==")+"){"},":([\\\\w-]+)(\\\\(([^)]+)\\\\))?":o(a,b,c,d){t"v("+H(Y.1t[b],W,d||"")+"){"},"\\\\[([\\\\w-]+)\\\\s*([^=]?=)?\\\\s*([^\\\\]]*)\\\\]":o(a,b,c,d){u e=1z.$1T[b]||b;v(b=="62")e="1r";E v(b=="13")e="htmlFor";v(c){b=H("(e%1.%3||e%1.3L(\'%2\'))",W,b,e)}E{b=H("1z.3L(e%1,\'%2\')",W,b)}u f=Y.4A[c||""];v(1b(f,19)){1u.2D(C 19(H(f.3j,1L(2w.2u(d)))));f="1u[%2].P(%1)";d=1u.B-1}t"v("+H(f,b,d)+"){"}});Y.3F=o(a){v(!3K[a]){1u=[];1Q="";u b=2w.3H(a).1y(",");13(u i=0;i1?2:0;u c=2w.1e(b[i])||"1K;";v(12&&2b){c+=H("v(e%1.29!=\'!\'){",W)}u d=(2S>1)?5S:"";c+=H(d+5T,W);c+=2e(1I(c,/\\{/g).B+1).2E("}");1Q+=c}1W(H(5U,1u)+2w.2u(1Q)+"t s?I:r}");3K[a]=1Q}t 3K[a]}};u 2o=1s.x({V:o(){q.y(2o.4G);q.2O.55(1,"$1$4$3$6")},3H:o(a){t q.y(a).D(/,/g,"\\3M")},2u:o(a){t q.y(a.D(/\\[2V::\\*\\]/g,"").D(/(^|\\3M)\\//g,"$1./").D(/\\3M/g," | "))},"@63":{2u:o(a){t q.y(a.D(/1k\\(\\)/g,"2j(3N-1E::*)+2j(2W-1E::*)+1"))}}},{14:o(){q.2X.1T[""]="[@$1]";F(q.64,o(a,b){F(q.2X[b],a,q.4G)},q)},3O:{1t:{"4C-Z":"[1]","1k-Z":"[1k()]","2Q-Z":"[1k()=1]"}},4G:x({},{"@!4w":{"(^|\\\\3M) (\\\\*|[\\\\w-]+)#([\\\\w-]+)":"$1id(\'$3\')[2V::$2]","([ >])(\\\\*|[\\\\w-]+):([\\\\w-]+-Z(\\\\(([^)]+)\\\\))?)":o(a,b,c,d,e,f){u g=(b==" ")?"//*":"/*";v(/^2U/i.P(d)){g+=2a(d,f,"position()")}E{g+=2o.3O.1t[d]}t g+"[2V::"+c+"]"}}}),64:{65:o(a,b){q[1L(b)+"([\\\\w-]+)"]=a},66:o(a,b){q[1L(b)+"(\\\\*|[\\\\w-]+)"]=a},1T:o(a,b){q["\\\\[([\\\\w-]+)\\\\s*"+1L(b)+"\\\\s*([^\\\\]]*)\\\\]"]=a},1t:o(a,b){q[":"+b.D(/\\(\\)$/,"\\\\(([^)]+)\\\\)")]=a}},2X:{65:{"#":"[@2M=\'$1\'][1]",".":"[17(1n(\' \',@62,\' \'),\' $1 \')]"},66:{" ":"/descendant::$1",">":"/Z::$1","+":"/2W-1E::*[1][2V::$1]","~":"/2W-1E::$1"},1T:{"*=":"[17(@$1,\'$2\')]","^=":"[starts-with(@$1,\'$2\')]","$=":"[5e(@$1,27-B(@$1)-27-B(\'$2\')+1)=\'$2\']","~=":"[17(1n(\' \',@$1,\' \'),\' $2 \')]","|=":"[17(1n(\'-\',@$1,\'-\'),\'-$2-\')]","!=":"[18(@$1=\'$2\')]","=":"[@$1=\'$2\']"},1t:{"5Q":"[18(Z::*) 3P 18(text())]","4C-Z":"[18(3N-1E::*)]","1k-Z":"[18(2W-1E::*)]","18()":68,"2U-Z()":2a,"2U-1k-Z()":2a,"2Q-Z":"[18(3N-1E::*) 3P 18(2W-1E::*)]","4D":"[18(parent::*)]"}},"@63":{14:o(){q.3O.1t["1k-Z"]=q.2X.1t["1k-Z"];q.3O.1t["2Q-Z"]=q.2X.1t["2Q-Z"];q.y()}}});o 68(a,b){u c=C 2o;t"[18("+c.1e(2k(b)).D(/\\[1\\]/g,"").D(/^(\\*|[\\w-]+)/,"[2V::$1]").D(/\\]\\[/g," 3P ").J(1,-1)+")]"};o 2a(a,b,c){t"["+1s.2a(a,b,c||"2j(3N-1E::*)+1","1k()","18"," 3P "," mod ","=")+"]"};Y.1a({2Y:o(){t Y.2Y(q)},"@(5F)":{$2N:o(a,b){v(Y.$2Z.P(q)){t q.y(a,b)}u c=T.2q(a);u d=b?9:7;u e=c.2N(q.2Y(),a,I,d,I);t b?e.singleNodeValue:e}},"@1m":{$2N:o(a,b){v(G a.69!="1j"&&!Y.$2Z.P(q)){u c=b?"selectSingleNode":"69";t a[c](q.2Y())}t q.y(a,b)}}});x(Y,{3Q:I,2Y:o(a){v(!q.3Q)q.3Q=C 2o;t q.3Q.3F(a)},$2Z:/:(3I|2P|4B|17)|^(#[\\w-]+\\s*)?\\w+$/,"@4w":{$2Z:/:(3I|2P|4B|17)|^(#[\\w-]+\\s*)?\\w+$|2U\\-/,"@!WebKit5":{$2Z:/./}}});u 28=3u.x({"@!(1l.6a)":{6a:o(a,b){v(T.17(a,b)){t 4|16}E v(T.17(b,a)){t 2|8}u c=28.3R(a);u d=28.3R(b);v(cd){t 2}t 0}}},{3R:o(a){u b=0;1o(a){b=T.5m(a)+"."+b;a=a.2L}t b},"@(1l.3J)":{3R:o(a){t a.3J}}});u 1O=28.x(I,{O:o(b){q.y(b);x(b,"3U",o(a){t 1N.O(q.y(a))});3q.O(b.2I);t b},"@!(10.2I)":{O:o(a){a.2I=T.3v(a);t q.y(a)}}});1O.3t("3U",2);u 1z=28.x({"@1m[67]":{3L:o(a,b,c){v(a.1r===1j||b=="6b"||b=="4v"){t q.y(a,b,2)}u d=a.getAttributeNode(b);t d&&d.6c?d.6d:I}},"@3z.+2H":{3L:o(a,b,c){v(a.1r===1j||b=="6b"||b=="4v"){t q.y(a,b,2)}u d=a.1T[q.$1T[b.4c()]||b];t d?d.6c?d.6d:I:q.y(a,b)}}},{$1T:{},"@3z.+2H":{14:o(){u a="colSpan,rowSpan,vAlign,dateTime,accessKey,tabIndex,encType,maxLength,readOnly,longDesc";u b=a.4c().1y(",");u c=a.1y(",");q.$1T=20.5b(b,c)}}});1z.3t("5H",3);3q.1a(4j);1O.1a(4h);1O.1a(3r);1O.1a(1g);1z.1a(4i);1z.1a(1g);u 4k=1O.x(I,{"@(10.4H===1j)":{O:o(b){q.y(b);b.4H=I;b.1C("focus",o(a){b.4H=a.3A},L);t b}}});u 2G=1z.x({addClass:o(a,b){v(!q.6e(a,b)){a.1r+=(a.1r?" ":"")+b;t b}},6e:o(a,b){u c=C 19("(^|\\\\s)"+b+"(\\\\s|$)");t c.P(a.1r)},removeClass:o(a,b){u c=C 19("(^|\\\\s)"+b+"(\\\\s|$)");a.1r=a.1r.D(c,"$2");t b}},{4l:{},4F:"*",x:o(){u b=y(q,A);u c=(b.4F||"").3n().1y(",");F(c,o(a){2G.4l[a]=b});t b},"@!(1l.3y)":{O:o(a){q.y(a);a.3y=T.2r(a);t a}}});1N.$=o(a,b){t C Y(a).1e(b,1)};1N.$$=o(a,b){t C Y(a).1e(b)};1W(q.1J)};',[],494,'||||||||||||||||||||||||function||this|||return|var|if||extend|base||arguments|length|new|replace|else|forEach|typeof|format|null|slice||false|prototype|Base|bind|test||String|_16|Traversal|base2|constructor|_35|apply|Selector|child|document|true|_36|for|init|call||contains|not|RegExp|implement|instanceOf|_15|case|exec|Item|EventTarget|detect|Module|undefined|last|element|MSIE|concat|while|klass|item|className|Parser|pseudoClasses|reg|name|_|copy|split|Element|nodeType|all|addEventListener|_37|sibling|delegate|callee|Function|match|exports|throw|rescape|assignID|DOM|Document|closures|fn|createEvent|DOMContentLoaded|attributes|platform|charAt|eval|toString|in|Undefined|Array2|assert|Enumerable|exists|store|indexOf|RegGrp|string|Node|tagName|_27|_28|global|error|Array|ancestor|Object|namespace|remove|count|trim|base2ID|Event||XPathParser|Interface|getDocument|getOwnerDocument|handleEvent|fire|unescape|indexed|parser|_10|delete|Namespace|reduce|StopIteration|map|push|join|break|HTMLElement|win|defaultView|isElement|TEXT|parentNode|id|evaluate|sorter|disabled|only|_29|_38|nodeName|nth|self|following|values|toXPath|NOT_XPATH|java|navigator|try|catch|_1|valueOf|ancestorOf|__prototyping|imports|_14|Hash|add|Math|switch|removeAt|sort|create|ignoreCase|object|source|partial|splice|_19|toUpperCase|unbind|type|AbstractView|DocumentEvent|StaticNodeList|createDelegate|Binding|getDefaultView|getNextElementSibling|nextSibling|ownerDocument|MSIE5|target|dispatchEvent|listener|fired|NodeSelector|parse|cache|escape|checked|sourceIndex|_39|getAttribute|x02|preceding|optimised|and|xpathParser|_41|cc_on|_jscript_version|createElement|_0|_2|_7|_12|__constructing|addName|Abstract|_13|merge|Collection|insertAt|default|reverse|replacement|number|parseInt|_18|toLowerCase|assertType|_20|_21|_22|DocumentSelector|ElementSelector|ViewCSS|HTMLDocument|bindings|attachEvent|continue|getPreviousElementSibling|isDocument|documentElement|initEvent|cancelable|returnValue|Events|src|KHTML|matchAll|matchSingle|b2_test|operators|enabled|first|root|_31|tags|rules|activeElement|version|alpha|jscript|gi|_4|_5|_6|_8|_9|_11|TypeError|every|Legacy|end|fetch|Duplicate|key|fetchAt|abs|Index|out|of|bounds|storeAt||Number|IGNORE|_17|index|combine|max|lastIndexOf|substring|Error|Invalid|assertArity|SyntaxError|_23|_24|_25|getNodeIndex|previousSibling|isEmpty|firstChild|parentWindow|bubbles|cancelBubble|preventDefault|on|event|createEventObject|load|script|__ready|readyState|complete|getComputedStyle|getElementsByClassName|matchesSelector|XPathResult|snapshotItem|setAttribute|_26|optimise|ESCAPE|x01|WHITESPACE|IMPLIED_SPACE|IMPLIED_ASTERISK|WILD_CARD|empty|_30|_32|_33|_34|e0|byId|register|b2_indexed|b2_index|b2_length|b2_adjacent|class|opera|types|identifiers|combinators||_40|selectNodes|compareDocumentPosition|href|specified|nodeValue|hasClass'.split('|'),0,{}));PK4i7P7$kss/core/kukit/3rd_party/cssQuery.js/* cssQuery, version 2.0.2 (2005-08-19) Copyright: 2004-2005, Dean Edwards (http://dean.edwards.name/) License: http://creativecommons.org/licenses/LGPL/2.1/ */ eval(function(p,a,c,k,e,d){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('7 x=6(){7 1D="2.0.2";7 C=/\\s*,\\s*/;7 x=6(s,A){33{7 m=[];7 u=1z.32.2c&&!A;7 b=(A)?(A.31==22)?A:[A]:[1g];7 1E=18(s).1l(C),i;9(i=0;i<1E.y;i++){s=1y(1E[i]);8(U&&s.Z(0,3).2b("")==" *#"){s=s.Z(2);A=24([],b,s[1])}1A A=b;7 j=0,t,f,a,c="";H(j+~]/;7 20=/[\\s#.:>+~()@]|[^\\s#.:>+~()@]+/g;6 1y(s){8(S.l(s))s=" "+s;5 s.P(20)||[]};7 W=/\\s*([\\s>+~(),]|^|$)\\s*/g;7 I=/([\\s>+~,]|[^(]\\+|^)([#.:@])/g;7 18=6(s){5 s.O(W,"$1").O(I,"$1*$2")};7 1u={1Z:6(){5"\'"},P:/^(\'[^\']*\')|("[^"]*")$/,l:6(s){5 o.P.l(s)},1S:6(s){5 o.l(s)?s:o+s+o},1Y:6(s){5 o.l(s)?s.Z(1,-1):s}};7 1s=6(t){5 1u.1Y(t)};7 E=/([\\/()[\\]?{}|*+-])/g;6 R(s){5 s.O(E,"\\\\$1")};x.15("1j-2H",6(){D[">"]=6(r,f,t,n){7 e,i,j;9(i=0;i=c);5(c%m)==s}});x.15("1j-2m",6(){U=1i("L;/*@2l@8(@\\2k)U=K@2j@*/");8(!U){X=6(e,t,n){5 n?e.2i("*",t):e.X(t)};14=6(e,n){5!n||(n=="*")||(e.2h==n)};1h=1g.1I?6(e){5/1J/i.l(Q(e).1I)}:6(e){5 Q(e).1H.1f!="2g"};1e=6(e){5 e.2f||e.1G||1b(e)};6 1b(e){7 t="",n,i;9(i=0;(n=e.1F[i]);i++){1d(n.1c){F 11:F 1:t+=1b(n);1a;F 3:t+=n.2e;1a}}5 t}}});19=K;5 x}();',62,190,'|||||return|function|var|if|for||||||||pseudoClasses||||test|||this||AttributeSelector|||||||cssQuery|length|push|fr|id||selectors||case|nextElementSibling|while||tests|true|false|thisElement||replace|match|getDocument|regEscape||attributeSelectors|isMSIE|cache||getElementsByTagName|isNaN|slice|child||new|getAttribute|compareNamespace|addModule|previousElementSibling|compareTagName|parseSelector|loaded|break|_0|nodeType|switch|getTextContent|tagName|document|isXML|eval|css|_1|split|ch|parentNode|childElements|nthChild|disabled|firstElementChild|getText|RegExp|Quote|x22|PREFIX|lang|_2|arguments|else|all|links|version|se|childNodes|innerText|documentElement|contentType|xml|parseInt|indeterminate|checked|last|nth|lastElementChild|parse|_3|add|href|String|className|create|NS_IE|remove|toString|ST|select|Array|null|_4|mimeType|lastChild|firstChild|continue|modules|delete|join|caching|error|nodeValue|textContent|HTML|prefix|getElementsByTagNameNS|end|x5fwin32|cc_on|standard||odd|even|enabled|hash|location|target|not|only|empty|root|contains|level3|outerHTML|htmlFor|class|toLowerCase|Function|name|first|level2|prototype|item|scopeName|toUpperCase|ownerDocument|Document|XML|Boolean|URL|unknown|typeof|nextSibling|previousSibling|visited|link|valueOf|clearCache|catch|concat|constructor|callee|try'.split('|'),0,{})) PK4i7tDnn#kss/core/kukit/3rd_party/sarissa.js/** * ==================================================================== * About * ==================================================================== * Sarissa is an ECMAScript library acting as a cross-browser wrapper for native XML APIs. * The library supports Gecko based browsers like Mozilla and Firefox, * Internet Explorer (5.5+ with MSXML3.0+), Konqueror, Safari and a little of Opera * @version 0.9.7.6 * @author: Manos Batsis, mailto: mbatsis at users full stop sourceforge full stop net * ==================================================================== * Licence * ==================================================================== * Sarissa is free software distributed under the GNU GPL version 2 (see gpl.txt) or higher, * GNU LGPL version 2.1 (see lgpl.txt) or higher and Apache Software License 2.0 or higher * (see asl.txt). This means you can choose one of the three and use that if you like. If * you make modifications under the ASL, i would appreciate it if you submitted those. * In case your copy of Sarissa does not include the license texts, you may find * them online in various formats at http://www.gnu.org and * http://www.apache.org. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /** *

    Sarissa is a utility class. Provides "static" methods for DOMDocument, * DOM Node serialization to XML strings and other utility goodies.

    * @constructor */ function Sarissa(){}; Sarissa.PARSED_OK = "Document contains no parsing errors"; Sarissa.PARSED_EMPTY = "Document is empty"; Sarissa.PARSED_UNKNOWN_ERROR = "Not well-formed or other error"; var _sarissa_iNsCounter = 0; var _SARISSA_IEPREFIX4XSLPARAM = ""; var _SARISSA_HAS_DOM_IMPLEMENTATION = document.implementation && true; var _SARISSA_HAS_DOM_CREATE_DOCUMENT = _SARISSA_HAS_DOM_IMPLEMENTATION && document.implementation.createDocument; var _SARISSA_HAS_DOM_FEATURE = _SARISSA_HAS_DOM_IMPLEMENTATION && document.implementation.hasFeature; var _SARISSA_IS_MOZ = _SARISSA_HAS_DOM_CREATE_DOCUMENT && _SARISSA_HAS_DOM_FEATURE; var _SARISSA_IS_SAFARI = (navigator.userAgent && navigator.vendor && (navigator.userAgent.toLowerCase().indexOf("applewebkit") != -1 || navigator.vendor.indexOf("Apple") != -1)); var _SARISSA_IS_IE = document.all && window.ActiveXObject && navigator.userAgent.toLowerCase().indexOf("msie") > -1 && navigator.userAgent.toLowerCase().indexOf("opera") == -1; if(!window.Node || !Node.ELEMENT_NODE){ Node = {ELEMENT_NODE: 1, ATTRIBUTE_NODE: 2, TEXT_NODE: 3, CDATA_SECTION_NODE: 4, ENTITY_REFERENCE_NODE: 5, ENTITY_NODE: 6, PROCESSING_INSTRUCTION_NODE: 7, COMMENT_NODE: 8, DOCUMENT_NODE: 9, DOCUMENT_TYPE_NODE: 10, DOCUMENT_FRAGMENT_NODE: 11, NOTATION_NODE: 12}; }; if(typeof XMLDocument == "undefined" && typeof Document !="undefined"){ XMLDocument = Document; } // IE initialization if(_SARISSA_IS_IE){ // for XSLT parameter names, prefix needed by IE _SARISSA_IEPREFIX4XSLPARAM = "xsl:"; // used to store the most recent ProgID available out of the above var _SARISSA_DOM_PROGID = ""; var _SARISSA_XMLHTTP_PROGID = ""; var _SARISSA_DOM_XMLWRITER = ""; /** * Called when the Sarissa_xx.js file is parsed, to pick most recent * ProgIDs for IE, then gets destroyed. * @private * @param idList an array of MSXML PROGIDs from which the most recent will be picked for a given object * @param enabledList an array of arrays where each array has two items; the index of the PROGID for which a certain feature is enabled */ Sarissa.pickRecentProgID = function (idList){ // found progID flag var bFound = false; for(var i=0; i < idList.length && !bFound; i++){ try{ var oDoc = new ActiveXObject(idList[i]); o2Store = idList[i]; bFound = true; }catch (objException){ // trap; try next progID }; }; if (!bFound) { throw "Could not retreive a valid progID of Class: " + idList[idList.length-1]+". (original exception: "+e+")"; }; idList = null; return o2Store; }; // pick best available MSXML progIDs _SARISSA_DOM_PROGID = null; _SARISSA_THREADEDDOM_PROGID = null; _SARISSA_XSLTEMPLATE_PROGID = null; _SARISSA_XMLHTTP_PROGID = null; if(!window.XMLHttpRequest){ /** * Emulate XMLHttpRequest * @constructor */ XMLHttpRequest = function() { if(!_SARISSA_XMLHTTP_PROGID){ _SARISSA_XMLHTTP_PROGID = Sarissa.pickRecentProgID(["Msxml2.XMLHTTP.6.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"]); }; return new ActiveXObject(_SARISSA_XMLHTTP_PROGID); }; }; // we dont need this anymore //============================================ // Factory methods (IE) //============================================ // see non-IE version Sarissa.getDomDocument = function(sUri, sName){ if(!_SARISSA_DOM_PROGID){ _SARISSA_DOM_PROGID = Sarissa.pickRecentProgID(["Msxml2.DOMDocument.6.0", "Msxml2.DOMDocument.3.0", "MSXML2.DOMDocument", "MSXML.DOMDocument", "Microsoft.XMLDOM"]); }; var oDoc = new ActiveXObject(_SARISSA_DOM_PROGID); // if a root tag name was provided, we need to load it in the DOM object if (sName){ // create an artifical namespace prefix // or reuse existing prefix if applicable var prefix = ""; if(sUri){ if(sName.indexOf(":") > 1){ prefix = sName.substring(0, sName.indexOf(":")); sName = sName.substring(sName.indexOf(":")+1); }else{ prefix = "a" + (_sarissa_iNsCounter++); }; }; // use namespaces if a namespace URI exists if(sUri){ oDoc.loadXML('<' + prefix+':'+sName + " xmlns:" + prefix + "=\"" + sUri + "\"" + " />"); } else { oDoc.loadXML('<' + sName + " />"); }; }; return oDoc; }; // see non-IE version Sarissa.getParseErrorText = function (oDoc) { var parseErrorText = Sarissa.PARSED_OK; if(oDoc.parseError.errorCode != 0){ parseErrorText = "XML Parsing Error: " + oDoc.parseError.reason + "\nLocation: " + oDoc.parseError.url + "\nLine Number " + oDoc.parseError.line + ", Column " + oDoc.parseError.linepos + ":\n" + oDoc.parseError.srcText + "\n"; for(var i = 0; i < oDoc.parseError.linepos;i++){ parseErrorText += "-"; }; parseErrorText += "^\n"; } else if(oDoc.documentElement == null){ parseErrorText = Sarissa.PARSED_EMPTY; }; return parseErrorText; }; // see non-IE version Sarissa.setXpathNamespaces = function(oDoc, sNsSet) { oDoc.setProperty("SelectionLanguage", "XPath"); oDoc.setProperty("SelectionNamespaces", sNsSet); }; /** * Basic implementation of Mozilla's XSLTProcessor for IE. * Reuses the same XSLT stylesheet for multiple transforms * @constructor */ XSLTProcessor = function(){ if(!_SARISSA_XSLTEMPLATE_PROGID){ _SARISSA_XSLTEMPLATE_PROGID = Sarissa.pickRecentProgID(["Msxml2.XSLTemplate.6.0", "MSXML2.XSLTemplate.3.0"]); }; this.template = new ActiveXObject(_SARISSA_XSLTEMPLATE_PROGID); this.processor = null; }; /** * Imports the given XSLT DOM and compiles it to a reusable transform * Note: If the stylesheet was loaded from a URL and contains xsl:import or xsl:include elements,it will be reloaded to resolve those * @argument xslDoc The XSLT DOMDocument to import */ XSLTProcessor.prototype.importStylesheet = function(xslDoc){ if(!_SARISSA_THREADEDDOM_PROGID){ _SARISSA_THREADEDDOM_PROGID = Sarissa.pickRecentProgID(["MSXML2.FreeThreadedDOMDocument.6.0", "MSXML2.FreeThreadedDOMDocument.3.0"]); }; xslDoc.setProperty("SelectionLanguage", "XPath"); xslDoc.setProperty("SelectionNamespaces", "xmlns:xsl='http://www.w3.org/1999/XSL/Transform'"); // convert stylesheet to free threaded var converted = new ActiveXObject(_SARISSA_THREADEDDOM_PROGID); // make included/imported stylesheets work if exist and xsl was originally loaded from url if(xslDoc.url && xslDoc.selectSingleNode("//xsl:*[local-name() = 'import' or local-name() = 'include']") != null){ converted.async = false; if (_SARISSA_THREADEDDOM_PROGID == "MSXML2.FreeThreadedDOMDocument.6.0") { converted.setProperty("AllowDocumentFunction", true); converted.resolveExternals = true; } converted.load(xslDoc.url); } else { converted.loadXML(xslDoc.xml); }; converted.setProperty("SelectionNamespaces", "xmlns:xsl='http://www.w3.org/1999/XSL/Transform'"); var output = converted.selectSingleNode("//xsl:output"); this.outputMethod = output ? output.getAttribute("method") : "html"; this.template.stylesheet = converted; this.processor = this.template.createProcessor(); // for getParameter and clearParameters this.paramsSet = new Array(); }; /** * Transform the given XML DOM and return the transformation result as a new DOM document * @argument sourceDoc The XML DOMDocument to transform * @return The transformation result as a DOM Document */ XSLTProcessor.prototype.transformToDocument = function(sourceDoc){ // fix for bug 1549749 if(_SARISSA_THREADEDDOM_PROGID){ this.processor.input=sourceDoc; var outDoc=new ActiveXObject(_SARISSA_DOM_PROGID); this.processor.output=outDoc; this.processor.transform(); return outDoc; } else{ if(!_SARISSA_DOM_XMLWRITER){ _SARISSA_DOM_XMLWRITER = Sarissa.pickRecentProgID(["Msxml2.MXXMLWriter.6.0", "Msxml2.MXXMLWriter.3.0", "MSXML2.MXXMLWriter", "MSXML.MXXMLWriter", "Microsoft.XMLDOM"]); }; this.processor.input = sourceDoc; var outDoc = new ActiveXObject(_SARISSA_DOM_XMLWRITER); this.processor.output = outDoc; this.processor.transform(); var oDoc = new ActiveXObject(_SARISSA_DOM_PROGID); oDoc.loadXML(outDoc.output+""); return oDoc; }; }; /** * Transform the given XML DOM and return the transformation result as a new DOM fragment. * Note: The xsl:output method must match the nature of the owner document (XML/HTML). * @argument sourceDoc The XML DOMDocument to transform * @argument ownerDoc The owner of the result fragment * @return The transformation result as a DOM Document */ XSLTProcessor.prototype.transformToFragment = function (sourceDoc, ownerDoc) { this.processor.input = sourceDoc; this.processor.transform(); var s = this.processor.output; var f = ownerDoc.createDocumentFragment(); if (this.outputMethod == 'text') { f.appendChild(ownerDoc.createTextNode(s)); } else if (ownerDoc.body && ownerDoc.body.innerHTML) { var container = ownerDoc.createElement('div'); container.innerHTML = s; while (container.hasChildNodes()) { f.appendChild(container.firstChild); } } else { var oDoc = new ActiveXObject(_SARISSA_DOM_PROGID); if (s.substring(0, 5) == '') + 2); } var xml = ''.concat('', s, ''); oDoc.loadXML(xml); var container = oDoc.documentElement; while (container.hasChildNodes()) { f.appendChild(container.firstChild); } } return f; }; /** * Set global XSLT parameter of the imported stylesheet * @argument nsURI The parameter namespace URI * @argument name The parameter base name * @argument value The new parameter value */ XSLTProcessor.prototype.setParameter = function(nsURI, name, value){ // nsURI is optional but cannot be null if(nsURI){ this.processor.addParameter(name, value, nsURI); }else{ this.processor.addParameter(name, value); }; // update updated params for getParameter if(!this.paramsSet[""+nsURI]){ this.paramsSet[""+nsURI] = new Array(); }; this.paramsSet[""+nsURI][name] = value; }; /** * Gets a parameter if previously set by setParameter. Returns null * otherwise * @argument name The parameter base name * @argument value The new parameter value * @return The parameter value if reviously set by setParameter, null otherwise */ XSLTProcessor.prototype.getParameter = function(nsURI, name){ nsURI = nsURI || ""; if(this.paramsSet[nsURI] && this.paramsSet[nsURI][name]){ return this.paramsSet[nsURI][name]; }else{ return null; }; }; /** * Clear parameters (set them to default values as defined in the stylesheet itself) */ XSLTProcessor.prototype.clearParameters = function(){ for(var nsURI in this.paramsSet){ for(var name in this.paramsSet[nsURI]){ if(nsURI){ this.processor.addParameter(name, null, nsURI); }else{ this.processor.addParameter(name, null); }; }; }; this.paramsSet = new Array(); }; }else{ /* end IE initialization, try to deal with real browsers now ;-) */ if(_SARISSA_HAS_DOM_CREATE_DOCUMENT){ /** *

    Ensures the document was loaded correctly, otherwise sets the * parseError to -1 to indicate something went wrong. Internal use

    * @private */ Sarissa.__handleLoad__ = function(oDoc){ Sarissa.__setReadyState__(oDoc, 4); }; /** *

    Attached by an event handler to the load event. Internal use.

    * @private */ _sarissa_XMLDocument_onload = function(){ Sarissa.__handleLoad__(this); }; /** *

    Sets the readyState property of the given DOM Document object. * Internal use.

    * @private * @argument oDoc the DOM Document object to fire the * readystatechange event * @argument iReadyState the number to change the readystate property to */ Sarissa.__setReadyState__ = function(oDoc, iReadyState){ oDoc.readyState = iReadyState; oDoc.readystate = iReadyState; if (oDoc.onreadystatechange != null && typeof oDoc.onreadystatechange == "function") oDoc.onreadystatechange(); }; Sarissa.getDomDocument = function(sUri, sName){ var oDoc = document.implementation.createDocument(sUri?sUri:null, sName?sName:null, null); if(!oDoc.onreadystatechange){ /** *

    Emulate IE's onreadystatechange attribute

    */ oDoc.onreadystatechange = null; }; if(!oDoc.readyState){ /** *

    Emulates IE's readyState property, which always gives an integer from 0 to 4:

    *
    • 1 == LOADING,
    • *
    • 2 == LOADED,
    • *
    • 3 == INTERACTIVE,
    • *
    • 4 == COMPLETED
    */ oDoc.readyState = 0; }; oDoc.addEventListener("load", _sarissa_XMLDocument_onload, false); return oDoc; }; if(window.XMLDocument){ // do nothing }// TODO: check if the new document has content before trying to copynodes, check for error handling in DOM 3 LS else if(_SARISSA_HAS_DOM_FEATURE && window.Document && !Document.prototype.load && document.implementation.hasFeature('LS', '3.0')){ //Opera 9 may get the XPath branch which gives creates XMLDocument, therefore it doesn't reach here which is good /** *

    Factory method to obtain a new DOM Document object

    * @argument sUri the namespace of the root node (if any) * @argument sUri the local name of the root node (if any) * @returns a new DOM Document */ Sarissa.getDomDocument = function(sUri, sName){ var oDoc = document.implementation.createDocument(sUri?sUri:null, sName?sName:null, null); return oDoc; }; } else { Sarissa.getDomDocument = function(sUri, sName){ var oDoc = document.implementation.createDocument(sUri?sUri:null, sName?sName:null, null); // looks like safari does not create the root element for some unknown reason if(oDoc && (sUri || sName) && !oDoc.documentElement){ oDoc.appendChild(oDoc.createElementNS(sUri, sName)); }; return oDoc; }; }; };//if(_SARISSA_HAS_DOM_CREATE_DOCUMENT) }; //========================================== // Common stuff //========================================== if(!window.DOMParser){ if(_SARISSA_IS_SAFARI){ /* * DOMParser is a utility class, used to construct DOMDocuments from XML strings * @constructor */ DOMParser = function() { }; /** * Construct a new DOM Document from the given XMLstring * @param sXml the given XML string * @param contentType the content type of the document the given string represents (one of text/xml, application/xml, application/xhtml+xml). * @return a new DOM Document from the given XML string */ DOMParser.prototype.parseFromString = function(sXml, contentType){ var xmlhttp = new XMLHttpRequest(); xmlhttp.open("GET", "data:text/xml;charset=utf-8," + encodeURIComponent(sXml), false); xmlhttp.send(null); return xmlhttp.responseXML; }; }else if(Sarissa.getDomDocument && Sarissa.getDomDocument() && Sarissa.getDomDocument(null, "bar").xml){ DOMParser = function() { }; DOMParser.prototype.parseFromString = function(sXml, contentType){ var doc = Sarissa.getDomDocument(); doc.loadXML(sXml); return doc; }; }; }; if((typeof(document.importNode) == "undefined") && _SARISSA_IS_IE){ try{ /** * Implementation of importNode for the context window document in IE * @param oNode the Node to import * @param bChildren whether to include the children of oNode * @returns the imported node for further use */ document.importNode = function(oNode, bChildren){ var tmp; if(oNode.nodeName == "tbody" || oNode.nodeName == "tr"){ tmp = document.createElement("table"); } else if(oNode.nodeName == "td"){ tmp = document.createElement("tr"); } else if(oNode.nodeName == "option"){ tmp = document.createElement("select"); } else{ tmp = document.createElement("div"); }; if(bChildren){ tmp.innerHTML = oNode.xml ? oNode.xml : oNode.outerHTML; }else{ tmp.innerHTML = oNode.xml ? oNode.cloneNode(false).xml : oNode.cloneNode(false).outerHTML; }; return tmp.getElementsByTagName("*")[0]; }; }catch(e){ }; }; if(!Sarissa.getParseErrorText){ /** *

    Returns a human readable description of the parsing error. Usefull * for debugging. Tip: append the returned error string in a <pre> * element if you want to render it.

    *

    Many thanks to Christian Stocker for the initial patch.

    * @argument oDoc The target DOM document * @returns The parsing error description of the target Document in * human readable form (preformated text) */ Sarissa.getParseErrorText = function (oDoc){ var parseErrorText = Sarissa.PARSED_OK; if(!oDoc.documentElement){ parseErrorText = Sarissa.PARSED_EMPTY; } else if(oDoc.documentElement.tagName == "parsererror"){ parseErrorText = oDoc.documentElement.firstChild.data; parseErrorText += "\n" + oDoc.documentElement.firstChild.nextSibling.firstChild.data; } else if(oDoc.getElementsByTagName("parsererror").length > 0){ var parsererror = oDoc.getElementsByTagName("parsererror")[0]; parseErrorText = Sarissa.getText(parsererror, true)+"\n"; } else if(oDoc.parseError && oDoc.parseError.errorCode != 0){ parseErrorText = Sarissa.PARSED_UNKNOWN_ERROR; }; return parseErrorText; }; }; Sarissa.getText = function(oNode, deep){ var s = ""; var nodes = oNode.childNodes; for(var i=0; i < nodes.length; i++){ var node = nodes[i]; var nodeType = node.nodeType; if(nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE){ s += node.data; } else if(deep == true && (nodeType == Node.ELEMENT_NODE || nodeType == Node.DOCUMENT_NODE || nodeType == Node.DOCUMENT_FRAGMENT_NODE)){ s += Sarissa.getText(node, true); }; }; return s; }; if(!window.XMLSerializer && Sarissa.getDomDocument && Sarissa.getDomDocument("","foo", null).xml){ /** * Utility class to serialize DOM Node objects to XML strings * @constructor */ XMLSerializer = function(){}; /** * Serialize the given DOM Node to an XML string * @param oNode the DOM Node to serialize */ XMLSerializer.prototype.serializeToString = function(oNode) { return oNode.xml; }; }; /** * strips tags from a markup string */ Sarissa.stripTags = function (s) { return s.replace(/<[^>]+>/g,""); }; /** *

    Deletes all child nodes of the given node

    * @argument oNode the Node to empty */ Sarissa.clearChildNodes = function(oNode) { // need to check for firstChild due to opera 8 bug with hasChildNodes while(oNode.firstChild) { oNode.removeChild(oNode.firstChild); }; }; /** *

    Copies the childNodes of nodeFrom to nodeTo

    *

    Note: The second object's original content is deleted before * the copy operation, unless you supply a true third parameter

    * @argument nodeFrom the Node to copy the childNodes from * @argument nodeTo the Node to copy the childNodes to * @argument bPreserveExisting whether to preserve the original content of nodeTo, default is false */ Sarissa.copyChildNodes = function(nodeFrom, nodeTo, bPreserveExisting) { if((!nodeFrom) || (!nodeTo)){ throw "Both source and destination nodes must be provided"; }; if(!bPreserveExisting){ Sarissa.clearChildNodes(nodeTo); }; var ownerDoc = nodeTo.nodeType == Node.DOCUMENT_NODE ? nodeTo : nodeTo.ownerDocument; var nodes = nodeFrom.childNodes; if(typeof(ownerDoc.importNode) != "undefined") { for(var i=0;i < nodes.length;i++) { nodeTo.appendChild(ownerDoc.importNode(nodes[i], true)); }; } else { for(var i=0;i < nodes.length;i++) { nodeTo.appendChild(nodes[i].cloneNode(true)); }; }; }; /** *

    Moves the childNodes of nodeFrom to nodeTo

    *

    Note: The second object's original content is deleted before * the move operation, unless you supply a true third parameter

    * @argument nodeFrom the Node to copy the childNodes from * @argument nodeTo the Node to copy the childNodes to * @argument bPreserveExisting whether to preserve the original content of nodeTo, default is */ Sarissa.moveChildNodes = function(nodeFrom, nodeTo, bPreserveExisting) { if((!nodeFrom) || (!nodeTo)){ throw "Both source and destination nodes must be provided"; }; if(!bPreserveExisting){ Sarissa.clearChildNodes(nodeTo); }; var nodes = nodeFrom.childNodes; // if within the same doc, just move, else copy and delete if(nodeFrom.ownerDocument == nodeTo.ownerDocument){ while(nodeFrom.firstChild){ nodeTo.appendChild(nodeFrom.firstChild); }; } else { var ownerDoc = nodeTo.nodeType == Node.DOCUMENT_NODE ? nodeTo : nodeTo.ownerDocument; if(typeof(ownerDoc.importNode) != "undefined") { for(var i=0;i < nodes.length;i++) { nodeTo.appendChild(ownerDoc.importNode(nodes[i], true)); }; }else{ for(var i=0;i < nodes.length;i++) { nodeTo.appendChild(nodes[i].cloneNode(true)); }; }; Sarissa.clearChildNodes(nodeFrom); }; }; /** *

    Serialize any object to an XML string. All properties are serialized using the property name * as the XML element name. Array elements are rendered as array-item elements, * using their index/key as the value of the key attribute.

    * @argument anyObject the object to serialize * @argument objectName a name for that object * @return the XML serializationj of the given object as a string */ Sarissa.xmlize = function(anyObject, objectName, indentSpace){ indentSpace = indentSpace?indentSpace:''; var s = indentSpace + '<' + objectName + '>'; var isLeaf = false; if(!(anyObject instanceof Object) || anyObject instanceof Number || anyObject instanceof String || anyObject instanceof Boolean || anyObject instanceof Date){ s += Sarissa.escape(""+anyObject); isLeaf = true; }else{ s += "\n"; var itemKey = ''; var isArrayItem = anyObject instanceof Array; for(var name in anyObject){ s += Sarissa.xmlize(anyObject[name], (isArrayItem?"array-item key=\""+name+"\"":name), indentSpace + " "); }; s += indentSpace; }; return s += (objectName.indexOf(' ')!=-1?"\n":"\n"); }; /** * Escape the given string chacters that correspond to the five predefined XML entities * @param sXml the string to escape */ Sarissa.escape = function(sXml){ return sXml.replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'"); }; /** * Unescape the given string. This turns the occurences of the predefined XML * entities to become the characters they represent correspond to the five predefined XML entities * @param sXml the string to unescape */ Sarissa.unescape = function(sXml){ return sXml.replace(/'/g,"'") .replace(/"/g,"\"") .replace(/>/g,">") .replace(/</g,"<") .replace(/&/g,"&"); }; // EOF PK4i7i2kss/core/kukit/3rd_party/firebuglite/errorIcon.pngPNG  IHDRH-gAMAOX2tEXtSoftwareAdobe ImageReadyqe<[IDATx|=KAgF4 : ئZ6)%EkRX,D!*_b}f'';;3offostSfA Ly]vE2*nvfaOq0 )ضI`>̔rb0&x!RD.gWbm> C"c6;hRK5mq kF捹ﰥ(r.Mp>IWChg٧A2W~ +ZW+\ n6¶}"p LOsF׈oNE2z 7~'ջ+Ѻ#A>8Es1IENDB`PK4i7d 0kss/core/kukit/3rd_party/firebuglite/firebug.css html, body { margin: 0; background: #FFFFFF; font-family: Lucida Grande, Tahoma, sans-serif; font-size: 11px; overflow: hidden; } a { text-decoration: none; } a:hover { text-decoration: underline; } .toolbar { height: 14px; border-top: 1px solid ThreeDHighlight; border-bottom: 1px solid ThreeDShadow; padding: 2px 6px; background: ThreeDFace; } .toolbarRight { position: absolute; top: 4px; right: 6px; } #log { overflow: auto; position: absolute; left: 0; width: 100%; } #commandLine { position: absolute; bottom: 0; left: 0; width: 100%; height: 18px; border: none; border-top: 1px solid ThreeDShadow; } /************************************************************************************************/ .logRow { position: relative; border-bottom: 1px solid #D7D7D7; padding: 2px 4px 1px 6px; background-color: #FFFFFF; } .logRow-command { font-family: Monaco, monospace; color: blue; } .objectBox-null { padding: 0 2px; border: 1px solid #666666; background-color: #888888; color: #FFFFFF; } .objectBox-string { font-family: Monaco, monospace; color: red; white-space: pre; } .objectBox-number { color: #000088; } .objectBox-function { font-family: Monaco, monospace; color: DarkGreen; } .objectBox-object { color: DarkGreen; font-weight: bold; } /************************************************************************************************/ .logRow-info, .logRow-error, .logRow-warning { background: #FFFFFF no-repeat 2px 2px; padding-left: 20px; padding-bottom: 3px; } .logRow-info { background-image: url(infoIcon.png); } .logRow-warning { background-color: cyan; background-image: url(warningIcon.png); } .logRow-error { background-color: LightYellow; background-image: url(errorIcon.png); } .errorMessage { vertical-align: top; color: #FF0000; } .objectBox-sourceLink { position: absolute; right: 4px; top: 2px; padding-left: 8px; font-family: Lucida Grande, sans-serif; font-weight: bold; color: #0000FF; } /************************************************************************************************/ .logRow-group { background: #EEEEEE; border-bottom: none; } .logGroup { background: #EEEEEE; } .logGroupBox { margin-left: 24px; border-top: 1px solid #D7D7D7; border-left: 1px solid #D7D7D7; } /************************************************************************************************/ .selectorTag, .selectorId, .selectorClass { font-family: Monaco, monospace; font-weight: normal; } .selectorTag { color: #0000FF; } .selectorId { color: DarkBlue; } .selectorClass { color: red; } /************************************************************************************************/ .objectBox-element { font-family: Monaco, monospace; color: #000088; } .nodeChildren { margin-left: 16px; } .nodeTag { color: blue; } .nodeValue { color: #FF0000; font-weight: normal; } .nodeText, .nodeComment { margin: 0 2px; vertical-align: top; } .nodeText { color: #333333; } .nodeComment { color: DarkGreen; } /************************************************************************************************/ .propertyNameCell { vertical-align: top; } .propertyName { font-weight: bold; } PK4i7w,II1kss/core/kukit/3rd_party/firebuglite/firebug.html Firebug
    PK4i7*JJ/kss/core/kukit/3rd_party/firebuglite/firebug.js if (!("console" in window) || !("firebug" in console)) { (function() { window.console = { log: function() { logFormatted(arguments, ""); }, debug: function() { logFormatted(arguments, "debug"); }, info: function() { logFormatted(arguments, "info"); }, warn: function() { logFormatted(arguments, "warning"); }, error: function() { logFormatted(arguments, "error"); }, assert: function(truth, message) { if (!truth) { var args = []; for (var i = 1; i < arguments.length; ++i) args.push(arguments[i]); logFormatted(args.length ? args : ["Assertion Failure"], "error"); throw message ? message : "Assertion Failure"; } }, dir: function(object) { var html = []; var pairs = []; for (var name in object) { try { pairs.push([name, object[name]]); } catch (exc) { } } pairs.sort(function(a, b) { return a[0] < b[0] ? -1 : 1; }); html.push('
    '); for (var i = 0; i < pairs.length; ++i) { var name = pairs[i][0], value = pairs[i][1]; html.push('', '', ''); } html.push('
    ', escapeHTML(name), ''); appendObject(value, html); html.push('
    '); logRow(html, "dir"); }, dirxml: function(node) { var html = []; appendNode(node, html); logRow(html, "dirxml"); }, group: function() { logRow(arguments, "group", pushGroup); }, groupEnd: function() { logRow(arguments, "", popGroup); }, time: function(name) { timeMap[name] = (new Date()).getTime(); }, timeEnd: function(name) { if (name in timeMap) { var delta = (new Date()).getTime() - timeMap[name]; logFormatted([name+ ":", delta+"ms"]); delete timeMap[name]; } }, count: function() { this.warn(["count() not supported."]); }, trace: function() { this.warn(["trace() not supported."]); }, profile: function() { this.warn(["profile() not supported."]); }, profileEnd: function() { }, clear: function() { consoleBody.innerHTML = ""; }, open: function() { toggleConsole(true); }, close: function() { if (frameVisible) toggleConsole(); } }; // ******************************************************************************************** var consoleFrame = null; var consoleBody = null; var commandLine = null; var frameVisible = false; var messageQueue = []; var groupStack = []; var timeMap = {}; var clPrefix = ">>> "; var isFirefox = navigator.userAgent.indexOf("Firefox") != -1; var isIE = navigator.userAgent.indexOf("MSIE") != -1; var isOpera = navigator.userAgent.indexOf("Opera") != -1; var isSafari = navigator.userAgent.indexOf("AppleWebKit") != -1; // ******************************************************************************************** function toggleConsole(forceOpen) { frameVisible = forceOpen || !frameVisible; if (consoleFrame) consoleFrame.style.visibility = frameVisible ? "visible" : "hidden"; else waitForBody(); } function focusCommandLine() { toggleConsole(true); if (commandLine) commandLine.focus(); } function waitForBody() { if (document.body) createFrame(); else setTimeout(waitForBody, 200); } function createFrame() { if (consoleFrame) return; window.onFirebugReady = function(doc) { window.onFirebugReady = null; var toolbar = doc.getElementById("toolbar"); toolbar.onmousedown = onSplitterMouseDown; commandLine = doc.getElementById("commandLine"); addEvent(commandLine, "keydown", onCommandLineKeyDown); addEvent(doc, isIE || isSafari ? "keydown" : "keypress", onKeyDown); consoleBody = doc.getElementById("log"); layout(); flush(); } var baseURL = getFirebugURL(); consoleFrame = document.createElement("iframe"); consoleFrame.setAttribute("src", baseURL+"/firebug.html"); consoleFrame.setAttribute("frameBorder", "0"); consoleFrame.style.visibility = (frameVisible ? "visible" : "hidden"); consoleFrame.style.zIndex = "2147483647"; consoleFrame.style.position = "fixed"; consoleFrame.style.width = "100%"; consoleFrame.style.left = "0"; consoleFrame.style.bottom = "0"; consoleFrame.style.height = "200px"; document.body.appendChild(consoleFrame); } function getFirebugURL() { var scripts = document.getElementsByTagName("script"); for (var i = 0; i < scripts.length; ++i) { if (scripts[i].src.indexOf("firebug.js") != -1) { var lastSlash = scripts[i].src.lastIndexOf("/"); return scripts[i].src.substr(0, lastSlash); } } } function evalCommandLine() { var text = commandLine.value; commandLine.value = ""; logRow([clPrefix, text], "command"); var value; try { value = eval(text); } catch (exc) { } console.log(value); } function layout() { var toolbar = consoleBody.ownerDocument.getElementById("toolbar"); var height = consoleFrame.offsetHeight - (toolbar.offsetHeight + commandLine.offsetHeight); consoleBody.style.top = toolbar.offsetHeight + "px"; consoleBody.style.height = height + "px"; commandLine.style.top = (consoleFrame.offsetHeight - commandLine.offsetHeight) + "px"; } function logRow(message, className, handler) { if (consoleBody) writeMessage(message, className, handler); else { messageQueue.push([message, className, handler]); waitForBody(); } } function flush() { var queue = messageQueue; messageQueue = []; for (var i = 0; i < queue.length; ++i) writeMessage(queue[i][0], queue[i][1], queue[i][2]); } function writeMessage(message, className, handler) { var isScrolledToBottom = consoleBody.scrollTop + consoleBody.offsetHeight >= consoleBody.scrollHeight; if (!handler) handler = writeRow; handler(message, className); if (isScrolledToBottom) consoleBody.scrollTop = consoleBody.scrollHeight - consoleBody.offsetHeight; } function appendRow(row) { var container = groupStack.length ? groupStack[groupStack.length-1] : consoleBody; container.appendChild(row); } function writeRow(message, className) { var row = consoleBody.ownerDocument.createElement("div"); row.className = "logRow" + (className ? " logRow-"+className : ""); row.innerHTML = message.join(""); appendRow(row); } function pushGroup(message, className) { logFormatted(message, className); var groupRow = consoleBody.ownerDocument.createElement("div"); groupRow.className = "logGroup"; var groupRowBox = consoleBody.ownerDocument.createElement("div"); groupRowBox.className = "logGroupBox"; groupRow.appendChild(groupRowBox); appendRow(groupRowBox); groupStack.push(groupRowBox); } function popGroup() { groupStack.pop(); } // ******************************************************************************************** function logFormatted(objects, className) { var html = []; var format = objects[0]; var objIndex = 0; if (typeof(format) != "string") { format = ""; objIndex = -1; } var parts = parseFormat(format); for (var i = 0; i < parts.length; ++i) { var part = parts[i]; if (part && typeof(part) == "object") { var object = objects[++objIndex]; part.appender(object, html); } else appendText(part, html); } for (var i = objIndex+1; i < objects.length; ++i) { appendText(" ", html); var object = objects[i]; if (typeof(object) == "string") appendText(object, html); else appendObject(object, html); } logRow(html, className); } function parseFormat(format) { var parts = []; var reg = /((^%|[^\\]%)(\d+)?(\.)([a-zA-Z]))|((^%|[^\\]%)([a-zA-Z]))/; var appenderMap = {s: appendText, d: appendInteger, i: appendInteger, f: appendFloat}; for (var m = reg.exec(format); m; m = reg.exec(format)) { var type = m[8] ? m[8] : m[5]; var appender = type in appenderMap ? appenderMap[type] : appendObject; var precision = m[3] ? parseInt(m[3]) : (m[4] == "." ? -1 : 0); parts.push(format.substr(0, m[0][0] == "%" ? m.index : m.index+1)); parts.push({appender: appender, precision: precision}); format = format.substr(m.index+m[0].length); } parts.push(format); return parts; } function escapeHTML(value) { function replaceChars(ch) { switch (ch) { case "<": return "<"; case ">": return ">"; case "&": return "&"; case "'": return "'"; case '"': return """; } return "?"; }; return String(value).replace(/[<>&"']/g, replaceChars); } function objectToString(object) { try { return object+""; } catch (exc) { return null; } } // ******************************************************************************************** function appendText(object, html) { html.push(escapeHTML(objectToString(object))); } function appendNull(object, html) { html.push('', escapeHTML(objectToString(object)), ''); } function appendString(object, html) { html.push('"', escapeHTML(objectToString(object)), '"'); } function appendInteger(object, html) { html.push('', escapeHTML(objectToString(object)), ''); } function appendFloat(object, html) { html.push('', escapeHTML(objectToString(object)), ''); } function appendFunction(object, html) { var reName = /function ?(.*?)\(/; var m = reName.exec(objectToString(object)); var name = m ? m[1] : "function"; html.push('', escapeHTML(name), '()'); } function appendObject(object, html) { try { if (object == undefined) appendNull("undefined", html); else if (object == null) appendNull("null", html); else if (typeof object == "string") appendString(object, html); else if (typeof object == "number") appendInteger(object, html); else if (typeof object == "function") appendFunction(object, html); else if (object.nodeType == 1) appendSelector(object, html); else if (typeof object == "object") appendObjectFormatted(object, html); else appendText(object, html); } catch (exc) { } } function appendObjectFormatted(object, html) { var text = objectToString(object); var reObject = /\[object (.*?)\]/; var m = reObject.exec(text); html.push('', m ? m[1] : text, '') } function appendSelector(object, html) { html.push(''); html.push('', escapeHTML(object.nodeName.toLowerCase()), ''); if (object.id) html.push('#', escapeHTML(object.id), ''); if (object.className) html.push('.', escapeHTML(object.className), ''); html.push(''); } function appendNode(node, html) { if (node.nodeType == 1) { html.push( '

    ', '<', node.nodeName.toLowerCase(), ''); for (var i = 0; i < node.attributes.length; ++i) { var attr = node.attributes[i]; if (!attr.specified) continue; html.push(' ', attr.nodeName.toLowerCase(), '="', escapeHTML(attr.nodeValue), '"') } if (node.firstChild) { html.push('>
    '); for (var child = node.firstChild; child; child = child.nextSibling) appendNode(child, html); html.push('
    </', node.nodeName.toLowerCase(), '>
    '); } else html.push('/>'); } else if (node.nodeType == 3) { html.push('
    ', escapeHTML(node.nodeValue), '
    '); } } // ******************************************************************************************** function addEvent(object, name, handler) { if (document.all) object.attachEvent("on"+name, handler); else object.addEventListener(name, handler, false); } function removeEvent(object, name, handler) { if (document.all) object.detachEvent("on"+name, handler); else object.removeEventListener(name, handler, false); } function cancelEvent(event) { if (document.all) event.cancelBubble = true; else event.stopPropagation(); } function onError(msg, href, lineNo) { var html = []; var lastSlash = href.lastIndexOf("/"); var fileName = lastSlash == -1 ? href : href.substr(lastSlash+1); html.push( '', msg, '', '' ); logRow(html, "error"); }; function onKeyDown(event) { if (event.keyCode == 123) toggleConsole(); else if ((event.keyCode == 108 || event.keyCode == 76) && event.shiftKey && (event.metaKey || event.ctrlKey)) focusCommandLine(); else return; cancelEvent(event); } function onSplitterMouseDown(event) { if (isSafari || isOpera) return; addEvent(document, "mousemove", onSplitterMouseMove); addEvent(document, "mouseup", onSplitterMouseUp); for (var i = 0; i < frames.length; ++i) { addEvent(frames[i].document, "mousemove", onSplitterMouseMove); addEvent(frames[i].document, "mouseup", onSplitterMouseUp); } } function onSplitterMouseMove(event) { var win = document.all ? event.srcElement.ownerDocument.parentWindow : event.target.ownerDocument.defaultView; var clientY = event.clientY; if (win != win.parent) clientY += win.frameElement ? win.frameElement.offsetTop : 0; var height = consoleFrame.offsetTop + consoleFrame.clientHeight; var y = height - clientY; consoleFrame.style.height = y + "px"; layout(); } function onSplitterMouseUp(event) { removeEvent(document, "mousemove", onSplitterMouseMove); removeEvent(document, "mouseup", onSplitterMouseUp); for (var i = 0; i < frames.length; ++i) { removeEvent(frames[i].document, "mousemove", onSplitterMouseMove); removeEvent(frames[i].document, "mouseup", onSplitterMouseUp); } } function onCommandLineKeyDown(event) { if (event.keyCode == 13) evalCommandLine(); else if (event.keyCode == 27) commandLine.value = ""; } window.onerror = onError; addEvent(document, isIE || isSafari ? "keydown" : "keypress", onKeyDown); if (document.documentElement.getAttribute("debug") == "true") toggleConsole(true); })(); } PK4i7B^^0kss/core/kukit/3rd_party/firebuglite/firebugx.js if (!("console" in window) || !("firebug" in console)) { var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"]; window.console = {}; for (var i = 0; i < names.length; ++i) window.console[names[i]] = function() {} }PK4i7#5(  1kss/core/kukit/3rd_party/firebuglite/infoIcon.pngPNG  IHDRH-gAMAOX2tEXtSoftwareAdobe ImageReadyqe<IDATxڌRM(DQ}Ϙ13addegkA6h,FFebeR"" a!57?{fo$ιC)`i^'# ׷l!(\fHw=(')Dz%*%$Ѩ2*fE~`y,_yxx| `$$ Q7 v>C`w;‡· ʨz0ې0d>B;QDW]-y4pǐLF^~6u`n|&4Br, EerBc#薻x;?f/rξۚs(K43 aDI\% Biuz8v 6& {s?XV0aIENDB`PK4i7U>4kss/core/kukit/3rd_party/firebuglite/warningIcon.pngPNG  IHDRH-gAMAOX2tEXtSoftwareAdobe ImageReadyqe<IDATxb? aRi@ĢP@8&$Ԕ0_I7_v.L 0<üȝ4`7XqUwζٜ>cq9𿣃ݻ`i0~rI\jBkz|W&o4q 2M3 c dHcHX VҨEB+)ajcf * `ŏ @P/XyddT l~+÷O[Wf`سYTM33 Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. PK4i74 %%kss/core/kukit/doc/README.txt===== kukit ===== More documentation... --------------------- General information o Authors: see doc/CREDITS.txt o License: see doc/LICENSE.txt License ------- Unless otherwise stated, kukit is released under the GNU GPL version 2 license. See doc/LICENSE.txt for the license text. PK4i7kss/core/kukit/doc/TODO.txtPK5i7ҮӃ!kss/core/kukit/kukit/actionreg.js/* * Copyright (c) 2005-2007 * Authors: KSS Project Contributors (see doc/CREDITS.txt) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ kukit.ar = {}; /* * class ActionRegistry * * The local event actions need to be registered here. */ kukit.ar.ActionRegistry = function () { this.content = {}; }; kukit.ar.ActionRegistry.prototype.register = function(name, func) { ;;; if (typeof(func) == 'undefined') { ;;; kukit.E = '[func] argument is mandatory when registering an action'; ;;; kukit.E += ' [ActionRegistry.register].'; ;;; throw kukit.E; ;;; } if (this.content[name]) { // Do not allow redefinition ;;; kukit.logError('Error : action [' + name + '] already registered.'); return; } this.content[name] = func; }; kukit.ar.ActionRegistry.prototype.exists = function(name) { var entry = this.content[name]; return (typeof(entry) != 'undefined'); }; kukit.ar.ActionRegistry.prototype.get = function(name) { var func = this.content[name]; if (! func) { // not found ;;; kukit.E = 'Error : undefined local action [' + name + '].'; throw kukit.E; } return func; }; kukit.actionsGlobalRegistry = new kukit.ar.ActionRegistry(); /* XXX deprecated methods, to be removed asap */ kukit.ar.actionRegistry = {}; kukit.ar.actionRegistry.register = function(name, func) { ;;; var msg='Deprecated kukit.ar.actionRegistry.register, use '; ;;; msg += 'kukit.actionsGlobalRegistry.register instead !'; ;;; kukit.logWarning(msg); kukit.actionsGlobalRegistry.register(name, func); }; PK5i7H ũ(kss/core/kukit/kukit/commandprocessor.js/* * Copyright (c) 2005-2007 * Authors: KSS Project Contributors (see doc/CREDITS.txt) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ kukit.cp = {}; /* * class CommandProcessor */ kukit.cp.CommandProcessor = function() { this.commands = new Array(); }; kukit.cp.CommandProcessor.prototype.parseCommands = function(commands, transport) { ;;; kukit.log('Parsing commands.'); ;;; kukit.logDebug('Number of commands : ' + commands.length + '.'); for (var y=0;y < commands.length;y++) { var command = commands[y]; this.parseCommand(command, transport); // If we receive an error command, we handle that separately. // We abort immediately and let the processError handler do its job. // This means that although no other commands should be in commands, // we make sure we execute none of them. var lastcommand = this.commands[this.commands.length-1]; if (lastcommand.name == 'error') { ;;; kukit.E = new kukit.err.ExplicitError(lastcommand); throw kukit.E; } } }; kukit.cp.CommandProcessor.prototype.parseCommand = function(command, transport) { var selector = ""; var params = {}; var name = ""; selector = command.getAttribute("selector"); name = command.getAttribute("name"); type = command.getAttribute("selectorType"); if (name == null) name = ""; var childNodes = command.childNodes; for (var n=0;n < childNodes.length;n++) { var childNode = childNodes[n]; if (childNode.nodeType != 1) continue; if (childNode.localName) { // (here tolerate both cases) if (childNode.localName.toLowerCase() != "param" && childNode.nodeName.toLowerCase() != "kukit:param") { throw 'Bad payload, expected param'; } } else { //IE does not know DOM2 if (childNode.nodeName.toLowerCase() != "kukit:param") { throw 'Bad payload, expected kukit:param'; } } data = childNode.getAttribute('name'); if (data != null) { // Decide if we have a string or a dom parameter var childCount = childNode.childNodes.length; var result; if (childCount == 0) { // We take this a string (although this could be dom) result = ''; } else if (childCount == 1 && childNode.firstChild.nodeType == 3) { // we have a single text node result = childNode.firstChild.nodeValue; } else { // dom result = childNode; } params[data] = result; } else { throw 'Bad payload, expected attribute "name"'; } } var command = new kukit.cr.makeCommand(selector, name, type, params, transport); this.addCommand(command); }; kukit.cp.CommandProcessor.prototype.addCommand = function(command) { this.commands[this.commands.length] = command; }; kukit.cp.CommandProcessor.prototype.executeCommands = function(oper) { kukit.engine.beginSetupEventsCollection(); // node, eventRule, binderInstance are given on oper, in case // the command was called up from an event if (typeof(oper) == 'undefined' || oper == null) { oper = new kukit.op.Oper(); } var commands = this.commands; for (var y=0;y < commands.length;y++) { var command = commands[y]; ;;; try { command.execute(oper); ;;; } catch (e) { ;;; if (e.name == 'RuleMergeError' || e.name == 'EventBindError') { ;;; throw(e); ;;; } else { ;;; // augment the error message ;;; throw new kukit.err.CommandExecutionError(e, command); ;;; } ;;; } } kukit.engine.finishSetupEventsCollection(); }; PK5i7NG66"kss/core/kukit/kukit/commandreg.js/* * Copyright (c) 2005-2007 * Authors: KSS Project Contributors (see doc/CREDITS.txt) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ /* Command registration */ kukit.cr = {}; /* * class CommandRegistry */ kukit.cr.CommandRegistry = function () { this.commands = {}; }; /* * This is the proposed way of registration, as we like all commands to be * client actions first. * * Examples: * * kukit.actionsGlobalRegistry.register('log', f1); * kukit.commandsGlobalRegistry.registerFromAction('log', * kukit.cr.makeGlobalCommand); * * kukit.actionsGlobalRegistry.register('replaceInnerHTML', f2); * kukit.commandsGlobalRegistry.registerFromAction('replaceInnerHTML', * kukit.cr.makeSelectorCommand); */ kukit.cr.CommandRegistry.prototype.registerFromAction = function(srcname, factory, name) { if (typeof(name) == 'undefined') { // allows to set a different name as the action name, // usable for backward // compatibility setups name = srcname; } // register a given action as a command, using the given vactor var f = kukit.actionsGlobalRegistry.get(srcname); factory(name, f); }; kukit.cr.CommandRegistry.prototype.register = function(name, klass) { if (this.commands[name]) { // Do not allow redefinition ;;; var msg = 'ValueError : command [' + name + '] is already registered.'; ;;; kukit.logError(msg); return; } this.commands[name] = klass; }; kukit.cr.CommandRegistry.prototype.get = function(name) { var klass = this.commands[name]; ;;; if (! klass) { ;;; // not found ;;; var msg = 'ValueError : no command registered under [' + name + '].'; ;;; kukit.logError(msg); ;;; } return klass; }; kukit.commandsGlobalRegistry = new kukit.cr.CommandRegistry(); /* XXX deprecated methods, to be removed asap */ kukit.cr.commandRegistry = {}; kukit.cr.commandRegistry.registerFromAction = function(srcname, factory, name) { ;;; var msg = 'Deprecated kukit.cr.commandRegistry.registerFromAction,'; ;;; msg += ' use kukit.commandsGlobalRegistry.registerFromAction instead! ('; ;;; msg += srcname + ')'; ;;; kukit.logWarning(msg); kukit.commandsGlobalRegistry.registerFromAction(srcname, factory, name); }; /* Command factories */ kukit.cr.makeCommand = function(selector, name, type, parms, transport) { var commandClass = kukit.commandsGlobalRegistry.get(name); var command = new commandClass(); command.selector = selector; command.name = name; command.selectorType = type; command.parms = parms; command.transport = transport; return command; }; kukit.cr._Command_execute = function(oper) { var newoper = oper.clone({ 'parms': this.parms, 'orignode': oper.node, 'node': null }); this.executeOnScope(newoper); }; kukit.cr._Command_execute_selector = function(oper) { var selfunc = kukit.selectorTypesGlobalRegistry.get(this.selectorType); // When applying the selection, the original event target will be used // as a starting point for the selection. var nodes = selfunc(this.selector, oper.orignode, {}); ;;; var printType; ;;; if (this.selectorType) { ;;; printType = this.selectorType; ;;; } else { ;;; printType = 'default ('; ;;; printType += kukit.selectorTypesGlobalRegistry.defaultSelectorType; ;;; printType += ')'; ;;; } ;;; var msg = 'Selector type [' + printType + '], selector ['; ;;; msg += this.selector + '], selected nodes [' + nodes.length + '].'; ;;; kukit.logDebug(msg); ;;; if (!nodes || nodes.length == 0) { ;;; kukit.logWarning('Selector found no nodes.'); ;;; } for (var i=0;i < nodes.length;i++) { oper.node = nodes[i]; //XXX error handling for wrong command name ;;; kukit.logDebug('[' + this.name + '] execution.'); this.executeOnSingleNode(oper); } }; kukit.cr.makeSelectorCommand = function(name, executeOnSingleNode) { var commandClass = function() {}; commandClass.prototype = { execute: kukit.cr._Command_execute, executeOnScope: kukit.cr._Command_execute_selector, executeOnSingleNode: executeOnSingleNode }; kukit.commandsGlobalRegistry.register(name, commandClass); }; kukit.cr.makeGlobalCommand = function(name, executeOnce) { var commandClass = function() {}; commandClass.prototype = { execute: kukit.cr._Command_execute, executeOnScope: executeOnce, executeOnSingleNode: executeOnce }; kukit.commandsGlobalRegistry.register(name, commandClass); }; PK5i7/U?U?kss/core/kukit/kukit/dom.js/* * Copyright (c) 2005-2007 * Authors: KSS Project Contributors (see doc/CREDITS.txt) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ /* Generic dom helpers */ kukit.dom = {}; kukit.dom.getPreviousSiblingTag = function(node) { var toNode = node.previousSibling; while ((toNode != null) && (toNode.nodeType != 1)) { toNode = toNode.previousSibling; } return toNode; }; kukit.dom.getNextSiblingTag = function(node) { var toNode = node.nextSibling; while ((toNode != null) && (toNode.nodeType != 1)) { toNode = toNode.nextSibling; } return toNode; }; kukit.dom.insertBefore = function(nodeFrom, parentNode, nodeTo) { var ownerDoc = nodeTo.nodeType == Node.DOCUMENT_NODE ? nodeTo : nodeTo.ownerDocument; var nodes = nodeFrom.childNodes; var result = new Array(); if(ownerDoc.importNode && (!kukit.HAVE_IE)) { for(var i=0;i < nodes.length;i++) { var imported = ownerDoc.importNode(nodes[i], true); result[i] = parentNode.insertBefore(imported, nodeTo); } } else { for(var i=0;i < nodes.length;i++) { var cloned = nodes[i].cloneNode(true); result[i] = parentNode.insertBefore(cloned, nodeTo); } } return result; }; kukit.dom.appendChildren = function(nodes, toNode) { var ownerDoc = toNode.nodeType == Node.DOCUMENT_NODE ? toNode : toNode.ownerDocument; var result = new Array(); if(ownerDoc.importNode && (!kukit.HAVE_IE)) { for(var i=0;i < nodes.length;i++) { result[i] = toNode.appendChild(ownerDoc.importNode(nodes[i], true)); } }else{ for(var i=0;i < nodes.length;i++) { result[i] = toNode.appendChild(nodes[i].cloneNode(true)); } } return result; }; kukit.dom.clearChildNodes = function(node) { //Maybe we want to get rid of sarissa once? Sarissa.clearChildNodes(node); }; kukit.dom.forceToDom = function(param) { // This is a dirty helper to avoid rewriting existing stuff. // If param is not a dom, it converts to it. // This is to assure that all methods that accept a dom can accept a string // instead. if (typeof(param) == 'string') { // // now convert to dom // // param // // // ***BROKEN*** param // // // param // // This is a good solution since it does not do magic to // our html - BUT html is parsed as xml // so we currently preprocess it on the server // and remove html named entities from it. // var rootText = '
    '; rootText += param + '
    '; var doc = (new DOMParser()).parseFromString(rootText, "text/xml"); var root = doc.getElementsByTagName('div')[0]; // XXX Sarissa bug; html docs would not have a // working serialize, and so importNodes would fail on them. // XXX Fixed in: Revision 1.23 - Sun Jul 10 18:53:53 2005 UTC // use at least 0.9.6.1 param = root; } // Need to do this or else IE fails miserably. // importNode acts strangely. // on FF, you can execute it several times but the next condition // always evaluated to False. // on IE, it is a big problem to execute this for the second time // but it needs to be executed once, thus the condition if (param.ownerDocument != document) { param = document.importNode(param, true); } //alert(Sarissa.serialize(param)); return param; }; /* * really the query should start from the document root, but * limited to inNodes subtrees! */ kukit.dom.cssQuery = function(selector, inNodes) { // to eliminate possible errors if (typeof(inNodes) != 'undefined' && inNodes == null) { ;;; kukit.E = 'Selection error in kukit.dom.cssQuery'; throw kukit.E; } return kukit.dom._cssQuery(selector, inNodes); }; /* * Decide which query to use */ kukit.dom._cssQuery = function(selector, inNodes) { var USE_BASE2 = (typeof(base2) != 'undefined'); if (USE_BASE2) { ;;; kukit.log('Using cssQuery from base2.'); kukit.dom._cssQuery = kukit.dom._cssQuery_base2 } else { ;;; kukit.log('Using original cssQuery.'); kukit.dom._cssQuery = kukit.dom._cssQuery_orig } return kukit.dom._cssQuery(selector, inNodes); }; kukit.dom._cssQuery_base2 = function(selector, inNodes) { // global scope, always. // This is very bad. However the binding makes sure that // nodes once bound will never be bound again // (also, noticed the following issue: cssQuery, when called // on an element, does not check the element itself.) var results = base2.DOM.Document.matchAll(document, selector); var nodes = []; for(var i = 0; i < results.length; i++) { nodes.push(results.item(i)); } return nodes; }; kukit.dom._cssQuery_orig = function(selector, inNodes) { // global scope, always. // This is very bad. However the binding makes sure that // nodes once bound will never be bound again // (also, noticed the following issue: cssQuery, when called // on an element, does not check the element itself.) var results = cssQuery(selector); return results; }; kukit.dom.focus = function(node) { tagName = node.tagName.toLowerCase(); if ((tagName == 'input') || (tagName == 'select') || (tagName == 'textarea')) { node.focus(); ;;; } else { ;;; kukit.logWarning('Focus on node that cannot have focus !'); } }; /* * Gets the textual content of the node * if recursive=false (default), does not descend into sub nodes */ kukit.dom.textContent = function(node, recursive) { var value = kukit.dom._textContent(node, recursive); // replace newline with spaces value = value.replace(/\r\n/g, ' '); value = value.replace(/[\r\n]/g, ' '); return value; }; kukit.dom._textContent = function(node, recursive) { if (typeof(recursive) == 'undefined') { recursive = false; } var value = ''; var childnodes = node.childNodes; for (var i=0; iPxx kss/core/kukit/kukit/eventreg.js/* * Copyright (c) 2005-2007 * Authors: KSS Project Contributors (see doc/CREDITS.txt) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ kukit.er = {}; kukit.er.eventClassCounter = 0; /* * * class CommandRegistry * * available for plugin registration * * usage: * * kukit.eventsGlobalRegistry.register(namespace, eventName, func, * bindMethodName, defaultActionMethodName); * * namespace = null: means global namespace * defaultActionMethodName = null: if there is no default action implemented * func must be a class (constructor) function, this is the class that * implements the binder. */ kukit.er.EventRegistry = function () { this.content = {}; this.classes = {}; this.eventSets = []; }; /* binder registration */ kukit.er.EventRegistry.prototype.registerBinder = function(className, func) { if (typeof(func) == 'undefined') { ;;; kukit.E = 'func argument is mandatory when registering an event'; ;;; kukit.E += ' binder (EventRegistry.registerBinder).'; throw kukit.E; } if (this.classes[className]) { // Do not allow redefinition ;;; var msg = 'Error : event class [' + className + '] already registered.'; ;;; kukit.logError(msg); return; } // Decorate and store the class kukit.er.decorateEventBinderClass(func); this.classes[className] = func; }; kukit.er.EventRegistry.prototype.existsBinder = function(className) { var func = this.classes[className]; return (typeof(func) != 'undefined'); }; kukit.er.EventRegistry.prototype.getBinder = function(className) { var func = this.classes[className]; if (! func) { // not found ;;; kukit.E = 'Error : undefined event setup type [' + className + '].'; throw kukit.E; } return func; }; /* events (methods) registration helpers (not to be called directly) */ kukit.er.EventRegistry.prototype._register = function(namespace, eventName, klass, bindMethodName, defaultActionMethodName, iterName) { if (typeof(defaultActionMethodName) == 'undefined') { ;;; kukit.E = 'Missing arguments when calling [EventRegistry.register].'; throw kukit.E; } // Find out the class name. (Not specified now.) var className = klass.prototype.__className__; if (typeof(className) == 'undefined') { // Create a className, and register it too. className = '' + kukit.er.eventClassCounter; kukit.er.eventClassCounter += 1; this.registerBinder(className, klass); klass.prototype.__className__ = className; } if (!eventName) { ;;; kukit.E = '[eventName] argument cannot be empty when registering'; ;;; kukit.E += ' an event with [EventRegistry.register].'; throw kukit.E; } var key = this._getKey(namespace, eventName); var entry = this.content[key]; if (typeof(entry) != 'undefined') { if (key[0] == '-') { key = key.substring(1); } ;;; kukit.E = 'Attempt to register key [' + key; ;;; kukit.E += '] twice when registering'; ;;; kukit.E += ' an event with [EventRegistry.register].'; throw kukit.E; } // check bindMethodName and defaultActionMethodName if (bindMethodName && ! klass.prototype[bindMethodName]) { ;;; kukit.E = 'In EventRegistry.register bind method [' + bindMethodName; ;;; kukit.E += '] is undefined for event [' + eventName; ;;; kukit.E += '] namespace [' + namespace + '].'; throw kukit.E; } if (defaultActionMethodName && ! klass.prototype[defaultActionMethodName]) { ;;; kukit.E = 'In EventRegistry.register default action method ['; ;;; kukit.E += defaultActionMethodName + '] is undefined for event ['; ;;; kukit.E += eventName + '] namespace [' + namespace + '].'; throw kukit.E; } // check the iterator. if (! kukit.er.getBindIterator(iterName)) { ;;; kukit.E = 'In EventRegistry.register unknown bind iterator ['; ;;; kukit.E += iterName + '].'; throw kukit.E; } // register it this.content[key] = { 'className': className, 'bindMethodName': bindMethodName, 'defaultActionMethodName': defaultActionMethodName, 'iterName': iterName }; }; /* events (methods) binding [ForAll] registration */ kukit.er.EventRegistry.prototype._registerEventSet = function(namespace, names, iterName, bindMethodName) { // At this name the values should be checked already. so this should // be called _after_ _register. this.eventSets.push({ 'namespace': namespace, 'names': names, 'iterName': iterName, 'bindMethodName': bindMethodName }); }; /* there are the actual registration methods, to be called from plugins */ kukit.er.EventRegistry.prototype.register = function(namespace, eventName, klass, bindMethodName, defaultActionMethodName) { this._register(namespace, eventName, klass, bindMethodName, defaultActionMethodName, 'EachLegacy'); this._registerEventSet(namespace, [eventName], 'EachLegacy', bindMethodName); }; kukit.er.EventRegistry.prototype.registerForAllEvents = function(namespace, eventNames, klass, bindMethodName, defaultActionMethodName, iterName) { if (typeof(eventNames) == 'string') { eventNames = [eventNames]; } for (var i=0; i 1) { ;;; kukit.E = 'In [EventRegistry.register], [namespace] cannot have'; ;;; kukit.E += 'dashes.'; throw kukit.E; } return namespace + '-' + eventName; }; kukit.er.EventRegistry.prototype.exists = function(namespace, eventName) { var key = this._getKey(namespace, eventName); var entry = this.content[key]; return (typeof(entry) != 'undefined'); }; kukit.er.EventRegistry.prototype.get = function(namespace, eventName) { var key = this._getKey(namespace, eventName); var entry = this.content[key]; if (typeof(entry) == 'undefined') { ;;; if (key.substr(0, 1) == '-') { ;;; key = key.substring(1); ;;; kukit.E = 'Error : undefined global event key '; ;;; kukit.E += key + ' (or maybe namespace is missing ?).'; ;;; } else { ;;; kukit.E = 'Error : undefined event key [' + key + '].'; ;;; } throw kukit.E; } return entry; }; kukit.eventsGlobalRegistry = new kukit.er.EventRegistry(); /* XXX deprecated methods, to be removed asap */ kukit.er.eventRegistry = {}; kukit.er.eventRegistry.register = function(namespace, eventName, klass, bindMethodName, defaultActionMethodName) { ;;; var msg = 'Deprecated kukit.er.eventRegistry.register,'; ;;; msg += ' use kukit.eventsGlobalRegistry.register instead ! ['; ;;; msg += namespace + '-' + eventName + '].'; ;;; kukit.logWarning(msg); kukit.eventsGlobalRegistry.register(namespace, eventName, klass, bindMethodName, defaultActionMethodName); }; /* Event class decoration * * poor man's subclassing * This is called automatically on registration, to dress * up the event class with the necessary methods * */ /* Provide callins on the state instance that execute a given * continuation event. * Parameters will be the ones specified in the call + * those defined in the rule will be added too. (Parameters can * be accessed with the [pass] kss parameter provider.) * * Call examples: * * trigger an event bound to a given state instance, same node * * binderInstance.__continueEvent__('doit', oper.node, {'extravalue': '5'}); * * with kss rule: * * node.selector:doit { * action-client: log; * log-message: pass(extravalue); * } * * or * * behaviour.selector:doit { * action-client: log; * log-message: pass(extravalue); * } * * trigger an event bound to a given state instance, and the document * (different from current scope) * * binderInstance.__continueEvent__('doit', null, {'extravalue': '5'}); * * with kss rule: * * document:doit { * action-client: log; * log-message: pass(extravalue); * } * * or * * behaviour.selector:doit { * action-client: log; * log-message: pass(extravalue); * } * * trigger an event on all the nodes + document bound to a given state instance * * binderInstance.__continueEvent_allNodes__('doit', {'extravalue': '5'}); * * with kss rule: * * node.selector:doit { * action-client: log; * log-message: pass(extravalue); * } * * p.s. oper is not required to make it easy to adapt existing code * so we create a new oper below */ kukit.er.EventBinder__continueEvent__ = function(name, node, defaultParameters) { // Trigger a continuation event bound to a given state instance, given node // (or on document, if node = null) // var oper = new kukit.op.Oper(); oper.node = node; if (node) { // if we found the binding, just use that var info = kukit.engine.binderInfoRegistry.getBinderInfoById( this.__binderId__); var newOper = info.bound.getBoundOperForNode(name, node); if (newOper) { oper = newOper; } } else { oper.eventRule = kukit.engine.documentRules.getMergedRule( 'document', name, this); } // Look up the behaviour rule, if any. var behav_eventRule = kukit.engine.documentRules.getMergedRule( 'behaviour', name, this); if (behav_eventRule) { if (! oper.eventRule) { // There was no node matching for the rule, use behaviour rule // this allows to set up parametrized actions in general. oper.eventRule = behav_eventRule; } else { // XXX this case should go away, as we should check // this already from binding time // and signal the appropriate error. // Also note that behaviour roles will only be allowed // for "non-binding" events. ;;; var msg = 'Behaviour rule for continuation event [' + name; ;;; msg += '] will be ignored, because we found an explicit rule.'; ;;; kukit.logError(msg); } } // If parms are specified in the call, use them. if (typeof(defaultParameters) != 'undefined') { oper.defaultParameters = defaultParameters; } else { oper.defaultParameters = {}; } // if eventRule is null here, we can yet have the default method, so go on. this._EventBinder_triggerEvent(name, oper); ;;; kukit.logDebug('Continuation event [' + name + '] executed on same node.'); }; kukit.er.EventBinder__continueEvent_allNodes__ = function(name, defaultParameters) { // Trigger an event bound to a given state instance, on all nodes. // (or on document, if node = null) // if no other nodes execute. var executed = 0; // Normal rules. If any of those match, execute them too // each on the node that it selects - not on the original node. var oper = new kukit.op.Oper(); var info = kukit.engine.binderInfoRegistry.getBinderInfoById( this.__binderId__); var opers = info.bound.getBoundOpers(name); for (var i=0; i