Verified Commit 2fcc7564 authored by Dave Long's avatar Dave Long
Browse files

Issue #1643386 by Grevil, Anybody, vasike, lauriii, Spokje, nod_, bnjmnm,...

Issue #1643386 by Grevil, Anybody, vasike, lauriii, Spokje, nod_, bnjmnm, Pancho, tim.plunkett, longwave: Strip useless "_" at beginning and end of JS-transliterated machine names
parent 80bad6f9
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -255,6 +255,9 @@ public function getMachineNameSuggestion() {
    $transliterated = mb_strtolower($transliterated);

    $transliterated = preg_replace('@[^a-z0-9_.]+@', '', $transliterated);
    // Furthermore remove any characters that are not alphanumerical from the
    // beginning and end of the transliterated string.
    $transliterated = preg_replace('@^([^a-z0-9]+)|([^a-z0-9]+)$@', '', $transliterated);

    return $transliterated;
  }
+54 −21
Original line number Diff line number Diff line
@@ -6,6 +6,53 @@
 */

(function ($, Drupal, drupalSettings, slugify) {
  /**
   * Trims string by a character.
   *
   * @param {string} string
   *   The string to trim.
   * @param {string} character
   *   The characters to trim.
   *
   * @returns {string}
   *   A trimmed string.
   */
  const trimByChar = (string, character) => {
    const first = [...string].findIndex((char) => char !== character);
    const last = [...string].reverse().findIndex((char) => char !== character);
    return string.substring(first, string.length - last);
  };

  /**
   * Transform a human-readable name to a machine name.
   *
   * @param {string} source
   *   A string to transform.
   * @see trans {object} settings
   *   The machine name settings for the corresponding field.
   * @param {string} settings.replace_pattern
   *   A regular expression (without modifiers) matching disallowed characters
   *   in the machine name; e.g., '[^a-z0-9]+'.
   * @param {string} settings.replace
   *   A character to replace disallowed characters with; e.g., '_' or '-'.
   * @param {number} settings.maxlength
   *   The maximum length of the machine name.
   *
   * @return {string}
   *   The machine name string.
   */
  const prepareMachineName = (source, settings) => {
    const rx = new RegExp(settings.replace_pattern, 'g');

    return trimByChar(
      source
        .toLowerCase()
        .replace(rx, settings.replace)
        .substring(0, settings.maxlength),
      settings.replace,
    );
  };

  /**
   * Attach the machine-readable name form element behavior.
   *
@@ -62,18 +109,11 @@
        const options = data.options;
        const baseValue = e.target.value;

        const rx = new RegExp(options.replace_pattern, 'g');
        const expected = baseValue
          .toLowerCase()
          .replace(rx, options.replace)
          .substr(0, options.maxlength);

        const needsTransliteration = !/^[A-Za-z0-9_\s]*$/.test(baseValue);
        if (needsTransliteration) {
          const machineName = self.transliterate(baseValue, options);
          self.showMachineName(machineName.substr(0, options.maxlength), data);
          self.showMachineName(self.transliterate(baseValue, options), data);
        } else {
          self.showMachineName(expected, data);
          self.showMachineName(prepareMachineName(baseValue, options), data);
        }
      }

@@ -153,18 +193,12 @@
        // human-readable form element value.
        if (machine === '' && $source[0].value !== '') {
          if (/^[A-Za-z0-9_\s]*$/.test($source[0].value)) {
            const rx = new RegExp(options.replace_pattern, 'g');
            const expected = $source[0].value
              .toLowerCase()
              .replace(rx, options.replace)
              .substr(0, options.maxlength);
            self.showMachineName(expected, eventData);
          } else {
            self.transliterate($source[0].value, options);
            self.showMachineName(
              machine.substr(0, options.maxlength),
              prepareMachineName($source[0].value, options),
              eventData,
            );
          } else {
            self.showMachineName(machine, eventData);
          }
        }

@@ -253,9 +287,8 @@
        allowedChars: settings.replace_pattern,
        replace: normalizedLanguageOverrides,
      });
      const transliterated = slugify(source.substr(0, settings.maxlength));
      const rx = new RegExp(settings.replace_pattern, 'g');
      return transliterated.replace(rx, settings.replace);

      return prepareMachineName(slugify(source), settings);
    },
  };
})(jQuery, Drupal, drupalSettings, slugify);
+22 −2
Original line number Diff line number Diff line
@@ -53,13 +53,33 @@ public function testMachineName() {
      [
        'input' => 'Test value !0-9@',
        'message' => 'A title that should be transliterated must be equal to the php generated machine name',
        'expected' => 'test_value_0_9_',
        'expected' => 'test_value_0_9',
      ],
      [
        'input' => 'Test value',
        'message' => 'A title that should not be transliterated must be equal to the php generated machine name',
        'expected' => 'test_value',
      ],
      [
        'input' => ' Test Value ',
        'message' => 'A title that should not be transliterated must be equal to the php generated machine name',
        'expected' => 'test_value',
      ],
      [
        'input' => ', Neglect?! ',
        'message' => 'A title that should not be transliterated must be equal to the php generated machine name',
        'expected' => 'neglect',
      ],
      [
        'input' => '0123456789!"$%&/()=?Test value?=)(/&%$"!9876543210',
        'message' => 'A title that should not be transliterated must be equal to the php generated machine name',
        'expected' => '0123456789_test_value_9876543210',
      ],
      [
        'input' => '_Test_Value_',
        'message' => 'A title that should not be transliterated must be equal to the php generated machine name',
        'expected' => 'test_value',
      ],
    ];

    // Get page and session.
@@ -118,7 +138,7 @@ public function testMachineName() {
    $this->assertFalse($machine_name_2_wrapper->isVisible(), 'The ID field must not be visible');

    // Validate if the element contains the correct value.
    $this->assertEquals($test_values[1]['expected'], $machine_name_1_field->getValue(), 'The ID field value must be equal to the php generated machine name');
    $this->assertEquals(end($test_values)['expected'], $machine_name_1_field->getValue(), 'The ID field value must be equal to the php generated machine name');

    // Test that machine name generation still occurs after an HTML 5
    // validation failure.
+2 −2
Original line number Diff line number Diff line
@@ -81,10 +81,10 @@ public function machineNameInputOutput(): array {
      // ['en', '𐌰𐌸', '__'],
      ['en', 'Ä Ö Ü Å Ø äöüåøhello', 'a_o_u_a_o_aouaohello'],
      ['de', 'Ä Ö Ü Å Ø äöüåøhello', 'ae_oe_ue_a_o_aeoeueaohello'],
      ['de', ']URY&m_G^;', ' _ury_m_g_'],
      ['de', ']URY&m_G^;', ' ury_m_g'],
      ['da', 'Ä Ö Ü Å Ø äöüåøhello', 'a_o_u_aa_oe_aouaaoehello'],
      ['kg', 'ц', 'ts'],
      ['en', ' Hello Abventor! ', '_hello_abventor_'],
      ['en', ' Hello Abventor! ', 'hello_abventor'],
      // cSpell:enable
    ];
  }