Pagedown extra enhancements. Fixes #15

This commit is contained in:
benweet 2013-06-02 20:35:44 +01:00
parent cc36894da7
commit d1e9b8c0a5
9 changed files with 59 additions and 59 deletions

View File

@ -794,7 +794,7 @@
<div id="modal-non-unique" class="modal hide"> <div id="modal-non-unique" class="modal hide">
<div class="modal-header"> <div class="modal-header">
<h3>Whoops...</h3> <h3>Ooops...</h3>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<p>StackEdit has stopped because another instance was running in <p>StackEdit has stopped because another instance was running in

View File

@ -321,14 +321,22 @@ define([
e.stopPropagation(); e.stopPropagation();
}); });
$(".modal").on('shown', function() { var shownModalId = undefined;
$(".modal").on('shown', function(e) {
// Focus on the first input when modal opens // Focus on the first input when modal opens
var modalId = $(this).attr("id");
if(shownModalId != modalId) {
// Hack to avoid conflict with tabs, collapse, tooltips events
shownModalId = modalId;
_.defer(function(elt) { _.defer(function(elt) {
elt.find("input:enabled:visible:first").focus(); elt.find("input:enabled:visible:first").focus();
}, $(this)); }, $(this));
}
}).on('hidden', function() { }).on('hidden', function() {
// Focus on the editor when modal is gone // Focus on the editor when modal is gone
if($(this).is(":hidden")) { var modalId = $(this).attr("id");
if(shownModalId == modalId && $(this).is(":hidden")) {
shownModalId = undefined;
_.defer(function() { _.defer(function() {
$("#wmd-input").focus(); $("#wmd-input").focus();
}); });
@ -345,12 +353,14 @@ define([
var value = utils.getInputTextValue($("#input-insert-link"), e); var value = utils.getInputTextValue($("#input-insert-link"), e);
if(value !== undefined) { if(value !== undefined) {
core.insertLinkCallback(value); core.insertLinkCallback(value);
core.insertLinkCallback = undefined;
} }
}); });
$(".action-insert-image").click(function(e) { $(".action-insert-image").click(function(e) {
var value = utils.getInputTextValue($("#input-insert-image"), e); var value = utils.getInputTextValue($("#input-insert-image"), e);
if(value !== undefined) { if(value !== undefined) {
core.insertLinkCallback(value); core.insertLinkCallback(value);
core.insertLinkCallback = undefined;
} }
}); });
@ -358,6 +368,7 @@ define([
$("#modal-insert-link, #modal-insert-image").on('hidden', function() { $("#modal-insert-link, #modal-insert-image").on('hidden', function() {
if(core.insertLinkCallback !== undefined) { if(core.insertLinkCallback !== undefined) {
core.insertLinkCallback(null); core.insertLinkCallback(null);
core.insertLinkCallback = undefined;
} }
}); });

View File

@ -88,11 +88,6 @@ define([
} }
documentSelector.onReady = function() { documentSelector.onReady = function() {
$("#file-selector").click(function() {
_.defer(function() {
$("#wmd-input").focus();
});
});
$(".action-open-file").click(function() { $(".action-open-file").click(function() {
filterFileSelector(); filterFileSelector();
_.defer(function() { _.defer(function() {

View File

@ -204,14 +204,14 @@ else
text = _UnescapeSpecialChars(text); text = _UnescapeSpecialChars(text);
text = pluginHooks.postConversion(text); // benweet
// attacklab: Restore dollar signs // attacklab: Restore dollar signs
text = text.replace(/~D/g, "$$"); text = text.replace(/~D/g, "$$");
// attacklab: Restore tildes // attacklab: Restore tildes
text = text.replace(/~T/g, "~"); text = text.replace(/~T/g, "~");
text = pluginHooks.postConversion(text);
g_html_blocks = g_titles = g_urls = null; g_html_blocks = g_titles = g_urls = null;
return text; return text;

View File

@ -693,6 +693,7 @@
timer = undefined; timer = undefined;
inputStateObj = undefined; inputStateObj = undefined;
refreshState(); refreshState();
inputStateObj.setInputAreaSelection();
saveState(); saveState();
}; };

View File

@ -88,30 +88,15 @@
} }
// Convert markdown within an element, retaining only span-level tags // Convert markdown within an element, retaining only span-level tags
// (An inefficient version of Pagedown's runSpanGamut. We rely on a function convertSpans(text, extra) {
// pagedown coverter to do the complete conversion, and then retain return sanitizeHtml(convertAll(text, extra), inlineTags);
// only the specified tags -- inline in this case).
function convertSpans(text, converter) {
text = denormalize(text);
var html = converter.makeHtml(text);
return sanitizeHtml(html, inlineTags);
} }
// Convert internal markdown using the stock pagedown converter // Convert internal markdown using the stock pagedown converter
function convertAll(text, converter) { function convertAll(text, extra) {
text = denormalize(text); var result = extra.blockGamutHookCallback(text);
return converter.makeHtml(text); result = extra.previousPostConversion(result);
} return result;
// We use convertSpans and convertAll to convert markdown inside of Markdown Extra
// elements we create. Since this markdown has already been through the pagedown
// normalization process before our hooks were called, we need to do some
// denormalization before sending it back through a different Pagedown converter.
function denormalize(text) {
// Restore dollar signs and tildes
text = text.replace(/~D/g, "$$");
text = text.replace(/~T/g, "~");
return text;
} }
// Convert escaped special characters to HTML decimal entity codes. // Convert escaped special characters to HTML decimal entity codes.
@ -123,13 +108,6 @@
return text.replace(/\\\|/g, '&#124;').replace(/\\:/g, '&#58;'); return text.replace(/\\\|/g, '&#124;').replace(/\\:/g, '&#58;');
} }
// Determine if the given pagedown converter performs sanitization
// on postConversion
function isSanitizing(converter) {
// call the converter's postConversion hook and see if it sanitizes its input
return converter.hooks.postConversion("<table>") === "";
}
/****************************************************************** /******************************************************************
* Markdown.Extra * * Markdown.Extra *
@ -186,10 +164,13 @@
// preBlockGamut also gives us access to a hook so we can run the // preBlockGamut also gives us access to a hook so we can run the
// block gamut recursively, however we don't need it at this point // block gamut recursively, however we don't need it at this point
converter.hooks.chain("preBlockGamut", function(text) { converter.hooks.chain("preBlockGamut", function(text, blockGamutHookCallback) {
extra.blockGamutHookCallback = blockGamutHookCallback;
return extra.doConversion(preBlockGamutTransformations, text); return extra.doConversion(preBlockGamutTransformations, text);
}); });
// Keep a reference to the hook chain running before finishConversion to apply on hashed extra blocks
extra.previousPostConversion = converter.hooks.postConversion;
converter.hooks.chain("postConversion", function(text) { converter.hooks.chain("postConversion", function(text) {
return extra.finishConversion(text); return extra.finishConversion(text);
}); });
@ -203,10 +184,7 @@
extra.tableClass = options.table_class; extra.tableClass = options.table_class;
} }
// we can't just use the same converter that the user passes in, as extra.converter = converter;
// Pagedown forbids it (doing so could cause an infinite loop)
extra.converter = isSanitizing(converter) ? Markdown.getSanitizingConverter()
: new Markdown.Converter();
// Caller usually won't need this, but it's handy for testing. // Caller usually won't need this, but it's handy for testing.
return extra; return extra;
@ -255,10 +233,21 @@
// html blocks in the hashBlocks array. // html blocks in the hashBlocks array.
Markdown.Extra.prototype.unHashExtraBlocks = function(text) { Markdown.Extra.prototype.unHashExtraBlocks = function(text) {
var self = this; var self = this;
function recursiveUnHash() {
var hasHash = false;
text = text.replace(/<p>~X(\d+)X<\/p>/g, function(wholeMatch, m1) { text = text.replace(/<p>~X(\d+)X<\/p>/g, function(wholeMatch, m1) {
hasHash = true;
var key = parseInt(m1, 10); var key = parseInt(m1, 10);
return self.hashBlocks[key]; var result = self.hashBlocks[key];
// We need to perform that since we skipped the steps in the converter
result = result.replace(/~D/g, "$$").replace(/~T/g, "~");
return result;
}); });
if(hasHash === true) {
recursiveUnHash();
}
}
recursiveUnHash();
return text; return text;
}; };
@ -419,7 +408,7 @@
// build column headers. // build column headers.
for (i = 0; i < colCount; i++) { for (i = 0; i < colCount; i++) {
var headerHtml = convertSpans(trim(headers[i]), self.converter); var headerHtml = convertSpans(trim(headers[i]), self);
html += [" <th", align[i], ">", headerHtml, "</th>\n"].join(''); html += [" <th", align[i], ">", headerHtml, "</th>\n"].join('');
} }
html += "</tr>\n</thead>\n"; html += "</tr>\n</thead>\n";
@ -438,7 +427,7 @@
html += "<tr>\n"; html += "<tr>\n";
for (j = 0; j < colCount; j++) { for (j = 0; j < colCount; j++) {
var colHtml = convertSpans(trim(rowCells[j]), self.converter); var colHtml = convertSpans(trim(rowCells[j]), self);
html += [" <td", align[j], ">", colHtml, "</td>\n"].join(''); html += [" <td", align[j], ">", colHtml, "</td>\n"].join('');
} }
html += "</tr>\n"; html += "</tr>\n";
@ -592,7 +581,7 @@
for (var i = 0; i < terms.length; i++) { for (var i = 0; i < terms.length; i++) {
var term = terms[i]; var term = terms[i];
// process spans inside dt // process spans inside dt
term = convertSpans(trim(term), self.converter); term = convertSpans(trim(term), self);
text += "\n<dt>" + term + "</dt>"; text += "\n<dt>" + term + "</dt>";
} }
return text + "\n"; return text + "\n";
@ -606,11 +595,11 @@
// process markdown inside definition // process markdown inside definition
// TODO?: currently doesn't apply extensions // TODO?: currently doesn't apply extensions
def = outdent(def) + "\n\n"; def = outdent(def) + "\n\n";
def = "\n" + convertAll(def, self.converter) + "\n"; def = "\n" + convertAll(def, self) + "\n";
} else { } else {
// convert span-level markdown inside definition // convert span-level markdown inside definition
def = rtrim(def); def = rtrim(def);
def = convertSpans(outdent(def), self.converter); def = convertSpans(outdent(def), self);
} }
return "\n<dd>" + def + "</dd>\n"; return "\n<dd>" + def + "</dd>\n";

View File

@ -7,13 +7,17 @@ define([
layoutOrientation: "horizontal", layoutOrientation: "horizontal",
lazyRendering: true, lazyRendering: true,
editorFontSize: 14, editorFontSize: 14,
defaultContent: "\n\n\n> Written with [StackEdit](http://benweet.github.io/stackedit/).", defaultContent: "\n\n\n> Written with [StackEdit](" + MAIN_URL + ").",
commitMsg: "Published by http://benweet.github.io/stackedit", commitMsg: "Published with " + MAIN_URL,
template: [ template: [
'<!DOCTYPE html>\n', '<!DOCTYPE html>\n',
'<html>\n', '<html>\n',
'<head>\n', '<head>\n',
'<meta charset="utf-8">\n',
'<title><%= documentTitle %></title>\n', '<title><%= documentTitle %></title>\n',
'<link rel="stylesheet" href="',
MAIN_URL,
'css/main-min.css" />\n',
'</head>\n', '</head>\n',
'<body><%= documentHTML %></body>\n', '<body><%= documentHTML %></body>\n',
'</html>' '</html>'

View File

@ -3,7 +3,7 @@ set -e
echo '### Optimizing resources ###' echo '### Optimizing resources ###'
scripts/run_optimize scripts/run_optimize
echo '### Modifying cache.manifest ###' echo '### Modifying cache.manifest ###'
sed -i "s/^#.*$/# `date`/g" cache.manifest sed -i "s/^#.*/# `date`/" cache.manifest
echo '### Commit and push ###' echo '### Commit and push ###'
git commit -a -m "Prepare deployment" git commit -a -m "Prepare deployment"
git branch -f gh-pages master git branch -f gh-pages master

View File

@ -79,7 +79,7 @@
<div id="modal-non-unique" class="modal hide"> <div id="modal-non-unique" class="modal hide">
<div class="modal-header"> <div class="modal-header">
<h3>Whoops...</h3> <h3>Ooops...</h3>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<p>StackEdit has stopped because another instance was running in <p>StackEdit has stopped because another instance was running in