summaryrefslogtreecommitdiff
path: root/Source/WebCore/editing/VisibleSelection.cpp
diff options
context:
space:
mode:
authorKonstantin Tokarev <annulen@yandex.ru>2016-08-25 19:20:41 +0300
committerKonstantin Tokarev <annulen@yandex.ru>2017-02-02 12:30:55 +0000
commit6882a04fb36642862b11efe514251d32070c3d65 (patch)
treeb7959826000b061fd5ccc7512035c7478742f7b0 /Source/WebCore/editing/VisibleSelection.cpp
parentab6df191029eeeb0b0f16f127d553265659f739e (diff)
downloadqtwebkit-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.cpp80
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(&currentPosition.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(&currentPosition.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)
{