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))
|
if (parameter.Name == "Output" && parameter.ParameterType == typeof(TextWriter))
|
||||||
return output;
|
return output;
|
||||||
|
|
||||||
|
if (parameter.Name == "Output" && parameter.ParameterType == typeof(Action<object>))
|
||||||
|
return new Action<object>(output.Write);
|
||||||
|
|
||||||
// meh--
|
// meh--
|
||||||
if (parameter.Name == "Html") {
|
if (parameter.Name == "Html") {
|
||||||
return new HtmlHelper(
|
return new HtmlHelper(
|
||||||
@@ -90,8 +93,12 @@ namespace Orchard.DisplayManagement.Descriptors.ShapeAttributeStrategy {
|
|||||||
_routeCollection);
|
_routeCollection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parameter.Name == "Url" && parameter.ParameterType.IsAssignableFrom(typeof(UrlHelper))) {
|
||||||
|
return new UrlHelper(displayContext.ViewContext.RequestContext, _routeCollection);
|
||||||
|
}
|
||||||
|
|
||||||
var getter = _getters.GetOrAdd(parameter.Name, n =>
|
var getter = _getters.GetOrAdd(parameter.Name, n =>
|
||||||
CallSite<Func<CallSite, object, object>>.Create(
|
CallSite<Func<CallSite, object, dynamic>>.Create(
|
||||||
Microsoft.CSharp.RuntimeBinder.Binder.GetMember(
|
Microsoft.CSharp.RuntimeBinder.Binder.GetMember(
|
||||||
CSharpBinderFlags.None, n, null, new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) })));
|
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 =
|
static readonly ConcurrentDictionary<string, CallSite<Func<CallSite, object, dynamic>>> _getters =
|
||||||
new ConcurrentDictionary<string, CallSite<Func<CallSite, object, object>>>();
|
new ConcurrentDictionary<string, CallSite<Func<CallSite, object, dynamic>>>();
|
||||||
|
|
||||||
static readonly ConcurrentDictionary<Type, Func<object, object>> _converters =
|
static readonly ConcurrentDictionary<Type, Func<dynamic, object>> _converters =
|
||||||
new ConcurrentDictionary<Type, Func<object, object>>();
|
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");
|
var valueParameter = Expression.Parameter(typeof(object), "value");
|
||||||
|
|
||||||
return Expression.Lambda<Func<object, object>>(
|
return Expression.Lambda<Func<object, object>>(
|
||||||
|
@@ -58,14 +58,15 @@ namespace Orchard.DisplayManagement.Implementation {
|
|||||||
new ClaySharp.Behaviors.InterfaceProxyBehavior(),
|
new ClaySharp.Behaviors.InterfaceProxyBehavior(),
|
||||||
new ClaySharp.Behaviors.PropBehavior(),
|
new ClaySharp.Behaviors.PropBehavior(),
|
||||||
new ClaySharp.Behaviors.ArrayBehavior(),
|
new ClaySharp.Behaviors.ArrayBehavior(),
|
||||||
new ClaySharp.Behaviors.NilResultBehavior()
|
new ClaySharp.Behaviors.NilResultBehavior(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
creatingContext.Behaviors = new List<IClayBehavior> {
|
creatingContext.Behaviors = new List<IClayBehavior> {
|
||||||
new ClaySharp.Behaviors.InterfaceProxyBehavior(),
|
new ClaySharp.Behaviors.InterfaceProxyBehavior(),
|
||||||
new ClaySharp.Behaviors.PropBehavior(),
|
new ClaySharp.Behaviors.PropBehavior(),
|
||||||
new ClaySharp.Behaviors.NilResultBehavior()
|
new ClaySharp.Behaviors.NilResultBehavior(),
|
||||||
|
new Shape.ShapeBehavior(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,8 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
|
using ClaySharp;
|
||||||
|
using ClaySharp.Implementation;
|
||||||
|
|
||||||
namespace Orchard.DisplayManagement.Shapes {
|
namespace Orchard.DisplayManagement.Shapes {
|
||||||
[DebuggerTypeProxy(typeof(ShapeDebugView))]
|
[DebuggerTypeProxy(typeof(ShapeDebugView))]
|
||||||
@@ -20,7 +23,7 @@ namespace Orchard.DisplayManagement.Shapes {
|
|||||||
public virtual IDictionary<string, string> Attributes { get { return _attributes; } }
|
public virtual IDictionary<string, string> Attributes { get { return _attributes; } }
|
||||||
public virtual IEnumerable<dynamic> Items { get { return _items; } }
|
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
|
// pszmyd: Ignoring null shapes
|
||||||
if (item == null) {
|
if (item == null) {
|
||||||
return this;
|
return this;
|
||||||
@@ -32,7 +35,7 @@ namespace Orchard.DisplayManagement.Shapes {
|
|||||||
item is String ) {
|
item is String ) {
|
||||||
// need to implement positioned wrapper for non-shape objects
|
// need to implement positioned wrapper for non-shape objects
|
||||||
}
|
}
|
||||||
else {
|
else if (item is IShape) {
|
||||||
((dynamic) item).Metadata.Position = position;
|
((dynamic) item).Metadata.Position = position;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -53,5 +56,123 @@ namespace Orchard.DisplayManagement.Shapes {
|
|||||||
public virtual IEnumerator GetEnumerator() {
|
public virtual IEnumerator GetEnumerator() {
|
||||||
return _items.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