做网站的本质无非是一些html加一点点css,再放一些Js做调料,这加工出来的就是各种各样的网站平台;但微软老大却先把html和css做成美国大汉堡,再把JS弄成根香肠提供给广大的食客。虽然大家都喜欢这种大餐,但吃多也终究不是很好,而且有时候我们需要的是一份简单的农家小炒,所以我就通过几天的努力让自己重新有机会直接与HTML、CSS、JS等打交道。
前面有朋友说我只是把<asp:Repeater id="rptTables" > 换成了{repeater rptTables},虽然我当时不太同意这种说法,但细想一下其实这种说法也是对的。这所以要把<asp:Repeater id="rptTables" > 换成{repeater rptTables},是因为后者比前者更容易分析。也有朋友说我是用另一种方式重新实现了另一种ASP.NET控件,其实这也是正确的,ASP.NET控件的好处和使用方式已经是广大.NET程序员所熟悉的东东,为了使别人看到我的方案不至于不知所谓,我也只能实现和它差不多的方案,而且我知道我要的是直接与最原始的原素打交道的权力,而不是要去否定别的方案和形式。
说了这么多,应该开始说说我的代码了,以下是模板分析的主要代码片段,具体的分析我会在后续的文章中进行说明。
1
internal class Template : IUI.ITemplate
2
{
3
bool _isInstantiateIn = false;
4
private Dictionary<string, UIModel.Control> dicContainer;
5
private List<Control> listContainer;
6
private List<Token> tokens;
7
private char[] chrs;
8
9
public Template()
10
{
11
dicContainer = new Dictionary<string, Control>();
12
listContainer = new List<Control>();
13
tokens = new List<Token>();
14
}
15
16
public void InstantiateIn(ref string input)
17
{
18
_isInstantiateIn = true;
19
chrs = input.ToCharArray();
20
21
InitTokens(chrs);
22
23
GroupTokens();
24
25
InitTags();
26
}
27
28
public bool ContainsKey(string id)
29
{
30
return dicContainer.ContainsKey(id);
31
}
32
33
public Ctit.TTCCostPro.UIModel.Control FindControl(string id)
34
{
35
if (dicContainer.ContainsKey(id))
36
{
37
return dicContainer[id];
38
}
39
else
40
{
41
return null;
42
}
43
}
44
45
public string Render()
46
{
47
if (!_isInstantiateIn)
48
throw new Exception("Template must InstantiateIn before render!!");
49
50
//StringBuilder sb = new StringBuilder();
51
52
//for (int i = 0; i < tokens.Count; i++)
53
//{
54
// sb.AppendFormat("First: {0}, Second: {1}, StartIndex: {2}, EndIndex: {3} TokenType: {4} InnerStart: {5}, InnerEnd: {6} <br />", tokens[i].First, tokens[i].Second, tokens[i].StartIndex, tokens[i].EndIndex, tokens[i].TokenType.ToString(), tokens[i].InnerStart, tokens[i].InnerEnd);
55
//}
56
//return sb.ToString();
57
58
StringBuilder sb = new StringBuilder();
59
60
int k = 0;
61
62
for (int i = 0; i < listContainer.Count; i++)
63
{
64
while (k < listContainer[i].StartIndex && k < chrs.Length)
65
{
66
sb.Append(chrs[k]);
67
k++;
68
}
69
70
if (listContainer[i].Display)
71
{
72
StringBuilder sHtml = new StringBuilder();
73
RenderControl(listContainer[i], sHtml);
74
sb.Append(sHtml);
75
}
76
k = listContainer[i].EndIndex + 1;
77
}
78
79
while (k < chrs.Length)
80
{
81
sb.Append(chrs[k++]);
82
}
83
84
return sb.ToString();
85
}
86
87
private void RenderControl(Control ctr, StringBuilder sHtml)
88
{
89
switch (ctr.TagName.ToLower())
90
{
91
case "repeater":
92
{
93
Repeater rpt = (Repeater)ctr;
94
95
96
if (rpt.DataSource != null)
97
{
98
CreateInnerTemplate(sHtml, rpt, rpt.HeaderTemplate);
99
IEnumerable date = (IEnumerable)rpt.DataSource;
100
101
foreach (object o in date)
102
{
103
rpt.Current = new Dictionary<string, string>();
104
PropertyInfo[] properties = o.GetType().GetProperties();
105
foreach (PropertyInfo p in properties)
106
{
107
rpt.Current.Add(p.Name, p.GetValue(o, null).ToString());
108
}
109
CreateInnerTemplate(sHtml, rpt, rpt.ItemTemplate);
110
}
111
112
CreateInnerTemplate(sHtml, rpt, rpt.FooterTemplate);
113
}
114
115
break;
116
}
117
case "view":
118
{
119
break;
120
}
121
case "eval":
122
{
123
TextControl eval = (TextControl)ctr;
124
if (eval.ParentNode.Current.ContainsKey(eval.Second))
125
{
126
sHtml.Append(eval.ParentNode.Current[eval.Second]);
127
}
128
break;
129
}
130
default:
131
{
132
break;
133
}
134
}
135
}
136
137
private void CreateInnerTemplate(StringBuilder sHtml, Repeater rpt, InnerIndex inner)
138
{
139
if (Controls.HadChildTag(inner, rpt))
140
{
141
List<Control> ls = Controls.GetChildNodes(inner, rpt);
142
int k = inner.InnerStart;
143
144
for (int i = 0; i < ls.Count; i++)
145
{
146
while (k < ls[i].StartIndex && k < inner.InnerEnd)
147
{
148
sHtml.Append(chrs[k++]);
149
}
150
151
if (ls[i].Display == true)
152
{
153
RenderControl(ls[i], sHtml);
154
}
155
156
k = ls[i].EndIndex + 1;
157
}
158
159
while (k < inner.InnerEnd)
160
{
161
sHtml.Append(chrs[k++]);
162
}
163
}
164
else
165
{
166
CharsManager.Copy(chrs, inner, sHtml);
167
}
168
}
169
170
private void AddSingleTag(Control parentNode, Token token)
171
{
172
switch (token.First.ToLower())
173
{
174
case "page":
175
case "eval":
176
{
177
TextControl textInfo = new TextControl();
178
textInfo.StartIndex = token.StartIndex;
179
textInfo.EndIndex = token.EndIndex;
180
textInfo.First = token.First;
181
textInfo.Second = token.Second;
182
textInfo.ParentNode = parentNode;
183
textInfo.TagName = token.First;
184
185
//把根结点元素放在列表容器里面去.
186
if (parentNode == null)
187
{
188
listContainer.Add(textInfo);
189
}
190
else//子结点放在父结点下面
191
{
192
parentNode.AppendChild(textInfo);
193
}
194
break;
195
}
196
default:
197
break;
198
}
199
}
200
201
private void AddComplexTag(Control parentNode, ref int index)
202
{
203
if (index >= tokens.Count)
204
return;
205
206
Token token = tokens[index];
207
208
switch (token.First.ToLower())
209
{
210
case "repeater":
211
{
212
Repeater rpt = new Repeater();
213
rpt.Id = token.Second;
214
rpt.StartIndex = token.StartIndex;
215
rpt.EndIndex = token.EndIndex;
216
rpt.ParentNode = parentNode;
217
rpt.TagName = token.First;
218
219
while (++index < tokens.Count && tokens[index].EndIndex != token.EndIndex)
220
{
221
if (tokens[index].TokenType == TokenType.Single)
222
{
223
AddSingleTag(rpt, tokens[index]);
224
}
225
else if (tokens[index].TokenType == TokenType.CloseBegin)
226
{
227
switch (tokens[index].First.ToLower())
228
{
229
case "headertemplate":
230
{
231
rpt.HeaderTemplate.InnerStart = tokens[index].InnerStart;
232
rpt.HeaderTemplate.InnerEnd = tokens[index].InnerEnd;
233
break;
234
}
235
case "itemtemplate":
236
{
237
rpt.ItemTemplate.InnerStart = tokens[index].InnerStart;
238
rpt.ItemTemplate.InnerEnd = tokens[index].InnerEnd;
239
break;
240
}
241
case "alternatingitemtemplate":
242
{
243
rpt.AlternatingItemTemplate.InnerStart = tokens[index].InnerStart;
244
rpt.AlternatingItemTemplate.InnerEnd = tokens[index].InnerEnd;
245
break;
246
}
247
case "separatortemplate":
248
{
249
rpt.SeparatorTemplate.InnerStart = tokens[index].InnerStart;
250
rpt.SeparatorTemplate.InnerEnd = tokens[index].InnerEnd;
251
break;
252
}
253
case "footertemplate":
254
{
255
rpt.FooterTemplate.InnerStart = tokens[index].InnerStart;
256
rpt.FooterTemplate.InnerEnd = tokens[index].InnerEnd;
257
break;
258
}
259
default:
260
break;
261
}
262
}
263
else if (tokens[index].TokenType == TokenType.ComplexBegin)
264
{
265
AddComplexTag(rpt, ref index);
266
}
267
}
268
269
if (parentNode != null)
270
{
271
parentNode.AppendChild(rpt);
272
}
273
else
274
{
275
listContainer.Add(rpt);
276
}
277
278
if (!dicContainer.ContainsKey(rpt.Id))
279
{
280
dicContainer.Add(rpt.Id, rpt);
281
}
282
#if DEBUG
283
else
284
{
285
throw new Exception(string.Format("Another control in this page already uses id: {0}", rpt.Id));
286
}
287
#endif
288
break;
289
}
290
case "view":
291
{
292
break;
293
}
294
default:
295
break;
296
}
297
}
298
299
private void InitTags()
300
{
301
for (int i = 0; i < tokens.Count; i++)
302
{
303
Token token = tokens[i];
304
if (token.TokenType == TokenType.Single)
305
{
306
AddSingleTag(null, token);
307
}
308
else if (token.TokenType == TokenType.ComplexBegin)
309
{
310
AddComplexTag(null, ref i);
311
}
312
}
313
}
314
315
private void InitTokens(char[] chrs)
316
{
317
for (int i = 0; i < chrs.Length; i++)
318
{
319
if (chrs[i] == '{' && (i == 0 || chrs[i - 1] != '\\'))
320
{
321
Token token = new Token();
322
token.StartIndex = i;
323
324
if (chrs[i + 1] == '/')
325
{
326
if (++i >= chrs.Length)
327
break;
328
329
Pair<string, string> p = Tags.GetTag(chrs, ref i);
330
token.First = p.First;
331
token.Second = p.Second;
332
token.TokenType = GetTokenType(token.First, true);
333
}
334
else
335
{
336
Pair<string, string> p = Tags.GetTag(chrs, ref i);
337
token.First = p.First;
338
token.Second = p.Second;
339
token.TokenType = GetTokenType(token.First, false);
340
}
341
342
token.EndIndex = i;
343
tokens.Add(token);
344
}
345
}
346
}
347
348
private void GroupTokens()
349
{
350
Stack<Token> s = new Stack<Token>();
351
352
for (int i = 0; i < tokens.Count; i++)
353
{
354
if (tokens[i].TokenType == TokenType.ComplexBegin || tokens[i].TokenType == TokenType.CloseBegin )
355
{
356
s.Push(tokens[i]);
357
}
358
else if (tokens[i].TokenType == TokenType.ComplexEnd || tokens[i].TokenType == TokenType.CloseEnd)
359
{
360
if (string.Compare(tokens[i].First, s.Peek().First) == 0)
361
{
362
Token token = s.Pop();
363
token.InnerStart = token.EndIndex + 1;
364
token.InnerEnd = tokens[i].StartIndex;
365
token.EndIndex = tokens[i].EndIndex;
366
}
367
else
368
{
369
s.Push(tokens[i]);
370
}
371
}
372
}
373
374
if (s.Count != 0)
375
{
376
throw new Exception("Tags do not match, please check your template file.");
377
}
378
}
379
380
private TokenType GetTokenType(string tagName, bool isEnd)
381
{
382
TagType tagType = TagTypeManager.GetTagType(tagName);
383
TokenType tokenType = new TokenType();
384
385
if (isEnd)
386
{
387
if (tagType == TagType.Close)
388
{
389
tokenType = TokenType.CloseEnd;
390
}
391
else if (tagType == TagType.Complex)
392
{
393
tokenType = TokenType.ComplexEnd;
394
}
395
else
396
{
397
tokenType = TokenType.NotToken;
398
}
399
}
400
else
401
{
402
if (tagType == TagType.Close)
403
{
404
tokenType = TokenType.CloseBegin;
405
}
406
else if (tagType == TagType.Complex)
407
{
408
tokenType = TokenType.ComplexBegin;
409
}
410
else if (tagType == TagType.Single)
411
{
412
tokenType = TokenType.Single;
413
}
414
else
415
{
416
tokenType = TokenType.NotToken;
417
}
418
}
419
420
return tokenType;
421
}
422
}

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

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389

390

391

392

393

394

395

396

397

398

399

400

401

402

403

404

405

406

407

408

409

410

411

412

413

414

415

416

417

418

419

420

421

422
