Browse Source

Chat boxes and rooms can now be resized vertically

The new size is not stored/persisted.
JC Brand 11 years ago
parent
commit
62f6997a25

+ 1 - 1
converse.css

@@ -758,7 +758,7 @@ a.close-chatbox-button:active {
 }
 
 #converse-roster {
-    overflow-y: scroll;
+    overflow-y: auto;
     overflow-x: hidden;
     width: 100%;
     position: relative;

+ 29 - 8
converse.js

@@ -8,17 +8,16 @@
 
 // AMD/global registrations
 (function (root, factory) {
-    if (typeof console === "undefined" || typeof console.log === "undefined") {
-        console = { log: function () {}, error: function () {} };
-    }
     if (typeof define === 'function' && define.amd) {
         define("converse",
               ["converse-dependencies", "converse-templates"],
-            function(otr, templates) {
+            function(dependencies, templates) {
+                var DragResize = dependencies[0];
+                var otr = dependencies[1];
                 if (typeof otr !== "undefined") {
-                    return factory(jQuery, _, otr.OTR, otr.DSA, console, templates);
+                    return factory(jQuery, _, otr.OTR, otr.DSA, templates, DragResize);
                 } else {
-                    return factory(jQuery, _, undefined, undefined, console, templates);
+                    return factory(jQuery, _, undefined, undefined, templates, DragResize);
                 }
             }
         );
@@ -29,9 +28,31 @@
             evaluate : /\{\[([\s\S]+?)\]\}/g,
             interpolate : /\{\{([\s\S]+?)\}\}/g
         };
-        root.converse = factory(jQuery, _, OTR, DSA, console || {log: function(){}});
+        // TODO Templates not defined
+        root.converse = factory(jQuery, _, OTR, DSA, templates, DragResize);
+    }
+}(this, function ($, _, OTR, DSA, templates, DragResize) {
+
+    var dragresize = new DragResize('dragresize', {
+        minWidth: 200,
+        minHeight: 250,
+        minLeft: 20,
+        minTop: 20,
+        maxLeft: 0,
+        maxTop: 600,
+        handles: ['tm']
+    });
+    dragresize.isElement = function(elm) {
+        if (elm.className && elm.className.indexOf('box-flyout') > -1) {
+            return true;
+        }
+    };
+    dragresize.apply(document);
+
+    if (typeof console === "undefined" || typeof console.log === "undefined") {
+        console = { log: function () {}, error: function () {} };
     }
-}(this, function ($, _, OTR, DSA, console, templates) {
+
     $.fn.addHyperlinks = function() {
         if (this.length > 0) {
             this.each(function(i, obj) {

+ 8 - 2
docs/CHANGES.rst

@@ -1,8 +1,14 @@
 Changelog
 =========
 
-Unreleased
-----------
+0.8 (Unreleased)
+----------------
+
+* Chat boxes and rooms can now be resized vertically. [jcbrand]
+* Chat boxes and rooms can be minimized. [jcbrand]
+
+0.7.3 (Unreleased)
+------------------
 
 * Option to display a call button in the chatbox toolbar, to allow third-party libraries to provide a calling feature. [Aupajo]
 * #108 Japanese Translations. [mako09]

+ 0 - 234
dragresize/dragresize.html

@@ -1,234 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
-<head>
- <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
- <title>Div Drag/Resize Demo</title>
- <script type="text/javascript" src="dragresize.js"></script>
-
-<style type="text/css">
-
-/* Required CSS classes: must be included in all pages using this script */
-
-/* Apply the element you want to drag/resize */
-.drsElement {
- position: absolute;
- border: 1px solid #333;
-}
-
-/*
- The main mouse handle that moves the whole element.
- You can apply to the same tag as drsElement if you want.
-*/
-.drsMoveHandle {
- height: 20px;
- background-color: #CCC;
- border-bottom: 1px solid #666;
- cursor: move;
-}
-
-/*
- The DragResize object name is automatically applied to all generated
- corner resize handles, as well as one of the individual classes below.
-*/
-.dragresize {
- position: absolute;
- width: 5px;
- height: 5px;
- font-size: 1px;
- background: #EEE;
- border: 1px solid #333;
-}
-
-/*
- Individual corner classes - required for resize support.
- These are based on the object name plus the handle ID.
-*/
-.dragresize-tl {
- top: -8px;
- left: -8px;
- cursor: nw-resize;
-}
-.dragresize-tm {
- top: -8px;
- left: 50%;
- margin-left: -4px;
- cursor: n-resize;
-}
-.dragresize-tr {
- top: -8px;
- right: -8px;
- cursor: ne-resize;
-}
-
-.dragresize-ml {
- top: 50%;
- margin-top: -4px;
- left: -8px;
- cursor: w-resize;
-}
-.dragresize-mr {
- top: 50%;
- margin-top: -4px;
- right: -8px;
- cursor: e-resize;
-}
-
-.dragresize-bl {
- bottom: -8px;
- left: -8px;
- cursor: sw-resize;
-}
-.dragresize-bm {
- bottom: -8px;
- left: 50%;
- margin-left: -4px;
- cursor: s-resize;
-}
-.dragresize-br {
- bottom: -8px;
- right: -8px;
- cursor: se-resize;
-}
-
-</style>
-
-<script type="text/javascript">
-//<![CDATA[
-
-// Using DragResize is simple!
-// You first declare a new DragResize() object, passing its own name and an object
-// whose keys constitute optional parameters/settings:
-
-var dragresize = new DragResize('dragresize',
- { minWidth: 50, minHeight: 50, minLeft: 20, minTop: 20, maxLeft: 600, maxTop: 600 });
-
-// Optional settings/properties of the DragResize object are:
-//  enabled: Toggle whether the object is active.
-//  handles[]: An array of drag handles to use (see the .JS file).
-//  minWidth, minHeight: Minimum size to which elements are resized (in pixels).
-//  minLeft, maxLeft, minTop, maxTop: Bounding box (in pixels).
-
-// Next, you must define two functions, isElement and isHandle. These are passed
-// a given DOM element, and must "return true" if the element in question is a
-// draggable element or draggable handle. Here, I'm checking for the CSS classname
-// of the elements, but you have have any combination of conditions you like:
-
-dragresize.isElement = function(elm)
-{
- if (elm.className && elm.className.indexOf('drsElement') > -1) return true;
-};
-dragresize.isHandle = function(elm)
-{
- if (elm.className && elm.className.indexOf('drsMoveHandle') > -1) return true;
-};
-
-// You can define optional functions that are called as elements are dragged/resized.
-// Some are passed true if the source event was a resize, or false if it's a drag.
-// The focus/blur events are called as handles are added/removed from an object,
-// and the others are called as users drag, move and release the object's handles.
-// You might use these to examine the properties of the DragResize object to sync
-// other page elements, etc.
-
-dragresize.ondragfocus = function() { };
-dragresize.ondragstart = function(isResize) { };
-dragresize.ondragmove = function(isResize) { };
-dragresize.ondragend = function(isResize) { };
-dragresize.ondragblur = function() { };
-
-// Finally, you must apply() your DragResize object to a DOM node; all children of this
-// node will then be made draggable. Here, I'm applying to the entire document.
-dragresize.apply(document);
-
-//]]>
-</script>
-
-</head>
-<body style="font: 13px/20px sans-serif; background-color: #FFF">
-
-<div style="text-align: center">
- <h1 style="font: 32px/48px sans-serif">DragResize v1.0</h1>
- by Angus Turnbull - <a href="http://www.twinhelix.com">http://www.twinhelix.com</a>.
- Updated: 27 June 2006.
- <hr />
-</div>
-
-
-<!--
- Here's our draggable elements.
- All that's required is that they have a relative or absolute CSS 'position',
- and are matched by the isElement/isHandle methods of a DragResize object.
- Easy!
--->
-
-<div class="drsElement"
- style="left: 50px; top: 150px; width: 250px; height: 120px;
- background: #CDF; text-align: center">
- <div class="drsMoveHandle">Div 0</div>
- Content
-</div>
-
-<div class="drsElement"
- style="left: 20px; top: 300px; width: 150px; height: 200px;
- background: #FDC; text-align: center">
- <div class="drsMoveHandle">Div 1</div>
- Content
-</div>
-
-<div class="drsElement drsMoveHandle"
- style="left: 150px; top: 280px; width: 50px; height: 100px;
- background: #DFC; text-align: center">
- Div 2
- Content
-</div>
-
-
-
-<div style="margin-top: 400px"><!-- spacer --></div>
-
-<p>This is a JavaScript library that lets you easily implement user-friendly
-and customisable dragging and resizing of your page elements. You might want to
-use it as part of a web application -- it contains all you need for a
-lightweight "windowing" system. Features include:</p>
-
-<ul>
- <li><strong>Can both drag and resize</strong> page elements.</li>
- <li><strong>Works with absolute and relatively positioned</strong> elements
-  in your page.</li>
- <li><strong>Customisable appearance</strong> as it makes extensive use of CSS
-  classes for layout of its resisze handles.</li>
- <li><strong>Unobtrusive, Object-Orientated JavaScript</strong> means it's easy
-  to add to your pages.</li>
- <li><strong>Bounding boxes and minimum sizes</strong> can be set and
-  automatically enforced.</li>
- <li><strong>Cross-browser compatible</strong> so it works for everyone.</li>
- <li><strong>Small code size</strong> so your visitors don't have to wait!</li>
-</ul>
-
-<div style="border: 2px solid red; background: #FFF0F0; padding: 0pt 10pt 0pt 10pt">
-
- <h4>Script License Agreement</h4>
-
- <p>DragResize &copy; 2005-2006 Angus Turnbull, TwinHelix Designs
- <a href="http://www.twinhelix.com">http://www.twinhelix.com</a></p>
- <p>Licensed under the
-  <a href="http://creativecommons.org/licenses/LGPL/2.1/">CC-GNU LGPL,
-  version 2.1 or later</a>.</p>
- <p>This is distributed WITHOUT ANY WARRANTY; without even the implied
-  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</p>
-
-</div>
-
-<p>I hope you find it handy!
-It's free for you to use and distribute, as long as you retain the license and
-copyright as per the LGPL.
-If you like this and/or my other scripts, you're more than welcome to
-<a href="http://www.twinhelix.com/donate/">make a donation</a>.
-See the source for more details and instructions.</p>
-
-<p>Note: DragResize was conceived initially as part of my work on the
-<a href="http://www.fotonotes.net">Fotonotes DHTML Client</a>.</p>
-
-<p><em>Good luck - Angus.</em></p>
-
-</body>
-</html>

File diff suppressed because it is too large
+ 0 - 13
dragresize/dragresize.js


+ 0 - 295
dragresize/dragresize_commented.js

@@ -1,295 +0,0 @@
-/*
-DragResize v1.0
-(c) 2005-2006 Angus Turnbull, TwinHelix Designs http://www.twinhelix.com
-
-Licensed under the CC-GNU LGPL, version 2.1 or later:
-http://creativecommons.org/licenses/LGPL/2.1/
-This is distributed WITHOUT ANY WARRANTY; without even the implied
-warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-*/
-
-// Common API code.
-if (typeof addEvent != 'function') {
-    var removeEvent = function(o, t, f, l) {
-        var d = 'removeEventListener';
-        if (o[d] && !l) {
-            return o[d](t, f, false);
-        }
-        if (o._evts && o._evts[t] && f._i) {
-            delete o._evts[t][f._i];
-        }
-    };
-
-    var addEvent = function(o, t, f, l) {
-        var d = 'addEventListener', n = 'on' + t, rO = o, rT = t, rF = f, rL = l;
-        if (o[d] && !l) {
-            return o[d](t, f, false);
-        }
-        if (!o._evts) {
-            o._evts = {};
-        }
-        if (!o._evts[t]) {
-            o._evts[t] = o[n] ? { b: o[n] } : {};
-            o[n] = new Function('e',
-                'var r = true, o = this, a = o._evts["' + t + '"], i; for (i in a) {' +
-                'o._f = a[i]; r = o._f(e||window.event) != false && r; o._f = null;' +
-                '} return r'
-            );
-            if (t != 'unload') {
-                addEvent(window, 'unload', function() {
-                    removeEvent(rO, rT, rF, rL);
-                });
-            }
-        }
-        if (!f._i) {
-            f._i = addEvent._i++;
-        }
-        o._evts[t][f._i] = f;
-    };
-    addEvent._i = 1;
-}
-
-function cancelEvent(e, c) {
-    e.returnValue = false;
-    if (e.preventDefault) {
-        e.preventDefault();
-    }
-    if (c) {
-        e.cancelBubble = true;
-        if (e.stopPropagation) {
-            e.stopPropagation();
-        }
-    }
-}
-
-// *** DRAG/RESIZE CODE ***
-function DragResize(myName, config) {
-    var props = {
-        myName: myName,                  // Name of the object.
-        enabled: true,                   // Global toggle of drag/resize.
-        handles: ['tl', 'tm', 'tr',
-        'ml', 'mr', 'bl', 'bm', 'br'],   // Array of drag handles: top/mid/bot/right.
-        isElement: null,                 // Function ref to test for an element.
-        element: null,                   // The currently selected element.
-        handle: null,                    // Active handle reference of the element.
-        minWidth: 10, minHeight: 10,     // Minimum pixel size of elements.
-        minLeft: 0, maxLeft: 9999,       // Bounding box area, in pixels.
-        minTop: 0, maxTop: 9999,
-        zIndex: 1,                       // The highest Z-Index yet allocated.
-        mouseX: 0, mouseY: 0,            // Current mouse position, recorded live.
-        lastMouseX: 0, lastMouseY: 0,    // Last processed mouse positions.
-        mOffX: 0, mOffY: 0,              // A known offset between position & mouse.
-        elmX: 0, elmY: 0,                // Element position.
-        elmW: 0, elmH: 0,                // Element size.
-        allowBlur: true,                 // Whether to allow automatic blur onclick.
-        ondragfocus: null,               // Event handler functions.
-        ondragstart: null,
-        ondragmove: null,
-        ondragend: null,
-        ondragblur: null
-    };
-
-    for (var p in props) {
-        this[p] = (typeof config[p] == 'undefined') ? props[p] : config[p];
-    }
-};
-
-
-DragResize.prototype.apply = function(node) {
-    // Adds object event handlers to the specified DOM node.
-    var obj = this;
-    addEvent(node, 'mousedown', function(e) { obj.mouseDown(e) } );
-    addEvent(node, 'mousemove', function(e) { obj.mouseMove(e) } );
-    addEvent(node, 'mouseup', function(e) { obj.mouseUp(e) } );
-};
-
-DragResize.prototype.select = function(newElement) { 
-    with (this) {
-        // Selects an element for dragging.
-        if (!document.getElementById || !enabled) return;
-
-        // Activate and record our new dragging element.
-        if (newElement && (newElement != element) && enabled) {
-            element = newElement;
-            // Elevate it
-            element.style.zIndex = ++zIndex;
-            // Record element attributes for mouseMove().
-            elmX = parseInt(element.style.left);
-            elmY = parseInt(element.style.top);
-            elmW = element.offsetWidth;
-            elmH = element.offsetHeight;
-            if (ondragfocus) this.ondragfocus();
-        }
-    }
-};
-
-DragResize.prototype.deselect = function(delHandles) {
-    with (this) {
-        // Immediately stops dragging an element. If 'delHandles' is true, this
-        // remove the handles from the element and clears the element flag,
-        // completely resetting the .
-        if (!document.getElementById || !enabled) return;
-
-        if (delHandles) {
-            if (ondragblur) this.ondragblur();
-            element = null;
-        }
-        handle = null;
-        mOffX = 0;
-        mOffY = 0;
-    }
-};
-
-DragResize.prototype.mouseDown = function(e) {
-    with (this) {
-        // Suitable elements are selected for drag/resize on mousedown.
-        // We also initialise the resize boxes, and drag parameters like mouse position etc.
-        if (!document.getElementById || !enabled) return true;
-
-        var elm = e.target || e.srcElement,
-            newElement = null,
-            newHandle = null,
-            hRE = new RegExp(myName + '-([trmbl]{2})', '');
-
-        while (elm) {
-            // Loop up the DOM looking for matching elements. Remember one if found.
-            if (elm.className) {
-                if (!newHandle && (hRE.test(elm.className))) newHandle = elm;
-                if (isElement(elm)) { newElement = elm; break }
-            }
-            elm = elm.parentNode;
-        }
-
-        // If this isn't on the last dragged element, call deselect(),
-        // which will hide its handles and clear element.
-        if (element && (element != newElement) && allowBlur) deselect(true);
-
-        // If we have a new matching element, call select().
-        if (newElement && (!element || (newElement == element))) {
-            // Stop mouse selections if we're dragging a handle.
-            if (newHandle) cancelEvent(e);
-            select(newElement, newHandle);
-            handle = newHandle;
-            if (handle && ondragstart) this.ondragstart(hRE.test(handle.className));
-        }
-    }
-};
-
-DragResize.prototype.mouseMove = function(e) { with (this) {
-    // This continually offsets the dragged element by the difference between the
-    // last recorded mouse position (mouseX/Y) and the current mouse position.
-    if (!document.getElementById || !enabled) return true;
-
-    // We always record the current mouse position.
-    mouseX = e.pageX || e.clientX + document.documentElement.scrollLeft;
-    mouseY = e.pageY || e.clientY + document.documentElement.scrollTop;
-    // Record the relative mouse movement, in case we're dragging.
-    // Add any previously stored & ignored offset to the calculations.
-    var diffX = mouseX - lastMouseX + mOffX;
-    var diffY = mouseY - lastMouseY + mOffY;
-    mOffX = mOffY = 0;
-    // Update last processed mouse positions.
-    lastMouseX = mouseX;
-    lastMouseY = mouseY;
-
-    // That's all we do if we're not dragging anything.
-    if (!handle) return true;
-
-    // If included in the script, run the resize handle drag routine.
-    // Let it create an object representing the drag offsets.
-    var isResize = false;
-    if (this.resizeHandleDrag && this.resizeHandleDrag(diffX, diffY)) {
-        isResize = true;
-    } else {
-        // If the resize drag handler isn't set or returns fase (to indicate the drag was
-        // not on a resize handle), we must be dragging the whole element, so move that.
-        // Bounds check left-right...
-        var dX = diffX, dY = diffY;
-        if (elmX + dX < minLeft) mOffX = (dX - (diffX = minLeft - elmX));
-        else if (elmX + elmW + dX > maxLeft) mOffX = (dX - (diffX = maxLeft - elmX - elmW));
-        // ...and up-down.
-        if (elmY + dY < minTop) mOffY = (dY - (diffY = minTop - elmY));
-        else if (elmY + elmH + dY > maxTop) mOffY = (dY - (diffY = maxTop - elmY - elmH));
-        elmX += diffX;
-        elmY += diffY;
-    }
-
-    // Assign new info back to the element, with minimum dimensions.
-    with (element.style) {
-        left =   elmX + 'px';
-        width =  elmW + 'px';
-        top =    elmY + 'px';
-        height = elmH + 'px';
-    }
-
-    // Evil, dirty, hackish Opera select-as-you-drag fix.
-    if (window.opera && document.documentElement) {
-        var oDF = document.getElementById('op-drag-fix');
-        if (!oDF) {
-            var oDF = document.createElement('input');
-            oDF.id = 'op-drag-fix';
-            oDF.style.display = 'none';
-            document.body.appendChild(oDF);
-        }
-        oDF.focus();
-    }
-
-    if (ondragmove) this.ondragmove(isResize);
-    // Stop a normal drag event.
-    cancelEvent(e);
-}};
-
-
-DragResize.prototype.mouseUp = function(e) { with (this) {
-    // On mouseup, stop dragging, but don't reset handler visibility.
-    if (!document.getElementById || !enabled) return;
-
-    var hRE = new RegExp(myName + '-([trmbl]{2})', '');
-    if (handle && ondragend) this.ondragend(hRE.test(handle.className));
-    deselect(false);
-}};
-
-DragResize.prototype.resizeHandleDrag = function(diffX, diffY) { with (this) {
-    // Passed the mouse movement amounts. This function checks to see whether the
-    // drag is from a resize handle created above; if so, it changes the stored
-    // elm* dimensions and mOffX/Y.
-
-    var hClass = handle && handle.className &&
-        handle.className.match(new RegExp(myName + '-([tmblr]{2})')) ? RegExp.$1 : '';
-
-    // If the hClass is one of the resize handles, resize one or two dimensions.
-    // Bounds checking is the hard bit -- basically for each edge, check that the
-    // element doesn't go under minimum size, and doesn't go beyond its boundary.
-    var dY = diffY, dX = diffX, processed = false;
-    if (hClass.indexOf('t') >= 0) {
-        rs = 1;
-        if (elmH - dY < minHeight) mOffY = (dY - (diffY = elmH - minHeight));
-        else if (elmY + dY < minTop) mOffY = (dY - (diffY = minTop - elmY));
-        elmY += diffY;
-        elmH -= diffY;
-        processed = true;
-    }
-    if (hClass.indexOf('b') >= 0) {
-        rs = 1;
-        if (elmH + dY < minHeight) mOffY = (dY - (diffY = minHeight - elmH));
-        else if (elmY + elmH + dY > maxTop) mOffY = (dY - (diffY = maxTop - elmY - elmH));
-        elmH += diffY;
-        processed = true;
-    }
-    if (hClass.indexOf('l') >= 0) {
-        rs = 1;
-        if (elmW - dX < minWidth) mOffX = (dX - (diffX = elmW - minWidth));
-        else if (elmX + dX < minLeft) mOffX = (dX - (diffX = minLeft - elmX));
-        elmX += diffX;
-        elmW -= diffX;
-        processed = true;
-    }
-    if (hClass.indexOf('r') >= 0) {
-        rs = 1;
-        if (elmW + dX < minWidth) mOffX = (dX - (diffX = minWidth - elmW));
-        else if (elmX + elmW + dX > maxLeft) mOffX = (dX - (diffX = maxLeft - elmX - elmW));
-        elmW += diffX;
-        processed = true;
-    }
-    return processed;
-}};

+ 2 - 1
main.js

@@ -1,8 +1,9 @@
 config = {
     paths: {
         "jquery": "components/jquery/jquery",
-        "locales": "locale/locales",
         "jquery.tinysort": "components/tinysort/src/jquery.tinysort",
+        "dragresize": "src/dragresize",
+        "locales": "locale/locales",
         "underscore": "components/underscore/underscore",
         "backbone": "components/backbone/backbone",
         "backbone.localStorage": "components/backbone.localStorage/backbone.localStorage",

+ 3 - 2
src/deps-full.js

@@ -1,4 +1,5 @@
 define("converse-dependencies", [
+    "dragresize",
     "otr",
     "locales",
     "backbone.localStorage",
@@ -8,6 +9,6 @@ define("converse-dependencies", [
     "strophe.roster",
     "strophe.vcard",
     "strophe.disco"
-], function(otr) {
-    return otr;
+], function() {
+    return arguments;
 });

+ 307 - 0
src/dragresize.js

@@ -0,0 +1,307 @@
+/*
+DragResize v1.1
+(c) 2005-2006 Angus Turnbull, TwinHelix Designs http://www.twinhelix.com
+
+Licensed under the CC-GNU LGPL, version 2.1 or later:
+http://creativecommons.org/licenses/LGPL/2.1/
+This is distributed WITHOUT ANY WARRANTY; without even the implied
+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+Simplified and modified for Converse.js by JC Brand https://opkode.com
+*/
+
+(function (root, factory) {
+    if (typeof define === 'function' && define.amd) {
+        define("dragresize", [], function() { return factory(); });
+    } else {
+        root.dragresize = factory();
+    }
+}(this, function () {
+
+    // Common API code.
+    if (typeof addEvent != 'function') {
+        var removeEvent = function(o, t, f, l) {
+            var d = 'removeEventListener';
+            if (o[d] && !l) {
+                return o[d](t, f, false);
+            }
+            if (o._evts && o._evts[t] && f._i) {
+                delete o._evts[t][f._i];
+            }
+        };
+
+        var addEvent = function(o, t, f, l) {
+            var d = 'addEventListener', n = 'on' + t, rO = o, rT = t, rF = f, rL = l;
+            if (o[d] && !l) {
+                return o[d](t, f, false);
+            }
+            if (!o._evts) {
+                o._evts = {};
+            }
+            if (!o._evts[t]) {
+                o._evts[t] = o[n] ? { b: o[n] } : {};
+                o[n] = new Function('e',
+                    'var r = true, o = this, a = o._evts["' + t + '"], i; for (i in a) {' +
+                    'o._f = a[i]; r = o._f(e||window.event) != false && r; o._f = null;' +
+                    '} return r'
+                );
+                if (t != 'unload') {
+                    addEvent(window, 'unload', function() {
+                        removeEvent(rO, rT, rF, rL);
+                    });
+                }
+            }
+            if (!f._i) {
+                f._i = addEvent._i++;
+            }
+            o._evts[t][f._i] = f;
+        };
+        addEvent._i = 1;
+    }
+
+    function cancelEvent(e, c) {
+        e.returnValue = false;
+        if (e.preventDefault) {
+            e.preventDefault();
+        }
+        if (c) {
+            e.cancelBubble = true;
+            if (e.stopPropagation) {
+                e.stopPropagation();
+            }
+        }
+    }
+
+    // *** DRAG/RESIZE CODE ***
+    function DragResize(myName, config) {
+        var props = {
+            myName: myName,                  // Name of the object.
+            enabled: true,                   // Global toggle of drag/resize.
+            handles: ['tl', 'tm', 'tr',
+            'ml', 'mr', 'bl', 'bm', 'br'],   // Array of drag handles: top/mid/bot/right.
+            isElement: null,                 // Function ref to test for an element.
+            element: null,                   // The currently selected element.
+            handle: null,                    // Active handle reference of the element.
+            minWidth: 10, minHeight: 10,     // Minimum pixel size of elements.
+            minLeft: 0, maxLeft: 9999,       // Bounding box area, in pixels.
+            minTop: 0, maxTop: 9999,
+            zIndex: 1,                       // The highest Z-Index yet allocated.
+            mouseX: 0, mouseY: 0,            // Current mouse position, recorded live.
+            lastMouseX: 0, lastMouseY: 0,    // Last processed mouse positions.
+            mOffX: 0, mOffY: 0,              // A known offset between position & mouse.
+            elmX: 0, elmY: 0,                // Element position.
+            elmW: 0, elmH: 0,                // Element size.
+            allowBlur: true,                 // Whether to allow automatic blur onclick.
+            ondragfocus: null,               // Event handler functions.
+            ondragstart: null,
+            ondragmove: null,
+            ondragend: null,
+            ondragblur: null
+        };
+
+        for (var p in props) {
+            this[p] = (typeof config[p] == 'undefined') ? props[p] : config[p];
+        }
+    };
+
+
+    DragResize.prototype.apply = function(node) {
+        // Adds object event handlers to the specified DOM node.
+        var obj = this;
+        addEvent(node, 'mousedown', function(e) { obj.mouseDown(e) } );
+        addEvent(node, 'mousemove', function(e) { obj.mouseMove(e) } );
+        addEvent(node, 'mouseup', function(e) { obj.mouseUp(e) } );
+    };
+
+    DragResize.prototype.select = function(newElement) { 
+        with (this) {
+            // Selects an element for dragging.
+            if (!document.getElementById || !enabled) return;
+
+            // Activate and record our new dragging element.
+            if (newElement && (newElement != element) && enabled) {
+                element = newElement;
+                // Elevate it
+                element.style.zIndex = ++zIndex;
+                // Record element attributes for mouseMove().
+                elmX = parseInt(element.style.left);
+                elmY = parseInt(element.style.top);
+                elmW = element.offsetWidth;
+                elmH = element.offsetHeight;
+                if (ondragfocus) this.ondragfocus();
+            }
+        }
+    };
+
+    DragResize.prototype.deselect = function(delHandles) {
+        with (this) {
+            // Immediately stops dragging an element. If 'delHandles' is true, this
+            // remove the handles from the element and clears the element flag,
+            // completely resetting the .
+            if (!document.getElementById || !enabled) return;
+
+            if (delHandles) {
+                if (ondragblur) this.ondragblur();
+                element = null;
+            }
+            handle = null;
+            mOffX = 0;
+            mOffY = 0;
+        }
+    };
+
+    DragResize.prototype.mouseDown = function(e) {
+        with (this) {
+            // Suitable elements are selected for drag/resize on mousedown.
+            // We also initialise the resize boxes, and drag parameters like mouse position etc.
+            if (!document.getElementById || !enabled) return true;
+
+            var elm = e.target || e.srcElement,
+                newElement = null,
+                newHandle = null,
+                hRE = new RegExp(myName + '-([trmbl]{2})', '');
+
+            while (elm) {
+                // Loop up the DOM looking for matching elements. Remember one if found.
+                if (elm.className) {
+                    if (!newHandle && (hRE.test(elm.className))) newHandle = elm;
+                    if (isElement(elm)) { newElement = elm; break }
+                }
+                elm = elm.parentNode;
+            }
+
+            // If this isn't on the last dragged element, call deselect(),
+            // which will hide its handles and clear element.
+            if (element && (element != newElement) && allowBlur) deselect(true);
+
+            // If we have a new matching element, call select().
+            if (newElement && (!element || (newElement == element))) {
+                // Stop mouse selections if we're dragging a handle.
+                if (newHandle) cancelEvent(e);
+                select(newElement, newHandle);
+                handle = newHandle;
+                if (handle && ondragstart) this.ondragstart(hRE.test(handle.className));
+            }
+        }
+    };
+
+    DragResize.prototype.mouseMove = function(e) { with (this) {
+        // This continually offsets the dragged element by the difference between the
+        // last recorded mouse position (mouseX/Y) and the current mouse position.
+        if (!document.getElementById || !enabled) return true;
+
+        // We always record the current mouse position.
+        mouseX = e.pageX || e.clientX + document.documentElement.scrollLeft;
+        mouseY = e.pageY || e.clientY + document.documentElement.scrollTop;
+        // Record the relative mouse movement, in case we're dragging.
+        // Add any previously stored & ignored offset to the calculations.
+        var diffX = mouseX - lastMouseX + mOffX;
+        var diffY = mouseY - lastMouseY + mOffY;
+        mOffX = mOffY = 0;
+        // Update last processed mouse positions.
+        lastMouseX = mouseX;
+        lastMouseY = mouseY;
+
+        // That's all we do if we're not dragging anything.
+        if (!handle) return true;
+
+        // If included in the script, run the resize handle drag routine.
+        // Let it create an object representing the drag offsets.
+        var isResize = false;
+        if (this.resizeHandleDrag && this.resizeHandleDrag(diffX, diffY)) {
+            isResize = true;
+        } else {
+            // If the resize drag handler isn't set or returns fase (to indicate the drag was
+            // not on a resize handle), we must be dragging the whole element, so move that.
+            // Bounds check left-right...
+            var dX = diffX, dY = diffY;
+            if (elmX + dX < minLeft) mOffX = (dX - (diffX = minLeft - elmX));
+            else if (elmX + elmW + dX > maxLeft) mOffX = (dX - (diffX = maxLeft - elmX - elmW));
+            // ...and up-down.
+            if (elmY + dY < minTop) mOffY = (dY - (diffY = minTop - elmY));
+            else if (elmY + elmH + dY > maxTop) mOffY = (dY - (diffY = maxTop - elmY - elmH));
+            elmX += diffX;
+            elmY += diffY;
+        }
+
+        // Assign new info back to the element, with minimum dimensions.
+        with (element.style) {
+            left =   elmX + 'px';
+            width =  elmW + 'px';
+            top =    elmY + 'px';
+            height = elmH + 'px';
+        }
+
+        // Evil, dirty, hackish Opera select-as-you-drag fix.
+        if (window.opera && document.documentElement) {
+            var oDF = document.getElementById('op-drag-fix');
+            if (!oDF) {
+                var oDF = document.createElement('input');
+                oDF.id = 'op-drag-fix';
+                oDF.style.display = 'none';
+                document.body.appendChild(oDF);
+            }
+            oDF.focus();
+        }
+
+        if (ondragmove) this.ondragmove(isResize);
+        // Stop a normal drag event.
+        cancelEvent(e);
+    }};
+
+
+    DragResize.prototype.mouseUp = function(e) { with (this) {
+        // On mouseup, stop dragging, but don't reset handler visibility.
+        if (!document.getElementById || !enabled) return;
+
+        var hRE = new RegExp(myName + '-([trmbl]{2})', '');
+        if (handle && ondragend) this.ondragend(hRE.test(handle.className));
+        deselect(false);
+    }};
+
+    DragResize.prototype.resizeHandleDrag = function(diffX, diffY) { with (this) {
+        // Passed the mouse movement amounts. This function checks to see whether the
+        // drag is from a resize handle created above; if so, it changes the stored
+        // elm* dimensions and mOffX/Y.
+
+        var hClass = handle && handle.className &&
+            handle.className.match(new RegExp(myName + '-([tmblr]{2})')) ? RegExp.$1 : '';
+
+        // If the hClass is one of the resize handles, resize one or two dimensions.
+        // Bounds checking is the hard bit -- basically for each edge, check that the
+        // element doesn't go under minimum size, and doesn't go beyond its boundary.
+        var dY = diffY, dX = diffX, processed = false;
+        if (hClass.indexOf('t') >= 0) {
+            rs = 1;
+            if (elmH - dY < minHeight) mOffY = (dY - (diffY = elmH - minHeight));
+            else if (elmY + dY < minTop) mOffY = (dY - (diffY = minTop - elmY));
+            elmY += diffY;
+            elmH -= diffY;
+            processed = true;
+        }
+        if (hClass.indexOf('b') >= 0) {
+            rs = 1;
+            if (elmH + dY < minHeight) mOffY = (dY - (diffY = minHeight - elmH));
+            else if (elmY + elmH + dY > maxTop) mOffY = (dY - (diffY = maxTop - elmY - elmH));
+            elmH += diffY;
+            processed = true;
+        }
+        if (hClass.indexOf('l') >= 0) {
+            rs = 1;
+            if (elmW - dX < minWidth) mOffX = (dX - (diffX = elmW - minWidth));
+            else if (elmX + dX < minLeft) mOffX = (dX - (diffX = minLeft - elmX));
+            elmX += diffX;
+            elmW -= diffX;
+            processed = true;
+        }
+        if (hClass.indexOf('r') >= 0) {
+            rs = 1;
+            if (elmW + dX < minWidth) mOffX = (dX - (diffX = minWidth - elmW));
+            else if (elmX + elmW + dX > maxLeft) mOffX = (dX - (diffX = maxLeft - elmX - elmW));
+            elmW += diffX;
+            processed = true;
+        }
+        return processed;
+    }};
+    return DragResize;
+}));

+ 1 - 1
src/templates/chatbox.html

@@ -2,7 +2,7 @@
     <div class="dragresize dragresize-tm"></div>
     <div class="chat-head chat-head-chatbox">
         <a class="close-chatbox-button icon-close"></a>
-        <a class="minimize-chatbox-button icon-minus"></a>
+        <a class="toggle-chatbox-button icon-minus"></a>
         <a href="{{url}}" target="_blank" class="user">
             <div class="chat-title"> {{ fullname }} </div>
         </a>

+ 1 - 1
src/templates/chatroom.html

@@ -2,7 +2,7 @@
     <div class="dragresize dragresize-tm"></div>
     <div class="chat-head chat-head-chatroom">
         <a class="close-chatbox-button icon-close"></a>
-        <a class="minimize-chatbox-button icon-minus"></a>
+        <a class="toggle-chatbox-button icon-minus"></a>
         <a class="configure-chatroom-button icon-wrench" style="display:none"></a>
         <div class="chat-title"> {{ name }} </div>
         <p class="chatroom-topic"><p/>

Some files were not shown because too many files changed in this diff