Upstream version 7.35.144.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / resources / video_player / js / video_player.js
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 'use strict';
6
7 /**
8  * Displays error message.
9  * @param {string} message Message id.
10  */
11 function showErrorMessage(message) {
12   var errorBanner = document.querySelector('#error');
13   errorBanner.textContent =
14       loadTimeData.getString(message);
15   errorBanner.setAttribute('visible', 'true');
16
17   // The window is hidden if the video has not loaded yet.
18   chrome.app.window.current().show();
19 }
20
21 /**
22  * Handles playback (decoder) errors.
23  */
24 function onPlaybackError() {
25   showErrorMessage('GALLERY_VIDEO_DECODING_ERROR');
26   decodeErrorOccured = true;
27
28   // Disable inactivity watcher, and disable the ui, by hiding tools manually.
29   controls.inactivityWatcher.disabled = true;
30   document.querySelector('#video-player').setAttribute('disabled', 'true');
31
32   // Detach the video element, since it may be unreliable and reset stored
33   // current playback time.
34   controls.cleanup();
35   controls.clearState();
36
37   // Avoid reusing a video element.
38   video.parentNode.removeChild(video);
39   video = null;
40 }
41
42 /**
43  * @param {Element} playerContainer Main container.
44  * @param {Element} videoContainer Container for the video element.
45  * @param {Element} controlsContainer Container for video controls.
46  * @constructor
47  */
48 function FullWindowVideoControls(
49     playerContainer, videoContainer, controlsContainer) {
50   VideoControls.call(this,
51       controlsContainer,
52       onPlaybackError,
53       loadTimeData.getString.bind(loadTimeData),
54       this.toggleFullScreen_.bind(this),
55       videoContainer);
56
57   this.playerContainer_ = playerContainer;
58
59   this.updateStyle();
60   window.addEventListener('resize', this.updateStyle.bind(this));
61
62   document.addEventListener('keydown', function(e) {
63     if (e.keyIdentifier == 'U+0020') {  // Space
64       this.togglePlayStateWithFeedback();
65       e.preventDefault();
66     }
67     if (e.keyIdentifier == 'U+001B') {  // Escape
68       util.toggleFullScreen(
69           chrome.app.window.current(),
70           false);  // Leave the full screen mode.
71       e.preventDefault();
72     }
73   }.bind(this));
74
75   // TODO(mtomasz): Simplify. crbug.com/254318.
76   videoContainer.addEventListener('click', function(e) {
77     if (e.ctrlKey) {
78       this.toggleLoopedModeWithFeedback(true);
79       if (!this.isPlaying())
80         this.togglePlayStateWithFeedback();
81     } else {
82       this.togglePlayStateWithFeedback();
83     }
84   }.bind(this));
85
86   this.inactivityWatcher_ = new MouseInactivityWatcher(playerContainer);
87   this.__defineGetter__('inactivityWatcher', function() {
88     return this.inactivityWatcher_;
89   });
90
91   this.inactivityWatcher_.check();
92 }
93
94 FullWindowVideoControls.prototype = { __proto__: VideoControls.prototype };
95
96 /**
97  * Toggles the full screen mode.
98  * @private
99  */
100 FullWindowVideoControls.prototype.toggleFullScreen_ = function() {
101   var appWindow = chrome.app.window.current();
102   util.toggleFullScreen(appWindow, !util.isFullScreen(appWindow));
103 };
104
105 // TODO(mtomasz): Convert it to class members: crbug.com/171191.
106 var decodeErrorOccured;
107 var video;
108 var controls;
109
110 /**
111  * Initializes the video player window.
112  */
113 function loadVideoPlayer() {
114   document.ondragstart = function(e) { e.preventDefault() };
115
116   chrome.fileBrowserPrivate.getStrings(function(strings) {
117     loadTimeData.data = strings;
118
119     var url = window.videoUrl;
120     document.title = window.videoTitle;
121
122     controls = new FullWindowVideoControls(
123         document.querySelector('#video-player'),
124         document.querySelector('#video-container'),
125         document.querySelector('#controls'));
126
127     var reloadVideo = function(e) {
128       if (decodeErrorOccured &&
129           // Ignore shortcut keys
130           !e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey) {
131         loadVideo(url);
132         e.preventDefault();
133       }
134     };
135
136     loadVideo(url);
137     document.addEventListener('keydown', reloadVideo, true);
138     document.addEventListener('click', reloadVideo, true);
139   });
140 }
141
142 /**
143  * Unloads the player.
144  */
145 function unload() {
146   if (!controls.getMedia())
147     return;
148
149   controls.savePosition(true /* exiting */);
150   controls.cleanup();
151 }
152
153 /**
154  * Reloads the player.
155  * @param {string} url URL of the video file.
156  */
157 function loadVideo(url) {
158   // Re-enable ui and hide error message if already displayed.
159   document.querySelector('#video-player').removeAttribute('disabled');
160   document.querySelector('#error').removeAttribute('visible');
161   controls.inactivityWatcher.disabled = false;
162   decodeErrorOccured = false;
163
164   // Detach the previous video element, if exists.
165   if (video)
166     video.parentNode.removeChild(video);
167
168   video = document.createElement('video');
169   document.querySelector('#video-container').appendChild(video);
170   controls.attachMedia(video);
171
172   video.src = url;
173   video.load();
174   video.addEventListener('loadedmetadata', function() {
175     // TODO: chrome.app.window soon will be able to resize the content area.
176     // Until then use approximate title bar height.
177     var TITLE_HEIGHT = 33;
178
179     var aspect = video.videoWidth / video.videoHeight;
180     var newWidth = video.videoWidth;
181     var newHeight = video.videoHeight + TITLE_HEIGHT;
182
183     var shrinkX = newWidth / window.screen.availWidth;
184     var shrinkY = newHeight / window.screen.availHeight;
185     if (shrinkX > 1 || shrinkY > 1) {
186       if (shrinkY > shrinkX) {
187         newHeight = newHeight / shrinkY;
188         newWidth = (newHeight - TITLE_HEIGHT) * aspect;
189       } else {
190         newWidth = newWidth / shrinkX;
191         newHeight = newWidth / aspect + TITLE_HEIGHT;
192       }
193     }
194
195     var oldLeft = window.screenX;
196     var oldTop = window.screenY;
197     var oldWidth = window.outerWidth;
198     var oldHeight = window.outerHeight;
199
200     if (!oldWidth && !oldHeight) {
201       oldLeft = window.screen.availWidth / 2;
202       oldTop = window.screen.availHeight / 2;
203     }
204
205     var appWindow = chrome.app.window.current();
206     appWindow.resizeTo(newWidth, newHeight);
207     appWindow.moveTo(oldLeft - (newWidth - oldWidth) / 2,
208                      oldTop - (newHeight - oldHeight) / 2);
209     appWindow.show();
210
211     video.play();
212   });
213 }
214
215 util.addPageLoadHandler(loadVideoPlayer);