Add asynchronous preview with JavaScript
parent
5d2fad6de0
commit
fc39747acc
|
@ -23,10 +23,6 @@ class BaseController(milla.controllers.Controller):
|
||||||
|
|
||||||
class IndexController(BaseController):
|
class IndexController(BaseController):
|
||||||
|
|
||||||
DOCUTILS_SETTINGS = {
|
|
||||||
'syntax_highlight': 'short',
|
|
||||||
}
|
|
||||||
|
|
||||||
allowed_methods = ('GET', 'HEAD', 'POST')
|
allowed_methods = ('GET', 'HEAD', 'POST')
|
||||||
|
|
||||||
def __call__(self, request):
|
def __call__(self, request):
|
||||||
|
@ -39,19 +35,38 @@ class IndexController(BaseController):
|
||||||
|
|
||||||
def POST(self, request):
|
def POST(self, request):
|
||||||
response = request.ResponseClass()
|
response = request.ResponseClass()
|
||||||
data = dict(request.POST)
|
try:
|
||||||
content = data.get('content')
|
content = request.POST['content']
|
||||||
if content:
|
preview = PreviewController.rst2html(content)
|
||||||
parts = docutils.core.publish_parts(
|
except KeyError:
|
||||||
source=content,
|
content = preview = ''
|
||||||
writer_name='html4css1',
|
|
||||||
settings_overrides=self.DOCUTILS_SETTINGS,
|
|
||||||
)
|
|
||||||
preview = parts['html_body']
|
|
||||||
else:
|
|
||||||
preview = ''
|
|
||||||
response.text = self.render('index.html.j2', **dict(
|
response.text = self.render('index.html.j2', **dict(
|
||||||
content=content,
|
content=content,
|
||||||
preview=preview,
|
preview=preview,
|
||||||
))
|
))
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
class PreviewController(BaseController):
|
||||||
|
|
||||||
|
DOCUTILS_SETTINGS = {
|
||||||
|
'syntax_highlight': 'short',
|
||||||
|
}
|
||||||
|
|
||||||
|
allowed_methods = ('HEAD', 'POST')
|
||||||
|
|
||||||
|
def __call__(self, request):
|
||||||
|
return getattr(self, request.method)(request)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def rst2html(cls, source):
|
||||||
|
return docutils.core.publish_parts(
|
||||||
|
source=source,
|
||||||
|
writer_name='html4css1',
|
||||||
|
settings_overrides=cls.DOCUTILS_SETTINGS,
|
||||||
|
)['html_body']
|
||||||
|
|
||||||
|
def POST(self, request):
|
||||||
|
response = request.ResponseClass()
|
||||||
|
response.text = self.rst2html(request.text)
|
||||||
|
return response
|
||||||
|
|
|
@ -5,3 +5,4 @@ from milla.dispatch import routing
|
||||||
router = routing.Router()
|
router = routing.Router()
|
||||||
|
|
||||||
router.add_route('/', controllers.IndexController())
|
router.add_route('/', controllers.IndexController())
|
||||||
|
router.add_route('/preview', controllers.PreviewController())
|
||||||
|
|
|
@ -35,7 +35,7 @@ pre {
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<section class="medium-6 columns">
|
<section class="medium-6 columns">
|
||||||
<form method="post" action="">
|
<form method="post" action="">
|
||||||
<textarea name="content" rows="20">
|
<textarea id="source" name="content" rows="20">
|
||||||
{% if content|d -%}
|
{% if content|d -%}
|
||||||
{{ content|escape }}
|
{{ content|escape }}
|
||||||
{% endif -%}
|
{% endif -%}
|
||||||
|
@ -45,7 +45,7 @@ pre {
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</section>
|
</section>
|
||||||
<section class="medium-6 columns">
|
<section id="preview" class="medium-6 columns">
|
||||||
{{ preview|d('') }}
|
{{ preview|d('') }}
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
@ -55,6 +55,58 @@ pre {
|
||||||
<a href="https://bitbucket.org/AdmiralNemo/rstpreview">RstPreview</a> |
|
<a href="https://bitbucket.org/AdmiralNemo/rstpreview">RstPreview</a> |
|
||||||
Copyright © 2015 Dustin C. Hatch
|
Copyright © 2015 Dustin C. Hatch
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
<script type="text/javascript"
|
||||||
|
src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js">
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript"
|
||||||
|
src="https://cdnjs.cloudflare.com/ajax/libs/foundation/5.5.1/js/foundation.min.js">
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
/* <![CDATA[ */
|
||||||
|
$(document).foundation();
|
||||||
|
$(document).ready(function() {
|
||||||
|
var timeout = 750;
|
||||||
|
var timer;
|
||||||
|
var source_field = $("#source");
|
||||||
|
var preview_pane = $("#preview");
|
||||||
|
var previous;
|
||||||
|
|
||||||
|
var value = source_field.val();
|
||||||
|
if (value) {
|
||||||
|
get_preview(value, preview_pane);
|
||||||
|
}
|
||||||
|
delete value;
|
||||||
|
|
||||||
|
source_field.closest("form").find("button[type=submit]").hide();
|
||||||
|
source_field.keyup(function(evt) {
|
||||||
|
if (timer) {
|
||||||
|
clearTimeout(timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
timer = setTimeout(function() {
|
||||||
|
var value = source_field.val();
|
||||||
|
if (value == previous) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
get_preview(value, preview_pane);
|
||||||
|
previous = value;
|
||||||
|
}, timeout);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function get_preview(value, output) {
|
||||||
|
$.ajax({
|
||||||
|
"url": "preview",
|
||||||
|
"method": "POST",
|
||||||
|
"contentType": "text/plain",
|
||||||
|
"data": value
|
||||||
|
}).done(function(data) {
|
||||||
|
output.html(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/* ]]> */
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Reference in New Issue