| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805 |
- import {
- addClass,
- empty,
- fastInnerHTML,
- fastInnerText,
- getComputedStyle,
- getScrollbarWidth,
- hasClass,
- isChildOf,
- isInput,
- isOutsideInput
- } from './helpers/dom/element';
- import {isChrome, isSafari} from './helpers/browser';
- import EventManager from './eventManager';
- import {stopPropagation, isImmediatePropagationStopped, isRightClick, isLeftClick} from './helpers/dom/event';
- import Walkontable, {CellCoords, Selection} from './3rdparty/walkontable/src';
- /**
- * Handsontable TableView constructor
- * @param {Object} instance
- */
- function TableView(instance) {
- var that = this;
- this.eventManager = new EventManager(instance);
- this.instance = instance;
- this.settings = instance.getSettings();
- this.selectionMouseDown = false;
- var originalStyle = instance.rootElement.getAttribute('style');
- if (originalStyle) {
- instance.rootElement.setAttribute('data-originalstyle', originalStyle); // needed to retrieve original style in jsFiddle link generator in HT examples. may be removed in future versions
- }
- addClass(instance.rootElement, 'handsontable');
- var table = document.createElement('TABLE');
- addClass(table, 'htCore');
- if (instance.getSettings().tableClassName) {
- addClass(table, instance.getSettings().tableClassName);
- }
- this.THEAD = document.createElement('THEAD');
- table.appendChild(this.THEAD);
- this.TBODY = document.createElement('TBODY');
- table.appendChild(this.TBODY);
- instance.table = table;
- instance.container.insertBefore(table, instance.container.firstChild);
- this.eventManager.addEventListener(instance.rootElement, 'mousedown', function(event) {
- this.selectionMouseDown = true;
- if (!that.isTextSelectionAllowed(event.target)) {
- clearTextSelection();
- event.preventDefault();
- window.focus(); // make sure that window that contains HOT is active. Important when HOT is in iframe.
- }
- });
- this.eventManager.addEventListener(instance.rootElement, 'mouseup', function(event) {
- this.selectionMouseDown = false;
- });
- this.eventManager.addEventListener(instance.rootElement, 'mousemove', function(event) {
- if (this.selectionMouseDown && !that.isTextSelectionAllowed(event.target)) {
- clearTextSelection();
- event.preventDefault();
- }
- });
- this.eventManager.addEventListener(document.documentElement, 'keyup', function(event) {
- if (instance.selection.isInProgress() && !event.shiftKey) {
- instance.selection.finish();
- }
- });
- var isMouseDown;
- this.isMouseDown = function() {
- return isMouseDown;
- };
- this.eventManager.addEventListener(document.documentElement, 'mouseup', function(event) {
- if (instance.selection.isInProgress() && event.which === 1) { // is left mouse button
- instance.selection.finish();
- }
- isMouseDown = false;
- if (isOutsideInput(document.activeElement)) {
- instance.unlisten();
- }
- });
- this.eventManager.addEventListener(document.documentElement, 'mousedown', function(event) {
- var originalTarget = event.target;
- var next = event.target;
- var eventX = event.x || event.clientX;
- var eventY = event.y || event.clientY;
- if (isMouseDown || !instance.rootElement) {
- return; // it must have been started in a cell
- }
- // immediate click on "holder" means click on the right side of vertical scrollbar
- if (next === instance.view.wt.wtTable.holder) {
- var scrollbarWidth = getScrollbarWidth();
- if (document.elementFromPoint(eventX + scrollbarWidth, eventY) !== instance.view.wt.wtTable.holder ||
- document.elementFromPoint(eventX, eventY + scrollbarWidth) !== instance.view.wt.wtTable.holder) {
- return;
- }
- } else {
- while (next !== document.documentElement) {
- if (next === null) {
- if (event.isTargetWebComponent) {
- break;
- }
- // click on something that was a row but now is detached (possibly because your click triggered a rerender)
- return;
- }
- if (next === instance.rootElement) {
- // click inside container
- return;
- }
- next = next.parentNode;
- }
- }
- // function did not return until here, we have an outside click!
- var outsideClickDeselects = typeof that.settings.outsideClickDeselects === 'function' ?
- that.settings.outsideClickDeselects(originalTarget) :
- that.settings.outsideClickDeselects;
- if (outsideClickDeselects) {
- instance.deselectCell();
- } else {
- instance.destroyEditor();
- }
- });
- this.eventManager.addEventListener(table, 'selectstart', function(event) {
- if (that.settings.fragmentSelection || isInput(event.target)) {
- return;
- }
- // https://github.com/handsontable/handsontable/issues/160
- // Prevent text from being selected when performing drag down.
- event.preventDefault();
- });
- var clearTextSelection = function() {
- // http://stackoverflow.com/questions/3169786/clear-text-selection-with-javascript
- if (window.getSelection) {
- if (window.getSelection().empty) { // Chrome
- window.getSelection().empty();
- } else if (window.getSelection().removeAllRanges) { // Firefox
- window.getSelection().removeAllRanges();
- }
- } else if (document.selection) { // IE?
- document.selection.empty();
- }
- };
- var selections = [
- new Selection({
- className: 'current',
- border: {
- width: 2,
- color: '#5292F7',
- // style: 'solid', // not used
- cornerVisible: function() {
- return that.settings.fillHandle && !that.isCellEdited() && !instance.selection.isMultiple();
- },
- multipleSelectionHandlesVisible: function() {
- return !that.isCellEdited() && !instance.selection.isMultiple();
- },
- },
- }),
- new Selection({
- className: 'area',
- border: {
- width: 1,
- color: '#89AFF9',
- // style: 'solid', // not used
- cornerVisible: function() {
- return that.settings.fillHandle && !that.isCellEdited() && instance.selection.isMultiple();
- },
- multipleSelectionHandlesVisible: function() {
- return !that.isCellEdited() && instance.selection.isMultiple();
- },
- },
- }),
- new Selection({
- className: 'highlight',
- highlightHeaderClassName: that.settings.currentHeaderClassName,
- highlightRowClassName: that.settings.currentRowClassName,
- highlightColumnClassName: that.settings.currentColClassName,
- }),
- new Selection({
- className: 'fill',
- border: {
- width: 1,
- color: 'red',
- // style: 'solid' // not used
- },
- }),
- ];
- selections.current = selections[0];
- selections.area = selections[1];
- selections.highlight = selections[2];
- selections.fill = selections[3];
- var walkontableConfig = {
- debug: function() {
- return that.settings.debug;
- },
- externalRowCalculator: this.instance.getPlugin('autoRowSize') && this.instance.getPlugin('autoRowSize').isEnabled(),
- table: table,
- preventOverflow: () => this.settings.preventOverflow,
- stretchH: function() {
- return that.settings.stretchH;
- },
- data: instance.getDataAtCell,
- totalRows: () => instance.countRows(),
- totalColumns: () => instance.countCols(),
- fixedColumnsLeft: function() {
- return that.settings.fixedColumnsLeft;
- },
- fixedRowsTop: function() {
- return that.settings.fixedRowsTop;
- },
- fixedRowsBottom: function() {
- return that.settings.fixedRowsBottom;
- },
- minSpareRows: function() {
- return that.settings.minSpareRows;
- },
- renderAllRows: that.settings.renderAllRows,
- rowHeaders: function() {
- let headerRenderers = [];
- if (instance.hasRowHeaders()) {
- headerRenderers.push(function(row, TH) {
- that.appendRowHeader(row, TH);
- });
- }
- instance.runHooks('afterGetRowHeaderRenderers', headerRenderers);
- return headerRenderers;
- },
- columnHeaders: function() {
- let headerRenderers = [];
- if (instance.hasColHeaders()) {
- headerRenderers.push(function(column, TH) {
- that.appendColHeader(column, TH);
- });
- }
- instance.runHooks('afterGetColumnHeaderRenderers', headerRenderers);
- return headerRenderers;
- },
- columnWidth: instance.getColWidth,
- rowHeight: instance.getRowHeight,
- cellRenderer: function(row, col, TD) {
- const cellProperties = that.instance.getCellMeta(row, col);
- const prop = that.instance.colToProp(col);
- let value = that.instance.getDataAtRowProp(row, prop);
- if (that.instance.hasHook('beforeValueRender')) {
- value = that.instance.runHooks('beforeValueRender', value);
- }
- that.instance.runHooks('beforeRenderer', TD, row, col, prop, value, cellProperties);
- that.instance.getCellRenderer(cellProperties)(that.instance, TD, row, col, prop, value, cellProperties);
- that.instance.runHooks('afterRenderer', TD, row, col, prop, value, cellProperties);
- },
- selections: selections,
- hideBorderOnMouseDownOver: function() {
- return that.settings.fragmentSelection;
- },
- onCellMouseDown: function(event, coords, TD, wt) {
- let blockCalculations = {
- row: false,
- column: false,
- cells: false
- };
- instance.listen();
- that.activeWt = wt;
- isMouseDown = true;
- instance.runHooks('beforeOnCellMouseDown', event, coords, TD, blockCalculations);
- if (isImmediatePropagationStopped(event)) {
- return;
- }
- let actualSelection = instance.getSelectedRange();
- let selection = instance.selection;
- let selectedHeader = selection.selectedHeader;
- if (event.shiftKey && actualSelection) {
- if (coords.row >= 0 && coords.col >= 0 && !blockCalculations.cells) {
- selection.setSelectedHeaders(false, false);
- selection.setRangeEnd(coords);
- } else if ((selectedHeader.cols || selectedHeader.rows) && coords.row >= 0 && coords.col >= 0 && !blockCalculations.cells) {
- selection.setSelectedHeaders(false, false);
- selection.setRangeEnd(new CellCoords(coords.row, coords.col));
- } else if (selectedHeader.cols && coords.row < 0 && !blockCalculations.column) {
- selection.setRangeEnd(new CellCoords(actualSelection.to.row, coords.col));
- } else if (selectedHeader.rows && coords.col < 0 && !blockCalculations.row) {
- selection.setRangeEnd(new CellCoords(coords.row, actualSelection.to.col));
- } else if (((!selectedHeader.cols && !selectedHeader.rows && coords.col < 0) ||
- (selectedHeader.cols && coords.col < 0)) && !blockCalculations.row) {
- selection.setSelectedHeaders(true, false);
- selection.setRangeStartOnly(new CellCoords(actualSelection.from.row, 0));
- selection.setRangeEnd(new CellCoords(coords.row, instance.countCols() - 1));
- } else if (((!selectedHeader.cols && !selectedHeader.rows && coords.row < 0) ||
- (selectedHeader.rows && coords.row < 0)) && !blockCalculations.column) {
- selection.setSelectedHeaders(false, true);
- selection.setRangeStartOnly(new CellCoords(0, actualSelection.from.col));
- selection.setRangeEnd(new CellCoords(instance.countRows() - 1, coords.col));
- }
- } else {
- let doNewSelection = true;
- if (actualSelection) {
- let {from, to} = actualSelection;
- let coordsNotInSelection = !selection.inInSelection(coords);
- if (coords.row < 0 && selectedHeader.cols) {
- let start = Math.min(from.col, to.col);
- let end = Math.max(from.col, to.col);
- doNewSelection = (coords.col < start || coords.col > end);
- } else if (coords.col < 0 && selectedHeader.rows) {
- let start = Math.min(from.row, to.row);
- let end = Math.max(from.row, to.row);
- doNewSelection = (coords.row < start || coords.row > end);
- } else {
- doNewSelection = coordsNotInSelection;
- }
- }
- const rightClick = isRightClick(event);
- const leftClick = isLeftClick(event) || event.type === 'touchstart';
- // clicked row header and when some column was selected
- if (coords.row < 0 && coords.col >= 0 && !blockCalculations.column) {
- selection.setSelectedHeaders(false, true);
- if (leftClick || (rightClick && doNewSelection)) {
- selection.setRangeStartOnly(new CellCoords(0, coords.col));
- selection.setRangeEnd(new CellCoords(Math.max(instance.countRows() - 1, 0), coords.col), false);
- }
- // clicked column header and when some row was selected
- } else if (coords.col < 0 && coords.row >= 0 && !blockCalculations.row) {
- selection.setSelectedHeaders(true, false);
- if (leftClick || (rightClick && doNewSelection)) {
- selection.setRangeStartOnly(new CellCoords(coords.row, 0));
- selection.setRangeEnd(new CellCoords(coords.row, Math.max(instance.countCols() - 1, 0)), false);
- }
- } else if (coords.col >= 0 && coords.row >= 0 && !blockCalculations.cells) {
- if (leftClick || (rightClick && doNewSelection)) {
- selection.setSelectedHeaders(false, false);
- selection.setRangeStart(coords);
- }
- } else if (coords.col < 0 && coords.row < 0) {
- coords.row = 0;
- coords.col = 0;
- selection.setSelectedHeaders(false, false, true);
- selection.setRangeStart(coords);
- }
- }
- instance.runHooks('afterOnCellMouseDown', event, coords, TD);
- that.activeWt = that.wt;
- },
- onCellMouseOut: function(event, coords, TD, wt) {
- that.activeWt = wt;
- instance.runHooks('beforeOnCellMouseOut', event, coords, TD);
- if (isImmediatePropagationStopped(event)) {
- return;
- }
- instance.runHooks('afterOnCellMouseOut', event, coords, TD);
- that.activeWt = that.wt;
- },
- onCellMouseOver: function(event, coords, TD, wt) {
- let blockCalculations = {
- row: false,
- column: false,
- cell: false
- };
- that.activeWt = wt;
- instance.runHooks('beforeOnCellMouseOver', event, coords, TD, blockCalculations);
- if (isImmediatePropagationStopped(event)) {
- return;
- }
- if (event.button === 0 && isMouseDown) {
- if (coords.row >= 0 && coords.col >= 0) { // is not a header
- if (instance.selection.selectedHeader.cols && !blockCalculations.column) {
- instance.selection.setRangeEnd(new CellCoords(instance.countRows() - 1, coords.col), false);
- } else if (instance.selection.selectedHeader.rows && !blockCalculations.row) {
- instance.selection.setRangeEnd(new CellCoords(coords.row, instance.countCols() - 1), false);
- } else if (!blockCalculations.cell) {
- instance.selection.setRangeEnd(coords);
- }
- } else {
- /* eslint-disable no-lonely-if */
- if (instance.selection.selectedHeader.cols && !blockCalculations.column) {
- instance.selection.setRangeEnd(new CellCoords(instance.countRows() - 1, coords.col), false);
- } else if (instance.selection.selectedHeader.rows && !blockCalculations.row) {
- instance.selection.setRangeEnd(new CellCoords(coords.row, instance.countCols() - 1), false);
- } else if (!blockCalculations.cell) {
- instance.selection.setRangeEnd(coords);
- }
- }
- }
- instance.runHooks('afterOnCellMouseOver', event, coords, TD);
- that.activeWt = that.wt;
- },
- onCellMouseUp: function(event, coords, TD, wt) {
- that.activeWt = wt;
- instance.runHooks('beforeOnCellMouseUp', event, coords, TD);
- instance.runHooks('afterOnCellMouseUp', event, coords, TD);
- that.activeWt = that.wt;
- },
- onCellCornerMouseDown: function(event) {
- event.preventDefault();
- instance.runHooks('afterOnCellCornerMouseDown', event);
- },
- onCellCornerDblClick: function(event) {
- event.preventDefault();
- instance.runHooks('afterOnCellCornerDblClick', event);
- },
- beforeDraw: function(force, skipRender) {
- that.beforeRender(force, skipRender);
- },
- onDraw: function(force) {
- that.onDraw(force);
- },
- onScrollVertically: function() {
- instance.runHooks('afterScrollVertically');
- },
- onScrollHorizontally: function() {
- instance.runHooks('afterScrollHorizontally');
- },
- onBeforeDrawBorders: function(corners, borderClassName) {
- instance.runHooks('beforeDrawBorders', corners, borderClassName);
- },
- onBeforeTouchScroll: function() {
- instance.runHooks('beforeTouchScroll');
- },
- onAfterMomentumScroll: function() {
- instance.runHooks('afterMomentumScroll');
- },
- onBeforeStretchingColumnWidth: function(stretchedWidth, column) {
- return instance.runHooks('beforeStretchingColumnWidth', stretchedWidth, column);
- },
- onModifyRowHeaderWidth: function(rowHeaderWidth) {
- return instance.runHooks('modifyRowHeaderWidth', rowHeaderWidth);
- },
- viewportRowCalculatorOverride: function(calc) {
- let rows = instance.countRows();
- let viewportOffset = that.settings.viewportRowRenderingOffset;
- if (viewportOffset === 'auto' && that.settings.fixedRowsTop) {
- viewportOffset = 10;
- }
- if (typeof viewportOffset === 'number') {
- calc.startRow = Math.max(calc.startRow - viewportOffset, 0);
- calc.endRow = Math.min(calc.endRow + viewportOffset, rows - 1);
- }
- if (viewportOffset === 'auto') {
- let center = calc.startRow + calc.endRow - calc.startRow;
- let offset = Math.ceil(center / rows * 12);
- calc.startRow = Math.max(calc.startRow - offset, 0);
- calc.endRow = Math.min(calc.endRow + offset, rows - 1);
- }
- instance.runHooks('afterViewportRowCalculatorOverride', calc);
- },
- viewportColumnCalculatorOverride: function(calc) {
- let cols = instance.countCols();
- let viewportOffset = that.settings.viewportColumnRenderingOffset;
- if (viewportOffset === 'auto' && that.settings.fixedColumnsLeft) {
- viewportOffset = 10;
- }
- if (typeof viewportOffset === 'number') {
- calc.startColumn = Math.max(calc.startColumn - viewportOffset, 0);
- calc.endColumn = Math.min(calc.endColumn + viewportOffset, cols - 1);
- }
- if (viewportOffset === 'auto') {
- let center = calc.startColumn + calc.endColumn - calc.startColumn;
- let offset = Math.ceil(center / cols * 12);
- calc.startRow = Math.max(calc.startColumn - offset, 0);
- calc.endColumn = Math.min(calc.endColumn + offset, cols - 1);
- }
- instance.runHooks('afterViewportColumnCalculatorOverride', calc);
- },
- rowHeaderWidth: function() {
- return that.settings.rowHeaderWidth;
- },
- columnHeaderHeight: function() {
- const columnHeaderHeight = instance.runHooks('modifyColumnHeaderHeight');
- return that.settings.columnHeaderHeight || columnHeaderHeight;
- }
- };
- instance.runHooks('beforeInitWalkontable', walkontableConfig);
- this.wt = new Walkontable(walkontableConfig);
- this.activeWt = this.wt;
- if (!isChrome() && !isSafari()) {
- this.eventManager.addEventListener(instance.rootElement, 'wheel', (event) => {
- event.preventDefault();
- const lineHeight = parseInt(getComputedStyle(document.body)['font-size'], 10);
- const holder = that.wt.wtOverlays.scrollableElement;
- let deltaY = event.wheelDeltaY || event.deltaY;
- let deltaX = event.wheelDeltaX || event.deltaX;
- switch (event.deltaMode) {
- case 0:
- holder.scrollLeft += deltaX;
- holder.scrollTop += deltaY;
- break;
- case 1:
- holder.scrollLeft += deltaX * lineHeight;
- holder.scrollTop += deltaY * lineHeight;
- break;
- default:
- break;
- }
- });
- }
- this.eventManager.addEventListener(that.wt.wtTable.spreader, 'mousedown', function(event) {
- // right mouse button exactly on spreader means right click on the right hand side of vertical scrollbar
- if (event.target === that.wt.wtTable.spreader && event.which === 3) {
- stopPropagation(event);
- }
- });
- this.eventManager.addEventListener(that.wt.wtTable.spreader, 'contextmenu', function(event) {
- // right mouse button exactly on spreader means right click on the right hand side of vertical scrollbar
- if (event.target === that.wt.wtTable.spreader && event.which === 3) {
- stopPropagation(event);
- }
- });
- this.eventManager.addEventListener(document.documentElement, 'click', function() {
- if (that.settings.observeDOMVisibility) {
- if (that.wt.drawInterrupted) {
- that.instance.forceFullRender = true;
- that.render();
- }
- }
- });
- }
- TableView.prototype.isTextSelectionAllowed = function(el) {
- if (isInput(el)) {
- return true;
- }
- let isChildOfTableBody = isChildOf(el, this.instance.view.wt.wtTable.spreader);
- if (this.settings.fragmentSelection === true && isChildOfTableBody) {
- return true;
- }
- if (this.settings.fragmentSelection === 'cell' && this.isSelectedOnlyCell() && isChildOfTableBody) {
- return true;
- }
- if (!this.settings.fragmentSelection && this.isCellEdited() && this.isSelectedOnlyCell()) {
- return true;
- }
- return false;
- };
- /**
- * Check if selected only one cell.
- *
- * @returns {Boolean}
- */
- TableView.prototype.isSelectedOnlyCell = function() {
- var [row, col, rowEnd, colEnd] = this.instance.getSelected() || [];
- return row !== void 0 && row === rowEnd && col === colEnd;
- };
- TableView.prototype.isCellEdited = function() {
- var activeEditor = this.instance.getActiveEditor();
- return activeEditor && activeEditor.isOpened();
- };
- TableView.prototype.beforeRender = function(force, skipRender) {
- if (force) {
- // this.instance.forceFullRender = did Handsontable request full render?
- this.instance.runHooks('beforeRender', this.instance.forceFullRender, skipRender);
- }
- };
- TableView.prototype.onDraw = function(force) {
- if (force) {
- // this.instance.forceFullRender = did Handsontable request full render?
- this.instance.runHooks('afterRender', this.instance.forceFullRender);
- }
- };
- TableView.prototype.render = function() {
- this.wt.draw(!this.instance.forceFullRender);
- this.instance.forceFullRender = false;
- this.instance.renderCall = false;
- };
- /**
- * Returns td object given coordinates
- *
- * @param {CellCoords} coords
- * @param {Boolean} topmost
- */
- TableView.prototype.getCellAtCoords = function(coords, topmost) {
- var td = this.wt.getCell(coords, topmost);
- if (td < 0) { // there was an exit code (cell is out of bounds)
- return null;
- }
- return td;
- };
- /**
- * Scroll viewport to selection.
- *
- * @param {CellCoords} coords
- */
- TableView.prototype.scrollViewport = function(coords) {
- this.wt.scrollViewport(coords);
- };
- /**
- * Append row header to a TH element
- * @param row
- * @param TH
- */
- TableView.prototype.appendRowHeader = function(row, TH) {
- if (TH.firstChild) {
- let container = TH.firstChild;
- if (!hasClass(container, 'relative')) {
- empty(TH);
- this.appendRowHeader(row, TH);
- return;
- }
- this.updateCellHeader(container.querySelector('.rowHeader'), row, this.instance.getRowHeader);
- } else {
- let div = document.createElement('div');
- let span = document.createElement('span');
- div.className = 'relative';
- span.className = 'rowHeader';
- this.updateCellHeader(span, row, this.instance.getRowHeader);
- div.appendChild(span);
- TH.appendChild(div);
- }
- this.instance.runHooks('afterGetRowHeader', row, TH);
- };
- /**
- * Append column header to a TH element
- * @param col
- * @param TH
- */
- TableView.prototype.appendColHeader = function(col, TH) {
- if (TH.firstChild) {
- let container = TH.firstChild;
- if (hasClass(container, 'relative')) {
- this.updateCellHeader(container.querySelector('.colHeader'), col, this.instance.getColHeader);
- } else {
- empty(TH);
- this.appendColHeader(col, TH);
- }
- } else {
- var div = document.createElement('div');
- let span = document.createElement('span');
- div.className = 'relative';
- span.className = 'colHeader';
- this.updateCellHeader(span, col, this.instance.getColHeader);
- div.appendChild(span);
- TH.appendChild(div);
- }
- this.instance.runHooks('afterGetColHeader', col, TH);
- };
- /**
- * Update header cell content
- *
- * @since 0.15.0-beta4
- * @param {HTMLElement} element Element to update
- * @param {Number} index Row index or column index
- * @param {Function} content Function which should be returns content for this cell
- */
- TableView.prototype.updateCellHeader = function(element, index, content) {
- let renderedIndex = index;
- let parentOverlay = this.wt.wtOverlays.getParentOverlay(element) || this.wt;
- // prevent wrong calculations from SampleGenerator
- if (element.parentNode) {
- if (hasClass(element, 'colHeader')) {
- renderedIndex = parentOverlay.wtTable.columnFilter.sourceToRendered(index);
- } else if (hasClass(element, 'rowHeader')) {
- renderedIndex = parentOverlay.wtTable.rowFilter.sourceToRendered(index);
- }
- }
- if (renderedIndex > -1) {
- fastInnerHTML(element, content(index));
- } else {
- // workaround for https://github.com/handsontable/handsontable/issues/1946
- fastInnerText(element, String.fromCharCode(160));
- addClass(element, 'cornerHeader');
- }
- };
- /**
- * Given a element's left position relative to the viewport, returns maximum element width until the right
- * edge of the viewport (before scrollbar)
- *
- * @param {Number} leftOffset
- * @return {Number}
- */
- TableView.prototype.maximumVisibleElementWidth = function(leftOffset) {
- var workspaceWidth = this.wt.wtViewport.getWorkspaceWidth();
- var maxWidth = workspaceWidth - leftOffset;
- return maxWidth > 0 ? maxWidth : 0;
- };
- /**
- * Given a element's top position relative to the viewport, returns maximum element height until the bottom
- * edge of the viewport (before scrollbar)
- *
- * @param {Number} topOffset
- * @return {Number}
- */
- TableView.prototype.maximumVisibleElementHeight = function(topOffset) {
- var workspaceHeight = this.wt.wtViewport.getWorkspaceHeight();
- var maxHeight = workspaceHeight - topOffset;
- return maxHeight > 0 ? maxHeight : 0;
- };
- TableView.prototype.mainViewIsActive = function() {
- return this.wt === this.activeWt;
- };
- TableView.prototype.destroy = function() {
- this.wt.destroy();
- this.eventManager.destroy();
- };
- export default TableView;
|