Skip to content
This repository was archived by the owner on Jan 29, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,10 @@ The `./examples` folder contains two examples:

| Name | Description | Type | Required |
| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------: | :-------: |
| [id]() | A unique id to identify component. | string | Mandatory |
| [locale]() | The locale of your editor. Import locales like this: `import locale from 'react-json-editor-ajrm/locale/en'`. [Learn More](https://github.com/AndrewRedican/react-json-editor-ajrm/wiki/Locale-Support) | object | Mandatory |
| [placeholder]() | Send a valid javascript object to be shown once the component is mounted. Assign a different value to have the component's initial content re-rendered. | object | Optional |
| [reset]() | Send `true` to have component always re-render or 'reset' to the value provided on the `placeholder` property. | boolean | Optional |
| [locale]() | The locale of your editor. Import locales like this: `import locale from 'react-json-editor-ajrm/locale/en'`. [Learn More](https://github.com/AndrewRedican/react-json-editor-ajrm/wiki/Locale-Support) | object | Mandatory |
| [id]() | An optional `id` to assign to the actual text input DOM node. Asides the from the text input, the following nodes will also receive an id: `{id}-outer-box`, `{id}-container`, `{id}-warning-box`, `{id}-labels` | string | Optional |
| [placeholder]() | Send a valid javascript object to be shown once the component is mounted. Assign a different value to have the component's initial content re-rendered. | object | Optional |
| [reset]() | Send `true` to have component always re-render or 'reset' to the value provided on the `placeholder` property. | boolean | Optional |
| [viewOnly]() | Send `true` if you would like for content shown not to be editable. | boolean | Optional |
| [onChange]() | Whenever `onBlur` or `onKeyPress` events take place, it will return content values. | object | Optional |
| [confirmGood]() | Send `false` if you would like for the checkmark to confirm good syntax to be hidden. | boolean | Optional |
Expand Down
1 change: 0 additions & 1 deletion example/create-react-app-project/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ class App extends Component {
return (
<div style={{ maxWidth: "1400px", maxHeight: "100%" }}>
<JSONInput
id="unique_string" // an id is required
placeholder={sampleData} // data to display
theme="light_mitsuketa_tribute"
locale={locale}
Expand Down
1 change: 0 additions & 1 deletion example/webpack-project/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ class App extends Component {
return (
<div style={{ maxWidth: "1400px", maxHeight: "100%" }}>
<JSONInput
id="unique_string" // an id is required
placeholder={sampleData} // data to display
theme="light_mitsuketa_tribute"
locale={locale}
Expand Down
91 changes: 36 additions & 55 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ import defaultLocale from './locale/en';
class JSONInput extends Component {
constructor(props){
super(props);
if(!('id' in this.props)) throw 'An \'id\' property must be specified. Must be unique.';
this.updateInternalProps = this.updateInternalProps .bind(this);
this.randomString = this.randomString .bind(this);
this.createMarkup = this.createMarkup .bind(this);
this.onClick = this.onClick .bind(this);
this.onBlur = this.onBlur .bind(this);
Expand All @@ -29,8 +27,8 @@ class JSONInput extends Component {
this.onKeyDown = this.onKeyDown .bind(this);
this.onPaste = this.onPaste .bind(this);
this.stopEvent = this.stopEvent .bind(this);
this.uniqueID = 'AJRM-JSON-EDITOR-' + ('test' in this.props ? '<RANDOM_NUMBER>' : this.randomString(10)) + '-' + this.props.id;
this.contentID = this.uniqueID + '-content-box';
this.refContent = null;
this.refLabels = null;
this.updateInternalProps();
this.renderCount = 1;
this.state = {
Expand Down Expand Up @@ -110,10 +108,9 @@ class JSONInput extends Component {
}
render(){
const
id = this.props.id,
markupText = this.state.markupText,
error = this.state.error,
uniqueID = this.uniqueID,
contentID = this.contentID,
colors = this.colors,
style = this.style,
confirmGood = this.confirmGood,
Expand All @@ -124,7 +121,7 @@ class JSONInput extends Component {
return (
<div
name = 'outer-box'
id = {uniqueID + '-outer-box'}
id = {id && id + '-outer-box'}
style = {{
display : 'block',
overflow : 'none',
Expand Down Expand Up @@ -170,7 +167,7 @@ class JSONInput extends Component {
}
<div
name = 'container'
id = {uniqueID + '-container'}
id = {id && id + '-container'}
style = {{
display : 'block',
height : totalHeight,
Expand All @@ -185,7 +182,7 @@ class JSONInput extends Component {
>
<div
name = 'warning-box'
id = {uniqueID + '-warning-box'}
id = {id && id + '-warning-box'}
style = {{
display : 'block',
overflow : 'hidden',
Expand Down Expand Up @@ -267,7 +264,7 @@ class JSONInput extends Component {
</div>
<div
name = 'body'
id = {uniqueID + '-body'}
id = {id && id + '-body'}
style = {{
display : 'flex',
overflow : 'none',
Expand All @@ -286,7 +283,8 @@ class JSONInput extends Component {
>
<span
name = 'labels'
id = {uniqueID + '-labels'}
id = {id && id + '-labels'}
ref = {ref => this.refLabels = ref}
style = {{
display : 'inline-block',
boxSizing : 'border-box',
Expand All @@ -304,7 +302,8 @@ class JSONInput extends Component {
{this.renderLabels()}
</span>
<span
id = {contentID}
id = { id }
ref = { ref => this.refContent = ref }
contentEditable = { true }
style = {{
display : 'inline-block',
Expand Down Expand Up @@ -371,7 +370,6 @@ class JSONInput extends Component {
}
renderLabels(){
const
uniqueID = this.uniqueID + '-line-',
colors = this.colors,
style = this.style,
errorLine = this.state.error ? this.state.error.line : -1,
Expand All @@ -383,8 +381,7 @@ class JSONInput extends Component {
const color = number !== errorLine ? colors.default : 'red';
return (
<div
key = {uniqueID + number}
id = {uniqueID + number}
key = {number}
style = {{
...style.labels,
color : color
Expand All @@ -401,7 +398,6 @@ class JSONInput extends Component {
}
newSpan(i,token,depth){
let
uniqueID = this.uniqueID + '-token-' + i + '-rc-' + this.renderCount,
colors = this.colors,
type = token.type,
string = token.string;
Expand All @@ -414,35 +410,25 @@ class JSONInput extends Component {
}
if(string.length!==string.replace(/</g,'').replace(/>/g,'').length) string = '<xmp style=display:inline;>' + string + '</xmp>';
return (
'<span' +
' id="' + uniqueID +
'" key="' + uniqueID +
'" type="' + type +
'" value="' + string +
'" depth="' + depth +
'" style="color:' + color +
'">' + string +
'<span' +
' type="' + type + '"' +
' value="' + string + '"' +
' depth="' + depth + '"' +
' style="color:' + color + '"' +
'>' + string +
'</span>'
);
}
randomString(length){
if(typeof length !== 'number') throw '@randomString: Expected \'length\' to be a number';
const chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
let result = '';
for (var i = length; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)];
return result;
}
}
getCursorPosition(countBR){
/**
* Need to deprecate countBR
* It is used to differenciate between good markup render, and aux render when error found
* Adjustments based on coundBR account for usage of <br> instead of <span> for linebreaks to determine acurate cursor position
* Find a way to consolidate render styles
*/
const contentID = this.contentID;
function isChildOf(node) {
const isChildOf = node => {
while (node !== null) {
if (node.id === contentID) return true;
if (node === this.refContent) return true;
node = node.parentNode;
}
return false;
Expand All @@ -452,12 +438,11 @@ class JSONInput extends Component {
charCount = -1,
linebreakCount = 0,
node;
if (selection.focusNode)
if (isChildOf(selection.focusNode)) {
if (selection.focusNode && isChildOf(selection.focusNode)) {
node = selection.focusNode;
charCount = selection.focusOffset;
while (node) {
if (node.id === contentID) break;
if (node === this.refContent) break;
if (node.previousSibling) {
node = node.previousSibling;
if(countBR) if(node.nodeName==='BR') linebreakCount++;
Expand All @@ -472,8 +457,7 @@ class JSONInput extends Component {
}
setCursorPosition(nextPosition) {
if([false,null,undefined].indexOf(nextPosition)>-1) return;
const contentID = this.contentID;
function createRange(node, chars, range) {
const createRange = (node, chars, range) => {
if (!range) {
range = document.createRange();
range.selectNode(node);
Expand All @@ -493,23 +477,22 @@ class JSONInput extends Component {
}
return range;
};
function setPosition(chars) {
const setPosition = chars => {
if (chars < 0) return;
let
selection = window.getSelection(),
range = createRange(document.getElementById(contentID), { count: chars });
range = createRange(this.refContent, { count: chars });
if (!range) return;
range.collapse(false);
selection.removeAllRanges();
selection.addRange(range);
};
if(nextPosition > 0) setPosition(nextPosition);
else document.getElementById(contentID).focus();
else this.refContent.focus();
}
update(cursorOffset=0,updateCursorPosition=true){
const
contentID = this.contentID,
container = document.getElementById(contentID),
container = this.refContent,
data = this.tokenize(container);
if('onChange' in this.props) this.props.onChange({
plainText : data.indented,
Expand Down Expand Up @@ -580,7 +563,13 @@ class JSONInput extends Component {
}
}
onPaste(event){
if('viewOnly' in this.props) if(this.props.viewOnly) this.stopEvent(event);
if (this.props.viewOnly) {
this.stopEvent(event);
} else {
event.preventDefault();
var text = event.clipboardData.getData('text/plain');
document.execCommand('insertHTML', false, text);
}
this.update();
}
onClick(){
Expand All @@ -591,21 +580,13 @@ class JSONInput extends Component {
this.update(0,false);
}
onScroll(event){
const uniqueID = this.uniqueID;
var labels = document.getElementById(uniqueID + '-labels');
labels.scrollTop = event.target.scrollTop;
this.refLabels.scrollTop = event.target.scrollTop;
}
componentDidUpdate(){
this.updateInternalProps();
this.showPlaceholder();
}
componentDidMount(){
const contentID = this.contentID;
document.getElementById(contentID).addEventListener('paste', e => {
e.preventDefault();
var text = e.clipboardData.getData('text/plain');
document.execCommand('insertHTML', false, text);
});
this.showPlaceholder();
}
componentWillUnmount(){
Expand Down
2 changes: 0 additions & 2 deletions test/change/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ function run() {
test(`Update placeholder property value`, () => {
let wrapper = mount(
<JSONInput
test
id='unique_string'
locale={locale}
reset={false}
placeholder={{ valueToChange : false }}
Expand Down
5 changes: 0 additions & 5 deletions test/logic/testSyntaxLogic.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ function testSyntaxLogic(language='JS',scope,input,output){
err.isNotType('output',output,'object');
err.isUndefined('input',input);

const uniqueID = 'unique_string';
let markup;


Expand All @@ -33,8 +32,6 @@ function testSyntaxLogic(language='JS',scope,input,output){
const
wrapper = shallow(
<JSONInput
test
id = {uniqueID}
locale = {locale}
/>,
{ attachTo: window.domNode }
Expand Down Expand Up @@ -72,8 +69,6 @@ function testSyntaxLogic(language='JS',scope,input,output){
const
wrapper = shallow(
<JSONInput
test
id = {uniqueID}
locale = {locale}
/>,
{ attachTo: window.domNode }
Expand Down
6 changes: 0 additions & 6 deletions test/render/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ function run() {
test(`Basic Component Render`, () => {
let wrapper = mount(
<JSONInput
test
id='unique_string'
locale={locale}
/>,
{ attachTo: window.domNode }
Expand All @@ -28,8 +26,6 @@ function run() {
test(`All Component Properties Render [1]`, () => {
let wrapper = mount(
<JSONInput
test
id='unique_string'
locale={locale}
placeholder={sampleData}
viewOnly={true}
Expand Down Expand Up @@ -61,8 +57,6 @@ function run() {
test(`All Component Properties Render [2]`, () => {
let wrapper = mount(
<JSONInput
test
id='unique_string'
locale={locale}
placeholder={sampleData}
viewOnly={false}
Expand Down