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

View File

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

View File

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

View File

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

View File

@ -1,19 +1,19 @@
'use strict'
var Ajv
let Ajv
try {
Ajv = require('ajv')
} catch (err) {
// no problem... when we need Ajv we will throw a neat exception
}
var 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 ace = require('./ace') // 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')
var textmode = require('./textmode')
var previewmode = require('./previewmode')
var util = require('./util')
const treemode = require('./treemode')
const textmode = require('./textmode')
const previewmode = require('./previewmode')
const util = require('./util')
if (typeof Promise === 'undefined') {
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)
var ieVersion = util.getInternetExplorerVersion()
const ieVersion = util.getInternetExplorerVersion()
if (ieVersion !== -1 && ieVersion < 9) {
throw new Error('Unsupported browser, IE9 or newer required. ' +
'Please install the newest version of your browser.')
@ -136,7 +136,7 @@ function JSONEditor (container, options, json) {
// validate options
if (options) {
Object.keys(options).forEach(function (option) {
Object.keys(options).forEach(option => {
if (JSONEditor.VALID_OPTIONS.indexOf(option) === -1) {
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.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)
}
/**
* Destroy the editor. Clean up DOM, event listeners, and web workers.
*/
JSONEditor.prototype.destroy = function () {}
JSONEditor.prototype.destroy = () => {}
/**
* Set JSON object in editor
@ -266,17 +266,17 @@ JSONEditor.prototype.setMode = function (mode) {
return
}
var container = this.container
var options = util.extend({}, this.options)
var oldMode = options.mode
var data
var name
const container = this.container
const options = util.extend({}, this.options)
const oldMode = options.mode
let data
let name
options.mode = mode
var config = JSONEditor.modes[mode]
const config = JSONEditor.modes[mode]
if (config) {
try {
var asText = (config.data === 'text')
const asText = (config.data === 'text')
name = this.getName()
data = this[asText ? 'getText' : 'get']() // get text or json
@ -343,7 +343,7 @@ JSONEditor.prototype._onError = function (err) {
JSONEditor.prototype.setSchema = function (schema, schemaRefs) {
// compile a JSON schema validator if a JSON schema is provided
if (schema) {
var ajv
let ajv
try {
// grab ajv from options if provided, else create a new instance
if (this.options.ajv) {
@ -366,7 +366,7 @@ JSONEditor.prototype.setSchema = function (schema, schemaRefs) {
if (ajv) {
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
if (schemaRefs[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
* Throws an exception when no JSON schema is configured
*/
JSONEditor.prototype.validate = function () {
JSONEditor.prototype.validate = () => {
// must be implemented by treemode and textmode
}
/**
* Refresh the rendered contents
*/
JSONEditor.prototype.refresh = function () {
JSONEditor.prototype.refresh = () => {
// 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.
*/
JSONEditor.registerMode = function (mode) {
var i, prop
JSONEditor.registerMode = mode => {
let i, prop
if (util.isArray(mode)) {
// multiple modes
@ -442,7 +442,7 @@ JSONEditor.registerMode = function (mode) {
if (!('mode' in mode)) throw new Error('Property "mode" missing')
if (!('mixin' in mode)) throw new Error('Property "mixin" missing')
if (!('data' in mode)) throw new Error('Property "data" missing')
var name = mode.mode
const name = mode.mode
if (name in JSONEditor.modes) {
throw new Error('Mode "' + name + '" already registered')
}
@ -451,7 +451,7 @@ JSONEditor.registerMode = function (mode) {
if (typeof mode.mixin.create !== 'function') {
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++) {
prop = reserved[i]
if (prop in mode.mixin) {

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

@ -28,7 +28,7 @@
*
* ***** 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.cssClass = 'ace-jsoneditor'
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
}`
var dom = acequire('../lib/dom')
const dom = acequire('../lib/dom')
dom.importCssString(exports.cssText, exports.cssClass)
})

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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