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() { + } +}