//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//------------------------------------------------------------------------------
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
*/
///
[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;
///
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];
}
}
///
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;
///
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 =
"";
internal override bool ShouldWriteFormID(Form form)
{
if (RequiresLoopDetectionCard)
{
return true;
}
return base.ShouldWriteFormID(form);
}
///
public override void EndForm()
{
if (AnalyzeMode)
{
CheckRawOutput();
CurrentCard.AnchorCount = _currentCardAnchorCount;
base.EndForm();
}
else
{
RenderCardClosing(_currentCardIndex);
base.EndForm();
}
}
///
protected override void RenderEndForm()
{
base.RenderEndForm();
if (_requiresOptionSubmitCard)
{
Write("");
Write("");
RenderGoAction(null, _postBackEventArgumentVarName, WmlPostFieldType.Variable, true);
WriteLine("");
WriteLine("");
WriteLine("");
}
}
///
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
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);
}
}
}
///
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;
}
///
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("