Implements the Property method on the Stylesheet class, so it can be used from the backoffice.

Completes U4-934
This commit is contained in:
sitereactor
2012-10-24 06:42:04 -02:00
parent 013513b439
commit 3ef0e302c3
4 changed files with 200 additions and 19 deletions

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using Umbraco.Core.IO;
using Umbraco.Core.Models.Css;
using Umbraco.Core.Models.EntityBase;
@@ -21,8 +22,14 @@ namespace Umbraco.Core.Models
}
/// <summary>
/// Returns a list of <see cref="StylesheetProperty"/>
/// Returns a flat list of <see cref="StylesheetProperty"/> objects
/// </summary>
/// <remarks>
/// Please note that the list is flattend by formatting single css selectors with
/// its value(s). Blocks in css @ rules are also flatten, but noted as part of an @ rule
/// by setting the <see cref="StylesheetProperty"/> property IsPartOfAtRule=true.
/// This is done to make the stylesheet usable in the backoffice.
/// </remarks>
[IgnoreDataMember]
public IEnumerable<StylesheetProperty> Properties
{
@@ -31,23 +38,78 @@ namespace Umbraco.Core.Models
var properties = new List<StylesheetProperty>();
var parser = new CssParser(Content);
//TODO Need to explorer how the Stylesheet should be iterated to generate a list of css properties
foreach (CssAtRule statement in parser.StyleSheet.Statements.Where(s => s is CssAtRule))
{
properties.Add(new StylesheetProperty(statement.Value, ""));
var cssBlock = statement.Block;
if(cssBlock == null) continue;
var cssValues = cssBlock.Values;
if(cssValues == null) continue;
properties.AddRange(FormatCss(cssBlock.Values, true));
}
foreach (CssRuleSet statement in parser.StyleSheet.Statements.Where(s => s is CssRuleSet))
{
var selector = statement.Selectors.First();
var declaration = statement.Declarations.FirstOrDefault();
properties.Add(new StylesheetProperty(selector.Value, declaration.ToString()));
}
var statements = parser.StyleSheet.Statements.Where(s => s is CssRuleSet);
properties.AddRange(FormatCss(statements, false));
return properties;
}
}
/// <summary>
/// Formats a list of statements to a simple <see cref="StylesheetProperty"/> object
/// </summary>
/// <param name="statements">Enumerable list of <see cref="ICssValue"/> statements</param>
/// <param name="isPartOfAtRule">Boolean indicating whether the current list of statements is part of an @ rule</param>
/// <returns>An Enumerable list of <see cref="StylesheetProperty"/> objects</returns>
private IEnumerable<StylesheetProperty> FormatCss(IEnumerable<ICssValue> statements, bool isPartOfAtRule)
{
var properties = new List<StylesheetProperty>();
foreach (CssRuleSet statement in statements)
{
foreach (var selector in statement.Selectors)
{
var declarations = new StringBuilder();
foreach (var declaration in statement.Declarations)
{
declarations.AppendFormat("{0}:{1};", declaration.Property, FormatCss(declaration.Value));
declarations.AppendLine("");
}
properties.Add(new StylesheetProperty(selector.Value.TrimStart('.', '#'), declarations.ToString()) { IsPartOfAtRule = isPartOfAtRule });
}
}
return properties;
}
/// <summary>
/// Formats a <see cref="CssValueList"/> to a single string
/// </summary>
/// <param name="valueList"><see cref="CssValueList"/> to format</param>
/// <returns>Value list formatted as a string</returns>
private string FormatCss(CssValueList valueList)
{
bool space = false;
var values = new StringBuilder();
foreach (CssString value in valueList.Values)
{
if (space)
{
values.Append(" ");
}
else
{
space = true;
}
values.Append(value);
}
return values.ToString();
}
/// <summary>
/// Boolean indicating whether the file could be validated
/// </summary>
@@ -71,11 +133,30 @@ namespace Umbraco.Core.Models
/// <returns>True if css is valid, otherwise false</returns>
public bool IsFileValidCss()
{
var parser = new CssParser(Path);//TODO change CssParser so we can use Content instead of Path
return parser.Errors.Any();
var parser = new CssParser(Content);
try
{
var styleSheet = parser.StyleSheet;//Get stylesheet to invoke parsing
}
catch (Exception ex)
{
//Log exception?
return false;
}
return !parser.Errors.Any();
}
}
/// <summary>
/// Represents a Stylesheet Property
/// </summary>
/// <remarks>
/// Properties are always formatted to have a single selector, so it can be used in the backoffice
/// </remarks>
[Serializable]
[DataContract(IsReference = true)]
public class StylesheetProperty : IValueObject
{
public StylesheetProperty(string @alias, string value)
@@ -86,5 +167,6 @@ namespace Umbraco.Core.Models
public string Alias { get; set; }
public string Value { get; set; }
public bool IsPartOfAtRule { get; set; }
}
}