diff --git a/converse.css b/converse.css
index d458ad9e0..244d2f0ae 100644
--- a/converse.css
+++ b/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;
diff --git a/converse.js b/converse.js
index 6819c3076..c61faa18d 100644
--- a/converse.js
+++ b/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, console, templates) {
+}(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 () {} };
+ }
+
$.fn.addHyperlinks = function() {
if (this.length > 0) {
this.each(function(i, obj) {
diff --git a/docs/CHANGES.rst b/docs/CHANGES.rst
index f6f8719a1..ef69ef6e0 100644
--- a/docs/CHANGES.rst
+++ b/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]
diff --git a/dragresize/dragresize.html b/dragresize/dragresize.html
deleted file mode 100644
index 2730601e9..000000000
--- a/dragresize/dragresize.html
+++ /dev/null
@@ -1,234 +0,0 @@
-
-
-
-
- Div Drag/Resize Demo
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Div 2
- Content
-
-
-
-
-
-
-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:
-
-
- - Can both drag and resize page elements.
- - Works with absolute and relatively positioned elements
- in your page.
- - Customisable appearance as it makes extensive use of CSS
- classes for layout of its resisze handles.
- - Unobtrusive, Object-Orientated JavaScript means it's easy
- to add to your pages.
- - Bounding boxes and minimum sizes can be set and
- automatically enforced.
- - Cross-browser compatible so it works for everyone.
- - Small code size so your visitors don't have to wait!
-
-
-
-
-
Script License Agreement
-
-
DragResize © 2005-2006 Angus Turnbull, TwinHelix Designs
- http://www.twinhelix.com
-
Licensed under the
- CC-GNU LGPL,
- version 2.1 or later.
-
This is distributed WITHOUT ANY WARRANTY; without even the implied
- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-
-
-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
-make a donation.
-See the source for more details and instructions.
-
-Note: DragResize was conceived initially as part of my work on the
-Fotonotes DHTML Client.
-
-Good luck - Angus.
-
-
-
diff --git a/dragresize/dragresize.js b/dragresize/dragresize.js
deleted file mode 100644
index e72fbfdfa..000000000
--- a/dragresize/dragresize.js
+++ /dev/null
@@ -1,14 +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.
-
-*/
-
-
-if(typeof addEvent!='function'){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;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]}}function cancelEvent(e,c){e.returnValue=false;if(e.preventDefault)e.preventDefault();if(c){e.cancelBubble=true;if(e.stopPropagation)e.stopPropagation()}};function DragResize(myName,config){var props={myName:myName,enabled:true,handles:['tl','tm','tr','ml','mr','bl','bm','br'],isElement:null,isHandle:null,element:null,handle:null,minWidth:10,minHeight:10,minLeft:0,maxLeft:9999,minTop:0,maxTop:9999,zIndex:1,mouseX:0,mouseY:0,lastMouseX:0,lastMouseY:0,mOffX:0,mOffY:0,elmX:0,elmY:0,elmW:0,elmH:0,allowBlur:true,ondragfocus:null,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){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){if(!document.getElementById||!enabled)return;if(newElement&&(newElement!=element)&&enabled){element=newElement;element.style.zIndex=++zIndex;if(this.resizeHandleSet)this.resizeHandleSet(element,true);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){if(!document.getElementById||!enabled)return;if(delHandles){if(ondragblur)this.ondragblur();if(this.resizeHandleSet)this.resizeHandleSet(element,false);element=null}handle=null;mOffX=0;mOffY=0}};DragResize.prototype.mouseDown=function(e){with(this){if(!document.getElementById||!enabled)return true;var elm=e.target||e.srcElement,newElement=null,newHandle=null,hRE=new RegExp(myName+'-([trmbl]{2})','');while(elm){if(elm.className){if(!newHandle&&(hRE.test(elm.className)||isHandle(elm)))newHandle=elm;if(isElement(elm)){newElement=elm;break}}elm=elm.parentNode}if(element&&(element!=newElement)&&allowBlur)deselect(true);if(newElement&&(!element||(newElement==element))){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){if(!document.getElementById||!enabled)return true;mouseX=e.pageX||e.clientX+document.documentElement.scrollLeft;mouseY=e.pageY||e.clientY+document.documentElement.scrollTop;var diffX=mouseX-lastMouseX+mOffX;var diffY=mouseY-lastMouseY+mOffY;mOffX=mOffY=0;lastMouseX=mouseX;lastMouseY=mouseY;if(!handle)return true;var isResize=false;if(this.resizeHandleDrag&&this.resizeHandleDrag(diffX,diffY)){isResize=true}else{var dX=diffX,dY=diffY;if(elmX+dXmaxLeft)mOffX=(dX-(diffX=maxLeft-elmX-elmW));if(elmY+dYmaxTop)mOffY=(dY-(diffY=maxTop-elmY-elmH));elmX+=diffX;elmY+=diffY}with(element.style){left=elmX+'px';width=elmW+'px';top=elmY+'px';height=elmH+'px'}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);cancelEvent(e)}};DragResize.prototype.mouseUp=function(e){with(this){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.resizeHandleSet=function(elm,show){with(this){if(!elm._handle_tr){for(var h=0;h=0){rs=1;if(elmH-dY=0){rs=1;if(elmH+dYmaxTop)mOffY=(dY-(diffY=maxTop-elmY-elmH));elmH+=diffY;processed=true}if(hClass.indexOf('l')>=0){rs=1;if(elmW-dX=0){rs=1;if(elmW+dXmaxLeft)mOffX=(dX-(diffX=maxLeft-elmX-elmW));elmW+=diffX;processed=true}return processed}};
\ No newline at end of file
diff --git a/dragresize/dragresize_commented.js b/dragresize/dragresize_commented.js
deleted file mode 100644
index 08d8d74c1..000000000
--- a/dragresize/dragresize_commented.js
+++ /dev/null
@@ -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;
-}};
diff --git a/main.js b/main.js
index 1a139cf0f..f0e1fba16 100644
--- a/main.js
+++ b/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",
diff --git a/src/deps-full.js b/src/deps-full.js
index 696f9e367..fdb7cf4cf 100644
--- a/src/deps-full.js
+++ b/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;
});
diff --git a/src/dragresize.js b/src/dragresize.js
new file mode 100644
index 000000000..3375d9cca
--- /dev/null
+++ b/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;
+}));
diff --git a/src/templates/chatbox.html b/src/templates/chatbox.html
index 211881baa..09e8e41e7 100644
--- a/src/templates/chatbox.html
+++ b/src/templates/chatbox.html
@@ -2,7 +2,7 @@
-
+
{{ fullname }}
diff --git a/src/templates/chatroom.html b/src/templates/chatroom.html
index 32c3aedf7..96dd21723 100644
--- a/src/templates/chatroom.html
+++ b/src/templates/chatroom.html
@@ -2,7 +2,7 @@