示例#1
0
// FIXME: We should merge this function with
// ApplyBlockElementCommand::formatSelection
void IndentOutdentCommand::outdentRegion(
    const VisiblePosition& startOfSelection,
    const VisiblePosition& endOfSelection,
    EditingState* editingState) {
  VisiblePosition endOfCurrentParagraph = endOfParagraph(startOfSelection);
  VisiblePosition endOfLastParagraph = endOfParagraph(endOfSelection);

  if (endOfCurrentParagraph.deepEquivalent() ==
      endOfLastParagraph.deepEquivalent()) {
    outdentParagraph(editingState);
    return;
  }

  Position originalSelectionEnd = endingSelection().end();
  Position endAfterSelection =
      endOfParagraph(nextPositionOf(endOfLastParagraph)).deepEquivalent();

  while (endOfCurrentParagraph.deepEquivalent() != endAfterSelection) {
    PositionWithAffinity endOfNextParagraph =
        endOfParagraph(nextPositionOf(endOfCurrentParagraph))
            .toPositionWithAffinity();
    if (endOfCurrentParagraph.deepEquivalent() ==
        endOfLastParagraph.deepEquivalent()) {
      SelectionInDOMTree::Builder builder;
      if (originalSelectionEnd.isNotNull())
        builder.collapse(originalSelectionEnd);
      setEndingSelection(builder.build());
    } else {
      setEndingSelection(SelectionInDOMTree::Builder()
                             .collapse(endOfCurrentParagraph.deepEquivalent())
                             .build());
    }

    outdentParagraph(editingState);
    if (editingState->isAborted())
      return;

    // outdentParagraph could move more than one paragraph if the paragraph
    // is in a list item. As a result, endAfterSelection and endOfNextParagraph
    // could refer to positions no longer in the document.
    if (endAfterSelection.isNotNull() && !endAfterSelection.isConnected())
      break;

    document().updateStyleAndLayoutIgnorePendingStylesheets();
    if (endOfNextParagraph.isNotNull() && !endOfNextParagraph.isConnected()) {
      endOfCurrentParagraph = createVisiblePosition(endingSelection().end());
      endOfNextParagraph = endOfParagraph(nextPositionOf(endOfCurrentParagraph))
                               .toPositionWithAffinity();
    }
    endOfCurrentParagraph = createVisiblePosition(endOfNextParagraph);
  }
}
示例#2
0
TEST_F(SelectionTest, caret) {
  setBodyContent("<div id='sample'>abcdef</div>");

  Element* sample = document().getElementById("sample");
  Position position(Position(sample->firstChild(), 2));
  SelectionInDOMTree::Builder builder;
  builder.collapse(position);
  const SelectionInDOMTree& selection = builder.build();

  EXPECT_EQ(TextAffinity::Downstream, selection.affinity());
  EXPECT_EQ(CharacterGranularity, selection.granularity());
  EXPECT_FALSE(selection.hasTrailingWhitespace());
  EXPECT_FALSE(selection.isDirectional());
  EXPECT_FALSE(selection.isNone());
  EXPECT_EQ(position, selection.base());
  EXPECT_EQ(position, selection.extent());
}
示例#3
0
void DOMSelection::collapseToStart(ExceptionState& exceptionState) {
    if (!isAvailable())
        return;

    const VisibleSelection& selection = frame()->selection().selection();

    if (selection.isNone()) {
        exceptionState.throwDOMException(InvalidStateError,
                                         "there is no selection.");
        return;
    }

    // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets
    // needs to be audited.  See http://crbug.com/590369 for more details.
    // In the long term, we should change FrameSelection::setSelection to take a
    // parameter that does not require clean layout, so that modifying selection
    // no longer performs synchronous layout by itself.
    frame()->document()->updateStyleAndLayoutIgnorePendingStylesheets();

    SelectionInDOMTree::Builder builder;
    builder.collapse(selection.start());
    frame()->selection().setSelection(createVisibleSelection(builder.build()));
}