mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 15:19:59 +07:00
[ui] fix loading plugin icons in html view (IJPL-43721)
Co-authored-by: Victor Turansky <victor.turansky@jetbrains.com> Merge-request: IJ-MR-126946 Merged-by: Victor Turansky <victor.turansky@jetbrains.com> GitOrigin-RevId: 11aa1c46f9348b3c4713ff5f35bec6abdce0e642
This commit is contained in:
committed by
intellij-monorepo-bot
parent
0c1287808f
commit
d58d166cd4
@@ -8,6 +8,7 @@ import com.intellij.AbstractBundle
|
||||
import com.intellij.DynamicBundle
|
||||
import com.intellij.icons.AllIcons
|
||||
import com.intellij.ide.IconLayerProvider
|
||||
import com.intellij.ide.plugins.PluginManager
|
||||
import com.intellij.ide.plugins.PluginManagerCore
|
||||
import com.intellij.ide.plugins.cl.PluginAwareClassLoader
|
||||
import com.intellij.openapi.diagnostic.logger
|
||||
@@ -257,6 +258,12 @@ class CoreIconManager : IconManager, CoreAwareIconManager {
|
||||
return plugin.content.modules.firstOrNull { it.name == moduleId }?.requireDescriptor()?.classLoader
|
||||
}
|
||||
}
|
||||
|
||||
override fun getClassLoaderByClassName(className: String): ClassLoader? {
|
||||
val pluginId = PluginManager.getPluginByClassNameAsNoAccessToClass(className)
|
||||
val plugin = PluginManagerCore.getPlugin(pluginId)
|
||||
return plugin?.classLoader
|
||||
}
|
||||
}
|
||||
|
||||
private class IconLayer(@JvmField val flagMask: Int, @JvmField val icon: Icon) {
|
||||
|
||||
@@ -107,6 +107,9 @@ interface IconManager {
|
||||
fun getPluginAndModuleId(classLoader: ClassLoader): Pair<String, String?> = "com.intellij" to null
|
||||
|
||||
fun getClassLoader(pluginId: String, moduleId: String?): ClassLoader? = IconManager::class.java.classLoader
|
||||
|
||||
@Internal
|
||||
fun getClassLoaderByClassName(className: String): ClassLoader? = IconManager::class.java.classLoader
|
||||
}
|
||||
|
||||
private object DummyIconManager : IconManager {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// 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.ui.icons
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Cache
|
||||
@@ -144,34 +144,39 @@ fun isReflectivePath(path: String): Boolean {
|
||||
@Internal
|
||||
fun getReflectiveIcon(path: String, classLoader: ClassLoader): Icon? {
|
||||
try {
|
||||
var dotIndex = path.lastIndexOf('.')
|
||||
val fieldName = path.substring(dotIndex + 1)
|
||||
val builder = StringBuilder(path.length + 20)
|
||||
builder.append(path, 0, dotIndex)
|
||||
var separatorIndex = -1
|
||||
do {
|
||||
dotIndex = path.lastIndexOf('.', dotIndex - 1)
|
||||
// if starts with a lower case, char - it is a package name
|
||||
if (dotIndex == -1 || path[dotIndex + 1].isLowerCase()) {
|
||||
break
|
||||
}
|
||||
if (separatorIndex != -1) {
|
||||
builder.setCharAt(separatorIndex, '$')
|
||||
}
|
||||
separatorIndex = dotIndex
|
||||
}
|
||||
while (true)
|
||||
if (!builder[0].isLowerCase()) {
|
||||
if (separatorIndex != -1) {
|
||||
builder.setCharAt(separatorIndex, '$')
|
||||
}
|
||||
builder.insert(0, if (path.startsWith("AllIcons.")) "com.intellij.icons." else "icons.")
|
||||
}
|
||||
val aClass = classLoader.loadClass(builder.toString())
|
||||
val fieldName = path.substring(path.lastIndexOf('.') + 1)
|
||||
val className = getClassNameByIconPath(path)
|
||||
val aClass = classLoader.loadClass(className)
|
||||
return LOOKUP.findStaticGetter(aClass, fieldName, Icon::class.java).invoke() as Icon
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
logger<CachedImageIcon>().warn("Cannot get reflective icon (path=$path)", e)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
internal fun getClassNameByIconPath(path: String): String {
|
||||
var dotIndex = path.lastIndexOf('.')
|
||||
val builder = StringBuilder(path.length + 20)
|
||||
builder.append(path, 0, dotIndex)
|
||||
var separatorIndex = -1
|
||||
do {
|
||||
dotIndex = path.lastIndexOf('.', dotIndex - 1)
|
||||
// if starts with a lower case, char - it is a package name
|
||||
if (dotIndex == -1 || path[dotIndex + 1].isLowerCase()) {
|
||||
break
|
||||
}
|
||||
if (separatorIndex != -1) {
|
||||
builder.setCharAt(separatorIndex, '$')
|
||||
}
|
||||
separatorIndex = dotIndex
|
||||
}
|
||||
while (true)
|
||||
if (!builder[0].isLowerCase()) {
|
||||
if (separatorIndex != -1) {
|
||||
builder.setCharAt(separatorIndex, '$')
|
||||
}
|
||||
builder.insert(0, if (path.startsWith("AllIcons.")) "com.intellij.icons." else "icons.")
|
||||
}
|
||||
return builder.toString()
|
||||
}
|
||||
@@ -6,6 +6,9 @@ package com.intellij.util.ui
|
||||
import com.intellij.openapi.diagnostic.thisLogger
|
||||
import com.intellij.openapi.util.findIconUsingNewImplementation
|
||||
import com.intellij.openapi.util.text.HtmlChunk
|
||||
import com.intellij.ui.IconManager
|
||||
import com.intellij.ui.icons.getClassNameByIconPath
|
||||
import com.intellij.ui.icons.isReflectivePath
|
||||
import com.intellij.ui.scale.JBUIScale
|
||||
import com.intellij.util.asSafely
|
||||
import com.intellij.util.text.nullize
|
||||
@@ -32,7 +35,7 @@ import kotlin.math.max
|
||||
*/
|
||||
class ExtendableHTMLViewFactory internal constructor(
|
||||
private val extensions: List<(Element, View) -> View?>,
|
||||
private val base: ViewFactory = HTMLEditorKit().viewFactory
|
||||
private val base: ViewFactory = HTMLEditorKit().viewFactory,
|
||||
) : HTMLFactory() {
|
||||
internal constructor(vararg extensions: (Element, View) -> View?) : this(extensions.asList())
|
||||
|
||||
@@ -190,7 +193,16 @@ private class IconExtension(private val existingIconProvider: (key: String) -> I
|
||||
if (existingIcon != null) {
|
||||
return existingIcon
|
||||
}
|
||||
return findIconUsingNewImplementation(path = src, classLoader = ExtendableHTMLViewFactory::class.java.classLoader)
|
||||
|
||||
val classLoader = if (isReflectivePath(src)) {
|
||||
val className = getClassNameByIconPath(src)
|
||||
IconManager.getInstance().getClassLoaderByClassName(className)
|
||||
} else null
|
||||
|
||||
return findIconUsingNewImplementation(
|
||||
path = src,
|
||||
classLoader = classLoader ?: ExtendableHTMLViewFactory::class.java.classLoader,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user