summaryrefslogtreecommitdiffstatshomepage
path: root/core/misc/machine-name.es6.js
diff options
context:
space:
mode:
authorAlex Pott <alex.a.pott@googlemail.com>2017-05-19 23:12:53 +0100
committerAlex Pott <alex.a.pott@googlemail.com>2017-05-19 23:12:53 +0100
commit8287017e034bc323dec1d86b3f37a804aa082d2d (patch)
treeebd8ff908859b0e1cc4319392da94e8f68033321 /core/misc/machine-name.es6.js
parent9a0e9a649ac8078ce6e5f6089749a1115bdda06b (diff)
downloaddrupal-8287017e034bc323dec1d86b3f37a804aa082d2d.tar.gz
drupal-8287017e034bc323dec1d86b3f37a804aa082d2d.zip
Issue #2818825 by drpal, nod_, droplet, cilefen: Rename all JS files to *.es6.js and compile them
Diffstat (limited to 'core/misc/machine-name.es6.js')
-rw-r--r--core/misc/machine-name.es6.js211
1 files changed, 211 insertions, 0 deletions
diff --git a/core/misc/machine-name.es6.js b/core/misc/machine-name.es6.js
new file mode 100644
index 000000000000..e76292e265cc
--- /dev/null
+++ b/core/misc/machine-name.es6.js
@@ -0,0 +1,211 @@
+/**
+ * @file
+ * Machine name functionality.
+ */
+
+(function ($, Drupal, drupalSettings) {
+
+ 'use strict';
+
+ /**
+ * Attach the machine-readable name form element behavior.
+ *
+ * @type {Drupal~behavior}
+ *
+ * @prop {Drupal~behaviorAttach} attach
+ * Attaches machine-name behaviors.
+ */
+ Drupal.behaviors.machineName = {
+
+ /**
+ * Attaches the behavior.
+ *
+ * @param {Element} context
+ * The context for attaching the behavior.
+ * @param {object} settings
+ * Settings object.
+ * @param {object} settings.machineName
+ * A list of elements to process, keyed by the HTML ID of the form
+ * element containing the human-readable value. Each element is an object
+ * defining the following properties:
+ * - target: The HTML ID of the machine name form element.
+ * - suffix: The HTML ID of a container to show the machine name preview
+ * in (usually a field suffix after the human-readable name
+ * form element).
+ * - label: The label to show for the machine name preview.
+ * - replace_pattern: A regular expression (without modifiers) matching
+ * disallowed characters in the machine name; e.g., '[^a-z0-9]+'.
+ * - replace: A character to replace disallowed characters with; e.g.,
+ * '_' or '-'.
+ * - standalone: Whether the preview should stay in its own element
+ * rather than the suffix of the source element.
+ * - field_prefix: The #field_prefix of the form element.
+ * - field_suffix: The #field_suffix of the form element.
+ */
+ attach: function (context, settings) {
+ var self = this;
+ var $context = $(context);
+ var timeout = null;
+ var xhr = null;
+
+ function clickEditHandler(e) {
+ var data = e.data;
+ data.$wrapper.removeClass('visually-hidden');
+ data.$target.trigger('focus');
+ data.$suffix.hide();
+ data.$source.off('.machineName');
+ }
+
+ function machineNameHandler(e) {
+ var data = e.data;
+ var options = data.options;
+ var baseValue = $(e.target).val();
+
+ var rx = new RegExp(options.replace_pattern, 'g');
+ var expected = baseValue.toLowerCase().replace(rx, options.replace).substr(0, options.maxlength);
+
+ // Abort the last pending request because the label has changed and it
+ // is no longer valid.
+ if (xhr && xhr.readystate !== 4) {
+ xhr.abort();
+ xhr = null;
+ }
+
+ // Wait 300 milliseconds for Ajax request since the last event to update
+ // the machine name i.e., after the user has stopped typing.
+ if (timeout) {
+ clearTimeout(timeout);
+ timeout = null;
+ }
+ if (baseValue.toLowerCase() !== expected) {
+ timeout = setTimeout(function () {
+ xhr = self.transliterate(baseValue, options).done(function (machine) {
+ self.showMachineName(machine.substr(0, options.maxlength), data);
+ });
+ }, 300);
+ }
+ else {
+ self.showMachineName(expected, data);
+ }
+ }
+
+ Object.keys(settings.machineName).forEach(function (source_id) {
+ var machine = '';
+ var eventData;
+ var options = settings.machineName[source_id];
+
+ var $source = $context.find(source_id).addClass('machine-name-source').once('machine-name');
+ var $target = $context.find(options.target).addClass('machine-name-target');
+ var $suffix = $context.find(options.suffix);
+ var $wrapper = $target.closest('.js-form-item');
+ // All elements have to exist.
+ if (!$source.length || !$target.length || !$suffix.length || !$wrapper.length) {
+ return;
+ }
+ // Skip processing upon a form validation error on the machine name.
+ if ($target.hasClass('error')) {
+ return;
+ }
+ // Figure out the maximum length for the machine name.
+ options.maxlength = $target.attr('maxlength');
+ // Hide the form item container of the machine name form element.
+ $wrapper.addClass('visually-hidden');
+ // Determine the initial machine name value. Unless the machine name
+ // form element is disabled or not empty, the initial default value is
+ // based on the human-readable form element value.
+ if ($target.is(':disabled') || $target.val() !== '') {
+ machine = $target.val();
+ }
+ else if ($source.val() !== '') {
+ machine = self.transliterate($source.val(), options);
+ }
+ // Append the machine name preview to the source field.
+ var $preview = $('<span class="machine-name-value">' + options.field_prefix + Drupal.checkPlain(machine) + options.field_suffix + '</span>');
+ $suffix.empty();
+ if (options.label) {
+ $suffix.append('<span class="machine-name-label">' + options.label + ': </span>');
+ }
+ $suffix.append($preview);
+
+ // If the machine name cannot be edited, stop further processing.
+ if ($target.is(':disabled')) {
+ return;
+ }
+
+ eventData = {
+ $source: $source,
+ $target: $target,
+ $suffix: $suffix,
+ $wrapper: $wrapper,
+ $preview: $preview,
+ options: options
+ };
+ // If it is editable, append an edit link.
+ var $link = $('<span class="admin-link"><button type="button" class="link">' + Drupal.t('Edit') + '</button></span>').on('click', eventData, clickEditHandler);
+ $suffix.append($link);
+
+ // Preview the machine name in realtime when the human-readable name
+ // changes, but only if there is no machine name yet; i.e., only upon
+ // initial creation, not when editing.
+ if ($target.val() === '') {
+ $source.on('formUpdated.machineName', eventData, machineNameHandler)
+ // Initialize machine name preview.
+ .trigger('formUpdated.machineName');
+ }
+
+ // Add a listener for an invalid event on the machine name input
+ // to show its container and focus it.
+ $target.on('invalid', eventData, clickEditHandler);
+ });
+ },
+
+ showMachineName: function (machine, data) {
+ var settings = data.options;
+ // Set the machine name to the transliterated value.
+ if (machine !== '') {
+ if (machine !== settings.replace) {
+ data.$target.val(machine);
+ data.$preview.html(settings.field_prefix + Drupal.checkPlain(machine) + settings.field_suffix);
+ }
+ data.$suffix.show();
+ }
+ else {
+ data.$suffix.hide();
+ data.$target.val(machine);
+ data.$preview.empty();
+ }
+ },
+
+ /**
+ * Transliterate a human-readable name to a machine name.
+ *
+ * @param {string} source
+ * A string to transliterate.
+ * @param {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_token
+ * A token to validate the regular expression.
+ * @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 {jQuery}
+ * The transliterated source string.
+ */
+ transliterate: function (source, settings) {
+ return $.get(Drupal.url('machine_name/transliterate'), {
+ text: source,
+ langcode: drupalSettings.langcode,
+ replace_pattern: settings.replace_pattern,
+ replace_token: settings.replace_token,
+ replace: settings.replace,
+ lowercase: true
+ });
+ }
+ };
+
+})(jQuery, Drupal, drupalSettings);