UNPKG

json-editor

Version:
449 lines (393 loc) 13.8 kB
JSONEditor.defaults.editors.string = JSONEditor.AbstractEditor.extend({ register: function() { this._super(); if(!this.input) return; this.input.setAttribute('name',this.formname); }, unregister: function() { this._super(); if(!this.input) return; this.input.removeAttribute('name'); }, setValue: function(value,initial,from_template) { var self = this; if(this.template && !from_template) { return; } if(value === null || typeof value === 'undefined') value = ""; else if(typeof value === "object") value = JSON.stringify(value); else if(typeof value !== "string") value = ""+value; if(value === this.serialized) return; // Sanitize value before setting it var sanitized = this.sanitize(value); if(this.input.value === sanitized) { return; } this.input.value = sanitized; // If using SCEditor, update the WYSIWYG if(this.sceditor_instance) { this.sceditor_instance.val(sanitized); } else if(this.epiceditor) { this.epiceditor.importFile(null,sanitized); } else if(this.ace_editor) { this.ace_editor.setValue(sanitized); } var changed = from_template || this.getValue() !== value; this.refreshValue(); if(initial) this.is_dirty = false; else if(this.jsoneditor.options.show_errors === "change") this.is_dirty = true; if(this.adjust_height) this.adjust_height(this.input); // Bubble this setValue to parents if the value changed this.onChange(changed); }, getNumColumns: function() { var min = Math.ceil(Math.max(this.getTitle().length,this.schema.maxLength||0,this.schema.minLength||0)/5); var num; if(this.input_type === 'textarea') num = 6; else if(['text','email'].indexOf(this.input_type) >= 0) num = 4; else num = 2; return Math.min(12,Math.max(min,num)); }, build: function() { var self = this, i; if(!this.options.compact) this.header = this.label = this.theme.getFormInputLabel(this.getTitle()); if(this.schema.description) this.description = this.theme.getFormInputDescription(this.schema.description); this.format = this.schema.format; if(!this.format && this.schema.media && this.schema.media.type) { this.format = this.schema.media.type.replace(/(^(application|text)\/(x-)?(script\.)?)|(-source$)/g,''); } if(!this.format && this.options.default_format) { this.format = this.options.default_format; } if(this.options.format) { this.format = this.options.format; } // Specific format if(this.format) { // Text Area if(this.format === 'textarea') { this.input_type = 'textarea'; this.input = this.theme.getTextareaInput(); } // Range Input else if(this.format === 'range') { this.input_type = 'range'; var min = this.schema.minimum || 0; var max = this.schema.maximum || Math.max(100,min+1); var step = 1; if(this.schema.multipleOf) { if(min%this.schema.multipleOf) min = Math.ceil(min/this.schema.multipleOf)*this.schema.multipleOf; if(max%this.schema.multipleOf) max = Math.floor(max/this.schema.multipleOf)*this.schema.multipleOf; step = this.schema.multipleOf; } this.input = this.theme.getRangeInput(min,max,step); } // Source Code else if([ 'actionscript', 'batchfile', 'bbcode', 'c', 'c++', 'cpp', 'coffee', 'csharp', 'css', 'dart', 'django', 'ejs', 'erlang', 'golang', 'groovy', 'handlebars', 'haskell', 'haxe', 'html', 'ini', 'jade', 'java', 'javascript', 'json', 'less', 'lisp', 'lua', 'makefile', 'markdown', 'matlab', 'mysql', 'objectivec', 'pascal', 'perl', 'pgsql', 'php', 'python', 'r', 'ruby', 'sass', 'scala', 'scss', 'smarty', 'sql', 'stylus', 'svg', 'twig', 'vbscript', 'xml', 'yaml' ].indexOf(this.format) >= 0 ) { this.input_type = this.format; this.source_code = true; this.input = this.theme.getTextareaInput(); } // HTML5 Input type else { this.input_type = this.format; this.input = this.theme.getFormInputField(this.input_type); } } // Normal text input else { this.input_type = 'text'; this.input = this.theme.getFormInputField(this.input_type); } // minLength, maxLength, and pattern if(typeof this.schema.maxLength !== "undefined") this.input.setAttribute('maxlength',this.schema.maxLength); if(typeof this.schema.pattern !== "undefined") this.input.setAttribute('pattern',this.schema.pattern); else if(typeof this.schema.minLength !== "undefined") this.input.setAttribute('pattern','.{'+this.schema.minLength+',}'); if(this.options.compact) { this.container.className += ' compact'; } else { if(this.options.input_width) this.input.style.width = this.options.input_width; } if(this.schema.readOnly || this.schema.readonly || this.schema.template) { this.always_disabled = true; this.input.disabled = true; } this.input .addEventListener('change',function(e) { e.preventDefault(); e.stopPropagation(); // Don't allow changing if this field is a template if(self.schema.template) { this.value = self.value; return; } var val = this.value; // sanitize value var sanitized = self.sanitize(val); if(val !== sanitized) { this.value = sanitized; } self.is_dirty = true; self.refreshValue(); self.onChange(true); }); if(this.options.input_height) this.input.style.height = this.options.input_height; if(this.options.expand_height) { this.adjust_height = function(el) { if(!el) return; var i, ch=el.offsetHeight; // Input too short if(el.offsetHeight < el.scrollHeight) { i=0; while(el.offsetHeight < el.scrollHeight+3) { if(i>100) break; i++; ch++; el.style.height = ch+'px'; } } else { i=0; while(el.offsetHeight >= el.scrollHeight+3) { if(i>100) break; i++; ch--; el.style.height = ch+'px'; } el.style.height = (ch+1)+'px'; } }; this.input.addEventListener('keyup',function(e) { self.adjust_height(this); }); this.input.addEventListener('change',function(e) { self.adjust_height(this); }); this.adjust_height(); } if(this.format) this.input.setAttribute('data-schemaformat',this.format); this.control = this.theme.getFormControl(this.label, this.input, this.description); this.container.appendChild(this.control); // Any special formatting that needs to happen after the input is added to the dom window.requestAnimationFrame(function() { // Skip in case the input is only a temporary editor, // otherwise, in the case of an ace_editor creation, // it will generate an error trying to append it to the missing parentNode if(self.input.parentNode) self.afterInputReady(); if(self.adjust_height) self.adjust_height(self.input); }); // Compile and store the template if(this.schema.template) { this.template = this.jsoneditor.compileTemplate(this.schema.template, this.template_engine); this.refreshValue(); } else { this.refreshValue(); } }, enable: function() { if(!this.always_disabled) { this.input.disabled = false; // TODO: WYSIWYG and Markdown editors } this._super(); }, disable: function() { this.input.disabled = true; // TODO: WYSIWYG and Markdown editors this._super(); }, afterInputReady: function() { var self = this, options; // Code editor if(this.source_code) { // WYSIWYG html and bbcode editor if(this.options.wysiwyg && ['html','bbcode'].indexOf(this.input_type) >= 0 && window.jQuery && window.jQuery.fn && window.jQuery.fn.sceditor ) { options = $extend({},{ plugins: self.input_type==='html'? 'xhtml' : 'bbcode', emoticonsEnabled: false, width: '100%', height: 300 },JSONEditor.plugins.sceditor,self.options.sceditor_options||{}); window.jQuery(self.input).sceditor(options); self.sceditor_instance = window.jQuery(self.input).sceditor('instance'); self.sceditor_instance.blur(function() { // Get editor's value var val = window.jQuery("<div>"+self.sceditor_instance.val()+"</div>"); // Remove sceditor spans/divs window.jQuery('#sceditor-start-marker,#sceditor-end-marker,.sceditor-nlf',val).remove(); // Set the value and update self.input.value = val.html(); self.value = self.input.value; self.is_dirty = true; self.onChange(true); }); } // EpicEditor for markdown (if it's loaded) else if (this.input_type === 'markdown' && window.EpicEditor) { this.epiceditor_container = document.createElement('div'); this.input.parentNode.insertBefore(this.epiceditor_container,this.input); this.input.style.display = 'none'; options = $extend({},JSONEditor.plugins.epiceditor,{ container: this.epiceditor_container, clientSideStorage: false }); this.epiceditor = new window.EpicEditor(options).load(); this.epiceditor.importFile(null,this.getValue()); this.epiceditor.on('update',function() { var val = self.epiceditor.exportFile(); self.input.value = val; self.value = val; self.is_dirty = true; self.onChange(true); }); } // ACE editor for everything else else if(window.ace) { var mode = this.input_type; // aliases for c/cpp if(mode === 'cpp' || mode === 'c++' || mode === 'c') { mode = 'c_cpp'; } this.ace_container = document.createElement('div'); this.ace_container.style.width = '100%'; this.ace_container.style.position = 'relative'; this.ace_container.style.height = '400px'; this.input.parentNode.insertBefore(this.ace_container,this.input); this.input.style.display = 'none'; this.ace_editor = window.ace.edit(this.ace_container); this.ace_editor.setValue(this.getValue()); // The theme if(JSONEditor.plugins.ace.theme) this.ace_editor.setTheme('ace/theme/'+JSONEditor.plugins.ace.theme); // The mode mode = window.ace.require("ace/mode/"+mode); if(mode) this.ace_editor.getSession().setMode(new mode.Mode()); // Listen for changes this.ace_editor.on('change',function() { var val = self.ace_editor.getValue(); self.input.value = val; self.refreshValue(); self.is_dirty = true; self.onChange(true); }); } } self.theme.afterInputReady(self.input); }, refreshValue: function() { this.value = this.input.value; if(typeof this.value !== "string") this.value = ''; this.serialized = this.value; }, destroy: function() { // If using SCEditor, destroy the editor instance if(this.sceditor_instance) { this.sceditor_instance.destroy(); } else if(this.epiceditor) { this.epiceditor.unload(); } else if(this.ace_editor) { this.ace_editor.destroy(); } this.template = null; if(this.input && this.input.parentNode) this.input.parentNode.removeChild(this.input); if(this.label && this.label.parentNode) this.label.parentNode.removeChild(this.label); if(this.description && this.description.parentNode) this.description.parentNode.removeChild(this.description); this._super(); }, /** * This is overridden in derivative editors */ sanitize: function(value) { return value; }, /** * Re-calculates the value if needed */ onWatchedFieldChange: function() { var self = this, vars, j; // If this editor needs to be rendered by a macro template if(this.template) { vars = this.getWatchedFieldValues(); this.setValue(this.template(vars),false,true); } this._super(); }, showValidationErrors: function(errors) { var self = this; if(this.jsoneditor.options.show_errors === "always") {} else if(!this.is_dirty && this.previous_error_setting===this.jsoneditor.options.show_errors) return; this.previous_error_setting = this.jsoneditor.options.show_errors; var messages = []; $each(errors,function(i,error) { if(error.path === self.path) { messages.push(error.message); } }); if(messages.length) { this.theme.addInputError(this.input, messages.join('. ')+'.'); } else { this.theme.removeInputError(this.input); } } });