mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Adding Shape editors infrastructure
--HG-- branch : 1.x
This commit is contained in:
@@ -82,6 +82,9 @@ namespace Orchard.DisplayManagement.Descriptors.ShapeAttributeStrategy {
|
||||
if (parameter.Name == "Output" && parameter.ParameterType == typeof(TextWriter))
|
||||
return output;
|
||||
|
||||
if (parameter.Name == "Output" && parameter.ParameterType == typeof(Action<object>))
|
||||
return new Action<object>(output.Write);
|
||||
|
||||
// meh--
|
||||
if (parameter.Name == "Html") {
|
||||
return new HtmlHelper(
|
||||
@@ -90,8 +93,12 @@ namespace Orchard.DisplayManagement.Descriptors.ShapeAttributeStrategy {
|
||||
_routeCollection);
|
||||
}
|
||||
|
||||
if (parameter.Name == "Url" && parameter.ParameterType.IsAssignableFrom(typeof(UrlHelper))) {
|
||||
return new UrlHelper(displayContext.ViewContext.RequestContext, _routeCollection);
|
||||
}
|
||||
|
||||
var getter = _getters.GetOrAdd(parameter.Name, n =>
|
||||
CallSite<Func<CallSite, object, object>>.Create(
|
||||
CallSite<Func<CallSite, object, dynamic>>.Create(
|
||||
Microsoft.CSharp.RuntimeBinder.Binder.GetMember(
|
||||
CSharpBinderFlags.None, n, null, new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) })));
|
||||
|
||||
@@ -106,13 +113,13 @@ namespace Orchard.DisplayManagement.Descriptors.ShapeAttributeStrategy {
|
||||
}
|
||||
|
||||
|
||||
static readonly ConcurrentDictionary<string, CallSite<Func<CallSite, object, object>>> _getters =
|
||||
new ConcurrentDictionary<string, CallSite<Func<CallSite, object, object>>>();
|
||||
static readonly ConcurrentDictionary<string, CallSite<Func<CallSite, object, dynamic>>> _getters =
|
||||
new ConcurrentDictionary<string, CallSite<Func<CallSite, object, dynamic>>>();
|
||||
|
||||
static readonly ConcurrentDictionary<Type, Func<object, object>> _converters =
|
||||
new ConcurrentDictionary<Type, Func<object, object>>();
|
||||
static readonly ConcurrentDictionary<Type, Func<dynamic, object>> _converters =
|
||||
new ConcurrentDictionary<Type, Func<dynamic, object>>();
|
||||
|
||||
static Func<object, object> CompileConverter(Type targetType) {
|
||||
static Func<dynamic, object> CompileConverter(Type targetType) {
|
||||
var valueParameter = Expression.Parameter(typeof(object), "value");
|
||||
|
||||
return Expression.Lambda<Func<object, object>>(
|
||||
|
@@ -58,14 +58,15 @@ namespace Orchard.DisplayManagement.Implementation {
|
||||
new ClaySharp.Behaviors.InterfaceProxyBehavior(),
|
||||
new ClaySharp.Behaviors.PropBehavior(),
|
||||
new ClaySharp.Behaviors.ArrayBehavior(),
|
||||
new ClaySharp.Behaviors.NilResultBehavior()
|
||||
new ClaySharp.Behaviors.NilResultBehavior(),
|
||||
};
|
||||
}
|
||||
else {
|
||||
creatingContext.Behaviors = new List<IClayBehavior> {
|
||||
new ClaySharp.Behaviors.InterfaceProxyBehavior(),
|
||||
new ClaySharp.Behaviors.PropBehavior(),
|
||||
new ClaySharp.Behaviors.NilResultBehavior()
|
||||
new ClaySharp.Behaviors.NilResultBehavior(),
|
||||
new Shape.ShapeBehavior(),
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -1,8 +1,11 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Web.Mvc;
|
||||
using ClaySharp;
|
||||
using ClaySharp.Implementation;
|
||||
|
||||
namespace Orchard.DisplayManagement.Shapes {
|
||||
[DebuggerTypeProxy(typeof(ShapeDebugView))]
|
||||
@@ -20,7 +23,7 @@ namespace Orchard.DisplayManagement.Shapes {
|
||||
public virtual IDictionary<string, string> Attributes { get { return _attributes; } }
|
||||
public virtual IEnumerable<dynamic> Items { get { return _items; } }
|
||||
|
||||
public virtual Shape Add(object item, string position = DefaultPosition) {
|
||||
public virtual Shape Add(object item, string position = null) {
|
||||
// pszmyd: Ignoring null shapes
|
||||
if (item == null) {
|
||||
return this;
|
||||
@@ -32,7 +35,7 @@ namespace Orchard.DisplayManagement.Shapes {
|
||||
item is String ) {
|
||||
// need to implement positioned wrapper for non-shape objects
|
||||
}
|
||||
else {
|
||||
else if (item is IShape) {
|
||||
((dynamic) item).Metadata.Position = position;
|
||||
}
|
||||
}
|
||||
@@ -53,5 +56,123 @@ namespace Orchard.DisplayManagement.Shapes {
|
||||
public virtual IEnumerator GetEnumerator() {
|
||||
return _items.GetEnumerator();
|
||||
}
|
||||
|
||||
public class ShapeBehavior : ClayBehavior {
|
||||
public override object SetIndex(Func<object> proceed, dynamic self, IEnumerable<object> keys, object value) {
|
||||
if (keys.Count() == 1) {
|
||||
var name = keys.Single().ToString();
|
||||
if (name.Equals("Id")) {
|
||||
// need to mutate the actual type
|
||||
var s = self as Shape;
|
||||
if (s != null) {
|
||||
s.Id = System.Convert.ToString(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
if (name.Equals("Classes")) {
|
||||
var args = Arguments.From(new[] { value }, Enumerable.Empty<string>());
|
||||
MergeClasses(args, self.Classes);
|
||||
return value;
|
||||
}
|
||||
if (name.Equals("Attributes")) {
|
||||
var args = Arguments.From(new[] { value }, Enumerable.Empty<string>());
|
||||
MergeAttributes(args, self.Attributes);
|
||||
return value;
|
||||
}
|
||||
if (name.Equals("Items")) {
|
||||
var args = Arguments.From(new[] { value }, Enumerable.Empty<string>());
|
||||
MergeItems(args, self);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return proceed();
|
||||
}
|
||||
|
||||
public override object InvokeMember(Func<object> proceed, dynamic self, string name, INamedEnumerable<object> args) {
|
||||
if (name.Equals("Id")) {
|
||||
// need to mutate the actual type
|
||||
var s = self as Shape;
|
||||
if (s != null) {
|
||||
s.Id = System.Convert.ToString(args.FirstOrDefault());
|
||||
}
|
||||
return self;
|
||||
}
|
||||
if (name.Equals("Classes") && !args.Named.Any()) {
|
||||
MergeClasses(args, self.Classes);
|
||||
return self;
|
||||
}
|
||||
if (name.Equals("Attributes") && args.Positional.Count() <= 1) {
|
||||
MergeAttributes(args, self.Attributes);
|
||||
return self;
|
||||
}
|
||||
if (name.Equals("Items")) {
|
||||
MergeItems(args, self);
|
||||
return self;
|
||||
}
|
||||
return proceed();
|
||||
}
|
||||
|
||||
private static void MergeAttributes(INamedEnumerable<object> args, IDictionary<string, string> attributes) {
|
||||
var arg = args.Positional.SingleOrDefault();
|
||||
if (arg != null) {
|
||||
if (arg is IDictionary) {
|
||||
var dictionary = arg as IDictionary;
|
||||
foreach (var key in dictionary.Keys) {
|
||||
attributes[System.Convert.ToString(key)] = System.Convert.ToString(dictionary[key]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
foreach (var prop in arg.GetType().GetProperties()) {
|
||||
attributes[TranslateIdentifier(prop.Name)] = System.Convert.ToString(prop.GetValue(arg, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (var named in args.Named) {
|
||||
attributes[named.Key] = System.Convert.ToString(named.Value);
|
||||
}
|
||||
}
|
||||
|
||||
private static string TranslateIdentifier(string name) {
|
||||
// Allows for certain characters in an identifier to represent different
|
||||
// characters in an HTML attribute (mimics MVC behavior):
|
||||
// data_foo ==> data-foo
|
||||
// @keyword ==> keyword
|
||||
return name.Replace("_", "-").Replace("@", "");
|
||||
}
|
||||
|
||||
private static void MergeClasses(INamedEnumerable<object> args, IList<string> classes) {
|
||||
foreach (var arg in args) {
|
||||
// look for string first, because the "string" type is also an IEnumerable of char
|
||||
if (arg is string) {
|
||||
classes.Add(arg as string);
|
||||
}
|
||||
else if (arg is IEnumerable) {
|
||||
foreach (var item in arg as IEnumerable) {
|
||||
classes.Add(System.Convert.ToString(item));
|
||||
}
|
||||
}
|
||||
else {
|
||||
classes.Add(System.Convert.ToString(arg));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void MergeItems(INamedEnumerable<object> args, dynamic shape) {
|
||||
foreach (var arg in args) {
|
||||
// look for string first, because the "string" type is also an IEnumerable of char
|
||||
if (arg is string) {
|
||||
shape.Add(arg as string);
|
||||
}
|
||||
else if (arg is IEnumerable) {
|
||||
foreach (var item in arg as IEnumerable) {
|
||||
shape.Add(item);
|
||||
}
|
||||
}
|
||||
else {
|
||||
shape.Add(System.Convert.ToString(arg));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user