[483] | 1 | define([ |
---|
| 2 | "dijit/registry", |
---|
| 3 | "dojo/_base/declare", |
---|
| 4 | "dojo/_base/lang", |
---|
| 5 | "./util", |
---|
| 6 | "dojo/_base/html" |
---|
| 7 | ], function(dijitRegistry, declare, lang, util, html){ |
---|
| 8 | |
---|
| 9 | var indexInParent = function(inNode){ |
---|
| 10 | var i=0, n, p=inNode.parentNode; |
---|
| 11 | while((n = p.childNodes[i++])){ |
---|
| 12 | if(n == inNode){ |
---|
| 13 | return i - 1; |
---|
| 14 | } |
---|
| 15 | } |
---|
| 16 | return -1; |
---|
| 17 | }; |
---|
| 18 | |
---|
| 19 | var cleanNode = function(inNode){ |
---|
| 20 | if(!inNode){ |
---|
| 21 | return; |
---|
| 22 | } |
---|
| 23 | dojo.forEach(dijitRegistry.toArray(), function(w){ |
---|
| 24 | if(w.domNode && html.isDescendant(w.domNode, inNode, true)){ |
---|
| 25 | w.destroy(); |
---|
| 26 | } |
---|
| 27 | }); |
---|
| 28 | }; |
---|
| 29 | |
---|
| 30 | var getTagName = function(inNodeOrId){ |
---|
| 31 | var node = html.byId(inNodeOrId); |
---|
| 32 | return (node && node.tagName ? node.tagName.toLowerCase() : ''); |
---|
| 33 | }; |
---|
| 34 | |
---|
| 35 | var nodeKids = function(inNode, inTag){ |
---|
| 36 | var result = []; |
---|
| 37 | var i=0, n; |
---|
| 38 | while((n = inNode.childNodes[i])){ |
---|
| 39 | i++; |
---|
| 40 | if(getTagName(n) == inTag){ |
---|
| 41 | result.push(n); |
---|
| 42 | } |
---|
| 43 | } |
---|
| 44 | return result; |
---|
| 45 | }; |
---|
| 46 | |
---|
| 47 | var divkids = function(inNode){ |
---|
| 48 | return nodeKids(inNode, 'div'); |
---|
| 49 | }; |
---|
| 50 | |
---|
| 51 | return declare("dojox.grid._Scroller", null, { |
---|
| 52 | constructor: function(inContentNodes){ |
---|
| 53 | this.setContentNodes(inContentNodes); |
---|
| 54 | this.pageHeights = []; |
---|
| 55 | this.pageNodes = []; |
---|
| 56 | this.stack = []; |
---|
| 57 | }, |
---|
| 58 | // specified |
---|
| 59 | rowCount: 0, // total number of rows to manage |
---|
| 60 | defaultRowHeight: 32, // default height of a row |
---|
| 61 | keepRows: 100, // maximum number of rows that should exist at one time |
---|
| 62 | contentNode: null, // node to contain pages |
---|
| 63 | scrollboxNode: null, // node that controls scrolling |
---|
| 64 | // calculated |
---|
| 65 | defaultPageHeight: 0, // default height of a page |
---|
| 66 | keepPages: 10, // maximum number of pages that should exists at one time |
---|
| 67 | pageCount: 0, |
---|
| 68 | windowHeight: 0, |
---|
| 69 | firstVisibleRow: 0, |
---|
| 70 | lastVisibleRow: 0, |
---|
| 71 | averageRowHeight: 0, // the average height of a row |
---|
| 72 | // private |
---|
| 73 | page: 0, |
---|
| 74 | pageTop: 0, |
---|
| 75 | // init |
---|
| 76 | init: function(inRowCount, inKeepRows, inRowsPerPage){ |
---|
| 77 | switch(arguments.length){ |
---|
| 78 | case 3: this.rowsPerPage = inRowsPerPage; |
---|
| 79 | case 2: this.keepRows = inKeepRows; |
---|
| 80 | case 1: this.rowCount = inRowCount; |
---|
| 81 | default: break; |
---|
| 82 | } |
---|
| 83 | this.defaultPageHeight = (this.grid.rowHeight > 0 ? this.grid.rowHeight : this.defaultRowHeight) * this.rowsPerPage; |
---|
| 84 | this.pageCount = this._getPageCount(this.rowCount, this.rowsPerPage); |
---|
| 85 | this.setKeepInfo(this.keepRows); |
---|
| 86 | this.invalidate(); |
---|
| 87 | if(this.scrollboxNode){ |
---|
| 88 | this.scrollboxNode.scrollTop = 0; |
---|
| 89 | this.scroll(0); |
---|
| 90 | this.scrollboxNode.onscroll = lang.hitch(this, 'onscroll'); |
---|
| 91 | } |
---|
| 92 | }, |
---|
| 93 | _getPageCount: function(rowCount, rowsPerPage){ |
---|
| 94 | return rowCount ? (Math.ceil(rowCount / rowsPerPage) || 1) : 0; |
---|
| 95 | }, |
---|
| 96 | destroy: function(){ |
---|
| 97 | this.invalidateNodes(); |
---|
| 98 | delete this.contentNodes; |
---|
| 99 | delete this.contentNode; |
---|
| 100 | delete this.scrollboxNode; |
---|
| 101 | }, |
---|
| 102 | setKeepInfo: function(inKeepRows){ |
---|
| 103 | this.keepRows = inKeepRows; |
---|
| 104 | this.keepPages = !this.keepRows ? this.keepPages : Math.max(Math.ceil(this.keepRows / this.rowsPerPage), 2); |
---|
| 105 | }, |
---|
| 106 | // nodes |
---|
| 107 | setContentNodes: function(inNodes){ |
---|
| 108 | this.contentNodes = inNodes; |
---|
| 109 | this.colCount = (this.contentNodes ? this.contentNodes.length : 0); |
---|
| 110 | this.pageNodes = []; |
---|
| 111 | for(var i=0; i<this.colCount; i++){ |
---|
| 112 | this.pageNodes[i] = []; |
---|
| 113 | } |
---|
| 114 | }, |
---|
| 115 | getDefaultNodes: function(){ |
---|
| 116 | return this.pageNodes[0] || []; |
---|
| 117 | }, |
---|
| 118 | // updating |
---|
| 119 | invalidate: function(){ |
---|
| 120 | this._invalidating = true; |
---|
| 121 | this.invalidateNodes(); |
---|
| 122 | this.pageHeights = []; |
---|
| 123 | this.height = (this.pageCount ? (this.pageCount - 1)* this.defaultPageHeight + this.calcLastPageHeight() : 0); |
---|
| 124 | this.resize(); |
---|
| 125 | this._invalidating = false; |
---|
| 126 | }, |
---|
| 127 | updateRowCount: function(inRowCount){ |
---|
| 128 | this.invalidateNodes(); |
---|
| 129 | this.rowCount = inRowCount; |
---|
| 130 | // update page count, adjust document height |
---|
| 131 | var oldPageCount = this.pageCount; |
---|
| 132 | if(oldPageCount === 0){ |
---|
| 133 | //We want to have at least 1px in height to keep scroller. Otherwise with an |
---|
| 134 | //empty grid you can't scroll to see the header. |
---|
| 135 | this.height = 1; |
---|
| 136 | } |
---|
| 137 | this.pageCount = this._getPageCount(this.rowCount, this.rowsPerPage); |
---|
| 138 | if(this.pageCount < oldPageCount){ |
---|
| 139 | for(var i=oldPageCount-1; i>=this.pageCount; i--){ |
---|
| 140 | this.height -= this.getPageHeight(i); |
---|
| 141 | delete this.pageHeights[i]; |
---|
| 142 | } |
---|
| 143 | }else if(this.pageCount > oldPageCount){ |
---|
| 144 | this.height += this.defaultPageHeight * (this.pageCount - oldPageCount - 1) + this.calcLastPageHeight(); |
---|
| 145 | } |
---|
| 146 | this.resize(); |
---|
| 147 | }, |
---|
| 148 | // implementation for page manager |
---|
| 149 | pageExists: function(inPageIndex){ |
---|
| 150 | return Boolean(this.getDefaultPageNode(inPageIndex)); |
---|
| 151 | }, |
---|
| 152 | measurePage: function(inPageIndex){ |
---|
| 153 | if(this.grid.rowHeight){ |
---|
| 154 | return ((inPageIndex + 1) * this.rowsPerPage > this.rowCount ? |
---|
| 155 | this.rowCount - inPageIndex * this.rowsPerPage : |
---|
| 156 | this.rowsPerPage) * this.grid.rowHeight; |
---|
| 157 | |
---|
| 158 | } |
---|
| 159 | var n = this.getDefaultPageNode(inPageIndex); |
---|
| 160 | return (n && n.innerHTML) ? n.offsetHeight : undefined; |
---|
| 161 | }, |
---|
| 162 | positionPage: function(inPageIndex, inPos){ |
---|
| 163 | for(var i=0; i<this.colCount; i++){ |
---|
| 164 | this.pageNodes[i][inPageIndex].style.top = inPos + 'px'; |
---|
| 165 | } |
---|
| 166 | }, |
---|
| 167 | repositionPages: function(inPageIndex){ |
---|
| 168 | var nodes = this.getDefaultNodes(); |
---|
| 169 | var last = 0; |
---|
| 170 | |
---|
| 171 | for(var i=0; i<this.stack.length; i++){ |
---|
| 172 | last = Math.max(this.stack[i], last); |
---|
| 173 | } |
---|
| 174 | // |
---|
| 175 | var n = nodes[inPageIndex]; |
---|
| 176 | var y = (n ? this.getPageNodePosition(n) + this.getPageHeight(inPageIndex) : 0); |
---|
| 177 | for(var p=inPageIndex+1; p<=last; p++){ |
---|
| 178 | n = nodes[p]; |
---|
| 179 | if(n){ |
---|
| 180 | if(this.getPageNodePosition(n) == y){ |
---|
| 181 | return; |
---|
| 182 | } |
---|
| 183 | this.positionPage(p, y); |
---|
| 184 | } |
---|
| 185 | y += this.getPageHeight(p); |
---|
| 186 | } |
---|
| 187 | }, |
---|
| 188 | installPage: function(inPageIndex){ |
---|
| 189 | for(var i=0; i<this.colCount; i++){ |
---|
| 190 | this.contentNodes[i].appendChild(this.pageNodes[i][inPageIndex]); |
---|
| 191 | } |
---|
| 192 | }, |
---|
| 193 | preparePage: function(inPageIndex, inReuseNode){ |
---|
| 194 | var p = (inReuseNode ? this.popPage() : null); |
---|
| 195 | for(var i=0; i<this.colCount; i++){ |
---|
| 196 | var nodes = this.pageNodes[i]; |
---|
| 197 | var new_p = (p === null ? this.createPageNode() : this.invalidatePageNode(p, nodes)); |
---|
| 198 | new_p.pageIndex = inPageIndex; |
---|
| 199 | nodes[inPageIndex] = new_p; |
---|
| 200 | } |
---|
| 201 | }, |
---|
| 202 | // rendering implementation |
---|
| 203 | renderPage: function(inPageIndex){ |
---|
| 204 | var nodes = []; |
---|
| 205 | var i, j; |
---|
| 206 | for(i=0; i<this.colCount; i++){ |
---|
| 207 | nodes[i] = this.pageNodes[i][inPageIndex]; |
---|
| 208 | } |
---|
| 209 | for(i=0, j=inPageIndex*this.rowsPerPage; (i<this.rowsPerPage)&&(j<this.rowCount); i++, j++){ |
---|
| 210 | this.renderRow(j, nodes); |
---|
| 211 | } |
---|
| 212 | }, |
---|
| 213 | removePage: function(inPageIndex){ |
---|
| 214 | for(var i=0, j=inPageIndex*this.rowsPerPage; i<this.rowsPerPage; i++, j++){ |
---|
| 215 | this.removeRow(j); |
---|
| 216 | } |
---|
| 217 | }, |
---|
| 218 | destroyPage: function(inPageIndex){ |
---|
| 219 | for(var i=0; i<this.colCount; i++){ |
---|
| 220 | var n = this.invalidatePageNode(inPageIndex, this.pageNodes[i]); |
---|
| 221 | if(n){ |
---|
| 222 | html.destroy(n); |
---|
| 223 | } |
---|
| 224 | } |
---|
| 225 | }, |
---|
| 226 | pacify: function(inShouldPacify){ |
---|
| 227 | }, |
---|
| 228 | // pacification |
---|
| 229 | pacifying: false, |
---|
| 230 | pacifyTicks: 200, |
---|
| 231 | setPacifying: function(inPacifying){ |
---|
| 232 | if(this.pacifying != inPacifying){ |
---|
| 233 | this.pacifying = inPacifying; |
---|
| 234 | this.pacify(this.pacifying); |
---|
| 235 | } |
---|
| 236 | }, |
---|
| 237 | startPacify: function(){ |
---|
| 238 | this.startPacifyTicks = new Date().getTime(); |
---|
| 239 | }, |
---|
| 240 | doPacify: function(){ |
---|
| 241 | var result = (new Date().getTime() - this.startPacifyTicks) > this.pacifyTicks; |
---|
| 242 | this.setPacifying(true); |
---|
| 243 | this.startPacify(); |
---|
| 244 | return result; |
---|
| 245 | }, |
---|
| 246 | endPacify: function(){ |
---|
| 247 | this.setPacifying(false); |
---|
| 248 | }, |
---|
| 249 | // default sizing implementation |
---|
| 250 | resize: function(){ |
---|
| 251 | if(this.scrollboxNode){ |
---|
| 252 | this.windowHeight = this.scrollboxNode.clientHeight; |
---|
| 253 | } |
---|
| 254 | for(var i=0; i<this.colCount; i++){ |
---|
| 255 | //We want to have 1px in height min to keep scroller. Otherwise can't scroll |
---|
| 256 | //and see header in empty grid. |
---|
| 257 | util.setStyleHeightPx(this.contentNodes[i], Math.max(1,this.height)); |
---|
| 258 | } |
---|
| 259 | |
---|
| 260 | // Calculate the average row height and update the defaults (row and page). |
---|
| 261 | var needPage = (!this._invalidating); |
---|
| 262 | if(!needPage){ |
---|
| 263 | var ah = this.grid.get("autoHeight"); |
---|
| 264 | if(typeof ah == "number" && ah <= Math.min(this.rowsPerPage, this.rowCount)){ |
---|
| 265 | needPage = true; |
---|
| 266 | } |
---|
| 267 | } |
---|
| 268 | if(needPage){ |
---|
| 269 | this.needPage(this.page, this.pageTop); |
---|
| 270 | } |
---|
| 271 | var rowsOnPage = (this.page < this.pageCount - 1) ? this.rowsPerPage : ((this.rowCount % this.rowsPerPage) || this.rowsPerPage); |
---|
| 272 | var pageHeight = this.getPageHeight(this.page); |
---|
| 273 | this.averageRowHeight = (pageHeight > 0 && rowsOnPage > 0) ? (pageHeight / rowsOnPage) : 0; |
---|
| 274 | }, |
---|
| 275 | calcLastPageHeight: function(){ |
---|
| 276 | if(!this.pageCount){ |
---|
| 277 | return 0; |
---|
| 278 | } |
---|
| 279 | var lastPage = this.pageCount - 1; |
---|
| 280 | var lastPageHeight = ((this.rowCount % this.rowsPerPage)||(this.rowsPerPage)) * this.defaultRowHeight; |
---|
| 281 | this.pageHeights[lastPage] = lastPageHeight; |
---|
| 282 | return lastPageHeight; |
---|
| 283 | }, |
---|
| 284 | updateContentHeight: function(inDh){ |
---|
| 285 | this.height += inDh; |
---|
| 286 | this.resize(); |
---|
| 287 | }, |
---|
| 288 | updatePageHeight: function(inPageIndex, fromBuild, fromAsynRendering){ |
---|
| 289 | if(this.pageExists(inPageIndex)){ |
---|
| 290 | var oh = this.getPageHeight(inPageIndex); |
---|
| 291 | var h = (this.measurePage(inPageIndex)); |
---|
| 292 | if(h === undefined){ |
---|
| 293 | h = oh; |
---|
| 294 | } |
---|
| 295 | this.pageHeights[inPageIndex] = h; |
---|
| 296 | if(oh != h){ |
---|
| 297 | this.updateContentHeight(h - oh); |
---|
| 298 | var ah = this.grid.get("autoHeight"); |
---|
| 299 | if((typeof ah == "number" && ah > this.rowCount)||(ah === true && !fromBuild)){ |
---|
| 300 | if(!fromAsynRendering){ |
---|
| 301 | this.grid.sizeChange(); |
---|
| 302 | }else{//fix #11101 by using fromAsynRendering to avoid deadlock |
---|
| 303 | var ns = this.grid.viewsNode.style; |
---|
| 304 | ns.height = parseInt(ns.height) + h - oh + 'px'; |
---|
| 305 | this.repositionPages(inPageIndex); |
---|
| 306 | } |
---|
| 307 | }else{ |
---|
| 308 | this.repositionPages(inPageIndex); |
---|
| 309 | } |
---|
| 310 | } |
---|
| 311 | return h; |
---|
| 312 | } |
---|
| 313 | return 0; |
---|
| 314 | }, |
---|
| 315 | rowHeightChanged: function(inRowIndex, fromAsynRendering){ |
---|
| 316 | this.updatePageHeight(Math.floor(inRowIndex / this.rowsPerPage), false, fromAsynRendering); |
---|
| 317 | }, |
---|
| 318 | // scroller core |
---|
| 319 | invalidateNodes: function(){ |
---|
| 320 | while(this.stack.length){ |
---|
| 321 | this.destroyPage(this.popPage()); |
---|
| 322 | } |
---|
| 323 | }, |
---|
| 324 | createPageNode: function(){ |
---|
| 325 | var p = document.createElement('div'); |
---|
| 326 | html.attr(p,"role","presentation"); |
---|
| 327 | p.style.position = 'absolute'; |
---|
| 328 | //p.style.width = '100%'; |
---|
| 329 | p.style[this.grid.isLeftToRight() ? "left" : "right"] = '0'; |
---|
| 330 | return p; |
---|
| 331 | }, |
---|
| 332 | getPageHeight: function(inPageIndex){ |
---|
| 333 | var ph = this.pageHeights[inPageIndex]; |
---|
| 334 | return (ph !== undefined ? ph : this.defaultPageHeight); |
---|
| 335 | }, |
---|
| 336 | // FIXME: this is not a stack, it's a FIFO list |
---|
| 337 | pushPage: function(inPageIndex){ |
---|
| 338 | return this.stack.push(inPageIndex); |
---|
| 339 | }, |
---|
| 340 | popPage: function(){ |
---|
| 341 | return this.stack.shift(); |
---|
| 342 | }, |
---|
| 343 | findPage: function(inTop){ |
---|
| 344 | var i = 0, h = 0; |
---|
| 345 | for(var ph = 0; i<this.pageCount; i++, h += ph){ |
---|
| 346 | ph = this.getPageHeight(i); |
---|
| 347 | if(h + ph >= inTop){ |
---|
| 348 | break; |
---|
| 349 | } |
---|
| 350 | } |
---|
| 351 | this.page = i; |
---|
| 352 | this.pageTop = h; |
---|
| 353 | }, |
---|
| 354 | buildPage: function(inPageIndex, inReuseNode, inPos){ |
---|
| 355 | this.preparePage(inPageIndex, inReuseNode); |
---|
| 356 | this.positionPage(inPageIndex, inPos); |
---|
| 357 | // order of operations is key below |
---|
| 358 | this.installPage(inPageIndex); |
---|
| 359 | this.renderPage(inPageIndex); |
---|
| 360 | // order of operations is key above |
---|
| 361 | this.pushPage(inPageIndex); |
---|
| 362 | }, |
---|
| 363 | needPage: function(inPageIndex, inPos){ |
---|
| 364 | var h = this.getPageHeight(inPageIndex), oh = h; |
---|
| 365 | if(!this.pageExists(inPageIndex)){ |
---|
| 366 | this.buildPage(inPageIndex, (!this.grid._autoHeight/*fix #10543*/ && this.keepPages&&(this.stack.length >= this.keepPages)), inPos); |
---|
| 367 | h = this.updatePageHeight(inPageIndex, true); |
---|
| 368 | }else{ |
---|
| 369 | this.positionPage(inPageIndex, inPos); |
---|
| 370 | } |
---|
| 371 | return h; |
---|
| 372 | }, |
---|
| 373 | onscroll: function(){ |
---|
| 374 | this.scroll(this.scrollboxNode.scrollTop); |
---|
| 375 | }, |
---|
| 376 | scroll: function(inTop){ |
---|
| 377 | this.grid.scrollTop = inTop; |
---|
| 378 | if(this.colCount){ |
---|
| 379 | this.startPacify(); |
---|
| 380 | this.findPage(inTop); |
---|
| 381 | var h = this.height; |
---|
| 382 | var b = this.getScrollBottom(inTop); |
---|
| 383 | for(var p=this.page, y=this.pageTop; (p<this.pageCount)&&((b<0)||(y<b)); p++){ |
---|
| 384 | y += this.needPage(p, y); |
---|
| 385 | } |
---|
| 386 | this.firstVisibleRow = this.getFirstVisibleRow(this.page, this.pageTop, inTop); |
---|
| 387 | this.lastVisibleRow = this.getLastVisibleRow(p - 1, y, b); |
---|
| 388 | // indicates some page size has been updated |
---|
| 389 | if(h != this.height){ |
---|
| 390 | this.repositionPages(p-1); |
---|
| 391 | } |
---|
| 392 | this.endPacify(); |
---|
| 393 | } |
---|
| 394 | }, |
---|
| 395 | getScrollBottom: function(inTop){ |
---|
| 396 | return (this.windowHeight >= 0 ? inTop + this.windowHeight : -1); |
---|
| 397 | }, |
---|
| 398 | // events |
---|
| 399 | processNodeEvent: function(e, inNode){ |
---|
| 400 | var t = e.target; |
---|
| 401 | while(t && (t != inNode) && t.parentNode && (t.parentNode.parentNode != inNode)){ |
---|
| 402 | t = t.parentNode; |
---|
| 403 | } |
---|
| 404 | if(!t || !t.parentNode || (t.parentNode.parentNode != inNode)){ |
---|
| 405 | return false; |
---|
| 406 | } |
---|
| 407 | var page = t.parentNode; |
---|
| 408 | e.topRowIndex = page.pageIndex * this.rowsPerPage; |
---|
| 409 | e.rowIndex = e.topRowIndex + indexInParent(t); |
---|
| 410 | e.rowTarget = t; |
---|
| 411 | return true; |
---|
| 412 | }, |
---|
| 413 | processEvent: function(e){ |
---|
| 414 | return this.processNodeEvent(e, this.contentNode); |
---|
| 415 | }, |
---|
| 416 | // virtual rendering interface |
---|
| 417 | renderRow: function(inRowIndex, inPageNode){ |
---|
| 418 | }, |
---|
| 419 | removeRow: function(inRowIndex){ |
---|
| 420 | }, |
---|
| 421 | // page node operations |
---|
| 422 | getDefaultPageNode: function(inPageIndex){ |
---|
| 423 | return this.getDefaultNodes()[inPageIndex]; |
---|
| 424 | }, |
---|
| 425 | positionPageNode: function(inNode, inPos){ |
---|
| 426 | }, |
---|
| 427 | getPageNodePosition: function(inNode){ |
---|
| 428 | return inNode.offsetTop; |
---|
| 429 | }, |
---|
| 430 | invalidatePageNode: function(inPageIndex, inNodes){ |
---|
| 431 | var p = inNodes[inPageIndex]; |
---|
| 432 | if(p){ |
---|
| 433 | delete inNodes[inPageIndex]; |
---|
| 434 | this.removePage(inPageIndex, p); |
---|
| 435 | cleanNode(p); |
---|
| 436 | p.innerHTML = ''; |
---|
| 437 | } |
---|
| 438 | return p; |
---|
| 439 | }, |
---|
| 440 | // scroll control |
---|
| 441 | getPageRow: function(inPage){ |
---|
| 442 | return inPage * this.rowsPerPage; |
---|
| 443 | }, |
---|
| 444 | getLastPageRow: function(inPage){ |
---|
| 445 | return Math.min(this.rowCount, this.getPageRow(inPage + 1)) - 1; |
---|
| 446 | }, |
---|
| 447 | getFirstVisibleRow: function(inPage, inPageTop, inScrollTop){ |
---|
| 448 | if(!this.pageExists(inPage)){ |
---|
| 449 | return 0; |
---|
| 450 | } |
---|
| 451 | var row = this.getPageRow(inPage); |
---|
| 452 | var nodes = this.getDefaultNodes(); |
---|
| 453 | var rows = divkids(nodes[inPage]); |
---|
| 454 | for(var i=0,l=rows.length; i<l && inPageTop<inScrollTop; i++, row++){ |
---|
| 455 | inPageTop += rows[i].offsetHeight; |
---|
| 456 | } |
---|
| 457 | return (row ? row - 1 : row); |
---|
| 458 | }, |
---|
| 459 | getLastVisibleRow: function(inPage, inBottom, inScrollBottom){ |
---|
| 460 | if(!this.pageExists(inPage)){ |
---|
| 461 | return 0; |
---|
| 462 | } |
---|
| 463 | var nodes = this.getDefaultNodes(); |
---|
| 464 | var row = this.getLastPageRow(inPage); |
---|
| 465 | var rows = divkids(nodes[inPage]); |
---|
| 466 | for(var i=rows.length-1; i>=0 && inBottom>inScrollBottom; i--, row--){ |
---|
| 467 | inBottom -= rows[i].offsetHeight; |
---|
| 468 | } |
---|
| 469 | return row + 1; |
---|
| 470 | }, |
---|
| 471 | findTopRow: function(inScrollTop){ |
---|
| 472 | var nodes = this.getDefaultNodes(); |
---|
| 473 | var rows = divkids(nodes[this.page]); |
---|
| 474 | for(var i=0,l=rows.length,t=this.pageTop,h; i<l; i++){ |
---|
| 475 | h = rows[i].offsetHeight; |
---|
| 476 | t += h; |
---|
| 477 | if(t >= inScrollTop){ |
---|
| 478 | this.offset = h - (t - inScrollTop); |
---|
| 479 | return i + this.page * this.rowsPerPage; |
---|
| 480 | } |
---|
| 481 | } |
---|
| 482 | return -1; |
---|
| 483 | }, |
---|
| 484 | findScrollTop: function(inRow){ |
---|
| 485 | var rowPage = Math.floor(inRow / this.rowsPerPage); |
---|
| 486 | var t = 0; |
---|
| 487 | var i, l; |
---|
| 488 | for(i=0; i<rowPage; i++){ |
---|
| 489 | t += this.getPageHeight(i); |
---|
| 490 | } |
---|
| 491 | this.pageTop = t; |
---|
| 492 | this.page = rowPage;//fix #10543 |
---|
| 493 | this.needPage(rowPage, this.pageTop); |
---|
| 494 | |
---|
| 495 | var nodes = this.getDefaultNodes(); |
---|
| 496 | var rows = divkids(nodes[rowPage]); |
---|
| 497 | var r = inRow - this.rowsPerPage * rowPage; |
---|
| 498 | for(i=0,l=rows.length; i<l && i<r; i++){ |
---|
| 499 | t += rows[i].offsetHeight; |
---|
| 500 | } |
---|
| 501 | return t; |
---|
| 502 | }, |
---|
| 503 | dummy: 0 |
---|
| 504 | }); |
---|
| 505 | }); |
---|