FIX: Performance regression on Markdown renderer.

This commit is contained in:
Robin Ward 2013-11-08 11:42:26 -05:00
parent 630ef0f322
commit 127c3d0e21
2 changed files with 70 additions and 25 deletions

View File

@ -156,6 +156,18 @@ Discourse.Dialect = {
return html;
},
/**
Registers an inline replacer function
@method registerInline
@param {String} start The token the replacement begins with
@param {Function} fn The replacing function
**/
registerInline: function(start, fn) {
dialect.inline[start] = fn;
},
/**
The simplest kind of replacement possible. Replace a stirng token with JsonML.
@ -173,9 +185,9 @@ Discourse.Dialect = {
@param {Function} emitter A function that emits the JsonML for the replacement.
**/
inlineReplace: function(token, emitter) {
dialect.inline[token] = function(text, match, prev) {
this.registerInline(token, function(text, match, prev) {
return [token.length, emitter.call(this, token)];
};
});
},
/**
@ -205,7 +217,7 @@ Discourse.Dialect = {
@param {Boolean} [opts.spaceBoundary] If true, the match must be on a sppace boundary
**/
inlineRegexp: function(args) {
dialect.inline[args.start] = function(text, match, prev) {
this.registerInline(args.start, function(text, match, prev) {
if (invalidBoundary(args, prev)) { return; }
args.matcher.lastIndex = 0;
@ -216,7 +228,7 @@ Discourse.Dialect = {
return [m[0].length, result];
}
}
};
});
},
/**
@ -252,7 +264,7 @@ Discourse.Dialect = {
stop = args.stop || args.between,
startLength = start.length;
dialect.inline[start] = function(text, match, prev) {
this.registerInline(start, function(text, match, prev) {
if (invalidBoundary(args, prev)) { return; }
var endPos = text.indexOf(stop, startLength);
@ -269,7 +281,7 @@ Discourse.Dialect = {
if (contents) {
return [endPos+stop.length, contents];
}
};
});
},
/**

View File

@ -37,17 +37,50 @@
":-$" : 'blush'
};
emoji.forEach(function (e) {
Discourse.Dialect.inlineReplace(":" + e + ":", function(code) {
return imageFor(e);
});
var translationsWithColon = {};
Object.keys(translations).forEach(function (t) {
if (t[0] === ':') {
translationsWithColon[t] = translations[t];
} else {
var replacement = translations[t];
Discourse.Dialect.inlineReplace(t, function () {
return imageFor(replacement);
});
}
});
Object.keys(translations).forEach(function (code) {
var replacement = translations[code];
Discourse.Dialect.inlineReplace(code, function (code) {
return imageFor(replacement);
});
function escapeRegExp(s) {
return s.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')
}
var translationColonRegexp = new RegExp("^" +
Object.keys(translationsWithColon).map(function (t) {
return "(" + escapeRegExp(t) + ")";
}).join("|")
);
Discourse.Dialect.registerInline(':', function(text, match, prev) {
var endPos = text.indexOf(':', 1),
contents;
// If there is no trailing colon, check our translations that begin with colons
if (endPos === -1) {
translationColonRegexp.lastIndex = 0;
var match = translationColonRegexp.exec(text);
if (match && match[0]) {
contents = imageFor(translationsWithColon[match[0]]);
if (contents) {
return [match[0].length, contents];
}
}
}
// Simple find and replace from our array
var between = text.slice(1, endPos);
contents = imageFor(between);
if (contents) {
return [endPos+1, contents];
}
});
if (Discourse && Discourse.ComposerView) {
@ -56,16 +89,16 @@
var baseUrl = Discourse.getURL("/");
template = Handlebars.compile("<div class='autocomplete'>" +
"<ul>" +
"{{#each options}}" +
"<li>" +
"<a href='#'>" +
"<img src='" + baseUrl + "assets/emoji/{{this}}.png' class='emoji'> " +
"{{this}}</a>" +
"</li>" +
"{{/each}}" +
"</ul>" +
"</div>");
"<ul>" +
"{{#each options}}" +
"<li>" +
"<a href='#'>" +
"<img src='" + baseUrl + "assets/emoji/{{this}}.png' class='emoji'> " +
"{{this}}</a>" +
"</li>" +
"{{/each}}" +
"</ul>" +
"</div>");
$('#wmd-input').autocomplete({
template: template,