view release on metacpan or search on metacpan
doc/html/AutoCompleter.html view on Meta::CPAN
<h3 class="TN_label">autocomplete(inputField)</h3>
<div class="TN_content">
<p>Returns an event handler to be bound to the <code>onfocus</code> event on
an input field, i.e.</p>
<pre> <input name="someInput" onfocus="myAutoCompleter.complete(this)"></pre>
<p>The autocompleter will automatically register
<code>onblur</code>, <code>onclick</code> and <code>onkeydown</code> handlers on the same field, so avoid
setting your own, which may cause unpredictable interactions.
However the autocompleter has its own event model
to which you can bind your handling code
(see the <i>EVENTS</i> section below).</p>
</div>
</div>
<div class="TN_node" id="detach_inputField_">
<h3 class="TN_label">detach(inputField)</h3>
<div class="TN_content">
<p>Permanently detaches the input field from the autocompleter object
(i.e. removes <code>onblur</code> and <code>onkeypress</code> handlers
that were previously set by the first invocation of the
doc/html/AutoCompleter.html view on Meta::CPAN
</div>
</div>
<div class="TN_node" id="EVENTS">
<h2 class="TN_label">EVENTS</h2>
<div class="TN_content">
<p>For a general explanation on registering handlers
for GvaScript events, see the <i>event</i> documentation.
In short, you can register handlers either on the
HTML input element, as in</p>
<pre> <input name="someInput" onfocus = "myAutoCompleter.complete(this)"
onBind = "bindHandler(this, event)"
onLeave = "leaveHandler"></pre>
<p>or on the javascript object, as in</p>
<pre> myAutocompleter.onBind = function(event) {
bindHandler(event.target, event)
};
myAutocompleter.onLeave = leaveHandler;</pre>
<p>Below is the list of events generated by
autocompleter objects.</p>
<div class="TN_node" id="onBind">
<h3 class="TN_label">onBind</h3>
<div class="TN_content">
<p>This event is triggered whenever the autocompleter object
becomes associated with an input field; typically this
doc/html/CustomButtons.html view on Meta::CPAN
<div class="TN_content">
<pre> var mybutton = new GvaScript.CustomButtons.Buttons(container, properties);</pre>
<p>The <code>properties</code> hash describes the button behavior and display, with
the following entries :</p>
<ul>
<li><a name="item_id__i__string___i_"></a><b>id <i>(string)</i></b>
<p>unique identifier of the button - will be set to the <button> element.</p>
<p>optional - system will provide one if none provided.</p>
</li>
<li><a name="item_tabindex__i__numeric___i_"></a><b>tabindex <i>(numeric)</i></b>
<p>numeric value of the tabindex to set on the generated button element.</p>
<p>optional - button will not have tabindex attribute if none provided.</p>
</li>
<li><a name="item_callback__i__function___i_"></a><b>callback <i>(function)</i></b>
<p>onclick handler of the <button> element - will execute in the <b>button context</b>.</p>
<p>optional - defaulted to empty function.</p>
</li>
<li><a name="item_condition__i__boolean_function___i_"></a><b>condition <i>(boolean|function)</i></b>
<p>boolean value <b>or</b> a function that returns a boolean value indicating whether to render and display the button or not.
Note that if condition is false, the button will <b>not</b> be a part of the DOM.</p>
<p>optional - defaulted to true.</p>
</li>
doc/html/Grid.html view on Meta::CPAN
}</pre>
</div>
</div>
<div class="TN_node" id="HTML">
<h3 class="TN_label">HTML</h3>
<div class="TN_content">
<pre> <div id="ex_container">
<div tabindex="0" id="ex_grid_list">
<table class="dmweb-grid">
<thead>
<tr>
<th class="grid-marker"> </th>
<th class="grid-header">Full Name</th>
<th class="grid-header">Gender</th>
</tr>
</thead>
<tbody>
<tr id="ex_grid_list.CL_choice.0" class="CL_choiceItem liste_highlight">
doc/html/TreeNavigator.html view on Meta::CPAN
</li>
<li><a name="item__code_Ctrl_keypad____code_"></a><b><code>Ctrl-keypad *</code></b>
<p>activate "show all" mode (the content of closed nodes is nevertheless
visible, which may be useful for printing)</p>
</li>
<li><a name="item__code_Ctrl_keypad____code_"></a><b><code>Ctrl-keypad /</code></b>
<p>deactivate the "show all" mode</p>
</li>
<li><a name="item__code_TAB__code_"></a><b><code>TAB</code></b>
<p>if closed, open the node; if already opened, pass focus to the next
item (maybe the next node, or another tabindex-enabled HTML element,
such as a form control).</p>
</li>
<li><a name="item__code_ARROW_UP__code_"></a><b><code>ARROW_UP</code></b>
<p>move to previous displayed node</p>
</li>
<li><a name="item__code_ARROW_DOWN__code_"></a><b><code>ARROW_DOWN</code></b>
<p>move to next displayed node</p>
</li>
<li><a name="item__code_ARROW_LEFT__code_"></a><b><code>ARROW_LEFT</code></b>
<p>if open, close the node; if already closed, move to parent node</p>
lib/Alien/GvaScript/AutoCompleter.pod view on Meta::CPAN
Returns an event handler to be bound to the C<onfocus> event on
an input field, i.e.
<input name="someInput" onfocus="myAutoCompleter.complete(this)">
The autocompleter will automatically register
C<onblur>, C<onclick> and C<onkeydown> handlers on the same field, so avoid
setting your own, which may cause unpredictable interactions.
However the autocompleter has its own event model
to which you can bind your handling code
(see the L<EVENTS> section below).
=head2 detach(inputField)
Permanently detaches the input field from the autocompleter object
(i.e. removes C<onblur> and C<onkeypress> handlers
that were previously set by the first invocation of the
C<autocomplete> method).
=head2 displayMessage(messageText)
lib/Alien/GvaScript/AutoCompleter.pod view on Meta::CPAN
=head1 EVENTS
For a general explanation on registering handlers
for GvaScript events, see the L<event> documentation.
In short, you can register handlers either on the
HTML input element, as in
<input name="someInput" onfocus = "myAutoCompleter.complete(this)"
onBind = "bindHandler(this, event)"
onLeave = "leaveHandler">
or on the javascript object, as in
myAutocompleter.onBind = function(event) {
bindHandler(event.target, event)
};
myAutocompleter.onLeave = leaveHandler;
Below is the list of events generated by
autocompleter objects.
=head2 onBind
This event is triggered whenever the autocompleter object
becomes associated with an input field; typically this
lib/Alien/GvaScript/CustomButtons.pod view on Meta::CPAN
the following entries :
=over
=item id I<(string)>
unique identifier of the button - will be set to the <button> element.
optional - system will provide one if none provided.
=item tabindex I<(numeric)>
numeric value of the tabindex to set on the generated button element.
optional - button will not have tabindex attribute if none provided.
=item callback I<(function)>
onclick handler of the <button> element - will execute in the B<button context>.
optional - defaulted to empty function.
=item condition I<(boolean|function)>
boolean value B<or> a function that returns a boolean value indicating whether to render and display the button or not.
lib/Alien/GvaScript/Grid.pod view on Meta::CPAN
can_create : 0,
can_update : 1,
can_delete : 0
}
}
=head2 HTML
<div id="ex_container">
<div tabindex="0" id="ex_grid_list">
<table class="dmweb-grid">
<thead>
<tr>
<th class="grid-marker"> </th>
<th class="grid-header">Full Name</th>
<th class="grid-header">Gender</th>
</tr>
</thead>
<tbody>
<tr id="ex_grid_list.CL_choice.0" class="CL_choiceItem liste_highlight">
lib/Alien/GvaScript/TreeNavigator.pod view on Meta::CPAN
=item C<Ctrl-keypad />
deactivate the "show all" mode
=item C<TAB>
if closed, open the node; if already opened, pass focus to the next
item (maybe the next node, or another tabindex-enabled HTML element,
such as a form control).
=item C<ARROW_UP>
move to previous displayed node
=item C<ARROW_DOWN>
move to next displayed node
lib/Alien/GvaScript/lib/GvaScript.js view on Meta::CPAN
var classname = options.classname || 'flash';
element._IS_FLASHING = true;
var endFlash = function() {
this.removeClassName(classname);
this._IS_FLASHING = false;
};
element.addClassName(classname);
setTimeout(endFlash.bind(element), duration);
}
});
// utilities for hash
// expands flat hash into a multi-level deep hash
// javascript version of Perl CGI::Expand::expand_hash
Hash.expand = function(flat_hash) {
var tree = {};
lib/Alien/GvaScript/lib/GvaScript.js view on Meta::CPAN
observe: function(eventType, elem, options) {
this.eventType = eventType || 'keydown';
this.elem = elem || document;
// "Shift" modifier usually does not make sense for keypress events
if (eventType == 'keypress' && !options)
options = {ignoreShift: true};
this.options = Class.checkOptions(Event.stopNone, this.options || {});
this.eventHandler = this.eventHandler.bindAsEventListener(this);
Event.observe(this.elem, this.eventType, this.eventHandler);
},
_findInStack: function(event, stack) {
for (var i = stack.length - 1; i >= 0; i--) {
var rules = stack[i];
// trick to differentiate between C_9 (digit) and C_09 (TAB)
var keyCode = event.keyCode>9 ? event.keyCode : ("0"+event.keyCode);
lib/Alien/GvaScript/lib/GvaScript.js view on Meta::CPAN
// add buttons and tabIndex to labels
this.initSubTree(elem);
// tree-wide navigation handlers
this._addHandlers();
// tree-wide tabbing handlers
this._addTabbingBehaviour();
// initializing the keymap
var keyHandlers = {
DOWN: this._downHandler .bindAsEventListener(this),
UP: this._upHandler .bindAsEventListener(this),
LEFT: this._leftHandler .bindAsEventListener(this),
RIGHT: this._rightHandler .bindAsEventListener(this),
KP_PLUS: this._kpPlusHandler .bindAsEventListener(this),
KP_MINUS: this._kpMinusHandler.bindAsEventListener(this),
KP_STAR: this._kpStarHandler .bindAsEventListener(this),
KP_SLASH: this._kpSlashHandler.bindAsEventListener(this),
C_R: this._ctrl_R_handler.bindAsEventListener(this),
RETURN: this._ReturnHandler .bindAsEventListener(this),
C_KP_STAR: this._showAll .bindAsEventListener(this, true),
C_KP_SLASH: this._showAll .bindAsEventListener(this, false),
HOME: this._homeHandler .bindAsEventListener(this),
END: this._endHandler .bindAsEventListener(this),
C_PAGE_UP : this._ctrlPgUpHandler .bindAsEventListener(this),
C_PAGE_DOWN: this._ctrlPgDownHandler.bindAsEventListener(this),
REGEX : [[ "", /^\w$/, this._charHandler.bindAsEventListener(this) ]]
};
if (this.options.tabIndex >= 0)
keyHandlers["TAB"] = this._tabHandler.bindAsEventListener(this);
// handlers for ctrl_1, ctrl_2, etc. to open the tree at that level
var numHandler = this._chooseLevel.bindAsEventListener(this);
$R(1, 9).each(function(num){keyHandlers["C_" + num] = numHandler});
// tabIndex for the tree element
elem.tabIndex = Math.max(elem.tabIndex, this.options.treeTabIndex);
this._clear_quick_navi();
if (options.keymap) {
this.keymap = options.keymap;
this.keymap.rules.push(keyHandlers);
lib/Alien/GvaScript/lib/GvaScript.js view on Meta::CPAN
if(! label.hasAttribute('hasFocus'))
label.focus();
}
}
}
// cancel if there was any select execution pending
if (this._selectionTimeoutId) clearTimeout(this._selectionTimeoutId);
// register code to call the selection handlers after some delay
var callback = this._selectionTimeoutHandler.bind(this, previousNode);
this._selectionTimeoutId =
setTimeout(callback, this.options.selectDelay);
},
scrollTo: function(node, with_content) {
if(!node) return;
var container = this.options.scrollingContainer;
if(typeof container == 'string') {
container = $(container);
lib/Alien/GvaScript/lib/GvaScript.js view on Meta::CPAN
if (this.isLeaf(node)) return null;
this._assertNode(node, 'content: arg type');
return Element.navigateDom(node.lastChild, 'previousSibling',
this.classes.content);
},
parentNode: function (node) {
this._assertNodeOrLeaf(node, 'parentNode: arg type');
return Element.navigateDom(
node.parentNode, 'parentNode', this.classes.node,
this.isRootElement.bind(this));
},
nextSibling: function (node) {
this._assertNodeOrLeaf(node, 'nextSibling: arg type');
return Element.navigateDom(node.nextSibling, 'nextSibling',
this.classes.nodeOrLeaf);
},
previousSibling: function (node) {
lib/Alien/GvaScript/lib/GvaScript.js view on Meta::CPAN
return this.lastVisibleSubnode(node);
}
// if no previous sibling
return this.parentNode(node_init);
},
enclosingNode: function (elem) {
return Element.navigateDom(
$(elem), 'parentNode', this.classes.nodeOrLeaf,
this.isRootElement.bind(this));
},
// flash the node
flash: function (node) {
var label = this.label(node);
ASSERT(label, "node has no label");
label.flash({duration: 200});
},
lib/Alien/GvaScript/lib/GvaScript.js view on Meta::CPAN
ASSERT(elem && Element.hasAnyClass(elem, this.classes.node), msg);
},
_assertNodeOrLeaf: function(elem, msg) {
ASSERT(elem && Element.hasAnyClass(elem, this.classes.nodeOrLeaf), msg);
},
_addHandlers: function() {
Event.observe(
this.rootElement, "mouseover",
this._treeMouseOverHandler.bindAsEventListener(this));
Event.observe(
this.rootElement, "mouseout",
this._treeMouseOutHandler.bindAsEventListener(this));
Event.observe(
// observing "mouseup" instead of "click", because "click"
// on MSIE8 only fires when there is a tabindex
this.rootElement, "mouseup",
this._treeClickHandler.bindAsEventListener(this));
Event.observe(
this.rootElement, "dblclick",
this._treeDblClickHandler.bindAsEventListener(this));
},
_removeHandlers: function() {
this.rootElement.stopObserving();
this.rootElement.unregister();
},
//-----------------------------------------------------
// mouse handlers
//-----------------------------------------------------
lib/Alien/GvaScript/lib/GvaScript.js view on Meta::CPAN
Event.stop(event);
}
},
_buttonClicked : function(node) {
var method = this.isClosed(node) ? this.open : this.close;
method.call(this, node);
if (this.options.selectOnButtonClick) {
window.setTimeout(function() {
this.select(node);
}.bind(this), 0);
}
},
_labelClicked : function(node, event) {
// situation before the mousedown
var is_selected = (this.selectedNode == node);
var is_first_click = !is_selected;
// select node if it wasn't
if (!is_selected) this.select(node);
lib/Alien/GvaScript/lib/GvaScript.js view on Meta::CPAN
var blur_handler = function(e) {
var label = e._target;
label.removeAttribute('hasFocus');
// deselect the previously selected node
treeNavigator.select(null);
};
// focus and blur do not bubble
// workaround per browser
focus_handler = focus_handler.bindAsEventListener(this);
blur_handler = blur_handler.bindAsEventListener(this);
this.rootElement.register('.'+this.classes.label, 'focus', focus_handler);
this.rootElement.register('.'+this.classes.label, 'blur', blur_handler );
},
//-----------------------------------------------------
// timeout handler for firing Select/Deselect events
//-----------------------------------------------------
lib/Alien/GvaScript/lib/GvaScript.js view on Meta::CPAN
}
// initialize labels_array on start of quick-search
// (mandate of dynamic trees)
else {
this.labels_array = this.rootElement.select('.'+this.classes.label);
}
// activate a new timer
this._quick_navi_mode = window.setTimeout(function() {
this._clear_quick_navi();
}.bind(this), 800);
var selectedLabel = this.label(selectedNode);
var selectedIndex = this.labels_array.indexOf(selectedLabel);
// partitions the labels array into 2 arrays
// 1: preceeding labels & selectedNode if not in quick_navi_mode
// 2: following labels & selectedNode if in quick_navi_mode
var labels = this.labels_array.partition(function(l, index) {
// quick-navi mode
if(is_quick_navi_mode) return index < selectedIndex;
else return index <= selectedIndex;
lib/Alien/GvaScript/lib/GvaScript.js view on Meta::CPAN
// handy vars
this.hasPaginator = this.options.paginator != null;
this.pageSize = (
// the step size of the paginator if any
(this.hasPaginator && this.options.paginator.options.step)
||
// scroll count
this.options.scrollCount
);
// prepare some stuff to be reused when binding to inputElements
this.reuse = {
onmouseover : this._listOverHandler.bindAsEventListener(this),
onclick : this._clickHandler.bindAsEventListener(this),
ondblclick : this._dblclickHandler.bindAsEventListener(this),
navigationRules: {
DOWN: this._highlightDelta.bindAsEventListener(this, 1),
UP: this._highlightDelta.bindAsEventListener(this, -1),
PAGE_DOWN: this._highlightDelta.bindAsEventListener(this, this.pageSize),
PAGE_UP: this._highlightDelta.bindAsEventListener(this, -this.pageSize),
HOME: this._jumpToIndex.bindAsEventListener(this, 0),
END: this._jumpToIndex.bindAsEventListener(this, 99999),
RETURN: this._returnHandler .bindAsEventListener(this),
ESCAPE: this._escapeHandler .bindAsEventListener(this)
}
};
if(this.hasPaginator) {
// next/prev page
this.reuse.navigationRules.RIGHT
= this._highlightDelta.bindAsEventListener(this, this.pageSize)
this.reuse.navigationRules.LEFT
= this._highlightDelta.bindAsEventListener(this, -this.pageSize);
// first/last page
this.reuse.navigationRules.C_HOME
= this._jumpToPage.bindAsEventListener(this, 0);
this.reuse.navigationRules.C_END
= this._jumpToPage.bindAsEventListener(this, 99999);
}
};
GvaScript.ChoiceList.prototype = {
//----------------------------------------------------------------------
// PUBLIC METHODS
//----------------------------------------------------------------------
destroy: function() {
lib/Alien/GvaScript/lib/GvaScript.js view on Meta::CPAN
}
return this.options.htmlWrapper(html);
},
choiceElementHTML: function(label, id) {
return "<" + this.options.choiceItemTagName + " class='"
+ this.classes.choiceItem + "' id='" + id + "'>"
+ label + "</" + this.options.choiceItemTagName + ">";
},
fireEvent: GvaScript.fireEvent, // must be copied here for binding "this"
//----------------------------------------------------------------------
// PRIVATE METHODS
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// conversion index <=> HTMLElement
//----------------------------------------------------------------------
lib/Alien/GvaScript/lib/GvaScript.js view on Meta::CPAN
this.dropdownDiv = null;
// array to store running ajax requests
// of same autocompleter but for different input element
this._runningAjax = [];
this.setdatasource(datasource);
// prepare an initial keymap; will be registered at first
// focus() event; then a second set of keymap rules is pushed/popped
// whenever the choice list is visible
var basicHandler = this._keyDownHandler.bindAsEventListener(this);
var detectedKeys = /^(BACKSPACE|DELETE|KP_.*|.)$/;
// catch any single char, plus some editing keys
var basicMap = { DOWN: this._ArrowDownHandler.bindAsEventListener(this),
REGEX: [[null, detectedKeys, basicHandler]] };
this.keymap = new GvaScript.KeyMap(basicMap);
// prepare some stuff to be reused when binding to inputElements
this.reuse = {
onblur : this._blurHandler.bindAsEventListener(this),
onclick : this._clickHandler.bindAsEventListener(this)
};
}
GvaScript.AutoCompleter.prototype = {
//----------------------------------------------------------------------
// PUBLIC METHODS
//----------------------------------------------------------------------
// autocomplete : called when the input element gets focus; binds
// the autocompleter to the input element
autocomplete: function(elem) {
elem = $(elem);// in case we got an id instead of an element
if (!elem) throw new Error("attempt to autocomplete a null element");
// elem is readonly => no action
if (elem.getAttribute('readonly') || elem.readOnly) return;
// if already bound, no more work to do
if (elem === this.inputElement) return;
// bind to the element; if first time, also register the event handlers
this.inputElement = elem;
if (!elem._autocompleter) {
elem._autocompleter = this;
this.keymap.observe("keydown", elem, Event.stopNone);
Element.observe(elem, "blur", this.reuse.onblur);
Element.observe(elem, "click", this.reuse.onclick);
// prevent browser builtin autocomplete behaviour
elem.writeAttribute("autocomplete", "off");
}
lib/Alien/GvaScript/lib/GvaScript.js view on Meta::CPAN
pos.top -= this.observed_scroll.scrollTop - this.currentScrollTop;
pos.left -= this.observed_scroll.scrollLeft;
this.dropdownDiv.style.top = pos.top + "px";
this.dropdownDiv.style.left = pos.left + "px";
}
this.currentScrollTop = this.observed_scroll.scrollTop;
this.currentScrollLeft = this.observed_scroll.scrollLeft;
}
Event.observe(elem, 'scroll',
correct_dropdown_position.bindAsEventListener(this));
},
//----------------------------------------------------------------------
// PRIVATE METHODS
//----------------------------------------------------------------------
_updateChoicesFromAjax: function (val_to_complete, continuation) {
// copies into local variables, needed for closures below (can't rely on
lib/Alien/GvaScript/lib/GvaScript.js view on Meta::CPAN
var matchPrefix = function(choice) {
var value;
switch(typeof choice) {
case "object" : value = choice[this.options.valueField]; break;
case "number" : value = choice.toString(10); break;
case "string" : value = choice; break;
default: throw new Error("unexpected type of value");
}
return value.search(regex) > -1;
};
continuation(this._datasource.select(matchPrefix.bind(this)));
}
},
_updateChoices : function (continuation) {
var value = this._getValueToComplete();
// if (window.console) console.log('updateChoices', value);
this._updateChoicesHandler(value, continuation);
lib/Alien/GvaScript/lib/GvaScript.js view on Meta::CPAN
}, this.inputElement);
if(! return_value) {
this.inputElement.style.backgroundColor = this.options.colorIllegal;
this._updateDependentFields(this.inputElement, null);
}
}
// otherwise get choices and then inspect status (maybe asynchronously)
else {
this._updateChoices(this._fireFinalStatus.bind(this,
this.inputElement));
}
}
this.fireEvent("Leave", this.inputElement);
this.inputElement = null;
},
_fireFinalStatus: function (inputElement, choices) {
// NOTE: takes inputElement and choices as arguments, because it might be
lib/Alien/GvaScript/lib/GvaScript.js view on Meta::CPAN
// invalidate previous lists of choices because value may have changed
this.choices = null;
this._removeDropdownDiv();
// cancel pending timeouts because we create a new one
if (this._timeoutId) clearTimeout(this._timeoutId);
this._timeLastKeyDown = (new Date()).getTime();
// if (window.console) console.log('keyDown', this._timeLastKeyDown, event.keyCode);
this._timeoutId = setTimeout(this._checkNewValue.bind(this),
this.options.checkNewValDelay);
// do NOT stop the event here : give back control so that the standard
// browser behaviour can update the value; then come back through a
// timeout to update the Autocompleter
},
_checkNewValue: function() {
lib/Alien/GvaScript/lib/GvaScript.js view on Meta::CPAN
this.inputElement.style.backgroundColor = ""; // remove colorIllegal
if (this.options.autoSuggest)
this._displayChoices();
}
else if (this.options.strict && (!this.options.blankOK)) {
this.inputElement.style.backgroundColor = this.options.colorIllegal;
}
};
// now call updateChoices (which then will call the continuation)
this._updateChoices(continuation.bind(this));
}
},
// return the value to be completed
// TODO : for multivalued, should return the value under the cursor,
// instead returning sytematically the last value
_getValueToComplete : function(value) {
// NOTE: the explicit value as argument is only used from
//_fireFinalStatus(), when we can no longer rely on
lib/Alien/GvaScript/lib/GvaScript.js view on Meta::CPAN
// maxHeight cannot be simulated untill displayChoices
if (navigator.userAgent.match(/\bMSIE [456]\b/)) {
div.style.width = this.options.minWidth + "px";
}
// mouseenter and mouseleave events to control
// whether autocompleter has been blurred
var elem = this.inputElement;
div.observe('mouseenter', function(e) {
Element.stopObserving(elem, "blur", this.reuse.onblur);
}.bind(this));
div.observe('mouseleave', function(e) {
Element.observe(elem, "blur", this.reuse.onblur);
}.bind(this));
return this.dropdownDiv = div;
},
_displayChoices: function() {
// if no choices are ready, can't display anything
if (!this.choices) return;
lib/Alien/GvaScript/lib/GvaScript.js view on Meta::CPAN
this.container.insert(_render(this.options));
this.btnContainer = $(this.options.id); // the outer <span/>
this.btnElt = this.btnContainer.down('.btn'); // the <button/>
// setting inline style on the button container
if(typeof this.options.style != 'undefined') {
this.btnContainer.setStyle(this.options.style);
}
// setting tabindex on button if any
if(typeof this.options.tabindex != 'undefined') {
this.btnElt.writeAttribute('tabindex', this.options.tabindex);
}
this.btnElt.observe('click', this.options.callback.bind(this.btnElt));
} catch (e) {}
}
}
}
}());
GvaScript.CustomButtons.ButtonNavigation = Class.create();
Object.extend(GvaScript.CustomButtons.ButtonNavigation.prototype, function() {
// private members
var bcss = CSSPREFIX();
lib/Alien/GvaScript/lib/GvaScript.js view on Meta::CPAN
// support focus function on span.buttonContainer
btnContainer.focus = function() {btn.focus();}
}
if(typeof btn == 'undefined') return;
}, this);
this.container.register('button.btn', 'focus', function(e) {
this.select.call(this, e._target.up('.'+bcss+'-btn-container'));
}.bind(this));
this.container.register('button.btn', 'blur', function(e) {
this.select.call(this, null);
}.bind(this));
}
// public members
return {
destroy: function() {
// test that element still in DOM
if(this.container) this.container.unregister();
this.keymap.destroy();
},
initialize: function(container, options) {
lib/Alien/GvaScript/lib/GvaScript.js view on Meta::CPAN
flashClassName : 'flash',
keymap : null,
selectFirstBtn : true,
className : bcss+'-button'
};
this.options = Object.extend(defaults, options || {});
this.container = $(container);
// initializing the keymap
var keyHandlers = {
LEFT: _leftHandler .bindAsEventListener(this),
RIGHT: _rightHandler .bindAsEventListener(this),
TAB: _tabHandler .bindAsEventListener(this),
S_TAB: _shiftTabHandler .bindAsEventListener(this),
HOME: _homeHandler .bindAsEventListener(this),
END: _endHandler .bindAsEventListener(this)
};
this.keymap = new GvaScript.KeyMap(keyHandlers);
this.keymap.observe("keydown", container, {
preventDefault:false,
stopPropagation:false
});
// get all buttons of designated className regardless of their
// visibility jump over hidden ones when navigating
this.buttons = this.container.select('.'+this.options.className);
_addHandlers.call(this);
if (this.options.selectFirstBtn) {
if(firstButObj = this.firstBtn()) {
this.select(firstButObj);
}
// set the focus on the container anyways so that the focus
// gets trasferred successfully to windows with empty
// actionsbar
else {
this.container.writeAttribute('tabindex', 0);
this.container.focus();
}
}
},
select: function (btn) {
var previousBtn = this.selectedBtn || null;
if (previousBtn === btn) return; // selection already handled
// blur the previously selected button
if (previousBtn) {
lib/Alien/GvaScript/lib/GvaScript.js view on Meta::CPAN
function _addPaginationElts() {
// append the pagination buttons
this.links_container.insert(pagination_buttons);
this.first = this.links_container.down('.first');
this.last = this.links_container.down('.last');
this.forward = this.links_container.down('.forward');
this.back = this.links_container.down('.back');
this.textElem = this.links_container.down('.text');
this.first.observe ('click', this.getFirstPage.bind(this));
this.last.observe ('click', this.getLastPage.bind(this));
this.back.observe ('click', this.getPrevPage.bind(this));
this.forward.observe('click', this.getNextPage.bind(this));
}
return {
destroy: function() {
this.first.stopObserving();
this.last.stopObserving();
this.back.stopObserving();
this.forward.stopObserving();
},
initialize: function(url, options) {
lib/Alien/GvaScript/lib/GvaScript.js view on Meta::CPAN
this.list_container.update(new Element('div', {'class': bcss+'-loading'}));
new Ajax.Request(url, {
evalJSON: 'force', // force evaluation of response into responseJSON
method: this.options.method,
parameters: this.options.parameters,
requestTimeout: this.options.timeoutAjax * 1000,
onTimeout: function(req) {
this._executing = false;
this.list_container.update(this.options.errorMsg);
}.bind(this),
// on s'attend à avoir du JSON en retour
onFailure: function(req) {
this._executing = false;
var answer = req.responseJSON;
var msg = answer.error.message || this.options.errorMsg;
this.list_container.update(msg);
}.bind(this),
onSuccess: function(req) {
this._executing = false;
var answer = req.responseJSON;
if(answer) {
var nb_displayed_records = this.options.onSuccess(answer);
this.total = answer.total; // total number of records
this.end_index = Math.min(this.total, this.index+nb_displayed_records-1); // end index of records on current page
this.textElem.innerHTML = (this.total > 0)?
this.index + " à " + this.end_index + " de " + this.total: '0';
_toggleNavigatorsVisibility.apply(this);
}
}.bind(this)
});
}
}
}());
//----------grid.js
// depends: custom-buttons.js
// paginator.js
// choiceList.js
GvaScript.Grid = Class.create();
lib/Alien/GvaScript/lib/GvaScript.js view on Meta::CPAN
this.toolbar_container.insert(this.paginatorbar_container);
this.toolbar_container.insert(this.actionsbar_container);
this.dto = _compileDTO(this.options.dto);
this.paginator = new GvaScript.Paginator(
this.datasource, {
list_container : this.grid_container,
links_container : this.paginatorbar_container,
method : this.options.method,
onSuccess : this.receiveRequest.bind(this),
parameters : this.dto,
step : this.limit,
timeoutAjax : this.options.requestTimeout,
errorMsg : this.options.errorMsg,
lazy : true
}
);
if(! (recycled = this.grid_container.choiceList) ) {
this.choiceList = new GvaScript.ChoiceList([], {
paginator : this.paginator,
mouseovernavi : false,
classes : {'choiceHighlight': "hilite"},
choiceItemTagName : "tr",
grabfocus : false,
htmlWrapper : this.gridWrapper.bind(this)
});
this.choiceList_initialized = false;
}
// recycle the previously created choiceList
else {
this.choiceList = recycled;
this.choiceList.options.htmlWrapper = this.gridWrapper.bind(this);
this.choiceList.options.paginator = this.paginator;
this.choiceList_initialized = true;
}
this.choiceList.onCancel = this.options.onCancel;
this.choiceList.onPing = this.pingWrapper.bind(this);
this.paginator.loadContent();
this.grid_container.addClassName(bcss+'-widget');
this.grid_container.store('widget', this);
GvaScript.Grids.register(this);
},
getId: function() {
lib/Alien/GvaScript/lib/GvaScript.js view on Meta::CPAN
onBeforeDestroy : Prototype.emptyFunction // called right before form.destroy
}
this.options = Object.extend(defaults, options || {});
// attaching submitMethod to form.onsubmit event
this.formElt.observe('submit', function() {
// submit method only called if
// onBeforeSubmit handler doesnot return false
if ( this.fire('BeforeSubmit') ) return this.fire('Submit');
}.bind(this));
// initializing watchers
$A(this.options.registry).each(function(w) {
this.register(w[0], w[1], w[2]);
}, this);
var that = this;
// workaround as change event doesnot bubble in IE
this.formElt.observe('value:change', function(event) {
if(event.memo.handler) {
lib/Alien/GvaScript/lib/prototype.js view on Meta::CPAN
for (var i = 0, length = properties.length; i < length; i++) {
var property = properties[i], value = source[property];
if (ancestor && Object.isFunction(value) &&
value.argumentNames()[0] == "$super") {
var method = value;
value = (function(m) {
return function() { return ancestor[m].apply(this, arguments); };
})(property).wrap(method);
value.valueOf = method.valueOf.bind(method);
value.toString = method.toString.bind(method);
}
this.prototype[property] = value;
}
return this;
}
return {
create: create,
Methods: {
lib/Alien/GvaScript/lib/prototype.js view on Meta::CPAN
return update(array, args);
}
function argumentNames() {
var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
.replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
.replace(/\s+/g, '').split(',');
return names.length == 1 && !names[0] ? [] : names;
}
function bind(context) {
if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
var __method = this, args = slice.call(arguments, 1);
return function() {
var a = merge(args, arguments);
return __method.apply(context, a);
}
}
function bindAsEventListener(context) {
var __method = this, args = slice.call(arguments, 1);
return function(event) {
var a = update([event || window.event], args);
return __method.apply(context, a);
}
}
function curry() {
if (!arguments.length) return this;
var __method = this, args = slice.call(arguments, 0);
lib/Alien/GvaScript/lib/prototype.js view on Meta::CPAN
}
function defer() {
var args = update([0.01], arguments);
return this.delay.apply(this, args);
}
function wrap(wrapper) {
var __method = this;
return function() {
var a = update([__method.bind(this)], arguments);
return wrapper.apply(this, a);
}
}
function methodize() {
if (this._methodized) return this._methodized;
var __method = this;
return this._methodized = function() {
var a = update([this], arguments);
return __method.apply(null, a);
};
}
return {
argumentNames: argumentNames,
bind: bind,
bindAsEventListener: bindAsEventListener,
curry: curry,
delay: delay,
defer: defer,
wrap: wrap,
methodize: methodize
}
})());
lib/Alien/GvaScript/lib/prototype.js view on Meta::CPAN
var PeriodicalExecuter = Class.create({
initialize: function(callback, frequency) {
this.callback = callback;
this.frequency = frequency;
this.currentlyExecuting = false;
this.registerCallback();
},
registerCallback: function() {
this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
},
execute: function() {
this.callback(this);
},
stop: function() {
if (!this.timer) return;
clearInterval(this.timer);
this.timer = null;
lib/Alien/GvaScript/lib/prototype.js view on Meta::CPAN
this.parameters = params.toQueryParams();
try {
var response = new Ajax.Response(this);
if (this.options.onCreate) this.options.onCreate(response);
Ajax.Responders.dispatch('onCreate', this, response);
this.transport.open(this.method.toUpperCase(), this.url,
this.options.asynchronous);
if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1);
this.transport.onreadystatechange = this.onStateChange.bind(this);
this.setRequestHeaders();
this.body = this.method == 'post' ? (this.options.postBody || params) : null;
this.transport.send(this.body);
/* Force Firefox to handle ready state 4 for synchronous requests */
if (!this.options.asynchronous && this.transport.overrideMimeType)
this.onStateChange();
}
lib/Alien/GvaScript/lib/prototype.js view on Meta::CPAN
this.container = {
success: (container.success || container),
failure: (container.failure || (container.success ? null : container))
};
options = Object.clone(options);
var onComplete = options.onComplete;
options.onComplete = (function(response, json) {
this.updateContent(response.responseText);
if (Object.isFunction(onComplete)) onComplete(response, json);
}).bind(this);
$super(url, options);
},
updateContent: function(responseText) {
var receiver = this.container[this.success() ? 'success' : 'failure'],
options = this.options;
if (!options.evalScripts) responseText = responseText.stripScripts();
lib/Alien/GvaScript/lib/prototype.js view on Meta::CPAN
this.decay = (this.options.decay || 1);
this.updater = { };
this.container = container;
this.url = url;
this.start();
},
start: function() {
this.options.onComplete = this.updateComplete.bind(this);
this.onTimerEvent();
},
stop: function() {
this.updater.options.onComplete = undefined;
clearTimeout(this.timer);
(this.onComplete || Prototype.emptyFunction).apply(this, arguments);
},
updateComplete: function(response) {
if (this.options.decay) {
this.decay = (response.responseText == this.lastText ?
this.decay * this.options.decay : 1);
this.lastText = response.responseText;
}
this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency);
},
onTimerEvent: function() {
this.updater = new Ajax.Updater(this.container, this.url, this.options);
}
});
function $(element) {
if (arguments.length > 1) {
lib/Alien/GvaScript/lib/prototype.js view on Meta::CPAN
nodes.each(function(node) { element.appendChild(node) });
}
else {
element.innerHTML = content.stripScripts();
}
}
else {
element.innerHTML = content.stripScripts();
}
content.evalScripts.bind(content).defer();
return element;
}
return update;
})(),
replace: function(element, content) {
element = $(element);
if (content && content.toElement) content = content.toElement();
else if (!Object.isElement(content)) {
content = Object.toHTML(content);
var range = element.ownerDocument.createRange();
range.selectNode(element);
content.evalScripts.bind(content).defer();
content = range.createContextualFragment(content.stripScripts());
}
element.parentNode.replaceChild(content, element);
return element;
},
insert: function(element, insertions) {
element = $(element);
if (Object.isString(insertions) || Object.isNumber(insertions) ||
lib/Alien/GvaScript/lib/prototype.js view on Meta::CPAN
content = Object.toHTML(content);
tagName = ((position == 'before' || position == 'after')
? element.parentNode : element).tagName.toUpperCase();
childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
if (position == 'top' || position == 'after') childNodes.reverse();
childNodes.each(insert.curry(element));
content.evalScripts.bind(content).defer();
}
return element;
},
wrap: function(element, wrapper, attributes) {
element = $(element);
if (Object.isElement(wrapper))
$(wrapper).writeAttribute(attributes || { });
else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes);
lib/Alien/GvaScript/lib/prototype.js view on Meta::CPAN
var nextSibling = element.next(),
fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
parent.removeChild(element);
if (nextSibling)
fragments.each(function(node) { parent.insertBefore(node, nextSibling) });
else
fragments.each(function(node) { parent.appendChild(node) });
}
else element.outerHTML = content.stripScripts();
content.evalScripts.bind(content).defer();
return element;
};
}
Element._returnOffset = function(l, t) {
var result = [l, t];
result.left = l;
result.top = t;
return result;
};
lib/Alien/GvaScript/lib/prototype.js view on Meta::CPAN
registerFormCallbacks: function() {
Form.getElements(this.element).each(this.registerCallback, this);
},
registerCallback: function(element) {
if (element.type) {
switch (element.type.toLowerCase()) {
case 'checkbox':
case 'radio':
Event.observe(element, 'click', this.onElementEvent.bind(this));
break;
default:
Event.observe(element, 'change', this.onElementEvent.bind(this));
break;
}
}
}
});
Form.Element.EventObserver = Class.create(Abstract.EventObserver, {
getValue: function() {
return Form.Element.getValue(this.element);
}
lib/Alien/GvaScript/lib/prototype.js view on Meta::CPAN
return Event.extend(event);
}
Event.Handler = Class.create({
initialize: function(element, eventName, selector, callback) {
this.element = $(element);
this.eventName = eventName;
this.selector = selector;
this.callback = callback;
this.handler = this.handleEvent.bind(this);
},
start: function() {
Event.observe(this.element, this.eventName, this.handler);
return this;
},
stop: function() {
Event.stopObserving(this.element, this.eventName, this.handler);
return this;
lib/Alien/GvaScript/lib/unittest.js view on Meta::CPAN
new Test.Unit.Testcase(
this.options.context ? ' -> ' + this.options.titles[testcase] : testcase,
testcases[testcase], testcases["setup"], testcases["teardown"]
));
}
}
}
}
this.currentTest = 0;
this.logger = new Test.Unit.Logger(this.options.testLog);
setTimeout(this.runTests.bind(this), 1000);
},
parseResultsURLQueryParameter: function() {
return window.location.search.parseQuery()["resultsURL"];
},
parseTestsQueryParameter: function(){
if (window.location.search.parseQuery()["tests"]){
return window.location.search.parseQuery()["tests"].split(',');
};
},
// Returns:
lib/Alien/GvaScript/lib/unittest.js view on Meta::CPAN
this.postResults();
this.logger.summary(this.summary());
return;
}
if(!test.isWaiting) {
this.logger.start(test.name);
}
test.run();
if(test.isWaiting) {
this.logger.message("Waiting for " + test.timeToWait + "ms");
setTimeout(this.runTests.bind(this), test.timeToWait || 1000);
} else {
this.logger.finish(test.status(), test.summary());
this.currentTest++;
// tail recursive, hopefully the browser will skip the stackframe
this.runTests();
}
},
summary: function() {
var assertions = 0;
var failures = 0;
lib/Alien/GvaScript/lib/unittest.js view on Meta::CPAN
assertElementsMatch: function() {
var expressions = $A(arguments), elements = $A(expressions.shift());
if (elements.length != expressions.length) {
this.fail('assertElementsMatch: size mismatch: ' + elements.length + ' elements, ' + expressions.length + ' expressions');
return false;
}
elements.zip(expressions).all(function(pair, index) {
var element = $(pair.first()), expression = pair.last();
if (element.match(expression)) return true;
this.fail('assertElementsMatch: (in index ' + index + ') expected ' + expression.inspect() + ' but got ' + element.inspect());
}.bind(this)) && this.pass();
},
assertElementMatches: function(element, expression) {
this.assertElementsMatch([element], expression);
},
benchmark: function(operation, iterations) {
var startAt = new Date();
(iterations || 1).times(operation);
var timeTaken = ((new Date())-startAt);
this.info((arguments[2] || 'Operation') + ' finished ' +
iterations + ' iterations in ' + (timeTaken/1000)+'s' );
lib/Alien/GvaScript/lib/unittest.js view on Meta::CPAN
var timeTaken = ((new Date())-startAt);
this.info((arguments[2] || 'Operation') + ' finished ' +
iterations + ' iterations in ' + (timeTaken/1000)+'s' );
return timeTaken;
}
};
Test.Unit.Testcase = Class.create();
Object.extend(Object.extend(Test.Unit.Testcase.prototype, Test.Unit.Assertions.prototype), {
initialize: function(name, test, setup, teardown) {
Test.Unit.Assertions.prototype.initialize.bind(this)();
this.name = name;
if(typeof test == 'string') {
test = test.gsub(/(\.should[^\(]+\()/,'#{0}this,');
test = test.gsub(/(\.should[^\(]+)\(this,\)/,'#{1}(this)');
this.test = function() {
eval('with(this){'+test+'}');
}
} else {
this.test = test || function() {};
lib/Alien/GvaScript/lib/unittest.js view on Meta::CPAN
this.timeToWait = 1000;
},
wait: function(time, nextPart) {
this.isWaiting = true;
this.test = nextPart;
this.timeToWait = time;
},
run: function() {
try {
try {
if (!this.isWaiting) this.setup.bind(this)();
this.isWaiting = false;
this.test.bind(this)();
} finally {
if(!this.isWaiting) {
this.teardown.bind(this)();
}
}
}
catch(e) { this.error(e); }
}
});
// *EXPERIMENTAL* BDD-style testing to please non-technical folk
// This draws many ideas from RSpec http://rspec.rubyforge.org/
src/autoCompleter.js view on Meta::CPAN
this.dropdownDiv = null;
// array to store running ajax requests
// of same autocompleter but for different input element
this._runningAjax = [];
this.setdatasource(datasource);
// prepare an initial keymap; will be registered at first
// focus() event; then a second set of keymap rules is pushed/popped
// whenever the choice list is visible
var basicHandler = this._keyDownHandler.bindAsEventListener(this);
var detectedKeys = /^(BACKSPACE|DELETE|KP_.*|.)$/;
// catch any single char, plus some editing keys
var basicMap = { DOWN: this._ArrowDownHandler.bindAsEventListener(this),
REGEX: [[null, detectedKeys, basicHandler]] };
this.keymap = new GvaScript.KeyMap(basicMap);
// prepare some stuff to be reused when binding to inputElements
this.reuse = {
onblur : this._blurHandler.bindAsEventListener(this),
onclick : this._clickHandler.bindAsEventListener(this)
};
}
GvaScript.AutoCompleter.prototype = {
//----------------------------------------------------------------------
// PUBLIC METHODS
//----------------------------------------------------------------------
// autocomplete : called when the input element gets focus; binds
// the autocompleter to the input element
autocomplete: function(elem) {
elem = $(elem);// in case we got an id instead of an element
if (!elem) throw new Error("attempt to autocomplete a null element");
// elem is readonly => no action
if (elem.getAttribute('readonly') || elem.readOnly) return;
// if already bound, no more work to do
if (elem === this.inputElement) return;
// bind to the element; if first time, also register the event handlers
this.inputElement = elem;
if (!elem._autocompleter) {
elem._autocompleter = this;
this.keymap.observe("keydown", elem, Event.stopNone);
Element.observe(elem, "blur", this.reuse.onblur);
Element.observe(elem, "click", this.reuse.onclick);
// prevent browser builtin autocomplete behaviour
elem.writeAttribute("autocomplete", "off");
}
src/autoCompleter.js view on Meta::CPAN
pos.top -= this.observed_scroll.scrollTop - this.currentScrollTop;
pos.left -= this.observed_scroll.scrollLeft;
this.dropdownDiv.style.top = pos.top + "px";
this.dropdownDiv.style.left = pos.left + "px";
}
this.currentScrollTop = this.observed_scroll.scrollTop;
this.currentScrollLeft = this.observed_scroll.scrollLeft;
}
Event.observe(elem, 'scroll',
correct_dropdown_position.bindAsEventListener(this));
},
//----------------------------------------------------------------------
// PRIVATE METHODS
//----------------------------------------------------------------------
_updateChoicesFromAjax: function (val_to_complete, continuation) {
// copies into local variables, needed for closures below (can't rely on
src/autoCompleter.js view on Meta::CPAN
var matchPrefix = function(choice) {
var value;
switch(typeof choice) {
case "object" : value = choice[this.options.valueField]; break;
case "number" : value = choice.toString(10); break;
case "string" : value = choice; break;
default: throw new Error("unexpected type of value");
}
return value.search(regex) > -1;
};
continuation(this._datasource.select(matchPrefix.bind(this)));
}
},
_updateChoices : function (continuation) {
var value = this._getValueToComplete();
// if (window.console) console.log('updateChoices', value);
this._updateChoicesHandler(value, continuation);
src/autoCompleter.js view on Meta::CPAN
}, this.inputElement);
if(! return_value) {
this.inputElement.style.backgroundColor = this.options.colorIllegal;
this._updateDependentFields(this.inputElement, null);
}
}
// otherwise get choices and then inspect status (maybe asynchronously)
else {
this._updateChoices(this._fireFinalStatus.bind(this,
this.inputElement));
}
}
this.fireEvent("Leave", this.inputElement);
this.inputElement = null;
},
_fireFinalStatus: function (inputElement, choices) {
// NOTE: takes inputElement and choices as arguments, because it might be
src/autoCompleter.js view on Meta::CPAN
// invalidate previous lists of choices because value may have changed
this.choices = null;
this._removeDropdownDiv();
// cancel pending timeouts because we create a new one
if (this._timeoutId) clearTimeout(this._timeoutId);
this._timeLastKeyDown = (new Date()).getTime();
// if (window.console) console.log('keyDown', this._timeLastKeyDown, event.keyCode);
this._timeoutId = setTimeout(this._checkNewValue.bind(this),
this.options.checkNewValDelay);
// do NOT stop the event here : give back control so that the standard
// browser behaviour can update the value; then come back through a
// timeout to update the Autocompleter
},
_checkNewValue: function() {
src/autoCompleter.js view on Meta::CPAN
this.inputElement.style.backgroundColor = ""; // remove colorIllegal
if (this.options.autoSuggest)
this._displayChoices();
}
else if (this.options.strict && (!this.options.blankOK)) {
this.inputElement.style.backgroundColor = this.options.colorIllegal;
}
};
// now call updateChoices (which then will call the continuation)
this._updateChoices(continuation.bind(this));
}
},
// return the value to be completed
// TODO : for multivalued, should return the value under the cursor,
// instead returning sytematically the last value
_getValueToComplete : function(value) {
// NOTE: the explicit value as argument is only used from
//_fireFinalStatus(), when we can no longer rely on
src/autoCompleter.js view on Meta::CPAN
// maxHeight cannot be simulated untill displayChoices
if (navigator.userAgent.match(/\bMSIE [456]\b/)) {
div.style.width = this.options.minWidth + "px";
}
// mouseenter and mouseleave events to control
// whether autocompleter has been blurred
var elem = this.inputElement;
div.observe('mouseenter', function(e) {
Element.stopObserving(elem, "blur", this.reuse.onblur);
}.bind(this));
div.observe('mouseleave', function(e) {
Element.observe(elem, "blur", this.reuse.onblur);
}.bind(this));
return this.dropdownDiv = div;
},
_displayChoices: function() {
// if no choices are ready, can't display anything
if (!this.choices) return;
src/choiceList.js view on Meta::CPAN
// handy vars
this.hasPaginator = this.options.paginator != null;
this.pageSize = (
// the step size of the paginator if any
(this.hasPaginator && this.options.paginator.options.step)
||
// scroll count
this.options.scrollCount
);
// prepare some stuff to be reused when binding to inputElements
this.reuse = {
onmouseover : this._listOverHandler.bindAsEventListener(this),
onclick : this._clickHandler.bindAsEventListener(this),
ondblclick : this._dblclickHandler.bindAsEventListener(this),
navigationRules: {
DOWN: this._highlightDelta.bindAsEventListener(this, 1),
UP: this._highlightDelta.bindAsEventListener(this, -1),
PAGE_DOWN: this._highlightDelta.bindAsEventListener(this, this.pageSize),
PAGE_UP: this._highlightDelta.bindAsEventListener(this, -this.pageSize),
HOME: this._jumpToIndex.bindAsEventListener(this, 0),
END: this._jumpToIndex.bindAsEventListener(this, 99999),
RETURN: this._returnHandler .bindAsEventListener(this),
ESCAPE: this._escapeHandler .bindAsEventListener(this)
}
};
if(this.hasPaginator) {
// next/prev page
this.reuse.navigationRules.RIGHT
= this._highlightDelta.bindAsEventListener(this, this.pageSize)
this.reuse.navigationRules.LEFT
= this._highlightDelta.bindAsEventListener(this, -this.pageSize);
// first/last page
this.reuse.navigationRules.C_HOME
= this._jumpToPage.bindAsEventListener(this, 0);
this.reuse.navigationRules.C_END
= this._jumpToPage.bindAsEventListener(this, 99999);
}
};
GvaScript.ChoiceList.prototype = {
//----------------------------------------------------------------------
// PUBLIC METHODS
//----------------------------------------------------------------------
destroy: function() {
src/choiceList.js view on Meta::CPAN
}
return this.options.htmlWrapper(html);
},
choiceElementHTML: function(label, id) {
return "<" + this.options.choiceItemTagName + " class='"
+ this.classes.choiceItem + "' id='" + id + "'>"
+ label + "</" + this.options.choiceItemTagName + ">";
},
fireEvent: GvaScript.fireEvent, // must be copied here for binding "this"
//----------------------------------------------------------------------
// PRIVATE METHODS
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// conversion index <=> HTMLElement
//----------------------------------------------------------------------
src/customButtons.js view on Meta::CPAN
this.container.insert(_render(this.options));
this.btnContainer = $(this.options.id); // the outer <span/>
this.btnElt = this.btnContainer.down('.btn'); // the <button/>
// setting inline style on the button container
if(typeof this.options.style != 'undefined') {
this.btnContainer.setStyle(this.options.style);
}
// setting tabindex on button if any
if(typeof this.options.tabindex != 'undefined') {
this.btnElt.writeAttribute('tabindex', this.options.tabindex);
}
this.btnElt.observe('click', this.options.callback.bind(this.btnElt));
} catch (e) {}
}
}
}
}());
GvaScript.CustomButtons.ButtonNavigation = Class.create();
Object.extend(GvaScript.CustomButtons.ButtonNavigation.prototype, function() {
// private members
var bcss = CSSPREFIX();
src/customButtons.js view on Meta::CPAN
// support focus function on span.buttonContainer
btnContainer.focus = function() {btn.focus();}
}
if(typeof btn == 'undefined') return;
}, this);
this.container.register('button.btn', 'focus', function(e) {
this.select.call(this, e._target.up('.'+bcss+'-btn-container'));
}.bind(this));
this.container.register('button.btn', 'blur', function(e) {
this.select.call(this, null);
}.bind(this));
}
// public members
return {
destroy: function() {
// test that element still in DOM
if(this.container) this.container.unregister();
this.keymap.destroy();
},
initialize: function(container, options) {
src/customButtons.js view on Meta::CPAN
flashClassName : 'flash',
keymap : null,
selectFirstBtn : true,
className : bcss+'-button'
};
this.options = Object.extend(defaults, options || {});
this.container = $(container);
// initializing the keymap
var keyHandlers = {
LEFT: _leftHandler .bindAsEventListener(this),
RIGHT: _rightHandler .bindAsEventListener(this),
TAB: _tabHandler .bindAsEventListener(this),
S_TAB: _shiftTabHandler .bindAsEventListener(this),
HOME: _homeHandler .bindAsEventListener(this),
END: _endHandler .bindAsEventListener(this)
};
this.keymap = new GvaScript.KeyMap(keyHandlers);
this.keymap.observe("keydown", container, {
preventDefault:false,
stopPropagation:false
});
// get all buttons of designated className regardless of their
// visibility jump over hidden ones when navigating
this.buttons = this.container.select('.'+this.options.className);
_addHandlers.call(this);
if (this.options.selectFirstBtn) {
if(firstButObj = this.firstBtn()) {
this.select(firstButObj);
}
// set the focus on the container anyways so that the focus
// gets trasferred successfully to windows with empty
// actionsbar
else {
this.container.writeAttribute('tabindex', 0);
this.container.focus();
}
}
},
select: function (btn) {
var previousBtn = this.selectedBtn || null;
if (previousBtn === btn) return; // selection already handled
// blur the previously selected button
if (previousBtn) {
src/form.js view on Meta::CPAN
onBeforeDestroy : Prototype.emptyFunction // called right before form.destroy
}
this.options = Object.extend(defaults, options || {});
// attaching submitMethod to form.onsubmit event
this.formElt.observe('submit', function() {
// submit method only called if
// onBeforeSubmit handler doesnot return false
if ( this.fire('BeforeSubmit') ) return this.fire('Submit');
}.bind(this));
// initializing watchers
$A(this.options.registry).each(function(w) {
this.register(w[0], w[1], w[2]);
}, this);
var that = this;
// workaround as change event doesnot bubble in IE
this.formElt.observe('value:change', function(event) {
if(event.memo.handler) {
src/grid.js view on Meta::CPAN
this.toolbar_container.insert(this.paginatorbar_container);
this.toolbar_container.insert(this.actionsbar_container);
this.dto = _compileDTO(this.options.dto);
this.paginator = new GvaScript.Paginator(
this.datasource, {
list_container : this.grid_container,
links_container : this.paginatorbar_container,
method : this.options.method,
onSuccess : this.receiveRequest.bind(this),
parameters : this.dto,
step : this.limit,
timeoutAjax : this.options.requestTimeout,
errorMsg : this.options.errorMsg,
lazy : true
}
);
if(! (recycled = this.grid_container.choiceList) ) {
this.choiceList = new GvaScript.ChoiceList([], {
paginator : this.paginator,
mouseovernavi : false,
classes : {'choiceHighlight': "hilite"},
choiceItemTagName : "tr",
grabfocus : false,
htmlWrapper : this.gridWrapper.bind(this)
});
this.choiceList_initialized = false;
}
// recycle the previously created choiceList
else {
this.choiceList = recycled;
this.choiceList.options.htmlWrapper = this.gridWrapper.bind(this);
this.choiceList.options.paginator = this.paginator;
this.choiceList_initialized = true;
}
this.choiceList.onCancel = this.options.onCancel;
this.choiceList.onPing = this.pingWrapper.bind(this);
this.paginator.loadContent();
this.grid_container.addClassName(bcss+'-widget');
this.grid_container.store('widget', this);
GvaScript.Grids.register(this);
},
getId: function() {
src/keyMap.js view on Meta::CPAN
observe: function(eventType, elem, options) {
this.eventType = eventType || 'keydown';
this.elem = elem || document;
// "Shift" modifier usually does not make sense for keypress events
if (eventType == 'keypress' && !options)
options = {ignoreShift: true};
this.options = Class.checkOptions(Event.stopNone, this.options || {});
this.eventHandler = this.eventHandler.bindAsEventListener(this);
Event.observe(this.elem, this.eventType, this.eventHandler);
},
_findInStack: function(event, stack) {
for (var i = stack.length - 1; i >= 0; i--) {
var rules = stack[i];
// trick to differentiate between C_9 (digit) and C_09 (TAB)
var keyCode = event.keyCode>9 ? event.keyCode : ("0"+event.keyCode);
src/paginator.js view on Meta::CPAN
function _addPaginationElts() {
// append the pagination buttons
this.links_container.insert(pagination_buttons);
this.first = this.links_container.down('.first');
this.last = this.links_container.down('.last');
this.forward = this.links_container.down('.forward');
this.back = this.links_container.down('.back');
this.textElem = this.links_container.down('.text');
this.first.observe ('click', this.getFirstPage.bind(this));
this.last.observe ('click', this.getLastPage.bind(this));
this.back.observe ('click', this.getPrevPage.bind(this));
this.forward.observe('click', this.getNextPage.bind(this));
}
return {
destroy: function() {
this.first.stopObserving();
this.last.stopObserving();
this.back.stopObserving();
this.forward.stopObserving();
},
initialize: function(url, options) {
src/paginator.js view on Meta::CPAN
this.list_container.update(new Element('div', {'class': bcss+'-loading'}));
new Ajax.Request(url, {
evalJSON: 'force', // force evaluation of response into responseJSON
method: this.options.method,
parameters: this.options.parameters,
requestTimeout: this.options.timeoutAjax * 1000,
onTimeout: function(req) {
this._executing = false;
this.list_container.update(this.options.errorMsg);
}.bind(this),
// on s'attend à avoir du JSON en retour
onFailure: function(req) {
this._executing = false;
var answer = req.responseJSON;
var msg = answer.error.message || this.options.errorMsg;
this.list_container.update(msg);
}.bind(this),
onSuccess: function(req) {
this._executing = false;
var answer = req.responseJSON;
if(answer) {
var nb_displayed_records = this.options.onSuccess(answer);
this.total = answer.total; // total number of records
this.end_index = Math.min(this.total, this.index+nb_displayed_records-1); // end index of records on current page
this.textElem.innerHTML = (this.total > 0)?
this.index + " à " + this.end_index + " de " + this.total: '0';
_toggleNavigatorsVisibility.apply(this);
}
}.bind(this)
});
}
}
}());
src/protoExtensions.js view on Meta::CPAN
var classname = options.classname || 'flash';
element._IS_FLASHING = true;
var endFlash = function() {
this.removeClassName(classname);
this._IS_FLASHING = false;
};
element.addClassName(classname);
setTimeout(endFlash.bind(element), duration);
}
});
// utilities for hash
// expands flat hash into a multi-level deep hash
// javascript version of Perl CGI::Expand::expand_hash
Hash.expand = function(flat_hash) {
var tree = {};
src/treeNavigator.js view on Meta::CPAN
// add buttons and tabIndex to labels
this.initSubTree(elem);
// tree-wide navigation handlers
this._addHandlers();
// tree-wide tabbing handlers
this._addTabbingBehaviour();
// initializing the keymap
var keyHandlers = {
DOWN: this._downHandler .bindAsEventListener(this),
UP: this._upHandler .bindAsEventListener(this),
LEFT: this._leftHandler .bindAsEventListener(this),
RIGHT: this._rightHandler .bindAsEventListener(this),
KP_PLUS: this._kpPlusHandler .bindAsEventListener(this),
KP_MINUS: this._kpMinusHandler.bindAsEventListener(this),
KP_STAR: this._kpStarHandler .bindAsEventListener(this),
KP_SLASH: this._kpSlashHandler.bindAsEventListener(this),
C_R: this._ctrl_R_handler.bindAsEventListener(this),
RETURN: this._ReturnHandler .bindAsEventListener(this),
C_KP_STAR: this._showAll .bindAsEventListener(this, true),
C_KP_SLASH: this._showAll .bindAsEventListener(this, false),
HOME: this._homeHandler .bindAsEventListener(this),
END: this._endHandler .bindAsEventListener(this),
C_PAGE_UP : this._ctrlPgUpHandler .bindAsEventListener(this),
C_PAGE_DOWN: this._ctrlPgDownHandler.bindAsEventListener(this),
REGEX : [[ "", /^\w$/, this._charHandler.bindAsEventListener(this) ]]
};
if (this.options.tabIndex >= 0)
keyHandlers["TAB"] = this._tabHandler.bindAsEventListener(this);
// handlers for ctrl_1, ctrl_2, etc. to open the tree at that level
var numHandler = this._chooseLevel.bindAsEventListener(this);
$R(1, 9).each(function(num){keyHandlers["C_" + num] = numHandler});
// tabIndex for the tree element
elem.tabIndex = Math.max(elem.tabIndex, this.options.treeTabIndex);
this._clear_quick_navi();
if (options.keymap) {
this.keymap = options.keymap;
this.keymap.rules.push(keyHandlers);
src/treeNavigator.js view on Meta::CPAN
if(! label.hasAttribute('hasFocus'))
label.focus();
}
}
}
// cancel if there was any select execution pending
if (this._selectionTimeoutId) clearTimeout(this._selectionTimeoutId);
// register code to call the selection handlers after some delay
var callback = this._selectionTimeoutHandler.bind(this, previousNode);
this._selectionTimeoutId =
setTimeout(callback, this.options.selectDelay);
},
scrollTo: function(node, with_content) {
if(!node) return;
var container = this.options.scrollingContainer;
if(typeof container == 'string') {
container = $(container);
src/treeNavigator.js view on Meta::CPAN
if (this.isLeaf(node)) return null;
this._assertNode(node, 'content: arg type');
return Element.navigateDom(node.lastChild, 'previousSibling',
this.classes.content);
},
parentNode: function (node) {
this._assertNodeOrLeaf(node, 'parentNode: arg type');
return Element.navigateDom(
node.parentNode, 'parentNode', this.classes.node,
this.isRootElement.bind(this));
},
nextSibling: function (node) {
this._assertNodeOrLeaf(node, 'nextSibling: arg type');
return Element.navigateDom(node.nextSibling, 'nextSibling',
this.classes.nodeOrLeaf);
},
previousSibling: function (node) {
src/treeNavigator.js view on Meta::CPAN
return this.lastVisibleSubnode(node);
}
// if no previous sibling
return this.parentNode(node_init);
},
enclosingNode: function (elem) {
return Element.navigateDom(
$(elem), 'parentNode', this.classes.nodeOrLeaf,
this.isRootElement.bind(this));
},
// flash the node
flash: function (node) {
var label = this.label(node);
ASSERT(label, "node has no label");
label.flash({duration: 200});
},
src/treeNavigator.js view on Meta::CPAN
ASSERT(elem && Element.hasAnyClass(elem, this.classes.node), msg);
},
_assertNodeOrLeaf: function(elem, msg) {
ASSERT(elem && Element.hasAnyClass(elem, this.classes.nodeOrLeaf), msg);
},
_addHandlers: function() {
Event.observe(
this.rootElement, "mouseover",
this._treeMouseOverHandler.bindAsEventListener(this));
Event.observe(
this.rootElement, "mouseout",
this._treeMouseOutHandler.bindAsEventListener(this));
Event.observe(
// observing "mouseup" instead of "click", because "click"
// on MSIE8 only fires when there is a tabindex
this.rootElement, "mouseup",
this._treeClickHandler.bindAsEventListener(this));
Event.observe(
this.rootElement, "dblclick",
this._treeDblClickHandler.bindAsEventListener(this));
},
_removeHandlers: function() {
this.rootElement.stopObserving();
this.rootElement.unregister();
},
//-----------------------------------------------------
// mouse handlers
//-----------------------------------------------------
src/treeNavigator.js view on Meta::CPAN
Event.stop(event);
}
},
_buttonClicked : function(node) {
var method = this.isClosed(node) ? this.open : this.close;
method.call(this, node);
if (this.options.selectOnButtonClick) {
window.setTimeout(function() {
this.select(node);
}.bind(this), 0);
}
},
_labelClicked : function(node, event) {
// situation before the mousedown
var is_selected = (this.selectedNode == node);
var is_first_click = !is_selected;
// select node if it wasn't
if (!is_selected) this.select(node);
src/treeNavigator.js view on Meta::CPAN
var blur_handler = function(e) {
var label = e._target;
label.removeAttribute('hasFocus');
// deselect the previously selected node
treeNavigator.select(null);
};
// focus and blur do not bubble
// workaround per browser
focus_handler = focus_handler.bindAsEventListener(this);
blur_handler = blur_handler.bindAsEventListener(this);
this.rootElement.register('.'+this.classes.label, 'focus', focus_handler);
this.rootElement.register('.'+this.classes.label, 'blur', blur_handler );
},
//-----------------------------------------------------
// timeout handler for firing Select/Deselect events
//-----------------------------------------------------
src/treeNavigator.js view on Meta::CPAN
}
// initialize labels_array on start of quick-search
// (mandate of dynamic trees)
else {
this.labels_array = this.rootElement.select('.'+this.classes.label);
}
// activate a new timer
this._quick_navi_mode = window.setTimeout(function() {
this._clear_quick_navi();
}.bind(this), 800);
var selectedLabel = this.label(selectedNode);
var selectedIndex = this.labels_array.indexOf(selectedLabel);
// partitions the labels array into 2 arrays
// 1: preceeding labels & selectedNode if not in quick_navi_mode
// 2: following labels & selectedNode if in quick_navi_mode
var labels = this.labels_array.partition(function(l, index) {
// quick-navi mode
if(is_quick_navi_mode) return index < selectedIndex;
else return index <= selectedIndex;
test/functional/form/effects.js view on Meta::CPAN
break;
}
effect.startOn += timestamp;
effect.finishOn += timestamp;
if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
this.effects.push(effect);
if (!this.interval)
this.interval = setInterval(this.loop.bind(this), 15);
},
remove: function(effect) {
this.effects = this.effects.reject(function(e) { return e==effect });
if (this.effects.length == 0) {
clearInterval(this.interval);
this.interval = null;
}
},
loop: function() {
var timePos = new Date().getTime();
test/functional/form/effects.js view on Meta::CPAN
effect.event('afterFinish');
});
}
});
Effect.Tween = Class.create(Effect.Base, {
initialize: function(object, from, to) {
object = Object.isString(object) ? $(object) : object;
var args = $A(arguments), method = args.last(),
options = args.length == 5 ? args[3] : null;
this.method = Object.isFunction(method) ? method.bind(object) :
Object.isFunction(object[method]) ? object[method].bind(object) :
function(value) { object[method] = value };
this.start(Object.extend({ from: from, to: to }, options || { }));
},
update: function(position) {
this.method(position);
}
});
Effect.Event = Class.create(Effect.Base, {
initialize: function() {
test/functional/form/effects.js view on Meta::CPAN
}, arguments[2] || { });
this.start(options);
},
setup: function() {
this.restoreAfterFinish = this.options.restoreAfterFinish || false;
this.elementPositioning = this.element.getStyle('position');
this.originalStyle = { };
['top','left','width','height','fontSize'].each( function(k) {
this.originalStyle[k] = this.element.style[k];
}.bind(this));
this.originalTop = this.element.offsetTop;
this.originalLeft = this.element.offsetLeft;
var fontSize = this.element.getStyle('font-size') || '100%';
['em','px','%','pt'].each( function(fontSizeType) {
if (fontSize.indexOf(fontSizeType)>0) {
this.fontSize = parseFloat(fontSize);
this.fontSizeType = fontSizeType;
}
}.bind(this));
this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
this.dims = null;
if (this.options.scaleMode=='box')
this.dims = [this.element.offsetHeight, this.element.offsetWidth];
if (/^content/.test(this.options.scaleMode))
this.dims = [this.element.scrollHeight, this.element.scrollWidth];
if (!this.dims)
this.dims = [this.options.scaleMode.originalHeight,
test/functional/form/effects.js view on Meta::CPAN
this.oldStyle = { };
if (!this.options.keepBackgroundImage) {
this.oldStyle.backgroundImage = this.element.getStyle('background-image');
this.element.setStyle({backgroundImage: 'none'});
}
if (!this.options.endcolor)
this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
if (!this.options.restorecolor)
this.options.restorecolor = this.element.getStyle('background-color');
// init color calculations
this._base = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this));
this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this));
},
update: function(position) {
this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){
return m+((this._base[i]+(this._delta[i]*position)).round().toColorPart()); }.bind(this)) });
},
finish: function() {
this.element.setStyle(Object.extend(this.oldStyle, {
backgroundColor: this.options.restorecolor
}));
}
});
Effect.ScrollTo = function(element) {
var options = arguments[1] || { },
test/functional/form/effects.js view on Meta::CPAN
}, options)
);
};
Effect.Pulsate = function(element) {
element = $(element);
var options = arguments[1] || { };
var oldOpacity = element.getInlineOpacity();
var transition = options.transition || Effect.Transitions.sinoidal;
var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) };
reverser.bind(transition);
return new Effect.Opacity(element,
Object.extend(Object.extend({ duration: 2.0, from: 0,
afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
}, options), {transition: reverser}));
};
Effect.Fold = function(element) {
element = $(element);
var oldStyle = {
top: element.style.top,
test/functional/form/effects.js view on Meta::CPAN
unit = (components.length == 3) ? components[2] : null;
}
var originalValue = this.element.getStyle(property);
return {
style: property.camelize(),
originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0),
targetValue: unit=='color' ? parseColor(value) : value,
unit: unit
};
}.bind(this)).reject(function(transform){
return (
(transform.originalValue == transform.targetValue) ||
(
transform.unit != 'color' &&
(isNaN(transform.originalValue) || isNaN(transform.targetValue))
)
)
});
},
update: function(position) {
test/functional/form/effects.js view on Meta::CPAN
},
addTracks: function(tracks){
tracks.each(function(track){
track = $H(track);
var data = track.values().first();
this.tracks.push($H({
ids: track.keys().first(),
effect: Effect.Morph,
options: { style: data }
}));
}.bind(this));
return this;
},
play: function(){
return new Effect.Parallel(
this.tracks.map(function(track){
var ids = track.get('ids'), effect = track.get('effect'), options = track.get('options');
var elements = [$(ids) || $$(ids)].flatten();
return elements.map(function(e){ return new effect(e, Object.extend({ sync:true }, options)) });
}).flatten(),
this.options
test/functional/form/validation.js view on Meta::CPAN
this.options = Object.extend({
onSubmit : true,
stopOnFirst : false,
immediate : false,
focusOnError : true,
useTitles : false,
onFormValidate : function(result, form) {},
onElementValidate : function(result, elm) {}
}, options || {});
this.form = $(form);
if(this.options.onSubmit) Event.observe(this.form,'submit',this.onSubmit.bind(this),false);
if(this.options.immediate) {
var useTitles = this.options.useTitles;
var callback = this.options.onElementValidate;
Form.getElements(this.form).each(function(input) { // Thanks Mike!
Event.observe(input, 'blur', function(ev) { Validation.validate(Event.element(ev),{useTitle : useTitles, onElementValidate : callback}); });
});
}
},
onSubmit : function(ev){
if(!this.validate()) Event.stop(ev);
test/functional/keyMap/basic.html view on Meta::CPAN
<h1>Keymap Example</h1>
<div id="d1">Use arrow keys to move the cursor in cells.</div>
<div id="d2">Press RETURN to color a cell.</div>
<div id="d3">Type digits or Ctrl-vowels to insert content in cells.</div>
<div id="d4">Try combinations <tt>Ctrl-X A</tt>, <tt>Ctrl-X B</tt>,
<tt>Ctrl-X R K</tt>, <tt>Ctrl-X R O</tt>.</div>
<br/>
<table id="table" border="1" tabindex="0">
<tr>
<td> </td><td>1</td><td class="rborder"> </td><td> </td><td> </td>
<td class="rborder"> </td><td> </td><td> </td><td> </td>
</tr>
<tr>
<td> </td><td>4</td><td class="rborder">2</td><td> </td><td> </td>
<td class="rborder"> </td><td> </td><td> </td><td> </td>
</tr>
test/functional/treeNavigator/dropdownMenu.html view on Meta::CPAN
var y = Event.pointerY(event);
if (Position.within($('menu'), x, y))
$('textbox').focus();
else
hideMenu();
}
function setup() {
var textbox = $('textbox');
// bind event handlers to the textbox
textboxKeymap = new GvaScript.KeyMap({DOWN:showMenu,
ESCAPE: hideMenu});
textboxKeymap.observe('keydown', textbox, {preventDefault:false,
stopPropagation:false});
Event.observe(textbox, "click", maybeToggleMenu);
Event.observe(textbox, "blur", maybeBackFocus);
with (textbox.style) {
backgroundImage = "url(special_icons/navclose.gif)";
backgroundRepeat = "no-repeat";
test/unit/grid.html view on Meta::CPAN
<script src="../../lib/Alien/GvaScript/lib/GvaScript.js" type="text/javascript"></script>
<title>GvaScript Unit Tests</title>
</head>
<body>
<h1>Unit Tests :: GvaScript/grid.js </h1>
<p>Tests for methods included in Grid</p>
<!-- Test Log output -->
<div id="testlog">...</div>
<div class="wrapper" style="height:220px;">
<div id="grid" tabindex="0"></div>
<div id="grid_toolbar" style="height:28px"></div>
</div>
<textarea id="gridlog"></textarea>
<script type="text/javascript" language="javascript" charset="iso-8859-1">
// <![CDATA[
new Test.Unit.Runner({
// test initialization of Grid component
testInit: function() { with(this) {
var url = "resources/_grid_result.json";
test/unittest.js view on Meta::CPAN
new Test.Unit.Testcase(
this.options.context ? ' -> ' + this.options.titles[testcase] : testcase,
testcases[testcase], testcases["setup"], testcases["teardown"]
));
}
}
}
}
this.currentTest = 0;
this.logger = new Test.Unit.Logger(this.options.testLog);
setTimeout(this.runTests.bind(this), 1000);
},
parseResultsURLQueryParameter: function() {
return window.location.search.parseQuery()["resultsURL"];
},
parseTestsQueryParameter: function(){
if (window.location.search.parseQuery()["tests"]){
return window.location.search.parseQuery()["tests"].split(',');
};
},
// Returns:
test/unittest.js view on Meta::CPAN
this.postResults();
this.logger.summary(this.summary());
return;
}
if(!test.isWaiting) {
this.logger.start(test.name);
}
test.run();
if(test.isWaiting) {
this.logger.message("Waiting for " + test.timeToWait + "ms");
setTimeout(this.runTests.bind(this), test.timeToWait || 1000);
} else {
this.logger.finish(test.status(), test.summary());
this.currentTest++;
// tail recursive, hopefully the browser will skip the stackframe
this.runTests();
}
},
summary: function() {
var assertions = 0;
var failures = 0;
test/unittest.js view on Meta::CPAN
assertElementsMatch: function() {
var expressions = $A(arguments), elements = $A(expressions.shift());
if (elements.length != expressions.length) {
this.fail('assertElementsMatch: size mismatch: ' + elements.length + ' elements, ' + expressions.length + ' expressions');
return false;
}
elements.zip(expressions).all(function(pair, index) {
var element = $(pair.first()), expression = pair.last();
if (element.match(expression)) return true;
this.fail('assertElementsMatch: (in index ' + index + ') expected ' + expression.inspect() + ' but got ' + element.inspect());
}.bind(this)) && this.pass();
},
assertElementMatches: function(element, expression) {
this.assertElementsMatch([element], expression);
},
benchmark: function(operation, iterations) {
var startAt = new Date();
(iterations || 1).times(operation);
var timeTaken = ((new Date())-startAt);
this.info((arguments[2] || 'Operation') + ' finished ' +
iterations + ' iterations in ' + (timeTaken/1000)+'s' );
test/unittest.js view on Meta::CPAN
var timeTaken = ((new Date())-startAt);
this.info((arguments[2] || 'Operation') + ' finished ' +
iterations + ' iterations in ' + (timeTaken/1000)+'s' );
return timeTaken;
}
};
Test.Unit.Testcase = Class.create();
Object.extend(Object.extend(Test.Unit.Testcase.prototype, Test.Unit.Assertions.prototype), {
initialize: function(name, test, setup, teardown) {
Test.Unit.Assertions.prototype.initialize.bind(this)();
this.name = name;
if(typeof test == 'string') {
test = test.gsub(/(\.should[^\(]+\()/,'#{0}this,');
test = test.gsub(/(\.should[^\(]+)\(this,\)/,'#{1}(this)');
this.test = function() {
eval('with(this){'+test+'}');
}
} else {
this.test = test || function() {};
test/unittest.js view on Meta::CPAN
this.timeToWait = 1000;
},
wait: function(time, nextPart) {
this.isWaiting = true;
this.test = nextPart;
this.timeToWait = time;
},
run: function() {
try {
try {
if (!this.isWaiting) this.setup.bind(this)();
this.isWaiting = false;
this.test.bind(this)();
} finally {
if(!this.isWaiting) {
this.teardown.bind(this)();
}
}
}
catch(e) { this.error(e); }
}
});
// *EXPERIMENTAL* BDD-style testing to please non-technical folk
// This draws many ideas from RSpec http://rspec.rubyforge.org/