OverviewFilesCommitsIssuesDocsReleasesPeers

keet-deobfuscated / @holepunchto / keet-editor / src / extensions / blockquote.js

72 lines · javascript ref:
import { InputRule as e, callOrReturn as t } from "@tiptap/core"
import { Blockquote as o } from "@tiptap/extension-blockquote"
import { canJoin as r, findWrapping as n } from "@tiptap/pm/transform"
import { Plugin as i } from "prosemirror-state"
import { exitAfterBlock as s, exitBeforeBlock as d } from "./helpers/index.js"
const a = /^\s*>\s$/
export const Blockquote = o.extend({
  addOptions: () => ({ levels: 1 }),
  addInputRules() {
    return [p({ find: a, type: this.type, depth: this.options.levels })]
  },
  addKeyboardShortcuts() {
    const e = s.bind(this),
      t = d.bind(this)
    return {
      "Mod-Shift-9": () => this.editor.commands.toggleBlockquote(),
      ArrowUp: () => t(),
      ArrowLeft: () => t(),
      ArrowDown: () => e(),
      ArrowRight: () => e(),
    }
  },
  addProseMirrorPlugins: () => [
    new i({
      props: {
        transformPastedHTML: (e) => {
          const { body: t } = new window.DOMParser().parseFromString(e, "text/html"),
            o = t.querySelector("blockquote")
          return (o && f(o), t.innerHTML)
        },
      },
    }),
  ],
})
function f(e) {
  Array.from(e.childNodes).forEach((t) => {
    if ("BLOCKQUOTE" === t.nodeName) {
      for (f(t); t.firstChild; ) e.insertBefore(t.firstChild, t)
      e.removeChild(t)
    }
  })
}
function p(o) {
  return new e({
    find: o.find,
    handler: ({ state: e, range: i, match: s }) => {
      const d = t(o.getAttributes, void 0, s) || {},
        a = e.tr.delete(i.from, i.to),
        f = a.doc.resolve(i.from).blockRange(),
        p = f && n(f, o.type, d),
        { selection: l, storedMarks: m } = e
      let c = 0
      for (let e = l.$from.depth; e > 0; e--) "blockquote" === l.$from.node(e).type.name && c++
      if (c >= o.depth || !p) return null
      if ((a.wrap(f, p), o.keepMarks && o.editor)) {
        const { splittableMarks: e } = o.editor.extensionManager,
          t = m || (l.$to.parentOffset && l.$from.marks())
        if (t) {
          const o = t.filter((t) => e.includes(t.type.name))
          a.ensureMarks(o)
        }
      }
      const u = a.doc.resolve(i.from - 1).nodeBefore
      u &&
        u.type === o.type &&
        r(a.doc, i.from - 1) &&
        (!o.joinPredicate || o.joinPredicate(s, u)) &&
        a.join(i.from - 1)
    },
  })
}