diff --git a/python/rest/resources/META-INF/rest.xml b/python/rest/resources/META-INF/rest.xml
index 8af190fbfbc8..59dec2d57c29 100644
--- a/python/rest/resources/META-INF/rest.xml
+++ b/python/rest/resources/META-INF/rest.xml
@@ -31,6 +31,11 @@
+
+
diff --git a/python/rest/src/com/jetbrains/rest/editor/RestConfigurable.java b/python/rest/src/com/jetbrains/rest/editor/RestConfigurable.java
new file mode 100644
index 000000000000..69a661195199
--- /dev/null
+++ b/python/rest/src/com/jetbrains/rest/editor/RestConfigurable.java
@@ -0,0 +1,72 @@
+// Copyright 2000-2018 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 com.jetbrains.rest.editor;
+
+import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.options.SearchableConfigurable;
+import com.intellij.openapi.ui.ComboBox;
+import com.intellij.openapi.ui.LabeledComponent;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.awt.*;
+
+public class RestConfigurable implements SearchableConfigurable, Configurable.NoScroll {
+ public static final String ID = "com.jetbrains.rest.editor.RestConfigurable";
+ private final JPanel myPanel = new JPanel(new BorderLayout());
+ private final ComboBox myComboBox;
+ public static final String JAVA_FX = "JavaFX";
+ public static final String SWING = "Swing";
+
+ RestConfigurable() {
+ myComboBox = new ComboBox<>();
+ myComboBox.addItem(JAVA_FX);
+ myComboBox.addItem(SWING);
+ myComboBox.setSelectedItem(RestSettings.getInstance().getCurrentPanel());
+ LabeledComponent component = new LabeledComponent<>();
+ component.setComponent(myComboBox);
+ component.setText("Preview panel:");
+ component.setLabelLocation(BorderLayout.WEST);
+ myPanel.add(component, BorderLayout.NORTH);
+ }
+
+ @NotNull
+ @Override
+ public String getId() {
+ return ID;
+ }
+
+ @Nls
+ @Override
+ public String getDisplayName() {
+ return "ReStructured text";
+ }
+
+ @Override
+ public String getHelpTopic() {
+ return ID;
+ }
+
+ @Override
+ public JComponent createComponent() {
+ return myPanel;
+ }
+
+ @Override
+ public void reset() {
+ }
+
+ @Override
+ public boolean isModified() {
+ return !RestSettings.getInstance().getCurrentPanel().equals(myComboBox.getSelectedItem());
+ }
+
+ @Override
+ public void apply() {
+ final String selectedItem = (String)myComboBox.getSelectedItem();
+ if (selectedItem != null) {
+ RestSettings.getInstance().setCurrentPanel(selectedItem);
+ }
+ }
+
+}
diff --git a/python/rest/src/com/jetbrains/rest/editor/RestJavaFxHtmlPanel.java b/python/rest/src/com/jetbrains/rest/editor/RestJavaFxHtmlPanel.java
new file mode 100644
index 000000000000..d68cecab7add
--- /dev/null
+++ b/python/rest/src/com/jetbrains/rest/editor/RestJavaFxHtmlPanel.java
@@ -0,0 +1,7 @@
+// Copyright 2000-2018 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 com.jetbrains.rest.editor;
+
+import com.intellij.ui.javafx.JavaFxHtmlPanel;
+
+public class RestJavaFxHtmlPanel extends JavaFxHtmlPanel implements RestPreviewPanel {
+}
diff --git a/python/rest/src/com/jetbrains/rest/editor/RestPreviewFileEditor.java b/python/rest/src/com/jetbrains/rest/editor/RestPreviewFileEditor.java
index 5153bdbfe24a..d2dcd4e76da6 100644
--- a/python/rest/src/com/jetbrains/rest/editor/RestPreviewFileEditor.java
+++ b/python/rest/src/com/jetbrains/rest/editor/RestPreviewFileEditor.java
@@ -15,7 +15,6 @@ import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.ui.javafx.JavaFxHtmlPanel;
import com.intellij.util.Alarm;
import kotlin.Pair;
import org.jetbrains.annotations.NotNull;
@@ -48,7 +47,14 @@ public class RestPreviewFileEditor extends UserDataHolderBase implements FileEdi
.allowUrlProtocols("file", "http", "https", "mailto").allowElements("a")
.allowAttributes("href", "title").onElements("a")
.toFactory())
- .and(Sanitizers.TABLES)
+ .and(new HtmlPolicyBuilder()
+ .allowStandardUrlProtocols()
+ .allowElements("table", "tr", "td", "th", "caption", "thead", "tbody", "tfoot")
+ .allowAttributes("summary").onElements("table")
+ .allowAttributes("align", "valign")
+ .onElements("table", "tr", "td", "th", "thead", "tbody", "tfoot")
+ .allowTextIn("table")
+ .toFactory())
.and(new HtmlPolicyBuilder()
.allowElements("code", "tr")
.allowAttributes("class").onElements("code", "tr")
@@ -56,7 +62,7 @@ public class RestPreviewFileEditor extends UserDataHolderBase implements FileEdi
}
};
@NotNull
- private final JavaFxHtmlPanel myPanel;
+ private final RestPreviewPanel myPanel;
@NotNull
private final VirtualFile myFile;
private final Project myProject;
@@ -78,7 +84,9 @@ public class RestPreviewFileEditor extends UserDataHolderBase implements FileEdi
myFile = file;
myProject = project;
myDocument = FileDocumentManager.getInstance().getDocument(myFile);
- myPanel = new JavaFxHtmlPanel();
+ myPanel = RestSettings.getInstance().getCurrentPanel().equals(RestConfigurable.SWING) ?
+ new RestSwingHtmlPanel() :
+ new RestJavaFxHtmlPanel();
if (myDocument != null) {
myDocument.addDocumentListener(new DocumentListener() {
diff --git a/python/rest/src/com/jetbrains/rest/editor/RestPreviewPanel.java b/python/rest/src/com/jetbrains/rest/editor/RestPreviewPanel.java
new file mode 100644
index 000000000000..de85a96e2cd7
--- /dev/null
+++ b/python/rest/src/com/jetbrains/rest/editor/RestPreviewPanel.java
@@ -0,0 +1,16 @@
+// Copyright 2000-2018 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 com.jetbrains.rest.editor;
+
+import com.intellij.openapi.Disposable;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+
+public interface RestPreviewPanel extends Disposable {
+
+ void setHtml(@NotNull String html);
+
+ void render();
+
+ JComponent getComponent();
+}
diff --git a/python/rest/src/com/jetbrains/rest/editor/RestSettings.java b/python/rest/src/com/jetbrains/rest/editor/RestSettings.java
new file mode 100644
index 000000000000..1620e6a0d25a
--- /dev/null
+++ b/python/rest/src/com/jetbrains/rest/editor/RestSettings.java
@@ -0,0 +1,37 @@
+// Copyright 2000-2018 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 com.jetbrains.rest.editor;
+
+import com.intellij.openapi.components.*;
+import com.intellij.util.xmlb.XmlSerializerUtil;
+import org.jetbrains.annotations.NotNull;
+
+import static com.jetbrains.rest.editor.RestConfigurable.JAVA_FX;
+
+@State(name = "RestSettings", storages = @Storage(value="other.xml", roamingType = RoamingType.DISABLED))
+public class RestSettings implements PersistentStateComponent {
+ @NotNull private String myCurrentPanel = JAVA_FX;
+
+ @NotNull
+ public String getCurrentPanel() {
+ return myCurrentPanel;
+ }
+
+ public void setCurrentPanel(@NotNull String currentPanel) {
+ myCurrentPanel = currentPanel;
+ }
+
+ public static RestSettings getInstance() {
+ return ServiceManager.getService(RestSettings.class);
+ }
+
+
+ @Override
+ public RestSettings getState() {
+ return this;
+ }
+
+ @Override
+ public void loadState(@NotNull RestSettings state) {
+ XmlSerializerUtil.copyBean(state, this);
+ }
+}
diff --git a/python/rest/src/com/jetbrains/rest/editor/RestSwingHtmlPanel.java b/python/rest/src/com/jetbrains/rest/editor/RestSwingHtmlPanel.java
new file mode 100644
index 000000000000..60058b40a9ea
--- /dev/null
+++ b/python/rest/src/com/jetbrains/rest/editor/RestSwingHtmlPanel.java
@@ -0,0 +1,39 @@
+// Copyright 2000-2018 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 com.jetbrains.rest.editor;
+
+import com.intellij.ui.components.JBScrollPane;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import javax.swing.text.html.HTMLEditorKit;
+
+public class RestSwingHtmlPanel implements RestPreviewPanel {
+ private final JTextPane myPane;
+ private final JScrollPane myScrollPane;
+
+ RestSwingHtmlPanel() {
+ myPane = new JTextPane();
+ myPane.setEditorKit(new HTMLEditorKit());
+ myScrollPane = new JBScrollPane(myPane);
+ }
+
+ @Override
+ public void setHtml(@NotNull String html) {
+ myPane.setText(html);
+ }
+
+ @Override
+ public void render() {
+ myPane.revalidate();
+ myPane.repaint();
+ }
+
+ @Override
+ public JComponent getComponent() {
+ return myScrollPane;
+ }
+
+ @Override
+ public void dispose() {
+ }
+}