mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-07 05:09:37 +07:00
IDEA-346213 QuickDoc: improve wrapping of long qualified names and URLs
GitOrigin-RevId: c808dd4c333636dc9dc36e01b3afa57f3037ec0c
This commit is contained in:
committed by
intellij-monorepo-bot
parent
8470728a07
commit
a028674bdb
@@ -15,8 +15,8 @@
|
||||
<!-- -->
|
||||
</a>
|
||||
<ul class="blockListLast">
|
||||
<h3><a href="psi_element://com.jetbrains.GenericClass"><code>com.jetbrains.GenericClass</code></a></h3>
|
||||
<pre>public void genericMethod(java.lang.Class<?> clazz)</pre>
|
||||
<h3><a href="psi_element://com.jetbrains.GenericClass"><code>com.<wbr>jetbrains.<wbr>GenericClass</code></a></h3>
|
||||
<pre>public void genericMethod(java.<wbr>lang.<wbr>Class<?> clazz)</pre>
|
||||
<div class="block">javadoc</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
</style><div class='content'><a name="m1--">
|
||||
<!-- -->
|
||||
</a>
|
||||
<h3><a href="psi_element://com.jetbrains.LinkBetweenMethods"><code>com.jetbrains.LinkBetweenMethods</code></a></h3>
|
||||
<h3><a href="psi_element://com.jetbrains.LinkBetweenMethods"><code>com.<wbr>jetbrains.<wbr>LinkBetweenMethods</code></a></h3>
|
||||
<pre>public void m1()</pre>
|
||||
<div class="block"><a href="psi_element://com.jetbrains.LinkBetweenMethods#m2()"><code>m2()</code></a></div>
|
||||
</li>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
}
|
||||
</style><div class='content'><!-- ======== START OF CLASS DATA ======== -->
|
||||
<div class="header">
|
||||
<div class="subTitle">com.jetbrains</div>
|
||||
<div class="subTitle">com.<wbr>jetbrains</div>
|
||||
<h2 title="Interface SimpleInterface" class="title">Interface SimpleInterface</h2>
|
||||
</div>
|
||||
<div class="contentContainer">
|
||||
|
||||
@@ -13,21 +13,21 @@
|
||||
}
|
||||
</style><div class='content'><!-- ======== START OF CLASS DATA ======== -->
|
||||
<div class="header">
|
||||
<div class="subTitle">com.jetbrains</div>
|
||||
<div class="subTitle">com.<wbr>jetbrains</div>
|
||||
<h2 title="Class ClassWithRefLink" class="title">Class ClassWithRefLink</h2>
|
||||
</div>
|
||||
<div class="contentContainer">
|
||||
<ul class="inheritance">
|
||||
<li>java.lang.Object</li>
|
||||
<li>java.<wbr>lang.<wbr>Object</li>
|
||||
<li>
|
||||
<ul class="inheritance">
|
||||
<li>com.jetbrains.ClassWithRefLink</li>
|
||||
<li>com.<wbr>jetbrains.<wbr>ClassWithRefLink</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<DL><br>
|
||||
<pre>public class <span class="typeNameLabel">ClassWithRefLink</span>
|
||||
extends java.lang.Object</pre>
|
||||
extends java.<wbr>lang.<wbr>Object</pre>
|
||||
<div class="block"><a href="psi_element://com.jetbrains.Test###someRef">link</a></div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
<!-- -->
|
||||
</a>
|
||||
<ul class="blockListLast">
|
||||
<h3><a href="psi_element://com.jetbrains.TestAnnotation"><code>com.jetbrains.TestAnnotation</code></a></h3>
|
||||
<pre>public abstract java.lang.String param</pre>
|
||||
<h3><a href="psi_element://com.jetbrains.TestAnnotation"><code>com.<wbr>jetbrains.<wbr>TestAnnotation</code></a></h3>
|
||||
<pre>public abstract java.<wbr>lang.<wbr>String param</pre>
|
||||
<div class="block">Some info and a <a href="psi_element://com.jetbrains.Test">link</a></div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<html><head><base href="placeholder"></head><body><div class="bottom"><icon src="AllIcons.Nodes.Class"> <a href="psi_element://java.util.List"><code><span style="color:#000000;">java.util.List</span><span style=""><</span><span style="color:#20999d;">E</span><span style="">></span></code></a></div><div class='definition-separated'><pre><span style="color:#808000;">@</span><span style="color:#808000;">Contract</span><span style="">(</span><span style="">pure</span><span style=""> = </span><span style="color:#000080;font-weight:bold;">true</span><span style="">)</span><a href="external.annotations"><icon src="AllIcons.Ide.External_link_arrow"></a>
|
||||
<html><head><base href="placeholder"></head><body><div class="bottom"><icon src="AllIcons.Nodes.Class"> <a href="psi_element://java.util.List"><code><span style="color:#000000;">java.<wbr>util.<wbr>List</span><span style=""><</span><span style="color:#20999d;">E</span><span style="">></span></code></a></div><div class='definition-separated'><pre><span style="color:#808000;">@</span><span style="color:#808000;">Contract</span><span style="">(</span><span style="">pure</span><span style=""> = </span><span style="color:#000080;font-weight:bold;">true</span><span style="">)</span><a href="external.annotations"><icon src="AllIcons.Ide.External_link_arrow"></a>
|
||||
<span style="color:#000080;font-weight:bold;">public abstract</span> <span style="color:#000080;font-weight:bold;">boolean</span> <span style="color:#000000;">contains</span><span style="">(</span><br> <a href="psi_element://java.lang.Object"><code><span style="color:#000000;">Object</span></code></a> <span style="color:#000000;">o</span><br><span style="">)</span></pre></div><div class='content'>
|
||||
<p>Returns <tt>true</tt> if this list contains the specified element.
|
||||
More formally, returns <tt>true</tt> if and only if this list contains
|
||||
at least one element <tt>e</tt> such that
|
||||
<tt>(o==null ? e==null : o.equals(e))</tt>.
|
||||
<tt>(o==null ? e==null : o.<wbr>equals(e))</tt>.
|
||||
|
||||
</div><table class='sections'><tr><td valign='top' class='section'><p>Overrides:</td><td valign='top'><p><a href="psi_element://java.util.Collection#contains(java.lang.Object)"><code><span style="color:#000000;">contains</span></code></a> in interface <a href="psi_element://java.util.Collection"><code><span style="color:#000000;">Collection</span></code></a></td><tr><td valign='top' class='section'><p>Params:</td><td valign='top'><code><span style="color:#000000;">o</span></code> – element whose presence in this list is to be tested </td><tr><td valign='top' class='section'><p>Returns:</td><td valign='top'><p><tt>true</tt> if this list contains the specified element </td><tr><td valign='top' class='section'><p>Throws:</td><td valign='top'><p><a href="psi_element://java.lang.ClassCastException"><code><span style="color:#0000ff;">ClassCastException</span></code></a> – if the type of the specified element is incompatible with this list (<a href="psi_element://java.util.Collection###optional-restrictions">optional</a>) <p><a href="psi_element://java.lang.NullPointerException"><code><span style="color:#0000ff;">NullPointerException</span></code></a> – if the specified element is null and this list does not permit null elements (<a href="psi_element://java.util.Collection###optional-restrictions">optional</a>)</td></table><div class="bottom"><icon src="AllIcons.Nodes.PpLibFolder"/> < java 1.7 ></div>
|
||||
@@ -1,9 +1,9 @@
|
||||
<html><head><base href="placeholder"></head><body><div class="bottom"><icon src="AllIcons.Nodes.Class"> <a href="psi_element://My"><code><span style="color:#000000;">My</span></code></a></div><div class='definition-separated'><pre><i><span style="color:#808000;">@</span><a href="psi_element://org.jetbrains.annotations.Contract"><code><span style="color:#808000;">Contract</span></code></a><span style="">(</span><span style="">pure</span><span style=""> = </span><span style="color:#000080;font-weight:bold;">true</span><span style="">)</span></i><sup><font color="808080" size="3"><i>i</i></font></sup><a href="inferred.annotations"><icon src="AllIcons.Ide.External_link_arrow"></a>
|
||||
<span style="color:#000080;font-weight:bold;">boolean</span> <span style="color:#000000;">contains</span><span style="">(</span><br> <a href="psi_element://java.lang.Object"><code><span style="color:#000000;">Object</span></code></a> <span style="color:#000000;">o</span><br><span style="">)</span>
|
||||
<span style="color:#000080;font-weight:bold;">throws</span> <span style="color:#ff0000">IOException</span></pre></div><table class='sections'><tr><td valign='top' class='section'><p>From interface:</td><td valign='top'><p><a href="psi_element://java.util.Collection"><code><span style="color:#000000;">java.util.Collection</span></code></a><br>
|
||||
<span style="color:#000080;font-weight:bold;">throws</span> <span style="color:#ff0000">IOException</span></pre></div><table class='sections'><tr><td valign='top' class='section'><p>From interface:</td><td valign='top'><p><a href="psi_element://java.util.Collection"><code><span style="color:#000000;">java.<wbr>util.<wbr>Collection</span></code></a><br>
|
||||
Returns <tt>true</tt> if this collection contains the specified element.
|
||||
More formally, returns <tt>true</tt> if and only if this collection
|
||||
contains at least one element <tt>e</tt> such that
|
||||
<tt>(o==null ? e==null : o.equals(e))</tt>.
|
||||
<tt>(o==null ? e==null : o.<wbr>equals(e))</tt>.
|
||||
|
||||
</td><tr><td valign='top' class='section'><p>Overrides:</td><td valign='top'><p><a href="psi_element://java.util.Collection#contains(java.lang.Object)"><code><span style="color:#000000;">contains</span></code></a> in interface <a href="psi_element://java.util.Collection"><code><span style="color:#000000;">Collection</span></code></a><br><a href="psi_element://I#contains(java.lang.Object)"><code><span style="color:#000000;">contains</span></code></a> in interface <a href="psi_element://I"><code><span style="color:#000000;">I</span></code></a></td><tr><td valign='top' class='section'><p>Params:</td><td valign='top'><code><span style="color:#000000;">o</span></code> – element whose presence in this collection is to be tested </td><tr><td valign='top' class='section'><p>Returns:</td><td valign='top'><p><tt>true</tt> if this collection contains the specified element </td><tr><td valign='top' class='section'><p>Throws:</td><td valign='top'><p><a href="psi_element://java.lang.NullPointerException"><code><span style="color:#0000ff;">NullPointerException</span></code></a> – before if the specified element is null and this collection does not permit null elements (<a href="psi_element://My###optional-restrictions">optional</a>) after<p><span style="color:#ff0000">IOException</span></td></table>
|
||||
@@ -1,4 +1,4 @@
|
||||
<html><head><base href="placeholder"></head><body><div class='definition-separated'><pre><span style="color:#000080;font-weight:bold;">class</span> <span style="color:#000000;">C</span></pre></div><div class='content'>
|
||||
<p>some text
|
||||
|
||||
</div><table class='sections'><tr><td valign='top' class='section'><p>See Also:</td><td valign='top'><p>System.out</td></table>
|
||||
</div><table class='sections'><tr><td valign='top' class='section'><p>See Also:</td><td valign='top'><p>System.<wbr>out</td></table>
|
||||
@@ -1,3 +1,3 @@
|
||||
<div class="bottom"><icon src="AllIcons.Nodes.Package"> <code>packageInfoWithCopyright</code></div><div class='content'>
|
||||
<p>This package contains nothing but package-info.java
|
||||
<p>This package contains nothing but package-info.<wbr>java
|
||||
</div>
|
||||
@@ -1,5 +1,5 @@
|
||||
<html><head><base href="placeholder"></head><body><div class="bottom"><icon src="AllIcons.Nodes.Class"> <a href="psi_element://java.lang.Class"><code><span style="color:#000000;">java.lang.Class</span><span style=""><</span><span style="color:#20999d;">T</span><span style="">></span></code></a></div><div class='definition-separated'><pre><span style="color:#ff0000">@<span style="color:#808000;">CallerSensitive</span></span>
|
||||
<html><head><base href="placeholder"></head><body><div class="bottom"><icon src="AllIcons.Nodes.Class"> <a href="psi_element://java.lang.Class"><code><span style="color:#000000;">java.<wbr>lang.<wbr>Class</span><span style=""><</span><span style="color:#20999d;">T</span><span style="">></span></code></a></div><div class='definition-separated'><pre><span style="color:#ff0000">@<span style="color:#808000;">CallerSensitive</span></span>
|
||||
<span style="color:#808000;">@</span><span style="color:#808000;">NotNull</span><a href="external.annotations"><icon src="AllIcons.Ide.External_link_arrow"></a>
|
||||
<span style="color:#808000;">@</span><span style="color:#808000;">Contract</span><span style="">(</span><span style="">pure</span><span style=""> = </span><span style="color:#000080;font-weight:bold;">true</span><span style="">)</span><a href="external.annotations"><icon src="AllIcons.Ide.External_link_arrow"></a>
|
||||
<span style="color:#000080;font-weight:bold;">public</span> <a href="psi_element://java.lang.reflect.Constructor"><code><span style="color:#000000;">java.lang.reflect.Constructor</span></code></a><span style=""><</span><span style="">?</span><span style="">></span><span style="">[]</span> <span style="color:#000000;">getDeclaredConstructors</span><span style="">(</span><span style="">)</span>
|
||||
<span style="color:#000080;font-weight:bold;">public</span> <a href="psi_element://java.lang.reflect.Constructor"><code><span style="color:#000000;">java.<wbr>lang.<wbr>reflect.<wbr>Constructor</span></code></a><span style=""><</span><span style="">?</span><span style="">></span><span style="">[]</span> <span style="color:#000000;">getDeclaredConstructors</span><span style="">(</span><span style="">)</span>
|
||||
<span style="color:#000080;font-weight:bold;">throws</span> <a href="psi_element://java.lang.SecurityException"><code><span style="color:#000000;">SecurityException</span></code></a></pre></div><table class='sections'><tr><td valign='top' class='section'><p>Throws:</td><td valign='top'><p><a href="psi_element://java.lang.SecurityException"><code><span style="color:#0000ff;">SecurityException</span></code></a></td></table><div class="bottom"><icon src="AllIcons.Nodes.PpLibFolder"/> < java 10 ></div>
|
||||
@@ -4,8 +4,8 @@
|
||||
type, in the order they're declared. This method may be
|
||||
used to iterate over the constants as follows:
|
||||
<pre>
|
||||
for(E c : E.values())
|
||||
System.out.println(c);
|
||||
for(E c : E.<wbr>values())
|
||||
System.<wbr>out.<wbr>println(c);
|
||||
</pre>
|
||||
|
||||
</div><table class='sections'><tr><td valign='top' class='section'><p>Returns:</td><td valign='top'><p>an array containing the constants of this enum type, in the order they're declared</td></table>
|
||||
@@ -289,7 +289,7 @@ class JavaDocumentationTest : LightJavaCodeInsightFixtureTestCase() {
|
||||
|
||||
val actual = JavaExternalDocumentationTest.getDocumentationText(myFixture.project, input)
|
||||
|
||||
val expected = "<html><div class='content'>Candidates for method call <b>s.regionMatches()</b> are:<br>" +
|
||||
val expected = "<html><div class='content'>Candidates for method call <b>s.<wbr>regionMatches()</b> are:<br>" +
|
||||
"<br>" +
|
||||
" <a href=\"psi_element://java.lang.String#regionMatches(int, java.lang.String, int, int)\">boolean regionMatches(int, String, int, int)</a><br>" +
|
||||
" <a href=\"psi_element://java.lang.String#regionMatches(boolean, int, java.lang.String, int, int)\">boolean regionMatches(boolean, int, String, int, int)</a><br>" +
|
||||
@@ -309,7 +309,7 @@ class JavaDocumentationTest : LightJavaCodeInsightFixtureTestCase() {
|
||||
|
||||
val documentationManager = DocumentationManager.getInstance(myFixture.project)
|
||||
JavaExternalDocumentationTest.getDocumentationText(myFixture.project, input) { component ->
|
||||
val expected = "<html><div class='content'>Candidates for method call <b>s.regionMatches()</b> are:<br>" +
|
||||
val expected = "<html><div class='content'>Candidates for method call <b>s.<wbr>regionMatches()</b> are:<br>" +
|
||||
"<br>" +
|
||||
" <a href=\"psi_element://java.lang.String#regionMatches(int, java.lang.String, int, int)\">boolean regionMatches(int, String, int, int)</a><br>" +
|
||||
" <a href=\"psi_element://java.lang.String#regionMatches(boolean, int, java.lang.String, int, int)\">boolean regionMatches(boolean, int, String, int, int)</a><br>" +
|
||||
|
||||
@@ -81,10 +81,11 @@ public abstract class DocumentationEditorPane extends JEditorPane implements Dis
|
||||
}
|
||||
setBackground(BACKGROUND_COLOR);
|
||||
HTMLEditorKit editorKit = new HTMLEditorKitBuilder()
|
||||
.replaceViewFactoryExtensions(DocumentationHtmlUtil.getIconsExtension(iconResolver),
|
||||
.replaceViewFactoryExtensions(getIconsExtension(iconResolver),
|
||||
Extensions.BASE64_IMAGES,
|
||||
Extensions.INLINE_VIEW_EX,
|
||||
Extensions.FIT_TO_WIDTH_IMAGES)
|
||||
Extensions.FIT_TO_WIDTH_IMAGES,
|
||||
Extensions.WBR_SUPPORT)
|
||||
.withFontResolver(EditorCssFontResolver.getGlobalInstance()).build();
|
||||
updateDocumentationPaneDefaultCssRules(editorKit);
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import com.intellij.util.ui.JBUI
|
||||
import com.intellij.util.ui.UIUtil
|
||||
import org.intellij.lang.annotations.Language
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import org.jetbrains.annotations.Contract
|
||||
import java.awt.Color
|
||||
import java.util.function.Function
|
||||
import javax.swing.Icon
|
||||
@@ -79,6 +80,7 @@ object DocumentationHtmlUtil {
|
||||
val contentSpacing = scale(contentSpacing)
|
||||
val contentInnerPadding = scale(contentInnerPadding)
|
||||
|
||||
@Suppress("CssUnusedSymbol")
|
||||
@Language("CSS")
|
||||
val result = ContainerUtil.newLinkedList(
|
||||
"""
|
||||
@@ -116,4 +118,115 @@ object DocumentationHtmlUtil {
|
||||
result.addAll(getDefaultFormattingStyles(contentSpacing))
|
||||
return result
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@Contract(pure = true)
|
||||
fun addWordBreaks(text: String): String {
|
||||
val codePoints = text.codePoints().iterator()
|
||||
if (!codePoints.hasNext()) return ""
|
||||
val result = StringBuilder(text.length + 50)
|
||||
var codePoint = codePoints.nextInt()
|
||||
val tagName = StringBuilder()
|
||||
|
||||
fun next(builder: StringBuilder = result) {
|
||||
builder.appendCodePoint(codePoint)
|
||||
codePoint = if (codePoints.hasNext())
|
||||
codePoints.nextInt()
|
||||
else
|
||||
-1
|
||||
}
|
||||
|
||||
while (codePoint >= 0) {
|
||||
// break after dot if surrounded by letters
|
||||
when {
|
||||
Character.isLetter(codePoint) -> {
|
||||
next()
|
||||
if (codePoint == '.'.code) {
|
||||
next()
|
||||
if (Character.isLetter(codePoint)) {
|
||||
result.append("<wbr>")
|
||||
}
|
||||
}
|
||||
}
|
||||
// break after ], ) or / followed by a char or digit
|
||||
codePoint == ')'.code || codePoint == ']'.code || codePoint == '/'.code -> {
|
||||
next()
|
||||
if (Character.isLetterOrDigit(codePoint)) {
|
||||
result.append("<wbr>")
|
||||
}
|
||||
}
|
||||
// skip tag
|
||||
codePoint == '<'.code -> {
|
||||
next()
|
||||
if (codePoint == '/'.code)
|
||||
next()
|
||||
if (!Character.isLetter(codePoint))
|
||||
continue
|
||||
tagName.clear()
|
||||
while (Character.isLetterOrDigit(codePoint) || codePoint == '-'.code) {
|
||||
next(tagName)
|
||||
}
|
||||
result.append(tagName)
|
||||
if (tagName.contentEquals("style", true)
|
||||
|| tagName.contentEquals("title", true)
|
||||
|| tagName.contentEquals("script", true)) {
|
||||
val curTag = tagName.toString()
|
||||
do {
|
||||
if (codePoint == '<'.code) {
|
||||
next()
|
||||
if (codePoint == '/'.code) {
|
||||
next()
|
||||
tagName.clear()
|
||||
while (Character.isLetterOrDigit(codePoint) || codePoint == '-'.code) {
|
||||
next(tagName)
|
||||
}
|
||||
result.append(tagName)
|
||||
if (tagName.contentEquals(curTag, true)) {
|
||||
while (codePoint >= 0 && codePoint != '>'.code) {
|
||||
next()
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
else next()
|
||||
}
|
||||
while (true)
|
||||
}
|
||||
else {
|
||||
while (codePoint >= 0) {
|
||||
when (codePoint) {
|
||||
'>'.code -> {
|
||||
next()
|
||||
break
|
||||
}
|
||||
'\''.code, '"'.code -> {
|
||||
val quoteStyle = codePoint
|
||||
next()
|
||||
while (codePoint >= 0) {
|
||||
when (codePoint) {
|
||||
'\\'.code -> {
|
||||
next()
|
||||
if (codePoint >= 0)
|
||||
next()
|
||||
}
|
||||
quoteStyle -> {
|
||||
next()
|
||||
break
|
||||
}
|
||||
else -> next()
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> next()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> next()
|
||||
}
|
||||
}
|
||||
|
||||
return result.toString()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,6 +112,7 @@ import static com.intellij.lang.documentation.DocumentationMarkup.*;
|
||||
*
|
||||
* @deprecated Unused in v2 implementation. Unsupported: use at own risk.
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
@Deprecated(forRemoval = true)
|
||||
public class DocumentationManager extends DockablePopupManager<DocumentationComponent> {
|
||||
public static final String JAVADOC_LOCATION_AND_SIZE = "javadoc.popup";
|
||||
@@ -1942,6 +1943,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
|
||||
}
|
||||
//noinspection HardCodedStringLiteral
|
||||
if (!text.startsWith("<p", nextChar) && !text.startsWith("<div", nextChar)) {
|
||||
//noinspection HardCodedStringLiteral
|
||||
text = text.substring(0, nextChar) + "<p>" + text.substring(nextChar);
|
||||
}
|
||||
}
|
||||
@@ -1970,6 +1972,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
|
||||
//workaround for Swing html renderer not removing empty paragraphs before non-inline tags
|
||||
text = text.replaceAll("<p>\\s*(<(?:[uo]l|h\\d|p|tr|td))", "$1");
|
||||
text = addExternalLinksIcon(text);
|
||||
text = DocumentationHtmlUtil.addWordBreaks(text);
|
||||
return text;
|
||||
}
|
||||
|
||||
|
||||
@@ -289,7 +289,6 @@ object QuickDocHighlightingHelper {
|
||||
"li { padding: ${scale(1)}px 0 ${scale(2)}px 0; }",
|
||||
"li p { padding-top: 0; padding-bottom: 0; }",
|
||||
"th { text-align: left; }",
|
||||
"table { width: 100%}",
|
||||
"tr, table { margin: 0 0 0 0; padding: 0 0 0 0; }",
|
||||
"td { margin: 0 0 0 0; padding: 0 0 ${spacing}px 0; }",
|
||||
"td p { padding-top: 0; padding-bottom: 0; }",
|
||||
|
||||
@@ -79,6 +79,8 @@ object StyleSheetRulesProviderForCodeHighlighting {
|
||||
if (enableInlineCodeBackground) {
|
||||
val selectors = inlineCodeParentSelectors.asSequence().map { "$it code" }.joinToString(", ")
|
||||
result.add("$selectors $codeColorStyle")
|
||||
// 'caption-side' is a hack to support 'border-radius'.
|
||||
// See also: com.intellij.util.ui.html.InlineViewEx
|
||||
result.add("$selectors { padding: 1px 4px; margin: 1px 0px; caption-side: 10px; }")
|
||||
}
|
||||
if (enableCodeBlocksBackground) {
|
||||
|
||||
@@ -6,9 +6,10 @@ import com.intellij.openapi.util.IconLoader
|
||||
import com.intellij.openapi.util.text.HtmlChunk
|
||||
import com.intellij.ui.scale.JBUIScale
|
||||
import com.intellij.util.text.nullize
|
||||
import com.intellij.util.ui.html.FitToWidthImageView
|
||||
import com.intellij.util.ui.html.HiDpiScalingImageView
|
||||
import com.intellij.util.ui.html.InlineViewEx
|
||||
import com.intellij.util.ui.html.FitToWidthImageView
|
||||
import com.intellij.util.ui.html.WbrView
|
||||
import java.awt.*
|
||||
import java.awt.image.BufferedImage
|
||||
import java.io.ByteArrayInputStream
|
||||
@@ -48,7 +49,7 @@ class ExtendableHTMLViewFactory internal constructor(
|
||||
companion object {
|
||||
@JvmField
|
||||
val DEFAULT_EXTENSIONS: List<Extension> = listOf(Extensions.ICONS, Extensions.BASE64_IMAGES, Extensions.HIDPI_IMAGES,
|
||||
Extensions.INLINE_VIEW_EX)
|
||||
Extensions.INLINE_VIEW_EX, Extensions.WBR_SUPPORT)
|
||||
|
||||
@JvmField
|
||||
val DEFAULT: ExtendableHTMLViewFactory = ExtendableHTMLViewFactory(DEFAULT_EXTENSIONS)
|
||||
@@ -134,6 +135,12 @@ class ExtendableHTMLViewFactory internal constructor(
|
||||
@JvmField
|
||||
val FIT_TO_WIDTH_IMAGES: Extension = FitToWidthImageViewExtension()
|
||||
|
||||
/**
|
||||
* Adds support for `<wbr>` tags
|
||||
*/
|
||||
@JvmField
|
||||
val WBR_SUPPORT: Extension = WbrSupportExtension()
|
||||
|
||||
private class IconsExtension(private val existingIconsProvider: (key: String) -> Icon?) : Extension {
|
||||
|
||||
constructor(preloadedIcons: Map<String, Icon>) : this(preloadedIconsProvider(preloadedIcons))
|
||||
@@ -385,6 +392,14 @@ class ExtendableHTMLViewFactory internal constructor(
|
||||
override fun invoke(element: Element, view: View): View? =
|
||||
if (view is ImageView) FitToWidthImageView(element) else null
|
||||
}
|
||||
|
||||
private class WbrSupportExtension : Extension {
|
||||
override fun invoke(elem: Element, defaultView: View): View? =
|
||||
if (elem.name.equals("wbr", true))
|
||||
WbrView(elem)
|
||||
else
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
private class HiDpiImagesExtension : ExtendableHTMLViewFactory.Extension {
|
||||
|
||||
@@ -46,20 +46,6 @@ internal class InlineViewEx(elem: Element) : InlineView(elem) {
|
||||
override fun setPropertiesFromAttributes() {
|
||||
super.setPropertiesFromAttributes()
|
||||
|
||||
val parentView = parent
|
||||
val index = (0..parentView.viewCount).firstOrNull { parentView.getView(it) === this } ?: -1
|
||||
|
||||
|
||||
// Heuristics to determine whether we are within the same inline (e.g. <span>) element with paddings.
|
||||
// Nested inline element insets are not supported, because hierarchy of inline elements is not preserved.
|
||||
val prevSibling = if (index > 0) parentView.getView(index - 1) else null
|
||||
val nextSibling = if (index < parentView.viewCount - 1) parentView.getView(index + 1) else null
|
||||
|
||||
padding = this.cssPadding
|
||||
margin = this.cssMargin
|
||||
|
||||
startView = prevSibling?.cssPadding != padding || prevSibling.cssMargin != margin
|
||||
endView = nextSibling?.cssPadding != padding || nextSibling.cssMargin != margin
|
||||
|
||||
// "caption-side" is used as "border-radius"
|
||||
borderRadius = attributes.getAttribute(CAPTION_SIDE)
|
||||
@@ -69,27 +55,7 @@ internal class InlineViewEx(elem: Element) : InlineView(elem) {
|
||||
?.toIntOrNull()
|
||||
?.let { JBUI.scale(it) }
|
||||
?: 0
|
||||
|
||||
padding.set(
|
||||
padding.top,
|
||||
if (startView) padding.left else 0,
|
||||
padding.bottom,
|
||||
if (endView) padding.right else 0,
|
||||
)
|
||||
|
||||
margin.set(
|
||||
margin.top,
|
||||
if (startView) margin.left else 0,
|
||||
margin.bottom,
|
||||
if (endView) margin.right else 0,
|
||||
)
|
||||
|
||||
insets = JBInsets(
|
||||
padding.top + margin.top,
|
||||
padding.left + margin.left,
|
||||
padding.bottom + margin.bottom,
|
||||
padding.right + margin.right,
|
||||
)
|
||||
updatePaddingsAndMargins(true)
|
||||
}
|
||||
|
||||
override fun getPartialSpan(p0: Int, p1: Int): Float {
|
||||
@@ -103,12 +69,14 @@ internal class InlineViewEx(elem: Element) : InlineView(elem) {
|
||||
return offset + super.getPartialSpan(p0, p1)
|
||||
}
|
||||
|
||||
override fun getPreferredSpan(axis: Int): Float =
|
||||
super.getPreferredSpan(axis) + when (axis) {
|
||||
override fun getPreferredSpan(axis: Int): Float {
|
||||
updatePaddingsAndMargins(false)
|
||||
return super.getPreferredSpan(axis) + when (axis) {
|
||||
View.X_AXIS -> insets.width()
|
||||
View.Y_AXIS -> insets.height()
|
||||
else -> throw IllegalArgumentException("Invalid axis: $axis")
|
||||
}
|
||||
}
|
||||
|
||||
override fun getTabbedSpan(x: Float, e: TabExpander?): Float =
|
||||
super.getTabbedSpan(x, e) + insets.width()
|
||||
@@ -173,4 +141,59 @@ internal class InlineViewEx(elem: Element) : InlineView(elem) {
|
||||
return super.getAlignment(axis)
|
||||
}
|
||||
|
||||
private fun getSibling(parentView: View, curIndex: Int, direction: Int): View? {
|
||||
var siblingIndex = curIndex + direction
|
||||
val viewCount = parentView.viewCount
|
||||
while (siblingIndex in 0..<viewCount) {
|
||||
parentView.getView(siblingIndex)
|
||||
.takeIf { it.element?.name?.equals("wbr", true) != true }
|
||||
?.let { return it }
|
||||
siblingIndex += direction
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun updatePaddingsAndMargins(force: Boolean) {
|
||||
val parentView = parent
|
||||
val index = (0..<parentView.viewCount).firstOrNull { parentView.getView(it) === this } ?: -1
|
||||
|
||||
// Heuristics to determine whether we are within the same inline (e.g. <span>) element with paddings.
|
||||
// Nested inline element insets are not supported, because hierarchy of inline elements is not preserved.
|
||||
val prevSibling = getSibling(parentView, index, -1)
|
||||
val nextSibling = getSibling(parentView, index, 1)
|
||||
|
||||
val cssPadding = this.cssPadding
|
||||
val cssMargin = this.cssMargin
|
||||
|
||||
val startView = prevSibling?.cssPadding != cssPadding || prevSibling.cssMargin != cssMargin
|
||||
val endView = nextSibling?.cssPadding != cssPadding || nextSibling.cssMargin != cssMargin
|
||||
|
||||
if (!force && startView == this.startView && endView == this.endView) {
|
||||
return
|
||||
}
|
||||
this.startView = startView
|
||||
this.endView = endView
|
||||
|
||||
padding = JBInsets(
|
||||
cssPadding.top,
|
||||
if (startView) cssPadding.left else 0,
|
||||
cssPadding.bottom,
|
||||
if (endView) cssPadding.right else 0,
|
||||
)
|
||||
|
||||
margin = JBInsets(
|
||||
cssMargin.top,
|
||||
if (startView) cssMargin.left else 0,
|
||||
cssMargin.bottom,
|
||||
if (endView) cssMargin.right else 0,
|
||||
)
|
||||
|
||||
insets = JBInsets(
|
||||
padding.top + margin.top,
|
||||
padding.left + margin.left,
|
||||
padding.bottom + margin.bottom,
|
||||
padding.right + margin.right,
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
38
platform/util/ui/src/com/intellij/util/ui/html/WbrView.kt
Normal file
38
platform/util/ui/src/com/intellij/util/ui/html/WbrView.kt
Normal file
@@ -0,0 +1,38 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.util.ui.html
|
||||
|
||||
import java.awt.Shape
|
||||
import javax.swing.text.Element
|
||||
import javax.swing.text.Position
|
||||
import javax.swing.text.Segment
|
||||
import javax.swing.text.View
|
||||
import javax.swing.text.html.InlineView
|
||||
|
||||
class WbrView(elem: Element) : InlineView(elem) {
|
||||
|
||||
override fun getMinimumSpan(axis: Int): Float = 0f
|
||||
|
||||
override fun getMaximumSpan(axis: Int): Float =
|
||||
if (axis == View.X_AXIS)
|
||||
0f
|
||||
else
|
||||
Int.MAX_VALUE.toFloat()
|
||||
|
||||
override fun getViewIndex(pos: Int, b: Position.Bias?): Int = -1
|
||||
|
||||
override fun getViewIndex(x: Float, y: Float, allocation: Shape?): Int = -1
|
||||
|
||||
override fun getResizeWeight(axis: Int): Int = 0
|
||||
|
||||
override fun setSize(width: Float, height: Float) {
|
||||
super.setSize(0f, 0f)
|
||||
}
|
||||
|
||||
override fun getPreferredSpan(axis: Int): Float = 0f
|
||||
|
||||
override fun getText(p0: Int, p1: Int): Segment = Segment()
|
||||
|
||||
override fun breakView(axis: Int, offset: Int, pos: Float, len: Float): View = this
|
||||
|
||||
override fun getBreakWeight(axis: Int, pos: Float, len: Float): Int = ExcellentBreakWeight
|
||||
}
|
||||
Reference in New Issue
Block a user