diff --git a/config/assets.yml b/config/assets.yml
index 1f154e490ee91ad717a96d03f62bec164aef6a5d..efe6ec11e710d20ffc4d7111a724ba136e78b79f 100644
--- a/config/assets.yml
+++ b/config/assets.yml
@@ -48,7 +48,7 @@ javascripts:
     - public/javascripts/aspect-edit.js
     - public/javascripts/contact-list.js
   home:
-    - public/javascripts/publisher.js
+    - public/javascripts/widgets/publisher.js
     - public/javascripts/aspect-filters.js
     - public/javascripts/contact-list.js
   people:
diff --git a/public/javascripts/widgets/publisher.js b/public/javascripts/widgets/publisher.js
new file mode 100644
index 0000000000000000000000000000000000000000..3b3a2dbaf7cb4eb22c39aa73fb5c6dd9acf37c04
--- /dev/null
+++ b/public/javascripts/widgets/publisher.js
@@ -0,0 +1,68 @@
+/*   Copyright (c) 2010, Diaspora Inc.  This file is
+ *   licensed under the Affero General Public License version 3 or later.  See
+ *   the COPYRIGHT file.
+ */
+
+(function() {
+  var Publisher = function() {
+    var self = this;
+
+    this.start = function() {
+      this.$publisher = $("#publisher");
+      this.$realMessage = this.$publisher.find("#status_message_message");
+      this.$fakeMessage = this.$publisher.find("#status_message_fake_message");
+
+      if(this.$fakeMessage.val() === "") {
+        this.toggle();
+      }
+
+
+      $("div.public_toggle input").live("click", function(evt) {
+        $("#publisher_service_icons").toggleClass("dim");
+        if (this.checked) {
+          $(".question_mark").click();
+        }
+      });
+
+      self
+        .$publisher
+        .find("textarea")
+        .focus(self.toggle)
+        .blur(self.toggle);
+
+
+      self
+        .$fakeMessage
+        .change(self.updateHiddenField);
+
+      self.updateHiddenField();
+    };
+
+    this.toggle = function() { 
+      self
+        .$publisher
+        .toggleClass("closed")
+        .find(".options_and_submit")
+        .toggle(
+          !self.$publisher.hasClass("closed")
+        );
+
+      self
+        .$fakeMessage
+        .css("min-height", (self.$publisher.hasClass("closed"))
+          ? ""
+          : "42px");
+    };
+
+    this.updateHiddenField = function() {
+      self
+        .$realMessage
+        .val(
+          self.$fakeMessage.val()
+        );
+    };
+  };
+
+  Diaspora.widgets.add("publisher", Publisher);
+
+})();
diff --git a/spec/javascripts/publisher-spec.js b/spec/javascripts/publisher-spec.js
index 203390b9c094207ac1fbe65234ef8eaa7bad403c..c479741f63640a90b5bd3ce4e6e3a8a0e4b9b22e 100644
--- a/spec/javascripts/publisher-spec.js
+++ b/spec/javascripts/publisher-spec.js
@@ -1,81 +1,79 @@
 /*   Copyright (c) 2010, Diaspora Inc.  This file is
-*   licensed under the Affero General Public License version 3 or later.  See
-*   the COPYRIGHT file.
-*/
+ *   licensed under the Affero General Public License version 3 or later.  See
+ *   the COPYRIGHT file.
+ */
 
-describe("Publisher", function() {
-
-    describe("initialize", function(){
-      it("calls updateHiddenField", function(){
-        spec.loadFixture('aspects_index_prefill');
-        spyOn(Publisher, 'updateHiddenField');
-        Publisher.initialize();
-        expect(Publisher.updateHiddenField).toHaveBeenCalled();
-      });
+describe("Diaspora", function() {
+  describe("widgets", function() {
+    describe("publisher", function() {
+      describe("start", function() {
+        it("calls updateHiddenField", function() {
+          spec.loadFixture('aspects_index_prefill');
+          spyOn(Diaspora.widgets.publisher, 'updateHiddenField');
+         Diaspora.widgets.publisher.start();
+          expect(Diaspora.widgets.publisher.updateHiddenField).toHaveBeenCalled();
+        });
 
-      it("attaches updateHiddenField to the change handler on fake_message", function(){
-        spec.loadFixture('aspects_index_prefill');
-        spyOn(Publisher, 'updateHiddenField');
-        Publisher.initialize();
-        Publisher.form().find('#status_message_fake_message').change();
-        expect(Publisher.updateHiddenField.mostRecentCall.args[0].type).toBe('change');
-      });
+        it("attaches updateHiddenField to the change handler on fake_message", function() {
+          spec.loadFixture('aspects_index_prefill');
+          spyOn(Diaspora.widgets.publisher, 'updateHiddenField');
+          Diaspora.widgets.publisher.start();
+          Diaspora.widgets.publisher.$fakeMessage.change();
+          expect(Diaspora.widgets.publisher.updateHiddenField.mostRecentCall.args[0].type).toBe('change');
+        });
 
-      it("calls close when it does not have text", function(){
-        spec.loadFixture('aspects_index');
-        spyOn(Publisher, 'close');
-        Publisher.initialize();
-        expect(Publisher.close).toHaveBeenCalled();
-      });
+        it("calls toggle when it does not have text", function() {
+          spec.loadFixture('aspects_index');
+          spyOn(Diaspora.widgets.publisher, 'toggle');
+          Diaspora.widgets.publisher.start();
+          expect(Diaspora.widgets.publisher.toggle).toHaveBeenCalled();
+        });
 
-      it("does not call close when there is prefilled text", function(){
-        spec.loadFixture('aspects_index_prefill');
-        spyOn(Publisher, 'close');
-        Publisher.initialize();
-        expect(Publisher.close).wasNotCalled();
+        it("does not call toggle when there is prefilled text", function() {
+          spec.loadFixture('aspects_index_prefill');
+          spyOn(Diaspora.widgets.publisher, 'toggle');
+          Diaspora.widgets.publisher.start();
+          expect(Diaspora.widgets.publisher.toggle).not.toHaveBeenCalled();
         });
-    });
-    describe("open", function() {
-      beforeEach(function() {
-        spec.loadFixture('aspects_index');
-        Publisher.initialize();
       });
-      it("removes the closed class", function() {
-        expect(Publisher.form().hasClass('closed')).toBeTruthy();
-        Publisher.open();
-        expect(Publisher.form().hasClass('closed')).toBeFalsy();
+      describe("toggle", function() {
+        beforeEach(function() {
+          spec.loadFixture('aspects_index');
+          Diaspora.widgets.publisher.start();
         });
-      it("shows the options_and_submit div", function() {
-        expect(Publisher.form().find(".options_and_submit:visible").length).toBe(0);
-        Publisher.open();
-        expect(Publisher.form().find(".options_and_submit:visible").length).toBe(1);
-        });
-    });
-    describe("close", function() {
-      beforeEach(function() {
-        spec.loadFixture('aspects_index_prefill');
-        Publisher.initialize();
-        });
-      it("adds the closed class", function() {
-        expect(Publisher.form().hasClass('closed')).toBeFalsy();
-        Publisher.close();
-        expect(Publisher.form().hasClass('closed')).toBeTruthy();
+        it("toggles the closed class", function() {
+          expect(Diaspora.widgets.publisher.$publisher.hasClass('closed')).toBeTruthy();
+          Diaspora.widgets.publisher.toggle();
+          expect(Diaspora.widgets.publisher.$publisher.hasClass('closed')).toBeFalsy();
+
+          expect(Diaspora.widgets.publisher.$publisher.hasClass('closed')).toBeFalsy();
+          Diaspora.widgets.publisher.toggle();
+          expect(Diaspora.widgets.publisher.$publisher.hasClass('closed')).toBeTruthy;
         });
-      it("hides the options_and_submit div", function() {
-        expect(Publisher.form().find(".options_and_submit:visible").length).toBe(1);
-        Publisher.close();
-        expect(Publisher.form().find(".options_and_submit:visible").length).toBe(0);
+
+        it("toggles the options_and_submit div", function() {
+          expect(Diaspora.widgets.publisher.$publisher.find(".options_and_submit").is(":visible")).toBeFalsy();
+          Diaspora.widgets.publisher.toggle();
+          expect(Diaspora.widgets.publisher.$publisher.find(".options_and_submit").is(":visible")).toBeTruthy();
+
+
+          expect(Diaspora.widgets.publisher.$publisher.find(".options_and_submit").is(":visible")).toBeTruthy();
+          Diaspora.widgets.publisher.toggle();
+          expect(Diaspora.widgets.publisher.$publisher.find(".options_and_submit").is(":visible")).toBeFalsy();
         });
-    });
-    describe("updateHiddenField", function(){
-      beforeEach(function(){
-        spec.loadFixture('aspects_index_prefill');
       });
 
-      it("copies the value of fake_message to message",function(){
-        Publisher.updateHiddenField();
-        expect(Publisher.form().find('#status_message_message').val()).toBe(
-          Publisher.form().find('#status_message_fake_message').val());
+      describe("updateHiddenField", function() {
+        beforeEach(function() {
+          spec.loadFixture('aspects_index_prefill');
+        });
+
+        it("copies the value of fake_message to message", function() {
+          Diaspora.widgets.publisher.updateHiddenField();
+          expect(Diaspora.widgets.publisher.$realMessage.val()).toBe(
+              Diaspora.widgets.publisher.$fakeMessage.val());
+        });
       });
     });
-});
+  });
+});
\ No newline at end of file
diff --git a/spec/javascripts/support/jasmine.yml b/spec/javascripts/support/jasmine.yml
index f142bd8f1967181476ec1b4ade2f0c60e2ed4656..1354e8d2b144b4e468931e7bc7010184160c3c85 100644
--- a/spec/javascripts/support/jasmine.yml
+++ b/spec/javascripts/support/jasmine.yml
@@ -24,12 +24,12 @@ src_files:
   - public/javascripts/widgets/embedder.js
   - public/javascripts/widgets/i18n.js
   - public/javascripts/widgets/timeago.js
+  - public/javascripts/widgets/publisher.js
   - public/javascripts/mobile.js
   - public/javascripts/aspect-edit.js
   - public/javascripts/aspect-contacts.js
   - public/javascripts/web-socket-receiver.js
   - public/javascripts/view.js
-  - public/javascripts/publisher.js
   - public/javascripts/stream.js
   - public/javascripts/validation.js
   - public/javascripts/rails.js