diff --git a/js/shs.js b/js/shs.js
index 428711e..54ef073 100644
--- a/js/shs.js
+++ b/js/shs.js
@@ -125,6 +125,9 @@
       cache: true,
       data: {
         callback: 'shs_json_term_get_children',
+        js_module: 'shs',
+        js_callback: 'json',
+        js_token: Drupal.settings.js && Drupal.settings.js.tokens && Drupal.settings.js.tokens['shs-json'],
         arguments: {
           vid: settings.vid,
           parent: parent_value,
@@ -222,6 +225,9 @@
       cache: true,
       data: {
         callback: 'shs_json_term_add',
+        js_module: 'shs',
+        js_callback: 'json',
+        js_token: Drupal.settings.js && Drupal.settings.js.tokens && Drupal.settings.js.tokens['shs-json'],        
         arguments: {
           vid: term.vid,
           parent: term.parent,
diff --git a/shs.module b/shs.module
index 486b717..e0b3446 100644
--- a/shs.module
+++ b/shs.module
@@ -15,7 +15,7 @@ function shs_menu() {
   $items['js/shs'] = array(
     'title' => 'JSON callback',
     'description' => 'JSON callbacks for Simple hierarchical select',
-    'page callback' => 'shs_json',
+    'page callback' => 'shs_js_callback_json',
     'access callback' => 'user_access',
     'access arguments' => array('access content'),
     'type' => MENU_CALLBACK,
@@ -26,19 +26,33 @@ function shs_menu() {
 
 /**
  * Implements hook_js().
+ *
+ * Provides the callback information for the 1.x version of the JS module.
+ *
+ * @deprecated
+ *   Support will be removed in future versions.
  */
 function shs_js() {
-  $settings = array(
+  $info = shs_js_info();
+  $info['json']['callback'] = 'shs_js_callback_json';
+  $info['json']['access callback'] = 'user_access';
+  return $info;
+}
+
+/**
+ * Implements hook_js_info().
+ */
+function shs_js_info() {
+  return array(
     'json' => array(
-      'callback' => 'shs_json',
-      'access callback' => 'user_access',
       'access arguments' => array('access content'),
       'includes' => array('path'),
       'dependencies' => array('taxonomy', 'field', 'field_sql_storage'),
+      // Select option values are added using "new Option" and hence do not
+      // require HTML escaping.
+      'xss' => FALSE,
     ),
   );
-  drupal_alter('shs_js_info', $settings);
-  return $settings;
 }
 
 /**
@@ -68,30 +82,43 @@ function shs_requirements($phase) {
 }
 
 /**
- * Menu callback to get data in JSON format.
+ * Implements MODULE_js_callback_CALLBACK().
  */
-function shs_json() {
-  $result = array(
+function shs_js_callback_json($callback = NULL, $arguments = array()) {
+  // JS module utilizes a global while in it's bootstrap process.
+  // Use this to detect if this request is invoked using the JS module
+  // bootstrap process.
+  global $_js;
+
+  $json = array(
     'success' => FALSE,
     'data' => array(),
   );
-  if (isset($_POST['callback'])) {
-    // Get name of function we need to call to get the data.
-    $_callback = check_plain($_POST['callback']);
-    // Is this a valid callback?
-    $valid_callbacks = shs_json_callbacks();
-    if (isset($valid_callbacks[$_callback]) && !empty($valid_callbacks[$_callback]['callback']) && function_exists($valid_callbacks[$_callback]['callback'])) {
-      // Get arguments and validate them.
-      $post_args = (isset($_POST['arguments']) && is_array($_POST['arguments'])) ? $_POST['arguments'] : array();
-      $arguments = _shs_json_callback_get_arguments($valid_callbacks[$_callback], $post_args);
-      if (($callback_result = call_user_func_array($valid_callbacks[$_callback]['callback'], $arguments)) !== FALSE) {
-        $result['success'] = TRUE;
-        $result['data'] = $callback_result;
-      }
+
+  // Override the callback and arguments if no or 1.x JS module support.
+  if (!isset($_js) && isset($_POST['callback']) && isset($_POST['arguments'])) {
+    $callback = check_plain($_POST['callback']);
+    $arguments = $_POST['arguments'];
+  }
+
+  // Check if SHS callback is valid.
+  $valid_callbacks = shs_json_callbacks();
+  if ($callback && isset($valid_callbacks[$callback]) && !empty($valid_callbacks[$callback]['callback']) && function_exists($valid_callbacks[$callback]['callback'])) {
+    // Invoke the SHS callback with any arguments provided.
+    if (($callback_result = call_user_func_array($valid_callbacks[$callback]['callback'], _shs_json_callback_get_arguments($valid_callbacks[$callback], $arguments))) !== FALSE) {
+      $json['success'] = TRUE;
+      $json['data'] = $callback_result;
     }
   }
-  // Return result as JSON string.
-  drupal_json_output($result);
+
+  // Return the result if a JS 2.x callback request.
+  if ($_js) {
+    return $json;
+  }
+  else {
+    // Otherwise just prit out the JSON (no or 1.x JS module support).
+    drupal_json_output($json);
+  }
 }
 
 /**
@@ -479,6 +506,8 @@ function shs_field_widget_form(&$form, &$form_state, $field, $instance, $langcod
     '#after_build' => array('shs_field_widget_afterbuild'),
     '#shs_settings' => $instance['widget']['settings']['shs'],
     '#shs_vocabularies' => $vocabularies,
+    // Generates the necessary XSS token to validate JS 2.x requests.
+    '#js_callback' => array('shs' => 'json'),
   );
 
   $return = array($field_column => $element);
