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

Convert FlashObject to native class #394

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion ember-cli-flash/declarations/flash/object.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,5 @@ declare module 'ember-cli-flash/flash/object' {
allowExit(): void;
timerTask(): void;
exitTimerTask(): void;
destroy(): void;
Copy link
Contributor Author

@gilest gilest Mar 7, 2024

Choose a reason for hiding this comment

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

This was an EmberObject method. Public API destroyMessage() will destroy the message and should be used instead.

}
}
24 changes: 10 additions & 14 deletions ember-cli-flash/src/flash/object.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { cancel, later } from '@ember/runloop';
import { isTesting, macroCondition } from '@embroider/macros';
import { tracked } from '@glimmer/tracking';
import { guidFor } from '@ember/object/internals';
import { destroy, isDestroyed, registerDestructor } from '@ember/destroyable';

// Disable timeout by default when running tests
const defaultDisableTimeout = macroCondition(isTesting()) ? true : false;
Expand All @@ -12,7 +13,6 @@ export default class FlashObject {
@tracked message = '';
isExitable = true;
initializedTime = null;
isDestroyed = false;

// testHelperDisableTimeout – Set by `disableTimeout` and `enableTimeout` in test-support.js

Expand All @@ -29,6 +29,13 @@ export default class FlashObject {
this[key] = value;
}

registerDestructor(this, () => {
this.onDestroy?.();

this._cancelTimer();
this._cancelTimer('exitTaskInstance');
});

if (this._disableTimeout || this.sticky) {
return;
}
Expand All @@ -53,17 +60,6 @@ export default class FlashObject {
this.exitTimerTask();
this.onDidExitMessage?.();
}

destroy() {
if (this.onDestroy) {
this.onDestroy();
}

this._cancelTimer();
this._cancelTimer('exitTaskInstance');
this.isDestroyed = true;
}

preventExit() {
this.isExitable = false;
}
Expand All @@ -84,7 +80,7 @@ export default class FlashObject {
}

exitTimerTask() {
if (this.isDestroyed) {
if (isDestroyed(this)) {
return;
}
this.exiting = true;
Expand Down Expand Up @@ -129,7 +125,7 @@ export default class FlashObject {
if (queue) {
queue.removeObject(this);
}
this.destroy();
destroy(this);
this.onDidDestroyMessage?.();
}
}
5 changes: 4 additions & 1 deletion ember-cli-flash/src/services/flash-messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import objectWithout from '../utils/object-without';
import { getOwner } from '@ember/application';
import flashMessageOptions from '../utils/flash-message-options';
import getWithDefault from '../utils/get-with-default';
import { associateDestroyableChild } from '@ember/destroyable';

export default class FlashMessagesService extends Service {
@(equal('queue.length', 0).readOnly())
Expand Down Expand Up @@ -103,7 +104,9 @@ export default class FlashMessagesService extends Service {
set(flashMessageOptions, key, option);
}

return new FlashMessage(flashMessageOptions);
const message = new FlashMessage(flashMessageOptions);
associateDestroyableChild(this, message);
return message;
}

_getOptionOrDefault(key, value) {
Expand Down
19 changes: 10 additions & 9 deletions test-app/tests/integration/components/flash-message-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
import hbs from 'htmlbars-inline-precompile';
import FlashMessage from 'ember-cli-flash/flash/object';
import { next, later } from '@ember/runloop';
import { isDestroyed } from '@ember/destroyable';

const timeoutDefault = 1000;
const TIMEOUT = 50;
Expand Down Expand Up @@ -89,7 +90,7 @@ module('Integration | Component | flash message', function (hooks) {
this.set('flag', false);

await settled();
assert.ok(this.flash.isDestroyed, 'Flash Object isDestroyed');
assert.ok(isDestroyed(this.flash), 'Flash Object isDestroyed');
});

test('flash message is removed after timeout', async function (assert) {
Expand All @@ -115,7 +116,7 @@ module('Integration | Component | flash message', function (hooks) {
() => {
assert.dom('*').hasText('hi');
assert.notOk(
this.flash.isDestroyed,
isDestroyed(this.flash),
'Flash is not destroyed immediately'
);
},
Expand All @@ -124,7 +125,7 @@ module('Integration | Component | flash message', function (hooks) {

await settled();

assert.ok(this.flash.isDestroyed, 'Flash Object is destroyed');
assert.ok(isDestroyed(this.flash), 'Flash Object is destroyed');
});

test('flash message is removed after timeout if mouse enters', async function (assert) {
Expand Down Expand Up @@ -152,7 +153,7 @@ module('Integration | Component | flash message', function (hooks) {

next(this, () => {
assert.notOk(
flashObject.isDestroyed,
isDestroyed(flashObject),
'Flash Object is not destroyed'
);
triggerEvent('#testFlash', 'mouseleave');
Expand All @@ -163,7 +164,7 @@ module('Integration | Component | flash message', function (hooks) {

await settled();

assert.ok(flashObject.isDestroyed, 'Flash Object is destroyed');
assert.ok(isDestroyed(flashObject), 'Flash Object is destroyed');
});

test('a custom component can use the close closure action', async function (assert) {
Expand All @@ -185,14 +186,14 @@ module('Integration | Component | flash message', function (hooks) {
</FlashMessage>
`);

assert.notOk(this.flash.isDestroyed, 'flash has not been destroyed yet');
assert.notOk(isDestroyed(this.flash), 'flash has not been destroyed yet');

await click('.alert');
assert.notOk(this.flash.isDestroyed, 'flash has not been destroyed yet');
assert.notOk(isDestroyed(this.flash), 'flash has not been destroyed yet');

await click('.alert a');
assert.ok(
this.flash.isDestroyed,
isDestroyed(this.flash),
'flash is destroyed after clicking close'
);
});
Expand All @@ -215,7 +216,7 @@ module('Integration | Component | flash message', function (hooks) {

await click('.alert');
assert.dom('.alert').hasClass('exiting', 'exiting class is applied');
assert.ok(flashObject.isDestroyed, 'Flash Object is destroyed');
assert.ok(isDestroyed(flashObject), 'Flash Object is destroyed');
});

test('custom message type class name prefix is applied', async function (assert) {
Expand Down
7 changes: 4 additions & 3 deletions test-app/tests/unit/flash/object-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { isPresent } from '@ember/utils';
import { module, test } from 'qunit';
import FlashMessage from 'ember-cli-flash/flash/object';
import { disableTimeout, enableTimeout } from 'ember-cli-flash/test-support';
import { isDestroyed } from '@ember/destroyable';

const testTimerDuration = 50;
let flash = null;
Expand Down Expand Up @@ -80,7 +81,7 @@ module('FlashMessageObject', function (hooks) {
};

later(() => {
assert.true(flash.isDestroyed, 'it sets `isDestroyed` to true');
assert.true(isDestroyed(flash), 'it sets `isDestroyed` to true');
assert.notOk(flash.timer, 'it cancels the timer');
assert.strictEqual(
result,
Expand All @@ -104,7 +105,7 @@ module('FlashMessageObject', function (hooks) {
});

later(() => {
assert.false(stickyFlash.isDestroyed, 'it is not destroyed');
assert.false(isDestroyed(stickyFlash), 'it is not destroyed');
done();
}, testTimerDuration);
});
Expand All @@ -116,7 +117,7 @@ module('FlashMessageObject', function (hooks) {
flash.destroyMessage();
});

assert.true(flash.isDestroyed);
assert.true(isDestroyed(flash));
assert.notOk(flash.timer);
});

Expand Down
Loading