1
0
mirror of https://github.com/twitter/twemoji.git synced 2025-03-28 19:20:28 +00:00

Update attributes option to only use a callback, more robust html encoding, add tests

This commit is contained in:
Derek Mooney 2015-03-01 02:07:00 -05:00
parent 13eac7a2d8
commit 3a3efd6063
6 changed files with 244 additions and 65 deletions

97
test.js
View File

@ -309,6 +309,103 @@ wru.test([{
div.getElementsByTagName('img')[0].className === className
);
}
},{
name: 'string parsing + attributes callback',
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!' ===
twemoji.parse(
'I \u2764 emoji!',
{
attributes: function(icon) {
return {
title: 'Emoji: ' + icon,
'data-test': 'We all <3 emoji'
};
}
}
)
);
}
},{
name: 'string parsing + attributes callback content properly encoded',
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!' ===
twemoji.parse(
'I \u2764 emoji!',
{
attributes: function(icon) {
return {
title: '&amp;lt;script&amp;gt;alert("yo")&amp;lt;/script&amp;gt;'
};
}
}
)
);
}
},{
name: 'string parsing + attributes callback "on" attributes are omitted',
test: function () {
wru.assert(
'custom attributes are inserted',
'I <img class="emoji" draggable="false" alt="❤" title="test" src="' + base + '36x36/2764.png"> emoji!' ===
twemoji.parse(
'I \u2764 emoji!',
{
attributes: function(icon) {
return {
title: 'test',
onsomething: 'whoops!',
onclick: 'nope',
onmousedown: 'nada'
};
}
}
)
);
}
},{
name: 'DOM parsing + attributes callback',
test: function () {
var img,
// without variant
div = document.createElement('div');
div.appendChild(document.createTextNode('I \u2764 emoji!'));
console.log(div);
twemoji.parse(
div, {
attributes: function(icon) {
return {
title: 'Emoji: ' + icon,
'data-test': 'We all <3 emoji',
onclick: 'nope',
onmousedown: 'nada'
};
}
}
);
wru.assert('default parsing works creating 3 nodes', div.childNodes.length === 3);
wru.assert('first child is the expected one', div.removeChild(div.firstChild).nodeValue === 'I ');
img = div.removeChild(div.firstChild);
wru.assert('second child is the image', img.nodeName === 'IMG');
wru.assert('img attributes are OK',
img.className === 'emoji' &&
img.getAttribute('draggable') === 'false' &&
img.src === base + '36x36/2764.png' &&
img.alt === '\u2764' &&
img.onerror === twemoji.onerror &&
img.getAttribute('title') === 'Emoji: \u2764' &&
img.getAttribute('data-test') === 'We all <3 emoji'
);
wru.assert('img on attributes are omitted',
img.onclick === null &&
img.onmousedown === null
);
}
},{
name: 'folder option',
test: function () {

View File

@ -527,6 +527,24 @@ function createTwemoji(re) {
return document.createTextNode(text);
}
/**
* Utility function to escape html attribute text
* @param string text use in HTML attribute
* @return string text encoded to use in HTML attribute
*/
function escape(s) {
var escaped = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
"'": '&#39;',
'"': '&quot;'
};
return s.replace(/[&<>'"]/g, function (m) {
return escaped[m];
});
}
/**
* Default callback used to generate emoji src
* based on Twitter CDN
@ -642,13 +660,15 @@ function createTwemoji(re) {
img.onerror = twemoji.onerror;
img.className = options.className;
img.setAttribute('draggable', 'false');
var attrib = options.attributes;
if (typeof(attrib) === 'function') {
attrib = attrib(alt);
}
if (attrib) {
for (var attrname in attrib) {
img.setAttribute(attrname) = attrib[attrname];
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) {
img.setAttribute(attrname, attrib[attrname]);
}
}
}
}
img.alt = alt;
@ -703,14 +723,16 @@ function createTwemoji(re) {
if (src) {
// recycle the match string replacing the emoji
// with its image counter part
var attrib = options.attributes;
if (typeof(attrib) === 'function') {
attrib = attrib(match);
}
var attr_text = '';
if (attrib) {
for (var attrname in attrib) {
attr_text = attr_text + ' ' + attrname + '="' + attrib[attrname].replace(/"/g, '&quot;') + '"';
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]) + '"';
}
}
}
}
@ -721,9 +743,9 @@ function createTwemoji(re) {
// when variants should be copied and pasted too
'alt="',
match,
'" ',
'"',
attr_text,
'src="',
' src="',
src,
'"',
'>'

View File

@ -250,6 +250,24 @@ define(function () {
return document.createTextNode(text);
}
/**
* Utility function to escape html attribute text
* @param string text use in HTML attribute
* @return string text encoded to use in HTML attribute
*/
function escape(s) {
var escaped = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
"'": '&#39;',
'"': '&quot;'
};
return s.replace(/[&<>'"]/g, function (m) {
return escaped[m];
});
}
/**
* Default callback used to generate emoji src
* based on Twitter CDN
@ -365,13 +383,14 @@ define(function () {
img.onerror = twemoji.onerror;
img.className = options.className;
img.setAttribute('draggable', 'false');
var attrib = options.attributes;
if (typeof(attrib) === 'function') {
attrib = attrib(alt);
}
if (attrib) {
for (var attrname in attrib) {
img.setAttribute(attrname) = attrib[attrname];
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) {
img.setAttribute(attrname, attrib[attrname]);
}
}
}
}
img.alt = alt;
@ -426,14 +445,15 @@ define(function () {
if (src) {
// recycle the match string replacing the emoji
// with its image counter part
var attrib = options.attributes;
if (typeof(attrib) === 'function') {
attrib = attrib(match);
}
var attr_text = '';
if (attrib) {
for (var attrname in attrib) {
attr_text = attr_text + ' ' + attrname + '="' + attrib[attrname].replace(/"/g, '&quot;') + '"';
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]) + '"';
}
}
}
}
@ -444,9 +464,9 @@ define(function () {
// when variants should be copied and pasted too
'alt="',
match,
'" ',
'"',
attr_text,
'src="',
' src="',
src,
'"',
'>'

View File

@ -249,6 +249,24 @@ var twemoji = (function (
return document.createTextNode(text);
}
/**
* Utility function to escape html attribute text
* @param string text use in HTML attribute
* @return string text encoded to use in HTML attribute
*/
function escape(s) {
var escaped = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
"'": '&#39;',
'"': '&quot;'
};
return s.replace(/[&<>'"]/g, function (m) {
return escaped[m];
});
}
/**
* Default callback used to generate emoji src
* based on Twitter CDN
@ -364,13 +382,14 @@ var twemoji = (function (
img.onerror = twemoji.onerror;
img.className = options.className;
img.setAttribute('draggable', 'false');
var attrib = options.attributes;
if (typeof(attrib) === 'function') {
attrib = attrib(alt);
}
if (attrib) {
for (var attrname in attrib) {
img.setAttribute(attrname) = attrib[attrname];
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) {
img.setAttribute(attrname, attrib[attrname]);
}
}
}
}
img.alt = alt;
@ -425,14 +444,15 @@ var twemoji = (function (
if (src) {
// recycle the match string replacing the emoji
// with its image counter part
var attrib = options.attributes;
if (typeof(attrib) === 'function') {
attrib = attrib(match);
}
var attr_text = '';
if (attrib) {
for (var attrname in attrib) {
attr_text = attr_text + ' ' + attrname + '="' + attrib[attrname].replace(/"/g, '&quot;') + '"';
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]) + '"';
}
}
}
}
@ -443,9 +463,9 @@ var twemoji = (function (
// when variants should be copied and pasted too
'alt="',
match,
'" ',
'"',
attr_text,
'src="',
' src="',
src,
'"',
'>'

2
twemoji.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -250,6 +250,24 @@ var twemoji = (function (
return document.createTextNode(text);
}
/**
* Utility function to escape html attribute text
* @param string text use in HTML attribute
* @return string text encoded to use in HTML attribute
*/
function escape(s) {
var escaped = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
"'": '&#39;',
'"': '&quot;'
};
return s.replace(/[&<>'"]/g, function (m) {
return escaped[m];
});
}
/**
* Default callback used to generate emoji src
* based on Twitter CDN
@ -365,13 +383,14 @@ var twemoji = (function (
img.onerror = twemoji.onerror;
img.className = options.className;
img.setAttribute('draggable', 'false');
var attrib = options.attributes;
if (typeof(attrib) === 'function') {
attrib = attrib(alt);
}
if (attrib) {
for (var attrname in attrib) {
img.setAttribute(attrname) = attrib[attrname];
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) {
img.setAttribute(attrname, attrib[attrname]);
}
}
}
}
img.alt = alt;
@ -426,14 +445,15 @@ var twemoji = (function (
if (src) {
// recycle the match string replacing the emoji
// with its image counter part
var attrib = options.attributes;
if (typeof(attrib) === 'function') {
attrib = attrib(match);
}
var attr_text = '';
if (attrib) {
for (var attrname in attrib) {
attr_text = attr_text + ' ' + attrname + '="' + attrib[attrname].replace(/"/g, '&quot;') + '"';
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]) + '"';
}
}
}
}
@ -444,9 +464,9 @@ var twemoji = (function (
// when variants should be copied and pasted too
'alt="',
match,
'" ',
'"',
attr_text,
'src="',
' src="',
src,
'"',
'>'