1
0
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:
Derek Mooney 2015-04-11 09:49:52 -04:00
parent 1fa5a27fba
commit 5d4f6fabca
7 changed files with 154 additions and 130 deletions

View File

@ -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.

View File

@ -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 &lt;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 &lt;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;amp;lt;script&amp;amp;gt;alert(&quot;yo&quot;)&amp;amp;lt;/script&amp;amp;gt;" src="' + base + '36x36/2764.png"> emoji!' ===
'I <img class="emoji" draggable="false" alt="\u2764" src="' + base + '36x36/2764.png" title="&amp;amp;lt;script&amp;amp;gt;alert(&quot;yo&quot;)&amp;amp;lt;/script&amp;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!',
{

View File

@ -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 = {
'&': '&amp;',
'<': '&lt;',
@ -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
});
}

View File

@ -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 = {
'&': '&amp;',
'<': '&lt;',
@ -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
});
}

View File

@ -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 = {
'&': '&amp;',
'<': '&lt;',
@ -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

File diff suppressed because one or more lines are too long

View File

@ -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 = {
'&': '&amp;',
'<': '&lt;',
@ -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
});
}