AspElements.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815
  1. //
  2. // System.Web.Compilation.AspElements
  3. //
  4. // Authors:
  5. // Gonzalo Paniagua Javier ([email protected])
  6. //
  7. // (C) 2002 Ximian, Inc (http://www.ximian.com)
  8. //
  9. using System;
  10. using System.Collections;
  11. using System.Reflection;
  12. using System.Text;
  13. using System.Web.UI;
  14. using System.Web.UI.HtmlControls;
  15. using System.Web.UI.WebControls;
  16. namespace System.Web.Compilation
  17. {
  18. enum ElementType
  19. {
  20. TAG,
  21. PLAINTEXT
  22. }
  23. abstract class Element
  24. {
  25. private ElementType elementType;
  26. public Element (ElementType type)
  27. {
  28. elementType = type;
  29. }
  30. public ElementType GetElementType
  31. {
  32. get { return elementType; }
  33. }
  34. } // class Element
  35. class PlainText : Element
  36. {
  37. private StringBuilder text;
  38. public PlainText () : base (ElementType.PLAINTEXT)
  39. {
  40. text = new StringBuilder ();
  41. }
  42. public PlainText (StringBuilder text) : base (ElementType.PLAINTEXT)
  43. {
  44. this.text = text;
  45. }
  46. public PlainText (string text) : this ()
  47. {
  48. this.text.Append (text);
  49. }
  50. public void Append (string more)
  51. {
  52. text.Append (more);
  53. }
  54. public string Text
  55. {
  56. get { return text.ToString (); }
  57. }
  58. public override string ToString ()
  59. {
  60. return "PlainText: " + Text;
  61. }
  62. }
  63. enum TagType
  64. {
  65. DIRECTIVE,
  66. HTML,
  67. HTMLCONTROL,
  68. SERVERCONTROL,
  69. INLINEVAR,
  70. INLINECODE,
  71. CLOSING,
  72. SERVEROBJECT,
  73. PROPERTYTAG,
  74. CODERENDER,
  75. DATABINDING,
  76. SERVERCOMMENT,
  77. NOTYET
  78. }
  79. /*
  80. * Attributes and values are stored in a couple of ArrayList in Add ().
  81. * When MakeHash () is called, they are converted to a Hashtable. If there are any
  82. * attributes duplicated it throws an ArgumentException.
  83. *
  84. * The [] operator works with the Hashtable if the values are in it, otherwise
  85. * it uses the ArrayList's.
  86. *
  87. * Why? You can have a tag in HTML like <a att="value" att="xxx">, but not in tags
  88. * marked runat=server and Hashtable requires the key to be unique.
  89. *
  90. */
  91. class TagAttributes
  92. {
  93. private Hashtable atts_hash;
  94. private ArrayList keys;
  95. private ArrayList values;
  96. private bool got_hashed;
  97. public TagAttributes ()
  98. {
  99. got_hashed = false;
  100. keys = new ArrayList ();
  101. values = new ArrayList ();
  102. }
  103. private void MakeHash ()
  104. {
  105. atts_hash = new Hashtable (new CaseInsensitiveHashCodeProvider (),
  106. new CaseInsensitiveComparer ());
  107. for (int i = 0; i < keys.Count; i++)
  108. atts_hash.Add (keys [i], values [i]);
  109. got_hashed = true;
  110. keys = null;
  111. values = null;
  112. }
  113. public bool IsRunAtServer ()
  114. {
  115. return got_hashed;
  116. }
  117. public void Add (object key, object value)
  118. {
  119. if (key != null && value != null &&
  120. 0 == String.Compare ((string) key, "runat", true) &&
  121. 0 == String.Compare ((string) value, "server", true))
  122. MakeHash ();
  123. if (got_hashed)
  124. atts_hash.Add (key, value);
  125. else {
  126. keys.Add (key);
  127. values.Add (value);
  128. }
  129. }
  130. public ICollection Keys
  131. {
  132. get { return (got_hashed ? atts_hash.Keys : keys); }
  133. }
  134. private int CaseInsensitiveSearch (string key)
  135. {
  136. // Hope not to have many attributes when the tag is not a server tag...
  137. for (int i = 0; i < keys.Count; i++){
  138. if (0 == String.Compare ((string) keys [i], key, true))
  139. return i;
  140. }
  141. return -1;
  142. }
  143. public object this [object key]
  144. {
  145. get {
  146. if (got_hashed)
  147. return atts_hash [key];
  148. int idx = CaseInsensitiveSearch ((string) key);
  149. if (idx == -1)
  150. return null;
  151. return values [idx];
  152. }
  153. set {
  154. if (got_hashed)
  155. atts_hash [key] = value;
  156. else {
  157. int idx = CaseInsensitiveSearch ((string) key);
  158. keys [idx] = value;
  159. }
  160. }
  161. }
  162. public int Count
  163. {
  164. get { return (got_hashed ? atts_hash.Count : keys.Count);}
  165. }
  166. public bool IsDataBound (string att)
  167. {
  168. if (att == null || !got_hashed)
  169. return false;
  170. return (att.StartsWith ("<%#") && att.EndsWith ("%>"));
  171. }
  172. public override string ToString ()
  173. {
  174. string ret = "";
  175. string value;
  176. foreach (string key in Keys){
  177. value = (string) this [key];
  178. value = value == null ? "" : value;
  179. ret += key + "=" + value + " ";
  180. }
  181. return ret;
  182. }
  183. }
  184. class Tag : Element
  185. {
  186. protected string tag;
  187. protected TagType tagType;
  188. protected TagAttributes attributes;
  189. protected bool self_closing;
  190. protected bool hasDefaultID;
  191. private static int ctrlNumber = 1;
  192. internal Tag (ElementType etype) : base (etype) { }
  193. internal Tag (Tag other) :
  194. this (other.tag, other.attributes, other.self_closing)
  195. {
  196. this.tagType = other.tagType;
  197. }
  198. public Tag (string tag, TagAttributes attributes, bool self_closing) :
  199. base (ElementType.TAG)
  200. {
  201. if (tag == null)
  202. throw new ArgumentNullException ();
  203. this.tag = tag;
  204. this.attributes = attributes;
  205. this.tagType = TagType.NOTYET;
  206. this.self_closing = self_closing;
  207. this.hasDefaultID = false;
  208. }
  209. public string TagID
  210. {
  211. get { return tag; }
  212. }
  213. public TagType TagType
  214. {
  215. get { return tagType; }
  216. }
  217. public bool SelfClosing
  218. {
  219. get { return self_closing; }
  220. }
  221. public TagAttributes Attributes
  222. {
  223. get { return attributes; }
  224. }
  225. public string PlainHtml
  226. {
  227. get {
  228. StringBuilder plain = new StringBuilder ();
  229. plain.Append ('<');
  230. if (tagType == TagType.CLOSING)
  231. plain.Append ('/');
  232. plain.Append (tag);
  233. if (attributes != null){
  234. plain.Append (' ');
  235. foreach (string key in attributes.Keys){
  236. plain.Append (key);
  237. if (attributes [key] != null){
  238. plain.Append ("=\"");
  239. plain.Append ((string) attributes [key]);
  240. plain.Append ("\" ");
  241. }
  242. }
  243. }
  244. if (self_closing)
  245. plain.Append ('/');
  246. plain.Append ('>');
  247. return plain.ToString ();
  248. }
  249. }
  250. public override string ToString ()
  251. {
  252. return TagID + " " + Attributes + " " + self_closing;
  253. }
  254. public bool HasDefaultID
  255. {
  256. get { return hasDefaultID; }
  257. }
  258. protected virtual void SetNewID ()
  259. {
  260. if (attributes == null)
  261. attributes = new TagAttributes ();
  262. attributes.Add ("ID", GetDefaultID ());
  263. hasDefaultID = true;
  264. }
  265. public static string GetDefaultID ()
  266. {
  267. return "_control" + ctrlNumber++;
  268. }
  269. }
  270. class CloseTag : Tag
  271. {
  272. public CloseTag (string tag) : base (tag, null, false)
  273. {
  274. tagType = TagType.CLOSING;
  275. }
  276. }
  277. class Directive : Tag
  278. {
  279. private static Hashtable directivesHash;
  280. private static string [] page_atts = { "AspCompat", "AutoEventWireup ", "Buffer",
  281. "ClassName", "ClientTarget", "CodePage",
  282. "CompilerOptions", "ContentType", "Culture", "Debug",
  283. "Description", "EnableSessionState", "EnableViewState",
  284. "EnableViewStateMac", "ErrorPage", "Explicit",
  285. "Inherits", "Language", "LCID", "ResponseEncoding",
  286. "Src", "SmartNavigation", "Strict", "Trace",
  287. "TraceMode", "Transaction", "UICulture",
  288. "WarningLevel" };
  289. private static string [] control_atts = { "AutoEventWireup", "ClassName", "CompilerOptions",
  290. "Debug", "Description", "EnableViewState",
  291. "Explicit", "Inherits", "Language", "Strict", "Src",
  292. "WarningLevel" };
  293. private static string [] import_atts = { "namespace" };
  294. private static string [] implements_atts = { "interface" };
  295. private static string [] assembly_atts = { "name", "src" };
  296. private static string [] register_atts = { "tagprefix", "tagname", "Namespace",
  297. "Src", "Assembly" };
  298. private static string [] outputcache_atts = { "Duration", "Location", "VaryByControl",
  299. "VaryByCustom", "VaryByHeader", "VaryByParam" };
  300. private static string [] reference_atts = { "page", "control" };
  301. private static string [] webservice_atts = { "class", "codebehind", "debug", "language" };
  302. private static string [] application_atts = { "description", "inherits" };
  303. static Directive ()
  304. {
  305. InitHash ();
  306. }
  307. private static void InitHash ()
  308. {
  309. CaseInsensitiveHashCodeProvider provider = new CaseInsensitiveHashCodeProvider ();
  310. CaseInsensitiveComparer comparer = new CaseInsensitiveComparer ();
  311. directivesHash = new Hashtable (provider, comparer);
  312. // Use Hashtable 'cause is O(1) in Contains (ArrayList is O(n))
  313. Hashtable valid_attributes = new Hashtable (provider, comparer);
  314. foreach (string att in page_atts) valid_attributes.Add (att, null);
  315. directivesHash.Add ("PAGE", valid_attributes);
  316. valid_attributes = new Hashtable (provider, comparer);
  317. foreach (string att in control_atts) valid_attributes.Add (att, null);
  318. directivesHash.Add ("CONTROL", valid_attributes);
  319. valid_attributes = new Hashtable (provider, comparer);
  320. foreach (string att in import_atts) valid_attributes.Add (att, null);
  321. directivesHash.Add ("IMPORT", valid_attributes);
  322. valid_attributes = new Hashtable (provider, comparer);
  323. foreach (string att in implements_atts) valid_attributes.Add (att, null);
  324. directivesHash.Add ("IMPLEMENTS", valid_attributes);
  325. valid_attributes = new Hashtable (provider, comparer);
  326. foreach (string att in register_atts) valid_attributes.Add (att, null);
  327. directivesHash.Add ("REGISTER", valid_attributes);
  328. valid_attributes = new Hashtable (provider, comparer);
  329. foreach (string att in assembly_atts) valid_attributes.Add (att, null);
  330. directivesHash.Add ("ASSEMBLY", valid_attributes);
  331. valid_attributes = new Hashtable (provider, comparer);
  332. foreach (string att in outputcache_atts) valid_attributes.Add (att, null);
  333. directivesHash.Add ("OUTPUTCACHE", valid_attributes);
  334. valid_attributes = new Hashtable (provider, comparer);
  335. foreach (string att in reference_atts) valid_attributes.Add (att, null);
  336. directivesHash.Add ("REFERENCE", valid_attributes);
  337. valid_attributes = new Hashtable (provider, comparer);
  338. foreach (string att in webservice_atts) valid_attributes.Add (att, null);
  339. directivesHash.Add ("WEBSERVICE", valid_attributes);
  340. valid_attributes = new Hashtable (provider, comparer);
  341. foreach (string att in application_atts) valid_attributes.Add (att, null);
  342. directivesHash.Add ("APPLICATION", valid_attributes);
  343. }
  344. public Directive (string tag, TagAttributes attributes) :
  345. base (tag, attributes, true)
  346. {
  347. CheckAttributes ();
  348. tagType = TagType.DIRECTIVE;
  349. }
  350. private void CheckAttributes ()
  351. {
  352. Hashtable atts;
  353. if (!(directivesHash [tag] is Hashtable))
  354. throw new ApplicationException ("Unknown directive: " + tag);
  355. atts = (Hashtable) directivesHash [tag];
  356. foreach (string att in attributes.Keys){
  357. if (!atts.Contains (att))
  358. throw new ApplicationException ("Attribute " + att +
  359. " not valid for tag " + tag);
  360. }
  361. }
  362. public static bool IsDirectiveID (string id)
  363. {
  364. return directivesHash.Contains (id);
  365. }
  366. public override string ToString ()
  367. {
  368. return "Directive: " + tag;
  369. }
  370. }
  371. class ServerObjectTag : Tag
  372. {
  373. public ServerObjectTag (Tag tag) :
  374. base (tag.TagID, tag.Attributes, tag.SelfClosing)
  375. {
  376. tagType = TagType.SERVEROBJECT;
  377. if (!attributes.IsRunAtServer ())
  378. throw new ApplicationException ("<object> without runat=server");
  379. if (attributes.Count != 3 || !SelfClosing || ObjectID == null || ObjectClass == null)
  380. throw new ApplicationException ("Incorrect syntax: <object id=\"name\" " +
  381. "class=\"full.class.name\" runat=\"server\" />");
  382. }
  383. public string ObjectID
  384. {
  385. get { return (string) attributes ["id"]; }
  386. }
  387. public string ObjectClass
  388. {
  389. get { return (string) attributes ["class"]; }
  390. }
  391. }
  392. class HtmlControlTag : Tag
  393. {
  394. private Type control_type;
  395. private bool is_container;
  396. private static Hashtable controls;
  397. private static Hashtable inputTypes;
  398. private static void InitHash ()
  399. {
  400. controls = new Hashtable (new CaseInsensitiveHashCodeProvider (),
  401. new CaseInsensitiveComparer ());
  402. controls.Add ("A", typeof (HtmlAnchor));
  403. controls.Add ("BUTTON", typeof (HtmlButton));
  404. controls.Add ("FORM", typeof (HtmlForm));
  405. controls.Add ("IMG", typeof (HtmlImage));
  406. controls.Add ("INPUT", "INPUT");
  407. controls.Add ("SELECT", typeof (HtmlSelect));
  408. controls.Add ("TABLE", typeof (HtmlTable));
  409. controls.Add ("TD", typeof (HtmlTableCell));
  410. controls.Add ("TH", typeof (HtmlTableCell));
  411. controls.Add ("TR", typeof (HtmlTableRow));
  412. controls.Add ("TEXTAREA", typeof (HtmlTextArea));
  413. inputTypes = new Hashtable (new CaseInsensitiveHashCodeProvider (),
  414. new CaseInsensitiveComparer ());
  415. inputTypes.Add ("BUTTON", typeof (HtmlInputButton));
  416. inputTypes.Add ("SUBMIT", typeof (HtmlInputButton));
  417. inputTypes.Add ("RESET", typeof (HtmlInputButton));
  418. inputTypes.Add ("CHECKBOX", typeof (HtmlInputCheckBox));
  419. inputTypes.Add ("FILE", typeof (HtmlInputFile));
  420. inputTypes.Add ("HIDDEN", typeof (HtmlInputHidden));
  421. inputTypes.Add ("IMAGE", typeof (HtmlInputImage));
  422. inputTypes.Add ("RADIO", typeof (HtmlInputRadioButton));
  423. inputTypes.Add ("TEXT", typeof (HtmlInputText));
  424. inputTypes.Add ("PASSWORD", typeof (HtmlInputText));
  425. }
  426. static HtmlControlTag ()
  427. {
  428. InitHash ();
  429. }
  430. public HtmlControlTag (string tag, TagAttributes attributes, bool self_closing) :
  431. base (tag, attributes, self_closing)
  432. {
  433. SetData ();
  434. if (attributes == null || attributes ["ID"] == null)
  435. SetNewID ();
  436. }
  437. public HtmlControlTag (Tag source_tag) :
  438. this (source_tag.TagID, source_tag.Attributes, source_tag.SelfClosing)
  439. {
  440. }
  441. private void SetData ()
  442. {
  443. tagType = TagType.HTMLCONTROL;
  444. if (!(controls [tag] is string)){
  445. control_type = (Type) controls [tag];
  446. if (control_type == null)
  447. control_type = typeof (HtmlGenericControl);
  448. is_container = (0 != String.Compare (tag, "img", true));
  449. } else {
  450. string type_value = (string) attributes ["TYPE"];
  451. if (type_value== null)
  452. throw new ArgumentException ("INPUT tag without TYPE attribute!!!");
  453. control_type = (Type) inputTypes [type_value];
  454. //TODO: what does MS with this one?
  455. if (control_type == null)
  456. throw new ArgumentException ("Unknown input type -> " + type_value);
  457. is_container = false;
  458. self_closing = true; // All <input ...> are self-closing
  459. }
  460. }
  461. public Type ControlType
  462. {
  463. get { return control_type; }
  464. }
  465. public string ControlID
  466. {
  467. get { return (string) attributes ["ID"]; }
  468. }
  469. public bool IsContainer
  470. {
  471. get { return is_container; }
  472. }
  473. public override string ToString ()
  474. {
  475. string ret = "HtmlControlTag: " + tag + " Name: " + ControlID + "Type:" +
  476. control_type.ToString () + "\n\tAttributes:\n";
  477. foreach (string key in attributes.Keys){
  478. ret += "\t" + key + "=" + attributes [key];
  479. }
  480. return ret;
  481. }
  482. }
  483. enum ChildrenKind
  484. {
  485. NONE,
  486. /*
  487. * Children must be ASP.NET server controls. Literal text is passed as LiteralControl.
  488. * Child controls and text are added using AddParsedSubObject ().
  489. */
  490. CONTROLS,
  491. /*
  492. * Children must correspond to properties of the parent control. No literal text allowed.
  493. */
  494. PROPERTIES,
  495. /*
  496. * Special case used inside <columns>...</columns>
  497. * Only allow DataGridColumn and derived classes.
  498. */
  499. DBCOLUMNS,
  500. /*
  501. * Special case for list controls (ListBox, DropDownList...)
  502. */
  503. LISTITEM,
  504. /* For HtmlSelect children. They are <option> tags that must
  505. * be treated as ListItem
  506. */
  507. OPTION
  508. }
  509. // TODO: support for ControlBuilderAttribute that may be used in custom controls
  510. class AspComponent : Tag
  511. {
  512. private Type type;
  513. private string alias;
  514. private string control_type;
  515. private bool is_close_tag;
  516. private bool allow_children;
  517. private ChildrenKind children_kind;
  518. private string defaultPropertyName;
  519. private ChildrenKind GuessChildrenKind (Type type)
  520. {
  521. object [] custom_atts = type.GetCustomAttributes (true);
  522. foreach (object custom_att in custom_atts){
  523. if (custom_att is ParseChildrenAttribute){
  524. /* FIXME
  525. * When adding full support for custom controls, we gotta
  526. * bear in mind the pca.DefaultProperty value
  527. */
  528. ParseChildrenAttribute pca = custom_att as ParseChildrenAttribute;
  529. defaultPropertyName = pca.DefaultProperty;
  530. /* this property will be true for all controls derived from
  531. * WebControls. */
  532. if (pca.ChildrenAsProperties == false)
  533. return ChildrenKind.CONTROLS;
  534. else if (defaultPropertyName == "")
  535. return ChildrenKind.PROPERTIES;
  536. else
  537. return ChildrenKind.LISTITEM;
  538. }
  539. }
  540. return ChildrenKind.NONE;
  541. }
  542. private static bool GuessAllowChildren (Type type)
  543. {
  544. PropertyInfo controls = type.GetProperty ("Controls");
  545. if (controls == null)
  546. return false;
  547. MethodInfo getm = controls.GetGetMethod ();
  548. object control_instance = Activator.CreateInstance (type);
  549. object control_collection = getm.Invoke (control_instance, null);
  550. return (!(control_collection is System.Web.UI.EmptyControlCollection));
  551. }
  552. public AspComponent (Tag input_tag, Type type) :
  553. base (input_tag)
  554. {
  555. tagType = TagType.SERVERCONTROL;
  556. this.is_close_tag = input_tag is CloseTag;
  557. this.type = type;
  558. this.defaultPropertyName = "";
  559. this.allow_children = GuessAllowChildren (type);
  560. if (input_tag.SelfClosing)
  561. this.children_kind = ChildrenKind.NONE;
  562. else if (type == typeof (System.Web.UI.WebControls.DataGridColumn) ||
  563. type.IsSubclassOf (typeof (System.Web.UI.WebControls.DataGridColumn)))
  564. this.children_kind = ChildrenKind.PROPERTIES;
  565. else if (type == typeof (System.Web.UI.WebControls.ListItem))
  566. this.children_kind = ChildrenKind.CONTROLS;
  567. else
  568. this.children_kind = GuessChildrenKind (type);
  569. int pos = input_tag.TagID.IndexOf (':');
  570. alias = tag.Substring (0, pos);
  571. control_type = tag.Substring (pos + 1);
  572. if (attributes == null || attributes ["ID"] == null)
  573. SetNewID ();
  574. }
  575. public Type ComponentType
  576. {
  577. get { return type; }
  578. }
  579. public string ControlID
  580. {
  581. get { return (string) attributes ["ID"]; }
  582. }
  583. public bool IsCloseTag
  584. {
  585. get { return is_close_tag; }
  586. }
  587. public bool AllowChildren
  588. {
  589. get { return allow_children; }
  590. }
  591. public ChildrenKind ChildrenKind
  592. {
  593. get { return children_kind; }
  594. }
  595. public string DefaultPropertyName
  596. {
  597. get { return defaultPropertyName; }
  598. }
  599. public override string ToString ()
  600. {
  601. return type.ToString () + " Alias: " + alias + " ID: " + (string) attributes ["id"];
  602. }
  603. }
  604. class PropertyTag : Tag
  605. {
  606. private Type type;
  607. private string name;
  608. public PropertyTag (Tag tag, Type type, string name)
  609. : base (tag)
  610. {
  611. tagType = TagType.PROPERTYTAG;
  612. SetNewID ();
  613. this.name = name;
  614. this.type = type;
  615. }
  616. public Type PropertyType
  617. {
  618. get { return type; }
  619. }
  620. public string PropertyID
  621. {
  622. get { return (string) attributes ["ID"]; }
  623. }
  624. public string PropertyName
  625. {
  626. get { return name; }
  627. }
  628. }
  629. class CodeRenderTag : Tag
  630. {
  631. private string code;
  632. private bool isVarName;
  633. public CodeRenderTag (bool isVarName, string code) : base ("", null, false)
  634. {
  635. tagType = TagType.CODERENDER;
  636. this.isVarName = isVarName;
  637. this.code = code.Trim ();
  638. }
  639. public string Code
  640. {
  641. get { return code; }
  642. }
  643. public bool IsVarName
  644. {
  645. get { return isVarName; }
  646. }
  647. public string AsText
  648. {
  649. get { return "<%" + (IsVarName ? "=" : "") + Code + "%>"; }
  650. }
  651. }
  652. class DataBindingTag : Tag
  653. {
  654. private string data;
  655. public DataBindingTag (string data) : base ("", null, false)
  656. {
  657. tagType = TagType.DATABINDING;
  658. this.data = data.Trim ();
  659. }
  660. public string Data
  661. {
  662. get { return data; }
  663. }
  664. public string AsText
  665. {
  666. get { return "<%#" + Data + "%>"; }
  667. }
  668. }
  669. class ServerComment : Tag
  670. {
  671. public ServerComment (string tag)
  672. : base (ElementType.TAG)
  673. {
  674. if (tag == null)
  675. throw new ArgumentNullException ();
  676. this.tag = tag;
  677. this.attributes = null;
  678. this.tagType = TagType.SERVERCOMMENT;
  679. this.self_closing = true;
  680. this.hasDefaultID = false;
  681. }
  682. public override string ToString ()
  683. {
  684. return TagID;
  685. }
  686. protected override void SetNewID ()
  687. {
  688. throw new NotSupportedException ();
  689. }
  690. }
  691. }