quill-blot-formatter icon indicating copy to clipboard operation
quill-blot-formatter copied to clipboard

image and video alignments do not save in quill.

Open wisteria-hill-technologies opened this issue 6 years ago • 16 comments

Hi, Thank you for making this library. I have an issue with image and video alignments. When I click on an image or video I inserted in the quill editor (I am using react-quill), I can align left, right, and center using the resizer box provided by quill-blot-formatter. But, as soon as I remove the editor and display the content in <div class="ql-editor" dangerouslySetInnerHTML={{ __html: content }} />, all the contents, images and videos are there but alignments are ignored.

Could you tell me what I may be missing? or at least can I hide the alignment boxes in quill-blot-formatter so that users can just use the alignment options in the quill-toolbar?

Thanks

For now, I have hidden the alignment boxes with below: .blot-formatter__toolbar-button { display: none !important; }

Same issue here. From your snippet, it looks like you are using react quill as well.

From what I can tell the onChange event doesn't fire when you click one of the hovering alignment buttons. But it does fire when you drag the resize handle. So if you change the alignment then resize or add some text, the alignment will be saved.

I think it has something to do with the AlignAction updating the quill state in a non-standard way. I'm still poking around to see I can find the root.

Trupal00p avatar Jun 18 '18 13:06 Trupal00p

Same issue. And I find a solution here.

oxdc avatar Jul 03 '18 11:07 oxdc

Any updates on this ?

shabbyk avatar May 29 '20 17:05 shabbyk

Hello all,

I'm using quill image resize module to resize the image and for image alignment but the thing is that I'm getting width and height values of image in image tag but not the alignment style css. I mean if I change the height and width of the image along with the alignment then only height and width attribute are showing in the image tag not the alignment style css of the image. Ti's like the alignment css is not creating no matter how we change the alignmnet of the image. Can anyone please help me out here, to how to get those alignment style within the image tag so that when I use that html created by the quill and use it with inner-html I'll get same look as I've created using editor. BDW I'm using Angular - 8.

Please help me out here. I'm stuck here.

manishatiwari1696 avatar Jun 20 '20 05:06 manishatiwari1696

By default the Image format of quill does not allow alignments. They are applied using the class attribute and by default alt, height and width attributes are allowed. To solve the issue, the default Image class can be extended as follows:

import Image from 'quill/formats/image';

const ATTRIBUTES = [
    'alt',
    'height',
    'width',
    'class' // this will allow the class attribute on the image tag
]

export default class CustomImage extends Image {
    static formats(domNode) {
        return ATTRIBUTES.reduce(function(formats, attribute) {
            if (domNode.hasAttribute(attribute)) {
                formats[attribute] = domNode.getAttribute(attribute);
            }
            return formats;
        }, {});
    }
    format(name, value) {
        if (ATTRIBUTES.indexOf(name) > -1) {
            if (value) {
                this.domNode.setAttribute(name, value);
            } else {
                this.domNode.removeAttribute(name);
            }
        } else {
            super.format(name, value);
        }
    }
}

And then this format can be registered instead of the default one:


Quill.register({
     // ... other formats
    'formats/image': CustomImage
});

miczed avatar Jul 09 '20 15:07 miczed

Using the code above I had to make some changes to make quill accept it and register.

import Quill from 'quill';

const Image = Quill.import('formats/image'); // Had to get the class this way, instead of ES6 imports, so that quill could register it without errors

const ATTRIBUTES = [
  'alt',
  'height',
  'width',
  'class', 
  'style', // Had to add this line because the style was inlined
];

class CustomImage extends Image {
  static formats(domNode) {
    return ATTRIBUTES.reduce((formats, attribute) => {
      const copy = { ...formats };

      if (domNode.hasAttribute(attribute)) {
        copy[attribute] = domNode.getAttribute(attribute);
      }

      return copy;
    }, {});
  }

  format(name, value) {
    if (ATTRIBUTES.indexOf(name) > -1) {
      if (value) {
        this.domNode.setAttribute(name, value);
      } else {
        this.domNode.removeAttribute(name);
      }
    } else {
      super.format(name, value);
    }
  }
}

export default CustomImage;

And them register it

Quill.register({
     // ... other formats
    'formats/image': CustomImage
});

Thanks miczed for pointing out the way

BrenoLopes avatar Aug 07 '20 20:08 BrenoLopes

How to register alignment styles in react-quill with nextjs ? SO question

nitink66 avatar Aug 21 '20 13:08 nitink66

@BrenoLopes @miczed How to implement the same using react-quill ? Because there's no module exist as formats/image or quill/formats/image in react-quill. Any help please

nitink66 avatar Aug 22 '20 03:08 nitink66

@nitink66 react-quill exposes Quill from their interface, just use import ReactQuill, {Quill} from 'react-quill' and it should work. see https://github.com/zenoamaro/react-quill#custom-formats

bewpage avatar Sep 08 '20 14:09 bewpage

In my case, to make it work, I have to add formats configs as well.

let quill = new Quill(element, {
...
formats : [... "height", "width", "class", "style"]
}

Hanho-Kim avatar Oct 21 '20 06:10 Hanho-Kim

Any chance this could get fixed please?

richardoptibrium avatar Apr 09 '21 12:04 richardoptibrium

Getting an Angular project to work required a couple of extra lines as Typescript needed a declaration. Hope this helps others with similar issues.

import Quill from 'quill';
const ImageBase = Quill.import('formats/image');

const ATTRIBUTES = [
  'alt',
  'height',
  'width',
  'style' // This is the added difference that needs to be saved properly
];

export default class CustomImage extends ImageBase {
  declare domNode: any; // Needed declaration for Typescript

  static formats(domNode) {
    return ATTRIBUTES.reduce((formats, attribute) => {
      const copy = { ...formats };

      if (domNode.hasAttribute(attribute)) {
        copy[attribute] = domNode.getAttribute(attribute);
      }

      return copy;
    }, {});
  }

  format(name, value) {
    if (ATTRIBUTES.indexOf(name) > -1) {
      if (value) {
        this.domNode.setAttribute(name, value);
      } else {
        this.domNode.removeAttribute(name);
      }
    } else {
      super.format(name, value);
    }
  }
}

Quill.register('formats/image', CustomImage);

LordAelfric avatar Feb 09 '22 13:02 LordAelfric

In my case, to make it work, I have to add formats configs as well.

let quill = new Quill(element, {
...
formats : [... "height", "width", "class", "style"]
}

This worked for me! Thanks from the future =D

tylerkneidl avatar Jun 10 '22 22:06 tylerkneidl

Thanks for this. It works great for the alignment of images but the alignment of videos still doesn't seem to register though. Any suggestion for saving the alignments of videos/iframes?

Getting an Angular project to work required a couple of extra lines as Typescript needed a declaration. Hope this helps others with similar issues.

import Quill from 'quill';
const ImageBase = Quill.import('formats/image');

const ATTRIBUTES = [
  'alt',
  'height',
  'width',
  'style' // This is the added difference that needs to be saved properly
];

export default class CustomImage extends ImageBase {
  declare domNode: any; // Needed declaration for Typescript

  static formats(domNode) {
    return ATTRIBUTES.reduce((formats, attribute) => {
      const copy = { ...formats };

      if (domNode.hasAttribute(attribute)) {
        copy[attribute] = domNode.getAttribute(attribute);
      }

      return copy;
    }, {});
  }

  format(name, value) {
    if (ATTRIBUTES.indexOf(name) > -1) {
      if (value) {
        this.domNode.setAttribute(name, value);
      } else {
        this.domNode.removeAttribute(name);
      }
    } else {
      super.format(name, value);
    }
  }
}

Quill.register('formats/image', CustomImage);

jonathantayyw avatar Dec 21 '22 18:12 jonathantayyw

Thanks for this. It works great for the alignment of images but the alignment of videos still doesn't seem to register though. Any suggestion for saving the alignments of videos/iframes?

Getting an Angular project to work required a couple of extra lines as Typescript needed a declaration. Hope this helps others with similar issues.

import Quill from 'quill';
const ImageBase = Quill.import('formats/image');

const ATTRIBUTES = [
  'alt',
  'height',
  'width',
  'style' // This is the added difference that needs to be saved properly
];

export default class CustomImage extends ImageBase {
  declare domNode: any; // Needed declaration for Typescript

  static formats(domNode) {
    return ATTRIBUTES.reduce((formats, attribute) => {
      const copy = { ...formats };

      if (domNode.hasAttribute(attribute)) {
        copy[attribute] = domNode.getAttribute(attribute);
      }

      return copy;
    }, {});
  }

  format(name, value) {
    if (ATTRIBUTES.indexOf(name) > -1) {
      if (value) {
        this.domNode.setAttribute(name, value);
      } else {
        this.domNode.removeAttribute(name);
      }
    } else {
      super.format(name, value);
    }
  }
}

Quill.register('formats/image', CustomImage);

Resolved video issue. Replaced 'formats/image' with 'formats/video'

jonathantayyw avatar Dec 22 '22 08:12 jonathantayyw