Implements the Property method on the Stylesheet class, so it can be used from the backoffice.
Completes U4-934
This commit is contained in:
@@ -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; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user