History

UI improvements

Thibaut Courouble committed 9 years ago

Commit 0f238601 parent fd03ac139 files · +295 −334Browse files

Unified · Split

39 files
  1. assets/images/icons.png +0 −0
  2. assets/images/icons@2x.png +0 −0
  3. assets/javascripts/templates/pages/about_tmpl.coffee +6 −6
  4. assets/javascripts/templates/pages/help_tmpl.coffee +5 −3
  5. assets/javascripts/templates/pages/news_tmpl.coffee.erb +1 −1
  6. assets/javascripts/templates/pages/offline_tmpl.coffee +1 −1
  7. assets/javascripts/templates/pages/root_tmpl.coffee.erb +0 −9
  8. assets/javascripts/views/content/root_page.coffee +0 −1
  9. assets/javascripts/views/layout/document.coffee +11 −37
  10. assets/javascripts/views/layout/menu.coffee +24 −0
  11. assets/javascripts/views/layout/mobile.coffee +17 −18
  12. assets/javascripts/views/layout/nav.coffee +0 −26
  13. assets/javascripts/views/layout/resizer.coffee +1 −1
  14. assets/javascripts/views/list/list_focus.coffee +6 −6
  15. assets/javascripts/views/misc/notice.coffee +0 −1
  16. assets/javascripts/views/search/search.coffee +1 −1
  17. assets/javascripts/views/sidebar/doc_list.coffee +1 −1
  18. assets/javascripts/views/sidebar/results.coffee +2 −2
  19. assets/javascripts/views/sidebar/sidebar.coffee +41 −14
  20. assets/javascripts/views/view.coffee +7 −0
  21. assets/stylesheets/components/_app.scss +2 −3
  22. assets/stylesheets/components/_content.scss +29 −14
  23. assets/stylesheets/components/_header.scss +104 −51
  24. assets/stylesheets/components/_mobile.scss +14 −108
  25. assets/stylesheets/components/_notice.scss +1 −11
  26. assets/stylesheets/components/_sidebar.scss +1 −1
  27. assets/stylesheets/global/_icons.scss +0 −3
  28. assets/stylesheets/global/_variables-dark.scss +2 −2
  29. assets/stylesheets/global/_variables.scss +4 −4
  30. lib/app.rb +1 −1
  31. public/icons/ui/back/16.png +0 −0
  32. public/icons/ui/back/16@2x.png +0 −0
  33. public/icons/ui/home/16.png +0 −0
  34. public/icons/ui/home/16@2x.png +0 −0
  35. public/icons/ui/home/SOURCE +0 −1
  36. public/icons/ui/menu/16.png +0 −0
  37. public/icons/ui/menu/16@2x.png +0 −0
  38. test/app_test.rb +2 −2
  39. views/app.erb +19 −13
assets/images/icons.png+0−0

Binary file not shown.

assets/images/icons@2x.png+0−0

Binary file not shown.

assets/javascripts/templates/pages/about_tmpl.coffee+6−6
@@ -10,7 +10,7 @@ app.templates.aboutPage = -> """ · 9 unmodified lines
10 </ul>10 </ul>
11 </nav>11 </nav>
12 12
13 <h1 class="_lined-heading">API Documentation Browser</h1>13 <h1 class="_lined-heading">DevDocs: API Documentation Browser</h1>
14 <p>DevDocs combines multiple API documentations in a fast, organized, and searchable interface.14 <p>DevDocs combines multiple API documentations in a fast, organized, and searchable interface.
15 <ul>15 <ul>
16 <li>Created and maintained by <a href="http://thibaut.me">Thibaut Courouble</a>16 <li>Created and maintained by <a href="http://thibaut.me">Thibaut Courouble</a>
@@ -26,7 +26,7 @@ app.templates.aboutPage = -> """ · 9 unmodified lines
26 <p class="_note _note-green">If you like DevDocs, please consider supporting my work on26 <p class="_note _note-green">If you like DevDocs, please consider supporting my work on
27 <a href="https://gratipay.com/devdocs/">Gratipay</a>. Thanks!<br>27 <a href="https://gratipay.com/devdocs/">Gratipay</a>. Thanks!<br>
28 28
29 <h2 class="_lined-heading" id="credits">Credits</h2>29 <h2 class="_block-heading" id="credits">Credits</h2>
30 30
31 <p><strong>Special thanks to:</strong>31 <p><strong>Special thanks to:</strong>
32 <ul>32 <ul>
@@ -45,7 +45,7 @@ app.templates.aboutPage = -> """ · 12 unmodified lines
45 #{("<tr><td>#{c[0]}<td>&copy; #{c[1]}<td><a href=\"#{c[3]}\">#{c[2]}</a>" for c in credits).join('')}45 #{("<tr><td>#{c[0]}<td>&copy; #{c[1]}<td><a href=\"#{c[3]}\">#{c[2]}</a>" for c in credits).join('')}
46 </table>46 </table>
47 47
48 <h2 class="_lined-heading" id="faq">Questions & Answers</h2>48 <h2 class="_block-heading" id="faq">Questions & Answers</h2>
49 <dl>49 <dl>
50 <dt>Where can I suggest new docs and features?50 <dt>Where can I suggest new docs and features?
51 <dd>You can suggest and vote for new docs on the <a href="https://trello.com/b/6BmTulfx/devdocs-documentation">Trello board</a>.<br>51 <dd>You can suggest and vote for new docs on the <a href="https://trello.com/b/6BmTulfx/devdocs-documentation">Trello board</a>.<br>
@@ -56,7 +56,7 @@ app.templates.aboutPage = -> """ · 4 unmodified lines
56 </dl>56 </dl>
57 <p>For anything else, feel free to email me at <a href="mailto:thibaut@devdocs.io">thibaut@devdocs.io</a>.57 <p>For anything else, feel free to email me at <a href="mailto:thibaut@devdocs.io">thibaut@devdocs.io</a>.
58 58
59 <h2 class="_lined-heading" id="copyright">Copyright and License</h2>59 <h2 class="_block-heading" id="copyright">Copyright and License</h2>
60 <p class="_note">60 <p class="_note">
61 <strong>Copyright 2013&ndash;2017 Thibaut Courouble and <a href="https://github.com/Thibaut/devdocs/graphs/contributors">other contributors</a></strong><br>61 <strong>Copyright 2013&ndash;2017 Thibaut Courouble and <a href="https://github.com/Thibaut/devdocs/graphs/contributors">other contributors</a></strong><br>
62 This software is licensed under the terms of the Mozilla Public License v2.0.<br>62 This software is licensed under the terms of the Mozilla Public License v2.0.<br>
@@ -64,7 +64,7 @@ app.templates.aboutPage = -> """ · 1 unmodified line
64 For more information, see the <a href="https://github.com/Thibaut/devdocs/blob/master/COPYRIGHT">COPYRIGHT</a>64 For more information, see the <a href="https://github.com/Thibaut/devdocs/blob/master/COPYRIGHT">COPYRIGHT</a>
65 and <a href="https://github.com/Thibaut/devdocs/blob/master/LICENSE">LICENSE</a> files.65 and <a href="https://github.com/Thibaut/devdocs/blob/master/LICENSE">LICENSE</a> files.
66 66
67 <h2 class="_lined-heading" id="plugins">Plugins and Extensions</h2>67 <h2 class="_block-heading" id="plugins">Plugins and Extensions</h2>
68 <ul>68 <ul>
69 <li><a href="https://chrome.google.com/webstore/detail/devdocs/mnfehgbmkapmjnhcnbodoamcioleeooe">Chrome web app</a>69 <li><a href="https://chrome.google.com/webstore/detail/devdocs/mnfehgbmkapmjnhcnbodoamcioleeooe">Chrome web app</a>
70 <li><a href="https://sublime.wbond.net/packages/DevDocs">Sublime Text plugin</a>70 <li><a href="https://sublime.wbond.net/packages/DevDocs">Sublime Text plugin</a>
@@ -73,7 +73,7 @@ app.templates.aboutPage = -> """ · 2 unmodified lines
73 <li><a href="https://github.com/xuchunyang/DevDocs.el">Emacs Package</a>73 <li><a href="https://github.com/xuchunyang/DevDocs.el">Emacs Package</a>
74 </ul>74 </ul>
75 75
76 <h2 class="_lined-heading" id="privacy">Privacy Policy</h2>76 <h2 class="_block-heading" id="privacy">Privacy Policy</h2>
77 <ul>77 <ul>
78 <li><a href="http://devdocs.io">devdocs.io</a> ("App") is operated by Thibaut Courouble ("We").78 <li><a href="http://devdocs.io">devdocs.io</a> ("App") is operated by Thibaut Courouble ("We").
79 <li>We do not collect personal information.79 <li>We do not collect personal information.
assets/javascripts/templates/pages/help_tmpl.coffee+5−3
@@ -11,7 +11,9 @@ app.templates.helpPage = """ · 10 unmodified lines
11 </ul>11 </ul>
12 </nav>12 </nav>
13 13
14 <h2 class="_lined-heading" id="search">Search</h2>14 <h1 class="_lined-heading" id="search">Help</h2>
15
16 <h2 class="_block-heading" id="search">Search</h2>
15 <p>17 <p>
16 The search is case-insensitive and supports fuzzy matching (for queries longer than two characters).18 The search is case-insensitive and supports fuzzy matching (for queries longer than two characters).
17 For example, searching <code class="_label">bgcp</code> brings up <code class="_label">background-clip</code>.<br>19 For example, searching <code class="_label">bgcp</code> brings up <code class="_label">background-clip</code>.<br>
@@ -42,7 +44,7 @@ app.templates.helpPage = """ · 24 unmodified lines
42 <a href="https://support.mozilla.org/en-US/kb/how-search-from-address-bar">these instructions</a>.44 <a href="https://support.mozilla.org/en-US/kb/how-search-from-address-bar">these instructions</a>.
43 </dl>45 </dl>
44 46
45 <h2 class="_lined-heading" id="shortcuts">Keyboard Shortcuts</h2>47 <h2 class="_block-heading" id="shortcuts">Keyboard Shortcuts</h2>
46 <h3 class="_shortcuts-title">Selection</h3>48 <h3 class="_shortcuts-title">Selection</h3>
47 <dl class="_shortcuts-dl">49 <dl class="_shortcuts-dl">
48 <dt class="_shortcuts-dt">50 <dt class="_shortcuts-dt">
@@ -110,7 +112,7 @@ app.templates.helpPage = """ · 61 unmodified lines
110 <strong>Tip:</strong> If the cursor is no longer in the search field, press <code class="_label">/</code> or112 <strong>Tip:</strong> If the cursor is no longer in the search field, press <code class="_label">/</code> or
111 continue to type and it will refocus the search field and start showing new results.113 continue to type and it will refocus the search field and start showing new results.
112 114
113 <h2 class="_lined-heading" id="abbreviations">Abbreviations</h2>115 <h2 class="_block-heading" id="abbreviations">Abbreviations</h2>
114 <p>Feel free to suggest new abbreviations on <a href="https://github.com/Thibaut/devdocs/issues/new">GitHub</a>.116 <p>Feel free to suggest new abbreviations on <a href="https://github.com/Thibaut/devdocs/issues/new">GitHub</a>.
115 <table class="_abbreviations">117 <table class="_abbreviations">
116 <tr>118 <tr>
assets/javascripts/templates/pages/news_tmpl.coffee.erb+1−1
@@ -15,7 +15,7 @@ app.templates.newsList = (news, options = {}) -> · 14 unmodified lines
15 date = new Date(value[0])15 date = new Date(value[0])
16 if options.years isnt false and year isnt date.getUTCFullYear()16 if options.years isnt false and year isnt date.getUTCFullYear()
17 year = date.getUTCFullYear()17 year = date.getUTCFullYear()
18 result += "<h4>#{year}</h4>"18 result += """<h2 class="_block-heading">#{year}</h2>"""
19 result += newsItem(date, value[1..])19 result += newsItem(date, value[1..])
20 20
21 result21 result
assets/javascripts/templates/pages/offline_tmpl.coffee+1−1
@@ -21,7 +21,7 @@ app.templates.offlinePage = (docs) -> """ · 20 unmodified lines
21 #{docs}21 #{docs}
22 </table>22 </table>
23 <p class="_note"><strong>Note:</strong> your browser may delete DevDocs's offline data if your computer is running low on disk space and you haven't used the app in a while. Load this page before going offline to make sure the data is still there.23 <p class="_note"><strong>Note:</strong> your browser may delete DevDocs's offline data if your computer is running low on disk space and you haven't used the app in a while. Load this page before going offline to make sure the data is still there.
24 <h1 class="_lined-heading">Questions & Answers</h1>24 <h2 class="_block-heading">Questions & Answers</h2>
25 <dl>25 <dl>
26 <dt>How does this work?26 <dt>How does this work?
27 <dd>Each page is cached as a key-value pair in <a href="https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API">IndexedDB</a> (downloaded from a single file).<br>27 <dd>Each page is cached as a key-value pair in <a href="https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API">IndexedDB</a> (downloaded from a single file).<br>
assets/javascripts/templates/pages/root_tmpl.coffee.erb+0−9
@@ -48,15 +48,6 @@ app.templates.intro = """ · 47 unmodified lines
48"""48"""
49<% end %>49<% end %>
50 50
51app.templates.mobileNav = """
52 <nav class="_mobile-nav">
53 <a href="/offline" class="_mobile-nav-link">Offline</a>
54 <a href="/about" class="_mobile-nav-link">About</a>
55 <a href="/news" class="_mobile-nav-link">News</a>
56 <a href="/help" class="_mobile-nav-link">Help</a>
57 </nav>
58"""
59
60app.templates.mobileIntro = """51app.templates.mobileIntro = """
61 <div class="_mobile-intro">52 <div class="_mobile-intro">
62 <h2 class="_intro-title">Welcome!</h2>53 <h2 class="_intro-title">Welcome!</h2>
assets/javascripts/views/content/root_page.coffee+0−1
@@ -9,7 +9,6 @@ class app.views.RootPage extends app.View · 8 unmodified lines
9 9
10 render: ->10 render: ->
11 @empty()11 @empty()
12 @append @tmpl('mobileNav') if app.isMobile()
13 if app.isAndroidWebview()12 if app.isAndroidWebview()
14 @append @tmpl('androidWarning')13 @append @tmpl('androidWarning')
15 else14 else
assets/javascripts/views/layout/document.coffee+11−37
@@ -1,6 +1,6 @@
1class app.views.Document extends app.View1class app.views.Document extends app.View
2 MAX_WIDTH_CLASS = '_max-width'2 MAX_WIDTH_LAYOUT = '_max-width'
3 HIDE_SIDEBAR_CLASS = '_sidebar-hidden'3 SIDEBAR_HIDDEN_LAYOUT = '_sidebar-hidden'
4 4
5 @el: document5 @el: document
6 6
@@ -14,16 +14,12 @@ class app.views.Document extends app.View · 7 unmodified lines
14 superRight: 'onForward'14 superRight: 'onForward'
15 15
16 init: ->16 init: ->
17 @addSubview @nav = new app.views.Nav,17 @addSubview @menu = new app.views.Menu,
18 @addSubview @sidebar = new app.views.Sidebar18 @addSubview @sidebar = new app.views.Sidebar
19 @addSubview @resizer = new app.views.Resizer if app.views.Resizer.isSupported()19 @addSubview @resizer = new app.views.Resizer if app.views.Resizer.isSupported()
20 @addSubview @content = new app.views.Content20 @addSubview @content = new app.views.Content
21 @addSubview @path = new app.views.Path unless app.isSingleDoc() or app.isMobile()21 @addSubview @path = new app.views.Path unless app.isSingleDoc() or app.isMobile()
22 22
23 @sidebar.search
24 .on 'searching', @onSearching
25 .on 'clear', @onSearchClear
26
27 $.on document.body, 'click', @onClick23 $.on document.body, 'click', @onClick
28 24
29 @activate()25 @activate()
@@ -39,39 +35,17 @@ class app.views.Document extends app.View · 9 unmodified lines
39 return35 return
40 36
41 toggleLayout: ->37 toggleLayout: ->
42 wantsMaxWidth = !app.el.classList.contains(MAX_WIDTH_CLASS)38 wantsMaxWidth = !app.el.classList.contains(MAX_WIDTH_LAYOUT)
43 app.el.classList[if wantsMaxWidth then 'add' else 'remove'](MAX_WIDTH_CLASS)39 app.el.classList[if wantsMaxWidth then 'add' else 'remove'](MAX_WIDTH_LAYOUT)
44 app.settings.setLayout(MAX_WIDTH_CLASS, wantsMaxWidth)40 app.settings.setLayout(MAX_WIDTH_LAYOUT, wantsMaxWidth)
45 app.appCache?.updateInBackground()41 app.appCache?.updateInBackground()
46 return42 return
47 43
48 showSidebar: (options = {}) ->44 toggleSidebarLayout: ->
49 @toggleSidebar(options, true)45 shouldHide = !app.settings.hasLayout(SIDEBAR_HIDDEN_LAYOUT)
50 return46 app.el.classList[if shouldHide then 'add' else 'remove'](SIDEBAR_HIDDEN_LAYOUT)
51 47 app.settings.setLayout(SIDEBAR_HIDDEN_LAYOUT, shouldHide)
52 hideSidebar: (options = {}) ->48 app.appCache?.updateInBackground()
53 @toggleSidebar(options, false)
54 return
55
56 toggleSidebar: (options = {}, shouldShow) ->
57 shouldShow ?= if options.save then !@hasSidebar() else app.el.classList.contains(HIDE_SIDEBAR_CLASS)
58 app.el.classList[if shouldShow then 'remove' else 'add'](HIDE_SIDEBAR_CLASS)
59 if options.save
60 app.settings.setLayout(HIDE_SIDEBAR_CLASS, !shouldShow)
61 app.appCache?.updateInBackground()
62 return
63
64 hasSidebar: ->
65 !app.settings.hasLayout(HIDE_SIDEBAR_CLASS)
66
67 onSearching: =>
68 unless @hasSidebar()
69 @showSidebar()
70 return
71
72 onSearchClear: =>
73 unless @hasSidebar()
74 @hideSidebar()
75 return49 return
76 50
77 setTitle: (title) ->51 setTitle: (title) ->
assets/javascripts/views/layout/menu.coffee+24−0
@@ -0,0 +1,24 @@
1class app.views.Menu extends app.View
2 @el: '._menu'
3 @activeClass: 'active'
4
5 @events:
6 click: 'onClick'
7
8 init: ->
9 $.on document.body, 'click', @onGlobalClick
10 return
11
12 onClick: =>
13 prev = @el.previousElementSibling
14 $.remove @el
15 $.requestAnimationFrame => $.after(prev, @el)
16 return
17
18 onGlobalClick: (event) =>
19 return if event.which isnt 1
20 if event.target.hasAttribute?('data-toggle-menu')
21 @toggleClass @constructor.activeClass
22 else if @hasClass @constructor.activeClass
23 @removeClass @constructor.activeClass
24 return
assets/javascripts/views/layout/mobile.coffee+17−18
@@ -35,44 +35,48 @@ class app.views.Mobile extends app.View · 34 unmodified lines
35 FastClick.attach @body35 FastClick.attach @body
36 36
37 $.on @body, 'click', @onClick37 $.on @body, 'click', @onClick
38 $.on $('._home-btn'), 'click', @onClickHome
39 $.on $('._menu-btn'), 'click', @onClickMenu
40 $.on $('._search'), 'touchend', @onTapSearch38 $.on $('._search'), 'touchend', @onTapSearch
41 39
42 @back = $('._back-btn')40 @toggleSidebar = $('button[data-toggle-sidebar]')
41 @toggleSidebar.removeAttribute('hidden')
42 $.on @toggleSidebar, 'click', @onClickToggleSidebar
43
44 @back = $('button[data-back]')
45 @back.removeAttribute('hidden')
43 $.on @back, 'click', @onClickBack46 $.on @back, 'click', @onClickBack
44 47
45 @forward = $('._forward-btn')48 @forward = $('button[data-forward]')
49 @forward.removeAttribute('hidden')
46 $.on @forward, 'click', @onClickForward50 $.on @forward, 'click', @onClickForward
47 51
48 app.document.sidebar.search52 app.document.sidebar.search
49 .on 'searching', @showSidebar53 .on 'searching', @showSidebar
50 .on 'clear', @hideSidebar
51 54
52 @activate()55 @activate()
53 return56 return
54 57
55 showSidebar: =>58 showSidebar: =>
56 if @isSidebarShown()59 if @isSidebarShown()
57 @body.scrollTop = 060 window.scrollTo 0, 0
58 return61 return
59 62
60 @contentTop = @body.scrollTop63 @contentTop = window.scrollY
61 @content.style.display = 'none'64 @content.style.display = 'none'
62 @sidebar.style.display = 'block'65 @sidebar.style.display = 'block'
63 66
64 if selection = @findByClass app.views.ListSelect.activeClass67 if selection = @findByClass app.views.ListSelect.activeClass
65 $.scrollTo selection, @body, 'center'68 scrollContainer = if window.scrollY is @body.scrollTop then @body else document.documentElement
69 $.scrollTo selection, scrollContainer, 'center'
66 else70 else
67 @body.scrollTop = @findByClass(app.views.ListFold.activeClass) and @sidebarTop or 071 window.scrollTo 0, @findByClass(app.views.ListFold.activeClass) and @sidebarTop or 0
68 return72 return
69 73
70 hideSidebar: =>74 hideSidebar: =>
71 return unless @isSidebarShown()75 return unless @isSidebarShown()
72 @sidebarTop = @body.scrollTop76 @sidebarTop = window.scrollY
73 @sidebar.style.display = 'none'77 @sidebar.style.display = 'none'
74 @content.style.display = 'block'78 @content.style.display = 'block'
75 @body.scrollTop = @contentTop or 079 window.scrollTo 0, @contentTop or 0
76 return80 return
77 81
78 isSidebarShown: ->82 isSidebarShown: ->
@@ -89,17 +93,12 @@ class app.views.Mobile extends app.View · 10 unmodified lines
89 onClickForward: =>93 onClickForward: =>
90 history.forward()94 history.forward()
91 95
92 onClickHome: =>96 onClickToggleSidebar: =>
93 app.shortcuts.trigger 'escape'
94 @hideSidebar()
95 return
96
97 onClickMenu: =>
98 if @isSidebarShown() then @hideSidebar() else @showSidebar()97 if @isSidebarShown() then @hideSidebar() else @showSidebar()
99 return98 return
100 99
101 onTapSearch: =>100 onTapSearch: =>
102 @body.scrollTop = 0101 window.scrollTo 0, 0
103 102
104 afterRoute: =>103 afterRoute: =>
105 @hideSidebar()104 @hideSidebar()
assets/javascripts/views/layout/nav.coffee+0−26
@@ -1,26 +0,0 @@
1class app.views.Nav extends app.View
2 @el: '._nav'
3 @activeClass: '_nav-current'
4
5 @routes:
6 after: 'afterRoute'
7
8 select: (href) ->
9 @deselect()
10 if @current = @find "a[href='#{href}']"
11 @current.classList.add @constructor.activeClass
12 @current.setAttribute 'tabindex', '-1'
13 return
14
15 deselect: ->
16 if @current
17 @current.classList.remove @constructor.activeClass
18 @current.removeAttribute 'tabindex'
19 @current = null
20 return
21
22 afterRoute: (route, context) =>
23 if route in ['page', 'offline']
24 @select context.pathname
25 else
26 @deselect()
assets/javascripts/views/layout/resizer.coffee+1−1
@@ -35,7 +35,7 @@ class app.views.Resizer extends app.View · 34 unmodified lines
35 return35 return
36 36
37 onClick: ->37 onClick: ->
38 app.document.toggleSidebar(save: true)38 app.document.toggleSidebarLayout()
39 return39 return
40 40
41 onDragStart: (event) =>41 onDragStart: (event) =>
assets/javascripts/views/list/list_focus.coffee+6−6
@@ -14,7 +14,7 @@ class app.views.ListFocus extends app.View · 13 unmodified lines
14 14
15 constructor: (@el) ->15 constructor: (@el) ->
16 super16 super
17 @focus = $.framify(@focus, @)17 @focusOnNextFrame = $.framify(@focus, @)
18 18
19 focus: (el) ->19 focus: (el) ->
20 if el and not el.classList.contains @constructor.activeClass20 if el and not el.classList.contains @constructor.activeClass
@@ -87,22 +87,22 @@ class app.views.ListFocus extends app.View · 66 unmodified lines
87 87
88 onDown: =>88 onDown: =>
89 if cursor = @getCursor()89 if cursor = @getCursor()
90 @focus @findNext(cursor)90 @focusOnNextFrame @findNext(cursor)
91 else91 else
92 @focus @findByTag('a')92 @focusOnNextFrame @findByTag('a')
93 return93 return
94 94
95 onUp: =>95 onUp: =>
96 if cursor = @getCursor()96 if cursor = @getCursor()
97 @focus @findPrev(cursor)97 @focusOnNextFrame @findPrev(cursor)
98 else98 else
99 @focus @findLastByTag('a')99 @focusOnNextFrame @findLastByTag('a')
100 return100 return
101 101
102 onLeft: =>102 onLeft: =>
103 cursor = @getCursor()103 cursor = @getCursor()
104 if cursor and not cursor.classList.contains(app.views.ListFold.activeClass) and cursor.parentElement isnt @el104 if cursor and not cursor.classList.contains(app.views.ListFold.activeClass) and cursor.parentElement isnt @el
105 @focus cursor.parentElement.previousSibling105 @focusOnNextFrame cursor.parentElement.previousSibling
106 return106 return
107 107
108 onEnter: =>108 onEnter: =>
assets/javascripts/views/misc/notice.coffee+0−1
@@ -18,7 +18,6 @@ class app.views.Notice extends app.View · 17 unmodified lines
18 return18 return
19 19
20 show: ->20 show: ->
21 @addClass '_top' if @type is 'disabledDoc'
22 @html @tmpl("#{@type}Notice", @args...)21 @html @tmpl("#{@type}Notice", @args...)
23 @prependTo $('._app')22 @prependTo $('._app')
24 return23 return
assets/javascripts/views/search/search.coffee+1−1
@@ -130,7 +130,7 @@ class app.views.Search extends app.View · 129 unmodified lines
130 if event.target is @resetLink130 if event.target is @resetLink
131 $.stopEvent(event)131 $.stopEvent(event)
132 @reset()132 @reset()
133 @focus()133 app.document.onEscape()
134 return134 return
135 135
136 onSubmit: (event) ->136 onSubmit: (event) ->
assets/javascripts/views/sidebar/doc_list.coffee+1−1
@@ -148,7 +148,7 @@ class app.views.DocList extends app.View · 147 unmodified lines
148 return148 return
149 149
150 scrollTo: (model) ->150 scrollTo: (model) ->
151 $.scrollTo @find("a[href='#{model.fullPath()}']"), null, 'top', margin: 0151 $.scrollTo @find("a[href='#{model.fullPath()}']"), null, 'top', margin: if app.isMobile() then 48 else 0
152 return152 return
153 153
154 toggleDisabled: ->154 toggleDisabled: ->
assets/javascripts/views/sidebar/results.coffee+2−2
@@ -15,8 +15,8 @@ class app.views.Results extends app.View · 14 unmodified lines
15 return15 return
16 16
17 init: ->17 init: ->
18 @addSubview @listSelect = new app.views.ListSelect @el
19 @addSubview @listFocus = new app.views.ListFocus @el unless app.isMobile()18 @addSubview @listFocus = new app.views.ListFocus @el unless app.isMobile()
19 @addSubview @listSelect = new app.views.ListSelect @el
20 20
21 @search21 @search
22 .on 'results', @onResults22 .on 'results', @onResults
@@ -42,7 +42,7 @@ class app.views.Results extends app.View · 19 unmodified lines
42 return42 return
43 43
44 focusFirst: ->44 focusFirst: ->
45 @listFocus?.focus @el.firstElementChild45 @listFocus?.focusOnNextFrame @el.firstElementChild
46 return46 return
47 47
48 openFirst: ->48 openFirst: ->
assets/javascripts/views/sidebar/sidebar.coffee+41−14
@@ -3,6 +3,7 @@ class app.views.Sidebar extends app.View · 2 unmodified lines
3 3
4 @events:4 @events:
5 focus: 'onFocus'5 focus: 'onFocus'
6 select: 'onSelect'
6 click: 'onClick'7 click: 'onClick'
7 8
8 @shortcuts:9 @shortcuts:
@@ -14,8 +15,8 @@ class app.views.Sidebar extends app.View · 5 unmodified lines
14 @addSubview @search = new app.views.Search15 @addSubview @search = new app.views.Search
15 16
16 @search17 @search
17 .on 'searching', @showResults18 .on 'searching', @onSearching
18 .on 'clear', @showDocList19 .on 'clear', @onSearchClear
19 .scope20 .scope
20 .on 'change', @onScopeChange21 .on 'change', @onScopeChange
21 22
@@ -27,7 +28,15 @@ class app.views.Sidebar extends app.View · 5 unmodified lines
27 $.on document, 'click', @onGlobalClick if @docPicker28 $.on document, 'click', @onGlobalClick if @docPicker
28 return29 return
29 30
30 show: (view) ->31 display: ->
32 @el.style.display = 'block'
33 return
34
35 resetDisplay: ->
36 @el.style.display = '' unless @el.style.display is 'none'
37 return
38
39 showView: (view) ->
31 unless @view is view40 unless @view is view
32 @hover?.hide()41 @hover?.hide()
33 @saveScrollPosition()42 @saveScrollPosition()
@@ -44,28 +53,29 @@ class app.views.Sidebar extends app.View · 10 unmodified lines
44 @append @tmpl('sidebarSettings') if @view is @docList and @docPicker53 @append @tmpl('sidebarSettings') if @view is @docList and @docPicker
45 return54 return
46 55
47 showDocList: (reset) =>56 showDocList: ->
48 @show @docList57 @showView @docList
49 if reset is true
50 @docList.reset(revealCurrent: true)
51 @search.reset()
52 return58 return
53 59
54 showDocPicker: =>60 showDocPicker: =>
55 @show @docPicker61 @showView @docPicker
56 return62 return
57 63
58 showResults: =>64 showResults: =>
59 @show @results65 @showView @results
66 return
67
68 reset: ->
69 @display()
70 @showDocList()
71 @docList.reset()
72 @search.reset()
60 return73 return
61 74
62 onReady: =>75 onReady: =>
63 @view = @docList76 @view = @docList
64 @render()77 @render()
65 @view.activate()78 @view.activate()
66
67 reset: ->
68 @showDocList true
69 return79 return
70 80
71 onScopeChange: (newDoc, previousDoc) =>81 onScopeChange: (newDoc, previousDoc) =>
@@ -90,15 +100,30 @@ class app.views.Sidebar extends app.View · 18 unmodified lines
90 @el.scrollTop = 0100 @el.scrollTop = 0
91 return101 return
92 102
103 onSearching: =>
104 @display()
105 @showResults()
106 return
107
108 onSearchClear: =>
109 @resetDisplay()
110 @showDocList()
111 return
112
93 onFocus: (event) =>113 onFocus: (event) =>
114 @display()
94 $.scrollTo event.target, @el, 'continuous', bottomGap: 2 unless event.target is @el115 $.scrollTo event.target, @el, 'continuous', bottomGap: 2 unless event.target is @el
95 return116 return
96 117
118 onSelect: =>
119 @resetDisplay()
120 return
121
97 onClick: (event) =>122 onClick: (event) =>
98 return if event.which isnt 1123 return if event.which isnt 1
99 if event.target.hasAttribute? 'data-reset-list'124 if event.target.hasAttribute? 'data-reset-list'
100 $.stopEvent(event)125 $.stopEvent(event)
101 @reset()126 @onAltR()
102 else if event.target.hasAttribute? 'data-light'127 else if event.target.hasAttribute? 'data-light'
103 $.stopEvent(event)128 $.stopEvent(event)
104 document.activeElement?.blur()129 document.activeElement?.blur()
@@ -120,6 +145,8 @@ class app.views.Sidebar extends app.View · 15 unmodified lines
120 145
121 onAltR: =>146 onAltR: =>
122 @reset()147 @reset()
148 @docList.reset(revealCurrent: true)
149 @display()
123 return150 return
124 151
125 onEscape: =>152 onEscape: =>
assets/javascripts/views/view.coffee+7−0
@@ -35,6 +35,13 @@ class app.View · 34 unmodified lines
35 @el.classList.remove(name)35 @el.classList.remove(name)
36 return36 return
37 37
38 toggleClass: (name) ->
39 @el.classList.toggle(name)
40 return
41
42 hasClass: (name) ->
43 @el.classList.contains(name)
44
38 resetClass: ->45 resetClass: ->
39 @el.className = @originalClassName or ''46 @el.className = @originalClassName or ''
40 if @constructor.className47 if @constructor.className
assets/stylesheets/components/_app.scss+2−3
@@ -2,7 +2,6 @@ · 1 unmodified line
2 position: relative;2 position: relative;
3 z-index: 1;3 z-index: 1;
4 height: 100%;4 height: 100%;
5 padding-top: $headerHeight;
6 overflow: hidden;5 overflow: hidden;
7 background: $contentBackground;6 background: $contentBackground;
8 -webkit-transition: opacity .2s;7 -webkit-transition: opacity .2s;
@@ -12,7 +11,7 @@ · 3 unmodified lines
12 ._booting > & { opacity: 0; }11 ._booting > & { opacity: 0; }
13 ._noscript > & { display: none; }12 ._noscript > & { display: none; }
14 13
15 &._max-width {14 &._max-width {
16 margin: 0 auto;15 margin: 0 auto;
17 max-width: $maxWidth;16 max-width: $maxWidth;
18 box-shadow: 1px 0 $headerBorder, -1px 0 $headerBorder;17 box-shadow: 1px 0 $headerBorder, -1px 0 $headerBorder;
@@ -31,7 +30,7 @@ · 12 unmodified lines
31 left: 0;30 left: 0;
32 right: 0;31 right: 0;
33 line-height: 1;32 line-height: 1;
34 margin-top: -.75em;33 margin-top: -.6em;
35 font-size: 4rem;34 font-size: 4rem;
36 font-weight: 300;35 font-weight: 300;
37 letter-spacing: -.125rem;36 letter-spacing: -.125rem;
assets/stylesheets/components/_content.scss+29−14
@@ -20,18 +20,24 @@ · 19 unmodified lines
20 height: 100%;20 height: 100%;
21 overflow-y: scroll;21 overflow-y: scroll;
22 margin-left: .875rem;22 margin-left: .875rem;
23 padding: 1.25rem 1.5rem 0;23 padding: 1.125rem 1.5rem 0;
24 font-size: .875rem;24 font-size: .875rem;
25 pointer-events: auto;25 pointer-events: auto;
26 -webkit-overflow-scrolling: touch;26 -webkit-overflow-scrolling: touch;
27 @extend %border-box;27 @extend %border-box;
28 28
29 -webkit-padding-start: .75rem;29 -webkit-padding-start: .625rem;
30 -webkit-padding-end: 1rem;30 -webkit-padding-end: .75rem;
31 31
32 @media (-moz-overlay-scrollbars) { padding-left: .75rem; }32 @media (-moz-overlay-scrollbars) { padding-left: .625rem; }
33 @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) { margin-left: 0; }33 @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) { margin-left: 0; }
34 34
35 ._sidebar-hidden &:before {
36 content: '';
37 display: block;
38 margin-top: $headerHeight;
39 }
40
35 &:after { // padding bottom41 &:after { // padding bottom
36 content: '';42 content: '';
37 display: block;43 display: block;
@@ -77,15 +83,22 @@ · 39 unmodified lines
77// Intro83// Intro
78//84//
79 85
80._intro { text-align: center; }86._intro {
87 display: flex;
88 flex-direction: column;
89 justify-content: center;
90 align-items: center;
91 min-height: calc(100vh - 2.375rem);
92
93 ._sidebar-hidden & {
94 min-height: calc(100vh - 2.375rem - #{$headerHeight});
95 }
96}
81 97
82._intro-message {98._intro-message {
83 position: relative;
84 display: inline-block;
85 vertical-align: top;
86 max-width: 37rem;99 max-width: 37rem;
100 margin: .5rem 0;
87 padding: 1rem 1.25rem;101 padding: 1rem 1.25rem;
88 text-align: left;
89 @extend %note, %note-green;102 @extend %note, %note-green;
90}103}
91 104
@@ -146,23 +159,25 @@ · 54 unmodified lines
146 159
147._lined-heading,160._lined-heading,
148%lined-heading {161%lined-heading {
149 white-space: nowrap;162 display: flex;
150 overflow: hidden;163 justify-content: center;
151 word-wrap: normal;164 align-items: center;
152 overflow-wrap: normal;
153 165
154 &:after {166 &:after {
155 content: '';167 content: '';
156 display: inline-block;168 display: inline-block;
157 vertical-align: middle;169 vertical-align: middle;
158 width: 100%;170 flex-grow: 1;
159 height: 1px;171 height: 1px;
160 line-height: 0;172 line-height: 0;
173 margin-top: .25rem;
161 margin-left: 1rem;174 margin-left: 1rem;
162 background: $boxBorderLight;175 background: $boxBorderLight;
163 }176 }
164}177}
165 178
179._block-heading { @extend %block-heading; }
180
166._heading-links {181._heading-links {
167 float: right;182 float: right;
168 font-weight: normal;183 font-weight: normal;
assets/stylesheets/components/_header.scss+104−51
@@ -7,79 +7,131 @@ · 6 unmodified lines
7 z-index: $headerZ;7 z-index: $headerZ;
8 top: 0;8 top: 0;
9 left: 0;9 left: 0;
10 right: 0;10 display: flex;
11 width: $sidebarWidth;
11 height: $headerHeight;12 height: $headerHeight;
12 line-height: $headerHeight;
13 background: $headerBackground;13 background: $headerBackground;
14 border-bottom: 1px solid $headerBorder;14 border-bottom: 1px solid $headerBorder;
15 @extend %user-select-none;15 @extend %user-select-none;
16
17 @media #{$mediumScreen} { width: $sidebarMediumWidth; }
16}18}
17 19
18//20._header-left {
19// Navigation menu21 float: left;
20//22 height: 100%;
23}
21 24
22._nav {25._header-right {
23 float: right;26 float: right;
24 margin-right: .5rem;27 height: 100%;
25 font-size: .875rem;
26 color: $textColor;
27}28}
28 29
29._nav-link,30._header-btn {
30._nav-link:hover {
31 position: relative;31 position: relative;
32 float: left;32 width: 2.25rem;
33 padding: 0 1.25rem;33 height: 100%;
34 color: inherit;34 color: $textColorLight;
35 text-decoration: none;35 text-align: center;
36 36
37 @media #{$mediumScreen} { padding: 0 .75rem; }37 &[hidden] { display: none; }
38}
39 38
40._nav-link {39 &[disabled] {
41 &:before, &:after {40 opacity: .3;
42 position: absolute;41 cursor: not-allowed;
43 left: 50%;
44 bottom: 0;
45 width: 0;
46 height: 0;
47 margin-left: -.375rem;
48 border: .375rem solid transparent;
49 border-bottom-color: darken($headerBorder, 2%);
50 }42 }
51 43
52 &:after {44 > svg {
53 bottom: -1px;45 display: inline-block;
54 border-bottom-color: $contentBackground;46 vertical-align: top;
47 width: 1.5rem;
48 height: 1.5rem;
49 fill: currentColor;
50 pointer-events: none;
55 }51 }
56}52}
57 53
58._nav-current {54//
59 outline: 0;55// Menu
56//
60 57
61 &:before, &:after { content: ''; }58._menu-btn {
59 border-right: 1px solid $headerBorder;
62}60}
63 61
64//62._menu {
65// Logo63 position: absolute;
66//64 z-index: 1;
65 top: .25rem;
66 right: .25rem;
67 width: 8rem;
68 height: calc(11.5rem + 1px);
69 font-size: .875rem;
70 background: $contentBackground;
71 border: 1px solid $headerBorder;
72 border-radius: 3px;
73 box-shadow: -1px 1px 1px rgba(black, .05);
74 transition: all 250ms cubic-bezier(0.23, 1, 0.32, 1);
75 opacity: 0;
76 -webkit-transform: scale(0, 0);
77 transform: scale(0, 0);
78 -webkit-transform-origin: 100% 0;
79 transform-origin: 100% 0;
80
81 &:hover,
82 ._menu-btn:hover + & {
83 transition-delay: 100ms;
84 }
67 85
68._logo {86 &:hover,
69 position: relative;87 &.active,
70 float: left;88 ._menu-btn:hover + &,
71 height: $headerHeight;89 ._menu-btn:focus + & {
90 opacity: 1;
91 -webkit-transform: scale(1, 1);
92 transform: scale(1, 1);
93 }
94
95 &:focus-within {
96 opacity: 1;
97 -webkit-transform: scale(1, 1);
98 transform: scale(1, 1);
99 }
100}
101
102._menu-title {
72 margin: 0;103 margin: 0;
73 line-height: inherit;104 line-height: 1.5rem;
74 font-size: inherit;105 font-size: 1rem;
75 font-weight: $boldFontWeight;106 font-weight: $boldFontWeight;
76 cursor: default;107 letter-spacing: -.5px;
108 background: $sidebarBackground;
109 border-bottom: 1px solid $sidebarBorder;
110 border-radius: 2px 2px 0 0;
111}
112
113._menu-title-link,
114._menu-title-link:hover {
115 display: block;
116 padding: .5rem 1rem;
117 color: $focusText;
118 text-decoration: none;
119}
77 120
78 > ._nav-link {121._menu-link {
79 float: none;122 display: block;
80 margin-left: .75rem;123 padding: 0 1rem;
81 padding: 0 .25rem;124 line-height: 2.25rem;
125 color: inherit;
126 text-decoration: none;
127
128 &:hover {
129 color: $focusText;
130 text-decoration: none;
131 background: $sidebarBackground;
82 }132 }
133
134 &:last-child { border-radius: 0 0 2px 2px; }
83}135}
84 136
85//137//
@@ -87,20 +139,19 @@ · 1 unmodified line
87//139//
88 140
89._search {141._search {
142 flex-grow: 1;
90 position: relative;143 position: relative;
91 float: left;
92 width: $sidebarWidth;
93 height: 100%;144 height: 100%;
94 padding: .5rem 0 .5rem .5rem;145 padding: .5rem 0 .5rem .5rem;
95 @extend %border-box;146 @extend %border-box;
96 147
97 @media #{$mediumScreen} { width: $sidebarMediumWidth; }
98
99 &:before {148 &:before {
100 position: absolute;149 position: absolute;
150 z-index: 1;
101 top: 1rem;151 top: 1rem;
102 left: 1rem;152 left: 1rem;
103 opacity: .4;153 opacity: .4;
154 pointer-events: none;
104 @if $style == 'dark' {155 @if $style == 'dark' {
105 @extend %icon, %icon-search-white;156 @extend %icon, %icon-search-white;
106 } @else {157 } @else {
@@ -110,6 +161,7 @@ · 3 unmodified lines
110}161}
111 162
112._search-input {163._search-input {
164 position: relative;
113 display: block;165 display: block;
114 width: 100%;166 width: 100%;
115 height: 100%;167 height: 100%;
@@ -164,6 +216,7 @@ · 48 unmodified lines
164._search-tag {216._search-tag {
165 display: none;217 display: none;
166 position: absolute;218 position: absolute;
219 z-index: 2;
167 top: .875rem;220 top: .875rem;
168 left: .875rem;221 left: .875rem;
169 padding: 0 .5rem;222 padding: 0 .5rem;
assets/stylesheets/components/_mobile.scss+14−108
@@ -10,18 +10,17 @@ · 9 unmodified lines
10 10
11 body { -ms-overflow-style: -ms-autohiding-scrollbar; }11 body { -ms-overflow-style: -ms-autohiding-scrollbar; }
12 12
13 ._app, ._container, ._content { overflow: visible; }13 ._app, ._content { overflow: visible; }
14 14 ._app { padding-top: $headerHeight; }
15 ._container {15 ._container { margin: 0; }
16 margin: 0;
17 border: 0;
18 }
19 16
20 ._content {17 ._content {
21 position: static;18 position: static;
22 height: auto;19 height: auto;
23 margin: 0;20 margin: 0;
24 padding: .75rem 1rem 2.5rem;21 padding: .75rem 1rem 2.5rem;
22
23 &:before { content: none; }
25 }24 }
26 25
27 ._booting:before, ._content-loading:before { font-size: 3rem; }26 ._booting:before, ._content-loading:before { font-size: 3rem; }
@@ -33,16 +32,13 @@ · 5 unmodified lines
33 max-width: 100vw;32 max-width: 100vw;
34 }33 }
35 34
36 ._logo, ._nav { display: none; }35 ._header-btn { width: 2.5rem; }
37 ._mobile-btn { display: block; }36 ._header-btn[hidden] { display: block; }
37 ._menu-btn { border-right: 0; }
38 38
39 ._search {39 ._search {
40 float: none;40 padding-right: .125rem;
41 width: auto;41 padding-left: .125rem;
42 overflow: hidden;
43 padding-left: 2px;
44 padding-right: 2px;
45 border-right: 0;
46 42
47 &:before { left: .5rem; }43 &:before { left: .5rem; }
48 }44 }
@@ -57,7 +53,7 @@ · 8 unmodified lines
57 overflow: visible;53 overflow: visible;
58 }54 }
59 55
60 ._list, ._sidebar-footer { width: 100%; }56 ._header, ._list, ._sidebar-footer { width: 100%; }
61 57
62 ._list-item {58 ._list-item {
63 white-space: normal;59 white-space: normal;
@@ -85,33 +81,12 @@ · 21 unmodified lines
85 box-shadow: 0 1px $noteGreenBorder, 0 -1px $noteGreenBorder;81 box-shadow: 0 1px $noteGreenBorder, 0 -1px $noteGreenBorder;
86 }82 }
87 83
88 // Splash
89
90 ._splash-sponsors { margin-top: 1rem; }
91
92 ._splash-sponsor {
93 position: static;
94
95 ._logo-info {
96 left: 1rem;
97 right: 1rem;
98 width: auto;
99 max-width: none;
100 margin: 0;
101 }
102 }
103
104 // Notice84 // Notice
105 85
106 ._notice {86 ._notice {
107 position: fixed;87 position: fixed;
108 left: 0;88 left: 0;
109 padding: 0 .5rem;89 padding: 0 .5rem;
110
111 ~ ._sidebar {
112 margin-top: 2.5rem;
113 padding-bottom: 4rem;
114 }
115 }90 }
116 91
117 ._notice-text { font-size: .75em; }92 ._notice-text { font-size: .75em; }
@@ -143,76 +118,10 @@ · 25 unmodified lines
143// Header buttons118// Header buttons
144//119//
145 120
146._mobile-btn {
147 display: none;
148 position: relative;
149 float: left;
150 width: 2.5rem;
151 height: 100%;
152 @extend %hide-text;
153
154 &[disabled] {
155 opacity: .3;
156 cursor: not-allowed;
157 }
158
159 &:before {
160 position: absolute;
161 top: 50%;
162 left: 50%;
163 margin: -.5rem 0 0 -.5rem;
164 @extend %icon;
165 }
166}
167
168._back-btn {
169 &:before { @extend %icon-back; }
170}
171
172._forward-btn {121._forward-btn {
173 width: 2.25rem;122 margin-right: -.5rem;
174 -webkit-transform: rotate(180deg);
175 transform: rotate(180deg);
176
177 &:before {
178 margin-left: -.375rem;
179 @extend %icon-back;
180 }
181}
182
183._home-btn {
184 float: right;
185 width: 2rem;
186
187 &:before {
188 margin-left: -.375rem;
189 @extend %icon-home;
190 }
191}
192 123
193._menu-btn {124 > svg { margin-left: -.375rem; }
194 float: right;
195
196 &:before { @extend %icon-menu; }
197}
198
199//
200// Navigation menu
201//
202
203._mobile-nav {
204 margin: .25rem 0 1.25rem;
205 padding: 0;
206 line-height: 2.8;
207 overflow: hidden;
208 @extend %box;
209}
210
211._mobile-nav-link {
212 float: left;
213 width: 25%;
214 text-align: center;
215 font-weight: $boldFontWeight;
216}125}
217 126
218//127//
@@ -222,14 +131,11 @@ · 3 unmodified lines
222._mobile-intro {131._mobile-intro {
223 > ._intro-list { padding-left: 1.5rem; }132 > ._intro-list { padding-left: 1.5rem; }
224 133
225 > ._intro-hide,134 ._intro-hide {
226 > ._intro-sponsors {
227 position: static;135 position: static;
228 float: none;136 float: none;
229 display: block;137 display: block;
230 margin-top: .75rem;138 margin-top: .75rem;
231 text-align: center;139 text-align: center;
232 }140 }
233
234 ._intro-sponsor { margin: .5em .75em; }
235}141}
assets/stylesheets/components/_notice.scss+1−11
@@ -12,17 +12,7 @@ · 11 unmodified lines
12 @media #{$mediumScreen} { left: $sidebarMediumWidth; }12 @media #{$mediumScreen} { left: $sidebarMediumWidth; }
13 13
14 ._sidebar-hidden & { left: $sidebarHiddenWidth; }14 ._sidebar-hidden & { left: $sidebarHiddenWidth; }
15 15 ~ ._container { padding-bottom: 2.5rem; }
16 &:not(._top) ~ ._container { padding-bottom: 2.5rem; }
17
18 &._top {
19 bottom: auto;
20 top: $headerHeight;
21 margin-top: 1px;
22 box-shadow: inset 0 -1px $noticeBorder;
23
24 ~ ._container { padding-top: 2.5rem; }
25 }
26}16}
27 17
28._notice-text {18._notice-text {
assets/stylesheets/components/_sidebar.scss+1−1
@@ -40,7 +40,7 @@ · 39 unmodified lines
40 40
41._resizer {41._resizer {
42 position: absolute;42 position: absolute;
43 z-index: $sidebarZ + 1;43 z-index: $sidebarZ;
44 top: $headerHeight;44 top: $headerHeight;
45 bottom: 0;45 bottom: 0;
46 left: $sidebarWidth;46 left: $sidebarWidth;
assets/stylesheets/global/_icons.scss+0−3
@@ -37,8 +37,6 @@ · 36 unmodified lines
37%icon-clear { background-position: -3rem 0; }37%icon-clear { background-position: -3rem 0; }
38%icon-settings { background-position: 0 -1rem; }38%icon-settings { background-position: 0 -1rem; }
39%icon-check { background-position: -1rem -1rem; }39%icon-check { background-position: -1rem -1rem; }
40%icon-menu { background-position: -2rem -1rem; @extend %darkIconFix !optional; }
41%icon-home { background-position: -3rem -1rem; @extend %darkIconFix !optional; }
42%icon-path { background-position: 0 -2rem; }40%icon-path { background-position: 0 -2rem; }
43%icon-search-white { background-position: -1rem -2rem; }41%icon-search-white { background-position: -1rem -2rem; }
44%icon-dir-white { background-position: -2rem -2rem; }42%icon-dir-white { background-position: -2rem -2rem; }
@@ -54,7 +52,6 @@ · 9 unmodified lines
54%icon-clipboard { background-position: 0 -5rem; }52%icon-clipboard { background-position: 0 -5rem; }
55%icon-clipboard-white { background-position: -1rem -5rem; }53%icon-clipboard-white { background-position: -1rem -5rem; }
56%icon-close-white { background-position: -2rem -5rem; }54%icon-close-white { background-position: -2rem -5rem; }
57%icon-back { background-position: -3rem -5rem; @extend %darkIconFix !optional; }
58 55
59._icon-codeceptjs:before { background-position: -3rem 0; }56._icon-codeceptjs:before { background-position: -3rem 0; }
60._icon-codeception:before { background-position: -4rem 0; }57._icon-codeception:before { background-position: -4rem 0; }
assets/stylesheets/global/_variables-dark.scss+2−2
@@ -7,7 +7,7 @@ $style: 'dark'; · 6 unmodified lines
7 7
8$maxWidth: 80rem;8$maxWidth: 80rem;
9$headerHeight: 3rem;9$headerHeight: 3rem;
10$sidebarWidth: 18rem;10$sidebarWidth: 20rem;
11$sidebarMediumWidth: 16rem;11$sidebarMediumWidth: 16rem;
12$sidebarHiddenWidth: 9px;12$sidebarHiddenWidth: 9px;
13 13
@@ -37,7 +37,7 @@ $linkColor: $textColor; · 23 unmodified lines
37$linkColorHover: white;37$linkColorHover: white;
38$linkTextDecoration: underline;38$linkTextDecoration: underline;
39 39
40$headerBackground: #1e1e1e;40$headerBackground: #1c1c1c;
41$headerBorder: #000;41$headerBorder: #000;
42 42
43$sidebarBackground: #24282a;43$sidebarBackground: #24282a;
assets/stylesheets/global/_variables.scss+4−4
@@ -7,7 +7,7 @@ $style: 'light'; · 6 unmodified lines
7 7
8$maxWidth: 80rem;8$maxWidth: 80rem;
9$headerHeight: 3rem;9$headerHeight: 3rem;
10$sidebarWidth: 18rem;10$sidebarWidth: 20rem;
11$sidebarMediumWidth: 16rem;11$sidebarMediumWidth: 16rem;
12$sidebarHiddenWidth: 9px;12$sidebarHiddenWidth: 9px;
13 13
@@ -37,11 +37,11 @@ $linkColor: #3377c0; · 23 unmodified lines
37$linkColorHover: #2f6cb6;37$linkColorHover: #2f6cb6;
38$linkTextDecoration: none;38$linkTextDecoration: none;
39 39
40$headerBackground: #f0f0f0;40$headerBackground: #eee;
41$headerBorder: #d9d9d9;41$headerBorder: #d7d7d7;
42 42
43$sidebarBackground: #f9f9f9;43$sidebarBackground: #f9f9f9;
44$sidebarBorder: #e3e3e3;44$sidebarBorder: #e1e1e1;
45 45
46$scrollbarColor: #d2d2d2;46$scrollbarColor: #d2d2d2;
47$scrollbarColorHover: #aaa;47$scrollbarColorHover: #aaa;
lib/app.rb+1−1
@@ -184,7 +184,7 @@ class App < Sinatra::Application · 183 unmodified lines
184 end184 end
185 185
186 def app_size186 def app_size
187 @app_size ||= cookies[:size].nil? ? '18rem' : "#{cookies[:size]}px"187 @app_size ||= cookies[:size].nil? ? '20rem' : "#{cookies[:size]}px"
188 end188 end
189 189
190 def app_layout190 def app_layout
public/icons/ui/back/16.png+0−0

Binary file not shown.

public/icons/ui/back/16@2x.png+0−0

Binary file not shown.

public/icons/ui/home/16.png+0−0

Binary file not shown.

public/icons/ui/home/16@2x.png+0−0

Binary file not shown.

public/icons/ui/home/SOURCE+0−1
@@ -1 +0,0 @@
1http://www.entypo.com/
public/icons/ui/menu/16.png+0−0

Binary file not shown.

public/icons/ui/menu/16@2x.png+0−0

Binary file not shown.

test/app_test.rb+2−2
@@ -31,7 +31,7 @@ class AppTest < MiniTest::Spec · 30 unmodified lines
31 31
32 it "sets default size" do32 it "sets default size" do
33 get '/'33 get '/'
34 assert_includes last_response.body, 'data-size="18rem"'34 assert_includes last_response.body, 'data-size="20rem"'
35 end35 end
36 36
37 it "sets size from cookie" do37 it "sets size from cookie" do
@@ -115,7 +115,7 @@ class AppTest < MiniTest::Spec · 77 unmodified lines
115 115
116 it "sets default size" do116 it "sets default size" do
117 get '/manifest.appcache'117 get '/manifest.appcache'
118 assert_includes last_response.body, '18rem'118 assert_includes last_response.body, '20rem'
119 end119 end
120 120
121 it "sets size from cookie" do121 it "sets size from cookie" do
views/app.erb+19−13
@@ -1,22 +1,28 @@
1<div class="_app<%= " #{app_layout}" if app_layout %>" role="application">1<div class="_app<%= " #{app_layout}" if app_layout %>" role="application">
2 <header class="_header" role="banner">2 <header class="_header" role="banner">
3 <button type="button" class="_mobile-btn _back-btn">Back</button>3 <button type="button" aria-label="Toggle navigation" class="_header-btn" data-toggle-sidebar hidden>
4 <button type="button" class="_mobile-btn _forward-btn">Forward</button>4 <svg viewBox="0 0 24 24"><path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"></path></svg>
5 <button type="button" class="_mobile-btn _menu-btn">Menu</button>5 </button>
6 <button type="button" class="_mobile-btn _home-btn">Home</button>
7 <form class="_search" role="search">6 <form class="_search" role="search">
8 <input type="search" name="q" class="_search-input" placeholder="Search&hellip;" autocomplete="off" autocapitalize="off" autocorrect="off" spellcheck="false" maxlength="30" aria-label="Search">7 <input type="search" name="q" class="_search-input" placeholder="Search&hellip;" autocomplete="off" autocapitalize="off" autocorrect="off" spellcheck="false" maxlength="30" aria-label="Search">
9 <button type="reset" class="_search-clear" title="Clear search">Clear search</button>8 <button type="reset" class="_search-clear" title="Clear search">Clear search</button>
10 <div class="_search-tag"></div>9 <div class="_search-tag"></div>
11 </form>10 </form>
12 <h1 class="_logo">11 <button type="button" aria-label="Back" class="_header-btn" data-back hidden>
13 <a href="/" class="_nav-link" title="Offline API Documentation Browser">DevDocs</a><%= "/ #{@doc['full_name']}" if @doc %>12 <svg viewBox="0 0 24 24"><path d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z"></svg>
14 </h1>13 </button>
15 <nav class="_nav" role="navigation">14 <button type="button" aria-label="Forward" class="_header-btn _forward-btn" data-forward hidden>
16 <a href="/offline" class="_nav-link">Offline</a>15 <svg viewBox="0 0 24 24"><path d="M12 4l-1.41 1.41L16.17 11H4v2h12.17l-5.58 5.59L12 20l8-8z"></svg>
17 <a href="/about" class="_nav-link">About</a>16 </button>
18 <a href="/news" class="_nav-link">News</a>17 <button type="button" aria-label="Toggle menu" title="Toggle menu" class="_header-btn _menu-btn" data-toggle-menu>
19 <a href="/help" class="_nav-link">Tips</a>18 <svg viewBox="0 0 24 24"><path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"></path></svg>
19 </button>
20 <nav class="_menu" role="navigation">
21 <h1 class="_menu-title"><a href="/" class="_menu-title-link">DevDocs</a></h1>
22 <a href="/offline" class="_menu-link">Offline</a>
23 <a href="/news" class="_menu-link">Changelog</a>
24 <a href="/help" class="_menu-link">Help</a>
25 <a href="/about" class="_menu-link">About</a>
20 </nav>26 </nav>
21 </header>27 </header>
22 <section class="_sidebar" tabindex="-1">28 <section class="_sidebar" tabindex="-1">
@@ -34,7 +40,7 @@ · 11 unmodified lines
34</div>40</div>
35<style data-size="<%= app_size %>" data-resizer>41<style data-size="<%= app_size %>" data-resizer>
36 ._container { margin-left: <%= app_size %>; }42 ._container { margin-left: <%= app_size %>; }
37 ._search, ._list, ._sidebar-footer { width: <%= app_size %>; }43 ._header, ._list, ._sidebar-footer { width: <%= app_size %>; }
38 ._list-hover.clone { min-width: <%= app_size %>; }44 ._list-hover.clone { min-width: <%= app_size %>; }
39 ._notice, ._path, ._resizer { left: <%= app_size %>; }45 ._notice, ._path, ._resizer { left: <%= app_size %>; }
40</style>46</style>