cc0d361f79c7f4cc801bfade5b757d36f369da84
[redakcja.git] / project / static / js / views / split.js
1 /*globals View*/
2
3 // Split view inspired by jQuery Splitter Plugin http://methvin.com/splitter/
4 var SplitView = View.extend({
5   splitbarClass: 'splitview-splitbar',
6   activeClass: 'splitview-active',
7   overlayClass: 'splitview-overlay',
8   element: null,
9   model: null,
10   zombie: null,
11   leftViewOffset: 0,
12   
13   // Cache
14   _splitbarWidth: 0,
15   
16   init: function(element, model) {
17     this.element = $(element).css('position', 'relative');
18     this.model = model;
19     this.views = $(">*", this.element[0]).css({
20         position: 'absolute',                     // positioned inside splitter container
21         'z-index': 1,                                           // splitbar is positioned above
22         '-moz-outline-style': 'none',   // don't show dotted outline
23       overflow: 'auto'
24     });
25     
26     this.leftView = $(this.views[0]);
27     this.rightView = $(this.views[1]);
28     this.splitbar = $(this.views[2] || '<div></div>')
29       .insertAfter(this.leftView)
30       .css({
31         position: 'absolute',
32         'user-select': 'none',
33         '-webkit-user-select': 'none',
34         '-khtml-user-select': 'none',
35         '-moz-user-select': 'none',
36         'z-index': 100
37       })
38       .attr('unselectable', 'on')
39       .addClass(this.splitbarClass)
40       .bind('mousedown.splitview', this.beginResize.bind(this));
41     
42     this._splitbarWidth = this.splitbar.outerWidth();
43     
44     // Solomon's algorithm ;-)
45     this.resplit(this.element.width() / 2);
46   },
47     
48   beginResize: function(event) {
49     this.zombie = this.zombie || this.splitbar.clone(false).insertAfter(this.leftView);
50     this.overlay = this.overlay || $('<div></div>').addClass(this.overlayClass).css({
51         position: 'absolute',
52         width: this.element.width(),
53         height: this.element.height(),
54         top: this.element.position().top,
55         left: this.element.position().left
56       }).appendTo(this.element);
57     this.views.css("-webkit-user-select", "none"); // Safari selects A/B text on a move
58     this.splitbar.addClass(this.activeClass);
59     this.leftViewOffset = this.leftView[0].offsetWidth - event.pageX;
60     
61     $(document)
62       .bind('mousemove.splitview', this.resizeChanged.bind(this))
63       .bind('mouseup.splitview', this.endResize.bind(this));
64   },
65   
66   resizeChanged: function(event) {
67     var newPosition = event.pageX + this.leftViewOffset;
68     newPosition = Math.max(0, Math.min(newPosition, this.element.width() - this._splitbarWidth));
69     this.splitbar.css('left', newPosition);
70   },
71
72   endResize: function(event) {
73     var newPosition = event.pageX + this.leftViewOffset;
74     this.zombie.remove();
75     this.zombie = null;
76     this.overlay.remove();
77     this.overlay = null;
78     this.resplit(newPosition);
79
80     $(document)
81       .unbind('mousemove.splitview')
82       .unbind('mouseup.splitview');
83   },
84
85   resplit: function(newPosition) {
86     newPosition = Math.max(0, Math.min(newPosition, this.element.width() - this._splitbarWidth));
87     this.splitbar.css('left', newPosition);
88     this.leftView.css({
89       left: 0,
90       width: newPosition
91     });
92     this.rightView.css({
93       left: newPosition + this._splitbarWidth,
94       width: this.element.width() - newPosition - this._splitbarWidth
95     });
96     if (!$.browser.msie) {
97                   this.views.trigger("resize");
98                 }
99   },
100   
101   dispose: function() {
102     this.splitter.unbind('mousedown.splitview');
103     this._super();
104   }
105 });
106