summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/frame/frame_content_as_text.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/core/frame/frame_content_as_text.cc')
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_content_as_text.cc76
1 files changed, 76 insertions, 0 deletions
diff --git a/chromium/third_party/blink/renderer/core/frame/frame_content_as_text.cc b/chromium/third_party/blink/renderer/core/frame/frame_content_as_text.cc
new file mode 100644
index 00000000000..0dc762f65c3
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/frame/frame_content_as_text.cc
@@ -0,0 +1,76 @@
+// Copyright 2021 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 "third_party/blink/renderer/core/frame/frame_content_as_text.h"
+
+#include "base/stl_util.h"
+#include "third_party/blink/public/web/web_document.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/core/frame/local_frame_view.h"
+#include "third_party/blink/renderer/core/html_element_type_helpers.h"
+#include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
+#include "third_party/blink/renderer/core/layout/layout_view.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+
+void FrameContentAsText(size_t max_chars,
+ LocalFrame* frame,
+ StringBuilder& output) {
+ Document* document = frame->GetDocument();
+ if (!document)
+ return;
+
+ if (!frame->View() || frame->View()->CanThrottleRendering())
+ return;
+
+ DCHECK(!frame->View()->NeedsLayout());
+ DCHECK(!document->NeedsLayoutTreeUpdate());
+
+ if (document->documentElement() &&
+ document->documentElement()->GetLayoutObject()) {
+ output.Append(document->documentElement()->innerText());
+ if (output.length() >= max_chars)
+ output.Resize(max_chars);
+ }
+
+ // The separator between frames when the frames are converted to plain text.
+ const LChar kFrameSeparator[] = {'\n', '\n'};
+ const size_t frame_separator_length = base::size(kFrameSeparator);
+
+ // Recursively walk the children.
+ const FrameTree& frame_tree = frame->Tree();
+ for (Frame* cur_child = frame_tree.FirstChild(); cur_child;
+ cur_child = cur_child->Tree().NextSibling()) {
+ auto* cur_local_child = DynamicTo<LocalFrame>(cur_child);
+ if (!cur_local_child)
+ continue;
+ // Ignore the text of non-visible frames.
+ LayoutView* layout_view = cur_local_child->ContentLayoutObject();
+ LayoutObject* owner_layout_object = cur_local_child->OwnerLayoutObject();
+ if (!layout_view || !layout_view->Size().Width() ||
+ !layout_view->Size().Height() ||
+ (layout_view->Location().X() + layout_view->Size().Width() <= 0) ||
+ (layout_view->Location().Y() + layout_view->Size().Height() <= 0) ||
+ (owner_layout_object && owner_layout_object->Style() &&
+ owner_layout_object->Style()->Visibility() != EVisibility::kVisible)) {
+ 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() >= max_chars - frame_separator_length)
+ return;
+
+ output.Append(kFrameSeparator, frame_separator_length);
+ FrameContentAsText(max_chars, cur_local_child, output);
+ if (output.length() >= max_chars)
+ return; // Filled up the buffer.
+ }
+}
+
+} // namespace blink