From 990d17d96a87e7da9c012333cbbaf4fbc719b44c Mon Sep 17 00:00:00 2001 From: Jesper Jakobsen Date: Fri, 3 Nov 2023 09:41:41 +0100 Subject: [PATCH 01/12] V1 of change, big example, old method 5-8 ms vs new is 8-11 ms --- examples/example-csp-header.html | 16 +++-- examples/example-csp-header.js | 64 +++++++++++++++++-- examples/example-optimizing-dataview.html | 6 +- src/slick.dataview.ts | 76 ++++++++++++++++++++--- 4 files changed, 143 insertions(+), 19 deletions(-) diff --git a/examples/example-csp-header.html b/examples/example-csp-header.html index eeba0d015..b6ff5237e 100644 --- a/examples/example-csp-header.html +++ b/examples/example-csp-header.html @@ -4,8 +4,9 @@ - - + + + @@ -33,12 +34,17 @@

View Source:

+ + + + - - - + + + + \ No newline at end of file diff --git a/examples/example-csp-header.js b/examples/example-csp-header.js index 37a040949..bbd588ea2 100644 --- a/examples/example-csp-header.js +++ b/examples/example-csp-header.js @@ -1,4 +1,6 @@ var grid; +var dataView; +var searchString; var columns = [ { id: "title", name: "Title", field: "title" }, { id: "duration", name: "Duration", field: "duration" }, @@ -26,8 +28,9 @@ document.addEventListener("DOMContentLoaded", function () { linkElement.style.fontSize = "22px"; var data = []; - for (var i = 0; i < 500; i++) { + for (var i = 0; i < 500000; i++) { data[i] = { + id: i, title: "Task " + i, duration: "5 days", percentComplete: Math.round(Math.random() * 100), @@ -57,7 +60,60 @@ document.addEventListener("DOMContentLoaded", function () { } }; - grid = new Slick.Grid("#myGrid", data, columns, options); + dataView = new Slick.Data.DataView({ inlineFilters: true }); + grid = new Slick.Grid("#myGrid", dataView, columns, options); + dataView.grid = grid; + // grid.setSelectionModel(new Slick.CellSelectionModel()); + grid.setSelectionModel(new Slick.RowSelectionModel({ selectActiveRow: true})); - grid.setSelectionModel(new Slick.CellSelectionModel()); -}); \ No newline at end of file + grid.onSort.subscribe(function (e, args) { + var comparer = function (a, b) { + if (args.sortCols[0].sortAsc) + return (a[args.sortCols[0].sortCol.field] > b[args.sortCols[0].sortCol.field]) ? 1 : -1; + else + return (a[args.sortCols[0].sortCol.field] < b[args.sortCols[0].sortCol.field]) ? 1 : -1; + } + + this.getData().sort(comparer, args.sortAsc); + }); + dataView.onRowCountChanged.subscribe(function (e, args) { + args.dataView.grid.updateRowCount(); + args.dataView.grid.render(); + }); + + dataView.onRowsChanged.subscribe(function (e, args) { + args.dataView.grid.invalidateRows(args.rows); + args.dataView.grid.render(); + }); + + dataView.beginUpdate(); + dataView.setItems(data); + dataView.setFilterArgs({ searchString: searchString }); + dataView.setFilter(myFilter); + dataView.endUpdate(); +}); +function updateFilter() { + dataView.setFilterArgs({ + searchString: searchString + }); + dataView.refresh(); +} +function myFilter(item, args) { + console.log(item, args) + var searchForString = args.searchString?.toLowerCase(); + //Check if input is empty + if (searchForString?.length == 0 || !searchForString) { + return true; + } + let keys = columns;// args.context.keys; + //Check if input value includes searchString value + for (var i = 0; i < keys.length; i++) { + if (item[keys[i]?.field] != null) { + if (item[keys[i]?.field].toString().toLowerCase().includes(searchForString)) { + return true; + } + } + } + + return false; +} \ No newline at end of file diff --git a/examples/example-optimizing-dataview.html b/examples/example-optimizing-dataview.html index 5d5b055ca..5145d654e 100644 --- a/examples/example-optimizing-dataview.html +++ b/examples/example-optimizing-dataview.html @@ -145,11 +145,11 @@

View Source:

// wire up the slider to apply the filter to the model var slider = document.getElementById("pcSlider"); var sliderCallback = function() { - if (percentCompleteThreshold != this.value) { + // if (percentCompleteThreshold != this.value) { window.clearTimeout(h_runfilters); h_runfilters = window.setTimeout(filterAndUpdate, 10); percentCompleteThreshold = this.value; - } + // } } slider.oninput = sliderCallback; @@ -173,7 +173,7 @@

View Source:

// initialize the model after all the events have been hooked up dataView.beginUpdate(); dataView.setItems(data); - dataView.setFilter(myFilter); + dataView.setFilter(myFilter, myFilter); dataView.setFilterArgs(0); dataView.endUpdate(); }); diff --git a/src/slick.dataview.ts b/src/slick.dataview.ts index 98d34ce9c..fac3d317f 100644 --- a/src/slick.dataview.ts +++ b/src/slick.dataview.ts @@ -60,6 +60,7 @@ export class SlickDataView implements CustomD protected idxById = new Map(); // indexes by id protected rowsById: { [id: DataIdType]: number } | undefined = undefined; // rows by id; lazy-calculated protected filter: FilterFn | null = null; // filter function + protected filterNew: Function | null = null; // filter function protected updated: ({ [id: DataIdType]: boolean }) | null = null; // updated item ids protected suspend = false; // suspends the recalculation protected isBulkSuspend = false; // delays protectedious operations like the @@ -74,9 +75,12 @@ export class SlickDataView implements CustomD protected filterArgs: any; protected filteredItems: TData[] = []; protected compiledFilter?: FilterFn | null; + protected compiledFilterNew?: Function | null; protected compiledFilterWithCaching?: FilterFn | null; + protected compiledFilterWithCachingNew?: Function | null; protected filterCache: any[] = []; protected _grid?: SlickGrid; // grid object will be defined only after using "syncGridSelection()" method" + protected useNewFilter = false; // grouping protected groupingInfoDefaults: Grouping = { @@ -359,16 +363,20 @@ export class SlickDataView implements CustomD /** Get current Filter used by the DataView */ getFilter() { - return this.filter; + return this.useNewFilter ? this.filterNew : this.filter; } /** * Set a Filter that will be used by the DataView * @param {Function} fn - filter callback function */ - setFilter(filterFn: FilterFn) { + setFilter(filterFn: FilterFn, filterFnNew: Function) { + // console.log(filterFnNew, filterFn, "hit"); + this.filterNew = filterFnNew; this.filter = filterFn; if (this._options.inlineFilters) { + this.compiledFilterNew = this.compileFilterNew; + this.compiledFilterWithCachingNew = this.compileFilterWithCachingNew; this.compiledFilter = this.compileFilter(); this.compiledFilterWithCaching = this.compileFilterWithCaching(); } @@ -1022,6 +1030,29 @@ export class SlickDataView implements CustomD } } + protected compileFilterNew(_items: TData[], _args: any): TData[] { + //const filterInfo = this.getFunctionInfo(this.filter as Function); + + //how do i fix this error? + + // const filterPath1 = () => { continue _coreloop; }; + // const filterPath2 = () => { _retval[_idx++] = $item$; continue _coreloop; }; + const _retval: TData[] = []; + let $item$; + + _coreloop: + for (let _i = 0, _il = _items.length; _i < _il; _i++) { + $item$ = _items[_i]; + if(this.filterNew){ + const exists = this.filterNew($item$, _args); + if(exists){ + _retval.push($item$); + } + } + } + + return _retval; + } protected compileFilter(): FilterFn { const filterInfo = this.getFunctionInfo(this.filter as Function); @@ -1104,6 +1135,26 @@ export class SlickDataView implements CustomD return fn; } + protected compileFilterWithCachingNew(_items: TData[], _args: any, filterCache: any[]): TData[]{ + const _retval: TData[] = []; + let _idx = 0; + let $item$; + _coreloop: + for (let _i = 0, _il = _items.length; _i < _il; _i++) { + $item$ = _items[_i]; + if (filterCache[_i]) { + _retval[_idx++] = $item$; + continue _coreloop; + } + //should only be called if it isnt present in the cache + if(this.filterNew && this.filterNew($item$, _args)){ + _retval.push($item$); + } + } + + return _retval; + } + /** * In ES5 we could set the function name on the fly but in ES6 this is forbidden and we need to set it through differently * We can use Object.defineProperty and set it the property to writable, see MDN for reference @@ -1154,10 +1205,19 @@ export class SlickDataView implements CustomD } protected getFilteredAndPagedItems(items: TData[]) { - if (this.filter) { - const batchFilter = (this._options.inlineFilters ? this.compiledFilter : this.uncompiledFilter) as Function; - const batchFilterWithCaching = (this._options.inlineFilters ? this.compiledFilterWithCaching : this.uncompiledFilterWithCaching) as Function; - + console.time("start"); + + if (this.useNewFilter ? this.filterNew : this.filter) { + let batchFilter: Function; + let batchFilterWithCaching: Function; + if(this.useNewFilter){ + batchFilter = (this._options.inlineFilters ? this.compiledFilterNew : this.uncompiledFilter) as Function; + batchFilterWithCaching = (this._options.inlineFilters ? this.compiledFilterWithCachingNew : this.uncompiledFilterWithCaching) as Function; + }else { + batchFilter = (this._options.inlineFilters ? this.compiledFilter : this.uncompiledFilter) as Function; + batchFilterWithCaching = (this._options.inlineFilters ? this.compiledFilterWithCaching : this.uncompiledFilterWithCaching) as Function; + } + // console.log(batchFilter, batchFilterWithCaching); if (this.refreshHints.isFilterNarrowing) { this.filteredItems = batchFilter.call(this, this.filteredItems, this.filterArgs); } else if (this.refreshHints.isFilterExpanding) { @@ -1165,13 +1225,14 @@ export class SlickDataView implements CustomD } else if (!this.refreshHints.isFilterUnchanged) { this.filteredItems = batchFilter.call(this, items, this.filterArgs); } + // console.log(this.filteredItems, "items"); } else { // special case: if not filtering and not paging, the resulting // rows collection needs to be a copy so that changes due to sort // can be caught this.filteredItems = this.pagesize ? items : items.concat(); } - + // console.timeLog("start"); // get the current page let paged: TData[]; if (this.pagesize) { @@ -1186,6 +1247,7 @@ export class SlickDataView implements CustomD } else { paged = this.filteredItems; } + console.timeEnd("start"); return { totalRows: this.filteredItems.length, rows: paged }; } From b9cd46c6e8fe48217bb231aed68f532eb30780d9 Mon Sep 17 00:00:00 2001 From: Jesper Jakobsen Date: Fri, 3 Nov 2023 10:25:02 +0100 Subject: [PATCH 02/12] after some minor optimizations on the 2 functions --- examples/example-optimizing-dataview.html | 39 ++++++------- src/slick.dataview.ts | 68 ++++++++++------------- 2 files changed, 48 insertions(+), 59 deletions(-) diff --git a/examples/example-optimizing-dataview.html b/examples/example-optimizing-dataview.html index 5145d654e..a135768f2 100644 --- a/examples/example-optimizing-dataview.html +++ b/examples/example-optimizing-dataview.html @@ -146,30 +146,15 @@

View Source:

var slider = document.getElementById("pcSlider"); var sliderCallback = function() { // if (percentCompleteThreshold != this.value) { - window.clearTimeout(h_runfilters); - h_runfilters = window.setTimeout(filterAndUpdate, 10); + // window.clearTimeout(h_runfilters); + // h_runfilters = window.setTimeout(filterAndUpdate, 10); + filterAndUpdate(); percentCompleteThreshold = this.value; // } } slider.oninput = sliderCallback; - function filterAndUpdate() { - var isNarrowing = percentCompleteThreshold > prevPercentCompleteThreshold; - var isExpanding = percentCompleteThreshold < prevPercentCompleteThreshold; - var renderedRange = grid.getRenderedRange(); - - dataView.setFilterArgs(percentCompleteThreshold); - dataView.setRefreshHints({ - ignoreDiffsBefore: renderedRange.top, - ignoreDiffsAfter: renderedRange.bottom + 1, - isFilterNarrowing: isNarrowing, - isFilterExpanding: isExpanding - }); - dataView.refresh(); - - prevPercentCompleteThreshold = percentCompleteThreshold; - } - + // initialize the model after all the events have been hooked up dataView.beginUpdate(); dataView.setItems(data); @@ -177,6 +162,22 @@

View Source:

dataView.setFilterArgs(0); dataView.endUpdate(); }); + function filterAndUpdate() { + var isNarrowing = percentCompleteThreshold > prevPercentCompleteThreshold; + var isExpanding = percentCompleteThreshold < prevPercentCompleteThreshold; + var renderedRange = grid.getRenderedRange(); + + dataView.setFilterArgs(percentCompleteThreshold); + dataView.setRefreshHints({ + ignoreDiffsBefore: renderedRange.top, + ignoreDiffsAfter: renderedRange.bottom + 1, + isFilterNarrowing: isNarrowing, + isFilterExpanding: isExpanding + }); + dataView.refresh(); + + prevPercentCompleteThreshold = percentCompleteThreshold; + } diff --git a/src/slick.dataview.ts b/src/slick.dataview.ts index fac3d317f..2b9bab289 100644 --- a/src/slick.dataview.ts +++ b/src/slick.dataview.ts @@ -80,7 +80,7 @@ export class SlickDataView implements CustomD protected compiledFilterWithCachingNew?: Function | null; protected filterCache: any[] = []; protected _grid?: SlickGrid; // grid object will be defined only after using "syncGridSelection()" method" - protected useNewFilter = false; + protected useNewFilter = true; // grouping protected groupingInfoDefaults: Grouping = { @@ -1031,26 +1031,18 @@ export class SlickDataView implements CustomD } protected compileFilterNew(_items: TData[], _args: any): TData[] { - //const filterInfo = this.getFunctionInfo(this.filter as Function); - - //how do i fix this error? - - // const filterPath1 = () => { continue _coreloop; }; - // const filterPath2 = () => { _retval[_idx++] = $item$; continue _coreloop; }; + if (typeof this.filterNew !== 'function') { + return []; + } const _retval: TData[] = []; - let $item$; - - _coreloop: - for (let _i = 0, _il = _items.length; _i < _il; _i++) { - $item$ = _items[_i]; - if(this.filterNew){ - const exists = this.filterNew($item$, _args); - if(exists){ - _retval.push($item$); - } + const _il = _items.length; + + for (let _i = 0; _i < _il; _i++) { + if (this.filterNew(_items[_i], _args)) { + _retval.push(_items[_i]); } - } - + } + return _retval; } protected compileFilter(): FilterFn { @@ -1135,23 +1127,20 @@ export class SlickDataView implements CustomD return fn; } - protected compileFilterWithCachingNew(_items: TData[], _args: any, filterCache: any[]): TData[]{ + protected compileFilterWithCachingNew(_items: TData[], _args: any, filterCache: any[]): TData[] { + if (typeof this.filterNew !== 'function') { + return []; + } + const _retval: TData[] = []; - let _idx = 0; - let $item$; - _coreloop: - for (let _i = 0, _il = _items.length; _i < _il; _i++) { - $item$ = _items[_i]; - if (filterCache[_i]) { - _retval[_idx++] = $item$; - continue _coreloop; - } - //should only be called if it isnt present in the cache - if(this.filterNew && this.filterNew($item$, _args)){ - _retval.push($item$); + const _il = _items.length; + + for (let _i = 0; _i < _il; _i++) { + if (filterCache[_i] || this.filterNew(_items[_i], _args)) { + _retval.push(_items[_i]); } } - + return _retval; } @@ -1205,15 +1194,14 @@ export class SlickDataView implements CustomD } protected getFilteredAndPagedItems(items: TData[]) { - console.time("start"); - + console.time("filtering"); if (this.useNewFilter ? this.filterNew : this.filter) { let batchFilter: Function; let batchFilterWithCaching: Function; - if(this.useNewFilter){ + if (this.useNewFilter) { batchFilter = (this._options.inlineFilters ? this.compiledFilterNew : this.uncompiledFilter) as Function; batchFilterWithCaching = (this._options.inlineFilters ? this.compiledFilterWithCachingNew : this.uncompiledFilterWithCaching) as Function; - }else { + } else { batchFilter = (this._options.inlineFilters ? this.compiledFilter : this.uncompiledFilter) as Function; batchFilterWithCaching = (this._options.inlineFilters ? this.compiledFilterWithCaching : this.uncompiledFilterWithCaching) as Function; } @@ -1232,7 +1220,7 @@ export class SlickDataView implements CustomD // can be caught this.filteredItems = this.pagesize ? items : items.concat(); } - // console.timeLog("start"); + // get the current page let paged: TData[]; if (this.pagesize) { @@ -1247,7 +1235,7 @@ export class SlickDataView implements CustomD } else { paged = this.filteredItems; } - console.timeEnd("start"); + console.timeEnd("filtering"); return { totalRows: this.filteredItems.length, rows: paged }; } @@ -1280,7 +1268,7 @@ export class SlickDataView implements CustomD // no good way to compare totals since they are arbitrary DTOs // deep object comparison is pretty expensive // always considering them 'dirty' seems easier for the time being - ((item as SlickGroupTotals_).__groupTotals || (r as SlickGroupTotals_).__groupTotals)) + ((item as SlickGroupTotals_).__groupTotals || (r as SlickGroupTotals_).__groupTotals)) || item[this.idProperty as keyof TData] !== r[this.idProperty as keyof TData] || (this.updated?.[item[this.idProperty as keyof TData]]) ) { From b70eee80e7ef391c74f2d19d4151627b70742a80 Mon Sep 17 00:00:00 2001 From: Jesper Jakobsen Date: Mon, 6 Nov 2023 09:23:47 +0100 Subject: [PATCH 03/12] added 'useCSPSafeFilter' to dataview options --- cypress/e2e/example-csp-header.cy.ts | 2 +- examples/example-csp-header.html | 7 ++- examples/example-csp-header.js | 28 +++++----- examples/example-optimizing-dataview.html | 45 ++++++++-------- src/slick.dataview.ts | 65 ++++++++++++----------- 5 files changed, 79 insertions(+), 68 deletions(-) diff --git a/cypress/e2e/example-csp-header.cy.ts b/cypress/e2e/example-csp-header.cy.ts index 4c2bcc661..1c487e23a 100644 --- a/cypress/e2e/example-csp-header.cy.ts +++ b/cypress/e2e/example-csp-header.cy.ts @@ -16,7 +16,7 @@ describe('Example CSP Header - with Column Span & Header Grouping', () => { it('should display Example title', () => { cy.visit(`${Cypress.config('baseUrl')}/examples/example-csp-header.html`); cy.get('h2').contains('Demonstrates'); - cy.get('h2 + ul > li').first().contains('column span'); + cy.get('h2 + ul > li').first().contains('CSP header'); }); it('should have exact column titles', () => { diff --git a/examples/example-csp-header.html b/examples/example-csp-header.html index b6ff5237e..78f18d118 100644 --- a/examples/example-csp-header.html +++ b/examples/example-csp-header.html @@ -5,8 +5,9 @@ + - +
@@ -15,12 +16,14 @@
+ +

Demonstrates:

    -
  • column span
  • +
  • CSP header, Currently used "default-src 'self'; script-src 'self' https://cdn.jsdelivr.net https://cdnjs.cloudflare.com 'nonce-browser-sync'; style-src 'self' 'unsafe-inline'; require-trusted-types-for 'script'; trusted-types dompurify"

View Source:

    diff --git a/examples/example-csp-header.js b/examples/example-csp-header.js index bbd588ea2..57cf36db2 100644 --- a/examples/example-csp-header.js +++ b/examples/example-csp-header.js @@ -13,7 +13,7 @@ var columns = [ var options = { enableCellNavigation: true, enableColumnReorder: false, - nonce: 'random-string', + // nonce: 'random-string', //tmp removal because there is another issue which needs to get fixed before this can be added back, alteast for testing sanitizer: (html) => DOMPurify.sanitize(html, { RETURN_TRUSTED_TYPE: true }) }; @@ -21,6 +21,15 @@ document.addEventListener("DOMContentLoaded", function () { let gridElement = document.getElementById("myGrid"); gridElement.style.width = "600px"; gridElement.style.height = "500px"; + let search = document.getElementById("search"); + let searchLabel= document.getElementById("search-label"); + searchLabel.style.width = "200px"; + searchLabel.style.float = "left"; + search.style.width = "100px"; + search.addEventListener("input", function (e) { + searchString = e.target.value; + updateFilter(); + }); let linkElement = document.getElementById("link"); //text-decoration: none; font-size: 22px @@ -28,7 +37,7 @@ document.addEventListener("DOMContentLoaded", function () { linkElement.style.fontSize = "22px"; var data = []; - for (var i = 0; i < 500000; i++) { + for (var i = 0; i < 500; i++) { data[i] = { id: i, title: "Task " + i, @@ -40,7 +49,8 @@ document.addEventListener("DOMContentLoaded", function () { }; } - data.getItemMetadata = function (row) { + dataView = new Slick.Data.DataView({ inlineFilters: true, useCSPSafeFilter: true }); + dataView.getItemMetadata = function (row) { if (row % 2 === 1) { return { "columns": { @@ -60,10 +70,8 @@ document.addEventListener("DOMContentLoaded", function () { } }; - dataView = new Slick.Data.DataView({ inlineFilters: true }); grid = new Slick.Grid("#myGrid", dataView, columns, options); dataView.grid = grid; - // grid.setSelectionModel(new Slick.CellSelectionModel()); grid.setSelectionModel(new Slick.RowSelectionModel({ selectActiveRow: true})); grid.onSort.subscribe(function (e, args) { @@ -99,19 +107,15 @@ function updateFilter() { dataView.refresh(); } function myFilter(item, args) { - console.log(item, args) var searchForString = args.searchString?.toLowerCase(); //Check if input is empty if (searchForString?.length == 0 || !searchForString) { return true; } - let keys = columns;// args.context.keys; //Check if input value includes searchString value - for (var i = 0; i < keys.length; i++) { - if (item[keys[i]?.field] != null) { - if (item[keys[i]?.field].toString().toLowerCase().includes(searchForString)) { - return true; - } + for (var i = 0; i < columns.length; i++) { + if (item[columns[i]?.field] != null && item[columns[i]?.field].toString().toLowerCase().includes(searchForString)) { + return true; } } diff --git a/examples/example-optimizing-dataview.html b/examples/example-optimizing-dataview.html index a135768f2..5d5b055ca 100644 --- a/examples/example-optimizing-dataview.html +++ b/examples/example-optimizing-dataview.html @@ -145,39 +145,38 @@

    View Source:

    // wire up the slider to apply the filter to the model var slider = document.getElementById("pcSlider"); var sliderCallback = function() { - // if (percentCompleteThreshold != this.value) { - // window.clearTimeout(h_runfilters); - // h_runfilters = window.setTimeout(filterAndUpdate, 10); - filterAndUpdate(); + if (percentCompleteThreshold != this.value) { + window.clearTimeout(h_runfilters); + h_runfilters = window.setTimeout(filterAndUpdate, 10); percentCompleteThreshold = this.value; - // } + } } slider.oninput = sliderCallback; - + function filterAndUpdate() { + var isNarrowing = percentCompleteThreshold > prevPercentCompleteThreshold; + var isExpanding = percentCompleteThreshold < prevPercentCompleteThreshold; + var renderedRange = grid.getRenderedRange(); + + dataView.setFilterArgs(percentCompleteThreshold); + dataView.setRefreshHints({ + ignoreDiffsBefore: renderedRange.top, + ignoreDiffsAfter: renderedRange.bottom + 1, + isFilterNarrowing: isNarrowing, + isFilterExpanding: isExpanding + }); + dataView.refresh(); + + prevPercentCompleteThreshold = percentCompleteThreshold; + } + // initialize the model after all the events have been hooked up dataView.beginUpdate(); dataView.setItems(data); - dataView.setFilter(myFilter, myFilter); + dataView.setFilter(myFilter); dataView.setFilterArgs(0); dataView.endUpdate(); }); - function filterAndUpdate() { - var isNarrowing = percentCompleteThreshold > prevPercentCompleteThreshold; - var isExpanding = percentCompleteThreshold < prevPercentCompleteThreshold; - var renderedRange = grid.getRenderedRange(); - - dataView.setFilterArgs(percentCompleteThreshold); - dataView.setRefreshHints({ - ignoreDiffsBefore: renderedRange.top, - ignoreDiffsAfter: renderedRange.bottom + 1, - isFilterNarrowing: isNarrowing, - isFilterExpanding: isExpanding - }); - dataView.refresh(); - - prevPercentCompleteThreshold = percentCompleteThreshold; - } diff --git a/src/slick.dataview.ts b/src/slick.dataview.ts index 2b9bab289..221f93d7d 100644 --- a/src/slick.dataview.ts +++ b/src/slick.dataview.ts @@ -36,6 +36,7 @@ const SlickGroupItemMetadataProvider = IIFE_ONLY ? Slick.Data?.GroupItemMetadata export interface DataViewOption { groupItemMetadataProvider: SlickGroupItemMetadataProvider_ | null; inlineFilters: boolean; + useCSPSafeFilter: boolean; } export type FilterFn = (item: T, args: any) => boolean; export type DataIdType = number | string; @@ -50,7 +51,8 @@ export type SlickDataItem = SlickNonDataItem | SlickGroup_ | SlickGroupTotals_ | export class SlickDataView implements CustomDataView { protected defaults: DataViewOption = { groupItemMetadataProvider: null, - inlineFilters: false + inlineFilters: false, + useCSPSafeFilter: false, }; // private @@ -60,7 +62,7 @@ export class SlickDataView implements CustomD protected idxById = new Map(); // indexes by id protected rowsById: { [id: DataIdType]: number } | undefined = undefined; // rows by id; lazy-calculated protected filter: FilterFn | null = null; // filter function - protected filterNew: Function | null = null; // filter function + protected filterCSPSafe: Function | null = null; // filter function protected updated: ({ [id: DataIdType]: boolean }) | null = null; // updated item ids protected suspend = false; // suspends the recalculation protected isBulkSuspend = false; // delays protectedious operations like the @@ -75,12 +77,11 @@ export class SlickDataView implements CustomD protected filterArgs: any; protected filteredItems: TData[] = []; protected compiledFilter?: FilterFn | null; - protected compiledFilterNew?: Function | null; + protected compiledFilterCSPSafe?: Function | null; protected compiledFilterWithCaching?: FilterFn | null; - protected compiledFilterWithCachingNew?: Function | null; + protected compiledFilterWithCachingCSPSafe?: Function | null; protected filterCache: any[] = []; protected _grid?: SlickGrid; // grid object will be defined only after using "syncGridSelection()" method" - protected useNewFilter = true; // grouping protected groupingInfoDefaults: Grouping = { @@ -151,12 +152,15 @@ export class SlickDataView implements CustomD this.idxById = null as any; this.rowsById = null as any; this.filter = null as any; + this.filterCSPSafe = null as any; this.updated = null as any; this.sortComparer = null as any; this.filterCache = []; this.filteredItems = []; this.compiledFilter = null; + this.compiledFilterCSPSafe = null; this.compiledFilterWithCaching = null; + this.compiledFilterWithCachingCSPSafe = null; if (this._grid && this._grid.onSelectedRowsChanged && this._grid.onCellCssStylesChanged) { this._grid.onSelectedRowsChanged.unsubscribe(); @@ -363,22 +367,21 @@ export class SlickDataView implements CustomD /** Get current Filter used by the DataView */ getFilter() { - return this.useNewFilter ? this.filterNew : this.filter; + return this._options.useCSPSafeFilter ? this.filterCSPSafe : this.filter; } /** * Set a Filter that will be used by the DataView * @param {Function} fn - filter callback function */ - setFilter(filterFn: FilterFn, filterFnNew: Function) { - // console.log(filterFnNew, filterFn, "hit"); - this.filterNew = filterFnNew; + setFilter(filterFn: FilterFn) { + this.filterCSPSafe = filterFn; this.filter = filterFn; if (this._options.inlineFilters) { - this.compiledFilterNew = this.compileFilterNew; - this.compiledFilterWithCachingNew = this.compileFilterWithCachingNew; - this.compiledFilter = this.compileFilter(); - this.compiledFilterWithCaching = this.compileFilterWithCaching(); + this.compiledFilterCSPSafe = this.compileFilterCSPSafe; + this.compiledFilterWithCachingCSPSafe = this.compileFilterWithCachingCSPSafe; + this.compiledFilter = this.compileFilter(this._options.useCSPSafeFilter); + this.compiledFilterWithCaching = this.compileFilterWithCaching(this._options.useCSPSafeFilter); } this.refresh(); } @@ -1030,22 +1033,25 @@ export class SlickDataView implements CustomD } } - protected compileFilterNew(_items: TData[], _args: any): TData[] { - if (typeof this.filterNew !== 'function') { + protected compileFilterCSPSafe(_items: TData[], _args: any): TData[] { + if (typeof this.filterCSPSafe !== 'function') { return []; } const _retval: TData[] = []; const _il = _items.length; for (let _i = 0; _i < _il; _i++) { - if (this.filterNew(_items[_i], _args)) { + if (this.filterCSPSafe(_items[_i], _args)) { _retval.push(_items[_i]); } } return _retval; } - protected compileFilter(): FilterFn { + protected compileFilter(stopRunningIfCSPSafeIsActive: boolean = false): FilterFn { + if(stopRunningIfCSPSafeIsActive) { + return null as any; + } const filterInfo = this.getFunctionInfo(this.filter as Function); const filterPath1 = "{ continue _coreloop; }$1"; @@ -1076,7 +1082,6 @@ export class SlickDataView implements CustomD tpl = tpl.replace(/\$filter\$/gi, filterBody); tpl = tpl.replace(/\$item\$/gi, filterInfo.params[0]); tpl = tpl.replace(/\$args\$/gi, filterInfo.params[1]); - const fn: any = new Function("_items,_args", tpl); const fnName = "compiledFilter"; fn.displayName = fnName; @@ -1084,7 +1089,11 @@ export class SlickDataView implements CustomD return fn; } - protected compileFilterWithCaching() { + protected compileFilterWithCaching(stopRunningIfCSPSafeIsActive: boolean = false) { + if(stopRunningIfCSPSafeIsActive) { + return null as any; + } + const filterInfo = this.getFunctionInfo(this.filter as Function); const filterPath1 = "{ continue _coreloop; }$1"; @@ -1127,8 +1136,8 @@ export class SlickDataView implements CustomD return fn; } - protected compileFilterWithCachingNew(_items: TData[], _args: any, filterCache: any[]): TData[] { - if (typeof this.filterNew !== 'function') { + protected compileFilterWithCachingCSPSafe(_items: TData[], _args: any, filterCache: any[]): TData[] { + if (typeof this.filterCSPSafe !== 'function') { return []; } @@ -1136,7 +1145,7 @@ export class SlickDataView implements CustomD const _il = _items.length; for (let _i = 0; _i < _il; _i++) { - if (filterCache[_i] || this.filterNew(_items[_i], _args)) { + if (filterCache[_i] || this.filterCSPSafe(_items[_i], _args)) { _retval.push(_items[_i]); } } @@ -1194,18 +1203,16 @@ export class SlickDataView implements CustomD } protected getFilteredAndPagedItems(items: TData[]) { - console.time("filtering"); - if (this.useNewFilter ? this.filterNew : this.filter) { + if (this._options.useCSPSafeFilter ? this.filterCSPSafe : this.filter) { let batchFilter: Function; let batchFilterWithCaching: Function; - if (this.useNewFilter) { - batchFilter = (this._options.inlineFilters ? this.compiledFilterNew : this.uncompiledFilter) as Function; - batchFilterWithCaching = (this._options.inlineFilters ? this.compiledFilterWithCachingNew : this.uncompiledFilterWithCaching) as Function; + if (this._options.useCSPSafeFilter) { + batchFilter = (this._options.inlineFilters ? this.compiledFilterCSPSafe : this.uncompiledFilter) as Function; + batchFilterWithCaching = (this._options.inlineFilters ? this.compiledFilterWithCachingCSPSafe : this.uncompiledFilterWithCaching) as Function; } else { batchFilter = (this._options.inlineFilters ? this.compiledFilter : this.uncompiledFilter) as Function; batchFilterWithCaching = (this._options.inlineFilters ? this.compiledFilterWithCaching : this.uncompiledFilterWithCaching) as Function; } - // console.log(batchFilter, batchFilterWithCaching); if (this.refreshHints.isFilterNarrowing) { this.filteredItems = batchFilter.call(this, this.filteredItems, this.filterArgs); } else if (this.refreshHints.isFilterExpanding) { @@ -1213,7 +1220,6 @@ export class SlickDataView implements CustomD } else if (!this.refreshHints.isFilterUnchanged) { this.filteredItems = batchFilter.call(this, items, this.filterArgs); } - // console.log(this.filteredItems, "items"); } else { // special case: if not filtering and not paging, the resulting // rows collection needs to be a copy so that changes due to sort @@ -1235,7 +1241,6 @@ export class SlickDataView implements CustomD } else { paged = this.filteredItems; } - console.timeEnd("filtering"); return { totalRows: this.filteredItems.length, rows: paged }; } From 9d371390cbe6147661b175309892d13937b1a6c9 Mon Sep 17 00:00:00 2001 From: Jesper Jakobsen Date: Mon, 6 Nov 2023 10:46:03 +0100 Subject: [PATCH 04/12] Changed the last inline style to get applied properly --- examples/example-csp-header.html | 2 +- examples/example-csp-header.js | 2 +- src/slick.grid.ts | 11 +++++++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/examples/example-csp-header.html b/examples/example-csp-header.html index 78f18d118..9568ff591 100644 --- a/examples/example-csp-header.html +++ b/examples/example-csp-header.html @@ -5,7 +5,7 @@ - + diff --git a/examples/example-csp-header.js b/examples/example-csp-header.js index 57cf36db2..0a401d993 100644 --- a/examples/example-csp-header.js +++ b/examples/example-csp-header.js @@ -13,7 +13,7 @@ var columns = [ var options = { enableCellNavigation: true, enableColumnReorder: false, - // nonce: 'random-string', //tmp removal because there is another issue which needs to get fixed before this can be added back, alteast for testing + nonce: 'random-string', sanitizer: (html) => DOMPurify.sanitize(html, { RETURN_TRUSTED_TYPE: true }) }; diff --git a/src/slick.grid.ts b/src/slick.grid.ts index b9cb596cc..b6454be0c 100644 --- a/src/slick.grid.ts +++ b/src/slick.grid.ts @@ -3806,7 +3806,7 @@ export class SlickGrid = Column, O e const frozenRowOffset = this.getFrozenRowOffset(row); - const rowHtml = `
    `; + const rowHtml = `
    `; //style="top:${(this.getRowTop(row) - frozenRowOffset)}px" stringArrayL.push(rowHtml); @@ -4660,7 +4660,14 @@ export class SlickGrid = Column, O e const xRight = document.createElement('div'); x.innerHTML = this.sanitizeHtmlString(stringArrayL.join('')); xRight.innerHTML = this.sanitizeHtmlString(stringArrayR.join('')); - + const elements = x.querySelectorAll('[data-top]') as NodeListOf; + elements?.forEach((element: HTMLElement) => { + const top = element.dataset.top; + if (top) { + element.style.top = `${top}px`; + } + }); + for (let i = 0, ii = rows.length; i < ii; i++) { if ((this.hasFrozenRows) && (rows[i] >= this.actualFrozenRow)) { if (this.hasFrozenColumns()) { From ad54e650c13870ab7573368ab9f9187113f367f7 Mon Sep 17 00:00:00 2001 From: Jesper Jakobsen Date: Mon, 6 Nov 2023 12:43:06 +0100 Subject: [PATCH 05/12] Adjusted test cases in for CSP safe style tag --- .../example-auto-scroll-when-dragging.cy.ts | 22 ++-- cypress/e2e/example-autotooltips.cy.ts | 24 ++-- cypress/e2e/example-checkbox-header-row.cy.ts | 6 +- cypress/e2e/example-checkbox-row-select.cy.ts | 6 +- cypress/e2e/example-colspan.cy.ts | 24 ++-- ...xample-composite-editor-modal-dialog.cy.ts | 124 +++++++++--------- cypress/e2e/example-csp-header.cy.ts | 24 ++-- cypress/e2e/example-draggable-grouping.cy.ts | 66 +++++----- ...mple-frozen-columns-and-column-group.cy.ts | 46 +++---- .../e2e/example-frozen-columns-and-rows.cy.ts | 84 ++++++------ cypress/e2e/example-frozen-rows.cy.ts | 84 ++++++------ cypress/e2e/example-grouping-esm.cy.ts | 50 +++---- cypress/e2e/example-grouping.cy.ts | 50 +++---- .../e2e/example-plugin-custom-tooltip.cy.ts | 14 +- ...xample-row-detail-selection-and-move.cy.ts | 86 ++++++------ cypress/e2e/example3-editing.cy.ts | 24 ++-- cypress/e2e/example3b-editing-with-undo.cy.ts | 44 +++---- cypress/support/commands.ts | 2 +- src/slick.grid.ts | 21 +-- 19 files changed, 403 insertions(+), 398 deletions(-) diff --git a/cypress/e2e/example-auto-scroll-when-dragging.cy.ts b/cypress/e2e/example-auto-scroll-when-dragging.cy.ts index 0f99a3557..31a3c7dac 100644 --- a/cypress/e2e/example-auto-scroll-when-dragging.cy.ts +++ b/cypress/e2e/example-auto-scroll-when-dragging.cy.ts @@ -190,15 +190,15 @@ describe('Example - Auto scroll when dragging', { retries: 1 }, () => { }); it('should have a frozen grid with 4 containers with 2 columns on the left and 3 rows on the top after click Set/Clear Frozen button', () => { - cy.get('#myGrid [style="top:0px"]').should('have.length', 1); - cy.get('#myGrid2 [style="top:0px"]').should('have.length', 1); + cy.get('#myGrid [style="top: 0px;"]').should('have.length', 1); + cy.get('#myGrid2 [style="top: 0px;"]').should('have.length', 1); cy.get('#toggleFrozen').click(); - cy.get('#myGrid [style="top:0px"]').should('have.length', 2 * 2); - cy.get('#myGrid2 [style="top:0px"]').should('have.length', 2 * 2); - cy.get('#myGrid .grid-canvas-left > [style="top:0px"]').children().should('have.length', 2 * 2); - cy.get('#myGrid2 .grid-canvas-left > [style="top:0px"]').children().should('have.length', 2 * 2); + cy.get('#myGrid [style="top: 0px;"]').should('have.length', 2 * 2); + cy.get('#myGrid2 [style="top: 0px;"]').should('have.length', 2 * 2); + cy.get('#myGrid .grid-canvas-left > [style="top: 0px;"]').children().should('have.length', 2 * 2); + cy.get('#myGrid2 .grid-canvas-left > [style="top: 0px;"]').children().should('have.length', 2 * 2); cy.get('#myGrid .grid-canvas-top').children().should('have.length', 3 * 2); cy.get('#myGrid2 .grid-canvas-top').children().should('have.length', 3 * 2); }); @@ -268,8 +268,8 @@ describe('Example - Auto scroll when dragging', { retries: 1 }, () => { it('should have a frozen & grouping by Duration grid after click Set/Clear grouping by Duration button', { scrollBehavior: false }, () => { cy.get('#toggleGroup').trigger('click'); - cy.get('#myGrid [style="top:0px"]').should('have.length', 2 * 2); - cy.get('#myGrid2 [style="top:0px"]').should('have.length', 2 * 2); + cy.get('#myGrid [style="top: 0px;"]').should('have.length', 2 * 2); + cy.get('#myGrid2 [style="top: 0px;"]').should('have.length', 2 * 2); cy.get('#myGrid .grid-canvas-top.grid-canvas-left').contains('Duration'); cy.get('#myGrid2 .grid-canvas-top.grid-canvas-left').contains('Duration'); }); @@ -282,7 +282,7 @@ describe('Example - Auto scroll when dragging', { retries: 1 }, () => { cy.get('@viewport').invoke('scrollTop').then(scrollAfter => { expect(scrollBefore).to.be.lessThan(scrollAfter); cy.dragEnd(selector); - cy.get(selector + ' [style="top:350px"].slick-group').should('not.be.hidden');; + cy.get(selector + ' [style="top: 350px;"].slick-group').should('not.be.hidden');; }); }); } @@ -295,8 +295,8 @@ describe('Example - Auto scroll when dragging', { retries: 1 }, () => { it('should reset to default grid when click Set/Clear Frozen button and Set/Clear grouping button', () => { cy.get('#toggleFrozen').trigger('click'); cy.get('#toggleGroup').trigger('click'); - cy.get('#myGrid [style="top:0px"]').should('have.length', 1); - cy.get('#myGrid2 [style="top:0px"]').should('have.length', 1); + cy.get('#myGrid [style="top: 0px;"]').should('have.length', 1); + cy.get('#myGrid2 [style="top: 0px;"]').should('have.length', 1); }); }); diff --git a/cypress/e2e/example-autotooltips.cy.ts b/cypress/e2e/example-autotooltips.cy.ts index c1f60f2de..a9b786b89 100644 --- a/cypress/e2e/example-autotooltips.cy.ts +++ b/cypress/e2e/example-autotooltips.cy.ts @@ -34,22 +34,22 @@ describe('Example AutoTooltips Plugin', () => { .trigger('mousemove', 'bottomRight') .trigger('mouseup', 'bottomRight', { which: 1, force: true }); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell.l3.r3`).should('contain', '01/01/2009'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell.l3.r3`).trigger('mouseover'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell.l3.r3`).should('have.attr', 'title', '01/01/2009'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell.l3.r3`).should('contain', '01/01/2009'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell.l3.r3`).trigger('mouseover'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell.l3.r3`).should('have.attr', 'title', '01/01/2009'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell.l3.r3`).should('contain', '01/01/2009'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell.l3.r3`).trigger('mouseover'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell.l3.r3`).should('have.attr', 'title', '01/01/2009'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell.l3.r3`).should('contain', '01/01/2009'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell.l3.r3`).trigger('mouseover'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell.l3.r3`).should('have.attr', 'title', '01/01/2009'); }); it('should hover over "Finish" cell to see tooltip', () => { - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell.l4.r4`).should('contain', '01/05/2009'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell.l4.r4`).trigger('mouseover'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell.l4.r4`).should('not.have.attr', 'title', '01/05/2009'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell.l4.r4`).should('contain', '01/05/2009'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell.l4.r4`).trigger('mouseover'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell.l4.r4`).should('not.have.attr', 'title', '01/05/2009'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell.l4.r4`).should('contain', '01/05/2009'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell.l4.r4`).trigger('mouseover'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell.l4.r4`).should('not.have.attr', 'title', '01/05/2009'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell.l4.r4`).should('contain', '01/05/2009'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell.l4.r4`).trigger('mouseover'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell.l4.r4`).should('not.have.attr', 'title', '01/05/2009'); }); }); \ No newline at end of file diff --git a/cypress/e2e/example-checkbox-header-row.cy.ts b/cypress/e2e/example-checkbox-header-row.cy.ts index a934e672e..b341a058c 100644 --- a/cypress/e2e/example-checkbox-header-row.cy.ts +++ b/cypress/e2e/example-checkbox-header-row.cy.ts @@ -118,8 +118,8 @@ describe('Example - Checkbox Header Row', () => { // Row index 3, 5 and 21 (last one will be on 2nd page) cy.get('input[type="checkbox"]:checked').should('have.length', 2); // 2x in current page and 1x in next page - cy.get('[style="top:75px"] > .slick-cell:nth(0) input[type="checkbox"]').should('be.checked'); - cy.get('[style="top:125px"] > .slick-cell:nth(0) input[type="checkbox"]').should('be.checked'); + cy.get('[style="top: 75px;"] > .slick-cell:nth(0) input[type="checkbox"]').should('be.checked'); + cy.get('[style="top: 125px;"] > .slick-cell:nth(0) input[type="checkbox"]').should('be.checked'); }); it('should go to next page and expect 1 row selected in that second page', () => { @@ -127,7 +127,7 @@ describe('Example - Checkbox Header Row', () => { .click(); cy.get('input[type="checkbox"]:checked').should('have.length', 1); // only 1x row in page 2 - cy.get('[style="top:100px"] > .slick-cell:nth(0) input[type="checkbox"]').should('be.checked'); + cy.get('[style="top: 100px;"] > .slick-cell:nth(0) input[type="checkbox"]').should('be.checked'); }); it('should click on "Select All" checkbox and expect all rows selected in current page', () => { diff --git a/cypress/e2e/example-checkbox-row-select.cy.ts b/cypress/e2e/example-checkbox-row-select.cy.ts index 76ca4b72b..37f919430 100644 --- a/cypress/e2e/example-checkbox-row-select.cy.ts +++ b/cypress/e2e/example-checkbox-row-select.cy.ts @@ -31,8 +31,8 @@ describe('Example - Checkbox Row Select', () => { }); it('should be able to select first 2 rows and now expect 3 rows selected', () => { - cy.get(`.slick-row[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(0) input[type=checkbox]`).click(); - cy.get(`.slick-row[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(0) input[type=checkbox]`).click(); + cy.get(`.slick-row[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0) input[type=checkbox]`).click(); + cy.get(`.slick-row[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(0) input[type=checkbox]`).click(); cy.get('#myGrid') .find('.slick-cell-checkboxsel input:checked') @@ -43,7 +43,7 @@ describe('Example - Checkbox Row Select', () => { cy.get('#unselectRow5') .click(); - cy.get(`.slick-row[style="top:${GRID_ROW_HEIGHT * 4}px"] > .slick-cell:nth(0) input[type=checkbox]`) + cy.get(`.slick-row[style="top: ${GRID_ROW_HEIGHT * 4}px;"] > .slick-cell:nth(0) input[type=checkbox]`) .should('not.be.checked'); cy.get('#myGrid') diff --git a/cypress/e2e/example-colspan.cy.ts b/cypress/e2e/example-colspan.cy.ts index 2b2fbf11a..e605e873d 100644 --- a/cypress/e2e/example-colspan.cy.ts +++ b/cypress/e2e/example-colspan.cy.ts @@ -20,26 +20,26 @@ describe('Example - Column Span & Header Grouping', { retries: 1 }, () => { }); it('should expect 1st row to be 1 column spanned to the entire width', () => { - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(0)`).should('contain', 'Task 0'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(1)`).should('not.exist'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0)`).should('contain', 'Task 0'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(1)`).should('not.exist'); }); it('should expect 2nd row to be 4 columns and not be spanned', () => { - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(0)`).should('contain', 'Task 1'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(1)`).should('contain', '5 days'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(2)`).should('contain', '01/05/2009'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(3)`).contains(/(true|false)/); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(0)`).should('contain', 'Task 1'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(1)`).should('contain', '5 days'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(2)`).should('contain', '01/05/2009'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(3)`).contains(/(true|false)/); }); it('should expect 3rd row to be 1 column spanned to the entire width', () => { - cy.get(`[style="top:${GRID_ROW_HEIGHT * 2}px"] > .slick-cell:nth(0)`).should('contain', 'Task 2'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 2}px"] > .slick-cell:nth(1)`).should('not.exist'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(0)`).should('contain', 'Task 2'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(1)`).should('not.exist'); }); it('should expect 4th row to be 4 columns and not be spanned', () => { - cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"] > .slick-cell:nth(0)`).should('contain', 'Task 3'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"] > .slick-cell:nth(1)`).should('contain', '5 days'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"] > .slick-cell:nth(2)`).should('contain', '01/05/2009'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"] > .slick-cell:nth(3)`).contains(/(true|false)/); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(0)`).should('contain', 'Task 3'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(1)`).should('contain', '5 days'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(2)`).should('contain', '01/05/2009'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(3)`).contains(/(true|false)/); }); }); diff --git a/cypress/e2e/example-composite-editor-modal-dialog.cy.ts b/cypress/e2e/example-composite-editor-modal-dialog.cy.ts index 9d2e4ade9..a45636663 100644 --- a/cypress/e2e/example-composite-editor-modal-dialog.cy.ts +++ b/cypress/e2e/example-composite-editor-modal-dialog.cy.ts @@ -23,11 +23,11 @@ describe('Example - Composite Editor Modal with Create/Edit/Mass-Update/Mass-Sel }); it('should expect first row to include "Task 0" and other specific properties', () => { - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(1)`).should('contain', 'Task 0'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(3)`).should('contain', '5 days'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(5)`).should('contain', '01/01/2009'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(6)`).should('contain', '01/05/2009'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(7)`).find('.sgi-check').should('exist'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 0'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(3)`).should('contain', '5 days'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(5)`).should('contain', '01/01/2009'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(6)`).should('contain', '01/05/2009'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(7)`).find('.sgi-check').should('exist'); }); it('should open the Edit Modal and expect same data to include "Task 0" and other specific properties', () => { @@ -110,11 +110,11 @@ describe('Example - Composite Editor Modal with Create/Edit/Mass-Update/Mass-Sel cy.wait(10); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(1)`).should('contain', 'Task 0000'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(3)`).should('contain', '27 days'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(5)`).should('contain', '01/01/2009'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(6)`).should('contain', '01/05/2009'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(7)`).find('.sgi-check').should('have.length', 0); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 0000'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(3)`).should('contain', '27 days'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(5)`).should('contain', '01/01/2009'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(6)`).should('contain', '01/05/2009'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(7)`).find('.sgi-check').should('have.length', 0); }); it('should open the Mass Update try to change "Duration" below 5 and expect it to become invalid', () => { @@ -161,29 +161,29 @@ describe('Example - Composite Editor Modal with Create/Edit/Mass-Update/Mass-Sel }); it('Should expect to see "Duration" of "27 days" and "Effort-Driven" to be enabled accross the entire grid', () => { - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(1)`).should('contain', 'Task 0000'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(3)`).should('contain', '27 days'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(7)`).find('.sgi-check').should('have.length', 1); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 0000'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(3)`).should('contain', '27 days'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(7)`).find('.sgi-check').should('have.length', 1); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(1)`).should('contain', 'Task 1'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(3)`).should('contain', '27 days'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(7)`).find('.sgi-check').should('have.length', 1); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 1'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(3)`).should('contain', '27 days'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(7)`).find('.sgi-check').should('have.length', 1); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 2}px"] > .slick-cell:nth(1)`).should('contain', 'Task 2'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 2}px"] > .slick-cell:nth(3)`).should('contain', '27 days'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 2}px"] > .slick-cell:nth(7)`).find('.sgi-check').should('have.length', 1); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 2'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(3)`).should('contain', '27 days'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(7)`).find('.sgi-check').should('have.length', 1); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"] > .slick-cell:nth(1)`).should('contain', 'Task 3'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"] > .slick-cell:nth(3)`).should('contain', '27 days'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"] > .slick-cell:nth(7)`).find('.sgi-check').should('have.length', 1); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 3'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(3)`).should('contain', '27 days'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(7)`).find('.sgi-check').should('have.length', 1); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 4}px"] > .slick-cell:nth(1)`).should('contain', 'Task 4'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 4}px"] > .slick-cell:nth(3)`).should('contain', '27 days'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 4}px"] > .slick-cell:nth(7)`).find('.sgi-check').should('have.length', 1); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 4}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 4'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 4}px;"] > .slick-cell:nth(3)`).should('contain', '27 days'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 4}px;"] > .slick-cell:nth(7)`).find('.sgi-check').should('have.length', 1); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 5}px"] > .slick-cell:nth(1)`).should('contain', 'Task 5'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 5}px"] > .slick-cell:nth(3)`).should('contain', '27 days'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 5}px"] > .slick-cell:nth(7)`).find('.sgi-check').should('have.length', 1); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 5}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 5'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 5}px;"] > .slick-cell:nth(3)`).should('contain', '27 days'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 5}px;"] > .slick-cell:nth(7)`).find('.sgi-check').should('have.length', 1); }); it('Should expect an Alert about missing row selection before executing Mass Selection', () => { @@ -198,8 +198,8 @@ describe('Example - Composite Editor Modal with Create/Edit/Mass-Update/Mass-Sel }); it('Should select row 2 and 3 and change ', () => { - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(0)`).click(); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 2}px"] > .slick-cell:nth(0)`).click(); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(0)`).click(); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(0)`).click(); cy.get('[data-test="mass-selection-button"]').click(); @@ -223,31 +223,31 @@ describe('Example - Composite Editor Modal with Create/Edit/Mass-Update/Mass-Sel }); it('Should expect to see "Duration" of "27 days" and "Effort-Driven" to be enabled accross the entire grid', () => { - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(1)`).should('contain', 'Task 0000'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(3)`).should('contain', '27 days'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(7)`).find('.sgi-check').should('have.length', 1); - - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(1)`).should('contain', 'Task 1'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(3)`).should('contain', '7 days'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(5)`).should('contain', '02/02/2020'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(7)`).find('.sgi-check').should('have.length', 1); - - cy.get(`[style="top:${GRID_ROW_HEIGHT * 2}px"] > .slick-cell:nth(1)`).should('contain', 'Task 2'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 2}px"] > .slick-cell:nth(3)`).should('contain', '7 days'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 2}px"] > .slick-cell:nth(5)`).should('contain', '02/02/2020'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 2}px"] > .slick-cell:nth(7)`).find('.sgi-check').should('have.length', 1); - - cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"] > .slick-cell:nth(1)`).should('contain', 'Task 3'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"] > .slick-cell:nth(3)`).should('contain', '27 days'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"] > .slick-cell:nth(7)`).find('.sgi-check').should('have.length', 1); - - cy.get(`[style="top:${GRID_ROW_HEIGHT * 4}px"] > .slick-cell:nth(1)`).should('contain', 'Task 4'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 4}px"] > .slick-cell:nth(3)`).should('contain', '27 days'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 4}px"] > .slick-cell:nth(7)`).find('.sgi-check').should('have.length', 1); - - cy.get(`[style="top:${GRID_ROW_HEIGHT * 5}px"] > .slick-cell:nth(1)`).should('contain', 'Task 5'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 5}px"] > .slick-cell:nth(3)`).should('contain', '27 days'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 5}px"] > .slick-cell:nth(7)`).find('.sgi-check').should('have.length', 1); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 0000'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(3)`).should('contain', '27 days'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(7)`).find('.sgi-check').should('have.length', 1); + + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 1'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(3)`).should('contain', '7 days'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(5)`).should('contain', '02/02/2020'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(7)`).find('.sgi-check').should('have.length', 1); + + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 2'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(3)`).should('contain', '7 days'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(5)`).should('contain', '02/02/2020'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(7)`).find('.sgi-check').should('have.length', 1); + + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 3'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(3)`).should('contain', '27 days'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(7)`).find('.sgi-check').should('have.length', 1); + + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 4}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 4'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 4}px;"] > .slick-cell:nth(3)`).should('contain', '27 days'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 4}px;"] > .slick-cell:nth(7)`).find('.sgi-check').should('have.length', 1); + + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 5}px;"] > .slick-cell:nth(1)`).should('contain', 'Task 5'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 5}px;"] > .slick-cell:nth(3)`).should('contain', '27 days'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 5}px;"] > .slick-cell:nth(7)`).find('.sgi-check').should('have.length', 1); }); it('Should open a Create Modal window and click on Effort-Driven then expect 3 validation errors', () => { @@ -316,15 +316,15 @@ describe('Example - Composite Editor Modal with Create/Edit/Mass-Update/Mass-Sel }); it('Should expect to see "Duration" of "27 days" and "Effort-Driven" to be enabled accross the entire grid', () => { - cy.get(`[style="top:12500px"] > .slick-cell:nth(1)`).should('contain', 'Task 8899'); - cy.get(`[style="top:12500px"] > .slick-cell:nth(2)`).should('contain', 'random text'); - cy.get(`[style="top:12500px"] > .slick-cell:nth(3)`).should('contain', '9 days'); - cy.get(`[style="top:12500px"] > .slick-cell:nth(4)`).each($cell => { + cy.get(`[style="top: 12500px;"] > .slick-cell:nth(1)`).should('contain', 'Task 8899'); + cy.get(`[style="top: 12500px;"] > .slick-cell:nth(2)`).should('contain', 'random text'); + cy.get(`[style="top: 12500px;"] > .slick-cell:nth(3)`).should('contain', '9 days'); + cy.get(`[style="top: 12500px;"] > .slick-cell:nth(4)`).each($cell => { const htmlText = $cell.html(); expect(htmlText).to.eq(''); }); - cy.get(`[style="top:12500px"] > .slick-cell:nth(5)`).should('contain', '02/02/2020'); - cy.get(`[style="top:12500px"] > .slick-cell:nth(6)`).should('contain', ''); - cy.get(`[style="top:12500px"] > .slick-cell:nth(7)`).find('.sgi-check').should('have.length', 1); + cy.get(`[style="top: 12500px;"] > .slick-cell:nth(5)`).should('contain', '02/02/2020'); + cy.get(`[style="top: 12500px;"] > .slick-cell:nth(6)`).should('contain', ''); + cy.get(`[style="top: 12500px;"] > .slick-cell:nth(7)`).find('.sgi-check').should('have.length', 1); }); }); diff --git a/cypress/e2e/example-csp-header.cy.ts b/cypress/e2e/example-csp-header.cy.ts index 1c487e23a..b9d3e6f7c 100644 --- a/cypress/e2e/example-csp-header.cy.ts +++ b/cypress/e2e/example-csp-header.cy.ts @@ -27,26 +27,26 @@ describe('Example CSP Header - with Column Span & Header Grouping', () => { }); it('should expect 1st row to be 1 column spanned to the entire width', () => { - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(0)`).should('contain', 'Task 0'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(1)`).should('not.exist'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0)`).should('contain', 'Task 0'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(1)`).should('not.exist'); }); it('should expect 2nd row to be 4 columns and not be spanned', () => { - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(0)`).should('contain', 'Task 1'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(1)`).should('contain', '5 days'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(2)`).should('contain', '01/05/2009'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(3)`).contains(/(true|false)/); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(0)`).should('contain', 'Task 1'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(1)`).should('contain', '5 days'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(2)`).should('contain', '01/05/2009'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(3)`).contains(/(true|false)/); }); it('should expect 3rd row to be 1 column spanned to the entire width', () => { - cy.get(`[style="top:${GRID_ROW_HEIGHT * 2}px"] > .slick-cell:nth(0)`).should('contain', 'Task 2'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 2}px"] > .slick-cell:nth(1)`).should('not.exist'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(0)`).should('contain', 'Task 2'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(1)`).should('not.exist'); }); it('should expect 4th row to be 4 columns and not be spanned', () => { - cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"] > .slick-cell:nth(0)`).should('contain', 'Task 3'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"] > .slick-cell:nth(1)`).should('contain', '5 days'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"] > .slick-cell:nth(2)`).should('contain', '01/05/2009'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"] > .slick-cell:nth(3)`).contains(/(true|false)/); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(0)`).should('contain', 'Task 3'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(1)`).should('contain', '5 days'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(2)`).should('contain', '01/05/2009'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(3)`).contains(/(true|false)/); }); }); diff --git a/cypress/e2e/example-draggable-grouping.cy.ts b/cypress/e2e/example-draggable-grouping.cy.ts index a54ecf214..1ed2f6a4a 100644 --- a/cypress/e2e/example-draggable-grouping.cy.ts +++ b/cypress/e2e/example-draggable-grouping.cy.ts @@ -38,13 +38,13 @@ describe('Example - Draggable Grouping', { retries: 1 }, () => { cy.get('[data-test="group-duration-sort-value-btn"]').click(); cy.get('[data-test="collapse-all-btn"]').click(); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(0) .slick-group-toggle.collapsed`).should('have.length', 1); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 0'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0) .slick-group-toggle.collapsed`).should('have.length', 1); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 0'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 1'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 2}px"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 2'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 3'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 4}px"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 4'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 1'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 2'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 3'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 4}px;"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 4'); }); it('should click on Expand All columns and expect 1st row as grouping title and 2nd row as a regular row', () => { @@ -52,11 +52,11 @@ describe('Example - Draggable Grouping', { retries: 1 }, () => { cy.get('[data-test="group-duration-sort-value-btn"]').click(); cy.get('[data-test="expand-all-btn"]').click(); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(0) .slick-group-toggle.expanded`).should('have.length', 1); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 0'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0) .slick-group-toggle.expanded`).should('have.length', 1); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 0'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(1)`).should('contain', 'Task'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(2)`).should('contain', '0'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(1)`).should('contain', 'Task'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(2)`).should('contain', '0'); }); it('should show 1 column title (Duration) shown in the pre-header section', () => { @@ -66,14 +66,14 @@ describe('Example - Draggable Grouping', { retries: 1 }, () => { it('should "Group by Duration then Effort-Driven" and expect 1st row to be expanded, 2nd row to be expanded and 3rd row to be a regular row', () => { cy.get('[data-test="group-duration-effort-btn"]').click(); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"].slick-group-level-0 > .slick-cell:nth(0) .slick-group-toggle.expanded`).should('have.length', 1); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"].slick-group-level-0 > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 0'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"].slick-group-level-0 > .slick-cell:nth(0) .slick-group-toggle.expanded`).should('have.length', 1); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"].slick-group-level-0 > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 0'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"].slick-group-level-1 .slick-group-toggle.expanded`).should('have.length', 1); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"].slick-group-level-1 .slick-group-title`).should('contain', 'Effort-Driven: False'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"].slick-group-level-1 .slick-group-toggle.expanded`).should('have.length', 1); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"].slick-group-level-1 .slick-group-title`).should('contain', 'Effort-Driven: False'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 2}px"] > .slick-cell:nth(1)`).should('contain', 'Task'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 2}px"] > .slick-cell:nth(2)`).should('contain', '0'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(1)`).should('contain', 'Task'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(2)`).should('contain', '0'); }); it('should show 2 column titles (Duration, Effort-Driven) shown in the pre-header section', () => { @@ -91,22 +91,22 @@ describe('Example - Draggable Grouping', { retries: 1 }, () => { }); it('should expect the grouping to be swapped as well in the grid', () => { - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"].slick-group-level-0 > .slick-cell:nth(0) .slick-group-toggle.expanded`).should('have.length', 1); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"].slick-group-level-0 > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Effort-Driven: False'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"].slick-group-level-0 > .slick-cell:nth(0) .slick-group-toggle.expanded`).should('have.length', 1); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"].slick-group-level-0 > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Effort-Driven: False'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"].slick-group-level-1 .slick-group-toggle.expanded`).should('have.length', 1); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"].slick-group-level-1 .slick-group-title`).should('contain', 'Duration: 0'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"].slick-group-level-1 .slick-group-toggle.expanded`).should('have.length', 1); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"].slick-group-level-1 .slick-group-title`).should('contain', 'Duration: 0'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 2}px"] > .slick-cell:nth(1)`).should('contain', 'Task'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 2}px"] > .slick-cell:nth(2)`).should('contain', '0'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(1)`).should('contain', 'Task'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(2)`).should('contain', '0'); }); it('should use the preheader Toggle All button and expect all groups to now be collapsed', () => { cy.get('.slick-preheader-panel .slick-group-toggle-all').click(); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(0) .slick-group-toggle.collapsed`).should('have.length', 1); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Effort-Driven: False'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Effort-Driven: True'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0) .slick-group-toggle.collapsed`).should('have.length', 1); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Effort-Driven: False'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Effort-Driven: True'); }); it('should expand all rows with "Expand All" and expect all the Groups to be expanded and the Toogle All icon to be collapsed', () => { @@ -152,21 +152,21 @@ describe('Example - Draggable Grouping', { retries: 1 }, () => { it('should use the preheader Toggle All button and expect all groups to now be expanded', () => { cy.get('.slick-preheader-panel .slick-group-toggle-all').click(); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(0) .slick-group-toggle.expanded`).should('have.length', 1); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Effort-Driven: False'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 0'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(0) .slick-group-toggle.expanded`) + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0) .slick-group-toggle.expanded`).should('have.length', 1); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Effort-Driven: False'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 0'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0) .slick-group-toggle.expanded`) .should('have.css', 'marginLeft').and('eq', `0px`); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(0) .slick-group-toggle.expanded`) + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(0) .slick-group-toggle.expanded`) .should('have.css', 'marginLeft').and('eq', `15px`); }); it('should use the preheader Toggle All button again and expect all groups to now be collapsed', () => { cy.get('.slick-preheader-panel .slick-group-toggle-all').click(); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(0) .slick-group-toggle.collapsed`).should('have.length', 1); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Effort-Driven: False'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Effort-Driven: True'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0) .slick-group-toggle.collapsed`).should('have.length', 1); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Effort-Driven: False'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Effort-Driven: True'); }); it('should clear all groups with "Clear all Grouping" and expect all the Groups to be collapsed and the Toogle All icon to be collapsed', () => { diff --git a/cypress/e2e/example-frozen-columns-and-column-group.cy.ts b/cypress/e2e/example-frozen-columns-and-column-group.cy.ts index 37adfd500..5ebef9c4a 100644 --- a/cypress/e2e/example-frozen-columns-and-column-group.cy.ts +++ b/cypress/e2e/example-frozen-columns-and-column-group.cy.ts @@ -21,16 +21,16 @@ describe('Example - Row Grouping Titles', () => { }); it('should have a frozen grid on page load with 3 columns on the left and 4 columns on the right', () => { - cy.get('[style="top:0px"]').should('have.length', 2); - cy.get('.grid-canvas-left > [style="top:0px"]').children().should('have.length', 3); - cy.get('.grid-canvas-right > [style="top:0px"]').children().should('have.length', 4); + cy.get('[style="top: 0px;"]').should('have.length', 2); + cy.get('.grid-canvas-left > [style="top: 0px;"]').children().should('have.length', 3); + cy.get('.grid-canvas-right > [style="top: 0px;"]').children().should('have.length', 4); - cy.get('.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(0)').should('contain', '0'); - cy.get('.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(1)').should('contain', 'Task 0'); - cy.get('.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(2)').should('contain', '5 days'); + cy.get('.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(0)').should('contain', '0'); + cy.get('.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', 'Task 0'); + cy.get('.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(2)').should('contain', '5 days'); - cy.get('.grid-canvas-right > [style="top:0px"] > .slick-cell:nth(0)').should('contain', '01/01/2009'); - cy.get('.grid-canvas-right > [style="top:0px"] > .slick-cell:nth(1)').should('contain', '01/05/2009'); + cy.get('.grid-canvas-right > [style="top: 0px;"] > .slick-cell:nth(0)').should('contain', '01/01/2009'); + cy.get('.grid-canvas-right > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', '01/05/2009'); }); it('should have exact Column Pre-Header & Column Header Titles in the grid', () => { @@ -49,14 +49,14 @@ describe('Example - Row Grouping Titles', () => { cy.contains('Remove Frozen Columns') .click({ force: true }); - cy.get('[style="top:0px"]').should('have.length', 1); - cy.get('.grid-canvas-left > [style="top:0px"]').children().should('have.length', 7); + cy.get('[style="top: 0px;"]').should('have.length', 1); + cy.get('.grid-canvas-left > [style="top: 0px;"]').children().should('have.length', 7); - cy.get('.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(0)').should('contain', '0'); - cy.get('.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(1)').should('contain', 'Task 0'); - cy.get('.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(2)').should('contain', '5 days'); - cy.get('.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(3)').should('contain', '01/01/2009'); - cy.get('.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(4)').should('contain', '01/05/2009'); + cy.get('.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(0)').should('contain', '0'); + cy.get('.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', 'Task 0'); + cy.get('.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(2)').should('contain', '5 days'); + cy.get('.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(3)').should('contain', '01/01/2009'); + cy.get('.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(4)').should('contain', '01/05/2009'); }); it('should have exact Column Pre-Header & Column Header Titles in the grid', () => { @@ -75,16 +75,16 @@ describe('Example - Row Grouping Titles', () => { cy.contains('Set 3 Frozen Columns') .click({ force: true }); - cy.get('[style="top:0px"]').should('have.length', 2); - cy.get('.grid-canvas-left > [style="top:0px"]').children().should('have.length', 3); - cy.get('.grid-canvas-right > [style="top:0px"]').children().should('have.length', 4); + cy.get('[style="top: 0px;"]').should('have.length', 2); + cy.get('.grid-canvas-left > [style="top: 0px;"]').children().should('have.length', 3); + cy.get('.grid-canvas-right > [style="top: 0px;"]').children().should('have.length', 4); - cy.get('.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(0)').should('contain', '0'); - cy.get('.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(1)').should('contain', 'Task 0'); - cy.get('.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(2)').should('contain', '5 days'); + cy.get('.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(0)').should('contain', '0'); + cy.get('.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', 'Task 0'); + cy.get('.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(2)').should('contain', '5 days'); - cy.get('.grid-canvas-right > [style="top:0px"] > .slick-cell:nth(0)').should('contain', '01/01/2009'); - cy.get('.grid-canvas-right > [style="top:0px"] > .slick-cell:nth(1)').should('contain', '01/05/2009'); + cy.get('.grid-canvas-right > [style="top: 0px;"] > .slick-cell:nth(0)').should('contain', '01/01/2009'); + cy.get('.grid-canvas-right > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', '01/05/2009'); }); it('should have exact Column Pre-Header & Column Header Titles in the grid', () => { diff --git a/cypress/e2e/example-frozen-columns-and-rows.cy.ts b/cypress/e2e/example-frozen-columns-and-rows.cy.ts index ac62fa538..738b97023 100644 --- a/cypress/e2e/example-frozen-columns-and-rows.cy.ts +++ b/cypress/e2e/example-frozen-columns-and-rows.cy.ts @@ -22,84 +22,84 @@ describe('Example - Frozen Columns & Rows', { retries: 1 }, () => { }); it('should have a frozen grid with 4 containers on page load with 3 columns on the left and 6 columns on the right', () => { - cy.get('[style="top:0px"]').should('have.length', 2 * 2); - cy.get('.grid-canvas-left > [style="top:0px"]').children().should('have.length', 3 * 2); - cy.get('.grid-canvas-right > [style="top:0px"]').children().should('have.length', 8 * 2); + cy.get('[style="top: 0px;"]').should('have.length', 2 * 2); + cy.get('.grid-canvas-left > [style="top: 0px;"]').children().should('have.length', 3 * 2); + cy.get('.grid-canvas-right > [style="top: 0px;"]').children().should('have.length', 8 * 2); // top-left - cy.get('.grid-canvas-top.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(0)').should('contain', ''); - cy.get('.grid-canvas-top.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(1)').should('contain', 'Task 0'); + cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(0)').should('contain', ''); + cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', 'Task 0'); // top-right - cy.get('.grid-canvas-top.grid-canvas-right > [style="top:0px"] > .slick-cell:nth(1)').should('contain', '01/01/2009'); - cy.get('.grid-canvas-top.grid-canvas-right > [style="top:0px"] > .slick-cell:nth(2)').should('contain', '01/05/2009'); - cy.get('.grid-canvas-top.grid-canvas-right > [style="top:0px"] > .slick-cell:nth(4)').should('contain', '0'); + cy.get('.grid-canvas-top.grid-canvas-right > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', '01/01/2009'); + cy.get('.grid-canvas-top.grid-canvas-right > [style="top: 0px;"] > .slick-cell:nth(2)').should('contain', '01/05/2009'); + cy.get('.grid-canvas-top.grid-canvas-right > [style="top: 0px;"] > .slick-cell:nth(4)').should('contain', '0'); // bottom-left - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(1)').should('contain', 'Task 5'); - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top:25px"] > .slick-cell:nth(1)').should('contain', 'Task 6'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', 'Task 5'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 25px;"] > .slick-cell:nth(1)').should('contain', 'Task 6'); // bottom-right - cy.get('.grid-canvas-bottom.grid-canvas-right > [style="top:0px"] > .slick-cell:nth(1)').should('contain', '01/01/2009'); - cy.get('.grid-canvas-bottom.grid-canvas-right > [style="top:0px"] > .slick-cell:nth(2)').should('contain', '01/05/2009'); - cy.get('.grid-canvas-bottom.grid-canvas-right > [style="top:0px"] > .slick-cell:nth(4)').should('contain', '5'); - cy.get('.grid-canvas-bottom.grid-canvas-right > [style="top:25px"] > .slick-cell:nth(4)').should('contain', '6'); + cy.get('.grid-canvas-bottom.grid-canvas-right > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', '01/01/2009'); + cy.get('.grid-canvas-bottom.grid-canvas-right > [style="top: 0px;"] > .slick-cell:nth(2)').should('contain', '01/05/2009'); + cy.get('.grid-canvas-bottom.grid-canvas-right > [style="top: 0px;"] > .slick-cell:nth(4)').should('contain', '5'); + cy.get('.grid-canvas-bottom.grid-canvas-right > [style="top: 25px;"] > .slick-cell:nth(4)').should('contain', '6'); }); it('should change frozen row and increment by 1 and expect changes to be reflected in the grid', () => { cy.get('input#frozenRow').type('{backspace}7'); cy.get('button#setFrozenRow').click(); - cy.get('[style="top:0px"]').should('have.length', 2 * 2); - cy.get('.grid-canvas-left > [style="top:0px"]').children().should('have.length', 3 * 2); - cy.get('.grid-canvas-right > [style="top:0px"]').children().should('have.length', 8 * 2); + cy.get('[style="top: 0px;"]').should('have.length', 2 * 2); + cy.get('.grid-canvas-left > [style="top: 0px;"]').children().should('have.length', 3 * 2); + cy.get('.grid-canvas-right > [style="top: 0px;"]').children().should('have.length', 8 * 2); // top-left - cy.get('.grid-canvas-top.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(0)').should('contain', ''); - cy.get('.grid-canvas-top.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(1)').should('contain', 'Task 0'); + cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(0)').should('contain', ''); + cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', 'Task 0'); // top-right - cy.get('.grid-canvas-top.grid-canvas-right > [style="top:0px"] > .slick-cell:nth(1)').should('contain', '01/01/2009'); - cy.get('.grid-canvas-top.grid-canvas-right > [style="top:0px"] > .slick-cell:nth(2)').should('contain', '01/05/2009'); - cy.get('.grid-canvas-top.grid-canvas-right > [style="top:0px"] > .slick-cell:nth(4)').should('contain', '0'); + cy.get('.grid-canvas-top.grid-canvas-right > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', '01/01/2009'); + cy.get('.grid-canvas-top.grid-canvas-right > [style="top: 0px;"] > .slick-cell:nth(2)').should('contain', '01/05/2009'); + cy.get('.grid-canvas-top.grid-canvas-right > [style="top: 0px;"] > .slick-cell:nth(4)').should('contain', '0'); // bottom-left - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(1)').should('contain', 'Task 7'); - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top:25px"] > .slick-cell:nth(1)').should('contain', 'Task 8'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', 'Task 7'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 25px;"] > .slick-cell:nth(1)').should('contain', 'Task 8'); // bottom-right - cy.get('.grid-canvas-bottom.grid-canvas-right > [style="top:0px"] > .slick-cell:nth(1)').should('contain', '01/01/2009'); - cy.get('.grid-canvas-bottom.grid-canvas-right > [style="top:0px"] > .slick-cell:nth(2)').should('contain', '01/05/2009'); - cy.get('.grid-canvas-bottom.grid-canvas-right > [style="top:0px"] > .slick-cell:nth(4)').should('contain', '7'); - cy.get('.grid-canvas-bottom.grid-canvas-right > [style="top:25px"] > .slick-cell:nth(4)').should('contain', '8'); + cy.get('.grid-canvas-bottom.grid-canvas-right > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', '01/01/2009'); + cy.get('.grid-canvas-bottom.grid-canvas-right > [style="top: 0px;"] > .slick-cell:nth(2)').should('contain', '01/05/2009'); + cy.get('.grid-canvas-bottom.grid-canvas-right > [style="top: 0px;"] > .slick-cell:nth(4)').should('contain', '7'); + cy.get('.grid-canvas-bottom.grid-canvas-right > [style="top: 25px;"] > .slick-cell:nth(4)').should('contain', '8'); }); it('should change frozen column and increment by 1 and expect changes to be reflected in the grid', () => { cy.get('input#frozenColumn').type('{backspace}3'); cy.get('button#setFrozenColumn').click(); - cy.get('[style="top:0px"]').should('have.length', 2 * 2); - cy.get('.grid-canvas-left > [style="top:0px"]').children().should('have.length', 4 * 2); - cy.get('.grid-canvas-right > [style="top:0px"]').children().should('have.length', 7 * 2); + cy.get('[style="top: 0px;"]').should('have.length', 2 * 2); + cy.get('.grid-canvas-left > [style="top: 0px;"]').children().should('have.length', 4 * 2); + cy.get('.grid-canvas-right > [style="top: 0px;"]').children().should('have.length', 7 * 2); // top-left - cy.get('.grid-canvas-top.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(0)').should('contain', ''); - cy.get('.grid-canvas-top.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(1)').should('contain', 'Task 0'); + cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(0)').should('contain', ''); + cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', 'Task 0'); // top-right - cy.get('.grid-canvas-top.grid-canvas-right > [style="top:0px"] > .slick-cell:nth(0)').should('contain', '01/01/2009'); - cy.get('.grid-canvas-top.grid-canvas-right > [style="top:0px"] > .slick-cell:nth(1)').should('contain', '01/05/2009'); - cy.get('.grid-canvas-top.grid-canvas-right > [style="top:0px"] > .slick-cell:nth(3)').should('contain', '0'); + cy.get('.grid-canvas-top.grid-canvas-right > [style="top: 0px;"] > .slick-cell:nth(0)').should('contain', '01/01/2009'); + cy.get('.grid-canvas-top.grid-canvas-right > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', '01/05/2009'); + cy.get('.grid-canvas-top.grid-canvas-right > [style="top: 0px;"] > .slick-cell:nth(3)').should('contain', '0'); // bottom-left - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(1)').should('contain', 'Task 7'); - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top:25px"] > .slick-cell:nth(1)').should('contain', 'Task 8'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', 'Task 7'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 25px;"] > .slick-cell:nth(1)').should('contain', 'Task 8'); // bottom-right - cy.get('.grid-canvas-bottom.grid-canvas-right > [style="top:0px"] > .slick-cell:nth(0)').should('contain', '01/01/2009'); - cy.get('.grid-canvas-bottom.grid-canvas-right > [style="top:0px"] > .slick-cell:nth(1)').should('contain', '01/05/2009'); - cy.get('.grid-canvas-bottom.grid-canvas-right > [style="top:0px"] > .slick-cell:nth(3)').should('contain', '7'); - cy.get('.grid-canvas-bottom.grid-canvas-right > [style="top:25px"] > .slick-cell:nth(3)').should('contain', '8'); + cy.get('.grid-canvas-bottom.grid-canvas-right > [style="top: 0px;"] > .slick-cell:nth(0)').should('contain', '01/01/2009'); + cy.get('.grid-canvas-bottom.grid-canvas-right > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', '01/05/2009'); + cy.get('.grid-canvas-bottom.grid-canvas-right > [style="top: 0px;"] > .slick-cell:nth(3)').should('contain', '7'); + cy.get('.grid-canvas-bottom.grid-canvas-right > [style="top: 25px;"] > .slick-cell:nth(3)').should('contain', '8'); }); it('should click on "Select first 10 rows" button and expect first few rows to be selected', () => { diff --git a/cypress/e2e/example-frozen-rows.cy.ts b/cypress/e2e/example-frozen-rows.cy.ts index 2f44970b5..4887146db 100644 --- a/cypress/e2e/example-frozen-rows.cy.ts +++ b/cypress/e2e/example-frozen-rows.cy.ts @@ -22,71 +22,71 @@ describe('Example - Frozen Rows', { retries: 1 }, () => { }); it('should have a frozen grid with 4 containers on page load with 3 columns on the left and 6 columns on the right', () => { - cy.get('[style="top:0px"]').should('have.length', 2); // top + bottom - cy.get('.grid-canvas-left > [style="top:0px"]').children().should('have.length', 11 * 2); + cy.get('[style="top: 0px;"]').should('have.length', 2); // top + bottom + cy.get('.grid-canvas-left > [style="top: 0px;"]').children().should('have.length', 11 * 2); // top-left - cy.get('.grid-canvas-top.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(0)').should('contain', ''); - cy.get('.grid-canvas-top.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(1)').should('contain', 'Task 0'); - cy.get('.grid-canvas-top.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(2)').should('contain', '5 days'); - cy.get('.grid-canvas-top.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(4)').should('contain', '01/01/2009'); - cy.get('.grid-canvas-top.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(5)').should('contain', '01/05/2009'); - cy.get('.grid-canvas-top.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(7)').should('contain', '0'); + cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(0)').should('contain', ''); + cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', 'Task 0'); + cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(2)').should('contain', '5 days'); + cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(4)').should('contain', '01/01/2009'); + cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(5)').should('contain', '01/05/2009'); + cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(7)').should('contain', '0'); // bottom-left - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(0)').should('contain', ''); - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(1)').should('contain', 'Task 49995'); - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(2)').should('contain', '5 days'); - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(4)').should('contain', '01/01/2009'); - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(5)').should('contain', '01/05/2009'); - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(7)').should('contain', '49995'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(0)').should('contain', ''); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', 'Task 49995'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(2)').should('contain', '5 days'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(4)').should('contain', '01/01/2009'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(5)').should('contain', '01/05/2009'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(7)').should('contain', '49995'); }); it('should change frozen row and increment by 1 and expect changes to be reflected in the grid', () => { cy.get('input#frozenRow').type('{backspace}7'); cy.get('button#setFrozenRow').click(); - cy.get('[style="top:0px"]').should('have.length', 2); // top + bottom - cy.get('.grid-canvas-left > [style="top:0px"]').children().should('have.length', 11 * 2); + cy.get('[style="top: 0px;"]').should('have.length', 2); // top + bottom + cy.get('.grid-canvas-left > [style="top: 0px;"]').children().should('have.length', 11 * 2); // top-left - cy.get('.grid-canvas-top.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(0)').should('contain', ''); - cy.get('.grid-canvas-top.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(1)').should('contain', 'Task 0'); - cy.get('.grid-canvas-top.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(2)').should('contain', '5 days'); - cy.get('.grid-canvas-top.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(4)').should('contain', '01/01/2009'); - cy.get('.grid-canvas-top.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(5)').should('contain', '01/05/2009'); - cy.get('.grid-canvas-top.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(7)').should('contain', '0'); + cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(0)').should('contain', ''); + cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', 'Task 0'); + cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(2)').should('contain', '5 days'); + cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(4)').should('contain', '01/01/2009'); + cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(5)').should('contain', '01/05/2009'); + cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(7)').should('contain', '0'); // bottom-left - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(0)').should('contain', ''); - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(1)').should('contain', 'Task 49993'); - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(2)').should('contain', '5 days'); - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(4)').should('contain', '01/01/2009'); - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(5)').should('contain', '01/05/2009'); - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(7)').should('contain', '49993'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(0)').should('contain', ''); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', 'Task 49993'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(2)').should('contain', '5 days'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(4)').should('contain', '01/01/2009'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(5)').should('contain', '01/05/2009'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(7)').should('contain', '49993'); }); it('should uncheck "frozen bottom rows" and set it', () => { cy.get('input#frozenBottomRows').uncheck(); cy.get('button#setFrozenBottomRows').click(); - cy.get('[style="top:0px"]').should('have.length', 2); // top + bottom - cy.get('.grid-canvas-left > [style="top:0px"]').children().should('have.length', 11 * 2); + cy.get('[style="top: 0px;"]').should('have.length', 2); // top + bottom + cy.get('.grid-canvas-left > [style="top: 0px;"]').children().should('have.length', 11 * 2); // top-left - cy.get('.grid-canvas-top.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(0)').should('contain', ''); - cy.get('.grid-canvas-top.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(1)').should('contain', 'Task 0'); - cy.get('.grid-canvas-top.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(2)').should('contain', '5 days'); - cy.get('.grid-canvas-top.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(4)').should('contain', '01/01/2009'); - cy.get('.grid-canvas-top.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(5)').should('contain', '01/05/2009'); - cy.get('.grid-canvas-top.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(7)').should('contain', '0'); + cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(0)').should('contain', ''); + cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', 'Task 0'); + cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(2)').should('contain', '5 days'); + cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(4)').should('contain', '01/01/2009'); + cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(5)').should('contain', '01/05/2009'); + cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(7)').should('contain', '0'); // bottom-left - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(0)').should('contain', ''); - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(1)').should('contain', 'Task 7'); - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(2)').should('contain', '5 days'); - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(4)').should('contain', '01/01/2009'); - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(5)').should('contain', '01/05/2009'); - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top:0px"] > .slick-cell:nth(7)').should('contain', '7'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(0)').should('contain', ''); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', 'Task 7'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(2)').should('contain', '5 days'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(4)').should('contain', '01/01/2009'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(5)').should('contain', '01/05/2009'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(7)').should('contain', '7'); }); }); diff --git a/cypress/e2e/example-grouping-esm.cy.ts b/cypress/e2e/example-grouping-esm.cy.ts index ab0170d01..7d78b62c1 100644 --- a/cypress/e2e/example-grouping-esm.cy.ts +++ b/cypress/e2e/example-grouping-esm.cy.ts @@ -25,13 +25,13 @@ describe('Example - Grouping & Aggregators (ESM)', { retries: 1 }, () => { cy.get('[data-test="group-duration-sort-value-btn"]').click(); cy.get('[data-test="collapse-all-btn"]').click(); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(0) .slick-group-toggle.collapsed`).should('have.length', 1); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 0'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0) .slick-group-toggle.collapsed`).should('have.length', 1); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 0'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 1'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 2}px"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 2'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 3'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 4}px"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 4'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 1'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 2'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 3'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 4}px;"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 4'); }); it('should click on Expand All columns and expect 1st row as grouping title and 2nd row as a regular row', () => { @@ -39,42 +39,42 @@ describe('Example - Grouping & Aggregators (ESM)', { retries: 1 }, () => { cy.get('[data-test="group-duration-sort-value-btn"]').click(); cy.get('[data-test="expand-all-btn"]').click(); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(0) .slick-group-toggle.expanded`).should('have.length', 1); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 0'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0) .slick-group-toggle.expanded`).should('have.length', 1); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 0'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(1)`).should('contain', 'Task'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(2)`).should('contain', '0'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(1)`).should('contain', 'Task'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(2)`).should('contain', '0'); }); it('should "Group by Duration then Effort-Driven" and expect 1st row to be expanded, 2nd row to be collapsed and 3rd row to have group totals', () => { cy.get('[data-test="group-duration-effort-btn"]').click(); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"].slick-group-level-0 > .slick-cell:nth(0) .slick-group-toggle.expanded`).should('have.length', 1); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"].slick-group-level-0 > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 0'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"].slick-group-level-0 > .slick-cell:nth(0) .slick-group-toggle.expanded`).should('have.length', 1); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"].slick-group-level-0 > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 0'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"].slick-group-level-1 .slick-group-toggle.collapsed`).should('have.length', 1); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"].slick-group-level-1 .slick-group-title`).should('contain', 'Effort-Driven: False'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"].slick-group-level-1 .slick-group-toggle.collapsed`).should('have.length', 1); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"].slick-group-level-1 .slick-group-title`).should('contain', 'Effort-Driven: False'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 2}px"].slick-group-level-1 .slick-group-toggle.collapsed`).should('have.length', 1); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 2}px"].slick-group-level-1 .slick-group-title`).should('contain', 'Effort-Driven: True'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"].slick-group-level-1 .slick-group-toggle.collapsed`).should('have.length', 1); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"].slick-group-level-1 .slick-group-title`).should('contain', 'Effort-Driven: True'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"].slick-group-totals.slick-group-level-0 .slick-cell:nth(2)`).should('contain', 'total: 0'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"].slick-group-totals.slick-group-level-0 .slick-cell:nth(2)`).should('contain', 'total: 0'); }); it('should "Group by Duration then Effort-Driven then Percent" and expect fist 2 rows to be expanded, 3rd row to be collapsed then 4th row to have group total', () => { cy.get('[data-test="group-duration-effort-percent-btn"]').click(); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"].slick-group-level-0 > .slick-cell:nth(0) .slick-group-toggle.expanded`).should('have.length', 1); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"].slick-group-level-0 > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 0'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"].slick-group-level-0 > .slick-cell:nth(0) .slick-group-toggle.expanded`).should('have.length', 1); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"].slick-group-level-0 > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 0'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"].slick-group-level-1 .slick-group-toggle.expanded`).should('have.length', 1); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"].slick-group-level-1 .slick-group-title`).should('contain', 'Effort-Driven: False'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"].slick-group-level-1 .slick-group-toggle.expanded`).should('have.length', 1); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"].slick-group-level-1 .slick-group-title`).should('contain', 'Effort-Driven: False'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 2}px"].slick-group-level-2 .slick-group-toggle.collapsed`).should('have.length', 1); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 2}px"].slick-group-level-2 .slick-group-title`).contains(/^% Complete: [0-9]/); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"].slick-group-level-2 .slick-group-toggle.collapsed`).should('have.length', 1); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"].slick-group-level-2 .slick-group-title`).contains(/^% Complete: [0-9]/); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"].slick-group-totals.slick-group-level-2 .slick-cell:nth(3)`).contains(/^avg: [0-9]\%$/); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"].slick-group-totals.slick-group-level-2`) + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"].slick-group-totals.slick-group-level-2 .slick-cell:nth(3)`).contains(/^avg: [0-9]\%$/); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"].slick-group-totals.slick-group-level-2`) .find('.slick-cell:nth(3)').contains('avg: '); }); }); diff --git a/cypress/e2e/example-grouping.cy.ts b/cypress/e2e/example-grouping.cy.ts index 002e69a69..7d33249c1 100644 --- a/cypress/e2e/example-grouping.cy.ts +++ b/cypress/e2e/example-grouping.cy.ts @@ -25,13 +25,13 @@ describe('Example - Grouping & Aggregators', { retries: 1 }, () => { cy.get('[data-test="group-duration-sort-value-btn"]').click(); cy.get('[data-test="collapse-all-btn"]').click(); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(0) .slick-group-toggle.collapsed`).should('have.length', 1); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 0'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0) .slick-group-toggle.collapsed`).should('have.length', 1); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 0'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 1'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 2}px"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 2'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 3'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 4}px"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 4'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 1'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 2'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 3'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 4}px;"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 4'); }); it('should click on Expand All columns and expect 1st row as grouping title and 2nd row as a regular row', () => { @@ -39,42 +39,42 @@ describe('Example - Grouping & Aggregators', { retries: 1 }, () => { cy.get('[data-test="group-duration-sort-value-btn"]').click(); cy.get('[data-test="expand-all-btn"]').click(); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(0) .slick-group-toggle.expanded`).should('have.length', 1); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 0'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0) .slick-group-toggle.expanded`).should('have.length', 1); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 0'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(1)`).should('contain', 'Task'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(2)`).should('contain', '0'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(1)`).should('contain', 'Task'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(2)`).should('contain', '0'); }); it('should "Group by Duration then Effort-Driven" and expect 1st row to be expanded, 2nd row to be collapsed and 3rd row to have group totals', () => { cy.get('[data-test="group-duration-effort-btn"]').click(); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"].slick-group-level-0 > .slick-cell:nth(0) .slick-group-toggle.expanded`).should('have.length', 1); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"].slick-group-level-0 > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 0'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"].slick-group-level-0 > .slick-cell:nth(0) .slick-group-toggle.expanded`).should('have.length', 1); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"].slick-group-level-0 > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 0'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"].slick-group-level-1 .slick-group-toggle.collapsed`).should('have.length', 1); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"].slick-group-level-1 .slick-group-title`).should('contain', 'Effort-Driven: False'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"].slick-group-level-1 .slick-group-toggle.collapsed`).should('have.length', 1); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"].slick-group-level-1 .slick-group-title`).should('contain', 'Effort-Driven: False'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 2}px"].slick-group-level-1 .slick-group-toggle.collapsed`).should('have.length', 1); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 2}px"].slick-group-level-1 .slick-group-title`).should('contain', 'Effort-Driven: True'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"].slick-group-level-1 .slick-group-toggle.collapsed`).should('have.length', 1); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"].slick-group-level-1 .slick-group-title`).should('contain', 'Effort-Driven: True'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"].slick-group-totals.slick-group-level-0 .slick-cell:nth(2)`).should('contain', 'total: 0'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"].slick-group-totals.slick-group-level-0 .slick-cell:nth(2)`).should('contain', 'total: 0'); }); it('should "Group by Duration then Effort-Driven then Percent" and expect fist 2 rows to be expanded, 3rd row to be collapsed then 4th row to have group total', () => { cy.get('[data-test="group-duration-effort-percent-btn"]').click(); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"].slick-group-level-0 > .slick-cell:nth(0) .slick-group-toggle.expanded`).should('have.length', 1); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"].slick-group-level-0 > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 0'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"].slick-group-level-0 > .slick-cell:nth(0) .slick-group-toggle.expanded`).should('have.length', 1); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"].slick-group-level-0 > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 0'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"].slick-group-level-1 .slick-group-toggle.expanded`).should('have.length', 1); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"].slick-group-level-1 .slick-group-title`).should('contain', 'Effort-Driven: False'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"].slick-group-level-1 .slick-group-toggle.expanded`).should('have.length', 1); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"].slick-group-level-1 .slick-group-title`).should('contain', 'Effort-Driven: False'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 2}px"].slick-group-level-2 .slick-group-toggle.collapsed`).should('have.length', 1); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 2}px"].slick-group-level-2 .slick-group-title`).contains(/^% Complete: [0-9]/); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"].slick-group-level-2 .slick-group-toggle.collapsed`).should('have.length', 1); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"].slick-group-level-2 .slick-group-title`).contains(/^% Complete: [0-9]/); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"].slick-group-totals.slick-group-level-2 .slick-cell:nth(3)`).contains(/^avg: [0-9]\%$/); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"].slick-group-totals.slick-group-level-2`) + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"].slick-group-totals.slick-group-level-2 .slick-cell:nth(3)`).contains(/^avg: [0-9]\%$/); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"].slick-group-totals.slick-group-level-2`) .find('.slick-cell:nth(3)').contains('avg: '); }); }); diff --git a/cypress/e2e/example-plugin-custom-tooltip.cy.ts b/cypress/e2e/example-plugin-custom-tooltip.cy.ts index fbb715011..a199d8e8f 100644 --- a/cypress/e2e/example-plugin-custom-tooltip.cy.ts +++ b/cypress/e2e/example-plugin-custom-tooltip.cy.ts @@ -27,7 +27,7 @@ describe('Example - Custom Tooltip', () => { }); it('should mouse over 1st row checkbox column and NOT expect any tooltip to show since it is disabled on that column', () => { - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(0)`).as('checkbox0-cell'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0)`).as('checkbox0-cell'); cy.get('@checkbox0-cell').trigger('mouseover'); cy.get('.slick-custom-tooltip').should('not.exist'); @@ -35,7 +35,7 @@ describe('Example - Custom Tooltip', () => { }); it('should mouse over Task 1 cell and expect async tooltip to show', () => { - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(1)`).as('task1-cell'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(1)`).as('task1-cell'); cy.get('@task1-cell').should('contain', 'Task 1'); cy.get('@task1-cell').trigger('mouseover'); cy.get('.slick-custom-tooltip').contains('loading...'); @@ -54,7 +54,7 @@ describe('Example - Custom Tooltip', () => { }); it('should mouse over Task 5 cell and expect async tooltip to show', () => { - cy.get(`[style="top:${GRID_ROW_HEIGHT * 5}px"] > .slick-cell:nth(1)`).as('task5-cell'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 5}px;"] > .slick-cell:nth(1)`).as('task5-cell'); cy.get('@task5-cell').should('contain', 'Task 5'); cy.get('@task5-cell').trigger('mouseover'); cy.get('.slick-custom-tooltip').contains('loading...'); @@ -73,7 +73,7 @@ describe('Example - Custom Tooltip', () => { }); it('should mouse over 6th row Description and expect full cell content to show in a tooltip because cell has ellipsis and is too long for the cell itself', () => { - cy.get(`[style="top:${GRID_ROW_HEIGHT * 5}px"] > .slick-cell:nth(2)`).as('desc5-cell'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 5}px;"] > .slick-cell:nth(2)`).as('desc5-cell'); cy.get('@desc5-cell').should('contain', 'This is a sample task description.'); cy.get('@desc5-cell').trigger('mouseover'); @@ -85,7 +85,7 @@ describe('Example - Custom Tooltip', () => { }); it('should mouse over 6th row Description 2 and expect regular tooltip title + concatenated full cell content when using "useRegularTooltipFromFormatterOnly: true"', () => { - cy.get(`[style="top:${GRID_ROW_HEIGHT * 5}px"] > .slick-cell:nth(3)`).as('desc2-5-cell'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 5}px;"] > .slick-cell:nth(3)`).as('desc2-5-cell'); cy.get('@desc2-5-cell').should('contain', 'This is a sample task description.'); cy.get('@desc2-5-cell').trigger('mouseover'); @@ -96,7 +96,7 @@ describe('Example - Custom Tooltip', () => { }); it('should mouse over 6th row Duration and expect a custom tooltip shown with 4 label/value pairs displayed', () => { - cy.get(`[style="top:${GRID_ROW_HEIGHT * 5}px"] > .slick-cell:nth(4)`).as('duration5-cell'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 5}px;"] > .slick-cell:nth(4)`).as('duration5-cell'); cy.get('@duration5-cell').should('contain', '5 days'); cy.get('@duration5-cell').trigger('mouseover'); @@ -119,7 +119,7 @@ describe('Example - Custom Tooltip', () => { }); it('should mouse over % Complete cell of Task 5 and expect regular tooltip to show with content "x %" where x is a number', () => { - cy.get(`[style="top:${GRID_ROW_HEIGHT * 5}px"] > .slick-cell:nth(5)`).as('percentage-cell'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 5}px;"] > .slick-cell:nth(5)`).as('percentage-cell'); cy.get('@percentage-cell').find('.percent-complete-bar').should('exist'); cy.get('@percentage-cell').trigger('mouseover'); diff --git a/cypress/e2e/example-row-detail-selection-and-move.cy.ts b/cypress/e2e/example-row-detail-selection-and-move.cy.ts index 2c6643dc5..ca7e6afda 100644 --- a/cypress/e2e/example-row-detail-selection-and-move.cy.ts +++ b/cypress/e2e/example-row-detail-selection-and-move.cy.ts @@ -38,18 +38,18 @@ describe('Example - Row Detail/Row Move/Checkbox Selector Plugins', () => { }); it('should drag opened Row Detail to another valid position in the grid', () => { - cy.get('[style="top:25px"] > .slick-cell.cell-reorder').as('moveIconTask1'); - cy.get('[style="top:75px"] > .slick-cell.cell-reorder').as('moveIconTask3'); - cy.get('[style="top:100px"]').as('expandIconTask4'); + cy.get('[style="top: 25px;"] > .slick-cell.cell-reorder').as('moveIconTask1'); + cy.get('[style="top: 75px;"] > .slick-cell.cell-reorder').as('moveIconTask3'); + cy.get('[style="top: 100px;"]').as('expandIconTask4'); cy.get('@moveIconTask3') .trigger('mousedown', { button: 0, force: true }) .trigger('mousemove', 'bottomRight'); - cy.get('[style="top:100px"]') + cy.get('[style="top: 100px;"]') .trigger('mousemove', 'bottomRight', { force: true }); - cy.get('[style="top:100px"]') + cy.get('[style="top: 100px;"]') .trigger('mouseup', 'bottomRight', { force: true }); cy.get('input[type="checkbox"]:checked') @@ -60,28 +60,28 @@ describe('Example - Row Detail/Row Move/Checkbox Selector Plugins', () => { cy.get('.slick-viewport-top.slick-viewport-left') .scrollTo('top'); - cy.get('[style="top:0px"] > .slick-cell:nth(4)').should('contain', 'Task 0'); - cy.get('[style="top:25px"] > .slick-cell:nth(4)').should('contain', 'Task 1'); - cy.get('[style="top:50px"] > .slick-cell:nth(4)').should('contain', 'Task 2'); - cy.get('[style="top:75px"] > .slick-cell:nth(4)').should('contain', 'Task 4'); - cy.get('[style="top:100px"] > .slick-cell:nth(4)').should('contain', 'Task 3'); + cy.get('[style="top: 0px;"] > .slick-cell:nth(4)').should('contain', 'Task 0'); + cy.get('[style="top: 25px;"] > .slick-cell:nth(4)').should('contain', 'Task 1'); + cy.get('[style="top: 50px;"] > .slick-cell:nth(4)').should('contain', 'Task 2'); + cy.get('[style="top: 75px;"] > .slick-cell:nth(4)').should('contain', 'Task 4'); + cy.get('[style="top: 100px;"] > .slick-cell:nth(4)').should('contain', 'Task 3'); cy.get('input[type="checkbox"]:checked') .should('have.length', 0); }); it('should try moving a row to an invalid target and expect nothing moved (same rows as prior test)', () => { - cy.get('[style="top:25px"] > .slick-cell.cell-reorder').as('moveIconTask1'); - cy.get('[style="top:100px"]').as('expandIconTask4'); + cy.get('[style="top: 25px;"] > .slick-cell.cell-reorder').as('moveIconTask1'); + cy.get('[style="top: 100px;"]').as('expandIconTask4'); cy.get('@moveIconTask1') .trigger('mousedown', { button: 0, force: true }) .trigger('mousemove', 'bottomRight'); - cy.get('[style="top:75px"]') + cy.get('[style="top: 75px;"]') .trigger('mousemove', 'topRight', { force: true }); - cy.get('[style="top:75px"]') + cy.get('[style="top: 75px;"]') .trigger('mouseup', 'topRight', { force: true }); cy.get('input[type="checkbox"]:checked') @@ -89,11 +89,11 @@ describe('Example - Row Detail/Row Move/Checkbox Selector Plugins', () => { }); it('should select 2 rows (Task 1,3), then move row and expect the 2 rows to still be selected without any other rows', () => { - cy.get('[style="top:25px"] > .slick-cell:nth(2)').click(); - cy.get('[style="top:100px"] > .slick-cell:nth(2)').click(); + cy.get('[style="top: 25px;"] > .slick-cell:nth(2)').click(); + cy.get('[style="top: 100px;"] > .slick-cell:nth(2)').click(); - cy.get('[style="top:25px"] > .slick-cell.cell-reorder').as('moveIconTask1'); - cy.get('[style="top:150px"]').as('moveIconTask3'); + cy.get('[style="top: 25px;"] > .slick-cell.cell-reorder').as('moveIconTask1'); + cy.get('[style="top: 150px;"]').as('moveIconTask3'); cy.get('@moveIconTask1').should('have.length', 1); @@ -105,25 +105,25 @@ describe('Example - Row Detail/Row Move/Checkbox Selector Plugins', () => { .trigger('mousemove', 'bottomRight', { force: true }) .trigger('mouseup', 'bottomRight', { force: true }); - cy.get('[style="top:0px"] > .slick-cell:nth(4)').should('contain', 'Task 0'); - cy.get('[style="top:25px"] > .slick-cell:nth(4)').should('contain', 'Task 2'); - cy.get('[style="top:50px"] > .slick-cell:nth(4)').should('contain', 'Task 4'); - cy.get('[style="top:75px"] > .slick-cell:nth(4)').should('contain', 'Task 3'); - cy.get('[style="top:100px"] > .slick-cell:nth(4)').should('contain', 'Task 5'); - cy.get('[style="top:125px"] > .slick-cell:nth(4)').should('contain', 'Task 6'); - cy.get('[style="top:150px"] > .slick-cell:nth(4)').should('contain', 'Task 1'); + cy.get('[style="top: 0px;"] > .slick-cell:nth(4)').should('contain', 'Task 0'); + cy.get('[style="top: 25px;"] > .slick-cell:nth(4)').should('contain', 'Task 2'); + cy.get('[style="top: 50px;"] > .slick-cell:nth(4)').should('contain', 'Task 4'); + cy.get('[style="top: 75px;"] > .slick-cell:nth(4)').should('contain', 'Task 3'); + cy.get('[style="top: 100px;"] > .slick-cell:nth(4)').should('contain', 'Task 5'); + cy.get('[style="top: 125px;"] > .slick-cell:nth(4)').should('contain', 'Task 6'); + cy.get('[style="top: 150px;"] > .slick-cell:nth(4)').should('contain', 'Task 1'); // Task 4 and 3 should be selected cy.get('input[type="checkbox"]:checked').should('have.length', 2); - cy.get('[style="top:75px"] > .slick-cell:nth(2) input[type="checkbox"]:checked').should('have.length', 1); - cy.get('[style="top:150px"] > .slick-cell:nth(2) input[type="checkbox"]:checked').should('have.length', 1); + cy.get('[style="top: 75px;"] > .slick-cell:nth(2) input[type="checkbox"]:checked').should('have.length', 1); + cy.get('[style="top: 150px;"] > .slick-cell:nth(2) input[type="checkbox"]:checked').should('have.length', 1); }); it('should click on "Single Row Move OFF", then drag a row and expect both selected rows to be moved together', () => { cy.contains('Single Row Move OFF').click(); - cy.get('[style="top:175px"] > .slick-cell.cell-reorder').as('moveIconTask7'); - cy.get('[style="top:75px"] > .slick-cell.cell-reorder').as('moveIconTask3'); + cy.get('[style="top: 175px;"] > .slick-cell.cell-reorder').as('moveIconTask7'); + cy.get('[style="top: 75px;"] > .slick-cell.cell-reorder').as('moveIconTask3'); cy.get('@moveIconTask3').should('have.length', 1); @@ -131,30 +131,30 @@ describe('Example - Row Detail/Row Move/Checkbox Selector Plugins', () => { .trigger('mousedown', { button: 0, force: true }) .trigger('mousemove', 'bottomRight'); - cy.get('[style="top:200px"]') + cy.get('[style="top: 200px;"]') .trigger('mousemove', 'bottomRight', { force: true }) .trigger('mouseup', 'bottomRight', { force: true }); - cy.get('[style="top:0px"] > .slick-cell:nth(4)').should('contain', 'Task 0'); - cy.get('[style="top:25px"] > .slick-cell:nth(4)').should('contain', 'Task 2'); - cy.get('[style="top:50px"] > .slick-cell:nth(4)').should('contain', 'Task 4'); - cy.get('[style="top:75px"] > .slick-cell:nth(4)').should('contain', 'Task 5'); - cy.get('[style="top:100px"] > .slick-cell:nth(4)').should('contain', 'Task 6'); - cy.get('[style="top:125px"] > .slick-cell:nth(4)').should('contain', 'Task 7'); - cy.get('[style="top:150px"] > .slick-cell:nth(4)').should('contain', 'Task 8'); - cy.get('[style="top:175px"] > .slick-cell:nth(4)').should('contain', 'Task 3'); - cy.get('[style="top:200px"] > .slick-cell:nth(4)').should('contain', 'Task 1'); + cy.get('[style="top: 0px;"] > .slick-cell:nth(4)').should('contain', 'Task 0'); + cy.get('[style="top: 25px;"] > .slick-cell:nth(4)').should('contain', 'Task 2'); + cy.get('[style="top: 50px;"] > .slick-cell:nth(4)').should('contain', 'Task 4'); + cy.get('[style="top: 75px;"] > .slick-cell:nth(4)').should('contain', 'Task 5'); + cy.get('[style="top: 100px;"] > .slick-cell:nth(4)').should('contain', 'Task 6'); + cy.get('[style="top: 125px;"] > .slick-cell:nth(4)').should('contain', 'Task 7'); + cy.get('[style="top: 150px;"] > .slick-cell:nth(4)').should('contain', 'Task 8'); + cy.get('[style="top: 175px;"] > .slick-cell:nth(4)').should('contain', 'Task 3'); + cy.get('[style="top: 200px;"] > .slick-cell:nth(4)').should('contain', 'Task 1'); // Task 1 and 3 should be selected cy.get('input[type="checkbox"]:checked').should('have.length', 2); - cy.get('[style="top:175px"] > .slick-cell:nth(2) input[type="checkbox"]:checked').should('have.length', 1); - cy.get('[style="top:200px"] > .slick-cell:nth(2) input[type="checkbox"]:checked').should('have.length', 1); + cy.get('[style="top: 175px;"] > .slick-cell:nth(2) input[type="checkbox"]:checked').should('have.length', 1); + cy.get('[style="top: 200px;"] > .slick-cell:nth(2) input[type="checkbox"]:checked').should('have.length', 1); }); it('should open the Task 3 Row Detail and still expect same detail', () => { - cy.get('[style="top:175px"] > .slick-cell:nth(4)').should('contain', 'Task 3'); + cy.get('[style="top: 175px;"] > .slick-cell:nth(4)').should('contain', 'Task 3'); - cy.get('[style="top:175px"] > .slick-cell:nth(0)') + cy.get('[style="top: 175px;"] > .slick-cell:nth(0)') .click() .wait(250); diff --git a/cypress/e2e/example3-editing.cy.ts b/cypress/e2e/example3-editing.cy.ts index 89712bedf..910ed0bea 100644 --- a/cypress/e2e/example3-editing.cy.ts +++ b/cypress/e2e/example3-editing.cy.ts @@ -23,11 +23,11 @@ describe('Example3 Editing', () => { }); it('should be able to edit "Description" by double-clicking on first row and expect no more editable cell', () => { - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(1)`).should('contain', 'This is a sample'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(1)`).click(); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(1)`).should('contain', 'This is a sample'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(1)`).click(); cy.get('.slick-large-editor-text').should('have.length', 0); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(1)`).dblclick(); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(1)`).dblclick(); cy.get('.slick-large-editor-text').should('have.length', 1); cy.get('.slick-large-editor-text textarea') @@ -46,8 +46,8 @@ describe('Example3 Editing', () => { }); it('should be able to edit "Description" by clicking once on second row and expect next row to become editable after clicking "Save" button', () => { - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(1)`).should('contain', 'This is a sample'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(1)`).click(); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(1)`).should('contain', 'This is a sample'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(1)`).click(); cy.get('.slick-large-editor-text').should('have.length', 1); cy.get('.slick-large-editor-text textarea') @@ -57,7 +57,7 @@ describe('Example3 Editing', () => { .contains('Save') .click(); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(1)`).should('contain', 'Second Row!'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(1)`).should('contain', 'Second Row!'); cy.get('.slick-large-editor-text').should('have.length', 1); cy.get('.slick-large-editor-text textarea') @@ -71,8 +71,8 @@ describe('Example3 Editing', () => { }); it('should be able to edit "Description" by clicking once on second row and expect next row and not expect next line to become editable', () => { - cy.get(`[style="top:${GRID_ROW_HEIGHT * 2}px"] > .slick-cell:nth(1)`).should('contain', 'This is a sample'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 2}px"] > .slick-cell:nth(1)`).click(); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(1)`).should('contain', 'This is a sample'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(1)`).click(); cy.get('.slick-large-editor-text').should('have.length', 1); cy.get('.slick-large-editor-text textarea') @@ -82,7 +82,7 @@ describe('Example3 Editing', () => { .contains('Save') .click(); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 2}px"] > .slick-cell:nth(1)`).should('contain', 'Third Row Text'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(1)`).should('contain', 'Third Row Text'); cy.get('.slick-large-editor-text').should('have.length', 0); }); @@ -92,8 +92,8 @@ describe('Example3 Editing', () => { }); it('should be able to edit "Description" and expect once again that the next line will become editable', () => { - cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"] > .slick-cell:nth(1)`).should('contain', 'This is a sample'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"] > .slick-cell:nth(1)`).click(); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(1)`).should('contain', 'This is a sample'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(1)`).click(); cy.get('.slick-large-editor-text').should('have.length', 1); cy.get('.slick-large-editor-text textarea') @@ -103,7 +103,7 @@ describe('Example3 Editing', () => { .contains('Save') .click(); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"] > .slick-cell:nth(1)`).should('contain', 'Fourth Row'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(1)`).should('contain', 'Fourth Row'); cy.get('.slick-large-editor-text').should('have.length', 1); cy.get('.slick-large-editor-text textarea') diff --git a/cypress/e2e/example3b-editing-with-undo.cy.ts b/cypress/e2e/example3b-editing-with-undo.cy.ts index d4ac285e2..71a5f09e5 100644 --- a/cypress/e2e/example3b-editing-with-undo.cy.ts +++ b/cypress/e2e/example3b-editing-with-undo.cy.ts @@ -23,11 +23,11 @@ describe('Example3 Editing', () => { }); it('should be able to edit "Description" by double-clicking on first row and expect no more editable cell', () => { - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(1)`).should('contain', 'This is a sample'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(1)`).click(); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(1)`).should('contain', 'This is a sample'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(1)`).click(); cy.get('.slick-large-editor-text').should('have.length', 0); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(1)`).dblclick(); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(1)`).dblclick(); cy.get('.slick-large-editor-text').should('have.length', 1); cy.get('.slick-large-editor-text textarea') @@ -45,8 +45,8 @@ describe('Example3 Editing', () => { }); it('should be able to edit "Description" by clicking once on second row and expect next row to become editable after clicking "Save" button', () => { - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(1)`).should('contain', 'This is a sample'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(1)`).click(); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(1)`).should('contain', 'This is a sample'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(1)`).click(); cy.get('.slick-large-editor-text').should('have.length', 1); cy.get('.slick-large-editor-text textarea') @@ -56,7 +56,7 @@ describe('Example3 Editing', () => { .contains('Save') .click(); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 1}px"] > .slick-cell:nth(1)`).should('contain', 'Second Row!'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(1)`).should('contain', 'Second Row!'); cy.get('.slick-large-editor-text').should('have.length', 1); cy.get('.slick-large-editor-text textarea') @@ -83,8 +83,8 @@ describe('Example3 Editing', () => { }); it('should be able to edit "Description" and expect once again that the next line will become editable', () => { - cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"] > .slick-cell:nth(1)`).should('contain', 'This is a sample'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"] > .slick-cell:nth(1)`).click(); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(1)`).should('contain', 'This is a sample'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(1)`).click(); cy.get('.slick-large-editor-text').should('have.length', 1); cy.get('.slick-large-editor-text textarea') @@ -94,7 +94,7 @@ describe('Example3 Editing', () => { .contains('Save') .click(); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"] > .slick-cell:nth(1)`).should('contain', 'Fourth Row'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(1)`).should('contain', 'Fourth Row'); cy.get('.slick-large-editor-text').should('have.length', 1); cy.get('.slick-large-editor-text textarea') @@ -115,12 +115,12 @@ describe('Example3 Editing', () => { }); it('should expect Task 0,3,4 to have descriptions other than original text', () => { - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(0)`).should('contain', 'Task 0'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"] > .slick-cell:nth(0)`).should('contain', 'Task 3'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 4}px"] > .slick-cell:nth(0)`).should('contain', 'Task 4'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(1)`).should('not.contain', 'This is a sample'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"] > .slick-cell:nth(1)`).should('not.contain', 'This is a sample'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 4}px"] > .slick-cell:nth(1)`).should('not.contain', 'This is a sample'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0)`).should('contain', 'Task 0'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(0)`).should('contain', 'Task 3'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 4}px;"] > .slick-cell:nth(0)`).should('contain', 'Task 4'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(1)`).should('not.contain', 'This is a sample'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(1)`).should('not.contain', 'This is a sample'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 4}px;"] > .slick-cell:nth(1)`).should('not.contain', 'This is a sample'); }); it('should click undo edits twice and expect Task 3-4 to be undoned but Task 0 to still be changed', () => { @@ -140,12 +140,12 @@ describe('Example3 Editing', () => { }); it('should expect Task 3-4 to have descriptions other than original text', () => { - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(0)`).should('contain', 'Task 0'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"] > .slick-cell:nth(0)`).should('contain', 'Task 3'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 4}px"] > .slick-cell:nth(0)`).should('contain', 'Task 4'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(1)`).should('not.contain', 'This is a sample'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 0}px"] > .slick-cell:nth(1)`).should('contain', 'Something else'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 3}px"] > .slick-cell:nth(1)`).should('contain', 'This is a sample'); - cy.get(`[style="top:${GRID_ROW_HEIGHT * 4}px"] > .slick-cell:nth(1)`).should('contain', 'This is a sample'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0)`).should('contain', 'Task 0'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(0)`).should('contain', 'Task 3'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 4}px;"] > .slick-cell:nth(0)`).should('contain', 'Task 4'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(1)`).should('not.contain', 'This is a sample'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(1)`).should('contain', 'Something else'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(1)`).should('contain', 'This is a sample'); + cy.get(`[style="top: ${GRID_ROW_HEIGHT * 4}px;"] > .slick-cell:nth(1)`).should('contain', 'This is a sample'); }); }); diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts index 28efab21c..a6135edda 100644 --- a/cypress/support/commands.ts +++ b/cypress/support/commands.ts @@ -47,7 +47,7 @@ Cypress.Commands.add('getCell', (row, col, viewport = 'topLeft', { parentSelecto const canvasSelectorX = position.x ? `.grid-canvas-${position.x}` : ''; const canvasSelectorY = position.y ? `.grid-canvas-${position.y}` : ''; - return cy.get(`${parentSelector} ${canvasSelectorX}${canvasSelectorY} [style="top:${row * rowHeight}px"] > .slick-cell:nth(${col})`); + return cy.get(`${parentSelector} ${canvasSelectorX}${canvasSelectorY} [style="top: ${row * rowHeight}px;"] > .slick-cell:nth(${col})`); }); const LOCAL_STORAGE_MEMORY = {}; diff --git a/src/slick.grid.ts b/src/slick.grid.ts index b6454be0c..5c73c4e28 100644 --- a/src/slick.grid.ts +++ b/src/slick.grid.ts @@ -3806,7 +3806,7 @@ export class SlickGrid = Column, O e const frozenRowOffset = this.getFrozenRowOffset(row); - const rowHtml = `
    `; //style="top:${(this.getRowTop(row) - frozenRowOffset)}px" + const rowHtml = `
    `; //style="top:${(this.getRowTop(row) - frozenRowOffset)}px" stringArrayL.push(rowHtml); @@ -4660,13 +4660,10 @@ export class SlickGrid = Column, O e const xRight = document.createElement('div'); x.innerHTML = this.sanitizeHtmlString(stringArrayL.join('')); xRight.innerHTML = this.sanitizeHtmlString(stringArrayR.join('')); - const elements = x.querySelectorAll('[data-top]') as NodeListOf; - elements?.forEach((element: HTMLElement) => { - const top = element.dataset.top; - if (top) { - element.style.top = `${top}px`; - } - }); + const elements1 = x.querySelectorAll('[data-top]') as NodeListOf; + const elements2 = xRight.querySelectorAll('[data-top]') as NodeListOf; + this.applyTopStyling(elements1); + this.applyTopStyling(elements2); for (let i = 0, ii = rows.length; i < ii; i++) { if ((this.hasFrozenRows) && (rows[i] >= this.actualFrozenRow)) { @@ -4700,6 +4697,14 @@ export class SlickGrid = Column, O e this.activeCellNode = this.getCellNode(this.activeRow, this.activeCell); } } + protected applyTopStyling(elements: NodeListOf) { + elements?.forEach((element: HTMLElement) => { + const top = element.dataset.top; + if (top) { + element.style.top = top; + } + }); + } protected startPostProcessing() { if (!this._options.enableAsyncPostRender) { From d7f2b4b8c097d263a140ce18f915ffbcd23f7cfd Mon Sep 17 00:00:00 2001 From: Jesper Jakobsen Date: Tue, 7 Nov 2023 07:10:27 +0100 Subject: [PATCH 06/12] Changed to check if undefined instead --- src/slick.grid.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/slick.grid.ts b/src/slick.grid.ts index 5c73c4e28..6d0216ad4 100644 --- a/src/slick.grid.ts +++ b/src/slick.grid.ts @@ -4660,10 +4660,12 @@ export class SlickGrid = Column, O e const xRight = document.createElement('div'); x.innerHTML = this.sanitizeHtmlString(stringArrayL.join('')); xRight.innerHTML = this.sanitizeHtmlString(stringArrayR.join('')); + console.time("applying css") const elements1 = x.querySelectorAll('[data-top]') as NodeListOf; const elements2 = xRight.querySelectorAll('[data-top]') as NodeListOf; this.applyTopStyling(elements1); this.applyTopStyling(elements2); + console.timeEnd("applying css") for (let i = 0, ii = rows.length; i < ii; i++) { if ((this.hasFrozenRows) && (rows[i] >= this.actualFrozenRow)) { @@ -4700,7 +4702,7 @@ export class SlickGrid = Column, O e protected applyTopStyling(elements: NodeListOf) { elements?.forEach((element: HTMLElement) => { const top = element.dataset.top; - if (top) { + if (top !== undefined) { element.style.top = top; } }); From 0fd72a4eb33bdcd5a3f3ef804c9be33bb6468f14 Mon Sep 17 00:00:00 2001 From: Jesper Jakobsen Date: Tue, 7 Nov 2023 07:13:27 +0100 Subject: [PATCH 07/12] added semicolons --- src/slick.grid.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/slick.grid.ts b/src/slick.grid.ts index 6d0216ad4..9ca6815c0 100644 --- a/src/slick.grid.ts +++ b/src/slick.grid.ts @@ -4660,12 +4660,12 @@ export class SlickGrid = Column, O e const xRight = document.createElement('div'); x.innerHTML = this.sanitizeHtmlString(stringArrayL.join('')); xRight.innerHTML = this.sanitizeHtmlString(stringArrayR.join('')); - console.time("applying css") + console.time("applying css"); const elements1 = x.querySelectorAll('[data-top]') as NodeListOf; const elements2 = xRight.querySelectorAll('[data-top]') as NodeListOf; this.applyTopStyling(elements1); this.applyTopStyling(elements2); - console.timeEnd("applying css") + console.timeEnd("applying css"); for (let i = 0, ii = rows.length; i < ii; i++) { if ((this.hasFrozenRows) && (rows[i] >= this.actualFrozenRow)) { From 113b6130512409a13c488826acf985f47b98490a Mon Sep 17 00:00:00 2001 From: Jesper Jakobsen Date: Wed, 8 Nov 2023 09:55:12 +0100 Subject: [PATCH 08/12] Added option for html rendering instead of dynamic string rendering --- src/slick.grid.ts | 159 +++++++++++++++++++++++++++++++--------------- 1 file changed, 107 insertions(+), 52 deletions(-) diff --git a/src/slick.grid.ts b/src/slick.grid.ts index 9ca6815c0..7cfb26c5e 100644 --- a/src/slick.grid.ts +++ b/src/slick.grid.ts @@ -3395,9 +3395,9 @@ export class SlickGrid = Column, O e } if (this.options.mixinDefaults) { - Utils.applyDefaults(m, this._columnDefaults); - if (!m.autoSize) { m.autoSize = {}; } - Utils.applyDefaults(m.autoSize, this._columnAutosizeDefaults); + Utils.applyDefaults(m, this._columnDefaults); + if (!m.autoSize) { m.autoSize = {}; } + Utils.applyDefaults(m.autoSize, this._columnAutosizeDefaults); } else { m = this.columns[i] = Utils.extend({}, this._columnDefaults, m); m.autoSize = Utils.extend({}, this._columnAutosizeDefaults, m.autoSize); @@ -3507,7 +3507,7 @@ export class SlickGrid = Column, O e this.makeActiveCellNormal(); } - protected internal_setOptions(suppressRender?: boolean, suppressColumnSet?: boolean, suppressSetOverflow?: boolean) : void { + protected internal_setOptions(suppressRender?: boolean, suppressColumnSet?: boolean, suppressSetOverflow?: boolean): void { if (this._options.showColumnHeader !== undefined) { this.setColumnHeaderVisibility(this._options.showColumnHeader); } @@ -3785,7 +3785,7 @@ export class SlickGrid = Column, O e return item[columnDef.field as keyof TData]; } - protected appendRowHtml(stringArrayL: string[], stringArrayR: string[], row: number, range: CellViewportRange, dataLength: number) { + protected appendRowHtml(stringArrayL: HTMLElement[] | string[], stringArrayR: HTMLElement[] | string[], row: number, range: CellViewportRange, dataLength: number) { const d = this.getDataItem(row); const dataLoading = row < dataLength && !d; let rowCss = 'slick-row' + @@ -3806,14 +3806,28 @@ export class SlickGrid = Column, O e const frozenRowOffset = this.getFrozenRowOffset(row); - const rowHtml = `
    `; //style="top:${(this.getRowTop(row) - frozenRowOffset)}px" + const rowDiv = document.createElement('div'); + let rowDivR: HTMLElement | undefined; + if (!this._options.nonce) { + const rowHtml = `
    `; + (stringArrayL as string[]).push(rowHtml); - stringArrayL.push(rowHtml); - - if (this.hasFrozenColumns()) { - stringArrayR.push(rowHtml); + if (this.hasFrozenColumns()) { + (stringArrayR as string[]).push(rowHtml); + } + } else { + rowDiv.className = 'ui-widget-content ' + rowCss; + rowDiv.style.top = `${(this.getRowTop(row) - frozenRowOffset)}px`; + (stringArrayL as HTMLElement[]).push(rowDiv); + if (this.hasFrozenColumns()) { + //it has to be a deep copy otherwise we will have issues with pass by reference in js since + //attempting to add the same element to 2 different arrays will just move 1 item to the other array + rowDivR = rowDiv.cloneNode(true) as HTMLElement; + (stringArrayR as HTMLElement[]).push(rowDivR); + } } + let colspan: number | string; let m: C; for (let i = 0, ii = this.columns.length; i < ii; i++) { @@ -3829,6 +3843,15 @@ export class SlickGrid = Column, O e } } + let tmpRow: HTMLElement | string[] | undefined; + let tmpRowR: HTMLElement | string[] | undefined; + if (this._options.nonce) { + tmpRow = rowDiv; + tmpRowR = rowDivR; + } else { + tmpRow = (stringArrayL as string[]); + tmpRowR = (stringArrayR as string[]); + } // Do not render cells outside of the viewport. if (this.columnPosRight[Math.min(ii - 1, i + (colspan as number) - 1)] > range.leftPx) { if (!m.alwaysRenderColumn && this.columnPosLeft[i] > range.rightPx) { @@ -3837,27 +3860,29 @@ export class SlickGrid = Column, O e } if (this.hasFrozenColumns() && (i > this._options.frozenColumn!)) { - this.appendCellHtml(stringArrayR, row, i, (colspan as number), d); + //could add it as a check in the if the ! + this.appendCellHtml(tmpRowR!, row, i, (colspan as number), d); } else { - this.appendCellHtml(stringArrayL, row, i, (colspan as number), d); + this.appendCellHtml(tmpRow, row, i, (colspan as number), d); } } else if (m.alwaysRenderColumn || (this.hasFrozenColumns() && i <= this._options.frozenColumn!)) { - this.appendCellHtml(stringArrayL, row, i, (colspan as number), d); + this.appendCellHtml(tmpRow, row, i, (colspan as number), d); } if ((colspan as number) > 1) { i += ((colspan as number) - 1); } } - - stringArrayL.push('
    '); + if(!this._options.nonce){ + (stringArrayL as string[]).push('
    '); if (this.hasFrozenColumns()) { - stringArrayR.push('
    '); + (stringArrayR as string[]).push('
    '); + } } } - protected appendCellHtml(stringArray: string[], row: number, cell: number, colspan: number, item: TData) { + protected appendCellHtml(stringArray: HTMLElement | string[], row: number, cell: number, colspan: number, item: TData) { // stringArray: stringBuilder containing the HTML parts // row, cell: row and column index // colspan: HTML colspan @@ -3899,25 +3924,50 @@ export class SlickGrid = Column, O e if ((formatterResult as FormatterResultObject)?.addClasses) { addlCssClasses += (addlCssClasses ? ' ' : '') + (formatterResult as FormatterResultObject).addClasses; } - const toolTip = (formatterResult as FormatterResultObject)?.toolTip ? `title="${(formatterResult as FormatterResultObject).toolTip}"` : ''; - let customAttrStr = ''; - if (m.hasOwnProperty('cellAttrs') && m.cellAttrs instanceof Object) { - for (const key in m.cellAttrs) { - if (m.cellAttrs.hasOwnProperty(key)) { - customAttrStr += ` ${key}="${m.cellAttrs[key]}" `; + if (this._options.nonce) { + const toolTipText = (formatterResult as FormatterResultObject)?.toolTip ? `${(formatterResult as FormatterResultObject).toolTip}` : ''; + const cellDiv = document.createElement('div'); + cellDiv.className = cellCss + (addlCssClasses ? ' ' + addlCssClasses : ''); + cellDiv.setAttribute('title', toolTipText); + if (m.hasOwnProperty('cellAttrs') && m.cellAttrs instanceof Object) { + for (const key in m.cellAttrs) { + if (m.cellAttrs.hasOwnProperty(key)) { + cellDiv.setAttribute(key, m.cellAttrs[key]); + } } } - } - stringArray.push(`
    `); + // if there is a corresponding row (if not, this is the Add New row or this data hasn't been loaded yet) + if (item) { + const obj = (Object.prototype.toString.call(formatterResult) !== '[object Object]' ? formatterResult : (formatterResult as FormatterResultObject).text) as string; + cellDiv.innerHTML = this.sanitizeHtmlString(obj); + } - // if there is a corresponding row (if not, this is the Add New row or this data hasn't been loaded yet) - if (item) { - stringArray.push((Object.prototype.toString.call(formatterResult) !== '[object Object]' ? formatterResult : (formatterResult as FormatterResultObject).text) as string); + (stringArray as HTMLElement).appendChild(cellDiv); + } else { + const toolTip = (formatterResult as FormatterResultObject)?.toolTip ? `title="${(formatterResult as FormatterResultObject).toolTip}"` : ''; + + let customAttrStr = ''; + if (m.hasOwnProperty('cellAttrs') && m.cellAttrs instanceof Object) { + for (const key in m.cellAttrs) { + if (m.cellAttrs.hasOwnProperty(key)) { + customAttrStr += ` ${key}="${m.cellAttrs[key]}" `; + } + } + } + + (stringArray as string[]).push(`
    `); + + // if there is a corresponding row (if not, this is the Add New row or this data hasn't been loaded yet) + if (item) { + (stringArray as string[]).push((Object.prototype.toString.call(formatterResult) !== '[object Object]' ? formatterResult : (formatterResult as FormatterResultObject).text) as string); + } + + (stringArray as string[]).push('
    '); } - stringArray.push('
    '); + this.rowsCache[row].cellRenderQueue.push(cell); this.rowsCache[row].cellColSpans[cell] = colspan; @@ -4526,7 +4576,7 @@ export class SlickGrid = Column, O e protected cleanUpAndRenderCells(range: CellViewportRange) { let cacheEntry; - const stringArray: string[] = []; + const stringArray: HTMLElement | string[] = this._options.nonce ? document.createElement('div') : []; const processedRows: number[] = []; let cellsAdded: number; let totalCellsAdded = 0; @@ -4589,13 +4639,19 @@ export class SlickGrid = Column, O e processedRows.push(row); } } + if (this._options.nonce) { + if (!(stringArray as HTMLElement).children.length) { + return; + } + } else { + if (!(stringArray as string[]).length) { + return; + } - if (!stringArray.length) { - return; } const x = document.createElement('div'); - x.innerHTML = this.sanitizeHtmlString(stringArray.join('')); + x.innerHTML = this.sanitizeHtmlString(this._options.nonce ? (stringArray as HTMLElement).outerHTML : (stringArray as string[]).join('')); let processedRow: number | null | undefined; let node: HTMLElement; @@ -4605,6 +4661,10 @@ export class SlickGrid = Column, O e while (Utils.isDefined(columnIdx = cacheEntry.cellRenderQueue.pop())) { node = x.lastChild as HTMLElement; + //no idea why node would be null here but apparently it is.. + if (!node && this._options.nonce) { + continue; + } if (this.hasFrozenColumns() && (columnIdx > this._options.frozenColumn!)) { cacheEntry.rowNode![1].appendChild(node); } else { @@ -4616,8 +4676,8 @@ export class SlickGrid = Column, O e } protected renderRows(range: { top: number; bottom: number; leftPx: number; rightPx: number; }) { - const stringArrayL: string[] = []; - const stringArrayR: string[] = []; + const stringArrayL: HTMLElement[] | string[] = []; + const stringArrayR: HTMLElement[] | string[] = []; const rows: number[] = []; let needToReselectCell = false; const dataLength = this.getDataLength(); @@ -4658,15 +4718,18 @@ export class SlickGrid = Column, O e const x = document.createElement('div'); const xRight = document.createElement('div'); - x.innerHTML = this.sanitizeHtmlString(stringArrayL.join('')); - xRight.innerHTML = this.sanitizeHtmlString(stringArrayR.join('')); - console.time("applying css"); - const elements1 = x.querySelectorAll('[data-top]') as NodeListOf; - const elements2 = xRight.querySelectorAll('[data-top]') as NodeListOf; - this.applyTopStyling(elements1); - this.applyTopStyling(elements2); - console.timeEnd("applying css"); - + if (this._options.nonce) { + stringArrayL.forEach(elm => { + x.appendChild(elm as HTMLElement); + }); + stringArrayR.forEach(elm => { + xRight.appendChild(elm as HTMLElement); + }); + } + else { + x.innerHTML = this.sanitizeHtmlString(stringArrayL.join('')); + xRight.innerHTML = this.sanitizeHtmlString(stringArrayR.join('')); + } for (let i = 0, ii = rows.length; i < ii; i++) { if ((this.hasFrozenRows) && (rows[i] >= this.actualFrozenRow)) { if (this.hasFrozenColumns()) { @@ -4699,14 +4762,6 @@ export class SlickGrid = Column, O e this.activeCellNode = this.getCellNode(this.activeRow, this.activeCell); } } - protected applyTopStyling(elements: NodeListOf) { - elements?.forEach((element: HTMLElement) => { - const top = element.dataset.top; - if (top !== undefined) { - element.style.top = top; - } - }); - } protected startPostProcessing() { if (!this._options.enableAsyncPostRender) { From 7cae5a2b98358b2210c22ab7d79a338040af9e05 Mon Sep 17 00:00:00 2001 From: Jesper Jakobsen Date: Thu, 9 Nov 2023 08:48:23 +0100 Subject: [PATCH 09/12] Changed the check to if the node is not set --- src/slick.grid.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slick.grid.ts b/src/slick.grid.ts index 7cfb26c5e..33837f541 100644 --- a/src/slick.grid.ts +++ b/src/slick.grid.ts @@ -4662,7 +4662,7 @@ export class SlickGrid = Column, O e node = x.lastChild as HTMLElement; //no idea why node would be null here but apparently it is.. - if (!node && this._options.nonce) { + if (!node) { continue; } if (this.hasFrozenColumns() && (columnIdx > this._options.frozenColumn!)) { From 966c804433962bcac3bdc44cc2d918c07fac12d6 Mon Sep 17 00:00:00 2001 From: Jesper Jakobsen Date: Thu, 9 Nov 2023 08:51:10 +0100 Subject: [PATCH 10/12] fixed indentation --- src/slick.grid.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/slick.grid.ts b/src/slick.grid.ts index 33837f541..aed7760e8 100644 --- a/src/slick.grid.ts +++ b/src/slick.grid.ts @@ -3873,12 +3873,12 @@ export class SlickGrid = Column, O e i += ((colspan as number) - 1); } } - if(!this._options.nonce){ + if (!this._options.nonce) { (stringArrayL as string[]).push('
    '); - if (this.hasFrozenColumns()) { - (stringArrayR as string[]).push('
    '); - } + if (this.hasFrozenColumns()) { + (stringArrayR as string[]).push(''); + } } } From 99f04431d0b1769df50e441b84bfac0fa45ac0ca Mon Sep 17 00:00:00 2001 From: Jesper Jakobsen Date: Mon, 13 Nov 2023 06:37:56 +0100 Subject: [PATCH 11/12] removed old method --- examples/example-csp-header.js | 1 + src/slick.grid.ts | 95 +++++++--------------------------- 2 files changed, 19 insertions(+), 77 deletions(-) diff --git a/examples/example-csp-header.js b/examples/example-csp-header.js index 0a401d993..c304b7d47 100644 --- a/examples/example-csp-header.js +++ b/examples/example-csp-header.js @@ -14,6 +14,7 @@ var options = { enableCellNavigation: true, enableColumnReorder: false, nonce: 'random-string', + // autoHeight: true, sanitizer: (html) => DOMPurify.sanitize(html, { RETURN_TRUSTED_TYPE: true }) }; diff --git a/src/slick.grid.ts b/src/slick.grid.ts index aed7760e8..1805ca01f 100644 --- a/src/slick.grid.ts +++ b/src/slick.grid.ts @@ -3785,7 +3785,7 @@ export class SlickGrid = Column, O e return item[columnDef.field as keyof TData]; } - protected appendRowHtml(stringArrayL: HTMLElement[] | string[], stringArrayR: HTMLElement[] | string[], row: number, range: CellViewportRange, dataLength: number) { + protected appendRowHtml(stringArrayL: HTMLElement[], stringArrayR: HTMLElement[], row: number, range: CellViewportRange, dataLength: number) { const d = this.getDataItem(row); const dataLoading = row < dataLength && !d; let rowCss = 'slick-row' + @@ -3808,14 +3808,7 @@ export class SlickGrid = Column, O e const rowDiv = document.createElement('div'); let rowDivR: HTMLElement | undefined; - if (!this._options.nonce) { - const rowHtml = `
    `; - (stringArrayL as string[]).push(rowHtml); - - if (this.hasFrozenColumns()) { - (stringArrayR as string[]).push(rowHtml); - } - } else { + rowDiv.className = 'ui-widget-content ' + rowCss; rowDiv.style.top = `${(this.getRowTop(row) - frozenRowOffset)}px`; (stringArrayL as HTMLElement[]).push(rowDiv); @@ -3825,7 +3818,6 @@ export class SlickGrid = Column, O e rowDivR = rowDiv.cloneNode(true) as HTMLElement; (stringArrayR as HTMLElement[]).push(rowDivR); } - } let colspan: number | string; @@ -3843,15 +3835,6 @@ export class SlickGrid = Column, O e } } - let tmpRow: HTMLElement | string[] | undefined; - let tmpRowR: HTMLElement | string[] | undefined; - if (this._options.nonce) { - tmpRow = rowDiv; - tmpRowR = rowDivR; - } else { - tmpRow = (stringArrayL as string[]); - tmpRowR = (stringArrayR as string[]); - } // Do not render cells outside of the viewport. if (this.columnPosRight[Math.min(ii - 1, i + (colspan as number) - 1)] > range.leftPx) { if (!m.alwaysRenderColumn && this.columnPosLeft[i] > range.rightPx) { @@ -3861,28 +3844,21 @@ export class SlickGrid = Column, O e if (this.hasFrozenColumns() && (i > this._options.frozenColumn!)) { //could add it as a check in the if the ! - this.appendCellHtml(tmpRowR!, row, i, (colspan as number), d); + this.appendCellHtml(rowDivR!, row, i, (colspan as number), d); } else { - this.appendCellHtml(tmpRow, row, i, (colspan as number), d); + this.appendCellHtml(rowDiv, row, i, (colspan as number), d); } } else if (m.alwaysRenderColumn || (this.hasFrozenColumns() && i <= this._options.frozenColumn!)) { - this.appendCellHtml(tmpRow, row, i, (colspan as number), d); + this.appendCellHtml(rowDiv, row, i, (colspan as number), d); } if ((colspan as number) > 1) { i += ((colspan as number) - 1); } } - if (!this._options.nonce) { - (stringArrayL as string[]).push('
    '); - - if (this.hasFrozenColumns()) { - (stringArrayR as string[]).push(''); - } - } } - protected appendCellHtml(stringArray: HTMLElement | string[], row: number, cell: number, colspan: number, item: TData) { + protected appendCellHtml(stringArray: HTMLElement, row: number, cell: number, colspan: number, item: TData) { // stringArray: stringBuilder containing the HTML parts // row, cell: row and column index // colspan: HTML colspan @@ -3925,7 +3901,6 @@ export class SlickGrid = Column, O e addlCssClasses += (addlCssClasses ? ' ' : '') + (formatterResult as FormatterResultObject).addClasses; } - if (this._options.nonce) { const toolTipText = (formatterResult as FormatterResultObject)?.toolTip ? `${(formatterResult as FormatterResultObject).toolTip}` : ''; const cellDiv = document.createElement('div'); cellDiv.className = cellCss + (addlCssClasses ? ' ' + addlCssClasses : ''); @@ -3945,27 +3920,6 @@ export class SlickGrid = Column, O e } (stringArray as HTMLElement).appendChild(cellDiv); - } else { - const toolTip = (formatterResult as FormatterResultObject)?.toolTip ? `title="${(formatterResult as FormatterResultObject).toolTip}"` : ''; - - let customAttrStr = ''; - if (m.hasOwnProperty('cellAttrs') && m.cellAttrs instanceof Object) { - for (const key in m.cellAttrs) { - if (m.cellAttrs.hasOwnProperty(key)) { - customAttrStr += ` ${key}="${m.cellAttrs[key]}" `; - } - } - } - - (stringArray as string[]).push(`
    `); - - // if there is a corresponding row (if not, this is the Add New row or this data hasn't been loaded yet) - if (item) { - (stringArray as string[]).push((Object.prototype.toString.call(formatterResult) !== '[object Object]' ? formatterResult : (formatterResult as FormatterResultObject).text) as string); - } - - (stringArray as string[]).push('
    '); - } @@ -4576,7 +4530,7 @@ export class SlickGrid = Column, O e protected cleanUpAndRenderCells(range: CellViewportRange) { let cacheEntry; - const stringArray: HTMLElement | string[] = this._options.nonce ? document.createElement('div') : []; + const stringArray: HTMLElement = document.createElement('div'); const processedRows: number[] = []; let cellsAdded: number; let totalCellsAdded = 0; @@ -4639,19 +4593,12 @@ export class SlickGrid = Column, O e processedRows.push(row); } } - if (this._options.nonce) { - if (!(stringArray as HTMLElement).children.length) { - return; - } - } else { - if (!(stringArray as string[]).length) { - return; - } - + if (!(stringArray as HTMLElement).children.length) { + return; } const x = document.createElement('div'); - x.innerHTML = this.sanitizeHtmlString(this._options.nonce ? (stringArray as HTMLElement).outerHTML : (stringArray as string[]).join('')); + x.innerHTML = this.sanitizeHtmlString(stringArray.outerHTML); let processedRow: number | null | undefined; let node: HTMLElement; @@ -4676,8 +4623,8 @@ export class SlickGrid = Column, O e } protected renderRows(range: { top: number; bottom: number; leftPx: number; rightPx: number; }) { - const stringArrayL: HTMLElement[] | string[] = []; - const stringArrayR: HTMLElement[] | string[] = []; + const stringArrayL: HTMLElement[] = []; + const stringArrayR: HTMLElement[] = []; const rows: number[] = []; let needToReselectCell = false; const dataLength = this.getDataLength(); @@ -4718,18 +4665,12 @@ export class SlickGrid = Column, O e const x = document.createElement('div'); const xRight = document.createElement('div'); - if (this._options.nonce) { - stringArrayL.forEach(elm => { - x.appendChild(elm as HTMLElement); - }); - stringArrayR.forEach(elm => { - xRight.appendChild(elm as HTMLElement); - }); - } - else { - x.innerHTML = this.sanitizeHtmlString(stringArrayL.join('')); - xRight.innerHTML = this.sanitizeHtmlString(stringArrayR.join('')); - } + stringArrayL.forEach(elm => { + x.appendChild(elm as HTMLElement); + }); + stringArrayR.forEach(elm => { + xRight.appendChild(elm as HTMLElement); + }); for (let i = 0, ii = rows.length; i < ii; i++) { if ((this.hasFrozenRows) && (rows[i] >= this.actualFrozenRow)) { if (this.hasFrozenColumns()) { From 22ad66ab77f002e3fe45c9e69ee56baad5149b8d Mon Sep 17 00:00:00 2001 From: Jesper Jakobsen Date: Mon, 13 Nov 2023 09:48:26 +0100 Subject: [PATCH 12/12] renamed stringArray to divArray --- src/slick.grid.ts | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/slick.grid.ts b/src/slick.grid.ts index 1805ca01f..1cd91f6e7 100644 --- a/src/slick.grid.ts +++ b/src/slick.grid.ts @@ -3785,7 +3785,7 @@ export class SlickGrid = Column, O e return item[columnDef.field as keyof TData]; } - protected appendRowHtml(stringArrayL: HTMLElement[], stringArrayR: HTMLElement[], row: number, range: CellViewportRange, dataLength: number) { + protected appendRowHtml(divArrayL: HTMLElement[], divArrayR: HTMLElement[], row: number, range: CellViewportRange, dataLength: number) { const d = this.getDataItem(row); const dataLoading = row < dataLength && !d; let rowCss = 'slick-row' + @@ -3811,12 +3811,12 @@ export class SlickGrid = Column, O e rowDiv.className = 'ui-widget-content ' + rowCss; rowDiv.style.top = `${(this.getRowTop(row) - frozenRowOffset)}px`; - (stringArrayL as HTMLElement[]).push(rowDiv); + divArrayL.push(rowDiv); if (this.hasFrozenColumns()) { //it has to be a deep copy otherwise we will have issues with pass by reference in js since //attempting to add the same element to 2 different arrays will just move 1 item to the other array rowDivR = rowDiv.cloneNode(true) as HTMLElement; - (stringArrayR as HTMLElement[]).push(rowDivR); + divArrayR.push(rowDivR); } @@ -3858,8 +3858,8 @@ export class SlickGrid = Column, O e } } - protected appendCellHtml(stringArray: HTMLElement, row: number, cell: number, colspan: number, item: TData) { - // stringArray: stringBuilder containing the HTML parts + protected appendCellHtml(divRow: HTMLElement, row: number, cell: number, colspan: number, item: TData) { + // divRow: the html element to append items too // row, cell: row and column index // colspan: HTML colspan // item: grid data for row @@ -3919,7 +3919,7 @@ export class SlickGrid = Column, O e cellDiv.innerHTML = this.sanitizeHtmlString(obj); } - (stringArray as HTMLElement).appendChild(cellDiv); + divRow.appendChild(cellDiv); @@ -4530,7 +4530,7 @@ export class SlickGrid = Column, O e protected cleanUpAndRenderCells(range: CellViewportRange) { let cacheEntry; - const stringArray: HTMLElement = document.createElement('div'); + const divRow: HTMLElement = document.createElement('div'); const processedRows: number[] = []; let cellsAdded: number; let totalCellsAdded = 0; @@ -4580,7 +4580,7 @@ export class SlickGrid = Column, O e } if (this.columnPosRight[Math.min(ii - 1, i + colspan - 1)] > range.leftPx) { - this.appendCellHtml(stringArray, row, i, colspan, d); + this.appendCellHtml(divRow, row, i, colspan, d); cellsAdded++; } @@ -4593,12 +4593,12 @@ export class SlickGrid = Column, O e processedRows.push(row); } } - if (!(stringArray as HTMLElement).children.length) { + if (!divRow.children.length) { return; } const x = document.createElement('div'); - x.innerHTML = this.sanitizeHtmlString(stringArray.outerHTML); + x.innerHTML = this.sanitizeHtmlString(divRow.outerHTML); let processedRow: number | null | undefined; let node: HTMLElement; @@ -4623,8 +4623,8 @@ export class SlickGrid = Column, O e } protected renderRows(range: { top: number; bottom: number; leftPx: number; rightPx: number; }) { - const stringArrayL: HTMLElement[] = []; - const stringArrayR: HTMLElement[] = []; + const divArrayL: HTMLElement[] = []; + const divArrayR: HTMLElement[] = []; const rows: number[] = []; let needToReselectCell = false; const dataLength = this.getDataLength(); @@ -4654,7 +4654,7 @@ export class SlickGrid = Column, O e cellRenderQueue: [] }; - this.appendRowHtml(stringArrayL, stringArrayR, i, range, dataLength); + this.appendRowHtml(divArrayL, divArrayR, i, range, dataLength); if (this.activeCellNode && this.activeRow === i) { needToReselectCell = true; } @@ -4665,10 +4665,10 @@ export class SlickGrid = Column, O e const x = document.createElement('div'); const xRight = document.createElement('div'); - stringArrayL.forEach(elm => { + divArrayL.forEach(elm => { x.appendChild(elm as HTMLElement); }); - stringArrayR.forEach(elm => { + divArrayR.forEach(elm => { xRight.appendChild(elm as HTMLElement); }); for (let i = 0, ii = rows.length; i < ii; i++) {