From cedc5b828a7619c5a8d984a7584e8bb667ae9fef Mon Sep 17 00:00:00 2001 From: Sam Hemelryk Date: Mon, 18 Jan 2010 06:19:51 +0000 Subject: [PATCH] navigation-javascript MDL-21329 Corrected dock issue when many blocks were docked and fixed misc sizing issues --- lib/javascript-static.js | 90 ++++++++++++++++++++++++++++++++++------ 1 file changed, 78 insertions(+), 12 deletions(-) diff --git a/lib/javascript-static.js b/lib/javascript-static.js index 4930b036e50..8dd76edd603 100644 --- a/lib/javascript-static.js +++ b/lib/javascript-static.js @@ -1441,7 +1441,8 @@ blocks.setup_generic_block = function(uid) { * @namespace */ blocks.dock = { - count:0, // The number of dock items through the page life + count:0, // The number of dock items currently + totalcount:0, // The number of dock items through the page life exists:false, // True if the dock exists items:[], // An array of dock items node:null, // The YUI node for the dock itself @@ -1471,7 +1472,8 @@ blocks.dock = { * @namespace */ display:{ - spacebeforefirstitem: 10 // Space between the top of the dock and the first item + spacebeforefirstitem: 10, // Space between the top of the dock and the first item + mindisplaywidth: null // Minimum width for the display of dock items }, /** * CSS classes to use with the dock @@ -1524,13 +1526,17 @@ blocks.dock = { * @param {blocks.dock.item} item */ add:function(item) { - item.id = this.count; + item.id = this.totalcount; this.count++; + this.totalcount++; this.items[item.id] = item; this.draw(); this.items[item.id].draw(); this.fire('dock:itemadded', item); }, + append : function(docknode) { + blocks.dock.node.one('#dock_item_container').append(docknode); + }, /** * Draws the dock * @function @@ -1541,8 +1547,10 @@ blocks.dock = { return true; } this.fire('dock:drawstarted'); + this.item_sizer.init(); this.node = Y.Node.create('
'); this.node.appendChild(Y.Node.create('
')); + this.node.appendChild(Y.Node.create('
')); if (Y.UA.ie > 0 && Y.UA.ie < 7) { this.node.setStyle('height', this.node.get('winHeight')+'px'); } @@ -1570,8 +1578,8 @@ blocks.dock = { } this.items[uid].remove(); delete this.items[uid]; - this.fire('dock:itemremoved', uid); this.count--; + this.fire('dock:itemremoved', uid); if (this.count===0) { this.fire('dock:toberemoved'); this.items = []; @@ -1589,6 +1597,7 @@ blocks.dock = { remove_all:function() { for (var i in this.items) { this.items[i].remove(); + this.count--; delete this.items[i]; } Y.fire('dock:toberemoved'); @@ -1642,6 +1651,53 @@ blocks.dock = { } this.earlybinds = []; }, + item_sizer : { + enabled : false, + init : function() { + blocks.dock.on('dock:itemadded', this.check_if_required, this); + blocks.dock.on('dock:itemremoved', this.check_if_required, this); + Y.on('windowresize', this.check_if_required, this); + }, + check_if_required : function() { + var possibleheight = blocks.dock.node.get('offsetHeight') - blocks.dock.node.one('.controls').get('offsetHeight') - (blocks.dock.cfg.buffer*3) - (blocks.dock.items.length*2); + var totalheight = 0; + for (var id in blocks.dock.items) { + var dockedtitle = Y.get(blocks.dock.items[id].title).ancestor('.'+blocks.dock.cfg.css.dockedtitle); + if (dockedtitle) { + if (this.enabled) { + dockedtitle.setStyle('height', 'auto'); + } + totalheight += dockedtitle.get('offsetHeight') || 0; + } + } + if (totalheight > possibleheight) { + this.enable(possibleheight); + } + }, + enable : function(possibleheight) { + this.enabled = true; + var runningcount = 0; + var usedheight = 0; + for (var id in blocks.dock.items) { + var itemtitle = Y.get(blocks.dock.items[id].title).ancestor('.'+blocks.dock.cfg.css.dockedtitle); + if (!itemtitle) { + continue; + } + var itemheight = Math.floor((possibleheight-usedheight) / (blocks.dock.count - runningcount)); + Y.log("("+possibleheight+"-"+usedheight+") / ("+blocks.dock.count+" - "+runningcount+") = "+itemheight); + var offsetheight = itemtitle.get('offsetHeight'); + itemtitle.setStyle('overflow', 'hidden'); + if (offsetheight > itemheight) { + itemtitle.setStyle('height', itemheight+'px'); + usedheight += itemheight; + } else { + usedheight += offsetheight; + } + runningcount++; + } + Y.log('possible: '+possibleheight+' - used height: '+usedheight); + } + }, /** * Namespace containing methods and properties that will be prototyped * to the generic block class and possibly overriden by themes @@ -1733,7 +1789,7 @@ blocks.dock = { node.replace(Y.Node.getDOMNode(placeholder)); node = null; - this.resize_block_space(placeholder); + var spacewidth = this.resize_block_space(placeholder); var blocktitle = Y.Node.getDOMNode(this.cachedcontentnode.one('.title h2')).cloneNode(true); blocktitle.innerHTML = blocktitle.innerHTML.replace(/([a-zA-Z0-9])/g, "$1
"); @@ -1746,6 +1802,9 @@ blocks.dock = { // Create a new dock item for the block var dockitem = new blocks.dock.item(this.id, blocktitle, blockcontent, blockcommands); + if (spacewidth !== null && blocks.dock.cfg.display.mindisplaywidth == null) { + dockitem.cfg.display.mindisplaywidth = spacewidth; + } // Wire the draw events to register remove events dockitem.on('dockeditem:drawcomplete', function(e){ // check the contents block [editing=off] @@ -1761,7 +1820,7 @@ blocks.dock = { }, dockitem); // Register an event so that when it is removed we can put it back as a block - dockitem.on('dock:itemremoved', this.return_to_block, this, dockitem); + dockitem.on('dockitem:itemremoved', this.return_to_block, this, dockitem); blocks.dock.add(dockitem); if (!this.skipsetposition) { @@ -1780,9 +1839,10 @@ blocks.dock = { resize_block_space : function(node) { node = node.ancestor('.block-region'); if (node) { + var width = node.getStyle('width'); if (node.all('.sideblock').size() === 0 && this.blockspacewidth === null) { // If the node has no children then we can shrink it - this.blockspacewidth = node.getStyle('width'); + this.blockspacewidth = width; node.setStyle('width', '0px'); } else if (this.blockspacewidth !== null) { // Otherwise if it contains children and we have saved a width @@ -1790,7 +1850,9 @@ blocks.dock = { node.setStyle('width', this.blockspacewidth); this.blockspacewidth = null; } + return width; } + return null; }, /** @@ -1864,7 +1926,7 @@ blocks.dock = { this.publish('dockeditem:resizecomplete', {prefix:'dockeditem'}); this.publish('dockeditem:itemremoved', {prefix:'dockeditem'}); }, - + /** * This function draws the item on the dock */ @@ -1880,7 +1942,7 @@ blocks.dock = { if (this.commands.hasChildNodes) { this.contents.appendChild(this.commands); } - blocks.dock.node.append(dockitem); + blocks.dock.append(dockitem); var position = dockitemtitle.getXY(); position[0] += parseInt(dockitemtitle.get('offsetWidth')); @@ -1905,6 +1967,10 @@ blocks.dock = { this.panel.showEvent.subscribe(this.resize_panel, this, true); this.panel.setBody(Y.Node.getDOMNode(this.contents)); this.panel.render(blocks.dock.node); + if (this.cfg.display.mindisplaywidth !== null && Y.one(this.panel.body).getStyle('minWidth') == '0px') { + Y.one(this.panel.body).setStyle('minWidth', this.cfg.display.mindisplaywidth); + Y.one(this.panel.body).setStyle('minHeight', dockitemtitle.get('offsetHeight')+'px'); + } dockitem.on('showitem|mouseover', this.show, this); this.fire('dockeditem:drawcomplete'); }, @@ -1916,7 +1982,7 @@ blocks.dock = { this.hide(e); Y.one('#dock_item_'+this.id).remove(); this.panel.destroy(); - this.fire('dock:itemremoved'); + this.fire('dockitem:itemremoved'); }, /** * This function toggles makes the item active and shows it @@ -1987,8 +2053,8 @@ blocks.dock = { // This makes the panel constrain to the screen's height if the panel is big if (paneltop <= buffer && ((panelheight+paneltop*2) > screenheight || panelbody.hasClass('oversized_content'))) { - this.panel.cfg.setProperty('height', screenheight-(buffer*2)); - panelbody.setStyle('height', (screenheight-(buffer*3))+'px'); + this.panel.cfg.setProperty('height', screenheight-(buffer*3)); + panelbody.setStyle('height', (screenheight-(buffer*3)-10)+'px'); panelbody.addClass('oversized_content'); } this.fire('dockeditem:resizecomplete');