From 62f6997a257d70a1869fe160a46534abed478e42 Mon Sep 17 00:00:00 2001 From: JC Brand Date: Thu, 23 Jan 2014 00:53:50 +0200 Subject: [PATCH] Chat boxes and rooms can now be resized vertically The new size is not stored/persisted. --- converse.css | 2 +- converse.js | 37 +++- docs/CHANGES.rst | 10 +- dragresize/dragresize.html | 234 ---------------------- dragresize/dragresize.js | 14 -- dragresize/dragresize_commented.js | 295 --------------------------- main.js | 3 +- src/deps-full.js | 5 +- src/dragresize.js | 307 +++++++++++++++++++++++++++++ src/templates/chatbox.html | 2 +- src/templates/chatroom.html | 2 +- 11 files changed, 352 insertions(+), 559 deletions(-) delete mode 100644 dragresize/dragresize.html delete mode 100644 dragresize/dragresize.js delete mode 100644 dragresize/dragresize_commented.js create mode 100644 src/dragresize.js 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 - - - - - - - - - -
-

DragResize v1.0

- by Angus Turnbull - http://www.twinhelix.com. - Updated: 27 June 2006. -
-
- - - - -
-
Div 0
- Content -
- -
-
Div 1
- Content -
- -
- 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:

- - - -
- -

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 @@
- +
{{ name }}