Skip to content

Commit

Permalink
Merge pull request #52 from smeijer/feature/refactor
Browse files Browse the repository at this point in the history
Feature/refactor
  • Loading branch information
omnidan authored Jul 21, 2017
2 parents 685312e + 67d5410 commit 62e7126
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 34 deletions.
86 changes: 52 additions & 34 deletions lib/emoji.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,33 @@
/*jslint node: true*/
var toArray = require('lodash.toarray');
var emojiByName = require('./emoji.json');

"use strict";

/**
* regex to parse emoji in a string - finds emoji, e.g. :coffee:
*/
var parser = /:([a-zA-Z0-9_\-\+]+):/g;
var emojiNameRegex = /:([a-zA-Z0-9_\-\+]+):/g;

/**
* Removes colons on either side
* of the string if present
* @param {string} str
* @return {string}
*/
var trim = function(str) {
var stripColons = function(str) {
var colonIndex = str.indexOf(':');
if (colonIndex > -1) {
// :emoji: (http://www.emoji-cheat-sheet.com/)
if (colonIndex === str.length - 1) {
str = str.substring(0, colonIndex);
return trim(str);
return stripColons(str);
} else {
str = str.substr(colonIndex + 1);
return trim(str);
return stripColons(str);
}
}

return str;
}

Expand All @@ -36,16 +38,45 @@ var trim = function(str) {
* @return {string}
*/
var wrapColons = function(str) {
return (str && str.length > 0) ? ':' + str + ':' : '';
return (typeof str === 'string' && str.length > 0) ? ':' + str + ':' : str;
}

/**
* Ensure that the word is wrapped in colons
* by only adding them, if they are not there.
* @param {string} str
* @return {string}
*/
var ensureColons = function(str) {
return (typeof str === 'string' && str[0] !== ':') ? wrapColons(str) : str;
}

// Non spacing mark, some emoticons have them. It's the 'Variant Form',
// which provides more information so that emoticons can be rendered as
// more colorful graphics. FE0E is a unicode text version, where as FE0F
// should be rendered as a graphical version. The code gracefully degrades.
var NON_SPACING_MARK = String.fromCharCode(65039); // 65039 - '️' - 0xFE0F;
var nonSpacingRegex = new RegExp(NON_SPACING_MARK, 'g')

// Remove the non-spacing-mark from the code, never send a stripped version
// to the client, as it kills graphical emoticons.
var stripNSB = function(code) {
return code.replace(nonSpacingRegex, '');
};

// Reversed hash table, where as emojiByName contains a { heart: '❤' }
// dictionary emojiByCode contains { ❤: 'heart' }. The codes are normalized
// to the text version.
var emojiByCode = Object.keys(emojiByName).reduce(function(h,k) {
h[stripNSB(emojiByName[k])] = k;
return h;
}, {});

/**
* Emoji namespace
*/
var Emoji = module.exports = {
emoji: require('./emoji.json')
var Emoji = {
emoji: emojiByName,
};

/**
Expand All @@ -54,10 +85,11 @@ var Emoji = module.exports = {
* @return {string}
*/
Emoji._get = function _get(emoji) {
if (Emoji.emoji.hasOwnProperty(emoji)) {
return Emoji.emoji[emoji];
if (emojiByName.hasOwnProperty(emoji)) {
return emojiByName[emoji];
}
return wrapColons(emoji);

return ensureColons(emoji);
};

/**
Expand All @@ -66,7 +98,7 @@ Emoji._get = function _get(emoji) {
* @return {string}
*/
Emoji.get = function get(emoji) {
emoji = trim(emoji);
emoji = stripColons(emoji);

return Emoji._get(emoji);
};
Expand All @@ -78,20 +110,8 @@ Emoji.get = function get(emoji) {
* @return {string}
*/
Emoji.which = function which(emoji_code, includeColons) {
var word = emojiToCode[emoji_code];
if (word) {
return includeColons ? wrapColons(word) : word;
}

// Most of the times, the word is already returned by now. Sometimes
// we need to handle the non-spacing-mark. If we haven't returned yet,
// we're going to try the oposite version, with or without the mark.
var endsWithMark = emoji_code[emoji_code.length - 1] === NON_SPACING_MARK;
var alias = endsWithMark
? emoji_code.substr(0, emoji_code.length - 1)
: emoji_code + NON_SPACING_MARK;

word = emojiToCode[alias];
var code = stripNSB(emoji_code);
var word = emojiByCode[code];

return includeColons ? wrapColons(word) : word;
};
Expand All @@ -106,7 +126,7 @@ Emoji.which = function which(emoji_code, includeColons) {
Emoji.emojify = function emojify(str, on_missing, format) {
if (!str) return '';

return str.split(parser) // parse emoji via regex
return str.split(emojiNameRegex) // parse emoji via regex
.map(function parseEmoji(s, i) {
// every second element is an emoji, e.g. "test :fast_forward:" -> [ "test ", "fast_forward" ]
if (i % 2 === 0) return s;
Expand All @@ -132,11 +152,11 @@ Emoji.emojify = function emojify(str, on_missing, format) {
* @return {string}
*/
Emoji.random = function random() {
var emojiKeys = Object.keys(Emoji.emoji);
var emojiKeys = Object.keys(emojiByName);
var randomIndex = Math.floor(Math.random() * emojiKeys.length);
var key = emojiKeys[randomIndex];
var emoji = Emoji._get(key);
return {key: key, emoji: emoji};
return { key: key, emoji: emoji };
}

/**
Expand All @@ -145,8 +165,8 @@ Emoji.random = function random() {
* @return {Array.<Object>}
*/
Emoji.search = function search(str) {
var emojiKeys = Object.keys(Emoji.emoji);
var matcher = trim(str)
var emojiKeys = Object.keys(emojiByName);
var matcher = stripColons(str)
var matchingKeys = emojiKeys.filter(function(key) {
return key.toString().indexOf(matcher) === 0;
});
Expand All @@ -158,10 +178,6 @@ Emoji.search = function search(str) {
});
}

var emojiToCode = Object.keys(Emoji.emoji).reduce(function(h,k) {
return h[Emoji.emoji[k]] = k, h;
}, {});

/**
* unemojify a string (replace emoji with :emoji:)
* @param {string} str
Expand All @@ -175,3 +191,5 @@ Emoji.unemojify = function unemojify(str) {
return Emoji.which(word, true) || word;
}).join('');
};

module.exports = Emoji;
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"coverage": "./node_modules/.bin/istanbul cover _mocha test",
"emojiparse": "node lib/emojiparse.js",
"test": "./node_modules/.bin/mocha --require should --bail --reporter spec test/*",
"watch": "./node_modules/.bin/mocha --require should --bail --reporter spec test/* --watch",
"prepublish": "npm run test"
},
"main": "index.js",
Expand Down

0 comments on commit 62e7126

Please sign in to comment.