Fixed HTML blocks in FCB

This commit is contained in:
benweet 2013-05-10 11:50:23 +01:00
parent 27d30c64d0
commit 47ef49808c
7 changed files with 98 additions and 79 deletions

View File

@ -1 +1 @@
CACHE MANIFEST # v26 CACHE: index.html viewer.html css/main-min.css js/main-min.js js/require.js img/ajax-loader.gif img/glyphicons-halflings.png img/glyphicons-halflings-white.png img/icons.png img/stackedit-32.ico img/stackedit-promo.png NETWORK: * CACHE MANIFEST # v27 CACHE: index.html viewer.html css/main-min.css js/main-min.js js/require.js img/ajax-loader.gif img/glyphicons-halflings.png img/glyphicons-halflings-white.png img/icons.png img/stackedit-32.ico img/stackedit-promo.png NETWORK: *

3
css/main-min.css vendored
View File

@ -5386,6 +5386,9 @@ div, span, a, ul, li, textarea, input, button {
border: 1px solid #e2e2e2 !important; border: 1px solid #e2e2e2 !important;
text-align: left; text-align: left;
} }
.dropdown-menu:before {
border-bottom-color: #e2e2e2 !important;
}
input, input,
select, select,
textarea, textarea,

View File

@ -55,6 +55,10 @@ div, span, a, ul, li, textarea, input, button {
text-align: left; text-align: left;
} }
.dropdown-menu:before {
border-bottom-color: #e2e2e2 !important;
}
input, input,
select, select,
textarea, textarea,

View File

@ -68,7 +68,7 @@
data-toggle="dropdown" title="Menu"><i data-toggle="dropdown" title="Menu"><i
class="icon-stackedit"></i>&nbsp;&nbsp;<b class="caret"></b></button> class="icon-stackedit"></i>&nbsp;&nbsp;<b class="caret"></b></button>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li><a href="viewer.html"><i class="icon-fullscreen"></i> <li><a href="viewer.html" title="Viewer"><i class="icon-fullscreen"></i>
Open in viewer</a></li> Open in viewer</a></li>
<li><a class="action-download-md" href="#"><i <li><a class="action-download-md" href="#"><i
class="icon-download-alt"></i> Save as Markdown</a></li> class="icon-download-alt"></i> Save as Markdown</a></li>
@ -259,7 +259,7 @@
<p class="msg-sync-list hide muted"><b>NOTE:</b> Removing a <p class="msg-sync-list hide muted"><b>NOTE:</b> Removing a
synchronized location will not delete any file.</p> synchronized location will not delete any file.</p>
<p class="msg-no-sync hide">"<span class="file-title"></span>" is <p class="msg-no-sync hide">"<span class="file-title"></span>" is
not synchronized. not synchronized yet.
</p> </p>
<p>Add a synchronized location manually:</p> <p>Add a synchronized location manually:</p>
<div class="input-prepend input-append"> <div class="input-prepend input-append">
@ -446,7 +446,7 @@
</p> </p>
<div id="manage-publish-list"></div> <div id="manage-publish-list"></div>
<p class="msg-no-publish hide">"<span class="file-title"></span>" <p class="msg-no-publish hide">"<span class="file-title"></span>"
is not published. is not published yet.
</p> </p>
<blockquote class="muted"> <blockquote class="muted">
<b>NOTE:</b> You can add locations using "Publish on" sub-menu. <b>NOTE:</b> You can add locations using "Publish on" sub-menu.

View File

@ -163,28 +163,31 @@
// Each call to init creates a new instance of Markdown.Extra so it's // Each call to init creates a new instance of Markdown.Extra so it's
// safe to have multiple converters, with different options, on a single page // safe to have multiple converters, with different options, on a single page
var extra = new Markdown.Extra(); var extra = new Markdown.Extra();
var transformations = []; var postNormalizationTransformations = [];
var preBlockGamutTransformations = [];
options = options || {}; options = options || {};
options.extensions = options.extensions || ["all"]; options.extensions = options.extensions || ["all"];
if (contains(options.extensions, "all")) { if (contains(options.extensions, "all"))
transformations.push("all"); options.extensions = ["tables", "fenced_code_gfm", "def_list", "attr_list"];
extra.attributeBlocks = true; if (contains(options.extensions, "tables"))
} else { preBlockGamutTransformations.push("tables");
if (contains(options.extensions, "tables")) if (contains(options.extensions, "fenced_code_gfm"))
transformations.push("tables"); postNormalizationTransformations.push("fencedCodeBlocks");
if (contains(options.extensions, "fenced_code_gfm")) if (contains(options.extensions, "def_list"))
transformations.push("fencedCodeBlocks"); preBlockGamutTransformations.push("definitionLists");
if (contains(options.extensions, "def_list")) if (contains(options.extensions, "attr_list"))
transformations.push("definitionLists");
if (contains(options.extensions, "attr_list"))
extra.attributeBlocks = true; extra.attributeBlocks = true;
}
converter.hooks.chain("postNormalization", function(text) {
return extra.doTransform(postNormalizationTransformations, text);
});
// 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) {
return extra.doConversion(transformations, text); return extra.doConversion(preBlockGamutTransformations, text);
}); });
converter.hooks.chain("postConversion", function(text) { converter.hooks.chain("postConversion", function(text) {
@ -209,19 +212,27 @@
return extra; return extra;
}; };
// Do transformations
Markdown.Extra.prototype.doTransform = function(transformations, text) {
if (this.attributeBlocks)
text = this.hashFcbAttributeBlocks(text);
for(var i = 0; i < transformations.length; i++)
text = this[transformations[i]](text);
return text + '\n';
};
// Setup state vars, do conversion // Setup state vars, do conversion
Markdown.Extra.prototype.doConversion = function(transformations, text) { Markdown.Extra.prototype.doConversion = function(transformations, text) {
text = processEscapes(text); text = processEscapes(text);
if (this.attributeBlocks) if (this.attributeBlocks)
text = this.hashAttributeBlocks(text); text = this.hashHeaderAttributeBlocks(text);
for(var i = 0; i < transformations.length; i++) return this.doTransform(transformations, text);
text = this[transformations[i]](text);
return text + '\n';
}; };
// Clear state vars that may use unnecessary memory. Unhash blocks we // Clear state vars that may use unnecessary memory. Unhash blocks we
// stored, apply attribute blocks if necessary, and return converted text. // stored, apply attribute blocks if necessary, and return converted text.
Markdown.Extra.prototype.finishConversion = function(text) { Markdown.Extra.prototype.finishConversion = function(text) {
@ -256,25 +267,40 @@
* Attribute Blocks * * Attribute Blocks *
*****************************************************************/ *****************************************************************/
// Extract attribute blocks, move them above the element they will be // Extract headers attribute blocks, move them above the element they will be
// applied to, and hash them for later. // applied to, and hash them for later.
Markdown.Extra.prototype.hashAttributeBlocks = function(text) { Markdown.Extra.prototype.hashHeaderAttributeBlocks = function(text) {
// TODO: use sentinels. Should we just add/remove them in doConversion?
// TODO: better matches for id / class attributes
var attrBlock = "\\{\\s*[.|#][^}]+\\}";
var hdrAttributesA = new RegExp("^(#{1,6}.*#{0,6})\\s+(" + attrBlock + ")[ \\t]*(\\n|0x03)", "gm");
var hdrAttributesB = new RegExp("^(.*)\\s+(" + attrBlock + ")[ \\t]*\\n" +
"(?=[\\-|=]+\\s*(\\n|0x03))", "gm"); // underline lookahead
var self = this;
function attributeCallback(wholeMatch, pre, attr) {
return '<p>~XX' + (self.hashBlocks.push(attr) - 1) + 'XX</p>\n' + pre + "\n";
}
text = text.replace(hdrAttributesA, attributeCallback); // ## headers
text = text.replace(hdrAttributesB, attributeCallback); // underline headers
return text;
};
// Extract FCB attribute blocks, move them above the element they will be
// applied to, and hash them for later.
Markdown.Extra.prototype.hashFcbAttributeBlocks = function(text) {
// TODO: use sentinels. Should we just add/remove them in doConversion? // TODO: use sentinels. Should we just add/remove them in doConversion?
// TODO: better matches for id / class attributes // TODO: better matches for id / class attributes
var attrBlock = "\\{\\s*[.|#][^}]+\\}"; var attrBlock = "\\{\\s*[.|#][^}]+\\}";
var hdrAttributesA = new RegExp("^(#{1,6}.*#{0,6})\\s+(" + attrBlock + ")[ \\t]*(\\n|0x03)", "gm");
var hdrAttributesB = new RegExp("^(.*)\\s+(" + attrBlock + ")[ \\t]*\\n" +
"(?=[\\-|=]+\\s*(\\n|0x03))", "gm"); // underline lookahead
var fcbAttributes = new RegExp("^(```[^{]*)\\s+(" + attrBlock + ")[ \\t]*\\n" + var fcbAttributes = new RegExp("^(```[^{]*)\\s+(" + attrBlock + ")[ \\t]*\\n" +
"(?=([\\s\\S]*?)\\n```\\s*(\\n|0x03))", "gm"); "(?=([\\s\\S]*?)\\n```\\s*(\\n|0x03))", "gm");
var self = this; var self = this;
function attributeCallback(wholeMatch, pre, attr) { function attributeCallback(wholeMatch, pre, attr) {
return '<p>~XX' + (self.hashBlocks.push(attr) - 1) + 'XX</p>\n' + pre + "\n"; return '<p>~XX' + (self.hashBlocks.push(attr) - 1) + 'XX</p>\n' + pre + "\n";
} }
text = text.replace(hdrAttributesA, attributeCallback); // ## headers
text = text.replace(hdrAttributesB, attributeCallback); // underline headers
return text.replace(fcbAttributes, attributeCallback); return text.replace(fcbAttributes, attributeCallback);
}; };
@ -467,13 +493,6 @@
return text; return text;
}; };
Markdown.Extra.prototype.all = function(text) {
text = this.tables(text);
text = this.fencedCodeBlocks(text);
text = this.definitionLists(text);
return text;
};
/****************************************************************** /******************************************************************
* Definition Lists * * Definition Lists *

View File

@ -65,7 +65,7 @@ define(
// Useful function for input control // Useful function for input control
function inputError(element, event) { function inputError(element, event) {
element.stop(true, true).addClass("error").delay(400).switchClass("error"); element.stop(true, true).addClass("error").delay(800).switchClass("error");
if(event !== undefined) { if(event !== undefined) {
event.stopPropagation(); event.stopPropagation();
} }
@ -370,7 +370,7 @@ define(
var editorScrollTop = editorElt.scrollTop(); var editorScrollTop = editorElt.scrollTop();
var previewElt = $("#wmd-preview"); var previewElt = $("#wmd-preview");
var previewScrollTop = previewElt.scrollTop(); var previewScrollTop = previewElt.scrollTop();
function animate(srcScrollTop, srcSectionList, destElt, destSectionList) { function animate(srcScrollTop, srcSectionList, destElt, destSectionList, callback) {
// Find the section corresponding to the offset // Find the section corresponding to the offset
var sectionIndex = undefined; var sectionIndex = undefined;
var srcSection = _.find(srcSectionList, function(section, index) { var srcSection = _.find(srcSectionList, function(section, index) {
@ -385,19 +385,22 @@ define(
var destSection = destSectionList[sectionIndex]; var destSection = destSectionList[sectionIndex];
var destScrollTop = destSection.startOffset + destSection.height * posInSection; var destScrollTop = destSection.startOffset + destSection.height * posInSection;
destScrollTop = _.min([destScrollTop, destElt.prop('scrollHeight') - destElt.outerHeight()]); destScrollTop = _.min([destScrollTop, destElt.prop('scrollHeight') - destElt.outerHeight()]);
destElt.animate({scrollTop: destScrollTop}, 800, function() { destElt.animate({scrollTop: destScrollTop}, 600, callback);
lastEditorScrollTop = editorElt.scrollTop();
lastPreviewScrollTop = previewElt.scrollTop();
});
return destScrollTop; return destScrollTop;
} }
if(Math.abs(editorScrollTop - lastEditorScrollTop) > 5) { if(Math.abs(editorScrollTop - lastEditorScrollTop) > 5) {
previewScrollTop = animate(editorScrollTop, mdSectionList, previewElt, htmlSectionList); lastEditorScrollTop = editorScrollTop;
previewScrollTop = animate(editorScrollTop, mdSectionList, previewElt, htmlSectionList, function() {
lastPreviewScrollTop = previewElt.scrollTop();
});
} }
else if(Math.abs(previewScrollTop - lastPreviewScrollTop) > 5) { else if(Math.abs(previewScrollTop - lastPreviewScrollTop) > 5) {
editorScrollTop = animate(previewScrollTop, htmlSectionList, editorElt, mdSectionList); lastPreviewScrollTop = previewScrollTop;
editorScrollTop = animate(previewScrollTop, htmlSectionList, editorElt, mdSectionList, function() {
lastEditorScrollTop = editorElt.scrollTop();
});
} }
}, 1000); }, 600);
// Create the layout // Create the layout
var layout = undefined; var layout = undefined;

44
js/main-min.js vendored

File diff suppressed because one or more lines are too long