#17626: Finalizing Shape Tracing module

Work Items: 17626

--HG--
branch : 1.x
This commit is contained in:
Sebastien Ros
2011-04-06 22:03:32 -07:00
parent 342b12539f
commit 41bdb56235
8 changed files with 113 additions and 63 deletions

View File

@@ -36,7 +36,7 @@ jQuery(function ($) {
var previousSize = 0;
// represents the arrow to add to any collpasible container
var glyph = $('<span class="expando-glyph-container closed"><span class="expando-glyph"></span>&#8203;</span>');
var glyph = '<span class="expando-glyph-container closed"><span class="expando-glyph"></span>&#8203;</span>';
// ensure the ghost has always the same size as the container
// and the container is always positionned correctly
@@ -117,7 +117,7 @@ jQuery(function ($) {
$('#shape-tracing-resize-handle').addClass('ui-resizable-handle ui-resizable-n');
shapeTracingContainer.resizable({
handles: { n: '#shape-tracing-resize-handle' },
grid: 20, // mitigates the number of calls to syncResize(), and aligns to the line height
grid: 20, // mitigates the number of calls to syncResize()
resize: function () { shapeTracingEnabled = false },
stop: function () { shapeTracingEnabled = true }
});
@@ -191,27 +191,34 @@ jQuery(function ($) {
shapeTracingWindowTree.append(shapes);
// add the expand/collapse logic to the shapes tree
shapeTracingWindowTree.find('li:has(ul:has(li))').prepend(glyph);
shapeTracingWindowTree.find('li:has(ul:has(li))').prepend($(glyph));
// collapse all sub uls
shapeTracingWindowTree.find('ul ul').toggle(false);
// expands a list of shapes in the tree
var openExpando = function (expando) {
if (expando.hasClass("closed") || expando.hasClass("closing")) {
expando.siblings('ul').slideDown(100, function () { expando.removeClass("opening").removeClass("closed").addClass("open"); });
expando.addClass("opening");
if (expando.hasClass("closed")) {
expando.siblings('ul').toggle(true);
expando.removeClass("closed").addClass("open");
}
}
// collapses a list of shapes in the tree
var closeExpando = function (expando) {
if (!expando.hasClass("closed") && !expando.hasClass("closing")) {
expando.siblings('ul').slideUp(100, function () { expando.removeClass("closing").removeClass("open").addClass("closed"); });
expando.addClass("closing");
if (expando.hasClass("open")) {
expando.siblings('ul').toggle(false);
expando.removeClass("open").addClass("closed");
}
}
shapeTracingWindow.add(shapeTracingResizeHandle).hover(function () {
shapeTracingOverlay.hide();
}, function () {
shapeTracingOverlay.show();
}
);
//create an overlay on shapes' descendants
var overlayTarget = null;
$('[shape-id]').add(shapeTracingOverlay).mousemove(
@@ -315,7 +322,7 @@ jQuery(function ($) {
$("[shape-id-meta]").detach().prependTo(shapeTracingWindowContent);
// add the expand/collapse logic to the shape model
shapeTracingWindowContent.find('li:has(ul:has(li))').prepend(glyph);
shapeTracingWindowContent.find('li:has(ul:has(li))').prepend($(glyph));
// collapse all sub uls
shapeTracingWindowContent.find('ul ul').toggle(false);
@@ -327,7 +334,7 @@ jQuery(function ($) {
shapeTracingTabsShape.addClass('selected');
// remove old content
shapeTracingMetaContent.empty();
shapeTracingMetaContent.children().remove();
// render the template
if (currentShape && shapeTracingMetadataHost[currentShape]) {
@@ -337,10 +344,14 @@ jQuery(function ($) {
shapeTracingBreadcrumb.text('');
// create collapsible containers
shapeTracingMetaContent.find('li:has(ul:has(li))').prepend(glyph);
shapeTracingMetaContent.find('li:has(ul:has(li))').prepend($(glyph));
shapeTracingMetaContent.find('ul ul').toggle(false);
shapeTracingMetaContent.find('.expando-glyph-container').click(expandCollapseExpando);
$('#activeTemplate').click(function () {
displayTabTemplate();
});
defaultTab = displayTabShape;
};
@@ -357,7 +368,7 @@ jQuery(function ($) {
shapeTracingTabsModel.addClass('selected');
// remove old content
shapeTracingMetaContent.empty();
shapeTracingMetaContent.children().remove();
// render the template
if (currentShape && shapeTracingMetadataHost[currentShape]) {
@@ -367,7 +378,7 @@ jQuery(function ($) {
shapeTracingBreadcrumb.text('');
// create collapsible containers
shapeTracingMetaContent.find('li:has(ul:has(li))').prepend(glyph);
shapeTracingMetaContent.find('li:has(ul:has(li))').prepend($(glyph));
shapeTracingMetaContent.find('ul ul').toggle(false);
shapeTracingMetaContent.find('.expando-glyph-container').click(expandCollapseExpando);
@@ -422,7 +433,7 @@ jQuery(function ($) {
shapeTracingTabsPlacement.addClass('selected');
// remove old content
shapeTracingMetaContent.empty();
shapeTracingMetaContent.children().remove();
// render the template
if (currentShape && shapeTracingMetadataHost[currentShape]) {
@@ -449,7 +460,7 @@ jQuery(function ($) {
shapeTracingTabsTemplate.addClass('selected');
// remove old content
shapeTracingMetaContent.empty();
shapeTracingMetaContent.children().remove();
// render the template
if (currentShape && shapeTracingMetadataHost[currentShape]) {
@@ -475,7 +486,7 @@ jQuery(function ($) {
shapeTracingTabsHtml.addClass('selected');
// remove old content
shapeTracingMetaContent.empty();
shapeTracingMetaContent.children().remove();
// render the template
if (currentShape && shapeTracingMetadataHost[currentShape]) {
@@ -506,7 +517,7 @@ jQuery(function ($) {
// hooks the click event on expandos
var expandCollapseExpando = function () {
var _this = $(this);
if (_this.hasClass("closed") || _this.hasClass("closing")) {
if (_this.hasClass("closed")) {
openExpando(_this);
}
else {

View File

@@ -272,17 +272,5 @@ namespace Orchard.DesignerTools.Services {
_current.Add(_current = new XElement(tag));
return _current;
}
private int MaxNodesLength(XElement el) {
int max = 1;
var local = 0;
foreach(var node in el.Elements()) {
local = Math.Max(local, MaxNodesLength(node));
}
return max + local;
}
}
public class DumpMap : Dictionary<int, XElement> {}
}

View File

@@ -1,8 +1,7 @@
using System.Collections.Generic;
using System;
using System.Linq;
using System.Text;
using System.Web.Routing;
using System.Runtime.CompilerServices;
using System.Xml.Linq;
using Orchard.DisplayManagement.Descriptors;
using Orchard.DisplayManagement.Implementation;
@@ -23,7 +22,6 @@ namespace Orchard.DesignerTools.Services {
private readonly IWebSiteFolder _webSiteFolder;
private readonly IAuthorizer _authorizer;
private int _shapeId;
private readonly DumpMap _dumped = new DumpMap();
public ShapeTracingFactory(
WorkContext workContext,
@@ -76,10 +74,12 @@ namespace Orchard.DesignerTools.Services {
}
shapeMetadata.Wrappers.Add("ShapeTracingWrapper");
shapeMetadata.OnDisplaying(OnDisplaying);
}
}
public void Displaying(ShapeDisplayingContext context) {}
public void Displaying(ShapeDisplayingContext context) {
public void OnDisplaying(ShapeDisplayingContext context) {
if (!IsActivable()) {
return;
}
@@ -106,8 +106,8 @@ namespace Orchard.DesignerTools.Services {
shape.OriginalTemplate = descriptor.BindingSource;
foreach (var extension in new[] { ".cshtml", ".aspx" }) {
foreach (var alternate in shapeMetadata.Alternates.Reverse()) {
var alternateFilename = currentTheme.Location + "/" + currentTheme.Id + "/Views/" + alternate.Replace("__", "-").Replace("_", ".") + extension;
foreach (var alternate in shapeMetadata.Alternates.Reverse().Concat(new [] {shapeMetadata.Type}) ) {
var alternateFilename = FormatShapeFilename(alternate, shapeMetadata.Type, shapeMetadata.DisplayType, currentTheme.Location + "/" + currentTheme.Id, extension);
if (_webSiteFolder.FileExists(alternateFilename)) {
shape.Template = alternateFilename;
}
@@ -191,5 +191,17 @@ namespace Orchard.DesignerTools.Services {
// replace " by \" in json strings
return value.Replace("\"", @"\""");
}
private static string FormatShapeFilename(string shape, string shapeType, string displayType, string themePrefix, string extension) {
if (!String.IsNullOrWhiteSpace(displayType)) {
if (shape.StartsWith(shapeType + "_" + displayType)) {
shape = shapeType + shape.Substring(shapeType.Length + displayType.Length + 1) + "_" + displayType;
}
}
return themePrefix + "/Views/" + shape.Replace("__", "-").Replace("_", ".") + extension;
}
}
}

View File

@@ -1,16 +1,22 @@
using System.Web.Mvc;
using System.Web.Routing;
using Orchard.DisplayManagement;
using Orchard.Mvc.Filters;
using Orchard.Security;
using Orchard.UI.Admin;
namespace Orchard.DesignerTools.Services {
public class TemplatesFilter : FilterProvider, IResultFilter {
private readonly IWorkContextAccessor _workContextAccessor;
private readonly WorkContext _workContext;
private readonly IAuthorizer _authorizer;
private readonly dynamic _shapeFactory;
public TemplatesFilter(
IWorkContextAccessor workContextAccessor,
WorkContext workContext,
IAuthorizer authorizer,
IShapeFactory shapeFactory) {
_workContextAccessor = workContextAccessor;
_workContext = workContext;
_authorizer = authorizer;
_shapeFactory = shapeFactory;
}
@@ -19,12 +25,27 @@ namespace Orchard.DesignerTools.Services {
if (!(filterContext.Result is ViewResult))
return;
var ctx = _workContextAccessor.GetContext();
var tail = ctx.Layout.Tail;
if(!IsActivable()) {
return;
}
var tail = _workContext.Layout.Tail;
tail.Add(_shapeFactory.ShapeTracingTemplates());
}
public void OnResultExecuted(ResultExecutedContext filterContext) {
}
private bool IsActivable() {
// activate on front-end only
if (AdminFilter.IsApplied(new RequestContext(_workContext.HttpContext, new RouteData())))
return false;
// if not logged as a site owner, still activate if it's a local request (development machine)
if (!_authorizer.Authorize(StandardPermissions.SiteOwner))
return _workContext.HttpContext.Request.IsLocal;
return true;
}
}
}

View File

@@ -75,7 +75,7 @@ button.create-template, button.create-template:hover, background-image:hover {
clear:both;
display:block;
font-size:10pt;
font-family:Segoe;
font-family:Segoe UI,Trebuchet,Arial,Sans-Serif;;
left: 0px;
bottom: 0px;
position:fixed;
@@ -321,10 +321,14 @@ ul#shape-tracing-tabs {
#shape-tracing-window-content .grid-display div.type, #shape-tracing-window-content .grid-display div.value {
position:absolute;
left:66%;
left:40%;
white-space:nowrap;
}
#shape-tracing-window-content div.model div.type, #shape-tracing-window-content div.model div.value {
left:66%;
}
#shape-tracing-breadcrumb {
background:rgba(236, 241, 242, 1.0);
border-bottom:1px solid rgba(182, 188, 189, 1.0);

View File

@@ -1,8 +1,22 @@
@using Orchard.Utility.Extensions;
@functions {
string FormatShapeFilename(string type, string themeId) {
return "~/Themes/" + themeId + "/Views/" + type.Replace("__", "-").Replace("_", ".") + ".cshtml";
string FormatShapeName(string shape) {
string shapeType = Model.ShapeType;
string displayType = Model.DisplayType;
if(!String.IsNullOrWhiteSpace(displayType)) {
if(shape.StartsWith(shapeType + "_" + displayType)) {
shape = shapeType + shape.Substring(shapeType.Length + displayType.Length + 1) + "_" + displayType;
}
}
return shape.Replace("__", "-").Replace("_", ".");
}
string FormatShapeFilename(string shape, string themeId) {
shape = FormatShapeName(shape);
return "~/Themes/" + themeId + "/Views/" + shape.Replace("__", "-").Replace("_", ".") + ".cshtml";
}
string RemoveBeacons(string htmlContent) {
@@ -28,10 +42,11 @@ shapeTracingMetadataHost[@Model.ShapeId].shape = {
position: '@(String.IsNullOrEmpty((string)Model.Position) ? T("n/a").Text : Model.Position.ToString())',
placement: '@(String.IsNullOrEmpty((string)Model.PlacementSource) ? T("n/a").Text : Model.PlacementSource.ToString())',
alternates: [
@foreach (var alternate in Model.Alternates) {
@foreach (var alternate in (new[] { (string)Model.ShapeType }).Concat((List<string>)Model.Alternates))
{
<text>{</text>
<text>filename: '@FormatShapeFilename(alternate, WorkContext.CurrentTheme.Id)',</text>
<text>alternate: '@alternate',</text>
<text>alternate: '@FormatShapeName(alternate)',</text>
<text>template: '@Model.Template',</text>
<text>returnUrl: '@Context.Request.RawUrl'</text>
<text>},</text>
@@ -49,8 +64,8 @@ shapeTracingMetadataHost[@Model.ShapeId].shape = {
model: { @(new MvcHtmlString((string)@Model.Dump)) }
};
@if(!String.IsNullOrEmpty((string)Model.PlacementSource) && !TempData.ContainsKey((string)Model.PlacementSource)) {
TempData[(string)Model.PlacementSource] = new object();
@if (!String.IsNullOrEmpty((string)Model.PlacementSource) && (WorkContext.HttpContext.Items[(string)Model.PlacementSource] == null)) {
WorkContext.HttpContext.Items[(string)Model.PlacementSource] = new object();
<text>shapeTracingMetadataHost.placement['@Model.PlacementSource.ToString()'] = '@Model.PlacementContent.Replace(Environment.NewLine, "\\n")'; </text>
}

View File

@@ -7,11 +7,11 @@
<div id="shape-tracing-window-tree"></div>
<div id="shape-tracing-window-content">
<ul id="shape-tracing-tabs">
<li id="shape-tracing-tabs-shape" class="selected first">Shape</li>
<li id="shape-tracing-tabs-model" class="middle">Model</li>
<li id="shape-tracing-tabs-placement" class="middle">Placement</li>
<li id="shape-tracing-tabs-template" class="middle">Template</li>
<li id="shape-tracing-tabs-html" class="last">HTML</li>
<li id="shape-tracing-tabs-shape" class="selected first">@T("Shape")</li>
<li id="shape-tracing-tabs-model" class="middle">@T("Model")</li>
<li id="shape-tracing-tabs-placement" class="middle">@T("Placement")</li>
<li id="shape-tracing-tabs-template" class="middle">@T("Template")</li>
<li id="shape-tracing-tabs-html" class="last">@T("HTML")</li>
</ul>
<div id="shape-tracing-breadcrumb"></div>
<div id="shape-tracing-meta-content"></div>
@@ -24,11 +24,13 @@
<script id="shape-tracing-tabs-shape-template" type="text/x-jquery-tmpl">
<div class="shape grid-display">
<ul class="properties">
<li class="sgd-s"><div class="name">Shape</div><div class="value">${shape.type}</div></li>
<li class="sgd-t"><div class="name">Template</div><div class="value"><a href="#">${shape.template}</a></div></li>
<li class="sgd-ot"><div class="name">Original Template</div><div class="value">${shape.originalTemplate}</div></li>
<li class="sgd-d"><div class="name">Display Type</div><div class="value">${shape.displayType}</div></li>
<li class="sgd-a"><div class="name">Alternates (${shape.alternates.length})</div>
<li class="sgd-s"><div class="name">@T("Shape").Text</div><div class="value">${shape.type}</div></li>
<li class="sgd-t"><div class="name">@T("Active Template").Text</div><div class="value"><a id="activeTemplate" href="#">${shape.template}</a></div></li>
{{if shape.template != shape.originalTemplate}}
<li class="sgd-ot"><div class="name">@T("Original Template").Text Template</div><div class="value">${shape.originalTemplate}</div></li>
{{/if}}
<li class="sgd-d"><div class="name">@T("Display Type").Text</div><div class="value">${shape.displayType}</div></li>
<li class="sgd-a"><div class="name">@T("Alternate ({0})", "${shape.alternates.length}").Text</div>
<div class="value">&nbsp;</div>
<ul>
{{each shape.alternates}}
@@ -47,7 +49,7 @@
{{/each}}
</ul>
</li>
<li class="sgd-w"><div class="name">Wrappers (${shape.wrappers.length})</div>
<li class="sgd-w"><div class="name">@T("Wrappers ({0})", "${shape.wrappers.length}")</div>
<div class="value">&nbsp;</div>
<ul>
{{each shape.wrappers}}

View File

@@ -121,9 +121,6 @@ body {
iframe {border:1px solid #eee;}
/*Hide shape tracing*/
#shape-tracing-container {display:none;}
/* Headings */
h1,h2,h3,h4,h5,h6 { font-weight: normal;}