Compare commits
64 Commits
Author | SHA1 | Date |
---|---|---|
ZaneYork | ecebf360b3 | |
dependabot-preview[bot] | b64e012da8 | |
Jos de Jong | 8eb4819d0e | |
Jos de Jong | e35e39ff2f | |
Jos de Jong | 58f460a383 | |
dependabot-preview[bot] | 1492f22eea | |
Jos de Jong | 223b78542e | |
Jos de Jong | e1a8077dc1 | |
Jos de Jong | 745a1597dd | |
Jos de Jong | 2a861a2868 | |
Josh Kelley | 69fbe63f0e | |
Jos de Jong | f3694c3126 | |
Žiga Miklič | 6cf627a61a | |
Jos de Jong | 41fbf6973f | |
Jos de Jong | 07e4221fad | |
Jos de Jong | 8855944bae | |
Stephan Ahlf | 09b8ed8af6 | |
Jos de Jong | 2aee4a6008 | |
Jos de Jong | 2314aa74e5 | |
Jos de Jong | 12fd998cc1 | |
Jos de Jong | 60b84bb6bd | |
Jos de Jong | 2cbac6fd5c | |
Jos de Jong | 70c9b0b454 | |
Jos de Jong | 59dd16a538 | |
Jos de Jong | b214915b34 | |
Jos de Jong | b48ec89953 | |
Jos de Jong | 295e771ec4 | |
Jos de Jong | df81d1098d | |
dependabot-preview[bot] | 475902593e | |
Jos de Jong | e92bdf407f | |
jos | f9649d1155 | |
Jos de Jong | e89632d9ce | |
Jos de Jong | 09f2a398ca | |
josdejong | 162756ef69 | |
josdejong | 025c0649fa | |
josdejong | fb994728fd | |
josdejong | 400b1eea37 | |
josdejong | 87bc7b2561 | |
josdejong | 8826c6f2b6 | |
josdejong | 394432d3a6 | |
josdejong | 3a5ddb2ae7 | |
josdejong | b6235a8d23 | |
josdejong | 70a2f94693 | |
patrikx3 | d71c7b4ca0 | |
dependabot[bot] | 3048e710c9 | |
dependabot[bot] | 2d38d0bbc9 | |
josdejong | ae84c74996 | |
josdejong | f94589c1e9 | |
josdejong | 901b8aa8dd | |
josdejong | 1b259e7e47 | |
josdejong | 62025c490d | |
josdejong | c2fa821a31 | |
josdejong | bd69cf9ebd | |
josdejong | 71e209528d | |
josdejong | 27eb02a410 | |
josdejong | 9fbd352c12 | |
josdejong | ad021ec7af | |
dependabot-preview[bot] | 81513d0f4a | |
josdejong | 79beb26d66 | |
josdejong | ea7893a2f6 | |
josdejong | d3231570ab | |
josdejong | 561e582de8 | |
josdejong | 7dafdf8d9a | |
josdejong | fe800bada7 |
78
HISTORY.md
78
HISTORY.md
|
@ -3,8 +3,84 @@
|
|||
https://github.com/josdejong/jsoneditor
|
||||
|
||||
|
||||
## not yet published, version 8.6.7
|
||||
## not yet published, version 9.1.2
|
||||
|
||||
- Log a clear error in the console when the returned value of `onEditable` is
|
||||
invalid. See #1112.
|
||||
|
||||
|
||||
## 2020-09-23, version 9.1.1
|
||||
|
||||
- Fix #1111: Enum dropdown not showing when using patternProperties for schema.
|
||||
Thanks @ziga-miklic.
|
||||
- Fixed JSONEditor not working when opened in a new window, see #1098.
|
||||
Thanks @joshkel.
|
||||
- Fix quick-key `Ctrl+D` (duplicate) not working.
|
||||
- Define "charset: utf-8" in all HTML examples.
|
||||
|
||||
|
||||
## 2020-09-15, version 9.1.0
|
||||
|
||||
- Implemented German translation (`de`). Thanks @s-a.
|
||||
- Fix quick-keys `Ctrl-\` (format) and `Ctrl-Shift-\` (compact) not working
|
||||
in `code` mode.
|
||||
- Updated dependencies to `ajv@6.12.5`.
|
||||
|
||||
|
||||
## 2020-09-09, version 9.0.5
|
||||
|
||||
- Fix #1090: autocomplete firing on dragging or clicking a node.
|
||||
- Fix #1096: editor crashing when passing an empty string as `name`.
|
||||
- Updated dependencies to `ajv@6.12.4`.
|
||||
|
||||
|
||||
## 2020-08-15, version 9.0.4
|
||||
|
||||
- Updated dependencies to `ace-builds@1.4.12`, `ajv@6.12.3`.
|
||||
- Fix #1077: change the `main` field in `package.json` to point to the actual
|
||||
bundled and minified file instead of a node.js index file.
|
||||
|
||||
|
||||
## 2020-07-02, version 9.0.3
|
||||
|
||||
- Fix regression introduced in `v9.0.2` in the select boxes in the
|
||||
Transform model not lighlighting the matches correctly.
|
||||
|
||||
|
||||
## 2020-07-01, version 9.0.2
|
||||
|
||||
- Fix #1029: XSS vulnerabilities. Thanks @onemoreflag for reporting.
|
||||
- Fix #1017: unable to style the color of a value containing a color.
|
||||
Thanks @p3x-robot.
|
||||
|
||||
|
||||
## 2020-06-24, version 9.0.1
|
||||
|
||||
- Fixed broken link to the Ace editor website (https://ace.c9.io/).
|
||||
Thanks @p3x-robot.
|
||||
- Fix #1027: create IE11 Array polyfills `find` and `findIndex` in such a way
|
||||
that they are not iterable.
|
||||
|
||||
|
||||
## 2020-05-24, version 9.0.0
|
||||
|
||||
- Implemented option `limitDragging`, see #962. This is a breaking change when
|
||||
using a JSON schema: dragging is more restrictive by default in that case.
|
||||
Set `limitDragging: false` to keep the old, non-restricted behavior.
|
||||
|
||||
|
||||
## 2020-05-13, version 8.6.8
|
||||
|
||||
- Fix #936: too many return characters inserted when pasting formatted text
|
||||
from OpenOffice.
|
||||
|
||||
|
||||
## 2020-05-10, version 8.6.7
|
||||
|
||||
- Fix #858: the `dist/jsoneditor.js` bundle containing a link to a
|
||||
non-existing source map.
|
||||
- Fix #978: in some special cases the caret was jumping to the beginning of the
|
||||
line whilst typing.
|
||||
- Update dependencies to `ajv@6.12.2`.
|
||||
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
[![Downloads](https://img.shields.io/npm/dm/jsoneditor.svg)](https://www.npmjs.com/package/jsoneditor)
|
||||
![Maintenance](https://img.shields.io/maintenance/yes/2020.svg)
|
||||
[![License](https://img.shields.io/github/license/josdejong/jsoneditor.svg)](https://github.com/josdejong/jsoneditor/blob/master/LICENSE)
|
||||
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fjosdejong%2Fjsoneditor.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fjosdejong%2Fjsoneditor?ref=badge_shield) [![Greenkeeper badge](https://badges.greenkeeper.io/josdejong/jsoneditor.svg)](https://greenkeeper.io/)
|
||||
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fjosdejong%2Fjsoneditor.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fjosdejong%2Fjsoneditor?ref=badge_shield)
|
||||
|
||||
JSON Editor is a web-based tool to view, edit, format, and validate JSON.
|
||||
It has various modes such as a tree editor, a code editor, and a plain text
|
||||
|
@ -83,10 +83,10 @@ with npm (recommended):
|
|||
|
||||
```html
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<!-- when using the mode "code", it's important to specify charset utf-8 -->
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
<meta charset="utf-8">
|
||||
|
||||
<link href="jsoneditor/dist/jsoneditor.min.css" rel="stylesheet" type="text/css">
|
||||
<script src="jsoneditor/dist/jsoneditor.min.js"></script>
|
||||
|
|
20
docs/api.md
20
docs/api.md
|
@ -222,11 +222,15 @@ Constructs a new JSONEditor.
|
|||
|
||||
- `{boolean} escapeUnicode`
|
||||
|
||||
If true, unicode characters are escaped and displayed as their hexadecimal code (like `\u260E`) instead of of the character itself (like `☎`). `false` by default.
|
||||
If `true`, unicode characters are escaped and displayed as their hexadecimal code (like `\u260E`) instead of of the character itself (like `☎`). `false` by default.
|
||||
|
||||
- `{boolean} sortObjectKeys`
|
||||
|
||||
If true, object keys in 'tree', 'view' or 'form' mode list be listed alphabetically instead by their insertion order. Sorting is performed using a natural sort algorithm, which makes it easier to see objects that have string numbers as keys. `false` by default.
|
||||
If `true`, object keys in 'tree', 'view' or 'form' mode list be listed alphabetically instead by their insertion order. Sorting is performed using a natural sort algorithm, which makes it easier to see objects that have string numbers as keys. `false` by default.
|
||||
|
||||
- `{boolean} limitDragging`
|
||||
|
||||
If `false`, nodes can be dragged from any parent node to any other parent node. If `true`, nodes can only be dragged inside the same parent node, which effectively only allows reordering of nodes. By default, `limitDragging` is `true` when no JSON `schema` is defined, and `false` otherwise.
|
||||
|
||||
- `{boolean} history`
|
||||
|
||||
|
@ -438,6 +442,14 @@ Constructs a new JSONEditor.
|
|||
```
|
||||
Only applicable when `mode` is 'form', 'tree' or 'view'.
|
||||
|
||||
- `{function} onFocus({ type: 'focus', target })`
|
||||
Callback method, triggered when the editor comes into focus,
|
||||
passing an object `{type, target}`, Applicable for all modes.
|
||||
|
||||
- `{function} onBlur({ type: 'blur', target })`
|
||||
Callback method, triggered when the editor goes out of focus,
|
||||
passing an object `{type, target}`, Applicable for all modes.
|
||||
|
||||
- `{boolean} colorPicker`
|
||||
|
||||
If `true` (default), values containing a color name or color code will have a color picker rendered on their left side.
|
||||
|
@ -543,7 +555,7 @@ Constructs a new JSONEditor.
|
|||
|
||||
- `{string} language`
|
||||
|
||||
The default language comes from the browser navigator, but you can force a specific language. So use here string as 'en' or 'pt-BR'. Built-in languages: `en`, `pt-BR`, `zh-CN`, `tr`, `ja`, `fr-FR`. Other translations can be specified via the option `languages`.
|
||||
The default language comes from the browser navigator, but you can force a specific language. So use here string as 'en' or 'pt-BR'. Built-in languages: `en`, `zh-CN`, `pt-BR`, `tr`, `ja`, `fr-FR`, `de`. Other translations can be specified via the option `languages`.
|
||||
|
||||
- `{Object} languages`
|
||||
|
||||
|
@ -755,7 +767,7 @@ See also `JSONEditor.update(json)`.
|
|||
|
||||
#### `JSONEditor.setMode(mode)`
|
||||
|
||||
Switch mode. Mode `code` requires the [Ace editor](http://ace.ajax.org/).
|
||||
Switch mode. Mode `code` requires the [Ace editor](https://ace.c9.io/).
|
||||
|
||||
*Parameters:*
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ customized with several classes that reflect its type and state.
|
|||
- `jsoneditor-undefined`
|
||||
- `jsoneditor-number`
|
||||
- `jsoneditor-string`
|
||||
- `jsoneditor-string jsoneditor-color-value`
|
||||
- `jsoneditor-boolean`
|
||||
- `jsoneditor-regexp`
|
||||
- `jsoneditor-array`
|
||||
|
|
|
@ -59,10 +59,10 @@ var json = editor.get();
|
|||
|
||||
```html
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<!-- when using the mode "code", it's important to specify charset utf-8 -->
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
<meta charset="utf-8">
|
||||
|
||||
<link href="jsoneditor/dist/jsoneditor.min.css" rel="stylesheet" type="text/css">
|
||||
<script src="jsoneditor/dist/jsoneditor.min.js"></script>
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>JSONEditor | Basic usage</title>
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
|
@ -36,7 +38,8 @@
|
|||
'number': 123,
|
||||
'object': {'a': 'b', 'c': 'd'},
|
||||
'time': 1575599819000,
|
||||
'string': 'Hello World'
|
||||
'string': 'Hello World',
|
||||
'onlineDemo': 'https://jsoneditoronline.org/'
|
||||
}
|
||||
editor.set(json)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>JSONEditor | Viewer</title>
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>JSONEditor | Switch mode</title>
|
||||
|
||||
<!-- when using the mode "code", it's important to specify charset utf-8 -->
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>JSONEditor | Switch mode</title>
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
<script src="../dist/jsoneditor.js"></script>
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>JSONEditor | Load and save</title>
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>JSONEditor | Custom editable fields</title>
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>JSONEditor | Custom styling</title>
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
|
@ -35,7 +37,7 @@
|
|||
// create the editor
|
||||
const container = document.getElementById('jsoneditor')
|
||||
const options = {
|
||||
modes: ['text', 'tree']
|
||||
modes: ['tree', 'text']
|
||||
}
|
||||
const json = {
|
||||
'array': [1, 2, 3],
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>JSONEditor | JSON schema validation</title>
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>JSONEditor | Custom Ace</title>
|
||||
|
||||
<!-- load a custom version of Ace editor -->
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>JSONEditor | Switch mode</title>
|
||||
|
||||
<!-- when using the mode "code", it's important to specify charset utf-8 -->
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>JSONEditor | Switch mode</title>
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
<script src="../dist/jsoneditor.js"></script>
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>JSONEditor | Item templates</title>
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>JSONEditor | Auto Complete</title>
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>JSONEditor | Dynamic Auto Complete</title>
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>JSONEditor | Advanced Auto Complete</title>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
<script src="../dist/jsoneditor.js"></script>
|
||||
<script src="https://unpkg.com/jsonpath@0.2.11/jsonpath.min.js"></script>
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
<meta charset="utf-8">
|
||||
<title>JSONEditor | Translate</title>
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
<meta charset="utf-8">
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
<script src="../dist/jsoneditor.js"></script>
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>JSONEditor | Synchronize two editors</title>
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
<meta charset="utf-8">
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
<script src="../dist/jsoneditor.js"></script>
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>JSONEditor | Custom validation</title>
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>JSONEditor | Custom validation (asynchronous)</title>
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
<meta charset="utf-8">
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
<script src="../dist/jsoneditor.js"></script>
|
||||
|
@ -32,12 +32,21 @@
|
|||
height: 500px;
|
||||
}
|
||||
#containerRight .different_element {
|
||||
background-color: greenyellow !important;
|
||||
background-color: #acee61;
|
||||
}
|
||||
#containerRight .different_element div.jsoneditor-field,
|
||||
#containerRight .different_element div.jsoneditor-value {
|
||||
color: red;
|
||||
}
|
||||
|
||||
#containerLeft .different_element {
|
||||
background-color: violet !important;
|
||||
background-color: pink;
|
||||
}
|
||||
</style>
|
||||
#containerLeft .different_element div.jsoneditor-field,
|
||||
#containerLeft .different_element div.jsoneditor-value {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>JSONEditor | Basic usage</title>
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>JSONEditor | onValidationError</title>
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>JSONEditor | New window</title>
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
<script src="../dist/jsoneditor.js"></script>
|
||||
|
||||
<style type="text/css">
|
||||
#jsoneditor {
|
||||
width: 500px;
|
||||
height: 500px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
<button id="openNewEditor">Open Editor in New Window</button>
|
||||
<button id="setJSON">Set JSON</button>
|
||||
<button id="getJSON">Get JSON</button>
|
||||
</p>
|
||||
|
||||
<script>
|
||||
let editor
|
||||
|
||||
function openNewEditor() {
|
||||
const child = window.open("", "_blank", "width=400,height=400")
|
||||
child.document.title = 'JSONEditor | New window'
|
||||
child.onunload = function () {
|
||||
editor = undefined
|
||||
}
|
||||
|
||||
// make the necessary styles available within the child window
|
||||
// for JSONEditor
|
||||
const baseUrl = window.location.href.slice(0, window.location.href.lastIndexOf('/'))
|
||||
const jsonEditorStyles = child.document.createElement("link")
|
||||
jsonEditorStyles.setAttribute("href", baseUrl + "/../dist/jsoneditor.css")
|
||||
jsonEditorStyles.setAttribute("rel", "stylesheet")
|
||||
child.document.head.append(jsonEditorStyles)
|
||||
// for vanilla-picker
|
||||
const colorPickerStyles = JSONEditor.VanillaPicker.StyleElement.cloneNode(true)
|
||||
child.document.head.append(colorPickerStyles)
|
||||
|
||||
const container = child.document.createElement("div")
|
||||
child.document.body.append(container)
|
||||
|
||||
// create the editor
|
||||
const options = {
|
||||
// Show sort and transform modals in the child window, not the parent.
|
||||
modalAnchor: child.document.body
|
||||
}
|
||||
editor = new JSONEditor(container, options)
|
||||
}
|
||||
|
||||
// create a new window
|
||||
document.getElementById('openNewEditor').onclick = openNewEditor
|
||||
|
||||
// set json
|
||||
document.getElementById('setJSON').onclick = function () {
|
||||
if (!editor) {
|
||||
openNewEditor()
|
||||
}
|
||||
const json = {
|
||||
'array': [1, 2, 3],
|
||||
'boolean': true,
|
||||
'color': '#82b92c',
|
||||
'null': null,
|
||||
'number': 123,
|
||||
'object': {'a': 'b', 'c': 'd'},
|
||||
'time': 1575599819000,
|
||||
'string': 'Hello World'
|
||||
}
|
||||
editor.set(json)
|
||||
}
|
||||
|
||||
// get json
|
||||
document.getElementById('getJSON').onclick = function () {
|
||||
if (!editor) {
|
||||
alert('No editor is open')
|
||||
} else {
|
||||
const json = editor.get()
|
||||
alert(JSON.stringify(json, null, 2))
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
File diff suppressed because it is too large
Load Diff
|
@ -3,11 +3,11 @@
|
|||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"jsoneditor": "^8.5.3",
|
||||
"jsoneditor": "latest",
|
||||
"lodash": "4.17.15",
|
||||
"react": "16.13.1",
|
||||
"react-dom": "16.13.1",
|
||||
"react-scripts": "3.4.0"
|
||||
"react-scripts": "3.4.1"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3,7 +3,7 @@
|
|||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"jsoneditor": "^8.5.3",
|
||||
"jsoneditor": "latest",
|
||||
"react": "16.13.1",
|
||||
"react-dom": "16.13.1",
|
||||
"react-scripts": "3.4.1"
|
||||
|
|
|
@ -43,6 +43,11 @@ const webpackConfigModule = {
|
|||
use: {
|
||||
loader: 'babel-loader'
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
use: ['source-map-loader'],
|
||||
enforce: 'pre'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
27
package.json
27
package.json
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "jsoneditor",
|
||||
"version": "8.6.6",
|
||||
"main": "./index",
|
||||
"version": "9.1.1",
|
||||
"main": "./dist/jsoneditor.min.js",
|
||||
"description": "A web-based tool to view, edit, format, and validate JSON",
|
||||
"tags": [
|
||||
"json",
|
||||
|
@ -26,8 +26,8 @@
|
|||
"prepublishOnly": "npm test && npm run build"
|
||||
},
|
||||
"dependencies": {
|
||||
"ace-builds": "^1.4.11",
|
||||
"ajv": "^6.12.2",
|
||||
"ace-builds": "^1.4.12",
|
||||
"ajv": "^6.12.5",
|
||||
"javascript-natural-sort": "^0.7.1",
|
||||
"jmespath": "^0.15.0",
|
||||
"json-source-map": "^0.6.1",
|
||||
|
@ -36,9 +36,9 @@
|
|||
"vanilla-picker": "^2.10.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.9.0",
|
||||
"@babel/preset-env": "7.9.5",
|
||||
"@babel/register": "7.9.0",
|
||||
"@babel/core": "7.11.6",
|
||||
"@babel/preset-env": "7.11.5",
|
||||
"@babel/register": "7.11.5",
|
||||
"babel-loader": "8.1.0",
|
||||
"btoa": "1.2.1",
|
||||
"date-format": "3.0.0",
|
||||
|
@ -46,14 +46,15 @@
|
|||
"gulp": "4.0.2",
|
||||
"gulp-clean-css": "4.3.0",
|
||||
"gulp-concat-css": "3.1.0",
|
||||
"gulp-sass": "4.0.2",
|
||||
"jsdom": "16.2.2",
|
||||
"gulp-sass": "4.1.0",
|
||||
"jsdom": "16.4.0",
|
||||
"json-loader": "0.5.7",
|
||||
"mkdirp": "1.0.4",
|
||||
"mocha": "7.1.1",
|
||||
"standard": "14.3.3",
|
||||
"uglify-js": "3.9.1",
|
||||
"webpack": "4.43.0"
|
||||
"mocha": "8.1.3",
|
||||
"source-map-loader": "1.1.0",
|
||||
"standard": "14.3.4",
|
||||
"uglify-js": "3.11.1",
|
||||
"webpack": "4.44.2"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
|
|
|
@ -107,7 +107,9 @@ export class ContextMenu {
|
|||
buttonExpand.type = 'button'
|
||||
domItem.buttonExpand = buttonExpand
|
||||
buttonExpand.className = 'jsoneditor-expand'
|
||||
buttonExpand.innerHTML = '<div class="jsoneditor-expand"></div>'
|
||||
const buttonExpandInner = document.createElement('div')
|
||||
buttonExpandInner.className = 'jsoneditor-expand'
|
||||
buttonExpand.appendChild(buttonExpandInner)
|
||||
li.appendChild(buttonExpand)
|
||||
if (item.submenuTitle) {
|
||||
buttonExpand.title = item.submenuTitle
|
||||
|
@ -141,8 +143,14 @@ export class ContextMenu {
|
|||
createMenuItems(ul, domSubItems, item.submenu)
|
||||
} else {
|
||||
// no submenu, just a button with clickhandler
|
||||
button.innerHTML = '<div class="jsoneditor-icon"></div>' +
|
||||
'<div class="jsoneditor-text">' + translate(item.text) + '</div>'
|
||||
const icon = document.createElement('div')
|
||||
icon.className = 'jsoneditor-icon'
|
||||
button.appendChild(icon)
|
||||
|
||||
const text = document.createElement('div')
|
||||
text.className = 'jsoneditor-text'
|
||||
text.appendChild(document.createTextNode(translate(item.text)))
|
||||
button.appendChild(text)
|
||||
}
|
||||
|
||||
domItems.push(domItem)
|
||||
|
@ -425,5 +433,3 @@ export class ContextMenu {
|
|||
|
||||
// currently displayed context menu, a singleton. We may only have one visible context menu
|
||||
ContextMenu.visibleMenu = undefined
|
||||
|
||||
export default ContextMenu
|
||||
|
|
|
@ -23,7 +23,7 @@ export class ErrorTable {
|
|||
const additionalErrorsIndication = document.createElement('div')
|
||||
additionalErrorsIndication.style.display = 'none'
|
||||
additionalErrorsIndication.className = 'jsoneditor-additional-errors fadein'
|
||||
additionalErrorsIndication.innerHTML = 'Scroll for more ▿'
|
||||
additionalErrorsIndication.textContent = 'Scroll for more \u25BF'
|
||||
this.dom.additionalErrorsIndication = additionalErrorsIndication
|
||||
validationErrorsContainer.appendChild(additionalErrorsIndication)
|
||||
|
||||
|
@ -76,19 +76,15 @@ export class ErrorTable {
|
|||
if (this.errorTableVisible && errors.length > 0) {
|
||||
const validationErrors = document.createElement('div')
|
||||
validationErrors.className = 'jsoneditor-validation-errors'
|
||||
validationErrors.innerHTML = '<table class="jsoneditor-text-errors"><tbody></tbody></table>'
|
||||
const tbody = validationErrors.getElementsByTagName('tbody')[0]
|
||||
|
||||
const table = document.createElement('table')
|
||||
table.className = 'jsoneditor-text-errors'
|
||||
validationErrors.appendChild(table)
|
||||
|
||||
const tbody = document.createElement('tbody')
|
||||
table.appendChild(tbody)
|
||||
|
||||
errors.forEach(error => {
|
||||
let message
|
||||
if (typeof error === 'string') {
|
||||
message = '<td colspan="2"><pre>' + error + '</pre></td>'
|
||||
} else {
|
||||
message =
|
||||
'<td>' + (error.dataPath || '') + '</td>' +
|
||||
'<td><pre>' + error.message + '</pre></td>'
|
||||
}
|
||||
|
||||
let line
|
||||
|
||||
if (!isNaN(error.line)) {
|
||||
|
@ -108,7 +104,36 @@ export class ErrorTable {
|
|||
trEl.className += ' validation-error'
|
||||
}
|
||||
|
||||
trEl.innerHTML = ('<td><button class="jsoneditor-schema-error"></button></td><td style="white-space:nowrap;">' + (!isNaN(line) ? ('Ln ' + line) : '') + '</td>' + message)
|
||||
const td1 = document.createElement('td')
|
||||
const button = document.createElement('button')
|
||||
button.className = 'jsoneditor-schema-error'
|
||||
td1.appendChild(button)
|
||||
trEl.appendChild(td1)
|
||||
|
||||
const td2 = document.createElement('td')
|
||||
td2.style = 'white-space: nowrap;'
|
||||
td2.textContent = (!isNaN(line) ? ('Ln ' + line) : '')
|
||||
trEl.appendChild(td2)
|
||||
|
||||
if (typeof error === 'string') {
|
||||
const td34 = document.createElement('td')
|
||||
td34.colSpan = 2
|
||||
const pre = document.createElement('pre')
|
||||
pre.appendChild(document.createTextNode(error))
|
||||
td34.appendChild(pre)
|
||||
trEl.appendChild(td34)
|
||||
} else {
|
||||
const td3 = document.createElement('td')
|
||||
td3.appendChild(document.createTextNode(error.dataPath || ''))
|
||||
trEl.appendChild(td3)
|
||||
|
||||
const td4 = document.createElement('td')
|
||||
const pre = document.createElement('pre')
|
||||
pre.appendChild(document.createTextNode(error.message))
|
||||
td4.appendChild(pre)
|
||||
trEl.appendChild(td4)
|
||||
}
|
||||
|
||||
trEl.onclick = () => {
|
||||
this.onFocusLine(line)
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ const VanillaPicker = require('./vanilla-picker') // may be undefined in case of
|
|||
const { treeModeMixins } = require('./treemode')
|
||||
const { textModeMixins } = require('./textmode')
|
||||
const { previewModeMixins } = require('./previewmode')
|
||||
const { clear, extend, getInternetExplorerVersion, parse } = require('./util')
|
||||
const { clear, extend, getInnerText, getInternetExplorerVersion, parse } = require('./util')
|
||||
const { tryRequireAjv } = require('./tryRequireAjv')
|
||||
const { showTransformModal } = require('./showTransformModal')
|
||||
const { showSortModal } = require('./showSortModal')
|
||||
|
@ -184,7 +184,7 @@ JSONEditor.VALID_OPTIONS = [
|
|||
'colorPicker', 'onColorPicker',
|
||||
'timestampTag', 'timestampFormat',
|
||||
'escapeUnicode', 'history', 'search', 'mode', 'modes', 'name', 'indentation',
|
||||
'sortObjectKeys', 'navigationBar', 'statusBar', 'mainMenuBar', 'languages', 'language', 'enableSort', 'enableTransform',
|
||||
'sortObjectKeys', 'navigationBar', 'statusBar', 'mainMenuBar', 'languages', 'language', 'enableSort', 'enableTransform', 'limitDragging',
|
||||
'maxVisibleChilds', 'onValidationError',
|
||||
'modalAnchor', 'popupAnchor',
|
||||
'createQuery', 'executeQuery', 'queryDescription'
|
||||
|
@ -484,6 +484,7 @@ JSONEditor.VanillaPicker = VanillaPicker
|
|||
// expose some utils (this is undocumented, unofficial)
|
||||
JSONEditor.showTransformModal = showTransformModal
|
||||
JSONEditor.showSortModal = showSortModal
|
||||
JSONEditor.getInnerText = getInnerText
|
||||
|
||||
// default export for TypeScript ES6 projects
|
||||
JSONEditor.default = JSONEditor
|
||||
|
|
|
@ -83,7 +83,7 @@ export class ModeSwitcher {
|
|||
const box = document.createElement('button')
|
||||
box.type = 'button'
|
||||
box.className = 'jsoneditor-modes jsoneditor-separator'
|
||||
box.innerHTML = currentTitle + ' ▾'
|
||||
box.textContent = currentTitle + ' \u25BE'
|
||||
box.title = translate('modeEditorTitle')
|
||||
box.onclick = () => {
|
||||
const menu = new ContextMenu(items)
|
||||
|
|
117
src/js/Node.js
117
src/js/Node.js
|
@ -104,9 +104,17 @@ export class Node {
|
|||
if (typeof editable === 'boolean') {
|
||||
this.editable.field = editable
|
||||
this.editable.value = editable
|
||||
} else {
|
||||
} else if (typeof editable === 'object' && editable !== null) {
|
||||
if (typeof editable.field === 'boolean') this.editable.field = editable.field
|
||||
if (typeof editable.value === 'boolean') this.editable.value = editable.value
|
||||
} else {
|
||||
console.error(
|
||||
'Invalid return value for function onEditable.',
|
||||
'Actual value:', editable, '.',
|
||||
'Either a boolean or object { field: boolean, value: boolean } expected.')
|
||||
|
||||
this.editable.field = false
|
||||
this.editable.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1507,6 +1515,12 @@ export class Node {
|
|||
|
||||
if (this.dom.value && this.type !== 'array' && this.type !== 'object') {
|
||||
this.valueInnerText = getInnerText(this.dom.value)
|
||||
|
||||
if (this.valueInnerText === '' && this.dom.value.innerHTML !== '') {
|
||||
// When clearing the contents, often a <br/> remains, messing up the
|
||||
// styling of the empty text box. Therefore we remove the <br/>
|
||||
this.dom.value.textContent = ''
|
||||
}
|
||||
}
|
||||
|
||||
if (this.valueInnerText !== undefined) {
|
||||
|
@ -1712,14 +1726,14 @@ export class Node {
|
|||
// Create the default empty option
|
||||
this.dom.select.option = document.createElement('option')
|
||||
this.dom.select.option.value = ''
|
||||
this.dom.select.option.innerHTML = '--'
|
||||
this.dom.select.option.textContent = '--'
|
||||
this.dom.select.appendChild(this.dom.select.option)
|
||||
|
||||
// Iterate all enum values and add them as options
|
||||
for (let i = 0; i < this.enum.length; i++) {
|
||||
this.dom.select.option = document.createElement('option')
|
||||
this.dom.select.option.value = this.enum[i]
|
||||
this.dom.select.option.innerHTML = this.enum[i]
|
||||
this.dom.select.option.textContent = this.enum[i]
|
||||
if (this.dom.select.option.value === this.value) {
|
||||
this.dom.select.option.selected = true
|
||||
}
|
||||
|
@ -1741,7 +1755,7 @@ export class Node {
|
|||
) {
|
||||
this.valueFieldHTML = this.dom.tdValue.innerHTML
|
||||
this.dom.tdValue.style.visibility = 'hidden'
|
||||
this.dom.tdValue.innerHTML = ''
|
||||
this.dom.tdValue.textContent = ''
|
||||
} else {
|
||||
delete this.valueFieldHTML
|
||||
}
|
||||
|
@ -1771,12 +1785,10 @@ export class Node {
|
|||
this.dom.tdColor.appendChild(this.dom.color)
|
||||
|
||||
this.dom.tdValue.parentNode.insertBefore(this.dom.tdColor, this.dom.tdValue)
|
||||
|
||||
// this is a bit hacky, overriding the text color like this. find a nicer solution
|
||||
this.dom.value.style.color = '#1A1A1A'
|
||||
}
|
||||
|
||||
// update the color background
|
||||
// update styling of value and color background
|
||||
addClassName(this.dom.value, 'jsoneditor-color-value')
|
||||
this.dom.color.style.backgroundColor = value
|
||||
} else {
|
||||
// cleanup color picker when displayed
|
||||
|
@ -1800,7 +1812,7 @@ export class Node {
|
|||
})
|
||||
}
|
||||
if (!title) {
|
||||
this.dom.date.innerHTML = new Date(value).toISOString()
|
||||
this.dom.date.textContent = new Date(value).toISOString()
|
||||
} else {
|
||||
while (this.dom.date.firstChild) {
|
||||
this.dom.date.removeChild(this.dom.date.firstChild)
|
||||
|
@ -1829,7 +1841,7 @@ export class Node {
|
|||
delete this.dom.tdColor
|
||||
delete this.dom.color
|
||||
|
||||
this.dom.value.style.color = ''
|
||||
removeClassName(this.dom.value, 'jsoneditor-color-value')
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1848,8 +1860,8 @@ export class Node {
|
|||
domField.title = tooltip
|
||||
}
|
||||
|
||||
// make backgound color lightgray when empty
|
||||
const isEmpty = (String(this.field) === '' && this.parent.type !== 'array')
|
||||
// make background color lightgray when empty
|
||||
const isEmpty = (String(this.field) === '' && this.parent && this.parent.type !== 'array')
|
||||
if (isEmpty) {
|
||||
addClassName(domField, 'jsoneditor-empty')
|
||||
} else {
|
||||
|
@ -1884,6 +1896,12 @@ export class Node {
|
|||
|
||||
if (this.dom.field && this.fieldEditable) {
|
||||
this.fieldInnerText = getInnerText(this.dom.field)
|
||||
|
||||
if (this.fieldInnerText === '' && this.dom.field.innerHTML !== '') {
|
||||
// When clearing the contents, often a <br/> remains, messing up the
|
||||
// styling of the empty text box. Therefore we remove the <br/>
|
||||
this.dom.field.textContent = ''
|
||||
}
|
||||
}
|
||||
|
||||
if (this.fieldInnerText !== undefined) {
|
||||
|
@ -2213,8 +2231,17 @@ export class Node {
|
|||
fieldText = ''
|
||||
}
|
||||
}
|
||||
domField.innerHTML = this._escapeHTML(fieldText)
|
||||
|
||||
const escapedField = this._escapeHTML(fieldText)
|
||||
if (
|
||||
document.activeElement !== domField ||
|
||||
escapedField !== this._unescapeHTML(getInnerText(domField))
|
||||
) {
|
||||
// only update if it not has the focus or when there is an actual change,
|
||||
// else you would needlessly loose the caret position when changing tabs
|
||||
// or whilst typing
|
||||
domField.innerHTML = escapedField
|
||||
}
|
||||
this._updateSchema()
|
||||
}
|
||||
|
||||
|
@ -2224,7 +2251,16 @@ export class Node {
|
|||
if (this.type === 'array' || this.type === 'object') {
|
||||
this.updateNodeName()
|
||||
} else {
|
||||
domValue.innerHTML = this._escapeHTML(this.value)
|
||||
const escapedValue = this._escapeHTML(this.value)
|
||||
if (
|
||||
document.activeElement !== domValue ||
|
||||
escapedValue !== this._unescapeHTML(getInnerText(domValue))
|
||||
) {
|
||||
// only update if it not has the focus or when there is an actual change,
|
||||
// else you would needlessly loose the caret position when changing tabs
|
||||
// or whilst typing
|
||||
domValue.innerHTML = escapedValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2321,7 +2357,7 @@ export class Node {
|
|||
child.index = index
|
||||
const childField = child.dom.field
|
||||
if (childField) {
|
||||
childField.innerHTML = index
|
||||
childField.textContent = index
|
||||
}
|
||||
})
|
||||
} else if (this.type === 'object') {
|
||||
|
@ -2347,10 +2383,10 @@ export class Node {
|
|||
|
||||
if (this.type === 'array') {
|
||||
domValue = document.createElement('div')
|
||||
domValue.innerHTML = '[...]'
|
||||
domValue.textContent = '[...]'
|
||||
} else if (this.type === 'object') {
|
||||
domValue = document.createElement('div')
|
||||
domValue.innerHTML = '{...}'
|
||||
domValue.textContent = '{...}'
|
||||
} else {
|
||||
if (!this.editable.value && isUrl(this.value)) {
|
||||
// create a link in case of read-only editor and value containing an url
|
||||
|
@ -2497,14 +2533,14 @@ export class Node {
|
|||
|
||||
// swap the value of a boolean when the checkbox displayed left is clicked
|
||||
if (type === 'change' && target === dom.checkbox) {
|
||||
this.dom.value.innerHTML = !this.value
|
||||
this.dom.value.textContent = String(!this.value)
|
||||
this._getDomValue()
|
||||
this._updateDomDefault()
|
||||
}
|
||||
|
||||
// update the value of the node based on the selected option
|
||||
if (type === 'change' && target === dom.select) {
|
||||
this.dom.value.innerHTML = dom.select.value
|
||||
this.dom.value.innerHTML = this._escapeHTML(dom.select.value)
|
||||
this._getDomValue()
|
||||
this._updateDomValue()
|
||||
}
|
||||
|
@ -2519,9 +2555,11 @@ export class Node {
|
|||
this._getDomValue()
|
||||
this._clearValueError()
|
||||
this._updateDomValue()
|
||||
|
||||
const escapedValue = this._escapeHTML(this.value)
|
||||
if (domValue.innerHTML !== escapedValue) {
|
||||
// only update if changed, else you lose the caret position when changing tabs for example
|
||||
if (escapedValue !== this._unescapeHTML(getInnerText(domValue))) {
|
||||
// only update when there is an actual change, else you loose the
|
||||
// caret position when changing tabs or whilst typing
|
||||
domValue.innerHTML = escapedValue
|
||||
}
|
||||
break
|
||||
|
@ -2544,7 +2582,7 @@ export class Node {
|
|||
// if read-only, we use the regular click behavior of an anchor
|
||||
if (isUrl(this.value)) {
|
||||
event.preventDefault()
|
||||
window.open(this.value, '_blank')
|
||||
window.open(this.value, '_blank', 'noopener')
|
||||
}
|
||||
}
|
||||
break
|
||||
|
@ -2572,9 +2610,11 @@ export class Node {
|
|||
case 'blur': {
|
||||
this._getDomField(true)
|
||||
this._updateDomField()
|
||||
|
||||
const escapedField = this._escapeHTML(this.field)
|
||||
if (domField.innerHTML !== escapedField) {
|
||||
// only update if changed, else you lose the caret position when changing tabs for example
|
||||
if (escapedField !== this._unescapeHTML(getInnerText(domField))) {
|
||||
// only update when there is an actual change, else you loose the
|
||||
// caret position when changing tabs or whilst typing
|
||||
domField.innerHTML = escapedField
|
||||
}
|
||||
break
|
||||
|
@ -2697,7 +2737,7 @@ export class Node {
|
|||
if (target === this.dom.value) {
|
||||
if (!this.editable.value || event.ctrlKey) {
|
||||
if (isUrl(this.value)) {
|
||||
window.open(this.value, '_blank')
|
||||
window.open(this.value, '_blank', 'noopener')
|
||||
handled = true
|
||||
}
|
||||
}
|
||||
|
@ -3885,7 +3925,7 @@ export class Node {
|
|||
const json = this.getValue()
|
||||
|
||||
showTransformModal({
|
||||
anchor: modalAnchor || DEFAULT_MODAL_ANCHOR,
|
||||
container: modalAnchor || DEFAULT_MODAL_ANCHOR,
|
||||
json,
|
||||
queryDescription, // can be undefined
|
||||
createQuery,
|
||||
|
@ -4015,7 +4055,7 @@ export class Node {
|
|||
}
|
||||
}
|
||||
|
||||
this.dom.value.innerHTML = (this.type === 'object')
|
||||
this.dom.value.textContent = (this.type === 'object')
|
||||
? ('{' + (nodeName || count) + '}')
|
||||
: ('[' + (nodeName || count) + ']')
|
||||
}
|
||||
|
@ -4084,13 +4124,13 @@ Node.onDragStart = (nodes, event) => {
|
|||
const offsetY = getAbsoluteTop(draggedNode.dom.tr) - getAbsoluteTop(firstNode.dom.tr)
|
||||
|
||||
if (!editor.mousemove) {
|
||||
editor.mousemove = addEventListener(window, 'mousemove', event => {
|
||||
editor.mousemove = addEventListener(event.view, 'mousemove', event => {
|
||||
Node.onDrag(nodes, event)
|
||||
})
|
||||
}
|
||||
|
||||
if (!editor.mouseup) {
|
||||
editor.mouseup = addEventListener(window, 'mouseup', event => {
|
||||
editor.mouseup = addEventListener(event.view, 'mouseup', event => {
|
||||
Node.onDragEnd(nodes, event)
|
||||
})
|
||||
}
|
||||
|
@ -4175,7 +4215,10 @@ Node.onDrag = (nodes, event) => {
|
|||
}
|
||||
}
|
||||
|
||||
if (nodePrev) {
|
||||
if (
|
||||
nodePrev &&
|
||||
(editor.options.limitDragging === false || nodePrev.parent === nodes[0].parent)
|
||||
) {
|
||||
nodes.forEach(node => {
|
||||
nodePrev.parent.moveBefore(node, nodePrev)
|
||||
})
|
||||
|
@ -4251,7 +4294,11 @@ Node.onDrag = (nodes, event) => {
|
|||
}
|
||||
|
||||
// move the node when its position is changed
|
||||
if (nodeNext && nodeNext.dom.tr && trLast.nextSibling !== nodeNext.dom.tr) {
|
||||
if (
|
||||
nodeNext &&
|
||||
(editor.options.limitDragging === false || nodeNext.parent === nodes[0].parent) &&
|
||||
nodeNext.dom.tr && nodeNext.dom.tr !== trLast.nextSibling
|
||||
) {
|
||||
nodes.forEach(node => {
|
||||
nodeNext.parent.moveBefore(node, nodeNext)
|
||||
})
|
||||
|
@ -4339,11 +4386,11 @@ Node.onDragEnd = (nodes, event) => {
|
|||
delete editor.drag
|
||||
|
||||
if (editor.mousemove) {
|
||||
removeEventListener(window, 'mousemove', editor.mousemove)
|
||||
removeEventListener(event.view, 'mousemove', editor.mousemove)
|
||||
delete editor.mousemove
|
||||
}
|
||||
if (editor.mouseup) {
|
||||
removeEventListener(window, 'mouseup', editor.mouseup)
|
||||
removeEventListener(event.view, 'mouseup', editor.mouseup)
|
||||
delete editor.mouseup
|
||||
}
|
||||
|
||||
|
@ -4409,7 +4456,7 @@ Node._findSchema = (schema, schemaRefs, path) => {
|
|||
|
||||
if (typeof key === 'string' && childSchema.patternProperties && !(childSchema.properties && key in childSchema.properties)) {
|
||||
for (const prop in childSchema.patternProperties) {
|
||||
if (key.match(prop)) {
|
||||
if (key.match(prop) && (foundSchema.properties || foundSchema.patternProperties)) {
|
||||
foundSchema = Node._findSchema(childSchema.patternProperties[prop], schemaRefs, nextPath)
|
||||
}
|
||||
}
|
||||
|
@ -4516,7 +4563,7 @@ Node.onDuplicate = nodes => {
|
|||
if (clones[0].parent.type === 'object') {
|
||||
// when duplicating a single object property,
|
||||
// set focus to the field and keep the original field name
|
||||
clones[0].dom.field.innerHTML = nodes[0].field
|
||||
clones[0].dom.field.innerHTML = nodes[0]._escapeHTML(nodes[0].field)
|
||||
clones[0].focus('field')
|
||||
} else {
|
||||
clones[0].focus()
|
||||
|
|
|
@ -229,16 +229,16 @@ export class SearchBox {
|
|||
if (text !== undefined) {
|
||||
const resultCount = this.results.length
|
||||
if (resultCount === 0) {
|
||||
this.dom.results.innerHTML = 'no results'
|
||||
this.dom.results.textContent = 'no\u00A0results'
|
||||
} else if (resultCount === 1) {
|
||||
this.dom.results.innerHTML = '1 result'
|
||||
this.dom.results.textContent = '1\u00A0result'
|
||||
} else if (resultCount > MAX_SEARCH_RESULTS) {
|
||||
this.dom.results.innerHTML = MAX_SEARCH_RESULTS + '+ results'
|
||||
this.dom.results.textContent = MAX_SEARCH_RESULTS + '+\u00A0results'
|
||||
} else {
|
||||
this.dom.results.innerHTML = resultCount + ' results'
|
||||
this.dom.results.textContent = resultCount + '\u00A0results'
|
||||
}
|
||||
} else {
|
||||
this.dom.results.innerHTML = ''
|
||||
this.dom.results.textContent = ''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ export class TreePath {
|
|||
* Reset component to initial status
|
||||
*/
|
||||
reset () {
|
||||
this.path.innerHTML = translate('selectNode')
|
||||
this.path.textContent = translate('selectNode')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -38,7 +38,7 @@ export class TreePath {
|
|||
setPath (pathObjs) {
|
||||
const me = this
|
||||
|
||||
this.path.innerHTML = ''
|
||||
this.path.textContent = ''
|
||||
|
||||
if (pathObjs && pathObjs.length) {
|
||||
pathObjs.forEach((pathObj, idx) => {
|
||||
|
@ -53,7 +53,7 @@ export class TreePath {
|
|||
if (pathObj.children.length) {
|
||||
sepEl = document.createElement('span')
|
||||
sepEl.className = 'jsoneditor-treepath-seperator'
|
||||
sepEl.innerHTML = '►'
|
||||
sepEl.textContent = '\u25BA'
|
||||
|
||||
sepEl.onclick = () => {
|
||||
me.contentMenuClicked = true
|
||||
|
@ -82,7 +82,7 @@ export class TreePath {
|
|||
const showAllBtn = document.createElement('span')
|
||||
showAllBtn.className = 'jsoneditor-treepath-show-all-btn'
|
||||
showAllBtn.title = 'show all path'
|
||||
showAllBtn.innerHTML = '...'
|
||||
showAllBtn.textContent = '...'
|
||||
showAllBtn.onclick = _onShowAllClick.bind(me, pathObjs)
|
||||
me.path.insertBefore(showAllBtn, me.path.firstChild)
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ if (window.ace) {
|
|||
|
||||
// load required Ace plugins
|
||||
require('ace-builds/src-noconflict/mode-json')
|
||||
require('ace-builds/src-noconflict/mode-text')
|
||||
require('ace-builds/src-noconflict/ext-searchbox')
|
||||
|
||||
// embed Ace json worker
|
||||
|
|
|
@ -64,7 +64,7 @@ export function appendNodeFactory (Node) {
|
|||
// a cell for the contents (showing text 'empty')
|
||||
const tdAppend = document.createElement('td')
|
||||
const domText = document.createElement('div')
|
||||
domText.innerHTML = '(' + translate('empty') + ')'
|
||||
domText.appendChild(document.createTextNode('(' + translate('empty') + ')'))
|
||||
domText.className = 'jsoneditor-readonly'
|
||||
tdAppend.appendChild(domText)
|
||||
dom.td = tdAppend
|
||||
|
@ -100,7 +100,7 @@ export function appendNodeFactory (Node) {
|
|||
|
||||
const domText = dom.text
|
||||
if (domText) {
|
||||
domText.innerHTML = '(' + translate('empty') + ' ' + this.parent.type + ')'
|
||||
domText.firstChild.nodeValue = '(' + translate('empty') + ' ' + this.parent.type + ')'
|
||||
}
|
||||
|
||||
// attach or detach the contents of the append node:
|
||||
|
|
|
@ -187,7 +187,7 @@ var util = {
|
|||
var i;
|
||||
for (i in a)
|
||||
if (i in el) el[i] = a[i];
|
||||
else if ("html" === i) el.innerHTML = a[i];
|
||||
else if ("html" === i) el.textContent = a[i];
|
||||
else if ("text" === i) {
|
||||
var t = d.createTextNode(a[i]);
|
||||
el.appendChild(t);
|
||||
|
@ -287,7 +287,7 @@ function appendItem(item, parent, custom) {
|
|||
|
||||
util.removeClass(item, "excluded");
|
||||
if (!custom) {
|
||||
item.innerHTML = item.textContent;
|
||||
item.textContent = item.textContent + ''; // clear highlighting
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -829,7 +829,7 @@ var addTag = function(item) {
|
|||
docFrag.appendChild(tg);
|
||||
});
|
||||
|
||||
this.label.innerHTML = "";
|
||||
this.label.textContent = "";
|
||||
|
||||
} else {
|
||||
docFrag.appendChild(tag);
|
||||
|
@ -917,7 +917,7 @@ var clearSearch = function() {
|
|||
util.removeClass(item, "excluded");
|
||||
// Remove the span element for underlining matched items
|
||||
if (!this.customOption) {
|
||||
item.innerHTML = item.textContent;
|
||||
item.textContent = item.textContent + ''; // clear highlighting
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
|
@ -926,15 +926,21 @@ var clearSearch = function() {
|
|||
/**
|
||||
* Query matching for searches
|
||||
* @param {string} query
|
||||
* @param {HTMLOptionElement} option
|
||||
* @return {bool}
|
||||
* @param {string} text
|
||||
*/
|
||||
var match = function(query, option) {
|
||||
var result = new RegExp(query, "i").exec(option.textContent);
|
||||
var match = function(query, text) {
|
||||
var result = new RegExp(query, "i").exec(text);
|
||||
if (result) {
|
||||
return option.textContent.replace(result[0], "<span class='selectr-match'>" + result[0] + "</span>");
|
||||
var start = result.index;
|
||||
var end = result.index + result[0].length;
|
||||
|
||||
return {
|
||||
before: text.substring(0, start),
|
||||
match: text.substring(start, end),
|
||||
after: text.substring(end)
|
||||
};
|
||||
}
|
||||
return false;
|
||||
return null;
|
||||
};
|
||||
|
||||
// Main Lib
|
||||
|
@ -1383,7 +1389,7 @@ Selectr.prototype.destroy = function() {
|
|||
}
|
||||
|
||||
if (this.config.data) {
|
||||
this.el.innerHTML = "";
|
||||
this.el.textContent = "";
|
||||
}
|
||||
|
||||
// Remove the className from select element
|
||||
|
@ -1457,7 +1463,7 @@ Selectr.prototype.select = function(index) {
|
|||
addTag.call(this, item);
|
||||
} else {
|
||||
var data = this.data ? this.data[index] : option;
|
||||
this.label.innerHTML = this.customSelected ? this.config.renderSelection(data) : option.textContent;
|
||||
this.label.textContent = this.customSelected ? this.config.renderSelection(data) : option.textContent;
|
||||
|
||||
this.selectedValue = option.value;
|
||||
this.selectedIndex = index;
|
||||
|
@ -1519,7 +1525,7 @@ Selectr.prototype.deselect = function(index, force) {
|
|||
return false;
|
||||
}
|
||||
|
||||
this.label.innerHTML = "";
|
||||
this.label.textContent = "";
|
||||
this.selectedValue = null;
|
||||
|
||||
this.el.selectedIndex = this.selectedIndex = -1;
|
||||
|
@ -1805,7 +1811,17 @@ Selectr.prototype.search = function(string) {
|
|||
|
||||
// Underline the matching results
|
||||
if (!this.customOption) {
|
||||
item.innerHTML = match(string, option);
|
||||
item.textContent = ''
|
||||
|
||||
var result = match(string, option.textContent);
|
||||
if (result) {
|
||||
item.appendChild(document.createTextNode(result.before));
|
||||
var highlight = document.createElement('span');
|
||||
highlight.className = 'selectr-match';
|
||||
highlight.appendChild(document.createTextNode(result.match));
|
||||
item.appendChild(highlight);
|
||||
item.appendChild(document.createTextNode(result.after));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
util.addClass(item, "excluded");
|
||||
|
@ -2081,7 +2097,7 @@ Selectr.prototype.setPlaceholder = function(placeholder) {
|
|||
placeholder = "No options available";
|
||||
}
|
||||
|
||||
this.placeEl.innerHTML = placeholder;
|
||||
this.placeEl.textContent = placeholder;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -2119,7 +2135,7 @@ Selectr.prototype.setMessage = function(message, close) {
|
|||
*/
|
||||
Selectr.prototype.removeMessage = function() {
|
||||
util.removeClass(this.container, "notice");
|
||||
this.notice.innerHTML = "";
|
||||
this.notice.textContent = "";
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -52,7 +52,7 @@ export function autocomplete (config) {
|
|||
refresh: function (token, array) {
|
||||
elem.style.visibility = 'hidden'
|
||||
ix = 0
|
||||
elem.innerHTML = ''
|
||||
elem.textContent = ''
|
||||
const vph = (window.innerHeight || document.documentElement.clientHeight)
|
||||
const rect = elem.parentNode.getBoundingClientRect()
|
||||
const distanceToTop = rect.top - 6 // heuristic give 6px
|
||||
|
@ -71,7 +71,11 @@ export function autocomplete (config) {
|
|||
divRow.onmouseout = onMouseOut
|
||||
divRow.onmousedown = onMouseDown
|
||||
divRow.__hint = row
|
||||
divRow.innerHTML = row.substring(0, token.length) + '<b>' + row.substring(token.length) + '</b>'
|
||||
divRow.textContent = ''
|
||||
divRow.appendChild(document.createTextNode(row.substring(0, token.length)))
|
||||
const b = document.createElement('b')
|
||||
b.appendChild(document.createTextNode(row.substring(token.length)))
|
||||
divRow.appendChild(b)
|
||||
elem.appendChild(divRow)
|
||||
return divRow
|
||||
})
|
||||
|
@ -153,13 +157,7 @@ export function autocomplete (config) {
|
|||
document.body.appendChild(spacer)
|
||||
}
|
||||
|
||||
// Used to encode an HTML string into a plain text.
|
||||
// taken from http://stackoverflow.com/questions/1219860/javascript-jquery-html-encoding
|
||||
spacer.innerHTML = String(text).replace(/&/g, '&')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
spacer.textContent = text
|
||||
return spacer.getBoundingClientRect().right
|
||||
}
|
||||
|
||||
|
|
119
src/js/i18n.js
119
src/js/i18n.js
|
@ -4,7 +4,7 @@
|
|||
|
||||
import './polyfills'
|
||||
|
||||
const _locales = ['en', 'pt-BR', 'zh-CN', 'tr', 'ja', 'fr-FR']
|
||||
const _locales = ['en', 'pt-BR', 'zh-CN', 'tr', 'ja', 'fr-FR', 'de']
|
||||
const _defs = {
|
||||
en: {
|
||||
array: 'Array',
|
||||
|
@ -102,7 +102,9 @@ const _defs = {
|
|||
modePreviewText: 'Preview',
|
||||
modePreviewTitle: 'Switch to preview mode',
|
||||
examples: 'Examples',
|
||||
default: 'Default'
|
||||
default: 'Default',
|
||||
containsInvalidProperties: 'Contains invalid properties',
|
||||
containsInvalidItems: 'Contains invalid items'
|
||||
},
|
||||
'zh-CN': {
|
||||
array: '数组',
|
||||
|
@ -196,7 +198,9 @@ const _defs = {
|
|||
modePreviewText: '预览',
|
||||
modePreviewTitle: '切换至预览模式',
|
||||
examples: '例子',
|
||||
default: '缺省'
|
||||
default: '缺省',
|
||||
containsInvalidProperties: '包含无效的属性',
|
||||
containsInvalidItems: '包含无效项目'
|
||||
},
|
||||
'pt-BR': {
|
||||
array: 'Lista',
|
||||
|
@ -276,7 +280,9 @@ const _defs = {
|
|||
'Campo do tipo nao é determinado através do seu valor, ' +
|
||||
'mas sempre retornara um texto.',
|
||||
examples: 'Exemplos',
|
||||
default: 'Revelia'
|
||||
default: 'Revelia',
|
||||
containsInvalidProperties: 'Contém propriedades inválidas',
|
||||
containsInvalidItems: 'Contém itens inválidos'
|
||||
},
|
||||
tr: {
|
||||
array: 'Dizin',
|
||||
|
@ -363,7 +369,9 @@ const _defs = {
|
|||
modeViewText: 'Görünüm',
|
||||
modeViewTitle: 'Ağaç görünümüne geç',
|
||||
examples: 'Örnekler',
|
||||
default: 'Varsayılan'
|
||||
default: 'Varsayılan',
|
||||
containsInvalidProperties: 'Geçersiz özellikler içeriyor',
|
||||
containsInvalidItems: 'Geçersiz öğeler içeriyor'
|
||||
},
|
||||
ja: {
|
||||
array: '配列',
|
||||
|
@ -454,7 +462,9 @@ const _defs = {
|
|||
modePreviewText: 'プレビュー',
|
||||
modePreviewTitle: 'プレビューに切り替え',
|
||||
examples: '例',
|
||||
default: 'デフォルト'
|
||||
default: 'デフォルト',
|
||||
containsInvalidProperties: '無効なプロパティが含まれています',
|
||||
containsInvalidItems: '無効なアイテムが含まれています'
|
||||
},
|
||||
'fr-FR': {
|
||||
array: 'Liste',
|
||||
|
@ -549,7 +559,102 @@ const _defs = {
|
|||
modePreviewText: 'Prévisualisation',
|
||||
modePreviewTitle: 'Activer mode prévisualiser',
|
||||
examples: 'Exemples',
|
||||
default: 'Défaut'
|
||||
default: 'Défaut',
|
||||
containsInvalidProperties: 'Contient des propriétés non valides',
|
||||
containsInvalidItems: 'Contient des éléments invalides'
|
||||
},
|
||||
de: {
|
||||
array: 'Auflistung',
|
||||
auto: 'Auto',
|
||||
appendText: 'anhängen',
|
||||
appendTitle: 'Fügen Sie nach diesem Feld ein neues Feld mit dem Typ \'auto\' ein (Strg+Umschalt+Ein)',
|
||||
appendSubmenuTitle: 'Wählen Sie den Typ des neuen Feldes',
|
||||
appendTitleAuto: 'Ein neues Feld vom Typ \'auto\' hinzufügen (Strg+Umschalt+Ein)',
|
||||
ascending: 'Aufsteigend',
|
||||
ascendingTitle: 'Sortieren Sie die Elemente dieses ${type} in aufsteigender Reihenfolge',
|
||||
actionsMenu: 'Klicken Sie zum Öffnen des Aktionsmenüs (Strg+M)',
|
||||
cannotParseFieldError: 'Feld kann nicht in JSON geparst werden',
|
||||
cannotParseValueError: 'Wert kann nicht in JSON geparst werden',
|
||||
collapseAll: 'Alle Felder zuklappen',
|
||||
compactTitle: 'JSON-Daten verdichten, alle Leerzeichen entfernen (Strg+Umschalt+\\)',
|
||||
descending: 'Absteigend',
|
||||
descendingTitle: 'Sortieren Sie die Elemente dieses ${type} in absteigender Reihenfolge',
|
||||
drag: 'Ziehen, um dieses Feld zu verschieben (Alt+Umschalt+Pfeile)',
|
||||
duplicateKey: 'Doppelter Schlüssel',
|
||||
duplicateText: 'Duplikat',
|
||||
duplicateTitle: 'Ausgewählte Felder duplizieren (Strg+D)',
|
||||
duplicateField: 'Dieses Feld duplizieren (Strg+D)',
|
||||
duplicateFieldError: 'Doppelter Feldname',
|
||||
empty: 'leer',
|
||||
expandAll: 'Alle Felder anzeigen',
|
||||
expandTitle: 'Klicken Sie, um dieses Feld zu erweitern/zu kollabieren (Strg+E). \nStrg+Klicken Sie, um dieses Feld einschließlich aller Elemente zu erweitern/zu kollabieren.',
|
||||
formatTitle: 'JSON-Daten mit korrekter Einrückung und Zeilenvorschüben formatieren (Strg+\\)',
|
||||
insert: 'einfügen',
|
||||
insertTitle: 'Fügen Sie vor diesem Feld ein neues Feld mit dem Typ \'auto\' ein (Strg+Einfg)',
|
||||
insertSub: 'Wählen Sie den Typ des neuen Feldes',
|
||||
object: 'Objekt',
|
||||
ok: 'Ok',
|
||||
redo: 'Wiederholen (Strg+Umschalt+Z)',
|
||||
removeText: 'entfernen',
|
||||
removeTitle: 'Ausgewählte Felder entfernen (Strg+Entf)',
|
||||
removeField: 'Dieses Feld entfernen (Strg+Entf)',
|
||||
repairTitle: 'JSON reparieren: Anführungszeichen und Escape-Zeichen korrigieren, Kommentare und JSONP-Notation entfernen, JavaScript-Objekte in JSON umwandeln.',
|
||||
searchTitle: 'Suchfelder und Werte',
|
||||
searchNextResultTitle: 'Nächstes Ergebnis (Enter)',
|
||||
searchPreviousResultTitle: 'Vorheriges Ergebnis (Umschalt + Eingabe)',
|
||||
selectNode: 'Wählen Sie einen Knoten aus...',
|
||||
showAll: 'alle anzeigen',
|
||||
showMore: 'mehr anzeigen',
|
||||
showMoreStatus: 'Anzeige von ${visibleChilds} von ${totalChilds}-Elementen.',
|
||||
sort: 'Sortieren',
|
||||
sortTitle: 'Sortieren Sie die Elemente dieses ${type}',
|
||||
sortTitleShort: 'Inhalt sortieren',
|
||||
sortFieldLabel: 'Feld:',
|
||||
sortDirectionLabel: 'Richtung:',
|
||||
sortFieldTitle: 'Wählen Sie das verschachtelte Feld, nach dem das Array oder Objekt sortiert werden soll.',
|
||||
sortAscending: 'Aufsteigend',
|
||||
sortAscendingTitle: 'Sortieren Sie das ausgewählte Feld in aufsteigender Reihenfolge',
|
||||
sortDescending: 'Absteigend',
|
||||
sortDescendingTitle: 'Sortieren Sie das ausgewählte Feld in absteigender Reihenfolge',
|
||||
string: 'Zeichenfolge',
|
||||
transform: 'Verwandeln',
|
||||
transformTitle: 'Die Elemente dieses ${type} filtern, sortieren oder transformieren',
|
||||
transformTitleShort: 'Inhalte filtern, sortieren oder transformieren',
|
||||
extract: 'Auszug',
|
||||
extractTitle: 'Extrahieren Sie diesen ${type}',
|
||||
transformQueryTitle: 'Eine JMESPath-Abfrage eingeben',
|
||||
transformWizardLabel: 'Zauberer',
|
||||
transformWizardFilter: 'Filter',
|
||||
transformWizardSortBy: 'Sortieren nach',
|
||||
transformWizardSelectFields: 'Felder auswählen',
|
||||
transformQueryLabel: 'Anfrage',
|
||||
transformPreviewLabel: 'Vorschau',
|
||||
type: 'Geben Sie ein.',
|
||||
typeTitle: 'Ändern Sie den Typ dieses Feldes',
|
||||
openUrl: 'Strg+Klicken oder Strg+Eingabe, um die URL in einem neuen Fenster zu öffnen',
|
||||
undo: 'Letzte Aktion rückgängig machen (Strg+Z)',
|
||||
validationCannotMove: 'Kann ein Feld nicht in ein Kind seiner selbst verschieben',
|
||||
autoType: 'Feldtyp "auto". Der Feldtyp wird automatisch aus dem Wert bestimmt und kann ein String, eine Zahl, boolesch oder null sein.',
|
||||
objectType: 'Feldtyp "Objekt". Ein Objekt enthält eine ungeordnete Menge von Schlüssel/Wert-Paaren.',
|
||||
arrayType: 'Feldtyp "Array". Ein Array enthält eine geordnete Sammlung von Werten.',
|
||||
stringType: 'Feldtyp "Zeichenfolge". Der Feldtyp wird nicht aus dem Wert bestimmt, sondern immer als Zeichenfolge zurückgegeben.',
|
||||
modeEditorTitle: 'Editor-Modus umschalten',
|
||||
modeCodeText: 'Code',
|
||||
modeCodeTitle: 'Umschalten auf Code-Highlighter',
|
||||
modeFormText: 'Formular',
|
||||
modeFormTitle: 'Zum Formular-Editor wechseln',
|
||||
modeTextText: 'Text',
|
||||
modeTextTitle: 'Zum Editor für einfachen Text wechseln',
|
||||
modeTreeText: 'Baum',
|
||||
modeTreeTitle: 'Zum Baum-Editor wechseln',
|
||||
modeViewText: 'Siehe',
|
||||
modeViewTitle: 'Zur Baumansicht wechseln',
|
||||
modePreviewText: 'Vorschau',
|
||||
modePreviewTitle: 'In den Vorschau-Modus wechseln',
|
||||
examples: 'Beispiele',
|
||||
default: 'Standardmäßig',
|
||||
containsInvalidProperties: 'Enthält ungültige Eigenschaften',
|
||||
containsInvalidItems: 'Enthält ungültige Elemente'
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,24 +25,32 @@ if (typeof Element !== 'undefined') {
|
|||
// simple polyfill for Array.findIndex
|
||||
if (!Array.prototype.findIndex) {
|
||||
// eslint-disable-next-line no-extend-native
|
||||
Array.prototype.findIndex = function (predicate) {
|
||||
for (let i = 0; i < this.length; i++) {
|
||||
const element = this[i]
|
||||
if (predicate.call(this, element, i, this)) {
|
||||
return i
|
||||
Object.defineProperty(Array.prototype, 'findIndex', {
|
||||
value: function (predicate) {
|
||||
for (let i = 0; i < this.length; i++) {
|
||||
const element = this[i]
|
||||
if (predicate.call(this, element, i, this)) {
|
||||
return i
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
return -1
|
||||
},
|
||||
configurable: true,
|
||||
writable: true
|
||||
})
|
||||
}
|
||||
|
||||
// Polyfill for Array.find
|
||||
if (!Array.prototype.find) {
|
||||
// eslint-disable-next-line no-extend-native
|
||||
Array.prototype.find = function (predicate) {
|
||||
const i = this.findIndex(predicate)
|
||||
return this[i]
|
||||
}
|
||||
Object.defineProperty(Array.prototype, 'find', {
|
||||
value: function (predicate) {
|
||||
const i = this.findIndex(predicate)
|
||||
return this[i]
|
||||
},
|
||||
configurable: true,
|
||||
writable: true
|
||||
})
|
||||
}
|
||||
|
||||
// Polyfill for String.trim
|
||||
|
|
|
@ -100,7 +100,7 @@ previewmode.create = function (container, options = {}) {
|
|||
this.dom.busy = document.createElement('div')
|
||||
this.dom.busy.className = 'jsoneditor-busy'
|
||||
this.dom.busyContent = document.createElement('span')
|
||||
this.dom.busyContent.innerHTML = 'busy...'
|
||||
this.dom.busyContent.textContent = 'busy...'
|
||||
this.dom.busy.appendChild(this.dom.busyContent)
|
||||
this.content.appendChild(this.dom.busy)
|
||||
|
||||
|
@ -398,7 +398,7 @@ previewmode._showTransformModal = function () {
|
|||
this._renderPreview() // update array count
|
||||
|
||||
showTransformModal({
|
||||
anchor: modalAnchor || DEFAULT_MODAL_ANCHOR,
|
||||
container: modalAnchor || DEFAULT_MODAL_ANCHOR,
|
||||
json,
|
||||
queryDescription, // can be undefined
|
||||
createQuery,
|
||||
|
|
|
@ -136,7 +136,7 @@ export function showTransformModal (
|
|||
|
||||
if (!Array.isArray(value)) {
|
||||
wizard.style.fontStyle = 'italic'
|
||||
wizard.innerHTML = '(wizard not available for objects, only for arrays)'
|
||||
wizard.textContent = '(wizard not available for objects, only for arrays)'
|
||||
}
|
||||
|
||||
const sortablePaths = getChildPaths(json)
|
||||
|
|
|
@ -68,7 +68,7 @@ textmode.create = function (container, options = {}) {
|
|||
// TODO: make the option options.ace deprecated, it's not needed anymore (see #309)
|
||||
|
||||
// determine mode
|
||||
this.mode = (options.mode === 'code') ? 'code' : 'text'
|
||||
this.mode = (options.mode === 'code') ? 'code' : ((options.mode === 'text') ? 'text' : 'text-plain')
|
||||
if (this.mode === 'code') {
|
||||
// verify whether Ace editor is available and supported
|
||||
if (typeof _ace === 'undefined') {
|
||||
|
@ -132,37 +132,41 @@ textmode.create = function (container, options = {}) {
|
|||
this.frame.appendChild(this.menu)
|
||||
|
||||
// create format button
|
||||
const buttonFormat = document.createElement('button')
|
||||
buttonFormat.type = 'button'
|
||||
buttonFormat.className = 'jsoneditor-format'
|
||||
buttonFormat.title = translate('formatTitle')
|
||||
this.menu.appendChild(buttonFormat)
|
||||
buttonFormat.onclick = () => {
|
||||
try {
|
||||
me.format()
|
||||
me._onChange()
|
||||
} catch (err) {
|
||||
me._onError(err)
|
||||
if(this.mode !== 'text-plain') {
|
||||
const buttonFormat = document.createElement('button')
|
||||
buttonFormat.type = 'button'
|
||||
buttonFormat.className = 'jsoneditor-format'
|
||||
buttonFormat.title = translate('formatTitle')
|
||||
this.menu.appendChild(buttonFormat)
|
||||
buttonFormat.onclick = () => {
|
||||
try {
|
||||
me.format()
|
||||
me._onChange()
|
||||
} catch (err) {
|
||||
me._onError(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// create compact button
|
||||
const buttonCompact = document.createElement('button')
|
||||
buttonCompact.type = 'button'
|
||||
buttonCompact.className = 'jsoneditor-compact'
|
||||
buttonCompact.title = translate('compactTitle')
|
||||
this.menu.appendChild(buttonCompact)
|
||||
buttonCompact.onclick = () => {
|
||||
try {
|
||||
me.compact()
|
||||
me._onChange()
|
||||
} catch (err) {
|
||||
me._onError(err)
|
||||
if(this.mode !== 'text-plain') {
|
||||
const buttonCompact = document.createElement('button')
|
||||
buttonCompact.type = 'button'
|
||||
buttonCompact.className = 'jsoneditor-compact'
|
||||
buttonCompact.title = translate('compactTitle')
|
||||
this.menu.appendChild(buttonCompact)
|
||||
buttonCompact.onclick = () => {
|
||||
try {
|
||||
me.compact()
|
||||
me._onChange()
|
||||
} catch (err) {
|
||||
me._onError(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// create sort button
|
||||
if (this.options.enableSort) {
|
||||
if (this.options.enableSort && this.mode !== 'text-plain') {
|
||||
const sort = document.createElement('button')
|
||||
sort.type = 'button'
|
||||
sort.className = 'jsoneditor-sort'
|
||||
|
@ -174,7 +178,7 @@ textmode.create = function (container, options = {}) {
|
|||
}
|
||||
|
||||
// create transform button
|
||||
if (this.options.enableTransform) {
|
||||
if (this.options.enableTransform && this.mode !== 'text-plain') {
|
||||
const transform = document.createElement('button')
|
||||
transform.type = 'button'
|
||||
transform.title = translate('transformTitleShort')
|
||||
|
@ -186,22 +190,24 @@ textmode.create = function (container, options = {}) {
|
|||
}
|
||||
|
||||
// create repair button
|
||||
const buttonRepair = document.createElement('button')
|
||||
buttonRepair.type = 'button'
|
||||
buttonRepair.className = 'jsoneditor-repair'
|
||||
buttonRepair.title = translate('repairTitle')
|
||||
this.menu.appendChild(buttonRepair)
|
||||
buttonRepair.onclick = () => {
|
||||
try {
|
||||
me.repair()
|
||||
me._onChange()
|
||||
} catch (err) {
|
||||
me._onError(err)
|
||||
if(this.mode !== 'text-plain') {
|
||||
const buttonRepair = document.createElement('button')
|
||||
buttonRepair.type = 'button'
|
||||
buttonRepair.className = 'jsoneditor-repair'
|
||||
buttonRepair.title = translate('repairTitle')
|
||||
this.menu.appendChild(buttonRepair)
|
||||
buttonRepair.onclick = () => {
|
||||
try {
|
||||
me.repair()
|
||||
me._onChange()
|
||||
} catch (err) {
|
||||
me._onError(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// create undo/redo buttons
|
||||
if (this.mode === 'code') {
|
||||
if (this.mode === 'code' || this.mode === 'text-plain') {
|
||||
// create undo button
|
||||
const undo = document.createElement('button')
|
||||
undo.type = 'button'
|
||||
|
@ -234,17 +240,17 @@ textmode.create = function (container, options = {}) {
|
|||
})
|
||||
}
|
||||
|
||||
if (this.mode === 'code') {
|
||||
if (this.mode === 'code' || this.mode === 'text-plain') {
|
||||
const poweredBy = document.createElement('a')
|
||||
poweredBy.appendChild(document.createTextNode('powered by ace'))
|
||||
poweredBy.href = 'http://ace.ajax.org'
|
||||
poweredBy.href = 'https://ace.c9.io/'
|
||||
poweredBy.target = '_blank'
|
||||
poweredBy.className = 'jsoneditor-poweredBy'
|
||||
poweredBy.onclick = () => {
|
||||
// TODO: this anchor falls below the margin of the content,
|
||||
// therefore the normal a.href does not work. We use a click event
|
||||
// for now, but this should be fixed.
|
||||
window.open(poweredBy.href, poweredBy.target)
|
||||
window.open(poweredBy.href, poweredBy.target, 'noopener')
|
||||
}
|
||||
this.menu.appendChild(poweredBy)
|
||||
}
|
||||
|
@ -258,7 +264,7 @@ textmode.create = function (container, options = {}) {
|
|||
this.frame.appendChild(this.content)
|
||||
this.container.appendChild(this.frame)
|
||||
|
||||
if (this.mode === 'code') {
|
||||
if (this.mode === 'code' || this.mode === 'text-plain') {
|
||||
this.editorDom = document.createElement('div')
|
||||
this.editorDom.style.height = '100%' // TODO: move to css
|
||||
this.editorDom.style.width = '100%' // TODO: move to css
|
||||
|
@ -271,7 +277,12 @@ textmode.create = function (container, options = {}) {
|
|||
aceEditor.setOptions({ readOnly: isReadOnly })
|
||||
aceEditor.setShowPrintMargin(false)
|
||||
aceEditor.setFontSize('13px')
|
||||
aceSession.setMode('ace/mode/json')
|
||||
if(this.mode === 'text-plain') {
|
||||
aceSession.setMode('ace/mode/text')
|
||||
}
|
||||
else{
|
||||
aceSession.setMode('ace/mode/json')
|
||||
}
|
||||
aceSession.setTabSize(this.indentation)
|
||||
aceSession.setUseSoftTabs(true)
|
||||
aceSession.setUseWrapMode(true)
|
||||
|
@ -282,8 +293,16 @@ textmode.create = function (container, options = {}) {
|
|||
originalSetAnnotations.call(this, annotations && annotations.length ? annotations : me.annotations)
|
||||
}
|
||||
|
||||
aceEditor.commands.bindKey('Ctrl-L', null) // disable Ctrl+L (is used by the browser to select the address bar)
|
||||
aceEditor.commands.bindKey('Command-L', null) // disable Ctrl+L (is used by the browser to select the address bar)
|
||||
// disable Ctrl+L quickkey of Ace (is used by the browser to select the address bar)
|
||||
aceEditor.commands.bindKey('Ctrl-L', null)
|
||||
aceEditor.commands.bindKey('Command-L', null)
|
||||
|
||||
// disable the quickkeys we want to use for Format and Compact
|
||||
aceEditor.commands.bindKey('Ctrl-\\', null)
|
||||
aceEditor.commands.bindKey('Command-\\', null)
|
||||
aceEditor.commands.bindKey('Ctrl-Shift-\\', null)
|
||||
aceEditor.commands.bindKey('Command-Shift-\\', null)
|
||||
|
||||
this.aceEditor = aceEditor
|
||||
|
||||
// register onchange event
|
||||
|
@ -476,7 +495,7 @@ textmode._showTransformModal = function () {
|
|||
const json = this.get()
|
||||
|
||||
showTransformModal({
|
||||
anchor: modalAnchor || DEFAULT_MODAL_ANCHOR,
|
||||
container: modalAnchor || DEFAULT_MODAL_ANCHOR,
|
||||
json,
|
||||
queryDescription, // can be undefined
|
||||
createQuery,
|
||||
|
@ -683,17 +702,24 @@ textmode.compact = function () {
|
|||
*/
|
||||
textmode.format = function () {
|
||||
const json = this.get()
|
||||
const text = JSON.stringify(json, null, this.indentation)
|
||||
this.updateText(text)
|
||||
if(this.mode !== 'text-plain') {
|
||||
const text = JSON.stringify(json, null, this.indentation)
|
||||
this.updateText(text)
|
||||
}
|
||||
else {
|
||||
this.updateText(json)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Repair the code in the text editor
|
||||
*/
|
||||
textmode.repair = function () {
|
||||
const text = this.getText()
|
||||
const repairedText = repair(text)
|
||||
this.updateText(repairedText)
|
||||
if(this.mode !== 'text-plain') {
|
||||
const text = this.getText()
|
||||
const repairedText = repair(text)
|
||||
this.updateText(repairedText)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -723,7 +749,12 @@ textmode.resize = function () {
|
|||
* @param {*} json
|
||||
*/
|
||||
textmode.set = function (json) {
|
||||
this.setText(JSON.stringify(json, null, this.indentation))
|
||||
if(this.mode !== 'text-plain') {
|
||||
this.setText(JSON.stringify(json, null, this.indentation))
|
||||
}
|
||||
else{
|
||||
this.setText(json)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -821,6 +852,9 @@ textmode.updateText = function (jsonText) {
|
|||
* Throws an exception when no JSON schema is configured
|
||||
*/
|
||||
textmode.validate = function () {
|
||||
if(this.mode === 'text-plain') {
|
||||
return
|
||||
}
|
||||
let schemaErrors = []
|
||||
let parseErrors = []
|
||||
let json
|
||||
|
@ -1055,5 +1089,11 @@ export const textModeMixins = [
|
|||
mixin: textmode,
|
||||
data: 'text',
|
||||
load: load
|
||||
},
|
||||
{
|
||||
mode: 'text-plain',
|
||||
mixin: textmode,
|
||||
data: 'text',
|
||||
load: load
|
||||
}
|
||||
]
|
||||
|
|
|
@ -25,7 +25,8 @@ import {
|
|||
repair,
|
||||
selectContentEditable,
|
||||
setSelectionOffset,
|
||||
isValidationErrorChanged
|
||||
isValidationErrorChanged,
|
||||
getWindow
|
||||
} from './util'
|
||||
import { autocomplete } from './autocomplete'
|
||||
import { setLanguage, setLanguages, translate } from './i18n'
|
||||
|
@ -127,6 +128,7 @@ treemode._setOptions = function (options) {
|
|||
autocomplete: null,
|
||||
navigationBar: true,
|
||||
mainMenuBar: true,
|
||||
limitDragging: false,
|
||||
onSelectionChange: null,
|
||||
colorPicker: true,
|
||||
onColorPicker: function (parent, color, onChange) {
|
||||
|
@ -135,7 +137,7 @@ treemode._setOptions = function (options) {
|
|||
// when there is not enough space below, and there is enough space above
|
||||
const pickerHeight = 300 // estimated height of the color picker
|
||||
const top = parent.getBoundingClientRect().top
|
||||
const windowHeight = window.innerHeight
|
||||
const windowHeight = getWindow(parent).innerHeight
|
||||
const showOnTop = ((windowHeight - top) < pickerHeight && top > pickerHeight)
|
||||
|
||||
new VanillaPicker({
|
||||
|
@ -169,6 +171,11 @@ treemode._setOptions = function (options) {
|
|||
Object.keys(options).forEach(prop => {
|
||||
this.options[prop] = options[prop]
|
||||
})
|
||||
|
||||
// default limitDragging to true when a JSON schema is defined
|
||||
if (options.limitDragging == null && options.schema != null) {
|
||||
this.options.limitDragging = true
|
||||
}
|
||||
}
|
||||
|
||||
// compile a JSON schema validator if a JSON schema is provided
|
||||
|
@ -626,8 +633,8 @@ treemode._renderValidationErrors = function (errorNodes) {
|
|||
|
||||
error: {
|
||||
message: pair[0].type === 'object'
|
||||
? 'Contains invalid properties' // object
|
||||
: 'Contains invalid items' // array
|
||||
? translate('containsInvalidProperties') // object
|
||||
: translate('containsInvalidItems') // array
|
||||
}
|
||||
}))
|
||||
.concat(errorNodes)
|
||||
|
@ -1274,7 +1281,7 @@ treemode._updateDragDistance = function (event) {
|
|||
|
||||
/**
|
||||
* Start multi selection of nodes by dragging the mouse
|
||||
* @param event
|
||||
* @param {MouseEvent} event
|
||||
* @private
|
||||
*/
|
||||
treemode._onMultiSelectStart = function (event) {
|
||||
|
@ -1296,12 +1303,12 @@ treemode._onMultiSelectStart = function (event) {
|
|||
|
||||
const editor = this
|
||||
if (!this.mousemove) {
|
||||
this.mousemove = addEventListener(window, 'mousemove', event => {
|
||||
this.mousemove = addEventListener(event.view, 'mousemove', event => {
|
||||
editor._onMultiSelect(event)
|
||||
})
|
||||
}
|
||||
if (!this.mouseup) {
|
||||
this.mouseup = addEventListener(window, 'mouseup', event => {
|
||||
this.mouseup = addEventListener(event.view, 'mouseup', event => {
|
||||
editor._onMultiSelectEnd(event)
|
||||
})
|
||||
}
|
||||
|
@ -1311,7 +1318,7 @@ treemode._onMultiSelectStart = function (event) {
|
|||
|
||||
/**
|
||||
* Multiselect nodes by dragging
|
||||
* @param event
|
||||
* @param {MouseEvent} event
|
||||
* @private
|
||||
*/
|
||||
treemode._onMultiSelect = function (event) {
|
||||
|
@ -1354,9 +1361,10 @@ treemode._onMultiSelect = function (event) {
|
|||
|
||||
/**
|
||||
* End of multiselect nodes by dragging
|
||||
* @param {MouseEvent} event
|
||||
* @private
|
||||
*/
|
||||
treemode._onMultiSelectEnd = function () {
|
||||
treemode._onMultiSelectEnd = function (event) {
|
||||
// set focus to the context menu button of the first node
|
||||
if (this.multiselection.nodes[0]) {
|
||||
this.multiselection.nodes[0].dom.menu.focus()
|
||||
|
@ -1367,11 +1375,11 @@ treemode._onMultiSelectEnd = function () {
|
|||
|
||||
// cleanup global event listeners
|
||||
if (this.mousemove) {
|
||||
removeEventListener(window, 'mousemove', this.mousemove)
|
||||
removeEventListener(event.view, 'mousemove', this.mousemove)
|
||||
delete this.mousemove
|
||||
}
|
||||
if (this.mouseup) {
|
||||
removeEventListener(window, 'mouseup', this.mouseup)
|
||||
removeEventListener(event.view, 'mouseup', this.mouseup)
|
||||
delete this.mouseup
|
||||
}
|
||||
}
|
||||
|
@ -1484,6 +1492,11 @@ treemode._showAutoComplete = function (element) {
|
|||
if (element.className.indexOf('jsoneditor-value') >= 0) jsonElementType = 'value'
|
||||
if (element.className.indexOf('jsoneditor-field') >= 0) jsonElementType = 'field'
|
||||
|
||||
if (jsonElementType === '') {
|
||||
// Unknown element field. Could be a button or something else
|
||||
return
|
||||
}
|
||||
|
||||
const self = this
|
||||
|
||||
setTimeout(() => {
|
||||
|
|
|
@ -455,6 +455,16 @@ export function isArray (obj) {
|
|||
return Object.prototype.toString.call(obj) === '[object Array]'
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a DOM element's Window. This is normally just the global `window`
|
||||
* variable, but if we opened a child window, it may be different.
|
||||
* @param {HTMLElement} element
|
||||
* @return {Window}
|
||||
*/
|
||||
export function getWindow (element) {
|
||||
return element.ownerDocument.defaultView
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the absolute left value of a DOM element
|
||||
* @param {Element} elem A dom element, for example a div
|
||||
|
@ -663,7 +673,6 @@ export function setSelectionOffset (params) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the inner text of an HTML element (for example a div element)
|
||||
* @param {Element} element
|
||||
|
@ -674,21 +683,28 @@ export function getInnerText (element, buffer) {
|
|||
const first = (buffer === undefined)
|
||||
if (first) {
|
||||
buffer = {
|
||||
text: '',
|
||||
_text: '',
|
||||
flush: function () {
|
||||
const text = this.text
|
||||
this.text = ''
|
||||
const text = this._text
|
||||
this._text = ''
|
||||
return text
|
||||
},
|
||||
set: function (text) {
|
||||
this.text = text
|
||||
this._text = text
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// text node
|
||||
if (element.nodeValue) {
|
||||
return buffer.flush() + element.nodeValue
|
||||
// remove return characters and the whitespace surrounding return characters
|
||||
const trimmedValue = element.nodeValue.replace(/\s*\n\s*/g, '')
|
||||
if (trimmedValue !== '') {
|
||||
return buffer.flush() + trimmedValue
|
||||
} else {
|
||||
// ignore empty text
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
// divs or other HTML elements
|
||||
|
@ -703,7 +719,9 @@ export function getInnerText (element, buffer) {
|
|||
const prevChild = childNodes[i - 1]
|
||||
const prevName = prevChild ? prevChild.nodeName : undefined
|
||||
if (prevName && prevName !== 'DIV' && prevName !== 'P' && prevName !== 'BR') {
|
||||
innerText += '\n'
|
||||
if (innerText !== '') {
|
||||
innerText += '\n'
|
||||
}
|
||||
buffer.flush()
|
||||
}
|
||||
innerText += getInnerText(child, buffer)
|
||||
|
@ -717,15 +735,6 @@ export function getInnerText (element, buffer) {
|
|||
}
|
||||
|
||||
return innerText
|
||||
} else {
|
||||
if (element.nodeName === 'P' && getInternetExplorerVersion() !== -1) {
|
||||
// On Internet Explorer, a <p> with hasChildNodes()==false is
|
||||
// rendered with a new line. Note that a <p> with
|
||||
// hasChildNodes()==true is rendered without a new line
|
||||
// Other browsers always ensure there is a <br> inside the <p>,
|
||||
// and if not, the <p> does not render a new line
|
||||
return buffer.flush()
|
||||
}
|
||||
}
|
||||
|
||||
// br or unknown
|
||||
|
@ -790,7 +799,7 @@ export function isFirefox () {
|
|||
var _ieVersion = -1
|
||||
|
||||
/**
|
||||
* Add and event listener. Works for all browsers
|
||||
* Add an event listener. Works for all browsers
|
||||
* @param {Element} element An html element
|
||||
* @param {string} action The action, for example "click",
|
||||
* without the prefix "on"
|
||||
|
@ -1140,7 +1149,7 @@ export function getInputSelection (el) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the index for certaion position in text element
|
||||
* Returns the index for certain position in text element
|
||||
* @param {DOMElement} el A dom element of a textarea or input text.
|
||||
* @param {Number} row row value, > 0, if exceeds rows number - last row will be returned
|
||||
* @param {Number} column column value, > 0, if exceeds column length - end of column will be returned
|
||||
|
@ -1500,7 +1509,7 @@ export function contains (array, item) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Checkes if validation has changed from the previous execution
|
||||
* Checks if validation has changed from the previous execution
|
||||
* @param {Array} currErr current validation errors
|
||||
* @param {Array} prevErr previous validation errors
|
||||
*/
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
.jsoneditor-contextmenu {
|
||||
position: absolute;
|
||||
box-sizing: content-box;
|
||||
z-index: 1;
|
||||
z-index: 2;
|
||||
.jsoneditor-menu {
|
||||
position: relative;
|
||||
left: 0;
|
||||
|
|
|
@ -46,6 +46,9 @@ div {
|
|||
&.jsoneditor-null {
|
||||
color: $jse-null;
|
||||
}
|
||||
&.jsoneditor-color-value {
|
||||
color: $jse-color-value;
|
||||
}
|
||||
&.jsoneditor-invalid {
|
||||
color: $jse-invalid;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,8 @@ $jse-string: #006000 !default;
|
|||
$jse-number: #ee422e !default;
|
||||
$jse-boolean: #ff8c00 !default;
|
||||
$jse-null: #004ed0 !default;
|
||||
$jse-invalid: #000000 !default;
|
||||
$jse-color-value: $jse-content-color !default;
|
||||
$jse-invalid: $jse-content-color !default;
|
||||
$jse-readonly: #808080 !default;
|
||||
$jse-empty: #d3d3d3 !default;
|
||||
$jse-preview: #f5f5f5 !default;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" type="text/css">
|
||||
<!--<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha/css/bootstrap.min.css" rel="stylesheet" type="text/css">-->
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
<meta charset="utf-8">
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
<script src="../dist/jsoneditor.js"></script>
|
||||
|
@ -50,6 +50,7 @@
|
|||
mode: 'tree',
|
||||
modes: ['code', 'form', 'text', 'tree', 'view', 'preview'], // allowed modes
|
||||
onError: function (err) {
|
||||
console.error(err);
|
||||
alert(err.toString());
|
||||
},
|
||||
onChange: function () {
|
||||
|
@ -57,6 +58,9 @@
|
|||
},
|
||||
onChangeJSON: function (json) {
|
||||
console.log('onChangeJSON', json);
|
||||
|
||||
// test feedback loop which is typical in React -> should not change anything
|
||||
editorTest.update(json)
|
||||
},
|
||||
onChangeText: function (text) {
|
||||
console.log('onChangeText', text);
|
||||
|
@ -68,7 +72,8 @@
|
|||
console.log("Blur : ",event);
|
||||
},
|
||||
indentation: 4,
|
||||
escapeUnicode: true
|
||||
// escapeUnicode: true,
|
||||
limitDragging: true
|
||||
};
|
||||
|
||||
json = {
|
||||
|
@ -77,14 +82,20 @@
|
|||
"color": "#82b92c",
|
||||
"htmlcode": '"',
|
||||
"escaped_unicode": '\\u20b9',
|
||||
"unicode": '\u20b9,\uD83D\uDCA9',
|
||||
"unicode": '\u{1F600},\uD83D\uDCA9',
|
||||
"return": '\n',
|
||||
"null": null,
|
||||
"number": 123,
|
||||
"object": {"a": "b", "c": "d"},
|
||||
"string": "Hello World",
|
||||
"timestamp": 1534952749890,
|
||||
"url": "http://jsoneditoronline.org"
|
||||
"url": "http://jsoneditoronline.org",
|
||||
"<button onclick=alert('oopsie!!!')>test xss</button>": "xss?",
|
||||
"xss array": [
|
||||
{
|
||||
"<button onclick=alert('oopsie!!!')>test xss</button>": "xss?"
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
editorTest = new JSONEditor(container, options, json);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
<meta charset="utf-8">
|
||||
|
||||
<link href="../dist/jsoneditor.min.css" rel="stylesheet" type="text/css">
|
||||
<script src="../dist/jsoneditor.min.js"></script>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
<meta charset="utf-8">
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
<script src="../dist/jsoneditor.js"></script>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
<meta charset="utf-8">
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
<script src="../dist/jsoneditor.js"></script>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
<meta charset="utf-8">
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
<script src="../dist/jsoneditor.js"></script>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
<meta charset="utf-8">
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
<script src="../dist/jsoneditor.js"></script>
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>JSONEditor test getInnerHtml</title>
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
<script src="../dist/jsoneditor.js"></script>
|
||||
|
||||
<style>
|
||||
html, body {
|
||||
font-family: verdana;
|
||||
background: #f5f5f5;
|
||||
font-size: 11pt;
|
||||
}
|
||||
|
||||
#editableDiv {
|
||||
width: 600px;
|
||||
height: 200px;
|
||||
border: 1px solid red;
|
||||
background: white;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
#editableDiv p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#innerText,
|
||||
#getInnerText,
|
||||
#innerTextStr,
|
||||
#textContentStr {
|
||||
width: 600px;
|
||||
}
|
||||
|
||||
#innerText,
|
||||
#getInnerText {
|
||||
height: 200px;
|
||||
border: 1px solid green;
|
||||
}
|
||||
|
||||
#innerTextStr,
|
||||
#textContentStr {
|
||||
width: 600px;
|
||||
border: 1px solid gray;
|
||||
background: #f5f5f5;
|
||||
font-family: monospace;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
contenteditable div:
|
||||
<div id="editableDiv" contenteditable="true">
|
||||
<p>Hello world</p>
|
||||
<p>test paste from OpenOffice </p>
|
||||
a
|
||||
<p>
|
||||
<br>
|
||||
</p>
|
||||
<p>test</p>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
innerText: <br/>
|
||||
<textarea id="innerText"></textarea>
|
||||
</p>
|
||||
<p>
|
||||
getInnerText: <br/>
|
||||
<textarea id="getInnerText"></textarea>
|
||||
</p>
|
||||
<p>
|
||||
<p>
|
||||
inner text (stringified): <br/>
|
||||
<input id="innerTextStr" readonly />
|
||||
</p>
|
||||
<p>
|
||||
text content (stringified): <br/>
|
||||
<input id="textContentStr" readonly />
|
||||
</p>
|
||||
|
||||
<script>
|
||||
const editableDiv = document.getElementById('editableDiv')
|
||||
const innerText = document.getElementById('innerText')
|
||||
const getInnerTextDiv = document.getElementById('getInnerText')
|
||||
const innerTextStr = document.getElementById('innerTextStr')
|
||||
const textContentStr = document.getElementById('textContentStr')
|
||||
|
||||
function updateInnerTexts () {
|
||||
innerText.value = editableDiv.innerText
|
||||
getInnerTextDiv.value = JSONEditor.getInnerText(editableDiv)
|
||||
innerTextStr.value = JSON.stringify(editableDiv.innerText)
|
||||
textContentStr.value = JSON.stringify(editableDiv.textContent)
|
||||
}
|
||||
|
||||
editableDiv.oninput = updateInnerTexts
|
||||
|
||||
updateInnerTexts()
|
||||
|
||||
innerText.oninput = function () {
|
||||
editableDiv.innerText = innerText.value
|
||||
getInnerTextDiv.value = getInnerText(editableDiv)
|
||||
}
|
||||
|
||||
getInnerTextDiv.oninput = function () {
|
||||
editableDiv.innerText = getInnerTextDiv.value
|
||||
innerText.value = editableDiv.innerText
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,7 +1,7 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
<meta charset="utf-8">
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
<script src="../dist/jsoneditor.js"></script>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
<meta charset="utf-8">
|
||||
|
||||
<!-- materialize css -->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.6/css/materialize.min.css">
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
<meta charset="utf-8">
|
||||
|
||||
<link href="../dist/jsoneditor.min.css" rel="stylesheet" type="text/css">
|
||||
<script src="../dist/jsoneditor-minimalist.min.js"></script>
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>JSONEditor | JSON schema validation</title>
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>JSONEditor | Preview mode load and save</title>
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
<meta charset="utf-8">
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
<script src="../dist/jsoneditor.js"></script>
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>JSONEditor | Update JSON</title>
|
||||
|
||||
<!-- when using the mode "code", it's important to specify charset utf-8 -->
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>JSONEditor | Update JSON</title>
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
<script src="../dist/jsoneditor.js"></script>
|
||||
|
|
Loading…
Reference in New Issue