public static void ValidateRepeaterTemplate1(ResolvedTreeRoot root) { ValidateRepeaterControl(root); DotHtmlCommonValidator.ValidatePropertyBinding(root, CreateStep5TitleProperty()); DotHtmlCommonValidator.CheckControlTypeCountInRepeater <LinkButton>(root, 1); }
public override void VisitView(ResolvedTreeRoot view) { lastMetadata = view.Metadata; var wrapperClassName = CreateControlClass(className, view.Metadata.Type); emitter.UsedAssemblies.Add(view.Metadata.Type.Assembly); emitter.BuilderDataContextType = view.DataContextTypeStack?.DataContextType; emitter.ResultControlType = wrapperClassName; // build the statements emitter.PushNewMethod(DefaultViewCompilerCodeEmitter.BuildControlFunctionName); var pageName = emitter.EmitCreateObject(wrapperClassName); emitter.EmitSetAttachedProperty(pageName, Internal.UniqueIDProperty, pageName); emitter.EmitSetAttachedProperty(pageName, Internal.MarkupFileNameProperty, view.Metadata.VirtualPath); if (typeof(DotvvmView).IsAssignableFrom(view.Metadata.Type)) { emitter.EmitSetProperty(pageName, nameof(DotvvmView.ViewModelType), emitter.EmitValue(view.DataContextTypeStack.DataContextType)); } if (view.Metadata.Type.IsAssignableFrom(typeof(DotvvmView))) { foreach (var directive in view.Directives) { emitter.EmitAddDirective(pageName, directive.Key, directive.Value); } } controlName = pageName; base.VisitView(view); emitter.EmitReturnClause(pageName); emitter.PopMethod(); }
public static void ValidateRepeaterControl(ResolvedTreeRoot resolvedTreeRoot) { ValidateAddTaskControlBindings(resolvedTreeRoot); DotHtmlCommonValidator.CheckControlTypeCount <Repeater>(resolvedTreeRoot, 1); var repeater = resolvedTreeRoot.GetDescendantControls <Repeater>().Single(); DotHtmlCommonValidator.ValidatePropertyBinding(resolvedTreeRoot, CreateStep6Property()); DotHtmlCommonValidator.CheckCountOfHtmlTag(resolvedTreeRoot, "div", 1); IAbstractPropertySetter setter; if (!repeater.TryGetProperty(Repeater.ItemTemplateProperty, out setter) || !(setter is ResolvedPropertyTemplate)) { throw new CodeValidationException(Lesson2Texts.RepeaterTemplateMissingDivError); } var template = (ResolvedPropertyTemplate)setter; var div = template.GetDescendantControls <HtmlGenericControl>().ToList(); if (div.Count(d => d.DothtmlNode.As <DothtmlElementNode>()?.TagName == "div") != 1) { throw new CodeValidationException(Lesson2Texts.RepeaterTemplateMissingDivError); } }
public void Validate(ResolvedTreeRoot resolvedTreeRoot) { Lesson3CommonValidator.CheckStep11Controls(resolvedTreeRoot); DotHtmlCommonValidator.CheckCountOfHtmlTag(resolvedTreeRoot, "div", 1); DotHtmlCommonValidator.ValidatePropertiesBindings(resolvedTreeRoot, Lesson3CommonValidator.CreateStep14Properties()); }
public ResolvedTreeRoot ResolveTree(DothtmlRootNode root, string fileName) { var wrapperType = ResolveWrapperType(root, fileName.EndsWith(".dotcontrol", StringComparison.Ordinal) ? typeof(DotvvmMarkupControl) : typeof(DotvvmView)); // We need to call BuildControlMetadata instead of ResolveControl. The control builder for the control doesn't have to be compiled yet so the // metadata would be incomplete and ResolveControl caches them internally. BuildControlMetadata just builds the metadata and the control is // actually resolved when the control builder is ready and the metadata are complete. var viewMetadata = controlResolver.BuildControlMetadata(new ControlType(wrapperType, virtualPath: fileName)); var view = new ResolvedTreeRoot(viewMetadata, root, null); foreach (var directive in root.Directives) { if (!string.Equals(directive.Name, Constants.BaseTypeDirective, StringComparison.InvariantCultureIgnoreCase)) { view.Directives.Add(directive.Name, directive.Value); } } ResolveViewModel(fileName, view, wrapperType); foreach (var node in root.Content) { view.Content.Add(ProcessNode(node, viewMetadata, view.DataContextTypeStack)); } return(view); }
public void Validate(ResolvedTreeRoot resolvedTreeRoot) { Lesson2CommonValidator.ValidateRepeaterTemplate3(resolvedTreeRoot); var template = resolvedTreeRoot.GetDescendantControls <Repeater>().Single() .Properties[Repeater.ItemTemplateProperty] .CastTo <ResolvedPropertyTemplate>(); List <ResolvedControl> resolvedControls = template .GetDescendantControls <HtmlGenericControl>() .ToList(); var div = resolvedControls.First(d => d.DothtmlNode.As <DothtmlElementNode>()?.TagName == "div"); List <ResolvedPropertyBinding> divClassProperties = div.Properties .Where(p => p.Value.Property.Name == "Attributes:class") .Select(p => p.Value) .OfType <ResolvedPropertyBinding>() .ToList(); if (divClassProperties.Count != 1) { throw new CodeValidationException(Lesson2Texts.InvalidClassBinding); } var classBinding = divClassProperties[0].Binding.Value.Replace(" ", "").Replace("\"", "'"); if ((classBinding != "IsCompleted?'task-completed':'task'") && (classBinding != "IsCompleted==true?'task-completed':'task'") && (classBinding != "!IsCompleted?'task':'task-completed'") && (classBinding != "IsCompleted==false?'task':'task-completed'")) { throw new CodeValidationException(Lesson2Texts.InvalidClassExpressionBinding); } }
public static void ValidateRepeaterTemplate3(ResolvedTreeRoot root) { ValidateRepeaterTemplate2(root); var linkButton = DotHtmlCommonValidator.GetControlInRepeater <LinkButton>(root); linkButton.ValidateCommandBindingExpression(ButtonBase.ClickProperty, "_parent.CompleteTask(_this)"); }
public void Validate(ResolvedTreeRoot resolvedTreeRoot) { var step9Properties = Lesson3CommonValidator.CreateStep9Properties(); var contriesProperty = step9Properties.Single(p => p.TargetControlBindName == ControlBindName.ComboBoxDataSource); contriesProperty.Name = $"_parent.{contriesProperty.Name}"; DotHtmlCommonValidator.ValidatePropertiesBindings(resolvedTreeRoot, step9Properties); }
public static void ValidateAddTaskControlBindings(ResolvedTreeRoot root) { ValidateAddTaskControls(root); DotHtmlCommonValidator.ValidatePropertyBinding(root, CreateStep3Property()); root.GetDescendantControls <Button>().Single() .ValidateCommandBindingExpression(ButtonBase.ClickProperty, "AddTask()"); }
public override void VisitView(ResolvedTreeRoot view) { lastMetadata = view.Metadata; var createsCustomDerivedType = view.Metadata.Type == typeof(DotvvmView); if (createsCustomDerivedType) { var resultControlType = className + "Control"; emitter.ResultControlTypeSyntax = SyntaxFactory.ParseTypeName(resultControlType); emitter.EmitControlClass(view.Metadata.Type, resultControlType); } else { emitter.ResultControlTypeSyntax = emitter.ParseTypeName(view.Metadata.Type); } emitter.UseType(view.Metadata.Type); emitter.BuilderDataContextType = view.DataContextTypeStack?.DataContextType; // build the statements emitter.PushNewMethod(nameof(IControlBuilder.BuildControl), typeof(DotvvmControl), emitter.EmitControlBuilderParameters()); var pageName = createsCustomDerivedType ? emitter.EmitCreateObject(emitter.ResultControlTypeSyntax) : this.EmitCreateControl(view.Metadata.Type, new object[0]); emitter.RegisterDotvvmProperties(pageName); emitter.EmitSetDotvvmProperty(pageName, Internal.UniqueIDProperty, pageName); emitter.EmitSetDotvvmProperty(pageName, Internal.MarkupFileNameProperty, view.Metadata.VirtualPath); emitter.EmitSetDotvvmProperty(pageName, Internal.DataContextTypeProperty, emitter.EmitValue(view.DataContextTypeStack)); if (typeof(DotvvmView).IsAssignableFrom(view.Metadata.Type)) { emitter.EmitSetProperty(pageName, nameof(DotvvmView.ViewModelType), emitter.EmitValue(view.DataContextTypeStack.DataContextType)); } if (typeof(DotvvmView).IsAssignableFrom(view.Metadata.Type) || typeof(DotvvmMarkupControl).IsAssignableFrom(view.Metadata.Type)) { foreach (var directive in view.Directives) { emitter.EmitAddDirective(pageName, directive.Key, directive.Value.First().Value); } } controlName = pageName; base.VisitView(view); emitter.CommitDotvvmProperties(pageName); emitter.EmitReturnClause(pageName); emitter.PopMethod(); }
public static void ValidateRepeaterTemplate2(ResolvedTreeRoot root) { ValidateRepeaterTemplate1(root); var linkButton = DotHtmlCommonValidator.GetControlInRepeater <LinkButton>(root); if (linkButton.GetValueBindingText(HtmlGenericControl.VisibleProperty) != "!IsCompleted") { throw new CodeValidationException(Lesson2Texts.InvalidVisibleBinding); } }
public void Validate(ResolvedTreeRoot resolvedTreeRoot) { Lesson4CommonValidator.ValidateStep5(resolvedTreeRoot); DotHtmlCommonValidator.CheckControlTypeCount <Validator>(resolvedTreeRoot, 1); DotHtmlCommonValidator.ValidatePropertyBinding(resolvedTreeRoot, Lesson4CommonValidator.CreateStep7ValidatorEmail()); var property = new Property("True", "fakeProp", ControlBindName.ValidatorShowErrorMessageText); DotHtmlCommonValidator.ValidatePropertyBinding(resolvedTreeRoot, property); }
public override void VisitView(ResolvedTreeRoot view) { var original = requiredResources; base.VisitView(view); if (original != requiredResources) { view.Content.AddRange( requiredResources.Except(original).Select(r => CreateRequiredResourceControl(r, view.DothtmlNode, view.Content.First().DataContextTypeStack))); requiredResources = original; } }
public void VisitAndAssert(ResolvedTreeRoot view) { if (this.Errors.Any()) { throw new Exception("The ControlUsageValidationVisitor has already collected some errors."); } VisitView(view); if (this.Errors.Any()) { var controlUsageError = this.Errors.First(); throw new DotvvmCompilationException(controlUsageError.ErrorMessage, controlUsageError.Nodes.SelectMany(n => n.Tokens)); } }
public static void ValidateAddTaskControls(ResolvedTreeRoot resolvedTreeRoot) { DotHtmlCommonValidator.CheckControlTypeCount <TextBox>(resolvedTreeRoot, 1); DotHtmlCommonValidator.CheckControlTypeCount <Button>(resolvedTreeRoot, 1); var buttonText = resolvedTreeRoot.GetDescendantControls <Button>() .Select(c => c.GetValue(ButtonBase.TextProperty)) .SingleOrDefault(); if (buttonText == null) { throw new CodeValidationException(Lesson2Texts.ButtonDoesNotHaveText); } }
public void Validate(ResolvedTreeRoot resolvedTreeRoot) { DotHtmlCommonValidator.CheckCountOfHtmlTag(resolvedTreeRoot, "div", 3); Lesson4CommonValidator.ValidateStep2ValidationProperties(resolvedTreeRoot); Lesson4CommonValidator.ValidateOnlyStep3Properties(resolvedTreeRoot); var property = new Property("has-error", "none", ControlBindName.DivValidatorInvalidCssClass); DotHtmlCommonValidator.ValidatePropertyBinding(resolvedTreeRoot, property); var invalidCssException = new CodeValidationException(Lesson4Texts.AllDivsMustHaveInvalidCssClass); DotHtmlCommonValidator.CheckCountOfHtmlTagWithPropertyDescriptor(resolvedTreeRoot, "div", 3, Validator.InvalidCssClassProperty, invalidCssException); }
public override void VisitView(ResolvedTreeRoot view) { if (view.DothtmlNode.HasNodeErrors) { throw new DotvvmCompilationException(string.Join("\r\n", view.DothtmlNode.NodeErrors), view.DothtmlNode.Tokens); } foreach (var directive in ((DothtmlRootNode)view.DothtmlNode).Directives) { if (directive.HasNodeErrors) { throw new DotvvmCompilationException(string.Join("\r\n", directive.NodeErrors), directive.Tokens); } } base.VisitView(view); }
public void Validate(ResolvedTreeRoot resolvedTreeRoot) { Lesson1CommonValidator.ValidateTextBoxBindings(resolvedTreeRoot); resolvedTreeRoot.GetDescendantControls <Button>().Single() .ValidateCommandBindingExpression(ButtonBase.ClickProperty, "Calculate()"); var buttonTextBinding = resolvedTreeRoot.GetDescendantControls <Button>() .Select(c => c.GetValue(ButtonBase.TextProperty)) .SingleOrDefault(); if (buttonTextBinding == null) { throw new CodeValidationException(Lesson1Texts.ButtonDoesNotHaveText); } }
private void ResolveViewModel(string fileName, ResolvedTreeRoot view, Type wrapperType) { if (!view.Directives.ContainsKey(Constants.ViewModelDirectiveName)) { throw new DotvvmCompilationException($"The @viewModel directive is missing in the page '{fileName}'!", view.DothtmlNode.Tokens.Take(1)); } var viewModelTypeName = view.Directives[Constants.ViewModelDirectiveName]; var viewModelType = ReflectionUtils.FindType(viewModelTypeName); if (viewModelType == null) { throw new DotvvmCompilationException($"The type '{viewModelTypeName}' required in the @viewModel directive in was not found!", (view.DothtmlNode as DothtmlRootNode)?.Directives?.FirstOrDefault(d => string.Equals(d.Name, Constants.ViewModelDirectiveName, StringComparison.InvariantCultureIgnoreCase))?.Tokens); } view.DataContextTypeStack = new DataContextStack(viewModelType) { RootControlType = wrapperType }; }
public void Validate(ResolvedTreeRoot resolvedTreeRoot) { DotHtmlCommonValidator.ValidatePropertiesBindings(resolvedTreeRoot, Lesson3CommonValidator.CreateStep6Properties()); Lesson3CommonValidator.CheckStep5Controls(resolvedTreeRoot); DotHtmlCommonValidator.CheckControlTypeCount <CheckBox>(resolvedTreeRoot, 3); var checkboxes = resolvedTreeRoot.GetDescendantControls <CheckBox>().ToList(); if (!checkboxes.Any(c => c.GetValue(CheckableControlBase.CheckedValueProperty) == "M")) { throw new CodeValidationException(string.Format(ValidationErrorMessages.PropertyValueError, "CheckedValue", "M")); } if (!checkboxes.Any(c => c.GetValue(CheckableControlBase.CheckedValueProperty) == "S")) { throw new CodeValidationException(string.Format(ValidationErrorMessages.PropertyValueError, "CheckedValue", "S")); } if (!checkboxes.Any(c => c.GetValue(CheckableControlBase.CheckedValueProperty) == "N")) { throw new CodeValidationException(string.Format(ValidationErrorMessages.PropertyValueError, "CheckedValue", "N")); } }
public static void ValidateStep5(ResolvedTreeRoot resolvedTreeRoot) { var divEnwrapException = new CodeValidationException(Lesson4Texts.WrapDivsInForm); DotHtmlCommonValidator.CheckCountOfHtmlTag(resolvedTreeRoot, "form", 1, divEnwrapException); var property = new Property("has-error", "fakeProp", ControlBindName.FormValidatorInvalidCssClass); DotHtmlCommonValidator.ValidatePropertyBinding(resolvedTreeRoot, property); var contentNode = resolvedTreeRoot.GetDescendantControls <HtmlGenericControl>(). FirstOrDefault(d => d.DothtmlNode.As <DothtmlElementNode>()?.TagName == "form"); DotHtmlCommonValidator.CheckCountOfHtmlTag(contentNode, "div", 3); var redundantInvalidCssException = new CodeValidationException(Lesson4Texts.ChildDivsDontNeedInvalidCssClassAnymore); ValidateStep2ValidationProperties(contentNode); DotHtmlCommonValidator.CheckCountOfHtmlTagWithPropertyDescriptor(contentNode, "div", 0, Validator.InvalidCssClassProperty, redundantInvalidCssException); property.TargetControlBindName = ControlBindName.DivValidatorInvalidCssClassRemove; DotHtmlCommonValidator.ValidatePropertyBinding(contentNode, property); }
public static void ValidateOnlyStep3Properties(ResolvedTreeRoot resolvedTreeRoot) { DotHtmlCommonValidator.CheckControlTypeCount <TextBox>(resolvedTreeRoot, 3); DotHtmlCommonValidator.ValidatePropertiesBindings(resolvedTreeRoot, CreateStep2ControlProperties()); }
public static void ValidateStep8(ResolvedTreeRoot resolvedTreeRoot) { ValidateStep5(resolvedTreeRoot); DotHtmlCommonValidator.CheckControlTypeCount <ValidationSummary>(resolvedTreeRoot, 1); }
public void Validate(ResolvedTreeRoot resolvedTreeRoot) { Lesson2CommonValidator.ValidateRepeaterTemplate3(resolvedTreeRoot); }
public void Validate(ResolvedTreeRoot resolvedTreeRoot) { Lesson1CommonValidator.ValidateBasicControls(resolvedTreeRoot); }
public static void CheckStep11Controls(ResolvedTreeRoot resolvedTreeRoot) { CheckStep5Controls(resolvedTreeRoot); DotHtmlCommonValidator.ValidatePropertiesBindings(resolvedTreeRoot, CreateStep11Properties()); DotHtmlCommonValidator.CheckControlTypeCount <ComboBox>(resolvedTreeRoot, 1); }
public static void CheckStep5Controls(ResolvedTreeRoot resolvedTreeRoot) { CheckStep3Controls(resolvedTreeRoot); DotHtmlCommonValidator.CheckControlTypeCount <RadioButton>(resolvedTreeRoot, 2); }
public static void CheckStep3Controls(ResolvedTreeRoot resolvedTreeRoot) { DotHtmlCommonValidator.CheckControlTypeCount <TextBox>(resolvedTreeRoot, 2); }
public override void VisitView(ResolvedTreeRoot view) { CurrentType = view.DataContextTypeStack; base.VisitView(view); }
public void Validate(ResolvedTreeRoot resolvedTreeRoot) { Lesson3CommonValidator.CheckStep5Controls(resolvedTreeRoot); DotHtmlCommonValidator.ValidatePropertiesBindings(resolvedTreeRoot, Lesson3CommonValidator.CreateStep4Properties()); }
public virtual void VisitView(ResolvedTreeRoot view) { DefaultVisit(view); }