=head1 NAME

GvaScript.Repeat - Support for repeated sections

=head1 SYNOPSIS

  <div repeat="foo">
    <h2>Foo #{foo.ix}</h2>
    This is the repeated foo section
    <table>
      <tr repeat="bar">
        <td>Item #{bar.ix}</td>
        <td><input name="#{bar.path}.buz"></td>
      </tr>
    </table>
     <button onclick="GvaScript.Repeat.add('#{foo.path}.bar')">Add a bar</button>
  </div>  
  <button onclick="GvaScript.Repeat.add('foo')">Add a foo</button>

  <script>
    GvaScript.Repeat.init(document.body);
  </script


=head1 DESCRIPTION

Implements a mechanism for repeated elements within an HTML
page. The main use is within forms, for dynamic expansion
of subforms (see L<Alien::GvaScript::Form>); however
the mechanism will work for any kind of HTML element.

=head2 Terminology

At initialization stage, the DOM is inspected for finding
I<repeat elements> (elements having a C<repeat> attribute).
These elements are removed from the DOM and replaced
by I<placeholders> (empty DOM elements, just marking where
the repetition blocks should be inserted).
Each placeholder stores a I<template>, which is 
a plain string representation of the repeat element, with 
special markup for template instanciation. 
The template may then be dynamically instanciated into
I<repetition blocks> by calling the L</add> method.



 - can be nested
 - inspired by Web Forms

=head1 HTML 

=head2 Markup of repeat elements

  <div repeat="foo" repeat-start="3" repeat-min="2" repeat-max="6" 
                    repeat-prefix="">
    <!-- content to be repeated, using #{foo.ix}, #{foo.path}, etc. -->
  </div>

Any element marked with a non-empty C<repeat> attribute is
a I<repeat element>; the value of that attribute defines
the I<repeat name>. Other attributes are optional. 
Here is the complete list of repeat attributes :

=over

=item repeat

marks the element as a repeat element, and defines the repeat name.

=item repeat-start

defines how many repetition blocks should be automatically
created as initialization time. Default is 1.

=item repeat-min

minimum number of repetition blocks. Prevents deletion
of repetition blocks under that number. Default is 1.

=item repeat-max

maximum number of repetition blocks. Prevents addition
of repetition blocks over that number. Default is 99.

=item repeat-prefix

defines the initial fragment of the C<repeat path> (see 
explanation below). Only valid for top-level repetition elements, 
because nested repetition elements are automatically prefixed
by their parent repetition element. Default is the empty string.

=back


=head2 String substitutions within repeat elements

The content of a repeat element may contain special markup
for repetition variables, which will be replaced by values
when the element is instanciated into a repetition block.

Variables are written C<< #{<repetition name>.<variable>} >>,
like for example C<#{foo.ix}> or C<#{bar.path}>. The repetition
name is the value of the C<repeat> attribute of the repeat element,
as explained above; in this namespace, the following variables
are defined

=over

=item ix 

integer index of the current repetition block, starting at 1.

=item path

cumulated list of repetition name and repetition indices, separated
by dots. 

=item count

current number of repetition blocks for that repeat element.

=item min

value of the C<repeat-min> attribute.

=item max

value of the C<repeat-max> attribute.

=back

The C<path> is unique within any nesting of repeat elements,
and therefore is typically used for ids or for
names of input elements :

  <tr repeat="bar">
    <td>Item #{bar.ix}</td>
    <td><input name="#{bar.path}.buz"></td>
  </tr>

Within the 3rd repetition block of C<bar>, nested
within the 2nd repetition block of C<foo>, the value of
C<#{bar.path}> will be C<foo.2.bar.3> and therefore
in this example the input name would be
C<foo.2.bar.3.buz>.


I<Implementation note>: the C<< #{...} >> syntax for
variables is borrowed from C<prototype.js>'s C<Template>
class; however, the implementation of substitutions
is done in plain javascript, without calling
C<Template.evaluate()> method.

=head1 METHODS

=head2 init

  GvaScript.Repeat.init(element)

Walks down the DOM under the given element, finds all 
elements having a C<repeat> attribute, replaces these
by placeholders.

The C<element> argument will be fed to C<prototype.js>'s
C<$()> function, so it can be either a DOM element or
an id string.

=head2 add

  GvaScript.Repeat.add(repeat_name)

Creates a new repetition block in the DOM, by instanciating
the repeat element C<repeat_name> (including prefix). 
So if the repeat structure looks like

  <div repeat="foo" repeat-prefix="top">
     <div repeat="bar">

then a new C<foo> repetition block is instanciated
through C<add('top.foo')>, and a new C<bar> repetition
block is instanciated through C<add('#{foo.path}.bar')>.


=head1 EVENTS

=head2 onRepeat

