Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gutenberg doesn’t react on changes which were caused by external scripts #13620

Closed
lex127 opened this issue Jan 31, 2019 · 4 comments
Closed
Labels
Needs Technical Feedback Needs testing from a developer perspective. [Type] Help Request Help with setup, implementation, or "How do I?" questions.

Comments

@lex127
Copy link

lex127 commented Jan 31, 2019

We are trying to add an extra functionality to Gutenberg but faced with a critical a problem. Gutenberg doesn’t see changes that are caused by external scripts. For example, if we try to change text using browser Range API, Gutenberg won’t react on (ignore) these changes. What is critical here – those changes won’t be applied after Updated/Publish actions. And this is quite frustrating, this is not what the end user might have expected when finally published a post, or updated a page.

We have tried to subscribe on saving post (see code below) but changes still are not applied.

wp.data.subscribe(function() {
    if (wp.data.select('core/editor').isSavingPost()) {
        // What should we call to apply our changes before Upload
    }
});

…..
Could you please suggest if there is something else we can try to overcome this problem? Or probably this is the case that must be taken into account, as other developers might face the same issues.

@swissspidy swissspidy added [Type] Help Request Help with setup, implementation, or "How do I?" questions. Needs Technical Feedback Needs testing from a developer perspective. labels Jan 31, 2019
@gziolo
Copy link
Member

gziolo commented Feb 8, 2019

if we try to change text using browser Range API, Gutenberg won’t react on (ignore) these changes.

Yes, this is the expected behavior. You should be using wp.data.dispatch (https://github.com/WordPress/gutenberg/tree/master/packages/data#dispatch-storename-string--object) to trigger update inside the editor instead which is going to be reflected in the DOM. @aduth do we have a more detailed document explaining those concepts in depth?

@aduth
Copy link
Member

aduth commented Feb 8, 2019

There's not currently a document which describes programmatic edits, but yes, this is the way you'd want to do it. Gutenberg uses its store as the source of truth, not the DOM.

Specifically, one of the following actions can be used to edit the attributes of a post or of a block, respectively:

I'm not positive whether these changes can take effect at the specific time a save starts. Ideally they'd be done earlier, as soon as it becomes relevant that a change be made. This is also discussed elsewhere in #13413, #7020.

In your specific code example, you should want to be careful to consider that subscribe will be called on any change to any store, so it's not just going to satisfy your condition of isSavingPost the one time it transitions from not-saving to saving.

You'll need to track the previous value to see whether it had changed. See similar: https://github.com/WordPress/gutenberg/blob/master/packages/edit-post/src/store/utils.js

I'll proactively consider the help request as resolved, with potential for further pre-save validation / behaviors as tracked at #13413.

@aduth aduth closed this as completed Feb 8, 2019
@lex127
Copy link
Author

lex127 commented Feb 15, 2019

Why do you not listen MutationObserver for handling all changes in the DOM?

How do you plan to work with native browser spell check?

There are many other third party scripts which make changes using Range API (for changing some part of text). So you will ignore these changes too.

We can emulate changes after replace some part of text with Range API. We do it using fake InputEvent which we fire on editable field. But this is not clear solution. And this fake event doesn't work for Classic block (TinyMCE editor).

Solutions suggested by you is not applicable in our case.

@aduth
Copy link
Member

aduth commented Feb 15, 2019

The block editor uses its internal data stores as the single source of truth, not the DOM. An implication of this is that you must interact with the store using the exposed actions as an interface, not by mutating the DOM directly.

That being said, the role of a component like RichText is to interpret events from the DOM and translate them to the corresponding state changes. This is how something like spell check would be handled. If you must manipulate the DOM directly and expect it to be reflected in the blocks state, you must do so in a way which would be understood by the implementation of the RichText component. Note that this is not a use-case which is officially supported, and the internal implementation of RichText may change over time. The data actions are the recommended interface.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Technical Feedback Needs testing from a developer perspective. [Type] Help Request Help with setup, implementation, or "How do I?" questions.
Projects
None yet
Development

No branches or pull requests

4 participants