Gordon Freeman
Gordon Freeman

Reputation: 3421

Quill.js keeps stripping classes from anchor tags

I've written a custom link module to handle internal links, etc. Also the module adds some classes to the A tags, so they can be displayed differently. But Quill removes the classes once it gets instantiated again.

I've already found out that you need a custom attributor. But I can not get it working.
To keep thinks simple, I've created a sandbox (without my module).

Here is the code:

<!-- ... -->
<div id="editor">
  <a href="/test" class="btn">Foo</a>
</div>
<!-- ... -->
import Quill from "quill";
import "quill-paste-smart";

import "quill/dist/quill.snow.css";

const Parchment = Quill.import("parchment");

let LinkClass = new Parchment.Attributor.Class("link", "ql-link", {
  scope: Parchment.Scope.INLINE,
  whitelist: ["btn"]
});
Quill.register({ "attributors/class/link": LinkClass }, true);

new Quill("#editor", {
  theme: "snow",
  modules: {
    toolbar: ["bold", "italic", "underline", "link", "clean"]
  }
});

Upvotes: 1

Views: 3537

Answers (3)

Reed
Reed

Reputation: 14984

This is a modified version of Gordon's Answer.

This version will keep all attributes (in my preliminary testing) & doesn't require them to be explicitly defined the blot.

const Inline = Quill.import("blots/inline");

class FixedLink extends Inline {
    static create(value) {
        let node = super.create(value);
        for (const key in value){
            node.setAttribute(key, value[key]);
        }
        return node;
    }

    static formats(domNode) {
        const attributes = {};
        for (const attr of domNode.attributes){
            attributes[attr.name] = attr.value;
        }
        return attributes;
    }
}

FixedLink.blotName = "fixed_link";
FixedLink.tagName = "A";


Upvotes: 0

Gordon Freeman
Gordon Freeman

Reputation: 3421

Unfortunately the accepted answer does not fully solve my issue.
I was looking for a possible way to add/keep multiple classes.

Here is the final solution:

const Inline = Quill.import("blots/inline");

const ATTRIBUTES = ["href", "rel", "target", "class"];
class InternalLink extends Inline {
  static create(value) {
    let node = super.create(value);
    node.setAttribute("href", value.href);
    if (value.rel) node.setAttribute("rel", value.rel);
    if (value.target) node.setAttribute("target", value.target);
    if (value.class) node.setAttribute("class", value.class);
    return node;
  }

  static formats(domNode) {
    return ATTRIBUTES.reduce((formats, attribute) => {
      if (domNode.hasAttribute(attribute)) {
        formats[attribute] = domNode.getAttribute(attribute);
      }
      return formats;
    }, {});
  }
}

InternalLink.blotName = "internal_link";
InternalLink.tagName = "A";

Quill.register({
  "formats/link": InternalLink
});

Edit Quill removes classes from anchor tags (forked)

Upvotes: 5

Don M
Don M

Reputation: 986

You will need to add that element in side of your Quill instance as well, using the Inline class.

Here is an example:

const Inline = Quill.import("blots/inline");


InternalLink.blotName = "internal_link";
InternalLink.className = "btn";
InternalLink.tagName = "A";

Quill.register({
  "attributors/class/link": LinkClass,
  "formats/internal_link": InternalLink
});

Edit Quill removes classes from anchor tags (forked)

I didn't think the documentation was helpful but here is an example that can help also:

Upvotes: 1

Related Questions