From 7ac58bec8abb7c5a9ac907f7632395e57c4f851d Mon Sep 17 00:00:00 2001 From: Kara Erickson Date: Fri, 1 Mar 2019 13:45:02 -0800 Subject: [PATCH] fix(ivy): move views that are already attached in insert() (#29047) Currently if a user accidentally calls ViewContainerRef.insert() with a view that has already been attached, we do not clean up the references properly, so we create a view tree with a cycle. This causes an infinite loop when the view is destroyed. This PR ensures that we fall back to ViewContainerRef.move() behavior if we try to insert a view that is already attached. This fixes the cycle and honors the user intention. PR Close #29047 --- packages/core/src/render3/instructions.ts | 10 +- .../core/src/render3/node_manipulation.ts | 1 + packages/core/src/render3/util/view_utils.ts | 17 +- .../src/render3/view_engine_compatibility.ts | 14 +- .../acceptance/view_container_ref_spec.ts | 107 +++++++ .../cyclic_import/bundle.golden_symbols.json | 2 +- .../hello_world/bundle.golden_symbols.json | 2 +- .../bundling/todo/bundle.golden_symbols.json | 5 +- .../angular_material_test_blocklist.js | 302 +----------------- 9 files changed, 148 insertions(+), 312 deletions(-) create mode 100644 packages/core/test/acceptance/view_container_ref_spec.ts diff --git a/packages/core/src/render3/instructions.ts b/packages/core/src/render3/instructions.ts index 84096f83c7..5e34be0df7 100644 --- a/packages/core/src/render3/instructions.ts +++ b/packages/core/src/render3/instructions.ts @@ -47,7 +47,7 @@ import {ANIMATION_PROP_PREFIX, allocateDirectiveIntoContext, createEmptyStylingC import {NO_CHANGE} from './tokens'; import {INTERPOLATION_DELIMITER, renderStringify} from './util/misc_utils'; import {findComponentView, getLViewParent, getRootContext, getRootView} from './util/view_traversal_utils'; -import {getComponentViewByIndex, getNativeByIndex, getNativeByTNode, getTNode, isComponent, isComponentDef, isContentQueryHost, isRootView, loadInternal, readPatchedLView, unwrapRNode} from './util/view_utils'; +import {getComponentViewByIndex, getNativeByIndex, getNativeByTNode, getTNode, isComponent, isComponentDef, isContentQueryHost, isRootView, loadInternal, readPatchedLView, unwrapRNode, viewAttachedToChangeDetector} from './util/view_utils'; @@ -2531,7 +2531,8 @@ export function componentRefresh(adjustedElementIndex: number): void { ngDevMode && assertNodeType(lView[TVIEW].data[adjustedElementIndex] as TNode, TNodeType.Element); // Only attached CheckAlways components or attached, dirty OnPush components should be checked - if (viewAttached(hostView) && hostView[FLAGS] & (LViewFlags.CheckAlways | LViewFlags.Dirty)) { + if (viewAttachedToChangeDetector(hostView) && + hostView[FLAGS] & (LViewFlags.CheckAlways | LViewFlags.Dirty)) { syncViewWithBlueprint(hostView); checkView(hostView, hostView[CONTEXT]); } @@ -2570,11 +2571,6 @@ function syncViewWithBlueprint(componentView: LView) { } } -/** Returns a boolean for whether the view is attached */ -export function viewAttached(view: LView): boolean { - return (view[FLAGS] & LViewFlags.Attached) === LViewFlags.Attached; -} - /** * Instruction to distribute projectable nodes among occurrences in a given template. * It takes all the selectors from the entire component's template and decides where diff --git a/packages/core/src/render3/node_manipulation.ts b/packages/core/src/render3/node_manipulation.ts index c5600d404d..78c1a6da82 100644 --- a/packages/core/src/render3/node_manipulation.ts +++ b/packages/core/src/render3/node_manipulation.ts @@ -354,6 +354,7 @@ export function detachView(lContainer: LContainer, removeIndex: number): LView { viewToDetach[QUERIES] !.removeView(); } viewToDetach[PARENT] = null; + viewToDetach[NEXT] = null; // Unsets the attached flag viewToDetach[FLAGS] &= ~LViewFlags.Attached; return viewToDetach; diff --git a/packages/core/src/render3/util/view_utils.ts b/packages/core/src/render3/util/view_utils.ts index 4c6a155fc2..36ecc7f11e 100644 --- a/packages/core/src/render3/util/view_utils.ts +++ b/packages/core/src/render3/util/view_utils.ts @@ -13,7 +13,7 @@ import {ComponentDef, DirectiveDef} from '../interfaces/definition'; import {TNode, TNodeFlags} from '../interfaces/node'; import {RNode} from '../interfaces/renderer'; import {StylingContext} from '../interfaces/styling'; -import {FLAGS, HEADER_OFFSET, HOST, LView, LViewFlags, TData, TVIEW} from '../interfaces/view'; +import {FLAGS, HEADER_OFFSET, HOST, LView, LViewFlags, PARENT, TData, TVIEW} from '../interfaces/view'; @@ -182,3 +182,18 @@ export function readPatchedLView(target: any): LView|null { } return null; } + +/** + * Returns a boolean for whether the view is attached to the change detection tree. + * + * Note: This determines whether a view should be checked, not whether it's inserted + * into a container. For that, you'll want `viewAttachedToContainer` below. + */ +export function viewAttachedToChangeDetector(view: LView): boolean { + return (view[FLAGS] & LViewFlags.Attached) === LViewFlags.Attached; +} + +/** Returns a boolean for whether the view is attached to a container. */ +export function viewAttachedToContainer(view: LView): boolean { + return isLContainer(view[PARENT]); +} diff --git a/packages/core/src/render3/view_engine_compatibility.ts b/packages/core/src/render3/view_engine_compatibility.ts index 04c6848b60..41b7321603 100644 --- a/packages/core/src/render3/view_engine_compatibility.ts +++ b/packages/core/src/render3/view_engine_compatibility.ts @@ -22,14 +22,14 @@ import {addToViewTree, createEmbeddedViewAndNode, createLContainer, renderEmbedd import {ACTIVE_INDEX, LContainer, NATIVE, VIEWS} from './interfaces/container'; import {TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeType, TViewNode} from './interfaces/node'; import {RComment, RElement, isProceduralRenderer} from './interfaces/renderer'; -import {CONTEXT, LView, QUERIES, RENDERER, TView, T_HOST} from './interfaces/view'; +import {CONTEXT, FLAGS, LView, LViewFlags, PARENT, QUERIES, RENDERER, TView, T_HOST} from './interfaces/view'; import {assertNodeOfPossibleTypes} from './node_assert'; import {addRemoveViewFromContainer, appendChild, detachView, getBeforeNodeForView, insertView, nativeInsertBefore, nativeNextSibling, nativeParentNode, removeView} from './node_manipulation'; import {getParentInjectorTNode} from './node_util'; import {getLView, getPreviousOrParentTNode} from './state'; import {getParentInjectorView, hasParentInjector} from './util/injector_utils'; import {findComponentView} from './util/view_traversal_utils'; -import {getComponentViewByIndex, getNativeByTNode, isComponent, isLContainer, isRootView} from './util/view_utils'; +import {getComponentViewByIndex, getNativeByTNode, isComponent, isLContainer, isRootView, viewAttachedToChangeDetector, viewAttachedToContainer} from './util/view_utils'; import {ViewRef} from './view_ref'; @@ -236,6 +236,12 @@ export function createContainerRef( const lView = (viewRef as ViewRef)._lView !; const adjustedIdx = this._adjustIndex(index); + if (viewAttachedToContainer(lView)) { + // If view is already attached, fall back to move() so we clean up + // references appropriately. + return this.move(viewRef, adjustedIdx); + } + insertView(lView, this._lContainer, adjustedIdx); const beforeNode = @@ -253,8 +259,8 @@ export function createContainerRef( throw new Error('Cannot move a destroyed View in a ViewContainer!'); } const index = this.indexOf(viewRef); - this.detach(index); - this.insert(viewRef, this._adjustIndex(newIndex)); + if (index !== -1) this.detach(index); + this.insert(viewRef, newIndex); return viewRef; } diff --git a/packages/core/test/acceptance/view_container_ref_spec.ts b/packages/core/test/acceptance/view_container_ref_spec.ts new file mode 100644 index 0000000000..cc5b963612 --- /dev/null +++ b/packages/core/test/acceptance/view_container_ref_spec.ts @@ -0,0 +1,107 @@ +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +import {Component, QueryList, TemplateRef, ViewChild, ViewChildren, ViewContainerRef} from '@angular/core'; +import {TestBed} from '@angular/core/testing'; +import {expect} from '@angular/platform-browser/testing/src/matchers'; +import {ivyEnabled, onlyInIvy} from '@angular/private/testing'; + +describe('ViewContainerRef', () => { + + beforeEach(() => { + TestBed.configureTestingModule({declarations: [ViewContainerRefComp, ViewContainerRefApp]}); + }); + + describe('insert', () => { + it('should not blow up on destroy when inserting a view that is already attached', () => { + const fixture = TestBed.createComponent(ViewContainerRefApp); + fixture.detectChanges(); + + const template0 = fixture.componentInstance.vcrComp.templates.first; + const viewContainerRef = fixture.componentInstance.vcrComp.vcr; + const ref0 = viewContainerRef.createEmbeddedView(template0); + + // Insert the view again at the same index + viewContainerRef.insert(ref0, 0); + + expect(() => { fixture.destroy(); }).not.toThrow(); + + expect(fixture.nativeElement.textContent).toEqual('0'); + }); + + it('should move views if they are already attached', () => { + const fixture = TestBed.createComponent(ViewContainerRefApp); + fixture.detectChanges(); + + const templates = fixture.componentInstance.vcrComp.templates.toArray(); + const viewContainerRef = fixture.componentInstance.vcrComp.vcr; + const ref0 = viewContainerRef.createEmbeddedView(templates[0]); + const ref1 = viewContainerRef.createEmbeddedView(templates[1]); + const ref2 = viewContainerRef.createEmbeddedView(templates[2]); + fixture.detectChanges(); + + expect(fixture.nativeElement.textContent).toEqual('012'); + + // Insert the view again at a different index + viewContainerRef.insert(ref0, 2); + fixture.detectChanges(); + + // In Ivy, we correctly move the "0" view to index 2. VE + // has a bug that duplicates the view, so it's at index 1. + if (ivyEnabled) { + expect(fixture.nativeElement.textContent).toEqual('120'); + } else { + expect(fixture.nativeElement.textContent).toEqual('102'); + } + }); + }); + + describe('move', () => { + onlyInIvy('Ivy will insert detached views in move') + .it('should insert detached views in move()', () => { + const fixture = TestBed.createComponent(ViewContainerRefApp); + fixture.detectChanges(); + + const templates = fixture.componentInstance.vcrComp.templates.toArray(); + const viewContainerRef = fixture.componentInstance.vcrComp.vcr; + const ref0 = viewContainerRef.createEmbeddedView(templates[0]); + const ref1 = viewContainerRef.createEmbeddedView(templates[1]); + const ref2 = viewContainerRef.createEmbeddedView(templates[2]); + + viewContainerRef.detach(0); + viewContainerRef.move(ref0, 0); + + expect(fixture.nativeElement.textContent).toEqual('012'); + }); + }); + +}); + +@Component({ + selector: 'view-container-ref-comp', + template: ` + 0 + 1 + 2 + ` +}) +class ViewContainerRefComp { + @ViewChildren(TemplateRef) templates !: QueryList>; + + constructor(public vcr: ViewContainerRef) {} +} + +@Component({ + selector: 'view-container-ref-app', + template: ` + + ` +}) +class ViewContainerRefApp { + @ViewChild(ViewContainerRefComp) vcrComp !: ViewContainerRefComp; +} diff --git a/packages/core/test/bundling/cyclic_import/bundle.golden_symbols.json b/packages/core/test/bundling/cyclic_import/bundle.golden_symbols.json index bff0cb4f66..10ee5080db 100644 --- a/packages/core/test/bundling/cyclic_import/bundle.golden_symbols.json +++ b/packages/core/test/bundling/cyclic_import/bundle.golden_symbols.json @@ -654,6 +654,6 @@ "name": "unwrapRNode" }, { - "name": "viewAttached" + "name": "viewAttachedToChangeDetector" } ] \ No newline at end of file diff --git a/packages/core/test/bundling/hello_world/bundle.golden_symbols.json b/packages/core/test/bundling/hello_world/bundle.golden_symbols.json index a1a9302bfd..353e2ea179 100644 --- a/packages/core/test/bundling/hello_world/bundle.golden_symbols.json +++ b/packages/core/test/bundling/hello_world/bundle.golden_symbols.json @@ -474,6 +474,6 @@ "name": "unwrapRNode" }, { - "name": "viewAttached" + "name": "viewAttachedToChangeDetector" } ] \ No newline at end of file diff --git a/packages/core/test/bundling/todo/bundle.golden_symbols.json b/packages/core/test/bundling/todo/bundle.golden_symbols.json index fd7839f54e..c8b4beddd7 100644 --- a/packages/core/test/bundling/todo/bundle.golden_symbols.json +++ b/packages/core/test/bundling/todo/bundle.golden_symbols.json @@ -1296,7 +1296,10 @@ "name": "valueExists" }, { - "name": "viewAttached" + "name": "viewAttachedToChangeDetector" + }, + { + "name": "viewAttachedToContainer" }, { "name": "walkTNodeTree" diff --git a/tools/material-ci/angular_material_test_blocklist.js b/tools/material-ci/angular_material_test_blocklist.js index 0b81814cc7..7df0187add 100644 --- a/tools/material-ci/angular_material_test_blocklist.js +++ b/tools/material-ci/angular_material_test_blocklist.js @@ -25,218 +25,6 @@ window.testBlocklist = { "error": "Error: Expected '

Pizza

Chocolate

' to be '', 'Expected the DomPortalOutlet to be empty after detach'.", "notes": "Unknown" }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should render initial state": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should get the data length": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should get the viewport size": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should update viewport size": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should get the rendered range": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should get the rendered content offset": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should get the scroll offset": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should get the rendered content size": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should measure range size": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should set total content size": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should set total content size in horizontal mode": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should set a class based on the orientation": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should set the vertical class if an invalid orientation is set": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should set rendered range": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should set content offset to top of content": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should set content offset to bottom of content": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should scroll to offset": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should scroll to index": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should scroll to offset in horizontal mode": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should scroll to index in horizontal mode": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should output scrolled index": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should update viewport as user scrolls down": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should update viewport as user scrolls up": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should render buffer element at the end when scrolled to the top": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should render buffer element at the start and end when scrolled to the middle": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should render buffer element at the start when scrolled to the bottom": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should handle dynamic item size": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should handle dynamic buffer size": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should handle dynamic item array": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should update viewport as user scrolls right in horizontal mode": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should update viewport as user scrolls left in horizontal mode": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should work with an Observable": { - "error": "TypeError: Cannot read property 'getRenderedRange' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should work with a DataSource": { - "error": "TypeError: Cannot read property 'getRenderedRange' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should trackBy value by default": { - "error": "Error: : could not find an object to spy upon for detach()", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should trackBy index when specified": { - "error": "Error: : could not find an object to spy upon for detach()", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should recycle views when template cache is large enough to accommodate": { - "error": "Error: : could not find an object to spy upon for createEmbeddedView()", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should not recycle views when template cache is full": { - "error": "Error: : could not find an object to spy upon for createEmbeddedView()", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should render up to maxBufferPx when buffer dips below minBufferPx": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should throw if maxBufferPx is less than minBufferPx": { - "error": "Error: Uncaught (in promise): TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should register and degregister with ScrollDispatcher": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should emit on viewChange inside the Angular zone": { - "error": "TypeError: Cannot read property 'viewChange' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with FixedSizeVirtualScrollStrategy should not throw when disposing of a view that will not fit in the cache": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with RTL direction should initially be scrolled all the way right and showing the first item in horizontal mode": { - "error": "TypeError: Cannot read property 'elementRef' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with RTL direction should scroll through items as user scrolls to the left in horizontal mode": { - "error": "TypeError: Cannot read property 'elementRef' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with RTL direction should interpret scrollToOffset amount as an offset from the right in horizontal mode": { - "error": "TypeError: Cannot read property 'elementRef' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with RTL direction should scroll to the correct index in horizontal mode": { - "error": "TypeError: Cannot read property 'elementRef' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with RTL direction should emit the scrolled to index in horizontal mode": { - "error": "TypeError: Cannot read property 'elementRef' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with RTL direction should set total content size": { - "error": "TypeError: Cannot read property 'elementRef' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with RTL direction should set total content size in horizontal mode": { - "error": "TypeError: Cannot read property 'elementRef' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with AutoSizeVirtualScrollStrategy should render initial state for uniform items": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with AutoSizeVirtualScrollStrategy should render extra content if first item is smaller than average": { - "error": "TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkVirtualScrollViewport with AutoSizeVirtualScrollStrategy should throw if maxBufferPx is less than minBufferPx": { - "error": "Error: Uncaught (in promise): TypeError: Cannot read property 'nativeElement' of undefined", - "notes": "FW-1114: Ivy doesn't support inserting same view instance multiple times" - }, - "CdkAccordion should not register nested items to the same accordion": { - "error": "TypeError: Cannot read property 'accordion' of undefined", - "notes": "Unknown" - }, "CdkDrag in a drop container should be able to customize the preview element": { "error": "Error: Expected cdk-drag cdk-drag-preview to contain 'custom-preview'.", "notes": "Unknown" @@ -341,62 +129,14 @@ window.testBlocklist = { "error": "Error: Failed: Expected node descendant num to be 2 but was 0", "notes": "Unknown" }, - "MatButton should apply class based on color attribute": { - "error": "Error: Template error: Can't bind to 'disabled' since it isn't a known property of 'a'.", + "MatInput without forms validates the type": { + "error": "Error: Input type \"file\" isn't supported by matInput.", "notes": "Unknown" }, - "MatButton should expose the ripple instance": { - "error": "Error: Expected undefined to be truthy.", + "MatInput with textarea autosize should work in a step": { + "error": "TypeError: Cannot read property 'getBoundingClientRect' of null", "notes": "Unknown" }, - "MatButton should not clear previous defined classes": { - "error": "Error: Template error: Can't bind to 'disabled' since it isn't a known property of 'a'.", - "notes": "FW-1037: Host bindings for host objects in metadata are inherited" - }, - "MatButton button[mat-fab] should have accent palette by default": { - "error": "Error: Template error: Can't bind to 'disabled' since it isn't a known property of 'a'.", - "notes": "FW-1037: Host bindings for host objects in metadata are inherited" - }, - "MatButton button[mat-mini-fab] should have accent palette by default": { - "error": "Error: Template error: Can't bind to 'disabled' since it isn't a known property of 'a'.", - "notes": "FW-1037: Host bindings for host objects in metadata are inherited" - }, - "MatButton button[mat-button] should not increment if disabled": { - "error": "Error: Template error: Can't bind to 'disabled' since it isn't a known property of 'a'.", - "notes": "FW-1037: Host bindings for host objects in metadata are inherited" - }, - "MatButton button[mat-button] should disable the native button element": { - "error": "Error: Template error: Can't bind to 'disabled' since it isn't a known property of 'a'.", - "notes": "FW-1037: Host bindings for host objects in metadata are inherited" - }, - "MatButton a[mat-button] should not redirect if disabled": { - "error": "Error: Template error: Can't bind to 'disabled' since it isn't a known property of 'a'.", - "notes": "FW-1037: Host bindings for host objects in metadata are inherited" - }, - "MatButton a[mat-button] should remove tabindex if disabled": { - "error": "Error: Template error: Can't bind to 'disabled' since it isn't a known property of 'a'.", - "notes": "FW-1037: Host bindings for host objects in metadata are inherited" - }, - "MatButton a[mat-button] should add aria-disabled attribute if disabled": { - "error": "Error: Template error: Can't bind to 'disabled' since it isn't a known property of 'a'.", - "notes": "FW-1037: Host bindings for host objects in metadata are inherited" - }, - "MatButton a[mat-button] should not add aria-disabled attribute if disabled is false": { - "error": "Error: Template error: Can't bind to 'disabled' since it isn't a known property of 'a'.", - "notes": "FW-1037: Host bindings for host objects in metadata are inherited" - }, - "MatButton a[mat-button] should be able to set a custom tabindex": { - "error": "Error: Template error: Can't bind to 'disabled' since it isn't a known property of 'a'.", - "notes": "FW-1037: Host bindings for host objects in metadata are inherited" - }, - "MatButton button ripples should disable the ripple if matRippleDisabled input is set": { - "error": "Error: Template error: Can't bind to 'disabled' since it isn't a known property of 'a'.", - "notes": "FW-1037: Host bindings for host objects in metadata are inherited" - }, - "MatButton button ripples should disable the ripple when the button is disabled": { - "error": "Error: Template error: Can't bind to 'disabled' since it isn't a known property of 'a'.", - "notes": "FW-1037: Host bindings for host objects in metadata are inherited" - }, "MatChipList StandardChipList basic behaviors should toggle the chips disabled state based on whether it is disabled": { "error": "Error: Expected true to be false.", "notes": "Unknown" @@ -525,12 +265,8 @@ window.testBlocklist = { "error": "TypeError: Cannot read property 'nativeElement' of undefined", "notes": "Unknown" }, - "MatSlideToggle without forms custom action configuration should not change value on dragging when drag action is noop": { - "error": "Error: Expected mat-slide-toggle-thumb-container to contain 'mat-dragging'.", - "notes": "Unknown" - }, "MatSidenav should be fixed position when in fixed mode": { - "error": "Error: Expected ng-tns-c23412-0 mat-drawer ng-trigger ng-trigger-transform mat-drawer-over ng-star-inserted to contain 'mat-sidenav-fixed'.", + "error": "Error: Expected ng-tns-c28435-0 ng-trigger ng-trigger-transform mat-drawer mat-drawer-over ng-star-inserted to contain 'mat-sidenav-fixed'.", "notes": "FW-1081: Static host classes don't work if component has superclass with host classes" }, "MatSidenav should set fixed bottom and top when in fixed mode": { @@ -569,34 +305,10 @@ window.testBlocklist = { "error": "TypeError: Cannot read property 'click' of undefined", "notes": "FW-1081: Static host classes don't work if component has superclass with host classes" }, - "MatGridList should throw error if rowHeight ratio is invalid": { - "error": "Error: mat-grid-list: invalid ratio given for row-height: \"4:3:2\"", - "notes": "Unknown" - }, - "MatInput without forms validates the type": { - "error": "Error: Input type \"file\" isn't supported by matInput.", - "notes": "Unknown" - }, - "MatInput with textarea autosize should work in a step": { - "error": "TypeError: Cannot read property 'getBoundingClientRect' of null", - "notes": "Unknown" - }, "Dialog should set the proper animation states": { "error": "TypeError: Cannot read property 'componentInstance' of null", "notes": "FW-1059: DebugNode.query should query nodes in the logical tree" }, - "FullscreenOverlayContainer should open an overlay inside a fullscreen element and move it to the body": { - "error": "Error: Must provide a portal to attach", - "notes": "Unknown" - }, - "FullscreenOverlayContainer should open an overlay inside the body and move it to a fullscreen element": { - "error": "Error: Must provide a portal to attach", - "notes": "Unknown" - }, - "OverlayContainer should remove the overlay container element from the DOM on destruction": { - "error": "Error: Must provide a portal to attach", - "notes": "Unknown" - }, "MatAutocomplete aria should set role of autocomplete panel to listbox": { "error": "TypeError: Cannot read property 'nativeElement' of null", "notes": "FW-1059: DebugNode.query should query nodes in the logical tree" @@ -609,10 +321,6 @@ window.testBlocklist = { "error": "TypeError: Cannot read property 'componentInstance' of null", "notes": "FW-1059: DebugNode.query should query nodes in the logical tree" }, - "MatMenu should close the menu when using the CloseScrollStrategy": { - "error": "TypeError: Cannot read property 'openMenu' of undefined", - "notes": "Unknown" - }, "MatMenu animations should enable ripples on items by default": { "error": "TypeError: Cannot read property 'query' of null", "notes": "FW-1059: DebugNode.query should query nodes in the logical tree"