Index: google_cse.theme.inc
===================================================================
--- google_cse.theme.inc	(.../vendor/drupal-contrib/modules/google_cse/current)	(revision 1372)
+++ google_cse.theme.inc	(.../appistry.com/trunk/sites/all/modules/google_cse)	(revision 1372)
@@ -1,5 +1,5 @@
 <?php
-// $Id: google_cse.theme.inc,v 1.1.2.7 2008/07/01 19:09:09 mfb Exp $
+// $Id$
 
 /**
  * @file
@@ -7,7 +7,8 @@
  */
 
 /**
- * The search results page can be themed/customized.
+ * The search results page can be themed/customized. This is the
+  * function for theming the JavaScript/Frame version of results page.
  */
 function template_preprocess_google_cse_results(&$variables) {
   $query = array(
@@ -15,7 +16,7 @@
     'cx' => variable_get('google_cse_cx', ''),
     'cof' => variable_get('google_cse_cof_google', 'FORID:0'),
     'sitesearch' => google_cse_sitesearch_default(),
-  ) + google_cse_advanced_settings();
+    ) + google_cse_advanced_settings();
 
   $variables['results_searchbox_form'] = $variables['form'] ? drupal_get_form('google_cse_results_searchbox_form', $variables['self']) : '';
   $variables['noscript'] = t('!google, or enable JavaScript to view them here.', array('!google' => l(t('View the results at Google'), 'http://'. variable_get('google_cse_domain', 'www.google.com') .'/cse', array('query' => $query))));
@@ -26,12 +27,109 @@
     'googleCSE' => array(
       'resultsWidth' => intval(variable_get('google_cse_results_width', 600)),
       'domain' => variable_get('google_cse_domain', 'www.google.com'),
-    ),
-  );
+      ),
+    );
   drupal_add_js($settings, 'setting');
 }
 
 /**
+ * The search results page can be themed/customized. This is the
+ * function for theming the Business search results page. 
+ *
+ * The input is a "results" array.
+ *
+ * Component 'items' is an array of search results, 
+ * where each item is an array with the
+ * following components (not all are displayed in this default function):
+ *   'url' - URL of search result
+ *   'title' - Title of search result
+ *   'crawldate' - Date page was last indexed by Google
+ *   'excerpt' - Excerpt of page with search terms highlighted
+ *   'lang' - Google's guess as to the language of the search result
+ *   'crowd_host' - Indicates that lots more results were found on this
+ *      host, and you could do another query on this host to find more
+ *      results (value is a URL-encoded host name to be used in a query)
+ *
+ * Components 'from', 'to', and 'total' 
+ * indicate "Viewing results [from] to [to] of approximately [total]'.
+ *
+ *
+ */
+function template_preprocess_google_cse_xml_results(&$variables) {
+  $results = $variables['form'];
+
+  $variables['prefix'] = filter_xss_admin(variable_get('google_cse_results_prefix', ''));
+  $variables['suffix'] = filter_xss_admin(variable_get('google_cse_results_suffix', ''));
+  $variables['results_searchbox_form'] = $variables['form'] ? drupal_get_form('google_cse_results_searchbox_form', $variables['self']) : '';
+
+  $variables['header'] = check_plain(variable_get('google_cse_results_title', t('Search Results')));
+
+  $variables['has_results'] = !(empty($results) || empty($results['items']));
+  $variables['no_results'] = t('Your search returned no results. Please try a different search.');
+
+  $variables['pager_status'] = t('Viewing results !from to !to of approximately !total',
+           array(
+             '!from' => intval($results['from']),
+             '!to' => intval($results['to']),
+             '!total' => intval($results['total'])
+             )
+           );
+
+  $perpage = variable_get('google_cse_results_num', 10);
+  $query = array('query' => $_GET['query']);
+
+  if ($results['from'] > 1) {
+    $newstart = intval($results['from']) - $perpage - 1;
+    if ($newstart < 0) {
+      $newstart = 0;
+    }
+    $query['start'] = $newstart;
+
+    $variables['pager_prev'] = l(t('Previous page'), 
+                                 variable_get('google_cse_results_path', 'search/google'),
+                                 array('query' => drupal_query_string_encode($query)));
+  }
+
+  if ($results['to'] < $results['total']) {
+    $query['start'] = intval($results['to']);
+
+    $variables['pager_next'] = l(t('Next page'),
+                                 variable_get('google_cse_results_path', 'search/google'),
+                                 array('query' => drupal_query_string_encode($query)));
+  }
+
+  $variables['original_query'] = preg_replace('/ more:[^&]*/', '', $_GET['query']);
+  $variables['has_refinements'] = count($results['labels']) == TRUE;
+  
+  if ($variables['has_refinements']) {
+    $variables['refinements_label'] = t('Refine results for');
+    $variables['refinements'] = array();
+    
+    preg_match('/ more:([^&]*)/', $_GET['query'], $selected_label);
+    $selected_label = $selected_label[1];
+
+    foreach ($results['labels'] as $label => $title) {
+      $selected = ($label == $selected_label) ? ' selected' : '';
+      $classes = "google-cse-refinements-label" . $selected;
+      $attributes = drupal_attributes(array('class' => $classes));
+      $new_query['query'] = $variables['original_query'] . " more:$label";
+      $link =  l(t($title),
+               variable_get('google_cse_results_path', 'search/google'),
+               array('query' => drupal_query_string_encode($new_query)));
+      $variables['refinements'][] = array('link' => $link, 'attributes' => $attributes);
+    }
+  }
+  
+  $variables['results'] = array();
+  foreach ($results['items'] as $item) {
+    $link = l($item['title'], $item['url'], array('html' => TRUE));
+    $filtered_excerpt = filter_xss_admin(preg_replace('/<br>/', '', $item['excerpt']));
+    $url = l($item['url'], $item['url']);
+    $variables['results'][] = array('title' => $link, 'excerpt' => $filtered_excerpt, 'url' => $url);
+  }
+}
+
+/**
  * Display an Add-to-Google button.
  */
 function template_preprocess_google_cse_results_gadget(&$variables) {
Index: google_cse.admin.inc
===================================================================
--- google_cse.admin.inc	(.../vendor/drupal-contrib/modules/google_cse/current)	(revision 1372)
+++ google_cse.admin.inc	(.../appistry.com/trunk/sites/all/modules/google_cse)	(revision 1372)
@@ -23,9 +23,10 @@
     '#default_value' => variable_get('google_cse_results_display', 'here'),
     '#options' => array(
       'here' => t('On this site (requires JavaScript)'),
+      'xml' => t('On this site (without JavaScript or frames, requires current Google Business account)'),      
       'google' => t('On Google'),
     ),
-    '#description' => t('Search results can be displayed on this site, using JavaScript, or on Google, which does not require JavaScript.'),
+    '#description' => t('Search results can be displayed on this site, using JavaScript, or on Google, which does not require JavaScript. If you have a Business account on Google Custom Search, you can also display results on this site without using JavaScript.'),
   );
   $form['google_cse_results_title'] = array(
     '#title' => t('Search results page title'),
Index: google_cse.module
===================================================================
--- google_cse.module	(.../vendor/drupal-contrib/modules/google_cse/current)	(revision 1372)
+++ google_cse.module	(.../appistry.com/trunk/sites/all/modules/google_cse)	(revision 1372)
@@ -1,5 +1,5 @@
 <?php
-// $Id: google_cse.module,v 1.1.4.12 2008/07/17 19:22:57 mfb Exp $
+// $Id$
 
 /**
  * @file
@@ -11,7 +11,8 @@
  */
 function google_cse_menu() {
   if (!module_exists('google') && variable_get('google_cse_results_display', 'here') != 'google') {
-    $items['search/google'] = array(
+    $path = variable_get('google_cse_results_path', 'search/google');
+    $items[$path] = array(
       'access arguments' => array('search Google CSE'),
       'title callback' => 'google_cse_results_tab',
       'description' => 'Google Custom Search Engine',
@@ -40,13 +41,18 @@
       'arguments' => array('form' => TRUE, 'self' => FALSE),
       'file' => 'google_cse.theme.inc',
       'template' => 'google_cse_results',
-    ),
+      ),
+    'google_cse_xml_results' => array(
+      'arguments' => array('form' => TRUE, 'self' => FALSE),
+      'file' => 'google_cse.theme.inc',
+      'template' => 'google_cse_xml_results',
+      ),
     'google_cse_results_gadget' => array(
       'arguments' => array(),
       'file' => 'google_cse.theme.inc',
       'template' => 'google_cse_results_gadget',
-    ),
-  );
+      ),
+    );
 }
 
 /**
@@ -57,7 +63,7 @@
     return array(
       0 => array('info' => t('Google CSE'), 'cache' => BLOCK_NO_CACHE),
       1 => array('info' => t('Google CSE results'), 'cache' => BLOCK_NO_CACHE),
-    );
+      );
   }
   elseif ($op == 'view' && user_access('search Google CSE')) {
     switch ($delta) {
@@ -74,11 +80,11 @@
  */
 function google_cse_forms() { 
   $forms = array();
-  $forms['google_cse_searchbox_form'] = array( 
+  $forms['google_cse_searchbox_form'] = array(
     'callback' => 'google_cse_searchbox_form_builder', 
     'callback arguments' => array('google_cse_searchbox_form'),
   ); 
-  $forms['google_cse_results_searchbox_form'] = array( 
+  $forms['google_cse_results_searchbox_form'] = array(
     'callback' => 'google_cse_searchbox_form_builder', 
     'callback arguments' => array('google_cse_results_searchbox_form'),
   ); 
@@ -91,37 +97,48 @@
 function google_cse_searchbox_form_builder(&$form_state, $form_id, $self = FALSE) {
   $form = array();
   // The default form.
-  if (variable_get('google_cse_results_display', 'here') == 'here') {
-    $form['#action'] = url($self ? $_GET['q'] : 'search/google');
+  if (variable_get('google_cse_results_display', 'here') != 'google') {
+    $form['#action'] = url($self ? $_GET['q'] : variable_get('google_cse_results_path', 'search/google'));
     $cof = variable_get('google_cse_cof_here', 'FORID:11');
   }
   else {
     $form['#action'] = 'http://'. variable_get('google_cse_domain', 'www.google.com') .'/cse';
     $cof = variable_get('google_cse_cof_google', 'FORID:0');
   }
+
   $form['#method'] = 'get';
-  $form['cx'] = array(
-    '#type' => 'hidden',
-    '#value' => variable_get('google_cse_cx', ''),
-  );
-  $form['cof'] = array(
-    '#type' => 'hidden',
-    '#value' => $cof,
-  );
+
   $form['query'] = array(
     '#type' => 'textfield',
-    '#default_value' => isset($_GET['query']) ? $_GET['query'] : '',
+    '#default_value' => isset($_GET['query']) ? preg_replace('/ more:[^&]*/', '', $_GET['query']) : '',
   );
   $form['sa'] = array(
     '#type' => 'submit',
     '#value' => t('Search'),
   );
-  foreach (google_cse_advanced_settings() as $parameter => $setting) {
-    $form[$parameter] = array(
+
+  // items needed for non-XML-display versions of search form,
+  // whether it is in the block or on the results page
+
+  if (variable_get('google_cse_results_display', 'here') != 'xml') {
+    $form['cx'] = array(
       '#type' => 'hidden',
-      '#value' => $setting,
+      '#value' => variable_get('google_cse_cx', ''),
     );
+
+    $form['cof'] = array(
+      '#type' => 'hidden',
+      '#value' => $cof,
+    );
+
+    foreach (google_cse_advanced_settings() as $parameter => $setting) {
+      $form[$parameter] = array(
+        '#type' => 'hidden',
+        '#value' => $setting,
+     );
+    }
   }
+
   // And the small differences between both.
   switch ($form_id) {
     case 'google_cse_searchbox_form':
@@ -130,12 +147,13 @@
       break;
     case 'google_cse_results_searchbox_form':
       $form['query']['#size'] = intval(variable_get('google_cse_results_searchbox_width', 40));
-      $form['query']['#title'] = t('Enter your keywords');
+      $form['query']['#title'] = variable_get('google_cse_searchbox_header', t('Enter your keywords'));
       if (variable_get('google_cse_results_gadget', 1)) {
         $form['sa']['#suffix'] = theme('google_cse_results_gadget');
       }
-      break;
   }
+
+  // TODO: May need to remove
   google_cse_sitesearch_form($form);
   return $form;
 }
@@ -145,7 +163,12 @@
  */
 function google_cse_results() {
   google_cse_results_set_title();
-  return theme('google_cse_results');
+  if (variable_get('google_cse_results_display', 'here') == 'here') {
+    print theme('page', theme('google_cse_results'));
+  } else {
+    $results = _google_cse_get_search_results();
+    print theme('page', theme('google_cse_xml_results', $results));
+  }
 }
 
 /**
@@ -220,7 +243,7 @@
       '#type' => $type,
       '#options' => array(
         '' => ($var = variable_get('google_cse_sitesearch_option', '')) ? (($type == 'radios') ? check_plain($var) : $var) : t('Search the web'),
-      ) + $options,
+     ) + $options,
       '#default_value' => google_cse_sitesearch_default(),
     );
     if ($type == 'select' && isset($form['sa'])) { 
@@ -235,3 +258,214 @@
 function google_cse_sitesearch_default() {
   return isset($_GET['sitesearch']) ? $_GET['sitesearch'] : (variable_get('google_cse_sitesearch_default', 0) ? array_shift(preg_split('/[\s]+/', variable_get('google_cse_sitesearch', ''))) : '');
 }
+
+/* Queries Google to get XML results, and parses them into an array
+ * of search items -- see theme_google_cse_result_items() function below
+ * for documentation of this array.
+ */
+function _google_cse_get_search_results() {
+
+  // formulate the query for Google
+
+  $url = 'http://www.google.com/search';
+
+  $query = array(
+    'q' => $_GET['refinement'] == '' ? $_GET['query'] : $_GET['query'] . ' more:' . $_GET['refinement'],
+    'start' => $_GET['start'],
+    'num' => variable_get('google_cse_results_num', 10),
+    'client' => 'google-csbe',
+    'output' => 'xml_no_dtd',
+    'cx' => variable_get('google_cse_cx', ''),
+    ) + google_cse_advanced_settings();
+
+  // get the XML results
+
+  $res = drupal_http_request($url . '?' . drupal_query_string_encode($query));
+
+  if ($res->code != '200') {
+    return array();
+  }
+
+  // parse results and return them
+  return _google_cse_parse_xml_results($res->data);
+
+}
+
+
+/*
+ * Internal function: parses the XML results returned by Google into
+ * a results array (see function theme_google_cse_result_items for doc)
+ */
+function _google_cse_parse_xml_results($data) {
+
+  global $google_cse_elem;
+  global $google_cse_item_index;
+  global $google_cse_results;
+  global $google_cse_in_facet_item;
+  
+  $google_cse_in_facet_item = FALSE;
+
+  $xml_p = drupal_xml_parser_create($data);
+  xml_set_element_handler($xml_p, '_google_cse_xml_elem_start',
+			   '_google_cse_xml_elem_end');
+  xml_set_character_data_handler($xml_p, '_google_cse_xml_character_data');
+
+  $google_cse_elem = '';
+  $google_cse_item_index = 0;
+  $google_cse_results = array('items' => array());
+
+  if (!xml_parse($xml_p, $data, 1)) {
+    return array();
+  }
+
+  return $google_cse_results;
+}
+
+/* 
+ * Internal function for handling XML elements when parsing Google results.
+ */
+function _google_cse_xml_elem_start($parser, $name, $attribs = array()) {
+  global $google_cse_elem;
+  global $google_cse_item_index;
+  global $google_cse_results;
+  global $google_cse_partial_data;
+  global $google_cse_in_facet_item;
+  global $google_cse_curr_facet_label;
+
+  // we only care about some of the XML elements in the Google results
+  // See http://www.google.com/coop/docs/cse/resultsxml.html for doc
+
+  switch ($name) {
+  case 'RES':
+    // attributes give the from/to indices of this results set
+    $google_cse_results['from'] = $attribs['SN'];
+    $google_cse_results['to'] = $attribs['EN'];
+    break;
+
+  case 'M':
+    // gives approx total number of results of search
+    $google_cse_elem = 'total';
+    break;
+
+  case 'R':
+    // starts a new search result item
+    $google_cse_item_index = count($google_cse_results['items']);
+    $google_cse_results['items'][$google_cse_item_index] = array();
+    break;
+
+  case 'FACETITEM':
+    // starts a new facet item
+    $google_cse_in_facet_item = TRUE;
+    break;
+  
+  case 'LABEL':
+    $google_cse_elem = $google_cse_in_facet_item ? 'facetlabel' : 'label';
+    break;
+    
+  case 'ANCHOR_TEXT':
+    $google_cse_elem = 'anchor_text';
+    break;  
+  
+  // The rest of these are components of search result items
+
+  case 'U':
+    $google_cse_elem = 'url';
+    break;
+
+  case 'T':
+    $google_cse_elem = 'title';
+    break;
+
+  case 'CRAWLDATE':
+    $google_cse_elem = 'crawldate';
+    break;
+
+  case 'S':
+    $google_cse_elem = 'excerpt';
+    break;
+
+  case 'LANG':
+    $google_cse_elem = 'lang';
+    break;
+
+  case 'HN':
+    $google_cse_elem = 'crowd_host';
+    break;
+
+  // anything else: make sure we are not getting data now!
+  default:
+    $google_cse_elem = '';
+    break;
+
+  }
+
+  // this flag makes sure the character data handler gets reset
+  $google_cse_partial_data = 0;
+}
+
+/* 
+ * Internal function for handling XML elements when parsing Google results
+ */
+function _google_cse_xml_elem_end($parser, $name) {
+  global $google_cse_elem;
+  global $google_cse_item_index;
+  global $google_cse_partial_data;
+  global $google_cse_in_facet_item;
+
+  // close out the element and make sure character data handler gets reset
+  $google_cse_elem = '';
+  $google_cse_partial_data = 0;
+  switch ($name) {
+    case 'FACETITEM':
+      $google_cse_in_facet_item = FALSE;
+      break;
+  }
+}
+
+
+/* 
+ * Internal function for handling XML elements when parsing Google results
+ */
+function _google_cse_xml_character_data($parser, $data) {
+  global $google_cse_elem;
+  global $google_cse_item_index;
+  global $google_cse_results;
+  global $google_cse_partial_data;
+  global $google_cse_curr_facet_label;
+
+  if ($google_cse_elem == 'total') {
+    // handle the "total" element
+    if (!$google_cse_partial_data) {
+      $google_cse_results['total'] = '';
+    }
+    $google_cse_results['total'] .= $data;
+
+  } else if ($google_cse_elem == 'facetlabel') {
+    if (!$google_cse_partial_data) {
+      $google_cse_curr_facet_label = '';
+    }
+    $google_cse_curr_facet_label .= html_entity_decode($data);
+    
+  } else if ($google_cse_elem == 'anchor_text') {
+    if (!$google_cse_partial_data) {
+      $google_cse_results['labels'][$google_cse_curr_facet_label] = '';
+    }
+    $google_cse_results['labels'][$google_cse_curr_facet_label] .= html_entity_decode($data);
+    
+  } else if (array_search($google_cse_elem,
+			   array('url', 'title', 'crawldate',
+				  'excerpt', 'lang', 'crowd_host')) !== FALSE) {
+
+    // handle the item sub-elements
+    if (!$google_cse_partial_data) {
+      $google_cse_results['items'][$google_cse_item_index][$google_cse_elem] = '';
+    }
+
+    $google_cse_results['items'][$google_cse_item_index][$google_cse_elem] .= html_entity_decode($data);
+
+  }
+
+  // sometimes this gets called multiple times within the same element,
+  // due to line breaks or whatever, so make sure we append data
+  $google_cse_partial_data = 1;
+}
\ No newline at end of file
Index: google_cse_xml_results.tpl.php
===================================================================
--- google_cse_xml_results.tpl.php	(.../vendor/drupal-contrib/modules/google_cse/current)	(revision 0)
+++ google_cse_xml_results.tpl.php	(.../appistry.com/trunk/sites/all/modules/google_cse)	(revision 1372)
@@ -0,0 +1,56 @@
+<?php
+// $Id$
+?>
+<div id="google-cse-results">
+  <h2 class="google-cse-results-header"><?php print $header; ?></h2>
+
+  <?php if ($prefix): ?>
+    <div class="google-cse-results-prefix"><?php print $prefix; ?></div>
+  <?php endif; ?>
+
+  <?php print $results_searchbox_form; ?>
+
+  <?php if (!$has_results): ?>
+    <p class="google-cse-no-results">
+      <?php print $no_results; ?>
+    </p>
+  <?php else: ?>
+
+  <?php if ($has_refinements): ?>
+    <div class="google-cse-refinements">
+      <p><?php print $refinements_label; ?> <span class="google-cse-original-query"><?php print $original_query; ?></span>:</p>
+      <?php foreach ($refinements as $refinement) { ?>
+        <span <?php print $refinement['attributes']; ?>><?php print $refinement['link']; ?></span>&nbsp;
+      <?php } ?>
+    </div>
+  <?php endif; ?>
+
+  <p class="google-cse-nav before"><?php print $pager_status; ?>
+    <span class="google-cse-nav-link-wrapper">
+    <?php if ($pager_prev): ?><span class="google-cse-nav-link prev"><?php print $pager_prev; ?></span> | <?php endif; ?>
+    <?php if ($pager_next): ?><span class="google-cse-nav-link next"><?php print $pager_next; ?></span><?php endif; ?>
+    </span>
+  </p>
+  
+  <?php foreach ($results as $result) { ?>
+    <div class="google-cse-result-item">
+      <p class="google-cse-item-title"><?php print $result['title']; ?></p>
+      <p class="google-cse-item-excerpt"><?php print $result['excerpt']; ?></p>
+      <p class="google-cse-item-url"><?php print $result['url']; ?></p>
+    </div>
+  <?php } ?>
+    
+  <p class="google-cse-nav after"><?php print $pager_status; ?>
+    <span class="google-cse-nav-link-wrapper">
+    <?php if ($pager_prev): ?><span class="google-cse-nav-link prev"><?php print $pager_prev; ?></span> | <?php endif; ?>
+    <?php if ($pager_next): ?><span class="google-cse-nav-link next"><?php print $pager_next; ?></span><?php endif; ?>
+    </span>
+  </p>    
+<?php endif; ?>
+
+<?php if ($suffix): ?>
+  <div class="google-cse-results-suffix"><?php print $suffix; ?></div>
+<?php endif; ?>
+
+</div>
+
Index: google_cse.css
===================================================================
--- google_cse.css	(.../vendor/drupal-contrib/modules/google_cse/current)	(revision 1372)
+++ google_cse.css	(.../appistry.com/trunk/sites/all/modules/google_cse)	(revision 1372)
@@ -4,3 +4,15 @@
 #google-cse-searchbox-form .form-radios div { display: block; }
 #google-cse-results-searchbox-form .form-radios div { display: block; }
 #google-cse-results-gadget a { margin-left: 2em; }
+#google-cse-results-gadget img { margin-left: 2em; }
+.google-cse-result-item { margin-bottom: 10px; }
+.google-cse-result-item p { margin-bottom: 0; margin-top: 0; }
+.google-cse-item-title { font-size: medium; }
+.google-cse-item-title a { color: #0000CC; }
+.google-cse-item-url { font-size: small; }
+.google-cse-item-url a { color: #008000; font-size: small; }
+.google-cse-refinements { font-size: medium; margin: 20px 0 30px 0;}
+.google-cse-refinements p { margin-bottom: 5px; }
+.google-cse-refinements-label { margin-right: 30px; }
+.google-cse-no-results { margin: 20px 0 30px 0;}
+.google-cse-nav-link-wrapper { float: right;}
\ No newline at end of file
