From 82ed57e41f789cda3984e75d6b8853d1ad855c1e Mon Sep 17 00:00:00 2001 From: David Back Date: Wed, 5 Sep 2018 17:59:03 -0700 Subject: [PATCH] triple list structure, added columns, sorting --- scripts/system/html/entityListNew.html | 37 +- scripts/system/html/js/entityListNew.js | 438 ++++++++++++++++-------- scripts/system/html/js/listView.js | 100 ++---- 3 files changed, 368 insertions(+), 207 deletions(-) diff --git a/scripts/system/html/entityListNew.html b/scripts/system/html/entityListNew.html index 1411286414..50488db6c7 100644 --- a/scripts/system/html/entityListNew.html +++ b/scripts/system/html/entityListNew.html @@ -40,19 +40,50 @@
- + + + + + + + + + + + - + + + + + + + + + + + - + + + + + + + + + + + + diff --git a/scripts/system/html/js/entityListNew.js b/scripts/system/html/js/entityListNew.js index 01b9785444..cda6907266 100644 --- a/scripts/system/html/js/entityListNew.js +++ b/scripts/system/html/js/entityListNew.js @@ -6,12 +6,56 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -var entities = {}; +const ASCENDING_SORT = 1; +const DESCENDING_SORT = -1; +const ASCENDING_STRING = '▴'; +const DESCENDING_STRING = '▾'; +const COMPARE_ASCENDING = function(a, b) { + let va = a[currentSortColumn]; + let vb = b[currentSortColumn]; + + if (va < vb) { + return -1; + } else if (va > vb) { + return 1; + } + return 0; +} +const COMPARE_DESCENDING = function(a, b) { + return COMPARE_ASCENDING(b, a); +} +const LOCKED_GLYPH = ""; +const VISIBLE_GLYPH = ""; +const TRANSPARENCY_GLYPH = ""; +const BAKED_GLYPH = "" +const SCRIPT_GLYPH = "k"; +const BYTES_PER_MEGABYTE = 1024 * 1024; +const IMAGE_MODEL_NAME = 'default-image-model.fbx'; +const NUM_COLUMNS = 12; + +var entities = []; +var entitiesByID = {}; +var visibleEntities = []; + var selectedEntities = []; + var currentSortColumn = 'type'; var currentSortOrder = 'des'; + var entityList = null; -var refreshEntityListTimer = null; + +const ENABLE_PROFILING = true; +var profileIndent = ''; +const PROFILE = !ENABLE_PROFILING ? function() { } : function(name, fn, args) { + console.log("PROFILE-Web " + profileIndent + "(" + name + ") Begin"); + var previousIndent = profileIndent; + profileIndent += ' '; + var before = Date.now(); + fn.apply(this, args); + var delta = Date.now() - before; + profileIndent = previousIndent; + console.log("PROFILE-Web " + profileIndent + "(" + name + ") End " + delta + "ms"); +}; debugPrint = function (message) { console.log(message); @@ -34,24 +78,80 @@ function loaded() { elExport = document.getElementById("export"); elPal = document.getElementById("pal"); elInfoToggle = document.getElementById("info-toggle"); - //elInfoToggleGlyph = elInfoToggle.firstChild; + elInfoToggleGlyph = elInfoToggle.firstChild; elFooter = document.getElementById("footer-text"); elNoEntitiesMessage = document.getElementById("no-entities"); elNoEntitiesInView = document.getElementById("no-entities-in-view"); elNoEntitiesRadius = document.getElementById("no-entities-radius"); entityList = new ListView("entity-table", "entity-table-body", "entity-table-scroll", createRowFunction, updateRowFunction, clearRowFunction); + + document.getElementById("entity-name").onclick = function() { + setSortColumn('name'); + }; + document.getElementById("entity-type").onclick = function() { + setSortColumn('type'); + }; + document.getElementById("entity-url").onclick = function() { + setSortColumn('url'); + }; + document.getElementById("entity-locked").onclick = function () { + setSortColumn('locked'); + }; + document.getElementById("entity-visible").onclick = function () { + setSortColumn('visible'); + }; + document.getElementById("entity-verticesCount").onclick = function () { + setSortColumn('verticesCount'); + }; + document.getElementById("entity-texturesCount").onclick = function () { + setSortColumn('texturesCount'); + }; + document.getElementById("entity-texturesSize").onclick = function () { + setSortColumn('texturesSize'); + }; + document.getElementById("entity-hasTransparent").onclick = function () { + setSortColumn('hasTransparent'); + }; + document.getElementById("entity-isBaked").onclick = function () { + setSortColumn('isBaked'); + }; + document.getElementById("entity-drawCalls").onclick = function () { + setSortColumn('drawCalls'); + }; + document.getElementById("entity-hasScript").onclick = function () { + setSortColumn('hasScript'); + }; + + elRefresh.onclick = function() { + refreshEntities(); + } + elToggleLocked.onclick = function() { + EventBridge.emitWebEvent(JSON.stringify({ type: 'toggleLocked' })); + } + elToggleVisible.onclick = function() { + EventBridge.emitWebEvent(JSON.stringify({ type: 'toggleVisible' })); + } + elExport.onclick = function() { + EventBridge.emitWebEvent(JSON.stringify({ type: 'export'})); + } + elPal.onclick = function() { + EventBridge.emitWebEvent(JSON.stringify({ type: 'pal' })); + } + elDelete.onclick = function() { + EventBridge.emitWebEvent(JSON.stringify({ type: 'delete' })); + } function createRowFunction(elBottomBuffer) { var row = document.createElement("tr"); - var typeCell = document.createElement("td"); - var typeCellText = document.createTextNode(""); - var nameCell = document.createElement("td"); - var nameCellText = document.createTextNode(""); - typeCell.appendChild(typeCellText); - nameCell.appendChild(nameCellText); - row.appendChild(typeCell); - row.appendChild(nameCell); + for (var i = 0; i < NUM_COLUMNS; i++) { + var column = document.createElement("td"); + // locked, visible, hasTransparent, isBaked glyph columns + if (i === 3 || i === 4 || i === 8 || i === 9) { + column.className = 'glyph'; + } + row.appendChild(column); + } row.onclick = onRowClicked; row.ondblclick = onRowDoubleClicked; elEntityTableBody.insertBefore(row, elBottomBuffer); @@ -60,33 +160,59 @@ function loaded() { function updateRowFunction(elRow, itemData) { var typeCell = elRow.childNodes[0]; + typeCell.innerText = itemData.type; var nameCell = elRow.childNodes[1]; - typeCell.innerHTML = itemData.type; - nameCell.innerHTML = itemData.name; + nameCell.innerText = itemData.name; + var urlCell = elRow.childNodes[2]; + urlCell.innerText = itemData.url; + var lockedCell = elRow.childNodes[3]; + lockedCell.innerHTML = itemData.locked; + var visibleCell = elRow.childNodes[4]; + visibleCell.innerHTML = itemData.visible; + var verticesCountCell = elRow.childNodes[5]; + verticesCountCell.innerText = itemData.verticesCount; + var texturesCountCell = elRow.childNodes[6]; + texturesCountCell.innerText = itemData.texturesCount; + var texturesSizeCell = elRow.childNodes[7]; + texturesSizeCell.innerText = itemData.texturesSize; + var hasTransparentCell = elRow.childNodes[8]; + hasTransparentCell.innerHTML = itemData.hasTransparent; + var isBakedCell = elRow.childNodes[9]; + isBakedCell.innerHTML = itemData.isBaked; + var drawCallsCell = elRow.childNodes[10]; + drawCallsCell.innerText = itemData.drawCalls; + var hasScriptCell = elRow.childNodes[11]; + hasScriptCell.innerText = itemData.hasScript; - var id = elRow.getAttribute("id"); - entities[id].el = elRow; + var prevItemId = elRow.getAttribute("id"); + var newItemId = itemData.id; + if (prevItemId && prevItemId !== newItemId) { + entitiesByID[prevItemId].elRow = null; + } + if (!prevItemId || prevItemId !== newItemId) { + elRow.setAttribute("id", newItemId); + entitiesByID[newItemId].elRow = elRow; + } } function clearRowFunction(elRow) { - var typeCell = elRow.childNodes[0]; - var nameCell = elRow.childNodes[1]; - typeCell.innerHTML = ""; - nameCell.innerHTML = ""; - + for (var i = 0; i < NUM_COLUMNS; i++) { + var cell = elRow.childNodes[i]; + cell.innerHTML = ""; + } + var id = elRow.getAttribute("id"); - if (id && entities[id]) { - entities[id].el = null; + if (id && entitiesByID[id]) { + entitiesByID[id].elRow = null; } } function onRowClicked(clickEvent) { - var id = this.getAttribute("id"); - var selection = [id]; + var entityID = this.getAttribute("id"); + var selection = [entityID]; - /* if (clickEvent.ctrlKey) { - var selectedIndex = selectedEntities.indexOf(id); + var selectedIndex = selectedEntities.indexOf(entityID); if (selectedIndex >= 0) { selection = selectedEntities; selection.splice(selectedIndex, 1) @@ -96,11 +222,12 @@ function loaded() { } else if (clickEvent.shiftKey && selectedEntities.length > 0) { var previousItemFound = -1; var clickedItemFound = -1; - for (var entity in entityList.visibleItems) { - if (clickedItemFound === -1 && this.dataset.entityId == entityList.visibleItems[entity].values().id) { - clickedItemFound = entity; - } else if(previousItemFound === -1 && selectedEntities[0] == entityList.visibleItems[entity].values().id) { - previousItemFound = entity; + for (var i = 0; i < visibleEntities.length; i++) { + var entity = visibleEntities[i]; + if (clickedItemFound === -1 && entityID == entity.id) { + clickedItemFound = i; + } else if(previousItemFound === -1 && selectedEntities[0] == entity.id) { + previousItemFound = i; } } if (previousItemFound !== -1 && clickedItemFound !== -1) { @@ -108,8 +235,8 @@ function loaded() { var toItem = Math.max(previousItemFound, clickedItemFound); // skip first and last item in this loop, we add them to selection after the loop for (var i = (Math.min(previousItemFound, clickedItemFound) + 1); i < toItem; i++) { - entityList.visibleItems[i].elm.className = 'selected'; - betweenItems.push(entityList.visibleItems[i].values().id); + visibleEntities[i].elRow.className = 'selected'; + betweenItems.push(visibleEntities[i].id); } if (previousItemFound > clickedItemFound) { // always make sure that we add the items in the right order @@ -118,7 +245,6 @@ function loaded() { selection = selection.concat(betweenItems, selectedEntities); } } - */ selectedEntities = selection; @@ -134,73 +260,45 @@ function loaded() { } function onRowDoubleClicked() { - var id = this.getAttribute("id"); + var entityID = this.getAttribute("id"); EventBridge.emitWebEvent(JSON.stringify({ type: "selectionUpdate", focus: true, - entityIds: [id], + entityIds: [entityID], })); } - function addEntity(id, name, type) { - //var urlParts = url.split('/'); - //var filename = urlParts[urlParts.length - 1]; - - var IMAGE_MODEL_NAME = 'default-image-model.fbx'; - - //if (filename === IMAGE_MODEL_NAME) { - // type = "Image"; - //} - - if (entities[id] === undefined) { - var entityData = {name: name, type: type}; - entityList.addItem(id, entityData); - entityData.el = null; - entities[id] = entityData; - } - } - - function removeEntities(deletedIDs) { - for (var i = 0, length = deletedIDs.length; i < length; i++) { - var deleteID = deletedIDs[i]; - delete entities[deleteID]; - entityList.removeItem(deleteID); - } - } - - function scheduleRefreshEntityList() { - var REFRESH_DELAY = 50; - if (refreshEntityListTimer) { - clearTimeout(refreshEntityListTimer); - } - refreshEntityListTimer = setTimeout(refreshEntityListObject, REFRESH_DELAY); - } - - function clearEntities() { - entities = {}; - entityList.clear(); - refreshFooter(); - } - var elSortOrder = { name: document.querySelector('#entity-name .sort-order'), type: document.querySelector('#entity-type .sort-order'), + url: document.querySelector('#entity-url .sort-order'), + locked: document.querySelector('#entity-locked .sort-order'), + visible: document.querySelector('#entity-visible .sort-order'), + verticesCount: document.querySelector('#entity-verticesCount .sort-order'), + texturesCount: document.querySelector('#entity-texturesCount .sort-order'), + texturesSize: document.querySelector('#entity-texturesSize .sort-order'), + hasTransparent: document.querySelector('#entity-hasTransparent .sort-order'), + isBaked: document.querySelector('#entity-isBaked .sort-order'), + drawCalls: document.querySelector('#entity-drawCalls .sort-order'), + hasScript: document.querySelector('#entity-hasScript .sort-order'), } function setSortColumn(column) { - if (currentSortColumn == column) { - currentSortOrder = currentSortOrder == "asc" ? "desc" : "asc"; - } else { - elSortOrder[currentSortColumn].innerHTML = ""; - currentSortColumn = column; - currentSortOrder = "asc"; - } - elSortOrder[column].innerHTML = currentSortOrder == "asc" ? ASCENDING_STRING : DESCENDING_STRING; - //entityList.sort(currentSortColumn, { order: currentSortOrder }); + PROFILE("set-sort-column", function() { + if (currentSortColumn === column) { + currentSortOrder *= -1; + } else { + elSortOrder[currentSortColumn].innerHTML = ""; + currentSortColumn = column; + currentSortOrder = ASCENDING_SORT; + } + elSortOrder[column].innerHTML = currentSortOrder == ASCENDING_SORT ? ASCENDING_STRING : DESCENDING_STRING; + refreshEntityList(); + }); } - - function refreshEntities() { - clearEntities(); - EventBridge.emitWebEvent(JSON.stringify({ type: 'refresh' })); + + function clearEntities() { + entities = {}; + refreshFooter(); } function refreshFooter() { @@ -208,26 +306,102 @@ function loaded() { elFooter.firstChild.nodeValue = selectedEntities.length + " entities selected"; } else if (selectedEntities.length === 1) { elFooter.firstChild.nodeValue = "1 entity selected"; - } /* else if (entityList.visibleItems.length === 1) { + } else if (visibleEntities.length === 1) { elFooter.firstChild.nodeValue = "1 entity found"; } else { - elFooter.firstChild.nodeValue = entityList.visibleItems.length + " entities found"; - } */ + elFooter.firstChild.nodeValue = visibleEntities.length + " entities found"; + } + } + + function refreshEntities() { + clearEntities(); + EventBridge.emitWebEvent(JSON.stringify({ type: 'refresh' })); } - function refreshEntityListObject() { - refreshEntityListTimer = null; - //entityList.sort(currentSortColumn, { order: currentSortOrder }); - //entityList.search(elFilter.value); - entityList.refresh(); - refreshFooter(); + function refreshEntityList() { + PROFILE("refresh-entity-list", function() { + PROFILE("filter", function() { + var searchTerm = elFilter.value; + if (searchTerm === '') { + visibleEntities = entities.slice(0); + } else { + visibleEntities = entities.filter(function(e) { + return e.name.indexOf(searchTerm) > -1 + || e.type.indexOf(searchTerm) > -1 + || e.fullUrl.indexOf(searchTerm) > -1; + }); + } + }); + + PROFILE("sort", function() { + var cmp = currentSortOrder === ASCENDING_SORT ? COMPARE_ASCENDING : COMPARE_DESCENDING; + visibleEntities.sort(cmp); + }); + + PROFILE("update-dom", function() { + entityList.setVisibleItemData(visibleEntities); + entityList.refresh(); + }); + + refreshFooter(); + }); + } + + function decimalMegabytes(number) { + return number ? (number / BYTES_PER_MEGABYTE).toFixed(1) : ""; + } + + function displayIfNonZero(number) { + return number ? number : ""; + } + + function getFilename(url) { + var urlParts = url.split('/'); + return urlParts[urlParts.length - 1]; + } + + function updateEntityData(entityData) { + entities = []; + entitiesByID = {}; + visibleEntities = []; + + PROFILE("map-data", function() { + entityData.forEach(function(entity) { + var type = entity.type + var filename = getFilename(entity.url); + if (filename === IMAGE_MODEL_NAME) { + type = "Image"; + } + + var entityData = { + id: entity.id, + name: entity.name, + type: type, + url: filename, + fullUrl: entity.url, + locked: entity.locked ? LOCKED_GLYPH : null, + visible: entity.visible ? VISIBLE_GLYPH : null, + verticesCount: displayIfNonZero(entity.verticesCount), + texturesCount: displayIfNonZero(entity.texturesCount), + texturesSize: decimalMegabytes(entity.texturesSize), + hasTransparent: entity.hasTransparent ? TRANSPARENCY_GLYPH : null, + isBaked: entity.isBaked ? BAKED_GLYPH : null, + drawCalls: displayIfNonZero(entity.drawCalls), + hasScript: entity.hasScript ? SCRIPT_GLYPH : null, + elRow : null + } + + entities.push(entityData); + entitiesByID[entityData.id] = entityData; + }); + }); } function updateSelectedEntities(selectedIDs) { var notFound = false; - for (var id in entities) { - if (entities[id].el) { - entities[id].el.className = ''; + for (var id in entitiesByID) { + if (entitiesByID[id].elRow) { + entitiesByID[id].elRow.className = ''; } } @@ -236,8 +410,8 @@ function loaded() { var id = selectedIDs[i]; selectedEntities.push(id); if (id in entities) { - var entity = entities[id]; - entity.el.className = 'selected'; + var entity = entitiesByID[id]; + entity.elRow.className = 'selected'; } else { notFound = true; } @@ -247,6 +421,13 @@ function loaded() { return notFound; } + + function removeEntities(deletedIDs) { + for (var i = 0, length = deletedIDs.length; i < length; i++) { + var deleteID = deletedIDs[i]; + delete entitiesByID[deleteID]; + } + } function resize() { // Take up available window space @@ -278,9 +459,9 @@ function loaded() { } else { ths[0].width = 0.16 * tableWidth; ths[1].width = 0.34 * tableWidth; - //ths[2].width = 0.34 * tableWidth; - //ths[3].width = 0.08 * tableWidth; - //ths[4].width = 0.08 * tableWidth; + ths[2].width = 0.34 * tableWidth; + ths[3].width = 0.08 * tableWidth; + ths[4].width = 0.08 * tableWidth; } } }; @@ -302,25 +483,6 @@ function loaded() { event.stopPropagation(); } elInfoToggle.addEventListener("click", toggleInfo, true); - - elRefresh.onclick = function() { - refreshEntities(); - } - elToggleLocked.onclick = function() { - EventBridge.emitWebEvent(JSON.stringify({ type: 'toggleLocked' })); - } - elToggleVisible.onclick = function() { - EventBridge.emitWebEvent(JSON.stringify({ type: 'toggleVisible' })); - } - elExport.onclick = function() { - EventBridge.emitWebEvent(JSON.stringify({ type: 'export'})); - } - elPal.onclick = function() { - EventBridge.emitWebEvent(JSON.stringify({ type: 'pal' })); - } - elDelete.onclick = function() { - EventBridge.emitWebEvent(JSON.stringify({ type: 'delete' })); - } document.addEventListener("keydown", function (keyDownEvent) { if (keyDownEvent.target.nodeName === "INPUT") { @@ -374,24 +536,21 @@ function loaded() { refreshEntities(); } } else if (data.type === "update" && data.selectedIDs !== undefined) { - var newEntities = data.entities; - if (newEntities && newEntities.length == 0) { - elNoEntitiesMessage.style.display = "block"; - elFooter.firstChild.nodeValue = "0 entities found"; - } else if (newEntities) { - elNoEntitiesMessage.style.display = "none"; - for (var i = 0; i < newEntities.length; i++) { - addEntity(newEntities[i].id, newEntities[i].name, newEntities[i].type); + PROFILE("update", function() { + var newEntities = data.entities; + if (newEntities && newEntities.length == 0) { + elNoEntitiesMessage.style.display = "block"; + elFooter.firstChild.nodeValue = "0 entities found"; + } else if (newEntities) { + elNoEntitiesMessage.style.display = "none"; + updateEntityData(newEntities); + refreshEntityList(); + updateSelectedEntities(data.selectedIDs); } - updateSelectedEntities(data.selectedIDs); - entityList.refresh(); - //scheduleRefreshEntityList(); - resize(); - } + }); } else if (data.type === "removeEntities" && data.deletedIDs !== undefined && data.selectedIDs !== undefined) { removeEntities(data.deletedIDs); updateSelectedEntities(data.selectedIDs); - //scheduleRefreshEntityList(); } else if (data.type === "deleted" && data.ids) { removeEntities(data.ids); refreshFooter(); @@ -399,6 +558,7 @@ function loaded() { }); } + setSortColumn('type'); resize(); entityList.initialize(572); refreshEntities(); diff --git a/scripts/system/html/js/listView.js b/scripts/system/html/js/listView.js index 729114bfdf..e0a9e4c0c0 100644 --- a/scripts/system/html/js/listView.js +++ b/scripts/system/html/js/listView.js @@ -22,30 +22,16 @@ ListView = function(tableId, tableBodyId, tableScrollId, createRowFunction, upda var elTopBuffer = null; var elBottomBuffer = null; - - var itemData = {}; + + var visibleItemData = []; var rowOffset = 0; var numRows = 0; var rowHeight = 0; var lastRowChangeScrollTop = 0; - that.addItem = function(id, data) { - if (itemData[id] === undefined) { - itemData[id] = data; - } - }; - - that.updateItem = function(id, data) { - if (itemData[id] !== undefined) { - - } - }; - - that.removeItem = function(id) { - if (itemData[id] !== undefined) { - delete itemData[id]; - } + that.setVisibleItemData = function(itemData) { + visibleItemData = itemData; }; that.clear = function() { @@ -63,23 +49,16 @@ ListView = function(tableId, tableBodyId, tableScrollId, createRowFunction, upda }; - that.scrollDown = function(numScrollRows) { + that.scrollDown = function(numScrollRows) { var prevTopHeight = parseInt(elTopBuffer.getAttribute("height")); var prevBottomHeight = parseInt(elBottomBuffer.getAttribute("height")); for (var i = 0; i < numScrollRows; i++) { - var topRow = elTableBody.childNodes[FIRST_ROW_INDEX]; - elTableBody.removeChild(topRow); - elTableBody.insertBefore(topRow, elBottomBuffer); - var rowIndex = 0; - for (var id in itemData) { - if (rowIndex === numRows + rowOffset) { - topRow.setAttribute("id", id); - updateRowFunction(topRow, itemData[id]); - break; - } - rowIndex++; - } + var rowMovedTopToBottom = elTableBody.childNodes[FIRST_ROW_INDEX]; + var rowIndex = numRows + rowOffset; + elTableBody.removeChild(rowMovedTopToBottom); + elTableBody.insertBefore(rowMovedTopToBottom, elBottomBuffer); + updateRowFunction(rowMovedTopToBottom, visibleItemData[rowIndex]); rowOffset++; } @@ -90,24 +69,17 @@ ListView = function(tableId, tableBodyId, tableScrollId, createRowFunction, upda lastRowChangeScrollTop += rowHeight * numScrollRows; }; - that.scrollUp = function(numScrollRows) { + that.scrollUp = function(numScrollRows) { var prevTopHeight = parseInt(elTopBuffer.getAttribute("height")); var prevBottomHeight = parseInt(elBottomBuffer.getAttribute("height")); - + for (var i = 0; i < numScrollRows; i++) { var topRow = elTableBody.childNodes[FIRST_ROW_INDEX]; - var bottomRow = elTableBody.childNodes[FIRST_ROW_INDEX + numRows - 1]; - elTableBody.removeChild(bottomRow); - elTableBody.insertBefore(bottomRow, topRow); - var rowIndex = 0; - for (var id in itemData) { - if (rowIndex === rowOffset - 1) { - bottomRow.setAttribute("id", id); - updateRowFunction(bottomRow, itemData[id]); - break; - } - rowIndex++; - } + var rowMovedBottomToTop = elTableBody.childNodes[FIRST_ROW_INDEX + numRows - 1]; + var rowIndex = rowOffset - 1; + elTableBody.removeChild(rowMovedBottomToTop); + elTableBody.insertBefore(rowMovedBottomToTop, topRow); + updateRowFunction(rowMovedBottomToTop, visibleItemData[rowIndex]); rowOffset--; } @@ -121,14 +93,14 @@ ListView = function(tableId, tableBodyId, tableScrollId, createRowFunction, upda that.onScroll = function() { var scrollTop = elTableScroll.scrollTop; var nextRowChangeScrollTop = lastRowChangeScrollTop + (rowHeight * SCROLL_ROWS); - var totalItems = Object.keys(itemData).length; var scrollHeight = rowHeight * SCROLL_ROWS; + var totalItems = visibleItemData.length; if (scrollTop >= nextRowChangeScrollTop && numRows + rowOffset < totalItems) { var numScrolls = Math.ceil((scrollTop - nextRowChangeScrollTop) / scrollHeight); var numScrollRows = numScrolls * SCROLL_ROWS; - if (numScrollRows + rowOffset > totalItems) { - numScrollRows = totalItems - rowOffset; + if (numScrollRows + rowOffset + numRows > totalItems) { + numScrollRows = totalItems - rowOffset - numRows; } that.scrollDown(numScrollRows); } else if (scrollTop < lastRowChangeScrollTop && rowOffset >= SCROLL_ROWS) { @@ -142,25 +114,23 @@ ListView = function(tableId, tableBodyId, tableScrollId, createRowFunction, upda }; that.refresh = function() { - var rowIndex = 0; - for (var id in itemData) { - if (rowIndex >= rowOffset) { - var rowElementIndex = rowIndex + FIRST_ROW_INDEX; - var elRow = elTableBody.childNodes[rowElementIndex]; - var data = itemData[id]; - elRow.setAttribute("id", id); - updateRowFunction(elRow, data); - } - - rowIndex++; - - if (rowIndex - rowOffset === numRows) { - break; - } + // block refreshing before rows are initialized + if (numRows === 0) { + return; } - var totalItems = Object.keys(itemData).length; - var bottomHiddenRows = totalItems - numRows - rowOffset; + for (var i = 0; i < numRows; i++) { + var rowIndex = i + rowOffset; + if (rowIndex >= visibleItemData.length) { + break; + } + var rowElementIndex = i + FIRST_ROW_INDEX; + var elRow = elTableBody.childNodes[rowElementIndex]; + var itemData = visibleItemData[rowIndex]; + updateRowFunction(elRow, itemData); + } + + var bottomHiddenRows = visibleItemData.length - numRows - rowOffset; var bottomBufferHeight = rowHeight * bottomHiddenRows; if (bottomHiddenRows < 0) { bottomBufferHeight = 0;
TypeDTypeD NameFileVertsTextsText MBBakedDrawsk