Client-side library to embed and transform remote SVG documents into a HTML page
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
example
lib
spec
.gitignore
CHANGELOG.md
README.md
config.js
package.json

README.md

Remote SVG

Embed and transform SVG documents from remote locations.

Add CSS classes, remove comments, add description and title elements and specify height and width attributes.

Changelog

All notable changes to this project are documented in the CHANGELOG.

Install

RemoteSVG is an ES6 module that can be installed via jspm. For example, install version 0.1.0 like this:

jspm install remote-svg=github:jamesmartin/remote-svg

Use

Simply add a (ideally hidden) DOM element in your document, with an ID and (at least) the following data attribute:

<!doctype html>
<script src="jspm_packages/system.js"></script>
<script src="config.js"></script>
<script>
  System.import('lib/main');
</script>

<body>
  <div id='my-svg' data-remote-svg-uri='/my-doc.svg' data-remote-svg-class='little-red'></div>
</body>

The RemoteSvg constructor returns a promise, so you can run your own code once the SVG has been fetched from the remote URI, transformed and embedded inline. Load the SVG like this:

import './style.css!';
import {RemoteSvg} from 'remote-svg';

new RemoteSvg(document.getElementById('my-svg'))
.then(function() { console.log('SVG loaded...'); })
.catch(function(err) { console.log('Something went wrong: ' + err); });

Here is the simple stylesheet we use:

.little-red {
  width: 5em;
  height: 5em;
  fill: red;
}

The SVG will be fetched from the remote location and embedded in place of your div, like this:

<svg id='my-svg' class='little-red'>
  <!-- svg data ... -->
</svg>

The full, working, example code is available.

Transformations

You can choose to apply transformations to the SVG by adding data attributes to the placeholder div. The following options are available:

key description
id the ID of the placeholder element will be applied to the SVG
class set a CSS class attribute on the SVG
size set width and height attributes on the SVG
Can also be set using height and/or width attributes, which take precedence over size
Supplied as "{Width} * {Height}" or "{Number}", so "30px*45px" becomes width="30px" and height="45px", and "50%" becomes width="50%" and height="50%"
title add a <title> node inside the top level of the SVG document
desc add a <desc> node inside the top level of the SVG document
nocomment remove comment tags (and other unsafe/unknown tags) from the svg
data all data attributes not prefixed with remote-svg will be copied to the SVG

An example of a placeholder element specifying some transformations follows:

<div 
  id='my-svg' 
  data-remote-svg-uri='http://example.com/my-doc.svg'
  data-remote-svg-class='my-class'
  data-remote-svg-height='25%'
  data-remote-svg-width='50px'
  data-remote-svg-desc='some description'
  data-remote-svg-title='some title'
  data-remote-nocomment='true'
  data-some-other-attr='my-attr'>
</div>

The output of the above transformations:

<svg id='my-svg' class='my-class' height='25%' width='50px' data-some-other-attr='my-attr'>
  <description>some description</description>
  <title>some title</title>
  <!-- svg data ... -->
</svg>

Contributing

Please fork, branch, test & pull-request. Thank you.

Local Development Setup

RemoteSvg is written in (mostly) ES6 module syntax. Its dependencies are managed, loaded and polyfilled with jspm.io and SystemJS.

To get the tests running locally, do this:

  1. Clone this repo.
  2. Install Node.js.
  3. Install jspm: npm install -g jspm/jspm-cli && npm install jspm --save-dev
  4. Install the dependencies locally (equivalent of bundle install in the Ruby world): jspm install
  5. I recommend using a simple reloading server, like live-server: npm install --global live-server

Testing

RemoteSvg is tested with jstest. Those familiar with jstest will be aware of the framework's use of the with(this) pattern to minimize pollution of the global namespace. For example:

JS.Test.describe('Some thing', function() { with(this) {
    describe('returning some value', function() { with(this) {
        it('does what we expect', function() { with(this) {
          assertEqual('some value', ourFunction());
        }});
      }});
  }});

Because RemoteSvg and its tests are loaded as ES6 modules, we are forced to run the tests in strict mode, which means we can't use the with(this) syntax, and our tests end up looking like this:

JS.Test.describe('Some thing', function() {
    this.describe('returning some value', function() {
        this.it('does what we expect', function() {
          this.assertEqual('some value', ourFunction());
        });
      });
  });

You will notice that because we also use Promises, and jstest's asynchronous tests, we also have to extract some of our assertions out into partially applied functions, in order to keep jstest's this and asnyc resume functions in scope:

JS.Test.describe('Some promise-based thing', function() {
    this.describe('returning some value', function() {
        this.it('does what we expect, eventually', function(resume) {

          var assertion = (function(jstest, resume) {
              return function(actual) {
                  jstest.assertEqual("expected", actual);
                  return resume();
                }
            })(this, resume);

          ourPromiseFunction().then(assertion);
        });
      });
  });