From cc1ac843cc520acb26eb0f6482593057600c7e83 Mon Sep 17 00:00:00 2001
From: danielgrippi <danielgrippi@gmail.com>
Date: Fri, 20 Jan 2012 22:30:27 -0800
Subject: [PATCH] re-added widget; fixed tests; use _.throttle instead of
 depricated custom debounce

---
 app/views/layouts/application.html.haml      |  4 ++
 public/javascripts/widgets/back-to-top.js    | 33 ++++++++++++
 public/stylesheets/sass/application.sass     | 17 +++++++
 spec/javascripts/widgets/back-to-top-spec.js | 53 ++++++++++++++++++++
 4 files changed, 107 insertions(+)
 create mode 100644 public/javascripts/widgets/back-to-top.js
 create mode 100644 spec/javascripts/widgets/back-to-top-spec.js

diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index cc6ddcad8f..9533c07e81 100644
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -133,6 +133,10 @@
         .span-24.last{:style=> "#{yield(:break_the_mold)}"}
           = yield
 
+    - unless @landing_page
+      %a{:id=>"back-to-top", :title=>"Back to top", :href=>"#"}
+        &#8679;
+
     %footer
       .container
         %ul#footer_nav
diff --git a/public/javascripts/widgets/back-to-top.js b/public/javascripts/widgets/back-to-top.js
new file mode 100644
index 0000000000..a76c09439f
--- /dev/null
+++ b/public/javascripts/widgets/back-to-top.js
@@ -0,0 +1,33 @@
+(function() {
+  var BackToTop = function() {
+    var self = this;
+
+    this.subscribe("widget/ready", function(evt, button) {
+      $.extend(self, {
+        button: button,
+        body: $("html, body"),
+        window: $(window)
+      });
+
+      self.button.click(self.backToTop);
+
+      var throttledScroll = _.throttle($.proxy(self.throttledScroll, self), 250);
+      self.window.scroll(throttledScroll);
+    });
+
+    this.backToTop = function(evt) {
+      evt.preventDefault();
+      self.body.animate({scrollTop: 0});
+    };
+
+    this.toggleVisibility = function() {
+      self.button[
+        (self.body.scrollTop() > 1000) ?
+          'addClass' :
+          'removeClass'
+      ]('visible')
+    };
+  };
+
+  Diaspora.Widgets.BackToTop = BackToTop;
+})();
diff --git a/public/stylesheets/sass/application.sass b/public/stylesheets/sass/application.sass
index 34d27c8cc8..500fb2b990 100644
--- a/public/stylesheets/sass/application.sass
+++ b/public/stylesheets/sass/application.sass
@@ -3506,3 +3506,20 @@ a.toggle_selector
   :position relative
   :margin
     :bottom 15px
+
+#back-to-top
+  :display block
+  :color white
+  :position fixed
+  :z-index 49
+  :right 20px
+  :bottom 20px
+  :opacity 0
+  :font-size 3em
+  :padding 0 11px 0 12px
+  :border-radius 10px
+  :background-color #aaa
+  &:hover
+    :opacity 0.85 !important
+  &:visible
+    :opacity 0.5
\ No newline at end of file
diff --git a/spec/javascripts/widgets/back-to-top-spec.js b/spec/javascripts/widgets/back-to-top-spec.js
new file mode 100644
index 0000000000..ea2e5337f6
--- /dev/null
+++ b/spec/javascripts/widgets/back-to-top-spec.js
@@ -0,0 +1,53 @@
+describe("Diaspora.Widgets.BackToTop", function() {
+  var backToTop;
+  beforeEach(function() {
+    spec.loadFixture("aspects_index");
+    backToTop = Diaspora.BaseWidget.instantiate("BackToTop", $("#back-to-top"));
+    $.fx.off = true;
+  });
+
+  describe("integration", function() {
+    beforeEach(function() {
+      backToTop = new Diaspora.Widgets.BackToTop();
+
+      spyOn(backToTop, "backToTop");
+      spyOn(backToTop, "toggleVisibility");
+
+      backToTop.publish("widget/ready", [$("#back-to-top")]);
+    });
+
+    it("calls backToTop when the button is clicked", function() {
+      backToTop.button.click();
+
+      expect(backToTop.backToTop).toHaveBeenCalled();
+    });
+  });
+
+  describe("backToTop", function() {
+    it("animates scrollTop to 0", function() {
+      backToTop.backToTop($.Event());
+
+      expect($("body").scrollTop()).toEqual(0);
+    });
+  });
+
+  describe("toggleVisibility", function() {
+    it("adds a visibility class to the button", function() {
+      var spy = spyOn(backToTop.body, "scrollTop").andReturn(999);
+
+      backToTop.toggleVisibility();
+
+      expect(backToTop.button.hasClass("visible")).toBe(false);
+
+      spy.andReturn(1001);
+
+      backToTop.toggleVisibility();
+
+      expect(backToTop.button.hasClass("visible")).toBe(true);
+    });
+  });
+
+  afterEach(function() {
+    $.fx.off = false;
+  });
+});
\ No newline at end of file
-- 
GitLab