Skip to content

Commit

Permalink
Added isFullscreen method to the video interface, fixes bugs with Chr…
Browse files Browse the repository at this point in the history
…ome and iOS
  • Loading branch information
wassgha committed Jul 26, 2017
1 parent 87eed65 commit 94f885f
Show file tree
Hide file tree
Showing 12 changed files with 149 additions and 20 deletions.
2 changes: 1 addition & 1 deletion build-system/tasks/presubmit-checks.js
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@ var forbiddenTerms = {
'src/event-helper.js',
],
},
'[A-Za-z]*Full[Ss]creen\\(': {
'([eE]xit|[eE]nter|[cC]ancel|[rR]equest)Full[Ss]creen\\(': {
message: 'Use fullscreenEnter() and fullscreenExit() from dom.js instead.',
whitelist: [
'ads/google/imaVideo.js',
Expand Down
12 changes: 11 additions & 1 deletion extensions/amp-3q-player/0.1/amp-3q-player.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@
import {isLayoutSizeDefined} from '../../../src/layout';
import {tryParseJson} from '../../../src/json';
import {user, dev} from '../../../src/log';
import {removeElement, fullscreenEnter, fullscreenExit} from '../../../src/dom';
import {
removeElement,
fullscreenEnter,
fullscreenExit,
isFullscreenElement,
} from '../../../src/dom';
import {
installVideoManagerForDoc,
} from '../../../src/service/video-manager-impl';
Expand Down Expand Up @@ -229,6 +234,11 @@ class Amp3QPlayer extends AMP.BaseElement {
fullscreenExit(dev().assertElement(this.iframe_));
}

/** @override */
isFullscreen() {
return isFullscreenElement(dev().assertElement(this.iframe_));
}

/** @override */
getCurrentTime() {
// Not supported.
Expand Down
12 changes: 11 additions & 1 deletion extensions/amp-brid-player/0.1/amp-brid-player.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ import {
import {VideoEvents} from '../../../src/video-interface';
import {Services} from '../../../src/services';
import {assertAbsoluteHttpOrHttpsUrl} from '../../../src/url';
import {removeElement, fullscreenEnter, fullscreenExit} from '../../../src/dom';
import {
removeElement,
fullscreenEnter,
fullscreenExit,
isFullscreenElement,
} from '../../../src/dom';
import {getData, listen} from '../../../src/event-helper';

/**
Expand Down Expand Up @@ -300,6 +305,11 @@ class AmpBridPlayer extends AMP.BaseElement {
fullscreenExit(dev().assertElement(this.iframe_));
}

/** @override */
isFullscreen() {
return isFullscreenElement(dev().assertElement(this.iframe_));
}

/** @override */
getCurrentTime() {
// Not supported.
Expand Down
18 changes: 18 additions & 0 deletions extensions/amp-dailymotion/0.1/amp-dailymotion.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
getDataParamsFromAttributes,
fullscreenEnter,
fullscreenExit,
isFullscreenElement,
} from '../../../src/dom';

/**
Expand Down Expand Up @@ -61,6 +62,7 @@ const DailymotionEvents = {
// Other events
VOLUMECHANGE: 'volumechange',
STARTED_BUFFERING: 'progress',
FULLSCREEN_CHANGE: 'fullscreenchange',
};

/**
Expand Down Expand Up @@ -101,6 +103,9 @@ class AmpDailymotion extends AMP.BaseElement {
/** @private {?Function} */
this.startedBufferingResolver_ = null;

/** @private {boolean} */
this.isFullscreen_ = false;

}

/**
Expand Down Expand Up @@ -222,6 +227,9 @@ class AmpDailymotion extends AMP.BaseElement {
case DailymotionEvents.STARTED_BUFFERING:
this.startedBufferingResolver_(true);
break;
case DailymotionEvents.FULLSCREEN_CHANGE:
this.isFullscreen_ = data['fullscreen'] == 'true';
break;
default:

}
Expand Down Expand Up @@ -365,6 +373,16 @@ class AmpDailymotion extends AMP.BaseElement {
}
}

/** @override */
isFullscreen() {
const platform = Services.platformFor(this.win);
if (platform.isSafari() || platform.isIos()) {
return this.isFullscreen_;
} else {
return isFullscreenElement(dev().assertElement(this.iframe_));
}
}

/** @override */
getCurrentTime() {
// Not supported.
Expand Down
14 changes: 13 additions & 1 deletion extensions/amp-ima-video/0.1/amp-ima-video.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,12 @@ import {
listen,
} from '../../../src/event-helper';
import {dict} from '../../../src/utils/object';
import {removeElement, fullscreenEnter, fullscreenExit} from '../../../src/dom';
import {
removeElement,
fullscreenEnter,
fullscreenExit,
isFullscreenElement,
} from '../../../src/dom';
import {user, dev} from '../../../src/log';
import {VideoEvents} from '../../../src/video-interface';
import {Services} from '../../../src/services';
Expand Down Expand Up @@ -289,6 +294,13 @@ class AmpImaVideo extends AMP.BaseElement {
fullscreenExit(dev().assertElement(this.iframe_));
}

/** @override */
isFullscreen() {
// TODO(@aghassemi, #10597) Report fullscreen status of internal <video>
// element rather than iframe
return isFullscreenElement(dev().assertElement(this.iframe_));
}

/** @override */
getCurrentTime() {
// Not supported.
Expand Down
12 changes: 11 additions & 1 deletion extensions/amp-nexxtv-player/0.1/amp-nexxtv-player.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ import {user, dev} from '../../../src/log';
import {
installVideoManagerForDoc,
} from '../../../src/service/video-manager-impl';
import {removeElement, fullscreenEnter, fullscreenExit} from '../../../src/dom';
import {
removeElement,
fullscreenEnter,
fullscreenExit,
isFullscreenElement,
} from '../../../src/dom';
import {getData, listen} from '../../../src/event-helper';
import {isObject} from '../../../src/types';
import {VideoEvents} from '../../../src/video-interface';
Expand Down Expand Up @@ -255,6 +260,11 @@ class AmpNexxtvPlayer extends AMP.BaseElement {
fullscreenExit(dev().assertElement(this.iframe_));
}

/** @override */
isFullscreen() {
return isFullscreenElement(dev().assertElement(this.iframe_));
}

/** @override */
getCurrentTime() {
// Not supported.
Expand Down
12 changes: 11 additions & 1 deletion extensions/amp-ooyala-player/0.1/amp-ooyala-player.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@
import {isLayoutSizeDefined} from '../../../src/layout';
import {tryParseJson} from '../../../src/json';
import {user, dev} from '../../../src/log';
import {removeElement, fullscreenEnter, fullscreenExit} from '../../../src/dom';
import {
removeElement,
fullscreenEnter,
fullscreenExit,
isFullscreenElement,
} from '../../../src/dom';
import {
installVideoManagerForDoc,
} from '../../../src/service/video-manager-impl';
Expand Down Expand Up @@ -240,6 +245,11 @@ class AmpOoyalaPlayer extends AMP.BaseElement {
fullscreenExit(dev().assertElement(this.iframe_));
}

/** @override */
isFullscreen() {
return isFullscreenElement(dev().assertElement(this.iframe_));
}

/** @override */
getCurrentTime() {
// Not supported.
Expand Down
12 changes: 11 additions & 1 deletion extensions/amp-video/0.1/amp-video.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@
* limitations under the License.
*/

import {elementByTag, fullscreenEnter, fullscreenExit} from '../../../src/dom';
import {
elementByTag,
fullscreenEnter,
fullscreenExit,
isFullscreenElement,
} from '../../../src/dom';
import {listen} from '../../../src/event-helper';
import {isLayoutSizeDefined} from '../../../src/layout';
import {getMode} from '../../../src/mode';
Expand Down Expand Up @@ -288,6 +293,11 @@ class AmpVideo extends AMP.BaseElement {
fullscreenExit(dev().assertElement(this.video_));
}

/** @override */
isFullscreen() {
return isFullscreenElement(dev().assertElement(this.video_));
}

/** @override */
getCurrentTime() {
return this.video_.currentTime;
Expand Down
5 changes: 5 additions & 0 deletions extensions/amp-youtube/0.1/amp-youtube.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
removeElement,
fullscreenEnter,
fullscreenExit,
isFullscreenElement,
} from '../../../src/dom';
import {tryParseJson} from '../../../src/json';
import {getData, listen} from '../../../src/event-helper';
Expand Down Expand Up @@ -451,6 +452,10 @@ class AmpYoutube extends AMP.BaseElement {
fullscreenExit(dev().assertElement(this.iframe_));
}

/** @override */
isFullscreen() {
return isFullscreenElement(dev().assertElement(this.iframe_));
}

/** @override */
getCurrentTime() {
Expand Down
24 changes: 24 additions & 0 deletions src/dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -803,3 +803,27 @@ export function fullscreenExit(element) {
return;
}
}


/**
* Replacement for `Document.fullscreenElement`.
* https://developer.mozilla.org/en-US/docs/Web/API/Document/fullscreenElement
* @param {!Element} element
* @return {boolean}
*/
export function isFullscreenElement(element) {
const isFullscreen = element.webkitDisplayingFullscreen;
if (isFullscreen) {
return true;
}
if (element.ownerDocument) {
const fullscreenElement = element.ownerDocument.fullscreenElement
|| element.ownerDocument.webkitFullscreenElement
|| element.ownerDocument.mozFullScreenElement
|| element.webkitCurrentFullScreenElement;
if (fullscreenElement == element) {
return true;
}
}
return false;
}
36 changes: 25 additions & 11 deletions src/service/video-manager-impl.js
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ export class VideoManager {
maybeInstallOrientationObserver_(entry) {
// The orientation observer is only useful for automatically putting videos
// in fullscreen.
if (!entry.video.element.hasAttribute(VideoAttributes.AUTOFULLSCREEN)) {
if (!entry.hasFullscreenOnLandscape) {
return;
}

Expand All @@ -223,15 +223,16 @@ export class VideoManager {
};
// Chrome apparently considers 'orientationchange' to be an untrusted
// event, while 'change' on screen.orientation is considered a user
// interaction
// interaction. However on Chrome we still need to listen to
// 'orientationchange' to be able to exit fullscreen since 'change' does not
// fire when a video is in fullscreen.
if (screen && 'orientation' in screen) {
const orient = /** @type {!ScreenOrientation} */ (screen.orientation);
listen(orient, 'change', handleOrientationChange.bind(this));
} else {
// iOS Safari does not have screen.orientation but classifies
// 'orientationchange' as a user interaction.
listen(win, 'orientationchange', handleOrientationChange.bind(this));
}
// iOS Safari does not have screen.orientation but classifies
// 'orientationchange' as a user interaction.
listen(win, 'orientationchange', handleOrientationChange.bind(this));
}

/**
Expand Down Expand Up @@ -439,7 +440,12 @@ class VideoEntry {

this.hasAutoplay = element.hasAttribute(VideoAttributes.AUTOPLAY);

this.hasAutoFs = element.hasAttribute(VideoAttributes.AUTOFULLSCREEN);
const fsOnLandscapeAttr = element.getAttribute(
VideoAttributes.FULLSCREEN_ON_LANDSCAPE
);

this.hasFullscreenOnLandscape = fsOnLandscapeAttr !== undefined
&& (fsOnLandscapeAttr === '' || fsOnLandscapeAttr == 'always');

listenOncePromise(element, VideoEvents.LOAD)
.then(() => this.videoLoaded());
Expand Down Expand Up @@ -543,11 +549,13 @@ class VideoEntry {
* @private
*/
orientationChanged_(isLandscape) {
// Put the video in/out of fullscreen depending on orientation
// Put the video in/out of fullscreen depending on screen orientation
if (!isLandscape && this.isFullscreenByOrientationChange_) {
this.exitFullscreen_();
} else if (this.getPlayingState() == PlayingStates.PLAYING_MANUAL
&& this.isVisible_) {
} else if (isLandscape
&& this.getPlayingState() == PlayingStates.PLAYING_MANUAL
&& this.isVisible_
&& Services.viewerForDoc(this.ampdoc_).isVisible()) {
this.enterFullscreen_();
}
}
Expand All @@ -557,15 +565,21 @@ class VideoEntry {
* @private
*/
enterFullscreen_() {
if (this.video.isFullscreen() || this.isFullscreenByOrientationChange_) {
return;
}
this.video.fullscreenEnter();
this.isFullscreenByOrientationChange_ = true;
this.isFullscreenByOrientationChange_ = this.video.isFullscreen();
}

/**
* Makes the video element quit fullscreen and updates its status
* @private
*/
exitFullscreen_() {
if (!this.isFullscreenByOrientationChange_) {
return;
}
this.video.fullscreenExit();
this.isFullscreenByOrientationChange_ = false;
}
Expand Down
10 changes: 8 additions & 2 deletions src/video-interface.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,12 @@ export class VideoInterface {
*/
fullscreenExit() {}

/**
* Returns whether the video is currently in fullscreen mode or not
* @return {boolean}
*/
isFullscreen() {}

/**
* Automatically comes from {@link ./base-element.BaseElement}
*
Expand Down Expand Up @@ -184,7 +190,7 @@ export const VideoAttributes = {
*/
DOCK: 'dock',
/**
* auto-fullscreen
* fullscreen-on-landscape
*
* If enabled, this automatically expands the currently visible video and
* playing to fullscreen when the user changes the device's orientation to
Expand All @@ -195,7 +201,7 @@ export const VideoAttributes = {
* http://caniuse.com/#feat=screen-orientation
* and http://caniuse.com/#feat=fullscreen
*/
AUTOFULLSCREEN: 'auto-fullscreen',
FULLSCREEN_ON_LANDSCAPE: 'fullscreen-on-landscape',
};


Expand Down

0 comments on commit 94f885f

Please sign in to comment.