"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
var _slate = require("slate");
var _slateReact = require("slate-react");
var _elementTypes = require("../constants/element-types");
var _prismjs = _interopRequireDefault(require("./prismjs"));
var _normalizeTokens = require("./normalize-tokens");
var _constant = require("../plugins/code-block/render-elem/constant");
const mergeMaps = function () {
  const map = new Map();
  for (var _len = arguments.length, maps = new Array(_len), _key = 0; _key < _len; _key++) {
    maps[_key] = arguments[_key];
  }
  for (const m of maps) {
    for (const item of m) {
      map.set(...item);
    }
  }
  return map;
};
const getChildNodeToDecorations = _ref => {
  let [block, blockPath] = _ref;
  const nodeToDecorations = new Map();
  const text = block.children.map(line => _slate.Node.string(line)).join('\n');
  const language = _constant.LANGUAGE_MAP[block.lang] ? block.lang : 'text';
  const tokens = _prismjs.default.tokenize(text, _prismjs.default.languages[language]);
  const normalizedTokens = (0, _normalizeTokens.normalizeTokens)(tokens); // make tokens flat and grouped by line
  const blockChildren = block.children;
  for (let index = 0; index < normalizedTokens.length; index++) {
    const tokens = normalizedTokens[index];
    const element = blockChildren[index];
    if (element) {
      if (!nodeToDecorations.has(element)) {
        nodeToDecorations.set(element, []);
      }
    }
    let start = 0;
    for (const token of tokens) {
      const length = token.content.length;
      if (!length) {
        continue;
      }
      const end = start + length;
      const path = [...blockPath, index, 0];
      const range = {
        anchor: {
          path,
          offset: start
        },
        focus: {
          path,
          offset: end
        },
        token: true,
        ...Object.fromEntries(token.types.map(type => [type, true]))
      };
      if (nodeToDecorations.get(element)) {
        nodeToDecorations.get(element).push(range);
      }
      start = end;
    }
  }
  return nodeToDecorations;
};
const SetNodeToDecorations = () => {
  const editor = (0, _slateReact.useSlate)();
  const blockEntries = Array.from(_slate.Editor.nodes(editor, {
    at: [],
    mode: 'highest',
    match: n => _slate.Element.isElement(n) && n.type === _elementTypes.CODE_BLOCK
  }));
  const nodeToDecorations = mergeMaps(...blockEntries.map(getChildNodeToDecorations));
  editor.nodeToDecorations = nodeToDecorations;
  return null;
};
var _default = exports.default = SetNodeToDecorations;