diff options
author | Alex Pott <alex.a.pott@googlemail.com> | 2017-05-19 23:12:53 +0100 |
---|---|---|
committer | Alex Pott <alex.a.pott@googlemail.com> | 2017-05-19 23:12:53 +0100 |
commit | 8287017e034bc323dec1d86b3f37a804aa082d2d (patch) | |
tree | ebd8ff908859b0e1cc4319392da94e8f68033321 /core/misc/machine-name.es6.js | |
parent | 9a0e9a649ac8078ce6e5f6089749a1115bdda06b (diff) | |
download | drupal-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.js | 211 |
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); |