History

Implement resizable sidebar

Closes #88.

Thibaut committed 11 years ago

Commit e2afa6e1 parent 9bb745f8 files · +91 −1Browse files

Unified · Split

8 files
  1. assets/javascripts/app/settings.coffee +8 −0
  2. assets/javascripts/news.json +4 −1
  3. assets/javascripts/views/layout/document.coffee +1 −0
  4. assets/javascripts/views/layout/resizer.coffee +46 −0
  5. assets/stylesheets/components/_sidebar.scss +11 −0
  6. lib/app.rb +4 −0
  7. test/app_test.rb +11 −0
  8. views/app.erb +6 −0
assets/javascripts/app/settings.coffee+8−0
@@ -2,6 +2,7 @@ class app.Settings · 1 unmodified line
2 SETTINGS_KEY = 'settings'2 SETTINGS_KEY = 'settings'
3 DOCS_KEY = 'docs'3 DOCS_KEY = 'docs'
4 DARK_KEY = 'dark'4 DARK_KEY = 'dark'
5 SIZE_KEY = 'size'
5 6
6 @defaults: ->7 @defaults: ->
7 count: 08 count: 0
@@ -59,8 +60,15 @@ class app.Settings · 51 unmodified lines
59 catch60 catch
60 return61 return
61 62
63 setSize: (value) ->
64 try
65 Cookies.set SIZE_KEY, value, path: '/', expires: 1e8
66 catch
67 return
68
62 reset: ->69 reset: ->
63 try Cookies.expire DOCS_KEY70 try Cookies.expire DOCS_KEY
64 try Cookies.expire DARK_KEY71 try Cookies.expire DARK_KEY
72 try Cookies.expire SIZE_KEY
65 try @store.del(SETTINGS_KEY)73 try @store.del(SETTINGS_KEY)
66 return74 return
assets/javascripts/news.json+4−1
@@ -1,5 +1,8 @@
1[1[
2 [ "2015-02-15",2 [ "2015-02-16",
3 "The sidebar is now resizable (drag & drop)."
4 ], [
5 "2015-02-15",
3 "New <a href=\"/iojs/\">io.js</a>, <a href=\"/symfony/\">Symfony</a>, <a href=\"/clojure/\">Clojure</a>, <a href=\"/lua/\">Lua</a> and <a href=\"/yii1/\">Yii 1.1</a> documentations"6 "New <a href=\"/iojs/\">io.js</a>, <a href=\"/symfony/\">Symfony</a>, <a href=\"/clojure/\">Clojure</a>, <a href=\"/lua/\">Lua</a> and <a href=\"/yii1/\">Yii 1.1</a> documentations"
4 ], [7 ], [
5 "2015-02-08",8 "2015-02-08",
assets/javascripts/views/layout/document.coffee+1−0
@@ -10,6 +10,7 @@ class app.views.Document extends app.View · 9 unmodified lines
10 init: ->10 init: ->
11 @addSubview @nav = new app.views.Nav,11 @addSubview @nav = new app.views.Nav,
12 @addSubview @sidebar = new app.views.Sidebar12 @addSubview @sidebar = new app.views.Sidebar
13 @addSubview @resizer = new app.views.Resizer if app.views.Resizer.isSupported()
13 @addSubview @content = new app.views.Content14 @addSubview @content = new app.views.Content
14 @addSubview @path = new app.views.Path unless app.isSingleDoc() or app.isMobile()15 @addSubview @path = new app.views.Path unless app.isSingleDoc() or app.isMobile()
15 16
assets/javascripts/views/layout/resizer.coffee+46−0
@@ -0,0 +1,46 @@
1class app.views.Resizer extends app.View
2 @className: '_resizer'
3
4 @events:
5 dragstart: 'onDragStart'
6 dragend: 'onDragEnd'
7 drag: 'onDrag'
8
9 @isSupported: ->
10 'ondragstart' of document.createElement('div') and !app.isMobile()
11
12 init: ->
13 @el.setAttribute('draggable', 'true')
14 @appendTo $('._app')
15
16 @style = $('style[data-resizer]')
17 @size = @style.getAttribute('data-size')
18 return
19
20 MIN = 250
21 MAX = 600
22
23 resize: (newSize) ->
24 return unless newSize > 0
25 newSize = Math.min(Math.max(Math.round(newSize), MIN), MAX)
26 app.settings.setSize(newSize)
27 newSize = "#{newSize}px"
28 @style.innerHTML = @style.innerHTML.replace(new RegExp(@size, 'g'), newSize)
29 @size = newSize
30 return
31
32 onDragStart: (event) =>
33 @style.removeAttribute('disabled')
34 event.dataTransfer.effectAllowed = 'link'
35 event.dataTransfer.setData('text/plain', '')
36 return
37
38 onDrag: (event) =>
39 return if @lastDrag and @lastDrag > Date.now() - 50
40 @lastDrag = Date.now()
41 @resize event.clientX
42 return
43
44 onDragEnd: (event) =>
45 @resize event.screenX - window.screenX
46 return
assets/stylesheets/components/_sidebar.scss+11−0
@@ -35,6 +35,17 @@ · 34 unmodified lines
35 a:focus { outline: 0; }35 a:focus { outline: 0; }
36}36}
37 37
38._resizer {
39 position: absolute;
40 z-index: $sidebarZ + 1;
41 top: $headerHeight;
42 bottom: 0;
43 left: $sidebarWidth;
44 margin-left: -2px;
45 width: 3px;
46 cursor: col-resize;
47}
48
38//49//
39// List50// List
40//51//
lib/app.rb+4−0
@@ -136,6 +136,10 @@ class App < Sinatra::Application · 135 unmodified lines
136 dark: stylesheet_path('application-dark')136 dark: stylesheet_path('application-dark')
137 }137 }
138 end138 end
139
140 def size
141 @size ||= cookies[:size].nil? ? '18rem' : "#{cookies[:size]}px"
142 end
139 end143 end
140 144
141 before do145 before do
test/app_test.rb+11−0
@@ -20,6 +20,17 @@ class AppTest < MiniTest::Spec · 19 unmodified lines
20 assert last_response.redirect?20 assert last_response.redirect?
21 assert_equal 'http://example.org/', last_response['Location']21 assert_equal 'http://example.org/', last_response['Location']
22 end22 end
23
24 it "sets default size" do
25 get '/'
26 assert_includes last_response.body, 'data-size="18rem"'
27 end
28
29 it "sets size from cookie" do
30 set_cookie('size=42')
31 get '/'
32 assert_includes last_response.body, 'data-size="42px"'
33 end
23 end34 end
24 35
25 describe "/[static-page]" do36 describe "/[static-page]" do
views/app.erb+6−0
@@ -44,3 +44,9 @@ · 43 unmodified lines
44 a.src="//secure.gaug.es/track.js";var b=document.getElementsByTagName("script")[0];44 a.src="//secure.gaug.es/track.js";var b=document.getElementsByTagName("script")[0];
45 b.parentNode.insertBefore(a,b)}();45 b.parentNode.insertBefore(a,b)}();
46</script><% end %>46</script><% end %>
47<style data-size="<%= size %>" data-resizer disabled>
48 ._container { margin-left: <%= size %>; }
49 ._search, ._list, ._sidebar-footer { width: <%= size %>; }
50 ._list-hover.clone { min-width: <%= size %>; }
51 ._notice, ._path, ._resizer { left: <%= size %>; }
52</style>