mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-13 09:19:13 +07:00
IDEA-138063 Support HTML links with fragment references in quick doc
This commit is contained in:
@@ -252,10 +252,17 @@ public class JavaDocInfoGenerator {
|
||||
protected String convertReference(@NonNls String href) {
|
||||
final String originalReference = href;
|
||||
|
||||
String fragment = null;
|
||||
int hashPosition = href.indexOf('#');
|
||||
if (hashPosition >= 0) {
|
||||
fragment = href.substring(hashPosition + 1);
|
||||
href = href.substring(0, hashPosition);
|
||||
}
|
||||
if (href.isEmpty()) {
|
||||
PsiElement containingClass = myElement instanceof PsiMember ? ((PsiMember)myElement).getContainingClass() : null;
|
||||
PsiElement rootElement = containingClass == null ? myElement : containingClass;
|
||||
return createLinkWithRef(rootElement, fragment);
|
||||
}
|
||||
if (!href.toLowerCase().endsWith(".htm") && !href.toLowerCase().endsWith(".html")) {
|
||||
return originalReference;
|
||||
}
|
||||
@@ -286,7 +293,12 @@ public class JavaDocInfoGenerator {
|
||||
PsiClass target = JavaPsiFacade.getInstance(myProject).findClass(qualifiedName, myElement.getResolveScope());
|
||||
if (target == null) return originalReference;
|
||||
|
||||
return DocumentationManagerProtocol.PSI_ELEMENT_PROTOCOL + JavaDocUtil.getReferenceText(myProject, target);
|
||||
return createLinkWithRef(target, fragment);
|
||||
}
|
||||
|
||||
private String createLinkWithRef(PsiElement psiElement, String ref) {
|
||||
return DocumentationManagerProtocol.PSI_ELEMENT_PROTOCOL + JavaDocUtil.getReferenceText(myProject, psiElement) +
|
||||
(ref == null ? "" : DocumentationManagerProtocol.PSI_ELEMENT_PROTOCOL_REF_SEPARATOR + ref);
|
||||
}
|
||||
|
||||
public boolean generateDocInfoCore (final StringBuilder buffer, final boolean generatePrologueAndEpilogue) {
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<html><head><base href="placeholder"> <style type="text/css"> #error { background-color: #eeeeee; margin-bottom: 10px; } p { margin: 5px 0; } </style></head><body><PRE>class <b>Test</b>
|
||||
extends <a href="psi_element://java.lang.Object"><code>Object</code></a></PRE>
|
||||
<a name="section1">section one</a>
|
||||
text
|
||||
<a href="psi_element://Test###section1">link up</a></body></html>
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* <a name="section1">section one</a>
|
||||
* text
|
||||
* <a href="#section1">link up</a>
|
||||
*/
|
||||
class Test {}
|
||||
@@ -254,6 +254,10 @@ public class JavaDocInfoGeneratorTest extends CodeInsightTestCase {
|
||||
assertEquals(StringUtil.convertLineSeparators(new String(htmlFile.getVirtualFile().contentsToByteArray()).trim()),
|
||||
replaceEnvironmentDependentContent(doc));
|
||||
}
|
||||
|
||||
public void testHtmlLinkWithRef() throws Exception {
|
||||
verifyJavaDoc(getTestClass());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
|
||||
+6
@@ -27,6 +27,12 @@ public interface DocumentationManagerProtocol {
|
||||
* @see DocumentationManagerUtil
|
||||
*/
|
||||
@NonNls String PSI_ELEMENT_PROTOCOL = "psi_element://";
|
||||
|
||||
/**
|
||||
* Separator between PSI element link and a reference to specific text fragment, which should be scrolled to on navigation. Can be used
|
||||
* with {@link #PSI_ELEMENT_PROTOCOL} links, full link should look like {@code psi_element://link###ref}.
|
||||
*/
|
||||
@NonNls String PSI_ELEMENT_PROTOCOL_REF_SEPARATOR = "###";
|
||||
|
||||
/**
|
||||
* @deprecated Link with such prefix will open documentation for current element in browser, regardless of full link content. Http links
|
||||
|
||||
+13
-6
@@ -524,6 +524,10 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
|
||||
}
|
||||
|
||||
public void setData(PsiElement _element, String text, final boolean clearHistory, String effectiveExternalUrl) {
|
||||
setData(_element, text, clearHistory, effectiveExternalUrl, null);
|
||||
}
|
||||
|
||||
public void setData(PsiElement _element, String text, final boolean clearHistory, String effectiveExternalUrl, String ref) {
|
||||
myEffectiveExternalUrl = effectiveExternalUrl;
|
||||
if (myElement != null) {
|
||||
myBackStack.push(saveContext());
|
||||
@@ -540,16 +544,16 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
|
||||
|
||||
myIsEmpty = false;
|
||||
updateControlState();
|
||||
setDataInternal(element, text, new Rectangle(0, 0));
|
||||
setDataInternal(element, text, new Rectangle(0, 0), ref);
|
||||
|
||||
if (clearHistory) clearHistory();
|
||||
}
|
||||
|
||||
private void setDataInternal(SmartPsiElementPointer element, String text, final Rectangle viewRect) {
|
||||
setDataInternal(element, text, viewRect, false);
|
||||
private void setDataInternal(SmartPsiElementPointer element, String text, final Rectangle viewRect, String ref) {
|
||||
setDataInternal(element, text, viewRect, ref, false);
|
||||
}
|
||||
|
||||
private void setDataInternal(SmartPsiElementPointer element, String text, final Rectangle viewRect, boolean skip) {
|
||||
private void setDataInternal(SmartPsiElementPointer element, String text, final Rectangle viewRect, final String ref, boolean skip) {
|
||||
setElement(element);
|
||||
|
||||
myEditorPane.setText(text);
|
||||
@@ -568,7 +572,10 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myEditorPane.scrollRectToVisible(viewRect);
|
||||
myEditorPane.scrollRectToVisible(viewRect); // if ref is defined but is not found in document, this provides a default location
|
||||
if (ref != null) {
|
||||
myEditorPane.scrollToReference(ref);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -618,7 +625,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
|
||||
}
|
||||
|
||||
private void restoreContext(Context context) {
|
||||
setDataInternal(context.element, context.text, context.viewRect);
|
||||
setDataInternal(context.element, context.text, context.viewRect, null);
|
||||
if (myNavigateCallback != null) {
|
||||
final PsiElement element = context.element.getElement();
|
||||
if (element != null) {
|
||||
|
||||
+39
-3
@@ -641,6 +641,10 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
|
||||
return new DefaultDocumentationCollector(element, originalElement);
|
||||
}
|
||||
|
||||
private DocumentationCollector getDefaultCollector(@NotNull final PsiElement element, @Nullable final PsiElement originalElement, String ref) {
|
||||
return new DefaultDocumentationCollector(element, originalElement, ref);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JBPopup getDocInfoHint() {
|
||||
if (myDocInfoHintRef == null) return null;
|
||||
@@ -748,7 +752,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
|
||||
component.setText(component.getText(), element, true, clearHistory);
|
||||
}
|
||||
else {
|
||||
component.setData(element, documentationText, clearHistory, provider.getEffectiveExternalUrl());
|
||||
component.setData(element, documentationText, clearHistory, provider.getEffectiveExternalUrl(), provider.getRef());
|
||||
}
|
||||
|
||||
final AbstractPopup jbPopup = (AbstractPopup)getDocInfoHint();
|
||||
@@ -854,7 +858,13 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
|
||||
}
|
||||
}
|
||||
else if (url.startsWith(DocumentationManagerProtocol.PSI_ELEMENT_PROTOCOL)) {
|
||||
final String refText = url.substring(DocumentationManagerProtocol.PSI_ELEMENT_PROTOCOL.length());
|
||||
String refText = url.substring(DocumentationManagerProtocol.PSI_ELEMENT_PROTOCOL.length());
|
||||
int separatorPos = refText.lastIndexOf(DocumentationManagerProtocol.PSI_ELEMENT_PROTOCOL_REF_SEPARATOR);
|
||||
String ref = null;
|
||||
if (separatorPos >= 0) {
|
||||
ref = refText.substring(separatorPos + DocumentationManagerProtocol.PSI_ELEMENT_PROTOCOL_REF_SEPARATOR.length());
|
||||
refText = refText.substring(0, separatorPos);
|
||||
}
|
||||
DocumentationProvider provider = getProviderFromElement(psiElement);
|
||||
PsiElement targetElement = provider.getDocumentationElementForLink(manager, refText, psiElement);
|
||||
if (targetElement == null) {
|
||||
@@ -877,7 +887,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
|
||||
}
|
||||
}
|
||||
if (targetElement != null) {
|
||||
fetchDocInfo(getDefaultCollector(targetElement, null), component);
|
||||
fetchDocInfo(getDefaultCollector(targetElement, null, ref), component);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -905,6 +915,12 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
|
||||
public String getEffectiveExternalUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getRef() {
|
||||
return null;
|
||||
}
|
||||
}, component);
|
||||
processed = true;
|
||||
}
|
||||
@@ -958,6 +974,12 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
|
||||
public String getEffectiveExternalUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getRef() {
|
||||
return null;
|
||||
}
|
||||
}, component);
|
||||
}
|
||||
}
|
||||
@@ -1049,18 +1071,26 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
|
||||
PsiElement getElement();
|
||||
@Nullable
|
||||
String getEffectiveExternalUrl();
|
||||
@Nullable
|
||||
String getRef();
|
||||
}
|
||||
|
||||
private class DefaultDocumentationCollector implements DocumentationCollector {
|
||||
|
||||
private final PsiElement myElement;
|
||||
private final PsiElement myOriginalElement;
|
||||
private final String myRef;
|
||||
|
||||
private String myEffectiveUrl;
|
||||
|
||||
private DefaultDocumentationCollector(PsiElement element, PsiElement originalElement) {
|
||||
this(element, originalElement, null);
|
||||
}
|
||||
|
||||
private DefaultDocumentationCollector(PsiElement element, PsiElement originalElement, String ref) {
|
||||
myElement = element;
|
||||
myOriginalElement = originalElement;
|
||||
myRef = ref;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1122,5 +1152,11 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
|
||||
public String getEffectiveExternalUrl() {
|
||||
return myEffectiveUrl;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getRef() {
|
||||
return myRef;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user