| Index: third_party/WebKit/Source/core/frame/FrameView.cpp
|
| diff --git a/third_party/WebKit/Source/core/frame/FrameView.cpp b/third_party/WebKit/Source/core/frame/FrameView.cpp
|
| index ac0dea61f5fd09dba165e76d92681dff8b919eb6..07be49a9157c72877105f47bbf2ed1e05c6338b3 100644
|
| --- a/third_party/WebKit/Source/core/frame/FrameView.cpp
|
| +++ b/third_party/WebKit/Source/core/frame/FrameView.cpp
|
| @@ -172,6 +172,7 @@ FrameView::FrameView(LocalFrame& frame, IntRect frame_rect)
|
| : frame_(frame),
|
| frame_rect_(frame_rect),
|
| parent_(nullptr),
|
| + frame_view_state_(kNotAttached),
|
| display_mode_(kWebDisplayModeBrowser),
|
| can_have_scrollbars_(true),
|
| has_pending_layout_(false),
|
| @@ -376,6 +377,7 @@ void FrameView::SetupRenderThrottling() {
|
| }
|
|
|
| void FrameView::Dispose() {
|
| + SetFrameOrPluginState(kDisposed);
|
| CHECK(!IsInPerformLayout());
|
|
|
| if (ScrollAnimatorBase* scroll_animator = ExistingScrollAnimator())
|
| @@ -2927,17 +2929,6 @@ Color FrameView::DocumentBackgroundColor() const {
|
| return result;
|
| }
|
|
|
| -FrameView* FrameView::ParentFrameView() const {
|
| - if (!Parent())
|
| - return nullptr;
|
| -
|
| - Frame* parent_frame = frame_->Tree().Parent();
|
| - if (parent_frame && parent_frame->IsLocalFrame())
|
| - return ToLocalFrame(parent_frame)->View();
|
| -
|
| - return nullptr;
|
| -}
|
| -
|
| void FrameView::DidChangeGlobalRootScroller() {
|
| if (!frame_->GetSettings() || !frame_->GetSettings()->GetViewportEnabled())
|
| return;
|
| @@ -3677,7 +3668,8 @@ IntPoint FrameView::ConvertSelfToChild(const FrameOrPlugin& child,
|
|
|
| IntRect FrameView::ConvertToContainingFrameViewBase(
|
| const IntRect& local_rect) const {
|
| - if (parent_) {
|
| + DCHECK(frame_view_state_ == kAttached);
|
| + if (FrameView* parent = ParentFrameView()) {
|
| // Get our layoutObject in the parent view
|
| LayoutPartItem layout_item = frame_->OwnerLayoutItem();
|
| if (layout_item.IsNull())
|
| @@ -3687,7 +3679,7 @@ IntRect FrameView::ConvertToContainingFrameViewBase(
|
| // Add borders and padding??
|
| rect.Move((layout_item.BorderLeft() + layout_item.PaddingLeft()).ToInt(),
|
| (layout_item.BorderTop() + layout_item.PaddingTop()).ToInt());
|
| - return parent_->ConvertFromLayoutItem(layout_item, rect);
|
| + return parent->ConvertFromLayoutItem(layout_item, rect);
|
| }
|
|
|
| return local_rect;
|
| @@ -3695,10 +3687,11 @@ IntRect FrameView::ConvertToContainingFrameViewBase(
|
|
|
| IntRect FrameView::ConvertFromContainingFrameViewBase(
|
| const IntRect& parent_rect) const {
|
| - if (parent_) {
|
| + DCHECK(frame_view_state_ == kAttached);
|
| + if (FrameView* parent = ParentFrameView()) {
|
| IntRect local_rect = parent_rect;
|
| local_rect.SetLocation(
|
| - parent_->ConvertSelfToChild(*this, local_rect.Location()));
|
| + parent->ConvertSelfToChild(*this, local_rect.Location()));
|
| return local_rect;
|
| }
|
|
|
| @@ -3707,7 +3700,8 @@ IntRect FrameView::ConvertFromContainingFrameViewBase(
|
|
|
| IntPoint FrameView::ConvertToContainingFrameViewBase(
|
| const IntPoint& local_point) const {
|
| - if (parent_) {
|
| + DCHECK(frame_->IsLocalRoot() || frame_view_state_ == kAttached);
|
| + if (FrameView* parent = ParentFrameView()) {
|
| // Get our layoutObject in the parent view
|
| LayoutPartItem layout_item = frame_->OwnerLayoutItem();
|
| if (layout_item.IsNull())
|
| @@ -3718,7 +3712,7 @@ IntPoint FrameView::ConvertToContainingFrameViewBase(
|
| // Add borders and padding
|
| point.Move((layout_item.BorderLeft() + layout_item.PaddingLeft()).ToInt(),
|
| (layout_item.BorderTop() + layout_item.PaddingTop()).ToInt());
|
| - return parent_->ConvertFromLayoutItem(layout_item, point);
|
| + return parent->ConvertFromLayoutItem(layout_item, point);
|
| }
|
|
|
| return local_point;
|
| @@ -3726,13 +3720,14 @@ IntPoint FrameView::ConvertToContainingFrameViewBase(
|
|
|
| IntPoint FrameView::ConvertFromContainingFrameViewBase(
|
| const IntPoint& parent_point) const {
|
| - if (parent_) {
|
| + DCHECK(frame_->IsLocalRoot() || frame_view_state_ == kAttached);
|
| + if (FrameView* parent = ParentFrameView()) {
|
| // Get our layoutObject in the parent view
|
| LayoutPartItem layout_item = frame_->OwnerLayoutItem();
|
| if (layout_item.IsNull())
|
| return parent_point;
|
|
|
| - IntPoint point = parent_->ConvertToLayoutItem(layout_item, parent_point);
|
| + IntPoint point = parent->ConvertToLayoutItem(layout_item, parent_point);
|
| // Subtract borders and padding
|
| point.Move((-layout_item.BorderLeft() - layout_item.PaddingLeft()).ToInt(),
|
| (-layout_item.BorderTop() - layout_item.PaddingTop()).ToInt());
|
| @@ -3868,6 +3863,15 @@ void FrameView::RemoveAnimatingScrollableArea(ScrollableArea* scrollable_area) {
|
| }
|
|
|
| void FrameView::SetParent(FrameView* parent) {
|
| + if (parent) {
|
| + SetFrameOrPluginState(kAttached);
|
| + }
|
| + if (!parent) {
|
| + DCHECK(frame_view_state_ == kAttached ||
|
| + (frame_view_state_ == kDisposed && parent_));
|
| + SetFrameOrPluginState(kNotAttached);
|
| + }
|
| +
|
| if (parent == parent_)
|
| return;
|
|
|
| @@ -3878,6 +3882,8 @@ void FrameView::SetParent(FrameView* parent) {
|
| if (parent && parent->IsVisible())
|
| SetParentVisible(true);
|
|
|
| + DCHECK(parent == ParentFrameView());
|
| +
|
| UpdateParentScrollableAreaSet();
|
| SetupRenderThrottling();
|
|
|
| @@ -3885,6 +3891,53 @@ void FrameView::SetParent(FrameView* parent) {
|
| subtree_throttled_ = ParentFrameView()->CanThrottleRendering();
|
| }
|
|
|
| +FrameView* FrameView::Parent() const {
|
| + if (frame_view_state_ == kNotAttached || frame_view_state_ == kAttached)
|
| + DCHECK(ParentFrameView() == parent_);
|
| +
|
| + return parent_;
|
| +}
|
| +
|
| +FrameView* FrameView::ParentFrameView() const {
|
| + if (frame_view_state_ != kAttached)
|
| + return nullptr;
|
| +
|
| + Frame* parent_frame = frame_->Tree().Parent();
|
| + if (parent_frame && parent_frame->IsLocalFrame())
|
| + return ToLocalFrame(parent_frame)->View();
|
| +
|
| + return nullptr;
|
| +}
|
| +
|
| +void FrameView::SetFrameOrPluginState(FrameOrPluginState state) {
|
| + VLOG(1) << "SetFrameOrPluginState " << this << " " << frame_view_state_
|
| + << "->" << state;
|
| + if (VLOG_IS_ON(2))
|
| + base::debug::StackTrace(10).Print();
|
| + switch (state) {
|
| + case kNotAttached:
|
| + DCHECK(frame_view_state_ == kAttached || frame_view_state_ == kDisposed);
|
| + break;
|
| + case kAttached:
|
| + DCHECK(frame_view_state_ == kNotAttached ||
|
| + frame_view_state_ == kDisposed);
|
| + break;
|
| + case kDeferred:
|
| + DCHECK(frame_view_state_ == kNotAttached ||
|
| + frame_view_state_ == kAttached || frame_view_state_ == kDeferred ||
|
| + frame_view_state_ == kDisposed);
|
| + break;
|
| + case kDisposed:
|
| + DCHECK(frame_view_state_ == kNotAttached ||
|
| + frame_view_state_ == kAttached || frame_view_state_ == kDeferred ||
|
| + frame_view_state_ == kDisposed);
|
| + break;
|
| + default:
|
| + NOTREACHED();
|
| + }
|
| + frame_view_state_ = state;
|
| +}
|
| +
|
| void FrameView::RemoveChild(FrameOrPlugin* child) {
|
| DCHECK(child->Parent() == this);
|
|
|
| @@ -4750,25 +4803,43 @@ bool FrameView::ScrollbarCornerPresent() const {
|
| }
|
|
|
| IntRect FrameView::ConvertToRootFrame(const IntRect& local_rect) const {
|
| - if (parent_) {
|
| + // TODO(joelhockey): I expect that this should only be called in state
|
| + // kAttached However, this is called in state
|
| + // kNotAttached: browser_tests
|
| + // --gtest_filter=DevToolsExtensionTest.HttpIframeInDevToolsExtensionDevtools
|
| + // kDeferred: interactive_ui_tests
|
| + // --gtest_filter=SitePerProcessInteractiveBrowserTest.FullscreenElementInMultipleSubframes
|
| + // kDisposed: run-webkit-tests -t Default
|
| + // third_party/WebKit/LayoutTests/virtual/disable-spinvalidation/compositing/iframes/invisible-nested-iframe-hide.html
|
| + DCHECK(frame_->IsLocalRoot() || frame_view_state_ == kNotAttached ||
|
| + frame_view_state_ == kAttached || frame_view_state_ == kDeferred ||
|
| + frame_view_state_ == kDisposed);
|
| + if (FrameView* parent = ParentFrameView()) {
|
| IntRect parent_rect = ConvertToContainingFrameViewBase(local_rect);
|
| - return parent_->ConvertToRootFrame(parent_rect);
|
| + return parent->ConvertToRootFrame(parent_rect);
|
| }
|
| return local_rect;
|
| }
|
|
|
| IntPoint FrameView::ConvertToRootFrame(const IntPoint& local_point) const {
|
| - if (parent_) {
|
| + DCHECK(frame_->IsLocalRoot() || frame_view_state_ == kAttached);
|
| + if (FrameView* parent = ParentFrameView()) {
|
| IntPoint parent_point = ConvertToContainingFrameViewBase(local_point);
|
| - return parent_->ConvertToRootFrame(parent_point);
|
| + return parent->ConvertToRootFrame(parent_point);
|
| }
|
| return local_point;
|
| }
|
|
|
| IntRect FrameView::ConvertFromRootFrame(
|
| const IntRect& rect_in_root_frame) const {
|
| - if (parent_) {
|
| - IntRect parent_rect = parent_->ConvertFromRootFrame(rect_in_root_frame);
|
| + // TODO(joelhockey): I expect that this should only be called in state
|
| + // kAttached However, this is called in state kDeferred in
|
| + // interactive_ui_tests
|
| + // --gtest_filter=SitePerProcessInteractiveBrowserTest.FullscreenElementInMultipleSubframes
|
| + DCHECK(frame_->IsLocalRoot() || frame_view_state_ == kAttached ||
|
| + frame_view_state_ == kDeferred);
|
| + if (FrameView* parent = ParentFrameView()) {
|
| + IntRect parent_rect = parent->ConvertFromRootFrame(rect_in_root_frame);
|
| return ConvertFromContainingFrameViewBase(parent_rect);
|
| }
|
| return rect_in_root_frame;
|
| @@ -4776,8 +4847,16 @@ IntRect FrameView::ConvertFromRootFrame(
|
|
|
| IntPoint FrameView::ConvertFromRootFrame(
|
| const IntPoint& point_in_root_frame) const {
|
| - if (parent_) {
|
| - IntPoint parent_point = parent_->ConvertFromRootFrame(point_in_root_frame);
|
| + // TODO(joelhockey): Usually parent should only be called when in state
|
| + // kAtached, but this is also called in state:
|
| + // kDisposed: content_shell --run-layout-test
|
| + // fast/events/frame-detached-in-mousedown.html kDeferred: content_shell
|
| + // --run-layout-test
|
| + // external/wpt/fullscreen/api/document-exit-fullscreen-nested-in-iframe-manual.html
|
| + DCHECK(frame_->IsLocalRoot() || frame_view_state_ == kAttached ||
|
| + frame_view_state_ == kDeferred || frame_view_state_ == kDisposed);
|
| + if (FrameView* parent = ParentFrameView()) {
|
| + IntPoint parent_point = parent->ConvertFromRootFrame(point_in_root_frame);
|
| return ConvertFromContainingFrameViewBase(parent_point);
|
| }
|
| return point_in_root_frame;
|
| @@ -4827,7 +4906,10 @@ void FrameView::SetParentVisible(bool visible) {
|
|
|
| // As parent visibility changes, we may need to recomposite this frame view
|
| // and potentially child frame views.
|
| - SetNeedsCompositingUpdate(GetLayoutViewItem(), kCompositingUpdateRebuildTree);
|
| + // TODO(joelhockey): This call doesn't seem to be needed, and it
|
| + // causes errors during dispose when checking document lifecycle state.
|
| + // SetNeedsCompositingUpdate(GetLayoutViewItem(),
|
| + // kCompositingUpdateRebuildTree);
|
|
|
| parent_visible_ = visible;
|
|
|
|
|