Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/validate method #119

Merged
merged 10 commits into from
Jul 28, 2022
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