I've got a Blot where I catch clicks using on('selection-change') and offer to change that blot with a menu. I'd now like to make the editor readonly, apart from changes made by the clicks on those blots. But if it's readonly, on('selection-change') is never hit, since source === "user".
You can "reproduce" this by doing quill.disable() on quilljs.com and trying to edit a link, which also seems to use on('selection-change').
Is there a way to have a "readonly-light", where users can't modify text by typing, but they can by clicking on blots? I see there is this function
https://github.com/quilljs/quill/blob/131db2b98d1fcabf8586ecd1b493345ea2bb1002/core/quill.js#L431
which never emits anything if the editor is disabled and source is user, so I'm guessing there's nothing implemented to do what I want using selection-change. But maybe there's a different way I could get what I want?
Can you just use normal DOM click events instead of selection-change?
Can I still get a hold of range.index from a DOM click event? I'm doing
onSelectionChange = function(range, _oldRange, source) {
let idx = range.index;
let blot_and_offset = this.quill.scroll.descendant(ErrorBlot, idx);
let beg = idx - blot_and_offset[1];
let blot = blot_and_offset[0];
…
};
more or less, in order to get the Blot at that point, along with its beginning and length.
Is this a custom Blot? If so can you paste the constructor / create functions?
slightly simplified:
let Inline = Quill.import('blots/inline');
class ErrorBlot extends Inline {
static create(err/*:err*/) {
let node = super.create();
if(typeof(err) != "object") {
console.log("Error creating ErrorBlot, expected object, not "+typeof(err));
return super.create();
}
$(node).data("error", err);
return node;
}
static formats(node) {
return $(node).data("error");
}
}
ErrorBlot.blotName = 'error';
ErrorBlot.tagName = 'span';
ErrorBlot.className = 'divvun-error';
Quill.register(ErrorBlot);
If your goal is to find the blot would something like this work:
static create() {
let node = super.create();
node.addEventListener('click', function(e) {
// e.target should always be node since it is attached to node
let blot = Quill.find(node);
// Do what you want with blot
});
// ...
}
I was unsure if just the blot element would have enough info to safely remove/unwrap the blot, or change the text contents in it, but after looking through https://github.com/quilljs/parchment/#blots I see I can use Quill.find(node).offset(quill.scroll) to get the the beginning/offset, and Quill.find(node).length()) to get the length, so I believe that gives me all the information I need :-)
Thanks! I'll close this then; using a normal DOM click event seems like a better solution than a "partial readonly" state.
Most helpful comment
If your goal is to find the blot would something like this work: