AspElements.cs 21 KB

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