           mbShortUrl (and localStorage
                           (.getItem localStorage localStorageKey))]
       (cond mbShortUrl
-            (.val $urlShortenerInput mbShortUrl)
+            ; the set! on `SHORTENING-IN-PROGRESS` is carried out to clear away
+            ; any actions that may have been added by the :else part of this
+            ; `cond` after the url has been shortened
+            (do (set! SHORTENING-IN-PROGRESS
+                      (dissoc SHORTENING-IN-PROGRESS currentUrl))
+                (.val $urlShortenerInput mbShortUrl)
+                (if actionAfterDone
+                    (do-action-after-url-shortening mbShortUrl actionAfterDone)))
 
             (not (contains? SHORTENING-IN-PROGRESS currentUrl))
-            (make-request-to-get-short-url currentUrl $urlShortenerInput
-                                           localStorage localStorageKey)))))
+            (do (add-url-and-action-to-shortening-in-progress currentUrl
+                                                              actionAfterDone)
+                (make-request-to-get-short-url currentUrl actionAfterDone
+                                               $urlShortenerInput localStorage
+                                               localStorageKey))
+
+            ; currentUrl in `SHORTENING-IN-PROGRESS`.
+            ; add `actionAfterDone` to the set of actions to perform
+            :else
+            (add-url-and-action-to-shortening-in-progress currentUrl
+                                                          actionAfterDone)))))
 
 (defn- qtip-for-sharing-button
   "Add qtip for social sharing buttons"

        localStorage        (aget js/window "localStorage")
        zcbClient           (ZeroClipboard. $copy-to-clipboard)
        $urlShortenerInput  ($ :#url-shortener)
        get-url-evt-handler (get-short-url-jq-evt-handler-maker
                              $urlShortenerInput localStorage)
        qtipOrgCopyText     "Copy to Clipboard"

        (initialize-exhibit3 (aget js/window "MODULES")
                             (aget js/window "AUXMODULES")))))

(def ^{:doc     "A map of urls that have been sent for shortening, but whose
                 ajax requests have not yet completed.

                 Values are a set of actions to be performed after the url
                 shortening has been done; refer to the
                 `action-after-url-shortening` function for more details on the
                 actions."
       :private true}
  SHORTENING-IN-PROGRESS {})

(defn- add-url-and-action-to-shortening-in-progress
  "Adds a url and its associated action to `SHORTENING-IN-PROGRESS`"
  [url action]
  (set! SHORTENING-IN-PROGRESS
        (update-in SHORTENING-IN-PROGRESS [url]
                   (fn [actionSet]
                     (if (nil? actionSet)
                         #{action}
                         (conj actionSet action))))))

(defn- do-action-after-url-shortening
  "Performs an action after url shortening"
  [shortUrl action]
  (case action
        :email   (aset js/window
                       "location"
                       (str "mailto:?"
                            "subject=My%20cljs-nusmods%20timetable&body="
                            "&body=" (js/encodeURI shortUrl)))
        :twitter nil
        nil      nil))

(defn- make-request-to-get-short-url
  "Makes the ajax request to the server to obtain a short url"
  [currentUrl actionAfterDone $urlShortenerInput localStorage localStorageKey]
  (ajax "/shorten"
        {:data     {:url (js/encodeURI currentUrl)}
         :dataType "json"
