Refactored 'object' and 'array' to 'Object' and 'Array' respectively

This commit is contained in:
jos 2016-09-17 15:40:17 +02:00
parent fb758d3135
commit 7b6a3747d2
6 changed files with 83 additions and 65 deletions

View File

@ -10,9 +10,9 @@ const TYPE_TITLES = {
'value': 'Item type "value". ' + 'value': 'Item type "value". ' +
'The item type is automatically determined from the value ' + 'The item type is automatically determined from the value ' +
'and can be a string, number, boolean, or null.', 'and can be a string, number, boolean, or null.',
'object': 'Item type "object". ' + 'Object': 'Item type "object". ' +
'An object contains an unordered set of key/value pairs.', 'An object contains an unordered set of key/value pairs.',
'array': 'Item type "array". ' + 'Array': 'Item type "array". ' +
'An array contains an ordered collection of values.', 'An array contains an ordered collection of values.',
'string': 'Item type "string". ' + 'string': 'Item type "string". ' +
'Item type is not determined from the value, ' + 'Item type is not determined from the value, ' +
@ -40,10 +40,10 @@ export default class JSONNode extends Component {
} }
render (props, state) { render (props, state) {
if (props.data.type === 'array') { if (props.data.type === 'Array') {
return this.renderJSONArray(props) return this.renderJSONArray(props)
} }
else if (props.data.type === 'object') { else if (props.data.type === 'Object') {
return this.renderJSONObject(props) return this.renderJSONObject(props)
} }
else { else {
@ -322,15 +322,15 @@ export default class JSONNode extends Component {
}, },
{ {
text: 'Array', text: 'Array',
className: 'jsoneditor-type-array' + (type == 'array' ? ' jsoneditor-selected' : ''), className: 'jsoneditor-type-array' + (type == 'Array' ? ' jsoneditor-selected' : ''),
title: TYPE_TITLES.array, title: TYPE_TITLES.array,
click: () => events.onChangeType(path, 'array') click: () => events.onChangeType(path, 'Array')
}, },
{ {
text: 'Object', text: 'Object',
className: 'jsoneditor-type-object' + (type == 'object' ? ' jsoneditor-selected' : ''), className: 'jsoneditor-type-object' + (type == 'Object' ? ' jsoneditor-selected' : ''),
title: TYPE_TITLES.object, title: TYPE_TITLES.object,
click: () => events.onChangeType(path, 'object') click: () => events.onChangeType(path, 'Object')
}, },
{ {
text: 'String', text: 'String',
@ -341,7 +341,7 @@ export default class JSONNode extends Component {
] ]
}) })
if (type === 'array' || type === 'object') { if (type === 'Array' || type === 'Object') {
var direction = ((this.sortOrder == 'asc') ? 'desc': 'asc') var direction = ((this.sortOrder == 'asc') ? 'desc': 'asc')
items.push({ items.push({
text: 'Sort', text: 'Sort',
@ -391,13 +391,13 @@ export default class JSONNode extends Component {
text: 'Array', text: 'Array',
className: 'jsoneditor-type-array', className: 'jsoneditor-type-array',
title: TYPE_TITLES.array, title: TYPE_TITLES.array,
click: () => events.onInsert(path, 'array') click: () => events.onInsert(path, 'Array')
}, },
{ {
text: 'Object', text: 'Object',
className: 'jsoneditor-type-object', className: 'jsoneditor-type-object',
title: TYPE_TITLES.object, title: TYPE_TITLES.object,
click: () => events.onInsert(path, 'object') click: () => events.onInsert(path, 'Object')
}, },
{ {
text: 'String', text: 'String',
@ -458,13 +458,13 @@ export default class JSONNode extends Component {
text: 'Array', text: 'Array',
className: 'jsoneditor-type-array', className: 'jsoneditor-type-array',
title: TYPE_TITLES.array, title: TYPE_TITLES.array,
click: () => events.onAppend(path, 'array') click: () => events.onAppend(path, 'Array')
}, },
{ {
text: 'Object', text: 'Object',
className: 'jsoneditor-type-object', className: 'jsoneditor-type-object',
title: TYPE_TITLES.object, title: TYPE_TITLES.object,
click: () => events.onAppend(path, 'object') click: () => events.onAppend(path, 'Object')
}, },
{ {
text: 'String', text: 'String',
@ -501,7 +501,7 @@ export default class JSONNode extends Component {
static getRootName (data, options) { static getRootName (data, options) {
return typeof options.name === 'string' return typeof options.name === 'string'
? options.name ? options.name
: (data.type === 'object' || data.type === 'array') : (data.type === 'Object' || data.type === 'Array')
? data.type ? data.type
: valueType(data.value) : valueType(data.value)
} }

View File

@ -17,13 +17,22 @@ export function changeValue (data, path, value) {
const dataPath = toDataPath(data, path) const dataPath = toDataPath(data, path)
const oldDataValue = getIn(data, dataPath) const oldDataValue = getIn(data, dataPath)
return [{ let patch = [{
op: 'replace', op: 'replace',
path: compileJSONPointer(path), path: compileJSONPointer(path),
value: value, value: value
jsoneditor: { type: oldDataValue.type } // TODO: send type only in case of 'string'
// TODO: send some information to ensure the correct order of fields?
}] }]
// when the old type is not something that can be detected from the
// value itself, store the type information
if(!isNativeType(oldDataValue.type)) {
// it's a string
patch[0].jsoneditor = {
type: oldDataValue.type
}
}
return patch
} }
/** /**
@ -35,7 +44,7 @@ export function changeValue (data, path, value) {
* @return {Array} * @return {Array}
*/ */
export function changeProperty (data, parentPath, oldProp, newProp) { export function changeProperty (data, parentPath, oldProp, newProp) {
console.log('changeProperty', parentPath, oldProp, newProp) // console.log('changeProperty', parentPath, oldProp, newProp)
const dataPath = toDataPath(data, parentPath) const dataPath = toDataPath(data, parentPath)
const parent = getIn(data, dataPath) const parent = getIn(data, dataPath)
@ -101,7 +110,7 @@ export function duplicate (data, path) {
const dataPath = toDataPath(data, parentPath) const dataPath = toDataPath(data, parentPath)
const parent = getIn(data, dataPath) const parent = getIn(data, dataPath)
if (parent.type === 'array') { if (parent.type === 'Array') {
const index = parseInt(path[path.length - 1]) + 1 const index = parseInt(path[path.length - 1]) + 1
return [{ return [{
op: 'copy', op: 'copy',
@ -109,7 +118,7 @@ export function duplicate (data, path) {
path: compileJSONPointer(parentPath.concat(index)) path: compileJSONPointer(parentPath.concat(index))
}] }]
} }
else { // object.type === 'object' else { // object.type === 'Object'
const afterProp = path[path.length - 1] const afterProp = path[path.length - 1]
const newProp = findUniqueName(afterProp, parent.props.map(p => p.name)) const newProp = findUniqueName(afterProp, parent.props.map(p => p.name))
@ -142,7 +151,7 @@ export function insert (data, path, type) {
const parent = getIn(data, dataPath) const parent = getIn(data, dataPath)
const value = createEntry(type) const value = createEntry(type)
if (parent.type === 'array') { if (parent.type === 'Array') {
const index = parseInt(path[path.length - 1]) + 1 const index = parseInt(path[path.length - 1]) + 1
return [{ return [{
op: 'add', op: 'add',
@ -150,7 +159,7 @@ export function insert (data, path, type) {
value value
}] }]
} }
else { // object.type === 'object' else { // object.type === 'Object'
const afterProp = path[path.length - 1] const afterProp = path[path.length - 1]
const newProp = findUniqueName('', parent.props.map(p => p.name)) const newProp = findUniqueName('', parent.props.map(p => p.name))
@ -182,14 +191,14 @@ export function append (data, parentPath, type) {
const parent = getIn(data, dataPath) const parent = getIn(data, dataPath)
const value = createEntry(type) const value = createEntry(type)
if (parent.type === 'array') { if (parent.type === 'Array') {
return [{ return [{
op: 'add', op: 'add',
path: compileJSONPointer(parentPath.concat('-')), path: compileJSONPointer(parentPath.concat('-')),
value value
}] }]
} }
else { // object.type === 'object' else { // object.type === 'Object'
const newProp = findUniqueName('', parent.props.map(p => p.name)) const newProp = findUniqueName('', parent.props.map(p => p.name))
return [{ return [{
@ -215,7 +224,7 @@ export function sort (data, path, order = null) {
const dataPath = toDataPath(data, path) const dataPath = toDataPath(data, path)
const object = getIn(data, dataPath) const object = getIn(data, dataPath)
if (object.type === 'array') { if (object.type === 'Array') {
const orderedItems = object.items.slice(0) const orderedItems = object.items.slice(0)
// order the items by value // order the items by value
@ -231,12 +240,12 @@ export function sort (data, path, order = null) {
op: 'replace', op: 'replace',
path: compileJSONPointer(path), path: compileJSONPointer(path),
value: dataToJson({ value: dataToJson({
type: 'array', type: 'Array',
items: orderedItems items: orderedItems
}) })
}] }]
} }
else { // object.type === 'object' else { // object.type === 'Object'
const orderedProps = object.props.slice(0) const orderedProps = object.props.slice(0)
// order the properties by key // order the properties by key
@ -252,7 +261,7 @@ export function sort (data, path, order = null) {
op: 'replace', op: 'replace',
path: compileJSONPointer(path), path: compileJSONPointer(path),
value: dataToJson({ value: dataToJson({
type: 'object', type: 'Object',
props: orderedProps props: orderedProps
}), }),
jsoneditor: { jsoneditor: {
@ -268,10 +277,10 @@ export function sort (data, path, order = null) {
* @return {Array | Object | string} * @return {Array | Object | string}
*/ */
export function createEntry (type) { export function createEntry (type) {
if (type === 'array') { if (type === 'Array') {
return [] return []
} }
else if (type === 'object') { else if (type === 'Object') {
return {} return {}
} }
else { else {
@ -305,7 +314,7 @@ export function convertType (value, type) {
} }
} }
if (type === 'object') { if (type === 'Object') {
let object = {} let object = {}
if (Array.isArray(value)) { if (Array.isArray(value)) {
@ -315,7 +324,7 @@ export function convertType (value, type) {
return object return object
} }
if (type === 'array') { if (type === 'Array') {
let array = [] let array = []
if (isObject(value)) { if (isObject(value)) {
@ -329,3 +338,13 @@ export function convertType (value, type) {
throw new Error(`Unknown type '${type}'`) throw new Error(`Unknown type '${type}'`)
} }
/**
* Test whether a type is a native JSON type:
* Native types are: Array, Object, or value
* @param {JSONDataType} type
* @return {boolean}
*/
export function isNativeType (type) {
return type === 'Object' || type === 'Array' || type === 'value'
}

View File

@ -24,14 +24,14 @@ const expandNever = function (path) {
export function jsonToData (path, json, expand) { export function jsonToData (path, json, expand) {
if (Array.isArray(json)) { if (Array.isArray(json)) {
return { return {
type: 'array', type: 'Array',
expanded: expand(path), expanded: expand(path),
items: json.map((child, index) => jsonToData(path.concat(index), child, expand)) items: json.map((child, index) => jsonToData(path.concat(index), child, expand))
} }
} }
else if (isObject(json)) { else if (isObject(json)) {
return { return {
type: 'object', type: 'Object',
expanded: expand(path), expanded: expand(path),
props: Object.keys(json).map(name => { props: Object.keys(json).map(name => {
return { return {
@ -56,10 +56,10 @@ export function jsonToData (path, json, expand) {
*/ */
export function dataToJson (data) { export function dataToJson (data) {
switch (data.type) { switch (data.type) {
case 'array': case 'Array':
return data.items.map(dataToJson) return data.items.map(dataToJson)
case 'object': case 'Object':
const object = {} const object = {}
data.props.forEach(prop => { data.props.forEach(prop => {
@ -86,7 +86,7 @@ export function toDataPath (data, path) {
} }
let index let index
if (data.type === 'array') { if (data.type === 'Array') {
// index of an array // index of an array
index = path[0] index = path[0]
@ -235,7 +235,7 @@ export function remove (data, path) {
// FIXME: store before // FIXME: store before
} }
if (parent.type === 'array') { if (parent.type === 'Array') {
const dataPath = toDataPath(data, _path) const dataPath = toDataPath(data, _path)
return { return {
@ -243,7 +243,7 @@ export function remove (data, path) {
revert: {op: 'add', path, value, jsoneditor} revert: {op: 'add', path, value, jsoneditor}
} }
} }
else { // object.type === 'object' else { // object.type === 'Object'
const dataPath = toDataPath(data, _path) const dataPath = toDataPath(data, _path)
dataPath.pop() // remove the 'value' property, we want to remove the whole object property dataPath.pop() // remove the 'value' property, we want to remove the whole object property
@ -281,7 +281,7 @@ export function add (data, path, value, afterProp) {
catch (err) {} catch (err) {}
let updatedData let updatedData
if (parent.type === 'array') { if (parent.type === 'Array') {
// TODO: create an immutable helper function to insert an item in an Array // TODO: create an immutable helper function to insert an item in an Array
updatedData = updateIn(data, dataPath.concat('items'), (items) => { updatedData = updateIn(data, dataPath.concat('items'), (items) => {
const index = parseInt(prop) const index = parseInt(prop)
@ -292,7 +292,7 @@ export function add (data, path, value, afterProp) {
return updatedItems return updatedItems
}) })
} }
else { // parent.type === 'object' else { // parent.type === 'Object'
// TODO: create an immutable helper function to append an item to an Array // TODO: create an immutable helper function to append an item to an Array
updatedData = updateIn(data, dataPath.concat('props'), (props) => { updatedData = updateIn(data, dataPath.concat('props'), (props) => {
const newProp = { name: prop, value } const newProp = { name: prop, value }
@ -313,7 +313,7 @@ export function add (data, path, value, afterProp) {
return { return {
data: updatedData, data: updatedData,
revert: (parent.type === 'object' && oldValue !== undefined) revert: (parent.type === 'Object' && oldValue !== undefined)
? {op: 'replace', path: compileJSONPointer(resolvedPath), value: dataToJson(oldValue)} ? {op: 'replace', path: compileJSONPointer(resolvedPath), value: dataToJson(oldValue)}
: {op: 'remove', path: compileJSONPointer(resolvedPath)} : {op: 'remove', path: compileJSONPointer(resolvedPath)}
} }
@ -450,7 +450,7 @@ export function expand (data, callback, expanded) {
*/ */
function expandRecursive (data, path, callback, expanded) { function expandRecursive (data, path, callback, expanded) {
switch (data.type) { switch (data.type) {
case 'array': { case 'Array': {
let updatedData = callback(path) let updatedData = callback(path)
? setIn(data, ['expanded'], expanded) ? setIn(data, ['expanded'], expanded)
: data : data
@ -464,7 +464,7 @@ function expandRecursive (data, path, callback, expanded) {
return setIn(updatedData, ['items'], updatedItems) return setIn(updatedData, ['items'], updatedItems)
} }
case 'object': { case 'Object': {
let updatedData = callback(path) let updatedData = callback(path)
? setIn(data, ['expanded'], expanded) ? setIn(data, ['expanded'], expanded)
: data : data
@ -501,7 +501,7 @@ export function pathExists (data, path) {
} }
let index let index
if (data.type === 'array') { if (data.type === 'Array') {
// index of an array // index of an array
index = path[0] index = path[0]
return pathExists(data.items[index], path.slice(1)) return pathExists(data.items[index], path.slice(1))
@ -527,7 +527,7 @@ export function resolvePathIndex (data, path) {
const parentPath = path.slice(0, path.length - 1) const parentPath = path.slice(0, path.length - 1)
const parent = getIn(data, toDataPath(data, parentPath)) const parent = getIn(data, toDataPath(data, parentPath))
if (parent.type === 'array') { if (parent.type === 'Array') {
const index = parent.items.length const index = parent.items.length
const resolvedPath = path.slice(0) const resolvedPath = path.slice(0)
resolvedPath[resolvedPath.length - 1] = index resolvedPath[resolvedPath.length - 1] = index

View File

@ -1,13 +1,12 @@
// TODO: rename type 'array' to 'Array' and 'object' to 'Object'
/** /**
* @typedef {{ * @typedef {{
* type: 'array', * type: 'Array',
* expanded: boolean?, * expanded: boolean?,
* props: Array.<{name: string, value: JSONData}>? * props: Array.<{name: string, value: JSONData}>?
* }} ObjectData * }} ObjectData
* *
* @typedef {{ * @typedef {{
* type: 'object', * type: 'Object',
* expanded: boolean?, * expanded: boolean?,
* items: JSONData[]? * items: JSONData[]?
* }} ArrayData * }} ArrayData
@ -21,7 +20,7 @@
* *
* @typedef {ObjectData | ArrayData | ValueData} JSONData * @typedef {ObjectData | ArrayData | ValueData} JSONData
* *
* @typedef {'object' | 'array' | 'value' | 'string'} JSONDataType * @typedef {'Object' | 'Array' | 'value' | 'string'} JSONDataType
* *
* @typedef {Array.<{op: string, path?: string, from?: string, value?: *}>} JSONPatch * @typedef {Array.<{op: string, path?: string, from?: string, value?: *}>} JSONPatch
* *

View File

@ -48,10 +48,10 @@ export function valueType(value) {
return 'regexp' return 'regexp'
} }
if (Array.isArray(value)) { if (Array.isArray(value)) {
return 'array' return 'Array'
} }
return 'object' return 'Object'
} }
/** /**

View File

@ -15,19 +15,19 @@ const JSON_EXAMPLE = {
} }
const JSON_DATA_EXAMPLE = { const JSON_DATA_EXAMPLE = {
type: 'object', type: 'Object',
expanded: true, expanded: true,
props: [ props: [
{ {
name: 'obj', name: 'obj',
value: { value: {
type: 'object', type: 'Object',
expanded: true, expanded: true,
props: [ props: [
{ {
name: 'arr', name: 'arr',
value: { value: {
type: 'array', type: 'Array',
expanded: true, expanded: true,
items: [ items: [
{ {
@ -39,7 +39,7 @@ const JSON_DATA_EXAMPLE = {
value: 2 value: 2
}, },
{ {
type: 'object', type: 'Object',
expanded: true, expanded: true,
props: [ props: [
{ {
@ -89,19 +89,19 @@ const JSON_DATA_EXAMPLE = {
} }
const JSON_DATA_EXAMPLE_COLLAPSED_1 = { const JSON_DATA_EXAMPLE_COLLAPSED_1 = {
type: 'object', type: 'Object',
expanded: true, expanded: true,
props: [ props: [
{ {
name: 'obj', name: 'obj',
value: { value: {
type: 'object', type: 'Object',
expanded: true, expanded: true,
props: [ props: [
{ {
name: 'arr', name: 'arr',
value: { value: {
type: 'array', type: 'Array',
expanded: true, expanded: true,
items: [ items: [
{ {
@ -113,7 +113,7 @@ const JSON_DATA_EXAMPLE_COLLAPSED_1 = {
value: 2 value: 2
}, },
{ {
type: 'object', type: 'Object',
expanded: false, expanded: false,
props: [ props: [
{ {
@ -163,19 +163,19 @@ const JSON_DATA_EXAMPLE_COLLAPSED_1 = {
} }
const JSON_DATA_EXAMPLE_COLLAPSED_2 = { const JSON_DATA_EXAMPLE_COLLAPSED_2 = {
type: 'object', type: 'Object',
expanded: true, expanded: true,
props: [ props: [
{ {
name: 'obj', name: 'obj',
value: { value: {
type: 'object', type: 'Object',
expanded: false, expanded: false,
props: [ props: [
{ {
name: 'arr', name: 'arr',
value: { value: {
type: 'array', type: 'Array',
expanded: false, expanded: false,
items: [ items: [
{ {
@ -187,7 +187,7 @@ const JSON_DATA_EXAMPLE_COLLAPSED_2 = {
value: 2 value: 2
}, },
{ {
type: 'object', type: 'Object',
expanded: false, expanded: false,
props: [ props: [
{ {