"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _react = require("react");
var _utils = require("../utils");
var _utils2 = require("../../utils");
var _classnames = _interopRequireDefault(require("classnames"));
var _constants = require("../../constants");
var _jsxRuntime = require("react/jsx-runtime");
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } // Copyright 1999-2023. Plesk International GmbH. All rights reserved.
/**
 * `CodeEditor` component is used for editing text as code with proper color highlighting according to selected programming language.
 * @since 0.0.61
 */
class CodeEditor extends _react.Component {
  constructor() {
    super(...arguments);
    (0, _defineProperty2.default)(this, "state", {
      content: this.props.children,
      lineSeparator: this.getLineSeparator(this.props.children),
      options: {
        lineNumbers: true,
        lineWrapping: true,
        matchBrackets: true,
        matchTags: {
          bothTags: true
        },
        indentUnit: 4,
        indentWithTabs: true,
        enterMode: 'keep',
        tabMode: 'shift',
        autoRefresh: true,
        extraKeys: {
          'Ctrl-S': 'save'
        },
        direction: (0, _utils2.isRtl)() ? 'rtl' : 'ltr'
      }
    });
    (0, _defineProperty2.default)(this, "textareaNode", /*#__PURE__*/(0, _react.createRef)());
    (0, _defineProperty2.default)(this, "CodeMirror", void 0);
    (0, _defineProperty2.default)(this, "codeMirror", void 0);
    (0, _defineProperty2.default)(this, "handleScroll", () => {
      const {
        onScroll
      } = this.props;
      if (!this.codeMirror) {
        return;
      }
      (0, _utils.safeInvoke)(onScroll, this.codeMirror.getScrollInfo());
    });
    (0, _defineProperty2.default)(this, "handleChange", (doc, changes) => {
      if (this.props.readOnly || changes.origin === 'setValue') {
        return;
      }
      const {
        lineSeparator
      } = this.state;
      const {
        onChange
      } = this.props;
      const content = doc.getValue(lineSeparator);
      this.setState({
        content
      }, () => {
        (0, _utils.safeInvoke)(onChange, content);
      });
    });
  }
  static getDerivedStateFromProps(_ref, state) {
    let {
      readOnly,
      autofocus,
      options
    } = _ref;
    return {
      options: {
        ...state.options,
        ...options,
        autofocus,
        readOnly
      }
    };
  }
  componentDidMount() {
    Promise.resolve().then(() => _interopRequireWildcard(require( /* webpackChunkName: "codemirror" */'./CodeMirror'))).then(_ref2 => {
      let {
        CodeMirror
      } = _ref2;
      if (!this.textareaNode.current) {
        return;
      }
      if (this.codeMirror) {
        this.codeMirror.toTextArea();
      }
      this.CodeMirror = CodeMirror;
      const {
        onInit,
        scrollPosition
      } = this.props;
      const {
        options
      } = this.state;
      this.codeMirror = CodeMirror.fromTextArea(this.textareaNode.current, options);
      this.codeMirror.on('scroll', this.handleScroll);
      if (scrollPosition) {
        this.codeMirror.scrollTo(scrollPosition.left, scrollPosition.top);
      }
      this.updateMode(this.props);
      // Save fn typing is missed by some reason.
      // @ts-ignore
      CodeMirror.commands.save = this.props.onSave;
      CodeMirror.commands.find = CodeMirror.commands.findPersistent;
      CodeMirror.commands.findNext = CodeMirror.commands.findPersistentNext;
      CodeMirror.commands.findPrev = CodeMirror.commands.findPersistentPrev;
      (0, _utils.safeInvoke)(onInit, this.codeMirror.getWrapperElement());
      this.codeMirror.on('change', this.handleChange);
    });
  }
  componentDidUpdate(prevProps) {
    if (!this.codeMirror) {
      return;
    }
    Object.entries(this.state.options).forEach(_ref3 => {
      let [key, value] = _ref3;
      this.codeMirror?.setOption(key, value);
    });
    const {
      children,
      mode,
      fileName,
      autofocus,
      scrollPosition
    } = this.props;
    this.updateMode({
      mode,
      fileName
    });
    const newContent = children || '';
    if (newContent !== prevProps.children && newContent !== this.codeMirror.getValue(this.state.lineSeparator)) {
      const prevScrollPosition = prevProps.scrollPosition || this.codeMirror.getScrollInfo();
      this.codeMirror.setValue(newContent);
      this.codeMirror.scrollTo(prevScrollPosition.left, prevScrollPosition.top);
      if (autofocus) {
        this.codeMirror.focus();
      }
    } else if (scrollPosition && scrollPosition !== prevProps.scrollPosition) {
      this.codeMirror.scrollTo(scrollPosition.left, scrollPosition.top);
    }
  }
  componentWillUnmount() {
    if (this.codeMirror) {
      this.codeMirror.off('scroll', this.handleScroll);
      this.codeMirror.toTextArea();
    }
  }
  findModeByFileName(fileName) {
    const modeInfo = this.CodeMirror?.findModeByFileName(fileName);
    if (modeInfo) {
      return modeInfo.mode;
    }
    return null;
  }
  updateMode(_ref4) {
    let {
      mode,
      fileName
    } = _ref4;
    if (!mode && fileName) {
      mode = this.findModeByFileName(fileName);
    }
    if (!mode) {
      return;
    }
    this.codeMirror?.setOption('mode', mode);
  }
  getLineSeparator() {
    let content = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
    const sep = /^.*?(\r\n?|\n)/.exec(content);
    return sep && sep[1] ? sep[1] : '\n';
  }
  render() {
    const {
      baseClassName,
      className,
      mode,
      fileName,
      readOnly,
      autofocus,
      children,
      onInit,
      onChange,
      onSave,
      options,
      scrollPosition,
      onScroll,
      ...props
    } = this.props;
    const {
      content
    } = this.state;
    return /*#__PURE__*/(0, _jsxRuntime.jsx)("textarea", {
      style: {
        display: 'none'
      },
      ref: this.textareaNode,
      className: (0, _classnames.default)(baseClassName, className),
      defaultValue: content,
      ...props
    });
  }
}
(0, _defineProperty2.default)(CodeEditor, "defaultProps", {
  mode: '',
  fileName: '',
  children: '',
  readOnly: false,
  autofocus: false,
  onInit: null,
  onChange: null,
  onSave: null,
  options: null,
  className: null,
  baseClassName: `${_constants.CLS_PREFIX}code-editor`,
  scrollPosition: undefined,
  onScroll: undefined
});
var _default = exports.default = CodeEditor;