"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.corePlugin = void 0;
var _model = require("@atlaskit/editor-prosemirror/model");
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
var _nodeAnchorProvider = require("../../node-anchor/node-anchor-provider");
var _processRawValue = require("../../utils/processRawValue");
var _editorCommands = require("../editor-commands");
var _requestDocument = require("./requestDocument");
/**
 * Core plugin that is always included in the preset.
 * Allows for executing `EditorCommand` and other core functionality.
 */
var corePlugin = exports.corePlugin = function corePlugin(_ref) {
  var config = _ref.config;
  // Create the document request throttler per editor (rather than at a module level)
  var scheduleDocumentRequest = (0, _requestDocument.createThrottleSchedule)(_requestDocument.returnDocumentRequest);
  var scheduleDocumentRequestNoThrowError = (0, _requestDocument.createThrottleSchedule)(_requestDocument.returnDocumentRequestNoThrowError);
  return {
    name: 'core',
    getSharedState: function getSharedState(state) {
      return {
        schema: state === null || state === void 0 ? void 0 : state.schema
      };
    },
    actions: {
      execute: function execute(command) {
        var editorView = config === null || config === void 0 ? void 0 : config.getEditorView();
        if (!editorView || !command) {
          return false;
        }
        var state = editorView.state,
          dispatch = editorView.dispatch;
        return (0, _editorCommands.editorCommandToPMCommand)(command)(state, dispatch);
      },
      // Code copied from `EditorActions.focus()`
      focus: function focus(options) {
        var _options$scrollIntoVi;
        var editorView = config === null || config === void 0 ? void 0 : config.getEditorView();
        if (!editorView || editorView.hasFocus()) {
          return false;
        }
        editorView.focus();
        if ((_options$scrollIntoVi = options === null || options === void 0 ? void 0 : options.scrollIntoView) !== null && _options$scrollIntoVi !== void 0 ? _options$scrollIntoVi : true) {
          editorView.dispatch(editorView.state.tr.scrollIntoView());
        }
        return true;
      },
      // Code copied from `EditorActions.blur()`
      blur: function blur() {
        var editorView = config === null || config === void 0 ? void 0 : config.getEditorView();
        if (!editorView || !editorView.hasFocus()) {
          return false;
        }

        // Ignored via go/ees005
        // eslint-disable-next-line @atlaskit/editor/no-as-casting
        editorView.dom.blur();
        return true;
      },
      scrollToPos: function scrollToPos(pos, scrollOptions) {
        var editorView = config === null || config === void 0 ? void 0 : config.getEditorView();
        if (!editorView) {
          return false;
        }
        var tr = editorView.state.tr;
        var isValidPos = typeof pos === 'number' && pos >= 0 && pos <= tr.doc.content.size;
        if (!isValidPos) {
          return false;
        }
        var dom = editorView.domAtPos(pos).node;
        if (!(dom instanceof Element)) {
          // If it's not an element (e.g. #text node), we'll try the parent.
          // This is expected to cover most of the scenarios, if not, window.scrollTo is an alternative
          if (dom.parentNode instanceof Element) {
            dom.parentNode.scrollIntoView(scrollOptions);
            return true;
          }
          return false;
        }
        dom.scrollIntoView(scrollOptions);
        return true;
      },
      replaceDocument: function replaceDocument(replaceValue, options) {
        var editorView = config === null || config === void 0 ? void 0 : config.getEditorView();
        if (!editorView || replaceValue === undefined || replaceValue === null) {
          return false;
        }
        var state = editorView.state;
        var schema = state.schema;
        var content = options !== null && options !== void 0 && options.skipValidation ? (0, _processRawValue.processRawValueWithoutValidation)(schema, replaceValue) : Array.isArray(replaceValue) ? (0, _processRawValue.processRawFragmentValue)(schema, replaceValue) : (0, _processRawValue.processRawValue)(schema, replaceValue);

        // Don't replace the document if it's the same document, as full size
        // replace transactions cause issues for collaborative editing and
        // content reconciliation (eg. inline comments getting dropped)
        if (content instanceof _model.Node && state.doc.eq(content)) {
          return false;
        }
        if (content) {
          var _options$scrollIntoVi2;
          var tr = state.tr.replaceWith(0, state.doc.nodeSize - 2, content);
          if ((options === null || options === void 0 ? void 0 : options.addToHistory) === false) {
            tr.setMeta('addToHistory', false);
          }
          if ((_options$scrollIntoVi2 = options === null || options === void 0 ? void 0 : options.scrollIntoView) !== null && _options$scrollIntoVi2 !== void 0 ? _options$scrollIntoVi2 : true) {
            editorView.dispatch(tr.scrollIntoView());
          } else {
            editorView.dispatch(tr.setMeta('scrollIntoView', false));
          }
          return true;
        }
        return false;
      },
      // Ignored via go/ees005
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      requestDocument: function requestDocument(onReceive, options) {
        var _config$getEditorView;
        var view = (_config$getEditorView = config === null || config === void 0 ? void 0 : config.getEditorView()) !== null && _config$getEditorView !== void 0 ? _config$getEditorView : null;
        scheduleDocumentRequest(view, onReceive, options === null || options === void 0 ? void 0 : options.transformer, config === null || config === void 0 ? void 0 : config.fireAnalyticsEvent, options === null || options === void 0 ? void 0 : options.alwaysFire);
      },
      requestDocumentAsync: function requestDocumentAsync(options) {
        return new Promise(function (resolve) {
          var _config$getEditorView2;
          var view = (_config$getEditorView2 = config === null || config === void 0 ? void 0 : config.getEditorView()) !== null && _config$getEditorView2 !== void 0 ? _config$getEditorView2 : null;
          scheduleDocumentRequestNoThrowError(view, function (doc) {
            resolve(doc);
          }, options === null || options === void 0 ? void 0 : options.transformer, config === null || config === void 0 ? void 0 : config.fireAnalyticsEvent, true);
        });
      },
      createTransformer: function createTransformer(cb) {
        var _config$getEditorView3;
        var view = (_config$getEditorView3 = config === null || config === void 0 ? void 0 : config.getEditorView()) !== null && _config$getEditorView3 !== void 0 ? _config$getEditorView3 : null;
        if (!(view !== null && view !== void 0 && view.state.schema)) {
          return undefined;
        }
        return cb(view === null || view === void 0 ? void 0 : view.state.schema);
      },
      getAnchorIdForNode: function getAnchorIdForNode(node, pos) {
        var _config$getEditorView4;
        var view = (_config$getEditorView4 = config === null || config === void 0 ? void 0 : config.getEditorView()) !== null && _config$getEditorView4 !== void 0 ? _config$getEditorView4 : null;
        if (!view) {
          return undefined;
        }
        var nodeIdProvider = (0, _nodeAnchorProvider.getNodeIdProvider)(view);
        var cachedId = nodeIdProvider.getIdForNode(node);
        if (cachedId) {
          return cachedId;
        }
        if (pos < 0) {
          return undefined;
        }

        // [FEATURE FLAG: platform_editor_fix_node_anchor_dom_cache]
        // Fixes drag handle misalignment on first focus after clicking from title
        // by checking DOM for existing anchor before generating a new ID with collision suffix.
        // To clean up: remove if-else block, keep only flag-on behavior (lines 217-229), remove old behavior (lines 231-238)
        if ((0, _platformFeatureFlags.fg)('platform_editor_fix_node_anchor_dom_cache')) {
          // Check DOM first to avoid generating a new ID with a collision suffix
          // when the DOM already has a valid anchor. This prevents misalignment
          // of drag handles on first focus after clicking from the title.
          var nodeDOM = view.nodeDOM(pos);
          if (nodeDOM instanceof HTMLElement) {
            var domAnchor = nodeDOM.getAttribute('data-node-anchor');
            if (domAnchor) {
              // Cache the DOM anchor for this node to maintain consistency
              // This ensures subsequent calls return the same anchor
              nodeIdProvider.setIdForNode(node, domAnchor);
              return domAnchor;
            }
          }

          // Only generate a new ID if DOM doesn't have one
          var generatedId = nodeIdProvider.getOrGenerateId(node, pos);
          if (generatedId) {
            return generatedId;
          }
          return undefined;
        } else {
          // OLD BEHAVIOR (to be removed when flag is cleaned up)
          // This approach can generate incorrect IDs with collision suffixes when
          // the DOM already has a valid anchor, causing drag handle misalignment
          var _generatedId = nodeIdProvider.getOrGenerateId(node, pos);
          if (_generatedId) {
            return _generatedId;
          }
          var _nodeDOM = view.nodeDOM(pos);
          if (_nodeDOM instanceof HTMLElement) {
            return _nodeDOM.getAttribute('data-node-anchor') || undefined;
          }
          return undefined;
        }
      }
    }
  };
};