void FlushExisingBuffer(int lastFlushAtIndex, HtmlLexerEvent lexerEvent) { //raise lexer event if (_appendCount > 0) { #if DEBUG //Console.WriteLine(lexerEvent.ToString() + " : " + // new string(this.textSnapshot.Copy(this._firstAppendAt, (this._readIndex - this._firstAppendAt) + 1))); #endif RaiseStateChanged(lexerEvent, this._firstAppendAt, (this._readIndex - this._firstAppendAt) + 1); } this._lastFlushAt = lastFlushAtIndex; this._appendCount = 0; }
protected void RaiseStateChanged(HtmlLexerEvent lexEvent, int startIndex, int len) { LexStateChanged(lexEvent, startIndex, len); }
void LexStateChanged(HtmlLexerEvent lexEvent, int startIndex, int len) { switch (lexEvent) { case HtmlLexerEvent.CommentContent: { //var commentContent = this.textSnapshot.Copy(startIndex, len); } break; case HtmlLexerEvent.FromContentPart: { if (curTextNode == null) { curTextNode = _resultHtmlDoc.CreateTextNode( HtmlDecodeHelper.DecodeHtml(this.textSnapshot, startIndex, len)); if (curHtmlNode != null) { curHtmlNode.AddChild(curTextNode); } } else { curTextNode.AppendTextContent(HtmlDecodeHelper.DecodeHtml(this.textSnapshot, startIndex, len)); } } break; case HtmlLexerEvent.AttributeValueAsLiteralString: { //assign value and add to parent curAttr.Value = textSnapshot.Substring(startIndex, len); curHtmlNode.AddAttribute(curAttr); } break; case HtmlLexerEvent.Attribute: { string nodename = textSnapshot.Substring(startIndex, len); curAttr = this._resultHtmlDoc.CreateAttribute(null, nodename); } break; case HtmlLexerEvent.NodeNameOrAttribute: { string name = textSnapshot.Substring(startIndex, len); switch (parseState) { case 0: { //create element DomElement elem = this._resultHtmlDoc.CreateElement(null, name); if (curHtmlNode != null) { curHtmlNode.AddChild(elem); openEltStack.Push(curHtmlNode); } curHtmlNode = elem; parseState = 1;//attribute curTextNode = null; curAttr = null; waitingAttrName = null; } break; case 1: { //wait for attr value if (waitingAttrName != null) { //push waiting attr curAttr = this._resultHtmlDoc.CreateAttribute(null, waitingAttrName); curAttr.Value = ""; curHtmlNode.AddAttribute(curAttr); curAttr = null; } waitingAttrName = name; } break; case 2: { //**** //node name after open slash //TODO: review here,avoid direct string comparison if (curHtmlNode.LocalName == name) { if (openEltStack.Count > 0) { waitingAttrName = null; curTextNode = null; curAttr = null; curHtmlNode = openEltStack.Pop(); } parseState = 3; } else { //if not equal then check if current node need close tag or not if (HtmlDecodeHelper.IsSingleTag(curHtmlNode.LocalNameIndex)) { if (openEltStack.Count > 0) { waitingAttrName = null; curHtmlNode = openEltStack.Pop(); curAttr = null; curTextNode = null; } if (curHtmlNode.LocalName == name) { if (openEltStack.Count > 0) { curTextNode = null; curAttr = null; curHtmlNode = openEltStack.Pop(); waitingAttrName = null; } parseState = 3; } else { //implement err handling here! throw new NotSupportedException(); } } else { //implement err handling here! throw new NotSupportedException(); } } } break; case 4: { //attribute value as id if (curAttr != null) { curAttr.Value = name; curAttr = null; parseState = 0; waitingAttrName = null; } else { } } break; case 10: { //document node parseState = 11; //after docnodename , this may be attr of the document node this.domDocNode = (DomDocumentNode)this._resultHtmlDoc.CreateDocumentNodeElement(); domDocNode.DocNodeName = name; } break; case 11: { //doc domDocNode.AddParameter(name); } break; default: { } break; } } break; case HtmlLexerEvent.VisitCloseAngle: { //close angle of current new node //enter into its content if (parseState == 11) { //add doctype to html this._resultHtmlDoc.RootNode.AddChild(this.domDocNode); domDocNode = null; } if (waitingAttrName != null) { curAttr = this._resultHtmlDoc.CreateAttribute(null, waitingAttrName); curAttr.Value = ""; curHtmlNode.AddAttribute(curAttr); curAttr = null; } waitingAttrName = null; parseState = 0; curTextNode = null; curAttr = null; } break; case HtmlLexerEvent.VisitAttrAssign: { parseState = 4; } break; case HtmlLexerEvent.VisitOpenSlashAngle: { parseState = 2; } break; case HtmlLexerEvent.VisitCloseSlashAngle: { if (openEltStack.Count > 0) { curTextNode = null; curAttr = null; waitingAttrName = null; curHtmlNode = openEltStack.Pop(); } parseState = 0; } break; case HtmlLexerEvent.VisitOpenAngleExclimation: { parseState = 10; } break; default: { //1. visit open angle } break; } }
void FlushExisingBuffer(int lastFlushAtIndex, HtmlLexerEvent lexerEvent) { //raise lexer event if (_appendCount > 0) { #if DEBUG //Console.WriteLine(lexerEvent.ToString() + " : " + // new string(this.textSnapshot.Copy(this._firstAppendAt, (this._readIndex - this._firstAppendAt) + 1))); #endif LexStateChanged(lexerEvent, this._firstAppendAt, (this._readIndex - this._firstAppendAt) + 1); } this._lastFlushAt = lastFlushAtIndex; this._appendCount = 0; }
void LexStateChanged(HtmlLexerEvent lexEvent, int startIndex, int len) { switch (lexEvent) { case HtmlLexerEvent.CommentContent: { //var commentContent = this.textSnapshot.Copy(startIndex, len); } break; case HtmlLexerEvent.FromContentPart: { if (curTextNode == null) { curTextNode = _resultHtmlDoc.CreateTextNode( HtmlDecodeHelper.DecodeHtml(this.textSnapshot, startIndex, len)); if (curHtmlNode != null) { curHtmlNode.AddChild(curTextNode); } } else { curTextNode.AppendTextContent(HtmlDecodeHelper.DecodeHtml(this.textSnapshot, startIndex, len)); } } break; case HtmlLexerEvent.AttributeValueAsLiteralString: { //assign value and add to parent curAttr.Value = textSnapshot.Substring(startIndex, len); curHtmlNode.AddAttribute(curAttr); } break; case HtmlLexerEvent.Attribute: { string nodename = textSnapshot.Substring(startIndex, len); curAttr = this._resultHtmlDoc.CreateAttribute(null, nodename); } break; case HtmlLexerEvent.NodeNameOrAttribute: { string name = textSnapshot.Substring(startIndex, len); switch (parseState) { case 0: { //create element DomElement elem = this._resultHtmlDoc.CreateElement(null, name); if (curHtmlNode != null) { curHtmlNode.AddChild(elem); openEltStack.Push(curHtmlNode); } curHtmlNode = elem; parseState = 1; //attribute curTextNode = null; curAttr = null; waitingAttrName = null; } break; case 1: { //wait for attr value if (waitingAttrName != null) { //push waiting attr curAttr = this._resultHtmlDoc.CreateAttribute(null, waitingAttrName); curAttr.Value = ""; curHtmlNode.AddAttribute(curAttr); curAttr = null; } waitingAttrName = name; } break; case 2: { //**** //node name after open slash //TODO: review here,avoid direct string comparison if (curHtmlNode.LocalName == name) { if (openEltStack.Count > 0) { waitingAttrName = null; curTextNode = null; curAttr = null; curHtmlNode = openEltStack.Pop(); } parseState = 3; } else { //if not equal then check if current node need close tag or not if (HtmlDecodeHelper.IsSingleTag(curHtmlNode.LocalNameIndex)) { if (openEltStack.Count > 0) { waitingAttrName = null; curHtmlNode = openEltStack.Pop(); curAttr = null; curTextNode = null; } if (curHtmlNode.LocalName == name) { if (openEltStack.Count > 0) { curTextNode = null; curAttr = null; curHtmlNode = openEltStack.Pop(); waitingAttrName = null; } parseState = 3; } else { //implement err handling here! throw new NotSupportedException(); } } else { //implement err handling here! throw new NotSupportedException(); } } } break; case 4: { //attribute value as id if (curAttr != null) { curAttr.Value = name; curAttr = null; parseState = 0; waitingAttrName = null; } else { } } break; case 10: { //document node parseState = 11; //after docnodename , this may be attr of the document node this.domDocNode = (DomDocumentNode)this._resultHtmlDoc.CreateDocumentNodeElement(); domDocNode.DocNodeName = name; } break; case 11: { //doc domDocNode.AddParameter(name); } break; default: { } break; } } break; case HtmlLexerEvent.VisitCloseAngle: { //close angle of current new node //enter into its content if (parseState == 11) { //add doctype to html this._resultHtmlDoc.RootNode.AddChild(this.domDocNode); domDocNode = null; } if (waitingAttrName != null) { curAttr = this._resultHtmlDoc.CreateAttribute(null, waitingAttrName); curAttr.Value = ""; curHtmlNode.AddAttribute(curAttr); curAttr = null; } waitingAttrName = null; parseState = 0; curTextNode = null; curAttr = null; } break; case HtmlLexerEvent.VisitAttrAssign: { parseState = 4; } break; case HtmlLexerEvent.VisitOpenSlashAngle: { parseState = 2; } break; case HtmlLexerEvent.VisitCloseSlashAngle: { if (openEltStack.Count > 0) { curTextNode = null; curAttr = null; waitingAttrName = null; curHtmlNode = openEltStack.Pop(); } parseState = 0; } break; case HtmlLexerEvent.VisitOpenAngleExclimation: { parseState = 10; } break; default: { //1. visit open angle } break; } }