#include "config.h"
#include "EditingRange.h"
#include <WebCore/Frame.h>
#include <WebCore/FrameSelection.h>
#include <WebCore/TextIterator.h>
#include <WebCore/VisibleUnits.h>
namespace WebKit {
RefPtr<WebCore::Range> EditingRange::toRange(WebCore::Frame& frame, const EditingRange& range, EditingRangeIsRelativeTo editingRangeIsRelativeTo)
{
ASSERT(range.location != notFound);
if (range.location > INT_MAX)
return nullptr;
int length;
if (range.length <= INT_MAX && range.location + range.length <= INT_MAX)
length = static_cast<int>(range.length);
else
length = INT_MAX - range.location;
if (editingRangeIsRelativeTo == EditingRangeIsRelativeTo::EditableRoot) {
return WebCore::TextIterator::rangeFromLocationAndLength(frame.selection().rootEditableElementOrDocumentElement(), static_cast<int>(range.location), length);
}
ASSERT(editingRangeIsRelativeTo == EditingRangeIsRelativeTo::Paragraph);
const WebCore::VisibleSelection& selection = frame.selection().selection();
RefPtr<WebCore::Range> selectedRange = selection.toNormalizedRange();
if (!selectedRange)
return nullptr;
RefPtr<WebCore::Range> paragraphRange = makeRange(startOfParagraph(selection.visibleStart()), selection.visibleEnd());
if (!paragraphRange)
return nullptr;
WebCore::ContainerNode& rootNode = paragraphRange.get()->startContainer().treeScope().rootNode();
int paragraphStartIndex = WebCore::TextIterator::rangeLength(WebCore::Range::create(rootNode.document(), &rootNode, 0, ¶graphRange->startContainer(), paragraphRange->startOffset()).ptr());
return WebCore::TextIterator::rangeFromLocationAndLength(&rootNode, paragraphStartIndex + static_cast<int>(range.location), length);
}
EditingRange EditingRange::fromRange(WebCore::Frame& frame, const WebCore::Range* range, EditingRangeIsRelativeTo editingRangeIsRelativeTo)
{
ASSERT(editingRangeIsRelativeTo == EditingRangeIsRelativeTo::EditableRoot);
size_t location;
size_t length;
if (!range || !WebCore::TextIterator::getLocationAndLengthFromRange(frame.selection().rootEditableElementOrDocumentElement(), range, location, length))
return { };
EditingRange editingRange(location, length);
if (!editingRange.isValid())
return { };
return editingRange;
}
}
namespace IPC {
void ArgumentCoder<WebKit::EditingRange>::encode(Encoder& encoder, const WebKit::EditingRange& editingRange)
{
encoder << editingRange.location;
encoder << editingRange.length;
}
Optional<WebKit::EditingRange> ArgumentCoder<WebKit::EditingRange>::decode(Decoder& decoder)
{
WebKit::EditingRange editingRange;
if (!decoder.decode(editingRange.location))
return WTF::nullopt;
if (!decoder.decode(editingRange.length))
return WTF::nullopt;
return editingRange;
}
}