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

Use delayIfDetached as default value in editor config #128

Merged
merged 27 commits into from
Jan 11, 2022
Merged

Conversation

sculpt0r
Copy link
Contributor

@sculpt0r sculpt0r commented Dec 20, 2021

Bump vue testing utility. It is no longer in the beta version. The newest version contains options for mount testing method which is useful in this case: https://vue-test-utils.vuejs.org/api/options.html#attachto

Adjust the component to use the new default config value. It requires moving editor inner instance initialization to the instanceReady event. Since with the delayIfDetach config options, it is possible that core replace or inline methods return null instead of editor instance.

Split mounted component logic onto separate methods - since preparing config for the editor is more complicated now.

Add safari launcher since BS Safari often ends with timeout errors. So it is possible to use safari in karma config on your local machine. However, I didn't modify the config.

As for the tests workflow. Hopefully, I was able to separate tests and test cases from each other. I have to make an ugly hack for the test with an empty editor config since I can't set there a fake observableParent. MutationObserver is disconnected while the editor switch mode, so I used that. But because of those problems, I made a follow up:

Currently, we are destroying the wrapper for the CKE4, however, we may destroy the editor first, and then clean up the wrapper. Currently, it makes no difference, but I've made a follow up: ckeditor/ckeditor4#5004

Extracted two functions in tests to util file.

Also, test changes may be a good introduction to #6 However - I feel like we need to put more effort to test refactoring.

Closes #102 , #86

@sculpt0r sculpt0r self-assigned this Dec 23, 2021
@sculpt0r sculpt0r marked this pull request as ready for review December 23, 2021 13:12
@sculpt0r sculpt0r removed their assignment Dec 27, 2021
@sculpt0r sculpt0r changed the title WIP: Use delayIfDetached as default value in editor config Use delayIfDetached as default value in editor config Dec 27, 2021
@github-actions
Copy link

github-actions bot commented Jan 4, 2022

It's been a while since we last heard from you. We are marking this pull request as stale due to inactivity. Please provide the requested feedback or the pull request will be closed after next 7 days.

@github-actions github-actions bot added the stale The issue / PR will be closed within the next 7 days of inactivity. label Jan 4, 2022
@jacekbogdanski jacekbogdanski self-requested a review January 4, 2022 09:33
@jacekbogdanski jacekbogdanski removed the stale The issue / PR will be closed within the next 7 days of inactivity. label Jan 4, 2022
@jacekbogdanski jacekbogdanski removed their request for review January 10, 2022 07:32
@Comandeer Comandeer self-requested a review January 10, 2022 09:00
@Comandeer Comandeer self-assigned this Jan 10, 2022
Copy link
Member

@Comandeer Comandeer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The proposed solution looks and works well. I've just only some minor comments.

We could also add a sample with a detachable component to show users how it could be used.

I've also seen that a safari launcher is added but it's not used at all. The karma config is not modified 🤔. Shouldn't it be added in place of BS Safari? Or at least added to the list of local browsers? However, it'd probably require making browsers list os-dependent.

}

config.on.instanceReady = evt => {
this.instance = evt.editor;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the moment we have two flows of setting this.instance – here and earlier, in line 63. I don't see a need to have two different flows and I'd remove the synchronous one in favor of this async one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah... that was only for the purpose of fulfilling the tests if I good remember. So the instance in 63 is eventually set to null and it is no longer undefined. I'll correct it.

config.on.instanceReady = evt => {
this.instance = evt.editor;

this.$nextTick().then( () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is nextTick needed?

Also, we could make the whole listener async and use await here – it'd eliminate one level of indentation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This particullar nextTick comes out of fix for IE: #120

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll give it a few more tries later - however making this listener async - breaks a lot of tests ;)

src/ckeditor.js Outdated
Comment on lines 101 to 104
let userInstanceReadyCallback;
if ( config.on && config.on.instanceReady ) {
userInstanceReadyCallback = config.on.instanceReady;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know which version of JS we use, buuuut…

Suggested change
let userInstanceReadyCallback;
if ( config.on && config.on.instanceReady ) {
userInstanceReadyCallback = config.on.instanceReady;
}
const userInstanceReadyCallback = config?.on?.instanceReady;

Also, it probably can be simplified to just

Suggested change
let userInstanceReadyCallback;
if ( config.on && config.on.instanceReady ) {
userInstanceReadyCallback = config.on.instanceReady;
}
const userInstanceReadyCallback = config.on.instanceReady;

as we set the value of config.on at the beginning of prepareConfig().

We can safely skip ifs here as we check the value of userInstanceReadyCallback right before invoking it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, IE11 may not allow us to use conditional chaining.

However, indeed, we already have a defensive check on config.on so this if may be skipped

@@ -413,3 +412,85 @@ describe( 'CKEditor Component', () => {
} );
}
} );

describe( 'comp on detach elem', () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
describe( 'comp on detach elem', () => {
describe( 'component on detached element', () => {

I'd rather avoid using such shortcuts. It took me a while to get what "comp" means (at first I thought it was a shortcut of "compatibility").

Copy link
Contributor Author

@sculpt0r sculpt0r Jan 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad :/ Actually, I also don't like it.

@@ -413,3 +412,85 @@ describe( 'CKEditor Component', () => {
} );
}
} );

describe( 'comp on detach elem', () => {
let wrapperr;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let wrapperr;
let wrapper;

} );

function createComponent( props, mountTarget = document.body ) {
const fakeParent = window.document.createElement( 'span' );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const fakeParent = window.document.createElement( 'span' );
const fakeParent = document.createElement( 'span' );

In all other places, we use document alone. I guess it's some leftover from the previous version of tests?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Must be... I don't remember to make it on some specific purpose 🤔

return Promise.all( [
createComponent( {}, spy ),
createComponent( {}, spy ),
createComponent( {}, spy )
] ).then( () => {
expect( spy.calledOnce ).to.equal( true );
expect( spy.callCount ).to.equal( 1 );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we use sinon + chai we could write nicer assertions using sinon-chai.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you tell what will be nicer from your perspective? :> This looks good for me. It's short, and tells you exactly the difference between calls count.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm ok with both versions, but the best one for me is:

expect( spy ).to.have.been.calledOnce;

😉

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you ok with both versions - I would keep callCount. Not sure if I mentioned that somewhere, but it is a huge difference (eg. in source of the bug) if the callback wasn't called at all or was called to many times. Current assertion gives us an exact number of calls in case of fail.

} );
}

export function delay( time, func = () => {} ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be more elegant to have something like:

await delay( 1000 );

The callback would be invoked just after the delay.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will :) However, this will require having test functions be async. And if I applied it - there is a problem to run tests at all. Not sure why 🤔 It is possible due to the docs: https://mochajs.org/#using-async-await, but I've got:
image

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to be a bug from Babel and we need an additional plugin if we want to use async/await syntax (which can, however, result in a slightly bigger bundle).

@sculpt0r sculpt0r self-assigned this Jan 10, 2022
@sculpt0r
Copy link
Contributor Author

Rebased on the newest master.

@sculpt0r
Copy link
Contributor Author

sculpt0r commented Jan 10, 2022

I've also seen that a safari launcher is added but it's not used at all. The karma config is not modified 🤔. Shouldn't it be added in place of BS Safari? Or at least added to the list of local browsers? However, it'd probably require making browsers list os-dependent.

I didn't touch the karma config. As you mentioned that will require additional changes around it. I thought it may be a nice option for the developer to just change the config without searching and installing the launcher. Do you want me to remove it from dependencies since it is not explicitly used in the code - @Comandeer ?

@Comandeer
Copy link
Member

Do you want me to remove it from dependencies since it is not explicitly used in the code - @Comandeer ?

Yes, it could be extracted as a separate ticket.

@sculpt0r
Copy link
Contributor Author

@Comandeer - ready for another review.

Copy link
Member

@Comandeer Comandeer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Use delayIfDetached config for editor set to true by default
3 participants