Commits

Toby Inkster  committed 60afafa

some useful test cases; implement quite a bit of the <table> stuff

  • Participants
  • Parent commits 03f9c90

Comments (0)

Files changed (70)

File lib/HTML/HTML5/DOM.pm

 BEGIN { $me = bless {}, __PACKAGE__ }
 
 use DateTime qw//;
+use IO::Detect qw//;
 use Scalar::Util qw/blessed/;
 use URI qw//;
+use Web::Magic qw//;
 
 sub getDOMImplementation
 {
 	HTML::HTML5::DOMutil::Feature->new(XMLVersion => '1.1'),
 	HTML::HTML5::DOMutil::Feature->new(HTML       => '2.0'),
 	HTML::HTML5::DOMutil::Feature->new(XHTML      => '2.0'),
-	);
+);
 
 sub getFeature
 {
 {
 	my ($self, $file, %options) = @_;
 	my $pclass = $options{using} =~ /libxml/i ? 'XML::LibXML' : 'HTML::HTML5::Parser';
-	my $dom = (ref $file =~ /^IO\b/)
+	my $dom = IO::Detect::is_filehandle $file
 		? $pclass->new->parse_fh($file)
 		: $pclass->new->parse_file($file);
 	XML::LibXML::Augment->upgrade($dom);
 		[ anchors => '//*[local-name()="a" and @name]', 'C<< <a> >> with a "name" attribute' ],
 		[ forms   => '//*[local-name()="form"]',   'forms' ],
 		[ scripts => '//*[local-name()="script"]', 'scripts' ],
+		[ p5_tables => '//*[local-name()="table"]', 'tables' ],
 		);
 	foreach my $x (@things)
 	{
 sub title
 {
 	my ($self) = @_;
-	my ($title) = $self->getElementsByTagName('title')->get_index(1)->textContent;
+	my ($title) = $self->getElementsByTagName('title')->get_node(1)->textContent;
 	$title =~ s/\s+/ /g;
 	$title =~ s/(^\s|\s$)//g;
 	return $title;
 	my ($self, $thing) = @_;
 	my @results = grep {
 		$_ == $self
-	} $thing->ancestors;
+	} $thing->p5_ancestors;
 	return 1 if @results;
 	return;
 }
 __PACKAGE__->_mk_attribute_accessors(qw/
 	href==URI target rel rev media hreflang target type
 	relList=rel=LIST revList=rev=LIST text==TEXT
+	name
 	/);
 __PACKAGE__->_mk_url_decomposition;
 __PACKAGE__->_mk_follow_method;
 	-names => [@ELEMENTS],
 	-isa   => ['HTML::HTML5::DOM::HTMLElement'];
 
-__PACKAGE__->_mk_attribute_accessors(qw/span/);
+sub span
+{
+	my $self = shift;
+	
+	if (@_)
+	{
+		my $set = shift;
+		int($set) > 0
+			? $self->setAttribute(span => int($set))
+			: $self->removeAttribute('span')
+	}
+	
+	my $span = $self->getAttribute('span');
+	int($span) > 0 ? int($span) : 1;
+}
+
+HTML::HTML5::DOMutil::AutoDoc->add(
+	__PACKAGE__,
+	span => 'Accessor for the C<< span >> attribute. Must always be a positive integer.',
+);
 
 package HTML::HTML5::DOM::HTMLCommandElement;
 
 	-names => [@ELEMENTS],
 	-isa   => ['HTML::HTML5::DOM::HTMLElement'];
 
+sub caption
+{
+	my $self  = shift;
+	my ($cap) = $self->getChildrenByTagName('caption');
+	return $cap if $cap;
+	return;
+}
+
+sub createCaption
+{
+	my $self = shift;
+	return $self->caption || do {
+		my $new = XML::LibXML::Element->new('caption');
+		$new->setNamespace($self->namespaceURI, '', 1);
+		$self->insertBefore($new, $self->childNodes->get_node(1));
+		XML::LibXML::Augment->rebless($new);
+		$new;
+	};
+}
+
+sub deleteCaption
+{
+	my $self = shift;
+	my $cap  = $self->caption;
+	$self->removeChild($cap) if $cap;
+	return !!$cap;
+}
+
+HTML::HTML5::DOMutil::AutoDoc->add(
+	__PACKAGE__,
+	caption => 'returns the C<< <caption> >> element (if any)',
+);
+
+HTML::HTML5::DOMutil::AutoDoc->add(
+	__PACKAGE__,
+	createCaption => 'returns the C<< <caption> >> element, creating one if there is none',
+);
+
+HTML::HTML5::DOMutil::AutoDoc->add(
+	__PACKAGE__,
+	deleteCaption => 'delete the C<< <caption> >> element (if any), and returns a boolean indicating whether anything was deleted',
+);
+
+foreach (qw/tHead createTHead deleteTHead tFoot createTFoot deleteTFoot
+	tBodies createTBody rows insertRow deleteRow border/)
+{
+	*$_ = sub { die 'TODO' };
+	HTML::HTML5::DOMutil::AutoDoc->add(__PACKAGE__, $_, '@@TODO - not implemented yet');
+}
+
 package HTML::HTML5::DOM::HTMLTableSectionElement;
 
 use 5.010;
 	-names => [@ELEMENTS],
 	-isa   => ['HTML::HTML5::DOM::HTMLElement'];
 
+sub rows
+{
+	my $self  = shift;
+	return $self->getChildrenByTagName('*')->grep(sub { $_->tagName =~ m{^(tr)$}i });
+}
+
+HTML::HTML5::DOMutil::AutoDoc->add(__PACKAGE__,
+	rows => 'returns a list of C<< <tr> >> child elements'
+);
+
+sub insertRow      { die "TODO" }
+sub deleteRow      { die "TODO" }
+
+HTML::HTML5::DOMutil::AutoDoc->add(__PACKAGE__, $_, '@@TODO')
+	for qw/insertRow deleteRow/;
+
 package HTML::HTML5::DOM::HTMLTableCellElement;
 
 use 5.010;
 	-names => [@ELEMENTS],
 	-isa   => ['HTML::HTML5::DOM::HTMLElement'];
 
+__PACKAGE__->_mk_attribute_accessors(
+	qw/rowSpan=rowspan colSpan=colspan/
+	);
+
+sub headers
+{
+	die "TODO";
+}
+
+HTML::HTML5::DOMutil::AutoDoc->add(
+	__PACKAGE__,
+	'headers',
+	'@@TODO - should return a list of C<< <th> >> elements that act as a header for this cell.',
+);
+
+sub cellIndex
+{
+	die "TODO";
+}
+
+HTML::HTML5::DOMutil::AutoDoc->add(
+	__PACKAGE__,
+	'cellIndex',
+	"\@\@TODO - should return the cell's index within its row.",
+	);
+
 package HTML::HTML5::DOM::HTMLTableDataCellElement;
 
 use 5.010;
 	-names => [@ELEMENTS],
 	-isa   => ['HTML::HTML5::DOM::HTMLTableCellElement'];
 
+__PACKAGE__->_mk_attribute_accessors(qw/scope/);
+
 package HTML::HTML5::DOM::HTMLTableRowElement;
 
 use 5.010;
 	-names => [@ELEMENTS],
 	-isa   => ['HTML::HTML5::DOM::HTMLElement'];
 
+sub rowIndex        { die "TODO" }
+sub sectionRowIndex { die "TODO" }
+sub insertCell      { die "TODO" }
+sub deleteCell      { die "TODO" }
+
+HTML::HTML5::DOMutil::AutoDoc->add(__PACKAGE__, $_, '@@TODO')
+	for qw/sectionRowIndex rowIndex insertCell deleteCell/;
+
+sub cells
+{
+	my $self  = shift;
+	return $self->getChildrenByTagName('*')->grep(sub { $_->tagName =~ m{^(td|th)$}i });
+}
+
+HTML::HTML5::DOMutil::AutoDoc->add(__PACKAGE__,
+	cells => 'returns a list of C<< <th> >> and C<< <td> >> child elements'
+);
+
+
 package HTML::HTML5::DOM::HTMLTextAreaElement;
 
 use 5.010;

File lib/HTML/HTML5/DOM/HTMLAnchorElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods
 
 Called with no arguments, is a shortcut for C<< $elem->getAttribute("media") >>. Called with a defined argument, acts as C<setAttribute>. Called with undef as an argument, acts as C<removeAttribute>.
 
+=item * C<< name >>
+
+Called with no arguments, is a shortcut for C<< $elem->getAttribute("name") >>. Called with a defined argument, acts as C<setAttribute>. Called with undef as an argument, acts as C<removeAttribute>.
+
 =item * C<< p5_follow >>
 
 Shortcut for C<< Web::Magic->new(GET => $elem->href) >>

File lib/HTML/HTML5/DOM/HTMLAreaElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLAudioElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLBRElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLBaseElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLBodyElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLButtonElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLCanvasElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLCollection.pod

 
 =item * L<XML::LibXML::NodeList>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLCommandElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLDListElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLDataListElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLDetailsElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLDivElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLDocument.pod

 
 =over
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =item * L<XML::LibXML::Augment::Document>
 
 =item * L<XML::LibXML::Augment::Node>
 
 =item * C<< doctype >>
 
-This method is not implemented yet.
+This method is not implemented yet, but will eventually support the functionality defined in DOM Core 3.
 
 =item * C<< documentURI >>
 
 
 Returns all forms found in the document.
 
+=item * C<< getElementById >>
+
+The world-famous C<getElementById> method. The default XML::LibXML implementation of this does not work with HTML::HTML5::Parser documents, because HTML::HTML5::Parser lacks the ability to inform libxml which element to use as an ID. (libxml defaults to xml:id.) This implementation is XPath-based, thus slower.
+
 =item * C<< head >>
 
 Returns the document head.
 
 =item * C<< inputEncoding >>
 
-This method is not implemented yet.
+This method is not implemented yet, but will eventually support the functionality defined in DOM Core 3.
 
 =item * C<< lastModified >>
 
 
 Alias for C<normalize>.
 
+=item * C<< p5_tables >>
+
+Returns all tables found in the document.
+
 =item * C<< plugins >>
 
 Returns all C<< <embed> >> elements found in the document.
 
 =item * C<< renameNode >>
 
-This method is not implemented yet.
+This method is not implemented yet, but will eventually support the functionality defined in DOM Core 3.
 
 =item * C<< scripts >>
 
 
 =item * C<< xmlEncoding >>
 
-This method is not implemented yet.
+This method is not implemented yet, but will eventually support the functionality defined in DOM Core 3.
 
 =item * C<< xmlStandalone >>
 

File lib/HTML/HTML5/DOM/HTMLElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods
 
 Called with no arguments, is a shortcut for C<< $elem->getAttribute("class") >>. Called with a defined argument, acts as C<setAttribute>. Called with undef as an argument, acts as C<removeAttribute>.
 
+=item * C<< compareDocumentPosition >>
+
+Compares this node with another based on document order.
+
 =item * C<< dataset >>
 
-Gets a hashref based on C<< data-foo >> attributes.
+Gets a hashref based on C<< data-foo >> attributes. This is currently read-only, but in future may be implemented as a tied hash to allow read/write access.
 
 =item * C<< dir >>
 
 
 =item * C<< getElementById >>
 
-The world-famous C<getElementById> method.
+The world-famous C<getElementById> method. The default XML::LibXML implementation of this does not work with HTML::HTML5::Parser documents, because HTML::HTML5::Parser lacks the ability to inform libxml which element to use as an ID. (libxml defaults to xml:id.) This implementation is XPath-based, thus slower.
 
 =item * C<< getElementsByClassName >>
 
 Given one or more class names, returns a list of elements bearing those classes.
 
+=item * C<< getFeature >>
+
+Acts as a shortcut for C<< $element->ownerDocument->implementation->getFeature >>.
+
+=item * C<< getUserData >>
+
+Not implemented - perhaps never will be. Try C<dataset> instead.
+
 =item * C<< hidden >>
 
 Called with no arguments, is a shortcut for C<< $elem->hasAttribute("hidden") >>. If called with a true argument, will C<setAttribute>; if called with a false argument will C<removeAttribute>.
 
 When called without arguments, serialises the contents of the element (but not the element itself) to a single string. When called with a string argument, parses the string as HTML and uses it to set the content of this element. When possible, attempts to use polyglot HTML (i.e. markup that works as HTML and XHTML).
 
+=item * C<< isDefaultNamespace >>
+
+Given a URI, returns true if that is the default namespace prefix.
+
+=item * C<< isSupported >>
+
+Acts as a shortcut for C<< $element->ownerDocument->implementation->hasFeature >>.
+
 =item * C<< lang >>
 
 Called with no arguments, is a shortcut for C<< $elem->getAttribute("lang") >>. Called with a defined argument, acts as C<setAttribute>. Called with undef as an argument, acts as C<removeAttribute>.
 
+=item * C<< lookupPrefix >>
+
+Alias for C<lookupNamespacePrefix>.
+
 =item * C<< outerHTML >>
 
 As per innerHTML, but includes the element itself. Can be used as a setter, but that's a bit of a weird thing to do.
 
 Given an argument, returns true if that argument is an element nested within this element.
 
+=item * C<< schemaTypeInfo >>
+
+Not implemented.
+
+=item * C<< setIdAttribute >>
+
+Not implemented.
+
+=item * C<< setIdAttributeNS >>
+
+Not implemented.
+
+=item * C<< setIdAttributeNode >>
+
+Not implemented.
+
+=item * C<< setUserData >>
+
+Not implemented - perhaps never will be. Try C<dataset> instead.
+
 =item * C<< tabIndex >>
 
 Called with no arguments, is a shortcut for C<< $elem->getAttribute("tabindex") >>. Called with a defined argument, acts as C<setAttribute>. Called with undef as an argument, acts as C<removeAttribute>.

File lib/HTML/HTML5/DOM/HTMLEmbedElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLFieldSetElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLFormControlsCollection.pod

 
 =item * L<XML::LibXML::NodeList>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLFormElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLHRElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLHeadElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLHeadingElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLHtmlElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLIFrameElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLImageElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLInputElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLKeygenElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLLIElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLLabelElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLLegendElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLLinkElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLMapElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLMediaElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLMenuElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLMetaElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLMeterElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLModElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLOListElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLObjectElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLOptGroupElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLOptionElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLOutputElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLParagraphElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLParamElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLPreElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLProgressElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLQuoteElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLScriptElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLSelectElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLSourceElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLSpanElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLStyleElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLTableCaptionElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLTableCellElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods
 
-This class provides no additional methods over those it inherits.
+As well as its inherited methods, this class provides the following methods.
 
-It is mostly pointless, but its existance is required by the HTML DOM.
+=over
+
+=item * C<< cellIndex >>
+
+@@TODO - should return the cell's index within its row.
+
+=item * C<< colSpan >>
+
+Called with no arguments, is a shortcut for C<< $elem->getAttribute("colspan") >>. Called with a defined argument, acts as C<setAttribute>. Called with undef as an argument, acts as C<removeAttribute>.
+
+=item * C<< headers >>
+
+@@TODO - should return a list of C<< <th> >> elements that act as a header for this cell.
+
+=item * C<< rowSpan >>
+
+Called with no arguments, is a shortcut for C<< $elem->getAttribute("rowspan") >>. Called with a defined argument, acts as C<setAttribute>. Called with undef as an argument, acts as C<removeAttribute>.
+
+=back
 
 =head1 BUGS
 

File lib/HTML/HTML5/DOM/HTMLTableColElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods
 
 =item * C<< span >>
 
-Called with no arguments, is a shortcut for C<< $elem->getAttribute("span") >>. Called with a defined argument, acts as C<setAttribute>. Called with undef as an argument, acts as C<removeAttribute>.
+Accessor for the C<< span >> attribute. Must always be a positive integer.
 
 =back
 

File lib/HTML/HTML5/DOM/HTMLTableDataCellElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLTableElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods
 
-This class provides no additional methods over those it inherits.
+As well as its inherited methods, this class provides the following methods.
 
-It is mostly pointless, but its existance is required by the HTML DOM.
+=over
+
+=item * C<< border >>
+
+@@TODO - not implemented yet
+
+=item * C<< caption >>
+
+returns the C<< <caption> >> element (if any)
+
+=item * C<< createCaption >>
+
+returns the C<< <caption> >> element, creating one if there is none
+
+=item * C<< createTBody >>
+
+@@TODO - not implemented yet
+
+=item * C<< createTFoot >>
+
+@@TODO - not implemented yet
+
+=item * C<< createTHead >>
+
+@@TODO - not implemented yet
+
+=item * C<< deleteCaption >>
+
+delete the C<< <caption> >> element (if any), and returns a boolean indicating whether anything was deleted
+
+=item * C<< deleteRow >>
+
+@@TODO - not implemented yet
+
+=item * C<< deleteTFoot >>
+
+@@TODO - not implemented yet
+
+=item * C<< deleteTHead >>
+
+@@TODO - not implemented yet
+
+=item * C<< insertRow >>
+
+@@TODO - not implemented yet
+
+=item * C<< rows >>
+
+@@TODO - not implemented yet
+
+=item * C<< tBodies >>
+
+@@TODO - not implemented yet
+
+=item * C<< tFoot >>
+
+@@TODO - not implemented yet
+
+=item * C<< tHead >>
+
+@@TODO - not implemented yet
+
+=back
 
 =head1 BUGS
 

File lib/HTML/HTML5/DOM/HTMLTableHeaderCellElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods
 
-This class provides no additional methods over those it inherits.
+As well as its inherited methods, this class provides the following methods.
 
-It is mostly pointless, but its existance is required by the HTML DOM.
+=over
+
+=item * C<< scope >>
+
+Called with no arguments, is a shortcut for C<< $elem->getAttribute("scope") >>. Called with a defined argument, acts as C<setAttribute>. Called with undef as an argument, acts as C<removeAttribute>.
+
+=back
 
 =head1 BUGS
 

File lib/HTML/HTML5/DOM/HTMLTableRowElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods
 
-This class provides no additional methods over those it inherits.
+As well as its inherited methods, this class provides the following methods.
 
-It is mostly pointless, but its existance is required by the HTML DOM.
+=over
+
+=item * C<< cells >>
+
+returns a list of C<< <th> >> and C<< <td> >> child elements
+
+=item * C<< deleteCell >>
+
+@@TODO
+
+=item * C<< insertCell >>
+
+@@TODO
+
+=item * C<< rowIndex >>
+
+@@TODO
+
+=item * C<< sectionRowIndex >>
+
+@@TODO
+
+=back
 
 =head1 BUGS
 

File lib/HTML/HTML5/DOM/HTMLTableSectionElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods
 
-This class provides no additional methods over those it inherits.
+As well as its inherited methods, this class provides the following methods.
 
-It is mostly pointless, but its existance is required by the HTML DOM.
+=over
+
+=item * C<< deleteRow >>
+
+@@TODO
+
+=item * C<< insertRow >>
+
+@@TODO
+
+=item * C<< rows >>
+
+returns a list of C<< <tr> >> child elements
+
+=back
 
 =head1 BUGS
 

File lib/HTML/HTML5/DOM/HTMLTextAreaElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLTimeElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLTitleElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLTrackElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLUListElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLUnknownElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File lib/HTML/HTML5/DOM/HTMLVideoElement.pod

 
 =item * L<XML::LibXML::QuerySelector>
 
+=item * L<HTML::HTML5::DOMutil::FancyISA>
+
 =back
 
 =head2 Additional Methods

File t/02simple.t

+use Test::More tests => 17;
+use HTML::HTML5::DOM;
+
+my $dom = HTML::HTML5::DOM->parse(\*DATA);
+
+is(
+	$dom->title,
+	"The Title",
+	"HTMLDocument->title",
+);
+
+is(
+	$dom->anchors->get_node(1)->name,
+	"table",
+	"HTMLDocument->anchors and HTMLAnchorElement->name",
+);
+
+is(
+	$dom->forms->get_node(1)->method,
+	"get",
+	"HTMLDocument->forms and HTMLFormElement->method",
+);
+
+ok(
+	$dom->implementation->hasFeature(Core => 2.0),
+	"HTMLDocument->implementation and HTML::HTML5::DOM->hasFeature(Core => 2.0)",
+);
+
+is(
+	$dom->xmlVersion,
+	undef,
+	"HTMLDocument->xmlVersion",
+);
+
+my ($link) = $dom->getElementsByTagName('link');
+ok(
+	$dom->head->p5_contains($link),
+	"HTMLDocument->head and HTMLElement->p5_contains",
+);
+
+ok(
+	!$dom->body->p5_contains($link),
+	"HTMLDocument->body and neg for HTMLElement->p5_contains",
+);
+
+isa_ok(
+	$dom->links->get_node(1)->href,
+	"URI",
+	"HTMLAnchorElement->href",
+);
+
+is(
+	$dom->links->get_node(1)->href->as_string,
+	"http://www.example.com/",
+	"HTMLAnchorElement->href",
+);
+
+isa_ok(
+	$dom->forms->get_node(1)->elements,
+	-HTMLFormControlsCollection,
+	"HTMLFormElement->elements",
+);
+
+is(
+	$dom->forms->get_node(1)->elements->p5_wwwFormUrlencoded,
+	'q=foo',
+	"HTMLFormControlsCollection->p5_wwwFormUrlencoded",
+);
+
+my $submit = $dom->forms->get_node(1)->submit;
+isa_ok(
+	$submit,
+	'Web::Magic',
+	"HTMLFormElement->submit",
+);
+
+is(
+	$submit->uri->as_string,
+	'http://www.example.com/search?q=foo',
+	'HTMLFormElement->submit->uri is correct URI',
+);
+
+is(
+	$dom->p5_tables->get_node(1)->caption->textContent,
+	'A table',
+	'HTMLDocument->p5_tables and HTMLTableElement->caption',
+);
+
+ok(
+	$dom->p5_tables->get_node(1)->deleteCaption,
+	'HTMLTableElement->deleteCaption',
+);
+
+is(
+	scalar $dom->p5_tables->get_node(1)->caption,
+	undef,
+	'HTMLDocument->p5_tables and HTMLTableElement->caption',
+);
+
+isa_ok(
+	$dom->p5_tables->get_node(1)->createCaption,
+	'caption',
+	'HTMLTableElement->createCaption',
+);
+
+__DATA__
+<!doctype html>
+<html>
+	<head profile="http://www.w3.org/1999/xhtml/vocab">
+		<title>The Title</title>
+		<link rel="stylesheet" type="text/css" media="hologram" href="hologram.css">
+	</head>
+	<body>
+		<h1>The Heading</h1>
+		<table>
+			<caption><a name="table"></a>A table</caption>
+			<tr>
+				<td><a href="http://www.example.com/">a cell</a></td>
+			</tr>
+		</table>
+		<form action="http://www.example.com/search" method="get">
+			<fieldset>
+				<legend>A search form</legend>
+				<label for="q">search terms</label>
+				<input id="q" name="q" value="foo">
+				<br>
+				<input type="submit" value="search">
+			</fieldset>
+		</form>
+	</body>
+</html>