diff --git a/background.js b/background.js index b5ed7d9..551ebae 100644 --- a/background.js +++ b/background.js @@ -1,7 +1,25 @@ chrome.runtime.onMessage.addListener( function(request, sender, sendResponse) { console.log("Message from content: " + request); + var messages = { + 'error': 'Error parsing RDF', + 'unlicensed': 'No machine readable licensing', + 'licensed': 'License declared' + }; + chrome.pageAction.setTitle({ + tabId: sender.tab.id, + title: messages[request.check] + }); + var icon = { + 'error': 'red', + 'unlicensed': 'amber', + 'licensed': 'green' + }; chrome.pageAction.show(sender.tab.id); + chrome.pageAction.setIcon({ + tabId: sender.tab.id, + path: 'pageIcon-' + icon[request.check] + '.png' + }); sendResponse({text: "ok"}); } ); diff --git a/contentscript.js b/contentscript.js index f95781d..4d5ff85 100644 --- a/contentscript.js +++ b/contentscript.js @@ -1,50 +1,103 @@ -function peelBackRdf(data) { +function peelBackRdf(data, format) { $('body').prepend('
'); $('#code').text(data); var cm = CodeMirror.fromTextArea($('#code')[0], { - mode: "xml", - readOnly: "nocursor" + mode: format, + readOnly: "nocursor", + viewportMargin: Infinity }); $('#target').fold({ - directory: "chrome-extension://" + chrome.runtime.id + directory: "chrome-extension://" + chrome.runtime.id, + autoCurl: true }); + $('#turn_wrapper').click( + function() { + $('#turn_fold').hide(); + $('#turn_wrapper').width('100%').height('100%').off(); + $('#turn_object').width('100%').height('100%').off(); + $('#turn_hideme').width('100%').height('100%').off(); + } + ); +} + +function checkRdf(data, format) { + var parser = new DOMParser(); + doc = parser.parseFromString(data, 'text/xml'); + try { + var rdf = $.rdf().load(doc); + var licenses = rdf + .prefix('cc', 'http://creativecommons.org/ns#') + .where('?doc cc:license ?license'); + licenses = licenses.add( + rdf + .prefix('dct', 'http://purl.org/dc/terms/') + .where('?doc dct:license ?license') + ); + if (licenses.select().length > 0) { + return 'licensed'; + } else { + return 'unlicensed'; + } + } catch (e) { + console.log(e); + return 'error'; + } } 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 (res.snapshotItem(i).type == "application/rdf+xml") { - console.log("Found link rel=(alternate|meta) type=application/rdf+xml"); + if (acceptFormats.indexOf(res.snapshotItem(i).type) > -1) { + rdfFormat = res.snapshotItem(i).type; rdfUrl = res.snapshotItem(i).href; // relative - chrome.runtime.sendMessage({type: 'rdf+xml'}, function(response) { - console.log(response.text); - }); break; } } if (rdfUrl == null) { // Try fetching current page as RDF $.ajax(document.URL, { - accepts: { text: 'application/rdf+xml' }, + headers: { + Accept: acceptFormats.join(', ') + }, dataType: 'text', success: function(data, textStatus, res) { var ct = res.getResponseHeader('Content-Type'); - if ((ct != null) && (ct.slice(0, 'application/rdf+xml'.length) == 'application/rdf+xml')) { - chrome.runtime.sendMessage({type: 'rdf+xml'}, function(response) { - console.log(response.text); - }); - peelBackRdf(data); + if (ct != null) { + var format = null; + for (var i = 0; i < acceptFormats.length; i++) { + if (ct.slice(0, acceptFormats[i].length) == acceptFormats[i]) { + format = acceptFormats[i]; + break; + } + } + if (format != null) { + peelBackRdf(data, format); + chrome.runtime.sendMessage({ + type: format, + check: checkRdf(data, format) + }, function(response) { + console.log(response.text); + }); + } } } }); } else { $.ajax(rdfUrl, { - accepts: { text: 'application/rdf+xml' }, + accepts: { text: rdfFormat }, dataType: 'text', success: function(data, textStatus, res) { - peelBackRdf(data); + peelBackRdf(data, rdfFormat); + chrome.runtime.sendMessage({ + type: format, + check: checkRdf(data, rdfFormat) + }, function(response) { + console.log(response.text); + }); } }); } diff --git a/custom.css b/custom.css index 6a593fe..ca2c2de 100644 --- a/custom.css +++ b/custom.css @@ -13,6 +13,11 @@ } .CodeMirror { - height: 800px; - width: 800px; + border: 1px solid #eee; + height: auto; +} + +.CodeMirror-scroll { + overflow-y: hidden; + overflow-x: auto; } \ No newline at end of file diff --git a/fold.svg b/fold.svg new file mode 100644 index 0000000..eef95a9 --- /dev/null +++ b/fold.svg @@ -0,0 +1,152 @@ + + + + diff --git a/jquery.rdfquery.core-1.0.js b/jquery.rdfquery.core-1.0.js new file mode 100644 index 0000000..65fff47 --- /dev/null +++ b/jquery.rdfquery.core-1.0.js @@ -0,0 +1,3598 @@ +/* + * $ 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/manifest.json b/manifest.json
index 68766ff..90d913c 100644
--- a/manifest.json
+++ b/manifest.json
@@ -4,7 +4,11 @@
"name": "RES-check",
"description": "Highlight RESable pages.",
"version": "1.0",
-
+ "icons": {
+ "16": "package-icon-16.png",
+ "48": "package-icon-48.png",
+ "128": "package-icon-128.png"
+ },
"page_action": {
"default_icon": {
"19": "r-icon.png"
@@ -20,7 +24,7 @@
"http://*/*",
"https://*/*"
],
- "js": [ "jquery.min.js", "jquery-ui.min.js", "turn.js", "codemirror-compressed.js", "jquery.rdfquery.core.min-1.0.js", "contentscript.js" ],
+ "js": [ "jquery.min.js", "jquery-ui.min.js", "turn.js", "codemirror-compressed.js", "jquery.rdfquery.core-1.0.js", "contentscript.js" ],
"css": [ "turn.css", "codemirror.css", "custom.css" ],
"run_at" : "document_idle",
"all_frames" : false
diff --git a/package-icon-128.png b/package-icon-128.png
new file mode 100644
index 0000000..c8a3928
--- /dev/null
+++ b/package-icon-128.png
Binary files differ
diff --git a/package-icon-16.png b/package-icon-16.png
new file mode 100644
index 0000000..68afa3d
--- /dev/null
+++ b/package-icon-16.png
Binary files differ
diff --git a/package-icon-48.png b/package-icon-48.png
new file mode 100644
index 0000000..5e9b0e2
--- /dev/null
+++ b/package-icon-48.png
Binary files differ
diff --git a/package-icon.svg b/package-icon.svg
new file mode 100644
index 0000000..2332aad
--- /dev/null
+++ b/package-icon.svg
@@ -0,0 +1,442 @@
+
+
+
+
diff --git a/pageIcon-amber.png b/pageIcon-amber.png
new file mode 100644
index 0000000..9c0ac52
--- /dev/null
+++ b/pageIcon-amber.png
Binary files differ
diff --git a/pageIcon-green.png b/pageIcon-green.png
new file mode 100644
index 0000000..c5e5f10
--- /dev/null
+++ b/pageIcon-green.png
Binary files differ
diff --git a/pageIcon-red.png b/pageIcon-red.png
new file mode 100644
index 0000000..82fada4
--- /dev/null
+++ b/pageIcon-red.png
Binary files differ