* Rename Umbraco.Core namespace to Umbraco.Cms.Core * Move extension methods in core project to Umbraco.Extensions * Move extension methods in core project to Umbraco.Extensions * Rename Umbraco.Examine namespace to Umbraco.Cms.Examine * Move examine extensions to Umbraco.Extensions namespace * Reflect changed namespaces in Builder and fix unit tests * Adjust namespace in Umbraco.ModelsBuilder.Embedded * Adjust namespace in Umbraco.Persistence.SqlCe * Adjust namespace in Umbraco.PublishedCache.NuCache * Align namespaces in Umbraco.Web.BackOffice * Align namespaces in Umbraco.Web.Common * Ensure that SqlCeSupport is still enabled after changing the namespace * Align namespaces in Umbraco.Web.Website * Align namespaces in Umbraco.Web.UI.NetCore * Align namespaces in Umbraco.Tests.Common * Align namespaces in Umbraco.Tests.UnitTests * Align namespaces in Umbraco.Tests.Integration * Fix errors caused by changed namespaces * Fix integration tests * Undo the Umbraco.Examine.Lucene namespace change This breaks integration tests on linux, since the namespace wont exists there because it's only used on windows. * Fix merge * Fix Merge
176 lines
6.7 KiB
C#
176 lines
6.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Data;
|
|
using System.Linq;
|
|
using System.Runtime.Serialization;
|
|
using Umbraco.Cms.Core.Strings.Css;
|
|
using Umbraco.Extensions;
|
|
|
|
namespace Umbraco.Cms.Core.Models
|
|
{
|
|
/// <summary>
|
|
/// Represents a Stylesheet file
|
|
/// </summary>
|
|
[Serializable]
|
|
[DataContract(IsReference = true)]
|
|
public class Stylesheet : File, IStylesheet
|
|
{
|
|
public Stylesheet(string path)
|
|
: this(path, null)
|
|
{ }
|
|
|
|
public Stylesheet(string path, Func<File, string> getFileContent)
|
|
: base(string.IsNullOrEmpty(path) ? path : path.EnsureEndsWith(".css"), getFileContent)
|
|
{
|
|
InitializeProperties();
|
|
}
|
|
|
|
private Lazy<List<StylesheetProperty>> _properties;
|
|
|
|
private void InitializeProperties()
|
|
{
|
|
//if the value is already created, we need to be created and update the collection according to
|
|
//what is now in the content
|
|
if (_properties != null && _properties.IsValueCreated)
|
|
{
|
|
//re-parse it so we can check what properties are different and adjust the event handlers
|
|
var parsed = StylesheetHelper.ParseRules(Content).ToArray();
|
|
var names = parsed.Select(x => x.Name).ToArray();
|
|
var existing = _properties.Value.Where(x => names.InvariantContains(x.Name)).ToArray();
|
|
//update existing
|
|
foreach (var stylesheetProperty in existing)
|
|
{
|
|
var updateFrom = parsed.Single(x => x.Name.InvariantEquals(stylesheetProperty.Name));
|
|
//remove current event handler while we update, we'll reset it after
|
|
stylesheetProperty.PropertyChanged -= Property_PropertyChanged;
|
|
stylesheetProperty.Alias = updateFrom.Selector;
|
|
stylesheetProperty.Value = updateFrom.Styles;
|
|
//re-add
|
|
stylesheetProperty.PropertyChanged += Property_PropertyChanged;
|
|
}
|
|
//remove no longer existing
|
|
var nonExisting = _properties.Value.Where(x => names.InvariantContains(x.Name) == false).ToArray();
|
|
foreach (var stylesheetProperty in nonExisting)
|
|
{
|
|
stylesheetProperty.PropertyChanged -= Property_PropertyChanged;
|
|
_properties.Value.Remove(stylesheetProperty);
|
|
}
|
|
//add new ones
|
|
var newItems = parsed.Where(x => _properties.Value.Select(p => p.Name).InvariantContains(x.Name) == false);
|
|
foreach (var stylesheetRule in newItems)
|
|
{
|
|
var prop = new StylesheetProperty(stylesheetRule.Name, stylesheetRule.Selector, stylesheetRule.Styles);
|
|
prop.PropertyChanged += Property_PropertyChanged;
|
|
_properties.Value.Add(prop);
|
|
}
|
|
}
|
|
|
|
//we haven't read the properties yet so create the lazy delegate
|
|
_properties = new Lazy<List<StylesheetProperty>>(() =>
|
|
{
|
|
var parsed = StylesheetHelper.ParseRules(Content);
|
|
return parsed.Select(statement =>
|
|
{
|
|
var property = new StylesheetProperty(statement.Name, statement.Selector, statement.Styles);
|
|
property.PropertyChanged += Property_PropertyChanged;
|
|
return property;
|
|
|
|
}).ToList();
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// If the property has changed then we need to update the content
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
void Property_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
|
{
|
|
var prop = (StylesheetProperty) sender;
|
|
|
|
//Ensure we are setting base.Content here so that the properties don't get reset and thus any event handlers would get reset too
|
|
base.Content = StylesheetHelper.ReplaceRule(Content, prop.Name, new StylesheetRule
|
|
{
|
|
Name = prop.Name,
|
|
Selector = prop.Alias,
|
|
Styles = prop.Value
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the Content of a File
|
|
/// </summary>
|
|
public override string Content
|
|
{
|
|
get { return base.Content; }
|
|
set
|
|
{
|
|
base.Content = value;
|
|
//re-set the properties so they are re-read from the content
|
|
InitializeProperties();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns a list of umbraco back office enabled stylesheet properties
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// An umbraco back office enabled stylesheet property has a special prefix, for example:
|
|
///
|
|
/// /** umb_name: MyPropertyName */ p { font-size: 1em; }
|
|
/// </remarks>
|
|
[IgnoreDataMember]
|
|
public IEnumerable<IStylesheetProperty> Properties
|
|
{
|
|
get { return _properties.Value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds an Umbraco stylesheet property for use in the back office
|
|
/// </summary>
|
|
/// <param name="property"></param>
|
|
public void AddProperty(IStylesheetProperty property)
|
|
{
|
|
if (Properties.Any(x => x.Name.InvariantEquals(property.Name)))
|
|
{
|
|
throw new DuplicateNameException("The property with the name " + property.Name + " already exists in the collection");
|
|
}
|
|
|
|
//now we need to serialize out the new property collection over-top of the string Content.
|
|
Content = StylesheetHelper.AppendRule(Content, new StylesheetRule
|
|
{
|
|
Name = property.Name,
|
|
Selector = property.Alias,
|
|
Styles = property.Value
|
|
});
|
|
|
|
//re-set lazy collection
|
|
InitializeProperties();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Removes an Umbraco stylesheet property
|
|
/// </summary>
|
|
/// <param name="name"></param>
|
|
public void RemoveProperty(string name)
|
|
{
|
|
if (Properties.Any(x => x.Name.InvariantEquals(name)))
|
|
{
|
|
Content = StylesheetHelper.ReplaceRule(Content, name, null);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Indicates whether the current entity has an identity, which in this case is a path/name.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Overrides the default Entity identity check.
|
|
/// </remarks>
|
|
public override bool HasIdentity
|
|
{
|
|
get { return string.IsNullOrEmpty(Path) == false; }
|
|
}
|
|
}
|
|
}
|