void BuildExpressionAndScriptsLists() { XExpressions = new List <S.XNode> (); XScriptBlocks = new List <S.XElement> (); foreach (S.XNode node in AspNetDocument.XDocument.AllDescendentNodes) { if (node is AspNetRenderExpression || node is AspNetHtmlEncodedExpression || node is AspNetRenderBlock) { XExpressions.Add(node); continue; } S.XElement el = node as S.XElement; if (el == null) { continue; } if (el.IsServerScriptTag()) { XScriptBlocks.Add(el); } } }
//case insensitive, no prefix static S.XAttribute GetHtmlAtt(S.XElement el, string name) { return(el.Attributes .Where(a => a.IsNamed && !a.Name.HasPrefix && a.Name.Name.Equals(name, StringComparison.OrdinalIgnoreCase)) .FirstOrDefault()); }
protected virtual void AddAttributeValueCompletionData(CodeCompletionDataProvider cp, S.XElement element, S.XAttribute attribute) { }
ICompletionDataProvider HandleCodeCompletion( CodeCompletionContext completionContext, bool forced, ref int triggerWordLength) { tracker.UpdateEngine(); //FIXME: lines in completionContext are zero-indexed, but ILocation and buffer are 1-indexed. //This could easily cause bugs. int line = completionContext.TriggerLine + 1, col = completionContext.TriggerLineOffset; ITextBuffer buf = this.Buffer; // completionChar may be a space even if the current char isn't, when ctrl-space is fired t int currentPosition = buf.CursorPosition - 1; char currentChar = buf.GetCharAt(currentPosition); char previousChar = buf.GetCharAt(currentPosition - 1); //decide whether completion will be auto-activated, to avoid unnecessary //parsing, which hurts editor responsiveness if (!forced) { // if (tracker.Engine.CurrentState is S.XmlFreeState && !(currentChar == '<' || currentChar == '>')) { return(null); } if (tracker.Engine.CurrentState is S.XmlNameState && tracker.Engine.CurrentState.Parent is S.XmlAttributeState && previousChar != ' ') { return(null); } if (tracker.Engine.CurrentState is S.XmlAttributeValueState && !(previousChar == '\'' || previousChar == '"' || currentChar == '\'' || currentChar == '"')) { return(null); } } //tag completion if (currentChar == '<') { CodeCompletionDataProvider cp = new CodeCompletionDataProvider(null, GetAmbience()); if (tracker.Engine.CurrentState is S.XmlFreeState) { S.XElement el = tracker.Engine.Nodes.Peek() as S.XElement; AddTagCompletionData(cp, el); } return(cp); } //closing tag completion if (tracker.Engine.CurrentState is S.XmlFreeState && currentPosition - 1 > 0 && currentChar == '>') { //get name of current node in document that's being ended S.XElement el = tracker.Engine.Nodes.Peek() as S.XElement; if (el != null && el.Position.End >= currentPosition && !el.IsClosed && el.IsNamed) { CodeCompletionDataProvider cp = new CodeCompletionDataProvider(null, GetAmbience()); cp.AddCompletionData( new MonoDevelop.XmlEditor.Completion.XmlTagCompletionData( String.Concat("</", el.Name.FullName, ">"), 0, true) ); return(cp); } } //attributes names within tags if (tracker.Engine.CurrentState is S.XmlTagState && forced || (tracker.Engine.CurrentState is S.XmlNameState && tracker.Engine.CurrentState.Parent is S.XmlAttributeState && tracker.Engine.CurrentStateLength == 1) ) { int peekp = (tracker.Engine.CurrentState is S.XmlTagState) ? 0 : 1; S.XElement el = (S.XElement)tracker.Engine.Nodes.Peek(peekp); // HACK S.XElement pel = tracker.Engine.Nodes.Peek(peekp + 1) as S.XElement; if (el.Parent == null && pel != null) { pel.AddChildNode(el); } //attributes if (el != null && el.Name.IsValid && (forced || char.IsWhiteSpace(currentChar) || (char.IsWhiteSpace(previousChar) && char.IsLetter(currentChar)))) { CodeCompletionDataProvider cp = new CodeCompletionDataProvider(null, GetAmbience()); if (!forced) { triggerWordLength = 1; } AddAttributeCompletionData(cp, el); return(cp); } } //attribute values //determine whether to trigger completion within attribute values quotes if ((tracker.Engine.CurrentState is S.XmlDoubleQuotedAttributeValueState || tracker.Engine.CurrentState is S.XmlSingleQuotedAttributeValueState) //trigger on the opening quote && (tracker.Engine.CurrentStateLength == 0 //or trigger on first letter of value, if unforced || (!forced && tracker.Engine.CurrentStateLength == 1)) ) { S.XAttribute att = (S.XAttribute)tracker.Engine.Nodes.Peek(); if (att.IsNamed) { S.XElement el = (S.XElement)tracker.Engine.Nodes.Peek(1); // HACK S.XElement pel = tracker.Engine.Nodes.Peek(2) as S.XElement; if (el.Parent == null && pel != null) { pel.AddChildNode(el); } char next = ' '; if (currentPosition + 1 < buf.Length) { next = buf.GetCharAt(currentPosition + 1); } char compareChar = (tracker.Engine.CurrentStateLength == 0)? currentChar : previousChar; Console.WriteLine("ppa: " + att.Value); if ((compareChar == '"' || compareChar == '\'') && (next == compareChar || char.IsWhiteSpace(next)) ) { //if triggered by first letter of value, grab that letter if (tracker.Engine.CurrentStateLength == 1) { triggerWordLength = 1; } CodeCompletionDataProvider cp = new CodeCompletionDataProvider(null, GetAmbience()); AddAttributeValueCompletionData(cp, el, att); return(cp); } } } return(null); }
protected virtual void AddTagCompletionData(CodeCompletionDataProvider cp, S.XElement element) { }