Commit 8990410e authored by Bryce Johnson's avatar Bryce Johnson

Remove emoji-menu from the render tree when hidden.

parent d15109dc
...@@ -23,6 +23,9 @@ const categoryLabelMap = { ...@@ -23,6 +23,9 @@ const categoryLabelMap = {
flags: 'Flags', flags: 'Flags',
}; };
const IS_VISIBLE = 'is-visible';
const IS_RENDERED = 'is-rendered';
class AwardsHandler { class AwardsHandler {
constructor(emoji) { constructor(emoji) {
this.emoji = emoji; this.emoji = emoji;
...@@ -50,7 +53,7 @@ class AwardsHandler { ...@@ -50,7 +53,7 @@ class AwardsHandler {
if (!$target.closest('.emoji-menu').length) { if (!$target.closest('.emoji-menu').length) {
if ($('.emoji-menu').is(':visible')) { if ($('.emoji-menu').is(':visible')) {
$('.js-add-award.is-active').removeClass('is-active'); $('.js-add-award.is-active').removeClass('is-active');
$('.emoji-menu').removeClass('is-visible'); this.hideMenuElement($('.emoji-menu'));
} }
} }
}); });
...@@ -87,12 +90,12 @@ class AwardsHandler { ...@@ -87,12 +90,12 @@ class AwardsHandler {
if ($menu.length) { if ($menu.length) {
if ($menu.is('.is-visible')) { if ($menu.is('.is-visible')) {
$addBtn.removeClass('is-active'); $addBtn.removeClass('is-active');
$menu.removeClass('is-visible'); this.hideMenuElement($menu);
$('.js-emoji-menu-search').blur(); $('.js-emoji-menu-search').blur();
} else { } else {
$addBtn.addClass('is-active'); $addBtn.addClass('is-active');
this.positionMenu($menu, $addBtn); this.positionMenu($menu, $addBtn);
$menu.addClass('is-visible'); this.showMenuElement($menu);
$('.js-emoji-menu-search').focus(); $('.js-emoji-menu-search').focus();
} }
} else { } else {
...@@ -102,7 +105,7 @@ class AwardsHandler { ...@@ -102,7 +105,7 @@ class AwardsHandler {
$addBtn.removeClass('is-loading'); $addBtn.removeClass('is-loading');
this.positionMenu($createdMenu, $addBtn); this.positionMenu($createdMenu, $addBtn);
return setTimeout(() => { return setTimeout(() => {
$createdMenu.addClass('is-visible'); this.showMenuElement($createdMenu);
$('.js-emoji-menu-search').focus(); $('.js-emoji-menu-search').focus();
}, 200); }, 200);
}); });
...@@ -240,7 +243,8 @@ class AwardsHandler { ...@@ -240,7 +243,8 @@ class AwardsHandler {
if (gl.utils.isInIssuePage() && !isMainAwardsBlock) { if (gl.utils.isInIssuePage() && !isMainAwardsBlock) {
const id = votesBlock.attr('id').replace('note_', ''); const id = votesBlock.attr('id').replace('note_', '');
$('.emoji-menu').removeClass('is-visible'); this.hideMenuElement($('.emoji-menu'));
$('.js-add-award.is-active').removeClass('is-active'); $('.js-add-award.is-active').removeClass('is-active');
const toggleAwardEvent = new CustomEvent('toggleAward', { const toggleAwardEvent = new CustomEvent('toggleAward', {
detail: { detail: {
...@@ -260,7 +264,8 @@ class AwardsHandler { ...@@ -260,7 +264,8 @@ class AwardsHandler {
return typeof callback === 'function' ? callback() : undefined; return typeof callback === 'function' ? callback() : undefined;
}); });
$('.emoji-menu').removeClass('is-visible'); this.hideMenuElement($('.emoji-menu'));
return $('.js-add-award.is-active').removeClass('is-active'); return $('.js-add-award.is-active').removeClass('is-active');
} }
...@@ -528,6 +533,34 @@ class AwardsHandler { ...@@ -528,6 +533,34 @@ class AwardsHandler {
return $matchingElements.closest('li').clone(); return $matchingElements.closest('li').clone();
} }
/* showMenuElement and hideMenuElement are performance optimizations. We use
* opacity to show/hide the emoji menu, because we can animate it. But opacity
* leaves hidden elements in the render tree, which is unacceptable given the number
* of emoji elements in the emoji menu (5k+). To get the best of both worlds, we separately
* apply IS_RENDERED to add/remove the menu from the render tree and IS_VISIBLE to animate
* the menu being opened and closed. */
showMenuElement($emojiMenu) {
// enqueues animation as a microtask, so it begins ASAP once IS_RENDERED added
Promise.resolve().then(() => { // eslint-disable-line promise/catch-or-return
$emojiMenu.addClass(IS_VISIBLE);
});
$emojiMenu.addClass(IS_RENDERED);
}
hideMenuElement($emojiMenu) {
$emojiMenu.on(transitionEndEventString, (e) => {
if (e.currentTarget === e.target) {
$emojiMenu
.removeClass(IS_RENDERED)
.off(transitionEndEventString);
}
});
$emojiMenu.removeClass(IS_VISIBLE);
}
destroy() { destroy() {
this.eventListeners.forEach((entry) => { this.eventListeners.forEach((entry) => {
entry.element.off.call(entry.element, ...entry.args); entry.element.off.call(entry.element, ...entry.args);
......
...@@ -27,6 +27,14 @@ ...@@ -27,6 +27,14 @@
transition: .3s cubic-bezier(.67, .06, .19, 1.44); transition: .3s cubic-bezier(.67, .06, .19, 1.44);
transition-property: transform, opacity; transition-property: transform, opacity;
&.is-rendered {
display: block;
}
&:not(.is-rendered) {
display: none;
}
&.is-aligned-right { &.is-aligned-right {
transform-origin: 100% -45px; transform-origin: 100% -45px;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment