Skip to content

Commit

Permalink
New search function;Fix Structure (Jump function is not available);Fi…
Browse files Browse the repository at this point in the history
…x Outline scrolling synchronously;Reduce mouse flicker;

close #13,close #16,close #17
  • Loading branch information
shuzijun committed Dec 2, 2021
1 parent e3e9c51 commit 568c88a
Show file tree
Hide file tree
Showing 13 changed files with 265 additions and 15 deletions.
12 changes: 12 additions & 0 deletions Demo.md
Original file line number Diff line number Diff line change
Expand Up @@ -248,3 +248,15 @@ st->op->cond
cond(yes)->e
cond(no)->op
```

### plantuml

```plantuml
@startuml component
actor client
node app
database db
db -> app
app -> client
@enduml
```
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
plugin_version = 1.9
plugin_version = 1.10
intellij_version = 2021.1
intellij_plugins =
39 changes: 39 additions & 0 deletions src/main/java/com/shuzijun/markdown/editor/MarkdownHtmlPanel.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.shuzijun.markdown.editor;

import com.alibaba.fastjson.JSONObject;
import com.intellij.ide.BrowserUtil;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationType;
Expand All @@ -12,8 +13,10 @@
import com.intellij.openapi.fileTypes.FileTypes;
import com.intellij.openapi.fileTypes.ex.FileTypeChooser;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.jcef.JBCefJSQuery;
import com.intellij.ui.jcef.JCEFHtmlPanel;
import com.intellij.util.io.HttpRequests;
import com.intellij.util.io.URLUtil;
Expand All @@ -36,6 +39,7 @@
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.function.Function;

/**
* @author shuzijun
Expand All @@ -46,6 +50,7 @@ public class MarkdownHtmlPanel extends JCEFHtmlPanel {

private final CefRequestHandler requestHandler;
private final CefLifeSpanHandler lifeSpanHandler;
private final JBCefJSQuery findJSQuery;

private final String url;
private final Project project;
Expand Down Expand Up @@ -118,12 +123,30 @@ public boolean onBeforePopup(CefBrowser browser, CefFrame frame, String target_u
return true;
}
}, getCefBrowser());
findJSQuery = JBCefJSQuery.create(this);
findJSQuery.addHandler(new Function<String, JBCefJSQuery.Response>() {
@Override
public JBCefJSQuery.Response apply(String find) {
if (StringUtils.isEmpty(find)) {
getCefBrowser().stopFinding(true);
return null;
}
JSONObject findObject = JSONObject.parseObject(find);
if (StringUtils.isEmpty(findObject.getString("searchText"))) {
getCefBrowser().stopFinding(true);
return null;
}
getCefBrowser().find(1, findObject.getString("searchText"), findObject.getBoolean("forward"), false, true);
return null;
}
});
}

@Override
public void dispose() {
getJBCefClient().removeRequestHandler(requestHandler, getCefBrowser());
getJBCefClient().removeLifeSpanHandler(lifeSpanHandler, getCefBrowser());
Disposer.dispose(findJSQuery);
super.dispose();
}

Expand Down Expand Up @@ -157,4 +180,20 @@ public void updateStyle(String style) {
getCefBrowser().executeJavaScript(
"updateStyle('" + style + "'," + UIUtil.isUnderDarcula() + ");", getCefBrowser().getURL(), 0);
}

public String getInjectScript() {
String script = "function find(searchText,forward){\n" +
" let findJson = '{\"searchText\":\"'+searchText+'\",\"forward\":'+forward+'}';\n" +
" " + findJSQuery.inject("findJson") +
" }";
return script;
}

public void browserFind(String txt,boolean forward){
if (StringUtils.isEmpty(txt)) {
getCefBrowser().stopFinding(true);
return;
}
getCefBrowser().find(1, txt, forward, false, true);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package com.shuzijun.markdown.editor;

import com.google.common.net.UrlEscapers;
import com.intellij.ide.structureView.StructureViewBuilder;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.ActionToolbar;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.colors.EditorColors;
Expand All @@ -18,8 +23,11 @@
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.DocumentAdapter;
import com.intellij.ui.JBColor;
import com.intellij.ui.components.JBLabel;
import com.intellij.ui.components.JBPanel;
import com.intellij.ui.components.JBTextField;
import com.intellij.util.Url;
import com.intellij.util.Urls;
import com.intellij.util.io.URLUtil;
Expand All @@ -37,7 +45,12 @@
import org.jetbrains.ide.BuiltInServerManager;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.FileInputStream;
Expand All @@ -57,6 +70,9 @@ public class MarkdownPreviewFileEditor extends UserDataHolderBase implements Fil
private final JPanel myHtmlPanelWrapper;
private final MarkdownHtmlPanel myPanel;

private final JBPanel toolbarPanel = new JBPanel(new FlowLayout(FlowLayout.LEFT));
private final JBTextField searchField = new JBTextField();

private final Url servicePath = BuiltInServerManager.getInstance().addAuthToken(Urls.parseEncoded("http://localhost:" + BuiltInServerManager.getInstance().getPort() + PreviewStaticServer.PREFIX));
private final String templateHtmlFile = "template/default.html";
private final boolean isPresentableUrl;
Expand All @@ -71,8 +87,54 @@ public MarkdownPreviewFileEditor(@NotNull Project project, @NotNull VirtualFile
MarkdownHtmlPanel tempPanel = null;
try {
tempPanel = new MarkdownHtmlPanel(url, project);
tempPanel.loadHTML(createHtml(isPresentableUrl), url);
tempPanel.loadHTML(createHtml(isPresentableUrl,tempPanel), url);
myHtmlPanelWrapper.add(tempPanel.getComponent(), BorderLayout.CENTER);

MarkdownHtmlPanel finalTempPanel = tempPanel;
searchField.setPreferredSize(new Dimension(200,25));
searchField.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_ENTER){
finalTempPanel.browserFind(searchField.getText(),true);
}
}
});
searchField.getDocument().addDocumentListener(new DocumentAdapter() {
@Override
protected void textChanged(@NotNull DocumentEvent e) {
finalTempPanel.browserFind(searchField.getText(),true);
}
});
JBLabel previousLabel = new JBLabel("<",JLabel.CENTER);
previousLabel.setPreferredSize(new Dimension(25,25));
previousLabel.addMouseListener(new LabelMouseListener(previousLabel,false));
JBLabel nextLabel = new JBLabel(">",JLabel.CENTER);
nextLabel.setPreferredSize(new Dimension(25,25));
nextLabel.addMouseListener(new LabelMouseListener(nextLabel,true));
JBLabel close = new JBLabel("x",JLabel.CENTER);
close.setPreferredSize(new Dimension(25,25));
close.addMouseListener(new LabelMouseListener(close,false){
@Override
public void mouseClicked(MouseEvent e) {
searchField.setText("");
toolbarPanel.setVisible(false);
}
});
toolbarPanel.add( new JBLabel("find:",JLabel.CENTER));
toolbarPanel.add(searchField);
toolbarPanel.add(previousLabel);
toolbarPanel.add(nextLabel);
toolbarPanel.add(close);
AnAction searchAction = ActionManager.getInstance().getAction("markdown.search");
AnAction searchVisibleAction = ActionManager.getInstance().getAction("markdown.searchVisible");
ActionToolbar actionToolbar = ActionManager.getInstance().createActionToolbar(PluginConstant.EDITOR_TOOLBAR,new DefaultActionGroup(searchAction,searchVisibleAction), true);
actionToolbar.setTargetComponent(myHtmlPanelWrapper);
JComponent actionToolbarComponent = actionToolbar.getComponent();
actionToolbarComponent.setVisible(false);
toolbarPanel.add(actionToolbarComponent);
toolbarPanel.setVisible(false);
myHtmlPanelWrapper.add(toolbarPanel,BorderLayout.NORTH);
} catch (IllegalStateException e) {
myHtmlPanelWrapper.add(new JBLabel(e.getMessage()), BorderLayout.CENTER);
}
Expand Down Expand Up @@ -137,6 +199,13 @@ public void removePropertyChangeListener(@NotNull PropertyChangeListener listene
return null;
}

@Override
public StructureViewBuilder getStructureViewBuilder() {
VirtualFile file = FileDocumentManager.getInstance().getFile(myDocument);
if (file == null || !file.isValid()) return null;
return StructureViewBuilder.PROVIDER.getStructureViewBuilder(file.getFileType(), file, myProject);
}

@Override
public void dispose() {
ApplicationManager.getApplication().getService(FileApplicationService.class)
Expand All @@ -146,7 +215,7 @@ public void dispose() {
}
}

private String createHtml(boolean isPresentableUrl) {
private String createHtml(boolean isPresentableUrl,MarkdownHtmlPanel tempPanel) {
InputStream inputStream = null;

try {
Expand All @@ -166,6 +235,7 @@ private String createHtml(boolean isPresentableUrl) {
.replace("{{projectUrl}}", isPresentableUrl ? myProject.getPresentableUrl() : "")
.replace("{{projectName}}", isPresentableUrl ? "" : myProject.getName())
.replace("{{ideStyle}}", getStyle(true))
.replace("{{injectScript}}", tempPanel.getInjectScript())
;
} catch (IOException e) {
throw new RuntimeException(e);
Expand Down Expand Up @@ -227,4 +297,42 @@ private String toHexColor(Color color) {
return String.format("rgba(%s,%s,%s,%s)", color.getRed(), color.getGreen(), color.getBlue(), df.format(color.getAlpha() / (float) 255));
}

public void visibleToolbarPanel(boolean visible){
toolbarPanel.setVisible(visible);
if(visible) {
searchField.requestFocus();
}else {
searchField.setText("");
}
}

private class LabelMouseListener extends MouseAdapter{

private JBLabel label;

private boolean forward;

private Color color;

public LabelMouseListener(JBLabel label, boolean forward) {
this.label = label;
this.forward = forward;
}

@Override
public void mouseClicked(MouseEvent e) {
myPanel.browserFind(searchField.getText(),forward);
}

@Override
public void mousePressed(MouseEvent e) {
color = label.getForeground();
label.setForeground(Color.BLUE);
}

@Override
public void mouseReleased(MouseEvent e) {
label.setForeground(color);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package com.shuzijun.markdown.editor;


import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.FileEditorPolicy;
import com.intellij.openapi.fileEditor.WeighedFileEditorProvider;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.jcef.JBCefApp;
import com.shuzijun.markdown.model.PluginConstant;
import org.jetbrains.annotations.NotNull;

/**
Expand Down Expand Up @@ -35,6 +37,7 @@ public String getEditorTypeId() {
@NotNull
@Override
public FileEditorPolicy getPolicy() {
return FileEditorPolicy.PLACE_AFTER_DEFAULT_EDITOR;
String editorPolicy = PropertiesComponent.getInstance().getValue(PluginConstant.editorPolicyKey,FileEditorPolicy.PLACE_AFTER_DEFAULT_EDITOR.name());
return FileEditorPolicy.valueOf(editorPolicy);
}
}
23 changes: 23 additions & 0 deletions src/main/java/com/shuzijun/markdown/editor/SearchAction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.shuzijun.markdown.editor;

import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.fileEditor.FileEditorManager;
import org.jetbrains.annotations.NotNull;

/**
* @author shuzijun
*/
public class SearchAction extends AnAction {
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
try {
MarkdownPreviewFileEditor fileEditor = (MarkdownPreviewFileEditor) FileEditorManager.getInstance(e.getProject()).getSelectedEditor();
fileEditor.visibleToolbarPanel(true);
}catch (Exception ignore){

}


}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.shuzijun.markdown.editor;

import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.fileEditor.FileEditorManager;
import org.jetbrains.annotations.NotNull;

/**
* @author shuzijun
*/
public class SearchVisibleAction extends AnAction {
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
try {
MarkdownPreviewFileEditor fileEditor = (MarkdownPreviewFileEditor) FileEditorManager.getInstance(e.getProject()).getSelectedEditor();
fileEditor.visibleToolbarPanel(false);
}catch (Exception ignore){

}


}
}
4 changes: 4 additions & 0 deletions src/main/java/com/shuzijun/markdown/model/PluginConstant.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,13 @@ public class PluginConstant {
public static final String NOTIFICATION_GROUP = "Markdown editor";
public static final String APPLICATION_CONFIGURABLE_DISPLAY_NAME = "Markdown editor";

public static final String EDITOR_TOOLBAR = "Markdown Editor Toolbar";

public static final String TEMPLATE_VERSION = "1";
public static final String TEMPLATE_PATH = PathManager.getPluginsPath() + File.separator + "markdown-editor" + File.separator + "assets" + File.separator;

public static final String JS_DELIVR_ENDPOINTS = "https://data.jsdelivr.com/v1/package/gh/shuzijun/markdown-editor";
public static final String CDN = "https://cdn.jsdelivr.net/gh/shuzijun/markdown-editor@";

public static final String editorPolicyKey="markdown.editor.editorPolicy";
}
Loading

0 comments on commit 568c88a

Please sign in to comment.