Merge branch 'dev' into feature/widget-elements

Conflicts:
	src/Orchard.Web/Modules/Orchard.Layouts/Orchard.Layouts.csproj
	src/Orchard.Web/Modules/Orchard.Layouts/Services/ElementManager.cs
This commit is contained in:
Sipke Schoorstra
2015-09-29 21:20:50 +01:00
253 changed files with 3021 additions and 1983 deletions

View File

@@ -11,9 +11,9 @@ namespace Orchard.Layouts {
builder
.AddImageSet("layouts")
.Add(T("Layouts"), "8.5", layouts => layouts
.Action("List", "Admin", new {id = "Layout", area = "Contents"})
.Action("List", "Admin", new {id = "Layout", area = "Contents"}).Permission(Permissions.ManageLayouts)
.LinkToFirstChild(false)
.Add(T("Elements"), "1", elements => elements.Action("Index", "BlueprintAdmin", new {area = "Orchard.Layouts"})));
.Add(T("Elements"), "1", elements => elements.Action("Index", "BlueprintAdmin", new {area = "Orchard.Layouts"}).Permission(Permissions.ManageLayouts)));
}
}
}

View File

@@ -74,45 +74,6 @@
return host.addElement(contentType);
};
$scope.toggleInlineEditing = function () {
if (!$scope.element.inlineEditingIsActive) {
$scope.element.inlineEditingIsActive = true;
$element.find(".layout-toolbar-container").show();
var selector = "#layout-editor-" + $scope.$id + " .layout-html .layout-content-markup[data-templated=false]";
var firstContentEditorId = $(selector).first().attr("id");
tinymce.init({
selector: selector,
theme: "modern",
schema: "html5",
plugins: [
"advlist autolink lists link image charmap print preview hr anchor pagebreak",
"searchreplace wordcount visualblocks visualchars code fullscreen",
"insertdatetime media nonbreaking table contextmenu directionality",
"emoticons template paste textcolor colorpicker textpattern",
"fullscreen autoresize"
],
toolbar: "undo redo cut copy paste | bold italic | bullist numlist outdent indent formatselect | alignleft aligncenter alignright alignjustify ltr rtl | link unlink charmap | code fullscreen close",
convert_urls: false,
valid_elements: "*[*]",
// Shouldn't be needed due to the valid_elements setting, but TinyMCE would strip script.src without it.
extended_valid_elements: "script[type|defer|src|language]",
statusbar: false,
skin: "orchardlightgray",
inline: true,
fixed_toolbar_container: "#layout-editor-" + $scope.$id + " .layout-toolbar-container",
init_instance_callback: function (editor) {
if (editor.id == firstContentEditorId)
tinymce.execCommand("mceFocus", false, editor.id);
}
});
}
else {
tinymce.remove("#layout-editor-" + $scope.$id + " .layout-content-markup");
$element.find(".layout-toolbar-container").hide();
$scope.element.inlineEditingIsActive = false;
}
};
$(document).on("cut copy paste", function (e) {
// If the pseudo clipboard was already invoked (which happens on the first clipboard
// operation after page load even if native clipboard support exists) then sit this
@@ -164,23 +125,12 @@
element.find(".layout-toolbar-container").click(function (e) {
e.stopPropagation();
});
// Intercept mousedown on editor while in inline editing mode to
// prevent current editor from losing focus.
element.mousedown(function (e) {
if (scope.element.inlineEditingIsActive) {
e.preventDefault();
e.stopPropagation();
}
})
// Unfocus and unselect everything on click outside of canvas.
$(window).click(function (e) {
// Except when in inline editing mode.
if (!scope.element.inlineEditingIsActive) {
scope.$apply(function () {
scope.element.activeElement = null;
scope.element.focusedElement = null;
});
}
scope.$apply(function () {
scope.element.activeElement = null;
scope.element.focusedElement = null;
});
});
}
};

View File

@@ -35,13 +35,6 @@
templateUrl: environment.templateUrl("Html"),
replace: true,
link: function (scope, element) {
// Mouse down events must not be intercepted by drag and drop while inline editing is active,
// otherwise clicks in inline editors will have no effect.
element.find(".layout-content-markup").mousedown(function (e) {
if (scope.element.editor.inlineEditingIsActive) {
e.stopPropagation();
}
});
}
};
}

View File

@@ -15,7 +15,7 @@
var resetFocus = false;
var element = $scope.element;
if (element.editor.isDragging || element.editor.inlineEditingIsActive)
if (element.editor.isDragging)
return;
// If native clipboard support exists, the pseudo-clipboard will have been disabled.

View File

@@ -9,7 +9,6 @@
this.focusedElement = null;
this.dropTargetElement = null;
this.isDragging = false;
this.inlineEditingIsActive = false;
this.isResizing = false;
this.resetToolboxElements = function () {

View File

@@ -57,7 +57,7 @@
this.setIsActive = function (value) {
if (!this.editor)
return;
if (this.editor.isDragging || this.editor.inlineEditingIsActive || this.editor.isResizing)
if (this.editor.isDragging || this.editor.isResizing)
return;
if (value)
@@ -81,7 +81,7 @@
return;
if (this.isTemplated && !this.allowSealedFocus())
return;
if (this.editor.isDragging || this.editor.inlineEditingIsActive || this.editor.isResizing)
if (this.editor.isDragging || this.editor.isResizing)
return;
this.editor.focusedElement = this;

View File

@@ -6,4 +6,4 @@
display: none;
}
}
}
}

View File

@@ -34,7 +34,8 @@ namespace Orchard.Layouts.Controllers {
ICultureAccessor cultureAccessor,
IShapeFactory shapeFactory,
ITransactionManager transactionManager,
ISignals signals) {
ISignals signals,
IOrchardServices orchardServices) {
_elementBlueprintService = elementBlueprintService;
_notifier = notifier;
@@ -43,12 +44,19 @@ namespace Orchard.Layouts.Controllers {
_shapeFactory = shapeFactory;
_transactionManager = transactionManager;
_signals = signals;
Services = orchardServices;
T = NullLocalizer.Instance;
}
public IOrchardServices Services { get; set; }
public Localizer T { get; set; }
public ActionResult Index() {
if (!Services.Authorizer.Authorize(Permissions.ManageLayouts, T("Not authorized to manage layouts."))) {
return new HttpUnauthorizedResult();
}
var blueprints = _elementBlueprintService.GetBlueprints().ToArray();
var viewModel = new BlueprintsIndexViewModel {
Blueprints = blueprints
@@ -57,6 +65,10 @@ namespace Orchard.Layouts.Controllers {
}
public ActionResult Browse() {
if (!Services.Authorizer.Authorize(Permissions.ManageLayouts, T("Not authorized to manage layouts."))) {
return new HttpUnauthorizedResult();
}
var categories = RemoveBlueprints(_elementManager.GetCategories(DescribeElementsContext.Empty)).ToArray();
var viewModel = new BrowseElementsViewModel {
Categories = categories
@@ -65,6 +77,10 @@ namespace Orchard.Layouts.Controllers {
}
public ActionResult Create(string id) {
if (!Services.Authorizer.Authorize(Permissions.ManageLayouts, T("Not authorized to manage layouts."))) {
return new HttpUnauthorizedResult();
}
if (String.IsNullOrWhiteSpace(id))
return RedirectToAction("Browse");
@@ -80,6 +96,10 @@ namespace Orchard.Layouts.Controllers {
[HttpPost]
public ActionResult Create(string id, CreateElementBlueprintViewModel model) {
if (!Services.Authorizer.Authorize(Permissions.ManageLayouts, T("Not authorized to manage layouts."))) {
return new HttpUnauthorizedResult();
}
var describeContext = DescribeElementsContext.Empty;
var descriptor = _elementManager.GetElementDescriptorByTypeName(describeContext, id);
var baseElement = _elementManager.ActivateElement(descriptor);
@@ -100,7 +120,11 @@ namespace Orchard.Layouts.Controllers {
return RedirectToAction("Edit", new { id = blueprint.Id });
}
public ViewResult Edit(int id) {
public ActionResult Edit(int id) {
if (!Services.Authorizer.Authorize(Permissions.ManageLayouts, T("Not authorized to manage layouts."))) {
return new HttpUnauthorizedResult();
}
var blueprint = _elementBlueprintService.GetBlueprint(id);
var describeContext = DescribeElementsContext.Empty;
var descriptor = _elementManager.GetElementDescriptorByTypeName(describeContext, blueprint.BaseElementTypeName);
@@ -125,6 +149,10 @@ namespace Orchard.Layouts.Controllers {
[HttpPost]
[ValidateInput(false)]
public ActionResult Edit(int id, ElementDataViewModel model) {
if (!Services.Authorizer.Authorize(Permissions.ManageLayouts, T("Not authorized to manage layouts."))) {
return new HttpUnauthorizedResult();
}
var blueprint = _elementBlueprintService.GetBlueprint(id);
var describeContext = DescribeElementsContext.Empty;
var descriptor = _elementManager.GetElementDescriptorByTypeName(describeContext, blueprint.BaseElementTypeName);
@@ -154,6 +182,10 @@ namespace Orchard.Layouts.Controllers {
}
public ActionResult Properties(int id) {
if (!Services.Authorizer.Authorize(Permissions.ManageLayouts, T("Not authorized to manage layouts."))) {
return new HttpUnauthorizedResult();
}
var blueprint = _elementBlueprintService.GetBlueprint(id);
var describeContext = DescribeElementsContext.Empty;
var descriptor = _elementManager.GetElementDescriptorByTypeName(describeContext, blueprint.BaseElementTypeName);
@@ -171,6 +203,10 @@ namespace Orchard.Layouts.Controllers {
[HttpPost]
public ActionResult Properties(int id, ElementBlueprintPropertiesViewModel model) {
if (!Services.Authorizer.Authorize(Permissions.ManageLayouts, T("Not authorized to manage layouts."))) {
return new HttpUnauthorizedResult();
}
var blueprint = _elementBlueprintService.GetBlueprint(id);
var describeContext = DescribeElementsContext.Empty;
var descriptor = _elementManager.GetElementDescriptorByTypeName(describeContext, blueprint.BaseElementTypeName);
@@ -191,7 +227,12 @@ namespace Orchard.Layouts.Controllers {
return RedirectToAction("Index");
}
[HttpPost]
public ActionResult Delete(int id) {
if (!Services.Authorizer.Authorize(Permissions.ManageLayouts, T("Not authorized to manage layouts."))) {
return new HttpUnauthorizedResult();
}
var blueprint = _elementBlueprintService.GetBlueprint(id);
if (blueprint == null)
@@ -204,7 +245,12 @@ namespace Orchard.Layouts.Controllers {
[FormValueRequired("submit.BulkEdit")]
[ActionName("Index")]
[HttpPost]
public ActionResult BulkDelete(IEnumerable<int> blueprintIds) {
if (!Services.Authorizer.Authorize(Permissions.ManageLayouts, T("Not authorized to manage layouts."))) {
return new HttpUnauthorizedResult();
}
if (blueprintIds == null || !blueprintIds.Any()) {
_notifier.Error(T("Please select the blueprints to delete."));
}

View File

@@ -142,18 +142,7 @@ namespace Orchard.Layouts.Controllers {
_objectStore.Set(session, state);
return RedirectToAction("Edit", new {session = session});
}
public RedirectToRouteResult Add(string session, string typeName, int? contentId = null, string contentType = null) {
var state = new ElementSessionState {
TypeName = typeName,
ContentId = contentId,
ContentType = contentType
};
_objectStore.Set(session, state);
return RedirectToAction("Edit", new { session = session });
}
public ViewResult Edit(string session) {
var sessionState = _objectStore.Get<ElementSessionState>(session);
var contentId = sessionState.ContentId;

View File

@@ -6,6 +6,7 @@ using Orchard.ContentManagement;
using Orchard.Layouts.Elements;
using Orchard.Layouts.Framework.Elements;
using Orchard.Layouts.Services;
using Orchard.Localization;
using Orchard.UI.Admin;
namespace Orchard.Layouts.Controllers {
@@ -15,15 +16,25 @@ namespace Orchard.Layouts.Controllers {
private readonly ILayoutManager _layoutManager;
private readonly ILayoutModelMapper _mapper;
public LayoutController(IContentManager contentManager, ILayoutManager layoutManager, ILayoutModelMapper mapper) {
public LayoutController(
IContentManager contentManager,
ILayoutManager layoutManager,
ILayoutModelMapper mapper,
IOrchardServices orchardServices) {
_contentManager = contentManager;
_layoutManager = layoutManager;
_mapper = mapper;
Services = orchardServices;
T = NullLocalizer.Instance;
}
public IOrchardServices Services { get; set; }
public Localizer T { get; set; }
[HttpPost, ValidateInput(enableValidation: false)]
public ContentResult ApplyTemplate(int? templateId = null, string layoutData = null, int? contentId = null, string contentType = null) {
public ActionResult ApplyTemplate(int? templateId = null, string layoutData = null, int? contentId = null, string contentType = null) {
var template = templateId != null ? _layoutManager.GetLayout(templateId.Value) : null;
var templateElements = template != null ? _layoutManager.LoadElements(template).ToList() : default(IEnumerable<Element>);
var describeContext = CreateDescribeElementsContext(contentId, contentType);

View File

@@ -307,10 +307,9 @@ namespace Orchard.Layouts.Drivers {
var queryPart = query.As<QueryPart>();
var layoutIndex = XmlHelper.Parse<int>(context.ExportableData.Get("LayoutIndex"));
var layout = queryPart.Layouts[layoutIndex];
element.QueryId = queryPart.Id;
element.LayoutId = layout.Id;
element.LayoutId = layoutIndex != -1 ? queryPart.Layouts[layoutIndex].Id : -1;
}
private static string GetLayoutDescription(IEnumerable<LayoutDescriptor> layouts, LayoutRecord l) {

View File

@@ -33,7 +33,6 @@ namespace Orchard.Layouts {
.WithPart("LayoutPart", p => p
.WithSetting("LayoutTypePartSettings.IsTemplate", "True"))
.DisplayedAs("Layout")
.Listable()
.Draftable());
ContentDefinitionManager.AlterTypeDefinition("LayoutWidget", type => type

View File

@@ -371,6 +371,7 @@
<Compile Include="Helpers\PrefixHelper.cs" />
<Compile Include="Helpers\JsonHelper.cs" />
<Compile Include="Helpers\StringHelper.cs" />
<Compile Include="Permissions.cs" />
<Compile Include="Providers\PlaceableContentElementHarvester.cs" />
<Compile Include="ViewModels\PlaceableContentItemViewModel.cs" />
<Compile Include="Recipes\Builders\CustomElementsStep.cs" />

View File

@@ -0,0 +1,40 @@
using System.Collections.Generic;
using Orchard.Environment.Extensions.Models;
using Orchard.Security.Permissions;
namespace Orchard.Layouts {
public class Permissions : IPermissionProvider {
public static readonly Permission ManageLayouts = new Permission { Description = "Managing Layouts", Name = "ManageLayouts" };
public virtual Feature Feature { get; set; }
public IEnumerable<Permission> GetPermissions() {
return new[] {
ManageLayouts,
};
}
public IEnumerable<PermissionStereotype> GetDefaultStereotypes() {
return new[] {
new PermissionStereotype {
Name = "Administrator",
Permissions = new[] { ManageLayouts }
},
new PermissionStereotype {
Name = "Editor",
Permissions = new[] { ManageLayouts }
},
new PermissionStereotype {
Name = "Moderator",
},
new PermissionStereotype {
Name = "Author"
},
new PermissionStereotype {
Name = "Contributor",
},
};
}
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -38,7 +38,7 @@ namespace Orchard.Layouts.Services {
public IEnumerable<ElementDescriptor> DescribeElements(DescribeElementsContext context) {
var contentType = context.Content != null ? context.Content.ContentItem.ContentType : default(string);
var cacheKey = String.Format("LayoutElementTypes-{0}-{1}", contentType ?? "AnyType", context.CacheVaryParam);
return _cacheManager.Get(cacheKey, acquireContext => {
return _cacheManager.Get(cacheKey, true, acquireContext => {
var harvesterContext = new HarvestElementsContext {
Content = context.Content
};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -2,7 +2,7 @@
@foreach (var contentItemShape in Model.ContentItems) {
var contentItem = (ContentItem)contentItemShape.ContentItem;
var displayTextHtmlString = Html.ItemDisplayText(contentItem);
var displayText = displayTextHtmlString != null ? displayTextHtmlString.ToString() : T("-").ToString();
var displayText = displayTextHtmlString != null ? (IHtmlString)displayTextHtmlString : T("-");
<div class="layout-snippet">
@displayText
</div>

View File

@@ -1,10 +1,6 @@
<div class="layout-toolbox-wrapper">
<div class="layout-toolbox">
<label>
<input type="checkbox" ng-checked="element.inlineEditingIsActive" ng-click="toggleInlineEditing()" />
@T("Edit HTML content inline")
</label>
<ul class="layout-toolbox-groups" ng-hide="element.inlineEditingIsActive">
<ul class="layout-toolbox-groups">
<li class="layout-toolbox-group" ng-class="{collapsed: layoutIsCollapsed}">
<a href="#" class="layout-toolbox-group-heading" ng-click="toggleLayoutIsCollapsed($event)">@T("Layout")</a>
<ul class="layout-toolbox-items">