diff --git a/src/jsoneditor/eson.js b/src/jsoneditor/eson.js index fd722fb..7fb1fa7 100644 --- a/src/jsoneditor/eson.js +++ b/src/jsoneditor/eson.js @@ -8,6 +8,8 @@ import isEqual from 'lodash/isEqual' import naturalSort from 'javascript-natural-sort' import times from 'lodash/times' import { immutableJSONPatch } from './immutableJSONPatch' +import { compareArrays } from './utils/arrayUtils' +import { compareStrings } from './utils/stringUtils' export const ID = typeof Symbol === 'function' ? Symbol('id') : '@jsoneditor-id' export const TYPE = typeof Symbol === 'function' ? Symbol('type') : '@jsoneditor-type' // 'object', 'array', 'value', or 'undefined' @@ -247,6 +249,18 @@ export function search (eson, text) { return updatedValue }) + matches.sort((a, b) => { + const arrayOrder = compareArrays(a.path, b.path) + if (arrayOrder !== 0) { + return arrayOrder + } + + // order property first, value second. + // we can use regular string ordering here because the word + // "property" comes before "value" + return compareStrings(a.area, b.area) + }) + return { eson: updatedEson, searchResult: { diff --git a/src/jsoneditor/utils/arrayUtils.js b/src/jsoneditor/utils/arrayUtils.js index 6c16450..52434bb 100644 --- a/src/jsoneditor/utils/arrayUtils.js +++ b/src/jsoneditor/utils/arrayUtils.js @@ -44,3 +44,19 @@ export function strictShallowEqual (a, b) { return true } + +export function compareArrays(a, b) { + const minLength = Math.min(a.length, b.length) + + for (let i = 0; i < minLength; i++) { + if (a[i] < b[i]) { + return -1 + } + + if (a[i] > b[i]) { + return 1 + } + } + + return a.length - b.length +} diff --git a/src/jsoneditor/utils/arrayUtils.test.js b/src/jsoneditor/utils/arrayUtils.test.js new file mode 100644 index 0000000..3181297 --- /dev/null +++ b/src/jsoneditor/utils/arrayUtils.test.js @@ -0,0 +1,27 @@ +import { compareArrays } from './arrayUtils' + +test('compareArrays', () => { + expect(compareArrays([], [])).toEqual(0) + expect(compareArrays(['a'], ['a'])).toEqual(0) + expect(compareArrays(['a'], ['b'])).toEqual(-1) + expect(compareArrays(['b'], ['a'])).toEqual(1) + expect(compareArrays(['a'], ['a', 'b'])).toEqual(-1) + expect(compareArrays(['a', 'b'], ['a'])).toEqual(1) + expect(compareArrays(['a', 'b'], ['a', 'b'])).toEqual(0) + + const arrays = [ + ['b', 'a'], + ['a'], + [], + ['b', 'c'], + ['b'], + ] + + expect(arrays.sort(compareArrays)).toEqual([ + [], + ['a'], + ['b'], + ['b', 'a'], + ['b', 'c'] + ]) +}) diff --git a/src/jsoneditor/utils/stringUtils.js b/src/jsoneditor/utils/stringUtils.js index c6c6386..c8f5476 100644 --- a/src/jsoneditor/utils/stringUtils.js +++ b/src/jsoneditor/utils/stringUtils.js @@ -123,3 +123,7 @@ export function toCapital(text) { ? text[0].toUpperCase() + text.substr(1).toLowerCase() : text } + +export function compareStrings (a, b) { + return (a < b) ? -1 : (a > b) ? 1 : 0 +} diff --git a/src/jsoneditor/utils/stringUtils.test.js b/src/jsoneditor/utils/stringUtils.test.js index 623a5e0..4ef0b05 100644 --- a/src/jsoneditor/utils/stringUtils.test.js +++ b/src/jsoneditor/utils/stringUtils.test.js @@ -1,4 +1,4 @@ -import { escapeHTML, unescapeHTML, findUniqueName, toCapital } from './stringUtils' +import { escapeHTML, unescapeHTML, findUniqueName, toCapital, compareStrings } from './stringUtils' test('escapeHTML', () => { expect(escapeHTML(' hello ')).toEqual('\u00A0\u00A0 hello \u00A0') @@ -31,3 +31,12 @@ test('toCapital', () => { expect(toCapital('')).toEqual('') expect(toCapital(undefined)).toEqual(undefined) }) + +test('compareStrings', () => { + expect(compareStrings('a', 'b')).toEqual(-1) + expect(compareStrings('b', 'a')).toEqual(1) + expect(compareStrings('a', 'a')).toEqual(0) + + const array = ['b', 'c', 'a'] + expect(array.sort(compareStrings)).toEqual(['a', 'b', 'c']) +})