Tuesday, September 8, 2015

OpenText Widget Customization

Below is how internally OpenText Content Widget loads different resources from Content server and renders the widget.

Here, we can see csui-base.css is downloaded from csui.js using helper.js. jquery-ui.css which imports original.css and adjustment.css has majority of the Stylesheet. 

For custom look and feel, we had downloaded entire %support\csui\lib\jquery.ui\themes\opentext% directory and made local copy of it. After that, adjustment.css can be customized using CSS overwrite rule. We could completely customize entire CSS using JQuery theme roller as well.



CSS overwrite

We had embedded content (widget) on hosted page and wanted to override the CSS which comes with hosted page. Here are a few techniques we tried:

1. Additional properties : Probably the most simple one. If we need to add properties to the style which is on hosted page. Browser will load both CSS and combine all the properties for that class.

 Hosted Page CSS:

 .my-button {  
      opacity: 1;  
      background-color: #fff;  
      border: 1px solid #999999;  
      color: #999999;  
 }   

Addition to CSS from embedded code:

 .my-button {  
      text-decoration: underline;  
 }   


2. Overwrite : When we want to overwrite the property which is already exists on hosted page's css. Here browser will give higher priority to property with !important, regardless of which of the order in which they are loaded.


 Hosted Page CSS:

 .my-button {  
      opacity: 1;  
      background-color: #fff;  
      border: 1px solid #999999;  
      color: #999999;  
      text-decoration: none;  
 }   

Addition to CSS from embedded code:

 .my-button {  
      text-decoration: underline  !important; 
 }   



3. Overwrite the Important : We had case when hosted page's css had !important in it. e.g. below, hosted page has text-decoration with !important, so it was not possible to overwrite it using another !important

 Hosted Page CSS:

 .my-button {  
      opacity: 1;  
      background-color: #fff;  
      border: 1px solid #999999;  
      color: #999999;  
      text-decoration: none  !important; 
 }   


Option a) Rely on Order

Let's say we write our write our custom CSS as below. In this case, if our custom CSS is loaded after hosted page CSS, then custom CSS will take priority over the hosted page CSS. Basically, CSS gives priority to last CSS loaded on the page if both are set to !important. However, it is not recommended to rely on order of the CSS as resource can take different time to load. Additionally if we use @import for sync loading it could potentially cause performance issues.

 .my-button {  
      text-decoration: underline  !important; 
 }   


Option b) Swap the style

Create a new style my-button-2, and use JQuery to replace all occurrences of my-button with my-button-2:

 .my-button-2 {  
      opacity: 1;  
      background-color: #fff;  
      border: 1px solid #999999;  
      color: #999999;  
      text-decoration: underline  !important; 
 }   

Swap the style for all the elements on the page:

      jQuery.noConflict();  
      jQuery( document ).ready(function( $ ) {  
           setTimeout(switchClass, 1000)  // make sure class was loaded  
      });  
      function switchClass() {  
           jQuery(".my-button").switchClass("my-button", "my-button-2", 1, "easeInOutQuad");  
      }  


Option c) disable/swap host css

Created copy of entire CSS file in the embedded code and disable the Hosted page's css.

      jQuery.noConflict();  
      jQuery( document ).ready(function( $ ) {  
           setTimeout(disableCSS, 1000)  // make sure class was loaded  
      });  
      function disableCSS() {  
           jQuery("link[href$='css-original.css']")[0].disabled = true;
      }  



Source code.