base tag support:

file reference helper for local paths
silence inspections for urls
#WEB-497 fixed
This commit is contained in:
Dennis Ushakov
2013-11-02 01:25:05 +04:00
parent dc5c46f857
commit bbc6dbb0c6
5 changed files with 78 additions and 2 deletions
@@ -299,6 +299,7 @@
<psi.referenceContributor implementation="com.intellij.xml.util.XmlReferenceContributor"/>
<!--<pom.declarationSearcher implementation="com.intellij.psi.impl.source.resolve.reference.impl.providers.IdDeclarationSearcher"/>-->
<anchorReferenceProvider implementation="com.intellij.xml.util.AnchorPathReferenceProvider"/>
<psi.fileReferenceHelper implementation="com.intellij.codeInsight.daemon.impl.analysis.HtmlFileReferenceHelper"/>
<extendWordSelectionHandler implementation="com.intellij.codeInsight.editorActions.HtmlSelectioner"/>
<extendWordSelectionHandler implementation="com.intellij.codeInsight.editorActions.XmlTagSelectioner"/>
@@ -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<PsiFileSystemItem> 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.<PsiFileSystemItem>singletonList(result);
}
}
}
return Collections.emptyList();
}
protected Collection<VirtualFile> 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;
}
}
@@ -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);
}
}
@@ -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);
}
}
@@ -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();
}