This chapter includes the following sections:
The Adaptive Pagelet Scripting Framework is a client-side JavaScript library that provides services to CSP pagelets and proxied pages. This section explains how to use the scripting framework to implement dynamic functionality in pagelets.
Note:
CSP (and the Adaptive Pagelet Scripting Framework) only applies to WCI and its predecessor, Plumtree Portal. WebCenter Portal does not support CSP.
This section includes the following topics:
For a full list of classes and methods, see the JSPortlet API documentation. For additional information about adaptive pagelets, see What You May Need to Know About Adaptive Pagelet Development.
This section describes how the adaptive pagelet scripting framework can be used as a client-side response handler for structured HTTP, typically encoded as XML.
In many cases it can be expensive and inefficient to send large amounts of HTML back in response to some HTTP request, if only a small part of the user interface needs to be changed. This is especially true with more complex user interfaces. In these cases, the response can be encoded in XML. The client-side response handler can then parse the XML, and update the user interface (or perform some other action) based on that response. Use the Structured Response design pattern to redraw a small area of the user interface after making an HTTP request, or to access a simple HTTP/URI type web service from a pagelet. The example code below (structuredresponse_portlet.html) accesses an RSS feed from a selection of news sites.
<!-- jsxml includes --> <a id="imgServerHref" href="/images/plumtree" style="display:none"></a> <script type="text/javascript" src="/images/plumtree/common/private/js/PTLoader.js"></script> <script type="text/javascript"> var oImgServer =new Object(); oImgServer.location =document.getElementById('imgServerHref').href; var imageServerURL =document.getElementById('imgServerHref').href; var imageServerConnectionURL =oImgServer.location; new PTLoader(imageServerURL, imageServerConnectionURL).include('jsxml','en'); </script> <!-- jscontrols includes --> <link rel="stylesheet" type="text/css" href="/portal-remote-server/js/jscontrols/styles/css/PTMenu.css"/> <link rel="stylesheet" type="text/css" href="/portal-remote-server/js/jscontrols/styles/css/PTRichTextEditor.css"/> <script type="text/javascript" src="/portal-remote-server/js/jscontrols/strings/PTControls-en.js"></script> <script type="text/javascript" src="/portal-remote-server/js/jscontrols/PTControls.js"></script> <!-- Inline JS helper functions --> --> <script defer type="text/javascript" id="structured-response-portlet-A-script"> // Function that gets the RSS XML feed found at the specified url getRSSFeed =function(url) { //First clear out any existing rows in the table channelTable.clearRows(); //Force the transformer to fix up the url var oURL =new Object(); oURL.location =url; //Do the http get var get =new PTHTTPGETRequest(oURL.location, handleRSSResponse); get.invoke(); } //Function that handles the RSS XML response and updates the table based on the RSS items handleRSSResponse =function(response) { //Get the rss xml var xml =response.responseText; if (!xml ||xml.indexOf('<?xml') ==-1) {return; } //Parse into a dom, and get the channel node var xmlDOM =new PTXMLParser(xml); var rssNode =xmlDOM.selectSingleNode('rss'); var channelNode =rssNode.selectSingleNode('channel'); //Get the channel title and set the status bar text in the table var channelTitle =channelNode.selectSingleNode('title').getNodeValue(); channelTable.statusBarText ='<b>Loaded Channel</b>: ' +channelTitle; //Get channel item nodes var itemNodes =channelNode.selectNodes('item'); //Build table rows channelTable.rows =new Array(); for (var i=0; i<itemNodes.length; i++) { var itemNode =itemNodes[i]; //Get channel item properties var itemTitle =itemNode.selectSingleNode('title').getNodeValue(); var itemLink =itemNode.selectSingleNode('link').getNodeValue(); var itemDescription =itemNode.selectSingleNode('description').getNodeValue(); if (itemNode.selectSingleNode('author')) var itemAuthor =itemNode.selectSingleNode('author').getNodeValue(); if (itemNode.selectSingleNode('category')) var itemCategory =itemNode.selectSingleNode('category').getNodeValue(); if (itemNode.selectSingleNode('pubDate')) var itemPubDate =itemNode.selectSingleNode('pubDate').getNodeValue(); //Create a row and add it to the table var row =new PTRow(); row.parent =channelTable; row.id =i; row.uid =i; row.previewText =itemDescription; row.link =itemLink; row.columnValues[0] =new PTTextColumnValue(itemTitle); row.columnValues[1] =new PTTextColumnValue(itemCategory); row.columnValues[2] =new PTTextColumnValue(itemAuthor); row.columnValues[3] =new PTTextColumnValue(itemPubDate); channelTable.rows[channelTable.rows.length] =row; } //Redraw the table channelTable.draw(); } </script> <b>Select RSS Feed:</b> <a href="#" onclick="getRSSFeed('http://www.wired.com/news/feeds/rss2/0,2610,,00.xml'); return false;">Wired News</a> <a href="#" onclick="getRSSFeed('http://news.com.com/2547-1_3-0-5.xml'); return false;">CNET News.com</a> <a href="#" onclick="getRSSFeed('http://partners.userland.com/nytRss/nytHomepage.xml'); return false;">NY Times</a> <br><br> <!-- Set up a table control to display channel items --> <div id="channelTableContainer"></div> <script defer type="text/javascript"> var channelTable =new PTTableControl(); channelTable.locale ='en_US'; channelTable.objName ='channelTable'; channelTable.container ='channelTableContainer'; channelTable.baseURL ='/imageserver/plumtree/common/private/portal-remote-server/js/jscontrols/1/'; channelTable.statusBarText ='No RSS Feed Selected'; channelTable.rowDetailAction =new PTJavaScriptAction('window.open(\'${ROW.link}\');'); channelTable.columns[0] =new PTColumn(); channelTable.columns[0].name ='Title'; channelTable.columns[0].width ='40%'; channelTable.columns[1] =new PTColumn(); channelTable.columns[1].name ='Category'; channelTable.columns[1].width ='20%'; channelTable.columns[2] =new PTColumn(); channelTable.columns[2].name ='Author'; channelTable.columns[2].width ='20%'; channelTable.columns[3] =new PTColumn(); channelTable.columns[3].name ='Publication Date'; channelTable.columns[3].width ='20%'; channelTable.areColumnsResizable =true; channelTable.clientSortEnabled =true; channelTable.scrollHeight =250; channelTable.init(); channelTable.draw(); </script> </div>
This section describes how the adaptive pagelet scripting framework allows pagelets to respond to both page-level events and custom events raised by other pagelets.
The registerForWindowEvent
and registerOnceForWindowEvent
methods in the scripting framework provide pagelets with access to page-level events. For a complete list, see How to Use Page-Level Events with the Scripting Framework. To register for notification of these events, pass in the name of the event and the name of the method that should be called when it occurs. When a page-level event is raised, the JavaScript event object is passed to the event handler as an argument. The scripting framework also allows pagelets to raise and respond to custom events using raiseEvent
and registerForEvent
. The Broadcast-Listener design pattern illustrates an important example of using notification services with session preferences. Users can select an item or perform some other action in a "broadcast" pagelet, which causes the content in other related "listener" pagelets to be redrawn. In the following example, the broadcast pagelet displays a form that allows you to enter a number in a text box.
When the user enters a number in the text box, the values in the listener pagelets change. The first listener pagelet displays the square root of the number entered in the broadcast pagelet.
The second listener pagelet displays the cube root of the number entered in the broadcast pagelet.
The following steps summarize how the pagelets work:
On load, each listener pagelet calls its own instance method (registerForEvent
) to register for events of type 'onBroadcastUpdate'.
On each onkeyup event that occurs in the "Enter number" text box, the broadcast pagelet sets a session preference to the value entered in the text box, and calls its own instance method (raiseEvent
) to raise an event of type 'onBroadcastUpdate'.
When the onBroadcastUpdate event is raised or the page is reloaded, each listener pagelet retrieves the session preference set by the broadcast pagelet and computes a new value to display based on the value of the preference.
Broadcast Pagelet
<div style="padding:10px;" align="center"> <p><b>Enter number:</b> <input type="text" style="font-size:22px;font-weight:bold;text-align:center;" id="broadcast_prefName" value="4" size="7" onkeyup="broadcast_setPrefs(this.value)"></p> <br> </div> <script type="text/javascript"> function broadcast_setPrefs(val) { var prefName ='broadcastNumber'; var prefValue =val; PTPortlet.setSessionPref(prefName,prefValue); var broadcastPortlet =PTPortlet.getPortletByGUID('{D9DFF3F4-EAE7-5478-0F4C-2DBD94444000}'); if (!broadcastPortlet) { broadcast_debug('Could not locate PTPortlet object which corresponds to <b>Broadcast Portlet</b> on page.'); return; } broadcast_debug('<b>Broadcast Portlet</b> raising onBroadcastUpdate event.'); broadcastPortlet.raiseEvent('onBroadcastUpdate',false); } function broadcast_debug(str) { if (window.PTDebugUtil) { PTDebugUtil.debug(str); } } </script>
Listener Pagelet #1
<div style="padding:10px;" align="center"> <p><b>Square root:</b> <div style="height:21px;border:2px solid black;padding:2px;overflow:visible;font-size:14px;"id="listener1-swatch"> </div> </div> <script> function listener1_update() { var broadcastNumber =parseFloat(PTPortlet.getSessionPref('broadcastNumber')); if (isNaN(broadcastNumber)) { listener1_error('<b>Listener-1 Portlet</b> cannot parse number from session pref broadcastNumber'); return; } listener1_debug('<b>Listener-1 Portlet</b> computing square root of ' +broadcastNumber); var swatch =document.getElementById('listener1-swatch'); swatch.innerHTML =Math.sqrt(broadcastNumber); } function listener1_debug(str) { if (window.PTDebugUtil) { PTDebugUtil.debug(str); } } function listener1_error(str) { if (window.PTDebugUtil) { PTDebugUtil.error(str); } } function listener1_getPortlet() { var portletGUID ='{D9DFF3F4-EAE7-5478-0F4C-2DBDB4F4A000}'; var listener1Portlet =PTPortlet.getPortletByGUID(portletGUID); return listener1Portlet; } var listener1Portlet =listener1_getPortlet(); if (listener1Portlet) { listener1Portlet.registerForEvent('onBroadcastUpdate','listener1_update'); listener1_debug('<b>Listener-1 Portlet</b> registered refreshOnEvent for event onBroadcastUpdate'); listener1Portlet.registerForEvent('onload','listener1_update'); } </script>
Listener Pagelet #2
<div style="padding:10px;" align="center"> <p><b>Cube root:</b> <div style="height:21px;border:2px solid black;padding:2px;overflow:visible;font-size:14px;"id="listener2-swatch"> </div> </div> <script> var listener2_oneThird =(1/3); function listener2_update() { var broadcastNumber =parseFloat(PTPortlet.getSessionPref('broadcastNumber')); if (isNaN(broadcastNumber)) { listener2_error('<b>Listener-2 Portlet</b> cannot parse number from session pref broadcastNumber'); return; } listener2_debug('<b>Listener-2 Portlet</b> computing square root of ' +broadcastNumber); var swatch =document.getElementById('listener2-swatch'); swatch.innerHTML =Math.pow(broadcastNumber,listener2_oneThird); } function listener2_debug(str) { if (window.PTDebugUtil) { PTDebugUtil.debug(str); } } function listener2_error(str) { if (window.PTDebugUtil) { PTDebugUtil.error(str); } } function listener2_getPortlet() { var portletGUID ='{D9DFF3F4-EAE7-5478-0F4C-2DBDCA1C7000}'; var listener2Portlet =PTPortlet.getPortletByGUID(portletGUID); return listener2Portlet; } var listener2Portlet =listener2_getPortlet(); if (listener2Portlet) { listener2Portlet.registerForEvent('onBroadcastUpdate','listener2_update'); listener2_debug('<b>Listener-2 Portlet</b> registered refreshOnEvent for event onBroadcastUpdate'); listener2Portlet.registerForEvent('onload','listener2_update'); } </script>
The scripting framework automatically has access to the following page-level events.
Table 17-1 Page-Level Events
Event | Triggered: |
---|---|
onload |
immediately after the browser loads the page |
onbeforeunload |
prior to a page being unloaded (browser window closes or navigates to different location) |
onunload |
immediately before the page is unloaded (browser window closes or navigates to different location) |
onactivate |
the page is set as the active element (receives focus) |
onbeforeactivate |
immediately before the page is set as the active element (receives focus) |
ondeactivate |
when the active element is changed from the current page to another page in the parent document |
onfocus |
when the page receives focus |
onblur |
when the page loses focus |
oncontrolselect |
when the user is about to make a control selection of the page |
onresize |
when the size of the page is about to change |
onresizestart |
when the user begins to change the dimensions of the page in a control selection |
onresizeend |
when the user finishes changing the dimensions of the page in a control selection |
onhelp |
when the user presses the F1 key while the browser is the active window |
onerror |
when an error occurs during page loading |
onafterprint |
immediately after an associated document prints or previews for printing |
This section describes how pagelets can reload their internal content without refreshing the page using the scripting framework to implement in-place refresh.
Many pagelets display data that is time sensitive. In some cases, users should be able to navigate across links within a pagelet without changing or refreshing the rest of the page. You can refresh pagelet content on command, associate the refresh action with an event (refreshOnEvent
), or program the pagelet to refresh at a set interval (setRefreshInterval
). The scripting framework also contains methods for expanding and collapsing pagelets. In the simplified example below, the refresh pagelet displays a "Refresh Portlet" button. Clicking the button updates the date and time displayed in the pagelet.
The in-place refresh is executed by calling the refresh()
method on the pagelet object instance. You can also set a new URL to be displayed within the pagelet upon refresh. (The title bar cannot be altered on refresh.)
<div style="padding:10px;" align="center"> <p><button onclick="refresh_portlet()">Refresh Portlet</button></p> <p><b>Current time is:</b><br> <span id="refreshTimeSpan"></span></p> </div> <script type="text/javascript"> function refresh_portlet() { var refreshPortlet =PTPortlet.getPortletByID($PORTLET_ID$); if (!refreshPortlet) { refresh_debug('Could not locate PTPortlet object which corresponds to <b>Refresh Portlet</b> on page.'); return; } refresh_debug('<b>Refresh Portlet</b> calling refresh() method.'); refreshPortlet.refresh(); } function refresh_debug(str) { if (window.PTDebugUtil) { PTDebugUtil.debug(str); } } var t =new Date(); document.getElementById('refreshTimeSpan').innerHTML =t; </script>
This section describes how browser-level variables can be stored and shared among pagelets, even if they are not on the same page. For example, a value entered by the user in one pagelet can be retrieved by another. The scripting framework acts as an intermediary, allowing all pagelets access to all values stored in a common session using session preferences.
Pagelets can use preferences to communicate with each other, but accessing preferences usually requires a round trip to a database. Session preferences provide a way to store and share settings in the user's session within the client browser. The Master-Detail design pattern illustrates the most basic usage of session preferences. This design pattern splits control and display between two pagelets. For example, the "master" pagelet could summarize data in list form, and the "detail" pagelet could display details on each data item in response to user selection. In the example below, the master pagelet displays a form that allows you to enter a color code in a text box.
When the user enters a color code in the text box, the color in the detail pagelet changes.
For each onkeyup
event that occurs in the "Enter color" text box in the master pagelet, the following steps are executed:
The master pagelet sets the session preference using the current value of the text box.
The master pagelet calls an update method on the detail pagelet.
The detail pagelet retrieves the session preference to get the color value.
The detail pagelet redraws its color swatch area to reflect the new color value.
Note:
Shared session preferences must be specified by name on the Preferences page for the pagelet in the Pagelet Producer Console or they will not be sent to the pagelet.
The adaptive pagelet scripting framework provides an easy way to detach the relationship between pagelets and use a common event interface for communication.
Note:
The example below is oversimplified; the master pagelet makes a direct call to a JavaScript method of the detail pagelet. Unless the master pagelet takes extra measures to ensure that the detail pagelet is actually present on the same page, calls from master to detail could generate errors.
Master Pagelet
<div style="padding:10px;" align="center"> <p><b>Enter color:</b> <input type="text" style="font-size:22px;font-weight:bold;text-align:center;" id="master_prefName" value="#FFFFFF" size="8" onkeyup="master_setPrefs(this.value)"></p><br> </div> <script type="text/javascript"> function master_setPrefs(val) { var prefName ='masterColor'; var prefValue =val; PTPortlet.setSessionPref(prefName,prefValue); master_debug('<b>Master Portlet</b> called PTPortlet.setSessionPref(\'masterColor\',\'' +prefValue +'\').'); if (window.detail_update) { master_debug('<b>Master Portlet</b> calling detail_update().'); detail_update(); } else { master_debug('Could not locate portlet <b>Detail Portlet</b> on page.'); } } function master_debug(str) { if (window.PTDebugUtil) { PTDebugUtil.debug(str); } } </script>
Detail Pagelet
<div style="padding:10px;" align="center"> <p><b>Color swatch</b> <div style="width:100px;height:100px;border:2px solid black;padding:2px;"id="detail-swatch"></div> <script> function detail_update() { var color =PTPortlet.getSessionPref('masterColor'); detail_debug('<b>Detail Portlet</b> received value="' +color +'" for PTPortlet.getSessionPref(\'masterColor\')'); var swatch =document.getElementById('detail-swatch'); if (swatch) { swatch.innerHTML ='<div style="background-color:' +color +';width:100%;height:100%;"></div>'; } else { detail_debug('<b>Detail Portlet</b> cannot find \'detail-swatch\' DIV element.'); } } function detail_debug(str) { if (window.PTDebugUtil) { PTDebugUtil.debug(str); } } </script>
These tips apply to most pagelets that use the adaptive pagelet scripting framework.
Use unique names for all forms and functions. Use the GUID of a pagelet to form unique names and values to avoid name collisions with other code on the page.
Proxy all URLs. You cannot make a request to a URL with a host/port that is different from that of the calling page. All URLs requested through JavaScript must be proxied.
If you are using the adaptive pagelet scripting framework, check for support. It is good practice to include code that determines whether or not the component is present. Ideally, your pagelet should be able to handle either situation. The simplest solution is to precede your code with an If statement that alerts the user if the scripting framework is not supported.
<script> if (PTPortlet ==null) { if (document.PCC ==null) { alert("This pagelet only works in portals that support the JSPortlet API . The pagelet will be displayed with severely reduced functionality. Contact your Administrator."); } } else { [scripting code here] } </script>
Close all popup windows opened by a pagelet when the window closes. The scripting framework can be used to close popup windows using the onunload
event.
Add all required JavaScript to the page in advance. Browsers might not process script blocks/includes added to the page through the innerHTML
property.
Microsoft Internet Explorer: Add the defer attribute to the script tag.
Netscape: Use RegExp to parse the response and look for the script, then eval it.
JavaScript HTTP and proxied HTTP must use the same authentication credentials. JavaScript brokered HTTP requests send the same authentication token (cookie) as when you make a normal gatewayed HTTP request.
This section describes how to modify pagelet functionality at runtime using custom injectors and parsers.
This section includes the following topics:
A web injector inserts content into a specified location in the proxied resource page. The content may be any text, including HTML, CSS, JavaScript, and pagelet declarations. An empty injector may also be used to remove unwanted content from a page. Injectors cannot be created for OpenSocial resources. While injecting simple HTML content has a limited use case, you can also inject JavaScript that directly modifies the pagelet's HTML markup. For details on creating a web injector, see Creating Web Injectors.
Custom parsers allow you to supplement or change built-in logic for parsing content and finding URLs. When the built-in parsers fail to identify URLs or identify sections that must not be rewritten as URLs, custom parsers can be used to change the default behavior. Parsers cannot be created for WSRP or Oracle PDK-Java portlet producers or for OpenSocial gadget producers. For details on creating a custom parser, see Creating Custom Parsers.
This section describes how to use advanced logging traces for debugging pagelets. Logging is configured in the Settings section of the Pagelet Producer Console, where you can define different levels of logging for each Pagelet Producer component. For more information, see Configuring Pagelet Producer Settings.
This section includes the following topics:
To view the HTTP requests and responses received and sent by Pagelet Producer, set the HTTP component on the Logging Settings page to Finest. The traces in "HTTP Request Received By Pagelet Producer," "HTTP Response Sent By Pagelet Producer," "HTTP Request Sent By Pagelet Producer," and "HTTP Response Received By Pagelet Producer" were captured from a test environment.
HTTP Request Received By Pagelet Producer
URL: http://example.com:7001/pagelets/bidwiki/includes/js/ajax.js METHOD: GET SESSION ID: GdYGNJzMhxy1CJBMVTX8xTNq32GmLXYNY9VqFBcdprFnhcyQtzdp!1377086614!1305769149498 HEADERS: Host: example.com Connection: keep-alive Referer: http://example.com:7001/pagelets/bidwiki/dashboard.action User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.205 Safari/534.16 Accept: */* Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,en;q=0.8,ru;q=0.6,it;q=0.4 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 If-None-Match: W/"736-1124953206000" If-Modified-Since: Thu, 25 Aug 2012 07:00:06 GMT COOKIES: JSESSIONID: GdYGNJzMhxy1CJBMVTX8xTNq32GmLXYNY9VqFBcdprFnhcyQtzdp!1377086614
HTTP Response Sent By Pagelet Producer
URL: http://example.com:7001/pagelets/bidwiki/styles/main-action.css Response Code: 200 Reason: HEADERS: Date: Thu, 19 May 2011 01:39:14 GMT Content-Type: text/css;charset=UTF-8 Server: Apache-Coyote/1.1 BODY: .sidebar { /*background-image: url(http://example.com:7001/pagelets/bidwiki/download/ resources/leftnav_bg.jpg);*/ /*background-repeat: repeat-y;*/ background-color: #F0F0F0; /*border-bottom:1px solid #F0F0F0;*/ } ...
HTTP Request Sent By Pagelet Producer
URL: http://xmlns.oracle.com/includes/js/ajax.js METHOD: GET HEADERS: CSP-Ensemble-REST-API: http://example.com:7001/pagelets X-Client-IP: example.com User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.205 Safari/534.16 CSP-Session-Username: weblogic Accept-Language: en-US,en;q=0.8,ru;q=0.6,it;q=0.4 CSP-Gateway-Type: Proxy PT-Proxy-Passes: 1 If-Modified-Since: Thu, 25 Aug 2012 07:00:06 GMT CSP-Protocol-Version: 1.4 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 Accept-Encoding: gzip,deflate,sdch Referer: http://example.com:7001/pagelets/bidwiki/dashboard.action If-None-Match: W/"736-1124953206000" Accept: */* CSP-Aggregation-Mode: Single PT-Proxy-instance0: {DECBB085-D891-72CF-2B75-005E7FE20000} CSP-Gateway-Specific-Config: PT-User-Name=weblogic,PT-Guest-User=0,...
HTTP Response Received By Pagelet Producer
Original URI: http://xmlns.oracle.com/styles/main-action.css Effective URI: http://xmlns.oracle.com/styles/main-action.css Status Code: 200 Reason: OK Version: HTTP/1.1 HEADERS: Content-Type: text/css;charset=UTF-8 Content-Length: 29178 Server: Apache-Coyote/1.1 Date: Thu, 19 May 2011 01:39:14 GMT TRAILERS: BODY: body, p, td, table, tr, .bodytext, .stepfield { font-family: Verdana, arial, sans-serif; font-size: 11px; line-height: 16px; color: #000000; font-weight: normal; }
To view the content proxied by Pagelet Producer before and after transformation, set the Transform component on the Logging Settings page to Finest. The purpose of these traces is to log response content at different stages of transformation, allowing you to compare them and view the result of different transformers. The example traces in the following examples were captured from a test environment.
Example: Untransformed Markup
Original request: URL: http://example.com:7001/pagelets/bidwiki/styles/main-action.css METHOD: GET SESSION ID: GdYGNJzMhxy1CJBMVTX8xTNq32GmLXYNY9VqFBcdprFnhcyQtzdp!1377086614!1305769149498 HEADERS: Host: example.com:7001 Connection: keep-alive Referer: http://example.com:7001/pagelets/bidwiki/dashboard.action User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.205 Safari/534.16 Accept: text/css,*/*;q=0.1 Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,en;q=0.8,ru;q=0.6,it;q=0.4 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 COOKIES: JSESSIONID: GdYGNJzMhxy1CJBMVTX8xTNq32GmLXYNY9VqFBcdprFnhcyQtzdp!1377086614 Untransformed content: body, p, td, table, tr, .bodytext, .stepfield { font-family: Verdana, arial, sans-serif; font-size: 11px; line-height: 16px; color: #000000; font-weight: normal; }
Example: Transformed Markup (Transformed by Transformer Class)
Transformed by: class com.plumtree.server.impl.portlet.transformers.CSSTurboParser Original request: URL: http://example.com:7001/pagelets/bidwiki/styles/main-action.css METHOD: GET SESSION ID: GdYGNJzMhxy1CJBMVTX8xTNq32GmLXYNY9VqFBcdprFnhcyQtzdp!1377086614!1305769149498 HEADERS: Host: 10.148.118.211:7001 Connection: keep-alive Referer: http://example.com:7001/pagelets/bidwiki/dashboard.action User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.205 Safari/534.16 Accept: text/css,*/*;q=0.1 Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,en;q=0.8,ru;q=0.6,it;q=0.4 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 COOKIES: JSESSIONID: GdYGNJzMhxy1CJBMVTX8xTNq32GmLXYNY9VqFBcdprFnhcyQtzdp!1377086614 Transformed content: body, p, td, table, tr, .bodytext, .stepfield { font-family: Verdana, arial, sans-serif; font-size: 11px; line-height: 16px; color: #000000; font-weight: normal; }