"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 _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
var _nodeAnchorProvider = require("../../node-anchor/node-anchor-provider");
var _processRawFragmentValue = require("../../utils/processRawFragmentValue");
var _processRawValue = require("../../utils/processRawValue");
var _editorCommands = require("../editor-commands");
var _appearancePlugin = require("./pm-plugins/appearance-plugin");
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) {
      var pluginState = state && _appearancePlugin.appearancePluginKey.getState(state);
      return {
        schema: state === null || state === void 0 ? void 0 : state.schema,
        appearance: (0, _expValEquals.expValEquals)('platform_editor_appearance_shared_state', 'isEnabled', true) ? pluginState === null || pluginState === void 0 ? void 0 : pluginState.appearance : undefined
      };
    },
    pmPlugins: function pmPlugins() {
      if ((0, _expValEquals.expValEquals)('platform_editor_appearance_shared_state', 'isEnabled', true)) {
        return [{
          name: 'appearancePlugin',
          plugin: function plugin() {
            return (0, _appearancePlugin.createAppearancePlugin)(config === null || config === void 0 ? void 0 : config.appearance);
          }
        }];
      }
      return [];
    },
    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;
        }
        if ((0, _platformFeatureFlags.fg)('platform_editor_fix_scroll_to_pos')) {
          var _ref2, _editorView$domAtPos;
          // nodeDOM can return a Text node for inline positions
          var nodeDom = editorView.nodeDOM(pos);
          var _dom = (_ref2 = nodeDom instanceof Element ? nodeDom : null) !== null && _ref2 !== void 0 ? _ref2 : (_editorView$domAtPos = editorView.domAtPos(pos)) === null || _editorView$domAtPos === void 0 ? void 0 : _editorView$domAtPos.node;
          if (!(_dom instanceof Element)) {
            return false;
          }
          _dom.scrollIntoView(scrollOptions);
          return true;
        }

        // Legacy path — domAtPos interprets block boundaries as the parent container
        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;
      },
      updateAppearance: function updateAppearance(newAppearance) {
        var _appearancePluginKey$;
        if (!(0, _expValEquals.expValEquals)('platform_editor_appearance_shared_state', 'isEnabled', true)) {
          return false;
        }
        var editorView = config === null || config === void 0 ? void 0 : config.getEditorView();
        if (!editorView) {
          return false;
        }
        // Avoid dispatching a redundant transaction if appearance hasn't changed
        var currentAppearance = (_appearancePluginKey$ = _appearancePlugin.appearancePluginKey.getState(editorView.state)) === null || _appearancePluginKey$ === void 0 ? void 0 : _appearancePluginKey$.appearance;
        if (currentAppearance === newAppearance) {
          return false;
        }
        var tr = editorView.state.tr.setMeta(_appearancePlugin.appearancePluginKey, {
          appearance: newAppearance
        });
        tr.setMeta('addToHistory', false);
        editorView.dispatch(tr);
        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, _processRawFragmentValue.processRawFragmentValue)(schema, replaceValue, undefined, undefined, options === null || options === void 0 ? void 0 : options.transformer) : (0, _processRawValue.processRawValue)(schema, replaceValue, undefined, undefined, options === null || options === void 0 ? void 0 : options.transformer);

        // 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);
          tr.setMeta('replaceDocument', true);
          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;
        }

        // 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;
      }
    }
  };
};