[Modern Media Controls] Basic MediaController
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 17 Oct 2016 22:03:16 +0000 (22:03 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 17 Oct 2016 22:03:16 +0000 (22:03 +0000)
https://bugs.webkit.org/show_bug.cgi?id=163539
<rdar://problem/28797542>

Patch by Antoine Quint <graouts@apple.com> on 2016-10-17
Reviewed by Darin Adler.

Source/WebCore:

We add a new main.js file which acts as the entry point by implementing the createControls()
function that HTMLMediaElement::ensureMediaControlsInjectedScript() once the shadow root has
been created. That functions creates an instance of the new MediaController class, which is
the controller object that will handle communication between the media controls and the media
element. At first, this MediaController class is very limited and assumes macOS inline
layout traits and forces a start button to be shown over the media, which can be played
to start the media and show the full controls. More functionality will be added by future patches.

Tests: media/modern-media-controls/media-controller/media-controller-click-to-start.html
       media/modern-media-controls/media-controller/media-controller-constructor.html
       media/modern-media-controls/media-controller/media-controller-resize.html

* Modules/modern-media-controls/main.js: Added.
(createControls):
* Modules/modern-media-controls/media/media-controller.js: Added.
(MediaController):
(MediaController.prototype.set pageScaleFactor):
(MediaController.prototype.set usesLTRUserInterfaceLayoutDirection):
(MediaController.prototype.handleEvent):
(MediaController.prototype.buttonWasClicked):
(MediaController.prototype._updateControlsSize):
* WebCore.xcodeproj/project.pbxproj:
* rendering/RenderThemeMac.mm:
(WebCore::RenderThemeMac::mediaControlsStyleSheet):
(WebCore::RenderThemeMac::mediaControlsScript):

LayoutTests:

Testing the properties of the new MediaController class and the availability and behavior of the
createControls() global function.

* media/modern-media-controls/media-controller/media-controller-click-to-start-expected.txt: Added.
* media/modern-media-controls/media-controller/media-controller-click-to-start.html: Added.
* media/modern-media-controls/media-controller/media-controller-constructor-expected.txt: Added.
* media/modern-media-controls/media-controller/media-controller-constructor.html: Added.
* media/modern-media-controls/media-controller/media-controller-resize-expected.txt: Added.
* media/modern-media-controls/media-controller/media-controller-resize.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207436 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
LayoutTests/ChangeLog
LayoutTests/media/modern-media-controls/media-controller/media-controller-click-to-start-expected.txt [new file with mode: 0644]
LayoutTests/media/modern-media-controls/media-controller/media-controller-click-to-start.html [new file with mode: 0644]
LayoutTests/media/modern-media-controls/media-controller/media-controller-constructor-expected.txt [new file with mode: 0644]
LayoutTests/media/modern-media-controls/media-controller/media-controller-constructor.html [new file with mode: 0644]
LayoutTests/media/modern-media-controls/media-controller/media-controller-resize-expected.txt [new file with mode: 0644]
LayoutTests/media/modern-media-controls/media-controller/media-controller-resize.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/Modules/modern-media-controls/main.js [new file with mode: 0644]
Source/WebCore/Modules/modern-media-controls/media/media-controller.js [new file with mode: 0644]
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/rendering/RenderThemeMac.mm

index 203cab6..38fd05c 100644 (file)
@@ -1,3 +1,21 @@
+2016-10-17  Antoine Quint  <graouts@apple.com>
+
+        [Modern Media Controls] Basic MediaController
+        https://bugs.webkit.org/show_bug.cgi?id=163539
+        <rdar://problem/28797542>
+
+        Reviewed by Darin Adler.
+
+        Testing the properties of the new MediaController class and the availability and behavior of the
+        createControls() global function.
+
+        * media/modern-media-controls/media-controller/media-controller-click-to-start-expected.txt: Added.
+        * media/modern-media-controls/media-controller/media-controller-click-to-start.html: Added.
+        * media/modern-media-controls/media-controller/media-controller-constructor-expected.txt: Added.
+        * media/modern-media-controls/media-controller/media-controller-constructor.html: Added.
+        * media/modern-media-controls/media-controller/media-controller-resize-expected.txt: Added.
+        * media/modern-media-controls/media-controller/media-controller-resize.html: Added.
+
 2016-10-17  Michael Catanzaro  <mcatanzaro@igalia.com>
 
         [GTK] Skip layout tests under crypto/workers/subtle
diff --git a/LayoutTests/media/modern-media-controls/media-controller/media-controller-click-to-start-expected.txt b/LayoutTests/media/modern-media-controls/media-controller/media-controller-click-to-start-expected.txt
new file mode 100644 (file)
index 0000000..18e9dae
--- /dev/null
@@ -0,0 +1,15 @@
+Testing the MediaController click-to-start behavior.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS mediaController.controls.showsStartButton is true
+
+Dispatching click event to the start button
+Media is playing
+PASS mediaController.controls.showsStartButton is false
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/media/modern-media-controls/media-controller/media-controller-click-to-start.html b/LayoutTests/media/modern-media-controls/media-controller/media-controller-click-to-start.html
new file mode 100644 (file)
index 0000000..4e511ac
--- /dev/null
@@ -0,0 +1,62 @@
+<script src="../../../resources/js-test-pre.js"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/scheduler.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/layout-node.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/layout-item.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/button.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/buttons-container.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/icon-service.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/start-button.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/icon-button.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/play-pause-button.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/skip-back-button.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/airplay-button.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/pip-button.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/fullscreen-button.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/mute-button.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/tracks-button.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/slider.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/volume-slider.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/scrubber.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/time-label.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/time-control.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/placard.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/airplay-placard.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/pip-placard.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/media-controls.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/macos-media-controls.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/macos-inline-media-controls.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/media/media-controller.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/main.js" type="text/javascript"></script>
+<body>
+<video src="../../content/test.mp4" style="width: 320px; height: 240px;"></video>
+<div id="shadow"></div>
+<script type="text/javascript">
+
+window.jsTestIsAsync = true;
+
+description("Testing the <code>MediaController</code> click-to-start behavior.");
+
+iconService.directoryPath = "../../../../Source/WebCore/Modules/modern-media-controls/images";
+
+const shadowRoot = document.querySelector("div#shadow").attachShadow({ mode: "open" });
+const media = document.querySelector("video");
+const mediaController = createControls(shadowRoot, media, null);
+
+shouldBeTrue("mediaController.controls.showsStartButton");
+
+media.addEventListener("play", function() {
+    debug("Media is playing");
+    shouldBeFalse("mediaController.controls.showsStartButton");
+    debug("");
+    shadowRoot.host.remove();
+    media.remove();
+    finishJSTest();
+});
+
+debug("");
+debug("Dispatching click event to the start button");
+mediaController.controls.startButton.element.click();
+
+</script>
+<script src="../../../resources/js-test-post.js"></script>
+</body>
diff --git a/LayoutTests/media/modern-media-controls/media-controller/media-controller-constructor-expected.txt b/LayoutTests/media/modern-media-controls/media-controller/media-controller-constructor-expected.txt
new file mode 100644 (file)
index 0000000..5d4aadc
--- /dev/null
@@ -0,0 +1,16 @@
+Testing the MediaController constructor.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS createControls is defined.
+PASS createControls is an instance of Function
+PASS mediaController is an instance of MediaController
+PASS mediaController.shadowRoot is shadowRoot
+PASS mediaController.media is media
+PASS mediaController.controls is an instance of MediaControls
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/media/modern-media-controls/media-controller/media-controller-constructor.html b/LayoutTests/media/modern-media-controls/media-controller/media-controller-constructor.html
new file mode 100644 (file)
index 0000000..15f40c5
--- /dev/null
@@ -0,0 +1,57 @@
+<script src="../../../resources/js-test-pre.js"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/scheduler.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/layout-node.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/layout-item.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/button.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/buttons-container.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/icon-service.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/start-button.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/icon-button.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/play-pause-button.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/skip-back-button.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/airplay-button.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/pip-button.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/fullscreen-button.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/mute-button.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/tracks-button.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/slider.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/volume-slider.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/scrubber.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/time-label.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/time-control.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/placard.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/airplay-placard.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/pip-placard.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/media-controls.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/macos-media-controls.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/macos-inline-media-controls.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/media/media-controller.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/main.js" type="text/javascript"></script>
+<body>
+<video src="../../content/test.mp4"></video>
+<div id="shadow"></div>
+<script type="text/javascript">
+
+description("Testing the <code>MediaController</code> constructor.");
+
+iconService.directoryPath = "../../../../Source/WebCore/Modules/modern-media-controls/images";
+
+shouldBeDefined("createControls");
+shouldBeType("createControls", "Function");
+
+const shadowRoot = document.querySelector("div#shadow").attachShadow({ mode: "open" });
+const media = document.querySelector("video");
+const mediaController = createControls(shadowRoot, media, null);
+
+shouldBeType("mediaController", "MediaController");
+shouldBe("mediaController.shadowRoot", "shadowRoot");
+shouldBe("mediaController.media", "media");
+shouldBeType("mediaController.controls", "MediaControls");
+
+shadowRoot.host.remove();
+media.remove();
+debug("");
+
+</script>
+<script src="../../../resources/js-test-post.js"></script>
+</body>
diff --git a/LayoutTests/media/modern-media-controls/media-controller/media-controller-resize-expected.txt b/LayoutTests/media/modern-media-controls/media-controller/media-controller-resize-expected.txt
new file mode 100644 (file)
index 0000000..7fafcd3
--- /dev/null
@@ -0,0 +1,17 @@
+Testing the MediaController resizing behavior.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Checking initial size
+PASS mediaController.controls.width is 320
+PASS mediaController.controls.height is 240
+
+Resizing to 400x300
+PASS mediaController.controls.width is 400
+PASS mediaController.controls.height is 300
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/media/modern-media-controls/media-controller/media-controller-resize.html b/LayoutTests/media/modern-media-controls/media-controller/media-controller-resize.html
new file mode 100644 (file)
index 0000000..7065642
--- /dev/null
@@ -0,0 +1,72 @@
+<script src="../../../resources/js-test-pre.js"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/scheduler.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/layout-node.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/layout-item.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/button.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/buttons-container.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/icon-service.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/start-button.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/icon-button.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/play-pause-button.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/skip-back-button.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/airplay-button.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/pip-button.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/fullscreen-button.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/mute-button.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/tracks-button.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/slider.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/volume-slider.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/scrubber.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/time-label.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/time-control.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/placard.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/airplay-placard.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/pip-placard.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/media-controls.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/macos-media-controls.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/controls/macos-inline-media-controls.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/media/media-controller.js" type="text/javascript"></script>
+<script src="../../../../Source/WebCore/Modules/modern-media-controls/main.js" type="text/javascript"></script>
+<body>
+<video src="../../content/test.mp4" style="width: 320px; height: 240px;"></video>
+<div id="shadow"></div>
+<script type="text/javascript">
+
+window.jsTestIsAsync = true;
+
+description("Testing the <code>MediaController</code> resizing behavior.");
+
+iconService.directoryPath = "../../../../Source/WebCore/Modules/modern-media-controls/images";
+
+const shadowRoot = document.querySelector("div#shadow").attachShadow({ mode: "open" });
+const media = document.querySelector("video");
+const mediaController = createControls(shadowRoot, media, null);
+
+let numberOfFrames = 0;
+scheduler.frameDidFire = function()
+{
+    numberOfFrames++;
+
+    if (numberOfFrames == 1) {
+        debug("Checking initial size");
+        shouldBe("mediaController.controls.width", "320");
+        shouldBe("mediaController.controls.height", "240");
+        
+        debug("");
+        debug("Resizing to 400x300");
+        media.style.width = "400px";
+        media.style.height = "300px";
+    } else {
+        shouldBe("mediaController.controls.width", "400");
+        shouldBe("mediaController.controls.height", "300");
+
+        debug("");
+        shadowRoot.host.remove();
+        media.remove();
+        finishJSTest();
+    }
+};
+
+</script>
+<script src="../../../resources/js-test-post.js"></script>
+</body>
index c2fb07d..9dcd87e 100644 (file)
@@ -1,3 +1,37 @@
+2016-10-17  Antoine Quint  <graouts@apple.com>
+
+        [Modern Media Controls] Basic MediaController
+        https://bugs.webkit.org/show_bug.cgi?id=163539
+        <rdar://problem/28797542>
+
+        Reviewed by Darin Adler.
+
+        We add a new main.js file which acts as the entry point by implementing the createControls()
+        function that HTMLMediaElement::ensureMediaControlsInjectedScript() once the shadow root has
+        been created. That functions creates an instance of the new MediaController class, which is
+        the controller object that will handle communication between the media controls and the media
+        element. At first, this MediaController class is very limited and assumes macOS inline
+        layout traits and forces a start button to be shown over the media, which can be played
+        to start the media and show the full controls. More functionality will be added by future patches.
+
+        Tests: media/modern-media-controls/media-controller/media-controller-click-to-start.html
+               media/modern-media-controls/media-controller/media-controller-constructor.html
+               media/modern-media-controls/media-controller/media-controller-resize.html
+
+        * Modules/modern-media-controls/main.js: Added.
+        (createControls):
+        * Modules/modern-media-controls/media/media-controller.js: Added.
+        (MediaController):
+        (MediaController.prototype.set pageScaleFactor):
+        (MediaController.prototype.set usesLTRUserInterfaceLayoutDirection):
+        (MediaController.prototype.handleEvent):
+        (MediaController.prototype.buttonWasClicked):
+        (MediaController.prototype._updateControlsSize):
+        * WebCore.xcodeproj/project.pbxproj:
+        * rendering/RenderThemeMac.mm:
+        (WebCore::RenderThemeMac::mediaControlsStyleSheet):
+        (WebCore::RenderThemeMac::mediaControlsScript):
+
 2016-10-17  Anders Carlsson  <andersca@apple.com>
 
         Remove an unused HistoryItem function
diff --git a/Source/WebCore/Modules/modern-media-controls/main.js b/Source/WebCore/Modules/modern-media-controls/main.js
new file mode 100644 (file)
index 0000000..14a48ac
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// This is called from HTMLMediaElement::ensureMediaControlsInjectedScript().
+function createControls(shadowRoot, media, host)
+{
+    if (host) {
+        iconService.mediaControlsHost = host;
+        shadowRoot.appendChild(document.createElement("style")).textContent = host.shadowRootCSSText;
+    }
+
+    return new MediaController(shadowRoot, media, host);
+}
diff --git a/Source/WebCore/Modules/modern-media-controls/media/media-controller.js b/Source/WebCore/Modules/modern-media-controls/media/media-controller.js
new file mode 100644 (file)
index 0000000..e350dea
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+class MediaController
+{
+
+    constructor(shadowRoot, media, host)
+    {
+        this.shadowRoot = shadowRoot;
+        this.media = media;
+
+        // FIXME: This should get set dynamically based on the current environment.
+        this.layoutTraits = LayoutTraits.macOS;
+
+        this.controls = new MacOSInlineMediaControls
+        shadowRoot.appendChild(this.controls.element);        
+
+        this.controls.startButton.uiDelegate = this;
+        this.controls.showsStartButton = true;
+
+        this._updateControlsSize();
+        media.addEventListener("resize", this);
+    }
+
+    // Protected
+
+    set pageScaleFactor(pageScaleFactor)
+    {
+        // FIXME: To be implemented.
+    }
+
+    set usesLTRUserInterfaceLayoutDirection(flag)
+    {
+        // FIXME: To be implemented.
+    }
+
+    handleEvent(event)
+    {
+        if (event.type === "resize" && event.currentTarget === this.media)
+            this._updateControlsSize();
+    }
+
+    buttonWasClicked(button)
+    {
+        if (button !== this.controls.startButton)
+            return;
+
+        this.controls.showsStartButton = false;
+        this.media.play();
+    }
+
+    // Private
+
+    _updateControlsSize()
+    {
+        this.controls.width = this.media.offsetWidth;
+        this.controls.height = this.media.offsetHeight;
+    }
+
+}
index 8c81b50..8ef1b99 100644 (file)
                0F49669C1DB408C100A274BB /* DOMPointReadOnly.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DOMPointReadOnly.idl; sourceTree = "<group>"; };
                0F4966A11DB4090100A274BB /* DOMPointInit.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = DOMPointInit.idl; sourceTree = "<group>"; };
                0F4966A21DB4091000A274BB /* DOMPointInit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMPointInit.h; sourceTree = "<group>"; };
-               0F4966A41DB40C4300A274BB /* JSDOMPoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JSDOMPoint.cpp; path = JSDOMPoint.cpp; sourceTree = "<group>"; };
-               0F4966A51DB40C4300A274BB /* JSDOMPoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSDOMPoint.h; path = JSDOMPoint.h; sourceTree = "<group>"; };
-               0F4966A61DB40C4300A274BB /* JSDOMPointInit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JSDOMPointInit.cpp; path = JSDOMPointInit.cpp; sourceTree = "<group>"; };
-               0F4966A71DB40C4300A274BB /* JSDOMPointInit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSDOMPointInit.h; path = JSDOMPointInit.h; sourceTree = "<group>"; };
-               0F4966A81DB40C4300A274BB /* JSDOMPointReadOnly.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JSDOMPointReadOnly.cpp; path = JSDOMPointReadOnly.cpp; sourceTree = "<group>"; };
-               0F4966A91DB40C4300A274BB /* JSDOMPointReadOnly.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSDOMPointReadOnly.h; path = JSDOMPointReadOnly.h; sourceTree = "<group>"; };
+               0F4966A41DB40C4300A274BB /* JSDOMPoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMPoint.cpp; sourceTree = "<group>"; };
+               0F4966A51DB40C4300A274BB /* JSDOMPoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMPoint.h; sourceTree = "<group>"; };
+               0F4966A61DB40C4300A274BB /* JSDOMPointInit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMPointInit.cpp; sourceTree = "<group>"; };
+               0F4966A71DB40C4300A274BB /* JSDOMPointInit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMPointInit.h; sourceTree = "<group>"; };
+               0F4966A81DB40C4300A274BB /* JSDOMPointReadOnly.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMPointReadOnly.cpp; sourceTree = "<group>"; };
+               0F4966A91DB40C4300A274BB /* JSDOMPointReadOnly.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMPointReadOnly.h; sourceTree = "<group>"; };
                0F4E57161313276200CF85AF /* RenderSVGAllInOne.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSVGAllInOne.cpp; sourceTree = "<group>"; };
                0F54DCCC1880C6AB003EEDBB /* ios-encodings.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "ios-encodings.txt"; sourceTree = "<group>"; };
                0F54DCE31881051D003EEDBB /* TextAutoSizing.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextAutoSizing.cpp; sourceTree = "<group>"; };
                71B1E124164048CC00B1880A /* InspectorLayerTreeAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorLayerTreeAgent.h; sourceTree = "<group>"; };
                71C916071D1483A300ACA47D /* UserInterfaceLayoutDirection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserInterfaceLayoutDirection.h; sourceTree = "<group>"; };
                71CC7A1F152A0BFE009EEAF9 /* SVGAnimatedEnumeration.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGAnimatedEnumeration.cpp; sourceTree = "<group>"; };
+               71D02D901DB55C4E00DD5CF5 /* main.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = main.js; sourceTree = "<group>"; };
+               71D02D921DB55C4E00DD5CF5 /* media-controller.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = "media-controller.js"; sourceTree = "<group>"; };
                71D6AA711DA4EAF700B23969 /* airplay-placard@1x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "airplay-placard@1x.png"; sourceTree = "<group>"; };
                71D6AA721DA4EAF700B23969 /* airplay-placard@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "airplay-placard@2x.png"; sourceTree = "<group>"; };
                71D6AA731DA4EAF700B23969 /* airplay-placard@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "airplay-placard@3x.png"; sourceTree = "<group>"; };
                        path = "Modules/modern-media-controls/controls";
                        sourceTree = SOURCE_ROOT;
                };
+               71D02D911DB55C4E00DD5CF5 /* media */ = {
+                       isa = PBXGroup;
+                       children = (
+                               71D02D921DB55C4E00DD5CF5 /* media-controller.js */,
+                       );
+                       path = media;
+                       sourceTree = "<group>";
+               };
                71D6AA391DA4EAF700B23969 /* modern-media-controls */ = {
                        isa = PBXGroup;
                        children = (
+                               71D02D901DB55C4E00DD5CF5 /* main.js */,
                                716FA0D71DB26591007323CC /* controls */,
                                71D6AA6F1DA4EAF700B23969 /* images */,
+                               71D02D911DB55C4E00DD5CF5 /* media */,
                        );
                        path = "modern-media-controls";
                        sourceTree = "<group>";
index 7cb6a17..de54d85 100644 (file)
@@ -237,8 +237,8 @@ String RenderThemeMac::mediaControlsStyleSheet()
     if (m_mediaControlsStyleSheet.isEmpty()) {
         StringBuilder styleSheetBuilder;
         if (RuntimeEnabledFeatures::sharedFeatures().modernMediaControlsEnabled()) {
-            NSArraypaths = @[@"airplay-button", @"button", @"buttons-container", @"icon-button", @"macos-inline-media-controls", @"media-controls", @"placard", @"scrubber", @"slider", @"start-button", @"time-label", @"volume-slider"];
-            for (NSStringpath in paths)
+            NSArray *paths = @[@"airplay-button", @"button", @"buttons-container", @"icon-button", @"macos-inline-media-controls", @"media-controls", @"placard", @"scrubber", @"slider", @"start-button", @"time-label", @"volume-slider"];
+            for (NSString *path in paths)
                 styleSheetBuilder.append([NSString stringWithContentsOfFile:[[NSBundle bundleForClass:[WebCoreRenderThemeBundle class]] pathForResource:path ofType:@"css" inDirectory:@"modern-media-controls/controls"] encoding:NSUTF8StringEncoding error:nil]);
         } else
             styleSheetBuilder.append([NSString stringWithContentsOfFile:[[NSBundle bundleForClass:[WebCoreRenderThemeBundle class]] pathForResource:@"mediaControlsApple" ofType:@"css"] encoding:NSUTF8StringEncoding error:nil]);
@@ -255,11 +255,13 @@ String RenderThemeMac::mediaControlsScript()
 #if ENABLE(MEDIA_CONTROLS_SCRIPT)
     if (m_mediaControlsScript.isEmpty()) {
         StringBuilder scriptBuilder;
-        NSBundlebundle = [NSBundle bundleForClass:[WebCoreRenderThemeBundle class]];
+        NSBundle *bundle = [NSBundle bundleForClass:[WebCoreRenderThemeBundle class]];
         if (RuntimeEnabledFeatures::sharedFeatures().modernMediaControlsEnabled()) {
-            NSArraycontrolsPaths = @[@"scheduler", @"layout-node", @"layout-item", @"icon-service", @"time-control", @"time-label", @"slider", @"volume-slider", @"scrubber", @"button", @"start-button", @"icon-button", @"play-pause-button", @"skip-back-button", @"mute-button", @"airplay-button", @"pip-button", @"tracks-button", @"fullscreen-button", @"aspect-ratio-button", @"rewind-button", @"forward-button", @"media-controls", @"macos-media-controls", @"macos-inline-media-controls", @"buttons-container", @"placard", @"airplay-placard", @"pip-placard"];
-            for (NSStringpath in controlsPaths)
+            NSArray *controlsPaths = @[@"scheduler", @"layout-node", @"layout-item", @"icon-service", @"time-control", @"time-label", @"slider", @"volume-slider", @"scrubber", @"button", @"start-button", @"icon-button", @"play-pause-button", @"skip-back-button", @"mute-button", @"airplay-button", @"pip-button", @"tracks-button", @"fullscreen-button", @"aspect-ratio-button", @"rewind-button", @"forward-button", @"media-controls", @"macos-media-controls", @"macos-inline-media-controls", @"buttons-container", @"placard", @"airplay-placard", @"pip-placard"];
+            for (NSString *path in controlsPaths)
                 scriptBuilder.append([NSString stringWithContentsOfFile:[bundle pathForResource:path ofType:@"js" inDirectory:@"modern-media-controls/controls"] encoding:NSUTF8StringEncoding error:nil]);
+            scriptBuilder.append([NSString stringWithContentsOfFile:[bundle pathForResource:@"media-controller" ofType:@"js" inDirectory:@"modern-media-controls/media"] encoding:NSUTF8StringEncoding error:nil]);
+            scriptBuilder.append([NSString stringWithContentsOfFile:[bundle pathForResource:@"main" ofType:@"js" inDirectory:@"modern-media-controls"] encoding:NSUTF8StringEncoding error:nil]);
         } else {
             scriptBuilder.append([NSString stringWithContentsOfFile:[bundle pathForResource:@"mediaControlsLocalizedStrings" ofType:@"js"] encoding:NSUTF8StringEncoding error:nil]);
             scriptBuilder.append([NSString stringWithContentsOfFile:[bundle pathForResource:@"mediaControlsApple" ofType:@"js"] encoding:NSUTF8StringEncoding error:nil]);