OverviewFilesCommitsIssuesDocsReleasesPeers

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

82 lines · javascript ref:
import { Link as t } from "@tiptap/extension-link"
import { Plugin as e, PluginKey as o } from "prosemirror-state"
import { find as r, registerCustomProtocol as i, init as n, reset as s } from "linkifyjs"
import { NODE_TYPE as a, LINK_PROTOCOLS_DEFAULT as l, NODE_ATTR as h } from "../constants.js"
import { isAllowedLink as d } from "./helpers/urls.js"
function p(t) {
  return new e({
    key: new o("handleGifPreview"),
    props: {
      handlePaste: (e, o, i) => {
        let n = ""
        i.content.forEach((t) => {
          n += t.textContent
        })
        const s = r(n).filter((t) => t.href.includes(".gif"))
        for (const o of s)
          window
            .fetch(o.href)
            .then((t) => {
              if (!t.ok) throw new Error("Error fetching url")
              if ("image/gif" !== t.headers.get("content-type")) throw new Error("Not a gif")
              return t.blob()
            })
            .then(async (r) => {
              try {
                const { state: i, dispatch: n } = e,
                  { schema: s, doc: l } = i,
                  d = t.createRandomName(o.href),
                  p = new window.File([r], d, { type: "image/gif" }),
                  {
                    id: c,
                    file: { url: f },
                  } = await t.editor.commands.upload([p]),
                  u = s.nodes[a.FILE_IMAGE].create({ [h.ID]: c, src: f, name: d, alt: d, title: d })
                n(e.state.tr.insert(l.content.size, u))
              } catch (t) {
                console.log("ERROR", t)
              }
            })
            .catch((t) => console.log("ERROR", t))
        return !1
      },
    },
  })
}
export const Link = t.extend({
  inclusive: !1,
  onCreate() {
    ;(s(),
      this.options.validate &&
        !this.options.shouldAutoLink &&
        ((this.options.shouldAutoLink = this.options.validate),
        console.warn(
          "The `validate` option is deprecated. Rename to the `shouldAutoLink` option instead.",
        )),
      this.options.protocols.forEach((t) => {
        "string" != typeof t ? i(t.scheme, t.optionalSlashes) : i(t)
      }),
      n())
  },
  addAttributes() {
    return {
      href: { default: null, parseHTML: (t) => t.getAttribute("href") },
      pasted: { default: !1 },
      target: { default: this.options.HTMLAttributes.target },
      rel: { default: this.options.HTMLAttributes.rel },
    }
  },
  onDestroy() {},
  addOptions() {
    return {
      ...this.parent?.(),
      protocols: [...(this.parent?.()?.protocols ?? []), ...l],
      isAllowedUri: (t, e) => !!e.defaultValidate(t) && d(t, e),
    }
  },
  addProseMirrorPlugins() {
    const t = this.parent()
    return [p({ editor: this.editor, type: this.type, ...this.options }), ...t]
  },
})