Tiptap: Error when adding links

Created on 1 Feb 2019  路  6Comments  路  Source: ueberdosis/tiptap

Hey guys, thanks for an awesome plugin!

I'm having a couple of issues adding links. I've copied the code from the links example on your site as well as adding a couple of extra buttons for bold and italic. The bold and italic buttons work ok. The button for adding a link doesn't work but that's a separate issue I need to figure out. The main issue is when I highlight a word to turn it in a link I get the following error...

Uncaught TypeError: Cannot read property 'getBoundingClientRect' of null
    at Menu.update (tiptap.esm.js?cd42:1271)
    at EditorView.updatePluginViews (index.js?703f:4380)
    at EditorView.updateState (index.js?703f:4345)
    at Editor.dispatchTransaction (tiptap.esm.js?cd42:1027)
    at EditorView.dispatch (index.js?703f:4550)
    at SelectionReader.readFromDOM (index.js?703f:2060)
    at HTMLDocument.SelectionChangePoller.readFunc (index.js?703f:2077)
    at HTMLDocument.sentryWrapped (helpers.ts:77)

I've tried to debug but I can't figure out where it's coming from. Appreciate any help you can offer.

Thanks

Example code...

<template>
  <div>
    <EditorMenuBubble
      class="menububble"
      :editor="editor"
    >
      <div
        slot-scope="{ commands, isActive, getMarkAttrs, menu }"
        class="menububble"
        :class="{ 'is-active': menu.isActive }"
        :style="`left: ${menu.left}px; bottom: ${menu.bottom}px;`"
      >
        <form
          v-if="linkMenuIsActive"
          class="menububble__form"
          @submit.prevent="setLinkUrl(commands.link, linkUrl)"
        >
          <input
            ref="linkInput"
            v-model="linkUrl"
            class="menububble__input"
            type="text"
            placeholder="https://"
            @keydown.esc="hideLinkMenu"
          >
          <button
            class="menububble__button"
            type="button"
            @click="setLinkUrl(commands.link, null)"
          >
            <v-icon name="times" />
          </button>
        </form>

        <template v-else>
          <button
            class="menububble__button"
            :class="{ 'is-active': isActive.link() }"
            @click="showLinkMenu(getMarkAttrs('link'))"
          >
            <span>Add Link</span>
            <v-icon name="link" />
          </button>
        </template>
      </div>
    </EditorMenuBubble>

    <EditorMenuBar :editor="editor">
      <div
        slot-scope="{ commands, isActive }"
        class="menubar"
      >
        <button
          class="menubar__button"
          :class="{ 'is-active': isActive.bold() }"
          @click="commands.bold"
        >
          <v-icon
            name="bold"
            class="menu-icon"
          />
        </button>

        <button
          class="menubar__button"
          :class="{ 'is-active': isActive.italic() }"
          @click="commands.italic"
        >
          <v-icon
            name="italic"
            class="menu-icon"
          />
        </button>

        <button
          class="menubar__button"
          :class="{ 'is-active': isActive.link() }"
          @click="showLinkMenu(getMarkAttrs('link'))"
        >
          <v-icon
            name="link"
            class="menu-icon"
          />
        </button>
      </div>
    </EditorMenuBar>

    <EditorContent
      :editor="editor"
      class="input"
      :class="{'disabled':
        disabled}"
    />
  </div>
</template>

<script>
import { Editor, EditorContent, EditorMenuBar, EditorMenuBubble } from "tiptap";
import { Bold, Italic, Link } from "tiptap-extensions";

export default {
  name: "RichInput",
  components: { EditorContent, EditorMenuBar, EditorMenuBubble },
  props: {
    disabled: {
      type: Boolean,
      default: false
    },
    maxlength: {
      default: 0,
      required: false,
      type: Number
    },
    multiLine: {
      type: Boolean,
      default: true
    },
    value: {
      type: String,
      default: ""
    }
  },
  data() {
    return {
      editor: null,
      linkUrl: null,
      linkMenuIsActive: false
    };
  },
  mounted() {
    this.editor = new Editor({
      content: this.$props.value,
      editable: !this.$props.disabled,
      extensions: [new Bold(), new Italic(), new Link()],
      onUpdate: state => this.$emit("input", state)
    });
  },
  beforeDestroy() {
    this.editor.destroy();
  },
  methods: {
    showLinkMenu(attrs) {
      this.linkUrl = attrs.href;
      this.linkMenuIsActive = true;
      this.$nextTick(() => {
        this.$refs.linkInput.focus();
      });
    },
    hideLinkMenu() {
      this.linkUrl = null;
      this.linkMenuIsActive = false;
    },
    setLinkUrl(command, url) {
      command({ href: url });
      this.hideLinkMenu();
      this.editor.focus();
    }
  }
};
</script>

bug

Most helpful comment

Hey all,
Thanks to @gilesbutler for creating this issue!! It really helps to be able to find others who are dealing with the same and try out possible solutions!!

For me, this was introduced after upgrading tiptap to version 1.8.0 from 1.7.0 and is breaking my tests. That I've seen, I'm not getting this error in the browser. It disappears when downgrading to 1.7.0

Here is a link to the test https://github.com/Human-Connection/Human-Connection/blob/696ddcb543d9be1163b955203e7eb7d57a5e8765/webapp/components/comments/CommentForm/spec.js

and here is a link to the component where we are using tiptap https://github.com/Human-Connection/Human-Connection/blob/master/webapp/components/Editor/index.vue#L563

Note that we are using visibility: hidden; and opacity: 0; as @lhermann suggests.

In general, we have found it difficult to interact with tiptap in unit tests, I wonder if anyone else has dealt with this, or might have some open source code with examples that we could benefit from?

Thanks in advance to the maintainer(s) of tiptap and those who have taken the time to create and report on this issue.

All 6 comments

This error might not be related to links. I got the same error when display: none; was set on the MenuBubble. It worked for me when I only used visibility: hidden; and opacity: 0;.

Hope this helps.

Thanks @lhermann I'll check it out 馃憤

Hey Guys - Im seeing the same error when highlighting text in the editor. Im not using display: none; on the bubble. Any updates?

Let me specify: If the menu bubble for some reason is not rendered in the DOM, because of display: none; or some other reason, then I found that this error occurs. However, this may not be the only reason.

@lhermann thanks for your response. I guess if there is an error then maybe I/we are using the library incorrectly?

the docs dont outline a best practice on how to do this but perhaps there is a best practice or guideline on how to use the library so we dont get the error

Hey all,
Thanks to @gilesbutler for creating this issue!! It really helps to be able to find others who are dealing with the same and try out possible solutions!!

For me, this was introduced after upgrading tiptap to version 1.8.0 from 1.7.0 and is breaking my tests. That I've seen, I'm not getting this error in the browser. It disappears when downgrading to 1.7.0

Here is a link to the test https://github.com/Human-Connection/Human-Connection/blob/696ddcb543d9be1163b955203e7eb7d57a5e8765/webapp/components/comments/CommentForm/spec.js

and here is a link to the component where we are using tiptap https://github.com/Human-Connection/Human-Connection/blob/master/webapp/components/Editor/index.vue#L563

Note that we are using visibility: hidden; and opacity: 0; as @lhermann suggests.

In general, we have found it difficult to interact with tiptap in unit tests, I wonder if anyone else has dealt with this, or might have some open source code with examples that we could benefit from?

Thanks in advance to the maintainer(s) of tiptap and those who have taken the time to create and report on this issue.

Was this page helpful?
0 / 5 - 0 ratings