diff --git a/cc/paint/paint_op_buffer.cc b/cc/paint/paint_op_buffer.cc index 20afc9bc84f62b..97a182902ff584 100644 --- a/cc/paint/paint_op_buffer.cc +++ b/cc/paint/paint_op_buffer.cc @@ -16,6 +16,7 @@ #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkRegion.h" #include "third_party/skia/include/core/SkSerialProcs.h" +#include "third_party/skia/include/docs/SkPDFDocument.h" #include "third_party/skia/include/gpu/GrContext.h" namespace cc { @@ -1395,9 +1396,11 @@ void DrawTextBlobOp::RasterWithFlags(const DrawTextBlobOp* op, const PaintFlags* flags, SkCanvas* canvas, const PlaybackParams& params) { + SkPDF::SetNodeId(canvas, op->node_id); flags->DrawToSk(canvas, [op](SkCanvas* c, const SkPaint& p) { c->drawTextBlob(op->blob.get(), op->x, op->y, p); }); + SkPDF::SetNodeId(canvas, 0); } void RestoreOp::Raster(const RestoreOp* op, diff --git a/cc/paint/skia_paint_canvas.cc b/cc/paint/skia_paint_canvas.cc index f143d9ea15d7ad..e71b9a77c6eedc 100644 --- a/cc/paint/skia_paint_canvas.cc +++ b/cc/paint/skia_paint_canvas.cc @@ -9,6 +9,7 @@ #include "cc/paint/paint_recorder.h" #include "cc/paint/scoped_raster_flags.h" #include "third_party/skia/include/core/SkAnnotation.h" +#include "third_party/skia/include/docs/SkPDFDocument.h" namespace cc { SkiaPaintCanvas::ContextFlushes::ContextFlushes() @@ -317,7 +318,9 @@ void SkiaPaintCanvas::drawTextBlob(sk_sp blob, SkScalar y, NodeId node_id, const PaintFlags& flags) { + SkPDF::SetNodeId(canvas_, node_id); drawTextBlob(blob, x, y, flags); + SkPDF::SetNodeId(canvas_, 0); } void SkiaPaintCanvas::drawPicture(sk_sp record) { diff --git a/components/printing/renderer/print_render_frame_helper.cc b/components/printing/renderer/print_render_frame_helper.cc index 35bcee6547ef87..d3f4055902c759 100644 --- a/components/printing/renderer/print_render_frame_helper.cc +++ b/components/printing/renderer/print_render_frame_helper.cc @@ -1043,6 +1043,10 @@ bool PrintRenderFrameHelper::Delegate::IsScriptedPrintEnabled() { return true; } +bool PrintRenderFrameHelper::Delegate::ShouldGenerateTaggedPDF() { + return false; +} + PrintRenderFrameHelper::PrintRenderFrameHelper( content::RenderFrame* render_frame, std::unique_ptr delegate) @@ -1865,6 +1869,18 @@ bool PrintRenderFrameHelper::PrintPagesNative(blink::WebLocalFrame* frame, print_params.document_cookie); CHECK(metafile.Init()); + // If tagged PDF exporting is enabled, we also need to capture an + // accessibility tree and store it in the metafile. AXTreeSnapshotter + // should stay alive through the end of this function, because text + // drawing commands are only annotated with a DOMNodeId if accessibility + // is enabled. + std::unique_ptr snapshotter; + if (delegate_->ShouldGenerateTaggedPDF()) { + snapshotter = render_frame()->CreateAXTreeSnapshotter(); + snapshotter->Snapshot(ui::kAXModeComplete, 0, + &metafile.accessibility_tree()); + } + PrintHostMsg_DidPrintDocument_Params page_params; gfx::Size* page_size_in_dpi; gfx::Rect* content_area_in_dpi; diff --git a/components/printing/renderer/print_render_frame_helper.h b/components/printing/renderer/print_render_frame_helper.h index bd00b17898627b..0778deefa7af69 100644 --- a/components/printing/renderer/print_render_frame_helper.h +++ b/components/printing/renderer/print_render_frame_helper.h @@ -106,6 +106,10 @@ class PrintRenderFrameHelper // The default implementation returns |true|. virtual bool IsScriptedPrintEnabled(); + // Whether we should send extra metadata necessary to produce a tagged + // (accessible) PDF. + virtual bool ShouldGenerateTaggedPDF(); + // Returns true if printing is overridden and the default behavior should be // skipped for |frame|. virtual bool OverridePrint(blink::WebLocalFrame* frame) = 0; diff --git a/components/services/pdf_compositor/BUILD.gn b/components/services/pdf_compositor/BUILD.gn index ccc4858e0ef979..2e0e99a4139daf 100644 --- a/components/services/pdf_compositor/BUILD.gn +++ b/components/services/pdf_compositor/BUILD.gn @@ -20,6 +20,7 @@ static_library("pdf_compositor") { "//printing/common", "//skia", "//third_party/blink/public:blink_headers", + "//ui/accessibility", ] if (is_win) { diff --git a/components/services/pdf_compositor/DEPS b/components/services/pdf_compositor/DEPS index 3dec59eb9f24df..980abab857c10b 100644 --- a/components/services/pdf_compositor/DEPS +++ b/components/services/pdf_compositor/DEPS @@ -11,4 +11,5 @@ include_rules = [ "+third_party/skia", "+third_party/blink/public/platform", # Test web sandbox support. "+ui/base/ui_base_features.h", # UI features. + "+ui/accessibility", # Tagged PDF exporting. ] diff --git a/components/services/pdf_compositor/pdf_compositor_impl.cc b/components/services/pdf_compositor/pdf_compositor_impl.cc index e3692fb1fc2ccf..5f1bca07a4197c 100644 --- a/components/services/pdf_compositor/pdf_compositor_impl.cc +++ b/components/services/pdf_compositor/pdf_compositor_impl.cc @@ -27,6 +27,7 @@ #include "third_party/skia/include/core/SkGraphics.h" #include "third_party/skia/include/core/SkSerialProcs.h" #include "third_party/skia/src/utils/SkMultiPictureDocument.h" +#include "ui/accessibility/ax_tree_update.h" #if defined(OS_WIN) #include "content/public/child/dwrite_font_proxy_init_win.h" @@ -336,7 +337,8 @@ mojom::PdfCompositor::Status PdfCompositorImpl::CompositeToPdf( } SkDynamicMemoryWStream wstream; - sk_sp doc = MakePdfDocument(creator_, &wstream); + sk_sp doc = + MakePdfDocument(creator_, ui::AXTreeUpdate(), &wstream); for (const auto& page : pages) { SkCanvas* canvas = doc->beginPage(page.fSize.width(), page.fSize.height()); @@ -447,7 +449,7 @@ PdfCompositorImpl::FrameInfo::FrameInfo() = default; PdfCompositorImpl::FrameInfo::~FrameInfo() = default; PdfCompositorImpl::DocumentInfo::DocumentInfo(const std::string& creator) - : doc(MakePdfDocument(creator, &compositor_stream)) {} + : doc(MakePdfDocument(creator, ui::AXTreeUpdate(), &compositor_stream)) {} PdfCompositorImpl::DocumentInfo::~DocumentInfo() = default; diff --git a/content/renderer/accessibility/render_accessibility_impl.cc b/content/renderer/accessibility/render_accessibility_impl.cc index 132bf220b8c98b..586c311073421f 100644 --- a/content/renderer/accessibility/render_accessibility_impl.cc +++ b/content/renderer/accessibility/render_accessibility_impl.cc @@ -134,6 +134,7 @@ void AXTreeSnapshotterImpl::SnapshotContentTree(ui::AXMode ax_mode, BlinkAXTreeSource tree_source(render_frame_, ax_mode); tree_source.SetRoot(root); + tree_source.EnableDOMNodeIDs(); ScopedFreezeBlinkAXTreeSource freeze(&tree_source); // The serializer returns an AXContentTreeUpdate, which can store a complete diff --git a/headless/app/headless_shell_switches.cc b/headless/app/headless_shell_switches.cc index 6b2c5f44911945..c91c5fbc03f66f 100644 --- a/headless/app/headless_shell_switches.cc +++ b/headless/app/headless_shell_switches.cc @@ -22,6 +22,11 @@ const char kEnableBeginFrameControl[] = "enable-begin-frame-control"; // Enable crash reporter for headless. const char kEnableCrashReporter[] = "enable-crash-reporter"; +// If enabled, generate a tagged (accessible) file when printing to PDF. +// The plan is for this to go away once tagged PDFs become the default. +// See https://crbug.com/607777 +const char kExportTaggedPDF[] = "export-tagged-pdf"; + // Disable crash reporter for headless. It is enabled by default in official // builds. const char kDisableCrashReporter[] = "disable-crash-reporter"; diff --git a/headless/app/headless_shell_switches.h b/headless/app/headless_shell_switches.h index 1e69ba64d97799..aeb3a14fcdfcf9 100644 --- a/headless/app/headless_shell_switches.h +++ b/headless/app/headless_shell_switches.h @@ -20,6 +20,7 @@ HEADLESS_EXPORT extern const char kDiskCacheDir[]; HEADLESS_EXPORT extern const char kDumpDom[]; HEADLESS_EXPORT extern const char kEnableBeginFrameControl[]; HEADLESS_EXPORT extern const char kEnableCrashReporter[]; +HEADLESS_EXPORT extern const char kExportTaggedPDF[]; HEADLESS_EXPORT extern const char kHideScrollbars[]; HEADLESS_EXPORT extern const char kPasswordStore[]; HEADLESS_EXPORT extern const char kPrintToPDF[]; diff --git a/headless/lib/browser/headless_content_browser_client.cc b/headless/lib/browser/headless_content_browser_client.cc index aac56725f11071..3612acbb692478 100644 --- a/headless/lib/browser/headless_content_browser_client.cc +++ b/headless/lib/browser/headless_content_browser_client.cc @@ -190,6 +190,9 @@ void HeadlessContentBrowserClient::AppendExtraCommandLineSwitches( command_line->AppendSwitch(::switches::kEnableCrashReporter); #endif // defined(HEADLESS_USE_BREAKPAD) + if (old_command_line.HasSwitch(switches::kExportTaggedPDF)) + command_line->AppendSwitch(switches::kExportTaggedPDF); + // If we're spawning a renderer, then override the language switch. std::string process_type = command_line->GetSwitchValueASCII(::switches::kProcessType); diff --git a/headless/lib/renderer/headless_print_render_frame_helper_delegate.cc b/headless/lib/renderer/headless_print_render_frame_helper_delegate.cc index 7d8ab3f36308ad..253e6857d413df 100644 --- a/headless/lib/renderer/headless_print_render_frame_helper_delegate.cc +++ b/headless/lib/renderer/headless_print_render_frame_helper_delegate.cc @@ -3,6 +3,8 @@ // found in the LICENSE file. #include "headless/lib/renderer/headless_print_render_frame_helper_delegate.h" +#include "base/command_line.h" +#include "headless/app/headless_shell_switches.h" #include "third_party/blink/public/web/web_element.h" @@ -23,6 +25,11 @@ bool HeadlessPrintRenderFrameHelperDelegate::IsPrintPreviewEnabled() { return false; } +bool HeadlessPrintRenderFrameHelperDelegate::ShouldGenerateTaggedPDF() { + return base::CommandLine::ForCurrentProcess()->HasSwitch( + headless::switches::kExportTaggedPDF); +} + bool HeadlessPrintRenderFrameHelperDelegate::OverridePrint( blink::WebLocalFrame* frame) { return false; diff --git a/headless/lib/renderer/headless_print_render_frame_helper_delegate.h b/headless/lib/renderer/headless_print_render_frame_helper_delegate.h index c5c070dce15f67..707e849c413870 100644 --- a/headless/lib/renderer/headless_print_render_frame_helper_delegate.h +++ b/headless/lib/renderer/headless_print_render_frame_helper_delegate.h @@ -19,6 +19,7 @@ class HeadlessPrintRenderFrameHelperDelegate private: // printing::PrintRenderFrameHelper::Delegate: bool IsPrintPreviewEnabled() override; + bool ShouldGenerateTaggedPDF() override; bool OverridePrint(blink::WebLocalFrame* frame) override; blink::WebElement GetPdfElement(blink::WebLocalFrame* frame) override; diff --git a/printing/BUILD.gn b/printing/BUILD.gn index 890028484cf403..1491e109522052 100644 --- a/printing/BUILD.gn +++ b/printing/BUILD.gn @@ -117,6 +117,7 @@ component("printing") { "//printing/common", "//skia", "//third_party/icu", + "//ui/accessibility", "//ui/gfx", "//ui/gfx/geometry", "//url", diff --git a/printing/DEPS b/printing/DEPS index 41732d72750d4c..71708c22400a56 100644 --- a/printing/DEPS +++ b/printing/DEPS @@ -5,6 +5,7 @@ include_rules = [ "+third_party/icu/source/common/unicode", "+third_party/icu/source/i18n/unicode", "+third_party/skia", + "+ui/accessibility", "+ui/android", "+ui/aura", "+ui/base/resource", diff --git a/printing/common/BUILD.gn b/printing/common/BUILD.gn index 4143ca728c7a56..029a42e5daa2d3 100644 --- a/printing/common/BUILD.gn +++ b/printing/common/BUILD.gn @@ -14,6 +14,7 @@ source_set("common") { "//base", "//printing:printing_export", "//skia", + "//ui/accessibility", ] defines = [ "PRINTING_IMPLEMENTATION" ] diff --git a/printing/common/metafile_utils.cc b/printing/common/metafile_utils.cc index eae01fb862e426..24278c28b9b793 100644 --- a/printing/common/metafile_utils.cc +++ b/printing/common/metafile_utils.cc @@ -11,6 +11,10 @@ #include "third_party/skia/include/core/SkPictureRecorder.h" #include "third_party/skia/include/core/SkTime.h" #include "third_party/skia/include/docs/SkPDFDocument.h" +#include "ui/accessibility/ax_node.h" +#include "ui/accessibility/ax_node_data.h" +#include "ui/accessibility/ax_tree.h" +#include "ui/accessibility/ax_tree_update.h" namespace { @@ -38,11 +42,94 @@ sk_sp GetEmptyPicture() { return rec.finishRecordingAsPicture(); } +// Convert an AXNode into a SkPDF::StructureElementNode in order to make a +// tagged (accessible) PDF. Returns true on success and false if we don't +// have enough data to build a valid tree. +bool RecursiveBuildStructureTree(const ui::AXNode* ax_node, + SkPDF::StructureElementNode* tag) { + bool valid = false; + + tag->fNodeId = ax_node->GetIntAttribute(ax::mojom::IntAttribute::kDOMNodeId); + switch (ax_node->data().role) { + case ax::mojom::Role::kRootWebArea: + tag->fType = SkPDF::DocumentStructureType::kDocument; + break; + case ax::mojom::Role::kParagraph: + tag->fType = SkPDF::DocumentStructureType::kP; + break; + case ax::mojom::Role::kGenericContainer: + tag->fType = SkPDF::DocumentStructureType::kDiv; + break; + case ax::mojom::Role::kHeading: + // TODO(dmazzoni): heading levels. https://crbug.com/1039816 + tag->fType = SkPDF::DocumentStructureType::kH; + break; + case ax::mojom::Role::kList: + tag->fType = SkPDF::DocumentStructureType::kL; + break; + case ax::mojom::Role::kListMarker: + tag->fType = SkPDF::DocumentStructureType::kLbl; + break; + case ax::mojom::Role::kListItem: + tag->fType = SkPDF::DocumentStructureType::kLI; + break; + case ax::mojom::Role::kTable: + tag->fType = SkPDF::DocumentStructureType::kTable; + break; + case ax::mojom::Role::kRow: + tag->fType = SkPDF::DocumentStructureType::kTR; + break; + case ax::mojom::Role::kColumnHeader: + case ax::mojom::Role::kRowHeader: + tag->fType = SkPDF::DocumentStructureType::kTH; + break; + case ax::mojom::Role::kCell: + tag->fType = SkPDF::DocumentStructureType::kTD; + break; + case ax::mojom::Role::kFigure: + case ax::mojom::Role::kImage: + tag->fType = SkPDF::DocumentStructureType::kFigure; + break; + case ax::mojom::Role::kStaticText: + // Currently we're only marking text content, so we can't generate + // a nonempty structure tree unless we have at least one kStaticText + // node in the tree. + tag->fType = SkPDF::DocumentStructureType::kNonStruct; + valid = true; + break; + default: + tag->fType = SkPDF::DocumentStructureType::kNonStruct; + } + + tag->fChildCount = ax_node->GetUnignoredChildCount(); + // Allocated here, cleaned up in DestroyStructureElementNodeTree(). + SkPDF::StructureElementNode* children = + new SkPDF::StructureElementNode[tag->fChildCount]; + tag->fChildren = children; + for (size_t i = 0; i < tag->fChildCount; i++) { + bool success = RecursiveBuildStructureTree( + ax_node->GetUnignoredChildAtIndex(i), &children[i]); + if (success) + valid = true; + } + + return valid; +} + +void DestroyStructureElementNodeTree(SkPDF::StructureElementNode* node) { + for (size_t i = 0; i < node->fChildCount; i++) { + DestroyStructureElementNodeTree( + const_cast(&node->fChildren[i])); + } + delete[] node->fChildren; +} + } // namespace namespace printing { sk_sp MakePdfDocument(const std::string& creator, + const ui::AXTreeUpdate& accessibility_tree, SkWStream* stream) { SkPDF::Metadata metadata; SkTime::DateTime now = TimeToSkTime(base::Time::Now()); @@ -56,7 +143,17 @@ sk_sp MakePdfDocument(const std::string& creator, base::FeatureList::IsEnabled(printing::features::kHarfBuzzPDFSubsetter) ? SkPDF::Metadata::kHarfbuzz_Subsetter : SkPDF::Metadata::kSfntly_Subsetter; - return SkPDF::MakeDocument(stream, metadata); + + SkPDF::StructureElementNode tag_root = {}; + if (!accessibility_tree.nodes.empty()) { + ui::AXTree tree(accessibility_tree); + if (RecursiveBuildStructureTree(tree.root(), &tag_root)) + metadata.fStructureElementTreeRoot = &tag_root; + } + + sk_sp document = SkPDF::MakeDocument(stream, metadata); + DestroyStructureElementNodeTree(&tag_root); + return document; } sk_sp SerializeOopPicture(SkPicture* pic, void* ctx) { diff --git a/printing/common/metafile_utils.h b/printing/common/metafile_utils.h index efda8507bd9f91..5796754fdd5c48 100644 --- a/printing/common/metafile_utils.h +++ b/printing/common/metafile_utils.h @@ -14,6 +14,7 @@ #include "third_party/skia/include/core/SkRefCnt.h" #include "third_party/skia/include/core/SkSerialProcs.h" #include "third_party/skia/include/core/SkStream.h" +#include "ui/accessibility/ax_tree_update_forward.h" namespace printing { @@ -34,6 +35,7 @@ using DeserializationContext = base::flat_map>; using SerializationContext = ContentToProxyIdMap; sk_sp MakePdfDocument(const std::string& creator, + const ui::AXTreeUpdate& accessibility_tree, SkWStream* stream); SkSerialProcs SerializationProcs(SerializationContext* ctx); diff --git a/printing/metafile_skia.cc b/printing/metafile_skia.cc index e14acb47f11ca3..8e2a9a713e7216 100644 --- a/printing/metafile_skia.cc +++ b/printing/metafile_skia.cc @@ -178,7 +178,7 @@ bool MetafileSkia::FinishDocument() { cc::PlaybackParams::CustomDataRasterCallback custom_callback; switch (data_->type) { case SkiaDocumentType::PDF: - doc = MakePdfDocument(printing::GetAgent(), &stream); + doc = MakePdfDocument(printing::GetAgent(), accessibility_tree_, &stream); break; case SkiaDocumentType::MSKP: SkSerialProcs procs = SerializationProcs(&data_->subframe_content_info); diff --git a/printing/metafile_skia.h b/printing/metafile_skia.h index 26b9049163f2c5..f2fb34f6284610 100644 --- a/printing/metafile_skia.h +++ b/printing/metafile_skia.h @@ -16,6 +16,7 @@ #include "printing/common/metafile_utils.h" #include "printing/metafile.h" #include "skia/ext/platform_canvas.h" +#include "ui/accessibility/ax_tree_update.h" #if defined(OS_WIN) #include @@ -95,6 +96,11 @@ class PRINTING_EXPORT MetafileSkia : public Metafile { int GetDocumentCookie() const; const ContentToProxyIdMap& GetSubframeContentInfo() const; + const ui::AXTreeUpdate& accessibility_tree() const { + return accessibility_tree_; + } + ui::AXTreeUpdate& accessibility_tree() { return accessibility_tree_; } + private: FRIEND_TEST_ALL_PREFIXES(MetafileSkiaTest, TestFrameContent); @@ -111,6 +117,8 @@ class PRINTING_EXPORT MetafileSkia : public Metafile { std::unique_ptr data_; + ui::AXTreeUpdate accessibility_tree_; + DISALLOW_COPY_AND_ASSIGN(MetafileSkia); }; diff --git a/third_party/blink/renderer/core/content_capture/content_capture_manager.cc b/third_party/blink/renderer/core/content_capture/content_capture_manager.cc index c0e166ff3a2140..d403eced1fe306 100644 --- a/third_party/blink/renderer/core/content_capture/content_capture_manager.cc +++ b/third_party/blink/renderer/core/content_capture/content_capture_manager.cc @@ -5,7 +5,6 @@ #include "third_party/blink/renderer/core/content_capture/content_capture_manager.h" #include "third_party/blink/renderer/core/content_capture/sent_nodes.h" -#include "third_party/blink/renderer/core/dom/dom_node_ids.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/layout/layout_text.h" @@ -20,14 +19,13 @@ ContentCaptureManager::ContentCaptureManager(LocalFrame& local_frame_root) ContentCaptureManager::~ContentCaptureManager() = default; -DOMNodeId ContentCaptureManager::GetNodeId(Node& node) { +void ContentCaptureManager::ScheduleTaskIfNeeded() { if (first_node_holder_created_) { ScheduleTask(ContentCaptureTask::ScheduleReason::kContentChange); } else { ScheduleTask(ContentCaptureTask::ScheduleReason::kFirstContentChange); first_node_holder_created_ = true; } - return DOMNodeIds::IdForNode(&node); } void ContentCaptureManager::ScheduleTask( diff --git a/third_party/blink/renderer/core/content_capture/content_capture_manager.h b/third_party/blink/renderer/core/content_capture/content_capture_manager.h index 9d374aa9777d3a..00a2e59655ece6 100644 --- a/third_party/blink/renderer/core/content_capture/content_capture_manager.h +++ b/third_party/blink/renderer/core/content_capture/content_capture_manager.h @@ -24,11 +24,8 @@ class CORE_EXPORT ContentCaptureManager explicit ContentCaptureManager(LocalFrame& local_frame_root); virtual ~ContentCaptureManager(); - // Creates and returns NodeHolder for the given |node|, and schedules - // ContentCaptureTask if it isn't already scheduled. - // Can't use const Node& for parameter, because |node| is passed to - // DOMNodeIds::IdForNode(Node*). - DOMNodeId GetNodeId(Node& node); + // Schedules ContentCaptureTask if it isn't already scheduled. + void ScheduleTaskIfNeeded(); // Invokes when the |node_holder| asscociated LayoutText will be destroyed. void OnLayoutTextWillBeDestroyed(const Node& node); diff --git a/third_party/blink/renderer/core/content_capture/content_capture_test.cc b/third_party/blink/renderer/core/content_capture/content_capture_test.cc index 930c04892ea99e..614eee7a6dd78f 100644 --- a/third_party/blink/renderer/core/content_capture/content_capture_test.cc +++ b/third_party/blink/renderer/core/content_capture/content_capture_test.cc @@ -8,6 +8,7 @@ #include "third_party/blink/public/web/web_content_capture_client.h" #include "third_party/blink/public/web/web_content_holder.h" #include "third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h" +#include "third_party/blink/renderer/core/dom/dom_node_ids.h" #include "third_party/blink/renderer/core/dom/element.h" #include "third_party/blink/renderer/core/dom/node.h" #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h" @@ -192,7 +193,8 @@ class ContentCaptureTest : public PageTestBase { Element* div_element = GetElementById("d1"); div_element->appendChild(element); UpdateAllLifecyclePhasesForTest(); - created_node_id_ = GetContentCaptureManager()->GetNodeId(*node); + GetContentCaptureManager()->ScheduleTaskIfNeeded(); + created_node_id_ = DOMNodeIds::IdForNode(node); Vector captured_content{created_node_id_}; content_capture_manager_->GetContentCaptureTask() ->SetCapturedContentForTesting(captured_content); @@ -268,7 +270,8 @@ class ContentCaptureTest : public PageTestBase { CHECK(layout_object); CHECK(layout_object->IsText()); nodes_.push_back(node); - node_ids_.push_back(GetContentCaptureManager()->GetNodeId(*node)); + GetContentCaptureManager()->ScheduleTaskIfNeeded(); + node_ids_.push_back(DOMNodeIds::IdForNode(node)); } } diff --git a/third_party/blink/renderer/core/layout/layout_text.cc b/third_party/blink/renderer/core/layout/layout_text.cc index 722664cf247d5c..e9082e4cd0f50a 100644 --- a/third_party/blink/renderer/core/layout/layout_text.cc +++ b/third_party/blink/renderer/core/layout/layout_text.cc @@ -29,6 +29,7 @@ #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/core/accessibility/ax_object_cache.h" #include "third_party/blink/renderer/core/content_capture/content_capture_manager.h" +#include "third_party/blink/renderer/core/dom/dom_node_ids.h" #include "third_party/blink/renderer/core/dom/text.h" #include "third_party/blink/renderer/core/editing/ephemeral_range.h" #include "third_party/blink/renderer/core/editing/frame_selection.h" @@ -2471,8 +2472,13 @@ PhysicalRect LayoutText::DebugRect() const { DOMNodeId LayoutText::EnsureNodeId() { if (node_id_ == kInvalidDOMNodeId) { - if (auto* content_capture_manager = GetContentCaptureManager()) - node_id_ = content_capture_manager->GetNodeId(*GetNode()); + auto* content_capture_manager = GetContentCaptureManager(); + if (content_capture_manager) + content_capture_manager->ScheduleTaskIfNeeded(); + + // If either content capture or accessibility are enabled, store a node ID. + if (content_capture_manager || GetDocument().ExistingAXObjectCache()) + node_id_ = DOMNodeIds::IdForNode(GetNode()); } return node_id_; } diff --git a/third_party/blink/renderer/core/page/print_context_test.cc b/third_party/blink/renderer/core/page/print_context_test.cc index cd38040c55b12e..7c9e9d9505dede 100644 --- a/third_party/blink/renderer/core/page/print_context_test.cc +++ b/third_party/blink/renderer/core/page/print_context_test.cc @@ -48,6 +48,10 @@ class MockPageContextCanvas : public SkCanvas { void onDrawAnnotation(const SkRect& rect, const char key[], SkData* value) override { + // Ignore PDF node key annotations, defined in SkPDFDocument.cpp. + if (0 == strcmp(key, "PDF_Node_Key")) + return; + if (rect.width() == 0 && rect.height() == 0) { SkPoint point = getTotalMatrix().mapXY(rect.x(), rect.y()); Operation operation = {kDrawPoint, diff --git a/ui/accessibility/BUILD.gn b/ui/accessibility/BUILD.gn index a51cbdce4c3373..efc671b8d4a08b 100644 --- a/ui/accessibility/BUILD.gn +++ b/ui/accessibility/BUILD.gn @@ -108,6 +108,7 @@ jumbo_component("accessibility") { "ax_tree_source.h", "ax_tree_source_checker.h", "ax_tree_update.h", + "ax_tree_update_forward.h", "null_ax_action_target.cc", "null_ax_action_target.h", "platform/ax_android_constants.cc", diff --git a/ui/accessibility/ax_tree_update_forward.h b/ui/accessibility/ax_tree_update_forward.h new file mode 100644 index 00000000000000..c59dfaaad7398d --- /dev/null +++ b/ui/accessibility/ax_tree_update_forward.h @@ -0,0 +1,18 @@ +// Copyright 2019 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. + +#ifndef UI_ACCESSIBILITY_AX_TREE_UPDATE_FORWARD_H_ +#define UI_ACCESSIBILITY_AX_TREE_UPDATE_FORWARD_H_ + +namespace ui { + +struct AXNodeData; +struct AXTreeData; +template +struct AXTreeUpdateBase; +using AXTreeUpdate = AXTreeUpdateBase; + +} // namespace ui + +#endif // UI_ACCESSIBILITY_AX_TREE_UPDATE_FORWARD_H_