mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-12-11 00:02:05 -05:00
177 lines
5.6 KiB
Text
177 lines
5.6 KiB
Text
(function() {
|
|
var emoji = <%= Dir.glob(File.expand_path("../../../public/images/*.png", __FILE__)).map{|f| File.basename(f).split(".")[0]}.inspect %>;
|
|
|
|
var _extendedEmoji = {};
|
|
Discourse.Dialect.registerEmoji = function(code, url) {
|
|
_extendedEmoji[code] = url;
|
|
};
|
|
|
|
function imageFor(code) {
|
|
if (emoji.indexOf(code) !== -1) {
|
|
var url = Discourse.getURL('/plugins/emoji/images/' + code + '.png');
|
|
return ['img', {href: url, title: ':' + code + ':', 'class': 'emoji', alt: code}];
|
|
} else {
|
|
var url = _extendedEmoji[code];
|
|
if (url) {
|
|
return ['img', {href: url, title: ':' + code + ':', 'class': 'emoji', alt: code}];
|
|
}
|
|
}
|
|
}
|
|
|
|
// Also support default emotions
|
|
var translations = {
|
|
':)' : 'smile',
|
|
':-)' : 'smile',
|
|
':(' : 'frowning',
|
|
':-(' : 'frowning',
|
|
';)' : 'wink',
|
|
';-)' : 'wink',
|
|
':\'(' : 'cry',
|
|
':\'-(' : 'cry',
|
|
':-\'(' : 'cry',
|
|
':p' : 'stuck_out_tongue',
|
|
':P' : 'stuck_out_tongue',
|
|
':-P' : 'stuck_out_tongue',
|
|
':O' : 'open_mouth',
|
|
':-O' : 'open_mouth',
|
|
':D' : 'smiley',
|
|
':-D' : 'smiley',
|
|
':|' : 'expressionless',
|
|
':-|' : 'expressionless',
|
|
";P" : 'stuck_out_tongue_winking_eye',
|
|
";-P" : 'stuck_out_tongue_winking_eye',
|
|
';)' : 'wink',
|
|
';-)' : 'wink',
|
|
":$" : 'blush',
|
|
":-$" : 'blush'
|
|
};
|
|
|
|
function checkPrev(prev) {
|
|
if (prev && prev.length) {
|
|
var lastToken = prev[prev.length-1];
|
|
if (lastToken && lastToken.charAt) {
|
|
var lastChar = lastToken.charAt(lastToken.length-1);
|
|
if (lastChar !== ' ' && lastChar !== "\n") return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
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 (token, match, prev) {
|
|
if (!Discourse.SiteSettings.enable_emoji) { return token; }
|
|
return checkPrev(prev) ? imageFor(replacement) : token;
|
|
});
|
|
}
|
|
});
|
|
|
|
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) {
|
|
if (!Discourse.SiteSettings.enable_emoji) { return; }
|
|
|
|
var endPos = text.indexOf(':', 1),
|
|
firstSpace = text.search(/\s/),
|
|
contents;
|
|
|
|
if (!checkPrev(prev)) { return; }
|
|
|
|
// If there is no trailing colon, check our translations that begin with colons
|
|
if (endPos === -1 || (firstSpace !== -1 && endPos > firstSpace)) {
|
|
translationColonRegexp.lastIndex = 0;
|
|
var m = translationColonRegexp.exec(text);
|
|
if (m && m[0] && text.indexOf(m[0]) === 0) {
|
|
|
|
// Check outer edge
|
|
var lastChar = text.charAt(m[0].length);
|
|
if (lastChar && (lastChar !== ' ' && lastChar !== "\n")) return;
|
|
contents = imageFor(translationsWithColon[m[0]]);
|
|
if (contents) {
|
|
return [m[0].length, contents];
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Simple find and replace from our array
|
|
var between = text.slice(1, endPos);
|
|
contents = imageFor(between);
|
|
if (contents) {
|
|
return [endPos+1, contents];
|
|
}
|
|
});
|
|
|
|
// TODO: Make this a proper ES6 import
|
|
var ComposerView = (Discourse && Discourse.ComposerView) || (typeof require !== "undefined" && require('discourse/views/composer').default);
|
|
if (ComposerView) {
|
|
ComposerView.on("initWmdEditor", function(event){
|
|
if (!Discourse.SiteSettings.enable_emoji) { return; }
|
|
|
|
var baseUrl = Discourse.getURL("/");
|
|
|
|
template = Handlebars.compile("<div class='autocomplete'>" +
|
|
"<ul>" +
|
|
"{{#each options}}" +
|
|
"<li>" +
|
|
"<a href='#'>" +
|
|
"<img src='" + baseUrl + "plugins/emoji/images/{{this}}.png?v=1' class='emoji'> " +
|
|
"{{this}}</a>" +
|
|
"</li>" +
|
|
"{{/each}}" +
|
|
"</ul>" +
|
|
"</div>");
|
|
|
|
$('#wmd-input').autocomplete({
|
|
template: template,
|
|
key: ":",
|
|
transformComplete: function(v){ return v + ":"; },
|
|
dataSource: function(term){
|
|
|
|
var full = ":" + term;
|
|
term = term.toLowerCase();
|
|
|
|
if (term === "") {
|
|
return Ember.RSVP.resolve(["smile", "smiley", "wink", "sunny", "blush"]);
|
|
}
|
|
|
|
if (translations[full]) {
|
|
return Ember.RSVP.resolve([translations[full]]);
|
|
}
|
|
|
|
var options = [];
|
|
var i;
|
|
for (i=0; i < emoji.length; i++) {
|
|
if (emoji[i].indexOf(term) === 0) {
|
|
options.push(emoji[i]);
|
|
if(options.length > 4) { break; }
|
|
}
|
|
}
|
|
|
|
if (options.length <= 4) {
|
|
for (i=0; i < emoji.length; i++) {
|
|
if (emoji[i].indexOf(term) > 0) {
|
|
options.push(emoji[i]);
|
|
if(options.length > 4) { break; }
|
|
}
|
|
}
|
|
}
|
|
|
|
return Ember.RSVP.resolve(options);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
Discourse.Markdown.whiteListTag('img', 'class', 'emoji');
|
|
}).call(this);
|