-
Bug
-
Resolution: Fixed
-
Normal
-
8.5.2, 8.5.1.2
-
None
-
Security Level: Jimmy
-
None
-
ZK 8.6.0 S1
-
None
Steps to Reproduce
Run fiddle:
http://zkfiddle.org/sample/2f70hon/3-span-flex-with-mesh-break-width-if-header-not-visible
Click on invisible to hide the first column.
Click on the remove button to delete the first column and the first cell
Current Result
When hiding the first column:
Since the column is visible:hidden, but not display:none; the isVisible() call during MeshWidget._adjSpanWd returns "true" even if the column element is hidden.
Since the isVisible returns true, the hidden column is calculated as part of the span width.
When removing the first column:
Sizes are calculated as expected.
Column width are different that when using hidden column
Expected Result
hidden column and removed column should produce the same widths for the remaining columns in the mesh component
Debug Info
The first column still counts as visible when calculating header width during MeshWidget._adjSpanWd (called during onSize with span / flex="min" to calculate span widths)
https://github.com/zkoss/zk/blob/cb68179664830f4e66aff97da415369e6994856c/zul/src/archive/web/js/zul/mesh/MeshWidget.js#L1444
isVisible() on the column header hidden element only checks for display:none (since isVisible is not called with the strict parameter)
https://github.com/zkoss/zk/blob/be15d1d0cbd2eccd811dbfad57a9cba5fa204df9/zk/src/archive/web/js/zk/dom.js#L618
Root Cause
Workaround
ZK 8.5.1.2 and 8.5.2
<script><![CDATA[ zk.afterLoad('zul.mesh', function() { var xMeshWidget = {}; zk.override(zul.mesh.MeshWidget.prototype, xMeshWidget ,{ _adjSpanWd: function () { //used in HeadWidgets if (!this._isAllWidths() || !this.isSpan()) return; var hdfaker = this.ehdfaker, bdfaker = this.ebdfaker, ftfaker = this.eftfaker; if (!hdfaker || !bdfaker) return; var head = this.head.$n(); if (!head) return; this._calcMinWds(); var wd, wds = [], width = 0, hdcol = hdfaker.firstChild, bdcol = bdfaker.firstChild, _minwds = this._minWd.wds, hdlen = this.head.nChildren; for (var temphdcol = hdcol, w = this.head.firstChild, i = 0; w; w = w.nextSibling, i++) { if (zk(temphdcol).isVisible(true)) { var wdh = w._width; if (w._hflex == 'min') wd = wds[i] = _minwds[i]; else if (wdh && wdh.endsWith('px')) wd = wds[i] = zk.parseInt(wdh); else wd = wds[i] = _minwds[i]; width += wd; } temphdcol = temphdcol.nextSibling; } var ftcol = ftfaker ? ftfaker.firstChild : null, total = this.ebody.clientWidth, extSum = total - width, count = total, visj = -1, tblWidth = 0; //refix B70-ZK-2394: should sync colgroup width with table width //span to all columns if (this._nspan < 0) { var hasFrozenScrolled = this.frozen && this.frozen.getStart(); for (var i = 0; hdcol && i < hdlen; hdcol = hdcol.nextSibling, i++) { // ZK-2222: should check visibility if (!zk(hdcol).isVisible(true)) { bdcol = bdcol.nextSibling; if (ftcol) ftcol = ftcol.nextSibling; continue; } else { // for bug ZK-2772, we don't span it when frozen column has scrolled. // Instead, we use its faker width. if (hasFrozenScrolled) { if (extSum <= 0) { wds[i] = wd = wds[i]; } else { if (hdcol.style.width) { wds[i] = wd = zk.parseInt(hdcol.style.width); } else { wds[i] = wd = Math.round(((wds[i] * total / width) + 0.5) || 0); } } } else { wds[i] = wd = extSum <= 0 ? wds[i] : Math.round(((wds[i] * total / width) + 0.5) || 0); } var stylew = jq.px0(wd); count -= wd; visj = i; hdcol.style.width = stylew; bdcol.style.width = stylew; tblWidth += wd; //refix B70-ZK-2394: store each col's width bdcol = bdcol.nextSibling; if (ftcol) { ftcol.style.width = stylew; ftcol = ftcol.nextSibling; } } } //compensate calc error but excluding scrolled frozen column if (extSum > 0 && count != 0 && visj >= 0) { tblWidth -= wd; //refix B70-ZK-2394: subtract the last wd (visj is the last) wd = wds[visj] + count; var stylew = jq.px0(wd); tblWidth += wd; //refix B70-ZK-2394: and add new wd if (!hasFrozenScrolled) { bdfaker.childNodes[visj].style.width = stylew; hdfaker.childNodes[visj].style.width = stylew; if (ftfaker) ftfaker.childNodes[visj].style.width = stylew; } } } else { //feature#3184415: span to a specific column visj = this._nspan - 1; for (var i = 0; hdcol && i < hdlen; hdcol = hdcol.nextSibling, i++) { if (!zk(hdcol).isVisible()) { bdcol = bdcol.nextSibling; if (ftcol) ftcol = ftcol.nextSibling; continue; } else { wd = visj == i && extSum > 0 ? (wds[visj] + extSum) : wds[i]; var stylew = jq.px0(wd); hdcol.style.width = stylew; bdcol.style.width = stylew; tblWidth += wd; //refix B70-ZK-2394: store each col's width bdcol = bdcol.nextSibling; if (ftcol) { ftcol.style.width = stylew; ftcol = ftcol.nextSibling; } } } } //refix B70-ZK-2394: sync colgroup width with (head, body, foot)table width var allWidths = this._isAllWidths(); if (allWidths) { var hdtbl = this.eheadtbl, bdtbl = this.ebodytbl, fttbl = this.efoottbl; if (hdtbl) { hdtbl.style.width = tblWidth + 'px'; if (bdtbl) bdtbl.style.width = tblWidth + 'px'; if (fttbl) fttbl.style.width = tblWidth + 'px'; } } //bug 3188738: Opera only. Grid/Listbox/Tree span="x" not working if (zk.opera) zk(this.$n()).redoCSS(); } });//zk.override });//zk.afterLoad ]]></script>