-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgs1LinksetViz.js
213 lines (195 loc) · 9.88 KB
/
gs1LinksetViz.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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
// The linksetViz function takes two arguments:
// 1. The linkset object
// 2. The element to which the visualization is to be appended
//
// Please note that this script does NOT constitute a validator for a linkset. That said, it does try to make minimal assumptions.
// We need a couple of constants
const RabinRegEx = /^((https?):)(\/\/((([^\/?#]*)@)?([^\/?#:]*)(:([^\/?#]*))?))?([^?#]*)(\?([^#]*))?(#(.*))?/;
const metaElementClass = 'metaElement';
const metaTitleClass = 'metaTitle'; // Used in CSS rules
const metaValueClass = 'metaValue'; // Used in CSS rules
const toTitleClass = 'toTitle';
function linksetViz(lsIn, displayElement) {
// Let's start by clearing the content of the display element
displayElement.innerHTML = null;
if (typeof lsIn.linkset === 'object') { // If this isn't true, we don't have a linkset
let linkset = lsIn.linkset; // So we're only looking at the linkset element within the object we were passed.
// A linkset is an array of objects
// Any objects can be included (e.g. as metadata) but the ones we're interested in are 'link context objects'
// Each link context object MUST have an "anchor" member with a value that represents the link context.
for (let context in linkset) {
if (linkset[context].anchor !== undefined) {
// We have a linkset that we'll present in an HTML section
let section = document.createElement('section');
section.classList.add('lsSection');
// Let's record the anchor
let sectionHead = document.createElement('h2');
sectionHead.classList.add('lsSectionHead');
let titleSpan = document.createElement('span');
titleSpan.className = metaTitleClass;
titleSpan.appendChild(document.createTextNode('GS1 Digital Link URI: '));
sectionHead.appendChild(titleSpan);
let valueSpan = document.createElement('span');
valueSpan.className = metaValueClass;
valueSpan.appendChild(document.createTextNode(linkset[context].anchor));
sectionHead.appendChild(valueSpan);
section.appendChild(sectionHead);
// And output any other info
// The GS1 resolver provides an item description
if (linkset[context].itemDescription !== undefined) {
let p = document.createElement('p');
p.className = metaElementClass;
p.classList.add('itemDescription');
titleSpan = document.createElement('span');
titleSpan.className = metaTitleClass;
titleSpan.appendChild(document.createTextNode('Item: '));
p.appendChild(titleSpan);
valueSpan = document.createElement('span');
valueSpan.className = metaValueClass;
valueSpan.appendChild(document.createTextNode(linkset[context].itemDescription));
p.appendChild(valueSpan);
section.appendChild(p);
}
// GS1 also provides a timestamp for the record that we can show
if (linkset[context].unixtime !== undefined) {
let p = document.createElement('p');
p.className = metaElementClass;
p.classList.add('lastModified');
titleSpan = document.createElement('span');
titleSpan.className = metaTitleClass;
titleSpan.appendChild(document.createTextNode('Last modified: '));
p.appendChild(titleSpan);
valueSpan = document.createElement('span');
valueSpan.className = metaValueClass;
let d = new Date(linkset[context].unixtime*1000);
valueSpan.appendChild(document.createTextNode(d.toISOString().replace('.000Z','Z')));
p.appendChild(valueSpan);
section.appendChild(p);
}
// Now we want to work through all the link types and display the links
// So we'll loop through link context and look for URLs
// Each link type will be a dt, and we'll make things below it dds.
let dl = document.createElement('dl');
dl.classList.add('linkList');
for (linkType in linkset[context]) {
// Ignore anythig that isn't a URL
if (RabinRegEx.test(linkType)) {
let dt = document.createElement('dt');
dt.className = 'linkType';
let a = document.createElement('a');
a.href = linkType;
a.appendChild(document.createTextNode(linkType));
dt.appendChild(a);
dl.appendChild(dt);
// The value should be an array of link objects (even if there's only one)
for (lo in linkset[context][linkType]) {
// Let's simplify this a little
let linkObject = linkset[context][linkType][lo];
// Now we work through the various elements within the link object, starting with the href
let dd = document.createElement('dd');
dd.className = 'href';
let span = document.createElement('span');
span.className = toTitleClass;
span.appendChild(document.createTextNode('Target URL: '));
dd.appendChild(span);
if (linkObject.href !== undefined) { // If this fails, there's something really quite wrong, as there is no link
a = document.createElement('a');
a.href = linkObject.href;
a.appendChild(document.createTextNode(linkObject.href));
dd.appendChild(a)
} else {
dd.appendChild(document.createTextNode('Error! There should be a link here.'));
dd.classList.add('error');
}
dl.appendChild(dd);
// Move on to the title
dd = document.createElement('dd');
dd.className = 'title';
span = document.createElement('span');
span.className = toTitleClass;
span.appendChild(document.createTextNode('Title: '));
dd.appendChild(span);
if (linkObject.title !== undefined) { // We have a simple title
dd.appendChild(document.createTextNode(linkObject.title));
} else if (linkObject['title*'] !== undefined) { // We have a complex title
let titleString = '';
for (let i in linkObject['title*']) {
titleString += linkObject['title*'][i].value + ' (' + linkObject['title*'][i].language + '); ';
}
titleString = titleString.substring(0, titleString.lastIndexOf(';'));
dd.appendChild(document.createTextNode(titleString));
} else {
dd.classList.add('error');
dd.appendChild(document.createTextNode('Error! There should be a title here.'));
}
dl.appendChild(dd);
// Move on to language(s)
if (linkObject.hreflang !== undefined) { // We should have an array of one or more languages to display
dd = document.createElement('dd');
dd.className = 'hreflang';
span = document.createElement('span');
span.className = toTitleClass;
span.appendChild(document.createTextNode('Language: '));
dd.appendChild(span);
if ((typeof linkObject.hreflang === 'object') && (linkObject.hreflang[0] !== undefined)) {// Hooray, we have an array of languages
let langString = '';
for (i in linkObject.hreflang) {
langString += linkObject.hreflang[i] + ', ';
}
langString = langString.substring(0, langString.lastIndexOf(','));
dd.appendChild(document.createTextNode(langString));
} else {
dd.appendChild(document.createTextNode('Error! Was expecting an array of languages'));
dd.classList.add('error');
}
dl.appendChild(dd);
}
// Media type
if ((linkObject.type !== undefined) && (linkObject.type !== '')) { // We have a media type.
dd = document.createElement('dd');
dd.className = 'mediaType';
span = document.createElement('span');
span.className = toTitleClass;
span.appendChild(document.createTextNode('Media type: '));
dd.appendChild(span);
dd.appendChild(document.createTextNode(linkObject.type));
dl.appendChild(dd);
}
// Context
if ((linkObject.context !== undefined) && (linkObject.context !== '')) { // We have a context.
dd = document.createElement('dd');
dd.className = 'context';
span = document.createElement('span');
span.className = toTitleClass;
span.appendChild(document.createTextNode('Context: '));
dd.appendChild(span);
dd.appendChild(document.createTextNode(linkObject.context));
dl.appendChild(dd);
}
// Forward Query String
if ((linkObject.fwqs !== undefined) && ((linkObject.fwqs === true) || (linkObject.fwqs === false))) { // We have a fwqs flag.
dd = document.createElement('dd');
dd.className = 'fwqs';
span = document.createElement('span');
span.className = toTitleClass;
span.appendChild(document.createTextNode('Forward query: '));
dd.appendChild(span);
dd.appendChild(document.createTextNode(linkObject.fwqs));
dl.appendChild(dd);
}
}
}
}
section.appendChild(dl);
displayElement.appendChild(section);
} else {
console.log('No anchor here');
}
}
} else {
let p = document.createElement('p');
p.className = 'error';
p.appendChild(document.createTextNode('Object cannot be parsed as a linkset'));
displayElement.appendChild(p);
}
}