Dropdown in iframe causes page to freeze in Chrome, Firefox, Safari, and IE11
See original GitHub issueBug description:
Hello! I’ve spent most of an afternoon trying to debug an issue with ng-bootstrap’s dropdown directives. I’m unable to provide a working Stackblitz example because the issue seems to be related to the Angular app being inside of an iframe and Stackblitz doesn’t work in an iframe. (If anyone has an alternative that works in an iframe, please let me know.)
In my app, I have a DomMutationObserver
listening for DOM changes to resize the containing iframe appropriately. I’m not sure if this is the cause of the issue, but loading the page outside of an iframe works fine.
When clicking on a ngbDropdownToggle
, the page stops responding and I get prompted by Chrome, Firefox, Safari, and IE11 to stop a slow script. The behavior happens every time after reloading the page and clicking the dropdown target.
Thinking that the script was struggling to calculate the dropdown menu’s placement, I tried display="static"
as well as placement="bottom"
and any other combinations I could think of.
Markup in question:
<div class="btn-group float-right" ngbDropdown>
<button type="button" class="btn btn-light" id="componentSelectorMenu" ngbDropdownToggle>
Add Component
</button>
<div class="dropdown-menu" aria-labelledby="componentSelectorMenu" ngbDropdownMenu>
<button class="dropdown-item" (click)="handleNewComponentSelection('Item 1')">
Item 1
</button>
<button class="dropdown-item" (click)="handleNewComponentSelection('Item 2')">
Item 2
</button>
<button class="dropdown-item" (click)="handleNewComponentSelection('Item 3')">
Item 3
</button>
</div>
</div>
Firefox reports the below call stack.
Error: Script terminated by timeout at:
__read@http://dev/angular/main.js:124863:53
__spread@http://dev/angular/main.js:124877:24
debugCheckAndUpdateNode@http://dev/angular/main.js:68198:106
debugCheckDirectivesFn@http://dev/angular/main.js:68158:13
View_AppProject/<@ng:///AppModule/AppProject.ngfactory.js:63:5
debugUpdateDirectives@http://dev/angular/main.js:68150:21
checkAndUpdateView@http://dev/angular/main.js:67546:14
callViewAction@http://dev/angular/main.js:67787:21
execEmbeddedViewsAction@http://dev/angular/main.js:67750:17
checkAndUpdateView@http://dev/angular/main.js:67547:5
callViewAction@http://dev/angular/main.js:67787:21
execComponentViewsAction@http://dev/angular/main.js:67729:13
checkAndUpdateView@http://dev/angular/main.js:67552:5
callViewAction@http://dev/angular/main.js:67787:21
execEmbeddedViewsAction@http://dev/angular/main.js:67750:17
checkAndUpdateView@http://dev/angular/main.js:67547:5
callViewAction@http://dev/angular/main.js:67787:21
execEmbeddedViewsAction@http://dev/angular/main.js:67750:17
checkAndUpdateView@http://dev/angular/main.js:67547:5
callViewAction@http://dev/angular/main.js:67787:21
execComponentViewsAction@http://dev/angular/main.js:67729:13
checkAndUpdateView@http://dev/angular/main.js:67552:5
callViewAction@http://dev/angular/main.js:67787:21
execEmbeddedViewsAction@http://dev/angular/main.js:67750:17
checkAndUpdateView@http://dev/angular/main.js:67547:5
callViewAction@http://dev/angular/main.js:67787:21
execComponentViewsAction@http://dev/angular/main.js:67729:13
checkAndUpdateView@http://dev/angular/main.js:67552:5
callWithDebugContext@http://dev/angular/main.js:68416:25
debugCheckAndUpdateView@http://dev/angular/main.js:68118:12
./node_modules/@angular/core/fesm5/core.js/ViewRef_.prototype.detectChanges@http://dev/angular/main.js:58793:22
./node_modules/@angular/core/fesm5/core.js/ApplicationRef.prototype.tick@http://dev/angular/main.js:65216:26
next/<@http://dev/angular/main.js:65105:105
./node_modules/zone.js/dist/zone.js/</Zone$1</ZoneDelegate</ZoneDelegate.prototype.invoke@http://dev/angular/polyfills.js:3406:30
onInvoke@http://dev/angular/main.js:64363:33
./node_modules/zone.js/dist/zone.js/</Zone$1</ZoneDelegate</ZoneDelegate.prototype.invoke@http://dev/angular/polyfills.js:3405:36
./node_modules/zone.js/dist/zone.js/</Zone$1</Zone</Zone.prototype.run@http://dev/angular/polyfills.js:3163:47
./node_modules/@angular/core/fesm5/core.js/NgZone.prototype.run@http://dev/angular/main.js:64277:28
next@http://dev/angular/main.js:65105:81
./node_modules/@angular/core/fesm5/core.js/EventEmitter.prototype.subscribe/schedulerFn<@http://dev/angular/main.js:61842:52
./node_modules/rxjs/_esm5/internal/Subscriber.js/SafeSubscriber.prototype.__tryOrUnsub@http://dev/angular/main.js:113595:16
./node_modules/rxjs/_esm5/internal/Subscriber.js/SafeSubscriber.prototype.next@http://dev/angular/main.js:113533:22
./node_modules/rxjs/_esm5/internal/Subscriber.js/Subscriber.prototype._next@http://dev/angular/main.js:113479:26
./node_modules/rxjs/_esm5/internal/Subscriber.js/Subscriber.prototype.next@http://dev/angular/main.js:113456:18
./node_modules/rxjs/_esm5/internal/Subject.js/Subject.prototype.next@http://dev/angular/main.js:113222:25
./node_modules/@angular/core/fesm5/core.js/EventEmitter.prototype.emit@http://dev/angular/main.js:61826:76
checkStable@http://dev/angular/main.js:64332:35
onLeave@http://dev/angular/main.js:64399:5
onInvoke@http://dev/angular/main.js:64366:17
./node_modules/zone.js/dist/zone.js/</Zone$1</ZoneDelegate</ZoneDelegate.prototype.invoke@http://dev/angular/polyfills.js:3405:36
./node_modules/zone.js/dist/zone.js/</Zone$1</Zone</Zone.prototype.runGuarded@http://dev/angular/polyfills.js:3174:51
./node_modules/zone.js/dist/zone.js/</Zone$1</Zone</Zone.prototype.wrap/<@http://dev/angular/polyfills.js:3157:33
Versions of Angular, ng-bootstrap and Bootstrap:
Angular: 8.2.2
ng-bootstrap: 5.1.0
Bootstrap: 4.3.1
Issue Analytics
- State:
- Created 4 years ago
- Comments:8 (6 by maintainers)
@benouat I don’t think this issue is about iframe, it’s about the infinite change detection loop caused by interaction of ng-bootstrap and the
MutationObserver
. ng-bootstrap updates the DOM, this triggers MutationObserver event, then Zone.js triggers Angular change detection, which triggers dropdown to re-position itself, which updates the DOM… and over and over.Here is the minimal reproduction: https://stackblitz.com/edit/angular-vskkky?file=src/app/app.module.ts
Once you click on the dropdown the page will hang (put a breakpoint in
app.module.ts
on line 21 to prevent page from hanging and observe thatMutationObserver
callback is triggered infinitely with the same values).What may be a potential solution is to not touch DOM if positioning is up to date.
Closing as no response, please reopen if necessary.