Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

react-ace

Package Overview
Dependencies
Maintainers
1
Versions
102
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-ace - npm Package Compare versions

Comparing version 6.4.0 to 6.5.0

.nyc_output/17eabc8e-c273-4d65-ad8b-2162d4b41c6c.json

7

CHANGELOG.md

@@ -8,2 +8,9 @@ # Changelog

## 6.5.0
- Upgrade dependencies
- Do not clear active line and active word markers #604
- New 'placeholder' prop to specify placeholder text #603
- Added optional prop to disable navigating to end of file #602
## 6.4.0

@@ -10,0 +17,0 @@

4

coverage/lcov-report/sorter.js

@@ -163,4 +163,4 @@ /* eslint-disable */

}
cols = loadColumns();
loadData(cols);
loadColumns();
loadData();
addSortIndicators();

@@ -167,0 +167,0 @@ enableUI();

@@ -163,4 +163,4 @@ /* eslint-disable */

}
cols = loadColumns();
loadData(cols);
loadColumns();
loadData();
addSortIndicators();

@@ -167,0 +167,0 @@ enableUI();

@@ -11,14 +11,13 @@ # Ace Editor

```javascript
import React from 'react';
import { render } from 'react-dom';
import brace from 'brace';
import AceEditor from 'react-ace';
import React from "react";
import { render } from "react-dom";
import brace from "brace";
import AceEditor from "react-ace";
import 'brace/mode/java';
import 'brace/theme/github';
import "brace/mode/java";
import "brace/theme/github";
function onChange(newValue) {
console.log('change',newValue);
console.log("change", newValue);
}

@@ -33,53 +32,53 @@

name="UNIQUE_ID_OF_DIV"
editorProps={{$blockScrolling: true}}
editorProps={{ $blockScrolling: true }}
/>,
document.getElementById('example')
document.getElementById("example")
);
```
## Available Props
|Prop|Default|Type|Description|
|-----|------|-----|-----|
|name| 'brace-editor'| String |Unique Id to be used for the editor|
|mode| ''| String |Language for parsing and code highlighting|
|theme| ''| String |theme to use|
|value | ''| String | value you want to populate in the code highlighter|
|defaultValue | ''| String |Default value of the editor|
|height| '500px'| String |CSS value for height|
|width| '500px'| String |CSS value for width|
|className| | String |custom className|
|fontSize| 12| Number |pixel value for font-size|
|showGutter| true| Boolean | show gutter |
|showPrintMargin| true| Boolean| show print margin |
|highlightActiveLine| true| Boolean| highlight active line|
|focus| false| Boolean| whether to focus
|cursorStart| 1| Number| the location of the cursor
|wrapEnabled| false| Boolean | Wrapping lines|
|readOnly| false| Boolean| make the editor read only |
|minLines| | Number |Minimum number of lines to be displayed|
|maxLines| | Number |Maximum number of lines to be displayed|
|enableBasicAutocompletion| false| Boolean | Enable basic autocompletion|
|enableLiveAutocompletion| false| Boolean | Enable live autocompletion|
|tabSize| 4| Number| tabSize|
|debounceChangePeriod| null| Number| A debounce delay period for the onChange event|
|onLoad| | Function | called on editor load. The first argument is the instance of the editor |
|onBeforeLoad| | Function | called before editor load. the first argument is an instance of `ace`|
|onChange| | Function | occurs on document change it has 2 arguments the value and the event.|
|onCopy| | Function | triggered by editor `copy` event, and passes text as argument|
|onPaste| | Function | Triggered by editor `paste` event, and passes text as argument|
|onSelectionChange| | Function | triggered by editor `selectionChange` event, and passes a [Selection](https://ace.c9.io/#nav=api&api=selection) as it's first argument and the event as the second|
|onCursorChange| | Function | triggered by editor `changeCursor` event, and passes a [Selection](https://ace.c9.io/#nav=api&api=selection) as it's first argument and the event as the second|
|onFocus| | Function | triggered by editor `focus` event|
|onBlur| | Function | triggered by editor `blur` event.It has two arguments event and editor|
|onInput| | Function | triggered by editor `input` event|
|onScroll| | Function | triggered by editor `scroll` event|
|onValidate| | Function | triggered, when annotations are changed|
|editorProps| | Object | properties to apply directly to the Ace editor instance|
|setOptions| | Object | [options](https://github.com/ajaxorg/ace/wiki/Configuring-Ace) to apply directly to the Ace editor instance|
|keyboardHandler| | String | corresponding to the keybinding mode to set (such as vim or emacs)|
|commands| | Array | new commands to add to the editor
|annotations| | Array | annotations to show in the editor i.e. `[{ row: 0, column: 2, type: 'error', text: 'Some error.'}]`, displayed in the gutter|
|markers| | Array | [markers](https://ace.c9.io/#nav=api&api=edit_session) to show in the editor, i.e. `[{ startRow: 0, startCol: 2, endRow: 1, endCol: 20, className: 'error-marker', type: 'background' }]`. Make sure to define the class (eg. ".error-marker") and set `position: absolute` for it.|
|style| | Object | camelCased properties |
| Prop | Default | Type | Description |
| ------------------------- | -------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| name | 'brace-editor' | String | Unique Id to be used for the editor |
| placeholder | null | String | Placeholder text to be displayed when editor is empty |
| mode | '' | String | Language for parsing and code highlighting |
| theme | '' | String | theme to use |
| value | '' | String | value you want to populate in the code highlighter |
| defaultValue | '' | String | Default value of the editor |
| height | '500px' | String | CSS value for height |
| width | '500px' | String | CSS value for width |
| className | | String | custom className |
| fontSize | 12 | Number | pixel value for font-size |
| showGutter | true | Boolean | show gutter |
| showPrintMargin | true | Boolean | show print margin |
| highlightActiveLine | true | Boolean | highlight active line |
| focus | false | Boolean | whether to focus |
| cursorStart | 1 | Number | the location of the cursor |
| wrapEnabled | false | Boolean | Wrapping lines |
| readOnly | false | Boolean | make the editor read only |
| minLines | | Number | Minimum number of lines to be displayed |
| maxLines | | Number | Maximum number of lines to be displayed |
| enableBasicAutocompletion | false | Boolean | Enable basic autocompletion |
| enableLiveAutocompletion | false | Boolean | Enable live autocompletion |
| tabSize | 4 | Number | tabSize |
| debounceChangePeriod | null | Number | A debounce delay period for the onChange event |
| onLoad | | Function | called on editor load. The first argument is the instance of the editor |
| onBeforeLoad | | Function | called before editor load. the first argument is an instance of `ace` |
| onChange | | Function | occurs on document change it has 2 arguments the value and the event. |
| onCopy | | Function | triggered by editor `copy` event, and passes text as argument |
| onPaste | | Function | Triggered by editor `paste` event, and passes text as argument |
| onSelectionChange | | Function | triggered by editor `selectionChange` event, and passes a [Selection](https://ace.c9.io/#nav=api&api=selection) as it's first argument and the event as the second |
| onCursorChange | | Function | triggered by editor `changeCursor` event, and passes a [Selection](https://ace.c9.io/#nav=api&api=selection) as it's first argument and the event as the second |
| onFocus | | Function | triggered by editor `focus` event |
| onBlur | | Function | triggered by editor `blur` event.It has two arguments event and editor |
| onInput | | Function | triggered by editor `input` event |
| onScroll | | Function | triggered by editor `scroll` event |
| onValidate | | Function | triggered, when annotations are changed |
| editorProps | | Object | properties to apply directly to the Ace editor instance |
| setOptions | | Object | [options](https://github.com/ajaxorg/ace/wiki/Configuring-Ace) to apply directly to the Ace editor instance |
| keyboardHandler | | String | corresponding to the keybinding mode to set (such as vim or emacs) |
| commands | | Array | new commands to add to the editor |
| annotations | | Array | annotations to show in the editor i.e. `[{ row: 0, column: 2, type: 'error', text: 'Some error.'}]`, displayed in the gutter |
| markers | | Array | [markers](https://ace.c9.io/#nav=api&api=edit_session) to show in the editor, i.e. `[{ startRow: 0, startCol: 2, endRow: 1, endCol: 20, className: 'error-marker', type: 'background' }]`. Make sure to define the class (eg. ".error-marker") and set `position: absolute` for it. |
| style | | Object | camelCased properties |

@@ -1,2 +0,2 @@

'use strict';
"use strict";

@@ -11,15 +11,15 @@ Object.defineProperty(exports, "__esModule", {

var _react = require('react');
var _react = require("react");
var _react2 = _interopRequireDefault(_react);
var _propTypes = require('prop-types');
var _propTypes = require("prop-types");
var _propTypes2 = _interopRequireDefault(_propTypes);
var _lodash = require('lodash.isequal');
var _lodash = require("lodash.isequal");
var _lodash2 = _interopRequireDefault(_lodash);
var _editorOptions = require('./editorOptions.js');
var _editorOptions = require("./editorOptions.js");

@@ -36,3 +36,3 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _ace$acequire = ace.acequire('ace/range'),
var _ace$acequire = ace.acequire("ace/range"),
Range = _ace$acequire.Range;

@@ -56,3 +56,3 @@

_createClass(ReactAce, [{
key: 'componentDidMount',
key: "componentDidMount",
value: function componentDidMount() {

@@ -81,3 +81,4 @@ var _this2 = this;

annotations = _props.annotations,
markers = _props.markers;
markers = _props.markers,
placeholder = _props.placeholder;

@@ -99,20 +100,25 @@

this.editor.renderer.setScrollMargin(scrollMargin[0], scrollMargin[1], scrollMargin[2], scrollMargin[3]);
this.editor.getSession().setMode('ace/mode/' + mode);
this.editor.setTheme('ace/theme/' + theme);
this.editor.getSession().setMode("ace/mode/" + mode);
this.editor.setTheme("ace/theme/" + theme);
this.editor.setFontSize(fontSize);
this.editor.getSession().setValue(!defaultValue ? value : defaultValue, cursorStart);
this.editor.navigateFileEnd();
if (this.props.navigateToFileEnd) {
this.editor.navigateFileEnd();
}
this.editor.renderer.setShowGutter(showGutter);
this.editor.getSession().setUseWrapMode(wrapEnabled);
this.editor.setShowPrintMargin(showPrintMargin);
this.editor.on('focus', this.onFocus);
this.editor.on('blur', this.onBlur);
this.editor.on('copy', this.onCopy);
this.editor.on('paste', this.onPaste);
this.editor.on('change', this.onChange);
this.editor.on('input', this.onInput);
this.editor.getSession().selection.on('changeSelection', this.onSelectionChange);
this.editor.getSession().selection.on('changeCursor', this.onCursorChange);
this.editor.on("focus", this.onFocus);
this.editor.on("blur", this.onBlur);
this.editor.on("copy", this.onCopy);
this.editor.on("paste", this.onPaste);
this.editor.on("change", this.onChange);
this.editor.on("input", this.onInput);
if (placeholder) {
this.updatePlaceholder(this.editor, placeholder);
}
this.editor.getSession().selection.on("changeSelection", this.onSelectionChange);
this.editor.getSession().selection.on("changeCursor", this.onCursorChange);
if (onValidate) {
this.editor.getSession().on('changeAnnotation', function () {
this.editor.getSession().on("changeAnnotation", function () {
var annotations = _this2.editor.getSession().getAnnotations();

@@ -122,3 +128,3 @@ _this2.props.onValidate(annotations);

}
this.editor.session.on('changeScrollTop', this.onScroll);
this.editor.session.on("changeScrollTop", this.onScroll);
this.editor.getSession().setAnnotations(annotations || []);

@@ -136,3 +142,3 @@ if (markers && markers.length > 0) {

} else if (this.props[option]) {
console.warn('ReactAce: editor option ' + option + ' was activated but not found. Did you need to import a related tool or did you possibly mispell the option?');
console.warn("ReactAce: editor option " + option + " was activated but not found. Did you need to import a related tool or did you possibly mispell the option?");
}

@@ -144,3 +150,3 @@ }

commands.forEach(function (command) {
if (typeof command.exec == 'string') {
if (typeof command.exec == "string") {
_this2.editor.commands.bindKey(command.bindKey, command.exec);

@@ -154,7 +160,7 @@ } else {

if (keyboardHandler) {
this.editor.setKeyboardHandler('ace/keyboard/' + keyboardHandler);
this.editor.setKeyboardHandler("ace/keyboard/" + keyboardHandler);
}
if (className) {
this.refEditor.className += ' ' + className;
this.refEditor.className += " " + className;
}

@@ -173,3 +179,3 @@

}, {
key: 'componentDidUpdate',
key: "componentDidUpdate",
value: function componentDidUpdate(prevProps) {

@@ -188,4 +194,4 @@ var oldProps = prevProps;

var appliedClasses = this.refEditor.className;
var appliedClassesArray = appliedClasses.trim().split(' ');
var oldClassesArray = oldProps.className.trim().split(' ');
var appliedClassesArray = appliedClasses.trim().split(" ");
var oldClassesArray = oldProps.className.trim().split(" ");
oldClassesArray.forEach(function (oldClass) {

@@ -195,3 +201,3 @@ var index = appliedClassesArray.indexOf(oldClass);

});
this.refEditor.className = ' ' + nextProps.className + ' ' + appliedClassesArray.join(' ');
this.refEditor.className = " " + nextProps.className + " " + appliedClassesArray.join(" ");
}

@@ -209,11 +215,14 @@

if (nextProps.placeholder !== oldProps.placeholder) {
this.updatePlaceholder();
}
if (nextProps.mode !== oldProps.mode) {
this.editor.getSession().setMode('ace/mode/' + nextProps.mode);
this.editor.getSession().setMode("ace/mode/" + nextProps.mode);
}
if (nextProps.theme !== oldProps.theme) {
this.editor.setTheme('ace/theme/' + nextProps.theme);
this.editor.setTheme("ace/theme/" + nextProps.theme);
}
if (nextProps.keyboardHandler !== oldProps.keyboardHandler) {
if (nextProps.keyboardHandler) {
this.editor.setKeyboardHandler('ace/keyboard/' + nextProps.keyboardHandler);
this.editor.setKeyboardHandler("ace/keyboard/" + nextProps.keyboardHandler);
} else {

@@ -258,3 +267,3 @@ this.editor.setKeyboardHandler(null);

}, {
key: 'handleScrollMargins',
key: "handleScrollMargins",
value: function handleScrollMargins() {

@@ -266,3 +275,3 @@ var margins = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [0, 0, 0, 0];

}, {
key: 'componentWillUnmount',
key: "componentWillUnmount",
value: function componentWillUnmount() {

@@ -273,3 +282,3 @@ this.editor.destroy();

}, {
key: 'onChange',
key: "onChange",
value: function onChange(event) {

@@ -282,3 +291,3 @@ if (this.props.onChange && !this.silent) {

}, {
key: 'onSelectionChange',
key: "onSelectionChange",
value: function onSelectionChange(event) {

@@ -291,3 +300,3 @@ if (this.props.onSelectionChange) {

}, {
key: 'onCursorChange',
key: "onCursorChange",
value: function onCursorChange(event) {

@@ -300,3 +309,3 @@ if (this.props.onCursorChange) {

}, {
key: 'onInput',
key: "onInput",
value: function onInput(event) {

@@ -306,5 +315,8 @@ if (this.props.onInput) {

}
if (this.props.placeholder) {
this.updatePlaceholder();
}
}
}, {
key: 'onFocus',
key: "onFocus",
value: function onFocus(event) {

@@ -316,3 +328,3 @@ if (this.props.onFocus) {

}, {
key: 'onBlur',
key: "onBlur",
value: function onBlur(event) {

@@ -324,3 +336,3 @@ if (this.props.onBlur) {

}, {
key: 'onCopy',
key: "onCopy",
value: function onCopy(text) {

@@ -332,3 +344,3 @@ if (this.props.onCopy) {

}, {
key: 'onPaste',
key: "onPaste",
value: function onPaste(text) {

@@ -340,3 +352,3 @@ if (this.props.onPaste) {

}, {
key: 'onScroll',
key: "onScroll",
value: function onScroll() {

@@ -348,3 +360,3 @@ if (this.props.onScroll) {

}, {
key: 'handleOptions',
key: "handleOptions",
value: function handleOptions(props) {

@@ -357,3 +369,3 @@ var setOptions = Object.keys(props.setOptions);

}, {
key: 'handleMarkers',
key: "handleMarkers",
value: function handleMarkers(markers) {

@@ -369,6 +381,6 @@ var _this3 = this;

}
// remove background markers
// remove background markers except active line marker and selected word marker
currentMarkers = this.editor.getSession().getMarkers(false);
for (var _i2 in currentMarkers) {
if (currentMarkers.hasOwnProperty(_i2)) {
if (currentMarkers.hasOwnProperty(_i2) && currentMarkers[_i2].clazz !== "ace_active-line" && currentMarkers[_i2].clazz !== "ace_selected-word") {
this.editor.getSession().removeMarker(currentMarkers[_i2].id);

@@ -393,3 +405,29 @@ }

}, {
key: 'updateRef',
key: "updatePlaceholder",
value: function updatePlaceholder() {
// Adapted from https://stackoverflow.com/questions/26695708/how-can-i-add-placeholder-text-when-the-editor-is-empty
var editor = this.editor;
var placeholder = this.props.placeholder;
var showPlaceholder = !editor.session.getValue().length;
var node = editor.renderer.placeholderNode;
if (!showPlaceholder && node) {
editor.renderer.scroller.removeChild(editor.renderer.placeholderNode);
editor.renderer.placeholderNode = null;
} else if (showPlaceholder && !node) {
node = editor.renderer.placeholderNode = document.createElement("div");
node.textContent = placeholder || "";
node.className = "ace_comment ace_placeholder";
node.style.padding = "0 9px";
node.style.position = "absolute";
node.style.zIndex = "3";
editor.renderer.scroller.appendChild(node);
} else if (showPlaceholder && node) {
node.textContent = placeholder;
}
}
}, {
key: "updateRef",
value: function updateRef(item) {

@@ -399,3 +437,3 @@ this.refEditor = item;

}, {
key: 'render',
key: "render",
value: function render() {

@@ -409,3 +447,3 @@ var _props2 = this.props,

var divStyle = _extends({ width: width, height: height }, style);
return _react2.default.createElement('div', { ref: this.updateRef, id: name, style: divStyle });
return _react2.default.createElement("div", { ref: this.updateRef, id: name, style: divStyle });
}

@@ -462,13 +500,15 @@ }]);

enableLiveAutocompletion: _propTypes2.default.oneOfType([_propTypes2.default.bool, _propTypes2.default.array]),
commands: _propTypes2.default.array
navigateToFileEnd: _propTypes2.default.bool,
commands: _propTypes2.default.array,
placeholder: _propTypes2.default.string
};
ReactAce.defaultProps = {
name: 'brace-editor',
name: "brace-editor",
focus: false,
mode: '',
theme: '',
height: '500px',
width: '500px',
value: '',
mode: "",
theme: "",
height: "500px",
width: "500px",
value: "",
fontSize: 12,

@@ -493,3 +533,5 @@ showGutter: true,

enableBasicAutocompletion: false,
enableLiveAutocompletion: false
enableLiveAutocompletion: false,
placeholder: null,
navigateToFileEnd: true
};
{
"name": "react-ace",
"version": "6.4.0",
"version": "6.5.0",
"description": "A react component for Ace Editor",

@@ -30,3 +30,3 @@ "main": "lib/index.js",

"babel-core": "^6.26.3",
"babel-eslint": "^10.0.0",
"babel-eslint": "^10.0.1",
"babel-loader": "^7.0.0",

@@ -41,18 +41,18 @@ "babel-plugin-transform-object-rest-spread": "^6.26.0",

"enzyme-adapter-react-16": "^1.5.0",
"eslint": "5.6.0",
"eslint": "5.16.0",
"eslint-plugin-import": "^2.14.0",
"eslint-plugin-jsx-a11y": "^6.1.1",
"eslint-plugin-react": "7.11.1",
"husky": "^1.1.1",
"jsdom": "^13.0.0",
"mocha": "5.2.0",
"nyc": "13.2.0",
"husky": "^1.3.1",
"jsdom": "^14.0.0",
"mocha": "6.1.4",
"nyc": "14.0.0",
"prettier": "^1.14.3",
"react": "^16.7.0",
"react-dom": "^16.7.0",
"pretty-quick": "^1.7.0",
"react": "^16.8.3",
"react-dom": "^16.8.3",
"react-test-renderer": "^16.7.0",
"pretty-quick": "^1.7.0",
"rimraf": "2.6.3",
"sinon": "7.2.3",
"webpack": "4.29.3",
"sinon": "7.3.2",
"webpack": "4.30.0",
"webpack-cli": "^3.1.0",

@@ -59,0 +59,0 @@ "webpack-dev-server": ">=3.1.11"

@@ -1,9 +0,13 @@

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import isEqual from 'lodash.isequal'
import { editorOptions, editorEvents, getAceInstance,debounce } from './editorOptions.js'
import React, { Component } from "react";
import PropTypes from "prop-types";
import isEqual from "lodash.isequal";
import {
editorOptions,
editorEvents,
getAceInstance,
debounce
} from "./editorOptions.js";
const ace = getAceInstance();
const { Range } = ace.acequire('ace/range');
const { Range } = ace.acequire("ace/range");
export default class ReactAce extends Component {

@@ -39,2 +43,3 @@ constructor(props) {

markers,
placeholder
} = this.props;

@@ -53,23 +58,40 @@

if (this.props.debounceChangePeriod) {
this.onChange = this.debounce(this.onChange, this.props.debounceChangePeriod);
this.onChange = this.debounce(
this.onChange,
this.props.debounceChangePeriod
);
}
this.editor.renderer.setScrollMargin(scrollMargin[0], scrollMargin[1], scrollMargin[2], scrollMargin[3]);
this.editor.renderer.setScrollMargin(
scrollMargin[0],
scrollMargin[1],
scrollMargin[2],
scrollMargin[3]
);
this.editor.getSession().setMode(`ace/mode/${mode}`);
this.editor.setTheme(`ace/theme/${theme}`);
this.editor.setFontSize(fontSize);
this.editor.getSession().setValue(!defaultValue ? value : defaultValue, cursorStart);
this.editor.navigateFileEnd();
this.editor
.getSession()
.setValue(!defaultValue ? value : defaultValue, cursorStart);
if (this.props.navigateToFileEnd) {
this.editor.navigateFileEnd();
}
this.editor.renderer.setShowGutter(showGutter);
this.editor.getSession().setUseWrapMode(wrapEnabled);
this.editor.setShowPrintMargin(showPrintMargin);
this.editor.on('focus', this.onFocus);
this.editor.on('blur', this.onBlur);
this.editor.on('copy', this.onCopy);
this.editor.on('paste', this.onPaste);
this.editor.on('change', this.onChange);
this.editor.on('input', this.onInput);
this.editor.getSession().selection.on('changeSelection', this.onSelectionChange);
this.editor.getSession().selection.on('changeCursor', this.onCursorChange);
this.editor.on("focus", this.onFocus);
this.editor.on("blur", this.onBlur);
this.editor.on("copy", this.onCopy);
this.editor.on("paste", this.onPaste);
this.editor.on("change", this.onChange);
this.editor.on("input", this.onInput);
if (placeholder) {
this.updatePlaceholder(this.editor, placeholder);
}
this.editor
.getSession()
.selection.on("changeSelection", this.onSelectionChange);
this.editor.getSession().selection.on("changeCursor", this.onCursorChange);
if (onValidate) {
this.editor.getSession().on('changeAnnotation', () => {
this.editor.getSession().on("changeAnnotation", () => {
const annotations = this.editor.getSession().getAnnotations();

@@ -79,3 +101,3 @@ this.props.onValidate(annotations);

}
this.editor.session.on('changeScrollTop', this.onScroll);
this.editor.session.on("changeScrollTop", this.onScroll);
this.editor.getSession().setAnnotations(annotations || []);

@@ -94,3 +116,3 @@ if (markers && markers.length > 0) {

console.warn(
`ReactAce: editor option ${option} was activated but not found. Did you need to import a related tool or did you possibly mispell the option?`,
`ReactAce: editor option ${option} was activated but not found. Did you need to import a related tool or did you possibly mispell the option?`
);

@@ -103,3 +125,3 @@ }

commands.forEach(command => {
if (typeof command.exec == 'string') {
if (typeof command.exec == "string") {
this.editor.commands.bindKey(command.bindKey, command.exec);

@@ -113,7 +135,7 @@ } else {

if (keyboardHandler) {
this.editor.setKeyboardHandler('ace/keyboard/' + keyboardHandler);
this.editor.setKeyboardHandler("ace/keyboard/" + keyboardHandler);
}
if (className) {
this.refEditor.className += ' ' + className;
this.refEditor.className += " " + className;
}

@@ -145,4 +167,4 @@

let appliedClasses = this.refEditor.className;
let appliedClassesArray = appliedClasses.trim().split(' ');
let oldClassesArray = oldProps.className.trim().split(' ');
let appliedClassesArray = appliedClasses.trim().split(" ");
let oldClassesArray = oldProps.className.trim().split(" ");
oldClassesArray.forEach(oldClass => {

@@ -152,3 +174,4 @@ let index = appliedClassesArray.indexOf(oldClass);

});
this.refEditor.className = ' ' + nextProps.className + ' ' + appliedClassesArray.join(' ');
this.refEditor.className =
" " + nextProps.className + " " + appliedClassesArray.join(" ");
}

@@ -166,11 +189,16 @@

if (nextProps.placeholder !== oldProps.placeholder) {
this.updatePlaceholder();
}
if (nextProps.mode !== oldProps.mode) {
this.editor.getSession().setMode('ace/mode/' + nextProps.mode);
this.editor.getSession().setMode("ace/mode/" + nextProps.mode);
}
if (nextProps.theme !== oldProps.theme) {
this.editor.setTheme('ace/theme/' + nextProps.theme);
this.editor.setTheme("ace/theme/" + nextProps.theme);
}
if (nextProps.keyboardHandler !== oldProps.keyboardHandler) {
if (nextProps.keyboardHandler) {
this.editor.setKeyboardHandler('ace/keyboard/' + nextProps.keyboardHandler);
this.editor.setKeyboardHandler(
"ace/keyboard/" + nextProps.keyboardHandler
);
} else {

@@ -198,3 +226,6 @@ this.editor.setKeyboardHandler(null);

}
if (!isEqual(nextProps.markers, oldProps.markers) && Array.isArray(nextProps.markers)) {
if (
!isEqual(nextProps.markers, oldProps.markers) &&
Array.isArray(nextProps.markers)
) {
this.handleMarkers(nextProps.markers);

@@ -208,3 +239,6 @@ }

if (prevProps.height !== this.props.height || prevProps.width !== this.props.width) {
if (
prevProps.height !== this.props.height ||
prevProps.width !== this.props.width
) {
this.editor.resize();

@@ -218,3 +252,8 @@ }

handleScrollMargins(margins = [0, 0, 0, 0]) {
this.editor.renderer.setScrollMargins(margins[0], margins[1], margins[2], margins[3]);
this.editor.renderer.setScrollMargins(
margins[0],
margins[1],
margins[2],
margins[3]
);
}

@@ -250,2 +289,5 @@

}
if (this.props.placeholder) {
this.updatePlaceholder();
}
}

@@ -297,6 +339,10 @@ onFocus(event) {

}
// remove background markers
// remove background markers except active line marker and selected word marker
currentMarkers = this.editor.getSession().getMarkers(false);
for (const i in currentMarkers) {
if (currentMarkers.hasOwnProperty(i)) {
if (
currentMarkers.hasOwnProperty(i) &&
currentMarkers[i].clazz !== "ace_active-line" &&
currentMarkers[i].clazz !== "ace_selected-word"
) {
this.editor.getSession().removeMarker(currentMarkers[i].id);

@@ -306,8 +352,42 @@ }

// add new markers
markers.forEach(({ startRow, startCol, endRow, endCol, className, type, inFront = false }) => {
const range = new Range(startRow, startCol, endRow, endCol);
this.editor.getSession().addMarker(range, className, type, inFront);
});
markers.forEach(
({
startRow,
startCol,
endRow,
endCol,
className,
type,
inFront = false
}) => {
const range = new Range(startRow, startCol, endRow, endCol);
this.editor.getSession().addMarker(range, className, type, inFront);
}
);
}
updatePlaceholder() {
// Adapted from https://stackoverflow.com/questions/26695708/how-can-i-add-placeholder-text-when-the-editor-is-empty
const editor = this.editor;
const { placeholder } = this.props;
const showPlaceholder = !editor.session.getValue().length;
let node = editor.renderer.placeholderNode;
if (!showPlaceholder && node) {
editor.renderer.scroller.removeChild(editor.renderer.placeholderNode);
editor.renderer.placeholderNode = null;
} else if (showPlaceholder && !node) {
node = editor.renderer.placeholderNode = document.createElement("div");
node.textContent = placeholder || "";
node.className = "ace_comment ace_placeholder";
node.style.padding = "0 9px";
node.style.position = "absolute";
node.style.zIndex = "3";
editor.renderer.scroller.appendChild(node);
} else if (showPlaceholder && node) {
node.textContent = placeholder;
}
}
updateRef(item) {

@@ -364,15 +444,23 @@ this.refEditor = item;

wrapEnabled: PropTypes.bool,
enableBasicAutocompletion: PropTypes.oneOfType([PropTypes.bool, PropTypes.array]),
enableLiveAutocompletion: PropTypes.oneOfType([PropTypes.bool, PropTypes.array]),
enableBasicAutocompletion: PropTypes.oneOfType([
PropTypes.bool,
PropTypes.array
]),
enableLiveAutocompletion: PropTypes.oneOfType([
PropTypes.bool,
PropTypes.array
]),
navigateToFileEnd: PropTypes.bool,
commands: PropTypes.array,
placeholder: PropTypes.string
};
ReactAce.defaultProps = {
name: 'brace-editor',
name: "brace-editor",
focus: false,
mode: '',
theme: '',
height: '500px',
width: '500px',
value: '',
mode: "",
theme: "",
height: "500px",
width: "500px",
value: "",
fontSize: 12,

@@ -398,2 +486,4 @@ showGutter: true,

enableLiveAutocompletion: false,
placeholder: null,
navigateToFileEnd: true
};

@@ -1,22 +0,20 @@

import { expect } from 'chai';
import React from 'react';
import sinon from 'sinon';
import ace from 'brace';
import Enzyme, { mount } from 'enzyme';
import AceEditor from '../../src/ace.js';
import brace from 'brace'; // eslint-disable-line no-unused-vars
import Adapter from 'enzyme-adapter-react-16';
import { expect } from "chai";
import React from "react";
import sinon from "sinon";
import ace from "brace";
import Enzyme, { mount } from "enzyme";
import AceEditor from "../../src/ace.js";
import brace from "brace"; // eslint-disable-line no-unused-vars
import Adapter from "enzyme-adapter-react-16";
Enzyme.configure({ adapter: new Adapter() });
describe('Ace Component', () => {
describe("Ace Component", () => {
// Required for the document.getElementById used by Ace can work in the test environment
const domElement = document.getElementById('app');
const domElement = document.getElementById("app");
const mountOptions = {
attachTo: domElement,
attachTo: domElement
};
describe('General', () => {
it('should render without problems with defaults properties', () => {
describe("General", () => {
it("should render without problems with defaults properties", () => {
const wrapper = mount(<AceEditor />, mountOptions);

@@ -26,35 +24,45 @@ expect(wrapper).to.exist;

it('should trigger console warn if editorOption is called', () => {
const stub = sinon.stub(console, 'warn');
const wrapper = mount(<AceEditor enableBasicAutocompletion={true} />, mountOptions);
it("should trigger console warn if editorOption is called", () => {
const stub = sinon.stub(console, "warn");
const wrapper = mount(
<AceEditor enableBasicAutocompletion={true} />,
mountOptions
);
expect(wrapper).to.exist;
expect(console.warn.calledWith('ReactAce: editor option enableBasicAutocompletion was activated but not found. Did you need to import a related tool or did you possibly mispell the option?') ).to.be.true;
expect(
console.warn.calledWith(
"ReactAce: editor option enableBasicAutocompletion was activated but not found. Did you need to import a related tool or did you possibly mispell the option?"
)
).to.be.true;
stub.restore();
});
it('should render without problems with defaults properties, defaultValue and keyboardHandler', () => {
const wrapper = mount(<AceEditor
keyboardHandler="vim"
defaultValue={'hi james'}
/>, mountOptions);
it("should render without problems with defaults properties, defaultValue and keyboardHandler", () => {
const wrapper = mount(
<AceEditor keyboardHandler="vim" defaultValue={"hi james"} />,
mountOptions
);
expect(wrapper).to.exist;
let editor = wrapper.instance().editor;
expect(editor.getValue()).to.equal('hi james');
expect(editor.getValue()).to.equal("hi james");
});
it('should render editor options not default values', () => {
const wrapper = mount((<AceEditor
keyboardHandler="vim"
setOptions={{
tabSize: 2
}}
/>), mountOptions);
it("should render editor options not default values", () => {
const wrapper = mount(
<AceEditor
keyboardHandler="vim"
setOptions={{
tabSize: 2
}}
/>,
mountOptions
);
expect(wrapper).to.exist;
let editor = wrapper.instance().editor;
expect(editor.getOption('tabSize')).to.equal(2);
expect(editor.getOption("tabSize")).to.equal(2);
});
it('should get the ace library from the onBeforeLoad callback', () => {
it("should get the ace library from the onBeforeLoad callback", () => {
const beforeLoadCallback = sinon.spy();
mount(<AceEditor onBeforeLoad={beforeLoadCallback}/>, mountOptions);
mount(<AceEditor onBeforeLoad={beforeLoadCallback} />, mountOptions);

@@ -65,5 +73,5 @@ expect(beforeLoadCallback.callCount).to.equal(1);

it('should get the editor from the onLoad callback', () => {
it("should get the editor from the onLoad callback", () => {
const loadCallback = sinon.spy();
const wrapper = mount(<AceEditor onLoad={loadCallback}/>, mountOptions);
const wrapper = mount(<AceEditor onLoad={loadCallback} />, mountOptions);

@@ -77,8 +85,11 @@ // Get the editor

it('should set the editor props to the Ace element', () => {
it("should set the editor props to the Ace element", () => {
const editorProperties = {
react: 'setFromReact',
test: 'setFromTest',
react: "setFromReact",
test: "setFromTest"
};
const wrapper = mount(<AceEditor editorProps={editorProperties}/>, mountOptions);
const wrapper = mount(
<AceEditor editorProps={editorProperties} />,
mountOptions
);

@@ -91,44 +102,54 @@ const editor = wrapper.instance().editor;

it('should set the command for the Ace element', () => {
it("should set the command for the Ace element", () => {
const commandsMock = [
{
name: 'myReactAceTest',
bindKey: {win: 'Ctrl-M', mac: 'Command-M'},
exec: () => {
},
name: "myReactAceTest",
bindKey: { win: "Ctrl-M", mac: "Command-M" },
exec: () => {},
readOnly: true
},
{
name: 'myTestCommand',
bindKey: {win: 'Ctrl-W', mac: 'Command-W'},
exec: () => {
},
name: "myTestCommand",
bindKey: { win: "Ctrl-W", mac: "Command-W" },
exec: () => {},
readOnly: true
}
];
const wrapper = mount(<AceEditor commands={commandsMock}/>, mountOptions);
const wrapper = mount(
<AceEditor commands={commandsMock} />,
mountOptions
);
const editor = wrapper.instance().editor;
expect(editor.commands.commands.myReactAceTest).to.deep.equal(commandsMock[0]);
expect(editor.commands.commands.myTestCommand).to.deep.equal(commandsMock[1]);
expect(editor.commands.commands.myReactAceTest).to.deep.equal(
commandsMock[0]
);
expect(editor.commands.commands.myTestCommand).to.deep.equal(
commandsMock[1]
);
});
it('should change the command binding for the Ace element', () => {
it("should change the command binding for the Ace element", () => {
const commandsMock = [
{
bindKey: {win: 'ctrl-d', mac: 'command-d'},
name: 'selectMoreAfter',
exec: 'selectMoreAfter'
bindKey: { win: "ctrl-d", mac: "command-d" },
name: "selectMoreAfter",
exec: "selectMoreAfter"
}
];
const wrapper = mount(<AceEditor commands={commandsMock}/>, mountOptions);
const wrapper = mount(
<AceEditor commands={commandsMock} />,
mountOptions
);
const editor = wrapper.instance().editor;
const expected = [editor.commands.commands.removeline, 'selectMoreAfter']
expect(editor.commands.commandKeyBinding['ctrl-d']).to.deep.equal(expected);
const expected = [editor.commands.commands.removeline, "selectMoreAfter"];
expect(editor.commands.commandKeyBinding["ctrl-d"]).to.deep.equal(
expected
);
});
it('should trigger the focus on mount', () => {
it("should trigger the focus on mount", () => {
const onFocusCallback = sinon.spy();
mount(<AceEditor focus={true} onFocus={onFocusCallback}/>, mountOptions);
mount(<AceEditor focus={true} onFocus={onFocusCallback} />, mountOptions);

@@ -139,65 +160,100 @@ // Read the focus

it('should set up the markers', () => {
const markers = [{
startRow: 3,
type: 'text',
className: 'test-marker'
}];
const wrapper = mount(<AceEditor markers={markers}/>, mountOptions);
it("should set up the placeholder text with no value set", () => {
const placeholder = "Placeholder Text Here";
const wrapper = mount(
<AceEditor placeholder={placeholder} />,
mountOptions
);
// Read the markers
const editor = wrapper.instance().editor;
expect(editor.getSession().getMarkers()['3'].clazz).to.equal('test-marker');
expect(editor.getSession().getMarkers()['3'].type).to.equal('text');
expect(editor.renderer.placeholderNode).to.exist;
expect(editor.renderer.placeholderNode.textContent).to.equal(placeholder);
});
it('should update the markers', () => {
it("should not set up the placeholder text with value set", () => {
const placeholder = "Placeholder Text Here";
const wrapper = mount(
<AceEditor placeholder={placeholder} value="Code here" />,
mountOptions
);
// Read the markers
const editor = wrapper.instance().editor;
expect(editor.renderer.placeholderNode).to.not.exist;
});
it("should set up the markers", () => {
const markers = [
{
startRow: 3,
type: "text",
className: "test-marker"
}
];
const wrapper = mount(<AceEditor markers={markers} />, mountOptions);
// Read the markers
const editor = wrapper.instance().editor;
expect(editor.getSession().getMarkers()["3"].clazz).to.equal(
"test-marker"
);
expect(editor.getSession().getMarkers()["3"].type).to.equal("text");
});
it("should update the markers", () => {
const oldMarkers = [
{
startRow: 4,
type: 'text',
className: 'test-marker-old'
type: "text",
className: "test-marker-old"
},
{
startRow: 7,
type: 'foo',
className: 'test-marker-old',
type: "foo",
className: "test-marker-old",
inFront: true
}
];
const markers = [{
startRow: 3,
type: 'text',
className: 'test-marker-new',
inFront: true,
},{
startRow: 5,
type: 'text',
className: 'test-marker-new'
}];
const wrapper = mount(<AceEditor markers={oldMarkers}/>, mountOptions);
const markers = [
{
startRow: 3,
type: "text",
className: "test-marker-new",
inFront: true
},
{
startRow: 5,
type: "text",
className: "test-marker-new"
}
];
const wrapper = mount(<AceEditor markers={oldMarkers} />, mountOptions);
// Read the markers
const editor = wrapper.instance().editor;
expect(editor.getSession().getMarkers()['3'].clazz).to.equal('test-marker-old');
expect(editor.getSession().getMarkers()['3'].type).to.equal('text');
wrapper.setProps({markers});
expect(editor.getSession().getMarkers()["3"].clazz).to.equal(
"test-marker-old"
);
expect(editor.getSession().getMarkers()["3"].type).to.equal("text");
wrapper.setProps({ markers });
const editorB = wrapper.instance().editor;
expect(editorB.getSession().getMarkers()['6'].clazz).to.equal('test-marker-new');
expect(editorB.getSession().getMarkers()['6'].type).to.equal('text');
expect(editorB.getSession().getMarkers()["6"].clazz).to.equal(
"test-marker-new"
);
expect(editorB.getSession().getMarkers()["6"].type).to.equal("text");
});
it('should clear the markers', () => {
it("should clear the markers", () => {
const oldMarkers = [
{
startRow: 4,
type: 'text',
className: 'test-marker-old'
type: "text",
className: "test-marker-old"
},
{
startRow: 7,
type: 'foo',
className: 'test-marker-old',
type: "foo",
className: "test-marker-old",
inFront: true

@@ -207,32 +263,73 @@ }

const markers = [];
const wrapper = mount(<AceEditor markers={oldMarkers}/>, mountOptions);
const wrapper = mount(<AceEditor markers={oldMarkers} />, mountOptions);
// Read the markers
const editor = wrapper.instance().editor;
expect(editor.getSession().getMarkers()['3'].clazz).to.equal('test-marker-old');
expect(editor.getSession().getMarkers()['3'].type).to.equal('text');
wrapper.setProps({markers});
expect(Object.keys(editor.getSession().getMarkers())).to.deep.equal([
"1",
"2",
"3"
]);
expect(editor.getSession().getMarkers()["3"].clazz).to.equal(
"test-marker-old"
);
expect(editor.getSession().getMarkers()["3"].type).to.equal("text");
wrapper.setProps({ markers });
const editorB = wrapper.instance().editor;
expect(editorB.getSession().getMarkers()).to.deep.equal({})
expect(Object.keys(editorB.getSession().getMarkers())).to.deep.equal([
"1",
"2"
]);
});
it('should add annotations and clear them', () => {
const annotations = [{
row: 3, // must be 0 based
column: 4, // must be 0 based
text: 'error.message', // text to show in tooltip
type: 'error'
}]
const wrapper = mount(<AceEditor/>, mountOptions);
it("should not remove active line and selected word highlight when clearing markers", () => {
const newMarkers = [
{
startRow: 4,
type: "text",
className: "test-marker"
}
];
const wrapper = mount(
<AceEditor highlightActiveLine markers={[]} />,
mountOptions
);
const editor = wrapper.instance().editor;
wrapper.setProps({annotations});
const bgMarkers = editor.getSession().getMarkers(false);
expect(Object.keys(bgMarkers)).to.deep.equal(["1", "2"]);
expect(bgMarkers["1"]).to.have.property("clazz", "ace_active-line");
expect(bgMarkers["2"]).to.have.property("clazz", "ace_selected-word");
wrapper.setProps({ markers: newMarkers });
const bgMarkersNew = editor.getSession().getMarkers(false);
expect(Object.keys(bgMarkersNew)).to.deep.equal(["1", "2", "3"]);
expect(bgMarkersNew["1"]).to.have.property("clazz", "ace_active-line");
expect(bgMarkersNew["2"]).to.have.property("clazz", "ace_selected-word");
expect(bgMarkersNew["3"]).to.have.property("clazz", "test-marker");
});
it("should add annotations and clear them", () => {
const annotations = [
{
row: 3, // must be 0 based
column: 4, // must be 0 based
text: "error.message", // text to show in tooltip
type: "error"
}
];
const wrapper = mount(<AceEditor />, mountOptions);
const editor = wrapper.instance().editor;
wrapper.setProps({ annotations });
expect(editor.getSession().getAnnotations()).to.deep.equal(annotations);
wrapper.setProps({annotations: null});
wrapper.setProps({ annotations: null });
expect(editor.getSession().getAnnotations()).to.deep.equal([]);
})
});
it('should add annotations with changing editor value', () => {
it("should add annotations with changing editor value", () => {
// See https://github.com/securingsincity/react-ace/issues/300
const annotations = [{ row: 0, column: 0, text: 'error.message', type: 'error' }];
const annotations = [
{ row: 0, column: 0, text: "error.message", type: "error" }
];
const initialText = `Initial

@@ -242,3 +339,6 @@ text`;

text`;
const wrapper = mount(<AceEditor annotations={[]} value={initialText}/>, mountOptions);
const wrapper = mount(
<AceEditor annotations={[]} value={initialText} />,
mountOptions
);
const editor = wrapper.instance().editor;

@@ -250,6 +350,8 @@ wrapper.setProps({

expect(editor.renderer.$gutterLayer.$annotations).to.have.length(1);
expect(editor.renderer.$gutterLayer.$annotations[0]).to.have.property('className');
})
expect(editor.renderer.$gutterLayer.$annotations[0]).to.have.property(
"className"
);
});
it('should set editor to null on componentWillUnmount', () => {
it("should set editor to null on componentWillUnmount", () => {
const wrapper = mount(<AceEditor />, mountOptions);

@@ -262,14 +364,11 @@ expect(wrapper.getElement().editor).to.not.equal(null);

});
});
//inspired from https://github.com/goodtimeaj/debounce-function/blob/master/test/unit/debounce-function.js
describe('Debounce function', () => {
it('function arg should be called when after timeout', (done) => {
const wrapper = mount(<AceEditor/>, mountOptions);
describe("Debounce function", () => {
it("function arg should be called when after timeout", done => {
const wrapper = mount(<AceEditor />, mountOptions);
var flag = false;
var func = wrapper.instance().debounce(function() {
flag = true
flag = true;
}, 100);

@@ -284,8 +383,8 @@ func();

it('timer should be reset on successive call', (done) => {
const wrapper = mount(<AceEditor/>, mountOptions);
it("timer should be reset on successive call", done => {
const wrapper = mount(<AceEditor />, mountOptions);
var flag = false;
var func = wrapper.instance().debounce(function() {
flag = true
flag = true;
}, 100);

@@ -307,4 +406,4 @@ func();

it('function should be called only once per period', (done) => {
const wrapper = mount(<AceEditor/>, mountOptions);
it("function should be called only once per period", done => {
const wrapper = mount(<AceEditor />, mountOptions);

@@ -317,3 +416,3 @@ var flag1 = false;

}
flag1 = true
flag1 = true;
}, 100);

@@ -340,18 +439,23 @@

});
it('should keep initial value after undo event', () => {
it("should keep initial value after undo event", () => {
const onInput = () => {
const editor = wrapper.instance().editor;
editor.undo();
expect(editor.getValue()).to.equal('foobar');
expect(editor.getValue()).to.equal("foobar");
};
const wrapper = mount(<AceEditor value="foobar" onInput={onInput} />, mountOptions);
const wrapper = mount(
<AceEditor value="foobar" onInput={onInput} />,
mountOptions
);
});
});
describe('Events', () => {
it('should call the onChange method callback', () => {
describe("Events", () => {
it("should call the onChange method callback", () => {
const onChangeCallback = sinon.spy();
const wrapper = mount(<AceEditor onChange={onChangeCallback}/>, mountOptions);
const wrapper = mount(
<AceEditor onChange={onChangeCallback} />,
mountOptions
);

@@ -362,3 +466,3 @@ // Check is not previously called

// Trigger the change event
const expectText = 'React Ace Test';
const expectText = "React Ace Test";
wrapper.instance().editor.setValue(expectText, 1);

@@ -368,9 +472,12 @@

expect(onChangeCallback.getCall(0).args[0]).to.equal(expectText);
expect(onChangeCallback.getCall(0).args[1].action).to.eq('insert')
expect(onChangeCallback.getCall(0).args[1].action).to.eq("insert");
});
it('should limit call to onChange (debounce)', (done) => {
it("should limit call to onChange (debounce)", done => {
const period = 100;
const onChangeCallback = sinon.spy();
const wrapper = mount(<AceEditor onChange={onChangeCallback} debounceChangePeriod={period}/>, mountOptions);
const wrapper = mount(
<AceEditor onChange={onChangeCallback} debounceChangePeriod={period} />,
mountOptions
);

@@ -381,4 +488,4 @@ // Check is not previously called

// Trigger the change event
const expectText = 'React Ace Test';
const expectText2 = 'React Ace Test2';
const expectText = "React Ace Test";
const expectText2 = "React Ace Test2";
wrapper.instance().editor.setValue(expectText, 1);

@@ -389,6 +496,6 @@ wrapper.instance().editor.setValue(expectText2, 1);

setTimeout(function(){
setTimeout(function() {
expect(onChangeCallback.callCount).to.equal(1);
expect(onChangeCallback.getCall(0).args[0]).to.equal(expectText2);
expect(onChangeCallback.getCall(0).args[1].action).to.eq('insert');
expect(onChangeCallback.getCall(0).args[1].action).to.eq("insert");
onChangeCallback.resetHistory();

@@ -398,14 +505,17 @@ wrapper.instance().editor.setValue(expectText2, 1);

expect(onChangeCallback.callCount).to.equal(0);
setTimeout(function(){
setTimeout(function() {
expect(onChangeCallback.callCount).to.equal(1);
expect(onChangeCallback.getCall(0).args[0]).to.equal(expectText);
expect(onChangeCallback.getCall(0).args[1].action).to.eq('insert');
expect(onChangeCallback.getCall(0).args[1].action).to.eq("insert");
done();
},100);
},100);
}, 100);
}, 100);
});
it('should call the onCopy method', () => {
it("should call the onCopy method", () => {
const onCopyCallback = sinon.spy();
const wrapper = mount(<AceEditor onCopy={onCopyCallback}/>, mountOptions);
const wrapper = mount(
<AceEditor onCopy={onCopyCallback} />,
mountOptions
);

@@ -416,3 +526,3 @@ // Check is not previously called

// Trigger the copy event
const expectText = 'React Ace Test';
const expectText = "React Ace Test";
wrapper.instance().onCopy(expectText);

@@ -424,5 +534,8 @@

it('should call the onPaste method', () => {
it("should call the onPaste method", () => {
const onPasteCallback = sinon.spy();
const wrapper = mount(<AceEditor onPaste={onPasteCallback}/>, mountOptions);
const wrapper = mount(
<AceEditor onPaste={onPasteCallback} />,
mountOptions
);

@@ -433,3 +546,3 @@ // Check is not previously called

// Trigger the Paste event
const expectText = 'React Ace Test';
const expectText = "React Ace Test";
wrapper.instance().onPaste(expectText);

@@ -441,5 +554,8 @@

it('should call the onFocus method callback', () => {
it("should call the onFocus method callback", () => {
const onFocusCallback = sinon.spy();
const wrapper = mount(<AceEditor onFocus={onFocusCallback}/>, mountOptions);
const wrapper = mount(
<AceEditor onFocus={onFocusCallback} />,
mountOptions
);

@@ -453,7 +569,7 @@ // Check is not previously called

expect(onFocusCallback.callCount).to.equal(1);
expect(onFocusCallback.args.length).to.equal(1)
expect(onFocusCallback.args.length).to.equal(1);
});
it('should call the onSelectionChange method callback', (done) => {
let onSelectionChange = function(){}
it("should call the onSelectionChange method callback", done => {
let onSelectionChange = function() {};
const value = `

@@ -468,13 +584,18 @@ function main(value) {

onSelectionChange = function(selection) {
const content = wrapper.instance().editor.session.getTextRange(selection.getRange());
expect(content).to.equal(value)
done()
}
wrapper.setProps({onSelectionChange})
wrapper.instance().editor.getSession().selection.selectAll()
const content = wrapper
.instance()
.editor.session.getTextRange(selection.getRange());
expect(content).to.equal(value);
done();
};
wrapper.setProps({ onSelectionChange });
wrapper
.instance()
.editor.getSession()
.selection.selectAll();
});
it('should call the onCursorChange method callback', (done) => {
let onCursorChange = function(){}
const value =`
it("should call the onCursorChange method callback", done => {
let onCursorChange = function() {};
const value = `
function main(value) {

@@ -484,17 +605,28 @@ console.log('hi james')

}
`
`;
const wrapper = mount(<AceEditor value={value} />, mountOptions);
onCursorChange = function (selection) {
expect(selection.getCursor()).to.deep.equal({ row: 0, column: 0 })
done()
}
wrapper.setProps({onCursorChange})
expect(wrapper.instance().editor.getSession().selection.getCursor()).to.deep.equal({row: 5, column: 6})
wrapper.instance().editor.getSession().selection.moveCursorTo(0, 0)
onCursorChange = function(selection) {
expect(selection.getCursor()).to.deep.equal({ row: 0, column: 0 });
done();
};
wrapper.setProps({ onCursorChange });
expect(
wrapper
.instance()
.editor.getSession()
.selection.getCursor()
).to.deep.equal({ row: 5, column: 6 });
wrapper
.instance()
.editor.getSession()
.selection.moveCursorTo(0, 0);
});
it('should call the onBlur method callback', () => {
it("should call the onBlur method callback", () => {
const onBlurCallback = sinon.spy();
const wrapper = mount(<AceEditor onBlur={onBlurCallback}/>, mountOptions);
const wrapper = mount(
<AceEditor onBlur={onBlurCallback} />,
mountOptions
);

@@ -508,6 +640,6 @@ // Check is not previously called

expect(onBlurCallback.callCount).to.equal(1);
expect(onBlurCallback.args.length).to.equal(1)
expect(onBlurCallback.args.length).to.equal(1);
});
it('should not trigger a component error to call the events without setting the props', () => {
it("should not trigger a component error to call the events without setting the props", () => {
const wrapper = mount(<AceEditor />, mountOptions);

@@ -517,21 +649,19 @@

wrapper.instance().onChange();
wrapper.instance().onCopy('copy');
wrapper.instance().onPaste('paste');
wrapper.instance().onCopy("copy");
wrapper.instance().onPaste("paste");
wrapper.instance().onFocus();
wrapper.instance().onBlur();
});
});
describe('ComponentDidUpdate', () => {
it('should update the editorOptions on componentDidUpdate', () => {
describe("ComponentDidUpdate", () => {
it("should update the editorOptions on componentDidUpdate", () => {
const options = {
printMargin: 80
};
const wrapper = mount(<AceEditor setOptions={options}/>, mountOptions);
const wrapper = mount(<AceEditor setOptions={options} />, mountOptions);
// Read set value
const editor = wrapper.instance().editor;
expect(editor.getOption('printMargin')).to.equal(options.printMargin);
expect(editor.getOption("printMargin")).to.equal(options.printMargin);

@@ -541,11 +671,12 @@ // Now trigger the componentDidUpdate

printMargin: 200,
animatedScroll: true,
animatedScroll: true
};
wrapper.setProps({setOptions: newOptions});
expect(editor.getOption('printMargin')).to.equal(newOptions.printMargin);
expect(editor.getOption('animatedScroll')).to.equal(newOptions.animatedScroll);
wrapper.setProps({ setOptions: newOptions });
expect(editor.getOption("printMargin")).to.equal(newOptions.printMargin);
expect(editor.getOption("animatedScroll")).to.equal(
newOptions.animatedScroll
);
});
it('should update the editorOptions on componentDidUpdate', () => {
it("should update the editorOptions on componentDidUpdate", () => {
const wrapper = mount(<AceEditor minLines={1} />, mountOptions);

@@ -555,28 +686,21 @@

const editor = wrapper.instance().editor;
expect(editor.getOption('minLines')).to.equal(1);
expect(editor.getOption("minLines")).to.equal(1);
wrapper.setProps({minLines: 2});
expect(editor.getOption('minLines')).to.equal(2);
wrapper.setProps({ minLines: 2 });
expect(editor.getOption("minLines")).to.equal(2);
});
it('should update the mode on componentDidUpdate', () => {
it("should update the mode on componentDidUpdate", () => {
const wrapper = mount(<AceEditor mode="javascript" />, mountOptions);
// Read set value
const oldMode = wrapper.first('AceEditor').props()
const oldMode = wrapper.first("AceEditor").props();
wrapper.setProps({mode: 'elixir'});
const newMode = wrapper.first('AceEditor').props()
wrapper.setProps({ mode: "elixir" });
const newMode = wrapper.first("AceEditor").props();
expect(oldMode).to.not.deep.equal(newMode);
});
it('should update many props on componentDidUpdate', () => {
const wrapper = mount((
it("should update many props on componentDidUpdate", () => {
const wrapper = mount(
<AceEditor

@@ -591,10 +715,12 @@ theme="github"

width="200px"
/>), mountOptions);
/>,
mountOptions
);
// Read set value
const oldMode = wrapper.first('AceEditor').props()
const oldMode = wrapper.first("AceEditor").props();
wrapper.setProps({
theme: 'solarized',
keyboardHandler: 'emacs',
theme: "solarized",
keyboardHandler: "emacs",
fontSize: 18,

@@ -604,31 +730,28 @@ wrapEnabled: false,

showGutter: true,
height: '120px',
width: '220px'
height: "120px",
width: "220px"
});
const newMode = wrapper.first('AceEditor').props()
const newMode = wrapper.first("AceEditor").props();
expect(oldMode).to.not.deep.equal(newMode);
});
it("should update the className on componentDidUpdate", () => {
const className = "old-class";
const wrapper = mount(<AceEditor className={className} />, mountOptions);
it('should update the className on componentDidUpdate', () => {
const className = 'old-class';
const wrapper = mount(<AceEditor className={className}/>, mountOptions);
// Read set value
let editor = wrapper.instance().refEditor;
expect(editor.className).to.equal(' ace_editor ace-tm old-class');
expect(editor.className).to.equal(" ace_editor ace-tm old-class");
// Now trigger the componentDidUpdate
const newClassName = 'new-class';
wrapper.setProps({className: newClassName});
const newClassName = "new-class";
wrapper.setProps({ className: newClassName });
editor = wrapper.instance().refEditor;
expect(editor.className).to.equal(' new-class ace_editor ace-tm');
expect(editor.className).to.equal(" new-class ace_editor ace-tm");
});
it("should update the value on componentDidUpdate", () => {
const startValue = "start value";
const wrapper = mount(<AceEditor value={startValue} />, mountOptions);
it('should update the value on componentDidUpdate', () => {
const startValue = 'start value';
const wrapper = mount(<AceEditor value={startValue}/>, mountOptions);
// Read set value

@@ -639,4 +762,4 @@ let editor = wrapper.instance().editor;

// Now trigger the componentDidUpdate
const newValue = 'updated value';
wrapper.setProps({value: newValue});
const newValue = "updated value";
wrapper.setProps({ value: newValue });
editor = wrapper.instance().editor;

@@ -646,5 +769,8 @@ expect(editor.getValue()).to.equal(newValue);

it('should trigger the focus on componentDidUpdate', () => {
it("should trigger the focus on componentDidUpdate", () => {
const onFocusCallback = sinon.spy();
const wrapper = mount(<AceEditor onFocus={onFocusCallback}/>, mountOptions);
const wrapper = mount(
<AceEditor onFocus={onFocusCallback} />,
mountOptions
);

@@ -655,9 +781,6 @@ // Read the focus

// Now trigger the componentDidUpdate
wrapper.setProps({focus: true});
wrapper.setProps({ focus: true });
expect(onFocusCallback.callCount).to.equal(1);
});
});
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc