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