diff --git a/api/js/etemplate/et2_widget_video.js b/api/js/etemplate/et2_widget_video.js index 4fb2825c3e..0e36799ec9 100644 --- a/api/js/etemplate/et2_widget_video.js +++ b/api/js/etemplate/et2_widget_video.js @@ -77,11 +77,14 @@ var et2_video = /** @class */ (function (_super) { .appendTo(_this.video) .attr('id', et2_video.youtubePrefixId + _this.id); _this.video.attr('id', _this.id); - //Load youtube iframe api - var tag = document.createElement('script'); - tag.src = "https://www.youtube.com/iframe_api"; - var firstScriptTag = document.getElementsByTagName('script')[0]; - firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); + if (!document.getElementById('youtube-api-script')) { + //Load youtube iframe api + var tag = document.createElement('script'); + tag.id = 'youtube-api-script'; + tag.src = "https://www.youtube.com/iframe_api"; + var firstScriptTag = document.getElementsByTagName('script')[0]; + firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); + } } if (!_this._isYoutube() && _this.options.controls) { _this.video.attr("controls", 1); @@ -117,30 +120,13 @@ var et2_video = /** @class */ (function (_super) { } } else if (_value) { - //initiate youtube Api object, it gets called automatically by iframe_api script from the api - // @ts-ignore - window.onYouTubeIframeAPIReady = function () { - // @ts-ignore - self.youtube = new YT.Player(et2_video.youtubePrefixId + self.id, { - height: '400', - width: '100%', - playerVars: { - 'autoplay': 0, - 'controls': 0, - 'modestbranding': 1, - 'fs': 0, - 'disablekb': 1, - 'rel': 0, - 'iv_load_policy': 0, - 'cc_load_policy': 0 - }, - videoId: _value.match(et2_video.youtubeRegexp)[4], - events: { - 'onReady': jQuery.proxy(self._onReady, self), - 'onStateChange': jQuery.proxy(self._onStateChangeYoutube, self) - } - }); - }; + if (typeof YT == 'undefined') { + //initiate youtube Api object, it gets called automatically by iframe_api script from the api + window.onYouTubeIframeAPIReady = this._onYoutubeIframeAPIReady; + } + window.addEventListener('et2_video.onYoutubeIframeAPIReady', function () { + self._createYoutubePlayer(self.options.video_src); + }); } }; /** @@ -310,6 +296,11 @@ var et2_video = /** @class */ (function (_super) { self._onTimeUpdate(); }); } + else { + // need to create the player after the DOM is ready otherwise player won't show up + if (window.YT) + this._createYoutubePlayer(this.options.video_src); + } return false; }; et2_video.prototype.videoLoadnigIsFinished = function () { @@ -355,6 +346,42 @@ var et2_video = /** @class */ (function (_super) { } console.log(_data); }; + /** + * youtube on IframeAPI ready event + */ + et2_video.prototype._onYoutubeIframeAPIReady = function () { + var event = document.createEvent("Event"); + event.initEvent('et2_video.onYoutubeIframeAPIReady', true, true); + window.dispatchEvent(event); + }; + /** + * create youtube player + * + * @param _value + */ + et2_video.prototype._createYoutubePlayer = function (_value) { + if (typeof YT != 'undefined') { + this.youtube = new YT.Player(et2_video.youtubePrefixId + this.id, { + height: this.options.height || '400', + width: '100%', + playerVars: { + 'autoplay': 0, + 'controls': 0, + 'modestbranding': 1, + 'fs': 0, + 'disablekb': 1, + 'rel': 0, + 'iv_load_policy': 0, + 'cc_load_policy': 0 + }, + videoId: _value.match(et2_video.youtubeRegexp)[4], + events: { + 'onReady': jQuery.proxy(this._onReady, this), + 'onStateChange': jQuery.proxy(this._onStateChangeYoutube, this) + } + }); + } + }; et2_video._attributes = { "video_src": { "name": "Video", diff --git a/api/js/etemplate/et2_widget_video.ts b/api/js/etemplate/et2_widget_video.ts index 1b7aaa90c6..dae7bb129c 100644 --- a/api/js/etemplate/et2_widget_video.ts +++ b/api/js/etemplate/et2_widget_video.ts @@ -154,12 +154,15 @@ export class et2_video extends et2_baseWidget implements et2_IDOMNode .attr('id', et2_video.youtubePrefixId+this.id); this.video.attr('id', this.id); - - //Load youtube iframe api - let tag = document.createElement('script'); - tag.src = "https://www.youtube.com/iframe_api"; - let firstScriptTag = document.getElementsByTagName('script')[0]; - firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); + if (!document.getElementById('youtube-api-script')) + { + //Load youtube iframe api + let tag = document.createElement('script'); + tag.id = 'youtube-api-script'; + tag.src = "https://www.youtube.com/iframe_api"; + let firstScriptTag = document.getElementsByTagName('script')[0]; + firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); + } } if (!this._isYoutube() && this.options.controls) @@ -205,30 +208,14 @@ export class et2_video extends et2_baseWidget implements et2_IDOMNode } else if(_value) { - //initiate youtube Api object, it gets called automatically by iframe_api script from the api - // @ts-ignore - window.onYouTubeIframeAPIReady = function() { - // @ts-ignore - self.youtube = new YT.Player( et2_video.youtubePrefixId+self.id, { - height: '400', - width: '100%', - playerVars: { - 'autoplay': 0, - 'controls': 0, - 'modestbranding': 1, - 'fs':0, - 'disablekb': 1, - 'rel': 0, - 'iv_load_policy': 0, - 'cc_load_policy': 0 - }, - videoId: _value.match(et2_video.youtubeRegexp)[4], - events: { - 'onReady': jQuery.proxy(self._onReady, self), - 'onStateChange': jQuery.proxy(self._onStateChangeYoutube, self) - } - }); - } + if (typeof YT == 'undefined') + { + //initiate youtube Api object, it gets called automatically by iframe_api script from the api + window.onYouTubeIframeAPIReady = this._onYoutubeIframeAPIReady; + } + window.addEventListener('et2_video.onYoutubeIframeAPIReady', function(){ + self._createYoutubePlayer(self.options.video_src); + }); } } @@ -443,6 +430,11 @@ export class et2_video extends et2_baseWidget implements et2_IDOMNode self._onTimeUpdate(); }); } + else + { + // need to create the player after the DOM is ready otherwise player won't show up + if (window.YT) this._createYoutubePlayer(this.options.video_src); + } return false; } @@ -499,5 +491,46 @@ export class et2_video extends et2_baseWidget implements et2_IDOMNode } console.log(_data) } + + /** + * youtube on IframeAPI ready event + */ + private _onYoutubeIframeAPIReady() + { + let event = document.createEvent("Event"); + event.initEvent('et2_video.onYoutubeIframeAPIReady', true, true); + window.dispatchEvent(event); + } + + /** + * create youtube player + * + * @param _value + */ + private _createYoutubePlayer(_value:string) + { + if (typeof YT != 'undefined') + { + this.youtube = new YT.Player( et2_video.youtubePrefixId+this.id, { + height: this.options.height || '400', + width: '100%', + playerVars: { + 'autoplay': 0, + 'controls': 0, + 'modestbranding': 1, + 'fs':0, + 'disablekb': 1, + 'rel': 0, + 'iv_load_policy': 0, + 'cc_load_policy': 0 + }, + videoId: _value.match(et2_video.youtubeRegexp)[4], + events: { + 'onReady': jQuery.proxy(this._onReady, this), + 'onStateChange': jQuery.proxy(this._onStateChangeYoutube, this) + } + }); + } + } } et2_register_widget(et2_video, ["video"]); \ No newline at end of file diff --git a/api/js/jsapi/egw_global.d.ts b/api/js/jsapi/egw_global.d.ts index c778c30147..1c062cb719 100644 --- a/api/js/jsapi/egw_global.d.ts +++ b/api/js/jsapi/egw_global.d.ts @@ -791,7 +791,7 @@ declare interface IegwWndLocal extends IegwGlobal * @return Promise */ request(_menuaction: string, param2: any[]): Promise; - + /** * Registers a new handler plugin. * @@ -1295,3 +1295,7 @@ declare function egw_getWindowInnerWidth() : number; declare function egw_getWindowInnerHeight() : number; declare function egw_getWindowOuterWidth() : number; declare function egw_getWindowOuterHeight() : number; + +// Youtube API golbal vars +declare var YT : any; +declare function onYouTubeIframeAPIReady();