diff --git a/src/service/resource.js b/src/service/resource.js index 9f9ceca5023f..d26d91cdb692 100644 --- a/src/service/resource.js +++ b/src/service/resource.js @@ -19,7 +19,7 @@ import {Layout} from '../layout'; import {Services} from '../services'; import {computedStyle, toggle} from '../style'; import {dev, devAssert} from '../log'; -import {isBlockedByConsent} from '../error'; +import {isBlockedByConsent, reportError} from '../error'; import { layoutRectLtwh, layoutRectSizeEquals, @@ -498,13 +498,19 @@ export class Resource { oldBox.top != newBox.top || sizeChanges ) { - if ( - this.element.isUpgraded() && - this.state_ != ResourceState.NOT_BUILT && - (this.state_ == ResourceState.NOT_LAID_OUT || - this.element.isRelayoutNeeded()) - ) { - this.state_ = ResourceState.READY_FOR_LAYOUT; + if (this.element.isUpgraded()) { + if (this.state_ == ResourceState.NOT_LAID_OUT) { + // If the element isn't laid out yet, then we're now ready for layout. + this.state_ = ResourceState.READY_FOR_LAYOUT; + } else if ( + (this.state_ == ResourceState.LAYOUT_COMPLETE || + this.state_ == ResourceState.LAYOUT_FAILED) && + this.element.isRelayoutNeeded() + ) { + // If the element was already laid out and we need to relayout, then + // go back to ready for layout. + this.state_ = ResourceState.READY_FOR_LAYOUT; + } } } @@ -902,6 +908,7 @@ export class Resource { this.state_ ); err.associatedElement = this.element; + reportError(err); return Promise.reject(err); } diff --git a/test/unit/test-resource.js b/test/unit/test-resource.js index 3142ffd28b81..376e690901d4 100644 --- a/test/unit/test-resource.js +++ b/test/unit/test-resource.js @@ -372,6 +372,22 @@ describes.realWin('Resource', {amp: true}, (env) => { expect(resource.getLayoutBox().width).to.equal(111 + 10); }); + it('should not relayout if element has not completed layout', () => { + elementMock.expects('isUpgraded').returns(true).atLeast(1); + resource.state_ = ResourceState.LAYOUT_SCHEDULED; + resource.layoutBox_ = {left: 11, top: 12, width: 111, height: 222}; + + // Width changed. + elementMock + .expects('getBoundingClientRect') + .returns({left: 11, top: 12, width: 111 + 10, height: 222}) + .once(); + elementMock.expects('isRelayoutNeeded').returns(true).atLeast(0); + resource.measure(); + expect(resource.getState()).to.equal(ResourceState.LAYOUT_SCHEDULED); + expect(resource.getLayoutBox().width).to.equal(111 + 10); + }); + it('should calculate NOT fixed for non-displayed elements', () => { elementMock.expects('isUpgraded').returns(true).atLeast(1); elementMock