"use strict";

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

var React = _interopRequireWildcard(require("react"));

var _prosemirrorState = require("prosemirror-state");

var _prosemirrorModel = require("prosemirror-model");

var _prosemirrorTransform = require("prosemirror-transform");

var _prosemirrorView = require("prosemirror-view");

var _licitDocAttrsStep = require("@modusoperandi/licit-doc-attrs-step");

var _uuid = _interopRequireDefault(require("./uuid"));

require("./listType.css");

var _CustomStyleItem = _interopRequireDefault(require("./CustomStyleItem"));

var _PopUpPosition = require("./PopUpPosition");

var _createPopUp = _interopRequireDefault(require("./createPopUp"));

var _AlertInfo = _interopRequireDefault(require("./AlertInfo"));

var _CustomStyleSubMenu = _interopRequireDefault(require("./CustomStyleSubMenu"));

var _CustomStyleEditor = _interopRequireDefault(require("./CustomStyleEditor"));

var _CustomStyleCommand = require("../CustomStyleCommand");

var _TextAlignCommand = require("../TextAlignCommand");

var _TextLineSpacingCommand = require("../TextLineSpacingCommand");

var _ParagraphSpacingCommand = require("../ParagraphSpacingCommand");

var _ParagraphNodeSpec = require("../ParagraphNodeSpec");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }

function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

// [FS] IRAD-1039 2020-09-24
// UI to show the list buttons
class CustomMenuUI extends React.PureComponent {
  constructor() {
    super(...arguments);

    _defineProperty(this, "_activeCommand", null);

    _defineProperty(this, "_popUp", null);

    _defineProperty(this, "_stylePopup", null);

    _defineProperty(this, "_styleName", null);

    _defineProperty(this, "_menuItemHeight", 28);

    _defineProperty(this, "props", void 0);

    _defineProperty(this, "_id", (0, _uuid.default)());

    _defineProperty(this, "_selectedIndex", 0);

    _defineProperty(this, "state", {
      expanded: false,
      style: {
        display: 'none',
        top: '',
        left: ''
      }
    });

    _defineProperty(this, "_onUIEnter", (command, event) => {
      if (command.shouldRespondToUIEvent(event)) {
        // check the mouse clicked on down arror to show sub menu
        if (event.currentTarget.className === 'czi-custom-menu-item edit-icon') {
          this.showSubMenu(command, event);
        } else {
          this._execute(command, event);
        }
      }
    });

    _defineProperty(this, "_execute", (command, e) => {
      if (undefined !== command) {
        const {
          dispatch,
          editorState,
          editorView,
          onCommand
        } = this.props;
        command.execute(editorState, dispatch, editorView, e);
        onCommand && onCommand();
      }
    });
  }

  render() {
    const {
      dispatch,
      editorState,
      editorView,
      commandGroups,
      staticCommand,
      onCommand
    } = this.props;
    const children = [];
    const children1 = [];
    let counter = 0;
    let selecteClassName = '';
    const selectedName = this.getTheSelectedCustomStyle(this.props.editorState);
    commandGroups.forEach((group, ii) => {
      Object.keys(group).forEach(label => {
        const command = group[label];
        const hasText = _ParagraphNodeSpec.RESERVED_STYLE_NONE !== label;
        counter++;

        if (label === selectedName && '' === selecteClassName) {
          selecteClassName = 'selectbackground';
          this._selectedIndex = counter;
        } else {
          selecteClassName = '';
        }

        children.push( /*#__PURE__*/React.createElement(_CustomStyleItem.default, {
          command: command,
          disabled: editorView && editorView.disabled ? true : false,
          dispatch: dispatch,
          editorState: editorState,
          editorView: editorView,
          hasText: hasText,
          key: label,
          label: label,
          onClick: this._onUIEnter,
          onCommand: onCommand,
          onMouseEnter: this._onUIEnter,
          selectionClassName: selecteClassName,
          value: command
        }));
      });
    });
    staticCommand.forEach((group, ii) => {
      Object.keys(group).forEach(label => {
        const command = group[label];
        children1.push( /*#__PURE__*/React.createElement(_CustomStyleItem.default, {
          command: command,
          disabled: editorView && editorView.disabled ? true : false,
          dispatch: dispatch,
          editorState: editorState,
          editorView: editorView,
          hasText: false,
          key: label,
          label: command._customStyleName,
          onClick: this._onUIEnter,
          onCommand: onCommand,
          onMouseEnter: this._onUIEnter,
          selectionClassName: '',
          value: command
        }));
      });
    });
    return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
      className: "dropbtn",
      id: this._id
    }, /*#__PURE__*/React.createElement("div", {
      className: "stylenames"
    }, children), /*#__PURE__*/React.createElement("hr", null), children1));
  }

  componentDidMount() {
    const styleDiv = document.getElementsByClassName('stylenames')[0];
    styleDiv.scrollTop = this._menuItemHeight * this._selectedIndex - this._menuItemHeight * 2 - 5;
  }

  isAllowedNode(node) {
    return node.type.name === 'paragraph' || node.type.name === 'ordered_list';
  }

  //shows the alignment and line spacing option
  showSubMenu(command, event) {
    const anchor = event ? event.currentTarget : null; // close the popup toggling effect

    if (this._stylePopup) {
      this._stylePopup.close();

      this._stylePopup = null;
      return;
    }

    this._popUp = (0, _createPopUp.default)(_CustomStyleSubMenu.default, {
      command: command
    }, {
      anchor,
      autoDismiss: true,
      IsChildDialog: true,
      onClose: val => {
        if (this._popUp) {
          this._popUp = null;

          if (undefined !== val && val.command._customStyle) {
            // do edit,remove,rename code here
            if ('remove' === val.type) {
              // [FS] IRAD-1223 2021-03-01
              // Not allow user to remove already in used custom style with numbering, which shall break the heirarchy.
              if (!(0, _CustomStyleCommand.isCustomStyleAlreadyApplied)(val.command._customStyleName, this.props.editorState)) {
                this.props.editorView.runtime.removeStyle(val.command._customStyleName).then(success => {
                  // [FS] IRAD-1099 2020-11-17
                  // Issue fix: Even the applied style is removed the style name is showing in the editor
                  this.removeCustomStyleName(this.props.editorState, val.command._customStyleName, this.props.editorView.dispatch);
                });
              } else {
                this.showAlert();
              }
            } else if ('rename' === val.type) {
              this.showStyleWindow(command, event, 2);
            } else {
              this.showStyleWindow(command, event, 1);
            }
          }
        }
      }
    });
  } // [FS] IRAD-1099 2020-11-17
  // Issue fix: Even the applied style is removed the style name is showing in the editor


  removeCustomStyleName(editorState, removedStyleName, dispatch) {
    const {
      selection,
      doc
    } = editorState;
    let {
      from,
      to
    } = selection;
    const {
      empty
    } = selection;

    if (empty) {
      from = selection.$from.before(1);
      to = selection.$to.after(1);
    }

    let tr = editorState.tr;
    const customStyleName = _ParagraphNodeSpec.RESERVED_STYLE_NONE;
    const tasks = [];
    const textAlignNode = [];
    doc.nodesBetween(0, doc.nodeSize - 2, (node, pos) => {
      if (node.content && node.content.content && node.content.content.length) {
        if (node.content && node.content.content && node.content.content[0].marks && node.content.content[0].marks.length) {
          node.content.content[0].marks.some(mark => {
            if (node.attrs.styleName === removedStyleName) {
              tasks.push({
                node,
                pos,
                mark
              });
            }
          });
        } else {
          textAlignNode.push({
            node,
            pos
          });
        }
      }
    });

    if (!tasks.length) {
      textAlignNode.forEach(eachnode => {
        const {
          node
        } = eachnode;
        node.attrs.styleName = customStyleName;
      }); // to remove both text align format and line spacing

      tr = this.removeTextAlignAndLineSpacing(tr, editorState.schema);
    }

    tasks.forEach(job => {
      const {
        node,
        mark,
        pos
      } = job;
      tr = tr.removeMark(pos, pos + node.nodeSize, mark.type); // reset the custom style name to NONE after remove the styles

      node.attrs.styleName = customStyleName;
    }); // to remove both text align format and line spacing

    tr = this.removeTextAlignAndLineSpacing(tr, editorState.schema);
    editorState.doc.nodesBetween(from, to, (node, startPos) => {
      if (node.type.name === 'paragraph') {
        tr = tr.setNodeMarkup(startPos, undefined, node.attrs);
      }
    });

    if (dispatch && tr.docChanged) {
      dispatch(tr);
      return true;
    }

    return false;
  } // to remove the text align, line spacing, paragraph spacing after and before format if applied.


  removeTextAlignAndLineSpacing(tr, schema) {
    tr = (0, _TextAlignCommand.setTextAlign)(tr, schema, null);
    tr = (0, _TextLineSpacingCommand.setTextLineSpacing)(tr, schema, null);
    tr = (0, _ParagraphSpacingCommand.setParagraphSpacing)(tr, schema, '0', true);
    tr = (0, _ParagraphSpacingCommand.setParagraphSpacing)(tr, schema, '0', false);
    return tr;
  }

  showAlert() {
    const anchor = null;
    this._popUp = (0, _createPopUp.default)(_AlertInfo.default, {
      content: 'This custom style already in use, by removing this style breaks the heirarchy ',
      title: 'Style Error!!!'
    }, {
      anchor,
      position: _PopUpPosition.atViewportCenter,
      onClose: val => {
        if (this._popUp) {
          this._popUp = null;
        }
      }
    });
  } //shows the alignment and line spacing option


  showStyleWindow(command, event, mode) {
    // const anchor = event ? event.currentTarget : null;
    // close the popup toggling effect
    if (this._stylePopup) {
      this._stylePopup.close();

      this._stylePopup = null; // return;
    }

    this._styleName = command._customStyleName;
    this._stylePopup = (0, _createPopUp.default)(_CustomStyleEditor.default, {
      styleName: command._customStyleName,
      mode: mode,
      //edit
      description: command._customStyle.description,
      styles: command._customStyle.styles,
      editorView: this.props.editorView
    }, {
      position: _PopUpPosition.atViewportCenter,
      autoDismiss: false,
      IsChildDialog: false,
      onClose: val => {
        if (this._stylePopup) {
          //handle save style object part here
          if (undefined !== val) {
            const {
              dispatch,
              runtime
            } = this.props.editorView; // [FS] IRAD-1112 2020-12-14
            // Issue fix: Duplicate style created while modified the style name.

            delete val.runtime;

            if (1 === mode) {
              // update
              delete val.editorView;
              let tr; // [FS] IRAD-1350 2021-05-19
              // blocks edit if the style is already applied in editor

              if ((0, _CustomStyleCommand.isLevelUpdated)(this.props.editorState, val.styleName, val)) {
                runtime.saveStyle(val).then(result => {
                  if (result) {
                    result.forEach(obj => {
                      if (val.styleName === obj.styleName) {
                        tr = (0, _CustomStyleCommand.updateDocument)(this.props.editorState, this.props.editorState.tr, val.styleName, obj);
                      }
                    });

                    if (tr) {
                      dispatch(tr);
                    }
                  }

                  this.props.editorView.focus();

                  this._stylePopup.close();

                  this._stylePopup = null;
                });
              } else {
                this.showAlert();
              }
            } else {
              // rename
              runtime.renameStyle(this._styleName, val.styleName).then(result => {
                // [FS] IRAD-1133 2021-01-06
                // Issue fix: After modify a custom style, the modified style not applied to the paragraph.
                if (null != result) {
                  let tr;
                  result.forEach(obj => {
                    if (val.styleName === obj.styleName) {
                      tr = this.renameStyleInDocument(this.props.editorState, this.props.editorState.tr, this._styleName, val.styleName, obj.styles);
                    }
                  });

                  if (tr) {
                    dispatch(tr);
                  }

                  this._stylePopup.close();

                  this._stylePopup = null;
                  this.props.editorView.focus();
                }
              });
            }
          }
        }

        this.props.editorView.focus();
      }
    });
  } // [FS] IRAD-1237 2021-05-05
  // Issue fix: Rename style not working on the fly


  renameStyleInDocument(state, tr, oldStyleName, styleName, style) {
    const {
      doc
    } = state;
    doc.descendants(function (child, pos) {
      if (oldStyleName === child.attrs.styleName) {
        child.attrs.styleName = styleName;
        tr = tr.setNodeMarkup(pos, undefined, child.attrs);
      }
    });
    return tr;
  } // [FS] IRAD-1308 2020-04-21
  // To get the customstylename of the selected paragraph


  getTheSelectedCustomStyle(editorState) {
    const {
      selection,
      doc
    } = editorState;
    const {
      from,
      to
    } = selection;
    let customStyleName = _ParagraphNodeSpec.RESERVED_STYLE_NONE;
    doc.nodesBetween(from, to, (node, pos) => {
      if (this.isAllowedNode(node)) {
        if (node.attrs.styleName) {
          customStyleName = node.attrs.styleName;
        }
      }
    });
    return customStyleName;
  }

}

var _default = CustomMenuUI;
exports.default = _default;