verbb / vizy

A flexible visual editor for Craft CMS
Other
44 stars 8 forks source link

Configure which tiptap extensions to enable #183

Open robinbisping opened 1 year ago

robinbisping commented 1 year ago

What are you trying to do?

Similar to how the topbar buttons can be configured, I would like to be able to configure which tiptap extensions are enabled. As a result, administrators gain more control over what content can be inserted into the field.

For example, there is currently no way of suppressing <hr> tags. Independently of whether the <hr> button is enabled or not, a user can simply type ---, which gets transformed into a horizontal line. By deactivating the HorizontalRule extension, this should no longer be possible.

What's your proposed solution?

Two options:

Option 1

Only enable the extensions, which have their button enabled.

https://github.com/verbb/vizy/blob/craft-4/src/web/assets/field/src/js/components/VizyInput.vue#L226-L272.

Option 2

Introduce a fourth configuration value called extensions, which can be set in the JSON configuration file:

{
    "buttons": ["html", "formatting", "h1", "h2", "h3", "h4", "h5", "h6", "bold", "italic", "underline", "strikethrough", "subscript", "superscript", "ordered-list", "unordered-list", "code-block", "hr", "highlight", "align-left", "align-right", "align-center", "align-justify", "clear-format", "line-break", "link", "image", "undo", "redo"],
    "extensions": ["h1", "h2", "h3", "h4", "h5", "h6", "bold", "italic", "underline", "strikethrough", "subscript", "superscript", "ordered-list", "unordered-list", "code-block", "hr", "highlight", "align", "line-break", "link", "image"],
    "formatting": ["paragraph", "code-block", "blockquote", "h1", "h2", "h3", "h4", "h5", "h6"],
    "toolbarFixed": true
}

It controls which extensions are enabled.

Special cases:

What do you think? Are you open to this feature idea?

robinbisping commented 1 year ago

Another example: Tiptap retains the formatting of pasted text. If I want to disallow bold text, for example, I cannot do so currently.

engram-design commented 1 year ago

The biggest issue I have with this is that the current TipTap behaviour when encountering marks/nodes in the field where their extension doesn't exist, it wipes the entire field's content. For example, you enter paragraph text, including a bold portion of content. You then disable the Bold extension. Next time you render the field all your content will be gone which is pretty catastrophic.

Similar to what happens when you paste in content that contains bold text, and if that's swapped to non-bold content.

In Vizy 1, we actually employed Option 1 but ran into this issue.

robinbisping commented 1 year ago

That is unfortunate, but I understand your reasoning.

For my usecase, it would be great to have some way of restricting what editors can insert.

Anyway, thank you for your reply!

engram-design commented 1 year ago

Yep, makes sense, and I want to get that issue fixed upstream in TipTap and/or ProseMirror first and then we'll sort this out!

jorisnoo commented 1 year ago

I'd also love to use Vizy — but would need the ability to disable certain extensions. I wouldn't mind taking the risk of losing content in case of extensions being disabled at a later point (possibly even through an undocumented way of disabling them) 😉

Looking forward on any update on this — please keep up the good work!

engram-design commented 1 year ago

FYI, still awaiting the following:

The problem @jorisnoo currently you could lose all your content. Basically, if Tiptap gets provided a document model (JSON blocks) that contains nodes or marks that aren't defined in the schema (what we provide extensions for) this bails on rendering any and all content for the field. It's incredibly heavy-handed, and I have no idea why they've taken that approach, rather than just discarding the nodes that Tiptap doesn't recognise.

In practice, what this means is that if you have say the Bold extension disabled, and some content you paste in contains some bold text, all of your content will fail to be pasted in. Or worse, you have bolded content in the field at one point, then disable the extension later - there goes all your content!

It's possible for us to maybe filter these out before they get to Tiptap, but that just seems like unnecessary overhead.

BenParizek commented 8 months ago

@engram-design We have a request from our publishing team to be able to paste content that clears formatting (such as bold, italic, etc) but does not clear out hyperlinks as they are much more tedious to add back into an article after pasting.

In my current understanding of this, I'd expect we might need a custom tip tap extension to do this. Could you confirm if that is true and if this open issue suggests that's not currently possible?

engram-design commented 8 months ago

@BenParizek That sounds more along the lines of a custom extension for Tiptap/Vizy. That would at least give you full control over the pasting rules.

A good start is the general extension user guide (you can stop when it starts talking about node specific things).

There's a user guide to get you started with creating a custom button - and a custom extension is very similar (no user guide for that sorry).

document.addEventListener('onVizyConfigReady', (e) => {
    const { Extension } = Craft.Vizy.Config.tiptap.core;

    const CustomExtension = Extension.create({
        name: 'customExtension',

        // ...
    })

    Craft.Vizy.Config.registerExtensions((extensions) => {
        return [
            CustomExtension,
        ];
    });
});

The CustomExtension object would be a Tiptap extensions where it could be anything! In particular the event listeners might be a good start, but you'll need to dive into how Tiptap works to handle things.