Commit 9db4af56 authored by webchick's avatar webchick
Browse files

Issue #2326891 by tim.plunkett, jhodgdon: Convert system_element_info() to Element classes.

parent 9c537ec4
......@@ -163,10 +163,10 @@
/**
* Form element processing handler for the #ajax form property.
*
* @deprecated Use \Drupal\Core\Render\Element\FormElement::processAjaxForm().
* @deprecated Use \Drupal\Core\Render\Element\RenderElement::processAjaxForm().
*/
function ajax_process_form($element, FormStateInterface $form_state, &$complete_form) {
return Element\FormElement::processAjaxForm($element, $form_state, $complete_form);
function ajax_process_form(&$element, FormStateInterface $form_state, &$complete_form) {
return Element\RenderElement::processAjaxForm($element, $form_state, $complete_form);
}
/**
......
......@@ -1062,8 +1062,9 @@ function drupal_add_html_head_link($attributes, $header = FALSE) {
* - 'preprocess': If TRUE and CSS aggregation/compression is enabled, the
* styles will be aggregated and compressed. Defaults to TRUE.
* - 'browsers': An array containing information specifying which browsers
* should load the CSS item. See drupal_pre_render_conditional_comments()
* for details.
* should load the CSS item. See
* \Drupal\Core\Render\Element\HtmlTag::preRenderConditionalComments() for
* details.
*
* @return
* An array of queued cascading stylesheets.
......@@ -1275,72 +1276,6 @@ function drupal_sort_css_js($a, $b) {
}
}
/**
* Pre-render callback: Adds the elements needed for CSS tags to be rendered.
*
* For production websites, LINK tags are preferable to STYLE tags with @import
* statements, because:
* - They are the standard tag intended for linking to a resource.
* - On Firefox 2 and perhaps other browsers, CSS files included with @import
* statements don't get saved when saving the complete web page for offline
* use: http://drupal.org/node/145218.
* - On IE, if only LINK tags and no @import statements are used, all the CSS
* files are downloaded in parallel, resulting in faster page load, but if
* @import statements are used and span across multiple STYLE tags, all the
* ones from one STYLE tag must be downloaded before downloading begins for
* the next STYLE tag. Furthermore, IE7 does not support media declaration on
* the @import statement, so multiple STYLE tags must be used when different
* files are for different media types. Non-IE browsers always download in
* parallel, so this is an IE-specific performance quirk:
* http://www.stevesouders.com/blog/2009/04/09/dont-use-import/.
*
* However, IE has an annoying limit of 31 total CSS inclusion tags
* (http://drupal.org/node/228818) and LINK tags are limited to one file per
* tag, whereas STYLE tags can contain multiple @import statements allowing
* multiple files to be loaded per tag. When CSS aggregation is disabled, a
* Drupal site can easily have more than 31 CSS files that need to be loaded, so
* using LINK tags exclusively would result in a site that would display
* incorrectly in IE. Depending on different needs, different strategies can be
* employed to decide when to use LINK tags and when to use STYLE tags.
*
* The strategy employed by this function is to use LINK tags for all aggregate
* files and for all files that cannot be aggregated (e.g., if 'preprocess' is
* set to FALSE or the type is 'external'), and to use STYLE tags for groups
* of files that could be aggregated together but aren't (e.g., if the site-wide
* aggregation setting is disabled). This results in all LINK tags when
* aggregation is enabled, a guarantee that as many or only slightly more tags
* are used with aggregation disabled than enabled (so that if the limit were to
* be crossed with aggregation enabled, the site developer would also notice the
* problem while aggregation is disabled), and an easy way for a developer to
* view HTML source while aggregation is disabled and know what files will be
* aggregated together when aggregation becomes enabled.
*
* This function evaluates the aggregation enabled/disabled condition on a group
* by group basis by testing whether an aggregate file has been made for the
* group rather than by testing the site-wide aggregation setting. This allows
* this function to work correctly even if modules have implemented custom
* logic for grouping and aggregating files.
*
* @param $element
* A render array containing:
* - '#items': The CSS items as returned by _drupal_add_css() and altered by
* drupal_get_css().
*
* @return
* A render array that will render to a string of XHTML CSS tags.
*
* @see drupal_get_css()
*/
function drupal_pre_render_styles($elements) {
$css_assets = $elements['#items'];
// Aggregate the CSS if necessary, but only during normal site operation.
if (!defined('MAINTENANCE_MODE') && \Drupal::config('system.performance')->get('css.preprocess')) {
$css_assets = \Drupal::service('asset.css.collection_optimizer')->optimize($css_assets);
}
return \Drupal::service('asset.css.collection_renderer')->render($css_assets);
}
/**
* Deletes old cached CSS files.
*
......@@ -1670,7 +1605,8 @@ function drupal_clean_id_identifier($id) {
* 'preprocess' option was set to FALSE.
* - browsers: An array containing information specifying which browsers
* should load the JavaScript item. See
* drupal_pre_render_conditional_comments() for details.
* \Drupal\Core\Render\Element\HtmlTag::preRenderConditionalComments() for
* details.
*
* @return
* The current array of JavaScript files, settings, and in-line code,
......@@ -1990,41 +1926,6 @@ function drupal_merge_attached(array $a, array $b) {
return NestedArray::mergeDeep($a, $b);
}
/**
* #pre_render callback to add the elements needed for JavaScript tags to be rendered.
*
* This function evaluates the aggregation enabled/disabled condition on a group
* by group basis by testing whether an aggregate file has been made for the
* group rather than by testing the site-wide aggregation setting. This allows
* this function to work correctly even if modules have implemented custom
* logic for grouping and aggregating files.
*
* @param $element
* A render array containing:
* - #items: The JavaScript items as returned by _drupal_add_js() and
* altered by drupal_get_js().
* - #group_callback: A function to call to group #items. Following
* this function, #aggregate_callback is called to aggregate items within
* the same group into a single file.
* - #aggregate_callback: A function to call to aggregate the items within
* the groups arranged by the #group_callback function.
*
* @return
* A render array that will render to a string of JavaScript tags.
*
* @see drupal_get_js()
*/
function drupal_pre_render_scripts($elements) {
$js_assets = $elements['#items'];
// Aggregate the JavaScript if necessary, but only during normal site
// operation.
if (!defined('MAINTENANCE_MODE') && \Drupal::config('system.performance')->get('js.preprocess')) {
$js_assets = \Drupal::service('asset.js.collection_optimizer')->optimize($js_assets);
}
return \Drupal::service('asset.js.collection_renderer')->render($js_assets);
}
/**
* Adds attachments to a render() structure.
*
......@@ -2562,137 +2463,6 @@ function drupal_set_page_content($content = NULL) {
}
}
/**
* Pre-render callback: Renders #browsers into #prefix and #suffix.
*
* @param $elements
* A render array with a '#browsers' property. The '#browsers' property can
* contain any or all of the following keys:
* - 'IE': If FALSE, the element is not rendered by Internet Explorer. If
* TRUE, the element is rendered by Internet Explorer. Can also be a string
* containing an expression for Internet Explorer to evaluate as part of a
* conditional comment. For example, this can be set to 'lt IE 7' for the
* element to be rendered in Internet Explorer 6, but not in Internet
* Explorer 7 or higher. Defaults to TRUE.
* - '!IE': If FALSE, the element is not rendered by browsers other than
* Internet Explorer. If TRUE, the element is rendered by those browsers.
* Defaults to TRUE.
* Examples:
* - To render an element in all browsers, '#browsers' can be left out or set
* to array('IE' => TRUE, '!IE' => TRUE).
* - To render an element in Internet Explorer only, '#browsers' can be set
* to array('!IE' => FALSE).
* - To render an element in Internet Explorer 6 only, '#browsers' can be set
* to array('IE' => 'lt IE 7', '!IE' => FALSE).
* - To render an element in Internet Explorer 8 and higher and in all other
* browsers, '#browsers' can be set to array('IE' => 'gte IE 8').
*
* @return
* The passed-in element with markup for conditional comments potentially
* added to '#prefix' and '#suffix'.
*/
function drupal_pre_render_conditional_comments($elements) {
$browsers = isset($elements['#browsers']) ? $elements['#browsers'] : array();
$browsers += array(
'IE' => TRUE,
'!IE' => TRUE,
);
// If rendering in all browsers, no need for conditional comments.
if ($browsers['IE'] === TRUE && $browsers['!IE']) {
return $elements;
}
// Determine the conditional comment expression for Internet Explorer to
// evaluate.
if ($browsers['IE'] === TRUE) {
$expression = 'IE';
}
elseif ($browsers['IE'] === FALSE) {
$expression = '!IE';
}
else {
$expression = $browsers['IE'];
}
// Wrap the element's potentially existing #prefix and #suffix properties with
// conditional comment markup. The conditional comment expression is evaluated
// by Internet Explorer only. To control the rendering by other browsers,
// either the "downlevel-hidden" or "downlevel-revealed" technique must be
// used. See http://en.wikipedia.org/wiki/Conditional_comment for details.
$elements += array(
'#prefix' => '',
'#suffix' => '',
);
if (!$browsers['!IE']) {
// "downlevel-hidden".
$elements['#prefix'] = "\n<!--[if $expression]>\n" . $elements['#prefix'];
$elements['#suffix'] .= "<![endif]-->\n";
}
else {
// "downlevel-revealed".
$elements['#prefix'] = "\n<!--[if $expression]><!-->\n" . $elements['#prefix'];
$elements['#suffix'] .= "<!--<![endif]-->\n";
}
return $elements;
}
/**
* Pre-render callback: Renders a generic HTML tag with attributes into #markup.
*
* Note: It is the caller's responsibility to sanitize any input parameters.
* This callback does not perform sanitization.
*
* @param array $element
* An associative array containing:
* - #tag: The tag name to output. Typical tags added to the HTML HEAD:
* - meta: To provide meta information, such as a page refresh.
* - link: To refer to stylesheets and other contextual information.
* - script: To load JavaScript.
* The value of #tag is not escaped or sanitized, so do not pass in user
* input.
* - #attributes: (optional) An array of HTML attributes to apply to the
* tag.
* - #value: (optional) A string containing tag content, such as inline
* CSS.
* - #value_prefix: (optional) A string to prepend to #value, e.g. a CDATA
* wrapper prefix.
* - #value_suffix: (optional) A string to append to #value, e.g. a CDATA
* wrapper suffix.
*/
function drupal_pre_render_html_tag($element) {
$attributes = isset($element['#attributes']) ? new Attribute($element['#attributes']) : '';
if (!isset($element['#value'])) {
// This function is intended for internal use, so we assume that no unsafe
// values are passed in #tag. The attributes are already safe because
// Attribute output is already automatically sanitized.
// @todo Escape this properly instead? https://www.drupal.org/node/2296101
$markup = SafeMarkup::set('<' . $element['#tag'] . $attributes . " />\n");
}
else {
$markup = '<' . $element['#tag'] . $attributes . '>';
if (isset($element['#value_prefix'])) {
$markup .= $element['#value_prefix'];
}
$markup .= $element['#value'];
if (isset($element['#value_suffix'])) {
$markup .= $element['#value_suffix'];
}
$markup .= '</' . $element['#tag'] . ">\n";
// @todo We cannot actually guarantee this markup is safe. Consider a fix
// in: https://www.drupal.org/node/2296101
$markup = SafeMarkup::set($markup);
}
if (!empty($element['#noscript'])) {
$element['#markup'] = '<noscript>' . $markup . '</noscript>';
}
else {
$element['#markup'] = $markup;
}
return $element;
}
/**
* Pre-render callback: Renders a link into #markup.
*
......@@ -2797,26 +2567,6 @@ function drupal_pre_render_links($element) {
return $element;
}
/**
* Pre-render callback: Attaches the dropbutton library and required markup.
*/
function drupal_pre_render_dropbutton($element) {
$element['#attached']['library'][] = 'core/drupal.dropbutton';
$element['#attributes']['class'][] = 'dropbutton';
if (!isset($element['#theme_wrappers'])) {
$element['#theme_wrappers'] = array();
}
array_unshift($element['#theme_wrappers'], 'dropbutton_wrapper');
// Enable targeted theming of specific dropbuttons (e.g., 'operations' or
// 'operations__node').
if (isset($element['#subtype'])) {
$element['#theme'] .= '__' . $element['#subtype'];
}
return $element;
}
/**
* Processes the page render array, enhancing it as necessary.
*
......
This diff is collapsed.
......@@ -11,7 +11,6 @@
use Drupal\Component\Serialization\Json;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Component\Utility\String;
use Drupal\Component\Utility\UrlHelper;
use Drupal\Component\Utility\Xss;
use Drupal\Core\Config\Config;
use Drupal\Core\Config\StorageException;
......@@ -801,25 +800,6 @@ function theme_disable($theme_list) {
return \Drupal::service('theme_handler')->disable($theme_list);
}
/**
* Renders a twig string directly.
*
* @param string $template_string
* The template string to render with placeholders.
* @param array $context
* An array of parameters to pass to the template.
*
* @return string
* The rendered inline template.
*/
function drupal_render_inline_template(&$element) {
/** @var \Drupal\Core\Template\TwigEnvironment $environment */
$environment = \Drupal::service('twig');
$markup = $environment->renderInline($element['#template'], $element['#context']);
$element['#markup'] = $markup;
return $element;
}
/**
* @addtogroup themeable
* @{
......@@ -1088,129 +1068,6 @@ function template_preprocess_image(&$variables) {
}
}
/**
* #pre_render callback to transform children of an element into #rows suitable for theme_table().
*
* This function converts sub-elements of an element of #type 'table' to be
* suitable for theme_table():
* - The first level of sub-elements are table rows. Only the #attributes
* property is taken into account.
* - The second level of sub-elements is converted into columns for the
* corresponding first-level table row.
*
* Simple example usage:
* @code
* $form['table'] = array(
* '#type' => 'table',
* '#header' => array(t('Title'), array('data' => t('Operations'), 'colspan' => '1')),
* // Optionally, to add tableDrag support:
* '#tabledrag' => array(
* array(
* 'action' => 'order',
* 'relationship' => 'sibling',
* 'group' => 'thing-weight',
* ),
* ),
* );
* foreach ($things as $row => $thing) {
* $form['table'][$row]['#weight'] = $thing['weight'];
*
* $form['table'][$row]['title'] = array(
* '#type' => 'textfield',
* '#default_value' => $thing['title'],
* );
*
* // Optionally, to add tableDrag support:
* $form['table'][$row]['#attributes']['class'][] = 'draggable';
* $form['table'][$row]['weight'] = array(
* '#type' => 'textfield',
* '#title' => t('Weight for @title', array('@title' => $thing['title'])),
* '#title_display' => 'invisible',
* '#size' => 4,
* '#default_value' => $thing['weight'],
* '#attributes' => array('class' => array('thing-weight')),
* );
*
* // The amount of link columns should be identical to the 'colspan'
* // attribute in #header above.
* $form['table'][$row]['edit'] = array(
* '#type' => 'link',
* '#title' => t('Edit'),
* '#href' => 'thing/' . $row . '/edit',
* );
* }
* @endcode
*
* @param array $element
* A structured array containing two sub-levels of elements. Properties used:
* - #tabledrag: The value is a list of $options arrays that are passed to
* drupal_attach_tabledrag(). The HTML ID of the table is added to each
* $options array.
*
* @see system_element_info()
* @see theme_table()
* @see drupal_process_attached()
* @see drupal_attach_tabledrag()
*/
function drupal_pre_render_table(array $element) {
foreach (Element::children($element) as $first) {
$row = array('data' => array());
// Apply attributes of first-level elements as table row attributes.
if (isset($element[$first]['#attributes'])) {
$row += $element[$first]['#attributes'];
}
// Turn second-level elements into table row columns.
// @todo Do not render a cell for children of #type 'value'.
// @see http://drupal.org/node/1248940
foreach (Element::children($element[$first]) as $second) {
// Assign the element by reference, so any potential changes to the
// original element are taken over.
$column = array('data' => &$element[$first][$second]);
// Apply wrapper attributes of second-level elements as table cell
// attributes.
if (isset($element[$first][$second]['#wrapper_attributes'])) {
$column += $element[$first][$second]['#wrapper_attributes'];
}
$row['data'][] = $column;
}
$element['#rows'][] = $row;
}
// Take over $element['#id'] as HTML ID attribute, if not already set.
Element::setAttributes($element, array('id'));
// Add sticky headers, if applicable.
if (count($element['#header']) && $element['#sticky']) {
$element['#attached']['library'][] = 'core/drupal.tableheader';
// Add 'sticky-enabled' class to the table to identify it for JS.
// This is needed to target tables constructed by this function.
$element['#attributes']['class'][] = 'sticky-enabled';
}
// If the table has headers and it should react responsively to columns hidden
// with the classes represented by the constants RESPONSIVE_PRIORITY_MEDIUM
// and RESPONSIVE_PRIORITY_LOW, add the tableresponsive behaviors.
if (count($element['#header']) && $element['#responsive']) {
$element['#attached']['library'][] = 'core/drupal.tableresponsive';
// Add 'responsive-enabled' class to the table to identify it for JS.
// This is needed to target tables constructed by this function.
$element['#attributes']['class'][] = 'responsive-enabled';
}
// If the custom #tabledrag is set and there is a HTML ID, add the table's
// HTML ID to the options and attach the behavior.
if (!empty($element['#tabledrag']) && isset($element['#attributes']['id'])) {
foreach ($element['#tabledrag'] as $options) {
$options['table_id'] = $element['#attributes']['id'];
drupal_attach_tabledrag($element, $options);
}
}
return $element;
}
/**
* Prepares variables for table templates.
*
......@@ -1732,38 +1589,10 @@ function _template_preprocess_default_variables() {
/**
* #pre_render callback for the html element type.
*
* @param array $element
* A structured array containing the html element type build properties.
*
* @see system_element_info()
* @deprecated Use \Drupal\Core\Render\Element\Html::preRenderHtml().
*/
function drupal_pre_render_html(array $element) {
// Add favicon.
if (theme_get_setting('features.favicon')) {
$favicon = theme_get_setting('favicon.url');
$type = theme_get_setting('favicon.mimetype');
$element['#attached']['drupal_add_html_head_link'][][] = array(
'rel' => 'shortcut icon',
'href' => UrlHelper::stripDangerousProtocols($favicon),
'type' => $type,
);
}
return $element;
}
/**
* #pre_render callback for the page element type.
*
* @param array $element
* A structured array containing the page element type build properties.
*
* @see system_element_info()
*/
function drupal_pre_render_page(array $element) {
$element['#cache']['tags']['theme'] = \Drupal::theme()->getActiveTheme()->getName();
$element['#cache']['tags']['theme_global_settings'] = TRUE;
return $element;
return Element\Html::preRenderHtml($element);
}
/**
......
......@@ -9,6 +9,7 @@
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Field\FieldItemBase;
use Drupal\Core\Render\Element\Email;
use Drupal\Core\TypedData\DataDefinition;
/**
......@@ -42,7 +43,7 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
'columns' => array(
'value' => array(
'type' => 'varchar',
'length' => EMAIL_MAX_LENGTH,
'length' => Email::EMAIL_MAX_LENGTH,
'not null' => FALSE,
),
),
......@@ -59,8 +60,8 @@ public function getConstraints() {
$constraints[] = $constraint_manager->create('ComplexData', array(
'value' => array(
'Length' => array(
'max' => EMAIL_MAX_LENGTH,
'maxMessage' => t('%name: the email address can not be longer than @max characters.', array('%name' => $this->getFieldDefinition()->getLabel(), '@max' => EMAIL_MAX_LENGTH)),
'max' => Email::EMAIL_MAX_LENGTH,
'maxMessage' => t('%name: the email address can not be longer than @max characters.', array('%name' => $this->getFieldDefinition()->getLabel(), '@max' => Email::EMAIL_MAX_LENGTH)),
)
),
));
......
<?php
/**
* @file
* Contains \Drupal\Core\Render\Element\Actions.
*/
namespace Drupal\Core\Render\Element;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
/**
* Provides a wrapper element to group one or more buttons in a form.
*
* Use of the 'actions' element as an array key helps to ensure proper styling
* in themes and to enable other modules to properly alter a form's actions.
*
* @RenderElement("actions")
*/
class Actions extends Container {
/**
* {@inheritdoc}
*/
public function getInfo() {
$class = get_class($this);
return array(
'#process' => array(
// @todo Move this to #pre_render.
array($class, 'preRenderActionsDropbutton'),
array($class, 'processActions'),
array($class, 'processContainer'),
),
'#weight' => 100,
'#theme_wrappers' => array('container'),
);
}
/**
* Processes a form actions container element.
*
* @param array $element
* An associative array containing the properties and children of the
* form actions container.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
* @param array $complete_form
* The complete form structure.
*
* @return array
* The processed element.
*/
public static function processActions(&$element, FormStateInterface $form_state, &$complete_form) {
$element['#attributes']['class'][] = 'form-actions';
return $element;
}
/**
* #pre_render callback for #type 'actions'.
*
* This callback iterates over all child elements of the #type 'actions'
* container to look for elements with a #dropbutton property, so as to group
* those elements into dropbuttons. As such, it works similar to #group, but is
* specialized for dropbuttons.
*
* The value of #dropbutton denotes the dropbutton to group the child element
* into. For example, two different values of 'foo' and 'bar' on child elements
* would generate two separate dropbuttons, which each contain the corresponding
* buttons.
*
* @param array $element
* The #type 'actions' element to process.
* @param \Drupal\Core\Form\FormStateInterface $form_state