Esempio n. 1
0
void SelectionAdjuster::adjustSelectionInDOMTree(VisibleSelection* selection, const VisibleSelectionInFlatTree& selectionInFlatTree)
{
    if (selectionInFlatTree.isNone()) {
        *selection = VisibleSelection();
        return;
    }

    const Position& base = toPositionInDOMTree(selectionInFlatTree.base());
    const Position& extent = toPositionInDOMTree(selectionInFlatTree.extent());

    if (isCrossingShadowBoundaries(selectionInFlatTree)) {
        *selection = VisibleSelection(base, extent);
        return;
    }

    const Position& position1 = toPositionInDOMTree(selectionInFlatTree.start());
    const Position& position2 = toPositionInDOMTree(selectionInFlatTree.end());
    selection->m_base = base;
    selection->m_extent = extent;
    selection->m_affinity = selectionInFlatTree.m_affinity;
    selection->m_isDirectional = selectionInFlatTree.m_isDirectional;
    selection->m_granularity = selectionInFlatTree.m_granularity;
    selection->m_hasTrailingWhitespace = selectionInFlatTree.m_hasTrailingWhitespace;
    selection->m_baseIsFirst = base.isNull() || base.compareTo(extent) <= 0;
    if (position1.compareTo(position2) <= 0) {
        selection->m_start = position1;
        selection->m_end = position2;
    } else {
        selection->m_start = position2;
        selection->m_end = position1;
    }
    selection->updateSelectionType();
    selection->didChange();
}
Esempio n. 2
0
static bool isCrossingShadowBoundaries(
    const VisibleSelectionInFlatTree& selection) {
  if (!selection.isRange())
    return false;
  TreeScope& treeScope = selection.base().anchorNode()->treeScope();
  return selection.extent().anchorNode()->treeScope() != treeScope ||
         selection.start().anchorNode()->treeScope() != treeScope ||
         selection.end().anchorNode()->treeScope() != treeScope;
}
TEST_F(SelectionAdjusterTest, adjustSelectionInFlatTree)
{
    setBodyContent("<div id=sample>foo</div>");
    MockVisibleSelectionChangeObserver selectionObserver;
    VisibleSelectionInFlatTree selectionInFlatTree;
    selectionInFlatTree.setChangeObserver(selectionObserver);

    Node* const sample = document().getElementById("sample");
    Node* const foo = sample->firstChild();
    // Select "foo"
    VisibleSelection selection(Position(foo, 0), Position(foo, 3));
    SelectionAdjuster::adjustSelectionInFlatTree(&selectionInFlatTree, selection);
    EXPECT_EQ(PositionInFlatTree(foo, 0), selectionInFlatTree.start());
    EXPECT_EQ(PositionInFlatTree(foo, 3), selectionInFlatTree.end());
    EXPECT_EQ(1, selectionObserver.callCounter()) << "adjustSelectionInFlatTree() should call didChangeVisibleSelection()";
}
Esempio n. 4
0
// TODO(yosin): We should make |adjustSelectionInDOMTree()| to return
// |VisibleSelection| once |VisibleSelection| constructor doesn't call
// |validate()|.
void SelectionAdjuster::adjustSelectionInDOMTree(
    VisibleSelection* selection,
    const VisibleSelectionInFlatTree& selectionInFlatTree) {
  if (selectionInFlatTree.isNone()) {
    *selection = VisibleSelection();
    return;
  }

  const Position& base = toPositionInDOMTree(selectionInFlatTree.base());
  const Position& extent = toPositionInDOMTree(selectionInFlatTree.extent());

  if (isCrossingShadowBoundaries(selectionInFlatTree)) {
    DCHECK(base.document());

    // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets
    // needs to be audited.  See http://crbug.com/590369 for more details.
    // This layout update call cannot be hoisted out of the |if|, otherwise it's
    // going to cause performance regression (http://crbug.com/652301).
    // TODO(yosin): Implement and apply lazy visible selection validation so
    // that we don't need to update layout here.
    base.document()->updateStyleAndLayoutIgnorePendingStylesheets();

    *selection = createVisibleSelection(
        SelectionInDOMTree::Builder().setBaseAndExtent(base, extent).build());
    return;
  }

  const Position& position1 = toPositionInDOMTree(selectionInFlatTree.start());
  const Position& position2 = toPositionInDOMTree(selectionInFlatTree.end());
  selection->m_base = base;
  selection->m_extent = extent;
  selection->m_affinity = selectionInFlatTree.m_affinity;
  selection->m_isDirectional = selectionInFlatTree.m_isDirectional;
  selection->m_granularity = selectionInFlatTree.m_granularity;
  selection->m_hasTrailingWhitespace =
      selectionInFlatTree.m_hasTrailingWhitespace;
  selection->m_baseIsFirst = base.isNull() || base.compareTo(extent) <= 0;
  if (position1.compareTo(position2) <= 0) {
    selection->m_start = position1;
    selection->m_end = position2;
  } else {
    selection->m_start = position2;
    selection->m_end = position1;
  }
  selection->updateSelectionType();
}