From reebalazs at codespeak.net Mon Oct 1 16:05:28 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Mon, 1 Oct 2007 16:05:28 +0200 (CEST) Subject: [KSS-checkins] r47074 - kukit/kukit.js/trunk/kukit Message-ID: <20071001140528.A811F80F5@code0.codespeak.net> Author: reebalazs Date: Mon Oct 1 16:05:27 2007 New Revision: 47074 Modified: kukit/kukit.js/trunk/kukit/commandprocessor.js kukit/kukit.js/trunk/kukit/dom.js Log: base2 followup: further simplify kukit payload since there is no namespace any more, we just check for tags in the global namespace (which is btw kukit) Modified: kukit/kukit.js/trunk/kukit/commandprocessor.js ============================================================================== --- kukit/kukit.js/trunk/kukit/commandprocessor.js (original) +++ kukit/kukit.js/trunk/kukit/commandprocessor.js Mon Oct 1 16:05:27 2007 @@ -64,15 +64,13 @@ if (childNode.nodeType != 1) continue; if (childNode.localName) { - // (here tolerate both cases) - if (childNode.localName.toLowerCase() != "param" - && childNode.nodeName.toLowerCase() != "kukit:param") { + if (childNode.localName.toLowerCase() != "param") { throw new Error('Bad payload, expected param'); } } else { //IE does not know DOM2 - if (childNode.nodeName.toLowerCase() != "kukit:param") { - throw new Error('Bad payload, expected kukit:param'); + if (childNode.nodeName.toLowerCase() != "param") { + throw new Error('Bad payload, expected param (IE)'); } } data = childNode.getAttribute('name'); Modified: kukit/kukit.js/trunk/kukit/dom.js ============================================================================== --- kukit/kukit.js/trunk/kukit/dom.js (original) +++ kukit/kukit.js/trunk/kukit/dom.js Mon Oct 1 16:05:27 2007 @@ -400,14 +400,10 @@ } }; -dom.getNsTags = function(dom, tagName) { - if (dom.getElementsByTagNameNS) { - tags = dom.getElementsByTagNameNS('http://www.kukit.org/commands/1.0', - tagName); - } else { - //IE does not know DOM2 - tags = dom.getElementsByTagName('kukit:' + tagName); - } +dom.getNsTags = function(dom_obj, tagName) { + // Now, all the document is in the kukit namespace, + // so we just access them by tagname. + tags = dom_obj.getElementsByTagName(tagName); return tags; }; From reebalazs at codespeak.net Mon Oct 1 16:06:40 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Mon, 1 Oct 2007 16:06:40 +0200 (CEST) Subject: [KSS-checkins] r47075 - kukit/kss.core/trunk/kss/core/browser Message-ID: <20071001140640.771B18095@code0.codespeak.net> Author: reebalazs Date: Mon Oct 1 16:06:38 2007 New Revision: 47075 Modified: kukit/kss.core/trunk/kss/core/browser/kukitresponse.pt Log: base2 followup: further simplify kukit payload All is in the same kukit namespace, no namespace quirks are needed Modified: kukit/kss.core/trunk/kss/core/browser/kukitresponse.pt ============================================================================== --- kukit/kss.core/trunk/kss/core/browser/kukitresponse.pt (original) +++ kukit/kss.core/trunk/kss/core/browser/kukitresponse.pt Mon Oct 1 16:06:38 2007 @@ -1,19 +1,19 @@ - - - + - it worked]]> - - - - + + + + From reebalazs at codespeak.net Mon Oct 1 16:35:44 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Mon, 1 Oct 2007 16:35:44 +0200 (CEST) Subject: [KSS-checkins] r47076 - in kukit/kss.core/trunk/kss/core: browser doc tests Message-ID: <20071001143544.1795780F8@code0.codespeak.net> Author: reebalazs Date: Mon Oct 1 16:35:44 2007 New Revision: 47076 Modified: kukit/kss.core/trunk/kss/core/browser/errorresponse.pt kukit/kss.core/trunk/kss/core/doc/tutorial_part2.rst kukit/kss.core/trunk/kss/core/tests/kukitresponse_test.pt kukit/kss.core/trunk/kss/core/tests/test_browserview.py kukit/kss.core/trunk/kss/core/tests/test_kssview_core.py Log: base2 followup: further simplify kukit payload / fix up tests and docs Modified: kukit/kss.core/trunk/kss/core/browser/errorresponse.pt ============================================================================== --- kukit/kss.core/trunk/kss/core/browser/errorresponse.pt (original) +++ kukit/kss.core/trunk/kss/core/browser/errorresponse.pt Mon Oct 1 16:35:44 2007 @@ -1,11 +1,11 @@ - - - - system - Exception: reason - - - + + + system + Exception: reason + + + 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 Mon Oct 1 16:35:44 2007 @@ -65,18 +65,17 @@ the source of the response : :: - - - - - + + + -

We did it!

-
-
- + 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 Modified: kukit/kss.core/trunk/kss/core/tests/kukitresponse_test.pt ============================================================================== --- kukit/kss.core/trunk/kss/core/tests/kukitresponse_test.pt (original) +++ kukit/kss.core/trunk/kss/core/tests/kukitresponse_test.pt Mon Oct 1 16:35:44 2007 @@ -1,16 +1,13 @@ - - - - - -

it worked

-
-
- - -

it worked again (test)

-
-
- - + + + + + it worked]]> + + + it worked again (test)]]> + + + Modified: kukit/kss.core/trunk/kss/core/tests/test_browserview.py ============================================================================== --- kukit/kss.core/trunk/kss/core/tests/test_browserview.py (original) +++ kukit/kss.core/trunk/kss/core/tests/test_browserview.py Mon Oct 1 16:35:44 2007 @@ -31,7 +31,7 @@ header = response.getHeader('x-ksscommands') self.assert_('the_&lt;&gt;message' in header) # no < > in the message self.assert_('\n' not in header) # no /n in the payload: would destroy the page - self.assertEqual(header, ' \t \t\tsystem \t\tTheError: the_&lt;&gt;message \t ') + self.assertEqual(header, ' \t \t\tsystem \t\tTheError: the_&lt;&gt;message \t ') def test_suite(): suites = [] Modified: kukit/kss.core/trunk/kss/core/tests/test_kssview_core.py ============================================================================== --- kukit/kss.core/trunk/kss/core/tests/test_kssview_core.py (original) +++ kukit/kss.core/trunk/kss/core/tests/test_kssview_core.py Mon Oct 1 16:35:44 2007 @@ -100,12 +100,12 @@ def _wrapped_commands(self, inline): header = textwrap.dedent(u'''\ - - + + ''') footer = textwrap.dedent('''\ - - + + ''') return header + inline + footer @@ -126,11 +126,11 @@ view.getCommandSet('core').replaceInnerHTML('div.class', 'new content') result = view.render() awaited = u'''\ - - - True - + + + True + ''' self.assertCommandsEqual(result, awaited) @@ -140,11 +140,11 @@ cs.replaceInnerHTML('div.class', 'new content') result = view.render() awaited = u'''\ - - - True - + + + True + ''' self.assertCommandsEqual(result, awaited) From kukit-checkins at codespeak.net Mon Oct 1 20:25:52 2007 From: kukit-checkins at codespeak.net (VIAGRA ® Official Site) Date: Mon, 1 Oct 2007 20:25:52 +0200 (CEST) Subject: [KSS-checkins] October 73% OFF Message-ID: <20071001092732.4984.qmail@host175-2-dynamic.8-87-r.retail.telecomitalia.it> An HTML attachment was scrubbed... URL: http://codespeak.net/pipermail/kukit-checkins/attachments/20071001/132f2c54/attachment.htm From kukit-checkins at codespeak.net Mon Oct 1 23:07:38 2007 From: kukit-checkins at codespeak.net (Viagra.com Inc) Date: Mon, 1 Oct 2007 23:07:38 +0200 (CEST) Subject: [KSS-checkins] October 79% OFF Message-ID: <20071001100923.3527.qmail@host81-129-153-59.range81-129.btcentralplus.com> An HTML attachment was scrubbed... URL: http://codespeak.net/pipermail/kukit-checkins/attachments/20071001/d03a4b26/attachment.htm From gotcha at codespeak.net Tue Oct 2 11:14:53 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Tue, 2 Oct 2007 11:14:53 +0200 (CEST) Subject: [KSS-checkins] r47088 - kukit/kukit.js/trunk/kukit Message-ID: <20071002091453.212A88143@code0.codespeak.net> Author: gotcha Date: Tue Oct 2 11:14:52 2007 New Revision: 47088 Modified: kukit/kukit.js/trunk/kukit/kukit.js Log: explicit error when type='text/kss' is missing Modified: kukit/kukit.js/trunk/kukit/kukit.js ============================================================================== --- kukit/kukit.js/trunk/kukit/kukit.js (original) +++ kukit/kukit.js/trunk/kukit/kukit.js Tue Oct 2 11:14:52 2007 @@ -91,6 +91,8 @@ // Resource syntax is decided on type attribute. if((nodes[i].type == 'text/css') || (nodes[i].type == 'text/kss')) { res_type = 'kss'; +;;; } else { +;;; throw kukit.err.explicitError("rel type is not text/css or text/kss"); } var newRuleLink = new kukit.RuleSheetLink(nodes[i].href, res_type); results[results.length] = newRuleLink; From gotcha at codespeak.net Tue Oct 2 14:08:53 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Tue, 2 Oct 2007 14:08:53 +0200 (CEST) Subject: [KSS-checkins] r47098 - in kukit/kss.core/trunk/kss/core: . browser Message-ID: <20071002120853.19B998125@code0.codespeak.net> Author: gotcha Date: Tue Oct 2 14:08:51 2007 New Revision: 47098 Added: kukit/kss.core/trunk/kss/core/browser/kss_javascript.pt Modified: kukit/kss.core/trunk/kss/core/configure.zcml Log: add a view that includes js simply for grok Added: kukit/kss.core/trunk/kss/core/browser/kss_javascript.pt ============================================================================== --- (empty file) +++ kukit/kss.core/trunk/kss/core/browser/kss_javascript.pt Tue Oct 2 14:08:51 2007 @@ -0,0 +1,7 @@ + + + + Modified: kukit/kss.core/trunk/kss/core/configure.zcml ============================================================================== --- kukit/kss.core/trunk/kss/core/configure.zcml (original) +++ kukit/kss.core/trunk/kss/core/configure.zcml Tue Oct 2 14:08:51 2007 @@ -66,5 +66,12 @@ class=".browserview.KSSBrowserView" allowed_attributes="attach_error" /> + + From gotcha at codespeak.net Tue Oct 2 14:18:18 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Tue, 2 Oct 2007 14:18:18 +0200 (CEST) Subject: [KSS-checkins] r47099 - kukit/kss.core/trunk/kss/core/browser Message-ID: <20071002121818.C81D2812B@code0.codespeak.net> Author: gotcha Date: Tue Oct 2 14:18:17 2007 New Revision: 47099 Modified: kukit/kss.core/trunk/kss/core/browser/kss_javascript.pt Log: add detection of devel mode Modified: kukit/kss.core/trunk/kss/core/browser/kss_javascript.pt ============================================================================== --- kukit/kss.core/trunk/kss/core/browser/kss_javascript.pt (original) +++ kukit/kss.core/trunk/kss/core/browser/kss_javascript.pt Tue Oct 2 14:18:17 2007 @@ -1,7 +1,20 @@ - - - + + + + + + + + + From gotcha at codespeak.net Tue Oct 2 14:19:15 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Tue, 2 Oct 2007 14:19:15 +0200 (CEST) Subject: [KSS-checkins] r47100 - kukit/kukit.js/trunk/kukit Message-ID: <20071002121915.0B6A58143@code0.codespeak.net> Author: gotcha Date: Tue Oct 2 14:19:15 2007 New Revision: 47100 Modified: kukit/kukit.js/trunk/kukit/kukit.js kukit/kukit.js/trunk/kukit/resourcedata.js Log: improve logging Modified: kukit/kukit.js/trunk/kukit/kukit.js ============================================================================== --- kukit/kukit.js/trunk/kukit/kukit.js (original) +++ kukit/kukit.js/trunk/kukit/kukit.js Tue Oct 2 14:19:15 2007 @@ -211,16 +211,18 @@ phase = 2; } this.binderInfoRegistry.startBindingPhase(); +;;; kukit.log('Selection of HTML nodes starts.'); var rules = this.getRules(); var ruletable = new kukit.rd.RuleTable(this.loadScheduler); for (var y=0; y < rules.length; y++) { rules[y].mergeForSelectedNodes(ruletable, phase, inNodes); } - // bind special selectors first +;;; kukit.log('Binding of document starts.'); if (phase == 1) { this.documentRules.bindall(phase); } // finally bind the merged events +;;; kukit.log('Binding of HTML nodes starts.'); ruletable.bindall(phase); // ... and do the actual binding. @@ -236,14 +238,14 @@ ;;; kukit.log('[initializeRules] is called twice.'); return; } -;;; kukit.log('Initializing rule sheets.'); +;;; kukit.log('Initializing kinetic stylesheets.'); // Succesful initialization. At the moment the engine is kept // as a global variable, but this needs refinement in the future. kukit.engine = this; window.kukitRulesInitializing = true; // load the rulesheets var rulelinks = this.getRuleSheetLinks(); -;;; kukit.log("Count of KSS links: " + rulelinks.length); +;;; kukit.log("Count of kinetic stylesheet links: " + rulelinks.length); for (var i=0; i Author: reebalazs Date: Thu Oct 4 18:11:49 2007 New Revision: 47150 Modified: kukit/kukit.js/trunk/doc/HISTORY.txt kukit/kukit.js/trunk/kukit/kssparser.js kukit/kukit.js/trunk/kukit/resourcedata.js kukit/kukit.js/trunk/tests/test_kssparser.js Log: Merge from ree-binding-improvements branch: Implement event binding based on the ids fetched dynamically from the dom, by value providers. The merge is partial, and complex because the branches has diverged too much. Modified: kukit/kukit.js/trunk/doc/HISTORY.txt ============================================================================== --- kukit/kukit.js/trunk/doc/HISTORY.txt (original) +++ kukit/kukit.js/trunk/doc/HISTORY.txt Thu Oct 4 18:11:49 2007 @@ -4,6 +4,12 @@ kukit.js - 1.4dev Unreleased + - ... + + - Implement event binding based on the ids fetched + dynamically from the dom, by value providers. + [ree] + - Store some data on HTML nodes for FireKiss [gotcha] Modified: kukit/kukit.js/trunk/kukit/kssparser.js ============================================================================== --- kukit/kukit.js/trunk/kukit/kssparser.js (original) +++ kukit/kukit.js/trunk/kukit/kssparser.js Thu Oct 4 18:11:49 2007 @@ -379,6 +379,7 @@ "(": 'new kukit.kssp.MethodArgs(this.cursor, kukit.kssp.openParent)' }); kukit.kssp.PropValue.prototype.process = function() { + // Parse all tokens (including first and last) var context = {'nextTokenIndex': 0}; this.digestTxt(context, kukit.tk.Fraction, kukit.kssp.Comment); this.txt = ''; @@ -466,16 +467,64 @@ "\r": 'this.emitAndReturn()', "\/\*": 'this.emitAndReturn()', ":": 'this.emitAndReturn()', - "(": 'this.emitAndReturn(new kukit.kssp.MethodArgs(this.cursor,' + - 'kukit.kssp.openParent))' + "(": '[new kukit.kssp.openParent(this.cursor), new kukit.kssp.PropValue(this.cursor)]', + ")": 'this.emitAndReturn(new kukit.kssp.closeParent(this.cursor))' }); kukit.kssp.EventValue.prototype.multiword_allowed = false; -kukit.kssp.EventValue.prototype.process = - kukit.kssp.PropValue.prototype.process; -kukit.kssp.EventValue.prototype.valueClass = kukit.rd.KssPseudoValue; +kukit.kssp.EventValue.prototype.process = function() { + // Parse all tokens (including first and last) + var context = {'nextTokenIndex': 0}; + this.digestTxt(context, kukit.tk.Fraction, kukit.kssp.Comment); + this.txt = ''; + var txt = context.txt; + if (this.notInTokens(context, kukit.kssp.String)) { + // The previous txt must be all whitespace. + if (txt) { +;;; kukit.E = 'Wrong value : unallowed characters [' + txt + ']'; +;;; kukit.E += ' before a string.'; + this.emitError(kukit.E); + } + // the next one must be a string. + this.expectToken(context, kukit.kssp.String); + this.produceTxt(context.token.txt); + } else if (this.notInTokens(context, kukit.kssp.openParent)) { + this.expectToken(context, kukit.kssp.openParent); + this.expectToken(context, kukit.kssp.PropValue); + this.value = new kukit.rd.KssEventValue(txt, context.token.value); + this.digestTxt(context, kukit.tk.Fraction, kukit.kssp.Comment); + // we have to be at the end and have no text after + if (context.txt) { +;;; kukit.E = 'Wrong event selector : [' + context.txt; +;;; kukit.E += '] is not expected before the closing'; +;;; kukit.E += ' parenthesis. :() can have'; +;;; kukit.E += ' only one parameter.'; + this.emitError(kukit.E); + } + // eat up everything before the closing parent + this.expectToken(context, kukit.kssp.closeParent); + } else { + // not a string or method: check if we allowed multiword. + if (! this.multiword_allowed && txt.indexOf(' ') != -1) { +;;; kukit.E = 'Wrong value : [' + txt + '] cannot have spaces.'; + this.emitError(kukit.E); + } + this.produceTxt(txt); + } + // see what's after + if (context.nextTokenIndex < this.result.length) { + this.digestTxt(context, kukit.tk.Fraction, kukit.kssp.Comment); + // we have to be at the end and have no text after + if (context.nextTokenIndex < this.result.length || context.txt) { +;;; kukit.E = 'Excess characters after the property value'; + this.emitError(kukit.E); + } + } + this.result = []; +}; + kukit.kssp.EventValue.prototype.produceTxt = function(txt) { // txt parms are returned embedded - this.value = new kukit.rd.KssPseudoValue(txt, []); + this.value = new kukit.rd.KssEventValue(txt, null); }; /* @@ -647,8 +696,10 @@ * embedded parser to parse the selector * KSS event selector: (has spaces in it) * selector:name(id) -* KSS method selector: (has no spaces in it) +* selector:name(pprov(id)) +* kss method selector: (has no spaces in it) * document:name(id) or behaviour:name(id) +* document:name(pprov(id)) or behaviour:name(pprov(id)) */ kukit.kssp.KssSelector = kukit.tk.mkParser('kssselector', { ":": '[new kukit.kssp.colon(this.cursor), new ' + @@ -713,11 +764,6 @@ ;;; kukit.E += ' event name cannot have spaces.'; this.emitError(kukit.E); } - if (pseudotoken.value.args.length > 1) { -;;; kukit.E = 'Wrong event selector :'; -;;; kukit.E += ':() can have only one parameter.'; - this.emitError(kukit.E); - } css = this.cursor.text.substring(this.startpos, commatoken.startpos); // Decide if we have an event or a method selector. // We have a method selector if a single word "document" or "behaviour". @@ -732,8 +778,18 @@ } // create the selector. var id = null; - if (pseudotoken.value.args.length == 1) { - id = pseudotoken.value.args[0]; + var ppid = null; + if (pseudotoken.value.arg) { + // We have something in the parentheses after the event name. + if (pseudotoken.value.arg.isMethod) { + // we have a param provider here. Just store. + ppid = pseudotoken.value.arg; + // Check its syntax too. + ppid.check(kukit.pprovidersGlobalRegistry); + } else { + // just an id. Express in txt. + id = pseudotoken.value.arg.txt; + } } var name = pseudotoken.value.methodName; var splitname = name.split('-'); @@ -750,7 +806,7 @@ // Protect the error for better logging ;;; try { this.kssSelector = new kukit.rd.KssSelector(isEvent, css, name, - namespace, id); + namespace, id, ppid); ;;; } catch(e) { ;;; if (e.name == 'KssSelectorError') { ;;; // Log the message @@ -791,6 +847,7 @@ // Store event rules in the common list for (var i=0; i -* Balazs Ree +* Copyright (c) 2005-2007 +* Authors: KSS Project Contributors (see docs/CREDITS.txt) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as published @@ -230,7 +228,7 @@ }; this.testEventValue = function() { - // Parsing prop values in pseudo (no methods allowed) + // Parsing event value (now methods allowed too) var txt= "b"; var cursor = new kukit.tk.Cursor(txt); @@ -268,7 +266,8 @@ parser = new kukit.kssp.EventValue(cursor, null, true); this.assertEquals(parser.finished, true); this.assertEquals(parser.value.methodName, 'click'); - this.assertListEquals(parser.value.args, ['x']); + this.assertEquals(parser.value.arg.isMethod, false); + this.assertEquals(parser.value.arg.txt, 'x'); // more then 1 args not ok (but we check it only from kss selector) //txt= "drag(x, y)"; @@ -282,6 +281,28 @@ }; + this.testEventValueWithValueProvider = function() { + // methods ok + txt= "click(kssAttr(x))"; + src = new kukit.tk.Cursor(txt); + parser = new kukit.kssp.EventValue(src, null, true); + this.assertEquals(parser.finished, true); + this.assertEquals(parser.value.methodName, 'click'); + this.assertEquals(parser.value.arg.isMethod, true); + this.assertEquals(parser.value.arg.methodName, 'kssAttr'); + this.assertListEquals(parser.value.arg.args, ['x']); + }; + + this.testEventValueWithValueProviderRejectsAccessValues = function() { + // no more values in the method + txt= "click(kssAttr(x), aaa)"; + src = new kukit.tk.Cursor(txt); + this.assertParsingError(kukit.kssp.EventValue, src, null, true, + 'Wrong event selector : [,] is not expected before the closing parenthesis. :() can have only one parameter.', 000); + + // XXX add more failing cases, maybe? + }; + this.testMethodArgs = function() { // Parsing method args var txt= "(a, b)"; @@ -419,6 +440,9 @@ +"#calendar-previous a:click {\n" +" action-server : kukitGetPreviousMonth /* place comment here*/;\n" +" kukitGetPreviousMonth-member: formVar(edit, kssAttr(foo));\n" + +'}\n' + +"#button-one:click(kssAttr(widannoy)) {\n" + +" action-client: alert;\n" +"}\n"; var cursor = new kukit.tk.Cursor(txt); @@ -427,13 +451,13 @@ var parser = new kukit.kssp.Document(cursor, null, true); this.assertEquals(parser.finished, true); - this.assertEquals(parser.eventRules.length, 13); + this.assertEquals(parser.eventRules.length, 14); var rule; var action; // rule 0 // #calendar-previous a:click { - // kss-action : kukitresponse/kukitGetPreviousMonth; + // action-server : kukitresponse/kukitGetPreviousMonth; // } rule = parser.eventRules[0]; this.assertDictEquals(rule.parms, {}); @@ -451,7 +475,7 @@ // div#update-area:timeout { // evt-timeout-delay: 2000; // effect: fade; - // kss-action: getCurrentTime; + // action-server: getCurrentTime; // } rule = parser.eventRules[1]; this.assertDictEquals(rule.parms, {'delay': '2000'}); @@ -469,7 +493,7 @@ // rule 2 // #calendar-previous a:click { - // kss-action : 'kukitresponse/kukitGetPreviousMonth' /* place comment here*/; + // action-server : 'kukitresponse/kukitGetPreviousMonth' /* place comment here*/; // } rule = parser.eventRules[2]; this.assertDictEquals(rule.parms, {}); @@ -485,7 +509,7 @@ // rule 3 // #calendar-previous a:click { - // kss-action : 'kukitresponse/kukitGetPreviousMonth' /* place comment here*/; + // action-server : 'kukitresponse/kukitGetPreviousMonth' /* place comment here*/; // member: formVar(edit, 'f_member'); // } rule = parser.eventRules[3]; @@ -504,7 +528,7 @@ // rule 4 // #calendar-previous a:dnd-drag(shelve) { - // kss-action : whatever + // action-server : whatever // } rule = parser.eventRules[4]; this.assertDictEquals(rule.parms, {}); @@ -522,7 +546,7 @@ // rule 5 //#button-one:dnd-drag(annoyMe) { - // kss-action: clickedButton; + // action-server: clickedButton; // id: nodeAttr(id); //} rule = parser.eventRules[5]; @@ -542,7 +566,7 @@ // rule 6 // document:dnd-drag(annoyMe) { - // kss-action: alert; + // action-client: alert; // message: "You are an idiot! Ha ha ha. (But just keep on trying...)"; //} rule = parser.eventRules[6]; @@ -562,8 +586,7 @@ // rule 7 // document:dnd-drag(annoyMe) { - // annoy#annoy-me { - // kss-action: alert; + // action-client: alert; // message: "You are an idiot! Ha ha ha. (But just keep on trying...)"; //} rule = parser.eventRules[7]; @@ -631,7 +654,6 @@ // setStyle-name: backgroundColor; // setStyle-value: #FFa0a0; //} - rule = parser.eventRules[10]; this.assertDictEquals(rule.parms, {}); this.assertEquals(rule.kssSelector.isEventSelector, true); @@ -649,14 +671,13 @@ 'kssSelector': new kukit.rd.KssMethodValue('htmlid', ['button_2']) }); - // rule 12 + // rule 11 //#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.kssSelector.isEventSelector, true); @@ -674,7 +695,7 @@ 'kssSelector': new kukit.rd.KssTextValue('#button_4') }); - // rule 13 + // rule 12 // #calendar-previous a:click { // kss-action : 'kukitresponse/kukitGetPreviousMonth' /* place comment here*/; // member: formVar(edit, kssAttr(foo)); @@ -695,9 +716,31 @@ var kssAttr = formVar.args[1]; this.assertEquals(kssAttr.methodName, 'kssAttr'); this.assertListEquals(kssAttr.args, ['foo']); + + // rule 13 + // #button-one:click(kssAttr(widannoy)) {\n" + // action-client: alert; + //} + rule = parser.eventRules[13]; + this.assertDictEquals(rule.parms, {}); + this.assertEquals(rule.kssSelector.css, '#button-one'); + this.assertEquals(rule.kssSelector.isEventSelector, true); + this.assertEquals(rule.kssSelector.name, 'click'); + this.assertEquals(rule.kssSelector.namespace, null); + this.assertEquals(rule.kssSelector.id, null); + this.assertEquals(rule.kssSelector.ppid.methodName, 'kssAttr'); + this.assertListEquals(rule.kssSelector.ppid.args, ['widannoy']); + action = rule.actions.content['alert']; + this.assertEquals(action.type, 'C'); + this.assertEquals(action.name, 'alert'); + this.assertEquals(action.error, null); + this.assertKssParmEquals(action.parms, { + }); + }; this.testActionErrorParameters = function() { + var txt= "" +"/* a long\n" +"** comment\n" @@ -850,7 +893,7 @@ txt= "a:click('hello', bello)"; cursor = new kukit.tk.Cursor(txt); this.assertParsingError(kukit.kssp.KssSelector, cursor, null, true, - 'Wrong event selector ::() can have only one parameter.', 22); + 'Wrong event selector : [,] is not expected before the closing parenthesis. :() can have only one parameter.', 22); // zero params: not std css but tolerated txt= "a:click()"; @@ -904,22 +947,23 @@ 'Wrong event selector : missing event qualifier : or :().', 20); // Spaces in the end - txt= " a:lang(hu, uh) b:click "; + // txt= " a:lang(hu, uh) b:click "; // XXX not supported + txt= " a:lang(hu-uh) b:click "; cursor = new kukit.tk.Cursor(txt); parser = new kukit.kssp.KssSelector(cursor, null, true); this.assertEquals(parser.finished, true); this.assertEquals(parser.kssSelector.isEventSelector, true); - this.assertEquals(parser.kssSelector.css, " a:lang(hu, uh) b"); + this.assertEquals(parser.kssSelector.css, " a:lang(hu-uh) b"); this.assertEquals(parser.kssSelector.name, 'click'); this.assertEquals(parser.kssSelector.namespace, null); // Comment in the end - txt= " a:lang(hu, uh) b:click/*comment here*/"; + txt= " a:lang(hu-uh) b:click/*comment here*/"; cursor = new kukit.tk.Cursor(txt); parser = new kukit.kssp.KssSelector(cursor, null, true); this.assertEquals(parser.finished, true); this.assertEquals(parser.kssSelector.isEventSelector, true); - this.assertEquals(parser.kssSelector.css, " a:lang(hu, uh) b"); + this.assertEquals(parser.kssSelector.css, " a:lang(hu-uh) b"); this.assertEquals(parser.kssSelector.name, 'click'); this.assertEquals(parser.kssSelector.namespace, null); @@ -1382,6 +1426,43 @@ 'Wrong value for evt-[-] [dnd-drag] : - should exist in the event of the selectors.', 6); } + this.testValueProvidersInEventIdentification = function() { + // Param providers within the event identification + + var txt= "a:click(kssAttr(hello))"; + var src = new kukit.tk.Cursor(txt); + var parser = new kukit.kssp.KssSelector(src, null, true); + this.assertEquals(parser.finished, true); + this.assertEquals(parser.kssSelector.isEventSelector, true); + this.assertEquals(parser.kssSelector.css, 'a'); + this.assertEquals(parser.kssSelector.name, 'click'); + this.assertEquals(parser.kssSelector.namespace, null); + this.assertEquals(parser.kssSelector.id, null); + this.assertEquals(parser.kssSelector.ppid.methodName, 'kssAttr'); + this.assertListEquals(parser.kssSelector.ppid.args, ['hello']); + }; + + this.testValueProvidersInEventIdentification2 = function() { + var txt= "a:click(kssAttr(hello, true ))"; + var src = new kukit.tk.Cursor(txt); + var parser = new kukit.kssp.KssSelector(src, null, true); + this.assertEquals(parser.finished, true); + this.assertEquals(parser.kssSelector.isEventSelector, true); + this.assertEquals(parser.kssSelector.css, 'a'); + this.assertEquals(parser.kssSelector.name, 'click'); + this.assertEquals(parser.kssSelector.namespace, null); + this.assertEquals(parser.kssSelector.id, null); + this.assertEquals(parser.kssSelector.ppid.methodName, 'kssAttr'); + this.assertListEquals(parser.kssSelector.ppid.args, ['hello', 'true']); + }; + + this.testValueProvidersInEventIdentificationRejectsMoreParameters = function() { + var txt= "a:drag(kssAttr(hello), xxx)"; + var src = new kukit.tk.Cursor(txt); + this.assertParsingError(kukit.kssp.KssSelector, src, null, true, + 'Wrong event selector : [,] is not expected before the closing parenthesis. :() can have only one parameter.', 000); + }; + }; kukit.KssParserSelectorsTestCase.prototype = new kukit.KssParserTestCaseBase; From reebalazs at codespeak.net Thu Oct 4 18:13:42 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Thu, 4 Oct 2007 18:13:42 +0200 (CEST) Subject: [KSS-checkins] r47151 - in kukit/kss.core/trunk: docs kss/core/plugins/core kss/core/plugins/core/demo_for_binderids kss/core/plugins/core/demo_for_binderids/selenium_tests Message-ID: <20071004161342.C06AB8199@code0.codespeak.net> Author: reebalazs Date: Thu Oct 4 18:13:40 2007 New Revision: 47151 Added: kukit/kss.core/trunk/kss/core/plugins/core/demo_for_binderids/ kukit/kss.core/trunk/kss/core/plugins/core/demo_for_binderids/README kukit/kss.core/trunk/kss/core/plugins/core/demo_for_binderids/__init__.py kukit/kss.core/trunk/kss/core/plugins/core/demo_for_binderids/binderids.kss kukit/kss.core/trunk/kss/core/plugins/core/demo_for_binderids/binderids.pt kukit/kss.core/trunk/kss/core/plugins/core/demo_for_binderids/configure.zcml kukit/kss.core/trunk/kss/core/plugins/core/demo_for_binderids/selenium_tests/ kukit/kss.core/trunk/kss/core/plugins/core/demo_for_binderids/selenium_tests/README.txt kukit/kss.core/trunk/kss/core/plugins/core/demo_for_binderids/zopeconfig.py Modified: kukit/kss.core/trunk/docs/HISTORY.txt kukit/kss.core/trunk/kss/core/plugins/core/configure.zcml Log: Merge from ree-binding-improvements branch: Implement event binding based on the ids fetched dynamically from the dom, by value providers. I created the demos for this in a temporary directory under the core plugin. This will be moved to the directory that contains the demos of all plugins. Modified: kukit/kss.core/trunk/docs/HISTORY.txt ============================================================================== --- kukit/kss.core/trunk/docs/HISTORY.txt (original) +++ kukit/kss.core/trunk/docs/HISTORY.txt Thu Oct 4 18:13:40 2007 @@ -6,12 +6,17 @@ - ... + - Implement event binding based on the ids fetched + dynamically from the dom, by value providers. + [ree] + - Changed kukit payload to encode HTML content of CDATA. This was necessary because us a supposed bug in FF, that prevented us to use base2 (xpath selection did not work on inserted elements, due to namespace issues.) Get rid of forceToDom, make sure all plugins accept html parameters as strings. + [ree] kss.core - 1.2 Released 2007-08-17 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 Thu Oct 4 18:13:40 2007 @@ -5,6 +5,9 @@ xmlns:zcml="http://namespaces.zope.org/zcml" > + + + + +

Binder ids

+ +

We bind the events on these two buttons with different binder ids. + Events bound to different binders will not merge. + (Note that this is not the typical usage + if event ids, only a simple check that it really works. + )If you click the buttons, you need to + receive alerts per each event bound. +

+ +
+ + + + + + + +
+ +

First we bind an event with id "manual" to each buttons. + We also bind event manual2 to the second button. Then + we bind events that acquire their id from kssattr to the second and + third buttons. So we will have the following events bound: +

+ + + + + + + +
ButtonBound event ids
button1click(manual), click(manual2)
button1click(manual), click(parm1))
button1click(manual), click(parm2))
+ + + + Added: kukit/kss.core/trunk/kss/core/plugins/core/demo_for_binderids/configure.zcml ============================================================================== --- (empty file) +++ kukit/kss.core/trunk/kss/core/plugins/core/demo_for_binderids/configure.zcml Thu Oct 4 18:13:40 2007 @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + Added: kukit/kss.core/trunk/kss/core/plugins/core/demo_for_binderids/selenium_tests/README.txt ============================================================================== --- (empty file) +++ kukit/kss.core/trunk/kss/core/plugins/core/demo_for_binderids/selenium_tests/README.txt Thu Oct 4 18:13:40 2007 @@ -0,0 +1,4 @@ + +Save sour selenium tests into this directory, in html format. +All the tests ending with .html will be processed automatically. + Added: kukit/kss.core/trunk/kss/core/plugins/core/demo_for_binderids/zopeconfig.py ============================================================================== --- (empty file) +++ kukit/kss.core/trunk/kss/core/plugins/core/demo_for_binderids/zopeconfig.py Thu Oct 4 18:13:40 2007 @@ -0,0 +1,35 @@ + +from kss.demo.interfaces import ( + IKSSDemoResource, + IKSSSeleniumTestResource, + ) +from kss.demo.resource import ( + KSSDemo, + KSSSeleniumTestDirectory, + ) +from zope.interface import implements + +# Create a mesh of provided interfaces +# This is needed, because an utility must have a single interface. +class IResource(IKSSDemoResource, IKSSSeleniumTestResource): + pass + +# XXX you do not need to change anything above here +# ------------------------------------------------- + +class KSSDemos(object): + implements(IResource) + + demos = ( + # List your demos here. + # (Second parameter can be a subcategory within the demo if needed.) + KSSDemo('', 'Core syntax', 'binderids.html', 'Binder ids'), + + ) + + # directories are relative from the location of this .py file + selenium_tests = ( + # if you only have one test directory, you + # need not change anything here. + KSSSeleniumTestDirectory('selenium_tests'), + ) From reebalazs at codespeak.net Thu Oct 4 18:24:53 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Thu, 4 Oct 2007 18:24:53 +0200 (CEST) Subject: [KSS-checkins] r47152 - kukit/kukit.js/trunk/kukit Message-ID: <20071004162453.48A02818F@code0.codespeak.net> Author: reebalazs Date: Thu Oct 4 18:24:52 2007 New Revision: 47152 Modified: kukit/kukit.js/trunk/kukit/oper.js Log: Merge critical fix from ree-binding-improvements branch: at default actions, when the usage of pass() is enforced, we need to think of the case when there were no defaultParameters and in this case we need to set the parms to empty dict Modified: kukit/kukit.js/trunk/kukit/oper.js ============================================================================== --- kukit/kukit.js/trunk/kukit/oper.js (original) +++ kukit/kukit.js/trunk/kukit/oper.js Thu Oct 4 18:24:52 2007 @@ -189,9 +189,13 @@ } else { // Put defaultParameters to parms! // This makes sure, that for implicit events - // you do need not to specify pass(xxx) + // you do not need to specify pass(key) // for making the parms arrive to the action. - this.parms = this.defaultParameters; + if (typeof(this.defaultParameters) != 'undefined') { + this.parms = this.defaultParameters; + } else { + this.parms = {}; + } this.binder._EventBinder_callMethod( namespace, name, this, methodName); success = true; From reebalazs at codespeak.net Thu Oct 4 18:27:01 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Thu, 4 Oct 2007 18:27:01 +0200 (CEST) Subject: [KSS-checkins] r47153 - kukit/kukit.js/branch/1.2/kukit Message-ID: <20071004162701.C08E5818F@code0.codespeak.net> Author: reebalazs Date: Thu Oct 4 18:27:01 2007 New Revision: 47153 Modified: kukit/kukit.js/branch/1.2/kukit/oper.js Log: Merge critical fix from trunk -r47152: at default actions, when the usage of pass() is enforced, we need to think of the case when there were no defaultParameters and in this case we need to set the parms to empty dict Modified: kukit/kukit.js/branch/1.2/kukit/oper.js ============================================================================== --- kukit/kukit.js/branch/1.2/kukit/oper.js (original) +++ kukit/kukit.js/branch/1.2/kukit/oper.js Thu Oct 4 18:27:01 2007 @@ -189,9 +189,13 @@ } else { // Put defaultParameters to parms! // This makes sure, that for implicit events - // you do need not to specify pass(xxx) + // you do not need to specify pass(key) // for making the parms arrive to the action. - this.parms = this.defaultParameters; + if (typeof(this.defaultParameters) != 'undefined') { + this.parms = this.defaultParameters; + } else { + this.parms = {}; + } this.binderInstance._EventBinder_callMethod( namespace, name, this, methodName); success = true; From reebalazs at codespeak.net Thu Oct 4 18:33:34 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Thu, 4 Oct 2007 18:33:34 +0200 (CEST) Subject: [KSS-checkins] r47154 - kukit/kukit.js/trunk/tests Message-ID: <20071004163334.00C8C80A9@code0.codespeak.net> Author: reebalazs Date: Thu Oct 4 18:33:34 2007 New Revision: 47154 Modified: kukit/kukit.js/trunk/tests/test_kssparser.js Log: Separate tests for event selectors 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 Thu Oct 4 18:33:34 2007 @@ -227,43 +227,50 @@ 'Wrong value : unallowed characters after the property', 17); }; - this.testEventValue = function() { - // Parsing event value (now methods allowed too) - + this.testEventValueSimple = function() { + // Parsing event value var txt= "b"; var cursor = new kukit.tk.Cursor(txt); var parser = new kukit.kssp.EventValue(cursor, null, true); this.assertEquals(parser.finished, true); this.assertEquals(parser.value.methodName, 'b'); + }; + this.testEventValueMultiword = function() { // multiword ok but does not finish - txt= "b c"; - cursor = new kukit.tk.Cursor(txt); - parser = new kukit.kssp.EventValue(cursor, null, true); + var txt= "b c"; + var cursor = new kukit.tk.Cursor(txt); + var parser = new kukit.kssp.EventValue(cursor, null, true); this.assertEquals(parser.finished, true); this.assertEquals(cursor.pos, 1); this.assertEquals(parser.value.methodName, 'b'); + }; + this.testEventValueStartsWithSpace = function() { // space ok but does not finish - txt= " b"; - cursor = new kukit.tk.Cursor(txt); - parser = new kukit.kssp.EventValue(cursor, null, true); + var txt= " b"; + var cursor = new kukit.tk.Cursor(txt); + var parser = new kukit.kssp.EventValue(cursor, null, true); this.assertEquals(parser.finished, true); this.assertEquals(cursor.pos, 0); this.assertEquals(parser.value.methodName, ''); + }; + this.testEventValueWithComment = function() { // ok, does not finish - txt= "apples/* more comments and*/"; - cursor = new kukit.tk.Cursor(txt); - parser = new kukit.kssp.EventValue(cursor, null, true); + var txt= "apples/* more comments and*/"; + var cursor = new kukit.tk.Cursor(txt); + var parser = new kukit.kssp.EventValue(cursor, null, true); this.assertEquals(parser.finished, true); this.assertEquals(cursor.pos, 6); this.assertEquals(parser.value.methodName, 'apples'); + }; + this.testEventValueWithBinderId = function() { // params ok - txt= "click(x)"; - cursor = new kukit.tk.Cursor(txt); - parser = new kukit.kssp.EventValue(cursor, null, true); + var txt= "click(x)"; + var cursor = new kukit.tk.Cursor(txt); + var parser = new kukit.kssp.EventValue(cursor, null, true); this.assertEquals(parser.finished, true); this.assertEquals(parser.value.methodName, 'click'); this.assertEquals(parser.value.arg.isMethod, false); @@ -278,14 +285,13 @@ //cursor = new kukit.tk.Cursor(txt); //this.assertParsingError(kukit.kssp.EventValue, cursor, null, true, // 'Excess characters after the property value', 16); - }; this.testEventValueWithValueProvider = function() { // methods ok - txt= "click(kssAttr(x))"; - src = new kukit.tk.Cursor(txt); - parser = new kukit.kssp.EventValue(src, null, true); + var txt= "click(kssAttr(x))"; + var cursor = new kukit.tk.Cursor(txt); + var parser = new kukit.kssp.EventValue(cursor, null, true); this.assertEquals(parser.finished, true); this.assertEquals(parser.value.methodName, 'click'); this.assertEquals(parser.value.arg.isMethod, true); @@ -295,9 +301,9 @@ this.testEventValueWithValueProviderRejectsAccessValues = function() { // no more values in the method - txt= "click(kssAttr(x), aaa)"; - src = new kukit.tk.Cursor(txt); - this.assertParsingError(kukit.kssp.EventValue, src, null, true, + var txt= "click(kssAttr(x), aaa)"; + var cursor = new kukit.tk.Cursor(txt); + this.assertParsingError(kukit.kssp.EventValue, cursor, null, true, 'Wrong event selector : [,] is not expected before the closing parenthesis. :() can have only one parameter.', 000); // XXX add more failing cases, maybe? From reebalazs at codespeak.net Thu Oct 4 19:19:06 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Thu, 4 Oct 2007 19:19:06 +0200 (CEST) Subject: [KSS-checkins] r47155 - kukit/kss.core/trunk/kss/core/plugins/core/demo_for_binderids Message-ID: <20071004171906.824BD81A8@code0.codespeak.net> Author: reebalazs Date: Thu Oct 4 19:19:04 2007 New Revision: 47155 Modified: kukit/kss.core/trunk/kss/core/plugins/core/demo_for_binderids/binderids.pt Log: Small fix in the informational text of the demo template Modified: kukit/kss.core/trunk/kss/core/plugins/core/demo_for_binderids/binderids.pt ============================================================================== --- kukit/kss.core/trunk/kss/core/plugins/core/demo_for_binderids/binderids.pt (original) +++ kukit/kss.core/trunk/kss/core/plugins/core/demo_for_binderids/binderids.pt Thu Oct 4 19:19:04 2007 @@ -29,10 +29,11 @@
-

First we bind an event with id "manual" to each buttons. - We also bind event manual2 to the second button. Then +

First we bind an event with id "manual" to each button. + We also bind event with id "manual2" to the first button. Then we bind events that acquire their id from kssattr to the second and - third buttons. So we will have the following events bound: + third buttons. This way each button will have 2 click events + bound, in the following way:

From reebalazs at codespeak.net Thu Oct 4 20:41:58 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Thu, 4 Oct 2007 20:41:58 +0200 (CEST) Subject: [KSS-checkins] r47156 - kukit/kss.demo/trunk/kss/demo/demo Message-ID: <20071004184158.022F5818F@code0.codespeak.net> Author: reebalazs Date: Thu Oct 4 20:41:57 2007 New Revision: 47156 Removed: kukit/kss.demo/trunk/kss/demo/demo/body_macros.pt Log: Remove body_macros that I forgot to remove. It is now in browsers. Deleted: /kukit/kss.demo/trunk/kss/demo/demo/body_macros.pt ============================================================================== --- /kukit/kss.demo/trunk/kss/demo/demo/body_macros.pt Thu Oct 4 20:41:57 2007 +++ (empty file) @@ -1,17 +0,0 @@ - - - - -

- Kss is in - development - production - - mode.
- Control development mode -

- -
- - \ No newline at end of file From reebalazs at codespeak.net Thu Oct 4 20:44:49 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Thu, 4 Oct 2007 20:44:49 +0200 (CEST) Subject: [KSS-checkins] r47157 - kukit/kss.demo/trunk/kss/demo/demo Message-ID: <20071004184449.DCBFB81A2@code0.codespeak.net> Author: reebalazs Date: Thu Oct 4 20:44:49 2007 New Revision: 47157 Removed: kukit/kss.demo/trunk/kss/demo/demo/demo.css kukit/kss.demo/trunk/kss/demo/demo/header_macros.pt Log: Remove header_macros, demo.css that I forgot to remove. They are now in browsers. Deleted: /kukit/kss.demo/trunk/kss/demo/demo/demo.css ============================================================================== --- /kukit/kss.demo/trunk/kss/demo/demo/demo.css Thu Oct 4 20:44:49 2007 +++ (empty file) @@ -1,90 +0,0 @@ -body { - font-family: Verdana, Arial, sans-serif; - font-size: 11pt; -} - -h3 { - font-size: 110%; - margin-top: 0.5em; - margin-bottom: 0.2em; -} - -#global-links { - display: table; - font-size: 80%; -} - -#global-links ul { - display: table-row; -} - -#global-links ul li { - display: table-cell; -} - -#global-links a { - display: block; - padding: 0.25em; - margin: 0.25em; - border: 1px solid #FF8888; - color: #CC0000; - text-decoration: none; -} - -#global-links a:hover { - border-color: #FF0000; - background-color: #FFCCCC; -} - -#target { - padding: 1em; - margin: 0.5em 0; - border: 1px solid #CCCCCC; - background-color: #EEEEEE; -} - -.cursorPointer { - cursor: pointer; -} - -.click { - color: #880000; -} - -radio.click { - background-color: #880000; -} - -a.button, -input[type="submit"] { - width: auto; - padding: 0.2em; - border: 1px solid #FF8888; - color: #CC0000; - text-decoration: none; -} - -fieldset { - margin: 0.5em 0; -} - -fieldset div { - margin: 0.3em 0; -} - -.help { - font-size: 80%; - color: #AAAAAA; -} - -.help pre { - color: black; - border: 1px solid #CCCCCC; - background-color: #EEEEEE; - padding: 0.5em; - margin: 0.25em; -} - -.container { - padding : 1em; -} Deleted: /kukit/kss.demo/trunk/kss/demo/demo/header_macros.pt ============================================================================== --- /kukit/kss.demo/trunk/kss/demo/demo/header_macros.pt Thu Oct 4 20:44:49 2007 +++ (empty file) @@ -1,113 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From jvloothuis at codespeak.net Thu Oct 4 21:20:25 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Thu, 4 Oct 2007 21:20:25 +0200 (CEST) Subject: [KSS-checkins] r47158 - kukit/KssTheme Message-ID: <20071004192025.AA67B80B2@code0.codespeak.net> Author: jvloothuis Date: Thu Oct 4 21:20:24 2007 New Revision: 47158 Added: kukit/KssTheme/ Log: New product for the website look From jvloothuis at codespeak.net Thu Oct 4 21:20:31 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Thu, 4 Oct 2007 21:20:31 +0200 (CEST) Subject: [KSS-checkins] r47159 - kukit/KssTheme/trunk Message-ID: <20071004192031.8F3AC8181@code0.codespeak.net> Author: jvloothuis Date: Thu Oct 4 21:20:31 2007 New Revision: 47159 Added: kukit/KssTheme/trunk/ Log: New product for the website look From jvloothuis at codespeak.net Thu Oct 4 21:22:23 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Thu, 4 Oct 2007 21:22:23 +0200 (CEST) Subject: [KSS-checkins] r47160 - in kukit/KssTheme/trunk: . Extensions profile profile/types skins skins/ksstheme_images skins/ksstheme_styles skins/ksstheme_templates Message-ID: <20071004192223.859708181@code0.codespeak.net> Author: jvloothuis Date: Thu Oct 4 21:22:22 2007 New Revision: 47160 Added: kukit/KssTheme/trunk/Extensions/ kukit/KssTheme/trunk/Extensions/Install.py kukit/KssTheme/trunk/HISTORY.txt kukit/KssTheme/trunk/LICENSE.txt kukit/KssTheme/trunk/README.txt kukit/KssTheme/trunk/__init__.py kukit/KssTheme/trunk/profile/ kukit/KssTheme/trunk/profile/cssregistry.xml kukit/KssTheme/trunk/profile/import_steps.xml kukit/KssTheme/trunk/profile/jsregistry.xml kukit/KssTheme/trunk/profile/properties.xml kukit/KssTheme/trunk/profile/skins.xml kukit/KssTheme/trunk/profile/types/ kukit/KssTheme/trunk/profile/types/Folder.xml kukit/KssTheme/trunk/setuphandlers.py kukit/KssTheme/trunk/skins/ kukit/KssTheme/trunk/skins/ksstheme_images/ kukit/KssTheme/trunk/skins/ksstheme_images/bg-left.gif (contents, props changed) kukit/KssTheme/trunk/skins/ksstheme_images/breadcrumb-bg.gif (contents, props changed) kukit/KssTheme/trunk/skins/ksstheme_images/breadcrumb-end.gif (contents, props changed) kukit/KssTheme/trunk/skins/ksstheme_images/breadcrumb-pijl.gif (contents, props changed) kukit/KssTheme/trunk/skins/ksstheme_images/bullit.gif (contents, props changed) kukit/KssTheme/trunk/skins/ksstheme_images/icon_bg.gif (contents, props changed) kukit/KssTheme/trunk/skins/ksstheme_images/icon_demo.gif (contents, props changed) kukit/KssTheme/trunk/skins/ksstheme_images/icon_doc.gif (contents, props changed) kukit/KssTheme/trunk/skins/ksstheme_images/icon_down.gif (contents, props changed) kukit/KssTheme/trunk/skins/ksstheme_images/logo.gif (contents, props changed) kukit/KssTheme/trunk/skins/ksstheme_images/menu-ov.gif (contents, props changed) kukit/KssTheme/trunk/skins/ksstheme_images/menu.gif (contents, props changed) kukit/KssTheme/trunk/skins/ksstheme_images/submenu-ov.gif (contents, props changed) kukit/KssTheme/trunk/skins/ksstheme_images/submenu.gif (contents, props changed) kukit/KssTheme/trunk/skins/ksstheme_styles/ kukit/KssTheme/trunk/skins/ksstheme_styles/authoring.css.dtml kukit/KssTheme/trunk/skins/ksstheme_styles/base.css.dtml kukit/KssTheme/trunk/skins/ksstheme_styles/base_properties.props kukit/KssTheme/trunk/skins/ksstheme_styles/generated.css.dtml kukit/KssTheme/trunk/skins/ksstheme_styles/ie6.css.dtml kukit/KssTheme/trunk/skins/ksstheme_styles/ie7.css.dtml kukit/KssTheme/trunk/skins/ksstheme_styles/ksstheme.css.dtml kukit/KssTheme/trunk/skins/ksstheme_styles/portlets.css.dtml kukit/KssTheme/trunk/skins/ksstheme_styles/public.css.dtml kukit/KssTheme/trunk/skins/ksstheme_templates/ kukit/KssTheme/trunk/skins/ksstheme_templates/fetchRecentNews.py kukit/KssTheme/trunk/skins/ksstheme_templates/footer.pt kukit/KssTheme/trunk/skins/ksstheme_templates/global_pathbar.pt kukit/KssTheme/trunk/skins/ksstheme_templates/header.pt kukit/KssTheme/trunk/skins/ksstheme_templates/main_template.pt kukit/KssTheme/trunk/skins/ksstheme_templates/portlet_login.pt kukit/KssTheme/trunk/skins/ksstheme_templates/portlet_navigation.pt kukit/KssTheme/trunk/skins/ksstheme_templates/portlet_news.pt kukit/KssTheme/trunk/update_info.txt kukit/KssTheme/trunk/version.txt Log: Added files created by Linda Added: kukit/KssTheme/trunk/Extensions/Install.py ============================================================================== --- (empty file) +++ kukit/KssTheme/trunk/Extensions/Install.py Thu Oct 4 21:22:22 2007 @@ -0,0 +1,8 @@ +from Products.CMFCore.utils import getToolByName + +def install(portal): + setup_tool = getToolByName(portal, 'portal_setup') + setup_tool.setImportContext('profile-KssTheme:ksstheme') + setup_tool.runAllImportSteps() + setup_tool.setImportContext('profile-CMFPlone:plone') + return "Ran all import steps." \ No newline at end of file Added: kukit/KssTheme/trunk/HISTORY.txt ============================================================================== --- (empty file) +++ kukit/KssTheme/trunk/HISTORY.txt Thu Oct 4 21:22:22 2007 @@ -0,0 +1,8 @@ +Changelog for KssTheme + + (name of developer listed in brackets) + +KssTheme 1.0 - Unreleased + + - Generated skeleton product from DIYPloneStyle 2.5. + [generator] Added: kukit/KssTheme/trunk/LICENSE.txt ============================================================================== --- (empty file) +++ kukit/KssTheme/trunk/LICENSE.txt Thu Oct 4 21:22:22 2007 @@ -0,0 +1,17 @@ +KssTheme +Copyright (C) 2005-2006 John Doe + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +MA 02110-1301, USA. Added: kukit/KssTheme/trunk/README.txt ============================================================================== --- (empty file) +++ kukit/KssTheme/trunk/README.txt Thu Oct 4 21:22:22 2007 @@ -0,0 +1,59 @@ +Description + + KssTheme is a product that adds a new style to a Plone 2.5.x portal. + It adds a new skin selection to the 'portal_skins' tool + (called KssTheme), and registers a custom stylesheet (called + ksstheme.css) with the 'portal_css' tool. + + KssTheme is based on DIYPloneStyle 2.5, a skeleton product + ready for building new graphical designs for Plone. + +Installation + + Place KssTheme in the Products directory of your Zope instance + and restart the server. + + The classic way: + + Go to the 'Site Setup' page in the Plone interface and click on the + 'Add/Remove Products' link. + + Choose the product (check its checkbox) and click the 'Install' button. + + Uninstall -- This can be done from the same management screen, but only + if you installed it from the quick installer. + + The Generic Setup way: + + In the ZMI, go to 'portal_setup' and, (1) select the 'Properties' tab + and choose KssTheme in the popup list before clicking 'Update'. + Then (2) go to the 'Import' tab and click 'Import all steps'. + + While adding a Plone Site to Zope (from the ZMI), you can select + KssTheme in the proposed Extension Profiles to have it installed + automatically during the creation of the portal. + + Uninstall -- This must be done manually from the ZMI, as GenericSetup + does not have an API for removing/uninstalling stuff (yet). + + Note: You may have to empty your browser cache to see the effects of the + product installation. + +Selecting a skin + + Depending on the values given in the skins tool profile (see + profiles/default/skins.xml), the skin will be selected (or not) as default + one while installing the product. If you need to switch from a default + skin to another, go to the 'Site Setup' page, and choose 'Skins' (as + portal manager). You can also decide from that page if members can choose + their preferred skin and, in that case, if the skin cookie should be + persistent. + + Note -- Don't forget to perform a full refresh of the page or reload all + images (not from browser cache) after selecting a skin. In Firefox, you + can do so by pressing the 'shift' key while reloading the page. In IE, use + the key combination . + +Written by + + John Doe Added: kukit/KssTheme/trunk/__init__.py ============================================================================== --- (empty file) +++ kukit/KssTheme/trunk/__init__.py Thu Oct 4 21:22:22 2007 @@ -0,0 +1,19 @@ +# Register our skins directory - this makes it available via portal_skins. +# register our profile + +from Products.CMFCore.DirectoryView import registerDirectory + +from Products.GenericSetup import EXTENSION, profile_registry +from Products.CMFPlone.interfaces import IPloneSiteRoot + +GLOBALS = globals() +registerDirectory('skins', GLOBALS) + +profile_registry.registerProfile( + 'ksstheme', + 'KssTheme', + 'Extension profile for KssTheme Product', + 'profile', + 'KssTheme', + EXTENSION, + for_=IPloneSiteRoot) Added: kukit/KssTheme/trunk/profile/cssregistry.xml ============================================================================== --- (empty file) +++ kukit/KssTheme/trunk/profile/cssregistry.xml Thu Oct 4 21:22:22 2007 @@ -0,0 +1,25 @@ + + + + + + + Added: kukit/KssTheme/trunk/profile/import_steps.xml ============================================================================== --- (empty file) +++ kukit/KssTheme/trunk/profile/import_steps.xml Thu Oct 4 21:22:22 2007 @@ -0,0 +1,11 @@ + + + + + Various import steps that are not handled by GS import/export + handlers. + + Added: kukit/KssTheme/trunk/profile/jsregistry.xml ============================================================================== --- (empty file) +++ kukit/KssTheme/trunk/profile/jsregistry.xml Thu Oct 4 21:22:22 2007 @@ -0,0 +1,24 @@ + + + + + + + + Added: kukit/KssTheme/trunk/profile/properties.xml ============================================================================== --- (empty file) +++ kukit/KssTheme/trunk/profile/properties.xml Thu Oct 4 21:22:22 2007 @@ -0,0 +1,38 @@ + + + + + + + + + + Added: kukit/KssTheme/trunk/profile/skins.xml ============================================================================== --- (empty file) +++ kukit/KssTheme/trunk/profile/skins.xml Thu Oct 4 21:22:22 2007 @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Added: kukit/KssTheme/trunk/profile/types/Folder.xml ============================================================================== --- (empty file) +++ kukit/KssTheme/trunk/profile/types/Folder.xml Thu Oct 4 21:22:22 2007 @@ -0,0 +1,34 @@ + + + + + + + + + + + + + Added: kukit/KssTheme/trunk/setuphandlers.py ============================================================================== --- (empty file) +++ kukit/KssTheme/trunk/setuphandlers.py Thu Oct 4 21:22:22 2007 @@ -0,0 +1,5 @@ +def setupVarious(context): + site = context.getSite() + logger = context.getLogger('ksstheme') + logger.info("ksstheme_various: Nothing done") + return \ No newline at end of file Added: kukit/KssTheme/trunk/skins/ksstheme_images/bg-left.gif ============================================================================== Binary file. No diff available. Added: kukit/KssTheme/trunk/skins/ksstheme_images/breadcrumb-bg.gif ============================================================================== Binary file. No diff available. Added: kukit/KssTheme/trunk/skins/ksstheme_images/breadcrumb-end.gif ============================================================================== Binary file. No diff available. Added: kukit/KssTheme/trunk/skins/ksstheme_images/breadcrumb-pijl.gif ============================================================================== Binary file. No diff available. Added: kukit/KssTheme/trunk/skins/ksstheme_images/bullit.gif ============================================================================== Binary file. No diff available. Added: kukit/KssTheme/trunk/skins/ksstheme_images/icon_bg.gif ============================================================================== Binary file. No diff available. Added: kukit/KssTheme/trunk/skins/ksstheme_images/icon_demo.gif ============================================================================== Binary file. No diff available. Added: kukit/KssTheme/trunk/skins/ksstheme_images/icon_doc.gif ============================================================================== Binary file. No diff available. Added: kukit/KssTheme/trunk/skins/ksstheme_images/icon_down.gif ============================================================================== Binary file. No diff available. Added: kukit/KssTheme/trunk/skins/ksstheme_images/logo.gif ============================================================================== Binary file. No diff available. Added: kukit/KssTheme/trunk/skins/ksstheme_images/menu-ov.gif ============================================================================== Binary file. No diff available. Added: kukit/KssTheme/trunk/skins/ksstheme_images/menu.gif ============================================================================== Binary file. No diff available. Added: kukit/KssTheme/trunk/skins/ksstheme_images/submenu-ov.gif ============================================================================== Binary file. No diff available. Added: kukit/KssTheme/trunk/skins/ksstheme_images/submenu.gif ============================================================================== Binary file. No diff available. Added: kukit/KssTheme/trunk/skins/ksstheme_styles/authoring.css.dtml ============================================================================== --- (empty file) +++ kukit/KssTheme/trunk/skins/ksstheme_styles/authoring.css.dtml Thu Oct 4 21:22:22 2007 @@ -0,0 +1,726 @@ +/* +** Plone style sheet - Authoring Elements +** +** Style sheet documentation can be found at http://plone.org/documentation +** +** You should preferrably use ploneCustom.css to add your own CSS classes and to +** customize your portal, as these are the base fundaments of Plone, and will +** change and be refined in newer versions. Keeping your changes in +** ploneCustom.css will make it easier to upgrade. +** +** Feel free to use whole or parts of this for your own designs, but give credit +** where credit is due. +** +*/ + +/* (do not remove this :) */ +/* (not this either :) */ + +.standalone, +.documentEditable * .standalone { +background: &dtml-globalBackgroundColor; url(&dtml-portal_url;/linkOpaque.gif) 9px 1px no-repeat; +cursor: pointer; +font-size: &dtml-fontSmallSize;; +padding: 1px 1px 1px 15px; +text-transform: &dtml-textTransform;; +overflow: visible; +} +.context, +.documentEditable * .context { +background: transparent url(&dtml-portal_url;/linkTransparent.gif) 9px 1px no-repeat; +cursor: pointer; +font-size: &dtml-fontSmallSize;; +padding: 1px 1px 1px 15px; +text-transform: &dtml-textTransform;; +overflow: visible; +} +.destructive, +.documentEditable * .destructive { +background: &dtml-notifyBackgroundColor; url(&dtml-portal_url;/linkTransparent.gif) 9px 1px no-repeat; +border: &dtml-borderWidth; &dtml-borderStyle; &dtml-notifyBorderColor;; +cursor: pointer; +font-size: &dtml-fontSmallSize;; +padding: 1px 1px 1px 15px; +text-transform: &dtml-textTransform;; +overflow: visible; +} +input.searchButton { +margin-bottom: &dtml-borderWidth; ! important; +font-size: &dtml-fontSmallSize;; +background: &dtml-backgroundColor; url(&dtml-portal_url;/search_icon.gif) 2px 1px no-repeat; +cursor: pointer; +padding: 1px 1px 1px 15px; +text-transform: &dtml-textTransform;; + +} +.add, +.documentEditable * .add { +} +.quickSearch { +} +.notify, +.documentEditable * .notify { +border: &dtml-borderWidth; &dtml-borderStyle; &dtml-notifyBorderColor;; +} + +.card { +background-color: &dtml-globalBackgroundColor;; +border-color: &dtml-globalBorderColor;; +border-width: &dtml-borderWidth;; +border-style: &dtml-borderStyle;; +float: left; +margin: 1em; +text-align: center; +width: 110px; +padding: 1em 0; +} + +.card a { +text-decoration: none; +} + +.portrait { +background-color: &dtml-globalBackgroundColor;; +border-color: &dtml-globalBorderColor;; +border-width: &dtml-borderWidth;; +border-style: &dtml-borderStyle;; +font-size: &dtml-fontSmallSize;; +margin: 0.5em; +padding: 1em 0 0.5em 0; +text-align: center; +width: 100px; +} + +.portraitPhoto { +border: 1px solid black; +} + +.listing, +.stx table { +/* The default table for document listings. Contains name, document types, modification times etc in a file-browser-like fashion */ +border-collapse: collapse; +border-left: &dtml-borderWidth; &dtml-borderStyle; &dtml-globalBorderColor;; +border-bottom: &dtml-borderWidth; &dtml-borderStyle; &dtml-globalBorderColor;; +font-size: &dtml-fontSmallSize;; +margin: 1em 0em 1em 0em; +} +.listing th, +.stx table th { +background: &dtml-globalBackgroundColor;; +border-top: &dtml-borderWidth; &dtml-borderStyle; &dtml-globalBorderColor;; +border-bottom: &dtml-borderWidth; &dtml-borderStyle; &dtml-globalBorderColor;; +border-right: &dtml-borderWidth; &dtml-borderStyle; &dtml-globalBorderColor;; +font-weight: normal; +padding: 0.25em 1em; +text-transform: &dtml-textTransform;; +} +.listing .top { +border-left: &dtml-borderWidth; &dtml-borderStyle; &dtml-backgroundColor;; +border-top: &dtml-borderWidth; &dtml-borderStyle; &dtml-backgroundColor; ! important; +border-right: &dtml-borderWidth; &dtml-borderStyle; &dtml-backgroundColor; ! important; +text-align: right ! important; +padding: 0em 0em 1em 0em; +} +.listing .listingCheckbox { +text-align: center; +} +.listing td, +.stx table td { +border-right: &dtml-borderWidth; &dtml-borderStyle; &dtml-globalBorderColor;; +padding: 0.25em 1em; +} + +.listing a { +text-decoration: none; +} + +.listing a:hover { +text-decoration: underline; +} +.listing img { +vertical-align: middle; +} + +.listing td a label, +.stx table td a label { +cursor: pointer; +} + +/* Vertical addition class */ + +.vertical { +background-color: &dtml-backgroundColor;; +} +.vertical th { +padding: 0.5em; +} + +.vertical td { +border-top: &dtml-borderWidth; &dtml-borderStyle; &dtml-globalBorderColor;; +padding: 0.5em; +} + + + +ul.configlets { +margin: 1em 0; +list-style-image: none; +list-style: none; +} + +ul.configlets li { +margin-bottom: 1em; +} + +ul.configlets li a { +text-decoration: none; +border: none; +} + +ul.configlets li a:visited { +color: &dtml-linkColor;; +background-color: transparent; +} + +ul.configlets li a:active { +color: &dtml-linkColor;; +background-color: transparent; +} + +ul.configlets li label { +font-weight: bold; +} + +ul.configletDetails { +margin: 0em 1em 1em 4em; +list-style-image: none; +list-style: none; +} + +ul.configletDetails li { +margin-bottom: 1em; +display: inline; +} + +ul.configletDetails li a { +text-decoration: none; +} + +ul.configletDetails li label { +font-weight: bold; +} + +/* List classes without markers */ + +ul.visualNoMarker, +ol.visualNoMarker { +list-style-type: none; +list-style-image: none; +margin: 0.5em 0 0 0; +} + + + +/* Additional STX workaround classes */ +.stx table p /* stupid STX table workaround */ +{ +margin: 0; +padding: 0; +} +.stx table /* stupid STX table workaround */ +{ +border: &dtml-borderWidth; &dtml-borderStyle; &dtml-globalBorderColor; ! important; +} +.stx table td { +border-bottom: &dtml-borderWidth; &dtml-borderStyle; &dtml-globalBorderColor;; +} + +.reviewHistory { +display: inline; +font-size: 110% !important; +color: Black; +} + +.comment { +background: &dtml-evenRowBackgroundColor;; +border: &dtml-borderWidth; &dtml-borderStyleAnnotations; &dtml-globalBorderColor;; +padding: 0.25em 1em 0.5em 1em; +margin-bottom: 1em; +} + +.comment h1, +.comment h2, +.comment h3, +.comment h4, +.comment h5, +.comment h6 { +border-bottom: &dtml-borderWidth; &dtml-borderStyleAnnotations; &dtml-discreetColor;; +font-weight: normal; +} + +.comment h3 a { +background-image: url(&dtml-portal_url;/discussionitem_icon.gif); +background-repeat: no-repeat; +padding-left: 18px; +margin-left: -1px; +margin-bottom: 1px; +min-height: 1.6em; +height: auto; +line-height: 1.6em; +} + +.commentBody { +margin: 0 1em 1em 1em; +} + +.spacer { +margin: 1em; +} + +.contentViews { +background-color: transparent; +padding-left: 1em; +line-height: normal; +margin: 0; +list-style: none; +border: &dtml-borderWidth; &dtml-borderStyle; &dtml-contentViewBorderColor;; +border-top-width: 0px; +border-left-width: 0px; +border-right-width: 0px; +} +.contentViews li { +display: inline; +padding-top: 0.5em; +} +.contentViews li a { +background-color: transparent; +border: &dtml-borderWidth; &dtml-borderStyle; &dtml-contentViewBorderColor;; +border-style: &dtml-borderStyle;; +color: &dtml-contentViewFontColor;; +height: auto; +margin-right: 0.5em; +padding: 0em 1em; +line-height: normal; +text-decoration: none; +text-transform: &dtml-textTransform;; +z-index: 1; +} +.contentViews .selected a { +background-color: &dtml-contentViewBackgroundColor;; +border-bottom: &dtml-contentViewBackgroundColor; &dtml-borderWidth; &dtml-borderStyle;; +color: &dtml-contentViewFontColor;; +} +.contentViews li a:hover { +background-color: &dtml-contentViewBackgroundColor;; +color: &dtml-contentViewFontColor;; +} + + +.configlet .contentViews { +font-size: 90%; +} + +/* +** begin ECMAScript Content Action Menus +*/ + +.contentActions { +background-color: &dtml-contentViewBackgroundColor;; +border-left: &dtml-borderWidth; &dtml-borderStyle; &dtml-contentViewBorderColor;; +border-right: &dtml-borderWidth; &dtml-borderStyle; &dtml-contentViewBorderColor;; +color: &dtml-contentViewFontColor;; +text-align: right; +text-transform: &dtml-textTransform;; +padding: 0 0 0 1em; +z-index: 2; +position:relative; +height: 1.6em; +} + +.contentActions ul, +.contentActions li { +margin: 0; +list-style: none; +list-style-image: none; +display: inline; +color: &dtml-fontColor;; +text-align: left; +} + +.contentActions ul { +line-height: 1.6em; +padding: 0; +margin: 0; +} +.contentActions li { +float: right; +z-index: 4; +border-left: &dtml-borderWidth; &dtml-borderStyle; &dtml-contentViewBorderColor;; +line-height: 1.6em; +} + +.actionItems li { +background-image: none; +} + +.contentActions a { +text-decoration: none; +color: &dtml-contentViewFontColor;; +padding: 0 0.5em; +} + +.actionMenu { +/* The spec says we can't put this on an element with a float (although +Opera is the only one that cares) and we need it in order to catch +the position:absolute bubbling up */ + +position: relative; +margin: 0; +padding: 0; +} + +.actionMenu .actionMenuHeader { +margin: 0; +padding: 0; +font-weight: normal; +cursor: pointer; +} + +.actionMenu.activated .actionMenuHeader { +position: relative; +z-index: 10; +} + +.actionMenu .actionMenuHeader a { +display: block; +} + +.actionMenu.activated .actionMenuHeader a, +.actionMenu.deactivated .actionMenuHeader a { +background-image: url(/arrowDownAlternative.gif); +background-repeat: no-repeat; +background-position: 95% 60%; +padding: 0 1.6em 0 0.5em !important; +cursor: pointer; +} + +.actionMenuDisabled { +padding: 0 0.5em 0 0.5em !important; +cursor: pointer; +} + +.actionMenu .actionMenuContent { +display: none; +z-index: 5; +position: absolute; +top: 1.6em; +right: -1px; +height: auto; +padding: 0; +margin: 0; +cursor: pointer; +} + +.actionMenu .actionMenuContent ul { +display: block; +background: &dtml-contentViewBackgroundColor;; +border: &dtml-borderWidth; &dtml-contentViewBorderColor;; +border-style: none &dtml-borderStyle; &dtml-borderStyle; &dtml-borderStyle;; +margin: -2px 0 0 0; +padding: 0; +cursor: pointer; +} + +.actionMenu.activated .actionMenuContent { +display: block !important; +} +.actionMenu.activated .actionMenuContent { +/* this one will be ignored by IE, it is here to fix the cut-off error in +Firefox */ +display: table !important; +border-collapse: collapse; +border-spacing: 0; +} + +.actionMenu.deactivated .actionMenuContent { +display: none !important; +} + +.actionMenu .actionMenuContent li { +float: none; +background-color: transparent; +display: inline; +padding: 0; +margin: 0; +border: 0; +} + +.actionMenu .actionMenuContent li a { +display: block; +white-space: nowrap; +padding: 0 0.5em; +margin: 0.2em 0; +} + +.actionMenu .actionMenuContent .selected { +display: block; +white-space: nowrap; +padding: 0 0.5em; +margin: 0.2em 0; +} + +.actionMenu .actionMenuContent li a:hover { +background-color: &dtml-contentViewBorderColor;; +color: White; +} + +.actionMenu .actionMenuContent .actionSeparator a { +margin-top: 0.2em; +padding-top: 0.2em; +border-top: &dtml-borderWidth; &dtml-borderStyle; &dtml-contentViewBorderColor;; +} + +.actionMenu .actionMenuContent .actionSeparator div.currentDefaultPage { +margin-top: 0.2em; +padding: 0.2em 0.5em 0em 0.5em; +white-space: nowrap; +border-top: &dtml-borderWidth; &dtml-borderStyle; &dtml-contentViewBorderColor;; +} + +.actionMenu .actionMenuContent .actionSeparator div.actionLabel { +margin-top: 0.2em; +padding: 0.2em 0.5em 0em 0.5em; +white-space: nowrap; +border-top: &dtml-borderWidth; &dtml-borderStyle; &dtml-contentViewBorderColor;; +background-color: &dtml-contentViewBorderColor;; +color: &dtml-contentViewBackgroundColor;; +cursor: default; +} + + +.contentBatchAction { +float: left !important; +padding: 0 0.5em; +border-top: &dtml-borderWidth; &dtml-borderStyle; &dtml-contentViewBorderColor;; +border-right: &dtml-borderWidth; &dtml-borderStyle; &dtml-contentViewBorderColor;; +border-left: none !important; +border-collapse: collapse; +position: relative; +top: -1px; +margin-left: -0.5em !important; +} + +#objectMenu.actionMenu .actionMenuContent li { +display: block; +} + +#objectMenu.actionMenu .actionMenuContent li, +#objectMenu.actionMenu .actionMenuContent li a:hover { +background-position: 3px 50%; +margin-left: 0; +} + +#objectMenu.actionMenu .actionMenuContent li a { +padding-left: 22px; +} + +.actionMenuSelected { +display: block; +cursor: default; +background-image: url(/bullet_icon.gif); +background-repeat: no-repeat; +background-position: 0% 3px; +padding-left: 16px !important; +} + +#templateMenu li a { +padding-left: 16px; +} + + +/* +** end ECMAScript Content Action Menus +*/ + + +/* Collapsible elements */ + +dl.collapsible { +border: &dtml-borderWidth; &dtml-borderStyle; &dtml-globalBorderColor; !important; +margin: 1em 0 0 0; +padding: 0; +} + +dl.collapsible dt.collapsibleHeader { +display: block; +float: left; +background: &dtml-backgroundColor;; +line-height: 1.2em; +vertical-align: middle; +font-size: 90%; +position: relative; +top: -0.6em; +width: auto; +margin: 0 0 -0.6em 1em; +padding: 0 0.5em; +} + +dl.collapsible dd.collapsibleContent { +margin: 0; +padding: 0 1em; +clear: left; +} + +/* for IE the following isn't needed, that's why the css2 selector is used */ +dl.collapsible dd.collapsibleContent > dl { +margin: 0; +padding: 0; +} + +dl.expandedInlineCollapsible dt.collapsibleHeader, +dl.expandedBlockCollapsible dt.collapsibleHeader { +padding: 0 6px 0 22px; +background: &dtml-backgroundColor; url(treeExpanded.gif) no-repeat 6px 50%; +cursor: pointer; +} + +dl.collapsedBlockCollapsible { +border: none !important; +height: 1em; +width: auto; +} + +dl.collapsedBlockCollapsible dt.collapsibleHeader { +float: none; +position: static; +margin: 0; +padding: 0 0 0 22px; +line-height: 1em; +background: transparent url(treeCollapsed.gif) no-repeat 6px 50%; +cursor: pointer; +} + +dl.collapsedInlineCollapsible dd.collapsibleContent, +dl.collapsedBlockCollapsible dd.collapsibleContent { +display: none; +} + +dl.collapsedInlineCollapsible { +border: none !important; +height: 1em; +width: auto; +display: inline; +} + +dl.collapsedInlineCollapsible dt.collapsibleHeader { +position: static; +float: none; +margin: 0; +padding: 0 0 0 22px; +line-height: 1em; +background: transparent url(treeCollapsed.gif) no-repeat 6px 50%; +cursor: pointer; +display: inline; +} + +.configlet .documentEditable { +padding: 0em !important; +} + +.documentEditable .documentContent { +border: &dtml-borderWidth; &dtml-borderStyle; &dtml-contentViewBorderColor;; +padding: 10px; + +} +.kupu-html, .kupu-html .documentContent{ + text-align: left; +} + +.label { +font-weight: bold; +display: inline; +padding-right: 0.5em; +} + +.optionsToggle { +border: &dtml-borderWidth; &dtml-borderStyle; &dtml-globalBorderColor;; +color: &dtml-fontColor;; +background-color: &dtml-globalBackgroundColor;; +font-weight: normal !important; +font-size: &dtml-fontSmallSize;; +} + +.portalNotLoggedIn {} /* Used on all descriptions relevant to those not logged in */ + +#portal-column-content fieldset > * input:focus, +#portal-column-content fieldset > * textarea:focus { +border-color: &dtml-notifyBorderColor;; +border-width: &dtml-borderWidth;; +} + +.visualOverflow { +overflow: auto; +margin: 0 0 1em 0; +} + +.visualOverflow pre, +.visualOverflow table, +.visualOverflow img { +margin: 0; +} + +.visualFontSizeCorrection { /* Correction for WYSIWYG editors */ +font-size: 75%; +background: transparent; +background-image: none; +} + + +/* for highlighting of search terms */ + +.highlightedSearchTerm { +background-color: #feff82; +} + +/* for greying out inherited roles */ + +.noInheritedRoles { +color: #a0a0a0; +} + +/* for highlighting current items, like the language or today in the calendar */ + +.currentItem { +border-collapse: collapse; +border: 2px &dtml-borderStyle; &dtml-notifyBorderColor;; +padding: 1px; +} + +/* Styles to make the editing widgets look more like their view counterparts */ + +#archetypes-fieldname-title input { +font-size: 160%; +font-family: ; +font-weight: normal; +width: 99%; +} + +#archetypes-fieldname-description textarea { +font: 100% ; +font-weight: bold; +} + +/* for draggable elements */ + +tr.dragging td { +background-color: yellow; +} + +.draggingHook { +cursor: move; +} + +.notDraggable { +} + +/* */ \ No newline at end of file Added: kukit/KssTheme/trunk/skins/ksstheme_styles/base.css.dtml ============================================================================== --- (empty file) +++ kukit/KssTheme/trunk/skins/ksstheme_styles/base.css.dtml Thu Oct 4 21:22:22 2007 @@ -0,0 +1,302 @@ +/* + This file is based on the ploneCustom.css.dtml shipped with Plone. + + (do not remove this) + (not this either) +*/ + +/* YOUR CSS RULES START HERE */ + +body{ + font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; + font-size: 0.7em; + background-color: #FAFAED; + color: #333333; + margin: 0 auto; + text-align: center; + padding: opx; +} +#visual-portal-wrapper{ + width: 955px; + text-align: left; + margin:10px auto; + padding: 0px; + background-color: #fafaed; + position: relative; +} +.hiddenStructure { + display: none; +} + +#portal-logo{ + display:block; + padding: 0px; + margin:5px 5px 0px 5px; +} + +#portal-logo a { + display: block; + text-decoration: none; + overflow: hidden; + border: 0; + margin-top: 0px; + background: url(&dtml-portal_url;/logo.gif) no-repeat; + padding: 0; + padding-top: 158px; + height: 0px !important; + width: 218px; + cursor: pointer; +} +#Icon{ + float:right; + margin-right: 45px; + width: 650px; +} + +#Icon a{ + display: block; + float:right; + width: 149px; + height: 153px; + margin: 0 40px 0 10px; + text-decoration: none; +} +#Icon a.down{ background: url(&dtml-portal_url;/icon_down.gif) no-repeat;} +#Icon a.demo{ background: url(&dtml-portal_url;/icon_demo.gif) no-repeat;} +#Icon a.doc{ background: url(&dtml-portal_url;/icon_doc.gif) no-repeat;} + +/** Headlines & other basics */ +H1{ + font-size:180%; + color: #ff4916; +} + +p{} + +a { color: #ff4916;} + +img, img a{ border:none;} + +input{ border: 1px solid #A8A890;} + +/* Navigation & breadcrumb & personalbar*/ +#portal-globalnav { + background-color: #A8A890; + padding: 10px 8px 10px 8px; + margin:0px 0px 0px 11px; + +} +#portal-globalnav li{ + display: inline; + padding: 0px 8px 0px 8px; + border-right: 2px solid #ffffff; +} +#portal-globalnav li a{ + color:#ffffff; + font-weight: bold; + text-decoration: none; +} +#portal-globalnav li a:hover{ color:#f0f0d8;} +#portal-breadcrumbs{ + position: absolute; + left:212px; + height:16px; + padding: 5px 15px 0px 20px; + color: #ffffff; + background: url(&dtml-portal_url;/breadcrumb-bg.gif) left top; +} +#portal-breadcrumbs a{ + color: #ffffff; + text-decoration: none; + font-weight: bold; +} +#portal-breadcrumbs a:hover{ + color: #A8A890; +} +#portal-breadcrumbs .breadcrumbs-end{ + background: url(&dtml-portal_url;/breadcrumb-end.gif) no-repeat right top; + padding:8px 15px 0px 0px; + top: 0px; + right:-3px; + position: absolute; +} +#portal-breadcrumbs .breadcrumbSeparator{ + background-image: url(&dtml-portal_url;/breadcrumb-pijl.gif); + padding: 2px 5px 0px 0px; +} + +/** columns */ +#portal-columns{ + /*margin: 0 0 0 4px;*/ + height: 500px; + border-right: #A8A890 1px solid; +} + +#portal-column-content{ +/* border-bottom: #A8A890 1px solid; + border-right: #A8A890 1px solid;*/ +} + +/** Jeroen vragen **/ +#portal-personaltools-wrapper{ + position:absolute; + right: 0px; +} +#portal-personaltools{ + list-style:none; +/*float: right;*/ + margin:0px; +} +#portal-personaltools li{ + display: inline; + padding:3px 5px 0 5px; +} + +#portal-column-one{ + background: url(&dtml-portal_url;/bg-left.gif) left top repeat-y; + width: 218px !important; +} + +#portal-column-content #content{ + margin: 40px 10px 10px 25px; +} + +.documentActions{ display: none;} +h1.documentFirstHeading{ border-bottom:2px solid #A8A890;} +.documentByLine{ display:none;} +.documentDescription{ font-weight: bold;} + +#portal-footer{ + border-top: #A8A890 1px solid; + margin-left: 11px; +} +#portal-footer #portal-siteactions{ + list-style: none; + text-align: center; +} +#portal-footer #portal-siteactions #siteaction-sitemap{ + border-left: 1px solid #FF4916; +} +#portal-footer #portal-siteactions li{ + display: inline; + padding: 0 8px 0 5px; + border-right: 1px solid #FF4916; + font-size: 90%; +} + +#portal-footer #portal-siteactions li a{ + text-decoration: none; +} + +input.searchButton{ + background-image: none !important; + padding: 1px 3px 1px 3px !important; + color:#FF4916; +} +.portlets .LSBox{ + padding-bottom: 5px; +} +/** news item view*/ +.newsImageContainer{ + float: left; + padding: 0 5px 0px 0px; +} +.discreet{ + font-size: 80%; + padding: 0px; + margin:0px; + color:#FF4916; + text-decoration: none; +} +/**samenvattings weergave view*/ +.tileItem { + border-bottom: #FF4916 1px solid; +} +.tileHeadline a { + text-decoration: none; + font-size:75%; +} +.tileFooter{ + text-align: right; + clear: both; +} +.tileFooter a{ + text-decoration: none; +} +.tileImage{ + float: left; + padding: 0 5px 5px 0px; +} +.link-parent{ + display: none; +} +/** photo album **/ +.photoAlbumEntry{ + display: block; + float:left; + margin: 0 30px 0 0; + height: 160px; +} +.photoAlbumEntry .photoAlbumEntryWrapper{ + display:block; + padding-bottom: 5px; +} +.photoAlbumEntry{ + text-align: center; +} +.visualClear{ + clear: both; +} +.photoAlbumEntry a{ +text-decoration: none; + +} +.listingBar{ + background-color: #F0F0D8; + border: #A8A890 1px solid; + padding: 5px; + color: #333333; + font-weight: bold; +} +.listingBar a{ + color: #333333; + font-weight: normal; + text-decoration: none; + +} +/** kupu styles */ +dt{ + font-weight: bold; +} +table.listing th, +.stx table th { + background: #F0F0D8; + border-top: 1px solid #A8A890 ; + border-bottom: 1px solid #A8A890 ; + border-right: 1px solid #A8A890 ; + font-weight: normal; + padding: 0.25em 1em; + text-transform: lowercase; +} +table.listing { + border-left: 1px solid #A8A890 ; + border-top: 1px solid #A8A890 ; + border-right: 1px solid #A8A890 ; + border-bottom: 1px solid #A8A890 ; + text-align: left; + padding: 0em 0em 1em 0em; +} +table.vertical td{ + border-bottom: 1px solid #A8A890 ; +} +table.listing td{ + border-right: 1px solid #A8A890; + padding: 0.25em 1em; +} +/* YOUR CSS RULES STOP HERE */ + +/* */ + +/* Latest version of the documentation on pre-defined properties from Plone + can be found in CMFPlone/skins/plone_styles/ploneCustom.css.dtml */ + Added: kukit/KssTheme/trunk/skins/ksstheme_styles/base_properties.props ============================================================================== --- (empty file) +++ kukit/KssTheme/trunk/skins/ksstheme_styles/base_properties.props Thu Oct 4 21:22:22 2007 @@ -0,0 +1,47 @@ +title:string=KssTheme's color, font, logo and border defaults + +plone_skin:string=KssTheme + +logoName:string=logo.gif + +fontFamily:string="Verdana", Lucida, Helvetica, Arial, sans-serif +fontBaseSize:string=69% +fontColor:string=#333333 +fontSmallSize:string=85% + +backgroundColor:string=#fafaed + +linkColor:string=#FF4916 +linkActiveColor:string=#FF4916 +linkVisitedColor:string=#fafaed + +borderWidth:string=1px +borderStyle:string=solid +borderStyleAnnotations:string=dashed + +globalBorderColor:string=#8cacbb +globalBackgroundColor:string=#dee7ec +globalFontColor:string=#436976 + +headingFontFamily:string="Verdana", Lucida, Helvetica, Arial, sans-serif + +contentViewBorderColor:string=#A8A890 +contentViewBackgroundColor:string=#D8D8C0 +contentViewFontColor:string=#333333 + +inputFontColor:string=Black + +textTransform:string=lowercase + +evenRowBackgroundColor:string=#eef3f5 +oddRowBackgroundColor:string=transparent + +notifyBorderColor:string=#ffa500 +notifyBackgroundColor:string=#ffce7b + +discreetColor:string=#76797c +helpBackgroundColor:string=#ffffe1 + +portalMinWidth:string=70em +columnOneWidth:string=16em +columnTwoWidth:string=16em Added: kukit/KssTheme/trunk/skins/ksstheme_styles/generated.css.dtml ============================================================================== --- (empty file) +++ kukit/KssTheme/trunk/skins/ksstheme_styles/generated.css.dtml Thu Oct 4 21:22:22 2007 @@ -0,0 +1,24 @@ +/* + This file is based on the ploneCustom.css.dtml shipped with Plone. + + (do not remove this) + (not this either) +*/ + +/* YOUR CSS RULES START HERE */ + +.portalMessage{ + background-color: #ff4916; + border: #A8A890 1px solid; + padding: 5px; + color: #ffffff; + margin-bottom: 3px; +} + +/* YOUR CSS RULES STOP HERE */ + +/* */ + +/* Latest version of the documentation on pre-defined properties from Plone + can be found in CMFPlone/skins/plone_styles/ploneCustom.css.dtml */ + Added: kukit/KssTheme/trunk/skins/ksstheme_styles/ie6.css.dtml ============================================================================== --- (empty file) +++ kukit/KssTheme/trunk/skins/ksstheme_styles/ie6.css.dtml Thu Oct 4 21:22:22 2007 @@ -0,0 +1,10 @@ +.CustomPortletNavigation li ul li a{ + width:163px; +} +#Icon{ margin-right: 5px;} + +.portlets { + border-top: #FF4916 1px solid ; + border-bottom: #FF4916 1px solid; + margin: 15px 6px 0px 8px; +} \ No newline at end of file Added: kukit/KssTheme/trunk/skins/ksstheme_styles/ie7.css.dtml ============================================================================== --- (empty file) +++ kukit/KssTheme/trunk/skins/ksstheme_styles/ie7.css.dtml Thu Oct 4 21:22:22 2007 @@ -0,0 +1,8 @@ +.portlets { + border-top: #FF4916 1px solid ; + border-bottom: #FF4916 1px solid; + margin: 15px 6px 0px 8px; +} +.tileItem { + margin-bottom: 10px; +} \ No newline at end of file Added: kukit/KssTheme/trunk/skins/ksstheme_styles/ksstheme.css.dtml ============================================================================== --- (empty file) +++ kukit/KssTheme/trunk/skins/ksstheme_styles/ksstheme.css.dtml Thu Oct 4 21:22:22 2007 @@ -0,0 +1,18 @@ +/* + This file is based on the ploneCustom.css.dtml shipped with Plone. + + (do not remove this) + (not this either) +*/ + +/* YOUR CSS RULES START HERE */ + + + +/* YOUR CSS RULES STOP HERE */ + +/* */ + +/* Latest version of the documentation on pre-defined properties from Plone + can be found in CMFPlone/skins/plone_styles/ploneCustom.css.dtml */ + Added: kukit/KssTheme/trunk/skins/ksstheme_styles/portlets.css.dtml ============================================================================== --- (empty file) +++ kukit/KssTheme/trunk/skins/ksstheme_styles/portlets.css.dtml Thu Oct 4 21:22:22 2007 @@ -0,0 +1,98 @@ +/* + This file is based on the ploneCustom.css.dtml shipped with Plone. + + (do not remove this) + (not this either) +*/ + +/* YOUR CSS RULES START HERE */ +/** navigation**/ +#portal-column-one .visualPadding{ + margin-top: 40px; + margin-left: 4px; +} + +.CustomPortletNavigation{ + margin: 0px; + padding: 0px; +} +.CustomPortletNavigation li{ + list-style: none; + color: #A8A890; +} +.CustomPortletNavigation li a{ + background: url(&dtml-portal_url;/menu.gif) left top no-repeat; + font-weight: bold; + text-decoration: none; + color: #A8A890; + padding: 5px 5px 3px 20px; + display: block; + height: 14px; + width:191px; +} +.CustomPortletNavigation li a:hover, .CustomPortletNavigation li a.active { + background: url(&dtml-portal_url;/menu-ov.gif) left top no-repeat; +} +.CustomPortletNavigation li ul { + background: #FAFAED; + width: 200px; + margin: 0 0 0 8px; + padding: 8px 0px 3px 0px; +} +.CustomPortletNavigation li ul li{ + margin-left:14px; +} +.CustomPortletNavigation li ul li a{ + background: url(&dtml-portal_url;/submenu.gif) left top no-repeat; + font-weight: normal; + padding: 0px 5px 3px 15px; + display: block; + height: 14px; + width:196px; +} + +.CustomPortletNavigation li ul li a:hover, .CustomPortletNavigation li ul li a.active { + background: url(&dtml-portal_url;/submenu-ov.gif) left top no-repeat; +} +/**portlet news*/ +.portlets { + border-top: #FF4916 1px solid ; + border-bottom: #FF4916 1px solid; + margin: 15px 8px 0px 8px; +} +.portlets .news{ + border-bottom: #A8A890 1px solid; + padding: 5px; + background-color: #F0F0D8; +} + +.portlets .news .portlettitle { + margin-bottom: 8px; +} +.portlets .news .portlettitle a, .portlets .news .morenews a{ + font-weight: bold; + text-decoration: none; +} +.portlets .news .morenews{ + text-align: right; + margin: 5px 0 5px 0; +} + +#search{ + padding: 5px; + background-color: #F0F0D8; +} +.portlets .search-title{ + font-weight: bold; + color: #FF4916; + margin: 5px 0 5px 0; +} + + +/* YOUR CSS RULES STOP HERE */ + +/* */ + +/* Latest version of the documentation on pre-defined properties from Plone + can be found in CMFPlone/skins/plone_styles/ploneCustom.css.dtml */ + Added: kukit/KssTheme/trunk/skins/ksstheme_styles/public.css.dtml ============================================================================== --- (empty file) +++ kukit/KssTheme/trunk/skins/ksstheme_styles/public.css.dtml Thu Oct 4 21:22:22 2007 @@ -0,0 +1,18 @@ +/* + This file is based on the ploneCustom.css.dtml shipped with Plone. + + (do not remove this) + (not this either) +*/ + +/* YOUR CSS RULES START HERE */ + + + +/* YOUR CSS RULES STOP HERE */ + +/* */ + +/* Latest version of the documentation on pre-defined properties from Plone + can be found in CMFPlone/skins/plone_styles/ploneCustom.css.dtml */ + Added: kukit/KssTheme/trunk/skins/ksstheme_templates/fetchRecentNews.py ============================================================================== --- (empty file) +++ kukit/KssTheme/trunk/skins/ksstheme_templates/fetchRecentNews.py Thu Oct 4 21:22:22 2007 @@ -0,0 +1 @@ +return context.portal_catalog(portal_type='News Item', review_state='published' ,sort_on='modified', sort_order='reverse', sort_limit=2) Added: kukit/KssTheme/trunk/skins/ksstheme_templates/footer.pt ============================================================================== --- (empty file) +++ kukit/KssTheme/trunk/skins/ksstheme_templates/footer.pt Thu Oct 4 21:22:22 2007 @@ -0,0 +1,13 @@ + + + + + + + Added: kukit/KssTheme/trunk/skins/ksstheme_templates/global_pathbar.pt ============================================================================== --- (empty file) +++ kukit/KssTheme/trunk/skins/ksstheme_templates/global_pathbar.pt Thu Oct 4 21:22:22 2007 @@ -0,0 +1,40 @@ + + + + + +
+ + You +are here: + Home + +   + » + + + + + crumb + + +   + » + + crumb + + +   + +
+ + \ No newline at end of file Added: kukit/KssTheme/trunk/skins/ksstheme_templates/header.pt ============================================================================== --- (empty file) +++ kukit/KssTheme/trunk/skins/ksstheme_templates/header.pt Thu Oct 4 21:22:22 2007 @@ -0,0 +1,147 @@ + + + + + + + + <tal:pagetitle replace="page_title"> + Inserts page title + </tal:pagetitle> + — + <tal:portaltitle replace="portal_title"> + Inserts portal title + </tal:portaltitle> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Inserts rel links specified from a page. + + + + + + + Inserts CSS specified from a page. + + + + This is deprecated, please use style_slot instead. + + + + Flexibility for published templates to inject stuff into the head tag. + + + + Inserts javascript specified from a page. + + + + + + + + + + + + + + + \ No newline at end of file Added: kukit/KssTheme/trunk/skins/ksstheme_templates/main_template.pt ============================================================================== --- (empty file) +++ kukit/KssTheme/trunk/skins/ksstheme_templates/main_template.pt Thu Oct 4 21:22:22 2007 @@ -0,0 +1,207 @@ + + + + + + + + + Get the global cache headers located in global_cache_settings. + + + + + + + + + + + + + + A slot where you can insert elements in the header from a template + + + + A slot where you can insert CSS in the header from a template + + + + + This is deprecated, please use style_slot instead. + + + + + A slot where you can insert javascript in the header from a template + + + + + + +
+ +
+ +
+

+ Skip to content. | + + Skip to navigation +

+ +
+   +   +   +
+ + The portal logo, linked to the portal root + + + +
+ The skin switcher tabs. Based on which role you have, you + get a selection of skins that you can switch between. +
+ +
+ The global sections tabs. (Welcome, News etc) +
+
+ +
+ The personal bar. (log in, logout etc...) +
+ +
+ The breadcrumb navigation ("you are here") +
+
+ +
+ + + The wrapper table. It contains the three columns. There's a table-less + alternative in the plone_tableless skin layer that you can use if you + prefer layouts that don't use tables. + + +
+ + + Start of the left column + + End of the left column + + Start of main content block + + End of main content block + + Start of right column + + End of the right column + + +
+
+ + + This instruction gets the portlets (boxes) for the left column. + + +   +
+
+ + +
+ + +
+ The content views (View, Edit, Properties, Workflow) +
+ +
+ The content bar +
+
+ +
+ + + +
+ Portal status message +
+ + + Visual Header + + + + Page body text + + + + + + +
+ +
+ +
+
+
+ + + This instruction gets the portlets (boxes) for the right column. + + +   +
+
+ end column wrapper + + + + + + + + Footer + + + + + + + + + + + \ No newline at end of file Added: kukit/KssTheme/trunk/skins/ksstheme_templates/portlet_login.pt ============================================================================== --- (empty file) +++ kukit/KssTheme/trunk/skins/ksstheme_templates/portlet_login.pt Thu Oct 4 21:22:22 2007 @@ -0,0 +1,16 @@ + + +
+ +
+ + \ No newline at end of file Added: kukit/KssTheme/trunk/skins/ksstheme_templates/portlet_navigation.pt ============================================================================== --- (empty file) +++ kukit/KssTheme/trunk/skins/ksstheme_templates/portlet_navigation.pt Thu Oct 4 21:22:22 2007 @@ -0,0 +1,27 @@ + + +
+ + + +
+ + \ No newline at end of file Added: kukit/KssTheme/trunk/skins/ksstheme_templates/portlet_news.pt ============================================================================== --- (empty file) +++ kukit/KssTheme/trunk/skins/ksstheme_templates/portlet_news.pt Thu Oct 4 21:22:22 2007 @@ -0,0 +1,18 @@ + + +
+
+
+
+
+ + +
+
+
+ + \ No newline at end of file Added: kukit/KssTheme/trunk/update_info.txt ============================================================================== --- (empty file) +++ kukit/KssTheme/trunk/update_info.txt Thu Oct 4 21:22:22 2007 @@ -0,0 +1 @@ +https://zopedev.pareto.nl/svn/Kss/KssTheme/tags/ \ No newline at end of file Added: kukit/KssTheme/trunk/version.txt ============================================================================== --- (empty file) +++ kukit/KssTheme/trunk/version.txt Thu Oct 4 21:22:22 2007 @@ -0,0 +1 @@ +1.0 \ No newline at end of file From jvloothuis at codespeak.net Thu Oct 4 21:33:35 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Thu, 4 Oct 2007 21:33:35 +0200 (CEST) Subject: [KSS-checkins] r47161 - kukit/buildout/kss-website Message-ID: <20071004193335.2905381A8@code0.codespeak.net> Author: jvloothuis Date: Thu Oct 4 21:33:34 2007 New Revision: 47161 Added: kukit/buildout/kss-website/ Log: buildout for the kss website From jvloothuis at codespeak.net Thu Oct 4 21:39:20 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Thu, 4 Oct 2007 21:39:20 +0200 (CEST) Subject: [KSS-checkins] r47162 - in kukit/buildout/kss-website: . develop-eggs products src Message-ID: <20071004193920.5C9E681A9@code0.codespeak.net> Author: jvloothuis Date: Thu Oct 4 21:39:19 2007 New Revision: 47162 Added: kukit/buildout/kss-website/README.txt kukit/buildout/kss-website/bootstrap.py kukit/buildout/kss-website/buildout.cfg kukit/buildout/kss-website/develop-eggs/ kukit/buildout/kss-website/products/ kukit/buildout/kss-website/products/EXTERNALS.txt kukit/buildout/kss-website/products/README.txt kukit/buildout/kss-website/src/ kukit/buildout/kss-website/src/README.txt Log: Add initial buildout stuff Added: kukit/buildout/kss-website/README.txt ============================================================================== --- (empty file) +++ kukit/buildout/kss-website/README.txt Thu Oct 4 21:39:19 2007 @@ -0,0 +1,327 @@ +======================= +Using a custom buildout +======================= + +Note: If you are using Windows, if you do not have PIL installed, or you are +not using Python 2.4 as your main system Python, please see the relevant +sections below. + +You probably got here by running something like: + + $ paster create -t plone3_buildout + +Now, you need to run: + + $ python bootstrap.py + +This will install zc.buildout for you. + +To create an instance immediately, run: + + $ bin/buildout + +This will download Plone's products for you, as well as other dependencies, +create a new Zope 2 installation (unless you specified an existing one when +you ran "paster create"), and create a new Zope instance configured with these +products. + +You can start your Zope instance by running: + + $ bin/instance start + +or, to run in foreground mode: + + $ bin/instance fg + +To run unit tests, you can use: + + $ bin/instance test -s my.package + +Installing PIL +-------------- + +To use Plone, you need PIL, the Python Imaging Library. If you don't already +have this, download and install it from http://www.pythonware.com/products/pil. + +Using a different Python installation +-------------------------------------- + +Buildout will use your system Python installation by default. However, Zope +2.10 (and by extension, Plone) will only work with Python 2.4. You can verify +which version of Python you have, by running: + + $ python -V + +If that is not a 2.4 version, you need to install Python 2.4 from +http://python.org. If you wish to keep another version as your main system +Python, edit buildout.cfg and add an 'executable' option to the "[buildout]" +section, pointing to a python interpreter binary: + + [buildout] + ... + executable = /path/to/python + +Working with buildout.cfg +------------------------- + +You can change any option in buildout.cfg and re-run bin/buildout to reflect +the changes. This may delete things inside the 'parts' directory, but should +keep your Data.fs and source files intact. + +To save time, you can run buildout in "offline" (-o) and non-updating (-N) +mode, which will prevent it from downloading things and checking for new +versions online: + + $ bin/buildout -Nov + +Creating new eggs +----------------- + +New packages you are working on (but which are not yet released as eggs and +uploaded to the Python Package Index, aka PYPI) should be placed in src. You can do: + + $ cd src/ + $ paster create -t plone my.package + +Use "paster create --list-templates" to see all available templates. Answer +the questions and you will get a new egg. Then tell buildout about your egg +by editing buildout.cfg and adding your source directory to 'develop': + + [buildout] + ... + develop = + src/my.package + +You can list multiple packages here, separated by whitespace or indented +newlines. + +You probably also want the Zope instance to know about the package. Add its +package name to the list of eggs in the "[instance]" section, or under the +main "[buildout]" section: + + [instance] + ... + eggs = + ${buildout:eggs} + ${plone:eggs} + my.package + +Leave the ${buildout:eggs} part in place - it tells the instance to use the +eggs that buildout will have downloaded from the Python Package Index +previously. + +If you also require a ZCML slug for your package, buildout can create one +automatically. Just add the package to the 'zcml' option: + + [instance] + ... + zcml = + my.package + +When you are finished, re-run buildout. Offline, non-updating mode should +suffice: + + $ bin/buildout -Nov + +Developing old-style products +----------------------------- + +If you are developing old-style Zope 2 products (not eggs) then you can do so +by placing the product code in the top-level 'products' directory. This is +analogous to the 'Products/' directory inside a normal Zope 2 instance and is +scanned on start-up for new products. + +Depending on a new egg +---------------------- + +If you want to use a new egg that is in the Python Package Index, all you need +to do is to add it to the "eggs" option under the main "[buildout]" section: + + [buildout] + ... + eggs = + my.package + +If it's listed somewhere else than the Python Package Index, you can add a link +telling buildout where to find it in the 'find-links' option: + + [buildout] + ... + find-links = + http://dist.plone.org + http://download.zope.org/distribution/ + http://effbot.org/downloads + http://some.host.com/packages + +Using existing old-style products +--------------------------------- + +If you are using an old-style (non-egg) product, you can either add it as an +automatically downloaded archive or put it in the top-level "products" folder. +The former is probably better, because it means you can redistribute your +buildout.cfg more easily: + + [productdistros] + recipe = plone.recipe.distros + urls = + http://plone.org/products/someproduct/releases/1.3/someproduct-1.3.tar.gz + +If someproduct-1.3.tar.gz extracts into several products inside a top-level +directory, e.g. SomeProduct-1.3/PartOne and SomeProduct-1.3/PartTwo, then +add it as a "nested package": + + [productdistros] + recipe = plone.recipe.distros + urls = + http://plone.org/products/someproduct/releases/1.3/someproduct-1.3.tar.gz + nested-packages = + someproduct-1.3.tar.gz + +Alternatively, if it extracts to a directory which contains the version +number, add it as a "version suffix package": + + [productdistros] + recipe = plone.recipe.distros + urls = + http://plone.org/products/someproduct/releases/1.3/someproduct-1.3.tar.gz + version-suffix-packages = + someproduct-1.3.tar.gz + +You can also track products by adding a new bundle checkout part. It +doesn't strictly have to be an svn bundle at all, any svn location will do, +and cvs is also supported: + + [buildout] + ... + parts = + plone + zope2 + productdistros + myproduct + instance + zopepy + +Note that "myproduct" comes before the "instance" part. You then +need to add a new section to buildout.cfg: + + [myproduct] + recipe = plone.recipe.bundlecheckout + url = http://svn.plone.org/svn/collective/myproduct/trunk + +Finally, you need to tell Zope to find this new checkout and add it to its +list of directories that are scanned for products: + + [instance] + ... + products = + ${buildout:directory}/products + ${productdistros:location} + ${plonebundle:location} + ${myproduct:location} + +Without this last step, the "myproduct" part is simply managing an svn +checkout and could potentially be used for something else instead. + +============= +Using Windows +============= + +To use buildout on Windows, you will need to install a few dependencies which +other platforms manage on their own. + +Here are the steps you need to follow (thanks to Hanno Schlichting for these): + +Python (http://python.org) +-------------------------- + + - Download and install Python 2.4.4 using the Windows installer from + http://www.python.org/ftp/python/2.4.4/python-2.4.4.msi + Select 'Install for all users' and it will put Python into the + "C:\Python24" folder by default. + + - You also want the pywin32 extensions available from + http://downloads.sourceforge.net/pywin32/pywin32-210.win32-py2.4.exe?modtime=1159009237&big_mirror=0 + + - And as a last step you want to download the Python imaging library available + from http://effbot.org/downloads/PIL-1.1.6.win32-py2.4.exe + + - If you develop Zope based applications you will usually only need Python 2.4 + at the moment, so it's easiest to put the Python binary on the systems PATH, + so you don't need to specify its location manually each time you call it. + + Thus, put "C:\Python24" and "C:\Python24\Scripts" onto the PATH. You can + find the PATH definition in the control panel under system preferences on + the advanced tab at the bottom. The button is called environment variables. + You want to add it at the end of the already existing PATH in the system + section. Paths are separated by a semicolons. + + - You can test if this was successful by opening a new shell (cmd) and type + in 'python -V'. It should report version 2.4.4 (or whichever version you + installed). + + Opening a new shell can be done quickly by using the key combination + 'Windows-r' or if you are using Parallels on a Mac 'Apple-r'. Type in 'cmd' + into the popup box that opens up and hit enter. + + +Subversion (http://subversion.tigris.org) +----------------------------------------- + + - Download the nice installer from + http://subversion.tigris.org/files/documents/15/35379/svn-1.4.2-setup.exe + + - Run the installer. It defaults to installing into + "C:\Program Files\Subversion". + + - Now put the install locations bin subfolder (for example + "C:\Program Files\Subversion\bin") on your system PATH in the same way you + put Python on it. + + - Open a new shell again and type in: 'svn --version' it should report + version 1.4.2 or newer. + + +MinGW (http://www.mingw.org/) +----------------------------- + + This is a native port of the gcc compiler and its dependencies for Windows. + There are other approaches enabling you to compile Python C extensions on + Windows including Cygwin and using the official Microsoft C compiler, but this + is a lightweight approach that uses only freely available tools. As + it's used by a lot of people chances are high it will work for you and there's + plenty of documentation out there to help you in troubleshooting problems. + + - Download the MinGW installer from + http://downloads.sourceforge.net/mingw/MinGW-5.1.3.exe?modtime=1168794334&big_mirror=1 + + - The installer will ask you which options you would like to install. Choose + base and make here. It will install into "C:\MinGW" by default. The install + might take some time as it's getting files from sourceforge.net and you + might need to hit 'retry' a couple of times. + + - Now put the install location's bin subfolder (for example "C:\MinGW\bin") on + your system PATH in the same way you put Python on it. + + - Test this again by typing in: 'gcc --version' on a newly opened shell and + it should report version 3.4.2 or newer. + + +Configure Distutils to use MinGW +-------------------------------- + + Some general information are available from + http://www.mingw.org/MinGWiki/index.php/Python%20extensions for example but + you don't need to read them all. + + - Create a file called 'distutils.cfg' in "C:\Python24\Lib\distutils". Open it + with a text editor ('notepad distutils.cfg') and fill in the following lines: + + [build] + compiler=mingw32 + + This will tell distutils to use MinGW as the default compiler, so you don't + need to specify it manually using "--compiler=mingw32" while calling a + package's setup.py with a command that involves building C extensions. This + is extremely useful if the build command is written down in a buildout + recipe where you cannot change the options without hacking the recipe + itself. The z2c.recipe.zope2install used in ploneout is one such example. Added: kukit/buildout/kss-website/bootstrap.py ============================================================================== --- (empty file) +++ kukit/buildout/kss-website/bootstrap.py Thu Oct 4 21:39:19 2007 @@ -0,0 +1,55 @@ +############################################################################## +# +# 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() + +try: + import pkg_resources +except ImportError: + 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) Added: kukit/buildout/kss-website/buildout.cfg ============================================================================== --- (empty file) +++ kukit/buildout/kss-website/buildout.cfg Thu Oct 4 21:39:19 2007 @@ -0,0 +1,78 @@ +[buildout] +parts = + plone + zope2 + productdistros + instance + zopepy + +# Add additional egg download sources here. dist.plone.org contains archives +# of Plone packages. +find-links = + http://dist.plone.org + http://download.zope.org/ppix/ + http://download.zope.org/distribution/ + http://effbot.org/downloads + +# Add additional eggs here +# elementtree is required by Plone +eggs = + elementtree + +# Reference any eggs you are developing here, one per line +# e.g.: develop = src/my.package +develop = + +[plone] +recipe = plone.recipe.distros +urls = http://plone.googlecode.com/files/Plone-2.5.3-final.tar.gz +nested-packages = Plone-2.5.3-final.tar.gz +version-suffix-packages = Plone-2.5.3-final.tar.gz + +[zope2] +recipe = plone.recipe.zope2install +url = http://www.zope.org/Products/Zope/2.9.8/Zope-2.9.8-final.tgz + +# Use this section to download additional old-style products. +# List any number of URLs for product tarballs under URLs (separate +# with whitespace, or break over several lines, with subsequent lines +# indented). If any archives contain several products inside a top-level +# directory, list the archive file name (i.e. the last part of the URL, +# normally with a .tar.gz suffix or similar) under 'nested-packages'. +# If any archives extract to a product directory with a version suffix, list +# the archive name under 'version-suffix-packages'. +[productdistros] +recipe = plone.recipe.distros +urls = +nested-packages = +version-suffix-packages = + +[instance] +recipe = plone.recipe.zope2instance +zope2-location = ${zope2:location} +user = admin: +http-address = 8080 +debug-mode = on +verbose-security = on + +# If you want Zope to know about any additional eggs, list them here. +# This should include any development eggs you listed in develop-eggs above, +# e.g. eggs = ${buildout:eggs} my.package +eggs = + ${buildout:eggs} + +# If you want to register ZCML slugs for any packages, list them here. +# e.g. zcml = my.package my.other.package +zcml = + +products = + ${buildout:directory}/products + ${productdistros:location} + ${plone:location} + +[zopepy] +recipe = zc.recipe.egg +eggs = ${instance:eggs} +interpreter = zopepy +extra-paths = ${zope2:location}/lib/python +scripts = zopepy \ No newline at end of file Added: kukit/buildout/kss-website/products/EXTERNALS.txt ============================================================================== --- (empty file) +++ kukit/buildout/kss-website/products/EXTERNALS.txt Thu Oct 4 21:39:19 2007 @@ -0,0 +1 @@ +KssTheme https://codespeak.net/svn/kukit/KssTheme/trunk \ No newline at end of file Added: kukit/buildout/kss-website/products/README.txt ============================================================================== --- (empty file) +++ kukit/buildout/kss-website/products/README.txt Thu Oct 4 21:39:19 2007 @@ -0,0 +1 @@ +Old-style Zope products you are developing can be added here Added: kukit/buildout/kss-website/src/README.txt ============================================================================== --- (empty file) +++ kukit/buildout/kss-website/src/README.txt Thu Oct 4 21:39:19 2007 @@ -0,0 +1 @@ +Packages in eggs that you develop should go in this directory From jvloothuis at codespeak.net Thu Oct 4 22:33:59 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Thu, 4 Oct 2007 22:33:59 +0200 (CEST) Subject: [KSS-checkins] r47167 - in kukit/buildout/kss-website: . products Message-ID: <20071004203359.C57E581A8@code0.codespeak.net> Author: jvloothuis Date: Thu Oct 4 22:33:58 2007 New Revision: 47167 Modified: kukit/buildout/kss-website/buildout.cfg kukit/buildout/kss-website/products/ (props changed) Log: Added more products to the buildout, including the new look for the website Modified: kukit/buildout/kss-website/buildout.cfg ============================================================================== --- kukit/buildout/kss-website/buildout.cfg (original) +++ kukit/buildout/kss-website/buildout.cfg Thu Oct 4 22:33:58 2007 @@ -5,6 +5,7 @@ productdistros instance zopepy + poi # Add additional egg download sources here. dist.plone.org contains archives # of Plone packages. @@ -43,9 +44,12 @@ # the archive name under 'version-suffix-packages'. [productdistros] recipe = plone.recipe.distros -urls = -nested-packages = -version-suffix-packages = +urls = + http://plone.org/products/quills/releases/1.5-alpha1/quills1-5alpha1-tar.gz + http://plone.org/products/plonehelpcenter/releases/1.0/plonehelpcenter-1-0.tgz + http://plone.org/products/poi/releases/1.0/poi-1-0rc2pre1-bundle-tar.gz +nested-packages = + quills1-5alpha1-tar.gz [instance] recipe = plone.recipe.zope2instance @@ -75,4 +79,5 @@ eggs = ${instance:eggs} interpreter = zopepy extra-paths = ${zope2:location}/lib/python -scripts = zopepy \ No newline at end of file +scripts = zopepy + From reebalazs at codespeak.net Thu Oct 4 22:39:39 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Thu, 4 Oct 2007 22:39:39 +0200 (CEST) Subject: [KSS-checkins] r47169 - kukit/kss.demo/branch/1.2/docs Message-ID: <20071004203939.7013D81A8@code0.codespeak.net> Author: reebalazs Date: Thu Oct 4 22:39:39 2007 New Revision: 47169 Modified: kukit/kss.demo/branch/1.2/docs/HISTORY.txt Log: Merge in demoload capability from trunk (-r47053) Modified: kukit/kss.demo/branch/1.2/docs/HISTORY.txt ============================================================================== --- kukit/kss.demo/branch/1.2/docs/HISTORY.txt (original) +++ kukit/kss.demo/branch/1.2/docs/HISTORY.txt Thu Oct 4 22:39:39 2007 @@ -6,6 +6,9 @@ - ... + - Implement pluggable demos + [ree] + kss.demo - 1.2.1 Released 2007-09-10 - Prepare for release From reebalazs at codespeak.net Thu Oct 4 23:04:50 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Thu, 4 Oct 2007 23:04:50 +0200 (CEST) Subject: [KSS-checkins] r47170 - kukit/kss.core/branch/1.2/kss/core/pluginregistry/browser Message-ID: <20071004210450.DB11781A5@code0.codespeak.net> Author: reebalazs Date: Thu Oct 4 23:04:50 2007 New Revision: 47170 Added: kukit/kss.core/branch/1.2/kss/core/pluginregistry/browser/interfaces.py - copied unchanged from r47044, kukit/kss.core/trunk/kss/core/pluginregistry/browser/interfaces.py Modified: kukit/kss.core/branch/1.2/kss/core/pluginregistry/browser/configure.zcml kukit/kss.core/branch/1.2/kss/core/pluginregistry/browser/develui.pt kukit/kss.core/branch/1.2/kss/core/pluginregistry/browser/develview.py Log: Port back necessary fixes needed to work on zope3 (fix @@kss_devel_mode), from trunk. (-r47044) Modified: kukit/kss.core/branch/1.2/kss/core/pluginregistry/browser/configure.zcml ============================================================================== --- kukit/kss.core/branch/1.2/kss/core/pluginregistry/browser/configure.zcml (original) +++ kukit/kss.core/branch/1.2/kss/core/pluginregistry/browser/configure.zcml Thu Oct 4 23:04:50 2007 @@ -10,7 +10,7 @@ class=".develview.DevelView" name="kss_devel_mode" permission="zope.Public" - allowed_attributes="ison isoff set unset ui ui_js ui_css ui_kss" + allowed_interface=".interfaces.IDevelView" /> - +

Kss development mode browser setup

@@ -58,7 +58,7 @@ @@kss_devel_mode/ison on the current context -

+

Kss development mode is on off Modified: kukit/kss.core/branch/1.2/kss/core/pluginregistry/browser/develview.py ============================================================================== --- kukit/kss.core/branch/1.2/kss/core/pluginregistry/browser/develview.py (original) +++ kukit/kss.core/branch/1.2/kss/core/pluginregistry/browser/develview.py Thu Oct 4 23:04:50 2007 @@ -6,12 +6,41 @@ from zope.publisher.browser import BrowserView from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile +from interfaces import IDevelView +from zope.interface import implements +from zope.traversing.interfaces import ITraverser +from zope.publisher.interfaces import NotFound COOKIE_NAME = '__kss_devel' class DevelView(BrowserView): + implements(IDevelView) - def ison(self, REQUEST=None): + # Zope3 requires the implementation of + # IBrowserPublisher, in order for the methods + # to be traversable. + # + # An alternative would be: + # + # + # + # + + def publishTraverse(self, request, name): + try: + return getattr(self, name) + except AttributeError: + raise NotFound(self.context, name, request) + + def browserDefault(self, request): + # make ui the default method + return self, ('ui', ) + + # -- + # Accessable methods + # -- + + def ison(self): '''Checks if running in development mode Two ways to induce development mode: @@ -36,8 +65,6 @@ pass result = bool(ison) - if REQUEST is not None: - result = str(result) return result def isoff(self, REQUEST=None): @@ -48,40 +75,46 @@ return result def set(self): - 'XXX' + 'Sets development mode cookie' self.request.response.setCookie(COOKIE_NAME, '1', path='/') def unset(self): - 'XXX' + 'Unsets development mode cookie' self.request.response.expireCookie(COOKIE_NAME, path='/') _ui = ViewPageTemplateFile('develui.pt', content_type='text/html;charset=utf-8') def ui(self): - 'XXX' + 'User interface for interactive switching' + options = {} if 'devel' in self.request.form: self.set() - self.request.cookies[COOKIE_NAME] = '1' + # setting it also to have immediate effect in the page + options['devel_mode'] = True if 'prod' in self.request.form: self.unset() if COOKIE_NAME in self.request.cookies: - del self.request.cookies[COOKIE_NAME] - return self._ui() + # setting it also to have immediate effect in the page + options['devel_mode'] = False + return self._ui(**options) def ui_js(self): - 'XXX' - resource = self.context.restrictedTraverse('++resource++kss_devel_ui.js') + 'Javascript needed for the ui' + resource = ITraverser(self.context).traverse('++resource++kss_devel_ui.js', + request=self.request) cooked = resource.GET() return cooked def ui_css(self): - 'XXX' - resource = self.context.restrictedTraverse('++resource++kss_devel_ui.css') + 'CSS needed for the ui' + resource = ITraverser(self.context).traverse('++resource++kss_devel_ui.css', + request=self.request) cooked = resource.GET() return cooked def ui_kss(self): - 'XXX' - resource = self.context.restrictedTraverse('++resource++kss_devel_ui.kss') + 'KSS needed for the ui' + resource = ITraverser(self.context).traverse('++resource++kss_devel_ui.kss', + request=self.request) cooked = resource.GET() return cooked From reebalazs at codespeak.net Fri Oct 5 08:09:03 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Fri, 5 Oct 2007 08:09:03 +0200 (CEST) Subject: [KSS-checkins] r47176 - in kukit: kss.core/trunk/kss/core/plugins/core/demo kss.demo/trunk/kss/demo/demo Message-ID: <20071005060903.35A0C8199@code0.codespeak.net> Author: reebalazs Date: Fri Oct 5 08:09:01 2007 New Revision: 47176 Added: kukit/kss.core/trunk/kss/core/plugins/core/demo/ - copied from r47175, kukit/kss.demo/trunk/kss/demo/demo/ Removed: kukit/kss.demo/trunk/kss/demo/demo/ Log: Relocate the actual demos from kss.demo to kss.core From reebalazs at codespeak.net Fri Oct 5 08:11:30 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Fri, 5 Oct 2007 08:11:30 +0200 (CEST) Subject: [KSS-checkins] r47177 - in kukit/kss.demo/trunk: docs kss/demo Message-ID: <20071005061130.B8DE9819F@code0.codespeak.net> Author: reebalazs Date: Fri Oct 5 08:11:30 2007 New Revision: 47177 Modified: kukit/kss.demo/trunk/docs/HISTORY.txt kukit/kss.demo/trunk/kss/demo/configure.zcml Log: Change configuration for core demo relocation. Modified: kukit/kss.demo/trunk/docs/HISTORY.txt ============================================================================== --- kukit/kss.demo/trunk/docs/HISTORY.txt (original) +++ kukit/kss.demo/trunk/docs/HISTORY.txt Fri Oct 5 08:11:30 2007 @@ -6,6 +6,9 @@ - ... + - Moved the core demos to kss.core. + [ree] + - Implement pluggable demos [ree] 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 Fri Oct 5 08:11:30 2007 @@ -90,11 +90,6 @@ --> - - - - - From reebalazs at codespeak.net Fri Oct 5 08:12:15 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Fri, 5 Oct 2007 08:12:15 +0200 (CEST) Subject: [KSS-checkins] r47178 - in kukit/kss.core/trunk: docs kss/core/plugins/core Message-ID: <20071005061215.6D1A881A2@code0.codespeak.net> Author: reebalazs Date: Fri Oct 5 08:12:15 2007 New Revision: 47178 Modified: kukit/kss.core/trunk/docs/HISTORY.txt kukit/kss.core/trunk/kss/core/plugins/core/configure.zcml Log: Change configuration for core demo relocation. Modified: kukit/kss.core/trunk/docs/HISTORY.txt ============================================================================== --- kukit/kss.core/trunk/docs/HISTORY.txt (original) +++ kukit/kss.core/trunk/docs/HISTORY.txt Fri Oct 5 08:12:15 2007 @@ -6,6 +6,10 @@ - ... + - Moved the core demos to this package from kss.demo. + They are now located under the core plugin. + [ree] + - Implement event binding based on the ids fetched dynamically from the dom, by value providers. [ree] 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 Fri Oct 5 08:12:15 2007 @@ -6,6 +6,7 @@ > + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + Deleted: /kukit/kss.demo/branch/1.2/kss/demo/browser/draganddrop.kss ============================================================================== --- /kukit/kss.demo/branch/1.2/kss/demo/browser/draganddrop.kss Thu Oct 4 22:35:04 2007 +++ (empty file) @@ -1,54 +0,0 @@ -.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; - setStyle-name: color; - setStyle-value: red; -} - -.draggable:dad-end { - action-client: logDebug; - action-client: setStyle; - setStyle-name: color; - setStyle-value: black; -} - - -.droppable:dad-drop { - action-client: replaceInnerHTML; - replaceInnerHTML-html: "dropped"; -} - -.droppable:dad-hover { - action-client: replaceInnerHTML; - replaceInnerHTML-html: "hovered"; -} - Deleted: /kukit/kss.demo/branch/1.2/kss/demo/browser/draganddrop.pt ============================================================================== --- /kukit/kss.demo/branch/1.2/kss/demo/browser/draganddrop.pt Thu Oct 4 22:35:04 2007 +++ (empty file) @@ -1,66 +0,0 @@ - - - - - - - -

All demos

-

Start logging pane

-

View KSS resource

-

Drag and drop

- - - - - - - - - - - -
FreeVerticalHorizontal
-
Drag me
-
Drop me here
-
or here
-
-
Drag me
-
Drop me here
-
or here
-
-
Drag me
-
Drop me here
-
or here
-
- - Deleted: /kukit/kss.demo/branch/1.2/kss/demo/browser/effects.kss ============================================================================== --- /kukit/kss.demo/branch/1.2/kss/demo/browser/effects.kss Thu Oct 4 22:35:04 2007 +++ (empty file) @@ -1,9 +0,0 @@ -.effects:click { - action-client: effect; - effect-type: nodeAttr('id'); -} - -input#resetEffects:click { - action-server: resetEffects; -} - Deleted: /kukit/kss.demo/branch/1.2/kss/demo/browser/effects.pt ============================================================================== --- /kukit/kss.demo/branch/1.2/kss/demo/browser/effects.pt Thu Oct 4 22:35:04 2007 +++ (empty file) @@ -1,27 +0,0 @@ - - - - - - - -

All demos

-

Start logging pane

-

View KSS resource

-

Effects

- -

Demo

-
Click here to make me fade
-
Click here to make me puff
-
Click here to make me blindup
- - - Deleted: /kukit/kss.demo/branch/1.2/kss/demo/browser/error_handling.kss ============================================================================== --- /kukit/kss.demo/branch/1.2/kss/demo/browser/error_handling.kss Thu Oct 4 22:35:04 2007 +++ (empty file) @@ -1,50 +0,0 @@ - - -.clickable:click { - evt-click-preventdefault: true; - action-server: errTest; - errTest-id: nodeAttr(id); - errTest-act: kssAttr(act); -} - -/* This one adds the err handling to the second row - It also demonstrates kss rules are merged like css ones -*/ - -/* -.handled:click { - errTest-error: alert; - alert-message: nodeAttr(id); -} -*/ - -/* The next rule demonstrates that instead of executing a local - action on the originally selected node, we use executeCommand - which execute a given local action on a new set of selected nodes. -*/ - -.handled:click { - errTest-error: executeCommand; - executeCommand-commandSelector: 'update-status'; - executeCommand-commandSelectorType: htmlid; - executeCommand-commandName: replaceInnerHTML; - executeCommand-html: 'Error handler activated.'; -} - -/* Spinner control -*/ - -#spinner-status:spinneron { - evt-spinneron-laziness: 0; - action-client: setStyle; - setStyle-name: display; - setStyle-value: block; -} - -#spinner-status:spinneroff { - evt-spinneroff-laziness: 0; - action-client: setStyle; - setStyle-name: display; - setStyle-value: none; -} - Deleted: /kukit/kss.demo/branch/1.2/kss/demo/browser/error_handling.pt ============================================================================== --- /kukit/kss.demo/branch/1.2/kss/demo/browser/error_handling.pt Thu Oct 4 22:35:04 2007 +++ (empty file) @@ -1,73 +0,0 @@ - - - - - - - -

All demos

-

Start logging pane

-

View KSS resource

- -

Error handling demo

-
-
Loading...
-
-

- -

We try four cases here. "No error" and "Empty action" are both valid responses, - except that the second one gives a response with no commands and so it issues a warning into - the kss log. "Error" gives a failed responses due to an exception in the server method - on the server.

-

The buttons in the first row have no error handled.

-
- - - - - -
-

The buttons in the second row have individual error handlers.

- -
- - - - - -
-

- You can also try suspending your server process and start generating timed out requests. - Timed out responses are also handled like ones arriving with error. - The timeout period is by default 8 s now.

-

- In addition, the request queue manager queues up the outgoing responses and maximizes - their number (currently in 4): click like crazy on the buttons and you will see that - your server will not get hogged. More will be told about this topic in the upcoming - documentation.

- - - Deleted: /kukit/kss.demo/branch/1.2/kss/demo/browser/form_submit.kss ============================================================================== --- /kukit/kss.demo/branch/1.2/kss/demo/browser/form_submit.kss Thu Oct 4 22:35:04 2007 +++ (empty file) @@ -1,5 +0,0 @@ -input#submit:click { - evt-click-preventdefault: true; - action-server: formSave; - formSave-data: currentForm(); -} Deleted: /kukit/kss.demo/branch/1.2/kss/demo/browser/form_submit.pt ============================================================================== --- /kukit/kss.demo/branch/1.2/kss/demo/browser/form_submit.pt Thu Oct 4 22:35:04 2007 +++ (empty file) @@ -1,54 +0,0 @@ - - - - - - - -

All demos

-

Start logging pane

-

View KSS resource

- -

Form Submit Demo

-

saved !

-

Empty

-
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
- - -
-
-
- - Modified: kukit/kss.demo/branch/1.2/kss/demo/browser/header_macros.pt ============================================================================== --- kukit/kss.demo/branch/1.2/kss/demo/browser/header_macros.pt (original) +++ kukit/kss.demo/branch/1.2/kss/demo/browser/header_macros.pt Thu Oct 4 22:35:04 2007 @@ -6,6 +6,17 @@ + + + + + + + - - - - - - - -

All demos

-

Start logging pane

-

View KSS resource

-

HTML insertions (a.k.a. Change tags II.)

-
    -
  • - -
  • -
  • - -
  • -
  • - -
  • -
  • - -
  • -
  • - -
  • -
-

The playground:

-

KSS for a life.

- - Deleted: /kukit/kss.demo/branch/1.2/kss/demo/browser/inline_edit.kss ============================================================================== --- /kukit/kss.demo/branch/1.2/kss/demo/browser/inline_edit.kss Thu Oct 4 22:35:04 2007 +++ (empty file) @@ -1,20 +0,0 @@ -div#text:click { - action-server: getInputField; - getInputField-value: currentFormVar(value); -} - -div#text:keydown { -evt-keydown-allowbubbling: true; -evt-keydown-keycodes: 13; -action-client:log; -action-server: saveText; -saveText-value:currentFormVar(value); - -} - -input#save:click { - action-server: saveText; - saveText-value: currentFormVar(value); -} - - Deleted: /kukit/kss.demo/branch/1.2/kss/demo/browser/inline_edit.pt ============================================================================== --- /kukit/kss.demo/branch/1.2/kss/demo/browser/inline_edit.pt Thu Oct 4 22:35:04 2007 +++ (empty file) @@ -1,22 +0,0 @@ - - - - - - -

All demos

-

Start logging pane

-

View KSS resource

- -

Instant edit Demo

-
-
-
- click me! - -
-
-
- - Modified: kukit/kss.demo/branch/1.2/kss/demo/browser/kss_demo_index.pt ============================================================================== --- kukit/kss.demo/branch/1.2/kss/demo/browser/kss_demo_index.pt (original) +++ kukit/kss.demo/branch/1.2/kss/demo/browser/kss_demo_index.pt Thu Oct 4 22:35:04 2007 @@ -4,52 +4,29 @@ tal:attributes="href string:${context/@@absolute_url}/++resource++demo.css"/> -

KSS demos

- -

Parameter functions

- -

Selectors

- -

Core syntax

- -

Core plugin

- -

Commands/Actions

- - -

- -

Unit tests

+

KSS demos

+

Unit tests

- + + +

Core plugin

+
+ +

Plugin namespace: core

+
+ +

Category

+
+ +
+ Deleted: /kukit/kss.demo/branch/1.2/kss/demo/browser/more_selectors.js ============================================================================== --- /kukit/kss.demo/branch/1.2/kss/demo/browser/more_selectors.js Thu Oct 4 22:35:04 2007 +++ (empty file) @@ -1,37 +0,0 @@ - -/* Event plugins for the more_selector demo */ -kukit.more_selectors = {}; - -kukit.more_selectors.AnnoyClickerEvent = function() { -}; - -kukit.more_selectors.AnnoyClickerEvent.prototype.__bind_click__ = function(name, func_to_bind, oper) { - // validate and set parameters - oper.completeParms([], {'count': '3'}, 'annoyClicker event binding'); - oper.evalInt('count', 'annoyClicker event binding'); - if (oper.parms.count < 1) - throw 'Parameter count must be > 0, "' + oper.parms.count + '"'; - // overwrite countsomuch - this.countsomuch = oper.parms.count; - this.count = this.countsomuch; - // Just bind the event via the native event binder - oper.parms = {}; - kukit.pl.NativeEventBinder.prototype.__bind__('click', func_to_bind, oper); -}; - -kukit.more_selectors.AnnoyClickerEvent.prototype.__default_click__ = function(name, oper) { - oper.completeParms([], {}, 'annoyClicker event binding'); - this.count -= 1; - if (this.count == 0) { - // Continue with the real action. - this.count = this.countsomuch; - this.__continue_event__('doit', oper.node, {}); - } else { - this.__continue_event__('annoy', oper.node, {}); - } -}; - -kukit.eventsGlobalRegistry.register('annoyclicker', 'click', kukit.more_selectors.AnnoyClickerEvent, '__bind_click__', '__default_click__'); -kukit.eventsGlobalRegistry.register('annoyclicker', 'annoy', kukit.more_selectors.AnnoyClickerEvent, null, null); -kukit.eventsGlobalRegistry.register('annoyclicker', 'doit', kukit.more_selectors.AnnoyClickerEvent, null, null); - Deleted: /kukit/kss.demo/branch/1.2/kss/demo/browser/more_selectors.kss ============================================================================== --- /kukit/kss.demo/branch/1.2/kss/demo/browser/more_selectors.kss Thu Oct 4 22:35:04 2007 +++ (empty file) @@ -1,29 +0,0 @@ - -#button-one:annoyclicker-click(annoyMe) { -} - -behaviour:annoyclicker-doit(annoyMe) { - action-server: clickedButton; - clickedButton-id: nodeAttr(id); - action-client: log; - log-message: "Was here."; -} - -behaviour:annoyclicker-annoy(annoyMe) { - action-client: alert; - alert-message: "Keep trying until you get there"; -} - -#button-two:annoyclicker-click(annoyYou) { - evt-annoyclicker-click-count: 2; -} - -behaviour:annoyclicker-doit(annoyYou) { - action-server: clickedButton; - clickedButton-id: nodeAttr(id); -} - -behaviour:annoyclicker-annoy(annoyYou) { - action-client: alert; - alert-message: "Keep trying until you get there, from the second button"; -} Deleted: /kukit/kss.demo/branch/1.2/kss/demo/browser/more_selectors.pt ============================================================================== --- /kukit/kss.demo/branch/1.2/kss/demo/browser/more_selectors.pt Thu Oct 4 22:35:04 2007 +++ (empty file) @@ -1,38 +0,0 @@ - - - - - - - -

All demos

-

Start logging pane

-

View KSS resource

-

More complex selectors

- -

-This demo implements the annoyclicker-click kss plugin that shows a simple -pattern of creating stateful (class-like) events in a plugin -and how to bind them from kss. -

- -

-The first button and the second button are bound to two "event binder -instances", the first one sends every 3rd click to the server and -executes a local action otherwise; the second button does -the same but with a count of two. -

- - -

Demo

-
-
- - - - Deleted: /kukit/kss.demo/branch/1.2/kss/demo/browser/preventdefault.kss ============================================================================== --- /kukit/kss.demo/branch/1.2/kss/demo/browser/preventdefault.kss Thu Oct 4 22:35:04 2007 +++ (empty file) @@ -1,62 +0,0 @@ - -a#follow:click { - evt-click-preventdefault: true; - action-client: log; -} - -/* preventdefault is explicit on this.*/ - -input[type="text"].text:keydown { - evt-keydown-preventdefault: true; - evt-keydown-keycodes: 13; - action-client: log; -} - -/* Since some browsers (mainly, some version of Safari) - do a little bit of fireworks with the events (yeah, - cause it fires them up all together) we disable the - default on all of them */ -input[type="text"].text:keypress { - evt-keypress-preventdefault: true; - evt-keypress-keycodes: 13; - action-client: log; -} - -input[type="text"].text:keyup { - evt-keyup-preventdefault: true; - evt-keyup-keycodes: 13; - action-client: log; -} - -/* This used to be the old hack for Safari, actually disabling - the default (submit) on button click. - Apparently the default action for Safari is not "submit the form" - but rather "click on submit", hence triggering another event - through an event */ -input[type="submit"]:click { - evt-click-preventdefault: true; - action-client: log; -} - -/* Second row, allowbubbling combined: */ - -div#follow-wrapper:click { - evt-click-preventdefault: true; - evt-click-allowbubbling: true; - action-client: log; -} - -/* preventdefault is explicit on this.*/ -div#text-wrapper:keydown { - evt-keydown-preventdefault: true; - evt-keydown-allowbubbling: true; - evt-keydown-keycodes: 13; - action-client: log; -} - -div#submit-wrapper:click { - evt-click-preventdefault: true; - evt-click-allowbubbling: true; - action-client: log; -} - Deleted: /kukit/kss.demo/branch/1.2/kss/demo/browser/preventdefault.pt ============================================================================== --- /kukit/kss.demo/branch/1.2/kss/demo/browser/preventdefault.pt Thu Oct 4 22:35:04 2007 +++ (empty file) @@ -1,46 +0,0 @@ - - - - - - - -

All demos

-

Start logging pane

-

View KSS resource

- -

Preventdefault Demo

-

- This is for testing the work of preventdefault to test a specific - workaround against a Safari bug. Specifically, none of the above - controls should cause a page reload. -

-
-

Do not follow

- - - - - -

The same with allowbubbling combined:

- -
- -
-
- -
-
- -
-
- - Added: kukit/kss.demo/branch/1.2/kss/demo/browser/registry.py ============================================================================== --- (empty file) +++ kukit/kss.demo/branch/1.2/kss/demo/browser/registry.py Thu Oct 4 22:35:04 2007 @@ -0,0 +1,94 @@ + +from kss.demo.interfaces import IKSSDemoRegistry +from zope.publisher.interfaces.browser import IBrowserPublisher +from zope.publisher.interfaces import NotFound +from zope.component import getUtility +from zope.interface import implements +try: + from Products.Five import BrowserView + BrowserView # make pyflakes happy +except ImportError: + from zope.publisher.browser import BrowserView + +class KSSDemoRegistryView(BrowserView): + + def getSortedDemos(self): + """Get demos""" + registry = getUtility(IKSSDemoRegistry) + return registry.getSortedDemos() + + def getDemoGroups(self): + """Get demos groupped by plugin_namespace, category""" + demo_groups = [] + prev_plugin_namespace, prev_category = None, None + group = None + for demo in self.getSortedDemos(): + plugin_namespace = demo['plugin_namespace'] + category = demo['category'] + # Set a flag on first rows in group, + # since z3 seems not to handle rpeeat(..).first() + # These will be used for grouping + if prev_plugin_namespace != plugin_namespace: + is_first_plugin_namespace = True + prev_plugin_namespace = plugin_namespace + else: + is_first_plugin_namespace = False + if prev_category != category: + is_first_category = True + prev_category = category + else: + is_first_category = False + # If plugin_namespace or category changed, time to + # start a new group. + if is_first_plugin_namespace or is_first_category: + # Start a new group. + group = [] + demo_groups.append(dict( + plugin_namespace = plugin_namespace, + category = category, + demos = group, + is_first_plugin_namespace = is_first_plugin_namespace, + is_first_category = is_first_category, + )) + # In any case append our demo to the group + group.append(demo) + return demo_groups + +class KSSDemoRegistryAdminView(BrowserView): + """Things that only admin should do""" + implements(IBrowserPublisher) + + # Zope3 requires the implementation of + # IBrowserPublisher, in order for the methods + # to be traversable. + # + # An alternative would be: + # + # + # + # + + def publishTraverse(self, request, name): + try: + return getattr(self, name) + except AttributeError: + raise NotFound(self.context, name, request) + + def browserDefault(self, request): + # make ui the default method + return self, ('cookSeleniumTests', ) + + # -- + # Accessable methods + # -- + + def cookSeleniumTests(self): + """Cook selenium tests + + The *.html tests from each plugin are produced + into the file seltest_all.pty in the directory + of kss.demo.selenium_utils . + """ + registry = getUtility(IKSSDemoRegistry) + registry.cookSeleniumTests() + return "Selenium tests cooked OK. (%i)" % (len(registry.selenium_tests), ) Deleted: /kukit/kss.demo/branch/1.2/kss/demo/browser/tree.kss ============================================================================== --- /kukit/kss.demo/branch/1.2/kss/demo/browser/tree.kss Thu Oct 4 22:35:04 2007 +++ (empty file) @@ -1,11 +0,0 @@ -.state-expanded:click { - action-server: collapseSubTree; - collapseSubTree-value: kssAttr("node"); - collapseSubTree-xvalue: kssAttr("xnode"); -} - -.state-collapsed:click { - action-server: expandSubTree; - expandSubTree-value: kssAttr("node"); - expandSubTree-xvalue: kssAttr("xnode"); -} Deleted: /kukit/kss.demo/branch/1.2/kss/demo/browser/tree.pt ============================================================================== --- /kukit/kss.demo/branch/1.2/kss/demo/browser/tree.pt Thu Oct 4 22:35:04 2007 +++ (empty file) @@ -1,50 +0,0 @@ - - - - - - - -

All demos

-

Start logging pane

-

View KSS resource

- -

Tree Demo

-

This is not finished yet.

-

In this demo we use attributes in a special namespace. This makes - it possible to put attributes to nodes without being forced to reuse "id" - or otherwise produce invalid html.

-

There are two ways to provide these attributes in pages: - with real xhtml (mimetype text/xhtml), namespace attributes can be used, - with transitional xhtml (mimetype text/html) - the attributes can be encoded into "class" attributes. Both are demonstrated - in this example in parallel, but in reality, one of these should be - used depending on the content type of the page.

-
-
    -
  • 1
  • -
  • 2
  • -
      -
    • 2.1
    • -
    • 2.2
    • -
    -
  • 3
  • -
      -
    • 3.1
    • -
    • 3.2
    • -
    -
- -
- - Deleted: /kukit/kss.demo/branch/1.2/kss/demo/browser/two_select_revisited.kss ============================================================================== --- /kukit/kss.demo/branch/1.2/kss/demo/browser/two_select_revisited.kss Thu Oct 4 22:35:04 2007 +++ (empty file) @@ -1,5 +0,0 @@ -select.master-select:change { - action-server: updateSlaveSelector; - updateSlaveSelector-masterid: nodeAttr("id"); - updateSlaveSelector-value: currentFormVar(); -} Deleted: /kukit/kss.demo/branch/1.2/kss/demo/browser/two_select_revisited.pt ============================================================================== --- /kukit/kss.demo/branch/1.2/kss/demo/browser/two_select_revisited.pt Thu Oct 4 22:35:04 2007 +++ (empty file) @@ -1,39 +0,0 @@ - - - - - - -

All demos

-

Start logging pane

-

View KSS resource

-

Master-slave selects revisited

-
-
- - -
-
- - -
-
- - -
-
- - Deleted: /kukit/kss.demo/branch/1.2/kss/demo/browser/two_selects.kss ============================================================================== --- /kukit/kss.demo/branch/1.2/kss/demo/browser/two_selects.kss Thu Oct 4 22:35:04 2007 +++ (empty file) @@ -1,4 +0,0 @@ -select#first:change { - action-server: getCorrespondingSelect; - getCorrespondingSelect-value: currentFormVar(value); -} Deleted: /kukit/kss.demo/branch/1.2/kss/demo/browser/two_selects.pt ============================================================================== --- /kukit/kss.demo/branch/1.2/kss/demo/browser/two_selects.pt Thu Oct 4 22:35:04 2007 +++ (empty file) @@ -1,21 +0,0 @@ - - - - - - -

All demos

-

Start logging pane

-

View KSS resource

-

Two Selects

-
- - - -

Remove Node with XPath

-

XPath

-

next 1

-

next 2

-

next 3

- - - Modified: kukit/kss.demo/branch/1.2/kss/demo/configure.zcml ============================================================================== --- kukit/kss.demo/branch/1.2/kss/demo/configure.zcml (original) +++ kukit/kss.demo/branch/1.2/kss/demo/configure.zcml Thu Oct 4 22:35:04 2007 @@ -15,502 +15,93 @@ title="View" /> - - + - + - - + - - + - - - + class=".simplecontent.SimpleContent" + meta_type="KssDemo SimpleContent" + addview="AddSimpleContent.html" + permission="zope.View" + global="True" + /> - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - + + + + - - - - - + + Added: kukit/kss.demo/branch/1.2/kss/demo/demo/__init__.pyc ============================================================================== Binary file. No diff available. Added: kukit/kss.demo/branch/1.2/kss/demo/demo/configure.zcml ============================================================================== --- (empty file) +++ kukit/kss.demo/branch/1.2/kss/demo/demo/configure.zcml Thu Oct 4 22:35:04 2007 @@ -0,0 +1,435 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Added: kukit/kss.demo/branch/1.2/kss/demo/demo/demoview.py ============================================================================== --- (empty file) +++ kukit/kss.demo/branch/1.2/kss/demo/demo/demoview.py Thu Oct 4 22:35:04 2007 @@ -0,0 +1,200 @@ +# Copyright (c) 2005-2007 +# Authors: KSS Project Contributors (see docs/CREDITS.txt) +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as published +# by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +from kss.core import KSSView, force_unicode, KSSExplicitError, kssaction +import datetime + +class KSSDemoView(KSSView): + + def clearDivContent(self): + """ clear div content """ + self.getCommandSet('core').clearChildNodes('div#demo') + return self.render() + + def copyFromDivContent(self): + """ copy div content """ + self.getCommandSet('core').copyChildNodesFrom('div#copy', 'demo') + return self.render() + + def copyToDivContent(self): + """ copy div content """ + self.getCommandSet('core').copyChildNodesTo('div#copy', 'demo') + return self.render() + + def moveToDivContent(self): + """ copy div content """ + self.getCommandSet('core').copyChildNodesTo('div#copy', 'demo') + self.getCommandSet('core').clearChildNodes('div#copy') + return self.render() + + def getDivContent(self): + """ returns div content """ + self.getCommandSet('core').replaceInnerHTML('div#demo', '

it worked

') + self.getCommandSet('core').replaceInnerHTML('div#demo', '

it worked again

') + return self.render() + + def getCorrespondingSelect(self, value): + """ returns select content """ + mapping = {} + mapping['']=[] + mapping['animals']=['dog', 'cat', 'cow'] + mapping['machines']=['computer', 'car', 'airplane'] + # XXX Note that originally we just used replaceInnerHTML to just put + # the options inside the select, however this is principally broken + # on IE due to an IE bug. Microsoft has confirmed the bug but is not + # giving information on whether it has or it will ever be fixed. + # For further info, see http://support.microsoft.com/default.aspx?scid=kb;en-us;276228 + # The current solution, replace the outer node, works solidly. + result = ['') + self.getCommandSet('core').replaceHTML('select#second', ' '.join(result)) + return self.render() + + def getAutoupdateMarkup(self): + """ returns the current time """ + self.getCommandSet('core').replaceInnerHTML('div#update-wrapper', '
') + return self.render() + + def getCurrentTime(self): + """ returns the current time """ + self.getCommandSet('core').replaceInnerHTML('div#update-area', "

%s

" % str(datetime.datetime.now())) + return self.render() + + def getInputField(self, value): + 'Inserts the value as entered into an input field' + # We need to make unicode. But on Z2 we receive utf-8, on Z3 unicode + value = force_unicode(value, 'utf') + self.getCommandSet('core').replaceInnerHTML('div#text', + '
' \ + '' + ) + return self.render() + + def saveText(self, value): + 'Inserts the value to display it on the page' + # We need to make unicode. But on Z2 we receive utf-8, on Z3 unicode + value = force_unicode(value, 'utf') + self.getCommandSet('core').replaceInnerHTML('div#text', value+'') + return self.render() + + def expandSubTree(self, value, xvalue): + 'Expands given subtree' + self.getCommandSet('core').replaceInnerHTML('#text', 'works, expand %s (xhtml attr: %s)' % (value, xvalue)) + return self.render() + + def collapseSubTree(self, value, xvalue): + 'Collapses given subtree' + self.getCommandSet('core').replaceInnerHTML('#text', 'works, collapse %s (xhtml attr: %s)' % (value, xvalue)) + return self.render() + + def cancelSubmitSave(self, text_save): + # We need to make unicode. But on Z2 we receive utf-8, on Z3 unicode + text_save = force_unicode(text_save, 'utf') + self.getCommandSet('core').replaceInnerHTML('div#async', 'Async saved %s' % text_save) + return self.render() + + def removeNodeXpath(self): + # XXX the xpath selector is now moved out of the core, see suppl, product "azaxslt" + sel = self.getSelector('xpath', "//P[@id='xpath']/following-sibling::*[position()=1]") + self.getCommandSet('core').deleteNode(sel) + return self.render() + + def clickedButton(self, id): + 'Show status of the button clicked' + self.getCommandSet('core').replaceInnerHTML('#update-status', "

Button %s clicked. %s

" % (id, datetime.datetime.now())) + return self.render() + + def updateSlaveSelector(self, masterid, value): + """ returns select content """ + mapping = {} + mapping['']=[] + mapping['animals']=['dog', 'cat', 'cow'] + mapping['machines']=['computer', 'car', 'airplane'] + # calculate the slave id + master, _dummy = masterid.split('-') + slaveid = '%s-slave' % master + # make the payload + result = ['') + # XXX See above remark why we need to replace the outer select. + self.getCommandSet('core').replaceHTML('select#%s' % slaveid, ' '.join(result)) + return self.render() + + def formSubmitSave(self, data): + result = ['

Async saved:

'] + for key, value in data.items(): + result.append('' % (key, value)) + result.append('
Name:Value:
%s%s
') + # We need to make unicode. But on Z2 we receive utf-8, on Z3 unicode + retval = force_unicode(''.join(result), 'utf') + self.getCommandSet('core').replaceInnerHTML('div#async', retval) + return self.render() + + def reset(self): + self.getCommandSet('effects').effect('.effects', 'appear') + return self.render() + + @kssaction + def errTest(self, id, act): + if act == 'error': + raise Exception, 'We have an error here.' + elif act == 'explicit': + raise KssExplicitError, 'Explicit error raised.' + elif act == 'empty': + # Just do nothing, we want to return a response with no commands. + # This is valid behaviour, should raise no error, however + # gives a warning in the kukit log. + pass + ## XXX This is commented out by default, but you can try this on your own + ## server, together with the timeout buttons in the page template timeout buttons in the page template. + ## + #elif act == 'timeout': + # # Wait longer then timeout, this is currently 4 s + # time.sleep(6.0); + # # the next reply will never arrive. + # self.replaceInnerHTML('#update-status', u'Timeout response, button %s clicked. %s' % (id, datetime.datetime.now())) + else: + # act = noerror: standard response. + self.getCommandSet('core').replaceInnerHTML('#update-status', u'Normal response, button %s clicked. %s' % (id, datetime.datetime.now())) + return self.render() + + def htmlReplace(self): + """html replace""" + self.getCommandSet('core').replaceHTML('div#frame', '

KSS for a life.

') + return self.render() + + def htmlInsertBefore(self): + """html insert""" + self.getCommandSet('core').insertHTMLBefore('#core', '
KSS for a life. %s
' % (str(datetime.datetime.now()), )) + return self.render() + + def htmlInsertAfter(self): + """html insert""" + self.getCommandSet('core').insertHTMLAfter('#core', '
KSS for a life. %s
' % (str(datetime.datetime.now()), )) + return self.render() + + def htmlInsertAsFirstChild(self): + """html insert""" + self.getCommandSet('core').insertHTMLAsFirstChild('div#frame', '
KSS for a life. %s
' % (str(datetime.datetime.now()), )) + return self.render() + + def htmlInsertAsLastChild(self): + """html insert""" + self.getCommandSet('core').insertHTMLAsLastChild('div#frame', '
KSS for a life. %s
' % (str(datetime.datetime.now()), )) + return self.render() Deleted: /kukit/kss.demo/branch/1.2/kss/demo/tests/selenium_tests/__init__.py ============================================================================== Deleted: /kukit/kss.demo/branch/1.2/kss/demo/tests/selenium_tests/createpythontests.py ============================================================================== --- /kukit/kss.demo/branch/1.2/kss/demo/tests/selenium_tests/createpythontests.py Thu Oct 4 22:35:04 2007 +++ (empty file) @@ -1,66 +0,0 @@ -#!/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 -import re - -template = Template(''' -from seleniumtestcase import SeleniumTestCase -import unittest, time - -class seltest_$testname(SeleniumTestCase): - -$tests - -def test_suite(): - return unittest.makeSuite(seltest_$testname) - -if __name__ == "__main__": - unittest.main() -''') - -variable_regexp = re.compile('\$\{(?P\w*)\}') - -def formatcommand(command, *args): - 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() -tests = [] -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 - 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() Deleted: /kukit/kss.demo/branch/1.2/kss/demo/tests/selenium_tests/patterns.py.txt ============================================================================== --- /kukit/kss.demo/branch/1.2/kss/demo/tests/selenium_tests/patterns.py.txt Thu Oct 4 22:35:04 2007 +++ (empty file) @@ -1,23 +0,0 @@ -#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 Deleted: /kukit/kss.demo/branch/1.2/kss/demo/tests/selenium_tests/selenium.py ============================================================================== --- /kukit/kss.demo/branch/1.2/kss/demo/tests/selenium_tests/selenium.py Thu Oct 4 22:35:04 2007 +++ (empty file) @@ -1,1405 +0,0 @@ - -""" -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,]) - Deleted: /kukit/kss.demo/branch/1.2/kss/demo/tests/selenium_tests/seleniumtestcase.py ============================================================================== --- /kukit/kss.demo/branch/1.2/kss/demo/tests/selenium_tests/seleniumtestcase.py Thu Oct 4 22:35:04 2007 +++ (empty file) @@ -1,113 +0,0 @@ -import os -import unittest -import time - -from selenium import selenium -try: - browser = os.environ["SELENIUMBROWSER"] -except: - browser = "*firefox" -try: - target = os.environ["SELENIUMTARGET"] -except: - target = "http://localhost:8080" - - -def trymanytimes(func): - '''Decorate a test method with this to make it try for ten seconds''' - def newfunc(*args, **kwargs): - exc = None - for i in range(10): - try: - func(*args, **kwargs) - except Exception, e: - exc = e - time.sleep(1) - else: - return - raise exc - return newfunc - -class SeleniumTestCase(unittest.TestCase): - def setUp(self): - 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) - - @trymanytimes - def waitForText(self, target, text): - self.failUnless(text in self.selenium.get_text(target)) - - @trymanytimes - def waitForNotText(self, target, text): - self.failIf(text in self.selenium.get_text(target)) - - @trymanytimes - def waitForTextPresent(self, text): - self.failUnless(self.selenium.is_text_present(text)) - - @trymanytimes - def waitForElementNotPresent(self, target): - self.failIf(self.selenium.is_element_present(target)) - - @trymanytimes - def waitForElementPresent(self, target): - self.failUnless(self.selenium.is_element_present(target)) - - @trymanytimes - def waitForValue(self, target, value): - self.failUnless(self.selenium.get_value(target)) - - @trymanytimes - def waitForAttribute(self, target, value): - self.assertEqual(self.selenium.get_attribute(target), value) - - 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 assertElementNotPresent(self, target): - self.failIf(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] Added: kukit/kss.demo/branch/1.2/kss/demo/demo/zopeconfig.py ============================================================================== --- (empty file) +++ kukit/kss.demo/branch/1.2/kss/demo/demo/zopeconfig.py Thu Oct 4 22:35:04 2007 @@ -0,0 +1,47 @@ + +from kss.demo.interfaces import ( + IKSSDemoResource, + IKSSSeleniumTestResource, + ) +from kss.demo.resource import ( + KSSDemo, + KSSSeleniumTestDirectory, + ) +from zope.interface import implements + +# Create a mesh of provided interfaces +# This is needed, because an utility must have a single interface. +class IResource(IKSSDemoResource, IKSSSeleniumTestResource): + pass + +class KSSCoreDemos(object): + implements(IResource) + + demos = ( + KSSDemo('', '', "basic_commands.html", "Change tag content"), + KSSDemo('', '', "two_selects.html", "Two selects"), + KSSDemo('', '', "autoupdate.html", "Auto update"), + KSSDemo('', '', "inline_edit.html", "Inline edit"), + KSSDemo('', '', "cancel_submit.html", "Cancel Submit Click"), + KSSDemo('', '', "tree.html", "Tree"), + KSSDemo('', '', "more_selectors.html", "More complex selectors"), + KSSDemo('', '', "two_select_revisited.html", "Master-slave selects revisited"), + KSSDemo('', '', "form_submit.html", "Form submit"), + KSSDemo('', '', "effects.html", "Effects"), + KSSDemo('', '', "error_handling.html", "Error handling"), + KSSDemo('', '', "preventdefault.html", "Preventdefault (a.k.a. Safari workarounds)"), + KSSDemo('', '', "html_inserts.html", "HTML insertions (Change tag content returns)"), +## KSSDemo('', '', "draganddrop.html", "Scriptaculous drag and drop"), + KSSDemo('', 'Parameter functions', 'pf_forms.html', 'Forms'), + KSSDemo('', 'Selectors', 'selectors.html', 'Parent node selector'), + KSSDemo('', 'Core syntax', "kss_selector_param.html", "Kss selector parameters"), + KSSDemo('', 'Core syntax', "kss_url_param.html", "Kss url parameters"), + KSSDemo('', 'Core plugin', "kss_evt_preventbubbling.html", "Prevent bubbling KSS event parameter"), + KSSDemo('', 'Commands/Actions', "ca_focus.html", "Focus"), + KSSDemo('', 'Commands/Actions', "actions.html", "Toggle case action"), + ) + + # directories are relative from the location of this .py file + selenium_tests = ( + KSSSeleniumTestDirectory('selenium_tests'), + ) Modified: kukit/kss.demo/branch/1.2/kss/demo/demoview.py ============================================================================== --- kukit/kss.demo/branch/1.2/kss/demo/demoview.py (original) +++ kukit/kss.demo/branch/1.2/kss/demo/demoview.py Thu Oct 4 22:35:04 2007 @@ -1,200 +0,0 @@ -# Copyright (c) 2005-2007 -# Authors: KSS Project Contributors (see docs/CREDITS.txt) -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as published -# by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -from kss.core import KSSView, force_unicode, KSSExplicitError, kssaction -import datetime - -class KSSDemoView(KSSView): - - def clearDivContent(self): - """ clear div content """ - self.getCommandSet('core').clearChildNodes('div#demo') - return self.render() - - def copyFromDivContent(self): - """ copy div content """ - self.getCommandSet('core').copyChildNodesFrom('div#copy', 'demo') - return self.render() - - def copyToDivContent(self): - """ copy div content """ - self.getCommandSet('core').copyChildNodesTo('div#copy', 'demo') - return self.render() - - def moveToDivContent(self): - """ copy div content """ - self.getCommandSet('core').copyChildNodesTo('div#copy', 'demo') - self.getCommandSet('core').clearChildNodes('div#copy') - return self.render() - - def getDivContent(self): - """ returns div content """ - self.getCommandSet('core').replaceInnerHTML('div#demo', '

it worked

') - self.getCommandSet('core').replaceInnerHTML('div#demo', '

it worked again

') - return self.render() - - def getCorrespondingSelect(self, value): - """ returns select content """ - mapping = {} - mapping['']=[] - mapping['animals']=['dog', 'cat', 'cow'] - mapping['machines']=['computer', 'car', 'airplane'] - # XXX Note that originally we just used replaceInnerHTML to just put - # the options inside the select, however this is principally broken - # on IE due to an IE bug. Microsoft has confirmed the bug but is not - # giving information on whether it has or it will ever be fixed. - # For further info, see http://support.microsoft.com/default.aspx?scid=kb;en-us;276228 - # The current solution, replace the outer node, works solidly. - result = ['') - self.getCommandSet('core').replaceHTML('select#second', ' '.join(result)) - return self.render() - - def getAutoupdateMarkup(self): - """ returns the current time """ - self.getCommandSet('core').replaceInnerHTML('div#update-wrapper', '
') - return self.render() - - def getCurrentTime(self): - """ returns the current time """ - self.getCommandSet('core').replaceInnerHTML('div#update-area', "

%s

" % str(datetime.datetime.now())) - return self.render() - - def getInputField(self, value): - 'Inserts the value as entered into an input field' - # We need to make unicode. But on Z2 we receive utf-8, on Z3 unicode - value = force_unicode(value, 'utf') - self.getCommandSet('core').replaceInnerHTML('div#text', - '
' \ - '' - ) - return self.render() - - def saveText(self, value): - 'Inserts the value to display it on the page' - # We need to make unicode. But on Z2 we receive utf-8, on Z3 unicode - value = force_unicode(value, 'utf') - self.getCommandSet('core').replaceInnerHTML('div#text', value+'') - return self.render() - - def expandSubTree(self, value, xvalue): - 'Expands given subtree' - self.getCommandSet('core').replaceInnerHTML('#text', 'works, expand %s (xhtml attr: %s)' % (value, xvalue)) - return self.render() - - def collapseSubTree(self, value, xvalue): - 'Collapses given subtree' - self.getCommandSet('core').replaceInnerHTML('#text', 'works, collapse %s (xhtml attr: %s)' % (value, xvalue)) - return self.render() - - def cancelSubmitSave(self, text_save): - # We need to make unicode. But on Z2 we receive utf-8, on Z3 unicode - text_save = force_unicode(text_save, 'utf') - self.getCommandSet('core').replaceInnerHTML('div#async', 'Async saved %s' % text_save) - return self.render() - - def removeNodeXpath(self): - # XXX the xpath selector is now moved out of the core, see suppl, product "azaxslt" - sel = self.getSelector('xpath', "//P[@id='xpath']/following-sibling::*[position()=1]") - self.getCommandSet('core').deleteNode(sel) - return self.render() - - def clickedButton(self, id): - 'Show status of the button clicked' - self.getCommandSet('core').replaceInnerHTML('#update-status', "

Button %s clicked. %s

" % (id, datetime.datetime.now())) - return self.render() - - def updateSlaveSelector(self, masterid, value): - """ returns select content """ - mapping = {} - mapping['']=[] - mapping['animals']=['dog', 'cat', 'cow'] - mapping['machines']=['computer', 'car', 'airplane'] - # calculate the slave id - master, _dummy = masterid.split('-') - slaveid = '%s-slave' % master - # make the payload - result = ['') - # XXX See above remark why we need to replace the outer select. - self.getCommandSet('core').replaceHTML('select#%s' % slaveid, ' '.join(result)) - return self.render() - - def formSubmitSave(self, data): - result = ['

Async saved:

'] - for key, value in data.items(): - result.append('' % (key, value)) - result.append('
Name:Value:
%s%s
') - # We need to make unicode. But on Z2 we receive utf-8, on Z3 unicode - retval = force_unicode(''.join(result), 'utf') - self.getCommandSet('core').replaceInnerHTML('div#async', retval) - return self.render() - - def reset(self): - self.getCommandSet('effects').effect('.effects', 'appear') - return self.render() - - @kssaction - def errTest(self, id, act): - if act == 'error': - raise Exception, 'We have an error here.' - elif act == 'explicit': - raise KssExplicitError, 'Explicit error raised.' - elif act == 'empty': - # Just do nothing, we want to return a response with no commands. - # This is valid behaviour, should raise no error, however - # gives a warning in the kukit log. - pass - ## XXX This is commented out by default, but you can try this on your own - ## server, together with the timeout buttons in the page template timeout buttons in the page template. - ## - #elif act == 'timeout': - # # Wait longer then timeout, this is currently 4 s - # time.sleep(6.0); - # # the next reply will never arrive. - # self.replaceInnerHTML('#update-status', u'Timeout response, button %s clicked. %s' % (id, datetime.datetime.now())) - else: - # act = noerror: standard response. - self.getCommandSet('core').replaceInnerHTML('#update-status', u'Normal response, button %s clicked. %s' % (id, datetime.datetime.now())) - return self.render() - - def htmlReplace(self): - """html replace""" - self.getCommandSet('core').replaceHTML('div#frame', '

KSS for a life.

') - return self.render() - - def htmlInsertBefore(self): - """html insert""" - self.getCommandSet('core').insertHTMLBefore('#core', '
KSS for a life. %s
' % (str(datetime.datetime.now()), )) - return self.render() - - def htmlInsertAfter(self): - """html insert""" - self.getCommandSet('core').insertHTMLAfter('#core', '
KSS for a life. %s
' % (str(datetime.datetime.now()), )) - return self.render() - - def htmlInsertAsFirstChild(self): - """html insert""" - self.getCommandSet('core').insertHTMLAsFirstChild('div#frame', '
KSS for a life. %s
' % (str(datetime.datetime.now()), )) - return self.render() - - def htmlInsertAsLastChild(self): - """html insert""" - self.getCommandSet('core').insertHTMLAsLastChild('div#frame', '
KSS for a life. %s
' % (str(datetime.datetime.now()), )) - return self.render() Added: kukit/kss.demo/branch/1.2/kss/demo/events.py ============================================================================== --- (empty file) +++ kukit/kss.demo/branch/1.2/kss/demo/events.py Thu Oct 4 22:35:04 2007 @@ -0,0 +1,32 @@ + +import zope.component +from zope.component.interfaces import ( + IUtilityRegistration, + IRegistrationEvent, + ) +from interfaces import ( + IKSSDemoResource, + IKSSSeleniumTestResource, + IKSSDemoRegistrationEvent, + ) +from zope.interface import implements + +class KSSDemoRegistrationEvent(object): + """Redispatch of registration for demo utilities""" + implements(IKSSDemoRegistrationEvent) + + at zope.component.adapter(IUtilityRegistration, IRegistrationEvent) +def dispatchRegistration(registration, event): + """When a demo utility is registered, add it to the registry. + When a demo utility is registered, + event handler registered for the particular component registered, + the registration and the event. + """ + component = registration.component + # Only dispatch registration of the interesting utilities. + new_event = KSSDemoRegistrationEvent() + if IKSSDemoResource.providedBy(component) or \ + IKSSSeleniumTestResource.providedBy(component): + handlers = zope.component.subscribers((component, registration, event, new_event), None) + for handler in handlers: + pass # getting them does the work Modified: kukit/kss.demo/branch/1.2/kss/demo/interfaces.py ============================================================================== --- kukit/kss.demo/branch/1.2/kss/demo/interfaces.py (original) +++ kukit/kss.demo/branch/1.2/kss/demo/interfaces.py Thu Oct 4 22:35:04 2007 @@ -1,4 +1,145 @@ from zope.interface import Interface +from zope.schema import ( + TextLine, + List, + ) class ISimpleContent(Interface): pass + +# -- +# Resources +# -- + +class IKSSDemo(Interface): + """Represents an actual demo page""" + + plugin_namespace = TextLine( + title=u"plugin_namespace", + description=u'string with the name of the plugin.' + u'Or: "" when it is the core part.', + required=False, + ) + + category = TextLine( + title=u"component", + description=u'text that will appear as the title of the' + u'category. "" if out of category.', + required=False, + ) + + page_url = TextLine( + title=u"page_url", + description=u'(relative) url of the demo page. This should' + u'traverse on ISimpleContent.', + required=True, + ) + + title = TextLine( + title=u"title", + description=u'Title of the demo. This also identifies it' + u'for removal.', + required=True, + ) + +class IKSSSeleniumTestDirectory(Interface): + """Represents an actual selenium test directory""" + + test_directory = TextLine( + title=u"test directory", + description=u'Relative directory path, contains *.html selenium tests', + required=False, + ) + +# -- +# Resource definition interfaces +# -- + +class IKSSDemoResource(Interface): + """An utility that a demo needs to register""" + + # list of IKSSDemo + demos = List( + title=u"demos", + description=u'The ordered list of demos contained in this plugin', + required=True, + ) + +class IKSSSeleniumTestResource(Interface): + """An utility that a demo needs to register""" + + # list of IKSSSeleniumTestDir + selenium_tests = List( + title=u"selenium tests", + description=u'The list of selenium test directories contained in this plugin', + required=True, + ) + +# -- +# The registry itself +# -- + +class IKSSDemoRegistry(Interface): + """Faciliates registration of demos. + + Implementations must look after the IKSSDemoResource + adapters, and use their content to set up themselves. + """ + + def registerDemo(demo): + """Register a demo + + It has the attributes specified in IKSSDemo: + + plugin_namespace - string with the name of the plugin. + Or: "" when it is the core part. + + category - text that will appear as the title of the + category. "" if out of category. + + demo_page - (relative) url of the demo page. This should + traverse on ISimpleContent. + + title - Title of the demo. This also identifies it + for removal. + """ + + def unregisterDemo(demo): + """Unregister the given demo.""" + + def getSortedDemos(): + """Get the (sorted) list of demos""" + +class IKSSSeleniumTestRegistry(Interface): + """Faciliates registration of demos. + + Implementations must look after the IKSSSeleniumTestResource + adapters, and use their content to set up themselves. + """ + + def registerSeleniumTestFile(test_filename): + """Register a selenium test directory + + It test_dir has the "filename" attributes specified in IKSSSeleniumTest. + """ + + def unregisterSeleniumTestFile(test_filename): + """Unregister the given test directory.""" + + def cookSeleniumTests(): + """Cook selenium tests + + The *.html tests from each plugin are produced + into the file seltest_all.pty in the directory + of kss.demo.selenium_utils . + """ + +# -- +# Event that gets redispatched, for allowing +# the listeners to filter on component +# -- + +class IKSSDemoRegistrationEvent(Interface): + """Redispatched evend for registration of + IKSSPDemoRegistry utilities. + """ Added: kukit/kss.demo/branch/1.2/kss/demo/registry.py ============================================================================== --- (empty file) +++ kukit/kss.demo/branch/1.2/kss/demo/registry.py Thu Oct 4 22:35:04 2007 @@ -0,0 +1,237 @@ +from zope.interface import implements +from zope.component import ( + adapter, + getSiteManager, + ) +from interfaces import ( + IKSSDemoRegistry, + IKSSSeleniumTestRegistry, + IKSSDemoResource, + IKSSSeleniumTestResource, + IKSSDemoRegistrationEvent, + ) +from zope.component.interfaces import ( + IUtilityRegistration, + IRegistered, + IUnregistered, + ) +import sys, os, re, textwrap +from elementtree import HTMLTreeBuilder +from string import Template +import kss.demo.selenium_utils +# shut the mouth of pyflakes +kss.demo.selenium_utils + +# -- +# Registry implementation for use with Zope +# -- + +def getRootDirOfModule(module_name): + return os.path.dirname(sys.modules[module_name].__file__) + +def getRootDirOfClass(cls): + return getRootDirOfModule(cls.__module__) + +def getRootDirOfInstance(obj): + return getRootDirOfClass(obj.__class__) + +# Create a mesh of provided interfaces +# This is needed, because an utility must have a single interface. +class IRegistry(IKSSDemoRegistry, IKSSSeleniumTestRegistry): + pass + +class KSSDemoRegistry(object): + """KSS demo registry. + """ + implements(IRegistry) + + def __init__(self): + # We will set up my handlers to get notified of new plugins + # (works via redispatching by events.py) + site = getSiteManager() + # registry for demos + self.demos_dict = {} + self.demos = [] + self.demos_are_sorted = False + site.registerHandler(self.registerDemosFromPlugin) + site.registerHandler(self.unregisterDemosFromPlugin) + # registry for selenium tests + self.selenium_tests = [] + site.registerHandler(self.registerSeleniumTestsFromPlugin) + site.registerHandler(self.unregisterSeleniumTestsFromPlugin) + + @adapter(IKSSDemoResource, IUtilityRegistration, IRegistered, IKSSDemoRegistrationEvent) + def registerDemosFromPlugin(self, plugin, registration=None, event=None, new_event=None): + """Add a demo collection to the registry. + """ + for demo in plugin.demos: + self.registerDemo(demo) + + @adapter(IKSSDemoResource, IUtilityRegistration, IUnregistered, IKSSDemoRegistrationEvent) + def unregisterDemosFromPlugin(self, plugin, registration=None, event=None, new_event=None): + """Remove a demo collection from the registry. + """ + for demo in plugin.demos: + self.unregisterDemo(demo) + + def registerDemo(self, demo): + """Register a demo + + It has the attributes specified in IKSSDemo: + + plugin_namespace - string with the name of the plugin. + Or: "" when it is the core part. + + category - text that will appear as the title of the + category. "" if out of category. + + demo_page - (relative) url of the demo page. This should + traverse on ISimpleContent. + + title - Title of the demo. This also identifies it + for removal. + """ + key = demo.plugin_namespace, demo.category, demo.page_url + if key in self.demos: + raise Exception, 'The demo for %s has already been registered. Cannot add.' % (key, ) + self.demos_dict[key] = demo + self.demos.append(demo) + self.demos_are_sorted = False + + def unregisterDemo(self, demo): + """Unregister the given demo.""" + key = demo.plugin_namespace, demo.category, demo.demo_page + try: + value = self.demos_dict[key] + except KeyError: + raise Exception, 'The demo for %s is yet unregistered. Cannot remove.' % (key, ) + del self.demos_dict[key] + self.demos.remove(value) + + def getSortedDemos(self): + """Get the (sorted) list of demos""" + if not self.demos_are_sorted: + self.demos.sort(key=lambda demo: ( + demo.plugin_namespace, + demo.category, + )) + self.demos_are_sorted = True + return list(self.demos) + + # -- + # Selenium tests + # -- + + @staticmethod + def _getSeleniumTestsFromPlugin(plugin): + test_filenames = [] + root_dir = getRootDirOfInstance(plugin) + for selenium_test_directory in plugin.selenium_tests: + tests_root_dir = os.path.join(root_dir, selenium_test_directory.test_directory) + for test_filename in os.listdir(tests_root_dir): + if test_filename.lower().endswith('.html') or \ + test_filename.endswith('.htm'): + test_filenames.append(os.path.join(tests_root_dir, test_filename)) + return test_filenames + + @adapter(IKSSSeleniumTestResource, IUtilityRegistration, IRegistered, IKSSDemoRegistrationEvent) + def registerSeleniumTestsFromPlugin(self, plugin, registration=None, event=None, new_event=None): + """Add a demo collection to the registry. + """ + for test_filename in self._getSeleniumTestsFromPlugin(plugin): + self.registerSeleniumTestFile(test_filename) + + @adapter(IKSSSeleniumTestResource, IUtilityRegistration, IUnregistered, IKSSDemoRegistrationEvent) + def unregisterSeleniumTestsFromPlugin(self, plugin, registration=None, event=None, new_event=None): + """Remove a demo collection from the registry. + """ + for test_filename in self._getSeleniumTestsFromPlugin(plugin): + self.registerSeleniumTestFile(test_filename) + + def registerSeleniumTestFile(self, test_filename): + """Register a selenium test by absolute filename + """ + if test_filename in self.selenium_tests: + raise Exception, 'The selenium test for %s has already been registered. Cannot add.' % (test_filename, ) + self.selenium_tests.append(test_filename) + + def unregisterSeleniumTestFile(self, test_filename): + """Unregister the given selenium test.""" + try: + del self.selenium_tests[test_filename] + except KeyError: + raise Exception, 'The selenium test for %s is yet unregistered. Cannot remove.' % (test_filename, ) + + template = Template(textwrap.dedent('''\ + from seleniumtestcase import SeleniumTestCase + import unittest, time + + class seltest_$testname(SeleniumTestCase): + + $tests + + def test_suite(): + return unittest.makeSuite(seltest_$testname) + + if __name__ == "__main__": + unittest.main() + ''')) + + variable_regexp = re.compile('\$\{(?P\w*)\}') + @classmethod + def formatcommand(cls, command, *args): + if not command: + return '' # Change this to raise an exception? + + arguments = [] + for arg in args: + if not arg: + continue + matched = cls.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)) + + def cookSeleniumTests(self): + """Cook selenium tests + + The *.html tests from each plugin are produced + into the file seltest_all.pty in the directory + of kss.demo.selenium_utils . + """ + # Try to open the file for writing. + output_dir = getRootDirOfModule('kss.demo.selenium_utils') + output_filename = os.path.join(output_dir, 'seltest_all.py') + try: + f = open(output_filename, 'wb') + except IOError, exc: + raise IOError, ('Cannot open file "%s" for writing. ' + 'Make sure zope process has write access in directory. ' + '["%s"]') \ + % (output_filename, exc) + + htmlparser = HTMLTreeBuilder.TreeBuilder() + tests = [] + for filename in self.selenium_tests: + 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(self.formatcommand(*[td.text for td in row.findall('td')])) + + testfilename = 'seltest_%s.py' % testname + testbody=' def test_%s(self):\n'%testname+' '*8+'\n '.join(commands)+'\n' + tests.append(testbody) + + f.write(self.template.substitute(dict( + testname=testname, + tests='\n'.join(tests), + ))) + f.close() Added: kukit/kss.demo/branch/1.2/kss/demo/resource.py ============================================================================== --- (empty file) +++ kukit/kss.demo/branch/1.2/kss/demo/resource.py Thu Oct 4 22:35:04 2007 @@ -0,0 +1,39 @@ +from zope.interface import implements +from interfaces import ( + IKSSDemo, + IKSSSeleniumTestDirectory, + ) + +# -- +# Reference implementations for the described elements +# They are designed to be passive +# -- + +class KSSDemo(object): + """Represents a demo. + """ + implements(IKSSDemo) + def __init__(self, plugin_namespace, category, page_url, title): + self.plugin_namespace = plugin_namespace + self.category = category + self.page_url = page_url + self.title = title + + # convenience access for page templates + __allow_access_to_unprotected_subobjects__ = 1 + def __getitem__(self, key): + return getattr(self, key) + +class KSSSeleniumTestDirectory(object): + """Represents a selenium test directory. + """ + implements(IKSSSeleniumTestDirectory) + def __init__(self, test_directory): + self.test_directory = test_directory + + # convenience access for page templates + __allow_access_to_unprotected_subobjects__ = 1 + def __getitem__(self, key): + return getattr(self, key) + + Added: kukit/kss.demo/branch/1.2/kss/demo/selenium_utils/__init__.py ============================================================================== --- (empty file) +++ kukit/kss.demo/branch/1.2/kss/demo/selenium_utils/__init__.py Thu Oct 4 22:35:04 2007 @@ -0,0 +1,4 @@ +'''\ +Module init +''' + Added: kukit/kss.demo/branch/1.2/kss/demo/selenium_utils/createpythontests.py ============================================================================== --- (empty file) +++ kukit/kss.demo/branch/1.2/kss/demo/selenium_utils/createpythontests.py Thu Oct 4 22:35:04 2007 @@ -0,0 +1,70 @@ +#!/usr/bin/env python + +raise SystemExit, 'Due to changes in the plugin registry, command line ' \ + 'method is disabled until kss.demo is ported to kss.base.\n' \ + ' (Hint: call .../@@kss_demo_registry_admin/cookSeleniumTests from zope.)' + +# Generate selenium test controller files from HTML selenium tests + +from elementtree import HTMLTreeBuilder, ElementTree +import glob +from string import Template +import os +import re + +template = Template(''' +from seleniumtestcase import SeleniumTestCase +import unittest, time + +class seltest_$testname(SeleniumTestCase): + +$tests + +def test_suite(): + return unittest.makeSuite(seltest_$testname) + +if __name__ == "__main__": + unittest.main() +''') + +variable_regexp = re.compile('\$\{(?P\w*)\}') + +def formatcommand(command, *args): + 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() +tests = [] +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 + 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() Added: kukit/kss.demo/branch/1.2/kss/demo/selenium_utils/patterns.py.txt ============================================================================== --- (empty file) +++ kukit/kss.demo/branch/1.2/kss/demo/selenium_utils/patterns.py.txt Thu Oct 4 22:35:04 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/branch/1.2/kss/demo/selenium_utils/selenium.py ============================================================================== --- (empty file) +++ kukit/kss.demo/branch/1.2/kss/demo/selenium_utils/selenium.py Thu Oct 4 22:35:04 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,]) + Added: kukit/kss.demo/branch/1.2/kss/demo/selenium_utils/seleniumtestcase.py ============================================================================== --- (empty file) +++ kukit/kss.demo/branch/1.2/kss/demo/selenium_utils/seleniumtestcase.py Thu Oct 4 22:35:04 2007 @@ -0,0 +1,113 @@ +import os +import unittest +import time + +from selenium import selenium +try: + browser = os.environ["SELENIUMBROWSER"] +except: + browser = "*firefox" +try: + target = os.environ["SELENIUMTARGET"] +except: + target = "http://localhost:8080" + + +def trymanytimes(func): + '''Decorate a test method with this to make it try for ten seconds''' + def newfunc(*args, **kwargs): + exc = None + for i in range(10): + try: + func(*args, **kwargs) + except Exception, e: + exc = e + time.sleep(1) + else: + return + raise exc + return newfunc + +class SeleniumTestCase(unittest.TestCase): + def setUp(self): + 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) + + @trymanytimes + def waitForText(self, target, text): + self.failUnless(text in self.selenium.get_text(target)) + + @trymanytimes + def waitForNotText(self, target, text): + self.failIf(text in self.selenium.get_text(target)) + + @trymanytimes + def waitForTextPresent(self, text): + self.failUnless(self.selenium.is_text_present(text)) + + @trymanytimes + def waitForElementNotPresent(self, target): + self.failIf(self.selenium.is_element_present(target)) + + @trymanytimes + def waitForElementPresent(self, target): + self.failUnless(self.selenium.is_element_present(target)) + + @trymanytimes + def waitForValue(self, target, value): + self.failUnless(self.selenium.get_value(target)) + + @trymanytimes + def waitForAttribute(self, target, value): + self.assertEqual(self.selenium.get_attribute(target), value) + + 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 assertElementNotPresent(self, target): + self.failIf(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] Modified: kukit/kss.demo/branch/1.2/kss/demo/tests/test_demoview.py ============================================================================== --- kukit/kss.demo/branch/1.2/kss/demo/tests/test_demoview.py (original) +++ kukit/kss.demo/branch/1.2/kss/demo/tests/test_demoview.py Thu Oct 4 22:35:04 2007 @@ -70,5 +70,4 @@ def test_suite(): return unittest.TestSuite(( unittest.makeSuite(KSSDemoTestCase), - doctest.DocTestSuite('kss.demo.demoview'), )) From jvloothuis at codespeak.net Fri Oct 5 21:28:52 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Fri, 5 Oct 2007 21:28:52 +0200 (CEST) Subject: [KSS-checkins] r47204 - kukit/buildout/kss-website Message-ID: <20071005192852.BD9578119@code0.codespeak.net> Author: jvloothuis Date: Fri Oct 5 21:28:52 2007 New Revision: 47204 Modified: kukit/buildout/kss-website/buildout.cfg Log: Added more products which are in use in the current site Modified: kukit/buildout/kss-website/buildout.cfg ============================================================================== --- kukit/buildout/kss-website/buildout.cfg (original) +++ kukit/buildout/kss-website/buildout.cfg Fri Oct 5 21:28:52 2007 @@ -5,7 +5,6 @@ productdistros instance zopepy - poi # Add additional egg download sources here. dist.plone.org contains archives # of Plone packages. @@ -45,16 +44,19 @@ [productdistros] recipe = plone.recipe.distros urls = - http://plone.org/products/quills/releases/1.5-alpha1/quills1-5alpha1-tar.gz + http://plone.org/products/cachefu/releases/1.1/CacheFu-1.1.tgz + http://plone.org/products/quills/releases/1.5/Quills-1.5RC3.tar.gz http://plone.org/products/plonehelpcenter/releases/1.0/plonehelpcenter-1-0.tgz + http://plone.org/products/cmfmember/releases/1.1b2/CMFMember-1.1b2.tar.gz http://plone.org/products/poi/releases/1.0/poi-1-0rc2pre1-bundle-tar.gz nested-packages = - quills1-5alpha1-tar.gz + Quills-1.5RC3.tar.gz + CacheFu-1.1.tgz [instance] recipe = plone.recipe.zope2instance zope2-location = ${zope2:location} -user = admin: +user = admin:admin http-address = 8080 debug-mode = on verbose-security = on From gotcha at codespeak.net Fri Oct 5 23:47:02 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Fri, 5 Oct 2007 23:47:02 +0200 (CEST) Subject: [KSS-checkins] r47211 - kukit/kss.demo/branch/1.2/kss/demo/demo Message-ID: <20071005214702.DDE1B80FC@code0.codespeak.net> Author: gotcha Date: Fri Oct 5 23:47:01 2007 New Revision: 47211 Removed: kukit/kss.demo/branch/1.2/kss/demo/demo/__init__.pyc Log: no pyc Deleted: /kukit/kss.demo/branch/1.2/kss/demo/demo/__init__.pyc ============================================================================== Binary file. No diff available. From gotcha at codespeak.net Fri Oct 5 23:49:23 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Fri, 5 Oct 2007 23:49:23 +0200 (CEST) Subject: [KSS-checkins] r47212 - kukit/kukit.js/branch/1.2/kukit Message-ID: <20071005214923.88A2E80FC@code0.codespeak.net> Author: gotcha Date: Fri Oct 5 23:49:23 2007 New Revision: 47212 Modified: kukit/kukit.js/branch/1.2/kukit/resourcedata.js Log: some code for firekiss Modified: kukit/kukit.js/branch/1.2/kukit/resourcedata.js ============================================================================== --- kukit/kukit.js/branch/1.2/kukit/resourcedata.js (original) +++ kukit/kukit.js/branch/1.2/kukit/resourcedata.js Fri Oct 5 23:49:23 2007 @@ -248,6 +248,7 @@ */ kukit.rd.EventRule.prototype.bind = function(node) { +;;; this.store(node); // Creation of the binding oper var oper = new kukit.op.Oper(); var binderInfo = this.getBinderInfo(); @@ -258,6 +259,14 @@ // mark on the instance as bound binderInfo.bindOper(oper); }; + +kukit.rd.EventRule.prototype.store = function(node) { +;;; if (typeof(node.kukitEventRules) == 'undefined') { +;;; var rules = []; +;;; node.kukitEventRules = rules; +;;; } +;;; node.kukitEventRules.push(this); +}; /* From gotcha at codespeak.net Fri Oct 5 23:53:36 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Fri, 5 Oct 2007 23:53:36 +0200 (CEST) Subject: [KSS-checkins] r47213 - kukit/kukit.js/tag/1.2.2 Message-ID: <20071005215336.969A880FC@code0.codespeak.net> Author: gotcha Date: Fri Oct 5 23:53:36 2007 New Revision: 47213 Added: kukit/kukit.js/tag/1.2.2/ - copied from r47212, kukit/kukit.js/branch/1.2/ Log: tag 1.2.2 From gotcha at codespeak.net Fri Oct 5 23:56:28 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Fri, 5 Oct 2007 23:56:28 +0200 (CEST) Subject: [KSS-checkins] r47214 - in kukit/kukit.js/tag/1.2.2: . doc Message-ID: <20071005215628.D80A780FC@code0.codespeak.net> Author: gotcha Date: Fri Oct 5 23:56:28 2007 New Revision: 47214 Modified: kukit/kukit.js/tag/1.2.2/doc/HISTORY.txt kukit/kukit.js/tag/1.2.2/version.txt Log: release tag Modified: kukit/kukit.js/tag/1.2.2/doc/HISTORY.txt ============================================================================== --- kukit/kukit.js/tag/1.2.2/doc/HISTORY.txt (original) +++ kukit/kukit.js/tag/1.2.2/doc/HISTORY.txt Fri Oct 5 23:56:28 2007 @@ -2,9 +2,10 @@ (name of developer listed in brackets) -kukit.js - 1.2dev Unreleased +kukit.js - 1.2.2 Released 2007-10-05 - - ... + - Some code for FireKiss + [gotcha] kukit.js - 1.2.1 Released 2007-09-10 Modified: kukit/kukit.js/tag/1.2.2/version.txt ============================================================================== --- kukit/kukit.js/tag/1.2.2/version.txt (original) +++ kukit/kukit.js/tag/1.2.2/version.txt Fri Oct 5 23:56:28 2007 @@ -1 +1 @@ -1.2dev unreleased +1.2.1 released 2007-10-05 From gotcha at codespeak.net Fri Oct 5 23:59:01 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Fri, 5 Oct 2007 23:59:01 +0200 (CEST) Subject: [KSS-checkins] r47216 - kukit/kss.concatresource/tag/1.2.2 Message-ID: <20071005215901.1201A80FC@code0.codespeak.net> Author: gotcha Date: Fri Oct 5 23:59:00 2007 New Revision: 47216 Added: kukit/kss.concatresource/tag/1.2.2/ - copied from r47215, kukit/kss.concatresource/branch/1.2/ Log: tag 1.2.2 From gotcha at codespeak.net Sat Oct 6 00:06:06 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Sat, 6 Oct 2007 00:06:06 +0200 (CEST) Subject: [KSS-checkins] r47217 - kukit/kss.concatresource/branch/1.2/kss/concatresource Message-ID: <20071005220606.DD3B88103@code0.codespeak.net> Author: gotcha Date: Sat Oct 6 00:06:04 2007 New Revision: 47217 Modified: kukit/kss.concatresource/branch/1.2/kss/concatresource/version.txt Log: release Modified: kukit/kss.concatresource/branch/1.2/kss/concatresource/version.txt ============================================================================== --- kukit/kss.concatresource/branch/1.2/kss/concatresource/version.txt (original) +++ kukit/kss.concatresource/branch/1.2/kss/concatresource/version.txt Sat Oct 6 00:06:04 2007 @@ -1 +1 @@ -1.2dev Unreleased +1.2.2 released 2007-10-05 From gotcha at codespeak.net Sat Oct 6 00:07:02 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Sat, 6 Oct 2007 00:07:02 +0200 (CEST) Subject: [KSS-checkins] r47218 - in kukit/kss.concatresource/tag/1.2.2: . docs Message-ID: <20071005220702.ACCCF8103@code0.codespeak.net> Author: gotcha Date: Sat Oct 6 00:07:00 2007 New Revision: 47218 Removed: kukit/kss.concatresource/tag/1.2.2/setup.cfg Modified: kukit/kss.concatresource/tag/1.2.2/docs/HISTORY.txt kukit/kss.concatresource/tag/1.2.2/setup.py Log: release Modified: kukit/kss.concatresource/tag/1.2.2/docs/HISTORY.txt ============================================================================== --- kukit/kss.concatresource/tag/1.2.2/docs/HISTORY.txt (original) +++ kukit/kss.concatresource/tag/1.2.2/docs/HISTORY.txt Sat Oct 6 00:07:00 2007 @@ -2,9 +2,7 @@ (name of developer listed in brackets) -kss.concatresource - 1.2dev Unreleased - - - ... +kss.concatresource - 1.2.2 Released 2007-10-05 kss.concatresource - 1.2.1 Released 2007-09-10 Deleted: /kukit/kss.concatresource/tag/1.2.2/setup.cfg ============================================================================== --- /kukit/kss.concatresource/tag/1.2.2/setup.cfg Sat Oct 6 00:07:00 2007 +++ (empty file) @@ -1,3 +0,0 @@ -[egg_info] -tag_build = dev -tag_svn_revision = true Modified: kukit/kss.concatresource/tag/1.2.2/setup.py ============================================================================== --- kukit/kss.concatresource/tag/1.2.2/setup.py (original) +++ kukit/kss.concatresource/tag/1.2.2/setup.py Sat Oct 6 00:07:00 2007 @@ -1,6 +1,6 @@ from setuptools import setup, find_packages -version = '1.2' +version = '1.2.2' setup(name='concatresource', version=version, From gotcha at codespeak.net Sat Oct 6 00:08:26 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Sat, 6 Oct 2007 00:08:26 +0200 (CEST) Subject: [KSS-checkins] r47219 - kukit/kss.core/tag/1.2.2 Message-ID: <20071005220826.834A38103@code0.codespeak.net> Author: gotcha Date: Sat Oct 6 00:08:26 2007 New Revision: 47219 Added: kukit/kss.core/tag/1.2.2/ - copied from r47218, kukit/kss.core/branch/1.2/ Log: tag 1.2.2 From gotcha at codespeak.net Sat Oct 6 00:14:03 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Sat, 6 Oct 2007 00:14:03 +0200 (CEST) Subject: [KSS-checkins] r47220 - in kukit/kss.core/tag/1.2.2: . docs kss/core kss/core/pluginregistry Message-ID: <20071005221403.C6A778103@code0.codespeak.net> Author: gotcha Date: Sat Oct 6 00:14:03 2007 New Revision: 47220 Removed: kukit/kss.core/tag/1.2.2/setup.cfg Modified: kukit/kss.core/tag/1.2.2/docs/HISTORY.txt kukit/kss.core/tag/1.2.2/kss/core/ (props changed) kukit/kss.core/tag/1.2.2/kss/core/EXTERNALS.TXT kukit/kss.core/tag/1.2.2/kss/core/pluginregistry/ (props changed) kukit/kss.core/tag/1.2.2/kss/core/pluginregistry/EXTERNALS.TXT kukit/kss.core/tag/1.2.2/kss/core/version.txt kukit/kss.core/tag/1.2.2/setup.py Log: release Modified: kukit/kss.core/tag/1.2.2/docs/HISTORY.txt ============================================================================== --- kukit/kss.core/tag/1.2.2/docs/HISTORY.txt (original) +++ kukit/kss.core/tag/1.2.2/docs/HISTORY.txt Sat Oct 6 00:14:03 2007 @@ -2,9 +2,10 @@ (name of developer listed in brackets) -kss.core - 1.2dev Unreleased +kss.core - 1.2.2 Released 2007-10-05 - - ... + - some code for firekiss + [gotcha] kss.core - 1.2.1 Released 2007-09-10 Modified: kukit/kss.core/tag/1.2.2/kss/core/EXTERNALS.TXT ============================================================================== --- kukit/kss.core/tag/1.2.2/kss/core/EXTERNALS.TXT (original) +++ kukit/kss.core/tag/1.2.2/kss/core/EXTERNALS.TXT Sat Oct 6 00:14:03 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/branch/1.2 +kukit http://codespeak.net/svn/kukit/kukit.js/tag/1.2.2 Modified: kukit/kss.core/tag/1.2.2/kss/core/pluginregistry/EXTERNALS.TXT ============================================================================== --- kukit/kss.core/tag/1.2.2/kss/core/pluginregistry/EXTERNALS.TXT (original) +++ kukit/kss.core/tag/1.2.2/kss/core/pluginregistry/EXTERNALS.TXT Sat Oct 6 00:14:03 2007 @@ -7,4 +7,4 @@ # # concatresource is now included like as batteries -_concatresource https://codespeak.net/svn/kukit/kss.concatresource/branch/1.2/kss/concatresource +_concatresource https://codespeak.net/svn/kukit/kss.concatresource/tag/1.2.2/kss/concatresource Modified: kukit/kss.core/tag/1.2.2/kss/core/version.txt ============================================================================== --- kukit/kss.core/tag/1.2.2/kss/core/version.txt (original) +++ kukit/kss.core/tag/1.2.2/kss/core/version.txt Sat Oct 6 00:14:03 2007 @@ -1 +1 @@ -1.2dev unreleased +1.2.2 released 2007-10-05 Deleted: /kukit/kss.core/tag/1.2.2/setup.cfg ============================================================================== --- /kukit/kss.core/tag/1.2.2/setup.cfg Sat Oct 6 00:14:03 2007 +++ (empty file) @@ -1,3 +0,0 @@ -[egg_info] -tag_build = dev -tag_svn_revision = true Modified: kukit/kss.core/tag/1.2.2/setup.py ============================================================================== --- kukit/kss.core/tag/1.2.2/setup.py (original) +++ kukit/kss.core/tag/1.2.2/setup.py Sat Oct 6 00:14:03 2007 @@ -1,7 +1,7 @@ from setuptools import setup, find_packages import sys, os -version = '1.2' +version = '1.2.1' setup(name='kss.core', version=version, From gotcha at codespeak.net Sat Oct 6 00:14:52 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Sat, 6 Oct 2007 00:14:52 +0200 (CEST) Subject: [KSS-checkins] r47221 - kukit/kss.demo/tag/1.2.2 Message-ID: <20071005221452.14D948108@code0.codespeak.net> Author: gotcha Date: Sat Oct 6 00:14:51 2007 New Revision: 47221 Added: kukit/kss.demo/tag/1.2.2/ - copied from r47220, kukit/kss.demo/branch/1.2/ Log: tag 1.2.2 From gotcha at codespeak.net Sat Oct 6 00:17:36 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Sat, 6 Oct 2007 00:17:36 +0200 (CEST) Subject: [KSS-checkins] r47222 - in kukit/kss.demo/tag/1.2.2: . docs kss/demo Message-ID: <20071005221736.B4D038104@code0.codespeak.net> Author: gotcha Date: Sat Oct 6 00:17:36 2007 New Revision: 47222 Removed: kukit/kss.demo/tag/1.2.2/setup.cfg Modified: kukit/kss.demo/tag/1.2.2/docs/HISTORY.txt kukit/kss.demo/tag/1.2.2/kss/demo/version.txt kukit/kss.demo/tag/1.2.2/setup.py Log: release Modified: kukit/kss.demo/tag/1.2.2/docs/HISTORY.txt ============================================================================== --- kukit/kss.demo/tag/1.2.2/docs/HISTORY.txt (original) +++ kukit/kss.demo/tag/1.2.2/docs/HISTORY.txt Sat Oct 6 00:17:36 2007 @@ -2,9 +2,7 @@ (name of developer listed in brackets) -kss.demo - 1.2dev Unreleased - - - ... +kss.demo - 1.2.2 Released 2007-10-05 - Implement pluggable demos [ree] Modified: kukit/kss.demo/tag/1.2.2/kss/demo/version.txt ============================================================================== --- kukit/kss.demo/tag/1.2.2/kss/demo/version.txt (original) +++ kukit/kss.demo/tag/1.2.2/kss/demo/version.txt Sat Oct 6 00:17:36 2007 @@ -1 +1 @@ -1.2dev Unreleased +1.2.2 released 2007-10-05 Deleted: /kukit/kss.demo/tag/1.2.2/setup.cfg ============================================================================== --- /kukit/kss.demo/tag/1.2.2/setup.cfg Sat Oct 6 00:17:36 2007 +++ (empty file) @@ -1,3 +0,0 @@ -[egg_info] -tag_build = dev -tag_svn_revision = true Modified: kukit/kss.demo/tag/1.2.2/setup.py ============================================================================== --- kukit/kss.demo/tag/1.2.2/setup.py (original) +++ kukit/kss.demo/tag/1.2.2/setup.py Sat Oct 6 00:17:36 2007 @@ -1,7 +1,7 @@ from setuptools import setup, find_packages import sys, os -version = '1.2' +version = '1.2.2' setup(name='kss.demo', version=version, @@ -26,12 +26,9 @@ zip_safe=False, install_requires=[ # -*- Extra requirements: -*- - 'kss.core>=dev', + 'kss.core>=1.2.2', ], entry_points=""" # -*- Entry points: -*- """, - dependency_links=[ - 'https://codespeak.net/svn/kukit/kss.core/branch/1.2#egg=kss.core-dev', - ], ) From gotcha at codespeak.net Sat Oct 6 00:28:58 2007 From: gotcha at codespeak.net (gotcha at codespeak.net) Date: Sat, 6 Oct 2007 00:28:58 +0200 (CEST) Subject: [KSS-checkins] r47223 - kukit/kss.core/tag/1.2.2 Message-ID: <20071005222858.A72EF810C@code0.codespeak.net> Author: gotcha Date: Sat Oct 6 00:28:58 2007 New Revision: 47223 Modified: kukit/kss.core/tag/1.2.2/setup.py Log: fix typo Modified: kukit/kss.core/tag/1.2.2/setup.py ============================================================================== --- kukit/kss.core/tag/1.2.2/setup.py (original) +++ kukit/kss.core/tag/1.2.2/setup.py Sat Oct 6 00:28:58 2007 @@ -1,7 +1,7 @@ from setuptools import setup, find_packages import sys, os -version = '1.2.1' +version = '1.2.2' setup(name='kss.core', version=version, From kukit-checkins at codespeak.net Sat Oct 6 05:32:14 2007 From: kukit-checkins at codespeak.net (VIAGRA ® Official Site) Date: Sat, 6 Oct 2007 05:32:14 +0200 (CEST) Subject: [KSS-checkins] October 78% OFF Message-ID: <20071006043355.79689.qmail@host217-44-170-218.range217-44.btcentralplus.com> An HTML attachment was scrubbed... URL: http://codespeak.net/pipermail/kukit-checkins/attachments/20071006/dc3858fc/attachment-0001.htm From jvloothuis at codespeak.net Sat Oct 6 09:23:03 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Sat, 6 Oct 2007 09:23:03 +0200 (CEST) Subject: [KSS-checkins] r47224 - kukit/buildout/kss.templates/trunk Message-ID: <20071006072303.8622380FE@code0.codespeak.net> Author: jvloothuis Date: Sat Oct 6 09:23:01 2007 New Revision: 47224 Modified: kukit/buildout/kss.templates/trunk/buildout.cfg Log: Removed PasterScript from eggs, should be required by kss.templates Modified: kukit/buildout/kss.templates/trunk/buildout.cfg ============================================================================== --- kukit/buildout/kss.templates/trunk/buildout.cfg (original) +++ kukit/buildout/kss.templates/trunk/buildout.cfg Sat Oct 6 09:23:01 2007 @@ -1,7 +1,8 @@ [buildout] parts = scripts -develop = src/kss.templates -eggs = PasteScript +develop = + src/kss.templates +eggs = [scripts] recipe = zc.recipe.egg From jvloothuis at codespeak.net Sat Oct 6 09:24:01 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Sat, 6 Oct 2007 09:24:01 +0200 (CEST) Subject: [KSS-checkins] r47225 - kukit/kss.templates/trunk Message-ID: <20071006072401.279D78103@code0.codespeak.net> Author: jvloothuis Date: Sat Oct 6 09:24:00 2007 New Revision: 47225 Modified: kukit/kss.templates/trunk/setup.py Log: Added PasteScript to the requirements Modified: kukit/kss.templates/trunk/setup.py ============================================================================== --- kukit/kss.templates/trunk/setup.py (original) +++ kukit/kss.templates/trunk/setup.py Sat Oct 6 09:24:00 2007 @@ -1,19 +1,27 @@ from setuptools import setup, find_packages -import sys, os version = '0.1' setup(name='kss.templates', version=version, description="Templates for creating KSS plugins", - long_description="""\ + long_description=""" +kss.templates provides templates for development with KSS. It +currently has templates for creating plugins. These generate the +server side and client side code (including heavily commented +Javascript code). """, - # Get more strings from http://www.python.org/pypi?%3Aaction=list_classifiers classifiers=[ + "Development Status :: 3 - Alpha", + "Framework :: KSS", + "Intended Audience :: Developers", + "License :: OSI Approved :: GNU General Public License (GPL)", + "Operating System :: OS Independent", "Programming Language :: Python", - "Topic :: Software Development :: Libraries :: Python Modules", + "Programming Language :: JavaScript", + "Topic :: Software Development :: Code Generators", ], - keywords='', + keywords='skeleton kss plugin', author='KSS Project', author_email='kss-devel at codespeak.net', url='http://kssproject.org', @@ -24,6 +32,7 @@ zip_safe=False, install_requires=[ 'setuptools', + 'PasteScript' ], entry_points={ 'paste.paster_create_template': [ @@ -31,5 +40,4 @@ 'kss_zope_plugin=kss.templates.util:KSSZopePluginTemplate', ], }, - #test_suite='kss.templates.tests.test_suite', ) From jvloothuis at codespeak.net Sat Oct 6 09:32:26 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Sat, 6 Oct 2007 09:32:26 +0200 (CEST) Subject: [KSS-checkins] r47226 - kukit/kss.templates/trunk Message-ID: <20071006073226.D627380FE@code0.codespeak.net> Author: jvloothuis Date: Sat Oct 6 09:32:26 2007 New Revision: 47226 Modified: kukit/kss.templates/trunk/setup.py Log: Change framework to Paste (KSS does not yet exist) Modified: kukit/kss.templates/trunk/setup.py ============================================================================== --- kukit/kss.templates/trunk/setup.py (original) +++ kukit/kss.templates/trunk/setup.py Sat Oct 6 09:32:26 2007 @@ -13,7 +13,7 @@ """, classifiers=[ "Development Status :: 3 - Alpha", - "Framework :: KSS", + "Framework :: Paste", "Intended Audience :: Developers", "License :: OSI Approved :: GNU General Public License (GPL)", "Operating System :: OS Independent", From jvloothuis at codespeak.net Sat Oct 6 11:12:36 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Sat, 6 Oct 2007 11:12:36 +0200 (CEST) Subject: [KSS-checkins] r47227 - kukit/docs/creating-plugins-plone-conf-2007/src/KSSDemoPlugin/kssdemoplugin/javascript Message-ID: <20071006091236.E76B380FB@code0.codespeak.net> Author: jvloothuis Date: Sat Oct 6 11:12:35 2007 New Revision: 47227 Modified: kukit/docs/creating-plugins-plone-conf-2007/src/KSSDemoPlugin/kssdemoplugin/javascript/plugin.js Log: Finished the demo for the event Modified: kukit/docs/creating-plugins-plone-conf-2007/src/KSSDemoPlugin/kssdemoplugin/javascript/plugin.js ============================================================================== --- kukit/docs/creating-plugins-plone-conf-2007/src/KSSDemoPlugin/kssdemoplugin/javascript/plugin.js (original) +++ kukit/docs/creating-plugins-plone-conf-2007/src/KSSDemoPlugin/kssdemoplugin/javascript/plugin.js Sat Oct 6 11:12:35 2007 @@ -72,35 +72,79 @@ kukit.pprovidersGlobalRegistry.register( 'demoplugin-random', RandomProvider); + +var RandomColorProvider = function() {}; +RandomColorProvider.prototype = { +;;; check: function(args) { +;;; // An example of what you could check is the argument length +// ;;; if (args.length < 1) { +// ;;; // Raise an error in case something is wrong +// ;;; throw new Error('demoplugin-randomColor needs at least 1 argument [max]'); +// ;;; } +;;; }, + eval: function(args, node) { + // Return the value which for this provider + var color = "rgba("; + for(var i=0; i<3; i++){ + color += Math.round(Math.random() * 255) + ", "; + } + return color + "0.2)"; + } +}; +kukit.pprovidersGlobalRegistry.register( + 'demoplugin-randomColor', RandomColorProvider); + //----------------------------------------------------------- // Simple event binder for stateful events //----------------------------------------------------------- -var ExampleEventBinder = function() { - // Add your initialization stuff here - this.exampleVar = {}; +var MovementEventBinder = function() { + this.x = 0; + this.y = 0; }; -ExampleEventBinder.prototype.__bind__ = function(name, func_to_bind, oper) { - // The following is used for logging -;;; oper.componentName = '[demoplugin-example] event binding'; - // Validate the parameters to this action, you can add multiple - // required or optional parameters. Optional parameters will be - // initialized with a default when not passed. - oper.evaluateParameters(['delay'], {'repeat': 'true'}); - - // optionally, you can check if a parameter is of a given data type, - // and convert to it. - oper.evalInt('delay'); - oper.evalBool('repeat'); + +MovementEventBinder.prototype.__bind__ = function(name, func_to_bind, oper) { + // The following is used for logging +;;; oper.componentName = '[demoplugin-movement] event binding'; - // Add your specific event code here + var keyMovement = { + 37: [-1, 0], // left + 38: [0, -1], // up + 39: [1, 0], // right + 40: [0, 1] // down + }; + + oper.completeParms([], {'x': '0', 'y': '0', 'speed': '1'}, 'movement event binding'); + oper.evalInt('x'); + oper.evalInt('y'); + oper.evalInt('speed'); + + var speed = oper.parms.speed; + + var f = oper.makeExecuteActionsHook(); + + var self = this; + // Set filter so that only the specified keys should trigger. + func = function(e) { + var keyCode = e.keyCode.toString(); + + // Ignore all non movement keys + if(typeof(keyMovement[keyCode]) == 'undefined'){ + return; + } + + self.x += keyMovement[keyCode][0] * speed; + self.y += keyMovement[keyCode][1] * speed; + + var parms = {'x': self.x, 'y': self.y}; + f({defaultParameters: parms}); + }; + kukit.ut.registerEventListener(document, 'keydown', func); }; -kukit.eventsGlobalRegistry.register('demoplugin', 'exampleEvent', - ExampleEventBinder, '__bind__', null); -// The above line registers the demoplugin-exampleEvent -// with the binder method __bind__. +kukit.eventsGlobalRegistry.register('demoplugin', 'movement', + MovementEventBinder, '__bind__', null); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< From jvloothuis at codespeak.net Sat Oct 6 11:14:08 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Sat, 6 Oct 2007 11:14:08 +0200 (CEST) Subject: [KSS-checkins] r47228 - in kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo: . profiles profiles/default skins skins/plonedemo Message-ID: <20071006091408.E5FCF8105@code0.codespeak.net> Author: jvloothuis Date: Sat Oct 6 11:14:08 2007 New Revision: 47228 Added: kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/plone-demo-plugin.kss kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/profiles/ kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/profiles/default/ kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/profiles/default/kssregistry.xml kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/profiles/default/skins.xml kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/skins/ kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/skins/plonedemo/ kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/skins/plonedemo/canvas_view.pt Log: Added Plone integration bits to show the plugin in action Added: kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/plone-demo-plugin.kss ============================================================================== --- (empty file) +++ kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/plone-demo-plugin.kss Sat Oct 6 11:14:08 2007 @@ -0,0 +1,28 @@ +/* + +This KSS file demonstrates the usage of the demo plugin. + +*/ + + +/* #canvas:timeout { */ +/* evt-timeout-delay: 1; */ +/* evt-timeout-repeat: True; */ + +/* action-client: demoplugin-canvasRect; */ +/* demoplugin-canvasRect-x: demoplugin-random(0, 300); */ +/* demoplugin-canvasRect-y: demoplugin-random(0, 300); */ +/* demoplugin-canvasRect-width: demoplugin-random(10, 30); */ +/* demoplugin-canvasRect-height: demoplugin-random(10, 30); */ +/* demoplugin-canvasRect-fillStyle: demoplugin-randomColor(); */ +/* } */ + +#canvas:demoplugin-movement { + action-client: demoplugin-canvasRect; + evt-demoplugin-movement-speed: 10; + demoplugin-canvasRect-x: pass(x); + demoplugin-canvasRect-y: pass(y); + demoplugin-canvasRect-width: 10; + demoplugin-canvasRect-height: 10; + demoplugin-canvasRect-fillStyle: "rgb(255, 0, 255)"; +} \ No newline at end of file Added: kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/profiles/default/kssregistry.xml ============================================================================== --- (empty file) +++ kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/profiles/default/kssregistry.xml Sat Oct 6 11:14:08 2007 @@ -0,0 +1,6 @@ + + + + Added: kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/profiles/default/skins.xml ============================================================================== --- (empty file) +++ kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/profiles/default/skins.xml Sat Oct 6 11:14:08 2007 @@ -0,0 +1,8 @@ + + + + + + + Added: kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/skins/plonedemo/canvas_view.pt ============================================================================== --- (empty file) +++ kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/skins/plonedemo/canvas_view.pt Sat Oct 6 11:14:08 2007 @@ -0,0 +1,13 @@ + + + +
+ + + +
+ + \ No newline at end of file From reebalazs at codespeak.net Sat Oct 6 12:25:02 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Sat, 6 Oct 2007 12:25:02 +0200 (CEST) Subject: [KSS-checkins] r47229 - kukit/kukit.js/trunk/kukit Message-ID: <20071006102502.1767C8119@code0.codespeak.net> Author: reebalazs Date: Sat Oct 6 12:25:01 2007 New Revision: 47229 Modified: kukit/kukit.js/trunk/kukit/forms.js Log: Make kukit.fo.fieldUpdateRegistry global, as this is meant to be used by plugins. Modified: kukit/kukit.js/trunk/kukit/forms.js ============================================================================== --- kukit/kukit.js/trunk/kukit/forms.js (original) +++ kukit/kukit.js/trunk/kukit/forms.js Sat Oct 6 12:25:01 2007 @@ -167,7 +167,7 @@ // Returns the value of the form element / or null // First: update the field in case an editor is lurking // in the background - _fieldUpdateRegistry.doUpdate(element); + fieldUpdateRegistry.doUpdate(element); // Collect the data if (element.selectedIndex != undefined) { // handle single selects first @@ -298,7 +298,9 @@ } }; -var _fieldUpdateRegistry = new _FieldUpdateRegistry(); +// fieldUpdateRegistry is a public service, available to all components +// that want to be notified when kss wants to use a field value. +this.fieldUpdateRegistry = new _FieldUpdateRegistry(); // Registry of the pprovider functions for kssSubmitForm From jvloothuis at codespeak.net Sat Oct 6 12:49:49 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Sat, 6 Oct 2007 12:49:49 +0200 (CEST) Subject: [KSS-checkins] r47231 - kukit/docs/creating-plugins-plone-conf-2007 Message-ID: <20071006104949.534BA8116@code0.codespeak.net> Author: jvloothuis Date: Sat Oct 6 12:49:49 2007 New Revision: 47231 Modified: kukit/docs/creating-plugins-plone-conf-2007/kss-presentation.odp Log: Added more slides about the Javascript plugin Modified: kukit/docs/creating-plugins-plone-conf-2007/kss-presentation.odp ============================================================================== Binary files. No diff available. From jvloothuis at codespeak.net Sat Oct 6 13:33:08 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Sat, 6 Oct 2007 13:33:08 +0200 (CEST) Subject: [KSS-checkins] r47234 - kukit/docs/creating-plugins-plone-conf-2007 Message-ID: <20071006113308.EDFE8811F@code0.codespeak.net> Author: jvloothuis Date: Sat Oct 6 13:33:08 2007 New Revision: 47234 Modified: kukit/docs/creating-plugins-plone-conf-2007/kss-presentation.odp Log: Added slides about creating commandsets Modified: kukit/docs/creating-plugins-plone-conf-2007/kss-presentation.odp ============================================================================== Binary files. No diff available. From jvloothuis at codespeak.net Sat Oct 6 13:33:56 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Sat, 6 Oct 2007 13:33:56 +0200 (CEST) Subject: [KSS-checkins] r47235 - in kukit/docs/creating-plugins-plone-conf-2007/src: KSSDemoPlugin/kssdemoplugin KSSDemoPlugin/kssdemoplugin/javascript plonedemo/plonedemo plonedemo/plonedemo/skins/plonedemo Message-ID: <20071006113356.621A58117@code0.codespeak.net> Author: jvloothuis Date: Sat Oct 6 13:33:55 2007 New Revision: 47235 Added: kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/canvas.py kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/skins/plonedemo/canvas_commandset.pt Modified: kukit/docs/creating-plugins-plone-conf-2007/src/KSSDemoPlugin/kssdemoplugin/commands.py kukit/docs/creating-plugins-plone-conf-2007/src/KSSDemoPlugin/kssdemoplugin/configure.zcml kukit/docs/creating-plugins-plone-conf-2007/src/KSSDemoPlugin/kssdemoplugin/interfaces.py kukit/docs/creating-plugins-plone-conf-2007/src/KSSDemoPlugin/kssdemoplugin/javascript/plugin.js kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/configure.zcml kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/plone-demo-plugin.kss Log: Added commandset demo Modified: kukit/docs/creating-plugins-plone-conf-2007/src/KSSDemoPlugin/kssdemoplugin/commands.py ============================================================================== --- kukit/docs/creating-plugins-plone-conf-2007/src/KSSDemoPlugin/kssdemoplugin/commands.py (original) +++ kukit/docs/creating-plugins-plone-conf-2007/src/KSSDemoPlugin/kssdemoplugin/commands.py Sat Oct 6 13:33:55 2007 @@ -1,10 +1,14 @@ from kss.core.kssview import CommandSet -class KssdemopluginCommands(CommandSet): +class KSSDemoPluginCommands(CommandSet): - # Add your own actions here, you can use the following code as - # a starting point - def yourAction(self, selector, data): - command = self.commands.addCommand('yourAction', selector) - # Repeat for each parameter you need - command.addParam('parameter', data) + def canvasRect(self, selector, x, y, width, height, fillStyle=None): + command = self.commands.addCommand('demoplugin-canvasRect', selector) + + command.addParam('x', str(int(x))) + command.addParam('y', str(int(y))) + command.addParam('width', str(int(width))) + command.addParam('height', str(int(height))) + + if fillStyle is not None: + command.addParam('fillStyle', fillStyle) Modified: kukit/docs/creating-plugins-plone-conf-2007/src/KSSDemoPlugin/kssdemoplugin/configure.zcml ============================================================================== --- kukit/docs/creating-plugins-plone-conf-2007/src/KSSDemoPlugin/kssdemoplugin/configure.zcml (original) +++ kukit/docs/creating-plugins-plone-conf-2007/src/KSSDemoPlugin/kssdemoplugin/configure.zcml Sat Oct 6 13:33:55 2007 @@ -19,12 +19,10 @@ - @@ -37,17 +35,22 @@ /> + + Modified: kukit/docs/creating-plugins-plone-conf-2007/src/KSSDemoPlugin/kssdemoplugin/interfaces.py ============================================================================== --- kukit/docs/creating-plugins-plone-conf-2007/src/KSSDemoPlugin/kssdemoplugin/interfaces.py (original) +++ kukit/docs/creating-plugins-plone-conf-2007/src/KSSDemoPlugin/kssdemoplugin/interfaces.py Sat Oct 6 13:33:55 2007 @@ -1,7 +1,7 @@ from zope.interface import Interface -class IKssdemopluginCommands(Interface): - '''Documentation for your command set''' +class IKSSDemoPluginCommands(Interface): + '''Demo plugin''' - def yourAction(selector, data): - '''Documentation on yourAction''' + def canvasRect(self, selector, x, y, width, height, fillStyle=None): + '''Draw a rectangle on a cavas node''' Modified: kukit/docs/creating-plugins-plone-conf-2007/src/KSSDemoPlugin/kssdemoplugin/javascript/plugin.js ============================================================================== --- kukit/docs/creating-plugins-plone-conf-2007/src/KSSDemoPlugin/kssdemoplugin/javascript/plugin.js (original) +++ kukit/docs/creating-plugins-plone-conf-2007/src/KSSDemoPlugin/kssdemoplugin/javascript/plugin.js Sat Oct 6 13:33:55 2007 @@ -48,14 +48,11 @@ var RandomProvider = function() {}; RandomProvider.prototype = { ;;; check: function(args) { -;;; // An example of what you could check is the argument length ;;; if (args.length < 1) { -;;; // Raise an error in case something is wrong ;;; throw new Error('demoplugin-random needs at least 1 argument [max]'); ;;; } ;;; }, eval: function(args, node) { - // Return the value which for this provider if(args.length == 2){ var min = args[0]; var max = args[1]; @@ -66,7 +63,6 @@ var range = max - min; var rand = (Math.random() * range) + min; return rand; - } }; kukit.pprovidersGlobalRegistry.register( @@ -103,9 +99,7 @@ this.y = 0; }; - MovementEventBinder.prototype.__bind__ = function(name, func_to_bind, oper) { - // The following is used for logging ;;; oper.componentName = '[demoplugin-movement] event binding'; var keyMovement = { @@ -115,30 +109,26 @@ 40: [0, 1] // down }; - oper.completeParms([], {'x': '0', 'y': '0', 'speed': '1'}, 'movement event binding'); + oper.completeParms([], {'x': '0', 'y': '0', 'speed': '1'}, + 'movement event binding'); oper.evalInt('x'); oper.evalInt('y'); oper.evalInt('speed'); + var self = this; var speed = oper.parms.speed; var f = oper.makeExecuteActionsHook(); - var self = this; - // Set filter so that only the specified keys should trigger. func = function(e) { var keyCode = e.keyCode.toString(); - - // Ignore all non movement keys if(typeof(keyMovement[keyCode]) == 'undefined'){ return; } - self.x += keyMovement[keyCode][0] * speed; self.y += keyMovement[keyCode][1] * speed; - var parms = {'x': self.x, 'y': self.y}; - f({defaultParameters: parms}); + f({defaultParameters: {'x': self.x, 'y': self.y}}); }; kukit.ut.registerEventListener(document, 'keydown', func); }; Added: kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/canvas.py ============================================================================== --- (empty file) +++ kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/canvas.py Sat Oct 6 13:33:55 2007 @@ -0,0 +1,12 @@ +from kss.core import kssaction, KSSView + + +class CanvasView(KSSView): + + @kssaction + def drawRectangle(self, size): + 'In-place refreshment of the calendar.' + ksscore = self.getCommandSet('core') + selector = ksscore.getHtmlIdSelector('canvas-commandset') + + self.getCommandSet('demoplugin').canvasRect(selector, 10, 10, size, size) Modified: kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/configure.zcml ============================================================================== --- kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/configure.zcml (original) +++ kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/configure.zcml Sat Oct 6 13:33:55 2007 @@ -26,5 +26,13 @@ recursive="True" /> - + + + Modified: kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/plone-demo-plugin.kss ============================================================================== --- kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/plone-demo-plugin.kss (original) +++ kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/plone-demo-plugin.kss Sat Oct 6 13:33:55 2007 @@ -5,17 +5,28 @@ */ -/* #canvas:timeout { */ -/* evt-timeout-delay: 1; */ -/* evt-timeout-repeat: True; */ - -/* action-client: demoplugin-canvasRect; */ -/* demoplugin-canvasRect-x: demoplugin-random(0, 300); */ -/* demoplugin-canvasRect-y: demoplugin-random(0, 300); */ -/* demoplugin-canvasRect-width: demoplugin-random(10, 30); */ -/* demoplugin-canvasRect-height: demoplugin-random(10, 30); */ -/* demoplugin-canvasRect-fillStyle: demoplugin-randomColor(); */ -/* } */ +#canvas:load { + action-client: demoplugin-canvasRect; + demoplugin-canvasRect-x: 10; + demoplugin-canvasRect-y: 10; + demoplugin-canvasRect-width: 200; + demoplugin-canvasRect-height: 200; + demoplugin-canvasRect-fillStyle: "rgb(0, 255, 0)"; +} + + + +#canvas:timeout { + evt-timeout-delay: 1; + evt-timeout-repeat: True; + + action-client: demoplugin-canvasRect; + demoplugin-canvasRect-x: demoplugin-random(0, 300); + demoplugin-canvasRect-y: demoplugin-random(0, 300); + demoplugin-canvasRect-width: demoplugin-random(10, 30); + demoplugin-canvasRect-height: demoplugin-random(10, 30); + demoplugin-canvasRect-fillStyle: demoplugin-randomColor(); +} #canvas:demoplugin-movement { action-client: demoplugin-canvasRect; @@ -25,4 +36,9 @@ demoplugin-canvasRect-width: 10; demoplugin-canvasRect-height: 10; demoplugin-canvasRect-fillStyle: "rgb(255, 0, 255)"; -} \ No newline at end of file +} + +#canvas-commandset:load { + action-server: drawRectangle; + drawRectangle-size: 200; +} Added: kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/skins/plonedemo/canvas_commandset.pt ============================================================================== --- (empty file) +++ kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/skins/plonedemo/canvas_commandset.pt Sat Oct 6 13:33:55 2007 @@ -0,0 +1,13 @@ + + + +
+ + + +
+ + \ No newline at end of file From jvloothuis at codespeak.net Sat Oct 6 14:11:55 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Sat, 6 Oct 2007 14:11:55 +0200 (CEST) Subject: [KSS-checkins] r47240 - kukit/docs/creating-plugins-plone-conf-2007 Message-ID: <20071006121155.EB5E7811D@code0.codespeak.net> Author: jvloothuis Date: Sat Oct 6 14:11:54 2007 New Revision: 47240 Modified: kukit/docs/creating-plugins-plone-conf-2007/kss-presentation.odp Log: Added terminologie slides Modified: kukit/docs/creating-plugins-plone-conf-2007/kss-presentation.odp ============================================================================== Binary files. No diff available. From jvloothuis at codespeak.net Sat Oct 6 14:17:08 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Sat, 6 Oct 2007 14:17:08 +0200 (CEST) Subject: [KSS-checkins] r47241 - kukit/docs/creating-plugins-plone-conf-2007 Message-ID: <20071006121708.609A5811D@code0.codespeak.net> Author: jvloothuis Date: Sat Oct 6 14:17:07 2007 New Revision: 47241 Modified: kukit/docs/creating-plugins-plone-conf-2007/kss-presentation.odp Log: Tweaked the slides a bit for better readability Modified: kukit/docs/creating-plugins-plone-conf-2007/kss-presentation.odp ============================================================================== Binary files. No diff available. From jvloothuis at codespeak.net Sat Oct 6 14:17:42 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Sat, 6 Oct 2007 14:17:42 +0200 (CEST) Subject: [KSS-checkins] r47242 - kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo Message-ID: <20071006121742.19280811E@code0.codespeak.net> Author: jvloothuis Date: Sat Oct 6 14:17:41 2007 New Revision: 47242 Modified: kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/canvas.py Log: Remove line feed so that it will fit better on the slide Modified: kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/canvas.py ============================================================================== --- kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/canvas.py (original) +++ kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/canvas.py Sat Oct 6 14:17:41 2007 @@ -1,6 +1,5 @@ from kss.core import kssaction, KSSView - class CanvasView(KSSView): @kssaction From jvloothuis at codespeak.net Sat Oct 6 18:05:28 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Sat, 6 Oct 2007 18:05:28 +0200 (CEST) Subject: [KSS-checkins] r47244 - kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/skins/plonedemo Message-ID: <20071006160528.86B658128@code0.codespeak.net> Author: jvloothuis Date: Sat Oct 6 18:05:28 2007 New Revision: 47244 Added: kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/skins/plonedemo/canvas_action.pt kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/skins/plonedemo/canvas_event.pt kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/skins/plonedemo/canvas_provider.pt Log: Added demo templates Added: kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/skins/plonedemo/canvas_action.pt ============================================================================== --- (empty file) +++ kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/skins/plonedemo/canvas_action.pt Sat Oct 6 18:05:28 2007 @@ -0,0 +1,13 @@ + + + +
+ + + +
+ + \ No newline at end of file Added: kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/skins/plonedemo/canvas_event.pt ============================================================================== --- (empty file) +++ kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/skins/plonedemo/canvas_event.pt Sat Oct 6 18:05:28 2007 @@ -0,0 +1,13 @@ + + + +
+ + + +
+ + \ No newline at end of file Added: kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/skins/plonedemo/canvas_provider.pt ============================================================================== --- (empty file) +++ kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/skins/plonedemo/canvas_provider.pt Sat Oct 6 18:05:28 2007 @@ -0,0 +1,13 @@ + + + +
+ + + +
+ + \ No newline at end of file From jvloothuis at codespeak.net Sat Oct 6 18:05:59 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Sat, 6 Oct 2007 18:05:59 +0200 (CEST) Subject: [KSS-checkins] r47245 - in kukit/docs/creating-plugins-plone-conf-2007: . src/KSSDemoPlugin/kssdemoplugin src/plonedemo/plonedemo Message-ID: <20071006160559.726FC813B@code0.codespeak.net> Author: jvloothuis Date: Sat Oct 6 18:05:59 2007 New Revision: 47245 Modified: kukit/docs/creating-plugins-plone-conf-2007/kss-presentation.odp kukit/docs/creating-plugins-plone-conf-2007/src/KSSDemoPlugin/kssdemoplugin/configure.zcml kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/canvas.py kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/plone-demo-plugin.kss Log: Cleanup of the code and slides (fixed some errors) Modified: kukit/docs/creating-plugins-plone-conf-2007/kss-presentation.odp ============================================================================== Binary files. No diff available. Modified: kukit/docs/creating-plugins-plone-conf-2007/src/KSSDemoPlugin/kssdemoplugin/configure.zcml ============================================================================== --- kukit/docs/creating-plugins-plone-conf-2007/src/KSSDemoPlugin/kssdemoplugin/configure.zcml (original) +++ kukit/docs/creating-plugins-plone-conf-2007/src/KSSDemoPlugin/kssdemoplugin/configure.zcml Sat Oct 6 18:05:59 2007 @@ -30,7 +30,7 @@ name="demoplugin-canvasRect" jsfile="javascript/plugin.js" command_factory="selector" - params_mandatory="fromX fromY toX toY" + params_mandatory="x y width height" params_optional="fillStyle" /> Modified: kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/canvas.py ============================================================================== --- kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/canvas.py (original) +++ kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/canvas.py Sat Oct 6 18:05:59 2007 @@ -4,7 +4,6 @@ @kssaction def drawRectangle(self, size): - 'In-place refreshment of the calendar.' ksscore = self.getCommandSet('core') selector = ksscore.getHtmlIdSelector('canvas-commandset') Modified: kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/plone-demo-plugin.kss ============================================================================== --- kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/plone-demo-plugin.kss (original) +++ kukit/docs/creating-plugins-plone-conf-2007/src/plonedemo/plonedemo/plone-demo-plugin.kss Sat Oct 6 18:05:59 2007 @@ -5,7 +5,7 @@ */ -#canvas:load { +#canvas-action:load { action-client: demoplugin-canvasRect; demoplugin-canvasRect-x: 10; demoplugin-canvasRect-y: 10; @@ -16,19 +16,19 @@ -#canvas:timeout { +#canvas-provider:timeout { evt-timeout-delay: 1; evt-timeout-repeat: True; action-client: demoplugin-canvasRect; - demoplugin-canvasRect-x: demoplugin-random(0, 300); - demoplugin-canvasRect-y: demoplugin-random(0, 300); + demoplugin-canvasRect-x: demoplugin-random(300); + demoplugin-canvasRect-y: demoplugin-random(300); demoplugin-canvasRect-width: demoplugin-random(10, 30); demoplugin-canvasRect-height: demoplugin-random(10, 30); demoplugin-canvasRect-fillStyle: demoplugin-randomColor(); } -#canvas:demoplugin-movement { +#canvas-event:demoplugin-movement { action-client: demoplugin-canvasRect; evt-demoplugin-movement-speed: 10; demoplugin-canvasRect-x: pass(x); From reebalazs at codespeak.net Mon Oct 8 15:07:25 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Mon, 8 Oct 2007 15:07:25 +0200 (CEST) Subject: [KSS-checkins] r47288 - kukit/kukit.js/branch/1.2/kukit Message-ID: <20071008130725.6811A81AB@code0.codespeak.net> Author: reebalazs Date: Mon Oct 8 15:07:22 2007 New Revision: 47288 Modified: kukit/kukit.js/branch/1.2/kukit/resourcedata.js Log: Critical fix, node can be null. Modified: kukit/kukit.js/branch/1.2/kukit/resourcedata.js ============================================================================== --- kukit/kukit.js/branch/1.2/kukit/resourcedata.js (original) +++ kukit/kukit.js/branch/1.2/kukit/resourcedata.js Mon Oct 8 15:07:22 2007 @@ -261,6 +261,10 @@ }; kukit.rd.EventRule.prototype.store = function(node) { +;;; if (node == null) { +;;; // node == null is *always* valid, it means "document". +;;; return; +;;; } ;;; if (typeof(node.kukitEventRules) == 'undefined') { ;;; var rules = []; ;;; node.kukitEventRules = rules; From reebalazs at codespeak.net Mon Oct 8 15:10:31 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Mon, 8 Oct 2007 15:10:31 +0200 (CEST) Subject: [KSS-checkins] r47289 - kukit/kukit.js/trunk/kukit Message-ID: <20071008131031.BE68381AB@code0.codespeak.net> Author: reebalazs Date: Mon Oct 8 15:10:31 2007 New Revision: 47289 Modified: kukit/kukit.js/trunk/kukit/resourcedata.js Log: Port up of -r47288 from 1.2 branch: Critical fix, node can be null. Modified: kukit/kukit.js/trunk/kukit/resourcedata.js ============================================================================== --- kukit/kukit.js/trunk/kukit/resourcedata.js (original) +++ kukit/kukit.js/trunk/kukit/resourcedata.js Mon Oct 8 15:10:31 2007 @@ -340,6 +340,10 @@ }; kukit.rd.EventRule.prototype.store = function(node) { + if (node == null) { + // node == null is *always* valid, it means "document". + return; + } if (typeof(node.kukitEventRules) == 'undefined') { var rules = []; node.kukitEventRules = rules; From reebalazs at codespeak.net Mon Oct 8 15:11:39 2007 From: reebalazs at codespeak.net (reebalazs at codespeak.net) Date: Mon, 8 Oct 2007 15:11:39 +0200 (CEST) Subject: [KSS-checkins] r47290 - kukit/kukit.js/tag/1.2.2/kukit Message-ID: <20071008131139.3388A81AB@code0.codespeak.net> Author: reebalazs Date: Mon Oct 8 15:11:38 2007 New Revision: 47290 Modified: kukit/kukit.js/tag/1.2.2/kukit/resourcedata.js Log: Port up of -r47288 from 1.2 branch: Critical fix, node can be null. Modified: kukit/kukit.js/tag/1.2.2/kukit/resourcedata.js ============================================================================== --- kukit/kukit.js/tag/1.2.2/kukit/resourcedata.js (original) +++ kukit/kukit.js/tag/1.2.2/kukit/resourcedata.js Mon Oct 8 15:11:38 2007 @@ -261,6 +261,10 @@ }; kukit.rd.EventRule.prototype.store = function(node) { +;;; if (node == null) { +;;; // node == null is *always* valid, it means "document". +;;; return; +;;; } ;;; if (typeof(node.kukitEventRules) == 'undefined') { ;;; var rules = []; ;;; node.kukitEventRules = rules; From jvloothuis at codespeak.net Wed Oct 10 11:40:07 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Wed, 10 Oct 2007 11:40:07 +0200 (CEST) Subject: [KSS-checkins] r47376 - in kukit/kss.base/trunk: . kss/base Message-ID: <20071010094007.08B5781EA@code0.codespeak.net> Author: jvloothuis Date: Wed Oct 10 11:40:07 2007 New Revision: 47376 Added: kukit/kss.base/trunk/kss/base/config.py kukit/kss.base/trunk/kss/base/corecommands.txt kukit/kss.base/trunk/kss/base/registry.txt Removed: kukit/kss.base/trunk/kss/base/pluginregistry.txt Modified: kukit/kss.base/trunk/kss/base/README.txt kukit/kss.base/trunk/kss/base/commands.py kukit/kss.base/trunk/kss/base/commandset.py kukit/kss.base/trunk/kss/base/corecommands.py kukit/kss.base/trunk/kss/base/plugin.py kukit/kss.base/trunk/kss/base/registry.py kukit/kss.base/trunk/kss/base/tests.py kukit/kss.base/trunk/setup.py Log: Refactored the registries and added more tests Modified: kukit/kss.base/trunk/kss/base/README.txt ============================================================================== --- kukit/kss.base/trunk/kss/base/README.txt (original) +++ kukit/kss.base/trunk/kss/base/README.txt Wed Oct 10 11:40:07 2007 @@ -112,24 +112,6 @@ The thing that makes this interesting is the actual command sets. Take a look at the core commands for a better understanding of the usage pattern. -Core commands -------------- - -The core commands wrap all standard KSS actions that are always available. -These do not contain any effects and focus mostly on DOM manipulation. - -First we will need to create our command set. - - >>> from kss.base.corecommands import KSSCoreCommands - >>> commands = KSSCommands() - >>> core = KSSCoreCommands(commands) - -Now we will look at the individual methods provided by the core commands. - - >>> core.replaceInnerHTML(CSS('div'), 'some <h1>html</h1>') - >>> commands.render() - '...replaceInnerHTML...some &lt;h1&gt;html&lt;/h1&gt;...' - Using command sets ================== @@ -140,6 +122,7 @@ We will now demonstrate this in the next example. First we need to load the registry. + >>> from kss.base.corecommands import KSSCoreCommands >>> from kss.base.registry import command_set_registry Now we can register our command set. For more information about the registry look at the documentation of kss.pluginregistry. Modified: kukit/kss.base/trunk/kss/base/commands.py ============================================================================== --- kukit/kss.base/trunk/kss/base/commands.py (original) +++ kukit/kss.base/trunk/kss/base/commands.py Wed Oct 10 11:40:07 2007 @@ -55,6 +55,9 @@ def lookup(self, name): return command_set_registry.get(name)(self) + def clear(self): + self.commands = [] + def __str__(self): def format_options(options): if not options: Modified: kukit/kss.base/trunk/kss/base/commandset.py ============================================================================== --- kukit/kss.base/trunk/kss/base/commandset.py (original) +++ kukit/kss.base/trunk/kss/base/commandset.py Wed Oct 10 11:40:07 2007 @@ -1,21 +0,0 @@ -class CommandSetRegistry(object): - def __init__(self): - self._sets = {} - - def register(self, name, factory): - if name in self._sets: - raise KeyError('Duplicate registration for name: %s' % name) - self._sets[name] = factory - - def unregister(self, name): - del self._sets[name] - - def get(self, name): - return self._sets[name] - - def items(self): - return self._sets.iteritems() - - -class PluginRegistry(CommandSetRegistry): - pass Added: kukit/kss.base/trunk/kss/base/config.py ============================================================================== --- (empty file) +++ kukit/kss.base/trunk/kss/base/config.py Wed Oct 10 11:40:07 2007 @@ -0,0 +1,48 @@ +import os + +from kss.base.plugin import Plugin, javascripts_from +from kss.base.corecommands import KSSCoreCommands +from kss.base.coreselectors import CSS, HTMLId, SameNode, ParentNode + +kukit_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'kukit') + +core_js = ['utils.js', + 'errors.js', + 'oper.js', + 'kukit.js', + 'tokenizer.js', + 'providerreg.js', + 'resourcedata.js', + 'kssparser.js', + 'eventreg.js', + 'actionreg.js', + 'dom.js', + 'commandreg.js', + 'serveraction.js', + 'requestmanager.js', + 'commandprocessor.js', + 'selectorreg.js', + 'forms.js', + 'plugin.js', + ] + + +class KSSCore(Plugin): + '''The KSS core plugin has all the standard functionality''' + + priority = -1000 + + javascripts = [os.path.join(kukit_dir, 'kukit', js) for js in core_js] + + extra_javascripts = javascripts_from(os.path.join(kukit_dir, '3rd_party')) + + commandsets = { + 'core': KSSCoreCommands, + } + + selectors = [CSS, HTMLId, SameNode, ParentNode] + + # OPTIONAL! + events={} + actions=[] + value_providers = [] Modified: kukit/kss.base/trunk/kss/base/corecommands.py ============================================================================== --- kukit/kss.base/trunk/kss/base/corecommands.py (original) +++ kukit/kss.base/trunk/kss/base/corecommands.py Wed Oct 10 11:40:07 2007 @@ -8,10 +8,92 @@ def replaceHTML(self, selector, value): self.commands.add('replaceHTML', selector, html=value) - def insert_html_after(self, selector, value): + + def setAttribute(self, selector, name, value): + self.commands.add('setAttribute', selector, name=name, value=value) + + def setStyle(self, selector, name, value): + if ' ' in name: + raise ValueError('Style properites cannot contain spaces') + self.commands.add('setStyle', selector, name=name, value=value) + + + def insertHTMLAfter(self, selector, value): self.commands.add('insertHTMLAfter', selector, html=value) - def insert_html_as_first_child(self, selector, value): + def insertHTMLAsFirstChild(self, selector, value): self.commands.add('insertHTMLAsFirstChild', selector, html=value) - - + + def insertHTMLAsLastChild(self, selector, value): + self.commands.add('insertHTMLAsLastChild', selector, html=value) + + def insertHTMLBefore(self, selector, value): + self.commands.add('insertHTMLBefore', selector, html=value) + + + + def clearChildNodes(self, selector): + self.commands.add('clearChildNodes', selector) + + def deleteNode(self, selector): + self.commands.add('deleteNode', selector) + + def deleteNodeAfter(self, selector): + self.commands.add('deleteNodeAfter', selector) + + def deleteNodeBefore(self, selector): + self.commands.add('deleteNodeBefore', selector) + + + + def copyChildNodesFrom(self, selector, id): + self.commands.add('copyChildNodesFrom', selector, html_id=id) + + def moveNodeAfter(self, selector, id): + self.commands.add('moveNodeAfter', selector, html_id=id) + + def moveNodeBefore(self, selector, id): + self.commands.add('moveNodeBefore', selector, html_id=id) + + def copyChildNodesTo(self, selector, id): + self.commands.add('copyChildNodesTo', selector, html_id=id) + + + + def setStateVar(self, varname, value): + selector = None + self.commands.add('setStateVar', selector, varname=varname, value=value) + + def triggerEvent(self, name, **kw): + self.commands.add('triggerEvent', name=name, **kwargs) + + def toggleClass(self, selector, *arg, **kw): + ##def toggleClass(self, selector, value): + """ see interfaces.py """ + # BBB 4 months, until 2007-10-18 + value = BBB_classParms('toggleClass', *arg, **kw) + + command = self.commands.addCommand('toggleClass', selector) + data = command.addParam('value', value) + + def addClass(self, selector, *arg, **kw): + ##def addClass(self, selector, name): + """ see interfaces.py """ + # BBB 4 months, until 2007-10-18 + value = BBB_classParms('addClass', *arg, **kw) + + command = self.commands.addCommand('addClass', selector) + data = command.addParam('value', value) + + def removeClass(self, selector, *arg, **kw): + ##def removeClass(self, selector, name): + """ see interfaces.py """ + # BBB 4 months, until 2007-10-18 + value = BBB_classParms('removeClass', *arg, **kw) + + command = self.commands.addCommand('removeClass', selector) + data = command.addParam('value', value) + + def focus(self, selector): + """ see interfaces.py """ + command = self.commands.addCommand('focus', selector) Added: kukit/kss.base/trunk/kss/base/corecommands.txt ============================================================================== --- (empty file) +++ kukit/kss.base/trunk/kss/base/corecommands.txt Wed Oct 10 11:40:07 2007 @@ -0,0 +1,40 @@ +============= +Core commands +============= + +The core commands wrap all standard KSS actions that are always available. +These do not contain any effects and focus mostly on DOM manipulation. + +First we will need to create our command set. + + >>> from kss.base.corecommands import KSSCoreCommands + >>> from kss.base import KSSCommands + >>> from kss.base.coreselectors import CSS + + >>> commands = KSSCommands() + >>> core = KSSCoreCommands(commands) + +Now we will look at the individual methods provided by the core commands. + + >>> core.replaceInnerHTML(CSS('div'), 'some <h1>html</h1>') + >>> commands.render() + '...replaceInnerHTML...some &lt;h1&gt;html&lt;/h1&gt;...' + + +Set attribute +------------- + + >>> commands.clear() + >>> core.setAttribute(CSS('div'), 'some name', 'some value') + >>> print commands + setAttribute(css('div'), name='some name', value='some value') + +Set style +--------- + + >>> commands.clear() + >>> core.setStyle(CSS('div'), 'somename', 'some value') + >>> print commands + setStyle(css('div'), name='somename', value='some value') + + Modified: kukit/kss.base/trunk/kss/base/plugin.py ============================================================================== --- kukit/kss.base/trunk/kss/base/plugin.py (original) +++ kukit/kss.base/trunk/kss/base/plugin.py Wed Oct 10 11:40:07 2007 @@ -45,51 +45,3 @@ def activated_plugins(): return plugin_registry.items() - - -# !TODO: Move to a seperate file -from kss.base.corecommands import KSSCoreCommands -from kss.base.coreselectors import CSS, HTMLId, SameNode, ParentNode - -kukit_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'kukit') - -core_js = ['utils.js', - 'errors.js', - 'oper.js', - 'kukit.js', - 'tokenizer.js', - 'providerreg.js', - 'resourcedata.js', - 'kssparser.js', - 'eventreg.js', - 'actionreg.js', - 'dom.js', - 'commandreg.js', - 'serveraction.js', - 'requestmanager.js', - 'commandprocessor.js', - 'selectorreg.js', - 'forms.js', - 'plugin.js', - ] - - -class KSSCore(Plugin): - '''The KSS core plugin has all the standard functionality''' - - priority = -1000 - - javascripts = [os.path.join(kukit_dir, 'kukit', js) for js in core_js] - - extra_javascripts = javascripts_from(os.path.join(kukit_dir, '3rd_party')) - - commandsets = { - 'core': KSSCoreCommands, - } - - selectors = [CSS, HTMLId, SameNode, ParentNode] - - # OPTIONAL! - events={} - actions=[] - value_providers = [] Deleted: /kukit/kss.base/trunk/kss/base/pluginregistry.txt ============================================================================== --- /kukit/kss.base/trunk/kss/base/pluginregistry.txt Wed Oct 10 11:40:07 2007 +++ (empty file) @@ -1,67 +0,0 @@ -=================== -KSS Plugin Registry -=================== - -The plugin registry is used so that extra plugins are easy to use. All -registries can be easily queried and modified using the provided api. - -Command Set Registry -==================== - -One of the main features of KSS are the command sets. These wrap the transport -protocol for easier usage. To make sure all access to the commandsets are -convenient we provide a registry. - -Using the registry is pretty simple. - - >>> from kss.base.registry import command_set_registry - -First we will create a simple factory for our command set. Note that any -callable object will do. For more information on command sets look at the -documentation in kss.commands. - - >>> def test_command_set_factory(commands): - ... pass - -We can register a command set by passing in the factory and a name. - - >>> command_set_registry.register('test', test_command_set_factory) - -The name is used as a unique identifier to lookup the command set factory. -When you try to register a factory under the same name you will get an error. - - >>> command_set_registry.register('test', test_command_set_factory) - Traceback (most recent call last): - ... - KeyError: ... - -This avoids any accidental overrides. If you want to override a command you -can unregister it first. - - >>> command_set_registry.unregister('test') - -Unregistering the same thing twice will throw a KeyError. - - >>> command_set_registry.unregister('test') - Traceback (most recent call last): - ... - KeyError: ... - -This is because we cannot unregister what is not there. - -Now that the registry is clean we can safely register our command set again. - - >>> command_set_registry.register('test', test_command_set_factory) - -To use a command set we will need to get it from the registry. Let us load the -previously defined `test` set. - - >>> command_set_registry.get('test') is test_command_set_factory - True - -Trying to load a command set which is not defined will result in a key error. - - >>> command_set_registry.get('does-not-exist') - Traceback (most recent call last): - ... - KeyError: ... Modified: kukit/kss.base/trunk/kss/base/registry.py ============================================================================== --- kukit/kss.base/trunk/kss/base/registry.py (original) +++ kukit/kss.base/trunk/kss/base/registry.py Wed Oct 10 11:40:07 2007 @@ -1,4 +1,20 @@ -from kss.base.commandset import CommandSetRegistry +class Registry(object): + def __init__(self): + self._items = {} -command_set_registry = CommandSetRegistry() -plugin_registry = CommandSetRegistry() + def register(self, name, factory): + if name in self._items: + raise KeyError('Duplicate registration for name: %s' % name) + self._items[name] = factory + + def unregister(self, name): + del self._items[name] + + def get(self, name): + return self._items[name] + + def items(self): + return self._items.iteritems() + +command_set_registry = Registry() +plugin_registry = Registry() Added: kukit/kss.base/trunk/kss/base/registry.txt ============================================================================== --- (empty file) +++ kukit/kss.base/trunk/kss/base/registry.txt Wed Oct 10 11:40:07 2007 @@ -0,0 +1,72 @@ +============== +KSS Registries +============== + +KSS can be extendend in a few different ways. To make these things +work we have a few different registries. + +The registries are all instances of a simple base class. Using these +is pretty simple. + + >>> from kss.base.registry import Registry + +We will now demonstrate the working of this registry with an sample +command set. + + >>> command_set_registry = Registry() + +First we will create a simple factory function for our command +set. Note that any callable object will do. For more information on +command sets look at the documentation in kss.commands. + + >>> def test_command_set_factory(commands): + ... pass + +We can register a command set by passing in the factory and a name. + + >>> command_set_registry.register('test', test_command_set_factory) + +The name is used as a unique identifier to lookup the command set factory. +When you try to register a factory under the same name you will get an error. + + >>> command_set_registry.register('test', test_command_set_factory) + Traceback (most recent call last): + ... + KeyError: ... + +This avoids any accidental overrides. If you want to override a command you +can unregister it first. + + >>> command_set_registry.unregister('test') + +Unregistering the same thing twice will throw a KeyError. + + >>> command_set_registry.unregister('test') + Traceback (most recent call last): + ... + KeyError: ... + +This is because we cannot unregister what is not there. + +Now that the registry is clean we can safely register our command set again. + + >>> command_set_registry.register('test', test_command_set_factory) + +To use a command set we will need to get it from the registry. Let us load the +previously defined `test` set. + + >>> command_set_registry.get('test') is test_command_set_factory + True + +Trying to load a command set which is not defined will result in a key error. + + >>> command_set_registry.get('does-not-exist') + Traceback (most recent call last): + ... + KeyError: ... + +Registries can list theirs registered items. + + >>> list(command_set_registry.items()) + [('test', )] + Modified: kukit/kss.base/trunk/kss/base/tests.py ============================================================================== --- kukit/kss.base/trunk/kss/base/tests.py (original) +++ kukit/kss.base/trunk/kss/base/tests.py Wed Oct 10 11:40:07 2007 @@ -5,7 +5,7 @@ suite = unittest.TestSuite(( doctest.DocFileSuite( 'README.txt', 'selectors.txt', - 'pluginregistry.txt', + 'registry.txt', 'corecommands.txt', package='kss.base', optionflags=doctest.ELLIPSIS|doctest.REPORT_ONLY_FIRST_FAILURE, ), Modified: kukit/kss.base/trunk/setup.py ============================================================================== --- kukit/kss.base/trunk/setup.py (original) +++ kukit/kss.base/trunk/setup.py Wed Oct 10 11:40:07 2007 @@ -26,7 +26,7 @@ ], entry_points={ 'kss.plugin': [ - 'kss-core=kss.base.plugin:KSSCore' + 'kss-core=kss.base.config:KSSCore' ], 'console_scripts': [ 'kssconcatjs=kss.base.utils:KSSConcatJs' From jvloothuis at codespeak.net Thu Oct 11 10:22:32 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Thu, 11 Oct 2007 10:22:32 +0200 (CEST) Subject: [KSS-checkins] r47387 - kukit/kss.base/trunk/kss/base Message-ID: <20071011082232.C15538224@code0.codespeak.net> Author: jvloothuis Date: Thu Oct 11 10:22:31 2007 New Revision: 47387 Modified: kukit/kss.base/trunk/kss/base/corecommands.py kukit/kss.base/trunk/kss/base/corecommands.txt Log: Started with the implementation of the core command set Modified: kukit/kss.base/trunk/kss/base/corecommands.py ============================================================================== --- kukit/kss.base/trunk/kss/base/corecommands.py (original) +++ kukit/kss.base/trunk/kss/base/corecommands.py Thu Oct 11 10:22:31 2007 @@ -1,13 +1,6 @@ from kss.base.commands import KSSCommandSet class KSSCoreCommands(KSSCommandSet): - - def replaceInnerHTML(self, selector, value): - self.commands.add('replaceInnerHTML', selector, html=value) - - def replaceHTML(self, selector, value): - self.commands.add('replaceHTML', selector, html=value) - def setAttribute(self, selector, name, value): self.commands.add('setAttribute', selector, name=name, value=value) @@ -17,6 +10,30 @@ raise ValueError('Style properites cannot contain spaces') self.commands.add('setStyle', selector, name=name, value=value) + def addClass(self, selector, value): + self.commands.add('addClass', selector, value=value) + + def removeClass(self, selector, value): + self.commands.add('removeClass', selector, value=value) + + def toggleClass(self, selector, value): + self.commands.add('toggleClass', selector, value=value) + + def focus(self, selector): + self.commands.add('focus', selector) + + + + def replaceInnerHTML(self, selector, value): + """Replace the contents of a node (selector) with the new `value`""" + self.commands.add('replaceInnerHTML', selector, html=value) + + def replaceHTML(self, selector, value): + self.commands.add('replaceHTML', selector, html=value) + + + def insertHTMLBefore(self, selector, value): + self.commands.add('insertHTMLBefore', selector, html=value) def insertHTMLAfter(self, selector, value): self.commands.add('insertHTMLAfter', selector, html=value) @@ -27,73 +44,45 @@ def insertHTMLAsLastChild(self, selector, value): self.commands.add('insertHTMLAsLastChild', selector, html=value) - def insertHTMLBefore(self, selector, value): - self.commands.add('insertHTMLBefore', selector, html=value) - - def clearChildNodes(self, selector): - self.commands.add('clearChildNodes', selector) - def deleteNode(self, selector): self.commands.add('deleteNode', selector) - def deleteNodeAfter(self, selector): - self.commands.add('deleteNodeAfter', selector) - def deleteNodeBefore(self, selector): self.commands.add('deleteNodeBefore', selector) + def deleteNodeAfter(self, selector): + self.commands.add('deleteNodeAfter', selector) + def clearChildNodes(self, selector): + self.commands.add('clearChildNodes', selector) + + def copyChildNodesFrom(self, selector, id): self.commands.add('copyChildNodesFrom', selector, html_id=id) - def moveNodeAfter(self, selector, id): - self.commands.add('moveNodeAfter', selector, html_id=id) + def copyChildNodesTo(self, selector, id): + self.commands.add('copyChildNodesTo', selector, html_id=id) + + def moveNodeBefore(self, selector, id): self.commands.add('moveNodeBefore', selector, html_id=id) - def copyChildNodesTo(self, selector, id): - self.commands.add('copyChildNodesTo', selector, html_id=id) + def moveNodeAfter(self, selector, id): + self.commands.add('moveNodeAfter', selector, html_id=id) + # TODO: Selector less actions def setStateVar(self, varname, value): selector = None self.commands.add('setStateVar', selector, varname=varname, value=value) - def triggerEvent(self, name, **kw): + def triggerEvent(self, name, **kwargs): self.commands.add('triggerEvent', name=name, **kwargs) - def toggleClass(self, selector, *arg, **kw): - ##def toggleClass(self, selector, value): - """ see interfaces.py """ - # BBB 4 months, until 2007-10-18 - value = BBB_classParms('toggleClass', *arg, **kw) - - command = self.commands.addCommand('toggleClass', selector) - data = command.addParam('value', value) - - def addClass(self, selector, *arg, **kw): - ##def addClass(self, selector, name): - """ see interfaces.py """ - # BBB 4 months, until 2007-10-18 - value = BBB_classParms('addClass', *arg, **kw) - - command = self.commands.addCommand('addClass', selector) - data = command.addParam('value', value) - - def removeClass(self, selector, *arg, **kw): - ##def removeClass(self, selector, name): - """ see interfaces.py """ - # BBB 4 months, until 2007-10-18 - value = BBB_classParms('removeClass', *arg, **kw) - command = self.commands.addCommand('removeClass', selector) - data = command.addParam('value', value) - def focus(self, selector): - """ see interfaces.py """ - command = self.commands.addCommand('focus', selector) Modified: kukit/kss.base/trunk/kss/base/corecommands.txt ============================================================================== --- kukit/kss.base/trunk/kss/base/corecommands.txt (original) +++ kukit/kss.base/trunk/kss/base/corecommands.txt Thu Oct 11 10:22:31 2007 @@ -20,6 +20,9 @@ >>> commands.render() '...replaceInnerHTML...some &lt;h1&gt;html&lt;/h1&gt;...' +----------------- +Node modification +----------------- Set attribute ------------- @@ -37,4 +40,176 @@ >>> print commands setStyle(css('div'), name='somename', value='some value') +Add class +--------- + + >>> commands.clear() + >>> core.addClass(CSS('div'), 'somename') + >>> print commands + addClass(css('div'), value='somename') + + +Remove class +------------ + + >>> commands.clear() + >>> core.removeClass(CSS('div'), 'somename') + >>> print commands + removeClass(css('div'), value='somename') + +Toggle class +------------ + + >>> commands.clear() + >>> core.toggleClass(CSS('div'), 'somename') + >>> print commands + toggleClass(css('div'), value='somename') + + +Focus +----- + + >>> commands.clear() + >>> core.focus(CSS('div')) + >>> print commands + focus(css('div')) + +---------------- +HTML replacement +---------------- + +Replace inner HTML +------------------ + + >>> commands.clear() + >>> core.replaceInnerHTML(CSS('div'), 'some html') + >>> print commands + replaceInnerHTML(css('div'), html='some html') + +Replace HTML +------------ + + >>> commands.clear() + >>> core.replaceHTML(CSS('div'), 'some html') + >>> print commands + replaceHTML(css('div'), html='some html') + + +-------------- +HTML insertion +-------------- + +Insert HTML before +------------------ + + >>> commands.clear() + >>> core.insertHTMLBefore(CSS('div'), 'some html') + >>> print commands + insertHTMLBefore(css('div'), html='some html') + +Insert HTML after +----------------- + + >>> commands.clear() + >>> core.insertHTMLAfter(CSS('div'), 'some html') + >>> print commands + insertHTMLAfter(css('div'), html='some html') + +Insert HTML as first child +-------------------------- + + >>> commands.clear() + >>> core.insertHTMLAsFirstChild(CSS('div'), 'some html') + >>> print commands + insertHTMLAsFirstChild(css('div'), html='some html') + +Insert HTML as last child +-------------------------- + + >>> commands.clear() + >>> core.insertHTMLAsLastChild(CSS('div'), 'some html') + >>> print commands + insertHTMLAsLastChild(css('div'), html='some html') + + +------------ +Node removal +------------ + +Delete node +----------- + + >>> commands.clear() + >>> core.deleteNode(CSS('div')) + >>> print commands + deleteNode(css('div')) + +Delete node before +------------------ + + >>> commands.clear() + >>> core.deleteNodeBefore(CSS('div')) + >>> print commands + deleteNodeBefore(css('div')) + +Delete node after +----------------- + + >>> commands.clear() + >>> core.deleteNodeAfter(CSS('div')) + >>> print commands + deleteNodeAfter(css('div')) + +Clear child nodes +----------------- + + >>> commands.clear() + >>> core.focus(CSS('div')) + >>> print commands + focus(css('div')) + + +------------- +Copying nodes +------------- + +Copy child nodes from +---------------------- + + >>> commands.clear() + >>> core.copyChildNodesFrom(CSS('div'), 'nodeid') + >>> print commands + copyChildNodesFrom(css('div'), html_id='nodeid') + + +Copy child nodes to +------------------- + + >>> commands.clear() + >>> core.copyChildNodesTo(CSS('div'), 'nodeid') + >>> print commands + copyChildNodesTo(css('div'), html_id='nodeid') + + +------------ +Moving nodes +------------ + +Move node before +---------------- + + >>> commands.clear() + >>> core.moveNodeBefore(CSS('div'), 'nodeid') + >>> print commands + moveNodeBefore(css('div'), html_id='nodeid') + +Move node after +--------------- + + >>> commands.clear() + >>> core.moveNodeAfter(CSS('div'), 'nodeid') + >>> print commands + moveNodeAfter(css('div'), html_id='nodeid') + + From jvloothuis at codespeak.net Thu Oct 11 15:38:44 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Thu, 11 Oct 2007 15:38:44 +0200 (CEST) Subject: [KSS-checkins] r47396 - kukit/kss.base/trunk/kss/base Message-ID: <20071011133844.6740E820A@code0.codespeak.net> Author: jvloothuis Date: Thu Oct 11 15:38:42 2007 New Revision: 47396 Added: kukit/kss.base/trunk/kss/base/commands.txt (props changed) - copied unchanged from r47376, kukit/kss.base/trunk/kss/base/README.txt Removed: kukit/kss.base/trunk/kss/base/README.txt Log: Made a better introduction readme (moved the old one as documentation for the command sets) Deleted: /kukit/kss.base/trunk/kss/base/README.txt ============================================================================== --- /kukit/kss.base/trunk/kss/base/README.txt Thu Oct 11 15:38:42 2007 +++ (empty file) @@ -1,143 +0,0 @@ -KSS Commands -============ - -The KSS commands system allows you to create a properly formatted KSS -response. - -Command renderer -================ - -The command renderer is the core of the system. This object is responsible -for create the KSS response. We will now take a look at an example to see it -in action. - - >>> from kss.base import KSSCommands - -The constructor takes no arguments. - - >>> commands = KSSCommands() - -We can add commands to the renderer using the `add` method. To do this we -also need to create a selector. In this case we will use the CSS selector. -For more information about selectors look at the selector documentation. - - >>> from kss.base.coreselectors import CSS - >>> commands.add('replaceHTML', CSS('#someid'), html='some value') - -Now we have added a command. The first argument is the name of the action -which will be invoked on the client. Our second argument is the selector. -Any given keyword arguments become arguments to the client side action. - -You can add any number of commands this way. Each command will be executed -in the order that it is added. - - >>> commands.add('someOtherAction', CSS('#otherid'), arg='some arg') - -Note that all data passed will be validated. Passing in invalid data will -raise a ValueError. - - >>> commands.add('brokenAction', CSS('#id'), arg='

invalid') - Traceback (most recent call last): - ... - ValueError: Argument with name: arg is not valid xml:

invalid - -The validation method can also be called directly. It will only raise and -exeption on data which has tags that are not closed properly. Data does not -need be valid XML (text nodes may procede any tags). - - >>> commands.validate_parameters(dict(html='valid data')) - >>> commands.validate_parameters(dict(html='valid data')) - >>> commands.validate_parameters(dict(html='invalid ')) - Traceback (most recent call last): - ... - ValueError: Argument with name: html is not valid xml: invalid - -Now that we have a few commands we can render them. - - >>> commands.render() - '...some value...some arg...' - -It is also possible to get a string representation of the -commandset. This can be used in doctests like this. - - >>> commands = KSSCommands() - -By default it does nothing. - - >>> print commands - - -It becomes more interesting if we add a command. - - >>> commands.add('replaceHTML', CSS('#someid')) - >>> print commands - replaceHTML(css('#someid')) - -If you add parameters they are also shown in the string -representation. Parameters are sorted before display to make them -stable for testing. - - >>> commands = KSSCommands() - >>> commands.add('replaceHTML', CSS('#someid'), b_arg='some data', a_arg='cheese') - >>> print commands - replaceHTML(css('#someid'), a_arg='cheese', b_arg='some data') - -Multiple commands are put on seperate lines. - - >>> commands.add('otherCommand', CSS('#something')) - >>> print commands - replaceHTML(css('#someid'), a_arg='cheese', b_arg='some data') - otherCommand(css('#something')) - - -Command sets -============ - -A command set wraps the commands system so that you get a highlevel way to -communicate with the browser. Command sets are responsible for escaping and -validating data and can provider a nicer api for calling. - -We will now take a look at the base class for all commandsets. - - >>> from kss.base.commands import KSSCommandSet - >>> commands = KSSCommands() - >>> commandset = KSSCommandSet(commands) - -All this does is wrap our commands in the command set. We can still access the -commands directly by using the `commands` attribute. - - >>> commandset.commands - <...KSSCommands object at ...> - -The thing that makes this interesting is the actual command sets. Take a look -at the core commands for a better understanding of the usage pattern. - -Using command sets -================== - -In the previous examples we saw how to load command sets directly. Normally we -do not need to do this. This is because the command renderer can also look -them up by name. This is done by using the KSS plugin registry. - -We will now demonstrate this in the next example. First we need to load the -registry. - - >>> from kss.base.corecommands import KSSCoreCommands - >>> from kss.base.registry import command_set_registry - -Now we can register our command set. For more information about the registry look at the documentation of kss.pluginregistry. - - >>> command_set_registry.register('core', KSSCoreCommands) - -To access a command set just need to create our command renderer like we do -normally. - - >>> commands = KSSCommands() - -We can now access the command set. - - >>> core = commands.lookup('core') - -This command set is initialized and ready for usage. - - >>> core.replaceInnerHTML(CSS('div'), 'example') From jvloothuis at codespeak.net Thu Oct 11 20:44:12 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Thu, 11 Oct 2007 20:44:12 +0200 (CEST) Subject: [KSS-checkins] r47397 - in kukit/KssTheme/trunk/skins: ksstheme_styles ksstheme_templates Message-ID: <20071011184412.C46DE8234@code0.codespeak.net> Author: jvloothuis Date: Thu Oct 11 20:44:10 2007 New Revision: 47397 Modified: kukit/KssTheme/trunk/skins/ksstheme_styles/base.css.dtml kukit/KssTheme/trunk/skins/ksstheme_styles/public.css.dtml kukit/KssTheme/trunk/skins/ksstheme_templates/main_template.pt Log: Applied changes from Jarno which fix a few style issues Modified: kukit/KssTheme/trunk/skins/ksstheme_styles/base.css.dtml ============================================================================== --- kukit/KssTheme/trunk/skins/ksstheme_styles/base.css.dtml (original) +++ kukit/KssTheme/trunk/skins/ksstheme_styles/base.css.dtml Thu Oct 11 20:44:10 2007 @@ -204,11 +204,11 @@ .discreet{ font-size: 80%; padding: 0px; - margin:0px; - color:#FF4916; + margin: 0px; + color: #666; text-decoration: none; } -/**samenvattings weergave view*/ +/**summary view*/ .tileItem { border-bottom: #FF4916 1px solid; } @@ -293,6 +293,38 @@ border-right: 1px solid #A8A890; padding: 0.25em 1em; } + +blockquote { + padding-left: 0.5em; + margin-left: 0; + border-left: 4px solid #76797c; + color: black; +} + +code { + font-family: Monaco,"Courier New",Courier,monospace; + font-size: 120%; + color: Black; + background-color: #dee7ec; + padding: 0 0.1em; +} + +pre { + font-family: Monaco,"Courier New",Courier,monospace; + font-size: 100%; + padding: 1em; + border: 1px solid #FF4916; + color: Black; + background-color: #F0F0D8; + overflow: auto; +} + +.callout { + font-weight: bold; + color: #FF4916; + padding: 0px 1em; +} + /* YOUR CSS RULES STOP HERE */ /* */ Modified: kukit/KssTheme/trunk/skins/ksstheme_styles/public.css.dtml ============================================================================== --- kukit/KssTheme/trunk/skins/ksstheme_styles/public.css.dtml (original) +++ kukit/KssTheme/trunk/skins/ksstheme_styles/public.css.dtml Thu Oct 11 20:44:10 2007 @@ -7,7 +7,12 @@ /* YOUR CSS RULES START HERE */ - +.field{top:0;left:0;margin:0 1em 1em 0;} +.field .field{margin:1em 0 0 0;} +.formHelp{font-size:90%;color:#76797c;margin:0 0 0.2em 0;} +.formHelp:hover{color:Black;cursor:default;} +.error{background-color:#ffce7b;border:1px solid #FF4916;padding:1em;margin:0 0 1em 0;width:95%;} +.error .fieldRequired{color:#ffce7b;} /* YOUR CSS RULES STOP HERE */ Modified: kukit/KssTheme/trunk/skins/ksstheme_templates/main_template.pt ============================================================================== --- kukit/KssTheme/trunk/skins/ksstheme_templates/main_template.pt (original) +++ kukit/KssTheme/trunk/skins/ksstheme_templates/main_template.pt Thu Oct 11 20:44:10 2007 @@ -104,7 +104,6 @@ Start of the left column
@@ -112,6 +111,7 @@ This instruction gets the portlets (boxes) for the left column. +  
From jvloothuis at codespeak.net Thu Oct 11 20:47:13 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Thu, 11 Oct 2007 20:47:13 +0200 (CEST) Subject: [KSS-checkins] r47398 - kukit/kss.base/trunk/kss/base Message-ID: <20071011184713.755C48224@code0.codespeak.net> Author: jvloothuis Date: Thu Oct 11 20:47:13 2007 New Revision: 47398 Added: kukit/kss.base/trunk/kss/base/README.txt Modified: kukit/kss.base/trunk/kss/base/commands.txt Log: Improved the readme Added: kukit/kss.base/trunk/kss/base/README.txt ============================================================================== --- (empty file) +++ kukit/kss.base/trunk/kss/base/README.txt Thu Oct 11 20:47:13 2007 @@ -0,0 +1,13 @@ +============== +The KSS system +============== + +KSS enables you write rich Ajax applications without having to code +Javascript. It does this by using a CSS like resource, this is called +a KSS file. All that you as a developer need to do is write files like +these and implement server side Python. + +This Python package contains the Javascript engine and the server side +infrastructure. The package forms the base for ingegration with +specific web development frameworks. To see if there is support for +your framework go to the KSS website. \ No newline at end of file Modified: kukit/kss.base/trunk/kss/base/commands.txt ============================================================================== --- kukit/kss.base/trunk/kss/base/commands.txt (original) +++ kukit/kss.base/trunk/kss/base/commands.txt Thu Oct 11 20:47:13 2007 @@ -88,7 +88,16 @@ >>> print commands replaceHTML(css('#someid'), a_arg='cheese', b_arg='some data') otherCommand(css('#something')) - + +If we add a parameter with a `None` value it will not be put into the +response. + + >>> commands.clear() + >>> commands.add('parameterCommand', CSS('#something'), + ... value='Testing', other_value=None) + >>> print commands + parameterCommand(css('#something'), value='Testing') + Command sets ============ @@ -112,6 +121,7 @@ The thing that makes this interesting is the actual command sets. Take a look at the core commands for a better understanding of the usage pattern. + Using command sets ================== From jvloothuis at codespeak.net Thu Oct 11 20:49:03 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Thu, 11 Oct 2007 20:49:03 +0200 (CEST) Subject: [KSS-checkins] r47399 - in kukit/kss.base/trunk: . kss/base Message-ID: <20071011184903.5B9E38224@code0.codespeak.net> Author: jvloothuis Date: Thu Oct 11 20:49:03 2007 New Revision: 47399 Added: kukit/kss.base/trunk/kss/base/plugin.txt Modified: kukit/kss.base/trunk/kss/base/plugin.py kukit/kss.base/trunk/kss/base/tests.py kukit/kss.base/trunk/setup.py Log: Added more tests for the plugin system Changed identifiers used in setup.py Modified: kukit/kss.base/trunk/kss/base/plugin.py ============================================================================== --- kukit/kss.base/trunk/kss/base/plugin.py (original) +++ kukit/kss.base/trunk/kss/base/plugin.py Thu Oct 11 20:49:03 2007 @@ -8,6 +8,11 @@ class Plugin(object): priority = 100 + javascripts = () + extra_javascripts = () + selectors = () + commandsets = {} + def register_commandsets(self, registry): for name, commandset in self.commandsets.iteritems(): registry.register(name, commandset) @@ -30,6 +35,12 @@ return javascripts_from(os.path.dirname(os.path.abspath(path))) return javascripts +def module_path(mod): + return os.path.join(os.path.dirname(os.path.abspath(mod.__file__))) + +def file_below_module(mod, subpath): + return os.path.join(module_path(mod), *subpath.split('/')) + def load_plugins(*names): for name in names: for entry_point in iter_entry_points('kss.plugin', name): Added: kukit/kss.base/trunk/kss/base/plugin.txt ============================================================================== --- (empty file) +++ kukit/kss.base/trunk/kss/base/plugin.txt Thu Oct 11 20:49:03 2007 @@ -0,0 +1,79 @@ +======= +Plugins +======= + +KSS is a framework which is meant to be extended. An extension is a +simple Python package with some setuptools glue. + +Before any plugin can be used it must be activated. There is a +function for this which will be shown later. We will now just query +all activated plugins and show that it is empty. + + >>> from kss.base.plugin import activated_plugins + >>> tuple(activated_plugins()) + () + +We will now create a sample registration. A registration consists of a +class like you can see below. + +The first thing we need to do is import the `Plugin` base class. This +contains a few methods used in registration. + + >>> from kss.base.plugin import Plugin, file_below_module + +Now we can create our class. We will reuse the core commands in this +example. + + >>> import kss.base + >>> from kss.base.corecommands import KSSCoreCommands + >>> from kss.base.coreselectors import CSS + + >>> class ExamplePlugin(Plugin): + ... javascripts = [file_below_module(kss.base, + ... 'javascript/plugin.js')] + ... extra_javascripts = [] + ... commandsets = { + ... 'example': KSSCoreCommands, + ... } + ... selectors = [CSS] + +As you can see from the lines above the registration has a few things +in it. The first thing is registering the Javascripts. All items in +the list to the `javascripts` variable should be full paths to your +plugins Javascript. This should not list any third party Javascript +files. For this you can use `extra_javascripts`. + +The `commandset` var is a dictionary containing the mapping with +identifiers and the command set factory. When using KSS you would +normally use this identifier for the lookup of command sets. + +We can also register additional selectors. + +Now that we have our registration it is time to hook it up with the +setuptools registry. + + >>> import pkg_resources + + >>> class FakeEntryPoint(pkg_resources.EntryPoint): + ... def load(self): + ... return ExamplePlugin + + >>> distribution = pkg_resources.Distribution(location='.') + + >>> entry_point = FakeEntryPoint('testing', 'modname', + ... attrs=('somemethod',), + ... dist=distribution) + + >>> distribution._ep_map = {'kss.plugin': {'kss-testing': entry_point}} + + >>> pkg_resources.working_set.add(distribution) + +After this we can load our newly created plugin. + + >>> kss.base.load_plugins('kss-testing') + +Now that we have activated our plugin it should show up as activated. + + >>> tuple(activated_plugins()) + (('kss-testing', ),) + Modified: kukit/kss.base/trunk/kss/base/tests.py ============================================================================== --- kukit/kss.base/trunk/kss/base/tests.py (original) +++ kukit/kss.base/trunk/kss/base/tests.py Thu Oct 11 20:49:03 2007 @@ -5,7 +5,8 @@ suite = unittest.TestSuite(( doctest.DocFileSuite( 'README.txt', 'selectors.txt', - 'registry.txt', 'corecommands.txt', + 'registry.txt', 'plugin.txt', + 'commands.txt', 'corecommands.txt', package='kss.base', optionflags=doctest.ELLIPSIS|doctest.REPORT_ONLY_FIRST_FAILURE, ), Modified: kukit/kss.base/trunk/setup.py ============================================================================== --- kukit/kss.base/trunk/setup.py (original) +++ kukit/kss.base/trunk/setup.py Thu Oct 11 20:49:03 2007 @@ -9,7 +9,13 @@ """, # Get more strings from http://www.python.org/pypi?%3Aaction=list_classifiers classifiers=[ + "Development Status :: 3 - Alpha", + "Framework :: Paste", + "Intended Audience :: Developers", + "License :: OSI Approved :: GNU General Public License (GPL)", + "Operating System :: OS Independent", "Programming Language :: Python", + "Programming Language :: JavaScript", "Topic :: Software Development :: Libraries :: Python Modules", ], keywords='', From jvloothuis at codespeak.net Thu Oct 11 20:53:11 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Thu, 11 Oct 2007 20:53:11 +0200 (CEST) Subject: [KSS-checkins] r47400 - kukit/KssTheme/trunk/skins/ksstheme_templates Message-ID: <20071011185311.615EE8241@code0.codespeak.net> Author: jvloothuis Date: Thu Oct 11 20:53:11 2007 New Revision: 47400 Removed: kukit/KssTheme/trunk/skins/ksstheme_templates/fetchRecentNews.py kukit/KssTheme/trunk/skins/ksstheme_templates/portlet_login.pt kukit/KssTheme/trunk/skins/ksstheme_templates/portlet_news.pt Log: Remove unneeded portlets Deleted: /kukit/KssTheme/trunk/skins/ksstheme_templates/fetchRecentNews.py ============================================================================== --- /kukit/KssTheme/trunk/skins/ksstheme_templates/fetchRecentNews.py Thu Oct 11 20:53:11 2007 +++ (empty file) @@ -1 +0,0 @@ -return context.portal_catalog(portal_type='News Item', review_state='published' ,sort_on='modified', sort_order='reverse', sort_limit=2) Deleted: /kukit/KssTheme/trunk/skins/ksstheme_templates/portlet_login.pt ============================================================================== --- /kukit/KssTheme/trunk/skins/ksstheme_templates/portlet_login.pt Thu Oct 11 20:53:11 2007 +++ (empty file) @@ -1,16 +0,0 @@ - - -
- -
- - \ No newline at end of file Deleted: /kukit/KssTheme/trunk/skins/ksstheme_templates/portlet_news.pt ============================================================================== --- /kukit/KssTheme/trunk/skins/ksstheme_templates/portlet_news.pt Thu Oct 11 20:53:11 2007 +++ (empty file) @@ -1,18 +0,0 @@ - - -
-
-
-
-
- - -
-
-
- - \ No newline at end of file From jvloothuis at codespeak.net Thu Oct 11 21:02:22 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Thu, 11 Oct 2007 21:02:22 +0200 (CEST) Subject: [KSS-checkins] r47401 - kukit/kukit.js/trunk/utils Message-ID: <20071011190222.8159E8241@code0.codespeak.net> Author: jvloothuis Date: Thu Oct 11 21:02:20 2007 New Revision: 47401 Modified: kukit/kukit.js/trunk/utils/kss-mode.el Log: Fix for certain selector/comment combinations Modified: kukit/kukit.js/trunk/utils/kss-mode.el ============================================================================== --- kukit/kukit.js/trunk/utils/kss-mode.el (original) +++ kukit/kukit.js/trunk/utils/kss-mode.el Thu Oct 11 21:02:20 2007 @@ -44,7 +44,7 @@ (defvar kss-font-lock-keywords `( ;; CSS selectors - ("^\\([#_[:alnum:]][^:]+\\):[[:alnum:]-]+[[:blank:]]*{" + ("^\\([#_[:alnum:]][^:\n]+\\):[[:alnum:]-]+[[:blank:]]*{" (1 font-lock-constant-face)) ;; Events From jvloothuis at codespeak.net Thu Oct 11 21:05:28 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Thu, 11 Oct 2007 21:05:28 +0200 (CEST) Subject: [KSS-checkins] r47402 - in kukit/KssTheme/trunk/skins: ksstheme_styles ksstheme_templates Message-ID: <20071011190528.55D658241@code0.codespeak.net> Author: jvloothuis Date: Thu Oct 11 21:05:25 2007 New Revision: 47402 Added: kukit/KssTheme/trunk/skins/ksstheme_templates/portlet_calendar.pt kukit/KssTheme/trunk/skins/ksstheme_templates/portlet_search.pt Modified: kukit/KssTheme/trunk/skins/ksstheme_styles/ie7.css.dtml kukit/KssTheme/trunk/skins/ksstheme_styles/portlets.css.dtml Log: Changes from Thijs which fix things with the portlets Modified: kukit/KssTheme/trunk/skins/ksstheme_styles/ie7.css.dtml ============================================================================== --- kukit/KssTheme/trunk/skins/ksstheme_styles/ie7.css.dtml (original) +++ kukit/KssTheme/trunk/skins/ksstheme_styles/ie7.css.dtml Thu Oct 11 21:05:25 2007 @@ -1,8 +1,11 @@ -.portlets { +/* .portlets { border-top: #FF4916 1px solid ; border-bottom: #FF4916 1px solid; margin: 15px 6px 0px 8px; } .tileItem { margin-bottom: 10px; +} */ +#LSResult { + padding:10px } \ No newline at end of file Modified: kukit/KssTheme/trunk/skins/ksstheme_styles/portlets.css.dtml ============================================================================== --- kukit/KssTheme/trunk/skins/ksstheme_styles/portlets.css.dtml (original) +++ kukit/KssTheme/trunk/skins/ksstheme_styles/portlets.css.dtml Thu Oct 11 21:05:25 2007 @@ -8,7 +8,6 @@ /* YOUR CSS RULES START HERE */ /** navigation**/ #portal-column-one .visualPadding{ - margin-top: 40px; margin-left: 4px; } @@ -34,7 +33,7 @@ background: url(&dtml-portal_url;/menu-ov.gif) left top no-repeat; } .CustomPortletNavigation li ul { - background: #FAFAED; + background: #FAFAED; width: 200px; margin: 0 0 0 8px; padding: 8px 0px 3px 0px; @@ -54,40 +53,117 @@ .CustomPortletNavigation li ul li a:hover, .CustomPortletNavigation li ul li a.active { background: url(&dtml-portal_url;/submenu-ov.gif) left top no-repeat; } -/**portlet news*/ -.portlets { - border-top: #FF4916 1px solid ; - border-bottom: #FF4916 1px solid; - margin: 15px 8px 0px 8px; +/*portlet news*/ + +.portlet { + border-bottom: 1px solid #A8A890; + margin: 0px 8px 0px 8px; + padding:10px; + background-color: #F0F0D8; } -.portlets .news{ + +#portlet-news{ + border-top: #FF4916 1px solid ; border-bottom: #A8A890 1px solid; padding: 5px; background-color: #F0F0D8; + margin: 15px 8px 0px 8px; } -.portlets .news .portlettitle { +.portlet .portletHeader { margin-bottom: 8px; } -.portlets .news .portlettitle a, .portlets .news .morenews a{ + +.portlet .portletHeader a, .portlet .portletFooter a{ font-weight: bold; text-decoration: none; } -.portlets .news .morenews{ + +.portlet .news .morenews{ text-align: right; margin: 5px 0 5px 0; } -#search{ - padding: 5px; - background-color: #F0F0D8; +#portlet-calendar { + padding: 5px 10px; + border-bottom: 1px solid #A8A890; + } + + #portlet-calendar thead tr th { + text-align:center; + color: #FF4916; + } + + #portlet-calendar thead tr #calendar-previous { + text-align:left; + } + + #portlet-calendar thead tr #calendar-next { + text-align:right; + } + + #thePloneCalendar { + width:100%; + } + + +#search { + background:transparent; + padding-left:10px; } -.portlets .search-title{ + +.portlet .search-title{ font-weight: bold; - color: #FF4916; + color: #fff; margin: 5px 0 5px 0; } +.portlet .portletFooter { + padding-top:5px; + text-align:right; + border:0px; +} + +#portal-column-one .portlet dd { + margin-left:0px; +} + +#searchGadget { + padding:0.2em 0.4em; +} + +#LSResult { + background:#FAFAED; + border:1px solid #FF4916; + position:absolute; + left:22px; + top:240px; + z-index:3; +} + +#LSResult legend{ + display:none; +} + +#LSResult fieldset{ + border:0px; +} + +/* + padding:0px; +#portal-column-one .portlet, + background-color: #F0F0D8; + width:190px; +} + +#search #LSTable { + width:auto; + border:1px solid #f60; + margin:0; + padding:0; +} + */ + /* YOUR CSS RULES STOP HERE */ Added: kukit/KssTheme/trunk/skins/ksstheme_templates/portlet_calendar.pt ============================================================================== --- (empty file) +++ kukit/KssTheme/trunk/skins/ksstheme_templates/portlet_calendar.pt Thu Oct 11 21:05:25 2007 @@ -0,0 +1,61 @@ + + + + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + +
+ « + + + monthname + year + + + » +
Su
+ 31 + +
+ +
+
+ + + + Added: kukit/KssTheme/trunk/skins/ksstheme_templates/portlet_search.pt ============================================================================== --- (empty file) +++ kukit/KssTheme/trunk/skins/ksstheme_templates/portlet_search.pt Thu Oct 11 21:05:25 2007 @@ -0,0 +1,13 @@ + + + +
+ +
+ + \ No newline at end of file From jvloothuis at codespeak.net Thu Oct 11 21:31:29 2007 From: jvloothuis at codespeak.net (jvloothuis at codespeak.net) Date: Thu, 11 Oct 2007 21:31:29 +0200 (CEST) Subject: [KSS-checkins] r47403 - kukit/KssTheme/trunk/skins/ksstheme_templates Message-ID: <20071011193129.D4E0C821D@code0.codespeak.net> Author: jvloothuis Date: Thu Oct 11 21:31:28 2007 New Revision: 47403 Modified: kukit/KssTheme/trunk/skins/ksstheme_templates/portlet_calendar.pt kukit/KssTheme/trunk/skins/ksstheme_templates/portlet_search.pt Log: Fixes from Thijs (without exchange f*ckups) Modified: kukit/KssTheme/trunk/skins/ksstheme_templates/portlet_calendar.pt ============================================================================== --- kukit/KssTheme/trunk/skins/ksstheme_templates/portlet_calendar.pt (original) +++ kukit/KssTheme/trunk/skins/ksstheme_templates/portlet_calendar.pt Thu Oct 11 21:31:28 2007 @@ -1,61 +1,127 @@ - - - - - -
- - -
- - - - + + + + +
+ + +
+ +
+ + - + tal:attributes="href python:'%s/%s?%s&month:int=%d&year:int=%d&orig_query=%s' % (anchor_url, anchor_method, query_string, prevMonthTime.month(),prevMonthTime.year(),url_quote_plus(query_string))" + tal:condition="showPrevMonth" + i18n:attributes="title title_previous_month;">« + + - - - - - - - - - - - + + + + + + + + + + - - -
+ tal:attributes="id python: test(showPrevMonth, 'calendar-previous', '')"> « - - - monthname - year - - + + monthname + year + + + tal:attributes="id python: test(showNextMonth, 'calendar-next', '')"> » -
Su
- 31 + tal:attributes="href python:'%s/%s?%s&month:int=%d&year:int=%d&orig_query=%s' % (anchor_url, anchor_method, query_string, nextMonthTime.month(),nextMonthTime.year(),url_quote_plus(query_string))" + tal:condition="showNextMonth" + i18n:attributes="title title_next_month;">» + +
Su
+ 31 + >
- -
-
- - - - + > + + + + +
+ + + + + Modified: kukit/KssTheme/trunk/skins/ksstheme_templates/portlet_search.pt ============================================================================== --- kukit/KssTheme/trunk/skins/ksstheme_templates/portlet_search.pt (original) +++ kukit/KssTheme/trunk/skins/ksstheme_templates/portlet_search.pt Thu Oct 11 21:31:28 2007 @@ -1,10 +1,13 @@ - - + -
+