Skip to content

Commit 39b9846

Browse files
committed
Improve tab navigation
Closes freeCodeCamp#396.
1 parent 87ede1f commit 39b9846

12 files changed

Lines changed: 54 additions & 27 deletions

File tree

assets/javascripts/templates/pages/about_tmpl.coffee

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ app.templates.aboutPage = -> """
1515
<ul>
1616
<li>Created and maintained by <a href="http://thibaut.me">Thibaut Courouble</a>
1717
<li>Free and <a href="https://github.com/Thibaut/devdocs">open source</a>
18-
<iframe class="_github-btn" src="proxy.php?url=https%3A%2F%2Fghbtns.com%2Fgithub-btn.html%3Fuser%3DThibaut%26amp%3Brepo%3Ddevdocs%26amp%3Btype%3Dwatch%26amp%3Bcount%3Dtrue" allowtransparency="true" frameborder="0" scrolling="0" width="100" height="20"></iframe>
18+
<iframe class="_github-btn" src="proxy.php?url=https%3A%2F%2Fghbtns.com%2Fgithub-btn.html%3Fuser%3DThibaut%26amp%3Brepo%3Ddevdocs%26amp%3Btype%3Dwatch%26amp%3Bcount%3Dtrue" allowtransparency="true" frameborder="0" scrolling="0" width="100" height="20" tabindex="-1"></iframe>
1919
</ul>
2020
<p>To keep up-to-date with the latest news:
2121
<ul>

assets/javascripts/templates/pages/root_tmpl.coffee.erb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ app.templates.splash = """<div class="_splash-title">DevDocs</div>"""
33
<% if App.development? %>
44
app.templates.intro = """
55
<div class="_intro"><div class="_intro-message">
6-
<a class="_intro-hide" data-hide-intro>Stop showing this message</a>
6+
<a href="#" class="_intro-hide" data-hide-intro>Stop showing this message</a>
77
<h2 class="_intro-title">Hi there!</h2>
88
<p>Thanks for downloading DevDocs. Here are a few things you should know:
99
<ol class="_intro-list">
@@ -27,7 +27,7 @@ app.templates.intro = """
2727
<% else %>
2828
app.templates.intro = """
2929
<div class="_intro"><div class="_intro-message">
30-
<a class="_intro-hide" data-hide-intro>Stop showing this message</a>
30+
<a href="#" class="_intro-hide" data-hide-intro>Stop showing this message</a>
3131
<h2 class="_intro-title">Welcome!</h2>
3232
<p>DevDocs combines multiple API documentations in a fast, organized, and searchable interface.
3333
Here's what you should know before you start:

assets/javascripts/templates/sidebar_tmpl.coffee

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ templates = app.templates
33
templates.sidebarDoc = (doc, options = {}) ->
44
link = """<a href="#{doc.fullPath()}" class="_list-item _icon-#{doc.icon} """
55
link += if options.disabled then '_list-disabled' else '_list-dir'
6-
link += """" data-slug="#{doc.slug}" title="#{doc.fullName}">"""
6+
link += """" data-slug="#{doc.slug}" title="#{doc.fullName}" tabindex="-1">"""
77
if options.disabled
88
link += """<span class="_list-enable" data-enable="#{doc.slug}">Enable</span>"""
99
else
@@ -14,28 +14,28 @@ templates.sidebarDoc = (doc, options = {}) ->
1414
link + "</span></a>"
1515

1616
templates.sidebarType = (type) ->
17-
"""<a href="proxy.php?url=https%3A%2F%2Fgithub.com%2F%3Cspan+class%3D"pl-s1">#{type.fullPath()}" class="_list-item _list-dir" data-slug="#{type.slug}"><span class="_list-arrow"></span><span class="_list-count">#{type.count}</span><span class="_list-text">#{type.name}</span></a>"""
17+
"""<a href="proxy.php?url=https%3A%2F%2Fgithub.com%2F%3Cspan+class%3D"pl-s1">#{type.fullPath()}" class="_list-item _list-dir" data-slug="#{type.slug}" tabindex="-1"><span class="_list-arrow"></span><span class="_list-count">#{type.count}</span><span class="_list-text">#{type.name}</span></a>"""
1818

1919
templates.sidebarEntry = (entry) ->
20-
"""<a href="proxy.php?url=https%3A%2F%2Fgithub.com%2F%3Cspan+class%3D"pl-s1">#{entry.fullPath()}" class="_list-item _list-hover">#{$.escape entry.name}</a>"""
20+
"""<a href="proxy.php?url=https%3A%2F%2Fgithub.com%2F%3Cspan+class%3D"pl-s1">#{entry.fullPath()}" class="_list-item _list-hover" tabindex="-1">#{$.escape entry.name}</a>"""
2121

2222
templates.sidebarResult = (entry) ->
2323
addons = if entry.isIndex() and app.disabledDocs.contains(entry.doc)
2424
"""<span class="_list-enable" data-enable="#{entry.doc.slug}">Enable</span>"""
2525
else
2626
"""<span class="_list-reveal" data-reset-list title="Reveal in list"></span>"""
2727
addons += """<span class="_list-count">#{entry.doc.short_version}</span>""" if entry.doc.version and not entry.isIndex()
28-
"""<a href="proxy.php?url=https%3A%2F%2Fgithub.com%2F%3Cspan+class%3D"pl-s1">#{entry.fullPath()}" class="_list-item _list-hover _list-result _icon-#{entry.doc.icon}">#{addons}<span class="_list-text">#{$.escape entry.name}</span></a>"""
28+
"""<a href="proxy.php?url=https%3A%2F%2Fgithub.com%2F%3Cspan+class%3D"pl-s1">#{entry.fullPath()}" class="_list-item _list-hover _list-result _icon-#{entry.doc.icon}" tabindex="-1">#{addons}<span class="_list-text">#{$.escape entry.name}</span></a>"""
2929

3030
templates.sidebarNoResults = ->
3131
html = """ <div class="_list-note">No results.</div> """
3232
html += """
33-
<div class="_list-note">Note: documentations must be <a class="_list-note-link" data-pick-docs>enabled</a> to appear in the search.</div>
33+
<div class="_list-note">Note: documentations must be <a href="#" class="_list-note-link" data-pick-docs>enabled</a> to appear in the search.</div>
3434
""" unless app.isSingleDoc() or app.disabledDocs.isEmpty()
3535
html
3636

3737
templates.sidebarPageLink = (count) ->
38-
"""<span class="_list-item _list-pagelink">Show more\u2026 (#{count})</span>"""
38+
"""<span role="link" class="_list-item _list-pagelink">Show more\u2026 (#{count})</span>"""
3939

4040
templates.sidebarLabel = (doc, options = {}) ->
4141
label = """<label class="_list-item"""
@@ -47,7 +47,7 @@ templates.sidebarLabel = (doc, options = {}) ->
4747
templates.sidebarVersionedDoc = (doc, versions, options = {}) ->
4848
html = """<div class="_list-item _list-dir _list-rdir _icon-#{doc.icon}"""
4949
html += " open" if options.open
50-
html + """"><span class="_list-arrow"></span>#{doc.name}</div><div class="_list _list-sub">#{versions}</div>"""
50+
html + """" tabindex="0"><span class="_list-arrow"></span>#{doc.name}</div><div class="_list _list-sub">#{versions}</div>"""
5151

5252
templates.sidebarDisabled = (options) ->
5353
"""<h6 class="_list-title"><span class="_list-arrow"></span>Disabled (#{options.count})</h6>"""
@@ -56,7 +56,7 @@ templates.sidebarDisabledList = (html) ->
5656
"""<div class="_disabled-list">#{html}</div>"""
5757

5858
templates.sidebarDisabledVersionedDoc = (doc, versions) ->
59-
"""<a class="_list-item _list-dir _icon-#{doc.icon} _list-disabled" data-slug="#{doc.slug_without_version}"><span class="_list-arrow"></span>#{doc.name}</a><div class="_list _list-sub">#{versions}</div>"""
59+
"""<a class="_list-item _list-dir _icon-#{doc.icon} _list-disabled" data-slug="#{doc.slug_without_version}" tabindex="-1"><span class="_list-arrow"></span>#{doc.name}</a><div class="_list _list-sub">#{versions}</div>"""
6060

6161
templates.sidebarPickerNote = """
6262
<div class="_list-note">Tip: for faster and better search results, select only the docs you need.</div>
@@ -67,9 +67,9 @@ sidebarFooter = (html) -> """<div class="_sidebar-footer">#{html}</div>"""
6767

6868
templates.sidebarSettings = ->
6969
sidebarFooter """
70+
<button type="button" class="_sidebar-footer-link _sidebar-footer-edit" data-pick-docs>Select documentation</button>
7071
<button type="button" class="_sidebar-footer-link _sidebar-footer-light" title="Toggle light" data-light>Toggle light</button>
7172
<button type="button" class="_sidebar-footer-link _sidebar-footer-layout" title="Toggle layout" data-layout>Toggle layout</button>
72-
<a href="#" class="_sidebar-footer-link _sidebar-footer-edit" data-pick-docs>Select documentation</a>
7373
"""
7474

7575
templates.sidebarSave = ->

assets/javascripts/views/layout/nav.coffee

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@ class app.views.Nav extends app.View
99
@deselect()
1010
if @current = @find "a[href='#{href}']"
1111
@current.classList.add @constructor.activeClass
12+
@current.setAttribute 'tabindex', '-1'
1213
return
1314

1415
deselect: ->
1516
if @current
1617
@current.classList.remove @constructor.activeClass
18+
@current.removeAttribute 'tabindex'
1719
@current = null
1820
return
1921

assets/javascripts/views/search/search_scope.coffee

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,11 @@ class app.views.SearchScope extends app.View
8484
if @doc and not @input.value
8585
$.stopEvent(event)
8686
@reset()
87-
else if event.which is 9 or # tab
88-
event.which is 32 and (app.isMobile() or $.isTouchScreen()) # space
89-
$.stopEvent(event)
90-
@search @input.value[0...@input.selectionStart]
87+
else if not @doc and @input.value
88+
if event.which is 9 or # tab
89+
event.which is 32 and (app.isMobile() or $.isTouchScreen()) # space
90+
@search @input.value[0...@input.selectionStart]
91+
$.stopEvent(event) if @doc
9192
return
9293

9394
extractHashValue: ->

assets/javascripts/views/sidebar/doc_picker.coffee

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@ class app.views.DocPicker extends app.View
2121
@render()
2222
@findByTag('input')?.focus()
2323
app.appCache?.on 'progress', @onAppCacheProgress
24-
$.on @el, 'focus', @onFocus, true
24+
$.on @el, 'focus', @onDOMFocus, true
2525
return
2626

2727
deactivate: ->
2828
if super
2929
@empty()
3030
app.appCache?.off 'progress', @onAppCacheProgress
31-
$.off @el, 'focus', @onFocus, true
31+
$.off @el, 'focus', @onDOMFocus, true
3232
return
3333

3434
render: ->
@@ -84,14 +84,27 @@ class app.views.DocPicker extends app.View
8484
input.name
8585

8686
onClick: (event) =>
87+
if @focusTimeout
88+
clearTimeout @focusTimeout
89+
@focusTimeout = null
8790
return if event.which isnt 1
8891
if event.target is @saveLink
8992
$.stopEvent(event)
9093
@save()
9194
return
9295

93-
onFocus: (event) ->
94-
$.scrollTo event.target.parentNode, null, 'continuous', bottomGap: 2
96+
onDOMFocus: (event) =>
97+
target = event.target
98+
if target.tagName is 'INPUT'
99+
$.scrollTo target.parentNode, null, 'continuous', bottomGap: 2
100+
else if target.classList.contains(app.views.ListFold.targetClass)
101+
target.blur()
102+
@focusTimeout = setTimeout =>
103+
@listFold.open(target) unless target.classList.contains(app.views.ListFold.activeClass)
104+
$('input', target.nextElementSibling).focus()
105+
@focusTimeout = null
106+
, 10
107+
return
95108

96109
onEnter: =>
97110
@save()

assets/javascripts/views/sidebar/sidebar.coffee

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,11 @@ class app.views.Sidebar extends app.View
101101
@reset()
102102
else if event.target.hasAttribute? 'data-light'
103103
$.stopEvent(event)
104+
document.activeElement?.blur()
104105
app.document.toggleLight()
105106
else if event.target.hasAttribute? 'data-layout'
106107
$.stopEvent(event)
108+
document.activeElement?.blur()
107109
app.document.toggleLayout()
108110
return
109111

assets/stylesheets/components/_header.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313
background: $headerBackground;
1414
border-bottom: 1px solid $headerBorder;
1515
@extend %user-select-none;
16-
17-
a:focus { outline: 0; }
1816
}
1917

2018
//
@@ -58,6 +56,8 @@
5856
}
5957

6058
._nav-current {
59+
outline: 0;
60+
6161
&:before, &:after { content: ''; }
6262
}
6363

assets/stylesheets/components/_sidebar.scss

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@
3232
}
3333
}
3434

35-
a:focus { outline: 0; }
36-
3735
._sidebar-hidden & {
3836
display: none;
3937
}
@@ -88,6 +86,8 @@
8886
min-height: 100%;
8987
padding-bottom: 3.5rem;
9088
}
89+
90+
a:focus { outline: 0; }
9191
}
9292

9393
._list-title {
@@ -422,6 +422,8 @@
422422
}
423423

424424
._sidebar-footer-edit {
425+
display: inline-block;
426+
425427
@if $style == 'dark' {
426428
&:before { @extend %icon-settings-white; }
427429
} @else {

assets/stylesheets/global/_base.scss

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@ td {
159159
> pre:last-child, > p:last-child, > ul:last-child, > ol:last-child { margin-bottom: 0; }
160160
}
161161

162+
section, main { outline: 0; }
163+
162164
input, button {
163165
margin: 0;
164166
font-family: inherit;
@@ -179,6 +181,11 @@ button, input[type="search"] {
179181
-moz-appearance: none;
180182
}
181183

184+
button:focus {
185+
outline: 1px dotted;
186+
outline: -webkit-focus-ring-color auto 5px;
187+
}
188+
182189
input[type="search"]::-webkit-search-cancel-button,
183190
input[type="search"]::-webkit-search-decoration {
184191
-webkit-appearance: none;

0 commit comments

Comments
 (0)