Add query parameter data loader and data permalink.
- Can load JSON-LD markup and/or frame data from query parameters.
- JSON-LD markup comes from "json-ld" query parameter.
- Frame comes from "frame" query parameter.
- Parameters can be encoded JSON strings or remote URLs.
- Due to same origin issues, remote URLs must be CORS enabled.
- Provide a permalink for current data that uses query parameters.
--- a/playground/index.html Thu Jul 14 12:09:06 2011 -0700
+++ b/playground/index.html Fri Jul 15 16:22:36 2011 -0400
@@ -47,23 +47,23 @@
<ul id="examples">
<li class="button-list">Simple Examples:</li>
<li class="button">
- <span onmousedown="playground.populate('Person')">Person</span>
- </li>
- <li class="button">
- <span onmousedown="playground.populate('Event')">Event</span>
+ <span onmousedown="playground.populateWithExample('Person')">Person</span>
</li>
<li class="button">
- <span onmousedown="playground.populate('Place')">Place</span>
+ <span onmousedown="playground.populateWithExample('Event')">Event</span>
</li>
<li class="button">
- <span onmousedown="playground.populate('Product')">Product</span>
+ <span onmousedown="playground.populateWithExample('Place')">Place</span>
</li>
<li class="button">
- <span onmousedown="playground.populate('Recipe')">Recipe</span>
+ <span onmousedown="playground.populateWithExample('Product')">Product</span>
+ </li>
+ <li class="button">
+ <span onmousedown="playground.populateWithExample('Recipe')">Recipe</span>
</li>
<li class="button-list">Framing Examples:</li>
<li class="button">
- <span onmousedown="playground.populate('Library')">Library</span>
+ <span onmousedown="playground.populateWithExample('Library')">Library</span>
</li>
</ul><br />
@@ -76,6 +76,8 @@
onkeyup="playground.process()"></textarea>
</div>
+ <div id="permalink"></div>
+
<div id="markup-errors" class="errors"></div>
<div id="frame-errors" class="errors"></div>
--- a/playground/playground.css Thu Jul 14 12:09:06 2011 -0700
+++ b/playground/playground.css Fri Jul 15 16:22:36 2011 -0400
@@ -69,3 +69,6 @@
padding: 6px 0 4px 18px; /* push text down 1px */
}
+#permalink {
+ text-align: right;
+}
--- a/playground/playground.js Thu Jul 14 12:09:06 2011 -0700
+++ b/playground/playground.js Fri Jul 15 16:22:36 2011 -0400
@@ -35,16 +35,110 @@
">": "gt"
}[c] + ";";
});
- }
+ };
+
/**
- * Used to initialize the UI, call once a document load.
+ * Get a query parameter by name.
+ *
+ * Code from:
+ * http://stackoverflow.com/questions/901115/get-query-string-values-in-javascript/5158301#5158301
+ *
+ * @param name a query parameter name.
+ *
+ * @return the value of the parameter or null if it does not exist
+ */
+ function getParameterByName(name) {
+ var match = RegExp('[?&]' + name + '=([^&]*)')
+ .exec(window.location.search);
+ return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
+ };
+
+ /**
+ * Handle URL query parameters.
+ *
+ * Checks "json-ld" and "frame" parameters. If they look like JSON then
+ * interpret as JSON strings else interpret as URLs of remote resources.
+ * Note: URLs must be CORS enabled to load due to browser same origin policy
+ * issues.
+ */
+ playground.processQueryParameters = function()
+ {
+ // data from the query
+ var queryData = {
+ markup: null,
+ frame: null
+ };
+
+ /**
+ * Read a parameter as JSON or created an jQuery AJAX Deferred call
+ * to read the data.
+ *
+ * @param param a query parameter value.
+ * @param fieldName the field name to populate in queryData object.
+ * @param msgName the param name to use in UI messages.
+ *
+ * @return jQuery Deferred or null
+ */
+ function handleParameter(param, fieldName, msgName)
+ {
+ // the ajax deferred or null
+ var rval = null;
+
+ // check "json-ld" parameter
+ if(param !== null)
+ {
+ hasQueryData = true;
+ if(param.length == 0 || param[0] == "{" || param[0] == "[")
+ {
+ // param looks like JSON
+ queryData[fieldName] = param;
+ }
+ else
+ {
+ // treat param as a URL
+ rval = $.ajax({
+ url: param,
+ dataType: 'text',
+ success: function(data, textStatus, jqXHR) {
+ queryData[fieldName] = data;
+ },
+ error: function(jqXHR, textStatus, errorThrown) {
+ // FIXME: better error handling
+ $("#markup-errors")
+ .text("Error loading " + msgName + " URL: " + param);
+ }
+ });
+ }
+ };
+
+ return rval;
+ };
+
+ // build deferreds
+ var jsonLdDeferred = handleParameter(
+ getParameterByName("json-ld"), "markup", "JSON-LD");
+ var frameDeferred = handleParameter(
+ getParameterByName("frame"), "frame", "frame");
+
+ // wait for ajax if needed
+ // failures handled in AJAX calls
+ $.when(jsonLdDeferred, frameDeferred)
+ .done(function() {
+ // populate UI with data
+ playground.populateWithJSON(queryData);
+ });
+ };
+
+ /**
+ * Used to initialize the UI, call once on document load.
*/
playground.init = function()
{
$("#tabs").tabs();
$("#frame").hide();
$("#tabs").bind("tabsselect", playground.tabSelected);
+ playground.processQueryParameters();
};
/**
@@ -102,7 +196,7 @@
try
{
$("#frame-errors").text("");
- var frame = JSON.parse($("#frame").val());
+ frame = JSON.parse($("#frame").val());
}
catch(e)
{
@@ -143,6 +237,28 @@
var turtle = forge.jsonld.turtle(input);
$("#turtle").html(playground.htmlEscape(turtle));
}
+
+ // generate a link for current data
+ var link = "?json-ld=" + encodeURIComponent(JSON.stringify(input));
+ if($("#frame").val().length > 0)
+ {
+ link += "&frame=" + encodeURIComponent(JSON.stringify(frame));
+ }
+ var permalink = '<a href="' + link + '">permalink</a>';
+ // size warning for huge links
+ if((window.location.protocol.length + 2 +
+ window.location.host.length + window.location.pathname.length +
+ link.length) > 2048)
+ {
+ permalink += " (2KB+)"
+ }
+ $("#permalink")
+ .html(permalink)
+ .show();
+ }
+ else
+ {
+ $("#permalink").hide();
}
// Start the colorization delay
@@ -185,26 +301,29 @@
};
/**
- * Callback when an example button is clicked.
+ * Populate the UI with markup and frame JSON. The data parameter should
+ * have a 'markup' field and optional 'frame' field that contain a
+ * serialized JSON string.
*
- * @param name the name of the example to pre-populate the input boxes.
+ * @param data object with optional 'markup' and 'frame' fields.
*/
- playground.populate = function(name)
+ playground.populateWithJSON = function(data)
{
- if(name in playground.examples)
+ if('markup' in data && data.markup !== null)
{
// fill the markup box with the example
- $("#markup").val(js_beautify(JSON.stringify(playground.examples[name]),
+ $("#markup").val(js_beautify(
+ data.markup,
{ "indent_size": 3, "brace_style": "expand" }));
$("#frame").val("{}");
+ }
- if(name in playground.frames)
- {
- // fill the frame input box with the example frame
- $("#frame").val(js_beautify(
- JSON.stringify(playground.frames[name]),
- { "indent_size": 3, "brace_style": "expand" }));
- }
+ if('frame' in data && data.frame !== null)
+ {
+ // fill the frame input box with the example frame
+ $("#frame").val(js_beautify(
+ data.frame,
+ { "indent_size": 3, "brace_style": "expand" }));
}
// perform processing on the data provided in the input boxes
@@ -214,5 +333,33 @@
prettyPrint();
};
+ /**
+ * Populate the UI with a named example.
+ *
+ * @param name the name of the example to pre-populate the input boxes.
+ */
+ playground.populateWithExample = function(name)
+ {
+ var data = {
+ markup: null,
+ frame: null
+ };
+
+ if(name in playground.examples)
+ {
+ // fill the markup with the example
+ data.markup = JSON.stringify(playground.examples[name]);
+
+ if(name in playground.frames)
+ {
+ // fill the frame with the example frame
+ data.frame = JSON.stringify(playground.frames[name]);
+ }
+ }
+
+ // populate with the example
+ playground.populateWithJSON(data);
+ };
+
})(jQuery);