diff --git a/platform/platform-resources/src/META-INF/XmlPlugin.xml b/platform/platform-resources/src/META-INF/XmlPlugin.xml index bf85eb6606f9..d66fc02dd09f 100644 --- a/platform/platform-resources/src/META-INF/XmlPlugin.xml +++ b/platform/platform-resources/src/META-INF/XmlPlugin.xml @@ -299,6 +299,7 @@ + diff --git a/xml/xml-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HtmlFileReferenceHelper.java b/xml/xml-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HtmlFileReferenceHelper.java new file mode 100644 index 000000000000..40c12a886140 --- /dev/null +++ b/xml/xml-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HtmlFileReferenceHelper.java @@ -0,0 +1,58 @@ +package com.intellij.codeInsight.daemon.impl.analysis; + +import com.intellij.ide.highlighter.HtmlFileType; +import com.intellij.ide.highlighter.XHtmlFileType; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleUtilCore; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiFileSystemItem; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceHelper; +import com.intellij.psi.xml.XmlFile; +import com.intellij.xml.util.HtmlUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + +/** + * @author Dennis.Ushakov + */ +public class HtmlFileReferenceHelper extends FileReferenceHelper { + @NotNull + @Override + public Collection getContexts(Project project, @NotNull VirtualFile vFile) { + final PsiFile file = PsiManager.getInstance(project).findFile(vFile); + final Module module = file != null ? ModuleUtilCore.findModuleForPsiElement(file) : null; + if (module == null || !(file instanceof XmlFile)) return Collections.emptyList(); + final String basePath = HtmlUtil.getHrefBase((XmlFile)file); + if (basePath != null && !HtmlUtil.hasHtmlPrefix(basePath)) { + for (VirtualFile virtualFile : getBaseRoots(module)) { + final VirtualFile base = virtualFile.findFileByRelativePath(basePath); + final PsiDirectory result = base != null ? PsiManager.getInstance(project).findDirectory(base) : null; + if (result != null) { + return Collections.singletonList(result); + } + } + } + return Collections.emptyList(); + } + + protected Collection getBaseRoots(final Module module) { + return Arrays.asList(ModuleRootManager.getInstance(module).getContentRoots()); + } + + @Override + public boolean isMine(Project project, @NotNull VirtualFile file) { + final FileType fileType = file.getFileType(); + return ProjectRootManager.getInstance(project).getFileIndex().isInContent(file) && + fileType == HtmlFileType.INSTANCE || fileType == XHtmlFileType.INSTANCE; + } +} diff --git a/xml/xml-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HtmlUnknownAnchorTargetInspection.java b/xml/xml-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HtmlUnknownAnchorTargetInspection.java index ced10ace50ae..2793d162fdfe 100644 --- a/xml/xml-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HtmlUnknownAnchorTargetInspection.java +++ b/xml/xml-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HtmlUnknownAnchorTargetInspection.java @@ -36,6 +36,6 @@ public class HtmlUnknownAnchorTargetInspection extends XmlPathReferenceInspectio @Override protected boolean needToCheckRef(PsiReference reference) { - return reference instanceof AnchorReference; + return reference instanceof AnchorReference && HtmlUnknownTargetInspection.notRemoteBase(reference); } } diff --git a/xml/xml-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HtmlUnknownTargetInspection.java b/xml/xml-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HtmlUnknownTargetInspection.java index c8b85f0946dd..3034e5bdc8ac 100644 --- a/xml/xml-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HtmlUnknownTargetInspection.java +++ b/xml/xml-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HtmlUnknownTargetInspection.java @@ -15,8 +15,11 @@ */ package com.intellij.codeInsight.daemon.impl.analysis; +import com.intellij.psi.PsiFile; import com.intellij.psi.PsiReference; +import com.intellij.psi.xml.XmlFile; import com.intellij.xml.util.AnchorReference; +import com.intellij.xml.util.HtmlUtil; import org.jetbrains.annotations.NotNull; /** @@ -36,6 +39,12 @@ public class HtmlUnknownTargetInspection extends XmlPathReferenceInspection { @Override protected boolean needToCheckRef(PsiReference reference) { - return !(reference instanceof AnchorReference); + return !(reference instanceof AnchorReference) && notRemoteBase(reference); + } + + static boolean notRemoteBase(PsiReference reference) { + final PsiFile file = reference.getElement().getContainingFile(); + final String basePath = file instanceof XmlFile ? HtmlUtil.getHrefBase((XmlFile)file) : null; + return basePath == null || !HtmlUtil.hasHtmlPrefix(basePath); } } diff --git a/xml/xml-psi-impl/src/com/intellij/xml/util/HtmlUtil.java b/xml/xml-psi-impl/src/com/intellij/xml/util/HtmlUtil.java index ac01d81a2f77..16fe99de28dd 100644 --- a/xml/xml-psi-impl/src/com/intellij/xml/util/HtmlUtil.java +++ b/xml/xml-psi-impl/src/com/intellij/xml/util/HtmlUtil.java @@ -415,6 +415,14 @@ public class HtmlUtil { return attributeName.startsWith(HTML5_DATA_ATTR_PREFIX); } + @Nullable + public static String getHrefBase(XmlFile file) { + final XmlTag root = file.getRootTag(); + final XmlTag head = root != null ? root.findFirstSubTag("head") : null; + final XmlTag base = head != null ? head.findFirstSubTag("base") : null; + return base != null ? base.getAttributeValue("href") : null; + } + private static class TerminateException extends RuntimeException { private static final TerminateException INSTANCE = new TerminateException(); }