Represent HTML element node in the tree
Inheritance: TreeNode, ICompositeTextRange, IHtmlTreeVisitorPattern, IPropertyOwner
示例#1
0
        private void WriteTag(ElementNode element, TagNode tag, bool endTag) {
            Indent();

            string prefix = _tree.Text.GetText(tag.PrefixRange);
            string colon = (tag.NameToken != null && tag.NameToken.HasColon) ? _tree.Text.GetText(tag.NameToken.ColonRange) : String.Empty;
            string name = _tree.Text.GetText(tag.NameRange);

            if (endTag)
                _sb.Append("</");
            else
                _sb.Append('<');

            _sb.Append(prefix);
            _sb.Append(colon);
            _sb.Append(name);

            foreach (AttributeNode a in tag.Attributes)
                WriteAttribute(a);

            if (tag.IsClosed) {
                if (String.Compare(element.Name, "?xml") == 0)
                    _sb.Append(" ?>");
                else if (tag.IsShorthand)
                    _sb.Append(" />");
                else
                    _sb.Append('>');
            }

            _sb.Append("\r\n");
        }
 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 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)
        {
            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 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)
            };
		}
示例#7
0
        public static AttributeNode Create(ElementNode parent, AttributeToken token) {
            var nameToken = token.NameToken as NameToken;

            if (nameToken != null && nameToken.HasPrefix())
                return new AttributeNodeWithPrefix(parent, token);

            return new AttributeNode(parent, token);

        }
		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 Visit(ElementNode element, object parameter)
        {
            if (element.HasAttribute("id"))
            {
                var list = (HashSet<string>)parameter;
                list.Add(element.GetAttribute("id").Value);
            }

            return true;
        }
		private static string GetReference(ElementNode element, string fileName, string root)
		{
			string relative = FileHelpers.RelativePath(root, fileName);
			string reference = "<script src=\"/{0}\"></script>";

			if (element.IsStyleBlock())
				reference = "<link rel=\"stylesheet\" href=\"/{0}\" />";

			return string.Format(CultureInfo.CurrentCulture, reference, HttpUtility.HtmlAttributeEncode(relative));
		}
        public bool Visit(ElementNode element, object parameter)
        {
            if (element.Name.Equals("datalist", StringComparison.OrdinalIgnoreCase))
            {
                var list = (HashSet<string>)parameter;
                list.Add(element.Id);
            }

            return true;
        }
        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 bool Visit(ElementNode element, object parameter)
        {
            if (element.Name.Equals("title", StringComparison.OrdinalIgnoreCase))
            {
                var list = (HashSet<string>)parameter;
                string text = element.GetText(element.InnerRange);
                list.Add(text);
            }

            return true;
        }
示例#14
0
文件: TagNode.cs 项目: Microsoft/RTVS
        public TagNode(ElementNode parent, int openAngleBracketPosition, NameToken nameToken, int maxEnd) {
            NameToken = nameToken;

            _name = nameToken.HasName() ? parent.GetText(nameToken.NameRange) : String.Empty;

            _start = openAngleBracketPosition;
            _end = maxEnd;

            IsClosed = false;
            IsShorthand = false;
        }
示例#15
0
        public ElementNode(ElementNode parent, int openAngleBracketPosition, NameToken nameToken, int maxEnd) {
            Parent = parent;

            if (nameToken.HasColon)
                StartTag = new TagNodeWithPrefix(this, openAngleBracketPosition, nameToken, maxEnd);
            else
                StartTag = new TagNode(this, openAngleBracketPosition, nameToken, maxEnd);

            VirtualEnd = maxEnd;
            Properties = new PropertyDictionary();
        }
示例#16
0
        private void WriteElement(ElementNode node) {
            WriteTag(node, node.StartTag, false);
            _indent++;

            foreach (ElementNode child in node.Children)
                WriteElement(child);

            _indent--;

            if (node.EndTag != null)
                WriteTag(node, node.EndTag, true);
        }
        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 bool Visit(ElementNode element, object parameter)
        {
            if (_inputTypes.Contains(element.Name.ToLowerInvariant()))
            {
                var list = (HashSet<string>)parameter;
                var id = element.GetAttribute("id");

                if (id != null)
                    list.Add(id.Value);
            }

            return true;
        }
        public bool Visit(ElementNode element, object parameter)
        {
            if (element.Name == "label")
            {
                var list = (HashSet<string>)parameter;
                var forAttr = element.GetAttribute("for");

                if (forAttr != null)
                    list.Add(forAttr.Value);
            }

            return true;
        }
        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 bool Visit(ElementNode element, object parameter)
        {
            // Search in class names to in order to make Intellisense show after typing "ng-" as a class value
            if (element.Attributes.Any(a => (a.Name.StartsWith("ng-", StringComparison.Ordinal)
                                         || a.Name.StartsWith("data-ng-", StringComparison.Ordinal)
                                         || (a.Name == "class" && a.Value != null && a.Value.StartsWith("ng-", StringComparison.Ordinal)))))
            {
                var list = (HashSet<bool>)parameter;
                list.Add(true);
                return true;
            }

            return true;
        }
		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); 
			}
		}
示例#24
0
        protected AttributeNode(ElementNode parent, AttributeToken token) {
            AttributeToken = token;

            if (parent != null && parent.Root.Tree != null) {
                var nameToken = token.NameToken as NameToken;

                if (token.HasName())
                    _name = parent.GetText(nameToken != null ? nameToken.NameRange : token);
                else
                    _name = String.Empty;

                UpdateValue(parent.TextProvider);
            }
        }
        private static bool IsValid(ElementNode element)
        {
            if (element == null)
                return false;

            ElementNode parent = element.Parent;

            while (parent != null)
            {
                if (parent.Name == "template")
                    return true;

                parent = parent.Parent;
            }

            return false;
        }
 public IntegrityLightBulbAction(ITextView textView, ITextBuffer textBuffer, ElementNode element)
     : base(textView, textBuffer, element, "Calculate integrity")
 { }
示例#27
0
        /// <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 HtmlAngularControllerLightBulbAction(ITextView textView, ITextBuffer textBuffer, ElementNode element, AttributeNode attribute)
			: base(textView, textBuffer, element, attribute, "Add new Angular Controller")
		{
			_ngController = attribute;
            IconMoniker = KnownMonikers.JSScript;
		}
		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 HtmlExtractLightBulbAction(ITextView textView, ITextBuffer textBuffer, ElementNode element)
			: base(textView, textBuffer, element, "Extract to 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);
		}
示例#32
0
 public TagNodeWithPrefix(ElementNode parent, int openAngleBracketPosition, NameToken nameToken, int maxEnd)
     : base(parent, openAngleBracketPosition, nameToken, maxEnd)
 {
     _prefix = nameToken.HasPrefix() ? parent.GetText(nameToken.PrefixRange) : String.Empty;
 }