This source file includes following definitions.
- m_end
- m_end
- m_end
- createRange
- createRangeForSelection
- createRangeFor
- create
#include "config.h"
#include "core/editing/PlainTextRange.h"
#include "core/dom/ContainerNode.h"
#include "core/dom/Document.h"
#include "core/dom/Range.h"
#include "core/editing/TextIterator.h"
#include "core/editing/VisiblePosition.h"
namespace WebCore {
PlainTextRange::PlainTextRange()
: m_start(kNotFound)
, m_end(kNotFound)
{
}
PlainTextRange::PlainTextRange(int location)
: m_start(location)
, m_end(location)
{
ASSERT(location >= 0);
}
PlainTextRange::PlainTextRange(int start, int end)
: m_start(start)
, m_end(end)
{
ASSERT(start >= 0);
ASSERT(end >= 0);
ASSERT(start <= end);
}
PassRefPtrWillBeRawPtr<Range> PlainTextRange::createRange(const ContainerNode& scope) const
{
return createRangeFor(scope, ForGeneric);
}
PassRefPtrWillBeRawPtr<Range> PlainTextRange::createRangeForSelection(const ContainerNode& scope) const
{
return createRangeFor(scope, ForSelection);
}
PassRefPtrWillBeRawPtr<Range> PlainTextRange::createRangeFor(const ContainerNode& scope, GetRangeFor getRangeFor) const
{
ASSERT(isNotNull());
RefPtrWillBeRawPtr<Range> resultRange = scope.document().createRange();
size_t docTextPosition = 0;
bool startRangeFound = false;
RefPtrWillBeRawPtr<Range> textRunRange = nullptr;
TextIterator it(rangeOfContents(const_cast<ContainerNode*>(&scope)).get(), getRangeFor == ForSelection ? TextIteratorEmitsCharactersBetweenAllVisiblePositions : TextIteratorDefaultBehavior);
if (!start() && !length() && it.atEnd()) {
textRunRange = it.range();
resultRange->setStart(textRunRange->startContainer(), 0, ASSERT_NO_EXCEPTION);
resultRange->setEnd(textRunRange->startContainer(), 0, ASSERT_NO_EXCEPTION);
return resultRange.release();
}
for (; !it.atEnd(); it.advance()) {
int len = it.length();
textRunRange = it.range();
bool foundStart = start() >= docTextPosition && start() <= docTextPosition + len;
bool foundEnd = end() >= docTextPosition && end() <= docTextPosition + len;
if (foundEnd) {
if (len == 1 && it.characterAt(0) == '\n') {
scope.document().updateLayoutIgnorePendingStylesheets();
it.advance();
if (!it.atEnd()) {
RefPtrWillBeRawPtr<Range> range = it.range();
textRunRange->setEnd(range->startContainer(), range->startOffset(), ASSERT_NO_EXCEPTION);
} else {
Position runStart = textRunRange->startPosition();
Position runEnd = VisiblePosition(runStart).next().deepEquivalent();
if (runEnd.isNotNull())
textRunRange->setEnd(runEnd.containerNode(), runEnd.computeOffsetInContainerNode(), ASSERT_NO_EXCEPTION);
}
}
}
if (foundStart) {
startRangeFound = true;
if (textRunRange->startContainer()->isTextNode()) {
int offset = start() - docTextPosition;
resultRange->setStart(textRunRange->startContainer(), offset + textRunRange->startOffset(), IGNORE_EXCEPTION);
} else {
if (start() == docTextPosition)
resultRange->setStart(textRunRange->startContainer(), textRunRange->startOffset(), IGNORE_EXCEPTION);
else
resultRange->setStart(textRunRange->endContainer(), textRunRange->endOffset(), IGNORE_EXCEPTION);
}
}
if (foundEnd) {
if (textRunRange->startContainer()->isTextNode()) {
int offset = end() - docTextPosition;
resultRange->setEnd(textRunRange->startContainer(), offset + textRunRange->startOffset(), IGNORE_EXCEPTION);
} else {
if (end() == docTextPosition)
resultRange->setEnd(textRunRange->startContainer(), textRunRange->startOffset(), IGNORE_EXCEPTION);
else
resultRange->setEnd(textRunRange->endContainer(), textRunRange->endOffset(), IGNORE_EXCEPTION);
}
docTextPosition += len;
break;
}
docTextPosition += len;
}
if (!startRangeFound)
return nullptr;
if (length() && end() > docTextPosition) {
resultRange->setEnd(textRunRange->endContainer(), textRunRange->endOffset(), IGNORE_EXCEPTION);
}
return resultRange.release();
}
PlainTextRange PlainTextRange::create(const Node& scope, const Range& range)
{
if (!range.startContainer())
return PlainTextRange();
if (range.startContainer() != &scope && !range.startContainer()->isDescendantOf(&scope))
return PlainTextRange();
if (range.endContainer() != scope && !range.endContainer()->isDescendantOf(&scope))
return PlainTextRange();
RefPtrWillBeRawPtr<Range> testRange = Range::create(scope.document(), const_cast<Node*>(&scope), 0, range.startContainer(), range.startOffset());
ASSERT(testRange->startContainer() == &scope);
size_t start = TextIterator::rangeLength(testRange.get());
testRange->setEnd(range.endContainer(), range.endOffset(), IGNORE_EXCEPTION);
ASSERT(testRange->startContainer() == &scope);
size_t end = TextIterator::rangeLength(testRange.get());
return PlainTextRange(start, end);
}
}