mirror of
https://github.com/twitter/twemoji.git
synced 2024-06-15 03:35:16 +00:00
Merge 61924877d5
into 1b2f0bf5e4
This commit is contained in:
commit
1a547ae6b1
30
README.md
30
README.md
@ -71,8 +71,8 @@ If a callback is passed, the value of the `src` attribute will be the value retu
|
|||||||
```js
|
```js
|
||||||
twemoji.parse(
|
twemoji.parse(
|
||||||
'I \u2764\uFE0F emoji!',
|
'I \u2764\uFE0F emoji!',
|
||||||
function(icon, options, variant) {
|
function(iconId, options) {
|
||||||
return '/assets/' + options.size + '/' + icon + '.gif';
|
return '/assets/' + options.size + '/' + iconId + '.gif';
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ I <img
|
|||||||
*/
|
*/
|
||||||
```
|
```
|
||||||
|
|
||||||
By default, the `options.size` parameter will be the string `"36x36"` and the `variant` will be an optional `\uFE0F` char that is usually ignored by default. If your assets include or distinguish between `\u2764\uFE0F` and `\u2764`, you might want to use such a variable.
|
By default, the `options.size` parameter will be the string `"36x36"`.
|
||||||
|
|
||||||
_string parsing + callback returning_ `falsy`
|
_string parsing + callback returning_ `falsy`
|
||||||
|
|
||||||
@ -95,11 +95,11 @@ If the callback returns "falsy values" such as `null`, `undefined`, `0`, `false`
|
|||||||
var i = 0;
|
var i = 0;
|
||||||
twemoji.parse(
|
twemoji.parse(
|
||||||
'emoji, m\u2764\uFE0Fn am\u2764\uFE0Fur',
|
'emoji, m\u2764\uFE0Fn am\u2764\uFE0Fur',
|
||||||
function(icon, options, variant) {
|
function(iconId, options) {
|
||||||
if (i++ === 0) {
|
if (i++ === 0) {
|
||||||
return; // no changes made first call
|
return; // no changes made first call
|
||||||
}
|
}
|
||||||
return '/assets/' + icon + options.ext;
|
return '/assets/' + iconId + options.ext;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -120,8 +120,8 @@ In case an object is passed as second parameter, the passed `options` object wil
|
|||||||
twemoji.parse(
|
twemoji.parse(
|
||||||
'I \u2764\uFE0F emoji!',
|
'I \u2764\uFE0F emoji!',
|
||||||
{
|
{
|
||||||
callback: function(icon, options) {
|
callback: function(iconId, options) {
|
||||||
return '/assets/' + options.size + '/' + icon + '.gif';
|
return '/assets/' + options.size + '/' + iconId + '.gif';
|
||||||
},
|
},
|
||||||
size: 128
|
size: 128
|
||||||
}
|
}
|
||||||
@ -185,12 +185,12 @@ The function to invoke in order to generate image `src`(s).
|
|||||||
|
|
||||||
By default it is a function like the following one:
|
By default it is a function like the following one:
|
||||||
```js
|
```js
|
||||||
function imageSourceGenerator(icon, options) {
|
function imageSourceGenerator(iconId, options) {
|
||||||
return ''.concat(
|
return ''.concat(
|
||||||
options.base, // by default Twitter Inc. CDN
|
options.base, // by default Twitter Inc. CDN
|
||||||
options.size, // by default "36x36" string
|
options.size, // by default "36x36" string
|
||||||
'/',
|
'/',
|
||||||
icon, // the found emoji as code point
|
iconId, // the found emoji as a string of hex code points
|
||||||
options.ext // by default ".png"
|
options.ext // by default ".png"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -201,9 +201,9 @@ The function to invoke in order to generate additional, custom attributes for th
|
|||||||
|
|
||||||
By default it is a function like the following one:
|
By default it is a function like the following one:
|
||||||
```js
|
```js
|
||||||
function attributesCallback(icon, variant) {
|
function attributesCallback(rawText, iconId) {
|
||||||
return {
|
return {
|
||||||
title: 'Emoji: ' + icon + variant
|
title: 'Emoji: ' + rawText
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -287,18 +287,18 @@ To properly support emoji, the document character set must be set to UTF-8. This
|
|||||||
|
|
||||||
#### Exclude Characters (V1)
|
#### Exclude Characters (V1)
|
||||||
|
|
||||||
To exclude certain characters from being replaced by twemoji.js, call twemoji.parse() with a callback, returning false for the specific unicode icon. For example:
|
To exclude certain characters from being replaced by twemoji.js, call twemoji.parse() with a callback, returning false for the specific unicode iconId. For example:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
twemoji.parse(document.body, {
|
twemoji.parse(document.body, {
|
||||||
callback: function(icon, options, variant) {
|
callback: function(iconId, options) {
|
||||||
switch ( icon ) {
|
switch ( iconId ) {
|
||||||
case 'a9': // © copyright
|
case 'a9': // © copyright
|
||||||
case 'ae': // ® registered trademark
|
case 'ae': // ® registered trademark
|
||||||
case '2122': // ™ trademark
|
case '2122': // ™ trademark
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return ''.concat(options.base, options.size, '/', icon, options.ext);
|
return ''.concat(options.base, options.size, '/', iconId, options.ext);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
96
test.js
96
test.js
@ -44,17 +44,17 @@ wru.test([{
|
|||||||
name: 'string parsing + callback',
|
name: 'string parsing + callback',
|
||||||
test: function () {
|
test: function () {
|
||||||
var result = false;
|
var result = false;
|
||||||
twemoji.parse('I \u2764 emoji!', function (icon, options, variant) {
|
twemoji.parse('I \u2764 emoji!', function (icon, options) {
|
||||||
result = icon === '2764' && options.size === '36x36' && !variant;
|
result = icon === '2764' && options.size === '36x36';
|
||||||
});
|
});
|
||||||
wru.assert('works OK without variant', result);
|
wru.assert('works OK without variant', result);
|
||||||
result = false;
|
result = false;
|
||||||
twemoji.parse('I \u2764\uFE0F emoji!', function (icon, options, variant) {
|
twemoji.parse('I \u2764\uFE0F emoji!', function (icon, options) {
|
||||||
result = icon === '2764' && options.size === '36x36' && variant === '\uFE0F';
|
result = icon === '2764' && options.size === '36x36';
|
||||||
});
|
});
|
||||||
wru.assert('works OK with variant', result);
|
wru.assert('works OK with variant', result);
|
||||||
result = true;
|
result = true;
|
||||||
twemoji.parse('I \u2764\uFE0E emoji!', function (icon, options, variant) {
|
twemoji.parse('I \u2764\uFE0E emoji!', function (icon, options) {
|
||||||
result = false;
|
result = false;
|
||||||
});
|
});
|
||||||
wru.assert('not invoked when \uFE0E is matched', result);
|
wru.assert('not invoked when \uFE0E is matched', result);
|
||||||
@ -83,26 +83,13 @@ wru.test([{
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},{
|
|
||||||
name: 'twemoji.replace(str, callback)',
|
|
||||||
test: function () {
|
|
||||||
var result = false;
|
|
||||||
var str = twemoji.replace('I \u2764\uFE0E emoji!', function (match, emoji, variant) {
|
|
||||||
result = match === '\u2764\uFE0E' &&
|
|
||||||
emoji === '\u2764\uFE0E' &&
|
|
||||||
variant === '\uFE0E';
|
|
||||||
return '<3';
|
|
||||||
});
|
|
||||||
wru.assert('all exepected values are passed through', result);
|
|
||||||
wru.assert('returned value is the expected', str === 'I <3 emoji!');
|
|
||||||
}
|
|
||||||
},{
|
},{
|
||||||
name: 'twemoji.test(str)',
|
name: 'twemoji.test(str)',
|
||||||
test: function () {
|
test: function () {
|
||||||
wru.assert(
|
wru.assert(
|
||||||
twemoji.test('I \u2764 emoji!') &&
|
twemoji.test('I \u2764 emoji!') &&
|
||||||
twemoji.test('I \u2764\uFE0F emoji!') &&
|
twemoji.test('I \u2764\uFE0F emoji!') &&
|
||||||
twemoji.test('I \u2764\uFE0E emoji!') &&
|
!twemoji.test('I \u2764\uFE0E emoji!') &&
|
||||||
!twemoji.test('nope')
|
!twemoji.test('nope')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -174,15 +161,15 @@ wru.test([{
|
|||||||
var result = false,
|
var result = false,
|
||||||
div = document.createElement('div');
|
div = document.createElement('div');
|
||||||
div.appendChild(document.createTextNode('I \u2764 emoji!'));
|
div.appendChild(document.createTextNode('I \u2764 emoji!'));
|
||||||
twemoji.parse(div, function (icon, options, variant) {
|
twemoji.parse(div, function (icon, options) {
|
||||||
result = icon === '2764' && options.size === '36x36' && !variant;
|
result = icon === '2764' && options.size === '36x36';
|
||||||
});
|
});
|
||||||
wru.assert('works OK without variant', result);
|
wru.assert('works OK without variant', result);
|
||||||
result = false;
|
result = false;
|
||||||
div = document.createElement('div');
|
div = document.createElement('div');
|
||||||
div.appendChild(document.createTextNode('I \u2764\uFE0F emoji!'));
|
div.appendChild(document.createTextNode('I \u2764\uFE0F emoji!'));
|
||||||
twemoji.parse(div, function (icon, options, variant) {
|
twemoji.parse(div, function (icon, options) {
|
||||||
result = icon === '2764' && options.size === '36x36' && variant === '\uFE0F';
|
result = icon === '2764' && options.size === '36x36';
|
||||||
});
|
});
|
||||||
wru.assert('works OK with variant', result);
|
wru.assert('works OK with variant', result);
|
||||||
result = true;
|
result = true;
|
||||||
@ -209,8 +196,8 @@ wru.test([{
|
|||||||
div.appendChild(document.createTextNode('I \u2764 emoji!'));
|
div.appendChild(document.createTextNode('I \u2764 emoji!'));
|
||||||
twemoji.parse(div, {
|
twemoji.parse(div, {
|
||||||
size: 16,
|
size: 16,
|
||||||
callback: function (icon, options, variant) {
|
callback: function (icon, options) {
|
||||||
result = icon === '2764' && options.size === '16x16' && !variant;
|
result = icon === '2764' && options.size === '16x16';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
wru.assert('works OK without variant', result);
|
wru.assert('works OK without variant', result);
|
||||||
@ -219,8 +206,8 @@ wru.test([{
|
|||||||
div.appendChild(document.createTextNode('I \u2764\uFE0F emoji!'));
|
div.appendChild(document.createTextNode('I \u2764\uFE0F emoji!'));
|
||||||
twemoji.parse(div, {
|
twemoji.parse(div, {
|
||||||
size: 72,
|
size: 72,
|
||||||
callback: function (icon, options, variant) {
|
callback: function (icon, options) {
|
||||||
result = icon === '2764' && options.size === '72x72' && !!variant;
|
result = icon === '2764' && options.size === '72x72';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
wru.assert('works OK with variant', result);
|
wru.assert('works OK with variant', result);
|
||||||
@ -315,9 +302,9 @@ wru.test([{
|
|||||||
twemoji.parse(
|
twemoji.parse(
|
||||||
'I \u2764 emoji!',
|
'I \u2764 emoji!',
|
||||||
{
|
{
|
||||||
attributes: function(icon) {
|
attributes: function(rawText, iconId) {
|
||||||
return {
|
return {
|
||||||
title: 'Emoji: ' + icon,
|
title: 'Emoji: ' + rawText,
|
||||||
'data-test': 'We all <3 emoji'
|
'data-test': 'We all <3 emoji'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -326,7 +313,25 @@ wru.test([{
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
},{
|
},{
|
||||||
name: 'string parsing + attributes callback content properly encoded',
|
name: 'string parsing + attributes callback icon id',
|
||||||
|
test: function () {
|
||||||
|
wru.assert(
|
||||||
|
'custom attributes are inserted',
|
||||||
|
'I <img class="emoji" draggable="false" alt="\u2764" src="' + base + '36x36/2764.png" title="Emoji: 2764" data-test="We all <3 emoji"> emoji!' ===
|
||||||
|
twemoji.parse(
|
||||||
|
'I \u2764 emoji!',
|
||||||
|
{
|
||||||
|
attributes: function(rawText, iconId) {
|
||||||
|
return {
|
||||||
|
title: 'Emoji: ' + iconId,
|
||||||
|
'data-test': 'We all <3 emoji'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},{ name: 'string parsing + attributes callback content properly encoded',
|
||||||
test: function () {
|
test: function () {
|
||||||
wru.assert(
|
wru.assert(
|
||||||
'custom attributes are inserted',
|
'custom attributes are inserted',
|
||||||
@ -334,7 +339,7 @@ wru.test([{
|
|||||||
twemoji.parse(
|
twemoji.parse(
|
||||||
'I \u2764 emoji!',
|
'I \u2764 emoji!',
|
||||||
{
|
{
|
||||||
attributes: function(icon) {
|
attributes: function(rawText, iconId) {
|
||||||
return {
|
return {
|
||||||
title: '&lt;script&gt;alert("yo")&lt;/script&gt;'
|
title: '&lt;script&gt;alert("yo")&lt;/script&gt;'
|
||||||
};
|
};
|
||||||
@ -352,7 +357,7 @@ wru.test([{
|
|||||||
twemoji.parse(
|
twemoji.parse(
|
||||||
'I \u2764 emoji!',
|
'I \u2764 emoji!',
|
||||||
{
|
{
|
||||||
attributes: function(icon) {
|
attributes: function(rawText, iconId) {
|
||||||
return {
|
return {
|
||||||
title: 'test',
|
title: 'test',
|
||||||
onsomething: 'whoops!',
|
onsomething: 'whoops!',
|
||||||
@ -373,9 +378,9 @@ wru.test([{
|
|||||||
div.appendChild(document.createTextNode('I \u2764 emoji!'));
|
div.appendChild(document.createTextNode('I \u2764 emoji!'));
|
||||||
twemoji.parse(
|
twemoji.parse(
|
||||||
div, {
|
div, {
|
||||||
attributes: function(icon) {
|
attributes: function(rawText, iconId) {
|
||||||
return {
|
return {
|
||||||
title: 'Emoji: ' + icon,
|
title: 'Emoji: ' + rawText,
|
||||||
'data-test': 'We all <3 emoji',
|
'data-test': 'We all <3 emoji',
|
||||||
onclick: 'nope',
|
onclick: 'nope',
|
||||||
onmousedown: 'nada'
|
onmousedown: 'nada'
|
||||||
@ -462,36 +467,17 @@ wru.test([{
|
|||||||
wru.assert('the length is preserved',
|
wru.assert('the length is preserved',
|
||||||
div.getElementsByTagName('img')[0].alt.length === 2);
|
div.getElementsByTagName('img')[0].alt.length === 2);
|
||||||
}
|
}
|
||||||
},{
|
}, {
|
||||||
name: 'multiple parsing using a callback',
|
name: 'multiple parsing using a callback',
|
||||||
test: function () {
|
test: function () {
|
||||||
wru.assert(
|
wru.assert(
|
||||||
'FE0E is still ignored',
|
'FE0E is still ignored',
|
||||||
twemoji.parse('\u25c0 \u25c0\ufe0e \u25c0\ufe0f', {
|
twemoji.parse('\u25c0 \u25c0\ufe0e \u25c0\ufe0f', {
|
||||||
callback: function(icon){ return 'icon'; }
|
callback: function(iconId, options){return 'icon';}
|
||||||
}) ===
|
}) ===
|
||||||
'<img class="emoji" draggable="false" alt="\u25c0" src="icon"> \u25c0\ufe0e <img class="emoji" draggable="false" alt="\u25c0\ufe0f" src="icon">'
|
'<img class="emoji" draggable="false" alt="\u25c0" src="icon"> \u25c0\ufe0e <img class="emoji" draggable="false" alt="\u25c0\ufe0f" src="icon">'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},{
|
|
||||||
name: 'non standard variant within others',
|
|
||||||
test: function () {
|
|
||||||
var a = [
|
|
||||||
'normal',
|
|
||||||
'forced-as-text',
|
|
||||||
'forced-as-apple-graphic',
|
|
||||||
'forced-as-graphic'
|
|
||||||
];
|
|
||||||
wru.assert('normal forced-as-text forced-as-apple-graphic forced-as-graphic' ===
|
|
||||||
twemoji.replace('\u25c0 \u25c0\ufe0e 5\ufe0f\u20e3 \u25c0\ufe0f', function(match, icon, variant){
|
|
||||||
if (variant === '\uFE0E') return a[1];
|
|
||||||
if (variant === '\uFE0F') return a[3];
|
|
||||||
if (!variant) return a[
|
|
||||||
icon.length === 3 && icon.charAt(1) === '\uFE0F' ? 2 : 0
|
|
||||||
];
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},{
|
},{
|
||||||
name: 'invalid variants and chars',
|
name: 'invalid variants and chars',
|
||||||
test: function () {
|
test: function () {
|
||||||
|
@ -229,11 +229,11 @@ Queue([
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// create a RegExp with properly ordered matches
|
// create a RegExp
|
||||||
q.re = '((?:' +
|
// the sensitive ones may be followed by U+FE0F but not U+FE0E
|
||||||
regular.join('|') + ')|(?:(?:' +
|
q.re = regular.join('|') + '|(?:' +
|
||||||
sensitive.join('|') +
|
sensitive.join('|') +
|
||||||
')([\\uFE0E\\uFE0F]?)))';
|
')(?:\\ufe0f|(?!\\ufe0e))';
|
||||||
|
|
||||||
q.next();
|
q.next();
|
||||||
|
|
||||||
@ -413,16 +413,11 @@ function createTwemoji(re) {
|
|||||||
* those follwed by the invariant \uFE0E ("as text").
|
* those follwed by the invariant \uFE0E ("as text").
|
||||||
* Once invoked, parameters will be:
|
* Once invoked, parameters will be:
|
||||||
*
|
*
|
||||||
* codePoint:string the lower case HEX code point
|
* iconId:string the lower case HEX code point
|
||||||
* i.e. "1f4a9"
|
* i.e. "1f4a9"
|
||||||
*
|
*
|
||||||
* options:Object all info for this parsing operation
|
* options:Object all info for this parsing operation
|
||||||
*
|
*
|
||||||
* variant:char the optional \uFE0F ("as image")
|
|
||||||
* variant, in case this info
|
|
||||||
* is anyhow meaningful.
|
|
||||||
* By default this is ignored.
|
|
||||||
*
|
|
||||||
* If such callback will return a falsy value instead
|
* If such callback will return a falsy value instead
|
||||||
* of a valid `src` to use for the image, nothing will
|
* of a valid `src` to use for the image, nothing will
|
||||||
* actually change for that specific emoji.
|
* actually change for that specific emoji.
|
||||||
@ -441,16 +436,16 @@ function createTwemoji(re) {
|
|||||||
* // I <img class="emoji" draggable="false" alt="❤️" src="/assets/2764.gif"> emoji!
|
* // I <img class="emoji" draggable="false" alt="❤️" src="/assets/2764.gif"> emoji!
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* twemoji.parse("I \u2764\uFE0F emoji!", function(icon, options, variant) {
|
* twemoji.parse("I \u2764\uFE0F emoji!", function(iconId, options) {
|
||||||
* return '/assets/' + icon + '.gif';
|
* return '/assets/' + iconId + '.gif';
|
||||||
* });
|
* });
|
||||||
* // I <img class="emoji" draggable="false" alt="❤️" src="/assets/2764.gif"> emoji!
|
* // I <img class="emoji" draggable="false" alt="❤️" src="/assets/2764.gif"> emoji!
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* twemoji.parse("I \u2764\uFE0F emoji!", {
|
* twemoji.parse("I \u2764\uFE0F emoji!", {
|
||||||
* size: 72,
|
* size: 72,
|
||||||
* callback: function(icon, options, variant) {
|
* callback: function(iconId, options) {
|
||||||
* return '/assets/' + options.size + '/' + icon + options.ext;
|
* return '/assets/' + options.size + '/' + iconId + options.ext;
|
||||||
* }
|
* }
|
||||||
* });
|
* });
|
||||||
* // I <img class="emoji" draggable="false" alt="❤️" src="/assets/72x72/2764.png"> emoji!
|
* // I <img class="emoji" draggable="false" alt="❤️" src="/assets/72x72/2764.png"> emoji!
|
||||||
@ -471,17 +466,10 @@ function createTwemoji(re) {
|
|||||||
* String.prototype.replace(str, callback)
|
* String.prototype.replace(str, callback)
|
||||||
* arguments such:
|
* arguments such:
|
||||||
* callback(
|
* callback(
|
||||||
* match, // the emoji match
|
* rawText, // the emoji match
|
||||||
* icon, // the emoji text (same as text)
|
|
||||||
* variant // either '\uFE0E' or '\uFE0F', if present
|
|
||||||
* );
|
* );
|
||||||
*
|
*
|
||||||
* and others commonly received via replace.
|
* and others commonly received via replace.
|
||||||
*
|
|
||||||
* NOTE: When the variant \uFE0E is found, remember this is an explicit intent
|
|
||||||
* from the user: the emoji should **not** be replaced with an image.
|
|
||||||
* In \uFE0F case one, it's the opposite, it should be graphic.
|
|
||||||
* This utility convetion is that only \uFE0E are not translated into images.
|
|
||||||
*/
|
*/
|
||||||
replace: replace,
|
replace: replace,
|
||||||
|
|
||||||
@ -553,7 +541,6 @@ function createTwemoji(re) {
|
|||||||
* based on Twitter CDN
|
* based on Twitter CDN
|
||||||
* @param string the emoji codepoint string
|
* @param string the emoji codepoint string
|
||||||
* @param string the default size to use, i.e. "36x36"
|
* @param string the default size to use, i.e. "36x36"
|
||||||
* @param string optional "\uFE0F" variant char, ignored by default
|
|
||||||
* @return string the image source to use
|
* @return string the image source to use
|
||||||
*/
|
*/
|
||||||
function defaultImageSrcGenerator(icon, options) {
|
function defaultImageSrcGenerator(icon, options) {
|
||||||
@ -592,19 +579,15 @@ function createTwemoji(re) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to both remove the possible variant
|
* Used to both remove the possible variant
|
||||||
* and to convert utf16 into code points
|
* and to convert utf16 into code points.
|
||||||
* @param string the emoji surrogate pair
|
* If there is a zero-width-joiner, leave the variant in.
|
||||||
* @param string the optional variant char, if any
|
* @param string the raw text of the emoji match
|
||||||
*/
|
*/
|
||||||
function grabTheRightIcon(icon, variant) {
|
function grabTheRightIcon(rawText) {
|
||||||
// if variant is present as \uFE0F
|
|
||||||
return toCodePoint(
|
return toCodePoint(
|
||||||
variant === '\uFE0F' ?
|
rawText.indexOf('\u200D') < 0 ?
|
||||||
// the icon should not contain it
|
rawText.replace(/\uFE0F/g, '') :
|
||||||
icon.slice(0, -1) :
|
rawText
|
||||||
// fix non standard OSX behavior
|
|
||||||
(icon.length === 3 && icon.charAt(1) === '\uFE0F' ?
|
|
||||||
icon.charAt(0) + icon.charAt(2) : icon)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -635,9 +618,8 @@ function createTwemoji(re) {
|
|||||||
i,
|
i,
|
||||||
index,
|
index,
|
||||||
img,
|
img,
|
||||||
alt,
|
rawText,
|
||||||
icon,
|
iconId,
|
||||||
variant,
|
|
||||||
src;
|
src;
|
||||||
while (length--) {
|
while (length--) {
|
||||||
modified = false;
|
modified = false;
|
||||||
@ -652,39 +634,35 @@ function createTwemoji(re) {
|
|||||||
createText(text.slice(i, index))
|
createText(text.slice(i, index))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
alt = match[0];
|
rawText = match[0];
|
||||||
icon = match[1];
|
iconId = grabTheRightIcon(rawText);
|
||||||
variant = match[2];
|
i = index + rawText.length;
|
||||||
i = index + alt.length;
|
src = options.callback(
|
||||||
if (variant !== '\uFE0E') {
|
iconId,
|
||||||
src = options.callback(
|
options
|
||||||
grabTheRightIcon(icon, variant),
|
);
|
||||||
options,
|
if (src) {
|
||||||
variant
|
img = new Image();
|
||||||
);
|
img.onerror = options.onerror;
|
||||||
if (src) {
|
img.setAttribute('draggable', 'false');
|
||||||
img = new Image();
|
attrib = options.attributes(rawText, iconId);
|
||||||
img.onerror = options.onerror;
|
for (attrname in attrib) {
|
||||||
img.setAttribute('draggable', 'false');
|
if (
|
||||||
attrib = options.attributes(icon, variant);
|
attrib.hasOwnProperty(attrname) &&
|
||||||
for (attrname in attrib) {
|
// don't allow any handlers to be set + don't allow overrides
|
||||||
if (
|
attrname.indexOf('on') !== 0 &&
|
||||||
attrib.hasOwnProperty(attrname) &&
|
!img.hasAttribute(attrname)
|
||||||
// don't allow any handlers to be set + don't allow overrides
|
) {
|
||||||
attrname.indexOf('on') !== 0 &&
|
img.setAttribute(attrname, attrib[attrname]);
|
||||||
!img.hasAttribute(attrname)
|
|
||||||
) {
|
|
||||||
img.setAttribute(attrname, attrib[attrname]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
img.className = options.className;
|
|
||||||
img.alt = alt;
|
|
||||||
img.src = src;
|
|
||||||
modified = true;
|
|
||||||
fragment.appendChild(img);
|
|
||||||
}
|
}
|
||||||
|
img.className = options.className;
|
||||||
|
img.alt = rawText;
|
||||||
|
img.src = src;
|
||||||
|
modified = true;
|
||||||
|
fragment.appendChild(img);
|
||||||
}
|
}
|
||||||
if (!img) fragment.appendChild(createText(alt));
|
if (!img) fragment.appendChild(createText(rawText));
|
||||||
img = null;
|
img = null;
|
||||||
}
|
}
|
||||||
// is there actually anything to replace in here ?
|
// is there actually anything to replace in here ?
|
||||||
@ -717,50 +695,45 @@ function createTwemoji(re) {
|
|||||||
* @return the string with <img tags> replacing all found and parsed emoji
|
* @return the string with <img tags> replacing all found and parsed emoji
|
||||||
*/
|
*/
|
||||||
function parseString(str, options) {
|
function parseString(str, options) {
|
||||||
return replace(str, function (match, icon, variant) {
|
return replace(str, function (rawText) {
|
||||||
var
|
var
|
||||||
ret = match,
|
ret = rawText,
|
||||||
attrib,
|
attrib,
|
||||||
attrname,
|
attrname,
|
||||||
|
iconId,
|
||||||
src;
|
src;
|
||||||
// verify the variant is not the FE0E one
|
iconId = grabTheRightIcon(rawText);
|
||||||
// this variant means "emoji as text" and should not
|
src = options.callback(
|
||||||
// require any action/replacement
|
iconId,
|
||||||
// http://unicode.org/Public/UNIDATA/StandardizedVariants.html
|
options
|
||||||
if (variant !== '\uFE0E') {
|
);
|
||||||
src = options.callback(
|
if (src) {
|
||||||
grabTheRightIcon(icon, variant),
|
// recycle the match string replacing the emoji
|
||||||
options,
|
// with its image counter part
|
||||||
variant
|
ret = '<img '.concat(
|
||||||
|
'class="', options.className, '" ',
|
||||||
|
'draggable="false" ',
|
||||||
|
// needs to preserve user original intent
|
||||||
|
// when variants should be copied and pasted too
|
||||||
|
'alt="',
|
||||||
|
rawText,
|
||||||
|
'"',
|
||||||
|
' src="',
|
||||||
|
src,
|
||||||
|
'"'
|
||||||
);
|
);
|
||||||
if (src) {
|
attrib = options.attributes(rawText, iconId);
|
||||||
// recycle the match string replacing the emoji
|
for (attrname in attrib) {
|
||||||
// with its image counter part
|
if (
|
||||||
ret = '<img '.concat(
|
attrib.hasOwnProperty(attrname) &&
|
||||||
'class="', options.className, '" ',
|
// don't allow any handlers to be set + don't allow overrides
|
||||||
'draggable="false" ',
|
attrname.indexOf('on') !== 0 &&
|
||||||
// needs to preserve user original intent
|
ret.indexOf(' ' + attrname + '=') === -1
|
||||||
// when variants should be copied and pasted too
|
) {
|
||||||
'alt="',
|
ret = ret.concat(' ', attrname, '="', escapeHTML(attrib[attrname]), '"');
|
||||||
match,
|
|
||||||
'"',
|
|
||||||
' src="',
|
|
||||||
src,
|
|
||||||
'"'
|
|
||||||
);
|
|
||||||
attrib = options.attributes(icon, variant);
|
|
||||||
for (attrname in attrib) {
|
|
||||||
if (
|
|
||||||
attrib.hasOwnProperty(attrname) &&
|
|
||||||
// don't allow any handlers to be set + don't allow overrides
|
|
||||||
attrname.indexOf('on') !== 0 &&
|
|
||||||
ret.indexOf(' ' + attrname + '=') === -1
|
|
||||||
) {
|
|
||||||
ret = ret.concat(' ', attrname, '="', escapeHTML(attrib[attrname]), '"');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ret = ret.concat('>');
|
|
||||||
}
|
}
|
||||||
|
ret = ret.concat('>');
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
});
|
});
|
||||||
|
175
twemoji.amd.js
175
twemoji.amd.js
File diff suppressed because one or more lines are too long
175
twemoji.js
175
twemoji.js
File diff suppressed because one or more lines are too long
2
twemoji.min.js
vendored
2
twemoji.min.js
vendored
File diff suppressed because one or more lines are too long
175
twemoji.npm.js
175
twemoji.npm.js
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user