Fandom-OSS / quill-blot-formatter

A module for Quill that allows editor elements to be resized, repositioned, etc.
Apache License 2.0
135 stars 50 forks source link

image and video alignments do not save in quill. #5

Open wisteria-hill-technologies opened 6 years ago

wisteria-hill-technologies commented 6 years ago

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

wisteria-hill-technologies commented 6 years ago

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

Trupal00p commented 6 years ago

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.

oxdc commented 6 years ago

Same issue. And I find a solution here.

shabbyk commented 4 years ago

Any updates on this ?

manishatiwari1696 commented 4 years ago

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.

miczed commented 4 years ago

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
});
BrenoLopes commented 4 years ago

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

nitink66 commented 4 years ago

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

nitink66 commented 4 years ago

@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

bewpage commented 4 years ago

@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

Hanho-Kim commented 4 years ago

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"]
}
richardoptibrium commented 3 years ago

Any chance this could get fixed please?

LordAelfric commented 2 years ago

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);
tylerkneidl commented 2 years ago

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

jonathantayyw commented 1 year ago

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 commented 1 year ago

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'