Skip to content
This repository was archived by the owner on Jun 1, 2025. It is now read-only.

Commit d9a0a4e

Browse files
committed
chore: merge master branch
2 parents caececa + e221a16 commit d9a0a4e

File tree

9 files changed

+206
-92
lines changed

9 files changed

+206
-92
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
# Change Log
22
All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
33

4+
## [8.13.1](https://github.com/ghiscoding/angular-slickgrid/compare/v8.13.0...v8.13.1) (2025-03-01)
5+
6+
### Bug Fixes
7+
8+
* add sanitizer to Row Detail create dynamic component ([363065a](https://github.com/ghiscoding/angular-slickgrid/commit/363065ad66dc12da0d082e4ceb6cae99ddd1b99d))
9+
* **deps:** update all non-major dependencies ([f276e6b](https://github.com/ghiscoding/angular-slickgrid/commit/f276e6b16adabc62559432891785a9d4da007b35))
10+
* Row Detail preload comp should call destroy lifecycle ([fd0185e](https://github.com/ghiscoding/angular-slickgrid/commit/fd0185edd1e4abd6f5115fed38f79945dcd6569e))
11+
* Row Detail with inner grids ([193b366](https://github.com/ghiscoding/angular-slickgrid/commit/193b3664f5fdfa84bb7c28314d5229e40223b550))
12+
413
## [8.13.0](https://github.com/ghiscoding/angular-slickgrid/compare/v8.12.1...v8.13.0) (2025-02-08)
514

615
### Features

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ npm start
100100
### Like it? ⭐ it
101101
You like to use **Angular-Slickgrid**? Be sure to upvote ⭐ and perhaps support me with caffeine [](https://ko-fi.com/ghiscoding) or GitHub sponsoring and feel free to contribute.
102102

103-
<a href='https://ko-fi.com/N4N679OT' target='_blank'><img height='36' style='border:0px;height:36px;' src='https://storage.ko-fi.com/cdn/kofi3.png?v=6' border='0' alt='Buy Me a Coffee at ko-fi.com' /></a>
103+
<a href='https://ko-fi.com/ghiscoding' target='_blank'><img height='36' style='border:0px;height:36px;' src='https://storage.ko-fi.com/cdn/kofi3.png?v=6' border='0' alt='Buy Me a Coffee at ko-fi.com' /></a>
104104

105105
### Contributions
106106
If you wish to contribute, please make sure to follow the steps shown in the [CONTRIBUTING](https://github.com/ghiscoding/Angular-Slickgrid/blob/master/CONTRIBUTING.md) guide.

docs/events/Available-Events.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ handleOnHeaderMenuCommand(e) {
165165
- `onBeforeFooterRowCellDestroy`
166166
- `onBeforeHeaderCellDestroy`
167167
- `onBeforeHeaderRowCellDestroy`
168+
- `onBeforeRemoveCachedRow`
168169
- `onBeforeSetColumns`
169170
- `onBeforeSort`
170171
- `onBeforeUpdateColumns`

package.json

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "angular-slickgrid",
3-
"version": "8.13.0",
3+
"version": "8.13.1",
44
"description": "Slickgrid components made available in Angular",
55
"keywords": [
66
"angular",
@@ -61,7 +61,7 @@
6161
"@slickgrid-universal/row-detail-view-plugin": "~5.13.0",
6262
"@slickgrid-universal/rxjs-observable": "~5.13.0",
6363
"dequal": "^2.0.3",
64-
"rxjs": "^7.8.1"
64+
"rxjs": "^7.8.2"
6565
},
6666
"peerDependencies": {
6767
"@angular/core": ">=18.0.0"
@@ -85,7 +85,7 @@
8585
"@angular/platform-browser": "^18.2.13",
8686
"@angular/platform-browser-dynamic": "^18.2.13",
8787
"@angular/router": "^18.2.13",
88-
"@faker-js/faker": "^9.4.0",
88+
"@faker-js/faker": "^9.5.1",
8989
"@fnando/sparkline": "^0.3.10",
9090
"@formkit/tempo": "^0.1.2",
9191
"@ng-select/ng-select": "^13.9.1",
@@ -100,47 +100,47 @@
100100
"@slickgrid-universal/text-export": "~5.13.0",
101101
"@types/fnando__sparkline": "^0.3.7",
102102
"@types/jest": "^29.5.14",
103-
"@types/node": "^22.13.1",
103+
"@types/node": "^22.13.8",
104104
"@types/sortablejs": "^1.15.8",
105105
"angular-eslint": "^18.4.3",
106106
"bootstrap": "^5.3.3",
107107
"custom-event-polyfill": "^1.0.7",
108-
"cypress": "^14.0.2",
108+
"cypress": "^14.1.0",
109109
"cypress-real-events": "^1.14.0",
110110
"dompurify": "^3.2.4",
111-
"eslint": "^9.20.0",
111+
"eslint": "^9.21.0",
112112
"eslint-plugin-cypress": "^4.1.0",
113113
"eslint-plugin-n": "^17.15.1",
114114
"jest": "^29.7.0",
115115
"jest-extended": "^4.0.2",
116-
"jest-preset-angular": "^14.5.1",
116+
"jest-preset-angular": "^14.5.3",
117117
"native-copyfiles": "^0.3.2",
118118
"ng-packagr": "^18.2.1",
119119
"ngx-bootstrap": "^18.1.3",
120120
"npm-run-all2": "^7.0.2",
121-
"prettier": "^3.4.2",
121+
"prettier": "^3.5.2",
122122
"release-it": "^19.0.0-next.0",
123123
"rimraf": "^5.0.10",
124-
"rxjs": "^7.8.1",
125-
"sass": "^1.84.0",
124+
"rxjs": "^7.8.2",
125+
"sass": "^1.85.1",
126126
"servor": "^4.0.2",
127127
"sortablejs": "^1.15.6",
128128
"stream-browserify": "^3.0.0",
129129
"ts-node": "^10.9.2",
130130
"tslib": "^2.8.1",
131131
"typescript": "~5.5.4",
132-
"typescript-eslint": "^8.23.0",
132+
"typescript-eslint": "^8.25.0",
133133
"zone.js": "~0.15.0"
134134
},
135135
"engines": {
136136
"node": ">=18.19.1"
137137
},
138138
"resolutions": {
139-
"caniuse-lite": "1.0.30001695",
139+
"caniuse-lite": "1.0.30001701",
140140
"express": "^4.21.2",
141-
"semver": "^7.6.3",
141+
"semver": "^7.7.1",
142142
"string-width": "4.2.3",
143143
"wrap-ansi": "7.0.0",
144-
"ws": "^8.18.0"
144+
"ws": "^8.18.1"
145145
}
146146
}

src/app/modules/angular-slickgrid/extensions/__tests__/slickRowDetailView.spec.ts

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -432,13 +432,18 @@ describe('SlickRowDetailView', () => {
432432
plugin.register();
433433
plugin.eventHandler.subscribe(plugin.onBeforeRowDetailToggle, () => {
434434
gridStub.onColumnsReordered.notify({ impactedColumns: [mockColumn] } as any, new SlickEventData(), gridStub);
435-
expect(appendSpy).toHaveBeenCalledWith(TestComponent, expect.objectContaining({ className: 'container_field1' }), {
436-
model: mockColumn,
437-
addon: expect.anything(),
438-
grid: gridStub,
439-
dataView: dataViewStub,
440-
parent: undefined,
441-
});
435+
expect(appendSpy).toHaveBeenCalledWith(
436+
TestComponent,
437+
expect.objectContaining({ className: 'container_field1' }),
438+
{
439+
model: mockColumn,
440+
addon: expect.anything(),
441+
grid: gridStub,
442+
dataView: undefined,
443+
parent: undefined,
444+
},
445+
{ sanitizer: expect.any(Function) }
446+
);
442447
done();
443448
});
444449
plugin.onBeforeRowDetailToggle.notify({ item: mockColumn, grid: gridStub }, new SlickEventData(), gridStub);
@@ -464,13 +469,18 @@ describe('SlickRowDetailView', () => {
464469
new SlickEventData(),
465470
gridStub
466471
);
467-
expect(appendSpy).toHaveBeenCalledWith(TestComponent, expect.objectContaining({ className: 'container_field1' }), {
468-
model: mockColumn,
469-
addon: expect.anything(),
470-
grid: gridStub,
471-
dataView: dataViewStub,
472-
parent: undefined,
473-
});
472+
expect(appendSpy).toHaveBeenCalledWith(
473+
TestComponent,
474+
expect.objectContaining({ className: 'container_field1' }),
475+
{
476+
model: mockColumn,
477+
addon: expect.anything(),
478+
grid: gridStub,
479+
dataView: undefined,
480+
parent: undefined,
481+
},
482+
{ sanitizer: expect.any(Function) }
483+
);
474484
});
475485
plugin.onBeforeRowDetailToggle.notify({ item: mockColumn, grid: gridStub }, new SlickEventData(), gridStub);
476486
plugin.onBeforeRowDetailToggle.notify({ item: { ...mockColumn, __collapsed: false }, grid: gridStub }, new SlickEventData(), gridStub);
@@ -494,13 +504,18 @@ describe('SlickRowDetailView', () => {
494504

495505
plugin.eventHandler.subscribe(plugin.onBeforeRowDetailToggle, () => {
496506
eventPubSubService.publish(eventName, { columnId: 'field1', operator: '=', searchTerms: [] });
497-
expect(appendSpy).toHaveBeenCalledWith(TestComponent, expect.objectContaining({ className: 'container_field1' }), {
498-
model: mockColumn,
499-
addon: expect.anything(),
500-
grid: gridStub,
501-
dataView: dataViewStub,
502-
parent: undefined,
503-
});
507+
expect(appendSpy).toHaveBeenCalledWith(
508+
TestComponent,
509+
expect.objectContaining({ className: 'container_field1' }),
510+
{
511+
model: mockColumn,
512+
addon: expect.anything(),
513+
grid: gridStub,
514+
dataView: undefined,
515+
parent: undefined,
516+
},
517+
{ sanitizer: expect.any(Function) }
518+
);
504519
});
505520
plugin.onBeforeRowDetailToggle.notify({ item: mockColumn, grid: gridStub }, new SlickEventData(), gridStub);
506521
plugin.onBeforeRowDetailToggle.notify({ item: { ...mockColumn, __collapsed: false }, grid: gridStub }, new SlickEventData(), gridStub);

src/app/modules/angular-slickgrid/extensions/slickRowDetailView.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,9 @@ export class SlickRowDetailView extends UniversalSlickRowDetailView {
260260
if (this._preloadComponent && containerElements?.length >= 0) {
261261
const preloadComp = this.angularUtilService.createAngularComponentAppendToDom(
262262
this._preloadComponent,
263-
containerElements[containerElements.length - 1]
263+
containerElements[containerElements.length - 1],
264+
{},
265+
{ sanitizer: this._grid.sanitizeHtmlString }
264266
);
265267
this._preloadCompRef = preloadComp.componentRef;
266268
}
@@ -283,6 +285,9 @@ export class SlickRowDetailView extends UniversalSlickRowDetailView {
283285
grid: this._grid,
284286
dataView: this.dataView,
285287
parent: this.rowDetailViewOptions?.parent,
288+
},
289+
{
290+
sanitizer: this._grid.sanitizeHtmlString,
286291
}
287292
);
288293
if (componentOutput?.componentRef) {

src/app/modules/angular-slickgrid/services/__tests__/angularUtilService.spec.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,23 @@ describe('AngularUtilService', () => {
7979
expect(output).toEqual({ componentRef: mockComponentFactory, domElement: h1Mock });
8080
});
8181

82+
it('should create an Angular Component with optional target element and extra data and sanitizer', () => {
83+
const titleMock = 'Some Title';
84+
const h1Mock = document.createElement('h1');
85+
h1Mock.textContent = titleMock;
86+
mockComponentFactory.hostView.rootNodes[0] = h1Mock;
87+
const sanitizerMock = jest.fn().mockReturnValue(titleMock);
88+
89+
// @ts-ignore
90+
const createCompSpy = jest.spyOn(viewContainerRefStub, 'createComponent').mockReturnValue(mockComponentFactory);
91+
const output = service.createAngularComponent(TestComponent, domParentElm, { title: titleMock }, { sanitizer: sanitizerMock });
92+
93+
expect(sanitizerMock).toHaveBeenCalled();
94+
expect(createCompSpy).toHaveBeenCalled();
95+
expect(domParentElm.innerHTML).toBe('Some Title');
96+
expect(output).toEqual({ componentRef: mockComponentFactory, domElement: h1Mock });
97+
});
98+
8299
it('should create an Interactive Angular Component with target element and extra data to provide to the component instance', () => {
83100
const titleMock = 'Some Title';
84101
const h1Mock = document.createElement('h1');

src/app/modules/angular-slickgrid/services/angularUtil.service.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ interface CreateComponentOption {
99
ngModuleRef?: NgModuleRef<unknown>;
1010
environmentInjector?: EnvironmentInjector | NgModuleRef<unknown>;
1111
projectableNodes?: Node[][];
12+
sanitizer?: (dirtyHtml: string) => string;
1213
}
1314

1415
@Injectable()
@@ -82,7 +83,10 @@ export class AngularUtilService {
8283

8384
// when user provides the DOM element target, we will read the new Component html and use it to replace the target html
8485
if (targetElement && domElem) {
85-
targetElement.innerHTML = domElem.innerHTML;
86+
targetElement.innerHTML =
87+
typeof createCompOptions?.sanitizer === 'function'
88+
? createCompOptions.sanitizer(domElem.innerHTML || '')
89+
: domElem.innerHTML;
8690
}
8791
}
8892

0 commit comments

Comments
 (0)