Thanks for throwing this up here Ryan. Here's an updated patch (for svn 410) that also works in IE and Opera in addition to Firefox. (Can someone test Safari?) This one also resizes the splitter bar when the window is resized. The setting still isn't saved in user_prefs but I'm sure Ryan will have that working soon... peace, David Glick
I really am batting 1000 today. Here's the diff. Going to bed.
--- program/include/main.inc (revision 410) +++ program/include/main.inc (working copy) @@ -1277,6 +1277,7 @@ // GENERAL 'loginform' => 'rcmail_login_form', 'username' => 'rcmail_current_username',
'splitter' => 'rcube_splitter',
// MAIL
'mailboxlist' => 'rcmail_mailbox_list',
@@ -1912,7 +1913,19 @@ return $select->show($set); }
+function rcube_splitter($attrib)
{
global $OUTPUT, $JS_OBJECT_NAME;
// register splitter in the system
$OUTPUT->add_script(sprintf("%s.register_splitter('%s', '%s', '%s');",
$JS_OBJECT_NAME,
$attrib['first'],
$attrib['second'],
$attrib['orientation']));
}
/****** debugging functions ********/
--- program/js/common.js (revision 410) +++ program/js/common.js (working copy) @@ -380,6 +380,187 @@ }
+/**
+function rcube_splitter(attrib)
this.layer = new rcube_layer(this.id, {x: this.p1pos.x, y: top,
height: height, zindex: 1, vis: 1});
this.layer = new rcube_layer(this.id, {x: left, y:
this.p1pos.y, width: width, zindex: 1, vis: 1});
this.elm.style.paddingTop = Math.floor(height / 2) + 'px';
this.elm.style.paddingLeft = Math.floor(width / 2) + 'px';
{
this.line.style.borderTopWidth = '1px';
this.line.style.width = '100%';
this.line.style.height = '1px';
}
{
this.line.style.borderLeftWidth = '1px';
this.line.style.width = '1px';
this.line.style.height = '100%';
}
object:this, method:'onMouseOver'});
object:this, method:'onMouseOut'});
object:this, method:'onDrag'});
object:this, method:'onDragStop'});
splitter stops moving when we move over an iframe
{
var iframedoc = null;
if (iframes[n].contentDocument)
iframedoc = iframes[n].contentDocument;
else if (iframes[n].contentWindow)
iframedoc = iframes[n].contentWindow.document;
else if (iframes[n].document)
iframedoc = iframes[n].document;
if (iframedoc)
{
// I don't use the add_listener function for this one because
I need to create closures to fetch
// the position of each iframe when the event is received
var s = this;
var id = iframes[n].id;
this.iframe_events[n] = function(e){ e._rc_pos_offset =
rcube_get_object_pos(document.getElementById(id)); return s.onDrag(e); }
if (iframedoc.addEventListener)
iframedoc.addEventListener('mousemove',
this.iframe_events[n], false);
else if (iframes[n].attachEvent)
iframedoc.attachEvent('onmousemove', this.iframe_events[n]);
else
iframedoc['onmousemove'] = this.iframe_events[n];
rcube_event.add_listener({element:iframedoc, event:'mouseup',
object:this, method:'onDragStop'});
}
}
{
pos.x += e._rc_pos_offset.x;
pos.y += e._rc_pos_offset.y;
}
{
if (((pos.y - this.layer.height * 1.5) > this.p1pos.y) &&
((pos.y + this.layer.height * 1.5) < (this.p2pos.y + this.p2.offsetHeight)))
{
// resize the panels
this.p2.style.top = Math.round(pos.y + this.layer.height / 2
this.p1.style.height = Math.round(pos.y - this.p1pos.y -
this.layer.height / 2 - 1) + 'px';
// move the splitter handle
this.layer.move(this.layer.x, Math.round(pos.y -
this.layer.height / 2 + 1));
}
}
{
if (((pos.x - this.layer.width * 1.5) > this.p1pos.x) &&
((pos.x + this.layer.width * 1.5) < (this.p2pos.x + this.p2.offsetWidth)))
{
this.p1.style.width = Math.round(pos.x - this.p1pos.x -
this.layer.width / 2 - 1) + 'px';
this.p2.style.left = Math.round(pos.x + this.layer.width / 2
this.layer.move(Math.round(pos.x - this.layer.width / 2 + 1),
this.layer.y);
}
}
object:this, method:'onDrag'});
object:this, method:'onDragStop'});
{
var iframedoc;
if (iframes[n].contentDocument)
iframedoc = iframes[n].contentDocument;
else if (iframes[n].contentWindow)
iframedoc = iframes[n].contentWindow.document;
else if (iframes[n].document)
iframedoc = iframes[n].document;
if (iframedoc)
{
if (this.iframe_events[n]) {
if (iframedoc.removeEventListener)
iframedoc.removeEventListener('mousemove',
this.iframe_events[n], false);
else if (iframedoc.detachEvent)
iframedoc.detachEvent('onmousemove', this.iframe_events[n]);
else
iframedoc['onmousemove'] = null;
}
rcube_event.remove_listener({element:iframedoc,
event:'mouseup', object:this, method:'onDragStop'});
}
}
// check if input is a valid email address // By Cal Henderson cal@iamcal.com // http://code.iamcal.com/php/rfc822/ Index: program/js/app.js =================================================================== --- program/js/app.js (revision 410) +++ program/js/app.js (working copy) @@ -24,6 +24,7 @@ this.env = new Object(); this.labels = new Object(); this.buttons = new Object();
@@ -78,6 +79,13 @@ };
p2, orientation: orientation});
@@ -108,6 +116,10 @@
// enable general commands
this.enable_command('logout', 'mail', 'addressbook', 'settings', true);
// initialize splitters
for (var n in this.splitters)
this.splitters[n].init();
switch (this.task) {
--- skins/default/common.css (revision 410) +++ skins/default/common.css (working copy) @@ -213,7 +213,21 @@ border: 1px solid #CCCCCC; }
+.splitter +{
+}
+.splitterLine +{
+}
/***** common table settings ******/
table.records-table thead tr td Index: skins/default/templates/mail.html =================================================================== --- skins/default/templates/mail.html (revision 410) +++ skins/default/templates/mail.html (working copy) @@ -55,6 +55,7 @@
</div>
<roundcube:if condition="config:preview_pane == true" /> +<roundcube:object name="splitter" first="mailcontframe" second="mailpreviewframe" orientation="horizontal" />
<div id="mailpreviewframe"> <roundcube:object name="messagecontentframe" id="messagecontframe" width="100%" height="100%" frameborder="0" src="/watermark.html" /> </div> Index: skins/default/templates/addressbook.html =================================================================== --- skins/default/templates/addressbook.html (revision 410) +++ skins/default/templates/addressbook.html (working copy) @@ -31,6 +31,8 @@ <roundcube:object name="addresslist" id="contacts-table" class="records-table" cellspacing="0" summary="Contacts list" /> </div>
+<roundcube:object name="splitter" first="addresslist" second="contacts-box" orientation="vertical" />
<div id="contacts-box"> <roundcube:object name="addressframe" id="contact-frame" width="100%" height="100%" frameborder="0" src="/watermark.html" /> </div> Index: skins/default/addresses.css =================================================================== --- skins/default/addresses.css (revision 410) +++ skins/default/addresses.css (working copy) @@ -70,10 +70,19 @@ border: 1px solid #999999; overflow: hidden; /* css hack for IE */ - width: expression((parseInt(document.documentElement.clientWidth)-530)+'px'); + width: expression((parseInt(document.documentElement.clientWidth)-80-document.getElementById('addresslist').offsetWidth)+'px'); height: expression((parseInt(document.documentElement.clientHeight)-135)+'px'); }
+#addresslist_contacts-box_splitter +{
+}
body.iframe, #contact-frame { Index: skins/default/mail.css =================================================================== --- skins/default/mail.css (revision 410) +++ skins/default/mail.css (working copy) @@ -131,9 +131,16 @@ background-color: #F9F9F9; /* css hack for IE */ width: expression((parseInt(document.documentElement.clientWidth)-240)+'px');
}
+#mailcontframe_mailpreviewframe_splitter +{
+}
#messagecontframe { width: 100%;