--- a/playground/jsonld.js Sun Feb 10 14:18:42 2013 -0500
+++ b/playground/jsonld.js Sun Feb 10 14:20:21 2013 -0500
@@ -861,14 +861,27 @@
/**
* The built-in jquery URL resolver.
+ *
+ * @param $ the jquery instance to use.
+ * @param options the options to use:
+ * secure: require all URLs to use HTTPS.
+ *
+ * @return the jquery URL resolver.
*/
-jsonld.urlResolvers['jquery'] = function($) {
+jsonld.urlResolvers['jquery'] = function($, options) {
var cache = new jsonld.ContextCache();
return function(url, callback) {
var ctx = cache.get(url);
if(ctx !== null) {
return callback(null, ctx);
}
+ options = options || {};
+ if(options.secure && url.indexOf('https') !== 0) {
+ return callback(new JsonLdError(
+ 'URL could not be dereferenced; secure mode is enabled and ' +
+ 'the URL\'s scheme is not "https".',
+ 'jsonld.InvalidUrl', {url: url}));
+ }
$.ajax({
url: url,
dataType: 'json',
@@ -886,8 +899,13 @@
/**
* The built-in node URL resolver.
+ *
+ * @param options the optionst o use:
+ * secure: require all URLs to use HTTPS.
+ *
+ * @return the node URL resolver.
*/
-jsonld.urlResolvers['node'] = function() {
+jsonld.urlResolvers['node'] = function(options) {
var request = require('request');
var http = require('http');
var cache = new jsonld.ContextCache();
@@ -896,6 +914,13 @@
if(ctx !== null) {
return callback(null, ctx);
}
+ options = options || {};
+ if(options.secure && url.indexOf('https') !== 0) {
+ return callback(new JsonLdError(
+ 'URL could not be dereferenced; secure mode is enabled and ' +
+ 'the URL\'s scheme is not "https".',
+ 'jsonld.InvalidUrl', {url: url}));
+ }
request(url, function(err, res, body) {
if(!err && res.statusCode >= 400) {
var statusText = http.STATUS_CODES[res.statusCode];
@@ -934,7 +959,6 @@
jsonld, Array.prototype.slice.call(arguments, 1));
};
-
/**
* Processes a local context, resolving any URLs as necessary, and returns a
* new active context in its callback.
@@ -1471,7 +1495,7 @@
// preserve empty arrays
if(expandedValue.length === 0) {
var activeProperty = _compactIri(
- activeCtx, expandedProperty, null, {vocab: true}, element);
+ activeCtx, expandedProperty, [], {vocab: true}, element);
jsonld.addValue(rval, activeProperty, [], {propertyIsArray: true});
}
@@ -1489,8 +1513,9 @@
// property generator
var mapping = activeCtx.mappings[activeProperty];
if(mapping && mapping.propertyGenerator) {
- _findAndRemovePropertyGeneratorDuplicates(
- activeCtx, element, expandedProperty, expandedItem, activeProperty);
+ _findPropertyGeneratorDuplicates(
+ activeCtx, element, expandedProperty, expandedItem, activeProperty,
+ true);
}
// get @list value if appropriate
@@ -3376,7 +3401,7 @@
if(!_isArray(preserve)) {
preserve = [preserve];
}
- output[prop] = [{'@preserve': [preserve]}];
+ output[prop] = [{'@preserve': preserve}];
}
}
@@ -3707,14 +3732,8 @@
if(_isObject(parent)) {
for(var pi = 0; pi < termInfo.propertyGenerators.length; ++pi) {
var propertyGenerator = termInfo.propertyGenerators[pi];
- var iris = activeCtx.mappings[propertyGenerator]['@id'];
- var match = true;
- for(var ii = 0; ii < iris.length; ++ii) {
- if(!(iris[ii] in parent)) {
- match = false;
- break;
- }
- }
+ var match = _findPropertyGeneratorDuplicates(
+ activeCtx, parent, iri, value, propertyGenerator, false);
if(match) {
term = propertyGenerator;
break;
@@ -3728,6 +3747,7 @@
}
}
}
+
return term;
}
@@ -3846,7 +3866,7 @@
typeOrLanguageValue = value['@type'];
}
}
- else {
+ else if(_isObject(value)) {
typeOrLanguage = '@type';
typeOrLanguageValue = '@id';
}
@@ -4002,40 +4022,69 @@
}
/**
- * Finds and removes any duplicate values that were presumably generated by
- * a property generator in the given element.
+ * Finds and, if specified, removes any duplicate values that were presumably
+ * generated by a property generator in the given element.
*
* @param activeCtx the active context.
* @param element the element to remove duplicates from.
* @param expandedProperty the property to map to a property generator.
* @param value the value to compare against when duplicate checking.
* @param activeProperty the property generator term.
+ * @param remove true to remove the duplicates found, false not to.
+ *
+ * @return true if duplicates were found for every IRI.
*/
-function _findAndRemovePropertyGeneratorDuplicates(
- activeCtx, element, expandedProperty, value, activeProperty) {
+function _findPropertyGeneratorDuplicates(
+ activeCtx, element, expandedProperty, value, activeProperty, remove) {
+ var rval = true;
+
// get property generator IRIs
var iris = activeCtx.mappings[activeProperty]['@id'];
// for each IRI that isn't 'expandedProperty', remove a single duplicate
// from element, if found
- for(var i = 0; i < iris.length; ++i) {
+ for(var i = 0; rval && i < iris.length; ++i) {
var iri = iris[i];
if(iri === expandedProperty) {
continue;
}
+
+ rval = false;
+ if(!(iri in element)) {
+ break;
+ }
+
var prospects = element[iri];
+
+ // handle empty array case
+ if(prospects.length === 0 && _isArray(value) && value.length === 0) {
+ rval = true;
+ if(remove) {
+ delete element[iri];
+ }
+ continue;
+ }
+
+ // handle other cases
for(var pi = 0; pi < prospects.length; ++pi) {
var prospect = prospects[pi];
if(jsonld.compareValues(prospect, value)) {
- // duplicate found, remove it in place
- prospects.splice(pi, 1);
- if(prospects.length === 0) {
- delete element[iri];
+ // duplicate found
+ rval = true;
+
+ if(remove) {
+ // remove it in place
+ prospects.splice(pi, 1);
+ if(prospects.length === 0) {
+ delete element[iri];
+ }
}
break;
}
}
}
+
+ return rval;
}
/**