json-object-editor
Version:
JOE the Json Object Editor | Platform Edition
1,428 lines (1,178 loc) • 384 kB
JavaScript
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
/*/---------------------------------------------------------
Craydent LLC
Copyright 2014 (http://craydent.com/joe)
Dual licensed under the MIT or GPL Version 2 licenses.
(http://craydent.com/license)
---------------------------------------------------------/*/
//render field - self.renderObjectPropFieldUI
//render list item - self.renderListItems()
//single field list item -renderFieldListItem()
if ($c.isMobile()) {
document.getElementsByTagName('html')[0].className += ' touch joesmall-size';
} else {
document.getElementsByTagName('html')[0].className += ' no-touch joelarge-size';
}
window._joeEditingHash = false;
var _webworkers = false;
var _joeworker;
if (!!window.Worker) {
_webworkers = true;
}
var joe_web_dir = '//' + location.hostname + ':' + (location.port || (location.protocol == "https:" ? 443 : 80)) + "/JsonObjectEditor/";
if (location && location.origin == 'file://') {
joe_web_dir = location.href.slice(0, location.href.lastIndexOf('/') + 1);
}
var __docWriter = function __docWriter(src, type, cancelWrite) {
var type = type || 'js';
var html = '';
switch (type.toLowerCase()) {
case 'js':
case 'javascript':
html += '<script type="text/javascript" src="' + src + '"></script>';
break;
case 'css':
case 'stylesheet':
html += '<link href="' + src + '" rel="stylesheet" type="text/css">';
break;
}
if (!cancelWrite) {
document.write(html);
}
return html;
};
var __loadAdditionalFiles = function __loadAdditionalFiles() {
var bonuses = '';
if (typeof jQuery == 'undefined') {
//console.log('loading jquery');
/* bonuses+=
__docWriter(joe_web_dir+"js/libs/jquery-1.11.3.min.js",'js')+
__docWriter(joe_web_dir+"js/libs/jquery-ui.min.js");*/
__docWriter(joe_web_dir + "js/libs/jquery-1.11.3.min.js", 'js') + __docWriter(joe_web_dir + "js/libs/jquery-ui.min.js");
}
bonuses += __docWriter(joe_web_dir + "js/libs/jquery.ui.touch-punch.min.js");
if (typeof Craydent == 'undefined' || !Craydent.VERSION || Craydent.VERSION < '1.7.37') {
bonuses += __docWriter(joe_web_dir + "js/libs/craydent-1.8.1.js", 'js', true);
}
/*
bonuses+=
__docWriter(joe_web_dir+'css/joe.css','css','css',true)
+__docWriter(joe_web_dir+'js/ace/ace.js','js',true)
+__docWriter(joe_web_dir+'js/plugins/tinymce.min.js','js',true);
*/
document.write(bonuses);
};
function __require(file, callback) {
var head = document.getElementsByTagName("head")[0];
var script = document.createElement('script');
script.src = file;
script.type = 'text/javascript'; //real browsers
script.onload = callback; //Internet explorer
script.onreadystatechange = function () {
if (this.readyState == 'complete') {
callback();
}
};
head.appendChild(script);
}
/*var __joeFieldTypes = [
'text',
'select',
'code',
'rendering',
'date',
'boolean',
'geo',
'image',
'url',
'objectList',
'objectReference',
'group',
'content'
];*/
//__loadAdditionalFiles();
function JsonObjectEditor(specs) {
var self = this;
var htmlRef = document.getElementsByTagName('html')[0];
self.initialDocumentTitle = document.title;
$c.TEMPLATE_VARS.push({
variable: '/textarea',
value: '</textarea>'
}, {
variable: 'textarea',
value: '<textarea>'
}, {
variable: 'SERVER',
value: '//' + $c.SERVER
});
var initialized = false;
var colCount = 1;
var listMode = false;
var gridMode = false;
var tableMode = false,
tableSpecs;
var multiEdit = false;
this.VERSION = '1.0.1';
window._joes = window._joes || [];
this.joe_index = window._joes.length;
if (!window._joes.length) {
window._joe = this;
}
this.Error = {
log: [],
add: function add(message, error, data) {
var payload = {
caller: arguments.callee.caller,
callerargs: arguments.callee.caller.arguments,
message: message,
error: error,
stack: new Error(error).stack,
data: data,
timestamp: new Date().toISOString(),
_id: cuid()
};
self.Error.log.push(payload);
logit('[error]: ' + message);
},
show: function show() {
self.show(self.Error.log, {
schema: {
title: '${message}',
idprop: '_id',
listView: {
title: '<joe-title>${message}</joe-title><joe-subtitle>${timestamp}</joe-subtitle>',
listWindowTitle: 'Errors'
},
fields: ['error:code', 'message', 'stack:code', {
name: 'data',
type: 'content',
run: function run(data, obj) {
return '<div><pre>' + tryEval(data) + '</pre></div>';
}
}, 'callerargs:code', 'timestamp:guid', '_id']
}
});
}
};
window._joes.push(this);
this.Cache = {
"static": {},
list: [],
lookup: {},
clear: function clear() {
self.Cache.lookup = {};
self.Cache.list = [];
},
remove: function remove(id) {//self.cache.
},
get: function get(id, specs) {
var cacheitem = self.Cache.lookup[id];
if (cacheitem && typeof cacheitem.value == "function" && cacheitem.type == "callback") {
return cacheitem.value(cacheitem.data, cacheitem.id);
}
if (!cacheitem) {
//if(autoadd){
var obj = self.search(id)[0] || false;
if (obj) {
self.Cache.add(obj, {
id: id
});
return obj;
} //}
return false;
}
return cacheitem.value;
},
callback: function callback(id) {
var cacheitem = self.Cache.lookup[id];
if (typeof cacheitem.value == "function") {
return cacheitem.value(cacheitem.data, cacheitem.id);
} else {
logit('cache item is not a function');
}
},
add: function add(value, specs) {
var specs = specs || {};
var obj = $.extend({
id: specs.id || cuid(),
value: value,
parent: self.joe_index
}, specs);
self.Cache.list.push(obj.id);
self.Cache.lookup[obj.id] = obj;
return obj;
}
};
this.Cache.set = this.Cache.add;
this.history = [];
/*-------------------------------------------------------------------->
0 | CONFIG
<--------------------------------------------------------------------*/
var defaults = {
localStorage: false,
container: 'body',
joeprofile: {
lockedFields: ['joeUpdated'],
hiddenFields: []
},
profiles: {},
fields: {},
schemas: {
'rendering': {
title: 'HTML Rendering',
callback: function callback() {
alert('yo');
} //fields:['id','name','thingType','legs','species','weight','color','gender'],
//_listID:'id',
//_listTitle:'${name} ${species}'
}
},
compact: false,
useControlEnter: true,
//to save
useEscapeKey: false,
//to close window
autoInit: false,
autosave: 2000,
dynamicDisplay: $(window).height() < 800 && $c.isMobile() ? 12 : 20,
sans: false,
listSubMenu: true,
documentTitle: false,
//tmplate to set document title
style: {
inset: true,
cards: false
},
speechRecognition: false
};
this.specs = $.extend({}, defaults, specs || {});
if (this.specs.localStorage && typeof Storage === "undefined") {
alert('no local storage');
this.specs.LocalStorage = false;
}
this.Indexes = {
_add: function _add(idprop, dataitem) {
self.Indexes[idprop] = self.Indexes[idprop] || {};
self.Indexes[idprop][dataitem[idprop]] = dataitem;
},
_usage: 0
};
this.Printer = {
init: function init() {
if (!document.querySelector('print-joe')) {
document.body.appendChild(document.createElement("print-joe"));
}
},
print: function print() {
self.Printer.init();
var elmnt = document.getElementsByTagName("joe-panel-content")[0];
var cln = elmnt.cloneNode(true);
document.querySelector('print-joe').innerHTML = '';
document.querySelector('print-joe').appendChild(cln);
var panelContent = document.querySelector('print-joe joe-panel-content');
panelContent.className = 'joe-panel-content';
var activeNodes = document.querySelectorAll('print-joe joe-panel-content .joe-content-section.active');
if (activeNodes.length) {
panelContent.innerHTML = '';
for (var i = 0; i < activeNodes.length; i++) {
panelContent.appendChild(activeNodes[i]);
}
}
window.print();
document.querySelector('print-joe').innerHTML = '';
}
};
this.Data = {};
this.Render = {}; //TODO: make current.clear a function
//TODO: check for class/id selector
this.container = $(this.specs.container);
this.fields = this.specs.fields;
this.Fields = {
reset: function reset(propname) {
var field = self.Fields.get(propname);
self.current.object[propname] = field.reset;
self.Fields.rerender(propname);
}
}; //configure schemas
this.schemas = this.specs.schemas;
/*
this.schemas._function = {
idprop:'name'
};*/
for (var s in _joe.schemas) {
_joe.schemas[s].__schemaname = _joe.schemas[s].name = s;
_joe.schemas[s]._id = cuid();
}
this.current = {}; //filters:{},
this.current.clear = function () {
/*|{
featured:true,
description:'cleans up variables that currently exist between a single JOE showings.',
tags:'cleanup, reset',
category:'core'
}|*/
self.current.list = null;
self.current.subsets = null;
self.current.subset = null;
self.current.filters = {};
self.current.fields = [];
self.current.schema = null;
self.current.object = null;
self.current.reset = {};
self.current.cache = {};
self.current.title = null;
self.current.keyword = '';
if (_joes.length == 1) {
document.title = self.initialDocumentTitle;
}
}; //profile
this.defaultProfile = this.specs.defaultProfile || this.specs.joeprofile;
this.current.profile = this.defaultProfile;
this.ace_editors = {};
this.Render.stripeColor = function (opt, colorfunc) {
var color = self.propAsFuncOrValue(colorfunc || opt.stripecolor, opt, null, _jco());
var title = '';
if (color && $c.isObject(color)) {
title = ' title="' + color.title + '" ';
color = color.color;
}
var h = '<joe-stripe-color ' + title + (color && 'style="background-color:' + color + ';"' || '') + '></joe-stripe-color>';
return h;
};
this.Render.bgColor = function (opt, colorfunc) {
var color = self.propAsFuncOrValue(colorfunc || opt.bgcolor, opt, null, _jco());
if (color && $c.isObject(color)) {
color = color.color;
}
var h = '<joe-bg-color ' + (color && 'style="background-color:' + color + ';"' || '') + '></joe-bg-color>';
return h;
};
this.Render.itemCheckbox = function (listItem, schema, specs) {
/*|{
description:'renders a checkbox for a lsititem',
specs:,expander,gotoButton,itemMenu,schemaprop,nonclickable,bgcolor,stripecolor,action
tags:'render, field list item, checkbox',
}|*/
var specs = specs || {};
var checkbox = self.propAsFuncOrValue(self.getCascadingProp('checkbox', schema));
var idprop = specs.idprop || self.getIDProp();
if (checkbox) {
var cbox_prop = checkbox;
var cbox_percentage = null;
var cbox_title = '';
if ($.type(checkbox) == "object") {
cbox_prop = checkbox.prop;
cbox_title = checkbox.title || cbox_prop;
cbox_percentage = self.propAsFuncOrValue(checkbox.percentage, listItem);
}
var cb_label = self.propAsFuncOrValue(checkbox.label, listItem);
var checked = [true, 'true'].contains(listItem[cbox_prop]) ? 'checked' : '';
checkbox = '<joe-checkbox title="' + cbox_title + '" ' + 'class="' + checked + '"' + 'onclick="_joe.checkItem(\'' + listItem[idprop] + '\',\'' + cbox_prop + '\',null,this)">' + (cbox_percentage !== false && checkbox.hasOwnProperty('percentage') ? '<joe-checkbox-percentage>' + Math.round(cbox_percentage * 100) + '%</joe-checkbox-percentage>' : '') + (cb_label && '<joe-checkbox-label>' + cb_label + '</joe-checkbox-label>' || '') + '</joe-checkbox>';
} else {
checkbox = '';
}
return checkbox;
};
/*-------------------------------------------------------------------->
1 | INIT
<--------------------------------------------------------------------*/
this.init = function (callback) {
/*|{
featured:true,
description:'primary entry point into JOE, sets up the UI necessary',
tags:'init, framework',
category:'core'
}|*/
if (initialized) {
return false;
}
beginLogGroup('JOE init');
self.current.clear();
var html = self.renderFramework(self.renderEditorHeader() + self.renderEditorContent() + self.renderEditorFooter());
self.container.append(html);
self.overlay = $('.joe-overlay[data-joeindex=' + self.joe_index + ']');
self.panel = self.overlay.find('.joe-overlay-panel');
self.initKeyHandlers();
self.Speech.init(); //self.Autosave.init();
self.readHashLink();
window.addEventListener("hashchange", function (newH, oldH) {
var useHash = $GET('!') || location.hash;
if (!useHash || self.joe_index != 0 || !specs.useHashlink) {
return false;
}
if (!window._joeEditingHash) {
self.readHashLink();
}
}, false);
var respond_timeout;
$(window).on('resize', function () {
if (self.resizeOk()) {
clearTimeout(respond_timeout);
respond_timeout = setTimeout(self.respond, 200);
}
});
initialized = true;
self.respond();
endLogGroup();
self.Components.init();
callback && callback();
};
this.resizeOk = function () {
if (!$c.isMobile()) {
return true;
}
if (document.activeElement.tagName == "INPUT") {
return false;
}
return true;
};
/*-------------------------------------------------------------------->
INIT KEY HANDLERS
<--------------------------------------------------------------------*/
this.initKeyHandlers = function () {
if (self.specs.useBackButton) {
window.onkeydown = function (e) {
var code = e.keyCode;
var nonBackElements = ['input', 'select', 'textarea'];
var isInputElement = nonBackElements.indexOf(e.target.tagName.toLowerCase()) != -1;
if (code == 8) {
//BACKBUTTON PRESSED
if (isInputElement) {//return false;
} else {
self.goBack();
return false;
}
} else if ([37, 39, 38, 40, 13, 16, 17, 27].indexOf(code) == -1) {
//set focus for alphanumeric keys
if (e.altKey) {
//alt control
switch (code) {
case 70:
//QUICKFIND
self.quickFind();
if (e.stopPropagation) e.stopPropagation();
if (e.preventDefault) e.preventDefault();
break;
case 78:
//QUICKADD
self.quickAdd();
if (e.stopPropagation) e.stopPropagation();
if (e.preventDefault) e.preventDefault();
break;
case 80:
//PRINT
self.Printer.print();
if (e.stopPropagation) e.stopPropagation();
if (e.preventDefault) e.preventDefault();
break;
}
} else {
if (listMode) {
var inSearchfield = false;
if ($(document.activeElement) && $(document.activeElement)[0] != $('.joe-submenu-search-field')[0]) {
self.overlay.find('.joe-submenu-search-field').focus();
inSearchfield = true;
$('.joe-panel-content-option.keyboard-selected').removeClass('keyboard-selected');
}
} else {
//NOT LIST MODE, DETAILS MODE
//is control key down
if (e.ctrlKey || e.metaKey) {
switch (code) {
case 83:
//look for control save
if (self.container.find('.joe-button.joe-quicksave-button').length) {
self.updateObject(null, null, true);
if (e.stopPropagation) e.stopPropagation();
if (e.preventDefault) e.preventDefault();
}
break;
}
}
}
}
} else {
var keyboardSelectOption = function keyboardSelectOption(selector, top) {
$(selector + '.keyboard-selected').toggleClass('keyboard-selected');
var el = $(selector).eq(keyboardSelectedIndex);
el.addClass('keyboard-selected');
self.overlay.find('.joe-submenu-search-field').blur(); // $('.joe-panel-content').scrollTop($('.joe-panel-content-option.keyboard-selected').offset().top);
el[0].scrollIntoView(top); //var panel_content = self.overlay.find('.joe-panel-content');
//panel_content.animate({ scrollTop: panel_content.scrollTop()-10 });
//panel_content.scrollTop(panel_content.scrollTop()-10);
};
//38 up, 40 dn,13 enter,37 left, 39 right
var autocompleteField = $('.joe-text-autocomplete.active').length;
if (autocompleteField) {
var sel = '.joe-text-autocomplete-option.visible' + '.keyboard-selected'; //$('.joe-text-autocomplete-option.visible').length();
var keyboardSelected = $(sel)[0];
var keyboardSelectedIndex = $(sel).length ? $(sel).index() : -1;
switch (code) {
case 38:
//up
keyboardSelectedIndex--;
if (keyboardSelectedIndex > -1) {
keyboardSelectOption('.joe-text-autocomplete-option.visible');
}
break;
case 40:
//down
keyboardSelectedIndex++;
if (keyboardSelectedIndex < $('.joe-text-autocomplete-option.visible').length) {
keyboardSelectOption('.joe-text-autocomplete-option.visible');
}
break;
case 13:
//enter
if (keyboardSelectedIndex != -1) {
keyboardSelected.click();
}
break;
}
}
if (listMode) {
if (e.altKey) {
//alt control
//get current index and add 1
if (self.current.subsets) {
var subindex = self.current.subsets.indexOf(self.current.subset) + 1; //$('joe-subset-option.active').index()+1;
switch (code) {
case 38:
//up
$('joe-subset-option').eq(subindex - 1).click();
break;
case 40:
//down
$('joe-subset-option').eq(subindex + 1).click();
break;
}
}
} else {
var keyboardSelectedIndex = $('.joe-panel-content-option.keyboard-selected').length ? $('.joe-panel-content-option.keyboard-selected').index() : -1; //logit(keyboardSelectedIndex);
switch (code) {
case 38:
//up
keyboardSelectedIndex--;
if (keyboardSelectedIndex > -1) {
keyboardSelectOption('.joe-panel-content-option', top);
}
break;
case 40:
//down
keyboardSelectedIndex++;
if (keyboardSelectedIndex < currentListItems.length) {
keyboardSelectOption('.joe-panel-content-option', top);
}
break;
case 13:
//enter
if (keyboardSelectedIndex != -1) {
$('.joe-panel-content-option.keyboard-selected').find('.joe-panel-content-option-content').click();
}
break;
}
}
} else {
//DETAILS MODE
if (e.altKey) {
switch (code) {
case 219: //left
case 221:
//right
var sside = code == 219 ? 'left' : 'right';
if (self.current.sidebars[sside].content && !self.current.sidebars[sside].hidden) {
self.toggleSidebar(sside);
}
break;
}
} else if (e.ctrlKey) {
switch (code) {
case 37:
//left
self.previous();
break;
case 39:
//right
self.next();
break;
}
} else if (code == 13) {
//add another row on enter click
var ae = $(document.activeElement);
if (ae && ae.is('input')) {
var fieldobj = ae.parents('.joe-object-field');
if (fieldobj.length) {
try {
fieldobj.find('.joe-plus-button').click();
} catch (e) {
self.Error.add('adding new row to objectlist', e);
}
}
}
}
}
}
};
}
};
/*-------------------------------------------------------------------->
2 | FRAMEWORK START
<--------------------------------------------------------------------*/
this.getMode = function () {
if (listMode) {
if (self.current.list) {
return 'list';
}
}
if (self.current.object) {
return 'details';
}
if (self.current.list) {
return 'list';
} else {
return false;
}
/*
if(listMode){return 'list';}
return 'details';*/
};
this.renderFramework = function (content) {
var style = 'style-variant1';
var html = '<joe-overlay class="joe-overlay sans cols-' + colCount + ' ' + style + ' ' + (self.specs.compact && ' compact ' || '') + (self.specs.sans && ' sans ' || '') + '" data-joeindex="' + this.joe_index + '">' + '<joe-panel class="joe-overlay-panel">' + (content || '') + '</joe-panel>' + //mini
'<div class="joe-mini-panel">' + '</div>' + '</joe-overlay>';
return html;
};
this.populateFramework = function (data, setts) {
/*|{
featured:true,
description:'primary function for populating and rendering JOE, called by goJoe and joe.show',
tags:'populate, framework, core'
}|*/
self.current.cache = {};
self.overlay.removeClass('multi-edit');
var joePopulateBenchmarker = new Benchmarker();
self.current.reset = self.current.reset || {};
beginLogGroup('JOE population'); //logit('------Beginning joe population');
var specs = setts || {};
self.current.specs = setts;
self.current.data = data; //clean copy for later;
self.current.userSpecs = $.extend({}, setts);
gridMode = self.current.specs.viewMode == 'grid' ? true : false;
tableMode = self.current.specs.viewMode == 'table' ? true : false; //update history 1/2
if (!self.current.specs.noHistory) {
self.history.push({
/* _joeHistoryTitle:self.overlay.find('.joe-panel-title').html(),
*/
specs: self.current.userSpecs,
data: self.current.data
});
}
var schema = setts.schema || '';
var profile = setts.profile || null;
var callback = setts.callback || null;
var datatype = setts.datatype || '';
var title = setts.title || ''; //callback
if (callback) {
self.current.callback = callback;
} else {
self.current.callback = null;
}
/*-------------------------
String data
-------------------------*/
if ($.type(data) == 'string' && datatype != "string" && self.getDataset(data, {
"boolean": true
})) {
if (!specs.schema && self.schemas[data]) {
schema = data;
}
data = self.getDataset(data);
}
/*setup schema*/
specs.schema = this.setSchema(schema);
/*-------------------------
Column Count
-------------------------*/
colCount = self.current.specs.colCount || specs.schema && specs.schema.colCount
/*|| colCount*/
|| 1;
if (self.sizeClass == "small-size") {
colCount = 1;
}
/*-------------------------
Preformat Functions
-------------------------*/
specs.preformat = specs.schema && specs.schema.preformat || specs.preformat || function (d) {
return d;
};
data = specs.preformat(data);
/*-------------------------
Object
-------------------------*/
//when object passed in
if ($.type(data) == 'object' || datatype == 'object') {
specs.object = data;
specs.menu = specs.menu || specs.schema && specs.schema.menu || self.specs.menu || specs.multiedit && __defaultMultiButtons || __defaultObjectButtons;
specs.mode = "object";
self.current.object = data;
}
/*-------------------------
MultiEdit (Arrays)
-------------------------*/
self.toggleMultiEditMode(specs, data);
/*-------------------------
Lists (Arrays)
-------------------------*/
//when array passed in
listMode = false;
if ($.type(data) == 'array' || datatype == 'array') {
listMode = true;
specs.list = data;
specs.menu = specs.listMenu || specs.schema && specs.schema.listMenu || __defaultButtons; //__defaultMultiButtons;
specs.mode = "list"; //TODO: filter list items here.
self.current.list = data;
/*-------------------------
Subsets
-------------------------*/
var currentSubsets; //setup subsets
currentSubsets = setts.subsets || specs.schema && specs.schema.subsets || null;
if (typeof currentSubsets == 'function') {
currentSubsets = currentSubsets();
} //a current subset selected
if (self.current.specs.subset && currentSubsets &&
/*currentSubsets.where({name:specs.subset})*/
currentSubsets.where({
$or: [{
name: specs.subset
}, {
group_start: specs.subset
}]
}).length) {
self.current.subset = currentSubsets.where({
$or: [{
name: specs.subset
}, {
group_start: specs.subset
}]
})[0] || false;
} else {
//all selected
if (self.current.specs.subset == "All") {
self.current.subset = {
name: "All",
filter: {}
};
} else {
//select default subset if it exists
self.current.subset = currentSubsets && currentSubsets.where({
'default': true
})[0] || null;
}
}
self.current.subsets = currentSubsets;
/*-------------------------
Sorting
-------------------------*/
//setup sorting
self.current.sorter = setts.sorter || self.current.subset && self.current.subset.sorter || specs.schema && specs.schema.sorter || 'name';
if ($.type(self.current.sorter) == 'string') {
self.current.sorter = [self.current.sorter];
} //self.current.object = null;
}
/*-------------------------
Submenu
-------------------------*/
if (specs.mode == 'list') {
self.current.submenu = self.current.specs.listsubmenu || self.current.specs.submenu || specs.schema && specs.schema.listSubMenu || self.specs.listSubMenu;
} else {
self.current.submenu = self.current.specs.submenu || specs.schema && specs.schema.subMenu || self.specs.subMenu;
}
if (self.current.submenu == 'none') {
self.current.submenu = null;
}
/*-------------------------
Rendering
-------------------------*/
//when rendering passed in
if ($.type(data) == 'string' && datatype == 'rendering') {
specs.rendering = data;
specs.menu = [__replaceBtn__];
specs.mode = "rendering";
self.current.rendering = specs.rendering; //specs.schema
}
/*-------------------------
String
-------------------------*/
//when string passed in
else if ($.type(data) == 'string' || datatype == 'string') {
specs.text = data;
specs.menu = __defaultButtons; //specs.menu = [{name:'save',label:'Save Object',action:'_joe.updateObject()'}];
specs.mode = "text";
self.current.text = specs.text;
} //setup window title
//specs.title = title || (specs.schema)? specs.schema._title : "Viewing "+specs.mode.capitalize();
specs.listWindowTitle = specs.list && (specs._listMenuTitle || //specs.listWindowTitle ||
specs._listWindowTitle || self.getCascadingProp('listWindowTitle') || getProperty('specs.list.windowTitle') || specs.schema && (specs.schema._listMenuTitle || specs.schema._listWindowTitle)) || false;
specs.title = specs.listWindowTitle || title || specs.schema && (specs.schema.title || specs.schema._title) || "Viewing " + (self.current.schema && self.current.schema.__schemaname || typeof self.current.userSpecs.schema == 'string' && self.current.userSpecs.schema || specs.mode).capitalize(); //setup profile
specs.profile = profile ? self.specs.profiles[profile] || self.specs.joeprofile : self.specs.joeprofile;
self.current.profile = specs.profile; //cleanup variables
self.cleanUp();
/*-------------------------------------------------------------------->
Set global view mode specs
<--------------------------------------------------------------------*/
if (self.current.schema && (self.current.schema.table || self.current.schema.tableView)) {
tableSpecs = $.extend({
cols: ['name', self.getIDProp()]
}, self.current.schema && (self.current.schema.table || self.current.schema.tableView) // &&(self.current.schema.table||self.current.schema.tableView).cols
|| {});
} else {
tableSpecs = null;
}
/*-------------------------------------------------------------------->
Framework Rendering
<--------------------------------------------------------------------*/
var contentBM = new Benchmarker();
beginLogGroup('Content');
var content = self.renderEditorContent(specs);
endLogGroup();
_bmResponse(contentBM, 'JOE [Content]');
var chromeBM = new Benchmarker();
var html = self.renderEditorHeader(specs) + self.renderEditorSubmenu(specs) + content + self.renderEditorFooter(specs) + self.renderMessageContainer();
_bmResponse(chromeBM, 'JOE [overlay-chrome]');
self.overlay.find('.joe-overlay-panel').html(html); //$('.joe-overlay-panel').html(html);
//update history 2/2 - add title
if (!self.current.specs.noHistory && self.history.length) {
$.extend(self.history[self.history.length - 1], {
_joeHistoryTitle: self.overlay.find('.joe-panel-title').html()
});
} //clear ace_editors
/* for (var p in _joe.ace_editors){
_joe.ace_editors[p].destroy();
}
_joe.ace_editors = {};*/
//update hashlink
self.updateHashLink(); //logit('Joe Populated in '+joePopulateBenchmarker.stop()+' seconds');
_bmResponse(joePopulateBenchmarker, '----Joe Populated');
endLogGroup();
return html;
};
/*-------------------------------------------------------------------->
2e | FRAMEWORK END
<--------------------------------------------------------------------*/
this.toggleMultiEditMode = function (specs, data) {
multiEdit = self.current.userSpecs && self.current.userSpecs.multiedit || false;
};
/*----------------------------->
A | Header
<-----------------------------*/
function createTitleObject(specs) {
var specs = specs || {};
var titleObj = $.extend({}, self.current.object);
var list = specs.list || self.current.list;
if (list) {
var lcount = list.length;
if (self.current.subset) {
lcount = list.where(self.current.subset.filter).length;
}
titleObj._listCount = lcount || '0';
titleObj._subsetName = self.current.subset && self.current.subset.name + ' ' || '';
}
self.current.title = specs.title || self.getCascadingProp('title') || self.current.schema && "new " + self.current.schema.__schemaname || 'Json Object Editor';
self.current.subtitle = specs.subtitle || self.getCascadingProp('subtitle');
var title = fillTemplate(self.propAsFuncOrValue(self.current.title), titleObj);
var subtitle = fillTemplate(self.propAsFuncOrValue(self.current.subtitle), titleObj);
titleObj.docTitle = title;
titleObj.subTitle = subtitle;
return titleObj;
}
this.Header = {};
this.toggleHelpMenu = function (show, target) {};
this.Header.Render = this.renderEditorHeader = function (specs) {
var BM = new Benchmarker();
var specs = specs || {};
var titleObj = createTitleObject(specs);
var title = titleObj.docTitle || self.current.schema && "new " + self.current.schema.__schemaname;
var subtitle = titleObj.subTitle; //show doctitle
if (self.specs.documentTitle) {
var doctitle = self.specs.documentTitle === true ? self.current.title : self.propAsFuncOrValue(self.specs.documentTitle, self.current.title);
document.title = fillTemplate(self.propAsFuncOrValue(doctitle), titleObj);
}
var close_action = specs.close_action || 'onclick="getJoe(' + self.joe_index + ').closeButtonAction()"';
var reload_action = specs.reload_action || 'onclick="getJoe(' + self.joe_index + ').reload()"';
function renderHeaderBackButton() {
var html = '';
if (self.history.length > 1
/*&& specs.useHeaderBackBtn*/
) {
html += '<div class="jif-header-back-btn jif-panel-header-button standard-button" onclick="window.history.back()" title="back">' + self.SVG.icon.left //+'<span class="jif-arrow-left"></span>'
+ '</div>';
}
return html;
}
function renderHelpButton() {
var html = '';
if (specs.minimode) {
return '';
}
html += '<div class="jif-panel-header-button joe-panel-help" onclick="_joe.toggleHelpMenu()" title="help">' + self.SVG.icon.help + '</div>';
return html;
}
var help_button = renderHelpButton();
function renderUnsavedIcon() {
var html = '';
if (specs.minimode) {
return '';
}
html += '<div class="jif-panel-header-button joe-panel-unsaved" onclick="_joe.updateObject(this,null,true);" title="unsaved changes">' + self.SVG.icon.unsaved + '</div>';
return html;
}
var unsaved_icon = renderUnsavedIcon();
var speech_action = specs.speech_action || 'onclick="getJoe(' + self.joe_index + ').Speech()"';
var reload_button = specs.minimode ? '' : '<div class="jif-panel-header-button joe-panel-reload" title="reload" ' + reload_action + '><span class="jif-reload"></span></div>';
var mic_button = !self.specs.speechRecognition || specs.minimode ? '' : '<div class="jif-panel-header-button joe-panel-speech" title="speech" id="speech-button-' + self.joe_index + '">M</div>';
var close_button = '<div class="jif-panel-header-button joe-panel-close" title="close" ' + close_action + '>' + self.SVG.icon.close //+'<span class="jif-close"></span>'+
+ '</div>'; // var schema_button = (!specs.minimode && (self.current.schema && self.current.schema.menuicon &&
// '<joe-schema-icon class="clickable" title="'+self.current.schema.__schemaname+'" onclick="goJoe(_joe.getDataset(\''+self.current.schema.__schemaname+'\'),{schema:\''+self.current.schema.__schemaname+'\'})">'+self.current.schema.menuicon+'</joe-schema-icon>')||'');
var schema_button = !specs.minimode && self.current.schema && self.current.schema.menuicon && '<joe-schema-icon class="clickable" title="' + self.current.schema.__schemaname + '" onclick="goJoe(\'' + self.current.schema.__schemaname + '\')">' + self.current.schema.menuicon + '</joe-schema-icon>' || '';
var back_button = !specs.minimode && renderHeaderBackButton() || '';
var left_buttons = [back_button, schema_button];
var right_buttons = [close_button, mic_button, reload_button, //help_button, TODO: add help button.
unsaved_icon];
var html = //'<div class="joe-panel-header">'+
'<joe-panel-header >' + (specs.schema && specs.schema.subsets && self.renderSubsetselector(specs.schema) || specs.subsets && self.renderSubsetselector(specs) || '') + //'<joe-panel-header-buttons class="left-side">'+
left_buttons.join(' ') + //'</joe-panel-header>'+
'<div class="joe-vcenter joe-panel-title-holder"><span class="joe-panel-title">' + (('<div>' + title + '</div>').toDomElement().innerText || title || 'Json Object Editor') + '</span></div>' + //'<div class="joe-panel-reload joe-panel-header-button" title="reload" '+reload_action+'></div>'+
'<joe-panel-header-buttons class="right-side">' + right_buttons.join(' ') + '<div class="clear"></div>' + '</joe-panel-header-buttons>' + '<div class="clear"></div>' + '</joe-panel-header>';
_bmResponse(BM, '[Header] rendered');
return html;
}; //What happens when the user clicks the close button.
this.closeButtonAction = function (prechecked) {
if (!this.checkChanges()) {
return;
}
self.history = [];
self.panel.addClass('centerscreen-collapse');
self.hide(500);
self.current.clear();
$(self.container).trigger({
type: "hideJoe",
index: self.joe_index
/*,
schema: self.current.specs.schema,
subset: self.current.specs.subset*/
});
self.updateHashLink();
var closeAction = self.getCascadingProp('onPanelHide');
if (closeAction) {
closeAction(self.getState());
}
self.Autosave.deactivate();
};
var goingBackFromID;
var goingBackQuery;
this.goBack = function (obj) {
if (!this.checkChanges()) {
return;
} //go back to last item and highlight
if (self.current.object) {
var gobackItem = self.current.object[self.getIDProp()];
if (gobackItem) {
goingBackFromID = gobackItem; // logit(goingBackFromID);
}
} //clearTimeout(self.searchTimeout );
self.history.pop();
var joespecs = self.history.pop();
if (!joespecs) {
self.closeButtonAction(true);
return;
} else {
if (obj && $c.isArray(joespecs.data)) {
var objid = obj[self.getIDProp()];
if (objid) {
var query = {};
query[self.getIDProp()] = objid;
var found = joespecs.data.where(query);
found.length && $.extend(found[0], obj);
}
}
if (joespecs.keyword) {
goingBackQuery = joespecs.keyword;
}
}
var specs = $.extend({}, joespecs.specs);
specs.filters = joespecs.filters;
self.show(joespecs.data, specs);
};
/* this.clearAuxiliaryData = function(){
/!*|{
featured:true,
description:'cleans up variables that currently exist between a single JOE showings.',
tags:'cleanup, reset',
category:'core'
}|*!/
self.current.list = null;
self.current.subsets = null;
self.current.subset = null;
self.current.filters = {};
self.current.fields = [];
self.current.schema = null;
self.current.object = null;
self.current.reset = {};
};*/
//this.current.clear = this.clearAuxiliaryData;
this.cleanUp = function () {
/*|{
featured:true,
description:'cleans up variables that currently exist between a single JOE showings.',
tags:'cleanup, reset',
category:'core'
}|*/
/* if(!self._reloading){
self.current.reset = {};
}*/
self.current.fields = [];
self.shiftSelecting = false;
self.allSelected = false;
/* for (var p in _joe.ace_editors){
_joe.ace_editors[p].destroy();
}
_joe.ace_editors = {};*/
if (self.current.userSpecs && self.current.userSpecs.multiedit) {
self.overlay.addClass('multi-edit');
} else {
self.overlay.removeClass('multi-edit');
}
};
/*----------------------------->
B | SubMenu
<-----------------------------*/
function renderSubmenuButtons(buttons) {
var html = ''; //<div class="joe-submenu-buttons">';
var buttons = self.propAsFuncOrValue(buttons || listMode && self.getCascadingProp('headerListMenu') || !listMode && self.getCascadingProp('headerMenu'));
var content;
if (buttons) {
var h = self.renderMenuButtons(buttons, 'joe-submenu-button');
if (h) {
content = true;
}
html += h;
}
return {
html: html,
content: content
}; // return {html:html +'</div>',content:content};
}
; //self.current.submenuButtons;
this.renderEditorSubmenu = function (specs) {
beginLogGroup('Submenu');
var BM = new Benchmarker();
var sectionAnchors = renderSectionAnchors(); //submenu buttons
var submenuButtons = renderSubmenuButtons();
if (!self.current.submenu && !sectionAnchors.count && !listMode && !self.getCascadingProp('headerMenu')) {
return '';
}
var showFilters = $c.getProperty(self.current, 'userSpecs.filters') || $c.getProperty(self.current, 'schema.filters') || $c.getProperty(self.current, 'schema.subsets') || false;
var subSpecs = {
search: true,
itemcount: true,
filters: showFilters,
numCols: self.current.schema.columns || 0
};
var userSubmenu = $.type(self.current.submenu) != 'object' ? {} : self.current.submenu;
$.extend(subSpecs, userSubmenu);
if (specs.mode == 'list') {
var filters_obj = self.Filter.getCached();
var submenu = '<div class="joe-panel-submenu">' //right side
+self.Submenu.Aggregator.renderToggleButton()
+ self.renderViewModeButtons(subSpecs) + self.renderColumnCountSelector(subSpecs.numCols) + self.renderSorter() //left side
+ (subSpecs.filters && self.renderSubmenuFilters(subSpecs.filter) || '') + (subSpecs.search && self.renderSubmenuSearch(subSpecs.search) || '') + (subSpecs.itemcount && self.renderSubmenuItemcount(subSpecs.itemcount) || '') + submenuButtons.html + '</div>' + "<div class='joe-filters-holder'>" + renderSubsetsDiv() + (filters_obj && renderFiltersDiv() || '') // +'<span class="jif-arrow-left"></span>'
+ "</div>";
} else {
var submenu = '<div class="joe-panel-submenu">' + renderSidebarToggle('left') + renderSidebarToggle('right') + submenuButtons.html + (sectionAnchors.count && sectionAnchors.code || '') + '</div>';
/*
+ "<div class='joe-filters-holder'>"
// + renderSubsetsDiv()
//+ (self.current.schema && (self.propAsFuncOrValue(self.current.schema.filters) && renderFiltersDiv()) || '')
// +'<span class="jif-arrow-left"></span>'
+ "</div>";*/
}
function renderOptStripeColor(opt) {
var color = self.propAsFuncOrValue(opt.stripecolor || opt.stripeColor, null, null, opt);
var title = '';
if (color && $c.isObject(color.title)) {
title = ' title="' + color.title + '" ';
color = color.color;
}
var h = '<joe-stripe-color ' + title + (color && 'style="background-color:' + color + ';"' || '') + '></joe-stripe-color>';
return h;
}
function renderOptBGColor(opt) {
var color = self.propAsFuncOrValue(opt.bgcolor || opt.bgColor, null, null, opt);
if (color && $c.isObject(color.title)) {
color = color.color;
}
var h = '<joe-bg-color ' + (color && 'style="background-color:' + color + ';"' || '') + '></joe-bg-color>';
return h;
}
function renderOptBorderColor(opt) {
var color = self.propAsFuncOrValue(opt.bordercolor || opt.borderColor, null, null, opt);
if (color && $c.isObject(color.title)) {
color = color.color;
}
var h = '<joe-border-color ' + (color && 'style="border:1px solid ' + color + ';"' || '') + '></joe-border-color>';
return h;
}
function renderOptionGroupStart(opt, childDom) {
var collapsed = self.propAsFuncOrValue(opt.collapsed) ? 'collapsed' : '';
if (!opt.hasOwnProperty('filter')) {
var html = '<joe-option-group id="' + opt.group_start + '-group" class="' + collapsed + '"><joe-menu-label onclick="$(this).parent().toggleClass(\'collapsed\');">' + (opt.display || opt.name || opt.group_start) + '</joe-menu-label>';
return html;
} else {
var optdisplay = opt.display || opt.name || opt.group_start || '';
var optname = opt.id || opt.name || opt.group_start || '';
var cbox = '',
act,
onclick;
var dataname;
if (childDom == 'joe-filter-option') {
dataname = ' data-filter="' + optname + '" ';
cbox = '<span class ="joe-option-checkbox"></span>';
act = self.current.filters && self.current.filters[optname] ? 'active' : '';
onclick = 'getJoe(' + self.joe_index + ').toggleFilter(\'' + optname + '\',this);_joe.Utils.stopPropagation();';
} else {
dataname = ' data-subset="' + optname + '" ';
act = self.current.subset && self.current.subset.name == optname || !self.current.subset && opt.name == "All" ? 'active' : '';
onclick = 'getJoe(' + self.joe_index + ').selectSubset(\'' + optname.toString().replace(/\'/g, "\\'") + '\');';
}
var optiondiv = '<' + childDom + ' ' + dataname + ' class="' + childDom + ' joe-group-option ' + act + ' " onclick=' + onclick + '>' + renderOptBorderColor(opt) + renderOptBGColor(opt) + renderOptStripeColor(opt) + cbox + '<span style="position:relative;">' + optdisplay + '</span>' + '</' + childDom + '>';
var html = '<joe-option-group id="' + opt.group_start + '-group" class="' + collapsed + ' ">' + '<joe-menu-label onclick="$(this).parent().toggleClass(\'collapsed\');">' + optiondiv + '</joe-menu-label>';
return html;
}
} //TODO:move to subsets filter rendering function
function renderSubsetsDiv() {
var sh = '<div><joe-menu-label>Subsets</joe-menu-label>';
var act;
var starting = [];
if (!self.current.schema || !self.current.schema.hideAllSubset) {
starting.push({
name: 'All',
filter: {}
});
}
var group = null;
starting.concat(_joe.current.subsets || []).map(function (opt) {
if (opt.group_start) {
group = opt.group_start;
sh += renderOptionGroupStart(opt, 'joe-subset-option');
} else if (opt.group_end) {
sh += '</joe-option-group>';
group = null;
} else {
var idval = opt.id || opt.name || ''; //if(!opt.condition || (typeof opt.condition == 'function' && opt.condition(self.current.object)) || (typeof opt.condition != 'function' && opt.condition)) {
if (!opt.condition || self.propAsFuncOrValue(opt.condition)) {
act = self.current.subset && self.current.subset.name == opt.name || !self.current.subset && opt.name == "All" ? 'active' : '';
if (act == 'active' && group) {
sh = sh.replace('<joe-option-group id="' + group + '-group" class="collapsed', '<joe-option-group id="' + group + '-group" class="');
} // sh += '<joe-subset-option data-subset="'+idval+'" class="joe-subset-option ' + act + ' " onclick="getJoe(' + self.joe_index + ').selectSubset(\''
// + (opt.id || opt.name || '').toString().replace(/\'/g,"\\'") + '\');">'
// +r