Mercurial > hg > rc2
comparison skins/classic/splitter.js @ 0:4681f974d28b
vanilla 1.3.3 distro, I hope
author | Charlie Root |
---|---|
date | Thu, 04 Jan 2018 15:52:31 -0500 |
parents | |
children | bf99236cc5cd |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4681f974d28b |
---|---|
1 /** | |
2 * Roundcube splitter GUI class | |
3 * | |
4 * @licstart The following is the entire license notice for the | |
5 * JavaScript code in this file. | |
6 * | |
7 * Copyright (c) 2006-2014, The Roundcube Dev Team | |
8 * | |
9 * The JavaScript code in this page is free software: you can redistribute it | |
10 * and/or modify it under the terms of the GNU General Public License | |
11 * as published by the Free Software Foundation, either version 3 of | |
12 * the License, or (at your option) any later version. | |
13 * | |
14 * @licend The above is the entire license notice | |
15 * for the JavaScript code in this file. | |
16 * | |
17 * @constructor | |
18 */ | |
19 function rcube_splitter(attrib) | |
20 { | |
21 this.p1id = attrib.p1; | |
22 this.p2id = attrib.p2; | |
23 this.id = attrib.id ? attrib.id : this.p1id + '_' + this.p2id + '_splitter'; | |
24 this.orientation = attrib.orientation; | |
25 this.horizontal = (this.orientation == 'horizontal' || this.orientation == 'h'); | |
26 this.pos = attrib.start ? attrib.start * 1 : 0; | |
27 this.relative = attrib.relative ? true : false; | |
28 this.drag_active = false; | |
29 this.callback = attrib.callback; | |
30 | |
31 var me = this; | |
32 | |
33 this.init = function() | |
34 { | |
35 this.p1 = document.getElementById(this.p1id); | |
36 this.p2 = document.getElementById(this.p2id); | |
37 | |
38 // create and position the handle for this splitter | |
39 this.p1pos = this.relative ? $(this.p1).position() : $(this.p1).offset(); | |
40 this.p2pos = this.relative ? $(this.p2).position() : $(this.p2).offset(); | |
41 | |
42 if (this.horizontal) { | |
43 var top = this.p1pos.top + this.p1.offsetHeight; | |
44 this.layer = new rcube_layer(this.id, {x: 0, y: top, height: 10, | |
45 width: '100%', vis: 1, parent: this.p1.parentNode}); | |
46 } | |
47 else { | |
48 var left = this.p1pos.left + this.p1.offsetWidth; | |
49 this.layer = new rcube_layer(this.id, {x: left, y: 0, width: 10, | |
50 height: '100%', vis: 1, parent: this.p1.parentNode}); | |
51 } | |
52 | |
53 this.elm = this.layer.elm; | |
54 this.elm.className = 'splitter '+(this.horizontal ? 'splitter-h' : 'splitter-v'); | |
55 this.elm.unselectable = 'on'; | |
56 | |
57 // add the mouse event listeners | |
58 $(this.elm).mousedown(onDragStart); | |
59 if (bw.ie) | |
60 $(window).resize(onResize); | |
61 | |
62 // read saved position from cookie | |
63 var cookie = rcmail.get_cookie(this.id); | |
64 if (cookie && !isNaN(cookie)) { | |
65 this.pos = parseFloat(cookie); | |
66 this.resize(); | |
67 } | |
68 else if (this.pos) { | |
69 this.resize(); | |
70 this.set_cookie(); | |
71 } | |
72 }; | |
73 | |
74 /** | |
75 * Set size and position of all DOM objects | |
76 * according to the saved splitter position | |
77 */ | |
78 this.resize = function() | |
79 { | |
80 if (this.horizontal) { | |
81 var lh = this.layer.height; | |
82 this.p1.style.height = Math.floor(this.pos - this.p1pos.top - lh / 2) + 'px'; | |
83 this.p2.style.top = Math.ceil(this.pos + lh / 2) + 'px'; | |
84 this.layer.move(this.layer.x, Math.round(this.pos - lh / 2 + 1)); | |
85 if (bw.ie) { | |
86 var new_height = parseInt(this.p2.parentNode.offsetHeight, 10) - parseInt(this.p2.style.top, 10) - (bw.ie8 ? 2 : 0); | |
87 this.p2.style.height = (new_height > 0 ? new_height : 0) + 'px'; | |
88 } | |
89 } | |
90 else { | |
91 this.p1.style.width = Math.floor(this.pos - this.p1pos.left - this.layer.width / 2) + 'px'; | |
92 this.p2.style.left = Math.ceil(this.pos + this.layer.width / 2) + 'px'; | |
93 this.layer.move(Math.round(this.pos - this.layer.width / 2 + 1), this.layer.y); | |
94 if (bw.ie) { | |
95 var new_width = parseInt(this.p2.parentNode.offsetWidth, 10) - parseInt(this.p2.style.left, 10) ; | |
96 this.p2.style.width = (new_width > 0 ? new_width : 0) + 'px'; | |
97 } | |
98 } | |
99 $(this.p2).resize(); | |
100 $(this.p1).resize(); | |
101 }; | |
102 | |
103 /** | |
104 * Handler for mousedown events | |
105 */ | |
106 function onDragStart(e) | |
107 { | |
108 me.drag_active = true; | |
109 | |
110 // disable text selection while dragging the splitter | |
111 if (bw.konq || bw.chrome || bw.safari) | |
112 document.body.style.webkitUserSelect = 'none'; | |
113 | |
114 me.p1pos = me.relative ? $(me.p1).position() : $(me.p1).offset(); | |
115 me.p2pos = me.relative ? $(me.p2).position() : $(me.p2).offset(); | |
116 | |
117 // start listening to mousemove events | |
118 $(document).bind('mousemove.'+me.id, onDrag).bind('mouseup.'+me.id, onDragStop); | |
119 | |
120 // enable dragging above iframes | |
121 $('iframe').each(function() { | |
122 $('<div class="iframe-splitter-fix"></div>') | |
123 .css({background: '#fff', | |
124 width: this.offsetWidth+'px', height: this.offsetHeight+'px', | |
125 position: 'absolute', opacity: '0.001', zIndex: 1000 | |
126 }) | |
127 .css($(this).offset()) | |
128 .appendTo('body'); | |
129 }); | |
130 }; | |
131 | |
132 /** | |
133 * Handler for mousemove events | |
134 */ | |
135 function onDrag(e) | |
136 { | |
137 if (!me.drag_active) | |
138 return false; | |
139 | |
140 // with timing events dragging action is more responsive | |
141 window.clearTimeout(me.ts); | |
142 me.ts = window.setTimeout(function() { onDragAction(e); }, 1); | |
143 | |
144 return false; | |
145 }; | |
146 | |
147 function onDragAction(e) | |
148 { | |
149 var pos = rcube_event.get_mouse_pos(e); | |
150 | |
151 if (me.relative) { | |
152 var parent = $(me.p1.parentNode).offset(); | |
153 pos.x -= parent.left; | |
154 pos.y -= parent.top; | |
155 } | |
156 | |
157 if (me.horizontal) { | |
158 if (((pos.y - me.layer.height * 1.5) > me.p1pos.top) && ((pos.y + me.layer.height * 1.5) < (me.p2pos.top + me.p2.offsetHeight))) { | |
159 me.pos = pos.y; | |
160 me.resize(); | |
161 } | |
162 } | |
163 else if (((pos.x - me.layer.width * 1.5) > me.p1pos.left) && ((pos.x + me.layer.width * 1.5) < (me.p2pos.left + me.p2.offsetWidth))) { | |
164 me.pos = pos.x; | |
165 me.resize(); | |
166 } | |
167 | |
168 me.p1pos = me.relative ? $(me.p1).position() : $(me.p1).offset(); | |
169 me.p2pos = me.relative ? $(me.p2).position() : $(me.p2).offset(); | |
170 }; | |
171 | |
172 /** | |
173 * Handler for mouseup events | |
174 */ | |
175 function onDragStop(e) | |
176 { | |
177 me.drag_active = false; | |
178 | |
179 // resume the ability to highlight text | |
180 if (bw.konq || bw.chrome || bw.safari) | |
181 document.body.style.webkitUserSelect = 'auto'; | |
182 | |
183 // cancel the listening for drag events | |
184 $(document).unbind('.' + me.id); | |
185 | |
186 // remove temp divs | |
187 $('div.iframe-splitter-fix').remove(); | |
188 | |
189 me.set_cookie(); | |
190 | |
191 if (typeof me.callback == 'function') | |
192 me.callback(me); | |
193 | |
194 return bw.safari ? true : rcube_event.cancel(e); | |
195 }; | |
196 | |
197 /** | |
198 * Handler for window resize events | |
199 */ | |
200 function onResize(e) | |
201 { | |
202 if (me.horizontal) { | |
203 var new_height = parseInt(me.p2.parentNode.offsetHeight, 10) - parseInt(me.p2.style.top, 10) - (bw.ie8 ? 2 : 0); | |
204 me.p2.style.height = (new_height > 0 ? new_height : 0) +'px'; | |
205 } | |
206 else { | |
207 var new_width = parseInt(me.p2.parentNode.offsetWidth, 10) - parseInt(me.p2.style.left, 10); | |
208 me.p2.style.width = (new_width > 0 ? new_width : 0) + 'px'; | |
209 } | |
210 }; | |
211 | |
212 /** | |
213 * Saves splitter position in cookie | |
214 */ | |
215 this.set_cookie = function() | |
216 { | |
217 var exp = new Date(); | |
218 exp.setYear(exp.getFullYear() + 1); | |
219 rcmail.set_cookie(this.id, this.pos, exp); | |
220 }; | |
221 | |
222 } // end class rcube_splitter |