UNPKG

rizzo-next

Version:

The next generation of Lonely Planet's style guide and pattern library.

506 lines (434 loc) 16.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; var _video_player = require("./video_player"); var _video_player2 = _interopRequireDefault(_video_player); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /* global videojs */ var Brightcove = function (_VideoPlayer) { _inherits(Brightcove, _VideoPlayer); function Brightcove() { _classCallCheck(this, Brightcove); return _possibleConstructorReturn(this, (Brightcove.__proto__ || Object.getPrototypeOf(Brightcove)).apply(this, arguments)); } _createClass(Brightcove, [{ key: "initialize", value: function initialize(options) { _get(Brightcove.prototype.__proto__ || Object.getPrototypeOf(Brightcove.prototype), "initialize", this).call(this, options); this.videos = []; this.currentVideoIndex = null; this.events["click .video-js"] = "onClickVideo"; } }, { key: "onClickVideo", value: function onClickVideo(event) { // Prevent event from bubbling into the UI // when the user interacts with the video. event.stopPropagation(); } }, { key: "play", value: function play() { _get(Brightcove.prototype.__proto__ || Object.getPrototypeOf(Brightcove.prototype), "play", this).call(this); this.autoplay = true; var promise = this.player.play(); // Catch any errors thrown within play promise (only applicable on some browsers) if (promise) { promise.catch(function (reason) { return console.log("VIDEOJS:", reason); }).then(function () {}); } } }, { key: "pause", value: function pause() { _get(Brightcove.prototype.__proto__ || Object.getPrototypeOf(Brightcove.prototype), "pause", this).call(this); this.autoplay = false; this.player.pause(); } }, { key: "start", value: function start() { this.currentVideoIndex = null; this.autoplay = true; this.loadNextVideo(); } }, { key: "setup", value: function setup() { if (!this.videoId) { this.trigger("ready"); } else if (!this.videoEl) { // Insert brightcove player html var html = "<video "; if (this.videoId) { html += "data-video-id='" + this.videoId + "' "; } html += "data-account='5104226627001' "; html += "data-player='default' "; html += "data-embed='default' "; html += "data-application-id "; html += "class='video-js' "; html += "></video>"; this.el.innerHTML = html; // Insert script to initialize brightcove player var scriptId = this.getPlayerScriptId(); var scriptSrc = "https://players.brightcove.net/5104226627001/default_default/index.min.js"; var script = document.createElement("script"); script.id = scriptId; script.src = scriptSrc; script.onload = this.onLoadSetupScript.bind(this); document.body.appendChild(script); } else if (!this.player) { this.player = videojs(this.videoEl); // We don't show the controls until the player is instantiated // or else the controls show briefly without the brightcove theme applied. this.player.controls(true); this.player.on("loadstart", this.onPlayerLoadStart.bind(this)); this.player.on("playing", this.onPlayerPlaying.bind(this)); this.player.on("ended", this.onPlayerEnded.bind(this)); this.player.on("ads-ad-started", this.onAdStarted.bind(this)); this.player.on("ads-ad-ended", this.onAdEnded.bind(this)); this.player.ready(this.onPlayerReady.bind(this)); } } }, { key: "dispose", value: function dispose() { var scriptId = this.getPlayerScriptId(); var script = document.getElementById(scriptId); if (script) { script.remove(); } if (this.player) { this.player.dispose(); this.player = null; } this.trigger("disposed", this); } }, { key: "getPlayerScriptId", value: function getPlayerScriptId() { return "video__initialize-" + this.playerId; } }, { key: "onLoadSetupScript", value: function onLoadSetupScript() { this.setup(); } }, { key: "onPlayerReady", value: function onPlayerReady() { this.currentVideoIndex = null; this.loadNextVideo(); this.trigger("ready"); } }, { key: "onPlayerCueChange", value: function onPlayerCueChange() { var tt = this.player.textTracks()[0]; var activeCue = tt.activeCues[0]; if (!activeCue || activeCue.text !== "CODE") { return; } var cue = activeCue.originalCuePoint; var overlayElementId = "ad-lowerthird-" + this.playerId + "-" + cue.id; var element = document.getElementById(overlayElementId); if (!element) { return; } var cueIndex = null; this.getCues().forEach(function (c, i) { if (c.originalCuePoint.id === cue.id) { cueIndex = i; } }); if (cueIndex === null) { return; } window.lp.analytics.dfp.video.lowerThird(cueIndex + 1, overlayElementId); } }, { key: "onPlayerLoadStart", value: function onPlayerLoadStart() { var tt = this.player.textTracks()[0]; if (tt) { tt.oncuechange = this.onPlayerCueChange.bind(this); } this.renderSEOMarkup(); this.updateDataLayer(); this.configureOverlays(); this.trigger("loadstart"); if (this.autoplay) { this.play(); } } }, { key: "onPlayerPlaying", value: function onPlayerPlaying() { this.updateDataLayer(); this.disableAdOverlay(); } }, { key: "onPlayerEnded", value: function onPlayerEnded() { if (this.currentVideoIndex >= this.videos.length - 1) { this.trigger("ended"); } else { this.loadNextVideo(); } } }, { key: "onAdStarted", value: function onAdStarted() { this.enableAdOverlay(); } }, { key: "onAdEnded", value: function onAdEnded() { this.disableAdOverlay(); } }, { key: "enableAdOverlay", value: function enableAdOverlay() { var adOverlay = this.$el.find("#" + this.getAdOverlayId()); adOverlay.css("display", "inline-block"); } }, { key: "disableAdOverlay", value: function disableAdOverlay() { var adOverlay = this.$el.find("#" + this.getAdOverlayId()); adOverlay.css("display", "none"); } }, { key: "fetchVideos", value: function fetchVideos() { var _this2 = this; var query = null; try { query = "dest_" + window.lp.place.atlasId; } catch (e) { return Promise.resolve(false); } var apiURL = "https://www.lonelyplanet.com/video/api/"; return new Promise(function (resolve) { $.ajax({ url: apiURL + "playlists.json?reference_id=" + query }).done(function (data, status, response) { if (response.status === 200 && data && data.length) { _this2.videos = data[0].playlistitems.map(function (item) { return item.video; }); } if (_this2.videos.length) { _this2.loadNextVideo(); resolve(true); } else { $.ajax({ url: apiURL + "video.json?reference_id=" + query }).done(function (data, status, response) { if (response.status === 200 && data && data.length) { _this2.videos = data; } if (_this2.videos.length) { _this2.loadNextVideo(); resolve(true); } else { resolve(false); } }); } }); }); } }, { key: "loadNextVideo", value: function loadNextVideo() { var _this3 = this; if (!this.videos.length) { return; } this.currentVideoIndex = this.currentVideoIndex === null ? 0 : this.currentVideoIndex + 1; this.currentVideoIndex = this.currentVideoIndex > this.videos.length - 1 ? 0 : this.currentVideoIndex; var video = this.videos[this.currentVideoIndex]; if (!this.player) { this.videoId = video.provider_id; this.setup(); } else if (!this.player.mediainfo || this.player.mediainfo.id !== video.provider_id) { // Do not load a video that is already loaded // (brightcove's engagement score metrics will break) this.player.catalog.getVideo(video.provider_id, function (error, video) { if (!error) { _this3.player.catalog.load(video); } }); } else if (this.autoplay) { this.play(); } } /** * Gets the ideal dimensions of the video, considering it's aspect ratio. * @param {number} maxw - (required) Maximum width to return (pixels) * @param {number} maxh - (optional) Maximum height to return (pixels) * @return {Object} object with 'width' and 'height' attributes */ }, { key: "getIdealDimensions", value: function getIdealDimensions(maxw, maxh) { var ratio = this.defaultAspectRatio; // If we have video data, use the aspect ratio of the // video as the width-height ratio value try { var source = this.player.mediainfo.rawSources[0]; ratio = source.width / source.height; } catch (e) {} var width = maxw; var height = maxw / ratio; if (typeof maxh != "undefined" && height > maxh) { height = maxh; width = height * ratio; } return { width: width, height: height }; } }, { key: "getAdOverlayId", value: function getAdOverlayId() { return "ad-overlay-" + this.playerId; } }, { key: "getCues", value: function getCues() { if (!this.player) { return []; } var tt = this.player.textTracks()[0]; if (!tt) { return []; } var index = 0; var cues = []; while (index < tt.cues.length) { var cue = tt.cues[index]; if (cue.text === "CODE") { cues.push(cue); } index += 1; } return cues; } }, { key: "configureOverlays", value: function configureOverlays() { var _this4 = this; if (!this.player) { return; } var overlays = this.getCues().map(function (c) { var cue = c.originalCuePoint; var defaultEnd = cue.startTime + 15; var end = defaultEnd < cue.endTime ? defaultEnd : cue.endTime; var cueElementId = "ad-lowerthird-" + _this4.playerId + "-" + cue.id; return { content: "<div id=\"" + cueElementId + "\" class=\"video__lowerthird-overlay\" />", align: "bottom", start: cue.startTime, end: end }; }); overlays.push({ content: "<div id=\"" + this.getAdOverlayId() + "\" class=\"video__ad-overlay\">Advertisement</div>", align: "top-left", start: "ads-ad-started", end: "playing" }); this.player.overlay({ content: "", overlays: overlays, showBackground: false, attachToControlBar: true, debug: false }); } /** * Retrieves metadata from the currently loaded video * @param {string} name - The metadata attribute to retrieve a value for * @returns The metadata value, or undefined if unable to retrieve the value */ }, { key: "getVideoProperty", value: function getVideoProperty(name) { if (!this.player || !this.player.mediainfo) { return; } return this.player.mediainfo[name]; } }, { key: "updateDataLayer", value: function updateDataLayer() { Object.assign(window.lp.analytics.dataLayer[0], { brightcoveID: this.getVideoProperty("id"), brightcoveTitle: this.getVideoProperty("name"), brightcoveDescription: this.getVideoProperty("description") }); } /** * Uses the currently loaded video data to build a block of * LD-JSON Schema.org markup and appends it to the "head" tag * * This is run automatically when any video is loaded. */ }, { key: "renderSEOMarkup", value: function renderSEOMarkup() { if (!this.player || !this.player.mediainfo) { return; } var videoId = this.getVideoProperty("id"); var scriptId = "ldjson-video-" + videoId; var script = document.getElementById(scriptId); if (script) { return; } var defaultDescription = ""; try { defaultDescription = window.lp.place.name; } catch (e) {} // Duration must be in ISO 8601 format // https://en.wikipedia.org/wiki/ISO_8601#Durations // Brightcove returns the number of seconds (ex. 161.685) var seconds = Math.ceil(this.getVideoProperty("duration")); var duration = "PT" + seconds + "S"; var embedUrl = "https://players.brightcove.net/5104226627001/default_default/index.html?videoId=" + videoId; var data = { "@context": "http://schema.org", "@type": "VideoObject", "name": this.getVideoProperty("name") || defaultDescription, "description": this.getVideoProperty("description") || defaultDescription, "thumbnailURL": this.getVideoProperty("poster"), "embedURL": embedUrl, "duration": duration, "uploadDate": this.getVideoProperty("createdAt") }; script = document.createElement("script"); script.id = scriptId; script.type = "application/ld+json"; script.innerHTML = JSON.stringify(data); document.getElementsByTagName("head")[0].appendChild(script); } }, { key: "videoEl", get: function get() { if (this.$el.hasClass("video-js")) { return this.el; } return this.$el.find(".video-js")[0]; } }]); return Brightcove; }(_video_player2.default); exports.default = Brightcove;