/* IBM Confidential OCO Source Materials IBM Cognos Products: rs (C) Copyright IBM Corp. 2018, 2020 The source code for this program is not published or otherwise divested of its trade secrets, irrespective of what has been deposited with the U.S. Copyright Office. */ define([ 'jquery', 'q', 'bi/authoring/utils/rsCommon' ], function($, Q, rsCommon){ 'use strict'; function isMyParentTheTopWindow(w) { try { return Boolean(w.parent == w.top); } catch(e) { return false; } } var rsIFrameManager = {}; rsIFrameManager.m_iNewFrameId = 1; rsIFrameManager.F_LaunchRS = function(v_oParameters, v_oGlassContext, v_oLaunchParameters) { console.info('rsperf: rsIFrameManager.F_LaunchRS ...'); this.m_oLaunchParameters = v_oLaunchParameters ? v_oLaunchParameters : null; var v_bPrelaunchTest = false; if (v_bPrelaunchTest) { this.F_PreLaunch(v_oGlassContext); } // Do not use prelaunch version is only for viewing or editing reports, do not use if creating or editing a data set if (this.m_oPrelaunchRSPromise && (v_oGlassContext.currentAppView.currentContentView.perspective !== 'datasets')) { console.time('rsIFrameManager.F_LaunchRS->f_relaunchRSIFrameInView'); var v_oIFramePromise = this.m_oPrelaunchRSPromise; this.m_oPrelaunchRSPromise = null; console.time("rsperf: Waiting for RS relaunch"); if (v_oIFramePromise.isFulfilled()) { // avoiding using done for performance reason because the done is called in a setTimeout which allows all sorts of other processing to happen // normally, this promise will always be resolved by this point return this.f_relaunchRSIFrameInView(v_oParameters, v_oLaunchParameters, v_oIFramePromise.inspect().value); } var v_oRelaunchDeferred = Q.defer(); v_oIFramePromise .then( this.f_relaunchRSIFrameInView.bind(this, v_oParameters, v_oLaunchParameters)) .done(function(v_idIFrameAuthoring){ v_oRelaunchDeferred.resolve(v_idIFrameAuthoring); }); return v_oRelaunchDeferred.promise; } console.time("rsperf: Launch RS->OnRSApplicationReadyForObservers"); var v_oLaunchDeferred = Q.defer(); this.f_launchRS( v_oGlassContext, v_oParameters, this.f_onLaunchReadyForObservers.bind(this, v_oGlassContext, v_oLaunchDeferred), v_oLaunchDeferred.reject.bind(v_oLaunchDeferred, new Error("rsIFrameManager: error during f_launchRS") ) ); return v_oLaunchDeferred.promise; }; rsIFrameManager.f_relaunchRSIFrameInView = function(v_oParameters, v_oLaunchParameters, v_iframeAuthoring) { console.timeEnd('rsIFrameManager.F_LaunchRS->f_relaunchRSIFrameInView'); var v_oIFrameLaunchedDeferred = Q.defer(); console.timeEnd("rsperf: Waiting for RS relaunch"); console.time("rsperf: Launch from prelaunch RS->OnRSApplicationReadyForObservers"); v_iframeAuthoring.OnRSApplicationReadyForObservers = function() { v_oIFrameLaunchedDeferred.resolve(v_iframeAuthoring.id); console.timeEnd("rsperf: Launch from prelaunch RS->OnRSApplicationReadyForObservers"); }.bind(this); var v_oRsParameters = JSON.parse(v_oParameters.rsParameters); v_iframeAuthoring.contentWindow.Application.Relaunch(v_oRsParameters, v_oLaunchParameters); return v_oIFrameLaunchedDeferred.promise; }; rsIFrameManager.f_getBodyRect = function(el) { // in the glass the scrollable element is the HTML element not the body as one would expect. var v_elScrollable = document.documentElement; var v_oRect = el.getBoundingClientRect(); var v_oBodyRect = document.body.getBoundingClientRect(); return { top : v_oRect.top - v_oBodyRect.top + (v_elScrollable.scrollTop ? v_elScrollable.scrollTop : 0), left : v_oRect.left - v_oBodyRect.left + (v_elScrollable.scrollLeft ? v_elScrollable.scrollLeft : 0), width : v_oRect.width, height : v_oRect.height }; }; rsIFrameManager.F_PositionAndSizeIFrame = function($elContainer, v_iframeAuthoring) { function f_getZIndex( v_el ) { var v_elCur = v_el; while(v_elCur && v_elCur.nodeName != "#document") { var v_oStyle = v_elCur.ownerDocument.defaultView.getComputedStyle( v_elCur, null ); var v_iValue = parseInt( v_oStyle.zIndex, 10 ); if (!isNaN(v_iValue) && v_iValue !== 0) { return v_iValue; } v_elCur = v_elCur.parentNode; } return 0; } var v_oRect = this.f_getBodyRect($elContainer.get(0)); v_iframeAuthoring.style.top = v_oRect.top + "px"; v_iframeAuthoring.style.left = v_oRect.left + "px"; v_iframeAuthoring.style.width = v_oRect.width + "px"; v_iframeAuthoring.style.height = v_oRect.height + "px"; v_iframeAuthoring.style.zIndex = f_getZIndex($elContainer.get(0)) + 1; v_iframeAuthoring.style.visibility = "visible"; //console.log("F_PositionAndSizeIFrame: " + v_iframeAuthoring.style.left + "," + v_iframeAuthoring.style.top + " " + v_iframeAuthoring.style.width + "," + v_iframeAuthoring.style.height); }; rsIFrameManager.F_HideIFrame = function(v_iframeAuthoring) { // since the iframe is still taking space in the flow, position it somewhere that doesn't cause scrollbars in glass window v_iframeAuthoring.style.top = "-5000px"; v_iframeAuthoring.style.left = "-5000px"; v_iframeAuthoring.style.zIndex = -1; v_iframeAuthoring.style.visibility = "hidden"; }; rsIFrameManager.F_DetachIFrame = function(v_iframeAuthoring) { var v_oApplication = v_iframeAuthoring.contentWindow.Application; if (v_oApplication) { v_oApplication.DetachFromGlass(); } this.m_divRSFrameHolder.removeChild(v_iframeAuthoring); }; rsIFrameManager.f_createRSIFrame = function(v_oParameters) { var v_aHTML = []; // Added the title to resolve the accessibility issue. v_aHTML.push(''); return v_aHTML.join(""); }; rsIFrameManager.f_onLaunchReadyForObservers = function(v_oGlassContext, v_oDeferred, v_iframeAuthoring) { console.timeEnd("rsperf: Launch RS->OnRSApplicationReadyForObservers"); var v_oApplication = v_iframeAuthoring.contentWindow.Application; // RS will need a glass context while launching v_oApplication.GlassContext = v_oGlassContext; v_oApplication.LaunchParameters = this.m_oLaunchParameters; v_oDeferred.resolve(v_iframeAuthoring.id); }; rsIFrameManager.f_HTMLEncode = function(s) { return s.replace( /&/g, "&" ).replace( //g, ">" ); }; rsIFrameManager.f_HTMLAttributeEncode = function(s) { return this.f_HTMLEncode(s).replace( /'/g, "'" ).replace( /"/g, """ ); }; rsIFrameManager.f_prelaunchRS = function(v_oGlassContext, v_fnOnLaunched, v_fnOnLaunchError) { console.time("rsperf: prelaunch RS"); var v_oRsParameters = rsCommon.createRSParameters( {}, v_oGlassContext ); v_oRsParameters.prelaunchRS = true; this.f_launchRS(v_oGlassContext, rsCommon.createTemplateParameters(v_oRsParameters), this.f_onPrelaunchRSReadyForObservers.bind(this, v_oGlassContext, v_fnOnLaunched), v_fnOnLaunchError); }; rsIFrameManager.f_launchRS = function(v_oGlassContext, v_oParameters, v_fnOnLaunched, v_fnOnLaunchError) { if (!this.m_divRSFrameHolder) { $("body").prepend('
'); this.m_divRSFrameHolder = $("body").find("div").get(0); } var $divRSFrameHolder = $(this.m_divRSFrameHolder); $divRSFrameHolder.prepend(this.f_createRSIFrame(v_oParameters)); var v_iframeAuthoring = $divRSFrameHolder.find("iframe").get(0); v_iframeAuthoring.id = "rsIFrameManager_" + this.m_iNewFrameId++; v_iframeAuthoring.OnRSApplicationReadyForObservers = v_fnOnLaunched.bind(null, v_iframeAuthoring); v_iframeAuthoring.onerror = v_fnOnLaunchError; }; rsIFrameManager.f_onPrelaunchRSReadyForObservers = function(v_oGlassContext, v_fnOnLaunched, v_iframeAuthoring) { var v_oApplication = v_iframeAuthoring.contentWindow.Application; v_oApplication.GlassContext = v_oGlassContext; v_oApplication.LaunchParameters = this.m_oLaunchParameters; if ( v_oApplication.SharedState.Get("isAppLoaded") ) { this.f_onPrelaunchAppLoaded(v_iframeAuthoring, v_fnOnLaunched); } else { v_oApplication.SharedState.AddObserver("rsIFrameManager", "isAppLoaded", this.f_onPrelaunchAppLoaded.bind(this, v_iframeAuthoring, v_fnOnLaunched, true) ); } }; rsIFrameManager.f_onPrelaunchAppLoaded = function(v_iframeAuthoring, v_fnOnLaunched, v_bRemoveObserver) { console.timeEnd("rsperf: prelaunch RS"); if (v_bRemoveObserver) { var v_oApplication = v_iframeAuthoring.contentWindow.Application; v_oApplication.SharedState.RemoveObserver("rsIFrameManager", "isAppLoaded"); } setTimeout(v_fnOnLaunched.bind(null, v_iframeAuthoring), 0); }; rsIFrameManager.F_PreLaunch = function(v_oGlassContext) { if (this.m_oPrelaunchRSPromise) { return; } var v_oDefer = Q.defer(); this.m_oPrelaunchRSPromise = v_oDefer.promise; this.f_prelaunchRS(v_oGlassContext, function(v_idIFrameAuthoring) { v_oDefer.resolve(v_idIFrameAuthoring); }.bind(this), v_oDefer.resolve.bind(v_oDefer, null)); }; return rsIFrameManager; });