diff --git a/core/lib/Drupal/Core/Datetime/DateFormatter.php b/core/lib/Drupal/Core/Datetime/DateFormatter.php index 7b56e77e0777b981e021c952dc4c0ee6f81c2daf..0b4f817f46fd5013fb146edf8fba84507a079ba0 100644 --- a/core/lib/Drupal/Core/Datetime/DateFormatter.php +++ b/core/lib/Drupal/Core/Datetime/DateFormatter.php @@ -192,33 +192,6 @@ public function formatInterval($interval, $granularity = 2, $langcode = NULL) { return $output ? $output : $this->t('0 sec', array(), array('langcode' => $langcode)); } - /** - * Provides values for all date formatting characters for a given timestamp. - * - * @param string|null $langcode - * (optional) Language code of the date format, if different from the site - * default language. - * @param int|null $timestamp - * (optional) The Unix timestamp to format, defaults to the request time. - * @param string|null $timezone - * (optional) The timezone to use, if different from the site's default - * timezone. - * - * @return array - * An array of formatted date values, indexed by the date format character. - * - * @see date() - */ - public function getSampleDateFormats($langcode = NULL, $timestamp = NULL, $timezone = NULL) { - $timestamp = $timestamp ?: (int) $_SERVER['REQUEST_TIME']; - // All date format characters for the PHP date() function. - $date_chars = str_split('dDjlNSwzWFmMntLoYyaABgGhHisueIOPTZcrU'); - $date_elements = array_combine($date_chars, $date_chars); - return array_map(function($character) use ($timestamp, $timezone, $langcode) { - return $this->format($timestamp, 'custom', $character, $timezone, $langcode); - }, $date_elements); - } - /** * Loads the given format pattern for the given langcode. * @@ -227,9 +200,8 @@ public function getSampleDateFormats($langcode = NULL, $timestamp = NULL, $timez * @param string $langcode * The langcode of the language to use. * - * @return string|null - * The pattern for the date format in the given language for non-custom - * formats, NULL otherwise. + * @return string + * The pattern for the date format in the given language. */ protected function dateFormat($format, $langcode) { if (!isset($this->dateFormats[$format][$langcode])) { diff --git a/core/modules/config_translation/src/Form/ConfigTranslationFormBase.php b/core/modules/config_translation/src/Form/ConfigTranslationFormBase.php index c4dfa10ec3499fe166f50ba6a593121d0c3cec6c..9e5372f05893d323a0dd1977e7d19dbedc63b841 100644 --- a/core/modules/config_translation/src/Form/ConfigTranslationFormBase.php +++ b/core/modules/config_translation/src/Form/ConfigTranslationFormBase.php @@ -176,9 +176,6 @@ public function buildForm(array $form, FormStateInterface $form_state, Request $ if ($form_element = $this->createFormElement($schema)) { $parents = array('config_names', $name); $form['config_names'][$name] += $form_element->getTranslationBuild($this->sourceLanguage, $this->language, $source_config, $translation_config, $parents); - if ($attributes = $form_element->getFormAttributes()) { - $form = array_merge_recursive($form, $attributes); - } } } diff --git a/core/modules/config_translation/src/FormElement/DateFormat.php b/core/modules/config_translation/src/FormElement/DateFormat.php index b5979a007a734af9fb3d87db68f86f3ef6fbb66e..729afeee94265366b9c4d065b8628e50c3fbee4f 100644 --- a/core/modules/config_translation/src/FormElement/DateFormat.php +++ b/core/modules/config_translation/src/FormElement/DateFormat.php @@ -22,29 +22,51 @@ class DateFormat extends FormElementBase { * {@inheritdoc} */ public function getTranslationElement(LanguageInterface $translation_language, $source_config, $translation_config) { - /** @var \Drupal\Core\Datetime\DateFormatter $date_formatter */ - $date_formatter = \Drupal::service('date.formatter'); $description = $this->t('A user-defined date format. See the <a href="@url">PHP manual</a> for available options.', array('@url' => 'http://php.net/manual/function.date.php')); - $format = $this->t('Displayed as %date_format', array('%date_format' => $date_formatter->format((int) $_SERVER['REQUEST_TIME'], 'custom', $translation_config))); + $format = $this->t('Displayed as %date_format', array('%date_format' => \Drupal::service('date.formatter')->format(REQUEST_TIME, 'custom', $translation_config))); - return [ + return array( '#type' => 'textfield', '#description' => $description, - '#field_suffix' => ' <small data-drupal-date-formatter="preview">' . $format . '</small>', - '#attributes' => [ - 'data-drupal-date-formatter' => 'source', - ], - '#attached' => [ - 'drupalSettings' => array('dateFormats' => $date_formatter->getSampleDateFormats($translation_language->getId())), - ], - ] + parent::getTranslationElement($translation_language, $source_config, $translation_config); + '#field_suffix' => ' <div class="edit-date-format-suffix"><small id="edit-date-format-suffix">' . $format . '</small></div>', + '#ajax' => array( + 'callback' => 'Drupal\config_translation\FormElement\DateFormat::ajaxSample', + 'event' => 'keyup', + 'progress' => array('type' => 'throbber', 'message' => NULL), + ), + ) + parent::getTranslationElement($translation_language, $source_config, $translation_config); } /** - * {@inheritdoc} + * Ajax callback to render a sample of the input date format. + * + * @param array $form + * Form API array structure. + * @param \Drupal\Core\Form\FormStateInterface $form_state + * Form state information. + * + * @return AjaxResponse + * Ajax response with the rendered sample date using the given format. If + * the given format cannot be identified or was empty, the response will + * be empty as well. */ - public function getFormAttributes() { - return ['#attached' => ['library' => ['system/drupal.system.date']]]; + public static function ajaxSample(array $form, FormStateInterface $form_state) { + $response = new AjaxResponse(); + + $format_value = NestedArray::getValue($form_state->getValues(), $form_state->getTriggeringElement()['#array_parents']); + if (!empty($format_value)) { + // Format the date with a custom date format with the given pattern. + // The object is not instantiated in an Ajax context, so $this->t() + // cannot be used here. + $format = t('Displayed as %date_format', array('%date_format' => \Drupal::service('date.formatter')->format(REQUEST_TIME, 'custom', $format_value))); + + // Return a command instead of a string, since the Ajax framework + // automatically prepends an additional empty DIV element for a string, + // which breaks the layout. + $response->addCommand(new ReplaceCommand('#edit-date-format-suffix', '<small id="edit-date-format-suffix">' . $format . '</small>')); + } + + return $response; } } diff --git a/core/modules/config_translation/src/FormElement/ElementInterface.php b/core/modules/config_translation/src/FormElement/ElementInterface.php index c9fb0b9ee7b9b27aebd5df9a14deac8bbe0ab47a..286eeba0b847e3d53c4647cbade44c42d509a629 100644 --- a/core/modules/config_translation/src/FormElement/ElementInterface.php +++ b/core/modules/config_translation/src/FormElement/ElementInterface.php @@ -70,12 +70,4 @@ public function getTranslationBuild(LanguageInterface $source_language, Language */ public function setConfig(Config $base_config, LanguageConfigOverride $config_translation, $config_values, $base_key = NULL); - /** - * Allows to provide form attributes for the configuration form. - * - * @return array - * An array of form attributes. - */ - public function getFormAttributes(); - } diff --git a/core/modules/config_translation/src/FormElement/FormElementBase.php b/core/modules/config_translation/src/FormElement/FormElementBase.php index ef76ef44447abded4fcc34b81d68a3f77724f264..e13cc31227c7af96cddd52cf65685ee733199c3f 100644 --- a/core/modules/config_translation/src/FormElement/FormElementBase.php +++ b/core/modules/config_translation/src/FormElement/FormElementBase.php @@ -74,13 +74,6 @@ public function getTranslationBuild(LanguageInterface $source_language, Language return $build; } - /** - * {@inheritdoc} - */ - public function getFormAttributes() { - return []; - } - /** * Returns the source element for a given configuration definition. * diff --git a/core/modules/config_translation/src/FormElement/ListElement.php b/core/modules/config_translation/src/FormElement/ListElement.php index 47232038d964ada0bd268fb872aa4abf131158b7..9365fc2a17471ed83492ba23971a6a6095649042 100644 --- a/core/modules/config_translation/src/FormElement/ListElement.php +++ b/core/modules/config_translation/src/FormElement/ListElement.php @@ -96,23 +96,6 @@ public function setConfig(Config $base_config, LanguageConfigOverride $config_tr } } - /** - * {@inheritdoc} - */ - public function getFormAttributes() { - $attributes = []; - foreach ($this->element as $key => $element) { - if ($form_element = ConfigTranslationFormBase::createFormElement($element)) { - $form_attributes = $form_element->getFormAttributes(); - if (empty($form_attributes)) { - continue; - } - $attributes += $form_attributes; - } - } - return $attributes; - } - /** * Returns the title for the 'details' element of a group of schema elements. * diff --git a/core/modules/config_translation/src/Tests/ConfigTranslationUiTest.php b/core/modules/config_translation/src/Tests/ConfigTranslationUiTest.php index 00b36c526df309a4060b653f38abe341f19e6978..807307c9338a316306676b5b949cda2686572ab5 100644 --- a/core/modules/config_translation/src/Tests/ConfigTranslationUiTest.php +++ b/core/modules/config_translation/src/Tests/ConfigTranslationUiTest.php @@ -446,9 +446,6 @@ public function testDateFormatTranslation() { $this->drupalGet($translation_page_url); $this->assertText($label); - // Make sure that the date library is added. - $this->assertRaw('core/modules/system/js/system.date.js'); - // Update translatable fields. $edit = array( 'translation[config_names][core.date_format.' . $id . '][label]' => $id . ' - FR', diff --git a/core/modules/system/js/system.date.js b/core/modules/system/js/system.date.js deleted file mode 100644 index fcab3efd55d91d65776ae374b6709332a4665c3c..0000000000000000000000000000000000000000 --- a/core/modules/system/js/system.date.js +++ /dev/null @@ -1,46 +0,0 @@ -(function ($, Drupal, drupalSettings) { - - "use strict"; - - var dateFormats = drupalSettings.dateFormats; - - /** - * Display the preview for date format entered. - */ - Drupal.behaviors.dateFormat = { - attach: function (context) { - var $context = $(context); - var $source = $context.find('[data-drupal-date-formatter="source"]').once('dateFormat'); - var $target = $context.find('[data-drupal-date-formatter="preview"]').once('dateFormat'); - var $preview = $target.find('em'); - - // All elements have to exist. - if (!$source.length || !$target.length) { - return; - } - - /** - * Event handler that replaces date characters with value. - * - * @param {object} e - */ - function dateFormatHandler(e) { - var baseValue = $(e.target).val() || ''; - var dateString = baseValue.replace(/\\?(.?)/gi, function (key, value) { - return dateFormats[key] ? dateFormats[key] : value; - }); - - $preview.html(dateString); - $target.toggleClass('js-hide', !dateString.length); - } - - /** - * On given event triggers the date character replacement. - */ - $source.on('keyup.dateFormat change.dateFormat input.dateFormat', dateFormatHandler) - // Initialize preview. - .trigger('keyup'); - } - }; - -})(jQuery, Drupal, drupalSettings); diff --git a/core/modules/system/src/Form/DateFormatEditForm.php b/core/modules/system/src/Form/DateFormatEditForm.php index 511ad1a935a5e60646c155acc487db610cc9d92c..f8e780f45aa5d6a69c437fb2654752fb2b2e4728 100644 --- a/core/modules/system/src/Form/DateFormatEditForm.php +++ b/core/modules/system/src/Form/DateFormatEditForm.php @@ -21,7 +21,7 @@ public function form(array $form, FormStateInterface $form_state) { $form = parent::form($form, $form_state); $now = t('Displayed as %date', array('%date' => $this->dateFormatter->format(REQUEST_TIME, $this->entity->id()))); - $form['date_format_pattern']['#field_suffix'] = ' <small data-drupal-date-formatter="preview">' . $now . '</small>'; + $form['date_format_pattern']['#field_suffix'] = ' <small id="edit-date-format-suffix">' . $now . '</small>'; $form['date_format_pattern']['#default_value'] = $this->entity->getPattern(); return $form; diff --git a/core/modules/system/src/Form/DateFormatFormBase.php b/core/modules/system/src/Form/DateFormatFormBase.php index 9061d895fa86eeba666aff6c8e4744142c6cab07..c843ba24210e8adfbbba6de2e116217fd6cde773 100644 --- a/core/modules/system/src/Form/DateFormatFormBase.php +++ b/core/modules/system/src/Form/DateFormatFormBase.php @@ -79,6 +79,30 @@ public function exists($entity_id, array $element) { ->execute(); } + /** + * Returns the date for a given format string. + * + * @param array $form + * An associative array containing the structure of the form. + * @param \Drupal\Core\Form\FormStateInterface $form_state + * The current state of the form. + * + * @return \Drupal\Core\Ajax\AjaxResponse + * An AJAX Response to update the date-time value of the date format. + */ + public static function dateTimeLookup(array $form, FormStateInterface $form_state) { + $format = ''; + if (!$form_state->isValueEmpty('date_format_pattern')) { + $format = t('Displayed as %date_format', array('%date_format' => \Drupal::service('date.formatter')->format(REQUEST_TIME, 'custom', $form_state->getValue('date_format_pattern')))); + } + // Return a command instead of a string, since the Ajax framework + // automatically prepends an additional empty DIV element for a string, which + // breaks the layout. + $response = new AjaxResponse(); + $response->addCommand(new ReplaceCommand('#edit-date-format-suffix', '<small id="edit-date-format-suffix">' . $format . '</small>')); + return $response; + } + /** * {@inheritdoc} */ @@ -102,16 +126,20 @@ public function form(array $form, FormStateInterface $form_state) { 'error' => $this->t('The machine-readable name must be unique, and can only contain lowercase letters, numbers, and underscores. Additionally, it can not be the reserved word "custom".'), ), ); + $form['date_format_pattern'] = array( '#type' => 'textfield', '#title' => t('Format string'), '#maxlength' => 100, '#description' => $this->t('A user-defined date format. See the <a href="@url">PHP manual</a> for available options.', array('@url' => 'http://php.net/manual/function.date.php')), + '#default_value' => '', + '#field_suffix' => ' <small id="edit-date-format-suffix"></small>', + '#ajax' => array( + 'callback' => '::dateTimeLookup', + 'event' => 'keyup', + 'progress' => array('type' => 'throbber', 'message' => NULL), + ), '#required' => TRUE, - '#attributes' => [ - 'data-drupal-date-formatter' => 'source', - ], - '#field_suffix' => ' <small class="js-hide" data-drupal-date-formatter="preview">' . $this->t('Displayed as %date_format', ['%date_format' => '']) . '</small>', ); $form['langcode'] = array( @@ -120,8 +148,7 @@ public function form(array $form, FormStateInterface $form_state) { '#languages' => LanguageInterface::STATE_ALL, '#default_value' => $this->entity->language()->getId(), ); - $form['#attached']['drupalSettings']['dateFormats'] = $this->dateFormatter->getSampleDateFormats(); - $form['#attached']['library'][] = 'system/drupal.system.date'; + return parent::form($form, $form_state); } diff --git a/core/modules/system/js/system.js b/core/modules/system/system.js similarity index 100% rename from core/modules/system/js/system.js rename to core/modules/system/system.js diff --git a/core/modules/system/system.libraries.yml b/core/modules/system/system.libraries.yml index b440e157f4be1e660eef0ec50b754fd660a79004..34c90ddd88d894fcdb2e29e9861bbfdfc4aa981d 100644 --- a/core/modules/system/system.libraries.yml +++ b/core/modules/system/system.libraries.yml @@ -29,7 +29,7 @@ maintenance: drupal.system: version: VERSION js: - js/system.js: {} + system.js: {} dependencies: - core/jquery - core/drupal @@ -39,7 +39,7 @@ drupal.system: drupal.system.modules: version: VERSION js: - js/system.modules.js: {} + system.modules.js: {} dependencies: - core/jquery - core/drupal @@ -50,14 +50,3 @@ diff: css: component: css/system.diff.css: {} - -drupal.system.date: - version: VERSION - js: - js/system.date.js: {} - dependencies: - - core/jquery - - core/drupal - - core/drupalSettings - - core/jquery.once - - core/drupal.form diff --git a/core/modules/system/js/system.modules.js b/core/modules/system/system.modules.js similarity index 100% rename from core/modules/system/js/system.modules.js rename to core/modules/system/system.modules.js diff --git a/core/tests/Drupal/Tests/Core/Datetime/DateTest.php b/core/tests/Drupal/Tests/Core/Datetime/DateTest.php index 4534ccd0bf98bcd9f9178f0f1e4d7cdfbb5c4d27..da9ebaa0ba63037784f02b887fa7941c3def1054 100644 --- a/core/tests/Drupal/Tests/Core/Datetime/DateTest.php +++ b/core/tests/Drupal/Tests/Core/Datetime/DateTest.php @@ -5,10 +5,9 @@ * Contains \Drupal\Tests\Core\Datetime\DateTest. */ -namespace Drupal\Tests\Core\Datetime { +namespace Drupal\Tests\Core\Datetime; use Drupal\Core\Datetime\DateFormatter; -use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Tests\UnitTestCase; /** @@ -46,21 +45,10 @@ class DateTest extends UnitTestCase { protected $dateFormatter; protected function setUp() { - parent::setUp(); - - $entity_storage = $this->getMock('Drupal\Core\Entity\EntityStorageInterface'); - $this->entityManager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface'); - $this->entityManager->expects($this->once())->method('getStorage')->with('date_format')->willReturn($entity_storage); - $this->languageManager = $this->getMock('Drupal\Core\Language\LanguageManagerInterface'); $this->stringTranslation = $this->getMock('Drupal\Core\StringTranslation\TranslationInterface'); - $config_factory = $this->getConfigFactoryStub(['system.date' => ['country' => ['default' => 'GB']]]); - $container = new ContainerBuilder(); - $container->set('config.factory', $config_factory); - \Drupal::setContainer($container); - $this->dateFormatter = new DateFormatter($this->entityManager, $this->languageManager, $this->stringTranslation, $this->getConfigFactoryStub()); } @@ -69,7 +57,7 @@ protected function setUp() { * * @dataProvider providerTestFormatInterval * - * @covers \Drupal\Core\Datetime\DateFormatter::formatInterval + * @see \Drupal\Core\Datetime\DateFormatter::formatInterval() */ public function testFormatInterval($interval, $granularity, $expected, $langcode = NULL) { // Mocks a simple formatPlural implementation. @@ -140,36 +128,4 @@ public function testFormatIntervalZeroSecond() { $this->assertEquals('0 sec', $result); } - /** - * Tests the getSampleDateFormats method. - * - * @covers \Drupal\Core\Datetime\DateFormatter::getSampleDateFormats - */ - public function testGetSampleDateFormats() { - include_once $this->root . '/core/includes/common.inc'; - $timestamp = strtotime('2015-03-22 14:23:00'); - $expected = $this->dateFormatter->getSampleDateFormats('en', $timestamp, 'Europe/London'); - - // Removed characters related to timezone 'e' and 'T', as test does not have - // timezone set. - $date_characters = 'dDjlNSwzWFmMntLoYyaABgGhHisuIOPZcrU'; - $date_chars = str_split($date_characters); - - foreach ($date_chars as $val) { - $this->assertEquals($expected[$val], date($val, $timestamp)); - } - } - -} - -} - -namespace { - use Drupal\Component\Utility\String; - - if (!function_exists('t')) { - function t($string, array $args = []) { - return String::format($string, $args); - } - } }