diff --git a/plugins/markdown/core/backend/resources/intellij.markdown.backend.xml b/plugins/markdown/core/backend/resources/intellij.markdown.backend.xml
index 960c80349259..69afef589557 100644
--- a/plugins/markdown/core/backend/resources/intellij.markdown.backend.xml
+++ b/plugins/markdown/core/backend/resources/intellij.markdown.backend.xml
@@ -5,8 +5,8 @@
+ implementation="org.intellij.plugins.markdown.backend.providers.MarkdownLinkOpenerApiProvider"/>
+ implementation="org.intellij.plugins.markdown.backend.providers.VirtualFileAccessorProvider"/>
\ No newline at end of file
diff --git a/plugins/markdown/core/backend/src/org/intellij/plugins/markdown/backend/providers/LinkOpenerApiProvider.kt b/plugins/markdown/core/backend/src/org/intellij/plugins/markdown/backend/providers/MarkdownLinkOpenerApiProvider.kt
similarity index 88%
rename from plugins/markdown/core/backend/src/org/intellij/plugins/markdown/backend/providers/LinkOpenerApiProvider.kt
rename to plugins/markdown/core/backend/src/org/intellij/plugins/markdown/backend/providers/MarkdownLinkOpenerApiProvider.kt
index 9a45f78b8c98..c43086a8f3b9 100644
--- a/plugins/markdown/core/backend/src/org/intellij/plugins/markdown/backend/providers/LinkOpenerApiProvider.kt
+++ b/plugins/markdown/core/backend/src/org/intellij/plugins/markdown/backend/providers/MarkdownLinkOpenerApiProvider.kt
@@ -5,7 +5,7 @@ import fleet.rpc.remoteApiDescriptor
import org.intellij.plugins.markdown.backend.services.MarkdownLinkOpenerRemoteApiImpl
import org.intellij.plugins.markdown.service.MarkdownLinkOpenerRemoteApi
-private class LinkOpenerApiProvider : RemoteApiProvider {
+private class MarkdownLinkOpenerApiProvider : RemoteApiProvider {
override fun RemoteApiProvider.Sink.remoteApis() {
remoteApi(remoteApiDescriptor()) {
MarkdownLinkOpenerRemoteApiImpl()
diff --git a/plugins/markdown/core/backend/src/org/intellij/plugins/markdown/backend/providers/ProjectStructureProvider.kt b/plugins/markdown/core/backend/src/org/intellij/plugins/markdown/backend/providers/ProjectStructureProvider.kt
deleted file mode 100644
index 9d330056ca8b..000000000000
--- a/plugins/markdown/core/backend/src/org/intellij/plugins/markdown/backend/providers/ProjectStructureProvider.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package org.intellij.plugins.markdown.backend.providers
-
-import com.intellij.platform.rpc.backend.RemoteApiProvider
-import fleet.rpc.remoteApiDescriptor
-import org.intellij.plugins.markdown.backend.services.ProjectStructureRemoteApiImpl
-import org.intellij.plugins.markdown.service.ProjectStructureRemoteApi
-
-private class ProjectStructureProvider : RemoteApiProvider {
- override fun RemoteApiProvider.Sink.remoteApis() {
- remoteApi(remoteApiDescriptor()) {
- ProjectStructureRemoteApiImpl()
- }
- }
-}
\ No newline at end of file
diff --git a/plugins/markdown/core/backend/src/org/intellij/plugins/markdown/backend/providers/VirtualFileAccessorProvider.kt b/plugins/markdown/core/backend/src/org/intellij/plugins/markdown/backend/providers/VirtualFileAccessorProvider.kt
new file mode 100644
index 000000000000..9c5696de3612
--- /dev/null
+++ b/plugins/markdown/core/backend/src/org/intellij/plugins/markdown/backend/providers/VirtualFileAccessorProvider.kt
@@ -0,0 +1,14 @@
+package org.intellij.plugins.markdown.backend.providers
+
+import com.intellij.platform.rpc.backend.RemoteApiProvider
+import fleet.rpc.remoteApiDescriptor
+import org.intellij.plugins.markdown.backend.services.VirtualFileAccessorImpl
+import org.intellij.plugins.markdown.service.VirtualFileAccessor
+
+private class VirtualFileAccessorProvider : RemoteApiProvider {
+ override fun RemoteApiProvider.Sink.remoteApis() {
+ remoteApi(remoteApiDescriptor()) {
+ VirtualFileAccessorImpl()
+ }
+ }
+}
\ No newline at end of file
diff --git a/plugins/markdown/core/backend/src/org/intellij/plugins/markdown/backend/services/ProjectStructureRemoteApiImpl.kt b/plugins/markdown/core/backend/src/org/intellij/plugins/markdown/backend/services/VirtualFileAccessorImpl.kt
similarity index 76%
rename from plugins/markdown/core/backend/src/org/intellij/plugins/markdown/backend/services/ProjectStructureRemoteApiImpl.kt
rename to plugins/markdown/core/backend/src/org/intellij/plugins/markdown/backend/services/VirtualFileAccessorImpl.kt
index 2147918b6d63..f95dfac3eec4 100644
--- a/plugins/markdown/core/backend/src/org/intellij/plugins/markdown/backend/services/ProjectStructureRemoteApiImpl.kt
+++ b/plugins/markdown/core/backend/src/org/intellij/plugins/markdown/backend/services/VirtualFileAccessorImpl.kt
@@ -9,11 +9,11 @@ import com.intellij.openapi.vfs.VfsUtil
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.platform.project.ProjectId
import com.intellij.platform.project.findProject
-import org.intellij.plugins.markdown.service.ProjectStructureRemoteApi
+import org.intellij.plugins.markdown.service.VirtualFileAccessor
import java.io.File
import java.net.URL
-class ProjectStructureRemoteApiImpl : ProjectStructureRemoteApi {
+class VirtualFileAccessorImpl : VirtualFileAccessor {
private fun getBaseDirectory(projectId: ProjectId, virtualFileId: VirtualFileId) : VirtualFile?{
val project = projectId.findProject()
val virtualFile = virtualFileId.virtualFile() ?: return null
@@ -21,8 +21,7 @@ class ProjectStructureRemoteApiImpl : ProjectStructureRemoteApi {
return baseDirectory
}
- override suspend fun getFileByResourceName(resourceName: String, virtualFileId: VirtualFileId?, projectId: ProjectId?): VirtualFileId? {
- if (projectId == null || virtualFileId == null) return null
+ override suspend fun getFileByResourceName(resourceName: String, virtualFileId: VirtualFileId, projectId: ProjectId): VirtualFileId? {
val projectRoot = getBaseDirectory(projectId, virtualFileId)
val resource = if (resourceName.startsWith("file:/")) {
VfsUtil.findFileByIoFile(File(URL(resourceName).path), true)
@@ -33,6 +32,6 @@ class ProjectStructureRemoteApiImpl : ProjectStructureRemoteApi {
}
companion object {
- private val logger: Logger = Logger.getInstance(ProjectStructureRemoteApiImpl::class.java)
+ private val logger: Logger = Logger.getInstance(VirtualFileAccessorImpl::class.java)
}
}
\ No newline at end of file
diff --git a/plugins/markdown/core/frontend/src/org/intellij/plugins/markdown/frontend/preview/accessor/impl/MarkdownLinkOpenerImpl.kt b/plugins/markdown/core/frontend/src/org/intellij/plugins/markdown/frontend/preview/accessor/impl/MarkdownLinkOpenerImpl.kt
index f50955188c59..d3ee6288da07 100644
--- a/plugins/markdown/core/frontend/src/org/intellij/plugins/markdown/frontend/preview/accessor/impl/MarkdownLinkOpenerImpl.kt
+++ b/plugins/markdown/core/frontend/src/org/intellij/plugins/markdown/frontend/preview/accessor/impl/MarkdownLinkOpenerImpl.kt
@@ -36,12 +36,13 @@ import org.intellij.plugins.markdown.settings.DocumentLinksSafeState
import org.intellij.plugins.markdown.ui.MarkdownNotifications
import org.intellij.plugins.markdown.ui.preview.accessor.MarkdownLinkOpener
import org.intellij.plugins.markdown.ui.preview.accessor.MarkdownLinkOpenerUtil
-import org.intellij.plugins.markdown.ui.preview.accessor.MarkdownLinkOpenerUtil.Companion.findVirtualFile
+import org.intellij.plugins.markdown.ui.preview.accessor.MarkdownLinkOpenerUtil.findVirtualFile
import org.intellij.plugins.markdown.util.MarkdownDisposable
import java.net.URI
import java.net.URISyntaxException
internal class MarkdownLinkOpenerImpl(val coroutineScope: CoroutineScope) : MarkdownLinkOpener {
+ @Deprecated("Use openLink(project, link, sourceFile) instead", replaceWith = ReplaceWith("openLink(project, link, sourceFile)"))
override fun openLink(project: Project?, link: String) {
val uri = createUri(link) ?: return
if (tryOpenInEditorDeprecated(project, uri)) {
@@ -52,16 +53,15 @@ internal class MarkdownLinkOpenerImpl(val coroutineScope: CoroutineScope) : Mark
}
}
- override fun openLink(project: Project?, link: String, containingFile: VirtualFile?) {
+ override fun openLink(currentProject: Project?, link: String, containingFile: VirtualFile?) {
coroutineScope.launch {
val data = MarkdownLinkOpenerRemoteApi.getInstance().fetchLinkNavigationData(link, containingFile?.rpcId())
val uri = createUri(data.uri) ?: return@launch
if (uri.scheme != "file") {
- openExternalLink(project, uri)
+ openExternalLink(currentProject, uri)
return@launch
}
- @Suppress("NAME_SHADOWING")
- val project = project ?: data.projectId?.findProject() ?: return@launch
+ val project = currentProject ?: data.projectId?.findProject() ?: return@launch
val fileToOpen = data.virtualFileId?.virtualFile() ?: return@launch
val anchor = uri.fragment
if (anchor == null) {
diff --git a/plugins/markdown/core/src/org/intellij/plugins/markdown/extensions/jcef/ProcessImagesExtension.kt b/plugins/markdown/core/src/org/intellij/plugins/markdown/extensions/jcef/ProcessImagesExtension.kt
index e1959166211e..795880b43767 100644
--- a/plugins/markdown/core/src/org/intellij/plugins/markdown/extensions/jcef/ProcessImagesExtension.kt
+++ b/plugins/markdown/core/src/org/intellij/plugins/markdown/extensions/jcef/ProcessImagesExtension.kt
@@ -8,14 +8,14 @@ import com.intellij.openapi.vfs.VirtualFile
import com.intellij.platform.project.projectId
import kotlinx.coroutines.runBlocking
import org.intellij.plugins.markdown.extensions.MarkdownBrowserPreviewExtension
-import org.intellij.plugins.markdown.service.ProjectStructureRemoteApi
+import org.intellij.plugins.markdown.service.VirtualFileAccessor
import org.intellij.plugins.markdown.ui.preview.MarkdownHtmlPanel
import org.intellij.plugins.markdown.ui.preview.ResourceProvider
internal class ProcessImagesExtension(
private val baseFile: VirtualFile?,
- private val project: Project?
-): ResourceProvider, MarkdownBrowserPreviewExtension {
+ private val project: Project?,
+) : ResourceProvider, MarkdownBrowserPreviewExtension {
override val resourceProvider: ResourceProvider = this
override fun canProvide(resourceName: String): Boolean {
@@ -23,32 +23,30 @@ internal class ProcessImagesExtension(
}
override fun loadResource(resourceName: String): ResourceProvider.Resource? {
- val baseFileId = baseFile?.rpcId()
- val projectId = project?.projectId()
+ val baseFileId = baseFile?.rpcId() ?: return null
+ val projectId = project?.projectId() ?: return null
val resource = runBlocking {
- ProjectStructureRemoteApi.getInstance().getFileByResourceName(resourceName, baseFileId, projectId)?.virtualFile()
+ VirtualFileAccessor.getInstance().getFileByResourceName(resourceName, baseFileId, projectId)?.virtualFile()
} ?: return null
return ResourceProvider.loadExternalResource(resource)
}
override fun dispose() = Unit
- companion object{
- fun hasImageExtension(name: String): Boolean {
- val lowerName = name.lowercase()
- return lowerName.endsWith(".jpeg") ||
- lowerName.endsWith(".jpg") ||
- lowerName.endsWith(".png") ||
- lowerName.endsWith(".gif") ||
- lowerName.endsWith(".bmp") ||
- lowerName.endsWith(".svg") ||
- lowerName.endsWith(".webp") ||
- lowerName.endsWith(".tiff") ||
- lowerName.endsWith(".tif")
- }
+ private fun hasImageExtension(name: String): Boolean {
+ val lowerName = name.lowercase()
+ return lowerName.endsWith(".jpeg") ||
+ lowerName.endsWith(".jpg") ||
+ lowerName.endsWith(".png") ||
+ lowerName.endsWith(".gif") ||
+ lowerName.endsWith(".bmp") ||
+ lowerName.endsWith(".svg") ||
+ lowerName.endsWith(".webp") ||
+ lowerName.endsWith(".tiff") ||
+ lowerName.endsWith(".tif")
}
- class Provider: MarkdownBrowserPreviewExtension.Provider {
+ class Provider : MarkdownBrowserPreviewExtension.Provider {
override fun createBrowserExtension(panel: MarkdownHtmlPanel): MarkdownBrowserPreviewExtension {
return ProcessImagesExtension(panel.virtualFile, panel.project)
}
diff --git a/plugins/markdown/core/src/org/intellij/plugins/markdown/mapper/MarkdownHeaderMapper.java b/plugins/markdown/core/src/org/intellij/plugins/markdown/mapper/MarkdownHeaderMapper.java
index 6cfca2890866..98ce072d4f69 100644
--- a/plugins/markdown/core/src/org/intellij/plugins/markdown/mapper/MarkdownHeaderMapper.java
+++ b/plugins/markdown/core/src/org/intellij/plugins/markdown/mapper/MarkdownHeaderMapper.java
@@ -2,6 +2,7 @@
package org.intellij.plugins.markdown.mapper;
import com.intellij.ide.vfs.VirtualFileId;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
@@ -13,9 +14,12 @@ import com.intellij.ide.vfs.VirtualFileIdKt;
* Mapper class for converting a MarkdownHeader into a MarkdownHeaderInfo.
*/
public final class MarkdownHeaderMapper {
+ private static final Logger logger = Logger.getInstance(MarkdownHeaderMapper.class);
+
public static MarkdownHeaderInfo map(MarkdownHeader header) {
if (header == null) {
- throw new IllegalArgumentException("header cannot be null");
+ logger.warn("Header is null, returning null");
+ return null;
}
String headerText = header.getText();
diff --git a/plugins/markdown/core/src/org/intellij/plugins/markdown/service/ProjectStructureRemoteApi.kt b/plugins/markdown/core/src/org/intellij/plugins/markdown/service/VirtualFileAccessor.kt
similarity index 75%
rename from plugins/markdown/core/src/org/intellij/plugins/markdown/service/ProjectStructureRemoteApi.kt
rename to plugins/markdown/core/src/org/intellij/plugins/markdown/service/VirtualFileAccessor.kt
index 131ffb401c40..2b50c15056ac 100644
--- a/plugins/markdown/core/src/org/intellij/plugins/markdown/service/ProjectStructureRemoteApi.kt
+++ b/plugins/markdown/core/src/org/intellij/plugins/markdown/service/VirtualFileAccessor.kt
@@ -11,13 +11,13 @@ import org.jetbrains.annotations.ApiStatus
@ApiStatus.Internal
@Rpc
-interface ProjectStructureRemoteApi : RemoteApi {
- suspend fun getFileByResourceName(resourceName: String, virtualFileId: VirtualFileId?, projectId: ProjectId?): VirtualFileId?
+interface VirtualFileAccessor : RemoteApi {
+ suspend fun getFileByResourceName(resourceName: String, virtualFileId: VirtualFileId, projectId: ProjectId): VirtualFileId?
companion object {
@JvmStatic
- suspend fun getInstance(): ProjectStructureRemoteApi {
- return RemoteApiProviderService.resolve(remoteApiDescriptor())
+ suspend fun getInstance(): VirtualFileAccessor {
+ return RemoteApiProviderService.resolve(remoteApiDescriptor())
}
}
}
\ No newline at end of file
diff --git a/plugins/markdown/core/src/org/intellij/plugins/markdown/ui/preview/accessor/MarkdownLinkOpener.kt b/plugins/markdown/core/src/org/intellij/plugins/markdown/ui/preview/accessor/MarkdownLinkOpener.kt
index c0fa7fe686e8..d85d6db3e1cd 100644
--- a/plugins/markdown/core/src/org/intellij/plugins/markdown/ui/preview/accessor/MarkdownLinkOpener.kt
+++ b/plugins/markdown/core/src/org/intellij/plugins/markdown/ui/preview/accessor/MarkdownLinkOpener.kt
@@ -22,6 +22,7 @@ interface MarkdownLinkOpener {
*
* Note: it is possible to add custom url handler with [com.intellij.ide.browsers.UrlOpener] EP.
*/
+ @Deprecated("this method lacks remote development support", ReplaceWith("openLink(project, link, sourceFile)"))
fun openLink(project: Project?, link: String)
fun openLink(project: Project?, link: String, sourceFile: VirtualFile?)
diff --git a/plugins/markdown/core/src/org/intellij/plugins/markdown/ui/preview/accessor/MarkdownLinkOpenerUtil.kt b/plugins/markdown/core/src/org/intellij/plugins/markdown/ui/preview/accessor/MarkdownLinkOpenerUtil.kt
index 7a2f36b05ced..226173700756 100644
--- a/plugins/markdown/core/src/org/intellij/plugins/markdown/ui/preview/accessor/MarkdownLinkOpenerUtil.kt
+++ b/plugins/markdown/core/src/org/intellij/plugins/markdown/ui/preview/accessor/MarkdownLinkOpenerUtil.kt
@@ -25,63 +25,61 @@ import java.net.URISyntaxException
import java.nio.file.Path
import com.intellij.openapi.diagnostic.logger
-class MarkdownLinkOpenerUtil {
- companion object{
- private val logger = logger()
+object MarkdownLinkOpenerUtil {
+ private val logger = logger()
- fun navigateToHeader(project: Project, headerInfo: MarkdownHeaderInfo) {
- val uri = createFileUri(headerInfo.filePath)
- if (uri == null) return
- val file = headerInfo.virtualFileId.virtualFile()
- if (file == null) return
- val manager = FileEditorManager.getInstance(project)
- val openedEditors = manager.getEditorList(file).stream()
- .filter { editor: FileEditor? -> editor is MarkdownEditorWithPreview }
- .map { editor: FileEditor? -> editor as MarkdownEditorWithPreview }
- .toList()
- val element = PsiUtilCore.getPsiFile(project, file).findElementAt(headerInfo.textOffset)
- if (element == null) return
- if (!openedEditors.isEmpty()) {
- for (editor in openedEditors) {
- PsiUtilCore.getElementAtOffset(PsiUtilCore.getPsiFile(project, file), element.getTextOffset())
- PsiNavigateUtil.navigate(element, true)
- }
- return
+ fun navigateToHeader(project: Project, headerInfo: MarkdownHeaderInfo) {
+ val uri = createFileUri(headerInfo.filePath)
+ if (uri == null) return
+ val file = headerInfo.virtualFileId.virtualFile()
+ if (file == null) return
+ val manager = FileEditorManager.getInstance(project)
+ val openedEditors = manager.getEditorList(file).stream()
+ .filter { editor: FileEditor? -> editor is MarkdownEditorWithPreview }
+ .map { editor: FileEditor? -> editor as MarkdownEditorWithPreview }
+ .toList()
+ val element = PsiUtilCore.getPsiFile(project, file).findElementAt(headerInfo.textOffset)
+ if (element == null) return
+ if (!openedEditors.isEmpty()) {
+ for (editor in openedEditors) {
+ PsiUtilCore.getElementAtOffset(PsiUtilCore.getPsiFile(project, file), element.getTextOffset())
+ PsiNavigateUtil.navigate(element, true)
}
- val descriptor = OpenFileDescriptor(project, file, element.getTextOffset())
- manager.openEditor(descriptor, true)
+ return
}
+ val descriptor = OpenFileDescriptor(project, file, element.getTextOffset())
+ manager.openEditor(descriptor, true)
+ }
- fun collectHeaders(project: Project, anchor: String, targetFile: VirtualFile): List? {
- return runReadAction {
- if (DumbService.isDumb(project)) {
- return@runReadAction emptyList()
- }
- val scope = when (val file = PsiManager.getInstance(project).findFile(targetFile)) {
- null -> GlobalSearchScope.EMPTY_SCOPE
- else -> GlobalSearchScope.fileScope(file)
- }
- return@runReadAction HeaderAnchorIndex.collectHeaders(project, scope, anchor).map(MarkdownHeaderMapper::map)
+ fun collectHeaders(project: Project, anchor: String, targetFile: VirtualFile): List? {
+ return runReadAction {
+ if (DumbService.isDumb(project)) {
+ return@runReadAction emptyList()
}
- }
-
- fun URI.findVirtualFile(): VirtualFile? {
- val actualPath = when {
- SystemInfo.isWindows -> UriUtil.trimLeadingSlashes(path)
- else -> path
- }
- val path = Path.of(actualPath)
- return VfsUtil.findFile(path, true)
- }
-
- private fun createFileUri(link: String?): URI? {
- try {
- return URI("file", null, link, null)
- }
- catch (exception: URISyntaxException) {
- logger.warn(exception)
- return null
+ val scope = when (val file = PsiManager.getInstance(project).findFile(targetFile)) {
+ null -> GlobalSearchScope.EMPTY_SCOPE
+ else -> GlobalSearchScope.fileScope(file)
}
+ return@runReadAction HeaderAnchorIndex.collectHeaders(project, scope, anchor).map(MarkdownHeaderMapper::map)
}
}
-}
\ No newline at end of file
+
+ fun URI.findVirtualFile(): VirtualFile? {
+ val actualPath = when {
+ SystemInfo.isWindows -> UriUtil.trimLeadingSlashes(path)
+ else -> path
+ }
+ val path = Path.of(actualPath)
+ return VfsUtil.findFile(path, true)
+ }
+
+ private fun createFileUri(link: String?): URI? {
+ try {
+ return URI("file", null, link, null)
+ }
+ catch (exception: URISyntaxException) {
+ logger.warn(exception)
+ return null
+ }
+ }
+}