diff --git a/README b/README deleted file mode 100644 index 821eed1..0000000 --- a/README +++ /dev/null @@ -1,69 +0,0 @@ -Chrome LOD extension -==================== - -An extension for Chrome that looks for the presence of Linked Open -Data behind the pages you browse and if available, reveals the -underlying data. - -Debugging/Building ------------------- - -In Chrome, open the tools/extensions page, ensure that developer mode -is selected, and click to 'load unpacked extension...'. Select the -directory you checked out the chrome-lod source to. This should -enable the extension directly. - -In order to package the extension for deployment, use the 'pack -extension' button, which will result in a chrome-lod.crx file and -associated keyfile. - -Rationale ---------- - -The extension runs once on each page you visit looking for any RDF -data it can find in the following order: - -1) Any tags in the page with relationship 'meta' or 'alternate' -pointing to a URI with media-type application/rdf+xml or text/turtle. - -2) Any RDFa in the body of the HTML document. - -3) Using content negotiation on the current URI, asking for -application/rdf+xml or text/turtle representation of the current -resource. - -If an RDF representation is available, it will be rendered behind the -current page and a peel-back animation will reveal the background RDF -data as the mouse hovers over the top left corner of the page. - -Examples --------- - -http://sws.geonames.org/3020251/ - -http://data.nytimes.com/48675831753778135041 - -http://collection.britishmuseum.org/id/object/EOC3130 - -http://data.ordnancesurvey.co.uk/datasets/os-linked-data - -http://id.loc.gov/vocabulary/organizations/ukmajru.html - -http://www.bbc.co.uk/programmes/b03kqfzx - -http://alpha.acropolis.org.uk/dc1c141fe5d14dcbb04e907156c62e46#id - -http://live.dbpedia.org/page/William_Shakespeare - -http://data.europeana.eu/item/92056/BD9D5C6C6B02248F187238E9D7CC09EAF17BEA59 - -http://didactalia.net/comunidad/materialeducativo/recurso/La-teoria-de-la-relatividad-en-ingles/eb95e40e-937f-4447-a68d-5f1a3fbc97ff - -Todo ----- - -Parsing Turtle to look for licensing statements. - -Checking that the license applies to the document URI of the RDF document. - -Checking what license is being applied and that it is usable. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..c9abd6d --- /dev/null +++ b/README.md @@ -0,0 +1,76 @@ +Chrome LOD extension +==================== + +An extension for Chrome that looks for the presence of Linked Open +Data behind the pages you browse and if available, reveals the +underlying data. + +Debugging/Building +------------------ + +In Chrome, open the tools/extensions page, ensure that developer mode +is selected, and click to 'load unpacked extension...'. Select the +directory you checked out the chrome-lod source to. This should +enable the extension directly. + +In order to package the extension for deployment, use the 'pack +extension' button, which will result in a chrome-lod.crx file and +associated keyfile. + +Rationale +--------- + +The extension runs once on each page you visit looking for any RDF +data it can find in the following order: + +1) Any tags in the page with relationship 'meta' or 'alternate' +pointing to a URI with media-type application/rdf+xml, text/turtle or +text/n3. + +2) If the page you're visiting is the result of a redirect, then try +to GET the previous page using content negotiation asking for an +application/rdf+xml, text/turtle or text/n3 representation, following +any further redirects. + +3) Just use content negotiation on the current URI, again asking for +RDF and following any redirects. + +If an RDF representation is available, it will be rendered behind the +current page and a peel-back animation will reveal the background RDF +data as the mouse hovers over the top left corner of the page. + +A limited check will be done to find out whether there is any machine +readable license about the published RDF document. + +Finally, a traffic light is rendered in the right of the omnibox to +give an indication of conformance of the underlying linked (open) +data. + +Examples to try +--------------- + +http://sws.geonames.org/3020251/ + +http://data.nytimes.com/48675831753778135041 + +http://collection.britishmuseum.org/id/object/EOC3130 + +http://data.ordnancesurvey.co.uk/datasets/os-linked-data + +http://id.loc.gov/vocabulary/organizations/ukmajru.html + +http://beta.acropolis.org.uk/79a5f7dd9c284e1193e94797fbf2f90f + +http://live.dbpedia.org/page/William_Shakespeare + +http://data.europeana.eu/item/92056/BD9D5C6C6B02248F187238E9D7CC09EAF17BEA59 + + +Todo +---- + +Parsing Turtle to look for licensing statements. + +Checking that the license applies to the document URI of the RDF document. + +Checking what license is being applied and that it is usable. \ No newline at end of file diff --git a/contentscript.js b/contentscript.js index 12baaa1..a5bb443 100644 --- a/contentscript.js +++ b/contentscript.js @@ -48,6 +48,7 @@ function checkRdfXmlLicense(data, format) { var parser = new DOMParser(); + // TODO: use a different library so we can parse different RDF formats. var doc = parser.parseFromString(data, 'text/xml'); try { var rdf = $.rdf().load(doc); @@ -71,6 +72,10 @@ } function fetchRdf(rdfUrl, failfunc) { + var onFail = $.noop; + if (typeof failFunc == 'function') { + onFail = failFunc; + } $.ajax(rdfUrl, { headers: { Accept: acceptFormats.join(', '), @@ -78,7 +83,7 @@ }, dataType: 'text', error: function(req, textStatus, errorThrown) { - failfunc(); + onFail(); }, success: function(data, textStatus, res) { var ct = res.getResponseHeader('Content-Type'); @@ -90,6 +95,13 @@ break; } } + for (var dodgyFormat in dodgyFormats) { + if (ct.slice(0, dodgyFormat.length) == dodgyFormat) { + format = dodgyFormats[dodgyFormat]; + console.log("Dodgy content type: " + dodgyFormat); + break; + } + } if (format != null) { peelBackRdf(data, format); console.log("baseURI: " + data.baseURI); @@ -101,31 +113,20 @@ console.log(response.text); }); } else { - failfunc(); + onFail(); } } else { - failfunc(); + onFail(); } } }); } -var res = document.evaluate("//link[(@rel = 'alternate') or (@rel = 'meta')]", document.head, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null) - -var rdfUrl = null; -var rdfFormat = null; -var acceptFormats = ['application/rdf+xml', 'text/turtle']; - -for (var i=0; i < res.snapshotLength; i++) { - if (acceptFormats.indexOf(res.snapshotItem(i).type) > -1) { - rdfFormat = res.snapshotItem(i).type; - rdfUrl = res.snapshotItem(i).href; // relative - break; +function checkRdfa(failFunc) { + var onFail = $.noop; + if (typeof failFunc == 'function') { + onFail = failFunc; } -} - -if (rdfUrl == null) { - // No link URL, so first check to see whether there's any RDFa in the current document var localdata = $(document.body).rdf(); if (localdata.databank.size() > 0) { // Serialize it out as RDF/XML @@ -142,20 +143,43 @@ console.log(response.text); }); } else { - // check to see whether we've been redirected here - chrome.runtime.sendMessage({ - method: 'isRedirect', - url: document.URL - }, function(response) { - if (response.redirect) { - fetchRdf(response.fromUrl, function() { - fetchRdf(document.URL, function() {}); // if failed to fetch prior page as RDF - }); - } else { // if no redirect, try fetching current page as RDF - fetchRdf(document.URL, function() {}); - } - }); + onFail(); } +} + +var res = document.evaluate("//link[(@rel = 'alternate') or (@rel = 'meta')]", document.head, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null) + +var rdfUrl = null; +var rdfFormat = null; +var acceptFormats = ['application/rdf+xml', 'text/turtle', 'text/n3']; +var dodgyFormats = {'text/rdf+n3': 'text/n3'}; + +for (var i=0; i < res.snapshotLength; i++) { + if (acceptFormats.indexOf(res.snapshotItem(i).type) > -1) { + rdfFormat = res.snapshotItem(i).type; + rdfUrl = res.snapshotItem(i).href; // relative + break; + } +} + +if (rdfUrl != null) { + // Got a to some RDF, so fetch it + fetchRdf(rdfUrl); } else { - fetchRdf(rdfUrl, function() {}); + // No link URL. + // Check to see whether we've been redirected here + chrome.runtime.sendMessage({ + method: 'isRedirect', + url: document.URL + }, function(response) { + if (response.redirect) { + // Redirected here, so try fetch RDF from previous URL to see if it was a + // content negotiation redirect. + fetchRdf(response.fromUrl, function() { // failed, so fallback to trying current page + fetchRdf(document.URL, checkRdfa); // and if that failed, look for RDFa + }); + } else { // if no redirect, try fetching current page as RDF + fetchRdf(document.URL, checkRdfa); // and if that failed, look for RDFa + } + }); } diff --git a/jquery.rdfquery.core-1.0.js b/jquery.rdfquery.core-1.0.js deleted file mode 100644 index ba35eb1..0000000 --- a/jquery.rdfquery.core-1.0.js +++ /dev/null @@ -1,3598 +0,0 @@ -/* - * $ URIs @VERSION - * - * Copyright (c) 2008,2009 Jeni Tennison - * Licensed under the MIT (MIT-LICENSE.txt) - * - */ -/** - * @fileOverview $ URIs - * @author Jeni Tennison - * @copyright (c) 2008,2009 Jeni Tennison - * @license MIT license (MIT-LICENSE.txt) - * @version 1.0 - */ -/** - * @class - * @name jQuery - * @exports $ as jQuery - * @description rdfQuery is a jQuery plugin. The only fields and methods listed here are those that come as part of the rdfQuery library. - */ -(function ($) { - - var - mem = {}, - uriRegex = /^(([a-z][\-a-z0-9+\.]*):)?(\/\/([^\/?#]+))?([^?#]*)?(\?([^#]*))?(#(.*))?$/i, - docURI, - - parseURI = function (u) { - var m = u.match(uriRegex); - if (m === null) { - throw "Malformed URI: " + u; - } - return { - scheme: m[1] ? m[2].toLowerCase() : undefined, - authority: m[3] ? m[4] : undefined, - path: m[5] || '', - query: m[6] ? m[7] : undefined, - fragment: m[8] ? m[9] : undefined - }; - }, - - removeDotSegments = function (u) { - var r = '', m = []; - if (/\./.test(u)) { - while (u !== undefined && u !== '') { - if (u === '.' || u === '..') { - u = ''; - } else if (/^\.\.\//.test(u)) { // starts with ../ - u = u.substring(3); - } else if (/^\.\//.test(u)) { // starts with ./ - u = u.substring(2); - } else if (/^\/\.(\/|$)/.test(u)) { // starts with /./ or consists of /. - u = '/' + u.substring(3); - } else if (/^\/\.\.(\/|$)/.test(u)) { // starts with /../ or consists of /.. - u = '/' + u.substring(4); - r = r.replace(/\/?[^\/]+$/, ''); - } else { - m = u.match(/^(\/?[^\/]*)(\/.*)?$/); - u = m[2]; - r = r + m[1]; - } - } - return r; - } else { - return u; - } - }, - - merge = function (b, r) { - if (b.authority !== '' && (b.path === undefined || b.path === '')) { - return '/' + r; - } else { - return b.path.replace(/[^\/]+$/, '') + r; - } - }; - - /** - * Creates a new jQuery.uri object. This should be invoked as a method rather than constructed using new. - * @class Represents a URI - * @param {String} [relative=''] - * @param {String|jQuery.uri} [base] Defaults to the base URI of the page - * @returns {jQuery.uri} The new jQuery.uri object. - * @example uri = jQuery.uri('/my/file.html'); - */ - $.uri = function (relative, base) { - var uri; - relative = relative || ''; - if (mem[relative]) { - return mem[relative]; - } - base = base || $.uri.base(); - if (typeof base === 'string') { - base = $.uri.absolute(base); - } - uri = new $.uri.fn.init(relative, base); - if (mem[uri]) { - return mem[uri]; - } else { - mem[uri] = uri; - return uri; - } - }; - - $.uri.fn = $.uri.prototype = { - /** - * The scheme used in the URI - * @type String - */ - scheme: undefined, - /** - * The authority used in the URI - * @type String - */ - authority: undefined, - /** - * The path used in the URI - * @type String - */ - path: undefined, - /** - * The query part of the URI - * @type String - */ - query: undefined, - /** - * The fragment part of the URI - * @type String - */ - fragment: undefined, - - init: function (relative, base) { - var r = {}; - base = base || {}; - $.extend(this, parseURI(relative)); - if (this.scheme === undefined) { - this.scheme = base.scheme; - if (this.authority !== undefined) { - this.path = removeDotSegments(this.path); - } else { - this.authority = base.authority; - if (this.path === '') { - this.path = base.path; - if (this.query === undefined) { - this.query = base.query; - } - } else { - if (!/^\//.test(this.path)) { - this.path = merge(base, this.path); - } - this.path = removeDotSegments(this.path); - } - } - } - if (this.scheme === undefined) { - throw "Malformed URI: URI is not an absolute URI and no base supplied: " + relative; - } - return this; - }, - - /** - * Resolves a relative URI relative to this URI - * @param {String} relative - * @returns jQuery.uri - */ - resolve: function (relative) { - return $.uri(relative, this); - }, - - /** - * Creates a relative URI giving the path from this URI to the absolute URI passed as a parameter - * @param {String|jQuery.uri} absolute - * @returns String - */ - relative: function (absolute) { - var aPath, bPath, i = 0, j, resultPath = [], result = ''; - if (typeof absolute === 'string') { - absolute = $.uri(absolute, {}); - } - if (absolute.scheme !== this.scheme || - absolute.authority !== this.authority) { - return absolute.toString(); - } - if (absolute.path !== this.path) { - aPath = absolute.path.split('/'); - bPath = this.path.split('/'); - if (aPath[1] !== bPath[1]) { - result = absolute.path; - } else { - while (aPath[i] === bPath[i]) { - i += 1; - } - j = i; - for (; i < bPath.length - 1; i += 1) { - resultPath.push('..'); - } - for (; j < aPath.length; j += 1) { - resultPath.push(aPath[j]); - } - result = resultPath.join('/'); - } - result = absolute.query === undefined ? result : result + '?' + absolute.query; - result = absolute.fragment === undefined ? result : result + '#' + absolute.fragment; - return result; - } - if (absolute.query !== undefined && absolute.query !== this.query) { - return '?' + absolute.query + (absolute.fragment === undefined ? '' : '#' + absolute.fragment); - } - if (absolute.fragment !== undefined && absolute.fragment !== this.fragment) { - return '#' + absolute.fragment; - } - return ''; - }, - - /** - * Returns the URI as an absolute string - * @returns String - */ - toString: function () { - var result = ''; - if (this._string) { - return this._string; - } else { - result = this.scheme === undefined ? result : (result + this.scheme + ':'); - result = this.authority === undefined ? result : (result + '//' + this.authority); - result = result + this.path; - result = this.query === undefined ? result : (result + '?' + this.query); - result = this.fragment === undefined ? result : (result + '#' + this.fragment); - this._string = result; - return result; - } - } - - }; - - $.uri.fn.init.prototype = $.uri.fn; - - /** - * Creates a {@link jQuery.uri} from a known-to-be-absolute URI - * @param {String} - * @returns {jQuery.uri} - */ - $.uri.absolute = function (uri) { - return $.uri(uri, {}); - }; - - /** - * Creates a {@link jQuery.uri} from a relative URI and an optional base URI - * @returns {jQuery.uri} - * @see jQuery.uri - */ - $.uri.resolve = function (relative, base) { - return $.uri(relative, base); - }; - - /** - * Creates a string giving the relative path from a base URI to an absolute URI - * @param {String} absolute - * @param {String} base - * @returns {String} - */ - $.uri.relative = function (absolute, base) { - return $.uri(base, {}).relative(absolute); - }; - - /** - * Returns the base URI of the page - * @returns {jQuery.uri} - */ - $.uri.base = function () { - return $(document).base(); - }; - - /** - * Returns the base URI in scope for the first selected element - * @methodOf jQuery# - * @name jQuery#base - * @returns {jQuery.uri} - * @example baseURI = $('img').base(); - */ - $.fn.base = function () { - var base = $(this).parents().andSelf().find('base').attr('href'), - doc = $(this)[0].ownerDocument || document, - docURI = $.uri.absolute(doc.location === null ? document.location.href : doc.location.href); - return base === undefined ? docURI : $.uri(base, docURI); - }; - -})(jQuery); -/* - * jQuery CURIE @VERSION - * - * Copyright (c) 2008,2009 Jeni Tennison - * Licensed under the MIT (MIT-LICENSE.txt) - * - * Depends: - * jquery.uri.js - */ -/** - * @fileOverview XML Namespace processing - * @author Jeni Tennison - * @copyright (c) 2008,2009 Jeni Tennison - * @license MIT license (MIT-LICENSE.txt) - * @version 1.0 - * @requires jquery.uri.js - */ - -/*global jQuery */ -(function ($) { - - var - xmlnsRegex = /\sxmlns(?::([^ =]+))?\s*=\s*(?:"([^"]*)"|'([^']*)')/g; - -/** - * Returns the namespaces declared in the scope of the first selected element, or - * adds a namespace declaration to all selected elements. Pass in no parameters - * to return all namespaces bindings on the first selected element. If only - * the prefix parameter is specified, this method will return the namespace - * URI that is bound to the specified prefix on the first element in the selection - * If the prefix and uri parameters are both specified, this method will - * add the binding of the specified prefix and namespace URI to all elements - * in the selection. - * @methodOf jQuery# - * @name jQuery#xmlns - * @param {String} [prefix] Restricts the namespaces returned to only the namespace with the specified namespace prefix. - * @param {String|jQuery.uri} [uri] Adds a namespace declaration to the selected elements that maps the specified prefix to the specified namespace. - * @param {Object} [inherited] A map of inherited namespace bindings. - * @returns {Object|jQuery.uri|jQuery} - * @example - * // Retrieve all of the namespace bindings on the HTML document element - * var nsMap = $('html').xmlns(); - * @example - * // Retrieve the namespace URI mapped to the 'dc' prefix on the HTML document element - * var dcNamespace = $('html').xmlns('dc'); - * @example - * // Create a namespace declaration that binds the 'dc' prefix to the URI 'http://purl.org/dc/elements/1.1/' - * $('html').xmlns('dc', 'http://purl.org/dc/elements/1.1/'); - */ - $.fn.xmlns = function (prefix, uri, inherited) { - var - elem = this.eq(0), - ns = elem.data('xmlns'), - e = elem[0], a, p, i, - decl = prefix ? 'xmlns:' + prefix : 'xmlns', - value, - tag, found = false; - if (uri === undefined) { - if (prefix === undefined) { // get the in-scope declarations on the first element - if (ns === undefined) { - ns = {}; - if (e.attributes && e.attributes.getNamedItemNS) { - for (i = 0; i < e.attributes.length; i += 1) { - a = e.attributes[i]; - if (/^xmlns(:(.+))?$/.test(a.nodeName)) { - prefix = /^xmlns(:(.+))?$/.exec(a.nodeName)[2] || ''; - value = a.nodeValue; - if (prefix === '' || value !== '') { - ns[prefix] = $.uri(a.nodeValue); - found = true; - } - } - } - } else { - tag = /<[^>]+>/.exec(e.outerHTML); - a = xmlnsRegex.exec(tag); - while (a !== null) { - prefix = a[1] || ''; - value = a[2] || a[3]; - if (prefix === '' || value !== '') { - ns[prefix] = $.uri(a[2] || a[3]); - found = true; - } - a = xmlnsRegex.exec(tag); - } - xmlnsRegex.lastIndex = 0; - } - inherited = inherited || (e.parentNode.nodeType === 1 ? elem.parent().xmlns() : {}); - ns = found ? $.extend({}, inherited, ns) : inherited; - elem.data('xmlns', ns); - } - return ns; - } else if (typeof prefix === 'object') { // set the prefix mappings defined in the object - for (p in prefix) { - if (typeof prefix[p] === 'string') { - this.xmlns(p, prefix[p]); - } - } - this.find('*').andSelf().removeData('xmlns'); - return this; - } else { // get the in-scope declaration associated with this prefix on the first element - if (ns === undefined) { - ns = elem.xmlns(); - } - return ns[prefix]; - } - } else { // set - this.find('*').andSelf().removeData('xmlns'); - return this.attr(decl, uri); - } - }; - -/** - * Removes one or more XML namespace bindings from the selected elements. - * @methodOf jQuery# - * @name jQuery#removeXmlns - * @param {String|Object|String[]} prefix The prefix(es) of the XML namespace bindings that are to be removed from the selected elements. - * @returns {jQuery} The original jQuery object. - * @example - * // Remove the foaf namespace declaration from the body element: - * $('body').removeXmlns('foaf'); - * @example - * // Remove the foo and bar namespace declarations from all h2 elements - * $('h2').removeXmlns(['foo', 'bar']); - * @example - * // Remove the foo and bar namespace declarations from all h2 elements - * var namespaces = { foo : 'http://www.example.org/foo', bar : 'http://www.example.org/bar' }; - * $('h2').removeXmlns(namespaces); - */ - $.fn.removeXmlns = function (prefix) { - var decl, p, i; - if (typeof prefix === 'object') { - if (prefix.length === undefined) { // assume an object representing namespaces - for (p in prefix) { - if (typeof prefix[p] === 'string') { - this.removeXmlns(p); - } - } - } else { // it's an array - for (i = 0; i < prefix.length; i += 1) { - this.removeXmlns(prefix[i]); - } - } - } else { - decl = prefix ? 'xmlns:' + prefix : 'xmlns'; - this.removeAttr(decl); - } - this.find('*').andSelf().removeData('xmlns'); - return this; - }; - - $.fn.qname = function (name) { - var m, prefix, namespace; - if (name === undefined) { - if (this[0].outerHTML === undefined) { - name = this[0].nodeName.toLowerCase(); - } else { - name = /<([^ >]+)/.exec(this[0].outerHTML)[1].toLowerCase(); - } - } - if (name === '?xml:namespace') { - // there's a prefix on the name, but we can't get at it - throw "XMLinHTML: Unable to get the prefix to resolve the name of this element"; - } - m = /^(([^:]+):)?([^:]+)$/.exec(name); - prefix = m[2] || ''; - namespace = this.xmlns(prefix); - if (namespace === undefined && prefix !== '') { - throw "MalformedQName: The prefix " + prefix + " is not declared"; - } - return { - namespace: namespace, - localPart: m[3], - prefix: prefix, - name: name - }; - }; - -})(jQuery); -/* - * jQuery CURIE @VERSION - * - * Copyright (c) 2008,2009 Jeni Tennison - * Licensed under the MIT (MIT-LICENSE.txt) - * - * Depends: - * jquery.uri.js - */ -/** - * @fileOverview XML Schema datatype handling - * @author Jeni Tennison - * @copyright (c) 2008,2009 Jeni Tennison - * @license MIT license (MIT-LICENSE.txt) - * @version 1.0 - * @requires jquery.uri.js - */ - -(function ($) { - - var strip = function (value) { - return value.replace(/[ \t\n\r]+/, ' ').replace(/^ +/, '').replace(/ +$/, ''); - }; - - /** - * Creates a new jQuery.typedValue object. This should be invoked as a method - * rather than constructed using new. - * @class Represents a value with an XML Schema datatype - * @param {String} value The string representation of the value - * @param {String} datatype The XML Schema datatype URI - * @returns {jQuery.typedValue} - * @example intValue = jQuery.typedValue('42', 'http://www.w3.org/2001/XMLSchema#integer'); - */ - $.typedValue = function (value, datatype) { - return $.typedValue.fn.init(value, datatype); - }; - - $.typedValue.fn = $.typedValue.prototype = { - /** - * The string representation of the value - * @memberOf jQuery.typedValue# - */ - representation: undefined, - /** - * The value as an object. The type of the object will - * depend on the XML Schema datatype URI specified - * in the constructor. The following table lists the mappings - * currently supported: - *
XML Schema Datatype | - *Value type | - *
---|---|
http://www.w3.org/2001/XMLSchema#string | - *string | - *
http://www.w3.org/2001/XMLSchema#boolean | - *bool | - *
http://www.w3.org/2001/XMLSchema#decimal | - *string | - *
http://www.w3.org/2001/XMLSchema#integer | - *int | - *
http://www.w3.org/2001/XMLSchema#int | - *int | - *
http://www.w3.org/2001/XMLSchema#float | - *float | - *
http://www.w3.org/2001/XMLSchema#double | - *float | - *
http://www.w3.org/2001/XMLSchema#dateTime | - *string | - *
http://www.w3.org/2001/XMLSchema#date | - *string | - *
http://www.w3.org/2001/XMLSchema#gMonthDay | - *string | - *
http://www.w3.org/2001/XMLSchema#anyURI | - *string | - *
Creates a new jQuery.rdf object. This should be invoked as a method rather than constructed using new; indeed you will usually want to generate these objects using a method such as {@link jQuery#rdf} or {@link jQuery.rdf#where}.
- * @classA jQuery.rdf object represents the results of a query over its {@link jQuery.rdf#databank}. The results of a query are a sequence of objects which represent the bindings of values to the variables used in filter expressions specified using {@link jQuery.rdf#where} or {@link jQuery.rdf#optional}. Each of the objects in this sequence has associated with it a set of triples that are the sources for the variable bindings, which you can get at using {@link jQuery.rdf#sources}.
- *The {@link jQuery.rdf} object itself is a lot like a {@link jQuery} object. It has a {@link jQuery.rdf#length} and the individual matches can be accessed using [n]
, but you can also iterate through the matches using {@link jQuery.rdf#map} or {@link jQuery.rdf#each}.
{@link jQuery.rdf} is designed to mirror the functionality of SPARQL while providing an interface that's familiar and easy to use for jQuery programmers.
- * @param {Object} [options] - * @param {jQuery.rdf.databank} [options.databank] The databank that this query should operate over. - * @param {jQuery.rdf.triple[]} [options.triples] A set of triples over which the query operates; this is only used if options.databank isn't specified, in which case a new databank with these triples is generated. - * @param {Object} [options.namespaces] An object representing a set of namespace bindings. Rather than passing this in when you construct the {@link jQuery.rdf} instance, you will usually want to use the {@link jQuery.rdf#prefix} method. - * @param {String|jQuery.uri} [options.base] The base URI used to interpret any relative URIs used within the query. - * @returns {jQuery.rdf} - * @example rdf = jQuery.rdf(); - * @see jQuery#rdf - */ - $.rdf = function (options) { - return new $.rdf.fn.init(options); - }; - - $.rdf.fn = $.rdf.prototype = { - /** - * The version of rdfQuery. - * @type String - */ - rdfquery: '0.9', - - init: function (options) { - var databanks; - options = options || {}; - /* must specify either a parent or a union, otherwise it's the top */ - this.parent = options.parent; - this.union = options.union; - this.top = this.parent === undefined && this.union === undefined; - if (this.union === undefined) { - if (options.databank === undefined) { - /** - * The databank over which this query operates. - * @type jQuery.rdf.databank - */ - this.databank = this.parent === undefined ? $.rdf.databank(options.triples, options) : this.parent.databank; - } else { - this.databank = options.databank; - } - } else { - databanks = $.map(this.union, function (query) { - return query.databank; - }); - databanks = $.unique(databanks); - if (databanks[1] !== undefined) { - this.databank = $.rdf.databank(undefined, { union: databanks }); - } else { - this.databank = databanks[0]; - } - } - this.children = []; - this.partOf = []; - this.filterExp = options.filter; - this.alphaMemory = []; - this.matches = []; - /** - * The number of matches represented by the {@link jQuery.rdf} object. - * @type Integer - */ - this.length = 0; - if (this.filterExp !== undefined) { - if (!$.isFunction(this.filterExp)) { - registerQuery(this.databank, this); - this.alphaMemory = findMatches(this.databank.triples(), this.filterExp); - } - } - leftActivate(this); - return this; - }, - - /** - * Sets or returns the base URI of the {@link jQuery.rdf#databank}. - * @param {String|jQuery.uri} [base] - * @returns A {@link jQuery.uri} if no base URI is specified, otherwise returns this {@link jQuery.rdf} object. - * @example baseURI = jQuery('html').rdf().base(); - * @example jQuery('html').rdf().base('http://www.example.org/'); - * @see jQuery.rdf.databank#base - */ - base: function (base) { - if (base === undefined) { - return this.databank.base(); - } else { - this.databank.base(base); - return this; - } - }, - - /** - * Sets or returns a namespace binding on the {@link jQuery.rdf#databank}. - * @param {String} [prefix] - * @param {String} [namespace] - * @returns {Object|jQuery.uri|jQuery.rdf} If no prefix or namespace is specified, returns an object providing all namespace bindings on the {@link jQuery.rdf.databank}. If a prefix is specified without a namespace, returns the {@link jQuery.uri} associated with that prefix. Otherwise returns this {@link jQuery.rdf} object after setting the namespace binding. - * @example namespace = jQuery('html').rdf().prefix('foaf'); - * @example jQuery('html').rdf().prefix('foaf', 'http://xmlns.com/foaf/0.1/'); - * @see jQuery.rdf.databank#prefix - */ - prefix: function (prefix, namespace) { - if (namespace === undefined) { - return this.databank.prefix(prefix); - } else { - this.databank.prefix(prefix, namespace); - return this; - } - }, - - /** - * Adds a triple to the {@link jQuery.rdf#databank} or another {@link jQuery.rdf} object to create a union. - * @param {String|jQuery.rdf.triple|jQuery.rdf.pattern|jQuery.rdf} triple The triple, {@link jQuery.rdf.pattern} or {@link jQuery.rdf} object to be added to this one. If the triple is a {@link jQuery.rdf} object, the two queries are unioned together. If the triple is a string, it's parsed as a {@link jQuery.rdf.pattern}. The pattern will be completed using the current matches on the {@link jQuery.rdf} object to create multiple triples, one for each set of bindings. - * @param {Object} [options] - * @param {Object} [options.namespaces] An object representing a set of namespace bindings used to interpret CURIEs within the triple. Defaults to the namespace bindings defined on the {@link jQuery.rdf#databank}. - * @param {String|jQuery.uri} [options.base] The base URI used to interpret any relative URIs used within the triple. Defaults to the base URI defined on the {@link jQuery.rdf#databank}. - * @returns {jQuery.rdf} This {@link jQuery.rdf} object. - * @example - * var rdf = $.rdf() - * .prefix('dc', ns.dc) - * .prefix('foaf', ns.foaf) - * .add('<photo1.jpg> dc:creator <http://www.blogger.com/profile/1109404> .') - * .add('<http://www.blogger.com/profile/1109404> foaf:img <photo1.jpg> .'); - * @example - * var rdfA = $.rdf() - * .prefix('dc', ns.dc) - * .add('<photo1.jpg> dc:creator "Jane"'); - * var rdfB = $.rdf() - * .prefix('foaf', ns.foaf) - * .add('<photo1.jpg> foaf:depicts "Jane"'); - * var rdf = rdfA.add(rdfB); - * @see jQuery.rdf.databank#add - */ - add: function (triple, options) { - var query, databank; - if (triple.rdfquery !== undefined) { - if (triple.top) { - databank = this.databank.add(triple.databank); - query = $.rdf({ parent: this.parent, databank: databank }); - return query; - } else if (this.top) { - databank = triple.databank.add(this.databank); - query = $.rdf({ parent: triple.parent, databank: databank }); - return query; - } else if (this.union === undefined) { - query = $.rdf({ union: [this, triple] }); - this.partOf.push(query); - triple.partOf.push(query); - return query; - } else { - this.union.push(triple); - triple.partOf.push(this); - } - } else { - if (typeof triple === 'string') { - options = $.extend({}, { base: this.base(), namespaces: this.prefix(), source: triple }, options); - triple = $.rdf.pattern(triple, options); - } - if (triple.isFixed()) { - this.databank.add(triple.triple(), options); - } else { - query = this; - this.each(function (i, data) { - var t = triple.triple(data); - if (t !== null) { - query.databank.add(t, options); - } - }); - } - } - return this; - }, - - /** - * Removes a triple or several triples from the {@link jQuery.rdf#databank}. - * @param {String|jQuery.rdf.triple|jQuery.rdf.pattern} triple The triple to be removed, or a {@link jQuery.rdf.pattern} that matches the triples that should be removed. - * @param {Object} [options] - * @param {Object} [options.namespaces] An object representing a set of namespace bindings used to interpret any CURIEs within the triple or pattern. Defaults to the namespace bindings defined on the {@link jQuery.rdf#databank}. - * @param {String|jQuery.uri} [options.base] The base URI used to interpret any relative URIs used within the triple or pattern. Defaults to the base URI defined on the {@link jQuery.rdf#databank}. - * @returns {jQuery.rdf} The {@link jQuery.rdf} object itself. - * @example - * var rdf = $('html').rdf() - * .prefix('foaf', ns.foaf) - * .where('?person foaf:givenname ?gname') - * .where('?person foaf:family_name ?fname') - * .remove('?person foaf:family_name ?fname'); - * @see jQuery.rdf.databank#remove - */ - remove: function (triple, options) { - if (typeof triple === 'string') { - options = $.extend({}, { base: this.base(), namespaces: this.prefix() }, options); - triple = $.rdf.pattern(triple, options); - } - if (triple.isFixed()) { - this.databank.remove(triple.triple(), options); - } else { - query = this; - this.each(function (i, data) { - var t = triple.triple(data); - if (t !== null) { - query.databank.remove(t, options); - } - }); - } - return this; - }, - - /** - * Loads some data into the {@link jQuery.rdf#databank} - * @param data - * @param {Object} [options] - * @see jQuery.rdf.databank#load - */ - load: function (data, options) { - this.databank.load(data, options); - return this; - }, - - /** - * Creates a new {@link jQuery.rdf} object whose databank contains all the triples in this object's databank except for those in the argument's databank. - * @param {jQuery.rdf} query - * @see jQuery.rdf.databank#except - */ - except: function (query) { - return $.rdf({ databank: this.databank.except(query.databank) }); - }, - - /** - * Creates a new {@link jQuery.rdf} object that is the result of filtering the matches on this {@link jQuery.rdf} object based on the filter that's passed into it. - * @param {String|jQuery.rdf.pattern} filter An expression that filters the triples in the {@link jQuery.rdf#databank} to locate matches based on the matches on this {@link jQuery.rdf} object. If it's a string, the filter is parsed as a {@link jQuery.rdf.pattern}. - * @param {Object} [options] - * @param {Object} [options.namespaces] An object representing a set of namespace bindings used to interpret any CURIEs within the pattern. Defaults to the namespace bindings defined on the {@link jQuery.rdf#databank}. - * @param {String|jQuery.uri} [options.base] The base URI used to interpret any relative URIs used within the pattern. Defaults to the base URI defined on the {@link jQuery.rdf#databank}. - * @param {boolean} [options.optional] Not usually used (use {@link jQuery.rdf#optional} instead). - * @returns {jQuery.rdf} A new {@link jQuery.rdf} object whose {@link jQuery.rdf#parent} is this {@link jQuery.rdf}. - * @see jQuery.rdf#optional - * @see jQuery.rdf#filter - * @see jQuery.rdf#about - * @example - * var rdf = $.rdf() - * .prefix('foaf', ns.foaf) - * .add('_:a foaf:givenname "Alice" .') - * .add('_:a foaf:family_name "Hacker" .') - * .add('_:b foaf:givenname "Bob" .') - * .add('_:b foaf:family_name "Hacker" .') - * .where('?person foaf:family_name "Hacker"') - * .where('?person foaf:givenname "Bob"); - */ - where: function (filter, options) { - var query, base, namespaces, optional; - options = options || {}; - if (typeof filter === 'string') { - base = options.base || this.base(); - namespaces = $.extend({}, this.prefix(), options.namespaces || {}); - optional = options.optional || false; - filter = $.rdf.pattern(filter, { namespaces: namespaces, base: base, optional: optional }); - } - query = $.rdf($.extend({}, options, { parent: this, filter: filter })); - this.children.push(query); - return query; - }, - - /** - * Creates a new {@link jQuery.rdf} object whose set of bindings might optionally include those based on the filter pattern. - * @param {String|jQuery.rdf.pattern} filter An pattern for a set of bindings that might be added to those in this {@link jQuery.rdf} object. - * @param {Object} [options] - * @param {Object} [options.namespaces] An object representing a set of namespace bindings used to interpret any CURIEs within the pattern. Defaults to the namespace bindings defined on the {@link jQuery.rdf#databank}. - * @param {String|jQuery.uri} [options.base] The base URI used to interpret any relative URIs used within the pattern. Defaults to the base URI defined on the {@link jQuery.rdf#databank}. - * @returns {jQuery.rdf} A new {@link jQuery.rdf} object whose {@link jQuery.rdf#parent} is this {@link jQuery.rdf}. - * @see jQuery.rdf#where - * @see jQuery.rdf#filter - * @see jQuery.rdf#about - * @example - * var rdf = $.rdf() - * .prefix('foaf', 'http://xmlns.com/foaf/0.1/') - * .prefix('rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#') - * .add('_:a rdf:type foaf:Person .') - * .add('_:a foaf:name "Alice" .') - * .add('_:a foaf:mbox <mailto:alice@example.com> .') - * .add('_:a foaf:mbox <mailto:alice@work.example> .') - * .add('_:b rdf:type foaf:Person .') - * .add('_:b foaf:name "Bob" .') - * .where('?x foaf:name ?name') - * .optional('?x foaf:mbox ?mbox'); - */ - optional: function (filter, options) { - return this.where(filter, $.extend({}, options || {}, { optional: true })); - }, - - /** - * Creates a new {@link jQuery.rdf} object whose set of bindings includeproperty
and value
for every triple that is about the specified resource.
- * @param {String|jQuery.rdf.resource} resource The subject of the matching triples.
- * @param {Object} [options]
- * @param {Object} [options.namespaces] An object representing a set of namespace bindings used to interpret the resource if it's a CURIE. Defaults to the namespace bindings defined on the {@link jQuery.rdf#databank}.
- * @param {String|jQuery.uri} [options.base] The base URI used to interpret the resource if it's a relative URI (wrapped in <
and >
). Defaults to the base URI defined on the {@link jQuery.rdf#databank}.
- * @returns {jQuery.rdf} A new {@link jQuery.rdf} object whose {@link jQuery.rdf#parent} is this {@link jQuery.rdf}.
- * @see jQuery.rdf#where
- * @see jQuery.rdf#optional
- * @see jQuery.rdf#filter
- * @example
- * var rdf = $.rdf()
- * .prefix('dc', ns.dc)
- * .prefix('foaf', ns.foaf)
- * .add('<photo1.jpg> dc:creator <http://www.blogger.com/profile/1109404> .')
- * .add('<http://www.blogger.com/profile/1109404> foaf:img <photo1.jpg> .')
- * .add('<photo2.jpg> dc:creator <http://www.blogger.com/profile/1109404> .')
- * .add('<http://www.blogger.com/profile/1109404> foaf:img <photo2.jpg> .')
- * .about('<http://www.blogger.com/profile/1109404>');
- */
- about: function (resource, options) {
- return this.where(resource + ' ?property ?value', options);
- },
-
- /**
- * Creates a new {@link jQuery.rdf} object whose set of bindings include only those that satisfy some arbitrary condition. There are two main ways to call this method: with two arguments in which case the first is a binding to be tested and the second represents a condition on the test, or with one argument which is a function that should return true for acceptable bindings.
- * @param {Function|String} property In the two-argument version, this is the name of a property to be tested against the condition specified in the second argument. In the one-argument version, this is a function in which this
is an object whose properties are a set of {@link jQuery.rdf.resource}, {@link jQuery.rdf.literal} or {@link jQuery.rdf.blank} objects and whose arguments are:
this
)?
) are taken as variable names; each matching resource is described by the function.
- * @returns {jQuery} A {@link jQuery} object that contains {@link jQuery.rdf.triple}s that describe the listed resources.
- * @see jQuery.rdf.databank#describe
- * @example
- * $.rdf.dump($('html').rdf().describe(['this
is set to the object representing the variable bindings. The function can take up to three parameters:
- * this
.this
is set to the object representing the variable bindings. The function can take up to three parameters and should return some kind of value:
- * this
.mime type | description |
---|---|
application/json |
- * An RDF/JSON object | - *
application/rdf+xml |
- * An DOMDocument node holding XML in RDF/XML syntax | - *
Creates a new jQuery.rdf.databank object. This should be invoked as a method rather than constructed using new; indeed you will not usually want to generate these objects directly, but manipulate them through a {@link jQuery.rdf} object.
- * @class Represents a triplestore, holding a bunch of {@link jQuery.rdf.triple}s. - * @param {(String|jQuery.rdf.triple)[]} [triples=[]] An array of triples to store in the databank. - * @param {Object} [options] Initialisation of the databank. - * @param {Object} [options.namespaces] An object representing a set of namespace bindings used when interpreting the CURIEs in strings representing triples. Rather than passing this in when you construct the {@link jQuery.rdf.databank} instance, you will usually want to use the {@link jQuery.rdf.databank#prefix} method. - * @param {String|jQuery.uri} [options.base] The base URI used to interpret any relative URIs used within the strings representing triples. - * @returns {jQuery.rdf.databank} The newly-created databank. - * @see jQuery.rdf - */ - $.rdf.databank = function (triples, options) { - return new $.rdf.databank.fn.init(triples, options); - }; - - $.rdf.databank.fn = $.rdf.databank.prototype = { - init: function (triples, options) { - var i; - triples = triples || []; - options = options || {}; - this.id = databankID(); - if (options.union === undefined) { - this.queries = {}; - this.tripleStore = {}; - this.objectStore = {}; - this.baseURI = options.base || $.uri.base(); - this.namespaces = $.extend({}, options.namespaces || {}); - for (i = 0; i < triples.length; i += 1) { - this.add(triples[i]); - } - } else { - this.union = options.union; - } - return this; - }, - - /** - * Sets or returns the base URI of the {@link jQuery.rdf.databank}. - * @param {String|jQuery.uri} [base] - * @returns A {@link jQuery.uri} if no base URI is specified, otherwise returns this {@link jQuery.rdf.databank} object. - * @see jQuery.rdf#base - */ - base: function (base) { - if (this.union === undefined) { - if (base === undefined) { - return this.baseURI; - } else { - this.baseURI = base; - return this; - } - } else if (base === undefined) { - return this.union[0].base(); - } else { - $.each(this.union, function (i, databank) { - databank.base(base); - }); - return this; - } - }, - - /** - * Sets or returns a namespace binding on the {@link jQuery.rdf.databank}. - * @param {String} [prefix] - * @param {String} [namespace] - * @returns {Object|jQuery.uri|jQuery.rdf} If no prefix or namespace is specified, returns an object providing all namespace bindings on the {@link jQuery.rdf#databank}. If a prefix is specified without a namespace, returns the {@link jQuery.uri} associated with that prefix. Otherwise returns this {@link jQuery.rdf} object after setting the namespace binding. - * @see jQuery.rdf#prefix - */ - prefix: function (prefix, uri) { - var namespaces = {}; - if (this.union === undefined) { - if (prefix === undefined) { - return this.namespaces; - } else if (uri === undefined) { - return this.namespaces[prefix]; - } else { - this.namespaces[prefix] = uri; - return this; - } - } else if (uri === undefined) { - $.each(this.union, function (i, databank) { - $.extend(namespaces, databank.prefix()); - }); - if (prefix === undefined) { - return namespaces; - } else { - return namespaces[prefix]; - } - } else { - $.each(this.union, function (i, databank) { - databank.prefix(prefix, uri); - }); - return this; - } - }, - - /** - * Adds a triple to the {@link jQuery.rdf.databank} or another {@link jQuery.rdf.databank} object to create a union. - * @param {String|jQuery.rdf.triple|jQuery.rdf.databank} triple The triple or {@link jQuery.rdf.databank} object to be added to this one. If the triple is a {@link jQuery.rdf.databank} object, the two databanks are unioned together. If the triple is a string, it's parsed as a {@link jQuery.rdf.triple}. - * @param {Object} [options] - * @param {Object} [options.namespaces] An object representing a set of namespace bindings used to interpret CURIEs within the triple. Defaults to the namespace bindings defined on the {@link jQuery.rdf.databank}. - * @param {String|jQuery.uri} [options.base] The base URI used to interpret any relative URIs used within the triple. Defaults to the base URI defined on the {@link jQuery.rdf.databank}. - * @returns {jQuery.rdf.databank} This {@link jQuery.rdf.databank} object. - * @see jQuery.rdf#add - */ - add: function (triple, options) { - var base = (options && options.base) || this.base(), - namespaces = $.extend({}, this.prefix(), (options && options.namespaces) || {}), - databank; - if (triple === this) { - return this; - } else if (triple.tripleStore !== undefined) { - // merging two databanks - if (this.union === undefined) { - databank = $.rdf.databank(undefined, { union: [this, triple] }); - return databank; - } else { - this.union.push(triple); - return this; - } - } else { - if (typeof triple === 'string') { - triple = $.rdf.triple(triple, { namespaces: namespaces, base: base, source: triple }); - } - if (this.union === undefined) { - if (this.tripleStore[triple.subject] === undefined) { - this.tripleStore[triple.subject] = []; - } - if ($.inArray(triple, this.tripleStore[triple.subject]) === -1) { - this.tripleStore[triple.subject].push(triple); - if (triple.object.type === 'uri' || triple.object.type === 'bnode') { - if (this.objectStore[triple.object] === undefined) { - this.objectStore[triple.object] = []; - } - this.objectStore[triple.object].push(triple); - } - addToDatabankQueries(this, triple); - } - } else { - $.each(this.union, function (i, databank) { - databank.add(triple); - }); - } - return this; - } - }, - - /** - * Removes a triple from the {@link jQuery.rdf.databank}. - * @param {String|jQuery.rdf.triple} triple The triple to be removed. - * @param {Object} [options] - * @param {Object} [options.namespaces] An object representing a set of namespace bindings used to interpret any CURIEs within the triple. Defaults to the namespace bindings defined on the {@link jQuery.rdf.databank}. - * @param {String|jQuery.uri} [options.base] The base URI used to interpret any relative URIs used within the triple. Defaults to the base URI defined on the {@link jQuery.rdf.databank}. - * @returns {jQuery.rdf.databank} The {@link jQuery.rdf.databank} object itself. - * @see jQuery.rdf#remove - */ - remove: function (triple, options) { - var base = (options && options.base) || this.base(), - namespaces = $.extend({}, this.prefix(), (options && options.namespaces) || {}), - striples, otriples, - databank; - if (typeof triple === 'string') { - triple = $.rdf.triple(triple, { namespaces: namespaces, base: base, source: triple }); - } - striples = this.tripleStore[triple.subject]; - if (striples !== undefined) { - striples.splice($.inArray(triple, striples), 1); - } - if (triple.object.type === 'uri' || triple.object.type === 'bnode') { - otriples = this.objectStore[triple.object]; - if (otriples !== undefined) { - otriples.splice($.inArray(triple, otriples), 1); - } - } - removeFromDatabankQueries(this, triple); - return this; - }, - - /** - * Creates a new databank containing all the triples in this {@link jQuery.rdf.databank} except those in the {@link jQuery.rdf.databank} passed as the argument. - * @param {jQuery.rdf.databank} data The other {@link jQuery.rdf.databank} - * @returns {jQuery.rdf.databank} A new {@link jQuery.rdf.databank} containing the triples in this {@link jQuery.rdf.databank} except for those in the data parameter. - * @example - * var old = $('html').rdf().databank; - * ...some processing occurs... - * var new = $('html').rdf().databank; - * var added = new.except(old); - * var removed = old.except(new); - */ - except: function (data) { - var store = data.tripleStore, - diff = []; - $.each(this.tripleStore, function (s, ts) { - var ots = store[s]; - if (ots === undefined) { - diff = diff.concat(ts); - } else { - $.each(ts, function (i, t) { - if ($.inArray(t, ots) === -1) { - diff.push(t); - } - }); - } - }); - return $.rdf.databank(diff); - }, - - /** - * Provides a {@link jQuery} object containing the triples held in this {@link jQuery.rdf.databank}. - * @returns {jQuery} A {@link jQuery} object containing {@link jQuery.rdf.triple} objects. - */ - triples: function () { - var triples = []; - if (this.union === undefined) { - $.each(this.tripleStore, function (s, t) { - triples = triples.concat(t); - }); - } else { - $.each(this.union, function (i, databank) { - triples = triples.concat(databank.triples().get()); - }); - triples = $.unique(triples); - } - return $(triples); - }, - - /** - * Tells you how many triples the databank contains. - * @returns {Integer} The number of triples in the {@link jQuery.rdf.databank}. - * @example $('html').rdf().databank.size(); - */ - size: function () { - return this.triples().length; - }, - - /** - * Provides simple concise bounded descriptions of the resources that are passed in the argument. This mirrors the DESCRIBE form in SPARQL. - * @param {(String|jQuery.rdf.resource)[]} resources An array that can contain strings, {@link jQuery.rdf.resource}s or a mixture of the two. - * @returns {jQuery} A {@link jQuery} object holding the {@link jQuery.rdf.triple}s that describe the listed resources. - * @see jQuery.rdf#describe - */ - describe: function (resources) { - var i, r, t, rhash = {}, triples = []; - while (resources.length > 0) { - r = resources.pop(); - if (rhash[r] === undefined) { - if (r.value === undefined) { - r = $.rdf.resource(r); - } - if (this.tripleStore[r] !== undefined) { - for (i = 0; i < this.tripleStore[r].length; i += 1) { - t = this.tripleStore[r][i]; - triples.push(t); - if (t.object.type === 'bnode') { - resources.push(t.object); - } - } - } - if (this.objectStore[r] !== undefined) { - for (i = 0; i < this.objectStore[r].length; i += 1) { - t = this.objectStore[r][i]; - triples.push(t); - if (t.subject.type === 'bnode') { - resources.push(t.subject); - } - } - } - rhash[r] = true; - } - } - return $.unique(triples); - }, - - /** - * Dumps the triples in the databank into a format that can be shown to the user or sent to a server. - * @param {Object} [options] Options that control the formatting of the triples. See {@link jQuery.rdf.dump} for details. - * @returns {Object|Node|String} - * @see jQuery.rdf.dump - */ - dump: function (options) { - options = $.extend({ namespaces: this.namespaces, base: this.base }, options || {}); - return $.rdf.dump(this.triples(), options); - }, - - /** - * Loads some data into the databank. - * @param {Node|Object} data If the data is a node, it's interpreted to be an RDF/XML syntax document and will be parsed as such. Otherwise, it's taken to be a RDF/JSON object. The data cannot be a string; it must be parsed before it is passed to this function. - * @returns {jQuery.rdf.databank} The {@link jQuery.rdf.databank} itself. - * @see jQuery.rdf#load - */ - load: function (data) { - var i, triples; - if (data.ownerDocument !== undefined) { - triples = parseRdfXml(data); - } else { - triples = parseJson(data); - } - for (i = 0; i < triples.length; i += 1) { - this.add(triples[i]); - } - return this; - }, - - /** - * Provides a string representation of the databank which simply specifies how many triples it contains. - * @returns {String} - */ - toString: function () { - return '[Databank with ' + this.size() + ' triples]'; - } - }; - - $.rdf.databank.fn.init.prototype = $.rdf.databank.fn; - - /** - *Creates a new jQuery.rdf.pattern object. This should be invoked as a method rather than constructed using new; indeed you will not usually want to generate these objects directly, since they are automatically created from strings where necessary, such as by {@link jQuery.rdf#where}.
- * @class Represents a pattern that may or may not match a given {@link jQuery.rdf.triple}. - * @param {String|jQuery.rdf.resource|jQuery.rdf.blank} subject The subject pattern, or a single string that defines the entire pattern. If the subject is specified as a string, it can be a fixed resource (<uri>
or curie
), a blank node (_:id
) or a variable placeholder (?name
).
- * @param {String|jQuery.rdf.resource} [property] The property pattern. If the property is specified as a string, it can be a fixed resource (<uri>
or curie
) or a variable placeholder (?name
).
- * @param {String|jQuery.rdf.resource|jQuery.rdf.blank|jQuery.rdf.literal} [value] The value pattern. If the property is specified as a string, it can be a fixed resource (<uri>
or curie
), a blank node (_:id
), a literal ("value"
) or a variable placeholder (?name
).
- * @param {Object} [options] Initialisation of the pattern.
- * @param {Object} [options.namespaces] An object representing a set of namespace bindings used when interpreting the CURIEs in the subject, property and object.
- * @param {String|jQuery.uri} [options.base] The base URI used to interpret any relative URIs used within the subject, property and object.
- * @param {boolean} [options.optional]
- * @returns {jQuery.rdf.pattern} The newly-created pattern.
- * @throws {String} Errors if any of the strings are not in a recognised format.
- * @example pattern = $.rdf.pattern('?person', $.rdf.type, 'foaf:Person', { namespaces: { foaf: "http://xmlns.com/foaf/0.1/" }});
- * @example
- * pattern = $.rdf.pattern('?person a foaf:Person', {
- * namespaces: { foaf: "http://xmlns.com/foaf/0.1/" },
- * optional: true
- * });
- * @see jQuery.rdf#where
- * @see jQuery.rdf.resource
- * @see jQuery.rdf.blank
- * @see jQuery.rdf.literal
- */
- $.rdf.pattern = function (subject, property, object, options) {
- var pattern, m, optional;
- // using a two-argument version; first argument is a Turtle statement string
- if (object === undefined) {
- options = property || {};
- m = $.trim(subject).match(tripleRegex);
- if (m.length === 3 || (m.length === 4 && m[3] === '.')) {
- subject = m[0];
- property = m[1];
- object = m[2];
- } else {
- throw "Bad Pattern: Couldn't parse string " + subject;
- }
- optional = (options.optional === undefined) ? $.rdf.pattern.defaults.optional : options.optional;
- }
- if (memPattern[subject] &&
- memPattern[subject][property] &&
- memPattern[subject][property][object] &&
- memPattern[subject][property][object][optional]) {
- return memPattern[subject][property][object][optional];
- }
- pattern = new $.rdf.pattern.fn.init(subject, property, object, options);
- if (memPattern[pattern.subject] &&
- memPattern[pattern.subject][pattern.property] &&
- memPattern[pattern.subject][pattern.property][pattern.object] &&
- memPattern[pattern.subject][pattern.property][pattern.object][pattern.optional]) {
- return memPattern[pattern.subject][pattern.property][pattern.object][pattern.optional];
- } else {
- if (memPattern[pattern.subject] === undefined) {
- memPattern[pattern.subject] = {};
- }
- if (memPattern[pattern.subject][pattern.property] === undefined) {
- memPattern[pattern.subject][pattern.property] = {};
- }
- if (memPattern[pattern.subject][pattern.property][pattern.object] === undefined) {
- memPattern[pattern.subject][pattern.property][pattern.object] = {};
- }
- memPattern[pattern.subject][pattern.property][pattern.object][pattern.optional] = pattern;
- return pattern;
- }
- };
-
- $.rdf.pattern.fn = $.rdf.pattern.prototype = {
- init: function (s, p, o, options) {
- var opts = $.extend({}, $.rdf.pattern.defaults, options);
- /**
- * The placeholder for the subject of triples matching against this pattern.
- * @type String|jQuery.rdf.resource|jQuery.rdf.blank
- */
- this.subject = s.toString().substring(0, 1) === '?' ? s : subject(s, opts);
- /**
- * The placeholder for the property of triples matching against this pattern.
- * @type String|jQuery.rdf.resource
- */
- this.property = p.toString().substring(0, 1) === '?' ? p : property(p, opts);
- /**
- * The placeholder for the object of triples matching against this pattern.
- * @type String|jQuery.rdf.resource|jQuery.rdf.blank|jQuery.rdf.literal
- */
- this.object = o.toString().substring(0, 1) === '?' ? o : object(o, opts);
- /**
- * Whether the pattern should only optionally match against the triple
- * @type boolean
- */
- this.optional = opts.optional;
- return this;
- },
-
- /**
- * Creates a new {@link jQuery.rdf.pattern} with any variable placeholders within this one's subject, property or object filled in with values from the bindings passed as the argument.
- * @param {Object} bindings An object holding the variable bindings to be used to replace any placeholders in the pattern. These bindings are of the type held by the {@link jQuery.rdf} object.
- * @returns {jQuery.rdf.pattern} A new {@link jQuery.rdf.pattern} object.
- * @example
- * pattern = $.rdf.pattern('?thing a ?class');
- * // pattern2 matches all triples that indicate the classes of this page.
- * pattern2 = pattern.fill({ thing: $.rdf.resource('<>') });
- */
- fill: function (bindings) {
- var s = this.subject,
- p = this.property,
- o = this.object;
- if (typeof s === 'string' && bindings[s.substring(1)]) {
- s = bindings[s.substring(1)];
- }
- if (typeof p === 'string' && bindings[p.substring(1)]) {
- p = bindings[p.substring(1)];
- }
- if (typeof o === 'string' && bindings[o.substring(1)]) {
- o = bindings[o.substring(1)];
- }
- return $.rdf.pattern(s, p, o, { optional: this.optional });
- },
-
- /**
- * Creates a new Object holding variable bindings by matching the passed triple against this pattern.
- * @param {jQuery.rdf.triple} triple A {@link jQuery.rdf.triple} for this pattern to match against.
- * @returns {null|Object} An object containing the bindings of variables (as specified in this pattern) to values (as specified in the triple), or null
if the triple doesn't match the pattern.
- * pattern = $.rdf.pattern('?thing a ?class');
- * bindings = pattern.exec($.rdf.triple('<> a foaf:Person', { namespaces: ns }));
- * thing = bindings.thing; // the resource for this page
- * class = bindings.class; // a resource for foaf:Person
- */
- exec: function (triple) {
- var binding = {};
- binding = testResource(triple.subject, this.subject, binding);
- if (binding === null) {
- return null;
- }
- binding = testResource(triple.property, this.property, binding);
- if (binding === null) {
- return null;
- }
- binding = testResource(triple.object, this.object, binding);
- return binding;
- },
-
- /**
- * Tests whether this pattern has any variable placeholders in it or not.
- * @returns {boolean} True if the pattern doesn't contain any variable placeholders.
- * @example
- * $.rdf.pattern('?thing a ?class').isFixed(); // false
- * $.rdf.pattern('<> a foaf:Person', { namespaces: ns }).isFixed(); // true
- */
- isFixed: function () {
- return typeof this.subject !== 'string' &&
- typeof this.property !== 'string' &&
- typeof this.object !== 'string';
- },
-
- /**
- * Creates a new triple based on the bindings passed to the pattern, if possible.
- * @param {Object} bindings An object holding the variable bindings to be used to replace any placeholders in the pattern. These bindings are of the type held by the {@link jQuery.rdf} object.
- * @returns {null|jQuery.rdf.triple} A new {@link jQuery.rdf.triple} object, or null if not all the variable placeholders in the pattern are specified in the bindings. The {@link jQuery.rdf.triple#source} of the generated triple is set to the string value of this pattern.
- * @example
- * pattern = $.rdf.pattern('?thing a ?class');
- * // triple is a new triple '<> a foaf:Person'
- * triple = pattern.triple({
- * thing: $.rdf.resource('<>'),
- * class: $.rdf.resource('foaf:Person', { namespaces: ns })
- * });
- */
- triple: function (bindings) {
- var t = this;
- if (!this.isFixed()) {
- t = this.fill(bindings);
- }
- if (t.isFixed()) {
- return $.rdf.triple(t.subject, t.property, t.object, { source: this.toString() });
- } else {
- return null;
- }
- },
-
- /**
- * Returns a string representation of the pattern by concatenating the subject, property and object.
- * @returns {String}
- */
- toString: function () {
- return this.subject + ' ' + this.property + ' ' + this.object;
- }
- };
-
- $.rdf.pattern.fn.init.prototype = $.rdf.pattern.fn;
-
- $.rdf.pattern.defaults = {
- base: $.uri.base(),
- namespaces: {},
- optional: false
- };
-
- /**
- * Creates a new jQuery.rdf.triple object. This should be invoked as a method rather than constructed using new; indeed you will not usually want to generate these objects directly, since they are automatically created from strings where necessary, such as by {@link jQuery.rdf#add}.
- * @class Represents an RDF triple. - * @param {String|jQuery.rdf.resource|jQuery.rdf.blank} subject The subject of the triple, or a single string that defines the entire triple. If the subject is specified as a string, it can be a fixed resource (<uri>
or curie
) or a blank node (_:id
).
- * @param {String|jQuery.rdf.resource} [property] The property pattern. If the property is specified as a string, it must be a fixed resource (<uri>
or curie
).
- * @param {String|jQuery.rdf.resource|jQuery.rdf.blank|jQuery.rdf.literal} [value] The value pattern. If the property is specified as a string, it can be a fixed resource (<uri>
or curie
), a blank node (_:id
), or a literal ("value"
).
- * @param {Object} [options] Initialisation of the triple.
- * @param {Object} [options.namespaces] An object representing a set of namespace bindings used when interpreting the CURIEs in the subject, property and object.
- * @param {String|jQuery.uri} [options.base] The base URI used to interpret any relative URIs used within the subject, property and object.
- * @returns {jQuery.rdf.triple} The newly-created triple.
- * @throws {String} Errors if any of the strings are not in a recognised format.
- * @example pattern = $.rdf.triple('<>', $.rdf.type, 'foaf:Person', { namespaces: { foaf: "http://xmlns.com/foaf/0.1/" }});
- * @example
- * pattern = $.rdf.triple('<> a foaf:Person', {
- * namespaces: { foaf: "http://xmlns.com/foaf/0.1/" }
- * });
- * @see jQuery.rdf#add
- * @see jQuery.rdf.resource
- * @see jQuery.rdf.blank
- * @see jQuery.rdf.literal
- */
- $.rdf.triple = function (subject, property, object, options) {
- var triple, graph, m;
- // using a two-argument version; first argument is a Turtle statement string
- if (object === undefined) {
- options = property;
- m = $.trim(subject).match(tripleRegex);
- if (m.length === 3 || (m.length === 4 && m[3] === '.')) {
- subject = m[0];
- property = m[1];
- object = m[2];
- } else {
- throw "Bad Triple: Couldn't parse string " + subject;
- }
- }
- graph = (options && options.graph) || '';
- if (memTriple[graph] &&
- memTriple[graph][subject] &&
- memTriple[graph][subject][property] &&
- memTriple[graph][subject][property][object]) {
- return memTriple[graph][subject][property][object];
- }
- triple = new $.rdf.triple.fn.init(subject, property, object, options);
- graph = triple.graph || '';
- if (memTriple[graph] &&
- memTriple[graph][triple.subject] &&
- memTriple[graph][triple.subject][triple.property] &&
- memTriple[graph][triple.subject][triple.property][triple.object]) {
- return memTriple[graph][triple.subject][triple.property][triple.object];
- } else {
- if (memTriple[graph] === undefined) {
- memTriple[graph] = {};
- }
- if (memTriple[graph][triple.subject] === undefined) {
- memTriple[graph][triple.subject] = {};
- }
- if (memTriple[graph][triple.subject][triple.property] === undefined) {
- memTriple[graph][triple.subject][triple.property] = {};
- }
- memTriple[graph][triple.subject][triple.property][triple.object] = triple;
- return triple;
- }
- };
-
- $.rdf.triple.fn = $.rdf.triple.prototype = {
- init: function (s, p, o, options) {
- var opts;
- opts = $.extend({}, $.rdf.triple.defaults, options);
- /**
- * The subject of the triple.
- * @type jQuery.rdf.resource|jQuery.rdf.blank
- */
- this.subject = subject(s, opts);
- /**
- * The property of the triple.
- * @type jQuery.rdf.resource
- */
- this.property = property(p, opts);
- /**
- * The object of the triple.
- * @type jQuery.rdf.resource|jQuery.rdf.blank|jQuery.rdf.literal
- */
- this.object = object(o, opts);
- /**
- * (Experimental) The named graph the triple belongs to.
- * @type jQuery.rdf.resource|jQuery.rdf.blank
- */
- this.graph = opts.graph === undefined ? undefined : subject(opts.graph, opts);
- /**
- * The source of the triple, which might be a node within the page (if the RDF is generated from the page) or a string holding the pattern that generated the triple.
- */
- this.source = opts.source;
- return this;
- },
-
- /**
- * Always returns true for triples.
- * @see jQuery.rdf.pattern#isFixed
- */
- isFixed: function () {
- return true;
- },
-
- /**
- * Always returns this triple.
- * @see jQuery.rdf.pattern#triple
- */
- triple: function (bindings) {
- return this;
- },
-
- /**
- * Returns a RDF/JSON representation of this triple.
- * @returns {Object}
- */
- dump: function () {
- var e = {},
- s = this.subject.value.toString(),
- p = this.property.value.toString();
- e[s] = {};
- e[s][p] = this.object.dump();
- return e;
- },
-
- /**
- * Returns a string representing this triple in Turtle format.
- * @returns {String}
- */
- toString: function () {
- return this.subject + ' ' + this.property + ' ' + this.object + ' .';
- }
- };
-
- $.rdf.triple.fn.init.prototype = $.rdf.triple.fn;
-
- $.rdf.triple.defaults = {
- base: $.uri.base(),
- source: [document],
- namespaces: {}
- };
-
- /**
- * Creates a new jQuery.rdf.resource object. This should be invoked as a method rather than constructed using new; indeed you will not usually want to generate these objects directly, since they are automatically created from strings where necessary, such as by {@link jQuery.rdf#add}.
- * @class Represents an RDF resource. - * @param {String|jQuery.uri} value The value of the resource. If it's a string it must be in the format<uri>
or curie
.
- * @param {Object} [options] Initialisation of the resource.
- * @param {Object} [options.namespaces] An object representing a set of namespace bindings used when interpreting the CURIE specifying the resource.
- * @param {String|jQuery.uri} [options.base] The base URI used to interpret any relative URIs used within the URI specifying the resource.
- * @returns {jQuery.rdf.resource} The newly-created resource.
- * @throws {String} Errors if the string is not in a recognised format.
- * @example thisPage = $.rdf.resource('<>');
- * @example foaf.Person = $.rdf.resource('foaf:Person', { namespaces: ns });
- * @see jQuery.rdf.pattern
- * @see jQuery.rdf.triple
- * @see jQuery.rdf.blank
- * @see jQuery.rdf.literal
- */
- $.rdf.resource = function (value, options) {
- var resource;
- if (memResource[value]) {
- return memResource[value];
- }
- resource = new $.rdf.resource.fn.init(value, options);
- if (memResource[resource]) {
- return memResource[resource];
- } else {
- memResource[resource] = resource;
- return resource;
- }
- };
-
- $.rdf.resource.fn = $.rdf.resource.prototype = {
- /**
- * Always fixed to 'uri' for resources.
- * @type String
- */
- type: 'uri',
- /**
- * The URI for the resource.
- * @type jQuery.rdf.uri
- */
- value: undefined,
-
- init: function (value, options) {
- var m, prefix, uri, opts;
- if (typeof value === 'string') {
- m = uriRegex.exec(value);
- opts = $.extend({}, $.rdf.resource.defaults, options);
- if (m !== null) {
- this.value = $.uri.resolve(m[1].replace(/\\>/g, '>'), opts.base);
- } else if (value.substring(0, 1) === ':') {
- uri = opts.namespaces[''];
- if (uri === undefined) {
- throw "Malformed Resource: No namespace binding for default namespace in " + value;
- } else {
- this.value = $.uri.resolve(uri + value.substring(1));
- }
- } else if (value.substring(value.length - 1) === ':') {
- prefix = value.substring(0, value.length - 1);
- uri = opts.namespaces[prefix];
- if (uri === undefined) {
- throw "Malformed Resource: No namespace binding for prefix " + prefix + " in " + value;
- } else {
- this.value = $.uri.resolve(uri);
- }
- } else {
- try {
- this.value = $.curie(value, { namespaces: opts.namespaces });
- } catch (e) {
- throw "Malformed Resource: Bad format for resource " + e;
- }
- }
- } else {
- this.value = value;
- }
- return this;
- }, // end init
-
- /**
- * Returns a RDF/JSON representation of this triple.
- * @returns {Object}
- */
- dump: function () {
- return {
- type: 'uri',
- value: this.value.toString()
- };
- },
-
- /**
- * Returns a string representing this resource in Turtle format.
- * @returns {String}
- */
- toString: function () {
- return '<' + this.value + '>';
- }
- };
-
- $.rdf.resource.fn.init.prototype = $.rdf.resource.fn;
-
- $.rdf.resource.defaults = {
- base: $.uri.base(),
- namespaces: {}
- };
-
- /**
- * A {@link jQuery.rdf.resource} for rdf:type
- * @constant
- * @type jQuery.rdf.resource
- */
- $.rdf.type = $.rdf.resource('<' + rdfNs + 'type>');
- /**
- * A {@link jQuery.rdf.resource} for rdfs:label
- * @constant
- * @type jQuery.rdf.resource
- */
- $.rdf.label = $.rdf.resource('<' + rdfsNs + 'label>');
- /**
- * A {@link jQuery.rdf.resource} for rdf:first
- * @constant
- * @type jQuery.rdf.resource
- */
- $.rdf.first = $.rdf.resource('<' + rdfNs + 'first>');
- /**
- * A {@link jQuery.rdf.resource} for rdf:rest
- * @constant
- * @type jQuery.rdf.resource
- */
- $.rdf.rest = $.rdf.resource('<' + rdfNs + 'rest>');
- /**
- * A {@link jQuery.rdf.resource} for rdf:nil
- * @constant
- * @type jQuery.rdf.resource
- */
- $.rdf.nil = $.rdf.resource('<' + rdfNs + 'nil>');
- /**
- * A {@link jQuery.rdf.resource} for rdf:subject
- * @constant
- * @type jQuery.rdf.resource
- */
- $.rdf.subject = $.rdf.resource('<' + rdfNs + 'subject>');
- /**
- * A {@link jQuery.rdf.resource} for rdf:property
- * @constant
- * @type jQuery.rdf.resource
- */
- $.rdf.property = $.rdf.resource('<' + rdfNs + 'property>');
- /**
- * A {@link jQuery.rdf.resource} for rdf:object
- * @constant
- * @type jQuery.rdf.resource
- */
- $.rdf.object = $.rdf.resource('<' + rdfNs + 'object>');
-
- /**
- * Creates a new jQuery.rdf.blank object. This should be invoked as a method rather than constructed using new; indeed you will not usually want to generate these objects directly, since they are automatically created from strings where necessary, such as by {@link jQuery.rdf#add}.
- * @class Represents an RDF blank node. - * @param {String} value A representation of the blank node in the format_:id
or []
(which automatically creates a new blank node with a unique ID).
- * @returns {jQuery.rdf.blank} The newly-created blank node.
- * @throws {String} Errors if the string is not in a recognised format.
- * @example newBlank = $.rdf.blank('[]');
- * @example identifiedBlank = $.rdf.blank('_:fred');
- * @see jQuery.rdf.pattern
- * @see jQuery.rdf.triple
- * @see jQuery.rdf.resource
- * @see jQuery.rdf.literal
- */
- $.rdf.blank = function (value) {
- var blank;
- if (memBlank[value]) {
- return memBlank[value];
- }
- blank = new $.rdf.blank.fn.init(value);
- if (memBlank[blank]) {
- return memBlank[blank];
- } else {
- memBlank[blank] = blank;
- return blank;
- }
- };
-
- $.rdf.blank.fn = $.rdf.blank.prototype = {
- /**
- * Always fixed to 'bnode' for blank nodes.
- * @type String
- */
- type: 'bnode',
- /**
- * The value of the blank node in the format _:id
- * @type String
- */
- value: undefined,
- /**
- * The id of the blank node.
- * @type String
- */
- id: undefined,
-
- init: function (value) {
- if (value === '[]') {
- this.id = blankNodeID();
- this.value = '_:' + this.id;
- } else if (value.substring(0, 2) === '_:') {
- this.id = value.substring(2);
- this.value = value;
- } else {
- throw "Malformed Blank Node: " + value + " is not a legal format for a blank node";
- }
- return this;
- },
-
- /**
- * Returns a RDF/JSON representation of this blank node.
- * @returns {Object}
- */
- dump: function () {
- return {
- type: 'bnode',
- value: this.value
- };
- },
-
- /**
- * Returns the value this blank node.
- * @returns {String}
- */
- toString: function () {
- return this.value;
- }
- };
-
- $.rdf.blank.fn.init.prototype = $.rdf.blank.fn;
-
- /**
- * Creates a new jQuery.rdf.literal object. This should be invoked as a method rather than constructed using new; indeed you will not usually want to generate these objects directly, since they are automatically created from strings where necessary, such as by {@link jQuery.rdf#add}.
- * @class Represents an RDF literal. - * @param {String|boolean|Number} value Either the value of the literal or a string representation of it. If the datatype or lang options are specified, the value is taken as given. Otherwise, if it's a Javascript boolean or numeric value, it is interpreted as a value with a xsd:boolean or xsd:double datatype. In all other cases it's interpreted as a literal as defined in Turtle syntax. - * @param {Object} [options] Initialisation options for the literal. - * @param {String} [options.datatype] The datatype for the literal. This should be a safe CURIE; in other words, it can be in the formaturi
or [curie]
. Must not be specified if options.lang is also specified.
- * @param {String} [options.lang] The language for the literal. Must not be specified if options.datatype is also specified.
- * @param {Object} [options.namespaces] An object representing a set of namespace bindings used when interpreting a CURIE in the datatype.
- * @param {String|jQuery.uri} [options.base] The base URI used to interpret a relative URI in the datatype.
- * @returns {jQuery.rdf.literal} The newly-created literal.
- * @throws {String} Errors if the string is not in a recognised format or if both options.datatype and options.lang are specified.
- * @example trueLiteral = $.rdf.literal(true);
- * @example numericLiteral = $.rdf.literal(5);
- * @example dateLiteral = $.rdf.literal('"2009-07-13"^^xsd:date', { namespaces: ns });
- * @see jQuery.rdf.pattern
- * @see jQuery.rdf.triple
- * @see jQuery.rdf.resource
- * @see jQuery.rdf.blank
- */
- $.rdf.literal = function (value, options) {
- var literal;
- if (memLiteral[value]) {
- return memLiteral[value];
- }
- literal = new $.rdf.literal.fn.init(value, options);
- if (memLiteral[literal]) {
- return memLiteral[literal];
- } else {
- memLiteral[literal] = literal;
- return literal;
- }
- };
-
- $.rdf.literal.fn = $.rdf.literal.prototype = {
- /**
- * Always fixed to 'literal' for literals.
- * @type String
- */
- type: 'literal',
- /**
- * The value of the literal as a string.
- * @type String
- */
- value: undefined,
- /**
- * The language of the literal, if it has one; otherwise undefined.
- * @type String
- */
- lang: undefined,
- /**
- * The datatype of the literal, if it has one; otherwise undefined.
- * @type jQuery.uri
- */
- datatype: undefined,
-
- init: function (value, options) {
- var
- m, datatype,
- opts = $.extend({}, $.rdf.literal.defaults, options);
- if (opts.lang !== undefined && opts.datatype !== undefined) {
- throw "Malformed Literal: Cannot define both a language and a datatype for a literal (" + value + ")";
- }
- if (opts.datatype !== undefined) {
- datatype = $.safeCurie(opts.datatype, { namespaces: opts.namespaces });
- $.extend(this, $.typedValue(value.toString(), datatype));
- } else if (opts.lang !== undefined) {
- this.value = value.toString();
- this.lang = opts.lang;
- } else if (typeof value === 'boolean') {
- $.extend(this, $.typedValue(value.toString(), xsdNs + 'boolean'));
- } else if (typeof value === 'number') {
- $.extend(this, $.typedValue(value.toString(), xsdNs + 'double'));
- } else if (value === 'true' || value === 'false') {
- $.extend(this, $.typedValue(value, xsdNs + 'boolean'));
- } else if ($.typedValue.valid(value, xsdNs + 'integer')) {
- $.extend(this, $.typedValue(value, xsdNs + 'integer'));
- } else if ($.typedValue.valid(value, xsdNs + 'decimal')) {
- $.extend(this, $.typedValue(value, xsdNs + 'decimal'));
- } else if ($.typedValue.valid(value, xsdNs + 'double') &&
- !/^\s*([\-\+]?INF|NaN)\s*$/.test(value)) { // INF, -INF and NaN aren't valid literals in Turtle
- $.extend(this, $.typedValue(value, xsdNs + 'double'));
- } else {
- m = literalRegex.exec(value);
- if (m !== null) {
- this.value = (m[2] || m[4]).replace(/\\"/g, '"');
- if (m[9]) {
- datatype = $.rdf.resource(m[9], opts);
- $.extend(this, $.typedValue(this.value, datatype.value));
- } else if (m[7]) {
- this.lang = m[7];
- }
- } else {
- throw "Malformed Literal: Couldn't recognise the value " + value;
- }
- }
- return this;
- }, // end init
-
- /**
- * Returns a RDF/JSON representation of this blank node.
- * @returns {Object}
- */
- dump: function () {
- var e = {
- type: 'literal',
- value: this.value.toString()
- };
- if (this.lang !== undefined) {
- e.lang = this.lang;
- } else if (this.datatype !== undefined) {
- e.datatype = this.datatype.toString();
- }
- return e;
- },
-
- /**
- * Returns a string representing this resource in Turtle format.
- * @returns {String}
- */
- toString: function () {
- var val = '"' + this.value + '"';
- if (this.lang !== undefined) {
- val += '@' + this.lang;
- } else if (this.datatype !== undefined) {
- val += '^^<' + this.datatype + '>';
- }
- return val;
- }
- };
-
- $.rdf.literal.fn.init.prototype = $.rdf.literal.fn;
-
- $.rdf.literal.defaults = {
- base: $.uri.base(),
- namespaces: {},
- datatype: undefined,
- lang: undefined
- };
-
-})(jQuery);
diff --git a/jquery.rdfquery.rdfa-1.0.js b/jquery.rdfquery.rdfa-1.0.js
new file mode 100644
index 0000000..885cd37
--- /dev/null
+++ b/jquery.rdfquery.rdfa-1.0.js
@@ -0,0 +1,4386 @@
+/*
+ * $ URIs @VERSION
+ *
+ * Copyright (c) 2008,2009 Jeni Tennison
+ * Licensed under the MIT (MIT-LICENSE.txt)
+ *
+ */
+/**
+ * @fileOverview $ URIs
+ * @author Jeni Tennison
+ * @copyright (c) 2008,2009 Jeni Tennison
+ * @license MIT license (MIT-LICENSE.txt)
+ * @version 1.0
+ */
+/**
+ * @class
+ * @name jQuery
+ * @exports $ as jQuery
+ * @description rdfQuery is a jQuery plugin. The only fields and methods listed here are those that come as part of the rdfQuery library.
+ */
+(function ($) {
+
+ var
+ mem = {},
+ uriRegex = /^(([a-z][\-a-z0-9+\.]*):)?(\/\/([^\/?#]+))?([^?#]*)?(\?([^#]*))?(#(.*))?$/i,
+ docURI,
+
+ parseURI = function (u) {
+ var m = u.match(uriRegex);
+ if (m === null) {
+ throw "Malformed URI: " + u;
+ }
+ return {
+ scheme: m[1] ? m[2].toLowerCase() : undefined,
+ authority: m[3] ? m[4] : undefined,
+ path: m[5] || '',
+ query: m[6] ? m[7] : undefined,
+ fragment: m[8] ? m[9] : undefined
+ };
+ },
+
+ removeDotSegments = function (u) {
+ var r = '', m = [];
+ if (/\./.test(u)) {
+ while (u !== undefined && u !== '') {
+ if (u === '.' || u === '..') {
+ u = '';
+ } else if (/^\.\.\//.test(u)) { // starts with ../
+ u = u.substring(3);
+ } else if (/^\.\//.test(u)) { // starts with ./
+ u = u.substring(2);
+ } else if (/^\/\.(\/|$)/.test(u)) { // starts with /./ or consists of /.
+ u = '/' + u.substring(3);
+ } else if (/^\/\.\.(\/|$)/.test(u)) { // starts with /../ or consists of /..
+ u = '/' + u.substring(4);
+ r = r.replace(/\/?[^\/]+$/, '');
+ } else {
+ m = u.match(/^(\/?[^\/]*)(\/.*)?$/);
+ u = m[2];
+ r = r + m[1];
+ }
+ }
+ return r;
+ } else {
+ return u;
+ }
+ },
+
+ merge = function (b, r) {
+ if (b.authority !== '' && (b.path === undefined || b.path === '')) {
+ return '/' + r;
+ } else {
+ return b.path.replace(/[^\/]+$/, '') + r;
+ }
+ };
+
+ /**
+ * Creates a new jQuery.uri object. This should be invoked as a method rather than constructed using new.
+ * @class Represents a URI
+ * @param {String} [relative='']
+ * @param {String|jQuery.uri} [base] Defaults to the base URI of the page
+ * @returns {jQuery.uri} The new jQuery.uri object.
+ * @example uri = jQuery.uri('/my/file.html');
+ */
+ $.uri = function (relative, base) {
+ var uri;
+ relative = relative || '';
+ if (mem[relative]) {
+ return mem[relative];
+ }
+ base = base || $.uri.base();
+ if (typeof base === 'string') {
+ base = $.uri.absolute(base);
+ }
+ uri = new $.uri.fn.init(relative, base);
+ if (mem[uri]) {
+ return mem[uri];
+ } else {
+ mem[uri] = uri;
+ return uri;
+ }
+ };
+
+ $.uri.fn = $.uri.prototype = {
+ /**
+ * The scheme used in the URI
+ * @type String
+ */
+ scheme: undefined,
+ /**
+ * The authority used in the URI
+ * @type String
+ */
+ authority: undefined,
+ /**
+ * The path used in the URI
+ * @type String
+ */
+ path: undefined,
+ /**
+ * The query part of the URI
+ * @type String
+ */
+ query: undefined,
+ /**
+ * The fragment part of the URI
+ * @type String
+ */
+ fragment: undefined,
+
+ init: function (relative, base) {
+ var r = {};
+ base = base || {};
+ $.extend(this, parseURI(relative));
+ if (this.scheme === undefined) {
+ this.scheme = base.scheme;
+ if (this.authority !== undefined) {
+ this.path = removeDotSegments(this.path);
+ } else {
+ this.authority = base.authority;
+ if (this.path === '') {
+ this.path = base.path;
+ if (this.query === undefined) {
+ this.query = base.query;
+ }
+ } else {
+ if (!/^\//.test(this.path)) {
+ this.path = merge(base, this.path);
+ }
+ this.path = removeDotSegments(this.path);
+ }
+ }
+ }
+ if (this.scheme === undefined) {
+ throw "Malformed URI: URI is not an absolute URI and no base supplied: " + relative;
+ }
+ return this;
+ },
+
+ /**
+ * Resolves a relative URI relative to this URI
+ * @param {String} relative
+ * @returns jQuery.uri
+ */
+ resolve: function (relative) {
+ return $.uri(relative, this);
+ },
+
+ /**
+ * Creates a relative URI giving the path from this URI to the absolute URI passed as a parameter
+ * @param {String|jQuery.uri} absolute
+ * @returns String
+ */
+ relative: function (absolute) {
+ var aPath, bPath, i = 0, j, resultPath = [], result = '';
+ if (typeof absolute === 'string') {
+ absolute = $.uri(absolute, {});
+ }
+ if (absolute.scheme !== this.scheme ||
+ absolute.authority !== this.authority) {
+ return absolute.toString();
+ }
+ if (absolute.path !== this.path) {
+ aPath = absolute.path.split('/');
+ bPath = this.path.split('/');
+ if (aPath[1] !== bPath[1]) {
+ result = absolute.path;
+ } else {
+ while (aPath[i] === bPath[i]) {
+ i += 1;
+ }
+ j = i;
+ for (; i < bPath.length - 1; i += 1) {
+ resultPath.push('..');
+ }
+ for (; j < aPath.length; j += 1) {
+ resultPath.push(aPath[j]);
+ }
+ result = resultPath.join('/');
+ }
+ result = absolute.query === undefined ? result : result + '?' + absolute.query;
+ result = absolute.fragment === undefined ? result : result + '#' + absolute.fragment;
+ return result;
+ }
+ if (absolute.query !== undefined && absolute.query !== this.query) {
+ return '?' + absolute.query + (absolute.fragment === undefined ? '' : '#' + absolute.fragment);
+ }
+ if (absolute.fragment !== undefined && absolute.fragment !== this.fragment) {
+ return '#' + absolute.fragment;
+ }
+ return '';
+ },
+
+ /**
+ * Returns the URI as an absolute string
+ * @returns String
+ */
+ toString: function () {
+ var result = '';
+ if (this._string) {
+ return this._string;
+ } else {
+ result = this.scheme === undefined ? result : (result + this.scheme + ':');
+ result = this.authority === undefined ? result : (result + '//' + this.authority);
+ result = result + this.path;
+ result = this.query === undefined ? result : (result + '?' + this.query);
+ result = this.fragment === undefined ? result : (result + '#' + this.fragment);
+ this._string = result;
+ return result;
+ }
+ }
+
+ };
+
+ $.uri.fn.init.prototype = $.uri.fn;
+
+ /**
+ * Creates a {@link jQuery.uri} from a known-to-be-absolute URI
+ * @param {String}
+ * @returns {jQuery.uri}
+ */
+ $.uri.absolute = function (uri) {
+ return $.uri(uri, {});
+ };
+
+ /**
+ * Creates a {@link jQuery.uri} from a relative URI and an optional base URI
+ * @returns {jQuery.uri}
+ * @see jQuery.uri
+ */
+ $.uri.resolve = function (relative, base) {
+ return $.uri(relative, base);
+ };
+
+ /**
+ * Creates a string giving the relative path from a base URI to an absolute URI
+ * @param {String} absolute
+ * @param {String} base
+ * @returns {String}
+ */
+ $.uri.relative = function (absolute, base) {
+ return $.uri(base, {}).relative(absolute);
+ };
+
+ /**
+ * Returns the base URI of the page
+ * @returns {jQuery.uri}
+ */
+ $.uri.base = function () {
+ return $(document).base();
+ };
+
+ /**
+ * Returns the base URI in scope for the first selected element
+ * @methodOf jQuery#
+ * @name jQuery#base
+ * @returns {jQuery.uri}
+ * @example baseURI = $('img').base();
+ */
+ $.fn.base = function () {
+ var base = $(this).parents().andSelf().find('base').attr('href'),
+ doc = $(this)[0].ownerDocument || document,
+ docURI = $.uri.absolute(doc.location === null ? document.location.href : doc.location.href);
+ return base === undefined ? docURI : $.uri(base, docURI);
+ };
+
+})(jQuery);
+/*
+ * jQuery CURIE @VERSION
+ *
+ * Copyright (c) 2008,2009 Jeni Tennison
+ * Licensed under the MIT (MIT-LICENSE.txt)
+ *
+ * Depends:
+ * jquery.uri.js
+ */
+/**
+ * @fileOverview XML Namespace processing
+ * @author Jeni Tennison
+ * @copyright (c) 2008,2009 Jeni Tennison
+ * @license MIT license (MIT-LICENSE.txt)
+ * @version 1.0
+ * @requires jquery.uri.js
+ */
+
+/*global jQuery */
+(function ($) {
+
+ var
+ xmlnsRegex = /\sxmlns(?::([^ =]+))?\s*=\s*(?:"([^"]*)"|'([^']*)')/g;
+
+/**
+ * Returns the namespaces declared in the scope of the first selected element, or
+ * adds a namespace declaration to all selected elements. Pass in no parameters
+ * to return all namespaces bindings on the first selected element. If only
+ * the prefix parameter is specified, this method will return the namespace
+ * URI that is bound to the specified prefix on the first element in the selection
+ * If the prefix and uri parameters are both specified, this method will
+ * add the binding of the specified prefix and namespace URI to all elements
+ * in the selection.
+ * @methodOf jQuery#
+ * @name jQuery#xmlns
+ * @param {String} [prefix] Restricts the namespaces returned to only the namespace with the specified namespace prefix.
+ * @param {String|jQuery.uri} [uri] Adds a namespace declaration to the selected elements that maps the specified prefix to the specified namespace.
+ * @param {Object} [inherited] A map of inherited namespace bindings.
+ * @returns {Object|jQuery.uri|jQuery}
+ * @example
+ * // Retrieve all of the namespace bindings on the HTML document element
+ * var nsMap = $('html').xmlns();
+ * @example
+ * // Retrieve the namespace URI mapped to the 'dc' prefix on the HTML document element
+ * var dcNamespace = $('html').xmlns('dc');
+ * @example
+ * // Create a namespace declaration that binds the 'dc' prefix to the URI 'http://purl.org/dc/elements/1.1/'
+ * $('html').xmlns('dc', 'http://purl.org/dc/elements/1.1/');
+ */
+ $.fn.xmlns = function (prefix, uri, inherited) {
+ var
+ elem = this.eq(0),
+ ns = elem.data('xmlns'),
+ e = elem[0], a, p, i,
+ decl = prefix ? 'xmlns:' + prefix : 'xmlns',
+ value,
+ tag, found = false;
+ if (uri === undefined) {
+ if (prefix === undefined) { // get the in-scope declarations on the first element
+ if (ns === undefined) {
+ ns = {};
+ if (e.attributes && e.attributes.getNamedItemNS) {
+ for (i = 0; i < e.attributes.length; i += 1) {
+ a = e.attributes[i];
+ if (/^xmlns(:(.+))?$/.test(a.nodeName)) {
+ prefix = /^xmlns(:(.+))?$/.exec(a.nodeName)[2] || '';
+ value = a.nodeValue;
+ if (prefix === '' || value !== '') {
+ ns[prefix] = $.uri(a.nodeValue);
+ found = true;
+ }
+ }
+ }
+ } else {
+ tag = /<[^>]+>/.exec(e.outerHTML);
+ a = xmlnsRegex.exec(tag);
+ while (a !== null) {
+ prefix = a[1] || '';
+ value = a[2] || a[3];
+ if (prefix === '' || value !== '') {
+ ns[prefix] = $.uri(a[2] || a[3]);
+ found = true;
+ }
+ a = xmlnsRegex.exec(tag);
+ }
+ xmlnsRegex.lastIndex = 0;
+ }
+ inherited = inherited || (e.parentNode.nodeType === 1 ? elem.parent().xmlns() : {});
+ ns = found ? $.extend({}, inherited, ns) : inherited;
+ elem.data('xmlns', ns);
+ }
+ return ns;
+ } else if (typeof prefix === 'object') { // set the prefix mappings defined in the object
+ for (p in prefix) {
+ if (typeof prefix[p] === 'string') {
+ this.xmlns(p, prefix[p]);
+ }
+ }
+ this.find('*').andSelf().removeData('xmlns');
+ return this;
+ } else { // get the in-scope declaration associated with this prefix on the first element
+ if (ns === undefined) {
+ ns = elem.xmlns();
+ }
+ return ns[prefix];
+ }
+ } else { // set
+ this.find('*').andSelf().removeData('xmlns');
+ return this.attr(decl, uri);
+ }
+ };
+
+/**
+ * Removes one or more XML namespace bindings from the selected elements.
+ * @methodOf jQuery#
+ * @name jQuery#removeXmlns
+ * @param {String|Object|String[]} prefix The prefix(es) of the XML namespace bindings that are to be removed from the selected elements.
+ * @returns {jQuery} The original jQuery object.
+ * @example
+ * // Remove the foaf namespace declaration from the body element:
+ * $('body').removeXmlns('foaf');
+ * @example
+ * // Remove the foo and bar namespace declarations from all h2 elements
+ * $('h2').removeXmlns(['foo', 'bar']);
+ * @example
+ * // Remove the foo and bar namespace declarations from all h2 elements
+ * var namespaces = { foo : 'http://www.example.org/foo', bar : 'http://www.example.org/bar' };
+ * $('h2').removeXmlns(namespaces);
+ */
+ $.fn.removeXmlns = function (prefix) {
+ var decl, p, i;
+ if (typeof prefix === 'object') {
+ if (prefix.length === undefined) { // assume an object representing namespaces
+ for (p in prefix) {
+ if (typeof prefix[p] === 'string') {
+ this.removeXmlns(p);
+ }
+ }
+ } else { // it's an array
+ for (i = 0; i < prefix.length; i += 1) {
+ this.removeXmlns(prefix[i]);
+ }
+ }
+ } else {
+ decl = prefix ? 'xmlns:' + prefix : 'xmlns';
+ this.removeAttr(decl);
+ }
+ this.find('*').andSelf().removeData('xmlns');
+ return this;
+ };
+
+ $.fn.qname = function (name) {
+ var m, prefix, namespace;
+ if (name === undefined) {
+ if (this[0].outerHTML === undefined) {
+ name = this[0].nodeName.toLowerCase();
+ } else {
+ name = /<([^ >]+)/.exec(this[0].outerHTML)[1].toLowerCase();
+ }
+ }
+ if (name === '?xml:namespace') {
+ // there's a prefix on the name, but we can't get at it
+ throw "XMLinHTML: Unable to get the prefix to resolve the name of this element";
+ }
+ m = /^(([^:]+):)?([^:]+)$/.exec(name);
+ prefix = m[2] || '';
+ namespace = this.xmlns(prefix);
+ if (namespace === undefined && prefix !== '') {
+ throw "MalformedQName: The prefix " + prefix + " is not declared";
+ }
+ return {
+ namespace: namespace,
+ localPart: m[3],
+ prefix: prefix,
+ name: name
+ };
+ };
+
+})(jQuery);
+/*
+ * jQuery CURIE @VERSION
+ *
+ * Copyright (c) 2008,2009 Jeni Tennison
+ * Licensed under the MIT (MIT-LICENSE.txt)
+ *
+ * Depends:
+ * jquery.uri.js
+ */
+/**
+ * @fileOverview XML Schema datatype handling
+ * @author Jeni Tennison
+ * @copyright (c) 2008,2009 Jeni Tennison
+ * @license MIT license (MIT-LICENSE.txt)
+ * @version 1.0
+ * @requires jquery.uri.js
+ */
+
+(function ($) {
+
+ var strip = function (value) {
+ return value.replace(/[ \t\n\r]+/, ' ').replace(/^ +/, '').replace(/ +$/, '');
+ };
+
+ /**
+ * Creates a new jQuery.typedValue object. This should be invoked as a method
+ * rather than constructed using new.
+ * @class Represents a value with an XML Schema datatype
+ * @param {String} value The string representation of the value
+ * @param {String} datatype The XML Schema datatype URI
+ * @returns {jQuery.typedValue}
+ * @example intValue = jQuery.typedValue('42', 'http://www.w3.org/2001/XMLSchema#integer');
+ */
+ $.typedValue = function (value, datatype) {
+ return $.typedValue.fn.init(value, datatype);
+ };
+
+ $.typedValue.fn = $.typedValue.prototype = {
+ /**
+ * The string representation of the value
+ * @memberOf jQuery.typedValue#
+ */
+ representation: undefined,
+ /**
+ * The value as an object. The type of the object will
+ * depend on the XML Schema datatype URI specified
+ * in the constructor. The following table lists the mappings
+ * currently supported:
+ * XML Schema Datatype | + *Value type | + *
---|---|
http://www.w3.org/2001/XMLSchema#string | + *string | + *
http://www.w3.org/2001/XMLSchema#boolean | + *bool | + *
http://www.w3.org/2001/XMLSchema#decimal | + *string | + *
http://www.w3.org/2001/XMLSchema#integer | + *int | + *
http://www.w3.org/2001/XMLSchema#int | + *int | + *
http://www.w3.org/2001/XMLSchema#float | + *float | + *
http://www.w3.org/2001/XMLSchema#double | + *float | + *
http://www.w3.org/2001/XMLSchema#dateTime | + *string | + *
http://www.w3.org/2001/XMLSchema#date | + *string | + *
http://www.w3.org/2001/XMLSchema#gMonthDay | + *string | + *
http://www.w3.org/2001/XMLSchema#anyURI | + *string | + *
Creates a new jQuery.rdf object. This should be invoked as a method rather than constructed using new; indeed you will usually want to generate these objects using a method such as {@link jQuery#rdf} or {@link jQuery.rdf#where}.
+ * @classA jQuery.rdf object represents the results of a query over its {@link jQuery.rdf#databank}. The results of a query are a sequence of objects which represent the bindings of values to the variables used in filter expressions specified using {@link jQuery.rdf#where} or {@link jQuery.rdf#optional}. Each of the objects in this sequence has associated with it a set of triples that are the sources for the variable bindings, which you can get at using {@link jQuery.rdf#sources}.
+ *The {@link jQuery.rdf} object itself is a lot like a {@link jQuery} object. It has a {@link jQuery.rdf#length} and the individual matches can be accessed using [n]
, but you can also iterate through the matches using {@link jQuery.rdf#map} or {@link jQuery.rdf#each}.
{@link jQuery.rdf} is designed to mirror the functionality of SPARQL while providing an interface that's familiar and easy to use for jQuery programmers.
+ * @param {Object} [options] + * @param {jQuery.rdf.databank} [options.databank] The databank that this query should operate over. + * @param {jQuery.rdf.triple[]} [options.triples] A set of triples over which the query operates; this is only used if options.databank isn't specified, in which case a new databank with these triples is generated. + * @param {Object} [options.namespaces] An object representing a set of namespace bindings. Rather than passing this in when you construct the {@link jQuery.rdf} instance, you will usually want to use the {@link jQuery.rdf#prefix} method. + * @param {String|jQuery.uri} [options.base] The base URI used to interpret any relative URIs used within the query. + * @returns {jQuery.rdf} + * @example rdf = jQuery.rdf(); + * @see jQuery#rdf + */ + $.rdf = function (options) { + return new $.rdf.fn.init(options); + }; + + $.rdf.fn = $.rdf.prototype = { + /** + * The version of rdfQuery. + * @type String + */ + rdfquery: '0.9', + + init: function (options) { + var databanks; + options = options || {}; + /* must specify either a parent or a union, otherwise it's the top */ + this.parent = options.parent; + this.union = options.union; + this.top = this.parent === undefined && this.union === undefined; + if (this.union === undefined) { + if (options.databank === undefined) { + /** + * The databank over which this query operates. + * @type jQuery.rdf.databank + */ + this.databank = this.parent === undefined ? $.rdf.databank(options.triples, options) : this.parent.databank; + } else { + this.databank = options.databank; + } + } else { + databanks = $.map(this.union, function (query) { + return query.databank; + }); + databanks = $.unique(databanks); + if (databanks[1] !== undefined) { + this.databank = $.rdf.databank(undefined, { union: databanks }); + } else { + this.databank = databanks[0]; + } + } + this.children = []; + this.partOf = []; + this.filterExp = options.filter; + this.alphaMemory = []; + this.matches = []; + /** + * The number of matches represented by the {@link jQuery.rdf} object. + * @type Integer + */ + this.length = 0; + if (this.filterExp !== undefined) { + if (!$.isFunction(this.filterExp)) { + registerQuery(this.databank, this); + this.alphaMemory = findMatches(this.databank.triples(), this.filterExp); + } + } + leftActivate(this); + return this; + }, + + /** + * Sets or returns the base URI of the {@link jQuery.rdf#databank}. + * @param {String|jQuery.uri} [base] + * @returns A {@link jQuery.uri} if no base URI is specified, otherwise returns this {@link jQuery.rdf} object. + * @example baseURI = jQuery('html').rdf().base(); + * @example jQuery('html').rdf().base('http://www.example.org/'); + * @see jQuery.rdf.databank#base + */ + base: function (base) { + if (base === undefined) { + return this.databank.base(); + } else { + this.databank.base(base); + return this; + } + }, + + /** + * Sets or returns a namespace binding on the {@link jQuery.rdf#databank}. + * @param {String} [prefix] + * @param {String} [namespace] + * @returns {Object|jQuery.uri|jQuery.rdf} If no prefix or namespace is specified, returns an object providing all namespace bindings on the {@link jQuery.rdf.databank}. If a prefix is specified without a namespace, returns the {@link jQuery.uri} associated with that prefix. Otherwise returns this {@link jQuery.rdf} object after setting the namespace binding. + * @example namespace = jQuery('html').rdf().prefix('foaf'); + * @example jQuery('html').rdf().prefix('foaf', 'http://xmlns.com/foaf/0.1/'); + * @see jQuery.rdf.databank#prefix + */ + prefix: function (prefix, namespace) { + if (namespace === undefined) { + return this.databank.prefix(prefix); + } else { + this.databank.prefix(prefix, namespace); + return this; + } + }, + + /** + * Adds a triple to the {@link jQuery.rdf#databank} or another {@link jQuery.rdf} object to create a union. + * @param {String|jQuery.rdf.triple|jQuery.rdf.pattern|jQuery.rdf} triple The triple, {@link jQuery.rdf.pattern} or {@link jQuery.rdf} object to be added to this one. If the triple is a {@link jQuery.rdf} object, the two queries are unioned together. If the triple is a string, it's parsed as a {@link jQuery.rdf.pattern}. The pattern will be completed using the current matches on the {@link jQuery.rdf} object to create multiple triples, one for each set of bindings. + * @param {Object} [options] + * @param {Object} [options.namespaces] An object representing a set of namespace bindings used to interpret CURIEs within the triple. Defaults to the namespace bindings defined on the {@link jQuery.rdf#databank}. + * @param {String|jQuery.uri} [options.base] The base URI used to interpret any relative URIs used within the triple. Defaults to the base URI defined on the {@link jQuery.rdf#databank}. + * @returns {jQuery.rdf} This {@link jQuery.rdf} object. + * @example + * var rdf = $.rdf() + * .prefix('dc', ns.dc) + * .prefix('foaf', ns.foaf) + * .add('<photo1.jpg> dc:creator <http://www.blogger.com/profile/1109404> .') + * .add('<http://www.blogger.com/profile/1109404> foaf:img <photo1.jpg> .'); + * @example + * var rdfA = $.rdf() + * .prefix('dc', ns.dc) + * .add('<photo1.jpg> dc:creator "Jane"'); + * var rdfB = $.rdf() + * .prefix('foaf', ns.foaf) + * .add('<photo1.jpg> foaf:depicts "Jane"'); + * var rdf = rdfA.add(rdfB); + * @see jQuery.rdf.databank#add + */ + add: function (triple, options) { + var query, databank; + if (triple.rdfquery !== undefined) { + if (triple.top) { + databank = this.databank.add(triple.databank); + query = $.rdf({ parent: this.parent, databank: databank }); + return query; + } else if (this.top) { + databank = triple.databank.add(this.databank); + query = $.rdf({ parent: triple.parent, databank: databank }); + return query; + } else if (this.union === undefined) { + query = $.rdf({ union: [this, triple] }); + this.partOf.push(query); + triple.partOf.push(query); + return query; + } else { + this.union.push(triple); + triple.partOf.push(this); + } + } else { + if (typeof triple === 'string') { + options = $.extend({}, { base: this.base(), namespaces: this.prefix(), source: triple }, options); + triple = $.rdf.pattern(triple, options); + } + if (triple.isFixed()) { + this.databank.add(triple.triple(), options); + } else { + query = this; + this.each(function (i, data) { + var t = triple.triple(data); + if (t !== null) { + query.databank.add(t, options); + } + }); + } + } + return this; + }, + + /** + * Removes a triple or several triples from the {@link jQuery.rdf#databank}. + * @param {String|jQuery.rdf.triple|jQuery.rdf.pattern} triple The triple to be removed, or a {@link jQuery.rdf.pattern} that matches the triples that should be removed. + * @param {Object} [options] + * @param {Object} [options.namespaces] An object representing a set of namespace bindings used to interpret any CURIEs within the triple or pattern. Defaults to the namespace bindings defined on the {@link jQuery.rdf#databank}. + * @param {String|jQuery.uri} [options.base] The base URI used to interpret any relative URIs used within the triple or pattern. Defaults to the base URI defined on the {@link jQuery.rdf#databank}. + * @returns {jQuery.rdf} The {@link jQuery.rdf} object itself. + * @example + * var rdf = $('html').rdf() + * .prefix('foaf', ns.foaf) + * .where('?person foaf:givenname ?gname') + * .where('?person foaf:family_name ?fname') + * .remove('?person foaf:family_name ?fname'); + * @see jQuery.rdf.databank#remove + */ + remove: function (triple, options) { + if (typeof triple === 'string') { + options = $.extend({}, { base: this.base(), namespaces: this.prefix() }, options); + triple = $.rdf.pattern(triple, options); + } + if (triple.isFixed()) { + this.databank.remove(triple.triple(), options); + } else { + query = this; + this.each(function (i, data) { + var t = triple.triple(data); + if (t !== null) { + query.databank.remove(t, options); + } + }); + } + return this; + }, + + /** + * Loads some data into the {@link jQuery.rdf#databank} + * @param data + * @param {Object} [options] + * @see jQuery.rdf.databank#load + */ + load: function (data, options) { + this.databank.load(data, options); + return this; + }, + + /** + * Creates a new {@link jQuery.rdf} object whose databank contains all the triples in this object's databank except for those in the argument's databank. + * @param {jQuery.rdf} query + * @see jQuery.rdf.databank#except + */ + except: function (query) { + return $.rdf({ databank: this.databank.except(query.databank) }); + }, + + /** + * Creates a new {@link jQuery.rdf} object that is the result of filtering the matches on this {@link jQuery.rdf} object based on the filter that's passed into it. + * @param {String|jQuery.rdf.pattern} filter An expression that filters the triples in the {@link jQuery.rdf#databank} to locate matches based on the matches on this {@link jQuery.rdf} object. If it's a string, the filter is parsed as a {@link jQuery.rdf.pattern}. + * @param {Object} [options] + * @param {Object} [options.namespaces] An object representing a set of namespace bindings used to interpret any CURIEs within the pattern. Defaults to the namespace bindings defined on the {@link jQuery.rdf#databank}. + * @param {String|jQuery.uri} [options.base] The base URI used to interpret any relative URIs used within the pattern. Defaults to the base URI defined on the {@link jQuery.rdf#databank}. + * @param {boolean} [options.optional] Not usually used (use {@link jQuery.rdf#optional} instead). + * @returns {jQuery.rdf} A new {@link jQuery.rdf} object whose {@link jQuery.rdf#parent} is this {@link jQuery.rdf}. + * @see jQuery.rdf#optional + * @see jQuery.rdf#filter + * @see jQuery.rdf#about + * @example + * var rdf = $.rdf() + * .prefix('foaf', ns.foaf) + * .add('_:a foaf:givenname "Alice" .') + * .add('_:a foaf:family_name "Hacker" .') + * .add('_:b foaf:givenname "Bob" .') + * .add('_:b foaf:family_name "Hacker" .') + * .where('?person foaf:family_name "Hacker"') + * .where('?person foaf:givenname "Bob"); + */ + where: function (filter, options) { + var query, base, namespaces, optional; + options = options || {}; + if (typeof filter === 'string') { + base = options.base || this.base(); + namespaces = $.extend({}, this.prefix(), options.namespaces || {}); + optional = options.optional || false; + filter = $.rdf.pattern(filter, { namespaces: namespaces, base: base, optional: optional }); + } + query = $.rdf($.extend({}, options, { parent: this, filter: filter })); + this.children.push(query); + return query; + }, + + /** + * Creates a new {@link jQuery.rdf} object whose set of bindings might optionally include those based on the filter pattern. + * @param {String|jQuery.rdf.pattern} filter An pattern for a set of bindings that might be added to those in this {@link jQuery.rdf} object. + * @param {Object} [options] + * @param {Object} [options.namespaces] An object representing a set of namespace bindings used to interpret any CURIEs within the pattern. Defaults to the namespace bindings defined on the {@link jQuery.rdf#databank}. + * @param {String|jQuery.uri} [options.base] The base URI used to interpret any relative URIs used within the pattern. Defaults to the base URI defined on the {@link jQuery.rdf#databank}. + * @returns {jQuery.rdf} A new {@link jQuery.rdf} object whose {@link jQuery.rdf#parent} is this {@link jQuery.rdf}. + * @see jQuery.rdf#where + * @see jQuery.rdf#filter + * @see jQuery.rdf#about + * @example + * var rdf = $.rdf() + * .prefix('foaf', 'http://xmlns.com/foaf/0.1/') + * .prefix('rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#') + * .add('_:a rdf:type foaf:Person .') + * .add('_:a foaf:name "Alice" .') + * .add('_:a foaf:mbox <mailto:alice@example.com> .') + * .add('_:a foaf:mbox <mailto:alice@work.example> .') + * .add('_:b rdf:type foaf:Person .') + * .add('_:b foaf:name "Bob" .') + * .where('?x foaf:name ?name') + * .optional('?x foaf:mbox ?mbox'); + */ + optional: function (filter, options) { + return this.where(filter, $.extend({}, options || {}, { optional: true })); + }, + + /** + * Creates a new {@link jQuery.rdf} object whose set of bindings includeproperty
and value
for every triple that is about the specified resource.
+ * @param {String|jQuery.rdf.resource} resource The subject of the matching triples.
+ * @param {Object} [options]
+ * @param {Object} [options.namespaces] An object representing a set of namespace bindings used to interpret the resource if it's a CURIE. Defaults to the namespace bindings defined on the {@link jQuery.rdf#databank}.
+ * @param {String|jQuery.uri} [options.base] The base URI used to interpret the resource if it's a relative URI (wrapped in <
and >
). Defaults to the base URI defined on the {@link jQuery.rdf#databank}.
+ * @returns {jQuery.rdf} A new {@link jQuery.rdf} object whose {@link jQuery.rdf#parent} is this {@link jQuery.rdf}.
+ * @see jQuery.rdf#where
+ * @see jQuery.rdf#optional
+ * @see jQuery.rdf#filter
+ * @example
+ * var rdf = $.rdf()
+ * .prefix('dc', ns.dc)
+ * .prefix('foaf', ns.foaf)
+ * .add('<photo1.jpg> dc:creator <http://www.blogger.com/profile/1109404> .')
+ * .add('<http://www.blogger.com/profile/1109404> foaf:img <photo1.jpg> .')
+ * .add('<photo2.jpg> dc:creator <http://www.blogger.com/profile/1109404> .')
+ * .add('<http://www.blogger.com/profile/1109404> foaf:img <photo2.jpg> .')
+ * .about('<http://www.blogger.com/profile/1109404>');
+ */
+ about: function (resource, options) {
+ return this.where(resource + ' ?property ?value', options);
+ },
+
+ /**
+ * Creates a new {@link jQuery.rdf} object whose set of bindings include only those that satisfy some arbitrary condition. There are two main ways to call this method: with two arguments in which case the first is a binding to be tested and the second represents a condition on the test, or with one argument which is a function that should return true for acceptable bindings.
+ * @param {Function|String} property In the two-argument version, this is the name of a property to be tested against the condition specified in the second argument. In the one-argument version, this is a function in which this
is an object whose properties are a set of {@link jQuery.rdf.resource}, {@link jQuery.rdf.literal} or {@link jQuery.rdf.blank} objects and whose arguments are:
this
)?
) are taken as variable names; each matching resource is described by the function.
+ * @returns {jQuery} A {@link jQuery} object that contains {@link jQuery.rdf.triple}s that describe the listed resources.
+ * @see jQuery.rdf.databank#describe
+ * @example
+ * $.rdf.dump($('html').rdf().describe(['this
is set to the object representing the variable bindings. The function can take up to three parameters:
+ * this
.this
is set to the object representing the variable bindings. The function can take up to three parameters and should return some kind of value:
+ * this
.mime type | description |
---|---|
application/json |
+ * An RDF/JSON object | + *
application/rdf+xml |
+ * An DOMDocument node holding XML in RDF/XML syntax | + *
Creates a new jQuery.rdf.databank object. This should be invoked as a method rather than constructed using new; indeed you will not usually want to generate these objects directly, but manipulate them through a {@link jQuery.rdf} object.
+ * @class Represents a triplestore, holding a bunch of {@link jQuery.rdf.triple}s. + * @param {(String|jQuery.rdf.triple)[]} [triples=[]] An array of triples to store in the databank. + * @param {Object} [options] Initialisation of the databank. + * @param {Object} [options.namespaces] An object representing a set of namespace bindings used when interpreting the CURIEs in strings representing triples. Rather than passing this in when you construct the {@link jQuery.rdf.databank} instance, you will usually want to use the {@link jQuery.rdf.databank#prefix} method. + * @param {String|jQuery.uri} [options.base] The base URI used to interpret any relative URIs used within the strings representing triples. + * @returns {jQuery.rdf.databank} The newly-created databank. + * @see jQuery.rdf + */ + $.rdf.databank = function (triples, options) { + return new $.rdf.databank.fn.init(triples, options); + }; + + $.rdf.databank.fn = $.rdf.databank.prototype = { + init: function (triples, options) { + var i; + triples = triples || []; + options = options || {}; + this.id = databankID(); + if (options.union === undefined) { + this.queries = {}; + this.tripleStore = {}; + this.objectStore = {}; + this.baseURI = options.base || $.uri.base(); + this.namespaces = $.extend({}, options.namespaces || {}); + for (i = 0; i < triples.length; i += 1) { + this.add(triples[i]); + } + } else { + this.union = options.union; + } + return this; + }, + + /** + * Sets or returns the base URI of the {@link jQuery.rdf.databank}. + * @param {String|jQuery.uri} [base] + * @returns A {@link jQuery.uri} if no base URI is specified, otherwise returns this {@link jQuery.rdf.databank} object. + * @see jQuery.rdf#base + */ + base: function (base) { + if (this.union === undefined) { + if (base === undefined) { + return this.baseURI; + } else { + this.baseURI = base; + return this; + } + } else if (base === undefined) { + return this.union[0].base(); + } else { + $.each(this.union, function (i, databank) { + databank.base(base); + }); + return this; + } + }, + + /** + * Sets or returns a namespace binding on the {@link jQuery.rdf.databank}. + * @param {String} [prefix] + * @param {String} [namespace] + * @returns {Object|jQuery.uri|jQuery.rdf} If no prefix or namespace is specified, returns an object providing all namespace bindings on the {@link jQuery.rdf#databank}. If a prefix is specified without a namespace, returns the {@link jQuery.uri} associated with that prefix. Otherwise returns this {@link jQuery.rdf} object after setting the namespace binding. + * @see jQuery.rdf#prefix + */ + prefix: function (prefix, uri) { + var namespaces = {}; + if (this.union === undefined) { + if (prefix === undefined) { + return this.namespaces; + } else if (uri === undefined) { + return this.namespaces[prefix]; + } else { + this.namespaces[prefix] = uri; + return this; + } + } else if (uri === undefined) { + $.each(this.union, function (i, databank) { + $.extend(namespaces, databank.prefix()); + }); + if (prefix === undefined) { + return namespaces; + } else { + return namespaces[prefix]; + } + } else { + $.each(this.union, function (i, databank) { + databank.prefix(prefix, uri); + }); + return this; + } + }, + + /** + * Adds a triple to the {@link jQuery.rdf.databank} or another {@link jQuery.rdf.databank} object to create a union. + * @param {String|jQuery.rdf.triple|jQuery.rdf.databank} triple The triple or {@link jQuery.rdf.databank} object to be added to this one. If the triple is a {@link jQuery.rdf.databank} object, the two databanks are unioned together. If the triple is a string, it's parsed as a {@link jQuery.rdf.triple}. + * @param {Object} [options] + * @param {Object} [options.namespaces] An object representing a set of namespace bindings used to interpret CURIEs within the triple. Defaults to the namespace bindings defined on the {@link jQuery.rdf.databank}. + * @param {String|jQuery.uri} [options.base] The base URI used to interpret any relative URIs used within the triple. Defaults to the base URI defined on the {@link jQuery.rdf.databank}. + * @returns {jQuery.rdf.databank} This {@link jQuery.rdf.databank} object. + * @see jQuery.rdf#add + */ + add: function (triple, options) { + var base = (options && options.base) || this.base(), + namespaces = $.extend({}, this.prefix(), (options && options.namespaces) || {}), + databank; + if (triple === this) { + return this; + } else if (triple.tripleStore !== undefined) { + // merging two databanks + if (this.union === undefined) { + databank = $.rdf.databank(undefined, { union: [this, triple] }); + return databank; + } else { + this.union.push(triple); + return this; + } + } else { + if (typeof triple === 'string') { + triple = $.rdf.triple(triple, { namespaces: namespaces, base: base, source: triple }); + } + if (this.union === undefined) { + if (this.tripleStore[triple.subject] === undefined) { + this.tripleStore[triple.subject] = []; + } + if ($.inArray(triple, this.tripleStore[triple.subject]) === -1) { + this.tripleStore[triple.subject].push(triple); + if (triple.object.type === 'uri' || triple.object.type === 'bnode') { + if (this.objectStore[triple.object] === undefined) { + this.objectStore[triple.object] = []; + } + this.objectStore[triple.object].push(triple); + } + addToDatabankQueries(this, triple); + } + } else { + $.each(this.union, function (i, databank) { + databank.add(triple); + }); + } + return this; + } + }, + + /** + * Removes a triple from the {@link jQuery.rdf.databank}. + * @param {String|jQuery.rdf.triple} triple The triple to be removed. + * @param {Object} [options] + * @param {Object} [options.namespaces] An object representing a set of namespace bindings used to interpret any CURIEs within the triple. Defaults to the namespace bindings defined on the {@link jQuery.rdf.databank}. + * @param {String|jQuery.uri} [options.base] The base URI used to interpret any relative URIs used within the triple. Defaults to the base URI defined on the {@link jQuery.rdf.databank}. + * @returns {jQuery.rdf.databank} The {@link jQuery.rdf.databank} object itself. + * @see jQuery.rdf#remove + */ + remove: function (triple, options) { + var base = (options && options.base) || this.base(), + namespaces = $.extend({}, this.prefix(), (options && options.namespaces) || {}), + striples, otriples, + databank; + if (typeof triple === 'string') { + triple = $.rdf.triple(triple, { namespaces: namespaces, base: base, source: triple }); + } + striples = this.tripleStore[triple.subject]; + if (striples !== undefined) { + striples.splice($.inArray(triple, striples), 1); + } + if (triple.object.type === 'uri' || triple.object.type === 'bnode') { + otriples = this.objectStore[triple.object]; + if (otriples !== undefined) { + otriples.splice($.inArray(triple, otriples), 1); + } + } + removeFromDatabankQueries(this, triple); + return this; + }, + + /** + * Creates a new databank containing all the triples in this {@link jQuery.rdf.databank} except those in the {@link jQuery.rdf.databank} passed as the argument. + * @param {jQuery.rdf.databank} data The other {@link jQuery.rdf.databank} + * @returns {jQuery.rdf.databank} A new {@link jQuery.rdf.databank} containing the triples in this {@link jQuery.rdf.databank} except for those in the data parameter. + * @example + * var old = $('html').rdf().databank; + * ...some processing occurs... + * var new = $('html').rdf().databank; + * var added = new.except(old); + * var removed = old.except(new); + */ + except: function (data) { + var store = data.tripleStore, + diff = []; + $.each(this.tripleStore, function (s, ts) { + var ots = store[s]; + if (ots === undefined) { + diff = diff.concat(ts); + } else { + $.each(ts, function (i, t) { + if ($.inArray(t, ots) === -1) { + diff.push(t); + } + }); + } + }); + return $.rdf.databank(diff); + }, + + /** + * Provides a {@link jQuery} object containing the triples held in this {@link jQuery.rdf.databank}. + * @returns {jQuery} A {@link jQuery} object containing {@link jQuery.rdf.triple} objects. + */ + triples: function () { + var triples = []; + if (this.union === undefined) { + $.each(this.tripleStore, function (s, t) { + triples = triples.concat(t); + }); + } else { + $.each(this.union, function (i, databank) { + triples = triples.concat(databank.triples().get()); + }); + triples = $.unique(triples); + } + return $(triples); + }, + + /** + * Tells you how many triples the databank contains. + * @returns {Integer} The number of triples in the {@link jQuery.rdf.databank}. + * @example $('html').rdf().databank.size(); + */ + size: function () { + return this.triples().length; + }, + + /** + * Provides simple concise bounded descriptions of the resources that are passed in the argument. This mirrors the DESCRIBE form in SPARQL. + * @param {(String|jQuery.rdf.resource)[]} resources An array that can contain strings, {@link jQuery.rdf.resource}s or a mixture of the two. + * @returns {jQuery} A {@link jQuery} object holding the {@link jQuery.rdf.triple}s that describe the listed resources. + * @see jQuery.rdf#describe + */ + describe: function (resources) { + var i, r, t, rhash = {}, triples = []; + while (resources.length > 0) { + r = resources.pop(); + if (rhash[r] === undefined) { + if (r.value === undefined) { + r = $.rdf.resource(r); + } + if (this.tripleStore[r] !== undefined) { + for (i = 0; i < this.tripleStore[r].length; i += 1) { + t = this.tripleStore[r][i]; + triples.push(t); + if (t.object.type === 'bnode') { + resources.push(t.object); + } + } + } + if (this.objectStore[r] !== undefined) { + for (i = 0; i < this.objectStore[r].length; i += 1) { + t = this.objectStore[r][i]; + triples.push(t); + if (t.subject.type === 'bnode') { + resources.push(t.subject); + } + } + } + rhash[r] = true; + } + } + return $.unique(triples); + }, + + /** + * Dumps the triples in the databank into a format that can be shown to the user or sent to a server. + * @param {Object} [options] Options that control the formatting of the triples. See {@link jQuery.rdf.dump} for details. + * @returns {Object|Node|String} + * @see jQuery.rdf.dump + */ + dump: function (options) { + options = $.extend({ namespaces: this.namespaces, base: this.base }, options || {}); + return $.rdf.dump(this.triples(), options); + }, + + /** + * Loads some data into the databank. + * @param {Node|Object} data If the data is a node, it's interpreted to be an RDF/XML syntax document and will be parsed as such. Otherwise, it's taken to be a RDF/JSON object. The data cannot be a string; it must be parsed before it is passed to this function. + * @returns {jQuery.rdf.databank} The {@link jQuery.rdf.databank} itself. + * @see jQuery.rdf#load + */ + load: function (data) { + var i, triples; + if (data.ownerDocument !== undefined) { + triples = parseRdfXml(data); + } else { + triples = parseJson(data); + } + for (i = 0; i < triples.length; i += 1) { + this.add(triples[i]); + } + return this; + }, + + /** + * Provides a string representation of the databank which simply specifies how many triples it contains. + * @returns {String} + */ + toString: function () { + return '[Databank with ' + this.size() + ' triples]'; + } + }; + + $.rdf.databank.fn.init.prototype = $.rdf.databank.fn; + + /** + *Creates a new jQuery.rdf.pattern object. This should be invoked as a method rather than constructed using new; indeed you will not usually want to generate these objects directly, since they are automatically created from strings where necessary, such as by {@link jQuery.rdf#where}.
+ * @class Represents a pattern that may or may not match a given {@link jQuery.rdf.triple}. + * @param {String|jQuery.rdf.resource|jQuery.rdf.blank} subject The subject pattern, or a single string that defines the entire pattern. If the subject is specified as a string, it can be a fixed resource (<uri>
or curie
), a blank node (_:id
) or a variable placeholder (?name
).
+ * @param {String|jQuery.rdf.resource} [property] The property pattern. If the property is specified as a string, it can be a fixed resource (<uri>
or curie
) or a variable placeholder (?name
).
+ * @param {String|jQuery.rdf.resource|jQuery.rdf.blank|jQuery.rdf.literal} [value] The value pattern. If the property is specified as a string, it can be a fixed resource (<uri>
or curie
), a blank node (_:id
), a literal ("value"
) or a variable placeholder (?name
).
+ * @param {Object} [options] Initialisation of the pattern.
+ * @param {Object} [options.namespaces] An object representing a set of namespace bindings used when interpreting the CURIEs in the subject, property and object.
+ * @param {String|jQuery.uri} [options.base] The base URI used to interpret any relative URIs used within the subject, property and object.
+ * @param {boolean} [options.optional]
+ * @returns {jQuery.rdf.pattern} The newly-created pattern.
+ * @throws {String} Errors if any of the strings are not in a recognised format.
+ * @example pattern = $.rdf.pattern('?person', $.rdf.type, 'foaf:Person', { namespaces: { foaf: "http://xmlns.com/foaf/0.1/" }});
+ * @example
+ * pattern = $.rdf.pattern('?person a foaf:Person', {
+ * namespaces: { foaf: "http://xmlns.com/foaf/0.1/" },
+ * optional: true
+ * });
+ * @see jQuery.rdf#where
+ * @see jQuery.rdf.resource
+ * @see jQuery.rdf.blank
+ * @see jQuery.rdf.literal
+ */
+ $.rdf.pattern = function (subject, property, object, options) {
+ var pattern, m, optional;
+ // using a two-argument version; first argument is a Turtle statement string
+ if (object === undefined) {
+ options = property || {};
+ m = $.trim(subject).match(tripleRegex);
+ if (m.length === 3 || (m.length === 4 && m[3] === '.')) {
+ subject = m[0];
+ property = m[1];
+ object = m[2];
+ } else {
+ throw "Bad Pattern: Couldn't parse string " + subject;
+ }
+ optional = (options.optional === undefined) ? $.rdf.pattern.defaults.optional : options.optional;
+ }
+ if (memPattern[subject] &&
+ memPattern[subject][property] &&
+ memPattern[subject][property][object] &&
+ memPattern[subject][property][object][optional]) {
+ return memPattern[subject][property][object][optional];
+ }
+ pattern = new $.rdf.pattern.fn.init(subject, property, object, options);
+ if (memPattern[pattern.subject] &&
+ memPattern[pattern.subject][pattern.property] &&
+ memPattern[pattern.subject][pattern.property][pattern.object] &&
+ memPattern[pattern.subject][pattern.property][pattern.object][pattern.optional]) {
+ return memPattern[pattern.subject][pattern.property][pattern.object][pattern.optional];
+ } else {
+ if (memPattern[pattern.subject] === undefined) {
+ memPattern[pattern.subject] = {};
+ }
+ if (memPattern[pattern.subject][pattern.property] === undefined) {
+ memPattern[pattern.subject][pattern.property] = {};
+ }
+ if (memPattern[pattern.subject][pattern.property][pattern.object] === undefined) {
+ memPattern[pattern.subject][pattern.property][pattern.object] = {};
+ }
+ memPattern[pattern.subject][pattern.property][pattern.object][pattern.optional] = pattern;
+ return pattern;
+ }
+ };
+
+ $.rdf.pattern.fn = $.rdf.pattern.prototype = {
+ init: function (s, p, o, options) {
+ var opts = $.extend({}, $.rdf.pattern.defaults, options);
+ /**
+ * The placeholder for the subject of triples matching against this pattern.
+ * @type String|jQuery.rdf.resource|jQuery.rdf.blank
+ */
+ this.subject = s.toString().substring(0, 1) === '?' ? s : subject(s, opts);
+ /**
+ * The placeholder for the property of triples matching against this pattern.
+ * @type String|jQuery.rdf.resource
+ */
+ this.property = p.toString().substring(0, 1) === '?' ? p : property(p, opts);
+ /**
+ * The placeholder for the object of triples matching against this pattern.
+ * @type String|jQuery.rdf.resource|jQuery.rdf.blank|jQuery.rdf.literal
+ */
+ this.object = o.toString().substring(0, 1) === '?' ? o : object(o, opts);
+ /**
+ * Whether the pattern should only optionally match against the triple
+ * @type boolean
+ */
+ this.optional = opts.optional;
+ return this;
+ },
+
+ /**
+ * Creates a new {@link jQuery.rdf.pattern} with any variable placeholders within this one's subject, property or object filled in with values from the bindings passed as the argument.
+ * @param {Object} bindings An object holding the variable bindings to be used to replace any placeholders in the pattern. These bindings are of the type held by the {@link jQuery.rdf} object.
+ * @returns {jQuery.rdf.pattern} A new {@link jQuery.rdf.pattern} object.
+ * @example
+ * pattern = $.rdf.pattern('?thing a ?class');
+ * // pattern2 matches all triples that indicate the classes of this page.
+ * pattern2 = pattern.fill({ thing: $.rdf.resource('<>') });
+ */
+ fill: function (bindings) {
+ var s = this.subject,
+ p = this.property,
+ o = this.object;
+ if (typeof s === 'string' && bindings[s.substring(1)]) {
+ s = bindings[s.substring(1)];
+ }
+ if (typeof p === 'string' && bindings[p.substring(1)]) {
+ p = bindings[p.substring(1)];
+ }
+ if (typeof o === 'string' && bindings[o.substring(1)]) {
+ o = bindings[o.substring(1)];
+ }
+ return $.rdf.pattern(s, p, o, { optional: this.optional });
+ },
+
+ /**
+ * Creates a new Object holding variable bindings by matching the passed triple against this pattern.
+ * @param {jQuery.rdf.triple} triple A {@link jQuery.rdf.triple} for this pattern to match against.
+ * @returns {null|Object} An object containing the bindings of variables (as specified in this pattern) to values (as specified in the triple), or null
if the triple doesn't match the pattern.
+ * pattern = $.rdf.pattern('?thing a ?class');
+ * bindings = pattern.exec($.rdf.triple('<> a foaf:Person', { namespaces: ns }));
+ * thing = bindings.thing; // the resource for this page
+ * class = bindings.class; // a resource for foaf:Person
+ */
+ exec: function (triple) {
+ var binding = {};
+ binding = testResource(triple.subject, this.subject, binding);
+ if (binding === null) {
+ return null;
+ }
+ binding = testResource(triple.property, this.property, binding);
+ if (binding === null) {
+ return null;
+ }
+ binding = testResource(triple.object, this.object, binding);
+ return binding;
+ },
+
+ /**
+ * Tests whether this pattern has any variable placeholders in it or not.
+ * @returns {boolean} True if the pattern doesn't contain any variable placeholders.
+ * @example
+ * $.rdf.pattern('?thing a ?class').isFixed(); // false
+ * $.rdf.pattern('<> a foaf:Person', { namespaces: ns }).isFixed(); // true
+ */
+ isFixed: function () {
+ return typeof this.subject !== 'string' &&
+ typeof this.property !== 'string' &&
+ typeof this.object !== 'string';
+ },
+
+ /**
+ * Creates a new triple based on the bindings passed to the pattern, if possible.
+ * @param {Object} bindings An object holding the variable bindings to be used to replace any placeholders in the pattern. These bindings are of the type held by the {@link jQuery.rdf} object.
+ * @returns {null|jQuery.rdf.triple} A new {@link jQuery.rdf.triple} object, or null if not all the variable placeholders in the pattern are specified in the bindings. The {@link jQuery.rdf.triple#source} of the generated triple is set to the string value of this pattern.
+ * @example
+ * pattern = $.rdf.pattern('?thing a ?class');
+ * // triple is a new triple '<> a foaf:Person'
+ * triple = pattern.triple({
+ * thing: $.rdf.resource('<>'),
+ * class: $.rdf.resource('foaf:Person', { namespaces: ns })
+ * });
+ */
+ triple: function (bindings) {
+ var t = this;
+ if (!this.isFixed()) {
+ t = this.fill(bindings);
+ }
+ if (t.isFixed()) {
+ return $.rdf.triple(t.subject, t.property, t.object, { source: this.toString() });
+ } else {
+ return null;
+ }
+ },
+
+ /**
+ * Returns a string representation of the pattern by concatenating the subject, property and object.
+ * @returns {String}
+ */
+ toString: function () {
+ return this.subject + ' ' + this.property + ' ' + this.object;
+ }
+ };
+
+ $.rdf.pattern.fn.init.prototype = $.rdf.pattern.fn;
+
+ $.rdf.pattern.defaults = {
+ base: $.uri.base(),
+ namespaces: {},
+ optional: false
+ };
+
+ /**
+ * Creates a new jQuery.rdf.triple object. This should be invoked as a method rather than constructed using new; indeed you will not usually want to generate these objects directly, since they are automatically created from strings where necessary, such as by {@link jQuery.rdf#add}.
+ * @class Represents an RDF triple. + * @param {String|jQuery.rdf.resource|jQuery.rdf.blank} subject The subject of the triple, or a single string that defines the entire triple. If the subject is specified as a string, it can be a fixed resource (<uri>
or curie
) or a blank node (_:id
).
+ * @param {String|jQuery.rdf.resource} [property] The property pattern. If the property is specified as a string, it must be a fixed resource (<uri>
or curie
).
+ * @param {String|jQuery.rdf.resource|jQuery.rdf.blank|jQuery.rdf.literal} [value] The value pattern. If the property is specified as a string, it can be a fixed resource (<uri>
or curie
), a blank node (_:id
), or a literal ("value"
).
+ * @param {Object} [options] Initialisation of the triple.
+ * @param {Object} [options.namespaces] An object representing a set of namespace bindings used when interpreting the CURIEs in the subject, property and object.
+ * @param {String|jQuery.uri} [options.base] The base URI used to interpret any relative URIs used within the subject, property and object.
+ * @returns {jQuery.rdf.triple} The newly-created triple.
+ * @throws {String} Errors if any of the strings are not in a recognised format.
+ * @example pattern = $.rdf.triple('<>', $.rdf.type, 'foaf:Person', { namespaces: { foaf: "http://xmlns.com/foaf/0.1/" }});
+ * @example
+ * pattern = $.rdf.triple('<> a foaf:Person', {
+ * namespaces: { foaf: "http://xmlns.com/foaf/0.1/" }
+ * });
+ * @see jQuery.rdf#add
+ * @see jQuery.rdf.resource
+ * @see jQuery.rdf.blank
+ * @see jQuery.rdf.literal
+ */
+ $.rdf.triple = function (subject, property, object, options) {
+ var triple, graph, m;
+ // using a two-argument version; first argument is a Turtle statement string
+ if (object === undefined) {
+ options = property;
+ m = $.trim(subject).match(tripleRegex);
+ if (m.length === 3 || (m.length === 4 && m[3] === '.')) {
+ subject = m[0];
+ property = m[1];
+ object = m[2];
+ } else {
+ throw "Bad Triple: Couldn't parse string " + subject;
+ }
+ }
+ graph = (options && options.graph) || '';
+ if (memTriple[graph] &&
+ memTriple[graph][subject] &&
+ memTriple[graph][subject][property] &&
+ memTriple[graph][subject][property][object]) {
+ return memTriple[graph][subject][property][object];
+ }
+ triple = new $.rdf.triple.fn.init(subject, property, object, options);
+ graph = triple.graph || '';
+ if (memTriple[graph] &&
+ memTriple[graph][triple.subject] &&
+ memTriple[graph][triple.subject][triple.property] &&
+ memTriple[graph][triple.subject][triple.property][triple.object]) {
+ return memTriple[graph][triple.subject][triple.property][triple.object];
+ } else {
+ if (memTriple[graph] === undefined) {
+ memTriple[graph] = {};
+ }
+ if (memTriple[graph][triple.subject] === undefined) {
+ memTriple[graph][triple.subject] = {};
+ }
+ if (memTriple[graph][triple.subject][triple.property] === undefined) {
+ memTriple[graph][triple.subject][triple.property] = {};
+ }
+ memTriple[graph][triple.subject][triple.property][triple.object] = triple;
+ return triple;
+ }
+ };
+
+ $.rdf.triple.fn = $.rdf.triple.prototype = {
+ init: function (s, p, o, options) {
+ var opts;
+ opts = $.extend({}, $.rdf.triple.defaults, options);
+ /**
+ * The subject of the triple.
+ * @type jQuery.rdf.resource|jQuery.rdf.blank
+ */
+ this.subject = subject(s, opts);
+ /**
+ * The property of the triple.
+ * @type jQuery.rdf.resource
+ */
+ this.property = property(p, opts);
+ /**
+ * The object of the triple.
+ * @type jQuery.rdf.resource|jQuery.rdf.blank|jQuery.rdf.literal
+ */
+ this.object = object(o, opts);
+ /**
+ * (Experimental) The named graph the triple belongs to.
+ * @type jQuery.rdf.resource|jQuery.rdf.blank
+ */
+ this.graph = opts.graph === undefined ? undefined : subject(opts.graph, opts);
+ /**
+ * The source of the triple, which might be a node within the page (if the RDF is generated from the page) or a string holding the pattern that generated the triple.
+ */
+ this.source = opts.source;
+ return this;
+ },
+
+ /**
+ * Always returns true for triples.
+ * @see jQuery.rdf.pattern#isFixed
+ */
+ isFixed: function () {
+ return true;
+ },
+
+ /**
+ * Always returns this triple.
+ * @see jQuery.rdf.pattern#triple
+ */
+ triple: function (bindings) {
+ return this;
+ },
+
+ /**
+ * Returns a RDF/JSON representation of this triple.
+ * @returns {Object}
+ */
+ dump: function () {
+ var e = {},
+ s = this.subject.value.toString(),
+ p = this.property.value.toString();
+ e[s] = {};
+ e[s][p] = this.object.dump();
+ return e;
+ },
+
+ /**
+ * Returns a string representing this triple in Turtle format.
+ * @returns {String}
+ */
+ toString: function () {
+ return this.subject + ' ' + this.property + ' ' + this.object + ' .';
+ }
+ };
+
+ $.rdf.triple.fn.init.prototype = $.rdf.triple.fn;
+
+ $.rdf.triple.defaults = {
+ base: $.uri.base(),
+ source: [document],
+ namespaces: {}
+ };
+
+ /**
+ * Creates a new jQuery.rdf.resource object. This should be invoked as a method rather than constructed using new; indeed you will not usually want to generate these objects directly, since they are automatically created from strings where necessary, such as by {@link jQuery.rdf#add}.
+ * @class Represents an RDF resource. + * @param {String|jQuery.uri} value The value of the resource. If it's a string it must be in the format<uri>
or curie
.
+ * @param {Object} [options] Initialisation of the resource.
+ * @param {Object} [options.namespaces] An object representing a set of namespace bindings used when interpreting the CURIE specifying the resource.
+ * @param {String|jQuery.uri} [options.base] The base URI used to interpret any relative URIs used within the URI specifying the resource.
+ * @returns {jQuery.rdf.resource} The newly-created resource.
+ * @throws {String} Errors if the string is not in a recognised format.
+ * @example thisPage = $.rdf.resource('<>');
+ * @example foaf.Person = $.rdf.resource('foaf:Person', { namespaces: ns });
+ * @see jQuery.rdf.pattern
+ * @see jQuery.rdf.triple
+ * @see jQuery.rdf.blank
+ * @see jQuery.rdf.literal
+ */
+ $.rdf.resource = function (value, options) {
+ var resource;
+ if (memResource[value]) {
+ return memResource[value];
+ }
+ resource = new $.rdf.resource.fn.init(value, options);
+ if (memResource[resource]) {
+ return memResource[resource];
+ } else {
+ memResource[resource] = resource;
+ return resource;
+ }
+ };
+
+ $.rdf.resource.fn = $.rdf.resource.prototype = {
+ /**
+ * Always fixed to 'uri' for resources.
+ * @type String
+ */
+ type: 'uri',
+ /**
+ * The URI for the resource.
+ * @type jQuery.rdf.uri
+ */
+ value: undefined,
+
+ init: function (value, options) {
+ var m, prefix, uri, opts;
+ if (typeof value === 'string') {
+ m = uriRegex.exec(value);
+ opts = $.extend({}, $.rdf.resource.defaults, options);
+ if (m !== null) {
+ this.value = $.uri.resolve(m[1].replace(/\\>/g, '>'), opts.base);
+ } else if (value.substring(0, 1) === ':') {
+ uri = opts.namespaces[''];
+ if (uri === undefined) {
+ throw "Malformed Resource: No namespace binding for default namespace in " + value;
+ } else {
+ this.value = $.uri.resolve(uri + value.substring(1));
+ }
+ } else if (value.substring(value.length - 1) === ':') {
+ prefix = value.substring(0, value.length - 1);
+ uri = opts.namespaces[prefix];
+ if (uri === undefined) {
+ throw "Malformed Resource: No namespace binding for prefix " + prefix + " in " + value;
+ } else {
+ this.value = $.uri.resolve(uri);
+ }
+ } else {
+ try {
+ this.value = $.curie(value, { namespaces: opts.namespaces });
+ } catch (e) {
+ throw "Malformed Resource: Bad format for resource " + e;
+ }
+ }
+ } else {
+ this.value = value;
+ }
+ return this;
+ }, // end init
+
+ /**
+ * Returns a RDF/JSON representation of this triple.
+ * @returns {Object}
+ */
+ dump: function () {
+ return {
+ type: 'uri',
+ value: this.value.toString()
+ };
+ },
+
+ /**
+ * Returns a string representing this resource in Turtle format.
+ * @returns {String}
+ */
+ toString: function () {
+ return '<' + this.value + '>';
+ }
+ };
+
+ $.rdf.resource.fn.init.prototype = $.rdf.resource.fn;
+
+ $.rdf.resource.defaults = {
+ base: $.uri.base(),
+ namespaces: {}
+ };
+
+ /**
+ * A {@link jQuery.rdf.resource} for rdf:type
+ * @constant
+ * @type jQuery.rdf.resource
+ */
+ $.rdf.type = $.rdf.resource('<' + rdfNs + 'type>');
+ /**
+ * A {@link jQuery.rdf.resource} for rdfs:label
+ * @constant
+ * @type jQuery.rdf.resource
+ */
+ $.rdf.label = $.rdf.resource('<' + rdfsNs + 'label>');
+ /**
+ * A {@link jQuery.rdf.resource} for rdf:first
+ * @constant
+ * @type jQuery.rdf.resource
+ */
+ $.rdf.first = $.rdf.resource('<' + rdfNs + 'first>');
+ /**
+ * A {@link jQuery.rdf.resource} for rdf:rest
+ * @constant
+ * @type jQuery.rdf.resource
+ */
+ $.rdf.rest = $.rdf.resource('<' + rdfNs + 'rest>');
+ /**
+ * A {@link jQuery.rdf.resource} for rdf:nil
+ * @constant
+ * @type jQuery.rdf.resource
+ */
+ $.rdf.nil = $.rdf.resource('<' + rdfNs + 'nil>');
+ /**
+ * A {@link jQuery.rdf.resource} for rdf:subject
+ * @constant
+ * @type jQuery.rdf.resource
+ */
+ $.rdf.subject = $.rdf.resource('<' + rdfNs + 'subject>');
+ /**
+ * A {@link jQuery.rdf.resource} for rdf:property
+ * @constant
+ * @type jQuery.rdf.resource
+ */
+ $.rdf.property = $.rdf.resource('<' + rdfNs + 'property>');
+ /**
+ * A {@link jQuery.rdf.resource} for rdf:object
+ * @constant
+ * @type jQuery.rdf.resource
+ */
+ $.rdf.object = $.rdf.resource('<' + rdfNs + 'object>');
+
+ /**
+ * Creates a new jQuery.rdf.blank object. This should be invoked as a method rather than constructed using new; indeed you will not usually want to generate these objects directly, since they are automatically created from strings where necessary, such as by {@link jQuery.rdf#add}.
+ * @class Represents an RDF blank node. + * @param {String} value A representation of the blank node in the format_:id
or []
(which automatically creates a new blank node with a unique ID).
+ * @returns {jQuery.rdf.blank} The newly-created blank node.
+ * @throws {String} Errors if the string is not in a recognised format.
+ * @example newBlank = $.rdf.blank('[]');
+ * @example identifiedBlank = $.rdf.blank('_:fred');
+ * @see jQuery.rdf.pattern
+ * @see jQuery.rdf.triple
+ * @see jQuery.rdf.resource
+ * @see jQuery.rdf.literal
+ */
+ $.rdf.blank = function (value) {
+ var blank;
+ if (memBlank[value]) {
+ return memBlank[value];
+ }
+ blank = new $.rdf.blank.fn.init(value);
+ if (memBlank[blank]) {
+ return memBlank[blank];
+ } else {
+ memBlank[blank] = blank;
+ return blank;
+ }
+ };
+
+ $.rdf.blank.fn = $.rdf.blank.prototype = {
+ /**
+ * Always fixed to 'bnode' for blank nodes.
+ * @type String
+ */
+ type: 'bnode',
+ /**
+ * The value of the blank node in the format _:id
+ * @type String
+ */
+ value: undefined,
+ /**
+ * The id of the blank node.
+ * @type String
+ */
+ id: undefined,
+
+ init: function (value) {
+ if (value === '[]') {
+ this.id = blankNodeID();
+ this.value = '_:' + this.id;
+ } else if (value.substring(0, 2) === '_:') {
+ this.id = value.substring(2);
+ this.value = value;
+ } else {
+ throw "Malformed Blank Node: " + value + " is not a legal format for a blank node";
+ }
+ return this;
+ },
+
+ /**
+ * Returns a RDF/JSON representation of this blank node.
+ * @returns {Object}
+ */
+ dump: function () {
+ return {
+ type: 'bnode',
+ value: this.value
+ };
+ },
+
+ /**
+ * Returns the value this blank node.
+ * @returns {String}
+ */
+ toString: function () {
+ return this.value;
+ }
+ };
+
+ $.rdf.blank.fn.init.prototype = $.rdf.blank.fn;
+
+ /**
+ * Creates a new jQuery.rdf.literal object. This should be invoked as a method rather than constructed using new; indeed you will not usually want to generate these objects directly, since they are automatically created from strings where necessary, such as by {@link jQuery.rdf#add}.
+ * @class Represents an RDF literal. + * @param {String|boolean|Number} value Either the value of the literal or a string representation of it. If the datatype or lang options are specified, the value is taken as given. Otherwise, if it's a Javascript boolean or numeric value, it is interpreted as a value with a xsd:boolean or xsd:double datatype. In all other cases it's interpreted as a literal as defined in Turtle syntax. + * @param {Object} [options] Initialisation options for the literal. + * @param {String} [options.datatype] The datatype for the literal. This should be a safe CURIE; in other words, it can be in the formaturi
or [curie]
. Must not be specified if options.lang is also specified.
+ * @param {String} [options.lang] The language for the literal. Must not be specified if options.datatype is also specified.
+ * @param {Object} [options.namespaces] An object representing a set of namespace bindings used when interpreting a CURIE in the datatype.
+ * @param {String|jQuery.uri} [options.base] The base URI used to interpret a relative URI in the datatype.
+ * @returns {jQuery.rdf.literal} The newly-created literal.
+ * @throws {String} Errors if the string is not in a recognised format or if both options.datatype and options.lang are specified.
+ * @example trueLiteral = $.rdf.literal(true);
+ * @example numericLiteral = $.rdf.literal(5);
+ * @example dateLiteral = $.rdf.literal('"2009-07-13"^^xsd:date', { namespaces: ns });
+ * @see jQuery.rdf.pattern
+ * @see jQuery.rdf.triple
+ * @see jQuery.rdf.resource
+ * @see jQuery.rdf.blank
+ */
+ $.rdf.literal = function (value, options) {
+ var literal;
+ if (memLiteral[value]) {
+ return memLiteral[value];
+ }
+ literal = new $.rdf.literal.fn.init(value, options);
+ if (memLiteral[literal]) {
+ return memLiteral[literal];
+ } else {
+ memLiteral[literal] = literal;
+ return literal;
+ }
+ };
+
+ $.rdf.literal.fn = $.rdf.literal.prototype = {
+ /**
+ * Always fixed to 'literal' for literals.
+ * @type String
+ */
+ type: 'literal',
+ /**
+ * The value of the literal as a string.
+ * @type String
+ */
+ value: undefined,
+ /**
+ * The language of the literal, if it has one; otherwise undefined.
+ * @type String
+ */
+ lang: undefined,
+ /**
+ * The datatype of the literal, if it has one; otherwise undefined.
+ * @type jQuery.uri
+ */
+ datatype: undefined,
+
+ init: function (value, options) {
+ var
+ m, datatype,
+ opts = $.extend({}, $.rdf.literal.defaults, options);
+ if (opts.lang !== undefined && opts.datatype !== undefined) {
+ throw "Malformed Literal: Cannot define both a language and a datatype for a literal (" + value + ")";
+ }
+ if (opts.datatype !== undefined) {
+ datatype = $.safeCurie(opts.datatype, { namespaces: opts.namespaces });
+ $.extend(this, $.typedValue(value.toString(), datatype));
+ } else if (opts.lang !== undefined) {
+ this.value = value.toString();
+ this.lang = opts.lang;
+ } else if (typeof value === 'boolean') {
+ $.extend(this, $.typedValue(value.toString(), xsdNs + 'boolean'));
+ } else if (typeof value === 'number') {
+ $.extend(this, $.typedValue(value.toString(), xsdNs + 'double'));
+ } else if (value === 'true' || value === 'false') {
+ $.extend(this, $.typedValue(value, xsdNs + 'boolean'));
+ } else if ($.typedValue.valid(value, xsdNs + 'integer')) {
+ $.extend(this, $.typedValue(value, xsdNs + 'integer'));
+ } else if ($.typedValue.valid(value, xsdNs + 'decimal')) {
+ $.extend(this, $.typedValue(value, xsdNs + 'decimal'));
+ } else if ($.typedValue.valid(value, xsdNs + 'double') &&
+ !/^\s*([\-\+]?INF|NaN)\s*$/.test(value)) { // INF, -INF and NaN aren't valid literals in Turtle
+ $.extend(this, $.typedValue(value, xsdNs + 'double'));
+ } else {
+ m = literalRegex.exec(value);
+ if (m !== null) {
+ this.value = (m[2] || m[4]).replace(/\\"/g, '"');
+ if (m[9]) {
+ datatype = $.rdf.resource(m[9], opts);
+ $.extend(this, $.typedValue(this.value, datatype.value));
+ } else if (m[7]) {
+ this.lang = m[7];
+ }
+ } else {
+ throw "Malformed Literal: Couldn't recognise the value " + value;
+ }
+ }
+ return this;
+ }, // end init
+
+ /**
+ * Returns a RDF/JSON representation of this blank node.
+ * @returns {Object}
+ */
+ dump: function () {
+ var e = {
+ type: 'literal',
+ value: this.value.toString()
+ };
+ if (this.lang !== undefined) {
+ e.lang = this.lang;
+ } else if (this.datatype !== undefined) {
+ e.datatype = this.datatype.toString();
+ }
+ return e;
+ },
+
+ /**
+ * Returns a string representing this resource in Turtle format.
+ * @returns {String}
+ */
+ toString: function () {
+ var val = '"' + this.value + '"';
+ if (this.lang !== undefined) {
+ val += '@' + this.lang;
+ } else if (this.datatype !== undefined) {
+ val += '^^<' + this.datatype + '>';
+ }
+ return val;
+ }
+ };
+
+ $.rdf.literal.fn.init.prototype = $.rdf.literal.fn;
+
+ $.rdf.literal.defaults = {
+ base: $.uri.base(),
+ namespaces: {},
+ datatype: undefined,
+ lang: undefined
+ };
+
+})(jQuery);
+/*
+ * jQuery RDFa @VERSION
+ *
+ * Copyright (c) 2008,2009 Jeni Tennison
+ * Licensed under the MIT (MIT-LICENSE.txt)
+ *
+ * Depends:
+ * jquery.uri.js
+ * jquery.xmlns.js
+ * jquery.curie.js
+ * jquery.datatype.js
+ * jquery.rdf.js
+ */
+/**
+ * @fileOverview jQuery RDFa processing
+ * @author Jeni Tennison
+ * @copyright (c) 2008,2009 Jeni Tennison
+ * @license MIT license (MIT-LICENSE.txt)
+ * @version 1.0
+ * @requires jquery.uri.js
+ * @requires jquery.xmlns.js
+ * @requires jquery.curie.js
+ * @requires jquery.datatype.js
+ * @requires jquery.rdf.js
+ */
+(function ($) {
+
+ var
+ ns = {
+ rdf: "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
+ xsd: "http://www.w3.org/2001/XMLSchema#"
+ },
+
+ rdfXMLLiteral = ns.rdf + 'XMLLiteral',
+
+ rdfaCurieDefaults = $.fn.curie.defaults,
+
+ attRegex = /\s([^ =]+)\s*=\s*(?:"([^"]*)"|'([^']*)'|([^ >]+))/g,
+
+ docResource = $.rdf.resource('<>'),
+
+ parseEntities = function (string) {
+ var result = "", m, entity;
+ if (!/&/.test(string)) {
+ return string;
+ }
+ while (string.length > 0) {
+ m = /([^&]*)(&([^;]+);)(.*)/g.exec(string);
+ if (m === null) {
+ result += string;
+ break;
+ }
+ result += m[1];
+ entity = m[3];
+ string = m[4];
+ if (entity.charAt(0) === '#') {
+ if (entity.charAt(1) === 'x') {
+ result += String.fromCharCode(parseInt(entity.substring(2), 16));
+ } else {
+ result += String.fromCharCode(parseInt(entity.substring(1), 10));
+ }
+ } else {
+ switch(entity) {
+ case 'amp':
+ result += '&';
+ break;
+ case 'nbsp':
+ result += String.fromCharCode(160);
+ break;
+ case 'quot':
+ result += '"';
+ break;
+ case 'apos':
+ result += "'";
+ break;
+ default:
+ result += '&' + entity + ';';
+ }
+ }
+ }
+ return result;
+ },
+
+ getAttributes = function (elem) {
+ var i, e, a, tag, name, value, attMap, prefix,
+ ns = {}, atts = {};
+ e = elem[0];
+ ns[':length'] = 0;
+ if (e.attributes && e.attributes.getNamedItemNS) {
+ attMap = e.attributes;
+ for (i = 0; i < attMap.length; i += 1) {
+ a = attMap[i];
+ if (/^xmlns(:(.+))?$/.test(a.nodeName) && a.nodeValue !== '') {
+ prefix = /^xmlns(:(.+))?$/.exec(a.nodeName)[2] || '';
+ ns[prefix] = $.uri(a.nodeValue);
+ ns[':length'] += 1;
+ } else if (/rel|rev|lang|xml:lang/.test(a.nodeName)) {
+ atts[a.nodeName] = a.nodeValue === '' ? undefined : a.nodeValue;
+ } else if (/about|href|src|resource|property|typeof|content|datatype/.test(a.nodeName)) {
+ atts[a.nodeName] = a.nodeValue === null ? undefined : a.nodeValue;
+ }
+ }
+ } else {
+ tag = /<[^>]+>/.exec(e.outerHTML);
+ a = attRegex.exec(tag);
+ while (a !== null) {
+ name = a[1];
+ value = a[2] || a[3] || a[4];
+ if (/^xmlns/.test(name) && name !== 'xmlns:' && value !== '') {
+ prefix = /^xmlns(:(.+))?$/.exec(name)[2] || '';
+ ns[prefix] = $.uri(value);
+ ns[':length'] += 1;
+ } else if (/about|href|src|resource|property|typeof|content|datatype|rel|rev|lang|xml:lang/.test(name)) {
+ atts[name] = parseEntities(value);
+ }
+ a = attRegex.exec(tag);
+ }
+ attRegex.lastIndex = 0;
+ }
+ return { atts: atts, namespaces: ns };
+ },
+
+ getAttribute = function (elem, attr) {
+ var val = elem[0].getAttribute(attr);
+ if (attr === 'rev' || attr === 'rel' || attr === 'lang' || attr === 'xml:lang') {
+ val = val === '' ? undefined : val;
+ }
+ return val === null ? undefined : val;
+ },
+
+ resourceFromUri = function (uri) {
+ return $.rdf.resource(uri);
+ },
+
+ resourceFromCurie = function (curie, elem, options) {
+ if (curie.substring(0, 2) === '_:') {
+ return $.rdf.blank(curie);
+ } else {
+ try {
+ return resourceFromUri($.curie(curie, options));
+ } catch (e) {
+ return undefined;
+ }
+ }
+ },
+
+ resourceFromSafeCurie = function (safeCurie, elem, options) {
+ var m = /^\[([^\]]+)\]$/.exec(safeCurie),
+ base = options.base || elem.base();
+ return m ? resourceFromCurie(m[1], elem, options) : resourceFromUri($.uri(safeCurie, base));
+ },
+
+ resourcesFromCuries = function (curies, elem, options) {
+ var i, resource, resources = [];
+ curies = curies && curies.split ? curies.split(/[ \t\n\r\x0C]+/g) : [];
+ for (i = 0; i < curies.length; i += 1) {
+ if (curies[i] !== '') {
+ resource = resourceFromCurie(curies[i], elem, options);
+ if (resource !== undefined) {
+ resources.push(resource);
+ }
+ }
+ }
+ return resources;
+ },
+
+ removeCurie = function (curies, resource, options) {
+ var i, r, newCuries = [];
+ resource = resource.type === 'uri' ? resource : $.rdf.resource(resource, options);
+ curies = curies && curies.split ? curies.split(/\s+/) : [];
+ for (i = 0; i < curies.length; i += 1) {
+ if (curies[i] !== '') {
+ r = resourceFromCurie(curies[i], null, options);
+ if (r !== resource) {
+ newCuries.push(curies[i]);
+ }
+ }
+ }
+ return newCuries.reverse().join(' ');
+ },
+
+ getObjectResource = function (elem, context, relation) {
+ var r, resource, atts, curieOptions;
+ context = context || {};
+ atts = context.atts || getAttributes(elem).atts;
+ r = relation === undefined ? atts.rel !== undefined || atts.rev !== undefined : relation;
+ resource = atts.resource;
+ resource = resource === undefined ? atts.href : resource;
+ if (resource === undefined) {
+ resource = r ? $.rdf.blank('[]') : resource;
+ } else {
+ curieOptions = context.curieOptions || $.extend({}, rdfaCurieDefaults, { namespaces: elem.xmlns() });
+ resource = resourceFromSafeCurie(resource, elem, curieOptions);
+ }
+ return resource;
+ },
+
+ getSubject = function (elem, context, relation) {
+ var r, atts, curieOptions, subject, skip = false;
+ context = context || {};
+ atts = context.atts || getAttributes(elem).atts;
+ curieOptions = context.curieOptions || $.extend({}, rdfaCurieDefaults, { namespaces: elem.xmlns(), base: elem.base() });
+ r = relation === undefined ? atts.rel !== undefined || atts.rev !== undefined : relation;
+ if (atts.about !== undefined) {
+ subject = resourceFromSafeCurie(atts.about, elem, curieOptions);
+ }
+ if (subject === undefined && atts.src !== undefined) {
+ subject = resourceFromSafeCurie(atts.src, elem, curieOptions);
+ }
+ if (!r && subject === undefined && atts.resource !== undefined) {
+ subject = resourceFromSafeCurie(atts.resource, elem, curieOptions);
+ }
+ if (!r && subject === undefined && atts.href !== undefined) {
+ subject = resourceFromSafeCurie(atts.href, elem, curieOptions);
+ }
+ if (subject === undefined) {
+ if (/head|body/i.test(elem[0].nodeName)) {
+ subject = docResource;
+ } else if (atts['typeof'] !== undefined) {
+ subject = $.rdf.blank('[]');
+ } else if (elem[0].parentNode.nodeType === 1) {
+ subject = context.object || getObjectResource(elem.parent()) || getSubject(elem.parent()).subject;
+ skip = !r && atts.property === undefined;
+ } else {
+ subject = docResource;
+ }
+ }
+ return { subject: subject, skip: skip };
+ },
+
+ getLang = function (elem, context) {
+ var lang;
+ context = context || {};
+ if (context.atts) {
+ lang = context.atts.lang;
+ lang = lang || context.atts['xml:lang'];
+ } else {
+ lang = elem[0].getAttribute('lang');
+ lang = (lang === null || lang === '') ? elem[0].getAttribute('xml:lang') : lang;
+ lang = (lang === null || lang === '') ? undefined : lang;
+ }
+ if (lang === undefined) {
+ if (context.lang) {
+ lang = context.lang;
+ } else {
+ if (elem[0].parentNode.nodeType === 1) {
+ lang = getLang(elem.parent());
+ }
+ }
+ }
+ return lang;
+ },
+
+ entity = function (c) {
+ switch (c) {
+ case '<':
+ return '<';
+ case '"':
+ return '"';
+ case '&':
+ return '&';
+ }
+ },
+
+ serialize = function (elem, ignoreNs) {
+ var i, string = '', atts, a, name, ns, tag;
+ elem.contents().each(function () {
+ var j = $(this),
+ e = j[0];
+ if (e.nodeType === 1) { // tests whether the node is an element
+ name = e.nodeName.toLowerCase();
+ string += '<' + name;
+ if (e.outerHTML) {
+ tag = /<[^>]+>/.exec(e.outerHTML);
+ a = attRegex.exec(tag);
+ while (a !== null) {
+ if (!/^jQuery/.test(a[1])) {
+ string += ' ' + a[1] + '=';
+ string += a[2] ? a[3] : '"' + a[1] + '"';
+ }
+ a = attRegex.exec(tag);
+ }
+ attRegex.lastIndex = 0;
+ } else {
+ atts = e.attributes;
+ for (i = 0; i < atts.length; i += 1) {
+ a = atts.item(i);
+ string += ' ' + a.nodeName + '="';
+ string += a.nodeValue.replace(/[<"&]/g, entity);
+ string += '"';
+ }
+ }
+ if (!ignoreNs) {
+ ns = j.xmlns('');
+ if (ns !== undefined && j.attr('xmlns') === undefined) {
+ string += ' xmlns="' + ns + '"';
+ }
+ }
+ string += '>';
+ string += serialize(j, true);
+ string += '' + name + '>';
+ } else if (e.nodeType === 8) { // tests whether the node is a comment
+ string += '';
+ } else {
+ string += e.nodeValue;
+ }
+ });
+ return string;
+ },
+
+ rdfa = function (context) {
+ var i, subject, resource, lang, datatype, content,
+ types, object, triple, parent,
+ properties, rels, revs,
+ forward, backward,
+ triples = [],
+ attsAndNs, atts, namespaces, ns,
+ children = this.children();
+ context = context || {};
+ forward = context.forward || [];
+ backward = context.backward || [];
+ attsAndNs = getAttributes(this);
+ atts = attsAndNs.atts;
+ context.atts = atts;
+ namespaces = context.namespaces || this.xmlns();
+ if (attsAndNs.namespaces[':length'] > 0) {
+ namespaces = $.extend({}, namespaces);
+ for (ns in attsAndNs.namespaces) {
+ if (ns !== ':length') {
+ namespaces[ns] = attsAndNs.namespaces[ns];
+ }
+ }
+ }
+ context.curieOptions = $.extend({}, rdfaCurieDefaults, { namespaces: namespaces, base: this.base() });
+ subject = getSubject(this, context);
+ lang = getLang(this, context);
+ if (subject.skip) {
+ rels = context.forward;
+ revs = context.backward;
+ subject = context.subject;
+ resource = context.object;
+ } else {
+ subject = subject.subject;
+ if (forward.length > 0 || backward.length > 0) {
+ parent = context.subject || getSubject(this.parent()).subject;
+ for (i = 0; i < forward.length; i += 1) {
+ triple = $.rdf.triple(parent, forward[i], subject, { source: this[0] });
+ triples.push(triple);
+ }
+ for (i = 0; i < backward.length; i += 1) {
+ triple = $.rdf.triple(subject, backward[i], parent, { source: this[0] });
+ triples.push(triple);
+ }
+ }
+ resource = getObjectResource(this, context);
+ types = resourcesFromCuries(atts['typeof'], this, context.curieOptions);
+ for (i = 0; i < types.length; i += 1) {
+ triple = $.rdf.triple(subject, $.rdf.type, types[i], { source: this[0] });
+ triples.push(triple);
+ }
+ properties = resourcesFromCuries(atts.property, this, context.curieOptions);
+ if (properties.length > 0) {
+ datatype = atts.datatype;
+ content = atts.content;
+ if (datatype !== undefined && datatype !== '') {
+ datatype = $.curie(datatype, context.curieOptions);
+ if (datatype === rdfXMLLiteral) {
+ object = $.rdf.literal(serialize(this), { datatype: rdfXMLLiteral });
+ } else if (content !== undefined) {
+ object = $.rdf.literal(content, { datatype: datatype });
+ } else {
+ object = $.rdf.literal(this.text(), { datatype: datatype });
+ }
+ } else if (content !== undefined) {
+ if (lang === undefined) {
+ object = $.rdf.literal('"' + content + '"');
+ } else {
+ object = $.rdf.literal(content, { lang: lang });
+ }
+ } else if (children.length === 0 ||
+ datatype === '') {
+ lang = getLang(this, context);
+ if (lang === undefined) {
+ object = $.rdf.literal('"' + this.text() + '"');
+ } else {
+ object = $.rdf.literal(this.text(), { lang: lang });
+ }
+ } else {
+ object = $.rdf.literal(serialize(this), { datatype: rdfXMLLiteral });
+ }
+ for (i = 0; i < properties.length; i += 1) {
+ triple = $.rdf.triple(subject, properties[i], object, { source: this[0] });
+ triples.push(triple);
+ }
+ }
+ rels = resourcesFromCuries(atts.rel, this, context.curieOptions);
+ revs = resourcesFromCuries(atts.rev, this, context.curieOptions);
+ if (atts.resource !== undefined || atts.href !== undefined) {
+ // make the triples immediately
+ if (rels !== undefined) {
+ for (i = 0; i < rels.length; i += 1) {
+ triple = $.rdf.triple(subject, rels[i], resource, { source: this[0] });
+ triples.push(triple);
+ }
+ }
+ rels = [];
+ if (revs !== undefined) {
+ for (i = 0; i < revs.length; i += 1) {
+ triple = $.rdf.triple(resource, revs[i], subject, { source: this[0] });
+ triples.push(triple);
+ }
+ }
+ revs = [];
+ }
+ }
+ children.each(function () {
+ triples = triples.concat(rdfa.call($(this), { forward: rels, backward: revs, subject: subject, object: resource || subject, lang: lang, namespaces: namespaces }));
+ });
+ return triples;
+ },
+
+ gleaner = function (options) {
+ var type, atts;
+ if (options && options.about !== undefined) {
+ atts = getAttributes(this).atts;
+ if (options.about === null) {
+ return atts.property !== undefined ||
+ atts.rel !== undefined ||
+ atts.rev !== undefined ||
+ atts['typeof'] !== undefined;
+ } else {
+ return getSubject(this, {atts: atts}).subject.value === options.about;
+ }
+ } else if (options && options.type !== undefined) {
+ type = getAttribute(this, 'typeof');
+ if (type !== undefined) {
+ return options.type === null ? true : this.curie(type) === options.type;
+ }
+ return false;
+ } else {
+ return rdfa.call(this);
+ }
+ },
+
+ nsCounter = 1,
+
+ createCurieAttr = function (elem, attr, uri) {
+ var m, curie, value;
+ try {
+ curie = elem.createCurie(uri);
+ } catch (e) {
+ if (uri.toString() === rdfXMLLiteral) {
+ elem.attr('xmlns:rdf', ns.rdf);
+ curie = 'rdf:XMLLiteral';
+ } else {
+ m = /^(.+[\/#])([^#]+)$/.exec(uri);
+ elem.attr('xmlns:ns' + nsCounter, m[1]);
+ curie = 'ns' + nsCounter + ':' + m[2];
+ nsCounter += 1;
+ }
+ }
+ value = getAttribute(elem, attr);
+ if (value !== undefined) {
+ if ($.inArray(curie, value.split(/\s+/)) === -1) {
+ elem.attr(attr, value + ' ' + curie);
+ }
+ } else {
+ elem.attr(attr, curie);
+ }
+ },
+
+ createResourceAttr = function (elem, attr, resource) {
+ var ref;
+ if (resource.type === 'bnode') {
+ ref = '[_:' + resource.id + ']';
+ } else {
+ ref = $(elem).base().relative(resource.value);
+ }
+ elem.attr(attr, ref);
+ },
+
+ createSubjectAttr = function (elem, subject) {
+ var s = getSubject(elem).subject;
+ if (subject !== s) {
+ createResourceAttr(elem, 'about', subject);
+ }
+ elem.removeData('rdfa.subject');
+ },
+
+ createObjectAttr = function (elem, object) {
+ var o = getObjectResource(elem);
+ if (object !== o) {
+ createResourceAttr(elem, 'resource', object);
+ }
+ elem.removeData('rdfa.objectResource');
+ },
+
+ resetLang = function (elem, lang) {
+ elem.wrapInner('')
+ .children('span')
+ .attr('lang', lang);
+ return elem;
+ },
+
+ addRDFa = function (triple) {
+ var hasContent, hasRelation, hasRDFa, overridableObject, span,
+ subject, sameSubject,
+ object, sameObject,
+ lang, content,
+ i, atts,
+ ns = this.xmlns();
+ span = this;
+ atts = getAttributes(this).atts;
+ if (typeof triple === 'string') {
+ triple = $.rdf.triple(triple, { namespaces: ns, base: this.base() });
+ } else if (triple.rdfquery) {
+ addRDFa.call(this, triple.sources().get(0));
+ return this;
+ } else if (triple.length) {
+ for (i = 0; i < triple.length; i += 1) {
+ addRDFa.call(this, triple[i]);
+ }
+ return this;
+ }
+ hasRelation = atts.rel !== undefined || atts.rev !== undefined;
+ hasRDFa = hasRelation || atts.property !== undefined || atts['typeof'] !== undefined;
+ if (triple.object.type !== 'literal') {
+ subject = getSubject(this, {atts: atts}, true).subject;
+ object = getObjectResource(this, {atts: atts}, true);
+ overridableObject = !hasRDFa && atts.resource === undefined;
+ sameSubject = subject === triple.subject;
+ sameObject = object === triple.object;
+ if (triple.property === $.rdf.type) {
+ if (sameSubject) {
+ createCurieAttr(this, 'typeof', triple.object.value);
+ } else if (hasRDFa) {
+ span = this.wrapInner('').children('span');
+ createCurieAttr(span, 'typeof', triple.object.value);
+ if (object !== triple.subject) {
+ createSubjectAttr(span, triple.subject);
+ }
+ } else {
+ createCurieAttr(this, 'typeof', triple.object.value);
+ createSubjectAttr(this, triple.subject);
+ }
+ } else if (sameSubject) {
+ // use a rel
+ if (sameObject) {
+ createCurieAttr(this, 'rel', triple.property.value);
+ } else if (overridableObject || !hasRDFa) {
+ createCurieAttr(this, 'rel', triple.property.value);
+ createObjectAttr(this, triple.object);
+ } else {
+ span = this.wrap('').parent();
+ createCurieAttr(span, 'rev', triple.property.value);
+ createSubjectAttr(span, triple.object);
+ }
+ } else if (subject === triple.object) {
+ if (object === triple.subject) {
+ // use a rev
+ createCurieAttr(this, 'rev', triple.property.value);
+ } else if (overridableObject || !hasRDFa) {
+ createCurieAttr(this, 'rev', triple.property.value);
+ createObjectAttr(this, triple.subject);
+ } else {
+ // wrap in a span with a rel
+ span = this.wrap('').parent();
+ createCurieAttr(span, 'rel', triple.property.value);
+ createSubjectAttr(span, triple.subject);
+ }
+ } else if (sameObject) {
+ if (hasRDFa) {
+ // use a rev on a nested span
+ span = this.wrapInner('').children('span');
+ createCurieAttr(span, 'rev', triple.property.value);
+ createObjectAttr(span, triple.subject);
+ span = span.wrapInner('').children('span');
+ createSubjectAttr(span, triple.object);
+ span = this;
+ } else {
+ createSubjectAttr(this, triple.subject);
+ createCurieAttr(this, 'rel', triple.property.value);
+ }
+ } else if (object === triple.subject) {
+ if (hasRDFa) {
+ // wrap the contents in a span and use a rel
+ span = this.wrapInner('').children('span');
+ createCurieAttr(span, 'rel', this.property.value);
+ createObjectAttr(span, triple.object);
+ span = span.wrapInner('').children('span');
+ createSubjectAttr(span, object);
+ span = this;
+ } else {
+ // use a rev on this element
+ createSubjectAttr(this, triple.object);
+ createCurieAttr(this, 'rev', triple.property.value);
+ }
+ } else if (hasRDFa) {
+ span = this.wrapInner('').children('span');
+ createCurieAttr(span, 'rel', triple.property.value);
+ createSubjectAttr(span, triple.subject);
+ createObjectAttr(span, triple.object);
+ if (span.children('*').length > 0) {
+ span = this.wrapInner('').children('span');
+ createSubjectAttr(span, subject);
+ }
+ span = this;
+ } else {
+ createCurieAttr(span, 'rel', triple.property.value);
+ createSubjectAttr(this, triple.subject);
+ createObjectAttr(this, triple.object);
+ if (this.children('*').length > 0) {
+ span = this.wrapInner('').children('span');
+ createSubjectAttr(span, subject);
+ span = this;
+ }
+ }
+ } else {
+ subject = getSubject(this, {atts: atts}).subject;
+ object = getObjectResource(this, {atts: atts});
+ sameSubject = subject === triple.subject;
+ hasContent = this.text() !== triple.object.value;
+ if (atts.property !== undefined) {
+ content = atts.content;
+ sameObject = content !== undefined ? content === triple.object.value : !hasContent;
+ if (sameSubject && sameObject) {
+ createCurieAttr(this, 'property', triple.property.value);
+ } else {
+ span = this.wrapInner('').children('span');
+ return addRDFa.call(span, triple);
+ }
+ } else {
+ if (object === triple.subject) {
+ span = this.wrapInner('').children('span');
+ return addRDFa.call(span, triple);
+ }
+ createCurieAttr(this, 'property', triple.property.value);
+ createSubjectAttr(this, triple.subject);
+ if (hasContent) {
+ if (triple.object.datatype && triple.object.datatype.toString() === rdfXMLLiteral) {
+ this.html(triple.object.value);
+ } else {
+ this.attr('content', triple.object.value);
+ }
+ }
+ lang = getLang(this);
+ if (triple.object.lang) {
+ if (lang !== triple.object.lang) {
+ this.attr('lang', triple.object.lang);
+ if (hasContent) {
+ resetLang(this, lang);
+ }
+ }
+ } else if (triple.object.datatype) {
+ createCurieAttr(this, 'datatype', triple.object.datatype);
+ } else {
+ // the empty datatype ensures that any child elements that might be added won't mess up this triple
+ if (!hasContent) {
+ this.attr('datatype', '');
+ }
+ // the empty lang ensures that a language won't be assigned to the literal
+ if (lang !== undefined) {
+ this.attr('lang', '');
+ if (hasContent) {
+ resetLang(this, lang);
+ }
+ }
+ }
+ }
+ }
+ this.parents().andSelf().trigger("rdfChange");
+ return span;
+ },
+
+ removeRDFa = function (what) {
+ var span, atts, property, rel, rev, type,
+ ns = this.xmlns();
+ atts = getAttributes(this).atts;
+ if (what.length) {
+ for (i = 0; i < what.length; i += 1) {
+ removeRDFa.call(this, what[i]);
+ }
+ return this;
+ }
+ hasRelation = atts.rel !== undefined || atts.rev !== undefined;
+ hasRDFa = hasRelation || atts.property !== undefined || atts['typeof'] !== undefined;
+ if (hasRDFa) {
+ if (what.property !== undefined) {
+ if (atts.property !== undefined) {
+ property = removeCurie(atts.property, what.property, { namespaces: ns });
+ if (property === '') {
+ this.removeAttr('property');
+ } else {
+ this.attr('property', property);
+ }
+ }
+ if (atts.rel !== undefined) {
+ rel = removeCurie(atts.rel, what.property, { namespaces: ns });
+ if (rel === '') {
+ this.removeAttr('rel');
+ } else {
+ this.attr('rel', rel);
+ }
+ }
+ if (atts.rev !== undefined) {
+ rev = removeCurie(atts.rev, what.property, { namespaces: ns });
+ if (rev === '') {
+ this.removeAttr('rev');
+ } else {
+ this.attr('rev', rev);
+ }
+ }
+ }
+ if (what.type !== undefined) {
+ if (atts['typeof'] !== undefined) {
+ type = removeCurie(atts['typeof'], what.type, { namespaces: ns });
+ if (type === '') {
+ this.removeAttr('typeof');
+ } else {
+ this.attr('typeof', type);
+ }
+ }
+ }
+ if (atts.property === this.attr('property') && atts.rel === this.attr('rel') && atts.rev === this.attr('rev') && atts['typeof'] === this.attr('typeof')) {
+ return removeRDFa.call(this.parent(), what);
+ }
+ }
+ this.parents().andSelf().trigger("rdfChange");
+ return this;
+ };
+
+ /**
+ * Creates a {@link jQuery.rdf} object containing the RDF triples parsed from the RDFa found in the current jQuery selection or adds the specified triple as RDFa markup on each member of the current jQuery selection. To create an {@link jQuery.rdf} object, you will usually want to use {@link jQuery#rdf} instead, as this may perform other useful processing (such as of microformats used within the page).
+ * @methodOf jQuery#
+ * @name jQuery#rdfa
+ * @param {jQuery.rdf.triple} [triple] The RDF triple to be added to each item in the jQuery selection.
+ * @returns {jQuery.rdf}
+ * @example
+ * // Extract RDFa markup from all span elements contained inside #main
+ * rdf = $('#main > span').rdfa();
+ * @example
+ * // Add RDFa markup to a particular element
+ * var span = $('#main > p > span');
+ * span.rdfa('<> dc:date "2008-10-19"^^xsd:date .');
+ */
+ $.fn.rdfa = function (triple) {
+ if (triple === undefined) {
+ var triples = $.map($(this), function (elem) {
+ return rdfa.call($(elem));
+ });
+ return $.rdf({ triples: triples });
+ } else {
+ $(this).each(function () {
+ addRDFa.call($(this), triple);
+ });
+ return this;
+ }
+ };
+
+ /**
+ * Removes the specified RDFa markup from each of the items in the current jQuery selection. The input parameter can be either an object or an array of objects. The objects can either have a type
property, in which case the specified type is removed from the RDFa provided on the selected elements, or a property
property, in which case the specified property is removed from the RDFa provided on the selected elements.
+ * @methodOf jQuery#
+ * @name jQuery#removeRdfa
+ * @param {Object|Object[]} triple The RDFa markup items to be removed
+ * from the items in the jQuery selection.
+ * @returns {jQuery} The original jQuery object.
+ * @example
+ * // To remove a property resource or relation from an element
+ * $('#main > p > a').removeRdfa({ property: "dc:creator" });
+ * @example
+ * // To remove a type from an element
+ * $('#main >p > a').removeRdfa({ type: "foaf:Person" });
+ * @example
+ * // To remove multiple triples from an element
+ * $('#main > p > a').removeRdfa([{ property: "foaf:depicts" }, { property: "dc:creator" }]);
+ */
+ $.fn.removeRdfa = function (triple) {
+ $(this).each(function () {
+ removeRDFa.call($(this), triple);
+ });
+ return this;
+ };
+
+ $.rdf.gleaners.push(gleaner);
+
+})(jQuery);
diff --git a/manifest.json b/manifest.json
index ce251b8..7b208b4 100644
--- a/manifest.json
+++ b/manifest.json
@@ -1,9 +1,8 @@
{
"manifest_version": 2,
-
"name": "LOD-check",
"description": "Checks pages as you browse for the presence of Linked Open Data behind them and reveals the underlying data.",
- "version": "1.1.3",
+ "version": "1.1.4",
"permissions": [
"webRequest",
"