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;