Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
nol_hendrikx
Active Contributor

In the portal there is a mechanism that holds session information. When the user navigates away from a page to another, you can see a small popup screen on the right-hand side of the screen. This is called the DSM Terminator.

As stated by SAP, to let the DSM Terminator work properly you will need to disable the popup blocker. That sounds fair, but our SAP portal is being accessed by endusers at home and the IT department can't control those pc's, since they are private.

First of all let's disable the popup blocker:

In Chrome goto chrome://settings/contentExceptions#popups

Here you can add your SAP portal with port number. Now the portal should work with the DSM terminator active. Now what happens if I don't add the portal site to this list? The DSM terminator is blocked, so my sessions are still alive. We don't want that.

So what's next? Some suggestions:

1) Inform everyone that they will need to disable the popup blocker for the SAP portal.

2) Add a script in the portal that checks if the popup blocker is active;

3) Add a script just before the DSM popup will be triggered.

4) Disable the DSM terminator.

1) Inform everyone that they will need to disable the popup blocker for the SAP portal.

This might be an option. When the user logs into the portal you can display a message as well.


2) Add a script in the portal that checks if the popup blocker is active;

There are a lot of scripts to check if a popup blocker is active. Unfortunately you cannot read a browser property if the popup blocker is active (safety). So you will need to launch a popup and check if the popup is active.

See the example here: http://davidwalsh.name/popup-block-javascript

You can create a portal component that launches the window and checks if it is active. If the window is active, no popup blocker is active as well. But.. you will see an ugly window popping up now and then. Personally I don't like that...


3) Add a script just before the DSM popup will be triggered. (possible with custom framework)

For me the popup check is only needed when the DSM terminator is launched. Now the deep dive into the code start :smile:

First I need to find out where there is a reference to DSM. I often check the html code of a page and knew that in the beginning of every page some methods are called in javascript:

The EPCM.DSM.init takes care of the popup box. Now I need to know where this EPCM is initialised. Searching for EPCM in all javascript files of the current page resulted in a hit in js13_epcf.js. EPCF is the portal client framework (Enterprise Portal Client Framework (EPCF) - Portal - SAP Library).

Diving more deep into the EPCM.DSM part resulted in two interesting functions: (the trick was to search for 'window.open').

- EPCM.DSM3.sendViaFormPost (IE)

- EPCM.DSM3.sendViaXHRPost (Chrome,FF, Safari)

Now I have the spot where the popup is triggered. But this is standard code in the file js13_epcf.js. I don't wanna change it, since updates of the portal will revert my change.

Since I do have my custom framework, I can overwrite the javascript function. How? Open your portal application, edit your custom javascript file and add the complete code:


EPCM.DSM3.sendViaFormPost = function(cmd) {


    if (this.NavigateAcrossSubFrames) {


        this.preFetchEmptyUrlWindow();


    }


    var myForm = document.getElementById(this.FormId);


    if (myForm == null) {


        this.createSenderForm();


    }


    myForm = document.forms[this.FormName];


    myForm.Command.value = cmd;


    myForm.SerPropString.value = this.SerPropString;


    myForm.SerKeyString.value = this.SerKeyString;


    myForm.SerAttrKeyString.value = this.AttrKeyString;


    myForm.SerWinIdString.value = this.WinIdString;


    myForm.Autoclose.value = "";


    myForm.DebugSet.value = this.DebugFlagSet;


    myForm.method = "POST";


    myForm.action = this.TerminatorUrl;


    if (this.CustomData) {


        myForm.CustomData.value = this.CustomData;


    }


    var targetResult = this.targetResolver(cmd);


    if (!targetResult.newWin) {


        myForm.target = targetResult.frameName;


    }


    if (targetResult.newWin) {


        if (EPCM.DSM.isLogoff(cmd)) {


            try {


                top.isLogoffFinalAllowed = false;


            } catch (ex) {


            }


        }


        var myTarget = this.TargetNameWindow + this.FormName;


        var myWinParams = (this.DbgWinHold) ? this.WinParamsDebug : this.WinParamsHidden;


        myForm.target = myTarget;


        myForm.Autoclose.value = (this.DbgWinHold) ? "" : "1000";


        var popUp = window.open(this.EmptyUrlWindow, myTarget, myWinParams);


  if (popUp == null || typeof(popUp)=='undefined') {


        alert('Please disable your pop-up blocker and click the "Open" link again.');


        } else {


  // no popup blocker


            popUp.focus();


        }



    }


    myForm.submit();


}









Cool... this should work I thought. And normally it should work. But....

Now I need your help!

The javascript function is called for the unload event (window.onunload - Web API Interfaces | MDN). During this event no alerts are allowed :sad: . The only thing I can think of right now is cancelling the unload event (DSM termination doesn't work since the popup blocker is active, so no big deal if you ask me) and display a big warning on the screen.

Your input is more than welcome!

UPDATE 14-03-2014: PROBLEM SOLVED!

Instead of alerting the end user, the script sets a cookie! In the framework the cookie is read and if there is a cookie, an error message is being displayed!

Setting the cookie:

IE browsers use the function EPCM.DSM3.sendViaFormPost


EPCM.DSM3.sendViaFormPost = function(cmd) {


    if (this.NavigateAcrossSubFrames) {


        this.preFetchEmptyUrlWindow();


    }


    var myForm = document.getElementById(this.FormId);


    if (myForm == null) {


        this.createSenderForm();


    }


    myForm = document.forms[this.FormName];


    myForm.Command.value = cmd;


    myForm.SerPropString.value = this.SerPropString;


    myForm.SerKeyString.value = this.SerKeyString;


    myForm.SerAttrKeyString.value = this.AttrKeyString;


    myForm.SerWinIdString.value = this.WinIdString;


    myForm.Autoclose.value = "";


    myForm.DebugSet.value = this.DebugFlagSet;


    myForm.method = "POST";


    myForm.action = this.TerminatorUrl;


    if (this.CustomData) {


        myForm.CustomData.value = this.CustomData;


    }


    var targetResult = this.targetResolver(cmd);


    if (!targetResult.newWin) {


        myForm.target = targetResult.frameName;


    }


    if (targetResult.newWin) {


        if (EPCM.DSM.isLogoff(cmd)) {


            try {


                top.isLogoffFinalAllowed = false;


            } catch (ex) {


            }


        }


        var myTarget = this.TargetNameWindow + this.FormName;


        var myWinParams = (this.DbgWinHold) ? this.WinParamsDebug : this.WinParamsHidden;


        myForm.target = myTarget;


        myForm.Autoclose.value = (this.DbgWinHold) ? "" : "1000";


        var popUp = window.open(this.EmptyUrlWindow, myTarget, myWinParams);


        if (popUp == null || typeof(popUp)=='undefined') {


               // set cookie


               document.cookie="PopupBlocker=Active";


         } else {


               // no popup blocker


               popUp.focus();


        }     



    }


    myForm.submit();


}






Other browsers use:


EPCM.DSM3.sendViaXHRPost = function(cmd) {


    var XHR = (window.XMLHttpRequest) ? new XMLHttpRequest() : null;


    if (!XHR) {


        throw new Error("Could not find any XMLHttpRequest alternative.")


    }


    var mapKeySend = this.ParamMapId + "_" + (new Date()).getTime();


    var mapKeyReceived,


    data = this.getParamMapAsBody(cmd, "SAVE", mapKeySend);


    XHR.open("POST", this.TerminatorUrl, false);


    XHR.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");


    XHR.send(data);


    if (XHR.status != 200)


        alert("DSM: XHR Status was " + XHR.status + ",\n not able to deliver DSM data");


    mapKeyReceived = XHR.responseText;


    var targetResult = this.targetResolver(cmd);


    if (targetResult.newWin) {


        if (EPCM.DSM.isLogoff(cmd)) {


            try {


                top.isLogoffFinalAllowed = false;


            } catch (ex) {


            }


        }


        var targetUrl = this.TerminatorUrl + "?ParamMapCmd=LOAD&ParamMapKey=" + mapKeyReceived;


        var myWinParams = (this.DbgWinHold) ? this.WinParamsDebug : this.WinParamsHidden;


        var popUp = window.open(targetUrl, "_blank", myWinParams);


        if (popUp == null || typeof(popUp)=='undefined') {


               // set cookie


               document.cookie="PopupBlocker=Active";


          } else {


               // no popup blocker


               popUp.focus();


        }       


    }


    else {


        var targetUrl = this.TerminatorUrl + "?ParamMapCmd=LOAD&ParamMapKey=" + mapKeyReceived;


        targetResult.frameElem.src = targetUrl;


    }


}






So if there is a popup blocker active for the portal, the DSM script will write a cookie as well, named PopupBlocker.

In my framework I have added a piece of code to check if there is a cookie called PopupBlocker.


// Check for Popup Blocker cookie


(function _checkPopupBlockerCookie(){


  var name = "PopupBlocker=";


  var ca = document.cookie.split(';');


  for(var i=0; i<ca.length; i++){


     var c = ca[i].replace(/^\s+|\s+$/g, '');


     if (c.indexOf(name)==0){


          // Cookie PopupBlocker exists!


          // display your message


          $("#popupBlocker").show();


          // reset cookie :smile:


          document.cookie = "PopupBlocker=; expires=Thu, 01 Jan 1970 00:00:00 GMT";


   }


  }


})();




The end result is:

For this screenshot I have commented the line document.cookie = "PopupBlocker=; expires=Thu, 01 Jan 1970 00:00:00 GMT";


The red message is something like: You have enabled the popup blocker. Follow the instructions here to disable the popup blocker for this site.

I think this solution (or workaround) will be implemented soon in the portal, if you ask me 🙂

Big thanks to ronny.amran, shani.ozeri and ido.fishler.


Some more reading stuff:

Session Release Agent (EP-PIN) (SAP Library - Glossary)

Disable DSM Terminator

/*

nol.hendrikx - SAP Portal consultant @ Peppie Portals.

Specialized in Corporate branding SAP Portal / Adobe Interactive Forms.

UI Theming blog series

Portal theming - also waited a couple of years?

How to... UI Theme Designer - Installation

How to... UI Theme Designer - Migration

How to... UI Theme Designer - Locating elements

How to... UI Theme Designer - Transportation

How to... UI Theme Designer - Make use of the Custom CSS tab in the Portal!

Other blogs:

Tired of zipping / unzipping portal theme?

Tips for the Portal Content Studio

DSM Terminator and popup blockers (or not)

My best development friend - Autoresponder FTW

/*

6 Comments
Labels in this area