New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 798908 link

Starred by 1 user

Issue metadata

Status: Available
Owner: ----
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 3
Type: Bug

Blocked on: View detail
issue 572908
issue 684940



Sign in to add a comment

SelectionEditor's cached VisibleSelection not cleared on rendering <object> fallback content

Project Member Reported by xiaoche...@chromium.org, Jan 4 2018

Issue description

Chrome Version: ToT (65.0.3310.0)
OS: all

SelectionEditor assumes that the frame's VisibleSelection can be uniquely determined from DOM tree and style, and hence, doesn't clear its cached VisibleSelection as long as no DOM/style change happens. This isn't true when there are <object> elements, if the following happens:

0. Let there be an <object> element whose fallback content isn't rendered yet
1. Let SelectionEditor compute cache a VisibleSelection
2. Render the <object> element's fallback content, which changes layout without changing DOM or style
3. Now SelectionEditor caches a stale VS!

Reproducible with unit test:

TEST_F(FrameSelectionTest, FallbackContentAndStaleVisibleSelection) {
  SetBodyContent("<object>x</object>");
  
  // The bug repros only with nested HTML elements
  Node* document_element = GetDocument().documentElement();
  Node* clone = document_element->cloneNode(true, ASSERT_NO_EXCEPTION);
  document_element->replaceChild(clone, GetDocument().body());
  UpdateAllLifecyclePhases();
  
  Position base = Position::FirstPositionInNode(*document_element);
  Position extent = Position::LastPositionInNode(*document_element);
  Selection().SetSelection(SelectionInDOMTree::Builder()
                               .SetBaseAndExtent(base, extent)
                               .SetIsDirectional(true)
                               .Build());
  
  // Compute and cache a VisibleSelection
  Selection().ComputeVisibleSelectionInDOMTree();
  
  Element* object = GetDocument().QuerySelector("object");

  // This renders the fallback content of |object| and invalidates layout,
  // without changing DOM or style version.
  ToHTMLPlugInElement(object)->UpdatePlugin();
  UpdateAllLifecyclePhases();

  VisibleSelection cached = Selection().ComputeVisibleSelectionInDOMTree();
  VisibleSelection fresh =
      CreateVisibleSelection(Selection().GetSelectionInDOMTree());
  
  EXPECT_EQ(cached, fresh); // Fails here!
}
 
Cc: tanvir.r...@samsung.com
Note: this bug was found in the review of crrev.com/c/839841. It also contains an HTML repro case of this bug in its patch set 2.
Blockedon: 572908
Possible solutions:

1. Clear SelectionEditor's cached VisibleSelections in HTMLObjectElement::RenderFallbackContent().

pro: one-liner
con: ad-hoc hacky solution. We should try to prevent special-casing on OBJECT elements.

2. Introduce Document::LayoutVersion() and make SelectionEditor (and in general, editing code) track that instead of DOM and Style versions

pro: looks clean
con: needs some amount of work

3. Remove the layout-reattach behavior from HTMLObjectElement (issue 572908). 

pro: there's already a tracking bug
con: not sure if this is the only layout change without DOM/style update
Cc: e...@chromium.org
Looping in eae@ because of proposed addition of layout versioning.
Thanks!

Comment 5 by yosin@chromium.org, Jan 10 2018

Labels: -Pri-1 Pri-3
Lower to Pri-3, since fallback content of OBJECT is rare.

It is nice to have layout tree version and check it along with dom tree version and style version in SelectionEdtior.

BTW, Once LayoutNG adaptation is done, we may not need to cache VisibleSelection.

Blockedon: 684940

Comment 7 by xiaoche...@chromium.org, Jan 18 (4 days ago)

Owner: ----
Status: Available (was: Assigned)
No plan to work on it. Unassigning myself.

Sign in to add a comment