text: "use strict";
  
  Object.defineProperty(exports, "__esModule", {
    value: true
  });
  exports.default = PortableTextInput;
  
  var _isEqual2 = _interopRequireDefault(require("lodash/isEqual"));
  
  var _uniqueId2 = _interopRequireDefault(require("lodash/uniqueId"));
  
  var _classnames = _interopRequireDefault(require("classnames"));
  
  var _react = _interopRequireWildcard(require("react"));
  
  var _portableTextEditor = require("@sanity/portable-text-editor");
  
  var _activateOnFocus = _interopRequireDefault(require("part:@sanity/components/utilities/activate-on-focus"));
  
  var _portal = require("part:@sanity/components/utilities/portal");
  
  var _stackedEscapable = _interopRequireDefault(require("part:@sanity/components/utilities/stacked-escapable"));
  
  var _path = require("../../typedefs/path");
  
  var _PortableTextInput = _interopRequireDefault(require("./PortableTextInput.css"));
  
  var _BlockObject = require("./Objects/BlockObject");
  
  var _InlineObject = require("./Objects/InlineObject");
  
  var _EditObject = require("./Objects/EditObject");
  
  var _Annotation = require("./Text/Annotation");
  
  var _Blockquote = _interopRequireDefault(require("./Text/Blockquote"));
  
  var _Header = _interopRequireDefault(require("./Text/Header"));
  
  var _Paragraph = _interopRequireDefault(require("./Text/Paragraph"));
  
  var _Editor = _interopRequireDefault(require("./Editor"));
  
  function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
  
  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (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 _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
  
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
  
  function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
  
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
  
  function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
  
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
  
  function PortableTextInput(props) {
    var focusPath = props.focusPath,
        hasFocus = props.hasFocus,
        hotkeys = props.hotkeys,
        isFullscreen = props.isFullscreen,
        markers = props.markers,
        onBlur = props.onBlur,
        onChange = props.onChange,
        onCopy = props.onCopy,
        onFocus = props.onFocus,
        onPaste = props.onPaste,
        onToggleFullscreen = props.onToggleFullscreen,
        presence = props.presence,
        readOnly = props.readOnly,
        renderBlockActions = props.renderBlockActions,
        renderCustomMarkers = props.renderCustomMarkers,
        value = props.value;
    var editor = (0, _portableTextEditor.usePortableTextEditor)();
    var selection = (0, _portableTextEditor.usePortableTextEditorSelection)();
    var ptFeatures = (0, _portableTextEditor.getPortableTextFeatures)(props.type); // States
  
    var _useState = (0, _react.useState)(false),
        _useState2 = _slicedToArray(_useState, 2),
        isActive = _useState2[0],
        setIsActive = _useState2[1];
  
    var _useState3 = (0, _react.useState)(null),
        _useState4 = _slicedToArray(_useState3, 2),
        objectEditData = _useState4[0],
        setObjectEditData = _useState4[1];
  
    var _useState5 = (0, _react.useState)(false),
        _useState6 = _slicedToArray(_useState5, 2),
        showValidationTooltip = _useState6[0],
        setShowValidationTooltip = _useState6[1];
  
    var _useState7 = (0, _react.useState)(undefined),
        _useState8 = _slicedToArray(_useState7, 2),
        initialSelection = _useState8[0],
        setInitialSelection = _useState8[1]; // This will open the editing interfaces automatically according to the focusPath.
    // eslint-disable-next-line complexity
  
  
    (0, _react.useEffect)(() => {
      if (focusPath && objectEditData === null) {
        var isChild = focusPath[1] === 'children';
        var isMarkdef = focusPath[1] === 'markDefs';
        var blockSegment = focusPath[0]; // Annotation focus paths
  
        if (isMarkdef && blockSegment && typeof blockSegment === 'object') {
          var block = value && value.find(blk => blk._key === blockSegment._key);
          var markDefSegment = focusPath[2]; // eslint-disable-next-line max-depth
  
          if (block && markDefSegment && typeof markDefSegment === 'object') {
            var span = block.children.find(child => Array.isArray(child.marks) && child.marks.includes(markDefSegment._key)); // eslint-disable-next-line max-depth
  
            if (span) {
              var spanPath = [blockSegment, 'children', {
                _key: span._key
              }];
              setIsActive(true);
  
              _portableTextEditor.PortableTextEditor.select(editor, {
                focus: {
                  path: spanPath,
                  offset: 0
                },
                anchor: {
                  path: spanPath,
                  offset: 0
                }
              });
  
              setObjectEditData({
                editorPath: spanPath,
                formBuilderPath: focusPath.slice(0, 3),
                kind: 'annotation'
              });
            }
          }
  
          return;
        } // Block focus paths
  
  
        if (focusPath && (isChild && focusPath.length > 3 || !isChild && focusPath.length > 1)) {
          var kind = 'blockObject';
          var path = focusPath.slice(0, 1); // eslint-disable-next-line max-depth
  
          if (isChild) {
            kind = 'inlineObject';
            path = path.concat(focusPath.slice(1, 3));
          }
  
          setIsActive(true);
  
          _portableTextEditor.PortableTextEditor.select(editor, {
            focus: {
              path,
              offset: 0
            },
            anchor: {
              path,
              offset: 0
            }
          }); // Make it go to selection first, then load  the editing interface
  
  
          setTimeout(() => setObjectEditData({
            editorPath: path,
            formBuilderPath: path,
            kind
          }));
        }
      }
    }, [focusPath]); // Set as active whenever we have focus inside the editor.
  
    (0, _react.useEffect)(() => {
      if (hasFocus) {
        setIsActive(true);
      }
    }, [hasFocus]); // Update the FormBuilder focusPath as we get a new selection from the editor
    // This will also set presence on that path
  
    (0, _react.useEffect)(() => {
      // If the focuspath is a annotation (markDef), don't update focusPath,
      // as this will close the editing interface
      var isAnnotationPath = focusPath && focusPath[1] === 'markDefs';
  
      if (selection && !objectEditData && !isAnnotationPath) {
        var isCollapsed = (0, _isEqual2.default)(selection.focus.path, selection.anchor.path) && selection.focus.offset === selection.anchor.offset; // Only do it when anchor and focus is the same, or the component will re-render
        // in the middle of selecting multiple lines with the keyboard.
        // TODO: handle this better when we support live cursors
  
        if (isCollapsed && !(0, _isEqual2.default)(focusPath, selection.focus.path)) {
          onFocus(selection.focus.path);
        }
      }
    }, [selection, initialSelection, objectEditData]);
  
    function handleCloseValidationResults() {
      setShowValidationTooltip(false);
    }
  
    function handleToggleValidationResults() {
      setShowValidationTooltip(!showValidationTooltip);
    }
  
    function handleToggleFullscreen() {
      setInitialSelection(_portableTextEditor.PortableTextEditor.getSelection(editor));
      onToggleFullscreen();
  
      _portableTextEditor.PortableTextEditor.focus(editor);
    }
  
    function focus() {
      _portableTextEditor.PortableTextEditor.focus(editor);
    }
  
    function blur() {
      _portableTextEditor.PortableTextEditor.blur(editor);
    }
  
    function handleActivate() {
      setIsActive(true);
      focus();
    }
  
    function handleFormBuilderEditObjectChange(patchEvent, path) {
      var _patchEvent = patchEvent;
      path.slice(0).reverse().forEach(segment => {
        _patchEvent = _patchEvent.prefixAll(segment);
      });
  
      _patchEvent.patches.map(patch => props.patche$.next(patch));
  
      onChange(_patchEvent);
    }
  
    function handleEditObjectFormBuilderFocus(nextPath) {
      if (objectEditData && nextPath) {
        onFocus(nextPath);
      }
    }
  
    function handleEditObjectFormBuilderBlur() {// Do nothing
    }
  
    function renderBlock(block, blockType, attributes, defaultRender) {
      var returned = defaultRender(block); // Text blocks
  
      if (block._type === ptFeatures.types.block.name) {
        // Deal with block style
        if (block.style === 'blockquote') {
          returned = /*#__PURE__*/_react.default.createElement(_Blockquote.default, null, returned);
        } else if (['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(block.style)) {
          returned = /*#__PURE__*/_react.default.createElement(_Header.default, {
            style: block.style
          }, returned);
        } else {
          returned = /*#__PURE__*/_react.default.createElement(_Paragraph.default, null, returned);
        }
      } else {
        // Object blocks
        var blockMarkers = markers.filter(marker => typeof marker.path[0] === 'object' && marker.path[0]._key === block._key);
        returned = /*#__PURE__*/_react.default.createElement(_BlockObject.BlockObject, {
          attributes: attributes,
          editor: editor,
          markers: blockMarkers,
          onChange: handleFormBuilderEditObjectChange,
          onFocus: onFocus,
          readOnly: readOnly,
          type: blockType,
          value: block
        });
      }
  
      return returned;
    }
  
    function renderChild(child, childType, attributes, defaultRender) {
      var isSpan = child._type === ptFeatures.types.span.name;
  
      if (isSpan) {
        return defaultRender(child);
      } // eslint-disable-next-line react/prop-types
  
  
      var inlineMarkers = markers.filter(marker => typeof marker.path[2] === 'object' && marker.path[2]._key === child._key);
      return /*#__PURE__*/_react.default.createElement(_InlineObject.InlineObject, {
        attributes: attributes,
        markers: inlineMarkers,
        onChange: handleFormBuilderEditObjectChange,
        onFocus: onFocus,
        readOnly: readOnly,
        type: childType,
        value: child
      });
    }
  
    function renderAnnotation(annotation, annotationType, attributes, defaultRender) {
      // eslint-disable-next-line react/prop-types
      var annotationMarkers = markers.filter(marker => typeof marker.path[2] === 'object' && marker.path[2]._key === annotation._key);
      return /*#__PURE__*/_react.default.createElement(_Annotation.Annotation, {
        key: annotation._key,
        attributes: attributes,
        markers: annotationMarkers,
        onFocus: onFocus,
        onChange: handleFormBuilderEditObjectChange,
        readOnly: readOnly,
        type: annotationType,
        value: annotation
      }, defaultRender());
    } // Use callback here in order to precisely track the related HTMLElement between renders (where to place popovers etc)
  
  
    var renderEditObject = (0, _react.useCallback)(() => {
      if (objectEditData === null) {
        return null;
      }
  
      var handleClose = () => {
        var editorPath = objectEditData.editorPath;
        setObjectEditData(null);
        var sel = {
          focus: {
            path: editorPath,
            offset: 0
          },
          anchor: {
            path: editorPath,
            offset: 0
          }
        };
        onFocus(editorPath);
  
        _portableTextEditor.PortableTextEditor.select(editor, sel);
  
        setInitialSelection(sel);
        focus();
      };
  
      return /*#__PURE__*/_react.default.createElement(_EditObject.EditObject, {
        focusPath: focusPath,
        objectEditData: objectEditData,
        markers: markers // TODO: filter relevant
        ,
        onBlur: handleEditObjectFormBuilderBlur,
        onChange: handleFormBuilderEditObjectChange,
        onClose: handleClose,
        onFocus: handleEditObjectFormBuilderFocus,
        readOnly: readOnly,
        presence: presence,
        value: value
      });
    }, [focusPath, isFullscreen, markers, objectEditData, presence, readOnly, value]);
  
    var ptEditor = /*#__PURE__*/_react.default.createElement(_Editor.default, {
      hotkeys: hotkeys,
      initialSelection: initialSelection,
      isFullscreen: isFullscreen,
      markers: markers,
      onBlur: onBlur,
      onCloseValidationResults: handleCloseValidationResults,
      onFocus: onFocus,
      onFormBuilderChange: onChange,
      onCopy: onCopy,
      onPaste: onPaste,
      onToggleFullscreen: handleToggleFullscreen,
      onToggleValidationResults: handleToggleValidationResults,
      portableTextFeatures: ptFeatures,
      readOnly: isActive === false || readOnly,
      renderAnnotation: renderAnnotation,
      renderBlock: renderBlock,
      renderBlockActions: renderBlockActions,
      renderChild: renderChild,
      renderCustomMarkers: renderCustomMarkers,
      showValidationTooltip: showValidationTooltip,
      value: value
    });
  
    var editObject = (0, _react.useMemo)(() => {
      return renderEditObject();
    }, [focusPath, markers, objectEditData, presence, value]);
    var activationId = (0, _react.useMemo)(() => (0, _uniqueId2.default)('PortableTextInput'), []);
  
    var fullscreenToggledEditor = /*#__PURE__*/_react.default.createElement("div", {
      className: (0, _classnames.default)(_PortableTextInput.default.root, hasFocus && _PortableTextInput.default.focus, readOnly && _PortableTextInput.default.readOnly)
    }, isFullscreen ? /*#__PURE__*/_react.default.createElement(_portal.Portal, null, /*#__PURE__*/_react.default.createElement(_stackedEscapable.default, {
      onEscape: handleToggleFullscreen
    }, /*#__PURE__*/_react.default.createElement("div", {
      className: (0, _classnames.default)(_PortableTextInput.default.fullscreenPortal, readOnly && _PortableTextInput.default.readOnly)
    }, ptEditor))) : /*#__PURE__*/_react.default.createElement(_activateOnFocus.default, {
      inputId: activationId,
      html: /*#__PURE__*/_react.default.createElement("h3", {
        className: _PortableTextInput.default.activeOnFocusHeading
      }, "Click to edit"),
      isActive: isActive,
      onActivate: handleActivate,
      overlayClassName: _PortableTextInput.default.activateOnFocusOverlay
    }, ptEditor));
  
    return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, fullscreenToggledEditor, editObject);
  }