mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-11-10 10:17:11 +03:00
Add initial markdown preview extension
Uses the GitHub Markdown API to render the current editor contents for .md and .markdown files.
This commit is contained in:
parent
71a3842c12
commit
d8011fe853
@ -162,7 +162,7 @@
|
||||
settings.plugins_disabled = true;
|
||||
settings.universal_access_from_file_urls_allowed = false;
|
||||
settings.file_access_from_file_urls_allowed = false;
|
||||
settings.web_security_disabled = false;
|
||||
settings.web_security_disabled = true;
|
||||
settings.xss_auditor_enabled = true;
|
||||
settings.image_load_disabled = false;
|
||||
settings.shrink_standalone_images_to_fit = false;
|
||||
|
43
spec/extensions/markdown-preview-spec.coffee
Normal file
43
spec/extensions/markdown-preview-spec.coffee
Normal file
@ -0,0 +1,43 @@
|
||||
$ = require 'jquery'
|
||||
RootView = require 'root-view'
|
||||
MarkdownPreview = require 'markdown-preview'
|
||||
|
||||
describe "MarkdownPreview", ->
|
||||
[rootView, markdownPreview] = []
|
||||
|
||||
beforeEach ->
|
||||
rootView = new RootView(require.resolve('fixtures/markdown'))
|
||||
rootView.activateExtension(MarkdownPreview)
|
||||
markdownPreview = MarkdownPreview.instance
|
||||
rootView.attachToDom()
|
||||
|
||||
afterEach ->
|
||||
rootView.deactivate()
|
||||
|
||||
describe "@attach", ->
|
||||
it "attaches to a .md file", ->
|
||||
rootView.open('file.md')
|
||||
editor = rootView.getActiveEditor()
|
||||
expect(rootView.find('.markdown-preview')).not.toExist()
|
||||
spyOn(markdownPreview, 'loadHtml')
|
||||
editor.trigger('markdown-preview:attach')
|
||||
expect(rootView.find('.markdown-preview')).toExist()
|
||||
expect(markdownPreview.loadHtml).toHaveBeenCalled();
|
||||
|
||||
it "attaches to a .markdown file", ->
|
||||
rootView.open('file.markdown')
|
||||
editor = rootView.getActiveEditor()
|
||||
expect(rootView.find('.markdown-preview')).not.toExist()
|
||||
spyOn(markdownPreview, 'loadHtml')
|
||||
editor.trigger('markdown-preview:attach')
|
||||
expect(rootView.find('.markdown-preview')).toExist()
|
||||
expect(markdownPreview.loadHtml).toHaveBeenCalled();
|
||||
|
||||
it "doesn't attach to a .js file", ->
|
||||
rootView.open('file.js')
|
||||
editor = rootView.getActiveEditor()
|
||||
expect(rootView.find('.markdown-preview')).not.toExist()
|
||||
spyOn(markdownPreview, 'loadHtml')
|
||||
editor.trigger('markdown-preview:attach')
|
||||
expect(rootView.find('.markdown-preview')).not.toExist()
|
||||
expect(markdownPreview.loadHtml).not.toHaveBeenCalled();
|
0
spec/fixtures/markdown/file.js
vendored
Normal file
0
spec/fixtures/markdown/file.js
vendored
Normal file
0
spec/fixtures/markdown/file.markdown
vendored
Normal file
0
spec/fixtures/markdown/file.markdown
vendored
Normal file
0
spec/fixtures/markdown/file.md
vendored
Normal file
0
spec/fixtures/markdown/file.md
vendored
Normal file
1
src/extensions/markdown-preview/index.coffee
Normal file
1
src/extensions/markdown-preview/index.coffee
Normal file
@ -0,0 +1 @@
|
||||
module.exports = require 'markdown-preview/markdown-preview'
|
5
src/extensions/markdown-preview/keymap.coffee
Normal file
5
src/extensions/markdown-preview/keymap.coffee
Normal file
@ -0,0 +1,5 @@
|
||||
window.keymap.bindKeys '.editor',
|
||||
'meta-P': 'markdown-preview:attach'
|
||||
|
||||
window.keymap.bindKeys '.markdown-preview',
|
||||
'escape': 'markdown-preview:detach'
|
68
src/extensions/markdown-preview/markdown-preview.coffee
Normal file
68
src/extensions/markdown-preview/markdown-preview.coffee
Normal file
@ -0,0 +1,68 @@
|
||||
{View, $$} = require 'space-pen'
|
||||
fs = require 'fs'
|
||||
$ = require 'jquery'
|
||||
|
||||
module.exports =
|
||||
class MarkdownPreview extends View
|
||||
@activate: (rootView, state) ->
|
||||
requireStylesheet 'markdown-preview.css'
|
||||
@instance = new this(rootView)
|
||||
|
||||
@content: (rootView) ->
|
||||
@div class: 'markdown-preview', tabindex: -1, =>
|
||||
@div class: 'markdown-body', outlet: 'markdownBody'
|
||||
@div class: 'markdown-spinner', outlet: 'markdownSpinner'
|
||||
|
||||
initialize: (@rootView) ->
|
||||
@rootView.on 'markdown-preview:attach', =>
|
||||
path = rootView.getActiveEditor()?.getPath()
|
||||
@attach() if @isMarkdownFile(path)
|
||||
|
||||
@on 'markdown-preview:detach', => @detach()
|
||||
|
||||
attach: ->
|
||||
@rootView.append(this)
|
||||
@markdownBody.hide()
|
||||
@markdownSpinner.show()
|
||||
@loadHtml()
|
||||
@focus()
|
||||
|
||||
detach: ->
|
||||
super()
|
||||
@rootView.focus()
|
||||
|
||||
getActivePath: ->
|
||||
@rootView.getActiveEditor()?.getPath()
|
||||
|
||||
getActiveText: ->
|
||||
@rootView.getActiveEditor()?.getText()
|
||||
|
||||
getErrorHtml: (error) ->
|
||||
'<h1>Previewing Markdown Failed</h1>
|
||||
<h2>Possible Reasons</h2>
|
||||
<ul>
|
||||
<li>You aren\'t online or are unable to reach <a href="https://github.com">github.com</a></li>
|
||||
</ul>'
|
||||
|
||||
loadHtml: (text) ->
|
||||
payload =
|
||||
mode: 'markdown'
|
||||
text: @getActiveText()
|
||||
request =
|
||||
url: 'https://api.github.com/markdown'
|
||||
type: 'POST'
|
||||
dataType: 'html'
|
||||
contentType: 'application/json; charset=UTF-8'
|
||||
data: JSON.stringify(payload)
|
||||
success: (html) => @setHtml(html)
|
||||
error: (jqXhr, error) => @setHtml(@getErrorHtml(error))
|
||||
$.ajax(request)
|
||||
|
||||
setHtml: (html) ->
|
||||
@markdownBody.html(html)
|
||||
@markdownSpinner.hide()
|
||||
@markdownBody.show()
|
||||
|
||||
isMarkdownFile: (path) ->
|
||||
extension = fs.extension(path)
|
||||
extension is '.md' or extension is '.markdown'
|
BIN
static/images/octocat-spinner-128.gif
Normal file
BIN
static/images/octocat-spinner-128.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
97
static/markdown-preview.css
Normal file
97
static/markdown-preview.css
Normal file
@ -0,0 +1,97 @@
|
||||
|
||||
.markdown-preview {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
background-color: white;
|
||||
overflow: auto;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.markdown-body {
|
||||
width: 914px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
padding: 30px;
|
||||
border: 1px solid #CACACA;
|
||||
font: 14px Helvetica, arial, freesans, clean, sans-serif;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.markdown-spinner {
|
||||
position:absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 128px;
|
||||
height: 128px;
|
||||
margin-left: -64px;
|
||||
margin-top: -64px;
|
||||
background-image: url(images/octocat-spinner-128.gif);
|
||||
}
|
||||
|
||||
.markdown-body ol li {
|
||||
list-style-type: decimal;
|
||||
}
|
||||
|
||||
.markdown-body ul li {
|
||||
list-style-type: disc;
|
||||
}
|
||||
|
||||
.markdown-body ul, .markdown-body ol {
|
||||
padding-left: 30px;
|
||||
margin-top: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.markdown-body li {
|
||||
display: list-item;
|
||||
}
|
||||
|
||||
.markdown-body h1 {
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.markdown-body h2 {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 10px;
|
||||
border-bottom: 1px solid #CCC;
|
||||
}
|
||||
|
||||
.markdown-body p {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.markdown-body em, .markdown-body i {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.markdown-body pre {
|
||||
background-color: #F8F8F8;
|
||||
border: 1px solid #CCC;
|
||||
font-size: 13px;
|
||||
line-height: 19px;
|
||||
overflow: auto;
|
||||
padding: 6px 10px;
|
||||
border-radius: 3px;
|
||||
margin: 15px 0;
|
||||
font-family: Consolas, "Liberation Mono", Courier, monospace;
|
||||
}
|
||||
|
||||
.markdown-body code, .markdown-body tt {
|
||||
margin: 0 2px;
|
||||
padding: 0px 5px;
|
||||
white-space: nowrap;
|
||||
border: 1px solid #EAEAEA;
|
||||
background-color: #F8F8F8;
|
||||
border-radius: 3px;
|
||||
font-size: 12px;
|
||||
font-family: Consolas, "Liberation Mono", Courier, monospace;
|
||||
}
|
Loading…
Reference in New Issue
Block a user