[KSS-checkins] r50936 - in kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes: doc kukit tests
reebalazs at codespeak.net
reebalazs at codespeak.net
Wed Jan 23 17:35:36 CET 2008
Author: reebalazs
Date: Wed Jan 23 17:35:34 2008
New Revision: 50936
Modified:
kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/doc/HISTORY.txt
kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/commandreg.js
kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/dom.js
kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/eventreg.js
kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/forms.js
kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/kssparser.js
kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/oper.js
kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/plugin.js
kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/providerreg.js
kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/requestmanager.js
kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/resourcedata.js
kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/selectorreg.js
kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/serveraction.js
kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/tokenizer.js
kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/tests/runtests.js
kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/tests/test_kssparser.js
kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/tests/test_requestmanager.js
kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/tests/test_utils.js
Log:
Rebase branch on gotcha's last merge
Modified: kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/doc/HISTORY.txt
==============================================================================
--- kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/doc/HISTORY.txt (original)
+++ kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/doc/HISTORY.txt Wed Jan 23 17:35:34 2008
@@ -6,6 +6,23 @@
- ...
+ - refactor the value provider registry to use
+ a single registry in place of 3.
+ This will enable to define value
+ providers that recieve non-string parameters
+ like a node selection.
+
+ Remove previously deprecated form() and
+ currentForm() value providers from normal
+ action parameters (remark: they should
+ be used with kssSelector.)
+ They now give a parsing error.
+
+ Implement multiproperties in
+ * action-client and action-server
+ * any value provider
+ [ree]
+
- Use functions in token table instead of code strings
that were evaluated. 'eval' is very slow.
[gotcha]
@@ -15,6 +32,11 @@
- Fix multiple selection form fields marshalling on Safari
(fixes #22 in kssproject) and on IE.
+
+ - Fix multiple selection form fields
+ marshalling on Safari
+ (fixes #22 in kssproject)
+ and on IE.
[ree]
- Fix error fallback handling
Modified: kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/commandreg.js
==============================================================================
--- kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/commandreg.js (original)
+++ kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/commandreg.js Wed Jan 23 17:35:34 2008
@@ -118,10 +118,30 @@
};
var _executeCommandOnSelector = function(oper) {
- var selfunc = kukit.selectorTypesGlobalRegistry.get(this.selectorType);
- // When applying the selection, the original event target will be used
+ // if the selector type is null or undefined or '',
+ // we use the default type.
+ var selectorType = this.selectorType ||
+ kukit.selectorTypesGlobalRegistry.defaultSelectorType;
+ // Use the provider registry to look up the selection provider.
+ var providerClass = kukit.pprovidersGlobalRegistry.get(selectorType);
+ // See if if is really a selection provider.
+ if (providerClass.prototype.returnType != 'selection') {
+ kukit.E = 'Undefined selector type [' + selectorType + '], ';
+ kukit.E = 'it exists as provider but it does not return a selection.';
+ throw new Error(kukit.E);
+ }
+ // Instantiate it
+ var provider = new providerClass();
+ var args = [this.selector];
+;;; // Check the provider first.
+;;; provider.check(args);
+ // When evaluating the provider, the original event target will be used
// as a starting point for the selection.
- var nodes = selfunc(this.selector, oper.orignode, {});
+ // args will contain a single item, since the server side currently
+ // cannot marshall selectors with more parameters
+ // defaultParameters will be empty when using from commands.
+ var nodes = provider.eval(args, oper.orignode, {});
+ //
;;;var printType;
;;;if (this.selectorType) {
;;; printType = this.selectorType;
Modified: kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/dom.js
==============================================================================
--- kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/dom.js (original)
+++ kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/dom.js Wed Jan 23 17:35:34 2008
@@ -227,27 +227,57 @@
var _kssAttrNamespace = 'kssattr';
+// the namespace prefix for kss values,
+// i.e.:
+// class="... kss-attr-key-value..."
+// id=="kss-id-key-value"
+// (XHTML:) kss-attr:key-value
+//
+var _kssNamespacePrefix = 'kss';
+
+var _getKssValueFromEncodings = function(encodings, prefix) {
+ // Value us a list of values.
+ // If a value equals prefix-value, it will find it
+ // and return the value after the prefix and the dash.
+ // (First value found will be returned.)
+ //
+ // For example:
+ //
+ // _getKssValueFromEncodings(['kss-attr-key1-value1', 'kss-attr-key2-value2',
+ // 'kss-id-key1-value1'], "kss-attr-key1')
+ //
+ // results 'value1'.
+ //
+ // Legacy example:
+ //
+ // _getKssValueFromEncodings(['kssattr-key1-value1', 'kssatt-rkey2-value2'],
+ // "kss-attr-key1')
+ //
+ // results 'value1'.
+ //
+ prefix = prefix + '-';
+ var prefixLength = prefix.length;
+ for (var i=0; i<encodings.length; i++) {
+ var encoding = encodings[i];
+ // Does the value start with the prefix?
+ if (encoding.substr(0, prefixLength) == prefix) {
+ // Found it.
+ return encoding.substr(prefixLength);
+ }
+ }
+ return null;
+};
+
+// BBB hint: used by getKssAttribute only, for providers
+// kssAttr and currentFormVarForKssAttr.
var _getKssClassAttribute = function(node, attrname) {
// Gets a given kss attribute from the class
var klass = dom.getAttribute(node, 'class');
- var result = null;
if (klass) {
var splitclass = klass.split(/ +/);
- for (var i=0; i<splitclass.length; i++) {
- var elem = splitclass[i];
- var splitelem = elem.split('-', 3);
- if (splitelem.length == 3 &&
- splitelem[0] == _kssAttrNamespace
- && splitelem[1] == attrname) {
- // Found it. (The last one will be valid,
- // in case of duplication)
- var index = splitelem[0].length + splitelem[1].length + 2;
- result = elem.substr(index);
- }
-
- }
+ return _getKssValueFromEncodings(splitclass, 'kssattr-' + attrname);
}
- return result;
+ return null;
};
dom.getKssAttribute = function(node, attrname) {
@@ -271,15 +301,68 @@
dom.setAttribute(node, fullName);
};
+/*
+ * Handling of kss values
+ */
+
+dom.getKssValue = function(node, keyType, key) {
+ // Gets a given kss value
+ // first try from the namespace (XHTML), then from the class and id
+ var namespacedName = _kssNamespacePrefix + '-' + keyType;
+ // We access node.getAttribute directly, because we don't need the
+ // other checks in dom.getAttribute
+ var attrName = namespacedName + ':' + key;
+ var result = node.getAttribute(attrName);
+ // XXX if this was '' it is the same as notfound,
+ // so it shadows the class attribute!
+ // This means setting an attribute to '' is the same as deleting it -
+ // at least at the moment
+ if (! result) {
+ // Make sure result is null, in case we can't produce one
+ // below.
+ result = null;
+ // Now try to get it from the class and id encodings.
+ // Having it in the id gives the advantage that we can use
+ // kss-id-key-value both as a unique html id, and widget markup.
+ var klass = dom.getAttribute(node, 'class');
+ var encodings;
+ if (klass) {
+ encodings = klass.split(/ +/);
+ } else {
+ encodings = [];
+ }
+ var id = dom.getAttribute(node, 'id');
+ if (id) {
+ // We have an id, consider it too
+ // id will be inserted 1st, ie. it overrides possible doubles in classes
+ encodings.unshift(id);
+ }
+ // Get the result-
+ var prefix = namespacedName + '-' + key;
+ return _getKssValueFromEncodings(encodings, prefix);
+ }
+ return result;
+};
+
+dom.setKssValue = function(node, keyType, key, value) {
+ // Sets a given kss attribute on the namespace
+ var namespacedName = _kssNamespacePrefix + '-' + keyType;
+ // We access node.setAttribute directly, because we don't need the
+ // other checks in dom.setAttribute
+ var attrName = namespacedName + ':' + key;
+ node.setAttribute(attrName, value);
+};
+
+
/* Recursive query of node attributes
getter is a function that gets the value from the node.
*/
-dom.getRecursiveAttribute =
- function(node, attrname, recurseParents, getter) {
- var value = getter(node, attrname);
+dom.locateMarkup =
+ function(node, recurseParents, getter, p1, p2, p3, p4, p5) {
+ var value = getter(node, p1, p2, p3, p4, p5);
+ var element = node;
if (recurseParents) {
- var element = node;
// need to recurse even if value="" !
// We cannot figure out if there exists
// and attribute in a crossbrowser way, or it is set to "".
@@ -288,16 +371,24 @@
if (! element || ! element.getAttribute) {
break;
}
- value = getter(element, attrname);
+ value = getter(element, p1, p2, p3, p4, p5);
}
}
if (typeof(value) == 'undefined') {
// notfound arguments will get null
value = null;
}
- return value;
+ // We return both the value and the node where
+ // it was found.
+ return {value:value, node:element};
};
+dom.getRecursiveAttribute =
+ function(node, attrname, recurseParents, getter) {
+ return dom.locateMarkup(node,
+ recurseParents, getter, attrname).value;
+}
+
/*
* From http://xkr.us/articles/dom/iframe-document/
* Note it's not necessary for the iframe to have the name
Modified: kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/eventreg.js
==============================================================================
--- kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/eventreg.js (original)
+++ kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/eventreg.js Wed Jan 23 17:35:34 2008
@@ -631,6 +631,38 @@
this.initialize = function(binder) {
this.binder = binder;
this.bound = new _OperRegistry();
+
+ this.getBinder = function () {
+ return this.binder;
+ };
+
+ this.startBindingPhase = function () {
+ // The binding phase starts and it has the information for
+ // the currently on-bound events.
+ this.binding = new _OperRegistry();
+ };
+
+ this.bindOper = function (oper) {
+ // We mark a given oper. This means a binding on the binder
+ // for given event, node and eventRule (containing event namespace,
+ // name, and evt- parms.)
+ //
+ // first see if it can go to already bound ones
+ this.bound.checkOperBindable(oper);
+ // then register it properly to the binding events
+ this.binding.bindOper(oper);
+ };
+
+ this.processBindingEvents = function () {
+ // We came to the end of the binding phase. Now we process all our binding
+ // events, This will do the actual binding on the browser side.
+ this.binding.processBindingEvents(this.binder);
+ // Now we to add these to the new ones.
+ this.binding.propagateTo(this.bound);
+ // Delete them from the registry, to protect against accidents.
+ this.binding = null;
+ };
+
this.startBindingPhase();
};
Modified: kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/forms.js
==============================================================================
--- kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/forms.js (original)
+++ kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/forms.js Wed Jan 23 17:35:34 2008
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2005-2007
+* Copyright (c) 2005-2008
* Authors: KSS Project Contributors (see doc/CREDITS.txt)
*
* This program is free software; you can redistribute it and/or modify
@@ -170,14 +170,14 @@
this.formname = formname;
};
-this.getForm = fo.CurrentFormLocator.getForm;
-
this.queryForm = function() {
// Find the form with the given name.
return document.forms[this.formname];
};
+this.initialize.apply(this, arguments);
};
+fo.NamedFormLocator.prototype = new fo.CurrentFormLocator();
/* methods to take the desired value(s) from the form */
@@ -210,13 +210,21 @@
}
}
}
+ // Safari 3.0.3 no longer has "item", instead it works
+ // with direct array access []. Although other browsers
+ // seem to support this as well, we provide checking
+ // in both ways. (No idea if item is still needed.)
} else if (typeof element.length != 'undefined' &&
- typeof element.item != 'undefined' &&
- element.item(0).type == "radio") {
+ ((typeof element[0] != 'undefined' &&
+ element[0].type == "radio") ||
+ (typeof element.item(0) != 'undefined' &&
+ element.item(0).type == "radio"))) {
+ // element really contains a list of input nodes,
+ // in this case.
var radioList = element;
value = null;
for (var i=0; i < radioList.length; i++) {
- var radio = radioList.item(i);
+ var radio = radioList[i] || radioList.item(i);
if (radio.checked) {
value = radio.value;
}
@@ -245,6 +253,8 @@
// Extract the value of a formvar
var value = null;
var element = form[name];
+ // (in case of a radio button this will give a collection
+ // that contains the list of input nodes.)
if (element) {
var value = fo.getValueOfFormElement(element);
;;; if (value != null) {
@@ -326,14 +336,14 @@
this.fieldUpdateRegistry = new _FieldUpdateRegistry();
-// Registry of the pprovider functions for kssSubmitForm
-
-fo.pproviderFormRegistry = new kukit.pr.ValueProviderRegistry();
-
-// form, currentForm will provide identical functions to those
-// in normal parameters
-// except they return a tuple list, not a dictionary.
+//
+// form, currentForm will fetch an entire form for marshalling.
// This is needed because duplications and order must be preserved.
+// The returnType of them will be registered as "formquery". This
+// represents a list of (key, value) tuples that need to be marshalled.
+// This assures to preserve order of keys, which is important
+// for multi-values.
+//
/*
*
@@ -356,7 +366,7 @@
};
-fo.pproviderFormRegistry.register('form', _FormValueProvider);
+kukit.pprovidersGlobalRegistry.register('form', _FormValueProvider, 'formquery');
/*
*
@@ -379,11 +389,7 @@
};
-fo.pproviderFormRegistry.register('currentForm', _CurrentFormValueProvider);
-
-// If a string is given, that will look like a form lookup,
-// ie. identical to form
-fo.pproviderFormRegistry.register('', _FormValueProvider);
+kukit.pprovidersGlobalRegistry.register('currentForm', _CurrentFormValueProvider, 'formquery');
/* BBB. To be deprecated on 2008-06-15 */
Modified: kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/kssparser.js
==============================================================================
--- kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/kssparser.js (original)
+++ kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/kssparser.js Wed Jan 23 17:35:34 2008
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2005-2007
+* Copyright (c) 2005-2008
* Authors: KSS Project Contributors (see doc/CREDITS.txt)
*
* This program is free software; you can redistribute it and/or modify
@@ -159,9 +159,9 @@
break;
}
this.expectToken(context, kssp.colon);
- this.expectToken(context, kssp.PropValue);
+ this.expectToken(context, kssp.MultiPropValue);
// store the wrapped prop
- this.addDeclaration(key, context.token.value);
+ this.addDeclaration(key, context.token.values);
if (context.nextTokenIndex == this.result.length-1) break;
this.expectToken(context, kssp.semicolon);
}
@@ -217,8 +217,7 @@
return results;
};
-this.addEventDeclaration = function(key, splitkey, value) {
-
+this.addEventDeclaration = function(key, splitkey, values) {
// evt-<EVTNAME>-<PARAMETER>: <VALUE>
// evt-<NAMESPACE>-<EVTNAME>-<PARAMETER>: <VALUE>
;;; if (splitkey.length < 3) {
@@ -245,6 +244,11 @@
eventKey = splitkey[3];
eventFullName = eventNamespace + '-' + eventName;
}
+ // preprocess values
+ var allowedReturnTypes;
+;;; allowedReturnTypes = {string: true};
+;;; kukit.E = 'event parameter [' + key + ']';
+ var value = this.preprocessValues(values, allowedReturnTypes, kukit.E).string;
;;; if (value.isMethod != false) {
;;; kukit.E = 'Wrong value for key [' + key + '] : ';
;;; kukit.E += 'value providers are not ';
@@ -260,7 +264,7 @@
eventParameters[eventKey] = value.txt;
};
-this.addActionDeclaration = function(key, splitkey, value) {
+this.addActionDeclaration = function(key, splitkey, values) {
// action-server: <ACTIONNAME>
// action-client: <ACTIONNAME>
// action-client: <NAMESPACE>-<ACTIONNAME>
@@ -270,13 +274,7 @@
;;; kukit.E = 'Wrong key [' + key + '] : ';
;;; kukit.E += 'action-<QUALIFIER> keys can have only one dash.';
;;; this.emitError(kukit.E);
-;;; }
-;;; if (value.isMethod != false) {
-;;; kukit.E = 'Wrong value for key [' + key + '] : ';
-;;; kukit.E += 'value providers are not ';
-;;; kukit.E += 'allowed for action-<QUALIFIER> keys.';
-;;; this.emitError(kukit.E);
-;;; }
+;;; }
var atab = {'server': 'S', 'client': 'C', 'cancel': 'X'};
var actionType = atab[splitkey[1]];
;;; if (! actionType) {
@@ -284,7 +282,28 @@
;;; kukit.E += 'qualifier in action-<QUALIFIER> keys must be ';
;;; kukit.E += '"server" or "client" or "cancel".';
;;; this.emitError(kukit.E);
-;;; }
+;;; }
+ // preprocess values
+ var allowedReturnTypes;
+;;; if (actionType == 'S') {
+;;; // action-server
+;;; allowedReturnTypes = {string: true, formquery: true, url: true};
+;;; } else if (actionType == 'C') {
+;;; // action-client
+;;; allowedReturnTypes = {string: true, selection: true, alias: true};
+;;; } else {
+;;; allowedReturnTypes = {string: true, selection: true};
+;;; }
+;;; kukit.E = 'action definition [' + key + ']';
+ var valuesByReturnType = this.preprocessValues(values, allowedReturnTypes, kukit.E);
+ var value = valuesByReturnType.string;
+ //
+;;; if (value.isMethod != false) {
+;;; kukit.E = 'Wrong value for key [' + key + '] : ';
+;;; kukit.E += 'value providers are not ';
+;;; kukit.E += 'allowed for action-<QUALIFIER> keys.';
+;;; this.emitError(kukit.E);
+;;; }
;;; // force value to be <ACTIONNAME> or <NAMESPACE>-<ACTIONNAME>
;;; var splitvalue = value.txt.split('-');
;;; if (splitvalue.length > 2) {
@@ -294,17 +313,28 @@
;;; this.emitError(kukit.E);
;;; }
// set it
- var action = this.actions.getOrCreateAction(value.txt);
- if (actionType != 'X' || action.type == null) {
- action.setType(actionType);
+ if (actionType != 'X') {
+ // any other qualifier then delete
+ var action = this.actions.getOrCreateAction(value.txt, valuesByReturnType);
+ if (action.type == null) {
+ action.setType(actionType);
+ }
} else {
+ // action-cancel
this.actions.deleteAction(value.txt);
}
};
-this.addActionError = function(action, key, value) {
+this.addActionError = function(action, key, values) {
// <ACTIONNAME>-error: <VALUE>
// default-error: <VALUE>
+ //
+ // This can only accept string.
+ var allowedReturnTypes;
+;;; allowedReturnTypes = {string: true};
+;;; kukit.E = 'action error parameter [' + key + ']';
+ var value = this.preprocessValues(values, allowedReturnTypes, kukit.E).string;
+;;; // It cannot be a provider, it must be a real string.
;;; if (value.isMethod == true) {
;;; kukit.E = 'Wrong value for key [' + key + '] : ';
;;; kukit.E += 'value providers are not ';
@@ -313,17 +343,11 @@
;;; }
action.setError(value.txt);
// also create the action for the error itself.
- var err_action = this.actions.getOrCreateAction(value.txt);
+ var err_action = this.actions.getOrCreateAction(value.txt, {});
err_action.setType('E');
};
-this.addActionParameter = function(action, key, value) {
- var ppRegistries = {
- '': kukit.pprovidersGlobalRegistry,
- 'kssSelector': kukit.sr.pproviderSelRegistry,
- 'kssSubmitForm': kukit.fo.pproviderFormRegistry
- };
-
+this.addActionParameter = function(action, key, values) {
// <ACTIONNAME>-<KEY>: <VALUE>
// default-<KEY>: <VALUE>
//
@@ -334,26 +358,54 @@
// This will also set the value providers on the value
// (from check).
//
- // Figure out which registry to use.
- var registry = ppRegistries[key];
- if (typeof(registry) == 'undefined') {
- // use default pproviders
- registry = ppRegistries[''];
- }
- //
- try {
- // Check also sets the value provider on the value.
- value.check(registry);
- } catch(e) {
-;;; kukit.E = 'Error in value : ' + e + '.';
- this.emitError(kukit.E);
+ var value;
+ if (key.substr(0, 3) == 'kss') {
+;;; // Special selector types can have only one value
+;;; if (values.length != 1) {
+;;; kukit.E = 'Must have exactly one value, and got [' + values.length;
+;;; kukit.E += '] in the kss action parameter [' + key + '].';
+;;; this.emitError(kukit.E);
+;;; }
+ value = values[0];
+;;; // kss special parameter need special checking of the strings.
+;;; // (not needed in production mode, since we have the value already)
+;;; var allowedReturnTypes = {};
+;;; if (key == 'kssSelector') {
+;;; // for kssSelector, one of string or formquery expected
+;;; allowedReturnTypes = {string: true, selection: true};
+;;; } else if (key == 'kssSubmitForm') {
+;;; // for kssSubmitForm string or formquery expected
+;;; allowedReturnTypes = {string: true, formquery: true};
+;;; } else if (key == 'kssUrl') {
+;;; // for kssUrl string or url expected
+;;; allowedReturnTypes = {string: true, url: true};
+;;; }
+;;; // We ignore actual results here, and just check.
+;;; kukit.E = 'kss action parameter [' + key + ']';
+ // Call preprocessValues in both production and development mode:
+ // it is always needed, since it calls check() on the value.
+ // Last parameter is true: means we do _not_ require the existence
+ // of a string type.
+ this.preprocessValues(values, allowedReturnTypes, kukit.E, true);
+ } else {
+ // Normal selectors: can have more values
+ // check its return types
+ var allowedReturnTypes;
+;;; allowedReturnTypes = {string: true, selection: true};
+;;; kukit.E = 'action parameter [' + key + ']';
+ var valuesByReturnType = this.preprocessValues(values, allowedReturnTypes, kukit.E);
+ value = valuesByReturnType.string;
+ // Store the selector on the value.
+ value.selectionValue = valuesByReturnType.selection;
}
+ // store the (main, string) value
action.parms[key] = value;
};
-this.addDeclaration = function(key, value) {
- // p.s. value is here a KssXxParm. In most cases we check and unwrap it.
- // the keys look like this:
+this.addDeclaration = function(key, values) {
+ // values contains a list of arguments (KssTextValue or KssMethodValue)
+ //
+ // the key looks like this:
//
// evt-<EVTNAME>-<KEY>: <VALUE>
// evt-<NAMESPACE>-<EVTNAME>-<KEY>: <VALUE>
@@ -381,11 +433,13 @@
;;; kukit.E += '"evt-<NAMESPACE>-<EVENTNAME>-<PARAMETER>".';
;;; this.emitError(kukit.E);
;;; }
+ // Preprocess the values
+ //
var name = splitkey[0];
if (name == 'evt') {
- this.addEventDeclaration(key, splitkey, value);
+ this.addEventDeclaration(key, splitkey, values);
} else if (name == 'action') {
- this.addActionDeclaration(key, splitkey, value);
+ this.addActionDeclaration(key, splitkey, values);
} else {
// <ACTIONNAME>-<KEY>: <VALUE>
// <NAMESPACE>-<ACTIONNAME>-<KEY>: <VALUE>
@@ -408,13 +462,77 @@
actionName = splitkey[0] + '-' + splitkey[1];
actionKey = splitkey[2];
}
- var action = this.actions.getOrCreateAction(actionName);
+ var action = this.actions.getOrCreateAction(actionName, {});
if (actionKey == 'error') {
- this.addActionError(action, key, value);
+ this.addActionError(action, key, values);
} else {
- this.addActionParameter(action, actionKey, value);
+ this.addActionParameter(action, actionKey, values);
+ }
+ }
+};
+
+this.preprocessValues = function(values, allowedReturnTypes,
+ errInfo, noStringRequired) {
+ // allowedReturnTypes is a dict keyed by the returnType, containing true as value.
+ // key is only used for the error reporting
+ // This will also call check on all the value names!
+ // noStringRequired is set to true at the kss special parameters. All other
+ // occasions require at least a string to be present, so we check for that too.
+ var valuesByReturnType = {};
+
+ for (var i=0; i<values.length; i++) {
+ var value = values[i];
+ // Checking the value
+ // this is needed for later evaluation.
+ try {
+ // Check also sets the value provider on the value.
+ value.check();
+ } catch(e) {
+;;; kukit.E = 'Error in value for ' + errInfo + ' : ' + e + '.';
+ this.emitError(kukit.E);
}
+ // XXX text values are not wrapped. So we need to check for the
+ // pprovider....
+ var returnType = (typeof(value.pprovider) != 'undefined') && value.pprovider.returnType;
+ //for(var xx in value) {print (xx, value[xx]);}
+ // Default return type is "string".
+ if (! returnType) {
+ returnType = 'string';
+ }
+;;; // Check if return type is allowed.
+;;; if (! allowedReturnTypes[returnType]){
+;;; kukit.E = 'Provider result type [' + returnType;
+;;; kukit.E += '] not allowed in the ' + errInfo + '.';
+;;; this.emitError(kukit.E);
+;;; }
+;;; // Check duplicate type. Only one provider is allowed
+;;; // from each return type, ie. maximum one string,
+;;; // one selector, etc.
+;;; if (typeof(valuesByReturnType[returnType]) != 'undefined') {
+;;; if (returnType == 'string') {
+;;; // Give a more sensible message for strings.
+;;; // (Do not mention the word "provider" in the message
+;;; // as action-xxx cannot take providers, only real strings.
+;;; kukit.E = 'Only one [string] value ';
+;;; kukit.E += 'is allowed in the ' + errInfo + '.';
+;;; } else {
+;;; kukit.E = 'Only one provider with result type [' + returnType;
+;;; kukit.E += '] is allowed in the ' + errInfo + '.';
+;;; }
+;;; this.emitError(kukit.E);
+;;; }
+ // store it
+ valuesByReturnType[returnType] = value;
}
+;;; // Check we have at least a string type. (unless asked otherwise)
+;;; if (! noStringRequired && typeof(valuesByReturnType.string) == 'undefined') {
+;;; // (Do not mention the word "provider" in the message
+;;; // as action-xxx cannot take providers, only real strings.
+;;; kukit.E = 'Missing [string] value ';
+;;; kukit.E += 'in the ' + errInfo + '.';
+;;; this.emitError(kukit.E);
+;;; }
+ return valuesByReturnType;
};
};
@@ -422,7 +540,7 @@
";": _mkReturnToken(kssp.semicolon),
":": function() {
return [new kssp.colon(this.cursor),
- new kssp.PropValue(this.cursor)]
+ new kssp.MultiPropValue(this.cursor)]
},
"}": _mkEmitAndReturnToken(kssp.closeBrace)
},
@@ -435,67 +553,110 @@
var _PropValue = function() {
this.process = function() {
+ // For multivalue only
+ this.values = []
// Parse all tokens (including first and last)
var context = {'nextTokenIndex': 0};
- this.digestTxt(context, kukit.tk.Fraction, kssp.Comment);
this.txt = '';
- var txt = context.txt;
- if (this.notInTokens(context, 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, kssp.String);
- this.produceTxt(context.token.txt);
- } else if (this.notInTokens(context, kssp.MethodArgs)) {
- // see if not empty and has no spaces in it
- if (! txt || txt.indexOf(' ') != -1) {
-;;; kukit.E = 'Wrong value : method name [' + txt + '] cannot ';
-;;; kukit.E += 'have spaces.';
- this.emitError(kukit.E);
- }
- // the next one must be the rules
- this.expectToken(context, kssp.MethodArgs);
- this.value = new this.valueClass(txt, context.token.args);
- } 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);
+ // Iterate for multiple values (in case allowed.)
+ // txtCarry holds the part of text that we need to consider
+ // as a possible method name, in case method args follow.
+ var txtCarry = '';
+ while (context.nextTokenIndex < this.result.length) {
+ if (this.notInTokens(context, kukit.kssp.String)) {
+ // A string token follows:
+ if (txtCarry) {
+ // If we have a txt carry left, it needs to be
+ // produced first, separately.
+ this.produceTxt(txtCarry);
+ txtCarry = '';
+ }
+ // 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.MethodArgs)) {
+ // A MethodArgs token follows:
+ // see if not empty
+ if (! txtCarry) {
+;;; // Be a little more intelligent with this error.
+;;; // If we are single value, and there is a value,
+;;; // the following raises a smarter error message, complaining
+;;; // about the () as excess.
+;;; this.addValue(null, '(');
+;;; // otherwise, just do the next error message:
+;;; kukit.E = 'Wrong value : empty method name.';
+ this.emitError(kukit.E);
+ }
+ // the next one must be the (a1, a2, ...an) method args.
+ this.expectToken(context, kukit.kssp.MethodArgs);
+ // The txtCarry will be used as the name of the method.
+ this.addValue(new kukit.rd.KssMethodValue(txtCarry, context.token.args),
+ txtCarry);
+ txtCarry = '';
+ } else {
+ // Try to digest another fraction.
+ this.digestTxt(context, kukit.tk.Fraction, kukit.kssp.Comment);
+ //
+ // Split the fraction to words. We may have a word
+ // and we may have a MethodArg after:
+ // wordone ... wordlast(...) ...
+ // ^^^^^^^^^^^^^^^^^^^^ - these are in the Fraction
+ // ^^^^^ - these are the MethodArgs
+ // So we produce all strings except the last one, and
+ // continue the cycle with the last one (worlast) as txt.
+ // This enables it to be produced with the MethodArgs.
+ //
+ var words = context.txt.split(' ');
+ // Emit the original txtCarry - if there is one.
+ if (txtCarry) {
+ this.produceTxt(txtCarry);
+ txtCarry = '';
+ }
+ // If we have input, process it.
+ if (words.length > 0) {
+ // Produce all strings except the last one
+ for (var i=0; i<words.length - 1; i++) {
+ this.produceTxt(words[i]);
+ }
+ // Carry the last one to the next iteration.
+ txtCarry = words[words.length - 1];
+ }
}
- this.produceTxt(txt);
}
- // see what's after
- if (context.nextTokenIndex < this.result.length) {
- this.digestTxt(context, kukit.tk.Fraction, kssp.Comment);
- // we have to be at the end and have no text after
- if (context.nextTokenIndex < this.result.length || context.txt) {
-;;; kukit.E = 'Wrong value : unallowed characters after ';
-;;; kukit.E += 'the property.';
- this.emitError(kukit.E);
- }
+ if (txtCarry) {
+ // If we have a txt carry, it needs to be produced finally.
+ this.produceTxt(txtCarry);
}
this.result = [];
};
this.initialize = function() {
- this.multiword_allowed = true;
+ this.multiword_allowed = false;
this.valueClass = kukit.rd.KssMethodValue;
};
this.produceTxt = function(txt) {
- // txt parms are returned embedded
- this.value = new kukit.rd.KssTextValue(txt);
+ this.addValue(new kukit.rd.KssTextValue(txt), txt);
+};
+
+this.addValue = function(value, errInfo) {
+ // Do not allow a second value
+ if (this.value) {
+;;; kukit.E = 'Wrong value : unallowed characters [';
+;;; kukit.E += errInfo + '] after ';
+;;; kukit.E += 'the argument.';
+ this.emitError(kukit.E);
+ }
+ this.value = value;
};
+
this.initialize.apply(this, arguments);
};
kssp.PropValue = kukit.tk.mkParser('propValue', {
";": _emitAndReturn,
"}": _emitAndReturn,
")": _emitAndReturn,
+ "]": _emitAndReturn,
",": _emitAndReturn,
"'": _returnString,
'"': _returnString2,
@@ -506,36 +667,35 @@
);
/*
-* class PropValueInMethod
-*
-* PropValue in method cannot have method-style vars.
+* class MultiPropValue
+*
+* A list of PropValue-s (arguments), separated by whitespace
*/
-var _PropValueInMethod = function() {
+var _MultiPropValue = function() {
-this.initialize = function() {
- this.multiword_allowed = false;
-};
+ this.addValue = function(value, errInfo) {
+ this.values.push(value);
+ };
+
+ this.initialize = function() {
+ this.multiword_allowed = true;
+ };
-this.produceTxt = function(txt) {
- // txt parms are returned unwrapped
- this.txt = txt;
-};
-this.initialize.apply(this, arguments);
};
-// this assignment needs to remain after initialization of _PropValue
-kssp.PropValueInMethod = kukit.tk.mkParser('propValue', {
+_MultiPropValue.prototype = new _PropValue();
+kssp.MultiPropValue = kukit.tk.mkParser('multiPropValue', {
";": _emitAndReturn,
"}": _emitAndReturn,
")": _emitAndReturn,
- "]": _emitAndReturn,
",": _emitAndReturn,
"'": _returnString,
'"': _returnString2,
- "\/\*": _returnComment
+ "\/\*": _returnComment,
+ "(": _returnMethodArgs
},
- _PropValueInMethod
+ _MultiPropValue
);
-kssp.PropValueInMethod.prototype.process = kssp.PropValue.prototype.process;
+
/*
* class EventValue
@@ -864,7 +1024,7 @@
} break;
}
}
- // Now we found the token that must be <fraction> <colon> <propValue>.
+ // Now we found the token that must be <fraction> <colon> <multiPropValue>.
tokenIndex -= 2;
if (tokenIndex < 0
|| (this.result[tokenIndex+2].symbol !=
@@ -942,7 +1102,7 @@
;;; } else {
;;; throw e;
;;; }
-;;; }
+;;; };
this.txt = '';
this.result = [];
};
Modified: kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/oper.js
==============================================================================
--- kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/oper.js (original)
+++ kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/oper.js Wed Jan 23 17:35:34 2008
@@ -59,6 +59,44 @@
this.orignode = null;
this.action = null;
this.browserevent = null;
+
+ this.clone = function(dict, restricted) {
+ var newoper = new kukit.op.Oper(this);
+ newoper.unrestrictedUpdate(dict, restricted);
+ return newoper;
+ };
+
+ this.update = function(dict) {
+ // restricted attrs must not be changed on existing oper.
+ this.unrestrictedUpdate(dict, true);
+ };
+
+ this.unrestrictedUpdate = function(dict, restricted) {
+ if (typeof(dict) == 'undefined') {
+ return;
+ }
+ for (var key in dict) {
+;;; if (typeof(checkKey) == 'undefined') {
+;;; var checkKey = function(key) {
+;;; var isNode = key == 'node';
+;;; var isParameters = key == 'parms';
+;;; var isEventRule = key == 'eventRule';
+;;; var isBinder = key == 'binder';
+;;; var isOrig = key == 'orignode';
+;;; return isNode || isParameters || isEventRule || isBinder || isOrig;
+;;; };
+;;; }
+;;; if (restricted && checkKey(key)) {
+;;; kukit.E = 'Illegal update on oper object, protected attribute [';
+;;; kukit.E += key + '].';
+;;; throw new Error(kukit.E);
+;;; }
+ var value = dict[key];
+ if (typeof(value) != 'function') {
+ this[key] = value;
+ }
+ }
+ };
// update from the dict
this.unrestrictedUpdate(dict);
};
@@ -206,18 +244,27 @@
};
this.executeServerAction = function(name) {
-;;; for (key in this.kssParms) {
-;;; if (key == 'kssUrl') {
-;;; // Value will be evaluated.
-;;; } else if (key == 'kssSubmitForm') {
+ for (key in this.kssParms) {
+ if (key == 'kssSubmitForm') {
+ // Value has been evaluated at this point.
+ var formQuery = this.kssParms[key];
+ // If a string is returned: this is to support
+ // kssSubmitForm: "formname";
+ // in this case this is evaluated as form("formname").
+ if (typeof(formQuery) == 'string') {
+ var locator = new kukit.fo.NamedFormLocator(formQuery);
+ var collector = new kukit.ut.TupleCollector();
+ formQuery = kukit.fo.getAllFormVars(locator, collector);
+ }
+;;; } else if (key == 'kssUrl') {
;;; // Value will be evaluated.
;;; } else {
;;; kukit.E = 'Wrong parameter : [' + key + '] starts with "kss";';
;;; kukit.E += ' normal parms (that do not start with kss)';
-;;; kukit.E += ' only are allowed in action-server keys.';
+;;; kukit.E += ' only are allowed in action-default keys.';
;;; throw new Error(kukit.E);
-;;; }
-;;; }
+ }
+ }
// oper will be accessible to some commands that execute in return
var sa = new kukit.sa.ServerAction(name, this);
};
Modified: kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/plugin.js
==============================================================================
--- kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/plugin.js (original)
+++ kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/plugin.js Wed Jan 23 17:35:34 2008
@@ -541,7 +541,8 @@
this.timeoutSetState = function() {
// really call the bound actions which should set the spinner
- this.func_to_bind();
+ var func = this.func_to_bind;
+ func();
};
this.initialize.apply(this, arguments);
};
Modified: kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/providerreg.js
==============================================================================
--- kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/providerreg.js (original)
+++ kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/providerreg.js Wed Jan 23 17:35:34 2008
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2005-2007
+* Copyright (c) 2005-2008
* Authors: KSS Project Contributors (see doc/CREDITS.txt)
*
* This program is free software; you can redistribute it and/or modify
@@ -32,7 +32,7 @@
this.content = {};
};
-this.register = function(name, func) {
+this.register = function(name, func, returnType) {
if (typeof(func) == 'undefined') {
;;; kukit.E = 'func argument is mandatory when registering a parameter'
;;; kukit.E += ' provider [ValueProviderRegistry.register].';
@@ -46,6 +46,11 @@
;;; return;
;;; }
this.content[name] = func;
+ // Handle return type
+ // XXX Store it on the func's prototype.
+ // This is a temporary solution, the service-layer
+ // branch offers a proper way to do this.
+ func.prototype.returnType = returnType;
};
this.exists = function(name) {
@@ -64,6 +69,9 @@
this.initialize.apply(this, arguments);
};
+}(); /// MODULE END
+
+kukit.dummy = new function() { /// MODULE START
/*
* Register the core parameter providers
*
@@ -164,8 +172,7 @@
if (args.length == 2) {
;;; kukit.E = '2nd attribute of currentFormVarForKssAttr must be a';
;;; kukit.E += ' boolean';
- kukit.ut.evalBool(args[1], kukit.E);
- recurseParents = args[1];
+ recurseParents = kukit.ut.evalBool(args[1], kukit.E);
}
var formvarname = kukit.dom.getRecursiveAttribute(node, argname,
recurseParents, kukit.dom.getKssAttribute);
@@ -176,50 +183,6 @@
};
-/* BBB. To be deprecated at 2007-08-15 */
-/*
-* class _FormPP
-*/
-var _FormPP = function() {
-
-this.check = function(args) {
-;;; if (args.length != 1) {
-;;; throw new Error('form method needs 1 arguments [formname]');
-;;; }
-;;; var msg = 'Deprecated the [form(formname)] parameter provider,';
-;;; msg += ' use [xxx-kssSubmitForm: form(formname)] instead !';
-;;; kukit.logWarning(msg);
-};
-
-this.eval = function(args, node) {
- return kukit.fo.getAllFormVars(new kukit.fo.NamedFormLocator(args[0]),
- new kukit.ut.DictCollector());
-};
-
-};
-
-/* BBB. To be deprecated at 2007-08-15 */
-/*
-* class _CurrentFormPP
-*/
-var _CurrentFormPP = function() {
-
-this.check = function(args) {
-;;; if (args.length != 0) {
-;;; throw new Error('currentForm method needs no argument');
-;;; }
-;;; var msg = 'Deprecated the [currentForm()] parameter provider,';
-;;; msg += ' use [xxx-kssSubmitForm: currentForm()] instead !';
-;;; kukit.logWarning(msg);
-};
-
-this.eval = function(args, node) {
- return kukit.fo.getAllFormVars(new kukit.fo.CurrentFormLocator(node),
- new kukit.ut.DictCollector());
-};
-
-};
-
/*
* class _NodeAttrPP
*/
@@ -231,10 +194,14 @@
;;; kukit.E += ' [recurseParents]).';
;;; throw new Error(kukit.E);
;;; }
-;;; if (args[0].toLowerCase() == 'style') {
+};
+
+this.eval = function(args, node) {
+ var argname = args[0];
+;;; if (argname.toLowerCase() == 'style') {
;;; throw new Error('nodeAttr method does not accept [style] as attrname.');
;;; }
-;;; if (args[0].match(/[ ]/)) {
+;;; if (argname.match(/[ ]/)) {
;;; throw new Error('attrname parameter in nodeAttr method cannot contain space.');
;;; }
};
@@ -245,7 +212,7 @@
if (args.length == 2) {
recurseParents = args[1];
;;; kukit.E = '2nd attribute of nodeAttr must be a boolean.';
- kukit.ut.evalBool(recurseParents, kukit.E);
+ recurseParents = kukit.ut.evalBool(recurseParents, kukit.E);
}
return kukit.dom.getRecursiveAttribute(node, argname, recurseParents,
kukit.dom.getAttribute);
@@ -259,12 +226,29 @@
var _KssAttrPP = function() {
this.check = function(args) {
+;;; // Uncomment next part to activate BBB:
+;;; //kukit.E = 'kssAttr is deprecated and will be removed at ';
+;;; //kukit.E += '2008-XX-XX';
+;;; //kukit.E += ', use kssValue. Change your html ';
+;;; //kukit.E += 'class markup from kssattr-key-value to ';
+;;; //kukit.E += 'kss-attr-key-value, ';
+;;; //kukit.E += 'and change the provider from kssAttr(key, true) to ';
+;;; //kukit.E += 'kssValue(attr, key). Note that kssValue has a third ';
+;;; //kukit.E += 'parameter to enable/disable recursion, but in contrary ';
+;;; //kukit.E += 'to kssAttr, kssValue has recursion by default enabled ';
+;;; //kukit.E += '(true).';
+;;; //kukit.logWarning(kukit.E);
;;; if (args.length != 1 && args.length != 2) {
;;; kukit.E = 'kssAttr method needs 1 or 2 argument (attrname,';
;;; kukit.E += ' [recurseParents]).';
;;; throw new Error(kukit.E);
;;; }
-;;; if (args[0].match(/[ -]/)) {
+};
+
+this.eval = function(args, node) {
+ var argname = args[0];
+ var recurseParents = false;
+;;; if (argname.match(/[ -]/)) {
;;; kukit.E = 'attrname parameter in kssAttr method cannot contain';
;;; kukit.E += ' dashes or spaces.';
;;; throw new Error(kukit.E);
@@ -277,7 +261,7 @@
if (args.length == 2) {
recurseParents = args[1];
;;; kukit.E = '2nd attribute of kssAttr must be a boolean.';
- kukit.ut.evalBool(recurseParents, kukit.E);
+ recurseParents = kukit.ut.evalBool(recurseParents, kukit.E);
}
return kukit.dom.getRecursiveAttribute(node, argname, recurseParents,
kukit.dom.getKssAttribute);
@@ -354,8 +338,114 @@
};
+var _KssValuePP = function() {
+
+ this.check = function(args) {
+;;; if (args.length != 2 && args.length != 3) {
+;;; kukit.E = 'kssValue provider needs 2 or 3 argument (keytype, key,';
+;;; kukit.E += ' [recurseParents]).';
+;;; throw new Error(kukit.E);
+;;; }
+ };
+
+ this.eval = function(args, node) {
+ var keytype = args[0];
+ var key = args[1];
+ // recurseParents is by default true
+ var recurseParents = true;
+;;; if (keytype.match(/[ -]/)) {
+;;; kukit.E = 'keytype parameter in kssValue provider cannot contain';
+;;; kukit.E += ' dashes or spaces.';
+;;; throw new Error(kukit.E);
+;;; }
+;;; if (key.match(/[ -]/)) {
+;;; kukit.E = 'key parameter in kssValue provider cannot contain';
+;;; kukit.E += ' dashes or spaces.';
+;;; throw new Error(kukit.E);
+;;; }
+ if (args.length == 3) {
+ recurseParents = args[2];
+;;; kukit.E = '3rd attribute of kssAttr must be a boolean.';
+ recurseParents = kukit.ut.evalBool(recurseParents, kukit.E);
+ }
+ return kukit.dom.locateMarkup(node, recurseParents,
+ kukit.dom.getKssValue,
+ keytype, key).value;
+
+ };
+
+};
+
+var _KssIdOfValuePP = function() {
+
+ this.check = function(args) {
+;;; if (args.length != 2) {
+;;; kukit.E = 'kssIdOfValue provider needs 2 arguments (keytype, key).';
+;;; throw new Error(kukit.E);
+;;; }
+ },
+
+ this.eval = function(args, node) {
+ var keytype = args[0];
+ var key = args[1];
+;;; if (keytype.match(/[ -]/)) {
+;;; kukit.E = 'keytype parameter in kssIdOfValue provider cannot contain';
+;;; kukit.E += ' dashes or spaces.';
+;;; throw new Error(kukit.E);
+;;; }
+;;; if (key.match(/[ -]/)) {
+;;; kukit.E = 'key parameter in kssIdOfValue provider cannot contain';
+;;; kukit.E += ' dashes or spaces.';
+;;; throw new Error(kukit.E);
+;;; }
+ var markup = kukit.dom.locateMarkup(node, true,
+ kukit.dom.getKssValue,
+ keytype, key);
+ // return the id of the node where the markup is found
+ var id = markup.node.id;
+ if (typeof(id) == 'undefined') {
+ // notfound arguments will get null
+ id = null;
+ }
+ return id;
+ }
+};
-kukit.pprovidersGlobalRegistry = new this.ValueProviderRegistry();
+
+/* The url() provider just passes the parameter, and is used to have
+ * a different return type. It can be used in the line of action-server.
+ * as an alternative to a separate kssUrl line.
+ */
+var _UrlPP = function() {
+ this.check = function(args) {
+;;; if (args.length != 1) {
+;;; throw new Error('url() needs 1 argument');
+;;; }
+ };
+};
+_UrlPP.prototype = new _IdentityPP();
+
+
+/* The alias() provider just passes the parameter, and is used to have
+ * a different return type. It can be used in the line of action-client.
+ */
+var _AliasPP = function() {
+ this.check = function(args) {
+;;; if (args.length != 1) {
+;;; throw new Error('alias() needs 1 argument');
+;;; }
+;;; if (args[0].isMethod) {
+;;; kukit.E = 'Value providers are not ';
+;;; kukit.E += 'allowed as argument for ';
+;;; kukit.E += 'alias(), [' + args[0].methodName + '] found.';
+;;; throw new Error(kukit.E);
+;;; }
+ };
+};
+_AliasPP.prototype = new _IdentityPP();
+
+
+kukit.pprovidersGlobalRegistry = new kukit.pr.ValueProviderRegistry();
kukit.pprovidersGlobalRegistry.register('', _IdentityPP);
kukit.pprovidersGlobalRegistry.register('currentFormVar',
@@ -368,8 +458,13 @@
kukit.pprovidersGlobalRegistry.register('pass', _PassPP);
kukit.pprovidersGlobalRegistry.register('nodeContent', _NodeContentPP);
kukit.pprovidersGlobalRegistry.register('nodeAttr', _NodeAttrPP);
-kukit.pprovidersGlobalRegistry.register('form', _FormPP);
-kukit.pprovidersGlobalRegistry.register('currentForm', _CurrentFormPP);
+kukit.pprovidersGlobalRegistry.register('kssValue', _KssValuePP);
+kukit.pprovidersGlobalRegistry.register('kssIdOfValue', _KssIdOfValuePP);
+// returnType = 'url'
+kukit.pprovidersGlobalRegistry.register('url', _UrlPP, 'url');
+// returnType = 'alias'
+kukit.pprovidersGlobalRegistry.register('alias', _AliasPP, 'alias');
}(); /// MODULE END
+
Modified: kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/requestmanager.js
==============================================================================
--- kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/requestmanager.js (original)
+++ kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/requestmanager.js Wed Jan 23 17:35:34 2008
@@ -171,7 +171,7 @@
*/
rm.RequestManager = function () {
-this.initialize = function (maxNr, name, schedulerClass) {
+this.initialize = function (name, maxNr, schedulerClass) {
// schedulerClass is mainly provided for debugging...
this.waitingQueue = new kukit.ut.FifoQueue();
this.sentNr = 0;
@@ -189,9 +189,12 @@
nameString = '[' + name + '] ';
}
this.nameString = nameString;
- if (typeof(maxNr) != 'undefined' && maxNr != null) {
- this.maxNr = maxNr;
+ // max request number
+ if (typeof(maxNr) == 'undefined' || maxNr == null) {
+ // Default is 4
+ maxNr = 4;
}
+ this.maxNr = maxNr;
// sets the timeout scheduler
var checkTimeout = function() {
self.checkTimeout();
Modified: kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/resourcedata.js
==============================================================================
--- kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/resourcedata.js (original)
+++ kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/resourcedata.js Wed Jan 23 17:35:34 2008
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2005-2007
+* Copyright (c) 2005-2008
* Authors: KSS Project Contributors (see doc/CREDITS.txt)
*
* This program is free software; you can redistribute it and/or modify
@@ -28,7 +28,7 @@
*/
rd.KssSelector = function() {
-this.initialize = function(isEvent, css, name, namespace, id, ppid, eventRegistry) {
+this.initialize = function(isEvent, css, name, namespace, id, ppid) {
this.isEventSelector = isEvent;
this.isMethodSelector = ! isEvent;
// XXX GC row and column are wrong...
@@ -70,16 +70,19 @@
this.className = null;
this.id = id;
this.ppid = ppid;
- this.setClassName(eventRegistry);
+ // finish up the KSS on it
+ // XXX This disables testing the parser
+ // without a plugin registry, since it needs access to the registry.
+ this.setClassName();
};
// finish up the KSS on it
-this.setClassName = function(eventRegistry) {
+this.setClassName = function() {
// Sets up id and class on the selector, based on registration info
// XXX GC instead of relying on exceptions, test if key exists
try {
- this.className = eventRegistry.get(
- this.namespace, this.name).className;
+ this.className = kukit.eventsGlobalRegistry.get(
+ this.namespace, this.name).className;
} catch(e) {
throw kukit.err.parsingError(e.message);
}
@@ -158,7 +161,7 @@
this.check = function(registry) {
// use the IdentityPP provider.
- this.pprovider = new (registry.get(''))();
+ this.pprovider = new (kukit.pprovidersGlobalRegistry.get(''))();
};
this.evaluate =
@@ -186,24 +189,60 @@
this.check = function(registry) {
// Check syntax
- var f = registry.get(this.methodName);
+ var f = kukit.pprovidersGlobalRegistry.get(this.methodName);
this.pprovider = new f();
- for(i=0; i < this.args.length; i++){
+;;; //Check the provider first.
+;;; this.pprovider.check(this.args);
+ // After checking the provider, we check the args recursively.
+ for(var i=0; i < this.args.length; i++){
// XXX We treat text values separetly because
// they are now currently wrapped as KssTextValue
// (as they should). TODO
var arg = this.args[i];
+ // XXX this is a check for a MethodValue, since
+ // all text arguments are strings. -- this is fixed
+ // on the service-layer branch
if(arg.check){
- // With the recursion we always use the global
- // provider registry
- arg.check(kukit.pprovidersGlobalRegistry);
+ arg.check();
+;;; // The page provider should have checked if the parameters
+;;; // return the appropriate value type. If it has done
+;;; // this check, it has set checkedArgTypes.
+;;; // If a provider expects all strings
+;;; // (like most value providers), it simply leaves this flag
+;;; // intact, and we do the check here.
+;;; if (! this.pprovider.checkedArgTypes) {
+;;; // We expect a string to each position.
+;;; // By default, returnType is "string" so we also
+;;; // check undefined.
+;;; var returnType = arg.pprovider.returnType;
+;;; if (returnType && returnType != 'string') {
+;;; kukit.E = 'Expected string value and got [' + returnType;
+;;; kukit.E += '] in argument #[' + (i + 1) + '] of provider [';
+;;; kukit.E += this.methodName + '].';
+;;; throw new Error(kukit.E);
+;;; }
+;;; }
+
}
}
-;;; this.pprovider.check(this.args);
};
this.evaluate =
function(node, defaultParameters) {
+ // In case we have a selector, evaluate it.
+ if (this.selectionValue) {
+ var nodes = this.selectionValue.evaluate(node, defaultParameters)
+ // This must have returned exactly one node. If not, we raise error.
+ if (nodes.length != 1) {
+;;; kukit.E = 'Selection provider [' + this.selectionValue.methodName;
+;;; kukit.E += '] of value provider [' + this.methodName;
+;;; kukit.E += '] must select exactly one node, '
+;;; kukit.E += 'got [' + nodes.length + '] instead.';
+ throw new Error(kukit.E);
+ }
+ // Use this as node!
+ node = nodes[0];
+ }
// First recursivly evaluate all arguments
var newArgs = [];
for(var i=0; i < this.args.length; i++){
@@ -492,13 +531,39 @@
}
};
-this.getOrCreateAction = function(name) {
+this.getOrCreateAction = function(name, valuesByReturnType) {
+ // kss parameters will ve set from valuesByReturnType
+ //
+ // In case we alias, use the alias for name, this will become
+ // the action name used for execution. The alias name will
+ // be used as name, and serve for decide merging.
+ var nameOverride;
+ if (valuesByReturnType.alias) {
+ nameOverride = name;
+ // This is always a string, no provider allowed.
+ //
+ // XXX atm, strings are unwrapped. (this is fixed
+ // in service-layer branch)
+ name = valuesByReturnType.alias.args[0];
+ }
+ // Check if we have this action already
var action = this.content[name];
if (typeof(action) == 'undefined') {
action = new _Action();
- action.setName(name);
+ action.setName(name, nameOverride);
this.content[name] = action;
}
+ // Set other values that were given at the same line as the name.
+ // This enables individual overriding.
+ if (valuesByReturnType.selection) {
+ action.parms.kssSelector = valuesByReturnType.selection;
+ }
+ if (valuesByReturnType.formquery) {
+ action.parms.kssSubmitForm = valuesByReturnType.formquery;
+ }
+ if (valuesByReturnType.url) {
+ action.parms.kssUrl = valuesByReturnType.url;
+ }
return action;
};
@@ -541,15 +606,55 @@
this.error = null;
this.parms = {};
this.type = null;
+ this.nameOverride = null;
};
-this.setName = function(name) {
-;;; if (this.name != null && this.name != name) {
-;;; var msg = 'Error overriding action name [' + this.name;
-;;; msg = msg + '] to [' + name + '] (Unmatching action names at merge?)';
-;;; throw kukit.err.ruleMergeError(msg);
+this.getExecutingName = function getExecutingName() {
+ // Returns action name that is to be used for execution.
+ // In case nameOverride is empty, name is used both as merging
+ // key, and for selecting the action at execution.
+ // In case nameOverride is specified, name is still used for
+ // merging, but nameOverride is used when we need to
+ // execute the action.
+ // This is used for action-client: nameOverride alias(name).
+ return this.nameOverride || this.name;
+};
+
+this.setName = function(name, nameOverride) {
+ if (typeof(nameOverride) == 'undefined' || name == nameOverride) {
+ // use null for no-value.
+ //
+ // Also: If we alias to the same name as the action name,
+ // simply ignore aliasing and just handle the real action.
+ nameOverride = null;
+ }
+;;; // We check that the name did not change.
+;;; if (this.name != null) {
+;;; if (this.name != name) {
+;;; kukit.E = 'Error overriding action name [' + this.name;
+;;; kukit.E += '] to [' + name + '] (Unmatching action names or aliases at merge?)';
+;;; throw kukit.err.ruleMergeError(kukit.E);
+;;; }
+;;; // nameOverride can only be specified when name is also specified.
+;;; // We also check that the override cannot change, ie. it is not
+;;; // possible to use the same alias for different actions.
+;;; // However we allow this.nameOverride to have a value and nameOverride
+;;; // to be null.
+;;; if (nameOverride != null && this.nameOverride != nameOverride) {
+;;; kukit.E = 'Error overriding action name for alias [' + this.name;
+;;; kukit.E += '] from [' + this.nameOverride;
+;;; kukit.E += '] to [' + nameOverride + '] ';
+;;; kukit.E += '(Different actions aliased by the same alias?)';
+;;; throw kukit.err.ruleMergeError(kukit.E);
+;;; }
;;; }
+ // Store the values.
this.name = name;
+ // nameOverride is only overwritten if value exists.
+ if (nameOverride != null) {
+ this.nameOverride = nameOverride;
+ }
+ // Handle default action.
if (name == 'default') {
;;; if (this.type != null && this.type != 'D') {
;;; var msg = 'Error setting action to default on action [' + this.name;
@@ -601,7 +706,8 @@
this.merge = function(other) {
// Merge to the instance.
if (other.name != null) {
- this.setName(other.name);
+ // We also use nameOverride from the other.
+ this.setName(other.name, other.nameOverride);
}
if (other.type != null) {
this.setType(other.type);
@@ -615,6 +721,17 @@
}
};
+// The evaluation of string is handled specially
+// in case of some parameter names.
+//
+// kssSelector string "foo" evaluates as css("foo")
+// kssSubmitForm string "foo" evaluates as form("foo")
+//
+var _defaultStringHandling = {
+ 'kssSelector': 'css',
+ 'kssSubmitForm': 'form'
+};
+
this.makeActionOper = function(oper) {
// Fill the completed action parms, based on the node
// The kssXxx parms, reserved for the action, are
@@ -626,16 +743,30 @@
if (typeof(oper.defaultParameters) == 'undefined') {
oper.defaultParameters = {};
}
+ // Evaluate all parameters.
for (var key in this.parms) {
- var kssvalue = this.parms[key];
+ // Evaluate the value of the parameter.
+ var value = this.parms[key].evaluate(oper.node,
+ oper.defaultParameters);
+ // Final handling of special cases.
+ // This is needed in case we have a string, and we
+ // look up the provider we need from the _defaultStringHandling table.
+ var providerName = _defaultStringHandling[key];
+ if (providerName && typeof(value) == 'string') {
+ // Use the value provider. This means the string is
+ // a shortcut and this provider is applied.
+ var providerClass = kukit.pprovidersGlobalRegistry.get(providerName);
+ var provider = new providerClass();
+ // check is not needed now... we evaluate it right away
+ value = provider.eval([value], oper.node, oper.defaultParameters);
+ }
+ // Store it, depending if it's a kss or normal parameter.
if (key.match(/^kss/)) {
// kssXxx parms are separated to kssParms.
- kssParms[key] = kssvalue.evaluate(oper.node,
- oper.defaultParameters);
+ kssParms[key] = value;
} else {
// evaluate the method parms into parms
- parms[key] = kssvalue.evaluate(oper.node,
- oper.defaultParameters);
+ parms[key] = value;
}
}
var anOper = oper.clone({
@@ -660,7 +791,9 @@
} break;
case 'C': {
// Client action.
- oper.executeClientAction(this.name);
+ // Need to execute the real name,
+ // since aliasing is possible here.
+ oper.executeClientAction(this.getExecutingName());
} break;
case 'E': {
// Error action (= client action)
Modified: kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/selectorreg.js
==============================================================================
--- kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/selectorreg.js (original)
+++ kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/selectorreg.js Wed Jan 23 17:35:34 2008
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2005-2007
+* Copyright (c) 2005-2008
* Authors: KSS Project Contributors (see doc/CREDITS.txt)
*
* This program is free software; you can redistribute it and/or modify
@@ -84,7 +84,7 @@
};
};
-sr.pproviderSelRegistry.register('passnode', _PassnodePP);
+sr.pproviderSelRegistry.register('passnode', _PassnodePP, 'selection');
/*
@@ -115,7 +115,8 @@
this.mapping[name] = func;
// Also register the selector param provider
var pp = sr.makeAnyPP(name);
- sr.pproviderSelRegistry.register(name, pp);
+ // register them with returnType = 'nodes'
+ kukit.pprovidersGlobalRegistry.register(name, pp, 'selection');
};
this.get = function(name) {
@@ -184,4 +185,35 @@
return results;
});
+var _KssMarkedNodePP = function() {
+ this.check = function(args){
+;;; if (args.length != 2) {
+;;; throw new Error('kssMarkedNode selector method needs 2 arguments (keyType, key)');
+;;; }
+ };
+
+ this.eval = function(args, node, defaultParameters) {
+ var keyType = args[0];
+ var key = args[1];
+;;; if (keyType.match(/[ -]/)) {
+;;; kukit.E = 'keyType parameter in kssMarkedNode selection provider cannot contain';
+;;; kukit.E += ' dashes or spaces.';
+;;; throw new Error(kukit.E);
+;;; }
+;;; if (key.match(/[ -]/)) {
+;;; kukit.E = 'key parameter in kssMarkedNode provider cannot contain';
+;;; kukit.E += ' dashes or spaces.';
+;;; throw new Error(kukit.E);
+;;; }
+ var markup = kukit.dom.locateMarkup(node, true,
+ kukit.dom.getKssValue,
+ keyType, key);
+ // Just return the markup's node as a single selection result.
+ return [markup.node];
+ };
+
+};
+kukit.pprovidersGlobalRegistry.register('kssMarkedNode', _KssMarkedNodePP, 'selection');
+
}(); /// MODULE END
+
Modified: kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/serveraction.js
==============================================================================
--- kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/serveraction.js (original)
+++ kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/serveraction.js Wed Jan 23 17:35:34 2008
@@ -29,6 +29,26 @@
if (typeof(this.url) == 'undefined') {
this.url = name;
}
+
+ this.calculateAbsoluteURL = function(url) {
+ //
+ // If the url is an absolute path, it is used
+ //
+ // If the url is not an absolute path, it is put at the end of the context
+ // url.
+ //
+ // example: url='@theview/getName',
+ // context='http://your.site.com/portal/folder/object'
+ //
+ // result='http://your.site.com/portal/folder/object/@@theview/getName'
+ //
+ if (url.match(RegExp('/^https?:\/\//'))) {
+ return url;
+ } else {
+ var result = kukit.engine.baseUrl + '/' + url;
+ return result;
+ }
+ };
this.url = this.calculateAbsoluteURL(this.url);
this.notifyServer();
};
@@ -134,7 +154,7 @@
}
}
}
- }
+ };
};
this.processResult = function(domDoc) {
@@ -164,9 +184,86 @@
}
commandstags = kukit.dom.getNsTags(dom, 'commands');
if (commandstags.length != 1) {
- // no good
+ // no good, maybe better luck with it as html payload
dom = null;
}
+ }
+ // Check for html too, this enables setting the kss error command on the
+ // error response.
+ if (dom == null) {
+ // Read the header and load it as xml, if defined.
+ var payload = domDoc.getResponseHeader('X-KSSCOMMANDS');
+ if (payload) {
+ try {
+ dom = (new DOMParser()).parseFromString(payload, "text/xml");
+ } catch(e) {
+;;; kukit.E = 'Error parsing X-KSSCOMMANDS header.';
+ throw kukit.err.responseParsingError(kukit.E);
+ }
+ commandstags = kukit.dom.getNsTags(dom, 'commands');
+ if (commandstags.length != 1) {
+ // no good
+ dom = null;
+ }
+ } else {
+ // Ok. we have not found it either in the headers.
+ // Check if there was a parsing error in the xml,
+ // and log it as reported from the dom
+ // Opera <= 8.5 does not have the parseError attribute,
+ // so check for it first
+;;; dom = domDoc.responseXML;
+;;; kukit.E = 'Unknown server error (invalid KSS response, no error';
+;;; kukit.E += ' info received)';
+;;; if (dom && dom.parseError && (dom.parseError != 0)) {
+;;; kukit.E += ' : ' + Sarissa.getParseErrorText(dom);
+;;; }
+ throw kukit.err.responseParsingError(kukit.E);
+ }
+ }
+ if (dom == null) {
+ // this should not happen
+;;; kukit.E = 'Neither xml nor html payload.';
+ throw kukit.err.responseParsingError(msg);
+ }
+ // find the commands (atm we don't limit ourselves inside the commandstag)
+ var commands = kukit.dom.getNsTags(dom, 'command');
+ // Warning, if there is a valid response containing 0 commands.
+ if (commands.length == 0) {
+;;; kukit.log('No commands in kukit response');
+ return;
+ }
+ // One or more valid commands to parse
+ var command_processor = new kukit.cp.CommandProcessor();
+ command_processor.parseCommands(commands, domDoc);
+ kukit.engine.beginSetupEventsCollection();
+ command_processor.executeCommands(this.oper);
+ kukit.engine.finishSetupEventsCollection();
+ };
+
+ this.processError = function(errorcommand) {
+ var error_action = null;
+ if (this.oper.eventRule) {
+ var error_action = this.oper.eventRule.actions.getErrorActionFor(
+ this.oper.action);
+ }
+;;; var reason = '';
+;;; if (typeof(errorcommand) == 'string') {
+;;; // not a command, just a string
+;;; reason = ', client_reason="' + errorcommand + '" ';
+;;; } else if (typeof(errorcommand) != 'undefined') {
+;;; // a real error command, sent by the server
+;;; // as kukit payload.
+;;; // this way the server sends whatever message he wants as a parameter
+;;; // to the error command.
+;;; reason = ', server_reason="' + errorcommand.parms.message + '" ';
+;;; }
+ if (error_action) {
+;;; kukit.E = 'Request failed at url ' + this.oper.queueItem.url;
+;;; kukit.E += ', rid=' + this.oper.queueItem.rid + reason;
+;;; kukit.E += ', will be handled by action "' + error_action.name + '"';
+;;; kukit.logWarning(kukit.E);
+ // Individual error handler was defined. Execute it!
+ error_action.execute(this.oper);
} else {
// Ok. we have not found it either in the headers.
// Check if there was a parsing error in the xml,
Modified: kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/tokenizer.js
==============================================================================
--- kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/tokenizer.js (original)
+++ kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/kukit/tokenizer.js Wed Jan 23 17:35:34 2008
@@ -55,6 +55,12 @@
*/
tk._ParserBase = function() {
+// Provide an empty initialize. This allows
+// that the tokens will inherit it and are
+// not forced to implement it themselves.
+this.initialize = function() {
+};
+
this.emitAndReturn = function(token) {
// handle return to the next level
this.finished = true;
@@ -249,13 +255,29 @@
this.updateFinished();
}
this.endpos = cursor.pos;
+ // Call initialize with the original arguments
+ // (no need to call it earlier, as
+ this.initialize.apply(this, arguments);
// post processing
this.process();
//this.cursor = null;
};
- _class.prototype = new tk._ParserBase();
- f.prototype = new _class();
+ // Extend class's prototype, instead of overwriting
+ // it, since it may have its own methods!
+ // This means: the parser class we create
+ // double inherits from the specified parser class
+ // and the paeser base.
+ f.prototype = new tk._ParserBase();
+ var _prototype = new _class();
+ for (key in _prototype) {
+ // Set the method (or attribute) on the new prototype.
+ // This allows that a parser class may eventually
+ // override some methods of _ParserBase: for example,
+ // process is usually overwritten.
+ f.prototype[key] = _prototype[key];
+ }
+ // Set the symbol on the new class, too
f.prototype.symbol = symbol;
return f;
};
Modified: kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/tests/runtests.js
==============================================================================
--- kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/tests/runtests.js (original)
+++ kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/tests/runtests.js Wed Jan 23 17:35:34 2008
@@ -23,6 +23,7 @@
testsuite.registerTest(kukit.TokenizerTestCase);
testsuite.registerTest(kukit.KssParserTestCase);
testsuite.registerTest(kukit.KssParserSelectorsTestCase);
+ testsuite.registerTest(kukit.KssParserValueProvidersCheckTestCase);
testsuite.registerTest(kukit.KssParserSelectorTestCase);
testsuite.runSuite();
};
Modified: kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/tests/test_kssparser.js
==============================================================================
--- kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/tests/test_kssparser.js (original)
+++ kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/tests/test_kssparser.js Wed Jan 23 17:35:34 2008
@@ -69,89 +69,6 @@
kukit.KssParserTestCase = function() {
this.name = 'kukit.KssParserTestCase';
- this.testPropvalueInMethod = function() {
- // Parsing prop values (no methods allowed)
- var txt= "apple;";
- var cursor = new kukit.tk.Cursor(txt);
- var parser = new kukit.kssp.PropValueInMethod(cursor, null, true);
- this.assertEquals(parser.finished, true);
- this.assertEquals(parser.txt, 'apple');
-
- txt= "'a string';";
- cursor = new kukit.tk.Cursor(txt);
- parser = new kukit.kssp.PropValueInMethod(cursor, null, true);
- this.assertEquals(parser.finished, true);
- this.assertEquals(parser.txt, 'a string');
-
- txt= '"a string";';
- cursor = new kukit.tk.Cursor(txt);
- parser = new kukit.kssp.PropValueInMethod(cursor, null, true);
- this.assertEquals(parser.finished, true);
- this.assertEquals(parser.txt, 'a string');
-
- txt= '"a \\"string";';
- cursor = new kukit.tk.Cursor(txt);
- parser = new kukit.kssp.PropValueInMethod(cursor, null, true);
- this.assertEquals(parser.finished, true);
- this.assertEquals(parser.txt, 'a "string');
-
- txt= " /* valid */ 'a string' /* here*/ /*and*/ /*there*/;";
- cursor = new kukit.tk.Cursor(txt);
- parser = new kukit.kssp.PropValueInMethod(cursor, null, true);
- this.assertEquals(parser.finished, true);
- this.assertEquals(parser.txt, 'a string');
-
- txt= " in /* valid */ 'a string';";
- cursor = new kukit.tk.Cursor(txt);
- this.assertParsingError(kukit.kssp.PropValueInMethod, cursor, null, true, 'Wrong value : unallowed characters [in] before a string.');
-
- txt= " 'a string' trashy;";
- cursor = new kukit.tk.Cursor(txt);
- this.assertParsingError(kukit.kssp.PropValueInMethod, cursor, null, true, 'Wrong value : unallowed characters after the property.');
-
- txt= " 'a string' trashy \"trishy\";";
- cursor = new kukit.tk.Cursor(txt);
- this.assertParsingError(kukit.kssp.PropValueInMethod, cursor, null, true, 'Wrong value : unallowed characters after the property.');
-
- // multiword not ok
- txt= "b c";
- cursor = new kukit.tk.Cursor(txt);
- this.assertParsingError(kukit.kssp.PropValueInMethod, cursor, null, true,
- 'Wrong value : [b c] cannot have spaces.', 5);
-
- txt= " apples and oranges ;";
- cursor = new kukit.tk.Cursor(txt);
- this.assertParsingError(kukit.kssp.PropValueInMethod, cursor, null, true,
- 'Wrong value : [apples and oranges] cannot have spaces.', 25);
-
- txt= " /* comments; */ apples and /* more comments and*/ oranges ;";
- cursor = new kukit.tk.Cursor(txt);
- this.assertParsingError(kukit.kssp.PropValueInMethod, cursor, null, true,
- //'Wrong value : [/* comments; */ apples and /* more comments and*/ oranges ;] cannot have spaces.', 62);
- 'Wrong value : [apples and oranges] cannot have spaces.', 62);
-
- // in string, multiword ok even in method
- txt= "'b c' ";
- cursor = new kukit.tk.Cursor(txt);
- parser = new kukit.kssp.PropValueInMethod(cursor, null, true);
- this.assertEquals(parser.finished, true);
- this.assertEquals(parser.txt, 'b c');
- this.assertEquals(parser.parms, null);
-
- // Not ok
- txt= "a'b c'";
- cursor = new kukit.tk.Cursor(txt);
- this.assertParsingError(kukit.kssp.PropValueInMethod, cursor, null, true,
- 'Wrong value : unallowed characters [a] before a string', 6);
-
- // Not ok
- txt= "'a''b c'";
- cursor = new kukit.tk.Cursor(txt);
- this.assertParsingError(kukit.kssp.PropValueInMethod, cursor, null, true,
- 'Wrong value : unallowed characters after the property.', 6);
-
- };
-
this.testPropValue = function() {
// Parsing property values
@@ -162,28 +79,27 @@
this.assertEquals(parser.value.isMethod, false);
this.assertEquals(parser.value.txt, 'b');
- // multiword ok
+ // XXX multiword in PropValue was supported by the token
+ // previously, but it really was never used.
+
+ // multiword is not allowed.
txt= "b c";
cursor = new kukit.tk.Cursor(txt);
- parser = new kukit.kssp.PropValue(cursor, null, true);
- this.assertEquals(parser.finished, true);
- this.assertEquals(parser.value.isMethod, false);
- this.assertEquals(parser.value.txt, 'b c');
+ this.assertParsingError(kukit.kssp.PropValue, cursor, null, true,
+ 'Wrong value : unallowed characters [c] after the argument.')
+ // multiword is not allowed.
txt= " apples and oranges ;";
cursor = new kukit.tk.Cursor(txt);
- parser = new kukit.kssp.PropValue(cursor, null, true);
- this.assertEquals(parser.finished, true);
- this.assertEquals(parser.value.isMethod, false);
- this.assertEquals(parser.value.txt, 'apples and oranges');
+ this.assertParsingError(kukit.kssp.PropValue, cursor, null, true,
+ 'Wrong value : unallowed characters [and] after the argument.')
+ // multiword is not allowed.
txt= " /* comments; */ apples and /* more comments and*/ oranges ;";
cursor = new kukit.tk.Cursor(txt);
- parser = new kukit.kssp.PropValue(cursor, null, true);
- this.assertEquals(parser.finished, true);
- this.assertEquals(parser.value.isMethod, false);
- this.assertEquals(parser.value.txt, 'apples and oranges');
-
+ this.assertParsingError(kukit.kssp.PropValue, cursor, null, true,
+ 'Wrong value : unallowed characters [and] after the argument.')
+
// params ok
txt= "formVar(x, y) ";
cursor = new kukit.tk.Cursor(txt);
@@ -214,19 +130,205 @@
txt= " a formVar(x, y)";
cursor = new kukit.tk.Cursor(txt);
this.assertParsingError(kukit.kssp.PropValue, cursor, null, true,
- 'Wrong value : method name [a formVar] cannot have spaces.', 16);
+ 'Wrong value : unallowed characters [formVar] after the argument.')
txt= " 'formVar'(x, y)";
cursor = new kukit.tk.Cursor(txt);
this.assertParsingError(kukit.kssp.PropValue, cursor, null, true,
- 'Wrong value : unallowed characters after the property', 16);
+ 'Wrong value : unallowed characters [(] after the argument.')
txt= "formVar(x, y) xxx";
cursor = new kukit.tk.Cursor(txt);
this.assertParsingError(kukit.kssp.PropValue, cursor, null, true,
- 'Wrong value : unallowed characters after the property', 17);
+ 'Wrong value : unallowed characters [xxx] after the argument.')
};
-
+
+ this.testPropValueNoParam = function() {
+ // no parameters ok in a provider.
+ var txt= "formVar()";
+ var cursor = new kukit.tk.Cursor(txt);
+ var parser = new kukit.kssp.PropValue(cursor, null, true);
+ this.assertEquals(parser.finished, true);
+ this.assertEquals(parser.value.isMethod, true);
+ this.assertEquals(parser.value.methodName, 'formVar');
+ this.assertListEquals(parser.value.args, []);
+ };
+
+ this.testPropValueNoMethodName = function() {
+ var txt= " (x, y)";
+ var cursor = new kukit.tk.Cursor(txt);
+ this.assertParsingError(kukit.kssp.PropValue, cursor, null, true,
+ 'Wrong value : empty method name.');
+ };
+
+ this.testMultiPropValueSingleWord = function() {
+ // Multi prop value with single word
+ var txt= "b";
+ var cursor = new kukit.tk.Cursor(txt);
+ var parser = new kukit.kssp.MultiPropValue(cursor, null, true);
+ this.assertEquals(parser.finished, true);
+ this.assertEquals(parser.values.length, 1);
+ this.assertEquals(parser.values[0].isMethod, false);
+ this.assertEquals(parser.values[0].txt, 'b');
+ };
+
+ this.testMultiPropValueMultiWord = function() {
+ // Multi prop value with multi word.
+ var txt= "b c";
+ var cursor = new kukit.tk.Cursor(txt);
+ var parser = new kukit.kssp.MultiPropValue(cursor, null, true);
+ this.assertEquals(parser.finished, true);
+ this.assertEquals(parser.values.length, 2);
+ this.assertEquals(parser.values[0].isMethod, false);
+ this.assertEquals(parser.values[0].txt, 'b');
+ this.assertEquals(parser.values[1].isMethod, false);
+ this.assertEquals(parser.values[1].txt, 'c');
+ };
+
+ this.testMultiPropValueMultiWord2 = function() {
+ // Multi prop value with multi word.
+ var txt= " apples and oranges ;";
+ var cursor = new kukit.tk.Cursor(txt);
+ var parser = new kukit.kssp.MultiPropValue(cursor, null, true);
+ this.assertEquals(parser.finished, true);
+ this.assertEquals(parser.values.length, 3);
+ this.assertEquals(parser.values[0].isMethod, false);
+ this.assertEquals(parser.values[0].txt, 'apples');
+ this.assertEquals(parser.values[1].isMethod, false);
+ this.assertEquals(parser.values[1].txt, 'and');
+ this.assertEquals(parser.values[2].isMethod, false);
+ this.assertEquals(parser.values[2].txt, 'oranges');
+ };
+
+ this.testMultiPropValueMultiWord2 = function() {
+ // Multi prop value with multi word and comments.
+ var txt= " /* comments; */ apples and /* more comments and*/ oranges ;";
+ var cursor = new kukit.tk.Cursor(txt);
+ var parser = new kukit.kssp.MultiPropValue(cursor, null, true);
+ this.assertEquals(parser.finished, true);
+ this.assertEquals(parser.values.length, 3);
+ this.assertEquals(parser.values[0].isMethod, false);
+ this.assertEquals(parser.values[0].txt, 'apples');
+ this.assertEquals(parser.values[1].isMethod, false);
+ this.assertEquals(parser.values[1].txt, 'and');
+ this.assertEquals(parser.values[2].isMethod, false);
+ this.assertEquals(parser.values[2].txt, 'oranges');
+ };
+
+
+ this.testMultiPropValueStringAndWord = function() {
+ // Multi prop value with string and word.
+ var txt= "'apples' and oranges;";
+ var cursor = new kukit.tk.Cursor(txt);
+ var parser = new kukit.kssp.MultiPropValue(cursor, null, true);
+ this.assertEquals(parser.finished, true);
+ this.assertEquals(parser.values.length, 3);
+ this.assertEquals(parser.values[0].isMethod, false);
+ this.assertEquals(parser.values[0].txt, 'apples');
+ this.assertEquals(parser.values[1].isMethod, false);
+ this.assertEquals(parser.values[1].txt, 'and');
+ this.assertEquals(parser.values[2].isMethod, false);
+ this.assertEquals(parser.values[2].txt, 'oranges');
+ };
+
+ this.testMultiPropValueWordAndString = function() {
+ // Multi prop value with string and word.
+ var txt= "'apples' and oranges;";
+ var cursor = new kukit.tk.Cursor(txt);
+ var parser = new kukit.kssp.MultiPropValue(cursor, null, true);
+ this.assertEquals(parser.finished, true);
+ this.assertEquals(parser.values.length, 3);
+ this.assertEquals(parser.values[0].isMethod, false);
+ this.assertEquals(parser.values[0].txt, 'apples');
+ this.assertEquals(parser.values[1].isMethod, false);
+ this.assertEquals(parser.values[1].txt, 'and');
+ this.assertEquals(parser.values[2].isMethod, false);
+ this.assertEquals(parser.values[2].txt, 'oranges');
+ };
+
+ this.testMultiPropValueWordAndProvider = function() {
+ // Multi prop value with word and provider and word.
+ var txt= "apples formVar(x, y) oranges;";
+ var cursor = new kukit.tk.Cursor(txt);
+ var parser = new kukit.kssp.MultiPropValue(cursor, null, true);
+ this.assertEquals(parser.finished, true);
+ this.assertEquals(parser.values.length, 3);
+ this.assertEquals(parser.values[0].isMethod, false);
+ this.assertEquals(parser.values[0].txt, 'apples');
+ this.assertEquals(parser.values[1].isMethod, true);
+ this.assertEquals(parser.values[1].methodName, 'formVar');
+ this.assertListEquals(parser.values[1].args, ['x', 'y']);
+ this.assertEquals(parser.values[2].isMethod, false);
+ this.assertEquals(parser.values[2].txt, 'oranges');
+ };
+
+ this.testMultiPropValueProviderAndWord = function() {
+ // Multi prop value with provider and word.
+ var txt= "formVar(x, y) and oranges;";
+ var cursor = new kukit.tk.Cursor(txt);
+ var parser = new kukit.kssp.MultiPropValue(cursor, null, true);
+ this.assertEquals(parser.finished, true);
+ this.assertEquals(parser.values.length, 3);
+ this.assertEquals(parser.values[0].isMethod, true);
+ this.assertEquals(parser.values[0].methodName, 'formVar');
+ this.assertListEquals(parser.values[0].args, ['x', 'y']);
+ this.assertEquals(parser.values[1].isMethod, false);
+ this.assertEquals(parser.values[1].txt, 'and');
+ this.assertEquals(parser.values[2].isMethod, false);
+ this.assertEquals(parser.values[2].txt, 'oranges');
+ };
+
+ this.testMultiPropValueMethodArgsWithSpace = function() {
+ // Multi prop value with space after the provider name.
+ var txt= "formVar (x, y) and oranges;";
+ var cursor = new kukit.tk.Cursor(txt);
+ var parser = new kukit.kssp.MultiPropValue(cursor, null, true);
+ this.assertEquals(parser.finished, true);
+ this.assertEquals(parser.values.length, 3);
+ this.assertEquals(parser.values[0].isMethod, true);
+ this.assertEquals(parser.values[0].methodName, 'formVar');
+ this.assertListEquals(parser.values[0].args, ['x', 'y']);
+ this.assertEquals(parser.values[1].isMethod, false);
+ this.assertEquals(parser.values[1].txt, 'and');
+ this.assertEquals(parser.values[2].isMethod, false);
+ this.assertEquals(parser.values[2].txt, 'oranges');
+ };
+
+ this.testMultiPropValueManyProviders = function() {
+ // Multi prop value with many providers
+ var txt= "formVar(x, y) kssAttr(foo, true) formVar(a, b);";
+ var cursor = new kukit.tk.Cursor(txt);
+ var parser = new kukit.kssp.MultiPropValue(cursor, null, true);
+ this.assertEquals(parser.finished, true);
+ this.assertEquals(parser.values.length, 3);
+ this.assertEquals(parser.values[0].isMethod, true);
+ this.assertEquals(parser.values[0].methodName, 'formVar');
+ this.assertListEquals(parser.values[0].args, ['x', 'y']);
+ this.assertEquals(parser.values[1].isMethod, true);
+ this.assertEquals(parser.values[1].methodName, 'kssAttr');
+ this.assertListEquals(parser.values[1].args, ['foo', 'true']);
+ this.assertEquals(parser.values[2].isMethod, true);
+ this.assertEquals(parser.values[2].methodName, 'formVar');
+ this.assertListEquals(parser.values[2].args, ['a', 'b']);
+ };
+
+ this.testMultiPropValueStringAndManyProviders = function() {
+ // Multi prop value with a string and many providers
+ var txt= "blah kssAttr(foo, true) formVar(a, b);";
+ var cursor = new kukit.tk.Cursor(txt);
+ var parser = new kukit.kssp.MultiPropValue(cursor, null, true);
+ this.assertEquals(parser.finished, true);
+ this.assertEquals(parser.values.length, 3);
+ this.assertEquals(parser.values[0].isMethod, false);
+ this.assertEquals(parser.values[0].txt, 'blah');
+ this.assertEquals(parser.values[1].isMethod, true);
+ this.assertEquals(parser.values[1].methodName, 'kssAttr');
+ this.assertListEquals(parser.values[1].args, ['foo', 'true']);
+ this.assertEquals(parser.values[2].isMethod, true);
+ this.assertEquals(parser.values[2].methodName, 'formVar');
+ this.assertListEquals(parser.values[2].args, ['a', 'b']);
+ };
+
this.testEventValueSimple = function() {
// Parsing event value
var txt= "b";
@@ -353,6 +455,15 @@
};
+ this.testMethodArgsNoParam = function() {
+ // Parsing method args with no parameters
+ txt= "()";
+ cursor = new kukit.tk.Cursor(txt);
+ parser = new kukit.kssp.MethodArgs(cursor, kukit.kssp.openParent, true);
+ this.assertEquals(parser.finished, true);
+ this.assertListEquals(parser.args, []);
+ };
+
this.testMethodArgsRecursive = function() {
var txt= "(a, b(c, d))";
var cursor = new kukit.tk.Cursor(txt);
@@ -813,6 +924,549 @@
kukit.KssParserTestCase.prototype = new kukit.KssParserTestCaseBase;
+kukit.KssParserValueProvidersCheckTestCase = function() {
+ this.name = 'kukit.KssParserValueProvidersCheckTestCase';
+ // Different tests to see if the syntax type check of
+ // the value providers is working correctly.
+ // At the moment we have the following return value types:
+ //
+ // string: almost all normal providers return string
+ // selection: a selector provider returns a list of nodes
+ // formquery: a form provider returns an ordered list
+ // of key-value pairs to be marshalled
+ // url: the return type of the url() provider
+ //
+ // We do not check the actual evaluation here, as we
+ // have no DOM at hand.
+ //
+ // We also check how these providers can be combined
+ // on one line.
+ //
+ // This testcase can run in DEVELOPMENT MODE ONLY,
+ // (because the checks are ignored in production mode)
+ // and all tests will be skipped
+ // and pass GREEN in production mode.
+
+ this.testNormalProviderAcceptsString = function() {
+ // normal providers does accept string
+ //
+ // This test can only run in development mode, pass otherwise.
+ if (! kukit.isDevelMode) {return;}
+ //
+ var txt= "nodeAttr('id')";
+ var cursor = new kukit.tk.Cursor(txt);
+ var parser = new kukit.kssp.PropValue(cursor, null, true);
+ var value = parser.value;
+ value.check();
+ };
+
+ this.testNormalProviderRejectsSelectionAsParameter = function() {
+ // normal providers does not accept selection
+ //
+ // This test can only run in development mode, pass otherwise.
+ if (! kukit.isDevelMode) {return;}
+ //
+ var txt= "nodeAttr(htmlid('id'))";
+ var cursor = new kukit.tk.Cursor(txt);
+ var parser = new kukit.kssp.PropValue(cursor, null, true);
+ var value = parser.value;
+ this.assertThrows(function() {
+ value.check();
+ },
+ Error);
+ };
+
+ this.testNormalProviderRejectsSelectionFullRule = function() {
+ // normal providers do not accept selection
+ // full rule
+ //
+ // This test can only run in development mode, pass otherwise.
+ if (! kukit.isDevelMode) {return;}
+ //
+ var txt= "#id:click {\n"
+ + " action-client: log;\n"
+ + " log-message: nodeAttr(htmlid('id'));\n"
+ + "}\n"
+ var cursor = new kukit.tk.Cursor(txt);
+ this.assertParsingError(kukit.kssp.Document, cursor, null, true,
+ // XXX This error message will be fixed in service-layer branch
+ // XXX This will also fix running from IE, currently broken at error assert.
+ 'Error in value for action parameter [message] : Error: Expected string value and got [selection] in argument #[1] of provider [nodeAttr].., at row 1, column 11');
+ };
+
+ this.testNormalProviderRejectsFormData = function() {
+ // normal providers do not accept form query
+ //
+ // This test can only run in development mode, pass otherwise.
+ if (! kukit.isDevelMode) {return;}
+ //
+ var txt= "nodeAttr(form('name'))";
+ var cursor = new kukit.tk.Cursor(txt);
+ var parser = new kukit.kssp.PropValue(cursor, null, true);
+ var value = parser.value;
+ this.assertThrows(function() {
+ value.check();
+ },
+ Error);
+ };
+
+ this.testNormalProviderRejectsFormDataFullRule = function() {
+ // normal providers do not accept form query
+ // full rule
+ //
+ // This test can only run in development mode, pass otherwise.
+ if (! kukit.isDevelMode) {return;}
+ //
+ var txt= "#id:click {\n"
+ + " action-client: log;\n"
+ + " log-message: nodeAttr(form('name'));\n"
+ + "}\n"
+ var cursor = new kukit.tk.Cursor(txt);
+ this.assertParsingError(kukit.kssp.Document, cursor, null, true,
+ // XXX This error message will be fixed in service-layer branch
+ // XXX This will also fix running from IE, currently broken at error assert.
+ 'Error in value for action parameter [message] : Error: Expected string value and got [formquery] in argument #[1] of provider [nodeAttr].., at row 1, column 11');
+ };
+
+ this.testNormalParameterRejectsSelectorInItself = function() {
+ // normal parameters do not accept selector (in itself)
+ //
+ // This test can only run in development mode, pass otherwise.
+ if (! kukit.isDevelMode) {return;}
+ //
+ var txt= "#id:click {\n"
+ + " action-client: log;\n"
+ + " log-message: htmlid('id');\n"
+ + "}\n"
+ var cursor = new kukit.tk.Cursor(txt);
+ this.assertParsingError(kukit.kssp.Document, cursor, null, true,
+ // XXX This error message will be fixed in service-layer branch
+ // XXX This will also fix running from IE, currently broken at error assert.
+ 'Missing [string] value in the action parameter [message]., at row 1, column 11');
+ };
+
+ this.testNormalParameterRejectsFormData = function() {
+ // normal parameters do not accept form query
+ //
+ // This test can only run in development mode, pass otherwise.
+ if (! kukit.isDevelMode) {return;}
+ //
+ var txt= "#id:click {\n"
+ + " action-client: log;\n"
+ + " log-message: form('name');\n"
+ + "}\n"
+ var cursor = new kukit.tk.Cursor(txt);
+ this.assertParsingError(kukit.kssp.Document, cursor, null, true,
+ // XXX This error message will be fixed in service-layer branch
+ // XXX This will also fix running from IE, currently broken at error assert.
+ 'Provider result type [formquery] not allowed in the action parameter [message]., at row 1, column 1');
+ };
+
+ this.testKssSelectorAcceptsSelector = function() {
+ // kssSelector accepts selector
+ //
+ // This test can only run in development mode, pass otherwise.
+ if (! kukit.isDevelMode) {return;}
+ //
+ var txt= "#id:click {\n"
+ + " action-client: setAttribute;\n"
+ + " setAttribute-kssSelector: htmlid('id');\n"
+ + " setAttribute-name: name;\n"
+ + " setAttribute-value: value;\n"
+ + "}\n"
+ var cursor = new kukit.tk.Cursor(txt);
+ var parser = new kukit.kssp.Document(cursor, null, true);
+ this.assertEquals(parser.finished, true);
+ };
+
+ this.testKssSelectorAcceptsString = function() {
+ // kssSelector accepts string
+ // (it will evaluate as css(xxx), but we can't check that without a dom)
+ //
+ // This test can only run in development mode, pass otherwise.
+ if (! kukit.isDevelMode) {return;}
+ //
+ var txt= "#id:click {\n"
+ + " action-client: setAttribute;\n"
+ + " setAttribute-kssSelector: htmlid('id');\n"
+ + " setAttribute-name: name;\n"
+ + " setAttribute-value: value;\n"
+ + "}\n"
+ var cursor = new kukit.tk.Cursor(txt);
+ var parser = new kukit.kssp.Document(cursor, null, true);
+ this.assertEquals(parser.finished, true);
+ };
+
+ this.testKssSelectorRejectsFormData = function() {
+ // kssSelector rejects form query
+ //
+ // This test can only run in development mode, pass otherwise.
+ if (! kukit.isDevelMode) {return;}
+ //
+ var txt= "#id:click {\n"
+ + " action-client: setAttribute;\n"
+ + " setAttribute-kssSelector: form('name');\n"
+ + " setAttribute-name: name;\n"
+ + " setAttribute-value: value;\n"
+ + "}\n"
+ var cursor = new kukit.tk.Cursor(txt);
+ this.assertParsingError(kukit.kssp.Document, cursor, null, true,
+ // XXX This error message will be fixed in service-layer branch
+ // XXX This will also fix running from IE, currently broken at error assert.
+ 'Provider result type [formquery] not allowed in the kss action parameter [kssSelector]., at row 1, column 11');
+ };
+
+ this.testKssSubmitFormAcceptsFormData = function() {
+ // kssSubmitForm accepts form query
+ //
+ // This test can only run in development mode, pass otherwise.
+ if (! kukit.isDevelMode) {return;}
+ //
+ var txt= "#id:click {\n"
+ + " action-server: doIt;\n"
+ + " doIt-kssSubmitForm: form('name');\n"
+ + "}\n"
+ var cursor = new kukit.tk.Cursor(txt);
+ var parser = new kukit.kssp.Document(cursor, null, true);
+ this.assertEquals(parser.finished, true);
+ };
+
+ this.testKssSubmitFormAcceptsString = function() {
+ // kssSubmitForm accepts string
+ // (it will evaluate as form(xxx), but we can't check that without a dom)
+ //
+ // This test can only run in development mode, pass otherwise.
+ if (! kukit.isDevelMode) {return;}
+ //
+ var txt= "#id:click {\n"
+ + " action-server: doIt;\n"
+ + " doIt-kssSubmitForm: 'name';\n"
+ + "}\n"
+ var cursor = new kukit.tk.Cursor(txt);
+ var parser = new kukit.kssp.Document(cursor, null, true);
+ this.assertEquals(parser.finished, true);
+ };
+
+ this.testKssSubmitFormRejectsSelection = function() {
+ // kssSubmitForm rejects selection
+ //
+ // This test can only run in development mode, pass otherwise.
+ if (! kukit.isDevelMode) {return;}
+ //
+ var txt= "#id:click {\n"
+ + " action-server: doIt;\n"
+ + " doIt-kssSubmitForm: htmlid('id');\n"
+ + "}\n"
+ var cursor = new kukit.tk.Cursor(txt);
+ this.assertParsingError(kukit.kssp.Document, cursor, null, true,
+ // XXX This error message will be fixed in service-layer branch
+ // XXX This will also fix running from IE, currently broken at error assert.
+ 'Provider result type [selection] not allowed in the kss action parameter [kssSubmitForm]., at row 1, column 11');
+ };
+
+ this.testCombinedClientAction = function() {
+ // Client action accepts a list of combined providers.
+ //
+ // This test can only run in development mode, pass otherwise.
+ if (! kukit.isDevelMode) {return;}
+ //
+ var txt= "#id:click {\n"
+ + " action-client: htmlid(id) doIt;\n"
+ + "}\n"
+ var cursor = new kukit.tk.Cursor(txt);
+ var parser = new kukit.kssp.Document(cursor, null, true);
+ this.assertEquals(parser.finished, true);
+ };
+
+ this.testCombinedClientActionRejectsFormData = function() {
+ // Client action rejects form query.
+ //
+ // This test can only run in development mode, pass otherwise.
+ if (! kukit.isDevelMode) {return;}
+ //
+ var txt= "#id:click {\n"
+ + " action-client: htmlid(id) doIt form();\n"
+ + "}\n"
+ var cursor = new kukit.tk.Cursor(txt);
+ this.assertParsingError(kukit.kssp.Document, cursor, null, true,
+ // XXX This error message will be fixed in service-layer branch
+ // XXX This will also fix running from IE, currently broken at error assert.
+ 'Error in value for action definition [action-client] : Error: form method needs 1 arguments (formname)., at row 1, column 11');
+ };
+
+ this.testCombinedServerAction = function() {
+ // Server action accepts a list of combined providers.
+ //
+ // This test can only run in development mode, pass otherwise.
+ if (! kukit.isDevelMode) {return;}
+ //
+ var txt= "#id:click {\n"
+ + " action-server: doIt currentForm();\n"
+ + "}\n"
+ var cursor = new kukit.tk.Cursor(txt);
+ var parser = new kukit.kssp.Document(cursor, null, true);
+ this.assertEquals(parser.finished, true);
+ };
+
+ this.testCombinedServerActionRejectsSelector = function() {
+ // Server action rejects a selection provider.
+ //
+ // This test can only run in development mode, pass otherwise.
+ if (! kukit.isDevelMode) {return;}
+ //
+ var txt= "#id:click {\n"
+ + " action-server: doIt currentForm() htmlid(id);\n"
+ + "}\n"
+ var cursor = new kukit.tk.Cursor(txt);
+ this.assertParsingError(kukit.kssp.Document, cursor, null, true,
+ // XXX This error message will be fixed in service-layer branch
+ // XXX This will also fix running from IE, currently broken at error assert.
+ 'Provider result type [selection] not allowed in the action definition [action-server]., at row 1, column 11');
+ };
+
+ this.testCombinedServerActionAcceptsStringAndUrl = function() {
+ // Server action accepts a string and an url.
+ //
+ // This test can only run in development mode, pass otherwise.
+ if (! kukit.isDevelMode) {return;}
+ //
+ var txt= "#id:click {\n"
+ + " action-server: doIt url('http://foo.bar');\n"
+ + "}\n"
+ var cursor = new kukit.tk.Cursor(txt);
+ var parser = new kukit.kssp.Document(cursor, null, true);
+ this.assertEquals(parser.finished, true);
+ };
+
+ this.testCombinedServerActionAcceptsUrlAndString = function() {
+ // Server action accepts a string and an url.
+ //
+ // This test can only run in development mode, pass otherwise.
+ if (! kukit.isDevelMode) {return;}
+ //
+ var txt= "#id:click {\n"
+ + " action-server: doIt url('http://foo.bar');\n"
+ + "}\n"
+ var cursor = new kukit.tk.Cursor(txt);
+ var parser = new kukit.kssp.Document(cursor, null, true);
+ this.assertEquals(parser.finished, true);
+ };
+
+ this.testCombinedServerActionAcceptsStringAndFormAndUrl = function() {
+ // Server action accepts string, form, and url providers together.
+ //
+ // This test can only run in development mode, pass otherwise.
+ if (! kukit.isDevelMode) {return;}
+ //
+ var txt= "#id:click {\n"
+ + " action-server: doIt currentForm() url('http://foo.bar');\n"
+ + "}\n"
+ var cursor = new kukit.tk.Cursor(txt);
+ var parser = new kukit.kssp.Document(cursor, null, true);
+ this.assertEquals(parser.finished, true);
+ };
+
+ this.testCombinedServerActionRejectsUrlInItself = function() {
+ // Server action rejects url() in itself.
+ // It should have a string in any case.
+ //
+ // This test can only run in development mode, pass otherwise.
+ if (! kukit.isDevelMode) {return;}
+ //
+ var txt= "#id:click {\n"
+ + " action-server: url('http://foo.bar');\n"
+ + "}\n"
+ var cursor = new kukit.tk.Cursor(txt);
+ this.assertParsingError(kukit.kssp.Document, cursor, null, true,
+ // XXX This error message will be fixed in service-layer branch
+ // XXX This will also fix running from IE, currently broken at error assert.
+ 'Missing [string] value in the action definition [action-server]., at row 1, column 11');
+ };
+
+ this.testCombinedServerActionRejectsTwoStrings = function() {
+ // Server action rejects two strings.
+ //
+ // This test can only run in development mode, pass otherwise.
+ if (! kukit.isDevelMode) {return;}
+ //
+ var txt= "#id:click {\n"
+ + " action-server: foo 'bar';\n"
+ + "}\n"
+ var cursor = new kukit.tk.Cursor(txt);
+ this.assertParsingError(kukit.kssp.Document, cursor, null, true,
+ // XXX This error message will be fixed in service-layer branch
+ // XXX This will also fix running from IE, currently broken at error assert.
+ 'Only one [string] value is allowed in the action definition [action-server]., at row 1, column 11');
+ };
+
+
+ this.testCombinedServerActionRejectsUrlWithoutParms = function() {
+ // Server action rejects url() if url has no parameter.
+ // It should have a string in any case.
+ //
+ // This test can only run in development mode, pass otherwise.
+ if (! kukit.isDevelMode) {return;}
+ //
+ var txt= "#id:click {\n"
+ + " action-server: doIt url();\n"
+ + "}\n"
+ var cursor = new kukit.tk.Cursor(txt);
+ this.assertParsingError(kukit.kssp.Document, cursor, null, true,
+ // XXX This error message will be fixed in service-layer branch
+ // XXX This will also fix running from IE, currently broken at error assert.
+ 'Error in value for action definition [action-server] : Error: url() needs 1 argument., at row 1, column 11');
+ };
+
+ this.testServerActionRejectsValueProviderForString = function() {
+ // Server action must have a string, no value provider is allowed here.
+ //
+ // This test can only run in development mode, pass otherwise.
+ if (! kukit.isDevelMode) {return;}
+ //
+ var txt= "#id:click {\n"
+ + " action-server: kssAttr(blah);\n"
+ + "}\n"
+ var cursor = new kukit.tk.Cursor(txt);
+ this.assertParsingError(kukit.kssp.Document, cursor, null, true,
+ // XXX This error message will be fixed in service-layer branch
+ // XXX This will also fix running from IE, currently broken at error assert.
+ 'Wrong value for key [action-server] : value providers are not allowed for action-<QUALIFIER> keys., at row 1, column 11');
+ };
+
+ this.testNormalProviderAcceptsValueAndSelector = function() {
+ // normal parameters accepts value and selector
+ //
+ // This test can only run in development mode, pass otherwise.
+ if (! kukit.isDevelMode) {return;}
+ //
+ var txt= "#id:click {\n"
+ + " action-client: log;\n"
+ + " log-message: kssAttr(blah) htmlid('id');\n"
+ + "}\n"
+ var cursor = new kukit.tk.Cursor(txt);
+ var parser = new kukit.kssp.Document(cursor, null, true);
+ this.assertEquals(parser.finished, true);
+ };
+
+ this.testNormalProviderAcceptsSelectorAndValue = function() {
+ // normal parameters accepts value and selector
+ //
+ // This test can only run in development mode, pass otherwise.
+ if (! kukit.isDevelMode) {return;}
+ //
+ var txt= "#id:click {\n"
+ + " action-client: log;\n"
+ + " log-message: htmlid('id') kssAttr(blah);\n"
+ + "}\n"
+ var cursor = new kukit.tk.Cursor(txt);
+ var parser = new kukit.kssp.Document(cursor, null, true);
+ this.assertEquals(parser.finished, true);
+ };
+
+ this.testNormalProviderAcceptsStringAndSelector = function() {
+ // normal parameters accepts string and selector
+ // although this does not make much sense... but it's allowed.
+ //
+ // This test can only run in development mode, pass otherwise.
+ if (! kukit.isDevelMode) {return;}
+ //
+ var txt= "#id:click {\n"
+ + " action-client: log;\n"
+ + " log-message: 'message' htmlid('id');\n"
+ + "}\n"
+ var cursor = new kukit.tk.Cursor(txt);
+ var parser = new kukit.kssp.Document(cursor, null, true);
+ this.assertEquals(parser.finished, true);
+ };
+
+ this.testNormalProviderAcceptsSelectorAndString = function() {
+ // normal parameters accepts selector and string
+ // although this does not make much sense... but it's allowed.
+ //
+ // This test can only run in development mode, pass otherwise.
+ if (! kukit.isDevelMode) {return;}
+ //
+ var txt= "#id:click {\n"
+ + " action-client: log;\n"
+ + " log-message: htmlid('id') 'message';\n"
+ + "}\n"
+ var cursor = new kukit.tk.Cursor(txt);
+ var parser = new kukit.kssp.Document(cursor, null, true);
+ this.assertEquals(parser.finished, true);
+ };
+
+ this.testNormalProviderAcceptsValueAndSelector = function() {
+ // normal parameters accepts value and selector
+ //
+ // This test can only run in development mode, pass otherwise.
+ if (! kukit.isDevelMode) {return;}
+ //
+ var txt= "#id:click {\n"
+ + " action-client: log;\n"
+ + " log-message: kssAttr(blah) htmlid('id');\n"
+ + "}\n"
+ var cursor = new kukit.tk.Cursor(txt);
+ var parser = new kukit.kssp.Document(cursor, null, true);
+ this.assertEquals(parser.finished, true);
+ };
+
+ this.testAliasedClientAction = function() {
+ // Client action can be aliased.
+ //
+ // This test can only run in development mode, pass otherwise.
+ // Note that merging the rules is not really tested from here,
+ // as we don't have DOM. So we can't really see if the alias
+ // is working, only that it is parsed well.
+ if (! kukit.isDevelMode) {return;}
+ //
+ var txt= "#id:click {\n"
+ + " action-client: doIt alias(doAlias);\n"
+ + " doAlias-foo: bar;\n"
+ + "}\n"
+ var cursor = new kukit.tk.Cursor(txt);
+ var parser = new kukit.kssp.Document(cursor, null, true);
+ this.assertEquals(parser.finished, true);
+ };
+
+ this.testServerActionRejectsAlias = function() {
+ // Server action rejects alias().
+ //
+ // This test can only run in development mode, pass otherwise.
+ if (! kukit.isDevelMode) {return;}
+ //
+ var txt= "#id:click {\n"
+ + " action-server: doIt alias(doAlias);\n"
+ + " doAlias-foo: bar;\n"
+ + "}\n"
+ var cursor = new kukit.tk.Cursor(txt);
+ this.assertParsingError(kukit.kssp.Document, cursor, null, true,
+ // XXX This error message will be fixed in service-layer branch
+ // XXX This will also fix running from IE, currently broken at error assert.
+ 'Provider result type [alias] not allowed in the action definition [action-server]., at row 1, column 11');
+ };
+
+ this.testNormalParameterRejectsAlias = function() {
+ // normal parameters do not accept alias.
+ //
+ // This test can only run in development mode, pass otherwise.
+ if (! kukit.isDevelMode) {return;}
+ //
+ var txt= "#id:click {\n"
+ + " action-client: log;\n"
+ + " log-message: whatever alias('name');\n"
+ + "}\n"
+ var cursor = new kukit.tk.Cursor(txt);
+ this.assertParsingError(kukit.kssp.Document, cursor, null, true,
+ // XXX This error message will be fixed in service-layer branch
+ // XXX This will also fix running from IE, currently broken at error assert.
+ 'Provider result type [alias] not allowed in the action parameter [message]., at row 1, column 11');
+ };
+
+};
+
+kukit.KssParserValueProvidersCheckTestCase.prototype = new kukit.KssParserTestCaseBase;
+
+
kukit.KssParserSelectorTestCase = function() {
this.name = 'kukit.KssParserSelectorTestCase';
@@ -1115,6 +1769,7 @@
this.assertParsingError(kukit.kssp.KssSelector, cursor, null, true,
'Error : undefined namespace or event in [dnd-drog].');
}
+
};
kukit.KssParserSelectorTestCase.prototype = new kukit.KssParserTestCaseBase;
@@ -1476,6 +2131,8 @@
if (typeof(testcase_registry) != 'undefined') {
testcase_registry.registerTestCase(kukit.KssParserTestCase,
'kukit.KssParserTestCase');
+ testcase_registry.registerTestCase(kukit.KssParserValueProvidersCheckTestCase,
+ 'kukit.KssParserValueProvidersCheckTestCase');
testcase_registry.registerTestCase(kukit.KssParserSelectorTestCase,
'kukit.KssParserSelectorTestCase');
testcase_registry.registerTestCase(kukit.KssParserSelectorsTestCase,
Modified: kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/tests/test_requestmanager.js
==============================================================================
--- kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/tests/test_requestmanager.js (original)
+++ kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/tests/test_requestmanager.js Wed Jan 23 17:35:34 2008
@@ -79,7 +79,7 @@
this.testNormalSend = function() {
// Test a simple send situation
- var rm = new kukit.rm.RequestManager(2, null, kukit.DummyScheduler);
+ var rm = new kukit.rm.RequestManager(null, 2, kukit.DummyScheduler);
this.assertRmQueues(rm, 0, 0);
// queues
var sent = [];
@@ -116,7 +116,7 @@
this.testSendWithTimeouts = function() {
// Test a simple timeout situation
- var rm = new kukit.rm.RequestManager(2, null, kukit.DummyScheduler);
+ var rm = new kukit.rm.RequestManager(null, 2, kukit.DummyScheduler);
this.assertRmQueues(rm, 0, 0);
// queues
var sent = [];
@@ -161,7 +161,7 @@
this.testSendWithQueuedTimeout = function() {
// Test timeout with queues not sent out
- var rm = new kukit.rm.RequestManager(2, null, kukit.DummyScheduler);
+ var rm = new kukit.rm.RequestManager(null, 2, kukit.DummyScheduler);
this.assertRmQueues(rm, 0, 0);
// queues
var sent = [];
@@ -203,7 +203,7 @@
this.testSendWithQueuedSwallowed = function() {
// If the queued element is timed out, it it not sent out
- var rm = new kukit.rm.RequestManager(2, null, kukit.DummyScheduler);
+ var rm = new kukit.rm.RequestManager(null, 2, kukit.DummyScheduler);
this.assertRmQueues(rm, 0, 0);
// queues
var sent = [];
@@ -246,7 +246,7 @@
this.testAllTimedOut = function() {
// If all elements are timed out
- var rm = new kukit.rm.RequestManager(2, null, kukit.DummyScheduler);
+ var rm = new kukit.rm.RequestManager(null, 2, kukit.DummyScheduler);
this.assertRmQueues(rm, 0, 0);
// queues
var sent = [];
@@ -284,7 +284,7 @@
this.testTimeoutHooks = function() {
// Test if timeout hook(s) are called
- var rm = new kukit.rm.RequestManager(2, null, kukit.DummyScheduler);
+ var rm = new kukit.rm.RequestManager(null, 2, kukit.DummyScheduler);
this.assertRmQueues(rm, 0, 0);
// queues
var sent = [];
Modified: kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/tests/test_utils.js
==============================================================================
--- kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/tests/test_utils.js (original)
+++ kukit/kukit.js/branch/ree-1.4-markup-and-syntax-changes/tests/test_utils.js Wed Jan 23 17:35:34 2008
@@ -227,7 +227,7 @@
var base = kukit.ut.calculateBase(this.doc, this.pageLocation);
this.assertEquals(base, this.pageRoot + '/');
};
-}
+};
kukit.BaseURLTestCase.prototype = new kukit.UtilsTestCaseBase;
More information about the Kukit-checkins
mailing list