Skip to content

Commit 8097de4

Browse files
Merge pull request #23 from atom-ide-community/feat/markdown-renderer
Feat/markdown renderer
2 parents e4770d7 + c46e6c5 commit 8097de4

8 files changed

Lines changed: 250 additions & 247 deletions

lib/datatip-manager.js

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
// @ts-check
2-
/// <reference path="../typings/atom-ide.d.ts"/>
31
'use babel';
42

53
const { CompositeDisposable, Disposable, Range, Point, TextEditor } = require('atom');
@@ -80,15 +78,18 @@ module.exports = class DatatipManager {
8078
* [cursorMoveTimer description]
8179
*/
8280
this.cursorMoveTimer = null;
81+
82+
this.renderer = null;
8383
}
8484

8585
/**
8686
* [initialize description]
8787
*/
88-
initialize() {
88+
initialize(renderer) {
8989
this.subscriptions = new CompositeDisposable();
9090
this.providerRegistry = new ProviderRegistry();
9191
this.watchedEditors = new WeakSet();
92+
this.renderer = renderer;
9293

9394
this.subscriptions.add(
9495
atom.workspace.observeTextEditors(editor => {
@@ -164,9 +165,9 @@ module.exports = class DatatipManager {
164165
if (editorView.hasFocus()) {
165166
this.updateCurrentEditor(editor);
166167
}
167-
let focusListener = (element) => this.updateCurrentEditor(editor);
168+
let focusListener = () => this.updateCurrentEditor(editor);
168169
editorView.addEventListener('focus', focusListener);
169-
let blurListener = (element) => this.hideDataTip();
170+
let blurListener = () => this.hideDataTip();
170171
editorView.addEventListener('blur', blurListener);
171172

172173
let disposable = new Disposable(() => {
@@ -305,14 +306,20 @@ module.exports = class DatatipManager {
305306
let dataTipView = null;
306307

307308
if (result.component){
308-
dataTipView = new DataTipView({ component: result.component });
309+
dataTipView = new DataTipView({ reactView: result.component });
310+
this.dataTipMarkerDisposables = this.mountDataTipWithMarker(editor, result.range, position, dataTipView);
309311
}
310312
else if (result.markedStrings.length > 0) {
311-
dataTipView = new DataTipView({ markedStrings: result.markedStrings });
312-
}
313-
314-
if (dataTipView) {
315-
this.dataTipMarkerDisposables = this.mountDataTipWithMarker(editor, result.range, position, dataTipView);
313+
let s = result.markedStrings.map((m) => {
314+
if (m.type === "markdown") return m.value;
315+
const regExpLSPPrefix = /^\((method|property|parameter)\)\W/;
316+
const snippet = m.value.replace(regExpLSPPrefix, '');
317+
return `<pre><code class="${editor.getGrammar().name.toLowerCase()}">${snippet}</code></pre>`;
318+
}).join('\r\n');
319+
this.renderer.render(s).then((html) => {
320+
dataTipView = new DataTipView({ htmlView: html });
321+
this.dataTipMarkerDisposables = this.mountDataTipWithMarker(editor, result.range, position, dataTipView);
322+
}).catch((err) => console.log(err));
316323
}
317324
});
318325
}

lib/datatip-view.js

Lines changed: 15 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -3,100 +3,20 @@
33

44
const ReactDOMServer = require('react-dom/server');
55
const etch = require('etch');
6-
const marked = require('marked');
76
const createDOMPurify = require('dompurify');
87
/**
98
* [domPurify description]
109
* @type {DOMPurify}
1110
*/
1211
const domPurify = createDOMPurify();
1312

14-
class SnippetView {
15-
constructor({ snippet, grammar }) {
16-
this.rootElement = document.createElement("div");
17-
this.rootElement.className = "datatip-container";
18-
if (snippet) {
19-
this.refreshRootElement(snippet, grammar);
20-
}
21-
}
22-
23-
update({ snippet, grammar }) {
24-
this.refreshRootElement(snippet, grammar);
25-
}
26-
27-
refreshRootElement(snippet, grammar) {
28-
const wrapper = document.createElement("div");
29-
wrapper.className = "datatip-marked-text-editor";
30-
if (snippet) {
31-
const regExpLSPPrefix = /^\((method|property|parameter)\)\W/;
32-
snippet = snippet.replace(regExpLSPPrefix, '');
33-
if (grammar) {
34-
const atomElem = atom.workspace.buildTextEditor({
35-
lineNumberGutterVisible: false,
36-
readonly: true,
37-
keyboardInputEnabled: false,
38-
showInvisibles: false,
39-
tabLength: atom.config.get("editor.tabLength")
40-
});
41-
atomElem.setGrammar(grammar);
42-
atomElem.setText(snippet);
43-
const atomView = atom.views.getView(atomElem);
44-
atomView.setUpdatedSynchronously(true);
45-
atomView.style.pointerEvents = "none"
46-
atomView.style.position = "absolute";
47-
atomView.style.width = "0px";
48-
atomView.style.height = "1px";
49-
atom.views.getView(atom.workspace).appendChild(atomView);
50-
this.editorTokenized(atomElem).then(() => {
51-
const html = Array.from(atomView.querySelectorAll(".line:not(.dummy)"));
52-
wrapper.innerHTML = domPurify.sanitize(html.map(x => x.innerHTML).join("\n"), { breaks: true });
53-
atomView.remove();
54-
}).catch(() => {
55-
atomView.remove();
56-
})
57-
}
58-
}
59-
this.rootElement.appendChild(wrapper);
60-
}
61-
62-
get element() {
63-
return this.rootElement;
64-
}
65-
66-
/**
67-
* [editorTokenized description]
68-
* @param {TextEditor} editor [description]
69-
* @return {Promise} [description]
70-
*/
71-
editorTokenized(editor) {
72-
return new Promise(resolve => {
73-
if (editor.getBuffer().getLanguageMode().fullyTokenized) {
74-
resolve()
75-
} else {
76-
const disp = editor.onDidTokenize(() => {
77-
disp.dispose()
78-
resolve()
79-
})
80-
}
81-
})
82-
}
83-
}
84-
85-
class MarkdownView {
86-
constructor({ markedString }) {
87-
this.markedString = markedString;
13+
class HtmlView {
14+
constructor({ html }) {
8815
this.rootElement = document.createElement('div');
8916
this.rootElement.className = "datatip-marked-container";
9017
this.rootElement.addEventListener("wheel", this.onMouseWheel, { passive: true });
91-
92-
if (this.markedString) {
93-
this.rootElement.innerHTML = domPurify.sanitize(marked(this.markedString, { breaks: true }));
94-
}
95-
}
96-
update({ markedString }) {
97-
this.markedString = markedString;
98-
if (this.markedString) {
99-
this.rootElement.innerHTML = domPurify.sanitize(marked(this.markedString, { breaks: true }));
18+
if (html){
19+
this.rootElement.innerHTML = domPurify.sanitize(html);
10020
}
10121
}
10222

@@ -113,7 +33,7 @@ class MarkdownView {
11333
}
11434
}
11535

116-
class ReactComponentView {
36+
class ReactView {
11737
constructor({ component }) {
11838
this.rootElement = document.createElement('span')
11939
if (component) {
@@ -134,24 +54,24 @@ module.exports = class DataTipView {
13454
}
13555

13656
render() {
137-
if (this.properties.component) {
57+
if (this.properties.reactView) {
58+
return (
59+
<div className="datatip-element">
60+
<ReactView component={this.properties.reactView} />
61+
</div>
62+
);
63+
}
64+
else if (this.properties.htmlView) {
13865
return (
13966
<div className="datatip-element">
140-
<ReactComponentView component={this.properties.component} />
67+
<HtmlView html={this.properties.htmlView} />
14168
</div>
14269
);
14370
}
14471
else {
14572
return (
14673
<div className="datatip-element">
147-
{this.properties.markedStrings.map((m, i) => {
148-
switch (m.type) {
149-
case "snippet":
150-
return <SnippetView key={i} snippet={m.value} grammar={m.grammar} />;
151-
case "markdown":
152-
return <MarkdownView key={i} markedString={m.value} />;
153-
}
154-
})}
74+
{ this.children }
15575
</div>
15676
);
15777
}

lib/main.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
// @ts-check
2-
/// <reference path="../typings/atom-ide.d.ts"/>
31
'use babel';
42

53
const { CompositeDisposable } = require('atom');
@@ -29,7 +27,11 @@ module.exports = {
2927

3028
if (!this.datatipManager) this.datatipManager = new DataTipManager();
3129
this.subscriptions.add(this.datatipManager);
32-
this.datatipManager.initialize();
30+
31+
require('atom-package-deps').install('atom-ide-datatip')
32+
.then(function() {
33+
console.log('All dependencies installed, good to go')
34+
});
3335
},
3436

3537
/**
@@ -49,5 +51,9 @@ module.exports = {
4951
*/
5052
provideDatatipService() {
5153
return this.datatipManager;
54+
},
55+
56+
consumeMarkdownRenderer(renderer) {
57+
this.datatipManager.initialize(renderer);
5258
}
5359
};

0 commit comments

Comments
 (0)