[Media Controls] Tracks panel can show text tracks with mode "hidden" as selected
https://bugs.webkit.org/show_bug.cgi?id=213839
<rdar://problem/57989325>

Reviewed by Jer Noble.

Source/WebCore:

We only considered text tracks that had their "mode" set to "disabled" as tracks that weren't selected,
but there is also the "hidden" mode which should share the same UI state. We now check for "mode" to
be set to "showing" to consider a text track as selected in the tracks panel.

Test: media/modern-media-controls/tracks-support/tracks-support-hidden-tracks.html

* Modules/modern-media-controls/media/tracks-support.js:
(TracksSupport.prototype.tracksPanelIsTrackInSectionSelected):

LayoutTests:

Add a new test that dumps the selection state of tracks in the tracks panel when all of media.textTracks
have been set to mode = "hidden".

* media/modern-media-controls/tracks-support/tracks-support-hidden-tracks-expected.txt: Added.
* media/modern-media-controls/tracks-support/tracks-support-hidden-tracks.html: Added.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@263802 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 10e4603..c3d8bb5 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,17 @@
+2020-07-01  Antoine Quint  <graouts@webkit.org>
+
+        [Media Controls] Tracks panel can show text tracks with mode "hidden" as selected
+        https://bugs.webkit.org/show_bug.cgi?id=213839
+        <rdar://problem/57989325>
+
+        Reviewed by Jer Noble.
+
+        Add a new test that dumps the selection state of tracks in the tracks panel when all of media.textTracks
+        have been set to mode = "hidden".
+
+        * media/modern-media-controls/tracks-support/tracks-support-hidden-tracks-expected.txt: Added.
+        * media/modern-media-controls/tracks-support/tracks-support-hidden-tracks.html: Added.
+
 2020-07-01  Karl Rackler  <rackler@apple.com>
 
         Remove expectation for fast/css/replaced-element-implicit-size.html as they are passing. 
diff --git a/LayoutTests/media/modern-media-controls/tracks-support/tracks-support-hidden-tracks-expected.txt b/LayoutTests/media/modern-media-controls/tracks-support/tracks-support-hidden-tracks-expected.txt
new file mode 100644
index 0000000..7ad3fc1
--- /dev/null
+++ b/LayoutTests/media/modern-media-controls/tracks-support/tracks-support-hidden-tracks-expected.txt
@@ -0,0 +1,21 @@
+This test checks that the tracks panel doesn't show any track as selected if all the text tracks for a media element are marked as "hidden".
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS shadowRoot.querySelector('button.tracks') became different from null
+PASS shadowRoot.querySelector('button.tracks').getBoundingClientRect().width became different from 0
+
+=== Initial state ===
+
+[x] Off
+[-] Auto (Recommended)
+[-] English Subtitles
+[-] French Subtitles
+[-] German Subtitles
+[-] Spanish Subtitles
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/media/modern-media-controls/tracks-support/tracks-support-hidden-tracks.html b/LayoutTests/media/modern-media-controls/tracks-support/tracks-support-hidden-tracks.html
new file mode 100644
index 0000000..5627785
--- /dev/null
+++ b/LayoutTests/media/modern-media-controls/tracks-support/tracks-support-hidden-tracks.html
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<script src="../../../resources/js-test-pre.js"></script>
+<body>
+<video src="../../content/CC+Subtitles.mov" style="position: absolute; left: 0; top: 0; width: 640px; height: 360px;" controls autoplay></video>
+<script type="text/javascript">
+
+window.jsTestIsAsync = true;
+
+description(`This test checks that the tracks panel doesn't show any track as selected if all the text tracks for a media element are marked as "hidden".`);
+
+const media = document.querySelector("video");
+const shadowRoot = window.internals.shadowRoot(media);
+
+media.addEventListener("play", () => {
+    media.pause();
+
+    shouldBecomeDifferent("shadowRoot.querySelector('button.tracks')", "null", () => {
+        shouldBecomeDifferent("shadowRoot.querySelector('button.tracks').getBoundingClientRect().width", "0", runTest);
+    });
+});
+
+async function runTest()
+{
+    // Start by making sure all tracks are marked as "hidden".
+    Array.from(media.textTracks).forEach(track => track.mode = "hidden");
+
+    // Next, bring up the tracks menu by clicking on the tracks button.
+    await clickOnTracksButton();
+    // Dump the state of the tracks menu for text tracks, which should show the first embedded text track as selected.
+    dumpTextTracksListNodes("Initial state");
+
+    finishTest();
+}
+
+function textTracksListNodes()
+{
+    return shadowRoot.querySelectorAll(".tracks-panel section:last-of-type > ul > li");
+}
+
+function dumpTextTracksListNodes(msg)
+{
+    debug("");
+    debug(`=== ${msg} ===`);
+    debug("");
+    Array.from(textTracksListNodes()).forEach(li => debug(`${li.classList.contains("selected") ? "[x]" : "[-]"} ${li.textContent}`));
+}
+
+async function clickOnTracksButton()
+{
+    await new Promise(requestAnimationFrame);
+    clickOnElement(shadowRoot.lastChild.querySelector("button.tracks"));
+    await new Promise(requestAnimationFrame);
+}
+
+function clickOnElement(element)
+{
+    const bounds = element.getBoundingClientRect();
+    eventSender.mouseMoveTo(bounds.left + 1, bounds.top + 1);
+    eventSender.mouseDown();
+    eventSender.mouseUp();
+}
+
+function finishTest()
+{
+    debug("");
+    media.remove();
+    finishJSTest();
+}
+
+</script>
+<script src="../../../resources/js-test-post.js"></script>
+</body>
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 449a850..6d8c56d 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,20 @@
+2020-07-01  Antoine Quint  <graouts@webkit.org>
+
+        [Media Controls] Tracks panel can show text tracks with mode "hidden" as selected
+        https://bugs.webkit.org/show_bug.cgi?id=213839
+        <rdar://problem/57989325>
+
+        Reviewed by Jer Noble.
+
+        We only considered text tracks that had their "mode" set to "disabled" as tracks that weren't selected,
+        but there is also the "hidden" mode which should share the same UI state. We now check for "mode" to
+        be set to "showing" to consider a text track as selected in the tracks panel.
+
+        Test: media/modern-media-controls/tracks-support/tracks-support-hidden-tracks.html
+
+        * Modules/modern-media-controls/media/tracks-support.js:
+        (TracksSupport.prototype.tracksPanelIsTrackInSectionSelected):
+
 2020-07-01  Sam Weinig  <weinig@apple.com>
 
         Regression (r263788): Windows build broken: nameForRenderTreeAsText is not a member of WebCore::Color
diff --git a/Source/WebCore/Modules/modern-media-controls/media/tracks-support.js b/Source/WebCore/Modules/modern-media-controls/media/tracks-support.js
index d11b7e5..a859084 100644
--- a/Source/WebCore/Modules/modern-media-controls/media/tracks-support.js
+++ b/Source/WebCore/Modules/modern-media-controls/media/tracks-support.js
@@ -104,14 +104,15 @@
         const textTracks = this._textTracks();
         const trackItem = textTracks[trackIndex];
         const host = this.mediaController.host;
-        const allTracksDisabled = textTracks.every(track => track.mode === "disabled");
+        const trackIsShowing = track => track.mode === "showing";
+        const allTracksDisabled = !textTracks.some(trackIsShowing);
         const usesAutomaticTrack = host ? (host.captionDisplayMode === "automatic" && allTracksDisabled) : false;
 
         if (allTracksDisabled && host && trackItem === host.captionMenuOffItem && (host.captionDisplayMode === "forced-only" || host.captionDisplayMode === "manual"))
             return true;
         if (host && trackItem === host.captionMenuAutomaticItem && usesAutomaticTrack)
             return true;
-        return !usesAutomaticTrack && trackItem.mode !== "disabled";
+        return !usesAutomaticTrack && trackIsShowing(trackItem);
     }
 
     tracksPanelSelectionDidChange(trackIndex, sectionIndex)