Welcome to TiddlyWiki created by Jeremy Ruston, Copyright © 2007 UnaMesa Association
/**
* Interface Elements for jQuery
* utility function
*
* http://interface.eyecon.ro
*
* Copyright (c) 2006 Stefan Petre
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
*
*/
jQuery.iUtil = {
getPosition : function(e)
{
var x = 0;
var y = 0;
var es = e.style;
var restoreStyles = false;
if (jQuery(e).css('display') == 'none') {
var oldVisibility = es.visibility;
var oldPosition = es.position;
restoreStyles = true;
es.visibility = 'hidden';
es.display = 'block';
es.position = 'absolute';
}
var el = e;
while (el){
x += el.offsetLeft + (el.currentStyle && !jQuery.browser.opera ?parseInt(el.currentStyle.borderLeftWidth)||0:0);
y += el.offsetTop + (el.currentStyle && !jQuery.browser.opera ?parseInt(el.currentStyle.borderTopWidth)||0:0);
el = el.offsetParent;
}
el = e;
while (el && el.tagName && el.tagName.toLowerCase() != 'body')
{
x -= el.scrollLeft||0;
y -= el.scrollTop||0;
el = el.parentNode;
}
if (restoreStyles == true) {
es.display = 'none';
es.position = oldPosition;
es.visibility = oldVisibility;
}
return {x:x, y:y};
},
getPositionLite : function(el)
{
var x = 0, y = 0;
while(el) {
x += el.offsetLeft || 0;
y += el.offsetTop || 0;
el = el.offsetParent;
}
return {x:x, y:y};
},
getSize : function(e)
{
var w = jQuery.css(e,'width');
var h = jQuery.css(e,'height');
var wb = 0;
var hb = 0;
var es = e.style;
if (jQuery(e).css('display') != 'none') {
wb = e.offsetWidth;
hb = e.offsetHeight;
} else {
var oldVisibility = es.visibility;
var oldPosition = es.position;
es.visibility = 'hidden';
es.display = 'block';
es.position = 'absolute';
wb = e.offsetWidth;
hb = e.offsetHeight;
es.display = 'none';
es.position = oldPosition;
es.visibility = oldVisibility;
}
return {w:w, h:h, wb:wb, hb:hb};
},
getSizeLite : function(el)
{
return {
wb:el.offsetWidth||0,
hb:el.offsetHeight||0
};
},
getClient : function(e)
{
var h, w, de;
if (e) {
w = e.clientWidth;
h = e.clientHeight;
} else {
de = document.documentElement;
w = window.innerWidth || self.innerWidth || (de&&de.clientWidth) || document.body.clientWidth;
h = window.innerHeight || self.innerHeight || (de&&de.clientHeight) || document.body.clientHeight;
}
return {w:w,h:h};
},
getScroll : function (e)
{
var t=0, l=0, w=0, h=0, iw=0, ih=0;
if (e && e.nodeName.toLowerCase() != 'body') {
t = e.scrollTop;
l = e.scrollLeft;
w = e.scrollWidth;
h = e.scrollHeight;
iw = 0;
ih = 0;
} else {
if (document.documentElement) {
t = document.documentElement.scrollTop;
l = document.documentElement.scrollLeft;
w = document.documentElement.scrollWidth;
h = document.documentElement.scrollHeight;
} else if (document.body) {
t = document.body.scrollTop;
l = document.body.scrollLeft;
w = document.body.scrollWidth;
h = document.body.scrollHeight;
}
iw = self.innerWidth||document.documentElement.clientWidth||document.body.clientWidth||0;
ih = self.innerHeight||document.documentElement.clientHeight||document.body.clientHeight||0;
}
return { t: t, l: l, w: w, h: h, iw: iw, ih: ih };
},
getMargins : function(e, toInteger)
{
var el = jQuery(e);
var t = el.css('marginTop') || '';
var r = el.css('marginRight') || '';
var b = el.css('marginBottom') || '';
var l = el.css('marginLeft') || '';
if (toInteger)
return {
t: parseInt(t)||0,
r: parseInt(r)||0,
b: parseInt(b)||0,
l: parseInt(l)
};
else
return {t: t, r: r, b: b, l: l};
},
getPadding : function(e, toInteger)
{
var el = jQuery(e);
var t = el.css('paddingTop') || '';
var r = el.css('paddingRight') || '';
var b = el.css('paddingBottom') || '';
var l = el.css('paddingLeft') || '';
if (toInteger)
return {
t: parseInt(t)||0,
r: parseInt(r)||0,
b: parseInt(b)||0,
l: parseInt(l)
};
else
return {t: t, r: r, b: b, l: l};
},
getBorder : function(e, toInteger)
{
var el = jQuery(e);
var t = el.css('borderTopWidth') || '';
var r = el.css('borderRightWidth') || '';
var b = el.css('borderBottomWidth') || '';
var l = el.css('borderLeftWidth') || '';
if (toInteger)
return {
t: parseInt(t)||0,
r: parseInt(r)||0,
b: parseInt(b)||0,
l: parseInt(l)||0
};
else
return {t: t, r: r, b: b, l: l};
},
getPointer : function(event)
{
var x = event.pageX || (event.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft)) || 0;
var y = event.pageY || (event.clientY + (document.documentElement.scrollTop || document.body.scrollTop)) || 0;
return {x:x, y:y};
},
traverseDOM : function(nodeEl, func)
{
func(nodeEl);
nodeEl = nodeEl.firstChild;
while(nodeEl){
jQuery.iUtil.traverseDOM(nodeEl, func);
nodeEl = nodeEl.nextSibling;
}
},
purgeEvents : function(nodeEl)
{
jQuery.iUtil.traverseDOM(
nodeEl,
function(el)
{
for(var attr in el){
if(typeof el[attr] === 'function') {
el[attr] = null;
}
}
}
);
},
centerEl : function(el, axis)
{
var clientScroll = jQuery.iUtil.getScroll();
var windowSize = jQuery.iUtil.getSize(el);
if (!axis || axis == 'vertically')
jQuery(el).css(
{
top: clientScroll.t + ((Math.max(clientScroll.h,clientScroll.ih) - clientScroll.t - windowSize.hb)/2) + 'px'
}
);
if (!axis || axis == 'horizontally')
jQuery(el).css(
{
left: clientScroll.l + ((Math.max(clientScroll.w,clientScroll.iw) - clientScroll.l - windowSize.wb)/2) + 'px'
}
);
},
fixPNG : function (el, emptyGIF) {
var images = jQuery('img[@src*="png"]', el||document), png;
images.each( function() {
png = this.src;
this.src = emptyGIF;
this.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + png + "')";
});
}
};
// Helper function to support older browsers!
[].indexOf || (Array.prototype.indexOf = function(v, n){
n = (n == null) ? 0 : n;
var m = this.length;
for (var i=n; i<m; i++)
if (this[i] == v)
return i;
return -1;
});
/**
* Interface Elements for jQuery
* Draggable
*
* http://interface.eyecon.ro
*
* Copyright (c) 2006 Stefan Petre
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*/
/**
* Create a draggable element with a number of advanced options including callback, Google Maps type draggables,
* reversion, ghosting, and grid dragging.
*
* @name Draggable
* @descr Creates draggable elements that can be moved across the page.
* @param Hash hash A hash of parameters. All parameters are optional.
* @option String handle (optional) The jQuery selector matching the handle that starts the draggable
* @option DOMElement handle (optional) The DOM Element of the handle that starts the draggable
* @option Boolean revert (optional) When true, on stop-drag the element returns to initial position
* @option Boolean ghosting (optional) When true, a copy of the element is moved
* @option Integer zIndex (optional) zIndex depth for the element while it is being dragged
* @option Float opacity (optional) A number between 0 and 1 that indicates the opacity of the element while being dragged
* @option Integer grid (optional) (optional) A number of pixels indicating the grid that the element should snap to
* @option Array grid (optional) A number of x-pixels and y-pixels indicating the grid that the element should snap to
* @option Integer fx (optional) Duration for the effect (like ghosting or revert) applied to the draggable
* @option String containment (optional) Define the zone where the draggable can be moved. 'parent' moves it inside parent
* element, while 'document' prevents it from leaving the document and forcing additional
* scrolling
* @option Array containment An 4-element array (left, top, width, height) indicating the containment of the element
* @option String axis (optional) Set an axis: vertical (with 'vertically') or horizontal (with 'horizontally')
* @option Function onStart (optional) Callback function triggered when the dragging starts
* @option Function onStop (optional) Callback function triggered when the dragging stops
* @option Function onChange (optional) Callback function triggered when the dragging stop *and* the element was moved at least
* one pixel
* @option Function onDrag (optional) Callback function triggered while the element is dragged. Receives two parameters: x and y
* coordinates. You can return an object with new coordinates {x: x, y: y} so this way you can
* interact with the dragging process (for instance, build your containment)
* @option Boolean insideParent Forces the element to remain inside its parent when being dragged (like Google Maps)
* @option Integer snapDistance (optional) The element is not moved unless it is dragged more than snapDistance. You can prevent
* accidental dragging and keep regular clicking enabled (for links or form elements,
* for instance)
* @option Object cursorAt (optional) The dragged element is moved to the cursor position with the offset specified. Accepts value
* for top, left, right and bottom offset. Basically, this forces the cursor to a particular
* position during the entire drag operation.
* @option Boolean autoSize (optional) When true, the drag helper is resized to its content, instead of the dragged element's sizes
* @option String frameClass (optional) When is set the cloned element is hidden so only a frame is dragged
* @type jQuery
* @cat Plugins/Interface
* @author Stefan Petre
*/
jQuery.iDrag = {
helper : null,
dragged: null,
destroy : function()
{
return this.each(
function ()
{
if (this.isDraggable) {
this.dragCfg.dhe.unbind('mousedown', jQuery.iDrag.draginit);
this.dragCfg = null;
this.isDraggable = false;
if(jQuery.browser.msie) {
this.unselectable = "off";
} else {
this.style.MozUserSelect = '';
this.style.KhtmlUserSelect = '';
this.style.userSelect = '';
}
}
}
);
},
draginit : function (e)
{
if (jQuery.iDrag.dragged != null) {
jQuery.iDrag.dragstop(e);
//return false;
}
var elm = this.dragElem;
jQuery(document)
.bind('mousemove', jQuery.iDrag.dragmove)
.bind('mouseup', jQuery.iDrag.dragstop);
elm.dragCfg.pointer = jQuery.iUtil.getPointer(e);
elm.dragCfg.currentPointer = elm.dragCfg.pointer;
elm.dragCfg.init = false;
elm.dragCfg.fromHandler = this != this.dragElem;
jQuery.iDrag.dragged = elm;
if (elm.dragCfg.si && this != this.dragElem) {
parentPos = jQuery.iUtil.getPosition(elm.parentNode);
sliderSize = jQuery.iUtil.getSize(elm);
sliderPos = {
x : parseInt(jQuery.css(elm,'left')) || 0,
y : parseInt(jQuery.css(elm,'top')) || 0
};
dx = elm.dragCfg.currentPointer.x - parentPos.x - sliderSize.wb/2 - sliderPos.x;
dy = elm.dragCfg.currentPointer.y - parentPos.y - sliderSize.hb/2 - sliderPos.y;
jQuery.iSlider.dragmoveBy(elm, [dx, dy]);
}
return jQuery.selectKeyHelper||false;
},
dragstart : function(e)
{
var elm = jQuery.iDrag.dragged;
elm.dragCfg.init = true;
var dEs = elm.style;
elm.dragCfg.oD = jQuery.css(elm,'display');
elm.dragCfg.oP = jQuery.css(elm,'position');
if (!elm.dragCfg.initialPosition)
elm.dragCfg.initialPosition = elm.dragCfg.oP;
elm.dragCfg.oR = {
x : parseInt(jQuery.css(elm,'left')) || 0,
y : parseInt(jQuery.css(elm,'top')) || 0
};
elm.dragCfg.diffX = 0;
elm.dragCfg.diffY = 0;
if (jQuery.browser.msie) {
var oldBorder = jQuery.iUtil.getBorder(elm, true);
elm.dragCfg.diffX = oldBorder.l||0;
elm.dragCfg.diffY = oldBorder.t||0;
}
elm.dragCfg.oC = jQuery.extend(
jQuery.iUtil.getPosition(elm),
jQuery.iUtil.getSize(elm)
);
if (elm.dragCfg.oP != 'relative' && elm.dragCfg.oP != 'absolute') {
dEs.position = 'relative';
}
jQuery.iDrag.helper.empty();
var clonedEl = elm.cloneNode(true);
jQuery(clonedEl).css(
{
display: 'block',
left: '0px',
top: '0px'
}
);
clonedEl.style.marginTop = '0';
clonedEl.style.marginRight = '0';
clonedEl.style.marginBottom = '0';
clonedEl.style.marginLeft = '0';
jQuery.iDrag.helper.append(clonedEl);
var dhs = jQuery.iDrag.helper.get(0).style;
if (elm.dragCfg.autoSize) {
dhs.width = 'auto';
dhs.height = 'auto';
} else {
dhs.height = elm.dragCfg.oC.hb + 'px';
dhs.width = elm.dragCfg.oC.wb + 'px';
}
dhs.display = 'block';
dhs.marginTop = '0px';
dhs.marginRight = '0px';
dhs.marginBottom = '0px';
dhs.marginLeft = '0px';
//remeasure the clone to check if the size was changed by user's functions
jQuery.extend(
elm.dragCfg.oC,
jQuery.iUtil.getSize(clonedEl)
);
if (elm.dragCfg.cursorAt) {
if (elm.dragCfg.cursorAt.left) {
elm.dragCfg.oR.x += elm.dragCfg.pointer.x - elm.dragCfg.oC.x - elm.dragCfg.cursorAt.left;
elm.dragCfg.oC.x = elm.dragCfg.pointer.x - elm.dragCfg.cursorAt.left;
}
if (elm.dragCfg.cursorAt.top) {
elm.dragCfg.oR.y += elm.dragCfg.pointer.y - elm.dragCfg.oC.y - elm.dragCfg.cursorAt.top;
elm.dragCfg.oC.y = elm.dragCfg.pointer.y - elm.dragCfg.cursorAt.top;
}
if (elm.dragCfg.cursorAt.right) {
elm.dragCfg.oR.x += elm.dragCfg.pointer.x - elm.dragCfg.oC.x -elm.dragCfg.oC.hb + elm.dragCfg.cursorAt.right;
elm.dragCfg.oC.x = elm.dragCfg.pointer.x - elm.dragCfg.oC.wb + elm.dragCfg.cursorAt.right;
}
if (elm.dragCfg.cursorAt.bottom) {
elm.dragCfg.oR.y += elm.dragCfg.pointer.y - elm.dragCfg.oC.y - elm.dragCfg.oC.hb + elm.dragCfg.cursorAt.bottom;
elm.dragCfg.oC.y = elm.dragCfg.pointer.y - elm.dragCfg.oC.hb + elm.dragCfg.cursorAt.bottom;
}
}
elm.dragCfg.nx = elm.dragCfg.oR.x;
elm.dragCfg.ny = elm.dragCfg.oR.y;
if (elm.dragCfg.insideParent || elm.dragCfg.containment == 'parent') {
parentBorders = jQuery.iUtil.getBorder(elm.parentNode, true);
elm.dragCfg.oC.x = elm.offsetLeft + (jQuery.browser.msie ? 0 : jQuery.browser.opera ? -parentBorders.l : parentBorders.l);
elm.dragCfg.oC.y = elm.offsetTop + (jQuery.browser.msie ? 0 : jQuery.browser.opera ? -parentBorders.t : parentBorders.t);
jQuery(elm.parentNode).append(jQuery.iDrag.helper.get(0));
}
if (elm.dragCfg.containment) {
jQuery.iDrag.getContainment(elm);
elm.dragCfg.onDragModifier.containment = jQuery.iDrag.fitToContainer;
}
if (elm.dragCfg.si) {
jQuery.iSlider.modifyContainer(elm);
}
dhs.left = elm.dragCfg.oC.x - elm.dragCfg.diffX + 'px';
dhs.top = elm.dragCfg.oC.y - elm.dragCfg.diffY + 'px';
//resize the helper to fit the clone
dhs.width = elm.dragCfg.oC.wb + 'px';
dhs.height = elm.dragCfg.oC.hb + 'px';
jQuery.iDrag.dragged.dragCfg.prot = false;
if (elm.dragCfg.gx) {
elm.dragCfg.onDragModifier.grid = jQuery.iDrag.snapToGrid;
}
if (elm.dragCfg.zIndex != false) {
jQuery.iDrag.helper.css('zIndex', elm.dragCfg.zIndex);
}
if (elm.dragCfg.opacity) {
jQuery.iDrag.helper.css('opacity', elm.dragCfg.opacity);
if (window.ActiveXObject) {
jQuery.iDrag.helper.css('filter', 'alpha(opacity=' + elm.dragCfg.opacity * 100 + ')');
}
}
if(elm.dragCfg.frameClass) {
jQuery.iDrag.helper.addClass(elm.dragCfg.frameClass);
jQuery.iDrag.helper.get(0).firstChild.style.display = 'none';
}
if (elm.dragCfg.onStart)
elm.dragCfg.onStart.apply(elm, [clonedEl, elm.dragCfg.oR.x, elm.dragCfg.oR.y]);
if (jQuery.iDrop && jQuery.iDrop.count > 0 ){
jQuery.iDrop.highlight(elm);
}
if (elm.dragCfg.ghosting == false) {
dEs.display = 'none';
}
return false;
},
getContainment : function(elm)
{
if (elm.dragCfg.containment.constructor == String) {
if (elm.dragCfg.containment == 'parent') {
elm.dragCfg.cont = jQuery.extend(
{x:0,y:0},
jQuery.iUtil.getSize(elm.parentNode)
);
var contBorders = jQuery.iUtil.getBorder(elm.parentNode, true);
elm.dragCfg.cont.w = elm.dragCfg.cont.wb - contBorders.l - contBorders.r;
elm.dragCfg.cont.h = elm.dragCfg.cont.hb - contBorders.t - contBorders.b;
} else if (elm.dragCfg.containment == 'document') {
var clnt = jQuery.iUtil.getClient();
elm.dragCfg.cont = {
x : 0,
y : 0,
w : clnt.w,
h : clnt.h
};
}
} else if (elm.dragCfg.containment.constructor == Array) {
elm.dragCfg.cont = {
x : parseInt(elm.dragCfg.containment[0])||0,
y : parseInt(elm.dragCfg.containment[1])||0,
w : parseInt(elm.dragCfg.containment[2])||0,
h : parseInt(elm.dragCfg.containment[3])||0
};
}
elm.dragCfg.cont.dx = elm.dragCfg.cont.x - elm.dragCfg.oC.x;
elm.dragCfg.cont.dy = elm.dragCfg.cont.y - elm.dragCfg.oC.y;
},
hidehelper : function(dragged)
{
if (dragged.dragCfg.insideParent || dragged.dragCfg.containment == 'parent') {
jQuery('body', document).append(jQuery.iDrag.helper.get(0));
}
jQuery.iDrag.helper.empty().hide().css('opacity', 1);
if (window.ActiveXObject) {
jQuery.iDrag.helper.css('filter', 'alpha(opacity=100)');
}
},
dragstop : function(e)
{
jQuery(document)
.unbind('mousemove', jQuery.iDrag.dragmove)
.unbind('mouseup', jQuery.iDrag.dragstop);
if (jQuery.iDrag.dragged == null) {
return;
}
var dragged = jQuery.iDrag.dragged;
jQuery.iDrag.dragged = null;
if (dragged.dragCfg.init == false) {
return false;
}
if (dragged.dragCfg.so == true) {
jQuery(dragged).css('position', dragged.dragCfg.oP);
}
var dEs = dragged.style;
if (dragged.si) {
jQuery.iDrag.helper.css('cursor', 'move');
}
if(dragged.dragCfg.frameClass) {
jQuery.iDrag.helper.removeClass(dragged.dragCfg.frameClass);
}
if (dragged.dragCfg.revert == false) {
if (dragged.dragCfg.fx > 0) {
if (!dragged.dragCfg.axis || dragged.dragCfg.axis == 'horizontally') {
var x = new jQuery.fx(dragged,{duration:dragged.dragCfg.fx}, 'left');
x.custom(dragged.dragCfg.oR.x,dragged.dragCfg.nRx);
}
if (!dragged.dragCfg.axis || dragged.dragCfg.axis == 'vertically') {
var y = new jQuery.fx(dragged,{duration:dragged.dragCfg.fx}, 'top');
y.custom(dragged.dragCfg.oR.y,dragged.dragCfg.nRy);
}
} else {
if (!dragged.dragCfg.axis || dragged.dragCfg.axis == 'horizontally')
dragged.style.left = dragged.dragCfg.nRx + 'px';
if (!dragged.dragCfg.axis || dragged.dragCfg.axis == 'vertically')
dragged.style.top = dragged.dragCfg.nRy + 'px';
}
jQuery.iDrag.hidehelper(dragged);
if (dragged.dragCfg.ghosting == false) {
jQuery(dragged).css('display', dragged.dragCfg.oD);
}
} else if (dragged.dragCfg.fx > 0) {
dragged.dragCfg.prot = true;
var dh = false;
if(jQuery.iDrop && jQuery.iSort && dragged.dragCfg.so) {
dh = jQuery.iUtil.getPosition(jQuery.iSort.helper.get(0));
}
jQuery.iDrag.helper.animate(
{
left : dh ? dh.x : dragged.dragCfg.oC.x,
top : dh ? dh.y : dragged.dragCfg.oC.y
},
dragged.dragCfg.fx,
function()
{
dragged.dragCfg.prot = false;
if (dragged.dragCfg.ghosting == false) {
dragged.style.display = dragged.dragCfg.oD;
}
jQuery.iDrag.hidehelper(dragged);
}
);
} else {
jQuery.iDrag.hidehelper(dragged);
if (dragged.dragCfg.ghosting == false) {
jQuery(dragged).css('display', dragged.dragCfg.oD);
}
}
if (jQuery.iDrop && jQuery.iDrop.count > 0 ){
jQuery.iDrop.checkdrop(dragged);
}
if (jQuery.iSort && dragged.dragCfg.so) {
jQuery.iSort.check(dragged);
}
if (dragged.dragCfg.onChange && (dragged.dragCfg.nRx != dragged.dragCfg.oR.x || dragged.dragCfg.nRy != dragged.dragCfg.oR.y)){
dragged.dragCfg.onChange.apply(dragged, dragged.dragCfg.lastSi||[0,0,dragged.dragCfg.nRx,dragged.dragCfg.nRy]);
}
if (dragged.dragCfg.onStop)
dragged.dragCfg.onStop.apply(dragged);
return false;
},
snapToGrid : function(x, y, dx, dy)
{
if (dx != 0)
dx = parseInt((dx + (this.dragCfg.gx * dx/Math.abs(dx))/2)/this.dragCfg.gx) * this.dragCfg.gx;
if (dy != 0)
dy = parseInt((dy + (this.dragCfg.gy * dy/Math.abs(dy))/2)/this.dragCfg.gy) * this.dragCfg.gy;
return {
dx : dx,
dy : dy,
x: 0,
y: 0
};
},
fitToContainer : function(x, y, dx, dy)
{
dx = Math.min(
Math.max(dx,this.dragCfg.cont.dx),
this.dragCfg.cont.w + this.dragCfg.cont.dx - this.dragCfg.oC.wb
);
dy = Math.min(
Math.max(dy,this.dragCfg.cont.dy),
this.dragCfg.cont.h + this.dragCfg.cont.dy - this.dragCfg.oC.hb
);
return {
dx : dx,
dy : dy,
x: 0,
y: 0
}
},
dragmove : function(e)
{
if (jQuery.iDrag.dragged == null || jQuery.iDrag.dragged.dragCfg.prot == true) {
return;
}
var dragged = jQuery.iDrag.dragged;
dragged.dragCfg.currentPointer = jQuery.iUtil.getPointer(e);
if (dragged.dragCfg.init == false) {
distance = Math.sqrt(Math.pow(dragged.dragCfg.pointer.x - dragged.dragCfg.currentPointer.x, 2) + Math.pow(dragged.dragCfg.pointer.y - dragged.dragCfg.currentPointer.y, 2));
if (distance < dragged.dragCfg.snapDistance){
return;
} else {
jQuery.iDrag.dragstart(e);
}
}
var dx = dragged.dragCfg.currentPointer.x - dragged.dragCfg.pointer.x;
var dy = dragged.dragCfg.currentPointer.y - dragged.dragCfg.pointer.y;
for (var i in dragged.dragCfg.onDragModifier) {
var newCoords = dragged.dragCfg.onDragModifier[i].apply(dragged, [dragged.dragCfg.oR.x + dx, dragged.dragCfg.oR.y + dy, dx, dy]);
if (newCoords && newCoords.constructor == Object) {
dx = i != 'user' ? newCoords.dx : (newCoords.x - dragged.dragCfg.oR.x);
dy = i != 'user' ? newCoords.dy : (newCoords.y - dragged.dragCfg.oR.y);
}
}
dragged.dragCfg.nx = dragged.dragCfg.oC.x + dx - dragged.dragCfg.diffX;
dragged.dragCfg.ny = dragged.dragCfg.oC.y + dy - dragged.dragCfg.diffY;
if (dragged.dragCfg.si && (dragged.dragCfg.onSlide || dragged.dragCfg.onChange)) {
jQuery.iSlider.onSlide(dragged, dragged.dragCfg.nx, dragged.dragCfg.ny);
}
if(dragged.dragCfg.onDrag)
dragged.dragCfg.onDrag.apply(dragged, [dragged.dragCfg.oR.x + dx, dragged.dragCfg.oR.y + dy]);
if (!dragged.dragCfg.axis || dragged.dragCfg.axis == 'horizontally') {
dragged.dragCfg.nRx = dragged.dragCfg.oR.x + dx;
jQuery.iDrag.helper.get(0).style.left = dragged.dragCfg.nx + 'px';
}
if (!dragged.dragCfg.axis || dragged.dragCfg.axis == 'vertically') {
dragged.dragCfg.nRy = dragged.dragCfg.oR.y + dy;
jQuery.iDrag.helper.get(0).style.top = dragged.dragCfg.ny + 'px';
}
if (jQuery.iDrop && jQuery.iDrop.count > 0 ){
jQuery.iDrop.checkhover(dragged);
}
return false;
},
build : function(o)
{
if (!jQuery.iDrag.helper) {
jQuery('body',document).append('<div id="dragHelper"></div>');
jQuery.iDrag.helper = jQuery('#dragHelper');
var el = jQuery.iDrag.helper.get(0);
var els = el.style;
els.position = 'absolute';
els.display = 'none';
els.cursor = 'move';
els.listStyle = 'none';
els.overflow = 'hidden';
if (window.ActiveXObject) {
el.unselectable = "on";
} else {
els.mozUserSelect = 'none';
els.userSelect = 'none';
els.KhtmlUserSelect = 'none';
}
}
if (!o) {
o = {};
}
return this.each(
function()
{
if (this.isDraggable || !jQuery.iUtil)
return;
if (window.ActiveXObject) {
this.onselectstart = function(){return false;};
this.ondragstart = function(){return false;};
}
var el = this;
var dhe = o.handle ? jQuery(this).find(o.handle) : jQuery(this);
if(jQuery.browser.msie) {
dhe.each(
function()
{
this.unselectable = "on";
}
);
} else {
dhe.css('-moz-user-select', 'none');
dhe.css('user-select', 'none');
dhe.css('-khtml-user-select', 'none');
}
this.dragCfg = {
dhe: dhe,
revert : o.revert ? true : false,
ghosting : o.ghosting ? true : false,
so : o.so ? o.so : false,
si : o.si ? o.si : false,
insideParent : o.insideParent ? o.insideParent : false,
zIndex : o.zIndex ? parseInt(o.zIndex)||0 : false,
opacity : o.opacity ? parseFloat(o.opacity) : false,
fx : parseInt(o.fx)||null,
hpc : o.hpc ? o.hpc : false,
onDragModifier : {},
pointer : {},
onStart : o.onStart && o.onStart.constructor == Function ? o.onStart : false,
onStop : o.onStop && o.onStop.constructor == Function ? o.onStop : false,
onChange : o.onChange && o.onChange.constructor == Function ? o.onChange : false,
axis : /vertically|horizontally/.test(o.axis) ? o.axis : false,
snapDistance : o.snapDistance ? parseInt(o.snapDistance)||0 : 0,
cursorAt: o.cursorAt ? o.cursorAt : false,
autoSize : o.autoSize ? true : false,
frameClass : o.frameClass || false
};
if (o.onDragModifier && o.onDragModifier.constructor == Function)
this.dragCfg.onDragModifier.user = o.onDragModifier;
if (o.onDrag && o.onDrag.constructor == Function)
this.dragCfg.onDrag = o.onDrag;
if (o.containment && ((o.containment.constructor == String && (o.containment == 'parent' || o.containment == 'document')) || (o.containment.constructor == Array && o.containment.length == 4) )) {
this.dragCfg.containment = o.containment;
}
if(o.fractions) {
this.dragCfg.fractions = o.fractions;
}
if(o.grid){
if(typeof o.grid == 'number'){
this.dragCfg.gx = parseInt(o.grid)||1;
this.dragCfg.gy = parseInt(o.grid)||1;
} else if (o.grid.length == 2) {
this.dragCfg.gx = parseInt(o.grid[0])||1;
this.dragCfg.gy = parseInt(o.grid[1])||1;
}
}
if (o.onSlide && o.onSlide.constructor == Function) {
this.dragCfg.onSlide = o.onSlide;
}
this.isDraggable = true;
dhe.each(
function(){
this.dragElem = el;
}
);
dhe.bind('mousedown', jQuery.iDrag.draginit);
}
)
}
};
/**
* Destroy an existing draggable on a collection of elements
*
* @name DraggableDestroy
* @descr Destroy a draggable
* @type jQuery
* @cat Plugins/Interface
* @example $('#drag2').DraggableDestroy();
*/
jQuery.fn.extend(
{
DraggableDestroy : jQuery.iDrag.destroy,
Draggable : jQuery.iDrag.build
}
);
/**
* Interface Elements for jQuery
* Droppables
*
* http://interface.eyecon.ro
*
* Copyright (c) 2006 Stefan Petre
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
*
*/
/**
* With the Draggables plugin, Droppable allows you to create drop zones for draggable elements.
*
* @name Droppable
* @cat Plugins/Interface
* @param Hash options A hash of options
* @option String accept The class name for draggables to get accepted by the droppable (mandatory)
* @option String activeclass When an acceptable draggable is moved, the droppable gets this class
* @option String hoverclass When an acceptable draggable is inside the droppable, the droppable gets
* this class
* @option String tolerance Choose from 'pointer', 'intersect', or 'fit'. The pointer options means
* that the pointer must be inside the droppable in order for the draggable
* to be dropped. The intersect option means that the draggable must intersect
* the droppable. The fit option means that the entire draggable must be
* inside the droppable.
* @option Function onDrop When an acceptable draggable is dropped on a droppable, this callback is
* called. It passes the draggable DOMElement as a parameter.
* @option Function onHover When an acceptable draggable is hovered over a droppable, this callback
* is called. It passes the draggable DOMElement as a parameter.
* @option Function onOut When an acceptable draggable leaves a droppable, this callback is called.
* It passes the draggable DOMElement as a parameter.
* @example $('#dropzone1').Droppable(
* {
* accept : 'dropaccept',
* activeclass: 'dropzoneactive',
* hoverclass: 'dropzonehover',
* ondrop: function (drag) {
* alert(this); //the droppable
* alert(drag); //the draggable
* },
* fit: true
* }
* )
*/
jQuery.iDrop = {
fit : function (zonex, zoney, zonew, zoneh)
{
return zonex <= jQuery.iDrag.dragged.dragCfg.nx &&
(zonex + zonew) >= (jQuery.iDrag.dragged.dragCfg.nx + jQuery.iDrag.dragged.dragCfg.oC.w) &&
zoney <= jQuery.iDrag.dragged.dragCfg.ny &&
(zoney + zoneh) >= (jQuery.iDrag.dragged.dragCfg.ny + jQuery.iDrag.dragged.dragCfg.oC.h) ? true :false;
},
intersect : function (zonex, zoney, zonew, zoneh)
{
return ! ( zonex > (jQuery.iDrag.dragged.dragCfg.nx + jQuery.iDrag.dragged.dragCfg.oC.w)
|| (zonex + zonew) < jQuery.iDrag.dragged.dragCfg.nx
|| zoney > (jQuery.iDrag.dragged.dragCfg.ny + jQuery.iDrag.dragged.dragCfg.oC.h)
|| (zoney + zoneh) < jQuery.iDrag.dragged.dragCfg.ny
) ? true :false;
},
pointer : function (zonex, zoney, zonew, zoneh)
{
return zonex < jQuery.iDrag.dragged.dragCfg.currentPointer.x
&& (zonex + zonew) > jQuery.iDrag.dragged.dragCfg.currentPointer.x
&& zoney < jQuery.iDrag.dragged.dragCfg.currentPointer.y
&& (zoney + zoneh) > jQuery.iDrag.dragged.dragCfg.currentPointer.y
? true :false;
},
overzone : false,
highlighted : {},
count : 0,
zones : {},
highlight : function (elm)
{
if (jQuery.iDrag.dragged == null) {
return;
}
var i;
jQuery.iDrop.highlighted = {};
var oneIsSortable = false;
for (i in jQuery.iDrop.zones) {
if (jQuery.iDrop.zones[i] != null) {
var iEL = jQuery.iDrop.zones[i].get(0);
if (jQuery(jQuery.iDrag.dragged).is('.' + iEL.dropCfg.a)) {
if (iEL.dropCfg.m == false) {
iEL.dropCfg.p = jQuery.extend(
jQuery.iUtil.getPositionLite(iEL),
jQuery.iUtil.getSizeLite(iEL)
);//jQuery.iUtil.getPos(iEL);
iEL.dropCfg.m = true;
}
if (iEL.dropCfg.ac) {
jQuery.iDrop.zones[i].addClass(iEL.dropCfg.ac);
}
jQuery.iDrop.highlighted[i] = jQuery.iDrop.zones[i];
//if (jQuery.iSort && jQuery.iDrag.dragged.dragCfg.so) {
if (jQuery.iSort && iEL.dropCfg.s && jQuery.iDrag.dragged.dragCfg.so) {
iEL.dropCfg.el = jQuery('.' + iEL.dropCfg.a, iEL);
elm.style.display = 'none';
jQuery.iSort.measure(iEL);
iEL.dropCfg.os = jQuery.iSort.serialize(jQuery.attr(iEL, 'id')).hash;
elm.style.display = elm.dragCfg.oD;
oneIsSortable = true;
}
if (iEL.dropCfg.onActivate) {
iEL.dropCfg.onActivate.apply(jQuery.iDrop.zones[i].get(0), [jQuery.iDrag.dragged]);
}
}
}
}
//if (jQuery.iSort && jQuery.iDrag.dragged.dragCfg.so) {
if (oneIsSortable) {
jQuery.iSort.start();
}
},
/**
* remeasure the droppable
*
* useful when the positions/dimensions for droppables
* are changed while dragging a element
*
* this works for sortables too but with a greate processor
* penality because remeasures each sort items too
*/
remeasure : function()
{
jQuery.iDrop.highlighted = {};
for (i in jQuery.iDrop.zones) {
if (jQuery.iDrop.zones[i] != null) {
var iEL = jQuery.iDrop.zones[i].get(0);
if (jQuery(jQuery.iDrag.dragged).is('.' + iEL.dropCfg.a)) {
iEL.dropCfg.p = jQuery.extend(
jQuery.iUtil.getPositionLite(iEL),
jQuery.iUtil.getSizeLite(iEL)
);
if (iEL.dropCfg.ac) {
jQuery.iDrop.zones[i].addClass(iEL.dropCfg.ac);
}
jQuery.iDrop.highlighted[i] = jQuery.iDrop.zones[i];
if (jQuery.iSort && iEL.dropCfg.s && jQuery.iDrag.dragged.dragCfg.so) {
iEL.dropCfg.el = jQuery('.' + iEL.dropCfg.a, iEL);
elm.style.display = 'none';
jQuery.iSort.measure(iEL);
elm.style.display = elm.dragCfg.oD;
}
}
}
}
},
checkhover : function (e)
{
if (jQuery.iDrag.dragged == null) {
return;
}
jQuery.iDrop.overzone = false;
var i;
var applyOnHover = false;
var hlt = 0;
for (i in jQuery.iDrop.highlighted)
{
var iEL = jQuery.iDrop.highlighted[i].get(0);
if (
jQuery.iDrop.overzone == false
&&
jQuery.iDrop[iEL.dropCfg.t](
iEL.dropCfg.p.x,
iEL.dropCfg.p.y,
iEL.dropCfg.p.wb,
iEL.dropCfg.p.hb
)
) {
if (iEL.dropCfg.hc && iEL.dropCfg.h == false) {
jQuery.iDrop.highlighted[i].addClass(iEL.dropCfg.hc);
}
//chec if onHover function has to be called
if (iEL.dropCfg.h == false &&iEL.dropCfg.onHover) {
applyOnHover = true;
}
iEL.dropCfg.h = true;
jQuery.iDrop.overzone = iEL;
//if(jQuery.iSort && jQuery.iDrag.dragged.dragCfg.so) {
if(jQuery.iSort && iEL.dropCfg.s && jQuery.iDrag.dragged.dragCfg.so) {
jQuery.iSort.helper.get(0).className = iEL.dropCfg.shc;
jQuery.iSort.checkhover(iEL);
}
hlt ++;
} else if(iEL.dropCfg.h == true) {
//onOut function
if (iEL.dropCfg.onOut) {
iEL.dropCfg.onOut.apply(iEL, [e, jQuery.iDrag.helper.get(0).firstChild, iEL.dropCfg.fx]);
}
if (iEL.dropCfg.hc) {
jQuery.iDrop.highlighted[i].removeClass(iEL.dropCfg.hc);
}
iEL.dropCfg.h = false;
}
}
if (jQuery.iSort && !jQuery.iDrop.overzone && jQuery.iDrag.dragged.so) {
jQuery.iSort.helper.get(0).style.display = 'none';
//jQuery('body').append(jQuery.iSort.helper.get(0));
}
//call onhover
if(applyOnHover) {
jQuery.iDrop.overzone.dropCfg.onHover.apply(jQuery.iDrop.overzone, [e, jQuery.iDrag.helper.get(0).firstChild]);
}
},
checkdrop : function (e)
{
var i;
for (i in jQuery.iDrop.highlighted) {
var iEL = jQuery.iDrop.highlighted[i].get(0);
if (iEL.dropCfg.ac) {
jQuery.iDrop.highlighted[i].removeClass(iEL.dropCfg.ac);
}
if (iEL.dropCfg.hc) {
jQuery.iDrop.highlighted[i].removeClass(iEL.dropCfg.hc);
}
if(iEL.dropCfg.s) {
jQuery.iSort.changed[jQuery.iSort.changed.length] = i;
}
if (iEL.dropCfg.onDrop && iEL.dropCfg.h == true) {
iEL.dropCfg.h = false;
iEL.dropCfg.onDrop.apply(iEL, [e, iEL.dropCfg.fx]);
}
iEL.dropCfg.m = false;
iEL.dropCfg.h = false;
}
jQuery.iDrop.highlighted = {};
},
destroy : function()
{
return this.each(
function()
{
if (this.isDroppable) {
if (this.dropCfg.s) {
id = jQuery.attr(this,'id');
jQuery.iSort.collected[id] = null;
jQuery('.' + this.dropCfg.a, this).DraggableDestroy();
}
jQuery.iDrop.zones['d' + this.idsa] = null;
this.isDroppable = false;
this.f = null;
}
}
);
},
build : function (o)
{
return this.each(
function()
{
if (this.isDroppable == true || !o.accept || !jQuery.iUtil || !jQuery.iDrag){
return;
}
this.dropCfg = {
a : o.accept,
ac: o.activeclass||false,
hc: o.hoverclass||false,
shc: o.helperclass||false,
onDrop: o.ondrop||o.onDrop||false,
onHover: o.onHover||o.onhover||false,
onOut: o.onOut||o.onout||false,
onActivate: o.onActivate||false,
t: o.tolerance && ( o.tolerance == 'fit' || o.tolerance == 'intersect') ? o.tolerance : 'pointer',
fx: o.fx ? o.fx : false,
m: false,
h: false
};
if (o.sortable == true && jQuery.iSort) {
id = jQuery.attr(this,'id');
jQuery.iSort.collected[id] = this.dropCfg.a;
this.dropCfg.s = true;
if(o.onChange) {
this.dropCfg.onChange = o.onChange;
this.dropCfg.os = jQuery.iSort.serialize(id).hash;
}
}
this.isDroppable = true;
this.idsa = parseInt(Math.random() * 10000);
jQuery.iDrop.zones['d' + this.idsa] = jQuery(this);
jQuery.iDrop.count ++;
}
);
}
};
/**
* Destroy an existing droppable on a collection of elements
*
* @name DroppableDestroy
* @descr Destroy a droppable
* @type jQuery
* @cat Plugins/Interface
* @example $('#drag2').DroppableDestroy();
*/
jQuery.fn.extend(
{
DroppableDestroy : jQuery.iDrop.destroy,
Droppable : jQuery.iDrop.build
}
);
/**
* Recalculate all Droppables
*
* @name $.recallDroppables
* @type jQuery
* @cat Plugins/Interface
* @example $.recallDroppable();
*/
jQuery.recallDroppables = jQuery.iDrop.remeasure;
/**
* Interface Elements for jQuery
* Sortables
*
* http://interface.eyecon.ro
*
* Copyright (c) 2006 Stefan Petre
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
*
*/
/**
* Allows you to resort elements within a container by dragging and dropping. Requires
* the Draggables and Droppables plugins. The container and each item inside the container
* must have an ID. Sortables are especially useful for lists.
*
* @see Plugins/Interface/Draggable
* @see Plugins/Interface/Droppable
* @author Stefan Petre
* @name Sortable
* @cat Plugins/Interface
* @param Hash options A hash of options
* @option String accept The class name for items inside the container (mandatory)
* @option String activeclass The class for the container when one of its items has started to move
* @option String hoverclass The class for the container when an acceptable item is inside it
* @option String helperclass The helper is used to point to the place where the item will be
* moved. This is the class for the helper.
* @option Float opacity Opacity (between 0 and 1) of the item while being dragged
* @option Boolean ghosting When true, the sortable is ghosted when dragged
* @option String tolerance Either 'pointer', 'intersect', or 'fit'. See Droppable for more details
* @option Boolean fit When true, sortable must be inside the container in order to drop
* @option Integer fx Duration for the effect applied to the sortable
* @option Function onchange Callback that gets called when the sortable list changed. It takes
* an array of serialized elements
* @option Boolean floats True if the sorted elements are floated
* @option String containment Use 'parent' to constrain the drag to the container
* @option String axis Use 'horizontally' or 'vertically' to constrain dragging to an axis
* @option String handle The jQuery selector that indicates the draggable handle
* @option DOMElement handle The node that indicates the draggable handle
* @option Function onHover Callback that is called when an acceptable item is dragged over the
* container. Gets the hovering DOMElement as a parameter
* @option Function onOut Callback that is called when an acceptable item leaves the container.
* Gets the leaving DOMElement as a parameter
* @option Object cursorAt The mouse cursor will be moved to the offset on the dragged item
* indicated by the object, which takes "top", "bottom", "left", and
* "right" keys
* @option Function onStart Callback function triggered when the dragging starts
* @option Function onStop Callback function triggered when the dragging stops
* @example $('ul').Sortable(
* {
* accept : 'sortableitem',
* activeclass : 'sortableactive',
* hoverclass : 'sortablehover',
* helperclass : 'sorthelper',
* opacity: 0.5,
* fit : false
* }
* )
*/
jQuery.iSort = {
changed : [],
collected : {},
helper : false,
inFrontOf: null,
start : function ()
{
if (jQuery.iDrag.dragged == null) {
return;
}
var shs, margins,c, cs;
jQuery.iSort.helper.get(0).className = jQuery.iDrag.dragged.dragCfg.hpc;
shs = jQuery.iSort.helper.get(0).style;
shs.display = 'block';
jQuery.iSort.helper.oC = jQuery.extend(
jQuery.iUtil.getPosition(jQuery.iSort.helper.get(0)),
jQuery.iUtil.getSize(jQuery.iSort.helper.get(0))
);
shs.width = jQuery.iDrag.dragged.dragCfg.oC.wb + 'px';
shs.height = jQuery.iDrag.dragged.dragCfg.oC.hb + 'px';
//shs.cssFloat = jQuery.iDrag.dragged.dragCfg.oF;
margins = jQuery.iUtil.getMargins(jQuery.iDrag.dragged);
shs.marginTop = margins.t;
shs.marginRight = margins.r;
shs.marginBottom = margins.b;
shs.marginLeft = margins.l;
if (jQuery.iDrag.dragged.dragCfg.ghosting == true) {
c = jQuery.iDrag.dragged.cloneNode(true);
cs = c.style;
cs.marginTop = '0px';
cs.marginRight = '0px';
cs.marginBottom = '0px';
cs.marginLeft = '0px';
cs.display = 'block';
jQuery.iSort.helper.empty().append(c);
}
jQuery(jQuery.iDrag.dragged).after(jQuery.iSort.helper.get(0));
jQuery.iDrag.dragged.style.display = 'none';
},
check : function (e)
{
if (!e.dragCfg.so && jQuery.iDrop.overzone.sortable) {
if (e.dragCfg.onStop)
e.dragCfg.onStop.apply(dragged);
jQuery(e).css('position', e.dragCfg.initialPosition || e.dragCfg.oP);
jQuery(e).DraggableDestroy();
jQuery(jQuery.iDrop.overzone).SortableAddItem(e);
}
jQuery.iSort.helper.removeClass(e.dragCfg.hpc).html(' ');
jQuery.iSort.inFrontOf = null;
var shs = jQuery.iSort.helper.get(0).style;
shs.display = 'none';
jQuery.iSort.helper.after(e);
if (e.dragCfg.fx > 0) {
jQuery(e).fadeIn(e.dragCfg.fx);
}
jQuery('body').append(jQuery.iSort.helper.get(0));
var ts = [];
var fnc = false;
for(var i=0; i<jQuery.iSort.changed.length; i++){
var iEL = jQuery.iDrop.zones[jQuery.iSort.changed[i]].get(0);
var id = jQuery.attr(iEL, 'id');
var ser = jQuery.iSort.serialize(id);
if (iEL.dropCfg.os != ser.hash) {
iEL.dropCfg.os = ser.hash;
if (fnc == false && iEL.dropCfg.onChange) {
fnc = iEL.dropCfg.onChange;
}
ser.id = id;
ts[ts.length] = ser;
}
}
jQuery.iSort.changed = [];
if (fnc != false && ts.length > 0) {
fnc(ts);
}
},
checkhover : function(e,o)
{
if (!jQuery.iDrag.dragged)
return;
var cur = false;
var i = 0;
if ( e.dropCfg.el.size() > 0) {
for (i = e.dropCfg.el.size(); i >0; i--) {
if (e.dropCfg.el.get(i-1) != jQuery.iDrag.dragged) {
if (!e.sortCfg.floats) {
if (
(e.dropCfg.el.get(i-1).pos.y + e.dropCfg.el.get(i-1).pos.hb/2) > jQuery.iDrag.dragged.dragCfg.ny
) {
cur = e.dropCfg.el.get(i-1);
} else {
break;
}
} else {
if (
(e.dropCfg.el.get(i-1).pos.x + e.dropCfg.el.get(i-1).pos.wb/2) > jQuery.iDrag.dragged.dragCfg.nx &&
(e.dropCfg.el.get(i-1).pos.y + e.dropCfg.el.get(i-1).pos.hb/2) > jQuery.iDrag.dragged.dragCfg.ny
) {
cur = e.dropCfg.el.get(i-1);
}
}
}
}
}
//helpos = jQuery.iUtil.getPos(jQuery.iSort.helper.get(0));
if (cur && jQuery.iSort.inFrontOf != cur) {
jQuery.iSort.inFrontOf = cur;
jQuery(cur).before(jQuery.iSort.helper.get(0));
} else if(!cur && (jQuery.iSort.inFrontOf != null || jQuery.iSort.helper.get(0).parentNode != e) ) {
jQuery.iSort.inFrontOf = null;
jQuery(e).append(jQuery.iSort.helper.get(0));
}
jQuery.iSort.helper.get(0).style.display = 'block';
},
measure : function (e)
{
if (jQuery.iDrag.dragged == null) {
return;
}
e.dropCfg.el.each (
function ()
{
this.pos = jQuery.extend(
jQuery.iUtil.getSizeLite(this),
jQuery.iUtil.getPositionLite(this)
);
}
);
},
serialize : function(s)
{
var i;
var h = '';
var o = {};
if (s) {
if (jQuery.iSort.collected[s] ) {
o[s] = [];
jQuery('#' + s + ' .' + jQuery.iSort.collected[s]).each(
function ()
{
if (h.length > 0) {
h += '&';
}
h += s + '[]=' + jQuery.attr(this,'id');
o[s][o[s].length] = jQuery.attr(this,'id');
}
);
} else {
for ( a in s) {
if (jQuery.iSort.collected[s[a]] ) {
o[s[a]] = [];
jQuery('#' + s[a] + ' .' + jQuery.iSort.collected[s[a]]).each(
function ()
{
if (h.length > 0) {
h += '&';
}
h += s[a] + '[]=' + jQuery.attr(this,'id');
o[s[a]][o[s[a]].length] = jQuery.attr(this,'id');
}
);
}
}
}
} else {
for ( i in jQuery.iSort.collected){
o[i] = [];
jQuery('#' + i + ' .' + jQuery.iSort.collected[i]).each(
function ()
{
if (h.length > 0) {
h += '&';
}
h += i + '[]=' + jQuery.attr(this,'id');
o[i][o[i].length] = jQuery.attr(this,'id');
}
);
}
}
return {hash:h, o:o};
},
addItem : function (e)
{
if ( !e.childNodes ) {
return;
}
return this.each(
function ()
{
if(!this.sortCfg || !jQuery(e).is('.' + this.sortCfg.accept))
jQuery(e).addClass(this.sortCfg.accept);
jQuery(e).Draggable(this.sortCfg.dragCfg);
}
);
},
destroy: function()
{
return this.each(
function()
{
jQuery('.' + this.sortCfg.accept).DraggableDestroy();
jQuery(this).DroppableDestroy();
this.sortCfg = null;
this.isSortable = null;
}
);
},
build : function (o)
{
if (o.accept && jQuery.iUtil && jQuery.iDrag && jQuery.iDrop) {
if (!jQuery.iSort.helper) {
jQuery('body',document).append('<div id="sortHelper"> </div>');
jQuery.iSort.helper = jQuery('#sortHelper');
jQuery.iSort.helper.get(0).style.display = 'none';
}
this.Droppable(
{
accept : o.accept,
activeclass : o.activeclass ? o.activeclass : false,
hoverclass : o.hoverclass ? o.hoverclass : false,
helperclass : o.helperclass ? o.helperclass : false,
/*onDrop: function (drag, fx)
{
jQuery.iSort.helper.after(drag);
if (fx > 0) {
jQuery(drag).fadeIn(fx);
}
},*/
onHover: o.onHover||o.onhover,
onOut: o.onOut||o.onout,
sortable : true,
onChange : o.onChange||o.onchange,
fx : o.fx ? o.fx : false,
ghosting : o.ghosting ? true : false,
tolerance: o.tolerance ? o.tolerance : 'intersect'
}
);
return this.each(
function()
{
var dragCfg = {
revert : o.revert? true : false,
zindex : 3000,
opacity : o.opacity ? parseFloat(o.opacity) : false,
hpc : o.helperclass ? o.helperclass : false,
fx : o.fx ? o.fx : false,
so : true,
ghosting : o.ghosting ? true : false,
handle: o.handle ? o.handle : null,
containment: o.containment ? o.containment : null,
onStart : o.onStart && o.onStart.constructor == Function ? o.onStart : false,
onDrag : o.onDrag && o.onDrag.constructor == Function ? o.onDrag : false,
onStop : o.onStop && o.onStop.constructor == Function ? o.onStop : false,
axis : /vertically|horizontally/.test(o.axis) ? o.axis : false,
snapDistance : o.snapDistance ? parseInt(o.snapDistance)||0 : false,
cursorAt: o.cursorAt ? o.cursorAt : false
};
jQuery('.' + o.accept, this).Draggable(dragCfg);
this.isSortable = true;
this.sortCfg = {
accept : o.accept,
revert : o.revert? true : false,
zindex : 3000,
opacity : o.opacity ? parseFloat(o.opacity) : false,
hpc : o.helperclass ? o.helperclass : false,
fx : o.fx ? o.fx : false,
so : true,
ghosting : o.ghosting ? true : false,
handle: o.handle ? o.handle : null,
containment: o.containment ? o.containment : null,
floats: o.floats ? true : false,
dragCfg : dragCfg
}
}
);
}
}
};
jQuery.fn.extend(
{
Sortable : jQuery.iSort.build,
/**
* A new item can be added to a sortable by adding it to the DOM and then adding it via
* SortableAddItem.
*
* @name SortableAddItem
* @param DOMElement elem A DOM Element to add to the sortable list
* @example $('#sortable1').append('<li id="newitem">new item</li>')
* .SortableAddItem($("#new_item")[0])
* @type jQuery
* @cat Plugins/Interface
*/
SortableAddItem : jQuery.iSort.addItem,
/**
* Destroy a sortable
*
* @name SortableDestroy
* @example $('#sortable1').SortableDestroy();
* @type jQuery
* @cat Plugins/Interface
*/
SortableDestroy: jQuery.iSort.destroy
}
);
/**
* This function returns the hash and an object (can be used as arguments for $.post) for every
* sortable in the page or specific sortables. The hash is based on the 'id' attributes of
* container and items.
*
* @params String sortable The id of the sortable to serialize
* @name $.SortSerialize
* @type String
* @cat Plugins/Interface
*/
jQuery.SortSerialize = jQuery.iSort.serialize;
!This is a test
!Do not use it for production at the moment.
!History
*2010.04.01 no joke
**Splitted InterfaceElements to 01iUtil, 02iDrag, 03iDrop, 04iSortable
**Drag and drop works fine in MainMenue now
***But: open the tiddler TOCTest
****Drag and Drop doesn't work there
***Keep TOCTest open
***Drag&Drop an element in MainMenue
***Save and reopen
***The menue is cloned -> doubles the structure.
!temporary replaced by
[[iUtil]]
[[iDrag]]
[[iDrop]]
[[iSortable]]
/*{{{*/
(function ($) {
var m = {
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'"' : '\\"',
'\\': '\\\\'
},
s = {
'array': function (x) {
var a = ['['], b, f, i, l = x.length, v;
for (i = 0; i < l; i += 1) {
v = x[i];
f = s[typeof v];
if (f) {
v = f(v);
if (typeof v == 'string') {
if (b) {
a[a.length] = ',';
}
a[a.length] = v;
b = true;
}
}
}
a[a.length] = ']';
return a.join('');
},
'boolean': function (x) {
return String(x);
},
'null': function (x) {
return "null";
},
'number': function (x) {
return isFinite(x) ? String(x) : 'null';
},
'object': function (x) {
if (x) {
if (x instanceof Array) {
return s.array(x);
}
var a = ['{'], b, f, i, v;
for (i in x) {
v = x[i];
f = s[typeof v];
if (f) {
v = f(v);
if (typeof v == 'string') {
if (b) {
a[a.length] = ',';
}
a.push(s.string(i), ':', v);
b = true;
}
}
}
a[a.length] = '}';
return a.join('');
}
return 'null';
},
'string': function (x) {
if (/["\\\x00-\x1f]/.test(x)) {
x = x.replace(/([\x00-\x1f\\"])/g, function(a, b) {
var c = m[b];
if (c) {
return c;
}
c = b.charCodeAt();
return '\\u00' +
Math.floor(c / 16).toString(16) +
(c % 16).toString(16);
});
}
return '"' + x + '"';
}
};
$.toJSON = function(v) {
var f = isNaN(v) ? s[typeof v] : s['number'];
if (f) return f(v);
};
$.parseJSON = function(v, safe) {
if (safe === undefined) safe = $.parseJSON.safe;
if (safe && !/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.test(v))
return undefined;
return eval('('+v+')');
};
$.parseJSON.safe = false;
})(jQuery);
/*}}}*/
/***
|''Name:''|LoadRemoteFileThroughProxy (previous LoadRemoteFileHijack)|
|''Description:''|When the TiddlyWiki file is located on the web (view over http) the content of [[SiteProxy]] tiddler is added in front of the file url. If [[SiteProxy]] does not exist "/proxy/" is added. |
|''Version:''|1.1.0|
|''Date:''|mar 17, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#LoadRemoteFileHijack|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
***/
//{{{
version.extensions.LoadRemoteFileThroughProxy = {
major: 1, minor: 1, revision: 0,
date: new Date("mar 17, 2007"),
source: "http://tiddlywiki.bidix.info/#LoadRemoteFileThroughProxy"};
if (!window.bidix) window.bidix = {}; // bidix namespace
if (!bidix.core) bidix.core = {};
bidix.core.loadRemoteFile = loadRemoteFile;
loadRemoteFile = function(url,callback,params)
{
if ((document.location.toString().substr(0,4) == "http") && (url.substr(0,4) == "http")){
url = store.getTiddlerText("SiteProxy", "/proxy/") + url;
}
return bidix.core.loadRemoteFile(url,callback,params);
}
//}}}
/***
|''Name:''|PasswordOptionPlugin|
|''Description:''|Extends TiddlyWiki options with non encrypted password option.|
|''Version:''|1.0.2|
|''Date:''|Apr 19, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#PasswordOptionPlugin|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0 (Beta 5)|
***/
//{{{
version.extensions.PasswordOptionPlugin = {
major: 1, minor: 0, revision: 2,
date: new Date("Apr 19, 2007"),
source: 'http://tiddlywiki.bidix.info/#PasswordOptionPlugin',
author: 'BidiX (BidiX (at) bidix (dot) info',
license: '[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D]]',
coreVersion: '2.2.0 (Beta 5)'
};
config.macros.option.passwordCheckboxLabel = "Save this password on this computer";
config.macros.option.passwordInputType = "password"; // password | text
setStylesheet(".pasOptionInput {width: 11em;}\n","passwordInputTypeStyle");
merge(config.macros.option.types, {
'pas': {
elementType: "input",
valueField: "value",
eventName: "onkeyup",
className: "pasOptionInput",
typeValue: config.macros.option.passwordInputType,
create: function(place,type,opt,className,desc) {
// password field
config.macros.option.genericCreate(place,'pas',opt,className,desc);
// checkbox linked with this password "save this password on this computer"
config.macros.option.genericCreate(place,'chk','chk'+opt,className,desc);
// text savePasswordCheckboxLabel
place.appendChild(document.createTextNode(config.macros.option.passwordCheckboxLabel));
},
onChange: config.macros.option.genericOnChange
}
});
merge(config.optionHandlers['chk'], {
get: function(name) {
// is there an option linked with this chk ?
var opt = name.substr(3);
if (config.options[opt])
saveOptionCookie(opt);
return config.options[name] ? "true" : "false";
}
});
merge(config.optionHandlers, {
'pas': {
get: function(name) {
if (config.options["chk"+name]) {
return encodeCookie(config.options[name].toString());
} else {
return "";
}
},
set: function(name,value) {config.options[name] = decodeCookie(value);}
}
});
// need to reload options to load passwordOptions
loadOptionsCookie();
/*
if (!config.options['pasPassword'])
config.options['pasPassword'] = '';
merge(config.optionsDesc,{
pasPassword: "Test password"
});
*/
//}}}
/***
|''Name''|SimpleSearchPlugin|
|''Description''|displays search results as a simple list of matching tiddlers|
|''Authors''|FND|
|''Version''|0.4.1|
|''Status''|stable|
|''Source''|http://devpad.tiddlyspot.com/#SimpleSearchPlugin|
|''CodeRepository''|http://svn.tiddlywiki.org/Trunk/contributors/FND/plugins/SimpleSearchPlugin.js|
|''License''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''Keywords''|search|
!Revision History
!!v0.2.0 (2008-08-18)
* initial release
!!v0.3.0 (2008-08-19)
* added Open All button (renders Classic Search option obsolete)
* sorting by relevance (title matches before content matches)
!!v0.4.0 (2008-08-26)
* added tag matching
!To Do
* tag matching optional
* animations for container creation and removal
* when clicking on search results, do not scroll to the respective tiddler (optional)
* use template for search results
!Code
***/
//{{{
if(!version.extensions.SimpleSearchPlugin) { //# ensure that the plugin is only installed once
version.extensions.SimpleSearchPlugin = { installed: true };
if(!config.extensions) { config.extensions = {}; }
config.extensions.SimpleSearchPlugin = {
heading: "Search Results",
containerId: "searchResults",
btnCloseLabel: "close",
btnCloseTooltip: "dismiss search results",
btnCloseId: "search_close",
btnOpenLabel: "Open all",
btnOpenTooltip: "open all search results",
btnOpenId: "search_open",
displayResults: function(matches, query) {
story.refreshAllTiddlers(true); // update highlighting within story tiddlers
var el = document.getElementById(this.containerId);
query = '"""' + query + '"""'; // prevent WikiLinks
if(el) {
removeChildren(el);
} else { //# fallback: use displayArea as parent
var container = document.getElementById("displayArea");
el = document.createElement("div");
el.id = this.containerId;
el = container.insertBefore(el, container.firstChild);
}
var msg = "!" + this.heading + "\n";
if(matches.length > 0) {
msg += "''" + config.macros.search.successMsg.format([matches.length.toString(), query]) + ":''\n";
this.results = [];
for(var i = 0 ; i < matches.length; i++) {
this.results.push(matches[i].title);
msg += "* [[" + matches[i].title + "]]\n";
}
} else {
msg += "''" + config.macros.search.failureMsg.format([query]) + "''"; // XXX: do not use bold here!?
}
createTiddlyButton(el, this.btnCloseLabel, this.btnCloseTooltip, config.extensions.SimpleSearchPlugin.closeResults, "button", this.btnCloseId);
wikify(msg, el);
if(matches.length > 0) { // XXX: redundant!?
createTiddlyButton(el, this.btnOpenLabel, this.btnOpenTooltip, config.extensions.SimpleSearchPlugin.openAll, "button", this.btnOpenId);
}
},
closeResults: function() {
var el = document.getElementById(config.extensions.SimpleSearchPlugin.containerId);
removeNode(el);
config.extensions.SimpleSearchPlugin.results = null;
highlightHack = null;
},
openAll: function(ev) {
story.displayTiddlers(null, config.extensions.SimpleSearchPlugin.results);
return false;
}
};
config.shadowTiddlers.StyleSheetSimpleSearch = "/*{{{*/\n" +
"#" + config.extensions.SimpleSearchPlugin.containerId + " {\n" +
"\toverflow: auto;\n" +
"\tpadding: 5px 1em 10px;\n" +
"\tbackground-color: [[ColorPalette::TertiaryPale]];\n" +
"}\n\n" +
"#" + config.extensions.SimpleSearchPlugin.containerId + " h1 {\n" +
"\tmargin-top: 0;\n" +
"\tborder: none;\n" +
"}\n\n" +
"#" + config.extensions.SimpleSearchPlugin.containerId + " ul {\n" +
"\tmargin: 0.5em;\n" +
"\tpadding-left: 1.5em;\n" +
"}\n\n" +
"#" + config.extensions.SimpleSearchPlugin.containerId + " .button {\n" +
"\tdisplay: block;\n" +
"\tborder-color: [[ColorPalette::TertiaryDark]];\n" +
"\tpadding: 5px;\n" +
"\tbackground-color: [[ColorPalette::TertiaryLight]];\n" +
"}\n\n" +
"#" + config.extensions.SimpleSearchPlugin.containerId + " .button:hover {\n" +
"\tborder-color: [[ColorPalette::SecondaryMid]];\n" +
"\tbackground-color: [[ColorPalette::SecondaryLight]];\n" +
"}\n\n" +
"#" + config.extensions.SimpleSearchPlugin.btnCloseId + " {\n" +
"\tfloat: right;\n" +
"\tmargin: -5px -1em 5px 5px;\n" +
"}\n\n" +
"#" + config.extensions.SimpleSearchPlugin.btnOpenId + " {\n" +
"\tfloat: left;\n" +
"\tmargin-top: 5px;\n" +
"}\n" +
"/*}}}*/";
store.addNotification("StyleSheetSimpleSearch", refreshStyles);
// override Story.search()
Story.prototype.search = function(text, useCaseSensitive, useRegExp) {
highlightHack = new RegExp(useRegExp ? text : text.escapeRegExp(), useCaseSensitive ? "mg" : "img");
var matches = store.search(highlightHack, null, "excludeSearch");
var q = useRegExp ? "/" : "'";
config.extensions.SimpleSearchPlugin.displayResults(matches, q + text + q);
};
// override TiddlyWiki.search() to sort by relevance
TiddlyWiki.prototype.search = function(searchRegExp, sortField, excludeTag, match) {
var candidates = this.reverseLookup("tags", excludeTag, !!match);
var primary = [];
var secondary = [];
var tertiary = [];
for(var t = 0; t < candidates.length; t++) {
if(candidates[t].title.search(searchRegExp) != -1) {
primary.push(candidates[t]);
} else if(candidates[t].tags.join(" ").search(searchRegExp) != -1) {
secondary.push(candidates[t]);
} else if(candidates[t].text.search(searchRegExp) != -1) {
tertiary.push(candidates[t]);
}
}
var results = primary.concat(secondary).concat(tertiary);
if(sortField) {
results.sort(function(a, b) {
return a[sortField] < b[sortField] ? -1 : (a[sortField] == b[sortField] ? 0 : +1);
});
}
return results;
};
} //# end of "install only once"
//}}}
{"format":{"name":"TiddlyDocsSpec","majorVersion":"0","minorVersion":"1"},"content":[{"title":"Terminology","children":[]},{"title":"History","children":[{"title":"University students appreciation and contributions","children":[]},{"title":"Growth","children":[]},{"title":"Creation","children":[{"title":"Internet structure","children":[]}]}]},{"title":"Todays Internet","children":[{"title":"FullCamelCaseTiddler","children":[]},{"title":"ICANN","children":[]},{"title":"Language","children":[]},{"title":"Internet and the workplace","children":[]},{"title":"The Internet viewed on mobile devices","children":[]}]},{"title":"Common uses","children":[{"title":"E-mail","children":[]},{"title":"The World Wide Web","children":[]},{"title":"Remote access","children":[]},{"title":"Collaboration","children":[]},{"title":"File sharing","children":[]},{"title":"Streaming media","children":[]},{"title":"Internet Telephony (VoIP)","children":[]}]},{"title":"Internet access","children":[]},{"title":"Social impact","children":[{"title":"Political organization and censorship","children":[]},{"title":"Leisure activities","children":[]}]}]}
window.activeDocument = 'TOC';
/***
|''Name''|TableOfContentPlugin|
|''Description''|macro provides a view on the table of content for the currently active document|
|''Authors''|Simon McManus|
|''Version''|0.1|
|''Status''|stable|
|''Source''|http://svn.tiddlywiki.org/Trunk/verticals/tiddlydocs/Plugins/TableOfContentPlugin.js|
|''CodeRepository''|http://svn.tiddlywiki.org/Trunk/verticals/tiddlydocs/Plugins/TableOfContentPlugin.js |
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''Requires''||
!Description
macro provides a view on the table of content for the currently active document
!Usage
{{{
<<TableOfContentPlugin>>
}}}
!Code
***/
//{{{
config.macros.TableOfContent={
'emptyDocumentSpecPrompt':'Click the "New Section" link above to add a section to the document. Document section titles can be dragged into the table of contents.',
'editTemplate':'TableOfContentPlugin##EditSectionTemplate',
'viewTemplate':DEFAULT_VIEW_TEMPLATE,
'dragToolTip': 'Drag and drop to re-arrange sections in the table of content.',
'deleteText': 'remove'
};
config.macros.TableOfContent.strip=function(s) {
return s.replace(/ /g,'');
};
config.macros.TableOfContent.handler=function(place,macroName,params,wikifier,paramString,tiddler){
config.shadowTiddlers["tdocsMenuStyles"] = store.getTiddlerText("TableOfContentPlugin##StyleSheet");
store.addNotification("tdocsMenuStyles", refreshStyles);
config.macros.TableOfContent.refresh(place,macroName,params,wikifier,paramString,tiddler);
};
config.macros.TableOfContent.specChanged = function() {
window.testSpec = config.macros.TableOfContent.buildSpec();
if(store.tiddlerExists(window.activeDocument)) {
var specTiddler = store.getTiddler(window.activeDocument);
var fields = merge(specTiddler.fields, config.defaultCustomFields);
} else {
var fields = config.defaultCustomFields;
}
var spec = { format: { name: 'TiddlyDocsSpec', majorVersion:'0', minorVersion:'1' }, content: window.testSpec};
store.saveTiddler(window.activeDocument, window.activeDocument, jQuery.toJSON(spec), null, null, "document", fields);
autoSaveChanges(true, window.activeDocument);
refreshAll();
};
config.macros.TableOfContent.renderSpec = function(specView, spec) {
window.ulCount=0;
window.liCount=0;
window.divCount=0;
window.sectionCount = 1;
jQuery(specView).empty();
if(spec[0]) {
config.macros.TableOfContent._renderSpec(specView, spec, []);
} else {
spec[0] = {};
spec[0].title = 'Empty Document';
spec[0].children = [];
config.macros.TableOfContent._renderSpec(specView, spec, []);
}
jQuery("#ul0").NestedSortable({
accept: 'toc-item',
noHoverClass: 'notHoverable',
noNestingClass: "no-nesting",
helperclass: 'helper',
onChange: function(serialized) {
config.macros.TableOfContent.specChanged();
},
autoScroll: true,
handle: '.toc-sort-handle',
onStart: function() {
story.refreshTiddler(this.id,1,true);
},
onStop: function() {
story.refreshTiddler(this.id,1,true);
}
});
jQuery(".sectionHeading").hover(
function() {
jQuery(this).parent().addClass("draggableHover");
jQuery(this).addClass("draggableChildHover");
},
function() {
jQuery(this).parent().removeClass("draggableHover");
jQuery(this).removeClass("draggableChildHover");
}
);
};
config.macros.TableOfContent.buildSpec = function() {
return config.macros.TableOfContent._buildSpec(jQuery(".specView > ul > li"));
};
config.macros.TableOfContent._buildSpec = function (liList) {
var spec = [];
liList.each(function() {
if(this.id != 'empty'){
var li=this;
var node = {
title: li.id
};
node.children = config.macros.TableOfContent._buildSpec(jQuery(li).children("ul").children("li"));
spec.push(node);
}
});
return spec;
};
config.macros.TableOfContent._renderSpec = function(specView, spec, label) {
var ul = createTiddlyElement(specView, "ul", "ul"+(window.ulCount++), "toc");
if(spec[0] && spec[0].title == 'Empty Document'){
var li = createTiddlyElement(ul, "li", 'empty', "clear-element toc-item no-nesting left ");
var sectionDiv = createTiddlyElement(li, "h5", null, null, config.macros.TableOfContent.emptyDocumentSpecPrompt);
return false;
}
var childCount=1;
label=label.concat([0])
jQuery.each(spec, function() {
label[label.length-1]++;
var li = createTiddlyElement(ul, "li", this.title, "clear-element toc-item left");
if(store.getTiddler(this.title)!=null){
if(store.getTiddler(this.title).fields.tt_status == "Complete")
var sectionClass = "completed";
}else{
var sectionClass = "";
}
var exists = (store.tiddlerExists(this.title)) ? "" : "sectionNotExist";
var sectionDiv = createTiddlyElement(li, "div", this.title+"_div", "sectionHeading toc-sort-handle "+sectionClass+" "+config.macros.TableOfContent.strip(this.title)+"_div "+exists);
sectionDiv.title = config.macros.TableOfContent.dragToolTip;
sectionDiv.onclick = function() {
if(config.options.chkOpenEditView == true)
story.displayTiddler(this.id, this.id.replace("_div", ""), config.macros.TableOfContent.editTemplate ,null, null, null, null,this);
else
story.displayTiddler(this.id, this.id.replace("_div", ""), config.macros.TableOfContent.viewTemplate,null, null, null, null,this);
}
jQuery(sectionDiv).hover(
function() {
jQuery(this).children().css('opacity', '1');
},
function() {
jQuery(this).children().css('opacity', '0');
}
);
createTiddlyText(sectionDiv, label.join(".")+" : "+this.title);
var a = createTiddlyElement(sectionDiv, "a", null, 'button deleteButton', config.macros.TableOfContent.deleteText);
jQuery(a).css('opacity', '0');
jQuery(a).click(function() {
jQuery(this).parent().parent().fadeOut('slow', function() {
jQuery(this).remove();
config.macros.TableOfContent.specChanged();
});
return false;
})
config.macros.TableOfContent._renderSpec(li, this.children, label);
});
};
config.macros.TableOfContent.refresh=function(place,macroName,params,wikifier,paramString,tiddler){
if(store.tiddlerExists(window.activeDocument)) {
var spec = jQuery.parseJSON(store.getTiddlerText(window.activeDocument)).content;
}
var specView = createTiddlyElement(place, "div", "", "specView");
config.macros.TableOfContent.renderSpec(specView, spec);
}
/***
!StyleSheet
#mainMenu {
width:25%;
margin-left:0.4%;
margin-top:0.5em;
text-align:left;
color:#333;
}
#displayArea {
margin-left:27%;
width:73%;
}
#tiddlerDisplay {
width:80%;
}
.current-nesting {
background-color: yellow;
}
.helper {
border:2px dashed #777777;
}
.deleteHelper {
background-color:#eee;
font-weight:bold;
border:1px solid red;
color:#222;
}
.sectionHeading {
width:100%;
}
.sort-handle-edit {
border:1px solid #C7C7C7;
background:white;
padding:1em;
margin-bottom:1em;
}
.sort-handle-edit .button {
border:1px solid #C7C7C7;
background:white !important;
color:black !important;
}
html body li.draggableHover {
color:[[ColorPalette::PrimaryDark]];
background:[[ColorPalette::SecondaryLight]];
border-color:[[ColorPalette::SecondaryMid]];
cursor:move;
}
html body div.draggableChildHover {
background:[[ColorPalette::SecondaryMid]];
cursor:move;
}
li.toc-item {
border:2px solid transparent;
border-right:0px solid;
list-style:none;
}
html body #backstageShow {
right:1em;
// display:none !important;
}
.secretBackstage {
background:#E6E6E6;
}
a.secretBackstage {
color:#E6E6E6;
}
#backstageArea, #backstageArea a {
background:#444444 none repeat scroll 0 0;
}
#backstageArea {
border-bottom:1px solid #777;
}
div.subtitle {
font-size:0.7em;
padding:0.5em;
}
div.title {
font-weight:none;
padding:0em 0.5em 0 0.2em;
color:#666;
}
#buttonHolder {
font-size:0.9em;
height:100%;
left:-3em;
position:relative;
top:-0.7em;
}
html body .btn span span {
background:#FFFFFF none repeat scroll 0 0;
border-bottom:1px solid #BBBBBB;
border-top:1px solid #CCCCCC;
border-width:1px 0;
color:#003366;
padding:3px 0.4em;
position:relative;
}
.completed {
border-right : 10px solid #248A22;
}
.incomplete {
border-right : 0px solid #d3bebe;
}
ul {
margin:0em;
}
.specView {
position:relative;
}
html body a.deleteButton {
cursor:pointer;
float:right;
position:absolute;
right:1em;
border:0em;
color:[[ColorPalette::Foreground]];
}
.specView h5.emptySpec {
position:relative;
left:4em;
}
.highlight {
background-color:red;
}
.sectionNotExist {
font-style:italic;
}
!(end of StyleSheet)
!EditSectionTemplate
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>
<div class='title' macro='droppableSection'></div>
<div class='taskControls' macro='tiddler TaskTiddlerControls'></div>
<div class='editor' macro='edit text'></div>
!(end of EditSectionTemplate)
***/
//}}}
/***
Description: Contains the stuff you need to use Tiddlyspot
Note, you also need UploadPlugin, PasswordOptionPlugin and LoadRemoteFileThroughProxy
from http://tiddlywiki.bidix.info for a complete working Tiddlyspot site.
***/
//{{{
// edit this if you are migrating sites or retrofitting an existing TW
config.tiddlyspotSiteId = 'dnd-menue';
// make it so you can by default see edit controls via http
config.options.chkHttpReadOnly = false;
window.readOnly = false; // make sure of it (for tw 2.2)
window.showBackstage = true; // show backstage too
// disable autosave in d3
if (window.location.protocol != "file:")
config.options.chkGTDLazyAutoSave = false;
// tweak shadow tiddlers to add upload button, password entry box etc
with (config.shadowTiddlers) {
SiteUrl = 'http://'+config.tiddlyspotSiteId+'.tiddlyspot.com';
SideBarOptions = SideBarOptions.replace(/(<<saveChanges>>)/,"$1<<tiddler TspotSidebar>>");
OptionsPanel = OptionsPanel.replace(/^/,"<<tiddler TspotOptions>>");
DefaultTiddlers = DefaultTiddlers.replace(/^/,"[[WelcomeToTiddlyspot]] ");
MainMenu = MainMenu.replace(/^/,"[[WelcomeToTiddlyspot]] ");
}
// create some shadow tiddler content
merge(config.shadowTiddlers,{
'TspotOptions':[
"tiddlyspot password:",
"<<option pasUploadPassword>>",
""
].join("\n"),
'TspotControls':[
"| tiddlyspot password:|<<option pasUploadPassword>>|",
"| site management:|<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . . " + config.tiddlyspotSiteId + ">>//(requires tiddlyspot password)//<br>[[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]], [[download (go offline)|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download]]|",
"| links:|[[tiddlyspot.com|http://tiddlyspot.com/]], [[FAQs|http://faq.tiddlyspot.com/]], [[blog|http://tiddlyspot.blogspot.com/]], email [[support|mailto:support@tiddlyspot.com]] & [[feedback|mailto:feedback@tiddlyspot.com]], [[donate|http://tiddlyspot.com/?page=donate]]|"
].join("\n"),
'WelcomeToTiddlyspot':[
"This document is a ~TiddlyWiki from tiddlyspot.com. A ~TiddlyWiki is an electronic notebook that is great for managing todo lists, personal information, and all sorts of things.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //What now?// @@ Before you can save any changes, you need to enter your password in the form below. Then configure privacy and other site settings at your [[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]] (your control panel username is //" + config.tiddlyspotSiteId + "//).",
"<<tiddler TspotControls>>",
"See also GettingStarted.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Working online// @@ You can edit this ~TiddlyWiki right now, and save your changes using the \"save to web\" button in the column on the right.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Working offline// @@ A fully functioning copy of this ~TiddlyWiki can be saved onto your hard drive or USB stick. You can make changes and save them locally without being connected to the Internet. When you're ready to sync up again, just click \"upload\" and your ~TiddlyWiki will be saved back to tiddlyspot.com.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Help!// @@ Find out more about ~TiddlyWiki at [[TiddlyWiki.com|http://tiddlywiki.com]]. Also visit [[TiddlyWiki.org|http://tiddlywiki.org]] for documentation on learning and using ~TiddlyWiki. New users are especially welcome on the [[TiddlyWiki mailing list|http://groups.google.com/group/TiddlyWiki]], which is an excellent place to ask questions and get help. If you have a tiddlyspot related problem email [[tiddlyspot support|mailto:support@tiddlyspot.com]].",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Enjoy :)// @@ We hope you like using your tiddlyspot.com site. Please email [[feedback@tiddlyspot.com|mailto:feedback@tiddlyspot.com]] with any comments or suggestions."
].join("\n"),
'TspotSidebar':[
"<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . . " + config.tiddlyspotSiteId + ">><html><a href='http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download' class='button'>download</a></html>"
].join("\n")
});
//}}}
| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |
| 22/03/2010 15:54:06 | YourName | [[/|http://dnd-menue.tiddlyspot.com/]] | [[store.cgi|http://dnd-menue.tiddlyspot.com/store.cgi]] | . | [[index.html | http://dnd-menue.tiddlyspot.com/index.html]] | . |
| 22/03/2010 16:00:14 | YourName | [[/|http://dnd-menue.tiddlyspot.com/]] | [[store.cgi|http://dnd-menue.tiddlyspot.com/store.cgi]] | . | [[index.html | http://dnd-menue.tiddlyspot.com/index.html]] | . |
| 01/04/2010 14:14:54 | PMario | [[dnd-menue(2).html|file:///C:/Downloads/dnd-menue(2).html]] | [[store.cgi|http://dnd-menue.tiddlyspot.com/store.cgi]] | . | [[index.html | http://dnd-menue.tiddlyspot.com/index.html]] | . | failed |
| 01/04/2010 14:30:16 | PMario | [[dnd-menue.html|file:///D:/TiddlyWikiMP/dnd-menue.html]] | [[store.cgi|http://dnd-menue.tiddlyspot.com/store.cgi]] | . | [[index.html | http://dnd-menue.tiddlyspot.com/index.html]] | . | failed |
| 01/04/2010 14:30:49 | PMario | [[dnd-menue.html|file:///D:/TiddlyWikiMP/dnd-menue.html]] | [[store.cgi|http://dnd-menue.tiddlyspot.com/store.cgi]] | . | [[index.html | http://dnd-menue.tiddlyspot.com/index.html]] | . |
/***
|''Name:''|UploadPlugin|
|''Description:''|Save to web a TiddlyWiki|
|''Version:''|4.1.3|
|''Date:''|Feb 24, 2008|
|''Source:''|http://tiddlywiki.bidix.info/#UploadPlugin|
|''Documentation:''|http://tiddlywiki.bidix.info/#UploadPluginDoc|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
|''Requires:''|PasswordOptionPlugin|
***/
//{{{
version.extensions.UploadPlugin = {
major: 4, minor: 1, revision: 3,
date: new Date("Feb 24, 2008"),
source: 'http://tiddlywiki.bidix.info/#UploadPlugin',
author: 'BidiX (BidiX (at) bidix (dot) info',
coreVersion: '2.2.0'
};
//
// Environment
//
if (!window.bidix) window.bidix = {}; // bidix namespace
bidix.debugMode = false; // true to activate both in Plugin and UploadService
//
// Upload Macro
//
config.macros.upload = {
// default values
defaultBackupDir: '', //no backup
defaultStoreScript: "store.php",
defaultToFilename: "index.html",
defaultUploadDir: ".",
authenticateUser: true // UploadService Authenticate User
};
config.macros.upload.label = {
promptOption: "Save and Upload this TiddlyWiki with UploadOptions",
promptParamMacro: "Save and Upload this TiddlyWiki in %0",
saveLabel: "save to web",
saveToDisk: "save to disk",
uploadLabel: "upload"
};
config.macros.upload.messages = {
noStoreUrl: "No store URL in parmeters or options",
usernameOrPasswordMissing: "Username or password missing"
};
config.macros.upload.handler = function(place,macroName,params) {
if (readOnly)
return;
var label;
if (document.location.toString().substr(0,4) == "http")
label = this.label.saveLabel;
else
label = this.label.uploadLabel;
var prompt;
if (params[0]) {
prompt = this.label.promptParamMacro.toString().format([this.destFile(params[0],
(params[1] ? params[1]:bidix.basename(window.location.toString())), params[3])]);
} else {
prompt = this.label.promptOption;
}
createTiddlyButton(place, label, prompt, function() {config.macros.upload.action(params);}, null, null, this.accessKey);
};
config.macros.upload.action = function(params)
{
// for missing macro parameter set value from options
if (!params) params = {};
var storeUrl = params[0] ? params[0] : config.options.txtUploadStoreUrl;
var toFilename = params[1] ? params[1] : config.options.txtUploadFilename;
var backupDir = params[2] ? params[2] : config.options.txtUploadBackupDir;
var uploadDir = params[3] ? params[3] : config.options.txtUploadDir;
var username = params[4] ? params[4] : config.options.txtUploadUserName;
var password = config.options.pasUploadPassword; // for security reason no password as macro parameter
// for still missing parameter set default value
if ((!storeUrl) && (document.location.toString().substr(0,4) == "http"))
storeUrl = bidix.dirname(document.location.toString())+'/'+config.macros.upload.defaultStoreScript;
if (storeUrl.substr(0,4) != "http")
storeUrl = bidix.dirname(document.location.toString()) +'/'+ storeUrl;
if (!toFilename)
toFilename = bidix.basename(window.location.toString());
if (!toFilename)
toFilename = config.macros.upload.defaultToFilename;
if (!uploadDir)
uploadDir = config.macros.upload.defaultUploadDir;
if (!backupDir)
backupDir = config.macros.upload.defaultBackupDir;
// report error if still missing
if (!storeUrl) {
alert(config.macros.upload.messages.noStoreUrl);
clearMessage();
return false;
}
if (config.macros.upload.authenticateUser && (!username || !password)) {
alert(config.macros.upload.messages.usernameOrPasswordMissing);
clearMessage();
return false;
}
bidix.upload.uploadChanges(false,null,storeUrl, toFilename, uploadDir, backupDir, username, password);
return false;
};
config.macros.upload.destFile = function(storeUrl, toFilename, uploadDir)
{
if (!storeUrl)
return null;
var dest = bidix.dirname(storeUrl);
if (uploadDir && uploadDir != '.')
dest = dest + '/' + uploadDir;
dest = dest + '/' + toFilename;
return dest;
};
//
// uploadOptions Macro
//
config.macros.uploadOptions = {
handler: function(place,macroName,params) {
var wizard = new Wizard();
wizard.createWizard(place,this.wizardTitle);
wizard.addStep(this.step1Title,this.step1Html);
var markList = wizard.getElement("markList");
var listWrapper = document.createElement("div");
markList.parentNode.insertBefore(listWrapper,markList);
wizard.setValue("listWrapper",listWrapper);
this.refreshOptions(listWrapper,false);
var uploadCaption;
if (document.location.toString().substr(0,4) == "http")
uploadCaption = config.macros.upload.label.saveLabel;
else
uploadCaption = config.macros.upload.label.uploadLabel;
wizard.setButtons([
{caption: uploadCaption, tooltip: config.macros.upload.label.promptOption,
onClick: config.macros.upload.action},
{caption: this.cancelButton, tooltip: this.cancelButtonPrompt, onClick: this.onCancel}
]);
},
options: [
"txtUploadUserName",
"pasUploadPassword",
"txtUploadStoreUrl",
"txtUploadDir",
"txtUploadFilename",
"txtUploadBackupDir",
"chkUploadLog",
"txtUploadLogMaxLine"
],
refreshOptions: function(listWrapper) {
var opts = [];
for(i=0; i<this.options.length; i++) {
var opt = {};
opts.push();
opt.option = "";
n = this.options[i];
opt.name = n;
opt.lowlight = !config.optionsDesc[n];
opt.description = opt.lowlight ? this.unknownDescription : config.optionsDesc[n];
opts.push(opt);
}
var listview = ListView.create(listWrapper,opts,this.listViewTemplate);
for(n=0; n<opts.length; n++) {
var type = opts[n].name.substr(0,3);
var h = config.macros.option.types[type];
if (h && h.create) {
h.create(opts[n].colElements['option'],type,opts[n].name,opts[n].name,"no");
}
}
},
onCancel: function(e)
{
backstage.switchTab(null);
return false;
},
wizardTitle: "Upload with options",
step1Title: "These options are saved in cookies in your browser",
step1Html: "<input type='hidden' name='markList'></input><br>",
cancelButton: "Cancel",
cancelButtonPrompt: "Cancel prompt",
listViewTemplate: {
columns: [
{name: 'Description', field: 'description', title: "Description", type: 'WikiText'},
{name: 'Option', field: 'option', title: "Option", type: 'String'},
{name: 'Name', field: 'name', title: "Name", type: 'String'}
],
rowClasses: [
{className: 'lowlight', field: 'lowlight'}
]}
};
//
// upload functions
//
if (!bidix.upload) bidix.upload = {};
if (!bidix.upload.messages) bidix.upload.messages = {
//from saving
invalidFileError: "The original file '%0' does not appear to be a valid TiddlyWiki",
backupSaved: "Backup saved",
backupFailed: "Failed to upload backup file",
rssSaved: "RSS feed uploaded",
rssFailed: "Failed to upload RSS feed file",
emptySaved: "Empty template uploaded",
emptyFailed: "Failed to upload empty template file",
mainSaved: "Main TiddlyWiki file uploaded",
mainFailed: "Failed to upload main TiddlyWiki file. Your changes have not been saved",
//specific upload
loadOriginalHttpPostError: "Can't get original file",
aboutToSaveOnHttpPost: 'About to upload on %0 ...',
storePhpNotFound: "The store script '%0' was not found."
};
bidix.upload.uploadChanges = function(onlyIfDirty,tiddlers,storeUrl,toFilename,uploadDir,backupDir,username,password)
{
var callback = function(status,uploadParams,original,url,xhr) {
if (!status) {
displayMessage(bidix.upload.messages.loadOriginalHttpPostError);
return;
}
if (bidix.debugMode)
alert(original.substr(0,500)+"\n...");
// Locate the storeArea div's
var posDiv = locateStoreArea(original);
if((posDiv[0] == -1) || (posDiv[1] == -1)) {
alert(config.messages.invalidFileError.format([localPath]));
return;
}
bidix.upload.uploadRss(uploadParams,original,posDiv);
};
if(onlyIfDirty && !store.isDirty())
return;
clearMessage();
// save on localdisk ?
if (document.location.toString().substr(0,4) == "file") {
var path = document.location.toString();
var localPath = getLocalPath(path);
saveChanges();
}
// get original
var uploadParams = new Array(storeUrl,toFilename,uploadDir,backupDir,username,password);
var originalPath = document.location.toString();
// If url is a directory : add index.html
if (originalPath.charAt(originalPath.length-1) == "/")
originalPath = originalPath + "index.html";
var dest = config.macros.upload.destFile(storeUrl,toFilename,uploadDir);
var log = new bidix.UploadLog();
log.startUpload(storeUrl, dest, uploadDir, backupDir);
displayMessage(bidix.upload.messages.aboutToSaveOnHttpPost.format([dest]));
if (bidix.debugMode)
alert("about to execute Http - GET on "+originalPath);
var r = doHttp("GET",originalPath,null,null,username,password,callback,uploadParams,null);
if (typeof r == "string")
displayMessage(r);
return r;
};
bidix.upload.uploadRss = function(uploadParams,original,posDiv)
{
var callback = function(status,params,responseText,url,xhr) {
if(status) {
var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
displayMessage(bidix.upload.messages.rssSaved,bidix.dirname(url)+'/'+destfile);
bidix.upload.uploadMain(params[0],params[1],params[2]);
} else {
displayMessage(bidix.upload.messages.rssFailed);
}
};
// do uploadRss
if(config.options.chkGenerateAnRssFeed) {
var rssPath = uploadParams[1].substr(0,uploadParams[1].lastIndexOf(".")) + ".xml";
var rssUploadParams = new Array(uploadParams[0],rssPath,uploadParams[2],'',uploadParams[4],uploadParams[5]);
var rssString = generateRss();
// no UnicodeToUTF8 conversion needed when location is "file" !!!
if (document.location.toString().substr(0,4) != "file")
rssString = convertUnicodeToUTF8(rssString);
bidix.upload.httpUpload(rssUploadParams,rssString,callback,Array(uploadParams,original,posDiv));
} else {
bidix.upload.uploadMain(uploadParams,original,posDiv);
}
};
bidix.upload.uploadMain = function(uploadParams,original,posDiv)
{
var callback = function(status,params,responseText,url,xhr) {
var log = new bidix.UploadLog();
if(status) {
// if backupDir specified
if ((params[3]) && (responseText.indexOf("backupfile:") > -1)) {
var backupfile = responseText.substring(responseText.indexOf("backupfile:")+11,responseText.indexOf("\n", responseText.indexOf("backupfile:")));
displayMessage(bidix.upload.messages.backupSaved,bidix.dirname(url)+'/'+backupfile);
}
var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
displayMessage(bidix.upload.messages.mainSaved,bidix.dirname(url)+'/'+destfile);
store.setDirty(false);
log.endUpload("ok");
} else {
alert(bidix.upload.messages.mainFailed);
displayMessage(bidix.upload.messages.mainFailed);
log.endUpload("failed");
}
};
// do uploadMain
var revised = bidix.upload.updateOriginal(original,posDiv);
bidix.upload.httpUpload(uploadParams,revised,callback,uploadParams);
};
bidix.upload.httpUpload = function(uploadParams,data,callback,params)
{
var localCallback = function(status,params,responseText,url,xhr) {
url = (url.indexOf("nocache=") < 0 ? url : url.substring(0,url.indexOf("nocache=")-1));
if (xhr.status == 404)
alert(bidix.upload.messages.storePhpNotFound.format([url]));
if ((bidix.debugMode) || (responseText.indexOf("Debug mode") >= 0 )) {
alert(responseText);
if (responseText.indexOf("Debug mode") >= 0 )
responseText = responseText.substring(responseText.indexOf("\n\n")+2);
} else if (responseText.charAt(0) != '0')
alert(responseText);
if (responseText.charAt(0) != '0')
status = null;
callback(status,params,responseText,url,xhr);
};
// do httpUpload
var boundary = "---------------------------"+"AaB03x";
var uploadFormName = "UploadPlugin";
// compose headers data
var sheader = "";
sheader += "--" + boundary + "\r\nContent-disposition: form-data; name=\"";
sheader += uploadFormName +"\"\r\n\r\n";
sheader += "backupDir="+uploadParams[3] +
";user=" + uploadParams[4] +
";password=" + uploadParams[5] +
";uploaddir=" + uploadParams[2];
if (bidix.debugMode)
sheader += ";debug=1";
sheader += ";;\r\n";
sheader += "\r\n" + "--" + boundary + "\r\n";
sheader += "Content-disposition: form-data; name=\"userfile\"; filename=\""+uploadParams[1]+"\"\r\n";
sheader += "Content-Type: text/html;charset=UTF-8" + "\r\n";
sheader += "Content-Length: " + data.length + "\r\n\r\n";
// compose trailer data
var strailer = new String();
strailer = "\r\n--" + boundary + "--\r\n";
data = sheader + data + strailer;
if (bidix.debugMode) alert("about to execute Http - POST on "+uploadParams[0]+"\n with \n"+data.substr(0,500)+ " ... ");
var r = doHttp("POST",uploadParams[0],data,"multipart/form-data; ;charset=UTF-8; boundary="+boundary,uploadParams[4],uploadParams[5],localCallback,params,null);
if (typeof r == "string")
displayMessage(r);
return r;
};
// same as Saving's updateOriginal but without convertUnicodeToUTF8 calls
bidix.upload.updateOriginal = function(original, posDiv)
{
if (!posDiv)
posDiv = locateStoreArea(original);
if((posDiv[0] == -1) || (posDiv[1] == -1)) {
alert(config.messages.invalidFileError.format([localPath]));
return;
}
var revised = original.substr(0,posDiv[0] + startSaveArea.length) + "\n" +
store.allTiddlersAsHtml() + "\n" +
original.substr(posDiv[1]);
var newSiteTitle = getPageTitle().htmlEncode();
revised = revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");
revised = updateMarkupBlock(revised,"PRE-HEAD","MarkupPreHead");
revised = updateMarkupBlock(revised,"POST-HEAD","MarkupPostHead");
revised = updateMarkupBlock(revised,"PRE-BODY","MarkupPreBody");
revised = updateMarkupBlock(revised,"POST-SCRIPT","MarkupPostBody");
return revised;
};
//
// UploadLog
//
// config.options.chkUploadLog :
// false : no logging
// true : logging
// config.options.txtUploadLogMaxLine :
// -1 : no limit
// 0 : no Log lines but UploadLog is still in place
// n : the last n lines are only kept
// NaN : no limit (-1)
bidix.UploadLog = function() {
if (!config.options.chkUploadLog)
return; // this.tiddler = null
this.tiddler = store.getTiddler("UploadLog");
if (!this.tiddler) {
this.tiddler = new Tiddler();
this.tiddler.title = "UploadLog";
this.tiddler.text = "| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |";
this.tiddler.created = new Date();
this.tiddler.modifier = config.options.txtUserName;
this.tiddler.modified = new Date();
store.addTiddler(this.tiddler);
}
return this;
};
bidix.UploadLog.prototype.addText = function(text) {
if (!this.tiddler)
return;
// retrieve maxLine when we need it
var maxLine = parseInt(config.options.txtUploadLogMaxLine,10);
if (isNaN(maxLine))
maxLine = -1;
// add text
if (maxLine != 0)
this.tiddler.text = this.tiddler.text + text;
// Trunck to maxLine
if (maxLine >= 0) {
var textArray = this.tiddler.text.split('\n');
if (textArray.length > maxLine + 1)
textArray.splice(1,textArray.length-1-maxLine);
this.tiddler.text = textArray.join('\n');
}
// update tiddler fields
this.tiddler.modifier = config.options.txtUserName;
this.tiddler.modified = new Date();
store.addTiddler(this.tiddler);
// refresh and notifiy for immediate update
story.refreshTiddler(this.tiddler.title);
store.notify(this.tiddler.title, true);
};
bidix.UploadLog.prototype.startUpload = function(storeUrl, toFilename, uploadDir, backupDir) {
if (!this.tiddler)
return;
var now = new Date();
var text = "\n| ";
var filename = bidix.basename(document.location.toString());
if (!filename) filename = '/';
text += now.formatString("0DD/0MM/YYYY 0hh:0mm:0ss") +" | ";
text += config.options.txtUserName + " | ";
text += "[["+filename+"|"+location + "]] |";
text += " [[" + bidix.basename(storeUrl) + "|" + storeUrl + "]] | ";
text += uploadDir + " | ";
text += "[[" + bidix.basename(toFilename) + " | " +toFilename + "]] | ";
text += backupDir + " |";
this.addText(text);
};
bidix.UploadLog.prototype.endUpload = function(status) {
if (!this.tiddler)
return;
this.addText(" "+status+" |");
};
//
// Utilities
//
bidix.checkPlugin = function(plugin, major, minor, revision) {
var ext = version.extensions[plugin];
if (!
(ext &&
((ext.major > major) ||
((ext.major == major) && (ext.minor > minor)) ||
((ext.major == major) && (ext.minor == minor) && (ext.revision >= revision))))) {
// write error in PluginManager
if (pluginInfo)
pluginInfo.log.push("Requires " + plugin + " " + major + "." + minor + "." + revision);
eval(plugin); // generate an error : "Error: ReferenceError: xxxx is not defined"
}
};
bidix.dirname = function(filePath) {
if (!filePath)
return;
var lastpos;
if ((lastpos = filePath.lastIndexOf("/")) != -1) {
return filePath.substring(0, lastpos);
} else {
return filePath.substring(0, filePath.lastIndexOf("\\"));
}
};
bidix.basename = function(filePath) {
if (!filePath)
return;
var lastpos;
if ((lastpos = filePath.lastIndexOf("#")) != -1)
filePath = filePath.substring(0, lastpos);
if ((lastpos = filePath.lastIndexOf("/")) != -1) {
return filePath.substring(lastpos + 1);
} else
return filePath.substring(filePath.lastIndexOf("\\")+1);
};
bidix.initOption = function(name,value) {
if (!config.options[name])
config.options[name] = value;
};
//
// Initializations
//
// require PasswordOptionPlugin 1.0.1 or better
bidix.checkPlugin("PasswordOptionPlugin", 1, 0, 1);
// styleSheet
setStylesheet('.txtUploadStoreUrl, .txtUploadBackupDir, .txtUploadDir {width: 22em;}',"uploadPluginStyles");
//optionsDesc
merge(config.optionsDesc,{
txtUploadStoreUrl: "Url of the UploadService script (default: store.php)",
txtUploadFilename: "Filename of the uploaded file (default: in index.html)",
txtUploadDir: "Relative Directory where to store the file (default: . (downloadService directory))",
txtUploadBackupDir: "Relative Directory where to backup the file. If empty no backup. (default: ''(empty))",
txtUploadUserName: "Upload Username",
pasUploadPassword: "Upload Password",
chkUploadLog: "do Logging in UploadLog (default: true)",
txtUploadLogMaxLine: "Maximum of lines in UploadLog (default: 10)"
});
// Options Initializations
bidix.initOption('txtUploadStoreUrl','');
bidix.initOption('txtUploadFilename','');
bidix.initOption('txtUploadDir','');
bidix.initOption('txtUploadBackupDir','');
bidix.initOption('txtUploadUserName','');
bidix.initOption('pasUploadPassword','');
bidix.initOption('chkUploadLog',true);
bidix.initOption('txtUploadLogMaxLine','10');
// Backstage
merge(config.tasks,{
uploadOptions: {text: "upload", tooltip: "Change UploadOptions and Upload", content: '<<uploadOptions>>'}
});
config.backstageTasks.push("uploadOptions");
//}}}
/***
|''Name:''|ValueSwitcherPlugin|
|''Description:''|Gather values from a definition tiddler, and present the user with a UI for setting a value from those available options as an extended field |
|''Version:''|0.2.2|
|''Date:''|13 Mar, 2010|
|''Source:''|http://www.hawksworx.com/playground/TeamTasks/#ValueTogglerPlugin|
|''Author:''|PhilHawksworth (phawksworth (at) gmail (dot) com)|
|''License:''|[[BSD open source license]]|
|''CoreVersion:''|2.5|
***/
//{{{
(function($) {
// Ensure that this Plugin is only installed once.
if(!version.extensions.ValueSwitcher)
{
version.extensions.ValueSwitcher = {installed:true};
config.macros.ValueSwitcher = {
fieldPrefix: "tt_",
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var taskTiddler = story.findContainingTiddler(place);
if(!(taskTiddler && taskTiddler != 'undefined')) {
return;
}
var params = paramString.parseParams("anon",null,true,false,false);
var control = getParam(params,"type",null);
var id = taskTiddler.id;
var title = id.substr(7);
var tiddler = store.getTiddler(title);
var field = getParam(params,"field", null);
var containerEl = createTiddlyElement(place,"div",null,"fieldContainer",null);
// build a drop down control
if (control == 'dropdown') {
config.macros.ValueSwitcher.makeDropdown(containerEl, field, params, title, tiddler);
} else if (control == 'text' || control == 'textarea') {
var autoComplete = (getParam(params,"autoComplete"));
// var autoComplete = (autoCompleteParam && autoCompleteParam.trim().length);
config.macros.ValueSwitcher.makeText
(containerEl, field, title, tiddler, control=='textarea', autoComplete);
} else {
displayMessage("Control type '" + control + "' unknown");
}
},
makeDropdown: function(fieldContainer, field, params, title, tiddler) {
var valueSrc = getParam(params,"valuesSource", null);
if(!valueSrc) {
displayMessage("No definition tiddler defined for a TeamTasks dropdown.");
return;
}
if (!field) { // revert to older convention of using name of values source
field = config.macros.ValueSwitcher.fieldPrefix +
valueSrc.toLowerCase().substr(0,valueSrc.length-11);
}
var values = this.getDefValues(valueSrc);
var selected = field + '::' + store.getValue(tiddler,field);
var options = [];
options.push({'caption': 'Please select', 'name': null});
for (var i=0; i < values.length; i++) {
options.push({'caption': values[i], 'name': field + '::' + values[i]});
}
var control = createTiddlyDropDown(fieldContainer,this.setDropDownMetaData,options,selected);
var note = getParam(params,"note", null);
if (note && note=="text"||note=="textarea") {
// params.field = field + "_note";
var control = config.macros.ValueSwitcher.makeText(fieldContainer, field+"_note", title, tiddler, note=="textarea");
control.className += " fieldNote";
}
return control;
},
makeText: function(fieldContainer, field, title, tiddler, isTextArea, autoComplete) {
if(!field) {
displayMessage("No field defined for a TeamTasks free text box.");
return;
}
// var ttname = fieldPrefix + tiddler
var text = store.getValue(tiddler,field);
if(!text) text = "";
var control;
if (isTextArea) {
control = createTiddlyElement(fieldContainer,"textarea",null,null,null,{rows: 4, cols: 40, ttname:field});
control.innerHTML = text;
} else {
control = createTiddlyElement(fieldContainer,"input",null,null,null,{"value":text, "type":"text", "ttname":field});
if (autoComplete) {
// NOTE matchContains doesn't seem to work, not sure why
// var autoCompleteOptions = (autoCompleteParam=="anywhere" ? {matchContains:true} : {});
jQuery(control).autocompleteArray
(config.macros.ValueSwitcher.findAllTextValues(field), "anywhere");
}
}
control.onblur = config.macros.ValueSwitcher.changeText;
return control;
},
// this happens each time the list is shown - we could improve performance
// by maintaining a cached version of the list
findAllTextValues: function(ttField) {
var valuesHash = {}, allValues = [];
var tasks = store.getTaggedTiddlers("task");
for (var i=0; i<tasks.length; i++) {
var value = tasks[i].fields[ttField];
if (value && value.trim().length) valuesHash[value] = true;
}
for (var value in valuesHash) { allValues.push(value); }
return allValues;
},
//Get definition values for populating UI from definition tiddlers.
getDefValues: function(src) {
var text = store.getTiddlerText(src).split('\n');
var output = [];
for(var t=0; t<text.length; t++) {
//support calling the old TaskViewBuilder macro to list the tasks here too.
var blob = wikifyStatic(text[t],null,tiddler,null);
var linktitle = /tiddlylink="[^"]*"/mg;
var titles = blob.match(linktitle);
if(titles) {
for(var n=0; n<titles.length; n++) {
output.push(titles[n].replace(/tiddlylink="([^"]*)"/,'$1'));
}
}
else {
output.push(text[t]);
}
}
return (output);
},
// Ensure that changes to a dropdown field are stored as an extended field.
setDropDownMetaData: function(ev) {
var e = ev ? ev : window.event;
var taskTiddler = story.findContainingTiddler(this);
if(taskTiddler && taskTiddler != undefined) {
var title = taskTiddler.getAttribute('tiddler');
var tiddler = store.getTiddler(title);
var option = this[this.selectedIndex].value.split('::');
var extField = option[0];
var extFieldVal = option[1];
store.setValue(tiddler,extField,extFieldVal);
}
},
// Ensure that changes to a free text field are stored as an extended field.
changeText: function(ev) {
var e = ev ? ev : window.event;
var ttField = this.getAttribute('ttname');
var value = this.value;
if(ttField) {
var t = story.findContainingTiddler(this);
var title = t.getAttribute('tiddler');
var tiddler = store.getTiddler(title);
store.setValue(tiddler,ttField,value);
refreshAll();
}
return false;
}
};
}
})(jQuery);
//}}}
/**
*
* Nested Sortable Plugin for jQuery/Interface.
*
* Version 1.0.1
*
*Change Log:
* 1.0
* Initial Release
* 1.0.1
* Added noNestingClass option to prevent nesting in some elements.
*
*
* Copyright (c) 2007 Bernardo de Padua dos Santos
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
* http://code.google.com/p/nestedsortables/
*
*/
/*{{{*/
jQuery.iNestedSortable = {
/*
* Called when an item is being dragged. Puts the sort helper in the proper place.
* The "e" argument passed in is the Sortable element.
*/
checkHover : function(e,o) {
if(e.isNestedSortable){
//A brand new NestedSortable hovering check
jQuery.iNestedSortable.scroll(e);
return jQuery.iNestedSortable.newCheckHover(e);
} else {
//The legacy hovering check performed by plain Sortables
//I don't think "o" is even used, but it is in the function declaration
return jQuery.iNestedSortable.oldCheckHover(e,o);
}
},
oldCheckHover : jQuery.iSort.checkhover,
newCheckHover : function (e) {
if (!jQuery.iDrag.dragged) {
return;
}
if ( !(e.dropCfg.el.size() > 0) ) {
return;
}
//we need to recalculate the position of the sortables,
//or there will be some mismatches
if(!e.nestedSortCfg.remeasured) {
jQuery.iSort.measure(e);
e.nestedSortCfg.remeasured = true;
}
//finds item that is on top of the one being dragged,
//and in a compatible nesting level
var precItem = jQuery.iNestedSortable.findPrecedingItem(e);
var shouldNest = jQuery.iNestedSortable.shouldNestItem(e, precItem);
var touchingFirst = (!precItem) ? jQuery.iNestedSortable.isTouchingFirstItem(e) : false;
var quit = false;
//avoids doing things more than once
if(precItem) {
if(e.nestedSortCfg.lastPrecedingItem === precItem && e.nestedSortCfg.lastShouldNest === shouldNest) {
quit = true;
}
}
else if(e.nestedSortCfg.lastPrecedingItem === precItem && e.nestedSortCfg.lastTouchingFirst === touchingFirst) {
quit = true;
}
e.nestedSortCfg.lastPrecedingItem = precItem;
e.nestedSortCfg.lastShouldNest = shouldNest;
e.nestedSortCfg.lastTouchingFirst = touchingFirst;
if(quit) {return;}
if (precItem !== null) {
//there is an element on top of this one
//on the same nesting, or smaller
if (shouldNest) {
jQuery.iNestedSortable.nestItem(e, precItem);
} else {
jQuery.iNestedSortable.appendItem(e, precItem);
}
} else if (touchingFirst) {
//no element on top, but touches the first item on the list
jQuery.iNestedSortable.insertOnTop(e);
}
},
/*
* Auto scrolls the page when we are dragging an element.
*/
scroll: function(e) {
if(!e.nestedSortCfg.autoScroll) {
return false;
}
var sensitivity = e.nestedSortCfg.scrollSensitivity;
var speed = e.nestedSortCfg.scrollSpeed;
var pointer = jQuery.iDrag.dragged.dragCfg.currentPointer;
var docDim = jQuery.iUtil.getScroll();
if((pointer.y - docDim.ih) - docDim.t > -sensitivity) {
window.scrollBy(0,speed);
}
if(pointer.y - docDim.t < sensitivity) {
window.scrollBy(0,-speed);
}
//The two lines bellow are for horizontal scrolling. It is not needed.
//if((pointer.x - docDim.iw) - docDim.l > -sensitivity) {window.scrollBy(speed,0);}
//if(pointer.x - docDim.l < sensitivity) {window.scrollBy(-speed,0);}
},
/*
* Called when the item is released after a drag.
* The argument passed in is the dragged element released.
*/
check : function(dragged) {
//A brand new NestedSortable release check
jQuery.iNestedSortable.newCheck(dragged);
//The legacy release check performed by plain Sortables
return jQuery.iNestedSortable.oldCheck(dragged);
},
oldCheck : jQuery.iSort.check,
newCheck : function(dragged) {
//removes nesting styling
if (jQuery.iNestedSortable.latestNestingClass &&
jQuery.iNestedSortable.currentNesting)
{
jQuery.iNestedSortable.currentNesting
.removeClass(jQuery.iNestedSortable.latestNestingClass);
jQuery.iNestedSortable.currentNesting = null;
jQuery.iNestedSortable.latestNestingClass = "";
}
if(jQuery.iDrop.overzone.isNestedSortable) {
jQuery.iDrop.overzone.nestedSortCfg.remeasured = false;
}
},
/*
* Called when there is a need to serialize the
* NestedSortable, to send back to the server. The
* parameter is a string with the id of the NestedSortable
* element, or an array of ids. If no parameter is passed,
* all nested sortables in the page will be serialized. The
* return value is an object with a 'hash' parameter, that
* contains a string for use in GET or POST, and a 'o' parameter,
* with contains a JavaScript object representation
* of the item order.
*/
serialize: function(s) {
if(jQuery('#' + s).get(0).isNestedSortable){
//A brand new NestedSortable serialization
return jQuery.iNestedSortable.newSerialize(s);
//return "a";
} else {
//The legacy serialization
return jQuery.iNestedSortable.oldSerialize(s);
//return "a";
}
},
oldSerialize: jQuery.iSort.serialize,
newSerialize: function (s) {
var i;
var h = ''; //url get string that represents the element order
var currentPath = ''; //used so the recursive function can build h
var o = {}; //json object that represents the element order
var e; //NestedSortable element being worked on
/*
* This recursive function will build the get string (h)
* and return the object (o) for a given NestedSortable.
*/
var buildHierarchySer = function(context) {
var retVal = [];
thisChildren = jQuery(context).children('.' + jQuery.iSort.collected[s]);
thisChildren.each( function(i) {
//Extracts part of the HTML element ID that
//will be shown in the serialization, using a RegExp.
var serId = jQuery.attr(this,'id');
if(serId && serId.match) {
serId = serId.match(e.nestedSortCfg.serializeRegExp)[0];
}
if (h.length > 0) {
h += '&';
}
h += s + currentPath + '['+i+'][id]=' + serId;
retVal[i] = {id: serId};
var newContext = jQuery(this).children(e.nestedSortCfg.nestingTag + "." + e.nestedSortCfg.nestingTagClass.split(" ").join(".")).get(0);
var oldPath = currentPath;
currentPath += '['+i+'][children]';
var thisChildren = buildHierarchySer(newContext);
if (thisChildren.length > 0) {
retVal[i].children = thisChildren;
}
currentPath = oldPath;
});
return retVal;
};
//analises the parameter passed in
if (s) {
if (jQuery.iSort.collected[s] ) {
//when only one NestedSortable id was passed in
e = jQuery('#' + s).get(0);
o[s] = buildHierarchySer(e);
} else {
for ( a in s) {
//when an array of NestedSortables ids was passed in
if (jQuery.iSort.collected[s[a]] ) {
e = jQuery('#' + s[a]).get(0);
o[s[a]] = buildHierarchySer(e);
}
}
}
} else {
//when nothing was passed in (we will serialize all)
for ( i in jQuery.iSort.collected){
e = jQuery('#' + i).get(0);
o[i] = buildHierarchySer(e);
}
}
return {hash:h, o:o};
},
/*
* Finds the sortable item that is on top of the one being dragged,
* and in a compatible nesting level. Returns null if none was found.
*/
findPrecedingItem : function (e) {
var largestY = 0;
var preceding = jQuery.grep(e.dropCfg.el, function(i) {
//needs to be on top of the one being dragged
var isOnTop = (i.pos.y < jQuery.iDrag.dragged.dragCfg.ny) && (i.pos.y > largestY);
if(!isOnTop) {
return false;
}
//needs to be on the same nesting level or a "child" level
var isSameLevel;
if(e.nestedSortCfg.rightToLeft) {
isSameLevel = (i.pos.x + i.pos.wb + e.nestedSortCfg.snapTolerance > jQuery.iDrag.dragged.dragCfg.nx + jQuery.iDrag.dragged.dragCfg.oC.wb);
} else {
isSameLevel = (i.pos.x - e.nestedSortCfg.snapTolerance < jQuery.iDrag.dragged.dragCfg.nx);
}
if(!isSameLevel) {
return false;
}
//can't be an element that is being dragged
var isBeingDragged = jQuery.iNestedSortable.isBeingDragged(e, i);
if(isBeingDragged) {
return false;
}
//got here because it is a match
largestY = i.pos.y;
return true;
});
if ( preceding.length > 0 ) {
//the last one should be it
return preceding[(preceding.length-1)];
} else {
//nothing above it
return null;
}
},
/*
* Checks if the item being dragged is on top and touching the first item on the list.
* Returns true or false.
*/
isTouchingFirstItem : function (e) {
var lowestY;
var firstItem = jQuery.grep(e.dropCfg.el, function(i) {
//needs to be on top of all elements already looked up
var isBefore = (lowestY === undefined || i.pos.y < lowestY);
if (!isBefore) {
return false;
}
//can't be an element that is being dragged
var isBeingDragged = jQuery.iNestedSortable.isBeingDragged(e, i);
if(isBeingDragged) {
return false;
}
//got here because it is a match
lowestY = i.pos.y;
return true;
});
if ( firstItem.length > 0 ) {
//the last one should be it
firstItem = firstItem[(firstItem.length-1)];
return firstItem.pos.y < jQuery.iDrag.dragged.dragCfg.ny + jQuery.iDrag.dragged.dragCfg.oC.hb &&
firstItem.pos.y > jQuery.iDrag.dragged.dragCfg.ny;
} else {
return false;
}
},
/*
* Checks to see if an element is being dragged.
* You may de dragging an element by itself or by one of his ancestors.
* Returns true or false.
*/
isBeingDragged : function (e, elem) {
var dragged = jQuery.iDrag.dragged;
//nothing being dragged
if(!dragged) {
return false;
}
//trivial case
if(elem == dragged) {
return true;
}
//looks for its ancestors
if (
jQuery(elem)
.parents("." + e.sortCfg.accept.split(" ").join("."))
.filter(function() {return this == dragged;}).length !== 0
) {
return true;
} else {
return false;
}
},
shouldNestItem : function(e, precedingItem ) {
//there should be a preceding item to be able to nest
if(!precedingItem) {return false;}
if(e.nestedSortCfg.noNestingClass &&
jQuery(precedingItem).filter("." + e.nestedSortCfg.noNestingClass).get(0) === precedingItem)
{return false;}
//This code is to limit the levels of nesting that can be achieved
//Development of this is currently halted.
/*
if( e.nestedSortCfg.nestingLimit !== false) {
//nesting level of the preceding item
var nLevelPrec = jQuery(precedingItem)
.parents("." + e.sortCfg.accept.split(" ").join("."))
.length;
//don't allow nesting
if (nLevelPrec >= e.nestedSortCfg.nestingLimit) return false;
//will hold the maximum level of nesting in the element being dragged
var nLevelDrag = 0;
//for each leaf element inside the dragged element (that have no elements nested to it)
jQuery(e.nestedSortCfg.nestingTag + "." + e.nestedSortCfg.nestingTagClass.split(" ").join(".") + " > ." + e.sortCfg.accept.split(" ").join(".") + ":first-child", jQuery.iDrag.dragged)
.not("*["+e.nestedSortCfg.nestingTag + "." + e.nestedSortCfg.nestingTagClass.split(" ").join(".")+"]")
.each( function(i) {
var draggedIndex = 0;
//finds out
var parentLength = jQuery(this).parents("." + e.sortCfg.accept.split(" ").join(".")).each(
function(i) {
draggedIndex = i;
return this == jQuery.iDrag.dragged;
}
).length;
//here dradraggedIndex holds the index
//of the dragged element in the ancestors array of the leaf element
var thisLevel = parentLength - draggedIndex;
if (thisLevel > nLevelDrag )
nLevelDrag = thisLevel;
}
);
//don't allow nesting
if (nLevelPrec + nLevelDrag > e.nestedSortCfg.nestingLimit) return false;
}*/
if (e.nestedSortCfg.rightToLeft) {
return precedingItem.pos.x + precedingItem.pos.wb - (e.nestedSortCfg.nestingPxSpace - e.nestedSortCfg.snapTolerance) > jQuery.iDrag.dragged.dragCfg.nx + jQuery.iDrag.dragged.dragCfg.oC.wb;
} else {
return precedingItem.pos.x + (e.nestedSortCfg.nestingPxSpace - e.nestedSortCfg.snapTolerance) < jQuery.iDrag.dragged.dragCfg.nx;
}
},
nestItem: function(e, parent) {
//selects the nesting tag inside the parent
var parentNesting = jQuery(parent).children(e.nestedSortCfg.nestingTag + "." + e.nestedSortCfg.nestingTagClass.split(" ").join(".") );
var helper = jQuery.iSort.helper;
styleHelper = helper.get(0).style;
styleHelper.width = 'auto'; //makes sure helper gets resized properly
//if there is none, creates it
if ( !parentNesting.size()) {
var newUl = "<" + e.nestedSortCfg.nestingTag + " class='"+e.nestedSortCfg.nestingTagClass+"'></" + e.nestedSortCfg.nestingTag+">";
// Place new nesting tag and adds style
parentNesting = jQuery(parent).append(newUl).children(e.nestedSortCfg.nestingTag).css(e.nestedSortCfg.styleToAttach);
}
//styles the nesting
jQuery.iNestedSortable.updateCurrentNestingClass(e, parentNesting );
//does stuff before the helper is removed
jQuery.iNestedSortable.beforeHelperRemove(e);
//puts the helper in the proper place.
parentNesting.prepend(helper.get(0));
//does stuff after the helper is inserted
jQuery.iNestedSortable.afterHelperInsert(e);
},
appendItem: function(e, itemBefore) {
jQuery.iNestedSortable.updateCurrentNestingClass(e, jQuery(itemBefore).parent() );
jQuery.iNestedSortable.beforeHelperRemove(e);
jQuery(itemBefore).after(jQuery.iSort.helper.get(0));
jQuery.iNestedSortable.afterHelperInsert(e);
},
insertOnTop: function (e) {
jQuery.iNestedSortable.updateCurrentNestingClass(e, e);
jQuery.iNestedSortable.beforeHelperRemove(e);
jQuery(e).prepend(jQuery.iSort.helper.get(0));
jQuery.iNestedSortable.afterHelperInsert(e);
},
beforeHelperRemove : function (e) {
//hides the nesting when it becomes empty
var parent = jQuery.iSort.helper.parent(e.nestedSortCfg.nestingTag + "." + e.nestedSortCfg.nestingTagClass.split(" ").join("."));
var numSiblings = parent
.children("." + e.sortCfg.accept.split(" ").join(".") + ":visible")
.size();
if(numSiblings === 0 && parent.get(0) !== e) {
parent.hide();
}
},
afterHelperInsert : function (e) {
//displays the nesting after something is inserted
var parent = jQuery.iSort.helper.parent();
if(parent.get(0) !== e) {
parent.show();
}
e.nestedSortCfg.remeasured = false;
},
updateCurrentNestingClass : function(e, nestingElem) {
var nesting = jQuery(nestingElem);
if ((e.nestedSortCfg.currentNestingClass) && //makes sure a special class is desired
(!jQuery.iNestedSortable.currentNesting || nesting.get(0) != jQuery.iNestedSortable.currentNesting.get(0)) ){ //avoids doing it on the same elem
//removes from last nesting
if(jQuery.iNestedSortable.currentNesting) {
jQuery.iNestedSortable.currentNesting
.removeClass(e.nestedSortCfg.currentNestingClass);
}
if(nesting.get(0) != e) { //not root nesting
jQuery.iNestedSortable.currentNesting = nesting;
//adds to this one
nesting.addClass(e.nestedSortCfg.currentNestingClass);
//this is need to remove the styling on "check"
jQuery.iNestedSortable.latestNestingClass = e.nestedSortCfg.currentNestingClass;
} else {
//don't style the "root nesting"
//cleans up
jQuery.iNestedSortable.currentNesting = null;
jQuery.iNestedSortable.latestNestingClass = "";
}
}
},
destroy: function () {
return this.each(
function () {
if(this.isNestedSortable) {
this.nestedSortCfg = null;
this.isNestedSortable = null;
jQuery(this).SortableDestroy();
}
}
);
},
build: function(conf) {
if (conf.accept && jQuery.iUtil && jQuery.iDrag && jQuery.iDrop && jQuery.iSort)
{
this.each(
function() {
this.isNestedSortable = true;
this.nestedSortCfg = {
noNestingClass : conf.noNestingClass ? conf.noNestingClass : false,
rightToLeft : conf.rightToLeft ? true : false ,
nestingPxSpace : parseInt(conf.nestingPxSpace, 10) || 30 ,
currentNestingClass : conf.currentNestingClass ? conf.currentNestingClass : "",
nestingLimit : conf.nestingLimit ? conf.nestingLimit : false, //not implemented yet
autoScroll : conf.autoScroll !== undefined ? conf.autoScroll == true : true,
scrollSensitivity: conf.scrollSensitivity ? conf.scrollSensitivity : 20,
scrollSpeed: conf.scrollSpeed ? conf.scrollSpeed : 20,
serializeRegExp : conf.serializeRegExp ? conf.serializeRegExp : /[^\-]*$/
};
//a "do nothing" tolerance when nesting/un-nesting, to stop things from jumping up too quickly
this.nestedSortCfg.snapTolerance = parseInt(this.nestedSortCfg.nestingPxSpace * 0.4, 10);
//the tag that will be used to nest items to parent items
this.nestedSortCfg.nestingTag = this.tagName;
this.nestedSortCfg.nestingTagClass = this.className;
//style that makes nested elements be padded to the right or to the left
this.nestedSortCfg.styleToAttach = (this.nestedSortCfg.rightToLeft) ?
{"padding-left":0, "padding-right": this.nestedSortCfg.nestingPxSpace + 'px' }
:{"padding-left": this.nestedSortCfg.nestingPxSpace + 'px', "padding-right": 0 };
jQuery(this.nestedSortCfg.nestingTag, this)
.css(this.nestedSortCfg.styleToAttach);
}
);
//overides checkhover, check and serialize, without losing backwards compatilibity (eg. plain Sortables can stil be used)
jQuery.iSort.checkhover = jQuery.iNestedSortable.checkHover;
jQuery.iSort.check = jQuery.iNestedSortable.check;
jQuery.iSort.serialize = jQuery.iNestedSortable.serialize;
}
return this.Sortable(conf);
}
};
//Extends jQuery to add the plugin.
jQuery.fn.extend(
{
NestedSortable : jQuery.iNestedSortable.build,
NestedSortableDestroy: jQuery.iNestedSortable.destroy
}
);
//Monkey patches interface with some corrections, which are not applied to
//the 1.2 version yet. getScroll is needed by the autoScroll option.
jQuery.iUtil.getScroll = function (e)
{
var t, l, w, h, iw, ih;
if (e && e.nodeName.toLowerCase() != 'body') {
t = e.scrollTop;
l = e.scrollLeft;
w = e.scrollWidth;
h = e.scrollHeight;
iw = 0;
ih = 0;
} else {
if (document.documentElement && document.documentElement.scrollTop) {
t = document.documentElement.scrollTop;
l = document.documentElement.scrollLeft;
w = document.documentElement.scrollWidth;
h = document.documentElement.scrollHeight;
} else if (document.body) {
t = document.body.scrollTop;
l = document.body.scrollLeft;
w = document.body.scrollWidth;
h = document.body.scrollHeight;
}
iw = self.innerWidth||document.documentElement.clientWidth||document.body.clientWidth||0;
ih = self.innerHeight||document.documentElement.clientHeight||document.body.clientHeight||0;
}
return { t: t, l: l, w: w, h: h, iw: iw, ih: ih };
};
/*}}}*/