link-rdflib
Version:
an RDF library for node.js, patched for speed.
1,174 lines (992 loc) • 45 kB
JavaScript
"use strict";
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
// RDFa Parser for rdflib.js
// Originally by: Alex Milowski
// From https://github.com/alexmilowski/green-turtle
// Converted: timbl 2015-08-25 not yet working
// Added wrapper: csarven 2016-05-09 working
// RDFaProcessor.prototype = new Object() // Was URIResolver
// RDFaProcessor.prototype.constructor=RDFaProcessor
// options.base = base URI not really an option, shopuld always be set.
//
var rdf = require('./data-factory');
var Uri = require('./uri');
var Util = require('./util');
if (typeof Node === 'undefined') {
// @@@@@@ Global. Interface to xmldom.
var Node = {
ELEMENT_NODE: 1,
ATTRIBUTE_NODE: 2,
TEXT_NODE: 3,
CDATA_SECTION_NODE: 4,
ENTITY_REFERENCE_NODE: 5,
ENTITY_NODE: 6,
PROCESSING_INSTRUCTION_NODE: 7,
COMMENT_NODE: 8,
DOCUMENT_NODE: 9,
DOCUMENT_TYPE_NODE: 10,
DOCUMENT_FRAGMENT_NODE: 11,
NOTATION_NODE: 12
};
}
var RDFaProcessor =
/*#__PURE__*/
function () {
function RDFaProcessor(kb, options) {
_classCallCheck(this, RDFaProcessor);
this.options = options || {};
this.kb = kb;
this.target = options.target || {
graph: {
subjects: {},
prefixes: {},
terms: {}
} // XXX: Added to track bnodes
};
this.blankNodes = []; // XXX: Added for normalisation
this.htmlOptions = {
'selfClosing': 'br img input area base basefont col colgroup source wbr isindex link meta param hr'
};
this.theOne = '_:' + new Date().getTime();
this.language = null;
this.vocabulary = null;
this.blankCounter = 0;
this.langAttributes = [{
namespaceURI: 'http://www.w3.org/XML/1998/namespace',
localName: 'lang'
}];
this.inXHTMLMode = false;
this.absURIRE = /[\w\_\-]+:\S+/;
this.finishedHandlers = [];
this.init();
}
_createClass(RDFaProcessor, [{
key: "addTriple",
value: function addTriple(origin, subject, predicate, object) {
var su, ob, pr, or;
if (typeof subject === 'undefined') {
su = rdf.namedNode(this.options.base);
} else {
su = this.toRDFNodeObject(subject);
}
pr = this.toRDFNodeObject(predicate);
ob = this.toRDFNodeObject(object);
or = rdf.namedNode(this.options.base); // console.log('Adding { ' + su + ' ' + pr + ' ' + ob + ' ' + or + ' }')
this.kb.add(su, pr, ob, or);
}
}, {
key: "ancestorPath",
value: function ancestorPath(node) {
var path = '';
while (node && node.nodeType !== Node.DOCUMENT_NODE) {
path = '/' + node.localName + path;
node = node.parentNode;
}
return path;
}
}, {
key: "copyMappings",
value: function copyMappings(mappings) {
var newMappings = {};
for (var k in mappings) {
newMappings[k] = mappings[k];
}
return newMappings;
}
}, {
key: "copyProperties",
value: function copyProperties() {}
}, {
key: "deriveDateTimeType",
value: function deriveDateTimeType(value) {
for (var i = 0; i < RDFaProcessor.dateTimeTypes.length; i++) {
// console.log("Checking "+value+" against "+RDFaProcessor.dateTimeTypes[i].type)
var matched = RDFaProcessor.dateTimeTypes[i].pattern.exec(value);
if (matched && matched[0].length === value.length) {
// console.log("Matched!")
return RDFaProcessor.dateTimeTypes[i].type;
}
}
return null;
}
}, {
key: "init",
value: function init() {}
}, {
key: "newBlankNode",
value: function newBlankNode() {
this.blankCounter++;
return '_:' + this.blankCounter;
}
}, {
key: "newSubjectOrigin",
value: function newSubjectOrigin(origin, subject) {}
}, {
key: "parseCURIE",
value: function parseCURIE(value, prefixes, base) {
var colon = value.indexOf(':');
var uri;
if (colon >= 0) {
var prefix = value.substring(0, colon);
if (prefix === '') {
// default prefix
uri = prefixes[''];
return uri ? uri + value.substring(colon + 1) : null;
} else if (prefix === '_') {
// blank node
return '_:' + value.substring(colon + 1);
} else if (RDFaProcessor.NCNAME.test(prefix)) {
uri = prefixes[prefix];
if (uri) {
return uri + value.substring(colon + 1);
}
}
}
return null;
}
}, {
key: "parseCURIEOrURI",
value: function parseCURIEOrURI(value, prefixes, base) {
var curie = this.parseCURIE(value, prefixes, base);
if (curie) {
return curie;
}
return this.resolveAndNormalize(base, value);
}
}, {
key: "parsePredicate",
value: function parsePredicate(value, defaultVocabulary, terms, prefixes, base, ignoreTerms) {
if (value === '') {
return null;
}
var predicate = this.parseTermOrCURIEOrAbsURI(value, defaultVocabulary, ignoreTerms ? null : terms, prefixes, base);
if (predicate && predicate.indexOf('_:') === 0) {
return null;
}
return predicate;
}
}, {
key: "parsePrefixMappings",
value: function parsePrefixMappings(str, target) {
var values = this.tokenize(str);
var prefix = null; // var uri = null
for (var i = 0; i < values.length; i++) {
if (values[i][values[i].length - 1] === ':') {
prefix = values[i].substring(0, values[i].length - 1);
} else if (prefix) {
target[prefix] = this.options.base ? Uri.join(values[i], this.options.base) : values[i];
prefix = null;
}
}
}
}, {
key: "parseSafeCURIEOrCURIEOrURI",
value: function parseSafeCURIEOrCURIEOrURI(value, prefixes, base) {
value = this.trim(value);
if (value.charAt(0) === '[' && value.charAt(value.length - 1) === ']') {
value = value.substring(1, value.length - 1);
value = value.trim(value);
if (value.length === 0) {
return null;
}
if (value === '_:') {
// the one node
return this.theOne;
}
return this.parseCURIE(value, prefixes, base);
} else {
return this.parseCURIEOrURI(value, prefixes, base);
}
}
}, {
key: "parseTermOrCURIEOrAbsURI",
value: function parseTermOrCURIEOrAbsURI(value, defaultVocabulary, terms, prefixes, base) {
// alert("Parsing "+value+" with default vocab "+defaultVocabulary)
value = this.trim(value);
var curie = this.parseCURIE(value, prefixes, base);
if (curie) {
return curie;
} else if (terms) {
if (defaultVocabulary && !this.absURIRE.exec(value)) {
return defaultVocabulary + value;
}
var term = terms[value];
if (term) {
return term;
}
var lcvalue = value.toLowerCase();
term = terms[lcvalue];
if (term) {
return term;
}
}
if (this.absURIRE.exec(value)) {
return this.resolveAndNormalize(base, value);
}
return null;
}
}, {
key: "parseTermOrCURIEOrURI",
value: function parseTermOrCURIEOrURI(value, defaultVocabulary, terms, prefixes, base) {
// alert("Parsing "+value+" with default vocab "+defaultVocabulary)
value = this.trim(value);
var curie = this.parseCURIE(value, prefixes, base);
if (curie) {
return curie;
} else {
var term = terms[value];
if (term) {
return term;
}
var lcvalue = value.toLowerCase();
term = terms[lcvalue];
if (term) {
return term;
}
if (defaultVocabulary && !this.absURIRE.exec(value)) {
return defaultVocabulary + value;
}
}
return this.resolveAndNormalize(base, value);
}
}, {
key: "parseURI",
value: function parseURI(uri) {
return uri; // We just use strings as URIs, not objects now.
}
}, {
key: "process",
value: function process(node, options) {
/*
if (!window.console) {
window.console = { log: function() {} }
}*/
var base;
if (node.nodeType === Node.DOCUMENT_NODE) {
base = node.baseURI;
node = node.documentElement;
node.baseURI = base;
this.setContext(node);
} else if (node.parentNode.nodeType === Node.DOCUMENT_NODE) {
this.setContext(node);
}
var queue = []; // Fix for Firefox that includes the hash in the base URI
var removeHash = function removeHash(baseURI) {
// Fix for undefined baseURI property
if (!baseURI && options && options.baseURI) {
return options.baseURI;
}
var hash = baseURI.indexOf('#');
if (hash >= 0) {
baseURI = baseURI.substring(0, hash);
}
if (options && options.baseURIMap) {
baseURI = options.baseURIMap(baseURI);
}
return baseURI;
};
queue.push({
current: node,
context: this.push(null, removeHash(node.baseURI))
});
while (queue.length > 0) {
var item = queue.shift();
if (item.parent) {
// Sequence Step 14: list triple generation
if (item.context.parent && item.context.parent.listMapping === item.listMapping) {
// Skip a child context with exactly the same mapping
continue;
} // console.log("Generating lists for "+item.subject+", tag "+item.parent.localName)
for (var _predicate in item.listMapping) {
var list = item.listMapping[_predicate];
if (list.length === 0) {
this.addTriple(item.parent, item.subject, _predicate, {
type: RDFaProcessor.objectURI,
value: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'
});
continue;
}
var bnodes = [];
for (var _i = 0; _i < list.length; _i++) {
bnodes.push(this.newBlankNode()); // this.newSubject(item.parent,bnodes[i])
}
for (var _i2 = 0; _i2 < bnodes.length; _i2++) {
this.addTriple(item.parent, bnodes[_i2], 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', list[_i2]);
this.addTriple(item.parent, bnodes[_i2], 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', {
type: RDFaProcessor.objectURI,
value: _i2 + 1 < bnodes.length ? bnodes[_i2 + 1] : 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'
});
}
this.addTriple(item.parent, item.subject, _predicate, {
type: RDFaProcessor.objectURI,
value: bnodes[0]
});
}
continue;
}
var current = item.current;
var context = item.context; // console.log("Tag: "+current.localName+", listMapping="+JSON.stringify(context.listMapping))
// Sequence Step 1
var skip = false;
var newSubject = null;
var currentObjectResource = null;
var typedResource = null;
var prefixes = context.prefixes;
var prefixesCopied = false;
var incomplete = [];
var listMapping = context.listMapping;
var listMappingDifferent = !context.parent;
var language = context.language;
var vocabulary = context.vocabulary; // TODO: the "base" element may be used for HTML+RDFa 1.1
base = this.parseURI(removeHash(current.baseURI));
current.item = null; // Sequence Step 2: set the default vocabulary
var vocabAtt = current.getAttributeNode('vocab');
if (vocabAtt) {
var value = this.trim(vocabAtt.value);
if (value.length > 0) {
vocabulary = value;
var baseSubject = base.spec; // this.newSubject(current,baseSubject)
this.addTriple(current, baseSubject, 'http://www.w3.org/ns/rdfa#usesVocabulary', {
type: RDFaProcessor.objectURI,
value: vocabulary
});
} else {
vocabulary = this.vocabulary;
}
} // Sequence Step 3: IRI mappings
// handle xmlns attributes
for (var i = 0; i < current.attributes.length; i++) {
var att = current.attributes[i]; // if (att.namespaceURI=="http://www.w3.org/2000/xmlns/") {
if (att.nodeName.charAt(0) === 'x' && att.nodeName.indexOf('xmlns:') === 0) {
if (!prefixesCopied) {
prefixes = this.copyMappings(prefixes);
prefixesCopied = true;
}
var prefix = att.nodeName.substring(6); // TODO: resolve relative?
var ref = RDFaProcessor.trim(att.value);
prefixes[prefix] = this.options.base ? Uri.join(ref, this.options.base) : ref;
}
} // Handle prefix mappings (@prefix)
var prefixAtt = current.getAttributeNode('prefix');
if (prefixAtt) {
if (!prefixesCopied) {
prefixes = this.copyMappings(prefixes);
prefixesCopied = true;
}
this.parsePrefixMappings(prefixAtt.value, prefixes);
} // Sequence Step 4: language
var xmlLangAtt = null;
for (var _i3 = 0; !xmlLangAtt && _i3 < this.langAttributes.length; _i3++) {
xmlLangAtt = current.getAttributeNodeNS(this.langAttributes[_i3].namespaceURI, this.langAttributes[_i3].localName);
}
if (xmlLangAtt) {
var _value = RDFaProcessor.trim(xmlLangAtt.value);
if (_value.length > 0) {
language = _value;
} else {
language = null;
}
}
var relAtt = current.getAttributeNode('rel');
var revAtt = current.getAttributeNode('rev');
var typeofAtt = current.getAttributeNode('typeof');
var propertyAtt = current.getAttributeNode('property');
var datatypeAtt = current.getAttributeNode('datatype');
var datetimeAtt = this.inHTMLMode ? current.getAttributeNode('datetime') : null;
var contentAtt = current.getAttributeNode('content');
var aboutAtt = current.getAttributeNode('about');
var srcAtt = current.getAttributeNode('src');
var resourceAtt = current.getAttributeNode('resource');
var hrefAtt = current.getAttributeNode('href');
var inlistAtt = current.getAttributeNode('inlist');
var relAttPredicates = [];
var predicate, values;
if (relAtt) {
values = this.tokenize(relAtt.value);
for (var _i4 = 0; _i4 < values.length; _i4++) {
predicate = this.parsePredicate(values[_i4], vocabulary, context.terms, prefixes, base, this.inHTMLMode && propertyAtt !== null);
if (predicate) {
relAttPredicates.push(predicate);
}
}
}
var revAttPredicates = [];
if (revAtt) {
values = this.tokenize(revAtt.value);
for (var _i5 = 0; _i5 < values.length; _i5++) {
predicate = this.parsePredicate(values[_i5], vocabulary, context.terms, prefixes, base, this.inHTMLMode && propertyAtt);
if (predicate) {
revAttPredicates.push(predicate);
}
}
} // Section 3.1, bullet 7
if (this.inHTMLMode && (relAtt || revAtt) && propertyAtt) {
if (relAttPredicates.length === 0) {
relAtt = null;
}
if (revAttPredicates.length === 0) {
revAtt = null;
}
}
if (relAtt || revAtt) {
// Sequence Step 6: establish new subject and value
if (aboutAtt) {
newSubject = this.parseSafeCURIEOrCURIEOrURI(aboutAtt.value, prefixes, base);
}
if (typeofAtt) {
typedResource = newSubject;
}
if (!newSubject) {
if (current.parentNode.nodeType === Node.DOCUMENT_NODE) {
newSubject = removeHash(current.baseURI);
} else if (context.parentObject) {
// 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
newSubject = removeHash(current.parentNode.baseURI) === context.parentObject ? removeHash(current.baseURI) : context.parentObject;
}
}
if (resourceAtt) {
currentObjectResource = this.parseSafeCURIEOrCURIEOrURI(resourceAtt.value, prefixes, base);
}
if (!currentObjectResource) {
if (hrefAtt) {
currentObjectResource = this.resolveAndNormalize(base, encodeURI(hrefAtt.value));
} else if (srcAtt) {
currentObjectResource = this.resolveAndNormalize(base, encodeURI(srcAtt.value));
} else if (typeofAtt && !aboutAtt && !(this.inXHTMLMode && (current.localName === 'head' || current.localName === 'body'))) {
currentObjectResource = this.newBlankNode();
}
}
if (typeofAtt && !aboutAtt && this.inXHTMLMode && (current.localName === 'head' || current.localName === 'body')) {
typedResource = newSubject;
} else if (typeofAtt && !aboutAtt) {
typedResource = currentObjectResource;
}
} else if (propertyAtt && !contentAtt && !datatypeAtt) {
// Sequence Step 5.1: establish a new subject
if (aboutAtt) {
newSubject = this.parseSafeCURIEOrCURIEOrURI(aboutAtt.value, prefixes, base);
if (typeofAtt) {
typedResource = newSubject;
}
}
if (!newSubject && current.parentNode.nodeType === Node.DOCUMENT_NODE) {
newSubject = removeHash(current.baseURI);
if (typeofAtt) {
typedResource = newSubject;
}
} else if (!newSubject && context.parentObject) {
// 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
newSubject = removeHash(current.parentNode.baseURI) === context.parentObject ? removeHash(current.baseURI) : context.parentObject;
}
if (typeofAtt && !typedResource) {
if (resourceAtt) {
typedResource = this.parseSafeCURIEOrCURIEOrURI(resourceAtt.value, prefixes, base);
}
if (!typedResource && hrefAtt) {
typedResource = this.resolveAndNormalize(base, encodeURI(hrefAtt.value));
}
if (!typedResource && srcAtt) {
typedResource = this.resolveAndNormalize(base, encodeURI(srcAtt.value));
}
if (!typedResource && (this.inXHTMLMode || this.inHTMLMode) && (current.localName === 'head' || current.localName === 'body')) {
typedResource = newSubject;
}
if (!typedResource) {
typedResource = this.newBlankNode();
}
currentObjectResource = typedResource;
} // console.log(current.localName+", newSubject="+newSubject+", typedResource="+typedResource+", currentObjectResource="+currentObjectResource)
} else {
// Sequence Step 5.2: establish a new subject
if (aboutAtt) {
newSubject = this.parseSafeCURIEOrCURIEOrURI(aboutAtt.value, prefixes, base);
}
if (!newSubject && resourceAtt) {
newSubject = this.parseSafeCURIEOrCURIEOrURI(resourceAtt.value, prefixes, base);
}
if (!newSubject && hrefAtt) {
newSubject = this.resolveAndNormalize(base, encodeURI(hrefAtt.value));
}
if (!newSubject && srcAtt) {
newSubject = this.resolveAndNormalize(base, encodeURI(srcAtt.value));
}
if (!newSubject) {
if (current.parentNode.nodeType === Node.DOCUMENT_NODE) {
newSubject = removeHash(current.baseURI);
} else if ((this.inXHTMLMode || this.inHTMLMode) && (current.localName === 'head' || current.localName === 'body')) {
newSubject = removeHash(current.parentNode.baseURI) === context.parentObject ? removeHash(current.baseURI) : context.parentObject;
} else if (typeofAtt) {
newSubject = this.newBlankNode();
} else if (context.parentObject) {
// 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
newSubject = removeHash(current.parentNode.baseURI) === context.parentObject ? removeHash(current.baseURI) : context.parentObject;
if (!propertyAtt) {
skip = true;
}
}
}
if (typeofAtt) {
typedResource = newSubject;
}
} // console.log(current.tagName+": newSubject="+newSubject+", currentObjectResource="+currentObjectResource+", typedResource="+typedResource+", skip="+skip)
// var rdfaData = null
if (newSubject) {
// this.newSubject(current,newSubject)
if (aboutAtt || resourceAtt || typedResource) {
var id = newSubject;
if (typeofAtt && !aboutAtt && !resourceAtt && currentObjectResource) {
id = currentObjectResource;
} // console.log("Setting data attribute for "+current.localName+" for subject "+id)
this.newSubjectOrigin(current, id);
}
} // Sequence Step 7: generate type triple
if (typedResource) {
values = this.tokenize(typeofAtt.value);
for (var _i6 = 0; _i6 < values.length; _i6++) {
var object = this.parseTermOrCURIEOrAbsURI(values[_i6], vocabulary, context.terms, prefixes, base);
if (object) {
this.addTriple(current, typedResource, RDFaProcessor.typeURI, {
type: RDFaProcessor.objectURI,
value: object
});
}
}
} // Sequence Step 8: new list mappings if there is a new subject
// console.log("Step 8: newSubject="+newSubject+", context.parentObject="+context.parentObject)
if (newSubject && newSubject !== context.parentObject) {
// console.log("Generating new list mapping for "+newSubject)
listMapping = {};
listMappingDifferent = true;
} // Sequence Step 9: generate object triple
if (currentObjectResource) {
if (relAtt && inlistAtt) {
for (var _i7 = 0; _i7 < relAttPredicates.length; _i7++) {
var _list = listMapping[relAttPredicates[_i7]];
if (!_list) {
_list = [];
listMapping[relAttPredicates[_i7]] = _list;
}
_list.push({
type: RDFaProcessor.objectURI,
value: currentObjectResource
});
}
} else if (relAtt) {
for (var _i8 = 0; _i8 < relAttPredicates.length; _i8++) {
this.addTriple(current, newSubject, relAttPredicates[_i8], {
type: RDFaProcessor.objectURI,
value: currentObjectResource
});
}
}
if (revAtt) {
for (var _i9 = 0; _i9 < revAttPredicates.length; _i9++) {
this.addTriple(current, currentObjectResource, revAttPredicates[_i9], {
type: RDFaProcessor.objectURI,
value: newSubject
});
}
}
} else {
// Sequence Step 10: incomplete triples
if (newSubject && !currentObjectResource && (relAtt || revAtt)) {
currentObjectResource = this.newBlankNode(); // alert(current.tagName+": generated blank node, newSubject="+newSubject+" currentObjectResource="+currentObjectResource)
}
if (relAtt && inlistAtt) {
for (var _i10 = 0; _i10 < relAttPredicates.length; _i10++) {
var _list2 = listMapping[relAttPredicates[_i10]];
if (!_list2) {
_list2 = [];
listMapping[predicate] = _list2;
} // console.log("Adding incomplete list for "+predicate)
incomplete.push({
predicate: relAttPredicates[_i10],
list: _list2
});
}
} else if (relAtt) {
for (var _i11 = 0; _i11 < relAttPredicates.length; _i11++) {
incomplete.push({
predicate: relAttPredicates[_i11],
forward: true
});
}
}
if (revAtt) {
for (var _i12 = 0; _i12 < revAttPredicates.length; _i12++) {
incomplete.push({
predicate: revAttPredicates[_i12],
forward: false
});
}
}
} // Step 11: Current property values
if (propertyAtt) {
var datatype = null;
var content = null;
if (datatypeAtt) {
datatype = datatypeAtt.value === '' ? RDFaProcessor.PlainLiteralURI : this.parseTermOrCURIEOrAbsURI(datatypeAtt.value, vocabulary, context.terms, prefixes, base);
if (datetimeAtt && !contentAtt) {
content = datetimeAtt.value;
} else {
content = datatype === RDFaProcessor.XMLLiteralURI || datatype === RDFaProcessor.HTMLLiteralURI ? null : contentAtt ? contentAtt.value : current.textContent;
}
} else if (contentAtt) {
datatype = RDFaProcessor.PlainLiteralURI;
content = contentAtt.value;
} else if (datetimeAtt) {
content = datetimeAtt.value;
datatype = RDFaProcessor.deriveDateTimeType(content);
if (!datatype) {
datatype = RDFaProcessor.PlainLiteralURI;
}
} else if (!relAtt && !revAtt) {
if (resourceAtt) {
content = this.parseSafeCURIEOrCURIEOrURI(resourceAtt.value, prefixes, base);
}
if (!content && hrefAtt) {
content = this.resolveAndNormalize(base, encodeURI(hrefAtt.value));
} else if (!content && srcAtt) {
content = this.resolveAndNormalize(base, encodeURI(srcAtt.value));
}
if (content) {
datatype = RDFaProcessor.objectURI;
}
}
if (!datatype) {
if (typeofAtt && !aboutAtt) {
datatype = RDFaProcessor.objectURI;
content = typedResource;
} else {
content = current.textContent;
if (this.inHTMLMode && current.localName === 'time') {
datatype = RDFaProcessor.deriveDateTimeType(content);
}
if (!datatype) {
datatype = RDFaProcessor.PlainLiteralURI;
}
}
}
values = this.tokenize(propertyAtt.value);
for (var _i13 = 0; _i13 < values.length; _i13++) {
var _predicate2 = this.parsePredicate(values[_i13], vocabulary, context.terms, prefixes, base);
if (_predicate2) {
if (inlistAtt) {
var _list3 = listMapping[_predicate2];
if (!_list3) {
_list3 = [];
listMapping[_predicate2] = _list3;
}
_list3.push(datatype === RDFaProcessor.XMLLiteralURI || datatype === RDFaProcessor.HTMLLiteralURI ? {
type: datatype,
value: current.childNodes
} : {
type: datatype ? datatype : RDFaProcessor.PlainLiteralURI,
value: content,
language: language
});
} else {
if (datatype === RDFaProcessor.XMLLiteralURI || datatype === RDFaProcessor.HTMLLiteralURI) {
this.addTriple(current, newSubject, _predicate2, {
type: datatype,
value: current.childNodes
});
} else {
this.addTriple(current, newSubject, _predicate2, {
type: datatype ? datatype : RDFaProcessor.PlainLiteralURI,
value: content,
language: language
}); // console.log(newSubject+" "+predicate+"="+content)
}
}
}
}
} // Sequence Step 12: complete incomplete triples with new subject
if (newSubject && !skip) {
for (var _i14 = 0; _i14 < context.incomplete.length; _i14++) {
if (context.incomplete[_i14].list) {
// console.log("Adding subject "+newSubject+" to list for "+context.incomplete[i].predicate)
// TODO: it is unclear what to do here
context.incomplete[_i14].list.push({
type: RDFaProcessor.objectURI,
value: newSubject
});
} else if (context.incomplete[_i14].forward) {
// console.log(current.tagName+": completing forward triple "+context.incomplete[i].predicate+" with object="+newSubject)
this.addTriple(current, context.subject, context.incomplete[_i14].predicate, {
type: RDFaProcessor.objectURI,
value: newSubject
});
} else {
// console.log(current.tagName+": completing reverse triple with object="+context.subject)
this.addTriple(current, newSubject, context.incomplete[_i14].predicate, {
type: RDFaProcessor.objectURI,
value: context.subject
});
}
}
}
var childContext = null;
var listSubject = newSubject;
if (skip) {
// TODO: should subject be null?
childContext = this.push(context, context.subject); // TODO: should the entObject be passed along? If not, then intermediary children will keep properties from being associated with incomplete triples.
// TODO: Verify: if the current baseURI has changed and the parentObject is the parent's base URI, then the baseURI should change
childContext.parentObject = removeHash(current.parentNode.baseURI) === context.parentObject ? removeHash(current.baseURI) : context.parentObject;
childContext.incomplete = context.incomplete;
childContext.language = language;
childContext.prefixes = prefixes;
childContext.vocabulary = vocabulary;
} else {
childContext = this.push(context, newSubject);
childContext.parentObject = currentObjectResource ? currentObjectResource : newSubject ? newSubject : context.subject;
childContext.prefixes = prefixes;
childContext.incomplete = incomplete;
if (currentObjectResource) {
// console.log("Generating new list mapping for "+currentObjectResource)
listSubject = currentObjectResource;
listMapping = {};
listMappingDifferent = true;
}
childContext.listMapping = listMapping;
childContext.language = language;
childContext.vocabulary = vocabulary;
}
if (listMappingDifferent) {
// console.log("Pushing list parent "+current.localName)
queue.unshift({
parent: current,
context: context,
subject: listSubject,
listMapping: listMapping
});
}
for (var child = current.lastChild; child; child = child.previousSibling) {
if (child.nodeType === Node.ELEMENT_NODE) {
// console.log("Pushing child "+child.localName)
child.baseURI = current.baseURI;
queue.unshift({
current: child,
context: childContext
});
}
}
}
if (this.inHTMLMode) {
this.copyProperties();
}
for (var _i15 = 0; _i15 < this.finishedHandlers.length; _i15++) {
this.finishedHandlers[_i15](node);
}
}
}, {
key: "push",
value: function push(parent, subject) {
return {
parent: parent,
subject: subject ? subject : parent ? parent.subject : null,
parentObject: null,
incomplete: [],
listMapping: parent ? parent.listMapping : {},
language: parent ? parent.language : this.language,
prefixes: parent ? parent.prefixes : this.target.graph.prefixes,
terms: parent ? parent.terms : this.target.graph.terms,
vocabulary: parent ? parent.vocabulary : this.vocabulary
};
}
}, {
key: "resolveAndNormalize",
value: function resolveAndNormalize(base, uri) {
// console.log("Joining " + uri + " to " + base + " making " + Uri.join(uri, base))
return Uri.join(uri, base); // @@ normalize?
}
}, {
key: "setContext",
value: function setContext(node) {
// We only recognized XHTML+RDFa 1.1 if the version is set propertyly
if (node.localName === 'html' && node.getAttribute('version') === 'XHTML+RDFa 1.1') {
this.setXHTMLContext();
} else if (node.localName === 'html' || node.namespaceURI === 'http://www.w3.org/1999/xhtml') {
if (typeof document !== 'undefined' && document.doctype) {
if (document.doctype.publicId === '-//W3C//DTD XHTML+RDFa 1.0//EN' && document.doctype.systemId === 'http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd') {
console.log('WARNING: RDF 1.0 is not supported. Defaulting to HTML5 mode.');
this.setHTMLContext();
} else if (document.doctype.publicId === '-//W3C//DTD XHTML+RDFa 1.1//EN' && document.doctype.systemId === 'http://www.w3.org/MarkUp/DTD/xhtml-rdfa-2.dtd') {
this.setXHTMLContext();
} else {
this.setHTMLContext();
}
} else {
this.setHTMLContext();
}
} else {
this.setXMLContext();
}
}
}, {
key: "setHTMLContext",
value: function setHTMLContext() {
this.setInitialContext();
this.langAttributes = [{
namespaceURI: 'http://www.w3.org/XML/1998/namespace',
localName: 'lang'
}, {
namespaceURI: null,
localName: 'lang'
}];
this.inXHTMLMode = false;
this.inHTMLMode = true;
}
}, {
key: "setInitialContext",
value: function setInitialContext() {
this.vocabulary = null; // By default, the prefixes are terms are loaded to the RDFa 1.1. standard within the graph constructor
this.langAttributes = [{
namespaceURI: 'http://www.w3.org/XML/1998/namespace',
localName: 'lang'
}];
}
}, {
key: "setXHTMLContext",
value: function setXHTMLContext() {
this.setInitialContext();
this.inXHTMLMode = true;
this.inHTMLMode = false;
this.langAttributes = [{
namespaceURI: 'http://www.w3.org/XML/1998/namespace',
localName: 'lang'
}, {
namespaceURI: null,
localName: 'lang'
}]; // From http://www.w3.org/2011/rdfa-context/xhtml-rdfa-1.1
this.target.graph.terms['alternate'] = 'http://www.w3.org/1999/xhtml/vocab#alternate';
this.target.graph.terms['appendix'] = 'http://www.w3.org/1999/xhtml/vocab#appendix';
this.target.graph.terms['bookmark'] = 'http://www.w3.org/1999/xhtml/vocab#bookmark';
this.target.graph.terms['cite'] = 'http://www.w3.org/1999/xhtml/vocab#cite';
this.target.graph.terms['chapter'] = 'http://www.w3.org/1999/xhtml/vocab#chapter';
this.target.graph.terms['contents'] = 'http://www.w3.org/1999/xhtml/vocab#contents';
this.target.graph.terms['copyright'] = 'http://www.w3.org/1999/xhtml/vocab#copyright';
this.target.graph.terms['first'] = 'http://www.w3.org/1999/xhtml/vocab#first';
this.target.graph.terms['glossary'] = 'http://www.w3.org/1999/xhtml/vocab#glossary';
this.target.graph.terms['help'] = 'http://www.w3.org/1999/xhtml/vocab#help';
this.target.graph.terms['icon'] = 'http://www.w3.org/1999/xhtml/vocab#icon';
this.target.graph.terms['index'] = 'http://www.w3.org/1999/xhtml/vocab#index';
this.target.graph.terms['last'] = 'http://www.w3.org/1999/xhtml/vocab#last';
this.target.graph.terms['license'] = 'http://www.w3.org/1999/xhtml/vocab#license';
this.target.graph.terms['meta'] = 'http://www.w3.org/1999/xhtml/vocab#meta';
this.target.graph.terms['next'] = 'http://www.w3.org/1999/xhtml/vocab#next';
this.target.graph.terms['prev'] = 'http://www.w3.org/1999/xhtml/vocab#prev';
this.target.graph.terms['previous'] = 'http://www.w3.org/1999/xhtml/vocab#previous';
this.target.graph.terms['section'] = 'http://www.w3.org/1999/xhtml/vocab#section';
this.target.graph.terms['stylesheet'] = 'http://www.w3.org/1999/xhtml/vocab#stylesheet';
this.target.graph.terms['subsection'] = 'http://www.w3.org/1999/xhtml/vocab#subsection';
this.target.graph.terms['start'] = 'http://www.w3.org/1999/xhtml/vocab#start';
this.target.graph.terms['top'] = 'http://www.w3.org/1999/xhtml/vocab#top';
this.target.graph.terms['up'] = 'http://www.w3.org/1999/xhtml/vocab#up';
this.target.graph.terms['p3pv1'] = 'http://www.w3.org/1999/xhtml/vocab#p3pv1'; // other
this.target.graph.terms['related'] = 'http://www.w3.org/1999/xhtml/vocab#related';
this.target.graph.terms['role'] = 'http://www.w3.org/1999/xhtml/vocab#role';
this.target.graph.terms['transformation'] = 'http://www.w3.org/1999/xhtml/vocab#transformation';
}
}, {
key: "setXMLContext",
value: function setXMLContext() {
this.setInitialContext();
this.inXHTMLMode = false;
this.inHTMLMode = false;
}
}, {
key: "tokenize",
value: function tokenize(str) {
return this.trim(str).split(/\s+/);
}
}, {
key: "toRDFNodeObject",
value: function toRDFNodeObject(x) {
if (typeof x === 'undefined') return undefined;
if (typeof x === 'string') {
if (x.substring(0, 2) === '_:') {
if (typeof this.blankNodes[x.substring(2)] === 'undefined') {
this.blankNodes[x.substring(2)] = rdf.blankNode(x.substring(2));
}
return this.blankNodes[x.substring(2)];
}
return rdf.namedNode(x);
}
switch (x.type) {
case RDFaProcessor.objectURI:
if (x.value.substring(0, 2) === '_:') {
if (typeof this.blankNodes[x.value.substring(2)] === 'undefined') {
this.blankNodes[x.value.substring(2)] = rdf.blankNode(x.value.substring(2));
}
return this.blankNodes[x.value.substring(2)];
}
return rdf.namedNode(x.value);
case RDFaProcessor.PlainLiteralURI:
return rdf.literal(x.value, x.language || '');
case RDFaProcessor.XMLLiteralURI:
case RDFaProcessor.HTMLLiteralURI:
var string = '';
Object.keys(x.value).forEach(function (i) {
string += Util.domToString(x.value[i], this.htmlOptions);
});
return rdf.literal(string, null, rdf.namedNode(x.type));
default:
return rdf.literal(x.value, null, rdf.namedNode(x.type));
}
}
}, {
key: "trim",
value: function trim(str) {
return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
}
}], [{
key: "parseRDFaDOM",
value: function parseRDFaDOM(dom, kb, base) {
var p = new RDFaProcessor(kb, {
'base': base
});
dom.baseURI = base;
p.process(dom);
}
}]);
return RDFaProcessor;
}();
RDFaProcessor.XMLLiteralURI = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral';
RDFaProcessor.HTMLLiteralURI = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#HTML';
RDFaProcessor.PlainLiteralURI = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#PlainLiteral';
RDFaProcessor.objectURI = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#object';
RDFaProcessor.typeURI = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type';
RDFaProcessor.nameChar = "[-A-Z_a-z\xC0-\xD6\xD8-\xF6\xF8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u10000-\uEFFFF.0-9\xB7\u0300-\u036F\u203F-\u2040]";
RDFaProcessor.nameStartChar = "[A-Za-z\xC0-\xD6\xD8-\xF6\xF8-\xFF\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_]";
RDFaProcessor.NCNAME = new RegExp('^' + RDFaProcessor.nameStartChar + RDFaProcessor.nameChar + '*$');
/*
RDFaProcessor.prototype.resolveAndNormalize = function(base,href) {
var u = base.resolve(href)
var parsed = this.parseURI(u)
parsed.normalize()
return parsed.spec
}
*/
RDFaProcessor.dateTimeTypes = [{
pattern: /-?P(?:[0-9]+Y)?(?:[0-9]+M)?(?:[0-9]+D)?(?:T(?:[0-9]+H)?(?:[0-9]+M)?(?:[0-9]+(?:\.[0-9]+)?S)?)?/,
type: 'http://www.w3.org/2001/XMLSchema#duration'
}, {
pattern: /-?(?:[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])?/,
type: 'http://www.w3.org/2001/XMLSchema#dateTime'
}, {
pattern: /-?(?:[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])?/,
type: 'http://www.w3.org/2001/XMLSchema#date'
}, {
pattern: /(?:[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])?/,
type: 'http://www.w3.org/2001/XMLSchema#time'
}, {
pattern: /-?(?:[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]/,
type: 'http://www.w3.org/2001/XMLSchema#gYearMonth'
}, {
pattern: /-?[1-9][0-9][0-9][0-9]|0[1-9][0-9][0-9]|00[1-9][0-9]|000[1-9]/,
type: 'http://www.w3.org/2001/XMLSchema#gYear'
}];
module.exports = RDFaProcessor;