Web Forms 2.0

Elliotte Rusty Harold

Thursday, March 22, 2007

elharo@metalab.unc.edu

http://www.cafeconleche.org/


Why did HTML Forms Succeed?


What are HTML Forms Missing Today?

Of course JavaScript makes up for some of this, but it's relatively hard to write and maintain.

Toolkits help.


History


Web Hypertext Application Technology Working Group (WhatWG)


Web Forms 2.0

provides new strongly-typed input fields, new attributes for defining constraints, a repeating model for declarative repeating of form sections, new DOM interfaces, new DOM events for validation and dependency tracking, and XML submission and initialization of forms. It also standardises and codifies existing practice in areas that have not been previously documented, and clarifies some of the interactions of HTML form controls and CSS.

Primitive Type and Validity Checking

<label>E-mail address: <input type="email" name="addr"></label>
<p>
  <label>Start date: <input type="date" name="start"></label>
</p>


Supported Types


More Type Examples

<form>
<p>
  <label>Time: <input type="time" name="time" /></label>
</p>
<p>
  <label>Date and time: 
  <input type="datetime" name="datetime" />
  </label>
</label>
</p>
<p>
  <label>Local date and time: 
  <input type="datetime-local" name="localdatetime" />
  </label>
</p>
<p>
  <label>Month: <input type="month" name="month" /></label>
</p>
<p>
  <label>Week: <input type="week" name="week" /></label>
</p>
<p>
  <label>Number: <input type="number" name="number" /></label>
</p>
<p>
  <label>URL: <input type="url" name="url" /></label>
</p>
<p>
  <label><input type="submit" value="Send data" /></label>
</p>
</form>


Min and Max

<form>
<p>
  <label>Pick a  number between 1 and 12: 
  <input type="number" name="number" min='1' max='12' />
  </label>
</p>
<p>
  <label>Time: 
  <input type="time" min="08:30" max="12:00" name="morning" />
  </label>
</p>
<p>
  <label>Pick a day: 
  <input type="date" name="date" min="2007-03-22"/>
  </label>
</p>
<p>
  <label>Month: 
  <input type="month" name="month" />
  </label>
</p>
<p>
  <label><input type="submit" value="Send data" /></label>
</p>
</form>


step attribute

<form>
<p>
  <label>Pick a  number between 1 and 12: 
  <input type="number" name="number" min='1' max='12' step='0.01'/>
  </label>
</p>
<p>
  <label>Time: 
  <input type="time" min="08:30" max="12:00" name="morning" step='1'/>
  </label>
</p>
<p>
  <label><input type="submit" value="Send data" /></label>
</p>
</form>


range type

<form>
<input type="range" name="number" 
       min='1' max='12' step='0.01'/></label>
<p> <label> <input type="submit" value="Send data" /> </label> </p> </form>


pattern attribute


<form>
<p>
  <label>Card number: 
  <input type="text" name="cardnumber" 
         pattern='\d\d\d\d ?\d\d\d\d ?\d\d\d\d ?\d(\d\d\d)?'/>
  </label>
</p>
<p>
  <label>
  <input type="submit" value="Send data" />
  </label>
</p>
</form>


required


<form>
<p>
  <label>Card number: 
    <input type="text" name="cardnumber" 
         required="required"
         pattern='\d\d\d\d ?\d\d\d\d ?\d\d\d\d ?\d(\d\d\d)?'/>
  </label>
</p>
<p>
  <label>
    <input type="submit" value="Send data" />
  </label>
</p>
</form>


Datalists

<form>
 <p><label>Type the species:
  <input type="text" name="species" list="species" />
 </label></p>
 <p><datalist id="species">
  <label>
   or choose one from the list:
   <select name="species">
    <option>Double-crested Cormorant</option>
    <option>Great Cormorant</option>
    <option>Great Blue Heron</option>
    <option>Little Blue Heron</option>
    <!-- ... -->
   </select>
  </label>
 </datalist></p>
 <p><label><input type="submit" value="Send data" /></label></p>
</form>


autocomplete

<form>
<p><label>Autocompleting E-mail address: 
  <input type="email" name="addr"/></label></p>
<p><label>Non-autocompleting e-mail address: 
  <input type="email" name="addr" autocomplete='off'/>
</label></p>
<p><label><input type="submit" value="Send data" /></label></p>
</form>


autofocus

<form>
<p>
  <label>E-mail address: 
  <input type="email" name="addr" 
    autofocus='autofocus' />
  </label>
</p>
<p>
  <label><input type="submit" value="Send data" /></label>
</p>
</form>


inputmode

<form>
<p><label>Family name:	
    <input name='family' inputmode='hiragana' />
</label></p>
<p><label>(in kana):	
    <input name='familykana' inputmode='katakana' />
</label></p>
<p><label>Given name:	
    <input name='given' inputmode='hiragana' />
</label></p>
<p><label>(in kana):	
    <input name='givenkana' inputmode='katakana' />
</label></p>
<p><label>Zip code:	
    <input name='zip' inputmode='latin digits' />
</label></p>
<p><label>Address:	
    <input name='address' inputmode='hiragana' />
</label></p>
<p><label>(in kana):	
    <input name='addresskana' inputmode='katakana' />
</label></p>
<p><label>Email:	
    <input name='email' inputmode='latin lowerCase' />
</label></p>
<p><label>Telephone:	
    <input name='telephone' inputmode='latin digits' />
</label></p>
<p><label>Comments:	
    <textarea name='comments' inputmode='user predictOn' />
</label></p>
</form>


inputmode scripts


inputmode modifiers

lowerCase
lowercase
upperCase
uppercase
titleCase
words start with an upper case letter
startUpper
initial uppercase letter, then continue with lowercase letters
digits
digits of a particular script
symbols
symbols, punctuation
predictOn
text prediction on
predictOff
text prediction off (passwords)

Not an exhaustive list


output

<form>
<p>
 <label>Name:
  <input name="a" value="" /> 
 </label>
</p>
<p>
  <output name="greetings" 
          onforminput='value = "Hello" + a.value'>
   Hello
  </output>
</p>
</form>

Hello


Form Controls Can Go Anywhere


The data attribute (for select elements)

<form>
 <label>Choose the species:
    <select name="species" data='examples/species.xhtml'></select>
  </label>
 <label><input type="submit" value="Send data" /></label></p>
</form>


The external data

Prefilling form element values



Repeating Controls


Repetition Templates

<div id="observation" repeat="template">
  <label>Species: 
    <input type="text" name="species[observation].name" value="" />
  </label>
  <label>Count: 
    <input type="number" min='1'  value=""
           name="species[observation].number" />
  </label>
</div>
<div><button type="add" template="observation">Add Species</button></div>

repeat-start

<div id="observation" repeat="template" repeat-start="5">
  <label>Species: 
    <input type="text" name="species[observation].name" value="" />
  </label>
  <label>Count: 
    <input type="number" min='1'  value=""
           name="species[observation].number" />
  </label>
</div>
<div><button type="add" template="observation">Add Species</button></div>

Buttons

add
add a repetition at the end
remove
delete the nearest repetition
move-up
move the nearest ancestor repetition up one
move-down
move the nearest ancestor repetition down one
<div id="observation" repeat="template" repeat-start="5">
  <label>Species: 
    <input type="text" name="species[observation].name" value="" />
  </label>
  <label>Count: 
    <input type="number" min='1'  value=""
           name="species[observation].number" />
  </label>
  <button type="remove">Delete</button>
  <button type="move-up">Move Up</button>
  <button type="move-down">Move Down</button>
</div>
<div><button type="add" template="observation">Add Species</button></div>

repeat-min repeat-max

<div id="observation" repeat="template" 
      repeat-start="5" repeat-min="3" repeat-max="10">
  <label>Species: 
    <input type="text" name="species[observation].name" value="" />
  </label>
  <label>Count: 
    <input type="number" min='1'  value=""
           name="species[observation].number" />
  </label>
<button type="remove">Delete Species</button>
</div>
<div><button type="add" template="observation">Add Species</button></div>

Full REST

method=

Form submission encoding


application/x-www-form-urlencoded


application/x-www-form+xml

This form:

<form action="http://example.com/formprocessor"
      enctype="application/x-www-form+xml"
      method="post">
<label>Family name:	
    <input name='family' />
</label></p>
<p><label>Given name:	
    <input name='given' />
</label></p>
<p><label>Address:	
    <input name='address' />
</label></p>
<p><label>Zip code:	
    <input name='zip' />
</label></p>
<p><label>Email:	
    <input name='email' />
</label></p>
<p><label>Telephone:	
    <input name='telephone' />
</label></p>
<p><label>Comments:	
    <textarea name='comments' />
</label></p>
<p><label><input type="submit" value="Send data" /></label></p>
</form>

Generates this submission:

Content-Type: application/x-www-form+xml

<formdata xmlns="http://n.whatwg.org/formdata">
 <field name="family" index="0">Smith</field>
 <field name="given" index="0">John</field>
 <field name="address" index="0">123 Nowhere Str.</field>
 <field name="zip" index="0">10003</field>
 <field name="email" index="0">jsmith456@aol.com</field>
 <field name="telephone" index="0">212-555-3248</field>
 <field name="comments" index="0">Web Forms 2.0 is cool.</field>
</formdata>

The index increments as necessary to handle repeating fields with the same name.


Files in application/x-www-form+xml


text/plain

This form:

<form action="http://example.com/formprocessor"
      enctype="text/plain"
      method="post">
<label>Family name:	
    <input name='family' />
</label></p>
<p><label>Given name:	
    <input name='given' />
</label></p>
<p><label>Address:	
    <input name='address' />
</label></p>
<p><label>Zip code:	
    <input name='zip' />
</label></p>
<p><label>Email:	
    <input name='email' />
</label></p>
<p><label>Telephone:	
    <input name='telephone' />
</label></p>
<p><label>Comments:	
    <textarea name='comments' />
</label></p>
<p><label><input type="submit" value="Send data" /></label></p>
</form>

Generates this submission:

Content-Type: text/plain

family=Smith
given=John
address=123 Nowhere Str.
zip=10003
email=jsmith456@aol.com
telephone=212-555-3248
comments=Web Forms 2.0 is cool

Other form submission targets

ftp:
GETs the specified file (not very useful)
data:
Load the specified URI, possibly after substituting in the form input
file:
Retrieve the file (GET), launch the file and pass the form input to it (POST), store the form input in the file (PUT), or delete the named file (DELETE)
mailto:
Form input becomes mail headers, except for POST where it's the message body
javascript:
Ignore form input; load the URI

Self Responding Forms


Event Model


Browser Support for Web Forms 2


Web Forms 2 vs. XForms


My Opinion


HTML Next

Over the course of history, a remarkable number of different groups have jumped up and down and said "*We're* the ones defining HTML!!! Listen to *us*!!!". It's foolish to draw conclusions about any HTML-related spec based either on which group is originating it or what anyone claims the browser engineers are going to do.

--Tim Bray on the atom-syntax mailing list, Tuesday, 28 Nov 2006 15:57:50


Web Applications 1.0


More Markup


Predefined class names


Predefined link types

rel

New Elements


canvas

<html><head>
  <title>canvas</title>
   <script type="text/javascript">
      function draw() {
        var canvas = document.getElementById('tutorial');
        if (canvas.getContext){
            var context = canvas.getContext('2d');
            context.fillRect(25, 25, 150, 150);
            context.clearRect(45, 45, 90, 90);
            context.strokeRect(50, 50, 50, 50);
        }
      }
    </script>

</head>
<body onload="draw()">

    <canvas style="border: 1px solid black;" 
            id="tutorial" 
            width="150" height="150"></canvas>

</body>
</html>
View in Browser

Interactive Elements


datagrid


details

<p>Josh Gibson holds the all time major
league record for home runs over a career with 962. </p>
<details>
<legend>Gibson's home runs are often not counted because he
played in the Negro Leagues instead of the white
leagues.</legend>
<p>Hank Aaron had only 755. Babe Ruth had 714. Gibson's home
runs are often not counted because he played in the <a
href="http://en.wikipedia.org/wiki/Negro_League_baseball">Negro
Leagues</a> instead of the white leagues. Aaron certainly had to
face tougher pitching in the integrated leagues of his day, but
Ruth faced weaker pitching than Gibson did. In truth, most
records before about 1950 should come with an asterisk.
 </p>
</details>

menu and command

<menu type="toolbar">
  <command icon="/icons/wishlist.png">Add to Wishlist</command>
  <command icon="/icons/cart.png">Add to Shopping cart</command>
  <command icon="/icons/wallet.png">Buy It Now</command>
</menu>

aside

<aside class="warning">
  <p>This is still in draft status and may change
     before the spoecificaiton is finished.</p>
</aside>

figures and legends

legendimgembedobject
<figure>
  <img src="08fig02.png" width='640' height='480' 
       alt="That value is not valid"/>
  <legend>Figure 8.2
Opera 9 won't allow the user to submit a non-number
 for a numeric typed field</legend>
</figure>

m

The Great <m>Egret</m> (also known as the
American <m>Egret</m>)  is a large wading bird found worldwide.
The Great <m>Egret</m> flies with slow wing beats.  The
scientific name of the Great <m>Egret</m> is <i>Casmerodius
albus</i>.

section

<section>
  <h1>Validity</h1>
  ...
  <section>
    <h2>Add a Transitional DOCTYPE declaration</h2>
    ...
    <section>
      <h3>Motivation</h3>
      ...
    </section>
    <section>
      <h3>Potential Trade-offs</h3>
      ...
    </section>
    <section>
      <h3>Mechanics</h3>
      ...
    </section>
  </section>
  <section>
    <h2>Eliminate bogons</h2>
    ...
    <section>
      <h3>Motivation</h3>
      ...
    </section>
    <section>
      <h3>Potential Trade-offs</h3>
      ...
    </section>
    <section>
      <h3>Mechanics</h3>
      ...
    </section>
  </section>  <section>
    <h2>Add alt attributes</h2>
    ...
    <section>
      <h3>Motivation</h3>
      ...
    </section>
    <section>
      <h3>Potential Trade-offs</h3>
      ...
    </section>
    <section>
      <h3>Mechanics</h3>
      ...
    </section>
  </section>
</section>

header

<section>
  <header>
   <p>Chapter 4</p>
   <h1>Validity</h1>
   <p>Revision information...</p>
   <p>Abstract...</p>
   <p>Epigraph...</p>
  </header>
  ...
</section>

footer

<footer>
  <address>
    <a href="mailto:author@somewhere.org">author@somewhere.org</a>
  </address>
  <p class="copyright">Copyright 2007 Elliotte Rusty Harold</p>
  <p class="last_modified">March 5, 2007</p>
</footer>

nav

<nav>
<a href="books/xmljava/">Processing XML with Java</a>

| <a href="books/xian3/">XML in a Nutshell</a>
| <a href="books/effectivexml/">Effective XML</a>
| <a href="books/bible3/">The XML 1.1 Bible</a>
| <a href="books/biblegold/">The XML Bible, Gold Edition</a>
| <a href="books/xml/">XML: Extensible Markup Language</a>
| <a href="reports/">Special Reports</a> 
| <a href="books.html">XML Book List</a>
| <a href="examples/">XML Examples</a>
| <a href="slides/">XML Seminar Slides</a>
| <a href="tradeshows.xml">XML Conferences</a>
| <a href="mailinglists.html">XML Mailing Lists</a>
| <a href="quotes2007.html">XML Quotes</a>
| <a href="today.rss">RSS Feed </a>
| <a href="today.atom">Atom Feed </a>
| <a href="http://cafe.elharo.com/">The Cafes</a> 
| <a href="http://www.elharo.com/blog/">Mokka mit Schlag</a> 
| <a href="http://www.cafeaulait.org">Cafe au Lait</a> 
| <a href="http://www.amazon.com/gp/pdp/profile/AYXOSXMBUAT1Y/">Amazon Plog</a>
</nav>

article

independent
<section title="Monday, March 5, 2007" id="news2007March5">
<article id='March_5_2007_61352' class='2007-03-05T17:03:32Z'>
<p> 
<img src="images/newicon.png" alt="" width="90" height="54"
hspace="5" vspace="5" border="0" align="left" /> Stephan Heiss
has released <a
href="http://snowmail.sn.funpic.de/tide/">tIDE</a>, an open
source (GPL) integrated development environment for Java. Java 6
is required. <br clear='all' />
</p>
</article>

<article id='March_5_2007_30410' class='2007-03-05T08:27:50Z'>
<p>
Syncro Soft has released <a
href="http://www.syncrosvnclient.com/">Syncro SVN Client
2.2</a>, a $59 GUI Subversion client written in Java. Version
2.2 "adds as main features support for SVN Annotations,
integration with bug tracking tools and operations on a revision
from the Affected Paths area of History view."
</p>
</article>
</section>

dialog

<dialog>
	<dt>Simplicius </dt> 
    <dd>According to the straight line AF,
	and not according to the curve, such being already excluded
	for such a use.</dd>

	<dt>Sagredo </dt> 
    <dd>But I should take neither of them,
	seeing that the straight line AF runs obliquely. I should
	draw a line perpendicular to CD, for this would seem to me
	to be the shortest, as well as being unique among the
	infinite number of longer and unequal ones which may be
	drawn from the point A to every other point of the opposite
	line CD. </dd>

	<dt>Salviati </dt> 
    <dd><p> Your choice and the reason you
	adduce for it seem to me most excellent. So now we have it
	that the first dimension is determined by a straight line;
	the second (namely, breadth) by another straight line, and
	not only straight, but at right angles to that which
	determines the length. Thus we have defined the two
	dimensions of a surface; that is, length and breadth. </p>

	<p> But suppose you had to determine a height -- for
	example, how high this platform is from the pavement down
	below there. Seeing that from any point in the platform we
	may draw infinite lines, curved or straight, and all of
	different lengths, to the infinite points of the pavement
	below, which of all these lines would you make use of? </p>
	</dd>

	<dt>Sagredo </dt> 
    <dd>I would fasten a string to the
	platform and, by hanging a plummet from it, would let it
	freely stretch till it reached very near to the pavement;
	the length of such a string being the straightest and
	shortest of all the lines that could possibly be drawn from
	the same point to the pavement, I should say that it was the
	true height in this case.</dd>

	<dt>Salviati</dt> 
    <dd>Very good. And if, from the point on
	the pavement indicated by this hanging string (taking the
	pavement to be level and not inclined), you should produce
	two other straight lines, one for the length and the other
	for the breadth of the surface of the pavement, what angles
	would they make with the thread?</dd>

	<dt>Sagredo </dt> 
    <dd>They would surely meet at right
	angles, since the string faIls perpendicularly and the
	pavement is quite flat and level.</dd>
</dialog>


meter

<meter min="0" max="489972528" value="297786952">297786952 blocks used of 489972528, 192185576 available</meter>


time

The Birding BoF leaves the hotel lobby at 
<time datetime="2007-03-21 06:00 -8">6:00 A.M. PDT</time>

progress

 <p>Progress: 
 <progress value="32" max="200"><span id="p1">16</span>%</progress>
 </p>
 <script>
  var progressBar = document.getElementById('p1');
  function updateProgress(newValue) {
    progressBar.textContent = newValue;
  }
 </script>

event-source


More DOM


HTMLDocument DOM interface

interface HTMLDocument {
  // Resource metadata management
  readonly attribute DOMString URL;
           attribute DOMString domain;
  readonly attribute DOMString referrer;
           attribute DOMString cookie;

  // DOM tree accessors
           attribute DOMString title;
           attribute HTMLElement body;
  readonly attribute HTMLCollection images;
  readonly attribute HTMLCollection links;
  readonly attribute HTMLCollection forms;
  readonly attribute HTMLCollection anchors;
  NodeList getElementsByName(in DOMString elementName);
  NodeList getElementsByClassName(in DOMString[] classNames);

  // Dynamic markup insertion
           attribute DOMString innerHTML;
  void open();
  void open(in DOMString type);
  void open(in DOMString type, in DOMString replace);
  void open(in DOMString url, in DOMString name, in DOMString features);
  void open(in DOMString url, in DOMString name, in DOMString features, in bool replace);
  void close();
  void write(in DOMString text);
  void writeln(in DOMString text);

  // Interaction
  readonly attribute Element activeElement;
  readonly attribute boolean hasFocus;

  // Commands
  readonly attribute HTMLCollection commands;

  // Editing
           attribute boolean designMode;
  boolean execCommand(in DOMString commandID);
  boolean execCommand(in DOMString commandID, in boolean doShowUI);
  boolean execCommand(in DOMString commandID, in boolean doShowUI, in DOMString value);
  Selection getSelection();

  // Cross-document messaging
  void postMessage(in DOMString message);

  // lots of other stuff to come
};

HTMLElement DOM interface

interface HTMLElement : Element {
  // DOM tree accessors
  NodeList getElementsByClassName(in DOMString[] classNames);

  // Dynamic markup insertion
   attribute DOMString innerHTML;

  // Metadata attributes
   attribute DOMString id;
   attribute DOMString title;
   attribute DOMString lang;
   attribute DOMString dir;
   attribute DOMTokenString className;

  // Interaction
  attribute long tabindex;
  void click();
  void focus();
  void blur();

  // Commands
  attribute HTMLMenuElement contextMenu;

  // Editing
  attribute boolean draggable;
  attribute DOMString contenteditable;

  // event handler DOM attributes
  attribute EventListener onclick;
           ...more events...
};

HTMLCollection DOM interface

interface HTMLCollection {
  readonly attribute unsigned long length;
  Element item(in unsigned long index);
  Element namedItem(in DOMString name);
};
public interface HTMLCollection {

  public int     getLength();
  public Element item(int index);
  public Element namedItem(String name);

};

HTMLFormControlsCollection DOM interface

interface HTMLFormControlsCollection {
  readonly attribute unsigned long length;
  Element item(in unsigned long index);
  Element namedItem(in DOMString name);
};
public interface HTMLFormControlsCollection {

  public int     getLength();
  public HTMLElement item(int index);
  public Object namedItem(String name);

};

HTMLOptions DOM interface

option
interface HTMLFormControlsCollection {
  readonly attribute unsigned long length;
  HTMLOptionElement item(in unsigned long index);
  Object namedItem(in DOMString name);
};
public interface HTMLFormControlsCollection {

  public int     getLength();
  public HTMLOptionElement item(int index);
  public Object namedItem(String name);

};

DOMTokenString interface

class
interface DOMTokenString : DOMString {
  boolean has(in DOMString token);
  void add(in DOMString token);
  void remove(in DOMString token);
};
public interface DOMTokenString {

  public boolean  has(String token);
  public void add(String token);
  public void remove(String token);

};

Old Friends (or enemies)


The Browser


WindowHTML

interface WindowHTML {

  // defined in this section
  readonly attribute History history;
  readonly attribute ClientInformation navigator; 
  readonly attribute UndoManager undoManager;
  Selection getSelection();
  readonly attribute Storage sessionStorage;
  readonly attribute StorageList globalStorage;

  // defined in other sections
           attribute Object onerror;

  // more...
};
Audio()
Image()
Image(in unsigned long width)
Image(in unsigned long width, in unsigned long height)
Option()
Option(in DOMString name)
Option(in DOMString name, in DOMString value) 

History

interface History {
  readonly attribute long length;
  void go(in long delta);
  void go();
  void back();
  void forward();
  void pushState(in DOMObject data);
  void clearState();
};

Location

interface Location {
  readonly attribute DOMString hash;
  readonly attribute DOMString host;
  readonly attribute DOMString hostname;
  readonly attribute DOMString href;
  readonly attribute DOMString pathname;
  readonly attribute DOMString port;
  readonly attribute DOMString protocol;
  readonly attribute DOMString search; 
  void assign(in DOMString url);
  void replace(in DOMString url);
  void reload();
};

Protocol and Content Handlers

interface ClientInformation {

  readonly attribute boolean onLine;

  void registerProtocolHandler(in DOMString protocol, 
                               in DOMString uri, in DOMString title);
  void registerContentHandler(in DOMString mimeType, 
                              in DOMString uri, in DOMString title);

};
The registerProtocolHandler() method allows Web sites to register themselves as possible handlers for particular protocols. For example, an online fax service could register itself as a handler of the fax: protocol ([RFC2806]), so that if the user clicks on such a link, he is given the opportunity to use that Web site. Analogously, the registerContentHandler() method allows Web sites to register themselves as possible handlers for content in a particular MIME type. For example, the same online fax service could register itself as a handler for image/g3fax files ([RFC1494]), so that if the user has no native application capable of handling G3 Facsimile byte streams, his Web browser can instead suggest he use that site to view the image.

Persistent client side storage

interface Storage {
  readonly attribute unsigned long length;
  DOMString key(in unsigned long index);
  StorageItem getItem(in DOMString key);
  void setItem(in DOMString key, in DOMString data);
  void removeItem(in DOMString key);
};

interface StorageItem {
    attribute boolean secure;
    attribute DOMString value;
};

Audio

interface Audio {

  attribute EventListener onload;
  attribute EventListener onerror;

  void play();
  void loop();
  void loop(in unsigned long playCount);
  void stop();

};

Editing


HTML 5 vs. XHTML


HTML 5 vs. XHTML 2


Browser Support for HTML 5


Schedule for Completion


To Learn More


Index | Cafe con Leche

Copyright 2007 Elliotte Rusty Harold
elharo@metalab.unc.edu
Last Modified March 13, 2007