Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix DOM leaks #365

Merged
merged 1 commit into from
Jul 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dist/ovenplayer.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/ovenplayer.js.map

Large diffs are not rendered by default.

8 changes: 7 additions & 1 deletion src/js/api/provider/html5/providers/WebRTCLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,10 @@ const WebRTCLoader = function (provider,

let currentBrowser = analUserAgent();

let existingHandler = null;

(function () {
let existingHandler = window.onbeforeunload;
existingHandler = window.onbeforeunload;
window.onbeforeunload = function (event) {
if (existingHandler) {
existingHandler(event);
Expand All @@ -79,6 +81,7 @@ const WebRTCLoader = function (provider,
}
})();


function getPeerConnectionById(id) {

let peerConnection = null;
Expand Down Expand Up @@ -989,6 +992,9 @@ const WebRTCLoader = function (provider,

wsClosedByPlayer = true;
closePeer();

window.onbeforeunload = existingHandler;
existingHandler = null;
};

return that;
Expand Down
6 changes: 3 additions & 3 deletions src/js/ovenplayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ function ovenPlayerFactory() {

OvenPlayer.create = function (container, options) {

console.log("[OvenPlayer] v."+ version);

let containerElement = checkAndGetContainerElement(container);

let player = View(containerElement);
Expand All @@ -21,10 +19,12 @@ function ovenPlayerFactory() {

player.setApi(playerInstance);

OvenPlayerConsole.log("[OvenPlayer] v."+ version);

return playerInstance;
};

return OvenPlayer;
}

export default ovenPlayerFactory()
export default ovenPlayerFactory()
169 changes: 168 additions & 1 deletion src/js/utils/resize-sensor.js
Original file line number Diff line number Diff line change
@@ -1 +1,168 @@
!function(a,b){"function"==typeof define&&define.amd?define([],function(){return a.returnExportsGlobal=b()}):"object"==typeof exports?module.exports=b():a.ResizeSensor=b()}(this,function(){var a=function(){"use strict";function a(){this.q=[],this.add=function(a){this.q.push(a)};var a,b;this.call=function(){for(a=0,b=this.q.length;b>a;a++)this.q[a].call()}}function b(a,b){return a.currentStyle?a.currentStyle[b]:window.getComputedStyle?window.getComputedStyle(a,null).getPropertyValue(b):a.style[b]}function c(c,e){if(c.resizedAttached){if(c.resizedAttached)return void c.resizedAttached.add(e)}else c.resizedAttached=new a,c.resizedAttached.add(e);c.resizeSensor=document.createElement("div"),c.resizeSensor.className="resize-sensor";var f="position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: hidden; z-index: -1; visibility: hidden; opacity: 0;",g="position: absolute; left: 0; top: 0; transition: 0s;";c.resizeSensor.style.cssText=f,c.resizeSensor.innerHTML='<div class="resize-sensor-expand" style="'+f+'"><div style="'+g+'"></div></div><div class="resize-sensor-shrink" style="'+f+'"><div style="'+g+' width: 200%; height: 200%"></div></div>',c.appendChild(c.resizeSensor),"static"==b(c,"position")&&(c.style.position="relative");var h=c.resizeSensor.childNodes[0],i=h.childNodes[0],j=c.resizeSensor.childNodes[1],k=function(){i.style.width=1e5+"px",i.style.height=1e5+"px",h.scrollLeft=1e5,h.scrollTop=1e5,j.scrollLeft=1e5,j.scrollTop=1e5};k();var l=!1,m=function(){c.resizedAttached&&(l&&(c.resizedAttached.call(),l=!1),d(m))};d(m);var n,o,p,q,r=function(){((p=c.offsetWidth)!=n||(q=c.offsetHeight)!=o)&&(l=!0,n=p,o=q),k()},s=function(a,b,c){a.attachEvent?a.attachEvent("on"+b,c):a.addEventListener(b,c)};s(h,"scroll",r),s(j,"scroll",r)}var d=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||function(a){return window.setTimeout(a,20)},e=function(a,b){var d=this,e=Object.prototype.toString.call(a),f=d._isCollectionTyped="[object Array]"===e||"[object NodeList]"===e||"[object HTMLCollection]"===e||"undefined"!=typeof jQuery&&a instanceof window.jQuery||"undefined"!=typeof Elements&&a instanceof window.Elements;if(d._element=a,f)for(var g=0,h=a.length;h>g;g++)c(a[g],b);else c(a,b)};return e.prototype.detach=function(){var a=this,b=a._isCollectionTyped,c=a._element;if(b)for(var d=0,f=c.length;f>d;d++)e.detach(c[d]);else e.detach(c)},e.detach=function(a){a.resizeSensor&&(a.removeChild(a.resizeSensor),delete a.resizeSensor,delete a.resizedAttached)},e}();return a});
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define([], function () {
return (root.returnExportsGlobal = factory());
});
} else if (typeof exports === 'object') {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like enviroments that support module.exports,
// like Node.
module.exports = factory();
} else {
root['ResizeSensor'] = factory();
}
}(this, function () {

var ResizeSensor = function () {
'use strict';
var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || function (fn) {
return window.setTimeout(fn, 20);
};
/**
*
* @constructor
*/
function EventQueue() {
this.q = [];
this.add = function (ev) {
this.q.push(ev);
};
var i, j;
this.call = function () {
for (i = 0, j = this.q.length; i < j; i++) {
this.q[i].call();
}
};
}
/**
* @param {HTMLElement} element
* @param {String} prop
* @returns {String|Number}
*/
function getComputedStyle(element, prop) {
if (element.currentStyle) {
return element.currentStyle[prop];
} else if (window.getComputedStyle) {
return window.getComputedStyle(element, null).getPropertyValue(prop);
} else {
return element.style[prop];
}
}
/**
*
* @param {HTMLElement} element
* @param {Function} resized
*/
function attachResizeEvent(element, resized) {
if (!element.resizedAttached) {
element.resizedAttached = new EventQueue();
element.resizedAttached.add(resized);
} else if (element.resizedAttached) {
element.resizedAttached.add(resized);
return;
}
element.resizeSensor = document.createElement('div');
element.resizeSensor.className = 'resize-sensor';
var style = 'position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: hidden; z-index: -1; visibility: hidden; opacity: 0;direction: ltr;';
var styleChild = 'position: absolute; left: 0; top: 0; transition: 0s;';
element.resizeSensor.style.cssText = style;
element.resizeSensor.innerHTML = '<div class="resize-sensor-expand" style="' + style + '">' + '<div style="' + styleChild + '"></div>' + '</div>' + '<div class="resize-sensor-shrink" style="' + style + '">' + '<div style="' + styleChild + ' width: 200%; height: 200%"></div>' + '</div>';
element.appendChild(element.resizeSensor);
if (getComputedStyle(element, 'position') == 'static') {
element.style.position = 'relative';
}
var expand = element.resizeSensor.childNodes[0];
var expandChild = expand.childNodes[0];
var shrink = element.resizeSensor.childNodes[1];
var reset = function () {
expandChild.style.width = 100000 + 'px';
expandChild.style.height = 100000 + 'px';
expand.scrollLeft = 100000;
expand.scrollTop = 100000;
shrink.scrollLeft = 100000;
shrink.scrollTop = 100000;
};
reset();
var dirty = false;
var dirtyChecking = function () {
if (!element.resizedAttached)
return;
if (dirty) {
element.resizedAttached.call();
dirty = false;
}
requestAnimationFrame(dirtyChecking);
};
requestAnimationFrame(dirtyChecking);
var lastWidth, lastHeight;
var cachedWidth, cachedHeight;
//useful to not query offsetWidth twice
var onScroll = function () {
if ((cachedWidth = element.offsetWidth) != lastWidth || (cachedHeight = element.offsetHeight) != lastHeight) {
dirty = true;
lastWidth = cachedWidth;
lastHeight = cachedHeight;
}
reset();
};
var addEvent = function (el, name, cb) {
if (el.attachEvent) {
el.attachEvent('on' + name, cb);
} else {
el.addEventListener(name, cb);
}
};
addEvent(expand, 'scroll', onScroll);
addEvent(shrink, 'scroll', onScroll);
}
/**
* Class for dimension change detection.
*
* @param {Element|Element[]|Elements|jQuery} element
* @param {Function} callback
*
* @constructor
*/
var ResizeSensor = function (element, callback) {
var me = this;
var elementType = Object.prototype.toString.call(element);
var isCollectionTyped = me._isCollectionTyped = '[object Array]' === elementType || '[object NodeList]' === elementType || '[object HTMLCollection]' === elementType || 'undefined' !== typeof jQuery && element instanceof window.jQuery || 'undefined' !== typeof Elements && element instanceof window.Elements;
me._element = element;
if (isCollectionTyped) {
var i = 0, j = element.length;
for (; i < j; i++) {
attachResizeEvent(element[i], callback);
}
} else {
attachResizeEvent(element, callback);
}
};
ResizeSensor.prototype.detach = function () {
var me = this;
var isCollectionTyped = me._isCollectionTyped;
var element = me._element;
if (isCollectionTyped) {
var i = 0, j = element.length;
for (; i < j; i++) {
ResizeSensor.detach(element[i]);
}
} else {
ResizeSensor.detach(element);
}
};
ResizeSensor.detach = function (element) {
if (element.resizeSensor) {
if (element.hasChildNodes()) {
element.removeChild(element.resizeSensor);
}
delete element.resizeSensor;
delete element.resizedAttached;
}
};
return ResizeSensor;
}();

return ResizeSensor;

}));
18 changes: 7 additions & 11 deletions src/js/view/components/controls/fullScreenButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const FullScreenButton = function($container, api){
let browserInfo = api.getBrowser();
let isIos = browserInfo.os === "iOS"; // && browserInfo.browser === "Safari";
let isAndroid = browserInfo.os === "Android";
let fullscreenChagedEventName = ""; //For IE11
let fullscreenChangedEventName = ""; //For IE11
let isForceMode = false; //This means to look like for fullscreen.

let fullScreenEventTypes = {
Expand Down Expand Up @@ -96,7 +96,7 @@ const FullScreenButton = function($container, api){
function findFullScreenChangedEventName(){
let rootElement = $root.get();
let eventName = "";
//ios don;t have a fullscreenchage event. go to hell.
//ios don;t have a fullscreenchange event. go to hell.
//ios will checkFullScreen();

if (rootElement.requestFullscreen) {
Expand Down Expand Up @@ -257,9 +257,9 @@ const FullScreenButton = function($container, api){

resetFullscreenButtonState();

fullscreenChagedEventName = findFullScreenChangedEventName();
if(fullscreenChagedEventName){
document.addEventListener(fullscreenChagedEventName, afterFullScreenChangedCallback, false);
fullscreenChangedEventName = findFullScreenChangedEventName();
if(fullscreenChangedEventName){
document.addEventListener(fullscreenChangedEventName, afterFullScreenChangedCallback, false);
}

api.on(AD_CHANGED, function(ad){
Expand Down Expand Up @@ -290,12 +290,8 @@ const FullScreenButton = function($container, api){


const onDestroyed = function(template){

if (api.getConfig() && !api.getConfig().expandFullScreenUI) {

if(fullscreenChagedEventName){
document.removeEventListener(fullscreenChagedEventName, afterFullScreenChangedCallback);
}
if (fullscreenChangedEventName){
document.removeEventListener(fullscreenChangedEventName, afterFullScreenChangedCallback);
}

api.off(AD_CHANGED, null, template);
Expand Down
8 changes: 7 additions & 1 deletion src/js/view/view.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const View = function($container){
let panelManager = PanelManager();
let screenSize = "";
let currentPlayerSize = "";
let resizeSensor = null;

let that = {};

Expand Down Expand Up @@ -136,7 +137,7 @@ const View = function($container){
viewTemplate = template;
calcPlayerWidth();
currentPlayerSize = screenSize;
new ResizeSensor($playerRoot.get(), function() {
resizeSensor = new ResizeSensor($playerRoot.get(), function() {

$playerRoot.removeClass("large");
$playerRoot.removeClass("medium");
Expand All @@ -154,6 +155,11 @@ const View = function($container){

};
const onDestroyed = function(){
if(resizeSensor) {
resizeSensor.detach();
resizeSensor = null;
}

if(helper){
helper.destroy();
helper = null;
Expand Down