"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = void 0;

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));

var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));

var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));

var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));

var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));

var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));

var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));

var _propTypes = _interopRequireDefault(require("prop-types"));

var _react = _interopRequireDefault(require("react"));

var _debug = _interopRequireDefault(require("debug"));

var _mathquill = _interopRequireDefault(require("@pie-framework/mathquill"));

var _updateSpans = require("../updateSpans");

function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; }

function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }

var MQ;

if (typeof window !== 'undefined') {
  MQ = _mathquill["default"].getInterface(2);
}

var log = (0, _debug["default"])('pie-lib:math-input:mq:static');
var REGEX = /\\MathQuillMathField\[r\d*\]\{(.*?)\}/g;
var WHITESPACE_REGEX = / /g;

function stripSpaces() {
  var string = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
  return string.replace(WHITESPACE_REGEX, '');
}

function countBraces(latex) {
  var count = 0;

  for (var i = 0; i < (latex || '').length; i++) {
    if (latex[i] === '{') {
      count++;
    }
  }

  return count;
}
/**
 * Wrapper for MathQuill MQ.MathField.
 */


var Static = /*#__PURE__*/function (_React$Component) {
  (0, _inherits2["default"])(Static, _React$Component);

  var _super = _createSuper(Static);

  function Static(props) {
    var _this;

    (0, _classCallCheck2["default"])(this, Static);
    _this = _super.call(this, props);
    (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "createLiveRegion", function () {
      _this.liveRegion = document.createElement('div');
      _this.liveRegion.style.position = 'absolute';
      _this.liveRegion.style.width = '1px';
      _this.liveRegion.style.height = '1px';
      _this.liveRegion.style.marginTop = '-1px';
      _this.liveRegion.style.clip = 'rect(1px, 1px, 1px, 1px)';
      _this.liveRegion.style.overflow = 'hidden';

      _this.liveRegion.setAttribute('aria-live', 'polite');

      _this.liveRegion.setAttribute('aria-atomic', 'true');

      document.body.appendChild(_this.liveRegion);
    });
    (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "addEventListeners", function () {
      var input = _this.inputRef.current;

      if (input) {
        input.addEventListener('keydown', _this.handleKeyDown);
        input.addEventListener('click', _this.handleMathKeyboardClick);
      }
    });
    (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "removeEventListeners", function () {
      var input = _this.inputRef.current;

      if (input) {
        input.removeEventListener('keydown', _this.handleKeyDown);
        input.removeEventListener('click', _this.handleMathKeyboardClick);
      }
    });
    (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "removeLiveRegion", function () {
      if (_this.liveRegion) {
        document.body.removeChild(_this.liveRegion);
        _this.liveRegion = null;
      }
    });
    (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "handleKeyDown", function (event) {
      if ((event === null || event === void 0 ? void 0 : event.key) === 'Backspace' || (event === null || event === void 0 ? void 0 : event.key) === 'Delete') {
        _this.setState({
          isDeleteKeyPressed: true
        });
      }

      _this.setState({
        inputSource: 'keyboard'
      });
    });
    (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "handleMathKeyboardClick", function () {
      _this.setState({
        inputSource: 'mathKeyboard'
      });
    });
    (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "onInputEdit", function (field) {
      if (!_this.mathField) {
        return;
      }

      var name = _this.props.getFieldName(field, _this.mathField.innerFields);

      if (_this.props.onSubFieldChange) {
        var _this$inputRef;

        // eslint-disable-next-line no-useless-escape
        var regexMatch = field.latex().match(/[0-9]\\ \\frac\{[^\{]*\}\{ \}/);

        if ((_this$inputRef = _this.inputRef) !== null && _this$inputRef !== void 0 && _this$inputRef.current && regexMatch && regexMatch !== null && regexMatch !== void 0 && regexMatch.length) {
          try {
            field.__controller.cursor.insLeftOf(field.__controller.cursor.parent[-1].parent);

            field.el().dispatchEvent(new KeyboardEvent('keydown', {
              keyCode: 8
            }));
          } catch (e) {
            // eslint-disable-next-line no-console
            console.error(e.toString());
          }
        } else {
          _this.props.onSubFieldChange(name, field.latex());
        }
      }

      _this.announceLatexConversion(field.latex());
    });
    (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "announceLatexConversion", function (newLatex) {
      if (!_this.state) {
        console.error('State is not initialized');
        return;
      }

      var _this$state = _this.state,
          previousLatex = _this$state.previousLatex,
          inputSource = _this$state.inputSource,
          isDeleteKeyPressed = _this$state.isDeleteKeyPressed;
      var announcement = 'Converted to math symbol';

      if (inputSource === 'keyboard' && !isDeleteKeyPressed) {
        var newBraces = countBraces(newLatex);
        var oldBraces = countBraces(previousLatex);

        if (newBraces > oldBraces) {
          _this.announceMessage(announcement);
        } else {
          try {
            _this.mathField.parseLatex(previousLatex);

            _this.mathField.parseLatex(newLatex);

            if (newLatex == previousLatex) {
              _this.announceMessage(announcement);
            }
          } catch (e) {
            console.warn('Error parsing latex:', e.message);
            console.warn(e);
          }
        }
      }

      _this.setState({
        previousLatex: newLatex,
        isDeleteKeyPressed: false
      });
    });
    (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "announceMessage", function (message) {
      _this.setState({
        previousLatex: ''
      });

      if (_this.liveRegion) {
        _this.liveRegion.textContent = message; // Clear the message after it is announced

        setTimeout(function () {
          _this.liveRegion.textContent = '';
        }, 500);
      }
    });
    (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "update", function () {
      if (!MQ) {
        throw new Error('MQ is not defined - but component has mounted?');
      }

      if (!_this.mathField) {
        var _this$inputRef2;

        _this.mathField = MQ.StaticMath((_this$inputRef2 = _this.inputRef) === null || _this$inputRef2 === void 0 ? void 0 : _this$inputRef2.current, {
          handlers: {
            edit: _this.onInputEdit.bind((0, _assertThisInitialized2["default"])(_this))
          }
        });
      }

      try {
        _this.mathField.parseLatex(_this.props.latex);

        _this.mathField.latex(_this.props.latex);
      } catch (e) {
        // default latex if received has errors
        _this.mathField.latex('\\MathQuillMathField[r1]{}');
      }
    });
    (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "blur", function () {
      log('blur mathfield');

      _this.mathField.blur();
    });
    (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "focus", function () {
      log('focus mathfield...');

      _this.mathField.focus();
    });
    (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "onFocus", function (e) {
      try {
        var rootBlock = e.target.parentElement.nextSibling;
        var id = parseInt(rootBlock.getAttribute('mathquill-block-id'), 10);

        if (!id) {
          rootBlock = rootBlock.parentElement;
          id = parseInt(rootBlock.getAttribute('mathquill-block-id'), 10);
        }

        var innerField = _this.mathField.innerFields.find(function (f) {
          return f.id === id;
        });

        if (innerField) {
          var name = _this.props.getFieldName(innerField, _this.mathField.innerFields);

          if (_this.props.setInput) {
            _this.props.setInput(innerField);
          }

          _this.props.onSubFieldFocus(name, innerField);
        }
      } catch (err) {
        // eslint-disable-next-line no-console
        console.error('error finding root block', err.message);
      }
    });
    _this.state = {
      announcement: '',
      previousLatex: '',
      inputSource: null,
      isDeleteKeyPressed: false
    };
    _this.inputRef = /*#__PURE__*/_react["default"].createRef();
    return _this;
  }

  (0, _createClass2["default"])(Static, [{
    key: "componentDidMount",
    value: function componentDidMount() {
      this.update();
      (0, _updateSpans.updateSpans)();
      this.createLiveRegion();
      this.addEventListeners();
    }
  }, {
    key: "componentDidUpdate",
    value: function componentDidUpdate() {
      this.update();
      (0, _updateSpans.updateSpans)();
    }
  }, {
    key: "componentWillUnmount",
    value: function componentWillUnmount() {
      this.removeLiveRegion();
      this.removeEventListeners();
    }
  }, {
    key: "shouldComponentUpdate",
    value: function shouldComponentUpdate(nextProps) {
      try {
        var parsedLatex = this.mathField.parseLatex(nextProps.latex);
        var stripped = stripSpaces(parsedLatex);
        var newFieldCount = (nextProps.latex.match(REGEX) || []).length;
        var out = stripped !== stripSpaces(this.mathField.latex().trim()) || newFieldCount !== Object.keys(this.mathField.innerFields).length / 2;
        log('[shouldComponentUpdate] ', out);
        return out;
      } catch (e) {
        // eslint-disable-next-line no-console
        console.warn('Error parsing latex:', e.message, 'skip update'); // eslint-disable-next-line no-console

        console.warn(e);
        return false;
      }
    }
  }, {
    key: "render",
    value: function render() {
      var _this$props = this.props,
          onBlur = _this$props.onBlur,
          className = _this$props.className;
      return /*#__PURE__*/_react["default"].createElement("span", {
        className: className,
        onFocus: this.onFocus,
        onBlur: onBlur,
        ref: this.inputRef
      });
    }
  }]);
  return Static;
}(_react["default"].Component);

exports["default"] = Static;
(0, _defineProperty2["default"])(Static, "propTypes", {
  latex: _propTypes["default"].string.isRequired,
  onFocus: _propTypes["default"].func,
  onBlur: _propTypes["default"].func,
  className: _propTypes["default"].string,
  getFieldName: _propTypes["default"].func,
  onSubFieldChange: _propTypes["default"].func,
  onSubFieldFocus: _propTypes["default"].func,
  setInput: _propTypes["default"].func
});
(0, _defineProperty2["default"])(Static, "defaultProps", {
  getFieldName: function getFieldName() {}
});
//# sourceMappingURL=static.js.map