Run lebab: convert let/const and arrow functions

This commit is contained in:
jos 2019-08-28 13:37:27 +02:00
parent d1a858548d
commit 531ddc5c74
27 changed files with 1310 additions and 1395 deletions

View File

@ -1,8 +1,8 @@
'use strict' 'use strict'
var createAbsoluteAnchor = require('./createAbsoluteAnchor').createAbsoluteAnchor const createAbsoluteAnchor = require('./createAbsoluteAnchor').createAbsoluteAnchor
var util = require('./util') const util = require('./util')
var translate = require('./i18n').translate const translate = require('./i18n').translate
/** /**
* A context menu * A context menu
@ -16,8 +16,8 @@ var translate = require('./i18n').translate
function ContextMenu (items, options) { function ContextMenu (items, options) {
this.dom = {} this.dom = {}
var me = this const me = this
var dom = this.dom const dom = this.dom
this.anchor = undefined this.anchor = undefined
this.items = items this.items = items
this.eventListeners = {} this.eventListeners = {}
@ -25,51 +25,51 @@ function ContextMenu (items, options) {
this.onClose = options ? options.close : undefined this.onClose = options ? options.close : undefined
// create root element // create root element
var root = document.createElement('div') const root = document.createElement('div')
root.className = 'jsoneditor-contextmenu-root' root.className = 'jsoneditor-contextmenu-root'
dom.root = root dom.root = root
// create a container element // create a container element
var menu = document.createElement('div') const menu = document.createElement('div')
menu.className = 'jsoneditor-contextmenu' menu.className = 'jsoneditor-contextmenu'
dom.menu = menu dom.menu = menu
root.appendChild(menu) root.appendChild(menu)
// create a list to hold the menu items // create a list to hold the menu items
var list = document.createElement('ul') const list = document.createElement('ul')
list.className = 'jsoneditor-menu' list.className = 'jsoneditor-menu'
menu.appendChild(list) menu.appendChild(list)
dom.list = list dom.list = list
dom.items = [] // list with all buttons dom.items = [] // list with all buttons
// create a (non-visible) button to set the focus to the menu // create a (non-visible) button to set the focus to the menu
var focusButton = document.createElement('button') const focusButton = document.createElement('button')
focusButton.type = 'button' focusButton.type = 'button'
dom.focusButton = focusButton dom.focusButton = focusButton
var li = document.createElement('li') const li = document.createElement('li')
li.style.overflow = 'hidden' li.style.overflow = 'hidden'
li.style.height = '0' li.style.height = '0'
li.appendChild(focusButton) li.appendChild(focusButton)
list.appendChild(li) list.appendChild(li)
function createMenuItems (list, domItems, items) { function createMenuItems (list, domItems, items) {
items.forEach(function (item) { items.forEach(item => {
if (item.type === 'separator') { if (item.type === 'separator') {
// create a separator // create a separator
var separator = document.createElement('div') const separator = document.createElement('div')
separator.className = 'jsoneditor-separator' separator.className = 'jsoneditor-separator'
const li = document.createElement('li') const li = document.createElement('li')
li.appendChild(separator) li.appendChild(separator)
list.appendChild(li) list.appendChild(li)
} else { } else {
var domItem = {} const domItem = {}
// create a menu item // create a menu item
const li = document.createElement('li') const li = document.createElement('li')
list.appendChild(li) list.appendChild(li)
// create a button in the menu item // create a button in the menu item
var button = document.createElement('button') const button = document.createElement('button')
button.type = 'button' button.type = 'button'
button.className = item.className button.className = item.className
domItem.button = button domItem.button = button
@ -77,7 +77,7 @@ function ContextMenu (items, options) {
button.title = item.title button.title = item.title
} }
if (item.click) { if (item.click) {
button.onclick = function (event) { button.onclick = event => {
event.preventDefault() event.preventDefault()
me.hide() me.hide()
item.click() item.click()
@ -88,21 +88,21 @@ function ContextMenu (items, options) {
// create the contents of the button // create the contents of the button
if (item.submenu) { if (item.submenu) {
// add the icon to the button // add the icon to the button
var divIcon = document.createElement('div') const divIcon = document.createElement('div')
divIcon.className = 'jsoneditor-icon' divIcon.className = 'jsoneditor-icon'
button.appendChild(divIcon) button.appendChild(divIcon)
var divText = document.createElement('div') const divText = document.createElement('div')
divText.className = 'jsoneditor-text' + divText.className = 'jsoneditor-text' +
(item.click ? '' : ' jsoneditor-right-margin') (item.click ? '' : ' jsoneditor-right-margin')
divText.appendChild(document.createTextNode(item.text)) divText.appendChild(document.createTextNode(item.text))
button.appendChild(divText) button.appendChild(divText)
var buttonSubmenu let buttonSubmenu
if (item.click) { if (item.click) {
// submenu and a button with a click handler // submenu and a button with a click handler
button.className += ' jsoneditor-default' button.className += ' jsoneditor-default'
var buttonExpand = document.createElement('button') const buttonExpand = document.createElement('button')
buttonExpand.type = 'button' buttonExpand.type = 'button'
domItem.buttonExpand = buttonExpand domItem.buttonExpand = buttonExpand
buttonExpand.className = 'jsoneditor-expand' buttonExpand.className = 'jsoneditor-expand'
@ -115,7 +115,7 @@ function ContextMenu (items, options) {
buttonSubmenu = buttonExpand buttonSubmenu = buttonExpand
} else { } else {
// submenu and a button without a click handler // submenu and a button without a click handler
var divExpand = document.createElement('div') const divExpand = document.createElement('div')
divExpand.className = 'jsoneditor-expand' divExpand.className = 'jsoneditor-expand'
button.appendChild(divExpand) button.appendChild(divExpand)
@ -123,16 +123,16 @@ function ContextMenu (items, options) {
} }
// attach a handler to expand/collapse the submenu // attach a handler to expand/collapse the submenu
buttonSubmenu.onclick = function (event) { buttonSubmenu.onclick = event => {
event.preventDefault() event.preventDefault()
me._onExpandItem(domItem) me._onExpandItem(domItem)
buttonSubmenu.focus() buttonSubmenu.focus()
} }
// create the submenu // create the submenu
var domSubItems = [] const domSubItems = []
domItem.subItems = domSubItems domItem.subItems = domSubItems
var ul = document.createElement('ul') const ul = document.createElement('ul')
domItem.ul = ul domItem.ul = ul
ul.className = 'jsoneditor-menu' ul.className = 'jsoneditor-menu'
ul.style.height = '0' ul.style.height = '0'
@ -154,8 +154,8 @@ function ContextMenu (items, options) {
// calculate the max height of the menu with one submenu expanded // calculate the max height of the menu with one submenu expanded
this.maxHeight = 0 // height in pixels this.maxHeight = 0 // height in pixels
items.forEach(function (item) { items.forEach(item => {
var height = (items.length + (item.submenu ? item.submenu.length : 0)) * 24 const height = (items.length + (item.submenu ? item.submenu.length : 0)) * 24
me.maxHeight = Math.max(me.maxHeight, height) me.maxHeight = Math.max(me.maxHeight, height)
}) })
} }
@ -166,15 +166,15 @@ function ContextMenu (items, options) {
* @private * @private
*/ */
ContextMenu.prototype._getVisibleButtons = function () { ContextMenu.prototype._getVisibleButtons = function () {
var buttons = [] const buttons = []
var me = this const me = this
this.dom.items.forEach(function (item) { this.dom.items.forEach(item => {
buttons.push(item.button) buttons.push(item.button)
if (item.buttonExpand) { if (item.buttonExpand) {
buttons.push(item.buttonExpand) buttons.push(item.buttonExpand)
} }
if (item.subItems && item === me.expandedItem) { if (item.subItems && item === me.expandedItem) {
item.subItems.forEach(function (subItem) { item.subItems.forEach(subItem => {
buttons.push(subItem.button) buttons.push(subItem.button)
if (subItem.buttonExpand) { if (subItem.buttonExpand) {
buttons.push(subItem.buttonExpand) buttons.push(subItem.buttonExpand)
@ -200,14 +200,14 @@ ContextMenu.prototype.show = function (anchor, frame, ignoreParent) {
this.hide() this.hide()
// determine whether to display the menu below or above the anchor // determine whether to display the menu below or above the anchor
var showBelow = true let showBelow = true
var parent = anchor.parentNode const parent = anchor.parentNode
var anchorRect = anchor.getBoundingClientRect() const anchorRect = anchor.getBoundingClientRect()
var parentRect = parent.getBoundingClientRect() const parentRect = parent.getBoundingClientRect()
var frameRect = frame.getBoundingClientRect() const frameRect = frame.getBoundingClientRect()
var me = this const me = this
this.dom.absoluteAnchor = createAbsoluteAnchor(anchor, frame, function () { this.dom.absoluteAnchor = createAbsoluteAnchor(anchor, frame, () => {
me.hide() me.hide()
}) })
@ -220,12 +220,12 @@ ContextMenu.prototype.show = function (anchor, frame, ignoreParent) {
// doesn't fit above nor below -> show below // doesn't fit above nor below -> show below
} }
var topGap = ignoreParent ? 0 : (anchorRect.top - parentRect.top) const topGap = ignoreParent ? 0 : (anchorRect.top - parentRect.top)
// position the menu // position the menu
if (showBelow) { if (showBelow) {
// display the menu below the anchor // display the menu below the anchor
var anchorHeight = anchor.offsetHeight const anchorHeight = anchor.offsetHeight
this.dom.menu.style.left = '0' this.dom.menu.style.left = '0'
this.dom.menu.style.top = topGap + anchorHeight + 'px' this.dom.menu.style.top = topGap + anchorHeight + 'px'
this.dom.menu.style.bottom = '' this.dom.menu.style.bottom = ''
@ -243,7 +243,7 @@ ContextMenu.prototype.show = function (anchor, frame, ignoreParent) {
// move focus to the first button in the context menu // move focus to the first button in the context menu
this.selection = util.getSelection() this.selection = util.getSelection()
this.anchor = anchor this.anchor = anchor
setTimeout(function () { setTimeout(() => {
me.dom.focusButton.focus() me.dom.focusButton.focus()
}, 0) }, 0)
@ -283,16 +283,16 @@ ContextMenu.prototype.hide = function () {
* @private * @private
*/ */
ContextMenu.prototype._onExpandItem = function (domItem) { ContextMenu.prototype._onExpandItem = function (domItem) {
var me = this const me = this
var alreadyVisible = (domItem === this.expandedItem) const alreadyVisible = (domItem === this.expandedItem)
// hide the currently visible submenu // hide the currently visible submenu
var expandedItem = this.expandedItem const expandedItem = this.expandedItem
if (expandedItem) { if (expandedItem) {
// var ul = expandedItem.ul; // var ul = expandedItem.ul;
expandedItem.ul.style.height = '0' expandedItem.ul.style.height = '0'
expandedItem.ul.style.padding = '' expandedItem.ul.style.padding = ''
setTimeout(function () { setTimeout(() => {
if (me.expandedItem !== expandedItem) { if (me.expandedItem !== expandedItem) {
expandedItem.ul.style.display = '' expandedItem.ul.style.display = ''
util.removeClassName(expandedItem.ul.parentNode, 'jsoneditor-selected') util.removeClassName(expandedItem.ul.parentNode, 'jsoneditor-selected')
@ -302,14 +302,14 @@ ContextMenu.prototype._onExpandItem = function (domItem) {
} }
if (!alreadyVisible) { if (!alreadyVisible) {
var ul = domItem.ul const ul = domItem.ul
ul.style.display = 'block' ul.style.display = 'block'
// eslint-disable-next-line no-unused-expressions // eslint-disable-next-line no-unused-expressions
ul.clientHeight // force a reflow in Firefox ul.clientHeight // force a reflow in Firefox
setTimeout(function () { setTimeout(() => {
if (me.expandedItem === domItem) { if (me.expandedItem === domItem) {
var childsHeight = 0 let childsHeight = 0
for (var i = 0; i < ul.childNodes.length; i++) { for (let i = 0; i < ul.childNodes.length; i++) {
childsHeight += ul.childNodes[i].clientHeight childsHeight += ul.childNodes[i].clientHeight
} }
ul.style.height = childsHeight + 'px' ul.style.height = childsHeight + 'px'
@ -327,10 +327,10 @@ ContextMenu.prototype._onExpandItem = function (domItem) {
* @private * @private
*/ */
ContextMenu.prototype._onKeyDown = function (event) { ContextMenu.prototype._onKeyDown = function (event) {
var target = event.target const target = event.target
var keynum = event.which const keynum = event.which
var handled = false let handled = false
var buttons, targetIndex, prevButton, nextButton let buttons, targetIndex, prevButton, nextButton
if (keynum === 27) { // ESC if (keynum === 27) { // ESC
// hide the menu on ESC key // hide the menu on ESC key

View File

@ -10,28 +10,28 @@
function ErrorTable (config) { function ErrorTable (config) {
this.errorTableVisible = config.errorTableVisible this.errorTableVisible = config.errorTableVisible
this.onToggleVisibility = config.onToggleVisibility this.onToggleVisibility = config.onToggleVisibility
this.onFocusLine = config.onFocusLine || function () {} this.onFocusLine = config.onFocusLine || (() => {})
this.onChangeHeight = config.onChangeHeight this.onChangeHeight = config.onChangeHeight
this.dom = {} this.dom = {}
var validationErrorsContainer = document.createElement('div') const validationErrorsContainer = document.createElement('div')
validationErrorsContainer.className = 'jsoneditor-validation-errors-container' validationErrorsContainer.className = 'jsoneditor-validation-errors-container'
this.dom.validationErrorsContainer = validationErrorsContainer this.dom.validationErrorsContainer = validationErrorsContainer
var additionalErrorsIndication = document.createElement('div') const additionalErrorsIndication = document.createElement('div')
additionalErrorsIndication.style.display = 'none' additionalErrorsIndication.style.display = 'none'
additionalErrorsIndication.className = 'jsoneditor-additional-errors fadein' additionalErrorsIndication.className = 'jsoneditor-additional-errors fadein'
additionalErrorsIndication.innerHTML = 'Scroll for more &#9663;' additionalErrorsIndication.innerHTML = 'Scroll for more &#9663;'
this.dom.additionalErrorsIndication = additionalErrorsIndication this.dom.additionalErrorsIndication = additionalErrorsIndication
validationErrorsContainer.appendChild(additionalErrorsIndication) validationErrorsContainer.appendChild(additionalErrorsIndication)
var validationErrorIcon = document.createElement('span') const validationErrorIcon = document.createElement('span')
validationErrorIcon.className = 'jsoneditor-validation-error-icon' validationErrorIcon.className = 'jsoneditor-validation-error-icon'
validationErrorIcon.style.display = 'none' validationErrorIcon.style.display = 'none'
this.dom.validationErrorIcon = validationErrorIcon this.dom.validationErrorIcon = validationErrorIcon
var validationErrorCount = document.createElement('span') const validationErrorCount = document.createElement('span')
validationErrorCount.className = 'jsoneditor-validation-error-count' validationErrorCount.className = 'jsoneditor-validation-error-count'
validationErrorCount.style.display = 'none' validationErrorCount.style.display = 'none'
this.dom.validationErrorCount = validationErrorCount this.dom.validationErrorCount = validationErrorCount
@ -63,7 +63,7 @@ ErrorTable.prototype.toggleTableVisibility = function () {
} }
ErrorTable.prototype.setErrors = function (errors, errorLocations) { ErrorTable.prototype.setErrors = function (errors, errorLocations) {
var me = this const me = this
// clear any previous errors // clear any previous errors
if (this.dom.validationErrors) { if (this.dom.validationErrors) {
@ -75,13 +75,13 @@ ErrorTable.prototype.setErrors = function (errors, errorLocations) {
// create the table with errors // create the table with errors
// keep default behavior for parse errors // keep default behavior for parse errors
if (this.errorTableVisible && errors.length > 0) { if (this.errorTableVisible && errors.length > 0) {
var validationErrors = document.createElement('div') const validationErrors = document.createElement('div')
validationErrors.className = 'jsoneditor-validation-errors' validationErrors.className = 'jsoneditor-validation-errors'
validationErrors.innerHTML = '<table class="jsoneditor-text-errors"><tbody></tbody></table>' validationErrors.innerHTML = '<table class="jsoneditor-text-errors"><tbody></tbody></table>'
var tbody = validationErrors.getElementsByTagName('tbody')[0] const tbody = validationErrors.getElementsByTagName('tbody')[0]
errors.forEach(function (error) { errors.forEach(error => {
var message let message
if (typeof error === 'string') { if (typeof error === 'string') {
message = '<td colspan="2"><pre>' + error + '</pre></td>' message = '<td colspan="2"><pre>' + error + '</pre></td>'
} else { } else {
@ -90,18 +90,18 @@ ErrorTable.prototype.setErrors = function (errors, errorLocations) {
'<td><pre>' + error.message + '</pre></td>' '<td><pre>' + error.message + '</pre></td>'
} }
var line let line
if (!isNaN(error.line)) { if (!isNaN(error.line)) {
line = error.line line = error.line
} else if (error.dataPath) { } else if (error.dataPath) {
var errLoc = errorLocations.find(function (loc) { return loc.path === error.dataPath }) const errLoc = errorLocations.find(loc => loc.path === error.dataPath)
if (errLoc) { if (errLoc) {
line = errLoc.line + 1 line = errLoc.line + 1
} }
} }
var trEl = document.createElement('tr') const trEl = document.createElement('tr')
trEl.className = !isNaN(line) ? 'jump-to-line' : '' trEl.className = !isNaN(line) ? 'jump-to-line' : ''
if (error.type === 'error') { if (error.type === 'error') {
trEl.className += ' parse-error' trEl.className += ' parse-error'
@ -110,7 +110,7 @@ ErrorTable.prototype.setErrors = function (errors, errorLocations) {
} }
trEl.innerHTML = ('<td><button class="jsoneditor-schema-error"></button></td><td style="white-space:nowrap;">' + (!isNaN(line) ? ('Ln ' + line) : '') + '</td>' + message) trEl.innerHTML = ('<td><button class="jsoneditor-schema-error"></button></td><td style="white-space:nowrap;">' + (!isNaN(line) ? ('Ln ' + line) : '') + '</td>' + message)
trEl.onclick = function () { trEl.onclick = () => {
me.onFocusLine(line) me.onFocusLine(line)
} }
@ -123,7 +123,7 @@ ErrorTable.prototype.setErrors = function (errors, errorLocations) {
if (this.dom.validationErrorsContainer.clientHeight < this.dom.validationErrorsContainer.scrollHeight) { if (this.dom.validationErrorsContainer.clientHeight < this.dom.validationErrorsContainer.scrollHeight) {
this.dom.additionalErrorsIndication.style.display = 'block' this.dom.additionalErrorsIndication.style.display = 'block'
this.dom.validationErrorsContainer.onscroll = function () { this.dom.validationErrorsContainer.onscroll = () => {
me.dom.additionalErrorsIndication.style.display = me.dom.additionalErrorsIndication.style.display =
(me.dom.validationErrorsContainer.clientHeight > 0 && me.dom.validationErrorsContainer.scrollTop === 0) ? 'block' : 'none' (me.dom.validationErrorsContainer.clientHeight > 0 && me.dom.validationErrorsContainer.scrollTop === 0) ? 'block' : 'none'
} }
@ -131,7 +131,7 @@ ErrorTable.prototype.setErrors = function (errors, errorLocations) {
this.dom.validationErrorsContainer.onscroll = undefined this.dom.validationErrorsContainer.onscroll = undefined
} }
var height = this.dom.validationErrorsContainer.clientHeight + (this.dom.statusBar ? this.dom.statusBar.clientHeight : 0) const height = this.dom.validationErrorsContainer.clientHeight + (this.dom.statusBar ? this.dom.statusBar.clientHeight : 0)
// this.content.style.marginBottom = (-height) + 'px'; // this.content.style.marginBottom = (-height) + 'px';
// this.content.style.paddingBottom = height + 'px'; // this.content.style.paddingBottom = height + 'px';
this.onChangeHeight(height) this.onChangeHeight(height)
@ -140,9 +140,7 @@ ErrorTable.prototype.setErrors = function (errors, errorLocations) {
} }
// update the status bar // update the status bar
var validationErrorsCount = errors.filter(function (error) { const validationErrorsCount = errors.filter(error => error.type !== 'error').length
return error.type !== 'error'
}).length
if (validationErrorsCount > 0) { if (validationErrorsCount > 0) {
this.dom.validationErrorCount.style.display = 'inline' this.dom.validationErrorCount.style.display = 'inline'
this.dom.validationErrorCount.innerText = validationErrorsCount this.dom.validationErrorCount.innerText = validationErrorsCount
@ -157,11 +155,9 @@ ErrorTable.prototype.setErrors = function (errors, errorLocations) {
} }
// update the parse error icon // update the parse error icon
var hasParseErrors = errors.some(function (error) { const hasParseErrors = errors.some(error => error.type === 'error')
return error.type === 'error'
})
if (hasParseErrors) { if (hasParseErrors) {
var line = errors[0].line const line = errors[0].line
this.dom.parseErrorIndication.style.display = 'block' this.dom.parseErrorIndication.style.display = 'block'
this.dom.parseErrorIndication.title = !isNaN(line) this.dom.parseErrorIndication.title = !isNaN(line)
? ('parse error on line ' + line) ? ('parse error on line ' + line)

View File

@ -42,14 +42,14 @@ Highlighter.prototype.unhighlight = function () {
return return
} }
var me = this const me = this
if (this.node) { if (this.node) {
this._cancelUnhighlight() this._cancelUnhighlight()
// do the unhighlighting after a small delay, to prevent re-highlighting // do the unhighlighting after a small delay, to prevent re-highlighting
// the same node when moving from the drag-icon to the contextmenu-icon // the same node when moving from the drag-icon to the contextmenu-icon
// or vice versa. // or vice versa.
this.unhighlightTimer = setTimeout(function () { this.unhighlightTimer = setTimeout(() => {
me.node.setHighlight(false) me.node.setHighlight(false)
me.node = undefined me.node = undefined
me.unhighlightTimer = undefined me.unhighlightTimer = undefined

View File

@ -8,9 +8,7 @@
*/ */
function History (onChange, calculateItemSize, limit) { function History (onChange, calculateItemSize, limit) {
this.onChange = onChange this.onChange = onChange
this.calculateItemSize = calculateItemSize || function () { this.calculateItemSize = calculateItemSize || (() => 1)
return 1
}
this.limit = limit this.limit = limit
this.items = [] this.items = []
@ -35,10 +33,10 @@ History.prototype.add = function (item) {
} }
History.prototype._calculateHistorySize = function () { History.prototype._calculateHistorySize = function () {
var calculateItemSize = this.calculateItemSize const calculateItemSize = this.calculateItemSize
var totalSize = 0 let totalSize = 0
this.items.forEach(function (item) { this.items.forEach(item => {
totalSize += calculateItemSize(item) totalSize += calculateItemSize(item)
}) })

View File

@ -1,19 +1,19 @@
'use strict' 'use strict'
var Ajv let Ajv
try { try {
Ajv = require('ajv') Ajv = require('ajv')
} catch (err) { } catch (err) {
// no problem... when we need Ajv we will throw a neat exception // no problem... when we need Ajv we will throw a neat exception
} }
var ace = require('./ace') // may be undefined in case of minimalist bundle const ace = require('./ace') // may be undefined in case of minimalist bundle
var VanillaPicker = require('./vanilla-picker') // may be undefined in case of minimalist bundle const VanillaPicker = require('./vanilla-picker') // may be undefined in case of minimalist bundle
var treemode = require('./treemode') const treemode = require('./treemode')
var textmode = require('./textmode') const textmode = require('./textmode')
var previewmode = require('./previewmode') const previewmode = require('./previewmode')
var util = require('./util') const util = require('./util')
if (typeof Promise === 'undefined') { if (typeof Promise === 'undefined') {
console.error('Promise undefined. Please load a Promise polyfill in the browser in order to use JSONEditor') console.error('Promise undefined. Please load a Promise polyfill in the browser in order to use JSONEditor')
@ -101,7 +101,7 @@ function JSONEditor (container, options, json) {
} }
// check for unsupported browser (IE8 and older) // check for unsupported browser (IE8 and older)
var ieVersion = util.getInternetExplorerVersion() const ieVersion = util.getInternetExplorerVersion()
if (ieVersion !== -1 && ieVersion < 9) { if (ieVersion !== -1 && ieVersion < 9) {
throw new Error('Unsupported browser, IE9 or newer required. ' + throw new Error('Unsupported browser, IE9 or newer required. ' +
'Please install the newest version of your browser.') 'Please install the newest version of your browser.')
@ -136,7 +136,7 @@ function JSONEditor (container, options, json) {
// validate options // validate options
if (options) { if (options) {
Object.keys(options).forEach(function (option) { Object.keys(options).forEach(option => {
if (JSONEditor.VALID_OPTIONS.indexOf(option) === -1) { if (JSONEditor.VALID_OPTIONS.indexOf(option) === -1) {
console.warn('Unknown option "' + option + '". This option will be ignored') console.warn('Unknown option "' + option + '". This option will be ignored')
} }
@ -194,14 +194,14 @@ JSONEditor.prototype._create = function (container, options, json) {
this.options = options || {} this.options = options || {}
this.json = json || {} this.json = json || {}
var mode = this.options.mode || (this.options.modes && this.options.modes[0]) || 'tree' const mode = this.options.mode || (this.options.modes && this.options.modes[0]) || 'tree'
this.setMode(mode) this.setMode(mode)
} }
/** /**
* Destroy the editor. Clean up DOM, event listeners, and web workers. * Destroy the editor. Clean up DOM, event listeners, and web workers.
*/ */
JSONEditor.prototype.destroy = function () {} JSONEditor.prototype.destroy = () => {}
/** /**
* Set JSON object in editor * Set JSON object in editor
@ -266,17 +266,17 @@ JSONEditor.prototype.setMode = function (mode) {
return return
} }
var container = this.container const container = this.container
var options = util.extend({}, this.options) const options = util.extend({}, this.options)
var oldMode = options.mode const oldMode = options.mode
var data let data
var name let name
options.mode = mode options.mode = mode
var config = JSONEditor.modes[mode] const config = JSONEditor.modes[mode]
if (config) { if (config) {
try { try {
var asText = (config.data === 'text') const asText = (config.data === 'text')
name = this.getName() name = this.getName()
data = this[asText ? 'getText' : 'get']() // get text or json data = this[asText ? 'getText' : 'get']() // get text or json
@ -343,7 +343,7 @@ JSONEditor.prototype._onError = function (err) {
JSONEditor.prototype.setSchema = function (schema, schemaRefs) { JSONEditor.prototype.setSchema = function (schema, schemaRefs) {
// compile a JSON schema validator if a JSON schema is provided // compile a JSON schema validator if a JSON schema is provided
if (schema) { if (schema) {
var ajv let ajv
try { try {
// grab ajv from options if provided, else create a new instance // grab ajv from options if provided, else create a new instance
if (this.options.ajv) { if (this.options.ajv) {
@ -366,7 +366,7 @@ JSONEditor.prototype.setSchema = function (schema, schemaRefs) {
if (ajv) { if (ajv) {
if (schemaRefs) { if (schemaRefs) {
for (var ref in schemaRefs) { for (const ref in schemaRefs) {
ajv.removeSchema(ref) // When updating a schema - old refs has to be removed first ajv.removeSchema(ref) // When updating a schema - old refs has to be removed first
if (schemaRefs[ref]) { if (schemaRefs[ref]) {
ajv.addSchema(schemaRefs[ref], ref) ajv.addSchema(schemaRefs[ref], ref)
@ -399,14 +399,14 @@ JSONEditor.prototype.setSchema = function (schema, schemaRefs) {
* Validate current JSON object against the configured JSON schema * Validate current JSON object against the configured JSON schema
* Throws an exception when no JSON schema is configured * Throws an exception when no JSON schema is configured
*/ */
JSONEditor.prototype.validate = function () { JSONEditor.prototype.validate = () => {
// must be implemented by treemode and textmode // must be implemented by treemode and textmode
} }
/** /**
* Refresh the rendered contents * Refresh the rendered contents
*/ */
JSONEditor.prototype.refresh = function () { JSONEditor.prototype.refresh = () => {
// can be implemented by treemode and textmode // can be implemented by treemode and textmode
} }
@ -429,8 +429,8 @@ JSONEditor.prototype.refresh = function () {
* *
* @param {Object | Array} mode A mode object or an array with multiple mode objects. * @param {Object | Array} mode A mode object or an array with multiple mode objects.
*/ */
JSONEditor.registerMode = function (mode) { JSONEditor.registerMode = mode => {
var i, prop let i, prop
if (util.isArray(mode)) { if (util.isArray(mode)) {
// multiple modes // multiple modes
@ -442,7 +442,7 @@ JSONEditor.registerMode = function (mode) {
if (!('mode' in mode)) throw new Error('Property "mode" missing') if (!('mode' in mode)) throw new Error('Property "mode" missing')
if (!('mixin' in mode)) throw new Error('Property "mixin" missing') if (!('mixin' in mode)) throw new Error('Property "mixin" missing')
if (!('data' in mode)) throw new Error('Property "data" missing') if (!('data' in mode)) throw new Error('Property "data" missing')
var name = mode.mode const name = mode.mode
if (name in JSONEditor.modes) { if (name in JSONEditor.modes) {
throw new Error('Mode "' + name + '" already registered') throw new Error('Mode "' + name + '" already registered')
} }
@ -451,7 +451,7 @@ JSONEditor.registerMode = function (mode) {
if (typeof mode.mixin.create !== 'function') { if (typeof mode.mixin.create !== 'function') {
throw new Error('Required function "create" missing on mixin') throw new Error('Required function "create" missing on mixin')
} }
var reserved = ['setMode', 'registerMode', 'modes'] const reserved = ['setMode', 'registerMode', 'modes']
for (i = 0; i < reserved.length; i++) { for (i = 0; i < reserved.length; i++) {
prop = reserved[i] prop = reserved[i]
if (prop in mode.mixin) { if (prop in mode.mixin) {

View File

@ -1,7 +1,7 @@
'use strict' 'use strict'
var ContextMenu = require('./ContextMenu') const ContextMenu = require('./ContextMenu')
var translate = require('./i18n').translate const translate = require('./i18n').translate
/** /**
* Create a select box to be used in the editor menu's, which allows to switch mode * Create a select box to be used in the editor menu's, which allows to switch mode
@ -13,7 +13,7 @@ var translate = require('./i18n').translate
*/ */
function ModeSwitcher (container, modes, current, onSwitch) { function ModeSwitcher (container, modes, current, onSwitch) {
// available modes // available modes
var availableModes = { const availableModes = {
code: { code: {
text: translate('modeCodeText'), text: translate('modeCodeText'),
title: translate('modeCodeTitle'), title: translate('modeCodeTitle'),
@ -59,10 +59,10 @@ function ModeSwitcher (container, modes, current, onSwitch) {
} }
// list the selected modes // list the selected modes
var items = [] const items = []
for (var i = 0; i < modes.length; i++) { for (let i = 0; i < modes.length; i++) {
var mode = modes[i] const mode = modes[i]
var item = availableModes[mode] const item = availableModes[mode]
if (!item) { if (!item) {
throw new Error('Unknown mode "' + mode + '"') throw new Error('Unknown mode "' + mode + '"')
} }
@ -72,24 +72,24 @@ function ModeSwitcher (container, modes, current, onSwitch) {
} }
// retrieve the title of current mode // retrieve the title of current mode
var currentMode = availableModes[current] const currentMode = availableModes[current]
if (!currentMode) { if (!currentMode) {
throw new Error('Unknown mode "' + current + '"') throw new Error('Unknown mode "' + current + '"')
} }
var currentTitle = currentMode.text const currentTitle = currentMode.text
// create the html element // create the html element
var box = document.createElement('button') const box = document.createElement('button')
box.type = 'button' box.type = 'button'
box.className = 'jsoneditor-modes jsoneditor-separator' box.className = 'jsoneditor-modes jsoneditor-separator'
box.innerHTML = currentTitle + ' &#x25BE;' box.innerHTML = currentTitle + ' &#x25BE;'
box.title = 'Switch editor mode' box.title = 'Switch editor mode'
box.onclick = function () { box.onclick = () => {
var menu = new ContextMenu(items) const menu = new ContextMenu(items)
menu.show(box, container) menu.show(box, container)
} }
var frame = document.createElement('div') const frame = document.createElement('div')
frame.className = 'jsoneditor-modes' frame.className = 'jsoneditor-modes'
frame.style.position = 'relative' frame.style.position = 'relative'
frame.appendChild(box) frame.appendChild(box)

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
'use strict' 'use strict'
var util = require('./util') const util = require('./util')
/** /**
* @constructor History * @constructor History
@ -23,13 +23,13 @@ function NodeHistory (editor) {
this.actions = { this.actions = {
editField: { editField: {
undo: function (params) { undo: function (params) {
var parentNode = findNode(params.parentPath) const parentNode = findNode(params.parentPath)
var node = parentNode.childs[params.index] const node = parentNode.childs[params.index]
node.updateField(params.oldValue) node.updateField(params.oldValue)
}, },
redo: function (params) { redo: function (params) {
var parentNode = findNode(params.parentPath) const parentNode = findNode(params.parentPath)
var node = parentNode.childs[params.index] const node = parentNode.childs[params.index]
node.updateField(params.newValue) node.updateField(params.newValue)
} }
}, },
@ -52,44 +52,44 @@ function NodeHistory (editor) {
appendNodes: { appendNodes: {
undo: function (params) { undo: function (params) {
var parentNode = findNode(params.parentPath) const parentNode = findNode(params.parentPath)
params.paths.map(findNode).forEach(function (node) { params.paths.map(findNode).forEach(node => {
parentNode.removeChild(node) parentNode.removeChild(node)
}) })
}, },
redo: function (params) { redo: function (params) {
var parentNode = findNode(params.parentPath) const parentNode = findNode(params.parentPath)
params.nodes.forEach(function (node) { params.nodes.forEach(node => {
parentNode.appendChild(node) parentNode.appendChild(node)
}) })
} }
}, },
insertBeforeNodes: { insertBeforeNodes: {
undo: function (params) { undo: function (params) {
var parentNode = findNode(params.parentPath) const parentNode = findNode(params.parentPath)
params.paths.map(findNode).forEach(function (node) { params.paths.map(findNode).forEach(node => {
parentNode.removeChild(node) parentNode.removeChild(node)
}) })
}, },
redo: function (params) { redo: function (params) {
var parentNode = findNode(params.parentPath) const parentNode = findNode(params.parentPath)
var beforeNode = findNode(params.beforePath) const beforeNode = findNode(params.beforePath)
params.nodes.forEach(function (node) { params.nodes.forEach(node => {
parentNode.insertBefore(node, beforeNode) parentNode.insertBefore(node, beforeNode)
}) })
} }
}, },
insertAfterNodes: { insertAfterNodes: {
undo: function (params) { undo: function (params) {
var parentNode = findNode(params.parentPath) const parentNode = findNode(params.parentPath)
params.paths.map(findNode).forEach(function (node) { params.paths.map(findNode).forEach(node => {
parentNode.removeChild(node) parentNode.removeChild(node)
}) })
}, },
redo: function (params) { redo: function (params) {
var parentNode = findNode(params.parentPath) const parentNode = findNode(params.parentPath)
var afterNode = findNode(params.afterPath) let afterNode = findNode(params.afterPath)
params.nodes.forEach(function (node) { params.nodes.forEach(node => {
parentNode.insertAfter(node, afterNode) parentNode.insertAfter(node, afterNode)
afterNode = node afterNode = node
}) })
@ -97,34 +97,34 @@ function NodeHistory (editor) {
}, },
removeNodes: { removeNodes: {
undo: function (params) { undo: function (params) {
var parentNode = findNode(params.parentPath) const parentNode = findNode(params.parentPath)
var beforeNode = parentNode.childs[params.index] || parentNode.append const beforeNode = parentNode.childs[params.index] || parentNode.append
params.nodes.forEach(function (node) { params.nodes.forEach(node => {
parentNode.insertBefore(node, beforeNode) parentNode.insertBefore(node, beforeNode)
}) })
}, },
redo: function (params) { redo: function (params) {
var parentNode = findNode(params.parentPath) const parentNode = findNode(params.parentPath)
params.paths.map(findNode).forEach(function (node) { params.paths.map(findNode).forEach(node => {
parentNode.removeChild(node) parentNode.removeChild(node)
}) })
} }
}, },
duplicateNodes: { duplicateNodes: {
undo: function (params) { undo: function (params) {
var parentNode = findNode(params.parentPath) const parentNode = findNode(params.parentPath)
params.clonePaths.map(findNode).forEach(function (node) { params.clonePaths.map(findNode).forEach(node => {
parentNode.removeChild(node) parentNode.removeChild(node)
}) })
}, },
redo: function (params) { redo: function (params) {
var parentNode = findNode(params.parentPath) const parentNode = findNode(params.parentPath)
var afterNode = findNode(params.afterPath) let afterNode = findNode(params.afterPath)
var nodes = params.paths.map(findNode) const nodes = params.paths.map(findNode)
nodes.forEach(function (node) { nodes.forEach(node => {
var clone = node.clone() const clone = node.clone()
if (parentNode.type === 'object') { if (parentNode.type === 'object') {
var existingFieldNames = parentNode.getFieldNames() const existingFieldNames = parentNode.getFieldNames()
clone.field = util.findUniqueName(node.field, existingFieldNames) clone.field = util.findUniqueName(node.field, existingFieldNames)
} }
parentNode.insertAfter(clone, afterNode) parentNode.insertAfter(clone, afterNode)
@ -134,14 +134,14 @@ function NodeHistory (editor) {
}, },
moveNodes: { moveNodes: {
undo: function (params) { undo: function (params) {
var oldParentNode = findNode(params.oldParentPath) const oldParentNode = findNode(params.oldParentPath)
var newParentNode = findNode(params.newParentPath) const newParentNode = findNode(params.newParentPath)
var oldBeforeNode = oldParentNode.childs[params.oldIndex] || oldParentNode.append const oldBeforeNode = oldParentNode.childs[params.oldIndex] || oldParentNode.append
// first copy the nodes, then move them // first copy the nodes, then move them
var nodes = newParentNode.childs.slice(params.newIndex, params.newIndex + params.count) const nodes = newParentNode.childs.slice(params.newIndex, params.newIndex + params.count)
nodes.forEach(function (node, index) { nodes.forEach((node, index) => {
node.field = params.fieldNames[index] node.field = params.fieldNames[index]
oldParentNode.moveBefore(node, oldBeforeNode) oldParentNode.moveBefore(node, oldBeforeNode)
}) })
@ -153,14 +153,14 @@ function NodeHistory (editor) {
} }
}, },
redo: function (params) { redo: function (params) {
var oldParentNode = findNode(params.oldParentPathRedo) const oldParentNode = findNode(params.oldParentPathRedo)
var newParentNode = findNode(params.newParentPathRedo) const newParentNode = findNode(params.newParentPathRedo)
var newBeforeNode = newParentNode.childs[params.newIndexRedo] || newParentNode.append const newBeforeNode = newParentNode.childs[params.newIndexRedo] || newParentNode.append
// first copy the nodes, then move them // first copy the nodes, then move them
var nodes = oldParentNode.childs.slice(params.oldIndexRedo, params.oldIndexRedo + params.count) const nodes = oldParentNode.childs.slice(params.oldIndexRedo, params.oldIndexRedo + params.count)
nodes.forEach(function (node, index) { nodes.forEach((node, index) => {
node.field = params.fieldNames[index] node.field = params.fieldNames[index]
newParentNode.moveBefore(node, newBeforeNode) newParentNode.moveBefore(node, newBeforeNode)
}) })
@ -169,14 +169,14 @@ function NodeHistory (editor) {
sort: { sort: {
undo: function (params) { undo: function (params) {
var node = findNode(params.path) const node = findNode(params.path)
node.hideChilds() node.hideChilds()
node.childs = params.oldChilds node.childs = params.oldChilds
node.updateDom({ updateIndexes: true }) node.updateDom({ updateIndexes: true })
node.showChilds() node.showChilds()
}, },
redo: function (params) { redo: function (params) {
var node = findNode(params.path) const node = findNode(params.path)
node.hideChilds() node.hideChilds()
node.childs = params.newChilds node.childs = params.newChilds
node.updateDom({ updateIndexes: true }) node.updateDom({ updateIndexes: true })
@ -206,7 +206,7 @@ function NodeHistory (editor) {
* The method onChange is executed when the History is changed, and can * The method onChange is executed when the History is changed, and can
* be overloaded. * be overloaded.
*/ */
NodeHistory.prototype.onChange = function () {} NodeHistory.prototype.onChange = () => {}
/** /**
* Add a new action to the history * Add a new action to the history
@ -268,9 +268,9 @@ NodeHistory.prototype.canRedo = function () {
*/ */
NodeHistory.prototype.undo = function () { NodeHistory.prototype.undo = function () {
if (this.canUndo()) { if (this.canUndo()) {
var obj = this.history[this.index] const obj = this.history[this.index]
if (obj) { if (obj) {
var action = this.actions[obj.action] const action = this.actions[obj.action]
if (action && action.undo) { if (action && action.undo) {
action.undo(obj.params) action.undo(obj.params)
if (obj.params.oldSelection) { if (obj.params.oldSelection) {
@ -298,9 +298,9 @@ NodeHistory.prototype.redo = function () {
if (this.canRedo()) { if (this.canRedo()) {
this.index++ this.index++
var obj = this.history[this.index] const obj = this.history[this.index]
if (obj) { if (obj) {
var action = this.actions[obj.action] const action = this.actions[obj.action]
if (action && action.redo) { if (action && action.redo) {
action.redo(obj.params) action.redo(obj.params)
if (obj.params.newSelection) { if (obj.params.newSelection) {

View File

@ -8,7 +8,7 @@
* create the search box * create the search box
*/ */
function SearchBox (editor, container) { function SearchBox (editor, container) {
var searchBox = this const searchBox = this
this.editor = editor this.editor = editor
this.timeout = undefined this.timeout = undefined
@ -18,65 +18,65 @@ function SearchBox (editor, container) {
this.dom = {} this.dom = {}
this.dom.container = container this.dom.container = container
var wrapper = document.createElement('div') const wrapper = document.createElement('div')
this.dom.wrapper = wrapper this.dom.wrapper = wrapper
wrapper.className = 'jsoneditor-search' wrapper.className = 'jsoneditor-search'
container.appendChild(wrapper) container.appendChild(wrapper)
var results = document.createElement('div') const results = document.createElement('div')
this.dom.results = results this.dom.results = results
results.className = 'jsoneditor-results' results.className = 'jsoneditor-results'
wrapper.appendChild(results) wrapper.appendChild(results)
var divInput = document.createElement('div') const divInput = document.createElement('div')
this.dom.input = divInput this.dom.input = divInput
divInput.className = 'jsoneditor-frame' divInput.className = 'jsoneditor-frame'
divInput.title = 'Search fields and values' divInput.title = 'Search fields and values'
wrapper.appendChild(divInput) wrapper.appendChild(divInput)
var refreshSearch = document.createElement('button') const refreshSearch = document.createElement('button')
refreshSearch.type = 'button' refreshSearch.type = 'button'
refreshSearch.className = 'jsoneditor-refresh' refreshSearch.className = 'jsoneditor-refresh'
divInput.appendChild(refreshSearch) divInput.appendChild(refreshSearch)
var search = document.createElement('input') const search = document.createElement('input')
search.type = 'text' search.type = 'text'
this.dom.search = search this.dom.search = search
search.oninput = function (event) { search.oninput = event => {
searchBox._onDelayedSearch(event) searchBox._onDelayedSearch(event)
} }
search.onchange = function (event) { search.onchange = event => {
// For IE 9 // For IE 9
searchBox._onSearch() searchBox._onSearch()
} }
search.onkeydown = function (event) { search.onkeydown = event => {
searchBox._onKeyDown(event) searchBox._onKeyDown(event)
} }
search.onkeyup = function (event) { search.onkeyup = event => {
searchBox._onKeyUp(event) searchBox._onKeyUp(event)
} }
refreshSearch.onclick = function (event) { refreshSearch.onclick = event => {
search.select() search.select()
} }
// TODO: ESC in FF restores the last input, is a FF bug, https://bugzilla.mozilla.org/show_bug.cgi?id=598819 // TODO: ESC in FF restores the last input, is a FF bug, https://bugzilla.mozilla.org/show_bug.cgi?id=598819
divInput.appendChild(search) divInput.appendChild(search)
var searchNext = document.createElement('button') const searchNext = document.createElement('button')
searchNext.type = 'button' searchNext.type = 'button'
searchNext.title = 'Next result (Enter)' searchNext.title = 'Next result (Enter)'
searchNext.className = 'jsoneditor-next' searchNext.className = 'jsoneditor-next'
searchNext.onclick = function () { searchNext.onclick = () => {
searchBox.next() searchBox.next()
} }
divInput.appendChild(searchNext) divInput.appendChild(searchNext)
var searchPrevious = document.createElement('button') const searchPrevious = document.createElement('button')
searchPrevious.type = 'button' searchPrevious.type = 'button'
searchPrevious.title = 'Previous result (Shift+Enter)' searchPrevious.title = 'Previous result (Shift+Enter)'
searchPrevious.className = 'jsoneditor-previous' searchPrevious.className = 'jsoneditor-previous'
searchPrevious.onclick = function () { searchPrevious.onclick = () => {
searchBox.previous() searchBox.previous()
} }
@ -90,7 +90,7 @@ function SearchBox (editor, container) {
*/ */
SearchBox.prototype.next = function (focus) { SearchBox.prototype.next = function (focus) {
if (this.results !== null) { if (this.results !== null) {
var index = this.resultIndex !== null ? this.resultIndex + 1 : 0 let index = this.resultIndex !== null ? this.resultIndex + 1 : 0
if (index > this.results.length - 1) { if (index > this.results.length - 1) {
index = 0 index = 0
} }
@ -105,8 +105,8 @@ SearchBox.prototype.next = function (focus) {
*/ */
SearchBox.prototype.previous = function (focus) { SearchBox.prototype.previous = function (focus) {
if (this.results !== null) { if (this.results !== null) {
var max = this.results.length - 1 const max = this.results.length - 1
var index = this.resultIndex !== null ? this.resultIndex - 1 : max let index = this.resultIndex !== null ? this.resultIndex - 1 : max
if (index < 0) { if (index < 0) {
index = max index = max
} }
@ -124,8 +124,8 @@ SearchBox.prototype.previous = function (focus) {
SearchBox.prototype._setActiveResult = function (index, focus) { SearchBox.prototype._setActiveResult = function (index, focus) {
// de-activate current active result // de-activate current active result
if (this.activeResult) { if (this.activeResult) {
var prevNode = this.activeResult.node const prevNode = this.activeResult.node
var prevElem = this.activeResult.elem const prevElem = this.activeResult.elem
if (prevElem === 'field') { if (prevElem === 'field') {
delete prevNode.searchFieldActive delete prevNode.searchFieldActive
} else { } else {
@ -144,8 +144,8 @@ SearchBox.prototype._setActiveResult = function (index, focus) {
this.resultIndex = index this.resultIndex = index
// set new node active // set new node active
var node = this.results[this.resultIndex].node const node = this.results[this.resultIndex].node
var elem = this.results[this.resultIndex].elem const elem = this.results[this.resultIndex].elem
if (elem === 'field') { if (elem === 'field') {
node.searchFieldActive = true node.searchFieldActive = true
} else { } else {
@ -155,7 +155,7 @@ SearchBox.prototype._setActiveResult = function (index, focus) {
node.updateDom() node.updateDom()
// TODO: not so nice that the focus is only set after the animation is finished // TODO: not so nice that the focus is only set after the animation is finished
node.scrollTo(function () { node.scrollTo(() => {
if (focus) { if (focus) {
node.focus(elem) node.focus(elem)
} }
@ -183,8 +183,8 @@ SearchBox.prototype._onDelayedSearch = function (event) {
// execute the search after a short delay (reduces the number of // execute the search after a short delay (reduces the number of
// search actions while typing in the search text box) // search actions while typing in the search text box)
this._clearDelay() this._clearDelay()
var searchBox = this const searchBox = this
this.timeout = setTimeout(function (event) { this.timeout = setTimeout(event => {
searchBox._onSearch() searchBox._onSearch()
}, this.delay) }, this.delay)
} }
@ -199,20 +199,20 @@ SearchBox.prototype._onDelayedSearch = function (event) {
SearchBox.prototype._onSearch = function (forceSearch) { SearchBox.prototype._onSearch = function (forceSearch) {
this._clearDelay() this._clearDelay()
var value = this.dom.search.value const value = this.dom.search.value
var text = value.length > 0 ? value : undefined const text = value.length > 0 ? value : undefined
if (text !== this.lastText || forceSearch) { if (text !== this.lastText || forceSearch) {
// only search again when changed // only search again when changed
this.lastText = text this.lastText = text
this.results = this.editor.search(text) this.results = this.editor.search(text)
var MAX_SEARCH_RESULTS = this.results[0] const MAX_SEARCH_RESULTS = this.results[0]
? this.results[0].node.MAX_SEARCH_RESULTS ? this.results[0].node.MAX_SEARCH_RESULTS
: Infinity : Infinity
// try to maintain the current active result if this is still part of the new search results // try to maintain the current active result if this is still part of the new search results
var activeResultIndex = 0 let activeResultIndex = 0
if (this.activeResult) { if (this.activeResult) {
for (var i = 0; i < this.results.length; i++) { for (let i = 0; i < this.results.length; i++) {
if (this.results[i].node === this.activeResult.node) { if (this.results[i].node === this.activeResult.node) {
activeResultIndex = i activeResultIndex = i
break break
@ -224,7 +224,7 @@ SearchBox.prototype._onSearch = function (forceSearch) {
// display search results // display search results
if (text !== undefined) { if (text !== undefined) {
var resultCount = this.results.length const resultCount = this.results.length
if (resultCount === 0) { if (resultCount === 0) {
this.dom.results.innerHTML = 'no&nbsp;results' this.dom.results.innerHTML = 'no&nbsp;results'
} else if (resultCount === 1) { } else if (resultCount === 1) {
@ -246,7 +246,7 @@ SearchBox.prototype._onSearch = function (forceSearch) {
* @private * @private
*/ */
SearchBox.prototype._onKeyDown = function (event) { SearchBox.prototype._onKeyDown = function (event) {
var keynum = event.which const keynum = event.which
if (keynum === 27) { if (keynum === 27) {
// ESC // ESC
this.dom.search.value = '' // clear search this.dom.search.value = '' // clear search
@ -276,7 +276,7 @@ SearchBox.prototype._onKeyDown = function (event) {
* @private * @private
*/ */
SearchBox.prototype._onKeyUp = function (event) { SearchBox.prototype._onKeyUp = function (event) {
var keynum = event.keyCode const keynum = event.keyCode
if (keynum !== 27 && keynum !== 13) { if (keynum !== 27 && keynum !== 13) {
// !show and !Enter // !show and !Enter
this._onDelayedSearch(event) // For IE 9 this._onDelayedSearch(event) // For IE 9

View File

@ -1,8 +1,8 @@
'use strict' 'use strict'
var ContextMenu = require('./ContextMenu') const ContextMenu = require('./ContextMenu')
var translate = require('./i18n').translate const translate = require('./i18n').translate
var util = require('./util') const util = require('./util')
/** /**
* Creates a component that visualize path selection in tree based editors * Creates a component that visualize path selection in tree based editors
@ -35,14 +35,14 @@ TreePath.prototype.reset = function () {
* *
*/ */
TreePath.prototype.setPath = function (pathObjs) { TreePath.prototype.setPath = function (pathObjs) {
var me = this const me = this
this.path.innerHTML = '' this.path.innerHTML = ''
if (pathObjs && pathObjs.length) { if (pathObjs && pathObjs.length) {
pathObjs.forEach(function (pathObj, idx) { pathObjs.forEach((pathObj, idx) => {
var pathEl = document.createElement('span') const pathEl = document.createElement('span')
var sepEl let sepEl
pathEl.className = 'jsoneditor-treepath-element' pathEl.className = 'jsoneditor-treepath-element'
pathEl.innerText = pathObj.name pathEl.innerText = pathObj.name
pathEl.onclick = _onSegmentClick.bind(me, pathObj) pathEl.onclick = _onSegmentClick.bind(me, pathObj)
@ -54,17 +54,17 @@ TreePath.prototype.setPath = function (pathObjs) {
sepEl.className = 'jsoneditor-treepath-seperator' sepEl.className = 'jsoneditor-treepath-seperator'
sepEl.innerHTML = '&#9658;' sepEl.innerHTML = '&#9658;'
sepEl.onclick = function () { sepEl.onclick = () => {
me.contentMenuClicked = true me.contentMenuClicked = true
var items = [] const items = []
pathObj.children.forEach(function (child) { pathObj.children.forEach(child => {
items.push({ items.push({
text: child.name, text: child.name,
className: 'jsoneditor-type-modes' + (pathObjs[idx + 1] + 1 && pathObjs[idx + 1].name === child.name ? ' jsoneditor-selected' : ''), className: 'jsoneditor-type-modes' + (pathObjs[idx + 1] + 1 && pathObjs[idx + 1].name === child.name ? ' jsoneditor-selected' : ''),
click: _onContextMenuItemClick.bind(me, pathObj, child.name) click: _onContextMenuItemClick.bind(me, pathObj, child.name)
}) })
}) })
var menu = new ContextMenu(items) const menu = new ContextMenu(items)
menu.show(sepEl, me.root, true) menu.show(sepEl, me.root, true)
} }
@ -72,13 +72,13 @@ TreePath.prototype.setPath = function (pathObjs) {
} }
if (idx === pathObjs.length - 1) { if (idx === pathObjs.length - 1) {
var leftRectPos = (sepEl || pathEl).getBoundingClientRect().right const leftRectPos = (sepEl || pathEl).getBoundingClientRect().right
if (me.path.offsetWidth < leftRectPos) { if (me.path.offsetWidth < leftRectPos) {
me.path.scrollLeft = leftRectPos me.path.scrollLeft = leftRectPos
} }
if (me.path.scrollLeft) { if (me.path.scrollLeft) {
var showAllBtn = document.createElement('span') const showAllBtn = document.createElement('span')
showAllBtn.className = 'jsoneditor-treepath-show-all-btn' showAllBtn.className = 'jsoneditor-treepath-show-all-btn'
showAllBtn.title = 'show all path' showAllBtn.title = 'show all path'
showAllBtn.innerHTML = '...' showAllBtn.innerHTML = '...'
@ -93,7 +93,7 @@ TreePath.prototype.setPath = function (pathObjs) {
me.contentMenuClicked = false me.contentMenuClicked = false
util.addClassName(me.path, 'show-all') util.addClassName(me.path, 'show-all')
me.path.style.width = me.path.parentNode.getBoundingClientRect().width - 10 + 'px' me.path.style.width = me.path.parentNode.getBoundingClientRect().width - 10 + 'px'
me.path.onblur = function () { me.path.onblur = () => {
if (me.contentMenuClicked) { if (me.contentMenuClicked) {
me.contentMenuClicked = false me.contentMenuClicked = false
me.path.focus() me.path.focus()

View File

@ -1,4 +1,4 @@
var ace let ace
if (window.ace) { if (window.ace) {
// use the already loaded instance of Ace // use the already loaded instance of Ace
ace = window.ace ace = window.ace

View File

@ -28,7 +28,7 @@
* *
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
window.ace.define('ace/theme/jsoneditor', ['require', 'exports', 'module', 'ace/lib/dom'], function (acequire, exports, module) { window.ace.define('ace/theme/jsoneditor', ['require', 'exports', 'module', 'ace/lib/dom'], (acequire, exports, module) => {
exports.isDark = false exports.isDark = false
exports.cssClass = 'ace-jsoneditor' exports.cssClass = 'ace-jsoneditor'
exports.cssText = `.ace-jsoneditor .ace_gutter { exports.cssText = `.ace-jsoneditor .ace_gutter {
@ -139,6 +139,6 @@ text-decoration: underline
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y
}` }`
var dom = acequire('../lib/dom') const dom = acequire('../lib/dom')
dom.importCssString(exports.cssText, exports.cssClass) dom.importCssString(exports.cssText, exports.cssClass)
}) })

View File

@ -1,8 +1,8 @@
'use strict' 'use strict'
var util = require('./util') const util = require('./util')
var ContextMenu = require('./ContextMenu') const ContextMenu = require('./ContextMenu')
var translate = require('./i18n').translate const translate = require('./i18n').translate
/** /**
* A factory function to create an AppendNode, which depends on a Node * A factory function to create an AppendNode, which depends on a Node
@ -30,7 +30,7 @@ function appendNodeFactory (Node) {
*/ */
AppendNode.prototype.getDom = function () { AppendNode.prototype.getDom = function () {
// TODO: implement a new solution for the append node // TODO: implement a new solution for the append node
var dom = this.dom const dom = this.dom
if (dom.tr) { if (dom.tr) {
return dom.tr return dom.tr
@ -39,7 +39,7 @@ function appendNodeFactory (Node) {
this._updateEditability() this._updateEditability()
// a row for the append button // a row for the append button
var trAppend = document.createElement('tr') const trAppend = document.createElement('tr')
trAppend.className = 'jsoneditor-append' trAppend.className = 'jsoneditor-append'
trAppend.node = this trAppend.node = this
dom.tr = trAppend dom.tr = trAppend
@ -51,9 +51,9 @@ function appendNodeFactory (Node) {
dom.tdDrag = document.createElement('td') dom.tdDrag = document.createElement('td')
// create context menu // create context menu
var tdMenu = document.createElement('td') const tdMenu = document.createElement('td')
dom.tdMenu = tdMenu dom.tdMenu = tdMenu
var menu = document.createElement('button') const menu = document.createElement('button')
menu.type = 'button' menu.type = 'button'
menu.className = 'jsoneditor-button jsoneditor-contextmenu' menu.className = 'jsoneditor-button jsoneditor-contextmenu'
menu.title = 'Click to open the actions menu (Ctrl+M)' menu.title = 'Click to open the actions menu (Ctrl+M)'
@ -62,8 +62,8 @@ function appendNodeFactory (Node) {
} }
// a cell for the contents (showing text 'empty') // a cell for the contents (showing text 'empty')
var tdAppend = document.createElement('td') const tdAppend = document.createElement('td')
var domText = document.createElement('div') const domText = document.createElement('div')
domText.innerHTML = '(' + translate('empty') + ')' domText.innerHTML = '(' + translate('empty') + ')'
domText.className = 'jsoneditor-readonly' domText.className = 'jsoneditor-readonly'
tdAppend.appendChild(domText) tdAppend.appendChild(domText)
@ -79,37 +79,33 @@ function appendNodeFactory (Node) {
* Append node doesn't have a path * Append node doesn't have a path
* @returns {null} * @returns {null}
*/ */
AppendNode.prototype.getPath = function () { AppendNode.prototype.getPath = () => null
return null
}
/** /**
* Append node doesn't have an index * Append node doesn't have an index
* @returns {null} * @returns {null}
*/ */
AppendNode.prototype.getIndex = function () { AppendNode.prototype.getIndex = () => null
return null
}
/** /**
* Update the HTML dom of the Node * Update the HTML dom of the Node
*/ */
AppendNode.prototype.updateDom = function (options) { AppendNode.prototype.updateDom = function (options) {
var dom = this.dom const dom = this.dom
var tdAppend = dom.td const tdAppend = dom.td
if (tdAppend) { if (tdAppend) {
tdAppend.style.paddingLeft = (this.getLevel() * 24 + 26) + 'px' tdAppend.style.paddingLeft = (this.getLevel() * 24 + 26) + 'px'
// TODO: not so nice hard coded offset // TODO: not so nice hard coded offset
} }
var domText = dom.text const domText = dom.text
if (domText) { if (domText) {
domText.innerHTML = '(' + translate('empty') + ' ' + this.parent.type + ')' domText.innerHTML = '(' + translate('empty') + ' ' + this.parent.type + ')'
} }
// attach or detach the contents of the append node: // attach or detach the contents of the append node:
// hide when the parent has childs, show when the parent has no childs // hide when the parent has childs, show when the parent has no childs
var trAppend = dom.tr const trAppend = dom.tr
if (!this.isVisible()) { if (!this.isVisible()) {
if (dom.tr.firstChild) { if (dom.tr.firstChild) {
if (dom.tdDrag) { if (dom.tdDrag) {
@ -149,9 +145,9 @@ function appendNodeFactory (Node) {
* is being closed. * is being closed.
*/ */
AppendNode.prototype.showContextMenu = function (anchor, onClose) { AppendNode.prototype.showContextMenu = function (anchor, onClose) {
var node = this const node = this
var titles = Node.TYPE_TITLES const titles = Node.TYPE_TITLES
var appendSubmenu = [ const appendSubmenu = [
{ {
text: translate('auto'), text: translate('auto'),
className: 'jsoneditor-type-auto', className: 'jsoneditor-type-auto',
@ -186,7 +182,7 @@ function appendNodeFactory (Node) {
} }
] ]
node.addTemplates(appendSubmenu, true) node.addTemplates(appendSubmenu, true)
var items = [ let items = [
// create append button // create append button
{ {
text: translate('appendText'), text: translate('appendText'),
@ -201,7 +197,7 @@ function appendNodeFactory (Node) {
] ]
if (this.editor.options.onCreateMenu) { if (this.editor.options.onCreateMenu) {
var path = node.parent.getPath() const path = node.parent.getPath()
items = this.editor.options.onCreateMenu(items, { items = this.editor.options.onCreateMenu(items, {
type: 'append', type: 'append',
@ -210,7 +206,7 @@ function appendNodeFactory (Node) {
}) })
} }
var menu = new ContextMenu(items, { close: onClose }) const menu = new ContextMenu(items, { close: onClose })
menu.show(anchor, this.editor.frame) menu.show(anchor, this.editor.frame)
} }
@ -219,12 +215,12 @@ function appendNodeFactory (Node) {
* @param {Event} event * @param {Event} event
*/ */
AppendNode.prototype.onEvent = function (event) { AppendNode.prototype.onEvent = function (event) {
var type = event.type const type = event.type
var target = event.target || event.srcElement const target = event.target || event.srcElement
var dom = this.dom const dom = this.dom
// highlight the append nodes parent // highlight the append nodes parent
var menu = dom.menu const menu = dom.menu
if (target === menu) { if (target === menu) {
if (type === 'mouseover') { if (type === 'mouseover') {
this.editor.highlighter.highlight(this.parent) this.editor.highlighter.highlight(this.parent)
@ -235,11 +231,11 @@ function appendNodeFactory (Node) {
// context menu events // context menu events
if (type === 'click' && target === dom.menu) { if (type === 'click' && target === dom.menu) {
var highlighter = this.editor.highlighter const highlighter = this.editor.highlighter
highlighter.highlight(this.parent) highlighter.highlight(this.parent)
highlighter.lock() highlighter.lock()
util.addClassName(dom.menu, 'jsoneditor-selected') util.addClassName(dom.menu, 'jsoneditor-selected')
this.showContextMenu(dom.menu, function () { this.showContextMenu(dom.menu, () => {
util.removeClassName(dom.menu, 'jsoneditor-selected') util.removeClassName(dom.menu, 'jsoneditor-selected')
highlighter.unlock() highlighter.unlock()
highlighter.unhighlight() highlighter.unhighlight()

View File

@ -1,6 +1,6 @@
'use strict' 'use strict'
var defaultFilterFunction = { const defaultFilterFunction = {
start: function (token, match, config) { start: function (token, match, config) {
return match.indexOf(token) === 0 return match.indexOf(token) === 0
}, },
@ -16,31 +16,31 @@ function completely (config) {
config.confirmKeys = config.confirmKeys || [39, 35, 9] // right, end, tab config.confirmKeys = config.confirmKeys || [39, 35, 9] // right, end, tab
config.caseSensitive = config.caseSensitive || false // autocomplete case sensitive config.caseSensitive = config.caseSensitive || false // autocomplete case sensitive
var fontSize = '' let fontSize = ''
var fontFamily = '' let fontFamily = ''
var wrapper = document.createElement('div') const wrapper = document.createElement('div')
wrapper.style.position = 'relative' wrapper.style.position = 'relative'
wrapper.style.outline = '0' wrapper.style.outline = '0'
wrapper.style.border = '0' wrapper.style.border = '0'
wrapper.style.margin = '0' wrapper.style.margin = '0'
wrapper.style.padding = '0' wrapper.style.padding = '0'
var dropDown = document.createElement('div') const dropDown = document.createElement('div')
dropDown.className = 'autocomplete dropdown' dropDown.className = 'autocomplete dropdown'
dropDown.style.position = 'absolute' dropDown.style.position = 'absolute'
dropDown.style.visibility = 'hidden' dropDown.style.visibility = 'hidden'
var spacer let spacer
var leftSide // <-- it will contain the leftSide part of the textfield (the bit that was already autocompleted) let leftSide // <-- it will contain the leftSide part of the textfield (the bit that was already autocompleted)
var createDropDownController = function (elem, rs) { const createDropDownController = (elem, rs) => {
var rows = [] let rows = []
var ix = 0 let ix = 0
var oldIndex = -1 let oldIndex = -1
var onMouseOver = function () { this.style.outline = '1px solid #ddd' } const onMouseOver = function () { this.style.outline = '1px solid #ddd' }
var onMouseOut = function () { this.style.outline = '0' } const onMouseOut = function () { this.style.outline = '0' }
var onMouseDown = function () { p.hide(); p.onmouseselection(this.__hint, p.rs) } const onMouseDown = function () { p.hide(); p.onmouseselection(this.__hint, p.rs) }
var p = { var p = {
rs: rs, rs: rs,
@ -52,20 +52,18 @@ function completely (config) {
elem.style.visibility = 'hidden' elem.style.visibility = 'hidden'
ix = 0 ix = 0
elem.innerHTML = '' elem.innerHTML = ''
var vph = (window.innerHeight || document.documentElement.clientHeight) const vph = (window.innerHeight || document.documentElement.clientHeight)
var rect = elem.parentNode.getBoundingClientRect() const rect = elem.parentNode.getBoundingClientRect()
var distanceToTop = rect.top - 6 // heuristic give 6px const distanceToTop = rect.top - 6 // heuristic give 6px
var distanceToBottom = vph - rect.bottom - 6 // distance from the browser border. const distanceToBottom = vph - rect.bottom - 6 // distance from the browser border.
rows = [] rows = []
var filterFn = typeof config.filter === 'function' ? config.filter : defaultFilterFunction[config.filter] const filterFn = typeof config.filter === 'function' ? config.filter : defaultFilterFunction[config.filter]
var filtered = !filterFn ? [] : array.filter(function (match) { const filtered = !filterFn ? [] : array.filter(match => filterFn(config.caseSensitive ? token : token.toLowerCase(), config.caseSensitive ? match : match.toLowerCase(), config))
return filterFn(config.caseSensitive ? token : token.toLowerCase(), config.caseSensitive ? match : match.toLowerCase(), config)
})
rows = filtered.map(function (row) { rows = filtered.map(row => {
var divRow = document.createElement('div') const divRow = document.createElement('div')
divRow.className = 'item' divRow.className = 'item'
// divRow.style.color = config.color; // divRow.style.color = config.color;
divRow.onmouseover = onMouseOver divRow.onmouseover = onMouseOver
@ -119,7 +117,7 @@ function completely (config) {
} }
function setEndOfContenteditable (contentEditableElement) { function setEndOfContenteditable (contentEditableElement) {
var range, selection let range, selection
if (document.createRange) { if (document.createRange) {
// Firefox, Chrome, Opera, Safari, IE 9+ // Firefox, Chrome, Opera, Safari, IE 9+
range = document.createRange()// Create a range (a range is a like the selection but invisible) range = document.createRange()// Create a range (a range is a like the selection but invisible)
@ -164,7 +162,7 @@ function completely (config) {
return spacer.getBoundingClientRect().right return spacer.getBoundingClientRect().right
} }
var rs = { const rs = {
onArrowDown: function () { }, // defaults to no action. onArrowDown: function () { }, // defaults to no action.
onArrowUp: function () { }, // defaults to no action. onArrowUp: function () { }, // defaults to no action.
onEnter: function () { }, // defaults to no action. onEnter: function () { }, // defaults to no action.
@ -213,7 +211,7 @@ function completely (config) {
this.elementHint.className = 'autocomplete hint' this.elementHint.className = 'autocomplete hint'
this.elementHint.style.zIndex = 2 this.elementHint.style.zIndex = 2
this.elementHint.style.position = 'absolute' this.elementHint.style.position = 'absolute'
this.elementHint.onfocus = function () { this.element.focus() }.bind(this) this.elementHint.onfocus = () => { this.element.focus() }
if (this.element.addEventListener) { if (this.element.addEventListener) {
this.element.removeEventListener('keydown', keyDownHandler) this.element.removeEventListener('keydown', keyDownHandler)
@ -247,18 +245,18 @@ function completely (config) {
} }
}, },
repaint: function (element) { repaint: function (element) {
var text = element.innerText let text = element.innerText
text = text.replace('\n', '') text = text.replace('\n', '')
var optionsLength = this.options.length const optionsLength = this.options.length
// breaking text in leftSide and token. // breaking text in leftSide and token.
var token = text.substring(this.startFrom) const token = text.substring(this.startFrom)
leftSide = text.substring(0, this.startFrom) leftSide = text.substring(0, this.startFrom)
for (var i = 0; i < optionsLength; i++) { for (let i = 0; i < optionsLength; i++) {
var opt = this.options[i] const opt = this.options[i]
if ((!config.caseSensitive && opt.toLowerCase().indexOf(token.toLowerCase()) === 0) || if ((!config.caseSensitive && opt.toLowerCase().indexOf(token.toLowerCase()) === 0) ||
(config.caseSensitive && opt.indexOf(token) === 0)) { // <-- how about upperCase vs. lowercase (config.caseSensitive && opt.indexOf(token) === 0)) { // <-- how about upperCase vs. lowercase
this.elementHint.innerText = leftSide + token + opt.substring(token.length) this.elementHint.innerText = leftSide + token + opt.substring(token.length)
@ -270,7 +268,7 @@ function completely (config) {
dropDown.style.left = calculateWidthForText(leftSide) + 'px' dropDown.style.left = calculateWidthForText(leftSide) + 'px'
dropDownController.refresh(token, this.options) dropDownController.refresh(token, this.options)
this.elementHint.style.width = calculateWidthForText(this.elementHint.innerText) + 10 + 'px' this.elementHint.style.width = calculateWidthForText(this.elementHint.innerText) + 10 + 'px'
var wasDropDownHidden = (dropDown.style.visibility === 'hidden') const wasDropDownHidden = (dropDown.style.visibility === 'hidden')
if (!wasDropDownHidden) { this.elementHint.style.width = calculateWidthForText(this.elementHint.innerText) + dropDown.clientWidth + 'px' } if (!wasDropDownHidden) { this.elementHint.style.width = calculateWidthForText(this.elementHint.innerText) + dropDown.clientWidth + 'px' }
} }
} }
@ -280,7 +278,7 @@ function completely (config) {
var keyDownHandler = function (e) { var keyDownHandler = function (e) {
// console.log("Keydown:" + e.keyCode); // console.log("Keydown:" + e.keyCode);
e = e || window.event e = e || window.event
var keyCode = e.keyCode const keyCode = e.keyCode
if (this.elementHint == null) return if (this.elementHint == null) return
@ -295,7 +293,7 @@ function completely (config) {
return return
} }
var text = this.element.innerText let text = this.element.innerText
text = text.replace('\n', '') text = text.replace('\n', '')
if (config.confirmKeys.indexOf(keyCode) >= 0) { // (autocomplete triggered) if (config.confirmKeys.indexOf(keyCode) >= 0) { // (autocomplete triggered)
@ -323,7 +321,7 @@ function completely (config) {
if (this.elementHint.innerText.length === 0) { // if there is a hint if (this.elementHint.innerText.length === 0) { // if there is a hint
rs.onEnter() rs.onEnter()
} else { } else {
var wasDropDownHidden = (dropDown.style.visibility === 'hidden') const wasDropDownHidden = (dropDown.style.visibility === 'hidden')
dropDownController.hide() dropDownController.hide()
if (wasDropDownHidden) { if (wasDropDownHidden) {
@ -364,15 +362,15 @@ function completely (config) {
} }
}.bind(rs) }.bind(rs)
var onBlurHandler = function (e) { var onBlurHandler = e => {
rs.hideDropDown() rs.hideDropDown()
// console.log("Lost focus."); // console.log("Lost focus.");
} }
dropDownController.onmouseselection = function (text, rs) { dropDownController.onmouseselection = (text, rs) => {
rs.element.innerText = rs.elementHint.innerText = leftSide + text rs.element.innerText = rs.elementHint.innerText = leftSide + text
rs.hideDropDown() rs.hideDropDown()
window.setTimeout(function () { window.setTimeout(() => {
rs.element.focus() rs.element.focus()
setEndOfContenteditable(rs.element) setEndOfContenteditable(rs.element)
}, 1) }, 1)

View File

@ -1,4 +1,4 @@
var util = require('./util') const util = require('./util')
/** /**
* Create an anchor element absolutely positioned in the `parent` * Create an anchor element absolutely positioned in the `parent`
@ -8,14 +8,14 @@ var util = require('./util')
* @param [onDestroy(function(anchor)] Callback when the anchor is destroyed * @param [onDestroy(function(anchor)] Callback when the anchor is destroyed
* @returns {HTMLElement} * @returns {HTMLElement}
*/ */
exports.createAbsoluteAnchor = function (anchor, parent, onDestroy) { exports.createAbsoluteAnchor = (anchor, parent, onDestroy) => {
var root = getRootNode(anchor) const root = getRootNode(anchor)
var eventListeners = {} const eventListeners = {}
var anchorRect = anchor.getBoundingClientRect() const anchorRect = anchor.getBoundingClientRect()
var frameRect = parent.getBoundingClientRect() const frameRect = parent.getBoundingClientRect()
var absoluteAnchor = document.createElement('div') const absoluteAnchor = document.createElement('div')
absoluteAnchor.className = 'jsoneditor-anchor' absoluteAnchor.className = 'jsoneditor-anchor'
absoluteAnchor.style.position = 'absolute' absoluteAnchor.style.position = 'absolute'
absoluteAnchor.style.left = (anchorRect.left - frameRect.left) + 'px' absoluteAnchor.style.left = (anchorRect.left - frameRect.left) + 'px'
@ -32,9 +32,9 @@ exports.createAbsoluteAnchor = function (anchor, parent, onDestroy) {
// remove all event listeners // remove all event listeners
// all event listeners are supposed to be attached to document. // all event listeners are supposed to be attached to document.
for (var name in eventListeners) { for (const name in eventListeners) {
if (hasOwnProperty(eventListeners, name)) { if (hasOwnProperty(eventListeners, name)) {
var fn = eventListeners[name] const fn = eventListeners[name]
if (fn) { if (fn) {
util.removeEventListener(root, name, fn) util.removeEventListener(root, name, fn)
} }
@ -49,8 +49,8 @@ exports.createAbsoluteAnchor = function (anchor, parent, onDestroy) {
} }
// create and attach event listeners // create and attach event listeners
var destroyIfOutside = function (event) { const destroyIfOutside = event => {
var target = event.target const target = event.target
if ((target !== absoluteAnchor) && !util.isChildOf(target, absoluteAnchor)) { if ((target !== absoluteAnchor) && !util.isChildOf(target, absoluteAnchor)) {
destroy() destroy()
} }

View File

@ -4,8 +4,8 @@
require('./polyfills') require('./polyfills')
var _locales = ['en', 'pt-BR', 'zh-CN', 'tr'] const _locales = ['en', 'pt-BR', 'zh-CN', 'tr']
var _defs = { const _defs = {
en: { en: {
array: 'Array', array: 'Array',
auto: 'Auto', auto: 'Auto',
@ -376,14 +376,12 @@ var _defs = {
} }
} }
var _defaultLang = 'en' const _defaultLang = 'en'
var _lang let _lang
var userLang = typeof navigator !== 'undefined' const userLang = typeof navigator !== 'undefined'
? navigator.language || navigator.userLanguage ? navigator.language || navigator.userLanguage
: undefined : undefined
_lang = _locales.find(function (l) { _lang = _locales.find(l => l === userLang)
return l === userLang
})
if (!_lang) { if (!_lang) {
_lang = _defaultLang _lang = _defaultLang
} }
@ -397,9 +395,7 @@ module.exports = {
if (!lang) { if (!lang) {
return return
} }
var langFound = _locales.find(function (l) { const langFound = _locales.find(l => l === lang)
return l === lang
})
if (langFound) { if (langFound) {
_lang = langFound _lang = langFound
} else { } else {
@ -410,10 +406,8 @@ module.exports = {
if (!languages) { if (!languages) {
return return
} }
for (var key in languages) { for (const key in languages) {
var langFound = _locales.find(function (l) { const langFound = _locales.find(l => l === key)
return l === key
})
if (!langFound) { if (!langFound) {
_locales.push(key) _locales.push(key)
} }
@ -424,7 +418,7 @@ module.exports = {
if (!lang) { if (!lang) {
lang = _lang lang = _lang
} }
var text = _defs[lang][key] let text = _defs[lang][key]
if (data) { if (data) {
for (key in data) { for (key in data) {
text = text.replace('${' + key + '}', data[key]) text = text.replace('${' + key + '}', data[key])

View File

@ -22,7 +22,7 @@
* @returns {string | undefined} Returns the string representation of the JSON object. * @returns {string | undefined} Returns the string representation of the JSON object.
*/ */
function stringifyPartial (value, space, limit) { function stringifyPartial (value, space, limit) {
var _space // undefined by default let _space // undefined by default
if (typeof space === 'number') { if (typeof space === 'number') {
if (space > 10) { if (space > 10) {
_space = repeat(' ', 10) _space = repeat(' ', 10)
@ -34,7 +34,7 @@ function stringifyPartial (value, space, limit) {
_space = space _space = space
} }
var output = stringifyValue(value, _space, '', limit) const output = stringifyValue(value, _space, '', limit)
return output.length > limit return output.length > limit
? (slice(output, limit) + '...') ? (slice(output, limit) + '...')
@ -81,11 +81,11 @@ function stringifyValue (value, space, indent, limit) {
* @return {string} * @return {string}
*/ */
function stringifyArray (array, space, indent, limit) { function stringifyArray (array, space, indent, limit) {
var childIndent = space ? (indent + space) : undefined const childIndent = space ? (indent + space) : undefined
var str = space ? '[\n' : '[' let str = space ? '[\n' : '['
for (var i = 0; i < array.length; i++) { for (let i = 0; i < array.length; i++) {
var item = array[i] const item = array[i]
if (space) { if (space) {
str += childIndent str += childIndent
@ -120,17 +120,17 @@ function stringifyArray (array, space, indent, limit) {
* @return {string} * @return {string}
*/ */
function stringifyObject (object, space, indent, limit) { function stringifyObject (object, space, indent, limit) {
var childIndent = space ? (indent + space) : undefined const childIndent = space ? (indent + space) : undefined
var first = true let first = true
var str = space ? '{\n' : '{' let str = space ? '{\n' : '{'
if (typeof object.toJSON === 'function') { if (typeof object.toJSON === 'function') {
return stringifyValue(object.toJSON(), space, indent, limit) return stringifyValue(object.toJSON(), space, indent, limit)
} }
for (var key in object) { for (const key in object) {
if (hasOwnProperty(object, key)) { if (hasOwnProperty(object, key)) {
var value = object[key] const value = object[key]
if (first) { if (first) {
first = false first = false
@ -163,7 +163,7 @@ function stringifyObject (object, space, indent, limit) {
* @return {string} * @return {string}
*/ */
function repeat (text, times) { function repeat (text, times) {
var res = '' let res = ''
while (times-- > 0) { while (times-- > 0) {
res += text res += text
} }

View File

@ -1,7 +1,7 @@
if (typeof Element !== 'undefined') { if (typeof Element !== 'undefined') {
// Polyfill for array remove // Polyfill for array remove
(function () { (() => {
function polyfill (item) { function polyfill (item) {
if ('remove' in item) { if ('remove' in item) {
return return
@ -26,8 +26,8 @@ if (typeof Element !== 'undefined') {
if (!Array.prototype.find) { if (!Array.prototype.find) {
// eslint-disable-next-line no-extend-native // eslint-disable-next-line no-extend-native
Array.prototype.find = function (callback) { Array.prototype.find = function (callback) {
for (var i = 0; i < this.length; i++) { for (let i = 0; i < this.length; i++) {
var element = this[i] const element = this[i]
if (callback.call(this, element, i, this)) { if (callback.call(this, element, i, this)) {
return element return element
} }

View File

@ -1,21 +1,21 @@
'use strict' 'use strict'
var jmespath = require('jmespath') const jmespath = require('jmespath')
var translate = require('./i18n').translate const translate = require('./i18n').translate
var ModeSwitcher = require('./ModeSwitcher') const ModeSwitcher = require('./ModeSwitcher')
var ErrorTable = require('./ErrorTable') const ErrorTable = require('./ErrorTable')
var textmode = require('./textmode')[0].mixin const textmode = require('./textmode')[0].mixin
var showSortModal = require('./showSortModal') const showSortModal = require('./showSortModal')
var showTransformModal = require('./showTransformModal') const showTransformModal = require('./showTransformModal')
var MAX_PREVIEW_CHARACTERS = require('./constants').MAX_PREVIEW_CHARACTERS const MAX_PREVIEW_CHARACTERS = require('./constants').MAX_PREVIEW_CHARACTERS
var DEFAULT_MODAL_ANCHOR = require('./constants').DEFAULT_MODAL_ANCHOR const DEFAULT_MODAL_ANCHOR = require('./constants').DEFAULT_MODAL_ANCHOR
var SIZE_LARGE = require('./constants').SIZE_LARGE const SIZE_LARGE = require('./constants').SIZE_LARGE
var PREVIEW_HISTORY_LIMIT = require('./constants').PREVIEW_HISTORY_LIMIT const PREVIEW_HISTORY_LIMIT = require('./constants').PREVIEW_HISTORY_LIMIT
var util = require('./util') const util = require('./util')
var History = require('./History') const History = require('./History')
// create a mixin with the functions for text mode // create a mixin with the functions for text mode
var previewmode = {} const previewmode = {}
/** /**
* Create a JSON document preview, suitable for processing of large documents * Create a JSON document preview, suitable for processing of large documents
@ -48,7 +48,7 @@ previewmode.create = function (container, options) {
// determine mode // determine mode
this.mode = 'preview' this.mode = 'preview'
var me = this const me = this
this.container = container this.container = container
this.dom = {} this.dom = {}
@ -65,7 +65,7 @@ previewmode.create = function (container, options) {
this.frame = document.createElement('div') this.frame = document.createElement('div')
this.frame.className = 'jsoneditor jsoneditor-mode-preview' this.frame.className = 'jsoneditor jsoneditor-mode-preview'
this.frame.onclick = function (event) { this.frame.onclick = event => {
// prevent default submit action when the editor is located inside a form // prevent default submit action when the editor is located inside a form
event.preventDefault() event.preventDefault()
} }
@ -95,13 +95,13 @@ previewmode.create = function (container, options) {
this.frame.appendChild(this.menu) this.frame.appendChild(this.menu)
// create format button // create format button
var buttonFormat = document.createElement('button') const buttonFormat = document.createElement('button')
buttonFormat.type = 'button' buttonFormat.type = 'button'
buttonFormat.className = 'jsoneditor-format' buttonFormat.className = 'jsoneditor-format'
buttonFormat.title = 'Format JSON data, with proper indentation and line feeds (Ctrl+\\)' buttonFormat.title = 'Format JSON data, with proper indentation and line feeds (Ctrl+\\)'
this.menu.appendChild(buttonFormat) this.menu.appendChild(buttonFormat)
buttonFormat.onclick = function handleFormat () { buttonFormat.onclick = function handleFormat () {
me.executeWithBusyMessage(function () { me.executeWithBusyMessage(() => {
try { try {
me.format() me.format()
} catch (err) { } catch (err) {
@ -111,13 +111,13 @@ previewmode.create = function (container, options) {
} }
// create compact button // create compact button
var buttonCompact = document.createElement('button') const buttonCompact = document.createElement('button')
buttonCompact.type = 'button' buttonCompact.type = 'button'
buttonCompact.className = 'jsoneditor-compact' buttonCompact.className = 'jsoneditor-compact'
buttonCompact.title = 'Compact JSON data, remove all whitespaces (Ctrl+Shift+\\)' buttonCompact.title = 'Compact JSON data, remove all whitespaces (Ctrl+Shift+\\)'
this.menu.appendChild(buttonCompact) this.menu.appendChild(buttonCompact)
buttonCompact.onclick = function handleCompact () { buttonCompact.onclick = function handleCompact () {
me.executeWithBusyMessage(function () { me.executeWithBusyMessage(() => {
try { try {
me.compact() me.compact()
} catch (err) { } catch (err) {
@ -128,11 +128,11 @@ previewmode.create = function (container, options) {
// create sort button // create sort button
if (this.options.enableSort) { if (this.options.enableSort) {
var sort = document.createElement('button') const sort = document.createElement('button')
sort.type = 'button' sort.type = 'button'
sort.className = 'jsoneditor-sort' sort.className = 'jsoneditor-sort'
sort.title = translate('sortTitleShort') sort.title = translate('sortTitleShort')
sort.onclick = function () { sort.onclick = () => {
me._showSortModal() me._showSortModal()
} }
this.menu.appendChild(sort) this.menu.appendChild(sort)
@ -140,11 +140,11 @@ previewmode.create = function (container, options) {
// create transform button // create transform button
if (this.options.enableTransform) { if (this.options.enableTransform) {
var transform = document.createElement('button') const transform = document.createElement('button')
transform.type = 'button' transform.type = 'button'
transform.title = translate('transformTitleShort') transform.title = translate('transformTitleShort')
transform.className = 'jsoneditor-transform' transform.className = 'jsoneditor-transform'
transform.onclick = function () { transform.onclick = () => {
me._showTransformModal() me._showTransformModal()
} }
this.dom.transform = transform this.dom.transform = transform
@ -152,14 +152,14 @@ previewmode.create = function (container, options) {
} }
// create repair button // create repair button
var buttonRepair = document.createElement('button') const buttonRepair = document.createElement('button')
buttonRepair.type = 'button' buttonRepair.type = 'button'
buttonRepair.className = 'jsoneditor-repair' buttonRepair.className = 'jsoneditor-repair'
buttonRepair.title = 'Repair JSON: fix quotes and escape characters, remove comments and JSONP notation, turn JavaScript objects into JSON.' buttonRepair.title = 'Repair JSON: fix quotes and escape characters, remove comments and JSONP notation, turn JavaScript objects into JSON.'
this.menu.appendChild(buttonRepair) this.menu.appendChild(buttonRepair)
buttonRepair.onclick = function () { buttonRepair.onclick = () => {
if (me.json === undefined) { // only repair if we don't have valid JSON if (me.json === undefined) { // only repair if we don't have valid JSON
me.executeWithBusyMessage(function () { me.executeWithBusyMessage(() => {
try { try {
me.repair() me.repair()
} catch (err) { } catch (err) {
@ -171,24 +171,23 @@ previewmode.create = function (container, options) {
// create history and undo/redo buttons // create history and undo/redo buttons
if (this.options.history !== false) { // default option value is true if (this.options.history !== false) { // default option value is true
var onHistoryChange = function () { const onHistoryChange = () => {
me.dom.undo.disabled = !me.history.canUndo() me.dom.undo.disabled = !me.history.canUndo()
me.dom.redo.disabled = !me.history.canRedo() me.dom.redo.disabled = !me.history.canRedo()
} }
var calculateItemSize = function (item) { const calculateItemSize = item => // times two to account for the json object
return item.text.length * 2 // times two to account for the json object item.text.length * 2
}
this.history = new History(onHistoryChange, calculateItemSize, PREVIEW_HISTORY_LIMIT) this.history = new History(onHistoryChange, calculateItemSize, PREVIEW_HISTORY_LIMIT)
// create undo button // create undo button
var undo = document.createElement('button') const undo = document.createElement('button')
undo.type = 'button' undo.type = 'button'
undo.className = 'jsoneditor-undo jsoneditor-separator' undo.className = 'jsoneditor-undo jsoneditor-separator'
undo.title = translate('undo') undo.title = translate('undo')
undo.onclick = function () { undo.onclick = () => {
var action = me.history.undo() const action = me.history.undo()
if (action) { if (action) {
me._applyHistory(action) me._applyHistory(action)
} }
@ -197,12 +196,12 @@ previewmode.create = function (container, options) {
this.dom.undo = undo this.dom.undo = undo
// create redo button // create redo button
var redo = document.createElement('button') const redo = document.createElement('button')
redo.type = 'button' redo.type = 'button'
redo.className = 'jsoneditor-redo' redo.className = 'jsoneditor-redo'
redo.title = translate('redo') redo.title = translate('redo')
redo.onclick = function () { redo.onclick = () => {
var action = me.history.redo() const action = me.history.redo()
if (action) { if (action) {
me._applyHistory(action) me._applyHistory(action)
} }
@ -232,8 +231,8 @@ previewmode.create = function (container, options) {
onFocusLine: null, onFocusLine: null,
onChangeHeight: function (height) { onChangeHeight: function (height) {
// TODO: change CSS to using flex box, remove setting height using JavaScript // TODO: change CSS to using flex box, remove setting height using JavaScript
var statusBarHeight = me.dom.statusBar ? me.dom.statusBar.clientHeight : 0 const statusBarHeight = me.dom.statusBar ? me.dom.statusBar.clientHeight : 0
var totalHeight = height + statusBarHeight + 1 const totalHeight = height + statusBarHeight + 1
me.content.style.marginBottom = (-totalHeight) + 'px' me.content.style.marginBottom = (-totalHeight) + 'px'
me.content.style.paddingBottom = totalHeight + 'px' me.content.style.paddingBottom = totalHeight + 'px'
} }
@ -246,7 +245,7 @@ previewmode.create = function (container, options) {
if (options.statusBar) { if (options.statusBar) {
util.addClassName(this.content, 'has-status-bar') util.addClassName(this.content, 'has-status-bar')
var statusBar = document.createElement('div') const statusBar = document.createElement('div')
this.dom.statusBar = statusBar this.dom.statusBar = statusBar
statusBar.className = 'jsoneditor-statusbar' statusBar.className = 'jsoneditor-statusbar'
this.frame.appendChild(statusBar) this.frame.appendChild(statusBar)
@ -272,7 +271,7 @@ previewmode.create = function (container, options) {
} }
previewmode._renderPreview = function () { previewmode._renderPreview = function () {
var text = this.getText() const text = this.getText()
this.dom.previewText.nodeValue = util.limitCharacters(text, MAX_PREVIEW_CHARACTERS) this.dom.previewText.nodeValue = util.limitCharacters(text, MAX_PREVIEW_CHARACTERS)
@ -332,31 +331,31 @@ previewmode._onChange = function () {
* @private * @private
*/ */
previewmode._showSortModal = function () { previewmode._showSortModal = function () {
var me = this const me = this
function onSort (json, sortedBy) { function onSort (json, sortedBy) {
if (Array.isArray(json)) { if (Array.isArray(json)) {
var sortedArray = util.sort(json, sortedBy.path, sortedBy.direction) const sortedArray = util.sort(json, sortedBy.path, sortedBy.direction)
me.sortedBy = sortedBy me.sortedBy = sortedBy
me._setAndFireOnChange(sortedArray) me._setAndFireOnChange(sortedArray)
} }
if (util.isObject(json)) { if (util.isObject(json)) {
var sortedObject = util.sortObjectKeys(json, sortedBy.direction) const sortedObject = util.sortObjectKeys(json, sortedBy.direction)
me.sortedBy = sortedBy me.sortedBy = sortedBy
me._setAndFireOnChange(sortedObject) me._setAndFireOnChange(sortedObject)
} }
} }
this.executeWithBusyMessage(function () { this.executeWithBusyMessage(() => {
var container = me.options.modalAnchor || DEFAULT_MODAL_ANCHOR const container = me.options.modalAnchor || DEFAULT_MODAL_ANCHOR
var json = me.get() const json = me.get()
me._renderPreview() // update array count me._renderPreview() // update array count
showSortModal(container, json, function (sortedBy) { showSortModal(container, json, sortedBy => {
me.executeWithBusyMessage(function () { me.executeWithBusyMessage(() => {
onSort(json, sortedBy) onSort(json, sortedBy)
}, 'sorting...') }, 'sorting...')
}, me.sortedBy) }, me.sortedBy)
@ -368,16 +367,16 @@ previewmode._showSortModal = function () {
* @private * @private
*/ */
previewmode._showTransformModal = function () { previewmode._showTransformModal = function () {
var me = this const me = this
this.executeWithBusyMessage(function () { this.executeWithBusyMessage(() => {
var anchor = me.options.modalAnchor || DEFAULT_MODAL_ANCHOR const anchor = me.options.modalAnchor || DEFAULT_MODAL_ANCHOR
var json = me.get() const json = me.get()
me._renderPreview() // update array count me._renderPreview() // update array count
showTransformModal(anchor, json, function (query) { showTransformModal(anchor, json, query => {
me.executeWithBusyMessage(function () { me.executeWithBusyMessage(() => {
var updatedJson = jmespath.search(json, query) const updatedJson = jmespath.search(json, query)
me._setAndFireOnChange(updatedJson) me._setAndFireOnChange(updatedJson)
}, 'transforming...') }, 'transforming...')
}) })
@ -407,8 +406,8 @@ previewmode.destroy = function () {
* Compact the code in the text editor * Compact the code in the text editor
*/ */
previewmode.compact = function () { previewmode.compact = function () {
var json = this.get() const json = this.get()
var text = JSON.stringify(json) const text = JSON.stringify(json)
// we know that in this case the json is still the same, so we pass json too // we know that in this case the json is still the same, so we pass json too
this._setTextAndFireOnChange(text, json) this._setTextAndFireOnChange(text, json)
@ -418,8 +417,8 @@ previewmode.compact = function () {
* Format the code in the text editor * Format the code in the text editor
*/ */
previewmode.format = function () { previewmode.format = function () {
var json = this.get() const json = this.get()
var text = JSON.stringify(json, null, this.indentation) const text = JSON.stringify(json, null, this.indentation)
// we know that in this case the json is still the same, so we pass json too // we know that in this case the json is still the same, so we pass json too
this._setTextAndFireOnChange(text, json) this._setTextAndFireOnChange(text, json)
@ -429,8 +428,8 @@ previewmode.format = function () {
* Repair the code in the text editor * Repair the code in the text editor
*/ */
previewmode.repair = function () { previewmode.repair = function () {
var text = this.getText() const text = this.getText()
var repairedText = util.repair(text) const repairedText = util.repair(text)
this._setTextAndFireOnChange(repairedText) this._setTextAndFireOnChange(repairedText)
} }
@ -491,7 +490,7 @@ previewmode._setAndFireOnChange = function (json) {
*/ */
previewmode.get = function () { previewmode.get = function () {
if (this.json === undefined) { if (this.json === undefined) {
var text = this.getText() const text = this.getText()
this.json = util.parse(text) // this can throw an error this.json = util.parse(text) // this can throw an error
} }
@ -557,8 +556,8 @@ previewmode._setText = function (jsonText, json) {
this._renderPreview() this._renderPreview()
if (this.json === undefined) { if (this.json === undefined) {
var me = this const me = this
this.executeWithBusyMessage(function () { this.executeWithBusyMessage(() => {
try { try {
// force parsing the json now, else it will be done in validate without feedback // force parsing the json now, else it will be done in validate without feedback
me.json = me.get() me.json = me.get()
@ -609,7 +608,7 @@ previewmode._pushHistory = function () {
return return
} }
var action = { const action = {
text: this.text, text: this.text,
json: this.json json: this.json
} }
@ -624,14 +623,14 @@ previewmode._pushHistory = function () {
* @param {string} message * @param {string} message
*/ */
previewmode.executeWithBusyMessage = function (fn, message) { previewmode.executeWithBusyMessage = function (fn, message) {
var size = this.getText().length const size = this.getText().length
if (size > SIZE_LARGE) { if (size > SIZE_LARGE) {
var me = this const me = this
util.addClassName(me.frame, 'busy') util.addClassName(me.frame, 'busy')
me.dom.busyContent.innerText = message me.dom.busyContent.innerText = message
setTimeout(function () { setTimeout(() => {
fn() fn()
util.removeClassName(me.frame, 'busy') util.removeClassName(me.frame, 'busy')
me.dom.busyContent.innerText = '' me.dom.busyContent.innerText = ''

View File

@ -1,6 +1,6 @@
'use strict' 'use strict'
var translate = require('./i18n').translate const translate = require('./i18n').translate
/** /**
* A factory function to create an ShowMoreNode, which depends on a Node * A factory function to create an ShowMoreNode, which depends on a Node
@ -37,12 +37,12 @@ function showMoreNodeFactory (Node) {
// display "show more" // display "show more"
if (!this.dom.tr) { if (!this.dom.tr) {
var me = this const me = this
var parent = this.parent const parent = this.parent
var showMoreButton = document.createElement('a') const showMoreButton = document.createElement('a')
showMoreButton.appendChild(document.createTextNode(translate('showMore'))) showMoreButton.appendChild(document.createTextNode(translate('showMore')))
showMoreButton.href = '#' showMoreButton.href = '#'
showMoreButton.onclick = function (event) { showMoreButton.onclick = event => {
// TODO: use callback instead of accessing a method of the parent // TODO: use callback instead of accessing a method of the parent
parent.visibleChilds = Math.floor(parent.visibleChilds / parent.getMaxVisibleChilds() + 1) * parent.visibleChilds = Math.floor(parent.visibleChilds / parent.getMaxVisibleChilds() + 1) *
parent.getMaxVisibleChilds() parent.getMaxVisibleChilds()
@ -53,10 +53,10 @@ function showMoreNodeFactory (Node) {
return false return false
} }
var showAllButton = document.createElement('a') const showAllButton = document.createElement('a')
showAllButton.appendChild(document.createTextNode(translate('showAll'))) showAllButton.appendChild(document.createTextNode(translate('showAll')))
showAllButton.href = '#' showAllButton.href = '#'
showAllButton.onclick = function (event) { showAllButton.onclick = event => {
// TODO: use callback instead of accessing a method of the parent // TODO: use callback instead of accessing a method of the parent
parent.visibleChilds = Infinity parent.visibleChilds = Infinity
me.updateDom() me.updateDom()
@ -66,8 +66,8 @@ function showMoreNodeFactory (Node) {
return false return false
} }
var moreContents = document.createElement('div') const moreContents = document.createElement('div')
var moreText = document.createTextNode(this._getShowMoreText()) const moreText = document.createTextNode(this._getShowMoreText())
moreContents.className = 'jsoneditor-show-more' moreContents.className = 'jsoneditor-show-more'
moreContents.appendChild(moreText) moreContents.appendChild(moreText)
moreContents.appendChild(showMoreButton) moreContents.appendChild(showMoreButton)
@ -75,10 +75,10 @@ function showMoreNodeFactory (Node) {
moreContents.appendChild(showAllButton) moreContents.appendChild(showAllButton)
moreContents.appendChild(document.createTextNode('. ')) moreContents.appendChild(document.createTextNode('. '))
var tdContents = document.createElement('td') const tdContents = document.createElement('td')
tdContents.appendChild(moreContents) tdContents.appendChild(moreContents)
var moreTr = document.createElement('tr') const moreTr = document.createElement('tr')
if (this.editor.options.mode === 'tree') { if (this.editor.options.mode === 'tree') {
moreTr.appendChild(document.createElement('td')) moreTr.appendChild(document.createElement('td'))
moreTr.appendChild(document.createElement('td')) moreTr.appendChild(document.createElement('td'))
@ -104,7 +104,7 @@ function showMoreNodeFactory (Node) {
this.dom.tr.node = this.parent.childs[this.parent.visibleChilds] this.dom.tr.node = this.parent.childs[this.parent.visibleChilds]
if (!this.dom.tr.parentNode) { if (!this.dom.tr.parentNode) {
var nextTr = this.parent._getNextTr() const nextTr = this.parent._getNextTr()
if (nextTr) { if (nextTr) {
nextTr.parentNode.insertBefore(this.dom.tr, nextTr) nextTr.parentNode.insertBefore(this.dom.tr, nextTr)
} }
@ -144,7 +144,7 @@ function showMoreNodeFactory (Node) {
* @param {Event} event * @param {Event} event
*/ */
ShowMoreNode.prototype.onEvent = function (event) { ShowMoreNode.prototype.onEvent = function (event) {
var type = event.type const type = event.type
if (type === 'keydown') { if (type === 'keydown') {
this.onKeyDown(event) this.onKeyDown(event)
} }

View File

@ -1,6 +1,6 @@
var picoModal = require('picomodal') const picoModal = require('picomodal')
var translate = require('./i18n').translate const translate = require('./i18n').translate
var util = require('./util') const util = require('./util')
/** /**
* Show advanced sorting modal * Show advanced sorting modal
@ -16,15 +16,15 @@ var util = require('./util')
* - {'asc' | 'desc'} direction The selected direction * - {'asc' | 'desc'} direction The selected direction
*/ */
function showSortModal (container, json, onSort, options) { function showSortModal (container, json, onSort, options) {
var paths = Array.isArray(json) const paths = Array.isArray(json)
? util.getChildPaths(json) ? util.getChildPaths(json)
: [''] : ['']
var selectedPath = options && options.path && util.contains(paths, options.path) const selectedPath = options && options.path && util.contains(paths, options.path)
? options.path ? options.path
: paths[0] : paths[0]
var selectedDirection = (options && options.direction) || 'asc' const selectedDirection = (options && options.direction) || 'asc'
var content = '<div class="pico-modal-contents">' + const content = '<div class="pico-modal-contents">' +
'<div class="pico-modal-header">' + translate('sort') + '</div>' + '<div class="pico-modal-header">' + translate('sort') + '</div>' +
'<form>' + '<form>' +
'<table>' + '<table>' +
@ -75,11 +75,11 @@ function showSortModal (container, json, onSort, options) {
}, },
modalClass: 'jsoneditor-modal jsoneditor-modal-sort' modalClass: 'jsoneditor-modal jsoneditor-modal-sort'
}) })
.afterCreate(function (modal) { .afterCreate(modal => {
var form = modal.modalElem().querySelector('form') const form = modal.modalElem().querySelector('form')
var ok = modal.modalElem().querySelector('#ok') const ok = modal.modalElem().querySelector('#ok')
var field = modal.modalElem().querySelector('#field') const field = modal.modalElem().querySelector('#field')
var direction = modal.modalElem().querySelector('#direction') const direction = modal.modalElem().querySelector('#direction')
function preprocessPath (path) { function preprocessPath (path) {
return (path === '') return (path === '')
@ -89,8 +89,8 @@ function showSortModal (container, json, onSort, options) {
: path : path
} }
paths.forEach(function (path) { paths.forEach(path => {
var option = document.createElement('option') const option = document.createElement('option')
option.text = preprocessPath(path) option.text = preprocessPath(path)
option.value = path option.value = path
field.appendChild(option) field.appendChild(option)
@ -104,11 +104,11 @@ function showSortModal (container, json, onSort, options) {
field.value = selectedPath || paths[0] field.value = selectedPath || paths[0]
setDirection(selectedDirection || 'asc') setDirection(selectedDirection || 'asc')
direction.onclick = function (event) { direction.onclick = event => {
setDirection(event.target.getAttribute('data-value')) setDirection(event.target.getAttribute('data-value'))
} }
ok.onclick = function (event) { ok.onclick = event => {
event.preventDefault() event.preventDefault()
event.stopPropagation() event.stopPropagation()
@ -124,7 +124,7 @@ function showSortModal (container, json, onSort, options) {
form.onsubmit = ok.onclick form.onsubmit = ok.onclick
} }
}) })
.afterClose(function (modal) { .afterClose(modal => {
modal.destroy() modal.destroy()
}) })
.show() .show()

View File

@ -1,11 +1,11 @@
var jmespath = require('jmespath') const jmespath = require('jmespath')
var picoModal = require('picomodal') const picoModal = require('picomodal')
var Selectr = require('./assets/selectr/selectr') const Selectr = require('./assets/selectr/selectr')
var translate = require('./i18n').translate const translate = require('./i18n').translate
var stringifyPartial = require('./jsonUtils').stringifyPartial const stringifyPartial = require('./jsonUtils').stringifyPartial
var util = require('./util') const util = require('./util')
var MAX_PREVIEW_CHARACTERS = require('./constants').MAX_PREVIEW_CHARACTERS const MAX_PREVIEW_CHARACTERS = require('./constants').MAX_PREVIEW_CHARACTERS
var debounce = util.debounce const debounce = util.debounce
/** /**
* Show advanced filter and transform modal using JMESPath * Show advanced filter and transform modal using JMESPath
@ -16,9 +16,9 @@ var debounce = util.debounce
* query as callback * query as callback
*/ */
function showTransformModal (container, json, onTransform) { function showTransformModal (container, json, onTransform) {
var value = json const value = json
var content = '<label class="pico-modal-contents">' + const content = '<label class="pico-modal-contents">' +
'<div class="pico-modal-header">' + translate('transform') + '</div>' + '<div class="pico-modal-header">' + translate('transform') + '</div>' +
'<p>' + '<p>' +
'Enter a <a href="http://jmespath.org" target="_blank">JMESPath</a> query to filter, sort, or transform the JSON data.<br/>' + 'Enter a <a href="http://jmespath.org" target="_blank">JMESPath</a> query to filter, sort, or transform the JSON data.<br/>' +
@ -106,63 +106,61 @@ function showTransformModal (container, json, onTransform) {
modalClass: 'jsoneditor-modal jsoneditor-modal-transform', modalClass: 'jsoneditor-modal jsoneditor-modal-transform',
focus: false focus: false
}) })
.afterCreate(function (modal) { .afterCreate(modal => {
var elem = modal.modalElem() const elem = modal.modalElem()
var wizard = elem.querySelector('#wizard') const wizard = elem.querySelector('#wizard')
var ok = elem.querySelector('#ok') const ok = elem.querySelector('#ok')
var filterField = elem.querySelector('#filterField') const filterField = elem.querySelector('#filterField')
var filterRelation = elem.querySelector('#filterRelation') const filterRelation = elem.querySelector('#filterRelation')
var filterValue = elem.querySelector('#filterValue') const filterValue = elem.querySelector('#filterValue')
var sortField = elem.querySelector('#sortField') const sortField = elem.querySelector('#sortField')
var sortOrder = elem.querySelector('#sortOrder') const sortOrder = elem.querySelector('#sortOrder')
var selectFields = elem.querySelector('#selectFields') const selectFields = elem.querySelector('#selectFields')
var query = elem.querySelector('#query') const query = elem.querySelector('#query')
var preview = elem.querySelector('#preview') const preview = elem.querySelector('#preview')
if (!Array.isArray(value)) { if (!Array.isArray(value)) {
wizard.style.fontStyle = 'italic' wizard.style.fontStyle = 'italic'
wizard.innerHTML = '(wizard not available for objects, only for arrays)' wizard.innerHTML = '(wizard not available for objects, only for arrays)'
} }
var sortablePaths = util.getChildPaths(json) const sortablePaths = util.getChildPaths(json)
sortablePaths.forEach(function (path) { sortablePaths.forEach(path => {
var formattedPath = preprocessPath(path) const formattedPath = preprocessPath(path)
var filterOption = document.createElement('option') const filterOption = document.createElement('option')
filterOption.text = formattedPath filterOption.text = formattedPath
filterOption.value = formattedPath filterOption.value = formattedPath
filterField.appendChild(filterOption) filterField.appendChild(filterOption)
var sortOption = document.createElement('option') const sortOption = document.createElement('option')
sortOption.text = formattedPath sortOption.text = formattedPath
sortOption.value = formattedPath sortOption.value = formattedPath
sortField.appendChild(sortOption) sortField.appendChild(sortOption)
}) })
var selectablePaths = util.getChildPaths(json, true).filter(function (path) { const selectablePaths = util.getChildPaths(json, true).filter(path => path !== '')
return path !== ''
})
if (selectablePaths.length > 0) { if (selectablePaths.length > 0) {
selectablePaths.forEach(function (path) { selectablePaths.forEach(path => {
var formattedPath = preprocessPath(path) const formattedPath = preprocessPath(path)
var option = document.createElement('option') const option = document.createElement('option')
option.text = formattedPath option.text = formattedPath
option.value = formattedPath option.value = formattedPath
selectFields.appendChild(option) selectFields.appendChild(option)
}) })
} else { } else {
var selectFieldsPart = elem.querySelector('#selectFieldsPart') const selectFieldsPart = elem.querySelector('#selectFieldsPart')
if (selectFieldsPart) { if (selectFieldsPart) {
selectFieldsPart.style.display = 'none' selectFieldsPart.style.display = 'none'
} }
} }
var selectrFilterField = new Selectr(filterField, { defaultSelected: false, clearable: true, allowDeselect: true, placeholder: 'field...' }) const selectrFilterField = new Selectr(filterField, { defaultSelected: false, clearable: true, allowDeselect: true, placeholder: 'field...' })
var selectrFilterRelation = new Selectr(filterRelation, { defaultSelected: false, clearable: true, allowDeselect: true, placeholder: 'compare...' }) const selectrFilterRelation = new Selectr(filterRelation, { defaultSelected: false, clearable: true, allowDeselect: true, placeholder: 'compare...' })
var selectrSortField = new Selectr(sortField, { defaultSelected: false, clearable: true, allowDeselect: true, placeholder: 'field...' }) const selectrSortField = new Selectr(sortField, { defaultSelected: false, clearable: true, allowDeselect: true, placeholder: 'field...' })
var selectrSortOrder = new Selectr(sortOrder, { defaultSelected: false, clearable: true, allowDeselect: true, placeholder: 'order...' }) const selectrSortOrder = new Selectr(sortOrder, { defaultSelected: false, clearable: true, allowDeselect: true, placeholder: 'order...' })
var selectrSelectFields = new Selectr(selectFields, { multiple: true, clearable: true, defaultSelected: false, placeholder: 'select fields...' }) const selectrSelectFields = new Selectr(selectFields, { multiple: true, clearable: true, defaultSelected: false, placeholder: 'select fields...' })
selectrFilterField.on('selectr.change', generateQueryFromWizard) selectrFilterField.on('selectr.change', generateQueryFromWizard)
selectrFilterRelation.on('selectr.change', generateQueryFromWizard) selectrFilterRelation.on('selectr.change', generateQueryFromWizard)
@ -171,7 +169,7 @@ function showTransformModal (container, json, onTransform) {
selectrSortOrder.on('selectr.change', generateQueryFromWizard) selectrSortOrder.on('selectr.change', generateQueryFromWizard)
selectrSelectFields.on('selectr.change', generateQueryFromWizard) selectrSelectFields.on('selectr.change', generateQueryFromWizard)
elem.querySelector('.pico-modal-contents').onclick = function (event) { elem.querySelector('.pico-modal-contents').onclick = event => {
// prevent the first clear button (in any select box) from getting // prevent the first clear button (in any select box) from getting
// focus when clicking anywhere in the modal. Only allow clicking links. // focus when clicking anywhere in the modal. Only allow clicking links.
if (event.target.nodeName !== 'A') { if (event.target.nodeName !== 'A') {
@ -191,12 +189,12 @@ function showTransformModal (container, json, onTransform) {
function generateQueryFromWizard () { function generateQueryFromWizard () {
if (filterField.value && filterRelation.value && filterValue.value) { if (filterField.value && filterRelation.value && filterValue.value) {
var field1 = filterField.value const field1 = filterField.value
var examplePath = field1 !== '@' const examplePath = field1 !== '@'
? ['0'].concat(util.parsePath('.' + field1)) ? ['0'].concat(util.parsePath('.' + field1))
: ['0'] : ['0']
var exampleValue = util.get(value, examplePath) const exampleValue = util.get(value, examplePath)
var value1 = typeof exampleValue === 'string' const value1 = typeof exampleValue === 'string'
? filterValue.value ? filterValue.value
: util.parseString(filterValue.value) : util.parseString(filterValue.value)
@ -210,7 +208,7 @@ function showTransformModal (container, json, onTransform) {
} }
if (sortField.value && sortOrder.value) { if (sortField.value && sortOrder.value) {
var field2 = sortField.value const field2 = sortField.value
if (sortOrder.value === 'desc') { if (sortOrder.value === 'desc') {
query.value += ' | reverse(sort_by(@, &' + field2 + '))' query.value += ' | reverse(sort_by(@, &' + field2 + '))'
} else { } else {
@ -219,10 +217,10 @@ function showTransformModal (container, json, onTransform) {
} }
if (selectFields.value) { if (selectFields.value) {
var values = [] const values = []
for (var i = 0; i < selectFields.options.length; i++) { for (let i = 0; i < selectFields.options.length; i++) {
if (selectFields.options[i].selected) { if (selectFields.options[i].selected) {
var selectedValue = selectFields.options[i].value const selectedValue = selectFields.options[i].value
values.push(selectedValue) values.push(selectedValue)
} }
} }
@ -235,9 +233,9 @@ function showTransformModal (container, json, onTransform) {
query.value += '.' + values[0] query.value += '.' + values[0]
} else if (values.length > 1) { } else if (values.length > 1) {
query.value += '.{' + query.value += '.{' +
values.map(function (value) { values.map(value => {
var parts = value.split('.') const parts = value.split('.')
var last = parts[parts.length - 1] const last = parts[parts.length - 1]
return last + ': ' + value return last + ': ' + value
}).join(', ') + }).join(', ') +
'}' '}'
@ -251,7 +249,7 @@ function showTransformModal (container, json, onTransform) {
function updatePreview () { function updatePreview () {
try { try {
var transformed = jmespath.search(value, query.value) const transformed = jmespath.search(value, query.value)
preview.className = 'jsoneditor-transform-preview' preview.className = 'jsoneditor-transform-preview'
preview.value = stringifyPartial(transformed, 2, MAX_PREVIEW_CHARACTERS) preview.value = stringifyPartial(transformed, 2, MAX_PREVIEW_CHARACTERS)
@ -269,7 +267,7 @@ function showTransformModal (container, json, onTransform) {
query.oninput = debouncedUpdatePreview query.oninput = debouncedUpdatePreview
debouncedUpdatePreview() debouncedUpdatePreview()
ok.onclick = function (event) { ok.onclick = event => {
event.preventDefault() event.preventDefault()
event.stopPropagation() event.stopPropagation()
@ -278,14 +276,14 @@ function showTransformModal (container, json, onTransform) {
onTransform(query.value) onTransform(query.value)
} }
setTimeout(function () { setTimeout(() => {
query.select() query.select()
query.focus() query.focus()
query.selectionStart = 3 query.selectionStart = 3
query.selectionEnd = 3 query.selectionEnd = 3
}) })
}) })
.afterClose(function (modal) { .afterClose(modal => {
modal.destroy() modal.destroy()
}) })
.show() .show()

View File

@ -1,20 +1,20 @@
'use strict' 'use strict'
var ace = require('./ace') const ace = require('./ace')
var jmespath = require('jmespath') const jmespath = require('jmespath')
var translate = require('./i18n').translate const translate = require('./i18n').translate
var ModeSwitcher = require('./ModeSwitcher') const ModeSwitcher = require('./ModeSwitcher')
var ErrorTable = require('./ErrorTable') const ErrorTable = require('./ErrorTable')
var validateCustom = require('./validationUtils').validateCustom const validateCustom = require('./validationUtils').validateCustom
var showSortModal = require('./showSortModal') const showSortModal = require('./showSortModal')
var showTransformModal = require('./showTransformModal') const showTransformModal = require('./showTransformModal')
var util = require('./util') const util = require('./util')
var DEFAULT_MODAL_ANCHOR = require('./constants').DEFAULT_MODAL_ANCHOR const DEFAULT_MODAL_ANCHOR = require('./constants').DEFAULT_MODAL_ANCHOR
// create a mixin with the functions for text mode // create a mixin with the functions for text mode
var textmode = {} const textmode = {}
var DEFAULT_THEME = 'ace/theme/jsoneditor' const DEFAULT_THEME = 'ace/theme/jsoneditor'
/** /**
* Create a text editor * Create a text editor
@ -45,7 +45,7 @@ textmode.create = function (container, options) {
} }
// grab ace from options if provided // grab ace from options if provided
var _ace = options.ace ? options.ace : ace const _ace = options.ace ? options.ace : ace
// TODO: make the option options.ace deprecated, it's not needed anymore (see #309) // TODO: make the option options.ace deprecated, it's not needed anymore (see #309)
// determine mode // determine mode
@ -72,7 +72,7 @@ textmode.create = function (container, options) {
this.onTextSelectionChange(options.onTextSelectionChange) this.onTextSelectionChange(options.onTextSelectionChange)
} }
var me = this const me = this
this.container = container this.container = container
this.dom = {} this.dom = {}
this.aceEditor = undefined // ace code editor this.aceEditor = undefined // ace code editor
@ -88,11 +88,11 @@ textmode.create = function (container, options) {
this.frame = document.createElement('div') this.frame = document.createElement('div')
this.frame.className = 'jsoneditor jsoneditor-mode-' + this.options.mode this.frame.className = 'jsoneditor jsoneditor-mode-' + this.options.mode
this.frame.onclick = function (event) { this.frame.onclick = event => {
// prevent default submit action when the editor is located inside a form // prevent default submit action when the editor is located inside a form
event.preventDefault() event.preventDefault()
} }
this.frame.onkeydown = function (event) { this.frame.onkeydown = event => {
me._onKeyDown(event) me._onKeyDown(event)
} }
@ -108,12 +108,12 @@ textmode.create = function (container, options) {
this.frame.appendChild(this.menu) this.frame.appendChild(this.menu)
// create format button // create format button
var buttonFormat = document.createElement('button') const buttonFormat = document.createElement('button')
buttonFormat.type = 'button' buttonFormat.type = 'button'
buttonFormat.className = 'jsoneditor-format' buttonFormat.className = 'jsoneditor-format'
buttonFormat.title = 'Format JSON data, with proper indentation and line feeds (Ctrl+\\)' buttonFormat.title = 'Format JSON data, with proper indentation and line feeds (Ctrl+\\)'
this.menu.appendChild(buttonFormat) this.menu.appendChild(buttonFormat)
buttonFormat.onclick = function () { buttonFormat.onclick = () => {
try { try {
me.format() me.format()
me._onChange() me._onChange()
@ -123,12 +123,12 @@ textmode.create = function (container, options) {
} }
// create compact button // create compact button
var buttonCompact = document.createElement('button') const buttonCompact = document.createElement('button')
buttonCompact.type = 'button' buttonCompact.type = 'button'
buttonCompact.className = 'jsoneditor-compact' buttonCompact.className = 'jsoneditor-compact'
buttonCompact.title = 'Compact JSON data, remove all whitespaces (Ctrl+Shift+\\)' buttonCompact.title = 'Compact JSON data, remove all whitespaces (Ctrl+Shift+\\)'
this.menu.appendChild(buttonCompact) this.menu.appendChild(buttonCompact)
buttonCompact.onclick = function () { buttonCompact.onclick = () => {
try { try {
me.compact() me.compact()
me._onChange() me._onChange()
@ -139,11 +139,11 @@ textmode.create = function (container, options) {
// create sort button // create sort button
if (this.options.enableSort) { if (this.options.enableSort) {
var sort = document.createElement('button') const sort = document.createElement('button')
sort.type = 'button' sort.type = 'button'
sort.className = 'jsoneditor-sort' sort.className = 'jsoneditor-sort'
sort.title = translate('sortTitleShort') sort.title = translate('sortTitleShort')
sort.onclick = function () { sort.onclick = () => {
me._showSortModal() me._showSortModal()
} }
this.menu.appendChild(sort) this.menu.appendChild(sort)
@ -151,23 +151,23 @@ textmode.create = function (container, options) {
// create transform button // create transform button
if (this.options.enableTransform) { if (this.options.enableTransform) {
var transform = document.createElement('button') const transform = document.createElement('button')
transform.type = 'button' transform.type = 'button'
transform.title = translate('transformTitleShort') transform.title = translate('transformTitleShort')
transform.className = 'jsoneditor-transform' transform.className = 'jsoneditor-transform'
transform.onclick = function () { transform.onclick = () => {
me._showTransformModal() me._showTransformModal()
} }
this.menu.appendChild(transform) this.menu.appendChild(transform)
} }
// create repair button // create repair button
var buttonRepair = document.createElement('button') const buttonRepair = document.createElement('button')
buttonRepair.type = 'button' buttonRepair.type = 'button'
buttonRepair.className = 'jsoneditor-repair' buttonRepair.className = 'jsoneditor-repair'
buttonRepair.title = 'Repair JSON: fix quotes and escape characters, remove comments and JSONP notation, turn JavaScript objects into JSON.' buttonRepair.title = 'Repair JSON: fix quotes and escape characters, remove comments and JSONP notation, turn JavaScript objects into JSON.'
this.menu.appendChild(buttonRepair) this.menu.appendChild(buttonRepair)
buttonRepair.onclick = function () { buttonRepair.onclick = () => {
try { try {
me.repair() me.repair()
me._onChange() me._onChange()
@ -186,12 +186,12 @@ textmode.create = function (container, options) {
} }
if (this.mode === 'code') { if (this.mode === 'code') {
var poweredBy = document.createElement('a') const poweredBy = document.createElement('a')
poweredBy.appendChild(document.createTextNode('powered by ace')) poweredBy.appendChild(document.createTextNode('powered by ace'))
poweredBy.href = 'http://ace.ajax.org' poweredBy.href = 'http://ace.ajax.org'
poweredBy.target = '_blank' poweredBy.target = '_blank'
poweredBy.className = 'jsoneditor-poweredBy' poweredBy.className = 'jsoneditor-poweredBy'
poweredBy.onclick = function () { poweredBy.onclick = () => {
// TODO: this anchor falls below the margin of the content, // TODO: this anchor falls below the margin of the content,
// therefore the normal a.href does not work. We use a click event // therefore the normal a.href does not work. We use a click event
// for now, but this should be fixed. // for now, but this should be fixed.
@ -201,8 +201,8 @@ textmode.create = function (container, options) {
} }
} }
var emptyNode = {} const emptyNode = {}
var isReadOnly = (this.options.onEditable && const isReadOnly = (this.options.onEditable &&
typeof (this.options.onEditable === 'function') && typeof (this.options.onEditable === 'function') &&
!this.options.onEditable(emptyNode)) !this.options.onEditable(emptyNode))
@ -215,8 +215,8 @@ textmode.create = function (container, options) {
this.editorDom.style.width = '100%' // TODO: move to css this.editorDom.style.width = '100%' // TODO: move to css
this.content.appendChild(this.editorDom) this.content.appendChild(this.editorDom)
var aceEditor = _ace.edit(this.editorDom) const aceEditor = _ace.edit(this.editorDom)
var aceSession = aceEditor.getSession() const aceSession = aceEditor.getSession()
aceEditor.$blockScrolling = Infinity aceEditor.$blockScrolling = Infinity
aceEditor.setTheme(this.theme) aceEditor.setTheme(this.theme)
aceEditor.setOptions({ readOnly: isReadOnly }) aceEditor.setOptions({ readOnly: isReadOnly })
@ -228,7 +228,7 @@ textmode.create = function (container, options) {
aceSession.setUseWrapMode(true) aceSession.setUseWrapMode(true)
// replace ace setAnnotations with custom function that also covers jsoneditor annotations // replace ace setAnnotations with custom function that also covers jsoneditor annotations
var originalSetAnnotations = aceSession.setAnnotations const originalSetAnnotations = aceSession.setAnnotations
aceSession.setAnnotations = function (annotations) { aceSession.setAnnotations = function (annotations) {
originalSetAnnotations.call(this, annotations && annotations.length ? annotations : me.annotations) originalSetAnnotations.call(this, annotations && annotations.length ? annotations : me.annotations)
} }
@ -242,7 +242,7 @@ textmode.create = function (container, options) {
aceEditor.on('changeSelection', this._onSelect.bind(this)) aceEditor.on('changeSelection', this._onSelect.bind(this))
} else { } else {
// load a plain text textarea // load a plain text textarea
var textarea = document.createElement('textarea') const textarea = document.createElement('textarea')
textarea.className = 'jsoneditor-text' textarea.className = 'jsoneditor-text'
textarea.spellcheck = false textarea.spellcheck = false
this.content.appendChild(textarea) this.content.appendChild(textarea)
@ -275,8 +275,8 @@ textmode.create = function (container, options) {
}, },
onChangeHeight: function (height) { onChangeHeight: function (height) {
// TODO: change CSS to using flex box, remove setting height using JavaScript // TODO: change CSS to using flex box, remove setting height using JavaScript
var statusBarHeight = me.dom.statusBar ? me.dom.statusBar.clientHeight : 0 const statusBarHeight = me.dom.statusBar ? me.dom.statusBar.clientHeight : 0
var totalHeight = height + statusBarHeight + 1 const totalHeight = height + statusBarHeight + 1
me.content.style.marginBottom = (-totalHeight) + 'px' me.content.style.marginBottom = (-totalHeight) + 'px'
me.content.style.paddingBottom = totalHeight + 'px' me.content.style.paddingBottom = totalHeight + 'px'
} }
@ -287,27 +287,27 @@ textmode.create = function (container, options) {
util.addClassName(this.content, 'has-status-bar') util.addClassName(this.content, 'has-status-bar')
this.curserInfoElements = {} this.curserInfoElements = {}
var statusBar = document.createElement('div') const statusBar = document.createElement('div')
this.dom.statusBar = statusBar this.dom.statusBar = statusBar
statusBar.className = 'jsoneditor-statusbar' statusBar.className = 'jsoneditor-statusbar'
this.frame.appendChild(statusBar) this.frame.appendChild(statusBar)
var lnLabel = document.createElement('span') const lnLabel = document.createElement('span')
lnLabel.className = 'jsoneditor-curserinfo-label' lnLabel.className = 'jsoneditor-curserinfo-label'
lnLabel.innerText = 'Ln:' lnLabel.innerText = 'Ln:'
var lnVal = document.createElement('span') const lnVal = document.createElement('span')
lnVal.className = 'jsoneditor-curserinfo-val' lnVal.className = 'jsoneditor-curserinfo-val'
lnVal.innerText = '1' lnVal.innerText = '1'
statusBar.appendChild(lnLabel) statusBar.appendChild(lnLabel)
statusBar.appendChild(lnVal) statusBar.appendChild(lnVal)
var colLabel = document.createElement('span') const colLabel = document.createElement('span')
colLabel.className = 'jsoneditor-curserinfo-label' colLabel.className = 'jsoneditor-curserinfo-label'
colLabel.innerText = 'Col:' colLabel.innerText = 'Col:'
var colVal = document.createElement('span') const colVal = document.createElement('span')
colVal.className = 'jsoneditor-curserinfo-val' colVal.className = 'jsoneditor-curserinfo-val'
colVal.innerText = '1' colVal.innerText = '1'
@ -317,12 +317,12 @@ textmode.create = function (container, options) {
this.curserInfoElements.colVal = colVal this.curserInfoElements.colVal = colVal
this.curserInfoElements.lnVal = lnVal this.curserInfoElements.lnVal = lnVal
var countLabel = document.createElement('span') const countLabel = document.createElement('span')
countLabel.className = 'jsoneditor-curserinfo-label' countLabel.className = 'jsoneditor-curserinfo-label'
countLabel.innerText = 'characters selected' countLabel.innerText = 'characters selected'
countLabel.style.display = 'none' countLabel.style.display = 'none'
var countVal = document.createElement('span') const countVal = document.createElement('span')
countVal.className = 'jsoneditor-curserinfo-count' countVal.className = 'jsoneditor-curserinfo-count'
countVal.innerText = '0' countVal.innerText = '0'
countVal.style.display = 'none' countVal.style.display = 'none'
@ -407,11 +407,11 @@ textmode._showSortModal = function () {
* @private * @private
*/ */
textmode._showTransformModal = function () { textmode._showTransformModal = function () {
var me = this const me = this
var anchor = this.options.modalAnchor || DEFAULT_MODAL_ANCHOR const anchor = this.options.modalAnchor || DEFAULT_MODAL_ANCHOR
var json = this.get() const json = this.get()
showTransformModal(anchor, json, function (query) { showTransformModal(anchor, json, query => {
var updatedJson = jmespath.search(json, query) const updatedJson = jmespath.search(json, query)
me.set(updatedJson) me.set(updatedJson)
}) })
} }
@ -432,8 +432,8 @@ textmode._onSelect = function () {
* @private * @private
*/ */
textmode._onKeyDown = function (event) { textmode._onKeyDown = function (event) {
var keynum = event.which || event.keyCode const keynum = event.which || event.keyCode
var handled = false let handled = false
if (keynum === 220 && event.ctrlKey) { if (keynum === 220 && event.ctrlKey) {
if (event.shiftKey) { // Ctrl+Shift+\ if (event.shiftKey) { // Ctrl+Shift+\
@ -469,10 +469,10 @@ textmode._onMouseDown = function () {
* @private * @private
*/ */
textmode._onBlur = function () { textmode._onBlur = function () {
var me = this const me = this
// this allows to avoid blur when clicking inner elements (like the errors panel) // this allows to avoid blur when clicking inner elements (like the errors panel)
// just make sure to set the isFocused to true on the inner element onclick callback // just make sure to set the isFocused to true on the inner element onclick callback
setTimeout(function () { setTimeout(() => {
if (!me.isFocused) { if (!me.isFocused) {
me._updateCursorInfo() me._updateCursorInfo()
me._emitSelectionChange() me._emitSelectionChange()
@ -485,12 +485,12 @@ textmode._onBlur = function () {
* Update the cursor info and the status bar, if presented * Update the cursor info and the status bar, if presented
*/ */
textmode._updateCursorInfo = function () { textmode._updateCursorInfo = function () {
var me = this const me = this
var line, col, count let line, col, count
if (this.textarea) { if (this.textarea) {
setTimeout(function () { // this to verify we get the most updated textarea cursor selection setTimeout(() => { // this to verify we get the most updated textarea cursor selection
var selectionRange = util.getInputSelection(me.textarea) const selectionRange = util.getInputSelection(me.textarea)
if (selectionRange.startIndex !== selectionRange.endIndex) { if (selectionRange.startIndex !== selectionRange.endIndex) {
count = selectionRange.endIndex - selectionRange.startIndex count = selectionRange.endIndex - selectionRange.startIndex
@ -515,8 +515,8 @@ textmode._updateCursorInfo = function () {
} }
}, 0) }, 0)
} else if (this.aceEditor && this.curserInfoElements) { } else if (this.aceEditor && this.curserInfoElements) {
var curserPos = this.aceEditor.getCursorPosition() const curserPos = this.aceEditor.getCursorPosition()
var selectedText = this.aceEditor.getSelectedText() const selectedText = this.aceEditor.getSelectedText()
line = curserPos.row + 1 line = curserPos.row + 1
col = curserPos.column + 1 col = curserPos.column + 1
@ -550,7 +550,7 @@ textmode._updateCursorInfo = function () {
*/ */
textmode._emitSelectionChange = function () { textmode._emitSelectionChange = function () {
if (this._selectionChangedHandler) { if (this._selectionChangedHandler) {
var currentSelection = this.getTextSelection() const currentSelection = this.getTextSelection()
this._selectionChangedHandler(currentSelection.start, currentSelection.end, currentSelection.text) this._selectionChangedHandler(currentSelection.start, currentSelection.end, currentSelection.text)
} }
} }
@ -563,9 +563,9 @@ textmode._emitSelectionChange = function () {
* @private * @private
*/ */
textmode._refreshAnnotations = function () { textmode._refreshAnnotations = function () {
var session = this.aceEditor && this.aceEditor.getSession() const session = this.aceEditor && this.aceEditor.getSession()
if (session) { if (session) {
var errEnnotations = session.getAnnotations().filter(function (annotation) { return annotation.type === 'error' }) const errEnnotations = session.getAnnotations().filter(annotation => annotation.type === 'error')
session.setAnnotations(errEnnotations) session.setAnnotations(errEnnotations)
} }
} }
@ -598,8 +598,8 @@ textmode.destroy = function () {
* Compact the code in the text editor * Compact the code in the text editor
*/ */
textmode.compact = function () { textmode.compact = function () {
var json = this.get() const json = this.get()
var text = JSON.stringify(json) const text = JSON.stringify(json)
this._setText(text, false) this._setText(text, false)
} }
@ -607,8 +607,8 @@ textmode.compact = function () {
* Format the code in the text editor * Format the code in the text editor
*/ */
textmode.format = function () { textmode.format = function () {
var json = this.get() const json = this.get()
var text = JSON.stringify(json, null, this.indentation) const text = JSON.stringify(json, null, this.indentation)
this._setText(text, false) this._setText(text, false)
} }
@ -616,8 +616,8 @@ textmode.format = function () {
* Repair the code in the text editor * Repair the code in the text editor
*/ */
textmode.repair = function () { textmode.repair = function () {
var text = this.getText() const text = this.getText()
var repairedText = util.repair(text) const repairedText = util.repair(text)
this._setText(repairedText, false) this._setText(repairedText, false)
} }
@ -638,7 +638,7 @@ textmode.focus = function () {
*/ */
textmode.resize = function () { textmode.resize = function () {
if (this.aceEditor) { if (this.aceEditor) {
var force = false const force = false
this.aceEditor.resize(force) this.aceEditor.resize(force)
} }
} }
@ -664,7 +664,7 @@ textmode.update = function (json) {
* @return {*} json * @return {*} json
*/ */
textmode.get = function () { textmode.get = function () {
var text = this.getText() const text = this.getText()
return util.parse(text) // this can throw an error return util.parse(text) // this can throw an error
} }
@ -690,7 +690,7 @@ textmode.getText = function () {
* @private * @private
*/ */
textmode._setText = function (jsonText, clearHistory) { textmode._setText = function (jsonText, clearHistory) {
var text let text
if (this.options.escapeUnicode === true) { if (this.options.escapeUnicode === true) {
text = util.escapeUnicodeChars(jsonText) text = util.escapeUnicodeChars(jsonText)
@ -709,8 +709,8 @@ textmode._setText = function (jsonText, clearHistory) {
if (clearHistory) { if (clearHistory) {
// prevent initial undo action clearing the initial contents // prevent initial undo action clearing the initial contents
var me = this const me = this
setTimeout(function () { setTimeout(() => {
me.aceEditor.session.getUndoManager().reset() me.aceEditor.session.getUndoManager().reset()
}, 0) }, 0)
} }
@ -747,17 +747,17 @@ textmode.updateText = function (jsonText) {
* Throws an exception when no JSON schema is configured * Throws an exception when no JSON schema is configured
*/ */
textmode.validate = function () { textmode.validate = function () {
var schemaErrors = [] let schemaErrors = []
var parseErrors = [] let parseErrors = []
var json let json
try { try {
json = this.get() // this can fail when there is no valid json json = this.get() // this can fail when there is no valid json
// execute JSON schema validation (ajv) // execute JSON schema validation (ajv)
if (this.validateSchema) { if (this.validateSchema) {
var valid = this.validateSchema(json) const valid = this.validateSchema(json)
if (!valid) { if (!valid) {
schemaErrors = this.validateSchema.errors.map(function (error) { schemaErrors = this.validateSchema.errors.map(error => {
error.type = 'validation' error.type = 'validation'
return util.improveSchemaError(error) return util.improveSchemaError(error)
}) })
@ -767,24 +767,24 @@ textmode.validate = function () {
// execute custom validation and after than merge and render all errors // execute custom validation and after than merge and render all errors
// TODO: implement a better mechanism for only using the last validation action // TODO: implement a better mechanism for only using the last validation action
this.validationSequence = (this.validationSequence || 0) + 1 this.validationSequence = (this.validationSequence || 0) + 1
var me = this const me = this
var seq = this.validationSequence const seq = this.validationSequence
validateCustom(json, this.options.onValidate) validateCustom(json, this.options.onValidate)
.then(function (customValidationErrors) { .then(customValidationErrors => {
// only apply when there was no other validation started whilst resolving async results // only apply when there was no other validation started whilst resolving async results
if (seq === me.validationSequence) { if (seq === me.validationSequence) {
var errors = schemaErrors.concat(parseErrors).concat(customValidationErrors) const errors = schemaErrors.concat(parseErrors).concat(customValidationErrors)
me._renderErrors(errors) me._renderErrors(errors)
} }
}) })
.catch(function (err) { .catch(err => {
console.error('Custom validation function did throw an error', err) console.error('Custom validation function did throw an error', err)
}) })
} catch (err) { } catch (err) {
if (this.getText()) { if (this.getText()) {
// try to extract the line number from the jsonlint error message // try to extract the line number from the jsonlint error message
var match = /\w*line\s*(\d+)\w*/g.exec(err.message) const match = /\w*line\s*(\d+)\w*/g.exec(err.message)
var line let line
if (match) { if (match) {
line = +match[1] line = +match[1]
} }
@ -800,21 +800,21 @@ textmode.validate = function () {
} }
textmode._renderErrors = function (errors) { textmode._renderErrors = function (errors) {
var jsonText = this.getText() const jsonText = this.getText()
var errorPaths = [] const errorPaths = []
errors.reduce(function (acc, curr) { errors.reduce((acc, curr) => {
if (acc.indexOf(curr.dataPath) === -1) { if (acc.indexOf(curr.dataPath) === -1) {
acc.push(curr.dataPath) acc.push(curr.dataPath)
} }
return acc return acc
}, errorPaths) }, errorPaths)
var errorLocations = util.getPositionForPath(jsonText, errorPaths) const errorLocations = util.getPositionForPath(jsonText, errorPaths)
// render annotations in Ace Editor (if any) // render annotations in Ace Editor (if any)
if (this.aceEditor) { if (this.aceEditor) {
this.annotations = errorLocations.map(function (errLoc) { this.annotations = errorLocations.map(errLoc => {
var validationErrors = errors.filter(function (err) { return err.dataPath === errLoc.path }) const validationErrors = errors.filter(err => err.dataPath === errLoc.path)
var message = validationErrors.map(function (err) { return err.message }).join('\n') const message = validationErrors.map(err => err.message).join('\n')
if (message) { if (message) {
return { return {
row: errLoc.line, row: errLoc.line,
@ -835,7 +835,7 @@ textmode._renderErrors = function (errors) {
// update the height of the ace editor // update the height of the ace editor
if (this.aceEditor) { if (this.aceEditor) {
var force = false const force = false
this.aceEditor.resize(force) this.aceEditor.resize(force)
} }
} }
@ -845,9 +845,9 @@ textmode._renderErrors = function (errors) {
* @returns {{start:{row:Number, column:Number},end:{row:Number, column:Number},text:String}} * @returns {{start:{row:Number, column:Number},end:{row:Number, column:Number},text:String}}
*/ */
textmode.getTextSelection = function () { textmode.getTextSelection = function () {
var selection = {} let selection = {}
if (this.textarea) { if (this.textarea) {
var selectionRange = util.getInputSelection(this.textarea) const selectionRange = util.getInputSelection(this.textarea)
if (this.cursorInfo && this.cursorInfo.line === selectionRange.end.row && this.cursorInfo.column === selectionRange.end.column) { if (this.cursorInfo && this.cursorInfo.line === selectionRange.end.row && this.cursorInfo.column === selectionRange.end.column) {
// selection direction is bottom => up // selection direction is bottom => up
@ -865,10 +865,10 @@ textmode.getTextSelection = function () {
} }
if (this.aceEditor) { if (this.aceEditor) {
var aceSelection = this.aceEditor.getSelection() const aceSelection = this.aceEditor.getSelection()
var selectedText = this.aceEditor.getSelectedText() const selectedText = this.aceEditor.getSelectedText()
var range = aceSelection.getRange() const range = aceSelection.getRange()
var lead = aceSelection.getSelectionLead() const lead = aceSelection.getSelectionLead()
if (lead.row === range.end.row && lead.column === range.end.column) { if (lead.row === range.end.row && lead.column === range.end.column) {
selection = range selection = range
@ -913,8 +913,8 @@ textmode.setTextSelection = function (startPos, endPos) {
if (!startPos || !endPos) return if (!startPos || !endPos) return
if (this.textarea) { if (this.textarea) {
var startIndex = util.getIndexForPosition(this.textarea, startPos.row, startPos.column) const startIndex = util.getIndexForPosition(this.textarea, startPos.row, startPos.column)
var endIndex = util.getIndexForPosition(this.textarea, endPos.row, endPos.column) const endIndex = util.getIndexForPosition(this.textarea, endPos.row, endPos.column)
if (startIndex > -1 && endIndex > -1) { if (startIndex > -1 && endIndex > -1) {
if (this.textarea.setSelectionRange) { if (this.textarea.setSelectionRange) {
this.textarea.focus() this.textarea.focus()
@ -926,9 +926,9 @@ textmode.setTextSelection = function (startPos, endPos) {
range.moveStart('character', startIndex) range.moveStart('character', startIndex)
range.select() range.select()
} }
var rows = (this.textarea.value.match(/\n/g) || []).length + 1 const rows = (this.textarea.value.match(/\n/g) || []).length + 1
var lineHeight = this.textarea.scrollHeight / rows const lineHeight = this.textarea.scrollHeight / rows
var selectionScrollPos = (startPos.row * lineHeight) const selectionScrollPos = (startPos.row * lineHeight)
this.textarea.scrollTop = selectionScrollPos > this.textarea.clientHeight ? (selectionScrollPos - (this.textarea.clientHeight / 2)) : 0 this.textarea.scrollTop = selectionScrollPos > this.textarea.clientHeight ? (selectionScrollPos - (this.textarea.clientHeight / 2)) : 0
} }
} else if (this.aceEditor) { } else if (this.aceEditor) {

View File

@ -1,21 +1,21 @@
'use strict' 'use strict'
var VanillaPicker = require('./vanilla-picker') const VanillaPicker = require('./vanilla-picker')
var Highlighter = require('./Highlighter') const Highlighter = require('./Highlighter')
var NodeHistory = require('./NodeHistory') const NodeHistory = require('./NodeHistory')
var SearchBox = require('./SearchBox') const SearchBox = require('./SearchBox')
var ContextMenu = require('./ContextMenu') const ContextMenu = require('./ContextMenu')
var TreePath = require('./TreePath') const TreePath = require('./TreePath')
var Node = require('./Node') const Node = require('./Node')
var ModeSwitcher = require('./ModeSwitcher') const ModeSwitcher = require('./ModeSwitcher')
var util = require('./util') const util = require('./util')
var autocomplete = require('./autocomplete') const autocomplete = require('./autocomplete')
var translate = require('./i18n').translate const translate = require('./i18n').translate
var setLanguages = require('./i18n').setLanguages const setLanguages = require('./i18n').setLanguages
var setLanguage = require('./i18n').setLanguage const setLanguage = require('./i18n').setLanguage
// create a mixin with the functions for tree mode // create a mixin with the functions for tree mode
var treemode = {} const treemode = {}
/** /**
* Create a tree editor * Create a tree editor
@ -115,8 +115,8 @@ treemode._setOptions = function (options) {
color: color, color: color,
popup: 'bottom', popup: 'bottom',
onDone: function (color) { onDone: function (color) {
var alpha = color.rgba[3] const alpha = color.rgba[3]
var hex = (alpha === 1) const hex = (alpha === 1)
? color.hex.substr(0, 7) // return #RRGGBB ? color.hex.substr(0, 7) // return #RRGGBB
: color.hex // return #RRGGBBAA : color.hex // return #RRGGBBAA
onChange(hex) onChange(hex)
@ -168,18 +168,18 @@ treemode.set = function (json) {
this.content.removeChild(this.table) // Take the table offline this.content.removeChild(this.table) // Take the table offline
// replace the root node // replace the root node
var params = { const params = {
field: this.options.name, field: this.options.name,
value: json value: json
} }
var node = new Node(this, params) const node = new Node(this, params)
this._setRoot(node) this._setRoot(node)
// validate JSON schema (if configured) // validate JSON schema (if configured)
this.validate() this.validate()
// expand // expand
var recurse = false const recurse = false
this.node.expand(recurse) this.node.expand(recurse)
this.content.appendChild(this.table) // Put the table online again this.content.appendChild(this.table) // Put the table online again
@ -208,7 +208,7 @@ treemode.update = function (json) {
return return
} }
var selection = this.getSelection() const selection = this.getSelection()
// apply the changed json // apply the changed json
this.onChangeDisabled = true // don't fire an onChange event this.onChangeDisabled = true // don't fire an onChange event
@ -227,8 +227,8 @@ treemode.update = function (json) {
if (selection && selection.start && selection.end) { if (selection && selection.start && selection.end) {
// only keep/update the selection if both start and end node still exists, // only keep/update the selection if both start and end node still exists,
// else we clear the selection // else we clear the selection
var startNode = this.node.findNodeByPath(selection.start.path) const startNode = this.node.findNodeByPath(selection.start.path)
var endNode = this.node.findNodeByPath(selection.end.path) const endNode = this.node.findNodeByPath(selection.end.path)
if (startNode && endNode) { if (startNode && endNode) {
this.setSelection(selection.start, selection.end) this.setSelection(selection.start, selection.end)
} else { } else {
@ -271,7 +271,7 @@ treemode.setText = function (jsonText) {
this.set(util.parse(jsonText)) // this can throw an error this.set(util.parse(jsonText)) // this can throw an error
} catch (err) { } catch (err) {
// try to repair json, replace JavaScript notation with JSON notation // try to repair json, replace JavaScript notation with JSON notation
var repairedJsonText = util.repair(jsonText) const repairedJsonText = util.repair(jsonText)
// try to parse again // try to parse again
this.set(util.parse(repairedJsonText)) // this can throw an error this.set(util.parse(repairedJsonText)) // this can throw an error
@ -288,7 +288,7 @@ treemode.updateText = function (jsonText) {
this.update(util.parse(jsonText)) // this can throw an error this.update(util.parse(jsonText)) // this can throw an error
} catch (err) { } catch (err) {
// try to repair json, replace JavaScript notation with JSON notation // try to repair json, replace JavaScript notation with JSON notation
var repairJsonText = util.repair(jsonText) const repairJsonText = util.repair(jsonText)
// try to parse again // try to parse again
this.update(util.parse(repairJsonText)) // this can throw an error this.update(util.parse(repairJsonText)) // this can throw an error
@ -322,7 +322,7 @@ treemode.getName = function () {
* - to the first button in the top menu * - to the first button in the top menu
*/ */
treemode.focus = function () { treemode.focus = function () {
var input = this.scrollableContent.querySelector('[contenteditable=true]') let input = this.scrollableContent.querySelector('[contenteditable=true]')
if (input) { if (input) {
input.focus() input.focus()
} else if (this.node.dom.expand) { } else if (this.node.dom.expand) {
@ -382,7 +382,7 @@ treemode._setRoot = function (node) {
* 'value') * 'value')
*/ */
treemode.search = function (text) { treemode.search = function (text) {
var results let results
if (this.node) { if (this.node) {
this.content.removeChild(this.table) // Take the table offline this.content.removeChild(this.table) // Take the table offline
results = this.node.search(text) results = this.node.search(text)
@ -457,7 +457,7 @@ treemode._onChange = function () {
this._debouncedValidate() this._debouncedValidate()
if (this.treePath) { if (this.treePath) {
var selectedNode = (this.node && this.selection) const selectedNode = (this.node && this.selection)
? this.node.findNodeByInternalPath(this.selection.path) ? this.node.findNodeByInternalPath(this.selection.path)
: this.multiselection : this.multiselection
? this.multiselection.nodes[0] ? this.multiselection.nodes[0]
@ -517,23 +517,21 @@ treemode._onChange = function () {
* Throws an exception when no JSON schema is configured * Throws an exception when no JSON schema is configured
*/ */
treemode.validate = function () { treemode.validate = function () {
var root = this.node const root = this.node
if (!root) { // TODO: this should be redundant but is needed on mode switch if (!root) { // TODO: this should be redundant but is needed on mode switch
return return
} }
var json = root.getValue() const json = root.getValue()
// execute JSON schema validation // execute JSON schema validation
var schemaErrors = [] let schemaErrors = []
if (this.validateSchema) { if (this.validateSchema) {
var valid = this.validateSchema(json) const valid = this.validateSchema(json)
if (!valid) { if (!valid) {
// apply all new errors // apply all new errors
schemaErrors = this.validateSchema.errors schemaErrors = this.validateSchema.errors
.map(function (error) { .map(error => util.improveSchemaError(error))
return util.improveSchemaError(error)
})
.map(function findNode (error) { .map(function findNode (error) {
return { return {
node: root.findNode(error.dataPath), node: root.findNode(error.dataPath),
@ -549,17 +547,17 @@ treemode.validate = function () {
// execute custom validation and after than merge and render all errors // execute custom validation and after than merge and render all errors
try { try {
this.validationSequence++ this.validationSequence++
var me = this const me = this
var seq = this.validationSequence const seq = this.validationSequence
this._validateCustom(json) this._validateCustom(json)
.then(function (customValidationErrors) { .then(customValidationErrors => {
// only apply when there was no other validation started whilst resolving async results // only apply when there was no other validation started whilst resolving async results
if (seq === me.validationSequence) { if (seq === me.validationSequence) {
var errorNodes = [].concat(schemaErrors, customValidationErrors || []) const errorNodes = [].concat(schemaErrors, customValidationErrors || [])
me._renderValidationErrors(errorNodes) me._renderValidationErrors(errorNodes)
} }
}) })
.catch(function (err) { .catch(err => {
console.error(err) console.error(err)
}) })
} catch (err) { } catch (err) {
@ -570,39 +568,30 @@ treemode.validate = function () {
treemode._renderValidationErrors = function (errorNodes) { treemode._renderValidationErrors = function (errorNodes) {
// clear all current errors // clear all current errors
if (this.errorNodes) { if (this.errorNodes) {
this.errorNodes.forEach(function (node) { this.errorNodes.forEach(node => {
node.setError(null) node.setError(null)
}) })
} }
// render the new errors // render the new errors
var parentPairs = errorNodes const parentPairs = errorNodes
.reduce(function (all, entry) { .reduce((all, entry) => entry.node
return entry.node .findParents()
.findParents() .filter(parent => !all.some(pair => pair[0] === parent))
.filter(function (parent) { .map(parent => [parent, entry.node])
return !all.some(function (pair) { .concat(all), [])
return pair[0] === parent
})
})
.map(function (parent) {
return [parent, entry.node]
})
.concat(all)
}, [])
this.errorNodes = parentPairs this.errorNodes = parentPairs
.map(function (pair) { .map(pair => ({
return { node: pair[0],
node: pair[0], child: pair[1],
child: pair[1],
error: { error: {
message: pair[0].type === 'object' message: pair[0].type === 'object'
? 'Contains invalid properties' // object ? 'Contains invalid properties' // object
: 'Contains invalid items' // array : 'Contains invalid items' // array
}
} }
}) }))
.concat(errorNodes) .concat(errorNodes)
.map(function setError (entry) { .map(function setError (entry) {
entry.node.setError(entry.error, entry.child) entry.node.setError(entry.error, entry.child)
@ -618,18 +607,18 @@ treemode._renderValidationErrors = function (errorNodes) {
treemode._validateCustom = function (json) { treemode._validateCustom = function (json) {
try { try {
if (this.options.onValidate) { if (this.options.onValidate) {
var root = this.node const root = this.node
var customValidateResults = this.options.onValidate(json) const customValidateResults = this.options.onValidate(json)
var resultPromise = util.isPromise(customValidateResults) const resultPromise = util.isPromise(customValidateResults)
? customValidateResults ? customValidateResults
: Promise.resolve(customValidateResults) : Promise.resolve(customValidateResults)
return resultPromise.then(function (customValidationPathErrors) { return resultPromise.then(customValidationPathErrors => {
if (Array.isArray(customValidationPathErrors)) { if (Array.isArray(customValidationPathErrors)) {
return customValidationPathErrors return customValidationPathErrors
.filter(function (error) { .filter(error => {
var valid = util.isValidValidationError(error) const valid = util.isValidValidationError(error)
if (!valid) { if (!valid) {
console.warn('Ignoring a custom validation error with invalid structure. ' + console.warn('Ignoring a custom validation error with invalid structure. ' +
@ -639,8 +628,8 @@ treemode._validateCustom = function (json) {
return valid return valid
}) })
.map(function (error) { .map(error => {
var node let node
try { try {
node = (error && error.path) ? root.findNodeByPath(error.path) : null node = (error && error.path) ? root.findNodeByPath(error.path) : null
} catch (err) { } catch (err) {
@ -655,9 +644,7 @@ treemode._validateCustom = function (json) {
error: error error: error
} }
}) })
.filter(function (entry) { .filter(entry => entry && entry.node && entry.error && entry.error.message)
return entry && entry.node && entry.error && entry.error.message
})
} else { } else {
return null return null
} }
@ -685,13 +672,13 @@ treemode.refresh = function () {
* @param {Number} mouseY Absolute mouse position in pixels * @param {Number} mouseY Absolute mouse position in pixels
*/ */
treemode.startAutoScroll = function (mouseY) { treemode.startAutoScroll = function (mouseY) {
var me = this const me = this
var content = this.scrollableContent const content = this.scrollableContent
var top = util.getAbsoluteTop(content) const top = util.getAbsoluteTop(content)
var height = content.clientHeight const height = content.clientHeight
var bottom = top + height const bottom = top + height
var margin = 24 const margin = 24
var interval = 50 // ms const interval = 50 // ms
if ((mouseY < top + margin) && content.scrollTop > 0) { if ((mouseY < top + margin) && content.scrollTop > 0) {
this.autoScrollStep = ((top + margin) - mouseY) / 3 this.autoScrollStep = ((top + margin) - mouseY) / 3
@ -704,7 +691,7 @@ treemode.startAutoScroll = function (mouseY) {
if (this.autoScrollStep) { if (this.autoScrollStep) {
if (!this.autoScrollTimer) { if (!this.autoScrollTimer) {
this.autoScrollTimer = setInterval(function () { this.autoScrollTimer = setInterval(() => {
if (me.autoScrollStep) { if (me.autoScrollStep) {
content.scrollTop -= me.autoScrollStep content.scrollTop -= me.autoScrollStep
} else { } else {
@ -751,22 +738,20 @@ treemode.setDomSelection = function (selection) {
} }
if (selection.paths) { if (selection.paths) {
// multi-select // multi-select
var me = this const me = this
var nodes = selection.paths.map(function (path) { const nodes = selection.paths.map(path => me.node.findNodeByInternalPath(path))
return me.node.findNodeByInternalPath(path)
})
this.select(nodes) this.select(nodes)
} else { } else {
// find the actual DOM element where to apply the focus // find the actual DOM element where to apply the focus
var node = selection.path const node = selection.path
? this.node.findNodeByInternalPath(selection.path) ? this.node.findNodeByInternalPath(selection.path)
: null : null
var container = (node && selection.domName) const container = (node && selection.domName)
? node.dom[selection.domName] ? node.dom[selection.domName]
: null : null
if (selection.range && container) { if (selection.range && container) {
var range = Object.assign({}, selection.range, { container: container }) const range = Object.assign({}, selection.range, { container: container })
util.setSelectionOffset(range) util.setSelectionOffset(range)
} else if (node) { // just a fallback } else if (node) { // just a fallback
node.focus() node.focus()
@ -787,15 +772,13 @@ treemode.getDomSelection = function () {
// find the node and field name of the current target, // find the node and field name of the current target,
// so we can store the current selection in a serializable // so we can store the current selection in a serializable
// way (internal node path and domName) // way (internal node path and domName)
var node = Node.getNodeFromTarget(this.focusTarget) const node = Node.getNodeFromTarget(this.focusTarget)
var focusTarget = this.focusTarget const focusTarget = this.focusTarget
var domName = node const domName = node
? Object.keys(node.dom).find(function (domName) { ? Object.keys(node.dom).find(domName => node.dom[domName] === focusTarget)
return node.dom[domName] === focusTarget
})
: null : null
var range = util.getSelectionOffset() let range = util.getSelectionOffset()
if (range && range.container.nodeName !== 'DIV') { // filter on (editable) divs) if (range && range.container.nodeName !== 'DIV') { // filter on (editable) divs)
range = null range = null
} }
@ -814,9 +797,7 @@ treemode.getDomSelection = function () {
domName: domName, domName: domName,
range: range, range: range,
paths: this.multiselection.length > 0 paths: this.multiselection.length > 0
? this.multiselection.nodes.map(function (node) { ? this.multiselection.nodes.map(node => node.getInternalPath())
return node.getInternalPath()
})
: null, : null,
scrollTop: this.scrollableContent ? this.scrollableContent.scrollTop : 0 scrollTop: this.scrollableContent ? this.scrollableContent.scrollTop : 0
} }
@ -832,9 +813,9 @@ treemode.getDomSelection = function () {
* when not. * when not.
*/ */
treemode.scrollTo = function (top, animateCallback) { treemode.scrollTo = function (top, animateCallback) {
var content = this.scrollableContent const content = this.scrollableContent
if (content) { if (content) {
var editor = this const editor = this
// cancel any running animation // cancel any running animation
if (editor.animateTimeout) { if (editor.animateTimeout) {
clearTimeout(editor.animateTimeout) clearTimeout(editor.animateTimeout)
@ -846,14 +827,14 @@ treemode.scrollTo = function (top, animateCallback) {
} }
// calculate final scroll position // calculate final scroll position
var height = content.clientHeight const height = content.clientHeight
var bottom = content.scrollHeight - height const bottom = content.scrollHeight - height
var finalScrollTop = Math.min(Math.max(top - height / 4, 0), bottom) const finalScrollTop = Math.min(Math.max(top - height / 4, 0), bottom)
// animate towards the new scroll position // animate towards the new scroll position
var animate = function () { const animate = () => {
var scrollTop = content.scrollTop const scrollTop = content.scrollTop
var diff = (finalScrollTop - scrollTop) const diff = (finalScrollTop - scrollTop)
if (Math.abs(diff) > 3) { if (Math.abs(diff) > 3) {
content.scrollTop += diff / 3 content.scrollTop += diff / 3
editor.animateCallback = animateCallback editor.animateCallback = animateCallback
@ -890,7 +871,7 @@ treemode._createFrame = function () {
this.contentOuter.className = 'jsoneditor-outer' this.contentOuter.className = 'jsoneditor-outer'
// create one global event listener to handle all events from all nodes // create one global event listener to handle all events from all nodes
var editor = this const editor = this
function onEvent (event) { function onEvent (event) {
// when switching to mode "code" or "text" via the menu, some events // when switching to mode "code" or "text" via the menu, some events
// are still fired whilst the _onEvent methods is already removed. // are still fired whilst the _onEvent methods is already removed.
@ -898,8 +879,8 @@ treemode._createFrame = function () {
editor._onEvent(event) editor._onEvent(event)
} }
} }
this.frame.onclick = function (event) { this.frame.onclick = event => {
var target = event.target// || event.srcElement; const target = event.target// || event.srcElement;
onEvent(event) onEvent(event)
@ -936,32 +917,32 @@ treemode._createFrame = function () {
this.frame.appendChild(this.menu) this.frame.appendChild(this.menu)
// create expand all button // create expand all button
var expandAll = document.createElement('button') const expandAll = document.createElement('button')
expandAll.type = 'button' expandAll.type = 'button'
expandAll.className = 'jsoneditor-expand-all' expandAll.className = 'jsoneditor-expand-all'
expandAll.title = translate('expandAll') expandAll.title = translate('expandAll')
expandAll.onclick = function () { expandAll.onclick = () => {
editor.expandAll() editor.expandAll()
} }
this.menu.appendChild(expandAll) this.menu.appendChild(expandAll)
// create collapse all button // create collapse all button
var collapseAll = document.createElement('button') const collapseAll = document.createElement('button')
collapseAll.type = 'button' collapseAll.type = 'button'
collapseAll.title = translate('collapseAll') collapseAll.title = translate('collapseAll')
collapseAll.className = 'jsoneditor-collapse-all' collapseAll.className = 'jsoneditor-collapse-all'
collapseAll.onclick = function () { collapseAll.onclick = () => {
editor.collapseAll() editor.collapseAll()
} }
this.menu.appendChild(collapseAll) this.menu.appendChild(collapseAll)
// create sort button // create sort button
if (this.options.enableSort) { if (this.options.enableSort) {
var sort = document.createElement('button') const sort = document.createElement('button')
sort.type = 'button' sort.type = 'button'
sort.className = 'jsoneditor-sort' sort.className = 'jsoneditor-sort'
sort.title = translate('sortTitleShort') sort.title = translate('sortTitleShort')
sort.onclick = function () { sort.onclick = () => {
editor.node.showSortModal() editor.node.showSortModal()
} }
this.menu.appendChild(sort) this.menu.appendChild(sort)
@ -969,11 +950,11 @@ treemode._createFrame = function () {
// create transform button // create transform button
if (this.options.enableTransform) { if (this.options.enableTransform) {
var transform = document.createElement('button') const transform = document.createElement('button')
transform.type = 'button' transform.type = 'button'
transform.title = translate('transformTitleShort') transform.title = translate('transformTitleShort')
transform.className = 'jsoneditor-transform' transform.className = 'jsoneditor-transform'
transform.onclick = function () { transform.onclick = () => {
editor.node.showTransformModal() editor.node.showTransformModal()
} }
this.menu.appendChild(transform) this.menu.appendChild(transform)
@ -982,29 +963,29 @@ treemode._createFrame = function () {
// create undo/redo buttons // create undo/redo buttons
if (this.history) { if (this.history) {
// create undo button // create undo button
var undo = document.createElement('button') const undo = document.createElement('button')
undo.type = 'button' undo.type = 'button'
undo.className = 'jsoneditor-undo jsoneditor-separator' undo.className = 'jsoneditor-undo jsoneditor-separator'
undo.title = translate('undo') undo.title = translate('undo')
undo.onclick = function () { undo.onclick = () => {
editor._onUndo() editor._onUndo()
} }
this.menu.appendChild(undo) this.menu.appendChild(undo)
this.dom.undo = undo this.dom.undo = undo
// create redo button // create redo button
var redo = document.createElement('button') const redo = document.createElement('button')
redo.type = 'button' redo.type = 'button'
redo.className = 'jsoneditor-redo' redo.className = 'jsoneditor-redo'
redo.title = translate('redo') redo.title = translate('redo')
redo.onclick = function () { redo.onclick = () => {
editor._onRedo() editor._onRedo()
} }
this.menu.appendChild(redo) this.menu.appendChild(redo)
this.dom.redo = redo this.dom.redo = redo
// register handler for onchange of history // register handler for onchange of history
this.history.onChange = function () { this.history.onChange = () => {
undo.disabled = !editor.history.canUndo() undo.disabled = !editor.history.canUndo()
redo.disabled = !editor.history.canRedo() redo.disabled = !editor.history.canRedo()
} }
@ -1013,7 +994,7 @@ treemode._createFrame = function () {
// create mode box // create mode box
if (this.options && this.options.modes && this.options.modes.length) { if (this.options && this.options.modes && this.options.modes.length) {
var me = this const me = this
this.modeSwitcher = new ModeSwitcher(this.menu, this.options.modes, this.options.mode, function onSwitch (mode) { this.modeSwitcher = new ModeSwitcher(this.menu, this.options.modes, this.options.mode, function onSwitch (mode) {
// switch mode and restore focus // switch mode and restore focus
me.setMode(mode) me.setMode(mode)
@ -1078,7 +1059,7 @@ treemode._onEvent = function (event) {
return return
} }
var node = Node.getNodeFromTarget(event.target) const node = Node.getNodeFromTarget(event.target)
if (event.type === 'keydown') { if (event.type === 'keydown') {
this._onKeyDown(event) this._onKeyDown(event)
@ -1100,8 +1081,8 @@ treemode._onEvent = function (event) {
if (node && this.options && this.options.navigationBar && node && (event.type === 'keydown' || event.type === 'mousedown')) { if (node && this.options && this.options.navigationBar && node && (event.type === 'keydown' || event.type === 'mousedown')) {
// apply on next tick, right after the new key press is applied // apply on next tick, right after the new key press is applied
var me = this const me = this
setTimeout(function () { setTimeout(() => {
me._updateTreePath(node.getNodePath()) me._updateTreePath(node.getNodePath())
}) })
} }
@ -1154,15 +1135,15 @@ treemode._updateTreePath = function (pathNodes) {
if (pathNodes && pathNodes.length) { if (pathNodes && pathNodes.length) {
util.removeClassName(this.navBar, 'nav-bar-empty') util.removeClassName(this.navBar, 'nav-bar-empty')
var pathObjs = [] const pathObjs = []
pathNodes.forEach(function (node) { pathNodes.forEach(node => {
var pathObj = { const pathObj = {
name: getName(node), name: getName(node),
node: node, node: node,
children: [] children: []
} }
if (node.childs && node.childs.length) { if (node.childs && node.childs.length) {
node.childs.forEach(function (childNode) { node.childs.forEach(childNode => {
pathObj.children.push({ pathObj.children.push({
name: getName(childNode), name: getName(childNode),
node: childNode node: childNode
@ -1188,7 +1169,7 @@ treemode._updateTreePath = function (pathNodes) {
* @param {Object} pathObj path object that was represents the selected section node * @param {Object} pathObj path object that was represents the selected section node
* @private * @private
*/ */
treemode._onTreePathSectionSelected = function (pathObj) { treemode._onTreePathSectionSelected = pathObj => {
if (pathObj && pathObj.node) { if (pathObj && pathObj.node) {
pathObj.node.expandTo() pathObj.node.expandTo()
pathObj.node.focus() pathObj.node.focus()
@ -1203,9 +1184,7 @@ treemode._onTreePathSectionSelected = function (pathObj) {
*/ */
treemode._onTreePathMenuItemSelected = function (pathObj, selection) { treemode._onTreePathMenuItemSelected = function (pathObj, selection) {
if (pathObj && pathObj.children.length) { if (pathObj && pathObj.children.length) {
var selectionObj = pathObj.children.find(function (obj) { const selectionObj = pathObj.children.find(obj => obj.name === selection)
return obj.name === selection
})
if (selectionObj && selectionObj.node) { if (selectionObj && selectionObj.node) {
this._updateTreePath(selectionObj.node.getNodePath()) this._updateTreePath(selectionObj.node.getNodePath())
selectionObj.node.expandTo() selectionObj.node.expandTo()
@ -1229,8 +1208,8 @@ treemode._updateDragDistance = function (event) {
this._startDragDistance(event) this._startDragDistance(event)
} }
var diffX = event.pageX - this.dragDistanceEvent.initialPageX const diffX = event.pageX - this.dragDistanceEvent.initialPageX
var diffY = event.pageY - this.dragDistanceEvent.initialPageY const diffY = event.pageY - this.dragDistanceEvent.initialPageY
this.dragDistanceEvent.dragDistance = Math.sqrt(diffX * diffX + diffY * diffY) this.dragDistanceEvent.dragDistance = Math.sqrt(diffX * diffX + diffY * diffY)
this.dragDistanceEvent.hasMoved = this.dragDistanceEvent.hasMoved =
@ -1248,7 +1227,7 @@ treemode._updateDragDistance = function (event) {
* @private * @private
*/ */
treemode._onMultiSelectStart = function (event) { treemode._onMultiSelectStart = function (event) {
var node = Node.getNodeFromTarget(event.target) const node = Node.getNodeFromTarget(event.target)
if (this.options.mode !== 'tree' || this.options.onEditable !== undefined) { if (this.options.mode !== 'tree' || this.options.onEditable !== undefined) {
// dragging not allowed in modes 'view' and 'form' // dragging not allowed in modes 'view' and 'form'
@ -1264,14 +1243,14 @@ treemode._onMultiSelectStart = function (event) {
this._startDragDistance(event) this._startDragDistance(event)
var editor = this const editor = this
if (!this.mousemove) { if (!this.mousemove) {
this.mousemove = util.addEventListener(window, 'mousemove', function (event) { this.mousemove = util.addEventListener(window, 'mousemove', event => {
editor._onMultiSelect(event) editor._onMultiSelect(event)
}) })
} }
if (!this.mouseup) { if (!this.mouseup) {
this.mouseup = util.addEventListener(window, 'mouseup', function (event) { this.mouseup = util.addEventListener(window, 'mouseup', event => {
editor._onMultiSelectEnd(event) editor._onMultiSelectEnd(event)
}) })
} }
@ -1292,7 +1271,7 @@ treemode._onMultiSelect = function (event) {
return return
} }
var node = Node.getNodeFromTarget(event.target) const node = Node.getNodeFromTarget(event.target)
if (node) { if (node) {
if (this.multiselection.start == null) { if (this.multiselection.start == null) {
@ -1305,13 +1284,13 @@ treemode._onMultiSelect = function (event) {
this.deselect() this.deselect()
// find the selected nodes in the range from first to last // find the selected nodes in the range from first to last
var start = this.multiselection.start const start = this.multiselection.start
var end = this.multiselection.end || this.multiselection.start const end = this.multiselection.end || this.multiselection.start
if (start && end) { if (start && end) {
// find the top level childs, all having the same parent // find the top level childs, all having the same parent
this.multiselection.nodes = this._findTopLevelNodes(start, end) this.multiselection.nodes = this._findTopLevelNodes(start, end)
if (this.multiselection.nodes && this.multiselection.nodes.length) { if (this.multiselection.nodes && this.multiselection.nodes.length) {
var firstNode = this.multiselection.nodes[0] const firstNode = this.multiselection.nodes[0]
if (this.multiselection.start === firstNode || this.multiselection.start.isDescendantOf(firstNode)) { if (this.multiselection.start === firstNode || this.multiselection.start.isDescendantOf(firstNode)) {
this.multiselection.direction = 'down' this.multiselection.direction = 'down'
} else { } else {
@ -1352,8 +1331,8 @@ treemode._onMultiSelectEnd = function () {
* state is cleared too. * state is cleared too.
*/ */
treemode.deselect = function (clearStartAndEnd) { treemode.deselect = function (clearStartAndEnd) {
var selectionChanged = !!this.multiselection.nodes.length const selectionChanged = !!this.multiselection.nodes.length
this.multiselection.nodes.forEach(function (node) { this.multiselection.nodes.forEach(node => {
node.setSelected(false) node.setSelected(false)
}) })
this.multiselection.nodes = [] this.multiselection.nodes = []
@ -1384,14 +1363,14 @@ treemode.select = function (nodes) {
this.multiselection.nodes = nodes.slice(0) this.multiselection.nodes = nodes.slice(0)
var first = nodes[0] const first = nodes[0]
nodes.forEach(function (node) { nodes.forEach(node => {
node.expandPathToNode() node.expandPathToNode()
node.setSelected(true, node === first) node.setSelected(true, node === first)
}) })
if (this._selectionChangedHandler) { if (this._selectionChangedHandler) {
var selection = this.getSelection() const selection = this.getSelection()
this._selectionChangedHandler(selection.start, selection.end) this._selectionChangedHandler(selection.start, selection.end)
} }
} }
@ -1406,16 +1385,16 @@ treemode.select = function (nodes) {
* @return {Array.<Node>} Returns an ordered list with child nodes * @return {Array.<Node>} Returns an ordered list with child nodes
* @private * @private
*/ */
treemode._findTopLevelNodes = function (start, end) { treemode._findTopLevelNodes = (start, end) => {
var startPath = start.getNodePath() const startPath = start.getNodePath()
var endPath = end.getNodePath() const endPath = end.getNodePath()
var i = 0 let i = 0
while (i < startPath.length && startPath[i] === endPath[i]) { while (i < startPath.length && startPath[i] === endPath[i]) {
i++ i++
} }
var root = startPath[i - 1] let root = startPath[i - 1]
var startChild = startPath[i] let startChild = startPath[i]
var endChild = endPath[i] let endChild = endPath[i]
if (!startChild || !endChild) { if (!startChild || !endChild) {
if (root.parent) { if (root.parent) {
@ -1431,10 +1410,10 @@ treemode._findTopLevelNodes = function (start, end) {
} }
if (root && startChild && endChild) { if (root && startChild && endChild) {
var startIndex = root.childs.indexOf(startChild) const startIndex = root.childs.indexOf(startChild)
var endIndex = root.childs.indexOf(endChild) const endIndex = root.childs.indexOf(endChild)
var firstIndex = Math.min(startIndex, endIndex) const firstIndex = Math.min(startIndex, endIndex)
var lastIndex = Math.max(startIndex, endIndex) const lastIndex = Math.max(startIndex, endIndex)
return root.childs.slice(firstIndex, lastIndex + 1) return root.childs.slice(firstIndex, lastIndex + 1)
} else { } else {
@ -1448,23 +1427,23 @@ treemode._findTopLevelNodes = function (start, end) {
* @private * @private
*/ */
treemode._showAutoComplete = function (element) { treemode._showAutoComplete = function (element) {
var node = Node.getNodeFromTarget(element) const node = Node.getNodeFromTarget(element)
var jsonElementType = '' let jsonElementType = ''
if (element.className.indexOf('jsoneditor-value') >= 0) jsonElementType = 'value' if (element.className.indexOf('jsoneditor-value') >= 0) jsonElementType = 'value'
if (element.className.indexOf('jsoneditor-field') >= 0) jsonElementType = 'field' if (element.className.indexOf('jsoneditor-field') >= 0) jsonElementType = 'field'
var self = this const self = this
setTimeout(function () { setTimeout(() => {
if (node && (self.options.autocomplete.trigger === 'focus' || element.innerText.length > 0)) { if (node && (self.options.autocomplete.trigger === 'focus' || element.innerText.length > 0)) {
var result = self.options.autocomplete.getOptions(element.innerText, node.getPath(), jsonElementType, node.editor) const result = self.options.autocomplete.getOptions(element.innerText, node.getPath(), jsonElementType, node.editor)
if (result === null) { if (result === null) {
self.autocomplete.hideDropDown() self.autocomplete.hideDropDown()
} else if (typeof result.then === 'function') { } else if (typeof result.then === 'function') {
// probably a promise // probably a promise
result result
.then(function (obj) { .then(obj => {
if (obj === null) { if (obj === null) {
self.autocomplete.hideDropDown() self.autocomplete.hideDropDown()
} else if (obj.options) { } else if (obj.options) {
@ -1473,7 +1452,7 @@ treemode._showAutoComplete = function (element) {
self.autocomplete.show(element, 0, obj) self.autocomplete.show(element, 0, obj)
} }
}) })
.catch(function (err) { .catch(err => {
console.error(err) console.error(err)
}) })
} else { } else {
@ -1490,16 +1469,16 @@ treemode._showAutoComplete = function (element) {
* @private * @private
*/ */
treemode._onKeyDown = function (event) { treemode._onKeyDown = function (event) {
var keynum = event.which || event.keyCode const keynum = event.which || event.keyCode
var altKey = event.altKey const altKey = event.altKey
var ctrlKey = event.ctrlKey const ctrlKey = event.ctrlKey
var metaKey = event.metaKey const metaKey = event.metaKey
var shiftKey = event.shiftKey const shiftKey = event.shiftKey
var handled = false let handled = false
if (keynum === 9) { // Tab or Shift+Tab if (keynum === 9) { // Tab or Shift+Tab
var me = this const me = this
setTimeout(function () { setTimeout(() => {
// select all text when moving focus to an editable div // select all text when moving focus to an editable div
util.selectContentEditable(me.focusTarget) util.selectContentEditable(me.focusTarget)
}, 0) }, 0)
@ -1511,7 +1490,7 @@ treemode._onKeyDown = function (event) {
this.searchBox.dom.search.select() this.searchBox.dom.search.select()
handled = true handled = true
} else if (keynum === 114 || (ctrlKey && keynum === 71)) { // F3 or Ctrl+G } else if (keynum === 114 || (ctrlKey && keynum === 71)) { // F3 or Ctrl+G
var focus = true const focus = true
if (!shiftKey) { if (!shiftKey) {
// select next search result (F3 or Ctrl+G) // select next search result (F3 or Ctrl+G)
this.searchBox.next(focus) this.searchBox.next(focus)
@ -1578,7 +1557,7 @@ treemode._createTable = function () {
// create colgroup where the first two columns don't have a fixed // create colgroup where the first two columns don't have a fixed
// width, and the edit columns do have a fixed width // width, and the edit columns do have a fixed width
var col let col
this.colgroupContent = document.createElement('colgroup') this.colgroupContent = document.createElement('colgroup')
if (this.options.mode === 'tree') { if (this.options.mode === 'tree') {
col = document.createElement('col') col = document.createElement('col')
@ -1606,8 +1585,8 @@ treemode._createTable = function () {
* is being closed. * is being closed.
*/ */
treemode.showContextMenu = function (anchor, onClose) { treemode.showContextMenu = function (anchor, onClose) {
var items = [] let items = []
var selectedNodes = this.multiselection.nodes.slice() const selectedNodes = this.multiselection.nodes.slice()
// create duplicate button // create duplicate button
items.push({ items.push({
@ -1630,9 +1609,7 @@ treemode.showContextMenu = function (anchor, onClose) {
}) })
if (this.options.onCreateMenu) { if (this.options.onCreateMenu) {
var paths = selectedNodes.map(function (node) { const paths = selectedNodes.map(node => node.getPath())
return node.getPath()
})
items = this.options.onCreateMenu(items, { items = this.options.onCreateMenu(items, {
type: 'multiple', type: 'multiple',
@ -1641,7 +1618,7 @@ treemode.showContextMenu = function (anchor, onClose) {
}) })
} }
var menu = new ContextMenu(items, { close: onClose }) const menu = new ContextMenu(items, { close: onClose })
menu.show(anchor, this.frame) menu.show(anchor, this.frame)
} }
@ -1650,14 +1627,14 @@ treemode.showContextMenu = function (anchor, onClose) {
* @return {{start:SerializableNode, end: SerializableNode}} * @return {{start:SerializableNode, end: SerializableNode}}
*/ */
treemode.getSelection = function () { treemode.getSelection = function () {
var selection = { const selection = {
start: null, start: null,
end: null end: null
} }
if (this.multiselection.nodes && this.multiselection.nodes.length) { if (this.multiselection.nodes && this.multiselection.nodes.length) {
if (this.multiselection.nodes.length) { if (this.multiselection.nodes.length) {
var selection1 = this.multiselection.nodes[0] const selection1 = this.multiselection.nodes[0]
var selection2 = this.multiselection.nodes[this.multiselection.nodes.length - 1] const selection2 = this.multiselection.nodes[this.multiselection.nodes.length - 1]
if (this.multiselection.direction === 'down') { if (this.multiselection.direction === 'down') {
selection.start = selection1.serialize() selection.start = selection1.serialize()
selection.end = selection2.serialize() selection.end = selection2.serialize()
@ -1697,9 +1674,9 @@ treemode.setSelection = function (start, end) {
this.setDomSelection(start) this.setDomSelection(start)
} }
var nodes = this._getNodeInstancesByRange(start, end) const nodes = this._getNodeInstancesByRange(start, end)
nodes.forEach(function (node) { nodes.forEach(node => {
node.expandTo() node.expandTo()
}) })
this.select(nodes) this.select(nodes)
@ -1713,7 +1690,7 @@ treemode.setSelection = function (start, end) {
* @private * @private
*/ */
treemode._getNodeInstancesByRange = function (start, end) { treemode._getNodeInstancesByRange = function (start, end) {
var startNode, endNode let startNode, endNode
if (start && start.path) { if (start && start.path) {
startNode = this.node.findNodeByPath(start.path) startNode = this.node.findNodeByPath(start.path)
@ -1722,7 +1699,7 @@ treemode._getNodeInstancesByRange = function (start, end) {
} }
} }
var nodes = [] let nodes = []
if (startNode instanceof Node) { if (startNode instanceof Node) {
if (endNode instanceof Node && endNode !== startNode) { if (endNode instanceof Node && endNode !== startNode) {
if (startNode.parent === endNode.parent) { if (startNode.parent === endNode.parent) {
@ -1733,7 +1710,7 @@ treemode._getNodeInstancesByRange = function (start, end) {
start = endNode start = endNode
end = startNode end = startNode
} }
var current = start let current = start
nodes.push(current) nodes.push(current)
do { do {
current = current.nextSibling() current = current.nextSibling()
@ -1751,10 +1728,10 @@ treemode._getNodeInstancesByRange = function (start, end) {
} }
treemode.getNodesByRange = function (start, end) { treemode.getNodesByRange = function (start, end) {
var nodes = this._getNodeInstancesByRange(start, end) const nodes = this._getNodeInstancesByRange(start, end)
var serializableNodes = [] const serializableNodes = []
nodes.forEach(function (node) { nodes.forEach(node => {
serializableNodes.push(node.serialize()) serializableNodes.push(node.serialize())
}) })

View File

@ -1,12 +1,12 @@
'use strict' 'use strict'
require('./polyfills') require('./polyfills')
var naturalSort = require('javascript-natural-sort') const naturalSort = require('javascript-natural-sort')
var jsonlint = require('./assets/jsonlint/jsonlint') const jsonlint = require('./assets/jsonlint/jsonlint')
var jsonMap = require('json-source-map') const jsonMap = require('json-source-map')
var translate = require('./i18n').translate const translate = require('./i18n').translate
var MAX_ITEMS_FIELDS_COLLECTION = 10000 const MAX_ITEMS_FIELDS_COLLECTION = 10000
/** /**
* Parse JSON using the parser built-in in the browser. * Parse JSON using the parser built-in in the browser.
@ -34,22 +34,22 @@ exports.parse = function parse (jsonString) {
* @param {string} jsString * @param {string} jsString
* @returns {string} json * @returns {string} json
*/ */
exports.repair = function (jsString) { exports.repair = jsString => {
// TODO: refactor this function, it's too large and complicated now // TODO: refactor this function, it's too large and complicated now
// escape all single and double quotes inside strings // escape all single and double quotes inside strings
var chars = [] const chars = []
var i = 0 let i = 0
// If JSON starts with a function (characters/digits/"_-"), remove this function. // If JSON starts with a function (characters/digits/"_-"), remove this function.
// This is useful for "stripping" JSONP objects to become JSON // This is useful for "stripping" JSONP objects to become JSON
// For example: /* some comment */ function_12321321 ( [{"a":"b"}] ); => [{"a":"b"}] // For example: /* some comment */ function_12321321 ( [{"a":"b"}] ); => [{"a":"b"}]
var match = jsString.match(/^\s*(\/\*(.|[\r\n])*?\*\/)?\s*[\da-zA-Z_$]+\s*\(([\s\S]*)\)\s*;?\s*$/) const match = jsString.match(/^\s*(\/\*(.|[\r\n])*?\*\/)?\s*[\da-zA-Z_$]+\s*\(([\s\S]*)\)\s*;?\s*$/)
if (match) { if (match) {
jsString = match[3] jsString = match[3]
} }
var controlChars = { const controlChars = {
'\b': '\\b', '\b': '\\b',
'\f': '\\f', '\f': '\\f',
'\n': '\\n', '\n': '\\n',
@ -57,14 +57,14 @@ exports.repair = function (jsString) {
'\t': '\\t' '\t': '\\t'
} }
var quote = '\'' const quote = '\''
var quoteDbl = '"' const quoteDbl = '"'
var quoteLeft = '\u2018' const quoteLeft = '\u2018'
var quoteRight = '\u2019' const quoteRight = '\u2019'
var quoteDblLeft = '\u201C' const quoteDblLeft = '\u201C'
var quoteDblRight = '\u201D' const quoteDblRight = '\u201D'
var graveAccent = '\u0060' const graveAccent = '\u0060'
var acuteAccent = '\u00B4' const acuteAccent = '\u00B4'
// helper functions to get the current/prev/next character // helper functions to get the current/prev/next character
function curr () { return jsString.charAt(i) } function curr () { return jsString.charAt(i) }
@ -77,10 +77,10 @@ exports.repair = function (jsString) {
// get the last parsed non-whitespace character // get the last parsed non-whitespace character
function lastNonWhitespace () { function lastNonWhitespace () {
var p = chars.length - 1 let p = chars.length - 1
while (p >= 0) { while (p >= 0) {
var pp = chars[p] const pp = chars[p]
if (!isWhiteSpace(pp)) { if (!isWhiteSpace(pp)) {
return pp return pp
} }
@ -92,7 +92,7 @@ exports.repair = function (jsString) {
// get at the first next non-white space character // get at the first next non-white space character
function nextNonWhiteSpace () { function nextNonWhiteSpace () {
var iNext = i + 1 let iNext = i + 1
while (iNext < jsString.length && isWhiteSpace(jsString[iNext])) { while (iNext < jsString.length && isWhiteSpace(jsString[iNext])) {
iNext++ iNext++
} }
@ -123,11 +123,11 @@ exports.repair = function (jsString) {
* @return {string} * @return {string}
*/ */
function parseString (endQuote) { function parseString (endQuote) {
var string = '' let string = ''
string += '"' string += '"'
i++ i++
var c = curr() let c = curr()
while (i < jsString.length && c !== endQuote) { while (i < jsString.length && c !== endQuote) {
if (c === '"' && prev() !== '\\') { if (c === '"' && prev() !== '\\') {
// unescaped double quote, escape it // unescaped double quote, escape it
@ -161,11 +161,11 @@ exports.repair = function (jsString) {
// parse an unquoted key // parse an unquoted key
function parseKey () { function parseKey () {
var specialValues = ['null', 'true', 'false'] const specialValues = ['null', 'true', 'false']
var key = '' let key = ''
var c = curr() let c = curr()
var regexp = /[a-zA-Z_$\d]/ // letter, number, underscore, dollar character const regexp = /[a-zA-Z_$\d]/ // letter, number, underscore, dollar character
while (regexp.test(c)) { while (regexp.test(c)) {
key += c key += c
i++ i++
@ -180,9 +180,9 @@ exports.repair = function (jsString) {
} }
function parseMongoDataType () { function parseMongoDataType () {
var c = curr() let c = curr()
var value let value
var dataType = '' let dataType = ''
while (/[a-zA-Z_$]/.test(c)) { while (/[a-zA-Z_$]/.test(c)) {
dataType += c dataType += c
i++ i++
@ -233,7 +233,7 @@ exports.repair = function (jsString) {
} }
while (i < jsString.length) { while (i < jsString.length) {
var c = curr() const c = curr()
if (c === '/' && next() === '*') { if (c === '/' && next() === '*') {
skipBlockComment() skipBlockComment()
@ -278,14 +278,13 @@ exports.repair = function (jsString) {
* @param {string} text * @param {string} text
* @return {string} * @return {string}
*/ */
exports.escapeUnicodeChars = function (text) { exports.escapeUnicodeChars = text => // see https://www.wikiwand.com/en/UTF-16
// see https://www.wikiwand.com/en/UTF-16 // note: we leave surrogate pairs as two individual chars,
// note: we leave surrogate pairs as two individual chars, // as JSON doesn't interpret them as a single unicode char.
// as JSON doesn't interpret them as a single unicode char. text.replace(
return text.replace(/[\u007F-\uFFFF]/g, function (c) { /[\u007F-\uFFFF]/g,
return '\\u' + ('0000' + c.charCodeAt(0).toString(16)).slice(-4) c => '\\u' + ('0000' + c.charCodeAt(0).toString(16)).slice(-4)
}) )
}
/** /**
* Validate a string containing a JSON object * Validate a string containing a JSON object
@ -309,7 +308,7 @@ exports.validate = function validate (jsonString) {
* @return {Object} a * @return {Object} a
*/ */
exports.extend = function extend (a, b) { exports.extend = function extend (a, b) {
for (var prop in b) { for (const prop in b) {
if (hasOwnProperty(b, prop)) { if (hasOwnProperty(b, prop)) {
a[prop] = b[prop] a[prop] = b[prop]
} }
@ -323,7 +322,7 @@ exports.extend = function extend (a, b) {
* @return {Object} a * @return {Object} a
*/ */
exports.clear = function clear (a) { exports.clear = function clear (a) {
for (var prop in a) { for (const prop in a) {
if (hasOwnProperty(a, prop)) { if (hasOwnProperty(a, prop)) {
delete a[prop] delete a[prop]
} }
@ -367,7 +366,7 @@ exports.type = function type (object) {
* with 'http://*' or 'https://*' and has no whitespace characters) * with 'http://*' or 'https://*' and has no whitespace characters)
* @param {String} text * @param {String} text
*/ */
var isUrlRegex = /^https?:\/\/\S+$/ const isUrlRegex = /^https?:\/\/\S+$/
exports.isUrl = function isUrl (text) { exports.isUrl = function isUrl (text) {
return (typeof text === 'string' || text instanceof String) && return (typeof text === 'string' || text instanceof String) &&
isUrlRegex.test(text) isUrlRegex.test(text)
@ -378,9 +377,7 @@ exports.isUrl = function isUrl (text) {
* @param {*} obj * @param {*} obj
* @returns {boolean} returns true when obj is an array * @returns {boolean} returns true when obj is an array
*/ */
exports.isArray = function (obj) { exports.isArray = obj => Object.prototype.toString.call(obj) === '[object Array]'
return Object.prototype.toString.call(obj) === '[object Array]'
}
/** /**
* Retrieve the absolute left value of a DOM element * Retrieve the absolute left value of a DOM element
@ -389,7 +386,7 @@ exports.isArray = function (obj) {
* in the browser page. * in the browser page.
*/ */
exports.getAbsoluteLeft = function getAbsoluteLeft (elem) { exports.getAbsoluteLeft = function getAbsoluteLeft (elem) {
var rect = elem.getBoundingClientRect() const rect = elem.getBoundingClientRect()
return rect.left + window.pageXOffset || document.scrollLeft || 0 return rect.left + window.pageXOffset || document.scrollLeft || 0
} }
@ -400,7 +397,7 @@ exports.getAbsoluteLeft = function getAbsoluteLeft (elem) {
* in the browser page. * in the browser page.
*/ */
exports.getAbsoluteTop = function getAbsoluteTop (elem) { exports.getAbsoluteTop = function getAbsoluteTop (elem) {
var rect = elem.getBoundingClientRect() const rect = elem.getBoundingClientRect()
return rect.top + window.pageYOffset || document.scrollTop || 0 return rect.top + window.pageYOffset || document.scrollTop || 0
} }
@ -410,7 +407,7 @@ exports.getAbsoluteTop = function getAbsoluteTop (elem) {
* @param {String} className * @param {String} className
*/ */
exports.addClassName = function addClassName (elem, className) { exports.addClassName = function addClassName (elem, className) {
var classes = elem.className.split(' ') const classes = elem.className.split(' ')
if (classes.indexOf(className) === -1) { if (classes.indexOf(className) === -1) {
classes.push(className) // add the class to the array classes.push(className) // add the class to the array
elem.className = classes.join(' ') elem.className = classes.join(' ')
@ -431,8 +428,8 @@ exports.removeAllClassNames = function removeAllClassNames (elem) {
* @param {String} className * @param {String} className
*/ */
exports.removeClassName = function removeClassName (elem, className) { exports.removeClassName = function removeClassName (elem, className) {
var classes = elem.className.split(' ') const classes = elem.className.split(' ')
var index = classes.indexOf(className) const index = classes.indexOf(className)
if (index !== -1) { if (index !== -1) {
classes.splice(index, 1) // remove the class from the array classes.splice(index, 1) // remove the class from the array
elem.className = classes.join(' ') elem.className = classes.join(' ')
@ -445,9 +442,9 @@ exports.removeClassName = function removeClassName (elem, className) {
* @param {Element} divElement * @param {Element} divElement
*/ */
exports.stripFormatting = function stripFormatting (divElement) { exports.stripFormatting = function stripFormatting (divElement) {
var childs = divElement.childNodes const childs = divElement.childNodes
for (var i = 0, iMax = childs.length; i < iMax; i++) { for (let i = 0, iMax = childs.length; i < iMax; i++) {
var child = childs[i] const child = childs[i]
// remove the style // remove the style
if (child.style) { if (child.style) {
@ -456,10 +453,10 @@ exports.stripFormatting = function stripFormatting (divElement) {
} }
// remove all attributes // remove all attributes
var attributes = child.attributes const attributes = child.attributes
if (attributes) { if (attributes) {
for (var j = attributes.length - 1; j >= 0; j--) { for (let j = attributes.length - 1; j >= 0; j--) {
var attribute = attributes[j] const attribute = attributes[j]
if (attribute.specified === true) { if (attribute.specified === true) {
child.removeAttribute(attribute.name) child.removeAttribute(attribute.name)
} }
@ -479,7 +476,7 @@ exports.stripFormatting = function stripFormatting (divElement) {
* @param {Element} contentEditableElement A content editable div * @param {Element} contentEditableElement A content editable div
*/ */
exports.setEndOfContentEditable = function setEndOfContentEditable (contentEditableElement) { exports.setEndOfContentEditable = function setEndOfContentEditable (contentEditableElement) {
var range, selection let range, selection
if (document.createRange) { if (document.createRange) {
range = document.createRange()// Create a range (a range is a like the selection but invisible) 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.selectNodeContents(contentEditableElement)// Select the entire contents of the element with the range
@ -500,7 +497,7 @@ exports.selectContentEditable = function selectContentEditable (contentEditableE
return return
} }
var sel, range let sel, range
if (window.getSelection && document.createRange) { if (window.getSelection && document.createRange) {
range = document.createRange() range = document.createRange()
range.selectNodeContents(contentEditableElement) range.selectNodeContents(contentEditableElement)
@ -517,7 +514,7 @@ exports.selectContentEditable = function selectContentEditable (contentEditableE
*/ */
exports.getSelection = function getSelection () { exports.getSelection = function getSelection () {
if (window.getSelection) { if (window.getSelection) {
var sel = window.getSelection() const sel = window.getSelection()
if (sel.getRangeAt && sel.rangeCount) { if (sel.getRangeAt && sel.rangeCount) {
return sel.getRangeAt(0) return sel.getRangeAt(0)
} }
@ -533,7 +530,7 @@ exports.getSelection = function getSelection () {
exports.setSelection = function setSelection (range) { exports.setSelection = function setSelection (range) {
if (range) { if (range) {
if (window.getSelection) { if (window.getSelection) {
var sel = window.getSelection() const sel = window.getSelection()
sel.removeAllRanges() sel.removeAllRanges()
sel.addRange(range) sel.addRange(range)
} }
@ -550,7 +547,7 @@ exports.setSelection = function setSelection (range) {
* Returns null if no text selection is found * Returns null if no text selection is found
*/ */
exports.getSelectionOffset = function getSelectionOffset () { exports.getSelectionOffset = function getSelectionOffset () {
var range = exports.getSelection() const range = exports.getSelection()
if (range && 'startOffset' in range && 'endOffset' in range && if (range && 'startOffset' in range && 'endOffset' in range &&
range.startContainer && (range.startContainer === range.endContainer)) { range.startContainer && (range.startContainer === range.endContainer)) {
@ -573,9 +570,9 @@ exports.getSelectionOffset = function getSelectionOffset () {
*/ */
exports.setSelectionOffset = function setSelectionOffset (params) { exports.setSelectionOffset = function setSelectionOffset (params) {
if (document.createRange && window.getSelection) { if (document.createRange && window.getSelection) {
var selection = window.getSelection() const selection = window.getSelection()
if (selection) { if (selection) {
var range = document.createRange() const range = document.createRange()
if (!params.container.firstChild) { if (!params.container.firstChild) {
params.container.appendChild(document.createTextNode('')) params.container.appendChild(document.createTextNode(''))
@ -598,12 +595,12 @@ exports.setSelectionOffset = function setSelectionOffset (params) {
* @return {String} innerText * @return {String} innerText
*/ */
exports.getInnerText = function getInnerText (element, buffer) { exports.getInnerText = function getInnerText (element, buffer) {
var first = (buffer === undefined) const first = (buffer === undefined)
if (first) { if (first) {
buffer = { buffer = {
text: '', text: '',
flush: function () { flush: function () {
var text = this.text const text = this.text
this.text = '' this.text = ''
return text return text
}, },
@ -620,15 +617,15 @@ exports.getInnerText = function getInnerText (element, buffer) {
// divs or other HTML elements // divs or other HTML elements
if (element.hasChildNodes()) { if (element.hasChildNodes()) {
var childNodes = element.childNodes const childNodes = element.childNodes
var innerText = '' let innerText = ''
for (var i = 0, iMax = childNodes.length; i < iMax; i++) { for (let i = 0, iMax = childNodes.length; i < iMax; i++) {
var child = childNodes[i] const child = childNodes[i]
if (child.nodeName === 'DIV' || child.nodeName === 'P') { if (child.nodeName === 'DIV' || child.nodeName === 'P') {
var prevChild = childNodes[i - 1] const prevChild = childNodes[i - 1]
var prevName = prevChild ? prevChild.nodeName : undefined const prevName = prevChild ? prevChild.nodeName : undefined
if (prevName && prevName !== 'DIV' && prevName !== 'P' && prevName !== 'BR') { if (prevName && prevName !== 'DIV' && prevName !== 'P' && prevName !== 'BR') {
innerText += '\n' innerText += '\n'
buffer.flush() buffer.flush()
@ -665,8 +662,8 @@ exports.getInnerText = function getInnerText (element, buffer) {
* @param {Element} parent * @param {Element} parent
* @return {boolean} * @return {boolean}
*/ */
exports.hasParentNode = function (elem, parent) { exports.hasParentNode = (elem, parent) => {
var e = elem ? elem.parentNode : undefined let e = elem ? elem.parentNode : undefined
while (e) { while (e) {
if (e === parent) { if (e === parent) {
@ -686,10 +683,10 @@ exports.hasParentNode = function (elem, parent) {
*/ */
exports.getInternetExplorerVersion = function getInternetExplorerVersion () { exports.getInternetExplorerVersion = function getInternetExplorerVersion () {
if (_ieVersion === -1) { if (_ieVersion === -1) {
var rv = -1 // Return value assumes failure. let rv = -1 // Return value assumes failure.
if (typeof navigator !== 'undefined' && navigator.appName === 'Microsoft Internet Explorer') { if (typeof navigator !== 'undefined' && navigator.appName === 'Microsoft Internet Explorer') {
var ua = navigator.userAgent const ua = navigator.userAgent
var re = new RegExp('MSIE ([0-9]+[.0-9]+)') const re = new RegExp('MSIE ([0-9]+[.0-9]+)')
if (re.exec(ua) != null) { if (re.exec(ua) != null) {
rv = parseFloat(RegExp.$1) rv = parseFloat(RegExp.$1)
} }
@ -737,9 +734,7 @@ exports.addEventListener = function addEventListener (element, action, listener,
return listener return listener
} else if (element.attachEvent) { } else if (element.attachEvent) {
// Old IE browsers // Old IE browsers
var f = function () { const f = () => listener.call(element, window.event)
return listener.call(element, window.event)
}
element.attachEvent('on' + action, f) element.attachEvent('on' + action, f)
return f return f
} }
@ -773,8 +768,8 @@ exports.removeEventListener = function removeEventListener (element, action, lis
* @param {Element} parent * @param {Element} parent
* @return {boolean} returns true if elem is a child of the parent * @return {boolean} returns true if elem is a child of the parent
*/ */
exports.isChildOf = function (elem, parent) { exports.isChildOf = (elem, parent) => {
var e = elem.parentNode let e = elem.parentNode
while (e) { while (e) {
if (e === parent) { if (e === parent) {
return true return true
@ -791,11 +786,11 @@ exports.isChildOf = function (elem, parent) {
* @return {Array} * @return {Array}
*/ */
exports.parsePath = function parsePath (jsonPath) { exports.parsePath = function parsePath (jsonPath) {
var path = [] const path = []
var i = 0 let i = 0
function parseProperty () { function parseProperty () {
var prop = '' let prop = ''
while (jsonPath[i] !== undefined && /[\w$]/.test(jsonPath[i])) { while (jsonPath[i] !== undefined && /[\w$]/.test(jsonPath[i])) {
prop += jsonPath[i] prop += jsonPath[i]
i++ i++
@ -809,7 +804,7 @@ exports.parsePath = function parsePath (jsonPath) {
} }
function parseIndex (end) { function parseIndex (end) {
var name = '' let name = ''
while (jsonPath[i] !== undefined && jsonPath[i] !== end) { while (jsonPath[i] !== undefined && jsonPath[i] !== end) {
name += jsonPath[i] name += jsonPath[i]
i++ i++
@ -830,7 +825,7 @@ exports.parsePath = function parsePath (jsonPath) {
i++ i++
if (jsonPath[i] === '\'' || jsonPath[i] === '"') { if (jsonPath[i] === '\'' || jsonPath[i] === '"') {
var end = jsonPath[i] const end = jsonPath[i]
i++ i++
path.push(parseIndex(end)) path.push(parseIndex(end))
@ -840,7 +835,7 @@ exports.parsePath = function parsePath (jsonPath) {
} }
i++ i++
} else { } else {
var index = parseIndex(']').trim() let index = parseIndex(']').trim()
if (index.length === 0) { if (index.length === 0) {
throw new Error('Invalid JSON path: array value expected at index ' + i) throw new Error('Invalid JSON path: array value expected at index ' + i)
} }
@ -868,7 +863,7 @@ exports.parsePath = function parsePath (jsonPath) {
*/ */
exports.stringifyPath = function stringifyPath (path) { exports.stringifyPath = function stringifyPath (path) {
return path return path
.map(function (p) { .map(p => {
if (typeof p === 'number') { if (typeof p === 'number') {
return ('[' + p + ']') return ('[' + p + ']')
} else if (typeof p === 'string' && p.match(/^[A-Za-z0-9_$]+$/)) { } else if (typeof p === 'string' && p.match(/^[A-Za-z0-9_$]+$/)) {
@ -885,16 +880,14 @@ exports.stringifyPath = function stringifyPath (path) {
* @param {Object} error * @param {Object} error
* @return {Object} The error * @return {Object} The error
*/ */
exports.improveSchemaError = function (error) { exports.improveSchemaError = error => {
if (error.keyword === 'enum' && Array.isArray(error.schema)) { if (error.keyword === 'enum' && Array.isArray(error.schema)) {
var enums = error.schema let enums = error.schema
if (enums) { if (enums) {
enums = enums.map(function (value) { enums = enums.map(value => JSON.stringify(value))
return JSON.stringify(value)
})
if (enums.length > 5) { if (enums.length > 5) {
var more = ['(' + (enums.length - 5) + ' more...)'] const more = ['(' + (enums.length - 5) + ' more...)']
enums = enums.slice(0, 5) enums = enums.slice(0, 5)
enums.push(more) enums.push(more)
} }
@ -914,20 +907,16 @@ exports.improveSchemaError = function (error) {
* @param {*} object * @param {*} object
* @returns {boolean} Returns true when object is a promise, false otherwise * @returns {boolean} Returns true when object is a promise, false otherwise
*/ */
exports.isPromise = function (object) { exports.isPromise = object => object && typeof object.then === 'function' && typeof object.catch === 'function'
return object && typeof object.then === 'function' && typeof object.catch === 'function'
}
/** /**
* Test whether a custom validation error has the correct structure * Test whether a custom validation error has the correct structure
* @param {*} validationError The error to be checked. * @param {*} validationError The error to be checked.
* @returns {boolean} Returns true if the structure is ok, false otherwise * @returns {boolean} Returns true if the structure is ok, false otherwise
*/ */
exports.isValidValidationError = function (validationError) { exports.isValidValidationError = validationError => typeof validationError === 'object' &&
return typeof validationError === 'object' && Array.isArray(validationError.path) &&
Array.isArray(validationError.path) && typeof validationError.message === 'string'
typeof validationError.message === 'string'
}
/** /**
* Test whether the child rect fits completely inside the parent rect. * Test whether the child rect fits completely inside the parent rect.
@ -935,8 +924,8 @@ exports.isValidValidationError = function (validationError) {
* @param {ClientRect} child * @param {ClientRect} child
* @param {number} margin * @param {number} margin
*/ */
exports.insideRect = function (parent, child, margin) { exports.insideRect = (parent, child, margin) => {
var _margin = margin !== undefined ? margin : 0 const _margin = margin !== undefined ? margin : 0
return child.left - _margin >= parent.left && return child.left - _margin >= parent.left &&
child.right + _margin <= parent.right && child.right + _margin <= parent.right &&
child.top - _margin >= parent.top && child.top - _margin >= parent.top &&
@ -958,14 +947,14 @@ exports.insideRect = function (parent, child, margin) {
* @return {function} Return the debounced function * @return {function} Return the debounced function
*/ */
exports.debounce = function debounce (func, wait, immediate) { exports.debounce = function debounce (func, wait, immediate) {
var timeout let timeout
return function () { return function () {
var context = this; var args = arguments const context = this; const args = arguments
var later = function () { const later = () => {
timeout = null timeout = null
if (!immediate) func.apply(context, args) if (!immediate) func.apply(context, args)
} }
var callNow = immediate && !timeout const callNow = immediate && !timeout
clearTimeout(timeout) clearTimeout(timeout)
timeout = setTimeout(later, wait) timeout = setTimeout(later, wait)
if (callNow) func.apply(context, args) if (callNow) func.apply(context, args)
@ -981,10 +970,10 @@ exports.debounce = function debounce (func, wait, immediate) {
* of the changed part in newText. * of the changed part in newText.
*/ */
exports.textDiff = function textDiff (oldText, newText) { exports.textDiff = function textDiff (oldText, newText) {
var len = newText.length const len = newText.length
var start = 0 let start = 0
var oldEnd = oldText.length let oldEnd = oldText.length
var newEnd = newText.length let newEnd = newText.length
while (newText.charAt(start) === oldText.charAt(start) && while (newText.charAt(start) === oldText.charAt(start) &&
start < len) { start < len) {
@ -1007,8 +996,8 @@ exports.textDiff = function textDiff (oldText, newText) {
* @param {DOMElement} el A dom element of a textarea or input text. * @param {DOMElement} el A dom element of a textarea or input text.
* @return {Object} reference Object with 2 properties (start and end) with the identifier of the location of the cursor and selected text. * @return {Object} reference Object with 2 properties (start and end) with the identifier of the location of the cursor and selected text.
**/ **/
exports.getInputSelection = function (el) { exports.getInputSelection = el => {
var startIndex = 0; var endIndex = 0; var normalizedValue; var range; var textInputRange; var len; var endRange let startIndex = 0; let endIndex = 0; let normalizedValue; let range; let textInputRange; let len; let endRange
if (typeof el.selectionStart === 'number' && typeof el.selectionEnd === 'number') { if (typeof el.selectionStart === 'number' && typeof el.selectionEnd === 'number') {
startIndex = el.selectionStart startIndex = el.selectionStart
@ -1059,9 +1048,9 @@ exports.getInputSelection = function (el) {
* @returns {{row: Number, column: Number}} * @returns {{row: Number, column: Number}}
*/ */
function _positionForIndex (index) { function _positionForIndex (index) {
var textTillIndex = el.value.substring(0, index) const textTillIndex = el.value.substring(0, index)
var row = (textTillIndex.match(/\n/g) || []).length + 1 const row = (textTillIndex.match(/\n/g) || []).length + 1
var col = textTillIndex.length - textTillIndex.lastIndexOf('\n') const col = textTillIndex.length - textTillIndex.lastIndexOf('\n')
return { return {
row: row, row: row,
@ -1077,13 +1066,13 @@ exports.getInputSelection = function (el) {
* @param {Number} column column value, > 0, if exceeds column length - end of column will be returned * @param {Number} column column value, > 0, if exceeds column length - end of column will be returned
* @returns {Number} index of position in text, -1 if not found * @returns {Number} index of position in text, -1 if not found
*/ */
exports.getIndexForPosition = function (el, row, column) { exports.getIndexForPosition = (el, row, column) => {
var text = el.value || '' const text = el.value || ''
if (row > 0 && column > 0) { if (row > 0 && column > 0) {
var rows = text.split('\n', row) const rows = text.split('\n', row)
row = Math.min(rows.length, row) row = Math.min(rows.length, row)
column = Math.min(rows[row - 1].length, column - 1) column = Math.min(rows[row - 1].length, column - 1)
var columnCount = (row === 1 ? column : column + 1) // count new line on multiple rows const columnCount = (row === 1 ? column : column + 1) // count new line on multiple rows
return rows.slice(0, row - 1).join('\n').length + columnCount return rows.slice(0, row - 1).join('\n').length + columnCount
} }
return -1 return -1
@ -1109,7 +1098,7 @@ exports.getPositionForPath = function (text, paths) {
return result return result
} }
paths.forEach(function (path) { paths.forEach(path => {
const pathArr = me.parsePath(path) const pathArr = me.parsePath(path)
const pointerName = exports.compileJSONPointer(pathArr) const pointerName = exports.compileJSONPointer(pathArr)
const pointer = jsmap.pointers[pointerName] const pointer = jsmap.pointers[pointerName]
@ -1131,14 +1120,12 @@ exports.getPositionForPath = function (text, paths) {
* @param {Array.<string | number>} path * @param {Array.<string | number>} path
* @return {string} * @return {string}
*/ */
exports.compileJSONPointer = function (path) { exports.compileJSONPointer = path => path
return path .map(p => ('/' + String(p)
.map(p => ('/' + String(p) .replace(/~/g, '~0')
.replace(/~/g, '~0') .replace(/\//g, '~1')
.replace(/\//g, '~1') ))
)) .join('')
.join('')
}
/** /**
* Get the applied color given a color name or code * Get the applied color given a color name or code
@ -1148,8 +1135,8 @@ exports.compileJSONPointer = function (path) {
* color, and returns null otherwise. Example output: * color, and returns null otherwise. Example output:
* 'rgba(255,0,0,0.7)' or 'rgb(255,0,0)' * 'rgba(255,0,0,0.7)' or 'rgb(255,0,0)'
*/ */
exports.getColorCSS = function (color) { exports.getColorCSS = color => {
var ele = document.createElement('div') const ele = document.createElement('div')
ele.style.color = color ele.style.color = color
return ele.style.color.split(/\s+/).join('').toLowerCase() || null return ele.style.color.split(/\s+/).join('').toLowerCase() || null
} }
@ -1159,9 +1146,7 @@ exports.getColorCSS = function (color) {
* @param {string} color * @param {string} color
* @returns {boolean} returns true if a valid color, false otherwise * @returns {boolean} returns true if a valid color, false otherwise
*/ */
exports.isValidColor = function (color) { exports.isValidColor = color => !!exports.getColorCSS(color)
return !!exports.getColorCSS(color)
}
/** /**
* Make a tooltip for a field based on the field's schema. * Make a tooltip for a field based on the field's schema.
@ -1169,12 +1154,12 @@ exports.isValidColor = function (color) {
* @param {string} [locale] Locale code (for example, zh-CN) * @param {string} [locale] Locale code (for example, zh-CN)
* @returns {string} Field tooltip, may be empty string if all relevant schema properties are missing * @returns {string} Field tooltip, may be empty string if all relevant schema properties are missing
*/ */
exports.makeFieldTooltip = function (schema, locale) { exports.makeFieldTooltip = (schema, locale) => {
if (!schema) { if (!schema) {
return '' return ''
} }
var tooltip = '' let tooltip = ''
if (schema.title) { if (schema.title) {
tooltip += schema.title tooltip += schema.title
} }
@ -1199,7 +1184,7 @@ exports.makeFieldTooltip = function (schema, locale) {
tooltip += '\n\n' tooltip += '\n\n'
} }
tooltip += translate('examples', undefined, locale) + '\n' tooltip += translate('examples', undefined, locale) + '\n'
schema.examples.forEach(function (example, index) { schema.examples.forEach((example, index) => {
tooltip += JSON.stringify(example, null, 2) tooltip += JSON.stringify(example, null, 2)
if (index !== schema.examples.length - 1) { if (index !== schema.examples.length - 1) {
tooltip += '\n' tooltip += '\n'
@ -1217,10 +1202,10 @@ exports.makeFieldTooltip = function (schema, locale) {
* @param {string[]} path * @param {string[]} path
* @return {*} * @return {*}
*/ */
exports.get = function (object, path) { exports.get = (object, path) => {
var value = object let value = object
for (var i = 0; i < path.length && value !== undefined && value !== null; i++) { for (let i = 0; i < path.length && value !== undefined && value !== null; i++) {
value = value[path[i]] value = value[path[i]]
} }
@ -1233,13 +1218,13 @@ exports.get = function (object, path) {
* @param {string} name * @param {string} name
* @param {Array} existingPropNames Array with existing prop names * @param {Array} existingPropNames Array with existing prop names
*/ */
exports.findUniqueName = function (name, existingPropNames) { exports.findUniqueName = (name, existingPropNames) => {
var strippedName = name.replace(/ \(copy( \d+)?\)$/, '') const strippedName = name.replace(/ \(copy( \d+)?\)$/, '')
var validName = strippedName let validName = strippedName
var i = 1 let i = 1
while (existingPropNames.indexOf(validName) !== -1) { while (existingPropNames.indexOf(validName) !== -1) {
var copy = 'copy' + (i > 1 ? (' ' + i) : '') const copy = 'copy' + (i > 1 ? (' ' + i) : '')
validName = strippedName + ' (' + copy + ')' validName = strippedName + ' (' + copy + ')'
i++ i++
} }
@ -1253,27 +1238,27 @@ exports.findUniqueName = function (name, existingPropNames) {
* @param {boolean} [includeObjects=false] If true, object and array paths are returned as well * @param {boolean} [includeObjects=false] If true, object and array paths are returned as well
* @return {string[]} * @return {string[]}
*/ */
exports.getChildPaths = function (json, includeObjects) { exports.getChildPaths = (json, includeObjects) => {
var pathsMap = {} const pathsMap = {}
function getObjectChildPaths (json, pathsMap, rootPath, includeObjects) { function getObjectChildPaths (json, pathsMap, rootPath, includeObjects) {
var isValue = !Array.isArray(json) && !exports.isObject(json) const isValue = !Array.isArray(json) && !exports.isObject(json)
if (isValue || includeObjects) { if (isValue || includeObjects) {
pathsMap[rootPath || ''] = true pathsMap[rootPath || ''] = true
} }
if (exports.isObject(json)) { if (exports.isObject(json)) {
Object.keys(json).forEach(function (field) { Object.keys(json).forEach(field => {
getObjectChildPaths(json[field], pathsMap, rootPath + '.' + field, includeObjects) getObjectChildPaths(json[field], pathsMap, rootPath + '.' + field, includeObjects)
}) })
} }
} }
if (Array.isArray(json)) { if (Array.isArray(json)) {
var max = Math.min(json.length, MAX_ITEMS_FIELDS_COLLECTION) const max = Math.min(json.length, MAX_ITEMS_FIELDS_COLLECTION)
for (var i = 0; i < max; i++) { for (let i = 0; i < max; i++) {
var item = json[i] const item = json[i]
getObjectChildPaths(item, pathsMap, '', includeObjects) getObjectChildPaths(item, pathsMap, '', includeObjects)
} }
} else { } else {
@ -1289,14 +1274,14 @@ exports.getChildPaths = function (json, includeObjects) {
* @param {String} [path] JSON pointer * @param {String} [path] JSON pointer
* @param {'asc' | 'desc'} [direction] * @param {'asc' | 'desc'} [direction]
*/ */
exports.sort = function (array, path, direction) { exports.sort = (array, path, direction) => {
var parsedPath = path && path !== '.' ? exports.parsePath(path) : [] const parsedPath = path && path !== '.' ? exports.parsePath(path) : []
var sign = direction === 'desc' ? -1 : 1 const sign = direction === 'desc' ? -1 : 1
var sortedArray = array.slice() const sortedArray = array.slice()
sortedArray.sort(function (a, b) { sortedArray.sort((a, b) => {
var aValue = exports.get(a, parsedPath) const aValue = exports.get(a, parsedPath)
var bValue = exports.get(b, parsedPath) const bValue = exports.get(b, parsedPath)
return sign * (aValue > bValue ? 1 : aValue < bValue ? -1 : 0) return sign * (aValue > bValue ? 1 : aValue < bValue ? -1 : 0)
}) })
@ -1309,14 +1294,12 @@ exports.sort = function (array, path, direction) {
* @param {Object} object * @param {Object} object
* @param {'asc' | 'desc'} [direction] * @param {'asc' | 'desc'} [direction]
*/ */
exports.sortObjectKeys = function (object, direction) { exports.sortObjectKeys = (object, direction) => {
var sign = (direction === 'desc') ? -1 : 1 const sign = (direction === 'desc') ? -1 : 1
var sortedFields = Object.keys(object).sort(function (a, b) { const sortedFields = Object.keys(object).sort((a, b) => sign * naturalSort(a, b))
return sign * naturalSort(a, b)
})
var sortedObject = {} const sortedObject = {}
sortedFields.forEach(function (field) { sortedFields.forEach(field => {
sortedObject[field] = object[field] sortedObject[field] = object[field]
}) })
@ -1330,10 +1313,10 @@ exports.sortObjectKeys = function (object, direction) {
* @return {*} castedStr * @return {*} castedStr
* @private * @private
*/ */
exports.parseString = function (str) { exports.parseString = str => {
var lower = str.toLowerCase() const lower = str.toLowerCase()
var num = Number(str) // will nicely fail with '123ab' const num = Number(str) // will nicely fail with '123ab'
var numFloat = parseFloat(str) // will nicely fail with ' ' const numFloat = parseFloat(str) // will nicely fail with ' '
if (str === '') { if (str === '') {
return '' return ''
@ -1356,27 +1339,27 @@ exports.parseString = function (str) {
* @param {number} size * @param {number} size
* @return {string} Returns a human readable size * @return {string} Returns a human readable size
*/ */
exports.formatSize = function (size) { exports.formatSize = size => {
if (size < 900) { if (size < 900) {
return size.toFixed() + ' B' return size.toFixed() + ' B'
} }
var KiB = size / 1024 const KiB = size / 1024
if (KiB < 900) { if (KiB < 900) {
return KiB.toFixed(1) + ' KiB' return KiB.toFixed(1) + ' KiB'
} }
var MiB = KiB / 1024 const MiB = KiB / 1024
if (MiB < 900) { if (MiB < 900) {
return MiB.toFixed(1) + ' MiB' return MiB.toFixed(1) + ' MiB'
} }
var GiB = MiB / 1024 const GiB = MiB / 1024
if (GiB < 900) { if (GiB < 900) {
return GiB.toFixed(1) + ' GiB' return GiB.toFixed(1) + ' GiB'
} }
var TiB = GiB / 1024 const TiB = GiB / 1024
return TiB.toFixed(1) + ' TiB' return TiB.toFixed(1) + ' TiB'
} }
@ -1387,7 +1370,7 @@ exports.formatSize = function (size) {
* @return {string} Returns the limited text, * @return {string} Returns the limited text,
* ending with '...' if the max was exceeded * ending with '...' if the max was exceeded
*/ */
exports.limitCharacters = function (text, maxCharacterCount) { exports.limitCharacters = (text, maxCharacterCount) => {
if (text.length <= maxCharacterCount) { if (text.length <= maxCharacterCount) {
return text return text
} }
@ -1400,9 +1383,7 @@ exports.limitCharacters = function (text, maxCharacterCount) {
* @param {*} value * @param {*} value
* @return {boolean} * @return {boolean}
*/ */
exports.isObject = function (value) { exports.isObject = value => typeof value === 'object' && value !== null && !Array.isArray(value)
return typeof value === 'object' && value !== null && !Array.isArray(value)
}
/** /**
* Helper function to test whether an array contains an item * Helper function to test whether an array contains an item
@ -1410,9 +1391,7 @@ exports.isObject = function (value) {
* @param {*} item * @param {*} item
* @return {boolean} Returns true if `item` is in `array`, returns false otherwise. * @return {boolean} Returns true if `item` is in `array`, returns false otherwise.
*/ */
exports.contains = function (array, item) { exports.contains = (array, item) => array.indexOf(item) !== -1
return array.indexOf(item) !== -1
}
function hasOwnProperty (object, key) { function hasOwnProperty (object, key) {
return Object.prototype.hasOwnProperty.call(object, key) return Object.prototype.hasOwnProperty.call(object, key)

View File

@ -1,6 +1,6 @@
var isPromise = require('./util').isPromise const isPromise = require('./util').isPromise
var isValidValidationError = require('./util').isValidValidationError const isValidValidationError = require('./util').isValidValidationError
var stringifyPath = require('./util').stringifyPath const stringifyPath = require('./util').stringifyPath
/** /**
* Execute custom validation if configured. * Execute custom validation if configured.
@ -13,17 +13,17 @@ function validateCustom (json, onValidate) {
} }
try { try {
var customValidateResults = onValidate(json) const customValidateResults = onValidate(json)
var resultPromise = isPromise(customValidateResults) const resultPromise = isPromise(customValidateResults)
? customValidateResults ? customValidateResults
: Promise.resolve(customValidateResults) : Promise.resolve(customValidateResults)
return resultPromise.then(function (customValidationPathErrors) { return resultPromise.then(customValidationPathErrors => {
if (Array.isArray(customValidationPathErrors)) { if (Array.isArray(customValidationPathErrors)) {
return customValidationPathErrors return customValidationPathErrors
.filter(function (error) { .filter(error => {
var valid = isValidValidationError(error) const valid = isValidValidationError(error)
if (!valid) { if (!valid) {
console.warn('Ignoring a custom validation error with invalid structure. ' + console.warn('Ignoring a custom validation error with invalid structure. ' +
@ -33,13 +33,11 @@ function validateCustom (json, onValidate) {
return valid return valid
}) })
.map(function (error) { .map(error => // change data structure into the structure matching the JSON schema errors
// change data structure into the structure matching the JSON schema errors ({
return {
dataPath: stringifyPath(error.path), dataPath: stringifyPath(error.path),
message: error.message message: error.message
} }))
})
} else { } else {
return [] return []
} }

View File

@ -1,4 +1,4 @@
var VanillaPicker let VanillaPicker
if (window.Picker) { if (window.Picker) {
// use the already loaded instance of VanillaPicker // use the already loaded instance of VanillaPicker