rendered paste bodyusing 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>
/// Summary description for XHTMLPage.
/// </summary>
public class XHTMLPage : Page
{
#region Private Variables
/// <summary>
/// XHTML Code.
/// </summary>
private string _xhtml;
/// <summary>
/// XHTML Format To Use.
/// </summary>
private XHtmlFormat _xhtmlFormat;
/// <summary>
/// XHTML Encoding.
/// </summary>
private Encoding _encoding;
/// <summary>
/// Encoding Language
/// </summary>
private string _language;
/// <summary>
/// XML CDATA For Use By Bool.
/// </summary>
private bool _xmlCDATA;
#endregion
#region Constructor
/// <summary>
/// Default Constructor.
/// </summary>
public XHTMLPage( )
{
_xhtml = "";
_xhtmlFormat = XHtmlFormat.XHtml10_Strict;
_encoding = Encoding.UTF8;
_language = "en";
_xmlCDATA = false;
}
#endregion
#region Properties
/// <summary>
/// Input of which XHTMLFormat to use out of Strict, Transitional, Or Frameset.
/// </summary>
public XHtmlFormat XHTMLFormat
{
get { return _xhtmlFormat; }
set { _xhtmlFormat = value; }
}
/// <summary>
/// Input of the page encoding type.
/// </summary>
public Encoding Encoding
{
get { return _encoding; }
set { _encoding = value; }
}
/// <summary>
/// Input of the user language.
/// </summary>
public string Language
{
get { return _language; }
set { _language = value; }
}
/// <summary>
/// Should we use CDATA of XML?
/// </summary>
public bool XmlCDATA
{
get { return _xmlCDATA; }
set { _xmlCDATA = value; }
}
#endregion
#region Overriden Methods
/// <summary>
/// Render XHTML to the page.
/// </summary>
/// <param name="output"></param>
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
/// <summary>
/// Self close the XHTML tag.
/// </summary>
/// <example>
/// <hr> => <hr />
/// </example>
/// <param name="sTagName">XHTML Tag</param>
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, " /" );
}
}
}
}
}
/// <summary>
/// Convert text to lowercase
/// </summary>
/// <example>
/// XHTML => xhtml
/// </example>
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 );
}
/// <summary>
/// Convert the page to XHTML 1.0 Frameset Compliance.
/// </summary>
private void ConvertToXHTMLFrameset( )
{
ConvertToLowerCase( );
AddSelfClose( "meta" );
AddSelfClose( "link" );
AddSelfClose( "img" );
AddSelfClose( "hr" );
//FixScript( );
FixBr( );
//FixStyle( );
FixHtml( );
maskScript( );
}
/// <summary>
/// Convert the page to XHTML 1.0 Strict Compliance.
/// </summary>
private void ConvertToXHTMLStrict( )
{
ConvertToLowerCase( );
AddSelfClose( "meta" );
AddSelfClose( "link" );
AddSelfClose( "img" );
AddSelfClose( "hr" );
//FixScript( );
RemoveAttribute( "form", "name" );
FixInput( );
FixBr( );
//FixStyle( );
FixHtml( );
maskScript( );
}
/// <summary>
/// Convert the page to XHTML 1.0 Transitional Compliance.
/// </summary>
private void ConvertToXHTMLTransitional( )
{
ConvertToLowerCase( );
AddSelfClose( "meta" );
AddSelfClose( "link" );
AddSelfClose( "img" );
AddSelfClose( "hr" );
//FixScript( );
FixBr( );
//FixStyle( );
FixHtml( );
}
/// <summary>
/// Turns the HTML 4.01 <br>.
/// </summary>
/// <example>
/// <br> => <br />
/// </example>
private void FixBr( )
{
_xhtml = _xhtml.Replace( "<br>", "<br />" );
}
/// <summary>
/// Fix the HTML tag.
/// </summary>
private void FixHtml( )
{
_xhtml = Regex.Replace( _xhtml, "<html>", new MatchEvaluator( HTMLTag ), RegexOptions.IgnoreCase );
}
/// <summary>
/// Fixes the Input
/// </summary>
private void FixInput( )
{
int nStart = 0;
int nPos = 0;
while ( nPos >= 0 )
{
string sSearch = "<input type=\"hidden\"";
nPos = _xhtml.IndexOf( sSearch, nStart );
if ( nPos > 0 )
{
nStart = nPos + sSearch.Length;
_xhtml = _xhtml.Insert( nPos, "<pre>" );
int nEnd = _xhtml.IndexOf( ">", nStart );
if ( nEnd > 0 )
{
_xhtml = _xhtml.Insert( nEnd + 1, "</pre>" );
}
}
}
}
/// <summary>
///
/// </summary>
private void FixScript( )
{
_xhtml = _xhtml.Replace( "<script language=\"javascript\">", "<script type=\"text/javascript\">" );
}
/// <summary>
/// Fixes the Style Tag.
/// </summary>
/// <example>
/// <!--
/// body, html
/// {
/// color: white;
/// }
/// -->
/// </example>
private void FixStyle( )
{
_xhtml = Regex.Replace( _xhtml, "style=\".+\"", new MatchEvaluator( ToLowerCase ), RegexOptions.IgnoreCase );
_xhtml = Regex.Replace( _xhtml, @"(<style[^<]*>){1}(?(?=\s*<!--)(\s*<!--)(\s*.*?)(//\s*-->)|(\s*.*?))\s*(</style>){1}", new MatchEvaluator( FixStyleAndScript ), RegexOptions.IgnoreCase | RegexOptions.Singleline );
}
/// <summary>
/// Fixes the style and script based on match.
/// </summary>
/// <param name="m">Expression to match.</param>
/// <returns></returns>
private string FixStyleAndScript( Match m )
{
string ret = "";
string st, ed;
if ( _xmlCDATA )
{
st = "\r\n<![CDATA[\r\n";
ed = "\r\n]]>\r\n";
}
else
{
st = "\r\n<!--\r\n";
ed = "\r\n//-->\r\n";
}
if ( m.Groups[ 2 ].ToString( ).Trim( ) == "" && m.Groups[ 4 ].ToString( ).Trim( ) == "" )
st = ed = "";
ret = m.Groups[ 1 ].ToString( ) + st;
ret += m.Groups[ 2 ].ToString( ) + m.Groups[ 4 ].ToString( ) + ed + m.Groups[ 5 ].ToString( );
return ret;
}
/// <summary>
/// Fixes the HTML tag to include the XMLNS and the XML:LANG
/// </summary>
/// <param name="m">Expression To Match.</param>
/// <returns>
/// Returns the correct XHTML Tag.
/// </returns>
private string HTMLTag( Match m )
{
return "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"" + _language + "\">";
}
/// <summary>
/// Fixes the script tag to hide from older browsers.
/// </summary>
/// <example>
/// <script type="text/javascript">
/// <!--
/// document.write("Example");
/// -->
/// </script>
/// </example>
private void maskScript( )
{
_xhtml = Regex.Replace( _xhtml, @"(<script[^<]*>){1}(?(?=\s*<!--)(\s*<!--)(\s*.*?)(//\s*-->)|(\s*.*?))\s*(</script>){1}", new MatchEvaluator( FixStyleAndScript ), RegexOptions.IgnoreCase | RegexOptions.Singleline );
}
/// <summary>
/// Recursively search for property in tag
/// </summary>
/// <param name="m">Match of the regular expression</param>
/// <returns>tag with lower case properties</returns>
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;
}
/// <summary>
/// Make the properties of the tag.
/// </summary>
/// <param name="m">Expression to match.</param>
/// <returns>
/// Returns the properties to lowercase.
/// </returns>
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;
}
/// <summary>
/// Removes the specific tag.
/// </summary>
/// <param name="sTagName">Tag name for attribute to be removed from.</param>
/// <param name="sAttrName">Attribute to remove.</param>
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( "<title", 0 );
if(nStart > 0)
{
int nEnd = _xhtml.IndexOf( ">", nStart + 1 );
if(nEnd > 0)
{
_xhtml = _xhtml.Remove(nStart, nEnd - nStart + 1);
_xhtml = "\n\t<title> Frost Designz </title>";
}
}
}
/// <summary>
/// Removes the default DOCTYPE and replacee. And uses the correct doctype.
/// </summary>
private void ReplaceDocType( )
{
int nStart = _xhtml.IndexOf( "<!DOCTYPE", 0 );
if ( nStart > 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, "<?xml encoding=\"utf-8\" version=\"1.0\" ?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">" );
break;
case XHtmlFormat.XHtml10_Transitional:
_xhtml = _xhtml.Insert( 0, "<?xml encoding=\"utf-8\" version=\"1.0\" ?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" );
break;
case XHtmlFormat.XHtml10_Frameset:
_xhtml = _xhtml.Insert( 0, "<?xml encoding=\"utf-8\" version=\"1.0\" ?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">" );
break;
}
}
}
}
/// <summary>
/// Single tag to be lowercase.
/// </summary>
/// <param name="m">Expression to be match.</param>
/// <returns></returns>
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( ) + ">";
}
/// <summary>
/// Lowercase the match.
/// </summary>
/// <param name="m">Expression to be match.</param>
/// <returns>
/// Returns the lowercase match.
/// </returns>
private string ToLowerCase( Match m )
{
return m.ToString( ).ToLower( );
}
#endregion
}
}