mirror of
https://github.com/twitter/twemoji.git
synced 2024-06-15 03:35:16 +00:00
Finish up attributes
This commit is contained in:
parent
1fa5a27fba
commit
5d4f6fabca
14
README.md
14
README.md
@ -148,6 +148,7 @@ Here the list of properties accepted by the optional object that could be passed
|
||||
```js
|
||||
{
|
||||
callback: Function, // default the common replacer
|
||||
attributes: Function, // default returns {}
|
||||
base: string, // default MaxCDN
|
||||
ext: string, // default ".png"
|
||||
className: string, // default "emoji"
|
||||
@ -173,6 +174,19 @@ function imageSourceGenerator(icon, options) {
|
||||
}
|
||||
```
|
||||
|
||||
##### attributes
|
||||
The function to invoke in order to generate additional, custom attributes for the image tag.
|
||||
|
||||
By default it is a function like the following one:
|
||||
```js
|
||||
function attributesCallback(icon, variant) {
|
||||
return {
|
||||
title: 'Emoji: ' + icon + variant
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Event handlers cannot be specified via this method, and twemoji-provided attributes (src, alt, className, draggable) cannot be re-defined.
|
||||
|
||||
##### base
|
||||
The default url is the same as `twemoji.base`, so if you modify the former, it will reflect as default for all parsed strings or nodes.
|
||||
|
6
test.js
6
test.js
@ -314,7 +314,7 @@ wru.test([{
|
||||
test: function () {
|
||||
wru.assert(
|
||||
'custom attributes are inserted',
|
||||
'I <img class="emoji" draggable="false" alt="\u2764" title="Emoji: \u2764" data-test="We all <3 emoji" src="' + base + '36x36/2764.png"> emoji!' ===
|
||||
'I <img class="emoji" draggable="false" alt="\u2764" src="' + base + '36x36/2764.png" title="Emoji: \u2764" data-test="We all <3 emoji"> emoji!' ===
|
||||
twemoji.parse(
|
||||
'I \u2764 emoji!',
|
||||
{
|
||||
@ -333,7 +333,7 @@ wru.test([{
|
||||
test: function () {
|
||||
wru.assert(
|
||||
'custom attributes are inserted',
|
||||
'I <img class="emoji" draggable="false" alt="\u2764" title="&amp;lt;script&amp;gt;alert("yo")&amp;lt;/script&amp;gt;" src="' + base + '36x36/2764.png"> emoji!' ===
|
||||
'I <img class="emoji" draggable="false" alt="\u2764" src="' + base + '36x36/2764.png" title="&amp;lt;script&amp;gt;alert("yo")&amp;lt;/script&amp;gt;"> emoji!' ===
|
||||
twemoji.parse(
|
||||
'I \u2764 emoji!',
|
||||
{
|
||||
@ -351,7 +351,7 @@ wru.test([{
|
||||
test: function () {
|
||||
wru.assert(
|
||||
'custom attributes are inserted',
|
||||
'I <img class="emoji" draggable="false" alt="❤" title="test" src="' + base + '36x36/2764.png"> emoji!' ===
|
||||
'I <img class="emoji" draggable="false" alt="❤" src="' + base + '36x36/2764.png" title="test"> emoji!' ===
|
||||
twemoji.parse(
|
||||
'I \u2764 emoji!',
|
||||
{
|
||||
|
@ -532,7 +532,7 @@ function createTwemoji(re) {
|
||||
* @param string text use in HTML attribute
|
||||
* @return string text encoded to use in HTML attribute
|
||||
*/
|
||||
function escape(s) {
|
||||
function escapeHTML(s) {
|
||||
var escaped = {
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
@ -544,7 +544,7 @@ function createTwemoji(re) {
|
||||
return escaped[m];
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default callback used to generate emoji src
|
||||
* based on Twitter CDN
|
||||
@ -658,19 +658,21 @@ function createTwemoji(re) {
|
||||
if (src) {
|
||||
img = new Image();
|
||||
img.onerror = twemoji.onerror;
|
||||
img.className = options.className;
|
||||
img.setAttribute('draggable', 'false');
|
||||
if (options.attributes && typeof(options.attributes) === 'function') {
|
||||
var attrib = options.attributes(alt);
|
||||
if (attrib) {
|
||||
for (var attrname in attrib) {
|
||||
// don't allow any handlers to be set
|
||||
if (attrname.lastIndexOf('on', 0) === -1) {
|
||||
|
||||
var attrib = options.attributes(icon, variant);
|
||||
if (attrib) {
|
||||
for (var attrname in attrib) {
|
||||
if (attrib.hasOwnProperty(attrname)) {
|
||||
// don't allow any handlers to be set, don't allow overrides
|
||||
if (attrname.indexOf('on') !== 0 && !img.hasAttribute(attrname)) {
|
||||
img.setAttribute(attrname, attrib[attrname]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
img.className = options.className;
|
||||
img.alt = alt;
|
||||
img.src = src;
|
||||
}
|
||||
@ -710,6 +712,7 @@ function createTwemoji(re) {
|
||||
function parseString(str, options) {
|
||||
return replace(str, function (match, icon, variant) {
|
||||
var src;
|
||||
var ret = match;
|
||||
// verify the variant is not the FE0E one
|
||||
// this variant means "emoji as text" and should not
|
||||
// require any action/replacement
|
||||
@ -723,20 +726,7 @@ function createTwemoji(re) {
|
||||
if (src) {
|
||||
// recycle the match string replacing the emoji
|
||||
// with its image counter part
|
||||
var attr_text = '';
|
||||
if (options.attributes && typeof(options.attributes) === 'function') {
|
||||
var attrib = options.attributes(match);
|
||||
if (attrib) {
|
||||
for (var attrname in attrib) {
|
||||
// don't allow any handlers to be set
|
||||
if (attrname.lastIndexOf('on', 0) === -1) {
|
||||
attr_text = attr_text + ' ' + attrname + '="' + escape(attrib[attrname]) + '"';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match = '<img '.concat(
|
||||
ret = '<img '.concat(
|
||||
'class="', options.className, '" ',
|
||||
'draggable="false" ',
|
||||
// needs to preserve user original intent
|
||||
@ -744,15 +734,26 @@ function createTwemoji(re) {
|
||||
'alt="',
|
||||
match,
|
||||
'"',
|
||||
attr_text,
|
||||
' src="',
|
||||
src,
|
||||
'"',
|
||||
'>'
|
||||
'"'
|
||||
);
|
||||
var attrib = options.attributes(icon, variant);
|
||||
if (attrib) {
|
||||
for (var attrname in attrib) {
|
||||
if (attrib.hasOwnProperty(attrname)) {
|
||||
// don't allow any handlers to be set, don't allow overrides
|
||||
if (attrname.indexOf('on') !== 0 && ret.indexOf(' ' + attrname + '=') === -1) {
|
||||
ret = ret.concat(' ', attrname, '="', escapeHTML(attrib[attrname]), '"');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = ret.concat('>');
|
||||
}
|
||||
}
|
||||
return match;
|
||||
return ret;
|
||||
});
|
||||
}
|
||||
|
||||
@ -796,12 +797,12 @@ function createTwemoji(re) {
|
||||
// if first argument is string, inject html <img> tags
|
||||
// otherwise use the DOM tree and parse text nodes only
|
||||
return (typeof what === 'string' ? parseString : parseNode)(what, {
|
||||
callback: how.callback || defaultImageSrcGenerator,
|
||||
attributes: how.attributes,
|
||||
base: typeof how.base === 'string' ? how.base : twemoji.base,
|
||||
ext: how.ext || twemoji.ext,
|
||||
size: how.folder || toSizeSquaredAsset(how.size || twemoji.size),
|
||||
className:how.className || twemoji.className
|
||||
callback: how.callback || defaultImageSrcGenerator,
|
||||
attributes: typeof how.attributes === 'function' ? how.attributes : function() {return {};},
|
||||
base: typeof how.base === 'string' ? how.base : twemoji.base,
|
||||
ext: how.ext || twemoji.ext,
|
||||
size: how.folder || toSizeSquaredAsset(how.size || twemoji.size),
|
||||
className: how.className || twemoji.className
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -255,7 +255,7 @@ define(function () {
|
||||
* @param string text use in HTML attribute
|
||||
* @return string text encoded to use in HTML attribute
|
||||
*/
|
||||
function escape(s) {
|
||||
function escapeHTML(s) {
|
||||
var escaped = {
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
@ -267,7 +267,7 @@ define(function () {
|
||||
return escaped[m];
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default callback used to generate emoji src
|
||||
* based on Twitter CDN
|
||||
@ -381,18 +381,21 @@ define(function () {
|
||||
if (src) {
|
||||
img = new Image();
|
||||
img.onerror = twemoji.onerror;
|
||||
img.className = options.className;
|
||||
img.setAttribute('draggable', 'false');
|
||||
if (options.attributes && typeof(options.attributes) === 'function') {
|
||||
var attrib = options.attributes(alt);
|
||||
if (attrib) {
|
||||
for (var attrname in attrib) {
|
||||
if (attrname.lastIndexOf('on', 0) === -1) {
|
||||
|
||||
var attrib = options.attributes(icon, variant);
|
||||
if (attrib) {
|
||||
for (var attrname in attrib) {
|
||||
if (attrib.hasOwnProperty(attrname)) {
|
||||
// don't allow any handlers to be set, don't allow overrides
|
||||
if (attrname.indexOf('on') !== 0 && !img.hasAttribute(attrname)) {
|
||||
img.setAttribute(attrname, attrib[attrname]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
img.className = options.className;
|
||||
img.alt = alt;
|
||||
img.src = src;
|
||||
}
|
||||
@ -432,6 +435,7 @@ define(function () {
|
||||
function parseString(str, options) {
|
||||
return replace(str, function (match, icon, variant) {
|
||||
var src;
|
||||
var ret = match;
|
||||
// verify the variant is not the FE0E one
|
||||
// this variant means "emoji as text" and should not
|
||||
// require any action/replacement
|
||||
@ -445,19 +449,7 @@ define(function () {
|
||||
if (src) {
|
||||
// recycle the match string replacing the emoji
|
||||
// with its image counter part
|
||||
var attr_text = '';
|
||||
if (options.attributes && typeof(options.attributes) === 'function') {
|
||||
var attrib = options.attributes(match);
|
||||
if (attrib) {
|
||||
for (var attrname in attrib) {
|
||||
if (attrname.lastIndexOf('on', 0) === -1) {
|
||||
attr_text = attr_text + ' ' + attrname + '="' + escape(attrib[attrname]) + '"';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match = '<img '.concat(
|
||||
ret = '<img '.concat(
|
||||
'class="', options.className, '" ',
|
||||
'draggable="false" ',
|
||||
// needs to preserve user original intent
|
||||
@ -465,15 +457,26 @@ define(function () {
|
||||
'alt="',
|
||||
match,
|
||||
'"',
|
||||
attr_text,
|
||||
' src="',
|
||||
src,
|
||||
'"',
|
||||
'>'
|
||||
'"'
|
||||
);
|
||||
var attrib = options.attributes(icon, variant);
|
||||
if (attrib) {
|
||||
for (var attrname in attrib) {
|
||||
if (attrib.hasOwnProperty(attrname)) {
|
||||
// don't allow any handlers to be set, don't allow overrides
|
||||
if (attrname.indexOf('on') !== 0 && ret.indexOf(' ' + attrname + '=') === -1) {
|
||||
ret = ret.concat(' ', attrname, '="', escapeHTML(attrib[attrname]), '"');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = ret.concat('>');
|
||||
}
|
||||
}
|
||||
return match;
|
||||
return ret;
|
||||
});
|
||||
}
|
||||
|
||||
@ -517,12 +520,12 @@ define(function () {
|
||||
// if first argument is string, inject html <img> tags
|
||||
// otherwise use the DOM tree and parse text nodes only
|
||||
return (typeof what === 'string' ? parseString : parseNode)(what, {
|
||||
callback: how.callback || defaultImageSrcGenerator,
|
||||
attributes: how.attributes,
|
||||
base: typeof how.base === 'string' ? how.base : twemoji.base,
|
||||
ext: how.ext || twemoji.ext,
|
||||
size: how.folder || toSizeSquaredAsset(how.size || twemoji.size),
|
||||
className:how.className || twemoji.className
|
||||
callback: how.callback || defaultImageSrcGenerator,
|
||||
attributes: typeof how.attributes === 'function' ? how.attributes : function() {return {};},
|
||||
base: typeof how.base === 'string' ? how.base : twemoji.base,
|
||||
ext: how.ext || twemoji.ext,
|
||||
size: how.folder || toSizeSquaredAsset(how.size || twemoji.size),
|
||||
className: how.className || twemoji.className
|
||||
});
|
||||
}
|
||||
|
||||
|
65
twemoji.js
65
twemoji.js
@ -254,7 +254,7 @@ var twemoji = (function (
|
||||
* @param string text use in HTML attribute
|
||||
* @return string text encoded to use in HTML attribute
|
||||
*/
|
||||
function escape(s) {
|
||||
function escapeHTML(s) {
|
||||
var escaped = {
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
@ -266,7 +266,7 @@ var twemoji = (function (
|
||||
return escaped[m];
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default callback used to generate emoji src
|
||||
* based on Twitter CDN
|
||||
@ -380,18 +380,21 @@ var twemoji = (function (
|
||||
if (src) {
|
||||
img = new Image();
|
||||
img.onerror = twemoji.onerror;
|
||||
img.className = options.className;
|
||||
img.setAttribute('draggable', 'false');
|
||||
if (options.attributes && typeof(options.attributes) === 'function') {
|
||||
var attrib = options.attributes(alt);
|
||||
if (attrib) {
|
||||
for (var attrname in attrib) {
|
||||
if (attrname.lastIndexOf('on', 0) === -1) {
|
||||
|
||||
var attrib = options.attributes(icon, variant);
|
||||
if (attrib) {
|
||||
for (var attrname in attrib) {
|
||||
if (attrib.hasOwnProperty(attrname)) {
|
||||
// don't allow any handlers to be set, don't allow overrides
|
||||
if (attrname.indexOf('on') !== 0 && !img.hasAttribute(attrname)) {
|
||||
img.setAttribute(attrname, attrib[attrname]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
img.className = options.className;
|
||||
img.alt = alt;
|
||||
img.src = src;
|
||||
}
|
||||
@ -431,6 +434,7 @@ var twemoji = (function (
|
||||
function parseString(str, options) {
|
||||
return replace(str, function (match, icon, variant) {
|
||||
var src;
|
||||
var ret = match;
|
||||
// verify the variant is not the FE0E one
|
||||
// this variant means "emoji as text" and should not
|
||||
// require any action/replacement
|
||||
@ -444,19 +448,7 @@ var twemoji = (function (
|
||||
if (src) {
|
||||
// recycle the match string replacing the emoji
|
||||
// with its image counter part
|
||||
var attr_text = '';
|
||||
if (options.attributes && typeof(options.attributes) === 'function') {
|
||||
var attrib = options.attributes(match);
|
||||
if (attrib) {
|
||||
for (var attrname in attrib) {
|
||||
if (attrname.lastIndexOf('on', 0) === -1) {
|
||||
attr_text = attr_text + ' ' + attrname + '="' + escape(attrib[attrname]) + '"';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match = '<img '.concat(
|
||||
ret = '<img '.concat(
|
||||
'class="', options.className, '" ',
|
||||
'draggable="false" ',
|
||||
// needs to preserve user original intent
|
||||
@ -464,15 +456,26 @@ var twemoji = (function (
|
||||
'alt="',
|
||||
match,
|
||||
'"',
|
||||
attr_text,
|
||||
' src="',
|
||||
src,
|
||||
'"',
|
||||
'>'
|
||||
'"'
|
||||
);
|
||||
var attrib = options.attributes(icon, variant);
|
||||
if (attrib) {
|
||||
for (var attrname in attrib) {
|
||||
if (attrib.hasOwnProperty(attrname)) {
|
||||
// don't allow any handlers to be set, don't allow overrides
|
||||
if (attrname.indexOf('on') !== 0 && ret.indexOf(' ' + attrname + '=') === -1) {
|
||||
ret = ret.concat(' ', attrname, '="', escapeHTML(attrib[attrname]), '"');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = ret.concat('>');
|
||||
}
|
||||
}
|
||||
return match;
|
||||
return ret;
|
||||
});
|
||||
}
|
||||
|
||||
@ -516,12 +519,12 @@ var twemoji = (function (
|
||||
// if first argument is string, inject html <img> tags
|
||||
// otherwise use the DOM tree and parse text nodes only
|
||||
return (typeof what === 'string' ? parseString : parseNode)(what, {
|
||||
callback: how.callback || defaultImageSrcGenerator,
|
||||
attributes: how.attributes,
|
||||
base: typeof how.base === 'string' ? how.base : twemoji.base,
|
||||
ext: how.ext || twemoji.ext,
|
||||
size: how.folder || toSizeSquaredAsset(how.size || twemoji.size),
|
||||
className:how.className || twemoji.className
|
||||
callback: how.callback || defaultImageSrcGenerator,
|
||||
attributes: typeof how.attributes === 'function' ? how.attributes : function() {return {};},
|
||||
base: typeof how.base === 'string' ? how.base : twemoji.base,
|
||||
ext: how.ext || twemoji.ext,
|
||||
size: how.folder || toSizeSquaredAsset(how.size || twemoji.size),
|
||||
className: how.className || twemoji.className
|
||||
});
|
||||
}
|
||||
|
||||
|
2
twemoji.min.js
vendored
2
twemoji.min.js
vendored
File diff suppressed because one or more lines are too long
@ -255,7 +255,7 @@ var twemoji = (function (
|
||||
* @param string text use in HTML attribute
|
||||
* @return string text encoded to use in HTML attribute
|
||||
*/
|
||||
function escape(s) {
|
||||
function escapeHTML(s) {
|
||||
var escaped = {
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
@ -267,7 +267,7 @@ var twemoji = (function (
|
||||
return escaped[m];
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default callback used to generate emoji src
|
||||
* based on Twitter CDN
|
||||
@ -381,18 +381,21 @@ var twemoji = (function (
|
||||
if (src) {
|
||||
img = new Image();
|
||||
img.onerror = twemoji.onerror;
|
||||
img.className = options.className;
|
||||
img.setAttribute('draggable', 'false');
|
||||
if (options.attributes && typeof(options.attributes) === 'function') {
|
||||
var attrib = options.attributes(alt);
|
||||
if (attrib) {
|
||||
for (var attrname in attrib) {
|
||||
if (attrname.lastIndexOf('on', 0) === -1) {
|
||||
|
||||
var attrib = options.attributes(icon, variant);
|
||||
if (attrib) {
|
||||
for (var attrname in attrib) {
|
||||
if (attrib.hasOwnProperty(attrname)) {
|
||||
// don't allow any handlers to be set, don't allow overrides
|
||||
if (attrname.indexOf('on') !== 0 && !img.hasAttribute(attrname)) {
|
||||
img.setAttribute(attrname, attrib[attrname]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
img.className = options.className;
|
||||
img.alt = alt;
|
||||
img.src = src;
|
||||
}
|
||||
@ -432,6 +435,7 @@ var twemoji = (function (
|
||||
function parseString(str, options) {
|
||||
return replace(str, function (match, icon, variant) {
|
||||
var src;
|
||||
var ret = match;
|
||||
// verify the variant is not the FE0E one
|
||||
// this variant means "emoji as text" and should not
|
||||
// require any action/replacement
|
||||
@ -445,19 +449,7 @@ var twemoji = (function (
|
||||
if (src) {
|
||||
// recycle the match string replacing the emoji
|
||||
// with its image counter part
|
||||
var attr_text = '';
|
||||
if (options.attributes && typeof(options.attributes) === 'function') {
|
||||
var attrib = options.attributes(match);
|
||||
if (attrib) {
|
||||
for (var attrname in attrib) {
|
||||
if (attrname.lastIndexOf('on', 0) === -1) {
|
||||
attr_text = attr_text + ' ' + attrname + '="' + escape(attrib[attrname]) + '"';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match = '<img '.concat(
|
||||
ret = '<img '.concat(
|
||||
'class="', options.className, '" ',
|
||||
'draggable="false" ',
|
||||
// needs to preserve user original intent
|
||||
@ -465,15 +457,26 @@ var twemoji = (function (
|
||||
'alt="',
|
||||
match,
|
||||
'"',
|
||||
attr_text,
|
||||
' src="',
|
||||
src,
|
||||
'"',
|
||||
'>'
|
||||
'"'
|
||||
);
|
||||
var attrib = options.attributes(icon, variant);
|
||||
if (attrib) {
|
||||
for (var attrname in attrib) {
|
||||
if (attrib.hasOwnProperty(attrname)) {
|
||||
// don't allow any handlers to be set, don't allow overrides
|
||||
if (attrname.indexOf('on') !== 0 && ret.indexOf(' ' + attrname + '=') === -1) {
|
||||
ret = ret.concat(' ', attrname, '="', escapeHTML(attrib[attrname]), '"');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = ret.concat('>');
|
||||
}
|
||||
}
|
||||
return match;
|
||||
return ret;
|
||||
});
|
||||
}
|
||||
|
||||
@ -517,12 +520,12 @@ var twemoji = (function (
|
||||
// if first argument is string, inject html <img> tags
|
||||
// otherwise use the DOM tree and parse text nodes only
|
||||
return (typeof what === 'string' ? parseString : parseNode)(what, {
|
||||
callback: how.callback || defaultImageSrcGenerator,
|
||||
attributes: how.attributes,
|
||||
base: typeof how.base === 'string' ? how.base : twemoji.base,
|
||||
ext: how.ext || twemoji.ext,
|
||||
size: how.folder || toSizeSquaredAsset(how.size || twemoji.size),
|
||||
className:how.className || twemoji.className
|
||||
callback: how.callback || defaultImageSrcGenerator,
|
||||
attributes: typeof how.attributes === 'function' ? how.attributes : function() {return {};},
|
||||
base: typeof how.base === 'string' ? how.base : twemoji.base,
|
||||
ext: how.ext || twemoji.ext,
|
||||
size: how.folder || toSizeSquaredAsset(how.size || twemoji.size),
|
||||
className: how.className || twemoji.className
|
||||
});
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user