slab / quill

Quill is a modern WYSIWYG editor built for compatibility and extensibility
https://quilljs.com
BSD 3-Clause "New" or "Revised" License
42.55k stars 3.32k forks source link

syntax highlight issue with text color #1993

Closed volser closed 3 months ago

volser commented 6 years ago

When remove code block format, text keeps highlighted color without ability to clear

Steps for Reproduction http://recordit.co/4hKevIAiqU

add code block type some keyword (should be highlighted) remove code block

Expected behavior: clear color (class) when remove code format

Actual behavior: keeps color

Platforms: any

Version: 1.3.5

benbro commented 6 years ago

Related and possible duplicate: https://github.com/quilljs/quill/issues/954 https://github.com/quilljs/quill/issues/1978 https://github.com/quilljs/quill/issues/1228

volser commented 6 years ago

I don't see here related issues. it's not format issue. Highlightjs add own classes to DOM elements, but after deleting code-block, DOM elements are not restored

benbro commented 6 years ago

OK, so the issue is that highlight.js classes aren't removed when removing the code block. Clicking the code button and than the clear-format button does clear the highlight.js classes. Clicking the clear-format button twice also removes the code block and highlight.js classes.

volser commented 6 years ago

is it intentional behavior?

benbro commented 6 years ago

I don't think so, probably a bug.

volser commented 6 years ago

any ideas how to fix that? thanks

pReya commented 5 years ago

Hmm, this is pretty major bug. I hope someone will tackle this soon.

geekcap-pluralsight commented 4 years ago

Did anyone find a solution to this bug? I'm running 1.3.7 and this is still a problem..

Thanks!

ArsalanSavand commented 4 years ago

I'm still observing this issue.

dropmann commented 3 years ago

So I worked out a hack around. The issue I found was that the children of the CodeBlock blot were being internally copied over to the Text blot during the replaceWith method call. So I made this work around and it seems to be ok. I am reasonably new to the quilljs code base so there maybe a better way to do this... it might also introduce other issues... but it works for my purposes.

let _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
const CodeBlock = Quill.import('formats/code-block');
class NewCodeBlock extends CodeBlock {
    replaceWith(block) {
        this.domNode.textContent = this.domNode.textContent;
        this.attach();
        let newItem = _get(CodeBlock.prototype.__proto__ || Object.getPrototypeOf(CodeBlock.prototype), 'replaceWith', this).call(this, block);
        newItem.domNode.textContent = newItem.domNode.textContent;
        this.scroll.update('silent');
    }
}
NewCodeBlock.className = 'ql-syntax';
Quill.register(NewCodeBlock, true);
mashuDuek commented 3 years ago

I've run into this issue as well and I'm working on a fix. I just got a hacky fix for it in my keyboard bindings, and will use this same one in a custom code-block blot. Keeping this solution for the time being because it appears my deltas are looking like expected.

Code:

// use quill.getLine method to access domNode
const { domNode } = this.quill.getLine(range.index)[0];
// setup queue to make sure we remove highlight classes from 
// current node and all its children
let nodes = [domNode];
while (nodes.length > 0) {
  const node = nodes.shift();
  // first append children to queue
  nodes = nodes.concat(Array.from(node.children));

  // go through class list of current node removing its "hljs" classes
  for (let i = 0; i < node.classList.length; i++) {
    const c = node.classList[i];
    if (c.indexOf('hljs') >= 0) {
       node.classList.remove(c);
       i--;
    }
  }
}

If there is any issue with this solution I would start by making sure the getLine method is returning the line in question, and not the parent. Sometimes you want to unhighlight only one line from a code-block, and in your keyboard binding function you may be referencing the whole code-block, so beware of that.

UPDATE: Hacky implementation worked without custom code-block blot. I simply added a toolbar handler for that button in the toolbar.

So it looks like this:

quill.getModule('toolbar').addHandler('code-block', () => {
    const range = quill.getSelection(true);
    const formats = quill.getFormat(range);
    // if its not a code-block yet, turn it into one.
    if (!formats['code-block']) {
      return quill.formatLine(range.index, 'code-block', 'user');
    };

    // if it was a code-block, and the user meant to remove it
    // then do all the work we did up top in the keybinding function
    quill.formatLine(range.index, 'code-block', false, 'user');
    const { domNode } = quill.getLine(range.index)[0];
    let nodes = [domNode];
    while (nodes.length > 0) {
       ......... 
    }

Hope this helps you if you ran into this also :).

AshanFernando commented 2 years ago

Not the best solution, but if you need to format multiple lines and clear multiple lines in code blocks, you can use the following

quill.getModule('toolbar').addHandler('code-block', () => {
    const range = this.quill.getSelection(true);
    const formats = this.quill.getFormat(range);
    // if its not a code-block yet, turn it into one.
    if (!formats['code-block']) {
        return this.quill.formatLine(range.index, range.length, 'code-block', 'user');
    };

    // if it was a code-block, and the user meant to remove it
    this.quill.removeFormat(range.index, range.length, 'user');
    // running it twise to remove colors
    this.quill.removeFormat(range.index, range.length, 'user');
});
stevemk42 commented 1 year ago

I manually edited the toolbar options in order to directly remove font color and background color from any selection.

[
      { color: [] },  // Full color list
      { color: [false] },  // One item list, when selected, it resets the font color from the selection
      { background: [] },  // Full color list
      { background: [false] }, // One item list, when selected, it resets the fotn background color from the selection
 ]

May this help or inspire a direction for a bugfix

quill-bot commented 3 months ago

Quill 2.0 has been released (announcement post) with many changes and fixes. If this is still an issue please create a new issue after reviewing our updated Contributing guide :pray: