forked from CodeConnect/SourceBrowser
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTreeViewTransformer.cs
159 lines (125 loc) · 5.83 KB
/
TreeViewTransformer.cs
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
157
158
159
using System;
using System.IO;
using System.Web.UI;
using System.Text;
using SourceBrowser.Generator.Model;
using System.Web;
namespace SourceBrowser.Generator.Transformers
{
/// <summary>
/// Converts a WorkspaceModel into HTML code
/// representing the tree view of the workspace's folder and file structure
/// </summary>
public class TreeViewTransformer : AbstractWorkspaceVisitor
{
private string _savePath;
private StreamWriter _sw;
private HtmlTextWriter _writer;
private readonly string _userNameAndRepoPrefix;
private const string _treeViewOutputFile = "treeView.html";
private int depth = 0;
public TreeViewTransformer(string savePath, string userName, string repoName)
{
_savePath = Path.Combine(savePath, _treeViewOutputFile);
Directory.CreateDirectory(Directory.GetParent(_savePath).FullName);
if (String.IsNullOrEmpty(userName) || String.IsNullOrEmpty(repoName))
{
throw new ArgumentNullException("TreeViewTransformer needs to be provided the user name and the repo name.");
}
_userNameAndRepoPrefix = Path.Combine("/Browse", userName, repoName);
}
protected override void VisitWorkspace(WorkspaceModel workspaceModel)
{
// The first WorkspaceModel that is visited is the root of the tree view
// and its children are the solutions.
bool disposeWriters = false;
// Create the writers only if they're null
if (_sw == null)
{
_sw = new StreamWriter(_savePath, false);
if (_writer != null)
_writer.Dispose();
_writer = new HtmlTextWriter(_sw);
disposeWriters = true;
}
if (disposeWriters)
{
// The current WorkspaceModel is the root node, no need to increase the depth
_writer.AddAttribute(HtmlTextWriterAttribute.Id, "browserTree");
_writer.AddAttribute(HtmlTextWriterAttribute.Class, "treeview");
_writer.AddAttribute("data-role", "treeview");
_writer.RenderBeginTag(HtmlTextWriterTag.Ul);
}
else
{
// The current WorkspaceModel is a Child of the root node.
depth++;
}
base.VisitWorkspace(workspaceModel);
if (disposeWriters)
{
// The current WorkspaceModel is the root node.
// Every child has been visited: dispose the writers.
disposeWriters = false;
_writer.RenderEndTag();
_writer.WriteLine();
_writer.Dispose();
_sw.Dispose();
}
else
{
// The current WorkspaceModel is a Child of the root node.
depth--;
}
}
protected override void VisitFolder(FolderModel folderModel)
{
// The clicable element with the folder name:
_writer.AddAttribute(HtmlTextWriterAttribute.Class, "node collapsed");
// ID will be used to programmatically show the underlying UL tag by removing "collapsed" class
//NOTE: We need to correct the backslashes to forward slashes... Thanks Windows...
var urlStylePath = folderModel.RelativePath.Replace('\\','/');
_writer.AddAttribute(HtmlTextWriterAttribute.Id, urlStylePath);
_writer.AddAttribute(HtmlTextWriterAttribute.Title, HttpUtility.HtmlEncode(folderModel.Name)); // Tooltip
_writer.RenderBeginTag(HtmlTextWriterTag.Li);
// Folder item is not a link. It is merely used to hide/show the underlying UL tag
_writer.AddAttribute(HtmlTextWriterAttribute.Href, "#");
_writer.AddAttribute(HtmlTextWriterAttribute.Style, "margin-left: " + depth * 10 + "px;");
_writer.RenderBeginTag(HtmlTextWriterTag.A);
// The expander:
_writer.AddAttribute(HtmlTextWriterAttribute.Class, "node-toggle");
_writer.RenderBeginTag(HtmlTextWriterTag.Span);
_writer.RenderEndTag(); // span
_writer.Write(HttpUtility.HtmlEncode(folderModel.Name));
_writer.RenderEndTag(); // a
// li end tag will be written later
_writer.WriteLine();
// The underlying tree branch:
_writer.RenderBeginTag(HtmlTextWriterTag.Ul);
depth++;
base.VisitFolder(folderModel);
depth--;
_writer.RenderEndTag(); // ul
_writer.WriteLine();
_writer.RenderEndTag(); // li
_writer.WriteLine();
}
protected override void VisitDocument(DocumentModel documentModel)
{
_writer.AddAttribute(HtmlTextWriterAttribute.Class, "node collapsed");
_writer.AddAttribute(HtmlTextWriterAttribute.Title, HttpUtility.HtmlEncode(documentModel.Name)); // Tooltip
_writer.RenderBeginTag(HtmlTextWriterTag.Li);
//NOTE: We need to correct the backslashes to forward slashes... Thanks Windows...
string linkPath = Path.Combine(_userNameAndRepoPrefix, documentModel.RelativePath);
var urlStylePath = linkPath.Replace('\\','/');
_writer.AddAttribute(HtmlTextWriterAttribute.Href, urlStylePath);
_writer.AddAttribute(HtmlTextWriterAttribute.Style, "margin-left: " + depth * 10 + "px;");
_writer.RenderBeginTag(HtmlTextWriterTag.A);
_writer.Write(HttpUtility.HtmlEncode(documentModel.Name));
_writer.RenderEndTag(); // a
base.VisitDocument(documentModel);
_writer.RenderEndTag(); // li
_writer.WriteLine();
}
}
}