Skip to content

Commit 73c8681

Browse files
committed
Fix test and reimplement ignore_emoticons option
1 parent 9264e1e commit 73c8681

File tree

2 files changed

+96
-76
lines changed

2 files changed

+96
-76
lines changed

tests/spec/string.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,10 @@ JS.Test.describe('emojify used with flat strings', function() {
5959
});
6060

6161
this.describe('isolated cases', function() {
62-
this.it(':neckbeard:', function() {
63-
var text = ":neckbeard:";
62+
this.it(':necktie:', function() {
63+
var text = ":necktie:";
6464
var result = emojify.replace(text);
65-
this.assertEqual('<img align=\'absmiddle\' alt=\':neckbeard:\' class=\'emoji\' src=\'images/emoji/neckbeard.png\' title=\':neckbeard:\' />', result);
65+
this.assertEqual('<img align=\'absmiddle\' alt=\':necktie:\' class=\'emoji\' src=\'images/emoji/necktie.png\' title=\':necktie:\' />', result);
6666
});
6767

6868
this.it('inserts a <3 heart', function() {

v2/index.ts

Lines changed: 93 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ const emoticons = {
3939
/* :+1: */ thumbsup: /:\+1:/g,
4040
/* :-1: */ thumbsdown: /:\-1:/g,
4141
};
42+
const ignoreModeAvailableKeys = [
43+
'named', 'thumbsup', 'thumbsdown'
44+
]
4245
const emoticonsProcessed: [RegExp, string][] = Object.entries(emoticons).map(
4346
([key, value]) => [value, key],
4447
);
@@ -74,23 +77,6 @@ function isWhitespace(s: string) {
7477
);
7578
}
7679

77-
/* Given an regex match, return the name of the matching emoji */
78-
function getEmojiNameForMatch(match: RegExpMatchArray) {
79-
/* Special case for named emoji */
80-
if (match[1] && match[2]) {
81-
var named = match[2];
82-
if (namedMatchHash[named]) {
83-
return named;
84-
}
85-
return;
86-
}
87-
for (var i = 3; i < match.length - 1; i++) {
88-
if (match[i]) {
89-
return emoticonsProcessed[i - 2][1];
90-
}
91-
}
92-
}
93-
9480
type EmojifyConfig = {
9581
blacklist?: {
9682
ids: string[];
@@ -104,58 +90,6 @@ type EmojifyConfig = {
10490
mode?: keyof modeToElementTag;
10591
};
10692

107-
class Validator {
108-
lastEmojiTerminatedAt = -1;
109-
110-
validate(match: RegExpMatchArray, index: number, input: string) {
111-
var self = this;
112-
113-
/* Validator */
114-
var emojiName = getEmojiNameForMatch(match);
115-
if (!emojiName) {
116-
return;
117-
}
118-
119-
var m = match[0];
120-
var length = m.length;
121-
// var index = match.index;
122-
// var input = match.input;
123-
124-
function success() {
125-
self.lastEmojiTerminatedAt = length + index;
126-
return emojiName;
127-
}
128-
129-
/* At the beginning? */
130-
if (index === 0) {
131-
return success();
132-
}
133-
134-
/* At the end? */
135-
if (input.length === m.length + index) {
136-
return success();
137-
}
138-
139-
var hasEmojiBefore = this.lastEmojiTerminatedAt === index;
140-
if (hasEmojiBefore) {
141-
return success();
142-
}
143-
144-
/* Has a whitespace before? */
145-
if (isWhitespace(input.charAt(index - 1))) {
146-
return success();
147-
}
148-
149-
var hasWhitespaceAfter = isWhitespace(input.charAt(m.length + index));
150-
/* Has a whitespace after? */
151-
if (hasWhitespaceAfter && hasEmojiBefore) {
152-
return success();
153-
}
154-
155-
return;
156-
}
157-
}
158-
15993
class Emojify {
16094
emojiMegaRe?: RegExp;
16195

@@ -174,9 +108,75 @@ class Emojify {
174108

175109
config: EmojifyConfig = {};
176110

111+
Validator: any
112+
113+
constructor () {
114+
const Emojifyself = this
115+
116+
this.Validator = class {
117+
lastEmojiTerminatedAt = -1;
118+
119+
validate(match: RegExpMatchArray, index: number, input: string) {
120+
var self = this;
121+
122+
/* Validator */
123+
var emojiName = Emojifyself.getEmojiNameForMatch(match);
124+
if (!emojiName) {
125+
return;
126+
}
127+
128+
var m = match[0];
129+
var length = m.length;
130+
// var index = match.index;
131+
// var input = match.input;
132+
133+
function success() {
134+
self.lastEmojiTerminatedAt = length + index;
135+
return emojiName;
136+
}
137+
138+
/* At the beginning? */
139+
if (index === 0) {
140+
return success();
141+
}
142+
143+
/* At the end? */
144+
if (input.length === m.length + index) {
145+
return success();
146+
}
147+
148+
var hasEmojiBefore = this.lastEmojiTerminatedAt === index;
149+
if (hasEmojiBefore) {
150+
return success();
151+
}
152+
153+
/* Has a whitespace before? */
154+
if (isWhitespace(input.charAt(index - 1))) {
155+
return success();
156+
}
157+
158+
var hasWhitespaceAfter = isWhitespace(input.charAt(m.length + index));
159+
/* Has a whitespace after? */
160+
if (hasWhitespaceAfter && hasEmojiBefore) {
161+
return success();
162+
}
163+
164+
return;
165+
}
166+
}
167+
}
168+
169+
get emoticonsProcessed () {
170+
if (this.defaultConfig.ignore_emoticons) {
171+
return emoticonsProcessed.filter(([,k]) => ignoreModeAvailableKeys.includes(k))
172+
} else {
173+
return emoticonsProcessed
174+
}
175+
}
176+
177177
initMegaRe() {
178178
/* The source for our mega-regex */
179-
const mega = emoticonsProcessed
179+
const mega = this.emoticonsProcessed
180180
.map(function(v) {
181181
var re = v[0];
182182
var val = re.source || re;
@@ -189,6 +189,23 @@ class Emojify {
189189
return new RegExp(mega, 'gi');
190190
}
191191

192+
/* Given an regex match, return the name of the matching emoji */
193+
getEmojiNameForMatch = (match: RegExpMatchArray) => {
194+
/* Special case for named emoji */
195+
if (match[1] && match[2]) {
196+
var named = match[2];
197+
if (namedMatchHash[named]) {
198+
return named;
199+
}
200+
return;
201+
}
202+
for (var i = 3; i < match.length - 1; i++) {
203+
if (match[i]) {
204+
return this.emoticonsProcessed[i - 2][1];
205+
}
206+
}
207+
}
208+
192209
emojifyString = (htmlString: string, replacer: Function) => {
193210
if (!htmlString) {
194211
return htmlString;
@@ -199,7 +216,7 @@ class Emojify {
199216

200217
this.emojiMegaRe = this.initMegaRe();
201218

202-
var validator = new Validator();
219+
var validator = new this.Validator();
203220

204221
return htmlString.replace(this.emojiMegaRe, (...args) => {
205222
var matches = Array.prototype.slice.call(args, 0, -2);
@@ -308,7 +325,8 @@ class Emojify {
308325
const matchAndInsertEmoji = (node: Text) => {
309326
var match;
310327
var matches = [];
311-
var validator = new Validator();
328+
329+
var validator = new this.Validator();
312330

313331
while ((match = this.emojiMegaRe!.exec(node.data)) !== null) {
314332
if (validator.validate(match, match.index, match.input)) {
@@ -318,7 +336,7 @@ class Emojify {
318336

319337
for (var i = matches.length; i-- > 0; ) {
320338
/* Replace the text with the emoji */
321-
var emojiName = getEmojiNameForMatch(matches[i])!;
339+
var emojiName = this.getEmojiNameForMatch(matches[i])!;
322340
this.insertEmojicon({
323341
node: node,
324342
match: matches[i],
@@ -329,6 +347,8 @@ class Emojify {
329347
}
330348
};
331349

350+
this.emojiMegaRe = this.initMegaRe();
351+
332352
var nodes = [];
333353

334354
var elementsBlacklist = new RegExp(

0 commit comments

Comments
 (0)