Improved expand function, fixed expand/collapse of TreeMode
This commit is contained in:
parent
e5c6459f73
commit
8b2541e3d8
|
@ -62,7 +62,7 @@ export default class TextMode extends Component {
|
||||||
this.applyProps(nextProps, this.props)
|
this.applyProps(nextProps, this.props)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: create some sort of watcher structure for these props? Is there a Reactpattern for that?
|
// TODO: create some sort of watcher structure for these props? Is there a React pattern for that?
|
||||||
applyProps (nextProps, currentProps) {
|
applyProps (nextProps, currentProps) {
|
||||||
// Apply text
|
// Apply text
|
||||||
if (nextProps.text !== currentProps.text) {
|
if (nextProps.text !== currentProps.text) {
|
||||||
|
@ -87,6 +87,7 @@ export default class TextMode extends Component {
|
||||||
this.findKeyBinding = createFindKeyBinding(keyBindings)
|
this.findKeyBinding = createFindKeyBinding(keyBindings)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: apply patch
|
||||||
// TODO: apply patchText
|
// TODO: apply patchText
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -156,9 +156,9 @@ export default class TreeMode extends PureComponent {
|
||||||
// Apply json
|
// Apply json
|
||||||
if (nextProps.json !== this.state.json) {
|
if (nextProps.json !== this.state.json) {
|
||||||
// FIXME: merge meta data from existing eson
|
// FIXME: merge meta data from existing eson
|
||||||
const expandCallback = this.props.expand || TreeMode.expandRoot
|
const callback = this.props.expand || TreeMode.expandRoot
|
||||||
const json = nextProps.json
|
const json = nextProps.json
|
||||||
const eson = expand(jsonToEson(json), expandCallback)
|
const eson = expand(jsonToEson(json), callback)
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
json,
|
json,
|
||||||
|
@ -571,7 +571,7 @@ export default class TreeMode extends PureComponent {
|
||||||
if (recurse) {
|
if (recurse) {
|
||||||
this.setState({
|
this.setState({
|
||||||
eson: updateIn(this.state.eson, path, function (child) {
|
eson: updateIn(this.state.eson, path, function (child) {
|
||||||
return expand(child, (path) => true, expanded)
|
return expand(child, (path) => expanded)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -588,18 +588,14 @@ export default class TreeMode extends PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
handleExpandAll = () => {
|
handleExpandAll = () => {
|
||||||
const expanded = true
|
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
eson: expand(this.state.eson, TreeMode.expandAll, expanded)
|
eson: expand(this.state.eson, TreeMode.expandAll)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
handleCollapseAll = () => {
|
handleCollapseAll = () => {
|
||||||
const expanded = false
|
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
eson: expand(this.state.eson, TreeMode.expandAll, expanded)
|
eson: expand(this.state.eson, TreeMode.collapseAll)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1008,20 +1004,38 @@ export default class TreeMode extends PureComponent {
|
||||||
* @param {Path | function (path: Path) : boolean} callback
|
* @param {Path | function (path: Path) : boolean} callback
|
||||||
*/
|
*/
|
||||||
expand (callback) {
|
expand (callback) {
|
||||||
|
if (Array.isArray(callback)) {
|
||||||
this.setState({
|
this.setState({
|
||||||
eson: expand(this.state.eson, callback, true)
|
eson: expandPath(this.state.eson, callback, true)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
else { // callback is a function
|
||||||
|
this.setState({
|
||||||
|
eson: expand(this.state.eson, (path) => {
|
||||||
|
return callback(path) === true ? true : undefined
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collapse one or multiple objects or arrays
|
* Collapse one or multiple objects or arrays
|
||||||
* @param {Path | function (path: Path) : boolean} callback
|
* @param {Path | function (path: Path) : boolean} callback
|
||||||
*/
|
*/
|
||||||
collapse (callback) {
|
collapse (callback) {
|
||||||
|
if (Array.isArray(callback)) {
|
||||||
this.setState({
|
this.setState({
|
||||||
eson: expand(this.state.eson, callback, false)
|
eson: expandPath(this.state.eson, callback, true)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
else { // callback is a function
|
||||||
|
this.setState({
|
||||||
|
eson: expand(this.state.eson, (path) => {
|
||||||
|
return callback(path) === true ? false : undefined
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test whether a path exists in the editor
|
* Test whether a path exists in the editor
|
||||||
|
@ -1074,6 +1088,16 @@ export default class TreeMode extends PureComponent {
|
||||||
static expandAll (path) {
|
static expandAll (path) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback function to collapse all nodes
|
||||||
|
*
|
||||||
|
* @param {Array.<string>} path
|
||||||
|
* @return {boolean}
|
||||||
|
*/
|
||||||
|
static collapseAll (path) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: describe PropTypes
|
// TODO: describe PropTypes
|
||||||
|
|
|
@ -138,19 +138,23 @@ export function updatePaths(eson, path = []) {
|
||||||
/**
|
/**
|
||||||
* Expand or collapse all items matching a filter callback
|
* Expand or collapse all items matching a filter callback
|
||||||
* @param {ESON} eson
|
* @param {ESON} eson
|
||||||
* @param {function(Path) : boolean | Path} filterCallback
|
* @param {function(Path) : boolean | undefined} callback
|
||||||
* When a path, the object/array at this path will be expanded/collapsed
|
* All objects and arrays for which callback returns true will be expanded
|
||||||
* When a function, all objects and arrays for which callback
|
* All objects and arrays for which callback returns false will be collapsed
|
||||||
* returns true will be expanded/collapsed
|
* All objects and arrays for which callback returns undefined will be left as is
|
||||||
* @param {boolean} [expanded=true] New expanded state: true to expand, false to collapse
|
|
||||||
* @return {ESON}
|
* @return {ESON}
|
||||||
*/
|
*/
|
||||||
export function expand (eson, filterCallback, expanded = true) {
|
export function expand (eson, callback) {
|
||||||
// TODO: adjust expand to have a filterCallback which can return true, false, or undefined. In the latter case, the expanded state is left as is.
|
|
||||||
return transform(eson, function (value, path) {
|
return transform(eson, function (value, path) {
|
||||||
return ((value[META].type === 'Array' || value[META].type === 'Object') && filterCallback(path))
|
if (value[META].type === 'Array' || value[META].type === 'Object') {
|
||||||
? expandOne(value, [], expanded)
|
const expanded = callback(path)
|
||||||
: value
|
return (typeof expanded === 'boolean')
|
||||||
|
? expandOne(value, [], expanded) // adjust expanded state
|
||||||
|
: value // leave as is when returned value is null or undefined
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return value
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,15 +112,16 @@ test('expand a callback', () => {
|
||||||
"bool": false
|
"bool": false
|
||||||
})
|
})
|
||||||
|
|
||||||
function filterCallback (path) {
|
function callback (path) {
|
||||||
return path.length >= 1
|
return (path.length >= 1)
|
||||||
|
? false // collapse
|
||||||
|
: undefined // leave untouched
|
||||||
}
|
}
|
||||||
const expandedValue = false
|
const collapsed = expand(eson, callback)
|
||||||
const collapsed = expand(eson, filterCallback, expandedValue)
|
|
||||||
expect(collapsed[META].expanded).toEqual(undefined)
|
expect(collapsed[META].expanded).toEqual(undefined)
|
||||||
expect(collapsed.obj[META].expanded).toEqual(expandedValue)
|
expect(collapsed.obj[META].expanded).toEqual(false)
|
||||||
expect(collapsed.obj.arr[META].expanded).toEqual(expandedValue)
|
expect(collapsed.obj.arr[META].expanded).toEqual(false)
|
||||||
expect(collapsed.obj.arr[2][META].expanded).toEqual(expandedValue)
|
expect(collapsed.obj.arr[2][META].expanded).toEqual(false)
|
||||||
|
|
||||||
let orig = collapsed
|
let orig = collapsed
|
||||||
orig = deleteIn(orig, ['obj'].concat([META, 'expanded']))
|
orig = deleteIn(orig, ['obj'].concat([META, 'expanded']))
|
||||||
|
@ -132,10 +133,9 @@ test('expand a callback', () => {
|
||||||
test('expand a callback should not change the object when nothing happens', () => {
|
test('expand a callback should not change the object when nothing happens', () => {
|
||||||
const eson = jsonToEson({a: [1,2,3], b: {c: 4}})
|
const eson = jsonToEson({a: [1,2,3], b: {c: 4}})
|
||||||
function callback (path) {
|
function callback (path) {
|
||||||
return false
|
return undefined
|
||||||
}
|
}
|
||||||
const expanded = false
|
const collapsed = expand(eson, callback)
|
||||||
const collapsed = expand(eson, callback, expanded)
|
|
||||||
|
|
||||||
expect(collapsed).toBe(eson)
|
expect(collapsed).toBe(eson)
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue