using System; using System.Diagnostics; using System.IO; using System.Text; using System.Text.RegularExpressions; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; namespace Frost { /// /// /// public class Xhtml : Page { #region Private Variables private string _xhtml; private string _language; private XHtmlFormat _xhtmlFormat; private Encoding _encoding; private bool _xmlCDATA; #endregion #region Constructor /// /// Default Constructor. /// public Xhtml( ) { _xhtml = ""; _xhtmlFormat = XHtmlFormat.XHtml10_Strict; _language = "en-GB"; _xmlCDATA = false; } #endregion #region Overriding Methods /// /// /// /// protected override void Render( HtmlTextWriter writer ) { StringWriter sw = new StringWriter( ); HtmlTextWriter output = new HtmlTextWriter( sw ); base.Render( output ); output.Close( ); _xhtml = sw.GetStringBuilder( ).ToString( ); ReplaceDocType( ); switch ( _xhtmlFormat ) { case XHtmlFormat.XHtml10_Frameset: ConvertToXHtmlFrameset( ); break; case XHtmlFormat.XHtml10_Strict: ConvertToXHtmlStrict( ); break; case XHtmlFormat.XHtml10_Transitional: ConvertToXHtmlTransitional( ); break; } writer.Write( _xhtml ); } #endregion #region Private Methods /// /// /// /// private void AddSelfClose( string TagName ) { int start = 0; int pos = 0; while ( pos >= 0 ) { string search = "<" + TagName; pos = _xhtml.IndexOf( search, start ); if ( pos > 0 ) { start = pos + 1; int end = _xhtml.IndexOf( ">", start ); if ( _xhtml[ end - 1 ] != '/' ) { _xhtml = _xhtml.Insert( end, "/>" ); } } } } /// /// /// private void ConvertToLowerCase( ) { _xhtml = Regex.Replace( _xhtml, "<(/?)([a-zA-Z]+)(\\s*)>", new MatchEvaluator( SingleTagToLowerCase ), RegexOptions.IgnoreCase ); _xhtml = Regex.Replace( _xhtml, "<(/?)([a-zA-Z0-9]+)[ ]*(.*?)>", new MatchEvaluator( PropertiesToLowerCase ), RegexOptions.IgnoreCase ); _xhtml = Regex.Replace( _xhtml, "<([a-zA-Z0-9]+)(\\s+[a-zA-Z]+)(=\".+?>)", new MatchEvaluator( PropertiesToLowerCase ), RegexOptions.IgnoreCase ); } /// /// /// private void ConvertToXHtmlFrameset( ) { ConvertToLowerCase( ); AddSelfClose( "meta" ); FixHtml( ); } /// /// /// private void ConvertToXHtmlStrict( ) { ConvertToLowerCase( ); AddSelfClose( "meta" ); AddSelfClose( "link" ); AddSelfClose( "img" ); AddSelfClose( "hr" ); FixScript( ); RemoveAttribute( "form", "name" ); FixInput( ); FixBr( ); FixStyle( ); FixHtml( ); MaskScript( ); } /// /// /// private void ConvertToXHtmlTransitional( ) { ConvertToLowerCase( ); AddSelfClose( "meta" ); AddSelfClose( "link" ); AddSelfClose( "img" ); AddSelfClose( "hr" ); FixScript( ); FixBr( ); FixStyle( ); FixHtml( ); } /// /// /// private void FixBr( ) { _xhtml = _xhtml.Replace( "
", "
" ); } /// /// /// private void FixHtml( ) { _xhtml = Regex.Replace( _xhtml, "", new MatchEvaluator( HTMLTag ), RegexOptions.IgnoreCase ); } /// /// /// private void FixInput( ) { int start = 0; int pos = 0; while ( pos >= 0 ) { string search = " 0) { start = pos + search .Length; _xhtml = _xhtml.Insert(pos, "
");

					int end = _xhtml.IndexOf(">", start);
					if(end > 0)
					{
						_xhtml = _xhtml.Insert(end + 1, "
"); } } } } /// /// /// private void FixScript( ) { _xhtml = _xhtml.Replace( "){1}", new MatchEvaluator( FixStyleAndScript ), RegexOptions.IgnoreCase | RegexOptions.Singleline ); } /// /// /// /// /// private string NextProperty( Match m ) { string replace = m.Groups[ 1 ].ToString( ) + m.Groups[ 2 ].ToString( ).ToLower( ); if ( Regex.Match( m.Groups[ 3 ].ToString( ), "(.*?\")(\\s+\\w+)(=\".+>)", RegexOptions.IgnoreCase ).Success && m.Groups[ 3 ].ToString( ).IndexOf( "__VIEWSTATE" ) == -1 ) { Debug.WriteLine( "Match OK", "NextProperty" ); replace += Regex.Replace( m.Groups[ 3 ].ToString( ), "(.*?\")(\\s+\\w+)(=\".+>)", new MatchEvaluator( NextProperty ), RegexOptions.IgnoreCase ); } else { Debug.WriteLine( "Match Not OK", "NextProperty" ); replace += m.Groups[ 3 ].ToString( ); } return replace; } /// /// /// /// /// private string PropertiesToLowerCase( Match m ) { string replace = "<" + m.Groups[ 1 ].ToString( ) + m.Groups[ 2 ].ToString( ).ToLower( ); if ( Regex.Match( m.Groups[ 3 ].ToString( ), "(.*?\")(\\s+\\w+)(=\".+>)", RegexOptions.IgnoreCase ).Success ) { replace += Regex.Replace( m.Groups[ 3 ].ToString( ), "(.*?\")(\\s+\\w+)(=\".+>)", new MatchEvaluator( NextProperty ), RegexOptions.IgnoreCase ); } else { replace += m.Groups[ 3 ].ToString( ); } return replace; } /// /// /// /// /// private void RemoveAttribute( string TagName, string AttributeName ) { int start = 0; int pos = 0; while ( pos >= 0 ) { string search = "<" + TagName + "" + AttributeName + "=\""; pos = _xhtml.IndexOf( search, start ); if ( pos > 0 ) { start = pos + TagName.Length + 1; int end = _xhtml.IndexOf( "\"", pos + search.Length + 1 ); if ( end > 0 ) { _xhtml = _xhtml.Remove( start, end - start + 1 ); } } } } /// /// /// private void ReplaceDocType( ) { int start = _xhtml.IndexOf( " 0) { int end = _xhtml.IndexOf(">", start + 1); if(end > 0) { _xhtml = _xhtml.Remove(start, end - start + 1); switch(_xhtmlFormat) { case XHtmlFormat.XHtml10_Frameset: _xhtml = _xhtml.Insert(0, ""); break; case XHtmlFormat.XHtml10_Strict: _xhtml = _xhtml.Insert(0, ""); break; case XHtmlFormat.XHtml10_Transitional: _xhtml = _xhtml.Insert(0, ""); break; } } } } /// /// /// /// /// private string SingleTagToLowerCase(Match m) { if(m.Groups[3].ToString().Trim() == string.Empty) return "<" + m.Groups[1].ToString().ToLower() + m.Groups[2].ToString().ToLower() + ">"; else return "<" + m.Groups[1].ToString().ToLower() + m.Groups[2].ToString().ToLower() + "" + m.Groups[3].ToString() + ">"; } /// /// /// /// /// private string ToLowerCase( Match m ) { return m.ToString( ).ToLower( ); } #endregion #region Properties /// /// /// public XHtmlFormat XHTMLFormat { get { return _xhtmlFormat; } set { _xhtmlFormat = value; } } /// /// /// public Encoding Encoding { get { return _encoding; } set { _encoding = value; } } /// /// /// public string Language { get { return _language; } set { _language = value; } } /// /// /// public bool XMLCDATA { get { return _xmlCDATA; } set { _xmlCDATA = value; } } #endregion } }