-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFillNode.aspx
156 lines (132 loc) · 4.77 KB
/
FillNode.aspx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
<%@ Page Language="C#" EnableViewState="False" %>
<script runat="server">
//===============================================================================================================
// System : Sandcastle Help File Builder
// File : FillNode.aspx
// Author : Eric Woodruff ([email protected])
// Updated : 07/17/2013
// Note : Copyright 2007-2013, Eric Woodruff, All rights reserved
// Compiler: Microsoft C#
//
// This file contains the code used to dynamically load a parent node with its child table of content nodes when
// first expanded.
//
// This code is published under the Microsoft Public License (Ms-PL). A copy of the license should be
// distributed with the code. It can also be found at the project website: http://SHFB.CodePlex.com. This
// notice, the author's name, and all copyright notices must remain intact in all applications, documentation,
// and source files.
//
// Version Date Who Comments
// ==============================================================================================================
// 1.5.0.0 06/21/2007 EFW Created the code
// 1.9.8.0 07/17/2013 EFW Merged code contributed by Procomp Solutions Oy that improves performance for large
// TOCs by using XML serialization and caching.
//===============================================================================================================
private static readonly TocNode[] NoChildNodes = new TocNode[0];
private static readonly object TocLoadSyncObject = new object();
// This is used to contain the serialized table of contents
[XmlRoot("HelpTOC")]
public sealed class TableOfContents
{
[XmlElement("HelpTOCNode")]
public TocNode[] ChildNodes;
[XmlIgnore]
public IDictionary<string, TocNode> NodesById;
internal void IndexNodes()
{
this.NodesById = new Dictionary<string, TocNode>();
AddToIndex(this.NodesById, this.ChildNodes);
}
private static void AddToIndex(IDictionary<string, TocNode> nodesById, TocNode[] nodes)
{
foreach(TocNode node in nodes)
if(!String.IsNullOrEmpty(node.Id))
{
nodesById.Add(node.Id, node);
AddToIndex(nodesById, node.ChildNodes);
}
}
}
// This represents a single node in the table of contents
public sealed class TocNode
{
[XmlAttribute("Id")]
public string Id;
[XmlAttribute("Title")]
public string Title;
[XmlAttribute("Url")]
public string Url;
[XmlElement("HelpTOCNode")]
public TocNode[] ChildNodes;
}
// Load the TOC info and store it in the cache on first use
private TableOfContents GetToc()
{
string tocPath = Server.MapPath("WebTOC.xml");
string tocCacheKey = tocPath;
lock(TocLoadSyncObject)
{
TableOfContents toc = this.Cache[tocCacheKey] as TableOfContents;
if(toc == null)
{
CacheDependency cacheDependency = new CacheDependency(tocPath);
using(XmlReader reader = XmlReader.Create(tocPath))
{
toc = (TableOfContents)new XmlSerializer(typeof(TableOfContents)).Deserialize(reader);
toc.IndexNodes();
}
this.Cache.Insert(tocCacheKey, toc, cacheDependency);
}
return toc;
}
}
// Load the requested node with its children
protected override void Render(HtmlTextWriter writer)
{
StringBuilder sb = new StringBuilder(10240);
TableOfContents toc = this.GetToc();
// The ID to use should be passed in the query string
string expandedId = this.Request.QueryString["Id"];
TocNode expandedNode;
if(toc.NodesById.TryGetValue(expandedId, out expandedNode))
{
foreach(TocNode childNode in expandedNode.ChildNodes ?? NoChildNodes)
{
if(childNode.ChildNodes != null && childNode.ChildNodes.Length != 0)
{
// Write out a parent TOC entry
string childUrl = childNode.Url;
string childTarget;
if(!String.IsNullOrEmpty(childUrl))
childTarget = " target=\"TopicContent\"";
else
{
childUrl = "#";
childTarget = String.Empty;
}
sb.AppendFormat("<div class=\"TreeNode\">\r\n" +
"<img class=\"TreeNodeImg\" onclick=\"javascript: Toggle(this);\" src=\"Collapsed.gif\"/>" +
"<a class=\"UnselectedNode\" onclick=\"javascript: return Expand(this);\" " +
"href=\"{0}\"{1}>{2}</a>\r\n" +
"<div id=\"{3}\" class=\"Hidden\"></div>\r\n" +
"</div>\r\n", childUrl, childTarget, HttpUtility.HtmlEncode(childNode.Title), childNode.Id);
}
else
{
string childUrl = childNode.Url;
if(String.IsNullOrEmpty(childUrl))
childUrl = "about:blank";
// Write out a TOC entry that has no children
sb.AppendFormat("<div class=\"TreeItem\">\r\n" +
"<img src=\"Item.gif\"/><a class=\"UnselectedNode\" " +
"onclick=\"javascript: return SelectNode(this);\" href=\"{0}\" " +
"target=\"TopicContent\">{1}</a>\r\n" +
"</div>\r\n", childUrl, HttpUtility.HtmlEncode(childNode.Title));
}
}
writer.Write(sb.ToString());
}
else
writer.Write("<b>TOC node not found!</b>");
}
</script>