コード例 #1
0
		public DirectiveNode (ILocation location, string name, TagAttributes attributes)
			: base (location)
		{
			this.name = name;
			this.attributes = attributes;
			
			//FIXME: workaround for weird parser MasterPage bug
			if (string.IsNullOrEmpty(name))
				foreach (string key in attributes.Keys)
					if (key.ToLower() == "master")
						this.name = "Master";
		}
コード例 #2
0
        public DirectiveNode(ILocation location, string name, TagAttributes attributes)
            : base(location)
        {
            this.name       = name;
            this.attributes = attributes;

            //FIXME: workaround for weird parser MasterPage bug
            if (string.IsNullOrEmpty(name))
            {
                foreach (string key in attributes.Keys)
                {
                    if (key.ToLower() == "master")
                    {
                        this.name = "Master";
                    }
                }
            }
        }
コード例 #3
0
        void TagParsed(ILocation location, TagType tagtype, string tagId, TagAttributes attributes)
        {
            switch (tagtype)
            {
            case TagType.Close:
                TagNode tn = currentNode as TagNode;
                if (tn == null)
                {
                    errors.Add(new ParseException(location, "Closing tag '" + tagId + "' does not match an opening tag."));
                }
                else
                {
                    if (tn.TagName == tagId)
                    {
                        tn.EndLocation = location;
                        currentNode    = currentNode.Parent;
                        tn.Close();
                    }
                    else
                    {
                        errors.Add(new ParseException(location, "Closing tag '" + tagId + "' does not match opening tag '" + tn.TagName + "'."));
                        currentNode = currentNode.Parent;
                        TagParsed(location, TagType.Close, tagId, null);
                    }
                }
                break;

            case TagType.CodeRender:
            case TagType.CodeRenderExpression:
            case TagType.DataBinding:
                try {
                    AddtoCurrent(location, new ExpressionNode(location, tagId, tagtype == TagType.CodeRenderExpression));
                } catch (ParseException ex) {
                    errors.Add(ex);
                }
                break;

            case TagType.Directive:
                try {
                    AddtoCurrent(location, new DirectiveNode(location, tagId, attributes));
                } catch (ParseException ex) {
                    errors.Add(ex);
                }
                break;

            case TagType.Include:
                throw new NotImplementedException("Server-side includes have not yet been implemented: " + location.PlainText);

            case TagType.ServerComment:
                //FIXME: the parser doesn't actually return these
                throw new NotImplementedException("Server comments have not yet been implemented: " + location.PlainText);

            case TagType.SelfClosing:
                try {
                    tn = new TagNode(location, tagId, attributes);
                    AddtoCurrent(location, tn);
                    tn.Close();
                } catch (ParseException ex) {
                    errors.Add(ex);
                }
                break;

            case TagType.Tag:
                try {
                    //HACK: implicit close on block level in HTML4
                    TagNode prevTag = currentNode as TagNode;
                    if (prevTag != null)
                    {
                        if (Array.IndexOf(implicitCloseOnBlock, prevTag.TagName.ToLowerInvariant()) > -1 &&
                            Array.IndexOf(blockLevel, tagId.ToLowerInvariant()) > -1)
                        {
                            errors.Add(new ParseException(location, "Unclosed " + prevTag.TagName + " tag. Assuming implicitly closed by block level tag."));
                            prevTag.Close();
                            currentNode = currentNode.Parent;
                        }
                    }

                    //create and add the new tag
                    TagNode child = new TagNode(location, tagId, attributes);
                    AddtoCurrent(location, child);

                    //HACK: implicitly closing tags in HTML4
                    if (Array.IndexOf(implicitSelfClosing, tagId.ToLowerInvariant()) > -1)
                    {
                        errors.Add(new ParseException(location, "Unclosed " + tagId + " tag. Assuming implicitly closed."));
                        child.Close();
                    }
                    else
                    {
                        currentNode = child;
                    }
                } catch (ParseException ex) {
                    errors.Add(ex);
                }
                break;

            case TagType.Text:
                //FIXME: the parser doesn't actually return these
                throw new NotImplementedException("Text tagtypes have not yet been implemented: " + location.PlainText);
            }
        }
コード例 #4
0
		void OnTagParsed (TagType tagtype, string id, TagAttributes attributes)
		{
			TagParsedHandler eh = events [tagParsedEvent] as TagParsedHandler;
			if (eh != null)
				eh (this, tagtype, id, attributes);
		}
コード例 #5
0
		void GetServerTag (out TagType tagtype, out string id, out TagAttributes attributes)
		{
			string inside_tags;
			bool old = tokenizer.ExpectAttrValue;

			tokenizer.ExpectAttrValue = false;
			if (Eat ('@')){
				tokenizer.ExpectAttrValue = old;
				tagtype = TagType.Directive;
				id = "";
				if (Eat (Token.DIRECTIVE))
					id = tokenizer.Value;

				attributes = GetAttributes ();
				if (!Eat ('%') || !Eat ('>'))
					OnError ("expecting '%>'");

				return;
			}
			
			if (Eat (Token.DOUBLEDASH)) {
				tokenizer.ExpectAttrValue = old;
				tokenizer.Verbatim = true;
				inside_tags = GetVerbatim (tokenizer.get_token (), "--%>");
				tokenizer.Verbatim = false;
				id = null;
				attributes = null;
				tagtype = TagType.ServerComment;
				return;
			}

			tokenizer.ExpectAttrValue = old;
			bool varname;
			bool databinding;
			varname = Eat ('=');
			databinding = !varname && Eat ('#');

			tokenizer.Verbatim = true;
			inside_tags = GetVerbatim (tokenizer.get_token (), "%>");
			tokenizer.Verbatim = false;
			id = inside_tags;
			attributes = null;
			tagtype = (databinding ? TagType.DataBinding :
				  (varname ? TagType.CodeRenderExpression : TagType.CodeRender));
		}
コード例 #6
0
		TagAttributes GetAttributes ()
		{
			int token;
			TagAttributes attributes;
			string id;
			bool wellFormedForServer = true;

			attributes = new TagAttributes ();
			while ((token = tokenizer.get_token ()) != Token.EOF){
				if (token == '<' && Eat ('%')) {
					tokenizer.Verbatim = true;
					attributes.Add ("", "<%" + 
							GetVerbatim (tokenizer.get_token (), "%>") + "%>");
					tokenizer.Verbatim = false;
					tokenizer.InTag = true;
					continue;
				}
					
				if (token != Token.IDENTIFIER)
					break;

				id = tokenizer.Value;
				if (Eat ('=')){
					if (Eat (Token.ATTVALUE)){
						attributes.Add (id, tokenizer.Value);
						wellFormedForServer &= tokenizer.AlternatingQuotes;
					} else if (Eat ('<') && Eat ('%')) {
						tokenizer.Verbatim = true;
						attributes.Add (id, "<%" + 
								GetVerbatim (tokenizer.get_token (), "%>") + "%>");
						tokenizer.Verbatim = false;
						tokenizer.InTag = true;
					} else {
						OnError ("expected ATTVALUE");
						return null;
					}
				} else {
					attributes.Add (id, null);
				}
			}

			tokenizer.put_back ();

			if (attributes.IsRunAtServer () && !wellFormedForServer) {
				OnError ("The server tag is not well formed.");
				return null;
			}
			
			return attributes;
		}
コード例 #7
0
		void GetTag (out TagType tagtype, out string id, out TagAttributes attributes)
		{
			int token = tokenizer.get_token ();

			tagtype = TagType.ServerComment;
			id = null;
			attributes = null;
			switch (token){
			case '%':
				GetServerTag (out tagtype, out id, out attributes);
				break;
			case '/':
				if (!Eat (Token.IDENTIFIER))
					OnError ("expecting TAGNAME");

				id = tokenizer.Value;
				if (!Eat ('>'))
					OnError ("expecting '>'. Got '" + id + "'");

				tagtype = TagType.Close;
				break;
			case '!':
				bool double_dash = Eat (Token.DOUBLEDASH);
				if (double_dash)
					tokenizer.put_back ();

				tokenizer.Verbatim = true;
				string end = double_dash ? "-->" : ">";
				string comment = GetVerbatim (tokenizer.get_token (), end);
				tokenizer.Verbatim = false;
				if (comment == null)
					OnError ("Unfinished HTML comment/DTD");

				string pathType, filename;
				if (double_dash && GetInclude (comment, out pathType, out filename)) {
					tagtype = TagType.Include;
					attributes = new TagAttributes ();
					attributes.Add (pathType, filename);
				} else {
					tagtype = TagType.Text;
					id = "<!" + comment + end;
				}
				break;
			case Token.IDENTIFIER:
				if (this.filename == "@@inner_string@@") {
					// Actually not tag but "xxx < yyy" stuff in inner_string!
					tagtype = TagType.Text;
					tokenizer.InTag = false;
					id = "<" + tokenizer.Odds + tokenizer.Value;
				} else {
					id = tokenizer.Value;
					try {
						attributes = GetAttributes ();
					} catch (Exception e) {
						OnError (e.Message);
						break;
					}
					
					tagtype = TagType.Tag;
					if (Eat ('/') && Eat ('>')) {
						tagtype = TagType.SelfClosing;
					} else if (!Eat ('>')) {
						if (attributes.IsRunAtServer ()) {
							OnError ("The server tag is not well formed.");
							break;
						}
						tokenizer.Verbatim = true;
						attributes.Add ("", GetVerbatim (tokenizer.get_token (), ">") + ">");
						tokenizer.Verbatim = false;
					}
				}

				break;
			default:
				tagtype = TagType.Text;
				tokenizer.InTag = false;
				id = "<" + tokenizer.Value;
				break;
			}
		}
コード例 #8
0
		void TagParsed (ILocation location, TagType tagtype, string tagId, TagAttributes attributes)
		{
			switch (tagtype)
			{
			case TagType.Close:
				TagNode tn = currentNode as TagNode;
				if (tn == null) {
					errors.Add (new ParseException (location, "Closing tag '" + tagId +"' does not match an opening tag."));
				} else {
					if (tn.TagName == tagId) {
						tn.EndLocation = location;
						currentNode = currentNode.Parent;
						tn.Close ();
					} else {
						errors.Add (new ParseException (location, "Closing tag '" + tagId +"' does not match opening tag '" + tn.TagName + "'."));
						currentNode = currentNode.Parent;
						TagParsed (location, TagType.Close, tagId, null);
					}
				}
				break;
				
			case TagType.CodeRender:
			case TagType.CodeRenderExpression:
			case TagType.DataBinding:
				try {
					AddtoCurrent (location, new ExpressionNode (location, tagId, tagtype == TagType.CodeRenderExpression));
				} catch (ParseException ex) {
					errors.Add (ex);
				}
				break;
				
			case TagType.Directive:
				try {
					AddtoCurrent (location, new DirectiveNode (location, tagId, attributes));
				} catch (ParseException ex) {
					errors.Add (ex);
				}	
				break;
				
			case TagType.Include:
				throw new NotImplementedException ("Server-side includes have not yet been implemented: " + location.PlainText);
				
			case TagType.ServerComment:
				//FIXME: the parser doesn't actually return these
				throw new NotImplementedException ("Server comments have not yet been implemented: " + location.PlainText);
				
			case TagType.SelfClosing:
				try {
					tn = new TagNode (location, tagId, attributes);
					AddtoCurrent (location, tn);
					tn.Close ();
				} catch (ParseException ex) {
					errors.Add (ex);
				}
				break;
				
			case TagType.Tag:
				try {
					//HACK: implicit close on block level in HTML4
					TagNode prevTag = currentNode as TagNode;
					if (prevTag != null) {
						if (Array.IndexOf (implicitCloseOnBlock, prevTag.TagName.ToLowerInvariant ()) > -1
						    && Array.IndexOf (blockLevel, tagId.ToLowerInvariant ()) > -1) {
							errors.Add (new ParseException (location, "Unclosed " + prevTag.TagName + " tag. Assuming implicitly closed by block level tag."));
							prevTag.Close ();
							currentNode = currentNode.Parent;
						}
					}
					
					//create and add the new tag
					TagNode child = new TagNode (location, tagId, attributes);
					AddtoCurrent (location, child);
					
					//HACK: implicitly closing tags in HTML4
					if (Array.IndexOf (implicitSelfClosing, tagId.ToLowerInvariant ()) > -1) {
						errors.Add (new ParseException (location, "Unclosed " + tagId + " tag. Assuming implicitly closed."));
						child.Close ();
					} else {
						currentNode = child;
					}
					
				} catch (ParseException ex) {
					errors.Add (ex);
				}
				break;
				
			case TagType.Text:
				//FIXME: the parser doesn't actually return these
				throw new NotImplementedException("Text tagtypes have not yet been implemented: " + location.PlainText);
			}
		}
コード例 #9
0
 internal TagNode(ILocation location, string name, TagAttributes attributes)
     : base(location)
 {
     this.tagName    = name;
     this.attributes = attributes;
 }
コード例 #10
0
		internal TagNode (ILocation location, string name, TagAttributes attributes)
			: base (location)
		{
			this.tagName = name;
			this.attributes = attributes;
		}