AspElements.cs 21 KB

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