I am trying to write a Nylas N1 plugin, and so I started by just modifying the built-in spellcheck (here https://github.com/nylas/N1/blob/master/internal_packages/composer-spellcheck/lib/spellcheck-composer-extension.es6). I imported the underscore library, and tried to throttle the _wrapMisspelledWords function:
import _ from 'underscore';
...
export default class SpellcheckComposerExtension extends ComposerExtension {
...
static onContentChanged({editor}) {
SpellcheckComposerExtension.update(editor);
}
static update = (editor) => {
SpellcheckComposerExtension._unwrapWords(editor);
SpellcheckComposerExtension._wrapMisspelledWords(editor);
}
static _wrapMisspelledWords = _.throttle((editor) => {
console.log('wrap mispelled words');
...
...
}, 2000)
...
}
It appears to throttle correctly at first, and then seems to get stuck in some loop, constantly repeating output from previous changes. I have read through another thread (Perform debounce in React.js) but can't figure out why this behavior is happening.
EDIT:
It might make more sense to throttle the update function, but I see the same issue.
EDIT:
OK instead of throttling or debouncing, I decided to wrap the update function in setTimeout(..., 0) in order to debug, and still shows this same issue.
The conditions for entering an infinite loop seem to be:
- there is at least one spelling mistake (so that unwrap and wrap say that they've modified the content)
- the update function is added to the event queue instead of firing immediately (using setTimeout, throttle or debounce)
The contenteditable component (https://github.com/nylas/N1/blob/1b4739335f4452faa720914309c5e6a593db531d/src/components/contenteditable/contenteditable.cjsx#L302-L333) has a mutation observer that stops listening while the extensions run, and I think when I add my update to the event queue, it starts listening for mutations before the update can run, causing another mutation to be observed, entering the infinite loop.
Any solutions, or tips?