/*jQuery plugin : jqDock v1.2 */
; (function($) { if (!$.fn.jqDock) { var jqDock = function() { return { version: 1.2, defaults: { size: 36, distance: 54, coefficient: 1.5, duration: 500, align: 'bottom', labels: false, source: false, loader: null }, useJqLoader: $.browser.opera || $.browser.safari, shrinkInterval: 100, docks: [], X: 0, Y: 0, verthorz: { v: { wh: 'height', xy: 'Y', tl: 'top', lead: 'Top', trail: 'Bottom', act: 'ActualInv' }, h: { wh: 'width', xy: 'X', tl: 'left', lead: 'Left', trail: 'Right', act: 'Actual'} }, elementCss: { position: 'relative', borderWidth: 0, borderStyle: 'none', verticalAlign: 'top' }, vanillaDiv: '<div style="position:relative;margin:0px;padding:0px;border:0px none;background-color:transparent;">', initDock: function(id) { var ME = this, Dock = this.docks[id], op = Dock.Opts, off = 0, AI = $('a, img', Dock.Menu), i = 0, j, el, wh, acc, upad, opPre95 = ($.browser.opera && (1 * ($.browser.version.match(/^(\d+\.\d+)/) || [0, 0])[1]) < 9.5); this.removeText(Dock.Menu); if (op.orient.vh == 'h') { AI.css(this.elementCss); if (opPre95 || !$.boxModel) { AI.filter('a').css({ lineHeight: 0, fontSize: '0px' }) } else { var hcss = { display: 'block' }; hcss['float'] = 'left'; AI.filter('img').css(hcss) } } else { AI.not($('a img', Dock.Menu)).wrap(this.vanillaDiv + '</div>').end().css(this.elementCss).css({ display: 'block' }) } while (i < Dock.Elem.length) { el = Dock.Elem[i++]; wh = this.keepProportion(el, op.size, { vh: op.orient.inv, inv: op.orient.vh }); el.Actual = el.Final = el.Initial = wh[op.vh.wh]; el.SizeDiff = el[op.vh.wh] - el.Initial; el.Img.css(wh); el.Img.removeAttr('title').attr({ alt: '' }).parent('a').removeAttr('title'); el.ShrinkStep = Math.floor(el.SizeDiff * this.shrinkInterval / op.duration); Dock[op.vh.inv.wh] = Math.max(Dock[op.vh.inv.wh], op.size + el.Pad[op.vh.inv.lead] + el.Pad[op.vh.inv.trail]); el.Offset = off; el.Centre = el.Offset + el.Pad[op.vh.lead] + (el.Initial / 2); off += el.Initial + el.Pad[op.vh.lead] + el.Pad[op.vh.trail] } i = 0; while (i < Dock.Elem.length) { el = Dock.Elem[i++]; acc = 0; upad = el.Pad[op.vh.lead] + el.Pad[op.vh.trail]; Dock.Spread += el.Initial + upad; this.setSizes(id, el.Centre); j = Dock.Elem.length; while (j) { acc += Dock.Elem[--j].Final + upad } Dock[op.vh.wh] = Math.max(Dock[op.vh.wh], acc) } while (i) { el = Dock.Elem[--i]; el.Final = el.Initial } var wrap = [this.vanillaDiv, '<div class="jqDock" style="position:absolute;top:0px;left:0px;padding:0px;', 'margin:0px;overflow:visible;height:', Dock.height, 'px;width:', Dock.width, 'px;"></div></div>'].join(''); Dock.Yard = $(Dock.Menu).wrapInner(wrap).find('div.jqDock'); $.each([op.vh.lead, op.vh.trail], function(n, v) { Dock.Borders[v] = ME.asNumber(Dock.Yard.css('border' + v + 'Width')) }); if (Dock.Borders[op.vh.lead]) { Dock.Yard.css(op.vh.tl, Math.ceil(Dock.Borders[op.vh.lead] / 2)) } while (i < Dock.Elem.length) { el = Dock.Elem[i]; this.changeSize(id, i, el.Final, true); el.Img.addClass('jqDockMouse' + id + '_' + (i++)) } $(Dock.Menu).show(); if (Dock.Opts.labels) { $.each(Dock.Elem, function(i) { ME.setLabel(id, this.Label) }); Dock.Label.hide() } Dock.Yard.bind('mouseover mouseout mousemove', function(e) { ME.mouseHandler(e) }) }, altImage: function() { var alt = $(this).attr('alt'); return (alt && alt.match(/\.(gif|jpg|jpeg|png)$/i)) ? alt : false }, removeText: function(el) { var i = el.childNodes.length, j; while (i) { j = el.childNodes[--i]; if (j.childNodes && j.childNodes.length) { this.removeText(j) } else if (j.nodeType == 3) { el.removeChild(j) } } }, asNumber: function(x) { var r = parseInt(x, 10); return isNaN(r) ? 0 : r }, keepProportion: function(el, dim, orient) { var r = {}, vh = this.verthorz[orient.vh], inv = this.verthorz[orient.inv]; r[vh.wh] = dim; r[inv.wh] = Math.round(dim * el[inv.wh] / el[vh.wh]); return r }, deltaXY: function(id) { var Dock = this.docks[id]; if (Dock.Current !== false) { var op = Dock.Opts, el = Dock.Elem[Dock.Current], p = el.Pad[op.vh.lead] + el.Pad[op.vh.trail], off = el.Img.offset(); Dock.Delta = Math.floor((this[op.vh.xy] - off[op.vh.tl]) * (p + el.Initial) / (p + el.Actual)) + el.Offset; this.doLabel(id, off) } }, setLabel: function(id, label) { var Dock = this.docks[id], ME = this, pad = {}; if (!Dock.Label) { Dock.Label = $('<div class="jqDockLabel jqDockMouse' + id + '_00 jqDockLabelImage" style="position:absolute;margin:0px;"></div>').hide().bind('click', function() { Dock.Elem[Dock.Current].Img.trigger('click') }).appendTo(Dock.Yard) } if (label.txt) { Dock.Label.text(label.txt); $.each(['Top', 'Right', 'Bottom', 'Left'], function(n, v) { pad[v] = ME.asNumber(Dock.Label.css('padding' + v)) }); $.each(this.verthorz, function(vh, o) { label[o.wh] = Dock.Label[o.wh](); label[o.wh + 'Pad'] = pad[o.lead] + pad[o.trail] }) } }, doLabel: function(id, off) { var Dock = this.docks[id]; if (Dock.Opts.labels && Dock.Current !== false) { var el = Dock.Elem[Dock.Current], L = el.Label, op = Dock.Opts, what = typeof off == 'string' ? off : 'move'; switch (what) { case 'show': case 'hide': Dock.Label[L.txt ? what : 'hide'](); break; case 'change': Dock.Label[0].className = Dock.Label[0].className.replace(/(jqDockLabel)(Link|Image)/, '$1' + (el.Linked ? 'Link' : 'Image')); Dock.Label.text(L.txt).css({ width: L.width, height: L.height }).hide(); break; default: var doff = Dock.Yard.offset(), css = { top: off.top - doff.top, left: off.left - doff.left }, splt = op.labels.split(''); if (splt[0] == 'm') { css.top += Math.floor((el[op.vh.inv.act] - L.height - L.heightPad) / 2) } else if (splt[0] == 'b') { css.top += el[op.vh.inv.act] + el.Pad.Top + el.Pad.Bottom - L.height - L.heightPad } if (splt[1] == 'c') { css.left += Math.floor((el[op.vh.act] - L.width - L.widthPad) / 2) } else if (splt[1] == 'r') { css.left += el[op.vh.act] + el.Pad.Left + el.Pad.Right - L.width - L.widthPad } Dock.Label.css(css) } } }, mouseHandler: function(e) { var r = null, t = e.target.className.match(/jqDockMouse(\d+)_(\d+)/), rt = !!(e.relatedTarget) && e.relatedTarget.tagName !== undefined; if (t) { r = false; var id = 1 * t[1], Dock = this.docks[id], idx = t[2] == '00' ? Dock.Current : 1 * t[2]; this.X = e.pageX; this.Y = e.pageY; if (e.type == 'mousemove') { if (idx == Dock.Current) { this.deltaXY(id); if (Dock.OnDock && Dock.Expanded) { this.setSizes(id); this.factorSizes(id) } } } else { var rel = rt && e.relatedTarget.className.match(/jqDockMouse(\d+)_(\d+)/); if (e.type == 'mouseover' && (!Dock.OnDock || idx !== Dock.Current)) { Dock.Current = idx; this.doLabel(id, 'change'); this.deltaXY(id); if (Dock.Expanded) { this.doLabel(id, 'show') } if (rt && (!rel || rel[1] != id)) { Dock.Timestamp = (new Date()).getTime(); this.setSizes(id); Dock.OnDock = true; this.overDock(id) } } else if (rt && e.type == 'mouseout') { if (!rel || rel[1] != id) { Dock.OnDock = false; this.doLabel(id, 'hide'); var i = Dock.Elem.length; while ((i--)) { Dock.Elem[i].Final = Dock.Elem[i].Intial } this.offDock(id) } } } } return r }, overDock: function(id) { var Dock = this.docks[id]; if (Dock.OnDock) { var ME = this, el = Dock.Elem, i = el.length; while ((i--) && !(el[i].Actual < el[i].Final)) { } if (i < 0) { Dock.Expanded = true; this.deltaXY(id); this.doLabel(id, 'show') } else { this.setSizes(id); this.factorSizes(id); setTimeout(function() { ME.overDock(id) }, 60) } } }, offDock: function(id) { var Dock = this.docks[id]; if (!Dock.OnDock) { var ME = this, done = true, i = Dock.Elem.length, el, sz; while (i) { el = Dock.Elem[--i]; if (el.Actual > el.Initial) { sz = el.Actual - el.ShrinkStep; if (sz > el.Initial) { done = false } else { sz = el.Initial } this.changeSize(id, i, sz) } } this.deltaXY(id); if (done) { while (i < Dock.Elem.length) { el = Dock.Elem[i++]; el.Actual = el.Final = el.Initial } Dock.Current = Dock.Expanded = false } else { setTimeout(function() { ME.offDock(id) }, this.shrinkInterval) } } }, setSizes: function(id, mxy) { var Dock = this.docks[id], op = Dock.Opts, i = Dock.Elem.length, el, sz; mxy = mxy || Dock.Delta; while (i) { el = Dock.Elem[--i]; sz = Math.floor(el.SizeDiff * Math.pow(Math.abs(mxy - el.Centre), op.coefficient) / op.attenuation); el.Final = (sz < el.SizeDiff ? el[op.vh.wh] - sz : el.Initial) } }, factorSizes: function(id) { var Dock = this.docks[id], op = Dock.Opts, lapse = op.duration + 60; if (Dock.Timestamp) { lapse = (new Date()).getTime() - Dock.Timestamp; if (lapse >= op.duration) { Dock.Timestamp = 0 } } if (lapse > 60) { var f = lapse < op.duration ? lapse / op.duration : 0, i = 0, el; while (i < Dock.Elem.length) { el = Dock.Elem[i]; this.changeSize(id, i++, (f ? Math.floor(el.Initial + ((el.Final - el.Initial) * f)) : el.Final)) } } }, changeSize: function(id, idx, dim, force) { var Dock = this.docks[id], el = Dock.Elem[idx]; if (force || el.Actual != dim) { var op = Dock.Opts, bdr = ($.boxModel || op.orient.vh == 'v') ? 0 : Dock.Borders[op.vh.lead] + Dock.Borders[op.vh.trail]; if (el.Source[2] && !force && el.Actual == el.Initial) { el.Img[0].src = el.Source[1] } if (Dock.OnDock) { this.deltaXY(id) } Dock.Spread += dim - el.Actual; var css = this.keepProportion(el, dim, op.orient), diff = op.size - css[op.vh.inv.wh], m = 'margin', z = op.vh.inv; switch (op.align) { case 'bottom': case 'right': css[m + z.lead] = diff; break; case 'middle': case 'center': css[m + z.lead] = (diff + diff % 2) / 2; css[m + z.trail] = (diff - diff % 2) / 2; break; case 'top': case 'left': css[m + z.trail] = diff; break; default: } Dock.Yard[op.vh.wh](Dock.Spread + bdr); el.Img.css(css); Dock.Yard.css('margin' + op.vh.lead, Math.floor(Math.max(0, (Dock[op.vh.wh] - Dock.Spread) / 2))); el.Actual = dim; el.ActualInv = css[op.vh.inv.wh]; if (el.Source[2] && !force && el.Actual == el.Initial) { el.Img[0].src = el.Source[0] } } } } } (); $.fn.jqDock = function(opts) { return this.filter(function() { var i = jqDock.docks.length; while ((i--) && this != jqDock.docks[i].Menu) { } return (i < 0) && ($('img', this).length) }).hide().each(function() { var id = jqDock.docks.length; jqDock.docks[id] = { Elem: [], Menu: this, OnDock: false, Expanded: false, Timestamp: 0, width: 0, height: 0, Spread: 0, Borders: {}, Yard: false, Opts: $.extend({}, jqDock.defaults, opts || {}), Current: false, Delta: 0, Loaded: 0, Label: false }; var Dock = jqDock.docks[id], op = Dock.Opts; op.attenuation = Math.pow(op.distance, op.coefficient); op.orient = ({ left: 1, center: 1, right: 1}[op.align]) ? { vh: 'v', inv: 'h'} : { vh: 'h', inv: 'v' }; op.vh = $.extend({}, jqDock.verthorz[op.orient.vh], { inv: jqDock.verthorz[op.orient.inv] }); op.loader = (op.loader) && typeof op.loader == 'string' && /^image|jquery$/i.test(op.loader) ? op.loader.toLowerCase() : ''; op.labels = op.labels === true ? { top: 'bc', left: 'tr', right: 'tl'}[op.align] || 'tc' : (typeof op.labels == 'string' && { tl: 1, tc: 1, tr: 1, ml: 1, mc: 1, mr: 1, bl: 1, bc: 1, br: 1}[op.labels] ? op.labels : false); $('img', this).each(function(n) { var me = $(this), s0 = me.attr('src'), s1 = (op.source ? op.source.call(me[0], n) : false) || jqDock.altImage.call(this) || s0, tx = op.labels ? me.attr('title') || me.parent('a').attr('title') || '' : ''; Dock.Elem[n] = { Img: me, Source: [s0, s1, !(s0 == s1)], Label: { txt: tx, width: 0, height: 0, widthPad: 0, heightPad: 0 }, Initial: 0, Actual: 0, ActualInv: 0, Final: 0, Offset: 0, Centre: 0, Pad: {}, Linked: !!me.parent('a').length, width: 0, height: 0 }; $.each(['Top', 'Right', 'Bottom', 'Left'], function(i, v) { Dock.Elem[n].Pad[v] = jqDock.asNumber(me.css('padding' + v)) }) }); var jqld = (!op.loader && jqDock.useJqLoader) || op.loader == 'jquery'; $.each(Dock.Elem, function(i) { var me = this, iLoaded = function() { me.height = this.height; me.width = this.width; if (++Dock.Loaded >= Dock.Elem.length) { setTimeout(function() { jqDock.initDock(id) }, 0) } }; if (jqld) { $('<img />').bind('load', iLoaded).attr({ src: this.Source[1] }) } else { var pre = new Image(); pre.onload = function() { iLoaded.call(this); pre.onload = function() { } }; pre.src = this.Source[1] } }) }).end() }; $.jqDock = function(x) { return jqDock[x] ? jqDock[x] : null } } })(jQuery);



