Xamarin Public Jenkins (auto-signing) e79aa3c0ed Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
2016-08-03 10:59:49 +00:00

996 lines
33 KiB
C#

//------------------------------------------------------------------------------
// <copyright file="WmlTextWriter.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
#if WMLSUPPORT
namespace System.Web.UI {
using System.Collections;
using System.Collections.Specialized;
using System.Globalization;
using System.IO;
using System.Security.Permissions;
using System.Web.UI.Adapters;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.Adapters;
using System.Web.Util;
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public class WmlTextWriter : HtmlTextWriter {
private static readonly char[] _attributeCharacters = new char[] {'"', '&', '<', '>', '$'};
private static Layout _defaultLayout = new Layout(HorizontalAlign.NotSet, true);
public const String PostBackWithVarsCardID = "__pbc1";
private bool _alwaysScrambleClientIDs = false;
private EmptyTextWriter _analyzeWriter;
private bool _analyzeMode = false;
private const String _boldTag = "b";
private bool _boldTagOpen = false;
// UNDONE: This HttpBrowserCapabilities instance couples the writer with the HttpContext and can be removed.
private HttpBrowserCapabilities _browser = null;
private IDictionary _controlShortNames = null;
private HtmlForm _currentForm = null;
private static Style _defaultStyle = new Style();
private bool _paragraphOpen = false;
private const String _italicTag = "i";
private bool _italicTagOpen = false;
private const String _largeTag = "big";
private bool _largeTagOpen = false;
private Stack _layoutStack = new Stack();
private const int _maxShortNameLength = 16;
private int _numberOfSoftkeys;
private bool _openingPWritten = true; // True if the current control was immediately preceded by an opening p. Valid between BeginRender and EndRender.
private bool _pendingP = false;
private Stack _panelStyleStack = new Stack();
private const String _postBackEventArgumentVarName = "mcsva";
private const String _postBackEventTargetVarName = "mcsvt";
private IDictionary _radioButtonGroups = new ListDictionary();
private static Random _random = new Random();
private TextWriter _realInnerWriter;
private const String _shortNamePrefix = "mcsv";
private const String _smallTag = "small";
private bool _smallTagOpen = false;
private Stack _styleStack = new Stack();
private bool _topOfFormOrPanel = false; // True if at top of form or panel, before opening p.
public WmlTextWriter(TextWriter writer) : this(writer, DefaultTabString) {
}
public WmlTextWriter(TextWriter writer, string tabString) : base(writer, tabString) {
_realInnerWriter = writer;
_numberOfSoftkeys = Convert.ToInt32(Browser["NumberOfSoftkeys"], CultureInfo.InvariantCulture);
if (_numberOfSoftkeys > 2) {
_numberOfSoftkeys = 2;
}
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
// AnalyzeMode is set to true during first analysis pass of rendering.
public bool AnalyzeMode
{
get {
return _analyzeMode;
}
}
// UNDONE: This property couples the writer to the HttpContext and can be removed.
private HttpBrowserCapabilities Browser {
get {
if (_browser == null && HttpContext.Current != null) {
_browser = HttpContext.Current.Request.Browser;
}
return _browser;
}
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public virtual HtmlForm CurrentForm {
set {
_currentForm = value;
}
get {
return _currentForm;
}
}
/// <devdoc>
/// <para> [To be supplied.]</para>
/// <devdoc>
private Layout CurrentLayout {
get {
if (_layoutStack.Count > 0) {
return(Layout) _layoutStack.Peek();
}
else {
return _defaultLayout;
}
}
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public Style CurrentStyle {
get {
if (_styleStack.Count > 0) {
return(Style)_styleStack.Peek();
}
else {
return DefaultStyle;
}
}
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
protected virtual Style DefaultStyle
{
get
{
return _defaultStyle;
}
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
protected int NumberOfSoftkeys
{
get
{
return _numberOfSoftkeys;
}
}
// See Whidbey 33012.
internal override bool SkipRenderDelegates {
get {
return AnalyzeMode;
}
}
/// <devdoc>
/// <para>True if at top of form or panel, before opening p.</para>
/// </devdoc>
public bool TopOfForm {
get {
return _topOfFormOrPanel;
}
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
// UNDONE: See whether this method can be replaced by calls to RenderBeginTag.
public override void BeginRender() {
if (AnalyzeMode) {
return;
}
_openingPWritten = WritePendingP();
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
internal void BeginFormOrPanel() {
if (AnalyzeMode) {
return;
}
_topOfFormOrPanel = true;
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
private void BeginBlockLevelControl() {
if (AnalyzeMode) {
return;
}
if (_openingPWritten || _topOfFormOrPanel) {
return;
}
CloseParagraph();
OpenParagraph();
}
// Helper to reset all the internal state whenever Analyze mode changes.
private void ClearFlags() {
_paragraphOpen = false;
_italicTagOpen = false;
_largeTagOpen = false;
_layoutStack = new Stack();
_openingPWritten = true; // True if the current control was immediately preceded by an opening p. Valid between BeginRender and EndRender.
_pendingP = false;
_panelStyleStack = new Stack();
_smallTagOpen = false;
_styleStack = new Stack();
_topOfFormOrPanel = false; // True if at top of form or panel, before opening p.
}
/// <devdoc>
/// <para>Close any open paragraph.</para>
/// </devdoc>
protected internal virtual void CloseParagraph() {
if (!_paragraphOpen) {
return;
}
CloseCurrentStyleTags();
Indent--;
WriteLine();
WriteEndTag("p");
WriteLine();
_paragraphOpen = false;
}
/// <devdoc>
/// <para>Close any open character formatting tags. Public for TextBox adapter.</para>
/// </devdoc>
internal void CloseCurrentStyleTags() {
if (_largeTagOpen) {
WriteEndTag(_largeTag);
_largeTagOpen = false;
}
if (_smallTagOpen) {
WriteEndTag(_smallTag);
_smallTagOpen = false;
}
if (_italicTagOpen) {
WriteEndTag(_italicTag);
_italicTagOpen = false;
}
if (_boldTagOpen) {
WriteEndTag(_boldTag);
_boldTagOpen = false;
}
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
private void EndBlockLevelControl() {
if (AnalyzeMode) {
return;
}
_pendingP = true;
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public override void EnterStyle(Style style, HtmlTextWriterTag tag) {
// Ignore tag for wml.
if (AnalyzeMode) {
return;
}
// All "block level controls" (controls that render using block level elements in HTML) call enterStyle
// using a div. Here we ensure that a new p is open for these controls to ensure line breaking behavior.
if (tag == HtmlTextWriterTag.Div) {
BeginBlockLevelControl();
}
Style stackStyle = new Style();
stackStyle.CopyFrom(style);
stackStyle.MergeWith(CurrentStyle);
if (_panelStyleStack.Count > 0) {
stackStyle.MergeWith((Style)_panelStyleStack.Peek());
}
_styleStack.Push(stackStyle); // updates CurrentStyle
if (_paragraphOpen) {
OpenCurrentStyleTags();
}
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public override void ExitStyle(Style style, HtmlTextWriterTag tag) {
// Ignore tag for wml.
if (AnalyzeMode) {
return;
}
// No need to call CloseCurrentStyleTags() here, because OpenCurrentStyleTags() closes anything
// that is not current and already open. Call to CurrentStyleTags() results in correct but
// unnecessary extra tags. VSWhidbey 156207.
if (_styleStack.Count > 0) {
_styleStack.Pop();
}
OpenCurrentStyleTags();
// All "block level controls" (controls that render using block level elements in HTML) call exitStyle
// using a div. Here we ensure that a new p is open for these controls to ensure line breaking behavior.
if (tag == HtmlTextWriterTag.Div) {
EndBlockLevelControl();
}
}
/// <devdoc>
/// <para>Escape '&' in XML if it hasn't been.</para>
/// </devdoc>
internal String EscapeAmpersand(String url) {
if (url == null) {
return null;
}
char ampersand = '&';
string ampEscaped = "amp;";
int ampPos = url.IndexOf(ampersand);
while (ampPos != -1) {
if (url.Length - ampPos <= ampEscaped.Length ||
url.Substring(ampPos + 1, ampEscaped.Length) != ampEscaped) {
url = url.Insert(ampPos + 1, ampEscaped);
}
ampPos = url.IndexOf(ampersand, ampPos + ampEscaped.Length + 1);
}
return url;
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public override void Flush() {
if (AnalyzeMode) {
return;
}
base.Flush();
}
/// <devdoc>
/// <para>Makes sure the writer has rendered character formatting tags corresponding to the current format.</para>
/// </devdoc>
private String GetRandomID(int length) {
Byte[] randomBytes = new Byte[length];
_random.NextBytes(randomBytes);
char[] randomChars = new char[length];
for (int i = 0; i < length; i++) {
randomChars[i] = (char)((((int)randomBytes[i]) % 26) + 'a');
}
return new String(randomChars);
}
/// <devdoc>
/// <para>
/// MapClientIDToShortName provides a unique map of control ClientID properties
/// to shorter names. In cases where a control has a very long ClientID, a
/// shorter unique name is used. All references to the client ID on the page
/// are mapped, resulting in the same postback regardless of mapping.
/// MapClientIDToShortName also scrambles client IDs that need to be
/// scrambled for security reasons.
/// </para>
/// </devdoc>
protected internal String MapClientIDToShortName(String clientID, bool generateRandomID) {
if (_alwaysScrambleClientIDs) {
generateRandomID = true;
}
if (_controlShortNames != null) {
String lookup = (String)_controlShortNames[clientID];
if (lookup != null) {
return lookup;
}
}
if (!generateRandomID) {
bool shortID = clientID.Length < _maxShortNameLength;
// Map names with underscores, colons, and conflicting names regardless of length.
bool goodID = (clientID.IndexOf(':') == -1) &&
(clientID.IndexOf('_') == -1) &&
!NameConflicts(clientID);
if (shortID && goodID) {
return clientID;
}
}
if (_controlShortNames == null) {
_controlShortNames = new ListDictionary();
}
String shortName;
if (generateRandomID) {
shortName = GetRandomID(5);
}
else {
shortName = String.Empty;
}
shortName = String.Concat(_shortNamePrefix, shortName, _controlShortNames.Count.ToString(CultureInfo.InvariantCulture));
_controlShortNames[clientID] = shortName;
return shortName;
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
private bool NameConflicts(String name) {
if (name == null) {
return false;
}
Debug.Assert(_postBackEventTargetVarName.ToLower(CultureInfo.InvariantCulture) == _postBackEventTargetVarName &&
_postBackEventArgumentVarName.ToLower(CultureInfo.InvariantCulture) == _postBackEventArgumentVarName &&
_shortNamePrefix.ToLower(CultureInfo.InvariantCulture) == _shortNamePrefix);
name = name.ToLower(CultureInfo.InvariantCulture);
return name == _postBackEventTargetVarName ||
name == _postBackEventArgumentVarName ||
StringUtil.StringStartsWith(name, _shortNamePrefix);
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public virtual void OpenParagraph() {
Layout layout = CurrentLayout;
OpenParagraph(layout,
(layout != null) && (layout.Align != HorizontalAlign.NotSet),
(layout != null) && !layout.Wrap);
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
private void OpenParagraph(Layout layout, bool writeHorizontalAlign, bool writeWrapping) {
CloseParagraph(); // does nothing if paragraph is not open.
WriteBeginTag("p");
if (writeHorizontalAlign) {
String alignment;
switch (layout.Align) {
case HorizontalAlign.Right:
alignment = "right";
break;
case HorizontalAlign.Center:
alignment = "center";
break;
default:
alignment = "left";
break;
}
WriteAttribute("align", alignment);
}
if (writeWrapping) {
WriteAttribute("mode",
layout.Wrap == true ? "wrap" : "nowrap");
}
Write(">");
_paragraphOpen = true;
Indent++;
WriteLine();
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
internal void OpenCurrentStyleTags() {
// Review: This results in extra tags in some situations. May want to get rid of the extra tags and make
// this logic more object oriented.
// Opening font tags are always kept in order in order <b>, <i>, <size>. If anything is open out of order,
// for example <i> is open and we want to open <b>, we close the "out of order" tag, then reopen it later,
// if necessary.
Style format = CurrentStyle;
// First close all open elements we no longer want.
if (_smallTagOpen) {
if (format.Font.Size == FontUnit.Empty ||
format.Font.Size == FontUnit.Larger ||
format.Font.Size == FontUnit.Large ||
format.Font.Size == FontUnit.XLarge ||
format.Font.Size == FontUnit.XXLarge) {
WriteEndTag(_smallTag);
_smallTagOpen = false;
}
}
if (_largeTagOpen) {
if (format.Font.Size == FontUnit.Empty ||
format.Font.Size == FontUnit.Smaller ||
format.Font.Size == FontUnit.Small ||
format.Font.Size == FontUnit.XSmall ||
format.Font.Size == FontUnit.XXSmall) {
WriteEndTag(_largeTag);
_largeTagOpen = false;
}
}
if (!format.Font.Italic && _italicTagOpen) {
if (_smallTagOpen) {
WriteEndTag(_smallTag);
_smallTagOpen = false;
}
if (_largeTagOpen) {
WriteEndTag(_largeTag);
_largeTagOpen = false;
}
WriteEndTag(_italicTag);
_italicTagOpen = false;
}
if (!format.Font.Bold && _boldTagOpen) {
if (_smallTagOpen) {
WriteEndTag(_smallTag);
_smallTagOpen = false;
}
if (_largeTagOpen) {
WriteEndTag(_largeTag);
_largeTagOpen = false;
}
if (_italicTagOpen) {
WriteEndTag(_italicTag);
_italicTagOpen = false;
}
WriteEndTag(_boldTag);
_boldTagOpen = false;
}
// Now open any elements we need which are not yet open.
if (format.Font.Bold && !_boldTagOpen) {
if (_smallTagOpen) {
WriteEndTag(_smallTag);
_smallTagOpen = false;
}
if (_largeTagOpen) {
WriteEndTag(_largeTag);
_largeTagOpen = false;
}
if (_italicTagOpen) {
WriteEndTag(_italicTag);
_italicTagOpen = false;
}
WriteFullBeginTag(_boldTag);
_boldTagOpen = true;
}
if (format.Font.Italic && !_italicTagOpen) {
if (_smallTagOpen) {
WriteEndTag(_smallTag);
_smallTagOpen = false;
}
if (_largeTagOpen) {
WriteEndTag(_largeTag);
_largeTagOpen = false;
}
WriteFullBeginTag(_italicTag);
_italicTagOpen = true;
}
if (format.Font.Size != FontUnit.Empty) {
if (format.Font.Size == FontUnit.Larger ||
format.Font.Size == FontUnit.Large ||
format.Font.Size == FontUnit.XLarge ||
format.Font.Size == FontUnit.XXLarge) {
if (!_largeTagOpen) {
WriteFullBeginTag(_largeTag);
_largeTagOpen = true;
}
}
if (format.Font.Size == FontUnit.Smaller ||
format.Font.Size == FontUnit.Small ||
format.Font.Size == FontUnit.XSmall ||
format.Font.Size == FontUnit.XXSmall) {
if (!_smallTagOpen) {
WriteFullBeginTag(_smallTag);
_smallTagOpen = true;
}
}
}
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public void PopLayout() {
if (_layoutStack.Count == 0) {
Debug.Fail("Layout stack is empty.");
return;
}
_layoutStack.Pop();
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
internal void PopPanelStyle() {
if (_panelStyleStack.Count == 0) {
Debug.Fail("Stack is empty.");
return;
}
_panelStyleStack.Pop();
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public void PushLayout(HorizontalAlign align, bool wrap) {
Layout newLayout = new Layout(align, wrap);
newLayout.MergeWith(CurrentLayout);
_layoutStack.Push(newLayout);
}
/// <devdoc>
/// <para>Push style on stack, but do not open it. Used for pending styles, as in the panel and page adapters.</para>
/// </devdoc>
internal void PushPanelStyle(Style style) {
Style stackStyle = new Style();
if (_panelStyleStack.Count == 0) {
stackStyle.CopyFrom(style);
_panelStyleStack.Push(stackStyle);
return;
}
stackStyle.CopyFrom((Style)_panelStyleStack.Peek());
stackStyle.MergeWith(style);
_panelStyleStack.Push(stackStyle);
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public virtual void RenderImage(String source, String localSource, String alternateText) {
if (AnalyzeMode) {
return;
}
WriteBeginTag("img");
WriteAttribute("src", source, true);
if (localSource != null) {
WriteAttribute("localsrc", localSource, true);
}
WriteTextEncodedAttribute("alt", alternateText != null ? alternateText : String.Empty);
Write(" />");
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
internal String ReplaceFormsCookieWithVariable(String queryString) {
// UNDONE: MMIT FormsAuthentication not integrated yet
return queryString;
}
public void SetAnalyzeMode(bool analyzeMode) {
_analyzeMode = analyzeMode;
if (analyzeMode) {
_analyzeWriter = new EmptyTextWriter();
InnerWriter = _analyzeWriter;
}
else {
InnerWriter = _realInnerWriter;
}
ClearFlags();
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public void SetPendingP() {
if (AnalyzeMode) {
return;
}
_pendingP = true;
}
/// <devdoc>
/// [To be supplied.]
/// </devdoc>
public override void WriteAttribute(String attribute, String value) {
// Must double $'s for valid WML, so call WriteAttribute with encode == true.
WriteAttribute(attribute, value, true /* encode */);
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public override void WriteAttribute(String attribute, String value, bool encode) {
// If in analyze mode, we don't actually have to perform the conversion, because
// it's not getting written anyway.
// If the value is null, we return without writing anything. This is different
// from HtmlTextWriter, which writes the name of the attribute, but no value at all.
// A name with no value is illegal in Wml.
if (value == null) {
return;
}
if (AnalyzeMode || !encode) {
base.WriteAttribute(attribute, value, false /* encode */);
return;
}
WriteTextEncodedAttribute(attribute, value);
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public virtual void WriteBeginSelect(String name, String value, String iname, String ivalue, String title, bool multiSelect) {
if (AnalyzeMode) {
return;
}
// Select tags cannot appear inside character formatting tags,
// so close any character formatting.
CloseCurrentStyleTags();
// Certain devices always render a break before a <select>. If
// we're on such a device, cancel any pending breaks.
if (Browser["rendersBreakBeforeWmlSelectAndInput"] == "true") {
// _pendingBreak = false;
}
//EnsureLayout();
WriteBeginTag("select");
if (!String.IsNullOrEmpty(name)) {
// Map the client ID to a short name. See
// MapClientIDToShortName for details.
WriteAttribute("name", MapClientIDToShortName(name, false));
}
if (!String.IsNullOrEmpty(value)) {
WriteTextEncodedAttribute("value", value);
}
if (!String.IsNullOrEmpty(iname)) {
// Map the client ID to a short name. See
// MapClientIDToShortName for details.
WriteAttribute("iname", MapClientIDToShortName(iname, false));
}
// UNDONE: The FormAdapter WrittenFormVariables property couples this writer with the form adapter. Consider
// removing the property somehow.
if (!((WmlPageAdapter)CurrentForm.Page.Adapter).WrittenFormVariables && ivalue != null && ivalue.Length > 0) {
WriteTextEncodedAttribute("ivalue", ivalue);
}
if (!String.IsNullOrEmpty(title)) {
WriteTextEncodedAttribute("title", title);
}
if (multiSelect) {
WriteAttribute("multiple", "true");
}
Write(">");
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public override void WriteBreak() {
WriteLine("<br/>");
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
protected internal void WriteTextEncodedAttribute(String attribute, String value) {
// Unlike HTML encoding, we need to replace $ with $$, and <> with &lt; and &gt;.
// We can't do this by piggybacking HtmlTextWriter.WriteAttribute, because it
// would translate the & in &lt; or &gt; to &amp;. So we more or less copy the
// ASP.NET code that does similar encoding.
Write(' ');
Write(attribute);
Write("=\"");
int cb = value.Length;
int pos = value.IndexOfAny(_attributeCharacters);
if (pos == -1) {
Write(value);
}
else {
char[] s = value.ToCharArray();
int startPos = 0;
while (pos < cb) {
if (pos > startPos) {
Write(s, startPos, pos - startPos);
}
char ch = s[pos];
switch (ch) {
case '\"':
Write("&quot;");
break;
case '&':
Write("&amp;");
break;
case '<':
Write("&lt;");
break;
case '>':
Write("&gt;");
break;
case '$':
Write("$$");
break;
}
startPos = pos + 1;
pos = value.IndexOfAny(_attributeCharacters, startPos);
if (pos == -1) {
Write(s, startPos, cb - startPos);
break;
}
}
}
Write('\"');
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public override void WriteEncodedUrl(String url) {
if (url == null) {
return;
}
int i = url.IndexOf('?');
if (i != -1) {
WriteUrlEncodedString(url.Substring(0, i), false);
String s = url.Substring(i);
if (s.IndexOf('$') != -1) {
s = s.Replace("$", "%24");
}
base.WriteEncodedText(s);
}
else {
WriteUrlEncodedString(url, false);
}
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public override void WriteEncodedText(String text) {
if (text == null) {
return;
}
if (text.IndexOf('$') != -1) {
text = text.Replace("$", "$$");
}
base.WriteEncodedText(text);
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public virtual void WriteEndSelect() {
if (AnalyzeMode) {
return;
}
WriteEndTag("select");
WriteLine();
OpenCurrentStyleTags(); // Style tags are closed before writing a begin select, so reopen them here.
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
private bool WritePendingP() {
if (!_topOfFormOrPanel && !_pendingP) {
return false; // no P written.
}
OpenParagraph();
_topOfFormOrPanel = _pendingP = false;
return true; // P written.
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
private void WritePlainText(String text) {
if (text == null) {
return;
}
if (text.IndexOf('$') != -1) {
text = text.Replace("$", "$$");
}
Write(text);
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
internal void WritePostField(String name, String value) {
WritePostField(name, value, WmlPostFieldType.Normal);
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
internal void WritePostField(String name, String value, WmlPostFieldType type) {
Write("<postfield name=\"");
Write(name);
Write("\" value=\"");
if (type == WmlPostFieldType.Variable) {
Write("$(");
}
if (type == WmlPostFieldType.Normal) {
if (Browser["requiresUrlEncodedPostfieldValues"] != "false") {
WriteEncodedUrlParameter(value);
}
else {
WriteEncodedText(value);
}
}
else {
Write(value);
}
if (type == WmlPostFieldType.Variable) {
Write(")");
}
Write("\" />");
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
internal void WritePostFieldVariable(String name, String arg) {
WritePostField(name, arg, WmlPostFieldType.Variable);
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public void WriteText(String text, bool encodeText) {
if (encodeText) {
WriteEncodedText(text);
}
else {
WritePlainText(text);
}
}
}
}
#endif