From reebalazs at codespeak.net Thu Feb 1 15:08:47 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Thu, 1 Feb 2007 15:08:47 +0100 (CET) Subject: [KSS-checkins] r37731 - in kukit/kss.core/trunk/kss/core: . plugins/draganddrop/browser Message-ID: <20070201140847.9563B10081@code0.codespeak.net> Author: reebalazs Date: Thu Feb 1 15:08:41 2007 New Revision: 37731 Modified: kukit/kss.core/trunk/kss/core/__init__.py kukit/kss.core/trunk/kss/core/azaxview.py kukit/kss.core/trunk/kss/core/browserview.py kukit/kss.core/trunk/kss/core/interfaces.py kukit/kss.core/trunk/kss/core/plugins/draganddrop/browser/kss_dragdrop.js Log: Fix import to work with Zope 3 Modified: kukit/kss.core/trunk/kss/core/__init__.py ============================================================================== --- kukit/kss.core/trunk/kss/core/__init__.py (original) +++ kukit/kss.core/trunk/kss/core/__init__.py Thu Feb 1 15:08:41 2007 @@ -23,6 +23,9 @@ 'CommandSet', 'ICommandSet', ) +from AccessControl import allow_module +allow_module('pdb') + import mimetypes mimetypes.types_map['.kkt'] = 'text/xml' # XXX legacy! Modified: kukit/kss.core/trunk/kss/core/azaxview.py ============================================================================== --- kukit/kss.core/trunk/kss/core/azaxview.py (original) +++ kukit/kss.core/trunk/kss/core/azaxview.py Thu Feb 1 15:08:41 2007 @@ -117,6 +117,8 @@ """ implements(IAzaxView) + + __allow_access_to_unprotected_subobjects__ = True def __init__(self, context, request): super(AzaxBaseView, self).__init__(context, request) Modified: kukit/kss.core/trunk/kss/core/browserview.py ============================================================================== --- kukit/kss.core/trunk/kss/core/browserview.py (original) +++ kukit/kss.core/trunk/kss/core/browserview.py Thu Feb 1 15:08:41 2007 @@ -18,7 +18,10 @@ # import cgi -from Products.Five.browser import BrowserView +try: + from Products.Five import BrowserView +except ImportError: + from zope.app.publisher.browser import BrowserView #from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile from zope.pagetemplate.pagetemplatefile import PageTemplateFile Modified: kukit/kss.core/trunk/kss/core/interfaces.py ============================================================================== --- kukit/kss.core/trunk/kss/core/interfaces.py (original) +++ kukit/kss.core/trunk/kss/core/interfaces.py Thu Feb 1 15:08:41 2007 @@ -110,6 +110,9 @@ def render(): '' + def getCommandSet(self, name): + 'Returns the command set for a given name' + class ICommandSet(Interface): 'Methods of this class implement a command set' Modified: kukit/kss.core/trunk/kss/core/plugins/draganddrop/browser/kss_dragdrop.js ============================================================================== --- kukit/kss.core/trunk/kss/core/plugins/draganddrop/browser/kss_dragdrop.js (original) +++ kukit/kss.core/trunk/kss/core/plugins/draganddrop/browser/kss_dragdrop.js Thu Feb 1 15:08:41 2007 @@ -42,8 +42,12 @@ } }; -kukit.eventsGlobalRegistry.register('dad', 'drop', kukit.draganddrop.DragAndDropEvent, '__bind_drop__', null); -kukit.eventsGlobalRegistry.register('dad', 'hover', kukit.draganddrop.DragAndDropEvent, '__bind_drop__', null); -kukit.eventsGlobalRegistry.register('dad', 'drag', kukit.draganddrop.DragAndDropEvent, '__bind_drag__', null); -kukit.eventsGlobalRegistry.register('dad', 'start', kukit.draganddrop.DragAndDropEvent, '__bind_drag__', null); -kukit.eventsGlobalRegistry.register('dad', 'end', kukit.draganddrop.DragAndDropEvent, '__bind_drag__', null); +/*kukit.eventsGlobalRegistry.register('dad', 'drop', kukit.draganddrop.DragAndDropEvent, '__bind_drop__', null);*/ +/*kukit.eventsGlobalRegistry.register('dad', 'hover', kukit.draganddrop.DragAndDropEvent, '__bind_drop__', null);*/ +/*kukit.eventsGlobalRegistry.register('dad', 'drag', kukit.draganddrop.DragAndDropEvent, '__bind_drag__', null);*/ +/*kukit.eventsGlobalRegistry.register('dad', 'start', kukit.draganddrop.DragAndDropEvent, '__bind_drag__', null);*/ +/*kukit.eventsGlobalRegistry.register('dad', 'end', kukit.draganddrop.DragAndDropEvent, '__bind_drag__', null);*/ + +//kukit.eventsGlobalRegistry.registerForAllEvents('dad', ['drag', 'start', 'end'], kukit.draganddrop.DragAndDropEvent, '__bind_drag__', null); +//kukit.eventsGlobalRegistry.registerForAllEvents('dad', ['drop', 'hover'], kukit.draganddrop.DragAndDropEvent, '__bind_drop__', null); + From reebalazs at codespeak.net Thu Feb 1 15:11:37 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Thu, 1 Feb 2007 15:11:37 +0100 (CET) Subject: [KSS-checkins] r37732 - in kukit/kss.core/trunk/kss/core: . plugins/draganddrop/browser Message-ID: <20070201141137.6419F10084@code0.codespeak.net> Author: reebalazs Date: Thu Feb 1 15:11:33 2007 New Revision: 37732 Modified: kukit/kss.core/trunk/kss/core/__init__.py kukit/kss.core/trunk/kss/core/azaxview.py kukit/kss.core/trunk/kss/core/interfaces.py kukit/kss.core/trunk/kss/core/plugins/draganddrop/browser/kss_dragdrop.js Log: Undo unnecessary commits from previous commit Modified: kukit/kss.core/trunk/kss/core/__init__.py ============================================================================== --- kukit/kss.core/trunk/kss/core/__init__.py (original) +++ kukit/kss.core/trunk/kss/core/__init__.py Thu Feb 1 15:11:33 2007 @@ -23,9 +23,6 @@ 'CommandSet', 'ICommandSet', ) -from AccessControl import allow_module -allow_module('pdb') - import mimetypes mimetypes.types_map['.kkt'] = 'text/xml' # XXX legacy! Modified: kukit/kss.core/trunk/kss/core/azaxview.py ============================================================================== --- kukit/kss.core/trunk/kss/core/azaxview.py (original) +++ kukit/kss.core/trunk/kss/core/azaxview.py Thu Feb 1 15:11:33 2007 @@ -117,8 +117,6 @@ """ implements(IAzaxView) - - __allow_access_to_unprotected_subobjects__ = True def __init__(self, context, request): super(AzaxBaseView, self).__init__(context, request) Modified: kukit/kss.core/trunk/kss/core/interfaces.py ============================================================================== --- kukit/kss.core/trunk/kss/core/interfaces.py (original) +++ kukit/kss.core/trunk/kss/core/interfaces.py Thu Feb 1 15:11:33 2007 @@ -110,9 +110,6 @@ def render(): '' - def getCommandSet(self, name): - 'Returns the command set for a given name' - class ICommandSet(Interface): 'Methods of this class implement a command set' Modified: kukit/kss.core/trunk/kss/core/plugins/draganddrop/browser/kss_dragdrop.js ============================================================================== --- kukit/kss.core/trunk/kss/core/plugins/draganddrop/browser/kss_dragdrop.js (original) +++ kukit/kss.core/trunk/kss/core/plugins/draganddrop/browser/kss_dragdrop.js Thu Feb 1 15:11:33 2007 @@ -42,12 +42,8 @@ } }; -/*kukit.eventsGlobalRegistry.register('dad', 'drop', kukit.draganddrop.DragAndDropEvent, '__bind_drop__', null);*/ -/*kukit.eventsGlobalRegistry.register('dad', 'hover', kukit.draganddrop.DragAndDropEvent, '__bind_drop__', null);*/ -/*kukit.eventsGlobalRegistry.register('dad', 'drag', kukit.draganddrop.DragAndDropEvent, '__bind_drag__', null);*/ -/*kukit.eventsGlobalRegistry.register('dad', 'start', kukit.draganddrop.DragAndDropEvent, '__bind_drag__', null);*/ -/*kukit.eventsGlobalRegistry.register('dad', 'end', kukit.draganddrop.DragAndDropEvent, '__bind_drag__', null);*/ - -//kukit.eventsGlobalRegistry.registerForAllEvents('dad', ['drag', 'start', 'end'], kukit.draganddrop.DragAndDropEvent, '__bind_drag__', null); -//kukit.eventsGlobalRegistry.registerForAllEvents('dad', ['drop', 'hover'], kukit.draganddrop.DragAndDropEvent, '__bind_drop__', null); - +kukit.eventsGlobalRegistry.register('dad', 'drop', kukit.draganddrop.DragAndDropEvent, '__bind_drop__', null); +kukit.eventsGlobalRegistry.register('dad', 'hover', kukit.draganddrop.DragAndDropEvent, '__bind_drop__', null); +kukit.eventsGlobalRegistry.register('dad', 'drag', kukit.draganddrop.DragAndDropEvent, '__bind_drag__', null); +kukit.eventsGlobalRegistry.register('dad', 'start', kukit.draganddrop.DragAndDropEvent, '__bind_drag__', null); +kukit.eventsGlobalRegistry.register('dad', 'end', kukit.draganddrop.DragAndDropEvent, '__bind_drag__', null); From gotcha at codespeak.net Thu Feb 1 18:30:47 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Thu, 1 Feb 2007 18:30:47 +0100 (CET) Subject: [KSS-checkins] r37755 - kukit/kss.demo/trunk/kss/demo/tests/selenium Message-ID: <20070201173047.F37CE10080@code0.codespeak.net> Author: gotcha Date: Thu Feb 1 18:30:29 2007 New Revision: 37755 Added: kukit/kss.demo/trunk/kss/demo/tests/selenium/selenium.py Log: selenium rc 0.9.0 python support Added: kukit/kss.demo/trunk/kss/demo/tests/selenium/selenium.py ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/tests/selenium/selenium.py Thu Feb 1 18:30:29 2007 @@ -0,0 +1,1405 @@ + +""" +Copyright 2006 ThoughtWorks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" +__docformat__ = "restructuredtext en" + +# This file has been automatically generated via XSL + +import httplib +import urllib +import re + +class selenium: + """ +Defines an object that runs Selenium commands. + + Element Locators + ~~~~~~~~~~~~~~~~ + Element Locators tell Selenium which HTML element a command refers to. + The format of a locator is: + \ *locatorType*\ **=**\ \ *argument* + We support the following strategies for locating elements: + + * \ **identifier**\ =\ *id* + Select the element with the specified @id attribute. If no match is + found, select the first element whose @name attribute is \ *id*. + (This is normally the default; see below.) + * \ **id**\ =\ *id* + Select the element with the specified @id attribute. + * \ **name**\ =\ *name* + Select the first element with the specified @name attribute. + + * username + * name=username + + + + The name may optionally be followed by one or more \ *element-filters*, separated from the name by whitespace. If the \ *filterType* is not specified, \ **value**\ is assumed. + + * name=flavour value=chocolate + + + * \ **dom**\ =\ *javascriptExpression* + + Find an element by evaluating the specified string. This allows you to traverse the HTML Document Object + Model using JavaScript. Note that you must not return a value in this string; simply make it the last expression in the block. + * dom=document.forms['myForm'].myDropdown + * dom=document.images[56] + * dom=function foo() { return document.links[1]; }; foo(); + + + + * \ **xpath**\ =\ *xpathExpression* + Locate an element using an XPath expression. + * xpath=//img[@alt='The image alt text'] + * xpath=//table[@id='table1']//tr[4]/td[2] + + + * \ **link**\ =\ *textPattern* + Select the link (anchor) element which contains text matching the + specified \ *pattern*. + * link=The link text + + + * \ **css**\ =\ *cssSelectorSyntax* + Select the element using css selectors. Please refer to CSS2 selectors, CSS3 selectors for more information. You can also check the TestCssLocators test in the selenium test suite for an example of usage, which is included in the downloaded selenium core package. + * css=a[href="#id3"] + * css=span#firstChild + span + + + + Currently the css selector locator supports all css1, css2 and css3 selectors except namespace in css3, some pseudo classes(:nth-of-type, :nth-last-of-type, :first-of-type, :last-of-type, :only-of-type, :visited, :hover, :active, :focus, :indeterminate) and pseudo elements(::first-line, ::first-letter, ::selection, ::before, ::after). + + + Without an explicit locator prefix, Selenium uses the following default + strategies: + + * \ **dom**\ , for locators starting with "document." + * \ **xpath**\ , for locators starting with "//" + * \ **identifier**\ , otherwise + + Element Filters + ~~~~~~~~~~~~~~~Element filters can be used with a locator to refine a list of candidate elements. They are currently used only in the 'name' element-locator. + Filters look much like locators, ie. + \ *filterType*\ **=**\ \ *argument*Supported element-filters are: + \ **value=**\ \ *valuePattern* + + Matches elements based on their values. This is particularly useful for refining a list of similarly-named toggle-buttons.\ **index=**\ \ *index* + + Selects a single element based on its position in the list (offset from zero).String-match Patterns + ~~~~~~~~~~~~~~~~~~~~~ + Various Pattern syntaxes are available for matching string values: + + * \ **glob:**\ \ *pattern* + Match a string against a "glob" (aka "wildmat") pattern. "Glob" is a + kind of limited regular-expression syntax typically used in command-line + shells. In a glob pattern, "*" represents any sequence of characters, and "?" + represents any single character. Glob patterns match against the entire + string. + * \ **regexp:**\ \ *regexp* + Match a string using a regular-expression. The full power of JavaScript + regular-expressions is available. + * \ **exact:**\ \ *string* + Match a string exactly, verbatim, without any of that fancy wildcard + stuff. + + + If no pattern prefix is specified, Selenium assumes that it's a "glob" + pattern. + + + """ + +### This part is hard-coded in the XSL + def __init__(self, host, port, browserStartCommand, browserURL): + self.host = host + self.port = port + self.browserStartCommand = browserStartCommand + self.browserURL = browserURL + self.sessionId = None + + def start(self): + result = self.get_string("getNewBrowserSession", [self.browserStartCommand, self.browserURL]) + try: + self.sessionId = long(result) + except ValueError: + raise Exception, result + + def stop(self): + self.do_command("testComplete", []) + self.sessionId = None + + def do_command(self, verb, args): + conn = httplib.HTTPConnection(self.host, self.port) + commandString = u'/selenium-server/driver/?cmd=' + urllib.quote_plus(unicode(verb).encode('utf-8')) + for i in range(len(args)): + commandString = commandString + '&' + unicode(i+1) + '=' + urllib.quote_plus(unicode(args[i]).encode('utf-8')) + if (None != self.sessionId): + commandString = commandString + "&sessionId=" + unicode(self.sessionId) + conn.request("GET", commandString) + + response = conn.getresponse() + #print response.status, response.reason + data = unicode(response.read(), "UTF-8") + result = response.reason + #print "Selenium Result: " + repr(data) + "\n\n" + if (not data.startswith('OK')): + raise Exception, data + return data + + def get_string(self, verb, args): + result = self.do_command(verb, args) + return result[3:] + + def get_string_array(self, verb, args): + csv = self.get_string(verb, args) + token = "" + tokens = [] + escape = False + for i in range(len(csv)): + letter = csv[i] + if (escape): + token = token + letter + escape = False + continue + if (letter == '\\'): + escape = True + elif (letter == ','): + tokens.append(token) + token = "" + else: + token = token + letter + tokens.append(token) + return tokens + + def get_number(self, verb, args): + # Is there something I need to do here? + return self.get_string(verb, args) + + def get_number_array(self, verb, args): + # Is there something I need to do here? + return self.get_string_array(verb, args) + + def get_boolean(self, verb, args): + boolstr = self.get_string(verb, args) + if ("true" == boolstr): + return True + if ("false" == boolstr): + return False + raise ValueError, "result is neither 'true' nor 'false': " + boolstr + + def get_boolean_array(self, verb, args): + boolarr = self.get_string_array(verb, args) + for i in range(len(boolarr)): + if ("true" == boolstr): + boolarr[i] = True + continue + if ("false" == boolstr): + boolarr[i] = False + continue + raise ValueError, "result is neither 'true' nor 'false': " + boolarr[i] + return boolarr + + + +### From here on, everything's auto-generated from XML + + + def click(self,locator): + """ + Clicks on a link, button, checkbox or radio button. If the click action + causes a new page to load (like a link usually does), call + waitForPageToLoad. + + 'locator' is an element locator + """ + self.do_command("click", [locator,]) + + + def double_click(self,locator): + """ + Double clicks on a link, button, checkbox or radio button. If the double click action + causes a new page to load (like a link usually does), call + waitForPageToLoad. + + 'locator' is an element locator + """ + self.do_command("doubleClick", [locator,]) + + + def click_at(self,locator,coordString): + """ + Clicks on a link, button, checkbox or radio button. If the click action + causes a new page to load (like a link usually does), call + waitForPageToLoad. + + 'locator' is an element locator + 'coordString' is specifies the x,y position (i.e. - 10,20) of the mouse event relative to the element returned by the locator. + """ + self.do_command("clickAt", [locator,coordString,]) + + + def double_click_at(self,locator,coordString): + """ + Doubleclicks on a link, button, checkbox or radio button. If the action + causes a new page to load (like a link usually does), call + waitForPageToLoad. + + 'locator' is an element locator + 'coordString' is specifies the x,y position (i.e. - 10,20) of the mouse event relative to the element returned by the locator. + """ + self.do_command("doubleClickAt", [locator,coordString,]) + + + def fire_event(self,locator,eventName): + """ + Explicitly simulate an event, to trigger the corresponding "on\ *event*" + handler. + + 'locator' is an element locator + 'eventName' is the event name, e.g. "focus" or "blur" + """ + self.do_command("fireEvent", [locator,eventName,]) + + + def key_press(self,locator,keySequence): + """ + Simulates a user pressing and releasing a key. + + 'locator' is an element locator + 'keySequence' is Either be a string("\" followed by the numeric keycode of the key to be pressed, normally the ASCII value of that key), or a single character. For example: "w", "\119". + """ + self.do_command("keyPress", [locator,keySequence,]) + + + def shift_key_down(self): + """ + Press the shift key and hold it down until doShiftUp() is called or a new page is loaded. + + """ + self.do_command("shiftKeyDown", []) + + + def shift_key_up(self): + """ + Release the shift key. + + """ + self.do_command("shiftKeyUp", []) + + + def meta_key_down(self): + """ + Press the meta key and hold it down until doMetaUp() is called or a new page is loaded. + + """ + self.do_command("metaKeyDown", []) + + + def meta_key_up(self): + """ + Release the meta key. + + """ + self.do_command("metaKeyUp", []) + + + def alt_key_down(self): + """ + Press the alt key and hold it down until doAltUp() is called or a new page is loaded. + + """ + self.do_command("altKeyDown", []) + + + def alt_key_up(self): + """ + Release the alt key. + + """ + self.do_command("altKeyUp", []) + + + def control_key_down(self): + """ + Press the control key and hold it down until doControlUp() is called or a new page is loaded. + + """ + self.do_command("controlKeyDown", []) + + + def control_key_up(self): + """ + Release the control key. + + """ + self.do_command("controlKeyUp", []) + + + def key_down(self,locator,keySequence): + """ + Simulates a user pressing a key (without releasing it yet). + + 'locator' is an element locator + 'keySequence' is Either be a string("\" followed by the numeric keycode of the key to be pressed, normally the ASCII value of that key), or a single character. For example: "w", "\119". + """ + self.do_command("keyDown", [locator,keySequence,]) + + + def key_up(self,locator,keySequence): + """ + Simulates a user releasing a key. + + 'locator' is an element locator + 'keySequence' is Either be a string("\" followed by the numeric keycode of the key to be pressed, normally the ASCII value of that key), or a single character. For example: "w", "\119". + """ + self.do_command("keyUp", [locator,keySequence,]) + + + def mouse_over(self,locator): + """ + Simulates a user hovering a mouse over the specified element. + + 'locator' is an element locator + """ + self.do_command("mouseOver", [locator,]) + + + def mouse_out(self,locator): + """ + Simulates a user moving the mouse pointer away from the specified element. + + 'locator' is an element locator + """ + self.do_command("mouseOut", [locator,]) + + + def mouse_down(self,locator): + """ + Simulates a user pressing the mouse button (without releasing it yet) on + the specified element. + + 'locator' is an element locator + """ + self.do_command("mouseDown", [locator,]) + + + def mouse_down_at(self,locator,coordString): + """ + Simulates a user pressing the mouse button (without releasing it yet) on + the specified element. + + 'locator' is an element locator + 'coordString' is specifies the x,y position (i.e. - 10,20) of the mouse event relative to the element returned by the locator. + """ + self.do_command("mouseDownAt", [locator,coordString,]) + + + def mouse_up(self,locator): + """ + Simulates a user pressing the mouse button (without releasing it yet) on + the specified element. + + 'locator' is an element locator + """ + self.do_command("mouseUp", [locator,]) + + + def mouse_up_at(self,locator,coordString): + """ + Simulates a user pressing the mouse button (without releasing it yet) on + the specified element. + + 'locator' is an element locator + 'coordString' is specifies the x,y position (i.e. - 10,20) of the mouse event relative to the element returned by the locator. + """ + self.do_command("mouseUpAt", [locator,coordString,]) + + + def mouse_move(self,locator): + """ + Simulates a user pressing the mouse button (without releasing it yet) on + the specified element. + + 'locator' is an element locator + """ + self.do_command("mouseMove", [locator,]) + + + def mouse_move_at(self,locator,coordString): + """ + Simulates a user pressing the mouse button (without releasing it yet) on + the specified element. + + 'locator' is an element locator + 'coordString' is specifies the x,y position (i.e. - 10,20) of the mouse event relative to the element returned by the locator. + """ + self.do_command("mouseMoveAt", [locator,coordString,]) + + + def type(self,locator,value): + """ + Sets the value of an input field, as though you typed it in. + + Can also be used to set the value of combo boxes, check boxes, etc. In these cases, + value should be the value of the option selected, not the visible text. + + + 'locator' is an element locator + 'value' is the value to type + """ + self.do_command("type", [locator,value,]) + + + def set_speed(self,value): + """ + Set execution speed (i.e., set the millisecond length of a delay which will follow each selenium operation). By default, there is no such delay, i.e., + the delay is 0 milliseconds. + + 'value' is the number of milliseconds to pause after operation + """ + self.do_command("setSpeed", [value,]) + + + def get_speed(self): + """ + Get execution speed (i.e., get the millisecond length of the delay following each selenium operation). By default, there is no such delay, i.e., + the delay is 0 milliseconds. + + See also setSpeed. + + """ + self.do_command("getSpeed", []) + + + def check(self,locator): + """ + Check a toggle-button (checkbox/radio) + + 'locator' is an element locator + """ + self.do_command("check", [locator,]) + + + def uncheck(self,locator): + """ + Uncheck a toggle-button (checkbox/radio) + + 'locator' is an element locator + """ + self.do_command("uncheck", [locator,]) + + + def select(self,selectLocator,optionLocator): + """ + Select an option from a drop-down using an option locator. + + + Option locators provide different ways of specifying options of an HTML + Select element (e.g. for selecting a specific option, or for asserting + that the selected option satisfies a specification). There are several + forms of Select Option Locator. + + * \ **label**\ =\ *labelPattern* + matches options based on their labels, i.e. the visible text. (This + is the default.) + * label=regexp:^[Oo]ther + + + * \ **value**\ =\ *valuePattern* + matches options based on their values. + * value=other + + + * \ **id**\ =\ *id* + matches options based on their ids. + * id=option1 + + + * \ **index**\ =\ *index* + matches an option based on its index (offset from zero). + * index=2 + + + + + If no option locator prefix is provided, the default behaviour is to match on \ **label**\ . + + + + 'selectLocator' is an element locator identifying a drop-down menu + 'optionLocator' is an option locator (a label by default) + """ + self.do_command("select", [selectLocator,optionLocator,]) + + + def add_selection(self,locator,optionLocator): + """ + Add a selection to the set of selected options in a multi-select element using an option locator. + + @see #doSelect for details of option locators + + 'locator' is an element locator identifying a multi-select box + 'optionLocator' is an option locator (a label by default) + """ + self.do_command("addSelection", [locator,optionLocator,]) + + + def remove_selection(self,locator,optionLocator): + """ + Remove a selection from the set of selected options in a multi-select element using an option locator. + + @see #doSelect for details of option locators + + 'locator' is an element locator identifying a multi-select box + 'optionLocator' is an option locator (a label by default) + """ + self.do_command("removeSelection", [locator,optionLocator,]) + + + def submit(self,formLocator): + """ + Submit the specified form. This is particularly useful for forms without + submit buttons, e.g. single-input "Search" forms. + + 'formLocator' is an element locator for the form you want to submit + """ + self.do_command("submit", [formLocator,]) + + + def open(self,url): + """ + Opens an URL in the test frame. This accepts both relative and absolute + URLs. + + The "open" command waits for the page to load before proceeding, + ie. the "AndWait" suffix is implicit. + + \ *Note*: The URL must be on the same domain as the runner HTML + due to security restrictions in the browser (Same Origin Policy). If you + need to open an URL on another domain, use the Selenium Server to start a + new browser session on that domain. + + 'url' is the URL to open; may be relative or absolute + """ + self.do_command("open", [url,]) + + + def open_window(self,url,windowID): + """ + Opens a popup window (if a window with that ID isn't already open). + After opening the window, you'll need to select it using the selectWindow + command. + + This command can also be a useful workaround for bug SEL-339. In some cases, Selenium will be unable to intercept a call to window.open (if the call occurs during or before the "onLoad" event, for example). + In those cases, you can force Selenium to notice the open window's name by using the Selenium openWindow command, using + an empty (blank) url, like this: openWindow("", "myFunnyWindow"). + + + 'url' is the URL to open, which can be blank + 'windowID' is the JavaScript window ID of the window to select + """ + self.do_command("openWindow", [url,windowID,]) + + + def select_window(self,windowID): + """ + Selects a popup window; once a popup window has been selected, all + commands go to that window. To select the main window again, use null + as the target. + + Selenium has several strategies for finding the window object referred to by the "windowID" parameter. + 1.) if windowID is null, then it is assumed the user is referring to the original window instantiated by the browser). + 2.) if the value of the "windowID" parameter is a JavaScript variable name in the current application window, then it is assumed + that this variable contains the return value from a call to the JavaScript window.open() method. + 3.) Otherwise, selenium looks in a hash it maintains that maps string names to window objects. Each of these string + names matches the second parameter "windowName" past to the JavaScript method window.open(url, windowName, windowFeatures, replaceFlag) + (which selenium intercepts). + If you're having trouble figuring out what is the name of a window that you want to manipulate, look at the selenium log messages + which identify the names of windows created via window.open (and therefore intercepted by selenium). You will see messages + like the following for each window as it is opened: + ``debug: window.open call intercepted; window ID (which you can use with selectWindow()) is "myNewWindow"`` + In some cases, Selenium will be unable to intercept a call to window.open (if the call occurs during or before the "onLoad" event, for example). + (This is bug SEL-339.) In those cases, you can force Selenium to notice the open window's name by using the Selenium openWindow command, using + an empty (blank) url, like this: openWindow("", "myFunnyWindow"). + + + 'windowID' is the JavaScript window ID of the window to select + """ + self.do_command("selectWindow", [windowID,]) + + + def select_frame(self,locator): + """ + Selects a frame within the current window. (You may invoke this command + multiple times to select nested frames.) To select the parent frame, use + "relative=parent" as a locator; to select the top frame, use "relative=top". + + You may also use a DOM expression to identify the frame you want directly, + like this: ``dom=frames["main"].frames["subframe"]`` + + + 'locator' is an element locator identifying a frame or iframe + """ + self.do_command("selectFrame", [locator,]) + + + def get_log_messages(self): + """ + Return the contents of the log. + + This is a placeholder intended to make the code generator make this API + available to clients. The selenium server will intercept this call, however, + and return its recordkeeping of log messages since the last call to this API. + Thus this code in JavaScript will never be called. + The reason I opted for a servercentric solution is to be able to support + multiple frames served from different domains, which would break a + centralized JavaScript logging mechanism under some conditions. + + + """ + return self.get_string("getLogMessages", []) + + + def get_whether_this_frame_match_frame_expression(self,currentFrameString,target): + """ + Determine whether current/locator identify the frame containing this running code. + + This is useful in proxy injection mode, where this code runs in every + browser frame and window, and sometimes the selenium server needs to identify + the "current" frame. In this case, when the test calls selectFrame, this + routine is called for each frame to figure out which one has been selected. + The selected frame will return true, while all others will return false. + + + 'currentFrameString' is starting frame + 'target' is new frame (which might be relative to the current one) + """ + return self.get_boolean("getWhetherThisFrameMatchFrameExpression", [currentFrameString,target,]) + + + def get_whether_this_window_match_window_expression(self,currentWindowString,target): + """ + Determine whether currentWindowString plus target identify the window containing this running code. + + This is useful in proxy injection mode, where this code runs in every + browser frame and window, and sometimes the selenium server needs to identify + the "current" window. In this case, when the test calls selectWindow, this + routine is called for each window to figure out which one has been selected. + The selected window will return true, while all others will return false. + + + 'currentWindowString' is starting window + 'target' is new window (which might be relative to the current one, e.g., "_parent") + """ + return self.get_boolean("getWhetherThisWindowMatchWindowExpression", [currentWindowString,target,]) + + + def wait_for_pop_up(self,windowID,timeout): + """ + Waits for a popup window to appear and load up. + + 'windowID' is the JavaScript window ID of the window that will appear + 'timeout' is a timeout in milliseconds, after which the action will return with an error + """ + self.do_command("waitForPopUp", [windowID,timeout,]) + + + def choose_cancel_on_next_confirmation(self): + """ + By default, Selenium's overridden window.confirm() function will + return true, as if the user had manually clicked OK. After running + this command, the next call to confirm() will return false, as if + the user had clicked Cancel. + + """ + self.do_command("chooseCancelOnNextConfirmation", []) + + + def answer_on_next_prompt(self,answer): + """ + Instructs Selenium to return the specified answer string in response to + the next JavaScript prompt [window.prompt()]. + + 'answer' is the answer to give in response to the prompt pop-up + """ + self.do_command("answerOnNextPrompt", [answer,]) + + + def go_back(self): + """ + Simulates the user clicking the "back" button on their browser. + + """ + self.do_command("goBack", []) + + + def refresh(self): + """ + Simulates the user clicking the "Refresh" button on their browser. + + """ + self.do_command("refresh", []) + + + def close(self): + """ + Simulates the user clicking the "close" button in the titlebar of a popup + window or tab. + + """ + self.do_command("close", []) + + + def is_alert_present(self): + """ + Has an alert occurred? + + + This function never throws an exception + + + + """ + return self.get_boolean("isAlertPresent", []) + + + def is_prompt_present(self): + """ + Has a prompt occurred? + + + This function never throws an exception + + + + """ + return self.get_boolean("isPromptPresent", []) + + + def is_confirmation_present(self): + """ + Has confirm() been called? + + + This function never throws an exception + + + + """ + return self.get_boolean("isConfirmationPresent", []) + + + def get_alert(self): + """ + Retrieves the message of a JavaScript alert generated during the previous action, or fail if there were no alerts. + + Getting an alert has the same effect as manually clicking OK. If an + alert is generated but you do not get/verify it, the next Selenium action + will fail. + NOTE: under Selenium, JavaScript alerts will NOT pop up a visible alert + dialog. + NOTE: Selenium does NOT support JavaScript alerts that are generated in a + page's onload() event handler. In this case a visible dialog WILL be + generated and Selenium will hang until someone manually clicks OK. + + + """ + return self.get_string("getAlert", []) + + + def get_confirmation(self): + """ + Retrieves the message of a JavaScript confirmation dialog generated during + the previous action. + + + By default, the confirm function will return true, having the same effect + as manually clicking OK. This can be changed by prior execution of the + chooseCancelOnNextConfirmation command. If an confirmation is generated + but you do not get/verify it, the next Selenium action will fail. + + + NOTE: under Selenium, JavaScript confirmations will NOT pop up a visible + dialog. + + + NOTE: Selenium does NOT support JavaScript confirmations that are + generated in a page's onload() event handler. In this case a visible + dialog WILL be generated and Selenium will hang until you manually click + OK. + + + + """ + return self.get_string("getConfirmation", []) + + + def get_prompt(self): + """ + Retrieves the message of a JavaScript question prompt dialog generated during + the previous action. + + Successful handling of the prompt requires prior execution of the + answerOnNextPrompt command. If a prompt is generated but you + do not get/verify it, the next Selenium action will fail. + NOTE: under Selenium, JavaScript prompts will NOT pop up a visible + dialog. + NOTE: Selenium does NOT support JavaScript prompts that are generated in a + page's onload() event handler. In this case a visible dialog WILL be + generated and Selenium will hang until someone manually clicks OK. + + + """ + return self.get_string("getPrompt", []) + + + def get_location(self): + """ + Gets the absolute URL of the current page. + + """ + return self.get_string("getLocation", []) + + + def get_title(self): + """ + Gets the title of the current page. + + """ + return self.get_string("getTitle", []) + + + def get_body_text(self): + """ + Gets the entire text of the page. + + """ + return self.get_string("getBodyText", []) + + + def get_value(self,locator): + """ + Gets the (whitespace-trimmed) value of an input field (or anything else with a value parameter). + For checkbox/radio elements, the value will be "on" or "off" depending on + whether the element is checked or not. + + 'locator' is an element locator + """ + return self.get_string("getValue", [locator,]) + + + def get_text(self,locator): + """ + Gets the text of an element. This works for any element that contains + text. This command uses either the textContent (Mozilla-like browsers) or + the innerText (IE-like browsers) of the element, which is the rendered + text shown to the user. + + 'locator' is an element locator + """ + return self.get_string("getText", [locator,]) + + + def get_eval(self,script): + """ + Gets the result of evaluating the specified JavaScript snippet. The snippet may + have multiple lines, but only the result of the last line will be returned. + + Note that, by default, the snippet will run in the context of the "selenium" + object itself, so ``this`` will refer to the Selenium object, and ``window`` will + refer to the top-level runner test window, not the window of your application. + If you need a reference to the window of your application, you can refer + to ``this.browserbot.getCurrentWindow()`` and if you need to use + a locator to refer to a single element in your application page, you can + use ``this.page().findElement("foo")`` where "foo" is your locator. + + + 'script' is the JavaScript snippet to run + """ + return self.get_string("getEval", [script,]) + + + def is_checked(self,locator): + """ + Gets whether a toggle-button (checkbox/radio) is checked. Fails if the specified element doesn't exist or isn't a toggle-button. + + 'locator' is an element locator pointing to a checkbox or radio button + """ + return self.get_boolean("isChecked", [locator,]) + + + def get_table(self,tableCellAddress): + """ + Gets the text from a cell of a table. The cellAddress syntax + tableLocator.row.column, where row and column start at 0. + + 'tableCellAddress' is a cell address, e.g. "foo.1.4" + """ + return self.get_string("getTable", [tableCellAddress,]) + + + def get_selected_labels(self,selectLocator): + """ + Gets all option labels (visible text) for selected options in the specified select or multi-select element. + + 'selectLocator' is an element locator identifying a drop-down menu + """ + return self.get_string_array("getSelectedLabels", [selectLocator,]) + + + def get_selected_label(self,selectLocator): + """ + Gets option label (visible text) for selected option in the specified select element. + + 'selectLocator' is an element locator identifying a drop-down menu + """ + return self.get_string("getSelectedLabel", [selectLocator,]) + + + def get_selected_values(self,selectLocator): + """ + Gets all option values (value attributes) for selected options in the specified select or multi-select element. + + 'selectLocator' is an element locator identifying a drop-down menu + """ + return self.get_string_array("getSelectedValues", [selectLocator,]) + + + def get_selected_value(self,selectLocator): + """ + Gets option value (value attribute) for selected option in the specified select element. + + 'selectLocator' is an element locator identifying a drop-down menu + """ + return self.get_string("getSelectedValue", [selectLocator,]) + + + def get_selected_indexes(self,selectLocator): + """ + Gets all option indexes (option number, starting at 0) for selected options in the specified select or multi-select element. + + 'selectLocator' is an element locator identifying a drop-down menu + """ + return self.get_string_array("getSelectedIndexes", [selectLocator,]) + + + def get_selected_index(self,selectLocator): + """ + Gets option index (option number, starting at 0) for selected option in the specified select element. + + 'selectLocator' is an element locator identifying a drop-down menu + """ + return self.get_string("getSelectedIndex", [selectLocator,]) + + + def get_selected_ids(self,selectLocator): + """ + Gets all option element IDs for selected options in the specified select or multi-select element. + + 'selectLocator' is an element locator identifying a drop-down menu + """ + return self.get_string_array("getSelectedIds", [selectLocator,]) + + + def get_selected_id(self,selectLocator): + """ + Gets option element ID for selected option in the specified select element. + + 'selectLocator' is an element locator identifying a drop-down menu + """ + return self.get_string("getSelectedId", [selectLocator,]) + + + def is_something_selected(self,selectLocator): + """ + Determines whether some option in a drop-down menu is selected. + + 'selectLocator' is an element locator identifying a drop-down menu + """ + return self.get_boolean("isSomethingSelected", [selectLocator,]) + + + def get_select_options(self,selectLocator): + """ + Gets all option labels in the specified select drop-down. + + 'selectLocator' is an element locator identifying a drop-down menu + """ + return self.get_string_array("getSelectOptions", [selectLocator,]) + + + def get_attribute(self,attributeLocator): + """ + Gets the value of an element attribute. + + 'attributeLocator' is an element locator followed by an + """ + return self.get_string("getAttribute", [attributeLocator,]) + + + def is_text_present(self,pattern): + """ + Verifies that the specified text pattern appears somewhere on the rendered page shown to the user. + + 'pattern' is a pattern to match with the text of the page + """ + return self.get_boolean("isTextPresent", [pattern,]) + + + def is_element_present(self,locator): + """ + Verifies that the specified element is somewhere on the page. + + 'locator' is an element locator + """ + return self.get_boolean("isElementPresent", [locator,]) + + + def is_visible(self,locator): + """ + Determines if the specified element is visible. An + element can be rendered invisible by setting the CSS "visibility" + property to "hidden", or the "display" property to "none", either for the + element itself or one if its ancestors. This method will fail if + the element is not present. + + 'locator' is an element locator + """ + return self.get_boolean("isVisible", [locator,]) + + + def is_editable(self,locator): + """ + Determines whether the specified input element is editable, ie hasn't been disabled. + This method will fail if the specified element isn't an input element. + + 'locator' is an element locator + """ + return self.get_boolean("isEditable", [locator,]) + + + def get_all_buttons(self): + """ + Returns the IDs of all buttons on the page. + + If a given button has no ID, it will appear as "" in this array. + + + """ + return self.get_string_array("getAllButtons", []) + + + def get_all_links(self): + """ + Returns the IDs of all links on the page. + + If a given link has no ID, it will appear as "" in this array. + + + """ + return self.get_string_array("getAllLinks", []) + + + def get_all_fields(self): + """ + Returns the IDs of all input fields on the page. + + If a given field has no ID, it will appear as "" in this array. + + + """ + return self.get_string_array("getAllFields", []) + + + def get_attribute_from_all_windows(self,attributeName): + """ + Returns every instance of some attribute from all known windows. + + 'attributeName' is name of an attribute on the windows + """ + return self.get_string_array("getAttributeFromAllWindows", [attributeName,]) + + + def dragdrop(self,locator,movementsString): + """ + deprecated - use dragAndDrop instead + + 'locator' is an element locator + 'movementsString' is offset in pixels from the current location to which the element should be moved, e.g., "+70,-300" + """ + self.do_command("dragdrop", [locator,movementsString,]) + + + def drag_and_drop(self,locator,movementsString): + """ + Drags an element a certain distance and then drops it + + 'locator' is an element locator + 'movementsString' is offset in pixels from the current location to which the element should be moved, e.g., "+70,-300" + """ + self.do_command("dragAndDrop", [locator,movementsString,]) + + + def drag_and_drop_to_object(self,locatorOfObjectToBeDragged,locatorOfDragDestinationObject): + """ + Drags an element and drops it on another element + + 'locatorOfObjectToBeDragged' is an element to be dragged + 'locatorOfDragDestinationObject' is an element whose location (i.e., whose top left corner) will be the point where locatorOfObjectToBeDragged is dropped + """ + self.do_command("dragAndDropToObject", [locatorOfObjectToBeDragged,locatorOfDragDestinationObject,]) + + + def window_focus(self,windowName): + """ + Gives focus to a window + + 'windowName' is name of the window to be given focus + """ + self.do_command("windowFocus", [windowName,]) + + + def window_maximize(self,windowName): + """ + Resize window to take up the entire screen + + 'windowName' is name of the window to be enlarged + """ + self.do_command("windowMaximize", [windowName,]) + + + def get_all_window_ids(self): + """ + Returns the IDs of all windows that the browser knows about. + + """ + return self.get_string_array("getAllWindowIds", []) + + + def get_all_window_names(self): + """ + Returns the names of all windows that the browser knows about. + + """ + return self.get_string_array("getAllWindowNames", []) + + + def get_all_window_titles(self): + """ + Returns the titles of all windows that the browser knows about. + + """ + return self.get_string_array("getAllWindowTitles", []) + + + def get_html_source(self): + """ + Returns the entire HTML source between the opening and + closing "html" tags. + + """ + return self.get_string("getHtmlSource", []) + + + def set_cursor_position(self,locator,position): + """ + Moves the text cursor to the specified position in the given input element or textarea. + This method will fail if the specified element isn't an input element or textarea. + + 'locator' is an element locator pointing to an input element or textarea + 'position' is the numerical position of the cursor in the field; position should be 0 to move the position to the beginning of the field. You can also set the cursor to -1 to move it to the end of the field. + """ + self.do_command("setCursorPosition", [locator,position,]) + + + def get_element_index(self,locator): + """ + Get the relative index of an element to its parent (starting from 0). The comment node and empty text node + will be ignored. + + 'locator' is an element locator pointing to an element + """ + return self.get_number("getElementIndex", [locator,]) + + + def is_ordered(self,locator1,locator2): + """ + Check if these two elements have same parent and are ordered. Two same elements will + not be considered ordered. + + 'locator1' is an element locator pointing to the first element + 'locator2' is an element locator pointing to the second element + """ + return self.get_boolean("isOrdered", [locator1,locator2,]) + + + def get_element_position_left(self,locator): + """ + Retrieves the horizontal position of an element + + 'locator' is an element locator pointing to an element OR an element itself + """ + return self.get_number("getElementPositionLeft", [locator,]) + + + def get_element_position_top(self,locator): + """ + Retrieves the vertical position of an element + + 'locator' is an element locator pointing to an element OR an element itself + """ + return self.get_number("getElementPositionTop", [locator,]) + + + def get_element_width(self,locator): + """ + Retrieves the width of an element + + 'locator' is an element locator pointing to an element + """ + return self.get_number("getElementWidth", [locator,]) + + + def get_element_height(self,locator): + """ + Retrieves the height of an element + + 'locator' is an element locator pointing to an element + """ + return self.get_number("getElementHeight", [locator,]) + + + def get_cursor_position(self,locator): + """ + Retrieves the text cursor position in the given input element or textarea; beware, this may not work perfectly on all browsers. + + Specifically, if the cursor/selection has been cleared by JavaScript, this command will tend to + return the position of the last location of the cursor, even though the cursor is now gone from the page. This is filed as SEL-243. + + This method will fail if the specified element isn't an input element or textarea, or there is no cursor in the element. + + 'locator' is an element locator pointing to an input element or textarea + """ + return self.get_number("getCursorPosition", [locator,]) + + + def set_context(self,context,logLevelThreshold): + """ + Writes a message to the status bar and adds a note to the browser-side + log. + + If logLevelThreshold is specified, set the threshold for logging + to that level (debug, info, warn, error). + (Note that the browser-side logs will \ *not* be sent back to the + server, and are invisible to the Client Driver.) + + + 'context' is the message to be sent to the browser + 'logLevelThreshold' is one of "debug", "info", "warn", "error", sets the threshold for browser-side logging + """ + self.do_command("setContext", [context,logLevelThreshold,]) + + + def get_expression(self,expression): + """ + Returns the specified expression. + + This is useful because of JavaScript preprocessing. + It is used to generate commands like assertExpression and waitForExpression. + + + 'expression' is the value to return + """ + return self.get_string("getExpression", [expression,]) + + + def wait_for_condition(self,script,timeout): + """ + Runs the specified JavaScript snippet repeatedly until it evaluates to "true". + The snippet may have multiple lines, but only the result of the last line + will be considered. + + Note that, by default, the snippet will be run in the runner's test window, not in the window + of your application. To get the window of your application, you can use + the JavaScript snippet ``selenium.browserbot.getCurrentWindow()``, and then + run your JavaScript in there + + + 'script' is the JavaScript snippet to run + 'timeout' is a timeout in milliseconds, after which this command will return with an error + """ + self.do_command("waitForCondition", [script,timeout,]) + + + def set_timeout(self,timeout): + """ + Specifies the amount of time that Selenium will wait for actions to complete. + + Actions that require waiting include "open" and the "waitFor*" actions. + + The default timeout is 30 seconds. + + 'timeout' is a timeout in milliseconds, after which the action will return with an error + """ + self.do_command("setTimeout", [timeout,]) + + + def wait_for_page_to_load(self,timeout): + """ + Waits for a new page to load. + + You can use this command instead of the "AndWait" suffixes, "clickAndWait", "selectAndWait", "typeAndWait" etc. + (which are only available in the JS API). + Selenium constantly keeps track of new pages loading, and sets a "newPageLoaded" + flag when it first notices a page load. Running any other Selenium command after + turns the flag to false. Hence, if you want to wait for a page to load, you must + wait immediately after a Selenium command that caused a page-load. + + + 'timeout' is a timeout in milliseconds, after which this command will return with an error + """ + self.do_command("waitForPageToLoad", [timeout,]) + + + def get_cookie(self): + """ + Return all cookies of the current page under test. + + """ + return self.get_string("getCookie", []) + + + def create_cookie(self,nameValuePair,optionsString): + """ + Create a new cookie whose path and domain are same with those of current page + under test, unless you specified a path for this cookie explicitly. + + 'nameValuePair' is name and value of the cookie in a format "name=value" + 'optionsString' is options for the cookie. Currently supported options include 'path' and 'max_age'. the optionsString's format is "path=/path/, max_age=60". The order of options are irrelevant, the unit of the value of 'max_age' is second. + """ + self.do_command("createCookie", [nameValuePair,optionsString,]) + + + def delete_cookie(self,name,path): + """ + Delete a named cookie with specified path. + + 'name' is the name of the cookie to be deleted + 'path' is the path property of the cookie to be deleted + """ + self.do_command("deleteCookie", [name,path,]) + From gotcha at codespeak.net Thu Feb 1 18:58:50 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Thu, 1 Feb 2007 18:58:50 +0100 (CET) Subject: [KSS-checkins] r37756 - kukit/kss.demo/trunk/kss/demo/tests/selenium Message-ID: <20070201175850.34D1710074@code0.codespeak.net> Author: gotcha Date: Thu Feb 1 18:58:33 2007 New Revision: 37756 Modified: kukit/kss.demo/trunk/kss/demo/tests/selenium/demo1.py Log: trial for linux Modified: kukit/kss.demo/trunk/kss/demo/tests/selenium/demo1.py ============================================================================== --- kukit/kss.demo/trunk/kss/demo/tests/selenium/demo1.py (original) +++ kukit/kss.demo/trunk/kss/demo/tests/selenium/demo1.py Thu Feb 1 18:58:33 2007 @@ -4,13 +4,13 @@ class demo1(unittest.TestCase): def setUp(self): self.verificationErrors = [] - self.selenium = selenium("localhost", 4444, "*firefox", "http://localhost:4444") + self.selenium = selenium("localhost", 4444, "*firefox /usr/lib/firefox/firefox-bin", "http://localhost:4444") self.selenium.start() def test_demo1(self): sel = self.selenium sel.open("/demo/demo1.html") - self.assertEqual("Azax", sel.get_text("demo")) + self.assertEqual("kss", sel.get_text("demo")) self.assertEqual("copy here", sel.get_text("copy")) sel.click("change") for i in range(60): From gotcha at codespeak.net Thu Feb 1 19:27:41 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Thu, 1 Feb 2007 19:27:41 +0100 (CET) Subject: [KSS-checkins] r37762 - kukit/kss.demo/trunk/kss/demo/tests/selenium Message-ID: <20070201182741.A5F2210083@code0.codespeak.net> Author: gotcha Date: Thu Feb 1 19:27:40 2007 New Revision: 37762 Modified: kukit/kss.demo/trunk/kss/demo/tests/selenium/demo1.py Log: trial for linux Modified: kukit/kss.demo/trunk/kss/demo/tests/selenium/demo1.py ============================================================================== --- kukit/kss.demo/trunk/kss/demo/tests/selenium/demo1.py (original) +++ kukit/kss.demo/trunk/kss/demo/tests/selenium/demo1.py Thu Feb 1 19:27:40 2007 @@ -9,8 +9,8 @@ def test_demo1(self): sel = self.selenium - sel.open("/demo/demo1.html") - self.assertEqual("kss", sel.get_text("demo")) + sel.open("/demo/basic_commands.html") + self.assertEqual("KSS", sel.get_text("demo")) self.assertEqual("copy here", sel.get_text("copy")) sel.click("change") for i in range(60): From gotcha at codespeak.net Thu Feb 1 21:55:37 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Thu, 1 Feb 2007 21:55:37 +0100 (CET) Subject: [KSS-checkins] r37768 - in kukit/kss.demo/trunk: kss.demo.egg-info kss/demo/tests/selenium Message-ID: <20070201205537.99D2B10071@code0.codespeak.net> Author: gotcha Date: Thu Feb 1 21:55:34 2007 New Revision: 37768 Modified: kukit/kss.demo/trunk/kss.demo.egg-info/PKG-INFO kukit/kss.demo/trunk/kss.demo.egg-info/SOURCES.txt kukit/kss.demo/trunk/kss.demo.egg-info/dependency_links.txt kukit/kss.demo/trunk/kss/demo/tests/selenium/demo1.py Log: fix port number Modified: kukit/kss.demo/trunk/kss.demo.egg-info/PKG-INFO ============================================================================== --- kukit/kss.demo/trunk/kss.demo.egg-info/PKG-INFO (original) +++ kukit/kss.demo/trunk/kss.demo.egg-info/PKG-INFO Thu Feb 1 21:55:34 2007 @@ -1,6 +1,6 @@ Metadata-Version: 1.0 Name: kss.demo -Version: 0.1dev +Version: 0.1dev-r37755 Summary: KSS (Kinetic Style Sheet) demo Home-page: http://kukit.org Author: KSS Project Modified: kukit/kss.demo/trunk/kss.demo.egg-info/SOURCES.txt ============================================================================== --- kukit/kss.demo/trunk/kss.demo.egg-info/SOURCES.txt (original) +++ kukit/kss.demo/trunk/kss.demo.egg-info/SOURCES.txt Thu Feb 1 21:55:34 2007 @@ -1,6 +1,10 @@ README.txt setup.cfg setup.py +docs/HISTORY.txt +docs/INSTALL.txt +docs/LICENSE.GPL +docs/LICENSE.txt kss/__init__.py kss.demo.egg-info/PKG-INFO kss.demo.egg-info/SOURCES.txt @@ -8,6 +12,79 @@ kss.demo.egg-info/entry_points.txt kss.demo.egg-info/namespace_packages.txt kss.demo.egg-info/not-zip-safe +kss.demo.egg-info/paster_plugins.txt +kss.demo.egg-info/requires.txt kss.demo.egg-info/top_level.txt +kss/demo/EXTERNALS.TXT +kss/demo/INSTALL.txt kss/demo/__init__.py -kss/demo/tests.py +kss/demo/azaxview.py +kss/demo/configure.zcml +kss/demo/helpers.py +kss/demo/interfaces.py +kss/demo/kss.demo-configure.zcml +kss/demo/kss.demo-meta.zcml +kss/demo/meta.zcml +kss/demo/simplecontent.py +kss/demo/simplecontent_z3.py +kss/demo/version.txt +kss/demo/browser/__init__.py +kss/demo/browser/azax_demo.kss +kss/demo/browser/azax_demo.pt +kss/demo/browser/azax_demo_index.pt +kss/demo/browser/azax_effects.kss +kss/demo/browser/azax_effects.pt +kss/demo/browser/azax_instant_edit.kss +kss/demo/browser/azax_instant_edit.pt +kss/demo/browser/azax_three_autoupdate.kss +kss/demo/browser/azax_three_autoupdate.pt +kss/demo/browser/azax_tree.kss +kss/demo/browser/azax_tree.pt +kss/demo/browser/azax_two_select.kss +kss/demo/browser/azax_two_select.pt +kss/demo/browser/azax_xpath.kss +kss/demo/browser/azax_xpath.pt +kss/demo/browser/cancel_submit.kss +kss/demo/browser/cancel_submit.pt +kss/demo/browser/draganddrop.kss +kss/demo/browser/draganddrop.pt +kss/demo/browser/error_handling.kss +kss/demo/browser/error_handling.pt +kss/demo/browser/form_submit.kss +kss/demo/browser/form_submit.pt +kss/demo/browser/header_macros.pt +kss/demo/browser/html_inserts.kss +kss/demo/browser/html_inserts.pt +kss/demo/browser/more_selectors.js +kss/demo/browser/more_selectors.kss +kss/demo/browser/more_selectors.pt +kss/demo/browser/preventdefault.kss +kss/demo/browser/preventdefault.pt +kss/demo/browser/two_select_revisited.kss +kss/demo/browser/two_select_revisited.pt +kss/demo/configfeature/README +kss/demo/configfeature/__init__.py +kss/demo/configfeature/configure.zcml +kss/demo/configfeature/directives.py +kss/demo/configfeature/fiveconfig.py +kss/demo/configfeature/fiveconfig.zcml +kss/demo/configfeature/meta.py +kss/demo/configfeature/meta.zcml +kss/demo/configfeature/metacore.zcml +kss/demo/configfeature/tests/__init__.py +kss/demo/configfeature/tests/__parent__.py +kss/demo/configfeature/tests/configtest.py +kss/demo/configfeature/tests/test_directive.py +kss/demo/configfeature/tests/test_fiveconfig.py +kss/demo/tests/__init__.py +kss/demo/tests/test_azaxview.py +kss/demo/tests/selenium/azax_instant_edit.html +kss/demo/tests/selenium/cancel_submit.html +kss/demo/tests/selenium/demo1.html +kss/demo/tests/selenium/demo1.py +kss/demo/tests/selenium/selenium.py +kss/demo/tests/selenium/suite.html +kss/demo/tests/selenium/three_autopupdate.html +kss/demo/tests/selenium/two_select_revisited.html +kss/demo/tests/selenium/two_selects.html +kss/demo/www/simpleContentAdd.zpt Modified: kukit/kss.demo/trunk/kss.demo.egg-info/dependency_links.txt ============================================================================== --- kukit/kss.demo/trunk/kss.demo.egg-info/dependency_links.txt (original) +++ kukit/kss.demo/trunk/kss.demo.egg-info/dependency_links.txt Thu Feb 1 21:55:34 2007 @@ -1 +1 @@ - +https://codespeak.net/svn/kukit/kss.core/trunk#egg=kss.core-dev Modified: kukit/kss.demo/trunk/kss/demo/tests/selenium/demo1.py ============================================================================== --- kukit/kss.demo/trunk/kss/demo/tests/selenium/demo1.py (original) +++ kukit/kss.demo/trunk/kss/demo/tests/selenium/demo1.py Thu Feb 1 21:55:34 2007 @@ -4,7 +4,7 @@ class demo1(unittest.TestCase): def setUp(self): self.verificationErrors = [] - self.selenium = selenium("localhost", 4444, "*firefox /usr/lib/firefox/firefox-bin", "http://localhost:4444") + self.selenium = selenium("localhost", 4444, "*firefox /usr/lib/firefox/firefox-bin", "http://localhost:8080") self.selenium.start() def test_demo1(self): From reebalazs at codespeak.net Sat Feb 3 14:38:17 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Sat, 3 Feb 2007 14:38:17 +0100 (CET) Subject: [KSS-checkins] r37870 - kukit/kukit.js/trunk/kukit Message-ID: <20070203133817.13A9310072@code0.codespeak.net> Author: reebalazs Date: Sat Feb 3 14:38:14 2007 New Revision: 37870 Modified: kukit/kukit.js/trunk/kukit/eventreg.js kukit/kukit.js/trunk/kukit/kukit.js kukit/kukit.js/trunk/kukit/oper.js kukit/kukit.js/trunk/kukit/resourcedata.js Log: Refactoring done on the snowsprint, the binding process changed to a late binding by default. Modified: kukit/kukit.js/trunk/kukit/eventreg.js ============================================================================== --- kukit/kukit.js/trunk/kukit/eventreg.js (original) +++ kukit/kukit.js/trunk/kukit/eventreg.js Sat Feb 3 14:38:14 2007 @@ -44,6 +44,7 @@ kukit.er.EventRegistry = function () { this.content = {}; this.classes = {}; + this.eventsets = []; }; /* binder registration */ @@ -77,10 +78,10 @@ return func; }; -/* events (methods) registration */ +/* events (methods) registration helpers (not to be called directly) */ -kukit.er.EventRegistry.prototype.register = function(namespace, eventname, klass, - bindmethodname, defaultactionmethodname) { +kukit.er.EventRegistry.prototype._register = function(namespace, eventname, klass, + bindmethodname, defaultactionmethodname, bindmethodapi) { if (typeof(defaultactionmethodname) == 'undefined') { throw 'some arguments are not passed when calling EventRegistry.register'; } @@ -108,10 +109,39 @@ this.content[key] = { 'classname': classname, 'bindmethodname': bindmethodname, - 'defaultactionmethodname': defaultactionmethodname + 'defaultactionmethodname': defaultactionmethodname, + 'bindmethodapi': bindmethodapi }; }; +/* events (methods) binding "ForAll" registration */ + +kukit.er.EventRegistry.prototype._registerEventSet = function(namespace, names) { + // At this name the class and event should be checked already. so this should + // be called _after_ _register. + this.eventsets.push({'namespace': namespace, 'names': names}); +}; + + +/* 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, 'old'); + this._registerEventSet(namespace, [eventname]); +}; + +kukit.er.EventRegistry.prototype.registerForAllEvents = function(namespace, eventnames, klass, + bindmethodname, defaultactionmethodname) { + if (typeof(eventnames) == 'string') { + eventnames = [eventnames]; + } + for (var eventname in eventnames) { + this._register(namespace, eventname, klass, bindmethodname, defaultactionmethodname, 'new'); + } + this._registerEventSet(namespace, eventnames); +}; + kukit.er.EventRegistry.prototype._getKey = function(namespace, eventname) { if (namespace == null) { namespace = ''; @@ -230,7 +260,8 @@ oper.node = node; if (node) { // if we found the binding, just use that - var newoper = oper.getBindingForNode(this, name, node); + var info = kukit.engine.binderInfoRegistry.getBinderInfoById(this.__binder_id__); + var newoper = info.bound.getBoundOperForNode(name, node); if (newoper) { oper = newoper; } @@ -270,7 +301,8 @@ // 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 opers = oper.getBinding(this, name); + var info = kukit.engine.binderInfoRegistry.getBinderInfoById(this.__binder_id__); + var opers = info.getBoundOpers(name); for (var i=0; i>'; + } var id = node.uniqueID; if (typeof(id) == 'undefined') { id = kukit.rd.uid; From reebalazs at codespeak.net Sat Feb 3 14:46:03 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Sat, 3 Feb 2007 14:46:03 +0100 (CET) Subject: [KSS-checkins] r37871 - kukit/kss.core/trunk/kss/core/plugins/draganddrop/browser Message-ID: <20070203134603.C779910072@code0.codespeak.net> Author: reebalazs Date: Sat Feb 3 14:46:00 2007 New Revision: 37871 Modified: kukit/kss.core/trunk/kss/core/plugins/draganddrop/browser/kss_dragdrop.js Log: Make dad work with the current refactorization; (- not in the new way yet) Modified: kukit/kss.core/trunk/kss/core/plugins/draganddrop/browser/kss_dragdrop.js ============================================================================== --- kukit/kss.core/trunk/kss/core/plugins/draganddrop/browser/kss_dragdrop.js (original) +++ kukit/kss.core/trunk/kss/core/plugins/draganddrop/browser/kss_dragdrop.js Sat Feb 3 14:46:00 2007 @@ -4,14 +4,16 @@ }; kukit.draganddrop.DragAndDropEvent.prototype.isNotBoundDraggable = function(oper) { - return ! (oper.getBindingForNode(this, 'drop', oper.node) || - oper.getBindingForNode(this, 'hover', oper.node)); + var info = kukit.engine.binderInfoRegistry.getBinderInfoById(this.__binder_id__); + return ! (info.bound.getBoundOperForNode('drop', oper.node) || + info.bound.getBoundOperForNode('hover', oper.node)); }; kukit.draganddrop.DragAndDropEvent.prototype.isNotBoundDroppable = function(oper) { - return ! (oper.getBindingForNode(this, 'drag', oper.node) || - oper.getBindingForNode(this, 'start', oper.node) || - oper.getBindingForNode(this, 'end', oper.node)); + var info = kukit.engine.binderInfoRegistry.getBinderInfoById(this.__binder_id__); + return ! (info.bound.getBoundOperForNode(this, 'drag', oper.node) || + info.bound.getBoundOperForNode(this, 'start', oper.node) || + info.bound.getBoundOperForNode(this, 'end', oper.node)); }; kukit.draganddrop.DragAndDropEvent.prototype.__bind_drop__ = function(name, func_to_bind, oper) { @@ -47,3 +49,7 @@ kukit.eventsGlobalRegistry.register('dad', 'drag', kukit.draganddrop.DragAndDropEvent, '__bind_drag__', null); kukit.eventsGlobalRegistry.register('dad', 'start', kukit.draganddrop.DragAndDropEvent, '__bind_drag__', null); kukit.eventsGlobalRegistry.register('dad', 'end', kukit.draganddrop.DragAndDropEvent, '__bind_drag__', null); + +//kukit.eventsGlobalRegistry.registerForAllEvents('dad', ['drag', 'start', 'end'], kukit.draganddrop.DragAndDropEvent, '__bind_drag__', null); +//kukit.eventsGlobalRegistry.registerForAllEvents('dad', ['drop', 'hover'], kukit.draganddrop.DragAndDropEvent, '__bind_drop__', null); + From reebalazs at codespeak.net Sat Feb 3 16:47:11 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Sat, 3 Feb 2007 16:47:11 +0100 (CET) Subject: [KSS-checkins] r37874 - kukit/kukit.js/trunk/kukit Message-ID: <20070203154711.CE2EE10071@code0.codespeak.net> Author: reebalazs Date: Sat Feb 3 16:47:10 2007 New Revision: 37874 Modified: kukit/kukit.js/trunk/kukit/eventreg.js Log: Make draganddrop demo again workable Modified: kukit/kukit.js/trunk/kukit/eventreg.js ============================================================================== --- kukit/kukit.js/trunk/kukit/eventreg.js (original) +++ kukit/kukit.js/trunk/kukit/eventreg.js Sat Feb 3 16:47:10 2007 @@ -136,7 +136,8 @@ if (typeof(eventnames) == 'string') { eventnames = [eventnames]; } - for (var eventname in eventnames) { + for (var i=0; i Author: reebalazs Date: Sat Feb 3 16:48:28 2007 New Revision: 37875 Modified: kukit/kss.core/trunk/kss/core/plugins/draganddrop/browser/kss_dragdrop.js Log: Place commands to draganddrop, to show how it works with the new api. Modified: kukit/kss.core/trunk/kss/core/plugins/draganddrop/browser/kss_dragdrop.js ============================================================================== --- kukit/kss.core/trunk/kss/core/plugins/draganddrop/browser/kss_dragdrop.js (original) +++ kukit/kss.core/trunk/kss/core/plugins/draganddrop/browser/kss_dragdrop.js Sat Feb 3 16:48:28 2007 @@ -50,6 +50,22 @@ kukit.eventsGlobalRegistry.register('dad', 'start', kukit.draganddrop.DragAndDropEvent, '__bind_drag__', null); kukit.eventsGlobalRegistry.register('dad', 'end', kukit.draganddrop.DragAndDropEvent, '__bind_drag__', null); -//kukit.eventsGlobalRegistry.registerForAllEvents('dad', ['drag', 'start', 'end'], kukit.draganddrop.DragAndDropEvent, '__bind_drag__', null); -//kukit.eventsGlobalRegistry.registerForAllEvents('dad', ['drop', 'hover'], kukit.draganddrop.DragAndDropEvent, '__bind_drop__', null); +/* +// This is how it should look like: + +kukit.draganddrop.DragAndDropEvent.prototype.__bind_drag__ = function(opers) { + kukit.log('Binding DRAG started'); + for (var i=0; i Author: reebalazs Date: Sat Feb 3 19:39:50 2007 New Revision: 37878 Modified: kukit/kukit.js/trunk/kukit/oper.js Log: Remove debug logging Modified: kukit/kukit.js/trunk/kukit/oper.js ============================================================================== --- kukit/kukit.js/trunk/kukit/oper.js (original) +++ kukit/kukit.js/trunk/kukit/oper.js Sat Feb 3 19:39:50 2007 @@ -147,7 +147,6 @@ kukit.op.Oper.prototype.makeExecuteActionsHook = function () { // Factory that creates the function that executes the actions. // The function may take a dict that is updated on the oper - kukit.log('makehook'); var eventname = this.getEventName(); var self = this; var func_to_bind = function(dict) { From philikon at codespeak.net Sun Feb 4 14:12:55 2007 From: philikon at codespeak.net (philikon at codespeak.net) Date: Sun, 4 Feb 2007 14:12:55 +0100 (CET) Subject: [KSS-checkins] r37903 - kukit/kss.core/branch/philikon-cleanup Message-ID: <20070204131255.96E7C10070@code0.codespeak.net> Author: philikon Date: Sun Feb 4 14:12:49 2007 New Revision: 37903 Added: kukit/kss.core/branch/philikon-cleanup/ - copied from r37902, kukit/kss.core/trunk/ Log: Branch for clean up, especially of deprecated imports and SiteView From philikon at codespeak.net Sun Feb 4 14:34:42 2007 From: philikon at codespeak.net (philikon at codespeak.net) Date: Sun, 4 Feb 2007 14:34:42 +0100 (CET) Subject: [KSS-checkins] r37904 - kukit/kss.core/branch/philikon-cleanup/kss/core Message-ID: <20070204133442.1FE9F10070@code0.codespeak.net> Author: philikon Date: Sun Feb 4 14:34:39 2007 New Revision: 37904 Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/interfaces.py Log: Remove unused import and actually document the *used* interface of IAzaxView. render() is really just a smaller, unimportant method. Much more important is that azax views must have a 'commands' attribute so that the command sets can append their KSS commands. Also, 'getCommandSet' is needed to get the command set (although I think there should also be a shorter spelling, more on that later). Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/interfaces.py ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/interfaces.py (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/interfaces.py Sun Feb 4 14:34:39 2007 @@ -19,11 +19,6 @@ # from zope.interface import Interface, Attribute -try: - # 2.10 - from zope.lifecycleevent.interfaces import IObjectModifiedEvent -except ImportError: - from zope.app.event.objectevent import IObjectModifiedEvent class IAzaxCommands(Interface): 'Azax commands' @@ -106,9 +101,17 @@ '' class IAzaxView(Interface): - #XXX document all interface - def render(): - '' + + commands = Attribute('An IAzaxCommands 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.""" class ICommandSet(Interface): 'Methods of this class implement a command set' From philikon at codespeak.net Sun Feb 4 14:42:21 2007 From: philikon at codespeak.net (philikon at codespeak.net) Date: Sun, 4 Feb 2007 14:42:21 +0100 (CET) Subject: [KSS-checkins] r37905 - kukit/kss.core/branch/philikon-cleanup/kss/core Message-ID: <20070204134221.CE17910074@code0.codespeak.net> Author: philikon Date: Sun Feb 4 14:42:18 2007 New Revision: 37905 Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.py Log: Clean up a horrible mess. I must have not explained the concept of a site (ISite) well enough. The view wasn't implementing ISite, it was manuplating the zope.component.getSite hook manually. How evil, error-prone and thread-unsafe (!). Now the view is a proper ISite, which means its sitemanager will automatically become the active component registry whenever the Zope traverses to the view. The cleanup allowed us to remove a lot of code: * a custom site manager implementation is not necessary, just use a global (i.e. non-persistent registry) * no need to clean up after the getSiteManager() hook mess using IEndRequestEvent Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.py ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.py (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.py Sun Feb 4 14:42:18 2007 @@ -49,25 +49,18 @@ from zope.event import notify from zope.interface import implements, Interface from zope.publisher.browser import BrowserView -from zope.app.publication.interfaces import IEndRequestEvent - -class ViewSiteManager(BaseGlobalComponents): - - def _init_registries(self): - self.adapters = PersistentAdapterRegistry() - self.utilities = PersistentAdapterRegistry() +from zope.app.components.interfaces import ISite class SiteView(BrowserView): """A browser view that is its own site """ + implements(ISite) def __init__(self, context, request): super(SiteView, self).__init__(context, request) _next_sitemanager = component.getSiteManager() - - self._sitemanager = ViewSiteManager('siteview') - + self._sitemanager = BaseGlobalComponents('siteview') self._sitemanager.__bases__ = (_next_sitemanager, ) # On Five, we should wrap it in the acquisition context @@ -83,32 +76,20 @@ # register object event handler self._sitemanager.registerHandler(wrapped_view._eventRedispatcher) + # ISite interface - # first get a reference to the old implementation before making - # ourselves the new default site manager - self._getSiteManagerHook = getSiteManager.implementation - getSiteManager.sethook(self.getSiteManager) - - def getSiteManager(self, context=None): + def getSiteManager(self): return self._sitemanager + def setSiteManager(self, sm): + raise TypeError("Site manager of SiteView can't be changed.") + @component.adapter(Interface) def _eventRedispatcher(self, event): - if IEndRequestEvent.providedBy(event): - # If this happens, we must finish activity - self.stopEventListening() - return if not IAzaxEvent.providedBy(event): azaxevent = AzaxEvent(self, event) notify(azaxevent) - def stopEventListening(self): - # reset the site manager to its original one - getSiteManager.sethook(self._getSiteManagerHook) - - def render(self): - self.stopEventListening() - class AzaxBaseView(SiteView): """ Base kss view @@ -137,7 +118,6 @@ '''All methods must use this to return their command set ''' commands = self.commands.render(self.request) - super(AzaxBaseView, self).render() return commands def cancelRedirect(self): From philikon at codespeak.net Sun Feb 4 14:48:50 2007 From: philikon at codespeak.net (philikon at codespeak.net) Date: Sun, 4 Feb 2007 14:48:50 +0100 (CET) Subject: [KSS-checkins] r37906 - kukit/kss.core/branch/philikon-cleanup/kss/core Message-ID: <20070204134850.3AF8710077@code0.codespeak.net> Author: philikon Date: Sun Feb 4 14:48:48 2007 New Revision: 37906 Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.py Log: some simple cleanup (remove unused imports, fix some comments). Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.py ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.py (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.py Sun Feb 4 14:48:48 2007 @@ -34,34 +34,30 @@ try: from Products.Five import BrowserView except ImportError: - from zope.app.publisher.browser import BrowserView + from zope.publisher.browser import BrowserView -from commands import AzaxCommands -from events import AzaxEvent -from interfaces import IAzaxEvent, IAzaxView, ICommandSet -from pluginregistry.commandset import getRegisteredCommandSet -from zope import app, component, interface -from zope.component import getSiteManager +from kss.core.commands import AzaxCommands +from kss.core.events import AzaxEvent +from kss.core.interfaces import IAzaxEvent, IAzaxView, ICommandSet +from kss.core.pluginregistry.commandset import getRegisteredCommandSet + +from zope import component, interface from zope.component.globalregistry import BaseGlobalComponents -from zope.component.persistentregistry import PersistentAdapterRegistry -from zope.component.interfaces import IComponentLookup -from zope.component.interfaces import ComponentLookupError +from zope.component.interfaces import IComponentLookup, ComponentLookupError from zope.event import notify -from zope.interface import implements, Interface -from zope.publisher.browser import BrowserView from zope.app.components.interfaces import ISite class SiteView(BrowserView): """A browser view that is its own site """ - implements(ISite) + interface.implements(ISite) def __init__(self, context, request): super(SiteView, self).__init__(context, request) - _next_sitemanager = component.getSiteManager() + next = component.getSiteManager() self._sitemanager = BaseGlobalComponents('siteview') - self._sitemanager.__bases__ = (_next_sitemanager, ) + self._sitemanager.__bases__ = (next, ) # On Five, we should wrap it in the acquisition context # see, if self has aq_parent, it is done obligatoraly @@ -91,13 +87,12 @@ notify(azaxevent) class AzaxBaseView(SiteView): - """ Base kss view + """Base KSS view - this allows setting up the content of the response, and then + This allows setting up the content of the response, and then generate it out. """ - - implements(IAzaxView) + interface.implements(IAzaxView) def __init__(self, context, request): super(AzaxBaseView, self).__init__(context, request) @@ -106,19 +101,17 @@ def _initcommands(self): self.commands = AzaxCommands() + # 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): - '''All methods must use this to return their command set - ''' - commands = self.commands.render(self.request) - return commands + """Views can use this to return their command set.""" + return self.commands.render(self.request) def cancelRedirect(self): if self.request.RESPONSE.getStatus() == 302: @@ -134,7 +127,7 @@ return commandset.provides(self) class CommandSet: - implements(ICommandSet) + interface.implements(ICommandSet) # XXX This is really bad. Is is needed for restricted access? # If not, it has to go. If no, it needs an alternate solution. From gotcha at codespeak.net Sun Feb 4 14:53:39 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Sun, 4 Feb 2007 14:53:39 +0100 (CET) Subject: [KSS-checkins] r37907 - in kukit/kss.demo/trunk/kss/demo/tests: selenium selenium_tests Message-ID: <20070204135339.92E7D10077@code0.codespeak.net> Author: gotcha Date: Sun Feb 4 14:53:37 2007 New Revision: 37907 Added: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/ - copied from r37833, kukit/kss.demo/trunk/kss/demo/tests/selenium/ kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/__init__.py kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/patterns.py.txt kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seleniumtestcase.py kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_azax_instant_edit.py kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_basic_commands.py kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_cancel_submit.py kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_three_autopupdate.py kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_two_select_revisited.py kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_two_selects.py Removed: kukit/kss.demo/trunk/kss/demo/tests/selenium/ kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/demo1.py Log: more steps to automate selenium testing Added: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/__init__.py ============================================================================== Deleted: /kukit/kss.demo/trunk/kss/demo/tests/selenium/demo1.py ============================================================================== --- /kukit/kss.demo/trunk/kss/demo/tests/selenium/demo1.py Sun Feb 4 14:53:37 2007 +++ (empty file) @@ -1,97 +0,0 @@ -from selenium import selenium -import unittest, time, re - -class demo1(unittest.TestCase): - def setUp(self): - self.verificationErrors = [] - self.selenium = selenium("localhost", 4444, "*firefox /usr/lib/firefox/firefox-bin", "http://localhost:8080") - self.selenium.start() - - def test_demo1(self): - sel = self.selenium - sel.open("/demo/basic_commands.html") - self.assertEqual("KSS", sel.get_text("demo")) - self.assertEqual("copy here", sel.get_text("copy")) - sel.click("change") - for i in range(60): - try: - if sel.is_element_present("workedagain"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.failUnless(sel.is_element_present("workedagain")) - self.assertEqual("it worked again", sel.get_text("demo")) - sel.click("clear") - for i in range(60): - try: - if not sel.is_element_present("workedagain"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.assertNotEqual("it worked again", sel.get_text("demo")) - sel.click("copyFrom") - for i in range(60): - try: - if "copy here" != sel.get_text("copy"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.assertNotEqual("copy here", sel.get_text("copy")) - self.failIf(sel.is_element_present("workedagain")) - sel.click("change") - for i in range(60): - try: - if sel.is_element_present("workedagain"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.failUnless(sel.is_element_present("workedagain")) - self.assertNotEqual("it worked again", sel.get_text("copy")) - sel.click("copyFrom") - for i in range(60): - try: - if "it worked again" == sel.get_text("copy"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.assertEqual("it worked again", sel.get_text("copy")) - sel.click("clear") - for i in range(60): - try: - if "it worked again" != sel.get_text("demo"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.assertNotEqual("it worked again", sel.get_text("demo")) - sel.click("copyTo") - for i in range(60): - try: - if "it worked again" == sel.get_text("demo"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.assertEqual("it worked again", sel.get_text("demo")) - sel.click("clear") - for i in range(60): - try: - if "it worked again" != sel.get_text("demo"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.assertNotEqual("it worked again", sel.get_text("demo")) - sel.click("moveTo") - for i in range(60): - try: - if "it worked again" == sel.get_text("demo"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.assertEqual("it worked again", sel.get_text("demo")) - self.assertNotEqual("it worked again", sel.get_text("copy")) - - def tearDown(self): - self.selenium.stop() - self.assertEqual([], self.verificationErrors) - -if __name__ == "__main__": - unittest.main() Added: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/patterns.py.txt ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/patterns.py.txt Sun Feb 4 14:53:37 2007 @@ -0,0 +1,23 @@ +#header for selenium IDE +#----------------------- +from seleniumtestcase import SeleniumTestCase +import unittest, time + +def getTestClass(): + return ${className} + +class ${className}(SeleniumTestCase): + + def ${methodName}(self): + sel = self.selenium +#footer for selenium IDE +#----------------------- + +def test_suite(): + return unittest.makeSuite(getTestClass()) + +if __name__ == "__main__": + unittest.main() + + +#bin/zopectl test--package-path ~/tmp/kss.selenium/src/kss.demo/kss/demo/tests kss.demo.tests --test-file-pattern=^seltest --tests-pattern=selenium_tests Added: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seleniumtestcase.py ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seleniumtestcase.py Sun Feb 4 14:53:37 2007 @@ -0,0 +1,23 @@ +import os +import unittest + +from selenium import selenium +try: + browser = os.environ["SELENIUMBROWSER"] +except: + browser = "*firefox" +try: + target = os.environ["SELENIUMTARGET"] +except: + target = "http://localhost:8080" + +class SeleniumTestCase(unittest.TestCase): + def setUp(self): + self.verificationErrors = [] + self.selenium = selenium("localhost", 4444, browser, target) + self.selenium.start() + + def tearDown(self): + self.selenium.stop() + self.assertEqual([], self.verificationErrors) + Added: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_azax_instant_edit.py ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_azax_instant_edit.py Sun Feb 4 14:53:37 2007 @@ -0,0 +1,37 @@ +from seleniumtestcase import SeleniumTestCase +import unittest, time + +def getTestClass(): + return seltest_azax_instant_edit + +class seltest_azax_instant_edit(SeleniumTestCase): + + def test_seltest_azax_instant_edit(self): + sel = self.selenium + sel.open("/demo/azax_instant_edit.html") + self.failUnless(sel.is_text_present("click me!")) + self.assertEqual("click me!", sel.get_text("text")) + sel.click("text") + for i in range(60): + try: + if "click me!" == sel.get_value("value"): break + except: pass + time.sleep(1) + else: self.fail("time out") + self.assertEqual("click me!", sel.get_value("value")) + sel.type("value", "change") + sel.click("save") + for i in range(60): + try: + if sel.is_text_present("change"): break + except: pass + time.sleep(1) + else: self.fail("time out") + self.failUnless(sel.is_text_present("change")) + self.failIf(sel.is_text_present("click me!")) + +def test_suite(): + return unittest.makeSuite(getTestClass()) + +if __name__ == "__main__": + unittest.main() Added: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_basic_commands.py ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_basic_commands.py Sun Feb 4 14:53:37 2007 @@ -0,0 +1,95 @@ +from seleniumtestcase import SeleniumTestCase +import unittest, time + +def getTestClass(): + return seltest_basic_commands + +class seltest_basic_commands(SeleniumTestCase): + + def test_seltest_basic_commands(self): + sel = self.selenium + sel.open("/demo/demo1.html") + self.assertEqual("Azax", sel.get_text("demo")) + self.assertEqual("copy here", sel.get_text("copy")) + sel.click("change") + for i in range(60): + try: + if sel.is_element_present("workedagain"): break + except: pass + time.sleep(1) + else: self.fail("time out") + self.failUnless(sel.is_element_present("workedagain")) + self.assertEqual("it worked again", sel.get_text("demo")) + sel.click("clear") + for i in range(60): + try: + if not sel.is_element_present("workedagain"): break + except: pass + time.sleep(1) + else: self.fail("time out") + self.assertNotEqual("it worked again", sel.get_text("demo")) + sel.click("copyFrom") + for i in range(60): + try: + if "copy here" != sel.get_text("copy"): break + except: pass + time.sleep(1) + else: self.fail("time out") + self.assertNotEqual("copy here", sel.get_text("copy")) + self.failIf(sel.is_element_present("workedagain")) + sel.click("change") + for i in range(60): + try: + if sel.is_element_present("workedagain"): break + except: pass + time.sleep(1) + else: self.fail("time out") + self.failUnless(sel.is_element_present("workedagain")) + self.assertNotEqual("it worked again", sel.get_text("copy")) + sel.click("copyFrom") + for i in range(60): + try: + if "it worked again" == sel.get_text("copy"): break + except: pass + time.sleep(1) + else: self.fail("time out") + self.assertEqual("it worked again", sel.get_text("copy")) + sel.click("clear") + for i in range(60): + try: + if "it worked again" != sel.get_text("demo"): break + except: pass + time.sleep(1) + else: self.fail("time out") + self.assertNotEqual("it worked again", sel.get_text("demo")) + sel.click("copyTo") + for i in range(60): + try: + if "it worked again" == sel.get_text("demo"): break + except: pass + time.sleep(1) + else: self.fail("time out") + self.assertEqual("it worked again", sel.get_text("demo")) + sel.click("clear") + for i in range(60): + try: + if "it worked again" != sel.get_text("demo"): break + except: pass + time.sleep(1) + else: self.fail("time out") + self.assertNotEqual("it worked again", sel.get_text("demo")) + sel.click("moveTo") + for i in range(60): + try: + if "it worked again" == sel.get_text("demo"): break + except: pass + time.sleep(1) + else: self.fail("time out") + self.assertEqual("it worked again", sel.get_text("demo")) + self.assertNotEqual("it worked again", sel.get_text("copy")) + +def test_suite(): + return unittest.makeSuite(getTestClass()) + +if __name__ == "__main__": + unittest.main() Added: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_cancel_submit.py ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_cancel_submit.py Sun Feb 4 14:53:37 2007 @@ -0,0 +1,27 @@ +from seleniumtestcase import SeleniumTestCase +import unittest, time + +def getTestClass(): + return seltest_cancel_submit + +class seltest_cancel_submit(SeleniumTestCase): + + def test_seltest_cancel_submit(self): + sel = self.selenium + sel.open("/demo/cancel_submit.html") + self.assertEqual("", sel.get_value("text_save")) + sel.type("text_save", "abc") + sel.click("submit") + for i in range(60): + try: + if "Async saved abc" == sel.get_text("async"): break + except: pass + time.sleep(1) + else: self.fail("time out") + self.assertEqual("Async saved abc", sel.get_text("async")) + +def test_suite(): + return unittest.makeSuite(getTestClass()) + +if __name__ == "__main__": + unittest.main() Added: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_three_autopupdate.py ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_three_autopupdate.py Sun Feb 4 14:53:37 2007 @@ -0,0 +1,32 @@ +from seleniumtestcase import SeleniumTestCase +import unittest, time + +def getTestClass(): + return seltest_three_autopupdate + +class seltest_three_autopupdate(SeleniumTestCase): + + def test_seltest_three_autopupdate(self): + sel = self.selenium + sel.open("/demo/three_autoupdate.html") + self.assertEqual("", sel.get_text("update-wrapper")) + sel.click("start-update") + for i in range(60): + try: + if sel.is_element_present("update-area"): break + except: pass + time.sleep(1) + else: self.fail("time out") + self.failUnless(sel.is_element_present("update-area")) + self.assertEqual("", sel.get_text("update-area")) + updateText = sel.get_text("update-area") + self.assertEqual(updateText, sel.get_text("update-area")) + time.sleep(3) + self.assertNotEqual(updateText, sel.get_text("update-area")) + # sel.() + +def test_suite(): + return unittest.makeSuite(getTestClass()) + +if __name__ == "__main__": + unittest.main() Added: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_two_select_revisited.py ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_two_select_revisited.py Sun Feb 4 14:53:37 2007 @@ -0,0 +1,71 @@ +from seleniumtestcase import SeleniumTestCase +import unittest, time + +def getTestClass(): + return seltest_two_select_revisited + +class seltest_two_select_revisited(SeleniumTestCase): + + def test_seltest_two_select_revisited(self): + sel = self.selenium + sel.open("/demo/two_select_revisited.html") + self.assertEqual("animals machines", sel.get_text("first-master")) + self.assertEqual("", sel.get_text("first-slave")) + sel.select("first-master", "label=animals") + for i in range(60): + try: + if "dog cat cow" == sel.get_text("first-slave"): break + except: pass + time.sleep(1) + else: self.fail("time out") + self.assertEqual("dog cat cow", sel.get_text("first-slave")) + sel.select("first-master", "label=machines") + for i in range(60): + try: + if "computer car airplane" == sel.get_text("first-slave"): break + except: pass + time.sleep(1) + else: self.fail("time out") + self.assertEqual("computer car airplane", sel.get_text("first-slave")) + self.assertEqual("animals machines", sel.get_text("second-master")) + self.assertEqual("", sel.get_text("second-slave")) + sel.select("second-master", "label=animals") + for i in range(60): + try: + if "dog cat cow" == sel.get_text("second-slave"): break + except: pass + time.sleep(1) + else: self.fail("time out") + self.assertEqual("dog cat cow", sel.get_text("second-slave")) + sel.select("second-master", "label=machines") + for i in range(60): + try: + if "computer car airplane" == sel.get_text("second-slave"): break + except: pass + time.sleep(1) + else: self.fail("time out") + self.assertEqual("computer car airplane", sel.get_text("second-slave")) + self.assertEqual("animals machines", sel.get_text("third-master")) + self.assertEqual("", sel.get_text("third-slave")) + sel.select("third-master", "label=animals") + for i in range(60): + try: + if "dog cat cow" == sel.get_text("third-slave"): break + except: pass + time.sleep(1) + else: self.fail("time out") + self.assertEqual("dog cat cow", sel.get_text("third-slave")) + sel.select("third-master", "label=machines") + for i in range(60): + try: + if "computer car airplane" == sel.get_text("third-slave"): break + except: pass + time.sleep(1) + else: self.fail("time out") + self.assertEqual("computer car airplane", sel.get_text("third-slave")) + +def test_suite(): + return unittest.makeSuite(getTestClass()) + +if __name__ == "__main__": + unittest.main() Added: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_two_selects.py ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_two_selects.py Sun Feb 4 14:53:37 2007 @@ -0,0 +1,35 @@ +from seleniumtestcase import SeleniumTestCase +import unittest, time + +def getTestClass(): + return seltest_two_selects + +class seltest_two_selects(SeleniumTestCase): + + def test_seltest_two_selects(self): + sel = self.selenium + sel.open("/demo/two_selects.html") + self.assertEqual("animals machines", sel.get_text("first")) + self.assertEqual("", sel.get_text("second")) + sel.select("first", "label=animals") + for i in range(60): + try: + if "dog cat cow" == sel.get_text("second"): break + except: pass + time.sleep(1) + else: self.fail("time out") + self.assertEqual("dog cat cow", sel.get_text("second")) + sel.select("first", "label=machines") + for i in range(60): + try: + if "computer car airplane" == sel.get_text("second"): break + except: pass + time.sleep(1) + else: self.fail("time out") + self.assertEqual("computer car airplane", sel.get_text("second")) + +def test_suite(): + return unittest.makeSuite(getTestClass()) + +if __name__ == "__main__": + unittest.main() From philikon at codespeak.net Sun Feb 4 15:06:31 2007 From: philikon at codespeak.net (philikon at codespeak.net) Date: Sun, 4 Feb 2007 15:06:31 +0100 (CET) Subject: [KSS-checkins] r37910 - kukit/kss.core/branch/philikon-cleanup/kss/core Message-ID: <20070204140631.56EBC10072@code0.codespeak.net> Author: philikon Date: Sun Feb 4 15:06:29 2007 New Revision: 37910 Removed: kukit/kss.core/branch/philikon-cleanup/kss/core/events.py Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.py kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.txt kukit/kss.core/branch/philikon-cleanup/kss/core/interfaces.py Log: Bye bye IAzaxEvent. The concept of launching an event in an event handler is error-prone, especially if that event listener is for all events. The new setup is as follows: SiteView adds a listener to object events (I don't think a general event handler is necessary). Those object events will be dispatched to event handlers that subscribe to (object, view, event), e.g.: @adapter(IDocument, None, IObjectModifiedEvent): def updateAfterDocumentHasChanged(doc, view, event): # event is the object modified event # view is the azax view # doc is the object that was modified view.commands.addCommand(...) This is a much more compact spelling and a bit more efficient that what we're currently doing. Plus, the event handlers i've seen in plone.app.kss often do if IObjectModifiedEvent.providedBy(event): ... anyway. That means they're currently called for *every* event though they only really want to listen to a specific one. The new way lets them to do so. Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.py ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.py (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.py Sun Feb 4 15:06:29 2007 @@ -37,15 +37,15 @@ from zope.publisher.browser import BrowserView from kss.core.commands import AzaxCommands -from kss.core.events import AzaxEvent -from kss.core.interfaces import IAzaxEvent, IAzaxView, ICommandSet +from kss.core.interfaces import IAzaxView, ICommandSet from kss.core.pluginregistry.commandset import getRegisteredCommandSet from zope import component, interface +from zope.component import getSiteManager from zope.component.globalregistry import BaseGlobalComponents -from zope.component.interfaces import IComponentLookup, ComponentLookupError -from zope.event import notify -from zope.app.components.interfaces import ISite +from zope.component.interfaces import (IComponentLookup, ComponentLookupError, + IObjectEvent) +from zope.app.component.interfaces import ISite class SiteView(BrowserView): """A browser view that is its own site @@ -80,11 +80,14 @@ def setSiteManager(self, sm): raise TypeError("Site manager of SiteView can't be changed.") - @component.adapter(Interface) + @component.adapter(IObjectEvent) def _eventRedispatcher(self, event): - if not IAzaxEvent.providedBy(event): - azaxevent = AzaxEvent(self, event) - notify(azaxevent) + """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 AzaxBaseView(SiteView): """Base KSS view Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.txt ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.txt (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.txt Sun Feb 4 15:06:29 2007 @@ -16,7 +16,6 @@ normal operation works. >>> from kss.core.azaxview import AzaxBaseView - >>> from kss.core.interfaces import IAzaxEvent >>> from kss.core.tests.base import IDebugRequest >>> from zope import component >>> from zope.lifecycleevent import ObjectModifiedEvent @@ -38,28 +37,37 @@ Now we will write our custom. >>> class SampleView(AzaxBaseView): - ... def add_page(self, title): - ... # normally you would change the zope database here - ... event.notify(ObjectModifiedEvent(title)) + ... def setTitle(self, title): + ... self.context.title = title + ... event.notify(ObjectModifiedEvent(self.context)) ... return self.render() >>> view = SampleView(myfolder, request) - >>> view.add_page("some title") + +Simulate traversal by making the view the current site: + + >>> from zope.app.component.hooks import setSite + >>> setSite(view) + +Let's set a title: + + >>> view.setTitle("some title") [] Now that we have shown that this will not generate any Azax commands we will register a handler. This handler will catch the object event and add some Azax commands. - >>> @component.adapter(IAzaxEvent) - ... def stuff_happend(azax_event): - ... orig_event = azax_event.event - ... azax_event.view.getCommandSet('core').replaceInnerHTML( - ... 'div.class', orig_event.object) + >>> @component.adapter(None, SampleView, IObjectModifiedEvent) + ... def stuff_happend(object, view, event): + ... view.getCommandSet('core').replaceInnerHTML( + ... 'div.class', object.title) >>> component.provideHandler(stuff_happend) When we call the renderer now it should have some more data in it. >>> view = SampleView(myfolder, request) - >>> view.add_page("some title")[0]['params']['html'] + >>> setSite(view) + + >>> view.setTitle(u"some title")[0]['params']['html'] u'some title' Deleted: /kukit/kss.core/branch/philikon-cleanup/kss/core/events.py ============================================================================== --- /kukit/kss.core/branch/philikon-cleanup/kss/core/events.py Sun Feb 4 15:06:29 2007 +++ (empty file) @@ -1,9 +0,0 @@ -from interfaces import IAzaxEvent -from zope.interface import implements - -class AzaxEvent(object): - implements(IAzaxEvent) - - def __init__(self, view, event): - self.view = view - self.event = event Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/interfaces.py ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/interfaces.py (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/interfaces.py Sun Feb 4 15:06:29 2007 @@ -118,12 +118,3 @@ def getCommandSet(self, name): 'Returns the command set for a given name' - -class IAzaxEvent(Interface): - """Used to notify of events during an Ajax call - - This will normally be accompanied by another event.""" - - view = Attribute(u"The Azax view") - event = Attribute(u"The orginal event") - From philikon at codespeak.net Sun Feb 4 15:10:53 2007 From: philikon at codespeak.net (philikon at codespeak.net) Date: Sun, 4 Feb 2007 15:10:53 +0100 (CET) Subject: [KSS-checkins] r37911 - kukit/kss.core/branch/philikon-cleanup/kss/core/tests Message-ID: <20070204141053.3696A1006E@code0.codespeak.net> Author: philikon Date: Sun Feb 4 15:10:51 2007 New Revision: 37911 Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_azaxview.py Log: cleanup: * remove unused stuff * better names here and there * set up hooks in doctest setup so that you can do setSite() Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_azaxview.py ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_azaxview.py (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_azaxview.py Sun Feb 4 15:10:51 2007 @@ -1,4 +1,4 @@ -# -*- coding: ISO-8859-15 -*- +# -*- coding: latin-1 -*- # Copyright (c) 2005-2006 # Authors: # Godefroid Chapelle @@ -19,53 +19,49 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # -import unittest, os -from textwrap import dedent -from zope.testing import doctest -from Testing.ZopeTestCase import FunctionalDocFileSuite -from base import AzaxViewTestCase +import unittest +import textwrap + from kss.core import AzaxUnicodeError +from kss.core.interfaces import IAzaxView, IAzaxCommands from kss.core.plugins.core.interfaces import IKSSCoreCommands -from zope.testing.cleanup import CleanUp as PlacelessSetup -#from kss.core.events import AzaxEvent -from kss.core.interfaces import IAzaxView +from kss.core.plugins.core.commands import KSSCoreCommands from kss.core.pluginregistry.interfaces import IAction, ICommandSet -from kss.core.interfaces import IAzaxCommands #, IAzaxEvent from kss.core.pluginregistry.action import Action from kss.core.pluginregistry.plugin import registerPlugin from kss.core.pluginregistry.commandset import CommandSet -from kss.core.plugins.core.commands import KSSCoreCommands +from kss.core.tests.base import AzaxViewTestCase from kss.core.tests.base import IDebugRequest, KssViewTestCase from kss.core.tests.commandinspector import CommandInspectorView -from zope import component -from Products.Five import zcml -import Products.Five + import zope.component.event -#from zope.app.component.hooks import setSite, getSite, setHooks +from zope.testing import doctest, cleanup +from zope.app.component.hooks import setHooks -def setUpDoctTest(test=None): - PlacelessSetup().setUp() +import Products.Five.component +from Testing.ZopeTestCase import FunctionalDocFileSuite +from Products.Five import zcml +def setUpAjaxView(test=None): zcml.load_config("meta.zcml", Products.Five) zcml.load_config("permissions.zcml", Products.Five) zcml.load_config("configure.zcml", Products.Five.component) - zcml.load_config("configure.zcml", Products.Five.site) + setHooks() - commandview = component.adapter( + commandview = zope.component.adapter( IAzaxCommands, IDebugRequest)(CommandInspectorView) - component.provideAdapter(commandview) + zope.component.provideAdapter(commandview) registerPlugin(Action, IAction, 'replaceInnerHTML', None, 'selector', 'html', [], None) - commands = component.adapter(IAzaxView)(KSSCoreCommands) - component.provideAdapter(commands, provides=IKSSCoreCommands) + commands = zope.component.adapter(IAzaxView)(KSSCoreCommands) + zope.component.provideAdapter(commands, provides=IKSSCoreCommands) registerPlugin(CommandSet, ICommandSet, 'core', IKSSCoreCommands) -def tearDownDoctTest(test=None): - PlacelessSetup().tearDown() - +def tearDownAjaxView(test=None): + cleanup.cleanUp() class TestAzaxView(AzaxViewTestCase): @@ -138,13 +134,13 @@ 'Functional tests' def _wrapped_commands(self, inline): - header = dedent(u'''\ + header = textwrap.dedent(u'''\ ''') - footer = dedent('''\ + footer = textwrap.dedent('''\ ''') @@ -197,8 +193,8 @@ suites.append(unittest.makeSuite(FTestAzaxView)) suites.append(doctest.DocTestSuite('kss.core.azaxview')) suites.append(doctest.DocFileSuite('../azaxview.txt', - setUp=setUpDoctTest, - tearDown=tearDownDoctTest)) + setUp=setUpAjaxView, + tearDown=tearDownAjaxView)) suites.append(FunctionalDocFileSuite('../actionwrapper.py', test_class=KssViewTestCase, setUp=afterSetUp, From philikon at codespeak.net Sun Feb 4 16:13:43 2007 From: philikon at codespeak.net (philikon at codespeak.net) Date: Sun, 4 Feb 2007 16:13:43 +0100 (CET) Subject: [KSS-checkins] r37917 - kukit/kss.core/branch/philikon-cleanup/kss/core Message-ID: <20070204151343.8200810070@code0.codespeak.net> Author: philikon Date: Sun Feb 4 16:13:41 2007 New Revision: 37917 Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.py Log: also support http/1.1 Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.py ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.py (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.py Sun Feb 4 16:13:41 2007 @@ -117,7 +117,7 @@ return self.commands.render(self.request) def cancelRedirect(self): - if self.request.RESPONSE.getStatus() == 302: + if self.request.RESPONSE.getStatus() in (302, 303): # Try to not redirect if requested self.request.RESPONSE.setStatus(200) From philikon at codespeak.net Sun Feb 4 16:18:58 2007 From: philikon at codespeak.net (philikon at codespeak.net) Date: Sun, 4 Feb 2007 16:18:58 +0100 (CET) Subject: [KSS-checkins] r37918 - kukit/kss.core/branch/philikon-cleanup/kss/core Message-ID: <20070204151858.0293310074@code0.codespeak.net> Author: philikon Date: Sun Feb 4 16:18:56 2007 New Revision: 37918 Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.py kukit/kss.core/branch/philikon-cleanup/kss/core/interfaces.py Log: rename AzaxBaseView to KSSView Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.py ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.py (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.py Sun Feb 4 16:18:56 2007 @@ -37,7 +37,7 @@ from zope.publisher.browser import BrowserView from kss.core.commands import AzaxCommands -from kss.core.interfaces import IAzaxView, ICommandSet +from kss.core.interfaces import IKSSView, ICommandSet from kss.core.pluginregistry.commandset import getRegisteredCommandSet from zope import component, interface @@ -89,16 +89,16 @@ for adapter in adapters: pass # getting them does the work -class AzaxBaseView(SiteView): - """Base KSS view +class KSSView(SiteView): + """KSS view This allows setting up the content of the response, and then generate it out. """ - interface.implements(IAzaxView) + interface.implements(IKSSView) def __init__(self, context, request): - super(AzaxBaseView, self).__init__(context, request) + super(KSSView, self).__init__(context, request) self._initcommands() def _initcommands(self): @@ -129,6 +129,9 @@ # return the adapted view return commandset.provides(self) +# BBB deprecated +AzaxBaseView = KSSView + class CommandSet: interface.implements(ICommandSet) @@ -146,5 +149,5 @@ def getCommandSet(self, name): return self.view.getCommandSet(name) -# XXX to be deprecated +# BBB deprecated AzaxViewAdapter = CommandSet Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/interfaces.py ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/interfaces.py (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/interfaces.py Sun Feb 4 16:18:56 2007 @@ -100,7 +100,7 @@ def getContent(self): '' -class IAzaxView(Interface): +class IKSSView(Interface): commands = Attribute('An IAzaxCommands object that keeps track of ' 'all commands that are sent to the browser') @@ -113,6 +113,9 @@ """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' From philikon at codespeak.net Sun Feb 4 16:44:32 2007 From: philikon at codespeak.net (philikon at codespeak.net) Date: Sun, 4 Feb 2007 16:44:32 +0100 (CET) Subject: [KSS-checkins] r37920 - kukit/kss.core/branch/philikon-cleanup/kss/core Message-ID: <20070204154432.07B3710070@code0.codespeak.net> Author: philikon Date: Sun Feb 4 16:44:30 2007 New Revision: 37920 Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/__init__.py Log: * expose renamed KSSView (with BBB for AzaxBaseView). * death to relative imports Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/__init__.py ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/__init__.py (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/__init__.py Sun Feb 4 16:44:30 2007 @@ -1,4 +1,3 @@ -# -*- coding: ISO-8859-15 -*- # Copyright (c) 2006 # Authors: # Godefroid Chapelle @@ -25,13 +24,16 @@ import mimetypes -mimetypes.types_map['.kkt'] = 'text/xml' # XXX legacy! +mimetypes.types_map['.kkt'] = 'text/xml' # BBB legacy! mimetypes.types_map['.kukit'] = 'text/xml' -from azaxview import AzaxBaseView, CommandSet -from actionwrapper import KssExplicitError, kssaction -from unicode_quirks import force_unicode, AzaxUnicodeError -from interfaces import ICommandSet +from kss.core.azaxview import KSSView, CommandSet +from kss.core.actionwrapper import KssExplicitError, kssaction +from kss.core.unicode_quirks import force_unicode, AzaxUnicodeError +from kss.core.interfaces import ICommandSet + +# BBB +from kss.core.azaxview import AzaxBaseView try: import Products.Five From philikon at codespeak.net Sun Feb 4 16:45:08 2007 From: philikon at codespeak.net (philikon at codespeak.net) Date: Sun, 4 Feb 2007 16:45:08 +0100 (CET) Subject: [KSS-checkins] r37921 - in kukit/kss.core/branch/philikon-cleanup/kss/core: . tests Message-ID: <20070204154508.C5BAC10070@code0.codespeak.net> Author: philikon Date: Sun Feb 4 16:45:07 2007 New Revision: 37921 Removed: kukit/kss.core/branch/philikon-cleanup/kss/core/siteview_life.txt Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_siteview.py Log: remove bogus test that became superfluous after my refactoring. Deleted: /kukit/kss.core/branch/philikon-cleanup/kss/core/siteview_life.txt ============================================================================== --- /kukit/kss.core/branch/philikon-cleanup/kss/core/siteview_life.txt Sun Feb 4 16:45:07 2007 +++ (empty file) @@ -1,104 +0,0 @@ -===================== -Site view, life cycle -===================== - -... or, making the view a site manager is a good idea after -all, but let's see what dangers are lurking in the dark. - -Checking if the view finishes its lifetime ------------------------------------------- - -It is important that the view does not stay on after the -request. This would cause them to continue listening to -events. We need a few imports first. - - >>> from kss.core.azaxview import SiteView - - >>> from zope.interface import Interface, implements - >>> from zope.component import adapter - >>> from zope.lifecycleevent import ObjectModifiedEvent - >>> from zope.event import notify - >>> from zope.app.publication.interfaces import IEndRequestEvent - >>> try: - ... from Products.Five.testbrowser import Browser - ... except ImportError: - ... from zope.testbrowser.browser import Browser - -First, let's create a funky view that has two methods, one -failing and one succeeding, and a habit to choke on any -events. - - >>> class FunkyView(SiteView): - ... def IAmGood(self): - ... 'XXX' - ... return self.render() - ... def IAmBad(self): - ... 'XXX' - ... raise Exception, 'Generic badness' - ... @adapter(Interface) - ... def _eventRedispatcher(self, event): - ... SiteView._eventRedispatcher(self, event) - ... if not IEndRequestEvent.providedBy(event): - ... raise Exception, 'Too late event %r' % event - - >>> import kss.core.tests - >>> kss.core.tests.FunkyView = FunkyView - -We provide this view as a browser page. We care to register -it properly, otherwise we would miss some Five acquisition -woodoo. (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 - - >>> load_string(''' - ... - ... - ... - ... - ... ''') - -Create a test browser now, so we can finally start. - - >>> browser = Browser() - -Let's call up the good request. - - >>> browser.open(self.folder.absolute_url() + '/@@funky_view/IAmGood') - -Now, if we happen to send an event... nothing happens, since -the render() method has taken care of unregistering the -event as a SiteView. - - >>> notify(ObjectModifiedEvent(None)) - -But it is also important, that even in case the render -method does not run (it gives an error since we raised an -exception, this is all right). We would already get an error -during this, thanks to the RequestEvent that arrives. - - >>> browser = browser.open('http://nohost/@@funky_view/IAmBad') - Traceback (most recent call last): - ... - HTTPError: HTTP Error 500: Internal Server Error - -And even if we send a new event, it must not get to the -redispatcher of the view. - - >>> notify(ObjectModifiedEvent(None)) - Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_siteview.py ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_siteview.py (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_siteview.py Sun Feb 4 16:45:07 2007 @@ -41,8 +41,4 @@ suite = FunctionalDocFileSuite('../siteview.txt', setUp=setUpDocTest, tearDown=tearDownDocTest) - suite = FunctionalDocFileSuite('../siteview_life.txt', - test_class=KssViewFunctionalTestCase, - setUp=setUpFDocTest, - tearDown=tearDownFDocTest) return unittest.TestSuite(suite) From philikon at codespeak.net Mon Feb 5 00:32:38 2007 From: philikon at codespeak.net (philikon at codespeak.net) Date: Mon, 5 Feb 2007 00:32:38 +0100 (CET) Subject: [KSS-checkins] r37937 - in kukit/kss.core/branch/philikon-cleanup/kss/core: . tests Message-ID: <20070204233238.845061006E@code0.codespeak.net> Author: philikon Date: Mon Feb 5 00:32:36 2007 New Revision: 37937 Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/siteview.txt kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_siteview.py Log: Put some sense in the SiteView test and work towards making it a real unit test. Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/siteview.txt ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/siteview.txt (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/siteview.txt Mon Feb 5 00:32:36 2007 @@ -2,90 +2,69 @@ Site view ========= -All Azax views are not only a browser view but provide a site manager as well. -The site manager is hooked into the component framework on creation time. This -allows the Azax views to intercept all incomming events. - -By doing so the view is able to hookup it's own event redispatcher. This is a -normal event handler which generates the specific Azax events. These events -contain a reference to the view itself. By doing so event handlers can modify -the response body. - -This behaviour is needed for making event driven changes to a page. For -instance when you change a title in a document you also want the menu reloaded. -By using events for this we can achieve a degree of decoupling. - -The main class which implements views with a site manager is `SiteView`. +All KSS views are not only a browser view but provide a site manager +as well. The site manager is hooked into the component framework on +traversal time. This allows the KSS views to dispatch incomming +object events to (object, view, event) so that KSS-view-specific event +handlers can add to the view's commands. + +This behaviour is needed for making event driven changes to a page. +For instance when you change a title in a document you also want the +menu reloaded. By using events for this we can achieve a degree of +decoupling. +The main class which implements views with a site manager is ``SiteView``: + >>> from kss.core.azaxview import SiteView -When created this view will make it's manager the default site manager. - -Context must be >>> from zope import component >>> old_sitemanager = component.getSiteManager() - >>> view = SiteView(None, None) + + >>> from zope.publisher.browser import TestRequest + >>> obj = object() + >>> request = TestRequest + >>> view = SiteView(obj, request) + +Let's make the view the current site. We'll see that its site manager +has become the current component registry: + + >>> from zope.app.component.hooks import setSite, setHooks + >>> setHooks() + >>> setSite(view) + >>> old_sitemanager is component.getSiteManager() False >>> view.getSiteManager() is component.getSiteManager() True -It also immediatly registers its special event handler. Like mentioned earlier -this will dispatch IAzaxEvent's. +The view also immediately registers its special event handler. Like +mentioned earlier this will dispatch to (obj, view, event) handlers. >>> from zope.component.eventtesting import getEvents, clearEvents - >>> from kss.core.interfaces import IAzaxEvent >>> from zope.lifecycleevent import ObjectModifiedEvent >>> from zope.event import notify >>> clearEvents() - >>> notify(ObjectModifiedEvent(None)) - -Two events are fired by this. - - >>> len(getEvents()) - 2 - -The original event and the special IAzaxEvent. - - >>> from zope.lifecycleevent.interfaces import IObjectModifiedEvent - >>> original_event = getEvents()[0] - >>> IObjectModifiedEvent.providedBy(original_event) - True - - >>> azax_event = getEvents()[1] - >>> IAzaxEvent.providedBy(azax_event) - True - -The Azax event has reference to the view and the original event. - - >>> azax_event.event is original_event - True - >>> azax_event.view is view - True - -When the view is rendered it unregisters itself as a site. - - >>> view.render() - >>> view.getSiteManager() is component.getSiteManager() - False -The view also has a specific way of unregistering itself for events. You can -use this from your tests or other specific use cases. First we will create a -new view to start listening. + >>> event = ObjectModifiedEvent(obj) - >>> view = SiteView(None, None) +Let's register a handler for this event and site views: -Now we will stop the view from listening to the events. - - >>> view.stopEventListening() - -If we raise an event we should only get the one event and not the AzaxEvent as well. - - >>> clearEvents() - >>> notify(ObjectModifiedEvent(None)) - >>> len(getEvents()) - 1 - >>> original_event = getEvents()[0] - >>> IObjectModifiedEvent.providedBy(original_event) - True + >>> @component.adapter(None, SiteView, ObjectModifiedEvent) + ... def catchSiteViewEvent(event_obj, event_view, event_event): + ... print "Special event handler was invoked, dispatch is working." + ... print "Object is the original one:", event_obj is obj + ... print "View is the original one:", event_view is view + ... print "Event is the original one:", event_event is event + ... + >>> component.provideHandler(catchSiteViewEvent) + +Now let's send an object modified event. We expect our site view +event handler will be invoked with the original object, view and +event: + + >>> notify(ObjectModifiedEvent(obj)) + Special event handler was invoked, dispatch is working. + Object is the original one: True + View is the original one: True + Event is the original one: False Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_siteview.py ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_siteview.py (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_siteview.py Mon Feb 5 00:32:36 2007 @@ -12,12 +12,6 @@ PlacelessSetup().setUp() eventtesting.setUp() - zcml.load_config("meta.zcml", Products.Five) - zcml.load_config("permissions.zcml", Products.Five) - zcml.load_config("configure.zcml", Products.Five.component) - - zcml.load_config("configure.zcml", Products.Five.site) - def tearDownDocTest(test=None): PlacelessSetup().tearDown() From philikon at codespeak.net Mon Feb 5 00:39:33 2007 From: philikon at codespeak.net (philikon at codespeak.net) Date: Mon, 5 Feb 2007 00:39:33 +0100 (CET) Subject: [KSS-checkins] r37939 - in kukit/kss.core/branch/philikon-cleanup/kss/core: . tests Message-ID: <20070204233933.E91081006E@code0.codespeak.net> Author: philikon Date: Mon Feb 5 00:39:32 2007 New Revision: 37939 Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/siteview.txt kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_siteview.py Log: fix tests so that they run on zope 3 AND on zope 2. Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/siteview.txt ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/siteview.txt (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/siteview.txt Mon Feb 5 00:39:32 2007 @@ -22,14 +22,13 @@ >>> from zope.publisher.browser import TestRequest >>> obj = object() - >>> request = TestRequest + >>> request = TestRequest() >>> view = SiteView(obj, request) Let's make the view the current site. We'll see that its site manager has become the current component registry: - >>> from zope.app.component.hooks import setSite, setHooks - >>> setHooks() + >>> from zope.app.component.hooks import setSite >>> setSite(view) >>> old_sitemanager is component.getSiteManager() @@ -40,12 +39,7 @@ The view also immediately registers its special event handler. Like mentioned earlier this will dispatch to (obj, view, event) handlers. - >>> from zope.component.eventtesting import getEvents, clearEvents >>> from zope.lifecycleevent import ObjectModifiedEvent - >>> from zope.event import notify - - >>> clearEvents() - >>> event = ObjectModifiedEvent(obj) Let's register a handler for this event and site views: @@ -63,6 +57,7 @@ event handler will be invoked with the original object, view and event: + >>> from zope.event import notify >>> notify(ObjectModifiedEvent(obj)) Special event handler was invoked, dispatch is working. Object is the original one: True Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_siteview.py ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_siteview.py (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_siteview.py Mon Feb 5 00:39:32 2007 @@ -1,38 +1,19 @@ -from Products.Five import zcml -from zope import component -from zope.component import eventtesting -from zope.testing import doctest -from zope.testing.cleanup import CleanUp as PlacelessSetup -import Products.Five import unittest -from Testing.ZopeTestCase import FunctionalDocFileSuite -from base import KssViewFunctionalTestCase - -def setUpDocTest(test=None): - PlacelessSetup().setUp() - eventtesting.setUp() - -def tearDownDocTest(test=None): - PlacelessSetup().tearDown() - -def setUpFDocTest(test=None): - #PlacelessSetup().setUp() - KssViewFunctionalTestCase.setUp(test) - eventtesting.setUp() +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 setSite, setHooks -# zcml.load_config("meta.zcml", Products.Five) -# zcml.load_config("permissions.zcml", Products.Five) -# zcml.load_config("configure.zcml", Products.Five.component) -# -# zcml.load_config("configure.zcml", Products.Five.site) -# zcml.load_config("configure.zcml", Products.Five.site) +def setUp(test=None): + setHooks() -def tearDownFDocTest(test=None): - #PlacelessSetup().tearDown() - KssViewFunctionalTestCase.tearDown(test) +def tearDown(test=None): + cleanUp() def test_suite(): - suite = FunctionalDocFileSuite('../siteview.txt', - setUp=setUpDocTest, - tearDown=tearDownDocTest) - return unittest.TestSuite(suite) + return unittest.TestSuite([ + doctest.DocFileSuite('siteview.txt', + package='kss.core', + setUp=setUp, + tearDown=tearDown) + ]) From philikon at codespeak.net Mon Feb 5 00:43:05 2007 From: philikon at codespeak.net (philikon at codespeak.net) Date: Mon, 5 Feb 2007 00:43:05 +0100 (CET) Subject: [KSS-checkins] r37940 - kukit/kss.core/branch/philikon-cleanup/kss/core Message-ID: <20070204234305.872D310070@code0.codespeak.net> Author: philikon Date: Mon Feb 5 00:42:58 2007 New Revision: 37940 Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/siteview.txt Log: Extend test a bit: make sure there's no event dispatching before making the view a site. Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/siteview.txt ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/siteview.txt (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/siteview.txt Mon Feb 5 00:42:58 2007 @@ -25,25 +25,12 @@ >>> request = TestRequest() >>> view = SiteView(obj, request) -Let's make the view the current site. We'll see that its site manager -has become the current component registry: - - >>> from zope.app.component.hooks import setSite - >>> setSite(view) - - >>> old_sitemanager is component.getSiteManager() - False - >>> view.getSiteManager() is component.getSiteManager() - True - -The view also immediately registers its special event handler. Like -mentioned earlier this will dispatch to (obj, view, event) handlers. +Let's register a handler for an object modified event event and +SiteView views: >>> from zope.lifecycleevent import ObjectModifiedEvent >>> event = ObjectModifiedEvent(obj) -Let's register a handler for this event and site views: - >>> @component.adapter(None, SiteView, ObjectModifiedEvent) ... def catchSiteViewEvent(event_obj, event_view, event_event): ... print "Special event handler was invoked, dispatch is working." @@ -53,12 +40,30 @@ ... >>> component.provideHandler(catchSiteViewEvent) -Now let's send an object modified event. We expect our site view -event handler will be invoked with the original object, view and -event: +Without the SiteView view being activated as a site, it won't dispatch +to the handler: >>> from zope.event import notify >>> notify(ObjectModifiedEvent(obj)) + +Now we make the view the current site. We'll see that its site +manager has become the current component registry: + + >>> from zope.app.component.hooks import setSite + >>> setSite(view) + + >>> old_sitemanager is component.getSiteManager() + False + >>> view.getSiteManager() is component.getSiteManager() + True + +The view also immediately registers its special event handler. Like +mentioned earlier this will dispatch to (obj, view, event) handlers, +including the one we defined above. So let's send that object +modified event again. We expect our site view event handler will be +invoked with the original object, view and event: + + >>> notify(ObjectModifiedEvent(obj)) Special event handler was invoked, dispatch is working. Object is the original one: True View is the original one: True From philikon at codespeak.net Mon Feb 5 00:53:20 2007 From: philikon at codespeak.net (philikon at codespeak.net) Date: Mon, 5 Feb 2007 00:53:20 +0100 (CET) Subject: [KSS-checkins] r37941 - kukit/kss.core/branch/philikon-cleanup/kss/core/tests Message-ID: <20070204235320.556D410070@code0.codespeak.net> Author: philikon Date: Mon Feb 5 00:53:17 2007 New Revision: 37941 Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/tests/commandinspector.py Log: get rid of unused imports Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/tests/commandinspector.py ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/tests/commandinspector.py (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/tests/commandinspector.py Mon Feb 5 00:53:17 2007 @@ -17,8 +17,7 @@ # 02111-1307, USA. # -from zope.interface import Interface, implements -from zope.app import zapi +from zope.interface import implements from kss.core.interfaces import IAzaxCommandView class CommandInspectorView(object): From philikon at codespeak.net Mon Feb 5 00:59:46 2007 From: philikon at codespeak.net (philikon at codespeak.net) Date: Mon, 5 Feb 2007 00:59:46 +0100 (CET) Subject: [KSS-checkins] r37942 - kukit/kss.core/branch/philikon-cleanup/kss/core Message-ID: <20070204235946.80BBF10070@code0.codespeak.net> Author: philikon Date: Mon Feb 5 00:59:44 2007 New Revision: 37942 Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.txt Log: Some text re-wrapping and getting rid of unnecessary stuff Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.txt ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.txt (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.txt Mon Feb 5 00:59:44 2007 @@ -1,22 +1,20 @@ -===================== -Azax views and events -===================== +==================== +KSS views and events +==================== + +When we make a change using Ajax calls we would like to update the +browser page. This can be done by sending browser commands. Some part +of the page may need to be update based on modifications. + +We don't want to handle all these modifications in our own code. An +example of such a modification change would be changing the +title. This should also update the navigation portlet. + +To make this work azax views do something special. We will explain +this by creating an example. The following will setup our enviroment +and show that normal operation works. -When we make a change using Ajax calls we would like to update the browser -page. This can be done by sending browser commands. Some part of the page may -need to be update based on modifications. - -We don't want to handle all these modifications in our own code. An example of -such a modification change would be changing the title. This should also update - -the navigation portlet. - -To make this work azax views do something special. We will explain this by -creating an example. The following will setup our enviroment and show that -normal operation works. - - >>> from kss.core.azaxview import AzaxBaseView - >>> from kss.core.tests.base import IDebugRequest + >>> from kss.core import KSSView >>> from zope import component >>> from zope.lifecycleevent import ObjectModifiedEvent >>> from zope.lifecycleevent.interfaces import IObjectModifiedEvent @@ -28,15 +26,11 @@ >>> from zope.app.folder import folder >>> myfolder = folder.rootFolder() - -This will make the commands rendered as test-friendly structures. - >>> request = TestRequest() - >>> directlyProvides(request, directlyProvidedBy(request) + IDebugRequest) Now we will write our custom. - >>> class SampleView(AzaxBaseView): + >>> class SampleView(KSSView): ... def setTitle(self, title): ... self.context.title = title ... event.notify(ObjectModifiedEvent(self.context)) @@ -54,9 +48,9 @@ >>> view.setTitle("some title") [] -Now that we have shown that this will not generate any Azax commands we will -register a handler. This handler will catch the object event and add some Azax -commands. +Now that we have shown that this will not generate any KSS commands +we will register a handler. This handler will catch the object event +and add some Azax commands. >>> @component.adapter(None, SampleView, IObjectModifiedEvent) ... def stuff_happend(object, view, event): From philikon at codespeak.net Mon Feb 5 01:00:12 2007 From: philikon at codespeak.net (philikon at codespeak.net) Date: Mon, 5 Feb 2007 01:00:12 +0100 (CET) Subject: [KSS-checkins] r37943 - kukit/kss.core/branch/philikon-cleanup/kss/core/tests Message-ID: <20070205000012.5E4AD10070@code0.codespeak.net> Author: philikon Date: Mon Feb 5 01:00:10 2007 New Revision: 37943 Added: kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_azaxview_core.py (contents, props changed) Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/tests/base.py kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_azaxview.py Log: Make more tests work in Zope 2 AND 3. Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/tests/base.py ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/tests/base.py (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/tests/base.py Mon Feb 5 01:00:10 2007 @@ -1,4 +1,4 @@ -# -*- coding: ISO-8859-15 -*- +# -*- coding: latin-1 -*- # Copyright (c) 2005-2006 # Authors: # Godefroid Chapelle @@ -19,27 +19,22 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # +from textwrap import dedent + from Testing.ZopeTestCase import ZopeTestCase, FunctionalTestCase -import kss.core -from kss.core import AzaxBaseView from OFS.SimpleItem import SimpleItem -from textwrap import dedent + +from zope import interface from zope.publisher.browser import TestRequest from zope.publisher.interfaces.browser import IBrowserRequest -from zope.interface import Interface, implements -from zope import interface as iapi +from zope.app.testing import placelesssetup -try: - # Zope > 2.8 - from zope.app.testing import placelesssetup -except ImportError: - # Zope == 2.8 - from zope.app.tests import placelesssetup +import kss.core +from kss.core import KSSView -# Test view -# -class TestView(AzaxBaseView): +# Test view +class TestView(KSSView): def testMethod(self): 'Yes.' @@ -108,7 +103,7 @@ def setDebugRequest(self): 'commands will be rendered as test friendly data structures' request = self.folder.REQUEST - iapi.directlyProvides(request, iapi.directlyProvidedBy(request) + IDebugRequest) + interface.directlyProvides(request, interface.directlyProvidedBy(request) + IDebugRequest) def beforeTearDown(self): placelesssetup.tearDown() Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_azaxview.py ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_azaxview.py (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_azaxview.py Mon Feb 5 01:00:10 2007 @@ -20,183 +20,40 @@ # 02111-1307, USA. # import unittest -import textwrap -from kss.core import AzaxUnicodeError -from kss.core.interfaces import IAzaxView, IAzaxCommands +from kss.core.interfaces import IKSSView, IAzaxCommands 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.base import AzaxViewTestCase -from kss.core.tests.base import IDebugRequest, KssViewTestCase 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 -import Products.Five.component -from Testing.ZopeTestCase import FunctionalDocFileSuite -from Products.Five import zcml - def setUpAjaxView(test=None): - zcml.load_config("meta.zcml", Products.Five) - zcml.load_config("permissions.zcml", Products.Five) - zcml.load_config("configure.zcml", Products.Five.component) - setHooks() - - commandview = zope.component.adapter( - IAzaxCommands, IDebugRequest)(CommandInspectorView) - zope.component.provideAdapter(commandview) - - registerPlugin(Action, IAction, 'replaceInnerHTML', None, 'selector', - 'html', [], None) - commands = zope.component.adapter(IAzaxView)(KSSCoreCommands) - zope.component.provideAdapter(commands, provides=IKSSCoreCommands) - + zope.component.provideAdapter(CommandInspectorView, + adapts=(IAzaxCommands, 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() -class TestAzaxView(AzaxViewTestCase): - - 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), 1) - self.assertEqual(params[0].getName(), 'html') - 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(AzaxUnicodeError, self._checkSetHtmlResult, 'abc?') - -class FTestAzaxView(AzaxViewTestCase): - '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 - -''' - 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 - -''' - self.assertCommandsEqual(result, awaited) - -def afterSetUp(self): - KssViewTestCase.afterSetUp(self) - self.setDebugRequest() - def test_suite(): - suites = [] - suites.append(unittest.makeSuite(TestAzaxView)) - suites.append(unittest.makeSuite(FTestAzaxView)) - suites.append(doctest.DocTestSuite('kss.core.azaxview')) - suites.append(doctest.DocFileSuite('../azaxview.txt', - setUp=setUpAjaxView, - tearDown=tearDownAjaxView)) - suites.append(FunctionalDocFileSuite('../actionwrapper.py', - test_class=KssViewTestCase, - setUp=afterSetUp, - tearDown=KssViewTestCase.beforeTearDown.im_func)) - return unittest.TestSuite(suites) + return unittest.TestSuite([ + doctest.DocTestSuite('kss.core.azaxview'), + doctest.DocFileSuite('azaxview.txt', + package='kss.core', + setUp=setUpAjaxView, + tearDown=tearDownAjaxView), + ]) Added: kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_azaxview_core.py ============================================================================== --- (empty file) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_azaxview_core.py Mon Feb 5 01:00:10 2007 @@ -0,0 +1,140 @@ +import unittest +import textwrap +from kss.core import AzaxUnicodeError +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), 1) + self.assertEqual(params[0].getName(), 'html') + 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(AzaxUnicodeError, 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 + +''' + 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 + +''' + 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) From tomster at codespeak.net Mon Feb 5 15:42:04 2007 From: tomster at codespeak.net (tomster at codespeak.net) Date: Mon, 5 Feb 2007 15:42:04 +0100 (CET) Subject: [KSS-checkins] r37968 - kukit/kss.core/trunk/kss/core/plugins/draganddrop/browser Message-ID: <20070205144204.26B5B1007F@code0.codespeak.net> Author: tomster Date: Mon Feb 5 15:42:01 2007 New Revision: 37968 Modified: kukit/kss.core/trunk/kss/core/plugins/draganddrop/browser/kss_dragdrop.js Log: added ''constraint'' parameter to `dad-drag` event (default is no constraint) Modified: kukit/kss.core/trunk/kss/core/plugins/draganddrop/browser/kss_dragdrop.js ============================================================================== --- kukit/kss.core/trunk/kss/core/plugins/draganddrop/browser/kss_dragdrop.js (original) +++ kukit/kss.core/trunk/kss/core/plugins/draganddrop/browser/kss_dragdrop.js Mon Feb 5 15:42:01 2007 @@ -32,13 +32,17 @@ kukit.draganddrop.DragAndDropEvent.prototype.__bind_drag__ = function(name, func_to_bind, oper) { // validate and set parameters - oper.completeParms([], {}, 'dad-drag event binding'); + oper.completeParms([], {'constraint' : 'not-set'}, 'dad-drag event binding'); if (this.isNotBoundDraggable(oper)) { var options = { onDrag : this.__make_func_to_bind__('drag', oper.node), onStart : this.__make_func_to_bind__('start', oper.node), onEnd : this.__make_func_to_bind__('end', oper.node) }; + if (oper.parms.constraint == 'horizontal' || oper.parms.constraint == 'vertical') { + kukit.logDebug('constraint: ' + oper.parms.constraint + "|" + name); + options['constraint'] = oper.parms.constraint; + } new Draggable(oper.node, options); kukit.logDebug('Draggable bound'); } From tomster at codespeak.net Mon Feb 5 15:42:54 2007 From: tomster at codespeak.net (tomster at codespeak.net) Date: Mon, 5 Feb 2007 15:42:54 +0100 (CET) Subject: [KSS-checkins] r37969 - kukit/kss.demo/trunk/kss/demo/browser Message-ID: <20070205144254.1E6481007F@code0.codespeak.net> Author: tomster Date: Mon Feb 5 15:42:52 2007 New Revision: 37969 Modified: kukit/kss.demo/trunk/kss/demo/browser/draganddrop.kss kukit/kss.demo/trunk/kss/demo/browser/draganddrop.pt Log: expanded the dad-demo to show off the new constraint parameter introduced in r37968 Modified: kukit/kss.demo/trunk/kss/demo/browser/draganddrop.kss ============================================================================== --- kukit/kss.demo/trunk/kss/demo/browser/draganddrop.kss (original) +++ kukit/kss.demo/trunk/kss/demo/browser/draganddrop.kss Mon Feb 5 15:42:52 2007 @@ -1,7 +1,32 @@ -/* .draggable:dad-drag { } -*/ + +.horizontal:dad-start { + evt-dad-start-constraint: horizontal; +} + +.horizontal:dad-end { + evt-dad-end-constraint: horizontal; +} + +.horizontal:dad-drag { + evt-dad-drag-constraint: horizontal; +} + +.vertical:dad-start { + evt-dad-start-constraint: vertical; +} + +.vertical:dad-end { + evt-dad-end-constraint: vertical; +} + +.vertical:dad-drag { + evt-dad-drag-constraint: vertical; +} + +} + .draggable:dad-start { action-client: logDebug; action-client: setStyle; Modified: kukit/kss.demo/trunk/kss/demo/browser/draganddrop.pt ============================================================================== --- kukit/kss.demo/trunk/kss/demo/browser/draganddrop.pt (original) +++ kukit/kss.demo/trunk/kss/demo/browser/draganddrop.pt Mon Feb 5 15:42:52 2007 @@ -12,6 +12,25 @@ .droppable { background-color: gray; } + table.wrapper td.wide div { + float: left; + } + table.wrapper td div, + .droppable { + width: 80px; + border: 1px solid purple; + margin-bottom: .5em; + } + table.wrapper td.wide { + width: 400px; + } + + table.wrapper td.wide div { + margin-right: .5em; + } + table.wrapper td { + vertical-align: top; + } @@ -19,8 +38,29 @@

Start logging pane

View KSS resource

Drag and drop

-
Drag me
-
Drop me here
-
or here
+ + + + + + + + + + + +
FreeVerticalHorizontal
+
Drag me
+
Drop me here
+
or here
+
+
Drag me
+
Drop me here
+
or here
+
+
Drag me
+
Drop me here
+
or here
+
From philikon at codespeak.net Mon Feb 5 22:01:42 2007 From: philikon at codespeak.net (philikon at codespeak.net) Date: Mon, 5 Feb 2007 22:01:42 +0100 (CET) Subject: [KSS-checkins] r37982 - kukit/kss.core/branch/philikon-cleanup/kss/core Message-ID: <20070205210142.4802E1007C@code0.codespeak.net> Author: philikon Date: Mon Feb 5 22:01:37 2007 New Revision: 37982 Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.py kukit/kss.core/branch/philikon-cleanup/kss/core/siteview.txt Log: Make it possible to use SiteView below a persistent site. My cleanup was a bit too rigid (though the fault really lies in the weirdness of the default global AdapterRegistry implementation). Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.py ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.py (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.py Mon Feb 5 22:01:37 2007 @@ -41,12 +41,22 @@ from kss.core.pluginregistry.commandset import getRegisteredCommandSet from zope import component, interface +from zope.interface.adapter import VerifyingAdapterRegistry from zope.component import getSiteManager from zope.component.globalregistry import BaseGlobalComponents from zope.component.interfaces import (IComponentLookup, ComponentLookupError, IObjectEvent) from zope.app.component.interfaces import ISite +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() + class SiteView(BrowserView): """A browser view that is its own site """ @@ -56,7 +66,7 @@ super(SiteView, self).__init__(context, request) next = component.getSiteManager() - self._sitemanager = BaseGlobalComponents('siteview') + self._sitemanager = SiteViewComponents('siteview') self._sitemanager.__bases__ = (next, ) # On Five, we should wrap it in the acquisition context Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/siteview.txt ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/siteview.txt (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/siteview.txt Mon Feb 5 22:01:37 2007 @@ -21,7 +21,9 @@ >>> old_sitemanager = component.getSiteManager() >>> from zope.publisher.browser import TestRequest - >>> obj = object() + >>> class TestObject: + ... pass + >>> obj = TestObject() >>> request = TestRequest() >>> view = SiteView(obj, request) @@ -31,14 +33,14 @@ >>> from zope.lifecycleevent import ObjectModifiedEvent >>> event = ObjectModifiedEvent(obj) - >>> @component.adapter(None, SiteView, ObjectModifiedEvent) - ... def catchSiteViewEvent(event_obj, event_view, event_event): + >>> @component.adapter(TestObject, SiteView, ObjectModifiedEvent) + ... def catchTestObjectEvent(event_obj, event_view, event_event): ... print "Special event handler was invoked, dispatch is working." ... print "Object is the original one:", event_obj is obj ... print "View is the original one:", event_view is view ... print "Event is the original one:", event_event is event ... - >>> component.provideHandler(catchSiteViewEvent) + >>> component.provideHandler(catchTestObjectEvent) Without the SiteView view being activated as a site, it won't dispatch to the handler: @@ -68,3 +70,48 @@ Object is the original one: True View is the original one: True Event is the original one: False + +Below a site +------------ + +Let's say SiteView is operating below a persistent site, e.g. the root +folder or a CMF site: + + >>> from zope.app.folder import Folder + >>> from zope.app.component.interfaces import ISite + >>> from zope.interface import alsoProvides + >>> from zope.component.globalregistry import base + >>> from zope.component.persistentregistry import PersistentComponents + + >>> site = Folder() + >>> components = PersistentComponents() + >>> components.__bases__ = (base,) + >>> site.setSiteManager(components) + >>> alsoProvides(site, ISite) + + >>> setSite(site) + +Let's also register a site view event subscriber *globally* and one +*locally* + + >>> @component.adapter(ISite, SiteView, ObjectModifiedEvent) + ... def catchSiteEventGlobally(event_obj, event_view, event_event): + ... print "Global event handler was invoked, dispatch is working." + ... + >>> component.provideHandler(catchSiteEventGlobally) + + >>> @component.adapter(ISite, SiteView, ObjectModifiedEvent) + ... def catchSiteEventLocally(event_obj, event_view, event_event): + ... print "Local event handler was invoked, dispatch is working." + ... + >>> components.registerHandler(catchSiteEventLocally) + +Let's now verify the SiteView still works and dispatches component +lookup accordingly. + + >>> view = SiteView(site, request) + >>> setSite(view) + + >>> notify(ObjectModifiedEvent(site)) + Global event handler was invoked, dispatch is working. + Local event handler was invoked, dispatch is working. From gotcha at codespeak.net Tue Feb 6 12:43:18 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Tue, 6 Feb 2007 12:43:18 +0100 (CET) Subject: [KSS-checkins] r38002 - kukit/kss.demo/trunk/kss/demo/tests/selenium_tests Message-ID: <20070206114318.A3B8310070@code0.codespeak.net> Author: gotcha Date: Tue Feb 6 12:43:17 2007 New Revision: 38002 Modified: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_basic_commands.py Log: fix test for name changes Modified: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_basic_commands.py ============================================================================== --- kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_basic_commands.py (original) +++ kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_basic_commands.py Tue Feb 6 12:43:17 2007 @@ -9,7 +9,7 @@ def test_seltest_basic_commands(self): sel = self.selenium sel.open("/demo/demo1.html") - self.assertEqual("Azax", sel.get_text("demo")) + self.assertEqual("KSS", sel.get_text("demo")) self.assertEqual("copy here", sel.get_text("copy")) sel.click("change") for i in range(60): From gotcha at codespeak.net Tue Feb 6 13:54:41 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Tue, 6 Feb 2007 13:54:41 +0100 (CET) Subject: [KSS-checkins] r38003 - kukit/kss.demo/trunk/kss/demo/tests/selenium_tests Message-ID: <20070206125441.516A410070@code0.codespeak.net> Author: gotcha Date: Tue Feb 6 13:54:39 2007 New Revision: 38003 Modified: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_basic_commands.py Log: fix test for url change Modified: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_basic_commands.py ============================================================================== --- kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_basic_commands.py (original) +++ kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_basic_commands.py Tue Feb 6 13:54:39 2007 @@ -8,7 +8,7 @@ def test_seltest_basic_commands(self): sel = self.selenium - sel.open("/demo/demo1.html") + sel.open("/demo/basic_commands.html") self.assertEqual("KSS", sel.get_text("demo")) self.assertEqual("copy here", sel.get_text("copy")) sel.click("change") From gotcha at codespeak.net Tue Feb 6 15:07:24 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Tue, 6 Feb 2007 15:07:24 +0100 (CET) Subject: [KSS-checkins] r38008 - kukit/kss.demo/trunk/kss/demo/tests/selenium_tests Message-ID: <20070206140724.78C6910070@code0.codespeak.net> Author: gotcha Date: Tue Feb 6 15:07:22 2007 New Revision: 38008 Modified: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_basic_commands.py Log: check-in broken test to test ;-) buildbot Modified: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_basic_commands.py ============================================================================== --- kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_basic_commands.py (original) +++ kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_basic_commands.py Tue Feb 6 15:07:22 2007 @@ -9,7 +9,7 @@ def test_seltest_basic_commands(self): sel = self.selenium sel.open("/demo/basic_commands.html") - self.assertEqual("KSS", sel.get_text("demo")) + self.assertEqual("sKSS", sel.get_text("demo")) self.assertEqual("copy here", sel.get_text("copy")) sel.click("change") for i in range(60): From gotcha at codespeak.net Tue Feb 6 15:15:59 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Tue, 6 Feb 2007 15:15:59 +0100 (CET) Subject: [KSS-checkins] r38009 - kukit/kss.demo/trunk/kss/demo/tests/selenium_tests Message-ID: <20070206141559.1B0FC10072@code0.codespeak.net> Author: gotcha Date: Tue Feb 6 15:15:56 2007 New Revision: 38009 Modified: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_basic_commands.py Log: fix test to test ;-) buildbot Modified: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_basic_commands.py ============================================================================== --- kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_basic_commands.py (original) +++ kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_basic_commands.py Tue Feb 6 15:15:56 2007 @@ -9,7 +9,7 @@ def test_seltest_basic_commands(self): sel = self.selenium sel.open("/demo/basic_commands.html") - self.assertEqual("sKSS", sel.get_text("demo")) + self.assertEqual("KSS", sel.get_text("demo")) self.assertEqual("copy here", sel.get_text("copy")) sel.click("change") for i in range(60): From gotcha at codespeak.net Tue Feb 6 16:47:21 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Tue, 6 Feb 2007 16:47:21 +0100 (CET) Subject: [KSS-checkins] r38010 - kukit/kss.demo/trunk/kss/demo/tests/selenium_tests Message-ID: <20070206154721.061B610072@code0.codespeak.net> Author: gotcha Date: Tue Feb 6 16:47:20 2007 New Revision: 38010 Modified: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_basic_commands.py Log: comments to trigger buildbot Modified: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_basic_commands.py ============================================================================== --- kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_basic_commands.py (original) +++ kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_basic_commands.py Tue Feb 6 16:47:20 2007 @@ -9,6 +9,7 @@ def test_seltest_basic_commands(self): sel = self.selenium sel.open("/demo/basic_commands.html") + #test initial state self.assertEqual("KSS", sel.get_text("demo")) self.assertEqual("copy here", sel.get_text("copy")) sel.click("change") From gotcha at codespeak.net Tue Feb 6 17:13:20 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Tue, 6 Feb 2007 17:13:20 +0100 (CET) Subject: [KSS-checkins] r38014 - kukit/kss.buildbot Message-ID: <20070206161320.36BA010077@code0.codespeak.net> Author: gotcha Date: Tue Feb 6 17:13:03 2007 New Revision: 38014 Added: kukit/kss.buildbot/ Log: buildbot configs From gotcha at codespeak.net Tue Feb 6 17:13:29 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Tue, 6 Feb 2007 17:13:29 +0100 (CET) Subject: [KSS-checkins] r38015 - kukit/kss.buildbot/trunk Message-ID: <20070206161329.AB88E1007D@code0.codespeak.net> Author: gotcha Date: Tue Feb 6 17:13:28 2007 New Revision: 38015 Added: kukit/kss.buildbot/trunk/ Log: buildbot configs From gotcha at codespeak.net Tue Feb 6 17:15:50 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Tue, 6 Feb 2007 17:15:50 +0100 (CET) Subject: [KSS-checkins] r38016 - kukit/kss.buildbot/trunk Message-ID: <20070206161550.CE7631007C@code0.codespeak.net> Author: gotcha Date: Tue Feb 6 17:15:44 2007 New Revision: 38016 Added: kukit/kss.buildbot/trunk/master.cfg.in Log: first working setup Added: kukit/kss.buildbot/trunk/master.cfg.in ============================================================================== --- (empty file) +++ kukit/kss.buildbot/trunk/master.cfg.in Tue Feb 6 17:15:44 2007 @@ -0,0 +1,196 @@ +# -*- python -*- +# ex: set syntax=python: + +# This is a sample buildmaster config file. It must be installed as +# 'master.cfg' in your buildmaster's base directory (although the filename +# can be changed with the --basedir option to 'mktap buildbot master'). + +# It has one job: define a dictionary named BuildmasterConfig. This +# dictionary has a variety of keys to control different aspects of the +# buildmaster. They are documented in docs/config.xhtml . + + +# This is the dictionary that the buildmaster pays attention to. We also use +# a shorter alias to save typing. +c = BuildmasterConfig = {} + +####### BUILDSLAVES + +# the 'bots' list defines the set of allowable buildslaves. Each element is a +# tuple of bot-name and bot-password. These correspond to values given to the +# buildslave's mktap invocation. +c['bots'] = [ + ("bubblenetlinux", "xxxxx"), + ("bubblenetwindows", "xxxx"), +] + + +# 'slavePortnum' defines the TCP port to listen on. This must match the value +# configured into the buildslaves (with their --master option) + +c['slavePortnum'] = 9989 + + +####### CHANGESOURCES + +# the 'sources' list tells the buildmaster how it should find out about +# source code changes. Any class which implements IChangeSource can be added +# to this list: there are several in buildbot/changes/*.py to choose from. + +c['sources'] = [] + +# For example, if you had CVSToys installed on your repository, and your +# CVSROOT/freshcfg file had an entry like this: +#pb = ConfigurationSet([ +# (None, None, None, PBService(userpass=('foo', 'bar'), port=4519)), +# ]) + +# then you could use the following buildmaster Change Source to subscribe to +# the FreshCVS daemon and be notified on every commit: +# +#from buildbot.changes.freshcvs import FreshCVSSource +#fc_source = FreshCVSSource("cvs.example.com", 4519, "foo", "bar") +#c['sources'].append(fc_source) + +# or, use a PBChangeSource, and then have your repository's commit script run +# 'buildbot sendchange', or contrib/svn_buildbot.py, or +# contrib/arch_buildbot.py : +# +#from buildbot.changes.pb import PBChangeSource +#c['sources'].append(PBChangeSource()) + +from buildbot.changes.svnpoller import SVNPoller +ksscore = 'http://codespeak.net/svn/kukit/kss.core/trunk' +kssdemo = 'http://codespeak.net/svn/kukit/kss.demo/trunk' +c['sources'].append(SVNPoller(svnurl=ksscore)) +c['sources'].append(SVNPoller(svnurl=kssdemo)) + + +####### SCHEDULERS + +## configure the Schedulers + +from buildbot.scheduler import Scheduler +from buildbot.scheduler import Periodic +c['schedulers'] = [] +scheduler = Scheduler(name="all", branch=None, + treeStableTimer=2*60, + builderNames=["kss-firefox-linux"]) +periodic = Periodic(name="all", branch=None, + periodicBuildTimer=300,#seconds + builderNames=["kss-firefox-linux"]) +c['schedulers'].append(scheduler) + + + +####### BUILDERS + +# the 'builders' list defines the Builders. Each one is configured with a +# dictionary, using the following keys: +# name (required): the name used to describe this bilder +# slavename (required): which slave to use, must appear in c['bots'] +# builddir (required): which subdirectory to run the builder in +# factory (required): a BuildFactory to define how the build is run +# periodicBuildTime (optional): if set, force a build every N seconds + +# buildbot/process/factory.py provides several BuildFactory classes you can +# start with, which implement build processes for common targets (GNU +# autoconf projects, CPAN perl modules, etc). The factory.BuildFactory is the +# base class, and is configured with a series of BuildSteps. When the build +# is run, the appropriate buildslave is told to execute each Step in turn. + +# the first BuildStep is typically responsible for obtaining a copy of the +# sources. There are source-obtaining Steps in buildbot/process/step.py for +# CVS, SVN, and others. + +cvsroot = ":pserver:anonymous at cvs.sourceforge.net:/cvsroot/buildbot" +cvsmodule = "buildbot" + +builders = [] + +from buildbot.process import factory +from buildbot.steps import source, shell + +class KSSSVN(source.SVN): + def computeSourceRevision(self, changes): + #don't take changes in account + return None + +f1 = factory.BuildFactory() +f1.addStep(KSSSVN, svnurl="https://svn.zitc.de/svn/snowsprint/buildbot/kss.selenium") +f1.addStep(shell.ShellCommand, + command=["python2.4","bootstrap.py"], +) +f1.addStep(shell.ShellCommand, command=["bin/buildout", "-v"]) +f1.addStep(shell.ShellCommand, command=["python", "dotests.py"]) + +b1 = {'name': "kss-firefox-linux", + 'slavenames': [ + "bubblenetlinux", + ], + 'builddir': "kss-firefox-linux", + 'factory': f1, } +c['builders'] = [b1] + + +####### STATUS TARGETS + +# 'status' is a list of Status Targets. The results of each build will be +# pushed to these targets. buildbot/status/*.py has a variety to choose from, +# including web pages, email senders, and IRC bots. + +c['status'] = [] + +from buildbot.status import html +c['status'].append(html.Waterfall(http_port=8010)) + +# from buildbot.status import mail +# c['status'].append(mail.MailNotifier(fromaddr="buildbot at localhost", +# extraRecipients=["builds at example.com"], +# sendToInterestedUsers=False)) +# +from buildbot.status import words +c['status'].append(words.IRC(host="irc.freenode.net", nick="kissbot", + password="celodor", channels=["#kss"])) +# +# from buildbot.status import client +# c['status'].append(client.PBListener(9988)) + + +####### DEBUGGING OPTIONS + +# if you set 'debugPassword', then you can connect to the buildmaster with +# the diagnostic tool in contrib/debugclient.py . From this tool, you can +# manually force builds and inject changes, which may be useful for testing +# your buildmaster without actually commiting changes to your repository (or +# before you have a functioning 'sources' set up). The debug tool uses the +# same port number as the slaves do: 'slavePortnum'. + +#c['debugPassword'] = "debugpassword" + +# if you set 'manhole', you can ssh into the buildmaster and get an +# interactive python shell, which may be useful for debugging buildbot +# internals. It is probably only useful for buildbot developers. You can also +# use an authorized_keys file, or plain telnet. +#from buildbot import manhole +#c['manhole'] = manhole.PasswordManhole("tcp:9999:interface=127.0.0.1", +# "admin", "password") + + +####### PROJECT IDENTITY + +# the 'projectName' string will be used to describe the project that this +# buildbot is working on. For example, it is used as the title of the +# waterfall HTML page. The 'projectURL' string will be used to provide a link +# from buildbot HTML pages to your project's home page. + +c['projectName'] = "Kinetic Stylesheets Buidlbot" +c['projectURL'] = "http://kukit.org" + +# the 'buildbotURL' string should point to the location where the buildbot's +# internal web server (usually the html.Waterfall page) is visible. This +# typically uses the port number set in the Waterfall 'status' entry, but +# with an externally-visible host name which the buildbot cannot figure out +# without some help. + +c['buildbotURL'] = "http://buildbot.bubblenet.be:8010/" From hannosch at codespeak.net Tue Feb 6 20:13:54 2007 From: hannosch at codespeak.net (hannosch at codespeak.net) Date: Tue, 6 Feb 2007 20:13:54 +0100 (CET) Subject: [KSS-checkins] r38026 - kukit/kss.core/trunk Message-ID: <20070206191354.57CF310063@code0.codespeak.net> Author: hannosch Date: Tue Feb 6 20:13:48 2007 New Revision: 38026 Modified: kukit/kss.core/trunk/setup.py Log: Added setuptools dependency, we use namespace packages. Modified: kukit/kss.core/trunk/setup.py ============================================================================== --- kukit/kss.core/trunk/setup.py (original) +++ kukit/kss.core/trunk/setup.py Tue Feb 6 20:13:48 2007 @@ -25,7 +25,7 @@ include_package_data=True, zip_safe=False, install_requires=[ - # -*- Extra requirements: -*- + 'setuptools', ], entry_points=""" # -*- Entry points: -*- From philikon at codespeak.net Thu Feb 8 01:13:02 2007 From: philikon at codespeak.net (philikon at codespeak.net) Date: Thu, 8 Feb 2007 01:13:02 +0100 (CET) Subject: [KSS-checkins] r38131 - in kukit/kss.core/branch/philikon-cleanup/kss/core: . tests Message-ID: <20070208001302.C515710081@code0.codespeak.net> Author: philikon Date: Thu Feb 8 01:12:59 2007 New Revision: 38131 Added: kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_azaxview_functional.py (contents, props changed) Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.py Log: Finishing touch: make the whole "the view is a site" thing work on Zope 2. Zope 2, unfortunately, doesn't yet send BeforeTraverseEvents for all objects (like Zope 3 does). We explicitly do this ourselves for now in a __before_publishing_traverse__, hoping that in a future Zope 2 release (2.11?) this will be fixed. At that point, KSSView.__before_publishing_traverse__ should disappear again. Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.py ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.py (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.py Thu Feb 8 01:12:59 2007 @@ -40,13 +40,14 @@ from kss.core.interfaces import IKSSView, ICommandSet from kss.core.pluginregistry.commandset import getRegisteredCommandSet -from zope import component, interface +from zope import component, interface, event from zope.interface.adapter import VerifyingAdapterRegistry from zope.component import getSiteManager from zope.component.globalregistry import BaseGlobalComponents from zope.component.interfaces import (IComponentLookup, ComponentLookupError, IObjectEvent) from zope.app.component.interfaces import ISite +from zope.app.publication.zopepublication import BeforeTraverseEvent class SiteViewComponents(BaseGlobalComponents): @@ -82,6 +83,15 @@ # 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): Added: kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_azaxview_functional.py ============================================================================== --- (empty file) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_azaxview_functional.py Thu Feb 8 01:12:59 2007 @@ -0,0 +1,79 @@ +# +# 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 + +from kss.core import KSSView + +class TestKSSView(KSSView): + + def __call__(self): + self.messages = [] + if getSite() == self: + self.messages.append("I'm the current site.") + event.notify(ObjectModifiedEvent(self.context)) + return "\n".join(self.messages) + + at 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) + +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. + Event subscriber was here. + """ + +def test_suite(): + return unittest.TestSuite([ + FunctionalDocTestSuite(setUp=setUp, tearDown=tearDown), + ]) From witsch at codespeak.net Thu Feb 8 17:16:25 2007 From: witsch at codespeak.net (witsch at codespeak.net) Date: Thu, 8 Feb 2007 17:16:25 +0100 (CET) Subject: [KSS-checkins] r38178 - in kukit/kss.buildout: . src trunk trunk/src Message-ID: <20070208161625.6E8781009C@code0.codespeak.net> Author: witsch Date: Thu Feb 8 17:15:41 2007 New Revision: 38178 Added: kukit/kss.buildout/trunk/ kukit/kss.buildout/trunk/bootstrap.py - copied unchanged from r38177, kukit/kss.buildout/bootstrap.py kukit/kss.buildout/trunk/buildout.cfg - copied unchanged from r38177, kukit/kss.buildout/buildout.cfg kukit/kss.buildout/trunk/dotests.py - copied unchanged from r38177, kukit/kss.buildout/dotests.py kukit/kss.buildout/trunk/src/ - copied from r38177, kukit/kss.buildout/src/ kukit/kss.buildout/trunk/tests - copied unchanged from r38177, kukit/kss.buildout/tests Removed: kukit/kss.buildout/bootstrap.py kukit/kss.buildout/buildout.cfg kukit/kss.buildout/dotests.py kukit/kss.buildout/src/ kukit/kss.buildout/tests Log: we want a trunk in here... Deleted: /kukit/kss.buildout/bootstrap.py ============================================================================== --- /kukit/kss.buildout/bootstrap.py Thu Feb 8 17:15:41 2007 +++ (empty file) @@ -1,52 +0,0 @@ -############################################################################## -# -# Copyright (c) 2006 Zope Corporation and Contributors. -# All Rights Reserved. -# -# This software is subject to the provisions of the Zope Public License, -# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. -# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -# FOR A PARTICULAR PURPOSE. -# -############################################################################## -"""Bootstrap a buildout-based project - -Simply run this script in a directory containing a buildout.cfg. -The script accepts buildout command-line options, so you can -use the -c option to specify an alternate configuration file. - -$Id$ -""" - -import os, shutil, sys, tempfile, urllib2 - -tmpeggs = tempfile.mkdtemp() - -ez = {} -exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py' - ).read() in ez -ez['use_setuptools'](to_dir=tmpeggs, download_delay=0) - -import pkg_resources - -cmd = 'from setuptools.command.easy_install import main; main()' -if sys.platform == 'win32': - cmd = '"%s"' % cmd # work around spawn lamosity on windows - -ws = pkg_resources.working_set -assert os.spawnle( - os.P_WAIT, sys.executable, sys.executable, - '-c', cmd, '-mqNxd', tmpeggs, 'zc.buildout', - dict(os.environ, - PYTHONPATH= - ws.find(pkg_resources.Requirement.parse('setuptools')).location - ), - ) == 0 - -ws.add_entry(tmpeggs) -ws.require('zc.buildout') -import zc.buildout.buildout -zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap']) -shutil.rmtree(tmpeggs) Deleted: /kukit/kss.buildout/buildout.cfg ============================================================================== --- /kukit/kss.buildout/buildout.cfg Thu Feb 8 17:15:41 2007 +++ (empty file) @@ -1,47 +0,0 @@ -[buildout] - -parts = - javaversion - seleniumrc - zope2 - instance - ksspy - -develop = - src/kss.core - src/kss.demo - src/kss.recipe.checkjavaversion - src/kss.recipe.seleniumrc - -[javaversion] -recipe = kss.recipe.checkjavaversion -javaversion = 1.5 - -[seleniumrc] -recipe = kss.recipe.seleniumrc -url = http://release.openqa.org/selenium-remote-control/0.9.0/selenium-remote-control-0.9.0.zip - -[zope2] -recipe = z2c.recipe.zope2install -url = http://www.zope.org/Products/Zope/2.10.2/Zope-2.10.2.tgz - -[instance] -recipe = z2c.recipe.zope2instance -zope2-location = ${zope2:location} -user = admin:admin -debug-mode = on -eggs = - kss.core - kss.demo -zcml = - kss.core:kss.core-meta.zcml - kss.core:kss.core-configure.zcml - kss.demo:kss.demo-meta.zcml - kss.demo:kss.demo-configure.zcml - -[ksspy] -recipe = zc.recipe.egg -eggs = ${instance:eggs} -interpreter = ksspy -extra-paths = ${zope2:location}/lib/python -scripts = ksspy Deleted: /kukit/kss.buildout/dotests.py ============================================================================== --- /kukit/kss.buildout/dotests.py Thu Feb 8 17:15:41 2007 +++ (empty file) @@ -1,45 +0,0 @@ -import os, signal, sys - -here = os.getcwd() -#start seleniumRC server -javapid = os.spawnl(os.P_NOWAIT, '/usr/bin/java', '/usr/bin/java', '-jar', 'parts/seleniumrc/selenium-server.jar') - -#start zope -zope = os.path.join(here, 'parts', 'instance', 'bin', 'zopectl') -os.spawnl(os.P_WAIT, zope, zope, 'start') - -#wait for zope instance to come up -from time import sleep -testcmd = "wget -O- http://localhost:8080" -while os.spawnvp(os.P_WAIT, 'wget', testcmd.split()): - sleep(1) - -#setup simple content instance -testcmd = "wget -O- http://localhost:8080/demo" -exitcode = os.spawnvp(os.P_WAIT, 'wget', testcmd.split()) -if exitcode <> 0: - print "add" - setupcmd = """wget -O- --http-user=admin --http-password=admin --post-data add_input_name=demo&UPDATE_SUBMIT=Add http://localhost:8080/+/AddSimpleContent.html""" - exitcode = os.spawnvp(os.P_WAIT, 'wget', setupcmd.split()) - -#start tests -python = sys.executable -zope_test = os.path.join(here, 'tests') -test_command_pieces = [zope_test] -test_command_pieces.append('--package-path') -test_command_pieces.append(os.path.join(here, 'src', 'kss.demo', 'kss', 'demo', 'tests')) -test_command_pieces.append('kss.demo.tests --test-file-pattern=^seltest --tests-pattern=selenium_tests') -test_command = ' '.join(test_command_pieces) -print test_command -std = os.popen(test_command) -print std.read() -test_exit = std.close() - -#stop seleniumRC server -os.kill(javapid, signal.SIGKILL) - -#stop zope -os.spawnl(os.P_WAIT, zope, zope, 'stop') - -print test_exit -sys.exit(test_exit) Deleted: /kukit/kss.buildout/tests ============================================================================== --- /kukit/kss.buildout/tests Thu Feb 8 17:15:41 2007 +++ (empty file) @@ -1,17 +0,0 @@ -#! /bin/sh -SELENIUMBROWSER="*firefox /usr/lib/firefox/firefox-bin" -HERE=`pwd` -PYTHON="/usr/local/bin/python2.4" -ZOPE_HOME="$HERE/parts/zope2" -INSTANCE_HOME="$HEREUsers/parts/instance" -CONFIG_FILE="$HERE/parts/instance/etc/zope.conf" -SOFTWARE_HOME="$HERE/parts/zope2/lib/python" -PYTHONPATH="$SOFTWARE_HOME:$HERE/kss.selenium/src/kss.core:$HERE/eggs/setuptools-0.6c5-py2.4.egg:$HERE/src/kss.demo:$PYTHONPATH" -export PYTHONPATH INSTANCE_HOME SOFTWARE_HOME SELENIUMBROWSER - -ZOPETEST="$ZOPE_HOME/test.py" -if exec "$PYTHON" "$ZOPETEST" --config-file "$CONFIG_FILE" "$@"; then - exit 0 - fi - -exit 127 From gotcha at codespeak.net Thu Feb 8 18:00:41 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Thu, 8 Feb 2007 18:00:41 +0100 (CET) Subject: [KSS-checkins] r38180 - in kukit/kss.core/branch/philikon-cleanup/kss/core: . pluginregistry plugins/core plugins/draganddrop plugins/effects tests Message-ID: <20070208170041.EA56B10083@code0.codespeak.net> Author: gotcha Date: Thu Feb 8 18:00:34 2007 New Revision: 38180 Added: kukit/kss.core/branch/philikon-cleanup/kss/core/tests/help_ttwapi.py kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_ttwapi.py kukit/kss.core/branch/philikon-cleanup/kss/core/ttwapi.py Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/__init__.py kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.py kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.txt kukit/kss.core/branch/philikon-cleanup/kss/core/pluginregistry/commandset.py kukit/kss.core/branch/philikon-cleanup/kss/core/pluginregistry/configure.py kukit/kss.core/branch/philikon-cleanup/kss/core/pluginregistry/directives.py kukit/kss.core/branch/philikon-cleanup/kss/core/pluginregistry/meta.zcml kukit/kss.core/branch/philikon-cleanup/kss/core/plugins/core/configure.zcml kukit/kss.core/branch/philikon-cleanup/kss/core/plugins/draganddrop/configure.zcml kukit/kss.core/branch/philikon-cleanup/kss/core/plugins/effects/configure.zcml kukit/kss.core/branch/philikon-cleanup/kss/core/plugins/effects/interfaces.py Log: * added ttwapi module to allow to return kss commands with Python scripts * cleaned up zcml directives Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/__init__.py ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/__init__.py (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/__init__.py Thu Feb 8 18:00:34 2007 @@ -40,13 +40,7 @@ except ImportError: pass else: -# Allow to build commands from restricted code - from AccessControl import allow_class - from commands import AzaxCommands, AzaxCommand, AzaxParam - allow_class(AzaxCommands) - allow_class(AzaxCommand) - allow_class(AzaxParam) - allow_class(AzaxUnicodeError) - # - allow_class(AzaxBaseView) + # Allow API to build commands from restricted code + from AccessControl import allow_module + allow_module('kss.core.ttwapi') Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.py ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.py (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.py Thu Feb 8 18:00:34 2007 @@ -44,8 +44,8 @@ from zope.interface.adapter import VerifyingAdapterRegistry from zope.component import getSiteManager from zope.component.globalregistry import BaseGlobalComponents -from zope.component.interfaces import (IComponentLookup, ComponentLookupError, - IObjectEvent) +from zope.component.interfaces import IComponentLookup, ComponentLookupError +from zope.component.interfaces import IObjectEvent from zope.app.component.interfaces import ISite from zope.app.publication.zopepublication import BeforeTraverseEvent @@ -155,11 +155,6 @@ class CommandSet: interface.implements(ICommandSet) - # XXX This is really bad. Is is needed for restricted access? - # If not, it has to go. If no, it needs an alternate solution. - # also we need test for this. - __allow_access_to_unprotected_subobjects__ = True - def __init__(self, view): self.view = view self.context = self.view.context Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.txt ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.txt (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/azaxview.txt Thu Feb 8 18:00:34 2007 @@ -18,9 +18,6 @@ >>> from zope import component >>> from zope.lifecycleevent import ObjectModifiedEvent >>> from zope.lifecycleevent.interfaces import IObjectModifiedEvent - >>> from zope.event import notify - >>> from zope.app.component.interfaces import ISite - >>> from zope.interface import directlyProvides, directlyProvidedBy >>> from zope.publisher.browser import TestRequest >>> from zope import event Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/pluginregistry/commandset.py ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/pluginregistry/commandset.py (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/pluginregistry/commandset.py Thu Feb 8 18:00:34 2007 @@ -1,9 +1,10 @@ - -from plugin import AzaxPlugin, AzaxPluginError -from interfaces import ICommandSet from zope.interface import implements import zope.component as capi +from plugin import AzaxPluginError +from plugin import registerPlugin +from interfaces import ICommandSet + def getRegisteredCommandSet(name): 'Get the command set' try: @@ -25,3 +26,15 @@ def __init__(self, name, provides): self.name = name self.provides = provides + +def registerAndAllowCommandSet(class_, name, provides, *arg, **kw): + registerPlugin(CommandSet, ICommandSet, name, provides, *arg, **kw) + try: + import Products.Five + except ImportError: + pass + else: + # Allow TTW to use commandsets + from AccessControl import allow_class + allow_class(class_) + Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/pluginregistry/configure.py ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/pluginregistry/configure.py (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/pluginregistry/configure.py Thu Feb 8 18:00:34 2007 @@ -1,12 +1,10 @@ -import os.path -from interfaces import ICommand, IEventType, ISelectorType, IAction, \ - ICommandSet -from command import Command +from zope.component.zcml import adapter +from interfaces import IEventType, ISelectorType, IAction from event_type import EventType from action import Action from selector_type import SelectorType -from commandset import CommandSet +from commandset import registerAndAllowCommandSet from plugin import registerPlugin #class AzaxConfigurationError(Exception): @@ -52,11 +50,12 @@ args = (SelectorType, ISelectorType, name, jsfile), ) -def registerCommandSet(_context, name, provides): +def registerCommandSet(_context, for_, class_, name, provides): 'Directive that registers a command set' + adapter(_context, [class_], provides, [for_]) _context.action( discriminator = ('registerKssCommandSet', name), - callable = registerPlugin, - args = (CommandSet, ICommandSet, name, provides), + callable = registerAndAllowCommandSet, + args = (class_, name, provides), ) Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/pluginregistry/directives.py ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/pluginregistry/directives.py (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/pluginregistry/directives.py Thu Feb 8 18:00:34 2007 @@ -1,7 +1,7 @@ from zope.interface import Interface from zope.schema import TextLine, Choice from zope.configuration.fields import Path, Tokens, PythonIdentifier, \ - GlobalInterface + GlobalInterface, GlobalObject class IRegisterEventTypeDirective(Interface): 'Register a KSS event type' @@ -78,6 +78,18 @@ class IRegisterCommandSetDirective(Interface): 'Register a KSS command set' + for_ = GlobalInterface( + title=u"For", + description=u"The interface of view that can be adapted to this commandset", + required=True, + ) + + class_ = GlobalObject( + title=u"Class", + description=u"The class that implements the commandset", + required=True, + ) + name = TextLine( title=u"Name", description=u"The name of the command set component.", Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/pluginregistry/meta.zcml ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/pluginregistry/meta.zcml (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/pluginregistry/meta.zcml Thu Feb 8 18:00:34 2007 @@ -10,25 +10,25 @@ Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/plugins/core/configure.zcml ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/plugins/core/configure.zcml (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/plugins/core/configure.zcml Thu Feb 8 18:00:34 2007 @@ -5,20 +5,14 @@ xmlns:zcml="http://namespaces.zope.org/zcml" > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/plugins/draganddrop/configure.zcml ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/plugins/draganddrop/configure.zcml (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/plugins/draganddrop/configure.zcml Thu Feb 8 18:00:34 2007 @@ -4,12 +4,6 @@ xmlns:zcml="http://namespaces.zope.org/zcml" > - - - - @@ -41,18 +35,29 @@ - + + + + + + + + - - Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/plugins/effects/configure.zcml ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/plugins/effects/configure.zcml (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/plugins/effects/configure.zcml Thu Feb 8 18:00:34 2007 @@ -4,12 +4,6 @@ xmlns:zcml="http://namespaces.zope.org/zcml" > - - - - @@ -48,7 +42,7 @@ - - + Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/plugins/effects/interfaces.py ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/plugins/effects/interfaces.py (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/plugins/effects/interfaces.py Thu Feb 8 18:00:34 2007 @@ -2,3 +2,5 @@ class IScriptaculousEffectsCommands(Interface): '''effects commands''' + def effect(selector, type): + '''scriptaculous effect''' Added: kukit/kss.core/branch/philikon-cleanup/kss/core/tests/help_ttwapi.py ============================================================================== --- (empty file) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/tests/help_ttwapi.py Thu Feb 8 18:00:34 2007 @@ -0,0 +1,5 @@ +from zope import event +from zope.lifecycleevent import ObjectModifiedEvent + +def objectModified(context): + event.notify(ObjectModifiedEvent(context)) Added: kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_ttwapi.py ============================================================================== --- (empty file) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_ttwapi.py Thu Feb 8 18:00:34 2007 @@ -0,0 +1,98 @@ +import unittest + +from zope import event, component +from zope.lifecycleevent import ObjectModifiedEvent + +from Testing import ZopeTestCase +ZopeTestCase.installProduct('PythonScripts') +ZopeTestCase.installProduct('Five') + +import Products.Five +from Products.Five import zcml + +from kss.core import KSSView +from kss.core.tests.base import KssViewTestCase + +from AccessControl import allow_module +allow_module('kss.core.tests.help_ttwapi') + +class TTWTestCase(KssViewTestCase): + def afterSetUp(self): + KssViewTestCase.afterSetUp(self) + self.app.manage_addProduct['PythonScripts'].manage_addPythonScript('kss_test') + self.setDebugRequest() + + def test_scriptWithCore(self): + pythonScriptCode = ''' +from kss.core.ttwapi import getKSSView +from kss.core.ttwapi import getKSSCommandSet +from kss.core.ttwapi import renderKSSCommands +view = getKSSView(context) +commandSet = getKSSCommandSet(view, 'core') +commandSet.replaceInnerHTML('#test', '

Done

') +return renderKSSCommands(view) +''' + 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 getKSSView +from kss.core.ttwapi import getKSSCommandSet +from kss.core.ttwapi import renderKSSCommands +view = getKSSView(context) +commandSet = getKSSCommandSet(view, 'effects') +commandSet.effect('#test', 'fade') +return renderKSSCommands(view) +''' + 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): + configure_zcml = '''\ + + + ''' + zcml.load_string(configure_zcml) + zcml.load_config('configure.zcml', package=Products.Five.component) + pythonScriptCode = ''' +from kss.core.ttwapi import getKSSView +from kss.core.ttwapi import getKSSCommandSet +from kss.core.ttwapi import renderKSSCommands +from kss.core.tests.help_ttwapi import objectModified +view = getKSSView(context) +commandSet = getKSSCommandSet(view, 'core') +commandSet.replaceInnerHTML('#test', '

Done

') +objectModified(context) +return renderKSSCommands(view) +''' + 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') + + at 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) Added: kukit/kss.core/branch/philikon-cleanup/kss/core/ttwapi.py ============================================================================== --- (empty file) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/ttwapi.py Thu Feb 8 18:00:34 2007 @@ -0,0 +1,14 @@ +from kss.core import KSSView + +def getKSSView(context): + view = KSSView(context, context.REQUEST) + view.__before_publishing_traverse__(context, context.REQUEST) + return view + +def getKSSCommandSet(view, name): + cs = view.getCommandSet(name) + return cs + +def renderKSSCommands(view): + return view.render() + From philikon at codespeak.net Thu Feb 8 18:48:53 2007 From: philikon at codespeak.net (philikon at codespeak.net) Date: Thu, 8 Feb 2007 18:48:53 +0100 (CET) Subject: [KSS-checkins] r38189 - kukit/kss.core/branch/philikon-cleanup/kss/core/tests Message-ID: <20070208174853.936DA1008F@code0.codespeak.net> Author: philikon Date: Thu Feb 8 18:48:51 2007 New Revision: 38189 Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_ttwapi.py Log: Don't installProducts('Five'). It's evil evil evil evil. In fact, I feel the need to burn somebody at the stakes right now... Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_ttwapi.py ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_ttwapi.py (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_ttwapi.py Thu Feb 8 18:48:51 2007 @@ -1,25 +1,25 @@ import unittest -from zope import event, component -from zope.lifecycleevent import ObjectModifiedEvent - from Testing import ZopeTestCase ZopeTestCase.installProduct('PythonScripts') -ZopeTestCase.installProduct('Five') + +from AccessControl import allow_module +allow_module('kss.core.tests.help_ttwapi') import Products.Five from Products.Five import zcml +from zope import event, component +from zope.lifecycleevent import ObjectModifiedEvent + from kss.core import KSSView from kss.core.tests.base import KssViewTestCase -from AccessControl import allow_module -allow_module('kss.core.tests.help_ttwapi') - class TTWTestCase(KssViewTestCase): def afterSetUp(self): KssViewTestCase.afterSetUp(self) - self.app.manage_addProduct['PythonScripts'].manage_addPythonScript('kss_test') + self.app.manage_addProduct['PythonScripts'].manage_addPythonScript( + 'kss_test') self.setDebugRequest() def test_scriptWithCore(self): From philikon at codespeak.net Thu Feb 8 19:50:02 2007 From: philikon at codespeak.net (philikon at codespeak.net) Date: Thu, 8 Feb 2007 19:50:02 +0100 (CET) Subject: [KSS-checkins] r38193 - kukit/kss.core/branch/philikon-cleanup/kss/core/tests Message-ID: <20070208185002.4475510082@code0.codespeak.net> Author: philikon Date: Thu Feb 8 19:50:00 2007 New Revision: 38193 Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/tests/base.py Log: If you do setup, gotta do teardown as well. Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/tests/base.py ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/tests/base.py (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/tests/base.py Thu Feb 8 19:50:00 2007 @@ -50,6 +50,9 @@ placelesssetup.setUp() self.loadCoreConfig() + def beforeTearDown(self): + placelesssetup.tearDown() + def loadCoreConfig(self, kss_core=True): # Allow traversing try: From philikon at codespeak.net Thu Feb 8 19:50:49 2007 From: philikon at codespeak.net (philikon at codespeak.net) Date: Thu, 8 Feb 2007 19:50:49 +0100 (CET) Subject: [KSS-checkins] r38194 - kukit/kss.core/branch/philikon-cleanup/kss/core/tests Message-ID: <20070208185049.92E7C10084@code0.codespeak.net> Author: philikon Date: Thu Feb 8 19:50:48 2007 New Revision: 38194 Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_azaxview_functional.py Log: Fix test setup bug that was shadowed by improper teardown of KssViewTestcase. Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_azaxview_functional.py ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_azaxview_functional.py (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_azaxview_functional.py Thu Feb 8 19:50:48 2007 @@ -22,7 +22,7 @@ from zope import event, component from zope.testing.cleanup import cleanUp from zope.lifecycleevent import ObjectModifiedEvent -from zope.app.component.hooks import getSite +from zope.app.component.hooks import getSite, setHooks from kss.core import KSSView @@ -32,6 +32,8 @@ 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) @@ -55,6 +57,7 @@ ''' zcml.load_config('configure.zcml', Products.Five) zcml.load_string(configure_zcml) + setHooks() def tearDown(test=None): cleanUp() @@ -70,6 +73,7 @@ >>> browser = Browser('http://localhost:8080/testkssview') >>> print browser.contents I'm the current site. + I have the current site manager. Event subscriber was here. """ From philikon at codespeak.net Thu Feb 8 19:51:53 2007 From: philikon at codespeak.net (philikon at codespeak.net) Date: Thu, 8 Feb 2007 19:51:53 +0100 (CET) Subject: [KSS-checkins] r38195 - kukit/kss.core/branch/philikon-cleanup/kss/core/tests Message-ID: <20070208185153.4B97210084@code0.codespeak.net> Author: philikon Date: Thu Feb 8 19:51:45 2007 New Revision: 38195 Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_ttwapi.py Log: Fix TTW API test case by adding more setup code. Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_ttwapi.py ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_ttwapi.py (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_ttwapi.py Thu Feb 8 19:51:45 2007 @@ -6,18 +6,21 @@ from AccessControl import allow_module allow_module('kss.core.tests.help_ttwapi') -import Products.Five +import Products.Five.component from Products.Five import zcml from zope import event, 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): + def afterSetUp(self): KssViewTestCase.afterSetUp(self) + setHooks() self.app.manage_addProduct['PythonScripts'].manage_addPythonScript( 'kss_test') self.setDebugRequest() @@ -79,7 +82,7 @@ return renderKSSCommands(view) ''' self.app.kss_test.ZPythonScript_edit('', pythonScriptCode) - result = self.app.kss_test() + result = self.app.kss_test() self.assertEquals(len(result), 2) command = result[0] self.assertEquals(command['selector'], '#test') @@ -90,7 +93,8 @@ @component.adapter(None, KSSView, ObjectModifiedEvent) def objectModifiedThruKSSView(obj, view, event): - view.getCommandSet('core').replaceInnerHTML("#event", "Event subscriber was here.") + view.getCommandSet('core').replaceInnerHTML( + "#event", "Event subscriber was here.") def test_suite(): suites = [] From gotcha at codespeak.net Fri Feb 9 09:24:09 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Fri, 9 Feb 2007 09:24:09 +0100 (CET) Subject: [KSS-checkins] r38229 - in kukit/kss.core/branch/philikon-cleanup/kss/core: . tests Message-ID: <20070209082409.991DE1007C@code0.codespeak.net> Author: gotcha Date: Fri Feb 9 09:24:06 2007 New Revision: 38229 Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_ttwapi.py kukit/kss.core/branch/philikon-cleanup/kss/core/ttwapi.py Log: clean up ttwapi Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_ttwapi.py ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_ttwapi.py (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_ttwapi.py Fri Feb 9 09:24:06 2007 @@ -20,6 +20,7 @@ def afterSetUp(self): KssViewTestCase.afterSetUp(self) + zcml.load_config('configure.zcml', package=Products.Five.component) setHooks() self.app.manage_addProduct['PythonScripts'].manage_addPythonScript( 'kss_test') @@ -27,13 +28,13 @@ def test_scriptWithCore(self): pythonScriptCode = ''' -from kss.core.ttwapi import getKSSView +from kss.core.ttwapi import startKSSCommands from kss.core.ttwapi import getKSSCommandSet from kss.core.ttwapi import renderKSSCommands -view = getKSSView(context) -commandSet = getKSSCommandSet(view, 'core') -commandSet.replaceInnerHTML('#test', '

Done

') -return renderKSSCommands(view) +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() @@ -44,13 +45,13 @@ def test_scriptWithEffect(self): pythonScriptCode = ''' -from kss.core.ttwapi import getKSSView +from kss.core.ttwapi import startKSSCommands from kss.core.ttwapi import getKSSCommandSet from kss.core.ttwapi import renderKSSCommands -view = getKSSView(context) -commandSet = getKSSCommandSet(view, 'effects') +startKSSCommands(context, context.REQUEST) +commandSet = getKSSCommandSet('effects') commandSet.effect('#test', 'fade') -return renderKSSCommands(view) +return renderKSSCommands() ''' self.app.kss_test.ZPythonScript_edit('', pythonScriptCode) result = self.app.kss_test() @@ -69,17 +70,16 @@ ''' zcml.load_string(configure_zcml) - zcml.load_config('configure.zcml', package=Products.Five.component) pythonScriptCode = ''' -from kss.core.ttwapi import getKSSView +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 -view = getKSSView(context) -commandSet = getKSSCommandSet(view, 'core') -commandSet.replaceInnerHTML('#test', '

Done

') +startKSSCommands(context, context.REQUEST) +core = getKSSCommandSet('core') +core.replaceInnerHTML('#test', '

Done

') objectModified(context) -return renderKSSCommands(view) +return renderKSSCommands() ''' self.app.kss_test.ZPythonScript_edit('', pythonScriptCode) result = self.app.kss_test() Modified: kukit/kss.core/branch/philikon-cleanup/kss/core/ttwapi.py ============================================================================== --- kukit/kss.core/branch/philikon-cleanup/kss/core/ttwapi.py (original) +++ kukit/kss.core/branch/philikon-cleanup/kss/core/ttwapi.py Fri Feb 9 09:24:06 2007 @@ -1,14 +1,28 @@ from kss.core import KSSView +from kss.core.interfaces import IKSSView +from zope.app.component.hooks import getSite -def getKSSView(context): - view = KSSView(context, context.REQUEST) - view.__before_publishing_traverse__(context, context.REQUEST) +def startKSSCommands(context, request): + view = KSSView(context, request) + view.__before_publishing_traverse__(context, request) return view -def getKSSCommandSet(view, name): +def getKSSCommandSet(name): + view = retrieveView() cs = view.getCommandSet(name) return cs -def renderKSSCommands(view): +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 + + From reebalazs at codespeak.net Fri Feb 9 23:15:13 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Fri, 9 Feb 2007 23:15:13 +0100 (CET) Subject: [KSS-checkins] r38323 - kukit/x Message-ID: <20070209221513.B873110095@code0.codespeak.net> Author: reebalazs Date: Fri Feb 9 23:15:04 2007 New Revision: 38323 Added: kukit/x/ Log: Testing From reebalazs at codespeak.net Fri Feb 9 23:15:25 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Fri, 9 Feb 2007 23:15:25 +0100 (CET) Subject: [KSS-checkins] r38324 - kukit/x Message-ID: <20070209221525.EA1FD10098@code0.codespeak.net> Author: reebalazs Date: Fri Feb 9 23:15:22 2007 New Revision: 38324 Removed: kukit/x/ Log: Testing From reebalazs at codespeak.net Sat Feb 10 11:23:00 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Sat, 10 Feb 2007 11:23:00 +0100 (CET) Subject: [KSS-checkins] r38357 - kukit/kss.core/trunk/kss/core/pluginregistry Message-ID: <20070210102300.8CF5C100AF@code0.codespeak.net> Author: reebalazs Date: Sat Feb 10 11:22:57 2007 New Revision: 38357 Added: kukit/kss.core/trunk/kss/core/pluginregistry/pprovider.py - copied unchanged from r38356, kukit/kss.core/branch/gotcha-late-binding/pluginregistry/pprovider.py Modified: kukit/kss.core/trunk/kss/core/pluginregistry/configure.py kukit/kss.core/trunk/kss/core/pluginregistry/directives.py kukit/kss.core/trunk/kss/core/pluginregistry/interfaces.py kukit/kss.core/trunk/kss/core/pluginregistry/meta.zcml Log: Forgotten change, the zcml registry of parameter providers. This did not get merged from the gotcha branch. Modified: kukit/kss.core/trunk/kss/core/pluginregistry/configure.py ============================================================================== --- kukit/kss.core/trunk/kss/core/pluginregistry/configure.py (original) +++ kukit/kss.core/trunk/kss/core/pluginregistry/configure.py Sat Feb 10 11:22:57 2007 @@ -1,12 +1,13 @@ import os.path from interfaces import ICommand, IEventType, ISelectorType, IAction, \ - ICommandSet + ICommandSet, IParamProvider from command import Command from event_type import EventType from action import Action from selector_type import SelectorType from commandset import CommandSet +from pprovider import ParamProvider from plugin import registerPlugin #class AzaxConfigurationError(Exception): @@ -60,3 +61,16 @@ callable = registerPlugin, args = (CommandSet, ICommandSet, name, provides), ) + +def registerParamProvider(_context, name, jsfile=None): + 'Directive that registers a parameter provider' + + # check to see if the file exists + if jsfile is not None: + file(jsfile, 'rb').close() + + _context.action( + discriminator = ('registerKssParamProvider', name), + callable = registerPlugin, + args = (ParamProvider, IParamProvider, name, jsfile), + ) Modified: kukit/kss.core/trunk/kss/core/pluginregistry/directives.py ============================================================================== --- kukit/kss.core/trunk/kss/core/pluginregistry/directives.py (original) +++ kukit/kss.core/trunk/kss/core/pluginregistry/directives.py Sat Feb 10 11:22:57 2007 @@ -89,3 +89,18 @@ description=u"The interface that does the adaptation on the view for this set", required=True, ) + +class IRegisterParamProviderDirective(Interface): + 'Register a KSS parameter provider' + + name = TextLine( + title=u"Name", + description=u"The name of the parameter provider plugin.", + required=True, + ) + + jsfile = Path( + title=u"Javascript file", + description=u"The path of the javascript file that defines the plugin", + required=False, + ) Modified: kukit/kss.core/trunk/kss/core/pluginregistry/interfaces.py ============================================================================== --- kukit/kss.core/trunk/kss/core/pluginregistry/interfaces.py (original) +++ kukit/kss.core/trunk/kss/core/pluginregistry/interfaces.py Sat Feb 10 11:22:57 2007 @@ -20,3 +20,6 @@ class ICommandSet(Interface): '''Command set plugin''' + +class IParamProvider(IAzaxPlugin): + '''Parameter provider plugin''' Modified: kukit/kss.core/trunk/kss/core/pluginregistry/meta.zcml ============================================================================== --- kukit/kss.core/trunk/kss/core/pluginregistry/meta.zcml (original) +++ kukit/kss.core/trunk/kss/core/pluginregistry/meta.zcml Sat Feb 10 11:22:57 2007 @@ -32,6 +32,12 @@ schema=".directives.IRegisterCommandSetDirective" handler=".configure.registerCommandSet" /> + +
From reebalazs at codespeak.net Sat Feb 10 16:20:48 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Sat, 10 Feb 2007 16:20:48 +0100 (CET) Subject: [KSS-checkins] r38394 - in kukit/kss.core/trunk/kss/core: . pluginregistry plugins/core plugins/draganddrop plugins/effects tests Message-ID: <20070210152048.0A32B1009A@code0.codespeak.net> Author: reebalazs Date: Sat Feb 10 16:20:23 2007 New Revision: 38394 Added: kukit/kss.core/trunk/kss/core/tests/help_ttwapi.py - copied unchanged from r38370, kukit/kss.core/branch/philikon-cleanup/kss/core/tests/help_ttwapi.py kukit/kss.core/trunk/kss/core/tests/test_azaxview_core.py - copied unchanged from r38370, kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_azaxview_core.py kukit/kss.core/trunk/kss/core/tests/test_azaxview_functional.py - copied unchanged from r38370, kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_azaxview_functional.py kukit/kss.core/trunk/kss/core/tests/test_ttwapi.py - copied unchanged from r38370, kukit/kss.core/branch/philikon-cleanup/kss/core/tests/test_ttwapi.py kukit/kss.core/trunk/kss/core/ttwapi.py - copied unchanged from r38370, kukit/kss.core/branch/philikon-cleanup/kss/core/ttwapi.py Removed: kukit/kss.core/trunk/kss/core/events.py kukit/kss.core/trunk/kss/core/siteview_life.txt Modified: kukit/kss.core/trunk/kss/core/__init__.py kukit/kss.core/trunk/kss/core/azaxview.py kukit/kss.core/trunk/kss/core/azaxview.txt kukit/kss.core/trunk/kss/core/interfaces.py kukit/kss.core/trunk/kss/core/pluginregistry/commandset.py kukit/kss.core/trunk/kss/core/pluginregistry/configure.py kukit/kss.core/trunk/kss/core/pluginregistry/directives.py kukit/kss.core/trunk/kss/core/pluginregistry/meta.zcml kukit/kss.core/trunk/kss/core/plugins/core/configure.zcml kukit/kss.core/trunk/kss/core/plugins/draganddrop/configure.zcml kukit/kss.core/trunk/kss/core/plugins/effects/configure.zcml kukit/kss.core/trunk/kss/core/plugins/effects/interfaces.py kukit/kss.core/trunk/kss/core/siteview.txt kukit/kss.core/trunk/kss/core/tests/base.py kukit/kss.core/trunk/kss/core/tests/commandinspector.py kukit/kss.core/trunk/kss/core/tests/test_azaxview.py kukit/kss.core/trunk/kss/core/tests/test_siteview.py Log: Merge changes from branch philikon-cleanup -r37903:HEAD Modified: kukit/kss.core/trunk/kss/core/__init__.py ============================================================================== --- kukit/kss.core/trunk/kss/core/__init__.py (original) +++ kukit/kss.core/trunk/kss/core/__init__.py Sat Feb 10 16:20:23 2007 @@ -1,4 +1,3 @@ -# -*- coding: ISO-8859-15 -*- # Copyright (c) 2006 # Authors: # Godefroid Chapelle @@ -25,26 +24,23 @@ import mimetypes -mimetypes.types_map['.kkt'] = 'text/xml' # XXX legacy! +mimetypes.types_map['.kkt'] = 'text/xml' # BBB legacy! mimetypes.types_map['.kukit'] = 'text/xml' -from azaxview import AzaxBaseView, CommandSet -from actionwrapper import KssExplicitError, kssaction -from unicode_quirks import force_unicode, AzaxUnicodeError -from interfaces import ICommandSet +from kss.core.azaxview import KSSView, CommandSet +from kss.core.actionwrapper import KssExplicitError, kssaction +from kss.core.unicode_quirks import force_unicode, AzaxUnicodeError +from kss.core.interfaces import ICommandSet + +# BBB +from kss.core.azaxview import AzaxBaseView try: import Products.Five except ImportError: pass else: -# Allow to build commands from restricted code - from AccessControl import allow_class - from commands import AzaxCommands, AzaxCommand, AzaxParam - allow_class(AzaxCommands) - allow_class(AzaxCommand) - allow_class(AzaxParam) - allow_class(AzaxUnicodeError) - # - allow_class(AzaxBaseView) + # Allow API to build commands from restricted code + from AccessControl import allow_module + allow_module('kss.core.ttwapi') Modified: kukit/kss.core/trunk/kss/core/azaxview.py ============================================================================== --- kukit/kss.core/trunk/kss/core/azaxview.py (original) +++ kukit/kss.core/trunk/kss/core/azaxview.py Sat Feb 10 16:20:23 2007 @@ -34,41 +34,41 @@ try: from Products.Five import BrowserView except ImportError: - from zope.app.publisher.browser import BrowserView + from zope.publisher.browser import BrowserView -from commands import AzaxCommands -from events import AzaxEvent -from interfaces import IAzaxEvent, IAzaxView, ICommandSet -from pluginregistry.commandset import getRegisteredCommandSet -from zope import app, component, interface +from kss.core.commands import AzaxCommands +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 import getSiteManager from zope.component.globalregistry import BaseGlobalComponents -from zope.component.persistentregistry import PersistentAdapterRegistry -from zope.component.interfaces import IComponentLookup -from zope.component.interfaces import ComponentLookupError -from zope.event import notify -from zope.interface import implements, Interface -from zope.publisher.browser import BrowserView -from zope.app.publication.interfaces import IEndRequestEvent +from zope.component.interfaces import IComponentLookup, ComponentLookupError +from zope.component.interfaces import IObjectEvent +from zope.app.component.interfaces import ISite +from zope.app.publication.zopepublication import BeforeTraverseEvent -class ViewSiteManager(BaseGlobalComponents): +class SiteViewComponents(BaseGlobalComponents): def _init_registries(self): - self.adapters = PersistentAdapterRegistry() - self.utilities = PersistentAdapterRegistry() + # 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() 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_sitemanager = component.getSiteManager() - - self._sitemanager = ViewSiteManager('siteview') - - self._sitemanager.__bases__ = (_next_sitemanager, ) + next = component.getSiteManager() + self._sitemanager = SiteViewComponents('siteview') + self._sitemanager.__bases__ = (next, ) # On Five, we should wrap it in the acquisition context # see, if self has aq_parent, it is done obligatoraly @@ -83,65 +83,61 @@ # 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)) - # first get a reference to the old implementation before making - # ourselves the new default site manager - self._getSiteManagerHook = getSiteManager.implementation - getSiteManager.sethook(self.getSiteManager) + # ISite interface - def getSiteManager(self, context=None): + def getSiteManager(self): return self._sitemanager - @component.adapter(Interface) - def _eventRedispatcher(self, event): - if IEndRequestEvent.providedBy(event): - # If this happens, we must finish activity - self.stopEventListening() - return - if not IAzaxEvent.providedBy(event): - azaxevent = AzaxEvent(self, event) - notify(azaxevent) - - def stopEventListening(self): - # reset the site manager to its original one - getSiteManager.sethook(self._getSiteManagerHook) + def setSiteManager(self, sm): + raise TypeError("Site manager of SiteView can't be changed.") - def render(self): - self.stopEventListening() + @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 AzaxBaseView(SiteView): - """ Base kss view +class KSSView(SiteView): + """KSS view - this allows setting up the content of the response, and then + This allows setting up the content of the response, and then generate it out. """ - - implements(IAzaxView) + interface.implements(IKSSView) def __init__(self, context, request): - super(AzaxBaseView, self).__init__(context, request) + super(KSSView, self).__init__(context, request) self._initcommands() def _initcommands(self): self.commands = AzaxCommands() + # 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): - '''All methods must use this to return their command set - ''' - commands = self.commands.render(self.request) - super(AzaxBaseView, self).render() - return commands + """Views can use this to return their command set.""" + return self.commands.render(self.request) def cancelRedirect(self): - if self.request.RESPONSE.getStatus() == 302: + if self.request.RESPONSE.getStatus() in (302, 303): # Try to not redirect if requested self.request.RESPONSE.setStatus(200) @@ -153,13 +149,11 @@ # return the adapted view return commandset.provides(self) -class CommandSet: - implements(ICommandSet) +# BBB deprecated +AzaxBaseView = KSSView - # XXX This is really bad. Is is needed for restricted access? - # If not, it has to go. If no, it needs an alternate solution. - # also we need test for this. - __allow_access_to_unprotected_subobjects__ = True +class CommandSet: + interface.implements(ICommandSet) def __init__(self, view): self.view = view @@ -170,5 +164,5 @@ def getCommandSet(self, name): return self.view.getCommandSet(name) -# XXX to be deprecated +# BBB deprecated AzaxViewAdapter = CommandSet Modified: kukit/kss.core/trunk/kss/core/azaxview.txt ============================================================================== --- kukit/kss.core/trunk/kss/core/azaxview.txt (original) +++ kukit/kss.core/trunk/kss/core/azaxview.txt Sat Feb 10 16:20:23 2007 @@ -1,65 +1,64 @@ -===================== -Azax views and events -===================== - -When we make a change using Ajax calls we would like to update the browser -page. This can be done by sending browser commands. Some part of the page may -need to be update based on modifications. - -We don't want to handle all these modifications in our own code. An example of -such a modification change would be changing the title. This should also update - -the navigation portlet. - -To make this work azax views do something special. We will explain this by -creating an example. The following will setup our enviroment and show that -normal operation works. - - >>> from kss.core.azaxview import AzaxBaseView - >>> from kss.core.interfaces import IAzaxEvent - >>> from kss.core.tests.base import IDebugRequest +==================== +KSS views and events +==================== + +When we make a change using Ajax calls we would like to update the +browser page. This can be done by sending browser commands. Some part +of the page may need to be update based on modifications. + +We don't want to handle all these modifications in our own code. An +example of such a modification change would be changing the +title. This should also update the navigation portlet. + +To make this work azax views do something special. We will explain +this by creating an example. The following will setup our enviroment +and show that normal operation works. + + >>> from kss.core import KSSView >>> from zope import component >>> from zope.lifecycleevent import ObjectModifiedEvent >>> from zope.lifecycleevent.interfaces import IObjectModifiedEvent - >>> from zope.event import notify - >>> from zope.app.component.interfaces import ISite - >>> from zope.interface import directlyProvides, directlyProvidedBy >>> from zope.publisher.browser import TestRequest >>> from zope import event >>> from zope.app.folder import folder >>> myfolder = folder.rootFolder() - -This will make the commands rendered as test-friendly structures. - >>> request = TestRequest() - >>> directlyProvides(request, directlyProvidedBy(request) + IDebugRequest) Now we will write our custom. - >>> class SampleView(AzaxBaseView): - ... def add_page(self, title): - ... # normally you would change the zope database here - ... event.notify(ObjectModifiedEvent(title)) + >>> class SampleView(KSSView): + ... def setTitle(self, title): + ... self.context.title = title + ... event.notify(ObjectModifiedEvent(self.context)) ... return self.render() >>> view = SampleView(myfolder, request) - >>> view.add_page("some title") + +Simulate traversal by making the view the current site: + + >>> from zope.app.component.hooks import setSite + >>> setSite(view) + +Let's set a title: + + >>> view.setTitle("some title") [] -Now that we have shown that this will not generate any Azax commands we will -register a handler. This handler will catch the object event and add some Azax -commands. - - >>> @component.adapter(IAzaxEvent) - ... def stuff_happend(azax_event): - ... orig_event = azax_event.event - ... azax_event.view.getCommandSet('core').replaceInnerHTML( - ... 'div.class', orig_event.object) +Now that we have shown that this will not generate any KSS commands +we will register a handler. This handler will catch the object event +and add some Azax commands. + + >>> @component.adapter(None, SampleView, IObjectModifiedEvent) + ... def stuff_happend(object, view, event): + ... view.getCommandSet('core').replaceInnerHTML( + ... 'div.class', object.title) >>> component.provideHandler(stuff_happend) When we call the renderer now it should have some more data in it. >>> view = SampleView(myfolder, request) - >>> view.add_page("some title")[0]['params']['html'] + >>> setSite(view) + + >>> view.setTitle(u"some title")[0]['params']['html'] u'some title' Deleted: /kukit/kss.core/trunk/kss/core/events.py ============================================================================== --- /kukit/kss.core/trunk/kss/core/events.py Sat Feb 10 16:20:23 2007 +++ (empty file) @@ -1,9 +0,0 @@ -from interfaces import IAzaxEvent -from zope.interface import implements - -class AzaxEvent(object): - implements(IAzaxEvent) - - def __init__(self, view, event): - self.view = view - self.event = event Modified: kukit/kss.core/trunk/kss/core/interfaces.py ============================================================================== --- kukit/kss.core/trunk/kss/core/interfaces.py (original) +++ kukit/kss.core/trunk/kss/core/interfaces.py Sat Feb 10 16:20:23 2007 @@ -19,11 +19,6 @@ # from zope.interface import Interface, Attribute -try: - # 2.10 - from zope.lifecycleevent.interfaces import IObjectModifiedEvent -except ImportError: - from zope.app.event.objectevent import IObjectModifiedEvent class IAzaxCommands(Interface): 'Azax commands' @@ -105,22 +100,24 @@ def getContent(self): '' -class IAzaxView(Interface): - #XXX document all interface - def render(): - '' +class IKSSView(Interface): + + commands = Attribute('An IAzaxCommands 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' - -class IAzaxEvent(Interface): - """Used to notify of events during an Ajax call - - This will normally be accompanied by another event.""" - - view = Attribute(u"The Azax view") - event = Attribute(u"The orginal event") - Modified: kukit/kss.core/trunk/kss/core/pluginregistry/commandset.py ============================================================================== --- kukit/kss.core/trunk/kss/core/pluginregistry/commandset.py (original) +++ kukit/kss.core/trunk/kss/core/pluginregistry/commandset.py Sat Feb 10 16:20:23 2007 @@ -1,9 +1,10 @@ - -from plugin import AzaxPlugin, AzaxPluginError -from interfaces import ICommandSet from zope.interface import implements import zope.component as capi +from plugin import AzaxPluginError +from plugin import registerPlugin +from interfaces import ICommandSet + def getRegisteredCommandSet(name): 'Get the command set' try: @@ -25,3 +26,15 @@ def __init__(self, name, provides): self.name = name self.provides = provides + +def registerAndAllowCommandSet(class_, name, provides, *arg, **kw): + registerPlugin(CommandSet, ICommandSet, name, provides, *arg, **kw) + try: + import Products.Five + except ImportError: + pass + else: + # Allow TTW to use commandsets + from AccessControl import allow_class + allow_class(class_) + Modified: kukit/kss.core/trunk/kss/core/pluginregistry/configure.py ============================================================================== --- kukit/kss.core/trunk/kss/core/pluginregistry/configure.py (original) +++ kukit/kss.core/trunk/kss/core/pluginregistry/configure.py Sat Feb 10 16:20:23 2007 @@ -1,12 +1,10 @@ -import os.path -from interfaces import ICommand, IEventType, ISelectorType, IAction, \ - ICommandSet, IParamProvider -from command import Command +from zope.component.zcml import adapter +from interfaces import IEventType, ISelectorType, IAction, IParamProvider from event_type import EventType from action import Action from selector_type import SelectorType -from commandset import CommandSet +from commandset import registerAndAllowCommandSet from pprovider import ParamProvider from plugin import registerPlugin @@ -53,13 +51,14 @@ args = (SelectorType, ISelectorType, name, jsfile), ) -def registerCommandSet(_context, name, provides): +def registerCommandSet(_context, for_, class_, name, provides): 'Directive that registers a command set' + adapter(_context, [class_], provides, [for_]) _context.action( discriminator = ('registerKssCommandSet', name), - callable = registerPlugin, - args = (CommandSet, ICommandSet, name, provides), + callable = registerAndAllowCommandSet, + args = (class_, name, provides), ) def registerParamProvider(_context, name, jsfile=None): Modified: kukit/kss.core/trunk/kss/core/pluginregistry/directives.py ============================================================================== --- kukit/kss.core/trunk/kss/core/pluginregistry/directives.py (original) +++ kukit/kss.core/trunk/kss/core/pluginregistry/directives.py Sat Feb 10 16:20:23 2007 @@ -1,7 +1,7 @@ from zope.interface import Interface from zope.schema import TextLine, Choice from zope.configuration.fields import Path, Tokens, PythonIdentifier, \ - GlobalInterface + GlobalInterface, GlobalObject class IRegisterEventTypeDirective(Interface): 'Register a KSS event type' @@ -78,6 +78,18 @@ class IRegisterCommandSetDirective(Interface): 'Register a KSS command set' + for_ = GlobalInterface( + title=u"For", + description=u"The interface of view that can be adapted to this commandset", + required=True, + ) + + class_ = GlobalObject( + title=u"Class", + description=u"The class that implements the commandset", + required=True, + ) + name = TextLine( title=u"Name", description=u"The name of the command set component.", Modified: kukit/kss.core/trunk/kss/core/pluginregistry/meta.zcml ============================================================================== --- kukit/kss.core/trunk/kss/core/pluginregistry/meta.zcml (original) +++ kukit/kss.core/trunk/kss/core/pluginregistry/meta.zcml Sat Feb 10 16:20:23 2007 @@ -10,31 +10,31 @@ Modified: kukit/kss.core/trunk/kss/core/plugins/core/configure.zcml ============================================================================== --- kukit/kss.core/trunk/kss/core/plugins/core/configure.zcml (original) +++ kukit/kss.core/trunk/kss/core/plugins/core/configure.zcml Sat Feb 10 16:20:23 2007 @@ -5,20 +5,14 @@ xmlns:zcml="http://namespaces.zope.org/zcml" > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + Modified: kukit/kss.core/trunk/kss/core/plugins/draganddrop/configure.zcml ============================================================================== --- kukit/kss.core/trunk/kss/core/plugins/draganddrop/configure.zcml (original) +++ kukit/kss.core/trunk/kss/core/plugins/draganddrop/configure.zcml Sat Feb 10 16:20:23 2007 @@ -4,12 +4,6 @@ xmlns:zcml="http://namespaces.zope.org/zcml" > - - - - @@ -41,18 +35,29 @@ - + + + + + + + + - - Modified: kukit/kss.core/trunk/kss/core/plugins/effects/configure.zcml ============================================================================== --- kukit/kss.core/trunk/kss/core/plugins/effects/configure.zcml (original) +++ kukit/kss.core/trunk/kss/core/plugins/effects/configure.zcml Sat Feb 10 16:20:23 2007 @@ -4,12 +4,6 @@ xmlns:zcml="http://namespaces.zope.org/zcml" > - - - - @@ -48,7 +42,7 @@ - - + Modified: kukit/kss.core/trunk/kss/core/plugins/effects/interfaces.py ============================================================================== --- kukit/kss.core/trunk/kss/core/plugins/effects/interfaces.py (original) +++ kukit/kss.core/trunk/kss/core/plugins/effects/interfaces.py Sat Feb 10 16:20:23 2007 @@ -2,3 +2,5 @@ class IScriptaculousEffectsCommands(Interface): '''effects commands''' + def effect(selector, type): + '''scriptaculous effect''' Modified: kukit/kss.core/trunk/kss/core/siteview.txt ============================================================================== --- kukit/kss.core/trunk/kss/core/siteview.txt (original) +++ kukit/kss.core/trunk/kss/core/siteview.txt Sat Feb 10 16:20:23 2007 @@ -2,90 +2,116 @@ Site view ========= -All Azax views are not only a browser view but provide a site manager as well. -The site manager is hooked into the component framework on creation time. This -allows the Azax views to intercept all incomming events. - -By doing so the view is able to hookup it's own event redispatcher. This is a -normal event handler which generates the specific Azax events. These events -contain a reference to the view itself. By doing so event handlers can modify -the response body. - -This behaviour is needed for making event driven changes to a page. For -instance when you change a title in a document you also want the menu reloaded. -By using events for this we can achieve a degree of decoupling. - -The main class which implements views with a site manager is `SiteView`. +All KSS views are not only a browser view but provide a site manager +as well. The site manager is hooked into the component framework on +traversal time. This allows the KSS views to dispatch incomming +object events to (object, view, event) so that KSS-view-specific event +handlers can add to the view's commands. + +This behaviour is needed for making event driven changes to a page. +For instance when you change a title in a document you also want the +menu reloaded. By using events for this we can achieve a degree of +decoupling. +The main class which implements views with a site manager is ``SiteView``: + >>> from kss.core.azaxview import SiteView -When created this view will make it's manager the default site manager. - -Context must be >>> from zope import component >>> old_sitemanager = component.getSiteManager() - >>> view = SiteView(None, None) - >>> old_sitemanager is component.getSiteManager() - False - >>> view.getSiteManager() is component.getSiteManager() - True -It also immediatly registers its special event handler. Like mentioned earlier -this will dispatch IAzaxEvent's. + >>> from zope.publisher.browser import TestRequest + >>> class TestObject: + ... pass + >>> obj = TestObject() + >>> request = TestRequest() + >>> view = SiteView(obj, request) + +Let's register a handler for an object modified event event and +SiteView views: - >>> from zope.component.eventtesting import getEvents, clearEvents - >>> from kss.core.interfaces import IAzaxEvent >>> from zope.lifecycleevent import ObjectModifiedEvent - >>> from zope.event import notify + >>> event = ObjectModifiedEvent(obj) - >>> clearEvents() - >>> notify(ObjectModifiedEvent(None)) + >>> @component.adapter(TestObject, SiteView, ObjectModifiedEvent) + ... def catchTestObjectEvent(event_obj, event_view, event_event): + ... print "Special event handler was invoked, dispatch is working." + ... print "Object is the original one:", event_obj is obj + ... print "View is the original one:", event_view is view + ... print "Event is the original one:", event_event is event + ... + >>> component.provideHandler(catchTestObjectEvent) -Two events are fired by this. - - >>> len(getEvents()) - 2 - -The original event and the special IAzaxEvent. - - >>> from zope.lifecycleevent.interfaces import IObjectModifiedEvent - >>> original_event = getEvents()[0] - >>> IObjectModifiedEvent.providedBy(original_event) - True +Without the SiteView view being activated as a site, it won't dispatch +to the handler: - >>> azax_event = getEvents()[1] - >>> IAzaxEvent.providedBy(azax_event) - True + >>> from zope.event import notify + >>> notify(ObjectModifiedEvent(obj)) -The Azax event has reference to the view and the original event. - - >>> azax_event.event is original_event - True - >>> azax_event.view is view - True +Now we make the view the current site. We'll see that its site +manager has become the current component registry: -When the view is rendered it unregisters itself as a site. + >>> from zope.app.component.hooks import setSite + >>> setSite(view) - >>> view.render() - >>> view.getSiteManager() is component.getSiteManager() + >>> old_sitemanager is component.getSiteManager() False - -The view also has a specific way of unregistering itself for events. You can -use this from your tests or other specific use cases. First we will create a -new view to start listening. - - >>> view = SiteView(None, None) - -Now we will stop the view from listening to the events. - - >>> view.stopEventListening() - -If we raise an event we should only get the one event and not the AzaxEvent as well. - - >>> clearEvents() - >>> notify(ObjectModifiedEvent(None)) - >>> len(getEvents()) - 1 - >>> original_event = getEvents()[0] - >>> IObjectModifiedEvent.providedBy(original_event) + >>> view.getSiteManager() is component.getSiteManager() True + +The view also immediately registers its special event handler. Like +mentioned earlier this will dispatch to (obj, view, event) handlers, +including the one we defined above. So let's send that object +modified event again. We expect our site view event handler will be +invoked with the original object, view and event: + + >>> notify(ObjectModifiedEvent(obj)) + Special event handler was invoked, dispatch is working. + Object is the original one: True + View is the original one: True + Event is the original one: False + +Below a site +------------ + +Let's say SiteView is operating below a persistent site, e.g. the root +folder or a CMF site: + + >>> from zope.app.folder import Folder + >>> from zope.app.component.interfaces import ISite + >>> from zope.interface import alsoProvides + >>> from zope.component.globalregistry import base + >>> from zope.component.persistentregistry import PersistentComponents + + >>> site = Folder() + >>> components = PersistentComponents() + >>> components.__bases__ = (base,) + >>> site.setSiteManager(components) + >>> alsoProvides(site, ISite) + + >>> setSite(site) + +Let's also register a site view event subscriber *globally* and one +*locally* + + >>> @component.adapter(ISite, SiteView, ObjectModifiedEvent) + ... def catchSiteEventGlobally(event_obj, event_view, event_event): + ... print "Global event handler was invoked, dispatch is working." + ... + >>> component.provideHandler(catchSiteEventGlobally) + + >>> @component.adapter(ISite, SiteView, ObjectModifiedEvent) + ... def catchSiteEventLocally(event_obj, event_view, event_event): + ... print "Local event handler was invoked, dispatch is working." + ... + >>> components.registerHandler(catchSiteEventLocally) + +Let's now verify the SiteView still works and dispatches component +lookup accordingly. + + >>> view = SiteView(site, request) + >>> setSite(view) + + >>> notify(ObjectModifiedEvent(site)) + Global event handler was invoked, dispatch is working. + Local event handler was invoked, dispatch is working. Deleted: /kukit/kss.core/trunk/kss/core/siteview_life.txt ============================================================================== --- /kukit/kss.core/trunk/kss/core/siteview_life.txt Sat Feb 10 16:20:23 2007 +++ (empty file) @@ -1,104 +0,0 @@ -===================== -Site view, life cycle -===================== - -... or, making the view a site manager is a good idea after -all, but let's see what dangers are lurking in the dark. - -Checking if the view finishes its lifetime ------------------------------------------- - -It is important that the view does not stay on after the -request. This would cause them to continue listening to -events. We need a few imports first. - - >>> from kss.core.azaxview import SiteView - - >>> from zope.interface import Interface, implements - >>> from zope.component import adapter - >>> from zope.lifecycleevent import ObjectModifiedEvent - >>> from zope.event import notify - >>> from zope.app.publication.interfaces import IEndRequestEvent - >>> try: - ... from Products.Five.testbrowser import Browser - ... except ImportError: - ... from zope.testbrowser.browser import Browser - -First, let's create a funky view that has two methods, one -failing and one succeeding, and a habit to choke on any -events. - - >>> class FunkyView(SiteView): - ... def IAmGood(self): - ... 'XXX' - ... return self.render() - ... def IAmBad(self): - ... 'XXX' - ... raise Exception, 'Generic badness' - ... @adapter(Interface) - ... def _eventRedispatcher(self, event): - ... SiteView._eventRedispatcher(self, event) - ... if not IEndRequestEvent.providedBy(event): - ... raise Exception, 'Too late event %r' % event - - >>> import kss.core.tests - >>> kss.core.tests.FunkyView = FunkyView - -We provide this view as a browser page. We care to register -it properly, otherwise we would miss some Five acquisition -woodoo. (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 - - >>> load_string(''' - ... - ... - ... - ... - ... ''') - -Create a test browser now, so we can finally start. - - >>> browser = Browser() - -Let's call up the good request. - - >>> browser.open(self.folder.absolute_url() + '/@@funky_view/IAmGood') - -Now, if we happen to send an event... nothing happens, since -the render() method has taken care of unregistering the -event as a SiteView. - - >>> notify(ObjectModifiedEvent(None)) - -But it is also important, that even in case the render -method does not run (it gives an error since we raised an -exception, this is all right). We would already get an error -during this, thanks to the RequestEvent that arrives. - - >>> browser = browser.open('http://nohost/@@funky_view/IAmBad') - Traceback (most recent call last): - ... - HTTPError: HTTP Error 500: Internal Server Error - -And even if we send a new event, it must not get to the -redispatcher of the view. - - >>> notify(ObjectModifiedEvent(None)) - Modified: kukit/kss.core/trunk/kss/core/tests/base.py ============================================================================== --- kukit/kss.core/trunk/kss/core/tests/base.py (original) +++ kukit/kss.core/trunk/kss/core/tests/base.py Sat Feb 10 16:20:23 2007 @@ -1,4 +1,4 @@ -# -*- coding: ISO-8859-15 -*- +# -*- coding: latin-1 -*- # Copyright (c) 2005-2006 # Authors: # Godefroid Chapelle @@ -19,27 +19,22 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # +from textwrap import dedent + from Testing.ZopeTestCase import ZopeTestCase, FunctionalTestCase -import kss.core -from kss.core import AzaxBaseView from OFS.SimpleItem import SimpleItem -from textwrap import dedent + +from zope import interface from zope.publisher.browser import TestRequest from zope.publisher.interfaces.browser import IBrowserRequest -from zope.interface import Interface, implements -from zope import interface as iapi +from zope.app.testing import placelesssetup + +import kss.core +from kss.core import KSSView -try: - # Zope > 2.8 - from zope.app.testing import placelesssetup -except ImportError: - # Zope == 2.8 - from zope.app.tests import placelesssetup # Test view -# - -class TestView(AzaxBaseView): +class TestView(KSSView): def testMethod(self): 'Yes.' @@ -55,6 +50,9 @@ placelesssetup.setUp() self.loadCoreConfig() + def beforeTearDown(self): + placelesssetup.tearDown() + def loadCoreConfig(self, kss_core=True): # Allow traversing try: @@ -108,7 +106,7 @@ def setDebugRequest(self): 'commands will be rendered as test friendly data structures' request = self.folder.REQUEST - iapi.directlyProvides(request, iapi.directlyProvidedBy(request) + IDebugRequest) + interface.directlyProvides(request, interface.directlyProvidedBy(request) + IDebugRequest) def beforeTearDown(self): placelesssetup.tearDown() Modified: kukit/kss.core/trunk/kss/core/tests/commandinspector.py ============================================================================== --- kukit/kss.core/trunk/kss/core/tests/commandinspector.py (original) +++ kukit/kss.core/trunk/kss/core/tests/commandinspector.py Sat Feb 10 16:20:23 2007 @@ -17,8 +17,7 @@ # 02111-1307, USA. # -from zope.interface import Interface, implements -from zope.app import zapi +from zope.interface import implements from kss.core.interfaces import IAzaxCommandView class CommandInspectorView(object): Modified: kukit/kss.core/trunk/kss/core/tests/test_azaxview.py ============================================================================== --- kukit/kss.core/trunk/kss/core/tests/test_azaxview.py (original) +++ kukit/kss.core/trunk/kss/core/tests/test_azaxview.py Sat Feb 10 16:20:23 2007 @@ -1,4 +1,4 @@ -# -*- coding: ISO-8859-15 -*- +# -*- coding: latin-1 -*- # Copyright (c) 2005-2006 # Authors: # Godefroid Chapelle @@ -19,188 +19,41 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # -import unittest, os -from textwrap import dedent -from zope.testing import doctest -from Testing.ZopeTestCase import FunctionalDocFileSuite -from base import AzaxViewTestCase -from kss.core import AzaxUnicodeError +import unittest + +from kss.core.interfaces import IKSSView, IAzaxCommands from kss.core.plugins.core.interfaces import IKSSCoreCommands -from zope.testing.cleanup import CleanUp as PlacelessSetup -#from kss.core.events import AzaxEvent -from kss.core.interfaces import IAzaxView +from kss.core.plugins.core.commands import KSSCoreCommands from kss.core.pluginregistry.interfaces import IAction, ICommandSet -from kss.core.interfaces import IAzaxCommands #, IAzaxEvent from kss.core.pluginregistry.action import Action from kss.core.pluginregistry.plugin import registerPlugin from kss.core.pluginregistry.commandset import CommandSet -from kss.core.plugins.core.commands import KSSCoreCommands -from kss.core.tests.base import IDebugRequest, KssViewTestCase from kss.core.tests.commandinspector import CommandInspectorView -from zope import component -from Products.Five import zcml -import Products.Five -import zope.component.event -#from zope.app.component.hooks import setSite, getSite, setHooks - -def setUpDoctTest(test=None): - PlacelessSetup().setUp() - - zcml.load_config("meta.zcml", Products.Five) - zcml.load_config("permissions.zcml", Products.Five) - zcml.load_config("configure.zcml", Products.Five.component) - - zcml.load_config("configure.zcml", Products.Five.site) - - commandview = component.adapter( - IAzaxCommands, IDebugRequest)(CommandInspectorView) - component.provideAdapter(commandview) - - registerPlugin(Action, IAction, 'replaceInnerHTML', None, 'selector', - 'html', [], None) - commands = component.adapter(IAzaxView)(KSSCoreCommands) - component.provideAdapter(commands, provides=IKSSCoreCommands) +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=(IAzaxCommands, IBrowserRequest)) + registerPlugin(Action, IAction, 'replaceInnerHTML', None, + 'selector', 'html', [], None) + zope.component.provideAdapter(KSSCoreCommands, + adapts=(IKSSView,), + provides=IKSSCoreCommands) registerPlugin(CommandSet, ICommandSet, 'core', IKSSCoreCommands) -def tearDownDoctTest(test=None): - PlacelessSetup().tearDown() - - -class TestAzaxView(AzaxViewTestCase): - - 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), 1) - self.assertEqual(params[0].getName(), 'html') - 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(AzaxUnicodeError, self._checkSetHtmlResult, 'abc?') - -class FTestAzaxView(AzaxViewTestCase): - 'Functional tests' - - def _wrapped_commands(self, inline): - header = dedent(u'''\ - - - - ''') - footer = 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 - -''' - 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 - -''' - self.assertCommandsEqual(result, awaited) - -def afterSetUp(self): - KssViewTestCase.afterSetUp(self) - self.setDebugRequest() +def tearDownAjaxView(test=None): + cleanup.cleanUp() def test_suite(): - suites = [] - suites.append(unittest.makeSuite(TestAzaxView)) - suites.append(unittest.makeSuite(FTestAzaxView)) - suites.append(doctest.DocTestSuite('kss.core.azaxview')) - suites.append(doctest.DocFileSuite('../azaxview.txt', - setUp=setUpDoctTest, - tearDown=tearDownDoctTest)) - suites.append(FunctionalDocFileSuite('../actionwrapper.py', - test_class=KssViewTestCase, - setUp=afterSetUp, - tearDown=KssViewTestCase.beforeTearDown.im_func)) - return unittest.TestSuite(suites) + return unittest.TestSuite([ + doctest.DocTestSuite('kss.core.azaxview'), + doctest.DocFileSuite('azaxview.txt', + package='kss.core', + setUp=setUpAjaxView, + tearDown=tearDownAjaxView), + ]) Modified: kukit/kss.core/trunk/kss/core/tests/test_siteview.py ============================================================================== --- kukit/kss.core/trunk/kss/core/tests/test_siteview.py (original) +++ kukit/kss.core/trunk/kss/core/tests/test_siteview.py Sat Feb 10 16:20:23 2007 @@ -1,48 +1,19 @@ -from Products.Five import zcml -from zope import component -from zope.component import eventtesting -from zope.testing import doctest -from zope.testing.cleanup import CleanUp as PlacelessSetup -import Products.Five import unittest -from Testing.ZopeTestCase import FunctionalDocFileSuite -from base import KssViewFunctionalTestCase - -def setUpDocTest(test=None): - PlacelessSetup().setUp() - eventtesting.setUp() - - zcml.load_config("meta.zcml", Products.Five) - zcml.load_config("permissions.zcml", Products.Five) - zcml.load_config("configure.zcml", Products.Five.component) - - zcml.load_config("configure.zcml", Products.Five.site) - -def tearDownDocTest(test=None): - PlacelessSetup().tearDown() - -def setUpFDocTest(test=None): - #PlacelessSetup().setUp() - KssViewFunctionalTestCase.setUp(test) - eventtesting.setUp() +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 setSite, setHooks -# zcml.load_config("meta.zcml", Products.Five) -# zcml.load_config("permissions.zcml", Products.Five) -# zcml.load_config("configure.zcml", Products.Five.component) -# -# zcml.load_config("configure.zcml", Products.Five.site) -# zcml.load_config("configure.zcml", Products.Five.site) +def setUp(test=None): + setHooks() -def tearDownFDocTest(test=None): - #PlacelessSetup().tearDown() - KssViewFunctionalTestCase.tearDown(test) +def tearDown(test=None): + cleanUp() def test_suite(): - suite = FunctionalDocFileSuite('../siteview.txt', - setUp=setUpDocTest, - tearDown=tearDownDocTest) - suite = FunctionalDocFileSuite('../siteview_life.txt', - test_class=KssViewFunctionalTestCase, - setUp=setUpFDocTest, - tearDown=tearDownFDocTest) - return unittest.TestSuite(suite) + return unittest.TestSuite([ + doctest.DocFileSuite('siteview.txt', + package='kss.core', + setUp=setUp, + tearDown=tearDown) + ]) From reebalazs at codespeak.net Sat Feb 10 16:22:28 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Sat, 10 Feb 2007 16:22:28 +0100 (CET) Subject: [KSS-checkins] r38395 - kukit/kss.demo/trunk/kss/demo Message-ID: <20070210152228.C08B41009A@code0.codespeak.net> Author: reebalazs Date: Sat Feb 10 16:22:27 2007 New Revision: 38395 Modified: kukit/kss.demo/trunk/kss/demo/configure.zcml Log: Make it compliant to the changed kss directives, after the merge from philikon-cleanup branch Modified: kukit/kss.demo/trunk/kss/demo/configure.zcml ============================================================================== --- kukit/kss.demo/trunk/kss/demo/configure.zcml (original) +++ kukit/kss.demo/trunk/kss/demo/configure.zcml Sat Feb 10 16:22:27 2007 @@ -343,7 +343,7 @@ permission="zope.View" /> - From reebalazs at codespeak.net Sat Feb 10 18:25:42 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Sat, 10 Feb 2007 18:25:42 +0100 (CET) Subject: [KSS-checkins] r38401 - kukit/kukit.js/trunk/kukit Message-ID: <20070210172542.03DCF100A5@code0.codespeak.net> Author: reebalazs Date: Sat Feb 10 18:25:42 2007 New Revision: 38401 Modified: kukit/kukit.js/trunk/kukit/providerreg.js Log: Fix typo that affected the param provider 'pass' Modified: kukit/kukit.js/trunk/kukit/providerreg.js ============================================================================== --- kukit/kukit.js/trunk/kukit/providerreg.js (original) +++ kukit/kukit.js/trunk/kukit/providerreg.js Sat Feb 10 18:25:42 2007 @@ -253,5 +253,5 @@ return value; } }; -kukit.pprovidersGlobalRegistry.register('PassPP', kukit.pr.PassPP); +kukit.pprovidersGlobalRegistry.register('pass', kukit.pr.PassPP); From reebalazs at codespeak.net Sat Feb 10 18:29:01 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Sat, 10 Feb 2007 18:29:01 +0100 (CET) Subject: [KSS-checkins] r38402 - kukit/kss.core/trunk/kss/core/plugins/core Message-ID: <20070210172901.0A871100A5@code0.codespeak.net> Author: reebalazs Date: Sat Feb 10 18:29:00 2007 New Revision: 38402 Modified: kukit/kss.core/trunk/kss/core/plugins/core/configure.zcml Log: Actually add the zcml directived for the param providers Modified: kukit/kss.core/trunk/kss/core/plugins/core/configure.zcml ============================================================================== --- kukit/kss.core/trunk/kss/core/plugins/core/configure.zcml (original) +++ kukit/kss.core/trunk/kss/core/plugins/core/configure.zcml Sat Feb 10 18:29:00 2007 @@ -332,6 +332,48 @@ name="samenode" /> + + + + + + + + + + + + + + + + + + + + + + Author: reebalazs Date: Sat Feb 10 20:49:47 2007 New Revision: 38405 Added: kukit/kss.core/trunk/docs/TODO.txt - copied unchanged from r38370, kukit/kss.core/trunk/kss/core/TODO.txt kukit/kss.core/trunk/kss.core.egg-info/ kukit/kss.core/trunk/kss.core.egg-info/PKG-INFO kukit/kss.core/trunk/kss.core.egg-info/SOURCES.txt kukit/kss.core/trunk/kss.core.egg-info/dependency_links.txt kukit/kss.core/trunk/kss.core.egg-info/entry_points.txt kukit/kss.core/trunk/kss.core.egg-info/namespace_packages.txt kukit/kss.core/trunk/kss.core.egg-info/not-zip-safe kukit/kss.core/trunk/kss.core.egg-info/paster_plugins.txt kukit/kss.core/trunk/kss.core.egg-info/top_level.txt Removed: kukit/kss.core/trunk/kss/core/DEPENDENCIES.txt kukit/kss.core/trunk/kss/core/HISTORY.txt kukit/kss.core/trunk/kss/core/LICENSE kukit/kss.core/trunk/kss/core/TODO.txt Modified: kukit/kss.core/trunk/README.txt kukit/kss.core/trunk/docs/HISTORY.txt kukit/kss.core/trunk/docs/LICENSE.txt kukit/kss.core/trunk/setup.py Log: Relocate docs to their correct egg nest, put back the egg-info Modified: kukit/kss.core/trunk/README.txt ============================================================================== --- kukit/kss.core/trunk/README.txt (original) +++ kukit/kss.core/trunk/README.txt Sat Feb 10 20:49:47 2007 @@ -1,5 +1,5 @@ -ZopeSkel#plone Package Readme -========================= +kss.code Package Readme +======================= Overview -------- Modified: kukit/kss.core/trunk/docs/HISTORY.txt ============================================================================== --- kukit/kss.core/trunk/docs/HISTORY.txt (original) +++ kukit/kss.core/trunk/docs/HISTORY.txt Sat Feb 10 20:49:47 2007 @@ -2,7 +2,15 @@ (name of developer listed in brackets) -kss.core - 0.1 Unreleased +kss.core - 1.2 Unreleased + + - ... + +kss.core - 1.2-alpha2 + + - Merge in Philikon's refactorization + Move docs to doc/ + [ree] - Initial package structure. [zopeskel] Modified: kukit/kss.core/trunk/docs/LICENSE.txt ============================================================================== --- kukit/kss.core/trunk/docs/LICENSE.txt (original) +++ kukit/kss.core/trunk/docs/LICENSE.txt Sat Feb 10 20:49:47 2007 @@ -13,3 +13,11 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + + + + Third party modules come with different licenses, see individual files + + BeautifulSoup.py is licensed with PSF, Copyright (c) 2004-2006 Leonard Richardson + Added: kukit/kss.core/trunk/kss.core.egg-info/PKG-INFO ============================================================================== --- (empty file) +++ kukit/kss.core/trunk/kss.core.egg-info/PKG-INFO Sat Feb 10 20:49:47 2007 @@ -0,0 +1,14 @@ +Metadata-Version: 1.0 +Name: kss.core +Version: 1.2dev +Summary: KSS (Kinetic Style Sheets) core framework +Home-page: http://kukit.org +Author: KSS Project +Author-email: kss-devel at codespeak.net +License: GPLv2 +Description: UNKNOWN +Platform: UNKNOWN +Classifier: Framework :: Zope2 +Classifier: Framework :: Zope3 +Classifier: Programming Language :: Python +Classifier: Topic :: Software Development :: Libraries :: Python Modules Added: kukit/kss.core/trunk/kss.core.egg-info/SOURCES.txt ============================================================================== --- (empty file) +++ kukit/kss.core/trunk/kss.core.egg-info/SOURCES.txt Sat Feb 10 20:49:47 2007 @@ -0,0 +1,12 @@ +README.txt +setup.cfg +setup.py +kss.core.egg-info/PKG-INFO +kss.core.egg-info/SOURCES.txt +kss.core.egg-info/dependency_links.txt +kss.core.egg-info/entry_points.txt +kss.core.egg-info/namespace_packages.txt +kss.core.egg-info/not-zip-safe +kss.core.egg-info/top_level.txt +kss/__init__.py +kss/core/__init__.py Added: kukit/kss.core/trunk/kss.core.egg-info/dependency_links.txt ============================================================================== --- (empty file) +++ kukit/kss.core/trunk/kss.core.egg-info/dependency_links.txt Sat Feb 10 20:49:47 2007 @@ -0,0 +1 @@ + Added: kukit/kss.core/trunk/kss.core.egg-info/entry_points.txt ============================================================================== --- (empty file) +++ kukit/kss.core/trunk/kss.core.egg-info/entry_points.txt Sat Feb 10 20:49:47 2007 @@ -0,0 +1,3 @@ + + # -*- Entry points: -*- + \ No newline at end of file Added: kukit/kss.core/trunk/kss.core.egg-info/namespace_packages.txt ============================================================================== --- (empty file) +++ kukit/kss.core/trunk/kss.core.egg-info/namespace_packages.txt Sat Feb 10 20:49:47 2007 @@ -0,0 +1 @@ +kss Added: kukit/kss.core/trunk/kss.core.egg-info/not-zip-safe ============================================================================== --- (empty file) +++ kukit/kss.core/trunk/kss.core.egg-info/not-zip-safe Sat Feb 10 20:49:47 2007 @@ -0,0 +1 @@ + Added: kukit/kss.core/trunk/kss.core.egg-info/paster_plugins.txt ============================================================================== --- (empty file) +++ kukit/kss.core/trunk/kss.core.egg-info/paster_plugins.txt Sat Feb 10 20:49:47 2007 @@ -0,0 +1 @@ +PasteScript Added: kukit/kss.core/trunk/kss.core.egg-info/top_level.txt ============================================================================== --- (empty file) +++ kukit/kss.core/trunk/kss.core.egg-info/top_level.txt Sat Feb 10 20:49:47 2007 @@ -0,0 +1 @@ +kss Deleted: /kukit/kss.core/trunk/kss/core/DEPENDENCIES.txt ============================================================================== --- /kukit/kss.core/trunk/kss/core/DEPENDENCIES.txt Sat Feb 10 20:49:47 2007 +++ (empty file) @@ -1,6 +0,0 @@ -$Id$ - -- Zope-2.7.3 or greater -- Zope X3.0.0 or greater -- Five 0.3 or greater - Deleted: /kukit/kss.core/trunk/kss/core/HISTORY.txt ============================================================================== --- /kukit/kss.core/trunk/kss/core/HISTORY.txt Sat Feb 10 20:49:47 2007 +++ (empty file) @@ -1,8 +0,0 @@ -Before 0.5.0 -============ - - * Simulate zope.deprecation.deprecated for Zope 2.8 - [gotcha] - - * Remove accented characters in code - [gotcha] Deleted: /kukit/kss.core/trunk/kss/core/LICENSE ============================================================================== --- /kukit/kss.core/trunk/kss/core/LICENSE Sat Feb 10 20:49:47 2007 +++ (empty file) @@ -1,7 +0,0 @@ - -Main part of the code is licensed under GPL Version 2.1 - -Third party modules come with different licenses, see individual files - -BeautifulSoup.py is licensed with PSF, Copyright (c) 2004-2006 Leonard Richardson - Deleted: /kukit/kss.core/trunk/kss/core/TODO.txt ============================================================================== --- /kukit/kss.core/trunk/kss/core/TODO.txt Sat Feb 10 20:49:47 2007 +++ (empty file) @@ -1,2 +0,0 @@ - - Modified: kukit/kss.core/trunk/setup.py ============================================================================== --- kukit/kss.core/trunk/setup.py (original) +++ kukit/kss.core/trunk/setup.py Sat Feb 10 20:49:47 2007 @@ -1,7 +1,7 @@ from setuptools import setup, find_packages import sys, os -version = '0.1' +version = '1.2' setup(name='kss.core', version=version, From reebalazs at codespeak.net Sat Feb 10 21:06:26 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Sat, 10 Feb 2007 21:06:26 +0100 (CET) Subject: [KSS-checkins] r38406 - kukit/kss.core/trunk/kss.core.egg-info Message-ID: <20070210200626.61E2910094@code0.codespeak.net> Author: reebalazs Date: Sat Feb 10 21:06:24 2007 New Revision: 38406 Removed: kukit/kss.core/trunk/kss.core.egg-info/ Log: egg-info is not needed after all From reebalazs at codespeak.net Sat Feb 10 21:13:45 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Sat, 10 Feb 2007 21:13:45 +0100 (CET) Subject: [KSS-checkins] r38407 - kukit/kss.core/trunk/kss/core Message-ID: <20070210201345.793EE10094@code0.codespeak.net> Author: reebalazs Date: Sat Feb 10 21:13:43 2007 New Revision: 38407 Modified: kukit/kss.core/trunk/kss/core/version.txt Log: Fix version.txt Modified: kukit/kss.core/trunk/kss/core/version.txt ============================================================================== --- kukit/kss.core/trunk/kss/core/version.txt (original) +++ kukit/kss.core/trunk/kss/core/version.txt Sat Feb 10 21:13:43 2007 @@ -1 +1 @@ -1.1-after unreleased +1.2dev unreleased From reebalazs at codespeak.net Sat Feb 10 21:36:31 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Sat, 10 Feb 2007 21:36:31 +0100 (CET) Subject: [KSS-checkins] r38409 - kukit/kukit.js/trunk Message-ID: <20070210203631.CA1E010093@code0.codespeak.net> Author: reebalazs Date: Sat Feb 10 21:36:30 2007 New Revision: 38409 Modified: kukit/kukit.js/trunk/version.txt Log: Adjust version.txt Modified: kukit/kukit.js/trunk/version.txt ============================================================================== --- kukit/kukit.js/trunk/version.txt (original) +++ kukit/kukit.js/trunk/version.txt Sat Feb 10 21:36:30 2007 @@ -1 +1 @@ -1.0-after unreleased +1.2dev unreleased From reebalazs at codespeak.net Sat Feb 10 21:37:20 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Sat, 10 Feb 2007 21:37:20 +0100 (CET) Subject: [KSS-checkins] r38410 - kukit/kukit.js/tag/1.2-alpha2 Message-ID: <20070210203720.BC88E10093@code0.codespeak.net> Author: reebalazs Date: Sat Feb 10 21:37:19 2007 New Revision: 38410 Added: kukit/kukit.js/tag/1.2-alpha2/ - copied from r38409, kukit/kukit.js/trunk/ Log: Release tag From reebalazs at codespeak.net Sat Feb 10 21:41:58 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Sat, 10 Feb 2007 21:41:58 +0100 (CET) Subject: [KSS-checkins] r38411 - kukit/kukit.js/tag/1.2-alpha2 Message-ID: <20070210204158.5975010093@code0.codespeak.net> Author: reebalazs Date: Sat Feb 10 21:41:57 2007 New Revision: 38411 Modified: kukit/kukit.js/tag/1.2-alpha2/version.txt Log: Change version.txt Modified: kukit/kukit.js/tag/1.2-alpha2/version.txt ============================================================================== --- kukit/kukit.js/tag/1.2-alpha2/version.txt (original) +++ kukit/kukit.js/tag/1.2-alpha2/version.txt Sat Feb 10 21:41:57 2007 @@ -1 +1 @@ -1.2dev unreleased +1.2-alpha2 Released 2007.02.10 From reebalazs at codespeak.net Sat Feb 10 21:43:00 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Sat, 10 Feb 2007 21:43:00 +0100 (CET) Subject: [KSS-checkins] r38412 - kukit/kss.core/tag/1.2-alpha2 Message-ID: <20070210204300.0206610093@code0.codespeak.net> Author: reebalazs Date: Sat Feb 10 21:42:59 2007 New Revision: 38412 Added: kukit/kss.core/tag/1.2-alpha2/ - copied from r38411, kukit/kss.core/trunk/ Log: Release tag From reebalazs at codespeak.net Sat Feb 10 21:47:13 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Sat, 10 Feb 2007 21:47:13 +0100 (CET) Subject: [KSS-checkins] r38413 - in kukit/kss.core/tag/1.2-alpha2: . kss/core Message-ID: <20070210204713.8826F10093@code0.codespeak.net> Author: reebalazs Date: Sat Feb 10 21:47:12 2007 New Revision: 38413 Removed: kukit/kss.core/tag/1.2-alpha2/setup.cfg Modified: kukit/kss.core/tag/1.2-alpha2/kss/core/ (props changed) kukit/kss.core/tag/1.2-alpha2/kss/core/EXTERNALS.TXT kukit/kss.core/tag/1.2-alpha2/kss/core/version.txt kukit/kss.core/tag/1.2-alpha2/setup.py Log: Adjust release version Modified: kukit/kss.core/tag/1.2-alpha2/kss/core/EXTERNALS.TXT ============================================================================== --- kukit/kss.core/tag/1.2-alpha2/kss/core/EXTERNALS.TXT (original) +++ kukit/kss.core/tag/1.2-alpha2/kss/core/EXTERNALS.TXT Sat Feb 10 21:47:12 2007 @@ -5,4 +5,4 @@ # You can update your working dir by: # svn propset svn:externals -F EXTERNALS.TXT . # -kukit http://codespeak.net/svn/kukit/kukit.js/trunk +kukit http://codespeak.net/svn/kukit/kukit.js/tag/1.2-alpha2 Modified: kukit/kss.core/tag/1.2-alpha2/kss/core/version.txt ============================================================================== --- kukit/kss.core/tag/1.2-alpha2/kss/core/version.txt (original) +++ kukit/kss.core/tag/1.2-alpha2/kss/core/version.txt Sat Feb 10 21:47:12 2007 @@ -1 +1 @@ -1.2dev unreleased +1.2-alpha2 Released 2007.02.10 Deleted: /kukit/kss.core/tag/1.2-alpha2/setup.cfg ============================================================================== --- /kukit/kss.core/tag/1.2-alpha2/setup.cfg Sat Feb 10 21:47:12 2007 +++ (empty file) @@ -1,3 +0,0 @@ -[egg_info] -tag_build = dev -tag_svn_revision = true Modified: kukit/kss.core/tag/1.2-alpha2/setup.py ============================================================================== --- kukit/kss.core/tag/1.2-alpha2/setup.py (original) +++ kukit/kss.core/tag/1.2-alpha2/setup.py Sat Feb 10 21:47:12 2007 @@ -1,7 +1,7 @@ from setuptools import setup, find_packages import sys, os -version = '1.2' +version = '1.2-alpha2' setup(name='kss.core', version=version, From reebalazs at codespeak.net Sat Feb 10 23:04:28 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Sat, 10 Feb 2007 23:04:28 +0100 (CET) Subject: [KSS-checkins] r38423 - in kukit/kss.demo/trunk: . docs kss.demo.egg-info kss/demo Message-ID: <20070210220428.BAFAD10093@code0.codespeak.net> Author: reebalazs Date: Sat Feb 10 23:04:27 2007 New Revision: 38423 Removed: kukit/kss.demo/trunk/kss.demo.egg-info/ kukit/kss.demo/trunk/kss/demo/INSTALL.txt Modified: kukit/kss.demo/trunk/README.txt kukit/kss.demo/trunk/docs/HISTORY.txt kukit/kss.demo/trunk/docs/INSTALL.txt kukit/kss.demo/trunk/kss/demo/version.txt kukit/kss.demo/trunk/setup.py Log: Removing egg-info, move docs to their egg nest, prepare versions for release Modified: kukit/kss.demo/trunk/README.txt ============================================================================== --- kukit/kss.demo/trunk/README.txt (original) +++ kukit/kss.demo/trunk/README.txt Sat Feb 10 23:04:27 2007 @@ -5,3 +5,4 @@ -------- KSS (Kinetic Style Sheet) demo + Modified: kukit/kss.demo/trunk/docs/HISTORY.txt ============================================================================== --- kukit/kss.demo/trunk/docs/HISTORY.txt (original) +++ kukit/kss.demo/trunk/docs/HISTORY.txt Sat Feb 10 23:04:27 2007 @@ -2,7 +2,14 @@ (name of developer listed in brackets) -kss.demo - 0.1 Unreleased +kss.demo - 1.2dev Unreleased + + - ... + +kss.demo - 1.2-alpha2 Unreleased + + - Preparation for release + [ree] - Initial package structure. [zopeskel] Modified: kukit/kss.demo/trunk/docs/INSTALL.txt ============================================================================== --- kukit/kss.demo/trunk/docs/INSTALL.txt (original) +++ kukit/kss.demo/trunk/docs/INSTALL.txt Sat Feb 10 23:04:27 2007 @@ -10,8 +10,8 @@ ``kss/demo/kss.demo-meta.zcml`` in the ``/path/to/instance/etc/package-includes`` directory. - * On Zope 2.8, the package-includes directory is not created by - default, so you also have to create it. + * On Zope 2.8, the package-includes directory is not created by + default, so you also have to create it. * In the ZMI, add a "Kss Simple content" anywhere. Call it "kssdemo" or anything you wish. Deleted: /kukit/kss.demo/trunk/kss/demo/INSTALL.txt ============================================================================== --- /kukit/kss.demo/trunk/kss/demo/INSTALL.txt Sat Feb 10 23:04:27 2007 +++ (empty file) @@ -1,18 +0,0 @@ - -INSTALLATION NOTES -================== - -1. Drop kss.demo into your $INSTANCE/lib/python dir (it must be in the subdir - kss/demo/, and the kss base directory must hold an empty __init__.py file). - -2. Copy slugs kss.demo-configure.zcml and kss.demo-meta.zcml into - $INSTANCE/etc/package-includes directory. - - * On Zope 2.8, the package-includes directory is not created by - default, so you also have to create it. - -3. In the zmi, add a "Kss Simple content" anywhere - let's call it "kssdemo" - -4. Get into "test" page, you should have a menu with available demos - Modified: kukit/kss.demo/trunk/kss/demo/version.txt ============================================================================== --- kukit/kss.demo/trunk/kss/demo/version.txt (original) +++ kukit/kss.demo/trunk/kss/demo/version.txt Sat Feb 10 23:04:27 2007 @@ -1 +1 @@ -1.1-after unreleased +1.2dev Unreleased Modified: kukit/kss.demo/trunk/setup.py ============================================================================== --- kukit/kss.demo/trunk/setup.py (original) +++ kukit/kss.demo/trunk/setup.py Sat Feb 10 23:04:27 2007 @@ -1,7 +1,7 @@ from setuptools import setup, find_packages import sys, os -version = '0.1' +version = '1.2' setup(name='kss.demo', version=version, From reebalazs at codespeak.net Sat Feb 10 23:05:00 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Sat, 10 Feb 2007 23:05:00 +0100 (CET) Subject: [KSS-checkins] r38424 - kukit/kss.demo/tag/1.2-alpha2 Message-ID: <20070210220500.8A81B10093@code0.codespeak.net> Author: reebalazs Date: Sat Feb 10 23:04:59 2007 New Revision: 38424 Added: kukit/kss.demo/tag/1.2-alpha2/ - copied from r38423, kukit/kss.demo/trunk/ Log: Tag for release From reebalazs at codespeak.net Sat Feb 10 23:07:19 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Sat, 10 Feb 2007 23:07:19 +0100 (CET) Subject: [KSS-checkins] r38425 - in kukit/kss.demo/tag/1.2-alpha2: . kss/demo Message-ID: <20070210220719.8219810093@code0.codespeak.net> Author: reebalazs Date: Sat Feb 10 23:07:18 2007 New Revision: 38425 Removed: kukit/kss.demo/tag/1.2-alpha2/setup.cfg Modified: kukit/kss.demo/tag/1.2-alpha2/kss/demo/version.txt kukit/kss.demo/tag/1.2-alpha2/setup.py Log: Adjust versions for release Modified: kukit/kss.demo/tag/1.2-alpha2/kss/demo/version.txt ============================================================================== --- kukit/kss.demo/tag/1.2-alpha2/kss/demo/version.txt (original) +++ kukit/kss.demo/tag/1.2-alpha2/kss/demo/version.txt Sat Feb 10 23:07:18 2007 @@ -1 +1 @@ -1.2dev Unreleased +1.2-alpha2 Released 2007.02.10 Deleted: /kukit/kss.demo/tag/1.2-alpha2/setup.cfg ============================================================================== --- /kukit/kss.demo/tag/1.2-alpha2/setup.cfg Sat Feb 10 23:07:18 2007 +++ (empty file) @@ -1,3 +0,0 @@ -[egg_info] -tag_build = dev -tag_svn_revision = true Modified: kukit/kss.demo/tag/1.2-alpha2/setup.py ============================================================================== --- kukit/kss.demo/tag/1.2-alpha2/setup.py (original) +++ kukit/kss.demo/tag/1.2-alpha2/setup.py Sat Feb 10 23:07:18 2007 @@ -1,7 +1,7 @@ from setuptools import setup, find_packages import sys, os -version = '1.2' +version = '1.2-alpha2' setup(name='kss.demo', version=version, @@ -26,12 +26,11 @@ zip_safe=False, install_requires=[ # -*- Extra requirements: -*- - 'kss.core>=dev', + 'kss.core>=1.2-alpha2', ], entry_points=""" # -*- Entry points: -*- """, dependency_links=[ - 'https://codespeak.net/svn/kukit/kss.core/trunk#egg=kss.core-dev', ], ) From reebalazs at codespeak.net Sat Feb 10 23:09:36 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Sat, 10 Feb 2007 23:09:36 +0100 (CET) Subject: [KSS-checkins] r38426 - kukit/kss.demo/trunk Message-ID: <20070210220936.6F90610093@code0.codespeak.net> Author: reebalazs Date: Sat Feb 10 23:09:35 2007 New Revision: 38426 Modified: kukit/kss.demo/trunk/setup.py Log: Minor fix in egg description Modified: kukit/kss.demo/trunk/setup.py ============================================================================== --- kukit/kss.demo/trunk/setup.py (original) +++ kukit/kss.demo/trunk/setup.py Sat Feb 10 23:09:35 2007 @@ -5,7 +5,7 @@ setup(name='kss.demo', version=version, - description="KSS (Kinetic Style Sheet) demo", + description="KSS (Kinetic Style Sheets) demo", long_description="""\ """, # Get more strings from http://www.python.org/pypi?%3Aaction=list_classifiers From gotcha at codespeak.net Sun Feb 11 17:08:35 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Sun, 11 Feb 2007 17:08:35 +0100 (CET) Subject: [KSS-checkins] r38471 - kukit/kss.core/trunk/kss/core/doc Message-ID: <20070211160835.AC01210093@code0.codespeak.net> Author: gotcha Date: Sun Feb 11 17:08:33 2007 New Revision: 38471 Added: kukit/kss.core/trunk/kss/core/doc/ kukit/kss.core/trunk/kss/core/doc/tutorial_part2.rst Log: add rest version of tutorial part 2 Added: kukit/kss.core/trunk/kss/core/doc/tutorial_part2.rst ============================================================================== --- (empty file) +++ kukit/kss.core/trunk/kss/core/doc/tutorial_part2.rst Sun Feb 11 17:08:33 2007 @@ -0,0 +1,383 @@ +This 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. + +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. + From gotcha at codespeak.net Sun Feb 11 17:29:29 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Sun, 11 Feb 2007 17:29:29 +0100 (CET) Subject: [KSS-checkins] r38476 - kukit/kss.core/trunk/kss/core/doc Message-ID: <20070211162929.0AC481007B@code0.codespeak.net> Author: gotcha Date: Sun Feb 11 17:29:28 2007 New Revision: 38476 Modified: kukit/kss.core/trunk/kss/core/doc/tutorial_part2.rst Log: fix hyperlink Modified: kukit/kss.core/trunk/kss/core/doc/tutorial_part2.rst ============================================================================== --- kukit/kss.core/trunk/kss/core/doc/tutorial_part2.rst (original) +++ kukit/kss.core/trunk/kss/core/doc/tutorial_part2.rst Sun Feb 11 17:29:28 2007 @@ -1,8 +1,9 @@ -This tutorial is the direct continuation of the `first part -`_. We will +This 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 ------------------------ From hannosch at codespeak.net Mon Feb 12 10:19:49 2007 From: hannosch at codespeak.net (hannosch at codespeak.net) Date: Mon, 12 Feb 2007 10:19:49 +0100 (CET) Subject: [KSS-checkins] r38536 - kukit/kss.core/trunk/kss/core/tests Message-ID: <20070212091949.2E265100B0@code0.codespeak.net> Author: hannosch Date: Mon Feb 12 10:19:48 2007 New Revision: 38536 Modified: kukit/kss.core/trunk/kss/core/tests/test_azaxview_core.py Log: Added a missing encoding declaration Modified: kukit/kss.core/trunk/kss/core/tests/test_azaxview_core.py ============================================================================== --- kukit/kss.core/trunk/kss/core/tests/test_azaxview_core.py (original) +++ kukit/kss.core/trunk/kss/core/tests/test_azaxview_core.py Mon Feb 12 10:19:48 2007 @@ -1,3 +1,4 @@ +# -*- coding: latin-1 -*- import unittest import textwrap from kss.core import AzaxUnicodeError From gotcha at codespeak.net Mon Feb 12 12:17:56 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Mon, 12 Feb 2007 12:17:56 +0100 (CET) Subject: [KSS-checkins] r38543 - kukit/kss.buildout/trunk Message-ID: <20070212111756.16C7C100A4@code0.codespeak.net> Author: gotcha Date: Mon Feb 12 12:17:48 2007 New Revision: 38543 Modified: kukit/kss.buildout/trunk/dotests.py Log: pass data through args Modified: kukit/kss.buildout/trunk/dotests.py ============================================================================== --- kukit/kss.buildout/trunk/dotests.py (original) +++ kukit/kss.buildout/trunk/dotests.py Mon Feb 12 12:17:48 2007 @@ -1,8 +1,12 @@ import os, signal, sys +java = sys.argv[1] +seleniumbrowser = sys.argv[2] here = os.getcwd() + #start seleniumRC server -javapid = os.spawnl(os.P_NOWAIT, '/usr/bin/java', '/usr/bin/java', '-jar', 'parts/seleniumrc/selenium-server.jar') +seleniumjar = os.path.join('parts', 'seleniumrc', 'selenium-server.jar') +javapid = os.spawnl(os.P_NOWAIT, java, java, '-jar', seleniumjar ) #start zope zope = os.path.join(here, 'parts', 'instance', 'bin', 'zopectl') @@ -25,6 +29,7 @@ #start tests python = sys.executable zope_test = os.path.join(here, 'tests') +os.environ['SELENIUMBROWSER'] = seleniumbrowser test_command_pieces = [zope_test] test_command_pieces.append('--package-path') test_command_pieces.append(os.path.join(here, 'src', 'kss.demo', 'kss', 'demo', 'tests')) From gotcha at codespeak.net Mon Feb 12 17:40:00 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Mon, 12 Feb 2007 17:40:00 +0100 (CET) Subject: [KSS-checkins] r38592 - kukit/kss.buildout/trunk Message-ID: <20070212164000.D14E710077@code0.codespeak.net> Author: gotcha Date: Mon Feb 12 17:39:59 2007 New Revision: 38592 Modified: kukit/kss.buildout/trunk/dotests.py Log: use subprocess Modified: kukit/kss.buildout/trunk/dotests.py ============================================================================== --- kukit/kss.buildout/trunk/dotests.py (original) +++ kukit/kss.buildout/trunk/dotests.py Mon Feb 12 17:39:59 2007 @@ -1,4 +1,5 @@ import os, signal, sys +import subprocess java = sys.argv[1] seleniumbrowser = sys.argv[2] @@ -6,37 +7,37 @@ #start seleniumRC server seleniumjar = os.path.join('parts', 'seleniumrc', 'selenium-server.jar') -javapid = os.spawnl(os.P_NOWAIT, java, java, '-jar', seleniumjar ) +javapid = subprocess.Popen([java, '-jar', seleniumjar]).pid #start zope zope = os.path.join(here, 'parts', 'instance', 'bin', 'zopectl') -os.spawnl(os.P_WAIT, zope, zope, 'start') +subprocess.call([zope, 'start']) #wait for zope instance to come up from time import sleep testcmd = "wget -O- http://localhost:8080" -while os.spawnvp(os.P_WAIT, 'wget', testcmd.split()): +while subprocess.call(testcmd.split()): sleep(1) #setup simple content instance testcmd = "wget -O- http://localhost:8080/demo" -exitcode = os.spawnvp(os.P_WAIT, 'wget', testcmd.split()) +exitcode = subprocess.call(testcmd.split()) if exitcode <> 0: print "add" setupcmd = """wget -O- --http-user=admin --http-password=admin --post-data add_input_name=demo&UPDATE_SUBMIT=Add http://localhost:8080/+/AddSimpleContent.html""" - exitcode = os.spawnvp(os.P_WAIT, 'wget', setupcmd.split()) + exitcode = subprocess.call(setupcmd.split()) #start tests python = sys.executable zope_test = os.path.join(here, 'tests') -os.environ['SELENIUMBROWSER'] = seleniumbrowser +environ = {} +environ['SELENIUMBROWSER'] = seleniumbrowser test_command_pieces = [zope_test] test_command_pieces.append('--package-path') test_command_pieces.append(os.path.join(here, 'src', 'kss.demo', 'kss', 'demo', 'tests')) test_command_pieces.append('kss.demo.tests --test-file-pattern=^seltest --tests-pattern=selenium_tests') test_command = ' '.join(test_command_pieces) -print test_command -std = os.popen(test_command) +std = Popen(cmd, shell=True, bufsize=bufsize, stdout=PIPE, env=environ).stdout print std.read() test_exit = std.close() @@ -44,7 +45,6 @@ os.kill(javapid, signal.SIGKILL) #stop zope -os.spawnl(os.P_WAIT, zope, zope, 'stop') +subprocess.call([zope, 'stop']) -print test_exit sys.exit(test_exit) From gotcha at codespeak.net Mon Feb 12 17:42:22 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Mon, 12 Feb 2007 17:42:22 +0100 (CET) Subject: [KSS-checkins] r38594 - kukit/kss.buildout/trunk Message-ID: <20070212164222.8D671100A9@code0.codespeak.net> Author: gotcha Date: Mon Feb 12 17:42:21 2007 New Revision: 38594 Modified: kukit/kss.buildout/trunk/dotests.py Log: fix global Popen Modified: kukit/kss.buildout/trunk/dotests.py ============================================================================== --- kukit/kss.buildout/trunk/dotests.py (original) +++ kukit/kss.buildout/trunk/dotests.py Mon Feb 12 17:42:21 2007 @@ -37,7 +37,7 @@ test_command_pieces.append(os.path.join(here, 'src', 'kss.demo', 'kss', 'demo', 'tests')) test_command_pieces.append('kss.demo.tests --test-file-pattern=^seltest --tests-pattern=selenium_tests') test_command = ' '.join(test_command_pieces) -std = Popen(cmd, shell=True, bufsize=bufsize, stdout=PIPE, env=environ).stdout +std = subprocess.Popen(cmd, shell=True, bufsize=bufsize, stdout=PIPE, env=environ).stdout print std.read() test_exit = std.close() From gotcha at codespeak.net Mon Feb 12 18:03:54 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Mon, 12 Feb 2007 18:03:54 +0100 (CET) Subject: [KSS-checkins] r38600 - kukit/kss.buildout/trunk Message-ID: <20070212170354.9A807100AB@code0.codespeak.net> Author: gotcha Date: Mon Feb 12 18:03:53 2007 New Revision: 38600 Modified: kukit/kss.buildout/trunk/dotests.py Log: fix command Modified: kukit/kss.buildout/trunk/dotests.py ============================================================================== --- kukit/kss.buildout/trunk/dotests.py (original) +++ kukit/kss.buildout/trunk/dotests.py Mon Feb 12 18:03:53 2007 @@ -37,7 +37,7 @@ test_command_pieces.append(os.path.join(here, 'src', 'kss.demo', 'kss', 'demo', 'tests')) test_command_pieces.append('kss.demo.tests --test-file-pattern=^seltest --tests-pattern=selenium_tests') test_command = ' '.join(test_command_pieces) -std = subprocess.Popen(cmd, shell=True, bufsize=bufsize, stdout=PIPE, env=environ).stdout +std = subprocess.Popen(test_command.split(), shell=True, bufsize=bufsize, stdout=PIPE, env=environ).stdout print std.read() test_exit = std.close() From gotcha at codespeak.net Mon Feb 12 18:06:10 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Mon, 12 Feb 2007 18:06:10 +0100 (CET) Subject: [KSS-checkins] r38604 - kukit/kss.buildout/trunk Message-ID: <20070212170610.6C1A2100AB@code0.codespeak.net> Author: gotcha Date: Mon Feb 12 18:06:09 2007 New Revision: 38604 Modified: kukit/kss.buildout/trunk/dotests.py Log: remove bufsize Modified: kukit/kss.buildout/trunk/dotests.py ============================================================================== --- kukit/kss.buildout/trunk/dotests.py (original) +++ kukit/kss.buildout/trunk/dotests.py Mon Feb 12 18:06:09 2007 @@ -37,7 +37,7 @@ test_command_pieces.append(os.path.join(here, 'src', 'kss.demo', 'kss', 'demo', 'tests')) test_command_pieces.append('kss.demo.tests --test-file-pattern=^seltest --tests-pattern=selenium_tests') test_command = ' '.join(test_command_pieces) -std = subprocess.Popen(test_command.split(), shell=True, bufsize=bufsize, stdout=PIPE, env=environ).stdout +std = subprocess.Popen(test_command.split(), shell=True, stdout=PIPE, env=environ).stdout print std.read() test_exit = std.close() From gotcha at codespeak.net Mon Feb 12 18:09:17 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Mon, 12 Feb 2007 18:09:17 +0100 (CET) Subject: [KSS-checkins] r38605 - kukit/kss.buildout/trunk Message-ID: <20070212170917.314B310077@code0.codespeak.net> Author: gotcha Date: Mon Feb 12 18:09:16 2007 New Revision: 38605 Modified: kukit/kss.buildout/trunk/dotests.py Log: fix global PIPE; I should never cut and paste ;-) Modified: kukit/kss.buildout/trunk/dotests.py ============================================================================== --- kukit/kss.buildout/trunk/dotests.py (original) +++ kukit/kss.buildout/trunk/dotests.py Mon Feb 12 18:09:16 2007 @@ -37,7 +37,7 @@ test_command_pieces.append(os.path.join(here, 'src', 'kss.demo', 'kss', 'demo', 'tests')) test_command_pieces.append('kss.demo.tests --test-file-pattern=^seltest --tests-pattern=selenium_tests') test_command = ' '.join(test_command_pieces) -std = subprocess.Popen(test_command.split(), shell=True, stdout=PIPE, env=environ).stdout +std = subprocess.Popen(test_command.split(), shell=True, stdout=subprocess.PIPE, env=environ).stdout print std.read() test_exit = std.close() From gotcha at codespeak.net Mon Feb 12 18:11:32 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Mon, 12 Feb 2007 18:11:32 +0100 (CET) Subject: [KSS-checkins] r38606 - kukit/kss.buildout/trunk Message-ID: <20070212171132.AC3C710077@code0.codespeak.net> Author: gotcha Date: Mon Feb 12 18:11:31 2007 New Revision: 38606 Modified: kukit/kss.buildout/trunk/dotests.py Log: debug Modified: kukit/kss.buildout/trunk/dotests.py ============================================================================== --- kukit/kss.buildout/trunk/dotests.py (original) +++ kukit/kss.buildout/trunk/dotests.py Mon Feb 12 18:11:31 2007 @@ -37,6 +37,7 @@ test_command_pieces.append(os.path.join(here, 'src', 'kss.demo', 'kss', 'demo', 'tests')) test_command_pieces.append('kss.demo.tests --test-file-pattern=^seltest --tests-pattern=selenium_tests') test_command = ' '.join(test_command_pieces) +print test_command std = subprocess.Popen(test_command.split(), shell=True, stdout=subprocess.PIPE, env=environ).stdout print std.read() test_exit = std.close() From gotcha at codespeak.net Mon Feb 12 18:27:28 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Mon, 12 Feb 2007 18:27:28 +0100 (CET) Subject: [KSS-checkins] r38609 - kukit/kss.buildout/trunk Message-ID: <20070212172728.AF8F8100A4@code0.codespeak.net> Author: gotcha Date: Mon Feb 12 18:27:27 2007 New Revision: 38609 Modified: kukit/kss.buildout/trunk/dotests.py Log: fix java startup for win32 Modified: kukit/kss.buildout/trunk/dotests.py ============================================================================== --- kukit/kss.buildout/trunk/dotests.py (original) +++ kukit/kss.buildout/trunk/dotests.py Mon Feb 12 18:27:27 2007 @@ -7,7 +7,8 @@ #start seleniumRC server seleniumjar = os.path.join('parts', 'seleniumrc', 'selenium-server.jar') -javapid = subprocess.Popen([java, '-jar', seleniumjar]).pid +javacmd = " ".join([java, '-jar', seleniumjar]) +javapid = subprocess.Popen(javacmd).pid #start zope zope = os.path.join(here, 'parts', 'instance', 'bin', 'zopectl') From gotcha at codespeak.net Mon Feb 12 18:35:23 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Mon, 12 Feb 2007 18:35:23 +0100 (CET) Subject: [KSS-checkins] r38612 - kukit/kss.buildout/trunk Message-ID: <20070212173523.B2FF3100A6@code0.codespeak.net> Author: gotcha Date: Mon Feb 12 18:35:22 2007 New Revision: 38612 Modified: kukit/kss.buildout/trunk/dotests.py Log: try to fix java startup for win32 Modified: kukit/kss.buildout/trunk/dotests.py ============================================================================== --- kukit/kss.buildout/trunk/dotests.py (original) +++ kukit/kss.buildout/trunk/dotests.py Mon Feb 12 18:35:22 2007 @@ -7,8 +7,7 @@ #start seleniumRC server seleniumjar = os.path.join('parts', 'seleniumrc', 'selenium-server.jar') -javacmd = " ".join([java, '-jar', seleniumjar]) -javapid = subprocess.Popen(javacmd).pid +javapid = os.spawnl(os.P_NOWAIT, java, 'java', '-jar', seleniumjar ) #start zope zope = os.path.join(here, 'parts', 'instance', 'bin', 'zopectl') @@ -39,7 +38,7 @@ test_command_pieces.append('kss.demo.tests --test-file-pattern=^seltest --tests-pattern=selenium_tests') test_command = ' '.join(test_command_pieces) print test_command -std = subprocess.Popen(test_command.split(), shell=True, stdout=subprocess.PIPE, env=environ).stdout +std = os.popen(test_command) print std.read() test_exit = std.close() From gotcha at codespeak.net Mon Feb 12 18:44:15 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Mon, 12 Feb 2007 18:44:15 +0100 (CET) Subject: [KSS-checkins] r38615 - kukit/kss.buildout/trunk Message-ID: <20070212174415.B6CF01009C@code0.codespeak.net> Author: gotcha Date: Mon Feb 12 18:44:14 2007 New Revision: 38615 Added: kukit/kss.buildout/trunk/dotests_win.py Log: stop to try sharing the script Added: kukit/kss.buildout/trunk/dotests_win.py ============================================================================== --- (empty file) +++ kukit/kss.buildout/trunk/dotests_win.py Mon Feb 12 18:44:14 2007 @@ -0,0 +1,51 @@ +import os, signal, sys +import subprocess + +java = sys.argv[1] +seleniumbrowser = sys.argv[2] +here = os.getcwd() + +#start seleniumRC server +seleniumjar = os.path.join('parts', 'seleniumrc', 'selenium-server.jar') +javapid = os.spawnl(os.P_NOWAIT, java, 'java', '-jar', seleniumjar ) + +#start zope +zope = os.path.join(here, 'parts', 'instance', 'bin', 'zopectl') +subprocess.call([zope, 'start']) + +#wait for zope instance to come up +from time import sleep +testcmd = "wget -O- http://localhost:8080" +while subprocess.call(testcmd.split()): + sleep(1) + +#setup simple content instance +testcmd = "wget -O- http://localhost:8080/demo" +exitcode = subprocess.call(testcmd.split()) +if exitcode <> 0: + print "add" + setupcmd = """wget -O- --http-user=admin --http-password=admin --post-data add_input_name=demo&UPDATE_SUBMIT=Add http://localhost:8080/+/AddSimpleContent.html""" + exitcode = subprocess.call(setupcmd.split()) + +#start tests +python = sys.executable +zope_test = os.path.join(here, 'tests') +environ = {} +environ['SELENIUMBROWSER'] = seleniumbrowser +test_command_pieces = [zope_test] +test_command_pieces.append('--package-path') +test_command_pieces.append(os.path.join(here, 'src', 'kss.demo', 'kss', 'demo', 'tests')) +test_command_pieces.append('kss.demo.tests --test-file-pattern=^seltest --tests-pattern=selenium_tests') +test_command = ' '.join(test_command_pieces) +print test_command +std = os.popen(test_command) +print std.read() +test_exit = std.close() + +#stop seleniumRC server +os.kill(javapid, signal.SIGKILL) + +#stop zope +subprocess.call([zope, 'stop']) + +sys.exit(test_exit) From gotcha at codespeak.net Mon Feb 12 18:45:31 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Mon, 12 Feb 2007 18:45:31 +0100 (CET) Subject: [KSS-checkins] r38616 - kukit/kss.buildout/trunk Message-ID: <20070212174531.280BF1009C@code0.codespeak.net> Author: gotcha Date: Mon Feb 12 18:45:30 2007 New Revision: 38616 Modified: kukit/kss.buildout/trunk/dotests.py Log: keep subprocess Modified: kukit/kss.buildout/trunk/dotests.py ============================================================================== --- kukit/kss.buildout/trunk/dotests.py (original) +++ kukit/kss.buildout/trunk/dotests.py Mon Feb 12 18:45:30 2007 @@ -7,7 +7,7 @@ #start seleniumRC server seleniumjar = os.path.join('parts', 'seleniumrc', 'selenium-server.jar') -javapid = os.spawnl(os.P_NOWAIT, java, 'java', '-jar', seleniumjar ) +javapid = subprocess.Popen(javacmd).pid #start zope zope = os.path.join(here, 'parts', 'instance', 'bin', 'zopectl') From gotcha at codespeak.net Mon Feb 12 18:49:04 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Mon, 12 Feb 2007 18:49:04 +0100 (CET) Subject: [KSS-checkins] r38617 - kukit/kss.buildout/trunk Message-ID: <20070212174904.0497E100A8@code0.codespeak.net> Author: gotcha Date: Mon Feb 12 18:49:04 2007 New Revision: 38617 Modified: kukit/kss.buildout/trunk/dotests_win.py Log: try bat file Modified: kukit/kss.buildout/trunk/dotests_win.py ============================================================================== --- kukit/kss.buildout/trunk/dotests_win.py (original) +++ kukit/kss.buildout/trunk/dotests_win.py Mon Feb 12 18:49:04 2007 @@ -11,7 +11,10 @@ #start zope zope = os.path.join(here, 'parts', 'instance', 'bin', 'zopectl') -subprocess.call([zope, 'start']) +batfile = open('script.bat', 'w') +batfile.write(" ".join([zope, 'start']) +batfile.close() +subprocess.call('script.bat') #wait for zope instance to come up from time import sleep From gotcha at codespeak.net Mon Feb 12 18:50:42 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Mon, 12 Feb 2007 18:50:42 +0100 (CET) Subject: [KSS-checkins] r38618 - kukit/kss.buildout/trunk Message-ID: <20070212175042.4628D100A8@code0.codespeak.net> Author: gotcha Date: Mon Feb 12 18:50:41 2007 New Revision: 38618 Modified: kukit/kss.buildout/trunk/dotests.py Log: too late to work ;-) Modified: kukit/kss.buildout/trunk/dotests.py ============================================================================== --- kukit/kss.buildout/trunk/dotests.py (original) +++ kukit/kss.buildout/trunk/dotests.py Mon Feb 12 18:50:41 2007 @@ -7,6 +7,7 @@ #start seleniumRC server seleniumjar = os.path.join('parts', 'seleniumrc', 'selenium-server.jar') +javacmd = " ".join([java, '-jar', seleniumjar]) javapid = subprocess.Popen(javacmd).pid #start zope From gotcha at codespeak.net Mon Feb 12 18:51:20 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Mon, 12 Feb 2007 18:51:20 +0100 (CET) Subject: [KSS-checkins] r38619 - kukit/kss.buildout/trunk Message-ID: <20070212175120.3FCE9100A8@code0.codespeak.net> Author: gotcha Date: Mon Feb 12 18:51:19 2007 New Revision: 38619 Modified: kukit/kss.buildout/trunk/dotests_win.py Log: too late to work ;-) Modified: kukit/kss.buildout/trunk/dotests_win.py ============================================================================== --- kukit/kss.buildout/trunk/dotests_win.py (original) +++ kukit/kss.buildout/trunk/dotests_win.py Mon Feb 12 18:51:19 2007 @@ -12,7 +12,7 @@ #start zope zope = os.path.join(here, 'parts', 'instance', 'bin', 'zopectl') batfile = open('script.bat', 'w') -batfile.write(" ".join([zope, 'start']) +batfile.write(" ".join([zope, 'start'])) batfile.close() subprocess.call('script.bat') From gotcha at codespeak.net Mon Feb 12 18:53:08 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Mon, 12 Feb 2007 18:53:08 +0100 (CET) Subject: [KSS-checkins] r38620 - kukit/kss.buildout/trunk Message-ID: <20070212175308.0206B100A8@code0.codespeak.net> Author: gotcha Date: Mon Feb 12 18:53:08 2007 New Revision: 38620 Modified: kukit/kss.buildout/trunk/dotests.py Log: too late to work ;-) Modified: kukit/kss.buildout/trunk/dotests.py ============================================================================== --- kukit/kss.buildout/trunk/dotests.py (original) +++ kukit/kss.buildout/trunk/dotests.py Mon Feb 12 18:53:08 2007 @@ -6,9 +6,8 @@ here = os.getcwd() #start seleniumRC server -seleniumjar = os.path.join('parts', 'seleniumrc', 'selenium-server.jar') -javacmd = " ".join([java, '-jar', seleniumjar]) -javapid = subprocess.Popen(javacmd).pid +seleniumjar = os.path.join(here, 'parts', 'seleniumrc', 'selenium-server.jar') +javapid = subprocess.Popen([java, '-jar', seleniumjar]).pid #start zope zope = os.path.join(here, 'parts', 'instance', 'bin', 'zopectl') From gotcha at codespeak.net Mon Feb 12 18:59:57 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Mon, 12 Feb 2007 18:59:57 +0100 (CET) Subject: [KSS-checkins] r38622 - kukit/kss.buildout/trunk Message-ID: <20070212175957.D96891009B@code0.codespeak.net> Author: gotcha Date: Mon Feb 12 18:59:56 2007 New Revision: 38622 Modified: kukit/kss.buildout/trunk/dotests_win.py Log: hints for another day Modified: kukit/kss.buildout/trunk/dotests_win.py ============================================================================== --- kukit/kss.buildout/trunk/dotests_win.py (original) +++ kukit/kss.buildout/trunk/dotests_win.py Mon Feb 12 18:59:56 2007 @@ -10,6 +10,7 @@ javapid = os.spawnl(os.P_NOWAIT, java, 'java', '-jar', seleniumjar ) #start zope +# should use runzope.bat zope = os.path.join(here, 'parts', 'instance', 'bin', 'zopectl') batfile = open('script.bat', 'w') batfile.write(" ".join([zope, 'start'])) @@ -46,6 +47,7 @@ test_exit = std.close() #stop seleniumRC server +#should not use os.kill os.kill(javapid, signal.SIGKILL) #stop zope From reebalazs at codespeak.net Tue Feb 13 11:37:08 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Tue, 13 Feb 2007 11:37:08 +0100 (CET) Subject: [KSS-checkins] r38668 - kukit/azax/branch/1.1 Message-ID: <20070213103708.729D8100A9@code0.codespeak.net> Author: reebalazs Date: Tue Feb 13 11:37:07 2007 New Revision: 38668 Modified: kukit/azax/branch/1.1/concatresource.zcml Log: Update concatresources according to new kukit updates. Modified: kukit/azax/branch/1.1/concatresource.zcml ============================================================================== --- kukit/azax/branch/1.1/concatresource.zcml (original) +++ kukit/azax/branch/1.1/concatresource.zcml Tue Feb 13 11:37:07 2007 @@ -4,22 +4,48 @@ + + + + + + + + Added: kukit/kss.demo/trunk/kss/demo/browser/parameterfunction/forms.kss ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/browser/parameterfunction/forms.kss Sat Feb 17 18:26:53 2007 @@ -0,0 +1,49 @@ +#text:click { + action-client: executeCommand; + executeCommand-name: replaceInnerHTML; + executeCommand-selector: "#target"; + executeCommand-html: currentFormVar(); +} + +#text-by-name:click { + action-client: executeCommand; + executeCommand-name: replaceInnerHTML; + executeCommand-selector: "#target"; + executeCommand-html: currentFormVar(text-by-name); +} + +#textarea:click { + action-client: executeCommand; + executeCommand-name: replaceInnerHTML; + executeCommand-selector: "#target"; + executeCommand-html: currentFormVar(); +} + +#textarea-by-name:click { + action-client: executeCommand; + executeCommand-name: replaceInnerHTML; + executeCommand-selector: "#target"; + executeCommand-html: currentFormVar("textarea-by-name"); +} + +#radio1:click { + action-client: executeCommand; + executeCommand-name: replaceInnerHTML; + executeCommand-selector: "#target"; + executeCommand-html: currentFormVar(); +} + +#radio2:click { + action-client: executeCommand; + executeCommand-name: replaceInnerHTML; + executeCommand-selector: "#target"; + executeCommand-html: currentFormVar(); +} + +#radio-by-name:click { + action-client: executeCommand; + executeCommand-name: replaceInnerHTML; + executeCommand-selector: "#target"; + executeCommand-html: currentFormVar(radio-by-name); +} + Added: kukit/kss.demo/trunk/kss/demo/browser/parameterfunction/forms.pt ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/browser/parameterfunction/forms.pt Sat Feb 17 18:26:53 2007 @@ -0,0 +1,106 @@ + + + + + + + + +

Forms

+

We test the parameter functions related to forms : those functions + extract values from fields to use them in the kinetic stylesheet.

+

The inner HTML of the div below will be replaced with the + value of the form element.

+
Target
+
+

+ currentFormVar() with text field. +

+
+ Click the text field. +
+
+ +
+

+ currentFormVar(name) with text field. +

+
+ Click the button. +
+
+
+ Click me ! + +
+
+

+ currentFormVar() with textarea field. +

+
+ Click the textarea field. +
+
+ +
+

+ currentFormVar() with textarea field. +

+
+ Click the button. +
+
+
+ Click me ! + +
+
+

+ currentFormVar() with radio field. +

+
+ Click one of the radio buttons. +
+
radio-1 + + radio-2 + +
+

+ currentFormVar(name) with radio field. +

+
+ Click the button. +
+
+ Click me ! + radio-1 + + radio-2 + +
+
+ + Modified: kukit/kss.demo/trunk/kss/demo/configure.zcml ============================================================================== --- kukit/kss.demo/trunk/kss/demo/configure.zcml (original) +++ kukit/kss.demo/trunk/kss/demo/configure.zcml Sat Feb 17 18:26:53 2007 @@ -60,6 +60,8 @@ /> + + Added: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/pf_forms.html ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/pf_forms.html Sat Feb 17 18:26:53 2007 @@ -0,0 +1,119 @@ + + + +pf_forms + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
pf_forms
open/demo/pf_forms.html
assertElementPresenttarget
assertTexttargetTarget
clicktext
waitForTexttargettext
assertTexttargettext
clicktext-by-name
waitForTexttargettext-by-name
assertTexttargettext-by-name
clicktextarea
waitForTexttargettextarea
assertTexttargettextarea
clicktextarea-by-name
waitForTexttargettextarea-by-name
assertTexttargettextarea-by-name
clickradio1
waitForTexttargetradio-1
assertTexttargetradio-1
clickradio-by-name
waitForTexttargetradio-2
assertTexttargetradio-2
+ + Added: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_pf_forms.py ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_pf_forms.py Sat Feb 17 18:26:53 2007 @@ -0,0 +1,67 @@ +from seleniumtestcase import SeleniumTestCase +import unittest, time + +def getTestClass(): + return seltest_pf_forms + +class seltest_pf_forms(SeleniumTestCase): + + def test_seltest_pf_forms(self): + sel = self.selenium + sel.open("/demo/pf_forms.html") + self.failUnless(sel.is_element_present("target")) + self.assertEqual("Target", sel.get_text("target")) + sel.click("text") + for i in range(60): + try: + if "text" == sel.get_text("target"): break + except: pass + time.sleep(1) + else: self.fail("time out") + self.assertEqual("text", sel.get_text("target")) + sel.click("text-by-name") + for i in range(60): + try: + if "text-by-name" == sel.get_text("target"): break + except: pass + time.sleep(1) + else: self.fail("time out") + self.assertEqual("text-by-name", sel.get_text("target")) + sel.click("textarea") + for i in range(60): + try: + if "textarea" == sel.get_text("target"): break + except: pass + time.sleep(1) + else: self.fail("time out") + self.assertEqual("textarea", sel.get_text("target")) + sel.click("textarea-by-name") + for i in range(60): + try: + if "textarea-by-name" == sel.get_text("target"): break + except: pass + time.sleep(1) + else: self.fail("time out") + self.assertEqual("textarea-by-name", sel.get_text("target")) + sel.click("radio1") + for i in range(60): + try: + if "radio-1" == sel.get_text("target"): break + except: pass + time.sleep(1) + else: self.fail("time out") + self.assertEqual("radio-1", sel.get_text("target")) + sel.click("radio-by-name") + for i in range(60): + try: + if "radio-2" == sel.get_text("target"): break + except: pass + time.sleep(1) + else: self.fail("time out") + self.assertEqual("radio-2", sel.get_text("target")) + +def test_suite(): + return unittest.makeSuite(getTestClass()) + +if __name__ == "__main__": + unittest.main() From gotcha at codespeak.net Sat Feb 17 19:29:01 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Sat, 17 Feb 2007 19:29:01 +0100 (CET) Subject: [KSS-checkins] r39137 - kukit/kss.core/trunk/docs Message-ID: <20070217182901.C9AD4101B3@code0.codespeak.net> Author: gotcha Date: Sat Feb 17 19:29:00 2007 New Revision: 39137 Added: kukit/kss.core/trunk/docs/CREDITS.TXT Log: credit where it is due Added: kukit/kss.core/trunk/docs/CREDITS.TXT ============================================================================== --- (empty file) +++ kukit/kss.core/trunk/docs/CREDITS.TXT Sat Feb 17 19:29:00 2007 @@ -0,0 +1,6 @@ +Godefroid Chapelle (gotcha at bubbblenet.be) +Tarek Ziade (ziade.tarek at gmail.com) +Florian Schulze (florian.schulze at gmx.net) +Balazs Ree (ree at greenfinity.hu) +Jeroen Vloothuis (jeroen.vloothuis at xs4all.nl) +Philipp von Weitershausen From jvloothuis at codespeak.net Sat Feb 17 21:36:00 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Sat, 17 Feb 2007 21:36:00 +0100 (CET) Subject: [KSS-checkins] r39140 - kukit/kukit.js/trunk/kukit Message-ID: <20070217203600.86A711019F@code0.codespeak.net> Author: jvloothuis Date: Sat Feb 17 21:35:59 2007 New Revision: 39140 Modified: kukit/kukit.js/trunk/kukit/selectorreg.js Log: Added a parent node selector which accepts a css selector to fetch Modified: kukit/kukit.js/trunk/kukit/selectorreg.js ============================================================================== --- kukit/kukit.js/trunk/kukit/selectorreg.js (original) +++ kukit/kukit.js/trunk/kukit/selectorreg.js Sat Feb 17 21:35:59 2007 @@ -132,5 +132,29 @@ return nodes; }); +// Return a list of all nodes that match the css expression in the parent chain +kukit.selectorTypesGlobalRegistry.register('parentnode', function(expr, node, orignode) { + var selectednodes = kukit.dom.cssQuery(expr); + var parentnodes = []; + var parentnode = orignode.parentNode; + while(parentnode.parentNode) { + parentnodes.push(parentnode); + parentnode = parentnode.parentNode; + } + // Filter the nodes so that only the ones in the parent chain remain + var results = []; + for(var i=0; i Author: jvloothuis Date: Sat Feb 17 21:37:47 2007 New Revision: 39141 Added: kukit/kss.demo/trunk/kss/demo/browser/selectors/ kukit/kss.demo/trunk/kss/demo/browser/selectors/__init__.py kukit/kss.demo/trunk/kss/demo/browser/selectors/configure.zcml kukit/kss.demo/trunk/kss/demo/browser/selectors/selectors.kss kukit/kss.demo/trunk/kss/demo/browser/selectors/selectors.pt kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/selectors.html kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_selectors.py Modified: kukit/kss.demo/trunk/kss/demo/browser/configure.zcml Log: Added a test for the new parentnode selector Modified: kukit/kss.demo/trunk/kss/demo/browser/configure.zcml ============================================================================== --- kukit/kss.demo/trunk/kss/demo/browser/configure.zcml (original) +++ kukit/kss.demo/trunk/kss/demo/browser/configure.zcml Sat Feb 17 21:37:47 2007 @@ -4,6 +4,7 @@ > + + + + + + + +
+ Added: kukit/kss.demo/trunk/kss/demo/browser/selectors/selectors.kss ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/browser/selectors/selectors.kss Sat Feb 17 21:37:47 2007 @@ -0,0 +1,23 @@ +#parentnodeok:click { + action-client: executeCommand; + executeCommand-name: replaceInnerHTML; + executeCommand-selector: '#target'; + executeCommand-selectorType: parentnode; + executeCommand-html: "ok"; +} + +#parentnodenotok:click { + action-client: executeCommand; + executeCommand-name: replaceInnerHTML; + executeCommand-selector: '#target'; + executeCommand-selectorType: parentnode; + executeCommand-html: "verry bad"; +} + +#parentnodechain:click { + action-client: executeCommand; + executeCommand-name: insertHTMLAsLastChild; + executeCommand-selector: '.nested'; + executeCommand-selectorType: parentnode; + executeCommand-html: '
selected
'; +} Added: kukit/kss.demo/trunk/kss/demo/browser/selectors/selectors.pt ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/browser/selectors/selectors.pt Sat Feb 17 21:37:47 2007 @@ -0,0 +1,52 @@ + + + + + + + + + +

Selectors

+

We test the selectors which are used in KSS. The selectors allow you to + specify what node to take action on etc.

+

+ parentnode() with node in path +

+
+ Click the text link. +
+
Target + Click me! +
+
+ Clicking the text link below should not update the target. +
+
+ Click me! +
+ + + +
+
+
+ Click me! +
+
+
+ + Added: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/selectors.html ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/selectors.html Sat Feb 17 21:37:47 2007 @@ -0,0 +1,74 @@ + + + +selectors + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
selectors
open/plone/demo/selectors.html
clickparentnodenotok
pause1000
assertTexttargetTarget Click me!
clickparentnodeok
waitForTexttargetok
assertTexttargetok
clickparentnodechain
waitForTextcss=#nesteddivs0 div.insertedselected
assertTextcss=#nesteddivs1 div.insertedselected
assertTextcss=#nesteddivs0 div.insertedselected
assertTextcss=#nesteddivs2 div.insertedselected
+ + Added: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_selectors.py ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_selectors.py Sat Feb 17 21:37:47 2007 @@ -0,0 +1,38 @@ +from seleniumtestcase import SeleniumTestCase +import unittest, time + +def getTestClass(): + return seltest_selectors + +class seltest_selectors(SeleniumTestCase): + + def test_seltest_selectors(self): + sel = self.selenium + sel.open("/plone/demo/selectors.html") + sel.click("parentnodenotok") + time.sleep(1) + self.assertEqual("Target Click me!", sel.get_text("target")) + sel.click("parentnodeok") + for i in range(60): + try: + if "ok" == sel.get_text("target"): break + except: pass + time.sleep(1) + else: self.fail("time out") + self.assertEqual("ok", sel.get_text("target")) + sel.click("parentnodechain") + for i in range(60): + try: + if "selected" == sel.get_text("css=#nesteddivs0 div.inserted"): break + except: pass + time.sleep(1) + else: self.fail("time out") + self.assertEqual("selected", sel.get_text("css=#nesteddivs1 div.inserted")) + self.assertEqual("selected", sel.get_text("css=#nesteddivs0 div.inserted")) + self.assertEqual("selected", sel.get_text("css=#nesteddivs2 div.inserted")) +def test_suite(): + return unittest.makeSuite(getTestClass()) + +if __name__ == "__main__": + unittest.main() + From jvloothuis at codespeak.net Sat Feb 17 21:39:56 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Sat, 17 Feb 2007 21:39:56 +0100 (CET) Subject: [KSS-checkins] r39142 - kukit/kss.core/trunk/kss/core/plugins/core Message-ID: <20070217203956.A68021019F@code0.codespeak.net> Author: jvloothuis Date: Sat Feb 17 21:39:55 2007 New Revision: 39142 Modified: kukit/kss.core/trunk/kss/core/plugins/core/configure.zcml Log: Added a registry for the new parentnode Modified: kukit/kss.core/trunk/kss/core/plugins/core/configure.zcml ============================================================================== --- kukit/kss.core/trunk/kss/core/plugins/core/configure.zcml (original) +++ kukit/kss.core/trunk/kss/core/plugins/core/configure.zcml Sat Feb 17 21:39:55 2007 @@ -332,6 +332,10 @@ name="samenode" /> + + Author: jvloothuis Date: Sat Feb 17 21:49:06 2007 New Revision: 39143 Modified: kukit/kss.core/trunk/kss/core/plugins/core/commands.py kukit/kss.core/trunk/kss/core/plugins/core/interfaces.py kukit/kss.core/trunk/kss/core/selectors.py Log: Added server side commands for samenode and parentnode Modified: kukit/kss.core/trunk/kss/core/plugins/core/commands.py ============================================================================== --- kukit/kss.core/trunk/kss/core/plugins/core/commands.py (original) +++ kukit/kss.core/trunk/kss/core/plugins/core/commands.py Sat Feb 17 21:49:06 2007 @@ -1,5 +1,6 @@ from interfaces import IKSSCoreCommands from kss.core.selectors import Selector, CssSelector, HtmlIdSelector +from kss.core.selectors import ParentNodeSelector, SameNodeSelector from kss.core.azaxview import CommandSet from kss.core.deprecated import deprecated from kss.core.parsers import XmlParser, HtmlParser @@ -19,6 +20,11 @@ def getHtmlIdSelector(self, selector): return HtmlIdSelector(selector) + def getSameNodeSelector(self, selector): + return SameNodeSelector(selector) + + def getParentNodeSelector(self): + return ParentNodeSelector() # XXX the list is not full: maybe complete them? Modified: kukit/kss.core/trunk/kss/core/plugins/core/interfaces.py ============================================================================== --- kukit/kss.core/trunk/kss/core/plugins/core/interfaces.py (original) +++ kukit/kss.core/trunk/kss/core/plugins/core/interfaces.py Sat Feb 17 21:49:06 2007 @@ -15,6 +15,13 @@ def getHtmlIdSelector(selector): """Return a HTML id selector with selector as the value""" + def getSameNodeSelector(): + """Return the same node as the value""" + + def getParentNodeSelector(selector): + """Return a all nodes in the parent chain which match the css + selector""" + def replaceInnerHTML(selector, new_value): """Replace the contents of a node (selector) with the new_value""" Modified: kukit/kss.core/trunk/kss/core/selectors.py ============================================================================== --- kukit/kss.core/trunk/kss/core/selectors.py (original) +++ kukit/kss.core/trunk/kss/core/selectors.py Sat Feb 17 21:49:06 2007 @@ -19,6 +19,8 @@ CSS_SELECTOR = 'css' HTMLID_SELECTOR = 'htmlid' +PARENTNODE_SELECTOR = 'parentnode' +SAMENODE_SELECTOR = 'samenode' class SelectorBase(object): @@ -29,7 +31,15 @@ type = CSS_SELECTOR class HtmlIdSelector(SelectorBase): - type = HTMLID_SELECTOR + 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 From jvloothuis at codespeak.net Sat Feb 17 21:59:47 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Sat, 17 Feb 2007 21:59:47 +0100 (CET) Subject: [KSS-checkins] r39144 - kukit/kss.demo/trunk/kss/demo/tests/selenium_tests Message-ID: <20070217205947.920D9101BC@code0.codespeak.net> Author: jvloothuis Date: Sat Feb 17 21:59:47 2007 New Revision: 39144 Modified: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/selectors.html kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_selectors.py Log: Removed plone from the url Modified: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/selectors.html ============================================================================== --- kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/selectors.html (original) +++ kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/selectors.html Sat Feb 17 21:59:47 2007 @@ -10,7 +10,7 @@ open - /plone/demo/selectors.html + /demo/selectors.html Modified: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_selectors.py ============================================================================== --- kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_selectors.py (original) +++ kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_selectors.py Sat Feb 17 21:59:47 2007 @@ -8,7 +8,7 @@ def test_seltest_selectors(self): sel = self.selenium - sel.open("/plone/demo/selectors.html") + sel.open("/demo/selectors.html") sel.click("parentnodenotok") time.sleep(1) self.assertEqual("Target Click me!", sel.get_text("target")) From jvloothuis at codespeak.net Sun Feb 18 01:10:50 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Sun, 18 Feb 2007 01:10:50 +0100 (CET) Subject: [KSS-checkins] r39148 - kukit/kss.demo/trunk/kss/demo/tests/selenium_tests Message-ID: <20070218001050.4B546101CC@code0.codespeak.net> Author: jvloothuis Date: Sun Feb 18 01:10:48 2007 New Revision: 39148 Added: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/createpythontests.py (contents, props changed) Log: Added a basic code generation script for creating the python test files from the selenium html Added: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/createpythontests.py ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/createpythontests.py Sun Feb 18 01:10:48 2007 @@ -0,0 +1,48 @@ +#!/usr/bin/env python + +# Generate selenium test controller files from HTML selenium tests + +from elementtree import HTMLTreeBuilder, ElementTree +import glob +from string import Template +import os + +template = Template(''' +from seleniumtestcase import SeleniumTestCase +import unittest, time + +class seltest_$testname(SeleniumTestCase): + + def test_seltest_$testname(self): + $testbody + +def test_suite(): + return unittest.makeSuite($testname) + +if __name__ == "__main__": + unittest.main() +''') + +def formatcommand(command, *args): + arguments = ['"%s"' % arg for arg in args if arg] + return 'self.%s(%s)' % (command, ', '.join(arguments)) + +htmlparser = HTMLTreeBuilder.TreeBuilder() +for filename in glob.glob('*.html'): + tree = HTMLTreeBuilder.parse(filename) + root = tree.getroot() + + try: + testname = root.find('.//title').text + except AttributeError: + continue + commands = [] + for row in root.findall('.//tbody/tr'): + commands.append(formatcommand(*[td.text for td in row.findall('td')])) + + testfilename = 'seltest_%s.py' % testname + f = open(testfilename, 'wb') + f.write(template.substitute(dict( + testname=testname, + testbody='\n '.join(commands)))) + f.close() From jvloothuis at codespeak.net Sun Feb 18 09:53:16 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Sun, 18 Feb 2007 09:53:16 +0100 (CET) Subject: [KSS-checkins] r39149 - kukit/kss.core/trunk/kss/core/plugins/core Message-ID: <20070218085316.79C72101C8@code0.codespeak.net> Author: jvloothuis Date: Sun Feb 18 09:53:15 2007 New Revision: 39149 Modified: kukit/kss.core/trunk/kss/core/plugins/core/commands.py kukit/kss.core/trunk/kss/core/plugins/core/configure.zcml kukit/kss.core/trunk/kss/core/plugins/core/interfaces.py Log: Added a new command to the core plugin set which can toggle a css class Modified: kukit/kss.core/trunk/kss/core/plugins/core/commands.py ============================================================================== --- kukit/kss.core/trunk/kss/core/plugins/core/commands.py (original) +++ kukit/kss.core/trunk/kss/core/plugins/core/commands.py Sun Feb 18 09:53:15 2007 @@ -120,6 +120,11 @@ for key, value in kw.iteritems(): command.addParam(key, value) + def toggleClass(self, selector, classname): + """ see interfaces.py """ + command = self.commands.addCommand('toggleClass', selector) + data = command.addParam('classname', classname) + # XXX Deprecated ones def moveChildrenTo(self, selector, id): Modified: kukit/kss.core/trunk/kss/core/plugins/core/configure.zcml ============================================================================== --- kukit/kss.core/trunk/kss/core/plugins/core/configure.zcml (original) +++ kukit/kss.core/trunk/kss/core/plugins/core/configure.zcml Sun Feb 18 09:53:15 2007 @@ -240,6 +240,12 @@ /> + + Author: jvloothuis Date: Sun Feb 18 09:54:09 2007 New Revision: 39150 Added: kukit/kss.demo/trunk/kss/demo/browser/coreplugin/ kukit/kss.demo/trunk/kss/demo/browser/coreplugin/2 kukit/kss.demo/trunk/kss/demo/browser/coreplugin/__init__.py kukit/kss.demo/trunk/kss/demo/browser/coreplugin/configure.zcml kukit/kss.demo/trunk/kss/demo/browser/coreplugin/coreplugin.kss kukit/kss.demo/trunk/kss/demo/browser/coreplugin/coreplugin.pt kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/coreplugin.html kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_coreplugin.py Modified: kukit/kss.demo/trunk/kss/demo/browser/configure.zcml Log: Added tests for the new toggleClass core plugin extension Modified: kukit/kss.demo/trunk/kss/demo/browser/configure.zcml ============================================================================== --- kukit/kss.demo/trunk/kss/demo/browser/configure.zcml (original) +++ kukit/kss.demo/trunk/kss/demo/browser/configure.zcml Sun Feb 18 09:54:09 2007 @@ -5,6 +5,7 @@ + + + + + + + + + +

Selectors

+

We test the selectors which are used in KSS. The selectors allow you to + specify what node to take action on etc.

+

+ parentnode() with node in path +

+
+ Click the text link. +
+
Target + Click me! +
+
+ Clicking the text link below should not update the target. +
+
+ Click me! +
+ + + +
+
+
+ Click me! +
+
+
+ + Added: kukit/kss.demo/trunk/kss/demo/browser/coreplugin/__init__.py ============================================================================== Added: kukit/kss.demo/trunk/kss/demo/browser/coreplugin/configure.zcml ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/browser/coreplugin/configure.zcml Sun Feb 18 09:54:09 2007 @@ -0,0 +1,20 @@ + + + + + + + + + Added: kukit/kss.demo/trunk/kss/demo/browser/coreplugin/coreplugin.kss ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/browser/coreplugin/coreplugin.kss Sun Feb 18 09:54:09 2007 @@ -0,0 +1,5 @@ + +#toggleclass-button:click { + action-client: toggleClass; + toggleClass-classname: 'selected'; +} Added: kukit/kss.demo/trunk/kss/demo/browser/coreplugin/coreplugin.pt ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/browser/coreplugin/coreplugin.pt Sun Feb 18 09:54:09 2007 @@ -0,0 +1,37 @@ + + + + + + + + + +

Core plugins

+

The core plugins are tested here.

+

+ toggleClass +

+
+ Toggeling the class means adding and removing it. Click the text link + to see the button highlight. Click it again to remove the highlight. +
+
+ Click me! +
+ + Added: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/coreplugin.html ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/coreplugin.html Sun Feb 18 09:54:09 2007 @@ -0,0 +1,44 @@ + + + +coreplugin + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
coreplugin
open/demo/coreplugin.html
assertAttributetoggleclass-button at classbutton click cursorPointer
clicktoggleclass-button
assertAttributetoggleclass-button at classbutton click cursorPointer selected
clicktoggleclass-button
assertAttributetoggleclass-button at classbutton click cursorPointer
+ + Added: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_coreplugin.py ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_coreplugin.py Sun Feb 18 09:54:09 2007 @@ -0,0 +1,22 @@ +from seleniumtestcase import SeleniumTestCase +import unittest, time + +def getTestClass(): + return seltest_coreplugin + +class seltest_coreplugin(SeleniumTestCase): + + def test_seltest_coreplugin(self): + sel = self.selenium + sel.open("/demo/coreplugin.html") + self.assertEqual("button click cursorPointer", sel.get_attribute("toggleclass-button at class")) + sel.click("toggleclass-button") + self.assertEqual("button click cursorPointer selected", sel.get_attribute("toggleclass-button at class")) + sel.click("toggleclass-button") + self.assertEqual("button click cursorPointer", sel.get_attribute("toggleclass-button at class")) +def test_suite(): + return unittest.makeSuite(getTestClass()) + +if __name__ == "__main__": + unittest.main() + From jvloothuis at codespeak.net Sun Feb 18 13:55:46 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Sun, 18 Feb 2007 13:55:46 +0100 (CET) Subject: [KSS-checkins] r39152 - kukit/kss.buildout/trunk Message-ID: <20070218125546.6B6DB101D7@code0.codespeak.net> Author: jvloothuis Date: Sun Feb 18 13:55:44 2007 New Revision: 39152 Modified: kukit/kss.buildout/trunk/dotests.py kukit/kss.buildout/trunk/tests Log: Improved code of dotests by using subprocess Made the testrunner accept a different Python installation Modified: kukit/kss.buildout/trunk/dotests.py ============================================================================== --- kukit/kss.buildout/trunk/dotests.py (original) +++ kukit/kss.buildout/trunk/dotests.py Sun Feb 18 13:55:44 2007 @@ -10,7 +10,7 @@ javapid = subprocess.Popen([java, '-jar', seleniumjar]).pid #start zope -zope = os.path.join(here, 'parts', 'instance', 'bin', 'zopectl') +zope = os.path.join(here, 'bin', 'instance') subprocess.call([zope, 'start']) #wait for zope instance to come up @@ -29,17 +29,26 @@ #start tests python = sys.executable + +env = { + 'SELENIUMBROWSER': seleniumbrowser, + 'PYTHON': python, +} zope_test = os.path.join(here, 'tests') -test_command_pieces = ['SELENIUMBROWSER="%s"'% seleniumbrowser] -test_command_pieces.append(zope_test) -test_command_pieces.append('--package-path') -test_command_pieces.append(os.path.join(here, 'src', 'kss.demo', 'kss', 'demo', 'tests')) -test_command_pieces.append('kss.demo.tests --test-file-pattern=^seltest --tests-pattern=selenium_tests') -test_command = ' '.join(test_command_pieces) -print test_command -std = os.popen(test_command) -print std.read() -test_exit = std.close() +kssdemotests = os.path.join(here, 'src', 'kss.demo', 'kss', 'demo', 'tests') +command = [zope_test, '--package-path', kssdemotests, 'kss.demo.tests', + '--test-file-pattern=^seltest', '--tests-pattern=selenium_tests'] + +testrunner = subprocess.Popen(command, + env=env, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + stdin=subprocess.PIPE, + ) +testrunner.wait() +print testrunner.stdout.read() +print testrunner.stderr.read() +test_exit = testrunner.returncode #stop seleniumRC server os.kill(javapid, signal.SIGKILL) @@ -47,4 +56,5 @@ #stop zope subprocess.call([zope, 'stop']) +print "Exit code", test_exit sys.exit(test_exit) Modified: kukit/kss.buildout/trunk/tests ============================================================================== --- kukit/kss.buildout/trunk/tests (original) +++ kukit/kss.buildout/trunk/tests Sun Feb 18 13:55:44 2007 @@ -1,13 +1,11 @@ -#! /bin/sh -#SELENIUMBROWSER="*firefox /usr/lib/firefox/firefox-bin" +#!/bin/bash HERE=`pwd` -PYTHON="/usr/bin/python2.4" ZOPE_HOME="$HERE/parts/zope2" INSTANCE_HOME="$HEREUsers/parts/instance" CONFIG_FILE="$HERE/parts/instance/etc/zope.conf" SOFTWARE_HOME="$HERE/parts/zope2/lib/python" PYTHONPATH="$SOFTWARE_HOME:$HERE/kss.selenium/src/kss.core:$HERE/eggs/setuptools-0.6c5-py2.4.egg:$HERE/src/kss.demo:$PYTHONPATH" -export PYTHONPATH INSTANCE_HOME SOFTWARE_HOME SELENIUMBROWSER +export PYTHONPATH INSTANCE_HOME SOFTWARE_HOME ZOPETEST="$ZOPE_HOME/test.py" if exec "$PYTHON" "$ZOPETEST" --config-file "$CONFIG_FILE" "$@"; then From reebalazs at codespeak.net Sun Feb 18 17:11:01 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Sun, 18 Feb 2007 17:11:01 +0100 (CET) Subject: [KSS-checkins] r39162 - kukit/kukit.js/trunk/kukit Message-ID: <20070218161101.C933E1006F@code0.codespeak.net> Author: reebalazs Date: Sun Feb 18 17:11:00 2007 New Revision: 39162 Modified: kukit/kukit.js/trunk/kukit/forms.js Log: Fix kupu interfacing Modified: kukit/kukit.js/trunk/kukit/forms.js ============================================================================== --- kukit/kukit.js/trunk/kukit/forms.js (original) +++ kukit/kukit.js/trunk/kukit/forms.js Sun Feb 18 17:11:00 2007 @@ -258,6 +258,8 @@ } this.editors[hash] = editor; //kukit.logDebug('Registered '+node.name + ' hash=' + hash); + //Initialize the editor + editor.doInit(); }; kukit.fo.FieldUpdateRegistry.prototype.doUpdate = function(node) { From jvloothuis at codespeak.net Sun Feb 18 17:47:12 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Sun, 18 Feb 2007 17:47:12 +0100 (CET) Subject: [KSS-checkins] r39165 - kukit/kss.demo/trunk/kss/demo/tests/selenium_tests Message-ID: <20070218164712.E1F13101F2@code0.codespeak.net> Author: jvloothuis Date: Sun Feb 18 17:47:12 2007 New Revision: 39165 Removed: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_azax_instant_edit.py kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_basic_commands.py kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_cancel_submit.py kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_coreplugin.py kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_pf_forms.py kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_selectors.py kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_three_autopupdate.py kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_two_select_revisited.py kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_two_selects.py Modified: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/createpythontests.py kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seleniumtestcase.py Log: Removed all Python test files as they can now be generated by the createpythontests script Modified: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/createpythontests.py ============================================================================== --- kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/createpythontests.py (original) +++ kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/createpythontests.py Sun Feb 18 17:47:12 2007 @@ -6,6 +6,7 @@ import glob from string import Template import os +import re template = Template(''' from seleniumtestcase import SeleniumTestCase @@ -17,14 +18,27 @@ $testbody def test_suite(): - return unittest.makeSuite($testname) + return unittest.makeSuite(seltest_$testname) if __name__ == "__main__": unittest.main() ''') +variable_regexp = re.compile('\$\{(?P\w*)\}') + def formatcommand(command, *args): - arguments = ['"%s"' % arg for arg in args if arg] + if not command: + return '' # Change this to raise an exception? + + arguments = [] + for arg in args: + if not arg: + continue + matched = variable_regexp.match(arg) + if matched is None: + arguments.append('"%s"'%arg) + else: + arguments.append("self.getVar('%s')"%matched.group('varname')) return 'self.%s(%s)' % (command, ', '.join(arguments)) htmlparser = HTMLTreeBuilder.TreeBuilder() Modified: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seleniumtestcase.py ============================================================================== --- kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seleniumtestcase.py (original) +++ kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seleniumtestcase.py Sun Feb 18 17:47:12 2007 @@ -1,5 +1,6 @@ import os import unittest +import time from selenium import selenium try: @@ -16,8 +17,73 @@ self.verificationErrors = [] self.selenium = selenium("localhost", 4444, browser, target) self.selenium.start() + self.storedvars = {} def tearDown(self): self.selenium.stop() self.assertEqual([], self.verificationErrors) + def __getattr__(self, name): + try: + return getattr(self.__dict__['selenium'], name) + except KeyError: + return super(SeleniumTestCase, self).__getattr__(name) + + def open(self, url): + self.selenium.open(url) + + def click(self, target): + self.selenium.click(target) + + def waitForExpression(self, func, timeout=60): + for i in range(timeout): + try: + if func(): + return + except: + pass + time.sleep(1) + self.fail('time out') + + + def waitForText(self, target, text, timeout=60): + self.waitForExpression(lambda: text in self.selenium.get_text(target)) + + def waitForTextPresent(self, text, timeout=60): + self.waitForExpression(lambda: self.selenium.is_text_present(text)) + + def waitForElementPresent(self, target, timeout=60): + self.waitForExpression(lambda: self.selenium.is_element_present(target)) + + def waitForValue(self, target, value, timeout=60): + self.waitForExpression(lambda: self.selenium.get_value(target)) + + def assertText(self, target, text=''): + self.assertEqual(self.selenium.get_text(target), text) + + def assertNotText(self, target, text=''): + self.failIfEqual(self.selenium.get_text(target), text) + + def assertValue(self, target, value=''): + self.assertEqual(self.selenium.get_value(target), value) + + def assertElementPresent(self, target): + self.failUnless(self.selenium.is_element_present(target)) + + def pause(self, seconds): + time.sleep(float(seconds)/1000) + + def assertTextPresent(self, text): + self.failUnless(self.selenium.is_text_present(text)) + + def assertTextNotPresent(self, text): + self.failIf(self.selenium.is_text_present(text)) + + def assertAttribute(self, target, value): + self.assertEqual(self.selenium.get_attribute(target), value) + + def storeText(self, target, varname): + self.storedvars[varname] = self.selenium.get_text(target) + + def getVar(self, varname): + return self.storedvars[varname] Deleted: /kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_azax_instant_edit.py ============================================================================== --- /kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_azax_instant_edit.py Sun Feb 18 17:47:12 2007 +++ (empty file) @@ -1,37 +0,0 @@ -from seleniumtestcase import SeleniumTestCase -import unittest, time - -def getTestClass(): - return seltest_azax_instant_edit - -class seltest_azax_instant_edit(SeleniumTestCase): - - def test_seltest_azax_instant_edit(self): - sel = self.selenium - sel.open("/demo/azax_instant_edit.html") - self.failUnless(sel.is_text_present("click me!")) - self.assertEqual("click me!", sel.get_text("text")) - sel.click("text") - for i in range(60): - try: - if "click me!" == sel.get_value("value"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.assertEqual("click me!", sel.get_value("value")) - sel.type("value", "change") - sel.click("save") - for i in range(60): - try: - if sel.is_text_present("change"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.failUnless(sel.is_text_present("change")) - self.failIf(sel.is_text_present("click me!")) - -def test_suite(): - return unittest.makeSuite(getTestClass()) - -if __name__ == "__main__": - unittest.main() Deleted: /kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_basic_commands.py ============================================================================== --- /kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_basic_commands.py Sun Feb 18 17:47:12 2007 +++ (empty file) @@ -1,96 +0,0 @@ -from seleniumtestcase import SeleniumTestCase -import unittest, time - -def getTestClass(): - return seltest_basic_commands - -class seltest_basic_commands(SeleniumTestCase): - - def test_seltest_basic_commands(self): - sel = self.selenium - sel.open("/demo/basic_commands.html") - #test initial state - self.assertEqual("KSS", sel.get_text("demo")) - self.assertEqual("copy here", sel.get_text("copy")) - sel.click("change") - for i in range(60): - try: - if sel.is_element_present("workedagain"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.failUnless(sel.is_element_present("workedagain")) - self.assertEqual("it worked again", sel.get_text("demo")) - sel.click("clear") - for i in range(60): - try: - if not sel.is_element_present("workedagain"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.assertNotEqual("it worked again", sel.get_text("demo")) - sel.click("copyFrom") - for i in range(60): - try: - if "copy here" != sel.get_text("copy"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.assertNotEqual("copy here", sel.get_text("copy")) - self.failIf(sel.is_element_present("workedagain")) - sel.click("change") - for i in range(60): - try: - if sel.is_element_present("workedagain"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.failUnless(sel.is_element_present("workedagain")) - self.assertNotEqual("it worked again", sel.get_text("copy")) - sel.click("copyFrom") - for i in range(60): - try: - if "it worked again" == sel.get_text("copy"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.assertEqual("it worked again", sel.get_text("copy")) - sel.click("clear") - for i in range(60): - try: - if "it worked again" != sel.get_text("demo"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.assertNotEqual("it worked again", sel.get_text("demo")) - sel.click("copyTo") - for i in range(60): - try: - if "it worked again" == sel.get_text("demo"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.assertEqual("it worked again", sel.get_text("demo")) - sel.click("clear") - for i in range(60): - try: - if "it worked again" != sel.get_text("demo"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.assertNotEqual("it worked again", sel.get_text("demo")) - sel.click("moveTo") - for i in range(60): - try: - if "it worked again" == sel.get_text("demo"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.assertEqual("it worked again", sel.get_text("demo")) - self.assertNotEqual("it worked again", sel.get_text("copy")) - -def test_suite(): - return unittest.makeSuite(getTestClass()) - -if __name__ == "__main__": - unittest.main() Deleted: /kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_cancel_submit.py ============================================================================== --- /kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_cancel_submit.py Sun Feb 18 17:47:12 2007 +++ (empty file) @@ -1,27 +0,0 @@ -from seleniumtestcase import SeleniumTestCase -import unittest, time - -def getTestClass(): - return seltest_cancel_submit - -class seltest_cancel_submit(SeleniumTestCase): - - def test_seltest_cancel_submit(self): - sel = self.selenium - sel.open("/demo/cancel_submit.html") - self.assertEqual("", sel.get_value("text_save")) - sel.type("text_save", "abc") - sel.click("submit") - for i in range(60): - try: - if "Async saved abc" == sel.get_text("async"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.assertEqual("Async saved abc", sel.get_text("async")) - -def test_suite(): - return unittest.makeSuite(getTestClass()) - -if __name__ == "__main__": - unittest.main() Deleted: /kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_coreplugin.py ============================================================================== --- /kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_coreplugin.py Sun Feb 18 17:47:12 2007 +++ (empty file) @@ -1,22 +0,0 @@ -from seleniumtestcase import SeleniumTestCase -import unittest, time - -def getTestClass(): - return seltest_coreplugin - -class seltest_coreplugin(SeleniumTestCase): - - def test_seltest_coreplugin(self): - sel = self.selenium - sel.open("/demo/coreplugin.html") - self.assertEqual("button click cursorPointer", sel.get_attribute("toggleclass-button at class")) - sel.click("toggleclass-button") - self.assertEqual("button click cursorPointer selected", sel.get_attribute("toggleclass-button at class")) - sel.click("toggleclass-button") - self.assertEqual("button click cursorPointer", sel.get_attribute("toggleclass-button at class")) -def test_suite(): - return unittest.makeSuite(getTestClass()) - -if __name__ == "__main__": - unittest.main() - Deleted: /kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_pf_forms.py ============================================================================== --- /kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_pf_forms.py Sun Feb 18 17:47:12 2007 +++ (empty file) @@ -1,67 +0,0 @@ -from seleniumtestcase import SeleniumTestCase -import unittest, time - -def getTestClass(): - return seltest_pf_forms - -class seltest_pf_forms(SeleniumTestCase): - - def test_seltest_pf_forms(self): - sel = self.selenium - sel.open("/demo/pf_forms.html") - self.failUnless(sel.is_element_present("target")) - self.assertEqual("Target", sel.get_text("target")) - sel.click("text") - for i in range(60): - try: - if "text" == sel.get_text("target"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.assertEqual("text", sel.get_text("target")) - sel.click("text-by-name") - for i in range(60): - try: - if "text-by-name" == sel.get_text("target"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.assertEqual("text-by-name", sel.get_text("target")) - sel.click("textarea") - for i in range(60): - try: - if "textarea" == sel.get_text("target"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.assertEqual("textarea", sel.get_text("target")) - sel.click("textarea-by-name") - for i in range(60): - try: - if "textarea-by-name" == sel.get_text("target"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.assertEqual("textarea-by-name", sel.get_text("target")) - sel.click("radio1") - for i in range(60): - try: - if "radio-1" == sel.get_text("target"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.assertEqual("radio-1", sel.get_text("target")) - sel.click("radio-by-name") - for i in range(60): - try: - if "radio-2" == sel.get_text("target"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.assertEqual("radio-2", sel.get_text("target")) - -def test_suite(): - return unittest.makeSuite(getTestClass()) - -if __name__ == "__main__": - unittest.main() Deleted: /kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_selectors.py ============================================================================== --- /kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_selectors.py Sun Feb 18 17:47:12 2007 +++ (empty file) @@ -1,38 +0,0 @@ -from seleniumtestcase import SeleniumTestCase -import unittest, time - -def getTestClass(): - return seltest_selectors - -class seltest_selectors(SeleniumTestCase): - - def test_seltest_selectors(self): - sel = self.selenium - sel.open("/demo/selectors.html") - sel.click("parentnodenotok") - time.sleep(1) - self.assertEqual("Target Click me!", sel.get_text("target")) - sel.click("parentnodeok") - for i in range(60): - try: - if "ok" == sel.get_text("target"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.assertEqual("ok", sel.get_text("target")) - sel.click("parentnodechain") - for i in range(60): - try: - if "selected" == sel.get_text("css=#nesteddivs0 div.inserted"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.assertEqual("selected", sel.get_text("css=#nesteddivs1 div.inserted")) - self.assertEqual("selected", sel.get_text("css=#nesteddivs0 div.inserted")) - self.assertEqual("selected", sel.get_text("css=#nesteddivs2 div.inserted")) -def test_suite(): - return unittest.makeSuite(getTestClass()) - -if __name__ == "__main__": - unittest.main() - Deleted: /kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_three_autopupdate.py ============================================================================== --- /kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_three_autopupdate.py Sun Feb 18 17:47:12 2007 +++ (empty file) @@ -1,32 +0,0 @@ -from seleniumtestcase import SeleniumTestCase -import unittest, time - -def getTestClass(): - return seltest_three_autopupdate - -class seltest_three_autopupdate(SeleniumTestCase): - - def test_seltest_three_autopupdate(self): - sel = self.selenium - sel.open("/demo/three_autoupdate.html") - self.assertEqual("", sel.get_text("update-wrapper")) - sel.click("start-update") - for i in range(60): - try: - if sel.is_element_present("update-area"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.failUnless(sel.is_element_present("update-area")) - self.assertEqual("", sel.get_text("update-area")) - updateText = sel.get_text("update-area") - self.assertEqual(updateText, sel.get_text("update-area")) - time.sleep(3) - self.assertNotEqual(updateText, sel.get_text("update-area")) - # sel.() - -def test_suite(): - return unittest.makeSuite(getTestClass()) - -if __name__ == "__main__": - unittest.main() Deleted: /kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_two_select_revisited.py ============================================================================== --- /kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_two_select_revisited.py Sun Feb 18 17:47:12 2007 +++ (empty file) @@ -1,71 +0,0 @@ -from seleniumtestcase import SeleniumTestCase -import unittest, time - -def getTestClass(): - return seltest_two_select_revisited - -class seltest_two_select_revisited(SeleniumTestCase): - - def test_seltest_two_select_revisited(self): - sel = self.selenium - sel.open("/demo/two_select_revisited.html") - self.assertEqual("animals machines", sel.get_text("first-master")) - self.assertEqual("", sel.get_text("first-slave")) - sel.select("first-master", "label=animals") - for i in range(60): - try: - if "dog cat cow" == sel.get_text("first-slave"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.assertEqual("dog cat cow", sel.get_text("first-slave")) - sel.select("first-master", "label=machines") - for i in range(60): - try: - if "computer car airplane" == sel.get_text("first-slave"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.assertEqual("computer car airplane", sel.get_text("first-slave")) - self.assertEqual("animals machines", sel.get_text("second-master")) - self.assertEqual("", sel.get_text("second-slave")) - sel.select("second-master", "label=animals") - for i in range(60): - try: - if "dog cat cow" == sel.get_text("second-slave"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.assertEqual("dog cat cow", sel.get_text("second-slave")) - sel.select("second-master", "label=machines") - for i in range(60): - try: - if "computer car airplane" == sel.get_text("second-slave"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.assertEqual("computer car airplane", sel.get_text("second-slave")) - self.assertEqual("animals machines", sel.get_text("third-master")) - self.assertEqual("", sel.get_text("third-slave")) - sel.select("third-master", "label=animals") - for i in range(60): - try: - if "dog cat cow" == sel.get_text("third-slave"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.assertEqual("dog cat cow", sel.get_text("third-slave")) - sel.select("third-master", "label=machines") - for i in range(60): - try: - if "computer car airplane" == sel.get_text("third-slave"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.assertEqual("computer car airplane", sel.get_text("third-slave")) - -def test_suite(): - return unittest.makeSuite(getTestClass()) - -if __name__ == "__main__": - unittest.main() Deleted: /kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_two_selects.py ============================================================================== --- /kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seltest_two_selects.py Sun Feb 18 17:47:12 2007 +++ (empty file) @@ -1,35 +0,0 @@ -from seleniumtestcase import SeleniumTestCase -import unittest, time - -def getTestClass(): - return seltest_two_selects - -class seltest_two_selects(SeleniumTestCase): - - def test_seltest_two_selects(self): - sel = self.selenium - sel.open("/demo/two_selects.html") - self.assertEqual("animals machines", sel.get_text("first")) - self.assertEqual("", sel.get_text("second")) - sel.select("first", "label=animals") - for i in range(60): - try: - if "dog cat cow" == sel.get_text("second"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.assertEqual("dog cat cow", sel.get_text("second")) - sel.select("first", "label=machines") - for i in range(60): - try: - if "computer car airplane" == sel.get_text("second"): break - except: pass - time.sleep(1) - else: self.fail("time out") - self.assertEqual("computer car airplane", sel.get_text("second")) - -def test_suite(): - return unittest.makeSuite(getTestClass()) - -if __name__ == "__main__": - unittest.main() From gotcha at codespeak.net Sun Feb 18 19:14:26 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Sun, 18 Feb 2007 19:14:26 +0100 (CET) Subject: [KSS-checkins] r39169 - kukit/kss.buildout/trunk Message-ID: <20070218181426.0F811101F8@code0.codespeak.net> Author: gotcha Date: Sun Feb 18 19:14:25 2007 New Revision: 39169 Modified: kukit/kss.buildout/trunk/dotests_win.py Log: almost there; thanks to Hanno Modified: kukit/kss.buildout/trunk/dotests_win.py ============================================================================== --- kukit/kss.buildout/trunk/dotests_win.py (original) +++ kukit/kss.buildout/trunk/dotests_win.py Sun Feb 18 19:14:25 2007 @@ -1,56 +1,110 @@ import os, signal, sys -import subprocess - -java = sys.argv[1] -seleniumbrowser = sys.argv[2] -here = os.getcwd() - -#start seleniumRC server -seleniumjar = os.path.join('parts', 'seleniumrc', 'selenium-server.jar') -javapid = os.spawnl(os.P_NOWAIT, java, 'java', '-jar', seleniumjar ) - -#start zope -# should use runzope.bat -zope = os.path.join(here, 'parts', 'instance', 'bin', 'zopectl') -batfile = open('script.bat', 'w') -batfile.write(" ".join([zope, 'start'])) -batfile.close() -subprocess.call('script.bat') - -#wait for zope instance to come up from time import sleep -testcmd = "wget -O- http://localhost:8080" -while subprocess.call(testcmd.split()): - sleep(1) - -#setup simple content instance -testcmd = "wget -O- http://localhost:8080/demo" -exitcode = subprocess.call(testcmd.split()) -if exitcode <> 0: - print "add" - setupcmd = """wget -O- --http-user=admin --http-password=admin --post-data add_input_name=demo&UPDATE_SUBMIT=Add http://localhost:8080/+/AddSimpleContent.html""" - exitcode = subprocess.call(setupcmd.split()) - -#start tests -python = sys.executable -zope_test = os.path.join(here, 'tests') -environ = {} -environ['SELENIUMBROWSER'] = seleniumbrowser -test_command_pieces = [zope_test] -test_command_pieces.append('--package-path') -test_command_pieces.append(os.path.join(here, 'src', 'kss.demo', 'kss', 'demo', 'tests')) -test_command_pieces.append('kss.demo.tests --test-file-pattern=^seltest --tests-pattern=selenium_tests') -test_command = ' '.join(test_command_pieces) -print test_command -std = os.popen(test_command) -print std.read() -test_exit = std.close() - -#stop seleniumRC server -#should not use os.kill -os.kill(javapid, signal.SIGKILL) +from win32process import CreateProcess +from win32process import GetExitCodeProcess +from win32process import TerminateProcess +from win32process import STARTUPINFO +from win32con import CREATE_NO_WINDOW +from win32con import CREATE_NEW_PROCESS_GROUP +from win32con import DETACHED_PROCESS +import subprocess + +def startProcess(app, commandline): + print commandline + print + process, thread, processid, threadid = CreateProcess(app, commandline, + None, None, True, + CREATE_NO_WINDOW+DETACHED_PROCESS, + None, None, STARTUPINFO()) + return process + +def getExitCode(process): + while True: + sleep(1) + exit = GetExitCodeProcess(process) + if exit <> 259: + return exit +def main(): + runner = Runner() + sys.exit(runner.process()) + +class Runner: + def __init__(self): + self.java = sys.argv[1] + self.seleniumbrowser = sys.argv[2] + self.here = os.getcwd() + self.wget = "c:\\cygwin\\bin\\wget.exe" + self.cmd = "cmd.exe" + self.zope = os.path.join(self.here, 'bin', 'instance.exe') + + def process(self): + self.startSeleniumRC() + self.startZope() + self.waitForZope() + self.setupKSSDemoInstance() + testExit = self.runTests() + self.stopZope() + self.stopSeleniumRC() + return testExit + + def startSeleniumRC(self): + seleniumjar = os.path.join('parts', 'seleniumrc', 'selenium-server.jar') + command = " ".join([self.java, '-jar', seleniumjar]) + self.javaprocess = startProcess(self.java, command) + + def startZope(self): + command = " ".join([self.zope, 'fg']) + process = startProcess(self.zope, command) + + def waitForZope(self): + command = " ".join([self.wget, "-O-", "http://localhost:8080"]) + exitcode = 1 + count = 0 + while exitcode or count > 60: + count +=1 + exitcode = subprocess.call(command) + sleep(1) + if exitcode == 0: + print "Zope started" + + def setupKSSDemoInstance(self): + command = " ".join([self.wget, "-O-", "http://localhost:8080/demo"]) + exitcode = subprocess.call(command) + if exitcode == 0: + print "demo exists" + if exitcode <> 0: + print "setup demo" + command = " ".join([self.wget, "-O-", + "--http-user=admin", "--http-password=admin", + "--post-data", "add_input_name=demo&UPDATE_SUBMIT=Add", + "http://localhost:8080/+/AddSimpleContent.html"]) + exitcode = subprocess.call(command) + if exitcode == 0: + print "demo instantiated" + + def stopZope(self): + command = " ".join([self.wget, "-O-", + "--http-user=admin", "--http-password=admin", + "http://localhost:8080/Control_Panel/manage_shutdown"]) + exitcode = subprocess.call(command) + if exitcode == 0: + print "zope shutting down" + + + def runTests(self): + environ = os.environ + environ['SELENIUMBROWSER'] = self.seleniumbrowser + testsPath = os.path.join(self.here, 'src', 'kss.demo', 'kss', 'demo', 'tests') + zope_test = os.path.join(self.here, 'parts', 'instance', 'bin', 'test.bat') + command = " ".join([self.cmd, "/C", zope_test, "test", + '--package-path', testsPath, + 'kss.demo.tests', '--test-file-pattern=^seltest', + '--tests-pattern=selenium_tests']) + print command + exitcode = subprocess.call(command, env=environ) + return exitcode -#stop zope -subprocess.call([zope, 'stop']) + def stopSeleniumRC(self): + TerminateProcess(self.javaprocess, 0) -sys.exit(test_exit) +main() From jvloothuis at codespeak.net Sun Feb 18 19:24:15 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Sun, 18 Feb 2007 19:24:15 +0100 (CET) Subject: [KSS-checkins] r39172 - kukit/kss.demo/trunk/kss/demo/tests/selenium_tests Message-ID: <20070218182415.9AD19101E6@code0.codespeak.net> Author: jvloothuis Date: Sun Feb 18 19:24:14 2007 New Revision: 39172 Modified: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/createpythontests.py Log: Changed the test generation so it creates one test class for a set of html files Modified: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/createpythontests.py ============================================================================== --- kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/createpythontests.py (original) +++ kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/createpythontests.py Sun Feb 18 19:24:14 2007 @@ -14,8 +14,7 @@ class seltest_$testname(SeleniumTestCase): - def test_seltest_$testname(self): - $testbody +$tests def test_suite(): return unittest.makeSuite(seltest_$testname) @@ -42,6 +41,7 @@ return 'self.%s(%s)' % (command, ', '.join(arguments)) htmlparser = HTMLTreeBuilder.TreeBuilder() +tests = [] for filename in glob.glob('*.html'): tree = HTMLTreeBuilder.parse(filename) root = tree.getroot() @@ -55,8 +55,12 @@ commands.append(formatcommand(*[td.text for td in row.findall('td')])) testfilename = 'seltest_%s.py' % testname - f = open(testfilename, 'wb') - f.write(template.substitute(dict( - testname=testname, - testbody='\n '.join(commands)))) - f.close() + testbody=' def test_%s(self):\n'%testname+' '*8+'\n '.join(commands)+'\n' + tests.append(testbody) + +f = open('seltest_all.py', 'wb') +f.write(template.substitute(dict( + testname=testname, + tests='\n'.join(tests), + ))) +f.close() From reebalazs at codespeak.net Sun Feb 18 20:30:35 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Sun, 18 Feb 2007 20:30:35 +0100 (CET) Subject: [KSS-checkins] r39183 - kukit/kukit.js/trunk/kukit Message-ID: <20070218193035.A63F41020F@code0.codespeak.net> Author: reebalazs Date: Sun Feb 18 20:30:33 2007 New Revision: 39183 Modified: kukit/kukit.js/trunk/kukit/plugin.js Log: Handle preventdefaut better. If there is a javascript error during executing the actions in an event, we want preventdefault _any way_ : as a result we can see an error and we do not jump away from the page. Modified: kukit/kukit.js/trunk/kukit/plugin.js ============================================================================== --- kukit/kukit.js/trunk/kukit/plugin.js (original) +++ kukit/kukit.js/trunk/kukit/plugin.js Sun Feb 18 20:30:33 2007 @@ -101,14 +101,25 @@ target = kukit.pl.getTargetForBrowserEvent(e); if (allowbubbling || target == node) { // Execute the action, provide browserevent on oper - func_to_bind({'browserevent': e}); + // ... however, do it protected. We want the preventdefault + // in any case! + var exc; + try { + func_to_bind({'browserevent': e}); + } catch(exc1) { + exc = exc1; + } // Cancel default event ? if (preventdefault) { // W3C style if (e.preventDefault) e.preventDefault(); // MS style - try { e.returnValue = false; } catch (exc) {} + try { e.returnValue = false; } catch (exc2) {} + } + if (exc != null) { + // throw the original exception + throw exc; } } else { kukit.log('Ignored bubbling event for "' + name + '" (target =' + target.tagName + '), EventRule #' + oper.eventrule.getNr() + ' mergeid ' + oper.eventrule.kss_selector.mergeid); From gotcha at codespeak.net Sun Feb 18 20:34:54 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Sun, 18 Feb 2007 20:34:54 +0100 (CET) Subject: [KSS-checkins] r39184 - kukit/kss.buildout/trunk Message-ID: <20070218193454.35DEC10209@code0.codespeak.net> Author: gotcha Date: Sun Feb 18 20:34:52 2007 New Revision: 39184 Modified: kukit/kss.buildout/trunk/dotests.py Log: add generation of python tests from selenium html Modified: kukit/kss.buildout/trunk/dotests.py ============================================================================== --- kukit/kss.buildout/trunk/dotests.py (original) +++ kukit/kss.buildout/trunk/dotests.py Sun Feb 18 20:34:52 2007 @@ -27,15 +27,23 @@ setupcmd = """wget -O- --http-user=admin --http-password=admin --post-data add_input_name=demo&UPDATE_SUBMIT=Add http://localhost:8080/+/AddSimpleContent.html""" exitcode = subprocess.call(setupcmd.split()) -#start tests +#create selenium tests +kssdemotests = os.path.join(here, 'src', 'kss.demo', 'kss', 'demo', 'tests') python = sys.executable +creationDir = os.path.join(kssdemotests, 'selenium_tests') +creationScript = os.path.join(creationDir, 'createpythontests.py') +command = " ".join([python, creationScript]) +os.chdir(creationDir) +exitcode = subprocess.call(command.split()) +print "creation exit code", exitcode +os.chdir(here) +#start tests env = { 'SELENIUMBROWSER': seleniumbrowser, 'PYTHON': python, } zope_test = os.path.join(here, 'tests') -kssdemotests = os.path.join(here, 'src', 'kss.demo', 'kss', 'demo', 'tests') command = [zope_test, '--package-path', kssdemotests, 'kss.demo.tests', '--test-file-pattern=^seltest', '--tests-pattern=selenium_tests'] From gotcha at codespeak.net Sun Feb 18 21:44:21 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Sun, 18 Feb 2007 21:44:21 +0100 (CET) Subject: [KSS-checkins] r39187 - kukit/kss.buildout/trunk Message-ID: <20070218204421.AE10B10217@code0.codespeak.net> Author: gotcha Date: Sun Feb 18 21:44:20 2007 New Revision: 39187 Modified: kukit/kss.buildout/trunk/buildout.cfg kukit/kss.buildout/trunk/dotests_win.py Log: setup elementtree egg, selenium tests creation in windows Modified: kukit/kss.buildout/trunk/buildout.cfg ============================================================================== --- kukit/kss.buildout/trunk/buildout.cfg (original) +++ kukit/kss.buildout/trunk/buildout.cfg Sun Feb 18 21:44:20 2007 @@ -1,5 +1,4 @@ [buildout] - parts = javaversion seleniumrc @@ -41,7 +40,10 @@ [ksspy] recipe = zc.recipe.egg -eggs = ${instance:eggs} +eggs = + ${instance:eggs} + elementtree + interpreter = ksspy extra-paths = ${zope2:location}/lib/python scripts = ksspy Modified: kukit/kss.buildout/trunk/dotests_win.py ============================================================================== --- kukit/kss.buildout/trunk/dotests_win.py (original) +++ kukit/kss.buildout/trunk/dotests_win.py Sun Feb 18 21:44:20 2007 @@ -36,12 +36,14 @@ self.wget = "c:\\cygwin\\bin\\wget.exe" self.cmd = "cmd.exe" self.zope = os.path.join(self.here, 'bin', 'instance.exe') + self.instancehome = os.path.join(self.here, 'parts', 'instance') def process(self): self.startSeleniumRC() self.startZope() self.waitForZope() self.setupKSSDemoInstance() + self.createSeleniumTests() testExit = self.runTests() self.stopZope() self.stopSeleniumRC() @@ -89,19 +91,36 @@ exitcode = subprocess.call(command) if exitcode == 0: print "zope shutting down" - + + def createSeleniumTests(self): + kssdemotests = os.path.join(self.here, 'src', 'kss.demo', 'kss', 'demo', 'tests') + ksspy = os.path.join(self.here, 'bin', 'ksspy') + creationDir = os.path.join(kssdemotests, 'selenium_tests') + creationScript = os.path.join(creationDir, 'createpythontests.py') + command = " ".join([ksspy, creationScript]) + os.chdir(creationDir) + exitcode = subprocess.call(command.split()) + print "creation exit code", exitcode + os.chdir(self.here) def runTests(self): environ = os.environ environ['SELENIUMBROWSER'] = self.seleniumbrowser testsPath = os.path.join(self.here, 'src', 'kss.demo', 'kss', 'demo', 'tests') zope_test = os.path.join(self.here, 'parts', 'instance', 'bin', 'test.bat') - command = " ".join([self.cmd, "/C", zope_test, "test", + command = " ".join([zope_test, "test", '--package-path', testsPath, 'kss.demo.tests', '--test-file-pattern=^seltest', '--tests-pattern=selenium_tests']) print command - exitcode = subprocess.call(command, env=environ) + dummy = subprocess.call(command, env=environ) + exitcodefile = os.path.join(self.instancehome, 'testsexitcode.err') + if '"0"' in open(exitcodefile).read(): + exitcode = 0 + else: + exitcode = 1 + + print 'tests exitcode', exitcode return exitcode def stopSeleniumRC(self): From gotcha at codespeak.net Sun Feb 18 22:33:05 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Sun, 18 Feb 2007 22:33:05 +0100 (CET) Subject: [KSS-checkins] r39188 - kukit/kss.demo/trunk/kss/demo/tests/selenium_tests Message-ID: <20070218213305.BBF5710218@code0.codespeak.net> Author: gotcha Date: Sun Feb 18 22:33:04 2007 New Revision: 39188 Modified: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/demo1.html Log: fix html test Modified: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/demo1.html ============================================================================== --- kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/demo1.html (original) +++ kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/demo1.html Sun Feb 18 22:33:04 2007 @@ -10,13 +10,13 @@ open - /demo/demo1.html + /demo/basic_commands.html assertText demo - Azax + KSS assertText From gotcha at codespeak.net Mon Feb 19 09:55:21 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Mon, 19 Feb 2007 09:55:21 +0100 (CET) Subject: [KSS-checkins] r39189 - kukit/kss.buildout/trunk Message-ID: <20070219085521.7AFE6101C3@code0.codespeak.net> Author: gotcha Date: Mon Feb 19 09:55:20 2007 New Revision: 39189 Modified: kukit/kss.buildout/trunk/buildout.cfg Log: missing executable Modified: kukit/kss.buildout/trunk/buildout.cfg ============================================================================== --- kukit/kss.buildout/trunk/buildout.cfg (original) +++ kukit/kss.buildout/trunk/buildout.cfg Mon Feb 19 09:55:20 2007 @@ -43,7 +43,7 @@ eggs = ${instance:eggs} elementtree - +executable = ksspy interpreter = ksspy extra-paths = ${zope2:location}/lib/python scripts = ksspy From gotcha at codespeak.net Mon Feb 19 10:42:29 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Mon, 19 Feb 2007 10:42:29 +0100 (CET) Subject: [KSS-checkins] r39190 - kukit/kss.buildout/trunk Message-ID: <20070219094229.6B70810210@code0.codespeak.net> Author: gotcha Date: Mon Feb 19 10:42:27 2007 New Revision: 39190 Modified: kukit/kss.buildout/trunk/buildout.cfg Log: revert unneeded 'fix' Modified: kukit/kss.buildout/trunk/buildout.cfg ============================================================================== --- kukit/kss.buildout/trunk/buildout.cfg (original) +++ kukit/kss.buildout/trunk/buildout.cfg Mon Feb 19 10:42:27 2007 @@ -43,7 +43,6 @@ eggs = ${instance:eggs} elementtree -executable = ksspy interpreter = ksspy extra-paths = ${zope2:location}/lib/python scripts = ksspy From gotcha at codespeak.net Mon Feb 19 10:56:23 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Mon, 19 Feb 2007 10:56:23 +0100 (CET) Subject: [KSS-checkins] r39191 - kukit/kss.demo/trunk/kss/demo/tests/selenium_tests Message-ID: <20070219095623.3E81210210@code0.codespeak.net> Author: gotcha Date: Mon Feb 19 10:56:21 2007 New Revision: 39191 Modified: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seleniumtestcase.py Log: missing methods from api Modified: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seleniumtestcase.py ============================================================================== --- kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seleniumtestcase.py (original) +++ kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seleniumtestcase.py Mon Feb 19 10:56:21 2007 @@ -49,9 +49,15 @@ def waitForText(self, target, text, timeout=60): self.waitForExpression(lambda: text in self.selenium.get_text(target)) + def waitForNotText(self, target, text, timeout=60): + self.waitForExpression(lambda: not text in self.selenium.get_text(target)) + def waitForTextPresent(self, text, timeout=60): self.waitForExpression(lambda: self.selenium.is_text_present(text)) + def waitForElementNotPresent(self, target, timeout=60): + self.waitForExpression(lambda: not self.selenium.is_element_present(target)) + def waitForElementPresent(self, target, timeout=60): self.waitForExpression(lambda: self.selenium.is_element_present(target)) From gotcha at codespeak.net Mon Feb 19 11:16:18 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Mon, 19 Feb 2007 11:16:18 +0100 (CET) Subject: [KSS-checkins] r39192 - kukit/kss.demo/trunk/kss/demo/tests/selenium_tests Message-ID: <20070219101618.6BA2A1020C@code0.codespeak.net> Author: gotcha Date: Mon Feb 19 11:16:16 2007 New Revision: 39192 Modified: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seleniumtestcase.py Log: missing selenium api Modified: kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seleniumtestcase.py ============================================================================== --- kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seleniumtestcase.py (original) +++ kukit/kss.demo/trunk/kss/demo/tests/selenium_tests/seleniumtestcase.py Mon Feb 19 11:16:16 2007 @@ -45,7 +45,6 @@ time.sleep(1) self.fail('time out') - def waitForText(self, target, text, timeout=60): self.waitForExpression(lambda: text in self.selenium.get_text(target)) @@ -76,6 +75,9 @@ def assertElementPresent(self, target): self.failUnless(self.selenium.is_element_present(target)) + def assertElementNotPresent(self, target): + self.failIf(self.selenium.is_element_present(target)) + def pause(self, seconds): time.sleep(float(seconds)/1000) From jvloothuis at codespeak.net Mon Feb 19 11:18:13 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Mon, 19 Feb 2007 11:18:13 +0100 (CET) Subject: [KSS-checkins] r39193 - kukit/kukit.js/trunk/kukit Message-ID: <20070219101813.9DA451020C@code0.codespeak.net> Author: jvloothuis Date: Mon Feb 19 11:18:12 2007 New Revision: 39193 Modified: kukit/kukit.js/trunk/kukit/plugin.js Log: Added missing plugin implementation for toggleClass Modified: kukit/kukit.js/trunk/kukit/plugin.js ============================================================================== --- kukit/kukit.js/trunk/kukit/plugin.js (original) +++ kukit/kukit.js/trunk/kukit/plugin.js Mon Feb 19 11:18:12 2007 @@ -638,6 +638,31 @@ command.execute(oper); }); + +// Add/remove a class to/from a node +kukit.actionsGlobalRegistry.register("toggleClass", function (oper) { + oper.completeParms(['classname'], {}, 'toggleClass action'); + + var node = oper.node; + var classname = oper.parms.classname; + + var nodeclass = kukit.dom.getAttribute(node, 'class'); + var foundclassatindex = -1; + var parts = nodeclass.split(' '); + for(var i=0; i Author: reebalazs Date: Mon Feb 19 11:20:49 2007 New Revision: 39194 Modified: kukit/kukit.js/trunk/kukit/kssparser.js kukit/kukit.js/trunk/kukit/oper.js kukit/kukit.js/trunk/kukit/resourcedata.js kukit/kukit.js/trunk/kukit/selectorreg.js kukit/kukit.js/trunk/tests/test_kssparser.js Log: Add kssSelector generic action parameter Modified: kukit/kukit.js/trunk/kukit/kssparser.js ============================================================================== --- kukit/kukit.js/trunk/kukit/kssparser.js (original) +++ kukit/kukit.js/trunk/kukit/kssparser.js Mon Feb 19 11:20:49 2007 @@ -129,6 +129,12 @@ this.txt = ''; }; kukit.kssp.Block.prototype.addDeclaration = function(key, value) { + + var ppRegistries = { + '': kukit.pprovidersGlobalRegistry, + 'kssSelector': kukit.sr.pproviderSelRegistry + }; + // p.s. value is here a KssXxParm. In most cases we check and unwrap it. // the keys look like this: // @@ -272,6 +278,24 @@ // // value may be either txt or method parms, and they get stored with the wrapper. action.parms[akey] = value; + // + // Check the syntax of the value at this point. This will also set + // the paramproviders on the value (from check). + // check the syntax of the declaration + // + // Figure out which registry to use. + var registry = ppRegistries[akey]; + if (typeof(registry) == 'undefined') { + // use default pproviders + registry = ppRegistries['']; + } + // + try { + // Check also sets the parameter provider on the value. + value.check(registry); + } catch(e) { + throw new kukit.err.tk.ParsingError('Error in value: ' + e, this.src.makeMarker(this.startpos)); + } } break; } } @@ -327,22 +351,6 @@ } } this.result = []; - } - // - if (typeof this.value != 'undefined') { - // Check the syntax of the value, enables early error detection. - // use a different registry, if it's a kssXxx parameter - var registry = kukit.pprovidersGlobalRegistry; - // XXX This is lame. We should not do it this way. - // TODO change this, it should be decided from the name of the key. - if (! registry.exists(this.value.methodname)) { - registry = kukit.selectorTypesGlobalRegistry; - try { - this.value.check(kukit.pprovidersGlobalRegistry); - } catch(e) { - throw new kukit.err.tk.ParsingError('Error in value: ' + e, this.src.makeMarker(this.startpos)); - } - } }; kukit.kssp.PropValue.prototype.multiword_allowed = true; kukit.kssp.PropValue.prototype.valueClass = kukit.rd.KssMethodValue; Modified: kukit/kukit.js/trunk/kukit/oper.js ============================================================================== --- kukit/kukit.js/trunk/kukit/oper.js (original) +++ kukit/kukit.js/trunk/kukit/oper.js Mon Feb 19 11:20:49 2007 @@ -108,11 +108,46 @@ }; kukit.op.Oper.prototype.executeClientAction = function(name) { - var func = kukit.actionsGlobalRegistry.get(name); - func(this); + // Check kss action parameters + var nodes = null; + // XXX TODO this should be refactored with parms constraint checking + for (key in this.aparms) { + switch (key) { + case 'kssSelector': { + // The value already contains the results + nodes = this.aparms[key]; + } break; + default: { + throw 'No kss parameter "' + key + '" allowed in action-client. (Normal parameters cannot start with kss.)'; + } break; + } + } + // + // XXX TODO refactor this with commands execution (or the other way) + var executeActions = kukit.actionsGlobalRegistry.get(name); + if (nodes != null) { + kukit.logDebug('action Selector type selected nodes:' + nodes.length); + if (!nodes || nodes.length == 0) { + kukit.logWarning('action Selector found no nodes'); + } + for (var i=0; i < nodes.length; i++) { + this.node = nodes[i]; + //XXX error handling for wrong command name + //kukit.logDebug('action Name: ' + this.name); + executeActions(this); + } + } else { + // single node + executeActions(this); + } }; kukit.op.Oper.prototype.executeDefaultAction = function(name, optional) { + // Check kss action parameters + for (key in this.aparms) { + throw 'No kss parameter "' + key + '" allowed in action-default. (Normal parameters cannot start with kss.)'; + } + // var namespace = this.binderinstance.__event_namespace__; var methodname = kukit.eventsGlobalRegistry.get(namespace, name).defaultactionmethodname; var success = false; @@ -128,6 +163,9 @@ }; kukit.op.Oper.prototype.executeServerAction = function(name) { + for (key in this.aparms) { + throw 'No kss parameter "' + key + '" allowed in action-server. (Normal parameters cannot start with kss.)'; + } // oper will be accessible to some commands that execute in return var sa = new kukit.sa.ServerAction(name, this.parms, this); }; Modified: kukit/kukit.js/trunk/kukit/resourcedata.js ============================================================================== --- kukit/kukit.js/trunk/kukit/resourcedata.js (original) +++ kukit/kukit.js/trunk/kukit/resourcedata.js Mon Feb 19 11:20:49 2007 @@ -104,9 +104,6 @@ // For normal string parameters, this would return the string itself. // In other execution contexts (like kssSelector, for example) this can // do something else. - if (! this.pprovider) { - this.check(kukit.pprovidersGlobalRegistry); - } parms[key] = this.pprovider.eval([this.txt], node, defaultparms); }; @@ -122,15 +119,13 @@ kukit.rd.KssMethodValue.prototype.isMethod = true; kukit.rd.KssMethodValue.prototype.check = function(registry) { // Check syntax - this.pprovider = new (registry.get(this.methodname))(); + var f = registry.get(this.methodname); + this.pprovider = new f(); this.pprovider.check(this.args); }; kukit.rd.KssMethodValue.prototype.evaluate = function(parms, key, node, defaultparms) { // Evaluate into parms. - if (! this.pprovider) { - this.check(kukit.pprovidersGlobalRegistry); - } parms[key] = this.pprovider.eval(this.args, node, defaultparms); }; Modified: kukit/kukit.js/trunk/kukit/selectorreg.js ============================================================================== --- kukit/kukit.js/trunk/kukit/selectorreg.js (original) +++ kukit/kukit.js/trunk/kukit/selectorreg.js Mon Feb 19 11:20:49 2007 @@ -1,9 +1,6 @@ /* * Copyright (c) 2005-2006 -* Authors: -* Godefroid Chapelle -* Florian Schulze -* Bal?zs Re? +# 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 @@ -26,37 +23,29 @@ kukit.sr.pproviderSelRegistry = new kukit.pr.ParamProviderRegistry(); -// This will provide the default case (string) -kukit.sr.DefaultPP = function() {}; -kukit.sr.DefaultPP.prototype = { - check: function(args) { - // check does not need to be used here actually. - if (args.length != 1) { - throw 'internal error, DefaultPP needs 1 argument'; - } - }, - eval: function(args, node) { - return args[0]; - } -}; -kukit.sr.pproviderSelRegistry.register('', kukit.sr.DefaultPP); - // this will provide an arbitrary selector, and is designed to // be used with the makeAnyPP factory function. kukit.sr.AnyPP = function() {}; kukit.sr.AnyPP.prototype = { - check: kukit.sr.DefaultPP.prototype.check, + check: function(args) { + // check does not need to be used here actually. + if (args.length != 1) { + throw 'internal error, AnyPP needs 1 argument'; + } + }, eval: function(args, node) { var f = kukit.selectorTypesGlobalRegistry.get(this.selector_type); return f(args[0], node); } }; +kukit.sr.pproviderSelRegistry.register('', kukit.sr.AnyPP); kukit.sr.makeAnyPP = function(selector_type) { var pp = function () {}; - pp.prototype = kukit.sr.AnyPP.prototype; + pp.prototype.eval = kukit.sr.AnyPP.prototype.eval; + pp.prototype.check = kukit.sr.AnyPP.prototype.check; pp.prototype.selector_type = selector_type; return pp; }; Modified: kukit/kukit.js/trunk/tests/test_kssparser.js ============================================================================== --- kukit/kukit.js/trunk/tests/test_kssparser.js (original) +++ kukit/kukit.js/trunk/tests/test_kssparser.js Mon Feb 19 11:20:49 2007 @@ -639,6 +639,18 @@ +" evt-annoyClicker-annoy-preventdefault: true;\n" +" action-client: namespaced-alert;\n" +' namespaced-alert-message: "You are an idiot! Ha ha ha. (But just keep on trying...)";\n' + +'}\n' + +'#button_1:click {\n' + +'action-client: setStyle;\n' + +'setStyle-kssSelector: htmlid(button_2);\n' + +'setStyle-name: backgroundColor;\n' + +'setStyle-value: #FFa0a0;\n' + +'}\n' + +'#button_3:click {\n' + +'action-client: setStyle;\n' + +'setStyle-kssSelector: "#button_4";\n' + +'setStyle-name: backgroundColor;\n' + +'setStyle-value: #FFa0a0;\n' +"}\n"; var src = new kukit.tk.Cursor(txt); @@ -647,7 +659,7 @@ var parser = new kukit.kssp.Document(src, null, true); this.assertEquals(parser.finished, true); - this.assertEquals(parser.eventRules.length, 10); + this.assertEquals(parser.eventRules.length, 12); var rule; var action; @@ -849,6 +861,59 @@ 'message': new kukit.rd.KssTextValue( "You are an idiot! Ha ha ha. (But just keep on trying...)") }); + // rule 10 + //#button_1:click { + // action-client: setStyle; + // setStyle-kssSelector: htmlid(button_2); + // setStyle-name: backgroundColor; + // setStyle-value: #FFa0a0; + //} + + rule = parser.eventRules[10]; + this.assertDictEquals(rule.parms, {}); + this.assertEquals(rule.kss_selector.isEventSelector, true); + this.assertEquals(rule.kss_selector.css, '#button_1'); + this.assertEquals(rule.kss_selector.name, 'click'); + this.assertEquals(rule.kss_selector.namespace, null); + this.assertEquals(rule.kss_selector.id, null); + action = rule.actions.content['setStyle']; + this.assertEquals(action.type, 'C'); + this.assertEquals(action.name, 'setStyle'); + this.assertEquals(action.error, null); + // At this point the parms are before separation yet + this.assertKssParmEquals(action.parms, { + 'name': new kukit.rd.KssTextValue('backgroundColor'), + 'value': new kukit.rd.KssTextValue('#FFa0a0'), + 'kssSelector': new kukit.rd.KssMethodValue('htmlid', ['button_2']) + }); + + // rule 10 + //#button_3:click { + // action-client: setStyle; + // setStyle-kssSelector: "#button_4"; + // setStyle-name: backgroundColor; + // setStyle-value: #FFa0a0; + //}\n"; + + rule = parser.eventRules[11]; + this.assertDictEquals(rule.parms, {}); + this.assertEquals(rule.kss_selector.isEventSelector, true); + this.assertEquals(rule.kss_selector.css, '#button_3'); + this.assertEquals(rule.kss_selector.name, 'click'); + this.assertEquals(rule.kss_selector.namespace, null); + this.assertEquals(rule.kss_selector.id, null); + action = rule.actions.content['setStyle']; + this.assertEquals(action.type, 'C'); + this.assertEquals(action.name, 'setStyle'); + this.assertEquals(action.error, null); + // At this point the parms are before separation yet + this.assertKssParmEquals(action.parms, { + 'name': new kukit.rd.KssTextValue('backgroundColor'), + 'value': new kukit.rd.KssTextValue('#FFa0a0'), + 'kssSelector': new kukit.rd.KssTextValue('#button_4') + }); + + }; }; From reebalazs at codespeak.net Mon Feb 19 11:21:38 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Mon, 19 Feb 2007 11:21:38 +0100 (CET) Subject: [KSS-checkins] r39195 - in kukit/kss.demo/trunk/kss/demo/browser: . coresyntax Message-ID: <20070219102138.BF3B71020C@code0.codespeak.net> Author: reebalazs Date: Mon Feb 19 11:21:37 2007 New Revision: 39195 Added: kukit/kss.demo/trunk/kss/demo/browser/coresyntax/ kukit/kss.demo/trunk/kss/demo/browser/coresyntax/__init__.py kukit/kss.demo/trunk/kss/demo/browser/coresyntax/configure.zcml kukit/kss.demo/trunk/kss/demo/browser/coresyntax/kss_selector_param.kss kukit/kss.demo/trunk/kss/demo/browser/coresyntax/kss_selector_param.pt Modified: kukit/kss.demo/trunk/kss/demo/browser/azax_demo_index.pt kukit/kss.demo/trunk/kss/demo/browser/configure.zcml kukit/kss.demo/trunk/kss/demo/browser/demo.css Log: Adding demo for kssSelector parameter Modified: kukit/kss.demo/trunk/kss/demo/browser/azax_demo_index.pt ============================================================================== --- kukit/kss.demo/trunk/kss/demo/browser/azax_demo_index.pt (original) +++ kukit/kss.demo/trunk/kss/demo/browser/azax_demo_index.pt Mon Feb 19 11:21:37 2007 @@ -24,7 +24,10 @@ - +

Core syntax

+

Unit tests

Modified: kukit/kss.demo/trunk/kss/demo/browser/configure.zcml ============================================================================== --- kukit/kss.demo/trunk/kss/demo/browser/configure.zcml (original) +++ kukit/kss.demo/trunk/kss/demo/browser/configure.zcml Mon Feb 19 11:21:37 2007 @@ -6,6 +6,7 @@ + + + + + + + + + Added: kukit/kss.demo/trunk/kss/demo/browser/coresyntax/kss_selector_param.kss ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/browser/coresyntax/kss_selector_param.kss Mon Feb 19 11:21:37 2007 @@ -0,0 +1,32 @@ + + +.clickable:click { + evt-click-preventdefault: true; +} + + +#button_1:click { + action-client: setStyle; + setStyle-kssSelector: htmlid(button_2); + setStyle-name: backgroundColor; + setStyle-value: #FFa0a0; +} + +#button_2:click { + action-client: setStyle; + setStyle-name: backgroundColor; + setStyle-value: white; +} + +#button_3:click { + action-client: setStyle; + setStyle-kssSelector: "#button_4"; + setStyle-name: backgroundColor; + setStyle-value: #FFa0a0; +} + +#button_4:click { + action-client: setStyle; + setStyle-name: backgroundColor; + setStyle-value: white; +} Added: kukit/kss.demo/trunk/kss/demo/browser/coresyntax/kss_selector_param.pt ============================================================================== --- (empty file) +++ kukit/kss.demo/trunk/kss/demo/browser/coresyntax/kss_selector_param.pt Mon Feb 19 11:21:37 2007 @@ -0,0 +1,38 @@ + + + + + + + +

All demos

+

Start logging pane

+

View KSS resource

+ +

Kss selector parameter demo

+
+

There are two buttons. If you click on the first button, it changes the style of the + second button. Look at the link on the kss file to understand. +

+ +
+ + +
+ +
+ + +
+ + +
+ + + Modified: kukit/kss.demo/trunk/kss/demo/browser/demo.css ============================================================================== --- kukit/kss.demo/trunk/kss/demo/browser/demo.css (original) +++ kukit/kss.demo/trunk/kss/demo/browser/demo.css Mon Feb 19 11:21:37 2007 @@ -55,7 +55,8 @@ background-color: #880000; } -a.button { +a.button, +input[type="submit"] { width: auto; padding: 0.2em; border: 1px solid #FF8888; From reebalazs at codespeak.net Mon Feb 19 11:39:39 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Mon, 19 Feb 2007 11:39:39 +0100 (CET) Subject: [KSS-checkins] r39196 - in kukit/kss.demo/trunk/kss/demo/browser: . coreplugin coresyntax parameterfunction selectors Message-ID: <20070219103939.002B210213@code0.codespeak.net> Author: reebalazs Date: Mon Feb 19 11:39:37 2007 New Revision: 39196 Modified: kukit/kss.demo/trunk/kss/demo/browser/azax_demo_index.pt kukit/kss.demo/trunk/kss/demo/browser/coreplugin/coreplugin.pt kukit/kss.demo/trunk/kss/demo/browser/coresyntax/kss_selector_param.kss kukit/kss.demo/trunk/kss/demo/browser/coresyntax/kss_selector_param.pt kukit/kss.demo/trunk/kss/demo/browser/header_macros.pt kukit/kss.demo/trunk/kss/demo/browser/parameterfunction/forms.pt kukit/kss.demo/trunk/kss/demo/browser/selectors/selectors.pt Log: Beautify demos, adding css and links to the index page Modified: kukit/kss.demo/trunk/kss/demo/browser/azax_demo_index.pt ============================================================================== --- kukit/kss.demo/trunk/kss/demo/browser/azax_demo_index.pt (original) +++ kukit/kss.demo/trunk/kss/demo/browser/azax_demo_index.pt Mon Feb 19 11:39:37 2007 @@ -1,5 +1,7 @@ +

KSS demos

@@ -24,6 +26,14 @@ +

Core plugins

+ +

Selectors

+

Core syntax

  • Kss selector parameters
  • Modified: kukit/kss.demo/trunk/kss/demo/browser/coreplugin/coreplugin.pt ============================================================================== --- kukit/kss.demo/trunk/kss/demo/browser/coreplugin/coreplugin.pt (original) +++ kukit/kss.demo/trunk/kss/demo/browser/coreplugin/coreplugin.pt Mon Feb 19 11:39:37 2007 @@ -3,9 +3,6 @@ -