public bool HasSuggestedActions(ITextView textView, ITextBuffer textBuffer, int caretPosition, ElementNode element, AttributeNode attribute, HtmlPositionType positionType) { if (element.IsRoot || (!element.StartTag.Contains(caretPosition) && !element.EndTag.Contains(caretPosition))) return false; return element.InnerRange != null && element.GetText(element.InnerRange).Trim().Length > 0; }
public IEnumerable<ISuggestedAction> GetSuggestedActions(ITextView textView, ITextBuffer textBuffer, int caretPosition, ElementNode element, AttributeNode attribute, HtmlPositionType positionType) { return new ISuggestedAction[] { new HtmlMinifyLightBulbAction(textView, textBuffer, element), new HtmlExtractLightBulbAction(textView, textBuffer, element), }; }
public IEnumerable<ISuggestedAction> GetSuggestedActions(ITextView textView, ITextBuffer textBuffer, int caretPosition, ElementNode element, AttributeNode attribute, HtmlPositionType positionType) { AttributeNode ngController = element.GetAttribute("ng-controller") ?? element.GetAttribute("data-ng-controller"); return new ISuggestedAction[] { new HtmlAngularControllerLightBulbAction(textView, textBuffer, element, ngController) }; }
public IEnumerable<ISuggestedAction> GetSuggestedActions(ITextView textView, ITextBuffer textBuffer, int caretPosition, ElementNode element, AttributeNode attribute, HtmlPositionType positionType) { AttributeNode src = element.GetAttribute("src"); return new ISuggestedAction[] { new HtmlBase64DecodeLightBulbAction(textView, textBuffer, element, src) }; }
public IEnumerable<ISuggestedAction> GetSuggestedActions(ITextView textView, ITextBuffer textBuffer, int caretPosition, ElementNode element, AttributeNode attribute, HtmlPositionType positionType) { if (HasSuggestedActions(textView, textBuffer, caretPosition, element, attribute, positionType)) { yield return new HtmlMinifyLightBulbAction(textView, textBuffer, element); yield return new HtmlExtractLightBulbAction(textView, textBuffer, element); } }
public bool HasSuggestedActions(ITextView textView, ITextBuffer textBuffer, int caretPosition, ElementNode element, AttributeNode attribute, HtmlPositionType positionType) { if (element.Name != "img") return false; AttributeNode src = element.GetAttribute("src"); return src != null && src.Value.Trim().Length > 0; }
public bool HasSuggestedActions(ITextView textView, ITextBuffer textBuffer, int caretPosition, ElementNode element, AttributeNode attribute, HtmlPositionType positionType) { if (!element.StartTag.Contains(caretPosition)) return false; if (element.InnerRange.Length < 5) return false; return element.IsStyleBlock() || element.IsJavaScriptBlock(); }
public static Uri NormalizeUrl(AttributeNode attribute) { string value = attribute.Value; if (value.StartsWith("//", StringComparison.Ordinal)) value = "http:" + value; Uri url; Uri.TryCreate(value, UriKind.Absolute, out url); return url; }
public bool HasSuggestedActions(ITextView textView, ITextBuffer textBuffer, int caretPosition, ElementNode element, AttributeNode attribute, HtmlPositionType positionType) { if (!element.IsElement("img")) return false; AttributeNode src = element.GetAttribute("src"); if (src == null) return false; return src.Value.StartsWith("data:image/", StringComparison.Ordinal); }
public bool HasSuggestedActions(ITextView textView, ITextBuffer textBuffer, int caretPosition, ElementNode element, AttributeNode attribute, HtmlPositionType positionType) { if (!element.StartTag.Contains(caretPosition)) return false; string url = (element.GetAttribute("src") ?? element.GetAttribute("href"))?.Value; if (string.IsNullOrEmpty(url) || (!url.Contains("://") && !url.StartsWith("//"))) return false; return element.IsElement("style") || element.IsElement("script"); }
public IEnumerable<ISuggestedAction> GetSuggestedActions(ITextView textView, ITextBuffer textBuffer, int caretPosition, ElementNode element, AttributeNode attribute, HtmlPositionType positionType) { AttributeNode src = element.GetAttribute("src"); if (src.Value.StartsWith("data:image/", StringComparison.Ordinal)) { yield return new HtmlBase64DecodeLightBulbAction(textView, textBuffer, element, src); } if (!src.Value.StartsWith("http:") && !src.Value.StartsWith("https:") && !src.Value.StartsWith("//")) { yield return new HtmlOptimizeImageLightBulbAction(textView, textBuffer, element, src); } }
public IHtmlSmartTag TryCreateSmartTag(ITextView textView, ITextBuffer textBuffer, ElementNode element, AttributeNode attribute, int caretPosition, HtmlPositionType positionType) { AttributeNode attr = element.GetAttribute("src") ?? element.GetAttribute("href"); if (attr == null) return null; Uri url = NormalizeUrl(attr); if (url == null || (!attr.Value.StartsWith("//", StringComparison.Ordinal) && !attr.Value.Contains("://"))) return null; return new RemoteDownloaderSmartTag(textView, textBuffer, element, attr); }
public HtmlAngularControllerLightBulbAction(ITextView textView, ITextBuffer textBuffer, ElementNode element, AttributeNode attribute) : base(textView, textBuffer, element, attribute, "Add new Angular Controller") { _ngController = attribute; IconMoniker = KnownMonikers.JSScript; }
protected HtmlSuggestedActionBase(ITextView textView, ITextBuffer textBuffer, ElementNode element, AttributeNode attribute, string displayText) : base(textBuffer, textView, displayText) { Element = element; Attribute = attribute; }
public HtmlAngularControllerLightBulbAction(ITextView textView, ITextBuffer textBuffer, ElementNode element, AttributeNode attribute) : base(textView, textBuffer, element, attribute, "Add new Angular Controller") { _ngController = attribute; IconSource = _icon; }
/// <summary> /// Determines position type and enclosing element node for a given position in the document text. /// </summary> /// <param name="position">Position in the document text</param> /// <param name="element">Element that contains position</param> /// <param name="attribute">Attribute that contains position (may be null)</param> /// <returns>Position type as a set of flags combined via OR operation</returns> public virtual HtmlPositionType GetPositionElement(int position, out ElementNode element, out AttributeNode attribute) { element = null; attribute = null; // If start tag is not closed, consider end position to be inside it // so user can continue getting attribute intellisense, like in <a href=|<a ...></a> if (StartTag.Contains(position) || (position == StartTag.End && !StartTag.IsClosed)) { // If position is right at the start, it is actually before the tag (in parent's content), // as if when caret position is like this: <table>|<tr></tr><table> if (position == StartTag.Start) { element = this.Parent; return HtmlPositionType.InContent; } if (position >= QualifiedNameRange.Start && position <= StartTag.QualifiedNameRange.End) { element = this; return HtmlPositionType.ElementName; } element = this; for (int i = 0; i < Attributes.Count; i++) { var attrNode = Attributes[i]; bool hasClosingQuote = false; var valueToken = attrNode.ValueToken; hasClosingQuote = (valueToken != null) && (valueToken.CloseQuote != '\0'); if (position == attrNode.End && hasClosingQuote) break; if (position > attrNode.End) continue; if (position < attrNode.Start) break; if (attrNode.Contains(position) || (position == attrNode.End && !hasClosingQuote)) { attribute = attrNode; return attrNode.GetPositionType(position); } } return HtmlPositionType.InStartTag; } if (!this.Contains(position)) return HtmlPositionType.Undefined; for (int i = 0; i < this.Children.Count; i++) { var child = Children[i]; if (position < child.Start) break; if (child.Contains(position)) return child.GetPositionElement(position, out element, out attribute); } element = this; // If position is right at the start, it is actually before the end tag, // like when caret is between opening and closing tags: <table>|<table> if (EndTag != null) { if (position == EndTag.Start) return HtmlPositionType.InContent; if (EndTag.Contains(position)) return HtmlPositionType.InEndTag; } if (this.IsScriptBlock()) return HtmlPositionType.InScriptBlock; if (this.IsStyleBlock()) return HtmlPositionType.InStyleBlock; return HtmlPositionType.InContent; }
public HtmlOptimizeImageLightBulbAction(ITextView textView, ITextBuffer textBuffer, ElementNode element, AttributeNode attribute) : base(textView, textBuffer, element, attribute, "Optimize Image (lossless)") { }
public IEnumerable<ISuggestedAction> GetSuggestedActions(ITextView textView, ITextBuffer textBuffer, int caretPosition, ElementNode element, AttributeNode attribute, HtmlPositionType positionType) { yield return new HtmlRemoveElementLightBulbAction(textView, textBuffer, element); }
public RemoteDownloaderSmartTag(ITextView textView, ITextBuffer textBuffer, ElementNode element, AttributeNode attribute) : base(textView, textBuffer, element, HtmlSmartTagPosition.StartTag) { _attribute = attribute; }
private static void ReplaceUrlValue(string fileName, ITextBuffer buffer, AttributeNode src) { string relative = FileHelpers.RelativePath(buffer.GetFileName(), fileName); Span span = new Span(src.ValueRangeUnquoted.Start, src.ValueRangeUnquoted.Length); buffer.Replace(span, relative.ToLowerInvariant()); }
public bool HasSuggestedActions(ITextView textView, ITextBuffer textBuffer, int caretPosition, ElementNode element, AttributeNode attribute, HtmlPositionType positionType) { return element.HasAttribute("ng-controller") || element.HasAttribute("data-ng-controller"); }
public RemoteDownloaderSmartTagAction(HtmlSmartTag htmlSmartTag, AttributeNode attribute) : base(htmlSmartTag, "Download remote file") { _attribute = attribute; }
/// <summary> /// Determines position type and enclosing element node for a given position in the document text. /// </summary> /// <param name="position">Position in the document text</param> /// <param name="element">Element that contains position</param> /// <param name="attribute">Attribute that contains position (may be null)</param> /// <returns>Position type as a set of flags combined via OR operation</returns> public virtual HtmlPositionType GetPositionElement(int position, out ElementNode element, out AttributeNode attribute) { element = null; attribute = null; // If start tag is not closed, consider end position to be inside it // so user can continue getting attribute intellisense, like in <a href=|<a ...></a> if (StartTag.Contains(position) || (position == StartTag.End && !StartTag.IsClosed)) { // If position is right at the start, it is actually before the tag (in parent's content), // as if when caret position is like this: <table>|<tr></tr><table> if (position == StartTag.Start) { element = this.Parent; return(HtmlPositionType.InContent); } if (position >= QualifiedNameRange.Start && position <= StartTag.QualifiedNameRange.End) { element = this; return(HtmlPositionType.ElementName); } element = this; for (int i = 0; i < Attributes.Count; i++) { var attrNode = Attributes[i]; bool hasClosingQuote = false; var valueToken = attrNode.ValueToken; hasClosingQuote = (valueToken != null) && (valueToken.CloseQuote != '\0'); if (position == attrNode.End && hasClosingQuote) { break; } if (position > attrNode.End) { continue; } if (position < attrNode.Start) { break; } if (attrNode.Contains(position) || (position == attrNode.End && !hasClosingQuote)) { attribute = attrNode; return(attrNode.GetPositionType(position)); } } return(HtmlPositionType.InStartTag); } if (!this.Contains(position)) { return(HtmlPositionType.Undefined); } for (int i = 0; i < this.Children.Count; i++) { var child = Children[i]; if (position < child.Start) { break; } if (child.Contains(position)) { return(child.GetPositionElement(position, out element, out attribute)); } } element = this; // If position is right at the start, it is actually before the end tag, // like when caret is between opening and closing tags: <table>|<table> if (EndTag != null) { if (position == EndTag.Start) { return(HtmlPositionType.InContent); } if (EndTag.Contains(position)) { return(HtmlPositionType.InEndTag); } } if (this.IsScriptBlock()) { return(HtmlPositionType.InScriptBlock); } if (this.IsStyleBlock()) { return(HtmlPositionType.InStyleBlock); } return(HtmlPositionType.InContent); }
/// <summary> /// Determines given position type. Returns element and attribute at this position. Attribute can be null. /// Return type specifies position as a set of flags <seealso cref="HtmlPositionType"/> /// </summary> /// <param name="position">Position in the document</param> /// <param name="element">Element that contains this position</param> /// <param name="attribute">Attribute that contains this position or null of none</param> /// <returns>Set of flags describing the position</returns> public override HtmlPositionType GetPositionElement(int position, out ElementNode element, out AttributeNode attribute) { element = null; attribute = null; foreach (ElementNode child in Children) { if (child.Start > position) break; if (child.Contains(position)) return child.GetPositionElement(position, out element, out attribute); } element = this; return HtmlPositionType.InContent; }
private void WriteAttribute(AttributeNode at) { _sb.Append(' '); string prefix = _tree.Text.GetText(at.PrefixRange); string colon = (at.NameToken != null && at.NameToken.HasColon) ? _tree.Text.GetText(at.NameToken.ColonRange) : String.Empty; string name = _tree.Text.GetText(at.NameRange); _sb.Append(prefix); _sb.Append(colon); _sb.Append(name); if (at.EqualsSignRange.Length > 0) _sb.Append('='); if (at.HasValue()) { string value = _tree.Text.GetText(at.ValueRange); _sb.Append(value); } }
public HtmlBase64DecodeLightBulbAction(ITextView textView, ITextBuffer textBuffer, ElementNode element, AttributeNode attribute) : base(textView, textBuffer, element, attribute, "Save as File...") { }
public HtmlRemoveElementLightBulbAction(ITextView textView, ITextBuffer textBuffer, ElementNode element) : base(textView, textBuffer, element, element.Children.Count == 0 ? "Remove <" + element.StartTag.Name + "> tag" : "Remove <" + element.StartTag.Name + "> and Keep Children") { _src = element.GetAttribute("src", true); }
/// <summary> /// Determines given position type. Returns element and attribute at this position. Attribute can be null. /// Return type specifies position as a set of flags <seealso cref="HtmlPositionType"/> /// </summary> /// <param name="position">Position in the document</param> /// <param name="element">Element that contains this position</param> /// <param name="attribute">Attribute that contains this position or null of none</param> /// <returns>Set of flags describing the position</returns> public override HtmlPositionType GetPositionElement(int position, out ElementNode element, out AttributeNode attribute) { element = null; attribute = null; foreach (ElementNode child in Children) { if (child.Start > position) { break; } if (child.Contains(position)) { return(child.GetPositionElement(position, out element, out attribute)); } } element = this; return(HtmlPositionType.InContent); }