From 7fc96d1a10ace1ae74e9aecc6a1718fc06facb63 Mon Sep 17 00:00:00 2001 From: Frank3K Date: Sat, 28 Jun 2014 21:27:41 +0200 Subject: [PATCH] Changed the way ID are collected. All referenced IDs are collected and mapped to uniqued IDs. Unreferenced IDs are removed in order to save space. --- Gruntfile.js | 9 ++++++ tasks/svgstore.js | 47 +++++++++++++++++------------ test/expected/cleanup.svg | 2 +- test/expected/includedemo-demo.html | 8 ++--- test/fixtures/usingdef.svg | 4 +-- test/svgstore_test.js | 12 ++++++-- 6 files changed, 53 insertions(+), 29 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index a4cbbba..59915f6 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -110,6 +110,15 @@ module.exports = function(grunt) { files: { 'tmp/cleanup.svg': ['test/fixtures/cleanup.svg'] } + }, + + removeunreferencedids: { + options: { + cleanup: true + }, + files: { + 'tmp/no_unref_ids.svg': ['test/fixtures/usingdef.svg'] + } } }, diff --git a/tasks/svgstore.js b/tasks/svgstore.js index 23cdf37..8373acd 100644 --- a/tasks/svgstore.js +++ b/tasks/svgstore.js @@ -68,26 +68,14 @@ module.exports = function (grunt) { }).map(function (filepath) { var filename = path.basename(filepath, '.svg'); var contentStr = grunt.file.read(filepath); - var uniqueId = md5(contentStr); var $ = cheerio.load(contentStr, { normalizeWhitespace: true, xmlMode: true }); // Map to store references from id to uniqueId + id; + // N.B.: only IDs that are referenced are mapped. var mappedIds = {}; - - // Make IDs unique - $('[id]').each(function () { - var $elem = $(this); - var id = $elem.attr('id'); - var newId = 'svgstore' + uniqueId + id; - mappedIds[id] = newId; - $elem.attr('id', newId); - }); - - // Search for an url() reference in every attribute of every tag - // replace the id with the unique one. $('*').each(function () { var $elem = $(this); var attrs = $elem.attr(); @@ -95,19 +83,38 @@ module.exports = function (grunt) { var value = attrs[key]; var match; while ((match = urlPattern.exec(value)) !== null) { - if (mappedIds[match[1]] !== undefined) { - value = value.replace(match[0], 'url(#' + mappedIds[match[1]] + ')'); - } else { - grunt.log.warn('Can\'t reference to id "' + match[1] + '" from attribute "' + attr + '" in "' + this[0].name + '" because it is not defined.'); + var refId = match[1]; + + // Add id mapping if not already present + if (!mappedIds[refId]) { + var uniqueId = md5(contentStr); + var newId = 'svgstore' + uniqueId + refId; + mappedIds[refId] = newId; } + + $elem.attr(key, value.replace(match[0], 'url(#' + mappedIds[refId] + ')')); } + if (options.cleanup && key === 'style') { - value = null; + $elem.removeAttr(key); } - $elem.attr(key, value); }); }); + // Apply ID mapping and remove unreferenced IDs + $('[id]').each(function () { + var $elem = $(this); + var id = $elem.attr('id'); + var newId = mappedIds[id]; + if (!newId) { + // ID is not refenced and can therefore be removed + $elem.removeAttr('id'); + } else { + // Replace id by mapped id + $elem.attr('id', newId); + } + }); + var $svg = $('svg'); var $title = $('title'); var $desc = $('desc'); @@ -150,7 +157,7 @@ module.exports = function (grunt) { $symbol.prepend('' + title + ''); } - // Add viewBox (if present of SVG) + // Add viewBox (if present on SVG) var viewBox = $svg.attr('viewBox'); if (viewBox) { $symbol.attr('viewBox', viewBox); diff --git a/test/expected/cleanup.svg b/test/expected/cleanup.svg index 797cb20..9d4fb5d 100644 --- a/test/expected/cleanup.svg +++ b/test/expected/cleanup.svg @@ -1 +1 @@ -cleanup image/svg+xml \ No newline at end of file +cleanup image/svg+xml \ No newline at end of file diff --git a/test/expected/includedemo-demo.html b/test/expected/includedemo-demo.html index 3525760..24186b8 100644 --- a/test/expected/includedemo-demo.html +++ b/test/expected/includedemo-demo.html @@ -10,7 +10,7 @@ - cleanup image/svg+xml Codepen IconThis is the offical Codepen icon cleanup image/svg+xml Codepen IconThis is the offical Codepen icon scissors scissors twitter twitter usingdef youtube usingdef youtube - - \ No newline at end of file + + diff --git a/test/svgstore_test.js b/test/svgstore_test.js index f5d19c5..36bc36b 100644 --- a/test/svgstore_test.js +++ b/test/svgstore_test.js @@ -118,6 +118,14 @@ exports.svgstore = { test.equal(actual, expected, 'Name should be cut after the first dot'); test.done(); - } + }, + + remove_unreferenced_ids: function(test){ + test.expect(1); -}; + var actual = grunt.file.read('tmp/no_unref_ids.svg'); + var expected = grunt.file.read('test/expected/no_unref_ids.svg'); + test.equal(actual, expected, 'Remove unreferenced IDs'); + + test.done(); + }};