| Index: third_party/WebKit/Source/web/WebFrameContentDumper.cpp
|
| diff --git a/third_party/WebKit/Source/web/WebFrameContentDumper.cpp b/third_party/WebKit/Source/web/WebFrameContentDumper.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..c28d1fc6b208da451b2aa6c1d5fdfee9094e1314
|
| --- /dev/null
|
| +++ b/third_party/WebKit/Source/web/WebFrameContentDumper.cpp
|
| @@ -0,0 +1,112 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "public/web/WebFrameContentDumper.h"
|
| +
|
| +#include "core/editing/EphemeralRange.h"
|
| +#include "core/editing/iterators/TextIterator.h"
|
| +#include "core/editing/serializers/Serialization.h"
|
| +#include "core/frame/LocalFrame.h"
|
| +#include "core/layout/LayoutPart.h"
|
| +#include "core/layout/LayoutTreeAsText.h"
|
| +#include "core/layout/LayoutView.h"
|
| +#include "public/web/WebDocument.h"
|
| +#include "public/web/WebLocalFrame.h"
|
| +#include "web/WebLocalFrameImpl.h"
|
| +#include "wtf/text/WTFString.h"
|
| +
|
| +namespace blink {
|
| +
|
| +static void frameContentAsPlainText(size_t maxChars, LocalFrame* frame, StringBuilder& output)
|
| +{
|
| + Document* document = frame->document();
|
| + if (!document)
|
| + return;
|
| +
|
| + if (!frame->view())
|
| + return;
|
| +
|
| + // Select the document body.
|
| + if (document->body()) {
|
| + const EphemeralRange range = EphemeralRange::rangeOfContents(*document->body());
|
| +
|
| + // The text iterator will walk nodes giving us text. This is similar to
|
| + // the plainText() function in core/editing/TextIterator.h, but we implement the maximum
|
| + // size and also copy the results directly into a wstring, avoiding the
|
| + // string conversion.
|
| + for (TextIterator it(range.startPosition(), range.endPosition()); !it.atEnd(); it.advance()) {
|
| + it.text().appendTextToStringBuilder(output, 0, maxChars - output.length());
|
| + if (output.length() >= maxChars)
|
| + return; // Filled up the buffer.
|
| + }
|
| + }
|
| +
|
| + // The separator between frames when the frames are converted to plain text.
|
| + const LChar frameSeparator[] = { '\n', '\n' };
|
| + const size_t frameSeparatorLength = WTF_ARRAY_LENGTH(frameSeparator);
|
| +
|
| + // Recursively walk the children.
|
| + const FrameTree& frameTree = frame->tree();
|
| + for (Frame* curChild = frameTree.firstChild(); curChild; curChild = curChild->tree().nextSibling()) {
|
| + if (!curChild->isLocalFrame())
|
| + continue;
|
| + LocalFrame* curLocalChild = toLocalFrame(curChild);
|
| + // Ignore the text of non-visible frames.
|
| + LayoutView* contentLayoutObject = curLocalChild->contentLayoutObject();
|
| + LayoutPart* ownerLayoutObject = curLocalChild->ownerLayoutObject();
|
| + if (!contentLayoutObject || !contentLayoutObject->size().width() || !contentLayoutObject->size().height()
|
| + || (contentLayoutObject->location().x() + contentLayoutObject->size().width() <= 0) || (contentLayoutObject->location().y() + contentLayoutObject->size().height() <= 0)
|
| + || (ownerLayoutObject && ownerLayoutObject->style() && ownerLayoutObject->style()->visibility() != VISIBLE)) {
|
| + continue;
|
| + }
|
| +
|
| + // Make sure the frame separator won't fill up the buffer, and give up if
|
| + // it will. The danger is if the separator will make the buffer longer than
|
| + // maxChars. This will cause the computation above:
|
| + // maxChars - output->size()
|
| + // to be a negative number which will crash when the subframe is added.
|
| + if (output.length() >= maxChars - frameSeparatorLength)
|
| + return;
|
| +
|
| + output.append(frameSeparator, frameSeparatorLength);
|
| + frameContentAsPlainText(maxChars, curLocalChild, output);
|
| + if (output.length() >= maxChars)
|
| + return; // Filled up the buffer.
|
| + }
|
| +}
|
| +
|
| +WebString WebFrameContentDumper::dumpFrameTreeAsText(WebLocalFrame* frame, size_t maxChars)
|
| +{
|
| + if (!frame)
|
| + return WebString();
|
| + StringBuilder text;
|
| + frameContentAsPlainText(maxChars, toWebLocalFrameImpl(frame)->frame(), text);
|
| + return text.toString();
|
| +}
|
| +
|
| +WebString WebFrameContentDumper::dumpAsMarkup(WebLocalFrame* frame)
|
| +{
|
| + if (!frame)
|
| + return WebString();
|
| + return createMarkup(toWebLocalFrameImpl(frame)->frame()->document());
|
| +}
|
| +
|
| +WebString WebFrameContentDumper::dumpLayoutTreeAsText(WebLocalFrame* frame, LayoutAsTextControls toShow)
|
| +{
|
| + if (!frame)
|
| + return WebString();
|
| + LayoutAsTextBehavior behavior = LayoutAsTextShowAllLayers;
|
| +
|
| + if (toShow & LayoutAsTextWithLineTrees)
|
| + behavior |= LayoutAsTextShowLineTrees;
|
| +
|
| + if (toShow & LayoutAsTextDebug)
|
| + behavior |= LayoutAsTextShowCompositedLayers | LayoutAsTextShowAddresses | LayoutAsTextShowIDAndClass | LayoutAsTextShowLayerNesting;
|
| +
|
| + if (toShow & LayoutAsTextPrinting)
|
| + behavior |= LayoutAsTextPrintingMode;
|
| +
|
| + return externalRepresentation(toWebLocalFrameImpl(frame)->frame(), behavior);
|
| +}
|
| +}
|
|
|