Unified · Split
| @@ -179,6 +179,14 @@ · 178 unmodified lines | |||
| 179 | # enabled because it doesn't support caching URLs that use CORS. | 179 | # enabled because it doesn't support caching URLs that use CORS. |
| 180 | @config[if @appCache and @settings.hasDocs() then 'index_path' else 'docs_host'] | 180 | @config[if @appCache and @settings.hasDocs() then 'index_path' else 'docs_host'] |
| 181 | 181 | ||
| 182 | toggleSidebar: -> | ||
| 183 | state = @el.getAttribute('data-sidebar') | ||
| 184 | newState = if state == 'visible' then 'hidden' else 'visible' | ||
| 185 | @el.setAttribute('data-sidebar', newState) | ||
| 186 | @settings.setSidebar(newState) | ||
| 187 | @appCache?.updateInBackground() | ||
| 188 | return | ||
| 189 | |||
| 182 | onBootError: (args...) -> | 190 | onBootError: (args...) -> |
| 183 | @trigger 'bootError' | 191 | @trigger 'bootError' |
| 184 | @hideLoading() | 192 | @hideLoading() |
| @@ -4,6 +4,7 @@ class app.Settings · 3 unmodified lines | |||
| 4 | DARK_KEY = 'dark' | 4 | DARK_KEY = 'dark' |
| 5 | LAYOUT_KEY = 'layout' | 5 | LAYOUT_KEY = 'layout' |
| 6 | SIZE_KEY = 'size' | 6 | SIZE_KEY = 'size' |
| 7 | SIDEBAR_KEY = 'sidebar' | ||
| 7 | 8 | ||
| 8 | @defaults: | 9 | @defaults: |
| 9 | count: 0 | 10 | count: 0 |
| @@ -77,10 +78,17 @@ class app.Settings · 67 unmodified lines | |||
| 77 | catch | 78 | catch |
| 78 | return | 79 | return |
| 79 | 80 | ||
| 81 | setSidebar: (value) -> | ||
| 82 | try | ||
| 83 | Cookies.set SIDEBAR_KEY, value, path: '/', expires: 1e8 | ||
| 84 | catch | ||
| 85 | return | ||
| 86 | |||
| 80 | reset: -> | 87 | reset: -> |
| 81 | try Cookies.expire DOCS_KEY | 88 | try Cookies.expire DOCS_KEY |
| 82 | try Cookies.expire DARK_KEY | 89 | try Cookies.expire DARK_KEY |
| 83 | try Cookies.expire LAYOUT_KEY | 90 | try Cookies.expire LAYOUT_KEY |
| 84 | try Cookies.expire SIZE_KEY | 91 | try Cookies.expire SIZE_KEY |
| 92 | try Cookies.expire SIDEBAR_KEY | ||
| 85 | try @store.del(SETTINGS_KEY) | 93 | try @store.del(SETTINGS_KEY) |
| 86 | return | 94 | return |
| @@ -4,6 +4,7 @@ class app.views.Resizer extends app.View · 3 unmodified lines | |||
| 4 | @events: | 4 | @events: |
| 5 | dragstart: 'onDragStart' | 5 | dragstart: 'onDragStart' |
| 6 | dragend: 'onDragEnd' | 6 | dragend: 'onDragEnd' |
| 7 | dblclick: 'onDbLClick' | ||
| 7 | 8 | ||
| 8 | @isSupported: -> | 9 | @isSupported: -> |
| 9 | 'ondragstart' of document.createElement('div') and !app.isMobile() | 10 | 'ondragstart' of document.createElement('div') and !app.isMobile() |
| @@ -31,6 +32,10 @@ class app.views.Resizer extends app.View · 21 unmodified lines | |||
| 31 | app.appCache?.updateInBackground() | 32 | app.appCache?.updateInBackground() |
| 32 | return | 33 | return |
| 33 | 34 | ||
| 35 | onDbLClick: (event) => | ||
| 36 | app.toggleSidebar() | ||
| 37 | return | ||
| 38 | |||
| 34 | onDragStart: (event) => | 39 | onDragStart: (event) => |
| 35 | @style.removeAttribute('disabled') | 40 | @style.removeAttribute('disabled') |
| 36 | event.dataTransfer.effectAllowed = 'link' | 41 | event.dataTransfer.effectAllowed = 'link' |
| @@ -10,6 +10,10 @@ · 9 unmodified lines | |||
| 10 | pointer-events: none; | 10 | pointer-events: none; |
| 11 | @extend %border-box; | 11 | @extend %border-box; |
| 12 | 12 | ||
| 13 | ._app[data-sidebar="hidden"] & { | ||
| 14 | margin-left: 0; | ||
| 15 | } | ||
| 16 | |||
| 13 | @media #{$mediumScreen} { margin-left: $sidebarMediumWidth; } | 17 | @media #{$mediumScreen} { margin-left: $sidebarMediumWidth; } |
| 14 | } | 18 | } |
| 15 | 19 | ||
| @@ -11,6 +11,10 @@ · 10 unmodified lines | |||
| 11 | background: $pathBackground; | 11 | background: $pathBackground; |
| 12 | box-shadow: inset 0 1px $pathBorder; | 12 | box-shadow: inset 0 1px $pathBorder; |
| 13 | 13 | ||
| 14 | ._app[data-sidebar="hidden"] & { | ||
| 15 | left: 0; | ||
| 16 | } | ||
| 17 | |||
| 14 | @media #{$mediumScreen} { left: $sidebarMediumWidth; } | 18 | @media #{$mediumScreen} { left: $sidebarMediumWidth; } |
| 15 | 19 | ||
| 16 | ~ ._container { padding-bottom: 2rem; } | 20 | ~ ._container { padding-bottom: 2rem; } |
| @@ -33,6 +33,10 @@ · 32 unmodified lines | |||
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | a:focus { outline: 0; } | 35 | a:focus { outline: 0; } |
| 36 | |||
| 37 | ._app[data-sidebar="hidden"] & { | ||
| 38 | display: none; | ||
| 39 | } | ||
| 36 | } | 40 | } |
| 37 | 41 | ||
| 38 | ._resizer { | 42 | ._resizer { |
| @@ -44,6 +48,13 @@ · 5 unmodified lines | |||
| 44 | margin-left: -2px; | 48 | margin-left: -2px; |
| 45 | width: 3px; | 49 | width: 3px; |
| 46 | cursor: col-resize; | 50 | cursor: col-resize; |
| 51 | |||
| 52 | ._app[data-sidebar="hidden"] & { | ||
| 53 | border: 1px solid $headerBorder; | ||
| 54 | background-color: $headerBackground; | ||
| 55 | margin-left: 0; | ||
| 56 | left: 1px; | ||
| 57 | } | ||
| 47 | } | 58 | } |
| 48 | 59 | ||
| 49 | // | 60 | // |
| @@ -185,6 +185,10 @@ class App < Sinatra::Application · 184 unmodified lines | |||
| 185 | app_theme == 'dark' | 185 | app_theme == 'dark' |
| 186 | end | 186 | end |
| 187 | 187 | ||
| 188 | def app_sidebar | ||
| 189 | cookies[:sidebar].nil? ? 'visible' : cookies[:sidebar] | ||
| 190 | end | ||
| 191 | |||
| 188 | def redirect_via_js(path) # courtesy of HTML5 App Cache | 192 | def redirect_via_js(path) # courtesy of HTML5 App Cache |
| 189 | response.set_cookie :initial_path, value: path, expires: Time.now + 15, path: '/' | 193 | response.set_cookie :initial_path, value: path, expires: Time.now + 15, path: '/' |
| 190 | redirect '/', 302 | 194 | redirect '/', 302 |
| @@ -1,4 +1,4 @@ | |||
| 1 | <div class="_app<%= " #{app_layout}" if app_layout %>"> | 1 | <div class="_app<%= " #{app_layout}" if app_layout %>" data-sidebar="<%= "#{app_sidebar}" if app_sidebar %>"> |
| 2 | <header class="_header"> | 2 | <header class="_header"> |
| 3 | <a class="_home-link"></a> | 3 | <a class="_home-link"></a> |
| 4 | <a class="_menu-link"></a> | 4 | <a class="_menu-link"></a> |