[markdown] drop JavaFX-based preview panel and use JCEF-based instead
authorNikolay Chashnikov <Nikolay.Chashnikov@jetbrains.com>
Mon, 10 Aug 2020 16:22:49 +0000 (19:22 +0300)
committerintellij-monorepo-bot <intellij-monorepo-bot-no-reply@jetbrains.com>
Mon, 10 Aug 2020 18:06:42 +0000 (18:06 +0000)
We need to get rid of usages of JavaFX classes in order to migrate to JDK 11 (IDEA-241075).

GitOrigin-RevId: 28547027735ff719f51d04334af3db710593774c

plugins/markdown/resource/META-INF/plugin.xml
plugins/markdown/resource/messages/MarkdownBundle.properties
plugins/markdown/src/org/intellij/plugins/markdown/settings/MarkdownPreviewSettings.java
plugins/markdown/src/org/intellij/plugins/markdown/settings/MarkdownScriptsTable.kt
plugins/markdown/src/org/intellij/plugins/markdown/settings/MarkdownSettingsForm.java
plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/MarkdownHtmlPanelProvider.java
plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/javafx/JavaFxHtmlPanelProvider.java [deleted file]
plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/javafx/MarkdownJavaFxHtmlPanel.java [deleted file]

index 4cebffcd9b059d596793d84712c904a6b5c4f209..9db2b41aca8cfb4a41bd88caea964efa5a0ab94e 100644 (file)
@@ -135,7 +135,6 @@ Includes the following features:</p>
   </applicationListeners>
 
   <extensions defaultExtensionNs="org.intellij.markdown">
-    <html.panel.provider implementation="org.intellij.plugins.markdown.ui.preview.javafx.JavaFxHtmlPanelProvider" />
     <html.panel.provider implementation="org.intellij.plugins.markdown.ui.preview.jcef.JCEFHtmlPanelProvider" />
 
     <fenceLanguageProvider implementation="org.intellij.plugins.markdown.extensions.common.plantuml.PlantUMLCodeFenceLanguageProvider"/>
index fa4bb31a71b65c07e13bdbe673514c3d4c1b93fb..ef9e1b7f63957258cc07508f75f7bdb0d3496f17 100644 (file)
@@ -72,7 +72,6 @@ markdown.cannot.resolve.anchor.in.file.error.message=Cannot resolve anchor in fi
 
 markdown.navigate.to.header=Select Header To Navigate To
 markdown.navigate.to.header.no.headers=Cannot find header to navigate to
-markdown.navigate.to.header.group=Markdown headers group
 markdown.settings.preview.plantUML.download=Install
 markdown.settings.preview.plantUML.installed=PlantUML framework is installed and ready to use.
 markdown.settings.preview.plantUML.download.success=PlantUML has been successfully installed!
@@ -132,5 +131,4 @@ action.org.intellij.plugins.markdown.ui.actions.styling.ToggleBoldAction.text=To
 action.org.intellij.plugins.markdown.ui.actions.styling.ToggleBoldAction.description=Toggles bold mode on caret/selection
 group.Markdown.Toolbar.Left.text=Markdown Editor Actions
 dialog.message.path.error=Could not load file: {0}
-dialog.message.cannot.set.preview.panel.provider=Cannot set preview panel provider ({0}):\n{1}
 dialog.message.tried.to.use.preview.panel.provider=Tried to use preview panel provider ({0}), but it is unavailable. Reverting to default.
index ff2ea05726195fc91b5e25725af43ab688f51955..15154112361cfa10b3b0710ee94ef2aa3f2f5c88 100644 (file)
@@ -5,7 +5,6 @@ import com.intellij.util.xmlb.annotations.Attribute;
 import com.intellij.util.xmlb.annotations.Property;
 import com.intellij.util.xmlb.annotations.Tag;
 import org.intellij.plugins.markdown.ui.preview.MarkdownHtmlPanelProvider;
-import org.intellij.plugins.markdown.ui.preview.javafx.JavaFxHtmlPanelProvider;
 import org.intellij.plugins.markdown.ui.preview.jcef.JCEFHtmlPanelProvider;
 import org.intellij.plugins.markdown.ui.split.SplitFileEditor;
 import org.jetbrains.annotations.NotNull;
@@ -21,7 +20,7 @@ public final class MarkdownPreviewSettings {
   @Property(surroundWithTag = false)
   @NotNull
   private MarkdownHtmlPanelProvider.ProviderInfo myHtmlPanelProviderInfo =
-    JBCefApp.isSupported() ? new JCEFHtmlPanelProvider().getProviderInfo() : new JavaFxHtmlPanelProvider().getProviderInfo();
+    JBCefApp.isSupported() ? new JCEFHtmlPanelProvider().getProviderInfo() : new MarkdownHtmlPanelProvider.ProviderInfo("Unavailable", "Unavailable");
 
   @Attribute("UseGrayscaleRendering")
   private boolean myUseGrayscaleRendering = true;
index 1c18fc7d523bef74da1b7e90237effc3bf48ec66..75eeaf5c77bc7316c098d68dd202d61befd76248 100644 (file)
@@ -11,7 +11,6 @@ import org.intellij.plugins.markdown.extensions.MarkdownExtensionWithExternalFil
 import org.intellij.plugins.markdown.extensions.javafx.MarkdownJavaFXPreviewExtension
 import org.intellij.plugins.markdown.extensions.jcef.MarkdownJCEFPreviewExtension
 import org.intellij.plugins.markdown.ui.preview.MarkdownHtmlPanelProvider
-import org.intellij.plugins.markdown.ui.preview.javafx.JavaFxHtmlPanelProvider
 import org.intellij.plugins.markdown.ui.preview.jcef.JCEFHtmlPanelProvider
 import java.awt.Component
 import javax.swing.JComponent
@@ -56,12 +55,6 @@ internal class MarkdownScriptsTable : JBTable() {
         this
       }
       else when (providerInfo.className) {
-        JavaFxHtmlPanelProvider::class.java.name -> filter {
-          if (it is MarkdownBrowserPreviewExtension) {
-            it !is MarkdownJCEFPreviewExtension
-          }
-          else true
-        }
         JCEFHtmlPanelProvider::class.java.name -> filter {
           if (it is MarkdownBrowserPreviewExtension) {
             it !is MarkdownJavaFXPreviewExtension
index 6fa558723f07c01a0dbce37261675d294cb9fbfe..b2d03e1456aea86acbb4c3c9e4e25c0099e311a8 100644 (file)
@@ -310,12 +310,10 @@ public class MarkdownSettingsForm implements MarkdownCssSettings.Holder, Markdow
   }
 
   @NotNull
-  private static MarkdownHtmlPanelProvider getProvider(@SuppressWarnings("SameParameterValue") @NotNull String providerClass) {
-    for (MarkdownHtmlPanelProvider provider : MarkdownHtmlPanelProvider.getProviders()) {
-      if (isProviderOf(provider.getProviderInfo(), providerClass)) return provider;
-    }
-
-    throw new RuntimeException("Cannot find " + providerClass);
+  private static MarkdownHtmlPanelProvider getDefaultProvider() {
+    MarkdownHtmlPanelProvider[] providers = MarkdownHtmlPanelProvider.getProviders();
+    if (providers.length > 0) return providers[0];
+    throw new RuntimeException("No providers are defined");
   }
 
   @NotNull
@@ -324,7 +322,7 @@ public class MarkdownSettingsForm implements MarkdownCssSettings.Holder, Markdow
       return Objects.requireNonNull(myPreviewPanelModel.getSelected());
     }
     else {
-      return getProvider(JAVA_FX_HTML_PANEL_PROVIDER).getProviderInfo();
+      return getDefaultProvider().getProviderInfo();
     }
   }
 
index ab983d565ac6023d003e511365b4b9bf97ecffd1..8fc0da06d6ad1529f09329b8282823f791e80956 100644 (file)
 // limitations under the License.
 package org.intellij.plugins.markdown.ui.preview;
 
-import com.intellij.CommonBundle;
-import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.extensions.ExtensionPointName;
-import com.intellij.openapi.ui.Messages;
 import com.intellij.util.xmlb.annotations.Attribute;
-import org.intellij.plugins.markdown.MarkdownBundle;
 import org.jetbrains.annotations.NotNull;
 
 import javax.swing.*;
@@ -44,18 +40,12 @@ public abstract class MarkdownHtmlPanelProvider {
 
   @NotNull
   public static MarkdownHtmlPanelProvider createFromInfo(@NotNull ProviderInfo providerInfo) {
-    try {
-      return ((MarkdownHtmlPanelProvider)Class.forName(providerInfo.getClassName()).newInstance());
-    }
-    catch (Exception e) {
-      Messages.showMessageDialog(
-        MarkdownBundle.message("dialog.message.cannot.set.preview.panel.provider", providerInfo.getName(), e.getMessage()),
-        CommonBundle.getErrorTitle(),
-        Messages.getErrorIcon()
-      );
-      Logger.getInstance(MarkdownHtmlPanelProvider.class).error(e);
-      return getProviders()[0];
+    for (MarkdownHtmlPanelProvider provider : getProviders()) {
+      if (provider.getProviderInfo().getClassName().equals(providerInfo.getClassName())) {
+        return provider;
+      }
     }
+    return getProviders()[0];
   }
 
   public static boolean hasAvailableProviders() {
diff --git a/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/javafx/JavaFxHtmlPanelProvider.java b/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/javafx/JavaFxHtmlPanelProvider.java
deleted file mode 100644 (file)
index 15e0dd9..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
-package org.intellij.plugins.markdown.ui.preview.javafx;
-
-import org.intellij.plugins.markdown.ui.preview.MarkdownHtmlPanel;
-import org.intellij.plugins.markdown.ui.preview.MarkdownHtmlPanelProvider;
-import org.jetbrains.annotations.NotNull;
-
-public class JavaFxHtmlPanelProvider extends MarkdownHtmlPanelProvider {
-
-  @NotNull
-  @Override
-  public MarkdownHtmlPanel createHtmlPanel() {
-    return new MarkdownJavaFxHtmlPanel();
-  }
-
-  @NotNull
-  @Override
-  public AvailabilityInfo isAvailable() {
-    try {
-      if (Class.forName("javafx.scene.web.WebView", false, getClass().getClassLoader()) != null) {
-        return AvailabilityInfo.AVAILABLE;
-      }
-    }
-    catch (ClassNotFoundException ignored) {
-    }
-
-    return AvailabilityInfo.UNAVAILABLE;
-  }
-
-  @NotNull
-  @Override
-  public ProviderInfo getProviderInfo() {
-    return new ProviderInfo("JavaFX WebView", JavaFxHtmlPanelProvider.class.getName());
-  }
-
-}
diff --git a/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/javafx/MarkdownJavaFxHtmlPanel.java b/plugins/markdown/src/org/intellij/plugins/markdown/ui/preview/javafx/MarkdownJavaFxHtmlPanel.java
deleted file mode 100644 (file)
index 7dec7ed..0000000
+++ /dev/null
@@ -1,243 +0,0 @@
-// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
-package org.intellij.plugins.markdown.ui.preview.javafx;
-
-import com.intellij.notification.NotificationGroup;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.util.NotNullLazyValue;
-import com.intellij.openapi.wm.ToolWindowId;
-import com.intellij.ui.javafx.JavaFxHtmlPanel;
-import com.intellij.util.containers.ContainerUtil;
-import com.intellij.util.messages.MessageBusConnection;
-import javafx.beans.value.ChangeListener;
-import javafx.beans.value.ObservableValue;
-import javafx.concurrent.Worker.State;
-import javafx.scene.text.FontSmoothingType;
-import javafx.scene.web.WebEngine;
-import javafx.scene.web.WebView;
-import netscape.javascript.JSObject;
-import org.intellij.markdown.html.HtmlGenerator;
-import org.intellij.plugins.markdown.MarkdownBundle;
-import org.intellij.plugins.markdown.extensions.javafx.MarkdownJavaFXPreviewExtension;
-import org.intellij.plugins.markdown.settings.MarkdownApplicationSettings;
-import org.intellij.plugins.markdown.ui.preview.MarkdownHtmlPanel;
-import org.intellij.plugins.markdown.ui.preview.PreviewStaticServer;
-import org.intellij.plugins.markdown.ui.preview.ResourceProvider;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.List;
-import java.util.stream.Collectors;
-
-public class MarkdownJavaFxHtmlPanel extends JavaFxHtmlPanel implements MarkdownHtmlPanel {
-  private static final List<String> BASE_SCRIPTS = ContainerUtil.immutableList(
-    "scrollToElement.js",
-    "processLinks.js"
-  );
-
-  private static final List<MarkdownJavaFXPreviewExtension> EXTENSIONS =
-    MarkdownJavaFXPreviewExtension.getAllSorted();
-
-  private static final List<String> SCRIPTS = ContainerUtil.concat(
-    BASE_SCRIPTS,
-    EXTENSIONS.stream()
-      .flatMap(extension -> extension.getScripts().stream())
-      .collect(Collectors.toList())
-  );
-
-  private static final List<String> STYLES = EXTENSIONS.stream()
-    .flatMap(extension -> extension.getStyles().stream())
-    .collect(Collectors.toList());
-
-  private static final NotNullLazyValue<String> SCRIPTING_LINES = new NotNullLazyValue<String>() {
-    @NotNull
-    @Override
-    protected String compute() {
-      return SCRIPTS.stream()
-        .map(s -> "<script src=\"" + PreviewStaticServer.getStaticUrl(s) + "\"></script>")
-        .reduce((s, s2) -> s + "\n" + s2)
-        .orElseGet(String::new);
-    }
-  };
-
-  private static final NotNullLazyValue<String> STYLES_LINES = new NotNullLazyValue<String>() {
-    @NotNull
-    @Override
-    protected String compute() {
-      return STYLES.stream()
-        .map(s -> "<link rel=\"stylesheet\" href=\"" + PreviewStaticServer.getStaticUrl(s) + "\"/>")
-        .reduce((s, s2) -> s + "\n" + s2)
-        .orElseGet(String::new);
-    }
-  };
-
-  private static final NotNullLazyValue<String> CSP = new NotNullLazyValue<String>() {
-    @NotNull
-    @Override
-    protected String compute() {
-      return PreviewStaticServer.createCSP(
-        ContainerUtil.map(SCRIPTS, s -> PreviewStaticServer.getStaticUrl(s)),
-        ContainerUtil.map(STYLES, s -> PreviewStaticServer.getStaticUrl(s)));
-    }
-  };
-
-  @NotNull
-  private final ScrollPreservingListener myScrollPreservingListener = new ScrollPreservingListener();
-  @NotNull
-  private final BridgeSettingListener myBridgeSettingListener = new BridgeSettingListener();
-
-  public MarkdownJavaFxHtmlPanel() {
-    super();
-    runInPlatformWhenAvailable(() -> {
-      if (myWebView != null) {
-        updateFontSmoothingType(
-          myWebView, MarkdownApplicationSettings.getInstance().getMarkdownPreviewSettings().isUseGrayscaleRendering()
-        );
-      }
-    });
-    PreviewStaticServer.getInstance().setResourceProvider(resourceProvider);
-    subscribeForGrayscaleSetting();
-  }
-
-  @Override
-  protected void registerListeners(@NotNull WebEngine engine) {
-    engine.getLoadWorker().stateProperty().addListener(myBridgeSettingListener);
-    engine.getLoadWorker().stateProperty().addListener(myScrollPreservingListener);
-  }
-
-  private void subscribeForGrayscaleSetting() {
-    MessageBusConnection settingsConnection = ApplicationManager.getApplication().getMessageBus().connect(this);
-    MarkdownApplicationSettings.SettingsChangedListener settingsChangedListener =
-      new MarkdownApplicationSettings.SettingsChangedListener() {
-        @Override
-        public void beforeSettingsChanged(@NotNull final MarkdownApplicationSettings settings) {
-          runInPlatformWhenAvailable(() -> {
-            if (myWebView != null) {
-              updateFontSmoothingType(myWebView, settings.getMarkdownPreviewSettings().isUseGrayscaleRendering());
-            }
-          });
-        }
-      };
-    settingsConnection.subscribe(MarkdownApplicationSettings.SettingsChangedListener.TOPIC, settingsChangedListener);
-  }
-
-  private static void updateFontSmoothingType(@NotNull WebView view, boolean isGrayscale) {
-    final FontSmoothingType typeToSet;
-    if (isGrayscale) {
-      typeToSet = FontSmoothingType.GRAY;
-    }
-    else {
-      typeToSet = FontSmoothingType.LCD;
-    }
-    view.fontSmoothingTypeProperty().setValue(typeToSet);
-  }
-
-
-  private static final MyResourceProvider resourceProvider = new MyResourceProvider();
-
-  @NotNull
-  @Override
-  protected String prepareHtml(@NotNull String html) {
-    return ImageRefreshFix.setStamps(
-      html.replace(
-        "<head>",
-        "<head>" +
-        "<meta http-equiv=\"Content-Security-Policy\" content=\"" + CSP + "\"/>" +
-        STYLES_LINES.getValue() + "\n" + SCRIPTING_LINES.getValue()
-      )
-    );
-  }
-
-  @Override
-  public void scrollToMarkdownSrcOffset(final int offset) {
-    runInPlatformWhenAvailable(() -> {
-      getWebViewGuaranteed().getEngine().executeScript(
-        "if ('__IntelliJTools' in window) " +
-        "__IntelliJTools.scrollToOffset(" + offset + ", '" + HtmlGenerator.Companion.getSRC_ATTRIBUTE_NAME() + "');"
-      );
-      final Object result = getWebViewGuaranteed().getEngine().executeScript(
-        "document.documentElement.scrollTop || (document.body && document.body.scrollTop)");
-      if (result instanceof Number) {
-        myScrollPreservingListener.myScrollY = ((Number)result).intValue();
-      }
-    });
-  }
-
-  @Override
-  public void dispose() {
-    runInPlatformWhenAvailable(() -> {
-      getWebViewGuaranteed().getEngine().getLoadWorker().stateProperty().removeListener(myScrollPreservingListener);
-      getWebViewGuaranteed().getEngine().getLoadWorker().stateProperty().removeListener(myBridgeSettingListener);
-    });
-  }
-
-  private static class MyResourceProvider implements ResourceProvider {
-    @Override
-    public boolean canProvide(@NotNull String resourceName) {
-      return BASE_SCRIPTS.contains(resourceName) ||
-             EXTENSIONS.stream()
-               .anyMatch(extension -> extension.getResourceProvider().canProvide(resourceName));
-    }
-
-    @Nullable
-    @Override
-    public Resource loadResource(@NotNull String resourceName) {
-      if (BASE_SCRIPTS.contains(resourceName)) {
-        return ResourceProvider.loadInternalResource(MarkdownJavaFxHtmlPanel.class, resourceName, null);
-      }
-      ResourceProvider provider = EXTENSIONS.stream()
-        .filter(extension -> extension.getResourceProvider().canProvide(resourceName))
-        .map(extension -> extension.getResourceProvider())
-        .findFirst()
-        .orElse(null);
-      if (provider == null) {
-        return null;
-      }
-      return provider.loadResource(resourceName);
-    }
-  }
-
-  @SuppressWarnings("unused")
-  public static class JavaPanelBridge {
-    static final JavaPanelBridge INSTANCE = new JavaPanelBridge();
-    private static final NotificationGroup MARKDOWN_NOTIFICATION_GROUP = NotificationGroup
-      .toolWindowGroup("Markdown headers group", ToolWindowId.MESSAGES_WINDOW, true,
-                       MarkdownBundle.message("markdown.navigate.to.header.group"));
-
-    public void openInExternalBrowser(@NotNull String link) {
-      SafeOpener.openLink(link);
-    }
-
-    public void log(@Nullable String text) {
-      Logger.getInstance(JavaPanelBridge.class).warn(text);
-    }
-  }
-
-  private class BridgeSettingListener implements ChangeListener<State> {
-    @Override
-    public void changed(ObservableValue<? extends State> observable, State oldValue, State newValue) {
-      JSObject win
-        = (JSObject)getWebViewGuaranteed().getEngine().executeScript("window");
-      win.setMember("JavaPanelBridge", JavaPanelBridge.INSTANCE);
-    }
-  }
-
-  private class ScrollPreservingListener implements ChangeListener<State> {
-    volatile int myScrollY = 0;
-
-    @Override
-    public void changed(ObservableValue<? extends State> observable, State oldValue, State newValue) {
-      if (newValue == State.RUNNING) {
-        final Object result =
-          getWebViewGuaranteed().getEngine().executeScript("document.documentElement.scrollTop || document.body.scrollTop");
-        if (result instanceof Number) {
-          myScrollY = ((Number)result).intValue();
-        }
-      }
-      else if (newValue == State.SUCCEEDED) {
-        getWebViewGuaranteed().getEngine()
-          .executeScript("document.documentElement.scrollTop = ({} || document.body).scrollTop = " + myScrollY);
-      }
-    }
-  }
-}