1279 lines
46 KiB
C#
1279 lines
46 KiB
C#
|
//------------------------------------------------------------------------------
|
||
|
// <copyright file="UpWmlMobileTextWriter.cs" company="Microsoft">
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
// </copyright>
|
||
|
//------------------------------------------------------------------------------
|
||
|
|
||
|
using System;
|
||
|
using System.Collections;
|
||
|
using System.Diagnostics;
|
||
|
using System.Globalization;
|
||
|
using System.IO;
|
||
|
using System.Text;
|
||
|
using System.Web.Mobile;
|
||
|
using System.Web.UI.MobileControls;
|
||
|
using System.Security.Permissions;
|
||
|
|
||
|
using SR=System.Web.UI.MobileControls.Adapters.SR;
|
||
|
|
||
|
#if COMPILING_FOR_SHIPPED_SOURCE
|
||
|
using Adapters=System.Web.UI.MobileControls.ShippedAdapterSource;
|
||
|
namespace System.Web.UI.MobileControls.ShippedAdapterSource
|
||
|
#else
|
||
|
using Adapters=System.Web.UI.MobileControls.Adapters;
|
||
|
namespace System.Web.UI.MobileControls.Adapters
|
||
|
#endif
|
||
|
|
||
|
{
|
||
|
/*
|
||
|
* UpWmlMobileTextWriter class.
|
||
|
*
|
||
|
* Copyright (c) 2000 Microsoft Corporation
|
||
|
*/
|
||
|
|
||
|
/// <include file='doc\UpWmlMobileTextWriter.uex' path='docs/doc[@for="UpWmlMobileTextWriter"]/*' />
|
||
|
[AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
|
||
|
[AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)]
|
||
|
[Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")]
|
||
|
public class UpWmlMobileTextWriter : WmlMobileTextWriter
|
||
|
{
|
||
|
private int _screenWidth;
|
||
|
private int _screenHeight;
|
||
|
private bool _inHyperlink = false;
|
||
|
private bool _inPostBack = false;
|
||
|
private bool _inSoftkey = false;
|
||
|
private Alignment _lastAlignment = Alignment.Left;
|
||
|
private Wrapping _lastWrapping = Wrapping.Wrap;
|
||
|
private int _currentCardIndex = -1;
|
||
|
private ArrayList _cards = new ArrayList();
|
||
|
private int _currentCardAnchorCount = 0;
|
||
|
private int _currentCardPostBacks = 0;
|
||
|
private int _currentCardSubmits = 0;
|
||
|
private bool _canRenderMixedSelects = false;
|
||
|
private bool _requiresOptionSubmitCard = false;
|
||
|
private int _optionSubmitCardIndex = 0;
|
||
|
private String _optionMenuName = null;
|
||
|
|
||
|
private String _linkText = null;
|
||
|
private String _targetUrl = null;
|
||
|
private String _softkeyLabel = null;
|
||
|
private bool _encodeUrl = false;
|
||
|
private bool _useMenuOptionTitle = false;
|
||
|
|
||
|
/// <include file='doc\UpWmlMobileTextWriter.uex' path='docs/doc[@for="UpWmlMobileTextWriter.UpWmlMobileTextWriter"]/*' />
|
||
|
public UpWmlMobileTextWriter(TextWriter writer, MobileCapabilities device, MobilePage page)
|
||
|
: base(writer, device, page)
|
||
|
{
|
||
|
_screenWidth = device.ScreenCharactersWidth;
|
||
|
_screenHeight = device.ScreenCharactersHeight;
|
||
|
_canRenderMixedSelects = device.CanRenderMixedSelects;
|
||
|
}
|
||
|
|
||
|
private UpCard CurrentCard
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return (UpCard)_cards[_currentCardIndex];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <include file='doc\UpWmlMobileTextWriter.uex' path='docs/doc[@for="UpWmlMobileTextWriter.BeginForm"]/*' />
|
||
|
public override void BeginForm(Form form)
|
||
|
{
|
||
|
ResetState();
|
||
|
if (AnalyzeMode)
|
||
|
{
|
||
|
AllocateNewCard();
|
||
|
base.BeginForm(form);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (form == form.MobilePage.ActiveForm)
|
||
|
{
|
||
|
PreRenderActiveForm();
|
||
|
}
|
||
|
|
||
|
base.BeginForm(form);
|
||
|
RenderCardOpening(0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static readonly int _filePathSuffixLength =
|
||
|
Constants.UniqueFilePathSuffixVariableWithoutEqual.Length + 1;
|
||
|
private int _sessionCount = -1;
|
||
|
private int SessionCount
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
if (_sessionCount == -1)
|
||
|
{
|
||
|
_sessionCount = 0;
|
||
|
String filePathSuffix =
|
||
|
Page.Request.QueryString[Constants.UniqueFilePathSuffixVariableWithoutEqual];
|
||
|
|
||
|
if (filePathSuffix != null && filePathSuffix.Length == _filePathSuffixLength)
|
||
|
{
|
||
|
Char c = filePathSuffix[_filePathSuffixLength - 1];
|
||
|
if (Char.IsDigit(c))
|
||
|
{
|
||
|
_sessionCount = (int)Char.GetNumericValue(c);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return _sessionCount;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private bool RequiresLoopDetectionCard
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
IDictionary dictionary = Page.Adapter.CookielessDataDictionary;
|
||
|
if((dictionary != null) && (dictionary.Count > 0))
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
return SessionCount == 9;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void PreRenderActiveForm()
|
||
|
{
|
||
|
if (Device.RequiresUniqueFilePathSuffix && RequiresLoopDetectionCard)
|
||
|
{
|
||
|
Debug.Assert(!AnalyzeMode);
|
||
|
Write(String.Format(CultureInfo.InvariantCulture, _loopDetectionCard, Page.ActiveForm.ClientID));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private String _cachedFormQueryString;
|
||
|
/// <include file='doc\UpWmlMobileTextWriter.uex' path='docs/doc[@for="UpWmlMobileTextWriter.CalculateFormQueryString"]/*' />
|
||
|
protected override String CalculateFormQueryString()
|
||
|
{
|
||
|
if(_cachedFormQueryString != null)
|
||
|
{
|
||
|
return _cachedFormQueryString;
|
||
|
}
|
||
|
String queryString = null;
|
||
|
if (CurrentForm.Method != FormMethod.Get)
|
||
|
{
|
||
|
queryString = Page.QueryStringText;
|
||
|
}
|
||
|
|
||
|
if (Device.RequiresUniqueFilePathSuffix)
|
||
|
{
|
||
|
String ufps = Page.UniqueFilePathSuffix;
|
||
|
if(this.HasFormVariables)
|
||
|
{
|
||
|
if (SessionCount == 9)
|
||
|
{
|
||
|
ufps += '0';
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ufps += (SessionCount + 1).ToString(CultureInfo.InvariantCulture);
|
||
|
}
|
||
|
}
|
||
|
if (queryString != null && queryString.Length > 0)
|
||
|
{
|
||
|
queryString = String.Concat(ufps, "&", queryString);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
queryString = ufps;
|
||
|
}
|
||
|
}
|
||
|
_cachedFormQueryString = queryString;
|
||
|
return queryString;
|
||
|
}
|
||
|
|
||
|
private const String _loopDetectionCard =
|
||
|
"<card ontimer=\"#{0}\"><onevent type=\"onenterbackward\"><prev /></onevent><timer value=\"1\" /></card>";
|
||
|
|
||
|
internal override bool ShouldWriteFormID(Form form)
|
||
|
{
|
||
|
if (RequiresLoopDetectionCard)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
return base.ShouldWriteFormID(form);
|
||
|
}
|
||
|
|
||
|
/// <include file='doc\UpWmlMobileTextWriter.uex' path='docs/doc[@for="UpWmlMobileTextWriter.EndForm"]/*' />
|
||
|
public override void EndForm()
|
||
|
{
|
||
|
if (AnalyzeMode)
|
||
|
{
|
||
|
CheckRawOutput();
|
||
|
CurrentCard.AnchorCount = _currentCardAnchorCount;
|
||
|
base.EndForm();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
RenderCardClosing(_currentCardIndex);
|
||
|
base.EndForm();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <include file='doc\UpWmlMobileTextWriter.uex' path='docs/doc[@for="UpWmlMobileTextWriter.RenderEndForm"]/*' />
|
||
|
protected override void RenderEndForm()
|
||
|
{
|
||
|
base.RenderEndForm();
|
||
|
if (_requiresOptionSubmitCard)
|
||
|
{
|
||
|
Write("<card id=\"");
|
||
|
Write(_postBackCardPrefix);
|
||
|
Write("0");
|
||
|
Write(_optionSubmitCardIndex++);
|
||
|
WriteLine("\">");
|
||
|
|
||
|
Write("<onevent type=\"onenterforward\">");
|
||
|
RenderGoAction(null, _postBackEventArgumentVarName, WmlPostFieldType.Variable, true);
|
||
|
WriteLine("</onevent>");
|
||
|
|
||
|
WriteLine("<onevent type=\"onenterbackward\"><prev /></onevent>");
|
||
|
WriteLine("</card>");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <include file='doc\UpWmlMobileTextWriter.uex' path='docs/doc[@for="UpWmlMobileTextWriter.RenderText"]/*' />
|
||
|
public override void RenderText(String text, bool breakAfter, bool encodeText)
|
||
|
{
|
||
|
if (AnalyzeMode)
|
||
|
{
|
||
|
if (CurrentCard.HasInputElements && !Device.CanRenderAfterInputOrSelectElement)
|
||
|
{
|
||
|
BeginNextCard();
|
||
|
}
|
||
|
|
||
|
CheckRawOutput();
|
||
|
if (_inHyperlink || _inPostBack)
|
||
|
{
|
||
|
// When analyzing, accumulate link text for use in figuring
|
||
|
// out softkey.
|
||
|
if (_inSoftkey)
|
||
|
{
|
||
|
_linkText += text;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Text cannot come after a menu.
|
||
|
if (CurrentCard.RenderAsMenu)
|
||
|
{
|
||
|
CurrentCard.RenderAsMenu = false;
|
||
|
CurrentCard.MenuCandidate = false;
|
||
|
}
|
||
|
else if (CurrentCard.MenuCandidate)
|
||
|
{
|
||
|
// Calculate weight of static items before a menu.
|
||
|
// This is used to check for screens that scroll past their
|
||
|
// initial content.
|
||
|
|
||
|
int weight = text != null ? text.Length : 0;
|
||
|
if (breakAfter)
|
||
|
{
|
||
|
weight = ((weight - 1) / _screenWidth + 1) * _screenWidth;
|
||
|
}
|
||
|
CurrentCard.StaticItemsWeight += weight;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bool willRenderText = false;
|
||
|
if (_inHyperlink || _inPostBack)
|
||
|
{
|
||
|
// If rendering in menu, simply accumulate text.
|
||
|
if (CurrentCard.RenderAsMenu)
|
||
|
{
|
||
|
_linkText += text;
|
||
|
}
|
||
|
else if (!CurrentCard.UsesDefaultSubmit)
|
||
|
{
|
||
|
willRenderText = true;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
willRenderText = true;
|
||
|
}
|
||
|
|
||
|
if (willRenderText)
|
||
|
{
|
||
|
// Some browsers that
|
||
|
// RendersBreakBeforeWmlSelectAndInput have the odd behavior
|
||
|
// of *not* rendering a break if there is nothing on the
|
||
|
// card before it, and entering an explicit <br> creates two
|
||
|
// breaks. Therefore, we just render a in this
|
||
|
// situation.
|
||
|
|
||
|
if (!CurrentCard.RenderedTextElementYet &&
|
||
|
Device.RendersBreakBeforeWmlSelectAndInput &&
|
||
|
!((WmlPageAdapter)Page.Adapter).IsKDDIPhone())
|
||
|
{
|
||
|
CurrentCard.RenderedTextElementYet = true;
|
||
|
if (breakAfter && (text != null && text.Length == 0))
|
||
|
{
|
||
|
base.RenderText(" ", false, false);
|
||
|
}
|
||
|
}
|
||
|
base.RenderText(text, breakAfter, encodeText);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <include file='doc\UpWmlMobileTextWriter.uex' path='docs/doc[@for="UpWmlMobileTextWriter.RenderBeginHyperlink"]/*' />
|
||
|
public override void RenderBeginHyperlink(String targetUrl,
|
||
|
bool encodeUrl,
|
||
|
String softkeyLabel,
|
||
|
bool implicitSoftkeyLabel,
|
||
|
bool mapToSoftkey)
|
||
|
{
|
||
|
if (_inHyperlink || _inPostBack)
|
||
|
{
|
||
|
throw new Exception();
|
||
|
}
|
||
|
|
||
|
// AUI 4137
|
||
|
if (targetUrl != null && targetUrl.Length > 0 && targetUrl[0] != '#')
|
||
|
{
|
||
|
targetUrl = Page.MakePathAbsolute(targetUrl);
|
||
|
}
|
||
|
|
||
|
if (AnalyzeMode)
|
||
|
{
|
||
|
if (CurrentCard.HasInputElements && !Device.CanRenderAfterInputOrSelectElement)
|
||
|
{
|
||
|
BeginNextCard();
|
||
|
}
|
||
|
|
||
|
CheckRawOutput();
|
||
|
|
||
|
// Try to map to softkey if possible.
|
||
|
if (mapToSoftkey && CurrentCard.SoftkeysUsed < NumberOfSoftkeys)
|
||
|
{
|
||
|
_inSoftkey = true;
|
||
|
_targetUrl = targetUrl;
|
||
|
_softkeyLabel = softkeyLabel;
|
||
|
_encodeUrl = encodeUrl;
|
||
|
_linkText = String.Empty;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (CurrentCard.RenderAsMenu)
|
||
|
{
|
||
|
if (!CurrentCard.MenuOpened)
|
||
|
{
|
||
|
OpenMenu();
|
||
|
}
|
||
|
|
||
|
// In menu mode, actual rendering is done on RenderEndHyperlink,
|
||
|
// when we have all available info.
|
||
|
|
||
|
_targetUrl = targetUrl;
|
||
|
_softkeyLabel = softkeyLabel;
|
||
|
_useMenuOptionTitle = mapToSoftkey && !implicitSoftkeyLabel;
|
||
|
_encodeUrl = encodeUrl;
|
||
|
_linkText = String.Empty;
|
||
|
}
|
||
|
else if (!CurrentCard.UsesDefaultSubmit)
|
||
|
{
|
||
|
base.RenderBeginHyperlink(targetUrl,
|
||
|
encodeUrl,
|
||
|
softkeyLabel,
|
||
|
implicitSoftkeyLabel,
|
||
|
mapToSoftkey);
|
||
|
}
|
||
|
}
|
||
|
_inHyperlink = true;
|
||
|
}
|
||
|
|
||
|
/// <include file='doc\UpWmlMobileTextWriter.uex' path='docs/doc[@for="UpWmlMobileTextWriter.RenderEndHyperlink"]/*' />
|
||
|
public override void RenderEndHyperlink(bool breakAfter)
|
||
|
{
|
||
|
if (!_inHyperlink)
|
||
|
{
|
||
|
throw new Exception();
|
||
|
}
|
||
|
|
||
|
_inHyperlink = false;
|
||
|
if (AnalyzeMode)
|
||
|
{
|
||
|
CheckRawOutput();
|
||
|
if (CurrentCard.MenuCandidate)
|
||
|
{
|
||
|
CurrentCard.RenderAsMenu = true;
|
||
|
}
|
||
|
CurrentCard.HasNonStaticElements = true;
|
||
|
|
||
|
if (_inSoftkey)
|
||
|
{
|
||
|
// Add a softkey if possible.
|
||
|
|
||
|
_inSoftkey = false;
|
||
|
UpHyperlinkSoftkey softkey = new UpHyperlinkSoftkey();
|
||
|
softkey.TargetUrl = _targetUrl;
|
||
|
softkey.EncodeUrl = _encodeUrl;
|
||
|
if (_softkeyLabel == null || _softkeyLabel.Length == 0)
|
||
|
{
|
||
|
_softkeyLabel = _linkText;
|
||
|
}
|
||
|
softkey.Label = _softkeyLabel;
|
||
|
CurrentCard.Softkeys[CurrentCard.SoftkeysUsed++] = softkey;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (CurrentCard.RenderAsMenu)
|
||
|
{
|
||
|
Write("<option onpick=\"");
|
||
|
if (_targetUrl.StartsWith(Constants.FormIDPrefix, StringComparison.Ordinal))
|
||
|
{
|
||
|
// no encoding needed if pointing to another form id
|
||
|
Write(_targetUrl);
|
||
|
}
|
||
|
else if (!_encodeUrl)
|
||
|
{
|
||
|
Write(EscapeAmpersand(_targetUrl));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
WriteEncodedUrl(_targetUrl);
|
||
|
}
|
||
|
Write("\"");
|
||
|
|
||
|
if (_useMenuOptionTitle && IsValidSoftkeyLabel(_softkeyLabel))
|
||
|
{
|
||
|
WriteTextEncodedAttribute("title", _softkeyLabel);
|
||
|
}
|
||
|
|
||
|
Write(">");
|
||
|
WriteEncodedText(_linkText);
|
||
|
WriteEndTag("option");
|
||
|
}
|
||
|
else if (!CurrentCard.UsesDefaultSubmit)
|
||
|
{
|
||
|
base.RenderEndHyperlink(breakAfter);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
_currentCardAnchorCount++;
|
||
|
|
||
|
if (!AnalyzeMode &&
|
||
|
_currentCardAnchorCount == CurrentCard.AnchorCount &&
|
||
|
_currentCardIndex < _cards.Count - 1)
|
||
|
{
|
||
|
BeginNextCard();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <include file='doc\UpWmlMobileTextWriter.uex' path='docs/doc[@for="UpWmlMobileTextWriter.RenderTextBox"]/*' />
|
||
|
public override void RenderTextBox(String id,
|
||
|
String value,
|
||
|
String format,
|
||
|
String title,
|
||
|
bool password,
|
||
|
int size,
|
||
|
int maxLength,
|
||
|
bool generateRandomID,
|
||
|
bool breakAfter)
|
||
|
{
|
||
|
if (AnalyzeMode)
|
||
|
{
|
||
|
CheckRawOutput();
|
||
|
|
||
|
// If an anchor precedes this control, then break to the
|
||
|
// next card.
|
||
|
if (_currentCardAnchorCount > 0)
|
||
|
{
|
||
|
BeginNextCard();
|
||
|
}
|
||
|
else if (CurrentCard.HasInputElements &&
|
||
|
(!Device.CanRenderInputAndSelectElementsTogether ||
|
||
|
!Device.CanRenderAfterInputOrSelectElement))
|
||
|
{
|
||
|
BeginNextCard();
|
||
|
}
|
||
|
|
||
|
CurrentCard.RenderAsMenu = false;
|
||
|
CurrentCard.MenuCandidate = false;
|
||
|
CurrentCard.HasNonStaticElements = true;
|
||
|
CurrentCard.HasInputElements = true;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Don't write breaks after textboxes on UP.
|
||
|
base.RenderTextBox(id, value, format, title, password, size, maxLength, generateRandomID, false);
|
||
|
|
||
|
// If we can't render more than one input element on this card, and
|
||
|
// there are no anchors left to render, break here.
|
||
|
|
||
|
if (!Device.CanRenderAfterInputOrSelectElement && _currentCardIndex < _cards.Count - 1)
|
||
|
{
|
||
|
CurrentCard.NoOKLink = true;
|
||
|
BeginNextCard();
|
||
|
}
|
||
|
else if (CurrentCard.AnchorCount == 0 && _currentCardIndex < _cards.Count - 1 &&
|
||
|
!Device.CanRenderInputAndSelectElementsTogether)
|
||
|
{
|
||
|
CurrentCard.NoOKLink = true;
|
||
|
BeginNextCard();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <include file='doc\UpWmlMobileTextWriter.uex' path='docs/doc[@for="UpWmlMobileTextWriter.RenderImage"]/*' />
|
||
|
public override void RenderImage(String source,
|
||
|
String localSource,
|
||
|
String alternateText,
|
||
|
bool breakAfter)
|
||
|
{
|
||
|
if (AnalyzeMode)
|
||
|
{
|
||
|
if (CurrentCard.HasInputElements && !Device.CanRenderAfterInputOrSelectElement)
|
||
|
{
|
||
|
BeginNextCard();
|
||
|
}
|
||
|
|
||
|
CheckRawOutput();
|
||
|
|
||
|
if (_inHyperlink || _inPostBack)
|
||
|
{
|
||
|
CurrentCard.RenderAsMenu = false;
|
||
|
CurrentCard.MenuCandidate = false;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (CurrentCard.RenderAsMenu)
|
||
|
{
|
||
|
// Images cannot come after a menu on a card.
|
||
|
CurrentCard.RenderAsMenu = false;
|
||
|
CurrentCard.MenuCandidate = false;
|
||
|
}
|
||
|
else if (CurrentCard.MenuCandidate)
|
||
|
{
|
||
|
CurrentCard.StaticItemsWeight += _screenWidth;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// AUI 4137
|
||
|
if (source != null)
|
||
|
{
|
||
|
source = Page.MakePathAbsolute(source);
|
||
|
}
|
||
|
|
||
|
if (_inHyperlink || _inPostBack)
|
||
|
{
|
||
|
if (CurrentCard.RenderAsMenu)
|
||
|
{
|
||
|
_linkText += alternateText;
|
||
|
}
|
||
|
else if (!CurrentCard.UsesDefaultSubmit)
|
||
|
{
|
||
|
base.RenderImage(source, localSource, alternateText, breakAfter);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
base.RenderImage(source, localSource, alternateText, breakAfter);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <include file='doc\UpWmlMobileTextWriter.uex' path='docs/doc[@for="UpWmlMobileTextWriter.RenderBeginPostBack"]/*' />
|
||
|
public override void RenderBeginPostBack(String softkeyLabel,
|
||
|
bool implicitSoftkeyLabel,
|
||
|
bool mapToSoftkey)
|
||
|
{
|
||
|
if (_inHyperlink || _inPostBack)
|
||
|
{
|
||
|
throw new Exception();
|
||
|
}
|
||
|
|
||
|
if (AnalyzeMode)
|
||
|
{
|
||
|
if (CurrentCard.HasInputElements && !Device.CanRenderAfterInputOrSelectElement)
|
||
|
{
|
||
|
BeginNextCard();
|
||
|
}
|
||
|
|
||
|
CheckRawOutput();
|
||
|
|
||
|
// Try to map to softkey if possible.
|
||
|
if (mapToSoftkey && CurrentCard.SoftkeysUsed < NumberOfSoftkeys)
|
||
|
{
|
||
|
_inSoftkey = true;
|
||
|
_softkeyLabel = softkeyLabel;
|
||
|
_linkText = String.Empty;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (CurrentCard.RenderAsMenu)
|
||
|
{
|
||
|
if (!CurrentCard.MenuOpened)
|
||
|
{
|
||
|
OpenMenu();
|
||
|
}
|
||
|
|
||
|
// In menu mode, actual rendering is done on RenderEndPostBack,
|
||
|
// when we have all available info.
|
||
|
_softkeyLabel = softkeyLabel;
|
||
|
_useMenuOptionTitle = mapToSoftkey && !implicitSoftkeyLabel;
|
||
|
_linkText = String.Empty;
|
||
|
}
|
||
|
else if (!CurrentCard.UsesDefaultSubmit)
|
||
|
{
|
||
|
base.RenderBeginPostBack(softkeyLabel, implicitSoftkeyLabel, mapToSoftkey);
|
||
|
}
|
||
|
}
|
||
|
_inPostBack = true;
|
||
|
}
|
||
|
|
||
|
/// <include file='doc\UpWmlMobileTextWriter.uex' path='docs/doc[@for="UpWmlMobileTextWriter.RenderEndPostBack"]/*' />
|
||
|
public override void RenderEndPostBack(String target, String argument, WmlPostFieldType postBackType, bool includeVariables, bool breakAfter)
|
||
|
{
|
||
|
if (!_inPostBack)
|
||
|
{
|
||
|
throw new Exception();
|
||
|
}
|
||
|
|
||
|
_inPostBack = false;
|
||
|
if (AnalyzeMode)
|
||
|
{
|
||
|
CheckRawOutput();
|
||
|
|
||
|
if (CurrentCard.MenuCandidate)
|
||
|
{
|
||
|
// If all postback menu items go to one target, we can write the do
|
||
|
// to hit that target. Otherwise, we must post back to the form.
|
||
|
|
||
|
if (CurrentCard.RenderAsMenu)
|
||
|
{
|
||
|
if (CurrentCard.MenuTarget != target)
|
||
|
{
|
||
|
CurrentCard.MenuTarget = null;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
CurrentCard.MenuTarget = target;
|
||
|
CurrentCard.RenderAsMenu = true;
|
||
|
}
|
||
|
}
|
||
|
CurrentCard.HasNonStaticElements = true;
|
||
|
|
||
|
if (_inSoftkey)
|
||
|
{
|
||
|
// Map to softkey.
|
||
|
_inSoftkey = false;
|
||
|
UpPostBackSoftkey softkey = new UpPostBackSoftkey();
|
||
|
softkey.Target = target;
|
||
|
softkey.Argument = argument;
|
||
|
softkey.PostBackType = postBackType;
|
||
|
softkey.IncludeVariables = includeVariables;
|
||
|
if (_softkeyLabel == null || _softkeyLabel.Length == 0)
|
||
|
{
|
||
|
_softkeyLabel = _linkText;
|
||
|
}
|
||
|
softkey.Label = _softkeyLabel;
|
||
|
CurrentCard.Softkeys[CurrentCard.SoftkeysUsed++] = softkey;
|
||
|
}
|
||
|
AnalyzePostBack(includeVariables, postBackType);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (CurrentCard.RenderAsMenu)
|
||
|
{
|
||
|
// Render as a menu item.
|
||
|
|
||
|
WriteBeginTag("option");
|
||
|
if (!_canRenderMixedSelects)
|
||
|
{
|
||
|
if (_useMenuOptionTitle && IsValidSoftkeyLabel(_softkeyLabel))
|
||
|
{
|
||
|
WriteTextEncodedAttribute("title", _softkeyLabel);
|
||
|
}
|
||
|
|
||
|
_requiresOptionSubmitCard = true;
|
||
|
Write("><onevent type=\"onpick\"><go href=\"#");
|
||
|
Write(_postBackCardPrefix);
|
||
|
Write("0");
|
||
|
Write(_optionSubmitCardIndex);
|
||
|
Write("\">");
|
||
|
Write("<setvar name=\"");
|
||
|
Write(_postBackEventTargetVarName);
|
||
|
Write("\" value=\"");
|
||
|
if (_optionMenuName != null)
|
||
|
{
|
||
|
Write(_optionMenuName);
|
||
|
}
|
||
|
Write("\" />");
|
||
|
Write("<setvar name=\"");
|
||
|
Write(_postBackEventArgumentVarName);
|
||
|
Write("\" value=\"");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Write(" value=\"");
|
||
|
}
|
||
|
|
||
|
if (CurrentCard.MenuTarget != null)
|
||
|
{
|
||
|
if (argument != null)
|
||
|
{
|
||
|
WriteEncodedText(argument);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
WriteEncodedText(target);
|
||
|
if (argument != null)
|
||
|
{
|
||
|
Write(",");
|
||
|
WriteEncodedText(argument);
|
||
|
}
|
||
|
}
|
||
|
if (!_canRenderMixedSelects)
|
||
|
{
|
||
|
Write("\" /></go></onevent>");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Write("\"");
|
||
|
if (_useMenuOptionTitle && IsValidSoftkeyLabel(_softkeyLabel))
|
||
|
{
|
||
|
WriteTextEncodedAttribute("title", _softkeyLabel);
|
||
|
}
|
||
|
Write(">");
|
||
|
}
|
||
|
|
||
|
WriteEncodedText(_linkText);
|
||
|
WriteEndTag("option");
|
||
|
}
|
||
|
else if (!CurrentCard.UsesDefaultSubmit)
|
||
|
{
|
||
|
base.RenderEndPostBack(target, argument, postBackType,
|
||
|
includeVariables, breakAfter);
|
||
|
}
|
||
|
}
|
||
|
_currentCardAnchorCount++;
|
||
|
|
||
|
if (!AnalyzeMode &&
|
||
|
_currentCardAnchorCount == CurrentCard.AnchorCount &&
|
||
|
_currentCardIndex < _cards.Count - 1)
|
||
|
{
|
||
|
BeginNextCard();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <include file='doc\UpWmlMobileTextWriter.uex' path='docs/doc[@for="UpWmlMobileTextWriter.BeginCustomMarkup"]/*' />
|
||
|
public override void BeginCustomMarkup()
|
||
|
{
|
||
|
if (!AnalyzeMode && !CurrentCard.MenuOpened)
|
||
|
{
|
||
|
EnsureLayout();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/// <include file='doc\UpWmlMobileTextWriter.uex' path='docs/doc[@for="UpWmlMobileTextWriter.AnalyzePostBack"]/*' />
|
||
|
protected override void AnalyzePostBack(bool includeVariables, WmlPostFieldType postBackType)
|
||
|
{
|
||
|
base.AnalyzePostBack(includeVariables, postBackType);
|
||
|
if (CurrentForm.Action.Length > 0)
|
||
|
{
|
||
|
if (postBackType == WmlPostFieldType.Submit)
|
||
|
{
|
||
|
_currentCardSubmits++;
|
||
|
CurrentCard.ExternalSubmitMenu = true;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
_currentCardPostBacks++;
|
||
|
}
|
||
|
if (_currentCardPostBacks > 0 && _currentCardSubmits > 0)
|
||
|
{
|
||
|
// Posts to more than one target, so we can't use a menu card.
|
||
|
|
||
|
CurrentCard.RenderAsMenu = false;
|
||
|
CurrentCard.MenuCandidate = false;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <include file='doc\UpWmlMobileTextWriter.uex' path='docs/doc[@for="UpWmlMobileTextWriter.RenderBeginSelect"]/*' />
|
||
|
public override void RenderBeginSelect(String name, String iname, String ivalue, String title, bool multiSelect)
|
||
|
{
|
||
|
if (AnalyzeMode)
|
||
|
{
|
||
|
CheckRawOutput();
|
||
|
if (_currentCardAnchorCount > 0)
|
||
|
{
|
||
|
// If an anchor precedes this control, then break to the
|
||
|
// next card.
|
||
|
BeginNextCard();
|
||
|
}
|
||
|
else if (CurrentCard.HasInputElements &&
|
||
|
(!Device.CanRenderInputAndSelectElementsTogether ||
|
||
|
!Device.CanRenderAfterInputOrSelectElement))
|
||
|
{
|
||
|
BeginNextCard();
|
||
|
}
|
||
|
|
||
|
CurrentCard.RenderAsMenu = false;
|
||
|
CurrentCard.MenuCandidate = false;
|
||
|
CurrentCard.HasNonStaticElements = true;
|
||
|
CurrentCard.HasInputElements = true;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
base.RenderBeginSelect(name, iname, ivalue, title, multiSelect);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <include file='doc\UpWmlMobileTextWriter.uex' path='docs/doc[@for="UpWmlMobileTextWriter.RenderEndSelect"]/*' />
|
||
|
public override void RenderEndSelect(bool breakAfter)
|
||
|
{
|
||
|
if (AnalyzeMode)
|
||
|
{
|
||
|
CheckRawOutput();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Don't write breaks after selects on UP.
|
||
|
base.RenderEndSelect(false);
|
||
|
|
||
|
// If we can't render more than one input element on this card, and
|
||
|
// there are no anchors left to render, break here.
|
||
|
|
||
|
if (!Device.CanRenderAfterInputOrSelectElement && _currentCardIndex < _cards.Count - 1)
|
||
|
{
|
||
|
CurrentCard.NoOKLink = true;
|
||
|
BeginNextCard();
|
||
|
}
|
||
|
else if (CurrentCard.AnchorCount == 0 && _currentCardIndex < _cards.Count - 1 &&
|
||
|
!Device.CanRenderInputAndSelectElementsTogether)
|
||
|
{
|
||
|
CurrentCard.NoOKLink = true;
|
||
|
BeginNextCard();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <include file='doc\UpWmlMobileTextWriter.uex' path='docs/doc[@for="UpWmlMobileTextWriter.RenderSelectOption"]/*' />
|
||
|
public override void RenderSelectOption(String text)
|
||
|
{
|
||
|
if (AnalyzeMode)
|
||
|
{
|
||
|
CheckRawOutput();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
base.RenderSelectOption(text);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <include file='doc\UpWmlMobileTextWriter.uex' path='docs/doc[@for="UpWmlMobileTextWriter.RenderSelectOption1"]/*' />
|
||
|
public override void RenderSelectOption(String text, String value)
|
||
|
{
|
||
|
if (AnalyzeMode)
|
||
|
{
|
||
|
CheckRawOutput();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
base.RenderSelectOption(text, value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void OpenMenu()
|
||
|
{
|
||
|
// Close any character formatting tags before starting a <do>.
|
||
|
CloseCharacterFormat();
|
||
|
|
||
|
String menuTarget;
|
||
|
String menuTargetClientID;
|
||
|
WmlPostFieldType postFieldType;
|
||
|
|
||
|
if (CurrentCard.ExternalSubmitMenu)
|
||
|
{
|
||
|
menuTarget = null;
|
||
|
menuTargetClientID = null;
|
||
|
postFieldType = WmlPostFieldType.Submit;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (CurrentCard.MenuTarget != null)
|
||
|
{
|
||
|
menuTarget = CurrentCard.MenuTarget;
|
||
|
if (menuTarget.IndexOf(":", StringComparison.Ordinal) >= 0)
|
||
|
{
|
||
|
menuTargetClientID = menuTarget.Replace(":", "_");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
menuTargetClientID = menuTarget;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
menuTarget = CurrentForm.UniqueID;
|
||
|
menuTargetClientID = CurrentForm.ClientID;
|
||
|
}
|
||
|
|
||
|
postFieldType = WmlPostFieldType.Variable;
|
||
|
}
|
||
|
|
||
|
if (!_canRenderMixedSelects)
|
||
|
{
|
||
|
_optionMenuName = menuTarget;
|
||
|
menuTargetClientID = null;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
String GoLabel = SR.GetString(SR.WmlMobileTextWriterGoLabel);
|
||
|
RenderDoEvent("accept",
|
||
|
menuTarget,
|
||
|
menuTargetClientID != null ? MapClientIDToShortName(menuTargetClientID, false) : null,
|
||
|
postFieldType,
|
||
|
GoLabel,
|
||
|
true);
|
||
|
}
|
||
|
|
||
|
base.RenderBeginSelect(menuTargetClientID, null, null, null, false);
|
||
|
|
||
|
CurrentCard.MenuOpened = true;
|
||
|
}
|
||
|
|
||
|
private void CloseMenu()
|
||
|
{
|
||
|
base.RenderEndSelect(false);
|
||
|
CurrentCard.MenuOpened = false;
|
||
|
}
|
||
|
|
||
|
// Overriden to convert relative file paths to absolute file paths,
|
||
|
// due to a redirection issue on UP phones.
|
||
|
|
||
|
/// <include file='doc\UpWmlMobileTextWriter.uex' path='docs/doc[@for="UpWmlMobileTextWriter.CalculateFormPostBackUrl"]/*' />
|
||
|
protected override String CalculateFormPostBackUrl(bool externalSubmit, ref bool encode)
|
||
|
{
|
||
|
String url = CurrentForm.Action;
|
||
|
if (externalSubmit && url.Length > 0)
|
||
|
{
|
||
|
// Not only do we need to resolve the URL, but we need to make it absolute.
|
||
|
url = Page.MakePathAbsolute(CurrentForm.ResolveUrl(url));
|
||
|
encode = false;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
url = Page.AbsoluteFilePath;
|
||
|
encode = true;
|
||
|
}
|
||
|
return url;
|
||
|
}
|
||
|
|
||
|
// Captures raw output written to the writers during analyze mode.
|
||
|
|
||
|
private void CheckRawOutput()
|
||
|
{
|
||
|
Debug.Assert(AnalyzeMode);
|
||
|
|
||
|
EmptyTextWriter innerWriter = (EmptyTextWriter)InnerWriter;
|
||
|
if (innerWriter.NonWhiteSpaceWritten)
|
||
|
{
|
||
|
CurrentCard.RenderAsMenu = false;
|
||
|
CurrentCard.MenuCandidate = false;
|
||
|
}
|
||
|
innerWriter.Reset();
|
||
|
}
|
||
|
|
||
|
// Overriden to always write the "align" or "wrap" attributes when
|
||
|
// they are changing, even if they are set to defaults.
|
||
|
|
||
|
/// <include file='doc\UpWmlMobileTextWriter.uex' path='docs/doc[@for="UpWmlMobileTextWriter.OpenParagraph"]/*' />
|
||
|
protected override void OpenParagraph(WmlLayout layout, bool writeAlignment, bool writeWrapping)
|
||
|
{
|
||
|
base.OpenParagraph(layout,
|
||
|
writeAlignment || layout.Align != _lastAlignment,
|
||
|
writeWrapping || layout.Wrap != _lastWrapping);
|
||
|
_lastAlignment = layout.Align;
|
||
|
_lastWrapping = layout.Wrap;
|
||
|
}
|
||
|
|
||
|
// Resets writer state between forms.
|
||
|
|
||
|
private void ResetState()
|
||
|
{
|
||
|
if (AnalyzeMode)
|
||
|
{
|
||
|
_currentCardPostBacks = 0;
|
||
|
_currentCardSubmits = 0;
|
||
|
_inHyperlink = false;
|
||
|
_inPostBack = false;
|
||
|
_inSoftkey = false;
|
||
|
if (_cards.Count > 0)
|
||
|
{
|
||
|
_cards.Clear();
|
||
|
}
|
||
|
}
|
||
|
_currentCardAnchorCount = 0;
|
||
|
_currentCardIndex = 0;
|
||
|
_currentCardPostBacks = 0;
|
||
|
_currentCardSubmits = 0;
|
||
|
_requiresOptionSubmitCard = false;
|
||
|
}
|
||
|
|
||
|
private UpCard AllocateNewCard()
|
||
|
{
|
||
|
UpCard card = new UpCard();
|
||
|
card.Softkeys = new UpSoftkey[NumberOfSoftkeys];
|
||
|
_cards.Add(card);
|
||
|
return card;
|
||
|
}
|
||
|
|
||
|
// Analyze an individual card.
|
||
|
|
||
|
private void PostAnalyzeCard(int cardIndex)
|
||
|
{
|
||
|
UpCard card = (UpCard)_cards[cardIndex];
|
||
|
if (card.RenderAsMenu)
|
||
|
{
|
||
|
// If the card is the last card, and has only
|
||
|
// one anchor that can be mapped to a softkey,
|
||
|
// ignore the
|
||
|
|
||
|
if (card.AnchorCount == 1 && cardIndex == _cards.Count - 1 && card.SoftkeysUsed == 1)
|
||
|
{
|
||
|
card.RenderAsMenu = false;
|
||
|
}
|
||
|
|
||
|
// If the card has a lot of static content followed by
|
||
|
// a number of links, don't render it as a menu card,
|
||
|
// because the card would scroll off the static content
|
||
|
// to get to the menu.
|
||
|
|
||
|
else if (card.StaticItemsWeight >= 3 * _screenWidth)
|
||
|
{
|
||
|
card.RenderAsMenu = false;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <include file='doc\UpWmlMobileTextWriter.uex' path='docs/doc[@for="UpWmlMobileTextWriter.PostAnalyzeForm"]/*' />
|
||
|
protected override void PostAnalyzeForm()
|
||
|
{
|
||
|
base.PostAnalyzeForm();
|
||
|
|
||
|
for(int i = 0; i < _cards.Count; i++)
|
||
|
{
|
||
|
PostAnalyzeCard(i);
|
||
|
}
|
||
|
|
||
|
// If the last card ends with an input element and an anchor
|
||
|
// then use the anchor as a do tag to submit the form, and
|
||
|
// don't render as a separate anchor (otherwise, the user would
|
||
|
// see an extra screen at the end with a single anchor)
|
||
|
UpCard lastCard = CurrentCard;
|
||
|
if (lastCard.HasInputElements && _currentCardAnchorCount >= 1 &&
|
||
|
_currentCardAnchorCount <= Device.DefaultSubmitButtonLimit)
|
||
|
{
|
||
|
lastCard.UsesDefaultSubmit = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void RenderCardOpening(int cardIndex)
|
||
|
{
|
||
|
UpCard card = (UpCard)_cards[cardIndex];
|
||
|
if (card.RenderAsMenu)
|
||
|
{
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Render softkeys
|
||
|
if (card.HasNonStaticElements)
|
||
|
{
|
||
|
for (int i = 0; i < card.SoftkeysUsed; i++)
|
||
|
{
|
||
|
RenderSoftkey(i == 0 ? "accept" : "options", card.Softkeys[i]);
|
||
|
}
|
||
|
}
|
||
|
else if (cardIndex == _cards.Count - 1)
|
||
|
{
|
||
|
// Render the last card with an extra <do>, so that
|
||
|
// it overrides the default function of the OK button,
|
||
|
// which is to go back a screen.
|
||
|
//EnsureLayout();
|
||
|
Write("<do type=\"accept\"><noop /></do>");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void RenderCardClosing(int cardIndex)
|
||
|
{
|
||
|
UpCard card = (UpCard)_cards[cardIndex];
|
||
|
|
||
|
if (cardIndex < _cards.Count - 1 && !card.NoOKLink)
|
||
|
{
|
||
|
// Add a link to go to the next card.
|
||
|
|
||
|
UpCard nextCard = (UpCard)_cards[cardIndex + 1];
|
||
|
String OkLabel = SR.GetString(SR.WmlMobileTextWriterOKLabel);
|
||
|
RenderBeginHyperlink("#" + nextCard.Id, false, OkLabel, true, true);
|
||
|
RenderText(OkLabel);
|
||
|
RenderEndHyperlink(true);
|
||
|
}
|
||
|
|
||
|
if (card.RenderAsMenu)
|
||
|
{
|
||
|
CloseMenu();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void BeginNextCard()
|
||
|
{
|
||
|
if (AnalyzeMode)
|
||
|
{
|
||
|
// Add a softkey on the current card, to go to the new card.
|
||
|
|
||
|
String nextCardId = "card" + (_currentCardIndex + 1).ToString(CultureInfo.InvariantCulture);
|
||
|
|
||
|
UpHyperlinkSoftkey softkey = new UpHyperlinkSoftkey();
|
||
|
softkey.TargetUrl = "#" + nextCardId;
|
||
|
softkey.EncodeUrl = false;
|
||
|
softkey.Label = "OK";
|
||
|
SetPrimarySoftkey(softkey);
|
||
|
|
||
|
CurrentCard.AnchorCount = _currentCardAnchorCount;
|
||
|
|
||
|
UpCard card = AllocateNewCard();
|
||
|
card.Id = nextCardId;
|
||
|
_currentCardIndex++;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
RenderCardClosing(_currentCardIndex);
|
||
|
CloseParagraph();
|
||
|
WriteEndTag("card");
|
||
|
WriteLine();
|
||
|
|
||
|
_currentCardIndex++;
|
||
|
_lastAlignment = Alignment.Left;
|
||
|
_lastWrapping = Wrapping.NoWrap;
|
||
|
|
||
|
WriteBeginTag("card");
|
||
|
WriteAttribute("id", CurrentCard.Id);
|
||
|
String formTitle = CurrentForm.Title;
|
||
|
if (formTitle != null && formTitle.Length > 0)
|
||
|
{
|
||
|
WriteTextEncodedAttribute("title", formTitle);
|
||
|
}
|
||
|
WriteLine(">");
|
||
|
RenderCardOpening(_currentCardIndex);
|
||
|
}
|
||
|
|
||
|
_currentCardAnchorCount = 0;
|
||
|
_currentCardPostBacks = 0;
|
||
|
_currentCardSubmits = 0;
|
||
|
}
|
||
|
|
||
|
private void SetPrimarySoftkey(UpSoftkey softkey)
|
||
|
{
|
||
|
for (int i = NumberOfSoftkeys - 1; i > 0; i--)
|
||
|
{
|
||
|
CurrentCard.Softkeys[i] = CurrentCard.Softkeys[i - 1];
|
||
|
}
|
||
|
CurrentCard.Softkeys[0] = softkey;
|
||
|
if (CurrentCard.SoftkeysUsed < NumberOfSoftkeys)
|
||
|
{
|
||
|
CurrentCard.SoftkeysUsed++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void RenderSoftkey(String doType, UpSoftkey softkey)
|
||
|
{
|
||
|
UpHyperlinkSoftkey linkSoftkey = softkey as UpHyperlinkSoftkey;
|
||
|
if (linkSoftkey != null)
|
||
|
{
|
||
|
WriteBeginTag("do");
|
||
|
WriteAttribute("type", doType);
|
||
|
WriteTextEncodedAttribute("label", linkSoftkey.Label);
|
||
|
Write(">");
|
||
|
WriteBeginTag("go");
|
||
|
Write(" href=\"");
|
||
|
|
||
|
if (linkSoftkey.EncodeUrl)
|
||
|
{
|
||
|
WriteEncodedUrl(linkSoftkey.TargetUrl);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Write(EscapeAmpersand(linkSoftkey.TargetUrl));
|
||
|
}
|
||
|
Write("\" />");
|
||
|
WriteEndTag("do");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
UpPostBackSoftkey postBackSoftkey = softkey as UpPostBackSoftkey;
|
||
|
if (postBackSoftkey != null)
|
||
|
{
|
||
|
RenderDoEvent(doType,
|
||
|
postBackSoftkey.Target,
|
||
|
postBackSoftkey.Argument,
|
||
|
postBackSoftkey.PostBackType,
|
||
|
postBackSoftkey.Label,
|
||
|
postBackSoftkey.IncludeVariables);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private class UpSoftkey
|
||
|
{
|
||
|
public String Label;
|
||
|
}
|
||
|
|
||
|
private class UpHyperlinkSoftkey : UpSoftkey
|
||
|
{
|
||
|
public String TargetUrl;
|
||
|
public bool EncodeUrl;
|
||
|
}
|
||
|
|
||
|
private class UpPostBackSoftkey : UpSoftkey
|
||
|
{
|
||
|
public String Target;
|
||
|
public String Argument;
|
||
|
public WmlPostFieldType PostBackType;
|
||
|
public bool IncludeVariables;
|
||
|
}
|
||
|
|
||
|
private class UpCard
|
||
|
{
|
||
|
public String Id;
|
||
|
public bool MenuCandidate = true;
|
||
|
public bool RenderAsMenu = false;
|
||
|
public int StaticItemsWeight = 0;
|
||
|
public bool HasNonStaticElements = false;
|
||
|
public bool MenuOpened = false;
|
||
|
public bool HasInputElements = false;
|
||
|
public bool UsesDefaultSubmit = false;
|
||
|
public int SoftkeysUsed = 0;
|
||
|
public UpSoftkey[] Softkeys = null;
|
||
|
public int AnchorCount = 0;
|
||
|
public String MenuTarget = null;
|
||
|
public bool ExternalSubmitMenu = false;
|
||
|
public bool NoOKLink = false;
|
||
|
public bool RenderedTextElementYet = false;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|