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
}
}