Repository: openmeetings
Updated Branches:
  refs/heads/master 568c47ac6 -> dd043e069


[OPENMEETINGS-1639] seems to be implemented


Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/dd043e06
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/dd043e06
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/dd043e06

Branch: refs/heads/master
Commit: dd043e06962a4d3f57290f6bc6414b06b14ed1c2
Parents: 568c47a
Author: Maxim Solodovnik <[email protected]>
Authored: Sun Jul 2 23:03:34 2017 +0700
Committer: Maxim Solodovnik <[email protected]>
Committed: Sun Jul 2 23:03:34 2017 +0700

----------------------------------------------------------------------
 .../openmeetings/db/dto/room/Whiteboard.java    |   8 +-
 .../openmeetings/web/common/MainPanel.java      |  10 +-
 .../openmeetings/web/room/wb/UndoObject.java    |  61 +++++++++
 .../openmeetings/web/room/wb/WbPanel.java       | 129 ++++++++++++++++---
 .../org/apache/openmeetings/web/room/wb/wb.js   | 117 ++++++++++-------
 5 files changed, 249 insertions(+), 76 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/openmeetings/blob/dd043e06/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/Whiteboard.java
----------------------------------------------------------------------
diff --git 
a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/Whiteboard.java
 
b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/Whiteboard.java
index be67d0e..393f608 100644
--- 
a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/Whiteboard.java
+++ 
b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/Whiteboard.java
@@ -102,8 +102,8 @@ public class Whiteboard {
                return roomItems;
        }
 
-       public void put(String uid, JSONObject obj) {
-               roomItems.put(uid, obj);
+       public JSONObject put(String uid, JSONObject obj) {
+               return roomItems.put(uid, obj);
        }
 
        public JSONObject get(String uid) {
@@ -114,8 +114,8 @@ public class Whiteboard {
                return roomItems.entrySet();
        }
 
-       public void remove(Object oid) {
-               roomItems.remove(oid);
+       public JSONObject remove(Object oid) {
+               return roomItems.remove(oid);
        }
 
        public String getName() {

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/dd043e06/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
----------------------------------------------------------------------
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
index 50afb36..edd8c9f 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
@@ -102,11 +102,11 @@ public class MainPanel extends Panel {
        private static final WebMarkupContainer EMPTY = new 
WebMarkupContainer(CHILD_ID);
        public static final String PARAM_USER_ID = "userId";
        private String uid = null;
-       private final MenuPanel menu;
+       private final MenuPanel menu = new MenuPanel("menu", getMainMenu());
        private final WebMarkupContainer topControls = new 
WebMarkupContainer("topControls");
        private final WebMarkupContainer topLinks = new 
WebMarkupContainer("topLinks");
-       private final MarkupContainer contents;
-       private final ChatPanel chat;
+       private final MarkupContainer contents = new 
WebMarkupContainer("contents");
+       private final ChatPanel chat = new ChatPanel("chatPanel");
        private final MessageDialog newMessage;
        private final UserInfoDialog userInfo;
        private BasePanel panel;
@@ -128,9 +128,7 @@ public class MainPanel extends Panel {
                super(id);
                this.panel = _panel;
                setOutputMarkupId(true);
-               menu = new MenuPanel("menu", getMainMenu());
-               contents = new WebMarkupContainer("contents");
-               add(chat = new ChatPanel("chatPanel"));
+               add(chat);
                add(newMessage = new MessageDialog("newMessageDialog", new 
CompoundPropertyModel<>(new PrivateMessage())) {
                        private static final long serialVersionUID = 1L;
 

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/dd043e06/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/UndoObject.java
----------------------------------------------------------------------
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/UndoObject.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/UndoObject.java
new file mode 100644
index 0000000..08b9134
--- /dev/null
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/UndoObject.java
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+package org.apache.openmeetings.web.room.wb;
+
+import java.io.Serializable;
+
+import org.apache.openmeetings.util.NullStringer;
+
+import com.github.openjson.JSONArray;
+import com.github.openjson.JSONObject;
+
+public class UndoObject implements Serializable {
+       private static final long serialVersionUID = 1L;
+
+       public enum Type {
+               add
+               , remove
+               , modify
+       }
+       private final Type type;
+       private final String object;
+
+       public UndoObject(Type type, JSONObject obj) {
+               this.type = type;
+               this.object = obj.toString(new NullStringer());
+       }
+
+       public UndoObject(Type type, JSONArray arr) {
+               this.type = type;
+               this.object = arr.toString(new NullStringer());
+       }
+
+       public Type getType() {
+               return type;
+       }
+
+       public String getObject() {
+               return object;
+       }
+
+       @Override
+       public String toString() {
+               return "UndoObject [type=" + type + "]";
+       }
+}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/dd043e06/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
----------------------------------------------------------------------
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
index e70e410..3bd23a9 100644
--- 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
+++ 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
@@ -30,8 +30,13 @@ import java.io.File;
 import java.io.IOException;
 import java.nio.file.Files;
 import java.util.Arrays;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
 import java.util.Map.Entry;
 import java.util.UUID;
+import java.util.function.Function;
 import java.util.function.Predicate;
 
 import org.apache.openmeetings.core.data.whiteboard.WhiteboardCache;
@@ -86,6 +91,7 @@ public class WbPanel extends Panel {
        private static final int UPLOAD_WB_TOP = 0;
        private static final int DEFAULT_WIDTH = 640;
        private static final int DEFAULT_HEIGHT = 480;
+       private static final int UNDO_SIZE = 20;
        public static final String FUNC_ACTION = "wbAction";
        public static final String PARAM_ACTION = "action";
        public static final String PARAM_OBJ = "obj";
@@ -106,7 +112,9 @@ public class WbPanel extends Panel {
                , clearSlide
                , save
                , load
+               , undo
        }
+       private final Map<Long, Deque<UndoObject>> undoList = new HashMap<>();
        private final AbstractDefaultAjaxBehavior wbAction = new 
AbstractDefaultAjaxBehavior() {
                private static final long serialVersionUID = 1L;
 
@@ -122,7 +130,8 @@ public class WbPanel extends Panel {
                                StringValue sv = 
getRequest().getRequestParameters().getParameterValue(PARAM_OBJ);
                                JSONObject obj = sv.isEmpty() ? new 
JSONObject() : new JSONObject(sv.toString());
                                if (Action.createObj == a || Action.modifyObj 
== a) {
-                                       if 
("pointer".equals(obj.getJSONObject("obj").getString("type"))) {
+                                       JSONObject o = obj.optJSONObject("obj");
+                                       if (o != null && 
"pointer".equals(o.getString("type"))) {
                                                sendWbOthers(a, obj);
                                                return;
                                        }
@@ -181,31 +190,41 @@ public class WbPanel extends Panel {
                                                        Whiteboard wb = 
getBean(WhiteboardCache.class).get(roomId).get(obj.getLong("wbId"));
                                                        JSONObject o = 
obj.getJSONObject("obj");
                                                        
wb.put(o.getString("uid"), o);
+                                                       addUndo(wb.getId(), new 
UndoObject(UndoObject.Type.add, o));
                                                        
sendWbOthers(Action.createObj, obj);
                                                }
                                                        break;
                                                case modifyObj:
                                                {
                                                        Whiteboard wb = 
getBean(WhiteboardCache.class).get(roomId).get(obj.getLong("wbId"));
-                                                       JSONObject o = 
obj.getJSONObject("obj");
-                                                       JSONArray arr = 
o.optJSONArray("objects");
-                                                       if (arr == null) {
-                                                               
wb.put(o.getString("uid"), o);
-                                                       } else {
-                                                               for (int i = 0; 
i < arr.length(); ++i) {
-                                                                       
JSONObject _o = arr.getJSONObject(i);
-                                                                       
wb.put(_o.getString("uid"), _o);
-                                                               }
+                                                       JSONArray arr = 
obj.getJSONArray("obj");
+                                                       JSONArray undo = new 
JSONArray();
+                                                       for (int i = 0; i < 
arr.length(); ++i) {
+                                                               JSONObject _o = 
arr.getJSONObject(i);
+                                                               String uid = 
_o.getString("uid");
+                                                               
undo.put(wb.get(uid));
+                                                               wb.put(uid, _o);
+                                                       }
+                                                       if (arr.length() != 0) {
+                                                               
addUndo(wb.getId(), new UndoObject(UndoObject.Type.modify, undo));
                                                        }
                                                        
sendWbOthers(Action.modifyObj, obj);
                                                }
+                                                       break;
                                                case deleteObj:
                                                {
                                                        Whiteboard wb = 
getBean(WhiteboardCache.class).get(roomId).get(obj.getLong("wbId"));
                                                        JSONArray arr = 
obj.getJSONArray("obj");
+                                                       JSONArray undo = new 
JSONArray();
                                                        for (int i = 0; i < 
arr.length(); ++i) {
                                                                JSONObject _o = 
arr.getJSONObject(i);
-                                                               
wb.remove(_o.getString("uid"));
+                                                               JSONObject u = 
wb.remove(_o.getString("uid"));
+                                                               if (u != null) {
+                                                                       
undo.put(u);
+                                                               }
+                                                       }
+                                                       if (undo.length() != 0) 
{
+                                                               
addUndo(wb.getId(), new UndoObject(UndoObject.Type.remove, undo));
                                                        }
                                                        
sendWbAll(Action.deleteObj, obj);
                                                }
@@ -213,7 +232,17 @@ public class WbPanel extends Panel {
                                                case clearSlide:
                                                {
                                                        Whiteboard wb = 
getBean(WhiteboardCache.class).get(roomId).get(obj.getLong("wbId"));
-                                                       
wb.entrySet().removeIf(e -> e.getValue().optInt("slide", -1) == 
obj.getInt("slide"));
+                                                       JSONArray arr = new 
JSONArray();
+                                                       
wb.entrySet().removeIf(e -> {
+                                                                       boolean 
match = e.getValue().optInt("slide", -1) == obj.getInt("slide");
+                                                                       if 
(match) {
+                                                                               
arr.put(e);
+                                                                       }
+                                                                       return 
match;
+                                                               });
+                                                       if (arr.length() != 0) {
+                                                               
addUndo(wb.getId(), new UndoObject(UndoObject.Type.remove, arr));
+                                                       }
                                                        
sendWbAll(Action.clearSlide, obj);
                                                }
                                                        break;
@@ -221,6 +250,25 @@ public class WbPanel extends Panel {
                                                        wb2save = 
obj.getLong("wbId");
                                                        fileName.open(target);
                                                        break;
+                                               case undo:
+                                               {
+                                                       Long wbId = 
obj.getLong("wbId");
+                                                       UndoObject uo = 
getUndo(wbId);
+                                                       if (uo != null) {
+                                                               switch 
(uo.getType()) {
+                                                                       case 
add:
+                                                                               
sendWbAll(Action.deleteObj, obj.put("obj", new JSONArray().put(new 
JSONObject(uo.getObject()))));
+                                                                               
break;
+                                                                       case 
remove:
+                                                                               
sendWbAll(Action.createObj, obj.put("obj", new JSONArray(uo.getObject())));
+                                                                               
break;
+                                                                       case 
modify:
+                                                                               
sendWbAll(Action.modifyObj, obj.put("obj", new JSONArray(uo.getObject())));
+                                                                               
break;
+                                                               }
+                                                       }
+                                               }
+                                                       break;
                                                default:
                                                        break;
                                        }
@@ -367,8 +415,9 @@ public class WbPanel extends Panel {
                }
                return _file;
        }
+
        private JSONObject addFileUrl(String ruid, JSONObject _file, FileItem 
fi, Client c) {
-               JSONObject file = new JSONObject(_file, 
JSONObject.getNames(_file)); //FIXME TODO openjson 1.0.2
+               JSONObject file = new JSONObject(_file.toString(new 
NullStringer()));
                final FileSystemResourceReference ref;
                final PageParameters pp = new PageParameters()
                                .add("id", fi.getId()).add("uid", c.getUid())
@@ -397,7 +446,24 @@ public class WbPanel extends Panel {
                return file;
        }
 
+       private static JSONArray getArray(JSONObject wb, Function<JSONObject, 
JSONObject> postprocess) {
+               JSONObject items = wb.getJSONObject("roomItems");
+               JSONArray arr = new JSONArray();
+               for (String uid : items.keySet()) {
+                       JSONObject o = items.getJSONObject(uid);
+                       if (postprocess != null) {
+                               o = postprocess.apply(o);
+                       }
+                       arr.put(o);
+               }
+               return arr;
+       }
+
        private void clearAll(Whiteboard wb) {
+               JSONArray arr = getArray(wb.toJson(), null);
+               if (arr.length() != 0) {
+                       addUndo(wb.getId(), new 
UndoObject(UndoObject.Type.remove, arr));
+               }
                wb.clear();
                sendWbAll(Action.clearAll, new JSONObject().put("wbId", 
wb.getId()));
        }
@@ -416,12 +482,7 @@ public class WbPanel extends Panel {
                                        File f = fi.getFile();
                                        if (f.exists() && f.isFile()) {
                                                try (BufferedReader br = 
Files.newBufferedReader(f.toPath())) {
-                                                       JSONObject items = new 
JSONObject(new JSONTokener(br)).getJSONObject("roomItems");
-                                                       JSONArray arr = new 
JSONArray();
-                                                       for (String uid : 
items.keySet()) {
-                                                               JSONObject o = 
items.getJSONObject(uid);
-                                                               
arr.put(addFileUrl(wbs.getUid(), o));
-                                                       }
+                                                       JSONArray arr = 
getArray(new JSONObject(new JSONTokener(br)), (o) -> addFileUrl(wbs.getUid(), 
o));
                                                        sendWbAll(Action.load, 
getObjWbJson(wb.getId(), arr));
                                                } catch (Exception e) {
                                                        log.error("Unexpected 
error while loading WB", e);
@@ -466,4 +527,34 @@ public class WbPanel extends Panel {
                        }
                }
        }
+
+       private void addUndo(Long wbId, UndoObject u) {
+               if (wbId == null) {
+                       return;
+               }
+               if (!undoList.containsKey(wbId)) {
+                       undoList.put(wbId, new LimitedLinkedList<>());
+               }
+               undoList.get(wbId).push(u);
+       }
+
+       private UndoObject getUndo(Long wbId) {
+               if (wbId == null || !undoList.containsKey(wbId)) {
+                       return null;
+               }
+               Deque<UndoObject> deq = undoList.get(wbId);
+               return deq.isEmpty() ? null : deq.pop();
+       }
+
+       private static class LimitedLinkedList<T> extends LinkedList<T> {
+               private static final long serialVersionUID = 1L;
+
+               @Override
+               public void push(T e) {
+                       super.push(e);
+                       while (size() > UNDO_SIZE) {
+                               removeLast();
+                       }
+               }
+       }
 }

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/dd043e06/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js
----------------------------------------------------------------------
diff --git 
a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js 
b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js
index 6c8a7be..bf0074d 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/wb.js
@@ -513,7 +513,7 @@ var Wb = function() {
        const ACTIVE = 'active';
        const BUMPER = 100;
        var wb = {id: -1}, a, t, s, canvases = [], mode, slide = 0, width = 0, 
height = 0
-                       , minWidth = 0, minHeight = 0, role = null;
+                       , minWidth = 0, minHeight = 0, role = null, extraProps 
= ['uid', 'fileId', 'fileType', 'count', 'slide'];
 
        function getBtn(m) {
                return !!t ? t.find(".om-icon." + (m || mode)) : null;
@@ -625,6 +625,9 @@ var Wb = function() {
                                t.find('.om-icon.save').click(function() {
                                        wbAction('save', JSON.stringify({wbId: 
wb.id}));
                                });
+                               t.find('.om-icon.undo').click(function() {
+                                       wbAction('undo', JSON.stringify({wbId: 
wb.id}));
+                               });
                                s.find('.wb-prop-b, .wb-prop-i')
                                        .button()
                                        .click(function() {
@@ -721,14 +724,16 @@ var Wb = function() {
        function _removeHandler(o) {
                var __o = _findObject(o);
                if (!!__o) {
-                       canvases[o.slide].remove(__o);
+                       var cnvs = canvases[o.slide];
+                       if (!!cnvs) {
+                               cnvs.discardActiveGroup();
+                               cnvs.remove(__o);
+                       }
                }
        }
        function _modifyHandler(_o) {
                _removeHandler(_o);
-               var canvas = canvases[_o.slide];
-               _o.selectable = canvas.selection;
-               canvas.add(_o);
+               _createHandler(_o);
        }
        function _createHandler(_o) {
                switch (_o.fileType) {
@@ -803,7 +808,7 @@ var Wb = function() {
        };
 
        function toOmJson(o) {
-               return o.toJSON(['uid', 'fileId', 'fileType', 'count', 
'slide']);
+               return o.toJSON(extraProps);
        }
        //events
        function wbObjCreatedHandler(o) {
@@ -843,9 +848,22 @@ var Wb = function() {
                if (role === NONE && o.type != 'pointer') return;
 
                o.includeDefaultValues = false;
+               var items = [];
+               if ("group" === o.type) {
+                       o.clone(function(_o) {
+                               // ungrouping
+                               _o.includeDefaultValues = false;
+                               var _items = _o.destroy().getObjects();
+                               for (var i = 0; i < _items.length; ++i) {
+                                       items.push(toOmJson(_items[i]));
+                               }
+                       }, extraProps);
+               } else {
+                       items.push(toOmJson(o));
+               }
                wbAction('modifyObj', JSON.stringify({
                        wbId: wb.id
-                       , obj: toOmJson(o)
+                       , obj: items
                }));
        };
        function objSelectedHandler(e) {
@@ -898,19 +916,21 @@ var Wb = function() {
                console.log('Text Changed', obj);
        };*/
        function setHandlers(canvas) {
+               // off everything first to prevent duplicates
+               canvas.off({
+                       'wb:object:created': wbObjCreatedHandler
+                       , 'object:modified': objModifiedHandler
+                       , 'object:added': objAddedHandler
+                       , 'object:selected': objSelectedHandler
+                       , 'path:created': pathCreatedHandler
+                       //, 'text:editing:exited': textEditedHandler
+                       //, 'text:changed': textChangedHandler
+               });
                canvas.on({
                        'wb:object:created': wbObjCreatedHandler
                        , 'object:modified': objModifiedHandler
                });
-               if (role === NONE) {
-                       canvas.off({
-                               'object:added': objAddedHandler
-                               , 'object:selected': objSelectedHandler
-                               , 'path:created': pathCreatedHandler
-                               //, 'text:editing:exited': textEditedHandler
-                               //, 'text:changed': textChangedHandler
-                       });
-               } else {
+               if (role !== NONE) {
                        canvas.on({
                                'object:added': objAddedHandler
                                , 'object:selected': objSelectedHandler
@@ -1002,26 +1022,38 @@ var Wb = function() {
                }
        };
        wb.createObj = function(o) {
-               switch(o.type) {
-                       case 'pointer':
+               var arr = [];
+               if (!Array.isArray(o)) {
+                       if ('pointer' === o.type) {
                                APointer().create(canvases[o.slide], o);
-                               break;
-                       default:
-                               var __o = _findObject(o);
-                               if (!__o) {
-                                       _createObject([o], _createHandler);
-                               }
-                               /*
-                                * https://jsfiddle.net/l2aelba/kro7h6rv/2/
-                               if ('Video' === o.fileType || 'Recording' === 
o.fileType) {
-                                       fabric.util.requestAnimFrame(function 
render() {
-                                               canvas.renderAll();
-                                               
fabric.util.requestAnimFrame(render);
-                                       });
-                               }
-                               */
-                               break;
+                               return;
+                       }
+                       switch(o.type) {
+                               case 'pointer':
+                                       APointer().create(canvases[o.slide], o);
+                                       break;
+                               default:
+                                       var __o = _findObject(o);
+                                       if (!__o) {
+                                               arr.push(o);
+                                       }
+                                       break;
+                       }
+               } else {
+                       arr = o;
+               }
+               if (arr.length > 0) {
+                       _createObject(arr, _createHandler);
+               }
+               /* FIXME TODO animation
+                * https://jsfiddle.net/l2aelba/kro7h6rv/2/
+               if ('Video' === o.fileType || 'Recording' === o.fileType) {
+                       fabric.util.requestAnimFrame(function render() {
+                               canvas.renderAll();
+                               fabric.util.requestAnimFrame(render);
+                       });
                }
+               */
        };
        wb.modifyObj = function(o) { //TODO need to be unified
                switch(o.type) {
@@ -1029,16 +1061,7 @@ var Wb = function() {
                                
_modifyHandler(APointer().create(canvases[o.slide], o))
                                break;
                        default:
-                               var arr = [o];
-                               if (!!o.objects) {
-                                       arr = o.objects;
-                                       for (var i = 0; i < arr.length; ++i) {
-                                               var _o = arr[i];
-                                               _o.left += o.left;
-                                               _o.top += o.top;
-                                       }
-                               }
-                               _createObject(o.objects || [o], _modifyHandler);
+                               _createObject(o, _modifyHandler);
                                break;
                }
        };
@@ -1104,8 +1127,8 @@ var WbArea = (function() {
                                        var canvas = wb.getCanvas();
                                        if (!!canvas) {
                                                var arr = [];
-                                               if (canvas.getActiveGroup()) {
-                                                       
canvas.getActiveGroup().forEachObject(function(o){
+                                               if (!!canvas.getActiveGroup()) {
+                                                       
canvas.getActiveGroup().forEachObject(function(o) {
                                                                arr.push({
                                                                        uid: 
o.uid
                                                                        , 
slide: o.slide
@@ -1309,7 +1332,7 @@ $(function() {
                                }
                        }
                } catch (err) {
-                       //console.log(err);
+                       console.log(err);
                        //no-op
                }
        });

Reply via email to