You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@deltaspike.apache.org by st...@apache.org on 2013/04/21 21:46:17 UTC
[3/3] git commit: DELTASPIKE-289 migrate windowhandler from CODI
DELTASPIKE-289 migrate windowhandler from CODI
Project: http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/commit/45770596
Tree: http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/tree/45770596
Diff: http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/diff/45770596
Branch: refs/heads/master
Commit: 45770596d64be289e202339bbc02ebb22aed3758
Parents: 30661b0
Author: Mark Struberg <st...@apache.org>
Authored: Sun Apr 21 20:56:15 2013 +0200
Committer: Mark Struberg <st...@apache.org>
Committed: Sun Apr 21 20:56:15 2013 +0200
----------------------------------------------------------------------
.../core/impl/scope/window/WindowBeanHolder.java | 7 +-
deltaspike/modules/jsf/impl/pom.xml | 4 +
.../request/DeltaSpikeLifecycleWrapper.java | 30 ++-
.../jsf/impl/scope/window/DefaultClientWindow.java | 165 +++++++++++++-
.../META-INF/resources/js/windowhandler.js | 180 +++++++++++++++
.../src/main/resources/static/windowhandler.html | 170 ++++++++++++++
6 files changed, 545 insertions(+), 11 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/45770596/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/scope/window/WindowBeanHolder.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/scope/window/WindowBeanHolder.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/scope/window/WindowBeanHolder.java
index b4acc46..429fa20 100644
--- a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/scope/window/WindowBeanHolder.java
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/scope/window/WindowBeanHolder.java
@@ -41,7 +41,7 @@ public class WindowBeanHolder implements Serializable
* value: the {@link ContextualStorage} which holds all the
* {@link javax.enterprise.inject.spi.Bean}s.
*/
- private volatile Map<String, ContextualStorage> storageMap = new ConcurrentHashMap<String, ContextualStorage>();
+ private Map<String, ContextualStorage> storageMap = new ConcurrentHashMap<String, ContextualStorage>();
/**
* This method will return the ContextualStorage or create a new one
@@ -67,6 +67,11 @@ public class WindowBeanHolder implements Serializable
return contextualStorage;
}
+ public Map<String, ContextualStorage> getStorageMap()
+ {
+ return storageMap;
+ }
+
/**
*
* This method will replace the storageMap and with
http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/45770596/deltaspike/modules/jsf/impl/pom.xml
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jsf/impl/pom.xml b/deltaspike/modules/jsf/impl/pom.xml
index c71899f..ee9947c 100644
--- a/deltaspike/modules/jsf/impl/pom.xml
+++ b/deltaspike/modules/jsf/impl/pom.xml
@@ -65,6 +65,10 @@
<version>1.0</version>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-servlet_3.0_spec</artifactId>
+ </dependency>
<!-- we use Arquillian Warp to test our JSF apps -->
<dependency>
http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/45770596/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/request/DeltaSpikeLifecycleWrapper.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/request/DeltaSpikeLifecycleWrapper.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/request/DeltaSpikeLifecycleWrapper.java
index 9d4808d..0f91b33 100644
--- a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/request/DeltaSpikeLifecycleWrapper.java
+++ b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/request/DeltaSpikeLifecycleWrapper.java
@@ -19,7 +19,9 @@
package org.apache.deltaspike.jsf.impl.listener.request;
import org.apache.deltaspike.core.api.provider.BeanProvider;
+import org.apache.deltaspike.core.spi.scope.window.WindowContext;
import org.apache.deltaspike.core.util.ClassDeactivationUtils;
+import org.apache.deltaspike.jsf.spi.scope.window.ClientWindow;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseListener;
@@ -31,6 +33,9 @@ class DeltaSpikeLifecycleWrapper extends Lifecycle
private BeforeAfterJsfRequestBroadcaster beforeAfterJsfRequestBroadcaster;
+ private ClientWindow clientWindow;
+ private WindowContext windowContext;
+
private volatile Boolean initialized;
DeltaSpikeLifecycleWrapper(Lifecycle wrapped)
@@ -53,13 +58,19 @@ class DeltaSpikeLifecycleWrapper extends Lifecycle
@Override
public void execute(FacesContext facesContext)
{
+ lazyInit();
+
//TODO broadcastApplicationStartupBroadcaster();
broadcastBeforeFacesRequestEvent(facesContext);
- //X TODO add ClientWindow handling
- this.wrapped.execute(facesContext);
-
+ // ClientWindow handling
+ String windowId = clientWindow.getWindowId(facesContext);
+ if (windowId != null)
+ {
+ windowContext.activateWindow(windowId);
+ }
+ this.wrapped.execute(facesContext);
}
@Override
@@ -85,7 +96,6 @@ class DeltaSpikeLifecycleWrapper extends Lifecycle
private void broadcastBeforeFacesRequestEvent(FacesContext facesContext)
{
- lazyInit();
if (this.beforeAfterJsfRequestBroadcaster != null)
{
this.beforeAfterJsfRequestBroadcaster.broadcastBeforeJsfRequestEvent(facesContext);
@@ -103,15 +113,21 @@ class DeltaSpikeLifecycleWrapper extends Lifecycle
private synchronized void init()
{
// switch into paranoia mode
- if (this.initialized == null)
+ if (initialized == null)
{
if (ClassDeactivationUtils.isActivated(BeforeAfterJsfRequestBroadcaster.class))
{
- this.beforeAfterJsfRequestBroadcaster =
+ beforeAfterJsfRequestBroadcaster =
BeanProvider.getContextualReference(BeforeAfterJsfRequestBroadcaster.class, true);
+
+ clientWindow =
+ BeanProvider.getContextualReference(ClientWindow.class, true);
+
+ windowContext =
+ BeanProvider.getContextualReference(WindowContext.class, true);
}
- this.initialized = true;
+ initialized = true;
}
}
}
http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/45770596/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/scope/window/DefaultClientWindow.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/scope/window/DefaultClientWindow.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/scope/window/DefaultClientWindow.java
index 4ab6d37..3ea9478 100644
--- a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/scope/window/DefaultClientWindow.java
+++ b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/scope/window/DefaultClientWindow.java
@@ -19,13 +19,20 @@
package org.apache.deltaspike.jsf.impl.scope.window;
import javax.enterprise.context.ApplicationScoped;
+import javax.faces.FacesException;
import javax.faces.component.UIViewRoot;
+import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.OutputStream;
import java.util.logging.Logger;
import org.apache.deltaspike.core.spi.scope.window.WindowContext;
+import org.apache.deltaspike.jsf.impl.util.JsfUtils;
import org.apache.deltaspike.jsf.spi.scope.window.ClientWindow;
import org.apache.deltaspike.jsf.spi.scope.window.ClientWindowConfig;
@@ -46,6 +53,24 @@ public class DefaultClientWindow implements ClientWindow
{
private static final Logger logger = Logger.getLogger(DefaultClientWindow.class.getName());
+ private static final String WINDOW_ID_COOKIE_PREFIX = "dsWindowId-";
+ private static final String DELTASPIKE_REQUEST_TOKEN = "dsRid";
+
+ private static final String UNINITIALIZED_WINDOW_ID_VALUE = "uninitializedWindowId";
+ private static final String WINDOW_ID_REPLACE_PATTERN = "$$windowIdValue$$";
+ private static final String NOSCRIPT_URL_REPLACE_PATTERN = "$$noscriptUrl$$";
+
+ /**
+ * Use this parameter to force a 'direct' request from the clients without any windowId detection
+ * We keep this name for backward compat with CODI.
+ */
+ private static final String NOSCRIPT_PARAMETER = "mfDirect";
+
+ /**
+ * This windowId will be used for all requests with disabled windowId feature
+ */
+ private static final String DEFAULT_WINDOW_ID = "default";
+
@Inject
private ClientWindowConfig clientWindowConfig;
@@ -59,16 +84,36 @@ public class DefaultClientWindow implements ClientWindow
{
if (ClientWindowRenderMode.NONE.equals(clientWindowConfig.getClientWindowRenderMode(facesContext)))
{
- return null;
+ // if this request should not get any window detection then we are done
+ return DEFAULT_WINDOW_ID;
}
- String windowId = null;
-
if (facesContext.isPostback())
{
+ // for POST we read the windowId from the WindowIdHolderComponent in our ViewRoot
return getPostBackWindowId(facesContext);
}
+ ExternalContext externalContext = facesContext.getExternalContext();
+
+ // and now for the GET request stuff
+ if (isNoscriptRequest(externalContext))
+ {
+ // the client has JavaScript disabled
+ clientWindowConfig.setJavaScriptEnabled(false);
+
+ return DEFAULT_WINDOW_ID;
+ }
+
+ String windowId = getVerifiedWindowIdFromCookie(externalContext);
+ if (windowId == null)
+ {
+ // GET request without windowId - send windowhandlerfilter.html to get the windowId
+ sendWindowHandlerHtml(externalContext, null);
+ facesContext.responseComplete();
+ }
+
+ // we have a valid windowId - set it and continue with the request
return windowId;
}
@@ -93,4 +138,118 @@ public class DefaultClientWindow implements ClientWindow
}
+ private boolean isNoscriptRequest(ExternalContext externalContext)
+ {
+ String noscript = externalContext.getRequestParameterMap().get(NOSCRIPT_PARAMETER);
+
+ return (noscript != null && "true".equals(noscript));
+ }
+
+
+ private void sendWindowHandlerHtml(ExternalContext externalContext, String windowId)
+ {
+ HttpServletResponse httpResponse = (HttpServletResponse) externalContext.getResponse();
+
+ try
+ {
+ httpResponse.setStatus(HttpServletResponse.SC_OK);
+ httpResponse.setContentType("text/html");
+
+ String windowHandlerHtml = clientWindowConfig.getClientWindowHtml();
+
+ if (windowId == null)
+ {
+ windowId = UNINITIALIZED_WINDOW_ID_VALUE;
+ }
+
+ // set the windowId value in the javascript code
+ windowHandlerHtml = windowHandlerHtml.replace(WINDOW_ID_REPLACE_PATTERN, windowId);
+
+ // set the noscript-URL for users with no JavaScript
+ windowHandlerHtml =
+ windowHandlerHtml.replace(NOSCRIPT_URL_REPLACE_PATTERN, getNoscriptUrl(externalContext));
+
+ OutputStream os = httpResponse.getOutputStream();
+ try
+ {
+ os.write(windowHandlerHtml.getBytes());
+ }
+ finally
+ {
+ os.close();
+ }
+ }
+ catch (IOException ioe)
+ {
+ throw new FacesException(ioe);
+ }
+ }
+
+ private String getNoscriptUrl(ExternalContext externalContext)
+ {
+ String url = externalContext.getRequestPathInfo();
+ if (url == null)
+ {
+ url = "";
+ }
+
+ // only use the very last part of the url
+ int lastSlash = url.lastIndexOf('/');
+ if (lastSlash != -1)
+ {
+ url = url.substring(lastSlash + 1);
+ }
+
+ // add request parameter
+ url = JsfUtils.addPageParameters(externalContext, url, true);
+
+ // add noscript parameter
+ if (url.contains("?"))
+ {
+ url = url + "&";
+ }
+ else
+ {
+ url = url + "?";
+ }
+ url = url + NOSCRIPT_PARAMETER + "=true";
+
+ // NOTE that the url could contain data for an XSS attack
+ // like e.g. ?"></a><a href%3D"http://hacker.org/attack.html?a
+ // DO NOT REMOVE THE FOLLOWING LINES!
+ url = url.replace("\"", "");
+ url = url.replace("\'", "");
+
+ return url;
+ }
+
+ private String getVerifiedWindowIdFromCookie(ExternalContext externalContext)
+ {
+ String cookieName = WINDOW_ID_COOKIE_PREFIX + getRequestToken(externalContext);
+ Cookie cookie = (Cookie) externalContext.getRequestCookieMap().get(cookieName);
+
+ if (cookie != null)
+ {
+ // manually blast the cookie away, otherwise it pollutes the
+ // cookie storage in some browsers. E.g. Firefox doesn't
+ // cleanup properly, even if the max-age is reached.
+ cookie.setMaxAge(0);
+
+ return cookie.getValue();
+ }
+
+ return null;
+ }
+
+ private String getRequestToken(ExternalContext externalContext)
+ {
+ String requestToken = externalContext.getRequestParameterMap().get(DELTASPIKE_REQUEST_TOKEN);
+ if (requestToken != null)
+ {
+ return requestToken;
+ }
+
+ return "";
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/45770596/deltaspike/modules/jsf/impl/src/main/resources/META-INF/resources/js/windowhandler.js
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jsf/impl/src/main/resources/META-INF/resources/js/windowhandler.js b/deltaspike/modules/jsf/impl/src/main/resources/META-INF/resources/js/windowhandler.js
new file mode 100644
index 0000000..b563b31
--- /dev/null
+++ b/deltaspike/modules/jsf/impl/src/main/resources/META-INF/resources/js/windowhandler.js
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+(function() {
+//wrapping so that all internal functions are privately scoped
+function isHtml5() {
+ try {
+ return !!localStorage.getItem;
+ } catch(e) {
+ return false;
+ }
+}
+
+// some browsers don't understand JSON - guess which one ... :(
+function stringify(someArray) {
+ if (JSON) {
+ return JSON.stringify(someArray);
+ }
+ return someArray.join("|||");
+}
+
+// store the current body in the html5 localstorage
+function storeWindowTree() {
+ // first we store all CSS we also need on the intermediate page
+ var headNodes = document.getElementsByTagName("head")[0].childNodes;
+ var oldSS = new Array();
+ var j = 0;
+ for (var i = 0; i < headNodes.length; i++) {
+ var tagName = headNodes[i].tagName;
+ if (tagName && equalsIgnoreCase(tagName, "link") &&
+ equalsIgnoreCase(headNodes[i].getAttribute("type"), "text/css")) {
+
+ // sort out media="print" and stuff
+ var media = headNodes[i].getAttribute("media");
+ if (!media || equalsIgnoreCase(media, "all") || equalsIgnoreCase(media, 'screen')) {
+ oldSS[j++] = headNodes[i].getAttribute("href");
+ }
+ }
+ }
+ localStorage.setItem(window.name + '_css', stringify(oldSS));
+ var body = document.getElementsByTagName("body")[0];
+ localStorage.setItem(window.name + '_body', body.innerHTML);
+ //X TODO: store ALL attributes of the body tag
+ localStorage.setItem(window.name + '_bodyAttrs', body.getAttribute("class"));
+ return true;
+}
+
+function equalsIgnoreCase(source, destination) {
+ //either both are not set or null
+ if (!source && !destination) {
+ return true;
+ }
+ //source or dest is set while the other is not
+ if (!source || !destination) return false;
+
+ //in any other case we do a strong string comparison
+ return source.toLowerCase() === destination.toLowerCase();
+}
+
+/** This method will be called onWindowLoad and after AJAX success */
+function applyOnClick() {
+ var links = document.getElementsByTagName("a");
+ for (var i = 0; i < links.length; i++) {
+ if (!links[i].onclick) {
+ links[i].onclick = function() {storeWindowTree(); return true;};
+ } else {
+ // prevent double decoration
+ if (!("" + links[i].onclick).match(".*storeWindowTree().*")) {
+ //the function wrapper is important otherwise the
+ //last onclick handler would be assigned to oldonclick
+ (function storeEvent() {
+ var oldonclick = links[i].onclick;
+ links[i].onclick = function(evt) {
+ //ie handling added
+ evt = evt || window.event;
+
+ return storeWindowTree() && oldonclick(evt);
+ };
+ })();
+ }
+ }
+ }
+}
+
+function getUrlParameter(name) {
+ var url = window.location.href;
+ var vars = url.split(/&|\?/g);
+ for (var i=0; vars != null && i < vars.length; i++) {
+ var pair = vars[i].split("=");
+ if (pair[0]==name) {
+ return pair[1];
+ }
+ }
+ return null;
+}
+function setUrlParam(baseUrl, paramName, paramValue) {
+ var query = baseUrl;
+ var vars = query.split(/&|\?/g);
+ var newQuery = "";
+ var iParam = 0;
+ var paramFound = false;
+ for (var i=0; vars != null && i < vars.length; i++) {
+ var pair = vars[i].split("=");
+ if (pair.length == 1) {
+ newQuery = pair[0];
+ } else {
+ if (pair[0] != paramName) {
+ var amp = iParam++ > 0 ? "&" : "?";
+ newQuery = newQuery + amp + pair[0] + "=" + pair[1];
+ } else {
+ paramFound = true;
+ if (paramValue) {
+ var amp = iParam++ > 0 ? "&" : "?";
+ newQuery = newQuery + amp + paramName + "=" + paramValue;
+ }
+ }
+ }
+ }
+ if (!paramFound && paramValue) {
+ var amp = iParam++ > 0 ? "&" : "?";
+ newQuery = newQuery + amp + paramName + "=" + paramValue;
+ }
+ return newQuery;
+}
+// this method runs to ensure that windowIds get checked even if no windowhandler.html is used
+function assertWindowId() {
+ if (!window.name || window.name.length < 1) {
+ url = setUrlParam(window.location.href, 'windowId', null);
+ window.name = 'tempWindowId';
+ window.location = url;
+ }
+}
+
+function eraseRequestCookie() {
+ var requestToken = getUrlParameter('dsRid'); // random request param
+ if (requestToken) {
+ var cookieName = 'dsiWindowId-' + requestToken;
+ var date = new Date();
+ date.setTime(date.getTime()-(10*24*60*60*1000)); // - 10 day
+ var expires = "; expires="+date.toGMTString();
+ document.cookie = cookieName+"="+expires+"; path=/";
+ }
+}
+
+var ajaxOnClick = function ajaxDecorateClick(event) {
+ if (event.status=="success") {
+ applyOnClick();
+ }
+}
+
+var oldWindowOnLoad = window.onload;
+
+window.onload = function(evt) {
+ try {
+ (oldWindowOnLoad)? oldWindowOnLoad(evt): null;
+ } finally {
+ eraseRequestCookie(); // manually erase the old dsRid cookie because Firefox doesn't do it properly
+ assertWindowId();
+ if (isHtml5()) {
+ applyOnClick();
+ jsf.ajax.addOnEvent(ajaxOnClick);
+ }
+ }
+}
+})();
http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/45770596/deltaspike/modules/jsf/impl/src/main/resources/static/windowhandler.html
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jsf/impl/src/main/resources/static/windowhandler.html b/deltaspike/modules/jsf/impl/src/main/resources/static/windowhandler.html
new file mode 100644
index 0000000..c096722
--- /dev/null
+++ b/deltaspike/modules/jsf/impl/src/main/resources/static/windowhandler.html
@@ -0,0 +1,170 @@
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<html>
+
+<head><title>Loading...</title></head>
+<body $$bodyAttributes$$><div id="message" style="position:absolute;left:40%;top:40%">
+ Your browser does not support JavaScript.
+ Click <a href="$$noscriptUrl$$">here</a> to continue without JavaScript.
+</div></body>
+
+<script type="text/javascript" >
+function isHtml5() {
+ try { return !!localStorage.getItem;
+ } catch(e) { return false; }
+}
+function unstringify(serialized) {
+ if (JSON) { return JSON.parse(serialized); }
+ return serialized.split("|||");
+}
+function getOldBody() {
+ if (window.name.length != null) {
+ return localStorage.getItem(window.name + '_body');
+ }
+}
+function getOldBodyAttrs() {
+ if (window.name.length != null) {
+ return localStorage.getItem(window.name + '_bodyAttrs');
+ }
+}
+function getOldCss() {
+ if (window.name.length != null) {
+ return unstringify(localStorage.getItem(window.name + '_css'));
+ }
+}
+
+function addCss(url) {
+ var newSS = document.createElement("style");
+ newSS.setAttribute("rel", "stylesheet");
+ newSS.setAttribute("type", "text/css");
+ newSS.appendChild(document.createTextNode("@import url(" +url + ");"));
+ document.getElementsByTagName("head")[0].appendChild(newSS);
+}
+
+function loadCss(clean) {
+ if (!isHtml5()) { // only do this stuff on html browsers
+ return;
+ }
+ var oldCss = getOldCss();
+ if (window.name && oldCss) {
+ for (i=0; oldCss && i< oldCss.length; i++) {
+ addCss(oldCss[i]);
+ }
+ if (clean) {
+ localStorage.removeItem(window.name + '_css');
+ }
+ }
+}
+
+function replaceContent() {
+ if (!isHtml5()) { // only do this stuff on html browsers
+ document.getElementById('message').textContent = "Loading...";
+ return;
+ }
+ loadCss(false);
+
+ var oldBody = getOldBody();
+
+ if (window.name && oldBody) {
+ document.body.innerHTML = oldBody;
+
+ //X TODO should restore all attribs of the body tag
+ document.body.setAttribute("class", getOldBodyAttrs());
+ document.body.setAttribute("style", " cursor: wait !important;");
+
+ localStorage.removeItem(window.name + '_body');
+ localStorage.removeItem(window.name + '_bodyAttrs');
+
+ // overlay the doc with an un-clickable full-size div
+ var newDiv = document.createElement("div");
+ newDiv.setAttribute("style", "position:absolute; z-index:1000; background-color:transparent; top:0; left:0; width:100%; height: 100%");
+ newDiv.setAttribute("class", "fulldiv");
+ document.body.appendChild(newDiv);
+ } else {
+ document.getElementById('message').textContent = "Loading...";
+ }
+}
+
+function setUrlParam(baseUrl, paramName, paramValue) {
+ var query = baseUrl;
+ var vars = query.split(/&|\?/g);
+ var newQuery = "";
+ var iParam = 0;
+ var paramFound = false;
+ for (var i=0; vars != null && i < vars.length; i++) {
+ var pair = vars[i].split("=");
+ if (pair.length == 1) {
+ newQuery = pair[0];
+ } else {
+ if (pair[0] != paramName) {
+ var amp = iParam++ > 0 ? "&" : "?";
+ newQuery = newQuery + amp + pair[0] + "=" + pair[1];
+ } else {
+ paramFound = true;
+ var amp = iParam++ > 0 ? "&" : "?";
+ newQuery = newQuery + amp + paramName + "=" + paramValue;
+ }
+ }
+ }
+ if (!paramFound) {
+ var amp = iParam++ > 0 ? "&" : "?";
+ newQuery = newQuery + amp + paramName + "=" + paramValue;
+ }
+ return newQuery;
+}
+
+replaceContent();
+
+window.onload = function() {
+ loadCss(true);
+ // this will be replaced in the phase listener
+ var windowId = '$$windowIdValue$$';
+ if (windowId == 'uninitializedWindowId') {
+ windowId = window.name
+ }
+ if (!windowId || windowId.length < 1) {
+ // request a new windowId
+ windowId = 'automatedEntryPoint';
+ }
+
+ window.name = windowId;
+
+ // uncomment the following line to debug the intermediate page
+ // if (!confirm('reload?')) { return true; }
+
+ // 3 seconds expiry time
+ var expdt = new Date();
+ expdt.setTime(expdt.getTime()+(3*1000));
+ var expires = "; expires="+expdt.toGMTString();
+
+ var requestToken = Math.floor(Math.random()*1001);
+ var newUrl = setUrlParam(window.location.href, "dsRid", requestToken);
+ newUrl = setUrlParam(newUrl, "windowId", windowId);
+
+ document.cookie = 'dsWindowId-' + requestToken + '=' + windowId + expires+"; path=/";
+
+ window.location = newUrl;
+}
+</script>
+
+</html>
+