You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by st...@apache.org on 2011/11/15 20:24:15 UTC

svn commit: r1202386 - in /myfaces/extensions/cdi/trunk: examples/jsf-playground/clientside_windowhandler_jsf20/src/main/java/org/apache/myfaces/examples/jsf20/conversation/grouped/ examples/jsf-playground/clientside_windowhandler_jsf20/src/main/resour...

Author: struberg
Date: Tue Nov 15 19:24:14 2011
New Revision: 1202386

URL: http://svn.apache.org/viewvc?rev=1202386&view=rev
Log:
EXTCDI-240 remove flickering from ClientSideWindowHandler

Added:
    myfaces/extensions/cdi/trunk/examples/jsf-playground/clientside_windowhandler_jsf20/src/main/resources/META-INF/resources/
    myfaces/extensions/cdi/trunk/examples/jsf-playground/clientside_windowhandler_jsf20/src/main/resources/META-INF/resources/js/
    myfaces/extensions/cdi/trunk/examples/jsf-playground/clientside_windowhandler_jsf20/src/main/resources/META-INF/resources/js/windowhandler.js   (with props)
Modified:
    myfaces/extensions/cdi/trunk/examples/jsf-playground/clientside_windowhandler_jsf20/src/main/java/org/apache/myfaces/examples/jsf20/conversation/grouped/ConversationDemoBean1.java
    myfaces/extensions/cdi/trunk/examples/jsf-playground/clientside_windowhandler_jsf20/src/main/webapp/helloMyFacesCodi.xhtml
    myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/resources/static/windowhandler.html

Modified: myfaces/extensions/cdi/trunk/examples/jsf-playground/clientside_windowhandler_jsf20/src/main/java/org/apache/myfaces/examples/jsf20/conversation/grouped/ConversationDemoBean1.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/examples/jsf-playground/clientside_windowhandler_jsf20/src/main/java/org/apache/myfaces/examples/jsf20/conversation/grouped/ConversationDemoBean1.java?rev=1202386&r1=1202385&r2=1202386&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/examples/jsf-playground/clientside_windowhandler_jsf20/src/main/java/org/apache/myfaces/examples/jsf20/conversation/grouped/ConversationDemoBean1.java (original)
+++ myfaces/extensions/cdi/trunk/examples/jsf-playground/clientside_windowhandler_jsf20/src/main/java/org/apache/myfaces/examples/jsf20/conversation/grouped/ConversationDemoBean1.java Tue Nov 15 19:24:14 2011
@@ -68,6 +68,15 @@ public class ConversationDemoBean1 imple
 
     public String getValue()
     {
+        // sleep 3 seconds just for testing the flickering
+        try
+        {
+            Thread.sleep(3000);
+        }
+        catch (InterruptedException e)
+        {
+            // do nothing
+        }
         return value + createdAt.toLocaleString();
     }
 }

Added: myfaces/extensions/cdi/trunk/examples/jsf-playground/clientside_windowhandler_jsf20/src/main/resources/META-INF/resources/js/windowhandler.js
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/examples/jsf-playground/clientside_windowhandler_jsf20/src/main/resources/META-INF/resources/js/windowhandler.js?rev=1202386&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/examples/jsf-playground/clientside_windowhandler_jsf20/src/main/resources/META-INF/resources/js/windowhandler.js (added)
+++ myfaces/extensions/cdi/trunk/examples/jsf-playground/clientside_windowhandler_jsf20/src/main/resources/META-INF/resources/js/windowhandler.js Tue Nov 15 19:24:14 2011
@@ -0,0 +1,103 @@
+/*
+ * 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 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 (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();
+}
+
+function applyOnClick()
+{
+    var links = document.getElementsByTagName("a");
+    for(var i = 0; i < links.length; i++)
+    {
+        if (!links[i].onclick)
+        {
+            links[i].setAttribute('onclick', 'storeWindowTree(); return true;');
+        }
+        else
+        {
+            var oldClick = links[i].getAttribute('onclick').replace(/\'/g,'\\\'');
+            var onclickCode = "jsf.util.chain(this, event, storeWindowTree(), '" + oldClick + "');";
+            links[i].setAttribute('onclick', onclickCode);
+        }
+    }
+}
+
+window.onload = function()
+{
+    if (isHtml5())
+    {
+        applyOnClick();
+    }
+}

Propchange: myfaces/extensions/cdi/trunk/examples/jsf-playground/clientside_windowhandler_jsf20/src/main/resources/META-INF/resources/js/windowhandler.js
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: myfaces/extensions/cdi/trunk/examples/jsf-playground/clientside_windowhandler_jsf20/src/main/webapp/helloMyFacesCodi.xhtml
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/examples/jsf-playground/clientside_windowhandler_jsf20/src/main/webapp/helloMyFacesCodi.xhtml?rev=1202386&r1=1202385&r2=1202386&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/examples/jsf-playground/clientside_windowhandler_jsf20/src/main/webapp/helloMyFacesCodi.xhtml (original)
+++ myfaces/extensions/cdi/trunk/examples/jsf-playground/clientside_windowhandler_jsf20/src/main/webapp/helloMyFacesCodi.xhtml Tue Nov 15 19:24:14 2011
@@ -26,7 +26,11 @@
       xmlns:h="http://java.sun.com/jsf/html"
       xmlns:ui="http://java.sun.com/jsf/facelets">
 
-    <head><title>CODI JSF 2.0 Client Side WindowHandler Demo</title></head>
+    <head>
+        <title>CODI JSF 2.0 Client Side WindowHandler Demo</title>
+        <h:outputScript library="javax.faces" name="jsf.js"/>
+        <h:outputScript library="js" name="windowhandler.js"/>
+    </head>
 
     <body>
         <h1 style="color:red">Dev-Demo (purpose: only for tests during development)</h1>
@@ -59,4 +63,4 @@
         
         <h:messages globalOnly="true"/>
     </body>
-</html>
\ No newline at end of file
+</html>

Modified: myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/resources/static/windowhandler.html
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/resources/static/windowhandler.html?rev=1202386&r1=1202385&r2=1202386&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/resources/static/windowhandler.html (original)
+++ myfaces/extensions/cdi/trunk/jee-modules/jsf-module/impl/src/main/resources/static/windowhandler.html Tue Nov 15 19:24:14 2011
@@ -20,49 +20,145 @@
  under the License.
 -->
 <html>
-    <head>
-        <meta http-equiv="cache-control" content="no-cache">
-        <meta http-equiv="pragma" content="no-cache">
-        <script type="text/javascript" >
-            window.onload = function()
-            {
-                document.getElementById('message').textContent = "Loading...";
-
-                // this will be replaced in the phase listener
-                var windowId = '$$windowIdValue$$';
-
-                if (windowId == 'uninitializedWindowId')
-                {
-                    windowId = window.name
-                }
-
-                if (!windowId || windowId.length < 3)
-                {
-                    // request a new windowId
-                    windowId = 'automatedEntryPoint';
-                }
-                
-                window.name = windowId;
-
-                // 2 seconds expiry time
-                var expdt = new Date();
-                expdt.setTime(expdt.getTime()+(2*1000));
-                var expires = "; expires="+expdt.toGMTString();
-
-                // include pathName (without "/"s) in cookie name
-                var pathName = encodeURIComponent(window.location.pathname.replace(/\//g, ""));
-
-                document.cookie = pathName + '-codiWindowId=' + windowId + expires;
-
-                // resubmit the page but now with the cookie
-                window.location.reload();
-            }
-        </script>
-    </head>
+
+<head>
+    <title>Loading...</title>
+</head>
 <body>
-    <div id="message" style="position:absolute;left:40%;top:40%;" >
-        Your browser does not support JavaScript!<br/><br/>
-        Click <a href="$$noscriptUrl$$">here to continue without JavaScript</a>.
-    </div>
+<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());
+
+        localStorage.removeItem(window.name + '_body');
+        localStorage.removeItem(window.name + '_bodyAttrs');
+    }
+    else {
+        document.getElementById('message').textContent = "Loading...";
+    }
+}
+
+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 < 3)
+    {
+        // request a new windowId
+        windowId = 'automatedEntryPoint';
+    }
+
+    window.name = windowId;
+
+    /* used to debug the intermediate page
+    if (!confirm('reload?')) {
+        return true;
+    }
+    */
+
+    // 2 seconds expiry time
+    var expdt = new Date();
+    expdt.setTime(expdt.getTime()+(2*1000));
+    var expires = "; expires="+expdt.toGMTString();
+
+    // include pathName (without "/"s) in cookie name
+    var pathName = encodeURIComponent(window.location.pathname.replace(/\//g, ""));
+
+    document.cookie = pathName + '-codiWindowId=' + windowId + expires;
+
+    // resubmit the page but now with the cookie
+    window.location.reload();
+}
+</script>
+
 </html>
+