public virtual Node findBody(TagTable tt) { Node node; node = this.content; while (node != null && node.tag != tt.tagHtml) { node = node.next; } if (node == null) { return(null); } node = node.content; while (node != null && node.tag != tt.tagBody) { node = node.next; } return(node); }
/* * unexpected content in table row is moved to just before * the table in accordance with Netscape and IE. This code * assumes that node hasn't been inserted into the row. */ public static void moveBeforeTable(Node row, Node node, TagTable tt) { Node table; /* first find the table element */ for (table = row.parent; table != null; table = table.parent) { if (table.tag == tt.tagTable) { if (table.parent.content == table) { table.parent.content = node; } node.prev = table.prev; node.next = table; table.prev = node; node.parent = table.parent; if (node.prev != null) { node.prev.next = node; } break; } } }
internal static void moveToHead(Lexer lexer, Node element, Node node) { Node head; TagTable tt = lexer.configuration.tt; if (node.type == Node.StartTag || node.type == Node.StartEndTag) { Report.Warning(lexer, element, node, Report.TAG_NOT_ALLOWED_IN); while (element.tag != tt.tagHtml) { element = element.parent; } for (head = element.content; head != null; head = head.next) { if (head.tag == tt.tagHead) { Node.insertNodeAtEnd(head, node); break; } } if (node.tag.parser != null) { parseTag(lexer, node, Lexer.IgnoreWhitespace); } } else { Report.Warning(lexer, element, node, Report.DISCARDING_UNEXPECTED); } }
/* * HTML is the top level element */ public static Node parseDocument(Lexer lexer) { Node node, document, html; Node doctype = null; TagTable tt = lexer.configuration.tt; document = lexer.newNode(); document.type = Node.RootNode; while (true) { node = lexer.GetToken(Lexer.IgnoreWhitespace); if (node == null) { break; } /* deal with comments etc. */ if (Node.insertMisc(document, node)) { continue; } if (node.type == Node.DocTypeTag) { if (doctype == null) { Node.insertNodeAtEnd(document, node); doctype = node; } else { Report.Warning(lexer, document, node, Report.DISCARDING_UNEXPECTED); } continue; } if (node.type == Node.EndTag) { Report.Warning(lexer, document, node, Report.DISCARDING_UNEXPECTED); //TODO? continue; } if (node.type != Node.StartTag || node.tag != tt.tagHtml) { lexer.ungetToken(); html = lexer.inferredTag("html"); } else { html = node; } Node.insertNodeAtEnd(document, html); getParseHTML().Parse(lexer, html, (short)0); // TODO? break; } return(document); }
/* find html element */ public virtual Node findHTML(TagTable tt) { Node node; for (node = this.content; node != null && node.tag != tt.tagHtml; node = node.next) { ; } return(node); }
/* * the doctype has been found after other tags, * and needs moving to before the html element */ public static void insertDocType(Lexer lexer, Node element, Node doctype) { TagTable tt = lexer.configuration.tt; Report.Warning(lexer, element, doctype, Report.DOCTYPE_AFTER_TAGS); while (element.tag != tt.tagHtml) { element = element.parent; } insertNodeBeforeElement(element, doctype); }
public virtual Node findHEAD(TagTable tt) { Node node; node = this.findHTML(tt); if (node != null) { for (node = node.content; node != null && node.tag != tt.tagHead; node = node.next) { ; } } return(node); }
/* * Move initial and trailing space out. * This routine maps: * * hello<em> world</em> * to * hello <em>world</em> * and * <em>hello </em><strong>world</strong> * to * <em>hello</em> <strong>world</strong> */ public static void trimSpaces(Lexer lexer, Node element) { Node text = element.content; TagTable tt = lexer.configuration.tt; if (text != null && text.type == Node.TextNode && element.tag != tt.tagPre) { trimInitialSpace(lexer, element, text); } text = element.last; if (text != null && text.type == Node.TextNode) { trimTrailingSpace(lexer, element, text); } }
/* ignore unknown attributes for proprietary elements */ public virtual Attribute checkAttribute(Lexer lexer, Node node) { TagTable tt = lexer.configuration.tt; if (this.asp == null && this.php == null) { this.checkUniqueAttribute(lexer, node); } Attribute attribute = this.dict; if (attribute != null) { /* title is vers 2.0 for A and LINK otherwise vers 4.0 */ if (attribute == AttributeTable.attrTitle && (node.tag == tt.tagA || node.tag == tt.tagLink)) { lexer.versions &= Dict.VERS_ALL; } else if ((attribute.Versions & Dict.VERS_XML) != 0) { if (!(lexer.configuration.XmlTags || lexer.configuration.XmlOut)) { Report.attrError(lexer, node, this.attribute, Report.XML_ATTRIBUTE_VALUE); } } else { lexer.versions &= attribute.Versions; } if (attribute.AttrChk != null) { attribute.AttrChk.check(lexer, node, this); } } else if (!lexer.configuration.XmlTags && !(node.tag == null) && this.asp == null && !(node.tag != null && ((node.tag.versions & Dict.VERS_PROPRIETARY) != 0))) { Report.attrError(lexer, node, this.attribute, Report.UNKNOWN_ATTRIBUTE); } return(attribute); }
public static void trimEmptyElement(Lexer lexer, Node element) { TagTable tt = lexer.configuration.tt; if (lexer.canPrune(element)) { if (element.type != TextNode) { Report.Warning(lexer, element, null, Report.TRIM_EMPTY_ELEMENT); } discardElement(element); } else if (element.tag == tt.tagP && element.content == null) { /* replace <p></p> by <br/><br/> to preserve formatting */ Node node = lexer.inferredTag("br"); Node.coerceNode(lexer, element, tt.tagBr); Node.insertNodeAfterElement(element, node); } }
/* * This maps * <em>hello </em><strong>world</strong> * to * <em>hello</em> <strong>world</strong> * * If last child of element is a text node * then trim trailing white space character * moving it to after element's end tag. */ public static void trimTrailingSpace(Lexer lexer, Node element, Node last) { sbyte c; TagTable tt = lexer.configuration.tt; if (last != null && last.type == Node.TextNode && last.end > last.start) { c = lexer.lexbuf[last.end - 1]; if (c == 160 || c == (sbyte)' ') { /* take care with <td> </td> */ if (element.tag == tt.tagTd || element.tag == tt.tagTh) { if (last.end > last.start + 1) { last.end -= 1; } } else { last.end -= 1; if (((element.tag.model & Dict.CM_INLINE) != 0) && !((element.tag.model & Dict.CM_FIELD) != 0)) { lexer.insertspace = true; } /* if empty string then delete from parse tree */ if (last.start == last.end) { trimEmptyElement(lexer, last); } } } } }
/// <summary> Indicates whether or not whitespace should be preserved for this element. /// If an <code>xml:space</code> attribute is found, then if the attribute value is /// <code>preserve</code>, returns <code>true</code>. For any other value, returns /// <code>false</code>. If an <code>xml:space</code> attribute was <em>not</em> /// found, then the following element names result in a return value of <code>true: /// pre, script, style,</code> and <code>xsl:text</code>. Finally, if a /// <code>TagTable</code> was passed in and the element appears as the "pre" element /// in the <code>TagTable</code>, then <code>true</code> will be returned. /// Otherwise, <code>false</code> is returned. /// </summary> /// <param name="element">The <code>Node</code> to test to see if whitespace should be /// preserved. /// </param> /// <param name="tt">The <code>TagTable</code> to test for the <code>getNodePre()</code> /// function. This may be <code>null</code>, in which case this test /// is bypassed. /// </param> /// <returns> <code>true</code> or <code>false</code>, as explained above. /// </returns> public static bool XMLPreserveWhiteSpace(Node element, TagTable tt) { AttVal attribute; /* search attributes for xml:space */ for (attribute = element.attributes; attribute != null; attribute = attribute.next) { if (attribute.attribute.Equals("xml:space")) { if (attribute.value_Renamed.Equals("preserve")) { return(true); } return(false); } } /* kludge for html docs without explicit xml:space attribute */ if (Lexer.wstrcasecmp(element.element, "pre") == 0 || Lexer.wstrcasecmp(element.element, "script") == 0 || Lexer.wstrcasecmp(element.element, "style") == 0) { return(true); } if ((tt != null) && (tt.findParser(element) == ParsePre)) { return(true); } /* kludge for XSL docs */ if (Lexer.wstrcasecmp(element.element, "xsl:text") == 0) { return(true); } return(false); }
public Node(short type, sbyte[] textarray, int start, int end, System.String element, TagTable tt) { this.parent = null; this.prev = null; this.next = null; this.last = null; this.start = start; this.end = end; this.textarray = textarray; this.type = type; this.closed = false; this.implicit_Renamed = false; this.linebreak = false; this.was = null; this.tag = null; this.element = element; this.attributes = null; this.content = null; if (type == StartTag || type == StartEndTag || type == EndTag) { tt.findTag(this); } }