Search in sources :

Example 36 with XmlElementDescriptor

use of com.intellij.xml.XmlElementDescriptor 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 37 with XmlElementDescriptor

use of com.intellij.xml.XmlElementDescriptor in project intellij-community by JetBrains.

the class XmlParameterInfoHandler method findElementForParameterInfo.

@Override
public XmlTag findElementForParameterInfo(@NotNull final CreateParameterInfoContext context) {
    final XmlTag tag = findXmlTag(context.getFile(), context.getOffset());
    final XmlElementDescriptor descriptor = tag != null ? tag.getDescriptor() : null;
    if (descriptor == null) {
        DaemonCodeAnalyzer.getInstance(context.getProject()).updateVisibleHighlighters(context.getEditor());
        return null;
    }
    context.setItemsToShow(new Object[] { descriptor });
    return tag;
}
Also used : XmlElementDescriptor(com.intellij.xml.XmlElementDescriptor) XmlTag(com.intellij.psi.xml.XmlTag)

Example 38 with XmlElementDescriptor

use of com.intellij.xml.XmlElementDescriptor in project intellij-community by JetBrains.

the class DomDescriptorProvider method getDescriptor.

@Override
@Nullable
public XmlElementDescriptor getDescriptor(final XmlTag tag) {
    Project project = tag.getProject();
    if (project.isDefault())
        return null;
    final DomInvocationHandler<?, ?> handler = DomManagerImpl.getDomManager(project).getDomHandler(tag);
    if (handler != null) {
        final DefinesXml definesXml = handler.getAnnotation(DefinesXml.class);
        if (definesXml != null) {
            return new DomElementXmlDescriptor(handler);
        }
        final PsiElement parent = tag.getParent();
        if (parent instanceof XmlTag) {
            final XmlElementDescriptor descriptor = ((XmlTag) parent).getDescriptor();
            if (descriptor instanceof DomElementXmlDescriptor) {
                return descriptor.getElementDescriptor(tag, (XmlTag) parent);
            }
        }
    }
    return null;
}
Also used : Project(com.intellij.openapi.project.Project) DomElementXmlDescriptor(com.intellij.xml.impl.dom.DomElementXmlDescriptor) XmlElementDescriptor(com.intellij.xml.XmlElementDescriptor) DefinesXml(com.intellij.util.xml.DefinesXml) PsiElement(com.intellij.psi.PsiElement) XmlTag(com.intellij.psi.xml.XmlTag) Nullable(org.jetbrains.annotations.Nullable)

Example 39 with XmlElementDescriptor

use of com.intellij.xml.XmlElementDescriptor in project intellij-community by JetBrains.

the class HtmlUtil method tagHasHtml5Schema.

public static boolean tagHasHtml5Schema(@NotNull XmlTag context) {
    XmlElementDescriptor descriptor = context.getDescriptor();
    if (descriptor != null) {
        XmlNSDescriptor nsDescriptor = descriptor.getNSDescriptor();
        XmlFile descriptorFile = nsDescriptor != null ? nsDescriptor.getDescriptorFile() : null;
        String descriptorPath = descriptorFile != null ? descriptorFile.getVirtualFile().getPath() : null;
        return Comparing.equal(Html5SchemaProvider.getHtml5SchemaLocation(), descriptorPath) || Comparing.equal(Html5SchemaProvider.getXhtml5SchemaLocation(), descriptorPath);
    }
    return false;
}
Also used : XmlNSDescriptor(com.intellij.xml.XmlNSDescriptor) XmlElementDescriptor(com.intellij.xml.XmlElementDescriptor)

Example 40 with XmlElementDescriptor

use of com.intellij.xml.XmlElementDescriptor in project intellij-community by JetBrains.

the class TagNameReference method resolve.

@Override
public PsiElement resolve() {
    final XmlTag tag = getTagElement();
    final XmlElementDescriptor descriptor = tag != null ? tag.getDescriptor() : null;
    if (LOG.isDebugEnabled()) {
        LOG.debug("Descriptor for tag " + (tag != null ? tag.getName() : "NULL") + " is " + (descriptor != null ? (descriptor.toString() + ": " + descriptor.getClass().getCanonicalName()) : "NULL"));
    }
    if (descriptor != null) {
        return descriptor instanceof AnyXmlElementDescriptor ? tag : descriptor.getDeclaration();
    }
    return null;
}
Also used : AnyXmlElementDescriptor(com.intellij.xml.impl.schema.AnyXmlElementDescriptor) XmlElementDescriptor(com.intellij.xml.XmlElementDescriptor) AnyXmlElementDescriptor(com.intellij.xml.impl.schema.AnyXmlElementDescriptor) XmlTag(com.intellij.psi.xml.XmlTag)

Aggregations

XmlElementDescriptor (com.intellij.xml.XmlElementDescriptor)159 XmlTag (com.intellij.psi.xml.XmlTag)88 XmlNSDescriptor (com.intellij.xml.XmlNSDescriptor)60 XmlAttributeDescriptor (com.intellij.xml.XmlAttributeDescriptor)54 PsiElement (com.intellij.psi.PsiElement)23 XmlFile (com.intellij.psi.xml.XmlFile)23 Nullable (org.jetbrains.annotations.Nullable)23 AnyXmlElementDescriptor (com.intellij.xml.impl.schema.AnyXmlElementDescriptor)22 PsiFile (com.intellij.psi.PsiFile)11 ArrayList (java.util.ArrayList)11 XmlAttribute (com.intellij.psi.xml.XmlAttribute)10 NotNull (org.jetbrains.annotations.NotNull)10 ClassBackedElementDescriptor (com.intellij.javascript.flex.mxml.schema.ClassBackedElementDescriptor)7 JSClass (com.intellij.lang.javascript.psi.ecmal4.JSClass)7 Project (com.intellij.openapi.project.Project)7 HtmlTag (com.intellij.psi.html.HtmlTag)7 AnnotationBackedDescriptor (com.intellij.lang.javascript.flex.AnnotationBackedDescriptor)5 XmlDocument (com.intellij.psi.xml.XmlDocument)5 DElementPattern (org.kohsuke.rngom.digested.DElementPattern)5 InvalidPropertyException (com.intellij.flex.uiDesigner.InvalidPropertyException)4