Index: js/ajax-responder.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/ctools/js/ajax-responder.js,v
retrieving revision 1.18.2.24
diff -u -p -r1.18.2.24 ajax-responder.js
--- js/ajax-responder.js	27 Aug 2010 22:09:48 -0000	1.18.2.24
+++ js/ajax-responder.js	5 Nov 2010 19:54:56 -0000
@@ -49,7 +49,7 @@
     var $objects = $('a[href=' + old_url + ']')
     $objects.addClass('ctools-fetching');
     try {
-      url = old_url.replace(/\/nojs(\/|$)/g, '/ajax$1');
+      url = Drupal.CTools.AJAX.urlReplaceNojs(url);
       $.ajax({
         type: "POST",
         url: url,
@@ -108,7 +108,7 @@
     var object = $(this);
     $(this).addClass('ctools-ajaxing');
     try {
-      url = url.replace(/\/nojs(\/|$)/g, '/ajax$1');
+      url = Drupal.CTools.AJAX.urlReplaceNojs(url);
       $.ajax({
         type: "POST",
         url: url,
@@ -150,7 +150,7 @@
     var object = $(this);
     try {
       if (url) {
-        url = url.replace(/\/nojs(\/|$)/g, '/ajax$1');
+        url = Drupal.CTools.AJAX.urlReplaceNojs(url);;
         $.ajax({
           type: "POST",
           url: url,
@@ -196,7 +196,7 @@
     $form.addClass('ctools-ajaxing');
 
     try {
-      url = url.replace(/\/nojs(\/|$)/g, '/ajax$1');
+      url = Drupal.CTools.AJAX.urlReplaceNojs(url);
 
       var ajaxOptions = {
         type: 'POST',
@@ -287,7 +287,7 @@
     var form_id = $(object).parents('form').get(0).id;
     try {
       if (url) {
-        url = url.replace(/\/nojs(\/|$)/g, '/ajax$1');
+        url = Drupal.CTools.AJAX.urlReplaceNojs(url);
         $.ajax({
           type: "POST",
           url: url,
@@ -518,6 +518,22 @@
     $(data.selector).submit();
   }
 
+  /**
+   * Replacing 'nojs' with 'ajax' in the URL allows for an easy method to let
+   * the server detect when it needs to degrade gracefully. 
+   * There are five scenarios to check for:
+   * 1. /nojs/
+   * 2. /nojs$ - The end of a URL string.
+   * 3. /nojs? - Followed by a query (with clean URLs enabled).
+   *      E.g.: path/nojs?destination=foobar
+   * 4. /nojs& - Followed by a query (without clean URLs enabled).
+   *      E.g.: ?q=path/nojs&destination=foobar
+   * 5. /nojs# - Followed by a fragment.
+   *      E.g.: path/nojs#myfragment
+   */
+  Drupal.CTools.AJAX.urlReplaceNojs = function(url) {
+    return url.replace(/\/nojs(\/|$|\?|&|#)/g, '/ajax$1');
+  }
 
   /**
    * Bind links that will open modals to the appropriate function.
