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; }
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(); }
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; } }
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); }
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); }
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); } }
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 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; }
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); }
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 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("\"")); } } }
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); } 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); }