Skip to content

Commit 99cdf16

Browse files
committed
Open homepage destinations in new tabs consistently
1 parent fa0b2f0 commit 99cdf16

4 files changed

Lines changed: 91 additions & 37 deletions

File tree

IMPLEMENTATION-NOTES.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,32 @@ while preserving the homepage. The mobile menu still closed after activation,
103103
with no horizontal overflow. Source/reduced-motion checks and HTML validation
104104
passed; the only console warning was the existing analytics localhost notice.
105105

106+
### Homepage-wide destination links — 2026-08-30
107+
108+
Starting from `fa0b2f09142996aff27ba2eb1eee6054c815d202`, all 43 homepage links
109+
to other pages now open new tabs, including Explore themes, the announcement,
110+
system/CLI links, mobile navigation, community, footer credits and all five
111+
video posters. Each uses `target="_blank"`, `rel="noopener noreferrer"` and an
112+
accessible new-tab announcement. Existing CTA arrows point diagonally where
113+
appropriate. All 57 original anchor destinations are unchanged.
114+
115+
The three ISO anchors remain byte-for-byte unchanged. The ten home/section
116+
navigation links stay in the current tab, and the email link retains native
117+
mail-handler behavior. This policy is scoped to the redesigned homepage, not
118+
the inherited manual or other secondary pages. The introduction poster no
119+
longer opts into the inline player, so its click opens YouTube consistently
120+
with the other four videos. No JavaScript or CSS changes were required.
121+
122+
`bin/check` now audits the complete homepage link policy, including the native
123+
exceptions and prevention of inline-video interception. Source, HTML and
124+
reduced-motion checks passed. A browser DOM audit found no policy violations.
125+
Explore themes opened separate tabs at 1440px and 390px; desktop section
126+
navigation stayed in place, the introduction video opened YouTube without an
127+
inline iframe, and mobile Security opened separately while closing the menu.
128+
The homepage remained open throughout, with no horizontal overflow. The only
129+
console warning was the existing analytics localhost notice. ISO downloads
130+
and the email application were deliberately not activated during testing.
131+
106132
### Push-to-deploy automation — 2026-08-30
107133

108134
Starting from `f728d6ab0d47da60b49269affa7cced2d2bd94e7`, the existing validation

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ development tool, not a production server.
4343
- All content and links remain available without JavaScript.
4444
- Reduced-motion support, keyboard navigation and visible focus states.
4545
- Responsive layouts verified at 1440px and 390px, with intermediate checks.
46-
- Video posters load a player only after activation; other videos remain links.
46+
- All five video posters open YouTube in a new tab; no player loads on the homepage.
47+
- Homepage destination links open new tabs; ISO downloads, home/section navigation
48+
and email links retain their native behavior.
4749

4850
The main changes are in `index.html`, `assets/css/home.css`, and
4951
`assets/js/modules/home.js`. Existing public routes and upstream history remain.

bin/check

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,32 @@ Dir.chdir(root) do
5959

6060
hrefs = tags.filter_map { |name, attributes| attributes["href"] if name == "a" }
6161
abort "Homepage has an empty or JavaScript-only link" if hrefs.any? { |href| href.empty? || href.match?(/\Ajavascript:/i) }
62+
63+
# A single homepage-wide policy prevents isolated CTA/footer regressions.
64+
link_counts = Hash.new(0)
65+
tags.select { |name, _attributes| name == "a" }.each do |_name, link|
66+
href = link.fetch("href", "")
67+
kind = if href.match?(%r{\Ahttps://iso\.omarchy\.org/[^?#]+\.iso(?:[?#].*)?\z})
68+
:iso
69+
elsif href == "/" || href.start_with?("#")
70+
:same_page
71+
elsif href.start_with?("mailto:")
72+
:email
73+
else
74+
:destination
75+
end
76+
link_counts[kind] += 1
77+
78+
if kind == :destination
79+
abort "Destination must open a safe new tab: #{href}" unless link["target"] == "_blank" && (%w[noopener noreferrer] - link.fetch("rel", "").split).empty?
80+
abort "Missing new-tab accessibility hint: #{href}" unless link.fetch("aria-label", "").include?("opens in a new tab")
81+
abort "A new-tab destination must not activate an inline video: #{href}" if link.key?("data-video")
82+
else
83+
abort "Keep #{kind} link behavior unchanged: #{href}" if link.key?("target")
84+
end
85+
end
86+
puts "PASS: all #{link_counts[:destination]} homepage destinations open safe, labeled new tabs; #{link_counts[:iso]} ISO downloads, #{link_counts[:same_page]} home/section links and #{link_counts[:email]} email link retain native behavior."
87+
6288
resources = tags.flat_map { |_name, attributes| attributes.values_at("href", "src") }.compact
6389
local_paths = resources.select { |value| value.start_with?("/") && !value.start_with?("//") }.map { |value| value.split(/[?#]/, 2).first }.uniq
6490
local_paths.each do |path|

0 commit comments

Comments
 (0)