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 displayeligible(element): predicate returning boolean if target is validexecute(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
- selector:
- 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)
- selector:
- 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
- selector:
- code_blocks:
- selector:
pre > code - copy_representation: exact innerText source code including shell prompts to preserve execution capability, excluding cosmetic line numbers
- selector:
- math_blocks:
- selector:
.math-display,.katex-display - copy_representation: original LaTeX source string extracted from
data-mathor KaTeX annotation fields
- selector:
- 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
- selector:
- tables:
- selector:
table - copy_representation: structured TSV (tab-separated values) or Markdown table syntax string
- selector:
- blockquotes_and_callouts:
- selector:
blockquote,.callout - copy_representation: standard Markdown syntax (e.g.,
> textor> [!info] text)
- selector:
- figures_and_captions:
- selector:
figure, figcaption - copy_representation: text content or markdown representation combining the figure source and the caption
- selector:
- inline_formatting:
- selector:
span, strong, em, code, mark, kbd - copy_representation: exact innerText of the inline element
- selector:
- details_and_summary:
- selector:
details, summary - copy_representation: combined plain text of disclosure summary title and collapsed/expanded details text content
- selector:
- images:
- selector:
img - copy_representation:
- rich_format: binary image blob (using
ClipboardItemfor PNG/JPEG) retrieved via async fetch (if CORS-safe) - fallback_format: falls back to copying the absolute source URL or markdown format
if binary copy fails
- rich_format: binary image blob (using
- selector:
- 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
- selector:
- embeds_and_media:
- selector:
iframe, embed, object, video, audio, .embed - copy_representation: absolute source URL, fallback stream URL, or HTML embedding source string
- selector:
- sections:
- selector:
section - copy_representation: full plaintext content of section nodes
- selector:
- whole_pages:
- selector:
article - copy_representation: full document content in raw Markdown or plaintext
- selector:
- 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
- selector:
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.
- rule: If there is an active window/document text selection (i.e.,
- priority_resolution:
- mechanism: runtime event delegation traverses from
event.targetupward via.closest() - rule: matches the most specific (innermost) eligible selector first
- mechanism: runtime event delegation traverses from
- 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"anddata-target-typeattributes
- tool: Rehype plugin with
- 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
MutationObserveron.mermaidblocks 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-dockto 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
- tab_index: dock buttons are keyboard-navigable via
clipboard_execution_and_fallbacks:
- protocol:
- primary: standard
navigator.clipboard.writeTextfor strings andnavigator.clipboard.writefor complex objects
- primary: standard
- 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, executesdocument.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
- secure_context_check: checks
security_and_sanitization:
- dom_manipulation:
- restriction: no dynamic manipulation of SVGs via
innerHTMLto prevent XSS vulnerabilities - mechanism: copy and success SVGs are pre-rendered into the dock DOM, toggled via CSS class selectors (e.g., adding
.successto toggle visibility/display)
- restriction: no dynamic manipulation of SVGs via
- 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.bodyor#quartz-body - DOM_management:
- trigger: zero querySelectorAll calls on SPA transition navigation
- layout: throttled geometry calculations using
requestAnimationFrameto 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
setTimeoutto 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
- selector:
- focus_indicator:
- selector:
#quartz-contextual-dock button:focus - properties:
outline: 2px solid var(--secondary)to ensure visible keyboard accessibility
- selector: