blob: 8a56d859b0828fa5c31773629bbec7b84647d936 [file] [log] [blame]
/*
* Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* 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
* 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
* 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
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "core/editing/spellcheck/TextCheckingParagraph.h"
#include "core/dom/Range.h"
#include "core/editing/VisiblePosition.h"
#include "core/editing/VisibleUnits.h"
#include "core/editing/iterators/CharacterIterator.h"
namespace blink {
TextCheckingParagraph::TextCheckingParagraph(
const EphemeralRange& checking_range)
: checking_range_(checking_range),
checking_start_(-1),
checking_end_(-1),
checking_length_(-1) {}
TextCheckingParagraph::TextCheckingParagraph(
const EphemeralRange& checking_range,
const EphemeralRange& paragraph_range)
: checking_range_(checking_range),
paragraph_range_(paragraph_range),
checking_start_(-1),
checking_end_(-1),
checking_length_(-1) {}
TextCheckingParagraph::TextCheckingParagraph(Range* checking_range,
Range* paragraph_range)
: checking_range_(checking_range),
paragraph_range_(paragraph_range),
checking_start_(-1),
checking_end_(-1),
checking_length_(-1) {}
TextCheckingParagraph::~TextCheckingParagraph() = default;
void TextCheckingParagraph::ExpandRangeToNextEnd() {
DCHECK(checking_range_.IsNotNull());
SetParagraphRange(
EphemeralRange(ParagraphRange().StartPosition(),
EndOfParagraph(StartOfNextParagraph(CreateVisiblePosition(
ParagraphRange().StartPosition())))
.DeepEquivalent()));
InvalidateParagraphRangeValues();
}
void TextCheckingParagraph::InvalidateParagraphRangeValues() {
checking_start_ = checking_end_ = -1;
offset_as_range_ = EphemeralRange();
text_ = String();
}
int TextCheckingParagraph::RangeLength() const {
DCHECK(checking_range_.IsNotNull());
return TextIterator::RangeLength(ParagraphRange());
}
EphemeralRange TextCheckingParagraph::ParagraphRange() const {
DCHECK(checking_range_.IsNotNull());
if (paragraph_range_.IsNull())
paragraph_range_ = ExpandToParagraphBoundary(CheckingRange());
return paragraph_range_;
}
void TextCheckingParagraph::SetParagraphRange(const EphemeralRange& range) {
paragraph_range_ = range;
}
EphemeralRange TextCheckingParagraph::Subrange(int character_offset,
int character_count) const {
DCHECK(checking_range_.IsNotNull());
return CalculateCharacterSubrange(ParagraphRange(), character_offset,
character_count);
}
bool TextCheckingParagraph::IsEmpty() const {
// Both predicates should have same result, but we check both just to be sure.
// We need to investigate to remove this redundancy.
return IsRangeEmpty() || IsTextEmpty();
}
EphemeralRange TextCheckingParagraph::OffsetAsRange() const {
DCHECK(checking_range_.IsNotNull());
if (offset_as_range_.IsNotNull())
return offset_as_range_;
const Position& paragraph_start = ParagraphRange().StartPosition();
const Position& checking_start = CheckingRange().StartPosition();
if (paragraph_start <= checking_start) {
offset_as_range_ = EphemeralRange(paragraph_start, checking_start);
return offset_as_range_;
}
// editing/pasteboard/paste-table-001.html and more reach here.
offset_as_range_ = EphemeralRange(checking_start, paragraph_start);
return offset_as_range_;
}
const String& TextCheckingParagraph::GetText() const {
DCHECK(checking_range_.IsNotNull());
if (text_.IsEmpty())
text_ = PlainText(ParagraphRange());
return text_;
}
int TextCheckingParagraph::CheckingStart() const {
DCHECK(checking_range_.IsNotNull());
if (checking_start_ == -1)
checking_start_ = TextIterator::RangeLength(OffsetAsRange());
return checking_start_;
}
int TextCheckingParagraph::CheckingEnd() const {
DCHECK(checking_range_.IsNotNull());
if (checking_end_ == -1) {
checking_end_ =
CheckingStart() + TextIterator::RangeLength(CheckingRange());
}
return checking_end_;
}
int TextCheckingParagraph::CheckingLength() const {
DCHECK(checking_range_.IsNotNull());
if (-1 == checking_length_)
checking_length_ = TextIterator::RangeLength(
CheckingRange().StartPosition(), CheckingRange().EndPosition());
return checking_length_;
}
} // namespace blink