From ed6e2b1d79ed8ef7fef675876ba781a37deb6576 Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Mon, 14 Apr 2014 16:51:18 -0400 Subject: [PATCH] Remove Zalgo API from `Discourse.Mention`: http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony - Thanks @riking for finding it. --- .../discourse/dialects/mention_dialect.js | 4 +- .../javascripts/discourse/lib/mention.js | 86 ++++++++++--------- .../discourse/views/composer/composer_view.js | 2 +- test/javascripts/lib/markdown_test.js | 4 +- test/javascripts/mdtest/mdtest.js.erb | 2 +- 5 files changed, 52 insertions(+), 46 deletions(-) diff --git a/app/assets/javascripts/discourse/dialects/mention_dialect.js b/app/assets/javascripts/discourse/dialects/mention_dialect.js index 55687257bc1..0e13d02637c 100644 --- a/app/assets/javascripts/discourse/dialects/mention_dialect.js +++ b/app/assets/javascripts/discourse/dialects/mention_dialect.js @@ -10,9 +10,9 @@ Discourse.Dialect.inlineRegexp({ emitter: function(matches) { var username = matches[1], - mentionLookup = this.dialect.options.mentionLookup || Discourse.Mention.lookupCache; + mentionLookup = this.dialect.options.mentionLookup; - if (mentionLookup(username.substr(1))) { + if (mentionLookup && mentionLookup(username.substr(1))) { return ['a', {'class': 'mention', href: Discourse.getURL("/users/") + username.substr(1).toLowerCase()}, username]; } else { return ['span', {'class': 'mention'}, username]; diff --git a/app/assets/javascripts/discourse/lib/mention.js b/app/assets/javascripts/discourse/lib/mention.js index bc8b6edc834..7668d7bbc93 100644 --- a/app/assets/javascripts/discourse/lib/mention.js +++ b/app/assets/javascripts/discourse/lib/mention.js @@ -1,53 +1,59 @@ + +// A local cache lookup +var localCache = []; + + /** - Helps us determine whether someone has been mentioned by looking up their username. + Lookup a username and return whether it is exists or not. + + @function lookup + @param {String} username to look up + @return {Promise} promise that results to whether the name was found or not +**/ +function lookup(username) { + return new Em.RSVP.Promise(function (resolve) { + var cached = localCache[username]; + + // If we have a cached answer, return it + if (typeof cached !== "undefined") { + resolve(cached); + } else { + Discourse.ajax("/users/is_local_username", { data: { username: username } }).then(function(r) { + localCache[username] = r.valid; + resolve(r.valid); + }); + } + }); +} + +/** + Help us link directly to a mentioned user's profile if the username exists. @class Mention @namespace Discourse @module Discourse **/ -Discourse.Mention = (function() { - var localCache = {}; +Discourse.Mention = { - var cache = function(name, valid) { - localCache[name] = valid; - }; + /** + Paints an element in the DOM with the appropriate classes and markup if the username + it is mentioning exists. - var lookupCache = function(name) { - return localCache[name]; - }; - - var lookup = function(name, callback) { - var cached = lookupCache(name); - if (cached === true || cached === false) { - callback(cached); - return false; - } else { - Discourse.ajax("/users/is_local_username", { data: { username: name } }).then(function(r) { - cache(name, r.valid); - callback(r.valid); - }); - return true; - } - }; - - var load = function(e) { + @method paint + @param {Element} the element in the DOM to decorate + **/ + paint: function(e) { var $elem = $(e); if ($elem.data('mention-tested')) return; - var username = $elem.text(); - username = username.substr(1); - var loading = lookup(username, function(valid) { - if (valid) { - return $elem.replaceWith("@" + username + ""); + var username = $elem.text().substr(1); + + $elem.addClass('mention-loading'); + lookup(username).then(function(found) { + if (found) { + $elem.replaceWith("@" + username + ""); } else { - return $elem.removeClass('mention-loading').addClass('mention-tested'); + $elem.removeClass('mention-loading').addClass('mention-tested'); } }); - if (loading) { - return $elem.addClass('mention-loading'); - } - }; - - return { load: load, lookup: lookup, lookupCache: lookupCache }; -})(); - - + } +}; diff --git a/app/assets/javascripts/discourse/views/composer/composer_view.js b/app/assets/javascripts/discourse/views/composer/composer_view.js index ad3080ff633..90e9ef8c9e0 100644 --- a/app/assets/javascripts/discourse/views/composer/composer_view.js +++ b/app/assets/javascripts/discourse/views/composer/composer_view.js @@ -157,7 +157,7 @@ Discourse.ComposerView = Discourse.View.extend(Ember.Evented, { Discourse.Onebox.load(e, refresh); }); $('span.mention', $wmdPreview).each(function(i, e) { - Discourse.Mention.load(e, refresh); + Discourse.Mention.paint(e); }); this.trigger('previewRefreshed', $wmdPreview); diff --git a/test/javascripts/lib/markdown_test.js b/test/javascripts/lib/markdown_test.js index ec18c80a2d1..e46ebc946e1 100644 --- a/test/javascripts/lib/markdown_test.js +++ b/test/javascripts/lib/markdown_test.js @@ -5,7 +5,7 @@ module("Discourse.Markdown", { }); var cooked = function(input, expected, text) { - var result = Discourse.Markdown.cook(input, {mentionLookup: false, sanitize: true}); + var result = Discourse.Markdown.cook(input, {sanitize: true}); equal(result, expected, text); }; @@ -243,7 +243,7 @@ test("Heading", function() { test("Oneboxing", function() { var matches = function(input, regexp) { - return Discourse.Markdown.cook(input, {mentionLookup: false }).match(regexp); + return Discourse.Markdown.cook(input).match(regexp); }; ok(!matches("- http://www.textfiles.com/bbs/MINDVOX/FORUMS/ethics\n\n- http://drupal.org", /onebox/), diff --git a/test/javascripts/mdtest/mdtest.js.erb b/test/javascripts/mdtest/mdtest.js.erb index b5d7c8632ee..5bf4c22fe05 100644 --- a/test/javascripts/mdtest/mdtest.js.erb +++ b/test/javascripts/mdtest/mdtest.js.erb @@ -14,7 +14,7 @@ function normalize(str) { } var md = function(input, expected, text) { - var result = Discourse.Markdown.cook(input, {mentionLookup: false, sanitize: true, traditional_markdown_linebreaks: true}), + var result = Discourse.Markdown.cook(input, {sanitize: true, traditional_markdown_linebreaks: true}), resultNorm = normalize(result), expectedNorm = normalize(expected), same = (result === expected) || (resultNorm === expectedNorm);