浏览代码

Add back/forward buttons on mobile

Closes #221.
Thibaut Courouble 9 年之前
父节点
当前提交
7303212dd2

二进制
assets/images/icons.png


二进制
assets/images/icons@2x.png


+ 12 - 0
assets/javascripts/lib/page.coffee

@@ -61,6 +61,12 @@ page.dispatch = (context) ->
   next()
   return
 
+page.canGoBack = ->
+  not Context.isIntialState(currentState)
+
+page.canGoForward = ->
+  not Context.isLastState(currentState)
+
 currentPath = ->
   location.pathname + location.search + location.hash
 
@@ -69,6 +75,12 @@ class Context
   @sessionId: Date.now()
   @stateId: 0
 
+  @isIntialState: (state) ->
+    state.id == 0
+
+  @isLastState: (state) ->
+    state.id == @stateId - 1
+
   @isInitialPopState: (state) ->
     state.path is @initialPath and @stateId is 1
 

+ 24 - 2
assets/javascripts/views/layout/mobile.coffee

@@ -37,10 +37,16 @@ class app.views.Mobile extends app.View
       app.shortcuts.stop()
 
     $.on @body, 'click', @onClick
-    $.on $('._home-link'), 'click', @onClickHome
-    $.on $('._menu-link'), 'click', @onClickMenu
+    $.on $('._home-btn'), 'click', @onClickHome
+    $.on $('._menu-btn'), 'click', @onClickMenu
     $.on $('._search'), 'touchend', @onTapSearch
 
+    @back = $('._back-btn')
+    $.on @back, 'click', @onClickBack
+
+    @forward = $('._forward-btn')
+    $.on @forward, 'click', @onClickForward
+
     app.document.sidebar.search
       .on 'searching', @showSidebar
       .on 'clear', @hideSidebar
@@ -76,6 +82,12 @@ class app.views.Mobile extends app.View
       @showSidebar()
     return
 
+  onClickBack: =>
+    history.back()
+
+  onClickForward: =>
+    history.forward()
+
   onClickHome: =>
     app.shortcuts.trigger 'escape'
     @hideSidebar()
@@ -90,4 +102,14 @@ class app.views.Mobile extends app.View
 
   afterRoute: =>
     @hideSidebar()
+
+    if page.canGoBack()
+      @back.removeAttribute('disabled')
+    else
+      @back.setAttribute('disabled', 'disabled')
+
+    if page.canGoForward()
+      @forward.removeAttribute('disabled')
+    else
+      @forward.setAttribute('disabled', 'disabled')
     return

+ 30 - 7
assets/stylesheets/components/_mobile.scss

@@ -34,7 +34,7 @@
   }
 
   ._logo, ._nav { display: none; }
-  ._home-link, ._menu-link { display: block; }
+  ._mobile-btn { display: block; }
 
   ._search {
     float: none;
@@ -149,12 +149,17 @@
 // Header buttons
 //
 
-%mobile-link {
+._mobile-btn {
   display: none;
   position: relative;
   float: left;
   width: 2.5rem;
   height: 100%;
+  background: none;
+  border: 0;
+  @extend %hide-text;
+
+  &[disabled] { opacity: .3; }
 
   &:before {
     position: absolute;
@@ -165,15 +170,33 @@
   }
 }
 
-._home-link {
-  @extend %mobile-link;
+._back-btn {
+  &:before { @extend %icon-back; }
+}
+
+._forward-btn {
+  width: 2.25rem;
+  -webkit-transform: rotate(180deg);
+          transform: rotate(180deg);
 
-  &:before { @extend %icon-home; }
+  &:before {
+    margin-left: -.375rem;
+    @extend %icon-back;
+  }
+}
+
+._home-btn {
+  float: right;
+  width: 2rem;
+
+  &:before {
+    margin-left: -.375rem;
+    @extend %icon-home;
+  }
 }
 
-._menu-link {
+._menu-btn {
   float: right;
-  @extend %mobile-link;
 
   &:before { @extend %icon-menu; }
 }

+ 7 - 0
assets/stylesheets/global/_classes.scss

@@ -14,6 +14,13 @@
           user-select: none;
 }
 
+%hide-text {
+  white-space: nowrap;
+  overflow: hidden;
+  color: transparent;
+  @extend %user-select-none;
+}
+
 //
 // Boxes
 //

+ 3 - 2
assets/stylesheets/global/_icons.scss

@@ -37,8 +37,8 @@
 %icon-clear                 { background-position: -3rem 0; }
 %icon-settings              { background-position: 0 -1rem; }
 %icon-check                 { background-position: -1rem -1rem; }
-%icon-menu                  { background-position: -2rem -1rem; }
-%icon-home                  { background-position: -3rem -1rem; }
+%icon-menu                  { background-position: -2rem -1rem; @extend %darkIconFix !optional; }
+%icon-home                  { background-position: -3rem -1rem; @extend %darkIconFix !optional; }
 %icon-path                  { background-position: 0 -2rem; }
 %icon-search-white          { background-position: -1rem -2rem; }
 %icon-dir-white             { background-position: -2rem -2rem; }
@@ -54,6 +54,7 @@
 %icon-clipboard             { background-position: 0 -5rem; }
 %icon-clipboard-white       { background-position: -1rem -5rem; }
 %icon-close-white           { background-position: -2rem -5rem; }
+%icon-back                  { background-position: -3rem -5rem; @extend %darkIconFix !optional; }
 
 ._icon-http:before          { background-position: -7rem 0; @extend %darkIconFix !optional; }
 ._icon-jquery:before        { background-position: -8rem 0; @extend %darkIconFix !optional; }

二进制
public/icons/ui/back/16.png


二进制
public/icons/ui/back/16@2x.png


+ 4 - 2
views/app.erb

@@ -1,7 +1,9 @@
 <div class="_app<%= " #{app_layout}" if app_layout %>">
   <header class="_header">
-    <a class="_home-link"></a>
-    <a class="_menu-link"></a>
+    <button type="button" class="_mobile-btn _back-btn">Back</button>
+    <button type="button" class="_mobile-btn _forward-btn">Forward</button>
+    <button type="button" class="_mobile-btn _menu-btn">Menu</button>
+    <button type="button" class="_mobile-btn _home-btn">Home</button>
     <form class="_search">
       <input type="search" class="_search-input" placeholder="Search&hellip;" autocomplete="off" autocapitalize="off" autocorrect="off" spellcheck="false" maxlength="30" aria-label="Search">
       <a class="_search-clear"></a>