Permalink
Browse files

Fix sprite multirendering

  • Loading branch information...
1 parent 42e0c75 commit 022a2ac527c3eb298eedd980d409a518dbbfef5e @outpunk outpunk committed Apr 29, 2015
Showing with 168 additions and 23 deletions.
  1. +6 −0 .jscsrc
  2. +21 −22 evil-icons.js
  3. +3 −1 package.json
  4. +138 −0 test/evil-icons.js
View
@@ -0,0 +1,6 @@
+{
+ "preset": "airbnb",
+ "disallowMultipleVarDecl": "exceptUndefined",
+ "requireCamelCaseOrUpperCaseIdentifiers": "ignoreProperties",
+ "disallowQuotedKeysInObjects": "allButReserved"
+}
View
@@ -1,41 +1,39 @@
var fs = require('fs');
-var spritePath = __dirname + "/assets/sprite.svg";
+var spritePath = __dirname + '/assets/sprite.svg';
var sprite = fs.readFileSync(spritePath).toString();
-
function icon(name, options) {
var options = options || {};
- var size = options.size ? "icon--" + options.size : "";
- var klass = "icon icon--" + name + " " + size + " " + (options.class || "");
-
+ var size = options.size ? ' icon--' + options.size : '';
+ var classes = 'icon icon--' + name + size + ' ' + (options.class || '');
+ classes = classes.trim();
- var icon = "<svg class='icon__cnt'>" +
- "<use xlink:href='#" + name + "-icon' />" +
- "</svg>";
+ var icon = '<svg class="icon__cnt">' +
+ '<use xlink:href="#' + name + '-icon" />' +
+ '</svg>';
- var html = "<div class='" + klass + "'>" +
- wrapSpinner(icon, klass) +
- "</div>";
+ var html = '<div class="' + classes + '">' +
+ wrapSpinner(icon, classes) +
+ '</div>';
return html;
}
-
function wrapSpinner(html, klass) {
- if (klass.indexOf("spinner") > -1) {
- return "<div class='icon__spinner'>" + html + "</div>";
+ if (klass.indexOf('spinner') > -1) {
+ return '<div class="icon__spinner">' + html + '</div>';
} else {
return html;
}
}
-
function buildParamsFromString(string) {
var paramsString;
var params = {};
+
var string = string.trim().replace(/['"]/gi, '');
- string.split(' ').forEach(function(param){
+ string.split(' ').forEach(function(param) {
var param = param.split('=');
var key = param[0];
var value = param[1];
@@ -46,11 +44,10 @@ function buildParamsFromString(string) {
return params;
}
-
function replaceIconTags(src) {
var match, tag, params, name;
var html = src.toString();
- var iconRegexp = /<icon\s+([-=\w\d'"\s]+)\s*\/?>(<\/icon>)?/gi;
+ var iconRegexp = /<icon\s+([-=\w\d'"\s]+)\s*\/?>(<\/icon>)?/gi;
while (match = iconRegexp.exec(html)) {
tag = match[0];
@@ -65,14 +62,16 @@ function replaceIconTags(src) {
return html;
}
-
function iconizeHtml(src) {
- var html = src.toString();
- html = html.replace(/<body.*?>/, function(match) { return match + sprite });
+ var html = src.toString();
+
+ if (html.indexOf(sprite) == -1) {
+ html = html.replace(/<body.*?>/, function(match) { return match + sprite });
+ }
+
return replaceIconTags(html);
}
-
module.exports = {
iconizeHtml: iconizeHtml,
sprite: sprite,
View
@@ -4,7 +4,7 @@
"description": "Evil Icons is a set of SVG icons designed extensively for using in modern web projects",
"main": "evil-icons.js",
"scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
+ "test": "jscs evil-icons.js test && mocha"
},
"repository": {
"type": "git",
@@ -30,6 +30,8 @@
},
"homepage": "http://evil-icons.io",
"devDependencies": {
+ "assert": "^1.3.0",
+ "mocha": "^2.2.4",
"svgo": "^0.5.0"
}
}
View
@@ -0,0 +1,138 @@
+var assert = require('assert');
+var icons = require('../evil-icons');
+
+describe('Evil Icons', function() {
+
+ describe('icon', function() {
+
+ function svg(icon) {
+ var svg = '<svg class="icon__cnt">' +
+ '<use xlink:href="#ei-' + icon + '-icon" />' +
+ '</svg>';
+ return svg;
+ }
+
+ it('renders', function() {
+ var actual = icons.icon('ei-search');
+ var expected = '<div class="icon icon--ei-search">' +
+ svg('search') +
+ '</div>';
+
+ assert.equal(actual, expected);
+ });
+
+ it('accepts size', function() {
+ var actual = icons.icon('ei-search', {size: 'l'});
+ var expected = '<div class="icon icon--ei-search icon--l">' +
+ svg('search') +
+ '</div>';
+
+ assert.equal(actual, expected);
+ });
+
+ it('accepts single class', function() {
+ var actual = icons.icon('ei-search', {class: 'foo'});
+ var expected = '<div class="icon icon--ei-search foo">' +
+ svg('search') +
+ '</div>';
+
+ assert.equal(actual, expected);
+ });
+
+ it('accepts multiple classes', function() {
+ var actual = icons.icon('ei-search', {class: 'foo bar'});
+ var expected = '<div class="icon icon--ei-search foo bar">' +
+ svg('search') +
+ '</div>';
+
+ assert.equal(actual, expected);
+ });
+
+ it('wraps spinners', function() {
+ var actual = icons.icon('ei-spinner');
+ var expected = '<div class="icon icon--ei-spinner">' +
+ '<div class="icon__spinner">' +
+ svg('spinner') +
+ '</div>' +
+ '</div>';
+
+ assert.equal(actual, expected);
+ });
+
+ });
+
+ describe('iconizeHtml', function() {
+
+ function doc(html) {
+ var head = '<!DOCTYPE html><html><head><title>Evil Icons</title></head>';
+ return head + html;
+ }
+
+ function docWithSprite(html) {
+ return doc('<body>' + icons.sprite + html + '</body>');
+ }
+
+ it('renders sprite', function() {
+ var actual = icons.iconizeHtml(doc('<body> </body>'));
+ var expected = doc('<body>' + icons.sprite + ' </body>');
+
+ assert.equal(actual, expected);
+
+ actual = icons.iconizeHtml(doc('<body class=red> </body>'));
+ expected = doc('<body class=red>' + icons.sprite + ' </body>');
+
+ assert.equal(actual, expected);
+
+ actual = icons.iconizeHtml(doc('<body class=red data-attr="a"> </body>'));
+ expected = doc('<body class=red data-attr="a">' + icons.sprite + ' </body>');
+
+ assert.equal(actual, expected);
+ });
+
+ it('doesn\'t render sprite twice', function() {
+ var expected = doc('<body>' + icons.sprite + ' </body>');
+ var actual = icons.iconizeHtml(doc('<body> </body>'));
+ actual = icons.iconizeHtml(actual);
+
+ assert.equal(actual, expected);
+ });
+
+ it('replaces single icon tag', function() {
+ var html = docWithSprite('<icon name="ei-archive" />');
+ var actual = icons.iconizeHtml(html);
+ var expected = docWithSprite(icons.icon('ei-archive'));
+
+ assert.equal(actual, expected);
+ });
+
+ it('replaces multiple icon tags', function() {
+ var html = docWithSprite(
+ '<p>Some&nbsp;entities</p>\n' +
+ '<icon name="ei-archive" />\n' +
+ '<a href="http://evil-icons.io>Evil Icons</a>\n' +
+ '<icon name="ei-search" />\n'
+ );
+
+ var expected = docWithSprite(
+ '<p>Some&nbsp;entities</p>\n' +
+ icons.icon('ei-archive') + '\n' +
+ '<a href="http://evil-icons.io>Evil Icons</a>\n' +
+ icons.icon('ei-search') + '\n'
+ );
+
+ var actual = icons.iconizeHtml(html);
+
+ assert.equal(actual, expected);
+ });
+
+ it('respects icon size attr', function() {
+ var html = docWithSprite('<icon name="ei-archive" size="l" />');
+ var actual = icons.iconizeHtml(html);
+ var expected = docWithSprite(icons.icon('ei-archive', {size: 'l'}));
+
+ assert.equal(actual, expected);
+ });
+
+ });
+
+});

0 comments on commit 022a2ac

Please sign in to comment.