<commit_before>// import Mantissa

Mantissa.ScrollTable = {};

Mantissa.ScrollTable.ScrollingWidget = Nevow.Athena.Widget.subclass('Mantissa.ScrollTable.ScrollingWidget');

Mantissa.ScrollTable.ScrollingWidget.methods(
    function __init__(self, node) {
        Mantissa.ScrollTable.ScrollingWidget.upcall(self, '__init__', node);
        self._rows = [];
        self._rowTimeout = null;
        self._requestWaiting = false;
        self._moreAfterRequest = false;

        self._scrollContent = self.nodeByAttribute("class", "scroll-content");
        self._scrollViewport = self.nodeByAttribute('class', 'scroll-viewport');
        self._headerRow = self.nodeByAttribute('class', 'scroll-header-row');
        self.callRemote("getTableMetadata").addCallback(
            function(metadata) {
                /*
                  argument passing convention!  woo, someday soon Javascript
                  will have all the expressiveness of PL/1.  Maybe then we can
                  decide what registers get used to store variables, too!!!!
                */
                var columnNames = metadata[0];
                self.columnTypes = metadata[1];
                var rowCount = metadata[2];
                var currentSort = metadata[3];
                var isAscendingNow = metadata[4];

                /*
                  (OK, seriously, there should be some kind of
                  multiple-value-unpacking that's easier than this, since we
                  want to decrease the number of round-trips as much as
                  possible...)
                */

                self._createRowHeaders(columnNames);
                self.setSortInfo(currentSort, isAscendingNow);
                self.setViewportHeight(rowCount);
                // Go suuuper fast for the first request
                self.scrolled(10);
            });
    },

    function setViewportHeight(self, rowCount) {
        var rowHeight = self._headerRow.clientHeight;
        if (rowHeight == 0) {
            rowHeight = 20; /* IE can't see clientHeight on some nodes...? */
        }
        /* actually this is wrong, we should calculate from a dummy
            row, but blah templates or something. */

        self._rowHeight = rowHeight;
        var scrollContentHeight = rowHeight * rowCount;
        self._scrollContent.style.height = scrollContentHeight + 'px';
    },

    function adjustViewportHeight(self, rowCount) {
        var rowHeight = self._headerRow.clientHeight;
        if(rowHeight == 0) {
            rowHeight = 20;
        }
        var height = parseInt(self._scrollContent.style.height);
        self._scrollContent.style.height = height + (rowHeight * rowCount) + "px";
    },

    function _getSomeRows(self) {
        var scrollViewportHeight = self._scrollViewport.clientHeight;
        var desiredRowCount = Math.ceil((scrollViewportHeight) / self._rowHeight);

        var firstRow = Math.floor(self._scrollViewport.scrollTop / self._rowHeight);

        var requestNeeded = false;

        for (var i = 0; i < desiredRowCount; i++) {
            if (typeof self._rows[firstRow] === 'undefined') {
                requestNeeded = true;
                break;
            }
            firstRow++;
        }

        if (!requestNeeded) {
            return Divmod.Defer.succeed(1);
        }

        /* do we have the rows we need ? */

        return self.callRemote("requestRowRange", firstRow, firstRow + desiredRowCount).addCallback(
            function(rowData) {
                return self.createRows(firstRow, rowData);
            });
    },

    function createRows(self, idx, rowData) {
        MochiKit.Base.map(
            function(row) {
                if (typeof self._rows[idx] === 'undefined') {
                    self._createRow(idx, row);
                }
                idx++;
            },
            rowData);
    },

    function massageColumnValue(self, columnName, columnType, columnValue) {
        if(columnType == 'timestamp') {
            columnValue = (new Date(columnValue * 1000)).toUTCString();
        }
	if(columnValue ==  null) {
            columnValue = '';
	}
        return columnValue;
    },

    function _createRow(self, rowOffset, rowData) {
        var cells = [];

        for(var colName in rowData) {
            if(!(colName in self._columnOffsets) || self.skipColumn(colName)) {
                continue;
            }
            cells.push([colName,
                        MochiKit.DOM.DIV({"class": "scroll-cell"},
                                         self.massageColumnValue(
                                             colName, self.columnTypes[colName], rowData[colName]))]);
        }<commit_msg>allow overriding of date formatting<commit_after>// import Mantissa

Mantissa.ScrollTable = {};

Mantissa.ScrollTable.ScrollingWidget = Nevow.Athena.Widget.subclass('Mantissa.ScrollTable.ScrollingWidget');

Mantissa.ScrollTable.ScrollingWidget.methods(
    function __init__(self, node) {
        Mantissa.ScrollTable.ScrollingWidget.upcall(self, '__init__', node);
        self._rows = [];
        self._rowTimeout = null;
        self._requestWaiting = false;
        self._moreAfterRequest = false;

        self._scrollContent = self.nodeByAttribute("class", "scroll-content");
        self._scrollViewport = self.nodeByAttribute('class', 'scroll-viewport');
        self._headerRow = self.nodeByAttribute('class', 'scroll-header-row');
        self.callRemote("getTableMetadata").addCallback(
            function(metadata) {
                /*
                  argument passing convention!  woo, someday soon Javascript
                  will have all the expressiveness of PL/1.  Maybe then we can
                  decide what registers get used to store variables, too!!!!
                */
                var columnNames = metadata[0];
                self.columnTypes = metadata[1];
                var rowCount = metadata[2];
                var currentSort = metadata[3];
                var isAscendingNow = metadata[4];

                /*
                  (OK, seriously, there should be some kind of
                  multiple-value-unpacking that's easier than this, since we
                  want to decrease the number of round-trips as much as
                  possible...)
                */

                self._createRowHeaders(columnNames);
                self.setSortInfo(currentSort, isAscendingNow);
                self.setViewportHeight(rowCount);
                // Go suuuper fast for the first request
                self.scrolled(10);
            });
    },

    function setViewportHeight(self, rowCount) {
        var rowHeight = self._headerRow.clientHeight;
        if (rowHeight == 0) {
            rowHeight = 20; /* IE can't see clientHeight on some nodes...? */
        }
        /* actually this is wrong, we should calculate from a dummy
            row, but blah templates or something. */

        self._rowHeight = rowHeight;
        var scrollContentHeight = rowHeight * rowCount;
        self._scrollContent.style.height = scrollContentHeight + 'px';
    },

    function adjustViewportHeight(self, rowCount) {
        var rowHeight = self._headerRow.clientHeight;
        if(rowHeight == 0) {
            rowHeight = 20;
        }
        var height = parseInt(self._scrollContent.style.height);
        self._scrollContent.style.height = height + (rowHeight * rowCount) + "px";
    },

    function _getSomeRows(self) {
        var scrollViewportHeight = self._scrollViewport.clientHeight;
        var desiredRowCount = Math.ceil((scrollViewportHeight) / self._rowHeight);

        var firstRow = Math.floor(self._scrollViewport.scrollTop / self._rowHeight);

        var requestNeeded = false;

        for (var i = 0; i < desiredRowCount; i++) {
            if (typeof self._rows[firstRow] === 'undefined') {
                requestNeeded = true;
                break;
            }
            firstRow++;
        }

        if (!requestNeeded) {
            return Divmod.Defer.succeed(1);
        }

        /* do we have the rows we need ? */

        return self.callRemote("requestRowRange", firstRow, firstRow + desiredRowCount).addCallback(
            function(rowData) {
                return self.createRows(firstRow, rowData);
            });
    },

    function createRows(self, idx, rowData) {
        MochiKit.Base.map(
            function(row) {
                if (typeof self._rows[idx] === 'undefined') {
                    self._createRow(idx, row);
                }
                idx++;
            },
            rowData);
    },

    function formatDate(self, date) {
        return date.toUTCString();
    },
    
    function massageColumnValue(self, columnName, columnType, columnValue) {
        if(columnType == 'timestamp') {
            return self.formatDate(new Date(columnValue * 1000));
        }
	if(columnValue ==  null) {
            return '';
	}
        return columnValue;
    },

    function makeCellElement(self, colName, rowData) {
        return MochiKit.DOM.DIV({"class": "scroll-cell"},
                                self.massageColumnValue(
                                     colName, self.columnTypes[colName], rowData[colName]));
    },

    function _createRow(self, rowOffset, rowData) {
        var cells = [];

        for(var colName in rowData) {
            if(!(colName in self._columnOffsets) || self.skipColumn(colName)) {
                continue;
            }
            cells.push([colName, self.makeCellElement(colName, rowData)]);
        }
{'fraction_non_alphanumeric': 0.1029917648285208, 'fraction_numerical': 0.004169707078077765, 'mean_word_length': 1.8367829686575992, 'pattern_counts': {'":': 2, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 5, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6521239', 'n_tokens_mistral': 2583, 'n_tokens_neox': 2438, 'n_words': 564}