Author: Christian Lopes
Date: 2010-12-20 15:14:14 -0800 (Mon, 20 Dec 2010)
New Revision: 23250

Added:
   
cytoscapeweb/trunk/cytoscapeweb/src-test/org/cytoscapeweb/view/render/ImageCacheTest.as
Modified:
   cytoscapeweb/trunk/cytoscapeweb/html-template/js/cytoscapeweb.js
   cytoscapeweb/trunk/cytoscapeweb/html-template/js/tests.js
   cytoscapeweb/trunk/cytoscapeweb/src-test/org/cytoscapeweb/AllTests.as
   
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/SetVisualStyleBypassCommand.as
   
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/SetVisualStyleCommand.as
   cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/ExternalMediator.as
   
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/render/ImageCache.as
Log:
Fixed bug that could cause JS exceptions when applying a Style Bypass with 
special characters in node IDs.
Added unit test for ImageCache and fixed some related bugs.

Modified: cytoscapeweb/trunk/cytoscapeweb/html-template/js/cytoscapeweb.js
===================================================================
--- cytoscapeweb/trunk/cytoscapeweb/html-template/js/cytoscapeweb.js    
2010-12-20 23:05:21 UTC (rev 23249)
+++ cytoscapeweb/trunk/cytoscapeweb/html-template/js/cytoscapeweb.js    
2010-12-20 23:14:14 UTC (rev 23250)
@@ -242,8 +242,6 @@
             this.embedSWF();
             return this;
         },
-        
-        _debug: function(o) { console.log(o); },
 
         /**
          * <p>Register a function to be called after a {...@link 
org.cytoscapeweb.Visualization#draw} method is executed and the visualization
@@ -390,8 +388,15 @@
          */
         visualStyleBypass: function (/*bypass*/) {
             var swf = this.swf();
-            if (arguments.length > 0) { 
swf.setVisualStyleBypass(arguments[0]); return this; }
-            else { return swf.getVisualStyleBypass(); }
+            var json;
+            if (arguments.length > 0) {
+               json = JSON.stringify(arguments[0]); // to avoid errors with 
special characters in node IDs
+               swf.setVisualStyleBypass(json);
+               return this;
+            } else {
+               json = swf.getVisualStyleBypass();
+               return JSON.parse(json);
+            }
         },
 
         /**

Modified: cytoscapeweb/trunk/cytoscapeweb/html-template/js/tests.js
===================================================================
--- cytoscapeweb/trunk/cytoscapeweb/html-template/js/tests.js   2010-12-20 
23:05:21 UTC (rev 23249)
+++ cytoscapeweb/trunk/cytoscapeweb/html-template/js/tests.js   2010-12-20 
23:14:14 UTC (rev 23250)
@@ -531,6 +531,19 @@
 
     });
     
+    test("Get empty Visual Style Bypass", function() {
+       var bypass = vis.visualStyleBypass();
+       ok(bypass.nodes != null);
+       ok(bypass.edges != null);
+
+       var fail = false;
+       try {
+               for (k in bypass.nodes) throw("Bypass.nodes should be empty!");
+               for (k in bypass.edges) throw("Bypass.edges should be empty!");
+       } catch (err) { fail = true; }
+       ok(fail === false, "bypass[nodes|edges] should be empty");
+    });
+    
     test("Set Visual Style Bypass", function() {
        var bypass = { nodes: {}, edges: {} };
        var id;
@@ -541,40 +554,43 @@
        var edgeOpacity = function(id) { return (id % 2 === 0 ? 0.5 : 0); };
        var nodeColor = "#345678";
        var edgeWidth = 4;
+       
+       $.each(nodes, function(i, n) {
+               var o = nodeOpacity(n.data.id);
+               bypass.nodes[n.data.id] = { opacity: o, color: nodeColor };
+       });
+       $.each(edges, function(i, e) {
+               var o = edgeOpacity(e.data.id);
+               bypass.edges[e.data.id] = { opacity: o, width: edgeWidth };
+       });
+       
+       // Just to test special characters as part of ID's:
+       // Note: Any UNICODE character except " or \ or control character
+       bypass.nodes["_...@1/4-4+9,0;'3:a?*&^%$#!`~<>{}[]"] = { color: 
"#000000" };
+       vis.visualStyleBypass(bypass);
 
-               $.each(nodes, function(i, n) {
-                       var o = nodeOpacity(n.data.id);
-                       bypass.nodes[n.data.id] = { opacity: o, color: 
nodeColor };
-           });
-               $.each(edges, function(i, e) {
-                       var o = edgeOpacity(e.data.id);
-                       bypass.edges[e.data.id] = { opacity: o, width: 
edgeWidth };
-               });
-
-               vis.visualStyleBypass(bypass);
-
-               var bp = vis.visualStyleBypass();
-               same (bp, bypass);
-               
-               nodes = vis.nodes();
-               edges = vis.edges();
-               
-               $.each(nodes, function(i, n) {
-                       var expected = nodeOpacity(n.data.id);
-                       same(bp.nodes[n.data.id].opacity, expected);
-                       same(Math.round(n.opacity*100)/100, expected);
-                       
-                       same(bp.nodes[n.data.id].color, nodeColor);
-                       same(n.color, nodeColor);
-           });
-               $.each(edges, function(i, e) {
-                       var expected = edgeOpacity(e.data.id);
-                       same(bp.edges[e.data.id].opacity, expected);
-                       same(Math.round(e.opacity*100)/100, expected);
-                       
-                       same(bp.edges[e.data.id].width, edgeWidth);
-                       same(e.width, edgeWidth);
-               });
+       var bp = vis.visualStyleBypass();
+       same (bp, bypass);
+       
+       nodes = vis.nodes();
+       edges = vis.edges();
+       
+       $.each(nodes, function(i, n) {
+               var expected = nodeOpacity(n.data.id);
+               same(bp.nodes[n.data.id].opacity, expected);
+               same(Math.round(n.opacity*100)/100, expected);
+               
+               same(bp.nodes[n.data.id].color, nodeColor);
+               same(n.color, nodeColor);
+       });
+       $.each(edges, function(i, e) {
+               var expected = edgeOpacity(e.data.id);
+               same(bp.edges[e.data.id].opacity, expected);
+               same(Math.round(e.opacity*100)/100, expected);
+               
+               same(bp.edges[e.data.id].width, edgeWidth);
+               same(e.width, edgeWidth);
+       });
     });
     
     test("Remove Visual Style Bypass", function() {

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/SetVisualStyleBypassCommand.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/SetVisualStyleBypassCommand.as
      2010-12-20 23:05:21 UTC (rev 23249)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/SetVisualStyleBypassCommand.as
      2010-12-20 23:14:14 UTC (rev 23250)
@@ -55,7 +55,7 @@
             }
         }
         
-        private function ready():void {
+        private function ready(obj:Object=null):void {
             graphMediator.applyVisualBypass(configProxy.visualStyleBypass);
         }
     }

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/SetVisualStyleCommand.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/SetVisualStyleCommand.as
    2010-12-20 23:05:21 UTC (rev 23249)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/controller/SetVisualStyleCommand.as
    2010-12-20 23:14:14 UTC (rev 23250)
@@ -48,14 +48,16 @@
                 configProxy.bindGraphData(graphProxy.graphData);
                 
                 // Preload images?
-                if (configProxy.preloadImages)
+                if (configProxy.preloadImages) {
                     _imgCache.loadImages(configProxy.visualStyle, 
graphProxy.nodes, ready);
-                else
+                } else {
+                    _imgCache.dispose(); // TODO: implement a better way of 
disposing previous images.
                     ready();
+                }
             }
         }
         
-        private function ready():void {
+        private function ready(obj:Object=null):void {
             // Ask the mediators to apply the new style:
             appMediator.applyVisualStyle(configProxy.visualStyle);
             graphMediator.applyVisualStyle(configProxy.visualStyle);

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/ExternalMediator.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/ExternalMediator.as   
    2010-12-20 23:05:21 UTC (rev 23249)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/ExternalMediator.as   
    2010-12-20 23:14:14 UTC (rev 23250)
@@ -343,13 +343,15 @@
             return configProxy.visualStyle.toObject();
         }
         
-        private function 
setVisualStyleBypass(obj:/*{group->{id->{propName->value}}}*/Object):void {
+        private function 
setVisualStyleBypass(json:/*{group->{id->{propName->value}}}*/String):void {
+            var obj:Object = JSON.decode(json);
             var bypass:VisualStyleBypassVO = 
VisualStyleBypassVO.fromObject(obj);
             sendNotification(ApplicationFacade.SET_VISUAL_STYLE_BYPASS, 
bypass);
         }
         
-        private function getVisualStyleBypass():Object {
-            return configProxy.visualStyleBypass.toObject();
+        private function getVisualStyleBypass():String {
+            var obj:Object = configProxy.visualStyleBypass.toObject();
+            return JSON.encode(obj);
         }
         
         private function addNode(x:Number, y:Number, 

Modified: 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/render/ImageCache.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/render/ImageCache.as  
    2010-12-20 23:05:21 UTC (rev 23249)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src/org/cytoscapeweb/view/render/ImageCache.as  
    2010-12-20 23:14:14 UTC (rev 23250)
@@ -65,6 +65,16 @@
         private var _bypassUrl:/*URL->Boolean*/Object = {};
         private var _onLoadingEnd:Function;
         
+        // ========[ PUBLIC PROPERTIES 
]============================================================
+        
+        public function get size():int {
+            var count:int = 0;
+            for (var url:String in _images) {
+                if (_images[url] is BitmapData) count++;
+            }
+            return count;
+        }
+                
         // ========[ PUBLIC METHODS 
]===============================================================
         
         public function isLoading():Boolean {
@@ -96,7 +106,7 @@
          * @param onLoadingEnd An optional callback function
          */
         public function loadImages(style:*, nodes:Array=null, 
onLoadingEnd:Function=null):void {trace("ImageCache.loadImages...");
-            var url:String, values:Array;
+            var url:String, values:Array, pname:String;
             _onLoadingEnd = onLoadingEnd;
 
             function loadIfNew(url:String, urlMap:Object):void {
@@ -111,15 +121,14 @@
             if (style is VisualStyleVO) {
                 // Decrease image counter for all current images associated 
with the previous visual style:
                 releasePrevious(_styleUrl);
-                
                 var vs:VisualStyleVO = VisualStyleVO(style);
                 
-                   $each(IMG_PROPS, function(i:uint, pname:String):Boolean {
+                   for each (pname in IMG_PROPS) {
                        if (vs.hasVisualProperty(pname)) {
                            var vp:VisualPropertyVO = 
vs.getVisualProperty(pname);
                            // Default value:
-                           var def:String = vp.defaultValue;
-                           if (!contains(def)) loadIfNew(url, _styleUrl);
+                           url = vp.defaultValue;
+                           loadIfNew(url, _styleUrl);
                            
                            // Discrete Mapper values:
                            var mapper:VizMapperVO= vp.vizMapper;
@@ -138,22 +147,17 @@
                                }
                            }
                        }
-                       
-                       return false;
-                   });
+                   }
             } else if (style is VisualStyleBypassVO) {
-// TODO: Test!!!
                 releasePrevious(_bypassUrl);
 
-                $each(IMG_PROPS, function(i:uint, pname:String):Boolean {
+                for each (pname in IMG_PROPS) {
                     values = VisualStyleBypassVO(style).getValuesSet(pname);
                     
                     for each (url in values) {
                         loadIfNew(url, _bypassUrl);
                     }
-                    
-                    return false;
-                });
+                }
             }
             
             deleteUnusedImages();
@@ -179,6 +183,7 @@
                     bmp = e.target.content.bitmapData;
                     _images[url] = bmp;
                     _broken[url] = false;
+                    retain(url);
                     if (onImgLoaded != null) onImgLoaded(url, bmp);
                     checkOnLoadingEnd();
                 });
@@ -193,11 +198,20 @@
             }
         }
         
-        public function releaseBypassImages() {
+        public function releaseBypassImages():void {
             releasePrevious(_bypassUrl);
             deleteUnusedImages();
         }
         
+        public function dispose():void {
+            _images = {};
+            _broken = {};
+            _imgCounter= {};
+            _styleUrl = {};
+            _bypassUrl = {};
+            _onLoadingEnd = null;
+        }
+        
         // ========[ PRIVATE METHODS 
]==============================================================
         
         /**
@@ -213,7 +227,7 @@
                            // Execute the callback function only once!
                     var fn:Function = _onLoadingEnd;
                     _onLoadingEnd = null;
-                    fn();
+                    fn(undefined);
                        }
                }
         }

Modified: cytoscapeweb/trunk/cytoscapeweb/src-test/org/cytoscapeweb/AllTests.as
===================================================================
--- cytoscapeweb/trunk/cytoscapeweb/src-test/org/cytoscapeweb/AllTests.as       
2010-12-20 23:05:21 UTC (rev 23249)
+++ cytoscapeweb/trunk/cytoscapeweb/src-test/org/cytoscapeweb/AllTests.as       
2010-12-20 23:14:14 UTC (rev 23250)
@@ -45,6 +45,7 @@
        import org.cytoscapeweb.model.data.VizMapperVOTest;
        import org.cytoscapeweb.util.UtilsTest;
        import org.cytoscapeweb.util.VisualPropertiesTest;
+       import org.cytoscapeweb.view.render.ImageCacheTest;
        import org.cytoscapeweb.view.render.LabelerTest;
 
        public class AllTests extends TestSuite {
@@ -67,6 +68,7 @@
                        addTestSuite(FirstNeighborsVOTest);
                        
                        addTestSuite(LabelerTest);
+                       addTestSuite(ImageCacheTest);
                        
                        addTestSuite(XGMMLConverterTest);
                        addTestSuite(SIFConverterTest);

Added: 
cytoscapeweb/trunk/cytoscapeweb/src-test/org/cytoscapeweb/view/render/ImageCacheTest.as
===================================================================
--- 
cytoscapeweb/trunk/cytoscapeweb/src-test/org/cytoscapeweb/view/render/ImageCacheTest.as
                             (rev 0)
+++ 
cytoscapeweb/trunk/cytoscapeweb/src-test/org/cytoscapeweb/view/render/ImageCacheTest.as
     2010-12-20 23:14:14 UTC (rev 23250)
@@ -0,0 +1,114 @@
+/*
+  This file is part of Cytoscape Web.
+  Copyright (c) 2009, The Cytoscape Consortium (www.cytoscape.org)
+
+  The Cytoscape Consortium is:
+    - Agilent Technologies
+    - Institut Pasteur
+    - Institute for Systems Biology
+    - Memorial Sloan-Kettering Cancer Center
+    - National Center for Integrative Biomedical Informatics
+    - Unilever
+    - University of California San Diego
+    - University of California San Francisco
+    - University of Toronto
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+package org.cytoscapeweb.view.render {
+    import flash.utils.setTimeout;
+    
+    import flexunit.framework.TestCase;
+    
+    import org.cytoscapeweb.model.data.VisualStyleVO;
+    
+    
+    public class ImageCacheTest extends TestCase {
+        
+        private const IMG_1:String = "assets/images/icons/arrow_d_666666.png";
+        private const IMG_2:String = "assets/images/icons/zoom_fit_666666.png";
+        private const IMG_3:String = "assets/images/icons/closed_hand.png";
+        
+        private const EMPTY_VS:Object = {
+            global: {
+                backgroundColor: "#000000"
+            }
+        };
+        private const SIMPLE_VS:Object = {
+            global: {
+                backgroundColor: "#000000",
+                image: IMG_2 // Should be ignored for now!
+            },
+            nodes: {
+                opacity: 1,
+                image: IMG_1,
+                size: 40
+            },
+            edges: {
+                opacity: 1,
+                color: "#ff0000",
+                image: IMG_3 // Should be ignored!
+            }
+        };
+        
+        private var _cache:ImageCache = ImageCache.instance;
+        private var _emptyVs:VisualStyleVO;
+        private var _simpleVs:VisualStyleVO;
+        
+        public override function setUp():void {
+            _emptyVs = VisualStyleVO.fromObject(EMPTY_VS);
+            _simpleVs = VisualStyleVO.fromObject(SIMPLE_VS);
+        }
+        
+        // ========[ TESTS 
]========================================================================
+        
+        public function testLoadImagesFromSimpleVisualStyle():void {
+            // Initial state:
+            assertEquals(0, _cache.size);
+            assertFalse(_cache.isLoading());
+            
+            // Load images:
+            function runTest():void {
+               assertEquals(1, _cache.size);
+               assertFalse(_cache.isLoading());
+               
+               assertTrue(_cache.contains(IMG_1));
+               assertFalse(_cache.contains(IMG_2));
+               assertFalse(_cache.contains(IMG_3));
+               
+               assertTrue(_cache.isLoaded(IMG_1));
+               assertFalse(_cache.isLoaded(IMG_2));
+               assertFalse(_cache.isLoaded(IMG_3));
+               
+               assertFalse(_cache.isBroken(IMG_1));
+               assertFalse(_cache.isBroken(IMG_2));
+               assertFalse(_cache.isBroken(IMG_3));
+            }
+            
+            _cache.loadImages(_simpleVs, null, addAsync(runTest, 3000));
+        }
+        
+        public function testDispose():void {
+            // Initial state:
+            assertEquals(1, _cache.size);
+            assertFalse(_cache.isLoading());
+            
+            _cache.dispose();
+            assertEquals(0, _cache.size);
+            assertFalse(_cache.isLoading());
+        }
+
+    }
+}
\ No newline at end of file

-- 
You received this message because you are subscribed to the Google Groups 
"cytoscape-cvs" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/cytoscape-cvs?hl=en.

Reply via email to