1// Production steps of ECMA-262, Edition 5, 15.4.4.18 2// Reference: http://es5.github.io/#x15.4.4.18 3if (!Array.prototype.forEach) { 4 5 Array.prototype.forEach = function(callback, thisArg) { 6 7 var T, k; 8 9 if (this === null) { 10 throw new TypeError(' this is null or not defined'); 11 } 12 13 // 1. Let O be the result of calling toObject() passing the 14 // |this| value as the argument. 15 var O = Object(this); 16 17 // 2. Let lenValue be the result of calling the Get() internal 18 // method of O with the argument "length". 19 // 3. Let len be toUint32(lenValue). 20 var len = O.length >>> 0; 21 22 // 4. If isCallable(callback) is false, throw a TypeError exception. 23 // See: http://es5.github.com/#x9.11 24 if (typeof callback !== "function") { 25 throw new TypeError(callback + ' is not a function'); 26 } 27 28 // 5. If thisArg was supplied, let T be thisArg; else let 29 // T be undefined. 30 if (arguments.length > 1) { 31 T = thisArg; 32 } 33 34 // 6. Let k be 0 35 k = 0; 36 37 // 7. Repeat, while k < len 38 while (k < len) { 39 40 var kValue; 41 42 // a. Let Pk be ToString(k). 43 // This is implicit for LHS operands of the in operator 44 // b. Let kPresent be the result of calling the HasProperty 45 // internal method of O with argument Pk. 46 // This step can be combined with c 47 // c. If kPresent is true, then 48 if (k in O) { 49 50 // i. Let kValue be the result of calling the Get internal 51 // method of O with argument Pk. 52 kValue = O[k]; 53 54 // ii. Call the Call internal method of callback with T as 55 // the this value and argument list containing kValue, k, and O. 56 callback.call(T, kValue, k, O); 57 } 58 // d. Increase k by 1. 59 k++; 60 } 61 // 8. return undefined 62 }; 63} 64 65// Production steps of ECMA-262, Edition 5, 15.4.4.19 66// Reference: http://es5.github.io/#x15.4.4.19 67if (!Array.prototype.map) { 68 69 Array.prototype.map = function(callback, thisArg) { 70 71 var T, A, k; 72 73 if (this == null) { 74 throw new TypeError(' this is null or not defined'); 75 } 76 77 // 1. Let O be the result of calling ToObject passing the |this| 78 // value as the argument. 79 var O = Object(this); 80 81 // 2. Let lenValue be the result of calling the Get internal 82 // method of O with the argument "length". 83 // 3. Let len be ToUint32(lenValue). 84 var len = O.length >>> 0; 85 86 // 4. If IsCallable(callback) is false, throw a TypeError exception. 87 // See: http://es5.github.com/#x9.11 88 if (typeof callback !== 'function') { 89 throw new TypeError(callback + ' is not a function'); 90 } 91 92 // 5. If thisArg was supplied, let T be thisArg; else let T be undefined. 93 if (arguments.length > 1) { 94 T = thisArg; 95 } 96 97 // 6. Let A be a new array created as if by the expression new Array(len) 98 // where Array is the standard built-in constructor with that name and 99 // len is the value of len. 100 A = new Array(len); 101 102 // 7. Let k be 0 103 k = 0; 104 105 // 8. Repeat, while k < len 106 while (k < len) { 107 108 var kValue, mappedValue; 109 110 // a. Let Pk be ToString(k). 111 // This is implicit for LHS operands of the in operator 112 // b. Let kPresent be the result of calling the HasProperty internal 113 // method of O with argument Pk. 114 // This step can be combined with c 115 // c. If kPresent is true, then 116 if (k in O) { 117 118 // i. Let kValue be the result of calling the Get internal 119 // method of O with argument Pk. 120 kValue = O[k]; 121 122 // ii. Let mappedValue be the result of calling the Call internal 123 // method of callback with T as the this value and argument 124 // list containing kValue, k, and O. 125 mappedValue = callback.call(T, kValue, k, O); 126 127 // iii. Call the DefineOwnProperty internal method of A with arguments 128 // Pk, Property Descriptor 129 // { Value: mappedValue, 130 // Writable: true, 131 // Enumerable: true, 132 // Configurable: true }, 133 // and false. 134 135 // In browsers that support Object.defineProperty, use the following: 136 // Object.defineProperty(A, k, { 137 // value: mappedValue, 138 // writable: true, 139 // enumerable: true, 140 // configurable: true 141 // }); 142 143 // For best browser support, use the following: 144 A[k] = mappedValue; 145 } 146 // d. Increase k by 1. 147 k++; 148 } 149 150 // 9. return A 151 return A; 152 }; 153} 154 155var PagedTable = function (pagedTable) { 156 var me = this; 157 158 var source = function(pagedTable) { 159 var sourceElems = [].slice.call(pagedTable.children).filter(function(e) { 160 return e.hasAttribute("data-pagedtable-source"); 161 }); 162 163 if (sourceElems === null || sourceElems.length !== 1) { 164 throw("A single data-pagedtable-source was not found"); 165 } 166 167 return JSON.parse(sourceElems[0].innerHTML); 168 }(pagedTable); 169 170 var options = function(source) { 171 var options = typeof(source.options) !== "undefined" && 172 source.options !== null ? source.options : {}; 173 174 var columns = typeof(options.columns) !== "undefined" ? options.columns : {}; 175 var rows = typeof(options.rows) !== "undefined" ? options.rows : {}; 176
177 var positiveIntOrNull = function(value) { 178 return parseInt(value) >= 0 ? parseInt(value) : null; 179 }; 180 181 return { 182 pages: positiveIntOrNull(options.pages), 183 rows: { 184 min: positiveIntOrNull(rows.min), 185 max: positiveIntOrNull(rows.max), 186 total: positiveIntOrNull(rows.total) 187 }, 188 columns: { 189 min: positiveIntOrNull(columns.min), 190 max: positiveIntOrNull(columns.max), 191 total: positiveIntOrNull(columns.total) 192 } 193 }; 194 }(source); 195 196 var Measurer = function() { 197 198 // set some default initial values that will get adjusted in runtime 199 me.measures = { 200 padding: 12, 201 character: 8, 202 height: 15, 203 defaults: true 204 }; 205 206 me.calculate = function(measuresCell) { 207 if (!me.measures.defaults) 208 return; 209 210 var measuresCellStyle = window.getComputedStyle(measuresCell, null); 211 212 var newPadding = parsePadding(measuresCellStyle.paddingLeft) + 213 parsePadding(measuresCellStyle.paddingRight); 214 215 var sampleString = "ABCDEFGHIJ0123456789"; 216 var newCharacter = Math.ceil(measuresCell.clientWidth / sampleString.length); 217 218 if (newPadding <= 0 || newCharacter <= 0) 219 return; 220 221 me.measures.padding = newPadding; 222 me.measures.character = newCharacter; 223 me.measures.height = measuresCell.clientHeight; 224 me.measures.defaults = false; 225 }; 226 227 return me; 228 }; 229 230 var Page = function(data, options) { 231 var me = this; 232 233 var defaults = { 234 max: 7, 235 rows: 10 236 }; 237 238 var totalPages = function() { 239 return Math.ceil(data.length / me.rows); 240 }; 241 242 me.number = 0; 243 me.max = options.pages !== null ? options.pages : defaults.max; 244 me.visible = me.max; 245 me.rows = options.rows.min !== null ? options.rows.min : defaults.rows; 246 me.total = totalPages(); 247 248 me.setRows = function(newRows) { 249 me.rows = newRows; 250 me.total = totalPages(); 251 }; 252 253 me.setPageNumber = function(newPageNumber) { 254 if (newPageNumber < 0) newPageNumber = 0; 255 if (newPageNumber >= me.total) newPageNumber = me.total - 1; 256 257 me.number = newPageNumber; 258 }; 259 260 me.setVisiblePages = function(visiblePages) { 261 me.visible = Math.min(me.max, visiblePages); 262 me.setPageNumber(me.number); 263 }; 264 265 me.getVisiblePageRange = function() { 266 var start = me.number - Math.max(Math.floor((me.visible - 1) / 2), 0); 267 var end = me.number + Math.floor(me.visible / 2) + 1; 268 var pageCount = me.total; 269 270 if (start < 0) { 271 var diffToStart = 0 - start; 272 start += diffToStart; 273 end += diffToStart; 274 } 275 276 if (end > pageCount) { 277 var diffToEnd = end - pageCount; 278 start -= diffToEnd; 279 end -= diffToEnd; 280 } 281 282 start = start < 0 ? 0 : start; 283 end = end >= pageCount ? pageCount : end; 284 285 var first = false; 286 var last = false; 287 288 if (start > 0 && me.visible > 1) { 289 start = start + 1; 290 first = true; 291 } 292 293 if (end < pageCount && me.visible > 2) { 294 end = end - 1; 295 last = true; 296 } 297 298 return { 299 first: first, 300 start: start, 301 end: end, 302 last: last 303 }; 304 }; 305 306 me.getRowStart = function() { 307 var rowStart = page.number * page.rows; 308 if (rowStart < 0) 309 rowStart = 0; 310 311 return rowStart; 312 }; 313 314 me.getRowEnd = function() { 315 var rowStart = me.getRowStart(); 316 return Math.min(rowStart + me.rows, data.length); 317 }; 318 319 me.getPaddingRows = function() { 320 var rowStart = me.getRowStart(); 321 var rowEnd = me.getRowEnd(); 322 return data.length > me.rows ? me.rows - (rowEnd - rowStart) : 0; 323 }; 324 }; 325 326 var Columns = function(data, columns, options) { 327 var me = this; 328 329 me.defaults = { 330 min: 5 331 }; 332 333 me.number = 0; 334 me.visible = 0; 335 me.total = columns.length; 336 me.subset = []; 337 me.padding = 0; 338 me.min = options.columns.min !== null ? options.columns.min : me.defaults.min; 339 me.max = options.columns.max !== null ? options.columns.max : null; 340 me.widths = {}; 341 342 var widthsLookAhead = Math.max(100, options.rows.min); 343 var paddingColChars = 10; 344 345 me.emptyNames = function() { 346 columns.forEach(function(column) { 347 if (columns.label !== null && columns.label !== "") 348 return false;
349 }); 350 351 return true; 352 }; 353 354 var parsePadding = function(value) { 355 return parseInt(value) >= 0 ? parseInt(value) : 0; 356 }; 357 358 me.calculateWidths = function(measures) { 359 columns.forEach(function(column) { 360 var maxChars = Math.max( 361 column.label.toString().length, 362 column.type.toString().length 363 ); 364 365 for (var idxRow = 0; idxRow < Math.min(widthsLookAhead, data.length); idxRow++) { 366 maxChars = Math.max(maxChars, data[idxRow][column.name.toString()].length); 367 } 368 369 me.widths[column.name] = { 370 // width in characters 371 chars: maxChars, 372 // width for the inner html columns 373 inner: maxChars * measures.character, 374 // width adding outer styles like padding 375 outer: maxChars * measures.character + measures.padding 376 }; 377 }); 378 }; 379 380 me.getWidth = function() { 381 var widthOuter = 0; 382 for (var idxCol = 0; idxCol < me.subset.length; idxCol++) { 383 var columnName = me.subset[idxCol].name; 384 widthOuter = widthOuter + me.widths[columnName].outer; 385 } 386 387 widthOuter = widthOuter + me.padding * paddingColChars * measurer.measures.character; 388 389 if (me.hasMoreLeftColumns()) { 390 widthOuter = widthOuter + columnNavigationWidthPX + measurer.measures.padding; 391 } 392 393 if (me.hasMoreRightColumns()) { 394 widthOuter = widthOuter + columnNavigationWidthPX + measurer.measures.padding; 395 } 396 397 return widthOuter; 398 }; 399 400 me.updateSlice = function() { 401 if (me.number + me.visible >= me.total) 402 me.number = me.total - me.visible; 403 404 if (me.number < 0) me.number = 0; 405 406 me.subset = columns.slice(me.number, Math.min(me.number + me.visible, me.total)); 407 408 me.subset = me.subset.map(function(column) { 409 Object.keys(column).forEach(function(colKey) { 410 column[colKey] = column[colKey] === null ? "" : column[colKey].toString(); 411 }); 412 413 column.width = null; 414 return column; 415 }); 416 }; 417 418 me.setVisibleColumns = function(columnNumber, newVisibleColumns, paddingCount) { 419 me.number = columnNumber; 420 me.visible = newVisibleColumns; 421 me.padding = paddingCount; 422 423 me.updateSlice(); 424 }; 425 426 me.incColumnNumber = function(increment) { 427 me.number = me.number + increment; 428 }; 429 430 me.setColumnNumber = function(newNumber) { 431 me.number = newNumber; 432 }; 433 434 me.setPaddingCount = function(newPadding) { 435 me.padding = newPadding; 436 }; 437 438 me.getPaddingCount = function() { 439 return me.padding; 440 }; 441 442 me.hasMoreLeftColumns = function() { 443 return me.number > 0; 444 }; 445 446 me.hasMoreRightColumns = function() { 447 return me.number + me.visible < me.total; 448 }; 449 450 me.updateSlice(0); 451 return me; 452 }; 453 454 var data = source.data; 455 var page = new Page(data, options); 456 var measurer = new Measurer(data, options); 457 var columns = new Columns(data, source.columns, options); 458 459 var table = null; 460 var tableDiv = null; 461 var header = null; 462 var footer = null; 463 var tbody = null; 464 465 // Caches pagedTable.clientWidth, specially for webkit 466 var cachedPagedTableClientWidth = null; 467 468 var onChangeCallbacks = []; 469 470 var clearSelection = function() { 471 if(document.selection && document.selection.empty) { 472 document.selection.empty(); 473 } else if(window.getSelection) { 474 var sel = window.getSelection(); 475 sel.removeAllRanges(); 476 } 477 }; 478 479 var columnNavigationWidthPX = 5; 480 481 var renderColumnNavigation = function(increment, backwards) { 482 var arrow = document.createElement("div"); 483 arrow.setAttribute("style", 484 "border-top: " + columnNavigationWidthPX + "px solid transparent;" + 485 "border-bottom: " + columnNavigationWidthPX + "px solid transparent;" + 486 "border-" + (backwards ? "right" : "left") + ": " + columnNavigationWidthPX + "px solid;"); 487 488 var header = document.createElement("th"); 489 header.appendChild(arrow); 490 header.setAttribute("style", 491 "cursor: pointer;" + 492 "vertical-align: middle;" + 493 "min-width: " + columnNavigationWidthPX + "px;" + 494 "width: " + columnNavigationWidthPX + "px;"); 495 496 header.onclick = function() { 497 columns.incColumnNumber(backwards ? -1 : increment); 498 499 me.animateColumns(backwards); 500 renderFooter(); 501 502 clearSelection(); 503 triggerOnChange(); 504 }; 505 506 return header; 507 }; 508 509 var maxColumnWidth = function(width) { 510 var padding = 80; 511 var columnMax = Math.max(cachedPagedTableClientWidth - padding, 0); 512 513 return parseInt(width) > 0 ? 514 Math.min(columnMax, parseInt(width)) + "px" : 515 columnMax + "px"; 516 }; 517 518 var clearHeader = function() { 519 var thead = pagedTable.querySelectorAll("thead")[0]; 520 thead.innerHTML = ""; 521 }; 522 523 var renderHeader = function(clear) { 524 cachedPagedTableClientWidth = pagedTable.clientWidth; 525 526 var fragment = document.createDocumentFragment(); 527 528 header = document.createElement("tr"); 529 fragment.appendChild(header); 530 531 if (columns.number > 0) 532 header.appendChild(renderColumnNavigation(-columns.visible, true)); 533 534 columns.subset = columns.subset.map(function(columnData) { 535 var column = document.createElement("th"); 536 column.setAttribute("align", columnData.align); 537 column.style.textAlign = columnData.align; 538 539 column.style.maxWidth = maxColumnWidth(null); 540 if (columnData.width) { 541 column.style.minWidth = 542 column.style.maxWidth = maxColumnWidth(columnData.width); 543 } 544 545 var columnName = document.createElement("div"); 546 columnName.setAttribute("class", "pagedtable-header-name"); 547 if (columnData.label === "") { 548 columnName.innerHTML = " "; 549 } 550 else { 551 columnName.appendChild(document.createTextNode(columnData.label)); 552 } 553 column.appendChild(columnName); 554 555 var columnType = document.createElement("div"); 556 columnType.setAttribute("class", "pagedtable-header-type"); 557 if (columnData.type === "") { 558 columnType.innerHTML = " "; 559 } 560 else { 561 columnType.appendChild(document.createTextNode("<" + columnData.type + ">")); 562 } 563 column.appendChild(columnType); 564 565 header.appendChild(column); 566 567 columnData.element = column; 568 569 return columnData; 570 }); 571 572 for (var idx = 0; idx < columns.getPaddingCount(); idx++) { 573 var paddingCol = document.createElement("th"); 574 paddingCol.setAttribute("class", "pagedtable-padding-col"); 575 header.appendChild(paddingCol); 576 } 577 578 if (columns.number + columns.visible < columns.total) 579 header.appendChild(renderColumnNavigation(columns.visible, false)); 580 581 if (typeof(clear) == "undefined" || clear) clearHeader(); 582 var thead = pagedTable.querySelectorAll("thead")[0]; 583 thead.appendChild(fragment); 584 }; 585 586 me.animateColumns = function(backwards) { 587 var thead = pagedTable.querySelectorAll("thead")[0]; 588 589 var headerOld = thead.querySelectorAll("tr")[0]; 590 var tbodyOld = table.querySelectorAll("tbody")[0]; 591 592 me.fitColumns(backwards); 593 594 renderHeader(false); 595 596 header.style.opacity = "0"; 597 header.style.transform = backwards ? "translateX(-30px)" : "translateX(30px)"; 598 header.style.transition = "transform 200ms linear, opacity 200ms"; 599 header.style.transitionDelay = "0"; 600 601 renderBody(false); 602 603 if (headerOld) { 604 headerOld.style.position = "absolute"; 605 headerOld.style.transform = "translateX(0px)"; 606 headerOld.style.opacity = "1"; 607 headerOld.style.transition = "transform 100ms linear, opacity 100ms"; 608 headerOld.setAttribute("class", "pagedtable-remove-head"); 609 if (headerOld.style.transitionEnd) { 610 headerOld.addEventListener("transitionend", function() { 611 var headerOldByClass = thead.querySelector(".pagedtable-remove-head"); 612 if (headerOldByClass) thead.removeChild(headerOldByClass); 613 }); 614 } 615 else { 616 thead.removeChild(headerOld); 617 } 618 } 619 620 if (tbodyOld) table.removeChild(tbodyOld); 621 622 tbody.style.opacity = "0"; 623 tbody.style.transition = "transform 200ms linear, opacity 200ms"; 624 tbody.style.transitionDelay = "0ms"; 625 626 // force relayout 627 window.getComputedStyle(header).opacity; 628 window.getComputedStyle(tbody).opacity; 629 630 if (headerOld) { 631 headerOld.style.transform = backwards ? "translateX(20px)" : "translateX(-30px)"; 632 headerOld.style.opacity = "0"; 633 } 634 635 header.style.transform = "translateX(0px)"; 636 header.style.opacity = "1"; 637 638 tbody.style.opacity = "1"; 639 } 640 641 me.onChange = function(callback) { 642 onChangeCallbacks.push(callback); 643 }; 644 645 var triggerOnChange = function() { 646 onChangeCallbacks.forEach(function(onChange) { 647 onChange(); 648 }); 649 }; 650 651 var clearBody = function() { 652 if (tbody) { 653 table.removeChild(tbody); 654 tbody = null; 655 } 656 }; 657 658 var renderBody = function(clear) { 659 cachedPagedTableClientWidth = pagedTable.clientWidth 660 661 var fragment = document.createDocumentFragment(); 662 663 var pageData = data.slice(page.getRowStart(), page.getRowEnd()); 664 665 pageData.forEach(function(dataRow, idxRow) { 666 var htmlRow = document.createElement("tr"); 667 htmlRow.setAttribute("class", (idxRow % 2 !==0) ? "even" : "odd"); 668 669 if (columns.hasMoreLeftColumns()) 670 htmlRow.appendChild(document.createElement("td")); 671 672 columns.subset.forEach(function(columnData) { 673 var cellName = columnData.name; 674 var dataCell = dataRow[cellName]; 675 var htmlCell = document.createElement("td"); 676 677 if (dataCell === "NA") htmlCell.setAttribute("class", "pagedtable-na-cell"); 678 if (dataCell === "__NA__") dataCell = "NA"; 679 680 var cellText = document.createTextNode(dataCell);
681 htmlCell.appendChild(cellText); 682 if (dataCell.length > 50) { 683 htmlCell.setAttribute("title", dataCell); 684 } 685 htmlCell.setAttribute("align", columnData.align); 686 htmlCell.style.textAlign = columnData.align; 687 htmlCell.style.maxWidth = maxColumnWidth(null); 688 if (columnData.width) { 689 htmlCell.style.minWidth = htmlCell.style.maxWidth = maxColumnWidth(columnData.width); 690 } 691 htmlRow.appendChild(htmlCell); 692 }); 693 694 for (var idx = 0; idx < columns.getPaddingCount(); idx++) { 695 var paddingCol = document.createElement("td"); 696 paddingCol.setAttribute("class", "pagedtable-padding-col"); 697 htmlRow.appendChild(paddingCol); 698 } 699 700 if (columns.hasMoreRightColumns()) 701 htmlRow.appendChild(document.createElement("td")); 702 703 fragment.appendChild(htmlRow); 704 }); 705 706 for (var idxPadding = 0; idxPadding < page.getPaddingRows(); idxPadding++) { 707 var paddingRow = document.createElement("tr"); 708 709 var paddingCellRow = document.createElement("td"); 710 paddingCellRow.innerHTML = " "; 711 paddingCellRow.setAttribute("colspan", "100%"); 712 paddingRow.appendChild(paddingCellRow); 713 714 fragment.appendChild(paddingRow); 715 } 716 717 if (typeof(clear) == "undefined" || clear) clearBody(); 718 tbody = document.createElement("tbody"); 719 tbody.appendChild(fragment); 720 721 table.appendChild(tbody); 722 }; 723 724 var getLabelInfo = function() { 725 var pageStart = page.getRowStart(); 726 var pageEnd = page.getRowEnd(); 727 var totalRows = data.length; 728 729 var totalRowsLabel = options.rows.total ? options.rows.total : totalRows; 730 var totalRowsLabelFormat = totalRowsLabel.toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,'); 731 732 var infoText = (pageStart + 1) + "-" + pageEnd + " of " + totalRowsLabelFormat + " rows"; 733 if (totalRows < page.rows) { 734 infoText = totalRowsLabel + " row" + (totalRows != 1 ? "s" : ""); 735 } 736 if (columns.total > columns.visible) { 737 var totalColumnsLabel = options.columns.total ? options.columns.total : columns.total; 738 739 infoText = infoText + " | " + (columns.number + 1) + "-" + 740 (Math.min(columns.number + columns.visible, columns.total)) + 741 " of " + totalColumnsLabel + " columns"; 742 } 743 744 return infoText; 745 }; 746 747 var clearFooter = function() { 748 footer = pagedTable.querySelectorAll("div.pagedtable-footer")[0]; 749 footer.innerHTML = ""; 750 751 return footer; 752 }; 753 754 var createPageLink = function(idxPage) { 755 var pageLink = document.createElement("a"); 756 pageLinkClass = idxPage === page.number ? "pagedtable-index pagedtable-index-current" : "pagedtable-index"; 757 pageLink.setAttribute("class", pageLinkClass); 758 pageLink.setAttribute("data-page-index", idxPage); 759 pageLink.onclick = function() { 760 page.setPageNumber(parseInt(this.getAttribute("data-page-index"))); 761 renderBody(); 762 renderFooter(); 763 764 triggerOnChange(); 765 }; 766 767 pageLink.appendChild(document.createTextNode(idxPage + 1)); 768 769 return pageLink; 770 } 771 772 var renderFooter = function() { 773 footer = clearFooter(); 774 775 var next = document.createElement("a"); 776 next.appendChild(document.createTextNode("Next")); 777 next.onclick = function() { 778 page.setPageNumber(page.number + 1); 779 renderBody(); 780 renderFooter(); 781 782 triggerOnChange(); 783 }; 784 if (data.length > page.rows) footer.appendChild(next); 785 786 var pageNumbers = document.createElement("div"); 787 pageNumbers.setAttribute("class", "pagedtable-indexes"); 788 789 var pageRange = page.getVisiblePageRange(); 790 791 if (pageRange.first) { 792 var pageLink = createPageLink(0); 793 pageNumbers.appendChild(pageLink); 794 795 var pageSeparator = document.createElement("div"); 796 pageSeparator.setAttribute("class", "pagedtable-index-separator-left"); 797 pageSeparator.appendChild(document.createTextNode("...")) 798 pageNumbers.appendChild(pageSeparator); 799 } 800 801 for (var idxPage = pageRange.start; idxPage < pageRange.end; idxPage++) { 802 var pageLink = createPageLink(idxPage); 803 804 pageNumbers.appendChild(pageLink); 805 } 806 807 if (pageRange.last) { 808 var pageSeparator = document.createElement("div"); 809 pageSeparator.setAttribute("class", "pagedtable-index-separator-right"); 810 pageSeparator.appendChild(document.createTextNode("...")) 811 pageNumbers.appendChild(pageSeparator); 812 813 var pageLink = createPageLink(page.total - 1); 814 pageNumbers.appendChild(pageLink); 815 } 816 817 if (data.length > page.rows) footer.appendChild(pageNumbers); 818 819 var previous = document.createElement("a"); 820 previous.appendChild(document.createTextNode("Previous")); 821 previous.onclick = function() { 822 page.setPageNumber(page.number - 1); 823 renderBody(); 824 renderFooter(); 825 826 triggerOnChange(); 827 }; 828 if (data.length > page.rows) footer.appendChild(previous); 829 830 var infoLabel = document.createElement("div"); 831 infoLabel.setAttribute("class", "pagedtable-info"); 832 infoLabel.setAttribute("title", getLabelInfo()); 833 infoLabel.appendChild(document.createTextNode(getLabelInfo())); 834 footer.appendChild(infoLabel); 835 836 var enabledClass = "pagedtable-index-nav"; 837 var disabledClass = "pagedtable-index-nav pagedtable-index-nav-disabled"; 838 previous.setAttribute("class", page.number <= 0 ? disabledClass : enabledClass); 839 next.setAttribute("class", (page.number + 1) * page.rows >= data.length ? disabledClass : enabledClass); 840 }; 841 842 var measuresCell = null; 843 844 var renderMeasures = function() { 845 var measuresTable = document.createElement("table"); 846 measuresTable.style.visibility = "hidden"; 847 measuresTable.style.position = "absolute"; 848 measuresTable.style.whiteSpace = "nowrap"; 849 measuresTable.style.height = "auto"; 850 measuresTable.style.width = "auto"; 851 852 var measuresRow = document.createElement("tr"); 853 measuresTable.appendChild(measuresRow); 854 855 measuresCell = document.createElement("td"); 856 var sampleString = "ABCDEFGHIJ0123456789"; 857 measuresCell.appendChild(document.createTextNode(sampleString)); 858 859 measuresRow.appendChild(measuresCell); 860 861 tableDiv.appendChild(measuresTable); 862 } 863 864 me.init = function() { 865 tableDiv = document.createElement("div"); 866 pagedTable.appendChild(tableDiv); 867 var pagedTableClass = data.length > 0 ? 868 "pagedtable pagedtable-not-empty" : 869 "pagedtable pagedtable-empty"; 870 871 if (columns.total == 0 || (columns.emptyNames() && data.length == 0)) { 872 pagedTableClass = pagedTableClass + " pagedtable-empty-columns"; 873 } 874 875 tableDiv.setAttribute("class", pagedTableClass); 876 877 renderMeasures(); 878 measurer.calculate(measuresCell); 879 columns.calculateWidths(measurer.measures); 880 881 table = document.createElement("table"); 882 table.setAttribute("cellspacing", "0"); 883 table.setAttribute("class", "table table-condensed"); 884 tableDiv.appendChild(table); 885 886 table.appendChild(document.createElement("thead")); 887 888 var footerDiv = document.createElement("div"); 889 footerDiv.setAttribute("class", "pagedtable-footer"); 890 tableDiv.appendChild(footerDiv); 891 892 // if the host has not yet provided horizontal space, render hidden 893 if (tableDiv.clientWidth <= 0) { 894 tableDiv.style.opacity = "0"; 895 } 896 897 me.render(); 898 899 // retry seizing columns later if the host has not provided space 900 function retryFit() { 901 if (tableDiv.clientWidth <= 0) {
902 setTimeout(retryFit, 100); 903 } else { 904 me.render(); 905 triggerOnChange(); 906 } 907 } 908 if (tableDiv.clientWidth <= 0) { 909 retryFit(); 910 } 911 }; 912 913 var registerWidths = function() { 914 columns.subset = columns.subset.map(function(column) { 915 column.width = columns.widths[column.name].inner; 916 return column; 917 }); 918 }; 919 920 var parsePadding = function(value) { 921 return parseInt(value) >= 0 ? parseInt(value) : 0; 922 }; 923 924 me.fixedHeight = function() { 925 return options.rows.max != null; 926 } 927 928 me.fitRows = function() { 929 if (me.fixedHeight()) 930 return; 931 932 measurer.calculate(measuresCell); 933 934 var rows = options.rows.min !== null ? options.rows.min : 0; 935 var headerHeight = header !== null && header.offsetHeight > 0 ? header.offsetHeight : 0; 936 var footerHeight = footer !== null && footer.offsetHeight > 0 ? footer.offsetHeight : 0; 937 938 if (pagedTable.offsetHeight > 0) { 939 var availableHeight = pagedTable.offsetHeight - headerHeight - footerHeight; 940 rows = Math.floor((availableHeight) / measurer.measures.height); 941 } 942 943 rows = options.rows.min !== null ? Math.max(options.rows.min, rows) : rows; 944 945 page.setRows(rows); 946 } 947 948 // The goal of this function is to add as many columns as possible 949 // starting from left-to-right, when the right most limit is reached 950 // it tries to add columns from the left as well. 951 // 952 // When startBackwards is true columns are added from right-to-left 953 me.fitColumns = function(startBackwards) { 954 measurer.calculate(measuresCell); 955 columns.calculateWidths(measurer.measures); 956 957 if (tableDiv.clientWidth > 0) { 958 tableDiv.style.opacity = 1; 959 } 960 961 var visibleColumns = tableDiv.clientWidth <= 0 ? Math.max(columns.min, 1) : 1; 962 var columnNumber = columns.number; 963 var paddingCount = 0; 964 965 // track a list of added columns as we build the visible ones to allow us 966 // to remove columns when they don't fit anymore. 967 var columnHistory = []; 968 969 var lastTableHeight = 0; 970 var backwards = startBackwards; 971 972 var tableDivStyle = window.getComputedStyle(tableDiv, null); 973 var tableDivPadding = parsePadding(tableDivStyle.paddingLeft) + 974 parsePadding(tableDivStyle.paddingRight); 975 976 var addPaddingCol = false; 977 var currentWidth = 0; 978 979 while (true) { 980 columns.setVisibleColumns(columnNumber, visibleColumns, paddingCount); 981 currentWidth = columns.getWidth(); 982 983 if (tableDiv.clientWidth - tableDivPadding < currentWidth) { 984 break; 985 } 986 987 columnHistory.push({ 988 columnNumber: columnNumber, 989 visibleColumns: visibleColumns, 990 paddingCount: paddingCount 991 }); 992 993 if (columnHistory.length > 100) { 994 console.error("More than 100 tries to fit columns, aborting"); 995 break; 996 } 997 998 if (columns.max !== null && 999 columns.visible + columns.getPaddingCount() >= columns.max) { 1000 break; 1001 } 1002 1003 // if we run out of right-columns 1004 if (!backwards && columnNumber + columns.visible >= columns.total) { 1005 // if we started adding right-columns, try adding left-columns 1006 if (!startBackwards && columnNumber > 0) { 1007 backwards = true; 1008 } 1009 else if (columns.min === null || visibleColumns + columns.getPaddingCount() >= columns.min) { 1010 break; 1011 } 1012 else { 1013 paddingCount = paddingCount + 1; 1014 } 1015 } 1016 1017 // if we run out of left-columns 1018 if (backwards && columnNumber == 0) { 1019 // if we started adding left-columns, try adding right-columns 1020 if (startBackwards && columnNumber + columns.visible < columns.total) { 1021 backwards = false; 1022 } 1023 else if (columns.min === null || visibleColumns + columns.getPaddingCount() >= columns.min) { 1024 break; 1025 } 1026 else { 1027 paddingCount = paddingCount + 1; 1028 } 1029 } 1030 1031 // when moving backwards try fitting left columns first 1032 if (backwards && columnNumber > 0) { 1033 columnNumber = columnNumber - 1; 1034 } 1035 1036 if (columnNumber + visibleColumns < columns.total) { 1037 visibleColumns = visibleColumns + 1; 1038 } 1039 } 1040 1041 var lastRenderableColumn = { 1042 columnNumber: columnNumber, 1043 visibleColumns: visibleColumns, 1044 paddingCount: paddingCount 1045 }; 1046 1047 if (columnHistory.length > 0) { 1048 lastRenderableColumn = columnHistory[columnHistory.length - 1]; 1049 } 1050 1051 columns.setVisibleColumns( 1052 lastRenderableColumn.columnNumber, 1053 lastRenderableColumn.visibleColumns, 1054 lastRenderableColumn.paddingCount); 1055 1056 if (pagedTable.offsetWidth > 0) { 1057 page.setVisiblePages(Math.max(Math.ceil(1.0 * (pagedTable.offsetWidth - 250) / 40), 2)); 1058 } 1059 1060 registerWidths(); 1061 }; 1062 1063 me.fit = function(startBackwards) { 1064 me.fitRows(); 1065 me.fitColumns(startBackwards); 1066 } 1067 1068 me.render = function() { 1069 me.fitColumns(false); 1070 1071 // render header/footer to measure height accurately 1072 renderHeader(); 1073 renderFooter(); 1074 1075 me.fitRows(); 1076 renderBody(); 1077 1078 // re-render footer to match new rows 1079 renderFooter(); 1080 } 1081 1082 var resizeLastWidth = -1; 1083 var resizeLastHeight = -1; 1084 var resizeNewWidth = -1; 1085 var resizeNewHeight = -1; 1086 var resizePending = false;
1087 1088 me.resize = function(newWidth, newHeight) { 1089 1090 function resizeDelayed() { 1091 resizePending = false; 1092 1093 if ( 1094 (resizeNewWidth !== resizeLastWidth) || 1095 (!me.fixedHeight() && resizeNewHeight !== resizeLastHeight) 1096 ) { 1097 resizeLastWidth = resizeNewWidth; 1098 resizeLastHeight = resizeNewHeight; 1099 1100 setTimeout(resizeDelayed, 200); 1101 resizePending = true; 1102 } else { 1103 me.render(); 1104 triggerOnChange(); 1105 1106 resizeLastWidth = -1; 1107 resizeLastHeight = -1; 1108 } 1109 } 1110 1111 resizeNewWidth = newWidth; 1112 resizeNewHeight = newHeight; 1113 1114 if (!resizePending) resizeDelayed(); 1115 }; 1116}; 1117 1118var PagedTableDoc; 1119(function (PagedTableDoc) { 1120 var allPagedTables = []; 1121 1122 PagedTableDoc.initAll = function() { 1123 allPagedTables = []; 1124 1125 var pagedTables = [].slice.call(document.querySelectorAll('[data-pagedtable="false"],[data-pagedtable=""]')); 1126 pagedTables.forEach(function(pagedTable, idx) { 1127 pagedTable.setAttribute("data-pagedtable", "true"); 1128 pagedTable.setAttribute("pagedtable-page", 0); 1129 pagedTable.setAttribute("class", "pagedtable-wrapper"); 1130 1131 var pagedTableInstance = new PagedTable(pagedTable); 1132 pagedTableInstance.init(); 1133 1134 allPagedTables.push(pagedTableInstance); 1135 }); 1136 }; 1137 1138 PagedTableDoc.resizeAll = function() { 1139 allPagedTables.forEach(function(pagedTable) { 1140 pagedTable.render(); 1141 }); 1142 }; 1143 1144 window.addEventListener("resize", PagedTableDoc.resizeAll); 1145 1146 return PagedTableDoc; 1147})(PagedTableDoc || (PagedTableDoc = {})); 1148 1149window.onload = function() { 1150 PagedTableDoc.initAll(); 1151};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.