diff options
author | Konstantin Tokarev <annulen@yandex.ru> | 2016-08-25 19:20:41 +0300 |
---|---|---|
committer | Konstantin Tokarev <annulen@yandex.ru> | 2017-02-02 12:30:55 +0000 |
commit | 6882a04fb36642862b11efe514251d32070c3d65 (patch) | |
tree | b7959826000b061fd5ccc7512035c7478742f7b0 /Source/WebCore/editing/VisibleSelection.cpp | |
parent | ab6df191029eeeb0b0f16f127d553265659f739e (diff) | |
download | qtwebkit-6882a04fb36642862b11efe514251d32070c3d65.tar.gz |
Imported QtWebKit TP3 (git b57bc6801f1876c3220d5a4bfea33d620d477443)
Change-Id: I3b1d8a2808782c9f34d50240000e20cb38d3680f
Reviewed-by: Konstantin Tokarev <annulen@yandex.ru>
Diffstat (limited to 'Source/WebCore/editing/VisibleSelection.cpp')
-rw-r--r-- | Source/WebCore/editing/VisibleSelection.cpp | 80 |
1 files changed, 50 insertions, 30 deletions
diff --git a/Source/WebCore/editing/VisibleSelection.cpp b/Source/WebCore/editing/VisibleSelection.cpp index 92e1c151b..ef78c88b7 100644 --- a/Source/WebCore/editing/VisibleSelection.cpp +++ b/Source/WebCore/editing/VisibleSelection.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2006, 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,10 +10,10 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR @@ -28,9 +28,8 @@ #include "Document.h" #include "Element.h" -#include "Range.h" +#include "HTMLInputElement.h" #include "TextIterator.h" -#include "VisiblePosition.h" #include "VisibleUnits.h" #include "htmlediting.h" #include <stdio.h> @@ -85,9 +84,9 @@ VisibleSelection::VisibleSelection(const VisiblePosition& base, const VisiblePos validate(); } -VisibleSelection::VisibleSelection(const Range* range, EAffinity affinity, bool isDirectional) - : m_base(range->startPosition()) - , m_extent(range->endPosition()) +VisibleSelection::VisibleSelection(const Range& range, EAffinity affinity, bool isDirectional) + : m_base(range.startPosition()) + , m_extent(range.endPosition()) , m_affinity(affinity) , m_isDirectional(isDirectional) { @@ -142,7 +141,7 @@ PassRefPtr<Range> VisibleSelection::toNormalizedRange() const // in the course of running edit commands which modify the DOM. // Failing to call this can result in equivalentXXXPosition calls returning // incorrect results. - m_start.anchorNode()->document()->updateLayout(); + m_start.anchorNode()->document().updateLayout(); // Check again, because updating layout can clear the selection. if (isNone()) @@ -203,15 +202,14 @@ static PassRefPtr<Range> makeSearchRange(const Position& pos) Node* n = pos.deprecatedNode(); if (!n) return 0; - Document* d = n->document(); - Node* de = d->documentElement(); + Node* de = n->document().documentElement(); if (!de) return 0; Element* boundary = deprecatedEnclosingBlockFlowElement(n); if (!boundary) return 0; - RefPtr<Range> searchRange(Range::create(d)); + RefPtr<Range> searchRange(Range::create(n->document())); ExceptionCode ec = 0; Position start(pos.parentAnchoredEquivalent()); @@ -236,10 +234,10 @@ void VisibleSelection::appendTrailingWhitespace() if (!searchRange) return; - CharacterIterator charIt(searchRange.get(), TextIteratorEmitsCharactersBetweenAllVisiblePositions); + CharacterIterator charIt(*searchRange, TextIteratorEmitsCharactersBetweenAllVisiblePositions); - for (; charIt.length(); charIt.advance(1)) { - UChar c = charIt.characters()[0]; + for (; !charIt.atEnd() && charIt.text().length(); charIt.advance(1)) { + UChar c = charIt.text()[0]; if ((!isSpaceOrNewline(c) && c != noBreakSpace) || c == '\n') break; m_end = charIt.range()->endPosition(); @@ -324,6 +322,12 @@ void VisibleSelection::setStartAndEndFromBaseAndExtentRespectingGranularity(Text } m_end = end.deepEquivalent(); + // End must not be before start. + if (m_start.deprecatedNode() == m_end.deprecatedNode() && m_start.deprecatedEditingOffset() > m_end.deprecatedEditingOffset()) { + Position swap(m_start); + m_start = m_end; + m_end = swap; + } break; } case SentenceGranularity: { @@ -387,6 +391,9 @@ void VisibleSelection::setStartAndEndFromBaseAndExtentRespectingGranularity(Text m_start = startOfSentence(VisiblePosition(m_start, m_affinity)).deepEquivalent(); m_end = endOfSentence(VisiblePosition(m_end, m_affinity)).deepEquivalent(); break; + case DocumentGranularity: + ASSERT_NOT_REACHED(); + break; } // Make sure we do not have a dangling start or end. @@ -464,17 +471,17 @@ void VisibleSelection::setWithoutValidation(const Position& base, const Position static Position adjustPositionForEnd(const Position& currentPosition, Node* startContainerNode) { - TreeScope* treeScope = startContainerNode->treeScope(); + TreeScope& treeScope = startContainerNode->treeScope(); - ASSERT(currentPosition.containerNode()->treeScope() != treeScope); + ASSERT(¤tPosition.containerNode()->treeScope() != &treeScope); - if (Node* ancestor = treeScope->ancestorInThisScope(currentPosition.containerNode())) { + if (Node* ancestor = treeScope.ancestorInThisScope(currentPosition.containerNode())) { if (ancestor->contains(startContainerNode)) return positionAfterNode(ancestor); return positionBeforeNode(ancestor); } - if (Node* lastChild = treeScope->rootNode()->lastChild()) + if (Node* lastChild = treeScope.rootNode().lastChild()) return positionAfterNode(lastChild); return Position(); @@ -482,17 +489,17 @@ static Position adjustPositionForEnd(const Position& currentPosition, Node* star static Position adjustPositionForStart(const Position& currentPosition, Node* endContainerNode) { - TreeScope* treeScope = endContainerNode->treeScope(); + TreeScope& treeScope = endContainerNode->treeScope(); - ASSERT(currentPosition.containerNode()->treeScope() != treeScope); + ASSERT(¤tPosition.containerNode()->treeScope() != &treeScope); - if (Node* ancestor = treeScope->ancestorInThisScope(currentPosition.containerNode())) { + if (Node* ancestor = treeScope.ancestorInThisScope(currentPosition.containerNode())) { if (ancestor->contains(endContainerNode)) return positionBeforeNode(ancestor); return positionAfterNode(ancestor); } - if (Node* firstChild = treeScope->rootNode()->firstChild()) + if (Node* firstChild = treeScope.rootNode().firstChild()) return positionBeforeNode(firstChild); return Position(); @@ -503,7 +510,7 @@ void VisibleSelection::adjustSelectionToAvoidCrossingShadowBoundaries() if (m_base.isNull() || m_start.isNull() || m_end.isNull()) return; - if (m_start.anchorNode()->treeScope() == m_end.anchorNode()->treeScope()) + if (&m_start.anchorNode()->treeScope() == &m_end.anchorNode()->treeScope()) return; if (m_baseIsFirst) { @@ -514,7 +521,7 @@ void VisibleSelection::adjustSelectionToAvoidCrossingShadowBoundaries() m_start = m_extent; } - ASSERT(m_start.anchorNode()->treeScope() == m_end.anchorNode()->treeScope()); + ASSERT(&m_start.anchorNode()->treeScope() == &m_end.anchorNode()->treeScope()); } void VisibleSelection::adjustSelectionToAvoidCrossingEditingBoundaries() @@ -522,6 +529,11 @@ void VisibleSelection::adjustSelectionToAvoidCrossingEditingBoundaries() if (m_base.isNull() || m_start.isNull() || m_end.isNull()) return; + // Early return in the caret case (the state hasn't actually been set yet, so we can't use isCaret()) to avoid the + // expense of computing highestEditableRoot. + if (m_base == m_start && m_base == m_end) + return; + Node* baseRoot = highestEditableRoot(m_base); Node* startRoot = highestEditableRoot(m_start); Node* endRoot = highestEditableRoot(m_end); @@ -629,9 +641,11 @@ bool VisibleSelection::isContentEditable() const return isEditablePosition(start()); } -bool VisibleSelection::rendererIsEditable() const +bool VisibleSelection::hasEditableStyle() const { - return isEditablePosition(start(), ContentIsEditable, DoNotUpdateStyle); + if (Node* containerNode = start().containerNode()) + return containerNode->hasEditableStyle(); + return false; } bool VisibleSelection::isContentRichlyEditable() const @@ -646,10 +660,16 @@ Element* VisibleSelection::rootEditableElement() const Node* VisibleSelection::nonBoundaryShadowTreeRootNode() const { - return start().deprecatedNode() ? start().deprecatedNode()->nonBoundaryShadowTreeRootNode() : 0; + return start().deprecatedNode() ? start().deprecatedNode()->nonBoundaryShadowTreeRootNode() : nullptr; +} + +bool VisibleSelection::isInPasswordField() const +{ + HTMLTextFormControlElement* textControl = enclosingTextFormControl(start()); + return is<HTMLInputElement>(textControl) && downcast<HTMLInputElement>(*textControl).isPasswordField(); } -#ifndef NDEBUG +#if ENABLE(TREE_DEBUGGING) void VisibleSelection::debugPosition() const { @@ -706,7 +726,7 @@ void VisibleSelection::showTreeForThis() const } // namespace WebCore -#ifndef NDEBUG +#if ENABLE(TREE_DEBUGGING) void showTree(const WebCore::VisibleSelection& sel) { |