Bug 1444489 - Part II, Replace touchControls with videoControls and remove touchControls r=Gijs

Also migrates TouchUtils to videoControls in order to keep some interactions.

Removed the casting button from TouchUtils (to be add back to Utils in the next
commit; not removing the SVG images for hg annotation)

MozReview-Commit-ID: DzhmjykCLzu

--HG--
extra : rebase_source : d77dfe3e2d9de2087d21dc2fb9b1773e710177d7
This commit is contained in:
Timothy Guan-tin Chien 2018-03-21 15:10:20 +08:00
Родитель de835f3700
Коммит 64808cfafc
18 изменённых файлов: 75 добавлений и 779 удалений

Просмотреть файл

@ -264,11 +264,6 @@ select:disabled > button {
padding-block-end: 1px; padding-block-end: 1px;
} }
/* -moz-touch-enabled? media elements */
:-moz-any(video, audio) > xul|videocontrols {
-moz-binding: url("chrome://global/content/bindings/videocontrols.xml#touchControls");
}
/* display click to play when autoplay is blocked for videos */ /* display click to play when autoplay is blocked for videos */
video:not([controls]) > xul|videocontrols { video:not([controls]) > xul|videocontrols {
visibility: visible; visibility: visible;

Просмотреть файл

@ -1,10 +0,0 @@
<?xml version="1.0"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g transform="translate(-276.000000, -1042.000000)" fill="#FFFFFF">
<g transform="translate(240.000000, 1006.000000)">
<path d="M36.96,80.16 C35.2060427,78.316034 35.8370453,76.8 38.4,76.8 L62.4,76.8 C65.0584079,76.8 67.2,78.9469741 67.2,81.6 L67.2,105.6 C67.2,108.165446 65.6848806,108.791856 63.84,107.04 L55.2,98.4 L49.92,104.16 C47.9768607,105.92543 44.9530217,105.908123 43.2,104.16 L39.84,100.8 C38.0648585,98.9095525 38.080377,95.8763717 39.84,94.08 L45.6,88.8 L36.96,80.16 Z M107.04,63.84 C108.79397,65.6843439 108.162544,67.2 105.6,67.2 L81.6,67.2 C78.941564,67.2 76.8,65.0529486 76.8,62.4 L76.8,38.4 C76.8,35.8334252 78.3157239,35.2076163 80.16,36.96 L88.8,45.6 L94.08,39.84 C95.909525,38.1209584 98.9004381,38.0799163 100.8,39.84 L104.16,43.2 C105.923072,45.1022004 105.884206,48.0879079 104.16,49.92 L98.4,55.2 L107.04,63.84 Z"></path>
</g>
</g>
</g>
</svg>

До

Ширина:  |  Высота:  |  Размер: 1.1 KiB

Просмотреть файл

@ -1,10 +0,0 @@
<?xml version="1.0"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g transform="translate(-84.000000, -1042.000000)" fill="#FFFFFF">
<g transform="translate(48.000000, 1006.000000)">
<path d="M77.1428571,36 L102.857143,36 C105.705437,36 108,38.3003294 108,41.1428571 L108,66.8571429 C108,69.6058346 106.376658,70.276989 104.4,68.4 L95.1428571,59.1428571 L89.4857143,65.3142857 C87.4037793,67.2058174 84.1639518,67.1872741 82.2857143,65.3142857 L78.6857143,61.7142857 C76.783777,59.6888062 76.8004039,56.4389697 78.6857143,54.5142857 L84.8571429,48.8571429 L75.6,39.6 C73.7207601,37.6243221 74.3968342,36 77.1428571,36 Z M66.8571429,108 L41.1428571,108 C38.2945329,108 36,105.699588 36,102.857143 L36,77.1428571 C36,74.3929556 37.6239899,73.7224461 39.6,75.6 L48.8571429,84.8571429 L54.5142857,78.6857143 C56.474491,76.843884 59.6790408,76.7999103 61.7142857,78.6857143 L65.3142857,82.2857143 C67.2032916,84.3237862 67.1616492,87.5227585 65.3142857,89.4857143 L59.1428571,95.1428571 L68.4,104.4 C70.279254,106.376083 69.6027253,108 66.8571429,108 Z"></path>
</g>
</g>
</g>
</svg>

До

Ширина:  |  Высота:  |  Размер: 1.3 KiB

Просмотреть файл

@ -1,10 +0,0 @@
<?xml version="1.0"?>
<svg width="70px" height="60px" viewBox="0 0 70 60" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g transform="translate(-469.000000, -1048.000000)" fill="#FFFFFF">
<g transform="translate(432.000000, 1006.000000)">
<path d="M98.3836922,53.1162172 C103.662239,57.6998888 107,64.4601112 107,71.9999094 C107,79.5397077 103.662239,86.2999301 98.3836922,90.8836016 L94.8371224,87.3370318 C99.2157236,83.6682614 102,78.1592367 102,71.9999094 C102,65.8405821 99.2157236,60.3315575 94.8371224,56.6627871 L98.3836922,53.1162172 Z M91.2831302,60.2167792 C94.7649686,62.9636534 97,67.2207716 97,71.9999094 C97,76.7790472 94.7649686,81.0361655 91.2831302,83.7830397 L87.7103386,80.210248 C90.3032555,78.4034792 92,75.3998422 92,71.9999094 C92,68.5999775 90.3032563,65.5963412 87.7103384,63.789571 L91.2831302,60.2167792 Z M37,61.9999094 C37,59.2105478 39.2364417,56.9712087 42,56.9999094 L58,56.9999094 L75.5,42.9999094 C79.1323004,40.818613 82,42.3919545 82,46.4999094 L82,97.4999094 C82,101.618951 79.1389004,103.178674 75.5,100.999909 L58,86.9999094 L42,86.9999094 C39.2362844,87.0258469 37,84.7863502 37,81.9999094 L37,61.9999094 Z"></path>
</g>
</g>
</g>
</svg>

До

Ширина:  |  Высота:  |  Размер: 1.3 KiB

Просмотреть файл

@ -1,10 +0,0 @@
<?xml version="1.0"?>
<svg width="54px" height="72px" viewBox="0 0 54 72" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g transform="translate(-285.000000, -1234.000000)" fill="#FFFFFF">
<g transform="translate(240.000000, 1198.000000)">
<path d="M63,103.5 C63,105.9849 60.9849,108 58.5,108 L49.5,108 C47.0151,108 45,105.9849 45,103.5 L45,40.5 C45,38.0151 47.0151,36 49.5,36 L58.5,36 C60.9849,36 63,38.0151 63,40.5 L63,103.5 Z M94.5,108 L85.5,108 C83.0151,108 81,105.9849 81,103.5 L81,40.5 C81,38.0151 83.0151,36 85.5,36 L94.5,36 C96.9849,36 99,38.0151 99,40.5 L99,103.5 C99,105.9849 96.9849,108 94.5,108 Z"></path>
</g>
</g>
</g>
</svg>

До

Ширина:  |  Высота:  |  Размер: 803 B

Просмотреть файл

@ -1,10 +0,0 @@
<?xml version="1.0"?>
<svg width="58px" height="72px" viewBox="0 0 58 72" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g transform="translate(-91.000000, -1234.000000)" fill="#FFFFFF">
<g transform="translate(48.000000, 1198.000000)">
<path d="M43,40 L43,104 C43,107.688656 45.5537886,109.093408 49,107 L99,75 C101.697423,73.3130096 101.692268,70.3534356 99,69 L49,37 C45.5596797,34.9042037 43,36.3212206 43,40 Z"></path>
</g>
</g>
</g>
</svg>

До

Ширина:  |  Высота:  |  Размер: 610 B

Просмотреть файл

@ -1,10 +0,0 @@
<?xml version="1.0"?>
<svg width="36px" height="36px" viewBox="0 0 36 36" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g transform="translate(-486.000000, -1444.000000)" fill="#FFFFFF">
<g transform="translate(432.000000, 1390.000000)">
<circle id="Oval-17" cx="72" cy="72" r="18"></circle>
</g>
</g>
</g>
</svg>

До

Ширина:  |  Высота:  |  Размер: 479 B

Просмотреть файл

@ -1,10 +0,0 @@
<?xml version="1.0"?>
<svg width="45px" height="60px" viewBox="0 0 45 60" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g transform="translate(-661.000000, -1048.000000)" fill="#FFFFFF">
<g transform="translate(624.000000, 1006.000000)">
<path d="M37,61.9999094 C37,59.2105478 39.2364417,56.9712087 42,56.9999094 L58,56.9999094 L75.5,42.9999094 C79.1323004,40.818613 82,42.3919545 82,46.4999094 L82,97.4999094 C82,101.618951 79.1389004,103.178674 75.5,100.999909 L58,86.9999094 L42,86.9999094 C39.2362844,87.0258469 37,84.7863502 37,81.9999094 L37,61.9999094 Z"></path>
</g>
</g>
</g>
</svg>

До

Ширина:  |  Высота:  |  Размер: 757 B

Просмотреть файл

@ -9,7 +9,6 @@ geckoview.jar:
skin/content.css (content.css) skin/content.css (content.css)
skin/defines.css (defines.css) skin/defines.css (defines.css)
skin/scrollbar.css (scrollbar-apz.css) skin/scrollbar.css (scrollbar-apz.css)
skin/videocontrols.css (videocontrols.css)
skin/images/accessiblecaret-normal-hdpi.png (images/accessiblecaret-normal-hdpi.png) skin/images/accessiblecaret-normal-hdpi.png (images/accessiblecaret-normal-hdpi.png)
skin/images/accessiblecaret-normal-xhdpi.png (images/accessiblecaret-normal-xhdpi.png) skin/images/accessiblecaret-normal-xhdpi.png (images/accessiblecaret-normal-xhdpi.png)
@ -22,14 +21,3 @@ geckoview.jar:
skin/images/accessiblecaret-tilt-right-xxhdpi.png (images/accessiblecaret-tilt-right-xxhdpi.png) skin/images/accessiblecaret-tilt-right-xxhdpi.png (images/accessiblecaret-tilt-right-xxhdpi.png)
skin/images/dropmarker.svg (images/dropmarker.svg) skin/images/dropmarker.svg (images/dropmarker.svg)
skin/images/dropmarker-right.svg (images/dropmarker-right.svg) skin/images/dropmarker-right.svg (images/dropmarker-right.svg)
skin/images/videocontrols-cast-ready.svg (images/videocontrols-cast-ready.svg)
skin/images/videocontrols-cast-active.svg (images/videocontrols-cast-active.svg)
skin/images/videocontrols-exitfullscreen.svg (images/videocontrols-exitfullscreen.svg)
skin/images/videocontrols-fullscreen.svg (images/videocontrols-fullscreen.svg)
skin/images/videocontrols-mute.svg (images/videocontrols-mute.svg)
skin/images/videocontrols-play.svg (images/videocontrols-play.svg)
skin/images/videocontrols-pause.svg (images/videocontrols-pause.svg)
skin/images/videocontrols-scrubber.svg (images/videocontrols-scrubber.svg)
skin/images/videocontrols-unmute.svg (images/videocontrols-unmute.svg)
% override chrome://global/skin/media/videocontrols.css chrome://geckoview/skin/videocontrols.css

Просмотреть файл

@ -1,251 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@namespace url(http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul);
/* video controls */
.controlsOverlay {
-moz-box-pack: center;
-moz-box-align: end;
-moz-box-flex: 1;
-moz-box-orient: horizontal;
}
.controlsOverlay[scaled] {
/* scaled attribute in videocontrols.css causes conflict
due to different -moz-box-orient values */
-moz-box-align: end;
}
.controlsSpacer {
display: none;
-moz-box-flex: 0;
}
.controlBar {
-moz-box-flex: 1;
width: 100%;
background-color: rgba(50,50,50,0.8);
}
.buttonsBar {
-moz-box-flex: 1;
-moz-box-align: center;
}
.playButton,
.castingButton,
.muteButton,
.fullscreenButton {
-moz-appearance: none;
padding: 15px;
border: none !important;
width: 48px;
height: 48px;
}
.playButton {
background: url("chrome://geckoview/skin/images/videocontrols-pause.svg") no-repeat center;
background-size: contain;
background-origin: content-box;
}
.playButton[paused="true"] {
background: url("chrome://geckoview/skin/images/videocontrols-play.svg") no-repeat center;
background-size: contain;
background-origin: content-box;
}
.castingButton {
background: url("chrome://geckoview/skin/images/videocontrols-cast-ready.svg") no-repeat center;
background-size: contain;
background-origin: content-box;
}
.castingButton[active="true"] {
background: url("chrome://geckoview/skin/images/videocontrols-cast-active.svg") no-repeat center;
background-size: contain;
background-origin: content-box;
}
/* If the casting button is showing, there will be two buttons on the right side of the controls.
* This shifts the play button to be centered.
*/
.castingButton:not([hidden="true"]) + .fullscreenButton + spacer + .playButton {
transform: translateX(-21px);
}
.muteButton {
padding-left: 17.25px;
padding-right: 9.75px;
background: url("chrome://geckoview/skin/images/videocontrols-mute.svg") no-repeat left;
background-size: contain;
background-origin: content-box;
}
.muteButton[muted="true"] {
background: url("chrome://geckoview/skin/images/videocontrols-unmute.svg") no-repeat left;
background-size: contain;
background-origin: content-box;
}
.fullscreenButton {
background-color: transparent;
background: url("chrome://geckoview/skin/images/videocontrols-fullscreen.svg") no-repeat center;
background-size: contain;
background-origin: content-box;
}
.fullscreenButton[fullscreened] {
background: url("chrome://geckoview/skin/images/videocontrols-exitfullscreen.svg") no-repeat center;
background-size: contain;
background-origin: content-box;
}
.controlBar[fullscreen-unavailable] .fullscreenButton {
display: none;
}
/* bars */
.scrubberStack {
-moz-box-flex: 1;
padding: 0px 18px;
}
.flexibleBar,
.flexibleBar .progress-bar,
.bufferBar,
.bufferBar .progress-bar,
.progressBar,
.progressBar .progress-bar,
.scrubber,
.scrubber .scale-slider,
.scrubber .scale-thumb {
-moz-appearance: none;
border: none;
padding: 0px;
margin: 0px;
background-color: transparent;
}
.flexibleBar,
.bufferBar,
.progressBar {
height: 32px;
padding: 15px 0px;
}
.flexibleBar {
padding: 16px 0px;
}
.flexibleBar .progress-bar {
border: 1px #777777 solid;
border-radius: 1px;
}
.bufferBar .progress-bar {
border: 2px #AFB1B3 solid;
border-radius: 2px;
}
.progressBar .progress-bar {
border: 2px #0A84FF solid;
border-radius: 2px;
}
.scrubber {
margin-left: -12px;
margin-right: -12px;
}
.scrubber .scale-thumb {
display: -moz-box;
margin: 0px !important;
padding: 0px !important;
background: url("chrome://geckoview/skin/images/videocontrols-scrubber.svg") no-repeat center;
background-size: 12px 12px;
height: 32px;
width: 32px;
}
.positionLabel, .durationLabel {
font-family: 'Roboto', Helvetica, Arial, sans-serif;
font-size: 16px;
color: white;
}
.statusOverlay[error] {
-moz-box-align: center;
-moz-box-pack: center;
background-color: rgb(50,50,50);
}
.statusIcon {
margin-bottom: 28px;
width: 36px;
height: 36px;
}
.statusIcon[type="error"] {
background: url(chrome://global/skin/media/error.png) no-repeat center;
}
/* CSS Transitions */
.controlBar:not([immediate]) {
transition-property: opacity;
transition-duration: 200ms;
}
.controlBar[fadeout] {
opacity: 0;
}
.statusOverlay:not([immediate]) {
transition-property: opacity;
transition-duration: 300ms;
transition-delay: 750ms;
}
.statusOverlay[fadeout] {
opacity: 0;
}
.volumeStack,
.timeLabel {
display: none;
}
.controlBar[firstshow="true"] .playButton {
-moz-transform: none;
}
/* Error description formatting */
.errorLabel {
font-family: Helvetica, Arial, sans-serif;
font-size: 11px;
color: #bbb;
text-shadow:
-1px -1px 0 #000,
1px -1px 0 #000,
-1px 1px 0 #000,
1px 1px 0 #000;
padding: 0 10px;
text-align: center;
}
/* Overlay Play button */
.clickToPlay {
width: 64px;
height: 64px;
-moz-box-pack: center;
-moz-box-align: center;
opacity: 0.7;
background-image: url(chrome://global/skin/media/clicktoplay-bgtexture.png),
url(chrome://global/skin/media/videoClickToPlayButton.svg);
background-repeat: repeat, no-repeat;
background-position: center, center;
background-size: auto, 64px 64px;
background-color: hsla(0,0%,10%,.5);
}

Просмотреть файл

@ -105,7 +105,6 @@ toolkit.jar:
content/global/bindings/toolbarbutton.xml (widgets/toolbarbutton.xml) content/global/bindings/toolbarbutton.xml (widgets/toolbarbutton.xml)
* content/global/bindings/tree.xml (widgets/tree.xml) * content/global/bindings/tree.xml (widgets/tree.xml)
content/global/bindings/videocontrols.xml (widgets/videocontrols.xml) content/global/bindings/videocontrols.xml (widgets/videocontrols.xml)
content/global/bindings/videocontrols.css (widgets/videocontrols.css)
* content/global/bindings/wizard.xml (widgets/wizard.xml) * content/global/bindings/wizard.xml (widgets/wizard.xml)
#ifdef XP_MACOSX #ifdef XP_MACOSX
content/global/macWindowMenu.js content/global/macWindowMenu.js

Просмотреть файл

@ -23,7 +23,6 @@ support-files =
videomask.css videomask.css
[test_audiocontrols_dimensions.html] [test_audiocontrols_dimensions.html]
skip-if = toolkit == 'android'
[test_mousecapture_area.html] [test_mousecapture_area.html]
[test_videocontrols.html] [test_videocontrols.html]
tags = fullscreen tags = fullscreen
@ -31,10 +30,8 @@ skip-if = toolkit == 'android' #TIMED_OUT
[test_videocontrols_keyhandler.html] [test_videocontrols_keyhandler.html]
skip-if = toolkit == 'android' skip-if = toolkit == 'android'
[test_videocontrols_vtt.html] [test_videocontrols_vtt.html]
skip-if = toolkit == 'android'
[test_videocontrols_iframe_fullscreen.html] [test_videocontrols_iframe_fullscreen.html]
[test_videocontrols_size.html] [test_videocontrols_size.html]
skip-if = toolkit == 'android'
[test_videocontrols_audio.html] [test_videocontrols_audio.html]
[test_videocontrols_audio_direction.html] [test_videocontrols_audio_direction.html]
[test_videocontrols_jsdisabled.html] [test_videocontrols_jsdisabled.html]
@ -44,9 +41,7 @@ skip-if = toolkit == 'android' # bug 1075573
[test_videocontrols_video_direction.html] [test_videocontrols_video_direction.html]
skip-if = os == 'win' skip-if = os == 'win'
[test_videocontrols_video_noaudio.html] [test_videocontrols_video_noaudio.html]
skip-if = toolkit == 'android'
[test_bug1319301.html] [test_bug1319301.html]
skip-if = toolkit == 'android'
[test_bug898940.html] [test_bug898940.html]
[test_videocontrols_error.html] [test_videocontrols_error.html]
[test_videocontrols_orientation.html] [test_videocontrols_orientation.html]

Просмотреть файл

@ -32,7 +32,11 @@
video.addEventListener("loadedmetadata", () => SimpleTest.executeSoon(resolve)); video.addEventListener("loadedmetadata", () => SimpleTest.executeSoon(resolve));
}); });
ok(statusOverlay.hidden, "statusOverlay shoud not present without error"); // Wait for the fade out transition to complete in case the throbber
// shows up on slower platforms.
await SimpleTest.promiseWaitForCondition(() => statusOverlay.hidden,
"statusOverlay should not present without error");
ok(!statusOverlay.hasAttribute("error"), "statusOverlay should not in error state"); ok(!statusOverlay.hasAttribute("error"), "statusOverlay should not in error state");
isnot(statusIcon.getAttribute("type"), "error", "should not show error icon"); isnot(statusIcon.getAttribute("type"), "error", "should not show error icon");
}); });

Просмотреть файл

@ -1,79 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
@namespace html url("http://www.w3.org/1999/xhtml");
.scrubber,
.volumeControl {
-moz-binding: url("chrome://global/content/bindings/videocontrols.xml#suppressChangeEvent");
}
.playButton,
.muteButton,
.scrubber .scale-slider,
.volumeControl .scale-slider {
-moz-user-focus: none;
}
.controlBar[fullscreen-unavailable] > .fullscreenButton {
display: none;
}
.mediaControlsFrame {
direction: ltr;
/* Prevent unwanted style inheritance. See bug 554717. */
text-align: left;
list-style-image: none !important;
font: normal normal normal 100%/normal sans-serif !important;
text-decoration: none !important;
}
.controlsOverlay[scaled] {
-moz-box-align: center;
}
/* CSS Transitions
*
* These are overriden by the default theme; the rules here just
* provide a fallback to drive the required transitionend event
* (in case a 3rd party theme does not provide transitions).
*/
.controlBar:not([immediate]) {
transition-property: opacity;
transition-duration: 1ms;
}
.controlBar[fadeout] {
opacity: 0;
}
.volumeStack:not([immediate]) {
transition-property: opacity, margin-top;
transition-duration: 1ms, 1ms;
}
.volumeStack[fadeout] {
opacity: 0;
margin-top: 0;
}
.statusOverlay:not([immediate]) {
transition-property: opacity;
transition-duration: 1ms;
transition-delay: 750ms;
}
.statusOverlay[fadeout] {
opacity: 0;
}
/* Error description formatting */
.errorLabel {
display: none;
}
[error="errorAborted"] > [anonid="errorAborted"],
[error="errorNetwork"] > [anonid="errorNetwork"],
[error="errorDecode"] > [anonid="errorDecode"],
[error="errorSrcNotSupported"] > [anonid="errorSrcNotSupported"],
[error="errorNoSource"] > [anonid="errorNoSource"],
[error="errorGeneric"] > [anonid="errorGeneric"] {
display: inline;
}

Просмотреть файл

@ -15,122 +15,12 @@
xmlns:svg="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"
xmlns:html="http://www.w3.org/1999/xhtml"> xmlns:html="http://www.w3.org/1999/xhtml">
<binding id="suppressChangeEvent"
extends="chrome://global/content/bindings/scale.xml#scale">
<implementation implements="nsIXBLAccessible">
<!-- nsIXBLAccessible -->
<property name="accessibleName" readonly="true">
<getter>
var currTime = this.positionValue;
var totalTime = this.durationValue;
return this.scrubberNameFormat
.replace(/#1/, currTime)
.replace(/#2/, totalTime);
</getter>
</property>
<constructor>
<![CDATA[
/* eslint-disable no-multi-spaces */
this.scrubberNameFormat = ]]>"&scrubberScale.nameFormat;"<![CDATA[;
/* eslint-enable no-multi-spaces */
this.positionValue = "";
this.durationValue = "";
this.valueBar = null;
this.isDragging = false;
this.isPausedByDragging = false;
this.type = this.getAttribute("class");
this.Utils = document.getBindingParent(this.parentNode).Utils;
this.valueBar = this.Utils.progressBar;
]]>
</constructor>
<method name="valueChanged">
<parameter name="which"/>
<parameter name="newValue"/>
<parameter name="userChanged"/>
<body>
<![CDATA[
// This method is a copy of the base binding's valueChanged(), except that it does
// not dispatch a |change| event (to avoid exposing the event to web content), and
// just calls the videocontrol's seekToPosition() method directly.
switch (which) {
case "curpos":
// Update the time shown in the thumb.
this.positionValue = this.Utils.formatTime(newValue, this.Utils.showHours);
this.Utils.positionLabel.setAttribute("value", this.positionValue);
// Update the value bar to match the thumb position.
let percent = newValue / this.max;
if (!isNaN(percent) && percent != Infinity) {
this.valueBar.value = Math.round(percent * 10000); // has max=10000
} else {
this.valueBar.removeAttribute("value");
}
// The value of userChanged is true when changing the position with the mouse,
// but not when pressing an arrow key. However, the base binding sets
// ._userChanged in its keypress handlers, so we just need to check both.
if (!userChanged && !this._userChanged) {
return;
}
this.setAttribute("value", newValue);
this.Utils.seekToPosition(newValue);
break;
case "minpos":
this.setAttribute("min", newValue);
break;
case "maxpos":
// Update the value bar to match the thumb position.
this.valueBar.value = Math.round(this.value / newValue * 10000); // has max=10000
this.setAttribute("max", newValue);
break;
}
]]>
</body>
</method>
<method name="dragStateChanged">
<parameter name="isDragging"/>
<body>
<![CDATA[
this.Utils.log("--- dragStateChanged: " + isDragging + " ---");
this.isDragging = isDragging;
if (this.isPausedByDragging && !isDragging) {
// After the drag ends, resume playing.
this.Utils.video.play();
this.isPausedByDragging = false;
}
]]>
</body>
</method>
<method name="pauseVideoDuringDragging">
<body>
<![CDATA[
if (this.isDragging &&
!this.Utils.video.paused && !this.isPausedByDragging) {
this.isPausedByDragging = true;
this.Utils.video.pause();
}
]]>
</body>
</method>
</implementation>
</binding>
<binding id="videoControls"> <binding id="videoControls">
<resources> <resources>
<stylesheet src="chrome://global/content/bindings/videocontrols.css"/>
<stylesheet src="chrome://global/skin/media/videocontrols.css"/> <stylesheet src="chrome://global/skin/media/videocontrols.css"/>
</resources> </resources>
<xbl:content xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" <xbl:content xmlns="http://www.w3.org/1999/xhtml" class="mediaControlsFrame">
xmlns="http://www.w3.org/1999/xhtml" class="mediaControlsFrame">
<div anonid="controlsContainer" class="controlsContainer" role="none"> <div anonid="controlsContainer" class="controlsContainer" role="none">
<div anonid="statusOverlay" class="statusOverlay stackItem" hidden="true"> <div anonid="statusOverlay" class="statusOverlay stackItem" hidden="true">
<div anonid="statusIcon" class="statusIcon"></div> <div anonid="statusIcon" class="statusIcon"></div>
@ -191,7 +81,6 @@
<constructor> <constructor>
<![CDATA[ <![CDATA[
this.isTouchControls = false;
this.randomID = 0; this.randomID = 0;
this.Utils = { this.Utils = {
@ -807,10 +696,6 @@
}, },
initPositionDurationBox() { initPositionDurationBox() {
if (this.videocontrols.isTouchControls) {
return;
}
const positionTextNode = Array.prototype.find.call( const positionTextNode = Array.prototype.find.call(
this.positionDurationBox.childNodes, (n) => !!~n.textContent.search("#1")); this.positionDurationBox.childNodes, (n) => !!~n.textContent.search("#1"));
const durationSpan = this.durationSpan; const durationSpan = this.durationSpan;
@ -851,15 +736,11 @@
// Format the duration as "h:mm:ss" or "m:ss" // Format the duration as "h:mm:ss" or "m:ss"
let timeString = isInfinite ? "" : this.formatTime(duration); let timeString = isInfinite ? "" : this.formatTime(duration);
if (this.videocontrols.isTouchControls) { this.positionDurationBox.duration = timeString;
this.durationLabel.setAttribute("value", timeString);
} else {
this.positionDurationBox.duration = timeString;
if (this.showHours) { if (this.showHours) {
this.positionDurationBox.modifier = "long"; this.positionDurationBox.modifier = "long";
this.durationSpan.modifier = "long"; this.durationSpan.modifier = "long";
}
} }
// "durationValue" property is used by scale binding to // "durationValue" property is used by scale binding to
@ -903,10 +784,6 @@
}, },
updateScrubberProgress() { updateScrubberProgress() {
if (this.videocontrols.isTouchControls) {
return;
}
const positionPercent = this.scrubber.value / this.scrubber.max * 100; const positionPercent = this.scrubber.value / this.scrubber.max * 100;
if (!isNaN(positionPercent) && positionPercent != Infinity) { if (!isNaN(positionPercent) && positionPercent != Infinity) {
@ -942,12 +819,8 @@
let positionTime = this.formatTime(currentTime, this.showHours); let positionTime = this.formatTime(currentTime, this.showHours);
this.scrubber.value = currentTime; this.scrubber.value = currentTime;
if (this.videocontrols.isTouchControls) { this.positionDurationBox.position = positionTime;
this.positionLabel.setAttribute("value", positionTime); this.updateScrubberProgress();
} else {
this.positionDurationBox.position = positionTime;
this.updateScrubberProgress();
}
}, },
showBuffered() { showBuffered() {
@ -1110,11 +983,7 @@
// so our dependent state (eg, timestamp in the thumb) will be stale. // so our dependent state (eg, timestamp in the thumb) will be stale.
// As a workaround, update it manually when it first becomes unhidden. // As a workaround, update it manually when it first becomes unhidden.
if (element.hidden) { if (element.hidden) {
if (this.videocontrols.isTouchControls) { this.scrubber.value = this.video.currentTime * 1000;
this.scrubber.valueChanged("curpos", this.video.currentTime * 1000, false);
} else {
this.scrubber.value = this.video.currentTime * 1000;
}
} }
} }
@ -1158,9 +1027,6 @@
return; return;
} }
if (this.videocontrols.isTouchControls) {
this.scrubber.dragStateChanged(false);
}
element.hidden = true; element.hidden = true;
}, },
@ -1470,7 +1336,7 @@
}, },
get isClosedCaptionAvailable() { get isClosedCaptionAvailable() {
return this.overlayableTextTracks.length && !this.videocontrols.isTouchControls; return this.overlayableTextTracks.length;
}, },
get overlayableTextTracks() { get overlayableTextTracks() {
@ -1652,10 +1518,6 @@
controlBarMinHeight: 40, controlBarMinHeight: 40,
controlBarMinVisibleHeight: 28, controlBarMinVisibleHeight: 28,
adjustControlSize() { adjustControlSize() {
if (this.videocontrols.isTouchControls) {
return;
}
const minControlBarPaddingWidth = 18; const minControlBarPaddingWidth = 18;
this.fullscreenButton.isWanted = !this.controlBar.hasAttribute("fullscreen-unavailable"); this.fullscreenButton.isWanted = !this.controlBar.hasAttribute("fullscreen-unavailable");
@ -1793,10 +1655,8 @@
this.volumeStack this.volumeStack
]; ];
// XXX controlsContainer is a desktop only element. To determine whether this.videocontrols.isTouchControls =
// isTouchControls or not during the whole initialization process, get navigator.appVersion.includes("Android");
// this state overridden here.
this.videocontrols.isTouchControls = !this.controlsContainer;
this.isAudioOnly = (this.video instanceof HTMLAudioElement); this.isAudioOnly = (this.video instanceof HTMLAudioElement);
this.setupInitialState(); this.setupInitialState();
this.setupNewLoadState(); this.setupNewLoadState();
@ -1837,8 +1697,13 @@
addListener(this.fullscreenButton, "click", this.toggleFullscreen); addListener(this.fullscreenButton, "click", this.toggleFullscreen);
addListener(this.playButton, "click", this.clickToPlayClickHandler); addListener(this.playButton, "click", this.clickToPlayClickHandler);
addListener(this.clickToPlay, "click", this.clickToPlayClickHandler); addListener(this.clickToPlay, "click", this.clickToPlayClickHandler);
addListener(this.controlsSpacer, "click", this.clickToPlayClickHandler);
addListener(this.controlsSpacer, "dblclick", this.toggleFullscreen); // On touch videocontrols, tapping controlsSpacer should show/hide
// the control bar, instead of playing the video or toggle fullscreen.
if (!this.videocontrols.isTouchControls) {
addListener(this.controlsSpacer, "click", this.clickToPlayClickHandler);
addListener(this.controlsSpacer, "dblclick", this.toggleFullscreen);
}
addListener(this.videocontrols, "resizevideocontrols", this.adjustControlSize); addListener(this.videocontrols, "resizevideocontrols", this.adjustControlSize);
addListener(this.videocontrols, "transitionend", this.onTransitionEnd); addListener(this.videocontrols, "transitionend", this.onTransitionEnd);
@ -1854,126 +1719,25 @@
event.preventDefault(); // prevent dragging of controls image (bug 517114) event.preventDefault(); // prevent dragging of controls image (bug 517114)
}); });
if (!this.videocontrols.isTouchControls) { addListener(this.scrubber, "input", this.onScrubberInput);
addListener(this.scrubber, "input", this.onScrubberInput); addListener(this.scrubber, "change", this.onScrubberChange);
addListener(this.scrubber, "change", this.onScrubberChange); // add mouseup listener additionally to handle the case that `change` event
// add mouseup listener additionally to handle the case that `change` event // isn't fired when the input value before/after dragging are the same. (bug 1328061)
// isn't fired when the input value before/after dragging are the same. (bug 1328061) addListener(this.scrubber, "mouseup", this.onScrubberChange);
addListener(this.scrubber, "mouseup", this.onScrubberChange); addListener(this.volumeControl, "input", this.updateVolume);
addListener(this.volumeControl, "input", this.updateVolume); addListener(this.video.textTracks, "addtrack", this.onTextTrackAdd);
addListener(this.video.textTracks, "addtrack", this.onTextTrackAdd); addListener(this.video.textTracks, "removetrack", this.onTextTrackRemove);
addListener(this.video.textTracks, "removetrack", this.onTextTrackRemove); addListener(this.video.textTracks, "change", this.setClosedCaptionButtonState);
addListener(this.video.textTracks, "change", this.setClosedCaptionButtonState);
}
this.log("--- videocontrols initialized ---"); this.log("--- videocontrols initialized ---");
} }
}; };
this.Utils.init(this);
]]>
</constructor>
<destructor>
<![CDATA[
this.Utils.terminateEventListeners();
this.Utils.updateOrientationState(false);
// randomID used to be a <field>, which meant that the XBL machinery
// undefined the property when the element was unbound. The code in
// this file actually depends on this, so now that randomID is an
// expando, we need to make sure to explicitly delete it.
delete this.randomID;
]]>
</destructor>
</implementation>
<handlers>
<handler event="mouseover">
if (!this.isTouchControls) {
this.Utils.onMouseInOut(event);
}
</handler>
<handler event="mouseout">
if (!this.isTouchControls) {
this.Utils.onMouseInOut(event);
}
</handler>
<handler event="mousemove">
if (!this.isTouchControls) {
this.Utils.onMouseMove(event);
}
</handler>
</handlers>
</binding>
<binding id="touchControls" extends="chrome://global/content/bindings/videocontrols.xml#videoControls">
<xbl:content xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" class="mediaControlsFrame">
<stack flex="1">
<vbox anonid="statusOverlay" flex="1" class="statusOverlay" hidden="true">
<box anonid="statusIcon" class="statusIcon"/>
<label class="errorLabel" anonid="errorAborted">&error.aborted;</label>
<label class="errorLabel" anonid="errorNetwork">&error.network;</label>
<label class="errorLabel" anonid="errorDecode">&error.decode;</label>
<label class="errorLabel" anonid="errorSrcNotSupported">&error.srcNotSupported;</label>
<label class="errorLabel" anonid="errorNoSource">&error.noSource2;</label>
<label class="errorLabel" anonid="errorGeneric">&error.generic;</label>
</vbox>
<vbox anonid="controlsOverlay" class="controlsOverlay">
<spacer anonid="controlsSpacer" class="controlsSpacer" flex="1"/>
<box flex="1" hidden="true">
<box anonid="clickToPlay" class="clickToPlay" hidden="true" flex="1"/>
<vbox anonid="textTrackList" class="textTrackList" hidden="true" offlabel="&closedCaption.off;"></vbox>
</box>
<vbox anonid="controlBar" class="controlBar" hidden="true">
<hbox class="buttonsBar">
<button anonid="playButton"
class="playButton"
playlabel="&playButton.playLabel;"
pauselabel="&playButton.pauseLabel;"/>
<label anonid="positionLabel" class="positionLabel" role="presentation"/>
<stack anonid="scrubberStack" class="scrubberStack">
<box class="backgroundBar"/>
<progressmeter class="flexibleBar" value="100"/>
<progressmeter anonid="bufferBar" class="bufferBar"/>
<progressmeter anonid="progressBar" class="progressBar" max="10000"/>
<scale anonid="scrubber" class="scrubber" movetoclick="true"/>
</stack>
<label anonid="durationLabel" class="durationLabel" role="presentation"/>
<button anonid="muteButton"
class="muteButton"
mutelabel="&muteButton.muteLabel;"
unmutelabel="&muteButton.unmuteLabel;"/>
<stack anonid="volumeStack" class="volumeStack">
<box anonid="volumeBackground" class="volumeBackground"/>
<box anonid="volumeForeground" class="volumeForeground"/>
<scale anonid="volumeControl" class="volumeControl" movetoclick="true"/>
</stack>
<button anonid="castingButton" class="castingButton" hidden="true"
aria-label="&castingButton.castingLabel;"/>
<button anonid="closedCaptionButton" class="closedCaptionButton" hidden="true"/>
<button anonid="fullscreenButton"
class="fullscreenButton"
enterfullscreenlabel="&fullscreenButton.enterfullscreenlabel;"
exitfullscreenlabel="&fullscreenButton.exitfullscreenlabel;"/>
</hbox>
</vbox>
</vbox>
</stack>
</xbl:content>
<implementation>
<constructor>
<![CDATA[
this.isTouchControls = true;
this.TouchUtils = { this.TouchUtils = {
videocontrols: null, videocontrols: null,
video: null, video: null,
controlsTimer: null, controlsTimer: null,
controlsTimeout: 5000, controlsTimeout: 5000,
positionLabel: null,
castingButton: null,
get Utils() { get Utils() {
return this.videocontrols.Utils; return this.videocontrols.Utils;
@ -2053,47 +1817,12 @@
} }
}, },
isVideoCasting() {
return this.video.mozIsCasting;
},
updateCasting(eventDetail) {
let castingData = JSON.parse(eventDetail);
if ("allow" in castingData) {
this.video.mozAllowCasting = !!castingData.allow;
}
if ("active" in castingData) {
this.video.mozIsCasting = !!castingData.active;
}
this.setCastButtonState();
},
startCasting() {
this.videocontrols.dispatchEvent(new CustomEvent("VideoBindingCast"));
},
setCastButtonState() {
if (this.isAudioOnly || !this.video.mozAllowCasting) {
this.castingButton.hidden = true;
return;
}
if (this.video.mozIsCasting) {
this.castingButton.setAttribute("active", "true");
} else {
this.castingButton.removeAttribute("active");
}
this.castingButton.hidden = false;
},
init(binding) { init(binding) {
this.videocontrols = binding; this.videocontrols = binding;
this.video = binding.parentNode; this.video = binding.parentNode;
let self = this; let self = this;
this.Utils.playButton.addEventListener("command", function() { this.Utils.playButton.addEventListener("click", function() {
if (!self.video.paused) { if (!self.video.paused) {
self.delayHideControls(0); self.delayHideControls(0);
} else { } else {
@ -2108,17 +1837,14 @@
}); });
this.Utils.muteButton.addEventListener("click", function() { self.delayHideControls(self.controlsTimeout); }); this.Utils.muteButton.addEventListener("click", function() { self.delayHideControls(self.controlsTimeout); });
this.castingButton = document.getAnonymousElementByAttribute(binding, "anonid", "castingButton"); this.Utils.controlsSpacer.addEventListener("mouseup", function(event) {
this.castingButton.addEventListener("command", function() { if (event.originalTarget == self.Utils.controlsSpacer) {
self.startCasting(); if (self.firstShow) {
}); self.Utils.video.play();
}
this.video.addEventListener("media-videoCasting", function(e) { self.toggleControls();
if (!e.isTrusted) {
return;
} }
self.updateCasting(e.detail); });
}, false, true);
// The first time the controls appear we want to just display // The first time the controls appear we want to just display
// a play button that does not fade away. The firstShow property // a play button that does not fade away. The firstShow property
@ -2141,14 +1867,21 @@
} }
}; };
this.TouchUtils.init(this); this.Utils.init(this);
if (this.isTouchControls) {
this.TouchUtils.init(this);
}
this.dispatchEvent(new CustomEvent("VideoBindingAttached")); this.dispatchEvent(new CustomEvent("VideoBindingAttached"));
]]> ]]>
</constructor> </constructor>
<destructor> <destructor>
<![CDATA[ <![CDATA[
// XBL destructors don't appear to be inherited properly, so we need this.Utils.terminateEventListeners();
// to do this here in addition to the videoControls destructor. :-( this.Utils.updateOrientationState(false);
// randomID used to be a <field>, which meant that the XBL machinery
// undefined the property when the element was unbound. The code in
// this file actually depends on this, so now that randomID is an
// expando, we need to make sure to explicitly delete it.
delete this.randomID; delete this.randomID;
]]> ]]>
</destructor> </destructor>
@ -2156,22 +1889,28 @@
</implementation> </implementation>
<handlers> <handlers>
<handler event="mouseup"> <handler event="mouseover">
if (event.originalTarget.nodeName == "vbox") { if (!this.isTouchControls) {
if (this.TouchUtils.firstShow) { this.Utils.onMouseInOut(event);
this.Utils.video.play(); }
} </handler>
this.TouchUtils.toggleControls(); <handler event="mouseout">
if (!this.isTouchControls) {
this.Utils.onMouseInOut(event);
}
</handler>
<handler event="mousemove">
if (!this.isTouchControls) {
this.Utils.onMouseMove(event);
} }
</handler> </handler>
</handlers> </handlers>
</binding> </binding>
<binding id="noControls"> <binding id="noControls">
<resources> <resources>
<stylesheet src="chrome://global/skin/media/videocontrols-html.css"/> <stylesheet src="chrome://global/skin/media/videocontrols.css"/>
</resources> </resources>
<xbl:content xmlns="http://www.w3.org/1999/xhtml" class="mediaControlsFrame"> <xbl:content xmlns="http://www.w3.org/1999/xhtml" class="mediaControlsFrame">

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 481 B

Просмотреть файл

@ -1,30 +0,0 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMinYMin meet" viewBox="0 0 64 64">
<defs>
<linearGradient id="whiteGradientStops">
<stop style="stop-color:#fff;stop-opacity:.95" offset="0"/>
<stop style="stop-color:#fff;stop-opacity:.75" offset=".45"/>
<stop style="stop-color:#fff;stop-opacity:.72" offset=".55"/>
<stop style="stop-color:#fff;stop-opacity:.65" offset="1"/>
</linearGradient>
<linearGradient x1="32" y1="0" x2="32" y2="62" id="whiteGradient" xlink:href="#whiteGradientStops" gradientUnits="userSpaceOnUse"/>
<linearGradient id="arrowGradientStops">
<stop style="stop-color:#333;stop-opacity:.5" offset="0"/>
<stop style="stop-color:#666;stop-opacity:.5" offset="1"/>
</linearGradient>
<linearGradient x1="32" y1="16" x2="32" y2="48" id="arrowGradient" xlink:href="#arrowGradientStops" gradientUnits="userSpaceOnUse"/>
<filter x="-0.15" y="-0.15" width="1.25" height="1.25" color-interpolation-filters="sRGB" id="dropShadow">
<feDropShadow dx="0" dy="1" flood-opacity="0.5"/>
</filter>
<mask id="dropShadowMask">
<path style="fill:#fff;" d="M47.285,30.991L23.75,17.24c-0.357-0.208-0.692-0.278-0.969-0.221 C22.32,17.115,22,17.555,22,18.252v27.499c0,1.112,0.797,1.568,1.75,1.011l23.535-13.748C48.238,32.458,48.238,31.547,47.285,30.991 z M0,0v64h64V0H0z M32,60C16.536,60,4,47.464,4,32S16.536,4,32,4s28,12.536,28,28S47.464,60,32,60z"/>
</mask>
</defs>
<path mask="url(#dropShadowMask)" id="playButtonShadow" style="filter:url(#dropShadow);" d="M32,4C16.536,4,4,16.536,4,32s12.536,28,28,28s28-12.536,28-28S47.464,4,32,4z M47.285,33.014 L23.75,46.762C22.797,47.319,22,46.863,22,45.751v-27.5c0-0.697,0.32-1.137,0.781-1.232c0.277-0.058,0.612,0.012,0.969,0.221 l23.535,13.751C48.238,31.546,48.238,32.458,47.285,33.014z"/>
<path id="playButtonArrow" style="fill:url(#arrowGradient);" d="M22.781,17.019C22.32,17.114,22,17.555,22,18.251v27.5c0,1.112,0.797,1.568,1.75,1.011 l23.535-13.748c0.953-0.556,0.953-1.467,0-2.023L23.75,17.24C23.393,17.031,23.058,16.961,22.781,17.019z"/>
<path id="playButton" style="fill:url(#whiteGradient);" d="M32,4C16.536,4,4,16.536,4,32s12.536,28,28,28s28-12.536,28-28S47.464,4,32,4z M47.285,33.014 L23.75,46.762C22.797,47.319,22,46.863,22,45.751v-27.5c0-0.697,0.32-1.137,0.781-1.232c0.277-0.058,0.612,0.012,0.969,0.221 l23.535,13.751C48.238,31.546,48.238,32.458,47.285,33.014z"/>
<path id="playButtonEdgeHighlights" style="fill:white;fill-opacity:.3;" d="M32,4C16.536,4,4,16.536,4,32s12.536,28,28,28s28-12.536,28-28S47.464,4,32,4z M32,59C17.112,59,5,46.888,5,32S17.112,5,32,5s27,12.112,27,27S46.888,59,32,59z M47.789,30.127l-23.534-13.75 C23.826,16.126,23.396,16,22.976,16c-0.135,0-0.27,0.014-0.398,0.041C21.62,16.238,21,17.106,21,18.251v27.5 C21,47.075,21.812,48,22.977,48c0.423,0,0.854-0.126,1.279-0.375L47.79,33.877c0.769-0.449,1.21-1.132,1.21-1.875 S48.559,30.576,47.789,30.127z M47.285,33.014L23.75,46.762C23.474,46.924,23.211,47,22.977,47C22.402,47,22,46.541,22,45.751v-27.5 c0-0.697,0.32-1.137,0.781-1.232L22.976,17c0.233,0,0.498,0.079,0.775,0.24l23.535,13.751 C48.238,31.546,48.238,32.458,47.285,33.014z"/>
<path id="playButtonTopEdgeHighlights" style="fill:white;fill-opacity:.8;" d="M32,4C16.536,4,4,16.536,4,32c0,0.167,0.01,0.333,0.013,0.5 C4.28,17.268,16.704,5,32,5c15.296,0,27.72,12.268,27.987,27.5C59.99,32.333,60,32.167,60,32C60,16.536,47.464,4,32,4z M47.285,33.014L23.75,46.762C22.797,47.319,22,46.863,22,45.751v1c0,1.112,0.797,1.568,1.75,1.011l23.535-13.748 c0.697-0.406,0.879-1.003,0.556-1.512C47.723,32.688,47.541,32.864,47.285,33.014z"/>
</svg>

До

Ширина:  |  Высота:  |  Размер: 3.8 KiB

Просмотреть файл

@ -32,17 +32,23 @@ toolkit.jar:
skin/classic/global/wizard.css (global/empty.css) skin/classic/global/wizard.css (global/empty.css)
skin/classic/global/scrollbars.css (global/empty.css) skin/classic/global/scrollbars.css (global/empty.css)
skin/classic/global/media/clicktoplay-bgtexture.png (global/media/clicktoplay-bgtexture.png)
skin/classic/global/media/error.png (global/media/error.png)
skin/classic/global/media/throbber.png (global/media/throbber.png)
skin/classic/global/media/videoClickToPlayButton.svg (global/media/videoClickToPlayButton.svg)
skin/classic/global/media/TopLevelImageDocument.css (global/media/TopLevelImageDocument.css) skin/classic/global/media/TopLevelImageDocument.css (global/media/TopLevelImageDocument.css)
skin/classic/global/media/TopLevelVideoDocument.css (global/media/TopLevelVideoDocument.css) skin/classic/global/media/TopLevelVideoDocument.css (global/media/TopLevelVideoDocument.css)
skin/classic/global/media/imagedoc-lightnoise.png (global/media/imagedoc-lightnoise.png) skin/classic/global/media/imagedoc-lightnoise.png (global/media/imagedoc-lightnoise.png)
skin/classic/global/media/imagedoc-darknoise.png (global/media/imagedoc-darknoise.png) skin/classic/global/media/imagedoc-darknoise.png (global/media/imagedoc-darknoise.png)
* skin/classic/global/media/videocontrols-html.css (../shared/media/videocontrols.css) * skin/classic/global/media/videocontrols.css (../shared/media/videocontrols.css)
skin/classic/global/media/pauseButton.svg (../shared/media/pauseButton.svg)
skin/classic/global/media/playButton.svg (../shared/media/playButton.svg) skin/classic/global/media/playButton.svg (../shared/media/playButton.svg)
skin/classic/global/media/error.png (../shared/media/error.png)
skin/classic/global/media/throbber.png (../shared/media/throbber.png)
skin/classic/global/media/stalled.png (../shared/media/stalled.png)
skin/classic/global/media/audioMutedButton.svg (../shared/media/audioMutedButton.svg)
skin/classic/global/media/audioNoAudioButton.svg (../shared/media/audioNoAudioButton.svg)
skin/classic/global/media/audioUnmutedButton.svg (../shared/media/audioUnmutedButton.svg)
skin/classic/global/media/closedCaptionButton-cc-off.svg (../shared/media/closedCaptionButton-cc-off.svg)
skin/classic/global/media/closedCaptionButton-cc-on.svg (../shared/media/closedCaptionButton-cc-on.svg)
skin/classic/global/media/fullscreenEnterButton.svg (../shared/media/fullscreenEnterButton.svg)
% skin mozapps classic/1.0 %skin/classic/mozapps/ % skin mozapps classic/1.0 %skin/classic/mozapps/
skin/classic/mozapps/plugins/pluginProblem.css (mozapps/plugins/pluginProblem.css) skin/classic/mozapps/plugins/pluginProblem.css (mozapps/plugins/pluginProblem.css)