1function createControls(root, video, host) 2{ 3 return new ControllerGtk(root, video, host); 4}; 5 6function ControllerGtk(root, video, host) 7{ 8 Controller.call(this, root, video, host); 9}; 10 11function contains(list, obj) 12{ 13 var i = list.length; 14 while (i--) 15 if (list[i] === obj) 16 return true; 17 return false; 18}; 19 20ControllerGtk.prototype = { 21 22 createControls: function() 23 { 24 Controller.prototype.createControls.apply(this); 25 26 this.controls.currentTime.classList.add(this.ClassNames.hidden); 27 this.controls.remainingTime.classList.add(this.ClassNames.hidden); 28 29 this.controls.volumeBox.classList.add(this.ClassNames.hiding); 30 31 this.listenFor(this.controls.muteBox, 'mouseout', this.handleVolumeBoxMouseOut); 32 this.listenFor(this.controls.muteButton, 'mouseover', this.handleMuteButtonMouseOver); 33 this.listenFor(this.controls.volumeBox, 'mouseover', this.handleMuteButtonMouseOver); 34 this.listenFor(this.controls.volume, 'mouseover', this.handleMuteButtonMouseOver); 35 this.listenFor(this.controls.captionButton, 'mouseover', this.handleCaptionButtonMouseOver); 36 this.listenFor(this.controls.captionButton, 'mouseout', this.handleCaptionButtonMouseOut); 37 38 var enclosure = this.controls.enclosure = document.createElement('div'); 39 enclosure.setAttribute('pseudo', '-webkit-media-controls-enclosure'); 40 }, 41 42 configureInlineControls: function() 43 { 44 this.controls.panel.appendChild(this.controls.playButton); 45 this.controls.panel.appendChild(this.controls.timeline); 46 this.controls.panel.appendChild(this.controls.currentTime); 47 this.controls.panel.appendChild(this.controls.remainingTime); 48 this.controls.panel.appendChild(this.controls.captionButton); 49 this.controls.panel.appendChild(this.controls.fullscreenButton); 50 this.controls.panel.appendChild(this.controls.muteBox); 51 this.controls.muteBox.appendChild(this.controls.muteButton); 52 this.controls.muteBox.appendChild(this.controls.volumeBox); 53 this.controls.volumeBox.appendChild(this.controls.volume); 54 this.controls.enclosure.appendChild(this.controls.panel); 55 }, 56 57 configureControls: function() { 58 if (this.controls.configured) 59 return; 60 61 this.configureInlineControls(); 62 this.controls.configured = true; 63 this.addControls(); 64 }, 65 66 reconnectControls: function() 67 { 68 this.configureControls(); 69 }, 70 71 setStatusHidden: function(hidden) 72 { 73 }, 74 75 updateTime: function() 76 { 77 var currentTime = this.video.currentTime; 78 var duration = this.video.duration; 79 80 this.controls.currentTime.innerText = this.formatTime(currentTime); 81 this.controls.timeline.value = currentTime; 82 if (duration === Infinity || duration === NaN) 83 this.controls.remainingTime.classList.add(this.ClassNames.hidden); 84 else { 85 this.controls.currentTime.innerText += " / " + this.formatTime(duration); 86 this.controls.remainingTime.innerText = this.formatTime(duration); 87 if (this.controls.currentTime.classList.contains(this.ClassNames.hidden)) 88 this.controls.remainingTime.classList.remove(this.ClassNames.hidden); 89 } 90 91 if (currentTime > 0) 92 this.showCurrentTime(); 93 }, 94 95 showCurrentTime: function() 96 { 97 this.controls.currentTime.classList.remove(this.ClassNames.hidden); 98 this.controls.remainingTime.classList.add(this.ClassNames.hidden); 99 }, 100 101 handlePlay: function(event) 102 { 103 Controller.prototype.handlePlay.apply(this, arguments); 104 this.showCurrentTime(); 105 if (!this.isLive) 106 this.showCurrentTime(); 107 }, 108 109 handleTimeUpdate: function(event) 110 { 111 this.updateTime(); 112 }, 113 114 handleMuteButtonMouseOver: function(event) 115 { 116 if (this.video.offsetTop + this.controls.enclosure.offsetTop < 105) { 117 this.controls.volumeBox.classList.add(this.ClassNames.down); 118 this.controls.panel.classList.add(this.ClassNames.down); 119 } else { 120 this.controls.volumeBox.classList.remove(this.ClassNames.down); 121 this.controls.panel.classList.remove(this.ClassNames.down); 122 } 123 this.controls.volumeBox.classList.remove(this.ClassNames.hiding); 124 return true; 125 }, 126 127 handleVolumeBoxMouseOut: function(event) 128 { 129 this.controls.volumeBox.classList.add(this.ClassNames.hiding); 130 return true; 131 }, 132 133 addControls: function() 134 { 135 this.base.appendChild(this.controls.enclosure); 136 }, 137 138 updateReadyState: function() 139 { 140 if (this.host.supportsFullscreen && this.video.videoTracks.length) 141 this.controls.fullscreenButton.classList.remove(this.ClassNames.hidden); 142 else 143 this.controls.fullscreenButton.classList.add(this.ClassNames.hidden); 144 this.updateVolume(); 145 }, 146 147 updateDuration: function() 148 { 149 Controller.prototype.updateDuration.apply(this, arguments); 150 if (this.isLive) 151 this.controls.timeline.max = 0; 152 }, 153 154 setIsLive: function(live) 155 { 156 Controller.prototype.setIsLive.apply(this, arguments); 157 this.controls.timeline.disabled = this.isLive; 158 }, 159 160 updatePlaying: function() 161 { 162 Controller.prototype.updatePlaying.apply(this, arguments); 163 if (!this.canPlay()) 164 this.showControls(); 165 }, 166 167 handleCaptionButtonClicked: function(event) 168 { 169 this.handleCaptionButtonShowMenu(event) 170 return true; 171 }, 172 173 buildCaptionMenu: function() 174 { 175 Controller.prototype.buildCaptionMenu.apply(this, arguments); 176 177 this.listenFor(this.captionMenu, 'mouseout', this.handleCaptionMouseOut); 178 this.listenFor(this.captionMenu, 'transitionend', this.captionMenuTransitionEnd); 179 180 this.captionMenu.captionMenuTreeElements = this.captionMenu.getElementsByTagName("*"); 181 182 // Caption menu has to be centered to the caption button. 183 var captionButtonCenter = this.controls.panel.offsetLeft + this.controls.captionButton.offsetLeft + 184 this.controls.captionButton.offsetWidth / 2; 185 var captionMenuLeft = (captionButtonCenter - this.captionMenu.offsetWidth / 2); 186 if (captionMenuLeft + this.captionMenu.offsetWidth > this.controls.panel.offsetLeft + this.controls.panel.offsetWidth) 187 this.captionMenu.classList.add(this.ClassNames.out); 188 this.captionMenu.style.left = captionMenuLeft + 'px'; 189 // As height is not in the css, it needs to be specified to animate it. 190 this.captionMenu.height = this.captionMenu.offsetHeight; 191 this.captionMenu.style.height = 0; 192 }, 193 194 destroyCaptionMenu: function() 195 { 196 this.hideCaptionMenu(); 197 }, 198 199 showCaptionMenu: function() 200 { 201 this.captionMenu.style.height = this.captionMenu.height + 'px'; 202 }, 203 204 hideCaptionMenu: function() 205 { 206 this.captionMenu.style.height = 0; 207 }, 208 209 captionMenuTransitionEnd: function(event) 210 { 211 if (this.captionMenu.offsetHeight === 0) 212 Controller.prototype.destroyCaptionMenu.apply(this, arguments); 213 }, 214 215 handleCaptionButtonMouseOver: function(event) 216 { 217 this.handleCaptionButtonShowMenu(event); 218 return true; 219 }, 220 221 handleCaptionButtonShowMenu: function(event) 222 { 223 if (!this.captionMenu) 224 this.buildCaptionMenu(); 225 if (!contains(this.captionMenu.captionMenuTreeElements, event.relatedTarget)) 226 this.showCaptionMenu(); 227 return true; 228 }, 229 230 handleCaptionButtonMouseOut: function(event) 231 { 232 if (this.captionMenu && !contains(this.captionMenu.captionMenuTreeElements, event.relatedTarget)) 233 this.hideCaptionMenu(); 234 return true; 235 }, 236 237 handleCaptionMouseOut: function(event) 238 { 239 if (event.relatedTarget != this.controls.captionButton && 240 !contains(this.captionMenu.captionMenuTreeElements, event.relatedTarget)) 241 this.hideCaptionMenu(); 242 return true; 243 }, 244}; 245 246Object.create(Controller.prototype).extend(ControllerGtk.prototype); 247Object.defineProperty(ControllerGtk.prototype, 'constructor', { enumerable:false, value:ControllerGtk }); 248