using System;
using System.IO;
using System.Text.RegularExpressions;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
namespace Frost.Controls
{
///
/// Summary description for XHTMLPage.
///
public class XHTMLPage : Page
{
#region Private Variables
///
/// XHTML Code.
///
private string _xhtml;
///
/// XHTML Format To Use.
///
private XHtmlFormat _xhtmlFormat;
///
/// XHTML Encoding.
///
private Encoding _encoding;
///
/// Encoding Language
///
private string _language;
///
/// XML CDATA For Use By Bool.
///
private bool _xmlCDATA;
#endregion
#region Constructor
///
/// Default Constructor.
///
public XHTMLPage( )
{
_xhtml = "";
_xhtmlFormat = XHtmlFormat.XHtml10_Strict;
_encoding = Encoding.UTF8;
_language = "en";
_xmlCDATA = false;
}
#endregion
#region Properties
///
/// Input of which XHTMLFormat to use out of Strict, Transitional, Or Frameset.
///
public XHtmlFormat XHTMLFormat
{
get { return _xhtmlFormat; }
set { _xhtmlFormat = value; }
}
///
/// Input of the page encoding type.
///
public Encoding Encoding
{
get { return _encoding; }
set { _encoding = value; }
}
///
/// Input of the user language.
///
public string Language
{
get { return _language; }
set { _language = value; }
}
///
/// Should we use CDATA of XML?
///
public bool XmlCDATA
{
get { return _xmlCDATA; }
set { _xmlCDATA = value; }
}
#endregion
#region Overriden Methods
///
/// Render XHTML to the page.
///
///
protected override void Render( HtmlTextWriter output )
{
StringWriter w;
w = new StringWriter( );
HtmlTextWriter myoutput = new HtmlTextWriter( w );
base.Render( myoutput );
myoutput.Close( );
_xhtml = w.GetStringBuilder( ).ToString( );
ReplaceDocType( );
switch ( _xhtmlFormat )
{
case XHtmlFormat.XHtml10_Strict:
ConvertToXHTMLStrict( );
break;
case XHtmlFormat.XHtml10_Transitional:
ConvertToXHTMLTransitional( );
break;
case XHtmlFormat.XHtml10_Frameset:
ConvertToXHTMLFrameset( );
break;
}
output.Write( _xhtml );
}
#endregion
#region Private Methods
///
/// Self close the XHTML tag.
///
///
///
=>
///
/// XHTML Tag
private void AddSelfClose( string sTagName )
{
int nStart = 0;
int nPos = 0;
while ( nPos >= 0 )
{
string sSearch = "<" + sTagName;
nPos = _xhtml.IndexOf( sSearch, nStart );
if ( nPos > 0 )
{
nStart = nPos + 1;
int nEnd = _xhtml.IndexOf( ">", nStart );
if ( nEnd > 0 )
{
if ( _xhtml[ nEnd - 1 ] != '/' )
{
_xhtml = _xhtml.Insert( nEnd, " /" );
}
}
}
}
}
///
/// Convert text to lowercase
///
///
/// XHTML => xhtml
///
private void ConvertToLowerCase( )
{
_xhtml = Regex.Replace( _xhtml, "<(/?)([a-zA-Z0-9]+)[ ]*(.*?)>", new MatchEvaluator( SingleTagToLowerCase ), RegexOptions.IgnoreCase );
_xhtml = Regex.Replace( _xhtml, "<([a-zA-Z0-9]+)(\\s+[a-zA-Z]+)(=\".+?>)", new MatchEvaluator( PropertiesToLowerCase ), RegexOptions.IgnoreCase );
}
///
/// Convert the page to XHTML 1.0 Frameset Compliance.
///
private void ConvertToXHTMLFrameset( )
{
ConvertToLowerCase( );
AddSelfClose( "meta" );
AddSelfClose( "link" );
AddSelfClose( "img" );
AddSelfClose( "hr" );
//FixScript( );
FixBr( );
//FixStyle( );
FixHtml( );
maskScript( );
}
///
/// Convert the page to XHTML 1.0 Strict Compliance.
///
private void ConvertToXHTMLStrict( )
{
ConvertToLowerCase( );
AddSelfClose( "meta" );
AddSelfClose( "link" );
AddSelfClose( "img" );
AddSelfClose( "hr" );
//FixScript( );
RemoveAttribute( "form", "name" );
FixInput( );
FixBr( );
//FixStyle( );
FixHtml( );
maskScript( );
}
///
/// Convert the page to XHTML 1.0 Transitional Compliance.
///
private void ConvertToXHTMLTransitional( )
{
ConvertToLowerCase( );
AddSelfClose( "meta" );
AddSelfClose( "link" );
AddSelfClose( "img" );
AddSelfClose( "hr" );
//FixScript( );
FixBr( );
//FixStyle( );
FixHtml( );
}
///
/// Turns the HTML 4.01
.
///
///
///
=>
///
private void FixBr( )
{
_xhtml = _xhtml.Replace( "
", "
" );
}
///
/// Fix the HTML tag.
///
private void FixHtml( )
{
_xhtml = Regex.Replace( _xhtml, "", new MatchEvaluator( HTMLTag ), RegexOptions.IgnoreCase );
}
///
/// Fixes the Input
///
private void FixInput( )
{
int nStart = 0;
int nPos = 0;
while ( nPos >= 0 )
{
string sSearch = " 0 )
{
nStart = nPos + sSearch.Length;
_xhtml = _xhtml.Insert( nPos, "
" );
int nEnd = _xhtml.IndexOf( ">", nStart );
if ( nEnd > 0 )
{
_xhtml = _xhtml.Insert( nEnd + 1, "" );
}
}
}
}
///
///
///
private void FixScript( )
{
_xhtml = _xhtml.Replace( "
///
private void maskScript( )
{
_xhtml = Regex.Replace( _xhtml, @"(){1}", new MatchEvaluator( FixStyleAndScript ), RegexOptions.IgnoreCase | RegexOptions.Singleline );
}
///
/// Recursively search for property in tag
///
/// Match of the regular expression
/// tag with lower case properties
private string nextProperty( Match m )
{
string szReplace = "";
szReplace = m.Groups[ 1 ].ToString( ) + m.Groups[ 2 ].ToString( ).ToLower( );
// Search another property in tag
// Ignore if tag contains __VIEWSTATE... prevent long time calculation.
if ( Regex.Match( m.Groups[ 3 ].ToString( ), "(.*?\")(\\s+\\w+)(=\".+>)",
RegexOptions.IgnoreCase ).Success && m.Groups[ 3 ].ToString( ).IndexOf( "__VIEWSTATE" ) == -1 )
{
System.Diagnostics.Debug.WriteLine( "Match OK", "nextProperty" );
szReplace += Regex.Replace( m.Groups[ 3 ].ToString( ),
"(.*?\")(\\s+\\w+)(=\".+>)", new MatchEvaluator( nextProperty ),
RegexOptions.IgnoreCase );
}
else
{
System.Diagnostics.Debug.WriteLine( "Match NOK", "nextProperty" );
szReplace += m.Groups[ 3 ].ToString( );
}
return szReplace;
}
///
/// Make the properties of the tag.
///
/// Expression to match.
///
/// Returns the properties to lowercase.
///
private string PropertiesToLowerCase( Match m )
{
string szReplace = "";
szReplace = "<" + m.Groups[ 1 ].ToString( ) + m.Groups[ 2 ].ToString( ).ToLower( );
if ( Regex.Match( m.Groups[ 3 ].ToString( ), "(.*?\")(\\s+\\w+)(=\".+>)", RegexOptions.IgnoreCase ).Success )
{
szReplace += Regex.Replace( m.Groups[ 3 ].ToString( ),
"(.*?\")(\\s+\\w+)(=\".+>)", new MatchEvaluator( nextProperty ), RegexOptions.IgnoreCase );
}
else
{
szReplace += m.Groups[ 3 ].ToString( );
}
return szReplace;
}
///
/// Removes the specific tag.
///
/// Tag name for attribute to be removed from.
/// Attribute to remove.
private void RemoveAttribute( string sTagName, string sAttrName )
{
int nStart = 0;
int nPos = 0;
while ( nPos >= 0 )
{
string sSearch = "<" + sTagName + " " + sAttrName + "=\"";
nPos = _xhtml.IndexOf( sSearch, nStart );
if ( nPos > 0 )
{
nStart = nPos + sTagName.Length + 1;
int nEnd = _xhtml.IndexOf( "\"", nPos + sSearch.Length + 1 );
if ( nEnd > 0 )
{
_xhtml = _xhtml.Remove( nStart, nEnd - nStart + 1 );
}
}
}
}
private void ReplaceTitle()
{
int nStart = _xhtml.IndexOf( " 0)
{
int nEnd = _xhtml.IndexOf( ">", nStart + 1 );
if(nEnd > 0)
{
_xhtml = _xhtml.Remove(nStart, nEnd - nStart + 1);
_xhtml = "\n\t Frost Designz ";
}
}
}
///
/// Removes the default DOCTYPE and replacee. And uses the correct doctype.
///
private void ReplaceDocType( )
{
int nStart = _xhtml.IndexOf( " 0 )
{
int nEnd = _xhtml.IndexOf( ">", nStart + 1 );
if ( nEnd > 0 )
{
_xhtml = _xhtml.Remove( nStart, nEnd - nStart + 1 );
switch ( _xhtmlFormat )
{
case XHtmlFormat.XHtml10_Strict:
_xhtml = _xhtml.Insert( 0, "\n" );
break;
case XHtmlFormat.XHtml10_Transitional:
_xhtml = _xhtml.Insert( 0, "\n" );
break;
case XHtmlFormat.XHtml10_Frameset:
_xhtml = _xhtml.Insert( 0, "\n" );
break;
}
}
}
}
///
/// Single tag to be lowercase.
///
/// Expression to be match.
///
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( ) + ">";
}
///
/// Lowercase the match.
///
/// Expression to be match.
///
/// Returns the lowercase match.
///
private string ToLowerCase( Match m )
{
return m.ToString( ).ToLower( );
}
#endregion
}
}