Switched everything to 2-space indentation

This commit is contained in:
josdejong 2013-11-15 18:11:50 +01:00
parent 8ddc6f3946
commit 8e07ebb711
44 changed files with 10535 additions and 10535 deletions

View File

@ -21,7 +21,7 @@ var JSONEDITOR = './jsoneditor.js',
*/
desc('Execute all tasks');
task('default', ['clear', 'build', 'minify', 'zip', 'webapp', 'chromeapp'], function () {
console.log('Done');
console.log('Done');
});
/**
@ -29,7 +29,7 @@ task('default', ['clear', 'build', 'minify', 'zip', 'webapp', 'chromeapp'], func
*/
desc('Clear the build directory');
task('clear', function () {
jake.rmRf(BUILD);
jake.rmRf(BUILD);
});
/**
@ -37,54 +37,54 @@ task('clear', function () {
*/
desc('Build the library');
task('build', ['clear'], function () {
var jsoneditorSrc = './jsoneditor/';
// concatenate the javascript files
concat({
src: [
jsoneditorSrc + 'js/jsoneditor.js',
jsoneditorSrc + 'js/treeeditor.js',
jsoneditorSrc + 'js/texteditor.js',
jsoneditorSrc + 'js/node.js',
jsoneditorSrc + 'js/appendnode.js',
jsoneditorSrc + 'js/contextmenu.js',
jsoneditorSrc + 'js/history.js',
jsoneditorSrc + 'js/modebox.js',
jsoneditorSrc + 'js/searchbox.js',
jsoneditorSrc + 'js/highlighter.js',
jsoneditorSrc + 'js/util.js',
jsoneditorSrc + 'js/module.js'
],
dest: JSONEDITOR,
header: read(jsoneditorSrc +'js/header.js') + '\n' +
'(function () {\n',
separator: '\n',
footer: '\n})();\n'
});
var jsoneditorSrc = './jsoneditor/';
// concatenate the javascript files
concat({
src: [
jsoneditorSrc + 'js/jsoneditor.js',
jsoneditorSrc + 'js/treeeditor.js',
jsoneditorSrc + 'js/texteditor.js',
jsoneditorSrc + 'js/node.js',
jsoneditorSrc + 'js/appendnode.js',
jsoneditorSrc + 'js/contextmenu.js',
jsoneditorSrc + 'js/history.js',
jsoneditorSrc + 'js/modebox.js',
jsoneditorSrc + 'js/searchbox.js',
jsoneditorSrc + 'js/highlighter.js',
jsoneditorSrc + 'js/util.js',
jsoneditorSrc + 'js/module.js'
],
dest: JSONEDITOR,
header: read(jsoneditorSrc +'js/header.js') + '\n' +
'(function () {\n',
separator: '\n',
footer: '\n})();\n'
});
// update version number and stuff in the javascript files
replacePlaceholders(JSONEDITOR);
console.log('Created ' + JSONEDITOR);
// update version number and stuff in the javascript files
replacePlaceholders(JSONEDITOR);
console.log('Created ' + JSONEDITOR);
// concatenate and stringify the css files
concat({
src: [
jsoneditorSrc + 'css/jsoneditor.css',
jsoneditorSrc + 'css/contextmenu.css',
jsoneditorSrc + 'css/menu.css',
jsoneditorSrc + 'css/searchbox.css'
],
dest: JSONEDITOR_CSS,
separator: '\n'
});
console.log('Created ' + JSONEDITOR_CSS);
// concatenate and stringify the css files
concat({
src: [
jsoneditorSrc + 'css/jsoneditor.css',
jsoneditorSrc + 'css/contextmenu.css',
jsoneditorSrc + 'css/menu.css',
jsoneditorSrc + 'css/searchbox.css'
],
dest: JSONEDITOR_CSS,
separator: '\n'
});
console.log('Created ' + JSONEDITOR_CSS);
// minify the css file
write(JSONEDITOR_CSS_MIN, new CleanCSS().minify(String(read(JSONEDITOR_CSS))));
// minify the css file
write(JSONEDITOR_CSS_MIN, new CleanCSS().minify(String(read(JSONEDITOR_CSS))));
// create a folder img and copy the icons
jake.mkdirP('./img');
jake.cpR(jsoneditorSrc + 'css/img/jsoneditor-icons.png', './img/');
console.log('Copied jsoneditor-icons.png to ./img/');
// create a folder img and copy the icons
jake.mkdirP('./img');
jake.cpR(jsoneditorSrc + 'css/img/jsoneditor-icons.png', './img/');
console.log('Copied jsoneditor-icons.png to ./img/');
});
/**
@ -92,18 +92,18 @@ task('build', ['clear'], function () {
*/
desc('Minify the library');
task('minify', ['build'], function () {
// minify javascript
minify({
src: JSONEDITOR,
dest: JSONEDITOR_MIN,
header: read('./jsoneditor/js/header.js'),
separator: '\n'
});
// minify javascript
minify({
src: JSONEDITOR,
dest: JSONEDITOR_MIN,
header: read('./jsoneditor/js/header.js'),
separator: '\n'
});
// update version number and stuff in the javascript files
replacePlaceholders(JSONEDITOR_MIN);
// update version number and stuff in the javascript files
replacePlaceholders(JSONEDITOR_MIN);
console.log('Created ' + JSONEDITOR_MIN);
console.log('Created ' + JSONEDITOR_MIN);
});
/**
@ -111,50 +111,50 @@ task('minify', ['build'], function () {
*/
desc('Zip the library');
task('zip', ['build', 'minify'], {async: true}, function () {
var zipfolder = BUILD + '/lib';
var pkg = 'jsoneditor-' + version();
var zipfile = zipfolder + '/' + pkg + '.zip';
jake.mkdirP(zipfolder);
var zipfolder = BUILD + '/lib';
var pkg = 'jsoneditor-' + version();
var zipfile = zipfolder + '/' + pkg + '.zip';
jake.mkdirP(zipfolder);
var output = fs.createWriteStream(zipfile);
var archive = archiver('zip');
var output = fs.createWriteStream(zipfile);
var archive = archiver('zip');
archive.on('error', function(err) {
throw err;
});
archive.on('error', function(err) {
throw err;
});
archive.pipe(output);
archive.pipe(output);
var filelist = new jake.FileList();
filelist.include([
'README.md',
'NOTICE',
'LICENSE',
'HISTORY.md',
JSONEDITOR,
JSONEDITOR_CSS,
JSONEDITOR_MIN,
JSONEDITOR_CSS_MIN,
'img/*.*',
'lib/**/*.*',
'docs/**/*.*',
'examples/**/*.*'
]);
var files = filelist.toArray();
files.forEach(function (file) {
archive.append(fs.createReadStream(file), {
name: pkg + '/' + file
})
});
var filelist = new jake.FileList();
filelist.include([
'README.md',
'NOTICE',
'LICENSE',
'HISTORY.md',
JSONEDITOR,
JSONEDITOR_CSS,
JSONEDITOR_MIN,
JSONEDITOR_CSS_MIN,
'img/*.*',
'lib/**/*.*',
'docs/**/*.*',
'examples/**/*.*'
]);
var files = filelist.toArray();
files.forEach(function (file) {
archive.append(fs.createReadStream(file), {
name: pkg + '/' + file
})
});
archive.finalize(function(err, written) {
if (err) {
throw err;
}
archive.finalize(function(err, written) {
if (err) {
throw err;
}
console.log('Zipped ' + zipfile);
complete();
});
console.log('Zipped ' + zipfile);
complete();
});
});
/**
@ -162,107 +162,107 @@ task('zip', ['build', 'minify'], {async: true}, function () {
*/
desc('Build web app');
task('webapp', ['build', 'minify'], function () {
var webAppSrc = './app/web/';
var libSrc = './lib/';
var webApp = BUILD + '/app/web/';
var webAppLib = webApp + 'lib/';
var webAppAce = webAppLib + 'ace/';
var webAppImg = webApp + 'img/';
var appJs = webApp + 'app.js';
var appCss = webApp + 'app.css';
var appCssMin = webApp + 'app-min.css';
var appJsMin = webApp + 'app-min.js';
var webAppSrc = './app/web/';
var libSrc = './lib/';
var webApp = BUILD + '/app/web/';
var webAppLib = webApp + 'lib/';
var webAppAce = webAppLib + 'ace/';
var webAppImg = webApp + 'img/';
var appJs = webApp + 'app.js';
var appCss = webApp + 'app.css';
var appCssMin = webApp + 'app-min.css';
var appJsMin = webApp + 'app-min.js';
// create directories
// TODO: should be created automatically...
jake.mkdirP(webApp);
jake.mkdirP(webAppLib);
jake.mkdirP(webAppLib + 'ace/');
jake.mkdirP(webAppLib + 'jsoneditor/');
jake.mkdirP(webAppLib + 'jsoneditor/img/');
jake.mkdirP(webAppLib + 'jsonlint/');
jake.mkdirP(webAppImg);
// create directories
// TODO: should be created automatically...
jake.mkdirP(webApp);
jake.mkdirP(webAppLib);
jake.mkdirP(webAppLib + 'ace/');
jake.mkdirP(webAppLib + 'jsoneditor/');
jake.mkdirP(webAppLib + 'jsoneditor/img/');
jake.mkdirP(webAppLib + 'jsonlint/');
jake.mkdirP(webAppImg);
// concatenate the javascript files
concat({
src: [
webAppSrc + 'queryparams.js',
webAppSrc + 'ajax.js',
webAppSrc + 'fileretriever.js',
webAppSrc + 'notify.js',
webAppSrc + 'splitter.js',
webAppSrc + 'app.js'
],
dest: appJs,
separator: '\n'
});
// concatenate the javascript files
concat({
src: [
webAppSrc + 'queryparams.js',
webAppSrc + 'ajax.js',
webAppSrc + 'fileretriever.js',
webAppSrc + 'notify.js',
webAppSrc + 'splitter.js',
webAppSrc + 'app.js'
],
dest: appJs,
separator: '\n'
});
// minify javascript
minify({
src: appJs,
dest: appJsMin
});
// minify javascript
minify({
src: appJs,
dest: appJsMin
});
// concatenate the css files
concat({
src: [
webAppSrc + 'fileretriever.css',
webAppSrc + 'app.css'
],
dest: appCss,
separator: '\n'
});
// concatenate the css files
concat({
src: [
webAppSrc + 'fileretriever.css',
webAppSrc + 'app.css'
],
dest: appCss,
separator: '\n'
});
// minify css file
write(appCssMin, new CleanCSS().minify(String(read(appCss))));
// minify css file
write(appCssMin, new CleanCSS().minify(String(read(appCss))));
// remove non minified javascript and css file
fs.unlinkSync(appJs);
fs.unlinkSync(appCss);
// remove non minified javascript and css file
fs.unlinkSync(appJs);
fs.unlinkSync(appCss);
// copy files
jake.cpR('./README.md', webApp);
jake.cpR('./HISTORY.md', webApp);
jake.cpR('./NOTICE', webApp);
jake.cpR('./LICENSE', webApp);
jake.cpR('./LICENSE', webApp);
jake.cpR(webAppSrc + 'cache.manifest', webApp);
jake.cpR(webAppSrc + 'robots.txt', webApp);
jake.cpR(webAppSrc + 'datapolicy.txt', webApp);
jake.cpR(webAppSrc + 'index.html', webApp);
jake.cpR(webAppSrc + 'favicon.ico', webApp);
jake.cpR(webAppSrc + 'fileretriever.php', webApp);
jake.cpR(webAppSrc + 'googlea47c4a0b36d11021.html', webApp);
jake.cpR(webAppSrc + 'img/logo.png', webAppImg);
jake.cpR(webAppSrc + 'img/header_background.png', webAppImg);
jake.cpR(webAppSrc + 'doc/', webApp);
// copy files
jake.cpR('./README.md', webApp);
jake.cpR('./HISTORY.md', webApp);
jake.cpR('./NOTICE', webApp);
jake.cpR('./LICENSE', webApp);
jake.cpR('./LICENSE', webApp);
jake.cpR(webAppSrc + 'cache.manifest', webApp);
jake.cpR(webAppSrc + 'robots.txt', webApp);
jake.cpR(webAppSrc + 'datapolicy.txt', webApp);
jake.cpR(webAppSrc + 'index.html', webApp);
jake.cpR(webAppSrc + 'favicon.ico', webApp);
jake.cpR(webAppSrc + 'fileretriever.php', webApp);
jake.cpR(webAppSrc + 'googlea47c4a0b36d11021.html', webApp);
jake.cpR(webAppSrc + 'img/logo.png', webAppImg);
jake.cpR(webAppSrc + 'img/header_background.png', webAppImg);
jake.cpR(webAppSrc + 'doc/', webApp);
// update date and verison in index.html
replacePlaceholders(webApp + 'index.html');
replacePlaceholders(webApp + 'index.html'); // TODO: fix bug in replace, should replace all occurrences
replacePlaceholders(webApp + 'cache.manifest');
// update date and verison in index.html
replacePlaceholders(webApp + 'index.html');
replacePlaceholders(webApp + 'index.html'); // TODO: fix bug in replace, should replace all occurrences
replacePlaceholders(webApp + 'cache.manifest');
// concatenate and copy ace files
concat({
src: [
libSrc + 'ace/ace.js',
libSrc + 'ace/mode-json.js',
libSrc + 'ace/theme-textmate.js',
libSrc + 'ace/theme-jsoneditor.js',
libSrc + 'ace/ext-searchbox.js'
],
dest: webAppAce + 'ace-min.js',
separator: '\n'
});
jake.cpR(libSrc + 'ace/worker-json.js', webAppAce);
// concatenate and copy ace files
concat({
src: [
libSrc + 'ace/ace.js',
libSrc + 'ace/mode-json.js',
libSrc + 'ace/theme-textmate.js',
libSrc + 'ace/theme-jsoneditor.js',
libSrc + 'ace/ext-searchbox.js'
],
dest: webAppAce + 'ace-min.js',
separator: '\n'
});
jake.cpR(libSrc + 'ace/worker-json.js', webAppAce);
// copy json lint file
jake.cpR(libSrc + 'jsonlint/jsonlint.js', webAppLib + 'jsonlint/')
// copy json lint file
jake.cpR(libSrc + 'jsonlint/jsonlint.js', webAppLib + 'jsonlint/')
// copy jsoneditor files
jake.cpR(JSONEDITOR_MIN, webAppLib + 'jsoneditor/');
jake.cpR(JSONEDITOR_CSS_MIN, webAppLib + 'jsoneditor/');
jake.cpR('img', webAppLib + 'jsoneditor/');
// copy jsoneditor files
jake.cpR(JSONEDITOR_MIN, webAppLib + 'jsoneditor/');
jake.cpR(JSONEDITOR_CSS_MIN, webAppLib + 'jsoneditor/');
jake.cpR('img', webAppLib + 'jsoneditor/');
});
@ -271,38 +271,38 @@ task('webapp', ['build', 'minify'], function () {
*/
desc('Build chrome app');
task('chromeapp', {async: true}, function () {
var folder = BUILD + '/app/';
var file = folder + 'chrome.zip';
jake.mkdirP(folder);
var folder = BUILD + '/app/';
var file = folder + 'chrome.zip';
jake.mkdirP(folder);
var output = fs.createWriteStream(file);
var archive = archiver('zip');
var output = fs.createWriteStream(file);
var archive = archiver('zip');
archive.on('error', function(err) {
throw err;
});
archive.on('error', function(err) {
throw err;
});
// create a temporary manifest file with version number
var manifestTmp = folder + 'manifest.json.tmp';
jake.cpR('./app/chrome/manifest.json', manifestTmp);
replacePlaceholders(manifestTmp);
// create a temporary manifest file with version number
var manifestTmp = folder + 'manifest.json.tmp';
jake.cpR('./app/chrome/manifest.json', manifestTmp);
replacePlaceholders(manifestTmp);
archive.pipe(output);
archive.append(fs.createReadStream(manifestTmp), {name: 'manifest.json'});
archive.append(fs.createReadStream('./app/web/img/icon_16.png'), {name: 'icon_16.png'});
archive.append(fs.createReadStream('./app/web/img/icon_128.png'), {name: 'icon_128.png'});
archive.pipe(output);
archive.append(fs.createReadStream(manifestTmp), {name: 'manifest.json'});
archive.append(fs.createReadStream('./app/web/img/icon_16.png'), {name: 'icon_16.png'});
archive.append(fs.createReadStream('./app/web/img/icon_128.png'), {name: 'icon_128.png'});
// cleanup temporary manifest file
fs.unlinkSync(manifestTmp);
// cleanup temporary manifest file
fs.unlinkSync(manifestTmp);
archive.finalize(function(err, written) {
if (err) {
throw err;
}
archive.finalize(function(err, written) {
if (err) {
throw err;
}
console.log('Created chrome app ' + file);
complete();
});
console.log('Created chrome app ' + file);
complete();
});
});
/**
@ -310,11 +310,11 @@ task('chromeapp', {async: true}, function () {
* @param {String} filename
*/
var replacePlaceholders = function (filename) {
replace({
replacements: [
{pattern: '@@date', replacement: today()},
{pattern: '@@version', replacement: version()}
],
src: filename
});
replace({
replacements: [
{pattern: '@@date', replacement: today()},
{pattern: '@@version', replacement: version()}
],
src: filename
});
};

View File

@ -1,25 +1,25 @@
{
"manifest_version": 2,
"name": "JSON Editor",
"version": "@@version",
"description": "JSON Editor is a tool to view, edit, and format JSON. It shows your data in an editable treeview and in a code editor.",
"app": {
"urls": [
"http://jsoneditoronline.org/",
"http://jsoneditoronline.org/index.html",
"http://jsoneditoronline.org/changelog.txt",
"http://jsoneditoronline.org/NOTICE"
],
"launch": {
"web_url": "http://jsoneditoronline.org/index.html"
}
},
"icons": {
"16": "icon_16.png",
"128": "icon_128.png"
},
"permissions": [
"unlimitedStorage"
"manifest_version": 2,
"name": "JSON Editor",
"version": "@@version",
"description": "JSON Editor is a tool to view, edit, and format JSON. It shows your data in an editable treeview and in a code editor.",
"app": {
"urls": [
"http://jsoneditoronline.org/",
"http://jsoneditoronline.org/index.html",
"http://jsoneditoronline.org/changelog.txt",
"http://jsoneditoronline.org/NOTICE"
],
"offline_enabled": true
"launch": {
"web_url": "http://jsoneditoronline.org/index.html"
}
},
"icons": {
"16": "icon_16.png",
"128": "icon_128.png"
},
"permissions": [
"unlimitedStorage"
],
"offline_enabled": true
}

View File

@ -1,43 +1,43 @@
/**
* ajax
* Utility to perform ajax get and post requests. Supported browsers:
* Utility to perform ajax get and post requests. Supported browsers:
* Chrome, Firefox, Opera, Safari, Internet Explorer 7+.
*/
var ajax = (function () {
function fetch (method, url, body, headers, callback) {
try {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
callback(xhr.responseText, xhr.status);
}
};
xhr.open(method, url, true);
if (headers) {
for (var name in headers) {
if (headers.hasOwnProperty(name)) {
xhr.setRequestHeader(name, headers[name]);
}
}
}
xhr.send(body);
function fetch (method, url, body, headers, callback) {
try {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
callback(xhr.responseText, xhr.status);
}
catch (err) {
callback(err, 0);
};
xhr.open(method, url, true);
if (headers) {
for (var name in headers) {
if (headers.hasOwnProperty(name)) {
xhr.setRequestHeader(name, headers[name]);
}
}
}
xhr.send(body);
}
catch (err) {
callback(err, 0);
}
}
function get (url, headers, callback) {
fetch('GET', url, null, headers, callback);
}
function get (url, headers, callback) {
fetch('GET', url, null, headers, callback);
}
function post (url, body, headers, callback) {
fetch('POST', url, body, headers, callback)
}
function post (url, body, headers, callback) {
fetch('POST', url, body, headers, callback)
}
return {
'fetch': fetch,
'get': get,
'post': post
}
return {
'fetch': fetch,
'get': get,
'post': post
}
})();

View File

@ -1,292 +1,292 @@
body, html {
font-family: arial, sans-serif;
font-size: 11pt;
font-family: arial, sans-serif;
font-size: 11pt;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
overflow: hidden;
}
span.header-light {
color: gray;
color: gray;
}
#header {
width: 100%;
height: 40px;
/* TODO
overflow: hidden;
*/
width: 100%;
height: 40px;
/* TODO
overflow: hidden;
*/
background: #4D4D4D url('img/header_background.png');
color: white;
background: #4D4D4D url('img/header_background.png');
color: white;
}
#logo {
height: 32px;
margin: 4px 10px;
border: none;
height: 32px;
margin: 4px 10px;
border: none;
}
#menu {
position: absolute;
top: 5px;
right: 15px;
font-size: 11pt;
position: absolute;
top: 5px;
right: 15px;
font-size: 11pt;
}
#menu ul {
list-style: none;
margin: 0;
padding: 0;
clear: both;
list-style: none;
margin: 0;
padding: 0;
clear: both;
}
#menu ul li {
color: #e6e6e6;
background: none;
border: none;
border-right: 1px solid #737373;
height: 30px;
padding: 0;
margin: 0;
float: left;
position: relative;
color: #e6e6e6;
background: none;
border: none;
border-right: 1px solid #737373;
height: 30px;
padding: 0;
margin: 0;
float: left;
position: relative;
text-decoration: none;
text-decoration: none;
}
#menu ul li:first-child {
border-left: 1px solid #737373;
border-left: 1px solid #737373;
}
#menu ul li:hover {
color: white;
background-color: #737373;
color: white;
background-color: #737373;
}
#menu ul li ul {
display: none;
display: none;
}
#menu ul li:hover > ul {
display: block;
display: block;
}
#menu ul li ul {
position: absolute;
top: 30px;
left: 0;
z-index: 999;
position: absolute;
top: 30px;
left: 0;
z-index: 999;
background: #f5f5f5;
border: 1px solid lightgray;
box-shadow: 0 0 15px rgba(128, 128, 128, 0.5);
background: #f5f5f5;
border: 1px solid lightgray;
box-shadow: 0 0 15px rgba(128, 128, 128, 0.5);
}
#menu ul li ul li {
color: #737373;
background: none;
border: none;
margin: 0;
padding: 0;
color: #737373;
background: none;
border: none;
margin: 0;
padding: 0;
}
#menu ul li ul li:first-child {
border-left: none;
border-left: none;
}
#menu ul li ul li:hover {
background-color: white;
background-color: white;
}
#menu a {
padding: 6px 10px;
display: block;
cursor: pointer;
text-decoration: none;
color: white;
padding: 6px 10px;
display: block;
cursor: pointer;
text-decoration: none;
color: white;
}
#menu ul li ul li a {
color: #737373;
width: 80px;
color: #737373;
width: 80px;
}
#openMenuButton {
font-size: 75%;
margin-left: 2px;
font-size: 75%;
margin-left: 2px;
}
#menu #open {
cursor: default;
cursor: default;
}
/* TODO: enable the menu with keys (when openMenuButton is active) */
#auto {
width: 100%;
height: 100%;
width: 100%;
height: 100%;
margin: -40px 0 -24px 0;
padding: 40px 0 24px 0;
margin: -40px 0 -24px 0;
padding: 40px 0 24px 0;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
overflow: hidden;
overflow: hidden;
}
#contents {
width: 100%;
height: 100%;
overflow: hidden;
width: 100%;
height: 100%;
overflow: hidden;
}
#codeEditor, #treeEditor {
height: 100%;
width: 400px;
height: 100%;
width: 400px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
#codeEditor {
float: left;
padding: 15px 0 15px 15px;
float: left;
padding: 15px 0 15px 15px;
}
#treeEditor {
float: left;
padding: 15px 15px 15px 0;
float: left;
padding: 15px 15px 15px 0;
}
#splitter {
text-align: center;
float: left;
height: 100%;
padding: 15px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
text-align: center;
float: left;
height: 100%;
padding: 15px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
#splitter #buttons {
margin: 0 0 15px 0;
margin: 0 0 15px 0;
}
#splitter #toTree {
margin: 40px 0 0 0 ;
margin: 40px 0 0 0 ;
}
#splitter #toCode {
margin: 20px 0 0 0 ;
margin: 20px 0 0 0 ;
}
#splitter #drag {
font-size: 32px;
color: lightgray;
border-radius: 3px;
min-width: 24px;
cursor: col-resize;
font-size: 32px;
color: lightgray;
border-radius: 3px;
min-width: 24px;
cursor: col-resize;
}
#splitter #drag:hover,
#splitter #drag.active {
color: gray;
background-color: #f5f5f5;
color: gray;
background-color: #f5f5f5;
}
#footer {
width: 100%;
height: 23px;
font-size: 10pt;
width: 100%;
height: 23px;
font-size: 10pt;
overflow: hidden;
color: #BFBFBF;
border-top: 1px solid lightgray;
text-align: center;
background-color: #F5F5F5;
overflow: hidden;
color: #BFBFBF;
border-top: 1px solid lightgray;
text-align: center;
background-color: #F5F5F5;
}
#footer-inner {
margin: 4px;
margin: 4px;
}
a.header {
color: white;
text-decoration: none;
color: white;
text-decoration: none;
}
a.footer {
color: #BFBFBF;
text-decoration: none;
color: #BFBFBF;
text-decoration: none;
}
a.footer:hover {
color: red;
text-decoration: underline;
color: red;
text-decoration: underline;
}
#ad {
float: right;
right: 15px;
padding: 15px 0 15px 0;
position: relative;
float: right;
right: 15px;
padding: 15px 0 15px 0;
position: relative;
}
#chromeAppInfo {
line-height: normal;
padding: 0 5px 20px 5px;
line-height: normal;
padding: 0 5px 20px 5px;
}
div.error, div.notification {
border-radius: 2px;
padding: 5px;
margin: 5px;
box-shadow: 0 0 15px rgba(128, 128, 128, 0.5);
border-radius: 2px;
padding: 5px;
margin: 5px;
box-shadow: 0 0 15px rgba(128, 128, 128, 0.5);
/* TODO: add some transition effect */
/* TODO: add some transition effect */
}
div.error {
color: red;
background-color: #FFC0CB;
border: 1px solid red;
color: red;
background-color: #FFC0CB;
border: 1px solid red;
}
div.notification {
color: #1a1a1a;
background-color: #FFFFAB;
border: 1px solid #e6d600;
color: #1a1a1a;
background-color: #FFFFAB;
border: 1px solid #e6d600;
}
pre.error {
margin: 0 0 10px 0;
white-space: pre-wrap;
font-family: droid sans mono, monospace, courier new, courier, sans-serif;
font-size: 10pt;
margin: 0 0 10px 0;
white-space: pre-wrap;
font-family: droid sans mono, monospace, courier new, courier, sans-serif;
font-size: 10pt;
}
a.error {
color: red;
font-size: 8pt;
color: red;
font-size: 8pt;
}
button.convert {
cursor: default;
padding: 2px;
cursor: default;
padding: 2px;
}
div.convert-right, div.convert-left {
width: 24px;
height: 24px;
margin: 0;
width: 24px;
height: 24px;
margin: 0;
}
div.convert-right {
background: url('lib/jsoneditor/img/jsoneditor-icons.png') -0 -48px;
background: url('lib/jsoneditor/img/jsoneditor-icons.png') -0 -48px;
}
div.convert-left {
background: url('lib/jsoneditor/img/jsoneditor-icons.png') -24px -48px;
background: url('lib/jsoneditor/img/jsoneditor-icons.png') -24px -48px;
}

View File

@ -39,24 +39,24 @@ var app = {};
* Get the JSON from the code editor and load it in the tree editor
*/
app.CodeToTree = function() {
try {
treeEditor.set(codeEditor.get());
}
catch (err) {
app.notify.showError(app.formatError(err));
}
try {
treeEditor.set(codeEditor.get());
}
catch (err) {
app.notify.showError(app.formatError(err));
}
};
/**
* Get the JSON from the tree editor and load it into the code editor
*/
app.treeToCode = function () {
try {
codeEditor.set(treeEditor.get());
}
catch (err) {
app.notify.showError(app.formatError(err));
}
try {
codeEditor.set(treeEditor.get());
}
catch (err) {
app.notify.showError(app.formatError(err));
}
};
/**
@ -64,139 +64,139 @@ app.treeToCode = function () {
*/
// TODO: split the method load in multiple methods, it is too large
app.load = function() {
try {
// notification handler
app.notify = new Notify();
try {
// notification handler
app.notify = new Notify();
// retriever for loading/saving files
app.retriever = new FileRetriever({
scriptUrl: 'fileretriever.php',
notify: app.notify
});
// retriever for loading/saving files
app.retriever = new FileRetriever({
scriptUrl: 'fileretriever.php',
notify: app.notify
});
// default json document
var json = {
"array": [1, 2, 3],
"boolean": true,
"null": null,
"number": 123,
"object": {"a": "b", "c": "d", "e": "f"},
"string": "Hello World"
};
// default json document
var json = {
"array": [1, 2, 3],
"boolean": true,
"null": null,
"number": 123,
"object": {"a": "b", "c": "d", "e": "f"},
"string": "Hello World"
};
// load url if query parameters contains a url
if (window.QueryParams) {
var qp = new QueryParams();
var url = qp.getValue('url');
if (url) {
json = {};
app.openUrl(url);
}
}
// Store whether tree editor or code editor is last changed
app.lastChanged = undefined;
// code editor
var container = document.getElementById("codeEditor");
codeEditor = new jsoneditor.JSONEditor(container, {
mode: 'code',
change: function () {
app.lastChanged = codeEditor;
},
error: function (err) {
app.notify.showError(app.formatError(err));
}
});
codeEditor.set(json);
// tree editor
container = document.getElementById("treeEditor");
treeEditor = new jsoneditor.JSONEditor(container, {
mode: 'tree',
change: function () {
app.lastChanged = treeEditor;
},
error: function (err) {
app.notify.showError(app.formatError(err));
}
});
treeEditor.set(json);
// TODO: automatically synchronize data of code and tree editor? (tree editor should keep its state though)
// splitter
app.splitter = new Splitter({
container: document.getElementById('drag'),
change: function () {
app.resize();
}
});
// button Code-to-Tree
var toTree = document.getElementById('toTree');
toTree.onclick = function () {
this.focus();
app.CodeToTree();
};
// button Tree-to-Code
var toCode = document.getElementById('toCode');
toCode.onclick = function () {
this.focus();
app.treeToCode();
};
// web page resize handler
jsoneditor.util.addEventListener(window, 'resize', app.resize);
// clear button
var domClear = document.getElementById('clear');
domClear.onclick = app.clearFile;
/* TODO: enable clicking on open to execute the default, "open file"
// open button
var domOpen = document.getElementById('open');
var domOpenMenuButton = document.getElementById('openMenuButton');
domOpen.onclick = function (event) {
var target = event.target || event.srcElement;
if (target == domOpenMenuButton ||
(event.offsetX > domOpen.offsetWidth - domOpenMenuButton.offsetWidth)) {
// clicked on the menu button
}
else {
app.openFile();
}
};
*/
// menu button open file
var domMenuOpenFile = document.getElementById('menuOpenFile');
domMenuOpenFile.onclick = function (event) {
app.openFile();
event.stopPropagation();
event.preventDefault();
};
// menu button open url
var domMenuOpenUrl = document.getElementById('menuOpenUrl');
domMenuOpenUrl.onclick = function (event) {
app.openUrl();
event.stopPropagation();
event.preventDefault();
};
// save button
var domSave = document.getElementById('save');
domSave.onclick = app.saveFile;
// set focus on the code editor
codeEditor.focus();
// enforce FireFox to not do spell checking on any input field
document.body.spellcheck = false;
} catch (err) {
app.notify.showError(err);
// load url if query parameters contains a url
if (window.QueryParams) {
var qp = new QueryParams();
var url = qp.getValue('url');
if (url) {
json = {};
app.openUrl(url);
}
}
// Store whether tree editor or code editor is last changed
app.lastChanged = undefined;
// code editor
var container = document.getElementById("codeEditor");
codeEditor = new jsoneditor.JSONEditor(container, {
mode: 'code',
change: function () {
app.lastChanged = codeEditor;
},
error: function (err) {
app.notify.showError(app.formatError(err));
}
});
codeEditor.set(json);
// tree editor
container = document.getElementById("treeEditor");
treeEditor = new jsoneditor.JSONEditor(container, {
mode: 'tree',
change: function () {
app.lastChanged = treeEditor;
},
error: function (err) {
app.notify.showError(app.formatError(err));
}
});
treeEditor.set(json);
// TODO: automatically synchronize data of code and tree editor? (tree editor should keep its state though)
// splitter
app.splitter = new Splitter({
container: document.getElementById('drag'),
change: function () {
app.resize();
}
});
// button Code-to-Tree
var toTree = document.getElementById('toTree');
toTree.onclick = function () {
this.focus();
app.CodeToTree();
};
// button Tree-to-Code
var toCode = document.getElementById('toCode');
toCode.onclick = function () {
this.focus();
app.treeToCode();
};
// web page resize handler
jsoneditor.util.addEventListener(window, 'resize', app.resize);
// clear button
var domClear = document.getElementById('clear');
domClear.onclick = app.clearFile;
/* TODO: enable clicking on open to execute the default, "open file"
// open button
var domOpen = document.getElementById('open');
var domOpenMenuButton = document.getElementById('openMenuButton');
domOpen.onclick = function (event) {
var target = event.target || event.srcElement;
if (target == domOpenMenuButton ||
(event.offsetX > domOpen.offsetWidth - domOpenMenuButton.offsetWidth)) {
// clicked on the menu button
}
else {
app.openFile();
}
};
*/
// menu button open file
var domMenuOpenFile = document.getElementById('menuOpenFile');
domMenuOpenFile.onclick = function (event) {
app.openFile();
event.stopPropagation();
event.preventDefault();
};
// menu button open url
var domMenuOpenUrl = document.getElementById('menuOpenUrl');
domMenuOpenUrl.onclick = function (event) {
app.openUrl();
event.stopPropagation();
event.preventDefault();
};
// save button
var domSave = document.getElementById('save');
domSave.onclick = app.saveFile;
// set focus on the code editor
codeEditor.focus();
// enforce FireFox to not do spell checking on any input field
document.body.spellcheck = false;
} catch (err) {
app.notify.showError(err);
}
};
/**
@ -205,29 +205,29 @@ app.load = function() {
* @param {String} data
*/
app.openCallback = function (err, data) {
if (!err) {
if (data != null) {
codeEditor.setText(data);
try {
var json = jsoneditor.util.parse(data);
treeEditor.set(json);
}
catch (err) {
treeEditor.set({});
app.notify.showError(app.formatError(err));
}
}
}
else {
app.notify.showError(err);
if (!err) {
if (data != null) {
codeEditor.setText(data);
try {
var json = jsoneditor.util.parse(data);
treeEditor.set(json);
}
catch (err) {
treeEditor.set({});
app.notify.showError(app.formatError(err));
}
}
}
else {
app.notify.showError(err);
}
};
/**
* Open a file explorer to select a file and open the file
*/
app.openFile = function() {
app.retriever.loadFile(app.openCallback);
app.retriever.loadFile(app.openCallback);
};
/**
@ -236,37 +236,37 @@ app.openFile = function() {
* @param {String} [url]
*/
app.openUrl = function (url) {
if (!url) {
app.retriever.loadUrlDialog(app.openCallback);
}
else {
app.retriever.loadUrl(url, app.openCallback);
}
if (!url) {
app.retriever.loadUrlDialog(app.openCallback);
}
else {
app.retriever.loadUrl(url, app.openCallback);
}
};
/**
* Open a file explorer to save the file.
*/
app.saveFile = function () {
// first synchronize both editors contents
if (app.lastChanged == treeEditor) {
app.treeToCode();
}
/* TODO: also sync from code to tree editor? will clear the history ...
if (app.lastChanged == codeEditor) {
app.CodeToEditor();
}
*/
app.lastChanged = undefined;
// first synchronize both editors contents
if (app.lastChanged == treeEditor) {
app.treeToCode();
}
/* TODO: also sync from code to tree editor? will clear the history ...
if (app.lastChanged == codeEditor) {
app.CodeToEditor();
}
*/
app.lastChanged = undefined;
// save the text from the code editor
// TODO: show a 'saving...' notification
var data = codeEditor.getText();
app.retriever.saveFile(data, function (err) {
if (err) {
app.notify.showError(err);
}
});
// save the text from the code editor
// TODO: show a 'saving...' notification
var data = codeEditor.getText();
app.retriever.saveFile(data, function (err) {
if (err) {
app.notify.showError(err);
}
});
};
/**
@ -275,102 +275,102 @@ app.saveFile = function () {
* @returns {string}
*/
app.formatError = function (err) {
var message = '<pre class="error">' + err.toString() + '</pre>';
if (typeof(jsonlint) != 'undefined') {
message +=
'<a class="error" href="http://zaach.github.com/jsonlint/" target="_blank">' +
'validated by jsonlint' +
'</a>';
}
return message;
var message = '<pre class="error">' + err.toString() + '</pre>';
if (typeof(jsonlint) != 'undefined') {
message +=
'<a class="error" href="http://zaach.github.com/jsonlint/" target="_blank">' +
'validated by jsonlint' +
'</a>';
}
return message;
};
/**
* Clear the current file
*/
app.clearFile = function () {
var json = {};
codeEditor.set(json);
treeEditor.set(json);
var json = {};
codeEditor.set(json);
treeEditor.set(json);
};
app.resize = function() {
var domMenu = document.getElementById('menu');
var domTreeEditor = document.getElementById('treeEditor');
var domCodeEditor = document.getElementById('codeEditor');
var domSplitter = document.getElementById('splitter');
var domSplitterButtons = document.getElementById('buttons');
var domSplitterDrag = document.getElementById('drag');
var domAd = document.getElementById('ad');
var domMenu = document.getElementById('menu');
var domTreeEditor = document.getElementById('treeEditor');
var domCodeEditor = document.getElementById('codeEditor');
var domSplitter = document.getElementById('splitter');
var domSplitterButtons = document.getElementById('buttons');
var domSplitterDrag = document.getElementById('drag');
var domAd = document.getElementById('ad');
var margin = 15;
var width = (window.innerWidth || document.body.offsetWidth ||
document.documentElement.offsetWidth);
var adWidth = domAd ? domAd.clientWidth : 0;
var margin = 15;
var width = (window.innerWidth || document.body.offsetWidth ||
document.documentElement.offsetWidth);
var adWidth = domAd ? domAd.clientWidth : 0;
if (adWidth) {
width -= (adWidth + margin);
}
if (app.splitter) {
app.splitter.setWidth(width);
// calculate horizontal splitter position
var value = app.splitter.getValue();
var showCodeEditor = (value > 0);
var showTreeEditor = (value < 1);
var showButtons = showCodeEditor && showTreeEditor;
domSplitterButtons.style.display = showButtons ? '' : 'none';
var splitterWidth = domSplitter.clientWidth;
var splitterLeft;
if (!showCodeEditor) {
// code editor not visible
splitterLeft = 0;
domSplitterDrag.innerHTML = '&rsaquo;';
domSplitterDrag.title = 'Drag right to show the code editor';
}
else if (!showTreeEditor) {
// tree editor not visible
splitterLeft = width * value - splitterWidth;
domSplitterDrag.innerHTML = '&lsaquo;';
domSplitterDrag.title = 'Drag left to show the tree editor';
}
else {
// both tree and code editor visible
splitterLeft = width * value - splitterWidth / 2;
// TODO: find a character with vertical dots that works on IE8 too, or use an image
var isIE8 = (jsoneditor.util.getInternetExplorerVersion() == 8);
domSplitterDrag.innerHTML = (!isIE8) ? '&#8942;' : '|';
domSplitterDrag.title = 'Drag left or right to change the width of the panels';
}
// resize code editor
domCodeEditor.style.display = (value == 0) ? 'none' : '';
domCodeEditor.style.width = Math.max(Math.round(splitterLeft), 0) + 'px';
codeEditor.resize();
// resize the splitter
domSplitterDrag.style.height = (domSplitter.clientHeight -
domSplitterButtons.clientHeight - 2 * margin -
(showButtons ? margin : 0)) + 'px';
domSplitterDrag.style.lineHeight = domSplitterDrag.style.height;
// resize tree editor
// the width has a -1 to prevent the width from being just half a pixel
// wider than the window, causing the content elements to wrap...
domTreeEditor.style.display = (value == 1) ? 'none' : '';
domTreeEditor.style.left = Math.round(splitterLeft + splitterWidth) + 'px';
domTreeEditor.style.width = Math.max(Math.round(width - splitterLeft - splitterWidth - 2), 0) + 'px';
}
// align main menu with ads
if (domMenu) {
if (adWidth) {
width -= (adWidth + margin);
domMenu.style.right = (margin + (adWidth + margin)) + 'px';
}
if (app.splitter) {
app.splitter.setWidth(width);
// calculate horizontal splitter position
var value = app.splitter.getValue();
var showCodeEditor = (value > 0);
var showTreeEditor = (value < 1);
var showButtons = showCodeEditor && showTreeEditor;
domSplitterButtons.style.display = showButtons ? '' : 'none';
var splitterWidth = domSplitter.clientWidth;
var splitterLeft;
if (!showCodeEditor) {
// code editor not visible
splitterLeft = 0;
domSplitterDrag.innerHTML = '&rsaquo;';
domSplitterDrag.title = 'Drag right to show the code editor';
}
else if (!showTreeEditor) {
// tree editor not visible
splitterLeft = width * value - splitterWidth;
domSplitterDrag.innerHTML = '&lsaquo;';
domSplitterDrag.title = 'Drag left to show the tree editor';
}
else {
// both tree and code editor visible
splitterLeft = width * value - splitterWidth / 2;
// TODO: find a character with vertical dots that works on IE8 too, or use an image
var isIE8 = (jsoneditor.util.getInternetExplorerVersion() == 8);
domSplitterDrag.innerHTML = (!isIE8) ? '&#8942;' : '|';
domSplitterDrag.title = 'Drag left or right to change the width of the panels';
}
// resize code editor
domCodeEditor.style.display = (value == 0) ? 'none' : '';
domCodeEditor.style.width = Math.max(Math.round(splitterLeft), 0) + 'px';
codeEditor.resize();
// resize the splitter
domSplitterDrag.style.height = (domSplitter.clientHeight -
domSplitterButtons.clientHeight - 2 * margin -
(showButtons ? margin : 0)) + 'px';
domSplitterDrag.style.lineHeight = domSplitterDrag.style.height;
// resize tree editor
// the width has a -1 to prevent the width from being just half a pixel
// wider than the window, causing the content elements to wrap...
domTreeEditor.style.display = (value == 1) ? 'none' : '';
domTreeEditor.style.left = Math.round(splitterLeft + splitterWidth) + 'px';
domTreeEditor.style.width = Math.max(Math.round(width - splitterLeft - splitterWidth - 2), 0) + 'px';
}
// align main menu with ads
if (domMenu) {
if (adWidth) {
domMenu.style.right = (margin + (adWidth + margin)) + 'px';
}
else {
domMenu.style.right = margin + 'px';
}
else {
domMenu.style.right = margin + 'px';
}
}
};

View File

@ -1,17 +1,17 @@
<html>
<head>
<title>JSON Editor Online - Beta</title>
<link href="../doc/doc.css" type="text/css" rel="stylesheet">
<title>JSON Editor Online - Beta</title>
<link href="../doc/doc.css" type="text/css" rel="stylesheet">
</head>
<body>
<div id="container">
<h1>JSON Editor Online - Beta</h1>
<p>
There is currently no beta version available.
</p>
<p>
<a href="http://jsoneditoronline.org/">Go to the current version</a>
</p>
<h1>JSON Editor Online - Beta</h1>
<p>
There is currently no beta version available.
</p>
<p>
<a href="http://jsoneditoronline.org/">Go to the current version</a>
</p>
</div>
</body>
</html>

View File

@ -1,60 +1,60 @@
body, td, th {
font-family: arial, sans-serif;
font-size: 11pt;
color: #4d4d4d;
font-family: arial, sans-serif;
font-size: 11pt;
color: #4d4d4d;
}
body, html {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
#container {
width: 600px;
margin: 0 auto;
padding: 20px 0 60px 0;
width: 600px;
margin: 0 auto;
padding: 20px 0 60px 0;
}
h1 {
font-size: 14pt;
color: #4d4d4d;
font-size: 14pt;
color: #4d4d4d;
}
h2 {
font-size: 11pt;
color: #97B0F8;
padding-top: 20px;
font-size: 11pt;
color: #97B0F8;
padding-top: 20px;
}
table {
border-collapse: collapse;
border-collapse: collapse;
}
th {
text-align: left;
background-color: #e5e5e5;;
text-align: left;
background-color: #e5e5e5;;
}
td {
vertical-align: top;
vertical-align: top;
}
th, td {
border: 1px solid #e5e5e5;
padding: 4px 4px;
border: 1px solid #e5e5e5;
padding: 4px 4px;
}
a {
color: #4183C4;
color: #4183C4;
}
a:hover {
color: red;
color: red;
}
img.icon {
vertical-align: middle;
margin: 0 5px;
vertical-align: middle;
margin: 0 5px;
}

View File

@ -1,201 +1,201 @@
<!DOCTYPE HTML>
<html>
<head>
<title>JSON Editor Online - Documentation</title>
<link href="doc.css" rel="stylesheet" type="text/css">
<title>JSON Editor Online - Documentation</title>
<link href="doc.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="container">
<h1 id="documentation">JSON Editor Online - Documentation</h1>
<h1 id="documentation">JSON Editor Online - Documentation</h1>
<h2 id="introduction">Introduction</h2>
<p>
JSON Editor Online is a web-based tool to view, edit, and format JSON.
It shows your data side by side in a clear, editable treeview and in
a code editor.
</p>
<p>
Supported browsers: Chrome, Firefox, Safari, Opera, Internet Explorer 8+.
</p>
<p>
Website: <a href="http://jsoneditoronline.org" target="_blank">
http://jsoneditoronline.org</a>.
</p>
<p>
Contents:
</p>
<ul>
<li><a href="#main_menu">Main menu</a></li>
<li><a href="#panels">Panels</a></li>
<li><a href="#code_editor">Code editor</a></li>
<li><a href="#tree_editor">Tree editor</a></li>
<li><a href="#shortcut_keys">Shortcut keys</a></li>
</ul>
<h2 id="introduction">Introduction</h2>
<p>
JSON Editor Online is a web-based tool to view, edit, and format JSON.
It shows your data side by side in a clear, editable treeview and in
a code editor.
</p>
<p>
Supported browsers: Chrome, Firefox, Safari, Opera, Internet Explorer 8+.
</p>
<p>
Website: <a href="http://jsoneditoronline.org" target="_blank">
http://jsoneditoronline.org</a>.
</p>
<p>
Contents:
</p>
<ul>
<li><a href="#main_menu">Main menu</a></li>
<li><a href="#panels">Panels</a></li>
<li><a href="#code_editor">Code editor</a></li>
<li><a href="#tree_editor">Tree editor</a></li>
<li><a href="#shortcut_keys">Shortcut keys</a></li>
</ul>
<h2 id="main_menu">Main menu</h2>
<p>
The applications main menu contains options to clear, load and save the
JSON contents of the application. Files can be loaded from disk or url,
and can be saved to disk. Please note that due to security restrictions,
the application can only open files from public websites, not from an
intranet. The data policy is described
<a href="http://jsoneditoronline.org/datapolicy.txt">here</a>.
</p>
<img src="img/main_menu.png" alt="Main menu">
<h2 id="main_menu">Main menu</h2>
<p>
The applications main menu contains options to clear, load and save the
JSON contents of the application. Files can be loaded from disk or url,
and can be saved to disk. Please note that due to security restrictions,
the application can only open files from public websites, not from an
intranet. The data policy is described
<a href="http://jsoneditoronline.org/datapolicy.txt">here</a>.
</p>
<img src="img/main_menu.png" alt="Main menu">
<h2 id="panels">Panels</h2>
<p>
The application contains two panels: a <b>code editor</b> on the left,
and a <b>Tree Editor</b> on the right.
</p>
<p>
There is a splitter between the two panels, allowing to change the
width of both panels according to ones needs.
To copy the contents from one panel to an other, the two copy buttons
between the panels can be used.
</p>
<img src="img/splitter.png">
<h2 id="panels">Panels</h2>
<p>
The application contains two panels: a <b>code editor</b> on the left,
and a <b>Tree Editor</b> on the right.
</p>
<p>
There is a splitter between the two panels, allowing to change the
width of both panels according to ones needs.
To copy the contents from one panel to an other, the two copy buttons
between the panels can be used.
</p>
<img src="img/splitter.png">
<h2 id="code_editor"> Code editor</h2>
<p>
The code editor displays JSON data in a code editor.
The editor is capable of formatting, compacting, and inspecting JSON.
</p>
<img src="img/code_editor.png">
<p>
The menu of the code editor contains the following buttons:
</p>
<ul>
<li>
<b>Format</b>.
Format the JSON data, make the data readable by applying indentation
and returns.
</li>
<li>
<b>Compact</b>.
Compact the JSON data, remove all unnecessary characters like
whitespaces and returns.
</li>
</ul>
<h2 id="code_editor"> Code editor</h2>
<p>
The code editor displays JSON data in a code editor.
The editor is capable of formatting, compacting, and inspecting JSON.
</p>
<img src="img/code_editor.png">
<p>
The menu of the code editor contains the following buttons:
</p>
<ul>
<li>
<b>Format</b>.
Format the JSON data, make the data readable by applying indentation
and returns.
</li>
<li>
<b>Compact</b>.
Compact the JSON data, remove all unnecessary characters like
whitespaces and returns.
</li>
</ul>
<h2 id="tree_editor">Tree editor</h2>
<p>
The Tree editor displays the JSON data in an editable tree.
The editor makes it easy to create, duplicate, remove fields,
and to edit the contents of the fields.
</p>
<img src="img/tree_editor.png">
<p>
The menu of the tree editor contains the following functions:
</p>
<ul>
<li>
<b>Expand all</b>. Expand all fields in the editor.
</li>
<li>
<b>Collapse all</b>. Collapse all fields in the editor.
</li>
<li>
<b>Undo</b>. Undo last action.
</li>
<li>
<b>Redo</b>. Redo last action.
</li>
<li>
<b>Search</b>. Search for text in the tree editor.
Search results will be highlighted, and can be iterated by
repeatedly pressing Enter or Shift+Enter.
The right side of the search box two buttons to go to the next or
previous search result.
</li>
</ul>
<h2 id="tree_editor">Tree editor</h2>
<p>
The Tree editor displays the JSON data in an editable tree.
The editor makes it easy to create, duplicate, remove fields,
and to edit the contents of the fields.
</p>
<img src="img/tree_editor.png">
<p>
The menu of the tree editor contains the following functions:
</p>
<ul>
<li>
<b>Expand all</b>. Expand all fields in the editor.
</li>
<li>
<b>Collapse all</b>. Collapse all fields in the editor.
</li>
<li>
<b>Undo</b>. Undo last action.
</li>
<li>
<b>Redo</b>. Redo last action.
</li>
<li>
<b>Search</b>. Search for text in the tree editor.
Search results will be highlighted, and can be iterated by
repeatedly pressing Enter or Shift+Enter.
The right side of the search box two buttons to go to the next or
previous search result.
</li>
</ul>
<p>
The field values in the editor are editable input fields.
The fields can be dragged up and down using the dragarea
<img src="img/button_dragarea.png" class="icon">
on the left side of the fields. When a field is the last item of the
childs of an array or object, the field can also be dragged horizontally
to move it in or out of the array or object.
</p>
<img src="img/actions_menu.png" align="right" style="padding-left: 20px;">
<p>
Right from the dragarea is a button
<img src="img/button_actions_menu.png" class="icon">
to open the <b>actions menu</b>.
Depending on the type of field, the following functionality is
available in the actions menu:
</p>
<ul>
<p>
The field values in the editor are editable input fields.
The fields can be dragged up and down using the dragarea
<img src="img/button_dragarea.png" class="icon">
on the left side of the fields. When a field is the last item of the
childs of an array or object, the field can also be dragged horizontally
to move it in or out of the array or object.
</p>
<img src="img/actions_menu.png" align="right" style="padding-left: 20px;">
<p>
Right from the dragarea is a button
<img src="img/button_actions_menu.png" class="icon">
to open the <b>actions menu</b>.
Depending on the type of field, the following functionality is
available in the actions menu:
</p>
<ul>
<li>
<b>Type</b>. Change the type of the field. Choose from:
<ul>
<li>
<b>Type</b>. Change the type of the field. Choose from:
<ul>
<li>
<b>auto</b> The field type is automatically determined from
the value and can be a string, number, boolean, or null.
</li>
<li>
<b>object</b> An unordered set of key/value pairs.
</li>
<li>
<b>array</b> An ordered collection of values.
</li>
<li>
<b>string</b> Field type is not determined from the value,
but always returned as string.
</li>
</ul>
<b>auto</b> The field type is automatically determined from
the value and can be a string, number, boolean, or null.
</li>
<li>
<b>Sort</b>. Sort the childs of an array or object.
For an array, the values of the childs will be sorted. In case of
an object, the childs will be sorted by key.
Arrays and objects can be sorted ascending or descending.
<b>object</b> An unordered set of key/value pairs.
</li>
<li>
<b>Insert</b>. Insert a new field before current field.
Available types are auto (default), object, array, and string.
<b>array</b> An ordered collection of values.
</li>
<li>
<b>Append</b>. Insert a new field after current field.
Available types are the same as the insert action.
<b>string</b> Field type is not determined from the value,
but always returned as string.
</li>
<li>
<b>Duplicate</b>. Duplicate the field including all childs.
</li>
<li>
<b>Remove</b>. Remove the field including all childs.
</li>
</ul>
</ul>
</li>
<li>
<b>Sort</b>. Sort the childs of an array or object.
For an array, the values of the childs will be sorted. In case of
an object, the childs will be sorted by key.
Arrays and objects can be sorted ascending or descending.
</li>
<li>
<b>Insert</b>. Insert a new field before current field.
Available types are auto (default), object, array, and string.
</li>
<li>
<b>Append</b>. Insert a new field after current field.
Available types are the same as the insert action.
</li>
<li>
<b>Duplicate</b>. Duplicate the field including all childs.
</li>
<li>
<b>Remove</b>. Remove the field including all childs.
</li>
</ul>
<h2 id="shortcut_keys">Shortcut keys</h2>
<p>
The tree editor supports shortcut keys for all available actions.
The editor can be used by just a keyboard.
The following short cut keys are available:
</p>
<h2 id="shortcut_keys">Shortcut keys</h2>
<p>
The tree editor supports shortcut keys for all available actions.
The editor can be used by just a keyboard.
The following short cut keys are available:
</p>
<table>
<tr><th>Key</th><th>Description</th></tr>
<tr><td>Alt+Arrows</td><td>Move the caret up/down/left/right between fields</td></tr>
<tr><td>Shift+Alt+Arrows</td><td>Move field up/down/left/right</td></tr>
<table>
<tr><th>Key</th><th>Description</th></tr>
<tr><td>Alt+Arrows</td><td>Move the caret up/down/left/right between fields</td></tr>
<tr><td>Shift+Alt+Arrows</td><td>Move field up/down/left/right</td></tr>
<tr><td>Ctrl+D</td><td>Duplicate field</td></tr>
<tr><td>Ctrl+Del</td><td>Remove field</td></tr>
<tr><td>Ctrl+Enter</td><td>Open link when on a field containing an url</td></tr>
<tr><td>Ctrl+Ins</td><td>Insert a new field with type auto</td></tr>
<tr><td>Ctrl+Shift+Ins</td><td>Append a new field with type auto</td></tr>
<tr><td>Ctrl+E</td><td>Expand or collapse field</td></tr>
<tr><td>Alt+End</td><td>Move the caret to the last field</td></tr>
<tr><td>Ctrl+F</td><td>Find</td></tr>
<tr><td>F3, Ctrl+G<br></td><td>Find next</td></tr>
<tr><td>Shift+F3, Ctrl+Shift+G</td><td>Find previous</td></tr>
<tr><td>Alt+Home</td><td>Move the caret to the first field</td></tr>
<tr><td>Ctrl+M</td><td>Show actions menu</td></tr>
<tr><td>Ctrl+Z</td><td>Undo last action</td></tr>
<tr><td>Ctrl+Shift+Z</td><td>Redo</td></tr>
</table>
<tr><td>Ctrl+D</td><td>Duplicate field</td></tr>
<tr><td>Ctrl+Del</td><td>Remove field</td></tr>
<tr><td>Ctrl+Enter</td><td>Open link when on a field containing an url</td></tr>
<tr><td>Ctrl+Ins</td><td>Insert a new field with type auto</td></tr>
<tr><td>Ctrl+Shift+Ins</td><td>Append a new field with type auto</td></tr>
<tr><td>Ctrl+E</td><td>Expand or collapse field</td></tr>
<tr><td>Alt+End</td><td>Move the caret to the last field</td></tr>
<tr><td>Ctrl+F</td><td>Find</td></tr>
<tr><td>F3, Ctrl+G<br></td><td>Find next</td></tr>
<tr><td>Shift+F3, Ctrl+Shift+G</td><td>Find previous</td></tr>
<tr><td>Alt+Home</td><td>Move the caret to the first field</td></tr>
<tr><td>Ctrl+M</td><td>Show actions menu</td></tr>
<tr><td>Ctrl+Z</td><td>Undo last action</td></tr>
<tr><td>Ctrl+Shift+Z</td><td>Redo</td></tr>
</table>
</div>
</body>
</html>

View File

@ -1,63 +1,63 @@
div.fileretriever-overlay, div.fileretriever-background {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 999;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 999;
}
div.fileretriever-overlay {
background-color: gray;
opacity: 0.2;
filter: alpha(opacity = 20);
background-color: gray;
opacity: 0.2;
filter: alpha(opacity = 20);
}
div.fileretriever-border {
width: 410px;
margin: 100px auto;
padding: 20px;
background-color: white;
border: 1px solid gray;
border-radius: 2px;
width: 410px;
margin: 100px auto;
padding: 20px;
background-color: white;
border: 1px solid gray;
border-radius: 2px;
-moz-box-shadow: 2px 2px 12px rgba(128, 128, 128, 0.3);
-webkit-box-shadow: 2px 2px 12px rgba(128, 128, 128, 0.3);
box-shadow: 2px 2px 12px rgba(128, 128, 128, 0.3);
-moz-box-shadow: 2px 2px 12px rgba(128, 128, 128, 0.3);
-webkit-box-shadow: 2px 2px 12px rgba(128, 128, 128, 0.3);
box-shadow: 2px 2px 12px rgba(128, 128, 128, 0.3);
}
form.fileretriever-form {
}
div.fileretriever-title {
font-weight: bold;
font-weight: bold;
}
div.fileretriever-description {
color: gray;
margin: 30px 0 0 0;
color: gray;
margin: 30px 0 0 0;
}
div.fileretriever-contents {
margin: 30px 0;
margin: 30px 0;
}
div.fileretriever-buttons {
text-align: right;
text-align: right;
}
input.fileretriever-field[type="file"] {
width: 400px;
padding: 3px;
width: 400px;
padding: 3px;
}
input.fileretriever-field[type="text"] {
width: 400px;
border: 1px solid lightgray;
border-radius: 2px;
padding: 3px;
width: 400px;
border: 1px solid lightgray;
border-radius: 2px;
padding: 3px;
}
input.fileretriever-submit, input.fileretriever-cancel {
margin-left: 10px;
margin-left: 10px;
}

View File

@ -1,16 +1,16 @@
/**
* @file fileretriever.js
*
*
* FileRetriever manages client side loading and saving of files.
* It requires a server script (fileretriever.php). Loading and saving
* files is done purely clientside using HTML5 techniques when supported
* by the browser.
*
*
* Requires ajax.js.
*
* Supported browsers: Chrome, Firefox, Opera, Safari,
*
* Supported browsers: Chrome, Firefox, Opera, Safari,
* Internet Explorer 8+.
*
*
* Example usage:
* var retriever = new FileRetriever({
* 'serverUrl': 'fileretriever.php'
@ -22,17 +22,17 @@
* console.log('url loaded:', data);
* });
* retriever.saveFile("some text");
*
*
* @constructor FileRetriever
* @param {String} options Available options:
* {string} serverUrl Server side script for
* handling files, for
* handling files, for
* example "fileretriever.php"
* {Number} [maxSize] Maximum allowed file size
* in bytes. (this should
* be the same as maximum
* size allowed by the server
* side script). Default is
* in bytes. (this should
* be the same as maximum
* size allowed by the server
* side script). Default is
* 1024 * 1024 bytes.
* {Number} [timeout] Timeout in milliseconds.
* 30000 ms by default.
@ -63,18 +63,18 @@
* @date 2013-01-01
*/
var FileRetriever = function (options) {
// set options and variables
options = options || {};
this.options = {
maxSize: ((options.maxSize != undefined) ? options.maxSize : 1024 * 1024),
html5: ((options.html5 != undefined) ? options.html5 : true)
};
this.timeout = Number(options.timeout) || 30000;
this.headers = {'Accept': 'application/json'}; // headers for ajax requests
this.scriptUrl = options.scriptUrl || 'fileretriever.php';
this.notify = options.notify || undefined;
this.defaultFilename = 'document.json';
this.dom = {};
// set options and variables
options = options || {};
this.options = {
maxSize: ((options.maxSize != undefined) ? options.maxSize : 1024 * 1024),
html5: ((options.html5 != undefined) ? options.html5 : true)
};
this.timeout = Number(options.timeout) || 30000;
this.headers = {'Accept': 'application/json'}; // headers for ajax requests
this.scriptUrl = options.scriptUrl || 'fileretriever.php';
this.notify = options.notify || undefined;
this.defaultFilename = 'document.json';
this.dom = {};
};
/**
@ -83,12 +83,12 @@ var FileRetriever = function (options) {
* @private
*/
FileRetriever.prototype._hide = function (elem) {
elem.style.visibility = 'hidden';
elem.style.position = 'absolute';
elem.style.left = '-1000px';
elem.style.top = '-1000px';
elem.style.width = '0';
elem.style.height = '0';
elem.style.visibility = 'hidden';
elem.style.position = 'absolute';
elem.style.left = '-1000px';
elem.style.top = '-1000px';
elem.style.width = '0';
elem.style.height = '0';
};
/**
@ -96,16 +96,16 @@ FileRetriever.prototype._hide = function (elem) {
* The FileRetriever cannot be used after its DOM elements are deleted.
*/
FileRetriever.prototype.remove = function () {
var dom = this.dom;
for (var prop in dom) {
if (dom.hasOwnProperty(prop)) {
var elem = dom[prop];
if (elem.parentNode) {
elem.parentNode.removeChild(elem);
}
}
var dom = this.dom;
for (var prop in dom) {
if (dom.hasOwnProperty(prop)) {
var elem = dom[prop];
if (elem.parentNode) {
elem.parentNode.removeChild(elem);
}
}
this.dom = {};
}
this.dom = {};
};
/**
@ -116,8 +116,8 @@ FileRetriever.prototype.remove = function () {
* @private
*/
FileRetriever.prototype._getFilename = function (path) {
// http://stackoverflow.com/a/423385/1262753
return path ? path.replace(/^.*[\\\/]/, '') : '';
// http://stackoverflow.com/a/423385/1262753
return path ? path.replace(/^.*[\\\/]/, '') : '';
};
/**
@ -125,7 +125,7 @@ FileRetriever.prototype._getFilename = function (path) {
* @param {String} url
*/
FileRetriever.prototype.setUrl = function (url) {
this.url = url;
this.url = url;
};
/**
@ -133,7 +133,7 @@ FileRetriever.prototype.setUrl = function (url) {
* @return {String} filename
*/
FileRetriever.prototype.getFilename = function () {
return this.defaultFilename;
return this.defaultFilename;
};
/**
@ -141,7 +141,7 @@ FileRetriever.prototype.getFilename = function () {
* @return {String | undefined} url
*/
FileRetriever.prototype.getUrl = function () {
return this.url;
return this.url;
};
/**
@ -152,61 +152,61 @@ FileRetriever.prototype.getUrl = function () {
* {string} data
*/
FileRetriever.prototype.loadUrl = function (url, callback) {
// set current filename (will be used when saving a file again)
this.setUrl(url);
// set current filename (will be used when saving a file again)
this.setUrl(url);
// loading notification
var loading = undefined;
if (this.notify) {
loading = this.notify.showNotification('loading url...');
// loading notification
var loading = undefined;
if (this.notify) {
loading = this.notify.showNotification('loading url...');
}
// method to ensure the callback is only executed once
var me = this;
var callbackOnce = function (error, data) {
if (callback) {
callback(error, data);
callback = undefined;
}
if (me.notify && loading) {
me.notify.removeMessage(loading);
loading = undefined;
}
};
// method to ensure the callback is only executed once
var me = this;
var callbackOnce = function (error, data) {
if (callback) {
callback(error, data);
callback = undefined;
}
if (me.notify && loading) {
me.notify.removeMessage(loading);
loading = undefined;
}
};
// try to fetch to the url directly (may result in a cross-domain error)
var scriptUrl = this.scriptUrl;
ajax.get(url, me.headers, function(data, status) {
// try to fetch to the url directly (may result in a cross-domain error)
var scriptUrl = this.scriptUrl;
ajax.get(url, me.headers, function(data, status) {
if (status == 200) {
// success. great. no cross-domain error
callbackOnce(null, data);
}
else {
// cross-domain error (or other). retrieve the url via the server
var indirectUrl = scriptUrl + '?url=' + encodeURIComponent(url);
var err;
ajax.get(indirectUrl, me.headers, function(data, status) {
if (status == 200) {
// success. great. no cross-domain error
callbackOnce(null, data);
callbackOnce(null, data);
}
else if (status == 404) {
console.log('Error: url "' + url + '" not found', status, data);
err = new Error('Error: url "' + url + '" not found');
callbackOnce(err, null);
}
else {
// cross-domain error (or other). retrieve the url via the server
var indirectUrl = scriptUrl + '?url=' + encodeURIComponent(url);
var err;
ajax.get(indirectUrl, me.headers, function(data, status) {
if (status == 200) {
callbackOnce(null, data);
}
else if (status == 404) {
console.log('Error: url "' + url + '" not found', status, data);
err = new Error('Error: url "' + url + '" not found');
callbackOnce(err, null);
}
else {
console.log('Error: failed to load url "' + url + '"', status, data);
err = new Error('Error: failed to load url "' + url + '"');
callbackOnce(err, null);
}
});
console.log('Error: failed to load url "' + url + '"', status, data);
err = new Error('Error: failed to load url "' + url + '"');
callbackOnce(err, null);
}
});
});
}
});
// safety mechanism: callback after a timeout
setTimeout(function () {
callbackOnce(new Error('Error loading url (time out)'));
}, this.timeout);
// safety mechanism: callback after a timeout
setTimeout(function () {
callbackOnce(new Error('Error loading url (time out)'));
}, this.timeout);
};
/**
@ -219,115 +219,115 @@ FileRetriever.prototype.loadUrl = function (url, callback) {
* {string} data
*/
FileRetriever.prototype.loadFile = function (callback) {
// loading notification
var loading = undefined;
var me = this;
// loading notification
var loading = undefined;
var me = this;
var startLoading = function () {
if (me.notify && !loading) {
loading = me.notify.showNotification('loading file...');
}
// safety mechanism: callback after a timeout
setTimeout(function () {
callbackOnce(new Error('Error loading url (time out)'));
}, me.timeout);
};
// method to ensure the callback is only executed once
var callbackOnce = function (error, data) {
if (callback) {
callback(error, data);
callback = undefined;
}
if (me.notify && loading) {
me.notify.removeMessage(loading);
loading = undefined;
}
};
// create a form to select a file and submit
var useFileReader = (me.options.html5 && window.File && window.FileReader);
if (useFileReader) {
this.prompt({
title: 'Open file',
titleSubmit: 'Open',
description: 'Select a file on your computer.',
inputType: 'file',
inputName: 'file',
callback: function (value, field) {
if (value) {
if (useFileReader) {
// load file via HTML5 FileReader (no size limits)
var file = field.files[0];
var reader = new FileReader();
reader.onload = function(event) {
var data = event.target.result;
callbackOnce(null, data);
};
// Read in the image file as a data URL.
reader.readAsText(file);
}
startLoading();
}
}
});
// TODO: handle a cancel
var startLoading = function () {
if (me.notify && !loading) {
loading = me.notify.showNotification('loading file...');
}
else {
// no html5 filereader available
// create an iframe for uploading files
// the iframe must have an unique name, allowing multiple
// FileRetrievers. The name is needed as target for the uploadForm
var iframeName = 'fileretriever-upload-' + Math.round(Math.random() * 1E15);
var iframe = document.createElement('iframe');
iframe.name = iframeName;
me._hide(iframe);
iframe.onload = function () {
// when a downloaded file is retrieved, send a callback with
// the retrieved data
var id = iframe.contentWindow.document.body.innerHTML;
if (id) {
var url = me.scriptUrl + '?id=' + id + '&filename=' + me.getFilename();
ajax.get(url, me.headers, function (data, status) {
if (status == 200) {
callbackOnce(null, data);
}
else {
var err = new Error('Error loading file ' + me.getFilename());
callbackOnce(err, null);
}
// safety mechanism: callback after a timeout
setTimeout(function () {
callbackOnce(new Error('Error loading url (time out)'));
}, me.timeout);
};
// cleanup the frame again
if (iframe.parentNode === document.body) {
document.body.removeChild(iframe);
}
});
}
};
document.body.appendChild(iframe);
this.prompt({
title: 'Open file',
titleSubmit: 'Open',
description: 'Select a file on your computer.',
inputType: 'file',
inputName: 'file',
formAction: this.scriptUrl,
formMethod: 'POST',
formTarget: iframeName,
callback: function (value) {
if (value) {
startLoading();
}
}
});
// TODO: handle a cancel
// method to ensure the callback is only executed once
var callbackOnce = function (error, data) {
if (callback) {
callback(error, data);
callback = undefined;
}
if (me.notify && loading) {
me.notify.removeMessage(loading);
loading = undefined;
}
};
// create a form to select a file and submit
var useFileReader = (me.options.html5 && window.File && window.FileReader);
if (useFileReader) {
this.prompt({
title: 'Open file',
titleSubmit: 'Open',
description: 'Select a file on your computer.',
inputType: 'file',
inputName: 'file',
callback: function (value, field) {
if (value) {
if (useFileReader) {
// load file via HTML5 FileReader (no size limits)
var file = field.files[0];
var reader = new FileReader();
reader.onload = function(event) {
var data = event.target.result;
callbackOnce(null, data);
};
// Read in the image file as a data URL.
reader.readAsText(file);
}
startLoading();
}
}
});
// TODO: handle a cancel
}
else {
// no html5 filereader available
// create an iframe for uploading files
// the iframe must have an unique name, allowing multiple
// FileRetrievers. The name is needed as target for the uploadForm
var iframeName = 'fileretriever-upload-' + Math.round(Math.random() * 1E15);
var iframe = document.createElement('iframe');
iframe.name = iframeName;
me._hide(iframe);
iframe.onload = function () {
// when a downloaded file is retrieved, send a callback with
// the retrieved data
var id = iframe.contentWindow.document.body.innerHTML;
if (id) {
var url = me.scriptUrl + '?id=' + id + '&filename=' + me.getFilename();
ajax.get(url, me.headers, function (data, status) {
if (status == 200) {
callbackOnce(null, data);
}
else {
var err = new Error('Error loading file ' + me.getFilename());
callbackOnce(err, null);
}
// cleanup the frame again
if (iframe.parentNode === document.body) {
document.body.removeChild(iframe);
}
});
}
};
document.body.appendChild(iframe);
this.prompt({
title: 'Open file',
titleSubmit: 'Open',
description: 'Select a file on your computer.',
inputType: 'file',
inputName: 'file',
formAction: this.scriptUrl,
formMethod: 'POST',
formTarget: iframeName,
callback: function (value) {
if (value) {
startLoading();
}
}
});
// TODO: handle a cancel
}
};
/**
@ -337,25 +337,25 @@ FileRetriever.prototype.loadFile = function (callback) {
* {String} data
*/
FileRetriever.prototype.loadUrlDialog = function (callback) {
var me = this;
this.prompt({
title: 'Open url',
titleSubmit: 'Open',
description: 'Enter a public url. ' +
'Urls which need authentication or are located on an intranet cannot be loaded.',
inputType: 'text',
inputName: 'url',
inputDefault: this.getUrl(),
callback: function (url) {
if (url) {
me.loadUrl(url, callback);
}
else {
// cancel
callback();
}
}
});
var me = this;
this.prompt({
title: 'Open url',
titleSubmit: 'Open',
description: 'Enter a public url. ' +
'Urls which need authentication or are located on an intranet cannot be loaded.',
inputType: 'text',
inputName: 'url',
inputDefault: this.getUrl(),
callback: function (url) {
if (url) {
me.loadUrl(url, callback);
}
else {
// cancel
callback();
}
}
});
};
/**
@ -379,197 +379,197 @@ FileRetriever.prototype.loadUrlDialog = function (callback) {
* {function} callback
*/
FileRetriever.prototype.prompt = function (params) {
var removeDialog = function () {
// remove the form
if (background.parentNode) {
background.parentNode.removeChild(background);
}
if (overlay.parentNode) {
overlay.parentNode.removeChild(overlay);
}
jsoneditor.util.removeEventListener(document, 'keydown', onKeyDown);
};
var onCancel = function () {
removeDialog();
if(params.callback) {
params.callback(null);
}
};
var onKeyDown = jsoneditor.util.addEventListener(document, 'keydown', function (event) {
var keynum = event.which;
if (keynum == 27) { // ESC
onCancel();
event.preventDefault();
event.stopPropagation();
}
});
var overlay = document.createElement('div');
overlay.className = 'fileretriever-overlay';
document.body.appendChild(overlay);
var form = document.createElement('form');
form.className = 'fileretriever-form';
form.target = params.formTarget || '';
form.action = params.formAction || '';
form.method = params.formMethod || 'POST';
form.enctype = 'multipart/form-data';
form.encoding = 'multipart/form-data'; // needed for IE8 and older
form.onsubmit = function () {
if (field.value) {
setTimeout(function () {
// remove *after* the submit has taken place!
removeDialog();
}, 0);
if (params.callback) {
params.callback(field.value, field);
}
return (params.formAction != undefined && params.formMethod != undefined);
}
else {
alert('Enter a ' + params.inputName + ' first...');
return false;
}
};
var title = document.createElement('div');
title.className = 'fileretriever-title';
title.appendChild(document.createTextNode(params.title || 'Dialog'));
form.appendChild(title);
if (params.description) {
var description = document.createElement('div');
description.className = 'fileretriever-description';
description.appendChild(document.createTextNode(params.description));
form.appendChild(description);
var removeDialog = function () {
// remove the form
if (background.parentNode) {
background.parentNode.removeChild(background);
}
if (overlay.parentNode) {
overlay.parentNode.removeChild(overlay);
}
var field = document.createElement('input');
field.className = 'fileretriever-field';
field.type = params.inputType || 'text';
field.name = params.inputName || 'text';
field.value = params.inputDefault || '';
jsoneditor.util.removeEventListener(document, 'keydown', onKeyDown);
};
var contents = document.createElement('div');
contents.className = 'fileretriever-contents';
contents.appendChild(field);
form.appendChild(contents);
var onCancel = function () {
removeDialog();
if(params.callback) {
params.callback(null);
}
};
var cancel = document.createElement('input');
cancel.className = 'fileretriever-cancel';
cancel.type = 'button';
cancel.value = params.titleCancel || 'Cancel';
cancel.onclick = onCancel;
var onKeyDown = jsoneditor.util.addEventListener(document, 'keydown', function (event) {
var keynum = event.which;
if (keynum == 27) { // ESC
onCancel();
event.preventDefault();
event.stopPropagation();
}
});
var submit = document.createElement('input');
submit.className = 'fileretriever-submit';
submit.type = 'submit';
submit.value = params.titleSubmit || 'Ok';
var overlay = document.createElement('div');
overlay.className = 'fileretriever-overlay';
document.body.appendChild(overlay);
var buttons = document.createElement('div');
buttons.className = 'fileretriever-buttons';
buttons.appendChild(cancel);
buttons.appendChild(submit);
form.appendChild(buttons);
var form = document.createElement('form');
form.className = 'fileretriever-form';
form.target = params.formTarget || '';
form.action = params.formAction || '';
form.method = params.formMethod || 'POST';
form.enctype = 'multipart/form-data';
form.encoding = 'multipart/form-data'; // needed for IE8 and older
form.onsubmit = function () {
if (field.value) {
setTimeout(function () {
// remove *after* the submit has taken place!
removeDialog();
}, 0);
if (params.callback) {
params.callback(field.value, field);
}
return (params.formAction != undefined && params.formMethod != undefined);
}
else {
alert('Enter a ' + params.inputName + ' first...');
return false;
}
};
var border = document.createElement('div');
border.className = 'fileretriever-border';
border.appendChild(form);
var title = document.createElement('div');
title.className = 'fileretriever-title';
title.appendChild(document.createTextNode(params.title || 'Dialog'));
form.appendChild(title);
var background = document.createElement('div');
background.className = 'fileretriever-background';
background.appendChild(border);
background.onclick = function (event) {
var target = event.target;
if (target == background) {
onCancel();
}
};
document.body.appendChild(background);
if (params.description) {
var description = document.createElement('div');
description.className = 'fileretriever-description';
description.appendChild(document.createTextNode(params.description));
form.appendChild(description);
}
field.focus();
field.select();
var field = document.createElement('input');
field.className = 'fileretriever-field';
field.type = params.inputType || 'text';
field.name = params.inputName || 'text';
field.value = params.inputDefault || '';
var contents = document.createElement('div');
contents.className = 'fileretriever-contents';
contents.appendChild(field);
form.appendChild(contents);
var cancel = document.createElement('input');
cancel.className = 'fileretriever-cancel';
cancel.type = 'button';
cancel.value = params.titleCancel || 'Cancel';
cancel.onclick = onCancel;
var submit = document.createElement('input');
submit.className = 'fileretriever-submit';
submit.type = 'submit';
submit.value = params.titleSubmit || 'Ok';
var buttons = document.createElement('div');
buttons.className = 'fileretriever-buttons';
buttons.appendChild(cancel);
buttons.appendChild(submit);
form.appendChild(buttons);
var border = document.createElement('div');
border.className = 'fileretriever-border';
border.appendChild(form);
var background = document.createElement('div');
background.className = 'fileretriever-background';
background.appendChild(border);
background.onclick = function (event) {
var target = event.target;
if (target == background) {
onCancel();
}
};
document.body.appendChild(background);
field.focus();
field.select();
};
/**
* Save data to disk
* @param {String} data
* @param {function} [callback] Callback when the file is saved, called
* @param {function} [callback] Callback when the file is saved, called
* with parameter:
* {Error} error
*/
FileRetriever.prototype.saveFile = function (data, callback) {
// saving notification
var saving = undefined;
if (this.notify) {
saving = this.notify.showNotification('saving file...');
// saving notification
var saving = undefined;
if (this.notify) {
saving = this.notify.showNotification('saving file...');
}
// method to ensure the callback is only executed once
var me = this;
var callbackOnce = function (error) {
if (callback) {
callback(error);
callback = undefined;
}
// method to ensure the callback is only executed once
var me = this;
var callbackOnce = function (error) {
if (callback) {
callback(error);
callback = undefined;
}
if (me.notify && saving) {
me.notify.removeMessage(saving);
saving = undefined;
}
};
// create an anchor to save files to disk (if supported by the browser)
// Note: save file using a.download is disabled in Firefox because of a
// a bug in Firefox, which breaks the cut/paste functionality of
// editable divs on the page.
var a = document.createElement('a');
if (this.options.html5 && a.download != undefined && !util.isFirefox()) {
// save file directly using a data URL
a.style.display = 'none';
a.href = 'data:application/json;charset=utf-8,' + encodeURIComponent(data);
a.download = this.getFilename();
// attach the element to the DOM, invoke a click action, and remove it again
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
callbackOnce();
if (me.notify && saving) {
me.notify.removeMessage(saving);
saving = undefined;
}
else {
// save file by uploading it to the server and then downloading
// it via an iframe
if (data.length < this.options.maxSize) {
ajax.post(me.scriptUrl, data, me.headers, function(id, status) {
if (status == 200) {
var iframe = document.createElement('iframe');
iframe.src = me.scriptUrl + '?id=' + id + '&filename=' + me.getFilename();
me._hide(iframe);
document.body.appendChild(iframe);
/* TODO: send callback after the iframe is loaded. Problem: iframe.onload does not work on IE
iframe.onload = function () {
callbackOnce();
};
//*/
callbackOnce();
// TODO: cleanup the iframe after the file is saved. Problem: we cannot know when the save dialog is closed.
}
else {
callbackOnce(new Error('Error saving file'));
}
});
};
// create an anchor to save files to disk (if supported by the browser)
// Note: save file using a.download is disabled in Firefox because of a
// a bug in Firefox, which breaks the cut/paste functionality of
// editable divs on the page.
var a = document.createElement('a');
if (this.options.html5 && a.download != undefined && !util.isFirefox()) {
// save file directly using a data URL
a.style.display = 'none';
a.href = 'data:application/json;charset=utf-8,' + encodeURIComponent(data);
a.download = this.getFilename();
// attach the element to the DOM, invoke a click action, and remove it again
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
callbackOnce();
}
else {
// save file by uploading it to the server and then downloading
// it via an iframe
if (data.length < this.options.maxSize) {
ajax.post(me.scriptUrl, data, me.headers, function(id, status) {
if (status == 200) {
var iframe = document.createElement('iframe');
iframe.src = me.scriptUrl + '?id=' + id + '&filename=' + me.getFilename();
me._hide(iframe);
document.body.appendChild(iframe);
/* TODO: send callback after the iframe is loaded. Problem: iframe.onload does not work on IE
iframe.onload = function () {
callbackOnce();
};
//*/
callbackOnce();
// TODO: cleanup the iframe after the file is saved. Problem: we cannot know when the save dialog is closed.
}
else {
callbackOnce(new Error('Maximum allowed file size exceeded (' +
this.options.maxSize + ' bytes)'));
callbackOnce(new Error('Error saving file'));
}
});
}
else {
callbackOnce(new Error('Maximum allowed file size exceeded (' +
this.options.maxSize + ' bytes)'));
}
}
// safety mechanism: callback after a timeout
setTimeout(function () {
callbackOnce(new Error('Error saving file (time out)'));
}, this.timeout);
// safety mechanism: callback after a timeout
setTimeout(function () {
callbackOnce(new Error('Error saving file (time out)'));
}, this.timeout);
};

View File

@ -10,18 +10,18 @@ function Hash() {}
* @return {Object} query object containing key/values
*/
Hash.prototype.getQuery = function () {
var hash = window.location.hash.substring(1); // skip the # character
var params = hash.split('&');
var query = {};
for (var i = 0, iMax = params.length; i < iMax; i++) {
var keyvalue = params[i].split('=');
if (keyvalue.length == 2) {
var key = decodeURIComponent(keyvalue[0]);
var value = decodeURIComponent(keyvalue[1]);
query[key] = value;
}
var hash = window.location.hash.substring(1); // skip the # character
var params = hash.split('&');
var query = {};
for (var i = 0, iMax = params.length; i < iMax; i++) {
var keyvalue = params[i].split('=');
if (keyvalue.length == 2) {
var key = decodeURIComponent(keyvalue[0]);
var value = decodeURIComponent(keyvalue[1]);
query[key] = value;
}
return query;
}
return query;
};
/**
@ -31,46 +31,46 @@ Hash.prototype.getQuery = function () {
* @param {function} callback Will be called with the new value as parameter
*/
Hash.prototype.onChange = function (key, callback) {
this.prevHash = '';
var me = this;
if (!me.callbacks) {
me.callbacks = [];
}
me.callbacks.push({
'key': key,
'value': undefined,
'callback': callback
});
this.prevHash = '';
var me = this;
if (!me.callbacks) {
me.callbacks = [];
}
me.callbacks.push({
'key': key,
'value': undefined,
'callback': callback
});
function checkForChanges() {
for (var i = 0; i < me.callbacks.length; i++) {
var obj = me.callbacks[i];
var value = me.getValue(obj.key);
var changed = (value !== obj.value);
obj.value = value;
if (changed) {
obj.callback(value);
}
}
function checkForChanges() {
for (var i = 0; i < me.callbacks.length; i++) {
var obj = me.callbacks[i];
var value = me.getValue(obj.key);
var changed = (value !== obj.value);
obj.value = value;
if (changed) {
obj.callback(value);
}
}
}
// source: http://stackoverflow.com/questions/2161906/handle-url-anchor-change-event-in-js
if ('onhashchange' in window) {
window.onhashchange = function () {
checkForChanges();
}
}
else {
// onhashchange event not supported
me.prevHash = window.location.hash;
window.setInterval(function () {
var hash = window.location.hash;
if (hash != me.prevHash) {
me.prevHash = hash;
checkForChanges();
}
}, 500);
// source: http://stackoverflow.com/questions/2161906/handle-url-anchor-change-event-in-js
if ('onhashchange' in window) {
window.onhashchange = function () {
checkForChanges();
}
}
else {
// onhashchange event not supported
me.prevHash = window.location.hash;
window.setInterval(function () {
var hash = window.location.hash;
if (hash != me.prevHash) {
me.prevHash = hash;
checkForChanges();
}
}, 500);
}
};
@ -79,23 +79,23 @@ Hash.prototype.onChange = function (key, callback) {
* @param {Object} query object with strings
*/
Hash.prototype.setQuery = function (query) {
var hash = '';
var hash = '';
for (var key in query) {
if (query.hasOwnProperty(key)) {
var value = query[key];
if (value != undefined) {
if (hash.length) {
hash += '&';
}
hash += encodeURIComponent(key);
hash += '=';
hash += encodeURIComponent(query[key]);
}
for (var key in query) {
if (query.hasOwnProperty(key)) {
var value = query[key];
if (value != undefined) {
if (hash.length) {
hash += '&';
}
hash += encodeURIComponent(key);
hash += '=';
hash += encodeURIComponent(query[key]);
}
}
}
window.location.hash = (hash.length ? ('#' + hash) : '');
window.location.hash = (hash.length ? ('#' + hash) : '');
};
@ -105,8 +105,8 @@ Hash.prototype.setQuery = function (query) {
* @return {String | undefined} value undefined when the value is not found
*/
Hash.prototype.getValue = function (key) {
var query = this.getQuery();
return query[key];
var query = this.getQuery();
return query[key];
};
/**
@ -115,9 +115,9 @@ Hash.prototype.getValue = function (key) {
* @param {String} value
*/
Hash.prototype.setValue = function (key, value) {
var query = this.getQuery();
query[key] = value;
this.setQuery(query);
var query = this.getQuery();
query[key] = value;
this.setQuery(query);
};
/**
@ -125,9 +125,9 @@ Hash.prototype.setValue = function (key, value) {
* @param {String} key
*/
Hash.prototype.removeValue = function (key) {
var query = this.getQuery();
if (query[key]) {
delete query[key];
this.setQuery(query);
}
var query = this.getQuery();
if (query[key]) {
delete query[key];
this.setQuery(query);
}
};

View File

@ -2,186 +2,186 @@
<html manifest="/cache.manifest">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>JSON Editor Online - view, edit and format JSON online</title>
<title>JSON Editor Online - view, edit and format JSON online</title>
<!--
<!--
@file index.html
@file index.html
@brief
JSON Editor Online is a web-based tool to view, edit, and format JSON.
It shows your data side by side in a clear, editable treeview and in
a code editor.
@brief
JSON Editor Online is a web-based tool to view, edit, and format JSON.
It shows your data side by side in a clear, editable treeview and in
a code editor.
Supported browsers: Chrome, Firefox, Safari, Opera, Internet Explorer 8+
Supported browsers: Chrome, Firefox, Safari, Opera, Internet Explorer 8+
@license
This json editor is open sourced with the intention to use the editor as
a component in your own application. Not to just copy and monetize the editor
as it is.
@license
This json editor is open sourced with the intention to use the editor as
a component in your own application. Not to just copy and monetize the editor
as it is.
Licensed under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy
of the License at
Licensed under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy
of the License at
http://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations under
the License.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations under
the License.
Copyright (C) 2011-2013 Jos de Jong, http://jsoneditoronline.org
Copyright (C) 2011-2013 Jos de Jong, http://jsoneditoronline.org
@author Jos de Jong, <wjosdejong@gmail.com>
@version @@version
@date @@date
-->
@author Jos de Jong, <wjosdejong@gmail.com>
@version @@version
@date @@date
-->
<meta name="description" content="JSON Editor Online is a web-based tool to view, edit, and format JSON. It shows your data side by side in a clear, editable treeview and in a code editor.">
<meta name="keywords" content="json, editor, formatter, online, format, parser, json editor, json editor online, online json editor, javascript, javascript object notation, tools, tool, json tools, treeview, open source, free, json parser, json parser online, json formatter, json formatter online, online json formatter, online json parser, format json online">
<meta name="author" content="Jos de Jong">
<meta name="description" content="JSON Editor Online is a web-based tool to view, edit, and format JSON. It shows your data side by side in a clear, editable treeview and in a code editor.">
<meta name="keywords" content="json, editor, formatter, online, format, parser, json editor, json editor online, online json editor, javascript, javascript object notation, tools, tool, json tools, treeview, open source, free, json parser, json parser online, json formatter, json formatter online, online json formatter, online json parser, format json online">
<meta name="author" content="Jos de Jong">
<link rel="shortcut icon" href="favicon.ico">
<link rel="shortcut icon" href="favicon.ico">
<link rel="stylesheet" type="text/css" href="app-min.css">
<link rel="stylesheet" type="text/css" href="lib/jsoneditor/jsoneditor-min.css">
<!-- TODO: droid font
<link href='http://fonts.googleapis.com/css?family=Droid+Sans+Mono' rel='stylesheet' type='text/css'>
-->
<link rel="stylesheet" type="text/css" href="app-min.css">
<link rel="stylesheet" type="text/css" href="lib/jsoneditor/jsoneditor-min.css">
<!-- TODO: droid font
<link href='http://fonts.googleapis.com/css?family=Droid+Sans+Mono' rel='stylesheet' type='text/css'>
-->
<script type="text/javascript" src="lib/jsoneditor/jsoneditor-min.js"></script>
<script type="text/javascript" src="lib/ace/ace-min.js"></script>
<script type="text/javascript" src="app-min.js"></script>
<script type="text/javascript" src="lib/jsoneditor/jsoneditor-min.js"></script>
<script type="text/javascript" src="lib/ace/ace-min.js"></script>
<script type="text/javascript" src="app-min.js"></script>
</head>
<body>
<div id="header">
<a href="http://jsoneditoronline.org" class="header">
<img alt="JSON Editor Online" title="JSON Editor Online" src="img/logo.png" id="logo">
</a>
<a href="http://jsoneditoronline.org" class="header">
<img alt="JSON Editor Online" title="JSON Editor Online" src="img/logo.png" id="logo">
</a>
<div id="menu">
<ul>
<li>
<a id="clear" title="Clear contents">Clear</a>
</li>
<li>
<a id="open" title="Open file from disk">
Open
<div id="menu">
<ul>
<li>
<a id="clear" title="Clear contents">Clear</a>
</li>
<li>
<a id="open" title="Open file from disk">
Open
<span id="openMenuButton" title="Open file from disk or url">
&#x25BC;
</span>
</a>
<ul id="openMenu">
<li>
<a id="menuOpenFile" title="Open file from disk">Open&nbsp;file</a>
</li>
<li>
<a id="menuOpenUrl" title="Open file from url">Open&nbsp;url</a>
</li>
</ul>
</li>
<li>
<a id="save" title="Save file to disk">Save</a>
</li>
<li>
<a id="help" title="Open documentation (opens in a new window)" href="doc/index.html" target="_blank">Help</a>
</li>
</a>
<ul id="openMenu">
<li>
<a id="menuOpenFile" title="Open file from disk">Open&nbsp;file</a>
</li>
<li>
<a id="menuOpenUrl" title="Open file from url">Open&nbsp;url</a>
</li>
</ul>
</div>
<!-- TODO: info, links, faq -->
<!--
<div class="info" style="display:none;">
JSON, or JavaScript Object Notation, is a lightweight text-based open standard
designed for human-readable data interchange. It is derived from the JavaScript
scripting language for representing simple data structures and associative arrays,
called objects. Despite its relationship to JavaScript, it is language-independent,
with parsers available for most languages.
The JSON format was originally specified by Douglas Crockford, and is described
in RFC 4627. The official Internet media type for JSON is application/json.
The JSON filename extension is .json.
The JSON format is often used for serializing and transmitting structured data
over a network connection. It is used primarily to transmit data between a server
and web application, serving as an alternative to XML.
<br><br>
From <a target="_blank" href="http://en.wikipedia.org/wiki/Json">Wikipedia</a>
</li>
<li>
<a id="save" title="Save file to disk">Save</a>
</li>
<li>
<a id="help" title="Open documentation (opens in a new window)" href="doc/index.html" target="_blank">Help</a>
</li>
</ul>
</div>
<div class="links" style="display:none;">
<a target="_blank" href="http://json.org/">http://json.org/</a><br>
<a target="_blank" href="http://en.wikipedia.org/wiki/Json">http://en.wikipedia.org/wiki/Json</a><br>
</div>
<!-- TODO: info, links, faq -->
<!--
<div class="info" style="display:none;">
JSON, or JavaScript Object Notation, is a lightweight text-based open standard
designed for human-readable data interchange. It is derived from the JavaScript
scripting language for representing simple data structures and associative arrays,
called objects. Despite its relationship to JavaScript, it is language-independent,
with parsers available for most languages.
The JSON format was originally specified by Douglas Crockford, and is described
in RFC 4627. The official Internet media type for JSON is application/json.
The JSON filename extension is .json.
The JSON format is often used for serializing and transmitting structured data
over a network connection. It is used primarily to transmit data between a server
and web application, serving as an alternative to XML.
<br><br>
From <a target="_blank" href="http://en.wikipedia.org/wiki/Json">Wikipedia</a>
</div>
<div class="faq" style="display:none;"></div>
-->
<div class="links" style="display:none;">
<a target="_blank" href="http://json.org/">http://json.org/</a><br>
<a target="_blank" href="http://en.wikipedia.org/wiki/Json">http://en.wikipedia.org/wiki/Json</a><br>
</div>
<div class="faq" style="display:none;"></div>
-->
</div>
<div id="auto">
<div id="contents">
<div id="codeEditor"></div>
<div id="contents">
<div id="codeEditor"></div>
<div id="splitter">
<div id="buttons">
<div>
<button id="toTree" class="convert" title="Copy code to tree editor">
<div class="convert-right"></div>
</button>
</div>
<div>
<button id="toCode" class="convert" title="Copy tree to code editor">
<div class="convert-left"></div>
</button>
</div>
</div>
<div id="drag">
</div>
<div id="splitter">
<div id="buttons">
<div>
<button id="toTree" class="convert" title="Copy code to tree editor">
<div class="convert-right"></div>
</button>
</div>
<div id="treeEditor"></div>
<script type="text/javascript">
app.load();
app.resize();
</script>
<div id="ad">
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- jsoneditoronline_160x600 -->
<ins class="adsbygoogle"
style="display:inline-block;width:160px;height:600px"
data-ad-client="ca-pub-7938810169574141"
data-ad-slot="4671869937"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
<div>
<button id="toCode" class="convert" title="Copy tree to code editor">
<div class="convert-left"></div>
</button>
</div>
</div>
<div id="drag">
</div>
</div>
<div id="treeEditor"></div>
<script type="text/javascript">
app.load();
app.resize();
</script>
<div id="ad">
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- jsoneditoronline_160x600 -->
<ins class="adsbygoogle"
style="display:inline-block;width:160px;height:600px"
data-ad-client="ca-pub-7938810169574141"
data-ad-slot="4671869937"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
</div>
</div>
</div>
<div id="footer">
<div id="footer-inner">
<a href="http://jsoneditoronline.org" class="footer">JSON Editor Online @@version</a>
&bull;
<a href="HISTORY.md" target="_blank" class="footer">History</a>
&bull;
<a href="https://github.com/josdejong/jsoneditor/" target="_blank" class="footer">Sourcecode</a>
&bull;
<a href="https://github.com/josdejong/jsoneditor/issues" target="_blank" class="footer">Report a bug</a>
&bull;
<a href="datapolicy.txt" target="_blank" class="footer">Data policy</a>
&bull;
<a href="NOTICE" target="_blank" class="footer">Copyright 2011-2013 Jos de Jong</a>
</div>
<div id="footer-inner">
<a href="http://jsoneditoronline.org" class="footer">JSON Editor Online @@version</a>
&bull;
<a href="HISTORY.md" target="_blank" class="footer">History</a>
&bull;
<a href="https://github.com/josdejong/jsoneditor/" target="_blank" class="footer">Sourcecode</a>
&bull;
<a href="https://github.com/josdejong/jsoneditor/issues" target="_blank" class="footer">Report a bug</a>
&bull;
<a href="datapolicy.txt" target="_blank" class="footer">Data policy</a>
&bull;
<a href="NOTICE" target="_blank" class="footer">Copyright 2011-2013 Jos de Jong</a>
</div>
</div>
<script type="text/javascript">
app.resize();
app.resize();
</script>
<script type="text/javascript" src="lib/jsonlint/jsonlint.js"></script>

View File

@ -4,14 +4,14 @@
* @constructor Notify
*/
function Notify () {
this.dom = {};
this.dom = {};
// TODO: attach the event as soon as there are one or multiple messages displayed,
// remove it as soon as they are all gone
var me = this;
jsoneditor.util.addEventListener(document, 'keydown', function (event) {
me.onKeyDown(event);
});
// TODO: attach the event as soon as there are one or multiple messages displayed,
// remove it as soon as they are all gone
var me = this;
jsoneditor.util.addEventListener(document, 'keydown', function (event) {
me.onKeyDown(event);
});
}
/**
@ -20,11 +20,11 @@ function Notify () {
* @return {Element} messageObject
*/
Notify.prototype.showNotification = function (message) {
return this.showMessage({
type: 'notification',
message: message,
closeButton: false
});
return this.showMessage({
type: 'notification',
message: message,
closeButton: false
});
};
/**
@ -33,11 +33,11 @@ Notify.prototype.showNotification = function (message) {
* @return {Element} messageObject
*/
Notify.prototype.showError = function (error) {
return this.showMessage({
type: 'error',
message: (error.message || error.toString()),
closeButton: true
});
return this.showMessage({
type: 'error',
message: (error.message || error.toString()),
closeButton: true
});
};
/**
@ -49,59 +49,59 @@ Notify.prototype.showError = function (error) {
* @return {Element} messageObject
*/
Notify.prototype.showMessage = function (params) {
var frame = this.dom.frame;
if (!frame) {
var width = 500;
var top = 5;
var windowWidth = document.body.offsetWidth || window.innerWidth;
frame = document.createElement('div');
frame.style.position = 'absolute';
frame.style.left = (windowWidth - width) / 2 + 'px';
frame.style.width = width + 'px';
frame.style.top = top + 'px';
frame.style.zIndex = '999';
document.body.appendChild(frame);
this.dom.frame = frame;
var frame = this.dom.frame;
if (!frame) {
var width = 500;
var top = 5;
var windowWidth = document.body.offsetWidth || window.innerWidth;
frame = document.createElement('div');
frame.style.position = 'absolute';
frame.style.left = (windowWidth - width) / 2 + 'px';
frame.style.width = width + 'px';
frame.style.top = top + 'px';
frame.style.zIndex = '999';
document.body.appendChild(frame);
this.dom.frame = frame;
}
var type = params.type || 'notification';
var closeable = (params.closeButton !== false);
var divMessage = document.createElement('div');
divMessage.className = type;
divMessage.type = type;
divMessage.closeable = closeable;
divMessage.style.position = 'relative';
frame.appendChild(divMessage);
var table = document.createElement('table');
table.style.width = '100%';
divMessage.appendChild(table);
var tbody = document.createElement('tbody');
table.appendChild(tbody);
var tr = document.createElement('tr');
tbody.appendChild(tr);
var tdMessage = document.createElement('td');
tdMessage.innerHTML = params.message || '';
tr.appendChild(tdMessage);
if (closeable) {
var tdClose = document.createElement('td');
tdClose.style.textAlign = 'right';
tdClose.style.verticalAlign = 'top';
tr.appendChild(tdClose);
var closeDiv = document.createElement('button');
closeDiv.innerHTML = '&times;';
closeDiv.title = 'Close message (ESC)';
tdClose.appendChild(closeDiv);
var me = this;
closeDiv.onclick = function () {
me.removeMessage(divMessage);
}
}
var type = params.type || 'notification';
var closeable = (params.closeButton !== false);
var divMessage = document.createElement('div');
divMessage.className = type;
divMessage.type = type;
divMessage.closeable = closeable;
divMessage.style.position = 'relative';
frame.appendChild(divMessage);
var table = document.createElement('table');
table.style.width = '100%';
divMessage.appendChild(table);
var tbody = document.createElement('tbody');
table.appendChild(tbody);
var tr = document.createElement('tr');
tbody.appendChild(tr);
var tdMessage = document.createElement('td');
tdMessage.innerHTML = params.message || '';
tr.appendChild(tdMessage);
if (closeable) {
var tdClose = document.createElement('td');
tdClose.style.textAlign = 'right';
tdClose.style.verticalAlign = 'top';
tr.appendChild(tdClose);
var closeDiv = document.createElement('button');
closeDiv.innerHTML = '&times;';
closeDiv.title = 'Close message (ESC)';
tdClose.appendChild(closeDiv);
var me = this;
closeDiv.onclick = function () {
me.removeMessage(divMessage);
}
}
return divMessage;
return divMessage;
};
/**
@ -111,26 +111,26 @@ Notify.prototype.showMessage = function (params) {
* closed.
*/
Notify.prototype.removeMessage = function (message) {
var frame = this.dom.frame;
if (!message && frame) {
// find the first closable message in the list with displayed messages
var child = frame.firstChild;
while (child && !child.closeable) {
child = child.nextSibling;
}
if (child && child.closeable) {
message = child;
}
var frame = this.dom.frame;
if (!message && frame) {
// find the first closable message in the list with displayed messages
var child = frame.firstChild;
while (child && !child.closeable) {
child = child.nextSibling;
}
if (child && child.closeable) {
message = child;
}
}
if (message && message.parentNode == frame) {
message.parentNode.removeChild(message);
}
if (message && message.parentNode == frame) {
message.parentNode.removeChild(message);
}
if (frame && frame.childNodes.length == 0) {
frame.parentNode.removeChild(frame);
delete this.dom.frame;
}
if (frame && frame.childNodes.length == 0) {
frame.parentNode.removeChild(frame);
delete this.dom.frame;
}
};
/**
@ -139,11 +139,11 @@ Notify.prototype.removeMessage = function (message) {
* @private
*/
Notify.prototype.onKeyDown = function (event) {
var keynum = event.which;
if (keynum == 27) { // ESC
// remove the oldest open and closeable message
this.removeMessage();
event.preventDefault();
event.stopPropagation();
}
var keynum = event.which;
if (keynum == 27) { // ESC
// remove the oldest open and closeable message
this.removeMessage();
event.preventDefault();
event.stopPropagation();
}
};

View File

@ -10,18 +10,18 @@ function QueryParams () {}
* @return {Object} query object containing key/values
*/
QueryParams.prototype.getQuery = function () {
var search = window.location.search.substring(1); // skip the ? character
var params = search.split('&');
var query = {};
for (var i = 0, iMax = params.length; i < iMax; i++) {
var keyvalue = params[i].split('=');
if (keyvalue.length == 2) {
var key = decodeURIComponent(keyvalue[0]);
var value = decodeURIComponent(keyvalue[1]);
query[key] = value;
}
var search = window.location.search.substring(1); // skip the ? character
var params = search.split('&');
var query = {};
for (var i = 0, iMax = params.length; i < iMax; i++) {
var keyvalue = params[i].split('=');
if (keyvalue.length == 2) {
var key = decodeURIComponent(keyvalue[0]);
var value = decodeURIComponent(keyvalue[1]);
query[key] = value;
}
return query;
}
return query;
};
/**
@ -29,23 +29,23 @@ QueryParams.prototype.getQuery = function () {
* @param {Object} query object with strings
*/
QueryParams.prototype.setQuery = function (query) {
var search = '';
var search = '';
for (var key in query) {
if (query.hasOwnProperty(key)) {
var value = query[key];
if (value != undefined) {
if (search.length) {
search += '&';
}
search += encodeURIComponent(key);
search += '=';
search += encodeURIComponent(query[key]);
}
for (var key in query) {
if (query.hasOwnProperty(key)) {
var value = query[key];
if (value != undefined) {
if (search.length) {
search += '&';
}
search += encodeURIComponent(key);
search += '=';
search += encodeURIComponent(query[key]);
}
}
}
window.location.search = (search.length ? ('#' + search) : '');
window.location.search = (search.length ? ('#' + search) : '');
};
@ -55,8 +55,8 @@ QueryParams.prototype.setQuery = function (query) {
* @return {String} value undefined when the value is not found
*/
QueryParams.prototype.getValue = function (key) {
var query = this.getQuery();
return query[key];
var query = this.getQuery();
return query[key];
};
/**
@ -65,7 +65,7 @@ QueryParams.prototype.getValue = function (key) {
* @param {String} value
*/
QueryParams.prototype.setValue = function (key, value) {
var query = this.getQuery();
query[key] = value;
this.setQuery(query);
var query = this.getQuery();
query[key] = value;
this.setQuery(query);
};

View File

@ -13,21 +13,21 @@
* the new value as parameter
*/
function Splitter (params) {
if (!params || !params.container) {
throw new Error('params.container undefined in Splitter constructor');
}
if (!params || !params.container) {
throw new Error('params.container undefined in Splitter constructor');
}
var me = this;
jsoneditor.util.addEventListener(params.container, "mousedown", function (event) {
me.onMouseDown(event);
});
var me = this;
jsoneditor.util.addEventListener(params.container, "mousedown", function (event) {
me.onMouseDown(event);
});
this.container = params.container;
this.snap = Number(params.snap) || 200; // px
this.width = undefined;
this.value = undefined;
this.onChange = (params.change) ? params.change : function () {};
this.params = {};
this.container = params.container;
this.snap = Number(params.snap) || 200; // px
this.width = undefined;
this.value = undefined;
this.onChange = (params.change) ? params.change : function () {};
this.params = {};
}
/**
@ -36,29 +36,29 @@ function Splitter (params) {
* @private
*/
Splitter.prototype.onMouseDown = function (event) {
var me = this;
var leftButtonDown = event.which ? (event.which == 1) : (event.button == 1);
if (!leftButtonDown) {
return;
}
jsoneditor.util.addClassName(this.container, 'active');
var me = this;
var leftButtonDown = event.which ? (event.which == 1) : (event.button == 1);
if (!leftButtonDown) {
return;
}
jsoneditor.util.addClassName(this.container, 'active');
if (!this.params.mousedown) {
this.params.mousedown = true;
this.params.mousemove =
jsoneditor.util.addEventListener(document, 'mousemove', function (event) {
me.onMouseMove(event);
});
this.params.mouseup =
jsoneditor.util.addEventListener(document, 'mouseup', function (event) {
me.onMouseUp(event);
});
this.params.screenX = event.screenX;
this.params.changed = false;
this.params.value = this.getValue();
}
event.preventDefault();
event.stopPropagation();
if (!this.params.mousedown) {
this.params.mousedown = true;
this.params.mousemove =
jsoneditor.util.addEventListener(document, 'mousemove', function (event) {
me.onMouseMove(event);
});
this.params.mouseup =
jsoneditor.util.addEventListener(document, 'mouseup', function (event) {
me.onMouseUp(event);
});
this.params.screenX = event.screenX;
this.params.changed = false;
this.params.value = this.getValue();
}
event.preventDefault();
event.stopPropagation();
};
/**
@ -67,22 +67,22 @@ Splitter.prototype.onMouseDown = function (event) {
* @private
*/
Splitter.prototype.onMouseMove = function (event) {
if (this.width != undefined) {
var diff = event.screenX - this.params.screenX;
if (this.width != undefined) {
var diff = event.screenX - this.params.screenX;
var value = this.params.value + diff / this.width;
value = this.setValue(value);
var value = this.params.value + diff / this.width;
value = this.setValue(value);
if (value != this.params.value) {
// value has been changed
this.params.changed = true;
}
this.onChange(value);
if (value != this.params.value) {
// value has been changed
this.params.changed = true;
}
event.preventDefault();
event.stopPropagation();
this.onChange(value);
}
event.preventDefault();
event.stopPropagation();
};
/**
@ -91,30 +91,30 @@ Splitter.prototype.onMouseMove = function (event) {
* @private
*/
Splitter.prototype.onMouseUp = function (event) {
jsoneditor.util.removeClassName(this.container, 'active');
jsoneditor.util.removeClassName(this.container, 'active');
if (this.params.mousedown) {
jsoneditor.util.removeEventListener(document, 'mousemove', this.params.mousemove);
jsoneditor.util.removeEventListener(document, 'mouseup', this.params.mouseup);
this.params.mousemove = undefined;
this.params.mouseup = undefined;
this.params.mousedown = false;
if (this.params.mousedown) {
jsoneditor.util.removeEventListener(document, 'mousemove', this.params.mousemove);
jsoneditor.util.removeEventListener(document, 'mouseup', this.params.mouseup);
this.params.mousemove = undefined;
this.params.mouseup = undefined;
this.params.mousedown = false;
var value = this.getValue();
if (!this.params.changed) {
// value is unchanged -> unsnap when currently snapped
if (value == 0) {
value = this.setValue(0.2);
this.onChange(value);
}
if (value == 1) {
value = this.setValue(0.8);
this.onChange(value);
}
}
var value = this.getValue();
if (!this.params.changed) {
// value is unchanged -> unsnap when currently snapped
if (value == 0) {
value = this.setValue(0.2);
this.onChange(value);
}
if (value == 1) {
value = this.setValue(0.8);
this.onChange(value);
}
}
event.preventDefault();
event.stopPropagation();
}
event.preventDefault();
event.stopPropagation();
};
/**
@ -122,7 +122,7 @@ Splitter.prototype.onMouseUp = function (event) {
* @param {Number} width
*/
Splitter.prototype.setWidth = function (width) {
this.width = width;
this.width = width;
};
/**
@ -131,29 +131,29 @@ Splitter.prototype.setWidth = function (width) {
* @return {Number} value The stored value
*/
Splitter.prototype.setValue = function (value) {
value = Number(value);
value = Number(value);
// snap to 0 or 1 when close
if (this.width != undefined && this.width > this.snap) {
if (value < this.snap / this.width) {
value = 0;
}
if (value > (this.width - this.snap) / this.width) {
value = 1;
}
// snap to 0 or 1 when close
if (this.width != undefined && this.width > this.snap) {
if (value < this.snap / this.width) {
value = 0;
}
if (value > (this.width - this.snap) / this.width) {
value = 1;
}
}
this.value = value;
this.value = value;
try {
localStorage['splitterValue'] = value;
try {
localStorage['splitterValue'] = value;
}
catch (e) {
if (console && console.log) {
console.log(e);
}
catch (e) {
if (console && console.log) {
console.log(e);
}
}
return value;
}
return value;
};
/**
@ -161,21 +161,21 @@ Splitter.prototype.setValue = function (value) {
* @return {Number} value A value between 0.1 and 0.9
*/
Splitter.prototype.getValue = function () {
var value = this.value;
if (value == undefined) {
// read from localStorage once
try {
if (localStorage['splitterValue'] != undefined) {
value = Number(localStorage['splitterValue']); // read
value = this.setValue(value); // verify and store
}
}
catch (e) {
console.log(e);
}
var value = this.value;
if (value == undefined) {
// read from localStorage once
try {
if (localStorage['splitterValue'] != undefined) {
value = Number(localStorage['splitterValue']); // read
value = this.setValue(value); // verify and store
}
}
if (value == undefined) {
value = this.setValue(0.5);
catch (e) {
console.log(e);
}
return value;
}
if (value == undefined) {
value = this.setValue(0.5);
}
return value;
};

View File

@ -1,226 +1,226 @@
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>JSON Editor Online - view, edit and format JSON online</title>
<title>JSON Editor Online - view, edit and format JSON online</title>
<!--
<!--
@file index_no_ads.html
@file index_no_ads.html
@brief
JSON Editor Online is a web-based tool to view, edit, and format JSON.
It shows your data side by side in a clear, editable treeview and in
a code editor.
Supported browsers: Chrome, Firefox, Safari, Opera, Internet Explorer 8+
@brief
JSON Editor Online is a web-based tool to view, edit, and format JSON.
It shows your data side by side in a clear, editable treeview and in
a code editor.
@license
This json editor is open sourced with the intention to use the editor as
a component in your own application. Not to just copy and monetize the editor
as it is.
Supported browsers: Chrome, Firefox, Safari, Opera, Internet Explorer 8+
Licensed under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy
of the License at
@license
This json editor is open sourced with the intention to use the editor as
a component in your own application. Not to just copy and monetize the editor
as it is.
http://www.apache.org/licenses/LICENSE-2.0
Licensed under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy
of the License at
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations under
the License.
http://www.apache.org/licenses/LICENSE-2.0
Copyright (C) 2011-2013 Jos de Jong, http://jsoneditoronline.org
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations under
the License.
@author Jos de Jong, <wjosdejong@gmail.com>
@version @@version
@date @@date
-->
Copyright (C) 2011-2013 Jos de Jong, http://jsoneditoronline.org
<meta name="description" content="JSON Editor Online is a web-based tool to view, edit, and format JSON. It shows your data side by side in a clear, editable treeview and in a code editor.">
<meta name="keywords" content="json, editor, formatter, online, format, parser, json editor, json editor online, online json editor, javascript, javascript object notation, tools, tool, json tools, treeview, open source, free, json parser, json parser online, json formatter, json formatter online, online json formatter, online json parser, format json online">
<meta name="author" content="Jos de Jong">
@author Jos de Jong, <wjosdejong@gmail.com>
@version @@version
@date @@date
-->
<link rel="shortcut icon" href="favicon.ico">
<meta name="description" content="JSON Editor Online is a web-based tool to view, edit, and format JSON. It shows your data side by side in a clear, editable treeview and in a code editor.">
<meta name="keywords" content="json, editor, formatter, online, format, parser, json editor, json editor online, online json editor, javascript, javascript object notation, tools, tool, json tools, treeview, open source, free, json parser, json parser online, json formatter, json formatter online, online json formatter, online json parser, format json online">
<meta name="author" content="Jos de Jong">
<link href="app.css" rel="stylesheet" type="text/css">
<link href="fileretriever.css" rel="stylesheet" type="text/css">
<link href="../../jsoneditor/css/jsoneditor.css" rel="stylesheet" type="text/css">
<link href="../../jsoneditor/css/menu.css" rel="stylesheet" type="text/css">
<link href="../../jsoneditor/css/searchbox.css" rel="stylesheet" type="text/css">
<link href="../../jsoneditor/css/contextmenu.css" rel="stylesheet" type="text/css">
<!-- TODO: droid font
<link href='http://fonts.googleapis.com/css?family=Droid+Sans+Mono' rel='stylesheet' type='text/css'>
-->
<link rel="shortcut icon" href="favicon.ico">
<script type="text/javascript" src="../../jsoneditor/js/jsoneditor.js"></script>
<script type="text/javascript" src="../../jsoneditor/js/treeeditor.js"></script>
<script type="text/javascript" src="../../jsoneditor/js/texteditor.js"></script>
<script type="text/javascript" src="../../jsoneditor/js/node.js"></script>
<script type="text/javascript" src="../../jsoneditor/js/appendnode.js"></script>
<script type="text/javascript" src="../../jsoneditor/js/contextmenu.js"></script>
<script type="text/javascript" src="../../jsoneditor/js/history.js"></script>
<script type="text/javascript" src="../../jsoneditor/js/searchbox.js"></script>
<script type="text/javascript" src="../../jsoneditor/js/modebox.js"></script>
<script type="text/javascript" src="../../jsoneditor/js/highlighter.js"></script>
<script type="text/javascript" src="../../jsoneditor/js/util.js"></script>
<script type="text/javascript" src="../../jsoneditor/js/module.js"></script>
<script type="text/javascript" src="queryparams.js"></script>
<script type="text/javascript" src="ajax.js"></script>
<script type="text/javascript" src="fileretriever.js"></script>
<script type="text/javascript" src="notify.js"></script>
<script type="text/javascript" src="splitter.js"></script>
<script type="text/javascript" src="app.js"></script>
<script type="text/javascript" src="../../lib/jsonlint/jsonlint.js"></script>
<link href="app.css" rel="stylesheet" type="text/css">
<link href="fileretriever.css" rel="stylesheet" type="text/css">
<link href="../../jsoneditor/css/jsoneditor.css" rel="stylesheet" type="text/css">
<link href="../../jsoneditor/css/menu.css" rel="stylesheet" type="text/css">
<link href="../../jsoneditor/css/searchbox.css" rel="stylesheet" type="text/css">
<link href="../../jsoneditor/css/contextmenu.css" rel="stylesheet" type="text/css">
<!-- TODO: droid font
<link href='http://fonts.googleapis.com/css?family=Droid+Sans+Mono' rel='stylesheet' type='text/css'>
-->
<script type="text/javascript" src="../../lib/ace/ace.js"></script>
<script type="text/javascript" src="../../lib/ace/mode-json.js"></script>
<script type="text/javascript" src="../../lib/ace/theme-textmate.js"></script>
<script type="text/javascript" src="../../lib/ace/theme-jsoneditor.js"></script>
<script type="text/javascript" src="../../jsoneditor/js/jsoneditor.js"></script>
<script type="text/javascript" src="../../jsoneditor/js/treeeditor.js"></script>
<script type="text/javascript" src="../../jsoneditor/js/texteditor.js"></script>
<script type="text/javascript" src="../../jsoneditor/js/node.js"></script>
<script type="text/javascript" src="../../jsoneditor/js/appendnode.js"></script>
<script type="text/javascript" src="../../jsoneditor/js/contextmenu.js"></script>
<script type="text/javascript" src="../../jsoneditor/js/history.js"></script>
<script type="text/javascript" src="../../jsoneditor/js/searchbox.js"></script>
<script type="text/javascript" src="../../jsoneditor/js/modebox.js"></script>
<script type="text/javascript" src="../../jsoneditor/js/highlighter.js"></script>
<script type="text/javascript" src="../../jsoneditor/js/util.js"></script>
<script type="text/javascript" src="../../jsoneditor/js/module.js"></script>
<script type="text/javascript" src="queryparams.js"></script>
<script type="text/javascript" src="ajax.js"></script>
<script type="text/javascript" src="fileretriever.js"></script>
<script type="text/javascript" src="notify.js"></script>
<script type="text/javascript" src="splitter.js"></script>
<script type="text/javascript" src="app.js"></script>
<script type="text/javascript" src="../../lib/jsonlint/jsonlint.js"></script>
<style type="text/css">
div.convert-right {
background: url('../../jsoneditor/css/img/jsoneditor-icons.png') -0 -48px;
}
div.convert-left {
background: url('../../jsoneditor/css/img/jsoneditor-icons.png') -24px -48px;
}
</style>
<script type="text/javascript" src="../../lib/ace/ace.js"></script>
<script type="text/javascript" src="../../lib/ace/mode-json.js"></script>
<script type="text/javascript" src="../../lib/ace/theme-textmate.js"></script>
<script type="text/javascript" src="../../lib/ace/theme-jsoneditor.js"></script>
<style type="text/css">
div.convert-right {
background: url('../../jsoneditor/css/img/jsoneditor-icons.png') -0 -48px;
}
div.convert-left {
background: url('../../jsoneditor/css/img/jsoneditor-icons.png') -24px -48px;
}
</style>
</head>
<body>
<div id="header" >
<a href="http://jsoneditoronline.org" class="header">
<img alt="JSON Editor Online" title="JSON Editor Online" src="img/logo.png" id="logo">
</a>
<a href="http://jsoneditoronline.org" class="header">
<img alt="JSON Editor Online" title="JSON Editor Online" src="img/logo.png" id="logo">
</a>
<div id="menu">
<ul>
<li>
<a id="clear" title="Clear contents">Clear</a>
</li>
<li>
<a id="open" title="Open file from disk">
Open
<div id="menu">
<ul>
<li>
<a id="clear" title="Clear contents">Clear</a>
</li>
<li>
<a id="open" title="Open file from disk">
Open
<span id="openMenuButton" title="Open file from disk or url">
&#x25BC;
</span>
</a>
<ul id="openMenu">
<li>
<a id="menuOpenFile" title="Open file from disk">Open&nbsp;file</a>
</li>
<li>
<a id="menuOpenUrl" title="Open file from url">Open&nbsp;url</a>
</li>
</ul>
</li>
<li>
<a id="save" title="Save file to disk">Save</a>
</li>
<li>
<a id="help" title="Open documentation (opens in a new window)" href="doc/index.html" target="_blank">Help</a>
</li>
</a>
<ul id="openMenu">
<li>
<a id="menuOpenFile" title="Open file from disk">Open&nbsp;file</a>
</li>
<li>
<a id="menuOpenUrl" title="Open file from url">Open&nbsp;url</a>
</li>
</ul>
</div>
<!-- TODO: info, links, faq -->
<!--
<div class="info" style="display:none;">
JSON, or JavaScript Object Notation, is a lightweight text-based open standard
designed for human-readable data interchange. It is derived from the JavaScript
scripting language for representing simple data structures and associative arrays,
called objects. Despite its relationship to JavaScript, it is language-independent,
with parsers available for most languages.
The JSON format was originally specified by Douglas Crockford, and is described
in RFC 4627. The official Internet media type for JSON is application/json.
The JSON filename extension is .json.
The JSON format is often used for serializing and transmitting structured data
over a network connection. It is used primarily to transmit data between a server
and web application, serving as an alternative to XML.
<br><br>
From <a target="_blank" href="http://en.wikipedia.org/wiki/Json">Wikipedia</a>
</li>
<li>
<a id="save" title="Save file to disk">Save</a>
</li>
<li>
<a id="help" title="Open documentation (opens in a new window)" href="doc/index.html" target="_blank">Help</a>
</li>
</ul>
</div>
<div class="links" style="display:none;">
<a target="_blank" href="http://json.org/">http://json.org/</a><br>
<a target="_blank" href="http://en.wikipedia.org/wiki/Json">http://en.wikipedia.org/wiki/Json</a><br>
</div>
<!-- TODO: info, links, faq -->
<!--
<div class="info" style="display:none;">
JSON, or JavaScript Object Notation, is a lightweight text-based open standard
designed for human-readable data interchange. It is derived from the JavaScript
scripting language for representing simple data structures and associative arrays,
called objects. Despite its relationship to JavaScript, it is language-independent,
with parsers available for most languages.
The JSON format was originally specified by Douglas Crockford, and is described
in RFC 4627. The official Internet media type for JSON is application/json.
The JSON filename extension is .json.
The JSON format is often used for serializing and transmitting structured data
over a network connection. It is used primarily to transmit data between a server
and web application, serving as an alternative to XML.
<br><br>
From <a target="_blank" href="http://en.wikipedia.org/wiki/Json">Wikipedia</a>
</div>
<div class="faq" style="display:none;"></div>
-->
<div class="links" style="display:none;">
<a target="_blank" href="http://json.org/">http://json.org/</a><br>
<a target="_blank" href="http://en.wikipedia.org/wiki/Json">http://en.wikipedia.org/wiki/Json</a><br>
</div>
<div class="faq" style="display:none;"></div>
-->
</div>
<div id="auto">
<div id="contents">
<div id="codeEditor"></div>
<div id="contents">
<div id="codeEditor"></div>
<div id="splitter">
<div id="buttons">
<div>
<button id="toTree" class="convert" title="Copy code to tree editor">
<div class="convert-right"></div>
</button>
</div>
<div>
<button id="toCode" class="convert" title="Copy tree to code editor">
<div class="convert-left"></div>
</button>
</div>
</div>
<div id="drag">
</div>
<div id="splitter">
<div id="buttons">
<div>
<button id="toTree" class="convert" title="Copy code to tree editor">
<div class="convert-right"></div>
</button>
</div>
<div id="treeEditor"></div>
<script type="text/javascript">
app.load();
app.resize();
</script>
<div id="ad" title="advertisement" >
<script type="text/javascript"><!--
google_ad_client = "ca-pub-7938810169574141";
/* jsoneditoronline_160x600 */
google_ad_slot = "4671869937";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<!--
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
-->
<div>
<button id="toCode" class="convert" title="Copy tree to code editor">
<div class="convert-left"></div>
</button>
</div>
</div>
<div id="drag">
</div>
</div>
<div id="treeEditor"></div>
<script type="text/javascript">
app.load();
app.resize();
</script>
<div id="ad" title="advertisement" >
<script type="text/javascript"><!--
google_ad_client = "ca-pub-7938810169574141";
/* jsoneditoronline_160x600 */
google_ad_slot = "4671869937";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<!--
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
-->
</div>
</div>
</div>
<div id="footer">
<div id="footer-inner">
<a href="http://jsoneditoronline.org" class="footer">JSON Editor Online @@version</a>
&bull;
<a href="../../HISTORY.md" target="_blank" class="footer">History</a>
&bull;
<a href="https://github.com/josdejong/jsoneditor/" target="_blank" class="footer">Sourcecode</a>
&bull;
<a href="https://github.com/josdejong/jsoneditor/issues" target="_blank" class="footer">Report a bug</a>
&bull;
<a href="datapolicy.txt" target="_blank" class="footer">Data policy</a>
&bull;
<a href="../../NOTICE" target="_blank" class="footer">Copyright 2011-2013 Jos de Jong</a>
</div>
<div id="footer-inner">
<a href="http://jsoneditoronline.org" class="footer">JSON Editor Online @@version</a>
&bull;
<a href="../../HISTORY.md" target="_blank" class="footer">History</a>
&bull;
<a href="https://github.com/josdejong/jsoneditor/" target="_blank" class="footer">Sourcecode</a>
&bull;
<a href="https://github.com/josdejong/jsoneditor/issues" target="_blank" class="footer">Report a bug</a>
&bull;
<a href="datapolicy.txt" target="_blank" class="footer">Data policy</a>
&bull;
<a href="../../NOTICE" target="_blank" class="footer">Copyright 2011-2013 Jos de Jong</a>
</div>
</div>
<script type="text/javascript">
app.resize();
app.resize();
</script>
</body>

View File

@ -1,33 +1,33 @@
{
"name": "jsoneditor",
"version": "2.4.0-SNAPSHOT",
"description": "A web-based tool to view, edit and format JSON",
"tags": [
"json",
"editor",
"viewer",
"formatter"
],
"homepage": "http://jsoneditoronline.org/",
"repository": {
"type": "git",
"url": "https://github.com/josdejong/jsoneditor.git"
},
"bugs": "https://github.com/josdejong/jsoneditor/issues",
"ignore": [
"app",
"build",
"downloads",
"jsoneditor",
"misc",
"node_modules",
"test",
"tools",
".idea",
"Jakefile.js",
"package.json",
".npmignore",
".gitignore"
],
"dependencies": {}
"name": "jsoneditor",
"version": "2.4.0-SNAPSHOT",
"description": "A web-based tool to view, edit and format JSON",
"tags": [
"json",
"editor",
"viewer",
"formatter"
],
"homepage": "http://jsoneditoronline.org/",
"repository": {
"type": "git",
"url": "https://github.com/josdejong/jsoneditor.git"
},
"bugs": "https://github.com/josdejong/jsoneditor/issues",
"ignore": [
"app",
"build",
"downloads",
"jsoneditor",
"misc",
"node_modules",
"test",
"tools",
".idea",
"Jakefile.js",
"package.json",
".npmignore",
".gitignore"
],
"dependencies": {}
}

View File

@ -44,7 +44,7 @@ Constructs a new JSONEditor.
True by default.
Only applicable when `mode` is 'tree', 'view', or 'form'.
- `{Number} indentation`.
Number of indentation spaces. 4 by default.
Number of indentation spaces. 2 by default.
Only applicable when `mode` is 'code' or 'text'.
- `{JSON} json`

View File

@ -1,45 +1,45 @@
<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" type="text/css" href="../jsoneditor.css">
<script type="text/javascript" src="../jsoneditor.js"></script>
<style type="text/css">
#jsoneditor {
width: 500px;
height: 500px;
}
</style>
<link rel="stylesheet" type="text/css" href="../jsoneditor.css">
<script type="text/javascript" src="../jsoneditor.js"></script>
<style type="text/css">
#jsoneditor {
width: 500px;
height: 500px;
}
</style>
</head>
<body>
<p>
<button id="setJSON">Set JSON</button>
<button id="getJSON">Get JSON</button>
</p>
<div id="jsoneditor"></div>
<p>
<button id="setJSON">Set JSON</button>
<button id="getJSON">Get JSON</button>
</p>
<div id="jsoneditor"></div>
<script type="text/javascript" >
// create the editor
var container = document.getElementById('jsoneditor');
var editor = new jsoneditor.JSONEditor(container);
<script type="text/javascript" >
// create the editor
var container = document.getElementById('jsoneditor');
var editor = new jsoneditor.JSONEditor(container);
// set json
document.getElementById('setJSON').onclick = function () {
var json = {
'array': [1, 2, 3],
'boolean': true,
'null': null,
'number': 123,
'object': {'a': 'b', 'c': 'd'},
'string': 'Hello World'
};
editor.set(json);
};
// set json
document.getElementById('setJSON').onclick = function () {
var json = {
'array': [1, 2, 3],
'boolean': true,
'null': null,
'number': 123,
'object': {'a': 'b', 'c': 'd'},
'string': 'Hello World'
};
editor.set(json);
};
// get json
document.getElementById('getJSON').onclick = function () {
var json = editor.get();
alert(JSON.stringify(json, null, 2));
};
</script>
// get json
document.getElementById('getJSON').onclick = function () {
var json = editor.get();
alert(JSON.stringify(json, null, 2));
};
</script>
</body>
</html>

View File

@ -1,40 +1,40 @@
<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" type="text/css" href="../jsoneditor.css">
<script type="text/javascript" src="../jsoneditor.js"></script>
<style type="text/css">
body {
font: 11pt arial;
}
#jsoneditor {
width: 500px;
}
</style>
<link rel="stylesheet" type="text/css" href="../jsoneditor.css">
<script type="text/javascript" src="../jsoneditor.js"></script>
<style type="text/css">
body {
font: 11pt arial;
}
#jsoneditor {
width: 500px;
}
</style>
</head>
<body>
<p>
This editor is read-only (mode='viewer').
</p>
<div id="jsoneditor"></div>
<p>
This editor is read-only (mode='viewer').
</p>
<div id="jsoneditor"></div>
<script type="text/javascript" >
var container = document.getElementById('jsoneditor');
<script type="text/javascript" >
var container = document.getElementById('jsoneditor');
var options = {
mode: 'view'
};
var options = {
mode: 'view'
};
var json = {
'array': [1, 2, 3],
'boolean': true,
'null': null,
'number': 123,
'object': {'a': 'b', 'c': 'd'},
'string': 'Hello World'
};
var json = {
'array': [1, 2, 3],
'boolean': true,
'null': null,
'number': 123,
'object': {'a': 'b', 'c': 'd'},
'string': 'Hello World'
};
var editor = new jsoneditor.JSONEditor(container, options, json);
</script>
var editor = new jsoneditor.JSONEditor(container, options, json);
</script>
</body>
</html>

View File

@ -1,70 +1,70 @@
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<!-- jsoneditor -->
<link rel="stylesheet" type="text/css" href="../jsoneditor.css">
<script type="text/javascript" src="../jsoneditor.js"></script>
<!-- jsoneditor -->
<link rel="stylesheet" type="text/css" href="../jsoneditor.css">
<script type="text/javascript" src="../jsoneditor.js"></script>
<!-- ace code editor -->
<script type="text/javascript" src="../lib/ace/ace.js"></script>
<script type="text/javascript" src="../lib/ace/mode-json.js"></script>
<script type="text/javascript" src="../lib/ace/theme-textmate.js"></script>
<script type="text/javascript" src="../lib/ace/theme-jsoneditor.js"></script>
<!-- ace code editor -->
<script type="text/javascript" src="../lib/ace/ace.js"></script>
<script type="text/javascript" src="../lib/ace/mode-json.js"></script>
<script type="text/javascript" src="../lib/ace/theme-textmate.js"></script>
<script type="text/javascript" src="../lib/ace/theme-jsoneditor.js"></script>
<!-- json lint -->
<script type="text/javascript" src="../lib/jsonlint/jsonlint.js"></script>
<!-- json lint -->
<script type="text/javascript" src="../lib/jsonlint/jsonlint.js"></script>
<style type="text/css">
body {
font: 10.5pt arial;
color: #4d4d4d;
line-height: 150%;
width: 500px;
}
<style type="text/css">
body {
font: 10.5pt arial;
color: #4d4d4d;
line-height: 150%;
width: 500px;
}
code {
background-color: #f5f5f5;
}
code {
background-color: #f5f5f5;
}
#jsoneditor {
width: 500px;
height: 500px;
}
</style>
#jsoneditor {
width: 500px;
height: 500px;
}
</style>
</head>
<body>
<p>
Switch editor mode using the mode box.
Note that the mode can be changed programmatically as well using the method
<code>editor.setMode(mode)</code>, try it in the console of your browser.
Switch editor mode using the mode box.
Note that the mode can be changed programmatically as well using the method
<code>editor.setMode(mode)</code>, try it in the console of your browser.
</p>
<div id="jsoneditor"></div>
<script type="text/javascript" >
var container = document.getElementById('jsoneditor');
var container = document.getElementById('jsoneditor');
var options = {
mode: 'tree',
modes: ['code', 'form', 'text', 'tree', 'view'], // allowed modes
error: function (err) {
alert(err.toString());
}
};
var options = {
mode: 'tree',
modes: ['code', 'form', 'text', 'tree', 'view'], // allowed modes
error: function (err) {
alert(err.toString());
}
};
var json = {
"array": [1, 2, 3],
"boolean": true,
"null": null,
"number": 123,
"object": {"a": "b", "c": "d"},
"string": "Hello World"
};
var json = {
"array": [1, 2, 3],
"boolean": true,
"null": null,
"number": 123,
"object": {"a": "b", "c": "d"},
"string": "Hello World"
};
var editor = new jsoneditor.JSONEditor(container, options, json);
var editor = new jsoneditor.JSONEditor(container, options, json);
</script>
</body>
</html>

View File

@ -1,19 +1,19 @@
<!DOCTYPE HTML>
<html>
<head>
<style type="text/css">
#jsoneditor {
width: 500px;
height: 500px;
}
</style>
<script data-main="scripts/main" src="scripts/require.js"></script>
<style type="text/css">
#jsoneditor {
width: 500px;
height: 500px;
}
</style>
<script data-main="scripts/main" src="scripts/require.js"></script>
</head>
<body>
<p>
<button id="setJSON">Set JSON</button>
<button id="getJSON">Get JSON</button>
</p>
<div id="jsoneditor"></div>
<p>
<button id="setJSON">Set JSON</button>
<button id="getJSON">Get JSON</button>
</p>
<div id="jsoneditor"></div>
</body>
</html>

View File

@ -1,25 +1,25 @@
var module = '../../../jsoneditor';
require([module], function (jsoneditor) {
// create the editor
var container = document.getElementById('jsoneditor');
var editor = new jsoneditor.JSONEditor(container);
// create the editor
var container = document.getElementById('jsoneditor');
var editor = new jsoneditor.JSONEditor(container);
// set json
document.getElementById('setJSON').onclick = function () {
var json = {
'array': [1, 2, 3],
'boolean': true,
'null': null,
'number': 123,
'object': {'a': 'b', 'c': 'd'},
'string': 'Hello World'
};
editor.set(json);
// set json
document.getElementById('setJSON').onclick = function () {
var json = {
'array': [1, 2, 3],
'boolean': true,
'null': null,
'number': 123,
'object': {'a': 'b', 'c': 'd'},
'string': 'Hello World'
};
editor.set(json);
};
// get json
document.getElementById('getJSON').onclick = function () {
var json = editor.get();
alert(JSON.stringify(json, null, 2));
};
// get json
document.getElementById('getJSON').onclick = function () {
var json = editor.get();
alert(JSON.stringify(json, null, 2));
};
});

2
jsoneditor-min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -2,60 +2,60 @@
.jsoneditor .field,
.jsoneditor .value,
.jsoneditor .readonly {
border: 1px solid transparent;
min-height: 16px;
min-width: 32px;
padding: 2px;
margin: 1px;
word-wrap: break-word;
float: left;
border: 1px solid transparent;
min-height: 16px;
min-width: 32px;
padding: 2px;
margin: 1px;
word-wrap: break-word;
float: left;
}
/* adjust margin of p elements inside editable divs, needed for Opera, IE */
.jsoneditor .field p,
.jsoneditor .value p {
margin: 0;
margin: 0;
}
.jsoneditor .value {
word-break: break-word;
word-break: break-word;
}
.jsoneditor .readonly {
min-width: 16px;
color: gray;
min-width: 16px;
color: gray;
}
.jsoneditor .empty {
border-color: lightgray;
border-style: dashed;
border-radius: 2px;
border-color: lightgray;
border-style: dashed;
border-radius: 2px;
}
.jsoneditor .field.empty {
background-image: url('img/jsoneditor-icons.png');
background-position: 0 -144px;
background-image: url('img/jsoneditor-icons.png');
background-position: 0 -144px;
}
.jsoneditor .value.empty {
background-image: url('img/jsoneditor-icons.png');
background-position: -48px -144px;
background-image: url('img/jsoneditor-icons.png');
background-position: -48px -144px;
}
.jsoneditor .value.url {
color: green;
text-decoration: underline;
color: green;
text-decoration: underline;
}
.jsoneditor a.value.url:hover,
.jsoneditor a.value.url:focus {
color: red;
color: red;
}
.jsoneditor .separator {
padding: 3px 0;
vertical-align: top;
color: gray;
padding: 3px 0;
vertical-align: top;
color: gray;
}
.jsoneditor .field[contenteditable=true]:focus,
@ -64,9 +64,9 @@
.jsoneditor .value[contenteditable=true]:hover,
.jsoneditor .field.highlight,
.jsoneditor .value.highlight {
background-color: #FFFFAB;
border: 1px solid yellow;
border-radius: 2px;
background-color: #FFFFAB;
border: 1px solid yellow;
border-radius: 2px;
}
.jsoneditor .field.highlight-active,
@ -75,141 +75,141 @@
.jsoneditor .value.highlight-active,
.jsoneditor .value.highlight-active:focus,
.jsoneditor .value.highlight-active:hover {
background-color: #ffee00;
border: 1px solid #ffc700;
border-radius: 2px;
background-color: #ffee00;
border: 1px solid #ffc700;
border-radius: 2px;
}
.jsoneditor div.tree button {
width: 24px;
height: 24px;
padding: 0;
margin: 0;
border: none;
cursor: pointer;
background: transparent url('img/jsoneditor-icons.png');
width: 24px;
height: 24px;
padding: 0;
margin: 0;
border: none;
cursor: pointer;
background: transparent url('img/jsoneditor-icons.png');
}
.jsoneditor div.tree button.collapsed {
background-position: 0 -48px;
background-position: 0 -48px;
}
.jsoneditor div.tree button.expanded {
background-position: 0 -72px;
background-position: 0 -72px;
}
.jsoneditor div.tree button.contextmenu {
background-position: -48px -72px;
background-position: -48px -72px;
}
.jsoneditor div.tree button.contextmenu:hover,
.jsoneditor div.tree button.contextmenu:focus,
.jsoneditor div.tree button.contextmenu.selected {
background-position: -48px -48px;
background-position: -48px -48px;
}
.jsoneditor div.tree *:focus {
outline: none;
outline: none;
}
.jsoneditor div.tree button:focus {
/* TODO: nice outline for buttons with focus
outline: #97B0F8 solid 2px;
box-shadow: 0 0 8px #97B0F8;
*/
background-color: #f5f5f5;
outline: #e5e5e5 solid 1px;
/* TODO: nice outline for buttons with focus
outline: #97B0F8 solid 2px;
box-shadow: 0 0 8px #97B0F8;
*/
background-color: #f5f5f5;
outline: #e5e5e5 solid 1px;
}
.jsoneditor div.tree button.invisible {
visibility: hidden;
background: none;
visibility: hidden;
background: none;
}
.jsoneditor {
color: #1A1A1A;
border: 1px solid #97B0F8;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
color: #1A1A1A;
border: 1px solid #97B0F8;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
width: 100%;
height: 100%;
overflow: auto;
position: relative;
padding: 0;
line-height: 100%;
width: 100%;
height: 100%;
overflow: auto;
position: relative;
padding: 0;
line-height: 100%;
}
.jsoneditor div.tree table.tree {
border-collapse: collapse;
border-spacing: 0;
width: 100%;
margin: 0;
border-collapse: collapse;
border-spacing: 0;
width: 100%;
margin: 0;
}
.jsoneditor div.outer {
width: 100%;
height: 100%;
margin: -35px 0 0 0;
padding: 35px 0 0 0;
width: 100%;
height: 100%;
margin: -35px 0 0 0;
padding: 35px 0 0 0;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
overflow: hidden;
overflow: hidden;
}
.jsoneditor div.tree {
width: 100%;
height: 100%;
position: relative;
overflow: auto;
width: 100%;
height: 100%;
position: relative;
overflow: auto;
}
.jsoneditor textarea.text {
width: 100%;
height: 100%;
margin: 0;
width: 100%;
height: 100%;
margin: 0;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
border: none;
background-color: white;
resize: none;
border: none;
background-color: white;
resize: none;
}
.jsoneditor tr.highlight {
background-color: #FFFFAB;
background-color: #FFFFAB;
}
.jsoneditor div.tree button.dragarea {
background: url('img/jsoneditor-icons.png') -72px -72px;
cursor: move;
background: url('img/jsoneditor-icons.png') -72px -72px;
cursor: move;
}
.jsoneditor div.tree button.dragarea:hover,
.jsoneditor div.tree button.dragarea:focus {
background-position: -72px -48px;
background-position: -72px -48px;
}
.jsoneditor tr,
.jsoneditor th,
.jsoneditor td {
padding: 0;
margin: 0;
padding: 0;
margin: 0;
}
.jsoneditor td {
vertical-align: top;
vertical-align: top;
}
.jsoneditor td.tree {
vertical-align: top;
vertical-align: top;
}
.jsoneditor .field,
@ -217,90 +217,90 @@
.jsoneditor td,
.jsoneditor th,
.jsoneditor textarea {
font-family: droid sans mono, monospace, courier new, courier, sans-serif;
font-size: 10pt;
color: #1A1A1A;
font-family: droid sans mono, monospace, courier new, courier, sans-serif;
font-size: 10pt;
color: #1A1A1A;
}
/* ContextMenu - main menu */
.jsoneditor-contextmenu {
position: fixed;
z-index: 99999;
position: fixed;
z-index: 99999;
}
.jsoneditor-contextmenu ul {
position: relative;
left: 0;
top: 0;
width: 124px;
position: relative;
left: 0;
top: 0;
width: 124px;
background: white;
border: 1px solid #d3d3d3;
box-shadow: 2px 2px 12px rgba(128, 128, 128, 0.3);
background: white;
border: 1px solid #d3d3d3;
box-shadow: 2px 2px 12px rgba(128, 128, 128, 0.3);
list-style: none;
margin: 0;
padding: 0;
list-style: none;
margin: 0;
padding: 0;
}
.jsoneditor-contextmenu ul li button {
padding: 0;
margin: 0;
width: 124px;
height: 24px;
border: none;
cursor: pointer;
color: #4d4d4d;
background: transparent;
padding: 0;
margin: 0;
width: 124px;
height: 24px;
border: none;
cursor: pointer;
color: #4d4d4d;
background: transparent;
line-height: 26px;
text-align: left;
line-height: 26px;
text-align: left;
}
/* Fix button padding in firefox */
.jsoneditor-contextmenu ul li button::-moz-focus-inner {
padding: 0;
border: 0;
padding: 0;
border: 0;
}
.jsoneditor-contextmenu ul li button:hover,
.jsoneditor-contextmenu ul li button:focus {
color: #1a1a1a;
background-color: #f5f5f5;
outline: none;
color: #1a1a1a;
background-color: #f5f5f5;
outline: none;
}
.jsoneditor-contextmenu ul li button.default {
width: 92px;
width: 92px;
}
.jsoneditor-contextmenu ul li button.expand {
float: right;
width: 32px;
height: 24px;
border-left: 1px solid #e5e5e5;
float: right;
width: 32px;
height: 24px;
border-left: 1px solid #e5e5e5;
}
.jsoneditor-contextmenu div.icon {
float: left;
width: 24px;
height: 24px;
border: none;
padding: 0;
margin: 0;
background-image: url('img/jsoneditor-icons.png');
float: left;
width: 24px;
height: 24px;
border: none;
padding: 0;
margin: 0;
background-image: url('img/jsoneditor-icons.png');
}
.jsoneditor-contextmenu ul li button div.expand {
float: right;
width: 24px;
height: 24px;
padding: 0;
margin: 0 4px 0 0;
background: url('img/jsoneditor-icons.png') 0 -72px;
opacity: 0.4;
float: right;
width: 24px;
height: 24px;
padding: 0;
margin: 0 4px 0 0;
background: url('img/jsoneditor-icons.png') 0 -72px;
opacity: 0.4;
}
.jsoneditor-contextmenu ul li button:hover div.expand,
@ -308,241 +308,241 @@
.jsoneditor-contextmenu ul li.selected div.expand,
.jsoneditor-contextmenu ul li button.expand:hover div.expand,
.jsoneditor-contextmenu ul li button.expand:focus div.expand {
opacity: 1;
opacity: 1;
}
.jsoneditor-contextmenu .separator {
height: 0;
border-top: 1px solid #e5e5e5;
padding-top: 5px;
margin-top: 5px;
height: 0;
border-top: 1px solid #e5e5e5;
padding-top: 5px;
margin-top: 5px;
}
.jsoneditor-contextmenu button.remove > .icon {
background-position: -24px -24px;
background-position: -24px -24px;
}
.jsoneditor-contextmenu button.remove:hover > .icon,
.jsoneditor-contextmenu button.remove:focus > .icon {
background-position: -24px 0;
background-position: -24px 0;
}
.jsoneditor-contextmenu button.append > .icon {
background-position: 0 -24px;
background-position: 0 -24px;
}
.jsoneditor-contextmenu button.append:hover > .icon,
.jsoneditor-contextmenu button.append:focus > .icon {
background-position: 0 0;
background-position: 0 0;
}
.jsoneditor-contextmenu button.insert > .icon {
background-position: 0 -24px;
background-position: 0 -24px;
}
.jsoneditor-contextmenu button.insert:hover > .icon,
.jsoneditor-contextmenu button.insert:focus > .icon {
background-position: 0 0;
background-position: 0 0;
}
.jsoneditor-contextmenu button.duplicate > .icon {
background-position: -48px -24px;
background-position: -48px -24px;
}
.jsoneditor-contextmenu button.duplicate:hover > .icon,
.jsoneditor-contextmenu button.duplicate:focus > .icon {
background-position: -48px 0;
background-position: -48px 0;
}
.jsoneditor-contextmenu button.sort-asc > .icon {
background-position: -168px -24px;
background-position: -168px -24px;
}
.jsoneditor-contextmenu button.sort-asc:hover > .icon,
.jsoneditor-contextmenu button.sort-asc:focus > .icon {
background-position: -168px 0;
background-position: -168px 0;
}
.jsoneditor-contextmenu button.sort-desc > .icon {
background-position: -192px -24px;
background-position: -192px -24px;
}
.jsoneditor-contextmenu button.sort-desc:hover > .icon,
.jsoneditor-contextmenu button.sort-desc:focus > .icon {
background-position: -192px 0;
background-position: -192px 0;
}
/* ContextMenu - sub menu */
.jsoneditor-contextmenu ul li .selected {
background-color: #D5DDF6;
background-color: #D5DDF6;
}
.jsoneditor-contextmenu ul li {
overflow: hidden;
overflow: hidden;
}
.jsoneditor-contextmenu ul li ul {
display: none;
position: relative;
left: -10px;
top: 0;
display: none;
position: relative;
left: -10px;
top: 0;
border: none;
box-shadow: inset 0 0 10px rgba(128, 128, 128, 0.5);
padding: 0 10px;
border: none;
box-shadow: inset 0 0 10px rgba(128, 128, 128, 0.5);
padding: 0 10px;
/* TODO: transition is not supported on IE8-9 */
-webkit-transition: all 0.3s ease-out;
-moz-transition: all 0.3s ease-out;
-o-transition: all 0.3s ease-out;
transition: all 0.3s ease-out;
/* TODO: transition is not supported on IE8-9 */
-webkit-transition: all 0.3s ease-out;
-moz-transition: all 0.3s ease-out;
-o-transition: all 0.3s ease-out;
transition: all 0.3s ease-out;
}
.jsoneditor-contextmenu ul li.selected ul {
}
.jsoneditor-contextmenu ul li ul li button {
padding-left: 24px;
padding-left: 24px;
}
.jsoneditor-contextmenu ul li ul li button:hover,
.jsoneditor-contextmenu ul li ul li button:focus {
background-color: #f5f5f5;
background-color: #f5f5f5;
}
.jsoneditor-contextmenu button.type-string > .icon {
background-position: -144px -24px;
background-position: -144px -24px;
}
.jsoneditor-contextmenu button.type-string:hover > .icon,
.jsoneditor-contextmenu button.type-string:focus > .icon,
.jsoneditor-contextmenu button.type-string.selected > .icon{
background-position: -144px 0;
background-position: -144px 0;
}
.jsoneditor-contextmenu button.type-auto > .icon {
background-position: -120px -24px;
background-position: -120px -24px;
}
.jsoneditor-contextmenu button.type-auto:hover > .icon,
.jsoneditor-contextmenu button.type-auto:focus > .icon,
.jsoneditor-contextmenu button.type-auto.selected > .icon {
background-position: -120px 0;
background-position: -120px 0;
}
.jsoneditor-contextmenu button.type-object > .icon {
background-position: -72px -24px;
background-position: -72px -24px;
}
.jsoneditor-contextmenu button.type-object:hover > .icon,
.jsoneditor-contextmenu button.type-object:focus > .icon,
.jsoneditor-contextmenu button.type-object.selected > .icon{
background-position: -72px 0;
background-position: -72px 0;
}
.jsoneditor-contextmenu button.type-array > .icon {
background-position: -96px -24px;
background-position: -96px -24px;
}
.jsoneditor-contextmenu button.type-array:hover > .icon,
.jsoneditor-contextmenu button.type-array:focus > .icon,
.jsoneditor-contextmenu button.type-array.selected > .icon{
background-position: -96px 0;
background-position: -96px 0;
}
.jsoneditor-contextmenu button.type-modes > .icon {
background-image: none;
width: 6px;
background-image: none;
width: 6px;
}
.jsoneditor .menu {
width: 100%;
height: 35px;
padding: 2px;
margin: 0;
overflow: hidden;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
width: 100%;
height: 35px;
padding: 2px;
margin: 0;
overflow: hidden;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
color: #1A1A1A;
background-color: #D5DDF6;
border-bottom: 1px solid #97B0F8;
color: #1A1A1A;
background-color: #D5DDF6;
border-bottom: 1px solid #97B0F8;
}
.jsoneditor .menu button {
width: 26px;
height: 26px;
margin: 2px;
padding: 0;
border-radius: 2px;
border: 1px solid #aec0f8;
background: #e3eaf6 url('img/jsoneditor-icons.png');
color: #4D4D4D;
opacity: 0.8;
width: 26px;
height: 26px;
margin: 2px;
padding: 0;
border-radius: 2px;
border: 1px solid #aec0f8;
background: #e3eaf6 url('img/jsoneditor-icons.png');
color: #4D4D4D;
opacity: 0.8;
font-family: arial, sans-serif;
font-size: 10pt;
font-family: arial, sans-serif;
font-size: 10pt;
float: left;
float: left;
}
.jsoneditor .menu button:hover {
background-color: #f0f2f5;
background-color: #f0f2f5;
}
.jsoneditor .menu button:active {
background-color: #ffffff;
background-color: #ffffff;
}
.jsoneditor .menu button:disabled {
background-color: #e3eaf6;
background-color: #e3eaf6;
}
.jsoneditor .menu button.collapse-all {
background-position: 0 -96px;
background-position: 0 -96px;
}
.jsoneditor .menu button.expand-all {
background-position: 0 -120px;
background-position: 0 -120px;
}
.jsoneditor .menu button.undo {
background-position: -24px -96px;
background-position: -24px -96px;
}
.jsoneditor .menu button.undo:disabled {
background-position: -24px -120px;
background-position: -24px -120px;
}
.jsoneditor .menu button.redo {
background-position: -48px -96px;
background-position: -48px -96px;
}
.jsoneditor .menu button.redo:disabled {
background-position: -48px -120px;
background-position: -48px -120px;
}
.jsoneditor .menu button.compact {
background-position: -72px -96px;
background-position: -72px -96px;
}
.jsoneditor .menu button.format {
background-position: -72px -120px;
background-position: -72px -120px;
}
.jsoneditor .menu button.modes {
background-image: none;
width: auto;
padding-left: 6px;
padding-right: 6px;
background-image: none;
width: auto;
padding-left: 6px;
padding-right: 6px;
}
.jsoneditor .menu button.separator {
margin-left: 10px;
margin-left: 10px;
}
.jsoneditor .menu a {
font-family: arial, sans-serif;
font-size: 10pt;
color: #97B0F8;
vertical-align: middle;
font-family: arial, sans-serif;
font-size: 10pt;
color: #97B0F8;
vertical-align: middle;
}
.jsoneditor .menu a:hover {
color: red;
color: red;
}
.jsoneditor .menu a.poweredBy {
font-size: 8pt;
position: absolute;
right: 0;
top: 0;
padding: 10px;
font-size: 8pt;
position: absolute;
right: 0;
top: 0;
padding: 10px;
}
/* TODO: css for button:disabled is not supported by IE8 */
@ -550,74 +550,74 @@
.jsoneditor .search input,
.jsoneditor .search .results {
font-family: arial, sans-serif;
font-size: 10pt;
color: #1A1A1A;
font-family: arial, sans-serif;
font-size: 10pt;
color: #1A1A1A;
}
.jsoneditor .search {
position: absolute;
right: 2px;
top: 2px;
position: absolute;
right: 2px;
top: 2px;
}
.jsoneditor .search .frame {
border: 1px solid #97B0F8;
background-color: white;
padding: 0 2px;
margin: 0;
border: 1px solid #97B0F8;
background-color: white;
padding: 0 2px;
margin: 0;
}
.jsoneditor .search .frame table {
border-collapse: collapse;
border-collapse: collapse;
}
.jsoneditor .search input {
width: 120px;
border: none;
outline: none;
margin: 1px;
width: 120px;
border: none;
outline: none;
margin: 1px;
}
.jsoneditor .search .results {
color: #4d4d4d;
padding-right: 5px;
line-height: 24px;
color: #4d4d4d;
padding-right: 5px;
line-height: 24px;
}
.jsoneditor .search button {
width: 16px;
height: 24px;
padding: 0;
margin: 0;
border: none;
background: url('img/jsoneditor-icons.png');
vertical-align: top;
width: 16px;
height: 24px;
padding: 0;
margin: 0;
border: none;
background: url('img/jsoneditor-icons.png');
vertical-align: top;
}
.jsoneditor .search button:hover {
background-color: transparent;
background-color: transparent;
}
.jsoneditor .search button.refresh {
width: 18px;
background-position: -99px -73px;
width: 18px;
background-position: -99px -73px;
}
.jsoneditor .search button.next {
cursor: pointer;
background-position: -124px -73px;
cursor: pointer;
background-position: -124px -73px;
}
.jsoneditor .search button.next:hover {
background-position: -124px -49px;
background-position: -124px -49px;
}
.jsoneditor .search button.previous {
cursor: pointer;
background-position: -148px -73px;
margin-right: 2px;
cursor: pointer;
background-position: -148px -73px;
margin-right: 2px;
}
.jsoneditor .search button.previous:hover {
background-position: -148px -49px;
background-position: -148px -49px;
}

File diff suppressed because it is too large Load Diff

View File

@ -2,81 +2,81 @@
/* ContextMenu - main menu */
.jsoneditor-contextmenu {
position: fixed;
z-index: 99999;
position: fixed;
z-index: 99999;
}
.jsoneditor-contextmenu ul {
position: relative;
left: 0;
top: 0;
width: 124px;
position: relative;
left: 0;
top: 0;
width: 124px;
background: white;
border: 1px solid #d3d3d3;
box-shadow: 2px 2px 12px rgba(128, 128, 128, 0.3);
background: white;
border: 1px solid #d3d3d3;
box-shadow: 2px 2px 12px rgba(128, 128, 128, 0.3);
list-style: none;
margin: 0;
padding: 0;
list-style: none;
margin: 0;
padding: 0;
}
.jsoneditor-contextmenu ul li button {
padding: 0;
margin: 0;
width: 124px;
height: 24px;
border: none;
cursor: pointer;
color: #4d4d4d;
background: transparent;
padding: 0;
margin: 0;
width: 124px;
height: 24px;
border: none;
cursor: pointer;
color: #4d4d4d;
background: transparent;
line-height: 26px;
text-align: left;
line-height: 26px;
text-align: left;
}
/* Fix button padding in firefox */
.jsoneditor-contextmenu ul li button::-moz-focus-inner {
padding: 0;
border: 0;
padding: 0;
border: 0;
}
.jsoneditor-contextmenu ul li button:hover,
.jsoneditor-contextmenu ul li button:focus {
color: #1a1a1a;
background-color: #f5f5f5;
outline: none;
color: #1a1a1a;
background-color: #f5f5f5;
outline: none;
}
.jsoneditor-contextmenu ul li button.default {
width: 92px;
width: 92px;
}
.jsoneditor-contextmenu ul li button.expand {
float: right;
width: 32px;
height: 24px;
border-left: 1px solid #e5e5e5;
float: right;
width: 32px;
height: 24px;
border-left: 1px solid #e5e5e5;
}
.jsoneditor-contextmenu div.icon {
float: left;
width: 24px;
height: 24px;
border: none;
padding: 0;
margin: 0;
background-image: url('img/jsoneditor-icons.png');
float: left;
width: 24px;
height: 24px;
border: none;
padding: 0;
margin: 0;
background-image: url('img/jsoneditor-icons.png');
}
.jsoneditor-contextmenu ul li button div.expand {
float: right;
width: 24px;
height: 24px;
padding: 0;
margin: 0 4px 0 0;
background: url('img/jsoneditor-icons.png') 0 -72px;
opacity: 0.4;
float: right;
width: 24px;
height: 24px;
padding: 0;
margin: 0 4px 0 0;
background: url('img/jsoneditor-icons.png') 0 -72px;
opacity: 0.4;
}
.jsoneditor-contextmenu ul li button:hover div.expand,
@ -84,141 +84,141 @@
.jsoneditor-contextmenu ul li.selected div.expand,
.jsoneditor-contextmenu ul li button.expand:hover div.expand,
.jsoneditor-contextmenu ul li button.expand:focus div.expand {
opacity: 1;
opacity: 1;
}
.jsoneditor-contextmenu .separator {
height: 0;
border-top: 1px solid #e5e5e5;
padding-top: 5px;
margin-top: 5px;
height: 0;
border-top: 1px solid #e5e5e5;
padding-top: 5px;
margin-top: 5px;
}
.jsoneditor-contextmenu button.remove > .icon {
background-position: -24px -24px;
background-position: -24px -24px;
}
.jsoneditor-contextmenu button.remove:hover > .icon,
.jsoneditor-contextmenu button.remove:focus > .icon {
background-position: -24px 0;
background-position: -24px 0;
}
.jsoneditor-contextmenu button.append > .icon {
background-position: 0 -24px;
background-position: 0 -24px;
}
.jsoneditor-contextmenu button.append:hover > .icon,
.jsoneditor-contextmenu button.append:focus > .icon {
background-position: 0 0;
background-position: 0 0;
}
.jsoneditor-contextmenu button.insert > .icon {
background-position: 0 -24px;
background-position: 0 -24px;
}
.jsoneditor-contextmenu button.insert:hover > .icon,
.jsoneditor-contextmenu button.insert:focus > .icon {
background-position: 0 0;
background-position: 0 0;
}
.jsoneditor-contextmenu button.duplicate > .icon {
background-position: -48px -24px;
background-position: -48px -24px;
}
.jsoneditor-contextmenu button.duplicate:hover > .icon,
.jsoneditor-contextmenu button.duplicate:focus > .icon {
background-position: -48px 0;
background-position: -48px 0;
}
.jsoneditor-contextmenu button.sort-asc > .icon {
background-position: -168px -24px;
background-position: -168px -24px;
}
.jsoneditor-contextmenu button.sort-asc:hover > .icon,
.jsoneditor-contextmenu button.sort-asc:focus > .icon {
background-position: -168px 0;
background-position: -168px 0;
}
.jsoneditor-contextmenu button.sort-desc > .icon {
background-position: -192px -24px;
background-position: -192px -24px;
}
.jsoneditor-contextmenu button.sort-desc:hover > .icon,
.jsoneditor-contextmenu button.sort-desc:focus > .icon {
background-position: -192px 0;
background-position: -192px 0;
}
/* ContextMenu - sub menu */
.jsoneditor-contextmenu ul li .selected {
background-color: #D5DDF6;
background-color: #D5DDF6;
}
.jsoneditor-contextmenu ul li {
overflow: hidden;
overflow: hidden;
}
.jsoneditor-contextmenu ul li ul {
display: none;
position: relative;
left: -10px;
top: 0;
display: none;
position: relative;
left: -10px;
top: 0;
border: none;
box-shadow: inset 0 0 10px rgba(128, 128, 128, 0.5);
padding: 0 10px;
border: none;
box-shadow: inset 0 0 10px rgba(128, 128, 128, 0.5);
padding: 0 10px;
/* TODO: transition is not supported on IE8-9 */
-webkit-transition: all 0.3s ease-out;
-moz-transition: all 0.3s ease-out;
-o-transition: all 0.3s ease-out;
transition: all 0.3s ease-out;
/* TODO: transition is not supported on IE8-9 */
-webkit-transition: all 0.3s ease-out;
-moz-transition: all 0.3s ease-out;
-o-transition: all 0.3s ease-out;
transition: all 0.3s ease-out;
}
.jsoneditor-contextmenu ul li.selected ul {
}
.jsoneditor-contextmenu ul li ul li button {
padding-left: 24px;
padding-left: 24px;
}
.jsoneditor-contextmenu ul li ul li button:hover,
.jsoneditor-contextmenu ul li ul li button:focus {
background-color: #f5f5f5;
background-color: #f5f5f5;
}
.jsoneditor-contextmenu button.type-string > .icon {
background-position: -144px -24px;
background-position: -144px -24px;
}
.jsoneditor-contextmenu button.type-string:hover > .icon,
.jsoneditor-contextmenu button.type-string:focus > .icon,
.jsoneditor-contextmenu button.type-string.selected > .icon{
background-position: -144px 0;
background-position: -144px 0;
}
.jsoneditor-contextmenu button.type-auto > .icon {
background-position: -120px -24px;
background-position: -120px -24px;
}
.jsoneditor-contextmenu button.type-auto:hover > .icon,
.jsoneditor-contextmenu button.type-auto:focus > .icon,
.jsoneditor-contextmenu button.type-auto.selected > .icon {
background-position: -120px 0;
background-position: -120px 0;
}
.jsoneditor-contextmenu button.type-object > .icon {
background-position: -72px -24px;
background-position: -72px -24px;
}
.jsoneditor-contextmenu button.type-object:hover > .icon,
.jsoneditor-contextmenu button.type-object:focus > .icon,
.jsoneditor-contextmenu button.type-object.selected > .icon{
background-position: -72px 0;
background-position: -72px 0;
}
.jsoneditor-contextmenu button.type-array > .icon {
background-position: -96px -24px;
background-position: -96px -24px;
}
.jsoneditor-contextmenu button.type-array:hover > .icon,
.jsoneditor-contextmenu button.type-array:focus > .icon,
.jsoneditor-contextmenu button.type-array.selected > .icon{
background-position: -96px 0;
background-position: -96px 0;
}
.jsoneditor-contextmenu button.type-modes > .icon {
background-image: none;
width: 6px;
background-image: none;
width: 6px;
}

View File

@ -2,60 +2,60 @@
.jsoneditor .field,
.jsoneditor .value,
.jsoneditor .readonly {
border: 1px solid transparent;
min-height: 16px;
min-width: 32px;
padding: 2px;
margin: 1px;
word-wrap: break-word;
float: left;
border: 1px solid transparent;
min-height: 16px;
min-width: 32px;
padding: 2px;
margin: 1px;
word-wrap: break-word;
float: left;
}
/* adjust margin of p elements inside editable divs, needed for Opera, IE */
.jsoneditor .field p,
.jsoneditor .value p {
margin: 0;
margin: 0;
}
.jsoneditor .value {
word-break: break-word;
word-break: break-word;
}
.jsoneditor .readonly {
min-width: 16px;
color: gray;
min-width: 16px;
color: gray;
}
.jsoneditor .empty {
border-color: lightgray;
border-style: dashed;
border-radius: 2px;
border-color: lightgray;
border-style: dashed;
border-radius: 2px;
}
.jsoneditor .field.empty {
background-image: url('img/jsoneditor-icons.png');
background-position: 0 -144px;
background-image: url('img/jsoneditor-icons.png');
background-position: 0 -144px;
}
.jsoneditor .value.empty {
background-image: url('img/jsoneditor-icons.png');
background-position: -48px -144px;
background-image: url('img/jsoneditor-icons.png');
background-position: -48px -144px;
}
.jsoneditor .value.url {
color: green;
text-decoration: underline;
color: green;
text-decoration: underline;
}
.jsoneditor a.value.url:hover,
.jsoneditor a.value.url:focus {
color: red;
color: red;
}
.jsoneditor .separator {
padding: 3px 0;
vertical-align: top;
color: gray;
padding: 3px 0;
vertical-align: top;
color: gray;
}
.jsoneditor .field[contenteditable=true]:focus,
@ -64,9 +64,9 @@
.jsoneditor .value[contenteditable=true]:hover,
.jsoneditor .field.highlight,
.jsoneditor .value.highlight {
background-color: #FFFFAB;
border: 1px solid yellow;
border-radius: 2px;
background-color: #FFFFAB;
border: 1px solid yellow;
border-radius: 2px;
}
.jsoneditor .field.highlight-active,
@ -75,141 +75,141 @@
.jsoneditor .value.highlight-active,
.jsoneditor .value.highlight-active:focus,
.jsoneditor .value.highlight-active:hover {
background-color: #ffee00;
border: 1px solid #ffc700;
border-radius: 2px;
background-color: #ffee00;
border: 1px solid #ffc700;
border-radius: 2px;
}
.jsoneditor div.tree button {
width: 24px;
height: 24px;
padding: 0;
margin: 0;
border: none;
cursor: pointer;
background: transparent url('img/jsoneditor-icons.png');
width: 24px;
height: 24px;
padding: 0;
margin: 0;
border: none;
cursor: pointer;
background: transparent url('img/jsoneditor-icons.png');
}
.jsoneditor div.tree button.collapsed {
background-position: 0 -48px;
background-position: 0 -48px;
}
.jsoneditor div.tree button.expanded {
background-position: 0 -72px;
background-position: 0 -72px;
}
.jsoneditor div.tree button.contextmenu {
background-position: -48px -72px;
background-position: -48px -72px;
}
.jsoneditor div.tree button.contextmenu:hover,
.jsoneditor div.tree button.contextmenu:focus,
.jsoneditor div.tree button.contextmenu.selected {
background-position: -48px -48px;
background-position: -48px -48px;
}
.jsoneditor div.tree *:focus {
outline: none;
outline: none;
}
.jsoneditor div.tree button:focus {
/* TODO: nice outline for buttons with focus
outline: #97B0F8 solid 2px;
box-shadow: 0 0 8px #97B0F8;
*/
background-color: #f5f5f5;
outline: #e5e5e5 solid 1px;
/* TODO: nice outline for buttons with focus
outline: #97B0F8 solid 2px;
box-shadow: 0 0 8px #97B0F8;
*/
background-color: #f5f5f5;
outline: #e5e5e5 solid 1px;
}
.jsoneditor div.tree button.invisible {
visibility: hidden;
background: none;
visibility: hidden;
background: none;
}
.jsoneditor {
color: #1A1A1A;
border: 1px solid #97B0F8;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
color: #1A1A1A;
border: 1px solid #97B0F8;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
width: 100%;
height: 100%;
overflow: auto;
position: relative;
padding: 0;
line-height: 100%;
width: 100%;
height: 100%;
overflow: auto;
position: relative;
padding: 0;
line-height: 100%;
}
.jsoneditor div.tree table.tree {
border-collapse: collapse;
border-spacing: 0;
width: 100%;
margin: 0;
border-collapse: collapse;
border-spacing: 0;
width: 100%;
margin: 0;
}
.jsoneditor div.outer {
width: 100%;
height: 100%;
margin: -35px 0 0 0;
padding: 35px 0 0 0;
width: 100%;
height: 100%;
margin: -35px 0 0 0;
padding: 35px 0 0 0;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
overflow: hidden;
overflow: hidden;
}
.jsoneditor div.tree {
width: 100%;
height: 100%;
position: relative;
overflow: auto;
width: 100%;
height: 100%;
position: relative;
overflow: auto;
}
.jsoneditor textarea.text {
width: 100%;
height: 100%;
margin: 0;
width: 100%;
height: 100%;
margin: 0;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
border: none;
background-color: white;
resize: none;
border: none;
background-color: white;
resize: none;
}
.jsoneditor tr.highlight {
background-color: #FFFFAB;
background-color: #FFFFAB;
}
.jsoneditor div.tree button.dragarea {
background: url('img/jsoneditor-icons.png') -72px -72px;
cursor: move;
background: url('img/jsoneditor-icons.png') -72px -72px;
cursor: move;
}
.jsoneditor div.tree button.dragarea:hover,
.jsoneditor div.tree button.dragarea:focus {
background-position: -72px -48px;
background-position: -72px -48px;
}
.jsoneditor tr,
.jsoneditor th,
.jsoneditor td {
padding: 0;
margin: 0;
padding: 0;
margin: 0;
}
.jsoneditor td {
vertical-align: top;
vertical-align: top;
}
.jsoneditor td.tree {
vertical-align: top;
vertical-align: top;
}
.jsoneditor .field,
@ -217,7 +217,7 @@
.jsoneditor td,
.jsoneditor th,
.jsoneditor textarea {
font-family: droid sans mono, monospace, courier new, courier, sans-serif;
font-size: 10pt;
color: #1A1A1A;
font-family: droid sans mono, monospace, courier new, courier, sans-serif;
font-size: 10pt;
color: #1A1A1A;
}

View File

@ -1,99 +1,99 @@
.jsoneditor .menu {
width: 100%;
height: 35px;
padding: 2px;
margin: 0;
overflow: hidden;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
width: 100%;
height: 35px;
padding: 2px;
margin: 0;
overflow: hidden;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
color: #1A1A1A;
background-color: #D5DDF6;
border-bottom: 1px solid #97B0F8;
color: #1A1A1A;
background-color: #D5DDF6;
border-bottom: 1px solid #97B0F8;
}
.jsoneditor .menu button {
width: 26px;
height: 26px;
margin: 2px;
padding: 0;
border-radius: 2px;
border: 1px solid #aec0f8;
background: #e3eaf6 url('img/jsoneditor-icons.png');
color: #4D4D4D;
opacity: 0.8;
width: 26px;
height: 26px;
margin: 2px;
padding: 0;
border-radius: 2px;
border: 1px solid #aec0f8;
background: #e3eaf6 url('img/jsoneditor-icons.png');
color: #4D4D4D;
opacity: 0.8;
font-family: arial, sans-serif;
font-size: 10pt;
font-family: arial, sans-serif;
font-size: 10pt;
float: left;
float: left;
}
.jsoneditor .menu button:hover {
background-color: #f0f2f5;
background-color: #f0f2f5;
}
.jsoneditor .menu button:active {
background-color: #ffffff;
background-color: #ffffff;
}
.jsoneditor .menu button:disabled {
background-color: #e3eaf6;
background-color: #e3eaf6;
}
.jsoneditor .menu button.collapse-all {
background-position: 0 -96px;
background-position: 0 -96px;
}
.jsoneditor .menu button.expand-all {
background-position: 0 -120px;
background-position: 0 -120px;
}
.jsoneditor .menu button.undo {
background-position: -24px -96px;
background-position: -24px -96px;
}
.jsoneditor .menu button.undo:disabled {
background-position: -24px -120px;
background-position: -24px -120px;
}
.jsoneditor .menu button.redo {
background-position: -48px -96px;
background-position: -48px -96px;
}
.jsoneditor .menu button.redo:disabled {
background-position: -48px -120px;
background-position: -48px -120px;
}
.jsoneditor .menu button.compact {
background-position: -72px -96px;
background-position: -72px -96px;
}
.jsoneditor .menu button.format {
background-position: -72px -120px;
background-position: -72px -120px;
}
.jsoneditor .menu button.modes {
background-image: none;
width: auto;
padding-left: 6px;
padding-right: 6px;
background-image: none;
width: auto;
padding-left: 6px;
padding-right: 6px;
}
.jsoneditor .menu button.separator {
margin-left: 10px;
margin-left: 10px;
}
.jsoneditor .menu a {
font-family: arial, sans-serif;
font-size: 10pt;
color: #97B0F8;
vertical-align: middle;
font-family: arial, sans-serif;
font-size: 10pt;
color: #97B0F8;
vertical-align: middle;
}
.jsoneditor .menu a:hover {
color: red;
color: red;
}
.jsoneditor .menu a.poweredBy {
font-size: 8pt;
position: absolute;
right: 0;
top: 0;
padding: 10px;
font-size: 8pt;
position: absolute;
right: 0;
top: 0;
padding: 10px;
}
/* TODO: css for button:disabled is not supported by IE8 */

View File

@ -1,73 +1,73 @@
.jsoneditor .search input,
.jsoneditor .search .results {
font-family: arial, sans-serif;
font-size: 10pt;
color: #1A1A1A;
font-family: arial, sans-serif;
font-size: 10pt;
color: #1A1A1A;
}
.jsoneditor .search {
position: absolute;
right: 2px;
top: 2px;
position: absolute;
right: 2px;
top: 2px;
}
.jsoneditor .search .frame {
border: 1px solid #97B0F8;
background-color: white;
padding: 0 2px;
margin: 0;
border: 1px solid #97B0F8;
background-color: white;
padding: 0 2px;
margin: 0;
}
.jsoneditor .search .frame table {
border-collapse: collapse;
border-collapse: collapse;
}
.jsoneditor .search input {
width: 120px;
border: none;
outline: none;
margin: 1px;
width: 120px;
border: none;
outline: none;
margin: 1px;
}
.jsoneditor .search .results {
color: #4d4d4d;
padding-right: 5px;
line-height: 24px;
color: #4d4d4d;
padding-right: 5px;
line-height: 24px;
}
.jsoneditor .search button {
width: 16px;
height: 24px;
padding: 0;
margin: 0;
border: none;
background: url('img/jsoneditor-icons.png');
vertical-align: top;
width: 16px;
height: 24px;
padding: 0;
margin: 0;
border: none;
background: url('img/jsoneditor-icons.png');
vertical-align: top;
}
.jsoneditor .search button:hover {
background-color: transparent;
background-color: transparent;
}
.jsoneditor .search button.refresh {
width: 18px;
background-position: -99px -73px;
width: 18px;
background-position: -99px -73px;
}
.jsoneditor .search button.next {
cursor: pointer;
background-position: -124px -73px;
cursor: pointer;
background-position: -124px -73px;
}
.jsoneditor .search button.next:hover {
background-position: -124px -49px;
background-position: -124px -49px;
}
.jsoneditor .search button.previous {
cursor: pointer;
background-position: -148px -73px;
margin-right: 2px;
cursor: pointer;
background-position: -148px -73px;
margin-right: 2px;
}
.jsoneditor .search button.previous:hover {
background-position: -148px -49px;
background-position: -148px -49px;
}

View File

@ -6,9 +6,9 @@
* end of the list with childs for an object or array
*/
function AppendNode (editor) {
/** @type {TreeEditor} */
this.editor = editor;
this.dom = {};
/** @type {TreeEditor} */
this.editor = editor;
this.dom = {};
}
AppendNode.prototype = new Node();
@ -18,89 +18,89 @@ AppendNode.prototype = new Node();
* @return {Element} dom TR element
*/
AppendNode.prototype.getDom = function () {
// TODO: implement a new solution for the append node
var dom = this.dom;
// TODO: implement a new solution for the append node
var dom = this.dom;
if (dom.tr) {
return dom.tr;
}
if (dom.tr) {
return dom.tr;
}
// a row for the append button
var trAppend = document.createElement('tr');
trAppend.node = this;
dom.tr = trAppend;
// a row for the append button
var trAppend = document.createElement('tr');
trAppend.node = this;
dom.tr = trAppend;
// TODO: consistent naming
// TODO: consistent naming
if (this.editor.mode.edit) {
// a cell for the dragarea column
dom.tdDrag = document.createElement('td');
if (this.editor.mode.edit) {
// a cell for the dragarea column
dom.tdDrag = document.createElement('td');
// create context menu
var tdMenu = document.createElement('td');
dom.tdMenu = tdMenu;
var menu = document.createElement('button');
menu.className = 'contextmenu';
menu.title = 'Click to open the actions menu (Ctrl+M)';
dom.menu = menu;
tdMenu.appendChild(dom.menu);
}
// create context menu
var tdMenu = document.createElement('td');
dom.tdMenu = tdMenu;
var menu = document.createElement('button');
menu.className = 'contextmenu';
menu.title = 'Click to open the actions menu (Ctrl+M)';
dom.menu = menu;
tdMenu.appendChild(dom.menu);
}
// a cell for the contents (showing text 'empty')
var tdAppend = document.createElement('td');
var domText = document.createElement('div');
domText.innerHTML = '(empty)';
domText.className = 'readonly';
tdAppend.appendChild(domText);
dom.td = tdAppend;
dom.text = domText;
// a cell for the contents (showing text 'empty')
var tdAppend = document.createElement('td');
var domText = document.createElement('div');
domText.innerHTML = '(empty)';
domText.className = 'readonly';
tdAppend.appendChild(domText);
dom.td = tdAppend;
dom.text = domText;
this.updateDom();
this.updateDom();
return trAppend;
return trAppend;
};
/**
* Update the HTML dom of the Node
*/
AppendNode.prototype.updateDom = function () {
var dom = this.dom;
var tdAppend = dom.td;
if (tdAppend) {
tdAppend.style.paddingLeft = (this.getLevel() * 24 + 26) + 'px';
// TODO: not so nice hard coded offset
}
var dom = this.dom;
var tdAppend = dom.td;
if (tdAppend) {
tdAppend.style.paddingLeft = (this.getLevel() * 24 + 26) + 'px';
// TODO: not so nice hard coded offset
}
var domText = dom.text;
if (domText) {
domText.innerHTML = '(empty ' + this.parent.type + ')';
}
var domText = dom.text;
if (domText) {
domText.innerHTML = '(empty ' + this.parent.type + ')';
}
// attach or detach the contents of the append node:
// hide when the parent has childs, show when the parent has no childs
var trAppend = dom.tr;
if (!this.isVisible()) {
if (dom.tr.firstChild) {
if (dom.tdDrag) {
trAppend.removeChild(dom.tdDrag);
}
if (dom.tdMenu) {
trAppend.removeChild(dom.tdMenu);
}
trAppend.removeChild(tdAppend);
}
// attach or detach the contents of the append node:
// hide when the parent has childs, show when the parent has no childs
var trAppend = dom.tr;
if (!this.isVisible()) {
if (dom.tr.firstChild) {
if (dom.tdDrag) {
trAppend.removeChild(dom.tdDrag);
}
if (dom.tdMenu) {
trAppend.removeChild(dom.tdMenu);
}
trAppend.removeChild(tdAppend);
}
else {
if (!dom.tr.firstChild) {
if (dom.tdDrag) {
trAppend.appendChild(dom.tdDrag);
}
if (dom.tdMenu) {
trAppend.appendChild(dom.tdMenu);
}
trAppend.appendChild(tdAppend);
}
}
else {
if (!dom.tr.firstChild) {
if (dom.tdDrag) {
trAppend.appendChild(dom.tdDrag);
}
if (dom.tdMenu) {
trAppend.appendChild(dom.tdMenu);
}
trAppend.appendChild(tdAppend);
}
}
};
/**
@ -109,7 +109,7 @@ AppendNode.prototype.updateDom = function () {
* @return {boolean} isVisible
*/
AppendNode.prototype.isVisible = function () {
return (this.parent.childs.length == 0);
return (this.parent.childs.length == 0);
};
/**
@ -119,57 +119,57 @@ AppendNode.prototype.isVisible = function () {
* is being closed.
*/
AppendNode.prototype.showContextMenu = function (anchor, onClose) {
var node = this;
var titles = Node.TYPE_TITLES;
var items = [
// create append button
var node = this;
var titles = Node.TYPE_TITLES;
var items = [
// create append button
{
'text': 'Append',
'title': 'Append a new field with type \'auto\' (Ctrl+Shift+Ins)',
'submenuTitle': 'Select the type of the field to be appended',
'className': 'insert',
'click': function () {
node._onAppend('', '', 'auto');
},
'submenu': [
{
'text': 'Append',
'title': 'Append a new field with type \'auto\' (Ctrl+Shift+Ins)',
'submenuTitle': 'Select the type of the field to be appended',
'className': 'insert',
'click': function () {
node._onAppend('', '', 'auto');
},
'submenu': [
{
'text': 'Auto',
'className': 'type-auto',
'title': titles.auto,
'click': function () {
node._onAppend('', '', 'auto');
}
},
{
'text': 'Array',
'className': 'type-array',
'title': titles.array,
'click': function () {
node._onAppend('', []);
}
},
{
'text': 'Object',
'className': 'type-object',
'title': titles.object,
'click': function () {
node._onAppend('', {});
}
},
{
'text': 'String',
'className': 'type-string',
'title': titles.string,
'click': function () {
node._onAppend('', '', 'string');
}
}
]
'text': 'Auto',
'className': 'type-auto',
'title': titles.auto,
'click': function () {
node._onAppend('', '', 'auto');
}
},
{
'text': 'Array',
'className': 'type-array',
'title': titles.array,
'click': function () {
node._onAppend('', []);
}
},
{
'text': 'Object',
'className': 'type-object',
'title': titles.object,
'click': function () {
node._onAppend('', {});
}
},
{
'text': 'String',
'className': 'type-string',
'title': titles.string,
'click': function () {
node._onAppend('', '', 'string');
}
}
];
]
}
];
var menu = new ContextMenu(items, {close: onClose});
menu.show(anchor);
var menu = new ContextMenu(items, {close: onClose});
menu.show(anchor);
};
/**
@ -177,35 +177,35 @@ AppendNode.prototype.showContextMenu = function (anchor, onClose) {
* @param {Event} event
*/
AppendNode.prototype.onEvent = function (event) {
var type = event.type;
var target = event.target || event.srcElement;
var dom = this.dom;
var type = event.type;
var target = event.target || event.srcElement;
var dom = this.dom;
// highlight the append nodes parent
var menu = dom.menu;
if (target == menu) {
if (type == 'mouseover') {
this.editor.highlighter.highlight(this.parent);
}
else if (type == 'mouseout') {
this.editor.highlighter.unhighlight();
}
// highlight the append nodes parent
var menu = dom.menu;
if (target == menu) {
if (type == 'mouseover') {
this.editor.highlighter.highlight(this.parent);
}
else if (type == 'mouseout') {
this.editor.highlighter.unhighlight();
}
}
// context menu events
if (type == 'click' && target == dom.menu) {
var highlighter = this.editor.highlighter;
highlighter.highlight(this.parent);
highlighter.lock();
util.addClassName(dom.menu, 'selected');
this.showContextMenu(dom.menu, function () {
util.removeClassName(dom.menu, 'selected');
highlighter.unlock();
highlighter.unhighlight();
});
}
// context menu events
if (type == 'click' && target == dom.menu) {
var highlighter = this.editor.highlighter;
highlighter.highlight(this.parent);
highlighter.lock();
util.addClassName(dom.menu, 'selected');
this.showContextMenu(dom.menu, function () {
util.removeClassName(dom.menu, 'selected');
highlighter.unlock();
highlighter.unhighlight();
});
}
if (type == 'keydown') {
this.onKeyDown(event);
}
if (type == 'keydown') {
this.onKeyDown(event);
}
};

View File

@ -8,138 +8,138 @@
* @constructor
*/
function ContextMenu (items, options) {
this.dom = {};
this.dom = {};
var me = this;
var dom = this.dom;
this.anchor = undefined;
this.items = items;
this.eventListeners = {};
this.selection = undefined; // holds the selection before the menu was opened
this.visibleSubmenu = undefined;
this.onClose = options ? options.close : undefined;
var me = this;
var dom = this.dom;
this.anchor = undefined;
this.items = items;
this.eventListeners = {};
this.selection = undefined; // holds the selection before the menu was opened
this.visibleSubmenu = undefined;
this.onClose = options ? options.close : undefined;
// create a container element
var menu = document.createElement('div');
menu.className = 'jsoneditor-contextmenu';
dom.menu = menu;
// create a container element
var menu = document.createElement('div');
menu.className = 'jsoneditor-contextmenu';
dom.menu = menu;
// create a list to hold the menu items
var list = document.createElement('ul');
list.className = 'menu';
menu.appendChild(list);
dom.list = list;
dom.items = []; // list with all buttons
// create a list to hold the menu items
var list = document.createElement('ul');
list.className = 'menu';
menu.appendChild(list);
dom.list = list;
dom.items = []; // list with all buttons
// create a (non-visible) button to set the focus to the menu
var focusButton = document.createElement('button');
dom.focusButton = focusButton;
var li = document.createElement('li');
li.style.overflow = 'hidden';
li.style.height = '0';
li.appendChild(focusButton);
list.appendChild(li);
// create a (non-visible) button to set the focus to the menu
var focusButton = document.createElement('button');
dom.focusButton = focusButton;
var li = document.createElement('li');
li.style.overflow = 'hidden';
li.style.height = '0';
li.appendChild(focusButton);
list.appendChild(li);
function createMenuItems (list, domItems, items) {
items.forEach(function (item) {
if (item.type == 'separator') {
// create a separator
var separator = document.createElement('div');
separator.className = 'separator';
li = document.createElement('li');
li.appendChild(separator);
list.appendChild(li);
}
else {
var domItem = {};
// create a menu item
var li = document.createElement('li');
list.appendChild(li);
// create a button in the menu item
var button = document.createElement('button');
button.className = item.className;
domItem.button = button;
if (item.title) {
button.title = item.title;
}
if (item.click) {
button.onclick = function () {
me.hide();
item.click();
};
}
li.appendChild(button);
// create the contents of the button
if (item.submenu) {
// add the icon to the button
var divIcon = document.createElement('div');
divIcon.className = 'icon';
button.appendChild(divIcon);
button.appendChild(document.createTextNode(item.text));
var buttonSubmenu;
if (item.click) {
// submenu and a button with a click handler
button.className += ' default';
var buttonExpand = document.createElement('button');
domItem.buttonExpand = buttonExpand;
buttonExpand.className = 'expand';
buttonExpand.innerHTML = '<div class="expand"></div>';
li.appendChild(buttonExpand);
if (item.submenuTitle) {
buttonExpand.title = item.submenuTitle;
}
buttonSubmenu = buttonExpand;
}
else {
// submenu and a button without a click handler
var divExpand = document.createElement('div');
divExpand.className = 'expand';
button.appendChild(divExpand);
buttonSubmenu = button;
}
// attach a handler to expand/collapse the submenu
buttonSubmenu.onclick = function () {
me._onExpandItem(domItem);
buttonSubmenu.focus();
};
// create the submenu
var domSubItems = [];
domItem.subItems = domSubItems;
var ul = document.createElement('ul');
domItem.ul = ul;
ul.className = 'menu';
ul.style.height = '0';
li.appendChild(ul);
createMenuItems(ul, domSubItems, item.submenu);
}
else {
// no submenu, just a button with clickhandler
button.innerHTML = '<div class="icon"></div>' + item.text;
}
domItems.push(domItem);
}
});
}
createMenuItems(list, this.dom.items, items);
// TODO: when the editor is small, show the submenu on the right instead of inline?
// calculate the max height of the menu with one submenu expanded
this.maxHeight = 0; // height in pixels
function createMenuItems (list, domItems, items) {
items.forEach(function (item) {
var height = (items.length + (item.submenu ? item.submenu.length : 0)) * 24;
me.maxHeight = Math.max(me.maxHeight, height);
if (item.type == 'separator') {
// create a separator
var separator = document.createElement('div');
separator.className = 'separator';
li = document.createElement('li');
li.appendChild(separator);
list.appendChild(li);
}
else {
var domItem = {};
// create a menu item
var li = document.createElement('li');
list.appendChild(li);
// create a button in the menu item
var button = document.createElement('button');
button.className = item.className;
domItem.button = button;
if (item.title) {
button.title = item.title;
}
if (item.click) {
button.onclick = function () {
me.hide();
item.click();
};
}
li.appendChild(button);
// create the contents of the button
if (item.submenu) {
// add the icon to the button
var divIcon = document.createElement('div');
divIcon.className = 'icon';
button.appendChild(divIcon);
button.appendChild(document.createTextNode(item.text));
var buttonSubmenu;
if (item.click) {
// submenu and a button with a click handler
button.className += ' default';
var buttonExpand = document.createElement('button');
domItem.buttonExpand = buttonExpand;
buttonExpand.className = 'expand';
buttonExpand.innerHTML = '<div class="expand"></div>';
li.appendChild(buttonExpand);
if (item.submenuTitle) {
buttonExpand.title = item.submenuTitle;
}
buttonSubmenu = buttonExpand;
}
else {
// submenu and a button without a click handler
var divExpand = document.createElement('div');
divExpand.className = 'expand';
button.appendChild(divExpand);
buttonSubmenu = button;
}
// attach a handler to expand/collapse the submenu
buttonSubmenu.onclick = function () {
me._onExpandItem(domItem);
buttonSubmenu.focus();
};
// create the submenu
var domSubItems = [];
domItem.subItems = domSubItems;
var ul = document.createElement('ul');
domItem.ul = ul;
ul.className = 'menu';
ul.style.height = '0';
li.appendChild(ul);
createMenuItems(ul, domSubItems, item.submenu);
}
else {
// no submenu, just a button with clickhandler
button.innerHTML = '<div class="icon"></div>' + item.text;
}
domItems.push(domItem);
}
});
}
createMenuItems(list, this.dom.items, items);
// TODO: when the editor is small, show the submenu on the right instead of inline?
// calculate the max height of the menu with one submenu expanded
this.maxHeight = 0; // height in pixels
items.forEach(function (item) {
var height = (items.length + (item.submenu ? item.submenu.length : 0)) * 24;
me.maxHeight = Math.max(me.maxHeight, height);
});
}
/**
@ -148,25 +148,25 @@ function ContextMenu (items, options) {
* @private
*/
ContextMenu.prototype._getVisibleButtons = function () {
var buttons = [];
var me = this;
this.dom.items.forEach(function (item) {
buttons.push(item.button);
if (item.buttonExpand) {
buttons.push(item.buttonExpand);
var buttons = [];
var me = this;
this.dom.items.forEach(function (item) {
buttons.push(item.button);
if (item.buttonExpand) {
buttons.push(item.buttonExpand);
}
if (item.subItems && item == me.expandedItem) {
item.subItems.forEach(function (subItem) {
buttons.push(subItem.button);
if (subItem.buttonExpand) {
buttons.push(subItem.buttonExpand);
}
if (item.subItems && item == me.expandedItem) {
item.subItems.forEach(function (subItem) {
buttons.push(subItem.button);
if (subItem.buttonExpand) {
buttons.push(subItem.buttonExpand);
}
// TODO: change to fully recursive method
});
}
});
// TODO: change to fully recursive method
});
}
});
return buttons;
return buttons;
};
// currently displayed context menu, a singleton. We may only have one visible context menu
@ -177,96 +177,96 @@ ContextMenu.visibleMenu = undefined;
* @param {HTMLElement} anchor
*/
ContextMenu.prototype.show = function (anchor) {
this.hide();
this.hide();
// calculate whether the menu fits below the anchor
var windowHeight = window.innerHeight;
var anchorHeight = anchor.offsetHeight;
var menuHeight = this.maxHeight;
// calculate whether the menu fits below the anchor
var windowHeight = window.innerHeight;
var anchorHeight = anchor.offsetHeight;
var menuHeight = this.maxHeight;
// position the menu
var left = util.getAbsoluteLeft(anchor);
var top = util.getAbsoluteTop(anchor);
if (top + anchorHeight + menuHeight < windowHeight) {
// display the menu below the anchor
this.dom.menu.style.left = left + 'px';
this.dom.menu.style.top = (top + anchorHeight) + 'px';
this.dom.menu.style.bottom = '';
}
else {
// display the menu above the anchor
this.dom.menu.style.left = left + 'px';
this.dom.menu.style.top = '';
this.dom.menu.style.bottom = (windowHeight - top) + 'px';
}
// position the menu
var left = util.getAbsoluteLeft(anchor);
var top = util.getAbsoluteTop(anchor);
if (top + anchorHeight + menuHeight < windowHeight) {
// display the menu below the anchor
this.dom.menu.style.left = left + 'px';
this.dom.menu.style.top = (top + anchorHeight) + 'px';
this.dom.menu.style.bottom = '';
}
else {
// display the menu above the anchor
this.dom.menu.style.left = left + 'px';
this.dom.menu.style.top = '';
this.dom.menu.style.bottom = (windowHeight - top) + 'px';
}
// attach the menu to the document
document.body.appendChild(this.dom.menu);
// attach the menu to the document
document.body.appendChild(this.dom.menu);
// create and attach event listeners
var me = this;
var list = this.dom.list;
this.eventListeners.mousedown = util.addEventListener(
document, 'mousedown', function (event) {
// hide menu on click outside of the menu
var target = event.target;
if ((target != list) && !me._isChildOf(target, list)) {
me.hide();
event.stopPropagation();
event.preventDefault();
}
});
this.eventListeners.mousewheel = util.addEventListener(
document, 'mousewheel', function (event) {
// block scrolling when context menu is visible
event.stopPropagation();
event.preventDefault();
});
this.eventListeners.keydown = util.addEventListener(
document, 'keydown', function (event) {
me._onKeyDown(event);
});
// create and attach event listeners
var me = this;
var list = this.dom.list;
this.eventListeners.mousedown = util.addEventListener(
document, 'mousedown', function (event) {
// hide menu on click outside of the menu
var target = event.target;
if ((target != list) && !me._isChildOf(target, list)) {
me.hide();
event.stopPropagation();
event.preventDefault();
}
});
this.eventListeners.mousewheel = util.addEventListener(
document, 'mousewheel', function (event) {
// block scrolling when context menu is visible
event.stopPropagation();
event.preventDefault();
});
this.eventListeners.keydown = util.addEventListener(
document, 'keydown', function (event) {
me._onKeyDown(event);
});
// move focus to the first button in the context menu
this.selection = util.getSelection();
this.anchor = anchor;
setTimeout(function () {
me.dom.focusButton.focus();
}, 0);
// move focus to the first button in the context menu
this.selection = util.getSelection();
this.anchor = anchor;
setTimeout(function () {
me.dom.focusButton.focus();
}, 0);
if (ContextMenu.visibleMenu) {
ContextMenu.visibleMenu.hide();
}
ContextMenu.visibleMenu = this;
if (ContextMenu.visibleMenu) {
ContextMenu.visibleMenu.hide();
}
ContextMenu.visibleMenu = this;
};
/**
* Hide the context menu if visible
*/
ContextMenu.prototype.hide = function () {
// remove the menu from the DOM
if (this.dom.menu.parentNode) {
this.dom.menu.parentNode.removeChild(this.dom.menu);
if (this.onClose) {
this.onClose();
}
// remove the menu from the DOM
if (this.dom.menu.parentNode) {
this.dom.menu.parentNode.removeChild(this.dom.menu);
if (this.onClose) {
this.onClose();
}
}
// remove all event listeners
// all event listeners are supposed to be attached to document.
for (var name in this.eventListeners) {
if (this.eventListeners.hasOwnProperty(name)) {
var fn = this.eventListeners[name];
if (fn) {
util.removeEventListener(document, name, fn);
}
delete this.eventListeners[name];
}
// remove all event listeners
// all event listeners are supposed to be attached to document.
for (var name in this.eventListeners) {
if (this.eventListeners.hasOwnProperty(name)) {
var fn = this.eventListeners[name];
if (fn) {
util.removeEventListener(document, name, fn);
}
delete this.eventListeners[name];
}
}
if (ContextMenu.visibleMenu == this) {
ContextMenu.visibleMenu = undefined;
}
if (ContextMenu.visibleMenu == this) {
ContextMenu.visibleMenu = undefined;
}
};
/**
@ -276,37 +276,37 @@ ContextMenu.prototype.hide = function () {
* @private
*/
ContextMenu.prototype._onExpandItem = function (domItem) {
var me = this;
var alreadyVisible = (domItem == this.expandedItem);
var me = this;
var alreadyVisible = (domItem == this.expandedItem);
// hide the currently visible submenu
var expandedItem = this.expandedItem;
if (expandedItem) {
//var ul = expandedItem.ul;
expandedItem.ul.style.height = '0';
expandedItem.ul.style.padding = '';
setTimeout(function () {
if (me.expandedItem != expandedItem) {
expandedItem.ul.style.display = '';
util.removeClassName(expandedItem.ul.parentNode, 'selected');
}
}, 300); // timeout duration must match the css transition duration
this.expandedItem = undefined;
}
// hide the currently visible submenu
var expandedItem = this.expandedItem;
if (expandedItem) {
//var ul = expandedItem.ul;
expandedItem.ul.style.height = '0';
expandedItem.ul.style.padding = '';
setTimeout(function () {
if (me.expandedItem != expandedItem) {
expandedItem.ul.style.display = '';
util.removeClassName(expandedItem.ul.parentNode, 'selected');
}
}, 300); // timeout duration must match the css transition duration
this.expandedItem = undefined;
}
if (!alreadyVisible) {
var ul = domItem.ul;
ul.style.display = 'block';
var height = ul.clientHeight; // force a reflow in Firefox
setTimeout(function () {
if (me.expandedItem == domItem) {
ul.style.height = (ul.childNodes.length * 24) + 'px';
ul.style.padding = '5px 10px';
}
}, 0);
util.addClassName(ul.parentNode, 'selected');
this.expandedItem = domItem;
}
if (!alreadyVisible) {
var ul = domItem.ul;
ul.style.display = 'block';
var height = ul.clientHeight; // force a reflow in Firefox
setTimeout(function () {
if (me.expandedItem == domItem) {
ul.style.height = (ul.childNodes.length * 24) + 'px';
ul.style.padding = '5px 10px';
}
}, 0);
util.addClassName(ul.parentNode, 'selected');
this.expandedItem = domItem;
}
};
/**
@ -315,107 +315,107 @@ ContextMenu.prototype._onExpandItem = function (domItem) {
* @private
*/
ContextMenu.prototype._onKeyDown = function (event) {
var target = event.target;
var keynum = event.which;
var handled = false;
var buttons, targetIndex, prevButton, nextButton;
var target = event.target;
var keynum = event.which;
var handled = false;
var buttons, targetIndex, prevButton, nextButton;
if (keynum == 27) { // ESC
// hide the menu on ESC key
if (keynum == 27) { // ESC
// hide the menu on ESC key
// restore previous selection and focus
if (this.selection) {
util.setSelection(this.selection);
}
if (this.anchor) {
this.anchor.focus();
}
// restore previous selection and focus
if (this.selection) {
util.setSelection(this.selection);
}
if (this.anchor) {
this.anchor.focus();
}
this.hide();
this.hide();
handled = true;
}
else if (keynum == 9) { // Tab
if (!event.shiftKey) { // Tab
buttons = this._getVisibleButtons();
targetIndex = buttons.indexOf(target);
if (targetIndex == buttons.length - 1) {
// move to first button
buttons[0].focus();
handled = true;
}
}
else if (keynum == 9) { // Tab
if (!event.shiftKey) { // Tab
buttons = this._getVisibleButtons();
targetIndex = buttons.indexOf(target);
if (targetIndex == buttons.length - 1) {
// move to first button
buttons[0].focus();
handled = true;
}
}
else { // Shift+Tab
buttons = this._getVisibleButtons();
targetIndex = buttons.indexOf(target);
if (targetIndex == 0) {
// move to last button
buttons[buttons.length - 1].focus();
handled = true;
}
}
}
else if (keynum == 37) { // Arrow Left
if (target.className == 'expand') {
buttons = this._getVisibleButtons();
targetIndex = buttons.indexOf(target);
prevButton = buttons[targetIndex - 1];
if (prevButton) {
prevButton.focus();
}
}
else { // Shift+Tab
buttons = this._getVisibleButtons();
targetIndex = buttons.indexOf(target);
if (targetIndex == 0) {
// move to last button
buttons[buttons.length - 1].focus();
handled = true;
}
}
else if (keynum == 38) { // Arrow Up
buttons = this._getVisibleButtons();
targetIndex = buttons.indexOf(target);
prevButton = buttons[targetIndex - 1];
if (prevButton && prevButton.className == 'expand') {
// skip expand button
prevButton = buttons[targetIndex - 2];
}
if (!prevButton) {
// move to last button
prevButton = buttons[buttons.length - 1];
}
if (prevButton) {
prevButton.focus();
}
handled = true;
}
else if (keynum == 37) { // Arrow Left
if (target.className == 'expand') {
buttons = this._getVisibleButtons();
targetIndex = buttons.indexOf(target);
prevButton = buttons[targetIndex - 1];
if (prevButton) {
prevButton.focus();
}
}
else if (keynum == 39) { // Arrow Right
buttons = this._getVisibleButtons();
targetIndex = buttons.indexOf(target);
nextButton = buttons[targetIndex + 1];
if (nextButton && nextButton.className == 'expand') {
nextButton.focus();
}
handled = true;
handled = true;
}
else if (keynum == 38) { // Arrow Up
buttons = this._getVisibleButtons();
targetIndex = buttons.indexOf(target);
prevButton = buttons[targetIndex - 1];
if (prevButton && prevButton.className == 'expand') {
// skip expand button
prevButton = buttons[targetIndex - 2];
}
else if (keynum == 40) { // Arrow Down
buttons = this._getVisibleButtons();
targetIndex = buttons.indexOf(target);
nextButton = buttons[targetIndex + 1];
if (nextButton && nextButton.className == 'expand') {
// skip expand button
nextButton = buttons[targetIndex + 2];
}
if (!nextButton) {
// move to first button
nextButton = buttons[0];
}
if (nextButton) {
nextButton.focus();
handled = true;
}
handled = true;
if (!prevButton) {
// move to last button
prevButton = buttons[buttons.length - 1];
}
// TODO: arrow left and right
if (prevButton) {
prevButton.focus();
}
handled = true;
}
else if (keynum == 39) { // Arrow Right
buttons = this._getVisibleButtons();
targetIndex = buttons.indexOf(target);
nextButton = buttons[targetIndex + 1];
if (nextButton && nextButton.className == 'expand') {
nextButton.focus();
}
handled = true;
}
else if (keynum == 40) { // Arrow Down
buttons = this._getVisibleButtons();
targetIndex = buttons.indexOf(target);
nextButton = buttons[targetIndex + 1];
if (nextButton && nextButton.className == 'expand') {
// skip expand button
nextButton = buttons[targetIndex + 2];
}
if (!nextButton) {
// move to first button
nextButton = buttons[0];
}
if (nextButton) {
nextButton.focus();
handled = true;
}
handled = true;
}
// TODO: arrow left and right
if (handled) {
event.stopPropagation();
event.preventDefault();
}
if (handled) {
event.stopPropagation();
event.preventDefault();
}
};
/**
@ -425,14 +425,14 @@ ContextMenu.prototype._onKeyDown = function (event) {
* @return {boolean} isChild
*/
ContextMenu.prototype._isChildOf = function (child, parent) {
var e = child.parentNode;
while (e) {
if (e == parent) {
return true;
}
e = e.parentNode;
var e = child.parentNode;
while (e) {
if (e == parent) {
return true;
}
e = e.parentNode;
}
return false;
return false;
};

View File

@ -4,7 +4,7 @@
* @constructor Highlighter
*/
function Highlighter () {
this.locked = false;
this.locked = false;
}
/**
@ -12,23 +12,23 @@ function Highlighter () {
* @param {Node} node
*/
Highlighter.prototype.highlight = function (node) {
if (this.locked) {
return;
if (this.locked) {
return;
}
if (this.node != node) {
// unhighlight current node
if (this.node) {
this.node.setHighlight(false);
}
if (this.node != node) {
// unhighlight current node
if (this.node) {
this.node.setHighlight(false);
}
// highlight new node
this.node = node;
this.node.setHighlight(true);
}
// highlight new node
this.node = node;
this.node.setHighlight(true);
}
// cancel any current timeout
this._cancelUnhighlight();
// cancel any current timeout
this._cancelUnhighlight();
};
/**
@ -36,23 +36,23 @@ Highlighter.prototype.highlight = function (node) {
* Will be done after a delay
*/
Highlighter.prototype.unhighlight = function () {
if (this.locked) {
return;
}
if (this.locked) {
return;
}
var me = this;
if (this.node) {
this._cancelUnhighlight();
var me = this;
if (this.node) {
this._cancelUnhighlight();
// do the unhighlighting after a small delay, to prevent re-highlighting
// the same node when moving from the drag-icon to the contextmenu-icon
// or vice versa.
this.unhighlightTimer = setTimeout(function () {
me.node.setHighlight(false);
me.node = undefined;
me.unhighlightTimer = undefined;
}, 0);
}
// do the unhighlighting after a small delay, to prevent re-highlighting
// the same node when moving from the drag-icon to the contextmenu-icon
// or vice versa.
this.unhighlightTimer = setTimeout(function () {
me.node.setHighlight(false);
me.node = undefined;
me.unhighlightTimer = undefined;
}, 0);
}
};
/**
@ -60,10 +60,10 @@ Highlighter.prototype.unhighlight = function () {
* @private
*/
Highlighter.prototype._cancelUnhighlight = function () {
if (this.unhighlightTimer) {
clearTimeout(this.unhighlightTimer);
this.unhighlightTimer = undefined;
}
if (this.unhighlightTimer) {
clearTimeout(this.unhighlightTimer);
this.unhighlightTimer = undefined;
}
};
/**
@ -71,12 +71,12 @@ Highlighter.prototype._cancelUnhighlight = function () {
* methods highlight and unhighlight do not work while locked.
*/
Highlighter.prototype.lock = function () {
this.locked = true;
this.locked = true;
};
/**
* Unlock highlighting or unhighlighting nodes
*/
Highlighter.prototype.unlock = function () {
this.locked = false;
this.locked = false;
};

View File

@ -4,105 +4,105 @@
* @param {JSONEditor} editor
*/
function History (editor) {
this.editor = editor;
this.clear();
this.editor = editor;
this.clear();
// map with all supported actions
this.actions = {
'editField': {
'undo': function (params) {
params.node.updateField(params.oldValue);
},
'redo': function (params) {
params.node.updateField(params.newValue);
}
},
'editValue': {
'undo': function (params) {
params.node.updateValue(params.oldValue);
},
'redo': function (params) {
params.node.updateValue(params.newValue);
}
},
'appendNode': {
'undo': function (params) {
params.parent.removeChild(params.node);
},
'redo': function (params) {
params.parent.appendChild(params.node);
}
},
'insertBeforeNode': {
'undo': function (params) {
params.parent.removeChild(params.node);
},
'redo': function (params) {
params.parent.insertBefore(params.node, params.beforeNode);
}
},
'insertAfterNode': {
'undo': function (params) {
params.parent.removeChild(params.node);
},
'redo': function (params) {
params.parent.insertAfter(params.node, params.afterNode);
}
},
'removeNode': {
'undo': function (params) {
var parent = params.parent;
var beforeNode = parent.childs[params.index] || parent.append;
parent.insertBefore(params.node, beforeNode);
},
'redo': function (params) {
params.parent.removeChild(params.node);
}
},
'duplicateNode': {
'undo': function (params) {
params.parent.removeChild(params.clone);
},
'redo': function (params) {
params.parent.insertAfter(params.clone, params.node);
}
},
'changeType': {
'undo': function (params) {
params.node.changeType(params.oldType);
},
'redo': function (params) {
params.node.changeType(params.newType);
}
},
'moveNode': {
'undo': function (params) {
params.startParent.moveTo(params.node, params.startIndex);
},
'redo': function (params) {
params.endParent.moveTo(params.node, params.endIndex);
}
},
'sort': {
'undo': function (params) {
var node = params.node;
node.hideChilds();
node.sort = params.oldSort;
node.childs = params.oldChilds;
node.showChilds();
},
'redo': function (params) {
var node = params.node;
node.hideChilds();
node.sort = params.newSort;
node.childs = params.newChilds;
node.showChilds();
}
}
// map with all supported actions
this.actions = {
'editField': {
'undo': function (params) {
params.node.updateField(params.oldValue);
},
'redo': function (params) {
params.node.updateField(params.newValue);
}
},
'editValue': {
'undo': function (params) {
params.node.updateValue(params.oldValue);
},
'redo': function (params) {
params.node.updateValue(params.newValue);
}
},
'appendNode': {
'undo': function (params) {
params.parent.removeChild(params.node);
},
'redo': function (params) {
params.parent.appendChild(params.node);
}
},
'insertBeforeNode': {
'undo': function (params) {
params.parent.removeChild(params.node);
},
'redo': function (params) {
params.parent.insertBefore(params.node, params.beforeNode);
}
},
'insertAfterNode': {
'undo': function (params) {
params.parent.removeChild(params.node);
},
'redo': function (params) {
params.parent.insertAfter(params.node, params.afterNode);
}
},
'removeNode': {
'undo': function (params) {
var parent = params.parent;
var beforeNode = parent.childs[params.index] || parent.append;
parent.insertBefore(params.node, beforeNode);
},
'redo': function (params) {
params.parent.removeChild(params.node);
}
},
'duplicateNode': {
'undo': function (params) {
params.parent.removeChild(params.clone);
},
'redo': function (params) {
params.parent.insertAfter(params.clone, params.node);
}
},
'changeType': {
'undo': function (params) {
params.node.changeType(params.oldType);
},
'redo': function (params) {
params.node.changeType(params.newType);
}
},
'moveNode': {
'undo': function (params) {
params.startParent.moveTo(params.node, params.startIndex);
},
'redo': function (params) {
params.endParent.moveTo(params.node, params.endIndex);
}
},
'sort': {
'undo': function (params) {
var node = params.node;
node.hideChilds();
node.sort = params.oldSort;
node.childs = params.oldChilds;
node.showChilds();
},
'redo': function (params) {
var node = params.node;
node.hideChilds();
node.sort = params.newSort;
node.childs = params.newChilds;
node.showChilds();
}
}
// TODO: restore the original caret position and selection with each undo
// TODO: implement history for actions "expand", "collapse", "scroll", "setDocument"
};
// TODO: restore the original caret position and selection with each undo
// TODO: implement history for actions "expand", "collapse", "scroll", "setDocument"
};
}
/**
@ -123,31 +123,31 @@ History.prototype.onChange = function () {};
* needed to undo or redo the action.
*/
History.prototype.add = function (action, params) {
this.index++;
this.history[this.index] = {
'action': action,
'params': params,
'timestamp': new Date()
};
this.index++;
this.history[this.index] = {
'action': action,
'params': params,
'timestamp': new Date()
};
// remove redo actions which are invalid now
if (this.index < this.history.length - 1) {
this.history.splice(this.index + 1, this.history.length - this.index - 1);
}
// remove redo actions which are invalid now
if (this.index < this.history.length - 1) {
this.history.splice(this.index + 1, this.history.length - this.index - 1);
}
// fire onchange event
this.onChange();
// fire onchange event
this.onChange();
};
/**
* Clear history
*/
History.prototype.clear = function () {
this.history = [];
this.index = -1;
this.history = [];
this.index = -1;
// fire onchange event
this.onChange();
// fire onchange event
this.onChange();
};
/**
@ -155,7 +155,7 @@ History.prototype.clear = function () {
* @return {Boolean} canUndo
*/
History.prototype.canUndo = function () {
return (this.index >= 0);
return (this.index >= 0);
};
/**
@ -163,56 +163,56 @@ History.prototype.canUndo = function () {
* @return {Boolean} canRedo
*/
History.prototype.canRedo = function () {
return (this.index < this.history.length - 1);
return (this.index < this.history.length - 1);
};
/**
* Undo the last action
*/
History.prototype.undo = function () {
if (this.canUndo()) {
var obj = this.history[this.index];
if (obj) {
var action = this.actions[obj.action];
if (action && action.undo) {
action.undo(obj.params);
if (obj.params.oldSelection) {
this.editor.setSelection(obj.params.oldSelection);
}
}
else {
util.log('Error: unknown action "' + obj.action + '"');
}
if (this.canUndo()) {
var obj = this.history[this.index];
if (obj) {
var action = this.actions[obj.action];
if (action && action.undo) {
action.undo(obj.params);
if (obj.params.oldSelection) {
this.editor.setSelection(obj.params.oldSelection);
}
this.index--;
// fire onchange event
this.onChange();
}
else {
util.log('Error: unknown action "' + obj.action + '"');
}
}
this.index--;
// fire onchange event
this.onChange();
}
};
/**
* Redo the last action
*/
History.prototype.redo = function () {
if (this.canRedo()) {
this.index++;
if (this.canRedo()) {
this.index++;
var obj = this.history[this.index];
if (obj) {
var action = this.actions[obj.action];
if (action && action.redo) {
action.redo(obj.params);
if (obj.params.newSelection) {
this.editor.setSelection(obj.params.newSelection);
}
}
else {
util.log('Error: unknown action "' + obj.action + '"');
}
var obj = this.history[this.index];
if (obj) {
var action = this.actions[obj.action];
if (action && action.redo) {
action.redo(obj.params);
if (obj.params.newSelection) {
this.editor.setSelection(obj.params.newSelection);
}
// fire onchange event
this.onChange();
}
else {
util.log('Error: unknown action "' + obj.action + '"');
}
}
// fire onchange event
this.onChange();
}
};

View File

@ -25,20 +25,20 @@
* @param {Object | undefined} json JSON object
*/
function JSONEditor (container, options, json) {
if (!(this instanceof JSONEditor)) {
throw new Error('JSONEditor constructor called without "new".');
}
if (!(this instanceof JSONEditor)) {
throw new Error('JSONEditor constructor called without "new".');
}
// check for unsupported browser (IE8 and older)
var ieVersion = util.getInternetExplorerVersion();
if (ieVersion != -1 && ieVersion < 9) {
throw new Error('Unsupported browser, IE9 or newer required. ' +
'Please install the newest version of your browser.');
}
// check for unsupported browser (IE8 and older)
var ieVersion = util.getInternetExplorerVersion();
if (ieVersion != -1 && ieVersion < 9) {
throw new Error('Unsupported browser, IE9 or newer required. ' +
'Please install the newest version of your browser.');
}
if (arguments.length) {
this._create(container, options, json);
}
if (arguments.length) {
this._create(container, options, json);
}
}
/**
@ -66,12 +66,12 @@ JSONEditor.modes = {};
* @private
*/
JSONEditor.prototype._create = function (container, options, json) {
this.container = container;
this.options = options || {};
this.json = json || {};
this.container = container;
this.options = options || {};
this.json = json || {};
var mode = this.options.mode || 'tree';
this.setMode(mode);
var mode = this.options.mode || 'tree';
this.setMode(mode);
};
/**
@ -85,7 +85,7 @@ JSONEditor.prototype._delete = function () {};
* @param {Object | undefined} json JSON data
*/
JSONEditor.prototype.set = function (json) {
this.json = json;
this.json = json;
};
/**
@ -93,7 +93,7 @@ JSONEditor.prototype.set = function (json) {
* @returns {Object} json
*/
JSONEditor.prototype.get = function () {
return this.json;
return this.json;
};
/**
@ -101,7 +101,7 @@ JSONEditor.prototype.get = function () {
* @param {String | undefined} jsonText
*/
JSONEditor.prototype.setText = function (jsonText) {
this.json = util.parse(jsonText);
this.json = util.parse(jsonText);
};
/**
@ -109,7 +109,7 @@ JSONEditor.prototype.setText = function (jsonText) {
* @returns {String} jsonText
*/
JSONEditor.prototype.getText = function () {
return JSON.stringify(this.json);
return JSON.stringify(this.json);
};
/**
@ -117,10 +117,10 @@ JSONEditor.prototype.getText = function () {
* @param {String | undefined} name
*/
JSONEditor.prototype.setName = function (name) {
if (!this.options) {
this.options = {};
}
this.options.name = name;
if (!this.options) {
this.options = {};
}
this.options.name = name;
};
/**
@ -128,7 +128,7 @@ JSONEditor.prototype.setName = function (name) {
* @return {String | undefined} name
*/
JSONEditor.prototype.getName = function () {
return this.options && this.options.name;
return this.options && this.options.name;
};
/**
@ -138,56 +138,56 @@ JSONEditor.prototype.getName = function () {
* 'text', and 'code'.
*/
JSONEditor.prototype.setMode = function (mode) {
var container = this.container,
options = util.extend({}, this.options),
data,
name;
var container = this.container,
options = util.extend({}, this.options),
data,
name;
options.mode = mode;
var config = JSONEditor.modes[mode];
if (config) {
options.mode = mode;
var config = JSONEditor.modes[mode];
if (config) {
try {
if (config.data == 'text') {
// text
name = this.getName();
data = this.getText();
this._delete();
util.clear(this);
util.extend(this, config.editor.prototype);
this._create(container, options);
this.setName(name);
this.setText(data);
}
else {
// json
name = this.getName();
data = this.get();
this._delete();
util.clear(this);
util.extend(this, config.editor.prototype);
this._create(container, options);
this.setName(name);
this.set(data);
}
if (typeof config.load === 'function') {
try {
if (config.data == 'text') {
// text
name = this.getName();
data = this.getText();
this._delete();
util.clear(this);
util.extend(this, config.editor.prototype);
this._create(container, options);
this.setName(name);
this.setText(data);
}
else {
// json
name = this.getName();
data = this.get();
this._delete();
util.clear(this);
util.extend(this, config.editor.prototype);
this._create(container, options);
this.setName(name);
this.set(data);
}
if (typeof config.load === 'function') {
try {
config.load.call(this);
}
catch (err) {}
}
}
catch (err) {
this._onError(err);
config.load.call(this);
}
catch (err) {}
}
}
else {
throw new Error('Unknown mode "' + options.mode + '"');
catch (err) {
this._onError(err);
}
}
else {
throw new Error('Unknown mode "' + options.mode + '"');
}
};
/**
@ -197,17 +197,17 @@ JSONEditor.prototype.setMode = function (mode) {
* @private
*/
JSONEditor.prototype._onError = function(err) {
// TODO: onError is deprecated since version 2.2.0. cleanup some day
if (typeof this.onError === 'function') {
util.log('WARNING: JSONEditor.onError is deprecated. ' +
'Use options.error instead.');
this.onError(err);
}
// TODO: onError is deprecated since version 2.2.0. cleanup some day
if (typeof this.onError === 'function') {
util.log('WARNING: JSONEditor.onError is deprecated. ' +
'Use options.error instead.');
this.onError(err);
}
if (this.options && typeof this.options.error === 'function') {
this.options.error(err);
}
else {
throw err;
}
if (this.options && typeof this.options.error === 'function') {
this.options.error(err);
}
else {
throw err;
}
};

View File

@ -6,89 +6,89 @@
* @returns {HTMLElement} box
*/
function createModeBox(editor, modes, current) {
/**
* Switch the mode of the editor
* @param {String} mode
*/
function switchMode(mode) {
// switch mode
editor.setMode(mode);
/**
* Switch the mode of the editor
* @param {String} mode
*/
function switchMode(mode) {
// switch mode
editor.setMode(mode);
// restore focus on mode box
var modeBox = editor.dom && editor.dom.modeBox;
if (modeBox) {
modeBox.focus();
}
// restore focus on mode box
var modeBox = editor.dom && editor.dom.modeBox;
if (modeBox) {
modeBox.focus();
}
}
// available modes
var availableModes = {
code: {
'text': 'Code',
'title': 'Switch to code highlighter',
'click': function () {
switchMode('code')
}
},
form: {
'text': 'Form',
'title': 'Switch to form editor',
'click': function () {
switchMode('form');
}
},
text: {
'text': 'Text',
'title': 'Switch to plain text editor',
'click': function () {
switchMode('text');
}
},
tree: {
'text': 'Tree',
'title': 'Switch to tree editor',
'click': function () {
switchMode('tree');
}
},
view: {
'text': 'View',
'title': 'Switch to tree view',
'click': function () {
switchMode('view');
}
}
};
// list the selected modes
var items = [];
for (var i = 0; i < modes.length; i++) {
var mode = modes[i];
var item = availableModes[mode];
if (!item) {
throw new Error('Unknown mode "' + mode + '"');
}
// available modes
var availableModes = {
code: {
'text': 'Code',
'title': 'Switch to code highlighter',
'click': function () {
switchMode('code')
}
},
form: {
'text': 'Form',
'title': 'Switch to form editor',
'click': function () {
switchMode('form');
}
},
text: {
'text': 'Text',
'title': 'Switch to plain text editor',
'click': function () {
switchMode('text');
}
},
tree: {
'text': 'Tree',
'title': 'Switch to tree editor',
'click': function () {
switchMode('tree');
}
},
view: {
'text': 'View',
'title': 'Switch to tree view',
'click': function () {
switchMode('view');
}
}
};
item.className = 'type-modes' + ((current == mode) ? ' selected' : '');
items.push(item);
}
// list the selected modes
var items = [];
for (var i = 0; i < modes.length; i++) {
var mode = modes[i];
var item = availableModes[mode];
if (!item) {
throw new Error('Unknown mode "' + mode + '"');
}
// retrieve the title of current mode
var currentMode = availableModes[current];
if (!currentMode) {
throw new Error('Unknown mode "' + current + '"');
}
var currentTitle = currentMode.text;
item.className = 'type-modes' + ((current == mode) ? ' selected' : '');
items.push(item);
}
// create the html element
var box = document.createElement('button');
box.className = 'modes separator';
box.innerHTML = currentTitle + ' &#x25BE;';
box.title = 'Switch editor mode';
box.onclick = function () {
var menu = new ContextMenu(items);
menu.show(box);
};
// retrieve the title of current mode
var currentMode = availableModes[current];
if (!currentMode) {
throw new Error('Unknown mode "' + current + '"');
}
var currentTitle = currentMode.text;
// create the html element
var box = document.createElement('button');
box.className = 'modes separator';
box.innerHTML = currentTitle + ' &#x25BE;';
box.title = 'Switch editor mode';
box.onclick = function () {
var menu = new ContextMenu(items);
menu.show(box);
};
return box;
return box;
}

View File

@ -1,58 +1,58 @@
// module exports
var jsoneditor = {
'JSONEditor': JSONEditor,
'JSONFormatter': function () {
throw new Error('JSONFormatter is deprecated. ' +
'Use JSONEditor with mode "text" or "code" instead');
},
'util': util
'JSONEditor': JSONEditor,
'JSONFormatter': function () {
throw new Error('JSONFormatter is deprecated. ' +
'Use JSONEditor with mode "text" or "code" instead');
},
'util': util
};
/**
* load jsoneditor.css
*/
var loadCss = function () {
// find the script named 'jsoneditor.js' or 'jsoneditor-min.js' or
// 'jsoneditor.min.js', and use its path to find the css file to be
// loaded.
var scripts = document.getElementsByTagName('script');
for (var s = 0; s < scripts.length; s++) {
var src = scripts[s].src;
if (/(^|\/)jsoneditor([-\.]min)?.js$/.test(src)) {
var jsFile = src.split('?')[0];
var cssFile = jsFile.substring(0, jsFile.length - 2) + 'css';
// find the script named 'jsoneditor.js' or 'jsoneditor-min.js' or
// 'jsoneditor.min.js', and use its path to find the css file to be
// loaded.
var scripts = document.getElementsByTagName('script');
for (var s = 0; s < scripts.length; s++) {
var src = scripts[s].src;
if (/(^|\/)jsoneditor([-\.]min)?.js$/.test(src)) {
var jsFile = src.split('?')[0];
var cssFile = jsFile.substring(0, jsFile.length - 2) + 'css';
// load css file
var link = document.createElement('link');
link.type = 'text/css';
link.rel = 'stylesheet';
link.href = cssFile;
document.getElementsByTagName('head')[0].appendChild(link);
// load css file
var link = document.createElement('link');
link.type = 'text/css';
link.rel = 'stylesheet';
link.href = cssFile;
document.getElementsByTagName('head')[0].appendChild(link);
break;
}
break;
}
}
};
/**
* CommonJS module exports
*/
if (typeof(module) != 'undefined' && typeof(exports) != 'undefined') {
loadCss();
module.exports = exports = jsoneditor;
loadCss();
module.exports = exports = jsoneditor;
}
/**
* AMD module exports
*/
if (typeof(require) != 'undefined' && typeof(define) != 'undefined') {
loadCss();
define(function () {
return jsoneditor;
});
loadCss();
define(function () {
return jsoneditor;
});
}
else {
// attach the module to the window, load as a regular javascript file
window['jsoneditor'] = jsoneditor;
// attach the module to the window, load as a regular javascript file
window['jsoneditor'] = jsoneditor;
}

File diff suppressed because it is too large Load Diff

View File

@ -6,97 +6,97 @@
* create the search box
*/
function SearchBox (editor, container) {
var searchBox = this;
var searchBox = this;
this.editor = editor;
this.timeout = undefined;
this.delay = 200; // ms
this.lastText = undefined;
this.editor = editor;
this.timeout = undefined;
this.delay = 200; // ms
this.lastText = undefined;
this.dom = {};
this.dom.container = container;
this.dom = {};
this.dom.container = container;
var table = document.createElement('table');
this.dom.table = table;
table.className = 'search';
container.appendChild(table);
var tbody = document.createElement('tbody');
this.dom.tbody = tbody;
table.appendChild(tbody);
var tr = document.createElement('tr');
tbody.appendChild(tr);
var table = document.createElement('table');
this.dom.table = table;
table.className = 'search';
container.appendChild(table);
var tbody = document.createElement('tbody');
this.dom.tbody = tbody;
table.appendChild(tbody);
var tr = document.createElement('tr');
tbody.appendChild(tr);
var td = document.createElement('td');
tr.appendChild(td);
var results = document.createElement('div');
this.dom.results = results;
results.className = 'results';
td.appendChild(results);
var td = document.createElement('td');
tr.appendChild(td);
var results = document.createElement('div');
this.dom.results = results;
results.className = 'results';
td.appendChild(results);
td = document.createElement('td');
tr.appendChild(td);
var divInput = document.createElement('div');
this.dom.input = divInput;
divInput.className = 'frame';
divInput.title = 'Search fields and values';
td.appendChild(divInput);
td = document.createElement('td');
tr.appendChild(td);
var divInput = document.createElement('div');
this.dom.input = divInput;
divInput.className = 'frame';
divInput.title = 'Search fields and values';
td.appendChild(divInput);
// table to contain the text input and search button
var tableInput = document.createElement('table');
divInput.appendChild(tableInput);
var tbodySearch = document.createElement('tbody');
tableInput.appendChild(tbodySearch);
tr = document.createElement('tr');
tbodySearch.appendChild(tr);
// table to contain the text input and search button
var tableInput = document.createElement('table');
divInput.appendChild(tableInput);
var tbodySearch = document.createElement('tbody');
tableInput.appendChild(tbodySearch);
tr = document.createElement('tr');
tbodySearch.appendChild(tr);
var refreshSearch = document.createElement('button');
refreshSearch.className = 'refresh';
td = document.createElement('td');
td.appendChild(refreshSearch);
tr.appendChild(td);
var refreshSearch = document.createElement('button');
refreshSearch.className = 'refresh';
td = document.createElement('td');
td.appendChild(refreshSearch);
tr.appendChild(td);
var search = document.createElement('input');
this.dom.search = search;
search.oninput = function (event) {
searchBox._onDelayedSearch(event);
};
search.onchange = function (event) { // For IE 9
searchBox._onSearch(event);
};
search.onkeydown = function (event) {
searchBox._onKeyDown(event);
};
search.onkeyup = function (event) {
searchBox._onKeyUp(event);
};
refreshSearch.onclick = function (event) {
search.select();
};
var search = document.createElement('input');
this.dom.search = search;
search.oninput = function (event) {
searchBox._onDelayedSearch(event);
};
search.onchange = function (event) { // For IE 9
searchBox._onSearch(event);
};
search.onkeydown = function (event) {
searchBox._onKeyDown(event);
};
search.onkeyup = function (event) {
searchBox._onKeyUp(event);
};
refreshSearch.onclick = function (event) {
search.select();
};
// TODO: ESC in FF restores the last input, is a FF bug, https://bugzilla.mozilla.org/show_bug.cgi?id=598819
td = document.createElement('td');
td.appendChild(search);
tr.appendChild(td);
// TODO: ESC in FF restores the last input, is a FF bug, https://bugzilla.mozilla.org/show_bug.cgi?id=598819
td = document.createElement('td');
td.appendChild(search);
tr.appendChild(td);
var searchNext = document.createElement('button');
searchNext.title = 'Next result (Enter)';
searchNext.className = 'next';
searchNext.onclick = function () {
searchBox.next();
};
td = document.createElement('td');
td.appendChild(searchNext);
tr.appendChild(td);
var searchNext = document.createElement('button');
searchNext.title = 'Next result (Enter)';
searchNext.className = 'next';
searchNext.onclick = function () {
searchBox.next();
};
td = document.createElement('td');
td.appendChild(searchNext);
tr.appendChild(td);
var searchPrevious = document.createElement('button');
searchPrevious.title = 'Previous result (Shift+Enter)';
searchPrevious.className = 'previous';
searchPrevious.onclick = function () {
searchBox.previous();
};
td = document.createElement('td');
td.appendChild(searchPrevious);
tr.appendChild(td);
var searchPrevious = document.createElement('button');
searchPrevious.title = 'Previous result (Shift+Enter)';
searchPrevious.className = 'previous';
searchPrevious.onclick = function () {
searchBox.previous();
};
td = document.createElement('td');
td.appendChild(searchPrevious);
tr.appendChild(td);
}
/**
@ -105,13 +105,13 @@ function SearchBox (editor, container) {
* focus is false by default.
*/
SearchBox.prototype.next = function(focus) {
if (this.results != undefined) {
var index = (this.resultIndex != undefined) ? this.resultIndex + 1 : 0;
if (index > this.results.length - 1) {
index = 0;
}
this._setActiveResult(index, focus);
if (this.results != undefined) {
var index = (this.resultIndex != undefined) ? this.resultIndex + 1 : 0;
if (index > this.results.length - 1) {
index = 0;
}
this._setActiveResult(index, focus);
}
};
/**
@ -120,14 +120,14 @@ SearchBox.prototype.next = function(focus) {
* focus is false by default.
*/
SearchBox.prototype.previous = function(focus) {
if (this.results != undefined) {
var max = this.results.length - 1;
var index = (this.resultIndex != undefined) ? this.resultIndex - 1 : max;
if (index < 0) {
index = max;
}
this._setActiveResult(index, focus);
if (this.results != undefined) {
var max = this.results.length - 1;
var index = (this.resultIndex != undefined) ? this.resultIndex - 1 : max;
if (index < 0) {
index = max;
}
this._setActiveResult(index, focus);
}
};
/**
@ -138,46 +138,46 @@ SearchBox.prototype.previous = function(focus) {
* @private
*/
SearchBox.prototype._setActiveResult = function(index, focus) {
// de-activate current active result
if (this.activeResult) {
var prevNode = this.activeResult.node;
var prevElem = this.activeResult.elem;
if (prevElem == 'field') {
delete prevNode.searchFieldActive;
}
else {
delete prevNode.searchValueActive;
}
prevNode.updateDom();
}
if (!this.results || !this.results[index]) {
// out of range, set to undefined
this.resultIndex = undefined;
this.activeResult = undefined;
return;
}
this.resultIndex = index;
// set new node active
var node = this.results[this.resultIndex].node;
var elem = this.results[this.resultIndex].elem;
if (elem == 'field') {
node.searchFieldActive = true;
// de-activate current active result
if (this.activeResult) {
var prevNode = this.activeResult.node;
var prevElem = this.activeResult.elem;
if (prevElem == 'field') {
delete prevNode.searchFieldActive;
}
else {
node.searchValueActive = true;
delete prevNode.searchValueActive;
}
this.activeResult = this.results[this.resultIndex];
node.updateDom();
prevNode.updateDom();
}
// TODO: not so nice that the focus is only set after the animation is finished
node.scrollTo(function () {
if (focus) {
node.focus(elem);
}
});
if (!this.results || !this.results[index]) {
// out of range, set to undefined
this.resultIndex = undefined;
this.activeResult = undefined;
return;
}
this.resultIndex = index;
// set new node active
var node = this.results[this.resultIndex].node;
var elem = this.results[this.resultIndex].elem;
if (elem == 'field') {
node.searchFieldActive = true;
}
else {
node.searchValueActive = true;
}
this.activeResult = this.results[this.resultIndex];
node.updateDom();
// TODO: not so nice that the focus is only set after the animation is finished
node.scrollTo(function () {
if (focus) {
node.focus(elem);
}
});
};
/**
@ -185,10 +185,10 @@ SearchBox.prototype._setActiveResult = function(index, focus) {
* @private
*/
SearchBox.prototype._clearDelay = function() {
if (this.timeout != undefined) {
clearTimeout(this.timeout);
delete this.timeout;
}
if (this.timeout != undefined) {
clearTimeout(this.timeout);
delete this.timeout;
}
};
/**
@ -198,14 +198,14 @@ SearchBox.prototype._clearDelay = function() {
* @private
*/
SearchBox.prototype._onDelayedSearch = function (event) {
// execute the search after a short delay (reduces the number of
// search actions while typing in the search text box)
this._clearDelay();
var searchBox = this;
this.timeout = setTimeout(function (event) {
searchBox._onSearch(event);
},
this.delay);
// execute the search after a short delay (reduces the number of
// search actions while typing in the search text box)
this._clearDelay();
var searchBox = this;
this.timeout = setTimeout(function (event) {
searchBox._onSearch(event);
},
this.delay);
};
/**
@ -217,29 +217,29 @@ SearchBox.prototype._onDelayedSearch = function (event) {
* @private
*/
SearchBox.prototype._onSearch = function (event, forceSearch) {
this._clearDelay();
this._clearDelay();
var value = this.dom.search.value;
var text = (value.length > 0) ? value : undefined;
if (text != this.lastText || forceSearch) {
// only search again when changed
this.lastText = text;
this.results = this.editor.search(text);
this._setActiveResult(undefined);
var value = this.dom.search.value;
var text = (value.length > 0) ? value : undefined;
if (text != this.lastText || forceSearch) {
// only search again when changed
this.lastText = text;
this.results = this.editor.search(text);
this._setActiveResult(undefined);
// display search results
if (text != undefined) {
var resultCount = this.results.length;
switch (resultCount) {
case 0: this.dom.results.innerHTML = 'no&nbsp;results'; break;
case 1: this.dom.results.innerHTML = '1&nbsp;result'; break;
default: this.dom.results.innerHTML = resultCount + '&nbsp;results'; break;
}
}
else {
this.dom.results.innerHTML = '';
}
// display search results
if (text != undefined) {
var resultCount = this.results.length;
switch (resultCount) {
case 0: this.dom.results.innerHTML = 'no&nbsp;results'; break;
case 1: this.dom.results.innerHTML = '1&nbsp;result'; break;
default: this.dom.results.innerHTML = resultCount + '&nbsp;results'; break;
}
}
else {
this.dom.results.innerHTML = '';
}
}
};
/**
@ -248,29 +248,29 @@ SearchBox.prototype._onSearch = function (event, forceSearch) {
* @private
*/
SearchBox.prototype._onKeyDown = function (event) {
var keynum = event.which;
if (keynum == 27) { // ESC
this.dom.search.value = ''; // clear search
this._onSearch(event);
event.preventDefault();
event.stopPropagation();
var keynum = event.which;
if (keynum == 27) { // ESC
this.dom.search.value = ''; // clear search
this._onSearch(event);
event.preventDefault();
event.stopPropagation();
}
else if (keynum == 13) { // Enter
if (event.ctrlKey) {
// force to search again
this._onSearch(event, true);
}
else if (keynum == 13) { // Enter
if (event.ctrlKey) {
// force to search again
this._onSearch(event, true);
}
else if (event.shiftKey) {
// move to the previous search result
this.previous();
}
else {
// move to the next search result
this.next();
}
event.preventDefault();
event.stopPropagation();
else if (event.shiftKey) {
// move to the previous search result
this.previous();
}
else {
// move to the next search result
this.next();
}
event.preventDefault();
event.stopPropagation();
}
};
/**
@ -279,8 +279,8 @@ SearchBox.prototype._onKeyDown = function (event) {
* @private
*/
SearchBox.prototype._onKeyUp = function (event) {
var keynum = event.keyCode;
if (keynum != 27 && keynum != 13) { // !show and !Enter
this._onDelayedSearch(event); // For IE 9
}
var keynum = event.keyCode;
if (keynum != 27 && keynum != 13) { // !show and !Enter
this._onDelayedSearch(event); // For IE 9
}
};

View File

@ -13,11 +13,11 @@
* @param {JSON | String} [json] initial contents of the formatter
*/
function TextEditor(container, options, json) {
if (!(this instanceof TextEditor)) {
throw new Error('TextEditor constructor called without "new".');
}
if (!(this instanceof TextEditor)) {
throw new Error('TextEditor constructor called without "new".');
}
this._create(container, options, json);
this._create(container, options, json);
}
/**
@ -29,153 +29,153 @@ function TextEditor(container, options, json) {
* @private
*/
TextEditor.prototype._create = function (container, options, json) {
// read options
options = options || {};
this.options = options;
if (options.indentation) {
this.indentation = Number(options.indentation);
// read options
options = options || {};
this.options = options;
if (options.indentation) {
this.indentation = Number(options.indentation);
}
else {
this.indentation = 2; // number of spaces
}
this.mode = (options.mode == 'code') ? 'code' : 'text';
if (this.mode == 'code') {
// verify whether Ace editor is available and supported
if (typeof ace === 'undefined') {
this.mode = 'text';
util.log('WARNING: Cannot load code editor, Ace library not loaded. ' +
'Falling back to plain text editor');
}
else {
this.indentation = 4; // number of spaces
}
var me = this;
this.container = container;
this.dom = {};
this.editor = undefined; // ace code editor
this.textarea = undefined; // plain text editor (fallback when Ace is not available)
this.width = container.clientWidth;
this.height = container.clientHeight;
this.frame = document.createElement('div');
this.frame.className = 'jsoneditor';
this.frame.onclick = function (event) {
// prevent default submit action when TextEditor is located inside a form
event.preventDefault();
};
// create menu
this.menu = document.createElement('div');
this.menu.className = 'menu';
this.frame.appendChild(this.menu);
// create format button
var buttonFormat = document.createElement('button');
buttonFormat.className = 'format';
buttonFormat.title = 'Format JSON data, with proper indentation and line feeds';
this.menu.appendChild(buttonFormat);
buttonFormat.onclick = function () {
try {
me.format();
}
this.mode = (options.mode == 'code') ? 'code' : 'text';
if (this.mode == 'code') {
// verify whether Ace editor is available and supported
if (typeof ace === 'undefined') {
this.mode = 'text';
util.log('WARNING: Cannot load code editor, Ace library not loaded. ' +
'Falling back to plain text editor');
}
catch (err) {
me._onError(err);
}
};
var me = this;
this.container = container;
this.dom = {};
this.editor = undefined; // ace code editor
this.textarea = undefined; // plain text editor (fallback when Ace is not available)
// create compact button
var buttonCompact = document.createElement('button');
buttonCompact.className = 'compact';
buttonCompact.title = 'Compact JSON data, remove all whitespaces';
this.menu.appendChild(buttonCompact);
buttonCompact.onclick = function () {
try {
me.compact();
}
catch (err) {
me._onError(err);
}
};
this.width = container.clientWidth;
this.height = container.clientHeight;
// create mode box
if (this.options && this.options.modes && this.options.modes.length) {
var modeBox = createModeBox(this, this.options.modes, this.options.mode);
this.menu.appendChild(modeBox);
this.dom.modeBox = modeBox;
}
this.frame = document.createElement('div');
this.frame.className = 'jsoneditor';
this.frame.onclick = function (event) {
// prevent default submit action when TextEditor is located inside a form
event.preventDefault();
this.content = document.createElement('div');
this.content.className = 'outer';
this.frame.appendChild(this.content);
this.container.appendChild(this.frame);
if (this.mode == 'code') {
this.editorDom = document.createElement('div');
this.editorDom.style.height = '100%'; // TODO: move to css
this.editorDom.style.width = '100%'; // TODO: move to css
this.content.appendChild(this.editorDom);
var editor = ace.edit(this.editorDom);
editor.setTheme('ace/theme/jsoneditor');
editor.setShowPrintMargin(false);
editor.setFontSize(13);
editor.getSession().setMode('ace/mode/json');
editor.getSession().setUseSoftTabs(true);
editor.getSession().setUseWrapMode(true);
this.editor = editor;
var poweredBy = document.createElement('a');
poweredBy.appendChild(document.createTextNode('powered by ace'));
poweredBy.href = 'http://ace.ajax.org';
poweredBy.target = '_blank';
poweredBy.className = 'poweredBy';
poweredBy.onclick = function () {
// TODO: this anchor falls below the margin of the content,
// therefore the normal a.href does not work. We use a click event
// for now, but this should be fixed.
window.open(poweredBy.href, poweredBy.target);
};
this.menu.appendChild(poweredBy);
// create menu
this.menu = document.createElement('div');
this.menu.className = 'menu';
this.frame.appendChild(this.menu);
// create format button
var buttonFormat = document.createElement('button');
buttonFormat.className = 'format';
buttonFormat.title = 'Format JSON data, with proper indentation and line feeds';
this.menu.appendChild(buttonFormat);
buttonFormat.onclick = function () {
try {
me.format();
}
catch (err) {
me._onError(err);
}
};
// create compact button
var buttonCompact = document.createElement('button');
buttonCompact.className = 'compact';
buttonCompact.title = 'Compact JSON data, remove all whitespaces';
this.menu.appendChild(buttonCompact);
buttonCompact.onclick = function () {
try {
me.compact();
}
catch (err) {
me._onError(err);
}
};
// create mode box
if (this.options && this.options.modes && this.options.modes.length) {
var modeBox = createModeBox(this, this.options.modes, this.options.mode);
this.menu.appendChild(modeBox);
this.dom.modeBox = modeBox;
if (options.change) {
// register onchange event
editor.on('change', function () {
options.change();
});
}
}
else {
// load a plain text textarea
var textarea = document.createElement('textarea');
textarea.className = 'text';
textarea.spellcheck = false;
this.content.appendChild(textarea);
this.textarea = textarea;
this.content = document.createElement('div');
this.content.className = 'outer';
this.frame.appendChild(this.content);
this.container.appendChild(this.frame);
if (this.mode == 'code') {
this.editorDom = document.createElement('div');
this.editorDom.style.height = '100%'; // TODO: move to css
this.editorDom.style.width = '100%'; // TODO: move to css
this.content.appendChild(this.editorDom);
var editor = ace.edit(this.editorDom);
editor.setTheme('ace/theme/jsoneditor');
editor.setShowPrintMargin(false);
editor.setFontSize(13);
editor.getSession().setMode('ace/mode/json');
editor.getSession().setUseSoftTabs(true);
editor.getSession().setUseWrapMode(true);
this.editor = editor;
var poweredBy = document.createElement('a');
poweredBy.appendChild(document.createTextNode('powered by ace'));
poweredBy.href = 'http://ace.ajax.org';
poweredBy.target = '_blank';
poweredBy.className = 'poweredBy';
poweredBy.onclick = function () {
// TODO: this anchor falls below the margin of the content,
// therefore the normal a.href does not work. We use a click event
// for now, but this should be fixed.
window.open(poweredBy.href, poweredBy.target);
};
this.menu.appendChild(poweredBy);
if (options.change) {
// register onchange event
editor.on('change', function () {
options.change();
});
if (options.change) {
// register onchange event
if (this.textarea.oninput === null) {
this.textarea.oninput = function () {
options.change();
}
}
else {
// load a plain text textarea
var textarea = document.createElement('textarea');
textarea.className = 'text';
textarea.spellcheck = false;
this.content.appendChild(textarea);
this.textarea = textarea;
if (options.change) {
// register onchange event
if (this.textarea.oninput === null) {
this.textarea.oninput = function () {
options.change();
}
}
else {
// oninput is undefined. For IE8-
this.textarea.onchange = function () {
options.change();
}
}
}
else {
// oninput is undefined. For IE8-
this.textarea.onchange = function () {
options.change();
}
}
}
}
// load initial json object or string
if (typeof(json) == 'string') {
this.setText(json);
}
else {
this.set(json);
}
// load initial json object or string
if (typeof(json) == 'string') {
this.setText(json);
}
else {
this.set(json);
}
};
/**
@ -183,9 +183,9 @@ TextEditor.prototype._create = function (container, options, json) {
* @private
*/
TextEditor.prototype._delete = function () {
if (this.frame && this.container && this.frame.parentNode == this.container) {
this.container.removeChild(this.frame);
}
if (this.frame && this.container && this.frame.parentNode == this.container) {
this.container.removeChild(this.frame);
}
};
/**
@ -195,57 +195,57 @@ TextEditor.prototype._delete = function () {
* @private
*/
TextEditor.prototype._onError = function(err) {
// TODO: onError is deprecated since version 2.2.0. cleanup some day
if (typeof this.onError === 'function') {
util.log('WARNING: JSONEditor.onError is deprecated. ' +
'Use options.error instead.');
this.onError(err);
}
// TODO: onError is deprecated since version 2.2.0. cleanup some day
if (typeof this.onError === 'function') {
util.log('WARNING: JSONEditor.onError is deprecated. ' +
'Use options.error instead.');
this.onError(err);
}
if (this.options && typeof this.options.error === 'function') {
this.options.error(err);
}
else {
throw err;
}
if (this.options && typeof this.options.error === 'function') {
this.options.error(err);
}
else {
throw err;
}
};
/**
* Compact the code in the formatter
*/
TextEditor.prototype.compact = function () {
var json = util.parse(this.getText());
this.setText(JSON.stringify(json));
var json = util.parse(this.getText());
this.setText(JSON.stringify(json));
};
/**
* Format the code in the formatter
*/
TextEditor.prototype.format = function () {
var json = util.parse(this.getText());
this.setText(JSON.stringify(json, null, this.indentation));
var json = util.parse(this.getText());
this.setText(JSON.stringify(json, null, this.indentation));
};
/**
* Set focus to the formatter
*/
TextEditor.prototype.focus = function () {
if (this.textarea) {
this.textarea.focus();
}
if (this.editor) {
this.editor.focus();
}
if (this.textarea) {
this.textarea.focus();
}
if (this.editor) {
this.editor.focus();
}
};
/**
* Resize the formatter
*/
TextEditor.prototype.resize = function () {
if (this.editor) {
var force = false;
this.editor.resize(force);
}
if (this.editor) {
var force = false;
this.editor.resize(force);
}
};
/**
@ -253,7 +253,7 @@ TextEditor.prototype.resize = function () {
* @param {Object} json
*/
TextEditor.prototype.set = function(json) {
this.setText(JSON.stringify(json, null, this.indentation));
this.setText(JSON.stringify(json, null, this.indentation));
};
/**
@ -261,7 +261,7 @@ TextEditor.prototype.set = function(json) {
* @return {Object} json
*/
TextEditor.prototype.get = function() {
return util.parse(this.getText());
return util.parse(this.getText());
};
/**
@ -269,13 +269,13 @@ TextEditor.prototype.get = function() {
* @return {String} jsonText
*/
TextEditor.prototype.getText = function() {
if (this.textarea) {
return this.textarea.value;
}
if (this.editor) {
return this.editor.getValue();
}
return '';
if (this.textarea) {
return this.textarea.value;
}
if (this.editor) {
return this.editor.getValue();
}
return '';
};
/**
@ -283,22 +283,22 @@ TextEditor.prototype.getText = function() {
* @param {String} jsonText
*/
TextEditor.prototype.setText = function(jsonText) {
if (this.textarea) {
this.textarea.value = jsonText;
}
if (this.editor) {
this.editor.setValue(jsonText, -1);
}
if (this.textarea) {
this.textarea.value = jsonText;
}
if (this.editor) {
this.editor.setValue(jsonText, -1);
}
};
// register modes at the JSONEditor
JSONEditor.modes.text = {
editor: TextEditor,
data: 'text',
load: TextEditor.prototype.format
editor: TextEditor,
data: 'text',
load: TextEditor.prototype.format
};
JSONEditor.modes.code = {
editor: TextEditor,
data: 'text',
load: TextEditor.prototype.format
editor: TextEditor,
data: 'text',
load: TextEditor.prototype.format
};

File diff suppressed because it is too large Load Diff

View File

@ -7,14 +7,14 @@ util = {};
* @param {String} jsonString
*/
util.parse = function parse(jsonString) {
try {
return JSON.parse(jsonString);
}
catch (err) {
// try to throw a more detailed error message using validate
util.validate(jsonString);
throw err;
}
try {
return JSON.parse(jsonString);
}
catch (err) {
// try to throw a more detailed error message using validate
util.validate(jsonString);
throw err;
}
};
/**
@ -25,12 +25,12 @@ util.parse = function parse(jsonString) {
* @throws Error
*/
util.validate = function validate(jsonString) {
if (typeof(jsonlint) != 'undefined') {
jsonlint.parse(jsonString);
}
else {
JSON.parse(jsonString);
}
if (typeof(jsonlint) != 'undefined') {
jsonlint.parse(jsonString);
}
else {
JSON.parse(jsonString);
}
};
/**
@ -40,12 +40,12 @@ util.validate = function validate(jsonString) {
* @return {Object} a
*/
util.extend = function extend(a, b) {
for (var prop in b) {
if (b.hasOwnProperty(prop)) {
a[prop] = b[prop];
}
for (var prop in b) {
if (b.hasOwnProperty(prop)) {
a[prop] = b[prop];
}
return a;
}
return a;
};
/**
@ -54,12 +54,12 @@ util.extend = function extend(a, b) {
* @return {Object} a
*/
util.clear = function clear (a) {
for (var prop in a) {
if (a.hasOwnProperty(prop)) {
delete a[prop];
}
for (var prop in a) {
if (a.hasOwnProperty(prop)) {
delete a[prop];
}
return a;
}
return a;
};
/**
@ -67,9 +67,9 @@ util.clear = function clear (a) {
* @param {...*} args
*/
util.log = function log (args) {
if (typeof console !== 'undefined' && typeof console.log === 'function') {
console.log.apply(console, arguments);
}
if (typeof console !== 'undefined' && typeof console.log === 'function') {
console.log.apply(console, arguments);
}
};
/**
@ -78,29 +78,29 @@ util.log = function log (args) {
* @return {String} type
*/
util.type = function type (object) {
if (object === null) {
return 'null';
}
if (object === undefined) {
return 'undefined';
}
if ((object instanceof Number) || (typeof object === 'number')) {
return 'number';
}
if ((object instanceof String) || (typeof object === 'string')) {
return 'string';
}
if ((object instanceof Boolean) || (typeof object === 'boolean')) {
return 'boolean';
}
if ((object instanceof RegExp) || (typeof object === 'regexp')) {
return 'regexp';
}
if (Array.isArray(object)) {
return 'array';
}
if (object === null) {
return 'null';
}
if (object === undefined) {
return 'undefined';
}
if ((object instanceof Number) || (typeof object === 'number')) {
return 'number';
}
if ((object instanceof String) || (typeof object === 'string')) {
return 'string';
}
if ((object instanceof Boolean) || (typeof object === 'boolean')) {
return 'boolean';
}
if ((object instanceof RegExp) || (typeof object === 'regexp')) {
return 'regexp';
}
if (Array.isArray(object)) {
return 'array';
}
return 'object';
return 'object';
};
/**
@ -110,8 +110,8 @@ util.type = function type (object) {
*/
var isUrlRegex = /^https?:\/\/\S+$/;
util.isUrl = function isUrl (text) {
return (typeof text == 'string' || text instanceof String) &&
isUrlRegex.test(text);
return (typeof text == 'string' || text instanceof String) &&
isUrlRegex.test(text);
};
/**
@ -121,15 +121,15 @@ util.isUrl = function isUrl (text) {
* in the browser page.
*/
util.getAbsoluteLeft = function getAbsoluteLeft(elem) {
var left = elem.offsetLeft;
var body = document.body;
var e = elem.offsetParent;
while (e != null && elem != body) {
left += e.offsetLeft;
left -= e.scrollLeft;
e = e.offsetParent;
}
return left;
var left = elem.offsetLeft;
var body = document.body;
var e = elem.offsetParent;
while (e != null && elem != body) {
left += e.offsetLeft;
left -= e.scrollLeft;
e = e.offsetParent;
}
return left;
};
/**
@ -139,15 +139,15 @@ util.getAbsoluteLeft = function getAbsoluteLeft(elem) {
* in the browser page.
*/
util.getAbsoluteTop = function getAbsoluteTop(elem) {
var top = elem.offsetTop;
var body = document.body;
var e = elem.offsetParent;
while (e != null && e != body) {
top += e.offsetTop;
top -= e.scrollTop;
e = e.offsetParent;
}
return top;
var top = elem.offsetTop;
var body = document.body;
var e = elem.offsetParent;
while (e != null && e != body) {
top += e.offsetTop;
top -= e.scrollTop;
e = e.offsetParent;
}
return top;
};
/**
@ -156,11 +156,11 @@ util.getAbsoluteTop = function getAbsoluteTop(elem) {
* @param {String} className
*/
util.addClassName = function addClassName(elem, className) {
var classes = elem.className.split(' ');
if (classes.indexOf(className) == -1) {
classes.push(className); // add the class to the array
elem.className = classes.join(' ');
}
var classes = elem.className.split(' ');
if (classes.indexOf(className) == -1) {
classes.push(className); // add the class to the array
elem.className = classes.join(' ');
}
};
/**
@ -169,12 +169,12 @@ util.addClassName = function addClassName(elem, className) {
* @param {String} className
*/
util.removeClassName = function removeClassName(elem, className) {
var classes = elem.className.split(' ');
var index = classes.indexOf(className);
if (index != -1) {
classes.splice(index, 1); // remove the class from the array
elem.className = classes.join(' ');
}
var classes = elem.className.split(' ');
var index = classes.indexOf(className);
if (index != -1) {
classes.splice(index, 1); // remove the class from the array
elem.className = classes.join(' ');
}
};
/**
@ -183,30 +183,30 @@ util.removeClassName = function removeClassName(elem, className) {
* @param {Element} divElement
*/
util.stripFormatting = function stripFormatting(divElement) {
var childs = divElement.childNodes;
for (var i = 0, iMax = childs.length; i < iMax; i++) {
var child = childs[i];
var childs = divElement.childNodes;
for (var i = 0, iMax = childs.length; i < iMax; i++) {
var child = childs[i];
// remove the style
if (child.style) {
// TODO: test if child.attributes does contain style
child.removeAttribute('style');
}
// remove all attributes
var attributes = child.attributes;
if (attributes) {
for (var j = attributes.length - 1; j >= 0; j--) {
var attribute = attributes[j];
if (attribute.specified == true) {
child.removeAttribute(attribute.name);
}
}
}
// recursively strip childs
util.stripFormatting(child);
// remove the style
if (child.style) {
// TODO: test if child.attributes does contain style
child.removeAttribute('style');
}
// remove all attributes
var attributes = child.attributes;
if (attributes) {
for (var j = attributes.length - 1; j >= 0; j--) {
var attribute = attributes[j];
if (attribute.specified == true) {
child.removeAttribute(attribute.name);
}
}
}
// recursively strip childs
util.stripFormatting(child);
}
};
/**
@ -217,15 +217,15 @@ util.stripFormatting = function stripFormatting(divElement) {
* @param {Element} contentEditableElement A content editable div
*/
util.setEndOfContentEditable = function setEndOfContentEditable(contentEditableElement) {
var range, selection;
if(document.createRange) {
range = document.createRange();//Create a range (a range is a like the selection but invisible)
range.selectNodeContents(contentEditableElement);//Select the entire contents of the element with the range
range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start
selection = window.getSelection();//get the selection object (allows you to change selection)
selection.removeAllRanges();//remove any selections already made
selection.addRange(range);//make the range you have just created the visible selection
}
var range, selection;
if(document.createRange) {
range = document.createRange();//Create a range (a range is a like the selection but invisible)
range.selectNodeContents(contentEditableElement);//Select the entire contents of the element with the range
range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start
selection = window.getSelection();//get the selection object (allows you to change selection)
selection.removeAllRanges();//remove any selections already made
selection.addRange(range);//make the range you have just created the visible selection
}
};
/**
@ -234,18 +234,18 @@ util.setEndOfContentEditable = function setEndOfContentEditable(contentEditableE
* @param {Element} contentEditableElement A content editable div
*/
util.selectContentEditable = function selectContentEditable(contentEditableElement) {
if (!contentEditableElement || contentEditableElement.nodeName != 'DIV') {
return;
}
if (!contentEditableElement || contentEditableElement.nodeName != 'DIV') {
return;
}
var sel, range;
if (window.getSelection && document.createRange) {
range = document.createRange();
range.selectNodeContents(contentEditableElement);
sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
var sel, range;
if (window.getSelection && document.createRange) {
range = document.createRange();
range.selectNodeContents(contentEditableElement);
sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
};
/**
@ -254,13 +254,13 @@ util.selectContentEditable = function selectContentEditable(contentEditableEleme
* @return {Range | TextRange | null} range
*/
util.getSelection = function getSelection() {
if (window.getSelection) {
var sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
return sel.getRangeAt(0);
}
if (window.getSelection) {
var sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
return sel.getRangeAt(0);
}
return null;
}
return null;
};
/**
@ -269,13 +269,13 @@ util.getSelection = function getSelection() {
* @param {Range | TextRange | null} range
*/
util.setSelection = function setSelection(range) {
if (range) {
if (window.getSelection) {
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
if (range) {
if (window.getSelection) {
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
}
};
/**
@ -288,18 +288,18 @@ util.setSelection = function setSelection(range) {
* Returns null if no text selection is found
*/
util.getSelectionOffset = function getSelectionOffset() {
var range = util.getSelection();
var range = util.getSelection();
if (range && 'startOffset' in range && 'endOffset' in range &&
range.startContainer && (range.startContainer == range.endContainer)) {
return {
startOffset: range.startOffset,
endOffset: range.endOffset,
container: range.startContainer.parentNode
};
}
if (range && 'startOffset' in range && 'endOffset' in range &&
range.startContainer && (range.startContainer == range.endContainer)) {
return {
startOffset: range.startOffset,
endOffset: range.endOffset,
container: range.startContainer.parentNode
};
}
return null;
return null;
};
/**
@ -310,18 +310,18 @@ util.getSelectionOffset = function getSelectionOffset() {
* {Number} endOffset
*/
util.setSelectionOffset = function setSelectionOffset(params) {
if (document.createRange && window.getSelection) {
var selection = window.getSelection();
if(selection) {
var range = document.createRange();
// TODO: do not suppose that the first child of the container is a textnode,
// but recursively find the textnodes
range.setStart(params.container.firstChild, params.startOffset);
range.setEnd(params.container.firstChild, params.endOffset);
if (document.createRange && window.getSelection) {
var selection = window.getSelection();
if(selection) {
var range = document.createRange();
// TODO: do not suppose that the first child of the container is a textnode,
// but recursively find the textnodes
range.setStart(params.container.firstChild, params.startOffset);
range.setEnd(params.container.firstChild, params.endOffset);
util.setSelection(range);
}
util.setSelection(range);
}
}
};
/**
@ -331,68 +331,68 @@ util.setSelectionOffset = function setSelectionOffset(params) {
* @return {String} innerText
*/
util.getInnerText = function getInnerText(element, buffer) {
var first = (buffer == undefined);
if (first) {
buffer = {
'text': '',
'flush': function () {
var text = this.text;
this.text = '';
return text;
},
'set': function (text) {
this.text = text;
}
};
}
var first = (buffer == undefined);
if (first) {
buffer = {
'text': '',
'flush': function () {
var text = this.text;
this.text = '';
return text;
},
'set': function (text) {
this.text = text;
}
};
}
// text node
if (element.nodeValue) {
return buffer.flush() + element.nodeValue;
}
// text node
if (element.nodeValue) {
return buffer.flush() + element.nodeValue;
}
// divs or other HTML elements
if (element.hasChildNodes()) {
var childNodes = element.childNodes;
var innerText = '';
// divs or other HTML elements
if (element.hasChildNodes()) {
var childNodes = element.childNodes;
var innerText = '';
for (var i = 0, iMax = childNodes.length; i < iMax; i++) {
var child = childNodes[i];
for (var i = 0, iMax = childNodes.length; i < iMax; i++) {
var child = childNodes[i];
if (child.nodeName == 'DIV' || child.nodeName == 'P') {
var prevChild = childNodes[i - 1];
var prevName = prevChild ? prevChild.nodeName : undefined;
if (prevName && prevName != 'DIV' && prevName != 'P' && prevName != 'BR') {
innerText += '\n';
buffer.flush();
}
innerText += util.getInnerText(child, buffer);
buffer.set('\n');
}
else if (child.nodeName == 'BR') {
innerText += buffer.flush();
buffer.set('\n');
}
else {
innerText += util.getInnerText(child, buffer);
}
}
return innerText;
}
else {
if (element.nodeName == 'P' && util.getInternetExplorerVersion() != -1) {
// On Internet Explorer, a <p> with hasChildNodes()==false is
// rendered with a new line. Note that a <p> with
// hasChildNodes()==true is rendered without a new line
// Other browsers always ensure there is a <br> inside the <p>,
// and if not, the <p> does not render a new line
return buffer.flush();
if (child.nodeName == 'DIV' || child.nodeName == 'P') {
var prevChild = childNodes[i - 1];
var prevName = prevChild ? prevChild.nodeName : undefined;
if (prevName && prevName != 'DIV' && prevName != 'P' && prevName != 'BR') {
innerText += '\n';
buffer.flush();
}
innerText += util.getInnerText(child, buffer);
buffer.set('\n');
}
else if (child.nodeName == 'BR') {
innerText += buffer.flush();
buffer.set('\n');
}
else {
innerText += util.getInnerText(child, buffer);
}
}
// br or unknown
return '';
return innerText;
}
else {
if (element.nodeName == 'P' && util.getInternetExplorerVersion() != -1) {
// On Internet Explorer, a <p> with hasChildNodes()==false is
// rendered with a new line. Note that a <p> with
// hasChildNodes()==true is rendered without a new line
// Other browsers always ensure there is a <br> inside the <p>,
// and if not, the <p> does not render a new line
return buffer.flush();
}
}
// br or unknown
return '';
};
/**
@ -402,21 +402,21 @@ util.getInnerText = function getInnerText(element, buffer) {
* @return {Number} Internet Explorer version, or -1 in case of an other browser
*/
util.getInternetExplorerVersion = function getInternetExplorerVersion() {
if (_ieVersion == -1) {
var rv = -1; // Return value assumes failure.
if (navigator.appName == 'Microsoft Internet Explorer')
{
var ua = navigator.userAgent;
var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
if (re.exec(ua) != null) {
rv = parseFloat( RegExp.$1 );
}
}
_ieVersion = rv;
if (_ieVersion == -1) {
var rv = -1; // Return value assumes failure.
if (navigator.appName == 'Microsoft Internet Explorer')
{
var ua = navigator.userAgent;
var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
if (re.exec(ua) != null) {
rv = parseFloat( RegExp.$1 );
}
}
return _ieVersion;
_ieVersion = rv;
}
return _ieVersion;
};
/**
@ -444,19 +444,19 @@ var _ieVersion = -1;
* @return {function} the created event listener
*/
util.addEventListener = function addEventListener(element, action, listener, useCapture) {
if (element.addEventListener) {
if (useCapture === undefined)
useCapture = false;
if (element.addEventListener) {
if (useCapture === undefined)
useCapture = false;
if (action === "mousewheel" && util.isFirefox()) {
action = "DOMMouseScroll"; // For Firefox
}
element.addEventListener(action, listener, useCapture);
return listener;
} else {
throw new Error('missing function addEventListener');
if (action === "mousewheel" && util.isFirefox()) {
action = "DOMMouseScroll"; // For Firefox
}
element.addEventListener(action, listener, useCapture);
return listener;
} else {
throw new Error('missing function addEventListener');
}
};
/**
@ -467,16 +467,16 @@ util.addEventListener = function addEventListener(element, action, listener, use
* @param {boolean} [useCapture] false by default
*/
util.removeEventListener = function removeEventListener(element, action, listener, useCapture) {
if (element.removeEventListener) {
if (useCapture === undefined)
useCapture = false;
if (element.removeEventListener) {
if (useCapture === undefined)
useCapture = false;
if (action === "mousewheel" && util.isFirefox()) {
action = "DOMMouseScroll"; // For Firefox
}
element.removeEventListener(action, listener, useCapture);
} else {
throw new Error('missing function removeEventListener');
if (action === "mousewheel" && util.isFirefox()) {
action = "DOMMouseScroll"; // For Firefox
}
element.removeEventListener(action, listener, useCapture);
} else {
throw new Error('missing function removeEventListener');
}
};

View File

@ -1,17 +1,17 @@
{
"Name": "JSON Editor Online",
"Website": "http://jsoneditoronline.org",
"Version": 2.0,
"Free": true,
"Description": "JSON Editor Online is a web-based tool to view, edit, and format JSON. It shows your data side by side in a clear, editable treeview and in a code editor.",
"Features": [
"View and edit JSON side by side in treeview and a code editor.",
"Edit, add, move, remove, and duplicate fields and values.",
"Change type of values.",
"Colorized values, color depends of the value type.",
"Search & highlight text in the treeview.",
"Undo and redo all actions.",
"Load and save file and urls.",
"Format, compact, and inspect JSON in the code editor."
]
"Name": "JSON Editor Online",
"Website": "http://jsoneditoronline.org",
"Version": 2.0,
"Free": true,
"Description": "JSON Editor Online is a web-based tool to view, edit, and format JSON. It shows your data side by side in a clear, editable treeview and in a code editor.",
"Features": [
"View and edit JSON side by side in treeview and a code editor.",
"Edit, add, move, remove, and duplicate fields and values.",
"Change type of values.",
"Colorized values, color depends of the value type.",
"Search & highlight text in the treeview.",
"Undo and redo all actions.",
"Load and save file and urls.",
"Format, compact, and inspect JSON in the code editor."
]
}

View File

@ -1,29 +1,29 @@
{
"name": "jsoneditor",
"version": "2.4.0-SNAPSHOT",
"main": "jsoneditor.js",
"description": "A web-based tool to view, edit and format JSON",
"tags": [
"json",
"editor",
"viewer",
"formatter"
],
"author": "Jos de Jong <wjosdejong@gmail.com>",
"homepage": "http://jsoneditoronline.org/",
"repository": {
"type": "git",
"url": "https://github.com/josdejong/jsoneditor.git"
},
"bugs": "https://github.com/josdejong/jsoneditor/issues",
"scripts": {
"prepublish": "jake"
},
"dependencies": {},
"devDependencies": {
"jake": "latest",
"jake-utils": "latest",
"archiver": "latest",
"clean-css": "latest"
}
"name": "jsoneditor",
"version": "2.4.0-SNAPSHOT",
"main": "jsoneditor.js",
"description": "A web-based tool to view, edit and format JSON",
"tags": [
"json",
"editor",
"viewer",
"formatter"
],
"author": "Jos de Jong <wjosdejong@gmail.com>",
"homepage": "http://jsoneditoronline.org/",
"repository": {
"type": "git",
"url": "https://github.com/josdejong/jsoneditor.git"
},
"bugs": "https://github.com/josdejong/jsoneditor/issues",
"scripts": {
"prepublish": "jake"
},
"dependencies": {},
"devDependencies": {
"jake": "latest",
"jake-utils": "latest",
"archiver": "latest",
"clean-css": "latest"
}
}