コード例 #1
0
ファイル: DOMSelection.cpp プロジェクト: jeremyroman/blink
void DOMSelection::addRange(Range* newRange)
{
    if (!m_frame)
        return;

    // FIXME: Should we throw DOMException for error cases below?
    if (!newRange) {
        addConsoleError("The given range is null.");
        return;
    }

    if (!newRange->startContainer()) {
        addConsoleError("The given range has no container. Perhaps 'detach()' has been invoked on it?");
        return;
    }

    FrameSelection& selection = m_frame->selection();

    if (selection.isNone()) {
        selection.setSelectedRange(newRange, VP_DEFAULT_AFFINITY);
        return;
    }

    RefPtrWillBeRawPtr<Range> originalRange = selection.firstRange();

    if (originalRange->startContainer()->document() != newRange->startContainer()->document()) {
        addConsoleError("The given range does not belong to the current selection's document.");
        return;
    }
    if (originalRange->startContainer()->treeScope() != newRange->startContainer()->treeScope()) {
        addConsoleError("The given range and the current selection belong to two different document fragments.");
        return;
    }

    if (originalRange->compareBoundaryPoints(Range::START_TO_END, newRange, ASSERT_NO_EXCEPTION) < 0
        || newRange->compareBoundaryPoints(Range::START_TO_END, originalRange.get(), ASSERT_NO_EXCEPTION) < 0) {
        addConsoleError("Discontiguous selection is not supported.");
        return;
    }

    // FIXME: "Merge the ranges if they intersect" is Blink-specific behavior; other browsers supporting discontiguous
    // selection (obviously) keep each Range added and return it in getRangeAt(). But it's unclear if we can really
    // do the same, since we don't support discontiguous selection. Further discussions at
    // <https://code.google.com/p/chromium/issues/detail?id=353069>.

    Range* start = originalRange->compareBoundaryPoints(Range::START_TO_START, newRange, ASSERT_NO_EXCEPTION) < 0 ? originalRange.get() : newRange;
    Range* end = originalRange->compareBoundaryPoints(Range::END_TO_END, newRange, ASSERT_NO_EXCEPTION) < 0 ? newRange : originalRange.get();
    RefPtrWillBeRawPtr<Range> merged = Range::create(originalRange->startContainer()->document(), start->startContainer(), start->startOffset(), end->endContainer(), end->endOffset());
    EAffinity affinity = selection.selection().affinity();
    selection.setSelectedRange(merged.get(), affinity);
}
コード例 #2
0
ファイル: DOMSelection.cpp プロジェクト: ollie314/chromium
void DOMSelection::addRange(Range* newRange) {
    DCHECK(newRange);

    if (!isAvailable())
        return;

    if (newRange->ownerDocument() != frame()->document())
        return;

    if (!newRange->isConnected()) {
        addConsoleError("The given range isn't in document.");
        return;
    }

    FrameSelection& selection = frame()->selection();

    if (newRange->ownerDocument() != selection.document()) {
        // "editing/selection/selection-in-iframe-removed-crash.html" goes here.
        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();

    if (selection.isNone()) {
        selection.setSelectedRange(EphemeralRange(newRange), VP_DEFAULT_AFFINITY);
        return;
    }

    Range* originalRange = selection.firstRange();

    if (originalRange->startContainer()->document() !=
            newRange->startContainer()->document()) {
        addConsoleError(
            "The given range does not belong to the current selection's document.");
        return;
    }
    if (originalRange->startContainer()->treeScope() !=
            newRange->startContainer()->treeScope()) {
        addConsoleError(
            "The given range and the current selection belong to two different "
            "document fragments.");
        return;
    }

    if (originalRange->compareBoundaryPoints(Range::kStartToEnd, newRange,
            ASSERT_NO_EXCEPTION) < 0 ||
            newRange->compareBoundaryPoints(Range::kStartToEnd, originalRange,
                                            ASSERT_NO_EXCEPTION) < 0) {
        addConsoleError("Discontiguous selection is not supported.");
        return;
    }

    // FIXME: "Merge the ranges if they intersect" is Blink-specific behavior;
    // other browsers supporting discontiguous selection (obviously) keep each
    // Range added and return it in getRangeAt(). But it's unclear if we can
    // really do the same, since we don't support discontiguous selection. Further
    // discussions at
    // <https://code.google.com/p/chromium/issues/detail?id=353069>.

    Range* start = originalRange->compareBoundaryPoints(
                       Range::kStartToStart, newRange, ASSERT_NO_EXCEPTION) < 0
                   ? originalRange
                   : newRange;
    Range* end = originalRange->compareBoundaryPoints(Range::kEndToEnd, newRange,
                 ASSERT_NO_EXCEPTION) < 0
                 ? newRange
                 : originalRange;
    const EphemeralRange merged =
        EphemeralRange(start->startPosition(), end->endPosition());
    TextAffinity affinity = selection.selection().affinity();
    selection.setSelectedRange(merged, affinity);
}