private void ActualProcess(XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction) {
			foreach (INodeProcessor p in processors) {
				if (p.TryProcess(this, node, isRoot, template, currentRenderFunction))
					return;
			}
			throw ParserUtils.TemplateErrorException("The node " + node.ToString() + " could not be handled.");
		}
		public void ProcessRecursive(XmlNode node, ITemplate template, IRenderFunction currentRenderFunction) {
			if (template == null) throw Utils.ArgumentException("template");
			if (currentRenderFunction == null) throw Utils.ArgumentException("currentRenderFunction");
			if (node == null) throw Utils.ArgumentNullException("node");

			ActualProcess(node, false, template, currentRenderFunction);
		}
		public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction) {
			if (node.NodeType != XmlNodeType.Element)
				return false;

			GenericElementProcessorContext context = new GenericElementProcessorContext();

			currentRenderFunction.AddFragment(new LiteralFragment("<" + node.Name));
			AddAttributeFragments(docProcessor, node, isRoot, template, currentRenderFunction, context);

			if (context.Id != null) {
				string tagName = node.Name;
				if (tagName.ToLowerCase() == "input" && context.Type != null)
					tagName += "/" + context.Type;
				template.AddMember(new NamedElementMember(tagName, context.Id));
			}

			if (noContentTags.Contains(node.Name)) {
				if (Utils.GetNumChildNodes(node) > 0)
					throw ParserUtils.TemplateErrorException("The tag " + node.Name + " can not have children.");
				currentRenderFunction.AddFragment(new LiteralFragment("/>"));
			}
			else {
				currentRenderFunction.AddFragment(new LiteralFragment(">"));
				Utils.DoForEachChild(node, delegate(XmlNode child) {
					docProcessor.ProcessRecursive(child, template, currentRenderFunction);
				});
				currentRenderFunction.AddFragment(new LiteralFragment("</" + node.Name + ">"));
			}

			return true;
		}
		public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction) {
			if (node.NodeType != XmlNodeType.ProcessingInstruction || node.Name != "view")
				return false;
			if (!isRoot)
				throw ParserUtils.TemplateErrorException(string.Format("The view directive can only appear outside of the template.", node.Name));

			string[] serverTypeArr = Utils.RegexExec(node.Value, "modelType=\"([^\"]*)\"", "");
			string[] clientTypeArr = Utils.RegexExec(node.Value, "clientModelType=\"([^\"]*)\"", "");
			if (serverTypeArr == null && clientTypeArr != null)
				throw ParserUtils.TemplateErrorException("You cannot specify a client type for the model if you don't specify a server type");

			if (template.HasMember("Model") || template.HasMember("model") || template.HasMember("Saltarelle.Mvc.IView.Model"))
				throw ParserUtils.TemplateErrorException("The template already defines at least one of the members essential to use the view directive. Have you specified <?view?> more than once?");

			string serverType = (serverTypeArr != null ? serverTypeArr[1] : "object"), clientType = (clientTypeArr != null ? clientTypeArr[1] : null);
			string viewInterface = "Saltarelle.Mvc.IView<" + serverType + ">";

			if (template.ImplementsServerInterface(viewInterface))
				throw ParserUtils.TemplateErrorException("The template already implements the interface " + viewInterface + ".");

			template.AddServerInterface(viewInterface);
			template.AddMember(new FieldMember("model", serverType, clientType));
			template.AddMember(new PropertyMember("Model", serverType, null, AccessModifier._Public, "model", serverType, null, true, true, "ModelChanged", false));
			template.AddMember(new PropertyMember("Saltarelle.Mvc.IView.Model", "object", null, AccessModifier._None, "model", serverType, null, true, true, "ModelChanged", false));

			return true;
		}
Пример #5
0
		public virtual void SetupRepo() {
			mocks = new MockRepository();
			template = mocks.StrictMock<ITemplate>();
			docProcessor = mocks.StrictMock<IDocumentProcessor>();
			renderFunction = mocks.StrictMock<IRenderFunction>();
			fragments = new List<IFragment>();
			Expect.Call(() => renderFunction.AddFragment(null)).Do((Action<IFragment>)(f => fragments.Add(f))).IgnoreArguments().Repeat.Any();
		}
Пример #6
0
 public virtual void SetupRepo()
 {
     mocks          = new MockRepository();
     template       = mocks.StrictMock <ITemplate>();
     docProcessor   = mocks.StrictMock <IDocumentProcessor>();
     renderFunction = mocks.StrictMock <IRenderFunction>();
     fragments      = new List <IFragment>();
     Expect.Call(() => renderFunction.AddFragment(null)).Do((Action <IFragment>)(f => fragments.Add(f))).IgnoreArguments().Repeat.Any();
 }
 private void ActualProcess(XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction)
 {
     foreach (INodeProcessor p in processors)
     {
         if (p.TryProcess(this, node, isRoot, template, currentRenderFunction))
         {
             return;
         }
     }
     throw ParserUtils.TemplateErrorException("The node " + node.ToString() + " could not be handled.");
 }
		public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction) {
			if (node.NodeType != XmlNodeType.ProcessingInstruction)
				return false;

			switch (node.Name) {
				case "enableClientCreate":
					if (!isRoot)
						throw ParserUtils.TemplateErrorException("The enableClientCreate directive can only appear outside of the template.");
					template.EnableClientCreate = true;
					return true;
				default:
					return false;
			}
		}
Пример #9
0
		public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction) {
			if (node.NodeType != XmlNodeType.Element || node.Name != "copyright")
				return false;

			if (node.ChildNodes.Count != 1 || node.ChildNodes[0].NodeType != XmlNodeType.Text)
				throw new TemplateErrorException("The copyright node must have a single text child.");

			CopyrightMember m = new CopyrightMember();
			if (template.HasMember(m.Name))
				throw new TemplateErrorException("Duplicate definition of the member " + m.Name);
			template.AddMember(m);
			
			currentRenderFunction.AddFragment(new CopyrightFragment(node.ChildNodes[0].Value));
			
			return true;
		}
		public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction) {
			string name = node.Name;
			if (node.NodeType == XmlNodeType.Element && name == "def-fragment") {
				if (isRoot)
					throw ParserUtils.TemplateErrorException("Fragment definitions must be inside the template.");
				ProcessDefFragment(docProcessor, node, template);
				return true;
			}
			else if (node.NodeType == XmlNodeType.Element && name == "call-fragment") {
				if (isRoot)
					throw ParserUtils.TemplateErrorException("Fragment instantiations must be inside the template.");
				currentRenderFunction.AddFragment(ProcessCallFragment(docProcessor, node));
				return true;
			}
			else
				return false;
		}
        public void ProcessRecursive(XmlNode node, ITemplate template, IRenderFunction currentRenderFunction)
        {
            if (template == null)
            {
                throw Utils.ArgumentException("template");
            }
            if (currentRenderFunction == null)
            {
                throw Utils.ArgumentException("currentRenderFunction");
            }
            if (node == null)
            {
                throw Utils.ArgumentNullException("node");
            }

            ActualProcess(node, false, template, currentRenderFunction);
        }
		public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction) {
			if (node.NodeType != XmlNodeType.ProcessingInstruction)
				return false;

			string v = node.Value.Trim();
			switch (node.Name) {
				case "x":
					if (v == "")
						throw ParserUtils.TemplateErrorException("Empty embedded expression");
					currentRenderFunction.AddFragment(new CodeExpressionFragment(v)); return true;
				case "c":
					if (v == "")
						throw ParserUtils.TemplateErrorException("Empty embedded code");
					currentRenderFunction.AddFragment(new CodeFragment(v, 0)); return true;
				default:  return false;
			}
		}
		internal static void AddAttributeFragments(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction fragments, GenericElementProcessorContext context) {
			bool hasStyle = false;
			Utils.DoForEachAttribute(node, delegate(XmlAttribute attr) {
				AddSingleAttributeFragments(docProcessor, attr.Name, attr.Value, isRoot, template, fragments, context);
				if (attr.Name == "style")
					hasStyle = true;
			});

			if (isRoot) {
				fragments.AddFragment(new LiteralFragment(" id=\""));
				fragments.AddFragment(new IdFragment());
				fragments.AddFragment(new LiteralFragment("\""));
				if (!hasStyle) {
					fragments.AddFragment(new LiteralFragment(" style=\""));
					fragments.AddFragment(new PositionFragment());
					fragments.AddFragment(new LiteralFragment("\""));
				}
			}
		}
		public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction) {
			if (node.NodeType != XmlNodeType.ProcessingInstruction || node.Name != "using")
				return false;

			if (!isRoot)
				throw ParserUtils.TemplateErrorException(string.Format("The using directive can only appear outside of the template.", node.Name));
				
			string[] sideArr      = Utils.RegexExec(node.Value, "side=\"([^\"]*)\"", "");
			string[] namespaceArr = Utils.RegexExec(node.Value, "namespace=\"([^\"]*)\"", "");
	
			if (namespaceArr == null)
				throw ParserUtils.TemplateErrorException("Using directive must have the namespace specified.");

			string nmspace = namespaceArr[1].Trim(), side = (sideArr != null ? sideArr[1].Trim() : "both");
			if (!ParserUtils.IsValidQualifiedName(nmspace))
				throw ParserUtils.TemplateErrorException(string.Format("The identifier '{0}' is not a valid namespace name.", nmspace));

			bool serverSide, clientSide;
			switch (side) {
				case "client":
					serverSide = false;
					clientSide = true;
					break;
				case "server":
					serverSide = true;
					clientSide = false;
					break;
				case "both":
					serverSide = true;
					clientSide = true;
					break;
				default:
					throw ParserUtils.TemplateErrorException("The side attribute of the using directive must be 'client', 'server', or 'both'.");
			}
			
			if (serverSide)
				template.AddServerUsingDirective(nmspace);
			if (clientSide)
				template.AddClientUsingDirective(nmspace);

			return true;
		}
		internal static void AddSingleAttributeFragments(IDocumentProcessor docProcessor, string attrName, string attrValue, bool isRoot, ITemplate template, IRenderFunction fragments, GenericElementProcessorContext context) {
			string actualName;
			if (attrName == "actualName") {
				// This will translate into "name", but not with our ID prefixed. We need this because for top-level templates we want the names undisturbed to allow for a nice form submission.
				// However, for nested forms which we won't submit using the normal techniques, we need to prefix it in order to make radio buttons work reliably.
				actualName = "name";
			}
			else
				actualName = attrName;
			
			fragments.AddFragment(new LiteralFragment(" " + actualName + "=\""));
			if (attrName == "id") {
				if (isRoot)
					throw ParserUtils.TemplateErrorException("Can't specify an ID for the top level element.");
				if (template.HasMember(attrValue))
					throw ParserUtils.TemplateErrorException("Duplicate member " + attrValue);
				context.Id = attrValue;

				fragments.AddFragment(new IdFragment());
				fragments.AddFragment(new LiteralFragment("_" + attrValue));
			}
			else if (attrName.ToLowerCase() == "for" || attrName.ToLowerCase() == "name") {
				fragments.AddFragment(new IdFragment());
				fragments.AddFragment(new LiteralFragment("_" + attrValue));
			}
			else {
				IFragment f = docProcessor.ParseUntypedMarkup(attrValue);
				fragments.AddFragment(f);
				if (attrName.ToLowerCase() == "type") {
					if (f is LiteralFragment)
						context.Type = ((LiteralFragment)f).Text;
				}
				else if (isRoot && attrName.ToLowerCase() == "style") {
					if (!(f is LiteralFragment) || !((LiteralFragment)f).Text.Trim().EndsWith(";"))
						fragments.AddFragment(new LiteralFragment(";"));
					fragments.AddFragment(new PositionFragment());
				}
			}

			fragments.AddFragment(new LiteralFragment("\""));
		}
		public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction) {
			if (node.NodeType != XmlNodeType.ProcessingInstruction || node.Name != "field")
				return false;
			if (!isRoot)
				throw ParserUtils.TemplateErrorException(string.Format("The {0} directive can only appear outside of the template.", node.Name));

			string[] typeArr       = Utils.RegexExec(node.Value, "type=\"([^\"]*)\"", "");
			string[] serverTypeArr = Utils.RegexExec(node.Value, "serverType=\"([^\"]*)\"", "");
			string[] clientTypeArr = Utils.RegexExec(node.Value, "clientType=\"([^\"]*)\"", "");
			string[] nameArr       = Utils.RegexExec(node.Value, "name=\"([^\"]*)\"", "");

			string serverType, clientType;
			if (typeArr != null) {
				if (string.IsNullOrEmpty(typeArr[1].Trim()))
					throw ParserUtils.TemplateErrorException("No type was specified for the field");
				if (serverTypeArr != null || clientTypeArr != null)
					throw ParserUtils.TemplateErrorException("field elements cannot have both server/client type and type specified.");
				serverType = clientType = typeArr[1].Trim();
			}
			else if (serverTypeArr != null && clientTypeArr != null) {
				if (string.IsNullOrEmpty(serverTypeArr[1].Trim()))
					throw ParserUtils.TemplateErrorException("No server type was specified for the field");
				if (string.IsNullOrEmpty(clientTypeArr[1].Trim()))
					throw ParserUtils.TemplateErrorException("No client type was specified for the field");
				serverType = serverTypeArr[1].Trim();
				clientType = clientTypeArr[1].Trim();
			}
			else
				throw ParserUtils.TemplateErrorException("field elements must have the type specified (either 'type' or 'serverType' and 'clientType').");

			string name = nameArr != null ? nameArr[1].Trim() : null;
			if (string.IsNullOrEmpty(name))
				throw ParserUtils.TemplateErrorException("field elements must have a name specified.");

			if (template.HasMember(name))
				throw ParserUtils.TemplateErrorException("Duplicate member " + name);

			template.AddMember(new FieldMember(name, serverType, clientType));

			return true;
		}
		public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction) {
			switch (node.NodeType) {
				case XmlNodeType.CDATA:
					currentRenderFunction.AddFragment(new LiteralFragment(node.Value, true));
					return true;

				case XmlNodeType.Text:
				#if !CLIENT
					case XmlNodeType.Whitespace:
					case XmlNodeType.SignificantWhitespace:
				#endif
					currentRenderFunction.AddFragment(new LiteralFragment(NormalizeSpaces(node.Value)));
					return true;

				case XmlNodeType.Comment:
					return true;

				default:
					return false;
			}
		}
        public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction)
        {
            if (node.NodeType != XmlNodeType.Element)
            {
                return(false);
            }

            GenericElementProcessorContext context = new GenericElementProcessorContext();

            currentRenderFunction.AddFragment(new LiteralFragment("<" + node.Name));
            AddAttributeFragments(docProcessor, node, isRoot, template, currentRenderFunction, context);

            if (context.Id != null)
            {
                string tagName = node.Name;
                if (tagName.ToLowerCase() == "input" && context.Type != null)
                {
                    tagName += "/" + context.Type;
                }
                template.AddMember(new NamedElementMember(tagName, context.Id));
            }

            if (noContentTags.Contains(node.Name))
            {
                if (Utils.GetNumChildNodes(node) > 0)
                {
                    throw ParserUtils.TemplateErrorException("The tag " + node.Name + " can not have children.");
                }
                currentRenderFunction.AddFragment(new LiteralFragment("/>"));
            }
            else
            {
                currentRenderFunction.AddFragment(new LiteralFragment(">"));
                Utils.DoForEachChild(node, delegate(XmlNode child) {
                    docProcessor.ProcessRecursive(child, template, currentRenderFunction);
                });
                currentRenderFunction.AddFragment(new LiteralFragment("</" + node.Name + ">"));
            }

            return(true);
        }
        public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction)
        {
            if (node.NodeType != XmlNodeType.ProcessingInstruction || node.Name != "using")
            {
                return(false);
            }

            if (!isRoot)
            {
                throw ParserUtils.TemplateErrorException(string.Format("The using directive can only appear outside of the template.", node.Name));
            }

            string[] sideArr      = Utils.RegexExec(node.Value, "side=\"([^\"]*)\"", "");
            string[] namespaceArr = Utils.RegexExec(node.Value, "namespace=\"([^\"]*)\"", "");

            if (namespaceArr == null)
            {
                throw ParserUtils.TemplateErrorException("Using directive must have the namespace specified.");
            }

            string nmspace = namespaceArr[1].Trim(), side = (sideArr != null ? sideArr[1].Trim() : "both");

            if (!ParserUtils.IsValidQualifiedName(nmspace))
            {
                throw ParserUtils.TemplateErrorException(string.Format("The identifier '{0}' is not a valid namespace name.", nmspace));
            }

            bool serverSide, clientSide;

            switch (side)
            {
            case "client":
                serverSide = false;
                clientSide = true;
                break;

            case "server":
                serverSide = true;
                clientSide = false;
                break;

            case "both":
                serverSide = true;
                clientSide = true;
                break;

            default:
                throw ParserUtils.TemplateErrorException("The side attribute of the using directive must be 'client', 'server', or 'both'.");
            }

            if (serverSide)
            {
                template.AddServerUsingDirective(nmspace);
            }
            if (clientSide)
            {
                template.AddClientUsingDirective(nmspace);
            }

            return(true);
        }
Пример #20
0
        public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction)
        {
            if (node.NodeType != XmlNodeType.Element || node.Name != "copyright")
            {
                return(false);
            }

            if (node.ChildNodes.Count != 1 || node.ChildNodes[0].NodeType != XmlNodeType.Text)
            {
                throw new TemplateErrorException("The copyright node must have a single text child.");
            }

            CopyrightMember m = new CopyrightMember();

            if (template.HasMember(m.Name))
            {
                throw new TemplateErrorException("Duplicate definition of the member " + m.Name);
            }
            template.AddMember(m);

            currentRenderFunction.AddFragment(new CopyrightFragment(node.ChildNodes[0].Value));

            return(true);
        }
        public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction)
        {
            if (node.NodeType != XmlNodeType.ProcessingInstruction || (node.Name != "inherits" && node.Name != "implements"))
            {
                return(false);
            }

            if (!isRoot)
            {
                throw ParserUtils.TemplateErrorException(string.Format("The {0} directive can only appear outside of the template.", node.Name));
            }

            string[] sideArr = Utils.RegexExec(node.Value, "side=\"([^\"]*)\"", "");
            string[] typeArr = Utils.RegexExec(node.Value, "type=\"([^\"]*)\"", "");

            if (typeArr == null)
            {
                throw ParserUtils.TemplateErrorException(node.Name + " elements must have the type specified.");
            }
            if (sideArr == null)
            {
                throw ParserUtils.TemplateErrorException(node.Name + " elements must have the side specified.");
            }

            string side = sideArr[1].Trim(), type = typeArr[1].Trim();

            bool serverSide, clientSide;

            switch (side)
            {
            case "client":
                serverSide = false;
                clientSide = true;
                break;

            case "server":
                serverSide = true;
                clientSide = false;
                break;

            case "both":
                serverSide = true;
                clientSide = true;
                break;

            default:
                throw ParserUtils.TemplateErrorException("The side attribute of the " + node.Name + " element must be 'client', 'server', or 'both'.");
            }

            if (node.Name == "implements")
            {
                if (serverSide)
                {
                    if (template.ImplementsServerInterface(type))
                    {
                        throw ParserUtils.TemplateErrorException("The interface " + type + " is implemented more than once on the server side.");
                    }
                    template.AddServerInterface(type);
                }
                if (clientSide)
                {
                    if (template.ImplementsClientInterface(type))
                    {
                        throw ParserUtils.TemplateErrorException("The interface " + type + " is implemented more than once on the client side.");
                    }
                    template.AddClientInterface(type);
                }
            }
            else
            {
                if (serverSide)
                {
                    if (template.ServerInherits != null)
                    {
                        throw ParserUtils.TemplateErrorException("Cannot inherit from more than one class on the server side.");
                    }
                    template.ServerInherits = type;
                }
                if (clientSide)
                {
                    if (template.ClientInherits != null)
                    {
                        throw ParserUtils.TemplateErrorException("Cannot inherit from more than one class on the client side.");
                    }
                    template.ClientInherits = type;
                }
            }

            return(true);
        }
Пример #22
0
        public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction)
        {
            if (node.NodeType != XmlNodeType.ProcessingInstruction)
            {
                return(false);
            }

            string v = node.Value.Trim();

            switch (node.Name)
            {
            case "x":
                if (v == "")
                {
                    throw ParserUtils.TemplateErrorException("Empty embedded expression");
                }
                currentRenderFunction.AddFragment(new CodeExpressionFragment(v)); return(true);

            case "c":
                if (v == "")
                {
                    throw ParserUtils.TemplateErrorException("Empty embedded code");
                }
                currentRenderFunction.AddFragment(new CodeFragment(v, 0)); return(true);

            default:  return(false);
            }
        }
Пример #23
0
        public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction)
        {
            string name = node.Name;

            if (node.NodeType == XmlNodeType.Element && name == "def-fragment")
            {
                if (isRoot)
                {
                    throw ParserUtils.TemplateErrorException("Fragment definitions must be inside the template.");
                }
                ProcessDefFragment(docProcessor, node, template);
                return(true);
            }
            else if (node.NodeType == XmlNodeType.Element && name == "call-fragment")
            {
                if (isRoot)
                {
                    throw ParserUtils.TemplateErrorException("Fragment instantiations must be inside the template.");
                }
                currentRenderFunction.AddFragment(ProcessCallFragment(docProcessor, node));
                return(true);
            }
            else
            {
                return(false);
            }
        }
Пример #24
0
        public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction)
        {
            if (node.NodeType != XmlNodeType.ProcessingInstruction)
            {
                return(false);
            }

            switch (node.Name)
            {
            case "enableClientCreate":
                if (!isRoot)
                {
                    throw ParserUtils.TemplateErrorException("The enableClientCreate directive can only appear outside of the template.");
                }
                template.EnableClientCreate = true;
                return(true);

            default:
                return(false);
            }
        }
		public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction) {
			if (node.NodeType != XmlNodeType.ProcessingInstruction || (node.Name != "inherits" && node.Name != "implements"))
				return false;

			if (!isRoot)
				throw ParserUtils.TemplateErrorException(string.Format("The {0} directive can only appear outside of the template.", node.Name));
				
			string[] sideArr = Utils.RegexExec(node.Value, "side=\"([^\"]*)\"", "");
			string[] typeArr = Utils.RegexExec(node.Value, "type=\"([^\"]*)\"", "");
	
			if (typeArr == null)
				throw ParserUtils.TemplateErrorException(node.Name + " elements must have the type specified.");
			if (sideArr == null)
				throw ParserUtils.TemplateErrorException(node.Name + " elements must have the side specified.");

			string side = sideArr[1].Trim(), type = typeArr[1].Trim();

			bool serverSide, clientSide;
			switch (side) {
				case "client":
					serverSide = false;
					clientSide = true;
					break;
				case "server":
					serverSide = true;
					clientSide = false;
					break;
				case "both":
					serverSide = true;
					clientSide = true;
					break;
				default:
					throw ParserUtils.TemplateErrorException("The side attribute of the " + node.Name + " element must be 'client', 'server', or 'both'.");
			}

			if (node.Name == "implements") {
				if (serverSide) {
					if (template.ImplementsServerInterface(type))
						throw ParserUtils.TemplateErrorException("The interface " + type + " is implemented more than once on the server side.");
					template.AddServerInterface(type);
				}
				if (clientSide) {
					if (template.ImplementsClientInterface(type))
						throw ParserUtils.TemplateErrorException("The interface " + type + " is implemented more than once on the client side.");
					template.AddClientInterface(type);
				}
			}
			else {
				if (serverSide) {
					if (template.ServerInherits != null)
						throw ParserUtils.TemplateErrorException("Cannot inherit from more than one class on the server side.");
					template.ServerInherits = type;
				}
				if (clientSide) {
					if (template.ClientInherits != null)
						throw ParserUtils.TemplateErrorException("Cannot inherit from more than one class on the client side.");
					template.ClientInherits = type;
				}
			}

			return true;
		}
Пример #26
0
        public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction)
        {
            if (node.NodeType != XmlNodeType.ProcessingInstruction || node.Name != "view")
            {
                return(false);
            }
            if (!isRoot)
            {
                throw ParserUtils.TemplateErrorException(string.Format("The view directive can only appear outside of the template.", node.Name));
            }

            string[] serverTypeArr = Utils.RegexExec(node.Value, "modelType=\"([^\"]*)\"", "");
            string[] clientTypeArr = Utils.RegexExec(node.Value, "clientModelType=\"([^\"]*)\"", "");
            if (serverTypeArr == null && clientTypeArr != null)
            {
                throw ParserUtils.TemplateErrorException("You cannot specify a client type for the model if you don't specify a server type");
            }

            if (template.HasMember("Model") || template.HasMember("model") || template.HasMember("Saltarelle.Mvc.IView.Model"))
            {
                throw ParserUtils.TemplateErrorException("The template already defines at least one of the members essential to use the view directive. Have you specified <?view?> more than once?");
            }

            string serverType = (serverTypeArr != null ? serverTypeArr[1] : "object"), clientType = (clientTypeArr != null ? clientTypeArr[1] : null);
            string viewInterface = "Saltarelle.Mvc.IView<" + serverType + ">";

            if (template.ImplementsServerInterface(viewInterface))
            {
                throw ParserUtils.TemplateErrorException("The template already implements the interface " + viewInterface + ".");
            }

            template.AddServerInterface(viewInterface);
            template.AddMember(new FieldMember("model", serverType, clientType));
            template.AddMember(new PropertyMember("Model", serverType, null, AccessModifier._Public, "model", serverType, null, true, true, "ModelChanged", false));
            template.AddMember(new PropertyMember("Saltarelle.Mvc.IView.Model", "object", null, AccessModifier._None, "model", serverType, null, true, true, "ModelChanged", false));

            return(true);
        }
Пример #27
0
        public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction)
        {
            if (node.NodeType != XmlNodeType.Element || node.Name != "control")
            {
                return(false);
            }

            if (isRoot)
            {
                throw ParserUtils.TemplateErrorException("The root element can not be a control.");
            }

            string id   = null;
            string type = null;
            bool   customInstantiate = false;
            Dictionary <string, TypedMarkupData> additionalProperties = new Dictionary <string, TypedMarkupData>();

            Utils.DoForEachAttribute(node, delegate(XmlAttribute attr) {
                if (attr.Name == "id")
                {
                    if (!ParserUtils.IsValidUnqualifiedName(attr.Value))
                    {
                        throw ParserUtils.TemplateErrorException("The id '" + attr.Value + "' is not a valid identifier.");
                    }
                    id = attr.Value;
                }
                else if (attr.Name == "type")
                {
                    if (string.IsNullOrEmpty(attr.Value))
                    {
                        throw ParserUtils.TemplateErrorException("The control type '" + attr.Value + "' is invalid.");
                    }
                    type = attr.Value;
                }
                else if (attr.Name == "customInstantiate")
                {
                    string v          = attr.Value.ToLowerCase();
                    customInstantiate = Utils.ParseBool(v);
                }
                else
                {
                    additionalProperties[attr.Name] = docProcessor.ParseTypedMarkup(attr.Value);
                }
            });

            if (customInstantiate && additionalProperties.Count > 0)
            {
                throw ParserUtils.TemplateErrorException("There can not be any property assignments when customInstantiate is true.");
            }

            if (type == null)
            {
                throw ParserUtils.TemplateErrorException("The control '" + id + "' does not have a type specified.");
            }
            if (id == null)
            {
                id = template.GetUniqueId();
            }
            if (template.HasMember(id))
            {
                throw ParserUtils.TemplateErrorException("Duplicate definition of member " + id);
            }

            var dependencies      = new List <IMember>();
            int numInnerFragments = 0;

            if (Utils.GetNumChildNodes(node) > 0)
            {
                Utils.DoForEachChild(node, delegate(XmlNode n) {
                    if (n.OuterXml.Trim() != "")
                    {
                        numInnerFragments++;
                        string innerName = id + "_inner" + Utils.ToStringInvariantInt(numInnerFragments);
                        if (template.HasMember(innerName))
                        {
                            throw ParserUtils.TemplateErrorException("The internal name " + innerName + " is already in use.");
                        }
                        IRenderFunction innerFunction = new RenderFunctionMember(innerName, "");
                        template.AddMember((IMember)innerFunction);
                        docProcessor.ProcessRecursive(n, template, innerFunction);
                        dependencies.Add(innerFunction);
                    }
                });
            }

            if (!template.HasMember("Container"))
            {
                template.AddMember(new PropertyMember("Container", "IContainer", "IContainer", AccessModifier._Public, "_container", "IContainer", "IContainer", true, true, null, true));
            }

            IMember controlMember = new InstantiatedControlMember(id, type, customInstantiate, additionalProperties, dependencies);

            template.AddMember(controlMember);

            currentRenderFunction.AddFragment(new InstantiatedControlFragment(id, customInstantiate, numInnerFragments));
            currentRenderFunction.AddDependency(controlMember);

            return(true);
        }
Пример #28
0
        internal static void ProcessSwitchContent(IDocumentProcessor docProcessor, XmlNode switchNode, ITemplate template, IRenderFunction currentRenderFunction)
        {
            bool hasDefault = false;
            bool hasAny     = false;

            Utils.DoForEachChild(switchNode, delegate(XmlNode child) {
                                #if CLIENT
                if (((child.NodeType == XmlNodeType.Text || child.NodeType == XmlNodeType.CDATA) && child.Value.Trim() == "") || child.NodeType == XmlNodeType.Comment)
                {
                    return;
                }
                                #else
                if (child.NodeType == XmlNodeType.Whitespace || child.NodeType == XmlNodeType.SignificantWhitespace || child.NodeType == XmlNodeType.Comment)
                {
                    return;
                }
                                #endif

                if (child.NodeType == XmlNodeType.Element && child.Name == "case")
                {
                    XmlAttribute valueAttr = (XmlAttribute)child.Attributes.GetNamedItem("value");
                    if (valueAttr == null)
                    {
                        throw ParserUtils.TemplateErrorException("The <case> element must have the value attribute specified.");
                    }
                    currentRenderFunction.AddFragment(new CodeFragment("case " + valueAttr.Value + ": {", 1));
                }
                else if (child.NodeType == XmlNodeType.Element && child.Name == "default")
                {
                    if (hasDefault)
                    {
                        throw ParserUtils.TemplateErrorException("There can only be one <default> element inside <switch>");
                    }
                    hasDefault = true;
                    currentRenderFunction.AddFragment(new CodeFragment("default: {", 1));
                }
                else
                {
                    throw ParserUtils.TemplateErrorException("The <switch> element can only have <case> and <default> elements as children.");
                }

                hasAny = true;
                Utils.DoForEachChild(child, delegate(XmlNode grandchild) {
                    docProcessor.ProcessRecursive(grandchild, template, currentRenderFunction);
                });

                currentRenderFunction.AddFragment(new CodeFragment("break;", -1));
                currentRenderFunction.AddFragment(new CodeFragment("}", 0));
            });
            if (!hasAny)
            {
                throw ParserUtils.TemplateErrorException("The <switch> element must contain at least one <case> or <default>");
            }
        }
        internal static void AddSingleAttributeFragments(IDocumentProcessor docProcessor, string attrName, string attrValue, bool isRoot, ITemplate template, IRenderFunction fragments, GenericElementProcessorContext context)
        {
            string actualName;

            if (attrName == "actualName")
            {
                // This will translate into "name", but not with our ID prefixed. We need this because for top-level templates we want the names undisturbed to allow for a nice form submission.
                // However, for nested forms which we won't submit using the normal techniques, we need to prefix it in order to make radio buttons work reliably.
                actualName = "name";
            }
            else
            {
                actualName = attrName;
            }

            fragments.AddFragment(new LiteralFragment(" " + actualName + "=\""));
            if (attrName == "id")
            {
                if (isRoot)
                {
                    throw ParserUtils.TemplateErrorException("Can't specify an ID for the top level element.");
                }
                if (template.HasMember(attrValue))
                {
                    throw ParserUtils.TemplateErrorException("Duplicate member " + attrValue);
                }
                context.Id = attrValue;

                fragments.AddFragment(new IdFragment());
                fragments.AddFragment(new LiteralFragment("_" + attrValue));
            }
            else if (attrName.ToLowerCase() == "for" || attrName.ToLowerCase() == "name")
            {
                fragments.AddFragment(new IdFragment());
                fragments.AddFragment(new LiteralFragment("_" + attrValue));
            }
            else
            {
                IFragment f = docProcessor.ParseUntypedMarkup(attrValue);
                fragments.AddFragment(f);
                if (attrName.ToLowerCase() == "type")
                {
                    if (f is LiteralFragment)
                    {
                        context.Type = ((LiteralFragment)f).Text;
                    }
                }
                else if (isRoot && attrName.ToLowerCase() == "style")
                {
                    if (!(f is LiteralFragment) || !((LiteralFragment)f).Text.Trim().EndsWith(";"))
                    {
                        fragments.AddFragment(new LiteralFragment(";"));
                    }
                    fragments.AddFragment(new PositionFragment());
                }
            }

            fragments.AddFragment(new LiteralFragment("\""));
        }
		public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction) {
			if (node.NodeType != XmlNodeType.Element || node.Name != "control")
				return false;
			
			if (isRoot)
				throw ParserUtils.TemplateErrorException("The root element can not be a control.");

			string id = null;
			string type = null;
			bool customInstantiate = false;
			Dictionary<string, TypedMarkupData> additionalProperties = new Dictionary<string, TypedMarkupData>();

			Utils.DoForEachAttribute(node, delegate(XmlAttribute attr) {
				if (attr.Name == "id") {
					if (!ParserUtils.IsValidUnqualifiedName(attr.Value))
						throw ParserUtils.TemplateErrorException("The id '" + attr.Value + "' is not a valid identifier.");
					id = attr.Value;
				}
				else if (attr.Name == "type") {
					if (string.IsNullOrEmpty(attr.Value))
						throw ParserUtils.TemplateErrorException("The control type '" + attr.Value + "' is invalid.");
					type = attr.Value;
				}
				else if (attr.Name == "customInstantiate") {
					string v = attr.Value.ToLowerCase();
					customInstantiate = Utils.ParseBool(v);
				}
				else {
					additionalProperties[attr.Name] = docProcessor.ParseTypedMarkup(attr.Value);
				}
			});
			
			if (customInstantiate && additionalProperties.Count > 0)
				throw ParserUtils.TemplateErrorException("There can not be any property assignments when customInstantiate is true.");

			if (type == null)
				throw ParserUtils.TemplateErrorException("The control '" + id + "' does not have a type specified.");
			if (id == null)
				id = template.GetUniqueId();
			if (template.HasMember(id))
				throw ParserUtils.TemplateErrorException("Duplicate definition of member " + id);

			var dependencies = new List<IMember>();
			int numInnerFragments = 0;
			if (Utils.GetNumChildNodes(node) > 0) {
				Utils.DoForEachChild(node, delegate(XmlNode n) {
					if (n.OuterXml.Trim() != "") {
						numInnerFragments++;
						string innerName = id + "_inner" + Utils.ToStringInvariantInt(numInnerFragments);
						if (template.HasMember(innerName))
							throw ParserUtils.TemplateErrorException("The internal name " + innerName + " is already in use.");
						IRenderFunction innerFunction = new RenderFunctionMember(innerName, "");
						template.AddMember((IMember)innerFunction);
						docProcessor.ProcessRecursive(n, template, innerFunction);
						dependencies.Add(innerFunction);
					}
				});
			}
			
			if (!template.HasMember("Container"))
				template.AddMember(new PropertyMember("Container", "IContainer", "IContainer", AccessModifier._Public, "_container", "IContainer", "IContainer", true, true, null, true));

			IMember controlMember = new InstantiatedControlMember(id, type, customInstantiate, additionalProperties, dependencies);
			template.AddMember(controlMember);

			currentRenderFunction.AddFragment(new InstantiatedControlFragment(id, customInstantiate, numInnerFragments));
			currentRenderFunction.AddDependency(controlMember);

			return true;
		}
        internal static void AddAttributeFragments(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction fragments, GenericElementProcessorContext context)
        {
            bool hasStyle = false;

            Utils.DoForEachAttribute(node, delegate(XmlAttribute attr) {
                AddSingleAttributeFragments(docProcessor, attr.Name, attr.Value, isRoot, template, fragments, context);
                if (attr.Name == "style")
                {
                    hasStyle = true;
                }
            });

            if (isRoot)
            {
                fragments.AddFragment(new LiteralFragment(" id=\""));
                fragments.AddFragment(new IdFragment());
                fragments.AddFragment(new LiteralFragment("\""));
                if (!hasStyle)
                {
                    fragments.AddFragment(new LiteralFragment(" style=\""));
                    fragments.AddFragment(new PositionFragment());
                    fragments.AddFragment(new LiteralFragment("\""));
                }
            }
        }
Пример #32
0
        public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction)
        {
            switch (node.NodeType)
            {
            case XmlNodeType.CDATA:
                currentRenderFunction.AddFragment(new LiteralFragment(node.Value, true));
                return(true);

            case XmlNodeType.Text:
                                #if !CLIENT
            case XmlNodeType.Whitespace:
            case XmlNodeType.SignificantWhitespace:
                                #endif
                currentRenderFunction.AddFragment(new LiteralFragment(NormalizeSpaces(node.Value)));
                return(true);

            case XmlNodeType.Comment:
                return(true);

            default:
                return(false);
            }
        }
Пример #33
0
        public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction)
        {
            if (node.NodeType != XmlNodeType.Element)
            {
                return(false);
            }

            if (node.Name == "case" || node.Name == "default")
            {
                throw ParserUtils.TemplateErrorException("<case> and <default> can only occur inside <switch>");
            }
            if (node.Name == "else-if" || node.Name == "else")
            {
                throw ParserUtils.TemplateErrorException("<else-if> and <else> can only occur inside <if>");
            }

            string statement = GetStatement(node);

            if (statement == null)
            {
                return(false);
            }

            if (isRoot)
            {
                throw ParserUtils.TemplateErrorException("Control flow nodes cannot be root elements.");
            }

            currentRenderFunction.AddFragment(new CodeFragment(statement + " {", 1));

            if (node.Name == "switch")
            {
                ProcessSwitchContent(docProcessor, node, template, currentRenderFunction);
            }
            else
            {
                bool hasElse = false;
                Utils.DoForEachChild(node, delegate(XmlNode child) {
                    if (node.Name == "if" && (child.NodeType == XmlNodeType.Element && (child.Name == "else-if" || child.Name == "else")))
                    {
                        if (hasElse)
                        {
                            throw ParserUtils.TemplateErrorException("There cannot be other <else-if> or <else> elements after <else>.");
                        }
                        if (Utils.GetNumChildNodes(child) > 0)
                        {
                            throw ParserUtils.TemplateErrorException("<" + child.Name + "> elements should not have children.");
                        }
                        string possibleTest;
                        if (child.Name == "else-if")
                        {
                            XmlAttribute testAttr = (XmlAttribute)child.Attributes.GetNamedItem("test");
                            if (testAttr == null)
                            {
                                throw ParserUtils.TemplateErrorException("The <else-if> elements must have the test attribute specified.");
                            }
                            possibleTest = "if (" + testAttr.Value + ") ";
                        }
                        else
                        {
                            hasElse      = true;
                            possibleTest = "";
                        }
                        currentRenderFunction.AddFragment(new CodeFragment(null, -1));
                        currentRenderFunction.AddFragment(new CodeFragment("}", 0));
                        currentRenderFunction.AddFragment(new CodeFragment("else " + possibleTest + "{", 1));
                    }
                    else
                    {
                        docProcessor.ProcessRecursive(child, template, currentRenderFunction);
                    }
                });
            }

            currentRenderFunction.AddFragment(new CodeFragment(null, -1));
            currentRenderFunction.AddFragment(new CodeFragment("}", 0));

            return(true);
        }
        public bool TryProcess(IDocumentProcessor docProcessor, XmlNode node, bool isRoot, ITemplate template, IRenderFunction currentRenderFunction)
        {
            if (node.NodeType != XmlNodeType.ProcessingInstruction || node.Name != "field")
            {
                return(false);
            }
            if (!isRoot)
            {
                throw ParserUtils.TemplateErrorException(string.Format("The {0} directive can only appear outside of the template.", node.Name));
            }

            string[] typeArr       = Utils.RegexExec(node.Value, "type=\"([^\"]*)\"", "");
            string[] serverTypeArr = Utils.RegexExec(node.Value, "serverType=\"([^\"]*)\"", "");
            string[] clientTypeArr = Utils.RegexExec(node.Value, "clientType=\"([^\"]*)\"", "");
            string[] nameArr       = Utils.RegexExec(node.Value, "name=\"([^\"]*)\"", "");

            string serverType, clientType;

            if (typeArr != null)
            {
                if (string.IsNullOrEmpty(typeArr[1].Trim()))
                {
                    throw ParserUtils.TemplateErrorException("No type was specified for the field");
                }
                if (serverTypeArr != null || clientTypeArr != null)
                {
                    throw ParserUtils.TemplateErrorException("field elements cannot have both server/client type and type specified.");
                }
                serverType = clientType = typeArr[1].Trim();
            }
            else if (serverTypeArr != null && clientTypeArr != null)
            {
                if (string.IsNullOrEmpty(serverTypeArr[1].Trim()))
                {
                    throw ParserUtils.TemplateErrorException("No server type was specified for the field");
                }
                if (string.IsNullOrEmpty(clientTypeArr[1].Trim()))
                {
                    throw ParserUtils.TemplateErrorException("No client type was specified for the field");
                }
                serverType = serverTypeArr[1].Trim();
                clientType = clientTypeArr[1].Trim();
            }
            else
            {
                throw ParserUtils.TemplateErrorException("field elements must have the type specified (either 'type' or 'serverType' and 'clientType').");
            }

            string name = nameArr != null ? nameArr[1].Trim() : null;

            if (string.IsNullOrEmpty(name))
            {
                throw ParserUtils.TemplateErrorException("field elements must have a name specified.");
            }

            if (template.HasMember(name))
            {
                throw ParserUtils.TemplateErrorException("Duplicate member " + name);
            }

            template.AddMember(new FieldMember(name, serverType, clientType));

            return(true);
        }