Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

node-emoji

Package Overview
Dependencies
Maintainers
1
Versions
31
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

node-emoji - npm Package Compare versions

Comparing version 1.7.0 to 1.8.0

185

lib/emoji.js
/*jslint node: true*/
require('string.prototype.codepointat');
var toArray = require('lodash.toarray');
var emojiByName = require('./emoji.json');

@@ -10,3 +10,3 @@ "use strict";

*/
var parser = /:([a-zA-Z0-9_\-\+]+):/g;
var emojiNameRegex = /:([a-zA-Z0-9_\-\+]+):/g;

@@ -19,3 +19,3 @@ /**

*/
var trim = function(str) {
function stripColons (str) {
var colonIndex = str.indexOf(':');

@@ -26,15 +26,58 @@ if (colonIndex > -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;
}
/**
* Adds colons to either side
* of the string
* @param {string} str
* @return {string}
*/
function wrapColons (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}
*/
function ensureColons (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.
function stripNSB (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,
};

@@ -47,7 +90,8 @@

*/
Emoji._get = function _get(emoji) {
if (Emoji.emoji.hasOwnProperty(emoji)) {
return Emoji.emoji[emoji];
Emoji._get = function _get (emoji) {
if (emojiByName.hasOwnProperty(emoji)) {
return emojiByName[emoji];
}
return ':' + emoji + ':';
return ensureColons(emoji);
};

@@ -60,4 +104,4 @@

*/
Emoji.get = function get(emoji) {
emoji = trim(emoji);
Emoji.get = function get (emoji) {
emoji = stripColons(emoji);

@@ -68,14 +112,76 @@ return Emoji._get(emoji);

/**
* find the emoji by either code or name
* @param {string} nameOrCode The emoji to find, either `coffee`, `:coffee:` or `☕`;
* @return {object}
*/
Emoji.find = function find (nameOrCode) {
return Emoji.findByName(nameOrCode) || Emoji.findByCode(nameOrCode);
};
/**
* find the emoji by name
* @param {string} name The emoji to find either `coffee` or `:coffee:`;
* @return {object}
*/
Emoji.findByName = function findByName (name) {
var stripped = stripColons(name);
var emoji = emojiByName[stripped];
return emoji ? ({ emoji: emoji, key: stripped }) : undefined;
};
/**
* find the emoji by code (emoji)
* @param {string} code The emoji to find; for example `☕` or `☔`
* @return {object}
*/
Emoji.findByCode = function findByCode (code) {
var stripped = stripNSB(code);
var name = emojiByCode[stripped];
// lookup emoji to ensure the Variant Form is returned
return name ? ({ emoji: emojiByName[name], key: name }) : undefined;
};
/**
* Check if an emoji is known by this library
* @param {string} nameOrCode The emoji to validate, either `coffee`, `:coffee:` or `☕`;
* @return {object}
*/
Emoji.hasEmoji = function hasEmoji (nameOrCode) {
return Emoji.hasEmojiByName(nameOrCode) || Emoji.hasEmojiByCode(nameOrCode);
};
/**
* Check if an emoji with given name is known by this library
* @param {string} name The emoji to validate either `coffee` or `:coffee:`;
* @return {object}
*/
Emoji.hasEmojiByName = function hasEmojiByName (name) {
var result = Emoji.findByName(name);
return !!result && result.key === stripColons(name);
};
/**
* Check if a given emoji is known by this library
* @param {string} code The emoji to validate; for example `☕` or `☔`
* @return {object}
*/
Emoji.hasEmojiByCode = function hasEmojiByCode (code) {
var result = Emoji.findByCode(code);
return !!result && stripNSB(result.emoji) === stripNSB(code);
};
/**
* get emoji name from code
* @param {string} emoji_code
* @param {string} emoji
* @param {boolean} includeColons should the result include the ::
* @return {string}
*/
Emoji.which = function which(emoji_code) {
for (var prop in Emoji.emoji) {
if (Emoji.emoji.hasOwnProperty(prop)) {
if (Emoji.emoji[prop].codePointAt() === emoji_code.codePointAt()) {
return prop;
}
}
}
Emoji.which = function which (emoji_code, includeColons) {
var code = stripNSB(emoji_code);
var word = emojiByCode[code];
return includeColons ? wrapColons(word) : word;
};

@@ -90,6 +196,6 @@

*/
Emoji.emojify = function emojify(str, on_missing, format) {
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) {

@@ -99,8 +205,9 @@ // every second element is an emoji, e.g. "test :fast_forward:" -> [ "test ", "fast_forward" ]

var emoji = Emoji._get(s);
var isMissing = emoji.indexOf(':') > -1;
if (emoji.indexOf(':') > -1 && typeof on_missing === 'function') {
if (isMissing && typeof on_missing === 'function') {
return on_missing(emoji.substr(1, emoji.length-2));
}
if (typeof format === 'function') {
if (!isMissing && typeof format === 'function') {
return format(emoji, s);

@@ -119,8 +226,8 @@ }

*/
Emoji.random = function random() {
var emojiKeys = Object.keys(Emoji.emoji);
Emoji.random = function random () {
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 };
}

@@ -133,5 +240,5 @@

*/
Emoji.search = function search(str) {
var emojiKeys = Object.keys(Emoji.emoji);
var matcher = trim(str)
Emoji.search = function search (str) {
var emojiKeys = Object.keys(emojiByName);
var matcher = stripColons(str)
var matchingKeys = emojiKeys.filter(function(key) {

@@ -148,6 +255,2 @@ return key.toString().indexOf(matcher) === 0;

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

@@ -158,3 +261,3 @@ * unemojify a string (replace emoji with :emoji:)

*/
Emoji.unemojify = function unemojify(str) {
Emoji.unemojify = function unemojify (str) {
if (!str) return '';

@@ -164,8 +267,6 @@ var words = toArray(str);

return words.map(function(word) {
var emoji_text = emojiToCode[word];
if (emoji_text) {
return ':'+emoji_text+':';
}
return word;
return Emoji.which(word, true) || word;
}).join('');
};
module.exports = Emoji;
{
"name": "node-emoji",
"version": "1.7.0",
"version": "1.8.0",
"description": "simple emoji support for node.js projects",

@@ -26,4 +26,3 @@ "author": "Daniel Bugl <daniel.bugl@touchlay.com>",

"dependencies": {
"lodash.toarray": "^4.4.0",
"string.prototype.codepointat": "^0.2.0"
"lodash.toarray": "^4.4.0"
},

@@ -39,2 +38,3 @@ "devDependencies": {

"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"

@@ -41,0 +41,0 @@ },

@@ -26,2 +26,6 @@ # node-emoji

emoji.unemojify('I ❤️ 🍕') // replaces the actual emoji with :emoji:, in this case: returns "I :heart: :pizza:"
emoji.find('🍕'); // Find the `pizza` emoji, and returns `({ emoji: '🍕', key: 'pizza' })`;
emoji.find('pizza'); // Find the `pizza` emoji, and returns `({ emoji: '🍕', key: 'pizza' })`;
emoji.hasEmoji('🍕'); // Validate if this library knows an emoji like `🍕`
emoji.hasEmoji('pizza'); // Validate if this library knowns a emoji with the name `pizza`
```

@@ -73,3 +77,1 @@

* Bitcoin: [1J5eKsrAcPPLv5gPxSjSUkXnbJpkhndFgA](bitcoin:1J5eKsrAcPPLv5gPxSjSUkXnbJpkhndFgA)
![http://i.imgur.com/RgzXqGD.png](http://i.imgur.com/RgzXqGD.png)

@@ -40,2 +40,3 @@ /*jslint node: true*/

});
it("should work for differently formed characters", function () {

@@ -46,2 +47,3 @@ var umbrella = emoji.which('☔');

});
it("should return the same name for differently formed characters", function () {

@@ -54,2 +56,15 @@ var umbrella1 = emoji.which('☔');

});
it("should work for flags", function() {
var mexico = emoji.which('🇲🇽');
should.exists(mexico);
mexico.should.be.exactly('flag-mx');
var marocco = emoji.which('🇲🇦');
should.exists(marocco);
marocco.should.be.exactly('flag-ma');
// see issue #21
mexico.should.not.equal(marocco);
});
});

@@ -63,2 +78,9 @@

});
it("should handle flags correctly", function() {
var flags = emoji.emojify('Mexico :flag-mx: and Marocco :flag-ma: are not the same');
should.exists(flags);
flags.should.be.exactly('Mexico 🇲🇽 and Marocco 🇲🇦 are not the same');
});
it("should leave unknown emoji", function () {

@@ -78,3 +100,3 @@ var coffee = emoji.emojify('I :unknown_emoji: :star: :another_one:');

it("should wrap emoji using provided cb function", function () {
it("should wrap emoji using provided format function", function () {
var coffee = emoji.emojify('I :heart: :coffee:', null, function(code, name) {

@@ -87,2 +109,25 @@ return '<img alt="' + code + '" src="' + name + '.png" />';

});
it("should not wrap unknown using provided format function", function () {
var coffee = emoji.emojify('I :unknown_emoji: :coffee:', null, function(code, name) {
return '<img alt="' + code + '" src="' + name + '.png" />';
});
should.exist(coffee);
coffee.should.be.exactly('I :unknown_emoji: <img alt="☕️" src="coffee.png" />');
});
it("should replace unknown emojis and wrap known emojis using cb functions", function () {
var coffee = emoji.emojify('I :unknown_emoji: :coffee:',
function(name) {
return name;
},
function(code, name) {
return '<img alt="' + code + '" src="' + name + '.png" />';
}
);
should.exist(coffee);
coffee.should.be.exactly('I unknown_emoji <img alt="☕️" src="coffee.png" />');
});
});

@@ -146,4 +191,67 @@

coffee.should.be.exactly('I love :woman-kiss-woman:');
});
it("should parse flags correctly", function () {
var flags = emoji.unemojify('The flags of 🇲🇽 and 🇲🇦 are not the same');
should.exists(flags);
flags.should.be.exactly('The flags of :flag-mx: and :flag-ma: are not the same');
});
});
describe('find emoji', function() {
it('Should be able to find a emoji by :name:', function() {
var result = emoji.find(':heart:')
should.exists(result);
result.should.eql({ emoji: '❤️', key: 'heart' });
});
it('Should be able to find an emoji by name', function() {
var result = emoji.find('heart');
should.exists(result);
result.should.eql({ emoji: '❤️', key: 'heart' });
});
it('Should be able to find an emoji by code', function() {
var result = emoji.find('❤');
should.exists(result);
result.should.eql({ emoji: '❤️', key: 'heart' });
});
it('Should return `undefined` for unknown emojis', function() {
var result = emoji.find('unknown_emoji');
should.not.exists(result);
})
});
describe('hasEmoji', function() {
it('Should be able to check a emoji by :name:', function() {
var result = emoji.hasEmoji(':heart:');
result.should.equal(true)
});
it('Should be able to check a emoji by name', function() {
var result = emoji.hasEmoji('heart');
result.should.equal(true);
});
it('Should be able to check a emoji by code text form)', function() {
var result = emoji.hasEmoji('❤');
result.should.equal(true);
});
it('Should be able to check a emoji by code in variant form', function() {
var result = emoji.hasEmoji('❤️');
result.should.equal(true);
});
it('Should return false for unknown emoji names', function() {
var result = emoji.hasEmoji(':pizza-kiss-coffee:');
result.should.equal(false);
});
it('Should return false for unknown emoji codes', function() {
var result = emoji.hasEmoji('🍕❤️‍💋‍☕');
result.should.equal(false);
});
});
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc