architecture:

  • implementation: Unified Action Dock & Registry System
  • relation_to_print:
    • status: shared interface foundation (copy-now, print-later)
    • binding: print registers as a callback within the same #quartz-contextual-dock
    • interface: conforms to the dynamic Action Registry contract
  • target_contract:
    • shared_registry: uses the same unified target selectors as Print Anything
    • element_targets:
      • p, .text-block (paragraphs and text blocks)
      • h1, h2, h3, h4, h5, h6 (headings)
      • ol, ul, dl (ordered, unordered, and definition lists)
      • li, dt, dd (list items)
      • pre > code (code blocks)
      • .math-display, .katex-display (math blocks)
      • .mermaid, pre > code.language-mermaid, svg, canvas (Mermaid diagrams, dynamic drawings, and direct visual SVGs/canvases)
      • table (tables)
      • blockquote, .callout (blockquotes and callouts)
      • figure, figcaption (figure elements and captions)
      • span, strong, em, code, mark, kbd (inline formatting and keyboard inputs)
      • details, summary (disclosure widgets)
      • img (images)
      • a[href], a[download] (links and downloadable/file links)
      • iframe, embed, object, video, audio, .embed (embeds, media, and interactive media frames)
      • section (document sections)
      • article (whole pages)
      • * (generic semantic fallback for other elements, filtered by a content-bearing eligibility predicate)

action_registry:

  • core_design: A central runtime registry storing available contextual operations.
  • interface:
    • id: unique action identifier (e.g., "copy", "print")
    • label: localized screen-reader string (aria-label)
    • icon_class: css class defining which pre-rendered SVG to display
    • eligible(element): predicate returning boolean if target is valid
    • execute(element): asynchronous callback handling the payload
  • active_actions:
    • copy: currently active and fully specified
    • print: planned subsequent feature; registers as a print callback without permanent raw DOM button controls

semantic_eligibility_and_representation:

  • paragraphs_and_text_blocks:
    • selector: p, .text-block
    • copy_representation: clean plain text content of the paragraph
  • headings:
    • selector: h1, h2, h3, h4, h5, h6
    • copy_representation: clean plain text of the heading, or formatted as Markdown heading structure (e.g., # heading)
  • lists_and_list_items:
    • selector: ol, ul, dl, li, dt, dd
    • copy_representation: plain text representation of the list/item, preserving semantic indentation and markers
  • code_blocks:
    • selector: pre > code
    • copy_representation: exact innerText source code including shell prompts to preserve execution capability, excluding cosmetic line numbers
  • math_blocks:
    • selector: .math-display, .katex-display
    • copy_representation: original LaTeX source string extracted from data-math or KaTeX annotation fields
  • diagrams_and_drawings:
    • selector: .mermaid, pre > code.language-mermaid, svg, canvas
    • copy_representation:
      • rich_format: raw Mermaid syntax source, SVG vector source markup, or canvas raster image URL / base64 representation
      • fallback_format: plain text node text or diagram reference link
  • tables:
    • selector: table
    • copy_representation: structured TSV (tab-separated values) or Markdown table syntax string
  • blockquotes_and_callouts:
    • selector: blockquote, .callout
    • copy_representation: standard Markdown syntax (e.g., > text or > [!info] text)
  • figures_and_captions:
    • selector: figure, figcaption
    • copy_representation: text content or markdown representation combining the figure source and the caption
  • inline_formatting:
    • selector: span, strong, em, code, mark, kbd
    • copy_representation: exact innerText of the inline element
  • details_and_summary:
    • selector: details, summary
    • copy_representation: combined plain text of disclosure summary title and collapsed/expanded details text content
  • images:
    • selector: img
    • copy_representation:
      • rich_format: binary image blob (using ClipboardItem for PNG/JPEG) retrieved via async fetch (if CORS-safe)
      • fallback_format: falls back to copying the absolute source URL or markdown format ![alt](url) if binary copy fails
  • links_and_downloads:
    • selector: a[href], a[download]
    • copy_representation: markdown format [text](url) or absolute URL; for download links (e.g. a[download] or file-extension links), copies the direct target download URL
  • embeds_and_media:
    • selector: iframe, embed, object, video, audio, .embed
    • copy_representation: absolute source URL, fallback stream URL, or HTML embedding source string
  • sections:
    • selector: section
    • copy_representation: full plaintext content of section nodes
  • whole_pages:
    • selector: article
    • copy_representation: full document content in raw Markdown or plaintext
  • generic_semantic_fallback:
    • selector: main *, article * (excluding elements matching .sidebar, .page-header, footer, #quartz-contextual-dock, script, style, nav, button, input, .copy-button)
    • eligibility_predicate: must contain direct text content (element.innerText.trim().length > 0) and must not be a purely structural layout wrapper (e.g., empty divs/spans) or raw SVG path elements
    • copy_representation: clean textContent of the matched element

nested_target_resolution:

  • selected_text_precedence:
    • rule: If there is an active window/document text selection (i.e., window.getSelection().toString() is not empty), the system prioritizes copying the exact selected text range rather than the clicked/hovered target element’s default representation.
  • priority_resolution:
    • mechanism: runtime event delegation traverses from event.target upward via .closest()
    • rule: matches the most specific (innermost) eligible selector first
  • boundary_prevention:
    • AST_discovery: AST scanner/visitor ignores children of already processed elements during static build-time annotations
    • runtime_filtering: target resolver prevents redundant docks by ignoring nested elements when a child element has active focus or mouse hover

build_time_annotations_and_runtime_discovery:

  • build_time:
    • tool: Rehype plugin with unist-util-visit
    • markers: annotates static eligible elements with data-copyable="true" and data-target-type attributes
  • runtime_discovery:
    • necessity: dynamic components (Mermaid rendering, KaTeX math blocks) mutate the DOM at runtime
    • mermaid_timing: hooks into Mermaid’s client-side post-render callback or registers a MutationObserver on .mermaid blocks to discover and bind to newly rendered SVGs without build-time wrappers
    • event_delegation: dynamic elements matched directly via runtime CSS selectors at the document level, bypassing static HTML wrapper requirements

contextual_dock:

  • element_count: single global element #quartz-contextual-dock to avoid performance tax of thousands of static buttons
  • position: absolute/fixed position updated dynamically relative to the active target element using getBoundingClientRect()
  • visibility:
    • pointer: revealed on mouse hover over target (throttled pointer tracking)
    • touch: revealed on element long-press or tap
    • keyboard: revealed when focus enters an eligible target via focusin / :focus-within
  • accessibility:
    • tab_index: dock buttons are keyboard-navigable via tabindex="0"
    • focus_management: visual focus ring explicitly styled; focus returned to target upon action completion or dismiss
    • aria_attributes: dynamic role attributes (role="toolbar" for the dock, role="button" for commands) and descriptive labels

clipboard_execution_and_fallbacks:

  • protocol:
    • primary: standard navigator.clipboard.writeText for strings and navigator.clipboard.write for complex objects
  • fallbacks:
    • secure_context_check: checks typeof navigator.clipboard !== "undefined" first to prevent TypeError in non-secure HTTP/file contexts
    • execution_fallback: creates a temporary hidden <textarea> element, populates it, appends to DOM, selects text, executes document.execCommand("copy"), then immediately destroys the element
    • representation_fallback: binary item failures (e.g. image CORS block) degrade gracefully to copying the plain text source URL

security_and_sanitization:

  • dom_manipulation:
    • restriction: no dynamic manipulation of SVGs via innerHTML to prevent XSS vulnerabilities
    • mechanism: copy and success SVGs are pre-rendered into the dock DOM, toggled via CSS class selectors (e.g., adding .success to toggle visibility/display)
  • clipboard_payloads:
    • bytes_preservation: preserve exact code/text bytes without silently stripping hidden/non-printable control characters, backspaces, or carriage returns from copy payloads
    • shell_prompt_preservation: do not mutate copied code blocks by stripping leading $, #, or other shell prompts
    • validation_warnings: surface a non-destructive warning or require user confirmation via toast/modal if copied text contains malicious control characters, multiple hidden execution commands, or active shell prompts to prevent accidental terminal execution while keeping the exact payload intact
    • bounds: limits copied text payload to safe memory buffers

performance_boundaries:

  • event_binding: single event delegation listener bound to document.body or #quartz-body
  • DOM_management:
    • trigger: zero querySelectorAll calls on SPA transition navigation
    • layout: throttled geometry calculations using requestAnimationFrame to prevent layout thrashing and scroll lag
    • lifecycle: clean teardown of references on DOM unload to prevent memory leaks

feedback_and_ux:

  • visual_feedback: CSS transition class swap on the action dock button
  • success_indicator: button shows checkmark state for 2000ms, managed via a clearable setTimeout to handle rapid double clicks
  • error_handling:
    • fallback_ux: displays an overlay notification toast or a fallback text modal on write failures (instead of silent console failure), prompting manual copy

styling_and_media_rules:

  • print_isolation:
    • selector: #quartz-contextual-dock, .copy-button
    • rule: @media print { display: none !important } to guarantee no copy controls appear in printed output
  • focus_indicator:
    • selector: #quartz-contextual-dock button:focus
    • properties: outline: 2px solid var(--secondary) to ensure visible keyboard accessibility