Search in sources :

Example 6 with HtmlTag

use of com.intellij.psi.html.HtmlTag in project intellij-community by JetBrains.

the class XmlHighlightVisitor method checkAttribute.

private void checkAttribute(XmlAttribute attribute) {
    XmlTag tag = attribute.getParent();
    if (tag == null)
        return;
    final String name = attribute.getName();
    PsiElement prevLeaf = PsiTreeUtil.prevLeaf(attribute);
    if (!(prevLeaf instanceof PsiWhiteSpace)) {
        TextRange textRange = attribute.getTextRange();
        HighlightInfoType type = tag instanceof HtmlTag ? HighlightInfoType.WARNING : HighlightInfoType.ERROR;
        String description = XmlErrorMessages.message("attribute.should.be.preceded.with.space");
        HighlightInfo info = HighlightInfo.newHighlightInfo(type).range(textRange.getStartOffset(), textRange.getStartOffset()).descriptionAndTooltip(description).create();
        addToResults(info);
    }
    if (attribute.isNamespaceDeclaration() || XmlUtil.XML_SCHEMA_INSTANCE_URI.equals(attribute.getNamespace())) {
        //checkReferences(attribute.getValueElement());
        return;
    }
    XmlElementDescriptor elementDescriptor = tag.getDescriptor();
    if (elementDescriptor == null || elementDescriptor instanceof AnyXmlElementDescriptor || ourDoJaxpTesting) {
        return;
    }
    XmlAttributeDescriptor attributeDescriptor = elementDescriptor.getAttributeDescriptor(attribute);
    if (attributeDescriptor == null) {
        if (!XmlUtil.attributeFromTemplateFramework(name, tag)) {
            final String localizedMessage = XmlErrorMessages.message("attribute.is.not.allowed.here", name);
            final HighlightInfo highlightInfo = reportAttributeProblem(tag, name, attribute, localizedMessage);
            if (highlightInfo != null) {
                PsiFile file = tag.getContainingFile();
                if (file != null) {
                    for (XmlUndefinedElementFixProvider fixProvider : Extensions.getExtensions(XmlUndefinedElementFixProvider.EP_NAME)) {
                        IntentionAction[] fixes = fixProvider.createFixes(attribute);
                        if (fixes != null) {
                            for (IntentionAction action : fixes) {
                                QuickFixAction.registerQuickFixAction(highlightInfo, action);
                            }
                            break;
                        }
                    }
                }
            }
        }
    } else {
        checkDuplicateAttribute(tag, attribute);
        // we skip resolve of attribute references since there is separate check when taking attribute descriptors
        PsiReference[] attrRefs = attribute.getReferences();
        doCheckRefs(attribute, attrRefs, !attribute.getNamespacePrefix().isEmpty() ? 2 : 1);
    }
}
Also used : AnyXmlElementDescriptor(com.intellij.xml.impl.schema.AnyXmlElementDescriptor) HighlightInfo(com.intellij.codeInsight.daemon.impl.HighlightInfo) TextRange(com.intellij.openapi.util.TextRange) HtmlTag(com.intellij.psi.html.HtmlTag) HighlightInfoType(com.intellij.codeInsight.daemon.impl.HighlightInfoType) IntentionAction(com.intellij.codeInsight.intention.IntentionAction) AnyXmlElementDescriptor(com.intellij.xml.impl.schema.AnyXmlElementDescriptor)

Example 7 with HtmlTag

use of com.intellij.psi.html.HtmlTag in project intellij-community by JetBrains.

the class RequiredAttributesInspectionBase method hasAttribute.

private static boolean hasAttribute(XmlTag tag, String attrName) {
    final XmlAttribute attribute = tag.getAttribute(attrName);
    if (attribute == null)
        return false;
    if (attribute.getValueElement() != null)
        return true;
    if (!(tag instanceof HtmlTag))
        return false;
    final XmlAttributeDescriptor descriptor = attribute.getDescriptor();
    return descriptor != null && HtmlUtil.isBooleanAttribute(descriptor, tag);
}
Also used : XmlAttribute(com.intellij.psi.xml.XmlAttribute) XmlAttributeDescriptor(com.intellij.xml.XmlAttributeDescriptor) HtmlTag(com.intellij.psi.html.HtmlTag)

Example 8 with HtmlTag

use of com.intellij.psi.html.HtmlTag in project intellij-community by JetBrains.

the class XmlGtTypedHandler method beforeCharTyped.

@Override
public Result beforeCharTyped(final char c, final Project project, Editor editor, PsiFile editedFile, final FileType fileType) {
    final WebEditorOptions webEditorOptions = WebEditorOptions.getInstance();
    if (c == '>' && webEditorOptions != null && webEditorOptions.isAutomaticallyInsertClosingTag() && fileContainsXmlLanguage(editedFile)) {
        PsiDocumentManager.getInstance(project).commitAllDocuments();
        PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
        FileViewProvider provider = editedFile.getViewProvider();
        int offset = editor.getCaretModel().getOffset();
        PsiElement element, elementAtCaret = null;
        if (offset < editor.getDocument().getTextLength()) {
            elementAtCaret = element = provider.findElementAt(offset, XMLLanguage.class);
            if (element == null && offset > 0) {
                // seems like a template language
                // <xml_code><caret><outer_element>
                elementAtCaret = element = provider.findElementAt(offset - 1, XMLLanguage.class);
            }
            if (!(element instanceof PsiWhiteSpace)) {
                boolean nonAcceptableDelimiter = true;
                if (element instanceof XmlToken) {
                    IElementType tokenType = ((XmlToken) element).getTokenType();
                    if (tokenType == XmlTokenType.XML_START_TAG_START || tokenType == XmlTokenType.XML_END_TAG_START) {
                        if (offset > 0) {
                            PsiElement previousElement = provider.findElementAt(offset - 1, XMLLanguage.class);
                            if (previousElement instanceof XmlToken) {
                                tokenType = ((XmlToken) previousElement).getTokenType();
                                element = previousElement;
                                nonAcceptableDelimiter = false;
                            }
                        }
                    } else if (tokenType == XmlTokenType.XML_NAME || tokenType == XmlTokenType.XML_TAG_NAME) {
                        if (element.getNextSibling() instanceof PsiErrorElement) {
                            nonAcceptableDelimiter = false;
                        }
                    }
                    if (tokenType == XmlTokenType.XML_TAG_END || tokenType == XmlTokenType.XML_EMPTY_ELEMENT_END && element.getTextOffset() == offset - 1) {
                        EditorModificationUtil.moveCaretRelatively(editor, 1);
                        editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
                        return Result.STOP;
                    }
                }
                if (nonAcceptableDelimiter)
                    return Result.CONTINUE;
            } else {
                // check if right after empty end
                PsiElement previousElement = provider.findElementAt(offset - 1, XMLLanguage.class);
                if (previousElement instanceof XmlToken) {
                    final IElementType tokenType = ((XmlToken) previousElement).getTokenType();
                    if (tokenType == XmlTokenType.XML_EMPTY_ELEMENT_END) {
                        return Result.STOP;
                    }
                }
            }
            PsiElement parent = element.getParent();
            if (parent instanceof XmlText) {
                final String text = parent.getText();
                // check /
                final int index = offset - parent.getTextOffset() - 1;
                if (index >= 0 && text.charAt(index) == '/') {
                    // already seen /
                    return Result.CONTINUE;
                }
                element = parent.getPrevSibling();
            } else if (parent instanceof XmlTag && !(element.getPrevSibling() instanceof XmlTag) && !(element.getPrevSibling() instanceof OuterLanguageElement)) {
                element = parent;
            } else if (parent instanceof XmlAttributeValue) {
                element = parent;
            }
        } else {
            element = provider.findElementAt(editor.getDocument().getTextLength() - 1, XMLLanguage.class);
            if (element == null)
                return Result.CONTINUE;
            element = element.getParent();
        }
        if (offset > 0 && offset <= editor.getDocument().getTextLength()) {
            if (editor.getDocument().getCharsSequence().charAt(offset - 1) == '/') {
                // Some languages (e.g. GSP) allow character '/' in tag name.
                return Result.CONTINUE;
            }
        }
        if (element instanceof XmlAttributeValue) {
            element = element.getParent().getParent();
        }
        while (element instanceof PsiWhiteSpace || element instanceof OuterLanguageElement) element = element.getPrevSibling();
        if (element instanceof XmlDocument) {
            // hack for closing tags in RHTML
            element = element.getLastChild();
        }
        if (element == null)
            return Result.CONTINUE;
        if (!(element instanceof XmlTag)) {
            if (element instanceof XmlTokenImpl && element.getPrevSibling() != null && element.getPrevSibling().getText().equals("<")) {
                // tag is started and there is another text in the end
                EditorModificationUtil.insertStringAtCaret(editor, "</" + element.getText() + ">", false, 0);
            }
            return Result.CONTINUE;
        }
        XmlTag tag = (XmlTag) element;
        if (XmlUtil.getTokenOfType(tag, XmlTokenType.XML_TAG_END) != null)
            return Result.CONTINUE;
        if (XmlUtil.getTokenOfType(tag, XmlTokenType.XML_EMPTY_ELEMENT_END) != null)
            return Result.CONTINUE;
        final XmlToken startToken = XmlUtil.getTokenOfType(tag, XmlTokenType.XML_START_TAG_START);
        if (startToken == null || !startToken.getText().equals("<"))
            return Result.CONTINUE;
        String name = tag.getName();
        if (elementAtCaret instanceof XmlToken && (((XmlToken) elementAtCaret).getTokenType() == XmlTokenType.XML_NAME || ((XmlToken) elementAtCaret).getTokenType() == XmlTokenType.XML_TAG_NAME)) {
            name = name.substring(0, offset - elementAtCaret.getTextOffset());
        }
        if (tag instanceof HtmlTag && HtmlUtil.isSingleHtmlTag(name))
            return Result.CONTINUE;
        if (name.isEmpty())
            return Result.CONTINUE;
        int tagOffset = tag.getTextRange().getStartOffset();
        final XmlToken nameToken = XmlUtil.getTokenOfType(tag, XmlTokenType.XML_NAME);
        if (nameToken != null && nameToken.getTextRange().getStartOffset() > offset)
            return Result.CONTINUE;
        HighlighterIterator iterator = ((EditorEx) editor).getHighlighter().createIterator(tagOffset);
        if (BraceMatchingUtil.matchBrace(editor.getDocument().getCharsSequence(), editedFile.getFileType(), iterator, true, true)) {
            PsiElement parent = tag.getParent();
            boolean hasBalance = true;
            loop: while (parent instanceof XmlTag) {
                if (name.equals(((XmlTag) parent).getName())) {
                    hasBalance = false;
                    ASTNode astNode = XmlChildRole.CLOSING_TAG_NAME_FINDER.findChild(parent.getNode());
                    if (astNode == null) {
                        hasBalance = true;
                        break;
                    }
                    for (PsiElement el = parent.getNextSibling(); el != null; el = el.getNextSibling()) {
                        if (el instanceof PsiErrorElement && el.getText().startsWith("</" + name)) {
                            hasBalance = true;
                            break loop;
                        }
                    }
                }
                parent = parent.getParent();
            }
            if (hasBalance)
                return Result.CONTINUE;
        }
        Collection<TextRange> cdataReformatRanges = null;
        final XmlElementDescriptor descriptor = tag.getDescriptor();
        EditorModificationUtil.insertStringAtCaret(editor, "</" + name + ">", false, 0);
        if (descriptor instanceof XmlElementDescriptorWithCDataContent) {
            final XmlElementDescriptorWithCDataContent cDataContainer = (XmlElementDescriptorWithCDataContent) descriptor;
            cdataReformatRanges = ContainerUtil.newSmartList();
            if (cDataContainer.requiresCdataBracesInContext(tag)) {
                @NonNls final String cDataStart = "><![CDATA[";
                final String inserted = cDataStart + "\n]]>";
                EditorModificationUtil.insertStringAtCaret(editor, inserted, false, cDataStart.length());
                int caretOffset = editor.getCaretModel().getOffset();
                if (caretOffset >= cDataStart.length()) {
                    cdataReformatRanges.add(TextRange.from(caretOffset - cDataStart.length(), inserted.length() + 1));
                }
            }
        }
        if (cdataReformatRanges != null && !cdataReformatRanges.isEmpty()) {
            PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
            try {
                CodeStyleManager.getInstance(project).reformatText(file, cdataReformatRanges);
            } catch (IncorrectOperationException e) {
                LOG.error(e);
            }
        }
        return cdataReformatRanges != null && !cdataReformatRanges.isEmpty() ? Result.STOP : Result.CONTINUE;
    }
    return Result.CONTINUE;
}
Also used : OuterLanguageElement(com.intellij.psi.templateLanguages.OuterLanguageElement) XmlTokenImpl(com.intellij.psi.impl.source.xml.XmlTokenImpl) TemplateLanguageFileViewProvider(com.intellij.psi.templateLanguages.TemplateLanguageFileViewProvider) WebEditorOptions(com.intellij.application.options.editor.WebEditorOptions) ASTNode(com.intellij.lang.ASTNode) XMLLanguage(com.intellij.lang.xml.XMLLanguage) NonNls(org.jetbrains.annotations.NonNls) HtmlTag(com.intellij.psi.html.HtmlTag) TextRange(com.intellij.openapi.util.TextRange) IElementType(com.intellij.psi.tree.IElementType) XmlElementDescriptorWithCDataContent(com.intellij.xml.XmlElementDescriptorWithCDataContent) IncorrectOperationException(com.intellij.util.IncorrectOperationException) XmlElementDescriptor(com.intellij.xml.XmlElementDescriptor) HighlighterIterator(com.intellij.openapi.editor.highlighter.HighlighterIterator)

Example 9 with HtmlTag

use of com.intellij.psi.html.HtmlTag in project intellij-community by JetBrains.

the class XmlTagInsertHandler method addRequiredAttributes.

@Nullable
private static StringBuilder addRequiredAttributes(XmlElementDescriptor descriptor, @Nullable XmlTag tag, Template template, PsiFile containingFile) {
    boolean htmlCode = HtmlUtil.hasHtml(containingFile) || HtmlUtil.supportsXmlTypedHandlers(containingFile);
    Set<String> notRequiredAttributes = Collections.emptySet();
    if (tag instanceof HtmlTag) {
        final InspectionProfile profile = InspectionProjectProfileManager.getInstance(tag.getProject()).getCurrentProfile();
        XmlEntitiesInspection inspection = (XmlEntitiesInspection) profile.getUnwrappedTool(XmlEntitiesInspection.REQUIRED_ATTRIBUTES_SHORT_NAME, tag);
        if (inspection != null) {
            StringTokenizer tokenizer = new StringTokenizer(inspection.getAdditionalEntries());
            notRequiredAttributes = new HashSet<>();
            while (tokenizer.hasMoreElements()) notRequiredAttributes.add(tokenizer.nextToken());
        }
    }
    XmlAttributeDescriptor[] attributes = descriptor.getAttributesDescriptors(tag);
    StringBuilder indirectRequiredAttrs = null;
    if (WebEditorOptions.getInstance().isAutomaticallyInsertRequiredAttributes()) {
        final XmlExtension extension = XmlExtension.getExtension(containingFile);
        for (XmlAttributeDescriptor attributeDecl : attributes) {
            String attributeName = attributeDecl.getName(tag);
            boolean shouldBeInserted = extension.shouldBeInserted(attributeDecl);
            if (shouldBeInserted && (tag == null || tag.getAttributeValue(attributeName) == null)) {
                if (!notRequiredAttributes.contains(attributeName)) {
                    if (!extension.isIndirectSyntax(attributeDecl)) {
                        template.addTextSegment(" " + attributeName + "=" + XmlAttributeInsertHandler.getAttributeQuote(htmlCode));
                        template.addVariable(new MacroCallNode(new CompleteMacro()), true);
                        template.addTextSegment(XmlAttributeInsertHandler.getAttributeQuote(htmlCode));
                    } else {
                        if (indirectRequiredAttrs == null)
                            indirectRequiredAttrs = new StringBuilder();
                        indirectRequiredAttrs.append("\n<jsp:attribute name=\"").append(attributeName).append("\"></jsp:attribute>\n");
                    }
                }
            } else if (shouldBeInserted && attributeDecl.isFixed() && attributeDecl.getDefaultValue() != null && !htmlCode) {
                template.addTextSegment(" " + attributeName + "=" + XmlAttributeInsertHandler.getAttributeQuote(false) + attributeDecl.getDefaultValue() + XmlAttributeInsertHandler.getAttributeQuote(false));
            }
        }
    }
    return indirectRequiredAttrs;
}
Also used : InspectionProfile(com.intellij.codeInspection.InspectionProfile) HtmlTag(com.intellij.psi.html.HtmlTag) CompleteMacro(com.intellij.codeInsight.template.macro.CompleteMacro) MacroCallNode(com.intellij.codeInsight.template.impl.MacroCallNode) XmlEntitiesInspection(com.intellij.codeInspection.htmlInspections.XmlEntitiesInspection) Nullable(org.jetbrains.annotations.Nullable)

Example 10 with HtmlTag

use of com.intellij.psi.html.HtmlTag in project intellij-community by JetBrains.

the class XmlDocumentationProvider method generateHtmlAdditionalDocTemplate.

static String generateHtmlAdditionalDocTemplate(@NotNull PsiElement element) {
    StringBuilder buf = new StringBuilder();
    final PsiFile containingFile = element.getContainingFile();
    if (containingFile != null) {
        final XmlTag tag = PsiTreeUtil.getParentOfType(element, XmlTag.class, false);
        boolean append;
        if (tag instanceof HtmlTag) {
            append = true;
        } else {
            final FileViewProvider provider = containingFile.getViewProvider();
            Language language;
            if (provider instanceof TemplateLanguageFileViewProvider) {
                language = ((TemplateLanguageFileViewProvider) provider).getTemplateDataLanguage();
            } else {
                language = provider.getBaseLanguage();
            }
            append = language == XHTMLLanguage.INSTANCE;
        }
        if (tag != null) {
            EntityDescriptor descriptor = HtmlDescriptorsTable.getTagDescriptor(tag.getName());
            if (descriptor != null && append) {
                buf.append("<br>");
                buf.append(XmlBundle.message("html.quickdoc.additional.template", descriptor.getHelpRef(), BASE_SITEPOINT_URL + tag.getName()));
            }
        }
    }
    return buf.toString();
}
Also used : TemplateLanguageFileViewProvider(com.intellij.psi.templateLanguages.TemplateLanguageFileViewProvider) Language(com.intellij.lang.Language) XHTMLLanguage(com.intellij.lang.xhtml.XHTMLLanguage) HtmlTag(com.intellij.psi.html.HtmlTag) TemplateLanguageFileViewProvider(com.intellij.psi.templateLanguages.TemplateLanguageFileViewProvider)

Aggregations

HtmlTag (com.intellij.psi.html.HtmlTag)25 XmlTag (com.intellij.psi.xml.XmlTag)9 AnyXmlElementDescriptor (com.intellij.xml.impl.schema.AnyXmlElementDescriptor)8 PsiElement (com.intellij.psi.PsiElement)7 PsiFile (com.intellij.psi.PsiFile)7 XmlElementDescriptor (com.intellij.xml.XmlElementDescriptor)7 XmlAttributeDescriptor (com.intellij.xml.XmlAttributeDescriptor)5 ASTNode (com.intellij.lang.ASTNode)4 Language (com.intellij.lang.Language)4 TextRange (com.intellij.openapi.util.TextRange)4 LocalQuickFix (com.intellij.codeInspection.LocalQuickFix)3 XHTMLLanguage (com.intellij.lang.xhtml.XHTMLLanguage)3 XMLLanguage (com.intellij.lang.xml.XMLLanguage)3 Project (com.intellij.openapi.project.Project)3 TemplateLanguageFileViewProvider (com.intellij.psi.templateLanguages.TemplateLanguageFileViewProvider)3 HighlightInfo (com.intellij.codeInsight.daemon.impl.HighlightInfo)2 HighlightInfoType (com.intellij.codeInsight.daemon.impl.HighlightInfoType)2 LookupElement (com.intellij.codeInsight.lookup.LookupElement)2 HTMLLanguage (com.intellij.lang.html.HTMLLanguage)2 PsiErrorElement (com.intellij.psi.PsiErrorElement)2