//
// System.Web.UI.CssStyleCollection.cs
//
// Authors:
// Duncan Mak (duncan@ximian.com)
// Gonzalo Paniagua (gonzalo@ximian.com)
//
// (C) 2002 Ximian, Inc. (http://www.ximian.com)
// Copyright (C) 2005-2010 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System.IO;
using System.Collections;
using System.Security.Permissions;
using System.Text;
using System.Collections.Specialized;
using System.Globalization;
using System.Web.Util;
namespace System.Web.UI{
// CAS - no InheritanceDemand here as the class is sealed
[AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
public sealed class CssStyleCollection
{
StateBag bag;
ListDictionary style;
StringBuilder _value = new StringBuilder ();
internal CssStyleCollection ()
{
style = new ListDictionary (StringComparer.OrdinalIgnoreCase);
}
internal CssStyleCollection (StateBag bag) : this ()
{
this.bag = bag;
if (bag != null && bag [AttributeCollection.StyleAttribute] != null)
_value.Append (bag [AttributeCollection.StyleAttribute]);
InitFromStyle ();
}
void InitFromStyle ()
{
style.Clear ();
if (_value.Length > 0) {
int startIndex = 0;
while (startIndex >= 0)
startIndex = ParseStyle (startIndex);
}
}
int ParseStyle (int startIndex)
{
int colon = -1;
for (int i = startIndex; i < _value.Length; i++) {
if (_value [i] == ':') {
colon = i;
break;
}
}
if (colon == -1 || colon + 1 == _value.Length)
return -1;
string key = _value.ToString (startIndex, colon - startIndex).Trim ();
int semicolon = -1;
for (int i = colon + 1; i < _value.Length; i++) {
if (_value [i] == ';') {
semicolon = i;
break;
}
}
string value;
if (semicolon == -1)
value = _value.ToString (colon + 1, _value.Length - colon - 1).Trim ();
else
value = _value.ToString (colon + 1, semicolon - colon - 1).Trim ();
style.Add (key, value);
if (semicolon == -1 || semicolon + 1 == _value.Length)
return -1;
return semicolon + 1;
}
void BagToValue ()
{
_value.Length = 0;
foreach (string key in style.Keys)
AppendStyle (_value, key, (string) style [key]);
}
static void AppendStyle (StringBuilder sb, string key, string value)
{
if (String.Compare (key, "background-image", StringComparison.OrdinalIgnoreCase) == 0 &&
value.Length >= 3 && String.Compare ("url", 0, value, 0, 3, StringComparison.OrdinalIgnoreCase) != 0)
sb.AppendFormat ("{0}:url({1});", key, HttpUtility.UrlPathEncode (value));
else
sb.AppendFormat ("{0}:{1};", key, value);
}
public int Count {
get { return style.Count; }
}
public string this [string key] {
get { return style [key] as string; }
set { Add (key, value); }
}
public ICollection Keys {
get { return style.Keys; }
}
public void Add (string key, string value)
{
if (key == null)
throw new ArgumentNullException ("key");
if (value == null) {
Remove (key);
return;
}
string curr = (string) style [key];
if (curr == null) {
// just append
style [key] = value;
AppendStyle (_value, key, value);
} else if (String.CompareOrdinal (curr, value) == 0) {
// do nothing
return;
} else {
style [key] = value;
BagToValue ();
}
if (bag != null)
bag [AttributeCollection.StyleAttribute] = _value.ToString ();
}
public void Add (HtmlTextWriterStyle key, string value)
{
Add (HtmlTextWriter.StaticGetStyleName (key), value);
}
public void Clear ()
{
style.Clear ();
SetValueInternal (null);
}
public void Remove (string key)
{
if (style [key] == null)
return;
style.Remove (key);
if (style.Count == 0)
SetValueInternal (null);
else
BagToValue ();
}
public string this [HtmlTextWriterStyle key] {
get { return style [HtmlTextWriter.StaticGetStyleName (key)] as string; }
set { Add (HtmlTextWriter.StaticGetStyleName (key), value); }
}
public void Remove (HtmlTextWriterStyle key)
{
Remove (HtmlTextWriter.StaticGetStyleName (key));
}
public string Value {
get { return _value.ToString (); }
set {
SetValueInternal (value);
InitFromStyle ();
}
}
void SetValueInternal (string value)
{
_value.Length = 0;
if (value != null)
_value.Append (value);
if (bag != null) {
if (value == null)
bag.Remove (AttributeCollection.StyleAttribute);
else
bag [AttributeCollection.StyleAttribute] = value;
}
}
}
}
|