public override bool Process(Token token) { // start tag, end tag, doctype, comment, character, eof switch (token.Type) { case TokenType.StartTag: Insert(token.AsStartTag()); break; case TokenType.EndTag: PopStackToClose(token.AsEndTag()); break; case TokenType.Comment: Insert(token.AsComment()); break; case TokenType.Character: Insert(token.AsCharacter()); break; case TokenType.Doctype: Insert(token.AsDoctype()); break; case TokenType.EOF: // could put some normalisation here if desired break; default: HtmlWarning.UnexpectedTokenType(); break; } return(true); }
private bool InSpecificScope(IReadOnlyCollection <string> targetNames, ICollection <string> baseTypes, ICollection <string> extraTypes) { IEnumerator <DomContainer> it = stack.GetDescendingEnumerator(); while (it.MoveNext()) { var el = it.Current; string elName = el.NodeName; if (targetNames.Contains(elName)) { return(true); } if (baseTypes.Contains(elName)) { return(false); } if (extraTypes != null && extraTypes.Contains(elName)) { return(false); } } HtmlWarning.ShouldNotBeReachable(); return(false); }
public void Emit(Token token) { if (isEmitPending) { HtmlWarning.UnreadTokenPending(); } emitPending = token; isEmitPending = true; if (token.Type == TokenType.StartTag) { Token.StartTag startTag = (Token.StartTag)token; lastStartTag = startTag; if (startTag.selfClosing) { selfClosingFlagAcknowledged = false; } } else if (token.Type == TokenType.EndTag) { Token.EndTag endTag = (Token.EndTag)token; if (endTag.Attributes.Any()) { ParseError.AttributesPresentOnEndTagError(this); } } }
public DomContainer Pop() { // TODO - dev, remove validation check if (stack.Last.Value.NodeName.Equals("td") && !_state.Name.Equals("InCellState")) { HtmlWarning.PoppingTDNotInCell(); } if (stack.Last.Value.NodeName.Equals("html")) { HtmlWarning.PoppingHtml(); } var last = stack.Last.Value; stack.RemoveLast(); return(last); }
public DomContainer AboveOnStack(DomContainer el) { if (!OnStack(el)) { HtmlWarning.ElementShouldBeOnStack(); } var it = stack.GetDescendingEnumerator(); while (it.MoveNext()) { var next = it.Current; if (next == el) { it.MoveNext(); return(it.Current); } } return(null); }
public bool InSelectScope(string targetName) { IEnumerator <DomContainer> it = stack.GetDescendingEnumerator(); while (it.MoveNext()) { var el = it.Current; string elName = el.NodeName; if (elName.Equals(targetName)) { return(true); } if (!StringUtil.In(elName, "optgroup", "option")) // all elements except { return(false); } } HtmlWarning.ShouldNotBeReachable(); return(false); }
public void InsertInFosterParent(DomNode input) { DomContainer fosterParent = null; var lastTable = GetFromStack("table"); bool isLastTableParent = false; if (lastTable != null) { if (lastTable.Parent != null) { fosterParent = lastTable.Parent; isLastTableParent = true; } else { fosterParent = AboveOnStack(lastTable); } } else // no table == frag { fosterParent = stack.ElementAt(0); } if (isLastTableParent) { // last table cannot be null by this point. if (lastTable == null) { HtmlWarning.FosterParentTableUnexpectedlyNull(); } lastTable.Before(input); } else { fosterParent.Append(input); } }
public void ReconstructFormattingElements() { int size = formattingElements.Count; if (size == 0 || formattingElements.Last.Value == null || OnStack(formattingElements.Last.Value)) { return; } var entry = formattingElements.Last.Value; int pos = size - 1; bool skip = false; while (true) { if (pos == 0) // step 4. if none before, skip to 8 { skip = true; break; } entry = formattingElements.ElementAt(--pos); // step 5. one earlier than entry if (entry == null || OnStack(entry)) // step 6 - neither marker nor on stack { break; // jump to 8, else continue back to 4 } } while (true) { if (!skip) // step 7: on later than entry { entry = formattingElements.ElementAt(++pos); } if (entry == null) { HtmlWarning.ReconstructUnexpectedlyEmpty(); // should not occur, as we break at last element } // 8. create new element from element, 9 insert into current node, onto stack skip = false; // can only skip increment from 4. HtmlElement newEl = Insert(entry.NodeName); // todo: avoid fostering here? // newEl.namespace(entry.namespace()); // todo: namespaces foreach (var attr in entry.Attributes) { newEl.Attributes.Add(attr.Clone()); } // 10. replace entry with new entry formattingElements.AddBefore(formattingElements.Find(entry), newEl); formattingElements.Remove(entry); // 11 if (pos == size - 1) // if not last entry in list, jump to 7 { break; } } }