Update to latest jsonld.js.
authorDave Longley <dlongley@digitalbazaar.com>
Sun, 10 Feb 2013 14:20:21 -0500
changeset 1201 c4d7e435ac1e
parent 1200 76364dc5ae26
child 1202 461c2ef66d72
Update to latest jsonld.js.
playground/jsonld.js
--- 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;
 }
 
 /**