Partial refactor to ES modules

This commit is contained in:
jos 2019-08-29 17:03:09 +02:00
parent a7d501fe3c
commit be61222225
27 changed files with 268 additions and 248 deletions

5
.babelrc Normal file
View File

@ -0,0 +1,5 @@
{
"presets": [
["@babel/preset-env"]
]
}

View File

@ -40,10 +40,7 @@ var webpackConfigModule = {
test: /\.m?js$/, test: /\.m?js$/,
exclude: /node_modules/, exclude: /node_modules/,
use: { use: {
loader: 'babel-loader', loader: 'babel-loader'
options: {
presets: ['@babel/preset-env']
}
} }
} }
] ]

35
package-lock.json generated
View File

@ -758,6 +758,20 @@
"semver": "^5.5.0" "semver": "^5.5.0"
} }
}, },
"@babel/register": {
"version": "7.5.5",
"resolved": "https://registry.npmjs.org/@babel/register/-/register-7.5.5.tgz",
"integrity": "sha512-pdd5nNR+g2qDkXZlW1yRCWFlNrAn2PPdnZUB72zjX4l1Vv4fMRRLwyf+n/idFCLI1UgVGboUU8oVziwTBiyNKQ==",
"dev": true,
"requires": {
"core-js": "^3.0.0",
"find-cache-dir": "^2.0.0",
"lodash": "^4.17.13",
"mkdirp": "^0.5.1",
"pirates": "^4.0.0",
"source-map-support": "^0.5.9"
}
},
"@babel/template": { "@babel/template": {
"version": "7.4.4", "version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz",
@ -2233,6 +2247,12 @@
"is-plain-object": "^2.0.1" "is-plain-object": "^2.0.1"
} }
}, },
"core-js": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.2.1.tgz",
"integrity": "sha512-Qa5XSVefSVPRxy2XfUC13WbvqkxhkwB3ve+pgCQveNgYzbM/UxZeu1dcOX/xr4UmfUd+muuvsaxilQzCyUurMw==",
"dev": true
},
"core-js-compat": { "core-js-compat": {
"version": "3.2.1", "version": "3.2.1",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.2.1.tgz", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.2.1.tgz",
@ -6569,6 +6589,12 @@
} }
} }
}, },
"node-modules-regexp": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz",
"integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=",
"dev": true
},
"node-releases": { "node-releases": {
"version": "1.1.28", "version": "1.1.28",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.28.tgz", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.28.tgz",
@ -7216,6 +7242,15 @@
"pinkie": "^2.0.0" "pinkie": "^2.0.0"
} }
}, },
"pirates": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz",
"integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==",
"dev": true,
"requires": {
"node-modules-regexp": "^1.0.0"
}
},
"pkg-conf": { "pkg-conf": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-3.1.0.tgz", "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-3.1.0.tgz",

View File

@ -21,7 +21,7 @@
"build": "gulp", "build": "gulp",
"minify": "gulp minify", "minify": "gulp minify",
"start": "gulp watch", "start": "gulp watch",
"test": "mocha test", "test": "mocha test --require @babel/register",
"lint": "standard --env=mocha" "lint": "standard --env=mocha"
}, },
"dependencies": { "dependencies": {
@ -37,6 +37,7 @@
"devDependencies": { "devDependencies": {
"@babel/core": "7.5.5", "@babel/core": "7.5.5",
"@babel/preset-env": "7.5.5", "@babel/preset-env": "7.5.5",
"@babel/register": "7.5.5",
"babel-loader": "8.0.6", "babel-loader": "8.0.6",
"date-format": "2.1.0", "date-format": "2.1.0",
"fancy-log": "1.3.3", "fancy-log": "1.3.3",

View File

@ -1,8 +1,8 @@
'use strict' 'use strict'
const createAbsoluteAnchor = require('./createAbsoluteAnchor').createAbsoluteAnchor import { createAbsoluteAnchor } from './createAbsoluteAnchor'
const util = require('./util') import { addClassName, getSelection, removeClassName, setSelection } from './util'
const translate = require('./i18n').translate import { translate } from './i18n'
/** /**
* A context menu * A context menu
@ -13,7 +13,7 @@ const translate = require('./i18n').translate
* context menu is being closed. * context menu is being closed.
* @constructor * @constructor
*/ */
function ContextMenu (items, options) { export function ContextMenu (items, options) {
this.dom = {} this.dom = {}
const me = this const me = this
@ -241,7 +241,7 @@ ContextMenu.prototype.show = function (anchor, frame, ignoreParent) {
this.dom.absoluteAnchor.appendChild(this.dom.root) this.dom.absoluteAnchor.appendChild(this.dom.root)
// move focus to the first button in the context menu // move focus to the first button in the context menu
this.selection = util.getSelection() this.selection = getSelection()
this.anchor = anchor this.anchor = anchor
setTimeout(() => { setTimeout(() => {
me.dom.focusButton.focus() me.dom.focusButton.focus()
@ -295,7 +295,7 @@ ContextMenu.prototype._onExpandItem = function (domItem) {
setTimeout(() => { setTimeout(() => {
if (me.expandedItem !== expandedItem) { if (me.expandedItem !== expandedItem) {
expandedItem.ul.style.display = '' expandedItem.ul.style.display = ''
util.removeClassName(expandedItem.ul.parentNode, 'jsoneditor-selected') removeClassName(expandedItem.ul.parentNode, 'jsoneditor-selected')
} }
}, 300) // timeout duration must match the css transition duration }, 300) // timeout duration must match the css transition duration
this.expandedItem = undefined this.expandedItem = undefined
@ -316,7 +316,7 @@ ContextMenu.prototype._onExpandItem = function (domItem) {
ul.style.padding = '5px 10px' ul.style.padding = '5px 10px'
} }
}, 0) }, 0)
util.addClassName(ul.parentNode, 'jsoneditor-selected') addClassName(ul.parentNode, 'jsoneditor-selected')
this.expandedItem = domItem this.expandedItem = domItem
} }
} }
@ -337,7 +337,7 @@ ContextMenu.prototype._onKeyDown = function (event) {
// restore previous selection and focus // restore previous selection and focus
if (this.selection) { if (this.selection) {
util.setSelection(this.selection) setSelection(this.selection)
} }
if (this.anchor) { if (this.anchor) {
this.anchor.focus() this.anchor.focus()
@ -424,4 +424,4 @@ ContextMenu.prototype._onKeyDown = function (event) {
} }
} }
module.exports = ContextMenu export default ContextMenu;

View File

@ -7,7 +7,7 @@
* @property {function (number)} onChangeHeight * @property {function (number)} onChangeHeight
* @constructor * @constructor
*/ */
function ErrorTable (config) { export function ErrorTable (config) {
this.errorTableVisible = config.errorTableVisible this.errorTableVisible = config.errorTableVisible
this.onToggleVisibility = config.onToggleVisibility this.onToggleVisibility = config.onToggleVisibility
this.onFocusLine = config.onFocusLine || (() => {}) this.onFocusLine = config.onFocusLine || (() => {})
@ -166,5 +166,3 @@ ErrorTable.prototype.setErrors = function (errors, errorLocations) {
this.dom.parseErrorIndication.style.display = 'none' this.dom.parseErrorIndication.style.display = 'none'
} }
} }
module.exports = ErrorTable

View File

@ -5,7 +5,7 @@
* animate the visibility of a context menu. * animate the visibility of a context menu.
* @constructor Highlighter * @constructor Highlighter
*/ */
function Highlighter () { export function Highlighter () {
this.locked = false this.locked = false
} }
@ -82,5 +82,3 @@ Highlighter.prototype.lock = function () {
Highlighter.prototype.unlock = function () { Highlighter.prototype.unlock = function () {
this.locked = false this.locked = false
} }
module.exports = Highlighter

View File

@ -6,7 +6,7 @@
* @param {number} limit Maximum size of all items in history * @param {number} limit Maximum size of all items in history
* @constructor * @constructor
*/ */
function History (onChange, calculateItemSize, limit) { export function History (onChange, calculateItemSize, limit) {
this.onChange = onChange this.onChange = onChange
this.calculateItemSize = calculateItemSize || (() => 1) this.calculateItemSize = calculateItemSize || (() => 1)
this.limit = limit this.limit = limit
@ -81,5 +81,3 @@ History.prototype.clear = function () {
this.onChange() this.onChange()
} }
module.exports = History

View File

@ -1,6 +1,6 @@
'use strict' 'use strict'
const ContextMenu = require('./ContextMenu') const ContextMenu = require('./ContextMenu').ContextMenu
const translate = require('./i18n').translate const translate = require('./i18n').translate
/** /**

View File

@ -3,11 +3,11 @@
const jmespath = require('jmespath') const jmespath = require('jmespath')
const naturalSort = require('javascript-natural-sort') const naturalSort = require('javascript-natural-sort')
const createAbsoluteAnchor = require('./createAbsoluteAnchor').createAbsoluteAnchor const createAbsoluteAnchor = require('./createAbsoluteAnchor').createAbsoluteAnchor
const ContextMenu = require('./ContextMenu') const ContextMenu = require('./ContextMenu').ContextMenu
const appendNodeFactory = require('./appendNodeFactory') const appendNodeFactory = require('./appendNodeFactory')
const showMoreNodeFactory = require('./showMoreNodeFactory') const showMoreNodeFactory = require('./showMoreNodeFactory').showMoreNodeFactory
const showSortModal = require('./showSortModal') const showSortModal = require('./showSortModal').showSortModal
const showTransformModal = require('./showTransformModal') const showTransformModal = require('./showTransformModal').showTransformModal
const util = require('./util') const util = require('./util')
const translate = require('./i18n').translate const translate = require('./i18n').translate
const DEFAULT_MODAL_ANCHOR = require('./constants').DEFAULT_MODAL_ANCHOR const DEFAULT_MODAL_ANCHOR = require('./constants').DEFAULT_MODAL_ANCHOR

View File

@ -1,13 +1,13 @@
'use strict' 'use strict'
const util = require('./util') import { findUniqueName } from './util'
/** /**
* @constructor History * @constructor History
* Store action history, enables undo and redo * Store action history, enables undo and redo
* @param {JSONEditor} editor * @param {JSONEditor} editor
*/ */
function NodeHistory (editor) { export function NodeHistory (editor) {
this.editor = editor this.editor = editor
this.history = [] this.history = []
this.index = -1 this.index = -1
@ -125,7 +125,7 @@ function NodeHistory (editor) {
const clone = node.clone() const clone = node.clone()
if (parentNode.type === 'object') { if (parentNode.type === 'object') {
const existingFieldNames = parentNode.getFieldNames() const existingFieldNames = parentNode.getFieldNames()
clone.field = util.findUniqueName(node.field, existingFieldNames) clone.field = findUniqueName(node.field, existingFieldNames)
} }
parentNode.insertAfter(clone, afterNode) parentNode.insertAfter(clone, afterNode)
afterNode = clone afterNode = clone
@ -329,5 +329,3 @@ NodeHistory.prototype.destroy = function () {
this.history = [] this.history = []
this.index = -1 this.index = -1
} }
module.exports = NodeHistory

View File

@ -7,7 +7,7 @@
* @param {Element} container HTML container element of where to * @param {Element} container HTML container element of where to
* create the search box * create the search box
*/ */
function SearchBox (editor, container) { export function SearchBox (editor, container) {
const searchBox = this const searchBox = this
this.editor = editor this.editor = editor
@ -319,5 +319,3 @@ SearchBox.prototype.destroy = function () {
this._clearDelay() this._clearDelay()
} }
module.exports = SearchBox

View File

@ -1,8 +1,8 @@
'use strict' 'use strict'
const ContextMenu = require('./ContextMenu') import { ContextMenu } from './ContextMenu'
const translate = require('./i18n').translate import { translate } from './i18n'
const util = require('./util') import { addClassName, removeClassName } from './util'
/** /**
* Creates a component that visualize path selection in tree based editors * Creates a component that visualize path selection in tree based editors
@ -10,7 +10,7 @@ const util = require('./util')
* @param {HTMLElement} root * @param {HTMLElement} root
* @constructor * @constructor
*/ */
function TreePath (container, root) { export function TreePath (container, root) {
if (container) { if (container) {
this.root = root this.root = root
this.path = document.createElement('div') this.path = document.createElement('div')
@ -91,7 +91,7 @@ TreePath.prototype.setPath = function (pathObjs) {
function _onShowAllClick (pathObjs) { function _onShowAllClick (pathObjs) {
me.contentMenuClicked = false me.contentMenuClicked = false
util.addClassName(me.path, 'show-all') addClassName(me.path, 'show-all')
me.path.style.width = me.path.parentNode.getBoundingClientRect().width - 10 + 'px' me.path.style.width = me.path.parentNode.getBoundingClientRect().width - 10 + 'px'
me.path.onblur = () => { me.path.onblur = () => {
if (me.contentMenuClicked) { if (me.contentMenuClicked) {
@ -99,7 +99,7 @@ TreePath.prototype.setPath = function (pathObjs) {
me.path.focus() me.path.focus()
return return
} }
util.removeClassName(me.path, 'show-all') removeClassName(me.path, 'show-all')
me.path.onblur = undefined me.path.onblur = undefined
me.path.style.width = '' me.path.style.width = ''
me.setPath(pathObjs) me.setPath(pathObjs)
@ -138,5 +138,3 @@ TreePath.prototype.onContextMenuItemSelected = function (callback) {
this.contextMenuCallback = callback this.contextMenuCallback = callback
} }
} }
module.exports = TreePath

View File

@ -1,7 +1,7 @@
'use strict' 'use strict'
const util = require('./util') const util = require('./util')
const ContextMenu = require('./ContextMenu') const ContextMenu = require('./ContextMenu').ContextMenu
const translate = require('./i18n').translate const translate = require('./i18n').translate
/** /**

View File

@ -9,7 +9,7 @@ const defaultFilterFunction = {
} }
} }
function completely (config) { export function autocomplete (config) {
config = config || {} config = config || {}
config.filter = config.filter || 'start' config.filter = config.filter || 'start'
config.trigger = config.trigger || 'keydown' config.trigger = config.trigger || 'keydown'
@ -379,5 +379,3 @@ function completely (config) {
return rs return rs
} }
module.exports = completely

View File

@ -1,7 +1,5 @@
exports.DEFAULT_MODAL_ANCHOR = document.body export var DEFAULT_MODAL_ANCHOR = document.body;
exports.SIZE_LARGE = 10 * 1024 * 1024 // 10 MB export var SIZE_LARGE = 10 * 1024 * 1024; // 10 MB
export var MAX_PREVIEW_CHARACTERS = 20000;
exports.MAX_PREVIEW_CHARACTERS = 20000 export var PREVIEW_HISTORY_LIMIT = 2 * 1024 * 1024 * 1024; // 2 GB
exports.PREVIEW_HISTORY_LIMIT = 2 * 1024 * 1024 * 1024 // 2 GB

View File

@ -1,4 +1,4 @@
const util = require('./util') import { isChildOf, removeEventListener, addEventListener } from './util'
/** /**
* Create an anchor element absolutely positioned in the `parent` * Create an anchor element absolutely positioned in the `parent`
@ -8,7 +8,7 @@ const util = require('./util')
* @param [onDestroy(function(anchor)] Callback when the anchor is destroyed * @param [onDestroy(function(anchor)] Callback when the anchor is destroyed
* @returns {HTMLElement} * @returns {HTMLElement}
*/ */
exports.createAbsoluteAnchor = (anchor, parent, onDestroy) => { export function createAbsoluteAnchor(anchor, parent, onDestroy) {
const root = getRootNode(anchor) const root = getRootNode(anchor)
const eventListeners = {} const eventListeners = {}
@ -36,7 +36,7 @@ exports.createAbsoluteAnchor = (anchor, parent, onDestroy) => {
if (hasOwnProperty(eventListeners, name)) { if (hasOwnProperty(eventListeners, name)) {
const fn = eventListeners[name] const fn = eventListeners[name]
if (fn) { if (fn) {
util.removeEventListener(root, name, fn) removeEventListener(root, name, fn)
} }
delete eventListeners[name] delete eventListeners[name]
} }
@ -51,14 +51,14 @@ exports.createAbsoluteAnchor = (anchor, parent, onDestroy) => {
// create and attach event listeners // create and attach event listeners
const destroyIfOutside = event => { const destroyIfOutside = event => {
const target = event.target const target = event.target
if ((target !== absoluteAnchor) && !util.isChildOf(target, absoluteAnchor)) { if ((target !== absoluteAnchor) && !isChildOf(target, absoluteAnchor)) {
destroy() destroy()
} }
} }
eventListeners.mousedown = util.addEventListener(root, 'mousedown', destroyIfOutside) eventListeners.mousedown = addEventListener(root, 'mousedown', destroyIfOutside)
eventListeners.mousewheel = util.addEventListener(root, 'mousewheel', destroyIfOutside) eventListeners.mousewheel = addEventListener(root, 'mousewheel', destroyIfOutside)
// eventListeners.scroll = util.addEventListener(root, 'scroll', destroyIfOutside); // eventListeners.scroll = addEventListener(root, 'scroll', destroyIfOutside);
absoluteAnchor.destroy = destroy absoluteAnchor.destroy = destroy

View File

@ -2,7 +2,7 @@
/* eslint-disable no-template-curly-in-string */ /* eslint-disable no-template-curly-in-string */
require('./polyfills') import './polyfills'
const _locales = ['en', 'pt-BR', 'zh-CN', 'tr'] const _locales = ['en', 'pt-BR', 'zh-CN', 'tr']
const _defs = { const _defs = {
@ -377,21 +377,12 @@ const _defs = {
} }
const _defaultLang = 'en' const _defaultLang = 'en'
let _lang
const userLang = typeof navigator !== 'undefined' const userLang = typeof navigator !== 'undefined'
? navigator.language || navigator.userLanguage ? navigator.language || navigator.userLanguage
: undefined : undefined
_lang = _locales.find(l => l === userLang) let _lang = _locales.find(l => l === userLang) || _defaultLang
if (!_lang) {
_lang = _defaultLang
}
module.exports = { export function setLanguage (lang) {
// supported locales
_locales: _locales,
_defs: _defs,
_lang: _lang,
setLanguage: function (lang) {
if (!lang) { if (!lang) {
return return
} }
@ -401,8 +392,9 @@ module.exports = {
} else { } else {
console.error('Language not found') console.error('Language not found')
} }
}, }
setLanguages: function (languages) {
export function setLanguages (languages) {
if (!languages) { if (!languages) {
return return
} }
@ -413,8 +405,9 @@ module.exports = {
} }
_defs[key] = Object.assign({}, _defs[_defaultLang], _defs[key], languages[key]) _defs[key] = Object.assign({}, _defs[_defaultLang], _defs[key], languages[key])
} }
}, }
translate: function (key, data, lang) {
export function translate (key, data, lang) {
if (!lang) { if (!lang) {
lang = _lang lang = _lang
} }
@ -426,4 +419,3 @@ module.exports = {
} }
return text || key return text || key
} }
}

View File

@ -21,7 +21,7 @@
* *
* @returns {string | undefined} Returns the string representation of the JSON object. * @returns {string | undefined} Returns the string representation of the JSON object.
*/ */
function stringifyPartial (value, space, limit) { export function stringifyPartial (value, space, limit) {
let _space // undefined by default let _space // undefined by default
if (typeof space === 'number') { if (typeof space === 'number') {
if (space > 10) { if (space > 10) {
@ -188,13 +188,10 @@ function slice (text, limit) {
* @param {string} jsonText * @param {string} jsonText
* @return {boolean} * @return {boolean}
*/ */
function containsArray (jsonText) { export function containsArray (jsonText) {
return /^\s*\[/.test(jsonText) return /^\s*\[/.test(jsonText)
} }
function hasOwnProperty (object, key) { function hasOwnProperty (object, key) {
return Object.prototype.hasOwnProperty.call(object, key) return Object.prototype.hasOwnProperty.call(object, key)
} }
exports.stringifyPartial = stringifyPartial
exports.containsArray = containsArray

View File

@ -5,14 +5,14 @@ const translate = require('./i18n').translate
const ModeSwitcher = require('./ModeSwitcher') const ModeSwitcher = require('./ModeSwitcher')
const ErrorTable = require('./ErrorTable') const ErrorTable = require('./ErrorTable')
const textmode = require('./textmode')[0].mixin const textmode = require('./textmode')[0].mixin
const showSortModal = require('./showSortModal') const showSortModal = require('./showSortModal').showSortModal
const showTransformModal = require('./showTransformModal') const showTransformModal = require('./showTransformModal').showTransformModal
const MAX_PREVIEW_CHARACTERS = require('./constants').MAX_PREVIEW_CHARACTERS const MAX_PREVIEW_CHARACTERS = require('./constants').MAX_PREVIEW_CHARACTERS
const DEFAULT_MODAL_ANCHOR = require('./constants').DEFAULT_MODAL_ANCHOR const DEFAULT_MODAL_ANCHOR = require('./constants').DEFAULT_MODAL_ANCHOR
const SIZE_LARGE = require('./constants').SIZE_LARGE const SIZE_LARGE = require('./constants').SIZE_LARGE
const PREVIEW_HISTORY_LIMIT = require('./constants').PREVIEW_HISTORY_LIMIT const PREVIEW_HISTORY_LIMIT = require('./constants').PREVIEW_HISTORY_LIMIT
const util = require('./util') const util = require('./util')
const History = require('./History') const History = require('./History').History
// create a mixin with the functions for text mode // create a mixin with the functions for text mode
const previewmode = {} const previewmode = {}
@ -23,10 +23,7 @@ const previewmode = {}
* @param {Object} [options] Object with options. See docs for details. * @param {Object} [options] Object with options. See docs for details.
* @private * @private
*/ */
previewmode.create = function (container, options) { previewmode.create = function (container, options = {}) {
// read options
options = options || {}
if (typeof options.statusBar === 'undefined') { if (typeof options.statusBar === 'undefined') {
options.statusBar = true options.statusBar = true
} }

View File

@ -1,12 +1,12 @@
'use strict' 'use strict'
const translate = require('./i18n').translate import {translate} from './i18n';
/** /**
* A factory function to create an ShowMoreNode, which depends on a Node * A factory function to create an ShowMoreNode, which depends on a Node
* @param {function} Node * @param {function} Node
*/ */
function showMoreNodeFactory (Node) { export function showMoreNodeFactory (Node) {
/** /**
* @constructor ShowMoreNode * @constructor ShowMoreNode
* @extends Node * @extends Node
@ -152,5 +152,3 @@ function showMoreNodeFactory (Node) {
return ShowMoreNode return ShowMoreNode
} }
module.exports = showMoreNodeFactory

View File

@ -1,6 +1,6 @@
const picoModal = require('picomodal') import picoModal from 'picomodal';
const translate = require('./i18n').translate import {translate} from './i18n';
const util = require('./util') import { contains, getChildPaths } from './util'
/** /**
* Show advanced sorting modal * Show advanced sorting modal
@ -15,11 +15,11 @@ const util = require('./util')
* - {string} path The selected path * - {string} path The selected path
* - {'asc' | 'desc'} direction The selected direction * - {'asc' | 'desc'} direction The selected direction
*/ */
function showSortModal (container, json, onSort, options) { export function showSortModal (container, json, onSort, options) {
const paths = Array.isArray(json) const paths = Array.isArray(json)
? util.getChildPaths(json) ? getChildPaths(json)
: [''] : ['']
const selectedPath = options && options.path && util.contains(paths, options.path) const selectedPath = options && options.path && contains(paths, options.path)
? options.path ? options.path
: paths[0] : paths[0]
const selectedDirection = (options && options.direction) || 'asc' const selectedDirection = (options && options.direction) || 'asc'
@ -129,5 +129,3 @@ function showSortModal (container, json, onSort, options) {
}) })
.show() .show()
} }
module.exports = showSortModal

View File

@ -1,11 +1,10 @@
const jmespath = require('jmespath') import jmespath from 'jmespath';
const picoModal = require('picomodal') import picoModal from 'picomodal';
const Selectr = require('./assets/selectr/selectr') import Selectr from './assets/selectr/selectr';
const translate = require('./i18n').translate import {translate} from './i18n';
const stringifyPartial = require('./jsonUtils').stringifyPartial import {stringifyPartial} from './jsonUtils';
const util = require('./util') import { getChildPaths, get, parsePath, parseString, debounce } from './util'
const MAX_PREVIEW_CHARACTERS = require('./constants').MAX_PREVIEW_CHARACTERS import {MAX_PREVIEW_CHARACTERS} from './constants';
const debounce = util.debounce
/** /**
* Show advanced filter and transform modal using JMESPath * Show advanced filter and transform modal using JMESPath
@ -15,7 +14,7 @@ const debounce = util.debounce
* @param {function} onTransform Callback invoked with the created * @param {function} onTransform Callback invoked with the created
* query as callback * query as callback
*/ */
function showTransformModal (container, json, onTransform) { export function showTransformModal (container, json, onTransform) {
const value = json const value = json
const content = '<label class="pico-modal-contents">' + const content = '<label class="pico-modal-contents">' +
@ -125,7 +124,7 @@ function showTransformModal (container, json, onTransform) {
wizard.innerHTML = '(wizard not available for objects, only for arrays)' wizard.innerHTML = '(wizard not available for objects, only for arrays)'
} }
const sortablePaths = util.getChildPaths(json) const sortablePaths = getChildPaths(json)
sortablePaths.forEach(path => { sortablePaths.forEach(path => {
const formattedPath = preprocessPath(path) const formattedPath = preprocessPath(path)
@ -140,7 +139,7 @@ function showTransformModal (container, json, onTransform) {
sortField.appendChild(sortOption) sortField.appendChild(sortOption)
}) })
const selectablePaths = util.getChildPaths(json, true).filter(path => path !== '') const selectablePaths = getChildPaths(json, true).filter(path => path !== '')
if (selectablePaths.length > 0) { if (selectablePaths.length > 0) {
selectablePaths.forEach(path => { selectablePaths.forEach(path => {
const formattedPath = preprocessPath(path) const formattedPath = preprocessPath(path)
@ -191,12 +190,12 @@ function showTransformModal (container, json, onTransform) {
if (filterField.value && filterRelation.value && filterValue.value) { if (filterField.value && filterRelation.value && filterValue.value) {
const field1 = filterField.value const field1 = filterField.value
const examplePath = field1 !== '@' const examplePath = field1 !== '@'
? ['0'].concat(util.parsePath('.' + field1)) ? ['0'].concat(parsePath('.' + field1))
: ['0'] : ['0']
const exampleValue = util.get(value, examplePath) const exampleValue = get(value, examplePath)
const value1 = typeof exampleValue === 'string' const value1 = typeof exampleValue === 'string'
? filterValue.value ? filterValue.value
: util.parseString(filterValue.value) : parseString(filterValue.value)
query.value = '[? ' + query.value = '[? ' +
field1 + ' ' + field1 + ' ' +
@ -288,5 +287,3 @@ function showTransformModal (container, json, onTransform) {
}) })
.show() .show()
} }
module.exports = showTransformModal

View File

@ -4,10 +4,10 @@ const ace = require('./ace')
const jmespath = require('jmespath') const jmespath = require('jmespath')
const translate = require('./i18n').translate const translate = require('./i18n').translate
const ModeSwitcher = require('./ModeSwitcher') const ModeSwitcher = require('./ModeSwitcher')
const ErrorTable = require('./ErrorTable') const ErrorTable = require('./ErrorTable').ErrorTable
const validateCustom = require('./validationUtils').validateCustom const validateCustom = require('./validationUtils').validateCustom
const showSortModal = require('./showSortModal') const showSortModal = require('./showSortModal').showSortModal
const showTransformModal = require('./showTransformModal') const showTransformModal = require('./showTransformModal').showTransformModal
const util = require('./util') const util = require('./util')
const DEFAULT_MODAL_ANCHOR = require('./constants').DEFAULT_MODAL_ANCHOR const DEFAULT_MODAL_ANCHOR = require('./constants').DEFAULT_MODAL_ANCHOR

View File

@ -1,15 +1,15 @@
'use strict' 'use strict'
const VanillaPicker = require('./vanilla-picker') const VanillaPicker = require('./vanilla-picker')
const Highlighter = require('./Highlighter') const Highlighter = require('./Highlighter').Highlighter
const NodeHistory = require('./NodeHistory') const NodeHistory = require('./NodeHistory').NodeHistory
const SearchBox = require('./SearchBox') const SearchBox = require('./SearchBox').SearchBox
const ContextMenu = require('./ContextMenu') const ContextMenu = require('./ContextMenu').ContextMenu
const TreePath = require('./TreePath') const TreePath = require('./TreePath').TreePath
const Node = require('./Node') const Node = require('./Node')
const ModeSwitcher = require('./ModeSwitcher') const ModeSwitcher = require('./ModeSwitcher')
const util = require('./util') const util = require('./util')
const autocomplete = require('./autocomplete') const autocomplete = require('./autocomplete').autocomplete
const translate = require('./i18n').translate const translate = require('./i18n').translate
const setLanguages = require('./i18n').setLanguages const setLanguages = require('./i18n').setLanguages
const setLanguage = require('./i18n').setLanguage const setLanguage = require('./i18n').setLanguage

View File

@ -1,10 +1,10 @@
'use strict' 'use strict'
require('./polyfills') import './polyfills'
const naturalSort = require('javascript-natural-sort') import naturalSort from 'javascript-natural-sort';
const jsonlint = require('./assets/jsonlint/jsonlint') import jsonlint from './assets/jsonlint/jsonlint';
const jsonMap = require('json-source-map') import jsonMap from 'json-source-map';
const translate = require('./i18n').translate import {translate} from './i18n';
const MAX_ITEMS_FIELDS_COLLECTION = 10000 const MAX_ITEMS_FIELDS_COLLECTION = 10000
@ -14,12 +14,12 @@ const MAX_ITEMS_FIELDS_COLLECTION = 10000
* @param {String} jsonString * @param {String} jsonString
* @return {JSON} json * @return {JSON} json
*/ */
exports.parse = function parse (jsonString) { export function parse(jsonString) {
try { try {
return JSON.parse(jsonString) return JSON.parse(jsonString)
} catch (err) { } catch (err) {
// try to throw a more detailed error message using validate // try to throw a more detailed error message using validate
exports.validate(jsonString) validate(jsonString)
// rethrow the original error // rethrow the original error
throw err throw err
@ -34,7 +34,7 @@ exports.parse = function parse (jsonString) {
* @param {string} jsString * @param {string} jsString
* @returns {string} json * @returns {string} json
*/ */
exports.repair = jsString => { export function repair(jsString) {
// TODO: refactor this function, it's too large and complicated now // TODO: refactor this function, it's too large and complicated now
// escape all single and double quotes inside strings // escape all single and double quotes inside strings
@ -278,13 +278,19 @@ exports.repair = jsString => {
* @param {string} text * @param {string} text
* @return {string} * @return {string}
*/ */
exports.escapeUnicodeChars = text => // see https://www.wikiwand.com/en/UTF-16 export function escapeUnicodeChars(
// see https://www.wikiwand.com/en/UTF-16
text
) {
return (
// note: we leave surrogate pairs as two individual chars, // note: we leave surrogate pairs as two individual chars,
// as JSON doesn't interpret them as a single unicode char. // as JSON doesn't interpret them as a single unicode char.
text.replace( text.replace(
/[\u007F-\uFFFF]/g, /[\u007F-\uFFFF]/g,
c => '\\u' + ('0000' + c.charCodeAt(0).toString(16)).slice(-4) c => '\\u' + ('0000' + c.charCodeAt(0).toString(16)).slice(-4)
) )
);
}
/** /**
* Validate a string containing a JSON object * Validate a string containing a JSON object
@ -293,7 +299,7 @@ exports.escapeUnicodeChars = text => // see https://www.wikiwand.com/en/UTF-16
* @param {String} jsonString String with an (invalid) JSON object * @param {String} jsonString String with an (invalid) JSON object
* @throws Error * @throws Error
*/ */
exports.validate = function validate (jsonString) { export function validate(jsonString) {
if (typeof (jsonlint) !== 'undefined') { if (typeof (jsonlint) !== 'undefined') {
jsonlint.parse(jsonString) jsonlint.parse(jsonString)
} else { } else {
@ -307,7 +313,7 @@ exports.validate = function validate (jsonString) {
* @param {Object} b * @param {Object} b
* @return {Object} a * @return {Object} a
*/ */
exports.extend = function extend (a, b) { export function extend(a, b) {
for (const prop in b) { for (const prop in b) {
if (hasOwnProperty(b, prop)) { if (hasOwnProperty(b, prop)) {
a[prop] = b[prop] a[prop] = b[prop]
@ -321,7 +327,7 @@ exports.extend = function extend (a, b) {
* @param {Object} a * @param {Object} a
* @return {Object} a * @return {Object} a
*/ */
exports.clear = function clear (a) { export function clear(a) {
for (const prop in a) { for (const prop in a) {
if (hasOwnProperty(a, prop)) { if (hasOwnProperty(a, prop)) {
delete a[prop] delete a[prop]
@ -335,7 +341,7 @@ exports.clear = function clear (a) {
* @param {*} object * @param {*} object
* @return {String} type * @return {String} type
*/ */
exports.type = function type (object) { export function type(object) {
if (object === null) { if (object === null) {
return 'null' return 'null'
} }
@ -354,7 +360,7 @@ exports.type = function type (object) {
if (object instanceof RegExp) { if (object instanceof RegExp) {
return 'regexp' return 'regexp'
} }
if (exports.isArray(object)) { if (isArray(object)) {
return 'array' return 'array'
} }
@ -367,7 +373,8 @@ exports.type = function type (object) {
* @param {String} text * @param {String} text
*/ */
const isUrlRegex = /^https?:\/\/\S+$/ const isUrlRegex = /^https?:\/\/\S+$/
exports.isUrl = function isUrl (text) {
export function isUrl(text) {
return (typeof text === 'string' || text instanceof String) && return (typeof text === 'string' || text instanceof String) &&
isUrlRegex.test(text) isUrlRegex.test(text)
} }
@ -377,7 +384,9 @@ exports.isUrl = function isUrl (text) {
* @param {*} obj * @param {*} obj
* @returns {boolean} returns true when obj is an array * @returns {boolean} returns true when obj is an array
*/ */
exports.isArray = obj => Object.prototype.toString.call(obj) === '[object Array]' export function isArray(obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
}
/** /**
* Retrieve the absolute left value of a DOM element * Retrieve the absolute left value of a DOM element
@ -385,7 +394,7 @@ exports.isArray = obj => Object.prototype.toString.call(obj) === '[object Array]
* @return {Number} left The absolute left position of this element * @return {Number} left The absolute left position of this element
* in the browser page. * in the browser page.
*/ */
exports.getAbsoluteLeft = function getAbsoluteLeft (elem) { export function getAbsoluteLeft(elem) {
const rect = elem.getBoundingClientRect() const rect = elem.getBoundingClientRect()
return rect.left + window.pageXOffset || document.scrollLeft || 0 return rect.left + window.pageXOffset || document.scrollLeft || 0
} }
@ -396,7 +405,7 @@ exports.getAbsoluteLeft = function getAbsoluteLeft (elem) {
* @return {Number} top The absolute top position of this element * @return {Number} top The absolute top position of this element
* in the browser page. * in the browser page.
*/ */
exports.getAbsoluteTop = function getAbsoluteTop (elem) { export function getAbsoluteTop(elem) {
const rect = elem.getBoundingClientRect() const rect = elem.getBoundingClientRect()
return rect.top + window.pageYOffset || document.scrollTop || 0 return rect.top + window.pageYOffset || document.scrollTop || 0
} }
@ -406,7 +415,7 @@ exports.getAbsoluteTop = function getAbsoluteTop (elem) {
* @param {Element} elem * @param {Element} elem
* @param {String} className * @param {String} className
*/ */
exports.addClassName = function addClassName (elem, className) { export function addClassName(elem, className) {
const classes = elem.className.split(' ') const classes = elem.className.split(' ')
if (classes.indexOf(className) === -1) { if (classes.indexOf(className) === -1) {
classes.push(className) // add the class to the array classes.push(className) // add the class to the array
@ -418,7 +427,7 @@ exports.addClassName = function addClassName (elem, className) {
* remove all classes from the given elements style * remove all classes from the given elements style
* @param {Element} elem * @param {Element} elem
*/ */
exports.removeAllClassNames = function removeAllClassNames (elem) { export function removeAllClassNames(elem) {
elem.className = '' elem.className = ''
} }
@ -427,7 +436,7 @@ exports.removeAllClassNames = function removeAllClassNames (elem) {
* @param {Element} elem * @param {Element} elem
* @param {String} className * @param {String} className
*/ */
exports.removeClassName = function removeClassName (elem, className) { export function removeClassName(elem, className) {
const classes = elem.className.split(' ') const classes = elem.className.split(' ')
const index = classes.indexOf(className) const index = classes.indexOf(className)
if (index !== -1) { if (index !== -1) {
@ -441,7 +450,7 @@ exports.removeClassName = function removeClassName (elem, className) {
* the formatting from the div itself is not stripped, only from its childs. * the formatting from the div itself is not stripped, only from its childs.
* @param {Element} divElement * @param {Element} divElement
*/ */
exports.stripFormatting = function stripFormatting (divElement) { export function stripFormatting(divElement) {
const childs = divElement.childNodes const childs = divElement.childNodes
for (let i = 0, iMax = childs.length; i < iMax; i++) { for (let i = 0, iMax = childs.length; i < iMax; i++) {
const child = childs[i] const child = childs[i]
@ -464,7 +473,7 @@ exports.stripFormatting = function stripFormatting (divElement) {
} }
// recursively strip childs // recursively strip childs
exports.stripFormatting(child) stripFormatting(child)
} }
} }
@ -475,7 +484,7 @@ exports.stripFormatting = function stripFormatting (divElement) {
* http://stackoverflow.com/questions/1125292/how-to-move-cursor-to-end-of-contenteditable-entity * http://stackoverflow.com/questions/1125292/how-to-move-cursor-to-end-of-contenteditable-entity
* @param {Element} contentEditableElement A content editable div * @param {Element} contentEditableElement A content editable div
*/ */
exports.setEndOfContentEditable = function setEndOfContentEditable (contentEditableElement) { export function setEndOfContentEditable(contentEditableElement) {
let range, selection let range, selection
if (document.createRange) { if (document.createRange) {
range = document.createRange()// Create a range (a range is a like the selection but invisible) range = document.createRange()// Create a range (a range is a like the selection but invisible)
@ -492,7 +501,7 @@ exports.setEndOfContentEditable = function setEndOfContentEditable (contentEdita
* http://stackoverflow.com/a/3806004/1262753 * http://stackoverflow.com/a/3806004/1262753
* @param {Element} contentEditableElement A content editable div * @param {Element} contentEditableElement A content editable div
*/ */
exports.selectContentEditable = function selectContentEditable (contentEditableElement) { export function selectContentEditable(contentEditableElement) {
if (!contentEditableElement || contentEditableElement.nodeName !== 'DIV') { if (!contentEditableElement || contentEditableElement.nodeName !== 'DIV') {
return return
} }
@ -512,7 +521,7 @@ exports.selectContentEditable = function selectContentEditable (contentEditableE
* http://stackoverflow.com/questions/4687808/contenteditable-selected-text-save-and-restore * http://stackoverflow.com/questions/4687808/contenteditable-selected-text-save-and-restore
* @return {Range | TextRange | null} range * @return {Range | TextRange | null} range
*/ */
exports.getSelection = function getSelection () { export function getSelection() {
if (window.getSelection) { if (window.getSelection) {
const sel = window.getSelection() const sel = window.getSelection()
if (sel.getRangeAt && sel.rangeCount) { if (sel.getRangeAt && sel.rangeCount) {
@ -527,7 +536,7 @@ exports.getSelection = function getSelection () {
* http://stackoverflow.com/questions/4687808/contenteditable-selected-text-save-and-restore * http://stackoverflow.com/questions/4687808/contenteditable-selected-text-save-and-restore
* @param {Range | TextRange | null} range * @param {Range | TextRange | null} range
*/ */
exports.setSelection = function setSelection (range) { export function setSelection(range) {
if (range) { if (range) {
if (window.getSelection) { if (window.getSelection) {
const sel = window.getSelection() const sel = window.getSelection()
@ -546,8 +555,8 @@ exports.setSelection = function setSelection (range) {
* selected text element * selected text element
* Returns null if no text selection is found * Returns null if no text selection is found
*/ */
exports.getSelectionOffset = function getSelectionOffset () { export function getSelectionOffset() {
const range = exports.getSelection() const range = getSelection()
if (range && 'startOffset' in range && 'endOffset' in range && if (range && 'startOffset' in range && 'endOffset' in range &&
range.startContainer && (range.startContainer === range.endContainer)) { range.startContainer && (range.startContainer === range.endContainer)) {
@ -568,7 +577,7 @@ exports.getSelectionOffset = function getSelectionOffset () {
* {Number} startOffset * {Number} startOffset
* {Number} endOffset * {Number} endOffset
*/ */
exports.setSelectionOffset = function setSelectionOffset (params) { export function setSelectionOffset(params) {
if (document.createRange && window.getSelection) { if (document.createRange && window.getSelection) {
const selection = window.getSelection() const selection = window.getSelection()
if (selection) { if (selection) {
@ -583,7 +592,7 @@ exports.setSelectionOffset = function setSelectionOffset (params) {
range.setStart(params.container.firstChild, params.startOffset) range.setStart(params.container.firstChild, params.startOffset)
range.setEnd(params.container.firstChild, params.endOffset) range.setEnd(params.container.firstChild, params.endOffset)
exports.setSelection(range) setSelection(range)
} }
} }
} }
@ -594,7 +603,7 @@ exports.setSelectionOffset = function setSelectionOffset (params) {
* @param {Object} [buffer] * @param {Object} [buffer]
* @return {String} innerText * @return {String} innerText
*/ */
exports.getInnerText = function getInnerText (element, buffer) { export function getInnerText(element, buffer) {
const first = (buffer === undefined) const first = (buffer === undefined)
if (first) { if (first) {
buffer = { buffer = {
@ -630,19 +639,19 @@ exports.getInnerText = function getInnerText (element, buffer) {
innerText += '\n' innerText += '\n'
buffer.flush() buffer.flush()
} }
innerText += exports.getInnerText(child, buffer) innerText += getInnerText(child, buffer)
buffer.set('\n') buffer.set('\n')
} else if (child.nodeName === 'BR') { } else if (child.nodeName === 'BR') {
innerText += buffer.flush() innerText += buffer.flush()
buffer.set('\n') buffer.set('\n')
} else { } else {
innerText += exports.getInnerText(child, buffer) innerText += getInnerText(child, buffer)
} }
} }
return innerText return innerText
} else { } else {
if (element.nodeName === 'P' && exports.getInternetExplorerVersion() !== -1) { if (element.nodeName === 'P' && getInternetExplorerVersion() !== -1) {
// On Internet Explorer, a <p> with hasChildNodes()==false is // On Internet Explorer, a <p> with hasChildNodes()==false is
// rendered with a new line. Note that a <p> with // rendered with a new line. Note that a <p> with
// hasChildNodes()==true is rendered without a new line // hasChildNodes()==true is rendered without a new line
@ -662,7 +671,7 @@ exports.getInnerText = function getInnerText (element, buffer) {
* @param {Element} parent * @param {Element} parent
* @return {boolean} * @return {boolean}
*/ */
exports.hasParentNode = (elem, parent) => { export function hasParentNode(elem, parent) {
let e = elem ? elem.parentNode : undefined let e = elem ? elem.parentNode : undefined
while (e) { while (e) {
@ -681,7 +690,7 @@ exports.hasParentNode = (elem, parent) => {
* Source: http://msdn.microsoft.com/en-us/library/ms537509(v=vs.85).aspx * Source: http://msdn.microsoft.com/en-us/library/ms537509(v=vs.85).aspx
* @return {Number} Internet Explorer version, or -1 in case of an other browser * @return {Number} Internet Explorer version, or -1 in case of an other browser
*/ */
exports.getInternetExplorerVersion = function getInternetExplorerVersion () { export function getInternetExplorerVersion() {
if (_ieVersion === -1) { if (_ieVersion === -1) {
let rv = -1 // Return value assumes failure. let rv = -1 // Return value assumes failure.
if (typeof navigator !== 'undefined' && navigator.appName === 'Microsoft Internet Explorer') { if (typeof navigator !== 'undefined' && navigator.appName === 'Microsoft Internet Explorer') {
@ -702,7 +711,7 @@ exports.getInternetExplorerVersion = function getInternetExplorerVersion () {
* Test whether the current browser is Firefox * Test whether the current browser is Firefox
* @returns {boolean} isFirefox * @returns {boolean} isFirefox
*/ */
exports.isFirefox = function isFirefox () { export function isFirefox() {
return (typeof navigator !== 'undefined' && navigator.userAgent.indexOf('Firefox') !== -1) return (typeof navigator !== 'undefined' && navigator.userAgent.indexOf('Firefox') !== -1)
} }
@ -722,11 +731,11 @@ var _ieVersion = -1
* @param {boolean} [useCapture] false by default * @param {boolean} [useCapture] false by default
* @return {function} the created event listener * @return {function} the created event listener
*/ */
exports.addEventListener = function addEventListener (element, action, listener, useCapture) { export function addEventListener(element, action, listener, useCapture) {
if (element.addEventListener) { if (element.addEventListener) {
if (useCapture === undefined) { useCapture = false } if (useCapture === undefined) { useCapture = false }
if (action === 'mousewheel' && exports.isFirefox()) { if (action === 'mousewheel' && isFirefox()) {
action = 'DOMMouseScroll' // For Firefox action = 'DOMMouseScroll' // For Firefox
} }
@ -747,11 +756,11 @@ exports.addEventListener = function addEventListener (element, action, listener,
* @param {function} listener The listener function * @param {function} listener The listener function
* @param {boolean} [useCapture] false by default * @param {boolean} [useCapture] false by default
*/ */
exports.removeEventListener = function removeEventListener (element, action, listener, useCapture) { export function removeEventListener(element, action, listener, useCapture) {
if (element.removeEventListener) { if (element.removeEventListener) {
if (useCapture === undefined) { useCapture = false } if (useCapture === undefined) { useCapture = false }
if (action === 'mousewheel' && exports.isFirefox()) { if (action === 'mousewheel' && isFirefox()) {
action = 'DOMMouseScroll' // For Firefox action = 'DOMMouseScroll' // For Firefox
} }
@ -768,7 +777,7 @@ exports.removeEventListener = function removeEventListener (element, action, lis
* @param {Element} parent * @param {Element} parent
* @return {boolean} returns true if elem is a child of the parent * @return {boolean} returns true if elem is a child of the parent
*/ */
exports.isChildOf = (elem, parent) => { export function isChildOf(elem, parent) {
let e = elem.parentNode let e = elem.parentNode
while (e) { while (e) {
if (e === parent) { if (e === parent) {
@ -785,7 +794,7 @@ exports.isChildOf = (elem, parent) => {
* @param {string} jsonPath * @param {string} jsonPath
* @return {Array} * @return {Array}
*/ */
exports.parsePath = function parsePath (jsonPath) { export function parsePath(jsonPath) {
const path = [] const path = []
let i = 0 let i = 0
@ -861,7 +870,7 @@ exports.parsePath = function parsePath (jsonPath) {
* @param {Array.<string | number>} path * @param {Array.<string | number>} path
* @returns {string} * @returns {string}
*/ */
exports.stringifyPath = function stringifyPath (path) { export function stringifyPath(path) {
return path return path
.map(p => { .map(p => {
if (typeof p === 'number') { if (typeof p === 'number') {
@ -880,7 +889,7 @@ exports.stringifyPath = function stringifyPath (path) {
* @param {Object} error * @param {Object} error
* @return {Object} The error * @return {Object} The error
*/ */
exports.improveSchemaError = error => { export function improveSchemaError(error) {
if (error.keyword === 'enum' && Array.isArray(error.schema)) { if (error.keyword === 'enum' && Array.isArray(error.schema)) {
let enums = error.schema let enums = error.schema
if (enums) { if (enums) {
@ -907,16 +916,20 @@ exports.improveSchemaError = error => {
* @param {*} object * @param {*} object
* @returns {boolean} Returns true when object is a promise, false otherwise * @returns {boolean} Returns true when object is a promise, false otherwise
*/ */
exports.isPromise = object => object && typeof object.then === 'function' && typeof object.catch === 'function' export function isPromise(object) {
return object && typeof object.then === 'function' && typeof object.catch === 'function';
}
/** /**
* Test whether a custom validation error has the correct structure * Test whether a custom validation error has the correct structure
* @param {*} validationError The error to be checked. * @param {*} validationError The error to be checked.
* @returns {boolean} Returns true if the structure is ok, false otherwise * @returns {boolean} Returns true if the structure is ok, false otherwise
*/ */
exports.isValidValidationError = validationError => typeof validationError === 'object' && export function isValidValidationError(validationError) {
return typeof validationError === 'object' &&
Array.isArray(validationError.path) && Array.isArray(validationError.path) &&
typeof validationError.message === 'string' typeof validationError.message === 'string';
}
/** /**
* Test whether the child rect fits completely inside the parent rect. * Test whether the child rect fits completely inside the parent rect.
@ -924,7 +937,7 @@ exports.isValidValidationError = validationError => typeof validationError === '
* @param {ClientRect} child * @param {ClientRect} child
* @param {number} margin * @param {number} margin
*/ */
exports.insideRect = (parent, child, margin) => { export function insideRect(parent, child, margin) {
const _margin = margin !== undefined ? margin : 0 const _margin = margin !== undefined ? margin : 0
return child.left - _margin >= parent.left && return child.left - _margin >= parent.left &&
child.right + _margin <= parent.right && child.right + _margin <= parent.right &&
@ -946,7 +959,7 @@ exports.insideRect = (parent, child, margin) => {
* of the trailing. * of the trailing.
* @return {function} Return the debounced function * @return {function} Return the debounced function
*/ */
exports.debounce = function debounce (func, wait, immediate) { export function debounce(func, wait, immediate) {
let timeout let timeout
return function () { return function () {
const context = this; const args = arguments const context = this; const args = arguments
@ -969,7 +982,7 @@ exports.debounce = function debounce (func, wait, immediate) {
* @return {{start: number, end: number}} Returns the start and end * @return {{start: number, end: number}} Returns the start and end
* of the changed part in newText. * of the changed part in newText.
*/ */
exports.textDiff = function textDiff (oldText, newText) { export function textDiff(oldText, newText) {
const len = newText.length const len = newText.length
let start = 0 let start = 0
let oldEnd = oldText.length let oldEnd = oldText.length
@ -996,7 +1009,7 @@ exports.textDiff = function textDiff (oldText, newText) {
* @param {DOMElement} el A dom element of a textarea or input text. * @param {DOMElement} el A dom element of a textarea or input text.
* @return {Object} reference Object with 2 properties (start and end) with the identifier of the location of the cursor and selected text. * @return {Object} reference Object with 2 properties (start and end) with the identifier of the location of the cursor and selected text.
**/ **/
exports.getInputSelection = el => { export function getInputSelection(el) {
let startIndex = 0; let endIndex = 0; let normalizedValue; let range; let textInputRange; let len; let endRange let startIndex = 0; let endIndex = 0; let normalizedValue; let range; let textInputRange; let len; let endRange
if (typeof el.selectionStart === 'number' && typeof el.selectionEnd === 'number') { if (typeof el.selectionStart === 'number' && typeof el.selectionEnd === 'number') {
@ -1066,7 +1079,7 @@ exports.getInputSelection = el => {
* @param {Number} column column value, > 0, if exceeds column length - end of column will be returned * @param {Number} column column value, > 0, if exceeds column length - end of column will be returned
* @returns {Number} index of position in text, -1 if not found * @returns {Number} index of position in text, -1 if not found
*/ */
exports.getIndexForPosition = (el, row, column) => { export function getIndexForPosition(el, row, column) {
const text = el.value || '' const text = el.value || ''
if (row > 0 && column > 0) { if (row > 0 && column > 0) {
const rows = text.split('\n', row) const rows = text.split('\n', row)
@ -1084,7 +1097,7 @@ exports.getIndexForPosition = (el, row, column) => {
* @param {Array<String>} paths array of json paths * @param {Array<String>} paths array of json paths
* @returns {Array<{path: String, line: Number, row: Number}>} * @returns {Array<{path: String, line: Number, row: Number}>}
*/ */
exports.getPositionForPath = function (text, paths) { export function getPositionForPath(text, paths) {
const me = this const me = this
const result = [] const result = []
let jsmap let jsmap
@ -1100,7 +1113,7 @@ exports.getPositionForPath = function (text, paths) {
paths.forEach(path => { paths.forEach(path => {
const pathArr = me.parsePath(path) const pathArr = me.parsePath(path)
const pointerName = exports.compileJSONPointer(pathArr) const pointerName = compileJSONPointer(pathArr)
const pointer = jsmap.pointers[pointerName] const pointer = jsmap.pointers[pointerName]
if (pointer) { if (pointer) {
result.push({ result.push({
@ -1120,12 +1133,14 @@ exports.getPositionForPath = function (text, paths) {
* @param {Array.<string | number>} path * @param {Array.<string | number>} path
* @return {string} * @return {string}
*/ */
exports.compileJSONPointer = path => path export function compileJSONPointer(path) {
return path
.map(p => ('/' + String(p) .map(p => ('/' + String(p)
.replace(/~/g, '~0') .replace(/~/g, '~0')
.replace(/\//g, '~1') .replace(/\//g, '~1')
)) ))
.join('') .join('');
}
/** /**
* Get the applied color given a color name or code * Get the applied color given a color name or code
@ -1135,7 +1150,7 @@ exports.compileJSONPointer = path => path
* color, and returns null otherwise. Example output: * color, and returns null otherwise. Example output:
* 'rgba(255,0,0,0.7)' or 'rgb(255,0,0)' * 'rgba(255,0,0,0.7)' or 'rgb(255,0,0)'
*/ */
exports.getColorCSS = color => { export function getColorCSS(color) {
const ele = document.createElement('div') const ele = document.createElement('div')
ele.style.color = color ele.style.color = color
return ele.style.color.split(/\s+/).join('').toLowerCase() || null return ele.style.color.split(/\s+/).join('').toLowerCase() || null
@ -1146,7 +1161,9 @@ exports.getColorCSS = color => {
* @param {string} color * @param {string} color
* @returns {boolean} returns true if a valid color, false otherwise * @returns {boolean} returns true if a valid color, false otherwise
*/ */
exports.isValidColor = color => !!exports.getColorCSS(color) export function isValidColor(color) {
return !!getColorCSS(color);
}
/** /**
* Make a tooltip for a field based on the field's schema. * Make a tooltip for a field based on the field's schema.
@ -1154,7 +1171,7 @@ exports.isValidColor = color => !!exports.getColorCSS(color)
* @param {string} [locale] Locale code (for example, zh-CN) * @param {string} [locale] Locale code (for example, zh-CN)
* @returns {string} Field tooltip, may be empty string if all relevant schema properties are missing * @returns {string} Field tooltip, may be empty string if all relevant schema properties are missing
*/ */
exports.makeFieldTooltip = (schema, locale) => { export function makeFieldTooltip(schema, locale) {
if (!schema) { if (!schema) {
return '' return ''
} }
@ -1202,7 +1219,7 @@ exports.makeFieldTooltip = (schema, locale) => {
* @param {string[]} path * @param {string[]} path
* @return {*} * @return {*}
*/ */
exports.get = (object, path) => { export function get(object, path) {
let value = object let value = object
for (let i = 0; i < path.length && value !== undefined && value !== null; i++) { for (let i = 0; i < path.length && value !== undefined && value !== null; i++) {
@ -1218,7 +1235,7 @@ exports.get = (object, path) => {
* @param {string} name * @param {string} name
* @param {Array} existingPropNames Array with existing prop names * @param {Array} existingPropNames Array with existing prop names
*/ */
exports.findUniqueName = (name, existingPropNames) => { export function findUniqueName(name, existingPropNames) {
const strippedName = name.replace(/ \(copy( \d+)?\)$/, '') const strippedName = name.replace(/ \(copy( \d+)?\)$/, '')
let validName = strippedName let validName = strippedName
let i = 1 let i = 1
@ -1238,17 +1255,17 @@ exports.findUniqueName = (name, existingPropNames) => {
* @param {boolean} [includeObjects=false] If true, object and array paths are returned as well * @param {boolean} [includeObjects=false] If true, object and array paths are returned as well
* @return {string[]} * @return {string[]}
*/ */
exports.getChildPaths = (json, includeObjects) => { export function getChildPaths(json, includeObjects) {
const pathsMap = {} const pathsMap = {}
function getObjectChildPaths (json, pathsMap, rootPath, includeObjects) { function getObjectChildPaths (json, pathsMap, rootPath, includeObjects) {
const isValue = !Array.isArray(json) && !exports.isObject(json) const isValue = !Array.isArray(json) && !isObject(json)
if (isValue || includeObjects) { if (isValue || includeObjects) {
pathsMap[rootPath || ''] = true pathsMap[rootPath || ''] = true
} }
if (exports.isObject(json)) { if (isObject(json)) {
Object.keys(json).forEach(field => { Object.keys(json).forEach(field => {
getObjectChildPaths(json[field], pathsMap, rootPath + '.' + field, includeObjects) getObjectChildPaths(json[field], pathsMap, rootPath + '.' + field, includeObjects)
}) })
@ -1274,14 +1291,14 @@ exports.getChildPaths = (json, includeObjects) => {
* @param {String} [path] JSON pointer * @param {String} [path] JSON pointer
* @param {'asc' | 'desc'} [direction] * @param {'asc' | 'desc'} [direction]
*/ */
exports.sort = (array, path, direction) => { export function sort(array, path, direction) {
const parsedPath = path && path !== '.' ? exports.parsePath(path) : [] const parsedPath = path && path !== '.' ? parsePath(path) : []
const sign = direction === 'desc' ? -1 : 1 const sign = direction === 'desc' ? -1 : 1
const sortedArray = array.slice() const sortedArray = array.slice()
sortedArray.sort((a, b) => { sortedArray.sort((a, b) => {
const aValue = exports.get(a, parsedPath) const aValue = get(a, parsedPath)
const bValue = exports.get(b, parsedPath) const bValue = get(b, parsedPath)
return sign * (aValue > bValue ? 1 : aValue < bValue ? -1 : 0) return sign * (aValue > bValue ? 1 : aValue < bValue ? -1 : 0)
}) })
@ -1294,7 +1311,7 @@ exports.sort = (array, path, direction) => {
* @param {Object} object * @param {Object} object
* @param {'asc' | 'desc'} [direction] * @param {'asc' | 'desc'} [direction]
*/ */
exports.sortObjectKeys = (object, direction) => { export function sortObjectKeys(object, direction) {
const sign = (direction === 'desc') ? -1 : 1 const sign = (direction === 'desc') ? -1 : 1
const sortedFields = Object.keys(object).sort((a, b) => sign * naturalSort(a, b)) const sortedFields = Object.keys(object).sort((a, b) => sign * naturalSort(a, b))
@ -1313,7 +1330,7 @@ exports.sortObjectKeys = (object, direction) => {
* @return {*} castedStr * @return {*} castedStr
* @private * @private
*/ */
exports.parseString = str => { export function parseString(str) {
const lower = str.toLowerCase() const lower = str.toLowerCase()
const num = Number(str) // will nicely fail with '123ab' const num = Number(str) // will nicely fail with '123ab'
const numFloat = parseFloat(str) // will nicely fail with ' ' const numFloat = parseFloat(str) // will nicely fail with ' '
@ -1339,7 +1356,7 @@ exports.parseString = str => {
* @param {number} size * @param {number} size
* @return {string} Returns a human readable size * @return {string} Returns a human readable size
*/ */
exports.formatSize = size => { export function formatSize(size) {
if (size < 900) { if (size < 900) {
return size.toFixed() + ' B' return size.toFixed() + ' B'
} }
@ -1370,7 +1387,7 @@ exports.formatSize = size => {
* @return {string} Returns the limited text, * @return {string} Returns the limited text,
* ending with '...' if the max was exceeded * ending with '...' if the max was exceeded
*/ */
exports.limitCharacters = (text, maxCharacterCount) => { export function limitCharacters(text, maxCharacterCount) {
if (text.length <= maxCharacterCount) { if (text.length <= maxCharacterCount) {
return text return text
} }
@ -1383,7 +1400,9 @@ exports.limitCharacters = (text, maxCharacterCount) => {
* @param {*} value * @param {*} value
* @return {boolean} * @return {boolean}
*/ */
exports.isObject = value => typeof value === 'object' && value !== null && !Array.isArray(value) export function isObject(value) {
return typeof value === 'object' && value !== null && !Array.isArray(value);
}
/** /**
* Helper function to test whether an array contains an item * Helper function to test whether an array contains an item
@ -1391,7 +1410,9 @@ exports.isObject = value => typeof value === 'object' && value !== null && !Arra
* @param {*} item * @param {*} item
* @return {boolean} Returns true if `item` is in `array`, returns false otherwise. * @return {boolean} Returns true if `item` is in `array`, returns false otherwise.
*/ */
exports.contains = (array, item) => array.indexOf(item) !== -1 export function contains(array, item) {
return array.indexOf(item) !== -1;
}
function hasOwnProperty (object, key) { function hasOwnProperty (object, key) {
return Object.prototype.hasOwnProperty.call(object, key) return Object.prototype.hasOwnProperty.call(object, key)

View File

@ -1,13 +1,13 @@
const isPromise = require('./util').isPromise import {isPromise} from './util';
const isValidValidationError = require('./util').isValidValidationError import {isValidValidationError} from './util';
const stringifyPath = require('./util').stringifyPath import {stringifyPath} from './util';
/** /**
* Execute custom validation if configured. * Execute custom validation if configured.
* *
* Returns a promise resolving with the custom errors (or an empty array). * Returns a promise resolving with the custom errors (or an empty array).
*/ */
function validateCustom (json, onValidate) { export function validateCustom (json, onValidate) {
if (!onValidate) { if (!onValidate) {
return Promise.resolve([]) return Promise.resolve([])
} }
@ -46,5 +46,3 @@ function validateCustom (json, onValidate) {
return Promise.reject(err) return Promise.reject(err)
} }
} }
exports.validateCustom = validateCustom