GUI -- implemeted GlyphService.loadDefs().

Change-Id: I2d93164dd6d1968982d3034b8c7bc50041d9bad9
diff --git a/web/gui/src/main/webapp/app/fw/svg/glyph.js b/web/gui/src/main/webapp/app/fw/svg/glyph.js
index 2afc102..8129c16 100644
--- a/web/gui/src/main/webapp/app/fw/svg/glyph.js
+++ b/web/gui/src/main/webapp/app/fw/svg/glyph.js
@@ -161,9 +161,17 @@
                 return glyphs.get(id);
             }
 
+            // Note: defs should be a D3 selection of a single <defs> element
             function loadDefs(defs) {
-                // TODO: clear defs element, then load all glyph definitions
+                // remove all existing content
+                defs.html(null);
 
+                // load up the currently registered glyphs
+                glyphs.values().forEach(function (g) {
+                    defs.append('symbol')
+                        .attr({ id: g.id, viewBox: g.vb })
+                        .append('path').attr('d', g.d);
+                });
             }
 
             return {
diff --git a/web/gui/src/main/webapp/tests/app/fw/svg/glyph-spec.js b/web/gui/src/main/webapp/tests/app/fw/svg/glyph-spec.js
index b6bd404..d743205 100644
--- a/web/gui/src/main/webapp/tests/app/fw/svg/glyph-spec.js
+++ b/web/gui/src/main/webapp/tests/app/fw/svg/glyph-spec.js
@@ -20,7 +20,7 @@
  @author Simon Hunt
  */
 describe('factory: fw/svg/glyph.js', function() {
-    var $log, fs, gs;
+    var $log, fs, gs, d3Elem;
 
     var numBaseGlyphs = 11,
         vbBird = '352 224 113 112',
@@ -33,8 +33,13 @@
         $log = _$log_;
         fs = FnService;
         gs = GlyphService;
+        d3Elem = d3.select('body').append('defs').attr('id', 'myDefs');
     }));
 
+    afterEach(function () {
+        d3.select('#myDefs').remove();
+    });
+
     it('should define GlyphService', function () {
         expect(gs).toBeDefined();
     });
@@ -168,4 +173,35 @@
         verifyGlyphLoaded('router', testVbox, 'M.5,.2');
         verifyGlyphLoaded('switch', testVbox, 'M.2,.5');
     });
+
+    function verifyPathPrefix(elem, prefix) {
+        var plen = prefix.length,
+            d = elem.select('path').attr('d');
+        expect(d.slice(0, plen)).toEqual(prefix);
+    }
+
+    it('should load base glyphs into the DOM', function () {
+        gs.init();
+        gs.loadDefs(d3Elem);
+        expect(d3Elem.selectAll('symbol').size()).toEqual(numBaseGlyphs);
+
+        // verify bgpSpeaker
+        var bs = d3Elem.select('#bgpSpeaker');
+        expect(bs.size()).toEqual(1);
+        expect(bs.attr('viewBox')).toEqual(vbGlyph);
+        verifyPathPrefix(bs, 'M10,40a45,35');
+    });
+
+    it('should load custom glyphs into the DOM', function () {
+        gs.init();
+        gs.register(testVbox, newGlyphs);
+        gs.loadDefs(d3Elem);
+        expect(d3Elem.selectAll('symbol').size()).toEqual(numBaseGlyphs + 2);
+
+        // verify diamond
+        var dia = d3Elem.select('#diamond');
+        expect(dia.size()).toEqual(1);
+        expect(dia.attr('viewBox')).toEqual(testVbox);
+        verifyPathPrefix(dia, 'M.2,.5l.3,-.3');
+    });
 });