1 /**
  2  * Copyright (C) 2013 KO GmbH <copyright@kogmbh.com>
  3  *
  4  * @licstart
  5  * This file is part of WebODF.
  6  *
  7  * WebODF is free software: you can redistribute it and/or modify it
  8  * under the terms of the GNU Affero General Public License (GNU AGPL)
  9  * as published by the Free Software Foundation, either version 3 of
 10  * the License, or (at your option) any later version.
 11  *
 12  * WebODF is distributed in the hope that it will be useful, but
 13  * WITHOUT ANY WARRANTY; without even the implied warranty of
 14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 15  * GNU Affero General Public License for more details.
 16  *
 17  * You should have received a copy of the GNU Affero General Public License
 18  * along with WebODF.  If not, see <http://www.gnu.org/licenses/>.
 19  * @licend
 20  *
 21  * @source: http://www.webodf.org/
 22  * @source: https://github.com/kogmbh/WebODF/
 23  */
 24 
 25 /*global runtime, core, gui, ops*/
 26 
 27 /**
 28  * The Selection View Manager is responsible for managing SelectionView objects
 29  * and attaching/detaching them to cursors.
 30  * @constructor
 31  * @implements {core.Destroyable}
 32  * @param {!function(new:gui.SelectionView, !(ops.OdtCursor|gui.ShadowCursor))} SelectionView
 33  */
 34 gui.SelectionViewManager = function SelectionViewManager(SelectionView) {
 35     "use strict";
 36     var /**@type{!Object.<string,gui.SelectionView>}*/
 37         selectionViews = {};
 38 
 39     /**
 40      * @param {!string} memberId
 41      * @return {?gui.SelectionView}
 42      */
 43     function getSelectionView(memberId) {
 44         return selectionViews.hasOwnProperty(memberId) ? selectionViews[memberId] : null;
 45     }
 46     this.getSelectionView = getSelectionView;
 47 
 48     /**
 49      * @return {!Array.<!gui.SelectionView>}
 50      */
 51     function getSelectionViews() {
 52         return Object.keys(selectionViews).map(function (memberid) { return selectionViews[memberid]; });
 53     }
 54     this.getSelectionViews = getSelectionViews;
 55 
 56     /**
 57      * @param {!string} memberId
 58      * @return {undefined}
 59      */
 60     function removeSelectionView(memberId) {
 61         if (selectionViews.hasOwnProperty(memberId)) {
 62             /*jslint emptyblock: true*/
 63             selectionViews[memberId].destroy(function () { });
 64             /*jslint emptyblock: false*/
 65             delete selectionViews[memberId];
 66         }
 67     }
 68     this.removeSelectionView = removeSelectionView;
 69 
 70     /**
 71      * @param {!string} memberId
 72      * @return {undefined}
 73      */
 74     function hideSelectionView(memberId) {
 75         if (selectionViews.hasOwnProperty(memberId)) {
 76             selectionViews[memberId].hide();
 77         }
 78     }
 79     this.hideSelectionView = hideSelectionView;
 80 
 81     /**
 82      * @param {!string} memberId
 83      * @return {undefined}
 84      */
 85     function showSelectionView(memberId) {
 86         if (selectionViews.hasOwnProperty(memberId)) {
 87             selectionViews[memberId].show();
 88         }
 89     }
 90     this.showSelectionView = showSelectionView;
 91 
 92     /**
 93      * Rerenders the selection views that are already visible
 94      * @return {undefined}
 95      */
 96     this.rerenderSelectionViews = function () {
 97         Object.keys(selectionViews).forEach(function (memberId) {
 98             selectionViews[memberId].rerender();
 99         });
100     };
101 
102     /**
103      * @param {!(ops.OdtCursor|gui.ShadowCursor)} cursor
104      * @param {!boolean} virtualSelectionsInitiallyVisible
105      * @return {!gui.SelectionView}
106      */
107     this.registerCursor = function (cursor, virtualSelectionsInitiallyVisible) {
108         var memberId = cursor.getMemberId(),
109             selectionView = new SelectionView(cursor);
110 
111         if (virtualSelectionsInitiallyVisible) {
112             selectionView.show();
113         } else {
114             selectionView.hide();
115         }
116 
117         selectionViews[memberId] = selectionView;
118         return selectionView;
119     };
120 
121     /**
122      * @param {function(!Error=)} callback
123      */
124     this.destroy = function (callback) {
125         var selectionViewArray = getSelectionViews();
126 
127         /**
128          * @param {!number} i
129          * @param {!Error=} err
130          * @return {undefined}
131          */
132         function destroySelectionView(i, err) {
133             if (err) {
134                 callback(err);
135             } else {
136                 if (i < selectionViewArray.length) {
137                     selectionViewArray[i].destroy(function (err) {
138                         destroySelectionView(i + 1, err);
139                     });
140                 } else {
141                     callback();
142                 }
143             }
144         }
145         destroySelectionView(0, undefined);
146     };
147 };
148