If browser returns selection outside of text element return cursor position as undefined
[fnpeditor.git] / modules / documentHistory / documentHistory.js
1 define([
2 'libs/jquery-1.9.1.min',
3 'libs/underscore-min',
4 './restoreDialog',
5 'libs/text!./templates/main.html',
6 'libs/text!./templates/item.html'
7 ], function($, _, restoreDialog, mainTemplateSrc, itemTemplateSrc) {
8
9 'use strict';
10     
11 return function(sandbox) {
12     
13     var dom = $(_.template(mainTemplateSrc)());
14     var domNodes = {
15         itemList: dom.find('.rng-module-documentHistory-itemsList'),
16     };
17     var itemViews = [];
18     
19     
20     dom.find('.btn.compare').click(function(e) {
21         var selected = historyItems.getSelected();
22         sandbox.publish('compare', selected[0], selected[1]);
23     });
24     
25     dom.find('.btn.restore').click(function(e) {
26         var dialog = restoreDialog.create();
27         dialog.on('restore', function(event) {
28             sandbox.publish('restoreVersion', {version: historyItems.getSelected()[0], description: event.data.description});
29             event.success();
30         });
31         dialog.show();
32     });
33     
34     dom.find('.btn.display').click(function(e) {
35         sandbox.publish('displayVersion', {version: historyItems.getSelected()[0]});
36     });
37         
38     var addHistoryItem = function(item, options) {
39         historyItems.add(item);
40         var view = new ItemView(item);
41         itemViews.push(view);
42         domNodes.itemList.prepend(view.dom);
43         if(options.animate) {
44             view.dom.hide().slideDown();
45         }
46     };
47     
48     var toggleItemViews = function(toggle) {
49         itemViews.forEach(function(view) {
50             if(!historyItems.isSelected(view.item))
51                 view.toggle(toggle);
52         });
53     };
54     
55     var toggleButton = function(btn, toggle) {
56         dom.find('button.'+btn).toggleClass('disabled', !toggle);
57     };
58     
59     var historyItems = {
60         _itemsById: {},
61         _selected: [],
62         select: function(item) {
63             if(this._selected.length < 2) {
64                 this._selected.push(item.version);
65                 this._updateUI();
66                 return true;
67             }
68             return false;
69         },
70         unselect: function(item) {
71             this._selected = _.without(this._selected, item.version);
72             this._updateUI();
73         },
74         add: function(item) {
75             this._itemsById[item.version] = item;
76         },
77         isSelected: function(item) {
78             return _.contains(this._selected, item.version);
79         },
80         getSelected: function() {
81             return this._selected;
82         },
83         _updateUI: function() {
84             var len = this._selected.length;
85             if(len === 0) {
86                 toggleButton('compare', false);
87                 toggleButton('display', false);
88                 toggleButton('restore', false);
89             }
90             if(len === 1) {
91                 toggleButton('compare', false);
92                 toggleButton('display', true);
93                 toggleButton('restore', true);
94             }
95             if(len === 2) {
96                 toggleItemViews(false);
97                 toggleButton('compare', true);
98                 toggleButton('display', false);
99                 toggleButton('restore', false);
100             } else {
101                 toggleItemViews(true);
102             }
103         }
104     };
105     historyItems._updateUI();
106     
107     var ItemView = function(item) {
108         this.item = item;
109         this.dom = $(this.template(item));
110         this.dom.on('click', _.bind(this.onItemClicked, this));
111     };
112     ItemView.prototype.template = _.template(itemTemplateSrc);
113     ItemView.prototype.onItemClicked = function() {
114         if(historyItems.isSelected(this.item)) {
115             historyItems.unselect(this.item);
116             this.dimItem();
117         } else if(historyItems.select(this.item)) {
118             this.highlightItem();
119         }            
120     };
121     ItemView.prototype.highlightItem = function() {
122         this.dom.addClass('highlighted');
123     };
124     ItemView.prototype.dimItem = function() {
125         this.dom.removeClass('highlighted');
126     };
127     ItemView.prototype.toggle = function(toggle) {
128         this.dom.toggleClass('disabled', !toggle);
129     };
130
131     
132     
133     return {
134         start: function() { sandbox.publish('ready'); },
135         addHistory: function(history, options) {
136             history.forEach(function(historyItem) {
137                 addHistoryItem(historyItem, options || {});
138             });
139         },
140         getView: function() {
141             return dom;
142         }
143     };
144 };
145
146 });