adding all weblabels from weblabels.fsf.org
[weblabels.fsf.org.git] / etherpad.fsf.org / 20130506 / files / draggable.js
1 /**
2 * This code is mostly from the old Etherpad. Please help us to comment this code.
3 * This helps other people to understand this code better and helps them to improve it.
4 * TL;DR COMMENTS ON THIS FILE ARE HIGHLY APPRECIATED
5 */
6
7 /**
8 * Copyright 2009 Google Inc.
9 *
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS-IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 */
22
23 function makeDraggable(jqueryNodes, eventHandler)
24 {
25 jqueryNodes.each(function()
26 {
27 var node = $(this);
28 var state = {};
29 var inDrag = false;
30
31 function dragStart(evt)
32 {
33 if (inDrag)
34 {
35 return;
36 }
37 inDrag = true;
38 if (eventHandler('dragstart', evt, state) !== false)
39 {
40 $(document).bind('mousemove', dragUpdate);
41 $(document).bind('mouseup', dragEnd);
42 }
43 evt.preventDefault();
44 return false;
45 }
46
47 function dragUpdate(evt)
48 {
49 if (!inDrag)
50 {
51 return;
52 }
53 eventHandler('dragupdate', evt, state);
54 evt.preventDefault();
55 return false;
56 }
57
58 function dragEnd(evt)
59 {
60 if (!inDrag)
61 {
62 return;
63 }
64 inDrag = false;
65 try
66 {
67 eventHandler('dragend', evt, state);
68 }
69 finally
70 {
71 $(document).unbind('mousemove', dragUpdate);
72 $(document).unbind('mouseup', dragEnd);
73 evt.preventDefault();
74 }
75 return false;
76 }
77 node.bind('mousedown', dragStart);
78 });
79 }
80
81 function makeResizableVPane(top, sep, bottom, minTop, minBottom, callback)
82 {
83 if (minTop === undefined) minTop = 0;
84 if (minBottom === undefined) minBottom = 0;
85
86 makeDraggable($(sep), function(eType, evt, state)
87 {
88 if (eType == 'dragstart')
89 {
90 state.startY = evt.pageY;
91 state.topHeight = $(top).height();
92 state.bottomHeight = $(bottom).height();
93 state.minTop = minTop;
94 state.maxTop = (state.topHeight + state.bottomHeight) - minBottom;
95 }
96 else if (eType == 'dragupdate')
97 {
98 var change = evt.pageY - state.startY;
99
100 var topHeight = state.topHeight + change;
101 if (topHeight < state.minTop)
102 {
103 topHeight = state.minTop;
104 }
105 if (topHeight > state.maxTop)
106 {
107 topHeight = state.maxTop;
108 }
109 change = topHeight - state.topHeight;
110
111 var bottomHeight = state.bottomHeight - change;
112 var sepHeight = $(sep).height();
113
114 var totalHeight = topHeight + sepHeight + bottomHeight;
115 topHeight = 100.0 * topHeight / totalHeight;
116 sepHeight = 100.0 * sepHeight / totalHeight;
117 bottomHeight = 100.0 * bottomHeight / totalHeight;
118
119 $(top).css('bottom', 'auto');
120 $(top).css('height', topHeight + "%");
121 $(sep).css('top', topHeight + "%");
122 $(bottom).css('top', (topHeight + sepHeight) + '%');
123 $(bottom).css('height', 'auto');
124 if (callback) callback();
125 }
126 });
127 }
128
129 function makeResizableHPane(left, sep, right, minLeft, minRight, sepWidth, sepOffset, callback)
130 {
131 if (minLeft === undefined) minLeft = 0;
132 if (minRight === undefined) minRight = 0;
133
134 makeDraggable($(sep), function(eType, evt, state)
135 {
136 if (eType == 'dragstart')
137 {
138 state.startX = evt.pageX;
139 state.leftWidth = $(left).width();
140 state.rightWidth = $(right).width();
141 state.minLeft = minLeft;
142 state.maxLeft = (state.leftWidth + state.rightWidth) - minRight;
143 }
144 else if (eType == 'dragend' || eType == 'dragupdate')
145 {
146 var change = evt.pageX - state.startX;
147
148 var leftWidth = state.leftWidth + change;
149 if (leftWidth < state.minLeft)
150 {
151 leftWidth = state.minLeft;
152 }
153 if (leftWidth > state.maxLeft)
154 {
155 leftWidth = state.maxLeft;
156 }
157 change = leftWidth - state.leftWidth;
158
159 var rightWidth = state.rightWidth - change;
160 newSepWidth = sepWidth;
161 if (newSepWidth == undefined) newSepWidth = $(sep).width();
162 newSepOffset = sepOffset;
163 if (newSepOffset == undefined) newSepOffset = 0;
164
165 if (change == 0)
166 {
167 if (rightWidth != minRight || state.lastRightWidth == undefined)
168 {
169 state.lastRightWidth = rightWidth;
170 rightWidth = minRight;
171 }
172 else
173 {
174 rightWidth = state.lastRightWidth;
175 state.lastRightWidth = minRight;
176 }
177 change = state.rightWidth - rightWidth;
178 leftWidth = change + state.leftWidth;
179 }
180
181 var totalWidth = leftWidth + newSepWidth + rightWidth;
182 leftWidth = 100.0 * leftWidth / totalWidth;
183 newSepWidth = 100.0 * newSepWidth / totalWidth;
184 newSepOffset = 100.0 * newSepOffset / totalWidth;
185 rightWidth = 100.0 * rightWidth / totalWidth;
186
187 $(left).css('right', 'auto');
188 $(left).css('width', leftWidth + "%");
189 $(sep).css('left', (leftWidth + newSepOffset) + "%");
190 $(right).css('left', (leftWidth + newSepWidth) + '%');
191 $(right).css('width', 'auto');
192 if (callback) callback();
193 }
194 });
195 }
196
197 exports.makeDraggable = makeDraggable;