blob: eb8deac8ab3adcda7f676dbe91b389402e5de15a [file] [log] [blame]
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
import React from "react";
import ReactDOM from "react-dom";
import {CodeEditor} from './codeeditor';
import {Beautify} from './beautify';
import {ZenModeOverlay} from './zenmodeoverlay';
// list of JSHINT errors to ignore: gets around problem of anonymous functions not being valid
const ignorableErrors = [
'Missing name in function declaration.',
"['{a}'] is better written in dot notation."
];
/**
* A pre-packaged JS editor panel for use on the Edit Index / Mango pages. Includes options for a title, zen mode
* icon and beautify button.
*/
export class CodeEditorPanel extends React.Component {
static defaultProps = {
id: 'code-editor',
className: '',
defaultCode: '',
title: '',
docLink: '',
allowZenMode: true,
blur () {}
};
getStoreState = () => {
return {
zenModeEnabled: false,
code: this.props.defaultCode
};
};
UNSAFE_componentWillReceiveProps(nextProps) {
if (nextProps.defaultCode !== this.props.defaultCode) {
this.setState({ code: nextProps.defaultCode });
}
}
getZenModeIcon = () => {
if (this.props.allowZenMode) {
return <span className="fonticon fonticon-resize-full zen-editor-icon" title="Enter Zen mode" onClick={this.enterZenMode}></span>;
}
};
getDocIcon = () => {
if (this.props.docLink) {
return (
<a className="help-link"
data-bypass="true"
href={this.props.docLink}
target="_blank"
rel="noopener noreferrer"
>
<i className="fonticon-help-circled"></i>
</a>
);
}
};
getZenModeOverlay = () => {
if (this.state.zenModeEnabled) {
return (
<ZenModeOverlay
defaultCode={this.state.code}
mode={this.props.mode}
ignorableErrors={ignorableErrors}
onExit={this.exitZenMode} />
);
}
};
enterZenMode = () => {
this.setState({
zenModeEnabled: true,
code: this.codeEditor.getValue()
});
};
exitZenMode = (content) => {
this.setState({ zenModeEnabled: false });
this.getEditor().setValue(content);
};
getEditor = () => {
return this.codeEditor;
};
getValue = () => {
return this.getEditor().getValue();
};
beautify = (code) => {
this.setState({ code: code });
this.getEditor().setValue(code);
};
update = () => {
this.getEditor().setValue(this.state.code);
};
state = this.getStoreState();
render() {
var classes = '';
if (this.props.className) {
classes = this.props.className;
}
return (
<div className={classes}>
<label>
<span>{this.props.title}</span>
{this.getDocIcon()}
{this.getZenModeIcon()}
</label>
<CodeEditor
id={this.props.id}
ref={node => this.codeEditor = node}
mode="javascript"
defaultCode={this.state.code}
showGutter={true}
ignorableErrors={ignorableErrors}
setHeightToLineCount={true}
maxLines={10000}
blur={this.props.blur}
/>
<Beautify code={this.state.code} beautifiedCode={this.beautify} />
{this.getZenModeOverlay()}
</div>
);
}
}