Skip to content

Commit

Permalink
fix: allow extra spaces in headerCssClass and other cssClass (#960)
Browse files Browse the repository at this point in the history
* fix: allow extra spaces in headerCssClass and other cssClass

Extra spaces in `class` dom attribute are allowed in html (e.g. `class="some-class  other-class "`). SlickGrid should probably also behave the same way (or at least fail with some meaningfull validation error).

This commit just ignores all extra spaces in headerCssClass (between individual classes or leading / trailing).
  • Loading branch information
jesenko authored and ghiscoding committed Jan 2, 2024
1 parent a132dfe commit dc30aea
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 40 deletions.
13 changes: 6 additions & 7 deletions src/controls/slick.gridmenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ export class SlickGridMenu {
this._buttonElm.ariaLabel = 'Grid Menu';

if (this._gridMenuOptions?.iconCssClass) {
this._buttonElm.classList.add(...this._gridMenuOptions.iconCssClass.split(' '));
this._buttonElm.classList.add(...Utils.classNameToList(this._gridMenuOptions.iconCssClass));
} else {
const iconImageElm = document.createElement('img');
iconImageElm.src = (this._gridMenuOptions?.iconImage) ? this._gridMenuOptions.iconImage : '../images/drag-handle.png';
Expand Down Expand Up @@ -440,7 +440,7 @@ export class SlickGridMenu {
}

if ((item as GridMenuItem).cssClass) {
liElm.classList.add(...(item as GridMenuItem).cssClass!.split(' '));
liElm.classList.add(...Utils.classNameToList((item as GridMenuItem).cssClass));
}

if ((item as GridMenuItem).tooltip) {
Expand All @@ -453,7 +453,7 @@ export class SlickGridMenu {
liElm.appendChild(iconElm);

if ((item as GridMenuItem).iconCssClass) {
iconElm.classList.add(...(item as GridMenuItem).iconCssClass!.split(' '));
iconElm.classList.add(...Utils.classNameToList((item as GridMenuItem).iconCssClass));
}

if ((item as GridMenuItem).iconImage) {
Expand All @@ -467,7 +467,7 @@ export class SlickGridMenu {
liElm.appendChild(textElm);

if ((item as GridMenuItem).textCssClass) {
textElm.classList.add(...(item as GridMenuItem).textCssClass!.split(' '));
textElm.classList.add(...Utils.classNameToList((item as GridMenuItem).textCssClass));
}

commandListElm.appendChild(liElm);
Expand All @@ -493,7 +493,7 @@ export class SlickGridMenu {
const chevronElm = document.createElement('span');
chevronElm.className = 'sub-item-chevron';
if (this._gridMenuOptions?.subItemChevronClass) {
chevronElm.classList.add(...this._gridMenuOptions.subItemChevronClass.split(' '));
chevronElm.classList.add(...Utils.classNameToList(this._gridMenuOptions.subItemChevronClass));
} else {
chevronElm.textContent = '⮞'; // ⮞ or ▸
}
Expand Down Expand Up @@ -776,7 +776,7 @@ export class SlickGridMenu {
subMenuTitleElm.textContent = item.subMenuTitle as string;
const subMenuTitleClass = item.subMenuTitleCssClass as string;
if (subMenuTitleClass) {
subMenuTitleElm.classList.add(...subMenuTitleClass.split(' '));
subMenuTitleElm.classList.add(...Utils.classNameToList(subMenuTitleClass));
}

commandOrOptionMenu.appendChild(subMenuTitleElm);
Expand Down Expand Up @@ -945,4 +945,3 @@ if (IIFE_ONLY && window.Slick) {
window.Slick.Controls = window.Slick.Controls || {};
window.Slick.Controls.GridMenu = SlickGridMenu;
}

10 changes: 5 additions & 5 deletions src/plugins/slick.cellmenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ export class SlickCellMenu implements SlickPlugin {
subMenuTitleElm.textContent = item.subMenuTitle as string;
const subMenuTitleClass = item.subMenuTitleCssClass as string;
if (subMenuTitleClass) {
subMenuTitleElm.classList.add(...subMenuTitleClass.split(' '));
subMenuTitleElm.classList.add(...Utils.classNameToList(subMenuTitleClass));
}

commandOrOptionMenu.appendChild(subMenuTitleElm);
Expand Down Expand Up @@ -676,7 +676,7 @@ export class SlickCellMenu implements SlickPlugin {
}

if ((item as MenuCommandItem | MenuOptionItem).cssClass) {
liElm.classList.add(...(item as MenuCommandItem | MenuOptionItem).cssClass!.split(' '));
liElm.classList.add(...Utils.classNameToList((item as MenuCommandItem | MenuOptionItem).cssClass));
}

if ((item as MenuCommandItem | MenuOptionItem).tooltip) {
Expand All @@ -689,7 +689,7 @@ export class SlickCellMenu implements SlickPlugin {
liElm.appendChild(iconElm);

if ((item as MenuCommandItem | MenuOptionItem).iconCssClass) {
iconElm.classList.add(...(item as MenuCommandItem | MenuOptionItem).iconCssClass!.split(' '));
iconElm.classList.add(...Utils.classNameToList((item as MenuCommandItem | MenuOptionItem).iconCssClass));
}

if ((item as MenuCommandItem | MenuOptionItem).iconImage) {
Expand All @@ -703,7 +703,7 @@ export class SlickCellMenu implements SlickPlugin {
liElm.appendChild(textElm);

if ((item as MenuCommandItem | MenuOptionItem).textCssClass) {
textElm.classList.add(...(item as MenuCommandItem | MenuOptionItem).textCssClass!.split(' '));
textElm.classList.add(...Utils.classNameToList((item as MenuCommandItem | MenuOptionItem).textCssClass));
}

commandOrOptionMenuElm.appendChild(liElm);
Expand All @@ -730,7 +730,7 @@ export class SlickCellMenu implements SlickPlugin {
const chevronElm = document.createElement('span');
chevronElm.className = 'sub-item-chevron';
if (this._cellMenuProperties.subItemChevronClass) {
chevronElm.classList.add(...this._cellMenuProperties.subItemChevronClass.split(' '));
chevronElm.classList.add(...Utils.classNameToList(this._cellMenuProperties.subItemChevronClass));
} else {
chevronElm.textContent = '⮞'; // ⮞ or ▸
}
Expand Down
11 changes: 5 additions & 6 deletions src/plugins/slick.contextmenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ export class SlickContextMenu implements SlickPlugin {
subMenuTitleElm.textContent = item.subMenuTitle as string;
const subMenuTitleClass = item.subMenuTitleCssClass as string;
if (subMenuTitleClass) {
subMenuTitleElm.classList.add(...subMenuTitleClass.split(' '));
subMenuTitleElm.classList.add(...Utils.classNameToList(subMenuTitleClass));
}

commandOrOptionMenu.appendChild(subMenuTitleElm);
Expand Down Expand Up @@ -604,7 +604,7 @@ export class SlickContextMenu implements SlickPlugin {
}

if ((item as MenuCommandItem | MenuOptionItem).cssClass) {
liElm.classList.add(...(item as MenuCommandItem | MenuOptionItem).cssClass!.split(' '));
liElm.classList.add(...Utils.classNameToList((item as MenuCommandItem | MenuOptionItem).cssClass));
}

if ((item as MenuCommandItem | MenuOptionItem).tooltip) {
Expand All @@ -617,7 +617,7 @@ export class SlickContextMenu implements SlickPlugin {
liElm.appendChild(iconElm);

if ((item as MenuCommandItem | MenuOptionItem).iconCssClass) {
iconElm.classList.add(...(item as MenuCommandItem | MenuOptionItem).iconCssClass!.split(' '));
iconElm.classList.add(...Utils.classNameToList((item as MenuCommandItem | MenuOptionItem).iconCssClass));
}

if ((item as MenuCommandItem | MenuOptionItem).iconImage) {
Expand All @@ -631,7 +631,7 @@ export class SlickContextMenu implements SlickPlugin {
liElm.appendChild(textElm);

if ((item as MenuCommandItem | MenuOptionItem).textCssClass) {
textElm.classList.add(...(item as MenuCommandItem | MenuOptionItem).textCssClass!.split(' '));
textElm.classList.add(...Utils.classNameToList((item as MenuCommandItem | MenuOptionItem).textCssClass));
}

commandOrOptionMenuElm.appendChild(liElm);
Expand All @@ -658,7 +658,7 @@ export class SlickContextMenu implements SlickPlugin {
const chevronElm = document.createElement('span');
chevronElm.className = 'sub-item-chevron';
if (this._contextMenuProperties.subItemChevronClass) {
chevronElm.classList.add(...this._contextMenuProperties.subItemChevronClass.split(' '));
chevronElm.classList.add(...Utils.classNameToList(this._contextMenuProperties.subItemChevronClass));
} else {
chevronElm.textContent = '⮞'; // ⮞ or ▸
}
Expand Down Expand Up @@ -837,4 +837,3 @@ if (IIFE_ONLY && window.Slick) {
}
});
}

7 changes: 3 additions & 4 deletions src/plugins/slick.draggablegrouping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ export class SlickDraggableGrouping {
const groupableIconElm = document.createElement('span');
groupableIconElm.className = 'slick-column-groupable';
if (this._options.groupIconCssClass) {
groupableIconElm.classList.add(...this._options.groupIconCssClass.split(' '));
groupableIconElm.classList.add(...Utils.classNameToList(this._options.groupIconCssClass));
}
if (this._options.groupIconImage) {
groupableIconElm.style.background = `url(${this._options.groupIconImage}) no-repeat center center`;
Expand Down Expand Up @@ -356,10 +356,10 @@ export class SlickDraggableGrouping {
const groupRemoveIconElm = document.createElement('div');
groupRemoveIconElm.className = 'slick-groupby-remove';
if (this._options.deleteIconCssClass) {
groupRemoveIconElm.classList.add(...this._options.deleteIconCssClass.split(' '));
groupRemoveIconElm.classList.add(...Utils.classNameToList(this._options.deleteIconCssClass));
}
if (this._options.deleteIconImage) {
groupRemoveIconElm.classList.add(...this._options.deleteIconImage.split(' '));
groupRemoveIconElm.classList.add(...Utils.classNameToList(this._options.deleteIconImage));
}
if (!this._options.deleteIconCssClass) {
groupRemoveIconElm.classList.add('slick-groupby-remove-icon');
Expand Down Expand Up @@ -496,4 +496,3 @@ if (IIFE_ONLY && window.Slick) {
}
});
}

3 changes: 1 addition & 2 deletions src/plugins/slick.headerbuttons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ export class SlickHeaderButtons implements SlickPlugin {
}

if (button.cssClass) {
btn.classList.add(...button.cssClass.split(' '));
btn.classList.add(...Utils.classNameToList(button.cssClass));
}

if (button.tooltip) {
Expand Down Expand Up @@ -244,4 +244,3 @@ if (IIFE_ONLY && window.Slick) {
}
});
}

13 changes: 6 additions & 7 deletions src/plugins/slick.headermenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ export class SlickHeaderMenu implements SlickPlugin {
if (this._options.buttonCssClass) {
// sgi icon with mask requires inner span to work properly
const icon = document.createElement('span');
icon.classList.add(...this._options.buttonCssClass.split(' '));
icon.classList.add(...Utils.classNameToList(this._options.buttonCssClass));
elm.appendChild(icon);
}

Expand Down Expand Up @@ -277,7 +277,7 @@ export class SlickHeaderMenu implements SlickPlugin {
subMenuTitleElm.textContent = item.subMenuTitle as string;
const subMenuTitleClass = item.subMenuTitleCssClass as string;
if (subMenuTitleClass) {
subMenuTitleElm.classList.add(...subMenuTitleClass.split(' '));
subMenuTitleElm.classList.add(...Utils.classNameToList(subMenuTitleClass));
}

commandMenuElm.appendChild(subMenuTitleElm);
Expand Down Expand Up @@ -400,7 +400,7 @@ export class SlickHeaderMenu implements SlickPlugin {
}

if ((item as HeaderMenuCommandItem).cssClass) {
menuItemElm.classList.add(...(item as HeaderMenuCommandItem).cssClass!.split(' '));
menuItemElm.classList.add(...Utils.classNameToList((item as HeaderMenuCommandItem).cssClass));
}

if ((item as HeaderMenuCommandItem).tooltip) {
Expand All @@ -412,7 +412,7 @@ export class SlickHeaderMenu implements SlickPlugin {
menuItemElm.appendChild(iconElm);

if ((item as HeaderMenuCommandItem).iconCssClass) {
iconElm.classList.add(...(item as HeaderMenuCommandItem).iconCssClass!.split(' '));
iconElm.classList.add(...Utils.classNameToList((item as HeaderMenuCommandItem).iconCssClass));
}

if ((item as HeaderMenuCommandItem).iconImage) {
Expand All @@ -425,7 +425,7 @@ export class SlickHeaderMenu implements SlickPlugin {
menuItemElm.appendChild(textElm);

if ((item as HeaderMenuCommandItem).textCssClass) {
textElm.classList.add(...(item as HeaderMenuCommandItem).textCssClass!.split(' '));
textElm.classList.add(...Utils.classNameToList((item as HeaderMenuCommandItem).textCssClass));
}
menuElm.appendChild(menuItemElm);

Expand All @@ -450,7 +450,7 @@ export class SlickHeaderMenu implements SlickPlugin {
const chevronElm = document.createElement('div');
chevronElm.className = 'sub-item-chevron';
if (this._options.subItemChevronClass) {
chevronElm.classList.add(...this._options.subItemChevronClass.split(' '));
chevronElm.classList.add(...Utils.classNameToList(this._options.subItemChevronClass));
} else {
chevronElm.textContent = '⮞'; // ⮞ or ▸
}
Expand Down Expand Up @@ -585,4 +585,3 @@ if (IIFE_ONLY && window.Slick) {
}
});
}

11 changes: 11 additions & 0 deletions src/slick.core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,17 @@ export class Utils {
return element;
}

/**
* Accepts string containing the class or space-separated list of classes, and
* returns list of individual classes.
* Method properly takes into account extra whitespaces in the `className`
* (e.g. ' class1 class2') will result in `['class1', 'class2']`.
* @param {String} className - space separated list of classes
*/
public static classNameToList(className = ''): string[] {
return className.split(' ').filter(cls => cls);
}

public static innerSize(elm: HTMLElement, type: 'height' | 'width') {
let size = 0;

Expand Down
19 changes: 10 additions & 9 deletions src/slick.grid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -766,7 +766,7 @@ export class SlickGrid<TData = any, C extends Column<TData> = Column<TData>, O e
this._viewport = [this._viewportTopL, this._viewportTopR, this._viewportBottomL, this._viewportBottomR];
if (this._options.viewportClass) {
this._viewport.forEach((view) => {
view.classList.add(...(this._options.viewportClass || '').split(' '));
view.classList.add(...Utils.classNameToList((this._options.viewportClass)));
});
}

Expand Down Expand Up @@ -1623,7 +1623,7 @@ export class SlickGrid<TData = any, C extends Column<TData> = Column<TData>, O e

let classname = m.headerCssClass || null;
if (classname) {
header.classList.add(...classname.split(' '));
header.classList.add(...Utils.classNameToList(classname));
}
classname = this.hasFrozenColumns() && i <= this._options.frozenColumn! ? 'frozen' : null;
if (classname) {
Expand Down Expand Up @@ -2311,10 +2311,11 @@ export class SlickGrid<TData = any, C extends Column<TData> = Column<TData>, O e
this._viewportBottomR.style.overflowY = this._options.alwaysShowVerticalScroll ? 'scroll' : ((this.hasFrozenColumns()) ? (this.hasFrozenRows ? 'auto' : 'auto') : (this.hasFrozenRows ? 'auto' : 'auto'));

if (this._options.viewportClass) {
this._viewportTopL.classList.add(...this._options.viewportClass.split(' '));
this._viewportTopR.classList.add(...this._options.viewportClass.split(' '));
this._viewportBottomL.classList.add(...this._options.viewportClass.split(' '));
this._viewportBottomR.classList.add(...this._options.viewportClass.split(' '));
const viewportClassList = Utils.classNameToList(this._options.viewportClass);
this._viewportTopL.classList.add(...viewportClassList);
this._viewportTopR.classList.add(...viewportClassList);
this._viewportBottomL.classList.add(...viewportClassList);
this._viewportBottomR.classList.add(...viewportClassList);
}
}

Expand Down Expand Up @@ -3147,7 +3148,7 @@ export class SlickGrid<TData = any, C extends Column<TData> = Column<TData>, O e
this.applyHtmlCode(colNameElm, columnDef.name!);
clone.style.cssText = 'position: absolute; visibility: hidden;right: auto;text-overflow: initial;white-space: nowrap;';
if (columnDef.headerCssClass) {
headerColEl.classList.add(...(columnDef.headerCssClass || '').split(' '));
headerColEl.classList.add(...Utils.classNameToList(columnDef.headerCssClass));
}
width = headerColEl.offsetWidth;
header.removeChild(headerColEl);
Expand Down Expand Up @@ -4168,11 +4169,11 @@ export class SlickGrid<TData = any, C extends Column<TData> = Column<TData>, O e
this.applyHtmlCode(cellNode, formatterVal);

if ((formatterResult as FormatterResultObject).removeClasses && !suppressRemove) {
const classes = (formatterResult as FormatterResultObject).removeClasses!.split(' ');
const classes = Utils.classNameToList((formatterResult as FormatterResultObject).removeClasses);
classes.forEach((c) => cellNode.classList.remove(c));
}
if ((formatterResult as FormatterResultObject).addClasses) {
const classes = (formatterResult as FormatterResultObject).addClasses!.split(' ');
const classes = Utils.classNameToList((formatterResult as FormatterResultObject).addClasses);
classes.forEach((c) => cellNode.classList.add(c));
}
if ((formatterResult as FormatterResultObject).toolTip) {
Expand Down

0 comments on commit dc30aea

Please sign in to comment.