-
Notifications
You must be signed in to change notification settings - Fork 125
/
Copy pathresolveReferences.js
294 lines (259 loc) · 9.85 KB
/
resolveReferences.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
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
/* globals respecConfig, $, localRoleInfo, roleInfo, require */
/* exported linkCrossReferences, restrictReferences, fixIncludes */
function linkCrossReferences() {
"use strict";
var specBaseURL = ( respecConfig.ariaSpecURLs ?
respecConfig.ariaSpecURLs[respecConfig.specStatus] : null
);
var coreMappingURL = (respecConfig.coreMappingURLs ?
respecConfig.coreMappingURLs[respecConfig.specStatus] : null
);
var accNameURL = (respecConfig.accNameURLs ?
respecConfig.accNameURLs[respecConfig.specStatus] : null
);
var htmlMappingURL = (respecConfig.htmlMappingURLs ?
respecConfig.htmlMappingURLs[respecConfig.specStatus] : null
);
var dpubModURL = ( respecConfig.dpubModURLs ?
respecConfig.dpubModURLs[respecConfig.specStatus] : null
);
var graphicsModURL = ( respecConfig.graphicsModURLs ?
respecConfig.graphicsModURLs[respecConfig.specStatus] : null
);
var graphicsMappingModURL = ( respecConfig.graphicsMappingModURLs ?
respecConfig.graphicsMappingModURLs[respecConfig.specStatus] : null
);
var practicesURL = ( respecConfig.practicesURLs ?
respecConfig.practicesURLs[respecConfig.specStatus] : null
);
function setHrefs (selString, baseUrl) {
$ (selString).each (
function (idx, el) {
var href = $ (el).attr ('href');
$ (el).attr ('href', baseUrl + href);
});
}
// First the links to the definitions of roles, states, and properties.
if (!!specBaseURL) {
setHrefs ('a.role-reference, a.property-reference, a.state-reference, a.specref', specBaseURL);
}
else {
console.log ("linkCrossReferences(): specBaseURL is not defined.");
}
// Second, for links to role, state, and property mappings in the core mapping
// doc.
if (!!coreMappingURL) {
setHrefs ('a.core-mapping', coreMappingURL);
}
else {
console.log ("linkCrossReferences(): Note -- coreMappingURL is not defined.");
}
// Third, for links into the accname document.
if (!!accNameURL) {
setHrefs ('a.accname', accNameURL);
}
else {
console.log ("linkCrossReferences(): Note -- accNameURL is not defined.");
}
// Fourth, for links to role, state, and property mappings in the html mapping
// doc.
if (!!htmlMappingURL) {
setHrefs ('a.html-mapping', htmlMappingURL);
}
else {
console.log ("linkCrossReferences(): Note -- htmlMappingURL is not defined.");
}
// Links to the DPub WAI-ARIA Module.
if (!!dpubModURL) {
setHrefs ('a.dpub-role-reference, a.dpub-property-reference, a.dpub-state-reference, a.dpub', dpubModURL);
}
else {
console.log ("linkCrossReferences(): dpubModURL is not defined.");
}
// Links to the Graphics WAI-ARIA Module.
if (!!graphicsModURL) {
setHrefs ('a.graphics-role-reference, a.graphics-property-reference, a.graphics-state-reference, a.graphics', graphicsModURL);
}
else {
console.log ("linkCrossReferences(): graphicsModURL is not defined.");
}
// Links to the Graphics Mapping WAI-ARIA Module.
if (!!graphicsMappingModURL) {
setHrefs ('a.graphics-role-mapping, a.graphics-property-mapping, a.graphics-state-mapping, a.graphics-mapping', graphicsMappingModURL);
}
else {
console.log ("linkCrossReferences(): graphicsMappingModURL is not defined.");
}
// Links to the Authoring Practices.
if (!!practicesURL) {
setHrefs ('a.practices', practicesURL);
}
else {
console.log ("linkCrossReferences(): practicesURL is not defined.");
}
}
function updateReferences(base) {
// update references to properties
//
// New logic:
// 1. for each item, find it's nearest 'section' ancestor (or nearest div
// with a class of role, property, or state)
// 2. if we have not already seen this item in this section, it is a link using 'a'
// 3. otherwise, it is just a styled reference to the item using 'code'
"use strict";
var baseURL = respecConfig.ariaSpecURLs[respecConfig.specStatus];
var sectionMap = {} ;
$.each(base.querySelectorAll("pref, sref, rref"), function(i, item) {
var $item = $(item) ;
// what are we referencing?
var content = $item.text();
var usedTitle = false;
var ref = $item.attr("title");
if (!ref) {
ref = $item.attr("data-lt");
if (!ref) {
ref = content;
} else {
usedTitle = true;
}
} else {
usedTitle = true;
}
// what sort of reference are we?
var theClass = ($item.is("pref") ? "property-reference" : ($item.is("sref") ? "state-reference" : "role-reference"));
// property and state references are assumed to be in the parent document
// a role reference might be local or might be elsewhere
var URL = $item.is("pref, sref") ? baseURL+"#" : "#";
// assume we are making a link
var theElement = "a";
// pSec is the nearest parent section element
var $pSec = $item.parents("section,div.role,div.state,div.property").first();
var pID = $pSec.attr("id");
if (pID) {
if (sectionMap[pID]) {
if (sectionMap[pID][ref]) {
// only change the element if we not in a table or a dl
if ($item.parents("table,dl").length === 0) {
if (usedTitle) {
theElement = "span";
} else {
theElement = "code";
}
}
} else {
sectionMap[pID][ref] = 1;
}
} else {
sectionMap[pID] = {} ;
sectionMap[pID][ref] = 1;
}
}
if (theElement === "a" && $item.is('rref') ) {
if (typeof localRoleInfo !== 'undefined' && localRoleInfo[ref]) {
ref = localRoleInfo[ref].fragID;
} else if (baseURL && roleInfo[ref]) {
ref = roleInfo[ref].fragID;
URL = baseURL + "#";
} else {
// no roleInfo structure. Make an assumption
URL = baseURL + "#";
}
}
var sp = document.createElement(theElement);
if (theElement === "a") {
sp.href = URL + ref;
sp.className = theClass;
content = "<code>" + content + "</code>";
}
sp.innerHTML=content;
$item.replaceWith(sp);
});
}
// We should be able to remove terms that are not actually
// referenced from the common definitions. This array is
// indexed with the element ids of the dfn tags to be pruned.
var termNames = [] ;
function restrictReferences(utils, content) {
"use strict";
var base = document.createElement("div");
base.innerHTML = content;
updateReferences(base);
// strategy: Traverse the content finding all of the terms defined
$.each(base.querySelectorAll("dfn"), function(i, item) {
var $t = $(item) ;
var titles = $t.getDfnTitles();
var n = $t.makeID("dfn", titles[0]);
if (n) {
termNames[n] = $t.parent() ;
}
});
return (base.innerHTML);
}
// add a handler to come in after all the definitions are resolved
//
// New logic: If the reference is within a 'dl' element of
// class 'termlist', and if the target of that reference is
// also within a 'dl' element of class 'termlist', then
// consider it an internal reference and ignore it -- assuming
// it is not part of another included term.
require(["core/pubsubhub"], function(respecEvents) {
"use strict";
respecEvents.sub('end', function(message) {
if (message === 'core/link-to-dfn') {
// all definitions are linked
$("a.internalDFN").each(function () {
var $item = $(this) ;
var t = $item.attr('href');
if ( $item.closest('dl.termlist').length ) {
if ( $(t).closest('dl.termlist').length ) {
// Figure out the id of the glossary term which holds this
// internal reference and see if it will be pruned (i.e.
// is in the termNames array). If it is, we can ignore
// this particular internal reference.
var dfn = $item.closest('dd').prev().find('dfn');
var parentTermId = dfn.makeID('dfn', dfn.getDfnTitles[0]);
if (termNames[parentTermId])
return;
}
}
var r = t.replace(/^#/,"") ;
if (termNames[r]) {
delete termNames[r] ;
}
});
// delete any terms that were not referenced.
Object.keys(termNames).forEach(function(term) {
var $p = $("#"+term);
if ($p) {
// Delete altered dfn elements and refs
$p.parent().next().remove();
$p.parent().remove();
$p.getDfnTitles().forEach(function( item ) {
if (respecConfig.definitionMap[item]) {
delete respecConfig.definitionMap[item];
}
});
}
});
}
});
});
// included files are brought in after proProc. Create a DOM tree
// of content then call the updateReferences method above on it. Return
// the transformed content
function fixIncludes(utils, content) {
"use strict";
var base = document.createElement("div");
base.innerHTML = content;
updateReferences(base);
return (base.innerHTML);
}
// Fix the scroll-to-fragID problem:
require(["core/pubsubhub"], function (respecEvents) {
"use strict";
respecEvents.sub("end-all", function () {
if(window.location.hash) {
window.location = window.location.hash;
}
});
});