// Section 11.2.5.4.1.
func initialIM(p *parser) (insertionMode, bool) {
- if p.tok.Type == DoctypeToken {
- p.addChild(&Node{
+ switch p.tok.Type {
+ case CommentToken:
+ p.doc.Add(&Node{
+ Type: CommentNode,
+ Data: p.tok.Data,
+ })
+ return initialIM, true
+ case DoctypeToken:
+ p.doc.Add(&Node{
Type: DoctypeNode,
Data: p.tok.Data,
})
default:
// Ignore the token.
}
+ case CommentToken:
+ p.doc.Add(&Node{
+ Type: CommentNode,
+ Data: p.tok.Data,
+ })
+ return beforeHTMLIM, true
}
if add || implied {
p.addElement("html", attr)
default:
// Ignore the token.
}
+ case CommentToken:
+ p.addChild(&Node{
+ Type: CommentNode,
+ Data: p.tok.Data,
+ })
+ return beforeHeadIM, true
}
if add || implied {
p.addElement("head", attr)
pop = true
}
// TODO.
+ case CommentToken:
+ p.addChild(&Node{
+ Type: CommentNode,
+ Data: p.tok.Data,
+ })
+ return inHeadIM, true
}
if pop || implied {
n := p.oe.pop()
if n.Data != "head" {
- panic("html: bad parser state")
+ panic("html: bad parser state: <head> element not found, in the in-head insertion mode")
}
return afterHeadIM, !implied
}
}
case EndTagToken:
// TODO.
+ case CommentToken:
+ p.addChild(&Node{
+ Type: CommentNode,
+ Data: p.tok.Data,
+ })
+ return afterHeadIM, true
}
if add || implied {
p.addElement("body", attr)
p.oe.pop()
}
}
+ case CommentToken:
+ p.addChild(&Node{
+ Type: CommentNode,
+ Data: p.tok.Data,
+ })
}
return inBodyIM, true
// Ignore the token.
return inTableIM, true
}
+ case CommentToken:
+ p.addChild(&Node{
+ Type: CommentNode,
+ Data: p.tok.Data,
+ })
+ return inTableIM, true
}
if add {
// TODO: clear the stack back to a table context.
// Ignore the token.
return inTableBodyIM, true
}
+ case CommentToken:
+ p.addChild(&Node{
+ Type: CommentNode,
+ Data: p.tok.Data,
+ })
+ return inTableBodyIM, true
}
if add {
// TODO: clear the stack back to a table body context.
default:
// TODO.
}
+ case CommentToken:
+ p.addChild(&Node{
+ Type: CommentNode,
+ Data: p.tok.Data,
+ })
+ return inRowIM, true
}
return useTheRulesFor(p, inRowIM, inTableIM)
}
// TODO: check for matching element in table scope.
closeTheCellAndReprocess = true
}
+ case CommentToken:
+ p.addChild(&Node{
+ Type: CommentNode,
+ Data: p.tok.Data,
+ })
+ return inCellIM, true
}
if closeTheCellAndReprocess {
if p.popUntil(tableScopeStopTags, "td") || p.popUntil(tableScopeStopTags, "th") {
default:
// TODO.
}
+ case CommentToken:
+ // The comment is attached to the <html> element.
+ if len(p.oe) < 1 || p.oe[0].Data != "html" {
+ panic("html: bad parser state: <html> element not found, in the after-body insertion mode")
+ }
+ p.oe[0].Add(&Node{
+ Type: CommentNode,
+ Data: p.tok.Data,
+ })
+ return afterBodyIM, true
}
+ // TODO: should this be "return inBodyIM, true"?
return afterBodyIM, true
}
if p.tok.Data == "html" {
return useTheRulesFor(p, afterAfterBodyIM, inBodyIM)
}
+ case CommentToken:
+ p.doc.Add(&Node{
+ Type: CommentNode,
+ Data: p.tok.Data,
+ })
+ return afterAfterBodyIM, true
}
return inBodyIM, false
}
scripting: true,
framesetOK: true,
}
+ p.tokenizer.ReturnComments = true
// Iterate until EOF. Any other error will cause an early return.
im, consumed := initialIM, true
for {
case TextNode:
fmt.Fprintf(w, "%q", n.Data)
case CommentNode:
- return os.NewError("COMMENT")
+ fmt.Fprintf(w, "<!-- %s -->", n.Data)
case DoctypeNode:
fmt.Fprintf(w, "<!DOCTYPE %s>", n.Data)
case scopeMarkerNode:
rc := make(chan io.Reader)
go readDat(filename, rc)
// TODO(nigeltao): Process all test cases, not just a subset.
- for i := 0; i < 27; i++ {
+ for i := 0; i < 29; i++ {
// Parse the #data section.
b, err := ioutil.ReadAll(<-rc)
if err != nil {
// would become a tree containing <html>, <head> and <body> elements. Another
// example is that the programmatic equivalent of "a<head>b</head>c" becomes
// "<html><head><head/><body>abc</body></html>".
-//
-// Comment nodes are elided from the output, analogous to Parse skipping over
-// any <!--comment--> input.
func Render(w io.Writer, n *Node) os.Error {
if x, ok := w.(writer); ok {
return render(x, n)
case ElementNode:
// No-op.
case CommentNode:
+ if _, err := w.WriteString("<!--"); err != nil {
+ return err
+ }
+ if _, err := w.WriteString(n.Data); err != nil {
+ return err
+ }
+ if _, err := w.WriteString("-->"); err != nil {
+ return err
+ }
return nil
case DoctypeNode:
if _, err := w.WriteString("<!DOCTYPE "); err != nil {