Alien-GvaScript

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

  - upgrade to prototype.js v1.7

1.21 18.01.2010
  - bug in Builder, Gvascript.js was written to wrong location
  
1.20   07.01.2009
  - Element.autoScroll : fix scroll amount when the scrolling block has
    an offsetTop > 0
  - removed PAGE_UP/DOWN handlers in TreeNavigator -- let the browser deal 
    with those
  - treeNavigator select() has an additional param "prevent_autoscroll"
  - treeNavigator autoscroll only active through kbd, not through click
  - treeNavigator observes "mouseup" (instead of mousedown or click)
  - autoCompleter bug fix on detach (stop observing "click")
  - protoExtensions : removed RegExp.escape() (now in prototype.js)
  - autoCompleter div, display above only if enough vertical space
  - autoCompleter : code layout improvements

1.18 13.10.2009
  - fix some minor doc glitches released in 1.17

MANIFEST  view on Meta::CPAN

lib/Alien/GvaScript/lib/GvaScript.js
lib/Alien/GvaScript/lib/images/formulaire/ajax_loading.gif
lib/Alien/GvaScript/lib/images/paginator/bg.gif
lib/Alien/GvaScript/lib/images/paginator/glass-bg-n-2.gif
lib/Alien/GvaScript/lib/images/paginator/glass-bg-n.gif
lib/Alien/GvaScript/lib/images/paginator/glass-bg.gif
lib/Alien/GvaScript/lib/images/paginator/page-first.gif
lib/Alien/GvaScript/lib/images/paginator/page-last.gif
lib/Alien/GvaScript/lib/images/paginator/page-next.gif
lib/Alien/GvaScript/lib/images/paginator/page-prev.gif
lib/Alien/GvaScript/lib/images/paginator/selector.gif
lib/Alien/GvaScript/lib/images/search-small.png
lib/Alien/GvaScript/lib/minus.gif
lib/Alien/GvaScript/lib/plus.gif
lib/Alien/GvaScript/lib/prototype.js
lib/Alien/GvaScript/lib/unittest.js
lib/Alien/GvaScript/Paginator.pod
lib/Alien/GvaScript/ProtoExtensions.pod
lib/Alien/GvaScript/Repeat.pod
lib/Alien/GvaScript/TreeNavigator.pod
MANIFEST			This list of files

MANIFEST  view on Meta::CPAN

test/images/bg.gif
test/images/btn_sprite.gif
test/images/delete.png
test/images/dot.gif
test/images/glass-bg.gif
test/images/GvaScript.css
test/images/minus.gif
test/images/paginator-sprite.png
test/images/plus.gif
test/images/search-small.png
test/images/selector.gif
test/images/tn_sprite.png
test/test.css
test/unit/boilerplate.html
test/unit/customButtons.html
test/unit/grid.html
test/unit/index.html
test/unit/protoExtensions.html
test/unit/resources/_grid_result.json
test/unit/toc.html
test/unittest.js

doc/html/AutoCompleter.html  view on Meta::CPAN

  </div>
  <div class="TN_node" id="Format_of_suggestions_returned_by_datasources">
    <h4 class="TN_label">Format of suggestions returned by datasources</h4>
    <div class="TN_content">
      <p>Datasources should return a list of suggestions in the form
of a Javascript array (in case of Ajax requests, the response 
should be a JSON body containing a single array).</p>
<p>For each suggestion in the array, the autocompleter needs
a <i>label</i> (an HTML fragment to display in suggestion
dropdown lists) and a <i>value</i> (a plain string to put into
the text field when the suggestion is selected). So 
each suggestion may be either</p>
<ul>
<li><a name="item_a_plain_string"></a><b>a plain string</b>
<p>this string will be used both as label and as value.</p>
</li>
<li><a name="item_an_inline_object"></a><b>an inline object</b>
<p>this object is supposed to have a <code>label</code> property and a 
<code>value</code> property. Actually, these are the default names for
the properties; they can be changed in the constructor options.</p>
<p>The <code>label</code> property may contain rich HTML, i.e. including

doc/html/AutoCompleter.html  view on Meta::CPAN


    </div>
  </div>
  <div class="TN_node" id="onComplete">
    <h3 class="TN_label">onComplete</h3>
    <div class="TN_content">
      <p>[OBSOLETE; use <code>onLegalValue</code> or <code>onIllegalValue</code> instead]</p>
<p>This event is triggered whenever the user has chosen
an item in the displayed suggestion list.
The event handler may use <code>event.index</code> to know the index of the
selected choice.</p>

    </div>
  </div>
  <div class="TN_node" id="onLegalValue">
    <h3 class="TN_label">onLegalValue</h3>
    <div class="TN_content">
      <p>This event is triggered when the autocompleter is in strict mode,
the input field has just been left (<code>onBlur</code> event), and the 
autocompleter was able to verify that the current input value
belongs to the list of available choices.</p>

doc/html/ChoiceList.html  view on Meta::CPAN

      <pre>  var choiceList = new GvaScript.ChoiceList(["foo", "bar", "buz"]);
  choiceList.fillContainer($('myChoiceDiv'));</pre>


    </div>
  </div>
  <div class="TN_node" id="DESCRIPTION">
    <h2 class="TN_label">DESCRIPTION</h2>
    <div class="TN_content">
      <p>Displays a list of "choices", handles navigation in those
choices, and generates events when a choice is highlighted, then selected,
or when the list display is cancelled.</p>
<p>At any moment the choiceList is bound to maximum one "container",
and highlights exactly one choice in the list.</p>

    </div>
  </div>
  <div class="TN_node" id="BEHAVIOUR">
    <h2 class="TN_label">BEHAVIOUR</h2>
    <div class="TN_content">
      <p>Once a choice list is displayed, the user can move the mouse over the
list, thus highlighting various choices; then click on the highlighted
choice to select it. Alternatively, the user can navigate the list
with keys <code>DOWN</code>, <code>UP</code>, <code>HOME</code>, <code>END</code>, and then use either
<code>RETURN</code> (for selecting) or <code>ESCAPE</code> (for cancelling).</p>

    </div>
  </div>
  <div class="TN_node" id="CONSTRUCTOR">
    <h2 class="TN_label">CONSTRUCTOR</h2>
    <div class="TN_content">
      <pre>  var choiceList = new GvaScript.ChoiceList(choices, options);</pre>

  <div class="TN_node" id="Choices">
    <h3 class="TN_label">Choices</h3>

doc/html/ChoiceList.html  view on Meta::CPAN

<li><a name="item_keymap"></a><b>keymap</b>
<p>If defined, the choiceList will add rules to the supplied keymap,
instead of creating a new one.</p>
</li>
<li><a name="item_scrollCount"></a><b>scrollCount</b>
<p>How many items to skip when hitting the 
<code>PAGE_UP</code> or <code>PAGE_DOWN</code> keys. 
Default is 5</p>
</li>
<li><a name="item_mouseovernavi"></a><b>mouseovernavi</b>
<p>Boolean indicating whether the choices would be selected/deselected with the 
mouseover event.
Default is <code>true</code></p>
</li>
<li><a name="item_classes"></a><b>classes</b>
<p>Classes that will be assigned to choice elements in the generated
HTML. Possible classes are <code>choiceItem</code> (default value <code>CL_choiceItem</code>) and
<code>choiceHighlight</code> (default value <code>CL_highlight</code>).</p>
</li>
<li><a name="item_htmlWrapper"></a><b>htmlWrapper</b>
<p>Callback function for generating HTML for the choiceList.

doc/html/ChoiceList.html  view on Meta::CPAN

The event handler may use <code>event.index</code> to know the index of the
highlighted choice.</p>

    </div>
  </div>
  <div class="TN_node" id="onPing">
    <h3 class="TN_label">onPing</h3>
    <div class="TN_content">
      <p>This event is triggered when a choice in the list is "ping-ed", i.e.
either by clicking or by pressing the <code>RETURN</code> key.
Usually this means "select", but it is up to the event handler to decide
how to interpret the event.
The event handler may use <code>event.index</code> to know the index of the
ping-ed choice.</p>

    </div>
  </div>
  <div class="TN_node" id="onCancel">
    <h3 class="TN_label">onCancel</h3>
    <div class="TN_content">
      <p>This event is triggered when the user presses the <code>ESCAPE</code> key.</p>

doc/html/CustomButtons.html  view on Meta::CPAN

    <h4 class="TN_label">Javascript</h4>
    <div class="TN_content">
      <pre>  // container of the buttons we are looking for
  var container  = $('my_buttons_are_contained_here');
  
  // classname of the buttons we are looking for
  var className  = 'gva-btn-container';
  
  // initialize ButtonNavigation to activate keyboard map
  var mybuttonnavigator = new GvaScript.CustomButtons.ButtonNavigation(container, {
    selectFirstBtn  : true, 
    className       : className,
    preventListBlur : false,
    flashClassName  : 'flash', 
    flashDuration   : 100
  });</pre>


    </div>
  </div>
  <div class="TN_node" id="HTML">

doc/html/CustomButtons.html  view on Meta::CPAN

    </div>
  </div>
  <div class="TN_node" id="Methods">
    <h3 class="TN_label">Methods</h3>
    <div class="TN_content">
        <div class="TN_node" id="new">
    <h4 class="TN_label">new</h4>
    <div class="TN_content">
      <p>The <code>properties</code> hash has the following entries :</p>
<ul>
<li><a name="item_selectFirstBtn__i__boolean___i_"></a><b>selectFirstBtn <i>(boolean)</i></b>
<p>boolean indicating whether to give focus to the first button in the found list.</p>
<p>optional - defaulted to true</p>
</li>
<li><a name="item_className__i__string___i_"></a><b>className <i>(string)</i></b>
<p>classname to match with button elements that are a part of navigation</p>
<p>optional - defaulted to 'BN_button'</p>
</li>
<li><a name="item_preventListBlur__i__boolean___i_"></a><b>preventListBlur <i>(boolean)</i></b>
<p>boolean indicating whether a user can use the TAB and S_TAB keys to prevent 
navigation outside the button list.</p>

doc/html/CustomButtons.html  view on Meta::CPAN

      <p>For rendering a list of Buttons and adding support of keyboard navigation</p>
  <div class="TN_node" id="Usage">
    <h3 class="TN_label">Usage</h3>
    <div class="TN_content">
        <div class="TN_node" id="Javascript">
    <h4 class="TN_label">Javascript</h4>
    <div class="TN_content">
      <pre>  var container = $('my_buttons_bar_will_display_here');
  var actionsbar_properties = {
    actions     : [],    // array of button_properties
    selectfirst : false  // focus on first button
  }
  
  // create a new buttons list and display next to each other in container
  var myactionsbar = new GvaScript.CustomButtons.ActionsBar(container, actionsbar_properties);</pre>


    </div>
  </div>
  <div class="TN_node" id="HTML">
    <h4 class="TN_label">HTML</h4>

doc/html/CustomButtons.html  view on Meta::CPAN

    <div class="TN_content">
        <div class="TN_node" id="new">
    <h4 class="TN_label">new</h4>
    <div class="TN_content">
      <p>The <code>properties</code> hash has the following entries :</p>
<ul>
<li><a name="item_actions__i_array__i_"></a><b>actions <i>array</i></b>
<p>list of button_properties describing a Button.</p>
<p>required.</p>
</li>
<li><a name="item_selectfirst__i_boolean__i_"></a><b>selectfirst <i>boolean</i></b>
<p>boolean indicating whether to give focus to the first button in the list when the actionsbar finished rendering.</p>
<p>optional - defaulted to false.</p>
</li>
</ul>
<p>ActionsBar implicitly initializes ButtonNavigation object with following properties</p>
<pre>  new GvaScript.CustomButtons.ButtonNavigation(this.container, {
    selectFirstBtn : this.options.selectfirst, 
    className      : 'gva-btn-container'
  });</pre>


    </div>
  </div>
  <div class="TN_node" id="destroy">
    <h4 class="TN_label">destroy</h4>
    <div class="TN_content">
      <pre>  myactionsbar.destory();</pre>

doc/html/Form.html  view on Meta::CPAN


    </div>
  </div>
  <div class="TN_node" id="register">
    <h3 class="TN_label">register</h3>
    <div class="TN_content">
      <pre>   gvascript_form.register(expression, eventName, handler)
   GvaScript.Form.register(form, expression, eventName, handler)</pre>

<p>tells the form to watch the <i>eventName</i> on elements that match the <i>expression</i> and to fire the corresponding <i>handler</i>.</p>
<p><code>expression</code> (String) - A css selector</p>
<p><code>eventName</code> (String) - The name of the event, in all lower case, without the "on" prefix &#x97; e.g., "click" (not "onclick").</p>
<p>A custom <b>"init"</b> event is also supported which is fired on an input that gets its value initialized with the initialization of the form.</p>
<p><code>handler</code> (Function) - handler to fire.</p>
<p>Signature</p>
<pre>  function handler(event[, newValue[, oldValue]]) {
    event.target // element being observed
  }</pre>

<p><code>newValue</code> is set for the <code>change</code> and the <code>init</code> events.</p>
<p><code>oldValue</code> is set for the <code>change</code>.</p>

doc/html/Grid.html  view on Meta::CPAN

      <p>This event is triggered when a choice in the list is highlighted.
The event handler may use <code>event.index</code> to know the index of the
highlighted choice.</p>

    </div>
  </div>
  <div class="TN_node" id="onPing">
    <h3 class="TN_label">onPing</h3>
    <div class="TN_content">
      <p>This event is triggered when a choice in the list is "ping-ed", i.e.
either by dblclicking, clicking on selected row or by pressing the <code>RETURN</code> key.
The event handler will recieve 1 arguement <code>target</code> which is the record object that has been "Pinged".</p>
<p>Ex: <code>{'fname': 'Mary', 'lname': 'Major', 'gender': 'f'}</code></p>

    </div>
  </div>
  <div class="TN_node" id="onCancel">
    <h3 class="TN_label">onCancel</h3>
    <div class="TN_content">
      <p>This event is triggered when the user presses the <code>ESCAPE</code> key.</p>

doc/html/Grid.html  view on Meta::CPAN

    text-align:center;
    padding:2px;
    font-size:75%;
    color: #183E6C;
    background-color: #D0D6ED;
    border:1px solid #6F82A5;
  }
  .dmweb-grid td {font-size:75%;color:#183E6C;}
  .dmweb-grid .grid-marker {width:15px;background-color: #D0D6ED;border:1px solid #6F82A5;}
  .dmweb-grid tr.liste_highlight td.grid-marker {
    background: #D0D6ED url(selector.gif) no-repeat center center;
  }
  .dmweb-grid tr.liste_highlight td.grid-cell {background-color: #6F82A5 !important;color:#f5f5f5 !important;}
  .dmweb-grid td.grid-cell {padding:2px !important;border:1px solid #e8e8e8;}
  .dmweb-grid td.grid-cell.index_1 {background-color:#EFEFEF;}
  .dmweb-grid td.grid-cell.center {text-align:center;float:none;}
  .dmweb-grid td.grid-cell.right {text-align:right;float:none;}
  .dmweb-grid td.grid-cell.red {color:red;}</pre>


    </div>

doc/html/GvaScript_doc.css  view on Meta::CPAN

.TN_button { 
  background-image: url(minus.gif);
  background-repeat : no-repeat;
  background-position : center left;
  width: 15px;
  padding-right: 15px;
  cursor: pointer;
 }


/* how to highlight the current selected node */
.TN_selected {
  background-color: #e0e3ef;
}


/* class to implement pseudo-hover on node labels */
.TN_mouse { 
  text-decoration: underline;
}

/* when a node is closed, the button icon becomes a 'plus', and 

doc/html/TreeNavigator.html  view on Meta::CPAN

</div>
<div class="TN_leaf">
  <a class="TN_label" href="#flashDuration">flashDuration</a>
  <div class="TN_content"></div>
</div>
<div class="TN_leaf">
  <a class="TN_label" href="#flashColor">flashColor</a>
  <div class="TN_content"></div>
</div>
<div class="TN_leaf">
  <a class="TN_label" href="#selectOnButtonClick">selectOnButtonClick</a>
  <div class="TN_content"></div>
</div>
<div class="TN_leaf">
  <a class="TN_label" href="#noPingOnFirstClick">noPingOnFirstClick</a>
  <div class="TN_content"></div>
</div>
<div class="TN_leaf">
  <a class="TN_label" href="#selectFirstNode">selectFirstNode</a>
  <div class="TN_content"></div>
</div>
<div class="TN_leaf">
  <a class="TN_label" href="#createButtons">createButtons</a>
  <div class="TN_content"></div>
</div>
<div class="TN_leaf">
  <a class="TN_label" href="#scrollingContainer">scrollingContainer</a>
  <div class="TN_content"></div>
</div>

doc/html/TreeNavigator.html  view on Meta::CPAN

  <a class="TN_label" href="#Walking_the_tree">Walking the tree</a>
  <div class="TN_content"></div>
</div>
</div>
</div>
<div class="TN_node">
  <a class="TN_label" href="#Event_handling">Event handling</a>
  <div class="TN_content"><div class="TN_node">
  <a class="TN_label" href="#Event_list">Event list</a>
  <div class="TN_content"><div class="TN_leaf">
  <a class="TN_label" href="#Select_Deselect"><code>Select</code> / <code>Deselect</code></a>
  <div class="TN_content"></div>
</div>
<div class="TN_leaf">
  <a class="TN_label" href="#Open_Close"><code>Open</code> / <code>Close</code></a>
  <div class="TN_content"></div>
</div>
<div class="TN_leaf">
  <a class="TN_label" href="#BeforeLoadContent_AfterLoadContent"><code>BeforeLoadContent</code> / <code>AfterLoadContent</code></a>
  <div class="TN_content"></div>
</div>

doc/html/TreeNavigator.html  view on Meta::CPAN

the node's content (like for example an open or closed
folder), you can proceed as follows:</p>
<ul>
<li>
<p>add an empty <code>span</code> element within the
labels that should have the icon</p>
<pre>  &lt;span class="TN_label"&gt;&lt;span class="specialNode"&gt;&lt;/span&gt;some label&lt;/span&gt;</pre>

</li>
<li>
<p>define CSS background images for selectors
<code>.specialNode</code> and  <code>.TN_closed .specialNode</code>,
as in the example above</p>
</li>
</ul>

    </div>
  </div>

    </div>
  </div>
  <div class="TN_node" id="Usage_navigation">
    <h2 class="TN_label">Usage : navigation</h2>
    <div class="TN_content">
      <p>Navigation in the tree is either with the mouse or with
the keyboard. At any point in time, at most one node is
<i>selected</i> : this is the one that receives keyboard
events. Hence if the tree has no
selected node, no keyboard events are interpreted.</p>
  <div class="TN_node" id="Mouse_events">
    <h3 class="TN_label">Mouse events</h3>
    <div class="TN_content">
      <p>Mousing over a node label adds the class
<code>TN_mouse</code> to that node; the default style for
that class is just to underline the label.</p>
<p>Clicking on a node label selects that node and
fires the <code>Ping</code> event.
Clicking on the square +/- icon on the left of the
label toggles the open/closed status of the node.</p>

    </div>
  </div>
  <div class="TN_node" id="Keyboard_events">
    <h3 class="TN_label">Keyboard events</h3>
    <div class="TN_content">
      <ul>

doc/html/TreeNavigator.html  view on Meta::CPAN

<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>
</li>
<li><a name="item__code_ARROW_RIGHT__code_"></a><b><code>ARROW_RIGHT</code></b>
<p>if closed, open the node; if already open, move to next subnode</p>
</li>
<li><a name="item__code_HOME__code_"></a><b><code>HOME</code></b>
<p>select the first node of the tree</p>
</li>
<li><a name="item__code_END__code_"></a><b><code>END</code></b>
<p>select the last visible subnode of the tree</p>
</li>
<li><a name="item__code_Ctrl_PAGE_UP__code_"></a><b><code>Ctrl-PAGE_UP</code></b>
<p>select the enclosing node (useful if not positioned on a node, but
within a long node content)</p>
</li>
<li><a name="item__code_Ctrl_PAGE_DOWN__code_"></a><b><code>Ctrl-PAGE_DOWN</code></b>
<p>select the displayed node after 
the current enclosing node (useful if not positioned on a node, but
within a long node content)</p>
</li>
<li><a name="item__code_Ctrl_R__code_"></a><b><code>Ctrl-R</code></b>
<p>refresh the node's content (if that node has an URL for dynamic
content).</p>
</li>
<li><a name="item__code_RETURN__code_"></a><b><code>RETURN</code></b>
<p>fire the <code>Ping</code> event</p>
</li>

doc/html/TreeNavigator.html  view on Meta::CPAN


    </div>
  </div>
  <div class="TN_node" id="flashColor">
    <h5 class="TN_label">flashColor</h5>
    <div class="TN_content">
      <p>Color for "flashing", expressed as standard CSS color; default is red.</p>

    </div>
  </div>
  <div class="TN_node" id="selectOnButtonClick">
    <h5 class="TN_label">selectOnButtonClick</h5>
    <div class="TN_content">
      <p>If true, clicking on a "+/-" button next to a label will not only open
or close the node, but will also select that node; default is true.</p>

    </div>
  </div>
  <div class="TN_node" id="noPingOnFirstClick">
    <h5 class="TN_label">noPingOnFirstClick</h5>
    <div class="TN_content">
      <p>If true, clicking on an unselected node will just select that node,
without firing the <code>Ping</code> event. Since the node will then be selected,
a second clic (or a double-clic) will fire the event.</p>
<p>This option is <code>false</code> by default.</p>

    </div>
  </div>
  <div class="TN_node" id="selectFirstNode">
    <h5 class="TN_label">selectFirstNode</h5>
    <div class="TN_content">
      <p>If true (the default), the first node is selected and gets focus
just after constructing the tree navigator.</p>

    </div>
  </div>
  <div class="TN_node" id="createButtons">
    <h5 class="TN_label">createButtons</h5>
    <div class="TN_content">
      <p>If true, creates the "+/-" buttons next to labels; default is true.</p>

    </div>

doc/html/TreeNavigator.html  view on Meta::CPAN

    <div class="TN_content">
      <p>The id of the container where the tree overflows.
Default to <code>tree.ownerDocument.documentElement</code>.</p>
<p>This is used for keyboard tree navigation autoscrolling.</p>

    </div>
  </div>
  <div class="TN_node" id="autoScrollPercentage">
    <h5 class="TN_label">autoScrollPercentage</h5>
    <div class="TN_content">
      <p>Makes sure that the selected node is visible in the central area of 
its offset parent; if not, the parent is scrolled.
The percentage is the ratio between the parent height and the 
margin at which scrolling must occur (default is 20%);</p>

    </div>
  </div>
  <div class="TN_node" id="keymap">
    <h5 class="TN_label">keymap</h5>
    <div class="TN_content">
      <p>A keymap object (see <code>Keymap.js</code>). If that option is given, keyboard

doc/html/TreeNavigator.html  view on Meta::CPAN

sure that:</p>
<ul>
<li>
<p>the keymap is attached to an element that properly receives keyboard
events. The document element does, but the tree DIV element does not,
unless it contains items with activated focus (with <code>tabIndex</code>
defined and positive).</p>
</li>
<li>
<p>the keymap is created with options <code>preventDefault:false</code> and
<code>stopPropagation:false</code> (because when the tree has no selected node,
the tree navigation handlers do not consume events and try to
propagate them further).</p>
</li>
</ul>

    </div>
  </div>
  <div class="TN_node" id="classes">
    <h5 class="TN_label">classes</h5>
    <div class="TN_content">

doc/html/TreeNavigator.html  view on Meta::CPAN

<li><a name="item_label"></a><b>label</b>
<p>Class(es) for label elements (default is <code>TN_label</code>). 
A label should have style <code>display:inline</code>.</p>
</li>
<li><a name="item_content"></a><b>content</b>
<p>Class(es) for content elements (default is <code>TN_content</code>).</p>
</li>
<li><a name="item_closed"></a><b>closed</b>
<p>Class(es) for marking closed nodes (default is <code>TN_closed</code>).</p>
</li>
<li><a name="item_selected"></a><b>selected</b>
<p>Class(es) for marking the selected node (default is <code>TN_selected</code>).</p>
</li>
<li><a name="item_mouse"></a><b>mouse</b>
<p>Class(es) added when the mouse hovers over a node
(default is <code>TN_mouse</code>).</p>
</li>
<li><a name="item_button"></a><b>button</b>
<p>Class(es) for buttons added automatically by the tree navigator
(default is <code>TN_button</code>).</p>
</li>
<li><a name="item_showall"></a><b>showall</b>

doc/html/TreeNavigator.html  view on Meta::CPAN

<p>closes the node</p>
</li>
<li><a name="item__code_openAtLevel_elem__level___code_"></a><b><code>openAtLevel(elem, level)</code></b>
<p>walks down the tree and opens all subnodes of <code>elem</code> until level
<code>level</code>; closes nodes underneath</p>
</li>
<li><a name="item__code_openEnclosingNodes_elem___code_"></a><b><code>openEnclosingNodes(elem)</code></b>
<p>walks up the DOM, starting at <code>elem</code> (which might by any element on
the page), and opens all nodes found on the way</p>
</li>
<li><a name="item__code_select_node__prevent_autoscroll___code_"></a><b><code>select(node, prevent_autoscroll)</code></b>
<p>If there was a selected node, unselect it; then select the argument
node. The argument can be <code>null</code>, in which case the tree no longer
has any selected node.</p>
<p>The second argument <code>prevent_autoscroll</code> is optional; if true,
no autoscroll will be performed.</p>
</li>
<li><a name="item__code_scrollTo_node___code_"></a><b><code>scrollTo(node)</code></b>
<p>Positions the node in the middle of the screen</p>
</li>
<li><a name="item__code_flash_node__duration__color___code_"></a><b><code>flash(node, duration, color)</code></b>
<p>Changes the background color of <i>node</i> to <i>color</i> for <i>duration</i>
milliseconds.  Duration and color are optional and default to 200 ms
and 'red' (unless otherwise specified in the options to the

doc/html/TreeNavigator.html  view on Meta::CPAN

  </div>
  <div class="TN_node" id="Event_handling">
    <h3 class="TN_label">Event handling</h3>
    <div class="TN_content">
      <p>Manipulations to the tree generate <i>events</i>
for which clients can register some <i>handlers</i>,
exactly like ordinary HTML events.</p>
  <div class="TN_node" id="Event_list">
    <h4 class="TN_label">Event list</h4>
    <div class="TN_content">
        <div class="TN_node" id="Select_Deselect">
    <h5 class="TN_label"><code>Select</code> / <code>Deselect</code></h5>
    <div class="TN_content">
      <p>triggered when a node is marked / unmarked as the
currently selected node. Both events are not
triggered immediately, but only after 
<code>selectDelay</code> milliseconds have elapsed :
this is an optimization to avoid too many calls
while the user is navigating quickly through the
nodes; in other words, intermediate nodes
crossed while navigating the tree will not
receive any trigger.</p>
<p>If label selection is associated with 
focus (i.e. if <code>tabIndex</code> was not set
to -1), then selection/deselection events
are also triggered when the user switches
to another desktop window.</p>

    </div>
  </div>
  <div class="TN_node" id="Open_Close">
    <h5 class="TN_label"><code>Open</code> / <code>Close</code></h5>
    <div class="TN_content">
      <p>triggered when a node is opened or
closed</p>

doc/html/TreeNavigator.html  view on Meta::CPAN

  </div>
  <div class="TN_node" id="Event_structure_passed_to_handlers">
    <h4 class="TN_label">Event structure passed to handlers</h4>
    <div class="TN_content">
      <p>Handlers can access an <code>event</code> structure,
similar to what is passed to ordinary HTML events;
the entries are:</p>
<ul>
<li><a name="item__code_type__code_"></a><b><code>type</code></b>
<p>the name of the triggered event
(i.e. <code>Select</code>, <code>Deselect</code>, <code>Open</code>, etc.)</p>
</li>
<li><a name="item__code_target__code_"></a><b><code>target</code></b>
<p>the node element on which the event was
triggered</p>
</li>
<li><a name="item__code_srcElement__code_"></a><b><code>srcElement</code></b>
<p>synonym for <code>target</code></p>
</li>
<li><a name="item__code_treeNavigator__code_"></a><b><code>treeNavigator</code></b>
<p>the tree navigator object controlling the

lib/Alien/GvaScript/AutoCompleter.pod  view on Meta::CPAN


=head3 Format of suggestions returned by datasources

Datasources should return a list of suggestions in the form
of a Javascript array (in case of Ajax requests, the response 
should be a JSON body containing a single array). 

For each suggestion in the array, the autocompleter needs
a I<label> (an HTML fragment to display in suggestion
dropdown lists) and a I<value> (a plain string to put into
the text field when the suggestion is selected). So 
each suggestion may be either

=over

=item a plain string

this string will be used both as label and as value.

=item an inline object

lib/Alien/GvaScript/AutoCompleter.pod  view on Meta::CPAN

triggered I<before> the C<onLegalValue> or C<onIllegalValue> events.


=head2 onComplete

[OBSOLETE; use C<onLegalValue> or C<onIllegalValue> instead]

This event is triggered whenever the user has chosen
an item in the displayed suggestion list.
The event handler may use C<event.index> to know the index of the
selected choice.


=head2 onLegalValue

This event is triggered when the autocompleter is in strict mode,
the input field has just been left (C<onBlur> event), and the 
autocompleter was able to verify that the current input value
belongs to the list of available choices.

The event contains a C<value> property (current value in the 

lib/Alien/GvaScript/ChoiceList.pod  view on Meta::CPAN

Alien::GvaScript::ChoiceList - Dropdown list of choices with navigation

=head1 SYNOPSIS

  var choiceList = new GvaScript.ChoiceList(["foo", "bar", "buz"]);
  choiceList.fillContainer($('myChoiceDiv'));

=head1 DESCRIPTION

Displays a list of "choices", handles navigation in those
choices, and generates events when a choice is highlighted, then selected,
or when the list display is cancelled.

At any moment the choiceList is bound to maximum one "container",
and highlights exactly one choice in the list.

=head1 BEHAVIOUR

Once a choice list is displayed, the user can move the mouse over the
list, thus highlighting various choices; then click on the highlighted
choice to select it. Alternatively, the user can navigate the list
with keys C<DOWN>, C<UP>, C<HOME>, C<END>, and then use either
C<RETURN> (for selecting) or C<ESCAPE> (for cancelling).



=head1 CONSTRUCTOR

  var choiceList = new GvaScript.ChoiceList(choices, options);

=head2 Choices

The choice list must be an array. Each item in the list is either

lib/Alien/GvaScript/ChoiceList.pod  view on Meta::CPAN

instead of creating a new one.

=item scrollCount

How many items to skip when hitting the 
C<PAGE_UP> or C<PAGE_DOWN> keys. 
Default is 5

=item mouseovernavi 

Boolean indicating whether the choices would be selected/deselected with the 
mouseover event.
Default is C<true>

=item classes

Classes that will be assigned to choice elements in the generated
HTML. Possible classes are C<choiceItem> (default value C<CL_choiceItem>) and
C<choiceHighlight> (default value C<CL_highlight>).


lib/Alien/GvaScript/ChoiceList.pod  view on Meta::CPAN

=head2 onHighlight

This event is triggered when a choice in the list is highlighted.
The event handler may use C<event.index> to know the index of the
highlighted choice.

=head2 onPing

This event is triggered when a choice in the list is "ping-ed", i.e.
either by clicking or by pressing the C<RETURN> key.
Usually this means "select", but it is up to the event handler to decide
how to interpret the event.
The event handler may use C<event.index> to know the index of the
ping-ed choice.


=head2 onCancel

This event is triggered when the user presses the C<ESCAPE> key.

lib/Alien/GvaScript/CustomButtons.pod  view on Meta::CPAN

=head3 Javascript

  // container of the buttons we are looking for
  var container  = $('my_buttons_are_contained_here');
  
  // classname of the buttons we are looking for
  var className  = 'gva-btn-container';
  
  // initialize ButtonNavigation to activate keyboard map
  var mybuttonnavigator = new GvaScript.CustomButtons.ButtonNavigation(container, {
    selectFirstBtn  : true, 
    className       : className,
    preventListBlur : false,
    flashClassName  : 'flash', 
    flashDuration   : 100
  });

=head3 HTML

I<class does not produce any HTML>


=head2 Methods

=head3 new

The C<properties> hash has the following entries : 

=over

=item selectFirstBtn I<(boolean)>

boolean indicating whether to give focus to the first button in the found list.

optional - defaulted to true

=item className I<(string)>

classname to match with button elements that are a part of navigation

optional - defaulted to 'BN_button'

lib/Alien/GvaScript/CustomButtons.pod  view on Meta::CPAN


For rendering a list of Buttons and adding support of keyboard navigation

=head2 Usage

=head3 Javascript

  var container = $('my_buttons_bar_will_display_here');
  var actionsbar_properties = {
    actions     : [],    // array of button_properties
    selectfirst : false  // focus on first button
  }
  
  // create a new buttons list and display next to each other in container
  var myactionsbar = new GvaScript.CustomButtons.ActionsBar(container, actionsbar_properties);


=head3 HTML

The list of buttons will be rendered one by one and the resulting HTML will be 
appended sequentially into the designated container.

lib/Alien/GvaScript/CustomButtons.pod  view on Meta::CPAN

The C<properties> hash has the following entries :

=over

=item actions I<array>

list of button_properties describing a Button.

required.

=item selectfirst I<boolean>

boolean indicating whether to give focus to the first button in the list when the actionsbar finished rendering.

optional - defaulted to false.

=back


ActionsBar implicitly initializes ButtonNavigation object with following properties

  new GvaScript.CustomButtons.ButtonNavigation(this.container, {
    selectFirstBtn : this.options.selectfirst, 
    className      : 'gva-btn-container'
  });




=head3 destroy

  myactionsbar.destory();

lib/Alien/GvaScript/Form.pod  view on Meta::CPAN

NOTE that the B<onBeforeSubmit, onSubmit> events cannot be notified programatically. 
You actually need to call form.submit() for these events to be fired.

=head2 register

   gvascript_form.register(expression, eventName, handler)
   GvaScript.Form.register(form, expression, eventName, handler)

tells the form to watch the I<eventName> on elements that match the I<expression> and to fire the corresponding I<handler>.

C<expression> (String) - A css selector

C<eventName> (String) - The name of the event, in all lower case, without the "on" prefix — e.g., "click" (not "onclick"). 

A custom B<"init"> event is also supported which is fired on an input that gets its value initialized with the initialization of the form.

C<handler> (Function) - handler to fire.

Signature

  function handler(event[, newValue[, oldValue]]) {

lib/Alien/GvaScript/Grid.pod  view on Meta::CPAN


=head2 onHighlight

This event is triggered when a choice in the list is highlighted.
The event handler may use C<event.index> to know the index of the
highlighted choice.

=head2 onPing

This event is triggered when a choice in the list is "ping-ed", i.e.
either by dblclicking, clicking on selected row or by pressing the C<RETURN> key.
The event handler will recieve 1 arguement C<target> which is the record object that has been "Pinged".

Ex: C<{'fname': 'Mary', 'lname': 'Major', 'gender': 'f'}>

=head2 onCancel

This event is triggered when the user presses the C<ESCAPE> key.

=head2 onEmpty 

lib/Alien/GvaScript/Grid.pod  view on Meta::CPAN

    text-align:center;
    padding:2px;
    font-size:75%;
    color: #183E6C;
    background-color: #D0D6ED;
    border:1px solid #6F82A5;
  }
  .dmweb-grid td {font-size:75%;color:#183E6C;}
  .dmweb-grid .grid-marker {width:15px;background-color: #D0D6ED;border:1px solid #6F82A5;}
  .dmweb-grid tr.liste_highlight td.grid-marker {
    background: #D0D6ED url(selector.gif) no-repeat center center;
  }
  .dmweb-grid tr.liste_highlight td.grid-cell {background-color: #6F82A5 !important;color:#f5f5f5 !important;}
  .dmweb-grid td.grid-cell {padding:2px !important;border:1px solid #e8e8e8;}
  .dmweb-grid td.grid-cell.index_1 {background-color:#EFEFEF;}
  .dmweb-grid td.grid-cell.center {text-align:center;float:none;}
  .dmweb-grid td.grid-cell.right {text-align:right;float:none;}
  .dmweb-grid td.grid-cell.red {color:red;}

=head1 DEPENDENCIES

lib/Alien/GvaScript/TreeNavigator.pod  view on Meta::CPAN


=item * 

add an empty C<span> element within the
labels that should have the icon

  <span class="TN_label"><span class="specialNode"></span>some label</span>

=item *

define CSS background images for selectors
C<.specialNode> and  C<.TN_closed .specialNode>,
as in the example above

=back

=head1 Usage : navigation

Navigation in the tree is either with the mouse or with
the keyboard. At any point in time, at most one node is
I<selected> : this is the one that receives keyboard
events. Hence if the tree has no
selected node, no keyboard events are interpreted.

=head2 Mouse events

Mousing over a node label adds the class
C<TN_mouse> to that node; the default style for
that class is just to underline the label.

Clicking on a node label selects that node and
fires the C<Ping> event.
Clicking on the square +/- icon on the left of the
label toggles the open/closed status of the node.

=head2 Keyboard events


=over

=item C<keypad +>

lib/Alien/GvaScript/TreeNavigator.pod  view on Meta::CPAN

=item C<ARROW_LEFT>

if open, close the node; if already closed, move to parent node

=item C<ARROW_RIGHT>

if closed, open the node; if already open, move to next subnode

=item C<HOME>

select the first node of the tree

=item C<END>

select the last visible subnode of the tree

=item C<Ctrl-PAGE_UP>

select the enclosing node (useful if not positioned on a node, but
within a long node content)

=item C<Ctrl-PAGE_DOWN>

select the displayed node after 
the current enclosing node (useful if not positioned on a node, but
within a long node content)

=item C<Ctrl-R>

refresh the node's content (if that node has an URL for dynamic
content).

=item C<RETURN>

lib/Alien/GvaScript/TreeNavigator.pod  view on Meta::CPAN

=head4 flashDuration

Duration (in milliseconds) of "flashing", i.e. visual feedback when a
key is pressed in a wrong context, like for example trying to open a
node which is already open; default is 200 ms.

=head4 flashColor

Color for "flashing", expressed as standard CSS color; default is red.

=head4 selectOnButtonClick

If true, clicking on a "+/-" button next to a label will not only open
or close the node, but will also select that node; default is true.

=head4 noPingOnFirstClick

If true, clicking on an unselected node will just select that node,
without firing the C<Ping> event. Since the node will then be selected,
a second clic (or a double-clic) will fire the event.

This option is C<false> by default.

=head4 selectFirstNode

If true (the default), the first node is selected and gets focus
just after constructing the tree navigator. 

=head4 createButtons

If true, creates the "+/-" buttons next to labels; default is true.

=head4 scrollingContainer

The id of the container where the tree overflows.
Default to C<tree.ownerDocument.documentElement>.

This is used for keyboard tree navigation autoscrolling.


=head4 autoScrollPercentage

Makes sure that the selected node is visible in the central area of 
its offset parent; if not, the parent is scrolled.
The percentage is the ratio between the parent height and the 
margin at which scrolling must occur (default is 20%);



=head4 keymap

A keymap object (see C<Keymap.js>). If that option is given, keyboard
handlers are pushed into that keymap; otherwise a new keymap is

lib/Alien/GvaScript/TreeNavigator.pod  view on Meta::CPAN


the keymap is attached to an element that properly receives keyboard
events. The document element does, but the tree DIV element does not,
unless it contains items with activated focus (with C<tabIndex>
defined and positive).


=item *

the keymap is created with options C<preventDefault:false> and
C<stopPropagation:false> (because when the tree has no selected node,
the tree navigation handlers do not consume events and try to
propagate them further).

=back


=head4 classes

Class names for various parts of the tree structure.
This should be an inline object, with keys corresponding 

lib/Alien/GvaScript/TreeNavigator.pod  view on Meta::CPAN



=item content

Class(es) for content elements (default is C<TN_content>). 

=item closed

Class(es) for marking closed nodes (default is C<TN_closed>). 

=item selected

Class(es) for marking the selected node (default is C<TN_selected>). 

=item mouse

Class(es) added when the mouse hovers over a node
(default is C<TN_mouse>). 

=item button

Class(es) for buttons added automatically by the tree navigator
(default is C<TN_button>). 

lib/Alien/GvaScript/TreeNavigator.pod  view on Meta::CPAN

=item C<openAtLevel(elem, level)>

walks down the tree and opens all subnodes of C<elem> until level
C<level>; closes nodes underneath

=item C<openEnclosingNodes(elem)>

walks up the DOM, starting at C<elem> (which might by any element on
the page), and opens all nodes found on the way

=item C<select(node, prevent_autoscroll)>

If there was a selected node, unselect it; then select the argument
node. The argument can be C<null>, in which case the tree no longer
has any selected node. 

The second argument C<prevent_autoscroll> is optional; if true,
no autoscroll will be performed.


=item C<scrollTo(node)>

Positions the node in the middle of the screen

=item C<flash(node, duration, color)>

lib/Alien/GvaScript/TreeNavigator.pod  view on Meta::CPAN


=head2 Event handling

Manipulations to the tree generate I<events>
for which clients can register some I<handlers>,
exactly like ordinary HTML events.


=head3 Event list

=head4 C<Select> / C<Deselect>

triggered when a node is marked / unmarked as the
currently selected node. Both events are not
triggered immediately, but only after 
C<selectDelay> milliseconds have elapsed :
this is an optimization to avoid too many calls
while the user is navigating quickly through the
nodes; in other words, intermediate nodes
crossed while navigating the tree will not
receive any trigger.

If label selection is associated with 
focus (i.e. if C<tabIndex> was not set
to -1), then selection/deselection events
are also triggered when the user switches
to another desktop window.


=head4 C<Open> / C<Close>

triggered when a node is opened or
closed


lib/Alien/GvaScript/TreeNavigator.pod  view on Meta::CPAN


Handlers can access an C<event> structure,
similar to what is passed to ordinary HTML events;
the entries are:

=over 

=item C<type>

the name of the triggered event
(i.e. C<Select>, C<Deselect>, C<Open>, etc.)

=item C<target>

the node element on which the event was
triggered

=item C<srcElement>

synonym for C<target>

lib/Alien/GvaScript/lib/GvaScript.css  view on Meta::CPAN

.TN_button { 
  background-image: url(minus.gif);
  background-repeat : no-repeat;
  background-position : center left;
  width: 15px;
  padding-right: 15px;
  cursor: pointer;
 }


/* how to highlight the current selected node */
.TN_selected {
  background-color: yellow;
}


/* class to implement pseudo-hover on node labels */
.TN_mouse { 
  text-decoration: underline;
}

/* when a node is closed, the button icon becomes a 'plus', and 

lib/Alien/GvaScript/lib/GvaScript.css  view on Meta::CPAN

  background-color: #D0D6ED;
  border:1px solid #6F82A5;
}
.gva-grid td {color: navy;}
.gva-grid .grid-marker {
    width:15px;
    background-color: #D0D6ED;
    border:1px solid #6F82A5;
}
.gva-grid tr.liste_highlight td.grid-marker {
    background: #D0D6ED url(images/paginator/selector.gif) no-repeat center center;
}
.gva-grid tr.liste_highlight td.grid-cell {background-color: #6F82A5 !important;color:#f5f5f5 !important;}
.gva-grid td.grid-cell {padding:2px !important;border:1px solid #e8e8e8;}
.gva-grid td.grid-cell.index_1 {background-color:#EFEFEF;}
.gva-grid td.grid-cell.center {text-align:center;float:none;}
.gva-grid td.grid-cell.right {text-align:right;float:none;}
.gva-grid td.grid-cell.red {color:#a00;}


.icon-add {

lib/Alien/GvaScript/lib/GvaScript.js  view on Meta::CPAN

  var eventManager = function(o_id, event) {
    // IE sometimes fires some events
    // while reloading (after unregister)
    if(! rules[o_id]) return;

    var element = event.target;
    var eventType = (event.memo)? event.eventName : event.type;
    do {
      if (element.nodeType == 1) {
        element = Element.extend(element);
        for (var selector in rules[o_id][eventType]) {
          if (_match = matches(rules[o_id][eventType][selector]._selector, element)) {
            for (var i=0, handlers=rules[o_id][eventType][selector], l=handlers.length; i<l; ++i) {
              handlers[i].call(element, Object.extend(event, { _target: element, _match: _match }));
            }
          }
        }
      }
    } while (element = element.parentNode)
  }
  var matches = function(selectors, element) {
    for (var i=0, l=selectors.length; i<l; ++i) {
      if (Prototype.Selector.match(element, selectors[i])) return selectors[i];
    }
    return undefined;
  }

  Event.register = function(observer, selector, eventName, handler) {
    var use_capture = (eventName == 'focus' || eventName == 'blur');
    if(use_capture && Prototype.Browser.IE) {
        eventName = (eventName == 'focus')? 'focusin' : 'focusout';
    }
    var observer_id = observer.identify ? observer.identify() : 'document';

    // create entry in cache for rules per observer
    if(! rules[observer_id]) {
        rules[observer_id] = { };
    }

lib/Alien/GvaScript/lib/GvaScript.js  view on Meta::CPAN

      if(use_capture) {
        if(Prototype.Browser.IE)
        Event.observe(observer, eventName, eventManager.curry(observer_id));
        else
        observer.addEventListener(eventName, eventManager.curry(observer_id), true);
      }
      else
      Event.observe(observer, eventName, eventManager.curry(observer_id));
    }

    var _selector = [ ], expr = selector.strip();
    // instantiate Selector's
    exprSplit(selector).each(function(s) { _selector.push(s) })

    // store instantiated Selector for faster matching
    if (!rules[observer_id][eventName][expr]) {
      rules[observer_id][eventName][expr] = Object.extend([ ], { _selector: _selector });
    }

    // associate handler with expression
    rules[observer_id][eventName][expr].push(handler);
  }

  // unregistering an event on an elemment
  Event.unregister = function(elt, selector, eventName) {
    var _id = (typeof elt == 'string')? elt :
              (elt.identify)? elt.identify() : 'document';
    // unregister event identified by name and selector
    if (eventName) {
      rules[_id][eventName][selector] = null;
      delete rules[_id][eventName][selector];
    }
    else {
      for (var eventName in rules[_id]) {
        // unregister all events identified by selector
        if(selector) {
          rules[_id][eventName][selector] = null;
          delete rules[_id][eventName][selector];
        }
        // unregister all events
        else {
          rules[_id][eventName] = null;
          delete rules[_id][eventName];
        }
      }
    }
  },

lib/Alien/GvaScript/lib/GvaScript.js  view on Meta::CPAN


  elem = $(elem); // in case we got an id instead of an element
  options = options || {};

  // default options
  var defaultOptions = {
    tabIndex            : -1,
    treeTabIndex        :  0,
    flashDuration       : 200,     // milliseconds
    flashColor          : "red",
    selectDelay         : 100,     // milliseconds
    selectOnButtonClick : true,
    noPingOnFirstClick  : false,
    selectFirstNode     : true,
    createButtons       : true,
    scrollingContainer  : elem.ownerDocument.documentElement,
    autoScrollPercentage: 20,
    classes             : {},
    keymap              : null
  };

  this.options = Class.checkOptions(defaultOptions, options);

  // values can be single class names or arrays of class names
  var defaultClasses = {
    node     : "TN_node",
    leaf     : "TN_leaf",
    label    : "TN_label",
    closed   : "TN_closed",
    content  : "TN_content",
    selected : "TN_selected",
    mouse    : "TN_mouse",
    button   : "TN_button",
    showall  : "TN_showall"
  };
  this.classes = Class.checkOptions(defaultClasses, this.options.classes);
  this.classes.nodeOrLeaf = [this.classes.node, this.classes.leaf].flatten();

  // connect to the root element
  this.rootElement = elem;

lib/Alien/GvaScript/lib/GvaScript.js  view on Meta::CPAN

    this.keymap = new GvaScript.KeyMap(keyHandlers);

    // observe keyboard events on tree (preferred) or on document
    var target = (elem.tabIndex  < 0) ? document : elem;
    this.keymap.observe("keydown", target, Event.stopNone);
  }

  this.rootElement.store('widget', this);
  this.rootElement.addClassName(CSSPREFIX() + '-widget');

  // selecting the first node
  if (this.options.selectFirstNode) {
    this.select(this.firstSubNode());

    // if labels do not take focus but tree does, then set focus on the tree
    if (this.options.tabIndex < 0 && elem.tabIndex >= 0)
      elem.focus();
  }
}


GvaScript.TreeNavigator.prototype = {

//-----------------------------------------------------
// Public methods
//-----------------------------------------------------
  destroy: function() {
    this._removeHandlers();
  },

  initSubTree: function (tree_root) {
    tree_root = $(tree_root);
    // get the labels of the sub tree
    var labels = tree_root.select('.'+this.classes.label);

    // add tabIndex per label
    if (this.options.tabIndex >= 0) {
      _idx = this.options.tabIndex;
      labels.each(function(label) {
        label.tabIndex = _idx;
      });
    }

    // add tree navigation buttons per label

lib/Alien/GvaScript/lib/GvaScript.js  view on Meta::CPAN

      var treeNavigator = this; // needed for closure below
      var callback = function() {
        treeNavigator.initSubTree(content);
        treeNavigator.fireEvent("AfterLoadContent", node, this.rootElement);
      };
      new Ajax.Updater(content, url, {onComplete: callback});
      return true;
    }
  },

  select: function (node) {
    var previousNode = this.selectedNode;

    // re-selecting the current node is a no-op
    if (node == previousNode) return;

    // deselect the previously selected node
    if (previousNode) {
        var label = this.label(previousNode);
        if (label) {
          Element.removeClassName(label, this.classes.selected);
        }
    }

    // select the new node
    this.selectedNode = node;
    if (node) {
      this._assertNodeOrLeaf(node, 'select node');
      var label = this.label(node);
      if (!label) {
        throw new Error("selected node has no label");
      }
      else {
        Element.addClassName(label, this.classes.selected);

        if (this.isVisible(label)) {
          // focus has not yet been given to label
          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);
    }
    if(!container) return;

lib/Alien/GvaScript/lib/GvaScript.js  view on Meta::CPAN

      if(container.style.overflow == 'hidden'
        || container.style.overflowY == 'hidden')
      return;
    }

    // test if the node in 'in view'
    _container_y_start = container.scrollTop;
    _container_y_end   = _container_y_start + container.clientHeight;
    _node_y  = Element.cumulativeOffset(node).top + (with_content? node.offsetHeight: 0);

    // calculate padding space between the selected node and
    // the edge of the scrollable container
    _perc = this.options.autoScrollPercentage || 0;
    _padding = container.clientHeight * _perc / 100;

    // calculate delta scroll to affect on scrollingContainer
    _delta = 0;

    // node is beneath scrolling area
    if(_node_y > _container_y_end - _padding) {
      _delta = _node_y - _container_y_end + _padding;

lib/Alien/GvaScript/lib/GvaScript.js  view on Meta::CPAN


    if(label = this.isLabel(target)) {
      Element.removeClassName(label, this.classes.mouse);
      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);

    // should ping : depends on options.noPingOnFirstClick
    var should_ping = (!is_first_click) || !this.options.noPingOnFirstClick;

    // do the ping if necessary
    var event_stop_mode;
    if (should_ping)
    event_stop_mode = this.fireEvent("Ping", node, this.rootElement);

    // avoid a second ping from the dblclick handler

lib/Alien/GvaScript/lib/GvaScript.js  view on Meta::CPAN

    var treeNavigator = this; // handlers will be closures on this

    // focus handler
    var focus_handler = function(e) {
      var label = e._target;
      label.writeAttribute('hasFocus', 'hasFocus');

      var node  = Element.navigateDom(label, 'parentNode',
                                      treeNavigator.classes.nodeOrLeaf);

      // not yet been selected
      if(node && !label.hasClassName(treeNavigator.classes.selected)) {
        treeNavigator.select  (node);
      }
    };

    // blur handler
    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
//-----------------------------------------------------

  _selectionTimeoutHandler: function(previousNode) {
      this._selectionTimeoutId = null;

      var newNode = this.selectedNode;

      // fire events
      if (previousNode != newNode) {
        if (previousNode) {
          this.fireEvent("Deselect", previousNode, this.rootElement);
        }
        if (newNode) {
          this.fireEvent("Select", newNode, this.rootElement);
        }
      }
  },


//-----------------------------------------------------
// Key handlers
//-----------------------------------------------------
  _charHandler: function (event) {
    var selectedNode = this.selectedNode;
    if(! selectedNode) return;

    // stop firefox quick search if enabled
    // via "accessibility.typeaheadfind" => 'true'
    Event.stop(event);

    this._quick_navi_word += event.keyName; // always uppercase
    var is_quick_navi_mode = (this._quick_navi_mode !== false);

    // drop the previous timer
    if(is_quick_navi_mode) {
      window.clearTimeout(this._quick_navi_mode);
    }
    // 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;
    });

    // returns first label found to start with word.
    var find_match = function(labels, word) {
        var match = labels.find(function(label) {
            return label.innerHTML.stripTags()          // in case label contains HTML elements
                    .replace(/\r?\n/g, '')              // clear line breaks
                    .replace(/\ \ /g, '')               // clear white-spaces
                    .toUpperCase().startsWith(word);
        });
        return match;
    }

    // first look ahead then look back
    var matching_label  =  find_match(labels[1], this._quick_navi_word)
                        || find_match(labels[0], this._quick_navi_word);

    // found a match -> make it visible and select it
    if(matching_label) {
      this.openEnclosingNodes(matching_label);

      var znode = this.enclosingNode(matching_label);
      this.scrollTo(znode);
      this.select  (znode);
    }
    // no match -> flash the selected label
    else {
      this.label(this.selectedNode).flash();
    }
  },

  _downHandler: function (event) {
    var selectedNode = this.selectedNode;
    if (selectedNode) {
      var nextNode = this.nextDisplayedNode(selectedNode);
      if (nextNode) {
        this.scrollTo(nextNode);
        this.select  (nextNode);
      }
      else this.flash(selectedNode);

      Event.stop(event);
    }
    // otherwise: do nothing and let default behaviour happen
  },

  _upHandler: function (event) {
    var selectedNode = this.selectedNode;
    if (selectedNode) {
      var prevNode = this.previousDisplayedNode(selectedNode);
      if (prevNode) {
        this.scrollTo(prevNode);
        this.select  (prevNode);
      }
      else this.flash(selectedNode);

      Event.stop(event);
    }
    // otherwise: do nothing and let default behaviour happen
  },

  _leftHandler: function (event) {
    var selectedNode = this.selectedNode;
    if (selectedNode) {
      if (!this.isLeaf(selectedNode) && !this.isClosed(selectedNode)) {
        this.close(selectedNode);
      }
      else {
        var zparent = this.parentNode(selectedNode);
        if (zparent) {
          this.scrollTo(zparent);
          this.select  (zparent);
        }
        else
          this.flash(selectedNode);
      }
      Event.stop(event);
    }
  },

  _rightHandler: function (event) {
    var selectedNode = this.selectedNode;
    if (selectedNode) {
      if (this.isLeaf(selectedNode)) return;
      if (this.isClosed(selectedNode))
        this.open(selectedNode);
      else {
        var subNode = this.firstSubNode(selectedNode);
        if (subNode) {
          this.scrollTo(subNode);
          this.select  (subNode);
        }
        else
          this.flash(selectedNode);
      }
      Event.stop(event);
    }
  },

  _tabHandler: function (event) {
    var selectedNode = this.selectedNode;
    if (selectedNode && this.isClosed(selectedNode)) {
      this.open(selectedNode);
      var label = this.label(selectedNode);
      Event.stop(event);
    }
  },

  _kpPlusHandler: function (event) {
    var selectedNode = this.selectedNode;
    if (selectedNode && this.isClosed(selectedNode)) {
      this.open(selectedNode);
      Event.stop(event);
    }
  },

  _kpMinusHandler: function (event) {
    var selectedNode = this.selectedNode;
    if (selectedNode && !this.isClosed(selectedNode)) {
      this.close(selectedNode);
      Event.stop(event);
    }
  },

  _kpStarHandler: function (event) {
    var selectedNode = this.selectedNode;
    if (selectedNode) {
      var nodes = Element.getElementsByClassNames(
        selectedNode,
        this.classes.node
      );
      nodes.unshift(selectedNode);
      nodes.each(function(node) {this.open(node)}, this);
      Event.stop(event);
    }
  },

  _kpSlashHandler: function (event) {
    var selectedNode = this.selectedNode;
    if (selectedNode) {
      var nodes = Element.getElementsByClassNames(
        selectedNode,
        this.classes.node
      );
      nodes.unshift(selectedNode);
      nodes.each(function(node) {this.close(node)}, this);
      Event.stop(event);
    }
  },

  _ctrl_R_handler: function (event) {
    var selectedNode = this.selectedNode;
    if (selectedNode) {
      if (this.loadContent(selectedNode))
        Event.stop(event);
    }
  },

  _ReturnHandler: function (event) {
    var selectedNode = this.selectedNode;
    if (selectedNode) {
      var toStop = this.fireEvent("Ping", selectedNode, this.rootElement);
      Event.detailedStop(event, toStop || Event.stopAll);
    }
  },

  _homeHandler: function (event) {
    if (this.selectedNode) {
      var znode = this.firstSubNode();
      this.scrollTo(znode);
      this.select  (znode);
      Event.stop(event);
    }
  },

  _endHandler: function (event) {
    if (this.selectedNode) {
      var znode = this.lastVisibleSubnode();
      this.scrollTo(znode);
      this.select  (znode);
      Event.stop(event);
    }
  },

  _ctrlPgUpHandler: function (event) {
    var node = this.enclosingNode(Event.element(event));
    if (node) {
      this.scrollTo(node);
      this.select  (node);
      Event.stop(event);
    }
  },

  _ctrlPgDownHandler: function (event) {
    var node = this.enclosingNode(Event.element(event));
    if (node) {
      node = this.nextDisplayedNode(node);
      if (node) {
        this.scrollTo(node);
        this.select  (node);
        Event.stop(event);
      }
    }
  },

  _chooseLevel: function(event) {
    var level = event.keyCode - "0".charCodeAt(0);
    this.openAtLevel(this.rootElement, level);

    // stop the default Ctrl-num event

lib/Alien/GvaScript/lib/GvaScript.js  view on Meta::CPAN

      var newIndex = this._choiceIndex(elem);
      this._highlightChoiceNum(newIndex, false);
      this._clickHandler(event);
    }
  },

  _clickHandler: function(event) {
    var elem = this._findChoiceItem(event);
    if (elem) {
      var newIndex = this._choiceIndex(elem);
      // check if choice is selected
      if (this.currentHighlightedIndex == newIndex) {
        // selected -> fire ping event
        var toStop = this.fireEvent({type : "Ping",
                                    index: this._choiceIndex(elem)},
                                    elem,
                                    this.container);
        Event.detailedStop(event, toStop || Event.stopAll);
      }
      else {
        // not selected -> select
        this._highlightChoiceNum(newIndex, false);
      }
    }
  },

  _returnHandler: function(event) {
    var index = this.currentHighlightedIndex;
    if (index != undefined) {
      var elem = this._choiceElem(index);
      var toStop = this.fireEvent({type : "Ping",

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

  _typeAhead : function () {
    var curLen     = this.lastTypedValue.length;
    var index      = this.choiceList.currentHighlightedIndex;
    var suggestion = this._valueFromChoice(index);
    var newLen     = suggestion.length;
    this._setValue(suggestion);

    if (this.inputElement.createTextRange){ // MSIE
      var range = this.inputElement.createTextRange();
      range.moveStart("character", curLen); // no need to moveEnd
      range.select(); // will call focus();
    }
    else if (this.inputElement.setSelectionRange){ // Mozilla
      this.inputElement.setSelectionRange(curLen, newLen);
    }
  },



//----------------------------------------------------------------------
// methods for the dropdown list of choices

lib/Alien/GvaScript/lib/GvaScript.js  view on Meta::CPAN

      }

      // catch keypress on TAB while choiceList has focus
      cl.keymap.rules[0].TAB = cl.keymap.rules[0].S_TAB = function(event) {
        var index = cl.currentHighlightedIndex;
        if (index != undefined) {

          var elem = cl._choiceElem(index);

          // generate a "Ping" on the choiceList, like if user had
          // pressed RETURN to select the current highlighted item
          cl.fireEvent({type : "Ping",
                        index: index}, elem, cl.container);

          // NO Event.stop() here, because the navigator should
          // do the tabbing (pass focus to next/previous element)
        }
      };

      // more key handlers when the suggestion list is displayed
      this.keymap.rules.push(cl.keymap.rules[0]);

lib/Alien/GvaScript/lib/GvaScript.js  view on Meta::CPAN

    return (choice !== null) ? this._valueFromChoiceItem(choice) : null;
  },

  _valueFromChoiceItem: function(choice) {
    return (typeof choice == "string") ? choice
                                       : choice[this.options.valueField];
  },



  //triggered by the onPing event on the choicelist, i.e. when the user selects
  //one of the choices in the list
  _completeFromChoiceElem: function(elem) {
    // identify the selected line and handle it
    var num = parseInt(elem.id.match(/\.(\d+)$/)[1], 10);

    // add the value to the input element
    var value = this._valueFromChoice(num);
    if (value !== null) {
      this._setValue(value)
      this._removeDropdownDiv();
      
      // ADDED LEMOINEJ 26.09.13
      this._timeLastCheck = this._timeLastKeyDown = 0;      
      this._checkNewValue();

      if (!this.options.multivalued) {
        this.inputElement.select();
      }

      this._updateDependentFields(this.inputElement, this.choices[num]);

      // fire events: "Complete" for backwards compatibility, "LegalValue"
      // for regular use
      var eventNames =  ["Complete", "LegalValue"];
      // for loop : can't use .each() from prototype.js because it alters "this"
      for (var i = 0; i < eventNames.length; i++) {
        this.fireEvent({
          type      : eventNames[i],
          referrer  : "select",    // choice selection fired this event
          index     : num,
          choice    : this.choices[num],
          controller: {choices: this.choices}
          }, elem, this.inputElement);
      }
    }
  }
}


lib/Alien/GvaScript/lib/GvaScript.js  view on Meta::CPAN

        }
    }
}());

GvaScript.CustomButtons.ButtonNavigation = Class.create();
Object.extend(GvaScript.CustomButtons.ButtonNavigation.prototype, function() {
        // private members
        var bcss = CSSPREFIX();

        function _leftHandler(event) {
            var selectedBtn = this.selectedBtn;
            if (selectedBtn) {
                var nextBtn = this.previousBtn(selectedBtn);

                if (nextBtn) this.select(nextBtn);
                else         selectedBtn.flash();

                Event.stop(event);
            }
        }
        function _rightHandler(event) {
            var selectedBtn = this.selectedBtn;
            if (selectedBtn) {
                var prevBtn = this.nextBtn(selectedBtn);

                if (prevBtn) this.select(prevBtn);
                else         selectedBtn.flash();

                Event.stop(event);
            }
        }
        function _tabHandler(event) {
            if (this.options.preventListBlur)
                if (this.isLast(this.selectedBtn))
                    Event.stop(event);
        }
        function _shiftTabHandler(event) {
            if (this.options.preventListBlur)
                if (this.isFirst(this.selectedBtn))
                    Event.stop(event);
        }
        function _homeHandler(event) {
            if (this.selectedBtn) {
                this.select(this.firstBtn());
                Event.stop(event);
            }
        }
        function _endHandler(event) {
            if (this.selectedBtn) {
                this.select(this.lastBtn());
                Event.stop(event);
            }
        }
        function _addHandlers() {
            this.buttons.each(function(btnContainer) {
                var btn;
                // if the button is a GvaScript.CustomButtons.BUTTON, then the actual <button> element
                // will be embedded and selectable via .btn classname:
                // <span class="gva-btn-container">
                //         <span class="left"/>
                //         <span class="center">
                //                 <button accesskey="r" class="btn" style="width: auto;" id="btn_1226916357164">
                //                         Rechercher dans Calvin
                //                 </button>
                //         </span>
                //         <span class="right"/>
                // </span>
                // this will be cleaner when all application buttons are transformed into

lib/Alien/GvaScript/lib/GvaScript.js  view on Meta::CPAN

                    btn.visible        = function() {return btnContainer.visible();}
                    // 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) {
                var defaults = {
                    preventListBlur     : false,
                    flashDuration       : 100,     // milliseconds
                    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),

lib/Alien/GvaScript/lib/GvaScript.js  view on Meta::CPAN

                    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) {
                    previousBtn.removeClassName('btn-focus');
                }
                this.selectedBtn = btn;
                if (btn) {
                    btn.addClassName('btn-focus');
                    try {
                        if(btn.tagName.search(/^(INPUT|BUTTON)$/i) > -1)
                            btn.focus();
                        else
                            btn.down('.btn').focus();
                    } catch (err) {}
                }
            },

lib/Alien/GvaScript/lib/GvaScript.js  view on Meta::CPAN

        }
}());


GvaScript.CustomButtons.ActionsBar = Class.create();
Object.extend(GvaScript.CustomButtons.ActionsBar.prototype, {
    initialize: function(container, options) {
        var bcss = CSSPREFIX();
        var defaults = {
            actions: [],
            selectfirst: false
        }
        this.container = $(container);
        this.container.update('');
        this.options = Object.extend(defaults, options || {});
        this.container.addClassName(bcss+'-actionsbar');

        this.options.actions.each(function(action_props, index) {
            action_props.id = action_props.id || this.container.id + '_btn_' + index;
            // renders a <button> element and appends it to container
            new GvaScript.CustomButtons.Button(this.container, action_props);
        }, this);

        this.buttonNavigation = new GvaScript.CustomButtons.ButtonNavigation(this.container, {
            selectFirstBtn: this.options.selectfirst,
            className: bcss+'-btn-container'
        });

        this.container.store('widget', this);
        this.container.addClassName(bcss+'-widget');
    },
    destroy: function() {
        this.buttonNavigation.destroy();
    }
});

lib/Alien/GvaScript/lib/GvaScript.js  view on Meta::CPAN

                    default          : action_props.condition = eval(prop_condition); break;
                }
                action_props.id = action_props.id || this.getId() + "_btn_" + index;

                // renders a <button> element and appends it to container
                new GvaScript.CustomButtons.Button(this.actionsbar_container, action_props);
            }, this);

            // activate the navigation over the action buttons
            this.actionButtons = new GvaScript.CustomButtons.ButtonNavigation(this.actionsbar_container, {
                selectFirstBtn: false,
                className: bcss+'-btn-container'
            });
        },

        // wrapping the recordset in a table with column headers
        gridWrapper: function(html) {
           return '<table class="'+bcss+'-grid '+this.options.css+'">' +
                    '<thead><tr>' +
                        '<th class="grid-marker">&nbsp;</th>' +
                        (this.columns.collect(function(e) {

lib/Alien/GvaScript/lib/GvaScript.js  view on Meta::CPAN

          elem.checked = false;
          for (var count = val.length; count--;) {
            if (val[count] == elem_val) {
                elem.checked = true;
                break;
            }
          }
          new_value = elem.checked ? elem_val : null;
        break;

        case "select-one" :
        case "select-multiple" :
          var options = elem.options;
          var old_values = [],
              new_values = [];
          for (var i=0, len=options.length; i<len; i++) {
            var opt = options[i];
            var opt_value = opt.value || opt.text;
            if (opt.selected) old_values.push(opt_value);
            // hand-crafted loop through val array (because val.include() is too slow
            opt.selected = false;
            for (var count = val.length; count--;) {
              if (val[count] == opt_value) {
                new_values.push(opt_value);
                opt.selected = true;
                break;
              }
            }
          }
          old_value = old_values.join(",");
          new_value = new_values.join(",");
        break;

        default:
          // if no element type, might be a node list

lib/Alien/GvaScript/lib/GvaScript.js  view on Meta::CPAN

      }
    }
    return fill_from_tree;
  })(),

  autofocus: function(container) {

    if (Object.isString(container)) 
      container = document.getElementById(container);

    // replace prototype's down selector
    // as it performs slowly on IE6
    var _find_autofocus = function(p_node) {
      var _kids = p_node.childNodes;

      for(var _idx = 0, len = _kids.length; _idx < len; ) {
        _kid = _kids[_idx ++];

        if(_kid.nodeType == 1) {
          if(Element.hasAttribute(_kid, 'autofocus')) {
            return _kid;

lib/Alien/GvaScript/lib/GvaScript.js  view on Meta::CPAN

    * wrapper around Element.register method.
    * method wrapped for special handling of form inputs
    * 'change' and 'init' events
    *
    * all handlers will receive 'event' object as a first argument.
    * 'change' handler will also receive input's oldvalue/newvalue as
    * second and third arguments respectively.
    * 'init' handler will also receive input's newvalue as a
    * second argument.
    *
    * @param {string} query : css selector to match elements
    *                         to watch
    * @param {string} eventname : standard event name that can be triggered
    *                             by form inputs + the custom 'init' event
    *                             that is triggerd on form initialization
    * @param {Function} handler : function to execute.
    *
    * @return undefined
    */
  register: function(form, query, eventname, handler) {
      form = $(form);

lib/Alien/GvaScript/lib/GvaScript.js  view on Meta::CPAN

      }
  },

  /**
    * wrapper around Element.unregister method.
    * method wrapped for special handling of form inputs
    * 'change' and 'init' events
    *
    * remove handler attached to eventname for inputs that match query
    *
    * @param {string} query : css selector to remove handlers from
    * @param {string} eventname : eventname to stop observing
    * @param {Funtion} handler : handler to stop firing oneventname
    *                            NOTE: should be identical to what was used in
    *                            register method.
    *                            {optional} : if not specified, will remove all
    *                            handlers attached to eventname for indicated selector
    * @return undefined
    */
  unregister: function(form, query, eventname, handler) {
    form = $(form);

    switch(eventname) {
      case 'change' :
        form.unregister(query, 'focus', handler);
        form.unregister(query, 'blur',  handler);
      break;

lib/Alien/GvaScript/lib/GvaScript.js  view on Meta::CPAN

Object.extend(GvaScript.Form.prototype, function() {
    // private method to initialize and add actions
    // to form's actions bar
    function _addActionButtons(form) {
        var _actionsbar = $H(form.options.actionsbar);
        if(_actions_container = _actionsbar.get('container')) {
            _actions_container = $(_actions_container);
            _actions_list = _actionsbar.get('actions') || [];

            form.actionsbar = new GvaScript.CustomButtons.ActionsBar(_actions_container, {
                selectfirst: _actionsbar.get('selectfirst') ,
                actions: _actions_list
            });
        }
    }

    return {
        formElt: null,
        actionsbar: null,
        initialize: function(formElt, options) {
            this.formElt = $(formElt);

            var defaults = {
                datatree: {},                               // data object to init form with
                dataprefix: '',                             // data prefix used on form elements


                actionsbar: {},                             // form actions
                registry: [],                               // list of [elements_selector, event_name, event_handler]

                skipAutofocus : false,

                onInit           : Prototype.emptyFunction,  // called after form initialization

                onRepeatBlockRemove : Prototype.emptyFunction,  // called when a repeatable block gets removed
                onRepeatBlockAdd    : Prototype.emptyFunction,  // called when a repeatable block gets added

                onChange         : Prototype.emptyFunction,  // called if any input/textarea value change
                onBeforeSubmit   : Prototype.emptyFunction,  // called right after form.submit

lib/Alien/GvaScript/lib/prototype.js  view on Meta::CPAN

    each:       each,
    eachSlice:  eachSlice,
    all:        all,
    every:      all,
    any:        any,
    some:       any,
    collect:    collect,
    map:        collect,
    detect:     detect,
    findAll:    findAll,
    select:     findAll,
    filter:     findAll,
    grep:       grep,
    include:    include,
    member:     include,
    inGroupsOf: inGroupsOf,
    inject:     inject,
    invoke:     invoke,
    max:        max,
    min:        min,
    partition:  partition,

lib/Alien/GvaScript/lib/prototype.js  view on Meta::CPAN


  function first() {
    return this[0];
  }

  function last() {
    return this[this.length - 1];
  }

  function compact() {
    return this.select(function(value) {
      return value != null;
    });
  }

  function flatten() {
    return this.inject([], function(array, value) {
      if (Object.isArray(value))
        return array.concat(value.flatten());
      array.push(value);
      return array;
    });
  }

  function without() {
    var values = slice.call(arguments, 0);
    return this.select(function(value) {
      return !values.include(value);
    });
  }

  function reverse(inline) {
    return (inline === false ? this.toArray() : this)._reverse();
  }

  function uniq(sorted) {
    return this.inject([], function(array, value, index) {

lib/Alien/GvaScript/lib/prototype.js  view on Meta::CPAN

    DOCUMENT_TYPE_NODE: 10,
    DOCUMENT_FRAGMENT_NODE: 11,
    NOTATION_NODE: 12
  });
}



(function(global) {
  function shouldUseCache(tagName, attributes) {
    if (tagName === 'select') return false;
    if ('type' in attributes) return false;
    return true;
  }

  var HAS_EXTENDED_CREATE_ELEMENT_SYNTAX = (function(){
    try {
      var el = document.createElement('<input name="x">');
      return el.tagName.toLowerCase() === 'input' && el.name === 'x';
    }
    catch(err) {

lib/Alien/GvaScript/lib/prototype.js  view on Meta::CPAN


  remove: function(element) {
    element = $(element);
    element.parentNode.removeChild(element);
    return element;
  },

  update: (function(){

    var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){
      var el = document.createElement("select"),
          isBuggy = true;
      el.innerHTML = "<option value=\"test\">test</option>";
      if (el.options && el.options[0]) {
        isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION";
      }
      el = null;
      return isBuggy;
    })();

    var TABLE_ELEMENT_INNERHTML_BUGGY = (function(){

lib/Alien/GvaScript/lib/prototype.js  view on Meta::CPAN


    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);

lib/Alien/GvaScript/lib/prototype.js  view on Meta::CPAN

    }

    return elements;
  },

  ancestors: function(element) {
    return Element.recursivelyCollect(element, 'parentNode');
  },

  descendants: function(element) {
    return Element.select(element, "*");
  },

  firstDescendant: function(element) {
    element = $(element).firstChild;
    while (element && element.nodeType != 1) element = element.nextSibling;
    return $(element);
  },

  immediateDescendants: function(element) {
    var results = [], child = $(element).firstChild;

lib/Alien/GvaScript/lib/prototype.js  view on Meta::CPAN

  nextSiblings: function(element) {
    return Element.recursivelyCollect(element, 'nextSibling');
  },

  siblings: function(element) {
    element = $(element);
    return Element.previousSiblings(element).reverse()
      .concat(Element.nextSiblings(element));
  },

  match: function(element, selector) {
    element = $(element);
    if (Object.isString(selector))
      return Prototype.Selector.match(element, selector);
    return selector.match(element);
  },

  up: function(element, expression, index) {
    element = $(element);
    if (arguments.length == 1) return $(element.parentNode);
    var ancestors = Element.ancestors(element);
    return Object.isNumber(expression) ? ancestors[expression] :
      Prototype.Selector.find(ancestors, expression, index);
  },

  down: function(element, expression, index) {
    element = $(element);
    if (arguments.length == 1) return Element.firstDescendant(element);
    return Object.isNumber(expression) ? Element.descendants(element)[expression] :
      Element.select(element, expression)[index || 0];
  },

  previous: function(element, expression, index) {
    element = $(element);
    if (Object.isNumber(expression)) index = expression, expression = false;
    if (!Object.isNumber(index)) index = 0;

    if (expression) {
      return Prototype.Selector.find(element.previousSiblings(), expression, index);
    } else {

lib/Alien/GvaScript/lib/prototype.js  view on Meta::CPAN


    if (expression) {
      return Prototype.Selector.find(element.nextSiblings(), expression, index);
    } else {
      var maximumLength = Object.isNumber(index) ? index + 1 : 1;
      return element.recursivelyCollect("nextSibling", index + 1)[index];
    }
  },


  select: function(element) {
    element = $(element);
    var expressions = Array.prototype.slice.call(arguments, 1).join(', ');
    return Prototype.Selector.select(expressions, element);
  },

  adjacent: function(element) {
    element = $(element);
    var expressions = Array.prototype.slice.call(arguments, 1).join(', ');
    return Prototype.Selector.select(expressions, element.parentNode).without(element);
  },

  identify: function(element) {
    element = $(element);
    var id = Element.readAttribute(element, 'id');
    if (id) return id;
    do { id = 'anonymous_element_' + Element.idCounter++ } while ($(id));
    Element.writeAttribute(element, 'id', id);
    return id;
  },

lib/Alien/GvaScript/lib/prototype.js  view on Meta::CPAN


    if (options.setLeft)   element.style.left  = (p[0] - delta[0] + options.offsetLeft) + 'px';
    if (options.setTop)    element.style.top   = (p[1] - delta[1] + options.offsetTop) + 'px';
    if (options.setWidth)  element.style.width = source.offsetWidth + 'px';
    if (options.setHeight) element.style.height = source.offsetHeight + 'px';
    return element;
  }
};

Object.extend(Element.Methods, {
  getElementsBySelector: Element.Methods.select,

  childElements: Element.Methods.immediateDescendants
});

Element._attributeTranslations = {
  write: {
    names: {
      className: 'class',
      htmlFor:   'for'
    },

lib/Alien/GvaScript/lib/prototype.js  view on Meta::CPAN

      onmouseover: v._getEv,
      onmousemove: v._getEv,
      onmouseout:  v._getEv,
      onfocus:     v._getEv,
      onblur:      v._getEv,
      onkeypress:  v._getEv,
      onkeydown:   v._getEv,
      onkeyup:     v._getEv,
      onsubmit:    v._getEv,
      onreset:     v._getEv,
      onselect:    v._getEv,
      onchange:    v._getEv
    });
  })(Element._attributeTranslations.read.values);

  if (Prototype.BrowserFeatures.ElementExtensions) {
    (function() {
      function _descendants(element) {
        var nodes = element.getElementsByTagName('*'), results = [];
        for (var i = 0, node; node = nodes[i]; i++)
          if (node.tagName !== "!") // Filter out comment nodes.
            results.push(node);
        return results;
      }

      Element.Methods.down = function(element, expression, index) {
        element = $(element);
        if (arguments.length == 1) return element.firstDescendant();
        return Object.isNumber(expression) ? _descendants(element)[expression] :
          Element.select(element, expression)[index || 0];
      }
    })();
  }

}

else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) {
  Element.Methods.setOpacity = function(element, value) {
    element = $(element);
    element.style.opacity = (value == 1) ? 0.999999 :

lib/Alien/GvaScript/lib/prototype.js  view on Meta::CPAN

    element.appendChild(node);
  },
  after: function(element, node) {
    element.parentNode.insertBefore(node, element.nextSibling);
  },
  tags: {
    TABLE:  ['<table>',                '</table>',                   1],
    TBODY:  ['<table><tbody>',         '</tbody></table>',           2],
    TR:     ['<table><tbody><tr>',     '</tr></tbody></table>',      3],
    TD:     ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4],
    SELECT: ['<select>',               '</select>',                  1]
  }
};

(function() {
  var tags = Element._insertionTranslations.tags;
  Object.extend(tags, {
    THEAD: tags.TBODY,
    TFOOT: tags.TBODY,
    TH:    tags.TD
  });

lib/Alien/GvaScript/lib/prototype.js  view on Meta::CPAN

    }

    return value;
  },

  clone: function(element, deep) {
    if (!(element = $(element))) return;
    var clone = element.cloneNode(deep);
    clone._prototypeUID = void 0;
    if (deep) {
      var descendants = Element.select(clone, '*'),
          i = descendants.length;
      while (i--) {
        descendants[i]._prototypeUID = void 0;
      }
    }
    return Element.extend(clone);
  },

  purge: function(element) {
    if (!(element = $(element))) return;

lib/Alien/GvaScript/lib/prototype.js  view on Meta::CPAN

        var rect = element.getBoundingClientRect(),
         docEl = document.documentElement;
        return new Element.Offset(rect.left - docEl.clientLeft,
         rect.top - docEl.clientTop);
      }
    });
  }
})();
window.$$ = function() {
  var expression = $A(arguments).join(', ');
  return Prototype.Selector.select(expression, document);
};

Prototype.Selector = (function() {

  function select() {
    throw new Error('Method "Prototype.Selector.select" must be defined.');
  }

  function match() {
    throw new Error('Method "Prototype.Selector.match" must be defined.');
  }

  function find(elements, expression, index) {
    index = index || 0;
    var match = Prototype.Selector.match, length = elements.length, matchIndex = 0, i;

lib/Alien/GvaScript/lib/prototype.js  view on Meta::CPAN

    for (var i = 0, length = elements.length; i < length; i++) {
      Element.extend(elements[i]);
    }
    return elements;
  }


  var K = Prototype.K;

  return {
    select: select,
    match: match,
    find: find,
    extendElements: (Element.extend === K) ? K : extendElements,
    extendElement: Element.extend
  };
})();
Prototype._original_property = window.Sizzle;
/*!
 * Sizzle CSS Selector Engine - v1.0
 *  Copyright 2009, The Dojo Foundation

lib/Alien/GvaScript/lib/prototype.js  view on Meta::CPAN

	done = 0,
	toString = Object.prototype.toString,
	hasDuplicate = false,
	baseHasDuplicate = true;

[0, 0].sort(function(){
	baseHasDuplicate = false;
	return 0;
});

var Sizzle = function(selector, context, results, seed) {
	results = results || [];
	var origContext = context = context || document;

	if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
		return [];
	}

	if ( !selector || typeof selector !== "string" ) {
		return results;
	}

	var parts = [], m, set, checkSet, check, mode, extra, prune = true, contextXML = isXML(context),
		soFar = selector;

	while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) {
		soFar = m[3];

		parts.push( m[1] );

		if ( m[2] ) {
			extra = m[3];
			break;
		}
	}

	if ( parts.length > 1 && origPOS.exec( selector ) ) {
		if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
			set = posProcess( parts[0] + parts[1], context );
		} else {
			set = Expr.relative[ parts[0] ] ?
				[ context ] :
				Sizzle( parts.shift(), context );

			while ( parts.length ) {
				selector = parts.shift();

				if ( Expr.relative[ selector ] )
					selector += parts.shift();

				set = posProcess( selector, set );
			}
		}
	} else {
		if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
				Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
			var ret = Sizzle.find( parts.shift(), context, contextXML );
			context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
		}

		if ( context ) {

lib/Alien/GvaScript/lib/prototype.js  view on Meta::CPAN

		} else {
			checkSet = parts = [];
		}
	}

	if ( !checkSet ) {
		checkSet = set;
	}

	if ( !checkSet ) {
		throw "Syntax error, unrecognized expression: " + (cur || selector);
	}

	if ( toString.call(checkSet) === "[object Array]" ) {
		if ( !prune ) {
			results.push.apply( results, checkSet );
		} else if ( context && context.nodeType === 1 ) {
			for ( var i = 0; checkSet[i] != null; i++ ) {
				if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
					results.push( set[i] );
				}

lib/Alien/GvaScript/lib/prototype.js  view on Meta::CPAN

				break;
			}
		}

		old = expr;
	}

	return curLoop;
};

var Expr = Sizzle.selectors = {
	order: [ "ID", "NAME", "TAG" ],
	match: {
		ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
		CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
		NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
		ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
		TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
		CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
		POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
		PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/

lib/Alien/GvaScript/lib/prototype.js  view on Meta::CPAN

	filters: {
		enabled: function(elem){
			return elem.disabled === false && elem.type !== "hidden";
		},
		disabled: function(elem){
			return elem.disabled === true;
		},
		checked: function(elem){
			return elem.checked === true;
		},
		selected: function(elem){
			elem.parentNode.selectedIndex;
			return elem.selected === true;
		},
		parent: function(elem){
			return !!elem.firstChild;
		},
		empty: function(elem){
			return !elem.firstChild;
		},
		has: function(elem, i, match){
			return !!Sizzle( match[3], elem ).length;
		},

lib/Alien/GvaScript/lib/prototype.js  view on Meta::CPAN

		image: function(elem){
			return "image" === elem.type;
		},
		reset: function(elem){
			return "reset" === elem.type;
		},
		button: function(elem){
			return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
		},
		input: function(elem){
			return /input|select|textarea|button/i.test(elem.nodeName);
		}
	},
	setFilters: {
		first: function(elem, i){
			return i === 0;
		},
		last: function(elem, i, match, array){
			return i === array.length - 1;
		},
		even: function(elem, i){

lib/Alien/GvaScript/lib/prototype.js  view on Meta::CPAN

	return a.compareDocumentPosition(b) & 16;
} : function(a, b){
	return a !== b && (a.contains ? a.contains(b) : true);
};

var isXML = function(elem){
	return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
		!!elem.ownerDocument && elem.ownerDocument.documentElement.nodeName !== "HTML";
};

var posProcess = function(selector, context){
	var tmpSet = [], later = "", match,
		root = context.nodeType ? [context] : context;

	while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
		later += match[0];
		selector = selector.replace( Expr.match.PSEUDO, "" );
	}

	selector = Expr.relative[selector] ? selector + "*" : selector;

	for ( var i = 0, l = root.length; i < l; i++ ) {
		Sizzle( selector, root[i], tmpSet );
	}

	return Sizzle.filter( later, tmpSet );
};


window.Sizzle = Sizzle;

})();

;(function(engine) {
  var extendElements = Prototype.Selector.extendElements;

  function select(selector, scope) {
    return extendElements(engine(selector, scope || document));
  }

  function match(element, selector) {
    return engine.matches(selector, [element]).length == 1;
  }

  Prototype.Selector.engine = engine;
  Prototype.Selector.select = select;
  Prototype.Selector.match = match;
})(Sizzle);

window.Sizzle = Prototype._original_property;
delete Prototype._original_property;

var Form = {
  reset: function(form) {
    form = $(form);
    form.reset();

lib/Alien/GvaScript/lib/prototype.js  view on Meta::CPAN


  findFirstElement: function(form) {
    var elements = $(form).getElements().findAll(function(element) {
      return 'hidden' != element.type && !element.disabled;
    });
    var firstByIndex = elements.findAll(function(element) {
      return element.hasAttribute('tabIndex') && element.tabIndex >= 0;
    }).sortBy(function(element) { return element.tabIndex }).first();

    return firstByIndex ? firstByIndex : elements.find(function(element) {
      return /^(?:input|select|textarea)$/i.test(element.tagName);
    });
  },

  focusFirstElement: function(form) {
    form = $(form);
    var element = form.findFirstElement();
    if (element) element.activate();
    return form;
  },

lib/Alien/GvaScript/lib/prototype.js  view on Meta::CPAN


/*--------------------------------------------------------------------------*/


Form.Element = {
  focus: function(element) {
    $(element).focus();
    return element;
  },

  select: function(element) {
    $(element).select();
    return element;
  }
};

Form.Element.Methods = {

  serialize: function(element) {
    element = $(element);
    if (!element.disabled && element.name) {
      var value = element.getValue();

lib/Alien/GvaScript/lib/prototype.js  view on Meta::CPAN

  },

  present: function(element) {
    return $(element).value != '';
  },

  activate: function(element) {
    element = $(element);
    try {
      element.focus();
      if (element.select && (element.tagName.toLowerCase() != 'input' ||
          !(/^(?:button|reset|submit)$/i.test(element.type))))
        element.select();
    } catch (e) { }
    return element;
  },

  disable: function(element) {
    element = $(element);
    element.disabled = true;
    return element;
  },

lib/Alien/GvaScript/lib/prototype.js  view on Meta::CPAN

    if (Object.isUndefined(value))
      return element.checked ? element.value : null;
    else element.checked = !!value;
  }

  function valueSelector(element, value) {
    if (Object.isUndefined(value)) return element.value;
    else element.value = value;
  }

  function select(element, value) {
    if (Object.isUndefined(value))
      return (element.type === 'select-one' ? selectOne : selectMany)(element);

    var opt, currentValue, single = !Object.isArray(value);
    for (var i = 0, length = element.length; i < length; i++) {
      opt = element.options[i];
      currentValue = this.optionValue(opt);
      if (single) {
        if (currentValue == value) {
          opt.selected = true;
          return;
        }
      }
      else opt.selected = value.include(currentValue);
    }
  }

  function selectOne(element) {
    var index = element.selectedIndex;
    return index >= 0 ? optionValue(element.options[index]) : null;
  }

  function selectMany(element) {
    var values, length = element.length;
    if (!length) return null;

    for (var i = 0, values = []; i < length; i++) {
      var opt = element.options[i];
      if (opt.selected) values.push(optionValue(opt));
    }
    return values;
  }

  function optionValue(opt) {
    return Element.hasAttribute(opt, 'value') ? opt.value : opt.text;
  }

  return {
    input:         input,
    inputSelector: inputSelector,
    textarea:      valueSelector,
    select:        select,
    selectOne:     selectOne,
    selectMany:    selectMany,
    optionValue:   optionValue,
    button:        valueSelector
  };
})();

/*--------------------------------------------------------------------------*/


Abstract.TimedObserver = Class.create(PeriodicalExecuter, {
  initialize: function($super, element, frequency, callback) {

lib/Alien/GvaScript/lib/prototype.js  view on Meta::CPAN


    if (document.createEvent)
      element.dispatchEvent(event);
    else
      element.fireEvent(event.eventType, event);

    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;
    },

    handleEvent: function(event) {
      var element = Event.findElement(event, this.selector);
      if (element) this.callback.call(this.element, event, element);
    }
  });

  function on(element, eventName, selector, callback) {
    element = $(element);
    if (Object.isFunction(selector) && Object.isUndefined(callback)) {
      callback = selector, selector = null;
    }

    return new Event.Handler(element, eventName, selector, callback).start();
  }

  Object.extend(Event, Event.Methods);

  Object.extend(Event, {
    fire:          fire,
    observe:       observe,
    stopObserving: stopObserving,
    on:            on
  });

lib/Alien/GvaScript/lib/prototype.js  view on Meta::CPAN


/*--------------------------------------------------------------------------*/

Element.ClassNames = Class.create();
Element.ClassNames.prototype = {
  initialize: function(element) {
    this.element = $(element);
  },

  _each: function(iterator) {
    this.element.className.split(/\s+/).select(function(name) {
      return name.length > 0;
    })._each(iterator);
  },

  set: function(className) {
    this.element.className = className;
  },

  add: function(classNameToAdd) {
    if (this.include(classNameToAdd)) return;

lib/Alien/GvaScript/lib/prototype.js  view on Meta::CPAN


/*--------------------------------------------------------------------------*/

(function() {
  window.Selector = Class.create({
    initialize: function(expression) {
      this.expression = expression.strip();
    },

    findElements: function(rootElement) {
      return Prototype.Selector.select(this.expression, rootElement);
    },

    match: function(element) {
      return Prototype.Selector.match(element, this.expression);
    },

    toString: function() {
      return this.expression;
    },

lib/Alien/GvaScript/lib/prototype.js  view on Meta::CPAN

      var matchIndex = 0, element;
      for (var i = 0, length = elements.length; i < length; i++) {
        element = elements[i];
        if (Prototype.Selector.match(element, expression) && index === matchIndex++) {
          return Element.extend(element);
        }
      }
    },

    findChildElements: function(element, expressions) {
      var selector = expressions.toArray().join(', ');
      return Prototype.Selector.select(selector, element || document);
    }
  });
})();

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

  _typeAhead : function () {
    var curLen     = this.lastTypedValue.length;
    var index      = this.choiceList.currentHighlightedIndex;
    var suggestion = this._valueFromChoice(index);
    var newLen     = suggestion.length;
    this._setValue(suggestion);

    if (this.inputElement.createTextRange){ // MSIE
      var range = this.inputElement.createTextRange();
      range.moveStart("character", curLen); // no need to moveEnd
      range.select(); // will call focus();
    }
    else if (this.inputElement.setSelectionRange){ // Mozilla
      this.inputElement.setSelectionRange(curLen, newLen);
    }
  },



//----------------------------------------------------------------------
// methods for the dropdown list of choices

src/autoCompleter.js  view on Meta::CPAN

      }

      // catch keypress on TAB while choiceList has focus
      cl.keymap.rules[0].TAB = cl.keymap.rules[0].S_TAB = function(event) {
        var index = cl.currentHighlightedIndex;
        if (index != undefined) {

          var elem = cl._choiceElem(index);

          // generate a "Ping" on the choiceList, like if user had
          // pressed RETURN to select the current highlighted item
          cl.fireEvent({type : "Ping",
                        index: index}, elem, cl.container);

          // NO Event.stop() here, because the navigator should
          // do the tabbing (pass focus to next/previous element)
        }
      };

      // more key handlers when the suggestion list is displayed
      this.keymap.rules.push(cl.keymap.rules[0]);

src/autoCompleter.js  view on Meta::CPAN

    return (choice !== null) ? this._valueFromChoiceItem(choice) : null;
  },

  _valueFromChoiceItem: function(choice) {
    return (typeof choice == "string") ? choice
                                       : choice[this.options.valueField];
  },



  //triggered by the onPing event on the choicelist, i.e. when the user selects
  //one of the choices in the list
  _completeFromChoiceElem: function(elem) {
    // identify the selected line and handle it
    var num = parseInt(elem.id.match(/\.(\d+)$/)[1], 10);

    // add the value to the input element
    var value = this._valueFromChoice(num);
    if (value !== null) {
      this._setValue(value)
      this._removeDropdownDiv();
      
      // ADDED LEMOINEJ 26.09.13
      this._timeLastCheck = this._timeLastKeyDown = 0;      
      this._checkNewValue();

      if (!this.options.multivalued) {
        this.inputElement.select();
      }

      this._updateDependentFields(this.inputElement, this.choices[num]);

      // fire events: "Complete" for backwards compatibility, "LegalValue"
      // for regular use
      var eventNames =  ["Complete", "LegalValue"];
      // for loop : can't use .each() from prototype.js because it alters "this"
      for (var i = 0; i < eventNames.length; i++) {
        this.fireEvent({
          type      : eventNames[i],
          referrer  : "select",    // choice selection fired this event
          index     : num,
          choice    : this.choices[num],
          controller: {choices: this.choices}
          }, elem, this.inputElement);
      }
    }
  }
}


src/choiceList.js  view on Meta::CPAN

      var newIndex = this._choiceIndex(elem);
      this._highlightChoiceNum(newIndex, false);
      this._clickHandler(event);
    }
  },

  _clickHandler: function(event) {
    var elem = this._findChoiceItem(event);
    if (elem) {
      var newIndex = this._choiceIndex(elem);
      // check if choice is selected
      if (this.currentHighlightedIndex == newIndex) {
        // selected -> fire ping event
        var toStop = this.fireEvent({type : "Ping",
                                    index: this._choiceIndex(elem)},
                                    elem,
                                    this.container);
        Event.detailedStop(event, toStop || Event.stopAll);
      }
      else {
        // not selected -> select
        this._highlightChoiceNum(newIndex, false);
      }
    }
  },

  _returnHandler: function(event) {
    var index = this.currentHighlightedIndex;
    if (index != undefined) {
      var elem = this._choiceElem(index);
      var toStop = this.fireEvent({type : "Ping",

src/customButtons.js  view on Meta::CPAN

        }
    }
}());

GvaScript.CustomButtons.ButtonNavigation = Class.create();
Object.extend(GvaScript.CustomButtons.ButtonNavigation.prototype, function() {
        // private members
        var bcss = CSSPREFIX();

        function _leftHandler(event) {
            var selectedBtn = this.selectedBtn;
            if (selectedBtn) {
                var nextBtn = this.previousBtn(selectedBtn);

                if (nextBtn) this.select(nextBtn);
                else         selectedBtn.flash();

                Event.stop(event);
            }
        }
        function _rightHandler(event) {
            var selectedBtn = this.selectedBtn;
            if (selectedBtn) {
                var prevBtn = this.nextBtn(selectedBtn);

                if (prevBtn) this.select(prevBtn);
                else         selectedBtn.flash();

                Event.stop(event);
            }
        }
        function _tabHandler(event) {
            if (this.options.preventListBlur)
                if (this.isLast(this.selectedBtn))
                    Event.stop(event);
        }
        function _shiftTabHandler(event) {
            if (this.options.preventListBlur)
                if (this.isFirst(this.selectedBtn))
                    Event.stop(event);
        }
        function _homeHandler(event) {
            if (this.selectedBtn) {
                this.select(this.firstBtn());
                Event.stop(event);
            }
        }
        function _endHandler(event) {
            if (this.selectedBtn) {
                this.select(this.lastBtn());
                Event.stop(event);
            }
        }
        function _addHandlers() {
            this.buttons.each(function(btnContainer) {
                var btn;
                // if the button is a GvaScript.CustomButtons.BUTTON, then the actual <button> element
                // will be embedded and selectable via .btn classname:
                // <span class="gva-btn-container">
                //         <span class="left"/>
                //         <span class="center">
                //                 <button accesskey="r" class="btn" style="width: auto;" id="btn_1226916357164">
                //                         Rechercher dans Calvin
                //                 </button>
                //         </span>
                //         <span class="right"/>
                // </span>
                // this will be cleaner when all application buttons are transformed into

src/customButtons.js  view on Meta::CPAN

                    btn.visible        = function() {return btnContainer.visible();}
                    // 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) {
                var defaults = {
                    preventListBlur     : false,
                    flashDuration       : 100,     // milliseconds
                    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),

src/customButtons.js  view on Meta::CPAN

                    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) {
                    previousBtn.removeClassName('btn-focus');
                }
                this.selectedBtn = btn;
                if (btn) {
                    btn.addClassName('btn-focus');
                    try {
                        if(btn.tagName.search(/^(INPUT|BUTTON)$/i) > -1)
                            btn.focus();
                        else
                            btn.down('.btn').focus();
                    } catch (err) {}
                }
            },

src/customButtons.js  view on Meta::CPAN

        }
}());


GvaScript.CustomButtons.ActionsBar = Class.create();
Object.extend(GvaScript.CustomButtons.ActionsBar.prototype, {
    initialize: function(container, options) {
        var bcss = CSSPREFIX();
        var defaults = {
            actions: [],
            selectfirst: false
        }
        this.container = $(container);
        this.container.update('');
        this.options = Object.extend(defaults, options || {});
        this.container.addClassName(bcss+'-actionsbar');

        this.options.actions.each(function(action_props, index) {
            action_props.id = action_props.id || this.container.id + '_btn_' + index;
            // renders a <button> element and appends it to container
            new GvaScript.CustomButtons.Button(this.container, action_props);
        }, this);

        this.buttonNavigation = new GvaScript.CustomButtons.ButtonNavigation(this.container, {
            selectFirstBtn: this.options.selectfirst,
            className: bcss+'-btn-container'
        });

        this.container.store('widget', this);
        this.container.addClassName(bcss+'-widget');
    },
    destroy: function() {
        this.buttonNavigation.destroy();
    }
});

src/form.js  view on Meta::CPAN

          elem.checked = false;
          for (var count = val.length; count--;) {
            if (val[count] == elem_val) {
                elem.checked = true;
                break;
            }
          }
          new_value = elem.checked ? elem_val : null;
        break;

        case "select-one" :
        case "select-multiple" :
          var options = elem.options;
          var old_values = [],
              new_values = [];
          for (var i=0, len=options.length; i<len; i++) {
            var opt = options[i];
            var opt_value = opt.value || opt.text;
            if (opt.selected) old_values.push(opt_value);
            // hand-crafted loop through val array (because val.include() is too slow
            opt.selected = false;
            for (var count = val.length; count--;) {
              if (val[count] == opt_value) {
                new_values.push(opt_value);
                opt.selected = true;
                break;
              }
            }
          }
          old_value = old_values.join(",");
          new_value = new_values.join(",");
        break;

        default:
          // if no element type, might be a node list

src/form.js  view on Meta::CPAN

      }
    }
    return fill_from_tree;
  })(),

  autofocus: function(container) {

    if (Object.isString(container)) 
      container = document.getElementById(container);

    // replace prototype's down selector
    // as it performs slowly on IE6
    var _find_autofocus = function(p_node) {
      var _kids = p_node.childNodes;

      for(var _idx = 0, len = _kids.length; _idx < len; ) {
        _kid = _kids[_idx ++];

        if(_kid.nodeType == 1) {
          if(Element.hasAttribute(_kid, 'autofocus')) {
            return _kid;

src/form.js  view on Meta::CPAN

    * wrapper around Element.register method.
    * method wrapped for special handling of form inputs
    * 'change' and 'init' events
    *
    * all handlers will receive 'event' object as a first argument.
    * 'change' handler will also receive input's oldvalue/newvalue as
    * second and third arguments respectively.
    * 'init' handler will also receive input's newvalue as a
    * second argument.
    *
    * @param {string} query : css selector to match elements
    *                         to watch
    * @param {string} eventname : standard event name that can be triggered
    *                             by form inputs + the custom 'init' event
    *                             that is triggerd on form initialization
    * @param {Function} handler : function to execute.
    *
    * @return undefined
    */
  register: function(form, query, eventname, handler) {
      form = $(form);

src/form.js  view on Meta::CPAN

      }
  },

  /**
    * wrapper around Element.unregister method.
    * method wrapped for special handling of form inputs
    * 'change' and 'init' events
    *
    * remove handler attached to eventname for inputs that match query
    *
    * @param {string} query : css selector to remove handlers from
    * @param {string} eventname : eventname to stop observing
    * @param {Funtion} handler : handler to stop firing oneventname
    *                            NOTE: should be identical to what was used in
    *                            register method.
    *                            {optional} : if not specified, will remove all
    *                            handlers attached to eventname for indicated selector
    * @return undefined
    */
  unregister: function(form, query, eventname, handler) {
    form = $(form);

    switch(eventname) {
      case 'change' :
        form.unregister(query, 'focus', handler);
        form.unregister(query, 'blur',  handler);
      break;

src/form.js  view on Meta::CPAN

Object.extend(GvaScript.Form.prototype, function() {
    // private method to initialize and add actions
    // to form's actions bar
    function _addActionButtons(form) {
        var _actionsbar = $H(form.options.actionsbar);
        if(_actions_container = _actionsbar.get('container')) {
            _actions_container = $(_actions_container);
            _actions_list = _actionsbar.get('actions') || [];

            form.actionsbar = new GvaScript.CustomButtons.ActionsBar(_actions_container, {
                selectfirst: _actionsbar.get('selectfirst') ,
                actions: _actions_list
            });
        }
    }

    return {
        formElt: null,
        actionsbar: null,
        initialize: function(formElt, options) {
            this.formElt = $(formElt);

            var defaults = {
                datatree: {},                               // data object to init form with
                dataprefix: '',                             // data prefix used on form elements


                actionsbar: {},                             // form actions
                registry: [],                               // list of [elements_selector, event_name, event_handler]

                skipAutofocus : false,

                onInit           : Prototype.emptyFunction,  // called after form initialization

                onRepeatBlockRemove : Prototype.emptyFunction,  // called when a repeatable block gets removed
                onRepeatBlockAdd    : Prototype.emptyFunction,  // called when a repeatable block gets added

                onChange         : Prototype.emptyFunction,  // called if any input/textarea value change
                onBeforeSubmit   : Prototype.emptyFunction,  // called right after form.submit

src/grid.js  view on Meta::CPAN

                    default          : action_props.condition = eval(prop_condition); break;
                }
                action_props.id = action_props.id || this.getId() + "_btn_" + index;

                // renders a <button> element and appends it to container
                new GvaScript.CustomButtons.Button(this.actionsbar_container, action_props);
            }, this);

            // activate the navigation over the action buttons
            this.actionButtons = new GvaScript.CustomButtons.ButtonNavigation(this.actionsbar_container, {
                selectFirstBtn: false,
                className: bcss+'-btn-container'
            });
        },

        // wrapping the recordset in a table with column headers
        gridWrapper: function(html) {
           return '<table class="'+bcss+'-grid '+this.options.css+'">' +
                    '<thead><tr>' +
                        '<th class="grid-marker">&nbsp;</th>' +
                        (this.columns.collect(function(e) {

src/protoExtensions.js  view on Meta::CPAN

  var eventManager = function(o_id, event) {
    // IE sometimes fires some events
    // while reloading (after unregister)
    if(! rules[o_id]) return;

    var element = event.target;
    var eventType = (event.memo)? event.eventName : event.type;
    do {
      if (element.nodeType == 1) {
        element = Element.extend(element);
        for (var selector in rules[o_id][eventType]) {
          if (_match = matches(rules[o_id][eventType][selector]._selector, element)) {
            for (var i=0, handlers=rules[o_id][eventType][selector], l=handlers.length; i<l; ++i) {
              handlers[i].call(element, Object.extend(event, { _target: element, _match: _match }));
            }
          }
        }
      }
    } while (element = element.parentNode)
  }
  var matches = function(selectors, element) {
    for (var i=0, l=selectors.length; i<l; ++i) {
      if (Prototype.Selector.match(element, selectors[i])) return selectors[i];
    }
    return undefined;
  }

  Event.register = function(observer, selector, eventName, handler) {
    var use_capture = (eventName == 'focus' || eventName == 'blur');
    if(use_capture && Prototype.Browser.IE) {
        eventName = (eventName == 'focus')? 'focusin' : 'focusout';
    }
    var observer_id = observer.identify ? observer.identify() : 'document';

    // create entry in cache for rules per observer
    if(! rules[observer_id]) {
        rules[observer_id] = { };
    }

src/protoExtensions.js  view on Meta::CPAN

      if(use_capture) {
        if(Prototype.Browser.IE)
        Event.observe(observer, eventName, eventManager.curry(observer_id));
        else
        observer.addEventListener(eventName, eventManager.curry(observer_id), true);
      }
      else
      Event.observe(observer, eventName, eventManager.curry(observer_id));
    }

    var _selector = [ ], expr = selector.strip();
    // instantiate Selector's
    exprSplit(selector).each(function(s) { _selector.push(s) })

    // store instantiated Selector for faster matching
    if (!rules[observer_id][eventName][expr]) {
      rules[observer_id][eventName][expr] = Object.extend([ ], { _selector: _selector });
    }

    // associate handler with expression
    rules[observer_id][eventName][expr].push(handler);
  }

  // unregistering an event on an elemment
  Event.unregister = function(elt, selector, eventName) {
    var _id = (typeof elt == 'string')? elt :
              (elt.identify)? elt.identify() : 'document';
    // unregister event identified by name and selector
    if (eventName) {
      rules[_id][eventName][selector] = null;
      delete rules[_id][eventName][selector];
    }
    else {
      for (var eventName in rules[_id]) {
        // unregister all events identified by selector
        if(selector) {
          rules[_id][eventName][selector] = null;
          delete rules[_id][eventName][selector];
        }
        // unregister all events
        else {
          rules[_id][eventName] = null;
          delete rules[_id][eventName];
        }
      }
    }
  },

src/treeNavigator.js  view on Meta::CPAN


  elem = $(elem); // in case we got an id instead of an element
  options = options || {};

  // default options
  var defaultOptions = {
    tabIndex            : -1,
    treeTabIndex        :  0,
    flashDuration       : 200,     // milliseconds
    flashColor          : "red",
    selectDelay         : 100,     // milliseconds
    selectOnButtonClick : true,
    noPingOnFirstClick  : false,
    selectFirstNode     : true,
    createButtons       : true,
    scrollingContainer  : elem.ownerDocument.documentElement,
    autoScrollPercentage: 20,
    classes             : {},
    keymap              : null
  };

  this.options = Class.checkOptions(defaultOptions, options);

  // values can be single class names or arrays of class names
  var defaultClasses = {
    node     : "TN_node",
    leaf     : "TN_leaf",
    label    : "TN_label",
    closed   : "TN_closed",
    content  : "TN_content",
    selected : "TN_selected",
    mouse    : "TN_mouse",
    button   : "TN_button",
    showall  : "TN_showall"
  };
  this.classes = Class.checkOptions(defaultClasses, this.options.classes);
  this.classes.nodeOrLeaf = [this.classes.node, this.classes.leaf].flatten();

  // connect to the root element
  this.rootElement = elem;

src/treeNavigator.js  view on Meta::CPAN

    this.keymap = new GvaScript.KeyMap(keyHandlers);

    // observe keyboard events on tree (preferred) or on document
    var target = (elem.tabIndex  < 0) ? document : elem;
    this.keymap.observe("keydown", target, Event.stopNone);
  }

  this.rootElement.store('widget', this);
  this.rootElement.addClassName(CSSPREFIX() + '-widget');

  // selecting the first node
  if (this.options.selectFirstNode) {
    this.select(this.firstSubNode());

    // if labels do not take focus but tree does, then set focus on the tree
    if (this.options.tabIndex < 0 && elem.tabIndex >= 0)
      elem.focus();
  }
}


GvaScript.TreeNavigator.prototype = {

//-----------------------------------------------------
// Public methods
//-----------------------------------------------------
  destroy: function() {
    this._removeHandlers();
  },

  initSubTree: function (tree_root) {
    tree_root = $(tree_root);
    // get the labels of the sub tree
    var labels = tree_root.select('.'+this.classes.label);

    // add tabIndex per label
    if (this.options.tabIndex >= 0) {
      _idx = this.options.tabIndex;
      labels.each(function(label) {
        label.tabIndex = _idx;
      });
    }

    // add tree navigation buttons per label

src/treeNavigator.js  view on Meta::CPAN

      var treeNavigator = this; // needed for closure below
      var callback = function() {
        treeNavigator.initSubTree(content);
        treeNavigator.fireEvent("AfterLoadContent", node, this.rootElement);
      };
      new Ajax.Updater(content, url, {onComplete: callback});
      return true;
    }
  },

  select: function (node) {
    var previousNode = this.selectedNode;

    // re-selecting the current node is a no-op
    if (node == previousNode) return;

    // deselect the previously selected node
    if (previousNode) {
        var label = this.label(previousNode);
        if (label) {
          Element.removeClassName(label, this.classes.selected);
        }
    }

    // select the new node
    this.selectedNode = node;
    if (node) {
      this._assertNodeOrLeaf(node, 'select node');
      var label = this.label(node);
      if (!label) {
        throw new Error("selected node has no label");
      }
      else {
        Element.addClassName(label, this.classes.selected);

        if (this.isVisible(label)) {
          // focus has not yet been given to label
          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);
    }
    if(!container) return;

src/treeNavigator.js  view on Meta::CPAN

      if(container.style.overflow == 'hidden'
        || container.style.overflowY == 'hidden')
      return;
    }

    // test if the node in 'in view'
    _container_y_start = container.scrollTop;
    _container_y_end   = _container_y_start + container.clientHeight;
    _node_y  = Element.cumulativeOffset(node).top + (with_content? node.offsetHeight: 0);

    // calculate padding space between the selected node and
    // the edge of the scrollable container
    _perc = this.options.autoScrollPercentage || 0;
    _padding = container.clientHeight * _perc / 100;

    // calculate delta scroll to affect on scrollingContainer
    _delta = 0;

    // node is beneath scrolling area
    if(_node_y > _container_y_end - _padding) {
      _delta = _node_y - _container_y_end + _padding;

src/treeNavigator.js  view on Meta::CPAN


    if(label = this.isLabel(target)) {
      Element.removeClassName(label, this.classes.mouse);
      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);

    // should ping : depends on options.noPingOnFirstClick
    var should_ping = (!is_first_click) || !this.options.noPingOnFirstClick;

    // do the ping if necessary
    var event_stop_mode;
    if (should_ping)
    event_stop_mode = this.fireEvent("Ping", node, this.rootElement);

    // avoid a second ping from the dblclick handler

src/treeNavigator.js  view on Meta::CPAN

    var treeNavigator = this; // handlers will be closures on this

    // focus handler
    var focus_handler = function(e) {
      var label = e._target;
      label.writeAttribute('hasFocus', 'hasFocus');

      var node  = Element.navigateDom(label, 'parentNode',
                                      treeNavigator.classes.nodeOrLeaf);

      // not yet been selected
      if(node && !label.hasClassName(treeNavigator.classes.selected)) {
        treeNavigator.select  (node);
      }
    };

    // blur handler
    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
//-----------------------------------------------------

  _selectionTimeoutHandler: function(previousNode) {
      this._selectionTimeoutId = null;

      var newNode = this.selectedNode;

      // fire events
      if (previousNode != newNode) {
        if (previousNode) {
          this.fireEvent("Deselect", previousNode, this.rootElement);
        }
        if (newNode) {
          this.fireEvent("Select", newNode, this.rootElement);
        }
      }
  },


//-----------------------------------------------------
// Key handlers
//-----------------------------------------------------
  _charHandler: function (event) {
    var selectedNode = this.selectedNode;
    if(! selectedNode) return;

    // stop firefox quick search if enabled
    // via "accessibility.typeaheadfind" => 'true'
    Event.stop(event);

    this._quick_navi_word += event.keyName; // always uppercase
    var is_quick_navi_mode = (this._quick_navi_mode !== false);

    // drop the previous timer
    if(is_quick_navi_mode) {
      window.clearTimeout(this._quick_navi_mode);
    }
    // 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;
    });

    // returns first label found to start with word.
    var find_match = function(labels, word) {
        var match = labels.find(function(label) {
            return label.innerHTML.stripTags()          // in case label contains HTML elements
                    .replace(/\r?\n/g, '')              // clear line breaks
                    .replace(/\ \ /g, '')               // clear white-spaces
                    .toUpperCase().startsWith(word);
        });
        return match;
    }

    // first look ahead then look back
    var matching_label  =  find_match(labels[1], this._quick_navi_word)
                        || find_match(labels[0], this._quick_navi_word);

    // found a match -> make it visible and select it
    if(matching_label) {
      this.openEnclosingNodes(matching_label);

      var znode = this.enclosingNode(matching_label);
      this.scrollTo(znode);
      this.select  (znode);
    }
    // no match -> flash the selected label
    else {
      this.label(this.selectedNode).flash();
    }
  },

  _downHandler: function (event) {
    var selectedNode = this.selectedNode;
    if (selectedNode) {
      var nextNode = this.nextDisplayedNode(selectedNode);
      if (nextNode) {
        this.scrollTo(nextNode);
        this.select  (nextNode);
      }
      else this.flash(selectedNode);

      Event.stop(event);
    }
    // otherwise: do nothing and let default behaviour happen
  },

  _upHandler: function (event) {
    var selectedNode = this.selectedNode;
    if (selectedNode) {
      var prevNode = this.previousDisplayedNode(selectedNode);
      if (prevNode) {
        this.scrollTo(prevNode);
        this.select  (prevNode);
      }
      else this.flash(selectedNode);

      Event.stop(event);
    }
    // otherwise: do nothing and let default behaviour happen
  },

  _leftHandler: function (event) {
    var selectedNode = this.selectedNode;
    if (selectedNode) {
      if (!this.isLeaf(selectedNode) && !this.isClosed(selectedNode)) {
        this.close(selectedNode);
      }
      else {
        var zparent = this.parentNode(selectedNode);
        if (zparent) {
          this.scrollTo(zparent);
          this.select  (zparent);
        }
        else
          this.flash(selectedNode);
      }
      Event.stop(event);
    }
  },

  _rightHandler: function (event) {
    var selectedNode = this.selectedNode;
    if (selectedNode) {
      if (this.isLeaf(selectedNode)) return;
      if (this.isClosed(selectedNode))
        this.open(selectedNode);
      else {
        var subNode = this.firstSubNode(selectedNode);
        if (subNode) {
          this.scrollTo(subNode);
          this.select  (subNode);
        }
        else
          this.flash(selectedNode);
      }
      Event.stop(event);
    }
  },

  _tabHandler: function (event) {
    var selectedNode = this.selectedNode;
    if (selectedNode && this.isClosed(selectedNode)) {
      this.open(selectedNode);
      var label = this.label(selectedNode);
      Event.stop(event);
    }
  },

  _kpPlusHandler: function (event) {
    var selectedNode = this.selectedNode;
    if (selectedNode && this.isClosed(selectedNode)) {
      this.open(selectedNode);
      Event.stop(event);
    }
  },

  _kpMinusHandler: function (event) {
    var selectedNode = this.selectedNode;
    if (selectedNode && !this.isClosed(selectedNode)) {
      this.close(selectedNode);
      Event.stop(event);
    }
  },

  _kpStarHandler: function (event) {
    var selectedNode = this.selectedNode;
    if (selectedNode) {
      var nodes = Element.getElementsByClassNames(
        selectedNode,
        this.classes.node
      );
      nodes.unshift(selectedNode);
      nodes.each(function(node) {this.open(node)}, this);
      Event.stop(event);
    }
  },

  _kpSlashHandler: function (event) {
    var selectedNode = this.selectedNode;
    if (selectedNode) {
      var nodes = Element.getElementsByClassNames(
        selectedNode,
        this.classes.node
      );
      nodes.unshift(selectedNode);
      nodes.each(function(node) {this.close(node)}, this);
      Event.stop(event);
    }
  },

  _ctrl_R_handler: function (event) {
    var selectedNode = this.selectedNode;
    if (selectedNode) {
      if (this.loadContent(selectedNode))
        Event.stop(event);
    }
  },

  _ReturnHandler: function (event) {
    var selectedNode = this.selectedNode;
    if (selectedNode) {
      var toStop = this.fireEvent("Ping", selectedNode, this.rootElement);
      Event.detailedStop(event, toStop || Event.stopAll);
    }
  },

  _homeHandler: function (event) {
    if (this.selectedNode) {
      var znode = this.firstSubNode();
      this.scrollTo(znode);
      this.select  (znode);
      Event.stop(event);
    }
  },

  _endHandler: function (event) {
    if (this.selectedNode) {
      var znode = this.lastVisibleSubnode();
      this.scrollTo(znode);
      this.select  (znode);
      Event.stop(event);
    }
  },

  _ctrlPgUpHandler: function (event) {
    var node = this.enclosingNode(Event.element(event));
    if (node) {
      this.scrollTo(node);
      this.select  (node);
      Event.stop(event);
    }
  },

  _ctrlPgDownHandler: function (event) {
    var node = this.enclosingNode(Event.element(event));
    if (node) {
      node = this.nextDisplayedNode(node);
      if (node) {
        this.scrollTo(node);
        this.select  (node);
        Event.stop(event);
      }
    }
  },

  _chooseLevel: function(event) {
    var level = event.keyCode - "0".charCodeAt(0);
    this.openAtLevel(this.rootElement, level);

    // stop the default Ctrl-num event

test/functional/buttons/buttons.html  view on Meta::CPAN

    </div>
    <div id="buttons_placeholder"></div>
  </form>

</div>

</body>

  <script type="text/javascript">
    new GvaScript.CustomButtons.ActionsBar('buttons_placeholder', {
      selectfirst: true,
      actions: [
          {
              label: 'Submit Form',
              type: 'submit'
          },
          {
              label: 'Reset Form',
              type: 'reset'
          },
          {

test/functional/form/validation.js  view on Meta::CPAN

							(parseInt(RegExp.$1, 10) == d.getDate()) && 
							(parseInt(RegExp.$3, 10) == d.getFullYear() );
			}],
	['validate-currency-dollar', 'Please enter a valid $ amount. For example $100.00 .', function(v) {
				// [$]1[##][,###]+[.##]
				// [$]1###+[.##]
				// [$]0.##
				// [$].##
				return Validation.get('IsEmpty').test(v) ||  /^\$?\-?([1-9]{1}[0-9]{0,2}(\,[0-9]{3})*(\.[0-9]{0,2})?|[1-9]{1}\d*(\.[0-9]{0,2})?|0(\.[0-9]{0,2})?|(\.[0-9]{1,2})?)$/.test(v)
			}],
	['validate-selection', 'Please make a selection', function(v,elm){
				return elm.options ? elm.selectedIndex > 0 : !Validation.get('IsEmpty').test(v);
			}],
	['validate-one-required', 'Please select one of the above options.', function (v,elm) {
				var p = elm.parentNode;
				var options = p.getElementsByTagName('INPUT');
				return $A(options).any(function(elm) {
					return $F(elm);
				});
			}]
]);

test/functional/treeNavigator/dropdownMenu.html  view on Meta::CPAN

        if (!menuVisible) return;
        menuVisible = false;

        $('menu').style.display = "none";
        treeNav_rules = textboxKeymap.rules.pop();
        $('textbox').style.backgroundImage = "url(special_icons/navclose.gif)";

        if (event) Event.stop(event);
      }

      function selectEntry(event) {
        var node = Event.element(event);
        if (treeNav.isLeaf(node)) {
          $('textbox').value = node.getAttribute("value");
          hideMenu();
        }
        else {
          var method = treeNav.isClosed(node) ? treeNav.open : treeNav.close;
          method.call(treeNav, node);
        }
      }

test/functional/treeNavigator/dropdownMenu.html  view on Meta::CPAN



  </head>

  <body>

    <h1>Tree Navigator as a dropdown menu</h1>

    Press the DOWN arrow or click on the triangle: <input id='textbox'>

    <div id='menu' onPing="selectEntry" >
      <div class="TN_leaf" value="value1" >
        <div class="TN_label">entry 1</div> 
      </div>
      <div class="TN_leaf" value="value2">
        <div class="TN_label">very <big><b>big</b></big> entry 2</div> 
      </div>
      <div class="TN_leaf" value="value3">
        <div class="TN_label">an <em>emphasized</em> entry 3</div> 
      </div>
      <div class="TN_node TN_closed">

test/functional/treeNavigator/form.html  view on Meta::CPAN

  <link href="../../images/GvaScript.css" rel="stylesheet" type="text/css">
  <script src="../../../lib/Alien/GvaScript/lib/prototype.js"></script>
  <script src="../../../lib/Alien/GvaScript/lib/GvaScript.js"></script>
  <script>
    document.observe('dom:loaded', function() {
      var treeNavigator = new GvaScript.TreeNavigator('TN_tree', {tabIndex: 0}); 

      treeNavigator.keymap.rules.push({
        RETURN: function(event) {
          var elem_type = Event.element(event).type;
          if (/^(text|checkbox|radio|select)$/.test(elem_type))
            Event.stop(event);
        }
      });
    });
  </script>

  <style>
    .TN_node { padding: 8px 2px; background-color: #ddd; border-bottom: 1px solid #aaa;}
    .TN_label { font-weight: 700; font-size: 1.2em;}
    .TN_content { background-color: #eee; padding: 0.5em; margin-top: 5px; }

test/functional/treeNavigator/form.html  view on Meta::CPAN

        <span class="TN_label">section 3 : checkbox</span>
        <div class="TN_content">
          Input checkbox elements: 
            <input type="checkbox" value="check1">check1
            <input type="checkbox" value="check2">check2
            <input type="checkbox" value="check3">check3
        </div>
      </div>

     <div class="TN_node TN_closed">
        <span class="TN_label">section 4 : select</span>
        <div class="TN_content">
          select element: 
          <select name="foo">
            <option>opt1</option>
            <option>opt2</option>
            <option>opt3</option>
            <option>opt4</option>
          </select>

        </div>
      </div>

     <div class="TN_node TN_closed">
        <span class="TN_label">section 5: buttons</span>
        <div class="TN_content">
          <input type="button" onclick="alert('clicked button 1')"
                     value="button 1">
          <input type="button" onclick="alert('clicked button 2')"

test/images/GvaScript.css  view on Meta::CPAN

  background-color: #ff9;
  padding : 4px;
  color: black;
  border: 1px black solid;
}


/* TREE NAVIGATOR */
.TN_node { display : block; }
.TN_label { cursor: pointer; } /* labels are clickable */
.TN_selected { background-color: yellow; } /* how to highlight the current selected node */
.TN_content {  display : block; margin: 0; margin-left: 15px; } /* node content is 15px more on the right than the node itself */
.TN_mouse { text-decoration: underline; } /* class to implement pseudo-hover on node labels */
/* buttons in front of each node label */
.TN_button { 
  background: transparent url(tn_sprite.png) no-repeat 0 -9px;
  float:left;
  width:9px;
  height:9px;
  margin:1px;margin-left:0;
  padding-right:2px;

test/images/GvaScript.css  view on Meta::CPAN

  background-color: #D0D6ED;
  border:1px solid #6F82A5;
}
.gva-grid td {color: navy;}
.gva-grid .grid-marker {
    width:15px;
    background-color: #D0D6ED;
    border:1px solid #6F82A5;
}
.gva-grid tr.liste_highlight td.grid-marker {
    background: #D0D6ED url(selector.gif) no-repeat center center;
}
.gva-grid tr.liste_highlight td.grid-cell {background-color: #6F82A5 !important;color:#f5f5f5 !important;}
.gva-grid td.grid-cell {padding:3px !important;border:1px solid #e8e8e8;}
.gva-grid td.grid-cell.index_1 {background-color:#EFEFEF;}
.gva-grid td.grid-cell.center {text-align:center;float:none;}
.gva-grid td.grid-cell.right {text-align:right;float:none;}
.gva-grid td.grid-cell.red {color:#a00;}


/* FORM REPEAT */



( run in 1.853 second using v1.01-cache-2.11-cpan-49f99fa48dc )