summaryrefslogtreecommitdiff
path: root/includes
diff options
context:
space:
mode:
authorGábor Hojtsy <gabor@hojtsy.hu>2007-10-24 13:35:26 +0000
committerGábor Hojtsy <gabor@hojtsy.hu>2007-10-24 13:35:26 +0000
commitbad3e24164093a74b88f1cce8831980b5f90b869 (patch)
tree1925516a729d485ea41af7b561d1ab81619c1d8b /includes
parenta0c920badf0cbfec5bfa3ae9af1157f03bb06de9 (diff)
downloadbrdo-bad3e24164093a74b88f1cce8831980b5f90b869.tar.gz
brdo-bad3e24164093a74b88f1cce8831980b5f90b869.tar.bz2
#111719 follow up patch by multiple contributors: ensure proper XHTML id attribute values for form elements
Diffstat (limited to 'includes')
-rw-r--r--includes/form.inc39
1 files changed, 37 insertions, 2 deletions
diff --git a/includes/form.inc b/includes/form.inc
index a6cf31996..e41340085 100644
--- a/includes/form.inc
+++ b/includes/form.inc
@@ -304,6 +304,13 @@ function drupal_process_form($form_id, &$form, &$form_state) {
if ((!empty($form['#programmed'])) || (!empty($form['#post']) && (isset($form['#post']['form_id']) && ($form['#post']['form_id'] == $form_id)))) {
drupal_validate_form($form_id, $form, $form_state);
+ // form_clean_id() maintains a cache of element IDs it has seen,
+ // so it can prevent duplicates. We want to be sure we reset that
+ // cache when a form is processed, so scenerios that result in
+ // the form being built behind the scenes and again for the
+ // browser don't increment all the element IDs needlessly.
+ form_clean_id(NULL, TRUE);
+
if ((!empty($form_state['submitted'])) && !form_get_errors() && empty($form_state['rebuild'])) {
$form_state['redirect'] = NULL;
form_execute_handlers('submit', $form, $form_state);
@@ -2002,15 +2009,43 @@ function _form_set_class(&$element, $class = array()) {
}
/**
- * Remove invalid characters from an HTML ID attribute string.
+ * Prepare an HTML ID attribute string for a form item.
+ *
+ * Remove invalid characters and guarantee uniqueness.
*
* @param $id
* The ID to clean.
+ * @param $flush
+ * If set to TRUE, the function will flush and reset the static array
+ * which is built to test the uniqueness of element IDs. This is only
+ * used if a form has completed the validation process. This parameter
+ * should never be set to TRUE if this function is being called to
+ * assign an ID to the #ID element.
* @return
* The cleaned ID.
*/
-function form_clean_id($id = NULL) {
+function form_clean_id($id = NULL, $flush = FALSE) {
+ static $seen_ids = array();
+
+ if ($flush) {
+ $seen_ids = array();
+ return;
+ }
$id = str_replace(array('][', '_', ' '), '-', $id);
+
+ // Ensure IDs are unique. The first occurrence is held but left alone.
+ // Subsequent occurrences get a number appended to them. This incrementing
+ // will almost certainly break code that relies on explicit HTML IDs in
+ // forms that appear more than once on the page, but the alternative is
+ // outputting duplicate IDs, which would break JS code and XHTML
+ // validity anyways. For now, it's an acceptable stopgap solution.
+ if (isset($seen_ids[$id])) {
+ $id = $id .'-'. $seen_ids[$id]++;
+ }
+ else {
+ $seen_ids[$id] = 1;
+ }
+
return $id;
}