Showing the changes to assets/javascripts (18 of 39 files). Show all
Unified · Split
| @@ -10,7 +10,7 @@ app.templates.aboutPage = -> """ · 9 unmodified lines | ||
| 10 | 10 | </ul> |
| 11 | 11 | </nav> |
| 12 | 12 | |
| 13 | − <h1 class="_lined-heading">API Documentation Browser</h1> | |
| 13 | + <h1 class="_lined-heading">DevDocs: API Documentation Browser</h1> | |
| 14 | 14 | <p>DevDocs combines multiple API documentations in a fast, organized, and searchable interface. |
| 15 | 15 | <ul> |
| 16 | 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 | 26 | <p class="_note _note-green">If you like DevDocs, please consider supporting my work on |
| 27 | 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 | 31 | <p><strong>Special thanks to:</strong> |
| 32 | 32 | <ul> |
| @@ -45,7 +45,7 @@ app.templates.aboutPage = -> """ · 12 unmodified lines | ||
| 45 | 45 | #{("<tr><td>#{c[0]}<td>© #{c[1]}<td><a href=\"#{c[3]}\">#{c[2]}</a>" for c in credits).join('')} |
| 46 | 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 | 49 | <dl> |
| 50 | 50 | <dt>Where can I suggest new docs and features? |
| 51 | 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 | 56 | </dl> |
| 57 | 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 | 60 | <p class="_note"> |
| 61 | 61 | <strong>Copyright 2013–2017 Thibaut Courouble and <a href="https://github.com/Thibaut/devdocs/graphs/contributors">other contributors</a></strong><br> |
| 62 | 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 | 64 | For more information, see the <a href="https://github.com/Thibaut/devdocs/blob/master/COPYRIGHT">COPYRIGHT</a> |
| 65 | 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 | 68 | <ul> |
| 69 | 69 | <li><a href="https://chrome.google.com/webstore/detail/devdocs/mnfehgbmkapmjnhcnbodoamcioleeooe">Chrome web app</a> |
| 70 | 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 | 73 | <li><a href="https://github.com/xuchunyang/DevDocs.el">Emacs Package</a> |
| 74 | 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 | 77 | <ul> |
| 78 | 78 | <li><a href="http://devdocs.io">devdocs.io</a> ("App") is operated by Thibaut Courouble ("We"). |
| 79 | 79 | <li>We do not collect personal information. |
| @@ -11,7 +11,9 @@ app.templates.helpPage = """ · 10 unmodified lines | ||
| 11 | 11 | </ul> |
| 12 | 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 | 17 | <p> |
| 16 | 18 | The search is case-insensitive and supports fuzzy matching (for queries longer than two characters). |
| 17 | 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 | 44 | <a href="https://support.mozilla.org/en-US/kb/how-search-from-address-bar">these instructions</a>. |
| 43 | 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 | 48 | <h3 class="_shortcuts-title">Selection</h3> |
| 47 | 49 | <dl class="_shortcuts-dl"> |
| 48 | 50 | <dt class="_shortcuts-dt"> |
| @@ -110,7 +112,7 @@ app.templates.helpPage = """ · 61 unmodified lines | ||
| 110 | 112 | <strong>Tip:</strong> If the cursor is no longer in the search field, press <code class="_label">/</code> or |
| 111 | 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 | 116 | <p>Feel free to suggest new abbreviations on <a href="https://github.com/Thibaut/devdocs/issues/new">GitHub</a>. |
| 115 | 117 | <table class="_abbreviations"> |
| 116 | 118 | <tr> |
| @@ -15,7 +15,7 @@ app.templates.newsList = (news, options = {}) -> · 14 unmodified lines | ||
| 15 | 15 | date = new Date(value[0]) |
| 16 | 16 | if options.years isnt false and year isnt date.getUTCFullYear() |
| 17 | 17 | year = date.getUTCFullYear() |
| 18 | − result += "<h4>#{year}</h4>" | |
| 18 | + result += """<h2 class="_block-heading">#{year}</h2>""" | |
| 19 | 19 | result += newsItem(date, value[1..]) |
| 20 | 20 | |
| 21 | 21 | result |
| @@ -21,7 +21,7 @@ app.templates.offlinePage = (docs) -> """ · 20 unmodified lines | ||
| 21 | 21 | #{docs} |
| 22 | 22 | </table> |
| 23 | 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 | 25 | <dl> |
| 26 | 26 | <dt>How does this work? |
| 27 | 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> |
| @@ -48,15 +48,6 @@ app.templates.intro = """ · 47 unmodified lines | ||
| 48 | 48 | """ |
| 49 | 49 | <% end %> |
| 50 | 50 | |
| 51 | −app.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 | − | |
| 60 | 51 | app.templates.mobileIntro = """ |
| 61 | 52 | <div class="_mobile-intro"> |
| 62 | 53 | <h2 class="_intro-title">Welcome!</h2> |
| @@ -9,7 +9,6 @@ class app.views.RootPage extends app.View · 8 unmodified lines | ||
| 9 | 9 | |
| 10 | 10 | render: -> |
| 11 | 11 | @empty() |
| 12 | − @append @tmpl('mobileNav') if app.isMobile() | |
| 13 | 12 | if app.isAndroidWebview() |
| 14 | 13 | @append @tmpl('androidWarning') |
| 15 | 14 | else |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | class app.views.Document extends app.View |
| 2 | − MAX_WIDTH_CLASS = '_max-width' | |
| 3 | − HIDE_SIDEBAR_CLASS = '_sidebar-hidden' | |
| 2 | + MAX_WIDTH_LAYOUT = '_max-width' | |
| 3 | + SIDEBAR_HIDDEN_LAYOUT = '_sidebar-hidden' | |
| 4 | 4 | |
| 5 | 5 | @el: document |
| 6 | 6 | |
| @@ -14,16 +14,12 @@ class app.views.Document extends app.View · 7 unmodified lines | ||
| 14 | 14 | superRight: 'onForward' |
| 15 | 15 | |
| 16 | 16 | init: -> |
| 17 | − @addSubview @nav = new app.views.Nav, | |
| 17 | + @addSubview @menu = new app.views.Menu, | |
| 18 | 18 | @addSubview @sidebar = new app.views.Sidebar |
| 19 | 19 | @addSubview @resizer = new app.views.Resizer if app.views.Resizer.isSupported() |
| 20 | 20 | @addSubview @content = new app.views.Content |
| 21 | 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 | 23 | $.on document.body, 'click', @onClick |
| 28 | 24 | |
| 29 | 25 | @activate() |
| @@ -39,39 +35,17 @@ class app.views.Document extends app.View · 9 unmodified lines | ||
| 39 | 35 | return |
| 40 | 36 | |
| 41 | 37 | toggleLayout: -> |
| 42 | − wantsMaxWidth = !app.el.classList.contains(MAX_WIDTH_CLASS) | |
| 43 | − app.el.classList[if wantsMaxWidth then 'add' else 'remove'](MAX_WIDTH_CLASS) | |
| 44 | − app.settings.setLayout(MAX_WIDTH_CLASS, wantsMaxWidth) | |
| 38 | + wantsMaxWidth = !app.el.classList.contains(MAX_WIDTH_LAYOUT) | |
| 39 | + app.el.classList[if wantsMaxWidth then 'add' else 'remove'](MAX_WIDTH_LAYOUT) | |
| 40 | + app.settings.setLayout(MAX_WIDTH_LAYOUT, wantsMaxWidth) | |
| 45 | 41 | app.appCache?.updateInBackground() |
| 46 | 42 | return |
| 47 | 43 | |
| 48 | − showSidebar: (options = {}) -> | |
| 49 | − @toggleSidebar(options, true) | |
| 50 | − return | |
| 51 | − | |
| 52 | − hideSidebar: (options = {}) -> | |
| 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() | |
| 44 | + toggleSidebarLayout: -> | |
| 45 | + shouldHide = !app.settings.hasLayout(SIDEBAR_HIDDEN_LAYOUT) | |
| 46 | + app.el.classList[if shouldHide then 'add' else 'remove'](SIDEBAR_HIDDEN_LAYOUT) | |
| 47 | + app.settings.setLayout(SIDEBAR_HIDDEN_LAYOUT, shouldHide) | |
| 48 | + app.appCache?.updateInBackground() | |
| 75 | 49 | return |
| 76 | 50 | |
| 77 | 51 | setTitle: (title) -> |
| @@ -0,0 +1,24 @@ | ||
| 1 | +class 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 | |
| @@ -35,44 +35,48 @@ class app.views.Mobile extends app.View · 34 unmodified lines | ||
| 35 | 35 | FastClick.attach @body |
| 36 | 36 | |
| 37 | 37 | $.on @body, 'click', @onClick |
| 38 | − $.on $('._home-btn'), 'click', @onClickHome | |
| 39 | − $.on $('._menu-btn'), 'click', @onClickMenu | |
| 40 | 38 | $.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 | 46 | $.on @back, 'click', @onClickBack |
| 44 | 47 | |
| 45 | − @forward = $('._forward-btn') | |
| 48 | + @forward = $('button[data-forward]') | |
| 49 | + @forward.removeAttribute('hidden') | |
| 46 | 50 | $.on @forward, 'click', @onClickForward |
| 47 | 51 | |
| 48 | 52 | app.document.sidebar.search |
| 49 | 53 | .on 'searching', @showSidebar |
| 50 | − .on 'clear', @hideSidebar | |
| 51 | 54 | |
| 52 | 55 | @activate() |
| 53 | 56 | return |
| 54 | 57 | |
| 55 | 58 | showSidebar: => |
| 56 | 59 | if @isSidebarShown() |
| 57 | − @body.scrollTop = 0 | |
| 60 | + window.scrollTo 0, 0 | |
| 58 | 61 | return |
| 59 | 62 | |
| 60 | − @contentTop = @body.scrollTop | |
| 63 | + @contentTop = window.scrollY | |
| 61 | 64 | @content.style.display = 'none' |
| 62 | 65 | @sidebar.style.display = 'block' |
| 63 | 66 | |
| 64 | 67 | 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 | 70 | else |
| 67 | − @body.scrollTop = @findByClass(app.views.ListFold.activeClass) and @sidebarTop or 0 | |
| 71 | + window.scrollTo 0, @findByClass(app.views.ListFold.activeClass) and @sidebarTop or 0 | |
| 68 | 72 | return |
| 69 | 73 | |
| 70 | 74 | hideSidebar: => |
| 71 | 75 | return unless @isSidebarShown() |
| 72 | − @sidebarTop = @body.scrollTop | |
| 76 | + @sidebarTop = window.scrollY | |
| 73 | 77 | @sidebar.style.display = 'none' |
| 74 | 78 | @content.style.display = 'block' |
| 75 | − @body.scrollTop = @contentTop or 0 | |
| 79 | + window.scrollTo 0, @contentTop or 0 | |
| 76 | 80 | return |
| 77 | 81 | |
| 78 | 82 | isSidebarShown: -> |
| @@ -89,17 +93,12 @@ class app.views.Mobile extends app.View · 10 unmodified lines | ||
| 89 | 93 | onClickForward: => |
| 90 | 94 | history.forward() |
| 91 | 95 | |
| 92 | − onClickHome: => | |
| 93 | − app.shortcuts.trigger 'escape' | |
| 94 | − @hideSidebar() | |
| 95 | − return | |
| 96 | − | |
| 97 | − onClickMenu: => | |
| 96 | + onClickToggleSidebar: => | |
| 98 | 97 | if @isSidebarShown() then @hideSidebar() else @showSidebar() |
| 99 | 98 | return |
| 100 | 99 | |
| 101 | 100 | onTapSearch: => |
| 102 | − @body.scrollTop = 0 | |
| 101 | + window.scrollTo 0, 0 | |
| 103 | 102 | |
| 104 | 103 | afterRoute: => |
| 105 | 104 | @hideSidebar() |
| @@ -1,26 +0,0 @@ | ||
| 1 | −class 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() | |
| @@ -35,7 +35,7 @@ class app.views.Resizer extends app.View · 34 unmodified lines | ||
| 35 | 35 | return |
| 36 | 36 | |
| 37 | 37 | onClick: -> |
| 38 | − app.document.toggleSidebar(save: true) | |
| 38 | + app.document.toggleSidebarLayout() | |
| 39 | 39 | return |
| 40 | 40 | |
| 41 | 41 | onDragStart: (event) => |
| @@ -14,7 +14,7 @@ class app.views.ListFocus extends app.View · 13 unmodified lines | ||
| 14 | 14 | |
| 15 | 15 | constructor: (@el) -> |
| 16 | 16 | super |
| 17 | − @focus = $.framify(@focus, @) | |
| 17 | + @focusOnNextFrame = $.framify(@focus, @) | |
| 18 | 18 | |
| 19 | 19 | focus: (el) -> |
| 20 | 20 | 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 | 88 | onDown: => |
| 89 | 89 | if cursor = @getCursor() |
| 90 | − @focus @findNext(cursor) | |
| 90 | + @focusOnNextFrame @findNext(cursor) | |
| 91 | 91 | else |
| 92 | − @focus @findByTag('a') | |
| 92 | + @focusOnNextFrame @findByTag('a') | |
| 93 | 93 | return |
| 94 | 94 | |
| 95 | 95 | onUp: => |
| 96 | 96 | if cursor = @getCursor() |
| 97 | − @focus @findPrev(cursor) | |
| 97 | + @focusOnNextFrame @findPrev(cursor) | |
| 98 | 98 | else |
| 99 | − @focus @findLastByTag('a') | |
| 99 | + @focusOnNextFrame @findLastByTag('a') | |
| 100 | 100 | return |
| 101 | 101 | |
| 102 | 102 | onLeft: => |
| 103 | 103 | cursor = @getCursor() |
| 104 | 104 | if cursor and not cursor.classList.contains(app.views.ListFold.activeClass) and cursor.parentElement isnt @el |
| 105 | − @focus cursor.parentElement.previousSibling | |
| 105 | + @focusOnNextFrame cursor.parentElement.previousSibling | |
| 106 | 106 | return |
| 107 | 107 | |
| 108 | 108 | onEnter: => |
| @@ -18,7 +18,6 @@ class app.views.Notice extends app.View · 17 unmodified lines | ||
| 18 | 18 | return |
| 19 | 19 | |
| 20 | 20 | show: -> |
| 21 | − @addClass '_top' if @type is 'disabledDoc' | |
| 22 | 21 | @html @tmpl("#{@type}Notice", @args...) |
| 23 | 22 | @prependTo $('._app') |
| 24 | 23 | return |
| @@ -130,7 +130,7 @@ class app.views.Search extends app.View · 129 unmodified lines | ||
| 130 | 130 | if event.target is @resetLink |
| 131 | 131 | $.stopEvent(event) |
| 132 | 132 | @reset() |
| 133 | − @focus() | |
| 133 | + app.document.onEscape() | |
| 134 | 134 | return |
| 135 | 135 | |
| 136 | 136 | onSubmit: (event) -> |
| @@ -148,7 +148,7 @@ class app.views.DocList extends app.View · 147 unmodified lines | ||
| 148 | 148 | return |
| 149 | 149 | |
| 150 | 150 | scrollTo: (model) -> |
| 151 | − $.scrollTo @find("a[href='#{model.fullPath()}']"), null, 'top', margin: 0 | |
| 151 | + $.scrollTo @find("a[href='#{model.fullPath()}']"), null, 'top', margin: if app.isMobile() then 48 else 0 | |
| 152 | 152 | return |
| 153 | 153 | |
| 154 | 154 | toggleDisabled: -> |
| @@ -15,8 +15,8 @@ class app.views.Results extends app.View · 14 unmodified lines | ||
| 15 | 15 | return |
| 16 | 16 | |
| 17 | 17 | init: -> |
| 18 | − @addSubview @listSelect = new app.views.ListSelect @el | |
| 19 | 18 | @addSubview @listFocus = new app.views.ListFocus @el unless app.isMobile() |
| 19 | + @addSubview @listSelect = new app.views.ListSelect @el | |
| 20 | 20 | |
| 21 | 21 | @search |
| 22 | 22 | .on 'results', @onResults |
| @@ -42,7 +42,7 @@ class app.views.Results extends app.View · 19 unmodified lines | ||
| 42 | 42 | return |
| 43 | 43 | |
| 44 | 44 | focusFirst: -> |
| 45 | − @listFocus?.focus @el.firstElementChild | |
| 45 | + @listFocus?.focusOnNextFrame @el.firstElementChild | |
| 46 | 46 | return |
| 47 | 47 | |
| 48 | 48 | openFirst: -> |
| @@ -3,6 +3,7 @@ class app.views.Sidebar extends app.View · 2 unmodified lines | ||
| 3 | 3 | |
| 4 | 4 | @events: |
| 5 | 5 | focus: 'onFocus' |
| 6 | + select: 'onSelect' | |
| 6 | 7 | click: 'onClick' |
| 7 | 8 | |
| 8 | 9 | @shortcuts: |
| @@ -14,8 +15,8 @@ class app.views.Sidebar extends app.View · 5 unmodified lines | ||
| 14 | 15 | @addSubview @search = new app.views.Search |
| 15 | 16 | |
| 16 | 17 | @search |
| 17 | − .on 'searching', @showResults | |
| 18 | − .on 'clear', @showDocList | |
| 18 | + .on 'searching', @onSearching | |
| 19 | + .on 'clear', @onSearchClear | |
| 19 | 20 | .scope |
| 20 | 21 | .on 'change', @onScopeChange |
| 21 | 22 | |
| @@ -27,7 +28,15 @@ class app.views.Sidebar extends app.View · 5 unmodified lines | ||
| 27 | 28 | $.on document, 'click', @onGlobalClick if @docPicker |
| 28 | 29 | 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 | 40 | unless @view is view |
| 32 | 41 | @hover?.hide() |
| 33 | 42 | @saveScrollPosition() |
| @@ -44,28 +53,29 @@ class app.views.Sidebar extends app.View · 10 unmodified lines | ||
| 44 | 53 | @append @tmpl('sidebarSettings') if @view is @docList and @docPicker |
| 45 | 54 | return |
| 46 | 55 | |
| 47 | − showDocList: (reset) => | |
| 48 | − @show @docList | |
| 49 | − if reset is true | |
| 50 | − @docList.reset(revealCurrent: true) | |
| 51 | − @search.reset() | |
| 56 | + showDocList: -> | |
| 57 | + @showView @docList | |
| 52 | 58 | return |
| 53 | 59 | |
| 54 | 60 | showDocPicker: => |
| 55 | − @show @docPicker | |
| 61 | + @showView @docPicker | |
| 56 | 62 | return |
| 57 | 63 | |
| 58 | 64 | showResults: => |
| 59 | − @show @results | |
| 65 | + @showView @results | |
| 66 | + return | |
| 67 | + | |
| 68 | + reset: -> | |
| 69 | + @display() | |
| 70 | + @showDocList() | |
| 71 | + @docList.reset() | |
| 72 | + @search.reset() | |
| 60 | 73 | return |
| 61 | 74 | |
| 62 | 75 | onReady: => |
| 63 | 76 | @view = @docList |
| 64 | 77 | @render() |
| 65 | 78 | @view.activate() |
| 66 | − | |
| 67 | − reset: -> | |
| 68 | − @showDocList true | |
| 69 | 79 | return |
| 70 | 80 | |
| 71 | 81 | onScopeChange: (newDoc, previousDoc) => |
| @@ -90,15 +100,30 @@ class app.views.Sidebar extends app.View · 18 unmodified lines | ||
| 90 | 100 | @el.scrollTop = 0 |
| 91 | 101 | return |
| 92 | 102 | |
| 103 | + onSearching: => | |
| 104 | + @display() | |
| 105 | + @showResults() | |
| 106 | + return | |
| 107 | + | |
| 108 | + onSearchClear: => | |
| 109 | + @resetDisplay() | |
| 110 | + @showDocList() | |
| 111 | + return | |
| 112 | + | |
| 93 | 113 | onFocus: (event) => |
| 114 | + @display() | |
| 94 | 115 | $.scrollTo event.target, @el, 'continuous', bottomGap: 2 unless event.target is @el |
| 95 | 116 | return |
| 96 | 117 | |
| 118 | + onSelect: => | |
| 119 | + @resetDisplay() | |
| 120 | + return | |
| 121 | + | |
| 97 | 122 | onClick: (event) => |
| 98 | 123 | return if event.which isnt 1 |
| 99 | 124 | if event.target.hasAttribute? 'data-reset-list' |
| 100 | 125 | $.stopEvent(event) |
| 101 | − @reset() | |
| 126 | + @onAltR() | |
| 102 | 127 | else if event.target.hasAttribute? 'data-light' |
| 103 | 128 | $.stopEvent(event) |
| 104 | 129 | document.activeElement?.blur() |
| @@ -120,6 +145,8 @@ class app.views.Sidebar extends app.View · 15 unmodified lines | ||
| 120 | 145 | |
| 121 | 146 | onAltR: => |
| 122 | 147 | @reset() |
| 148 | + @docList.reset(revealCurrent: true) | |
| 149 | + @display() | |
| 123 | 150 | return |
| 124 | 151 | |
| 125 | 152 | onEscape: => |
| @@ -35,6 +35,13 @@ class app.View · 34 unmodified lines | ||
| 35 | 35 | @el.classList.remove(name) |
| 36 | 36 | return |
| 37 | 37 | |
| 38 | + toggleClass: (name) -> | |
| 39 | + @el.classList.toggle(name) | |
| 40 | + return | |
| 41 | + | |
| 42 | + hasClass: (name) -> | |
| 43 | + @el.classList.contains(name) | |
| 44 | + | |
| 38 | 45 | resetClass: -> |
| 39 | 46 | @el.className = @originalClassName or '' |
| 40 | 47 | if @constructor.className |