260 lines
9.1 KiB
HTML
260 lines
9.1 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>JSV: JSON Schema Validator</title>
|
|
<style type="text/css">
|
|
|
|
/* 1140px CSS Fluid Grid System */
|
|
|
|
html,body,div,span,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,address,cite,code,del,dfn,em,img,ins,q,small,strong,sub,sup,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{border:0;margin:0;padding:0}
|
|
article,aside,figure,figure img,figcaption,hgroup,footer,header,nav,section,video,object{display:block}
|
|
a img{border:0}
|
|
figure{position:relative}
|
|
figure img{width:100%}
|
|
.container{padding-left:20px;padding-right:20px}
|
|
.row{width:100%;max-width:1140px;min-width:755px;overflow:hidden;margin:0 auto}
|
|
.onecol,.twocol,.threecol,.fourcol,.fivecol,.sixcol,.sevencol,.eightcol,.ninecol,.tencol,.elevencol{margin-right:3.8%;float:left;min-height:1px}
|
|
.row .onecol{width:4.85%}
|
|
.row .twocol{width:13.45%}
|
|
.row .threecol{width:22.05%}
|
|
.row .fourcol{width:30.75%}
|
|
.row .fivecol{width:39.45%}
|
|
.row .sixcol{width:48%}
|
|
.row .sevencol{width:56.75%}
|
|
.row .eightcol{width:65.4%}
|
|
.row .ninecol{width:74.05%}
|
|
.row .tencol{width:82.7%}
|
|
.row .elevencol{width:91.35%}
|
|
.row .twelvecol{width:100%;float:left}
|
|
.last{margin-right:0}
|
|
img,object,embed{max-width:100%}
|
|
img{height:auto}
|
|
@media only screen and (max-width: 1023px) {
|
|
body{font-size:.8em;line-height:1.5em}
|
|
}
|
|
@media handheld, only screen and (max-width: 767px) {
|
|
body{font-size:16px;-webkit-text-size-adjust:none}
|
|
.row,body,.container{width:100%;min-width:0;margin-left:0;margin-right:0;padding-left:0;padding-right:0}
|
|
.row .onecol,.row .twocol,.row .threecol,.row .fourcol,.row .fivecol,.row .sixcol,.row .sevencol,.row .eightcol,.row .ninecol,.row .tencol,.row .elevencol,.row .twelvecol{width:auto;float:none;margin-left:0;margin-right:0;padding-left:20px;padding-right:20px}
|
|
}
|
|
|
|
/* Styles */
|
|
|
|
.container { padding-bottom: 20px; font-family: sans-serif; }
|
|
.row { margin-top: 20px; }
|
|
legend { font-weight: bold; font-size: 125%; }
|
|
label { display: block; font-weight: bold; }
|
|
.value_label { display: none; }
|
|
.value { height: 360px; font-size: 12px; tab-size: 4; }
|
|
.value, .uri { width: 100%; }
|
|
.value, .uri, .error code { font-family: Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif; }
|
|
.error { margin: 20px 0; font-size: 12px; }
|
|
.error:first-child { margin-top: 0; }
|
|
.error:last-child { margin-bottom: 0; }
|
|
.error_message { font-weight: bold; }
|
|
.error_schemaUri { margin-left: 15px; }
|
|
.error_attribute { margin-left: 15px; }
|
|
#report { padding: 20px; }
|
|
#report.valid { border: 1px solid #0f0; background-color: #efe; }
|
|
#report.invalid { border: 1px solid #f00; background-color: #fee; }
|
|
|
|
</style>
|
|
</head>
|
|
<body class="container">
|
|
<div class="row">
|
|
<h1>JSV: JSON Schema Validator</h1>
|
|
<p></p>
|
|
</div>
|
|
|
|
<form id="jsv" class="row">
|
|
<div class="row">
|
|
<div class="twelvecol last">
|
|
<fieldset id="environment_properties">
|
|
<label for="environment">Environment</label>
|
|
<select id="environment" name="environment">
|
|
<option value="json-schema-draft-03">JSON Schema Draft-03</option>
|
|
<option value="json-schema-draft-02">JSON Schema Draft-02</option>
|
|
<option value="json-schema-draft-01">JSON Schema Draft-01</option>
|
|
</select>
|
|
</fieldset>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="sixcol">
|
|
<fieldset id="json_properties">
|
|
<legend>Input</legend>
|
|
<label id="json_label" class="value_label" for="json">Value</label>
|
|
<textarea id="json" class="value" name="json" wrap="off"></textarea>
|
|
<label id="json_uri_label" class="uri_label" for="json_uri">URI</label>
|
|
<input id="json_uri" class="uri" type="text" name="json_uri" value="json">
|
|
</fieldset>
|
|
</div>
|
|
|
|
<div class="sixcol last">
|
|
<fieldset id="schema_properties">
|
|
<legend>Schema</legend>
|
|
<label id="schema_label" class="value_label" for="schema">Value</label>
|
|
<textarea id="schema" class="value" name="schema" wrap="off"></textarea>
|
|
<label id="schema_uri_label" class="uri_label" for="schema_uri">URI</label>
|
|
<input id="schema_uri" class="uri" type="text" name="schema_uri" value="schema">
|
|
</fieldset>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="twelvecol last">
|
|
<fieldset id="controls">
|
|
<input id="validate" type="submit" value="Validate"/>
|
|
</fieldset>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
|
|
<div class="row">
|
|
<div id="report"></div>
|
|
</div>
|
|
|
|
<!-- Load Scripts -->
|
|
|
|
<script type="text/javascript">
|
|
|
|
/* Code by: http://bitprophet.org/code/javascript_tab.html */
|
|
|
|
var TAB_CHAR = "\t";
|
|
function checkTab(evt) {
|
|
var t = evt.target;
|
|
var ss = t.selectionStart;
|
|
var se = t.selectionEnd;
|
|
|
|
// Tab key - insert tab expansion
|
|
if (evt.keyCode == 9) {
|
|
evt.preventDefault();
|
|
|
|
// Special case of multi line selection
|
|
if (ss != se && t.value.slice(ss,se).indexOf("n") != -1) {
|
|
// In case selection was not of entire lines (e.g. selection begins in the middle of a line)
|
|
// we ought to tab at the beginning as well as at the start of every following line.
|
|
var pre = t.value.slice(0,ss);
|
|
var sel = t.value.slice(ss,se).replace(/n/g,"n"+TAB_CHAR);
|
|
var post = t.value.slice(se,t.value.length);
|
|
t.value = pre.concat(TAB_CHAR).concat(sel).concat(post);
|
|
|
|
t.selectionStart = ss + TAB_CHAR.length;
|
|
t.selectionEnd = se + TAB_CHAR.length;
|
|
}
|
|
|
|
// "Normal" case (no selection or selection on one line only)
|
|
else {
|
|
t.value = t.value.slice(0,ss).concat(TAB_CHAR).concat(t.value.slice(ss,t.value.length));
|
|
if (ss == se) {
|
|
t.selectionStart = t.selectionEnd = ss + TAB_CHAR.length;
|
|
}
|
|
else {
|
|
t.selectionStart = ss + TAB_CHAR.length;
|
|
t.selectionEnd = se + TAB_CHAR.length;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Backspace key - delete preceding tab expansion, if exists
|
|
else if (evt.keyCode==8 && t.value.slice(ss - 4,ss) == TAB_CHAR) {
|
|
evt.preventDefault();
|
|
|
|
t.value = t.value.slice(0,ss - 4).concat(t.value.slice(ss,t.value.length));
|
|
t.selectionStart = t.selectionEnd = ss - TAB_CHAR.length;
|
|
}
|
|
|
|
// Delete key - delete following tab expansion, if exists
|
|
else if (evt.keyCode==46 && t.value.slice(se,se + 4) == TAB_CHAR) {
|
|
evt.preventDefault();
|
|
|
|
t.value = t.value.slice(0,ss).concat(t.value.slice(ss + 4,t.value.length));
|
|
t.selectionStart = t.selectionEnd = ss;
|
|
}
|
|
// Left/right arrow keys - move across the tab in one go
|
|
else if (evt.keyCode == 37 && t.value.slice(ss - 4,ss) == TAB_CHAR) {
|
|
evt.preventDefault();
|
|
t.selectionStart = t.selectionEnd = ss - 4;
|
|
}
|
|
else if (evt.keyCode == 39 && t.value.slice(ss,ss + 4) == TAB_CHAR) {
|
|
evt.preventDefault();
|
|
t.selectionStart = t.selectionEnd = ss + 4;
|
|
}
|
|
}
|
|
|
|
/* Form Logic */
|
|
|
|
window.addEventListener("load", function (event) {
|
|
var textareas = document.getElementsByTagName("textarea");
|
|
for (var x = 0, xl = textareas.length; x < xl; ++x) {
|
|
textareas[x].addEventListener("keypress", checkTab);
|
|
}
|
|
|
|
var form = document.forms["jsv"];
|
|
form.addEventListener("submit", function (event) {
|
|
try {
|
|
var environmentId = form.elements["environment"].value;
|
|
var json = form.elements["json"].value;
|
|
var jsonUri = form.elements["json_uri"].value;
|
|
var schema = form.elements["schema"].value;
|
|
var schemaUri = form.elements["schema_uri"].value;
|
|
|
|
try {
|
|
json = json ? JSON.parse(json) : undefined;
|
|
} catch (e) {
|
|
throw new Error("Input is not valid JSON");
|
|
}
|
|
|
|
try {
|
|
schema = schema ? JSON.parse(schema) : undefined;
|
|
} catch (e) {
|
|
throw new Error("Schema is not valid JSON");
|
|
}
|
|
|
|
var environment = JSV.createEnvironment(environmentId);
|
|
var report = environment.validate(environment.createInstance(json, jsonUri), environment.createSchema(schema, null, schemaUri));
|
|
var reportElement = document.getElementById("report");
|
|
var output;
|
|
|
|
if (report.errors.length) {
|
|
reportElement.className = "invalid";
|
|
output = "";
|
|
for (var x = 0, xl = report.errors.length; x < xl; ++x) {
|
|
output += '<div class="error"><span class="error_uri">Problem with <code>' +
|
|
report.errors[x].uri +
|
|
'</code> : </span><span class="error_message">' +
|
|
report.errors[x].message +
|
|
'</span><br/><span class="error_schemaUri">Reported by <code>' +
|
|
report.errors[x].schemaUri +
|
|
'</code></span><br/><span class="error_attribute">Attribute "<code>' +
|
|
report.errors[x].attribute +
|
|
'</code>"</span><span class="error_details"> (<code>' +
|
|
JSON.stringify(report.errors[x].details) +
|
|
'</code>)</span></div>';
|
|
}
|
|
reportElement.innerHTML = output;
|
|
} else {
|
|
reportElement.className = "valid";
|
|
reportElement.textContent = "Input is valid!";
|
|
}
|
|
} catch (e) {
|
|
var reportElement = document.getElementById("report");
|
|
reportElement.className = "invalid";
|
|
reportElement.textContent = e;
|
|
}
|
|
|
|
event.preventDefault();
|
|
return false;
|
|
});
|
|
});
|
|
|
|
</script>
|
|
<script type="text/javascript" src="../lib/uri/uri.js"></script>
|
|
<script type="text/javascript" src="../lib/uri/schemes/urn.js"></script>
|
|
<script type="text/javascript" src="../lib/jsv.js"></script>
|
|
<script type="text/javascript" src="../lib/json-schema-draft-03.js"></script>
|
|
<script type="text/javascript" src="../lib/json-schema-draft-02.js"></script>
|
|
<script type="text/javascript" src="../lib/json-schema-draft-01.js"></script>
|
|
</body>
|
|
</html> |