/
iconSingleton.js
81 lines (68 loc) · 2.38 KB
/
iconSingleton.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/**
* IconSingleton.js
* Created by Kevin Li 7/19/16
*/
import Request from 'superagent';
import xmldoc from 'xmldoc';
import uuid from 'node-uuid';
require('../../../../graphics/icons.svg');
class IconSingleton {
constructor() {
this.subscribers = {};
this.svgCache = {};
this.svgLoaded = false;
this.svgRequested = false;
}
downloadIcons() {
this.svgRequested = true;
Request.get('graphics/icons.svg')
.send()
.end((err, res) => {
if (!err) {
// parse the response
this.parseSvg(res.text);
// mark the SVG as loaded
this.svgLoaded = true;
// notify any other icon components that the SVG data is ready
this.notifySubscribers('usa-da-icons.loaded');
}
});
}
parseSvg(rawSvg) {
// downloaded raw SVG data, send it through an XML parser
const data = new xmldoc.XmlDocument(rawSvg);
// iterate through each symbol and extract the symbol's content XML as a string and also its viewbox attribute
data.childrenNamed('symbol').forEach((symbol) => {
let childData = '';
symbol.eachChild((child) => {
childData += child.toString();
});
// save all this data into the svg data singleton
this.svgCache[symbol.attr.id] = {
data: childData,
viewBox: symbol.attr.viewBox
};
});
}
notifySubscribers(event) {
// iterate through subscribers to notify them that icons are ready
for (const subscriptionId in this.subscribers) {
if (Object.prototype.hasOwnProperty.call(this.subscribers, subscriptionId)) {
const subscriber = this.subscribers[subscriptionId];
subscriber(event);
}
}
}
subscribe(subscriber) {
// add a subscriber and return a UUID as a subscription ID so they can later unsubscribe
const subscriptionId = uuid.v4();
this.subscribers[subscriptionId] = subscriber;
return subscriptionId;
}
unsubscribe(subscriptionId) {
// unsubscribe the observer
delete this.subscribers[subscriptionId];
}
}
const instance = new IconSingleton();
export default instance;