react-quill icon indicating copy to clipboard operation
react-quill copied to clipboard

image attributes removed on load of editor

Open levous opened this issue 7 years ago • 8 comments

CodePen here no matter how I override, extend or register ImageFormat, the overridden format(name, value) is never entered. I can break into static formats(domNode) and style is being recognized and added to the returned formats but passing html with img tags containing style attributes are still stripped of their attributes and then sent through onEditorChange.

My most recent attempt was to remove 'image' from formats and replace it with my custom blot... No luck

Upon setting editor value, it strips attributes.

const ParchmentEmbed = Quill.import('blots/block/embed');
console.log('>>>> ParchmentEmbed');
console.log(ParchmentEmbed);
const ATTRIBUTES = [
  'alt',
  'height',
  'width',
  'style'
];


class ImageWithStyle extends ParchmentEmbed {
  static create(value) {
    let node = super.create(value);
    if (typeof value === 'string') {
      node.setAttribute('src', this.sanitize(value));
    }
    return node;
  }

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

  static match(url) { 
    return /\.(jpe?g|gif|png)$/.test(url) || /^data:image\/.+;base64/.test(url);
  }

  static sanitize(url) {
    return url;
    //return sanitize(url, ['http', 'https', 'data']) ? url : '//:0';
  }

/*
  static value(domNode) {
    debugger;
    return domNode.getAttribute('src');
  }*/

  format(name, value) {
    debugger; // never gets hit
    if (ATTRIBUTES.indexOf(name) > -1) {
      if (value) {
        this.domNode.setAttribute(name, value);
      } else {
        this.domNode.removeAttribute(name);
      }
    } else {
      super.format(name, value);
    }
  }
}
ImageWithStyle.blotName = 'imagewithstyle';
ImageWithStyle.tagName = 'IMG';

Quill.register(ImageWithStyle, true);
Quill.register('modules/imageDrop', ImageDrop);
Quill.register('modules/imageResize', ImageResize);

...

<ReactQuill
          ref={(el) => { this.reactQuillRef = el }}
          theme='snow'
          onChange={this.handleChange}
          value={this.props.editorHtml}
          modules={Editor.modules}
          formats={Editor.formats}
          bounds={'.app'}
          placeholder='Author or Paste your contents'
         />


Editor.modules = {
  toolbar: [
    [{ 'header': '1'}, {'header': '2'}, { 'font': [] }],
    [{size: []}],
    ['bold', 'italic', 'underline', 'strike', 'blockquote'],
    [{'list': 'ordered'}, {'list': 'bullet'},
     {'indent': '-1'}, {'indent': '+1'}],
    ['link', 'image', 'video'],
    ['clean']
  ],
  clipboard: {
    // toggle to add extra line breaks when pasting HTML:
    matchVisual: false,
  },
  imageDrop: true,
  imageResize: {}
}

Editor.formats = [
  'header', 'font', 'size',
  'bold', 'italic', 'underline', 'strike', 'blockquote',
  'list', 'bullet', 'indent',
  'link', 'imagewithstyle', 'video'
]

...

If anyone can point me in the right direction, I'd really appreciate it

I'm using image resize and image drop but this behavior persists when I remove them as well.

levous avatar Feb 17 '18 20:02 levous

This is probably due to the initialization using the paste method from Quill. Possibly a dupe of #323.

alexkrolick avatar Feb 18 '18 07:02 alexkrolick

I believe this issue relates to which formats you allow Quill to handle, which is declared in Editor.formats. I'll explain.

These image attributes will show up in the delta as such:

insert: {
    image: "my/source.jpg",
}
attributes: {
    style: "float: left; margin: 1em;"
    width: "200px",
    height: "200px",
}

Just like a bold formatted text blot will have the attribute of bold: true, these image attributes will be processed into the image block embed blot as formats. Since alt, style, width and height are not included in your allowed Editor.formats array, Quill will discard them when processing content (be it a delta or your HTML).

I've forked your example, adding those 4 attributes to the allowed formats, and it works as expected: https://codepen.io/bakkerjoeri/pen/wXbBxB?editors=1111

I've had trouble with this myself in the past. Quill's guides mentions these kinds of formats as unregistered formats, because they are not registered to correspondent with creating a specific blot. And while, indeed, you do not need to register them to Quill, you still need to allow them in order for them to be processed.

I hope this helps. Let me know if this raises further questions.

bakkerjoeri avatar Jul 04 '18 15:07 bakkerjoeri

@joeribakker Thanks for your answer.....It works....

image

wangxdmm avatar Jan 25 '19 03:01 wangxdmm

Got it working on the images, but it won't accept these attributes on other tags now

rustyonrampage avatar Oct 08 '21 20:10 rustyonrampage

I believe this issue relates to which formats you allow Quill to handle, which is declared in Editor.formats. I'll explain.

These image attributes will show up in the delta as such:

insert: {
    image: "my/source.jpg",
}
attributes: {
    style: "float: left; margin: 1em;"
    width: "200px",
    height: "200px",
}

Just like a bold formatted text blot will have the attribute of bold: true, these image attributes will be processed into the image block embed blot as formats. Since alt, style, width and height are not included in your allowed Editor.formats array, Quill will discard them when processing content (be it a delta or your HTML).

I've forked your example, adding those 4 attributes to the allowed formats, and it works as expected: https://codepen.io/bakkerjoeri/pen/wXbBxB?editors=1111

I've had trouble with this myself in the past. Quill's guides mentions these kinds of formats as unregistered formats, because they are not registered to correspondent with creating a specific blot. And while, indeed, you do not need to register them to Quill, you still need to allow them in order for them to be processed.

I hope this helps. Let me know if this raises further questions.

Thanks @bakkerjoeri , it works for attributes. Then I use editor.insertEmbed(cursorIndex, 'imagewithstyle', source, 'api') to insert image. But the inserted image always take a whole line and no word is allowed by its side. Do you have any idea about this? image

zhanghan3 avatar Feb 24 '23 09:02 zhanghan3

That's hard to say without looking at a code example, but my best guess is that it's a CSS problem and not related to quill.

Your image is surrounded by div elements, which are block level elements. These order themselves vertically, taking up a whole line. If you make those display: inline it will probably work more as expected. Alternatively you might need to make sure your image is set to display: inline.

bakkerjoeri avatar Feb 24 '23 11:02 bakkerjoeri

Thanks for your quick answer @bakkerjoeri 🙏🙏🙏. The default behavior of inserting image is that image is always wrapped in a div. So I try to add a div outside img, then everything becomes normal. But it is difficult to take all situation into account if adding div. So I guess the root reason is why there is no div in the outer layer of img after using the new method. I can reproduce this problem by this, which based on your example: https://codepen.io/hudson999/pen/bGxBRry. Only delete style="float:left;margin:1em;" and <p>I am some floated text</p>

zhanghan3 avatar Feb 27 '23 03:02 zhanghan3