mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-04-05 21:01:35 +08:00
Merge with clayless
--HG-- branch : 1.x
This commit is contained in:
commit
fca554ddc9
Binary file not shown.
Binary file not shown.
@ -59,9 +59,6 @@
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\lib\autofac\Autofac.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ClaySharp">
|
||||
<HintPath>..\..\lib\claysharp\ClaySharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="FluentNHibernate, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8aa435e3cb308880, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\lib\nhibernate\FluentNHibernate.dll</HintPath>
|
||||
|
@ -62,9 +62,6 @@
|
||||
<Reference Include="Castle.Core">
|
||||
<HintPath>..\..\lib\Castle Windsor 2.0\bin\Castle.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ClaySharp">
|
||||
<HintPath>..\..\lib\claysharp\ClaySharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="FluentNHibernate, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8aa435e3cb308880, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\lib\nhibernate\FluentNHibernate.dll</HintPath>
|
||||
|
@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using Autofac;
|
||||
using ClaySharp;
|
||||
using NUnit.Framework;
|
||||
using Orchard.Scripting.Dlr.Services;
|
||||
using Path = Bleroy.FluentPath.Path;
|
||||
@ -83,22 +82,6 @@ namespace Orchard.Tests.Modules.Scripting.Dlr {
|
||||
Assert.That(_scriptingManager.ExecuteExpression("f / 4"), Is.EqualTo(8));
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void CanDeclareCallbackOnGlobalMethod() {
|
||||
_scriptingManager.SetVariable("x", new Clay(new ReturnMethodNameLengthBehavior()));
|
||||
|
||||
Assert.That(_scriptingManager.ExecuteExpression("3 + x.foo()"), Is.EqualTo(6));
|
||||
}
|
||||
|
||||
|
||||
public class ReturnMethodNameLengthBehavior : ClayBehavior {
|
||||
public override object InvokeMemberMissing(Func<object> proceed, object self, string name, INamedEnumerable<object> args) {
|
||||
Trace.WriteLine("Returning length of " + name);
|
||||
return name.Length;
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CanDeclareCallbackOnInstanceEvalWithFile() {
|
||||
var targetPath = _tempFolderName.Combine("CallbackOnInstanceEval.rb");
|
||||
|
@ -1,8 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web.Routing;
|
||||
using ClaySharp;
|
||||
using ClaySharp.Implementation;
|
||||
using Orchard.DisplayManagement;
|
||||
|
||||
namespace Orchard.Tests.DisplayManagement {
|
||||
public static class ArgsUtility {
|
||||
|
61
src/Orchard.Tests/DisplayManagement/CompositeTests.cs
Normal file
61
src/Orchard.Tests/DisplayManagement/CompositeTests.cs
Normal file
@ -0,0 +1,61 @@
|
||||
using NUnit.Framework;
|
||||
using Orchard.DisplayManagement.Shapes;
|
||||
|
||||
namespace Orchard.Tests.DisplayManagement {
|
||||
[TestFixture]
|
||||
public class CompositeTests {
|
||||
|
||||
[Test]
|
||||
public void CompositesShouldNotOverrideExistingMembers() {
|
||||
var composite = new Animal {Color = "Pink"};
|
||||
|
||||
Assert.That(composite.Color, Is.EqualTo("Pink"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CompositesShouldNotOverrideExistingMembersWhenUsedAsDynamic() {
|
||||
dynamic composite = new Animal();
|
||||
|
||||
composite.Color = "Pink";
|
||||
Assert.That(composite.Color, Is.EqualTo("Pink"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CompositesShouldAccessUnknownProperties() {
|
||||
dynamic composite = new Animal();
|
||||
|
||||
composite.Fake = 42;
|
||||
Assert.That(composite.Fake, Is.EqualTo(42));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CompositesShouldAccessUnknownPropertiesByIndex() {
|
||||
dynamic composite = new Animal();
|
||||
|
||||
composite["Fake"] = 42;
|
||||
Assert.That(composite["Fake"], Is.EqualTo(42));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CompositesShouldAccessKnownPropertiesByIndex() {
|
||||
dynamic composite = new Animal();
|
||||
|
||||
composite["Pink"] = "Pink";
|
||||
Assert.That(composite["Pink"], Is.EqualTo("Pink"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ChainProperties() {
|
||||
dynamic foo = new Animal();
|
||||
foo.Bar("bar");
|
||||
|
||||
Assert.That(foo.Bar, Is.EqualTo("bar"));
|
||||
Assert.That(foo.Bar == null, Is.False);
|
||||
}
|
||||
}
|
||||
|
||||
public class Animal : Composite {
|
||||
public string Kind { get; set; }
|
||||
public string Color { get; set; }
|
||||
}
|
||||
}
|
@ -37,7 +37,43 @@ namespace Orchard.Tests.DisplayManagement {
|
||||
[Test]
|
||||
public void CreateShapeWithNamedArguments() {
|
||||
var factory = _container.Resolve<IShapeFactory>();
|
||||
var foo = factory.Create("Foo", ArgsUtility.Named(new { one = 1, two = "dos" }));
|
||||
dynamic foo = factory.Create("Foo", ArgsUtility.Named(new { one = 1, two = "dos" }));
|
||||
Assert.That(foo.one, Is.EqualTo(1));
|
||||
Assert.That(foo.two, Is.EqualTo("dos"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CallSyntax() {
|
||||
dynamic factory = _container.Resolve<IShapeFactory>();
|
||||
var foo = factory.Foo();
|
||||
ShapeMetadata metadata = foo.Metadata;
|
||||
Assert.That(metadata.Type, Is.EqualTo("Foo"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CallInitializer() {
|
||||
dynamic factory = _container.Resolve<IShapeFactory>();
|
||||
var bar = new {One = 1, Two = "two"};
|
||||
var foo = factory.Foo(bar);
|
||||
|
||||
Assert.That(foo.One, Is.EqualTo(1));
|
||||
Assert.That(foo.Two, Is.EqualTo("two"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CallInitializerWithBaseType() {
|
||||
dynamic factory = _container.Resolve<IShapeFactory>();
|
||||
var bar = new { One = 1, Two = "two" };
|
||||
var foo = factory.Foo(typeof(MyShape), bar);
|
||||
|
||||
Assert.That(foo, Is.InstanceOf<MyShape>());
|
||||
Assert.That(foo.One, Is.EqualTo(1));
|
||||
Assert.That(foo.Two, Is.EqualTo("two"));
|
||||
}
|
||||
|
||||
public class MyShape : Shape {
|
||||
public string Kind { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
88
src/Orchard.Tests/DisplayManagement/ZoneHoldingTests.cs
Normal file
88
src/Orchard.Tests/DisplayManagement/ZoneHoldingTests.cs
Normal file
@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
using Orchard.DisplayManagement.Shapes;
|
||||
using Orchard.UI.Zones;
|
||||
|
||||
namespace Orchard.Tests.DisplayManagement {
|
||||
[TestFixture]
|
||||
public class ZoneHoldingTests {
|
||||
|
||||
[Test]
|
||||
public void ZonesShouldReturn() {
|
||||
Func<dynamic> factory = () => new Shape();
|
||||
|
||||
var foo = new ZoneHolding(factory);
|
||||
Assert.That(foo.Zones, Is.InstanceOf<Zones>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MemberShouldCreateAZone() {
|
||||
Func<dynamic> factory = () => new Shape();
|
||||
|
||||
dynamic foo = new ZoneHolding(factory);
|
||||
Assert.That(foo.Header, Is.InstanceOf<ZoneOnDemand>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IndexShouldCreateAZone() {
|
||||
Func<dynamic> factory = () => new Shape();
|
||||
|
||||
dynamic foo = new ZoneHolding(factory);
|
||||
Assert.That(foo.Zones["Header"], Is.InstanceOf<ZoneOnDemand>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ZonesMemberShouldCreateAZone() {
|
||||
Func<dynamic> factory = () => new Shape();
|
||||
|
||||
dynamic foo = new ZoneHolding(factory);
|
||||
Assert.That(foo.Zones.Header, Is.InstanceOf<ZoneOnDemand>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ZonesShouldBeUnique() {
|
||||
Func<dynamic> factory = () => new Shape();
|
||||
|
||||
dynamic foo = new ZoneHolding(factory);
|
||||
var header = foo.Header;
|
||||
|
||||
Assert.That(foo.Zones.Header, Is.EqualTo(header));
|
||||
Assert.That(foo.Zones["Header"], Is.EqualTo(header));
|
||||
Assert.That(foo.Header, Is.EqualTo(header));
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void EmptyZonesShouldBeNull() {
|
||||
Func<dynamic> factory = () => new Shape();
|
||||
|
||||
dynamic foo = new ZoneHolding(factory);
|
||||
|
||||
Assert.That(foo.Header == 1, Is.False);
|
||||
Assert.That(foo.Header != 1, Is.True);
|
||||
|
||||
dynamic header = foo.Header;
|
||||
|
||||
Assert.That(header == null, Is.True);
|
||||
Assert.That(header != null, Is.False);
|
||||
|
||||
Assert.That(header == Nil.Instance, Is.True);
|
||||
Assert.That(header != Nil.Instance, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NoneEmptyZonesShouldBeNull() {
|
||||
Func<dynamic> factory = () => new Shape();
|
||||
|
||||
dynamic foo = new ZoneHolding(factory);
|
||||
foo.Header.Add("blah");
|
||||
|
||||
Assert.That(foo.Header == null, Is.False);
|
||||
Assert.That(foo.Header != null, Is.True);
|
||||
|
||||
Assert.That(foo.Header == Nil.Instance, Is.False);
|
||||
Assert.That(foo.Header != Nil.Instance, Is.True);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -71,10 +71,6 @@
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\lib\Castle Windsor 2.0\bin\Castle.DynamicProxy2.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ClaySharp, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\lib\claysharp\ClaySharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="FluentNHibernate, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8aa435e3cb308880, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\lib\nhibernate\FluentNHibernate.dll</HintPath>
|
||||
@ -220,6 +216,8 @@
|
||||
<Compile Include="Data\Bags\SettingsTests.cs" />
|
||||
<Compile Include="Data\StubLocator.cs" />
|
||||
<Compile Include="DisplayManagement\ArgsUtility.cs" />
|
||||
<Compile Include="DisplayManagement\CompositeTests.cs" />
|
||||
<Compile Include="DisplayManagement\ZoneHoldingTests.cs" />
|
||||
<Compile Include="DisplayManagement\DefaultDisplayManagerTests.cs" />
|
||||
<Compile Include="ContainerTestBase.cs" />
|
||||
<Compile Include="DisplayManagement\Descriptors\BasicShapeTemplateHarvesterTests.cs" />
|
||||
|
@ -2,107 +2,98 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Autofac;
|
||||
using ClaySharp;
|
||||
using NUnit.Framework;
|
||||
using Orchard.Core.Shapes;
|
||||
using Orchard.DisplayManagement;
|
||||
using Orchard.DisplayManagement.Descriptors;
|
||||
using Orchard.DisplayManagement.Implementation;
|
||||
using Orchard.DisplayManagement.Shapes;
|
||||
using Orchard.Environment;
|
||||
using Orchard.Mvc;
|
||||
using Orchard.Tests.DisplayManagement;
|
||||
using Orchard.UI.Zones;
|
||||
|
||||
namespace Orchard.Tests.UI {
|
||||
[TestFixture]
|
||||
public class ShapeTests : ContainerTestBase {
|
||||
private WorkContext _workContext;
|
||||
dynamic _layout;
|
||||
|
||||
protected override void Register(ContainerBuilder builder) {
|
||||
builder.RegisterType<HttpContextAccessor>().As<IHttpContextAccessor>();
|
||||
builder.RegisterType<WorkContextAccessor>().As<IWorkContextAccessor>();
|
||||
var defaultShapeTable = new ShapeTable {
|
||||
Descriptors = new Dictionary<string, ShapeDescriptor>(StringComparer.OrdinalIgnoreCase),
|
||||
Bindings = new Dictionary<string, ShapeBinding>(StringComparer.OrdinalIgnoreCase)
|
||||
};
|
||||
builder.Register(ctx => defaultShapeTable);
|
||||
|
||||
builder.RegisterType<DefaultDisplayManagerTests.TestWorkContextAccessor>().As<IWorkContextAccessor>();
|
||||
builder.RegisterType<DefaultShapeFactory>().As<IShapeFactory>();
|
||||
builder.RegisterType<DefaultShapeTableManager>().As<IShapeTableManager>();
|
||||
builder.RegisterType<LayoutWorkContext>().As<IWorkContextStateProvider>();
|
||||
//builder.RegisterType<CoreShapes>().As<IShapeTableProvider>();
|
||||
builder.RegisterType<NumberIsAlwaysFortyTwo>().As<IShapeFactoryEvents>();
|
||||
|
||||
throw new NotImplementedException("this test fixture needs to move to modules tests now");
|
||||
builder.RegisterType<ShapeTableLocator>().As<IShapeTableLocator>();
|
||||
builder.RegisterType<DefaultDisplayManager>().As<IDisplayManager>();
|
||||
builder.RegisterType<DefaultDisplayManagerTests.TestShapeTableManager>().As<IShapeTableManager>();
|
||||
builder.RegisterType<CoreShapes>().As<IShapeTableProvider>();
|
||||
}
|
||||
|
||||
protected override void Resolve(ILifetimeScope container) {
|
||||
_workContext = container.Resolve<IWorkContextAccessor>().CreateWorkContextScope().WorkContext;
|
||||
var shapeFactory = _container.Resolve<IShapeFactory>();
|
||||
_layout = new ZoneHolding(() => shapeFactory.Create("Zone"));
|
||||
}
|
||||
|
||||
[Test, Ignore("implementation pending")]
|
||||
public void WorkContextPageIsLayoutShape() {
|
||||
var layout = _workContext.Layout;
|
||||
ShapeMetadata pageMetadata = layout.Metadata;
|
||||
Assert.That(pageMetadata.Type, Is.EqualTo("Layout"));
|
||||
Assert.That(layout.Metadata.Type, Is.EqualTo("Layout"));
|
||||
}
|
||||
|
||||
[Test, Ignore("implementation pending")]
|
||||
[Test]
|
||||
public void PagePropertiesAreNil() {
|
||||
var layout = _workContext.Layout;
|
||||
var pageFoo = layout.Foo;
|
||||
|
||||
var pageFoo = _layout.Foo;
|
||||
Assert.That(pageFoo == null);
|
||||
}
|
||||
|
||||
[Test, Ignore("implementation pending")]
|
||||
[Test]
|
||||
public void PageZonesPropertyIsNotNil() {
|
||||
var layout = _workContext.Layout;
|
||||
var pageZones = layout.Zones;
|
||||
var pageZones = _layout.Zones;
|
||||
Assert.That(pageZones != null);
|
||||
Assert.That(pageZones.Foo == null);
|
||||
}
|
||||
|
||||
[Test, Ignore("implementation pending")]
|
||||
[Test]
|
||||
public void AddingToZonePropertyMakesItExist() {
|
||||
var layout = _workContext.Layout;
|
||||
Assert.That(layout.Zones.Foo == null);
|
||||
Assert.That(_layout.Zones.Foo == null);
|
||||
|
||||
var pageZonesFoo = layout.Zones.Foo;
|
||||
var pageZonesFoo = _layout.Zones.Foo;
|
||||
pageZonesFoo.Add("hello");
|
||||
|
||||
Assert.That(layout.Zones.Foo != null);
|
||||
Assert.That(layout.Foo != null);
|
||||
Assert.That(layout.Foo.Metadata.Type, Is.EqualTo("Zone"));
|
||||
Assert.That(_layout.Zones.Foo != null);
|
||||
Assert.That(_layout.Foo != null);
|
||||
Assert.That(_layout.Foo.Metadata.Type, Is.EqualTo("Zone"));
|
||||
}
|
||||
|
||||
[Test, Ignore("implementation pending")]
|
||||
[Test]
|
||||
public void AddingToZoneIndexedMakesItExist() {
|
||||
var layout = _workContext.Layout;
|
||||
Assert.That(layout.Zones["Foo"] == null);
|
||||
Assert.That(_layout.Zones["Foo"] == null);
|
||||
|
||||
var pageZonesFoo = layout.Zones["Foo"];
|
||||
var pageZonesFoo = _layout.Zones["Foo"];
|
||||
pageZonesFoo.Add("hello");
|
||||
|
||||
Assert.That(layout.Zones["Foo"] != null);
|
||||
Assert.That(layout["Foo"] != null);
|
||||
Assert.That(layout["Foo"].Metadata.Type, Is.EqualTo("Zone"));
|
||||
Assert.That(_layout.Zones["Foo"] != null);
|
||||
Assert.That(_layout["Foo"] != null);
|
||||
Assert.That(_layout["Foo"].Metadata.Type, Is.EqualTo("Zone"));
|
||||
}
|
||||
|
||||
[Test, Ignore("implementation pending")]
|
||||
[Test]
|
||||
public void CallingAddOnNilPropertyMakesItBecomeZone() {
|
||||
var layout = _workContext.Layout;
|
||||
Assert.That(layout.Foo == null);
|
||||
Assert.That(_layout.Foo == null);
|
||||
|
||||
layout.Foo.Add("hello");
|
||||
_layout.Foo.Add("hello");
|
||||
|
||||
Assert.That(layout.Foo != null);
|
||||
Assert.That(layout.Foo.Metadata.Type, Is.EqualTo("Zone"));
|
||||
Assert.That(_layout.Foo != null);
|
||||
Assert.That(_layout.Foo.Metadata.Type, Is.EqualTo("Zone"));
|
||||
}
|
||||
|
||||
[Test, Ignore("implementation pending")]
|
||||
[Test]
|
||||
public void ZoneContentsAreEnumerable() {
|
||||
var layout = _workContext.Layout;
|
||||
Assert.That(layout.Foo == null);
|
||||
Assert.That(_layout.Foo == null);
|
||||
|
||||
layout.Foo.Add("hello");
|
||||
layout.Foo.Add("world");
|
||||
_layout.Foo.Add("hello");
|
||||
_layout.Foo.Add("world");
|
||||
|
||||
var list = new List<object>();
|
||||
foreach (var item in layout.Foo) {
|
||||
foreach (var item in _layout.Foo) {
|
||||
list.Add(item);
|
||||
}
|
||||
|
||||
@ -111,27 +102,38 @@ namespace Orchard.Tests.UI {
|
||||
Assert.That(list.Last(), Is.EqualTo("world"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ZoneContentsCastBeConvertedToEnunerableOfObject() {
|
||||
Assert.That(_layout.Foo == null);
|
||||
|
||||
class NumberIsAlwaysFortyTwo : ShapeFactoryEvents {
|
||||
public override void Creating(ShapeCreatingContext context) {
|
||||
context.Behaviors.Add(new Behavior());
|
||||
}
|
||||
_layout.Foo.Add("hello");
|
||||
_layout.Foo.Add("world");
|
||||
|
||||
class Behavior : ClayBehavior {
|
||||
public override object GetMember(Func<object> proceed, object self, string name) {
|
||||
return name == "Number" ? 42 : proceed();
|
||||
}
|
||||
}
|
||||
IEnumerable<object> list = _layout.Foo;
|
||||
|
||||
Assert.That(list.Count(), Is.EqualTo(2));
|
||||
Assert.That(list.First(), Is.EqualTo("hello"));
|
||||
Assert.That(list.Last(), Is.EqualTo("world"));
|
||||
|
||||
var first = ((IEnumerable<object>)_layout.Foo).FirstOrDefault();
|
||||
Assert.That(first, Is.EqualTo("hello"));
|
||||
}
|
||||
|
||||
[Test, Ignore("implementation pending")]
|
||||
public void NumberIsFortyTwo() {
|
||||
var layout = _workContext.Layout;
|
||||
Assert.That(layout.Number, Is.EqualTo(42));
|
||||
Assert.That(layout.Foo.Number == null);
|
||||
layout.Foo.Add("yarg");
|
||||
Assert.That(layout.Foo.Number, Is.EqualTo(42));
|
||||
[Test]
|
||||
public void ZoneContentsCastBeConvertedToEnunerableOfDynamics() {
|
||||
Assert.That(_layout.Foo == null);
|
||||
|
||||
_layout.Foo.Add("hello");
|
||||
_layout.Foo.Add("world");
|
||||
|
||||
IEnumerable<dynamic> list = _layout.Foo;
|
||||
|
||||
Assert.That(list.Count(), Is.EqualTo(2));
|
||||
Assert.That(list.First(), Is.EqualTo("hello"));
|
||||
Assert.That(list.Last(), Is.EqualTo("world"));
|
||||
|
||||
var first = ((IEnumerable<dynamic>) _layout.Foo).FirstOrDefault();
|
||||
Assert.That(first, Is.EqualTo("hello"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -46,11 +46,6 @@
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="ClaySharp, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\lib\claysharp\ClaySharp.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.ComponentModel.DataAnnotations">
|
||||
|
@ -48,7 +48,7 @@ namespace Orchard.Core.Shapes {
|
||||
// and has an automatic zone creating behavior
|
||||
builder.Describe("Layout")
|
||||
.Configure(descriptor => descriptor.Wrappers.Add("Document"))
|
||||
.OnCreating(creating => creating.Behaviors.Add(new ZoneHoldingBehavior(() => creating.New.Zone(), null)))
|
||||
.OnCreating(creating => creating.Create = () => new ZoneHolding(() => creating.New.Zone()))
|
||||
.OnCreated(created => {
|
||||
var layout = created.Shape;
|
||||
|
||||
@ -68,7 +68,7 @@ namespace Orchard.Core.Shapes {
|
||||
// They have class="zone zone-{name}"
|
||||
// and the template can be specialized with "Zone-{Name}" base file name
|
||||
builder.Describe("Zone")
|
||||
.OnCreating(creating => creating.BaseType = typeof(Zone))
|
||||
.OnCreating(creating => creating.Create = () => new Zone())
|
||||
.OnDisplaying(displaying => {
|
||||
var zone = displaying.Shape;
|
||||
string zoneName = zone.ZoneName;
|
||||
|
@ -21,6 +21,10 @@
|
||||
<UpgradeBackupLocation>
|
||||
</UpgradeBackupLocation>
|
||||
<OldToolsVersion>4.0</OldToolsVersion>
|
||||
<IISExpressSSLPort />
|
||||
<IISExpressAnonymousAuthentication />
|
||||
<IISExpressWindowsAuthentication />
|
||||
<IISExpressUseClassicPipelineMode />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@ -41,7 +45,6 @@
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="ClaySharp, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.ComponentModel.DataAnnotations" />
|
||||
|
@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Routing;
|
||||
using ClaySharp.Implementation;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
@ -215,8 +214,9 @@ namespace Orchard.ContentTypes.Services {
|
||||
}
|
||||
|
||||
private dynamic CreateItemShape(string actualShapeType) {
|
||||
var zoneHoldingBehavior = new ZoneHoldingBehavior((Func<dynamic>)(() => _shapeFactory.Create("ContentZone", Arguments.Empty())), _workContextAccessor.GetContext().Layout);
|
||||
return _shapeFactory.Create(actualShapeType, Arguments.Empty(), new[] { zoneHoldingBehavior });
|
||||
var zoneHolding = new ZoneHolding(() => _shapeFactory.Create("ContentZone", Arguments.Empty()));
|
||||
zoneHolding.Metadata.Type = actualShapeType;
|
||||
return zoneHolding;
|
||||
}
|
||||
|
||||
private void BindPlacement(BuildShapeContext context, string displayType, string stereotype) {
|
||||
|
@ -21,6 +21,10 @@
|
||||
</UpgradeBackupLocation>
|
||||
<TargetFrameworkProfile />
|
||||
<UseIISExpress>false</UseIISExpress>
|
||||
<IISExpressSSLPort />
|
||||
<IISExpressAnonymousAuthentication />
|
||||
<IISExpressWindowsAuthentication />
|
||||
<IISExpressUseClassicPipelineMode />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@ -42,10 +46,6 @@
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="ClaySharp">
|
||||
<HintPath>..\..\..\..\lib\claysharp\ClaySharp.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
|
@ -550,7 +550,7 @@ jQuery(function ($) {
|
||||
|
||||
var text = shapeNode.type;
|
||||
// add the hint to the tree node if available
|
||||
if (shapeNode.hint != '') {
|
||||
if (shapeNode.hint && shapeNode.hint != '') {
|
||||
text += ' [' + shapeNode.hint + ']';
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,6 @@ using System.Collections;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Xml.Linq;
|
||||
using ClaySharp;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.DisplayManagement;
|
||||
using Orchard.DisplayManagement.Shapes;
|
||||
@ -195,12 +194,19 @@ namespace Orchard.DesignerTools.Services {
|
||||
}
|
||||
|
||||
private void DumpShape(IShape shape) {
|
||||
var members = new Dictionary<string, object>();
|
||||
((IClayBehaviorProvider) (dynamic) shape).Behavior.GetMembers(() => null, shape, members);
|
||||
var value = shape as Shape;
|
||||
|
||||
foreach (var key in members.Keys.Where(key => !key.StartsWith("_"))) {
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (DictionaryEntry entry in value.Properties) {
|
||||
// ignore private members (added dynamically by the shape wrapper)
|
||||
Dump(members[key], key);
|
||||
if (entry.Key.ToString().StartsWith("_")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Dump(entry.Value, entry.Key.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,9 +46,6 @@
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="ClaySharp">
|
||||
<HintPath>..\..\..\..\lib\claysharp\ClaySharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>..\..\..\..\lib\newtonsoft.json\Newtonsoft.Json.dll</HintPath>
|
||||
|
@ -26,8 +26,8 @@ namespace Orchard.Forms.Shapes {
|
||||
builder.Describe("Input").Configure(descriptor => descriptor.Wrappers.Add("InputWrapper"));
|
||||
builder.Describe("SelectList").Configure(descriptor => descriptor.Wrappers.Add("InputWrapper"));
|
||||
builder.Describe("Textarea").Configure(descriptor => descriptor.Wrappers.Add("InputWrapper"));
|
||||
builder.Describe("Form").OnCreating(ctx => ctx.Behaviors.Add(new PropertiesAreItems()));
|
||||
builder.Describe("Fieldset").OnCreating(ctx => ctx.Behaviors.Add(new PropertiesAreItems()));
|
||||
builder.Describe("Form").OnCreating(ctx => ctx.Create = () => new PropertiesAreItems());
|
||||
builder.Describe("Fieldset").OnCreating(ctx => ctx.Create = () => new PropertiesAreItems());
|
||||
}
|
||||
|
||||
[Shape]
|
||||
|
@ -1,26 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Orchard.DisplayManagement;
|
||||
using ClaySharp;
|
||||
using Orchard.DisplayManagement.Shapes;
|
||||
|
||||
namespace Orchard.Forms.Shapes {
|
||||
public class PropertiesAreItems : ClayBehavior {
|
||||
public override object SetMember(Func<object> proceed, dynamic self, string name, object value) {
|
||||
Patch(self, name, value);
|
||||
return proceed();
|
||||
public class PropertiesAreItems : Composite {
|
||||
public override bool TrySetMember(System.Dynamic.SetMemberBinder binder, object value) {
|
||||
Patch(this, binder.Name, value);
|
||||
return base.TrySetMember(binder, value);
|
||||
}
|
||||
|
||||
public override object SetIndex(Func<object> proceed, dynamic self, IEnumerable<object> keys, object value) {
|
||||
if (keys.Count() == 1 && keys.All(k => k is string))
|
||||
Patch(self, System.Convert.ToString(keys.Single()), value);
|
||||
return proceed();
|
||||
public override bool TrySetIndex(System.Dynamic.SetIndexBinder binder, object[] indexes, object value) {
|
||||
if (indexes.Count() == 1 && indexes.All(k => k is string))
|
||||
Patch(this, System.Convert.ToString(indexes.Single()), value);
|
||||
return base.TrySetIndex(binder, indexes, value);
|
||||
}
|
||||
|
||||
public override object InvokeMember(Func<object> proceed, dynamic self, string name, INamedEnumerable<object> args) {
|
||||
if (args.Count() == 1 && args.Named.Count() == 0)
|
||||
Patch(self, name, args.Single());
|
||||
return proceed();
|
||||
public override bool TryInvokeMember(System.Dynamic.InvokeMemberBinder binder, object[] args, out object result) {
|
||||
var arguments = Arguments.From(args, binder.CallInfo.ArgumentNames);
|
||||
if (args.Count() == 1 && !arguments.Named.Any())
|
||||
Patch(this, binder.Name, args.Single());
|
||||
return base.TryInvokeMember(binder, args, out result);
|
||||
}
|
||||
|
||||
readonly IDictionary<string, object> _assigned = new Dictionary<string, object>();
|
||||
|
@ -21,6 +21,10 @@
|
||||
</UpgradeBackupLocation>
|
||||
<TargetFrameworkProfile />
|
||||
<UseIISExpress>false</UseIISExpress>
|
||||
<IISExpressSSLPort />
|
||||
<IISExpressAnonymousAuthentication />
|
||||
<IISExpressWindowsAuthentication />
|
||||
<IISExpressUseClassicPipelineMode />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@ -42,7 +46,6 @@
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="ClaySharp, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
|
@ -50,9 +50,6 @@
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\..\lib\autofac\Autofac.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ClaySharp">
|
||||
<HintPath>..\..\..\..\lib\claysharp\ClaySharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.ComponentModel.DataAnnotations">
|
||||
|
@ -30,7 +30,11 @@
|
||||
: null;
|
||||
|
||||
IHtmlString sectionHeaderMarkup;
|
||||
if (firstOfTheSecond != null && firstLevelMenuItem.LinkToFirstChild && (firstOfTheSecond.RouteValues != null || HasText(firstOfTheSecond.Url))) {
|
||||
if (firstOfTheSecond != null
|
||||
&& firstLevelMenuItem.LinkToFirstChild
|
||||
&& (
|
||||
firstOfTheSecond.RouteValues != null
|
||||
|| HasText(firstOfTheSecond.Url))) {
|
||||
sectionHeaderMarkup = HasText(itemId)
|
||||
? Html.Link(sectionHeaderText, (string)firstOfTheSecond.Href, new { @class = itemClassName, id = itemId })
|
||||
: Html.Link(sectionHeaderText, (string)firstOfTheSecond.Href, new { @class = itemClassName });
|
||||
@ -72,7 +76,7 @@
|
||||
<ul class="menuItems">
|
||||
@foreach (var secondLevelMenuItem in secondLevelMenuItems.Where(menuItem => !menuItem.LocalNav)) {
|
||||
string secondLevelTextHint = secondLevelMenuItem.Text.TextHint;
|
||||
var firstOfTheThird = ((IEnumerable<dynamic>)secondLevelMenuItem).FirstOrDefault();
|
||||
var firstOfTheThird = ((IEnumerable<dynamic>)secondLevelMenuItem.Items).FirstOrDefault();
|
||||
|
||||
var secondLevelItemClassName = HasText(secondLevelTextHint)
|
||||
? "subnavicon-" + secondLevelTextHint.HtmlClassify()
|
||||
|
@ -10,36 +10,32 @@
|
||||
<configuration>
|
||||
<configSections>
|
||||
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
|
||||
<remove name="host" />
|
||||
<remove name="pages" />
|
||||
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
|
||||
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
|
||||
<remove name="host"/>
|
||||
<remove name="pages"/>
|
||||
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false"/>
|
||||
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false"/>
|
||||
</sectionGroup>
|
||||
|
||||
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" requirePermission="false" />
|
||||
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" requirePermission="false"/>
|
||||
</configSections>
|
||||
|
||||
<appSettings>
|
||||
<add key="webpages:Enabled" value="false" />
|
||||
<add key="log4net.Config" value="Config\log4net.config" />
|
||||
<add key="webpages:Enabled" value="false"/>
|
||||
<add key="log4net.Config" value="Config\log4net.config"/>
|
||||
</appSettings>
|
||||
|
||||
<system.web.webPages.razor>
|
||||
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
|
||||
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
|
||||
<pages pageBaseType="Orchard.Mvc.ViewEngines.Razor.WebViewPage">
|
||||
<namespaces>
|
||||
<add namespace="System.Web.Mvc" />
|
||||
<add namespace="System.Web.Mvc.Ajax" />
|
||||
<add namespace="System.Web.Mvc.Html" />
|
||||
<add namespace="System.Web.Routing" />
|
||||
<add namespace="System.Web.WebPages" />
|
||||
<add namespace="System.Web.Mvc"/>
|
||||
<add namespace="System.Web.Mvc.Ajax"/>
|
||||
<add namespace="System.Web.Mvc.Html"/>
|
||||
<add namespace="System.Web.Routing"/>
|
||||
<add namespace="System.Web.WebPages"/>
|
||||
<add namespace="System.Linq"/>
|
||||
<add namespace="System.Collections.Generic"/>
|
||||
<add namespace="Orchard.Mvc.Html"/>
|
||||
</namespaces>
|
||||
</pages>
|
||||
</system.web.webPages.razor>
|
||||
|
||||
<!--
|
||||
Set default transaction timeout to 30 minutes so that interactive debugging
|
||||
is easier (default timeout is less than one minute)
|
||||
@ -49,8 +45,7 @@
|
||||
</system.transactions>
|
||||
<system.web>
|
||||
<!--<trust level="Medium" originUrl="" />-->
|
||||
|
||||
<httpRuntime requestValidationMode="2.0" />
|
||||
<httpRuntime requestValidationMode="2.0"/>
|
||||
<!--
|
||||
Set compilation debug="true" to insert debugging
|
||||
symbols into the compiled page. Because this
|
||||
@ -58,7 +53,7 @@
|
||||
during development.
|
||||
-->
|
||||
<compilation debug="false" targetFramework="4.0" batch="true" numRecompilesBeforeAppRestart="250" optimizeCompilations="true">
|
||||
<buildProviders>
|
||||
<buildProviders>
|
||||
<add extension=".csproj" type="Orchard.Environment.Extensions.Compilers.CSharpExtensionBuildProviderShim"/>
|
||||
</buildProviders>
|
||||
<assemblies>
|
||||
@ -66,24 +61,24 @@
|
||||
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"/>
|
||||
<add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"/>
|
||||
<add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
|
||||
<remove assembly="System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<remove assembly="System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<remove assembly="System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<remove assembly="System.Web.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<remove assembly="System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<remove assembly="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<remove assembly="System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<remove assembly="System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<remove assembly="System.Runtime.Serialization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<remove assembly="System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<remove assembly="System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
|
||||
<remove assembly="System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
|
||||
<remove assembly="System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
|
||||
<remove assembly="System.Web.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
|
||||
<remove assembly="System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
|
||||
<remove assembly="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
|
||||
<remove assembly="System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
|
||||
<remove assembly="System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
|
||||
<remove assembly="System.Runtime.Serialization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
|
||||
<remove assembly="System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
|
||||
<remove assembly="System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
|
||||
<remove assembly="System.ServiceModel.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
|
||||
<remove assembly="System.Activities, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
|
||||
<remove assembly="System.ServiceModel.Activities, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
|
||||
<remove assembly="System.WorkflowServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
|
||||
<remove assembly="System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
|
||||
<remove assembly="System.Data.DataSetExtensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<remove assembly="System.Web.ApplicationServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
|
||||
<remove assembly="System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
|
||||
<remove assembly="System.Data.DataSetExtensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
|
||||
<remove assembly="System.Web.ApplicationServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
|
||||
</assemblies>
|
||||
</compilation>
|
||||
<!--
|
||||
@ -94,7 +89,6 @@
|
||||
<authentication mode="Forms">
|
||||
<forms loginUrl="~/Users/Account/AccessDenied" timeout="2880"/>
|
||||
</authentication>
|
||||
|
||||
<!--
|
||||
The <customErrors> section enables configuration
|
||||
of what to do if/when an unhandled error occurs
|
||||
@ -102,7 +96,7 @@
|
||||
it enables developers to configure html error pages
|
||||
to be displayed in place of a error stack trace.
|
||||
-->
|
||||
<customErrors mode="RemoteOnly" />
|
||||
<customErrors mode="RemoteOnly"/>
|
||||
<pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID">
|
||||
<namespaces>
|
||||
<add namespace="System.Web.Mvc"/>
|
||||
@ -114,14 +108,11 @@
|
||||
<add namespace="Orchard.Mvc.Html"/>
|
||||
</namespaces>
|
||||
</pages>
|
||||
|
||||
<httpHandlers>
|
||||
<!-- see below -->
|
||||
<clear />
|
||||
<clear/>
|
||||
<add path="*" verb="*" type="System.Web.HttpNotFoundHandler"/>
|
||||
|
||||
</httpHandlers>
|
||||
|
||||
<httpModules>
|
||||
<add name="WarmupHttpModule" type="Orchard.WarmupStarter.WarmupHttpModule, Orchard.WarmupStarter, Version=1.0.20, Culture=neutral"/>
|
||||
</httpModules>
|
||||
@ -131,10 +122,9 @@
|
||||
Information Services 7.0. It is not necessary for previous version of IIS.
|
||||
-->
|
||||
<system.webServer>
|
||||
|
||||
<validation validateIntegratedModeConfiguration="false" />
|
||||
<validation validateIntegratedModeConfiguration="false"/>
|
||||
<modules runAllManagedModulesForAllRequests="true">
|
||||
<remove name="WarmupHttpModule" />
|
||||
<remove name="WarmupHttpModule"/>
|
||||
<add name="WarmupHttpModule" type="Orchard.WarmupStarter.WarmupHttpModule, Orchard.WarmupStarter, Version=1.0.20, Culture=neutral"/>
|
||||
</modules>
|
||||
<handlers accessPolicy="Script">
|
||||
@ -142,18 +132,16 @@
|
||||
<clear/>
|
||||
<!-- Return 404 for all requests via managed handler. The url routing handler will substitute the mvc request handler when routes match. -->
|
||||
<add name="NotFound" path="*" verb="*" type="System.Web.HttpNotFoundHandler" preCondition="integratedMode" requireAccess="Script"/>
|
||||
|
||||
<!-- WebApi -->
|
||||
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
|
||||
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
|
||||
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
|
||||
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||
|
||||
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit"/>
|
||||
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit"/>
|
||||
<remove name="ExtensionlessUrlHandler-Integrated-4.0"/>
|
||||
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0"/>
|
||||
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0"/>
|
||||
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0"/>
|
||||
</handlers>
|
||||
<!-- Prevent IIS 7.0 from returning a custom 404/500 error page of its own -->
|
||||
<httpErrors existingResponse="PassThrough" />
|
||||
<httpErrors existingResponse="PassThrough"/>
|
||||
</system.webServer>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
@ -162,42 +150,34 @@
|
||||
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0"/>
|
||||
</dependentAssembly>
|
||||
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
|
||||
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0"/>
|
||||
</dependentAssembly>
|
||||
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.Razor" publicKeyToken="31bf3856ad364e35" />
|
||||
<assemblyIdentity name="System.Web.Razor" publicKeyToken="31bf3856ad364e35"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0"/>
|
||||
</dependentAssembly>
|
||||
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
|
||||
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0"/>
|
||||
</dependentAssembly>
|
||||
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.WebPages.Deployment" publicKeyToken="31bf3856ad364e35" />
|
||||
<assemblyIdentity name="System.Web.WebPages.Deployment" publicKeyToken="31bf3856ad364e35"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0"/>
|
||||
</dependentAssembly>
|
||||
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.WebPages.Razor" publicKeyToken="31bf3856ad364e35" />
|
||||
<assemblyIdentity name="System.Web.WebPages.Razor" publicKeyToken="31bf3856ad364e35"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0"/>
|
||||
</dependentAssembly>
|
||||
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="NHibernate" publicKeyToken="aa95f207798dfdb4" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.3.1.4000" newVersion="3.3.1.4000" />
|
||||
<assemblyIdentity name="NHibernate" publicKeyToken="aa95f207798dfdb4" culture="neutral"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.3.1.4000" newVersion="3.3.1.4000"/>
|
||||
</dependentAssembly>
|
||||
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Autofac" publicKeyToken="17863af14b0044da" />
|
||||
<bindingRedirect oldVersion="2.2.0.0-2.6.3.862" newVersion="2.6.3.862" />
|
||||
<assemblyIdentity name="Autofac" publicKeyToken="17863af14b0044da"/>
|
||||
<bindingRedirect oldVersion="2.2.0.0-2.6.3.862" newVersion="2.6.3.862"/>
|
||||
</dependentAssembly>
|
||||
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
||||
</configuration>
|
@ -2,15 +2,12 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Dynamic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using ClaySharp;
|
||||
using Orchard.ContentManagement.MetaData.Models;
|
||||
using Orchard.ContentManagement.Records;
|
||||
|
||||
namespace Orchard.ContentManagement {
|
||||
public class ContentItem : IContent, IContentBehavior, IDynamicMetaObjectProvider {
|
||||
public class ContentItem : DynamicObject, IContent {
|
||||
public ContentItem() {
|
||||
_behavior = new ClayBehaviorCollection(new[] { new ContentItemBehavior(this) });
|
||||
_parts = new List<ContentPart>();
|
||||
}
|
||||
|
||||
@ -45,14 +42,20 @@ namespace Orchard.ContentManagement {
|
||||
_parts.Add(part);
|
||||
}
|
||||
|
||||
public override bool TryGetMember(GetMemberBinder binder, out object result) {
|
||||
|
||||
private readonly IClayBehavior _behavior;
|
||||
IClayBehavior IContentBehavior.Behavior {
|
||||
get { return _behavior; }
|
||||
}
|
||||
DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression parameter) {
|
||||
return new ClayMetaObject(this, parameter, ex => Expression.Property(Expression.Convert(ex, typeof(IContentBehavior)), "Behavior"));
|
||||
}
|
||||
var found = base.TryGetMember(binder, out result);
|
||||
if (!found) {
|
||||
foreach (var part in Parts) {
|
||||
if (part.PartDefinition.Name == binder.Name) {
|
||||
result = part;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
using System;
|
||||
using ClaySharp;
|
||||
|
||||
namespace Orchard.ContentManagement {
|
||||
public class ContentItemBehavior : ClayBehavior {
|
||||
private readonly IContent _content;
|
||||
|
||||
public ContentItemBehavior(IContent content) {
|
||||
_content = content;
|
||||
}
|
||||
|
||||
public override object GetMemberMissing(Func<object> proceed, object self, string name) {
|
||||
var contentItem = _content.ContentItem;
|
||||
foreach (var part in contentItem.Parts) {
|
||||
if (part.PartDefinition.Name == name)
|
||||
return part;
|
||||
}
|
||||
return base.GetMemberMissing(proceed, self, name);
|
||||
}
|
||||
}
|
||||
}
|
@ -2,19 +2,16 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Dynamic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Web.Mvc;
|
||||
using ClaySharp;
|
||||
using Orchard.ContentManagement.MetaData.Models;
|
||||
using Orchard.ContentManagement.Utilities;
|
||||
using Orchard.UI;
|
||||
|
||||
namespace Orchard.ContentManagement {
|
||||
public class ContentPart : IContent, IContentBehavior, IDynamicMetaObjectProvider {
|
||||
public class ContentPart : DynamicObject, IContent {
|
||||
private readonly IList<ContentField> _fields;
|
||||
|
||||
public ContentPart() {
|
||||
_behavior = new ClayBehaviorCollection(new[] { new ContentPartBehavior(this) });
|
||||
_fields = new List<ContentField>();
|
||||
}
|
||||
|
||||
@ -29,14 +26,6 @@ namespace Orchard.ContentManagement {
|
||||
}
|
||||
}
|
||||
|
||||
private readonly IClayBehavior _behavior;
|
||||
IClayBehavior IContentBehavior.Behavior {
|
||||
get { return _behavior; }
|
||||
}
|
||||
DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression parameter) {
|
||||
return new ClayMetaObject(this, parameter, ex => Expression.Property(Expression.Convert(ex, typeof(IContentBehavior)), "Behavior"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The ContentItem's identifier.
|
||||
/// </summary>
|
||||
@ -65,6 +54,28 @@ namespace Orchard.ContentManagement {
|
||||
_fields.Add(field);
|
||||
}
|
||||
|
||||
public override bool TryGetMember(GetMemberBinder binder, out object result) {
|
||||
|
||||
var found = base.TryGetMember(binder, out result);
|
||||
if (!found) {
|
||||
foreach (var part in ContentItem.Parts) {
|
||||
if (part.PartDefinition.Name == binder.Name) {
|
||||
result = part;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var field in Fields) {
|
||||
if (field.PartFieldDefinition.Name == binder.Name) {
|
||||
result = field;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,20 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Orchard.ContentManagement {
|
||||
public class ContentPartBehavior : ContentItemBehavior {
|
||||
private readonly ContentPart _contentPart;
|
||||
|
||||
public ContentPartBehavior(ContentPart contentPart)
|
||||
: base(contentPart) {
|
||||
_contentPart = contentPart;
|
||||
}
|
||||
|
||||
public override object GetMemberMissing(Func<object> proceed, object self, string name) {
|
||||
foreach (var field in _contentPart.Fields) {
|
||||
if (field.PartFieldDefinition.Name == name)
|
||||
return field;
|
||||
}
|
||||
return base.GetMemberMissing(proceed, self, name);
|
||||
}
|
||||
}
|
||||
}
|
@ -2,7 +2,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Web;
|
||||
using System.Web.Routing;
|
||||
using ClaySharp.Implementation;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.DisplayManagement;
|
||||
using Orchard.DisplayManagement.Descriptors;
|
||||
@ -110,8 +109,7 @@ namespace Orchard.ContentManagement {
|
||||
}
|
||||
|
||||
private dynamic CreateItemShape(string actualShapeType) {
|
||||
var zoneHoldingBehavior = new ZoneHoldingBehavior((Func<dynamic>)(() => _shapeFactory.Create("ContentZone", Arguments.Empty())), _workContextAccessor.GetContext().Layout);
|
||||
return _shapeFactory.Create(actualShapeType, Arguments.Empty(), new[] { zoneHoldingBehavior });
|
||||
return _shapeFactory.Create(actualShapeType, Arguments.Empty(), () => new ZoneHolding(() => _shapeFactory.Create("ContentZone", Arguments.Empty())));
|
||||
}
|
||||
|
||||
private void BindPlacement(BuildShapeContext context, string displayType, string stereotype) {
|
||||
|
@ -1,7 +0,0 @@
|
||||
using ClaySharp;
|
||||
|
||||
namespace Orchard.ContentManagement {
|
||||
public interface IContentBehavior {
|
||||
IClayBehavior Behavior { get; }
|
||||
}
|
||||
}
|
152
src/Orchard/DisplayManagement/Arguments.cs
Normal file
152
src/Orchard/DisplayManagement/Arguments.cs
Normal file
@ -0,0 +1,152 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Orchard.DisplayManagement {
|
||||
public static class Arguments {
|
||||
public static INamedEnumerable<T> FromT<T>(IEnumerable<T> arguments, IEnumerable<string> names) {
|
||||
return new NamedEnumerable<T>(arguments, names);
|
||||
}
|
||||
|
||||
public static INamedEnumerable<object> From(IEnumerable<object> arguments, IEnumerable<string> names) {
|
||||
return new NamedEnumerable<object>(arguments, names);
|
||||
}
|
||||
|
||||
class NamedEnumerable<T> : INamedEnumerable<T> {
|
||||
readonly IEnumerable<T> _arguments;
|
||||
readonly IEnumerable<string> _names;
|
||||
|
||||
public NamedEnumerable(IEnumerable<T> arguments, IEnumerable<string> names) {
|
||||
if (arguments == null) {
|
||||
throw new ArgumentNullException("arguments");
|
||||
}
|
||||
if (names == null) {
|
||||
throw new ArgumentNullException("names");
|
||||
}
|
||||
if (arguments.Count() < names.Count()) {
|
||||
throw new ArgumentException("arguments.Count() < names.Count()");
|
||||
}
|
||||
|
||||
_arguments = arguments;
|
||||
_names = names;
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() {
|
||||
return _arguments.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator<T> IEnumerable<T>.GetEnumerator() {
|
||||
return _arguments.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerable<T> INamedEnumerable<T>.Positional {
|
||||
get { return _arguments.Take(_arguments.Count() - _names.Count()); }
|
||||
}
|
||||
|
||||
IDictionary<string, T> INamedEnumerable<T>.Named {
|
||||
get { return new Named(_arguments, _names); }
|
||||
}
|
||||
|
||||
class Named : IDictionary<string, T> {
|
||||
private readonly IEnumerable<T> _arguments;
|
||||
private readonly IEnumerable<string> _names;
|
||||
|
||||
private ICollection<T> _argumentsCollection;
|
||||
private ICollection<string> _namesCollection;
|
||||
|
||||
public Named(IEnumerable<T> arguments, IEnumerable<string> names) {
|
||||
_arguments = arguments.Skip(arguments.Count() - names.Count());
|
||||
_names = names;
|
||||
}
|
||||
|
||||
IEnumerable<KeyValuePair<string, T>> MakeEnumerable() {
|
||||
return _arguments.Zip(_names, (arg, name) => new KeyValuePair<string, T>(name, arg));
|
||||
}
|
||||
|
||||
IEnumerator<KeyValuePair<string, T>> IEnumerable<KeyValuePair<string, T>>.GetEnumerator() {
|
||||
return MakeEnumerable().GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() {
|
||||
return MakeEnumerable().GetEnumerator();
|
||||
}
|
||||
|
||||
void ICollection<KeyValuePair<string, T>>.Add(KeyValuePair<string, T> item) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void ICollection<KeyValuePair<string, T>>.Clear() {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
bool ICollection<KeyValuePair<string, T>>.Contains(KeyValuePair<string, T> item) {
|
||||
return MakeEnumerable().Contains(item);
|
||||
}
|
||||
|
||||
void ICollection<KeyValuePair<string, T>>.CopyTo(KeyValuePair<string, T>[] array, int arrayIndex) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
bool ICollection<KeyValuePair<string, T>>.Remove(KeyValuePair<string, T> item) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
int ICollection<KeyValuePair<string, T>>.Count {
|
||||
get { return _names.Count(); }
|
||||
}
|
||||
|
||||
bool ICollection<KeyValuePair<string, T>>.IsReadOnly {
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
bool IDictionary<string, T>.ContainsKey(string key) {
|
||||
return _names.Contains(key);
|
||||
}
|
||||
|
||||
void IDictionary<string, T>.Add(string key, T value) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
bool IDictionary<string, T>.Remove(string key) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
bool IDictionary<string, T>.TryGetValue(string key, out T value) {
|
||||
var pair = MakeEnumerable().FirstOrDefault(kv => kv.Key == key);
|
||||
|
||||
// pair is a value type. in case of key-miss,
|
||||
// will default to key=(string)null,value=(object)null
|
||||
|
||||
value = pair.Value;
|
||||
return pair.Key != null;
|
||||
}
|
||||
|
||||
//TBD
|
||||
T IDictionary<string, T>.this[string key] {
|
||||
get {
|
||||
return MakeEnumerable()
|
||||
.Where(kv => kv.Key == key)
|
||||
.Select(kv => kv.Value)
|
||||
.FirstOrDefault();
|
||||
}
|
||||
set { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
ICollection<string> IDictionary<string, T>.Keys {
|
||||
get {
|
||||
return _namesCollection = _namesCollection ?? _names as ICollection<string> ?? _names.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
ICollection<T> IDictionary<string, T>.Values {
|
||||
get { return _argumentsCollection = _argumentsCollection ?? _arguments as ICollection<T> ?? _arguments.ToArray(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static INamedEnumerable<object> Empty() {
|
||||
return From(Enumerable.Empty<object>(), Enumerable.Empty<string>());
|
||||
}
|
||||
}
|
||||
}
|
8
src/Orchard/DisplayManagement/INamedEnumerable.cs
Normal file
8
src/Orchard/DisplayManagement/INamedEnumerable.cs
Normal file
@ -0,0 +1,8 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Orchard.DisplayManagement {
|
||||
public interface INamedEnumerable<T> : IEnumerable<T> {
|
||||
IEnumerable<T> Positional { get; }
|
||||
IDictionary<string, T> Named { get; }
|
||||
}
|
||||
}
|
@ -1,6 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using ClaySharp;
|
||||
using ClaySharp.Implementation;
|
||||
using System;
|
||||
|
||||
namespace Orchard.DisplayManagement {
|
||||
/// <summary>
|
||||
@ -9,7 +7,7 @@ namespace Orchard.DisplayManagement {
|
||||
/// </summary>
|
||||
public interface IShapeFactory : IDependency {
|
||||
IShape Create(string shapeType, INamedEnumerable<object> parameters);
|
||||
IShape Create(string shapeType, INamedEnumerable<object> parameters, IEnumerable<IClayBehavior> behaviors);
|
||||
IShape Create(string shapeType, INamedEnumerable<object> parameters, Func<dynamic> createShape);
|
||||
}
|
||||
|
||||
public static class ShapeFactoryExtensions {
|
||||
|
@ -1,35 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ClaySharp;
|
||||
using Orchard.DisplayManagement.Descriptors;
|
||||
using Orchard.DisplayManagement.Shapes;
|
||||
|
||||
namespace Orchard.DisplayManagement.Implementation {
|
||||
|
||||
public class DefaultShapeFactory : Clay, IShapeFactory {
|
||||
public class DefaultShapeFactory : Composite, IShapeFactory {
|
||||
private readonly IEnumerable<Lazy<IShapeFactoryEvents>> _events;
|
||||
private readonly Lazy<IShapeTableLocator> _shapeTableLocator;
|
||||
|
||||
public DefaultShapeFactory(
|
||||
IEnumerable<Lazy<IShapeFactoryEvents>> events,
|
||||
Lazy<IShapeTableLocator> shapeTableLocator) : base(new ShapeFactoryBehavior())
|
||||
Lazy<IShapeTableLocator> shapeTableLocator)
|
||||
{
|
||||
_events = events;
|
||||
_shapeTableLocator = shapeTableLocator;
|
||||
}
|
||||
|
||||
class ShapeFactoryBehavior : ClayBehavior {
|
||||
public override object InvokeMember(Func<object> proceed, object target, string name, INamedEnumerable<object> args) {
|
||||
return ((DefaultShapeFactory)target).Create(name, args);
|
||||
}
|
||||
|
||||
public override bool TryInvokeMember(System.Dynamic.InvokeMemberBinder binder, object[] args, out object result) {
|
||||
result = Create(binder.Name, Arguments.From(args, binder.CallInfo.ArgumentNames));
|
||||
return true;
|
||||
}
|
||||
|
||||
public IShape Create(string shapeType, INamedEnumerable<object> parameters) {
|
||||
return Create(shapeType, parameters, Enumerable.Empty<IClayBehavior>());
|
||||
return Create(shapeType, parameters, () => new Shape());
|
||||
}
|
||||
|
||||
public IShape Create(string shapeType, INamedEnumerable<object> parameters, IEnumerable<IClayBehavior> behaviors) {
|
||||
public IShape Create(string shapeType, INamedEnumerable<object> parameters, Func<dynamic> createShape) {
|
||||
var defaultShapeTable = _shapeTableLocator.Value.Lookup(null);
|
||||
ShapeDescriptor shapeDescriptor;
|
||||
defaultShapeTable.Descriptors.TryGetValue(shapeType, out shapeDescriptor);
|
||||
@ -40,42 +38,20 @@ namespace Orchard.DisplayManagement.Implementation {
|
||||
ShapeType = shapeType,
|
||||
OnCreated = new List<Action<ShapeCreatedContext>>()
|
||||
};
|
||||
var positional = parameters.Positional;
|
||||
|
||||
creatingContext.BaseType = positional.Take(1).OfType<Type>().SingleOrDefault();
|
||||
if (creatingContext.BaseType == null) {
|
||||
IEnumerable<object> positional = parameters.Positional.ToList();
|
||||
var baseType = positional.FirstOrDefault() as Type;
|
||||
|
||||
if (baseType == null) {
|
||||
// default to common base class
|
||||
creatingContext.BaseType = typeof(Shape);
|
||||
creatingContext.Create = createShape ?? (() => new Shape());
|
||||
}
|
||||
else {
|
||||
// consume the first argument
|
||||
positional = positional.Skip(1);
|
||||
}
|
||||
|
||||
if (creatingContext.BaseType == typeof(Array)) {
|
||||
// array is a hint - not an intended base class
|
||||
creatingContext.BaseType = typeof(Shape);
|
||||
creatingContext.Behaviors = new List<IClayBehavior> {
|
||||
new ClaySharp.Behaviors.InterfaceProxyBehavior(),
|
||||
new ClaySharp.Behaviors.PropBehavior(),
|
||||
new ClaySharp.Behaviors.ArrayBehavior(),
|
||||
new ClaySharp.Behaviors.NilResultBehavior(),
|
||||
};
|
||||
}
|
||||
else {
|
||||
creatingContext.Behaviors = new List<IClayBehavior> {
|
||||
new ClaySharp.Behaviors.InterfaceProxyBehavior(),
|
||||
new ClaySharp.Behaviors.PropBehavior(),
|
||||
new ClaySharp.Behaviors.NilResultBehavior(),
|
||||
new Shape.ShapeBehavior(),
|
||||
};
|
||||
creatingContext.Create = () => Activator.CreateInstance(baseType);
|
||||
}
|
||||
|
||||
if (behaviors != null && behaviors.Any()) {
|
||||
// include behaviors passed in by caller, if any
|
||||
creatingContext.Behaviors = creatingContext.Behaviors.Concat(behaviors).ToList();
|
||||
}
|
||||
|
||||
// "creating" events may add behaviors and alter base type)
|
||||
foreach (var ev in _events) {
|
||||
ev.Value.Creating(creatingContext);
|
||||
@ -90,10 +66,15 @@ namespace Orchard.DisplayManagement.Implementation {
|
||||
var createdContext = new ShapeCreatedContext {
|
||||
New = creatingContext.New,
|
||||
ShapeType = creatingContext.ShapeType,
|
||||
Shape = ClayActivator.CreateInstance(creatingContext.BaseType, creatingContext.Behaviors)
|
||||
Shape = creatingContext.Create()
|
||||
};
|
||||
var shapeMetadata = new ShapeMetadata { Type = shapeType };
|
||||
createdContext.Shape.Metadata = shapeMetadata;
|
||||
|
||||
if (!(createdContext.Shape is IShape)) {
|
||||
throw new InvalidOperationException("Invalid base type for shape: " + createdContext.Shape.GetType().ToString());
|
||||
}
|
||||
|
||||
ShapeMetadata shapeMetadata = createdContext.Shape.Metadata;
|
||||
createdContext.Shape.Metadata.Type = shapeType;
|
||||
|
||||
if (shapeDescriptor != null)
|
||||
shapeMetadata.Wrappers = shapeMetadata.Wrappers.Concat(shapeDescriptor.Wrappers).ToList();
|
||||
|
@ -1,17 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Dynamic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using ClaySharp;
|
||||
|
||||
namespace Orchard.DisplayManagement.Implementation {
|
||||
|
||||
/// <summary>
|
||||
/// Refactor: I this doesn't really need to exist, does it?
|
||||
/// It can all be an aspect of a display helper behavior implementation...
|
||||
/// Or should this remain a CLR type for clarity?
|
||||
/// </summary>
|
||||
public class DisplayHelper {
|
||||
public class DisplayHelper : DynamicObject {
|
||||
private readonly IDisplayManager _displayManager;
|
||||
private readonly IShapeFactory _shapeFactory;
|
||||
|
||||
@ -29,6 +24,16 @@ namespace Orchard.DisplayManagement.Implementation {
|
||||
public ViewContext ViewContext { get; set; }
|
||||
public IViewDataContainer ViewDataContainer { get; set; }
|
||||
|
||||
public override bool TryInvoke(InvokeBinder binder, object[] args, out object result) {
|
||||
result = Invoke(null, Arguments.From(args, binder.CallInfo.ArgumentNames));
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) {
|
||||
result = Invoke(binder.Name, Arguments.From(args, binder.CallInfo.ArgumentNames));
|
||||
return true;
|
||||
}
|
||||
|
||||
public object Invoke(string name, INamedEnumerable<object> parameters) {
|
||||
if (!string.IsNullOrEmpty(name)) {
|
||||
return ShapeTypeExecute(name, parameters);
|
||||
@ -67,6 +72,10 @@ namespace Orchard.DisplayManagement.Implementation {
|
||||
}
|
||||
|
||||
public object ShapeExecute(object shape) {
|
||||
if (shape == null) {
|
||||
return new HtmlString(string.Empty);
|
||||
}
|
||||
|
||||
var context = new DisplayContext { Display = this, Value = shape, ViewContext = ViewContext, ViewDataContainer = ViewDataContainer };
|
||||
return _displayManager.Execute(context);
|
||||
}
|
||||
|
@ -1,10 +1,7 @@
|
||||
using System;
|
||||
using System.Web.Mvc;
|
||||
using ClaySharp;
|
||||
using System.Web.Mvc;
|
||||
|
||||
namespace Orchard.DisplayManagement.Implementation {
|
||||
public class DisplayHelperFactory : IDisplayHelperFactory {
|
||||
static private readonly DisplayHelperBehavior[] _behaviors = new[] { new DisplayHelperBehavior() };
|
||||
private readonly IDisplayManager _displayManager;
|
||||
private readonly IShapeFactory _shapeFactory;
|
||||
|
||||
@ -14,20 +11,11 @@ namespace Orchard.DisplayManagement.Implementation {
|
||||
}
|
||||
|
||||
public dynamic CreateHelper(ViewContext viewContext, IViewDataContainer viewDataContainer) {
|
||||
return ClayActivator.CreateInstance<DisplayHelper>(
|
||||
_behaviors,
|
||||
return new DisplayHelper(
|
||||
_displayManager,
|
||||
_shapeFactory,
|
||||
viewContext,
|
||||
viewDataContainer);
|
||||
}
|
||||
|
||||
class DisplayHelperBehavior : ClayBehavior {
|
||||
public override object InvokeMember(Func<object> proceed, object target, string name, INamedEnumerable<object> args) {
|
||||
return ((DisplayHelper)target).Invoke(name, args);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ClaySharp;
|
||||
|
||||
namespace Orchard.DisplayManagement.Implementation {
|
||||
public interface IShapeFactoryEvents : IDependency {
|
||||
@ -12,8 +11,7 @@ namespace Orchard.DisplayManagement.Implementation {
|
||||
public IShapeFactory ShapeFactory { get; set; }
|
||||
public dynamic New { get; set; }
|
||||
public string ShapeType { get; set; }
|
||||
public Type BaseType { get; set; }
|
||||
public IList<IClayBehavior> Behaviors { get; set; }
|
||||
public Func<dynamic> Create { get; set; }
|
||||
public IList<Action<ShapeCreatedContext>> OnCreated { get; set; }
|
||||
}
|
||||
|
||||
|
137
src/Orchard/DisplayManagement/Shapes/Composite.cs
Normal file
137
src/Orchard/DisplayManagement/Shapes/Composite.cs
Normal file
@ -0,0 +1,137 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.Dynamic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace Orchard.DisplayManagement.Shapes {
|
||||
public class Composite : DynamicObject {
|
||||
private readonly IDictionary _props = new HybridDictionary();
|
||||
|
||||
public override bool TryGetMember(GetMemberBinder binder, out object result) {
|
||||
return TryGetMemberImpl(binder.Name, out result);
|
||||
}
|
||||
|
||||
protected bool TryGetMemberImpl(string name, out object result) {
|
||||
if (_props.Contains(name)) {
|
||||
result = _props[name];
|
||||
return true;
|
||||
}
|
||||
|
||||
result = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool TrySetMember(SetMemberBinder binder, object value) {
|
||||
return TrySetMemberImpl(binder.Name, value);
|
||||
}
|
||||
|
||||
protected bool TrySetMemberImpl(string name, object value) {
|
||||
_props[name] = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) {
|
||||
if (!args.Any()) {
|
||||
return TryGetMemberImpl(binder.Name, out result);
|
||||
}
|
||||
|
||||
// method call with one argument will assign the property
|
||||
if (args.Count() == 1) {
|
||||
result = this;
|
||||
return TrySetMemberImpl(binder.Name, args.Single());
|
||||
}
|
||||
|
||||
if (!base.TryInvokeMember(binder, args, out result)) {
|
||||
if (binder.Name == "ToString") {
|
||||
result = string.Empty;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result) {
|
||||
if (indexes.Count() != 1) {
|
||||
return base.TryGetIndex(binder, indexes, out result);
|
||||
}
|
||||
|
||||
var index = indexes.Single();
|
||||
|
||||
if (_props.Contains(index)) {
|
||||
result = _props[index];
|
||||
return true;
|
||||
}
|
||||
|
||||
// try to access an existing member
|
||||
var strinIndex = index as string;
|
||||
|
||||
if (strinIndex != null && TryGetMemberImpl(strinIndex, out result)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.TryGetIndex(binder, indexes, out result);
|
||||
}
|
||||
|
||||
public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value) {
|
||||
if (indexes.Count() != 1) {
|
||||
return base.TrySetIndex(binder, indexes, value);
|
||||
}
|
||||
|
||||
var index = indexes.Single();
|
||||
|
||||
// try to access an existing member
|
||||
var strinIndex = index as string;
|
||||
|
||||
if (strinIndex != null && TrySetMemberImpl(strinIndex, value)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
_props[indexes.Single()] = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
public IDictionary Properties {
|
||||
get { return _props; }
|
||||
}
|
||||
}
|
||||
|
||||
public class Nil : DynamicObject {
|
||||
static readonly object Singleton = new Nil();
|
||||
public static object Instance { get { return Singleton; } }
|
||||
|
||||
private Nil() {
|
||||
}
|
||||
|
||||
public override bool TryGetMember(GetMemberBinder binder, out object result) {
|
||||
result = Instance;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result) {
|
||||
result = Instance;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool TryBinaryOperation(BinaryOperationBinder binder, object arg, out object result) {
|
||||
switch (binder.Operation) {
|
||||
case ExpressionType.Equal:
|
||||
result = ReferenceEquals(arg, Nil.Instance) || arg == null;
|
||||
return true;
|
||||
case ExpressionType.NotEqual:
|
||||
result = !ReferenceEquals(arg, Nil.Instance) && arg != null;
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.TryBinaryOperation(binder, arg, out result);
|
||||
}
|
||||
|
||||
public override bool TryConvert(ConvertBinder binder, out object result) {
|
||||
result = null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,28 +1,31 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Dynamic;
|
||||
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))]
|
||||
public class Shape : IShape, IEnumerable {
|
||||
public class Shape : Composite, IShape, IEnumerable<object> {
|
||||
private const string DefaultPosition = "5";
|
||||
|
||||
private readonly IList<object> _items = new List<object>();
|
||||
private readonly IList<string> _classes = new List<string>();
|
||||
private readonly IDictionary<string, string> _attributes = new Dictionary<string, string>();
|
||||
|
||||
public virtual ShapeMetadata Metadata { get; set; }
|
||||
public ShapeMetadata Metadata { get; set; }
|
||||
|
||||
public virtual string Id { get; set; }
|
||||
public virtual IList<string> Classes { get { return _classes; } }
|
||||
public virtual IDictionary<string, string> Attributes { get { return _attributes; } }
|
||||
public virtual IEnumerable<dynamic> Items { get { return _items; } }
|
||||
|
||||
public Shape() {
|
||||
Metadata = new ShapeMetadata();
|
||||
}
|
||||
|
||||
public virtual Shape Add(object item, string position = null) {
|
||||
// pszmyd: Ignoring null shapes
|
||||
if (item == null) {
|
||||
@ -31,12 +34,12 @@ namespace Orchard.DisplayManagement.Shapes {
|
||||
|
||||
try {
|
||||
// todo: (sebros) this is a temporary implementation to prevent common known scenarios throwing exceptions. The final solution would need to filter based on the fact that it is a Shape instance
|
||||
if ( item is MvcHtmlString ||
|
||||
item is String ) {
|
||||
if (item is MvcHtmlString ||
|
||||
item is String) {
|
||||
// need to implement positioned wrapper for non-shape objects
|
||||
}
|
||||
else if (item is IShape) {
|
||||
((dynamic) item).Metadata.Position = position;
|
||||
((dynamic)item).Metadata.Position = position;
|
||||
}
|
||||
}
|
||||
catch {
|
||||
@ -53,126 +56,144 @@ namespace Orchard.DisplayManagement.Shapes {
|
||||
return this;
|
||||
}
|
||||
|
||||
IEnumerator<object> IEnumerable<object>.GetEnumerator() {
|
||||
return _items.GetEnumerator();
|
||||
}
|
||||
|
||||
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 bool TryConvert(ConvertBinder binder, out object result) {
|
||||
result = Items;
|
||||
|
||||
if (binder.ReturnType == typeof(IEnumerable<object>)
|
||||
|| binder.ReturnType == typeof(IEnumerable<dynamic>)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public override object InvokeMember(Func<object> proceed, dynamic self, string name, INamedEnumerable<object> args) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//public class ShapeBehavior : ClayBehavior {
|
||||
public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value) {
|
||||
if (indexes.Count() == 1) {
|
||||
var name = indexes.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(args.FirstOrDefault());
|
||||
}
|
||||
return self;
|
||||
Id = Convert.ToString(value);
|
||||
return true;
|
||||
}
|
||||
if (name.Equals("Classes") && !args.Named.Any()) {
|
||||
MergeClasses(args, self.Classes);
|
||||
return self;
|
||||
if (name.Equals("Classes")) {
|
||||
var args = Arguments.From(new[] { value }, Enumerable.Empty<string>());
|
||||
MergeClasses(args, Classes);
|
||||
return true;
|
||||
}
|
||||
if (name.Equals("Attributes") && args.Positional.Count() <= 1) {
|
||||
MergeAttributes(args, self.Attributes);
|
||||
return self;
|
||||
if (name.Equals("Attributes")) {
|
||||
var args = Arguments.From(new[] { value }, Enumerable.Empty<string>());
|
||||
MergeAttributes(args, Attributes);
|
||||
return true;
|
||||
}
|
||||
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);
|
||||
var args = Arguments.From(new[] { value }, Enumerable.Empty<string>());
|
||||
MergeItems(args, this);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
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("@", "");
|
||||
return base.TrySetIndex(binder, indexes, value);
|
||||
|
||||
}
|
||||
|
||||
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) {
|
||||
var name = binder.Name;
|
||||
var arguments = Arguments.From(args, binder.CallInfo.ArgumentNames);
|
||||
if (name.Equals("Id")) {
|
||||
// need to mutate the actual type
|
||||
Id = Convert.ToString(args.FirstOrDefault());
|
||||
result = this;
|
||||
return true;
|
||||
}
|
||||
if (name.Equals("Classes") && !arguments.Named.Any()) {
|
||||
MergeClasses(arguments, Classes);
|
||||
result = this;
|
||||
return true;
|
||||
}
|
||||
if (name.Equals("Attributes") && arguments.Positional.Count() <= 1) {
|
||||
MergeAttributes(arguments, Attributes);
|
||||
result = this;
|
||||
return true;
|
||||
}
|
||||
if (name.Equals("Items")) {
|
||||
MergeItems(arguments, this);
|
||||
result = this;
|
||||
return true;
|
||||
}
|
||||
|
||||
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);
|
||||
return base.TryInvokeMember(binder, args, out result);
|
||||
}
|
||||
|
||||
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[Convert.ToString(key)] = Convert.ToString(dictionary[key]);
|
||||
}
|
||||
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));
|
||||
}
|
||||
else {
|
||||
foreach (var prop in arg.GetType().GetProperties()) {
|
||||
attributes[TranslateIdentifier(prop.Name)] = Convert.ToString(prop.GetValue(arg, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (var named in args.Named) {
|
||||
attributes[named.Key] = Convert.ToString(named.Value);
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
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(Convert.ToString(item));
|
||||
}
|
||||
}
|
||||
else {
|
||||
classes.Add(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(Convert.ToString(arg));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using ClaySharp;
|
||||
|
||||
namespace Orchard.DisplayManagement.Shapes {
|
||||
public class ShapeDebugView {
|
||||
@ -19,12 +19,12 @@ namespace Orchard.DisplayManagement.Shapes {
|
||||
public IEnumerable<dynamic> Items { get { return _shape.Items; } }
|
||||
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
|
||||
public KeyValuePairs[] ClayProperties {
|
||||
public KeyValuePairs[] Properties {
|
||||
get {
|
||||
var members = new Dictionary<string, object>();
|
||||
((IClayBehaviorProvider)_shape).Behavior.GetMembers(() => null, _shape, members);
|
||||
|
||||
return members.Keys.Select(key => new KeyValuePairs(key, members[key])).ToArray();
|
||||
return _shape.Properties
|
||||
.Cast<DictionaryEntry>()
|
||||
.Select(entry => new KeyValuePairs(entry.Key, entry.Value))
|
||||
.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,20 +32,11 @@ namespace Orchard.DisplayManagement.Shapes {
|
||||
public class KeyValuePairs {
|
||||
|
||||
public KeyValuePairs(object key, object value) {
|
||||
try {
|
||||
var dynProxyGetTarget = value.GetType().GetMethod("DynProxyGetTarget");
|
||||
if (dynProxyGetTarget != null) {
|
||||
_value = dynProxyGetTarget.Invoke(value, null);
|
||||
_shapeType = ((IShape)_value).Metadata.Type;
|
||||
}
|
||||
else {
|
||||
_value = value;
|
||||
}
|
||||
}
|
||||
catch {
|
||||
_value = value;
|
||||
if (_value is IShape) {
|
||||
_shapeType = ((IShape)_value).Metadata.Type;
|
||||
}
|
||||
|
||||
_value = value;
|
||||
_key = key;
|
||||
}
|
||||
|
||||
|
@ -71,11 +71,6 @@
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\lib\Castle Windsor 2.0\bin\Castle.DynamicProxy2.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ClaySharp, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\lib\claysharp\ClaySharp.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="FluentNHibernate, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8aa435e3cb308880, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\lib\nhibernate\FluentNHibernate.dll</HintPath>
|
||||
@ -157,8 +152,6 @@
|
||||
<Compile Include="ContentManagement\Aspects\ITitleAspect.cs" />
|
||||
<Compile Include="ContentManagement\Aspects\ILocalizableAspect.cs" />
|
||||
<Compile Include="ContentManagement\ContentIdentity.cs" />
|
||||
<Compile Include="ContentManagement\ContentItemBehavior.cs" />
|
||||
<Compile Include="ContentManagement\ContentPartBehavior.cs" />
|
||||
<Compile Include="ContentManagement\DefaultHqlQuery.cs" />
|
||||
<Compile Include="ContentManagement\Handlers\UpdateContentContext.cs" />
|
||||
<Compile Include="ContentManagement\IHqlExpression.cs" />
|
||||
@ -172,12 +165,11 @@
|
||||
<Compile Include="ContentManagement\Handlers\BuildShapeContext.cs" />
|
||||
<Compile Include="ContentManagement\Handlers\ExportContentContext.cs" />
|
||||
<Compile Include="ContentManagement\Handlers\ImportContentContext.cs" />
|
||||
<Compile Include="ContentManagement\IContentBehavior.cs" />
|
||||
<Compile Include="ContentManagement\ImportContentSession.cs" />
|
||||
<Compile Include="ContentManagement\MetaData\Services\ISettingsFormatter.cs" />
|
||||
<Compile Include="ContentManagement\QueryHints.cs" />
|
||||
<Compile Include="ContentManagement\Utilities\ComputedField.cs" />
|
||||
<Compile Include="Data\Bags\SArray.cs" />
|
||||
<Compile Include="DisplayManagement\Arguments.cs" />
|
||||
<Compile Include="Data\Bags\SConvert.cs" />
|
||||
<Compile Include="Data\Bags\Serialization\IBagSerializer.cs" />
|
||||
<Compile Include="Data\Bags\Serialization\XmlSettingsSerializer.cs" />
|
||||
@ -204,6 +196,8 @@
|
||||
<Compile Include="DisplayManagement\Descriptors\ShapeTableLocator.cs" />
|
||||
<Compile Include="DisplayManagement\Implementation\IShapeDisplayEvents.cs" />
|
||||
<Compile Include="DisplayManagement\Implementation\IShapeFactoryEvents.cs" />
|
||||
<Compile Include="DisplayManagement\INamedEnumerable.cs" />
|
||||
<Compile Include="DisplayManagement\Shapes\Composite.cs" />
|
||||
<Compile Include="DisplayManagement\Shapes\ShapeDebugView.cs" />
|
||||
<Compile Include="DisplayManagement\Shapes\ITagBuilderFactory.cs" />
|
||||
<Compile Include="Environment\CollectionOrderModule.cs" />
|
||||
|
@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using ClaySharp.Implementation;
|
||||
using Orchard.DisplayManagement;
|
||||
|
||||
namespace Orchard.UI.Zones {
|
||||
|
@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using ClaySharp;
|
||||
using ClaySharp.Behaviors;
|
||||
using System.Linq.Expressions;
|
||||
using Orchard.DisplayManagement.Shapes;
|
||||
|
||||
namespace Orchard.UI.Zones {
|
||||
/// <summary>
|
||||
@ -17,102 +17,179 @@ namespace Orchard.UI.Zones {
|
||||
/// Foo.Alpha :same
|
||||
///
|
||||
/// </summary>
|
||||
public class ZoneHoldingBehavior : ClayBehavior {
|
||||
public class ZoneHolding : Shape {
|
||||
private readonly Func<dynamic> _zoneFactory;
|
||||
private readonly dynamic _layoutShape;
|
||||
|
||||
public ZoneHoldingBehavior(Func<dynamic> zoneFactory, dynamic layoutShape) {
|
||||
public ZoneHolding(Func<dynamic> zoneFactory) {
|
||||
_zoneFactory = zoneFactory;
|
||||
_layoutShape = layoutShape;
|
||||
}
|
||||
|
||||
public override object GetMember(Func<object> proceed, object self, string name) {
|
||||
if (name == "Zones") {
|
||||
// provide a robot for zone manipulation on parent object
|
||||
return ClayActivator.CreateInstance(new IClayBehavior[] {
|
||||
new InterfaceProxyBehavior(),
|
||||
new ZonesBehavior(_zoneFactory, self, _layoutShape)
|
||||
});
|
||||
private Zones _zones;
|
||||
public Zones Zones {
|
||||
get {
|
||||
if (_zones == null) {
|
||||
return _zones = new Zones(_zoneFactory, this);
|
||||
}
|
||||
|
||||
return _zones;
|
||||
}
|
||||
}
|
||||
|
||||
var result = proceed();
|
||||
if (((dynamic)result) == null) {
|
||||
public override bool TryGetMember(System.Dynamic.GetMemberBinder binder, out object result) {
|
||||
var name = binder.Name;
|
||||
|
||||
if (!base.TryGetMember(binder, out result) || ((dynamic)result) == null) {
|
||||
// substitute nil results with a robot that turns adds a zone on
|
||||
// the parent when .Add is invoked
|
||||
return ClayActivator.CreateInstance(new IClayBehavior[] {
|
||||
new InterfaceProxyBehavior(),
|
||||
new NilBehavior(),
|
||||
new ZoneOnDemandBehavior(_zoneFactory, self, name)
|
||||
});
|
||||
result = new ZoneOnDemand(_zoneFactory, this, name);
|
||||
TrySetMemberImpl(name, result);
|
||||
}
|
||||
return result;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public class ZonesBehavior : ClayBehavior {
|
||||
private readonly Func<dynamic> _zoneFactory;
|
||||
private object _parent;
|
||||
private readonly dynamic _layoutShape;
|
||||
}
|
||||
|
||||
public ZonesBehavior(Func<dynamic> zoneFactory, object parent, dynamic layoutShape) {
|
||||
_zoneFactory = zoneFactory;
|
||||
_parent = parent;
|
||||
_layoutShape = layoutShape;
|
||||
/// <remarks>
|
||||
/// InterfaceProxyBehavior()
|
||||
/// ZonesBehavior(_zoneFactory, self, _layoutShape) => Create ZoneOnDemand if member access
|
||||
/// </remarks>
|
||||
public class Zones : Composite {
|
||||
private readonly Func<dynamic> _zoneFactory;
|
||||
private readonly object _parent;
|
||||
|
||||
public Zones(Func<dynamic> zoneFactory, object parent) {
|
||||
_zoneFactory = zoneFactory;
|
||||
_parent = parent;
|
||||
}
|
||||
|
||||
public override bool TryGetMember(System.Dynamic.GetMemberBinder binder, out object result) {
|
||||
return TryGetMemberImpl(binder.Name, out result);
|
||||
}
|
||||
|
||||
private bool TryGetMemberImpl(string name, out object result) {
|
||||
|
||||
var parentMember = ((dynamic)_parent)[name];
|
||||
if (parentMember == null) {
|
||||
result = new ZoneOnDemand(_zoneFactory, _parent, name);
|
||||
return true;
|
||||
}
|
||||
|
||||
public override object GetMember(Func<object> proceed, object self, string name) {
|
||||
var parentMember = ((dynamic)_parent)[name];
|
||||
if (parentMember == null) {
|
||||
return ClayActivator.CreateInstance(new IClayBehavior[] {
|
||||
new InterfaceProxyBehavior(),
|
||||
new NilBehavior(),
|
||||
new ZoneOnDemandBehavior(_zoneFactory, _parent, name)
|
||||
});
|
||||
}
|
||||
return parentMember;
|
||||
}
|
||||
public override object GetIndex(Func<object> proceed, object self, System.Collections.Generic.IEnumerable<object> keys) {
|
||||
if (keys.Count() == 1) {
|
||||
var key = System.Convert.ToString(keys.Single());
|
||||
result = parentMember;
|
||||
return true;
|
||||
}
|
||||
|
||||
return GetMember(proceed, null, key);
|
||||
}
|
||||
return proceed();
|
||||
|
||||
public override bool TryGetIndex(System.Dynamic.GetIndexBinder binder, object[] indexes, out object result) {
|
||||
|
||||
if (indexes.Count() == 1) {
|
||||
var key = Convert.ToString(indexes.Single());
|
||||
|
||||
return TryGetMemberImpl(key, out result);
|
||||
}
|
||||
|
||||
return base.TryGetIndex(binder, indexes, out result);
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// InterfaceProxyBehavior()
|
||||
/// NilBehavior() => return Nil on GetMember and GetIndex in all cases
|
||||
/// ZoneOnDemandBehavior(_zoneFactory, _parent, name) => when a zone (Shape) is
|
||||
/// created, replace itself with the zone so that Layout.ZoneName is no more equal to Nil
|
||||
/// </remarks>
|
||||
public class ZoneOnDemand : Shape {
|
||||
|
||||
private readonly Func<dynamic> _zoneFactory;
|
||||
private readonly object _parent;
|
||||
private readonly string _potentialZoneName;
|
||||
|
||||
public ZoneOnDemand(Func<dynamic> zoneFactory, object parent, string potentialZoneName) {
|
||||
_zoneFactory = zoneFactory;
|
||||
_parent = parent;
|
||||
_potentialZoneName = potentialZoneName;
|
||||
}
|
||||
|
||||
public override bool TryGetMember(System.Dynamic.GetMemberBinder binder, out object result) {
|
||||
// NilBehavior
|
||||
result = Nil.Instance;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool TryGetIndex(System.Dynamic.GetIndexBinder binder, object[] indexes, out object result) {
|
||||
// NilBehavior
|
||||
result = Nil.Instance;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool TryInvokeMember(System.Dynamic.InvokeMemberBinder binder, object[] args, out object result) {
|
||||
var name = binder.Name;
|
||||
|
||||
// NilBehavior
|
||||
if (!args.Any() && name != "ToString") {
|
||||
result = Nil.Instance;
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.TryInvokeMember(binder, args, out result);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
public override bool TryConvert(System.Dynamic.ConvertBinder binder, out object result) {
|
||||
result = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool operator ==(ZoneOnDemand expr, object arg) {
|
||||
// if ZoneOnDemand is compared to null it must return true
|
||||
return arg == null || ReferenceEquals(arg, Nil.Instance);
|
||||
}
|
||||
|
||||
public static bool operator !=(ZoneOnDemand expr, object arg) {
|
||||
// if ZoneOnDemand is compared to null it must return true
|
||||
return arg != null && !ReferenceEquals(arg, Nil.Instance);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj) {
|
||||
if (ReferenceEquals(null, obj)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int GetHashCode() {
|
||||
unchecked {
|
||||
int hashCode = (_parent != null ? _parent.GetHashCode() : 0);
|
||||
hashCode = (hashCode * 397) ^ (_potentialZoneName != null ? _potentialZoneName.GetHashCode() : 0);
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
public class ZoneOnDemandBehavior : ClayBehavior {
|
||||
private readonly Func<dynamic> _zoneFactory;
|
||||
private readonly object _parent;
|
||||
private readonly string _potentialZoneName;
|
||||
|
||||
public ZoneOnDemandBehavior(Func<dynamic> zoneFactory, object parent, string potentialZoneName) {
|
||||
_zoneFactory = zoneFactory;
|
||||
_parent = parent;
|
||||
_potentialZoneName = potentialZoneName;
|
||||
}
|
||||
|
||||
public override object InvokeMember(Func<object> proceed, object self, string name, INamedEnumerable<object> args) {
|
||||
var argsCount = args.Count();
|
||||
if (name == "Add" && (argsCount == 1 || argsCount == 2)) {
|
||||
// pszmyd: Ignore null shapes
|
||||
if (args.First() == null)
|
||||
return _parent;
|
||||
|
||||
dynamic parent = _parent;
|
||||
|
||||
dynamic zone = _zoneFactory();
|
||||
zone.Parent = _parent;
|
||||
zone.ZoneName = _potentialZoneName;
|
||||
parent[_potentialZoneName] = zone;
|
||||
|
||||
if (argsCount == 1)
|
||||
return zone.Add(args.Single());
|
||||
|
||||
return zone.Add(args.First(), (string)args.Last());
|
||||
public override Shape Add(object item, string position = null) {
|
||||
if (item == null) {
|
||||
return (Shape)_parent;
|
||||
}
|
||||
return proceed();
|
||||
}
|
||||
|
||||
dynamic parent = _parent;
|
||||
|
||||
dynamic zone = _zoneFactory();
|
||||
zone.Parent = _parent;
|
||||
zone.ZoneName = _potentialZoneName;
|
||||
parent[_potentialZoneName] = zone;
|
||||
|
||||
if (position == null) {
|
||||
return zone.Add(item);
|
||||
}
|
||||
|
||||
return zone.Add(item, position);
|
||||
}
|
||||
}
|
||||
}
|
@ -41,7 +41,7 @@ namespace Orchard {
|
||||
/// The Layout shape corresponding to the work context
|
||||
/// </summary>
|
||||
public dynamic Layout {
|
||||
get { return GetState<object>("Layout"); }
|
||||
get { return GetState<dynamic>("Layout"); }
|
||||
set { SetState("Layout", value); }
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user