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

fix(MenuButton) Implement unified method of showing/hiding MenuButton #3993

Merged
merged 1 commit into from
Mar 2, 2017

Conversation

justinanastos
Copy link
Contributor

@justinanastos justinanastos commented Jan 27, 2017

Description

When remote subtitle text tracks are removed and there are none left, the subtitle button button persists in the menu bar. This also applies to the descriptions button as seen in #3994.

Reduced test case created by @mctep: http://jsbin.com/navoruk/1/edit?html,js,output

Addresses #3890, #3994

Specific Changes proposed

  • Implement a getHideThreshold function in menu-button and override it in captions-button.
  • Remove menu-button descendants' update methods

Requirements Checklist

  • Feature implemented / Bug fixed
  • Reviewed by Two Core Contributors

@@ -58,7 +59,7 @@ class MenuButton extends ClickableComponent {
this.buttonPressed_ = false;
this.el_.setAttribute('aria-expanded', 'false');

if (this.items && this.items.length === 0) {
if (this.items && (this.items.length === 0 || (this.items.length === 1 && this.items[0] instanceof OffTextTrackMenuItem))) {
Copy link
Member

@OwenEdwards OwenEdwards Jan 31, 2017

Choose a reason for hiding this comment

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

I don't this should be handled in the MenuButton component; it should be in the sub-component CaptionsButton, using the update method which explicitly understands the different threshold if the OffTextTrackMenuItem is included.

Copy link
Member

Choose a reason for hiding this comment

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

Oh, my mistake - I was thinking of the CaptionsSettings menu item, not the OffTextTrackMenuItem.

@justinanastos
Copy link
Contributor Author

@OwenEdwards Any more feedback?

@OwenEdwards
Copy link
Member

@justinanastos I'm still confused why this happens on the subtitles menu button, and not on the captions menu button, but you're fixing it on the generic menuButton. Can you give me a little more explanation of why that is?

@justinanastos justinanastos changed the base branch from master to 5.x February 21, 2017 16:32
@justinanastos
Copy link
Contributor Author

@OwenEdwards In trying to explain why I implemented this the way I did, I realized there was a smarter way of handing it.

First, when using emulated text tracks, video.js will add a "captions settings" menu item, which is an instance of OffTextTrackMenuItem:

captions menu button

subtitles menu button

When removing the caption button, video.js will use a threshold for how many menu items exist for showing or hiding the button in control-bar/text-track-controls/subtitles-button:

/**
 * Update caption menu items
 *
 * @param {EventTarget~Event} [event]
 *        The `addtrack` or `removetrack` event that caused this function to be
 *        called.
 *
 * @listens TextTrackList#addtrack
 * @listens TextTrackList#removetrack
 */
update(event) {
  let threshold = 2;

  super.update();

  // if native, then threshold is 1 because no settings button
  if (this.player().tech_ && this.player().tech_.featuresNativeTextTracks) {
    threshold = 1;
  }
  if (this.items && this.items.length > threshold) {
    this.show();
  } else {
    this.hide();
  }
}

A more appropriate solution would be to add a similar function in control-bar/text-track-controls/subtitles-button


This PR has been updated to add an update function to control-bar/text-track-controls/subtitles-button. A "subtitles settings" menu item is never added for native or emulated subtitles, so the threshold will always be 1.

@OwenEdwards
Copy link
Member

@justinanastos okay, that seems like a cleaner fix. The problem is, this also affect the Descriptions button (see #3994). If you look at the update method in MenuButton, you'll see that it hides the menu if there are zero menu items, shows the menu if there are more than one items, but doesn't explicitly do anything if there is just one item!

So you need to look at which other menus extend the MenuButton (TrackButton, TextTrackButton, etc.), and see how far up the hierarchy you can push this change so that it affects all the menus which need fixing (e.g. does the AudioTrackButton need fixing?) without you having to put this fix in multiple places. @gkatsev may have some thoughts on that, too.

@gkatsev
Copy link
Member

gkatsev commented Feb 21, 2017

In #3890, I was thinking that we should make the threshold a generic thing for text track buttons and maybe track buttons in general. That way, captions button can set its own threshold and subtitles could use the default. And then a value of -1 or something could disable this hiding.

This PR solves the specific issue with subtitles, so, maybe it might be worth pulling it in anyway, but I think we should make it generic that way we don't have the same code in the various track buttons.

@gkatsev
Copy link
Member

gkatsev commented Feb 21, 2017

Given that @mister-ben did a similar thing in #4028, I'd be inclined to pull this in, and then making the more general fix later.

@OwenEdwards
Copy link
Member

Hmm, I'm just concerned that the Descriptions button, which is essentially identical to the subtitles button except with a different track kind and button controlText is going to be the orphaned control if we don't fix the identical issue in both of them by moving this fix up the hierarchy.

@gkatsev
Copy link
Member

gkatsev commented Feb 21, 2017

I don't disagree. However, we have a fix for subtitles, so, why not get it fixed?

@OwenEdwards
Copy link
Member

I guess I'm a fan if "do it right the first time" :-) If we pull this patch, we'll either want to undo it later and apply it higher up the hierarchy to fix #3994, or it'll get copied into DescriptionsButton, and that way lies madness ;-)

@OwenEdwards
Copy link
Member

@gkatsev I guess another way to look at this is - was it intentional, or is it a bug, that in the update method for the core component MenuButton, it hides if there are no items, shows if there are more than one items, but does nothing if there is exactly one item? If it's a bug, it should be fixed (I'm having a hard time imagining a use case for a menu with just one item, but I guess it's possible), no?

@gkatsev
Copy link
Member

gkatsev commented Feb 22, 2017

The default menu button should probably should for one and more and then TextTracks buttons need the threshold fix applied to it as a general solution, which each type of text track specifying if it needs a higher threshold (like captions button sometimes needing a threshold of 2). AudioTrackButton could be shown or not with only one item.

Looks like MenuButton has been around like that for a long time.

@justinanastos
Copy link
Contributor Author

@gkatsev I didn't fully understand what you meant in #3890 until now. This makes total sense and would be pretty simple to implement. Let me give it a shot.

@gkatsev
Copy link
Member

gkatsev commented Feb 22, 2017

Cool, that would be awesome, @justinanastos. Let me know if you have any questions, feel free to drop by our slack (http://slack.videojs.com), too.

@justinanastos
Copy link
Contributor Author

@gkatsev I did not implement the -1 behavior because, as far as I can tell, it won't be used anywhere. All menus appear to have a title, so we'll never actually want to show the menu with no content, right?

@justinanastos justinanastos changed the title fix(SubtitlesButton) Hide when the only item is OffTextTrackMenuItem fix(MenuButton) Implement unified method of showing/hiding MenuButton Feb 22, 2017
Copy link
Member

@gkatsev gkatsev left a comment

Choose a reason for hiding this comment

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

This looks simple enough, I'll take it for a spin after the change is made.

Thanks @justinanastos!

* to 1 beacuse all menus have a title.
* @type {Number}
*/
get hideThreshold() {
Copy link
Member

Choose a reason for hiding this comment

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

these should be regular methods rather than getters.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated @gkatsev .

@@ -37,6 +37,16 @@ class MenuButton extends ClickableComponent {
}

/**
* Hide the menu if the number of items is less than or equal to this threshold. This defaults
* to 1 beacuse all menus have a title.
Copy link
Member

Choose a reason for hiding this comment

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

Not all menus have a title - the Subtitles menu and the Descriptions menu have an "off" button, which should be hidden if it is the only item. <Captain Pedantic ;-) >

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated @OwenEdwards

@@ -37,6 +37,16 @@ class MenuButton extends ClickableComponent {
}

/**
* Hide the menu if the number of items is less than or equal to this threshold. This defaults
Copy link
Member

Choose a reason for hiding this comment

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

Ultimately I'd love to see each menu component actually set their threshold as they add items to the menu which can be hidden (title, off button, caption settings button, etc), but this looks like it will do for now, and covers both #3890 and #3994.

Copy link
Member

Choose a reason for hiding this comment

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

You're right. Maybe just making it be a private instance variable would be easier in the long run.
At least should be a private method.

@justinanastos thoughts?

Copy link
Member

Choose a reason for hiding this comment

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

That would avoid the multiple uses of if (this.player().tech_ && this.player().tech_.featuresNativeTextTracks) { in this component - just increment the threshold count at the same time it adds the Captions Settings Menu Item.

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 this idea a shot.

@justinanastos
Copy link
Contributor Author

@OwenEdwards and @gkatsev : I updated the logic to use a private instance variable that is incremented when menus are added.

Copy link
Member

@gkatsev gkatsev left a comment

Choose a reason for hiding this comment

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

Thanks @justinanastos!

Tests are failing, saying some of the menu buttons aren't shown correctly.
Moving the variable init might fix those tests.

*
* @type {Number}
*/
this.hideThreshold_ = 0;
Copy link
Member

Choose a reason for hiding this comment

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

this should probably move above this.update(). createItems gets called as part of createMenu which is called in update, so, we need to make sure that this threshold is initialized properly.

* Hide the menu if the number of items is less than or equal to this threshold. This defaults
* to 0 and whenever we add items to the menu we'll increment it.
*
* @type {Number}
Copy link
Member

Choose a reason for hiding this comment

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

does this need to be marked @private?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes it does @gkatsev

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Correction @gkatsev : It should be @protected because descendants should be allowed access.

Copy link
Member

Choose a reason for hiding this comment

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

Ah, didn't realize that existed.

Copy link
Contributor Author

@justinanastos justinanastos Feb 28, 2017

Choose a reason for hiding this comment

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

Me neither, I googled where to put the @private tag and found it.

@gkatsev gkatsev added the 5.x label Feb 27, 2017
@OwenEdwards
Copy link
Member

This looks much better! Once you've made the changes @gkatsev requested, and fixed the tests, it'll be a really clean solution to the various problems.

@@ -29,6 +29,14 @@ class MenuButton extends ClickableComponent {

this.update();

/**
* Hide the menu if the number of items is less than or equal to this threshold. This defaults
* to 0 and whenever we add items to the menu we'll increment it.
Copy link
Member

Choose a reason for hiding this comment

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

If I'm going to be pedantic, this ought to be "... and whenever we add items which can be hidden to the menu ..." I don't want future additions to the code to increment this when they add non-hideable items!

@justinanastos justinanastos force-pushed the fix-subtitle-button branch 2 times, most recently from 45f4546 to f84246f Compare February 28, 2017 19:39
Implement a `hideThreshold` property that defaults to 1 so
descendants can override it if necessary. Right now the only
descendant that will override will be `CaptionsButton` because
video.js adds a "captions settings" for emulated text tracks.
@gkatsev gkatsev merged commit 4367c69 into videojs:5.x Mar 2, 2017
@gkatsev
Copy link
Member

gkatsev commented Mar 2, 2017

@justinanastos can we get a version of this against master as well? If you don't have a chance to do it, let us know and we can port it over for you.

@justinanastos
Copy link
Contributor Author

Sure thing @gkatsev

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

Successfully merging this pull request may close these issues.

3 participants