From de253bf5fcbd693a7ac5b4d167cb6e398dd66968 Mon Sep 17 00:00:00 2001 From: gsarng517_comcast Date: Mon, 16 Feb 2026 15:33:34 +0530 Subject: [PATCH] RDKEMW-13250: Memory Metrics analysis for VIPA Reason for change: Added minified jsdom for widget Test Procedure: build should be successful Risk: low Priority: P2 --- include/ModuleSettings.h | 1 + include/NativeJSRenderer.h | 3 +- src/ModuleSettings.cpp | 13 ++- src/NativeJSRenderer.cpp | 5 +- src/jsc/JavaScriptContext.cpp | 6 + src/jsc/modules/minified_linkedjsdom.js | 141 ++++++++++++++++++++++++ src/jsruntime.cpp | 4 + 7 files changed, 166 insertions(+), 7 deletions(-) create mode 100644 src/jsc/modules/minified_linkedjsdom.js diff --git a/include/ModuleSettings.h b/include/ModuleSettings.h index a255182..ba43d2e 100644 --- a/include/ModuleSettings.h +++ b/include/ModuleSettings.h @@ -34,5 +34,6 @@ struct ModuleSettings bool enableJSDOM; bool enableWindow; bool enablePlayer; + bool enableMiniJSDOM; }; #endif diff --git a/include/NativeJSRenderer.h b/include/NativeJSRenderer.h index 6fc061e..ee9f629 100644 --- a/include/NativeJSRenderer.h +++ b/include/NativeJSRenderer.h @@ -95,7 +95,7 @@ namespace JsRuntime { struct ApplicationRequest { - ApplicationRequest(uint32_t id, RequestType requestType, std::string url="", bool enableHttp=false, bool enableXHR=false, bool enableWebSocket=false, bool enableWebSocketEnhanced=false, bool enableFetch=false, bool enableJSDOM=false, bool enableWindow=false, bool enablePlayer=false, std::string userAgent=""): mId(id), mRequestType(requestType), mUrl(url), mEnableHttp(enableHttp), mEnableXHR(enableXHR), mEnableWebSocket(enableWebSocket), mEnableWebSocketEnhanced(enableWebSocketEnhanced), mEnableFetch(enableFetch), mEnableJSDOM(enableJSDOM), mEnableWindow(enableWindow), mEnablePlayer(enablePlayer), mUserAgent(userAgent) + ApplicationRequest(uint32_t id, RequestType requestType, std::string url="", bool enableHttp=false, bool enableXHR=false, bool enableWebSocket=false, bool enableWebSocketEnhanced=false, bool enableFetch=false, bool enableJSDOM=false, bool enableWindow=false, bool enablePlayer=false, bool enableMiniJSDOM=false, std::string userAgent=""): mId(id), mRequestType(requestType), mUrl(url), mEnableHttp(enableHttp), mEnableXHR(enableXHR), mEnableWebSocket(enableWebSocket), mEnableWebSocketEnhanced(enableWebSocketEnhanced), mEnableFetch(enableFetch), mEnableJSDOM(enableJSDOM), mEnableWindow(enableWindow), mEnablePlayer(enablePlayer), mEnableMiniJSDOM(enableMiniJSDOM), mUserAgent(userAgent) { } uint32_t mId; @@ -109,6 +109,7 @@ namespace JsRuntime { bool mEnableJSDOM; bool mEnableWindow; bool mEnablePlayer; + bool mEnableMiniJSDOM; std::string mUserAgent; }; diff --git a/src/ModuleSettings.cpp b/src/ModuleSettings.cpp index 32f2586..5dd762e 100644 --- a/src/ModuleSettings.cpp +++ b/src/ModuleSettings.cpp @@ -19,7 +19,7 @@ #include ModuleSettings::ModuleSettings(): enableHttp(false), enableXHR(false), enableWebSocket(false), enableWebSocketEnhanced(false) - , enableFetch(false), enableJSDOM(false), enableWindow(false), enablePlayer(false) + , enableFetch(false), enableJSDOM(false), enableWindow(false), enablePlayer(false), enableMiniJSDOM(false) { } @@ -30,7 +30,8 @@ ModuleSettings::ModuleSettings(ModuleSettings& settings): enableHttp(settings.en enableFetch(settings.enableFetch), enableJSDOM(settings.enableJSDOM), enableWindow(settings.enableWindow), - enablePlayer(settings.enablePlayer) + enablePlayer(settings.enablePlayer), + enableMiniJSDOM(settings.enableMiniJSDOM) { } @@ -56,7 +57,11 @@ void ModuleSettings::fromString(std::string& options) { enableFetch = true; } - if (options.find("jsdom") != std::string::npos) + if (options.find("minijsdom") != std::string::npos) + { + enableMiniJSDOM = true; + } + else if (options.find("jsdom") != std::string::npos) { enableJSDOM = true; } @@ -67,5 +72,5 @@ void ModuleSettings::fromString(std::string& options) if (options.find("player") != std::string::npos) { enablePlayer = true; - } + } } diff --git a/src/NativeJSRenderer.cpp b/src/NativeJSRenderer.cpp index 4e98f41..ca370d8 100644 --- a/src/NativeJSRenderer.cpp +++ b/src/NativeJSRenderer.cpp @@ -235,7 +235,7 @@ uint32_t NativeJSRenderer::createApplication(ModuleSettings& moduleSettings, st uint32_t id=0; mUserMutex.lock(); id = createApplicationIdentifier(); - ApplicationRequest request(id, CREATE, "", moduleSettings.enableHttp, moduleSettings.enableXHR, moduleSettings.enableWebSocket, moduleSettings.enableWebSocketEnhanced, moduleSettings.enableFetch, moduleSettings.enableJSDOM, moduleSettings.enableWindow, moduleSettings.enablePlayer, userAgent); + ApplicationRequest request(id, CREATE, "", moduleSettings.enableHttp, moduleSettings.enableXHR, moduleSettings.enableWebSocket, moduleSettings.enableWebSocketEnhanced, moduleSettings.enableFetch, moduleSettings.enableJSDOM, moduleSettings.enableWindow, moduleSettings.enablePlayer, moduleSettings.enableMiniJSDOM, userAgent); gPendingRequests.push_back(request); mUserMutex.unlock(); return id; @@ -305,6 +305,7 @@ void NativeJSRenderer::createApplicationInternal(ApplicationRequest& appRequest) settings.enableJSDOM = appRequest.mEnableJSDOM; settings.enableWindow = appRequest.mEnableWindow; settings.enablePlayer = appRequest.mEnablePlayer; + settings.enableMiniJSDOM = appRequest.mEnableMiniJSDOM; uint32_t id= appRequest.mId; std::string userAgent = appRequest.mUserAgent; JavaScriptContextFeatures features(mEmbedThunderJS, mEmbedRdkWebBridge, mEnableWebSocketServer, settings); @@ -509,7 +510,7 @@ void NativeJSRenderer::run() ModuleSettings settings; uint32_t id = createApplicationIdentifier(); settings.enableJSDOM = mEnableTestFileDOMSupport; - ApplicationRequest appRequest(id, RUN, mTestFileName, settings.enableHttp, settings.enableXHR, settings.enableWebSocket, settings.enableWebSocketEnhanced, settings.enableFetch, settings.enableJSDOM, settings.enableWindow, settings.enablePlayer); + ApplicationRequest appRequest(id, RUN, mTestFileName, settings.enableHttp, settings.enableXHR, settings.enableWebSocket, settings.enableWebSocketEnhanced, settings.enableFetch, settings.enableJSDOM, settings.enableWindow, settings.enablePlayer, settings.enableMiniJSDOM); mUserMutex.lock(); NativeJSRenderer::createApplicationInternal(appRequest); NativeJSRenderer::runApplicationInternal(appRequest); diff --git a/src/jsc/JavaScriptContext.cpp b/src/jsc/JavaScriptContext.cpp index 3dd3389..c70e11a 100644 --- a/src/jsc/JavaScriptContext.cpp +++ b/src/jsc/JavaScriptContext.cpp @@ -466,6 +466,12 @@ if (mModuleSettings.enablePlayer) runFile("linkedjsdomwrapper.js", nullptr/*, true*/); runFile("windowwrapper.js", nullptr/*, true*/); runFile("url.js", nullptr/*, true*/); + + } + else if (mModuleSettings.enableMiniJSDOM) + { + runFile("minified_linkedjsdom.js", nullptr/*, true*/); + runFile("url.js", nullptr/*, true*/); if(getenv("FIREBOLT_ENDPOINT")!=NULL) { auto FireboltEndpoint = std::string(getenv("FIREBOLT_ENDPOINT")); diff --git a/src/jsc/modules/minified_linkedjsdom.js b/src/jsc/modules/minified_linkedjsdom.js new file mode 100644 index 0000000..cb9d064 --- /dev/null +++ b/src/jsc/modules/minified_linkedjsdom.js @@ -0,0 +1,141 @@ +var document = { + createElement: function() { + return { + style: {}, + setAttribute: function() {}, + getAttribute: function() { return null; }, + hasAttribute: function() { return false; }, + appendChild: function(c) { return c; }, + removeChild: function(c) { return c; }, + addEventListener: function() {}, + getBoundingClientRect: function() { return {top:0,left:0,right:0,bottom:0,width:0,height:0,x:0,y:0}; } + }; + }, + createEvent: function(type) { + return { + initEvent: function(t, bubbles, cancelable) { this.type = t; this.bubbles = bubbles; this.cancelable = cancelable; }, + type: '', + bubbles: false, + cancelable: false, + preventDefault: function() {} + }; + }, + getElementById: function(id) { return id === 'videoDiv' ? this.createElement() : null; }, + querySelector: function(s) { return s === '#videoDiv' ? this.getElementById('videoDiv') : null; }, + body: { appendChild: function(c) { return c; } }, + head: { appendChild: function(c) { return c; } } +}; + +function Event(t) { this.type = t; } +Event.prototype.preventDefault = function() {}; + +function DOMParser() {} +DOMParser.prototype.parseFromString = function() { return document; }; + +function Blob(parts, options) { this.size = 0; this.type = (options && options.type) || ''; } +Blob.prototype.slice = function() { return new Blob([], {}); }; + +// AbortController for fetch API +function AbortController() { + this.signal = { aborted: false, addEventListener: function() {} }; +} +AbortController.prototype.abort = function() { + this.signal.aborted = true; +}; + +// Minimal fetch stub +function fetch(url, options) { + return new Promise(function(resolve, reject) { + if (options && options.signal && options.signal.aborted) { + var error = new Error('Aborted'); + error.name = 'AbortError'; + reject(error); + return; + } + // Stub response + resolve({ + ok: true, + status: 200, + json: function() { return Promise.resolve({}); }, + text: function() { return Promise.resolve(''); }, + blob: function() { return Promise.resolve(new Blob([], {})); } + }); + }); +} + +// Wrap timer functions to ensure .apply() works +var _setTimeout = setTimeout; +var _setInterval = setInterval; +var _clearTimeout = clearTimeout; +var _clearInterval = clearInterval; + +function wrappedSetTimeout(fn, delay) { + var args = Array.prototype.slice.call(arguments, 2); + return _setTimeout(function() { fn.apply(null, args); }, delay); +} +wrappedSetTimeout.apply = function(thisArg, argArray) { + if (!argArray || argArray.length === 0) return _setTimeout(); + if (argArray.length === 1) return _setTimeout(argArray[0]); + if (argArray.length === 2) return _setTimeout(argArray[0], argArray[1]); + var args = Array.prototype.slice.call(argArray, 2); + return _setTimeout(function() { argArray[0].apply(null, args); }, argArray[1]); +}; + +function wrappedSetInterval(fn, delay) { + var args = Array.prototype.slice.call(arguments, 2); + return _setInterval(function() { fn.apply(null, args); }, delay); +} +wrappedSetInterval.apply = function(thisArg, argArray) { + if (!argArray || argArray.length === 0) return _setInterval(); + if (argArray.length === 1) return _setInterval(argArray[0]); + if (argArray.length === 2) return _setInterval(argArray[0], argArray[1]); + var args = Array.prototype.slice.call(argArray, 2); + return _setInterval(function() { argArray[0].apply(null, args); }, argArray[1]); +}; + +function wrappedClearTimeout(id) { return _clearTimeout(id); } +wrappedClearTimeout.apply = function(thisArg, argArray) { + return _clearTimeout(argArray ? argArray[0] : undefined); +}; + +function wrappedClearInterval(id) { return _clearInterval(id); } +wrappedClearInterval.apply = function(thisArg, argArray) { + return _clearInterval(argArray ? argArray[0] : undefined); +}; + +var window = { + document: document, + location: {href:'',host:'127.0.0.1',hostname:'127.0.0.1'}, + navigator: {userAgent:'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36',platform:'Linux'}, + console: console, + setTimeout: wrappedSetTimeout, + setInterval: wrappedSetInterval, + clearTimeout: wrappedClearTimeout, + clearInterval: wrappedClearInterval, + addEventListener: function() {}, + Event: Event, + DOMParser: DOMParser, + Blob: Blob, + AbortController: AbortController, + fetch: fetch, + Promise: Promise +}; + +window.window = window; +window.self = window; +var navigator = window.navigator; +var location = window.location; +window.top = window; +var tv = window.tv = {}; +var DOMParser = window.DOMParser; +var Event = window.Event; +var Blob = window.Blob; +var AbortController = window.AbortController; +var fetch = window.fetch; +var Promise = window.Promise; +var top = window; +var setTimeout = wrappedSetTimeout; +var setInterval = wrappedSetInterval; +var clearTimeout = wrappedClearTimeout; +var clearInterval = wrappedClearInterval; +var LinkedJSDOMLib = {parseHTML: function() { return {window:window,document:document,defaultView:window}; }}; diff --git a/src/jsruntime.cpp b/src/jsruntime.cpp index cdfe54e..f0e4bf9 100644 --- a/src/jsruntime.cpp +++ b/src/jsruntime.cpp @@ -128,6 +128,10 @@ int main(int argc, char* argv[]) { moduleSettings.enablePlayer = true; } + else if (strcmp(argv[i], "--enableMiniJSDOM") == 0) + { + moduleSettings.enableMiniJSDOM = true; + } else if (strcmp(argv[i], "--console") == 0) { consoleMode = true;