@lblod/graph-rdfa-processor 0.13.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,1160 @@
1
+ import URIResolver from "./uri-resolver";
2
+ import Node from "./node";
3
+
4
+ export default class RDFaProcessor extends URIResolver {
5
+ constructor(targetObject) {
6
+ super();
7
+
8
+ if (targetObject) {
9
+ this.target = targetObject;
10
+ } else {
11
+ this.target = {
12
+ graph: {
13
+ subjects: {},
14
+ prefixes: {},
15
+ terms: {},
16
+ },
17
+ };
18
+ }
19
+ this.theOne = "_:" + new Date().getTime();
20
+ this.language = null;
21
+ this.vocabulary = null;
22
+ this.blankCounter = 0;
23
+ this.langAttributes = [
24
+ {
25
+ namespaceURI: "http://www.w3.org/XML/1998/namespace",
26
+ localName: "lang",
27
+ },
28
+ ];
29
+ this.inXHTMLMode = false;
30
+ this.absURIRE = /[\w\_\-]+:\S+/;
31
+ this.finishedHandlers = [];
32
+ this.init();
33
+ }
34
+
35
+ newBlankNode() {
36
+ this.blankCounter++;
37
+ return "_:" + this.blankCounter;
38
+ }
39
+
40
+ tokenize(str) {
41
+ return RDFaProcessor.trim(str).split(/\s+/);
42
+ }
43
+
44
+ parseSafeCURIEOrCURIEOrURI(value, prefixes, base) {
45
+ value = RDFaProcessor.trim(value);
46
+ if (value.charAt(0) == "[" && value.charAt(value.length - 1) == "]") {
47
+ value = value.substring(1, value.length - 1);
48
+ value = value.trim(value);
49
+ if (value.length == 0) {
50
+ return null;
51
+ }
52
+ if (value == "_:") {
53
+ // the one node
54
+ return this.theOne;
55
+ }
56
+ return this.parseCURIE(value, prefixes, base);
57
+ } else {
58
+ return this.parseCURIEOrURI(value, prefixes, base);
59
+ }
60
+ }
61
+
62
+ parseCURIE(value, prefixes, base) {
63
+ var colon = value.indexOf(":");
64
+ if (colon >= 0) {
65
+ var prefix = value.substring(0, colon);
66
+ if (prefix == "") {
67
+ // default prefix
68
+ var uri = prefixes[""];
69
+ return uri ? uri + value.substring(colon + 1) : null;
70
+ } else if (prefix == "_") {
71
+ // blank node
72
+ return "_:" + value.substring(colon + 1);
73
+ } else if (RDFaProcessor.NCNAME.test(prefix)) {
74
+ var uri = prefixes[prefix];
75
+ if (uri) {
76
+ return uri + value.substring(colon + 1);
77
+ }
78
+ }
79
+ }
80
+ return null;
81
+ }
82
+
83
+ parseCURIEOrURI(value, prefixes, base) {
84
+ var curie = this.parseCURIE(value, prefixes, base);
85
+ if (curie) {
86
+ return curie;
87
+ }
88
+ return this.resolveAndNormalize(base, value);
89
+ }
90
+
91
+ parsePredicate(value, defaultVocabulary, terms, prefixes, base, ignoreTerms) {
92
+ if (value == "") {
93
+ return null;
94
+ }
95
+ var predicate = this.parseTermOrCURIEOrAbsURI(
96
+ value,
97
+ defaultVocabulary,
98
+ ignoreTerms ? null : terms,
99
+ prefixes,
100
+ base,
101
+ );
102
+ if (predicate && predicate.indexOf("_:") == 0) {
103
+ return null;
104
+ }
105
+ return predicate;
106
+ }
107
+
108
+ parseTermOrCURIEOrURI(value, defaultVocabulary, terms, prefixes, base) {
109
+ //alert("Parsing "+value+" with default vocab "+defaultVocabulary);
110
+ value = RDFaProcessor.trim(value);
111
+ var curie = this.parseCURIE(value, prefixes, base);
112
+ if (curie) {
113
+ return curie;
114
+ } else {
115
+ var term = terms[value];
116
+ if (term) {
117
+ return term;
118
+ }
119
+ var lcvalue = value.toLowerCase();
120
+ term = terms[lcvalue];
121
+ if (term) {
122
+ return term;
123
+ }
124
+ if (defaultVocabulary && !this.absURIRE.exec(value)) {
125
+ return defaultVocabulary + value;
126
+ }
127
+ }
128
+ return this.resolveAndNormalize(base, value);
129
+ }
130
+
131
+ parseTermOrCURIEOrAbsURI(value, defaultVocabulary, terms, prefixes, base) {
132
+ //alert("Parsing "+value+" with default vocab "+defaultVocabulary);
133
+ value = RDFaProcessor.trim(value);
134
+ var curie = this.parseCURIE(value, prefixes, base);
135
+ if (curie) {
136
+ return curie;
137
+ } else if (terms) {
138
+ if (defaultVocabulary && !this.absURIRE.exec(value)) {
139
+ return defaultVocabulary + value;
140
+ }
141
+ var term = terms[value];
142
+ if (term) {
143
+ return term;
144
+ }
145
+ var lcvalue = value.toLowerCase();
146
+ term = terms[lcvalue];
147
+ if (term) {
148
+ return term;
149
+ }
150
+ }
151
+ if (this.absURIRE.exec(value)) {
152
+ return this.resolveAndNormalize(base, value);
153
+ }
154
+ return null;
155
+ }
156
+
157
+ resolveAndNormalize(base, href) {
158
+ var u = base.resolve(href);
159
+ var parsed = this.parseURI(u);
160
+ parsed.normalize();
161
+ return parsed.spec;
162
+ }
163
+
164
+ parsePrefixMappings(str, target) {
165
+ var values = this.tokenize(str);
166
+ var prefix = null;
167
+ var uri = null;
168
+ for (var i = 0; i < values.length; i++) {
169
+ if (values[i][values[i].length - 1] == ":") {
170
+ prefix = values[i].substring(0, values[i].length - 1);
171
+ } else if (prefix) {
172
+ target[prefix] = this.target.baseURI
173
+ ? this.target.baseURI.resolve(values[i])
174
+ : values[i];
175
+ prefix = null;
176
+ }
177
+ }
178
+ }
179
+
180
+ copyMappings(mappings) {
181
+ var newMappings = {};
182
+ for (var k in mappings) {
183
+ newMappings[k] = mappings[k];
184
+ }
185
+ return newMappings;
186
+ }
187
+
188
+ ancestorPath(node) {
189
+ var path = "";
190
+ while (node && node.nodeType != Node.DOCUMENT_NODE) {
191
+ path = "/" + node.localName + path;
192
+ node = node.parentNode;
193
+ }
194
+ return path;
195
+ }
196
+
197
+ setContext(node) {
198
+ // We only recognized XHTML+RDFa 1.1 if the version is set propertyly
199
+ if (
200
+ node.localName == "html" &&
201
+ node.getAttribute("version") == "XHTML+RDFa 1.1"
202
+ ) {
203
+ this.setXHTMLContext();
204
+ } else if (
205
+ node.localName == "html" ||
206
+ node.namespaceURI == "http://www.w3.org/1999/xhtml"
207
+ ) {
208
+ if (node.ownerDocument.doctype) {
209
+ if (
210
+ node.ownerDocument.doctype.publicId ==
211
+ "-//W3C//DTD XHTML+RDFa 1.0//EN" &&
212
+ node.ownerDocument.doctype.systemId ==
213
+ "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd"
214
+ ) {
215
+ console.log(
216
+ "WARNING: RDF 1.0 is not supported. Defaulting to HTML5 mode.",
217
+ );
218
+ this.setHTMLContext();
219
+ } else if (
220
+ node.ownerDocument.doctype.publicId ==
221
+ "-//W3C//DTD XHTML+RDFa 1.1//EN" &&
222
+ node.ownerDocument.doctype.systemId ==
223
+ "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-2.dtd"
224
+ ) {
225
+ this.setXHTMLContext();
226
+ } else {
227
+ this.setHTMLContext();
228
+ }
229
+ } else {
230
+ this.setHTMLContext();
231
+ }
232
+ } else {
233
+ this.setXMLContext();
234
+ }
235
+ }
236
+
237
+ setInitialContext() {
238
+ this.vocabulary = null;
239
+ // By default, the prefixes are terms are loaded to the RDFa 1.1. standard within the graph constructor
240
+ this.langAttributes = [
241
+ {
242
+ namespaceURI: "http://www.w3.org/XML/1998/namespace",
243
+ localName: "lang",
244
+ },
245
+ ];
246
+ }
247
+
248
+ setXMLContext() {
249
+ this.setInitialContext();
250
+ this.inXHTMLMode = false;
251
+ this.inHTMLMode = false;
252
+ }
253
+
254
+ setHTMLContext() {
255
+ this.setInitialContext();
256
+ this.langAttributes = [
257
+ {
258
+ namespaceURI: "http://www.w3.org/XML/1998/namespace",
259
+ localName: "lang",
260
+ },
261
+ { namespaceURI: null, localName: "lang" },
262
+ ];
263
+ this.inXHTMLMode = false;
264
+ this.inHTMLMode = true;
265
+ }
266
+
267
+ setXHTMLContext() {
268
+ this.setInitialContext();
269
+
270
+ this.inXHTMLMode = true;
271
+ this.inHTMLMode = false;
272
+
273
+ this.langAttributes = [
274
+ {
275
+ namespaceURI: "http://www.w3.org/XML/1998/namespace",
276
+ localName: "lang",
277
+ },
278
+ { namespaceURI: null, localName: "lang" },
279
+ ];
280
+
281
+ // From http://www.w3.org/2011/rdfa-context/xhtml-rdfa-1.1
282
+ this.target.graph.terms["alternate"] =
283
+ "http://www.w3.org/1999/xhtml/vocab#alternate";
284
+ this.target.graph.terms["appendix"] =
285
+ "http://www.w3.org/1999/xhtml/vocab#appendix";
286
+ this.target.graph.terms["bookmark"] =
287
+ "http://www.w3.org/1999/xhtml/vocab#bookmark";
288
+ this.target.graph.terms["cite"] = "http://www.w3.org/1999/xhtml/vocab#cite";
289
+ this.target.graph.terms["chapter"] =
290
+ "http://www.w3.org/1999/xhtml/vocab#chapter";
291
+ this.target.graph.terms["contents"] =
292
+ "http://www.w3.org/1999/xhtml/vocab#contents";
293
+ this.target.graph.terms["copyright"] =
294
+ "http://www.w3.org/1999/xhtml/vocab#copyright";
295
+ this.target.graph.terms["first"] =
296
+ "http://www.w3.org/1999/xhtml/vocab#first";
297
+ this.target.graph.terms["glossary"] =
298
+ "http://www.w3.org/1999/xhtml/vocab#glossary";
299
+ this.target.graph.terms["help"] = "http://www.w3.org/1999/xhtml/vocab#help";
300
+ this.target.graph.terms["icon"] = "http://www.w3.org/1999/xhtml/vocab#icon";
301
+ this.target.graph.terms["index"] =
302
+ "http://www.w3.org/1999/xhtml/vocab#index";
303
+ this.target.graph.terms["last"] = "http://www.w3.org/1999/xhtml/vocab#last";
304
+ this.target.graph.terms["license"] =
305
+ "http://www.w3.org/1999/xhtml/vocab#license";
306
+ this.target.graph.terms["meta"] = "http://www.w3.org/1999/xhtml/vocab#meta";
307
+ this.target.graph.terms["next"] = "http://www.w3.org/1999/xhtml/vocab#next";
308
+ this.target.graph.terms["prev"] = "http://www.w3.org/1999/xhtml/vocab#prev";
309
+ this.target.graph.terms["previous"] =
310
+ "http://www.w3.org/1999/xhtml/vocab#previous";
311
+ this.target.graph.terms["section"] =
312
+ "http://www.w3.org/1999/xhtml/vocab#section";
313
+ this.target.graph.terms["stylesheet"] =
314
+ "http://www.w3.org/1999/xhtml/vocab#stylesheet";
315
+ this.target.graph.terms["subsection"] =
316
+ "http://www.w3.org/1999/xhtml/vocab#subsection";
317
+ this.target.graph.terms["start"] =
318
+ "http://www.w3.org/1999/xhtml/vocab#start";
319
+ this.target.graph.terms["top"] = "http://www.w3.org/1999/xhtml/vocab#top";
320
+ this.target.graph.terms["up"] = "http://www.w3.org/1999/xhtml/vocab#up";
321
+ this.target.graph.terms["p3pv1"] =
322
+ "http://www.w3.org/1999/xhtml/vocab#p3pv1";
323
+
324
+ // other
325
+ this.target.graph.terms["related"] =
326
+ "http://www.w3.org/1999/xhtml/vocab#related";
327
+ this.target.graph.terms["role"] = "http://www.w3.org/1999/xhtml/vocab#role";
328
+ this.target.graph.terms["transformation"] =
329
+ "http://www.w3.org/1999/xhtml/vocab#transformation";
330
+ }
331
+
332
+ init() { }
333
+
334
+ newSubjectOrigin(origin, subject) { }
335
+
336
+ addTriple(origin, subject, predicate, object) { }
337
+
338
+ process(node, options) {
339
+ if (node.nodeType == Node.DOCUMENT_NODE) {
340
+ node = node.documentElement;
341
+ this.setContext(node);
342
+ } else if (node.parentNode.nodeType == Node.DOCUMENT_NODE) {
343
+ this.setContext(node);
344
+ }
345
+ var queue = [];
346
+ // Fix for Firefox that includes the hash in the base URI
347
+ var removeHash = function(baseURI) {
348
+ var hash = baseURI.indexOf("#");
349
+ if (hash >= 0) {
350
+ baseURI = baseURI.substring(0, hash);
351
+ }
352
+ if (options && options.baseURIMap) {
353
+ baseURI = options.baseURIMap(baseURI);
354
+ }
355
+ if (baseURI == "about:blank") {
356
+ baseURI = options.baseURI;
357
+ }
358
+ return baseURI;
359
+ };
360
+ queue.push({
361
+ current: node,
362
+ context: this.push(null, removeHash(node.baseURI)),
363
+ });
364
+ while (queue.length > 0) {
365
+ var item = queue.shift();
366
+ if (item.parent) {
367
+ // Sequence Step 14: list triple generation
368
+ if (
369
+ item.context.parent &&
370
+ item.context.parent.listMapping == item.listMapping
371
+ ) {
372
+ // Skip a child context with exactly the same mapping
373
+ continue;
374
+ }
375
+ //console.log("Generating lists for "+item.subject+", tag "+item.parent.localName);
376
+ for (var predicate in item.listMapping) {
377
+ var list = item.listMapping[predicate];
378
+ if (list.length == 0) {
379
+ this.addTriple(item.parent, item.subject, predicate, {
380
+ type: RDFaProcessor.objectURI,
381
+ value: "http://www.w3.org/1999/02/22-rdf-syntax-ns#nil",
382
+ });
383
+ continue;
384
+ }
385
+ var bnodes = [];
386
+ for (var i = 0; i < list.length; i++) {
387
+ bnodes.push(this.newBlankNode());
388
+ //this.newSubject(item.parent,bnodes[i]);
389
+ }
390
+ for (var i = 0; i < bnodes.length; i++) {
391
+ this.addTriple(
392
+ item.parent,
393
+ bnodes[i],
394
+ "http://www.w3.org/1999/02/22-rdf-syntax-ns#first",
395
+ list[i],
396
+ );
397
+ this.addTriple(
398
+ item.parent,
399
+ bnodes[i],
400
+ "http://www.w3.org/1999/02/22-rdf-syntax-ns#rest",
401
+ {
402
+ type: RDFaProcessor.objectURI,
403
+ value:
404
+ i + 1 < bnodes.length
405
+ ? bnodes[i + 1]
406
+ : "http://www.w3.org/1999/02/22-rdf-syntax-ns#nil",
407
+ },
408
+ );
409
+ }
410
+ this.addTriple(item.parent, item.subject, predicate, {
411
+ type: RDFaProcessor.objectURI,
412
+ value: bnodes[0],
413
+ });
414
+ }
415
+ continue;
416
+ }
417
+ var current = item.current;
418
+ var context = item.context;
419
+
420
+ //console.log("Tag: "+current.localName+", listMapping="+JSON.stringify(context.listMapping));
421
+
422
+ // Sequence Step 1
423
+ var skip = false;
424
+ var newSubject = null;
425
+ var currentObjectResource = null;
426
+ var typedResource = null;
427
+ var prefixes = context.prefixes;
428
+ var prefixesCopied = false;
429
+ var incomplete = [];
430
+ var listMapping = context.listMapping;
431
+ var listMappingDifferent = context.parent ? false : true;
432
+ var language = context.language;
433
+ var vocabulary = context.vocabulary;
434
+
435
+ // TODO: the "base" element may be used for HTML+RDFa 1.1
436
+ var base;
437
+ if (!current.baseURI) {
438
+ if (this.target.baseURI) {
439
+ base = this.target.baseURI;
440
+ } else {
441
+ throw new Error(
442
+ "node.baseURI was null as baseURI must be specified as an option",
443
+ );
444
+ }
445
+ } else if (current.baseURI === "about:blank") {
446
+ if (this.target.baseURI) {
447
+ base = this.target.baseURI;
448
+ } else {
449
+ throw new Error(
450
+ "node.baseURI is about:blank a valid URL must be provided with the baseURI option. If you use JSDOM call it with an `url` parameter or, set the baseURI option of this library",
451
+ );
452
+ }
453
+ } else {
454
+ base = this.parseURI(removeHash(current.baseURI));
455
+ }
456
+
457
+ current.item = null;
458
+
459
+ // Sequence Step 2: set the default vocabulary
460
+ var vocabAtt = current.getAttributeNode("vocab");
461
+ if (vocabAtt) {
462
+ var value = RDFaProcessor.trim(vocabAtt.value);
463
+ if (value.length > 0) {
464
+ vocabulary = value;
465
+ var baseSubject = base.spec;
466
+ //this.newSubject(current,baseSubject);
467
+ this.addTriple(
468
+ current,
469
+ baseSubject,
470
+ "http://www.w3.org/ns/rdfa#usesVocabulary",
471
+ { type: RDFaProcessor.objectURI, value: vocabulary },
472
+ );
473
+ } else {
474
+ vocabulary = this.vocabulary;
475
+ }
476
+ }
477
+
478
+ // Sequence Step 3: IRI mappings
479
+ // handle xmlns attributes
480
+ for (var i = 0; i < current.attributes.length; i++) {
481
+ var att = current.attributes[i];
482
+ //if (att.namespaceURI=="http://www.w3.org/2000/xmlns/") {
483
+ if (att.name.charAt(0) == "x" && att.name.indexOf("xmlns:") == 0) {
484
+ if (!prefixesCopied) {
485
+ prefixes = this.copyMappings(prefixes);
486
+ prefixesCopied = true;
487
+ }
488
+ var prefix = att.name.substring(6);
489
+ // TODO: resolve relative?
490
+ var ref = RDFaProcessor.trim(att.value);
491
+ prefixes[prefix] = this.target.baseURI
492
+ ? this.target.baseURI.resolve(ref)
493
+ : ref;
494
+ }
495
+ }
496
+ // Handle prefix mappings (@prefix)
497
+ var prefixAtt = current.getAttributeNode("prefix");
498
+ if (prefixAtt) {
499
+ if (!prefixesCopied) {
500
+ prefixes = this.copyMappings(prefixes);
501
+ prefixesCopied = true;
502
+ }
503
+ this.parsePrefixMappings(prefixAtt.value, prefixes);
504
+ }
505
+
506
+ // Sequence Step 4: language
507
+ var xmlLangAtt = null;
508
+ for (var i = 0; !xmlLangAtt && i < this.langAttributes.length; i++) {
509
+ xmlLangAtt = current.getAttributeNodeNS(
510
+ this.langAttributes[i].namespaceURI,
511
+ this.langAttributes[i].localName,
512
+ );
513
+ }
514
+ if (xmlLangAtt) {
515
+ var value = RDFaProcessor.trim(xmlLangAtt.value);
516
+ if (value.length > 0) {
517
+ language = value;
518
+ } else {
519
+ language = null;
520
+ }
521
+ }
522
+
523
+ var relAtt = current.getAttributeNode("rel");
524
+ var revAtt = current.getAttributeNode("rev");
525
+ var typeofAtt = current.getAttributeNode("typeof");
526
+ var propertyAtt = current.getAttributeNode("property");
527
+ var datatypeAtt = current.getAttributeNode("datatype");
528
+ var datetimeAtt = this.inHTMLMode
529
+ ? current.getAttributeNode("datetime")
530
+ : null;
531
+ var contentAtt = current.getAttributeNode("content");
532
+ var aboutAtt = current.getAttributeNode("about");
533
+ var srcAtt = current.getAttributeNode("src");
534
+ var resourceAtt = current.getAttributeNode("resource");
535
+ var hrefAtt = current.getAttributeNode("href");
536
+ var inlistAtt = current.getAttributeNode("inlist");
537
+
538
+ var relAttPredicates = [];
539
+ if (relAtt) {
540
+ var values = this.tokenize(relAtt.value);
541
+ for (var i = 0; i < values.length; i++) {
542
+ var predicate = this.parsePredicate(
543
+ values[i],
544
+ vocabulary,
545
+ context.terms,
546
+ prefixes,
547
+ base,
548
+ this.inHTMLMode && propertyAtt != null,
549
+ );
550
+ if (predicate) {
551
+ relAttPredicates.push(predicate);
552
+ }
553
+ }
554
+ }
555
+ var revAttPredicates = [];
556
+ if (revAtt) {
557
+ var values = this.tokenize(revAtt.value);
558
+ for (var i = 0; i < values.length; i++) {
559
+ var predicate = this.parsePredicate(
560
+ values[i],
561
+ vocabulary,
562
+ context.terms,
563
+ prefixes,
564
+ base,
565
+ this.inHTMLMode && propertyAtt != null,
566
+ );
567
+ if (predicate) {
568
+ revAttPredicates.push(predicate);
569
+ }
570
+ }
571
+ }
572
+
573
+ // Section 3.1, bullet 7
574
+ if (
575
+ this.inHTMLMode &&
576
+ (relAtt != null || revAtt != null) &&
577
+ propertyAtt != null
578
+ ) {
579
+ if (relAttPredicates.length == 0) {
580
+ relAtt = null;
581
+ }
582
+ if (revAttPredicates.length == 0) {
583
+ revAtt = null;
584
+ }
585
+ }
586
+
587
+ if (relAtt || revAtt) {
588
+ // Sequence Step 6: establish new subject and value
589
+ if (aboutAtt) {
590
+ newSubject = this.parseSafeCURIEOrCURIEOrURI(
591
+ aboutAtt.value,
592
+ prefixes,
593
+ base,
594
+ );
595
+ }
596
+ if (typeofAtt) {
597
+ typedResource = newSubject;
598
+ }
599
+ if (!newSubject) {
600
+ if (current.parentNode.nodeType == Node.DOCUMENT_NODE) {
601
+ newSubject = removeHash(current.baseURI);
602
+ } else if (context.parentObject) {
603
+ // TODO: Verify: If the xml:base has been set and the parentObject is the baseURI of the parent, then the subject needs to be the new base URI
604
+ newSubject =
605
+ removeHash(current.parentNode.baseURI) == context.parentObject
606
+ ? removeHash(current.baseURI)
607
+ : context.parentObject;
608
+ }
609
+ }
610
+ if (resourceAtt) {
611
+ currentObjectResource = this.parseSafeCURIEOrCURIEOrURI(
612
+ resourceAtt.value,
613
+ prefixes,
614
+ base,
615
+ );
616
+ }
617
+
618
+ if (!currentObjectResource) {
619
+ if (hrefAtt) {
620
+ currentObjectResource = this.resolveAndNormalize(
621
+ base,
622
+ encodeURI(hrefAtt.value),
623
+ );
624
+ } else if (srcAtt) {
625
+ currentObjectResource = this.resolveAndNormalize(
626
+ base,
627
+ encodeURI(srcAtt.value),
628
+ );
629
+ } else if (
630
+ typeofAtt &&
631
+ !aboutAtt &&
632
+ !(
633
+ this.inXHTMLMode &&
634
+ (current.localName == "head" || current.localName == "body")
635
+ )
636
+ ) {
637
+ currentObjectResource = this.newBlankNode();
638
+ }
639
+ }
640
+ if (
641
+ typeofAtt &&
642
+ !aboutAtt &&
643
+ this.inXHTMLMode &&
644
+ (current.localName == "head" || current.localName == "body")
645
+ ) {
646
+ typedResource = newSubject;
647
+ } else if (typeofAtt && !aboutAtt) {
648
+ typedResource = currentObjectResource;
649
+ }
650
+ } else if (propertyAtt && !contentAtt && !datatypeAtt) {
651
+ // Sequence Step 5.1: establish a new subject
652
+ if (aboutAtt) {
653
+ newSubject = this.parseSafeCURIEOrCURIEOrURI(
654
+ aboutAtt.value,
655
+ prefixes,
656
+ base,
657
+ );
658
+ if (typeofAtt) {
659
+ typedResource = newSubject;
660
+ }
661
+ }
662
+ if (!newSubject && current.parentNode.nodeType == Node.DOCUMENT_NODE) {
663
+ newSubject = removeHash(current.baseURI);
664
+ if (typeofAtt) {
665
+ typedResource = newSubject;
666
+ }
667
+ } else if (!newSubject && context.parentObject) {
668
+ // TODO: Verify: If the xml:base has been set and the parentObject is the baseURI of the parent, then the subject needs to be the new base URI
669
+ newSubject =
670
+ removeHash(current.parentNode.baseURI) == context.parentObject
671
+ ? removeHash(current.baseURI)
672
+ : context.parentObject;
673
+ }
674
+ if (typeofAtt && !typedResource) {
675
+ if (resourceAtt) {
676
+ typedResource = this.parseSafeCURIEOrCURIEOrURI(
677
+ resourceAtt.value,
678
+ prefixes,
679
+ base,
680
+ );
681
+ }
682
+ if (!typedResource && hrefAtt) {
683
+ typedResource = this.resolveAndNormalize(
684
+ base,
685
+ encodeURI(hrefAtt.value),
686
+ );
687
+ }
688
+ if (!typedResource && srcAtt) {
689
+ typedResource = this.resolveAndNormalize(
690
+ base,
691
+ encodeURI(srcAtt.value),
692
+ );
693
+ }
694
+ if (
695
+ !typedResource &&
696
+ (this.inXHTMLMode || this.inHTMLMode) &&
697
+ (current.localName == "head" || current.localName == "body")
698
+ ) {
699
+ typedResource = newSubject;
700
+ }
701
+ if (!typedResource) {
702
+ typedResource = this.newBlankNode();
703
+ }
704
+ currentObjectResource = typedResource;
705
+ }
706
+ //console.log(current.localName+", newSubject="+newSubject+", typedResource="+typedResource+", currentObjectResource="+currentObjectResource);
707
+ } else {
708
+ // Sequence Step 5.2: establish a new subject
709
+ if (aboutAtt) {
710
+ newSubject = this.parseSafeCURIEOrCURIEOrURI(
711
+ aboutAtt.value,
712
+ prefixes,
713
+ base,
714
+ );
715
+ }
716
+ if (!newSubject && resourceAtt) {
717
+ newSubject = this.parseSafeCURIEOrCURIEOrURI(
718
+ resourceAtt.value,
719
+ prefixes,
720
+ base,
721
+ );
722
+ }
723
+ if (!newSubject && hrefAtt) {
724
+ newSubject = this.resolveAndNormalize(base, encodeURI(hrefAtt.value));
725
+ }
726
+ if (!newSubject && srcAtt) {
727
+ newSubject = this.resolveAndNormalize(base, encodeURI(srcAtt.value));
728
+ }
729
+ if (!newSubject) {
730
+ if (current.parentNode.nodeType == Node.DOCUMENT_NODE) {
731
+ newSubject = removeHash(current.baseURI);
732
+ } else if (
733
+ (this.inXHTMLMode || this.inHTMLMode) &&
734
+ (current.localName == "head" || current.localName == "body")
735
+ ) {
736
+ newSubject =
737
+ removeHash(current.parentNode.baseURI) == context.parentObject
738
+ ? removeHash(current.baseURI)
739
+ : context.parentObject;
740
+ } else if (typeofAtt) {
741
+ newSubject = this.newBlankNode();
742
+ } else if (context.parentObject) {
743
+ // TODO: Verify: If the xml:base has been set and the parentObject is the baseURI of the parent, then the subject needs to be the new base URI
744
+ newSubject =
745
+ removeHash(current.parentNode.baseURI) == context.parentObject
746
+ ? removeHash(current.baseURI)
747
+ : context.parentObject;
748
+ if (!propertyAtt) {
749
+ skip = true;
750
+ }
751
+ }
752
+ }
753
+ if (typeofAtt) {
754
+ typedResource = newSubject;
755
+ }
756
+ }
757
+
758
+ //console.log(current.tagName+": newSubject="+newSubject+", currentObjectResource="+currentObjectResource+", typedResource="+typedResource+", skip="+skip);
759
+
760
+ var rdfaData = null;
761
+ if (newSubject) {
762
+ //this.newSubject(current,newSubject);
763
+ if (aboutAtt || resourceAtt || typedResource) {
764
+ var id = newSubject;
765
+ if (typeofAtt && !aboutAtt && !resourceAtt && currentObjectResource) {
766
+ id = currentObjectResource;
767
+ }
768
+ //console.log("Setting data attribute for "+current.localName+" for subject "+id);
769
+ this.newSubjectOrigin(current, id);
770
+ }
771
+ }
772
+
773
+ // Sequence Step 7: generate type triple
774
+ if (typedResource) {
775
+ var values = this.tokenize(typeofAtt.value);
776
+ for (var i = 0; i < values.length; i++) {
777
+ var object = this.parseTermOrCURIEOrAbsURI(
778
+ values[i],
779
+ vocabulary,
780
+ context.terms,
781
+ prefixes,
782
+ base,
783
+ );
784
+ if (object) {
785
+ this.addTriple(current, typedResource, RDFaProcessor.typeURI, {
786
+ type: RDFaProcessor.objectURI,
787
+ value: object,
788
+ });
789
+ }
790
+ }
791
+ }
792
+
793
+ // Sequence Step 8: new list mappings if there is a new subject
794
+ //console.log("Step 8: newSubject="+newSubject+", context.parentObject="+context.parentObject);
795
+ if (newSubject && newSubject != context.parentObject) {
796
+ //console.log("Generating new list mapping for "+newSubject);
797
+ listMapping = {};
798
+ listMappingDifferent = true;
799
+ }
800
+
801
+ // Sequence Step 9: generate object triple
802
+ if (currentObjectResource) {
803
+ if (relAtt && inlistAtt) {
804
+ for (var i = 0; i < relAttPredicates.length; i++) {
805
+ var list = listMapping[relAttPredicates[i]];
806
+ if (!list) {
807
+ list = [];
808
+ listMapping[relAttPredicates[i]] = list;
809
+ }
810
+ list.push({
811
+ type: RDFaProcessor.objectURI,
812
+ value: currentObjectResource,
813
+ });
814
+ }
815
+ } else if (relAtt) {
816
+ for (var i = 0; i < relAttPredicates.length; i++) {
817
+ this.addTriple(current, newSubject, relAttPredicates[i], {
818
+ type: RDFaProcessor.objectURI,
819
+ value: currentObjectResource,
820
+ });
821
+ }
822
+ }
823
+ if (revAtt) {
824
+ for (var i = 0; i < revAttPredicates.length; i++) {
825
+ this.addTriple(
826
+ current,
827
+ currentObjectResource,
828
+ revAttPredicates[i],
829
+ { type: RDFaProcessor.objectURI, value: newSubject },
830
+ );
831
+ }
832
+ }
833
+ } else {
834
+ // Sequence Step 10: incomplete triples
835
+ if (newSubject && !currentObjectResource && (relAtt || revAtt)) {
836
+ currentObjectResource = this.newBlankNode();
837
+ //alert(current.tagName+": generated blank node, newSubject="+newSubject+" currentObjectResource="+currentObjectResource);
838
+ }
839
+ if (relAtt && inlistAtt) {
840
+ for (var i = 0; i < relAttPredicates.length; i++) {
841
+ var list = listMapping[relAttPredicates[i]];
842
+ if (!list) {
843
+ list = [];
844
+ listMapping[predicate] = list;
845
+ }
846
+ //console.log("Adding incomplete list for "+predicate);
847
+ incomplete.push({ predicate: relAttPredicates[i], list: list });
848
+ }
849
+ } else if (relAtt) {
850
+ for (var i = 0; i < relAttPredicates.length; i++) {
851
+ incomplete.push({ predicate: relAttPredicates[i], forward: true });
852
+ }
853
+ }
854
+ if (revAtt) {
855
+ for (var i = 0; i < revAttPredicates.length; i++) {
856
+ incomplete.push({ predicate: revAttPredicates[i], forward: false });
857
+ }
858
+ }
859
+ }
860
+
861
+ // Step 11: Current property values
862
+ if (propertyAtt) {
863
+ var datatype = null;
864
+ var content = null;
865
+ if (datatypeAtt) {
866
+ datatype =
867
+ datatypeAtt.value == ""
868
+ ? RDFaProcessor.PlainLiteralURI
869
+ : this.parseTermOrCURIEOrAbsURI(
870
+ datatypeAtt.value,
871
+ vocabulary,
872
+ context.terms,
873
+ prefixes,
874
+ base,
875
+ );
876
+ if (datetimeAtt && !contentAtt) {
877
+ content = datetimeAtt.value;
878
+ } else {
879
+ content =
880
+ datatype == RDFaProcessor.XMLLiteralURI ||
881
+ datatype == RDFaProcessor.HTMLLiteralURI
882
+ ? null
883
+ : contentAtt
884
+ ? contentAtt.value
885
+ : current.textContent;
886
+ }
887
+ } else if (contentAtt) {
888
+ datatype = RDFaProcessor.PlainLiteralURI;
889
+ content = contentAtt.value;
890
+ } else if (datetimeAtt) {
891
+ content = datetimeAtt.value;
892
+ datatype = RDFaProcessor.deriveDateTimeType(content);
893
+ if (!datatype) {
894
+ datatype = RDFaProcessor.PlainLiteralURI;
895
+ }
896
+ } else if (!relAtt && !revAtt) {
897
+ if (resourceAtt) {
898
+ content = this.parseSafeCURIEOrCURIEOrURI(
899
+ resourceAtt.value,
900
+ prefixes,
901
+ base,
902
+ );
903
+ }
904
+ if (!content && hrefAtt) {
905
+ content = this.resolveAndNormalize(base, encodeURI(hrefAtt.value));
906
+ } else if (!content && srcAtt) {
907
+ content = this.resolveAndNormalize(base, encodeURI(srcAtt.value));
908
+ }
909
+ if (content) {
910
+ datatype = RDFaProcessor.objectURI;
911
+ }
912
+ }
913
+ if (!datatype) {
914
+ if (typeofAtt && !aboutAtt) {
915
+ datatype = RDFaProcessor.objectURI;
916
+ content = typedResource;
917
+ } else {
918
+ content = current.textContent;
919
+
920
+ if (this.inHTMLMode && current.localName == "time") {
921
+ datatype = RDFaProcessor.deriveDateTimeType(content);
922
+ }
923
+ if (!datatype) {
924
+ datatype = RDFaProcessor.PlainLiteralURI;
925
+ }
926
+ }
927
+ }
928
+ var values = this.tokenize(propertyAtt.value);
929
+ for (var i = 0; i < values.length; i++) {
930
+ var predicate = this.parsePredicate(
931
+ values[i],
932
+ vocabulary,
933
+ context.terms,
934
+ prefixes,
935
+ base,
936
+ );
937
+ if (predicate) {
938
+ if (inlistAtt) {
939
+ var list = listMapping[predicate];
940
+ if (!list) {
941
+ list = [];
942
+ listMapping[predicate] = list;
943
+ }
944
+ list.push(
945
+ datatype == RDFaProcessor.XMLLiteralURI ||
946
+ datatype == RDFaProcessor.HTMLLiteralURI
947
+ ? { type: datatype, value: current.childNodes }
948
+ : {
949
+ type: datatype ? datatype : RDFaProcessor.PlainLiteralURI,
950
+ value: content,
951
+ language: language,
952
+ },
953
+ );
954
+ } else {
955
+ if (
956
+ datatype == RDFaProcessor.XMLLiteralURI ||
957
+ datatype == RDFaProcessor.HTMLLiteralURI
958
+ ) {
959
+ this.addTriple(current, newSubject, predicate, {
960
+ type: datatype,
961
+ value: current.childNodes,
962
+ });
963
+ } else {
964
+ this.addTriple(current, newSubject, predicate, {
965
+ type: datatype ? datatype : RDFaProcessor.PlainLiteralURI,
966
+ value: content,
967
+ language: language,
968
+ });
969
+ const specialPredicate = this.target.specialHtmlPredicates.find(
970
+ (sp) => sp.source === predicate,
971
+ );
972
+ if (specialPredicate) {
973
+ this.addTriple(current, newSubject, specialPredicate.target, {
974
+ type: RDFaProcessor.HTMLLiteralURI,
975
+ value: current.childNodes,
976
+ });
977
+ }
978
+ //console.log(newSubject+" "+predicate+"="+content);
979
+ }
980
+ }
981
+ }
982
+ }
983
+ }
984
+
985
+ // Sequence Step 12: complete incomplete triples with new subject
986
+ if (newSubject && !skip) {
987
+ for (var i = 0; i < context.incomplete.length; i++) {
988
+ if (context.incomplete[i].list) {
989
+ //console.log("Adding subject "+newSubject+" to list for "+context.incomplete[i].predicate);
990
+ // TODO: it is unclear what to do here
991
+ context.incomplete[i].list.push({
992
+ type: RDFaProcessor.objectURI,
993
+ value: newSubject,
994
+ });
995
+ } else if (context.incomplete[i].forward) {
996
+ //console.log(current.tagName+": completing forward triple "+context.incomplete[i].predicate+" with object="+newSubject);
997
+ this.addTriple(
998
+ current,
999
+ context.subject,
1000
+ context.incomplete[i].predicate,
1001
+ { type: RDFaProcessor.objectURI, value: newSubject },
1002
+ );
1003
+ } else {
1004
+ //console.log(current.tagName+": completing reverse triple with object="+context.subject);
1005
+ this.addTriple(
1006
+ current,
1007
+ newSubject,
1008
+ context.incomplete[i].predicate,
1009
+ { type: RDFaProcessor.objectURI, value: context.subject },
1010
+ );
1011
+ }
1012
+ }
1013
+ }
1014
+
1015
+ var childContext = null;
1016
+ var listSubject = newSubject;
1017
+ if (skip) {
1018
+ // TODO: should subject be null?
1019
+ childContext = this.push(context, context.subject);
1020
+ // TODO: should the entObject be passed along? If not, then intermediary children will keep properties from being associated with incomplete triples.
1021
+ // TODO: Verify: if the current baseURI has changed and the parentObject is the parent's base URI, then the baseURI should change
1022
+ childContext.parentObject =
1023
+ removeHash(current.parentNode.baseURI) == context.parentObject
1024
+ ? removeHash(current.baseURI)
1025
+ : context.parentObject;
1026
+ childContext.incomplete = context.incomplete;
1027
+ childContext.language = language;
1028
+ childContext.prefixes = prefixes;
1029
+ childContext.vocabulary = vocabulary;
1030
+ } else {
1031
+ childContext = this.push(context, newSubject);
1032
+ childContext.parentObject = currentObjectResource
1033
+ ? currentObjectResource
1034
+ : newSubject
1035
+ ? newSubject
1036
+ : context.subject;
1037
+ childContext.prefixes = prefixes;
1038
+ childContext.incomplete = incomplete;
1039
+ if (currentObjectResource) {
1040
+ //console.log("Generating new list mapping for "+currentObjectResource);
1041
+ listSubject = currentObjectResource;
1042
+ listMapping = {};
1043
+ listMappingDifferent = true;
1044
+ }
1045
+ childContext.listMapping = listMapping;
1046
+ childContext.language = language;
1047
+ childContext.vocabulary = vocabulary;
1048
+ }
1049
+ if (listMappingDifferent) {
1050
+ //console.log("Pushing list parent "+current.localName);
1051
+ queue.unshift({
1052
+ parent: current,
1053
+ context: context,
1054
+ subject: listSubject,
1055
+ listMapping: listMapping,
1056
+ });
1057
+ }
1058
+ for (
1059
+ var child = current.lastChild;
1060
+ child;
1061
+ child = child.previousSibling
1062
+ ) {
1063
+ if (child.nodeType == Node.ELEMENT_NODE) {
1064
+ //console.log("Pushing child "+child.localName);
1065
+ queue.unshift({ current: child, context: childContext });
1066
+ }
1067
+ }
1068
+ }
1069
+
1070
+ if (this.inHTMLMode) {
1071
+ this.copyProperties();
1072
+ }
1073
+
1074
+ for (var i = 0; i < this.finishedHandlers.length; i++) {
1075
+ this.finishedHandlers[i](node);
1076
+ }
1077
+ }
1078
+
1079
+ copyProperties() { }
1080
+
1081
+ push(parent, subject) {
1082
+ return {
1083
+ parent: parent,
1084
+ subject: subject ? subject : parent ? parent.subject : null,
1085
+ parentObject: null,
1086
+ incomplete: [],
1087
+ listMapping: parent ? parent.listMapping : {},
1088
+ language: parent ? parent.language : this.language,
1089
+ prefixes: parent ? parent.prefixes : this.target.graph.prefixes,
1090
+ terms: parent ? parent.terms : this.target.graph.terms,
1091
+ vocabulary: parent ? parent.vocabulary : this.vocabulary,
1092
+ };
1093
+ }
1094
+ }
1095
+
1096
+ RDFaProcessor.XMLLiteralURI =
1097
+ "http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral";
1098
+ RDFaProcessor.HTMLLiteralURI =
1099
+ "http://www.w3.org/1999/02/22-rdf-syntax-ns#HTML";
1100
+ RDFaProcessor.PlainLiteralURI =
1101
+ "http://www.w3.org/1999/02/22-rdf-syntax-ns#PlainLiteral";
1102
+ RDFaProcessor.objectURI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#object";
1103
+ RDFaProcessor.typeURI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type";
1104
+
1105
+ RDFaProcessor.nameChar =
1106
+ "[-A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u10000-\uEFFFF.0-9\u00B7\u0300-\u036F\u203F-\u2040]";
1107
+ RDFaProcessor.nameStartChar =
1108
+ "[\u0041-\u005A\u0061-\u007A\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF\u0100-\u0131\u0134-\u013E\u0141-\u0148\u014A-\u017E\u0180-\u01C3\u01CD-\u01F0\u01F4-\u01F5\u01FA-\u0217\u0250-\u02A8\u02BB-\u02C1\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03CE\u03D0-\u03D6\u03DA\u03DC\u03DE\u03E0\u03E2-\u03F3\u0401-\u040C\u040E-\u044F\u0451-\u045C\u045E-\u0481\u0490-\u04C4\u04C7-\u04C8\u04CB-\u04CC\u04D0-\u04EB\u04EE-\u04F5\u04F8-\u04F9\u0531-\u0556\u0559\u0561-\u0586\u05D0-\u05EA\u05F0-\u05F2\u0621-\u063A\u0641-\u064A\u0671-\u06B7\u06BA-\u06BE\u06C0-\u06CE\u06D0-\u06D3\u06D5\u06E5-\u06E6\u0905-\u0939\u093D\u0958-\u0961\u0985-\u098C\u098F-\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09DC-\u09DD\u09DF-\u09E1\u09F0-\u09F1\u0A05-\u0A0A\u0A0F-\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32-\u0A33\u0A35-\u0A36\u0A38-\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8B\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2-\u0AB3\u0AB5-\u0AB9\u0ABD\u0AE0\u0B05-\u0B0C\u0B0F-\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32-\u0B33\u0B36-\u0B39\u0B3D\u0B5C-\u0B5D\u0B5F-\u0B61\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99-\u0B9A\u0B9C\u0B9E-\u0B9F\u0BA3-\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB5\u0BB7-\u0BB9\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C60-\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CDE\u0CE0-\u0CE1\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D28\u0D2A-\u0D39\u0D60-\u0D61\u0E01-\u0E2E\u0E30\u0E32-\u0E33\u0E40-\u0E45\u0E81-\u0E82\u0E84\u0E87-\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA-\u0EAB\u0EAD-\u0EAE\u0EB0\u0EB2-\u0EB3\u0EBD\u0EC0-\u0EC4\u0F40-\u0F47\u0F49-\u0F69\u10A0-\u10C5\u10D0-\u10F6\u1100\u1102-\u1103\u1105-\u1107\u1109\u110B-\u110C\u110E-\u1112\u113C\u113E\u1140\u114C\u114E\u1150\u1154-\u1155\u1159\u115F-\u1161\u1163\u1165\u1167\u1169\u116D-\u116E\u1172-\u1173\u1175\u119E\u11A8\u11AB\u11AE-\u11AF\u11B7-\u11B8\u11BA\u11BC-\u11C2\u11EB\u11F0\u11F9\u1E00-\u1E9B\u1EA0-\u1EF9\u1F00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2126\u212A-\u212B\u212E\u2180-\u2182\u3041-\u3094\u30A1-\u30FA\u3105-\u312C\uAC00-\uD7A3\u4E00-\u9FA5\u3007\u3021-\u3029_]";
1109
+
1110
+ RDFaProcessor.NCNAME = new RegExp(
1111
+ "^" + RDFaProcessor.nameStartChar + RDFaProcessor.nameChar + "*$",
1112
+ );
1113
+
1114
+ RDFaProcessor.trim = function(str) {
1115
+ return str.replace(/^\s\s*/, "").replace(/\s\s*$/, "");
1116
+ };
1117
+
1118
+ RDFaProcessor.dateTimeTypes = [
1119
+ {
1120
+ pattern:
1121
+ /-?P(?:[0-9]+Y)?(?:[0-9]+M)?(?:[0-9]+D)?(?:T(?:[0-9]+H)?(?:[0-9]+M)?(?:[0-9]+(?:\.[0-9]+)?S)?)?/,
1122
+ type: "http://www.w3.org/2001/XMLSchema#duration",
1123
+ },
1124
+ {
1125
+ pattern:
1126
+ /-?(?:[1-9][0-9][0-9][0-9]|0[1-9][0-9][0-9]|00[1-9][0-9]|000[1-9])-[0-9][0-9]-[0-9][0-9]T(?:[0-1][0-9]|2[0-4]):[0-5][0-9]:[0-5][0-9](?:\.[0-9]+)?(?:Z|[+\-][0-9][0-9]:[0-9][0-9])?/,
1127
+ type: "http://www.w3.org/2001/XMLSchema#dateTime",
1128
+ },
1129
+ {
1130
+ pattern:
1131
+ /-?(?:[1-9][0-9][0-9][0-9]|0[1-9][0-9][0-9]|00[1-9][0-9]|000[1-9])-[0-9][0-9]-[0-9][0-9](?:Z|[+\-][0-9][0-9]:[0-9][0-9])?/,
1132
+ type: "http://www.w3.org/2001/XMLSchema#date",
1133
+ },
1134
+ {
1135
+ pattern:
1136
+ /(?:[0-1][0-9]|2[0-4]):[0-5][0-9]:[0-5][0-9](?:\.[0-9]+)?(?:Z|[+\-][0-9][0-9]:[0-9][0-9])?/,
1137
+ type: "http://www.w3.org/2001/XMLSchema#time",
1138
+ },
1139
+ {
1140
+ pattern:
1141
+ /-?(?:[1-9][0-9][0-9][0-9]|0[1-9][0-9][0-9]|00[1-9][0-9]|000[1-9])-[0-9][0-9]/,
1142
+ type: "http://www.w3.org/2001/XMLSchema#gYearMonth",
1143
+ },
1144
+ {
1145
+ pattern: /-?[1-9][0-9][0-9][0-9]|0[1-9][0-9][0-9]|00[1-9][0-9]|000[1-9]/,
1146
+ type: "http://www.w3.org/2001/XMLSchema#gYear",
1147
+ },
1148
+ ];
1149
+
1150
+ RDFaProcessor.deriveDateTimeType = function(value) {
1151
+ for (var i = 0; i < RDFaProcessor.dateTimeTypes.length; i++) {
1152
+ //console.log("Checking "+value+" against "+RDFaProcessor.dateTimeTypes[i].type);
1153
+ var matched = RDFaProcessor.dateTimeTypes[i].pattern.exec(value);
1154
+ if (matched && matched[0].length == value.length) {
1155
+ //console.log("Matched!");
1156
+ return RDFaProcessor.dateTimeTypes[i].type;
1157
+ }
1158
+ }
1159
+ return null;
1160
+ };