This commit is contained in:
jos 2017-12-17 21:52:21 +01:00
parent aee48b75db
commit 34ca56aee0
6 changed files with 27 additions and 65 deletions

View File

@ -10,7 +10,7 @@ import { getInnerText, insideRect, findParentWithAttribute } from '../utils/domU
import { stringConvert, valueType, isUrl } from '../utils/typeUtils' import { stringConvert, valueType, isUrl } from '../utils/typeUtils'
import { compileJSONPointer, META, SELECTED, SELECTED_END, SELECTED_AFTER, SELECTED_BEFORE } from '../eson' import { compileJSONPointer, META, SELECTED, SELECTED_END, SELECTED_AFTER, SELECTED_BEFORE } from '../eson'
import type { ESONObjectProperty, ESON, SearchResultStatus, Path } from '../types' import type { ESON, SearchResultStatus, Path } from '../types'
// TODO: rename SELECTED, SELECTED_END, etc to AREA_*? It's used for both selection and hovering // TODO: rename SELECTED, SELECTED_END, etc to AREA_*? It's used for both selection and hovering
const SELECTED_CLASS_NAMES = { const SELECTED_CLASS_NAMES = {

View File

@ -2,7 +2,7 @@
import JSONNode from './JSONNode' import JSONNode from './JSONNode'
import type { ESONObjectProperty, ESON, Path } from '../types' import type { ESON, Path } from '../types'
/** /**
* JSONNodeForm * JSONNodeForm
@ -22,7 +22,7 @@ export default class JSONNodeForm extends JSONNode {
} }
// render a readonly property // render a readonly property
renderProperty (prop?: ESONObjectProperty, index?: number, data: ESON, options: {escapeUnicode: boolean, isPropertyEditable: (Path) => boolean}) { renderProperty (prop?: String, index?: number, eson: ESON, options: {escapeUnicode: boolean, isPropertyEditable: (Path) => boolean}) {
const formOptions = Object.assign({}, options, { isPropertyEditable }) const formOptions = Object.assign({}, options, { isPropertyEditable })
return JSONNode.prototype.renderProperty.call(this, prop, index, data, formOptions) return JSONNode.prototype.renderProperty.call(this, prop, index, data, formOptions)

View File

@ -36,7 +36,10 @@ import {
import { createFindKeyBinding } from '../utils/keyBindings' import { createFindKeyBinding } from '../utils/keyBindings'
import { KEY_BINDINGS } from '../constants' import { KEY_BINDINGS } from '../constants'
import type { ESON, ESONPatch, JSONPath, Selection, ESONPointer } from '../types' import type {
ESON, ESONPatch, Selection, ESONPointer,
Path
} from '../types'
const AJV_OPTIONS = { const AJV_OPTIONS = {
allErrors: true, allErrors: true,
@ -707,7 +710,7 @@ export default class TreeMode extends Component {
} }
} }
findDataPathFromElement (element: Element) : JSONPath | null { findDataPathFromElement (element: Element) : Path | null {
const base = findBaseNode(element) const base = findBaseNode(element)
const attr = base && base.getAttribute && base.getAttribute('data-path') const attr = base && base.getAttribute && base.getAttribute('data-path')

View File

@ -17,7 +17,7 @@ import last from 'lodash/last'
import type { import type {
ESON, ESONPointer, Selection, ESON, ESONPointer, Selection,
Path, Path,
JSONPath, JSONType JSONType
} from './types' } from './types'
export const SELECTED = 1 export const SELECTED = 1
@ -447,7 +447,7 @@ export function findSelectionIndices (root, rootPath, selection) {
/** /**
* Get the JSON paths from a selection, sorted from first to last * Get the JSON paths from a selection, sorted from first to last
*/ */
export function pathsFromSelection (eson, selection: Selection): JSONPath[] { export function pathsFromSelection (eson, selection: Selection): Path[] {
// find the parent node shared by both start and end of the selection // find the parent node shared by both start and end of the selection
const rootPath = findRootPath(selection) const rootPath = findRootPath(selection)
const root = getIn(eson, rootPath) const root = getIn(eson, rootPath)
@ -465,10 +465,10 @@ export function pathsFromSelection (eson, selection: Selection): JSONPath[] {
/** /**
* Get the contents of a list with paths * Get the contents of a list with paths
* @param {ESON} data * @param {ESON} data
* @param {JSONPath[]} paths * @param {Path[]} paths
* @return {Array.<{name: string, value: JSONType}>} * @return {Array.<{name: string, value: JSONType}>}
*/ */
export function contentsFromPaths (data: ESON, paths: JSONPath[]) { export function contentsFromPaths (data: ESON, paths: Path[]) {
return paths.map(path => { return paths.map(path => {
return { return {
name: last(path), name: last(path),
@ -482,7 +482,7 @@ export function contentsFromPaths (data: ESON, paths: JSONPath[]) {
* Find the root path of a selection: the parent node shared by both start * Find the root path of a selection: the parent node shared by both start
* and end of the selection * and end of the selection
* @param {Selection} selection * @param {Selection} selection
* @return {JSONPath} * @return {Path}
*/ */
export function findRootPath(selection) { export function findRootPath(selection) {
if (selection.before) { if (selection.before) {
@ -509,7 +509,7 @@ export function findRootPath(selection) {
* Find the common path of two paths. * Find the common path of two paths.
* For example findCommonRoot(['arr', '1', 'name'], ['arr', '1', 'address', 'contact']) returns ['arr', '1'] * For example findCommonRoot(['arr', '1', 'name'], ['arr', '1', 'address', 'contact']) returns ['arr', '1']
*/ */
function findSharedPath (path1: JSONPath, path2: JSONPath): JSONPath { function findSharedPath (path1: Path, path2: Path): Path {
let i = 0; let i = 0;
while (i < path1.length && path1[i] === path2[i]) { while (i < path1.length && path1[i] === path2[i]) {
i++; i++;
@ -616,16 +616,6 @@ export function containsCaseInsensitive (text: string, search: string): boolean
return String(text).toLowerCase().indexOf(search.toLowerCase()) !== -1 return String(text).toLowerCase().indexOf(search.toLowerCase()) !== -1
} }
/**
* Test whether an array contains a specific item
* @param {Array} array
* @param {*} item
* @return {boolean} Returnts true when item is in array, false otherwise.
*/
function contains (array, item) {
return array.indexOf(item) !== -1
}
/** /**
* Get a new "unique" id. Id's are created from an incremental counter. * Get a new "unique" id. Id's are created from an incremental counter.
* @return {number} * @return {number}

View File

@ -162,7 +162,6 @@ export function replace (data, path, value) {
* @param {Path} path * @param {Path} path
* @return {{data: ESON, revert: ESONPatch}} * @return {{data: ESON, revert: ESONPatch}}
*/ */
// FIXME: path should be a path instead of a string? (all functions in patchEson)
export function remove (data, path) { export function remove (data, path) {
// console.log('remove', path) // console.log('remove', path)
@ -215,9 +214,7 @@ export function remove (data, path) {
* @return {{data: ESON, revert: ESONPatch}} * @return {{data: ESON, revert: ESONPatch}}
* @private * @private
*/ */
// TODO: refactor path to an array with strings
export function add (data, path, value, options) { export function add (data, path, value, options) {
// FIXME: apply id to new created values
const parentPath = initial(path) const parentPath = initial(path)
const parent = getIn(data, parentPath) const parent = getIn(data, parentPath)
const resolvedPath = resolvePathIndex(data, path) const resolvedPath = resolvePathIndex(data, path)
@ -312,7 +309,6 @@ export function move (data, path, from, options) {
const result1 = remove(data, from) const result1 = remove(data, from)
const result2 = add(result1.data, path, dataValue, options) const result2 = add(result1.data, path, dataValue, options)
// FIXME: passing id as parameter is ugly, make that redundant (use replace instead of remove/add? (that would give less predictive output :( ))
const before = result1.revert[0].meta.before const before = result1.revert[0].meta.before
const beforeNeeded = (parent[META].type === 'Object' && before) const beforeNeeded = (parent[META].type === 'Object' && before)

View File

@ -8,7 +8,7 @@
* modes: string[]?, * modes: string[]?,
* history: boolean?, * history: boolean?,
* indentation: number | string?, * indentation: number | string?,
* onChange: function (patch: JSONPatch, revert: JSONPatch)?, * onChange: function (patch: ESONPatch, revert: ESONPatch)?,
* onChangeText: function ()?, * onChangeText: function ()?,
* onChangeMode: function (mode: string, prevMode: string)?, * onChangeMode: function (mode: string, prevMode: string)?,
* onError: function (err: Error)?, * onError: function (err: Error)?,
@ -41,22 +41,10 @@ export type JSONArrayType = JSONType[]
export type SearchResultStatus = 'normal' | 'active' export type SearchResultStatus = 'normal' | 'active'
export type ESONPointerArea = 'value' | 'property' export type ESONPointerArea = 'value' | 'property'
export type ESONObjectProperty = {
id: number,
name: string,
value: ESON,
searchResult?: SearchResultStatus
}
export type ESONArrayItem = {
id: number,
value: ESON
}
export type ESONObject = { export type ESONObject = {
_meta: { _meta: {
type: 'Object', type: 'Object',
path: JSONPath, path: Path,
expanded?: boolean, expanded?: boolean,
selected?: boolean, selected?: boolean,
searchProperty?: SearchResultStatus, searchProperty?: SearchResultStatus,
@ -67,7 +55,7 @@ export type ESONObject = {
export type ESONArray = { export type ESONArray = {
_meta: { _meta: {
type: 'Array', type: 'Array',
path: JSONPath, path: Path,
length: number length: number
expanded?: boolean, expanded?: boolean,
selected?: boolean, selected?: boolean,
@ -79,7 +67,7 @@ export type ESONArray = {
export type ESONValue = { export type ESONValue = {
_meta: { _meta: {
type: 'value' | 'string', type: 'value' | 'string',
path: JSONPath, path: Path,
value: null | boolean | string | number, value: null | boolean | string | number,
selected?: boolean, selected?: boolean,
searchProperty?: SearchResultStatus, searchProperty?: SearchResultStatus,
@ -91,28 +79,18 @@ export type ESON = ESONObject | ESONArray | ESONValue
export type ESONType = 'Object' | 'Array' | 'value' | 'string' export type ESONType = 'Object' | 'Array' | 'value' | 'string'
export type Path = string[] // TODO: Path must become redundant, replace with JSONPath or ESONPath everywhere export type Path = string[]
export type JSONPath = string[]
export type ESONPath = string[]
export type ESONPointer = { export type ESONPointer = {
path: JSONPath, // TODO: change path to an ESONPath? path: Path,
area?: ESONPointerArea area?: ESONPointerArea
} }
export type Selection = { export type Selection = {
start?: JSONPath, start?: Path,
end?: JSONPath, end?: Path,
before?: JSONPath, before?: Path,
after?: JSONPath after?: Path
}
// TODO: ESONPointer.path is an array, JSONSchemaError.path is a string -> make this consistent
// TODO: remove SetOptions, merge into Options (everywhere in the public API)
export type SetOptions = {
expand?: (path: Path) => boolean
} }
export type ESONPatchAction = { export type ESONPatchAction = {
@ -120,7 +98,7 @@ export type ESONPatchAction = {
path: string, path: string,
from?: string, from?: string,
value?: any, value?: any,
jsoneditor?: ESONPatchOptions meta?: ESONPatchOptions
} }
export type ESONPatch = ESONPatchAction[] export type ESONPatch = ESONPatchAction[]
@ -129,13 +107,8 @@ export type ESONPatchOptions = {
expand: (Path) => boolean expand: (Path) => boolean
} }
export type ESONPatchResult = { // TODO: ESONPointer.path is an array, JSONSchemaError.path is a string -> make this consistent
patch: ESONPatch,
revert: ESONPatch,
error: null | Error
}
export type JSONSchemaError = { export type JSONSchemaError = {
dataPath: string, // TODO: change type to JSONPath dataPath: string, // TODO: change type to Path
message: string message: string
} }