diff --git a/core/includes/ajax.inc b/core/includes/ajax.inc index 45bb706e17e02837655aa2635a9e6baf91a43a4a..1edd871269c8b6ae8c46062cd898c026814cc90e 100644 --- a/core/includes/ajax.inc +++ b/core/includes/ajax.inc @@ -631,7 +631,7 @@ function ajax_pre_render_element($element) { // If the element is a (non-image) button, its name may not identify it // uniquely, in which case a match on value is also needed. // @see _form_button_was_clicked() - if (isset($element['#button_type']) && empty($element['#has_garbage_value'])) { + if (!empty($element['#is_button']) && empty($element['#has_garbage_value'])) { $settings['submit']['_triggering_element_value'] = $element['#value']; } } diff --git a/core/includes/form.inc b/core/includes/form.inc index 226d4a69d98f2599973b948e89f4fb7009708793..5634be8f92130e88b4e82c4b094b6f4788cf3796 100644 --- a/core/includes/form.inc +++ b/core/includes/form.inc @@ -1169,7 +1169,7 @@ function drupal_validate_form($form_id, &$form, &$form_state) { // allow the value of the clicked button to be retained in its normal // $form_state['values'] locations, even if these locations are not included // in #limit_validation_errors. - if (isset($form_state['triggering_element']['#button_type'])) { + if (!empty($form_state['triggering_element']['#is_button'])) { $button_value = $form_state['triggering_element']['#value']; // Like all input controls, the button value may be in the location @@ -1947,7 +1947,7 @@ function form_builder($form_id, &$element, &$form_state) { } // Special processing if the triggering element is a button. - if (isset($form_state['triggering_element']['#button_type'])) { + if (!empty($form_state['triggering_element']['#is_button'])) { // Because there are several ways in which the triggering element could // have been determined (including from input variables set by JavaScript // or fallback behavior implemented for IE), and because buttons often @@ -2083,7 +2083,7 @@ function _form_builder_handle_input_element($form_id, &$element, &$form_state) { // If the form was submitted by the browser rather than via Ajax, then it // can only have been triggered by a button, and we need to determine which // button within the constraints of how browsers provide this information. - if (isset($element['#button_type'])) { + if (!empty($element['#is_button'])) { // All buttons in the form need to be tracked for // form_state_values_clean() and for the form_builder() code that handles // a form submission containing no button information in $_POST. @@ -3929,6 +3929,9 @@ function theme_submit($variables) { * - element: An associative array containing the properties of the element. * Properties used: #attributes, #button_type, #name, #value. * + * The #button_type property accepts any value, though core themes have css that + * styles the following button_types appropriately: 'primary', 'danger'. + * * @ingroup themeable */ function theme_button($variables) { @@ -3936,7 +3939,13 @@ function theme_button($variables) { $element['#attributes']['type'] = 'submit'; element_set_attributes($element, array('id', 'name', 'value')); - $element['#attributes']['class'][] = 'form-' . $element['#button_type']; + $element['#attributes']['class'][] = 'form-button'; + if (!empty($element['#button_type'])) { + $element['#attributes']['class'][] = 'form-button-' . $element['#button_type']; + } + // @todo Various JavaScript depends on this button class. + $element['#attributes']['class'][] = 'form-submit'; + if (!empty($element['#attributes']['disabled'])) { $element['#attributes']['class'][] = 'form-button-disabled'; } @@ -3952,6 +3961,9 @@ function theme_button($variables) { * - element: An associative array containing the properties of the element. * Properties used: #attributes, #button_type, #name, #value, #title, #src. * + * The #button_type property accepts any value, though core themes have css that + * styles the following button_types appropriately: 'primary', 'danger'. + * * @ingroup themeable */ function theme_image_button($variables) { @@ -3965,9 +3977,15 @@ function theme_image_button($variables) { $element['#attributes']['title'] = $element['#title']; } - $element['#attributes']['class'][] = 'form-' . $element['#button_type']; + $element['#attributes']['class'][] = 'image-button'; + if (!empty($element['#button_type'])) { + $element['#attributes']['class'][] = 'image-button-' . $element['#button_type']; + } + // @todo Various JavaScript depends on this button class. + $element['#attributes']['class'][] = 'form-submit'; + if (!empty($element['#attributes']['disabled'])) { - $element['#attributes']['class'][] = 'form-button-disabled'; + $element['#attributes']['class'][] = 'image-button-disabled'; } return ''; diff --git a/core/lib/Drupal/Core/Entity/EntityFormController.php b/core/lib/Drupal/Core/Entity/EntityFormController.php index 2e9daacdec011e3141ee2a25a5f6a1b652470a42..f4fc45923e0c7399c01c572506c135bfb12c8427 100644 --- a/core/lib/Drupal/Core/Entity/EntityFormController.php +++ b/core/lib/Drupal/Core/Entity/EntityFormController.php @@ -99,6 +99,12 @@ protected function actionsElement(array $form, array &$form_state) { $delete = $element['delete']; unset($element['delete']); $element['delete'] = $delete; + $element['delete']['#button_type'] = 'danger'; + } + + if (isset($element['submit'])) { + // Give the primary submit button a #button_type of primary. + $element['submit']['#button_type'] = 'primary'; } $count = 0; diff --git a/core/modules/comment/lib/Drupal/comment/CommentFormController.php b/core/modules/comment/lib/Drupal/comment/CommentFormController.php index f1f910e0207342ff2f596dc92259e0cb31c06116..10c6b479bef3cbce2fa5e5642e227d9a0fb61267 100644 --- a/core/modules/comment/lib/Drupal/comment/CommentFormController.php +++ b/core/modules/comment/lib/Drupal/comment/CommentFormController.php @@ -204,6 +204,9 @@ protected function actions(array $form, array &$form_state) { // No delete action on the comment form. unset($element['delete']); + // Mark the submit action as the primary action, when it appears. + $element['submit']['#button_type'] = 'primary'; + // Only show the save button if comment previews are optional or if we are // already previewing the submission. $element['submit']['#access'] = ($comment->cid && user_access('administer comments')) || $preview_mode != DRUPAL_REQUIRED || isset($form_state['comment_preview']); diff --git a/core/modules/system/lib/Drupal/system/Tests/Form/ElementTest.php b/core/modules/system/lib/Drupal/system/Tests/Form/ElementTest.php index 621578c904560f83b49ae6fb553f614b9994c7a7..b8ebfbc7993e06ffce491d3281eec164f809e9da 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Form/ElementTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Form/ElementTest.php @@ -92,4 +92,18 @@ function testOptions() { ))); } } + + /** + * Tests button classes. + */ + function testButtonClasses() { + $this->drupalGet('form-test/button-class'); + // Just contains(@class, "form-button") won't do because then + // form-button-foo would contain form-button. Instead, check + // ' form-button '. Make sure it matches in the beginning and the end too + // by adding a space before and after. + $this->assertEqual(1, count($this->xpath('//*[contains(concat(" ", @class, " "), " form-button ")]'))); + $this->assertEqual(1, count($this->xpath('//*[contains(concat(" ", @class, " "), " form-button-foo ")]'))); + } + } diff --git a/core/modules/system/system.module b/core/modules/system/system.module index 640136108c1246a69969cb290de156f4e3da76b7..745dc7bba6bcc29f9839b3dd42edad7bde5c4b25 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -300,7 +300,7 @@ function system_element_info() { $types['submit'] = array( '#input' => TRUE, '#name' => 'op', - '#button_type' => 'submit', + '#is_button' => TRUE, '#executes_submit_callback' => TRUE, '#limit_validation_errors' => FALSE, '#process' => array('form_process_button', 'ajax_process_form'), @@ -309,7 +309,7 @@ function system_element_info() { $types['button'] = array( '#input' => TRUE, '#name' => 'op', - '#button_type' => 'submit', + '#is_button' => TRUE, '#executes_submit_callback' => FALSE, '#limit_validation_errors' => FALSE, '#process' => array('form_process_button', 'ajax_process_form'), @@ -317,7 +317,7 @@ function system_element_info() { ); $types['image_button'] = array( '#input' => TRUE, - '#button_type' => 'submit', + '#is_button' => TRUE, '#executes_submit_callback' => TRUE, '#limit_validation_errors' => FALSE, '#process' => array('form_process_button', 'ajax_process_form'), diff --git a/core/modules/system/tests/modules/form_test/form_test.module b/core/modules/system/tests/modules/form_test/form_test.module index 03b7cb82f97721c17284ead4198dbdc0a6e9aa91..b8a38675bd1bd1cee9939566d5022f3771f40ab9 100644 --- a/core/modules/system/tests/modules/form_test/form_test.module +++ b/core/modules/system/tests/modules/form_test/form_test.module @@ -307,6 +307,12 @@ function form_test_menu() { 'page arguments' => array('form_test_required_attribute'), 'access callback' => TRUE, ); + $items['form-test/button-class'] = array( + 'title' => 'Button class testing', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('form_test_button_class'), + 'access callback' => TRUE, + ); return $items; } @@ -2310,3 +2316,16 @@ function form_test_html_id($form, &$form_state) { ); return $form; } + +/** + * Builds a simple form to test form button classes. + */ +function form_test_button_class($form, &$form_state) { + $form['button'] = array( + '#value' => 'test', + '#type' => 'button', + '#button_type' => 'foo', + ); + + return $form; +} diff --git a/core/modules/user/lib/Drupal/user/ProfileFormController.php b/core/modules/user/lib/Drupal/user/ProfileFormController.php index d2a7e8107a17fe881925c97bb76d111d0877a153..5584e6344222fdeba8f2f5349d6b525ac62b055f 100644 --- a/core/modules/user/lib/Drupal/user/ProfileFormController.php +++ b/core/modules/user/lib/Drupal/user/ProfileFormController.php @@ -21,16 +21,10 @@ protected function actions(array $form, array &$form_state) { $element = parent::actions($form, $form_state); $account = $this->getEntity($form_state); - // @todo Actually the cancel action can be assimilated to the delete one: we - // should alter it instead of providing a new one. - unset($element['delete']); - - $element['cancel'] = array( - '#type' => 'submit', - '#value' => t('Cancel account'), - '#submit' => array('user_edit_cancel_submit'), - '#access' => $account->uid > 1 && (($account->uid == $GLOBALS['user']->uid && user_access('cancel account')) || user_access('administer users')), - ); + $element['delete']['#type'] = 'submit'; + $element['delete']['#value'] = t('Cancel account'); + $element['delete']['#submit'] = array('user_edit_cancel_submit'); + $element['delete']['#access'] = $account->uid > 1 && (($account->uid == $GLOBALS['user']->uid && user_access('cancel account')) || user_access('administer users')); return $element; } diff --git a/core/modules/views/views_ui/admin.inc b/core/modules/views/views_ui/admin.inc index 5b0ae41b4102104b6fe8e353dc1b1b702a343e87..a37297fec039f38d4b8608d7d26fca7539efab4e 100644 --- a/core/modules/views/views_ui/admin.inc +++ b/core/modules/views/views_ui/admin.inc @@ -2303,7 +2303,7 @@ function views_fetch_fields($base, $type, $grouping = FALSE, $sub_type = NULL) { */ function views_ui_form_button_was_clicked($element, &$form_state) { $process_input = empty($element['#disabled']) && ($form_state['programmed'] || ($form_state['process_input'] && (!isset($element['#access']) || $element['#access']))); - if ($process_input && !isset($form_state['triggering_element']) && isset($element['#button_type']) && isset($form_state['input'][$element['#name']]) && isset($element['#values']) && in_array($form_state['input'][$element['#name']], $element['#values'], TRUE)) { + if ($process_input && !isset($form_state['triggering_element']) && !empty($element['#is_button']) && isset($form_state['input'][$element['#name']]) && isset($element['#values']) && in_array($form_state['input'][$element['#name']], $element['#values'], TRUE)) { $form_state['triggering_element'] = $element; } return $element; diff --git a/core/themes/bartik/css/style-rtl.css b/core/themes/bartik/css/style-rtl.css index d95d66bc33cc61d516176cc7a795ce9c93d4d2af..711a742da8ca0f0ebfd7c0ec43f896ec4fe468f1 100644 --- a/core/themes/bartik/css/style-rtl.css +++ b/core/themes/bartik/css/style-rtl.css @@ -146,7 +146,7 @@ ul.tips { /* ----------------- Buttons ------------------ */ -input.form-submit, +.form-button, a.button { margin-right: 0; margin-left: 0.6em; diff --git a/core/themes/bartik/css/style.css b/core/themes/bartik/css/style.css index 94ac77510719c7d52a5b5c74bcf22d953910e815..6ebcbd728f1d32ac82f69c96cbda9fc74ab8d913 100644 --- a/core/themes/bartik/css/style.css +++ b/core/themes/bartik/css/style.css @@ -128,6 +128,7 @@ table, input, textarea, select, +.form-button, a.button { font-family: "Lucida Grande", "Lucida Sans Unicode", Verdana, sans-serif; } @@ -1096,7 +1097,7 @@ div.password-confirm { /* ---------------- Buttons ---------------- */ -input.form-submit, +.form-button, a.button { background: #fff url(../images/buttons.png) 0 0 repeat-x; border: 1px solid #e4e4e4; @@ -1113,13 +1114,15 @@ a.button { padding: 4px 17px; border-radius: 15px; } -a.button:link, -a.button:visited, -a.button:hover, +.form-button:focus, +.form-button:hover, +.form-button:active, a.button:focus, +a.button:hover, a.button:active { text-decoration: none; color: #5a5a5a; + background: #dedede; } /* -------------- Form Elements ------------- */ @@ -1254,6 +1257,7 @@ input.form-submit:focus { .form-actions { padding-top: 10px; } + /* Contact Form */ .contact-form #edit-name { width: 75%; @@ -1274,17 +1278,25 @@ input.form-submit:focus { } /* Disabled form elements */ -input.form-button-disabled, -input.form-button-disabled:hover, -input.form-button-disabled:focus, -input.form-button-disabled:active, .form-disabled input, .form-disabled select, -.form-disabled textarea { +.form-disabled textarea, +.form-button-disabled, +.form-button-disabled:hover, +.form-button-disabled:focus, +.form-button-disabled:active { background: #ededed; border-color: #bbb; color: #717171; } +.image-button-disabled, +.image-button-disabled:hover, +.image-button-disabled:focus, +.image-button-disabled:active { + -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"; + filter: alpha(opacity=50); + opacity: .5; +} .form-disabled label { color: #717171; } diff --git a/core/themes/seven/images/buttons.png b/core/themes/seven/images/buttons.png deleted file mode 100644 index 0a89f98ea1f3e680690912f099dcaa79c28e6d2d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 503 zcmeAS@N?(olHy`uVBq!ia0y~yV4MJCS8y-^$>6=l2Y>?mJY5_^D&pQ=xmn7~z~FlE zwo=m;sm&5j;)d*kF3kVpS>LbO`u(})gE#UHNBEczY`mrG(2~d~`I}oHF~Z^4KL(dK z1`IN*|FU%$=qMzcGYGb^ro0gcE7=VZvu9M|;XZMLzk%a0lhHR>g+m(}dSV$}B*Z3c z%!eq~hM33%Hqnk5EaeZ8Qiez|fTi>pmC7U-`mWxCC@BXk0h$AHh#mvjmS~7AY+zgV zLL9IjB4r6S3g|qL&C?;qvqJq;4AI5|)@I8J^2^~34Ll$Rvp~ckM)gCCk^~!NjjRsn zMI=oEAWb0cAfGdX4M$Oc!YPwSR?Ug*%xYvWzGDJ~4A8S}!0_MA3=WcdDRZ7#lV?ti Q0!AomdKI;Vst0B{VasQ>@~ diff --git a/core/themes/seven/style-rtl.css b/core/themes/seven/style-rtl.css index 3276ce8d15d0fba9aac901923f022027585a729f..4974785ae60fe1ca4b5d1de9dd84fd898dfa1c9a 100644 --- a/core/themes/seven/style-rtl.css +++ b/core/themes/seven/style-rtl.css @@ -127,8 +127,9 @@ body div.form-type-checkbox div.description { margin-left: 0; margin-right: 1.5em; } -input.form-submit, -a.button { +a.button, +.form-button, +.image-button { margin-left: 1em; margin-right: 0; } diff --git a/core/themes/seven/style.css b/core/themes/seven/style.css index 9c43ac9e4434c773cfbca6714418e1598a6f565c..4cf229dfcf8e17caa1fb43ff2f035d3cc7f7fba0 100644 --- a/core/themes/seven/style.css +++ b/core/themes/seven/style.css @@ -615,12 +615,16 @@ body div.form-type-radio div.description, body div.form-type-checkbox div.description { margin-left: 1.5em; /* LTR */ } -input.form-submit, -a.button { - cursor: pointer; - padding: 4px 17px; +a.button, +.form-button, +.image-button { margin-bottom: 1em; margin-right: 1em; /* LTR */ +} +a.button, +.form-button { + cursor: pointer; + padding: 4px 17px; color: #5a5a5a; text-align: center; font-weight: normal; @@ -630,29 +634,29 @@ a.button { border-bottom: 1px solid #b4b4b4; border-left-color: #d2d2d2; border-right-color: #d2d2d2; - background: url(images/buttons.png) 0 0 repeat-x; + background-color: #e4e4e4; border-radius: 20px; } -a.button:link, -a.button:visited, a.button:hover, -a.button:active { +a.button:active, +.form-button:hover, +.form-button:active { text-decoration: none; } -input.form-submit:hover, -input.form-submit:focus, +a.button:focus, a.button:hover, -a.button:focus { - background-position: 0 -40px; +.form-button:focus, +.form-button:hover { + background-color: #c0c0c0; border: 1px solid #bebebe; border-left-color: #afafaf; border-right-color: #afafaf; border-bottom-color: #9b9b9b; color: #2e2e2e; } -input.form-submit:active, -a.button:active { - background-position: 0 -80px; +a.button:active, +.form-button:active { + background-color: #565656; border: 1px solid #333; border-left-color: #222; border-right-color: #222; @@ -660,9 +664,26 @@ a.button:active { color: #fff; text-shadow: #222 0 -1px 0; } -input.form-button-disabled, -input.form-button-disabled:active { - background: #eee none; +.form-button-primary { + background-color: #9dcae7; + border: 1px solid #8eB7cd; + border-bottom-color: #7691a2; + color: #133B54; +} +.form-button-primary:focus, +.form-button-primary:hover { + background-color: #73b3dd; + border: 1px solid #6ea3bf; + border-bottom-color: #4680a0; +} +.form-button-primary:active { + background-color: #3981b1; + border: 1px solid #36647c; + border-bottom-color: #284657; +} +.form-button-disabled, +.form-button-disabled:active { + background-color: #eee; border-color: #eee; text-shadow: none; color: #999;