aboutsummaryrefslogtreecommitdiff
path: root/assets/netcut/lib/videojs-markers/videojs-markers.js
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--assets/netcut/lib/videojs-markers/videojs-markers.js517
-rw-r--r--assets/netcut/lib/videojs-markers/videojs-markers.js.map1
2 files changed, 518 insertions, 0 deletions
diff --git a/assets/netcut/lib/videojs-markers/videojs-markers.js b/assets/netcut/lib/videojs-markers/videojs-markers.js
new file mode 100644
index 0000000..7fc6822
--- /dev/null
+++ b/assets/netcut/lib/videojs-markers/videojs-markers.js
@@ -0,0 +1,517 @@
+(function (global, factory) {
+ if (typeof define === "function" && define.amd) {
+ define(['video.js'], factory);
+ } else if (typeof exports !== "undefined") {
+ factory(require('video.js'));
+ } else {
+ var mod = {
+ exports: {}
+ };
+ factory(global.videojs);
+ global.videojsMarkers = mod.exports;
+ }
+})(this, function (_video) {
+ /*! videojs-markers - v1.0.1 - 2018-04-03
+ * Copyright (c) 2018 ; Licensed */
+ 'use strict';
+
+ var _video2 = _interopRequireDefault(_video);
+
+ function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : {
+ default: obj
+ };
+ }
+
+ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
+ return typeof obj;
+ } : function (obj) {
+ return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
+ };
+
+ // default setting
+ var defaultSetting = {
+ markerStyle: {
+ 'width': '7px',
+ 'border-radius': '30%',
+ 'background-color': 'red'
+ },
+ markerTip: {
+ display: true,
+ text: function text(marker) {
+ return "Break: " + marker.text;
+ },
+ time: function time(marker) {
+ return marker.time;
+ }
+ },
+ breakOverlay: {
+ display: false,
+ displayTime: 3,
+ text: function text(marker) {
+ return "Break overlay: " + marker.overlayText;
+ },
+ style: {
+ 'width': '100%',
+ 'height': '20%',
+ 'background-color': 'rgba(0,0,0,0.7)',
+ 'color': 'white',
+ 'font-size': '17px'
+ }
+ },
+ onMarkerClick: function onMarkerClick(marker) {},
+ onMarkerReached: function onMarkerReached(marker, index) {},
+ markers: []
+ };
+
+ // create a non-colliding random number
+ function generateUUID() {
+ var d = new Date().getTime();
+ var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
+ var r = (d + Math.random() * 16) % 16 | 0;
+ d = Math.floor(d / 16);
+ return (c == 'x' ? r : r & 0x3 | 0x8).toString(16);
+ });
+ return uuid;
+ };
+
+ /**
+ * Returns the size of an element and its position
+ * a default Object with 0 on each of its properties
+ * its return in case there's an error
+ * @param {Element} element el to get the size and position
+ * @return {DOMRect|Object} size and position of an element
+ */
+ function getElementBounding(element) {
+ var elementBounding;
+ var defaultBoundingRect = {
+ top: 0,
+ bottom: 0,
+ left: 0,
+ width: 0,
+ height: 0,
+ right: 0
+ };
+
+ try {
+ elementBounding = element.getBoundingClientRect();
+ } catch (e) {
+ elementBounding = defaultBoundingRect;
+ }
+
+ return elementBounding;
+ }
+
+ var NULL_INDEX = -1;
+
+ function registerVideoJsMarkersPlugin(options) {
+ // copied from video.js/src/js/utils/merge-options.js since
+ // videojs 4 doens't support it by defualt.
+ if (!_video2.default.mergeOptions) {
+ var isPlain = function isPlain(value) {
+ return !!value && (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object' && toString.call(value) === '[object Object]' && value.constructor === Object;
+ };
+
+ var mergeOptions = function mergeOptions(source1, source2) {
+
+ var result = {};
+ var sources = [source1, source2];
+ sources.forEach(function (source) {
+ if (!source) {
+ return;
+ }
+ Object.keys(source).forEach(function (key) {
+ var value = source[key];
+ if (!isPlain(value)) {
+ result[key] = value;
+ return;
+ }
+ if (!isPlain(result[key])) {
+ result[key] = {};
+ }
+ result[key] = mergeOptions(result[key], value);
+ });
+ });
+ return result;
+ };
+
+ _video2.default.mergeOptions = mergeOptions;
+ }
+
+ if (!_video2.default.dom.createEl) {
+ _video2.default.dom.createEl = function (tagName, props, attrs) {
+ var el = _video2.default.Player.prototype.dom.createEl(tagName, props);
+ if (!!attrs) {
+ Object.keys(attrs).forEach(function (key) {
+ el.setAttribute(key, attrs[key]);
+ });
+ }
+ return el;
+ };
+ }
+
+ /**
+ * register the markers plugin (dependent on jquery)
+ */
+ var setting = _video2.default.mergeOptions(defaultSetting, options),
+ markersMap = {},
+ markersList = [],
+ // list of markers sorted by time
+ currentMarkerIndex = NULL_INDEX,
+ player = this,
+ markerTip = null,
+ breakOverlay = null,
+ overlayIndex = NULL_INDEX;
+
+ function sortMarkersList() {
+ // sort the list by time in asc order
+ markersList.sort(function (a, b) {
+ return setting.markerTip.time(a) - setting.markerTip.time(b);
+ });
+ }
+
+ function addMarkers(newMarkers) {
+ newMarkers.forEach(function (marker) {
+ marker.key = generateUUID();
+
+ player.el().querySelector('.vjs-progress-holder').appendChild(createMarkerDiv(marker));
+
+ // store marker in an internal hash map
+ markersMap[marker.key] = marker;
+ markersList.push(marker);
+ });
+
+ sortMarkersList();
+ }
+
+ function getPosition(marker) {
+ return setting.markerTip.time(marker) / player.duration() * 100;
+ }
+
+ function setMarkderDivStyle(marker, markerDiv) {
+ markerDiv.className = 'vjs-marker ' + (marker.class || "");
+
+ Object.keys(setting.markerStyle).forEach(function (key) {
+ markerDiv.style[key] = setting.markerStyle[key];
+ });
+
+ // hide out-of-bound markers
+ var ratio = marker.time / player.duration();
+ if (ratio < 0 || ratio > 1) {
+ markerDiv.style.display = 'none';
+ }
+
+ // set position
+ markerDiv.style.left = getPosition(marker) + '%';
+ if (marker.duration) {
+ markerDiv.style.width = marker.duration / player.duration() * 100 + '%';
+ markerDiv.style.marginLeft = '0px';
+ } else {
+ var markerDivBounding = getElementBounding(markerDiv);
+ markerDiv.style.marginLeft = markerDivBounding.width / 2 + 'px';
+ }
+ }
+
+ function createMarkerDiv(marker) {
+
+ var markerDiv = _video2.default.dom.createEl('div', {}, {
+ 'data-marker-key': marker.key,
+ 'data-marker-time': setting.markerTip.time(marker)
+ });
+
+ setMarkderDivStyle(marker, markerDiv);
+
+ // bind click event to seek to marker time
+ markerDiv.addEventListener('click', function (e) {
+ var preventDefault = false;
+ if (typeof setting.onMarkerClick === "function") {
+ // if return false, prevent default behavior
+ preventDefault = setting.onMarkerClick(marker) === false;
+ }
+
+ if (!preventDefault) {
+ var key = this.getAttribute('data-marker-key');
+ player.currentTime(setting.markerTip.time(markersMap[key]));
+ }
+ });
+
+ if (setting.markerTip.display) {
+ registerMarkerTipHandler(markerDiv);
+ }
+
+ return markerDiv;
+ }
+
+ function updateMarkers(force) {
+ // update UI for markers whose time changed
+ markersList.forEach(function (marker) {
+ var markerDiv = player.el().querySelector(".vjs-marker[data-marker-key='" + marker.key + "']");
+ var markerTime = setting.markerTip.time(marker);
+
+ if (force || markerDiv.getAttribute('data-marker-time') !== markerTime) {
+ setMarkderDivStyle(marker, markerDiv);
+ markerDiv.setAttribute('data-marker-time', markerTime);
+ }
+ });
+ sortMarkersList();
+ }
+
+ function removeMarkers(indexArray) {
+ // reset overlay
+ if (!!breakOverlay) {
+ overlayIndex = NULL_INDEX;
+ breakOverlay.style.visibility = "hidden";
+ }
+ currentMarkerIndex = NULL_INDEX;
+
+ var deleteIndexList = [];
+ indexArray.forEach(function (index) {
+ var marker = markersList[index];
+ if (marker) {
+ // delete from memory
+ delete markersMap[marker.key];
+ deleteIndexList.push(index);
+
+ // delete from dom
+ var el = player.el().querySelector(".vjs-marker[data-marker-key='" + marker.key + "']");
+ el && el.parentNode.removeChild(el);
+ }
+ });
+
+ // clean up markers array
+ deleteIndexList.reverse();
+ deleteIndexList.forEach(function (deleteIndex) {
+ markersList.splice(deleteIndex, 1);
+ });
+
+ // sort again
+ sortMarkersList();
+ }
+
+ // attach hover event handler
+ function registerMarkerTipHandler(markerDiv) {
+ markerDiv.addEventListener('mouseover', function () {
+ var marker = markersMap[markerDiv.getAttribute('data-marker-key')];
+ if (!!markerTip) {
+ markerTip.querySelector('.vjs-tip-inner').innerText = setting.markerTip.text(marker);
+ // margin-left needs to minus the padding length to align correctly with the marker
+ markerTip.style.left = getPosition(marker) + '%';
+ var markerTipBounding = getElementBounding(markerTip);
+ var markerDivBounding = getElementBounding(markerDiv);
+ markerTip.style.marginLeft = -parseFloat(markerTipBounding.width / 2) + parseFloat(markerDivBounding.width / 4) + 'px';
+ markerTip.style.visibility = 'visible';
+ }
+ });
+
+ markerDiv.addEventListener('mouseout', function () {
+ if (!!markerTip) {
+ markerTip.style.visibility = "hidden";
+ }
+ });
+ }
+
+ function initializeMarkerTip() {
+ markerTip = _video2.default.dom.createEl('div', {
+ className: 'vjs-tip',
+ innerHTML: "<div class='vjs-tip-arrow'></div><div class='vjs-tip-inner'></div>"
+ });
+ player.el().querySelector('.vjs-progress-holder').appendChild(markerTip);
+ }
+
+ // show or hide break overlays
+ function updateBreakOverlay() {
+ if (!setting.breakOverlay.display || currentMarkerIndex < 0) {
+ return;
+ }
+
+ var currentTime = player.currentTime();
+ var marker = markersList[currentMarkerIndex];
+ var markerTime = setting.markerTip.time(marker);
+
+ if (currentTime >= markerTime && currentTime <= markerTime + setting.breakOverlay.displayTime) {
+ if (overlayIndex !== currentMarkerIndex) {
+ overlayIndex = currentMarkerIndex;
+ if (breakOverlay) {
+ breakOverlay.querySelector('.vjs-break-overlay-text').innerHTML = setting.breakOverlay.text(marker);
+ }
+ }
+
+ if (breakOverlay) {
+ breakOverlay.style.visibility = "visible";
+ }
+ } else {
+ overlayIndex = NULL_INDEX;
+ if (breakOverlay) {
+ breakOverlay.style.visibility = "hidden";
+ }
+ }
+ }
+
+ // problem when the next marker is within the overlay display time from the previous marker
+ function initializeOverlay() {
+ breakOverlay = _video2.default.dom.createEl('div', {
+ className: 'vjs-break-overlay',
+ innerHTML: "<div class='vjs-break-overlay-text'></div>"
+ });
+ Object.keys(setting.breakOverlay.style).forEach(function (key) {
+ if (breakOverlay) {
+ breakOverlay.style[key] = setting.breakOverlay.style[key];
+ }
+ });
+ player.el().appendChild(breakOverlay);
+ overlayIndex = NULL_INDEX;
+ }
+
+ function onTimeUpdate() {
+ onUpdateMarker();
+ updateBreakOverlay();
+ options.onTimeUpdateAfterMarkerUpdate && options.onTimeUpdateAfterMarkerUpdate();
+ }
+
+ function onUpdateMarker() {
+ /*
+ check marker reached in between markers
+ the logic here is that it triggers a new marker reached event only if the player
+ enters a new marker range (e.g. from marker 1 to marker 2). Thus, if player is on marker 1 and user clicked on marker 1 again, no new reached event is triggered)
+ */
+ if (!markersList.length) {
+ return;
+ }
+
+ var getNextMarkerTime = function getNextMarkerTime(index) {
+ if (index < markersList.length - 1) {
+ return setting.markerTip.time(markersList[index + 1]);
+ }
+ // next marker time of last marker would be end of video time
+ return player.duration();
+ };
+ var currentTime = player.currentTime();
+ var newMarkerIndex = NULL_INDEX;
+
+ if (currentMarkerIndex !== NULL_INDEX) {
+ // check if staying at same marker
+ var nextMarkerTime = getNextMarkerTime(currentMarkerIndex);
+ if (currentTime >= setting.markerTip.time(markersList[currentMarkerIndex]) && currentTime < nextMarkerTime) {
+ return;
+ }
+
+ // check for ending (at the end current time equals player duration)
+ if (currentMarkerIndex === markersList.length - 1 && currentTime === player.duration()) {
+ return;
+ }
+ }
+
+ // check first marker, no marker is selected
+ if (currentTime < setting.markerTip.time(markersList[0])) {
+ newMarkerIndex = NULL_INDEX;
+ } else {
+ // look for new index
+ for (var i = 0; i < markersList.length; i++) {
+ nextMarkerTime = getNextMarkerTime(i);
+ if (currentTime >= setting.markerTip.time(markersList[i]) && currentTime < nextMarkerTime) {
+ newMarkerIndex = i;
+ break;
+ }
+ }
+ }
+
+ // set new marker index
+ if (newMarkerIndex !== currentMarkerIndex) {
+ // trigger event if index is not null
+ if (newMarkerIndex !== NULL_INDEX && options.onMarkerReached) {
+ options.onMarkerReached(markersList[newMarkerIndex], newMarkerIndex);
+ }
+ currentMarkerIndex = newMarkerIndex;
+ }
+ }
+
+ // setup the whole thing
+ function initialize() {
+ if (setting.markerTip.display) {
+ initializeMarkerTip();
+ }
+
+ // remove existing markers if already initialized
+ player.markers.removeAll();
+ addMarkers(setting.markers);
+
+ if (setting.breakOverlay.display) {
+ initializeOverlay();
+ }
+ onTimeUpdate();
+ player.on("timeupdate", onTimeUpdate);
+ player.off("loadedmetadata");
+ }
+
+ // setup the plugin after we loaded video's meta data
+ player.on("loadedmetadata", function () {
+ initialize();
+ });
+
+ // exposed plugin API
+ player.markers = {
+ getMarkers: function getMarkers() {
+ return markersList;
+ },
+ next: function next() {
+ // go to the next marker from current timestamp
+ var currentTime = player.currentTime();
+ for (var i = 0; i < markersList.length; i++) {
+ var markerTime = setting.markerTip.time(markersList[i]);
+ if (markerTime > currentTime) {
+ player.currentTime(markerTime);
+ break;
+ }
+ }
+ },
+ prev: function prev() {
+ // go to previous marker
+ var currentTime = player.currentTime();
+ for (var i = markersList.length - 1; i >= 0; i--) {
+ var markerTime = setting.markerTip.time(markersList[i]);
+ // add a threshold
+ if (markerTime + 0.5 < currentTime) {
+ player.currentTime(markerTime);
+ return;
+ }
+ }
+ },
+ add: function add(newMarkers) {
+ // add new markers given an array of index
+ addMarkers(newMarkers);
+ },
+ remove: function remove(indexArray) {
+ // remove markers given an array of index
+ removeMarkers(indexArray);
+ },
+ removeAll: function removeAll() {
+ var indexArray = [];
+ for (var i = 0; i < markersList.length; i++) {
+ indexArray.push(i);
+ }
+ removeMarkers(indexArray);
+ },
+ // force - force all markers to be updated, regardless of if they have changed or not.
+ updateTime: function updateTime(force) {
+ // notify the plugin to update the UI for changes in marker times
+ updateMarkers(force);
+ },
+ reset: function reset(newMarkers) {
+ // remove all the existing markers and add new ones
+ player.markers.removeAll();
+ addMarkers(newMarkers);
+ },
+ destroy: function destroy() {
+ // unregister the plugins and clean up even handlers
+ player.markers.removeAll();
+ breakOverlay && breakOverlay.remove();
+ markerTip && markerTip.remove();
+ player.off("timeupdate", updateBreakOverlay);
+ delete player.markers;
+ }
+ };
+ }
+
+ _video2.default.registerPlugin('markers', registerVideoJsMarkersPlugin);
+});
+//# sourceMappingURL=videojs-markers.js.map
diff --git a/assets/netcut/lib/videojs-markers/videojs-markers.js.map b/assets/netcut/lib/videojs-markers/videojs-markers.js.map
new file mode 100644
index 0000000..0dbedd3
--- /dev/null
+++ b/assets/netcut/lib/videojs-markers/videojs-markers.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["videojs-markers.js"],"names":["defaultSetting","markerStyle","markerTip","display","text","marker","time","breakOverlay","displayTime","overlayText","style","onMarkerClick","onMarkerReached","index","markers","generateUUID","d","Date","getTime","uuid","replace","c","r","Math","random","floor","toString","getElementBounding","element","elementBounding","defaultBoundingRect","top","bottom","left","width","height","right","getBoundingClientRect","e","NULL_INDEX","registerVideoJsMarkersPlugin","options","mergeOptions","isPlain","value","call","constructor","Object","source1","source2","result","sources","forEach","source","keys","key","dom","createEl","tagName","props","attrs","el","Player","prototype","setAttribute","setting","markersMap","markersList","currentMarkerIndex","player","overlayIndex","sortMarkersList","sort","a","b","addMarkers","newMarkers","querySelector","appendChild","createMarkerDiv","push","getPosition","duration","setMarkderDivStyle","markerDiv","className","class","ratio","marginLeft","markerDivBounding","addEventListener","preventDefault","getAttribute","currentTime","registerMarkerTipHandler","updateMarkers","force","markerTime","removeMarkers","indexArray","visibility","deleteIndexList","parentNode","removeChild","reverse","deleteIndex","splice","innerText","markerTipBounding","parseFloat","initializeMarkerTip","innerHTML","updateBreakOverlay","initializeOverlay","onTimeUpdate","onUpdateMarker","onTimeUpdateAfterMarkerUpdate","length","getNextMarkerTime","newMarkerIndex","nextMarkerTime","i","initialize","removeAll","on","off","getMarkers","next","prev","add","remove","updateTime","reset","destroy","registerPlugin"],"mappings":"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","file":"videojs-markers.js","sourcesContent":["/*! videojs-markers - v1.0.1 - 2018-04-03\n* Copyright (c) 2018 ; Licensed */\n'use strict';\n\nimport videojs from 'video.js';\n\ntype Marker = {\n time: number,\n duration: number,\n text?: string,\n class?: string,\n overlayText?: string,\n // private property\n key: string,\n};\n\n// default setting\nconst defaultSetting = {\n markerStyle: {\n 'width':'7px',\n 'border-radius': '30%',\n 'background-color': 'red',\n },\n markerTip: {\n display: true,\n text: function(marker) {\n return \"Break: \" + marker.text;\n },\n time: function(marker) {\n return marker.time;\n },\n },\n breakOverlay:{\n display: false,\n displayTime: 3,\n text: function(marker) {\n return \"Break overlay: \" + marker.overlayText;\n },\n style: {\n 'width':'100%',\n 'height': '20%',\n 'background-color': 'rgba(0,0,0,0.7)',\n 'color': 'white',\n 'font-size': '17px',\n },\n },\n onMarkerClick: function(marker) {},\n onMarkerReached: function(marker, index) {},\n markers: [],\n};\n\n// create a non-colliding random number\nfunction generateUUID(): string {\n var d = new Date().getTime();\n var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n var r = (d + Math.random()*16)%16 | 0;\n d = Math.floor(d/16);\n return (c=='x' ? r : (r&0x3|0x8)).toString(16);\n });\n return uuid;\n};\n\n/**\n * Returns the size of an element and its position\n * a default Object with 0 on each of its properties\n * its return in case there's an error\n * @param {Element} element el to get the size and position\n * @return {DOMRect|Object} size and position of an element\n */\nfunction getElementBounding(element) {\n var elementBounding;\n const defaultBoundingRect = {\n top: 0,\n bottom: 0,\n left: 0,\n width: 0,\n height: 0,\n right: 0\n };\n\n try {\n elementBounding = element.getBoundingClientRect();\n } catch (e) {\n elementBounding = defaultBoundingRect;\n }\n\n return elementBounding;\n}\n\nconst NULL_INDEX = -1;\n\nfunction registerVideoJsMarkersPlugin(options) {\n // copied from video.js/src/js/utils/merge-options.js since\n // videojs 4 doens't support it by defualt.\n if (!videojs.mergeOptions) {\n function isPlain(value) {\n return !!value && typeof value === 'object' &&\n toString.call(value) === '[object Object]' &&\n value.constructor === Object;\n }\n function mergeOptions(source1: Object, source2: Object) {\n\n const result = {};\n const sources = [source1, source2];\n sources.forEach(source => {\n if (!source) {\n return;\n }\n Object.keys(source).forEach(key => {\n let value = source[key];\n if (!isPlain(value)) {\n result[key] = value;\n return;\n }\n if (!isPlain(result[key])) {\n result[key] = {};\n }\n result[key] = mergeOptions(result[key], value);\n })\n });\n return result;\n }\n videojs.mergeOptions = mergeOptions;\n }\n\n if (!videojs.dom.createEl) {\n videojs.dom.createEl = function(tagName: string, props: Object, attrs?: Object): void {\n const el = videojs.Player.prototype.dom.createEl(tagName, props);\n if (!!attrs) {\n Object.keys(attrs).forEach(key => {\n el.setAttribute(key, attrs[key]);\n });\n }\n return el;\n }\n }\n \n\n /**\n * register the markers plugin (dependent on jquery)\n */\n let setting = videojs.mergeOptions(defaultSetting, options),\n markersMap: {[key:string]: Marker} = {},\n markersList: Array<Marker> = [], // list of markers sorted by time\n currentMarkerIndex = NULL_INDEX,\n player = this,\n markerTip = null,\n breakOverlay = null,\n overlayIndex = NULL_INDEX;\n\n function sortMarkersList(): void {\n // sort the list by time in asc order\n markersList.sort((a, b) => {\n return setting.markerTip.time(a) - setting.markerTip.time(b);\n });\n }\n\n function addMarkers(newMarkers: Array<Marker>): void {\n newMarkers.forEach((marker: Marker) => {\n marker.key = generateUUID();\n\n player.el().querySelector('.vjs-progress-holder')\n .appendChild(createMarkerDiv(marker));\n\n // store marker in an internal hash map\n markersMap[marker.key] = marker;\n markersList.push(marker);\n })\n\n sortMarkersList();\n }\n\n function getPosition(marker: Marker): number {\n return (setting.markerTip.time(marker) / player.duration()) * 100;\n }\n\n function setMarkderDivStyle(marker: Marker, markerDiv: Object): void {\n markerDiv.className = `vjs-marker ${marker.class || \"\"}`;\n\n Object.keys(setting.markerStyle).forEach(key => {\n markerDiv.style[key] = setting.markerStyle[key];\n });\n\n // hide out-of-bound markers\n const ratio = marker.time / player.duration();\n if (ratio < 0 || ratio > 1) {\n markerDiv.style.display = 'none';\n }\n\n // set position\n markerDiv.style.left = getPosition(marker) + '%';\n if (marker.duration) {\n markerDiv.style.width = (marker.duration / player.duration()) * 100 + '%';\n markerDiv.style.marginLeft = '0px';\n } else {\n const markerDivBounding = getElementBounding(markerDiv);\n markerDiv.style.marginLeft = markerDivBounding.width / 2 + 'px';\n } \n }\n\n function createMarkerDiv(marker: Marker): Object {\n\n var markerDiv = videojs.dom.createEl('div', {}, {\n 'data-marker-key': marker.key,\n 'data-marker-time': setting.markerTip.time(marker)\n });\n\n setMarkderDivStyle(marker, markerDiv);\n\n // bind click event to seek to marker time\n markerDiv.addEventListener('click', function(e) {\n var preventDefault = false;\n if (typeof setting.onMarkerClick === \"function\") {\n // if return false, prevent default behavior\n preventDefault = setting.onMarkerClick(marker) === false;\n }\n\n if (!preventDefault) {\n var key = this.getAttribute('data-marker-key');\n player.currentTime(setting.markerTip.time(markersMap[key]));\n }\n });\n\n if (setting.markerTip.display) {\n registerMarkerTipHandler(markerDiv);\n }\n\n return markerDiv;\n }\n\n function updateMarkers(force: boolean): void {\n // update UI for markers whose time changed\n markersList.forEach((marker: Marker) => {\n var markerDiv = player.el().querySelector(\".vjs-marker[data-marker-key='\" + marker.key +\"']\");\n var markerTime = setting.markerTip.time(marker);\n\n if (force || markerDiv.getAttribute('data-marker-time') !== markerTime) {\n setMarkderDivStyle(marker, markerDiv);\n markerDiv.setAttribute('data-marker-time', markerTime);\n }\n });\n sortMarkersList();\n }\n\n function removeMarkers(indexArray: Array<number>): void {\n // reset overlay\n if (!!breakOverlay){\n overlayIndex = NULL_INDEX;\n breakOverlay.style.visibility = \"hidden\";\n }\n currentMarkerIndex = NULL_INDEX;\n\n let deleteIndexList: Array<number> = [];\n indexArray.forEach((index: number) => {\n let marker = markersList[index];\n if (marker) {\n // delete from memory\n delete markersMap[marker.key];\n deleteIndexList.push(index);\n\n // delete from dom\n let el = player.el().querySelector(\".vjs-marker[data-marker-key='\" + marker.key +\"']\");\n el && el.parentNode.removeChild(el);\n }\n });\n\n // clean up markers array\n deleteIndexList.reverse();\n deleteIndexList.forEach((deleteIndex: number) => {\n markersList.splice(deleteIndex, 1);\n });\n\n // sort again\n sortMarkersList();\n }\n\n // attach hover event handler\n function registerMarkerTipHandler(markerDiv: Object): void {\n markerDiv.addEventListener('mouseover', () => {\n var marker = markersMap[markerDiv.getAttribute('data-marker-key')];\n if (!!markerTip) {\n markerTip.querySelector('.vjs-tip-inner').innerText = setting.markerTip.text(marker);\n // margin-left needs to minus the padding length to align correctly with the marker\n markerTip.style.left = getPosition(marker) + '%';\n var markerTipBounding = getElementBounding(markerTip);\n var markerDivBounding = getElementBounding(markerDiv);\n markerTip.style.marginLeft = \n -parseFloat(markerTipBounding.width / 2) + parseFloat(markerDivBounding.width / 4) + 'px';\n markerTip.style.visibility = 'visible';\n }\n });\n\n markerDiv.addEventListener('mouseout',() => {\n if (!!markerTip) {\n markerTip.style.visibility = \"hidden\";\n }\n });\n }\n\n function initializeMarkerTip(): void {\n markerTip = videojs.dom.createEl('div', {\n className: 'vjs-tip',\n innerHTML: \"<div class='vjs-tip-arrow'></div><div class='vjs-tip-inner'></div>\",\n });\n player.el().querySelector('.vjs-progress-holder').appendChild(markerTip);\n }\n\n // show or hide break overlays\n function updateBreakOverlay(): void {\n if (!setting.breakOverlay.display || currentMarkerIndex < 0) {\n return;\n }\n\n var currentTime = player.currentTime();\n var marker = markersList[currentMarkerIndex];\n var markerTime = setting.markerTip.time(marker);\n\n if (\n currentTime >= markerTime &&\n currentTime <= (markerTime + setting.breakOverlay.displayTime)\n ) {\n if (overlayIndex !== currentMarkerIndex) {\n overlayIndex = currentMarkerIndex;\n if (breakOverlay) {\n breakOverlay.querySelector('.vjs-break-overlay-text').innerHTML = setting.breakOverlay.text(marker);\n }\n }\n\n if (breakOverlay) {\n breakOverlay.style.visibility = \"visible\";\n }\n } else {\n overlayIndex = NULL_INDEX;\n if (breakOverlay) {\n breakOverlay.style.visibility = \"hidden\";\n }\n }\n }\n\n // problem when the next marker is within the overlay display time from the previous marker\n function initializeOverlay(): void {\n breakOverlay = videojs.dom.createEl('div', {\n className: 'vjs-break-overlay',\n innerHTML: \"<div class='vjs-break-overlay-text'></div>\"\n });\n Object.keys(setting.breakOverlay.style).forEach(key => {\n if (breakOverlay) {\n breakOverlay.style[key] = setting.breakOverlay.style[key];\n }\n });\n player.el().appendChild(breakOverlay);\n overlayIndex = NULL_INDEX;\n }\n\n function onTimeUpdate(): void {\n onUpdateMarker();\n updateBreakOverlay();\n options.onTimeUpdateAfterMarkerUpdate && options.onTimeUpdateAfterMarkerUpdate();\n }\n\n function onUpdateMarker() {\n /*\n check marker reached in between markers\n the logic here is that it triggers a new marker reached event only if the player\n enters a new marker range (e.g. from marker 1 to marker 2). Thus, if player is on marker 1 and user clicked on marker 1 again, no new reached event is triggered)\n */\n if (!markersList.length) {\n return;\n }\n\n var getNextMarkerTime = (index: number) => {\n if (index < markersList.length - 1) {\n return setting.markerTip.time(markersList[index + 1]);\n }\n // next marker time of last marker would be end of video time\n return player.duration();\n }\n var currentTime = player.currentTime();\n var newMarkerIndex = NULL_INDEX;\n\n if (currentMarkerIndex !== NULL_INDEX) {\n // check if staying at same marker\n var nextMarkerTime = getNextMarkerTime(currentMarkerIndex);\n if(\n currentTime >= setting.markerTip.time(markersList[currentMarkerIndex]) &&\n currentTime < nextMarkerTime\n ) {\n return;\n }\n\n // check for ending (at the end current time equals player duration)\n if (\n currentMarkerIndex === markersList.length - 1 &&\n currentTime === player.duration()\n ) {\n return;\n }\n }\n\n // check first marker, no marker is selected\n if (currentTime < setting.markerTip.time(markersList[0])) {\n newMarkerIndex = NULL_INDEX;\n } else {\n // look for new index\n for (var i = 0; i < markersList.length; i++) {\n nextMarkerTime = getNextMarkerTime(i);\n if (\n currentTime >= setting.markerTip.time(markersList[i]) &&\n currentTime < nextMarkerTime\n ) {\n newMarkerIndex = i;\n break;\n }\n }\n }\n\n // set new marker index\n if (newMarkerIndex !== currentMarkerIndex) {\n // trigger event if index is not null\n if (newMarkerIndex !== NULL_INDEX && options.onMarkerReached) {\n options.onMarkerReached(markersList[newMarkerIndex], newMarkerIndex);\n }\n currentMarkerIndex = newMarkerIndex;\n }\n }\n\n // setup the whole thing\n function initialize(): void {\n if (setting.markerTip.display) {\n initializeMarkerTip();\n }\n\n // remove existing markers if already initialized\n player.markers.removeAll();\n addMarkers(setting.markers);\n\n if (setting.breakOverlay.display) {\n initializeOverlay();\n }\n onTimeUpdate();\n player.on(\"timeupdate\", onTimeUpdate);\n player.off(\"loadedmetadata\");\n }\n\n // setup the plugin after we loaded video's meta data\n player.on(\"loadedmetadata\", function() {\n initialize();\n });\n\n // exposed plugin API\n player.markers = {\n getMarkers: function(): Array<Marker> {\n return markersList;\n },\n next : function(): void {\n // go to the next marker from current timestamp\n const currentTime = player.currentTime();\n for (var i = 0; i < markersList.length; i++) {\n var markerTime = setting.markerTip.time(markersList[i]);\n if (markerTime > currentTime) {\n player.currentTime(markerTime);\n break;\n }\n }\n },\n prev : function(): void {\n // go to previous marker\n const currentTime = player.currentTime();\n for (var i = markersList.length - 1; i >= 0 ; i--) {\n var markerTime = setting.markerTip.time(markersList[i]);\n // add a threshold\n if (markerTime + 0.5 < currentTime) {\n player.currentTime(markerTime);\n return;\n }\n }\n },\n add : function(newMarkers: Array<Marker>): void {\n // add new markers given an array of index\n addMarkers(newMarkers);\n },\n remove: function(indexArray: Array<number>): void {\n // remove markers given an array of index\n removeMarkers(indexArray);\n },\n removeAll: function(): void {\n var indexArray = [];\n for (var i = 0; i < markersList.length; i++) {\n indexArray.push(i);\n }\n removeMarkers(indexArray);\n },\n // force - force all markers to be updated, regardless of if they have changed or not.\n updateTime: function(force: boolean): void {\n // notify the plugin to update the UI for changes in marker times\n updateMarkers(force);\n },\n reset: function(newMarkers: Array<Marker>): void {\n // remove all the existing markers and add new ones\n player.markers.removeAll();\n addMarkers(newMarkers);\n },\n destroy: function(): void {\n // unregister the plugins and clean up even handlers\n player.markers.removeAll();\n breakOverlay && breakOverlay.remove();\n markerTip && markerTip.remove();\n player.off(\"timeupdate\", updateBreakOverlay);\n delete player.markers;\n },\n };\n}\n\nvideojs.registerPlugin('markers', registerVideoJsMarkersPlugin);\n"]} \ No newline at end of file