Skip to content

Commit

Permalink
feat: implement validate method and pass contentErrors via onChange, f…
Browse files Browse the repository at this point in the history
…ixes #56 (#119)

BREAKING CHANGES:

The signature of `onChange` is changed from `onChange(updatedContent, previousContent, patchResult)`
to `onChange(updatedContent, previousContent, { contentErrors, patchResult })`.
  • Loading branch information
josdejong authored Jul 28, 2022
1 parent f37483e commit 705f5f2
Show file tree
Hide file tree
Showing 17 changed files with 420 additions and 200 deletions.
4 changes: 2 additions & 2 deletions README-VANILLA.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ Browser example loading the ES module:
target: document.getElementById('jsoneditor'),
props: {
content,
onChange: (updatedContent, previousContent, patchResult) => {
onChange: (updatedContent, previousContent, { contentErrors, patchResult }) => {
// content is an object { json: JSONData } | { text: string }
console.log('onChange', updatedContent, previousContent, patchResult)
console.log('onChange', { updatedContent, previousContent, contentErrors, patchResult })
content = updatedContent
}
}
Expand Down
43 changes: 31 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,13 @@ Or one-way binding:
}
}
function handleChange(updatedContent, previousContent, patchResult) {
function handleChange(updatedContent, previousContent, { contentErrors, patchResult }) {
// content is an object { json: JSONData } | { text: string }
console.log('onChange: ', updatedContent, previousContent, patchResult)
console.log('onChange: ', { updatedContent, previousContent, contentErrors, patchResult })
content = updatedContent
}
</script>
F

<div>
<JSONEditor {content} onChange="{handleChange}" />
Expand Down Expand Up @@ -123,9 +124,9 @@ Browser example loading the ES module:
target: document.getElementById('jsoneditor'),
props: {
content,
onChange: (updatedContent, previousContent, patchResult) => {
onChange: (updatedContent, previousContent, { contentErrors, patchResult }) => {
// content is an object { json: JSONData } | { text: string }
console.log('onChange', updatedContent, previousContent, patchResult)
console.log('onChange', { updatedContent, previousContent, contentErrors, patchResult })
content = updatedContent
}
}
Expand Down Expand Up @@ -163,9 +164,9 @@ const editor = new JSONEditor({
target: document.getElementById('jsoneditor'),
props: {
content,
onChange: (updatedContent, previousContent, patchResult) => {
onChange: (updatedContent, previousContent, { contentErrors, patchResult }) => {
// content is an object { json: JSONData } | { text: string }
console.log('onChange', updatedContent, previousContent, patchResult)
console.log('onChange', { updatedContent, previousContent, contentErrors, patchResult })
}
}
})
Expand Down Expand Up @@ -194,7 +195,7 @@ const editor = new JSONEditor({

- `onError(err: Error)`.
Callback fired when an error occurs. Default implementation is to log an error in the console and show a simple alert message to the user.
- `onChange(content: Content, previousContent: Content, patchResult: JSONPatchResult | null)`. The callback which is invoked on every change made in the JSON document. The parameter `patchResult` is only available in `tree` mode, and not in `text` mode, since a change in arbitrary text cannot be expressed as a JSON Patch document.
- `onChange(content: Content, previousContent: Content, changeStatus: { contentErrors: ContentErrors, patchResult: JSONPatchResult | null })`. The callback which is invoked on every change made in the JSON document. The parameter `patchResult` is only available in `tree` mode, and not in `text` mode, since a change in arbitrary text cannot be expressed as a JSON Patch document.
- `onChangeMode(mode: 'tree' | 'text')`. Invoked when the mode is changed.
- `onClassName(path: Path, value: any): string | undefined`.
Add a custom class name to specific nodes, based on their path and/or value.
Expand Down Expand Up @@ -328,21 +329,39 @@ type JSONPatchResult = {
redo: JSONPatchDocument
}
type ValidationError = {
path: Path
interface ParseError {
position: number | null
line: number | null
column: number | null
message: string
isChildError?: boolean
}
type QueryLanguage = {
interface ValidationError {
path: JSONPath
message: string
severity: ValidationSeverity
}
interface ContentParseError {
parseError: ParseError
isRepairable: boolean
}
interface ContentValidationErrors {
validationErrors: ValidationError[]
}
type ContentErrors = ContentParseError | ContentValidationErrors
interface QueryLanguage {
id: string
name: string
description: string
createQuery: (json: JSONData, queryOptions: QueryLanguageOptions) => string
executeQuery: (json: JSONData, query: string) => JSONData
}
type QueryLanguageOptions = {
interface QueryLanguageOptions {
filter?: {
path?: string[]
relation?: '==' | '!=' | '<' | '<=' | '>' | '>='
Expand Down
11 changes: 11 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
"json-source-map": "^0.6.1",
"jsonrepair": "^2.2.1",
"lodash-es": "^4.17.21",
"memoize-one": "^6.0.0",
"natural-compare-lite": "^1.4.0",
"sass": "^1.53.0",
"svelte": "^3.48.0",
Expand Down
44 changes: 20 additions & 24 deletions src/lib/components/JSONEditor.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import ModalRef from './modals/ModalRef.svelte'
import type {
Content,
ContentErrors,
JSONEditorPropsOptional,
JSONPatchResult,
MenuItem,
Expand All @@ -25,6 +26,7 @@
OnChange,
OnChangeMode,
OnChangeQueryLanguage,
OnChangeStatus,
OnClassName,
OnError,
OnFocus,
Expand All @@ -36,10 +38,10 @@
TransformModalOptions,
Validator
} from '../types'
import { Mode } from '../types'
import type { JSONPatchDocument, JSONPath } from 'immutable-json-patch'
import { isMenuSpaceItem } from '../typeguards'
import { noop } from 'lodash-es'
import { Mode } from '../types'
// TODO: document how to enable debugging in the readme: localStorage.debug="jsoneditor:*", then reload
const debug = createDebug('jsoneditor:Main')
Expand Down Expand Up @@ -167,6 +169,20 @@
}
}
/**
* Validate the contents of the editor using the configured validator.
* Returns a parse error or a list with validation warnings
*/
export function validate(): ContentErrors {
if (refTextMode) {
return refTextMode.validate()
} else if (refTreeMode) {
return refTreeMode.validate()
} else {
throw new Error(`Method validate is not available in mode "${mode}"`)
}
}
/**
* In tree mode, invalid JSON is automatically repaired when loaded. When the
* repair was successful, the repaired contents are rendered but not yet
Expand Down Expand Up @@ -229,34 +245,14 @@
this.$destroy()
}
function handleChange(
updatedContent: Content,
previousContent: Content,
patchResult: JSONPatchResult | null
) {
function handleChange(updatedContent: Content, previousContent: Content, status: OnChangeStatus) {
content = updatedContent
if (onChange) {
onChange(updatedContent, previousContent, patchResult)
onChange(updatedContent, previousContent, status)
}
}
function handleChangeText(updatedText: string, previousText: string) {
const updatedContent = {
text: updatedText,
json: undefined
}
const previousContent = {
text: previousText,
json: undefined
}
const patchResult = null
handleChange(updatedContent, previousContent, patchResult)
}
async function handleRequestRepair() {
mode = Mode.text
Expand Down Expand Up @@ -419,7 +415,7 @@
{statusBar}
{escapeUnicodeCharacters}
{validator}
onChange={handleChangeText}
onChange={handleChange}
onSwitchToTreeMode={handleSwitchToTreeMode}
{onError}
onFocus={handleFocus}
Expand Down
Loading

0 comments on commit 705f5f2

Please sign in to comment.