internal void AddDataBindingExpression(CodeBlockBuilder codeBlockBuilder) { object lastBuilder = base.GetLastBuilder(); if ((lastBuilder == null) || (lastBuilder is CodeBlockBuilder)) { base.AddSubBuilder(null); } base.AddSubBuilder(codeBlockBuilder); }
internal void AddDataBindingExpression(CodeBlockBuilder codeBlockBuilder) { Debug.Assert(!InDesigner, "!InDesigner"); // Make sure strings and databinding expressions alternate object lastBuilder = GetLastBuilder(); if (lastBuilder == null || lastBuilder is CodeBlockBuilder) { AddSubBuilder(null); } AddSubBuilder(codeBlockBuilder); }
/// <include file='doc\ControlBuilder.uex' path='docs/doc[@for="ControlBuilder.AppendSubBuilder"]/*' /> /// <devdoc> /// <para>[To be supplied.]</para> /// </devdoc> public virtual void AppendSubBuilder(ControlBuilder subBuilder) { // Tell the sub builder that it's about to be appended to its parent subBuilder.OnAppendToParentBuilder(this); if (FChildrenAsProperties) { // Don't allow code blocks when properties are expected (ASURT 97838) if (subBuilder is CodeBlockBuilder) { throw new HttpException( HttpRuntime.FormatResourceString(SR.Code_not_supported_on_not_controls)); } // If there is a default property, delegate to its builder if (_defaultPropBuilder != null) { _defaultPropBuilder.AppendSubBuilder(subBuilder); return; } // The tagname is the property name string propName = subBuilder.TagName; if (subBuilder is TemplateBuilder) // The subBuilder is for building a template { TemplateBuilder tplBuilder = (TemplateBuilder)subBuilder; if (_templateSetter == null) { _templateSetter = new PropertySetter(_ctrlType, InDesigner || NonCompiledPage); } // Add TemplateBuilder to the template setter. _templateSetter.AddTemplateProperty(propName, tplBuilder); return; } if (subBuilder is CollectionBuilder) // The subBuilder is for building a collection // If there are no items in the collection, we're done { if (subBuilder.SubBuilders == null || subBuilder.SubBuilders.Count == 0) { return; } IEnumerator subBuilders = subBuilder.SubBuilders.GetEnumerator(); while (subBuilders.MoveNext()) { ControlBuilder builder = (ControlBuilder)subBuilders.Current; subBuilder.ComplexAttribSetter.AddCollectionItem(builder); } subBuilder.SubBuilders.Clear(); ComplexAttribSetter.AddComplexProperty(propName, subBuilder); return; } ComplexAttribSetter.AddComplexProperty(propName, subBuilder); return; } CodeBlockBuilder codeBlockBuilder = subBuilder as CodeBlockBuilder; if (codeBlockBuilder != null) { // Don't allow code blocks inside non-control tags (ASURT 76719) if (ControlType != null && !typeof(Control).IsAssignableFrom(ControlType)) { throw new HttpException( HttpRuntime.FormatResourceString(SR.Code_not_supported_on_not_controls)); } // Is it a databinding expression? <%# ... %> if (codeBlockBuilder.BlockType == CodeBlockType.DataBinding) { if (InDesigner) { // In the designer, don't use the fancy multipart DataBoundLiteralControl, // which breaks a number of things (ASURT 82925,86738). Instead, use the // simpler DesignerDataBoundLiteralControl, and do standard databinding // on its Text property. IDictionary attribs = new SortedList(); attribs.Add("Text", "<%#" + codeBlockBuilder.Content + "%>"); subBuilder = CreateBuilderFromType( Parser, this, typeof(DesignerDataBoundLiteralControl), null, null, attribs, codeBlockBuilder.Line, codeBlockBuilder.SourceFileName); } else { // Get the last builder, and check if it's a DataBoundLiteralControlBuilder object lastBuilder = GetLastBuilder(); DataBoundLiteralControlBuilder dataBoundBuilder = lastBuilder as DataBoundLiteralControlBuilder; // If not, then we need to create one. Otherwise, just append to the // existing one bool fNewDataBoundLiteralControl = false; if (dataBoundBuilder == null) { dataBoundBuilder = new DataBoundLiteralControlBuilder(); dataBoundBuilder.Init(_parser, this, typeof(DataBoundLiteralControl), null, null, null); fNewDataBoundLiteralControl = true; // If the previous builder was a string, add it as the first // entry in the composite control. string s = lastBuilder as string; if (s != null) { _subBuilders.RemoveAt(_subBuilders.Count - 1); dataBoundBuilder.AddLiteralString(s); } } dataBoundBuilder.AddDataBindingExpression(codeBlockBuilder); if (!fNewDataBoundLiteralControl) { return; } subBuilder = dataBoundBuilder; } } else { // Set a flag if there is at least one block of ASP code _fHasAspCode = true; } } if (FIsNonParserAccessor) { throw new HttpException( HttpRuntime.FormatResourceString(SR.Children_not_supported_on_not_controls)); } AddSubBuilder(subBuilder); }
/* * Handle <%= ... %>, <%# ... %> and <% ... %> blocks */ private void ProcessCodeBlock(Match match, CodeBlockType blockType, string text) { // Take care of the previous literal string ProcessLiteral(); // Get the piece of code Group codeGroup = match.Groups["code"]; string code = codeGroup.Value; bool encode = match.Groups["encode"].Success; // Replace "%\>" with "%>" (ASURT 7175) code = code.Replace(@"%\>", "%>"); int lineNumber = _lineNumber; int column = -1; if (blockType != CodeBlockType.Code) { // It a <%= %>, <%# %> or <%: %> block. We need to do special handling of newline chars // If there are newlines in the beginning of the code string we need to get rid of them, // and adjust the line pragma accordingly. This is needed because some compilers (like VB) // don't support multiline expression (ASURT 13662) int newlineIndex = -1; for (int i = 0; i < code.Length && Char.IsWhiteSpace(code[i]); i++) { if (code[i] == '\r' || (code[i] == '\n' && (i == 0 || code[i - 1] != '\r'))) { lineNumber++; newlineIndex = i; } else if (code[i] == '\n') { newlineIndex = i; } } if (newlineIndex >= 0) { // If we found some newlines in the beginning, get rid of them. Note // that we preserve the spaces, to get correct column information code = code.Substring(newlineIndex + 1); // The code starts at column 1 (since we keep the spaces) column = 1; } // Same deal for the end of the string: look for the first newline // after the last non-blank chararacter newlineIndex = -1; for (int i = code.Length - 1; i >= 0 && Char.IsWhiteSpace(code[i]); i--) { if (code[i] == '\r' || code[i] == '\n') newlineIndex = i; } // And if we found one, remove it and everything after if (newlineIndex >= 0) code = code.Substring(0, newlineIndex); // Disallow empty expressions (ASURT 40124) // Do not treat as error in CBM. This is necessary so we still generate // code blocks for empty expressions. (VSWhidbey 406212) if (!IgnoreParseErrors && Util.IsWhiteSpaceString(code)) { ProcessError(SR.GetString(SR.Empty_expression)); return; } } if (column < 0) { // It a <% %> block. Newline chars are not a problem. // Look for the last newline before the code string int newlineIndex = text.LastIndexOfAny(s_newlineChars, codeGroup.Index-1); // Use it to calculate the column where the code starts, // which improves the debugging experience (VSWhidbey 87172) column = codeGroup.Index-newlineIndex; Debug.Assert(column > 0); } ControlBuilder builder = ((BuilderStackEntry) BuilderStack.Peek())._builder; ControlBuilder subBuilder; // First, give the PageParserFilter a chance to handle the code block if (!PageParserFilterProcessedCodeBlock(CodeConstructTypeFromCodeBlockType(blockType), code, lineNumber)) { // Make sure it's legal to have code in this page EnsureCodeAllowed(); // Add the code block to the top builder subBuilder = new CodeBlockBuilder(blockType, code, lineNumber, column, CurrentVirtualPath, encode); AppendSubBuilder(builder, subBuilder); // Optionally record code block position data ParseRecorders.RecordCodeBlock(subBuilder, match); } // Always ignore the spaces after a <% ... %> block if (blockType == CodeBlockType.Code) flags[ignoreNextSpaceString] = true; }