Rendering shape tracing model using json and jquery templates

--HG--
branch : 1.x
This commit is contained in:
Sebastien Ros
2011-04-05 18:02:15 -07:00
parent 040c3d78d5
commit 7166bbbf6e
5 changed files with 151 additions and 51 deletions

View File

@@ -4,6 +4,7 @@ if (!window.shapeTracingMetadataHost) {
window.shapeTracingMetadataHost.placement = {
'n/a': 'n/a'
};
window.shapeTracingMetadataHost.references = {};
}
jQuery(function ($) {
@@ -350,6 +351,68 @@ jQuery(function ($) {
displayTabShape();
});
// Model tab
var displayTabModel = function () {
// toggle the selected class
shapeTracingTabs.children('.selected').removeClass('selected');
shapeTracingTabsModel.addClass('selected');
// remove old content
shapeTracingMetaContent.empty();
// render the template
if (currentShape && shapeTracingMetadataHost[currentShape]) {
$("#shape-tracing-tabs-model-template").tmpl(shapeTracingMetadataHost[currentShape].shape.model).appendTo(shapeTracingMetaContent);
}
shapeTracingBreadcrumb.text('');
// create collapsible containers
shapeTracingMetaContent.find('li:has(ul:has(li))').prepend(glyph);
shapeTracingMetaContent.find('ul ul').toggle(false);
shapeTracingMetaContent.find('.expando-glyph-container').click(expandCollapseExpando);
shapeTracingMetaContent.find('.model div.name')
.hover(
function () {
var _this = $(this);
$('.shape-tracing-overlay').removeClass('shape-tracing-overlay');
_this.addClass('shape-tracing-overlay');
},
function () {
$('.shape-tracing-overlay').removeClass('shape-tracing-overlay');
})
.click(function (event) {
// model node is selected
var _this = $(this);
shapeTracingWindowContent.find('.shape-tracing-selected').removeClass('shape-tracing-selected');
_this.addClass('shape-tracing-selected');
// display breadcrumb
var breadcrumb = null;
_this.parentsUntil('.model').children('.name').each(function () {
if (breadcrumb != null) {
breadcrumb = $(this).text() + '.' + breadcrumb;
}
else {
breadcrumb = $(this).text();
}
});
// fix enumerable properties display
breadcrumb = breadcrumb.replace('.[', '[');
shapeTracingBreadcrumb.text('@' + breadcrumb);
event.stopPropagation();
});
defaultTab = displayTabModel;
};
shapeTracingTabsModel.click(function () {
displayTabModel();
});
// Placement tab
var displayTabPlacement = function () {
// toggle the selected class
@@ -416,7 +479,7 @@ jQuery(function ($) {
if (currentShape && shapeTracingMetadataHost[currentShape]) {
$("#shape-tracing-tabs-html-template").tmpl(shapeTracingMetadataHost[currentShape].shape.html).appendTo(shapeTracingMetaContent);
}
shapeTracingBreadcrumb.text('');
enableCodeMirror(shapeTracingMetaContent);
@@ -454,41 +517,6 @@ jQuery(function ($) {
// automatically expand or collapse shapes in the tree
shapeTracingWindowTree.find('.expando-glyph-container').click(expandCollapseExpando);
//create an overlay on model nodes
shapeTracingWindowContent.find('.model div.name')
.hover(
function () {
var _this = $(this);
$('.shape-tracing-overlay').removeClass('shape-tracing-overlay');
_this.addClass('shape-tracing-overlay');
},
function () {
$('.shape-tracing-overlay').removeClass('shape-tracing-overlay');
})
.click(function (event) {
// model node is selected
var _this = $(this);
shapeTracingWindowContent.find('.shape-tracing-selected').removeClass('shape-tracing-selected');
_this.addClass('shape-tracing-selected');
// display breadcrumb
var breadcrumb = null;
_this.parentsUntil('.model').children('.name').each(function () {
if (breadcrumb != null) {
breadcrumb = $(this).text() + '.' + breadcrumb;
}
else {
breadcrumb = $(this).text();
}
});
// fix enumerable properties display
breadcrumb = breadcrumb.replace('.[', '[');
_this.parents('.shape-tracing-meta').find('.shape-tracing-breadcrumb').text('@' + breadcrumb);
event.stopPropagation();
});
// recursively create a node for the shapes tree
function createTreeNode(shapeNode) {
var node = $('<li></li>');

View File

@@ -1,7 +1,9 @@
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Routing;
using System.Xml;
using System.Runtime.CompilerServices;
using System.Xml.Linq;
using Orchard.DisplayManagement.Descriptors;
using Orchard.DisplayManagement.Implementation;
using Orchard.DisplayManagement.Shapes;
@@ -21,6 +23,7 @@ namespace Orchard.DesignerTools.Services {
private readonly IWebSiteFolder _webSiteFolder;
private readonly IAuthorizer _authorizer;
private int _shapeId;
private readonly Dictionary<int, XElement> _dumped = new Dictionary<int, XElement>(1000);
public ShapeTracingFactory(
WorkContext workContext,
@@ -93,11 +96,16 @@ namespace Orchard.DesignerTools.Services {
var descriptor = shapeTable.Descriptors[shapeMetadata.Type];
// dump the Shape's content
var dumper = new ObjectDumper(1);
var el = dumper.Dump(context.Shape, "Model");
using (var sw = new StringWriter()) {
el.WriteTo(new XmlTextWriter(sw) {Formatting = Formatting.None});
context.Shape._Dump = sw.ToString();
var local = new Dictionary<int, XElement>();
new ObjectDumper(6, local, _dumped).Dump(context.Shape, "Model");
context.Shape.Reference = RuntimeHelpers.GetHashCode(context.Shape);
var sb = new StringBuilder();
context.Shape.LocalReferences = new Dictionary<int, string>();
foreach (var key in local.Keys) {
sb.Clear();
ConvertToJSon(local[key], sb);
((Dictionary<int, string>) context.Shape.LocalReferences)[key] = sb.ToString();
}
shape.Template = null;
@@ -149,5 +157,48 @@ namespace Orchard.DesignerTools.Services {
public void Displayed(ShapeDisplayedContext context) {
}
private static void ConvertToJSon(XElement x, StringBuilder sb) {
if(x == null) {
return;
}
switch (x.Name.ToString()) {
case "ul" :
foreach(var li in x.Elements()) {
ConvertToJSon(li, sb);
sb.Append(",");
}
break;
case "li":
var name = x.Element("h1").Value;
var value = x.Element("span").Value;
sb.AppendFormat("name: \"{0}\", ", FormatJsonValue(name));
sb.AppendFormat("value: \"{0}\"", FormatJsonValue(value));
var a = x.Element("a");
if (a != null) {
sb.AppendFormat(", children: shapeTracingMetadataHost.references[{0}]", a.Attribute("href").Value);
}
var ul = x.Element("ul");
if (ul != null) {
sb.Append(", children: [");
foreach (var li in ul.Elements()) {
sb.Append("{ ");
ConvertToJSon(li, sb);
sb.Append(" },");
}
sb.Append("]");
}
break;
}
}
private static string FormatJsonValue(string value) {
// replace " by \" in json strings
return value.Replace("\"", @"\""");
}
}
}

View File

@@ -15,14 +15,15 @@
return regex.Replace(htmlContent, System.Environment.NewLine);
}
}
<div class="shape-tracing-meta" shape-id-meta="@Model.ShapeId" style="display:none">
<div class="model grid-display" style="display:none">
@(new MvcHtmlString((string)@Model.Dump))
</div>
</div>
<script type="text/javascript">
shapeTracingMetadataHost[@Model.ShapeId] = {};
@foreach (var pair in Model.LocalReferences) {
<text>shapeTracingMetadataHost.references[@pair.Key] = { @(new MvcHtmlString(pair.Value)) };</text>
}
shapeTracingMetadataHost[@Model.ShapeId].shape = {
type: '@Model.ShapeType',
template: '@Model.Template',
@@ -48,7 +49,8 @@ shapeTracingMetadataHost[@Model.ShapeId].shape = {
}
],
html: '@RemoveEmptyLines(RemoveBeacons(Display(Model.ChildContent).ToString())).Replace(Environment.NewLine, "\\n")',
templateContent: '@(String.IsNullOrWhiteSpace((string)Model.TemplateContent) ? @T("Content not available as coming from source code.") : @Model.TemplateContent.Replace(Environment.NewLine, "\\n"))'
templateContent: '@(String.IsNullOrWhiteSpace((string)Model.TemplateContent) ? @T("Content not available as coming from source code.") : @Model.TemplateContent.Replace(Environment.NewLine, "\\n"))',
model: shapeTracingMetadataHost.references[@Model.Reference]
};
@if(!String.IsNullOrEmpty((string)Model.PlacementSource) && !TempData.ContainsKey((string)Model.PlacementSource)) {

View File

@@ -59,6 +59,24 @@
</div>
</script>
<script id="shape-tracing-tabs-model-template" type="text/x-jquery-tmpl">
<div class="model grid-display">
<ul>{{tmpl "#shape-tracing-tabs-model-node-template"}}</ul>
</div>
</script>
<script id="shape-tracing-tabs-model-node-template" type="text/x-jquery-tmpl">
<li>
<div class="name">${name}</div>
<div class="value">${value}</div>
{{if children}}
<ul>
{{tmpl(children) "#shape-tracing-tabs-model-node-template"}}
</ul>
{{/if}}
</li>
</script>
<script id="shape-tracing-tabs-placement-template" type="text/x-jquery-tmpl">
<div class="placement">
<textarea>${$data}</textarea>

View File

@@ -35,11 +35,12 @@
DisplayType: Model.Metadata.DisplayType,
Position: Model.Metadata.Position,
PlacementSource: Model.Metadata.PlacementSource,
Dump: Model._Dump,
PlacementContent: Model.PlacementContent,
Alternates: Model.Metadata.Alternates,
Wrappers: Model.Metadata.Wrappers,
ChildContent: Model.Metadata.ChildContent,
ShapeId: Model.ShapeId
ShapeId: Model.ShapeId,
Reference: Model.Reference,
LocalReferences: Model.LocalReferences
));
}