architecture:

  • implementation: Action Dock extension
  • relation_to_copy:
    • status: planned subsequent feature (print-later)
    • binding: registers as a callback within the shared contextual action dock
    • interface: matches the dock’s Action interface: (targetElement) => Promise<void>
  • target_contract:
    • shared_registry: uses the same unified target selectors as Copy Anything
    • element_targets:
      • pre > code (code blocks)
      • .math-display, .katex-display (math blocks)
      • .mermaid, pre > code.language-mermaid (Mermaid diagrams)
      • table (tables)
      • blockquote, .callout (blockquotes and callouts)
      • img (images)
      • p (paragraphs/text blocks)
      • h1, h2, h3, h4, h5, h6 (headings)
      • ol, ul, dl, li, dt, dd (lists and list items)
      • a (links)
      • iframe, video, audio, embed, object (embeds and media elements)
      • section (document sections)
      • article (whole pages)
    • nested_targets: priority resolver traverses from interaction source upward, matching the most specific (innermost) eligible selector first using .closest(), where child blocks take precedence over parent containers
    • exclusions_and_fallbacks:
      • exclusions: interactive elements (button, input, select, textarea, dialog), UI/navigation structures (nav, .sidebar, .left, .right, .page-header, footer, #quartz-contextual-dock, .copy-button), and empty elements
      • generic_fallback: generic text-containing block elements not matching exclusions fall back to standard text content printing
    • dynamic_elements: Mermaid blocks and client-side rendered code/math are matched dynamically at runtime using runtime selectors (.mermaid, .math-display) rather than static build-time wrappers

user_interface:

  • contextual_dock:
    • element: integrated as a command in the shared action dock (#quartz-contextual-dock)
    • action_registration: registered dynamically in the action registry
  • page_trigger:
    • trigger: window.print() for whole-document printing
    • controls: keyboard shortcut (Cmd+P / Ctrl+P) or dedicated main header menu print action
  • routing_resilience:
    • mechanism: event delegation on document body is inherently SPA-safe
    • cleanup: removal of any active temporary iframes and event listeners on custom nav events
  • accessibility_and_feedback:
    • focus_accessibility: triggers are accessible via :focus-within and :focus keyboard navigation, avoiding hover-only states
    • user_feedback: user-visible status notifications for print preparation, success, and graceful error handling if dialog or loading fails

element_print_isolation:

  • mechanism: sandbox printing using a temporary iframe to avoid mutating source DOM

  • execution_steps:

    1. Create a temporary hidden iframe (display: none; position: absolute; width: 0; height: 0; border: none).
    2. Append iframe to the document body.
    3. Clone the target element’s HTML content.
    4. Sanitize the cloned markup to mitigate XSS (strip all <script> tags, inline event handler attributes like on*, and sensitive elements).
    5. Write the sanitized markup into the iframe’s document using safe APIs; no direct assignment of untrusted HTML to sensitive globals.
    6. Clone document stylesheets (document.styleSheets) by iterating and appending <link> or <style> tags to the iframe’s head.
    7. Wait for resources/stylesheets inside the iframe to load.
    8. Call iframe.contentWindow.print().
    9. Remove the iframe from the DOM immediately after printing or in case of a load failure/timeout. styling_encapsulation:
  • wrapper: @media print

  • theme_enforcement:

    • mechanism: local redeclaration of Quartz CSS variables
    • palette: strict high-contrast monochrome light theme
    • overrides: --light, --dark, --tertiary, --secondary

layout_geometry:

  • dimensions:
    • selector: @page
    • properties: size: letter, margin: 1in
  • truncation_prevention:
    • selectors: html, body, #quartz-body
    • properties: overflow: visible !important
  • column_reset:
    • selectors: .center, .page > article
    • properties: width: 100% !important, max-width: none !important, margin: 0 !important, padding: 0 !important

element_suppression:

  • selectors:
    • .sidebar
    • .left
    • .right
    • .page-header
    • footer
    • .popover-hint
    • #quartz-contextual-dock
    • .copy-button
  • properties: display: none !important

content_formatting:

  • fragmentation_control:
    • selectors: img, pre, blockquote, tr, .math-display, .mermaid
    • properties: break-inside: avoid
  • overflow_containment:
    • selectors: pre, table
    • properties: white-space: pre-wrap !important, overflow: visible !important, overflow-x: visible !important
  • semantic_fidelity:
    • selectors: callouts, syntax blocks
    • properties: print-color-adjust: exact, -webkit-print-color-adjust: exact
  • hyperlink_expansion:
    • selectors: a[href^="http"]::after
    • properties: content: " (" attr(href) ")"